• Skip to primary navigation
  • Skip to main content
Ethan Banks

Ethan Banks

@ecbanks

  • Blog
  • Book
  • Podcasts
  • RSS
  • Show Search
Hide Search

Auto-Adding Routes When Mac PPTP Connection Comes Up

Ethan Banks · 4 minutes to read
Published September 26, 2016 · Updated September 27, 2016

Before you read this post, understand that PPTP is insecure. Don’t use PPTP to create a VPN to anything you care about. Really. Apple has even pulled PPTP support from macOS Sierra. Read all about PPTP’s Apple death here, and thanks to @scottm32768 for letting me know about it.

TL;DR

Skip to Solution #3.

Problem

When successfully making a PPTP connection to a remote VPN server with the built-in Mac OS X client, you find that you can’t connect to hosts on the other side of the VPN tunnel. You can still connect to the Internet and LAN hosts.

The root issue is that, by default, OS X has no reason to send traffic across the VPN tunnel. A reason must be provided.

Solution #1 – Setting Service Order

In System Preferences > Network, perform “Set Service Order” (the drop down gear icon), and move the PPTP connection to the top of the list.

This means that when the PPTP tunnel is up, traffic will flow through it before other network connections. This will gain you access to hosts on the other side of the VPN tunnel. It will also break everything else, unless the network on the other side of the PPTP tunnel can also service your Internet traffic. This is going to be a function of the VPN termination device as well as the firewall configuration at the remote site.

The issue here is that ALL traffic, even your Internet traffic, will be routed through the tunnel. Thus, Internet traffic on your system is tossed into the tunnel, pops out at the remote site, gets hairpinned back around right back out through the remote network’s firewall, hits the Internet server you were trying to get to, comes all the way back to the remote network, where it finally gets popped back into the tunnel to you. Not all firewalls or VPN termination devices will be configured to support this hairpin routing.

If you choose this method, remember to set a DNS server in your PPTP connection profile that can be reached via the VPN tunnel. Something public like Google’s 8.8.8.8 and 8.8.4.4 might work. This is important because there’s a good chance your local DNS server will become unreachable as soon as the tunnel comes up, leaving you without name resolution. You might have connectivity, but without name resolution, it will feel like you don’t.

Solution #2 – Disabling Split Tunneling

By default, OS X will “split tunnel” when using the built-in PPTP client. That is, traffic will follow OS X’s routing table. Networks on the other side of the tunnel flow via the tunnel, assuming there are routes that send appropriate traffic that way. Other traffic, such as local LAN or Internet, flows via the wifi or Ethernet connection directly – no tunnel. Therefore, traffic is “split” between the tunnel and physical network interfaces. You can check OS X’s routing table via netstat -rn.

The catch here is that bringing up a PPTP tunnel doesn’t automatically add routes to OS X’s routing table, which is why your PPTP tunnel doesn’t seem to be working and you’re reading this article. There’s a tunnel, but nothing instructing OS X to forward any traffic across that tunnel. Therefore, you’re going to check a box that defeats split tunneling, forcing all traffic into the tunnel.

In System Preference  > Network, select the PPTP connection profile. Click the “Advanced…” button. Check “Send all traffic over VPN connection”. In this case, the service order doesn’t matter.

All the same caveats about hairpin routing and DNS as mentioned in solution #1 hold true.

Solution #3 (and my favorite) – /etc/ppp/ip-up

The script /etc/ppp/ip-up will automatically fire after a PPTP tunnel is brought up. This appears to be default behavior in *NIX kernels, based on this.

Once the PPP link is established, pppd looks for /etc/ppp/ip-up. If this script exists and is executable, the PPP daemon executes the script. This allows you to automate any special routing commands that may be necessary and any other actions that you want to occur every time the PPP link is activated.

This is definitely the behavior of OS X. When the PPTP tunnel comes up, the /etc/ppp/ip-up script fires. Therefore, you can use this script to add routes to the OS X routing table.

1. Create /etc/ppp/ip-up as sudo. If you aren’t a sudo-er on your Mac (i.e. not an admin equivalent), this is going to be an issue for you. You have to have root equivalent to edit this script. I use vi as my editor. Thus, sudo vi /etc/ppp/ip-up.

2. Let’s say there are two networks I care about on the other side of my PPTP tunnel: 10.10.10.0/24 and 10.10.20.0/24. An /etc/ppp/ip-up script to add them to the routing table could look as follows.

#!/bin/sh
/sbin/route add -net 10.10.10.0/24 -interface $1
/sbin/route add -net 10.10.20.0/24 -interface $1

3. We’re using the explicit path “/sbin/” to be certain that the script can find the route command.

4. The $1 is a variable representing the name of the interface used by PPPd.

5. Make sure root is the owner of /etc/ppp/ip-up. It should be by default. sudo chown root /etc/ppp/ip-up

6. Make sure the script is executable. It will not be by default. sudo chmod 755 /etc/ppp/ip-up

The next time you bring up a PPTP tunnel, /etc/ppp/ip-up will run, adding those two routes to the OS X routing table. Don’t forget that you can validate that the script ran by looking at netstat -rn.

With the routes added to the routing table, OS X knows to send traffic for those networks across the tunnel.

This isn’t a perfect solution, as the script is a blunt hammer that doesn’t distinguish between tunnels. This particular script will add those routes to the OS X routing table, no matter what PPTP server you access. You’d need a smarter script to support multiple PPTP sites, which is beyond my scope here. Maybe in a future post.

Filed Under: Hands OnPublished on ethancbanks.com.

Have You Read…?

  1. What Does An ‘R’ Before A String Mean In Python?
  2. How To Pass API Query Parameters In A Curl Request
  3. Synology Running Out Of Space? Empty The Recycle Bin.
  4. Free Networking Lab Images From Arista, Cisco, nVidia (Cumulus)
  5. How To Create A Python Function You Can Call From Other Scripts
  6. How To Use Grep + Regex To Match Non-200 HTTP Status Codes In Apache Server Logs
  7. When Stretching Layer Two, Separate Your Fate
  8. How To: Simple Juniper SRX Rate-Limiting via Policer
  9. Using AppleScript To Size A Window To 16×9 On MacOS
  10. Auto-Adding Routes When Mac PPTP Connection Comes Up

MORE FREE STUFF!

Check out my IT Education Twitter Collection.
Curated tweets for IT professionals trying to up their game.

twitter mastodon linkedin instagram linkedin

Have a great day. You're doing an outstanding job. 👍

About · Privacy

Copyright © 2007–2023 Ethan Banks