This tutorial will be a short and sweet introduction into setting up ssh
What is a SSH bastion:
SSH bastions (jump hosts) are used to middleman SSH connections between isolated networks. In a high security scenario, say a backend database server, we want complete isolation from the internet. However, we may require remote access to machines, so we have a middle man which is connected to both interfaces.
Bastions are commonly used in cloud environments to securely access VMs which lack public IP addresses, but it can be used for any type of server.
"Dumb" vs "Smart" - Middlebox vs Bastions
In the past, to improve my security on my SSH servers, I used
iptables to restrict ssh access only to my static home IP.
If I wanted to access these servers outside of home, I'd first ssh home,
then once I have a shell at home, I'd ssh into the webserver.
The connection to my webserver thus originates from home. It's simple in concept but it's clunky and amateurish
So having a 'master server' that we ssh into, and from there, launch a new ssh process to connect into our infrastructure sounds reasonable right? In fact, how is this configuration any different from a bastion host.
Well, there's two massive problems
The identity is contained on the workstation, there is no authentication between the client and the endpoint.
- What we have is completely manual, no good for scripts etc. We need to launch a shell to the middle box everytime
We need a better solution than "Hey, Lets store the keys to everything in a single place. Better yet, why not open that place up to the internet!"
The smart way (how bastions work)
Recall that with SSH you can forward ports between the client and the ssh server (the ssh server works as a proxy).
With a proxy based solution, we don't put anything sensitive on the bastion server. The
id_rsa key remains on the client, and only on the client.
Basically the bastion is just acting as a gateway and isn't really participating in the ssh connection between you (the external client) and your internal server.
All the magic is done with a single client instance of ssh.
Let's set it up
$ vi ~/.ssh/config Host bastion Hostname 192.0.2.66 Port 22 User bastion-user IdentityFile ~/.ssh/bastion_host_x509.pem Host *.etherarp.net ProxyCommand ssh bastion -W %h:%p
Now any connections on
etherarp.net will pivot through the bastion. You can set up a ACL/firewall on the clients to only allow connections from the bastion IP.
Primary Use Case
You have cloud instances that are on a private only network. You want authenticated access from outside. You create a
bastion that has both a public facing IP and access to the internal network.
Authenticated connections from the outside, pivot through the bastion in order to reach the internal end points.
In my upcoming post we'll look at best practices of setting up dedicated bastions on Amazon EC2 and further extensions to secure SSH such as SSHFP dns records.
It's not just for cloud
The principles of bastions can be applied to other set-ups too. Perhaps, you have a NAT set up at home. Rather than port forwarding, you could use the SSH service on your router as a bastion. Although, the principle of bastions is that they don't run other services.
You can also use them for random collections of SSH internet hosts you have. Simply set a firewall rule that SSH traffic is only allowed inbound from the bastion.
Then for extra security, you can optionally add outbound rules on the bastion, limiting its egress ssh access only to your allowed preset of hosts.