nftables: 특정 후크에 대해 여러 유형의 체인이 평가됩니까?

nftables: 특정 후크에 대해 여러 유형의 체인이 평가됩니까?

에 관한 특집 기사입니다.nftables 체인 유형리눅스 커널에서.

나는 그들이 어떻게 처리되는지 이해하지 못합니다. 나는 한동안 커널 코드를 살펴보았는데, nftables "체인"이 후크 항목( struct netns_nf.hooks_ipv4예를 들어 IPv4의 경우) 으로 netns에 연결되어 있는 것 같습니다 .

filter체인을 생성하거나 처리할 때 체인의 "유형"( , , 또는 )에 대한 차별이 없습니다 nat. 모든 체인 유형은 단순히 후크 항목으로 채워지고 기능만 유형에 따라 route달라지는 것처럼 보입니다 . struct nf_hook_entry.hook예를 들어 체인 함수일 것이라고 생각했습니다 nf_hook_entry.hook.nft_nat_do_chaintype nat

보고 있다이 테이블에는 제품군, 후크 및 유형의 조합이 포함되어 있습니다.input, 후크에 두 개의 체인을 추가한다고 가정해 보겠습니다 . 하나는 이고 type filter다른 하나는 입니다. type nat또한 두 체인 모두 동일한 우선순위로 생성됩니다.

질문:

  1. 동일한 후크에 두 개의 체인이 있고 유형만 다른 ​​가상의 시나리오가 가능합니까? 그렇지 않다면 커널은 이러한 일이 발생하는 것을 방지하는 곳이 어디입니까?
  2. 가능하다면 이 두 체인이 실행되는 순서는 어떻게 결정됩니까? type nat이전 체인 처럼 실행되는 것이 누락되었나요 type filter? 아니면 첫 번째와 두 번째로 추가된 체인(커널 버전 등)에 따라 달라지나요?

가지다동일한 우선순위를 가진 체인에 대한 탁월한 관련 답변, 그러나 구체적인 상황은 두 개의 체인이 있다는 것입니다.같은 종류.

이 질문을 하는 궁극적인 목적은 nftables에 "유형"이라는 개념이 있는 이유를 이해하는 것입니다.

예를 들어, type route체인의 핸들러가 ip_route_me_harder(농담 아니야!) 패킷의 일부 필드가 체인에 의해 변경되면 이는 체인에 고유합니다 type route. type nat우선순위에 몇 가지 제한이 있는 것으로 알고 있습니다 . type nat체인점이라는 것도 읽어봤는데오직연결의 첫 번째 패킷에서 호출되지만 코드 어디에서나 정확한 제한을 찾을 수 없습니다(비록 nf_nat_inet_fn? 일 수도 있음 nf_nat_core.c).

typenftables 체인이 커널에서 처리되는 방법과 위치에 대해 알려주실 수 있는 조언을 주시면 감사하겠습니다 !

편집하다: 이 답변은 nftables "유형"이 거의 문체 선택임을 나타내는 것 같습니다., 비록 이 유형 의 특별한 동작 을 지적 하지만 route. 또 다른 대답은 더 혼란 스럽습니다내 거Waters는 NAT 규칙을 체인에 추가할 수 없다고 말하는데 type filter, 이것이 사실이라면 정말 혼란스럽습니다. 그러한 제한은 어디에 구현됩니까? (사용자 공간에서만?)

답변1

긴 이야기 짧게

트래픽을 수신하고 이를 NAT하는 네트워크 네임스페이스를 실험할 때 체인에 지정된 우선순위에 관계없이 필터 체인의 우선순위가 중요하지 않다는 것을 알 수 있습니다 type nat hook prerouting. NAT는 항상 정확한 경로 전 후크 우선순위로 끝납니다. - 일명 100 NF_IP_PRI_NAT_DSTNAT 체인 자체 간의 우선순위가 유지됩니다.

.hook패킷 통과 중에 실제로 수행되는 작업에 대한 정의의 항목을 살펴보았지만 체인 등록 시 다른 동작을 도입하는 NAT 후크에 대해서만 정의된 .ops_register/ 항목을 무시했습니다..ops_unregister

커널 6.5.x 사용 및nftables1.0.9, 일부 링크 제공https://elixir.bootlin.com/현재 최신 LTS 커널을 사용하고 있으며 패치 버전은 없습니다: 6.1(6.1.x 아님).

결론적으로:

  • NAT는 특별한 후크 우선순위와 함께 작동하며 다음과 같은 다른 후크 유형과도 잘 작동합니다.필터또는노선: NAT 체인은 다른 체인과 다르게 등록됩니다. 지정된 우선순위는 동일한 위치에 연결된 서로 다른 NAT 체인 간에 계속 적용됩니다.

  • 노선다음과 같은 일반적인 우선순위를 따르세요.필터(특별한 등록이 필요하지 않습니다.)

  • NF_IP_PRI_NAT_DST다른 곳(또는 기타 다양한 NAT 관련 정확한 값)에서 정확한 우선순위를 사용 하지 마십시오 .nftablesNetfilter의 NAT 후크는 결정적이지 않고 정의되지 않을 수 있습니다(예: 생성 순서에 따라 변경될 수 있거나 동작이 커널 버전에 따라 변경될 수 있음). 예를 들어 DNAT 이전에는 -101 이하를 사용하고 DNAT 이후에는 -99 이상을 사용하지만 정의되지 않은 동작을 방지하려면 -100을 사용하지 마세요.

  • 다른 특수 시설 우선 순위에도 동일한 주의 사항이 적용됩니다.거기, 또는 NF_IP_PRI_CONNTRACK_DEFRAGNF_IP_PRI_CONNTRACK(그리고iptables상호작용 시 우선순위iptables규칙을 따르며 결정적인 결과가 필요합니다).


실험

가족과 같은 경우는 제쳐두겠습니다 inet. 충분한 규칙 세트와 테스트 사례를 사용하면 동일하게 작동하는지 확인할 수 있습니다.

규칙 세트 예( load 사용 nft -f ...):

table t         # for idempotence
delete table t  # for idempotence

table t {
    chain pf1 {
        type filter hook prerouting priority -250; policy accept;

    udp dport 5555 meta nftrace set 1 counter
    }

    chain pf2 {
        type filter hook prerouting priority -101; policy accept;

    udp dport 5555 counter accept
    udp dport 6666 counter accept
    }

    chain pf3 {
        type filter hook prerouting priority -99; policy accept;

    udp dport 5555 counter accept
    udp dport 6666 counter accept
    }

    chain pn1 {
        type nat hook prerouting priority -160; policy accept;

        counter
    }

    chain pn2 {
        type nat hook prerouting priority 180; policy accept;

        udp dport 5555 counter dnat to :6666
    }

    chain pn3 {
        type nat hook prerouting priority -190; policy accept;

        counter
    }

    chain pn4 {
        type nat hook prerouting priority 190; policy accept;

        udp dport 5555 counter dnat to :7777
        udp dport 6666 counter dnat to :7777
    }

}

이 규칙 세트 는 수신 된 UDP 포트 5555 를 pn2. 이 테스트에 사용한 UDP 포트 6666(연결할 수 없는 ICMP 대상 포트에 의해 스트림이 삭제되지 않음)에 수신 애플리케이션이 있고 (대화식으로)pn1pn3pn4pn4socat UDP4-LISTEN:6666,fork EXEC:date외딴클라이언트 사용 socat UDP4:192.0.2.2:5555 -.

pn2우선순위가 180인 NAT 체인이 DNAT를 수행할 것이라고 생각할 수 있습니다.뒤쪽에우선순위가 -99 인 필터 체인 pf3. 하지만 type nat다른 유형에서는 이런 일이 발생하지 않습니다 . NAT는 특별합니다. 다음과 같이 사용하세요 nft monitor trace:

# nft monitor trace
trace id 4ab9ba62 ip t pf1 packet: iif "lan0" ether saddr 8e:3e:82:1a:dc:87 ether daddr fa:2f:7e:2d:f1:03 ip saddr 192.0.2.1 ip daddr 192.0.2.2 ip dscp cs0 ip ecn not-ect ip ttl 64 ip id 49393 ip length 30 udp sport 58201 udp dport 5555 udp length 10 @th,64,16 0x610a
trace id 4ab9ba62 ip t pf1 rule udp dport 5555 meta nftrace set 1 counter packets 0 bytes 0 (verdict continue)
trace id 4ab9ba62 ip t pf1 verdict continue
trace id 4ab9ba62 ip t pf1 policy accept
trace id 4ab9ba62 ip t pf2 packet: iif "lan0" ether saddr 8e:3e:82:1a:dc:87 ether daddr fa:2f:7e:2d:f1:03 ip saddr 192.0.2.1 ip daddr 192.0.2.2 ip dscp cs0 ip ecn not-ect ip ttl 64 ip id 49393 ip length 30 udp sport 58201 udp dport 5555 udp length 10 @th,64,16 0x610a
trace id 4ab9ba62 ip t pf2 rule udp dport 5555 counter packets 0 bytes 0 accept (verdict accept)
trace id 4ab9ba62 ip t pn3 packet: iif "lan0" ether saddr 8e:3e:82:1a:dc:87 ether daddr fa:2f:7e:2d:f1:03 ip saddr 192.0.2.1 ip daddr 192.0.2.2 ip dscp cs0 ip ecn not-ect ip ttl 64 ip id 49393 ip length 30 udp sport 58201 udp dport 5555 udp length 10 @th,64,16 0x610a
trace id 4ab9ba62 ip t pn3 rule counter packets 0 bytes 0 (verdict continue)
trace id 4ab9ba62 ip t pn3 verdict continue
trace id 4ab9ba62 ip t pn3 policy accept
trace id 4ab9ba62 ip t pn1 packet: iif "lan0" ether saddr 8e:3e:82:1a:dc:87 ether daddr fa:2f:7e:2d:f1:03 ip saddr 192.0.2.1 ip daddr 192.0.2.2 ip dscp cs0 ip ecn not-ect ip ttl 64 ip id 49393 ip length 30 udp sport 58201 udp dport 5555 udp length 10 @th,64,16 0x610a
trace id 4ab9ba62 ip t pn1 rule counter packets 0 bytes 0 (verdict continue)
trace id 4ab9ba62 ip t pn1 verdict continue
trace id 4ab9ba62 ip t pn1 policy accept
trace id 4ab9ba62 ip t pn2 packet: iif "lan0" ether saddr 8e:3e:82:1a:dc:87 ether daddr fa:2f:7e:2d:f1:03 ip saddr 192.0.2.1 ip daddr 192.0.2.2 ip dscp cs0 ip ecn not-ect ip ttl 64 ip id 49393 ip length 30 udp sport 58201 udp dport 5555 udp length 10 @th,64,16 0x610a
trace id 4ab9ba62 ip t pn2 rule udp dport 5555 counter packets 0 bytes 0 dnat to :6666 (verdict accept)
trace id 4ab9ba62 ip t pf3 packet: iif "lan0" ether saddr 8e:3e:82:1a:dc:87 ether daddr fa:2f:7e:2d:f1:03 ip saddr 192.0.2.1 ip daddr 192.0.2.2 ip dscp cs0 ip ecn not-ect ip ttl 64 ip id 49393 ip length 30 udp sport 58201 udp dport 6666 udp length 10 @th,64,16 0x610a
trace id 4ab9ba62 ip t pf3 rule udp dport 6666 counter packets 0 bytes 0 accept (verdict accept)

trace id 46ad0497 ip t pf1 packet: iif "lan0" ether saddr 8e:3e:82:1a:dc:87 ether daddr fa:2f:7e:2d:f1:03 ip saddr 192.0.2.1 ip daddr 192.0.2.2 ip dscp cs0 ip ecn not-ect ip ttl 64 ip id 49394 ip length 30 udp sport 58201 udp dport 5555 udp length 10 @th,64,16 0x620a
trace id 46ad0497 ip t pf1 rule udp dport 5555 meta nftrace set 1 counter packets 0 bytes 0 (verdict continue)
trace id 46ad0497 ip t pf1 verdict continue
trace id 46ad0497 ip t pf1 policy accept
trace id 46ad0497 ip t pf2 packet: iif "lan0" ether saddr 8e:3e:82:1a:dc:87 ether daddr fa:2f:7e:2d:f1:03 ip saddr 192.0.2.1 ip daddr 192.0.2.2 ip dscp cs0 ip ecn not-ect ip ttl 64 ip id 49394 ip length 30 udp sport 58201 udp dport 5555 udp length 10 @th,64,16 0x620a
trace id 46ad0497 ip t pf2 rule udp dport 5555 counter packets 0 bytes 0 accept (verdict accept)
trace id 46ad0497 ip t pf3 packet: iif "lan0" ether saddr 8e:3e:82:1a:dc:87 ether daddr fa:2f:7e:2d:f1:03 ip saddr 192.0.2.1 ip daddr 192.0.2.2 ip dscp cs0 ip ecn not-ect ip ttl 64 ip id 49394 ip length 30 udp sport 58201 udp dport 6666 udp length 10 @th,64,16 0x620a
trace id 46ad0497 ip t pf3 rule udp dport 6666 counter packets 0 bytes 0 accept (verdict accept)
^C

모든 사전 라우팅된 NAT 후크가 와 사이 pf2, pf3즉 우선순위 -101과 -99 사이에서 발생하고, 우선순위 -100, 즉 우선순위에서 발생하는 것을 볼 수 있습니다.NF_IP_PRI_NAT_DSTNetfilter 자체 구조에서 사용static const struct nf_hook_ops nf_nat_ipv4_ops[]. 체인에는 ip t pf35555 대신 포트 6666이 표시됩니다.

NAT 문이 적용된 경우 Netfilter는 (동일한 후크에서) 다음 규칙을 건너뛰므로 pn4위의 예에서는 여기를 전혀 통과할 기회가 없습니다(동일한 흐름에 대한 2개의 패킷만 처음에 포트 5555에 도착함). 나타나는 : 이 동작은 type filter다음 후크의 위치를 ​​계속 탐색하는 것과도 다릅니다(예: pf3여전히 이후를 탐색하는 중 pf2).

평소와 같이 스트림의 다음 패킷은 더 이상 NAT 체인을 트리거하지 않습니다. 새 스트림(conntrack 상태 NEW)을 생성하는 패킷만 NAT 체인으로 전송되므로 다음 패킷은 더 이상 체인을 통과하는 것처럼 보이지 않습니다 pnX. 미리 라우팅된 4개의 NAT 체인 간에 우선순위가 존중됩니다. 우선순위 순서는 pn3(-190), pn1(-160), pn2(180)입니다(그러면 (190)이 되지만 pn4기회는 없습니다).

참고: 동일한 실행에서 패킷/바이트 카운터가 증가하지 않는 것으로 보인다는 사실은 nft monitor trace버그나 누락된 기능처럼 보입니다(확인할 때 증가하고 있었습니다 nft list ruleset).

type nat후크 사용다른 기본 기능과 다른 등록 기능nftables따라서 다양한 방법으로 처리할 수 있습니다.

.ops_register = nf_nat_ipv4_register_fn,
.ops_unregister = nf_nat_ipv4_unregister_fn,

NAT(Netfilter에 의해 관리됨)에 의해 처리되고 후크됩니다.NF_INET_PRE_ROUTING(여전히 Netfilter에서 제공)nftables) 이 작업이 먼저 수행됩니다 NF_IP_PRI_NAT_DST.

이건 아니야유형 필터(도 아니다노선) 그런 다음 일반을 사용합니다nftables대신 방법지정된 것.

관련 정보