iptables가 허용 된 패킷의 두 번째 및 이후 조각을 거부하는 이유는 무엇입니까?


9

서로 IPSec 연결을 설정하려는 두 개의 호스트가 있습니다. 이를 위해 UDP 포트 500 및 4500에서 통신해야하므로 양쪽 끝의 방화벽에서 열었습니다 (관련 부분에 표시됨).

-A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT
-A INPUT -m udp -p udp --dport 500 -j ACCEPT
-A INPUT -m udp -p udp --dport 4500 -j ACCEPT
#.....
-A INPUT -j REJECT --reject-with icmp6-port-unreachable

그러나 키 교환은 성공하지 못합니다. 각 측은 UDP 패킷을 계속해서 재전송하려고 시도하고 최종적으로 포기할 때까지 응답을 듣지 않습니다.

tcpdump한쪽 끝에서 시작 하여 UDP 패킷이 조각화되고 있고 두 번째 조각이 들어온 후 도달 할 수없는 ICMP 포트가 반환되는 것을 관찰했습니다.

그러한 실패한 교환의 예 (귀하의 보호를 위해 위생 처리됨) :

04:00:43.311572 IP6 (hlim 51, next-header Fragment (44) payload length: 1240) 2001:db8::be6b:d879 > 2001:db8:f:608::2: frag (0x5efa507c:0|1232) ipsec-nat-t > ipsec-nat-t: NONESP-encap: isakmp 2.0 msgid 00000001 cookie 55fa7f39522011ef->f8259707aad5f995: child_sa  ikev2_auth[I]: [|v2e] (len mismatch: isakmp 1596/ip 1220)
04:00:43.311597 IP6 (hlim 51, next-header Fragment (44) payload length: 384) 2001:db8::be6b:d879 > 2001:db8:f:608::2: frag (0x5efa507c:1232|376)
04:00:43.311722 IP6 (hlim 64, next-header ICMPv6 (58) payload length: 432) 2001:db8:f:608::2 > 2001:db8::be6b:d879: [icmp6 sum ok] ICMP6, destination unreachable, length 432, unreachable port[|icmp6]

방화벽은이 패킷과 관련하여 다음을 기록했습니다.

Aug 26 04:00:43 grummle kernel: iptables: REJECT IN=eth0 OUT= MAC=############### SRC=2001:0db8:0000:0000:0000:0000:be6b:d879 DST=2001:0db8:000f:0608:0000:0000:0000:0002 LEN=424 TC=0 HOPLIMIT=51 FLOWLBL=0 OPT ( FRAG:1232 ID:5efa507c ) PROTO=UDP

나는 리눅스가 프래그먼트를 패킷 필터로 전달하기 전에 자동으로 재 조립했다는 인상을 받았다. 그렇다면 왜이 조각들이 재 조립되지 않아서 두 번째 조각이 거부됩니까?


참고로 IME는 ESP도 허용해야합니다.iptables -A INPUT -p esp -j ACCEPT
fukawi2

@ fukawi2 네,하지만이 질문과 관련이 없습니다.
Michael Hampton

답변:


14

방화벽 규칙이 연결 추적을 사용하는 경우 (즉, 방화벽 규칙이 상태 저장이고 사용 -m conntrack되지 -m state않거나 더 이상 사용되지 않음 ) 또는 NAT 인 경우 netfilter 코드는 패킷 필터링 전에 조각을 리 어셈블 합니다 . 그렇지 않으면 모든 조각이 별도로 처리되며 이와 같은 문제가 발생합니다.

이를 통해 문제를 쉽고 명확하게 해결할 수 있습니다 (어쨌든). 문제의 방화벽 규칙에 연결 추적을 추가하기 만하면됩니다.

-A INPUT -m conntrack --ctstate ESTABLISHED,RELATED -j ACCEPT
-A INPUT -m conntrack --ctstate NEW -m udp -p udp --dport 500 -j ACCEPT
-A INPUT -m conntrack --ctstate NEW -m udp -p udp --dport 4500 -j ACCEPT

또는 이전 Linux 시스템 (예 : RHEL 5 이하) :

-A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT
-A INPUT -m state --state NEW -m udp -p udp --dport 500 -j ACCEPT
-A INPUT -m state --state NEW -m udp -p udp --dport 4500 -j ACCEPT
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.