nftables:セグメント間でブロードキャストパケットを複製します

Aug 18 2020

4つの異なるネットワークセグメントに接続されたDebianバスターボックス(nftables 0.9.0、カーネル4.19)があります。これらのセグメントのうち3つは、UDPポート21027へのブロードキャストを介して独自のローカル検出を実行するSyncthingを実行するデバイスのホームです。したがって、ブロードキャストはセグメントを横断しないため、デバイスはすべて互いに「見る」ことができません。バスターボックス自体は同期クラスターに参加しません。

BusterボックスでSyncthingの検出サーバーまたはリレーサーバーを実行することでこれを解決できますが、それらを使用しないように要求されています(構成および他のサイトにローミングするデバイスに関する理由)。したがって、nftablesベースのソリューションを検討しています。私の理解では、これは通常は行われていませんが、これを機能させるには、次のことを行う必要があります。

  • UDP21027の着信パケットを照合します
  • それらのパケットを、表示する必要のある他のセグメントインターフェイスにコピーします
  • 新しいパケットの宛先IPを、新しいセグメントのブロードキャストアドレスと一致するように変更します(検出プロトコルが信頼できるため、送信元IPを保持します)。
  • 再度複製されることなく、新しいブロードキャストを送信します

アタッチされたセグメントのうち3つだけがデバイスに参加します。すべてが/ 24としてサブネットマスクされます。

  • セグメントA(eth0、192.168.0.1)は転送しないでください
  • セグメントB(eth1、192.168.1.1)はセグメントAにのみ転送する必要があります
  • セグメントC(eth2、192.168.2.1)はAとBの両方に転送する必要があります

これまでのところ、これの作業ルールに最も近いものは次のとおりです(簡潔にするために他のDNAT / MASQおよびローカルフィルタリングルールは省略されています)。

table ip mangle {
    chain repeater {
        type filter hook prerouting priority -152; policy accept;
        ip protocol tcp return
        udp dport != 21027 return
        iifname "eth1" ip saddr 192.168.2.0/24 counter ip daddr set 192.168.1.255 return
        iifname "eth0" ip saddr 192.168.2.0/24 counter ip daddr set 192.168.0.255 return
        iifname "eth0" ip saddr 192.168.1.0/24 counter ip daddr set 192.168.0.255 return
        iifname "eth2" ip saddr 192.168.2.0/24 counter dup to 192.168.0.255 device "eth0" nftrace set 1
        iifname "eth2" ip saddr 192.168.2.0/24 counter dup to 192.168.1.255 device "eth1" nftrace set 1
        iifname "eth1" ip saddr 192.168.1.0/24 counter dup to 192.168.0.255 device "eth0" nftrace set 1
    }
}

カウンタは、ルールがヒットしていることを示しますが、ルールがないとdaddr set、ブロードキャストアドレスは元のセグメントと同じままです。nft monitor traceは、少なくとも一部のパケットが正しい宛先IPで目的のインターフェイスに到達しているが、ボックス自体の入力フックに到達しており、セグメント上の他のデバイスからは見えないことを示しています。

ここで私たちが探している結果は実際に達成可能ですか?もしそうなら、どのルールで達成できますか?

回答

1 A.B Aug 21 2020 at 03:53

この場合、入力のみが必要であるため(nftablesにはまだ出力がありません)、netdevファミリーで(ipファミリーではなく)nftablesを使用することは可能です。入力フック内のおよびの動作は、tc-mirredのおよびとまったく同じです。dupfwdmirrorredirect

また、マイナーな詳細についても説明しました。これがなくても実際にルーティングされたパケットの場合と同様に、イーサネット送信元アドレスを新しいイーサネット発信インターフェイスのMACアドレスに書き換えます。したがって、インターフェイスのMACアドレスは事前に知っておく必要があります。必要な2つ(eth0eth1)を変数/マクロ定義に入れました。これは正しい値で編集する必要があります。

define eth0mac = 02:0a:00:00:00:01
define eth1mac = 02:0b:00:00:00:01

table netdev statelessnat
delete table netdev statelessnat

table netdev statelessnat {
    chain b { type filter hook ingress device eth1 priority 0;
        pkttype broadcast ether type ip ip daddr 192.168.1.255 udp dport 21027 jump b-to-a
        
    }

    chain c { type filter hook ingress device eth2 priority 0;
        pkttype broadcast ether type ip ip daddr 192.168.2.255 udp dport 21027 counter jump c-to-b-a
    }

    chain b-to-a {
        ether saddr set $eth0mac ip daddr set 192.168.0.255 fwd to eth0 } chain c-to-b-a { ether saddr set $eth1mac ip daddr set 192.168.1.255 dup to eth1 goto b-to-a
    }
}
1 T2PS Aug 19 2020 at 21:44

編集:後でこれを見つけた人のために、ABから受け入れられた答えは純粋にnftの解決策を与えます。

ABの提案のおかげで、これは純粋にnftablesルールではなくtcを使用して機能しています。

tc qdisc add dev eth2 ingress
tc filter add dev eth2 ingress \
    protocol ip u32 \
    match ip dst 192.168.2.255 \
    match ip protocol 17 0xff \
    match ip dport 21027 0xffff \
    action nat ingress 192.168.2.255/32 192.168.0.255 \
    pipe action mirred egress mirror dev eth0 \
    pipe action nat ingress 192.168.0.255/32 192.168.1.255 \
    pipe action mirred egress redirect dev eth1

tc qdisc add dev eth1 ingress
tc filter add dev eth1 ingress \
    protocol ip u32 \
    match ip dst 192.168.1.255 \
    match ip protocol 17 0xff \
    match ip dport 21027 0xffff \
    action nat ingress 192.168.1.255/32 192.168.0.255 \
    pipe action mirred egress redirect dev eth0

これらのフィルターについての私の理解は、UDPポート21027の着信ブロードキャストパケットと一致し、それらを他の目的のサブネットのそれぞれのブロードキャストアドレスにNATして(ingress変更する送信元IPではなく宛先IPを変更nat egressするため)、複製/リ​​ダイレクトすることです。他のインターフェイスの出力キューへのNATされたパケット。

tcの初心者であることは、問題を解決するための最良の方法ではないかもしれませんが、アナウンスブロードキャストをセグメント間で移動させるという点では機能します(そしてSyncthingは新しいノードを喜んで発見しています)。