VPN Routing and Security
I was working abroad temporarily and had to use a shopping mall Internet service. This shopping had open Wifi that anyone could use after going through a captive portal.
So, I filled out the necessary form, and once the network had access to the Internet, I activated the VPN based on the OpenVPN client. All traffic will go through the VPN, so I should be safe, right?
Well, …not exactly!
I was using this shopping mall's Internet without any issue until… I had to connect to an internal IP through SSH. Strangely, it was timing out.
$ ssh my-host
ssh: connect to host 10.2.1.30 port 22: Operation timed out
I started to try to understand what was happening. The first thing I thought was that it was a problem with the server itself or the internal network. But, I was told my packets were not reaching the internal network.
So.. what’s happening to the packets in my laptop? I did a tcpdump:
$ tcpdump -lvvnp port 22
tcpdump: data link type PKTAP
tcpdump: listening on pktap, link-type PKTAP (Apple DLT_PKTAP), capture size 262144 bytes
15:17:39.392720 IP (tos 0x0, ttl 64, id 0, offset 0, flags [DF], proto TCP (6), length 64)
10.199.125.146.59021 > 10.2.1.30.22: Flags [SEW], cksum 0x7d95 (correct), seq 1625334601, win 65535, options [mss 1460,nop,wscale 6,nop,nop,TS val 719456825 ecr 0,sackOK,eol], length 0
15:17:40.379066 IP (tos 0x0, ttl 64, id 0, offset 0, flags [DF], proto TCP (6), length 64)
10.199.125.146.59021 > 10.2.1.30.22: Flags [S], cksum 0x7a6d (correct), seq 1625334601, win 65535, options [mss 1460,nop,wscale 6,nop,nop,TS val 719457825 ecr 0,sackOK,eol], length 0
15:17:41.382076 IP (tos 0x0, ttl 64, id 0, offset 0, flags [DF], proto TCP (6), length 64)
10.199.125.146.59021 > 10.2.1.30.22: Flags [S], cksum 0x7685 (correct), seq 1625334601, win 65535, options [mss 1460,nop,wscale 6,nop,nop,TS val 719458825 ecr 0,sackOK,eol], length 0
15:17:42.384117 IP (tos 0x0, ttl 64, id 0, offset 0, flags [DF], proto TCP (6), length 64)
10.199.125.146.59021 > 10.2.1.30.22: Flags [S], cksum 0x729d (correct), seq 1625334601, win 65535, options [mss 1460,nop,wscale 6,nop,nop,TS val 719459825 ecr 0,sackOK,eol], length 0
The source IP of the packets is set to the gateway of the Wifi AP and not from the VPN tunnel interface. Why? I’d expect that if I have the VPN active and with adequate VPN configuration, all packets would go through the VPN tunnel...
The next step was to look at the route tables. In macOS we can use netstat -rn
command. An excerpt of the output is:
$ netstat -rn
Routing tables
Internet:
Destination Gateway Flags Netif Expire
0/1 x.x.x.x UGSc utun2
default 10.128.128.128 UGSc en0
10 link#4 UCS en0 !
10.128.128.128/32 link#4 UCS en0 !
10.128.128.128 x.x.x.x UHLWIir en0 1145
10.199.125.146/32 link#4 UCS en0 !
10.248.5.109 x.x.x.x. UHLWI en0 1194
10.255.255.255 ff:ff:ff:ff:ff:ff UHLWbI en0 !
80.1.1.1/29 x.x.x.x UGSc utun2
80.1.1.1/32 10.128.128.128 UGSc en0
127 127.0.0.1 UCS lo0
127.0.0.1 127.0.0.1 UH lo0
...
The 80.1.1.1
is the public IP of the VPN gateway, and the 10.128.128.128
is the internal IP of the Wifi AP gateway. So, the VPN configuration is adding a default destination 0/1
, which should have more priority than the “default” gateway of the Wifi AP.
Why is the packet routed from the en0 interface if the routing table looks good? 🤔
If we look more carefully, we see an additional entry for the destination 10.0.0.0/8
:
...
default 10.128.128.128 UGSc en0
10 link#4 UCS en0 <---
10.128.128.128/32 link#4 UCS en0
...
Since the network stack will prioritize routes with a longer prefix, instead of forwarding the packet through the default gateway, it will use this route with a longer prefix: 10.0.0.0/8
(instead of 0/1
) if the destination IP is within the range 10.0.0.0/8
which is the case!
So even though the VPN configuration is setting a default gateway.. that doesn’t mean network-provided routes for specific IP ranges can’t override it!
# route delete -host 10.0.0.0/8 -link 4
Comments? feel free to send me an email or reach out through Twitter.