As a consultant, I’m frequently working on client sites. In many cases, I will end up with a client-supplied workstation or laptop that allows me to access everything internally, but the bigger the company, the likelier it is that they have piles of security infrastructure that means that I can’t get out to my mail server from the machine that they’ve given me, VPN connections are usually out of the question, Dropbox is blocked, along with protocols like BitTorrent used by Resilio Sync so I end up working with my personal MacBook Pro sitting on the desk next to theirs connected to my own 4G router, tethered to my iPhone or one some kind of relatively permissive guest Wifi.
But there are times when I end up using my own laptop connected to their network, like last week when the Windows laptop they gave me started acting so wonky that we decided it was time to send it in for remastering.
Using my laptop is problematic since I can either be connected to their network, or connected to the internet via my 4G Router. So I can either have my email or have access to the internal services I’m working on.
Now MacOS will happily connect to multiple networks at the same time, but it will basically only use the first one listed in the Network Preference pane unless you are addressing an IP address directly on the subnet of the second interface.
So in order of awfulness, the options are basically the following:
Disconnect from the internal network to check mail (unplug the cable)
The most brutal approach is not really viable since it means that every time I want to check my email, all of the internal RDP and SSH connections will end up getting dropped. This gets old really quickly.
Swap the interface priority before opening a connection
This is marginally better since as long as an interface is up and a connection established, it will be maintained even if the interface priority is changed. But for something like an email client that doesn’t keep an open TCP session to the server, it means that on the next connection attempt it will end up using the priority interface (internal) and I have to start the dance all over again of swapping interfaces, making the connection and swapping them back again.
Cheating with route manipulation
Under the MacOS hood there’s a complete BSD environment so all of the cool networking goodness is available to you and there are a few interesting ways to abuse this.
In the simplest case, where the internal network allows for http/https traffic from any device, I only need to really get to a few specific services externally like my mail server over IMAP. So in this case, I just need to look up the gateway of the Wifi connection, using the terminal :
netstat -f inet -r | grep default default 192.168.99.254 UGSc en0
I’m forcing things to use IPv4 at the moment, and will have to start looking into how to IPv6 in the future. Given that most enterprises are light years away from internal IPv6, setting everything to go directly to your internet connected interface is probably a safe bet at the moment.
So with that information in hand, I can manually override the routing table with a command like:
sudo route add x.x.x.x 192.168.99.254
Poking around the route man page shows that there is an option to force traffic over an interface instead of specifying the gateway, but that doesn’t actually work as it seems that it tries to push it out through the selected interface, but addressing the default gateway that is defined on the primary interface so the packets end up going nowhere.
Back to the route command, you can be as specific (or not) as you like. If you only want to get to your email server, the destination can be the actual IP address so only that address will be routed through this gateway, or you can grab wide swathes of the internet by using something like:
sudo route add -net xxx 192.168.99.254
This is a great way to scoop up a pile of sites services and useful for places that use lots of CDN endpoints that happen to be found in the same range so you just put in the first octet of the IP address.
Pushing things further, this can easily be put into a little shell script where you can have an entry for the useful destinations that you want and you can just update the gateway with a find and replace or get fancy and have the script accept the gateway as an input variable. The script method is also useful in that you can also have a tear down script that you can use to clean things up afterwards which is done using the “route delete” command.
sudo route delete -net xxx