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

Aug 18 2020

데비안 버스터 박스 (nftables 0.9.0, 커널 4.19)가 4 개의 다른 네트워크 세그먼트에 연결되어 있습니다. 이들 세그먼트 중 3 개는 UDP 포트 21027에 대한 브로드 캐스트를 통해 자체 로컬 검색을 실행하는 Syncthing을 실행하는 장치의 홈입니다. 따라서 브로드 캐스트가 세그먼트를 교차하지 않기 때문에 장치는 모두 서로 "볼"수 없습니다. 버스터 박스 자체는 동기화 클러스터에 참여하지 않습니다.

버스터 박스에서 Syncthing의 검색 또는 릴레이 서버를 실행하여이 문제를 해결할 수 있지만,이를 사용하지 않는 것이 요청되었습니다 (다른 사이트로 로밍하는 구성 및 장치에 대한 이유). 따라서 우리는 nftables 기반 솔루션을 찾고 있습니다. 내 이해는 이것은 일반적으로 수행되지 않지만이 작업을 수행하려면 다음을 수행해야합니다.

  • UDP 21027에서 수신 패킷 일치
  • 해당 패킷을 확인해야하는 다른 세그먼트 인터페이스에 복사합니다.
  • 새 세그먼트의 브로드 캐스트 주소와 일치하도록 새 패킷의 대상 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

이 경우에는 netdev 계열 ( ip 계열이 아닌 )에서 nftables를 사용할 수 있습니다. 수신 만 필요하기 때문입니다 (nftables에는 여전히 송신을 사용할 수 없음). 의 동작 dupfwd진입 후크는 정확히 동일 TC-mirred는mirrorredirect.

나는 또한 사소한 세부 사항을 다루었습니다. 이것이 없이도 작동하더라도 실제로 라우팅 된 패킷에 대해 수행 된 것처럼 이더넷 소스 주소를 새 이더넷 발신 인터페이스의 MAC 주소로 다시 작성합니다. 따라서 인터페이스의 MAC 주소를 미리 알아야합니다. 두 가지 필수 ( 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은 행복하게 새로운 노드를 발견합니다).