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.

jemos / Sep 14, 2022