My company recently switched their VPN out with a new system and being a Linux user, I have no available option for a client on my workstation. So I needed another method to access both our AWS-based hosts as well as our on-prem machines. SSH tunnels to the rescue.
Consider the following network diagram: you have a secured network with only public access to a single ‘bastion’ host. This bastion host has access to all machines in the network. Here’s how we can easily access all protected machines as if we were on the same network.
First, basic shell access
For the following to work, you do have to have 1 machine that you can shell into from a public network that has SSH access to the other machines. You don’t have to have the necessary SSH keys on the bastion server to connect to the destination boxes, but it does have to have access to SSH to them (whether this be through NACLs, AWS security groups, etc). SSH supports this really cool config option called
ProxyJump which allows you to specify a host to route through for a specific host or set of hosts defined.
First, define your bastion host in
HostName 123.456.789.10 # This is the public IP of the host
User ec2-user # This is the user for SSH access on the bastion
The above config defines your bastion host’s IP, user, and key for access. Next, define either a specific IP or IP wildcard of the machines you want to connect to behind your firewall:
ProxyJump bastion # This is the SSH host name of bastion
The above defines a wildcard IP host block in your SSH config that tells your SSH client that for any of those IPs, automatically route my traffic through the host called
NOTE: Your bastion host does NOT need the SSH keys required to connect to the machines behind the firewall. In fact, for security purposes, it shouldn’t. You need both the bastion private key and the firewalled machines private key only on your workstation.
Now, the following will get you into your firewalled machine without the use of a VPN:
Let’s get fancy and access web services
Shelling into servers is great and all, but what if you need to access a web service, like your Grafana instance or your Portainer dashboard? You can use SSH tunnels to forward local ports to remote hosts. Combined with the proxy jumping above, this is true even for hosts behind firewalls.
Continuing with our above example, you can run the following command:
ssh -NL 10000:172.16.0.5:443
Now, navigating to
https://localhost:10000 in your browser should present you with the web page. If your machine is using virtual hosts to delegate different services, you may need to add an entry in your
Now, navigating to
https://my.webservice.com:10000 will direct traffic to the remote web service and forward on the necessary host header.
What else are you using SSH tunnels to accomplish without a VPN?