Simple multi-user SSH bastion

4 min read Original article ↗

A SSH bastion (or jump) host allows a group of permitted users to access a bunch of servers in another security ring by first connecting to the bastion host, and then jumping to the target server.

I want to describe my solution on how to quickly set up such a SSH jumphost, while…

  • only using software that comes with the system (in my case Debian)

  • being multi-user capable, with different users having a different set of servers they’re allowed to connect to

  • not only tunnelling console, but also sftp/scp.

Out of scope is:

  • authenticating the user to the target server. In this solution, the user still has to bring their own credential, such as a ssh key or password, to authenticate to the target server after successfully authenticating to the bastion host.

  • Session recording

Setup

Authenticating users

For every user of the ssh bastion, I create a linux user account.

useradd -s /usr/sbin/nologin -m bestie

In this command, I create a home directory (-m) for storing their ssh key and set their shell so that they cannot login interactively. They may only use the host as a SSH bastion host to connect to other systems (using port forwarding).

Settings inside /etc/ssh/sshd_config

…most of the magic happens inside that file.

Disabling Password Authentication

Generally, it’s a good idea to disable password authentication on public systems if not strictly required:

PasswordAuthentication no

Password authentication can be re-enabled on a per-ip or per-user basis:

Match address 10.0.0.1/32
  PasswordAuthentication yes

Match User bestie
  PasswordAuthentication yes

Restricting access to servers

Inside the Match blocks, you can also disallow using ssh tunneling for all IPs but the permitted ones - paired with a disabled shell: making it impossible to jump to all hosts but the permitted ones.

Match User bestie
  PermitOpen 10.0.0.2:22

The port is important there - omitting it won’t work.

It may seem unintuitive, but using PermitOpen to allow access to one, automatically disallows the rest. You can specify multiple IP-port-combinations (separated by spaces). You don’t seem to be able to specify subnets.

General workflow

Setting up users

To set up a new user…

  • create it using useradd as usual: useradd -s /usr/sbin/nologin -m bestie

  • If you want to use password authentication for that user, set a password using passwd and enable PasswordAuthentication in the sshd_config-Match clause for that user.

  • If you want the user to not be able to connect to all hosts that the bastion host can reach, use PermitOpen in the sshd_config-Match clause for that user to restrict the access.

  • If that user shall authenticate using a SSH key, place that key inside their authorized_keys file inside their personal .ssh directory.

Connecting using the bastion

using the command line

You can use your jumphost like this - however, it’s not very fun, and I usually require multiple attempts.

ssh -J <bastion username>@<bastion ip>:<bastion port> <target user>@<target ip>

using the command line (and the ssh config)

This is the more fun way:

Host my-bastion
        HostName <bastion-ip>
        User <bastion user>
        Port <bastion port>
        IdentityFile <bastion ssh key>

Host my-target
        HostName <target ip>
        User <target user>
        ProxyJump my-bastion
        IdentityFile <target ssh key>

After putting the text above into the ~/.ssh/config file, run:

ssh my-target
sftp my-target

…and due to both connections having a ssh key, the connection will open no questions asked. SSH keys are not required though, they’re just here for completeness sake - you can also be asked for a password at connection time, and if your ssh key is encrypted you will be anyway.

using PuTTY

Thankfully, PuTTY supports this too.

In the sidebar, you can navigate to Connection -> Proxy, set the select to “SSH to use and port forward”, and enter hostname, port, username and password.

Sadly, the SSH key from SSH -> Auth -> Credentials doesn’t apply to the connection to the SSH bastion - you can however load the SSH key into your PuTTY Pageant Agent, that works.

The settings page for Proxy should roughly look like this:

Et Voilà:

Further reading: The OVH SSH bastion host

The web hosting company OVH (better known for their demonstration on why having a backup is important) quite some time ago published two articles (article 1 and article 2).

They need such a bastion host on a much bigger scale than I do (mainly many more servers, which is why created their own bastion host software that automatically authenticates to the target server using an egress key, so that all servers only have to trust that one egress key and the access permission (who may connect to which server) is purely done on the bastion host, which the users have to authenticate against of course).

These articles are a good (and short) read, and I can recommend them. I have not tried their bastion host software though.