Armadilloフォーラム

nftablesでブロードキャストを受信したい

a2c-maru

2024年3月4日 18時02分

nftablesでパケットフィルタを実施しています。

サービスにてセンサからの受信データをUDPポートで待ち受けているのですが、
そのセンサはある条件で宛先IPアドレス(本来はArmadilloのアドレス)が
ブロードキャスト(MAC=FF:FF:FF:FF:FF:FF, IP=255.255.255.255)になります。
その条件は回避が難しいため何とか受信できるようにしたいのですが、
そもそも nftables を止めていても受信できません。
かなり特殊なケースのため、有用な情報に辿り着けていない状況です。

Armadillo固有でなく一般的な話題となり恐縮ですが、
参考になる情報などありましたらご教授いただけないでしょうか?

現状の設定ファイル (nftables.conf) を添付します。
待ち受けるUDPポートを"11111"としています。

ファイル ファイルの説明
nftables.conf
コメント

at_dominique.m…

2024年3月5日 14時57分

a2c-maru さん

お世話になっています、
マルティネです。

> Armadillo固有でなく一般的な話題となり恐縮ですが、
> 参考になる情報などありましたらご教授いただけないでしょうか?

nftables を止めても受信できないとのことですので、まずは nftables 止めた状態でなぜ受信できてないか確認した方がいいと思います。

- Armadillo 自体には届いてますか?
tcpdump をインストールして、tcpdump -nn -i eth0 udp and port 11111 等で 255.255.255.255宛のパケットが表示されてなければ、ルーターか switch 等のネットワーク機器の問題の可能性もあります。
届いた場合にはできればその tcpdump の行も見せてもらえたら嬉しいですが、いかがでしょうか。(正常のパケットとbroadcast のパケットの両方を拝見できるトレースがあればパケットの差を確認できます)
- アプリケーションで受信する際のコードを共有できますか?
socket, bind, recv/recvmsg だけの流れでしたら broadcast アドレス宛でも受信できるはずですが、recvfrom や connect 等を使ってしまうとそれ以外のパケットを受信できなくなってしまいますのでそれを確認したいです。
確認が難しい場合は一旦サービスを停止して、「socat -d -d udp4-recv:11111 stdout」などで受信できてるかどうかを確認していただければと思います(接続先のアドレスが表示されてませんので「正常」のパケットもあれば tcpdump と一致させる必要があります…)

よろしくお願いします。

a2c-maru

2024年3月8日 17時57分

お返事が遅くなり申しわけありません。
マルティネさん、コメントありがとうございました。

> - Armadillo 自体には届いてますか?

届いていました。
1行目が通常受信可能のパターン、
2行目が特定条件により受信できないパターンです。

root@armadillo:~# tcpdump -nn -i eth0 udp and port 11111
tcpdump: verbose output suppressed, use -v or -vv for full protocol decode
listening on eth0, link-type EN10MB (Ethernet), capture size 262144 bytes
17:47:10.163512 IP 192.168.1.200.11110 > 192.168.1.201.11111: UDP, length 125
17:47:55.375140 IP 192.168.1.200.11110 > 255.255.255.255.11111: UDP, length 125

> - アプリケーションで受信する際のコードを共有できますか?

確認したところ、
bindで自分のIPアドレス(192.168.1.201)を指定して recvfrom でした。
nftablesの問題ではなかったようです。
nftablesを動作させてもブロードキャストは受信していました。

サービスのコードを修正するのがあるべき姿だとは思うのですが、
諸事情あってサービスのコードは変更が難しいので、
nftablesで解決できるものなら解決したいのですが、
こういう場合 NAT機能は使えるものでしょうか?

at_dominique.m…

2024年3月11日 9時22分

a2c-maruさん、

マルティネです。

> bindで自分のIPアドレス(192.168.1.201)を指定して recvfrom でした。

なるほど、bind で 0.0.0.0/port をしていする場合に届きますが、自分の IP を指定するとそちらのパケットしか受信できなくなりますね…

> サービスのコードを修正するのがあるべき姿だとは思うのですが、
> 諸事情あってサービスのコードは変更が難しいので、
> nftablesで解決できるものなら解決したいのですが、
> こういう場合 NAT機能は使えるものでしょうか?

そうですね、DNAT で無理やりに修正できます。
自分の IP に bind して broadcast のパケットを送信してみたら、以下のルールで受信できるようになりました:

table inet fixup {
	chain fix_broadcast {
		type nat hook prerouting priority dstnat; policy accept;
		ip daddr 255.255.255.255 udp dport 11111 dnat ip to 192.168.1.201:111111
	}
}

ただし、Armadillo の IP をルールに固定する必要がありますので、場合によっては不便になる可能性もありますね。

よろしくお願いします。