nftables: bölümler arasında yinelenen yayın paketleri

Aug 18 2020

Dört farklı ağ segmentine eklenmiş bir Debian Buster kutumuz (nftables 0.9.0, kernel 4.19) var. Bu segmentlerden üçü, UDP bağlantı noktası 21027'ye yayınlar aracılığıyla kendi yerel keşfini çalıştıran Syncthing çalıştıran cihazlara ev sahipliği yapmaktadır. Bu nedenle, yayınlar segmentleri geçmediği için cihazlar birbirlerini "göremez"; Buster kutusunun kendisi senkronizasyon kümesine katılmaz.

Bunu, Syncthing'in keşif veya aktarma sunucularını Buster kutusunda çalıştırarak çözebilirken, bunları kullanmamamız istenmiştir (yapılandırma ve diğer sitelerde dolaşan cihazlarla ilgili nedenler). Bu nedenle, nftables tabanlı bir çözüm arıyoruz; Anladığım kadarıyla bu normalde yapılmaz, ancak bunun işe yaraması için şunları yapmamız gerekiyor:

  • UDP 21027'de gelen paketleri eşleştirin
  • Bu paketleri, görülmeleri gereken diğer segment arayüzlerine kopyalayın
  • Yeni paketin / paketlerin hedef IP'sini yeni segmentin yayın adresiyle eşleşecek şekilde değiştirin (keşif protokolü buna güvenebileceği için kaynak IP'yi korurken)
  • Yeni yayınları tekrar kopyalanmadan yayınlayın

Ekli segmentlerden yalnızca üçü cihazlarla katılır; tümü / 24 olarak alt ağ maskelenir.

  • Segment A (eth0, 192.168.0.1) iletilmemelidir
  • Segment B (eth1, 192.168.1.1) yalnızca segment A'ya iletilmelidir
  • Segment C (eth2, 192.168.2.1) hem A hem de B'ye iletilmelidir

Şimdiye kadar bunun için bir çalışma kuralına en yakın olanı (diğer DNAT / MASQ ve kısalık için atlanan yerel filtreleme kuralları):

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
    }
}

Sayaçlar, kurallara uyulduğunu gösterir, ancak kurallar olmadan daddr setyayın adresi, kaynak segmentteki ile aynı kalır. nft monitor traceen azından bazı paketlerin doğru hedef IP ile amaçlanan arayüze ulaştığını, ancak daha sonra kutunun kendisi için giriş kancasına indiğini ve segmentteki diğer cihazlar tarafından görülmediğini göstermektedir.

Burada aradığımız sonuç pratikte elde edilebilir mi ve eğer öyleyse, hangi kurallarla?

Yanıtlar

1 A.B Aug 21 2020 at 03:53

Netdev ailesinde ( ip ailesi yerine) nftables kullanmak hala mümkündür , çünkü yalnızca giriş gereklidir (nftables hala mevcut çıkışa sahip değildir ). Davranışı dupve fwdde giriş kanca ile tam olarak aynı olan tc-mirred S' mirrorve redirect.

Ayrıca küçük bir ayrıntıya da değindim: sizin için bu olmadan çalışsa bile, gerçekten yönlendirilmiş bir paket için yapılacağı gibi, Ethernet kaynak adresini yeni Ethernet giden arayüzünün MAC adresine yeniden yazın. Bu nedenle arayüzlerin MAC adreslerinin önceden bilinmesi gerekir. Doğru değerlerle düzenlenmesi gereken iki gerekli ( eth0 ve eth1 ) değişkenleri / makro tanımlarını koydum .

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

Düzenleme: Bunu daha sonra bulan herkes için AB'den kabul edilen cevap tamamen nft bir çözüm sunar.

AB'nin önerisi sayesinde, bu artık tamamen nftable kuralları yerine tc kullanarak çalışıyor:

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

Bu filtrelerden anladığım kadarıyla, UDP bağlantı noktası 21027 için gelen yayın paketlerini, NAT bunları diğer amaçlanan alt ağların her biri için yayın adresiyle eşleştirmeleri ( ingressdeğiştirecek olan kaynak IP yerine hedef IP'yi nat egressdeğiştirmek için), ardından çoğaltma / yönlendirme NATted paketleri diğer arayüzlerin çıktı kuyruklarına.

Tc konusunda acemi olmak sorunu çözmenin en iyi yolu olmayabilir, ancak duyuru yayınlarının segmentler arasında dolaşmasını sağlamak açısından işe yarar (ve Syncthing mutlu bir şekilde yeni düğümler keşfediyor).