nftables: bölümler arasında yinelenen yayın paketleri
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 set
yayın adresi, kaynak segmentteki ile aynı kalır. nft monitor trace
en 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
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ışı dup
ve fwd
de giriş kanca ile tam olarak aynı olan tc-mirred S' mirror
ve 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
}
}
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 ( ingress
değiştirecek olan kaynak IP yerine hedef IP'yi nat egress
değ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).