IPv4 中的 IPv6 GRE 隧道中 ACK 数据包丢失

IPv4 中的 IPv6 GRE 隧道中 ACK 数据包丢失

在家里(79.1.1.156),我的 ISP 不提供 IPv6,因此我将我的服务器通过 GRE 隧道连接到具有 IPv6 访问权限的外部服务器(95.1.1.126),使用以下简单设置:

ip tunnel add gretun mode gre ttl 255 local 79.1.1.156 remote 95.1.1.126 pmtudisc
ip link set dev gretun up

ip -6 addr add fd12:3456:789a:1::2 dev gretun
ip -6 route add fd12:3456:789a:1::1/128 dev gretun metric 1

我为家庭服务器分配了 IP6 地址fd12:3456:789a:1::2,为外部服务器分配了 IP6 地址fd12:3456:789a:1::1。外部服务器具有相同的配置交换 IP。

从一台服务器 ping 另一台服务器一切正常。问题出在 TCP 上,看起来“第 2 个 ACK​​”(TCP 三次握手的第 3 步)被丢弃了,从未到达目的地。

在服务器(95.1.1.126)上我运行:

socat - tcp6-listen:3000

然后在客户端(79.1.1.156)上运行:

telnet fd12:3456:789a:1::1 3000
Trying fd12:3456:789a:1::1...
Connected to fd12:3456:789a:1::1.
Escape character is '^]'.
aaaaa
aaaaa
^]quit

从客户端我可以看到(我添加了>>服务器端缺少的 ACK 数据包,注意服务器如何继续发送 SYN-ACK):

02:46:42.063091 IP 79.1.1.156 > 95.1.1.126: GREv0, length 84: IP6 fd12:3456:789a:1::2.43704 > fd12:3456:789a:1::1.3000: Flags [S], seq 2473235054, win 28160, options [mss 1408,sackOK,TS val 1651249830 ecr 0,nop,wscale 7], length 0
02:46:42.129852 IP 95.1.1.126 > 79.1.1.156: GREv0, length 84: IP6 fd12:3456:789a:1::1.3000 > fd12:3456:789a:1::2.43704: Flags [S.], seq 3770099713, ack 2473235055, win 28080, options [mss 1416,sackOK,TS val 2610159587 ecr 1651249830,nop,wscale 7], length 0
>> 02:46:42.129897 IP 79.1.1.156 > 95.1.1.126: GREv0, length 76: IP6 fd12:3456:789a:1::2.43704 > fd12:3456:789a:1::1.3000: Flags [.], ack 1, win 220, options [nop,nop,TS val 1651249897 ecr 2610159587], length 0
02:46:43.131703 IP 95.1.1.126 > 79.1.1.156: GREv0, length 84: IP6 fd12:3456:789a:1::1.3000 > fd12:3456:789a:1::2.43704: Flags [S.], seq 3770099713, ack 2473235055, win 28080, options [mss 1416,sackOK,TS val 2610160589 ecr 1651249830,nop,wscale 7], length 0
>> 02:46:43.131835 IP 79.1.1.156 > 95.1.1.126: GREv0, length 76: IP6 fd12:3456:789a:1::2.43704 > fd12:3456:789a:1::1.3000: Flags [.], ack 1, win 220, options [nop,nop,TS val 1651250899 ecr 2610159587], length 0
02:46:43.354503 IP 79.1.1.156 > 95.1.1.126: GREv0, length 83: IP6 fd12:3456:789a:1::2.43704 > fd12:3456:789a:1::1.3000: Flags [P.], seq 1:8, ack 1, win 220, options [nop,nop,TS val 1651251122 ecr 2610159587], length 7
02:46:43.626815 IP 79.1.1.156 > 95.1.1.126: GREv0, length 83: IP6 fd12:3456:789a:1::2.43704 > fd12:3456:789a:1::1.3000: Flags [P.], seq 1:8, ack 1, win 220, options [nop,nop,TS val 1651251394 ecr 2610159587], length 7
02:46:43.914770 IP 79.1.1.156 > 95.1.1.126: GREv0, length 83: IP6 fd12:3456:789a:1::2.43704 > fd12:3456:789a:1::1.3000: Flags [P.], seq 1:8, ack 1, win 220, options [nop,nop,TS val 1651251682 ecr 2610159587], length 7
02:46:44.458751 IP 79.1.1.156 > 95.1.1.126: GREv0, length 83: IP6 fd12:3456:789a:1::2.43704 > fd12:3456:789a:1::1.3000: Flags [P.], seq 1:8, ack 1, win 220, options [nop,nop,TS val 1651252226 ecr 2610159587], length 7
02:46:45.147699 IP 95.1.1.126 > 79.1.1.156: GREv0, length 84: IP6 fd12:3456:789a:1::1.3000 > fd12:3456:789a:1::2.43704: Flags [S.], seq 3770099713, ack 2473235055, win 28080, options [mss 1416,sackOK,TS val 2610162605 ecr 1651249830,nop,wscale 7], length 0
>> 02:46:45.147800 IP 79.1.1.156 > 95.1.1.126: GREv0, length 76: IP6 fd12:3456:789a:1::2.43704 > fd12:3456:789a:1::1.3000: Flags [.], ack 1, win 220, options [nop,nop,TS val 1651252915 ecr 2610159587], length 0
02:46:45.546762 IP 79.1.1.156 > 95.1.1.126: GREv0, length 83: IP6 fd12:3456:789a:1::2.43704 > fd12:3456:789a:1::1.3000: Flags [P.], seq 1:8, ack 1, win 220, options [nop,nop,TS val 1651253314 ecr 2610159587], length 7
02:46:47.818801 IP 79.1.1.156 > 95.1.1.126: GREv0, length 83: IP6 fd12:3456:789a:1::2.43704 > fd12:3456:789a:1::1.3000: Flags [P.], seq 1:8, ack 1, win 220, options [nop,nop,TS val 1651255586 ecr 2610159587], length 7
02:46:49.211726 IP 95.1.1.126 > 79.1.1.156: GREv0, length 84: IP6 fd12:3456:789a:1::1.3000 > fd12:3456:789a:1::2.43704: Flags [S.], seq 3770099713, ack 2473235055, win 28080, options [mss 1416,sackOK,TS val 2610166669 ecr 1651249830,nop,wscale 7], length 0
>> 02:46:49.211807 IP 79.1.1.156 > 95.1.1.126: GREv0, length 76: IP6 fd12:3456:789a:1::2.43704 > fd12:3456:789a:1::1.3000: Flags [.], ack 1, win 220, options [nop,nop,TS val 1651256979 ecr 2610159587], length 0
02:46:49.367297 IP 79.1.1.156 > 95.1.1.126: GREv0, length 83: IP6 fd12:3456:789a:1::2.43704 > fd12:3456:789a:1::1.3000: Flags [FP.], seq 8:15, ack 1, win 220, options [nop,nop,TS val 1651257134 ecr 2610159587], length 7
02:46:52.170758 IP 79.1.1.156 > 95.1.1.126: GREv0, length 90: IP6 fd12:3456:789a:1::2.43704 > fd12:3456:789a:1::1.3000: Flags [FP.], seq 1:15, ack 1, win 220, options [nop,nop,TS val 1651259938 ecr 2610159587], length 14
02:46:52.738281 IP 95.1.1.126 > 79.1.1.156: GREv0, length 76: IP6 fd12:3456:789a:1::1.3000 > fd12:3456:789a:1::2.43704: Flags [F.], seq 1, ack 16, win 228, options [nop,nop,TS val 2610170196 ecr 1651259938], length 0
02:46:52.738361 IP 79.1.1.156 > 95.1.1.126: GREv0, length 76: IP6 fd12:3456:789a:1::2.43704 > fd12:3456:789a:1::1.3000: Flags [.], ack 2, win 220, options [nop,nop,TS val 1651260506 ecr 2610170196], length 0

在服务器上时,我从未收到客户端的 TCP 三次握手的“ACK”(我添加了>>应该收到“ACK”的位置):

11:46:42.095788 IP 79.1.1.156 > 95.1.1.126: GREv0, length 84: IP6 fd12:3456:789a:1::2.43704 > fd12:3456:789a:1::1.3000: Flags [S], seq 2473235054, win 28160, options [mss 1408,sackOK,TS val 1651249830 ecr 0,nop,wscale 7], length 0
11:46:42.096254 IP 95.1.1.126 > 79.1.1.156: GREv0, length 84: IP6 fd12:3456:789a:1::1.3000 > fd12:3456:789a:1::2.43704: Flags [S.], seq 3770099713, ack 2473235055, win 28080, options [mss 1416,sackOK,TS val 2610159587 ecr 1651249830,nop,wscale 7], length 0
>>
11:46:43.098129 IP 95.1.1.126 > 79.1.1.156: GREv0, length 84: IP6 fd12:3456:789a:1::1.3000 > fd12:3456:789a:1::2.43704: Flags [S.], seq 3770099713, ack 2473235055, win 28080, options [mss 1416,sackOK,TS val 2610160589 ecr 1651249830,nop,wscale 7], length 0
>>
11:46:45.114065 IP 95.1.1.126 > 79.1.1.156: GREv0, length 84: IP6 fd12:3456:789a:1::1.3000 > fd12:3456:789a:1::2.43704: Flags [S.], seq 3770099713, ack 2473235055, win 28080, options [mss 1416,sackOK,TS val 2610162605 ecr 1651249830,nop,wscale 7], length 0
>>
11:46:49.178098 IP 95.1.1.126 > 79.1.1.156: GREv0, length 84: IP6 fd12:3456:789a:1::1.3000 > fd12:3456:789a:1::2.43704: Flags [S.], seq 3770099713, ack 2473235055, win 28080, options [mss 1416,sackOK,TS val 2610166669 ecr 1651249830,nop,wscale 7], length 0
>>
11:46:49.399856 IP 79.1.1.156 > 95.1.1.126: GREv0, length 83: IP6 fd12:3456:789a:1::2.43704 > fd12:3456:789a:1::1.3000: Flags [FP.], seq 8:15, ack 1, win 220, options [nop,nop,TS val 1651257134 ecr 2610159587], length 7
11:46:49.400046 IP 95.1.1.126 > 79.1.1.156: GREv0, length 88: IP6 fd12:3456:789a:1::1.3000 > fd12:3456:789a:1::2.43704: Flags [.], ack 1, win 228, options [nop,nop,TS val 2610166891 ecr 1651249830,nop,nop,sack 1 {8:16}], length 0
11:46:52.203490 IP 79.1.1.156 > 95.1.1.126: GREv0, length 90: IP6 fd12:3456:789a:1::2.43704 > fd12:3456:789a:1::1.3000: Flags [FP.], seq 1:15, ack 1, win 220, options [nop,nop,TS val 1651259938 ecr 2610159587], length 14
11:46:52.246072 IP 95.1.1.126 > 79.1.1.156: GREv0, length 76: IP6 fd12:3456:789a:1::1.3000 > fd12:3456:789a:1::2.43704: Flags [.], ack 16, win 228, options [nop,nop,TS val 2610169737 ecr 1651259938], length 0
11:46:52.704683 IP 95.1.1.126 > 79.1.1.156: GREv0, length 76: IP6 fd12:3456:789a:1::1.3000 > fd12:3456:789a:1::2.43704: Flags [F.], seq 1, ack 16, win 228, options [nop,nop,TS val 2610170196 ecr 1651259938], length 0
11:46:52.770338 IP 79.1.1.156 > 95.1.1.126: GREv0, length 76: IP6 fd12:3456:789a:1::2.43704 > fd12:3456:789a:1::1.3000: Flags [.], ack 2, win 220, options [nop,nop,TS val 1651260506 ecr 2610170196], length 0

在关闭客户端连接几秒钟后,运行“socat”的服务器会打印从客户端发送的信息并关闭套接字。这个“几秒钟”是客户端之间的间隔2:46:492:46:52添加 +9h 作为服务器时间戳)。看起来尽管从未收到来自客户端的 ACK,但服务器在关闭连接时仍会处理其余数据包,但这不适用于 HTTP 连接。

如果我反转客户端/服务器角色(在远程服务器上运行 telnet 并在主服务器上运行 socat),也会发生此问题

如果我在 GRE 隧道内使用 IPv4 地址,则不会发生此问题。

我已经尝试过运行 Debian(内核 4.19)和 Ubuntu(内核 5.0)的两台电脑,问题是一样的。

相同的配置在直接连接到 Internet 的两台服务器之间工作正常。这里的主要区别在于,我通过在我的家庭服务器 (79.1.1.156) 中设置的 PPPoE 连接连接到我的 ISP,因此我们有 PPPoE > GRE > IPv6。

相关内容