Last Updated: February 25, 2016
·
29.33K
· shannonmoeller

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.

  1. Open Automator
  2. Click "New Document"
  3. Choose the "Application" document type.
  4. Type "shell" into the actions search field.
  5. Drag "Run Shell Script" from the left into the area that says "Drag actions or files here..."
  6. Replace cat with this magical command:

    /usr/local/bin/autossh -M 20000 -fND 1080 username@gateway.example.com

  7. 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.

  1. Open System Preferences
  2. Go to "Users & Groups"
  3. Choose yourself in the list on the left.
  4. Click the "Login Items" tab.
  5. Click the "+" button at the bottom of the login items list.
  6. Add ~/Applications/autossh.app

Now your proxy app will start whenever you log in.

  1. Log out
  2. Log in
  3. Open "Activity Monitor"
  4. Click the "CPU" tab.
  5. 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

  1. Open System Preferences
  2. Go to "Network"
  3. Choose your active network connection on the left. For me, that's "Wi-Fi"
  4. Click "Advanced" in the lower right.
  5. Click the "Proxies" tab.
  6. Click on "Automatic Proxy Configuration" and tick the box.
  7. Enter http://127.0.0.1/proxy.pac into the URL field.
  8. Click "OK"
  9. 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!

1 Response
Add your 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.

over 1 year ago ·