Using SSH Tunnels to Access Firewalled Servers Without a VPN

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 ~/.ssh/config:

Host bastion
    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
    IdentityFile ~/.ssh/my_bastion.key

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:

Host 172.16.0.*
    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 bastion.

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:

ssh [email protected]

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:

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 /etc/hosts file:    my.webservice.com

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?

Alex Phillips

Leave a Reply

Your email address will not be published. Required fields are marked *