I am trying to write a vpn server on my vps. I have setup the tun interface < tun2 > and the packages that received from network can be written to tun device on the server. However when I test the connectivity by ping command from client, there is no ICMP response package from server's kernel. What did I miss?
this is the topology:
┼─────────────────┼ ┼─────────────────┼
│ client │ │ server │
┼─────────────────┼ ┼─────────────────┼
│tun0: │──────────────TCP─────────────│tun2: │
│ 192.168.255.2 │ │ 192.168.255.1 │
│ │ │ │
┼─────────────────┼ ┼─────────────────┼
This is the server's configure:
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
I can see the ICMP echo requests are sent to tun2 on server by tcpdump, but no response:
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
looks like the routing on server is correct:
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
which means if a ICMP response is generated by kernel, it can be routed to tun2? So my guess is, kernel did not response to the ICMP pings?
this is client's configure:
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
After hours of debugging, it is turn out a code bug: I don't have IFF_NO_PI flag set when openning tun device, but I accidentally ntohs the flag and proto fields before sending it thru network, so the proto was changed from \x08\x00 to \x00\x08. When the package was written into tun, kernel actually don't treat it as IPv4 package and ignored.