SOCKS5 alternative to VPN on OSX
Many of my fellow work-from-home colleagues have had various issues with using VPN on a near-full-time basis. From connection timeouts to VPN outages, it's kept people from Getting Things Done®, and that's no good.
I constantly gloat about not having these issues because I don't use VPN. Purposefully. Intentionally. Vehemently. After gloating, I move on to singing the praises of SOCK5 proxies, then mumble something about setup being a pain, blah blah blah.
Time to stop mumbling and share the path to secure transparent connection enlightenment.
Warning: Terminal ahead.
Prerequisites
You'll need a few things to get this working. If you already have one of these, skip to the next.
Gateway Server
This is only going to work if there is a publicly accessible server inside the network into which you need to connect. If you don't have something like that, this isn't going to work. Sorry!
For purposes of this protip we'll use the fictitious:
gateway.example.com
OS X Yosemite
These instructions may work in older versions of OSX, but your milage may vary. Linux is probably similarish. No clue how to set this up on Windows. My bad.
XCode
Grab the latest from the App Store. You don't need to use it, but you need to have it installed for Homebrew to work.
Homebrew
The missing package manager for OS X. You can install it via your terminal with this one-liner:
ruby -e "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install)"
If you hit any errors, just follow the instructions in the messages. Then make sure everything's running properly with:
brew doctor
autossh
More on this later. Just install it.
brew install autossh
Setup
Password-less SSH
Everyone likes security. No one likes typing passwords. Pre-shared keys to the rescue!
Open up your terminal. Make sure you have an ~/.ssh
directory and navigate to it.
mkdir ~/.ssh
cd ~/.ssh
Create a new key. You'll be asked questions. Accept the defaults (unless you know what you're doing). DO NOT ENTER A PASSWORD.
ssh-keygen -t rsa
If you already have a key, you can use that one, or create a new one with a new name, then use that anytime this tip says id_rsa.pub
. If you overwrite an existing key, you'll run into other issues.
Upload your new public key to the gateway server (this is the second-to-last time you'll need to enter your gateway password).
scp id_rsa.pub username@gateway.example.com:id_rsa.pub
SSH into the gateway server (the last time you'll need to enter your password).
ssh username@gateway.example.com
Now that you're on the server, make sure you have an ~/.ssh
directory here too.
mkdir ~/.ssh
Append your public key to the list of authorized keys. This is what allows you to login to the gateway without a password.
cat ~/id_rsa.pub >> ~/.ssh/authorized_keys
You don't need the public key file on the gateway server anymore.
rm -f ~/id_rsa.pub
Close the connection.
exit
Make sure it's working.
ssh username@gateway.example.com
Are you in? Without a password? Yay! (If not, try again.) We're done on the server side.
exit
Automator
Now that we can connect to the gateway without a password, it's time to setup the proxy.
- Open
Automator
- Click "New Document"
- Choose the "Application" document type.
- Type "shell" into the actions search field.
- Drag "Run Shell Script" from the left into the area that says "Drag actions or files here..."
-
Replace
cat
with this magical command:/usr/local/bin/autossh -M 20000 -fND 1080 username@gateway.example.com
Save the application as
~/Applications/autossh.app
You've just created an application that will start up a SOCKS5 proxy that will reconnect to the server if the connection is ever dropped (such as when your laptop goes to sleep).
Login Item
We want the proxy to start automatically when we login, so add it to your login items.
- Open
System Preferences
- Go to "Users & Groups"
- Choose yourself in the list on the left.
- Click the "Login Items" tab.
- Click the "+" button at the bottom of the login items list.
- Add
~/Applications/autossh.app
Now your proxy app will start whenever you log in.
- Log out
- Log in
- Open "Activity Monitor"
- Click the "CPU" tab.
- Search for
autossh
If it's in the list of running stuff, you're set to move on. (If not, try again.)
Proxy
Now that you have a proxy server running, you need to use it. For that you'll use a proxy.pac
file. It's a special JavaScript file that OS X uses to route traffic.
Create one.
touch /Library/WebServer/Documents/proxy.pac
Open it up and paste this in.
function FindProxyForURL(url, host) {
if (
// Local
shExpMatch(host, '*.localhost')
) {
return 'PROXY 127.0.0.1;DIRECT';
}
if (
// Private remote
shExpMatch(host, '10.10.*.*') ||
shExpMatch(host, '*.example.com')
) {
return 'SOCKS5 127.0.0.1:1080;DIRECT';
}
// Public remote
return 'DIRECT';
}
This says to keep localhost traffic local, send example.com
traffic through the new gateway proxy, and access everything else directly.
Now that you have a proxy.pac
, it needs to be served from a website. Why the heck you can't just access it from the filesystem is beyond me and beyond annoying.
To host it, you have to turn on web sharing. There used to be an option for this in System Preferences, but they removed it. Also annoying.
Just run this to have apache start itself on login.
sudo launchctl load -w /System/Library/LaunchDaemons/org.apache.httpd.plist
This once, start it manually.
sudo apachectl start
Proxy discovery
- Open
System Preferences
- Go to "Network"
- Choose your active network connection on the left. For me, that's "Wi-Fi"
- Click "Advanced" in the lower right.
- Click the "Proxies" tab.
- Click on "Automatic Proxy Configuration" and tick the box.
- Enter
http://127.0.0.1/proxy.pac
into the URL field. - Click "OK"
- Click "Apply"
If all went well this should work straight away, but you might need to restart your computer.
Enjoy
You should now be able to open up your favorite browser and navigate to an .example.com
site that would otherwise only be available via VPN.
If you need to access more domains or IPs via the private network, add the appropriate lines to the conditionals in your proxy.pac
file.
Update: SSH
If you wish to use this same proxy for another ssh connection, you'll want to configure it in your local .ssh/config
file.
ServerAliveInterval 120
ServerAliveCountMax 30
Host *
ForwardAgent yes
Host gateway
HostName gateway.example.com
ForwardAgent yes
Host foobar
HostName foobar.example.com
ProxyCommand ssh -T gateway 'nc %h %p'
ForwardAgent yes
You can then ssh to foobar.example.com
via the proxy with ssh foobar
. Yay shortcuts!
Written by Shannon Moeller
Related protips
1 Response
save a couple of steps:
brew ssh-copy-id ;
ssh-copy-id user@gateway.example.com
that will transfer AND install your default identity's public file on the remote machine's authorized_keys automatically. ssh-copy-id for some reason, although a part of OpenSSH, is not installed on OSX, hence the need to brew it.