▼nmblookupがIPアドレスを牽けない▼

$Id$ (2015.12)

Keywords: nmblookup iptables "name_query failed to find name"

UNIX (Linux)のSambaクライアントから、 ホスト名だけわかっている Windows 機の IPアドレスを知りたいときは nmblookupを使いますが、
WINSサーバーがないワークグループ環境では NetBIOS名では牽けないことがあったりします。

$ nmblookup SCORPIO2
querying SCORPIO2 on 10.5.0.255
name_query failed to find name SCORPIO2
直接Windows機の IPアドレス宛てに聞くと牽けるので、単純な設定ミスではない。
$ nmblookup -U 10.5.0.68 SCORPIO2
querying SCORPIO2 on 10.5.0.68
10.5.0.68 SCORPIO2<00>

▼原因(この場合)

Linux側のファイアウォール設定 (iptables) が悪さをしていました。 iptablesを止めると牽けるようになります。

$ sudo service iptables stop
$ nmblookup SCORPIO2
querying SCORPIO2 on 10.5.0.255
10.5.0.68 SCORPIO2<00>
ただ iptables を止めるのは激しく推奨されないので、どうしたもんですかねぇ。

iptablesがこのパケットを通せないのは、tcpdumpしてみるとわかります。

$ nmblookup SCORPIO2
querying SCORPIO2 on 10.5.0.255
15:24:16.455357 IP 10.5.0.100.57713 > 10.5.0.255.netbios-ns: NBT UDP PACKET(137): QUERY; REQUEST; BROADCAST
15:24:16.455553 IP 10.5.0.68.netbios-ns > 10.5.0.100.57713: NBT UDP PACKET(137): QUERY; POSITIVE; RESPONSE; UNICAST
15:24:16.455583 IP 10.5.0.100 > 10.5.0.68: ICMP host 10.5.0.100 unreachable - admin prohibited, length 98
name_query failed to find name SCORPIO2
つまり、聞いた側のLinux機はブロードキャスト(10.5.0.255)宛てに送信していて、 名前を聞かれたWindowsは正常に応答してるのですが、 ユニキャスト用の 10.5.0.68 からの応答は想定外で、iptables が開いてないので 受信拒否してしまう。 iptables のRELATED,ESTABLISED 設定は、送受信IPアドレスが一致してないと 機能しないので、意味ありません。

iptablesに、「10.5.0.255へブロードキャストしたら、一時的に 発信UDPポートへの返信はどこからでも受け付ける」みたいな設定ができれば いいんですが、できないです。 (iptables(8)の-m recent でできそうだったが、できない)

ARPやDHCPでも似たような問題がありそうですが、こちらは なぜか問題に引っかからない。

▼対策(1)

Windows機の137番ポートからのパケットを受けられればいいので、 iptablesのルールに追加します:

# nmblookup  sends to broadcaast,but reply comes as unicast,
# so iptables won't open by ESTABLISHED.
# --dport should match net.ipv4.ip_local_port_range
-A INPUT -p udp -s 10.5.0.0/24 --sport 137 --dport 32768:61000 -j ACCEPT
/etc/sysconfig/iptables に直に書き込むと、次回に system-config-firewall や lokkit をしたときに失われてしまうので、 上記設定だけを /etc/sysconfig/iptables.cust などとして保存し、
# lokkit --custom-rules=ipv4:filter:/etc/sysconfig/iptables.cust
で /etc/sysconfig/system-config-firewall に保存するのがいいでしょう。

ただし、これは同一LAN内の137番ポート→自機の一般ユーザー用ポート全部、 に対しての通信を許可するので、セキュリティ対策としては甘めの設定です。 イントラネットなどで同一セグメントの端末がそれなりに信用できるなら これでも十分でしょう。 -s 10.5.0.0/24 で発信元アドレスを制限しておけば、外部から イタズラされる心配は減ります。

複数のネットワークセグメントがある環境では WINSサーバーを立てるのが普通なので、こういった問題は生じないはずです。 WINSサーバーにunicastで聞けば応答が得られるので。

▼対策(2)

もうちょっと堅くしたい場合は、パケットの大きさで制限してみましょう。 NetBIOSの名前解決パケットは128バイトもあれば足りるので、 それ以上のパケットを遮断してしまえばバッファオーバーフローの予防 くらいにはなります。

## safer rule to restrict packet length
-N Netbios
-A Netbios -m length --length 64:128 -j ACCEPT
-A Netbios -j REJECT
-A INPUT -p udp -s 10.5.0.0/24 --sport 137 --dport 32768:61000 -j Netbios
"Netbios" という新しいチェインを作って、 「10.5.0.0/24:137→*:32768〜61000 かつ パケット長64〜128」という ルールです。


かべ@sra-tohoku.co.jp