Hello,
The plot thickens.
While augmenting my test scenario on your request, I decided to switch computers in the lab, and the pings started happening. Hmmm, said I.
The bottom line is if I run openvpn-2.3.10-1ubuntu2.1 on both sides my pings succeed.
I had openvpn-2.4.0-6+deb9u2 on one side when I had the asymmetric behavior.
Real good news for me and our members is that on my production Debian 9 servers I copied over an amd64 openvpn-2.3.10-1ubuntu2.1 binary
onto both sides, and now my hairpin NAT setup is running smoothly.
So says I, what next?
I went back to my experiment machines and built openvpn-2.5_git on both machines, one i386, one amd64.
I can confirm that my experiment as described in my previous post shows the asymmetric tcpdump behavior in 2.5_git,
meaning I see certain packets only on 1-ot-of-2 tcpdumps.
I switch to 2.3.10 on both sides, restart the tunnel, and the pings happen.
I also noticed in my last post I sent the content of experiment-server.sh twice so I repeat all files below.
These files are now using 10.250.60.120 and 10.250.60.130 as the tunnel addresses which is slightly more symmetrical.
I also added 10.250.120.120 on a bridge on the client and 10.250.130.130 on a bridge on the server to prove general routing.
dev tuntestserver
local 10.250.60.120
port 1194
proto udp
remote 10.250.60.130 1194
topology p2p
ifconfig 10.249.58.57 10.249.57.58
route-noexec
dev tuntestclient
local 10.250.60.130
port 1194
proto udp
remote 10.250.60.120 1194
topology p2p
ifconfig 10.249.57.58 10.249.58.57
route-noexec
/etc/network/interfaces server:
auto eth0
iface eth0 inet static
address 10.250.60.120
netmask 255.255.255.0
gateway 10.250.60.254
post-up ip link add brserver type bridge
post-up ip link set brserver up
post-up ip address add 10.250.120.120/24 dev brserver
/etc/network/interfaces client:
auto enp1s0
iface enp1s0 inet static
address 10.250.60.130
netmask 255.255.255.0
gateway 10.250.60.254
post-up ip link add brclient type bridge
post-up ip link set brclient up
post-up ip address add 10.250.130.130/24 dev brclient
experiment-server.sh
service openvpn@vpn-testserver restart
iptables -t raw -F ; iptables -t mangle -F
iptables -t raw -A OUTPUT -p icmp -d 10.250.0.0/16 -j TRACE
iptables -t raw -A PREROUTING -p icmp -d 10.250.0.0/16 -j TRACE
iptables -t mangle -A OUTPUT -p udp --dport 1194 -j RETURN
iptables -t mangle -A OUTPUT -d 10.250.60.130 -j MARK --set-mark 1
ip rule delete priority 1 ; ip rule add priority 1 fwmark 1 lookup 1
ip route replace table 1 default via 10.249.57.58 dev tuntestserver
ip route replace 10.250.130.0/24 dev tuntestserver src 10.250.120.120
ip route show
ip route show table 1
ip rule show
tcpdump -i tuntestserver &
experiment-client.sh
service openvpn@vpn-testclient restart
iptables -t raw -F ; iptables -t mangle -F
iptables -t raw -A OUTPUT -p icmp -d 10.250.60.0/24 -j TRACE
iptables -t raw -A PREROUTING -p icmp -d 10.250.60.0/24 -j TRACE
iptables -t mangle -A OUTPUT -p udp --dport 1194 -j RETURN
iptables -t mangle -A OUTPUT -d 10.250.60.120/31 -j MARK --set-mark 1
ip rule delete priority 1 ; ip rule add priority 1 fwmark 1 lookup 1
ip route replace table 1 default via 10.249.58.57 dev tuntestclient
ip route replace 10.250.120.0/24 dev tuntestclient src 10.250.130.130
ip route show
ip route show table 1
ip rule show
tcpdump -i tuntestclient &
bash -x experiment-server.sh # excerpted
+ ip route show
default via 10.250.60.254 dev eth0 onlink
10.249.57.58 dev tuntestserver proto kernel scope link src 10.249.58.57
10.250.60.0/24 dev eth0 proto kernel scope link src 10.250.60.120
10.250.120.0/24 dev brserver proto kernel scope link src 10.250.120.120
10.250.130.0/24 dev tuntestserver scope link src 10.250.120.120
+ ip route show table 1
default via 10.249.57.58 dev tuntestserver
+ ip rule show
0: from all lookup local
1: from all fwmark 0x1 lookup 1
32766: from all lookup main
32767: from all lookup default
bash -x experiment-client.sh # excerpted
+ ip route show
default via 10.250.60.254 dev enp1s0 onlink
10.249.58.57 dev tuntestclient proto kernel scope link src 10.249.57.58
10.250.60.0/24 dev enp1s0 proto kernel scope link src 10.250.60.130
10.250.120.0/24 dev tuntestclient scope link src 10.250.130.130
10.250.130.0/24 dev brclient proto kernel scope link src 10.250.130.130
+ ip route show table 1
default via 10.249.58.57 dev tuntestclient
+ ip rule show
0: from all lookup local
1: from all fwmark 0x1 lookup 1
32766: from all lookup main
32767: from all lookup default
Now the fun.
With 2.3.10 on both sides, prove correct ping from client to server bridge:
root@idspgw7-a:~# ping 10.250.120.120
PING 10.250.120.120 (10.250.120.120) 56(84) bytes of data.
64 bytes from 10.250.120.120: icmp_seq=1 ttl=64 time=0.965 ms
64 bytes from 10.250.120.120: icmp_seq=2 ttl=64 time=0.714 ms
tcpdump on client tunnel interface:
19:37:03.579608 IP 10.250.130.130 > 10.250.120.120: ICMP echo request, id 2013, seq 1, length 64
19:37:03.580549 IP 10.250.120.120 > 10.250.130.130: ICMP echo reply, id 2013, seq 1, length 64
19:37:04.580673 IP 10.250.130.130 > 10.250.120.120: ICMP echo request, id 2013, seq 2, length 64
19:37:04.581375 IP 10.250.120.120 > 10.250.130.130: ICMP echo reply, id 2013, seq 2, length 64
tcpdump on server tunnel interface:
19:37:03.611313 IP 10.250.130.130 > 10.250.120.120: ICMP echo request, id 2013, seq 1, length 64
19:37:03.611402 IP 10.250.120.120 > 10.250.130.130: ICMP echo reply, id 2013, seq 1, length 64
19:37:04.612448 IP 10.250.130.130 > 10.250.120.120: ICMP echo request, id 2013, seq 2, length 64
19:37:04.612530 IP 10.250.120.120 > 10.250.130.130: ICMP echo reply, id 2013, seq 2, length 64
With 2.3.10 on both sides, prove correct ping from server to client bridge:
root@ahau1:~# ping 10.250.130.130
PING 10.250.130.130 (10.250.130.130) 56(84) bytes of data.
64 bytes from 10.250.130.130: icmp_seq=1 ttl=64 time=0.909 ms
64 bytes from 10.250.130.130: icmp_seq=2 ttl=64 time=0.585 ms
tcpdump on server tunnel interface:
19:41:39.600735 IP 10.250.120.120 > 10.250.130.130: ICMP echo request, id 6922, seq 1, length 64
19:41:39.601578 IP 10.250.130.130 > 10.250.120.120: ICMP echo reply, id 6922, seq 1, length 64
19:41:40.601730 IP 10.250.120.120 > 10.250.130.130: ICMP echo request, id 6922, seq 2, length 64
19:41:40.602290 IP 10.250.130.130 > 10.250.120.120: ICMP echo reply, id 6922, seq 2, length 64
tcpdump on client tunnel interface:
19:41:39.570693 IP 10.250.120.120 > 10.250.130.130: ICMP echo request, id 6922, seq 1, length 64
19:41:39.570722 IP 10.250.130.130 > 10.250.120.120: ICMP echo reply, id 6922, seq 1, length 64
19:41:40.571449 IP 10.250.120.120 > 10.250.130.130: ICMP echo request, id 6922, seq 2, length 64
19:41:40.571467 IP 10.250.130.130 > 10.250.120.120: ICMP echo reply, id 6922, seq 2, length 64
Now run the test, first from server to client, with openvpn 2.3.10, succeeds:
root@ahau1:~# ping 10.250.60.130
PING 10.250.60.130 (10.250.60.130) 56(84) bytes of data.
64 bytes from 10.250.60.130: icmp_seq=1 ttl=64 time=0.700 ms
64 bytes from 10.250.60.130: icmp_seq=2 ttl=64 time=0.991 ms
tcpdump on the server, packets correctly routed through the tunnel:
19:44:52.104097 IP 10.250.60.120 > 10.250.60.130: ICMP echo request, id 11500, seq 1, length 64
19:44:52.104739 IP 10.250.60.130 > 10.250.60.120: ICMP echo reply, id 11500, seq 1, length 64
19:44:53.111335 IP 10.250.60.120 > 10.250.60.130: ICMP echo request, id 11500, seq 2, length 64
19:44:53.112249 IP 10.250.60.130 > 10.250.60.120: ICMP echo reply, id 11500, seq 2, length 64
tcpdump on the client:
19:44:52.066904 IP 10.250.60.120 > 10.250.60.130: ICMP echo request, id 11500, seq 1, length 64
19:44:52.066975 IP 10.250.60.130 > 10.250.60.120: ICMP echo reply, id 11500, seq 1, length 64
19:44:53.074138 IP 10.250.60.120 > 10.250.60.130: ICMP echo request, id 11500, seq 2, length 64
19:44:53.074189 IP 10.250.60.130 > 10.250.60.120: ICMP echo reply, id 11500, seq 2, length 64
And the test from client to server, with 2.3.10 succeeds:
root@idspgw7-a:~# ping 10.250.60.120
PING 10.250.60.120 (10.250.60.120) 56(84) bytes of data.
64 bytes from 10.250.60.120: icmp_seq=1 ttl=64 time=0.813 ms
64 bytes from 10.250.60.120: icmp_seq=2 ttl=64 time=0.670 ms
tcpdump on the client:
19:46:59.479822 IP 10.250.60.130 > 10.250.60.120: ICMP echo request, id 2020, seq 1, length 64
19:46:59.480576 IP 10.250.60.120 > 10.250.60.130: ICMP echo reply, id 2020, seq 1, length 64
19:47:00.480840 IP 10.250.60.130 > 10.250.60.120: ICMP echo request, id 2020, seq 2, length 64
19:47:00.481471 IP 10.250.60.120 > 10.250.60.130: ICMP echo reply, id 2020, seq 2, length 64
tcpdump on the server:
19:46:59.523940 IP 10.250.60.130 > 10.250.60.120: ICMP echo request, id 2020, seq 1, length 64
19:46:59.524013 IP 10.250.60.120 > 10.250.60.130: ICMP echo reply, id 2020, seq 1, length 64
19:47:00.524931 IP 10.250.60.130 > 10.250.60.120: ICMP echo request, id 2020, seq 2, length 64
19:47:00.524976 IP 10.250.60.120 > 10.250.60.130: ICMP echo reply, id 2020, seq 2, length 64
And now repeat the tests with openerp-2.5_git from the master branch,
meaning I replace the binaries and re-run the experiment script on both sides,
same exact addressing, same exact routing rules and policies:
ping from client to the server bridge to prove routing:
root@idspgw7-a:~# ping 10.250.120.120
PING 10.250.120.120 (10.250.120.120) 56(84) bytes of data.
64 bytes from 10.250.120.120: icmp_seq=1 ttl=64 time=0.574 ms
64 bytes from 10.250.120.120: icmp_seq=2 ttl=64 time=0.511 ms
tcpdump on client:
19:55:19.197598 IP 10.250.130.130 > 10.250.120.120: ICMP echo request, id 2239, seq 1, length 64
19:55:19.198138 IP 10.250.120.120 > 10.250.130.130: ICMP echo reply, id 2239, seq 1, length 64
19:55:20.197307 IP 10.250.130.130 > 10.250.120.120: ICMP echo request, id 2239, seq 2, length 64
19:55:20.197802 IP 10.250.120.120 > 10.250.130.130: ICMP echo reply, id 2239, seq 2, length 64
tcpdump on server:
19:55:19.232602 IP 10.250.130.130 > 10.250.120.120: ICMP echo request, id 2239, seq 1, length 64
19:55:19.232666 IP 10.250.120.120 > 10.250.130.130: ICMP echo reply, id 2239, seq 1, length 64
19:55:20.232226 IP 10.250.130.130 > 10.250.120.120: ICMP echo request, id 2239, seq 2, length 64
19:55:20.232256 IP 10.250.120.120 > 10.250.130.130: ICMP echo reply, id 2239, seq 2, length 64
and ping client bridge from server to prove routing:
[root@ahau1:~# ping 10.250.130.130
PING 10.250.130.130 (10.250.130.130) 56(84) bytes of data.
64 bytes from 10.250.130.130: icmp_seq=1 ttl=64 time=0.649 ms
64 bytes from 10.250.130.130: icmp_seq=2 ttl=64 time=0.375 ms
tcpdump on server:
19:57:19.511575 IP 10.250.120.120 > 10.250.130.130: ICMP echo request, id 30698, seq 1, length 64
19:57:19.512177 IP 10.250.130.130 > 10.250.120.120: ICMP echo reply, id 30698, seq 1, length 64
19:57:20.535237 IP 10.250.120.120 > 10.250.130.130: ICMP echo request, id 30698, seq 2, length 64
19:57:20.535590 IP 10.250.130.130 > 10.250.120.120: ICMP echo reply, id 30698, seq 2, length 64
tcpdump on client:
19:57:19.483475 IP 10.250.120.120 > 10.250.130.130: ICMP echo request, id 30698, seq 1, length 64
19:57:19.483504 IP 10.250.130.130 > 10.250.120.120: ICMP echo reply, id 30698, seq 1, length 64
19:57:20.507030 IP 10.250.120.120 > 10.250.130.130: ICMP echo request, id 30698, seq 2, length 64
19:57:20.507048 IP 10.250.130.130 > 10.250.120.120: ICMP echo reply, id 30698, seq 2, length 64
And here is the testcase, from server to client, with openvpn 2.5_git
root@ahau1:~# ping 10.250.60.130
PING 10.250.60.130 (10.250.60.130) 56(84) bytes of data.
^C
--- 10.250.60.130 ping statistics ---
3 packets transmitted, 0 received, 100% packet loss, time 2044ms
tcpdump on server:
19:59:12.730433 IP 10.250.60.120 > 10.250.60.130: ICMP echo request, id 1072, seq 1, length 64
19:59:13.751246 IP 10.250.60.120 > 10.250.60.130: ICMP echo request, id 1072, seq 2, length 64
tcpdump on client:
(empty)
And here is the testcase from client to server, openvpn-2.5_git:
root@idspgw7-a:~# ping 10.250.60.120
PING 10.250.60.120 (10.250.60.120) 56(84) bytes of data.
^C
--- 10.250.60.120 ping statistics ---
3 packets transmitted, 0 received, 100% packet loss, time 1999ms
tcpdump on client:
20:00:45.679662 IP 10.250.60.130 > 10.250.60.120: ICMP echo request, id 2241, seq 1, length 64
20:00:46.679376 IP 10.250.60.130 > 10.250.60.120: ICMP echo request, id 2241, seq 2, length 64
tcpdump on server
(empty)
occasionally if restarting the server and client and re-running the test, I do see the a first reply
in the server tcpdump, never any indicator of seq 2 or seq 3:
20:02:18.246623 IP 10.250.60.130 > 10.250.60.120: ICMP echo request, id 2370, seq 1, length 64
20:02:18.246704 IP 10.250.60.120 > 10.250.60.130: ICMP echo reply, id 2370, seq 1, length 64
(occasionally I see like that, stops here, reply never makes it back to client, seq 2 never arrives at server)
so the bottom line is, I wonder what is new in 2.5_git from 2.3.10,
and perhaps is there a setting or patch I could make so I can move my live servers forward
from the 2.3.10-ubuntu16 patch I applied over debian 9. I am happy with the patch for now....
forwarding config on server:
root@ahau1:/etc/openvpn# for f in $(find /proc/sys -name rp_filter) ; do echo $f ; cat $f ; done
/proc/sys/net/ipv4/conf/all/rp_filter
0
/proc/sys/net/ipv4/conf/brserver/rp_filter
0
/proc/sys/net/ipv4/conf/default/rp_filter
0
/proc/sys/net/ipv4/conf/eth0/rp_filter
0
/proc/sys/net/ipv4/conf/eth1/rp_filter
0
/proc/sys/net/ipv4/conf/lo/rp_filter
0
/proc/sys/net/ipv4/conf/tuntestserver/rp_filter
0
root@ahau1:/etc/openvpn# cat /proc/sys/net/ipv4/ip_forward
1
forwarding config on client:
root@idspgw7-a:/etc/openvpn# for f in $(find /proc/sys -name rp_filter) ; do echo $f ; cat $f ; done
/proc/sys/net/ipv4/conf/all/rp_filter
0
/proc/sys/net/ipv4/conf/brclient/rp_filter
0
/proc/sys/net/ipv4/conf/default/rp_filter
0
/proc/sys/net/ipv4/conf/enp0s25/rp_filter
0
/proc/sys/net/ipv4/conf/enp1s0/rp_filter
0
/proc/sys/net/ipv4/conf/enp2s0/rp_filter
0
/proc/sys/net/ipv4/conf/lo/rp_filter
0
/proc/sys/net/ipv4/conf/tuntestclient/rp_filter
0
root@idspgw7-a:/etc/openvpn# cat /proc/sys/net/ipv4/ip_forward
1
Gratitude.