Share VPN with OS X Sierra Internet Sharing

After finding that it suited my requirements, I finally decided on a solid VPN - F-Secure Freedome - as recommended by a friend in security. Then I needed to share my connection with my Roku, but Freedome is an application that has to be run on a phone or computer and routers aren't supported.

Once I confirmed that sharing a Freedome encrypted connection is supported and within the TOS, I began the 6-hour journey into sharing my VPN connection with my Roku.

Try, Try Again

First, I tried simply connecting to Freedome then turning on my Mac's Internet Sharing. I found that as soon as I successfully connected to Freedome, my Internet Sharing would stop working.

So I revisited my blog post that I wrote a few years ago, How to Setup NAT on Lion and Mountain Lion, because I figured I needed to do some command-line magic.

The commands I used there were deprecated, so I moved on and found this awesome comment on StackExchange to get me started. This comment provides a majority of the code below. But it was only mostly working. This post, Share your VPN with Mac OS X El Capitan, felt like it got me closer.

And finally, this post suggested that I setup two rules instead of one and voila! Success.

Setup the infrastructure

Set this part up however you need, I did this wired to wired and it worked, too.

So I connected my Mac to my primary wireless network haxx, then plugged the Mac's Ethernet port to the upstream of my second wireless router otherhaxx. I setup the otherhaxx the way I would any other wireless router and connected my Roku wirelessly to otherhaxx.

setup3

Note that some of these IPs won't appear until later. Namely, Internet Sharing creates the 192 subnet once it starts and the Roku won't get its IP until everything is setup. Also, 24.0.175.222 was my first broadband IP ever back in 1997 :D

Now back to the Mac. I did some ifconfigs and found that my wireless connection was en1 and Freedome created an interface named utun0. Mac Internet Sharing created a network with the subnet 192.168.2.x.

I then set Freedome to connect on startup.

Ensure you add a single trailing empty line

My code formatter won't let me add them, but in the original post, the author said a single trailing empty line in each file is required.

Create /private/etc/nat-rules

This is where I spent most of my time testing and retesting different configs. This right here is the key to sharing your VPN connection with Internet Sharing. I tried doing it without explicitly listing the subnet but was unable to get it to work.

nat on en1 from 192.168.0.0/16 to any -> (en1) nat on utun0 from 192.168.0.0/16 to any -> (utun0)

Create /usr/local/nat-pf.sh

This file is cool because it's universal; you really only need to edit nat-rules when you need to make modifications. Oh, also, one of my Macs refused to acknowledge that net.inet.ip.fw.enable existed and it still works anyway. I don't think that particular entry matters.

#!/bin/sh sysctl -w net.inet.ip.forwarding=1 sysctl -w net.inet.ip.fw.enable=1

#disables pfctl pfctl -d sleep 1

#flushes all pfctl rules pfctl -F all sleep 1

#starts pfctl and loads the rules from the nat-rules file pfctl -f /private/etc/nat-rules -e

Create /Library/LaunchDaemons/org.user.natpf.plist

No idea if this works, but it seems to. I should reboot and test ;)

Disabled KeepAlive SuccessfulExit Label org.user.natpf ProgramArguments /usr/local/nat-pf.sh RunAtLoad

Clean up and launch the daemon

Now that the files have been created, ensure they've got the proper owners and permissions.

sudo chown root:wheel /private/etc/nat-rules sudo chown root:wheel /usr/local/nat-pf.sh sudo chmod 755 /usr/local/nat-pf.sh sudo chown root:wheel /Library/LaunchDaemons/org.user.natpf.plist sudo launchctl load /Library/LaunchDaemons/org.user.natpf.plist

Didn't work?

I ended up editing /private/etc/nat-rules and executing /usr/local/nat-pf.sh more times than I can count. Mess with that until it works. Ensure you're using the appropriate device names be examining the output of ifconfig.