글로벌 네트워크에서 특수 네트워크 네임스페이스로의 두 UDP 연결에 대해 상태 비저장 NAT를 설정하는 방법은 무엇입니까?

글로벌 네트워크에서 특수 네트워크 네임스페이스로의 두 UDP 연결에 대해 상태 비저장 NAT를 설정하는 방법은 무엇입니까?

상태 비저장 NAT는 글로벌 네트워크 네임스페이스의 물리적 네트워크 어댑터(가상 네트워크 어댑터의 연결된 쌍을 통해)에서 특수 네트워크 네임스페이스에서 실행되는 서비스로의 두 개의 UDP 연결을 위해 설정되어야 합니다. 이 작업은 커널이 포함된 Linux(Debian)를 실행하는 산업용 장치의 CPU(Intel Atom)에서 수행되어야 합니다.5.9.7.

설정해야 하는 네트워크 구성 시나리오는 다음과 같습니다.

=====================    =====================================================
|| application CPU ||    ||                communication CPU                ||
||                 ||    ||                                                 ||
||                 ||    ||    global namespace    |   nsprot1 namespace    ||
||                 ||    ||                        |                        ||
||     enp4s0      ||    ||       enp1s0           |          enp3s0        ||
||    0.0.0.5/30  ==========     0.0.0.6/30        |    192.168.2.15/24    =======
||                 ||    ||                        |                        ||
|| UDP port 50001  ||    || UDP port 50001 for sv1 |  TCP port 2404 for sv2 ||
|| UDP port 50002  ||    || UDP port 50002 for sv1 |                        ||
|| UDP port 53401  ||    || UDP port 50401 for sv1 |                        ||
|| UDP port 53402  ||    || UDP port 50402 for sv1 |                        ||
||                 ||    ||                        |                        ||
||                 ||    ||      vprot0            |         vprot1         ||
||                 ||    ||     0.0.0.16/31       ---      0.0.0.17/31      ||
||                 ||    ||                        |                        ||
|| UDP port 53404  ||    || UDP port 50404 for sv2 - UDP port 50404 for sv2 ||
|| UDP port 53441  ||    || UDP port 50441 for sv2 - UDP port 50441 for sv2 ||
=====================    =====================================================

애플리케이션 CPU는 항상 먼저 시작되고 sv1IP 주소가 있는 물리적 네트워크 어댑터를 통해 통신 CPU의 서비스 및 서비스와 통신하기 위해 여러 UDP 포트를 엽니다.sv2enp4s00.0.0.5

애플리케이션 CPU에서 실행될 때의 출력은 다음 ss --ipv4 --all --numeric --processes --udp과 같습니다.

Netid  State   Recv-Q  Send-Q   Local Address:Port    Peer Address:Port   Process
udp    UNCONN  0       0              0.0.0.0:50001        0.0.0.0:*      users:(("sva",pid=471,fd=5))
udp    UNCONN  0       0              0.0.0.0:50002        0.0.0.0:*      users:(("sva",pid=471,fd=6))
udp    ESTAB   0       0              0.0.0.5:53401        0.0.0.6:50401  users:(("sva",pid=471,fd=12))
udp    ESTAB   0       0              0.0.0.5:53402        0.0.0.6:50402  users:(("sva",pid=471,fd=13))
udp    ESTAB   0       0              0.0.0.5:53404        0.0.0.6:50404  users:(("sva",pid=471,fd=19))
udp    ESTAB   0       0              0.0.0.5:53441        0.0.0.6:50441  users:(("sva",pid=471,fd=21))

통신 CPU가 두 번째로 시작되고 마지막으로 두 가지 서비스가 실행됩니다.

  • sv1전역 네임스페이스에서그리고
  • sv2특별한 네트워크 네임스페이스에 있습니다 nsprot1.

ss --ipv4 --all --numeric --processes --udp통신 CPU의 전역 네임스페이스에서 실행한 결과는 다음과 같습니다.

Netid  State   Recv-Q  Send-Q   Local Address:Port    Peer Address:Port   Process
udp    UNCONN  0       0              0.0.0.0:50001        0.0.0.0:*      users:(("sv1",pid=812,fd=18))
udp    UNCONN  0       0              0.0.0.6:50002        0.0.0.0:*      users:(("sv1",pid=812,fd=17))
udp    UNCONN  0       0              0.0.0.6:50401        0.0.0.0:*      users:(("sv1",pid=812,fd=13))
udp    UNCONN  0       0              0.0.0.6:50402        0.0.0.0:*      users:(("sv1",pid=812,fd=15))

ip netns exec nsprot1 ss --ipv4 --all --numeric --processes --udp(네임스페이스)의 출력은 다음 nsprot1과 같습니다.

Netid  State   Recv-Q  Send-Q   Local Address:Port    Peer Address:Port   Process
udp    ESTAB   0       0             0.0.0.17:50404        0.0.0.5:53404  users:(("sv2",pid=2421,fd=11))
udp    ESTAB   0       0             0.0.0.17:50441        0.0.0.5:53441  users:(("sv2",pid=2421,fd=12))

sysctl일반적으로 모든 물리적 네트워크 어댑터에는 IPv4 전달이 활성화되어 있습니다.
브로드캐스트 및 멀티캐스트 전달만 필요하지도 않고 원하지도 않으므로 비활성화됩니다.

다음 명령을 사용하여 통신 CPU의 네트워크 구성을 설정합니다.

ip netns add nsprot1
ip link add vprot0 type veth peer name vprot1 netns nsprot1
ip link set dev enp3s0 netns nsprot1
ip address add 0.0.0.16/31 dev vprot0
ip netns exec nsprot1 ip address add 0.0.0.17/31 dev vprot1
ip netns exec nsprot1 ip address add 192.168.2.15/24 dev enp3s0
ip link set dev vprot0 up
ip netns exec nsprot1 ip link set vprot1 up
ip netns exec nsprot1 ip link set enp3s0 up
ip netns exec nsprot1 ip route add 0.0.0.4/30 via 0.0.0.16 dev vprot1

다음 명령을 사용하여 네트워크 주소 변환을 설정합니다.

nft add table ip prot1
nft add chain ip prot1 prerouting '{ type nat hook prerouting priority -100; policy accept; }'
nft add rule prot1 prerouting iif enp1s0 udp dport '{ 50404, 50441 }' dnat 0.0.0.17
nft add chain ip prot1 postrouting '{ type nat hook postrouting priority 100; policy accept; }'
nft add rule prot1 postrouting ip saddr 0.0.0.16/31 oif enp1s0 snat 0.0.0.6

출력은 nft list table ip prot1다음과 같습니다

table ip prot1 {
    chain prerouting {
        type nat hook prerouting priority -100; policy accept;
        iif "enp1s0" udp dport { 50404, 50441 } dnat to 0.0.0.17
    }

    chain postrouting {
        type nat hook postrouting priority 100; policy accept;
        ip saddr 0.0.0.16/31 oif "enp1s0" snat to 0.0.0.6
    }
}

전역 네임스페이스에 추가로 정의됩니다.오직테이블에는 다음 inet filter이 포함됩니다.

table inet filter {
    chain input {
        type filter hook input priority 0; policy accept;
    }

    chain forward {
        type filter hook forward priority 0; policy accept;
    }

    chain output {
        type filter hook output priority 0; policy accept;
    }
}

이 NAT 구성은 상태 저장 NAT용입니다. 이는 포트 번호가 있는 UDP 채널에서 작동하며 50404 마지막 으로 시작된 53404이후 UDP 패킷을 sv2열어 ​​전송합니다. 이 패킷에는 전역 네임스페이스의 후크에 소스 네트워크 주소 변환이 적용됩니다. 응용 프로그램 CPU 서비스는 UDP 패킷을 에서 로 다시 보냅니다. UDP 패킷이 에 대한 규칙을 전달하지 않았습니다. 나중에 발견한 대로 연결 추적을 통해 직접 전송되었습니다.0.0.0.17:504040.0.0.5:53404postroutingenp1s0sva0.0.0.5:534040.0.0.6:504040.0.0.17:50404preroutingdnat0.0.0.170.0.0.17

그러나 이 상태 저장 NAT 구성은 포트 번호가 50441및 인 UDP 채널에는 적용되지 않습니다 534441. 원인은 sva서비스가 시작되기 전에 애플리케이션 CPU가 여러 UDP 패킷을 보냈고 대상 포트가 0.0.0.5:53441네트워크 네임스페이스에 열려 있기 때문인 것 같습니다. ICMP는 대상 포트에 연결할 수 없다고 반환합니다. 목적지 항구가 아직 열려 있지 않다는 점을 고려하면 이는 놀라운 일이 아닙니다. 불행하게도 서비스가 시작되고 두 UDP 포트가 모두 열릴 때까지 UDP 패킷이 서비스에서 전송되는 것을 방지할 수 있는 방법은 없습니다. 이 서비스는 연결 상태에 관계없이 주기적으로 전송하고 때로는 추가로 자발적인 UDP 패킷을 트리거합니다.0.0.0.6:50441sv2nsprot1svasv2sva0.0.0.5:534410.0.0.6:50441

따라서 이 구성의 문제는 상태 저장 NAT인 것 같습니다. 후크 dnat의 규칙 prerouting이 네트워크 네임스페이스에서 열리게 되는 대상 포트에서 여전히 사용되지 않기 때문입니다 nsprot1. UDP 패킷은 어쨌든 계속 라우팅되므로 0.0.0.6:50441UDP 패킷이 삭제되고 대상 포트에 연결할 수 없음을 나타내는 ICMP가 반환됩니다.

따라서 해결책은 Stateless NAT를 사용하는 것일 수 있습니다. 따라서 다음 명령도 실행되었습니다.

nft add table ip raw
nft add chain ip raw prerouting '{ type filter hook prerouting priority -300; policy accept; }'
nft add rule ip raw prerouting udp dport '{ 50404, 50441, 53404, 53441 }' notrack

그러나 결과는 예상과 달랐다. 입력 인터페이스와 대상 포트에서 들어오는 UDP 패킷의 경우 prerouting대상 주소를 에서 로 변경하는 규칙 0.0.0.6은 아직 고려되지 않습니다.0.0.0.17enp1s05040450441

다음은 내가 실행한 것입니다.

nft add table ip filter
nft add chain filter trace_in '{ type filter hook prerouting priority -301; }'
nft add rule filter trace_in meta nftrace set 1
nft add chain filter trace_out '{ type filter hook postrouting priority 99; }'
nft add rule filter trace_out meta nftrace set 1
nft monitor trace

추적을 살펴보니 notrack규칙이 고려되었지만 대상 포트가 있는 UDP 패킷이 후크 50441로 직접 전달되는 것을 볼 수 있습니다. input이유는 모르겠습니다.

나는 다음과 같은 내용을 아주 오랜 시간 동안 매우 주의 깊게 연구했습니다.

  • NFT 핸드북(위에서 아래로 여러 번 완전히 읽으십시오)
  • nftables 위키(대부분의 페이지가 완료됨)
  • ArchWiki의 nftables
  • 그리고 네트워크 네임스페이스 사용 및 네트워크 주소 변환에 관한 수많은 기타 웹 페이지가 있습니다.

Wireshark를 사용하여 다양한 구성을 시도했지만 포트가 있는 UDP 채널에 대해 작동 하고 대상 포트가 열리기 전에 UDP 패킷을 보내는 nft monitor trace솔루션을 찾을 수 없습니다 .5044153441sva0.0.0.17:50441

애플리케이션 CPU에서 서비스를 수동으로 종료하고 sva, 통신 CPU에서 네트워크 구성을 설정하고 두 서비스를 모두 시작한 다음 sv1, sv2마지막으로 sva통신 CPU에서 열려 있는 모든 UDP 포트에서 서비스를 수동으로 다시 시작하면 상태 저장 NAT 구성이 적용됩니다. . 그러나 기본적으로 이러한 서비스 시작 시퀀스는 산업용 장비에서 수행될 수 없습니다. 애플리케이션 서비스는 sva통신 서비스가 통신할 준비가 되었는지 여부와 독립적으로 실행되어야 합니다.

대상 포트의 개방 상태와 관계없이 두 개의 UDP 채널에 대해 상태 비저장 NAT를 갖기 위해 필요한 명령(체인/규칙)은 무엇이며, 어떤 서비스가 UDP 패킷을 다른 서비스에 먼저 전송 0.0.0.5:53404 - 0.0.0.17:50404합니까 ?0.0.0.5:53441 - 0.0.0.17:50441

추신: 서비스는 sv2장치 구성에 따라 시작될 수도 있고, NAT 및 네트워크 네임스페이스 없이 전역 네임스페이스에서 다른 물리적 네트워크 어댑터를 사용할 수도 있습니다. 이 네트워크 구성에서는 세 서비스 간의 UDP 통신에 전혀 문제가 없습니다.

답변1

여러 시간에 걸쳐 문서, 튜토리얼, 다양한 웹 페이지에 대한 조언, 많은 실험, 심층적이고 포괄적인 네트워크 및 넷필터 모니터링 및 분석을 읽은 후 마침내 솔루션을 직접 찾았습니다.

nft add table ip prot1
nft add chain ip prot1 prerouting '{ type filter hook prerouting priority -300; policy accept; }'
nft add rule ip prot1 prerouting iif enp1s0 udp dport '{ 50404, 50441 }' ip daddr set 0.0.0.17 notrack accept
nft add rule ip prot1 prerouting iif vprot0 ip saddr 0.0.0.17 notrack accept
nft add chain ip prot1 postrouting '{ type filter hook postrouting priority 100; policy accept; }'
nft add rule ip prot1 postrouting oif enp1s0 ip saddr 0.0.0.17 ip saddr set 0.0.0.6 accept

이것웹 필터 후크다음 지침을 이해하려면 먼저 페이지를 열고 읽어야 합니다.

명령 사용 지침:

  1. 웹 필터 테이블ip(IPv4) 라는 프로토콜에 추가되었습니다 prot1.
  2. 체인우선순위로 후크 유형 이름 테이블에 추가됩니다 prot1. 연결 추적을 우회하려면 이보다 낮은 우선순위 번호를 사용하는 것이 중요합니다. 이는 우선순위가 낮은 대상 네트워크 주소 변환 유형 체인을 사용하는 것을 배제합니다.preroutingfilterprerouting-300-200conntracknat
  3. 필터 규칙프로토콜 유형 또는 의 입력 인터페이스 에서 수신된 IPv4 패킷에만 적용 prot1되는 테이블 체인에 추가되어 패킷의 대상을 에서 로 변경하고 이 UDP 패킷에 대한 연결을 활성화합니다. 실제로 통신 CPU의 서비스를 위해 애플리케이션 CPU의 서비스에서 수신한 UDP 패킷을 가능한 한 빨리 다음 후크(이 경우 후크)로 전달할 필요는 없지만 결정은 명시적으로 지정됩니다.preroutingiifenp1s0udpdport5040450441ip daddr0.0.0.60.0.0.17no trackacceptsvasv2forward
  4. 일초필터 규칙prot1체인에 테이블에 추가 prerouting, 다음에만 적용됩니다.모두i프로토콜 유형(,,...)에 관계없이 입력 인터페이스에서 수신된 IPv4 패킷은 i패킷을 활성화한 연결의 출처를 갖습니다. 물론 적절한 소스 또는 대상 포트 번호를 사용하여 UDP 패킷만 필터링하는 것이 가능하지만 이 추가 제한은 여기에서 필요하지 않으며 이 규칙은 서비스에 따라 아직 열려 있지 않은 대상 포트에서 다시 전송되는 ICMP 패킷에도 적용됩니다. 현재는 실행되지 않습니다. 암시적 기본값을 사용하는 대신 명시적으로 판정을 다시 지정하면 패킷이 가능한 한 빨리 후크에 전달됩니다.fvprot0udpicmpip saddr0.0.0.17no track0.0.0.170.0.0.5sv2acceptcontinueforward
  5. 일초체인우선순위로 후크 유형 이름 테이블에 추가됩니다 prot1. 연결 추적을 우회하는 UDP(및 ICMP) 패킷에 소스 주소 변환을 적용하려면 유형 체인 대신 유형 체인을 사용하는 것이 중요합니다.postroutingfilterpostrouting100filternat
  6. 필터 규칙ess에서 패킷의 출처를 수정하는 소스를 사용하여 프로토콜 유형(,, ...)에 관계없이 출력 인터페이스에서 전송된 IPv4 패킷 에만 적용되는 prot1두 번째 체인을 테이블 에 추가합니다 . 통신 CPU의 서비스에서 수신된 UDP 패킷은 실제로 가능한 한 빨리 응용 CPU의 서비스로 전달될 필요는 없지만 이 결정은 다시 명시적으로 지정됩니다. 또한 이 규칙은 서비스가 아직 실행되지 않아 연결할 수 없는 대상 포트로 전송된 ICMP 패킷의 소스 주소를 변경합니다. 따라서 애플리케이션 CPU는 두 UDP 채널의 통신에 서로 다른 인터페이스를 사용한다는 사실을 결코 인식하지 못합니다. 이는 중요하지는 않지만 충족해야 할 두 번째 요구 사항입니다.postroutingoifenp1s0udpicmpsaddr0.0.0.17ip saddr0.0.0.170.0.0.6acceptsv2sva0.0.0.60.0.0.17sv20.0.0.6

매우 구체적인 네트워크 구성과 무상태 네트워크 변환이 필요한 서비스 간 통신 유형 svasv2수행해야 하는 NAT를 검색하는 것은 어려운 작업입니다.아니요후크를 사용하세요 nat.

답변2

귀하의 기사에 진심으로 감사드립니다. 나에게 많은 도움이되었습니다.

팁 하나 더: 설정을 하는 중인데 작동하지 않으면 "conntrack -L"을 사용하여 contrack에서 기존 연결을 확인하고 "conntrack -D"를 사용하여 삭제하세요.

이는 내 구성에서 프로브를 검색하는 데 몇 시간을 소비했기 때문입니다. 문제는 없지만 이전 연결은 여전히 ​​사용할 수 있습니다.

관련 정보