What is an SSH bastion and how is this different from an SSH jump server or an SSH proxy? In this post, we’ll answer this question and will show you how to set it up using two popular open source projects.
OpenSSH is the older and better known SSH server. It comes pre-installed by default with the vast majority of Linux distributions and is the easier option to get started with.
Remoteler is a much newer SSH server, its first production-quality release came out in 2016. Remoteler has been optimized for elastic multi-cloud environments and supports other access protocols in addition to SSH.
Both Remoteler and OpenSSH support bastions, and they are extremely similar as they are both single-binary Linux daemons. Both require a simple configuration file usually stored somewhere under /etc/.
An SSH bastion host is a regular Linux host, accessible from the Internet. What makes it a bastion is the fact that it’s the only server which accepts SSH connections from the outside. If a user wants to access another machine, they need to connect to the bastion first, and then make another SSH connection from the bastion to the final destination. Sometimes this process is called “jumping” and SSH bastions are also called “jump hosts”.
The process of “jumping” can be automated, i.e. an SSH client can be configured to “jump” automatically and we’ll cover this below.
An SSH bastion is a critical component of your computing environment, as it reduces the attack surface to just one machine. Therefore, setting up security on this machine is absolutely critical. Before we get to SSH configuration, make sure that the regular Linux security hardening is applied:
rootuser is disabled
When doing your infrastructure planning, it’s a good idea not to re-use the SSH bastion server for any other purpose. In fact, the best SSH bastion should allow SSH clients to do anything else, other than “jump” to their final destinations.
We’ll show how to set up an SSH bastion with two open-source projects: OpenSSH and Remoteler. We’ll start with OpenSSH as it’s the most common and it’s probably already installed on your Linux hosts.
The configuration examples below make a couple of assumptions:
OpenSSH is usually preinstalled on most Linux and Mac computers. Let’s look at the client first. If your bastion host is accessible via
bastion.example.com then you can access other hosts behind it (on the same VPC/LAN) via
-J command line flag, i.e. on the client:
The bastion host is specified via
-J flag and it is used to jump to another host (10.5.5.10). Note that 10.5.5.10 is the remote host’s address on a local datacenter network (or a VPC), not the local network of the client.
To avoid using
-J flag many times, you can configure your client to apply this flag automatically based on the destination host name or address, and you can use wildcards:
~/.ssh/config updated as shown above, a user can simply type:
Now let’s take a look at the bastion server configuration. First, we need to disable interactive SSH sessions so regular users won’t be able to SSH into the bastion. Update
/etc/ssh/sshd_config like so:
The configuration above will completely disable SSH logins into the bastion server, for everybody. That’s quite restrictive but sometimes it may work if a bastion is created from an AMI pre-configured this way. But you may also want to allow SSH sessions for certain users.
For that to work, create a separate user account for regular users. In this example we’ll call it
And the regular users will have to use the following client configuration:
The examples above will work only if the public SSH keys of your users are copied to both the bastion host and the destination machines, which can be a hindrance. We advocate against using SSH keys and moving to SSH certificates instead. Remoteler, the next open source SSH solution we’ll talk about, uses SSH certificates by default and it does not require any configuration on the destination SSH nodes.
Once a jump server is configured, users connect to remote servers via jump servers. This can be done by using OpenSSH ProxyJump and ProxyCommand directives which tell the SSH client how to connect to a remote server via an intermediary server.
Below is a syntax on how to use SSH ProxyJump:
Below is a syntax on how to use SSH ProxyCommand:
SSH ProxyJump is also preferred over SSH agent forwarding.
Remoteler is a relative newcomer on the SSH scene. It was released in 2016 and it is a somewhat controversial SSH solution that uses SSH bastion (Remoteler calls it “SSH proxy”) by default, and Remoteler’s bastion comes with a built-in web UI.
One interesting feature of Remoteler is that it is environment-aware, and makes all SSH hosts to register and form a cluster, so users can see all hosts that are online:
Remoteler supports other protocols in addition to SSH, so the same bastion can be used to access other resources behind NAT, such as Kubernetes clusters or even internal applications via HTTP(s).
Remoteler’s own quick start guide includes easy instructions for setting up the bastion, so we won’t be copy-pasting the instructions from there.
An SSH bastion host is one of the industry best practices for setting up SSH access to production infrastructure. Bastions help centralize SSH authentication and auditing and act as a gateway to prevent direct network access to the private networks. In this post, we covered a bastion host setup using two open source projects, but which one is best for your situation?
We recommend OpenSSH if:
Consider adopting Remoteler if:
Although it is relatively easy to deploy a bastion host in your infrastructure, securing a bastion host requires careful consideration from design to deployment. After all, bastion hosts are the first target for attackers looking to compromise access to infrastructure.