배경, 오랫동안 방화벽에 문제가있어 TCP 요청 시간이 초과 될 때까지 HTTP 요청이 부분적으로로드되는 경우가 있습니다.
방화벽에서 트래픽을 추적 한 후 클라이언트가 페이로드에서 두 번째 ACK를 전송하기 전에 웹 서버가 전체 응답을 보낸 경우와 같이 특정 타이밍 조건에서만 발생하는 것으로 나타났습니다. [SYN, SYN / ACK, ACK]가 교환되고, REQUEST가 전송되고 ACK되고 첫 번째 RESPONSE 패킷이 수신되고 ACK 된 후 웹 서버는 나머지 응답 본문을 한 번에 전송합니다 (8 패킷) 마지막 FIN, PSH를 포함하여) 클라이언트가 그 중 하나를 ACK하기 전에 방화벽은 웹 서버를 향한 RST로 거부하고 클라이언트를 무한정 행합니다.
다음은 방화벽 양쪽의 패킷이 포함 된 전체 wireshark 추적입니다. 192.168.126.161은 클라이언트의 개인 NAT'et IP 주소입니다. 172.16.1.2는 웹 서버 IP (실제 공개 IP를 표시하지 않음)이고 10.1.1.1은 방화벽 외부 IP (실제 공개 IP를 표시하지 않음)입니다
2105 0.086275 192.168.126.161 172.16.1.2 TCP 37854 > http [SYN] Seq=0 Win=5840 Len=0 MSS=1460 SACK_PERM=1 TSV=89375083 TSER=0
2106 0.000066 10.1.1.1 172.16.1.2 TCP 37854 > http [SYN] Seq=0 Win=5840 Len=0 MSS=1460 SACK_PERM=1 TSV=89375083 TSER=0
2107 0.002643 172.16.1.2 10.1.1.1 TCP http > 37854 [SYN, ACK] Seq=0 Ack=1 Win=32768 Len=0 MSS=1460
2108 0.007705 172.16.1.2 192.168.126.161 TCP http > 37854 [SYN, ACK] Seq=0 Ack=1 Win=32768 Len=0 MSS=1460
2109 0.006301 192.168.126.161 172.16.1.2 TCP 37854 > http [ACK] Seq=1 Ack=1 Win=5840 Len=0
2110 0.000025 10.1.1.1 172.16.1.2 TCP 37854 > http [ACK] Seq=1 Ack=1 Win=5840 Len=0
2111 0.000007 192.168.126.161 172.16.1.2 HTTP GET /test/style.css HTTP/1.1
2112 0.000015 10.1.1.1 172.16.1.2 HTTP GET /test/style.css HTTP/1.1
2113 0.001536 172.16.1.2 10.1.1.1 TCP http > 37854 [ACK] Seq=1 Ack=111 Win=32658 Len=0
2114 0.000014 172.16.1.2 192.168.126.161 TCP http > 37854 [ACK] Seq=1 Ack=111 Win=32658 Len=0
2115 0.002274 172.16.1.2 10.1.1.1 HTTP HTTP/1.1 200 OK (text/css)
2116 0.000025 172.16.1.2 192.168.126.161 HTTP HTTP/1.1 200 OK (text/css)
2117 0.005689 192.168.126.161 172.16.1.2 TCP 37854 > http [ACK] Seq=111 Ack=1461 Win=8760 Len=0
2118 0.000024 10.1.1.1 172.16.1.2 TCP 37854 > http [ACK] Seq=111 Ack=1461 Win=8760 Len=0
2119 0.001536 172.16.1.2 10.1.1.1 HTTP Continuation or non-HTTP traffic
2120 0.000026 172.16.1.2 192.168.126.161 HTTP Continuation or non-HTTP traffic
2121 0.000007 172.16.1.2 10.1.1.1 HTTP Continuation or non-HTTP traffic
2122 0.000023 172.16.1.2 192.168.126.161 HTTP Continuation or non-HTTP traffic
2123 0.000313 172.16.1.2 10.1.1.1 HTTP Continuation or non-HTTP traffic
2124 0.000030 172.16.1.2 192.168.126.161 HTTP Continuation or non-HTTP traffic
2125 0.000007 172.16.1.2 10.1.1.1 HTTP Continuation or non-HTTP traffic
2126 0.000023 172.16.1.2 192.168.126.161 HTTP Continuation or non-HTTP traffic
2127 0.000009 172.16.1.2 10.1.1.1 HTTP Continuation or non-HTTP traffic
2128 0.000023 172.16.1.2 192.168.126.161 HTTP Continuation or non-HTTP traffic
2129 0.001108 172.16.1.2 10.1.1.1 HTTP Continuation or non-HTTP traffic
2130 0.000035 172.16.1.2 192.168.126.161 HTTP Continuation or non-HTTP traffic
2131 0.000008 172.16.1.2 10.1.1.1 HTTP Continuation or non-HTTP traffic
2132 0.000022 172.16.1.2 192.168.126.161 HTTP Continuation or non-HTTP traffic
2133 0.000007 172.16.1.2 10.1.1.1 HTTP Continuation or non-HTTP traffic
REJECT-->
2134 0.000089 10.1.1.1 172.16.1.2 TCP 37854 > http [RST] Seq=111 Win=0 Len=0
CLIENT FIRST ACK-->
2135 0.002421 192.168.126.161 172.16.1.2 TCP 37854 > http [ACK] Seq=111 Ack=2921 Win=11680 Len=0
2136 0.000033 10.1.1.1 172.16.1.2 TCP 37854 > http [ACK] Seq=111 Ack=2921 Win=11680 Len=0
2137 0.000007 192.168.126.161 172.16.1.2 TCP 37854 > http [ACK] Seq=111 Ack=4381 Win=14600 Len=0
2138 0.000014 10.1.1.1 172.16.1.2 TCP 37854 > http [ACK] Seq=111 Ack=4381 Win=14600 Len=0
2139 0.000008 192.168.126.161 172.16.1.2 TCP 37854 > http [ACK] Seq=111 Ack=5841 Win=17520 Len=0
2140 0.000014 10.1.1.1 172.16.1.2 TCP 37854 > http [ACK] Seq=111 Ack=5841 Win=17520 Len=0
2141 0.000007 192.168.126.161 172.16.1.2 TCP 37854 > http [ACK] Seq=111 Ack=7301 Win=20440 Len=0
2142 0.000013 10.1.1.1 172.16.1.2 TCP 37854 > http [ACK] Seq=111 Ack=7301 Win=20440 Len=0
2143 0.000007 192.168.126.161 172.16.1.2 TCP 37854 > http [ACK] Seq=111 Ack=8761 Win=23360 Len=0
2144 0.000015 10.1.1.1 172.16.1.2 TCP 37854 > http [ACK] Seq=111 Ack=8761 Win=23360 Len=0
2145 0.000007 192.168.126.161 172.16.1.2 TCP 37854 > http [ACK] Seq=111 Ack=10221 Win=26280 Len=0
2146 0.000013 10.1.1.1 172.16.1.2 TCP 37854 > http [ACK] Seq=111 Ack=10221 Win=26280 Len=0
2147 0.001059 192.168.126.161 172.16.1.2 TCP 37854 > http [ACK] Seq=111 Ack=11681 Win=29200 Len=0
2148 0.000018 10.1.1.1 172.16.1.2 TCP 37854 > http [ACK] Seq=111 Ack=11681 Win=29200 Len=0
나는이 차트 에 따라 패킷 순회를 파고 로깅하고 있으며 마지막 수신 패킷 2133은 원시 PROUTING, conntrack, mangle-PREROUTING을 지나서 사라지는 것처럼 보입니다. 내 iptables에 거부 규칙이 없으며 모든 DROP 규칙을 기록하며 패킷 2133이 손실되는 위치를 표시하지 않습니다.
들어오는 필터에서 TRACE 대상을 사용하고 싶지만 불행히도 우분투 8.04는 TRACE 대상을 지원하지 않습니다.
따라서 일부 내부 암시 적 라우팅 / 콘 트랙 / 맨 글링 규칙이 어떤 이유로 연결을 재설정하는 규칙이 적용된다고 생각합니다. 트래픽이 일부 DOS 보호를 트리거 할 수 있지만 어디서 구성 / 분석해야할지 모르겠습니다. 가장 실망스러운 것은 패킷이 거부되고 아무것도 기록되지 않는다는 것입니다.
또한이 파일을 요청하면 Windows 호스트에서 100 % 작동하지만 특정 Linux 호스트에서는 실패하고 모든 요청의 99.9 %가 통과하지만 때로는 패킷 타이밍으로 인해 방화벽 에서이 동작이 트리거됩니다.
편집 Ok, 이제 iptables에 수많은 로깅을 추가했으며 다음과 같은 일이 발생합니다 (아직도 이유를 모르겠습니다!)
방화벽을 성공적으로 통과하는 패킷의 경우 여기에서 다음 단계, 테이블 / 단계 참조가 수행 됩니다.
Table 3-3 step
2 raw-pre
conntrack
3 mangle-pre
4 [nat-pre]
5 routing-decision -> destination forward
6 mangle-fwd
7 filter-fwd
8 mangle-post
9 [nat-post]
거부 된 패킷 2133은 다음 단계를 통과합니다.
Table 3-1 steps for the incoming FIN,ACK packet 2133
2 raw-pre
conntrack
3 mangle-pre
4 [nat-pre]
5 routing-decision -> destination local
6 mangle-input
7 filter-input
8 local process emits RST -> webserver
Table 3-2 steps for the outgoing RST packet 2134 in response to 2133
1 raw-out
2 routing decision
conntrack
3 mangle-out
reroute-check
4 [nat-out]
5 filter-out
6 mangle-post
7 nat-post
이상한 것은 5 단계에서 패킷 (2133)에 대한 라우팅 결정이 다른 패킷에 대한 라우팅 결정과 다르다는 것이다. 작동하지 않는 요청 (예 : 중단되지 않은 요청)을 분석 할 때 마지막 FIN도 올바르게 라우팅됩니다. 커널의 버그 또는 라우팅 결정이 어떤 식 으로든 상태 저장되어있는 것 같습니다.
편집하다
이러한 문제를 일으킬 수있는 한 가지 이유는 트래픽이 방화벽과 로컬 LAN간에 라우팅되므로 클라이언트 LAN은 L2를 통해 방화벽에 직접 연결되지 않습니다.
+---------------------------+ +------------------+ +------------------------+
| | | Router | ( Lab network ) | |
( Internet ) -- + eth1 eth0 +-------+ +-- ( ) -+ Client 192.168.126.161 |
| 10.1.1.1 192.168.60.254 | | | ( 192.168.126.0/24 ) | |
+---------------------------+ +------------------+ +------------------------+
이 그림에서 10.1.1.1은 방화벽의 외부 IP 주소를 나타내고 다른 모든 주소는 사용 된 실제 IP 주소입니다.
방화벽의 라우팅 테이블은 다음과 같습니다.
Destination Gateway Genmask Flags Metric Ref Use Iface
10.1.1.0 0.0.0.0 255.255.255.240 U 0 0 0 eth1
192.168.126.0 0.0.0.0 255.255.255.0 U 0 0 0 eth0
192.168.60.0 0.0.0.0 255.255.255.0 U 0 0 0 eth0
0.0.0.0 10.1.1.15 0.0.0.0 UG 0 0 0 eth1
10.1.1.0 및 기본 gw 10.1.1.15가 구성되고 나머지는 사용 된 것과 정확히 동일합니다. eth0 (192.168.60.254)에서 실험실 네트워크에 도달하려면 192.168.126.0/24 경로를 수동으로 추가해야했습니다.
다음은 로컬 호스트 (예 : 방화벽)로 라우팅되어 거부 된 마지막 패킷 2133의 패킷 통과에 대한 광범위한 로그입니다.
[16406874.374588] raw pre IN=eth1 OUT= MAC=00:02:b3:b9:ff:b5:00:90:1a:10:06:88:08:00 SRC=172.16.1.2 DST=10.1.1.1 LEN=1004 TOS=0x00 PREC=0x00 TTL=55 ID=13739 DF PROTO=TCP SPT=80 DPT=53497 WINDOW=5840 RES=0x00 ACK PSH FIN URGP=0
[16406874.374625] mangle pre IN=eth1 OUT= MAC=00:02:b3:b9:ff:b5:00:90:1a:10:06:88:08:00 SRC=172.16.1.2 DST=10.1.1.1 LEN=1004 TOS=0x00 PREC=0x00 TTL=55 ID=13739 DF PROTO=TCP SPT=80 DPT=53497 WINDOW=5840 RES=0x00 ACK PSH FIN URGP=0
[16406874.374667] mangle in IN=eth1 OUT= MAC=00:02:b3:b9:ff:b5:00:90:1a:10:06:88:08:00 SRC=172.16.1.2 DST=10.1.1.1 LEN=1004 TOS=0x00 PREC=0x00 TTL=55 ID=13739 DF PROTO=TCP SPT=80 DPT=53497 WINDOW=5840 RES=0x00 ACK PSH FIN URGP=0
[16406874.374699] filter in IN=eth1 OUT= MAC=00:02:b3:b9:ff:b5:00:90:1a:10:06:88:08:00 SRC=172.16.1.2 DST=10.1.1.1 LEN=1004 TOS=0x00 PREC=0x00 TTL=55 ID=13739 DF PROTO=TCP SPT=80 DPT=53497 WINDOW=5840 RES=0x00 ACK PSH FIN URGP=0
[16406874.374780] mangle out IN= OUT=eth1 SRC=10.1.1.1 DST=172.16.1.2 LEN=40 TOS=0x00 PREC=0x00 TTL=64 ID=0 DF PROTO=TCP SPT=53497 DPT=80 WINDOW=0 RES=0x00 RST URGP=0
[16406874.374807] mangle post IN= OUT=eth1 SRC=10.1.1.1 DST=172.16.1.2 LEN=40 TOS=0x00 PREC=0x00 TTL=64 ID=0 DF PROTO=TCP SPT=53497 DPT=80 WINDOW=0 RES=0x00 RST URGP=0
[16406874.378813] mangle pre IN=eth0 OUT= MAC=00:02:b3:b9:ff:b4:00:90:1a:10:0c:dd:08:00 SRC=192.168.126.161 DST=172.16.1.2 LEN=40 TOS=0x00 PREC=0x00 TTL=63 ID=35424 DF PROTO=TCP SPT=53497 DPT=80 WINDOW=11680 RES=0x00 ACK URGP=0
[16406874.378863] mangle fwd IN=eth0 OUT=eth1 SRC=192.168.126.161 DST=172.16.1.2 LEN=40 TOS=0x00 PREC=0x00 TTL=62 ID=35424 DF PROTO=TCP SPT=53497 DPT=80 WINDOW=11680 RES=0x00 ACK URGP=0
다시 한번, 우리의 fw 외부 IP는 10.1.1.1로 대체되었고 NAT의 네트워크 외부의 웹 서버의 IP는 172.16.1.2로 대체되었습니다.
속보 편집!
마지막 시도는 RST 패킷을 삭제하는 것이 었습니다. 매우 흥미 롭습니다. 파일 요청에 문제가있는 웹 서버로 향하는 모든 RST 패킷을 삭제하는 iptables 규칙을 추가했습니다. 그리고이 일을 , 삭제 위의 로그에 마지막 FIN, ACK, PSH 패킷 2133을 예,하지만 RST이 삭제되기 때문에 웹 서버는 ACK의 개미가 다음 마지막 패킷을 retransmitt하기로 결정 모든 패킷 2133 다시 한 번 얻을 수있는 시간이 이제 contrack 모듈이 ACK가 클라이언트에서 되돌아오고 마지막 페이로드와 함께 마지막 ACK, FIN 패킷을 허용하므로 방화벽을 통과합니다.
따라서 타이밍 / 창 문제입니다.이 특정 파일은 클라이언트의 ACK 타이밍과 함께 웹 서버에서 최종 패킷을 거부하는 conntrack에서 무언가를 트리거합니다.
지금까지 인터넷 문서를 읽고 읽고 커널 문서를 읽으면이 동작을 유발할 수있는 것이 아무것도 없습니다. 다음 단계는 라우팅 / conntrack 모듈의 커널 소스 코드를 읽는 것입니다.
문제 해결됨
글쎄, 적어도 지금 우리는 무슨 일이 일어나는지 정확히 알고 문제를 해결하는 해결 방법이 있습니다.
Sergey는 디버깅에 많은 도움이 된 매우 중요한 -m state --state INVALID 일치 규칙을 지적했으며, 이제 INVALID 패킷에 대한 명시적인 규칙이없는 iptables 설정이 완료되지 않았기 때문에 이상한 동작이 때때로 발생하는 것으로 보입니다.
잘못된 패킷을 일으키는 원인에 대해 conntrack 모듈에서 로깅을 활성화하면 그 결과가 매우 명백하며 이에 대해 의심을 가졌습니다.
[16659529.322465] nf_ct_tcp: SEQ is over the upper bound (over the window of the receiver) IN= OUT= SRC=172.16.1.2 DST=10.1.1.1 LEN=1004 TOS=0x00 PREC=0x00 TTL=55 ID=40874 DF PROTO=TCP SPT=80 DPT=55498 SEQ=658735108 ACK=1194081763 WINDOW=5840 RES=0x00 ACK PSH FIN URGP=0
다시 한 번, 172.16.1.2는 외부 웹 서버 (잘못된 동작)이고 10.1.1.1은 방화벽의 외부 주소입니다.
웹 서버가 클라이언트가 수신 창에서 보급 한 것보다 많은 데이터를 유선으로 푸시합니다 (conntrack이 상태가 가득 차서 이것을 확인합니다). 수신 창이 실제로 초과되어 FIN 패킷이 도착하면 conntrack이 사라지는 것처럼 보입니다. 일찍이.
웹 서버의 네트워크 카드에서 잘못된 TCP 오프로드로 인해 발생할 수 있다고 생각합니다. 이것을 분석하기 시작했을 때 나는 웹 서버에서 캡처를했고 tcpdump / wireshark 추적에 따르면 점보 프레임은 커널의 TCP 계층에 의해 작성된 다음 네트워크 카드에 의해 MTU = 1500으로 작은 프레임으로 분할되었습니다. 따라서 수신자가 수신 창에 adverties보다 많은 데이터를 보내는 것이 올바른 TCP 동작이 아니기 때문에 웹 서버에서 주소를 지정해야합니다.
Polynomial과 Sergey는 모두 귀중한 정보를 제공했지만 Sergey는 패킷 통과와 관련하여 conntrack / NAT 모듈의 정확한 동작을 알려주었습니다.