We have a Debian Buster box (nftables 0.9.0, kernel 4.19) attached to four different network segments. Three of these segments are home to devices running Syncthing, which runs its own local discovery via broadcasts to UDP port 21027. The devices thus can't all "see" each other as the broadcasts don't cross segments; the Buster box itself does not participate in the sync cluster.
While we could solve this by running Syncthing's discovery or relay servers on the Buster box, it's been requested that we not use them (reasons around configuration and devices which roam to other sites). Hence, we're looking at a nftables-based solution; my understanding is that this isn't normally done, but to make this work, we have to:
- Match incoming packets on UDP 21027
- Copy those packets to the other segment interface(s) they need to be seen on
- Change the destination IP of the new packet(s) to match the new segment's broadcast address (while preserving the source IP as the discovery protocol can rely on it)
- Emit the new broadcasts without them getting duplicated again
Only three of the attached segments participate with devices; all are subnet masked as /24.
- Segment A (eth0, 192.168.0.1) should not be forwarded
- Segment B (eth1, 192.168.1.1) should be forwarded to segment A only
- Segment C (eth2, 192.168.2.1) should be forwarded to both A and B
The closest we have to a working rule for this so far is (other DNAT/MASQ and local filtering rules omitted for brevity):
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
}
}
The counters show that the rules are being hit, though without the daddr set
rules the broadcast address remains the same as on the originating segment. nft monitor trace
shows least some packets are reaching the intended interface with the correct destination IP, but are then landing in the input hook for the box itself and are not seen by other devices on the segment.
Is the outcome we're looking for here achievable in practice, and if so, with which rules?
dup to
IPs to match the interface IPs and merged thedaddr set
into thedup
rules. Trace shows packets appear with the right IP destination on the right interfaces, but inbound rather than out. Trace also showsether daddr ff:ff:ff:ff:ff:ff
, which would seem right if it were going in the opposite direction... – T2PS Aug 18 '20 at 13:00tc
for this purpose yet, I'll take a closer look at it and nft ingress. – T2PS Aug 18 '20 at 16:36