UDP/ICMP가 정책 라우팅 설정을 사용할 때 TCP 연결이 실패하는 이유는 무엇입니까?

UDP/ICMP가 정책 라우팅 설정을 사용할 때 TCP 연결이 실패하는 이유는 무엇입니까?

해결할 수 없는 매우 까다로운 문제가 있습니다. 내 목표는 기본 경로 테이블을 별도의 테이블에 배치하고(나중에 여러 테이블에 여러 기본 경로를 가질 수 있도록) 정책에 따라 선택하여 기본 게이트웨이에서 분리하는 것입니다.

이 단순화된 예에서는 두 개의 인터페이스만 있습니다. eth0.2는 WAN(공용 IP가 있는 DSL)이고 eth0.3은 LAN입니다.

$ ip -4 addr
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000
    inet 127.0.0.1/8 scope host lo
       valid_lft forever preferred_lft forever
3: vrf_sonic: <NOARP,MASTER,UP,LOWER_UP> mtu 65575 qdisc noqueue state UP group default qlen 1000
    inet 127.0.0.1/8 brd 127.255.255.255 scope host vrf_sonic
       valid_lft forever preferred_lft forever
5: eth0.2@eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue master vrf_sonic state UP group default qlen 1000
    inet 192.184.144.21/21 brd 192.184.151.255 scope global dynamic eth0.2
       valid_lft 19730sec preferred_lft 19730sec
6: eth0.3@eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default qlen 1000
    inet 10.227.79.2/24 brd 10.227.79.255 scope global eth0.3
       valid_lft forever preferred_lft forever

eth0.2의 기본 경로는 DHCP를 통해 동적으로 할당되므로 인터페이스/DHCP 인스턴스에서 VRF를 사용합니다. 내 기본 경로는 표 170에 있는 것으로 나타났습니다.

$ sudo ip vrf
Name              Table
-----------------------
vrf_sonic          170
$ sudo ip route show table 170
default nhid 38 via 192.184.144.1 dev eth0.2 proto static metric 20
broadcast 127.0.0.0 dev vrf_sonic proto kernel scope link src 127.0.0.1
127.0.0.0/8 dev vrf_sonic proto kernel scope link src 127.0.0.1
local 127.0.0.1 dev vrf_sonic proto kernel scope host src 127.0.0.1
broadcast 127.255.255.255 dev vrf_sonic proto kernel scope link src 127.0.0.1
broadcast 192.184.144.0 dev eth0.2 proto kernel scope link src 192.184.144.21
192.184.144.0/21 dev eth0.2 proto kernel scope link src 192.184.144.21
local 192.184.144.21 dev eth0.2 proto kernel scope host src 192.184.144.21
broadcast 192.184.151.255 dev eth0.2 proto kernel scope link src 192.184.144.21

내 기본 테이블에는 많은 OSPF 경로가 포함되지만 현재는 하나만 포함됩니다.

$ sudo ip route show table main
10.227.79.0/24 dev eth0.3 proto kernel scope link src 10.227.79.2

이제 내 규칙은 다음과 같습니다.

$ sudo ip rule
101:    from all lookup local
102:    from all lookup main
104:    from all lookup vrf_sonic
1000:   from all lookup [l3mdev-table]
2000:   from all lookup [l3mdev-table] unreachable

먼저 로컬 테이블(=직접 연결된 인터페이스)을 확인합니다. 그런 다음 기본 라우팅 테이블이 있습니다. 그런 다음 vrf_sonic에는 기본 경로(기본적으로 catch-all)가 포함됩니다. 규칙 1000/2000은 자동으로 삽입되지만(VRF로 인해) 포괄적인 규칙 104로 인해 절대 사용해서는 안 됩니다.

모든 방화벽 테이블은 ACCEPT 상태이고, mangle 테이블은 비어 있고, nat 테이블도 비어 있습니다.

여태까지는 그런대로 잘됐다. ICMP(ping) 작동 방식:

$ ping 142.250.189.164
PING 142.250.189.164 56(84) bytes of data.
64 bytes from 142.250.189.164: icmp_seq=1 ttl=113 time=4.78 ms
64 bytes from 142.250.189.164: icmp_seq=2 ttl=113 time=4.59 ms
^C
--- 142.250.189.164 ping statistics ---
2 packets transmitted, 2 received, 0% packet loss, time 4ms
rtt min/avg/max/mdev = 4.589/4.683/4.778/0.116 ms
$

이는 규칙 104를 통해 테이블 ​​170을 선택하면 예상대로 올바른 기본 경로가 선택됨을 의미합니다.

이제 미친 부분이 나옵니다.

$ telnet 142.250.189.164 80
Trying 142.250.189.164...
telnet: Unable to connect to remote host: Network is unreachable
$

이것은 WTF # 1입니다. 하지만 더 큰 WTF가 있습니다.

$ sudo ip vrf exec vrf_sonic /bin/telnet 142.250.189.164 80
Trying 142.250.189.164...
Connected to 142.250.189.164.
Escape character is '^]'.
GET / HTTP/1.0
[...]
stener("click",G)});}).call(this);</script></body></html>Connection closed by foreign host.
$

이는 vrf_sonic VRF의 맥락에서 작동한다는 것을 의미합니다. 마지막으로 (실패한) telnet과 병렬로 tcpdump를 시작했습니다.

$ sudo tcpdump -n -i eth0.2 'host 142.250.189.164'
tcpdump: verbose output suppressed, use -v or -vv for full protocol decode
listening on eth0.2, link-type EN10MB (Ethernet), capture size 262144 bytes
23:34:18.875675 IP 192.184.144.21.55124 > 142.250.189.164.80: Flags [S], seq 1179612779, win 64240, options [mss 1460,sackOK,TS val 333932630 ecr 0,nop,wscale 7], length 0
23:34:18.879471 IP 142.250.189.164.80 > 192.184.144.21.55124: Flags [S.], seq 3829270116, ack 1179612780, win 65535, options [mss 1412,sackOK,TS val 146008037 ecr 333932630,nop,wscale 8], length 0
23:34:18.879573 IP 192.184.144.21.55124 > 142.250.189.164.80: Flags [R], seq 1179612780, win 0, length 0
23:34:19.888499 IP 192.184.144.21.55124 > 142.250.189.164.80: Flags [S], seq 1179612779, win 64240, options [mss 1460,sackOK,TS val 333933643 ecr 0,nop,wscale 7], length 0
23:34:19.896597 IP 142.250.189.164.80 > 192.184.144.21.55124: Flags [S.], seq 3845107556, ack 1179612780, win 65535, options [mss 1412,sackOK,TS val 146009050 ecr 333933643,nop,wscale 8], length 0
23:34:19.896719 IP 192.184.144.21.55124 > 142.250.189.164.80: Flags [R], seq 11779612780, win 0, length 0
23:34:21.935744 IP 192.184.144.21.55124 > 142.250.189.164.80: Flags [S], seq 117], length 0n 64240, options [mss 1460,sackOK,TS val 333935690 ecr 0,nop,wscale 7
23:34:21.947596 IP 142.250.189.164.80 > 192.184.144.21.55124: Flags [S.], seq 3ecr 333935690,nop,wscale 8], length 0 options [mss 1412,sackOK,TS val 146011097 e
23:34:21.947717 IP 192.184.144.21.55124 > 142.250.189.164.80: Flags [R], seq 1179612780, win 0, length 0
^C
9 packets captured
9 packets received by filter
0 packets dropped by kernel
$

호스트가 SYN을 보내고 Google 호스트가 SYN-ACK에 응답한 다음우리 주인님보내세요...RST? ! 이것을 제대로 보기 위해 몇 번이나 눈을 비비어야 했습니다. #3은 어떻게 됐나요? ?

정말 놀랍습니다. 어떻게 그래? 여기서 무슨 일이 일어나고 있는 걸까요?

관련 정보