전달된 IPv4 패킷의 불필요한 조각 모음

전달된 IPv4 패킷의 불필요한 조각 모음

사용자 공간에서 IP 조각을 처리하고 싶고 iptables NF_QUEUE를 사용하여 패킷을 사용자 공간으로 전달하고 있습니다.

문제는 IPv4 패킷이 항상 개별 조각이 아닌 하나의 패킷으로 재조립되어 전달된다는 것입니다. IPv6의 경우 조각이 예상대로 전달됩니다.

나는 conntracker가 이 문제를 일으킬 수 있다고 생각하고 rawiptables 테이블에서 비활성화했지만 원래 테이블에 도달했을 때 패킷이 이미 재조립된 것으로 나타났습니다.

# iptables -t raw -nvL
Chain PREROUTING (policy ACCEPT 58 packets, 62981 bytes)
 pkts bytes target     prot opt in     out     source               destination         
    1 30028 CT         all  --  *      *       0.0.0.0/0            10.0.0.0/24          NOTRACK

이는 IPv4를 통해 30000바이트 UDP 패킷을 보낼 때 발생하는 현상입니다. IPv6에 해당:

# ip6tables -t raw -nvL
Chain PREROUTING (policy ACCEPT 46 packets, 62304 bytes)
 pkts bytes target     prot opt in     out     source               destination         
   21 31016 CT         all      *      *       ::/0                 1000::               NOTRACK

이는 virtio 네트워크 장치 mtu=1500이 있는 가상 환경 kvm/qemu에 있습니다. .tcpdump -ni eth2 host 10.0.0.0

그래서 제 질문은 Linux 커널에서 IPv4 패킷이 netfilter 체인 전에 다시 조립되도록 강제할 수 있는 것이 무엇입니까 raw/PREROUTING?

AF_PACKET(tcpdump)와 원시/PREROUTING 체인 사이에 있기 때문에 "ingress/qdisc"가 의심되지만 문제를 찾을 수 없습니다.

패킷 흐름 방향:https://upload.wikimedia.org/wikipedia/commons/3/37/Netfilter-packet-flow.svg

답변1

언제든지연결하다사용 중 주로 다음 용도로 사용됩니다.

  • 상태 저장 방화벽( -m conntrack ...)
  • 네트워크 주소 변환( -t nat ...)

nf_defrag_ipv4 커널 모듈에서 제공하는 추가 숨김 기능을 로드합니다 nf_defrag_ipv6. 시설은 우선순위 -400으로 네트워크 사전 라우팅에 연결됩니다.iptables'원본 테이블은 우선순위 -300으로 고정되어 있습니다. 패킷 통과 후에는 nf_defrag_ipv[46]조각이 존재하지 않습니다. 패킷은 미리 재조립됩니다. 목표는 Netfilter 및 iptables의 다양한 프로토콜 검사기가 UDP 대상 포트를 포함한 모든 패킷 콘텐츠를 얻을 수 있다는 것입니다. 이 정보는 첫 번째 조각에만 나타납니다.

따라서 이러한 상황을 방지하려면 원래 테이블의 ( 에서 사용되지 않음)만으로는 -j NOTRACK충분하지 않습니다.-j CT --notrack

하나는 수:

  • 절대 사용하지 마세요연결하다직접(상태 규칙) 또는 간접적으로(NAT),

  • 또는 새 네트워크 네임스페이스 생성

    트래픽을 직접 처리합니다(대개 도난당한 물리적 인터페이스를 사용하거나맥에버랜드인터페이스 또는 브리지하지만 라우팅되지 않음호스트에 의해) 이 네임스페이스에 상태 저장 규칙이 발생하지 않는지 확인하세요. 강제로 수행하지 않는 한 조각 모음 도구는 네트워크 네임스페이스에 연결되지 않습니다(그리고 아마도 더 새로운 커널을 사용할 수도 있음).

  • 또는 우선순위 -400 이전에 연결된 체인이 있습니다. 이것은 실제로 최근 커널에서 가능합니다:

    • ~을 위한iptables-이전 버전~부터커널 (아마도) >= 4.16

      # modinfo -p iptable_raw
      raw_before_defrag:Enable raw table before defrag (bool)
      

      원본 테이블을 새로 고치고 모듈을 언로드한 후 다시 로드(및 조정 /etc/modprobe.d/)합니다.

      modprobe iptable_raw raw_before_defrag=1
      
    • ~을 위한nftables

      예를 들어 -400보다 낮은 우선순위로 체인을 생성하면 됩니다.

      nft add table ip handlefrag
      nft add chain ip handlefrag predefrag '{ type filter hook prerouting priority -450; policy accept; }'
      nft add rule ip handlefrag predefrag ip 'frag-off & 0x3fff != 0' notrack 
      

      (첫 번째 조각이 아닌 다음 조각만 처리됩니다. 0x3fff로 교체 0x1fff)

      IPv6의 경우 접근 방식이 다릅니다.조각 헤더는 다음과 같습니다.아니요다음 타이틀. 하지만NFFTman에는 exthdr frag exists조각에 속하는 패킷을 감지하는 간단한 표현이 제공됩니다.

    • 아무것도 존재하지 않는다iptables-nftAPI(Debian과 같은 많은 배포판의 기본값): 이 모듈을 사용하지 않습니다.iptable_raw실제 옵션은 생성되지 않습니다.nftables우선순위가 -450인 체인입니다.

      따라서 명령의 출력이 다음과 같은 경우:

      # iptables -V
      iptables v1.8.7 (nf_tables)
      

      이것만으로는 사용할 수 없습니다연결하다. 다음으로 되돌려야 합니다.iptables-이전 버전또는로 전환NFFT, 또는...

    • 아직도 할 수 있는 일은 섞는 것nftables(위 규칙) 패킷을 다음과 같이 표시합니다.추적 안 함조각 모음을 한 다음 계속하기 전에iptables나머지를 처리하기 위해. 사용에는 문제가 없습니다nftables그리고iptables그동안 OP에 연결된 Netfilter 다이어그램의 작업 순서를 이해하세요.

답변2

iptables(IPv4의 경우) 이 플래그가 있습니다 -f. 추가하면 작동합니다. 또한 체인을 확인하십시오 INPUT.

[!] -f, --fragment

즉, 규칙은 조각화된 패킷의 두 번째 및 후속 IPv4 조각에만 적용됩니다. 이러한 패킷(또는 ICMP 유형)의 소스 또는 대상 포트를 알 수 없기 때문에 해당 패킷은 이를 지정하는 어떤 규칙과도 일치하지 않습니다. 언제. . . "!" 인수가 "-f" 플래그 앞에 오면 규칙은 헤더 조각 또는 조각화되지 않은 패킷과만 일치합니다. 이 옵션은 IPv4에만 해당되며 ip6tables에서는 사용할 수 없습니다.

관련 정보