nftables: 세그먼트 간 중복된 브로드캐스트 패킷

nftables: 세그먼트 간 중복된 브로드캐스트 패킷

우리는 네 개의 다른 네트워크 세그먼트에 연결된 Debian Buster 상자(nftables 0.9.0, 커널 4.19)를 가지고 있습니다. 네트워크 세그먼트 중 3개는 UDP 포트 21027에 브로드캐스팅하여 자체 로컬 검색을 실행하는 Syncthing을 실행하는 장치의 본거지입니다. 따라서 브로드캐스트가 네트워크 세그먼트에 걸쳐 있지 않기 때문에 이러한 장치는 모두 서로 "볼" 수 없습니다. 버스터 상자 자체는 동기화된 클러스터에 참여하지 않습니다.

Buster 상자에서 Syncthing의 검색 또는 릴레이 서버를 실행하여 이 문제를 해결할 수 있지만 이를 사용하지 않도록 요청받습니다(장치 구성 및 다른 사이트로의 로밍으로 인해). 그래서 우리는 nftables 기반 솔루션을 찾고 있습니다. 제 생각에는 이것이 일반적으로 수행되지는 않지만 이것이 작동하려면 다음을 수행해야 합니다.

  • UDP 21027에서 들어오는 패킷과 일치합니다.
  • 이러한 패킷을 확인해야 하는 다른 네트워크 세그먼트 인터페이스에 복사합니다.
  • 새 네트워크 세그먼트의 브로드캐스트 주소와 일치하도록 새 패킷의 대상 IP를 변경합니다(검색 프로토콜이 이에 의존할 수 있으므로 소스 IP를 유지하면서).
  • 다시 반복하지 않고 새 방송을 발행합니다.

세 개의 추가 세그먼트만 장치에 참여합니다. 모든 서브넷 마스크는 /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

nftables를 여전히 사용할 수 있습니다.웹 개발자가족(대신아이피가족) 이 경우에만입구필수(nftables에는 아직출구쓸 수 있는). dup조화 fwd로운 행동입구와 연결하다TC 거울' mirror모래 redirect.

또한 작은 세부 사항에 대해서도 논의했습니다. 이더넷 소스 주소를 새로운 이더넷 발신 인터페이스의 MAC 주소로 다시 쓰는 것입니다. 마치 실제로 라우팅된 패킷을 사용하는 것처럼 패킷 없이도 작동합니다. 따라서 인터페이스의 MAC 주소를 미리 알고 있어야 합니다. 나는 필요한 두 개를 넣었습니다 (이더넷 0'모래이더넷 1's)의 변수/매크로 정의를 올바른 값으로 편집해야 합니다.

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

답변2

편집: 나중에 이 질문을 찾는 사람을 위해 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) 복사/리디렉션이 NATed 전송을 보낸다는 것입니다. 패킷을 다른 인터페이스의 출력 대기열로 보냅니다.

tc를 처음 사용하는 경우 이것이 문제를 해결하는 가장 좋은 방법은 아닐 수 있지만 공지 브로드캐스트가 세그먼트 전체에 전파될 수 있습니다(Syncthing은 새로운 노드를 발견하게 되어 기쁘게 생각합니다).

관련 정보