ACA Blog

ACA Blog

January 2020
« Dec    


SSH Summer School: jump hosts and file transferring

Jan BeerdenJan Beerden

SSH Summer School: jump hosts & transferring files

This blog post is the final part of a 3 part series about SSH (Secure Shell) connections with OpenSSH. In this last part of the series, I’ll talk about jump/bastion hosts, using ‘screen’ and transferring files. You can check out the first post here and the second part here. The aim of this blog post series is to teach you more about SSH. In these blog posts, I assume you are using a UNIX-like operating system with OpenSSH.

Let’s start off by talking about jump/bastion hosts and why they’re so handy. It’s becoming more and more common that the remote server you want to access isn’t directly reachable. Instead, you need to pass through a jump or bastion host. And that’s a good thing, because:

Passing through a jump host can be annoying because you need to SSH through multiple servers. Luckily, there are multiple ways to do this. I’ve listed 4 methods below!

How to pass through a jump host

1. ‘Manually’

One method of passing through a jump host is to SSH into the jump host and then from the jump host SSH into your server.

You’ll soon come to the conclusion that connecting to your remote server from the jump host requires an SSH key on the jump host. A solution could be to create an SSH key on the jump host, but this isn’t an option for jump hosts that are replaced on a regular basis. This probably isn’t a suitable method for most of us, so let’s go on to the next method. Oh, and by the way: never copy your local SSH key to another host such as a jump host!

2. Agent forwarding

I have already explained the ssh-agent concept in the first blog post of this series. With agent forwarding, you can expose your local ssh-agent on a remote server, such as a jump host. You can either use the command line option -A or the config file option ForwardAgent.

By doing this, you no longer need an intermediary key. Your account on the jump host and the remote server should only contain the public part of your local SSH key. Easy enough, right? (smile)

SSH agentHowever, because you are exposing your local ssh-agent to the jump host, the jump host can use your SSH key without needing the passphrase. If you are the only one using (and maintaining) this jump host, you’re probably fine. If that isn’t the case (probably most of the times), someone could use your key while it’s being forwarded to the jump host.

When starting an SSH connection with agent forwarding enabled, the SSH server will create a socket to expose your ssh-agent. Only your user on the jump host will have permissions on this socket, but these restrictions do not apply to the root user or any user that has enough permissions via sudo.

Let me show you how this would work in an example with 2 people, Bob and Sid. First, Bob will SSH to a jump host with agent forwarding enabled so he can than SSH to a remote server.

While Bob is working on the remote server, Sid, who has root access to the jump host, is trying to get access to Bob’s private server. The only allowed method of accessing Bob’s private server is by using Bob’s SSH key.

Once Sid’s session to Bob’s private server is active, he can continue to use this session even if Bob terminates his session. As you can see in this short demo, this isn’t a long or complex process and it allows your keys to be used as long as you are connected. You can reduce the risk by creating a dedicated SSH key per server you connect to, but I think this is way too much hassle and it still exposes your account on that specific server.

3. ProxyCommand

With the ProxyCommand option, you can specify a command to be used to connect to the remote server. This option can be used to ‘chain’ SSH connections. By using “ssh -W” as ProxyCommand, we request that standard input and output on the client is forwarded to Hostname over the secure channel to my-jump-host.

As you can see, this requires some configuration, but that only needs to be done once.

Once this configuration is in place, you can ssh ‘directly’ in to your remote server. Passing through the bastion host is taken care of by the ProxyCommand.

4. ProxyJump (I recommend this one!)

Since OpenSSH 7.3, there is an easier to configure alternative to ProxyCommand called ProxyJump.

As you can see, this option’s configuration is a lot simpler.

Connecting to your remote server is no different from the ProxyCommand method. If you want to connect to a remote server without having to add it to your config file via a jump host (that you have added to your config file), ProxyJump is also very simple.

When you share an SSH config file with your team, you can also include the config shown above. They will certainly appreciate not having to create or add the configuration themselves! Just make sure to follow the conventions mentioned in part one of this series.

I recommend this method instead of the others because:Hold themed retrospectives

With methods 3 and 4, you will also have the benefit of being able to transfer files directly to your remote server using scp or sftp without having to copy them to the jump host first. But how exactly do you start transferring files then? We’ll dive into the details of file transfer, but first let me tell you about using ‘screen’.

Using ‘screen’

Since each jump host introduces an extra point of failure, now is the perfect time to start using ‘screen’. Have you ever had your SSH session disconnect while running a lengthy and/or delicate process on a remote server? When your SSH session gets disconnected, all processes started in the session that are running on the foreground will be terminated. This will require you to start all over or, depending on the process, leave you with a mess to clean up manually. Luckily, you can prevent this from becoming a problem by using ‘screen’. From its man page:

Screen is a full-screen window manager that multiplexes a physical terminal between several processes (typically interactive shells).

Some benefits of using screen:

First of all, screen needs to be installed on your remote server. If screen isn’t installed yet, you can use your systems package manager to install it.

Starting a new screen

Starting a screen is very simple:

Screen will create a new shell, similarly as SSH’ing into a server would.

Disconnecting from a screen

The difference from a ‘standard’ shell is that you can disconnect from it, without killing all the sub processes. First you need to enter the escape command, which is CTRL+a, followed by CTRL+d

Screen will tell you it detached you from a screen session. In this case, the session is called If you want to exit the shell instead of disconnecting for the screen session, you can do so as if it is any other shell. Enter:

(warning) However, be careful! Screen does not protect you from accidentally exiting your shell. (warning)

Listing active screen sessions

With the -ls option, you can list all active screen sessions.

Each line consists of the process id and the session name, separated by a period.

Starting a new screen with a custom session name

As you can see from the output above, screen sessions can be hard to identify. Therefore, it might be wise to name your screen session when starting it:

Attaching to a detached screen session

When you want to re-attach to a screen session, you can do so with the -r option. This option takes either the process id or the session name as parameter.

Multiple windows in a single screen session

Each of the following subsections assume you are attached to a screen session.

Creating a new window inside your screen session

By issuing CTRL+a followed by CTRL+c, you create a new window.

List of open windows

By issuing CTRL+a followed by CTRL+w, you get a list of open windows.

As you can see from the output above, I have 3 open windows, identified by a number followed by its title.

Switching between windows

There are 4 (5) ways to switch between windows:

  1. switch to a specific window:
    • CTRL+a followed by the number of the window
    • CTRL+a followed by , this method is probably the easiest since it presents you with an interactive window selector. By using the arrow keys, you can select the desired screen and press the return key to select it.
  2. switch to the next window: CTRL+a followed by n
  3. switch to the previous window: CTRL+a followed by p
  4. switch to the last window: CTRL+a followed by o

Other screen key bindings

There are several keys bindings that can be used inside a screen session, after issuing the control command (CTRL+a). You can get an overview of the available key bindings by pressing the ? key. Hit CTRL+a first, then hit the ? key.

One of my favorites is copy. As the name gives away, it can be used to copy text from one window to another. For a complete overview and explanation of the available command line options and key bindings, please have a look at the man page.

Transferring files

As promised above, we’ll touch upon transferring files. There are a number of methods to transfer files to, from and between remote hosts. In this section, I’ll go over file transfer via SCP, SFTP and SSH ‘streaming’. All three of these methods also work when using a jump host when you use the ProxyCommand or ProxyJump directive as described above.


scp or secure copy allows you to securely copy files from, to or between remote hosts.


For more information about using scp, have a look at it’s man page.


sftp or secure file transfer protocol is an interactive file transfer program similar to ftp which allows you to securely copy files to or from a remote server. By entering the “?” command you will get a list of possible commands.

For more information about using sftp, have a look at it’s man page.

‘Stream’ through SSH

Let’s say you need an archive of the log files on your remote server, but you don’t have enough space on that server to create the archive. Instead of creating the archive on the remote server and then copying the archive, you could also ‘stream’ it to your local machine. Just like scp, this method can be used to copy files from, to or between remote servers.


In the examples above you will notice I use a dash “-” as the file name, this is the way of instructing tar, cat and several other programs to write to standard output (stdout) or read from standard input (stdin).

And there we have it! I know this final part in the series is a rather lengthy post, but I didn’t want to split it up into parts that would be too small to be interesting on their own. As always, if you have any questions or remarks, leave them below as a comment and I’ll answer them asap or address them in a future blog post.

System Engineer at ACA IT-Solutions