A short and quick guide to setting up a reverse proxy from your local machine thru a remote virtual private server (VPS). This setup is useful for manual testing a service that's running on your local machine temporarily or if you're running permanent services behind a NAT firewall.

The first thing you will need to do is to reconfigure the SSH service on your VPS. You will need to add the following options to the SSH service's configuration file:

GatewayPorts yes
AllowTcpForwarding yes
ClientAliveInterval 60
ClientAliveCountMax 10
  • GatewayPorts - When set to "yes", remote hosts are allowed to connect to ports forwarded for the client.
  • AllowTcpForwarding - When set to "yes", TCP forwarding is permitted.
  • ClientAliveInterval - Number of seconds that the server will wait before sending a null packet to the client (to keep the connection alive).
  • ClientAliveCountMax - This is the limit of how long (increments of ClientAliveInterval) a client is allowed to stay unresponsive before being disconnected.

You can simply append the above configuration options to the end of your server's /etc/ssh/sshd_config, but the options will be applied to all SSH connections - not immediately insecure but also not a good habit to leave such options available system-wide.

A more secure setup is to grant these options to a single user which will be created for the sole purpose of reverse proxying.

To create the reverse proxy user:

useradd \
    --shell /bin/rbash \
    --home-dir /home/reverseproxy \
    --create-home \
  • --shell /bin/rbash - Sets the login shell for the user to a restricted version of bash.

It is necessary to set a password for the new user even if logging in via pubkey:

passwd reverseproxy

Generate the .ssh directory with authorized_keys file for the new user:

mkdir -p /home/reverseproxy/.ssh; \
    touch /home/reverseproxy/.ssh/authorized_keys

Don't forget to append your pubkey to the authorized_keys file.

If you need further help with this step, see my previous tutorial about how to configure passwordless SSH.

Append the configuration options to your server's SSH configuration file:

cat >> /etc/ssh/sshd_config << EOL
Match User reverseproxy
    GatewayPorts yes
    AllowTcpForwarding yes
    ClientAliveInterval 60
    ClientAliveCountMax 10

Then restart the server's SSH service:

service ssh restart

And finally run the following command on your local machine to establish the reverse proxy tunnel:

ssh -v -N -T -R 8080:localhost:8080 reverseproxy@IP_ADDRESS_OF_VPS
  • -v - Print verbose log messages.
  • -N - Do not execute a remote command.
  • -T - Disable pseudo-terminal allocation.
  • -R - Establish a reverse tunnel with a remote entry point.

That's it! You should now be able to access the service running at port 8080 (in this example) on your local machine via the virtual private server's IP address.

If you'd like to keep the tunnel open long-term, I suggest to use autossh:

autossh is a program to start a copy of ssh and monitor it, restarting it as necessary should it die or stop passing traffic

And if you followed this tutorial and you're still not able to get it working, you can try ngrok instead:

ngrok exposes local servers behind NATs and firewalls to the public internet over secure tunnels