Skip to content

Instantly share code, notes, and snippets.

@rma92
Last active September 15, 2023 04:26
Show Gist options
  • Save rma92/4deb7fcbe92ae325f6547a24591d05f2 to your computer and use it in GitHub Desktop.
Save rma92/4deb7fcbe92ae325f6547a24591d05f2 to your computer and use it in GitHub Desktop.
SSH proxy to make a local resource available on the Internet

Use an SSH proxy to make a server on your local machine available on the Internet

You can use any random cloud host with an SSH server to make a server on your local computer available on the internet. The process described here is not reliable enough to be used for productive use, but can be useful for testing.

There's a setting in sshd that allows reverse SSH tunnels to optionally accept connections from other hosts: GatewayHosts. By default, this is disabled. Set it to enabled, and reload the SSH configuration.

  • On OpenBSD, edit /etc/ssh/sshd_config, add the line GatewayPorts yes (or uncomment and edit the existing no line).
  • Reload the sshd config by running sh -c 'kill -HUP $(cat /var/run/sshd.pid)' as root. (This only reloads the configuration, and can be done through SSH)
  • The port you want exposed needs to be allowed through the firewall.
    • doas vi /etc/pf.conf
    • add the relevant line, something like: pass out proto tcp to port 8080 (note this will be different on FreeBSD)
    • doas pfctl -nf /etc/pf.conf to verify the config. If no errors, continue to the next step.
    • doas pfctl -f /etc/pf.conf to load the firewall configuration.

You can now use an SSH remote port, for example, to expose a web server running on localhost:24601 to the internet on the server at port 8080:

image

ssh user@100.100.10.10 -R *:8080:localhost:24601

To do this in PuTTY, go to the SSH > Tunnels tab, add a Remote Tunnel, with the source port 8080 and the destination localhost:24601, click "Add". Check the box "Remote ports do the same (SSH-2 only)". Note this doesn't work with low ports, as generally only root can bind to low ports.

Use a second SSH tunnel as root to use a low port.

Since a normal user cannot bind to a low port, and root can, and we generally can't SSH to the server as root, we can create another proxy by running the SSH client as root.

Say we have the tunnel above, where the web server is now accessible on port 8080, and port 81 has been allowed through the firewall. All we need to do is run SSH as root.

doas ssh user@localhost -L *:81:localhost:8080

If port 81 has been allowed through the firewall, the server will now be accessible on port 81.

Using the internet server as a jump host

Say you have a web server on your work network, http://worksite.local/ (on port 80) and you want to make it accessible from the machines on your home network. You can use an SSH server on the internet to do this. No firewall changes are needed on the SSH server, as we will use two tunnels to the internet server to facilitate this.

On your work computer, run PuTTY, connect to the internet server, user@100.100.10.10, with a REVERSE tunnel. Pick any unused high port on the server, say 24000, choose Remote, and set the destination to worksite.local:80. The normal ssh command looks like:

ssh user@100.100.10.10 -R 24000:worksite.local:80

image

On your home computer, run PuTTY. connect to the internet server, user@100.100.10.10, with a normal tunnel. Using port 10000, and send the tunnel to localhost:24000 on the server. If you want other computers on your home network to be able to access the site, check "Local ports acccept connections from other hosts". Remember to allow the port through Windows Firewall if you want to accept connections from other hosts.

You can now connect to localhost:10000 and access the site.

image

ssh user@100.100.10.10 -L *:10000:localhost:24000

Getting around HTTP expecting a specific hostname

A lot of web servers host multiple sites, so expect a hostname to be specified within the HTTP request itself, and will return an error with an unrecognized IP address. This can be worked around by editing your hosts file to route worksite.local to 127.0.0.1 (or the IP address of your home computer running PuTTY if you're using another machine).

Note that if you attempt to use HTTPS, some intranet sites use unusual certificates, and you'll get a certificate error.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment