Using a VPS and SSH to expose your local machine's ports
When working with certain APIs it can be necessary to expose certain ports on your local machine to the world. In this case, I need to expose port 80, but most consumer ISPs (and work firewalls) block port 80 incoming.
Enter SSH port forwarding (and Amazon's free micro instance tier, although any VPS would work).
Once your machine is set up (the default configuration of Ubuntu Server is what I used, but most Linux machines should be fairly similarly configured), you need to do the following:
Enable SSH access for root.
In my case, I did this by setting up the public/private key for SSH so that I can connect root in but still disallow password SSH access. Root is needed to be able to SSH in since port 80 is a privileged port. If you don't need to forward port 80, then you don't need to connect as root.
Enable "GatewayPorts" in your /etc/ssh/sshd_config file.
Without this setting, sshd will not allow you to set up a port forward on anything but the loopback adapter, meaning you'll never be able to connect to your forwarded port from external IP addresses. This is the most important step to making this work, because without this it will fail silently.
# grep Gateway /etc/ssh/sshd_config GatewayPorts yes #
Run a service on your local machine on any port.
My development laptop has port 80 running apache2. This could be any port.
Connect to the remote machine with SSH and port forwarding.
This makes the magic happen - just run a simple SSH command:
ssh -R*:VPS_PORT:127.0.0.1:LOCAL_PORT root@yourVPS
Since I have my VPS set up in my ~/.ssh/config file, I can simply run this command:
ssh -R*:80:127.0.0.1:80 root@micro
From left to right, these parameters mean:
- -R - use remote port forwarding (remote machine port to local machine port)
- * - bind on all interfaces (this allows remote connections, not just local connections on the server)
- 80 - bind to port 80 on the REMOTE machine
- 127.0.0.1 - forward to the LOCAL machine's IP
- 80 - forward to the LOCAL machine's port 80
Test the configuration.
From another machine enter in your SERVER's ip address into a web browser (or some other method for testing) and you should see output from your LOCAL machine.
This is all very straightforward.
The only gotcha here is enabling GatewayPorts. This is mentioned in the docs, but had been holding me up in the past when I tried to make this configuration work.
