内核不回显 ICMP ping 包写入 tun 设备?
kernel not echo ICMP ping package written to tun device?
我正在尝试在我的 vps 上编写一个 vpn 服务器。我已经设置了 tun 接口 < tun2 >,并且可以将从网络接收的包写入服务器上的 tun 设备。但是,当我通过客户端的 ping 命令测试连通性时,服务器内核没有 ICMP 响应包。我错过了什么?
这是拓扑:
┼─────────────────┼ ┼─────────────────┼
│ client │ │ server │
┼─────────────────┼ ┼─────────────────┼
│tun0: │──────────────TCP─────────────│tun2: │
│ 192.168.255.2 │ │ 192.168.255.1 │
│ │ │ │
┼─────────────────┼ ┼─────────────────┼
这是服务器的配置:
seven@server:~$ ifconfig tun2
tun2 Link encap:UNSPEC HWaddr 00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00
inet addr:192.168.255.1 P-t-P:192.168.255.2 Mask:255.255.255.255
UP POINTOPOINT RUNNING NOARP MULTICAST MTU:1500 Metric:1
RX packets:3 errors:0 dropped:0 overruns:0 frame:0
TX packets:0 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:500
RX bytes:252 (252.0 B) TX bytes:0 (0.0 B)
seven@server:~$ ip route
10.77.88.5 dev tun0 proto kernel scope link src 10.77.88.1
10.77.99.2 dev tun1 proto kernel scope link src 10.77.99.1
192.168.255.2 dev tun2 proto kernel scope link src 192.168.255.1
10.77.99.0/24 via 10.77.99.2 dev tun1
default dev venet0 scope link
我可以看到 ICMP 回显请求通过 tcpdump 发送到服务器上的 tun2,但没有响应:
seven@server:~$ sudo tcpdump -n -vvv -i tun2
tcpdump: listening on tun2, link-type RAW (Raw IP), capture size 262144 bytes
11:15:08.046578 IP (tos 0x0, ttl 64, id 63330, offset 0, flags [DF], proto ICMP (1), length 84)
192.168.255.2 > 192.168.255.1: ICMP echo request, id 7392, seq 1, length 64
11:15:09.073521 IP (tos 0x0, ttl 64, id 63527, offset 0, flags [DF], proto ICMP (1), length 84)
192.168.255.2 > 192.168.255.1: ICMP echo request, id 7392, seq 2, length 64
11:15:10.097919 IP (tos 0x0, ttl 64, id 63632, offset 0, flags [DF], proto ICMP (1), length 84)
192.168.255.2 > 192.168.255.1: ICMP echo request, id 7392, seq 3, length 64
看起来服务器上的路由是正确的:
seven@vps:~$ ip route get 192.168.255.2
192.168.255.2 dev tun2 src 192.168.255.1
cache mtu 1500 hoplimit 64
这意味着如果内核生成 ICMP 响应,它可以路由到 tun2?所以我的猜测是,内核没有响应 ICMP ping?
这是客户的配置:
seven@client:~$ ifconfig tun0
tun0 Link encap:UNSPEC HWaddr 00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00
inet addr:192.168.255.2 P-t-P:192.168.255.1 Mask:255.255.255.255
inet6 addr: fe80::c940:cd18:2f2c:9206/64 Scope:Link
UP POINTOPOINT RUNNING NOARP MULTICAST MTU:1500 Metric:1
RX packets:0 errors:0 dropped:0 overruns:0 frame:0
TX packets:8 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:500
RX bytes:0 (0.0 B) TX bytes:492 (492.0 B)
seven@client:~$ ip route
default via 192.168.1.1 dev enp4s0 proto static metric 100
169.254.0.0/16 dev docker_gwbridge scope link metric 1000 linkdown
172.17.0.0/16 dev docker0 proto kernel scope link src 172.17.0.1 linkdown
172.18.0.0/16 dev docker_gwbridge proto kernel scope link src 172.18.0.1 linkdown
192.168.1.0/24 dev enp4s0 proto kernel scope link src 192.168.1.5 metric 100
192.168.255.1 dev tun0 proto kernel scope link src 192.168.255.2
经过几个小时的调试,结果是一个代码错误:我在打开 tun 设备时没有设置 IFF_NO_PI 标志,但我在通过网络发送它之前不小心插入了标志和原型字段,所以原型从 \x08\x00 更改为 \x00\x08。当包被写入tun时,内核实际上并没有把它当作IPv4包而被忽略。
我正在尝试在我的 vps 上编写一个 vpn 服务器。我已经设置了 tun 接口 < tun2 >,并且可以将从网络接收的包写入服务器上的 tun 设备。但是,当我通过客户端的 ping 命令测试连通性时,服务器内核没有 ICMP 响应包。我错过了什么?
这是拓扑:
┼─────────────────┼ ┼─────────────────┼
│ client │ │ server │
┼─────────────────┼ ┼─────────────────┼
│tun0: │──────────────TCP─────────────│tun2: │
│ 192.168.255.2 │ │ 192.168.255.1 │
│ │ │ │
┼─────────────────┼ ┼─────────────────┼
这是服务器的配置:
seven@server:~$ ifconfig tun2
tun2 Link encap:UNSPEC HWaddr 00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00
inet addr:192.168.255.1 P-t-P:192.168.255.2 Mask:255.255.255.255
UP POINTOPOINT RUNNING NOARP MULTICAST MTU:1500 Metric:1
RX packets:3 errors:0 dropped:0 overruns:0 frame:0
TX packets:0 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:500
RX bytes:252 (252.0 B) TX bytes:0 (0.0 B)
seven@server:~$ ip route
10.77.88.5 dev tun0 proto kernel scope link src 10.77.88.1
10.77.99.2 dev tun1 proto kernel scope link src 10.77.99.1
192.168.255.2 dev tun2 proto kernel scope link src 192.168.255.1
10.77.99.0/24 via 10.77.99.2 dev tun1
default dev venet0 scope link
我可以看到 ICMP 回显请求通过 tcpdump 发送到服务器上的 tun2,但没有响应:
seven@server:~$ sudo tcpdump -n -vvv -i tun2
tcpdump: listening on tun2, link-type RAW (Raw IP), capture size 262144 bytes
11:15:08.046578 IP (tos 0x0, ttl 64, id 63330, offset 0, flags [DF], proto ICMP (1), length 84)
192.168.255.2 > 192.168.255.1: ICMP echo request, id 7392, seq 1, length 64
11:15:09.073521 IP (tos 0x0, ttl 64, id 63527, offset 0, flags [DF], proto ICMP (1), length 84)
192.168.255.2 > 192.168.255.1: ICMP echo request, id 7392, seq 2, length 64
11:15:10.097919 IP (tos 0x0, ttl 64, id 63632, offset 0, flags [DF], proto ICMP (1), length 84)
192.168.255.2 > 192.168.255.1: ICMP echo request, id 7392, seq 3, length 64
看起来服务器上的路由是正确的:
seven@vps:~$ ip route get 192.168.255.2
192.168.255.2 dev tun2 src 192.168.255.1
cache mtu 1500 hoplimit 64
这意味着如果内核生成 ICMP 响应,它可以路由到 tun2?所以我的猜测是,内核没有响应 ICMP ping?
这是客户的配置:
seven@client:~$ ifconfig tun0
tun0 Link encap:UNSPEC HWaddr 00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00
inet addr:192.168.255.2 P-t-P:192.168.255.1 Mask:255.255.255.255
inet6 addr: fe80::c940:cd18:2f2c:9206/64 Scope:Link
UP POINTOPOINT RUNNING NOARP MULTICAST MTU:1500 Metric:1
RX packets:0 errors:0 dropped:0 overruns:0 frame:0
TX packets:8 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:500
RX bytes:0 (0.0 B) TX bytes:492 (492.0 B)
seven@client:~$ ip route
default via 192.168.1.1 dev enp4s0 proto static metric 100
169.254.0.0/16 dev docker_gwbridge scope link metric 1000 linkdown
172.17.0.0/16 dev docker0 proto kernel scope link src 172.17.0.1 linkdown
172.18.0.0/16 dev docker_gwbridge proto kernel scope link src 172.18.0.1 linkdown
192.168.1.0/24 dev enp4s0 proto kernel scope link src 192.168.1.5 metric 100
192.168.255.1 dev tun0 proto kernel scope link src 192.168.255.2
经过几个小时的调试,结果是一个代码错误:我在打开 tun 设备时没有设置 IFF_NO_PI 标志,但我在通过网络发送它之前不小心插入了标志和原型字段,所以原型从 \x08\x00 更改为 \x00\x08。当包被写入tun时,内核实际上并没有把它当作IPv4包而被忽略。