Exposing localhost to internet using SSH tunnels
You're developing a website locally, and you need to test it on other devices for bugs, visual glitches or layout. Or you need to show your client a feature and get their feedback. Or you need to validate some configuration for a service. You need a way to access your local setup from the web. What do you do?
You've got several options. Well, for visual feedback, you might manage to satisfy your client with a screenshot. But for others, you need some interactivity, a physical connection. You can upload or commit all your progress, files and configuration every time you change something, that's cumbersome. You can also commit to a service that redirects your local traffic to web. There are some free and paid services, like localtunnel (free), ngrok (free & paid), Forward (paid with trial), but localtunnel keeps disconnecting with free server, ngrok doesn't let you have custom subdomains, and Forward is paid only.
Good thing is if you have a server with SSH access lying around, you can forego all these options. You will have a public link to your local setup with any domain you own, keep the connection open as long as you want, and any change you make is accessible to public instantly.
Configuring SSH service on server
Now we need to define some context. Say you have a domain
example.com which points to a remote server at IP address
r.r.r.r listening to requests on port
8080). On your local machine, you have an HTTP server listening to requests at
localhost for that matter) on port
We'll expose the local setup to internet such that any request coming to
example.com:RMT will be forwarded through a secure SSH connection into
local.dev:LCL on your local machine.
As a first step, you should configure SSH service for more secure practices, this includes disabling logging in as root and with a password. You can use this tutorial to set up SSH keys for Ubuntu systems as a guide. Make sure you've set up your firewall to accept connections from
RMT port as well. If you haven't touched any server configuration before, fear not, DigitalOcean Community is more than enough to get you up and running.
Once this system is working fine open up a terminal and edit your SSH service configuration by
sudo nano /etc/ssh/sshd_config
GatewayPorts clientspecified to the end, then save by CTRL + X, Y and confirm with Enter. This setting lets client specify which port SSH will listen on the public side of your server.
Setting up the connection
Now, you need start an SSH connection. This one is different from what you're used to. Open another terminal on your local machine. Type in
ssh -N -R :RMT:local.dev:LCL email@example.com # after substituting real values ssh -v -N -R :8080:local.dev:80 firstname.lastname@example.org
Explanation of switches1:
-Rswitch allocates a socket on the remote server to forward remote connections to your local machine.
-Ndisables command execution, preferable if you'll be using the connection for forwarding only.
-vis verbose option, useful for debugging.
This will establish an SSH connection to your remote server. If you examine the debug log, you should be able to see following messages.
debug1: Authentication succeeded (publickey). Authenticated to r.r.r.r ([r.r.r.r]:22). debug1: Remote connections from :8000 forwarded to local address local.dev:80
Voila! Now try going to
example.com:8080, you'll be welcomed with your local website.