OpenSSH jump-host and file-transfer

This article was inspired by a previous post on my personal blog:


OpenSSH is a great tool, everybody knows that (even Microsoft). It’s commonly used to securely take control or copy a bunch of files to or from remote machines. Another common scenario is to have a machine between two networks that acts as a gateway or “jump-host” between those networks; you connect to this machine and from there you open another connection to the other network. Something annoying is when you want to transfer files between the two networks, you’ll have to copy the files two times, once from the source to the gateway and then from the gateway to the destination. So if your files are huge, it means having disk space available on the jump-host and if you do so frequently it’s a headache; and everybody knows that sysadmins are lazy guys.

This tutorial will explain how to copy files from the source to the target directly and vice-versa.


In my example, target server (srv2) is behind a firewalled + NATed connection at home2 and we have no access to the router, so we can’t configure port-forwarding. Outbound connection is not filtered though, so we will initiate a reverse-tunnel to join the jump-host ( so connection can then be initiated from to srv2 through that persistent tunnel. Then we will configure the client machine located at home1 to access srv2 through reverse-tunnel. We will finish with a bunch of example on how to transfer files between the client and srv2. The whole setup will use public key authentication instead of static passwords.



Step 1: Let’s start srv2 and reverse-tunnel configuration:

1.1 Create a private/public ssh key-pair on srv2:

$ ssh-keygen -t rsa -b 4096

1.2: Copy srv2 public-key in /home/myuser/.ssh/authorized_keys file

1.3: Try to connect from srv2 to, you should obtain a shell without entering a password

$ ssh [email protected]

1.4: Open again /home/myuser/.ssh/authorized_keys on and add the following options before srv2 public key:


The whole file will looks something like this

command="/bin/false",no-agent-forwarding,no-pty,no-user-rc,no-X11-forwarding ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAACAQC5TBa86GUdvTdTuK5nLEaIFVp2zTwxWD+NLG3EfrCRoCA/iaRVM2lF/FyeOdQ2WfMcg4AzpxVy6GTpRWAYzO2uZKSmk+wMxLqU5k5nrOOrBRuwIWXmbTVhDCJX+A9RMG+BL7nOrwNeg2niuow5tiGUi+HMTh9NIPDiP9e36jOWQL2lTDtJ1wXFfR+zPoiCR9bCEphfioseVJSFEzj1pDLc8IQvoLrCcbSBoy16sKPxRfuP2dSmB3jU6tNMS6r79RC4CYJ5iYjBNU8TBtjsAvrskDqSD9vRlAR2lD6o0jSqKowm1AaX7bkUvM7RbJCniDsUFj6Erz2SxsXsVC3FOsP6sZyLuiggJBiVoQ7Fp4YHJyNsBSzoEIsTNxAwGaQIB5fYQ6ZlEmW+tPnC1vrzZDUj5s90nkldFFP3g4V1NkcXTLWTrjBkU8e8s6IBTpJcCELaLTZzQ9hXEjlR6zuJslPwXaXyMoEANGHWNAoJvj1ldk9h4+sUws4DluuUO1LKbDmjQ9+hC+ylR7nYYCkzCkSsQoHJS3ZFeZWkDC3ZTLrTtG5oPi+zYGb7j+BEFfaSL1CAz7n0Ai87ruN7Rf6CpMtjJsO2aCFxwSZ0sRFfXUd9RJdXzDBGOC6IIcbUDcwOWAL2vrYiiehloG7HMQ+2Xup5ddIXV5yBtQ== [email protected]

This will harden a bit the connection from srv to (no shell, no X11 forwarding, …), more info about it here or here

1.5: We will create a script that keeps the reverse-tunnel opened on srv2, copy the following script on srv2 homedir (call it and make it executable:


process=$(pidof ssh)

if [[ $process == “” ]] ; then
ssh -TNnR 19999:localhost:22 [email protected];

1.6: Insert the following crontab entry on srv2

*/1 * * * * /home/user/

1.7: Connect to, the tunnel should have been opened, you can check that with the following command:

# netstat -tulpn | grep 19999
tcp 0 0* LISTEN 25261/sshd:
tcp6 0 0 ::1:19999 :::* LISTEN 25261/sshd:

In this example we can see that the reverse tunnel has created two sockets and ::1:19999. We should now be able to connect to srv2 through it.

$ ssh [email protected]:19999

You’ll need to supply the password for myuser, as we haven’t yet configured pubkey authentication in these instructions. We will do that now.

Step 2: Pubkey authentication from to srv2:

2.1: Create a private/public ssh key-pair on

$ ssh-keygen -t rsa -b 4096

2.2: Copy public-key in srv2 /home/myuser/.ssh/authorized_keys file

2.3: You should now be able to connect using pubkey authentication from to srv2 through the reverse-tunnel established from srv2 to, pfew ! Just try the above command again and this time you should obtain the shell directly.

2.4: Like previously we will harden a bit the authentication mechanism; add the following before the key in /home/myuser/.ssh/authorized_keys file


2.5: Great the hardest part is done, we will now work on the machine located at home1.

Create a private/public ssh key-pair on the client, we’re kinda used to it… :)

$ ssh-keygen -t rsa -b 4096

2.6: Copy the client public key in /home/myuser/.ssh/authorized_keys on

This time we will add the following option line before the public-key


2.7: Create the following file in your user home dir ~/.ssh/config

Host srv2
ProxyCommand ssh [email protected] nc 19999

So basically when we connect to host `srv2` from the client machine the connection will be initiated to `` with user `myuser` then `nc` will be used to open the connection through the reverse-tunnel. What’s very cool with this mechanism is that it’s transparent to the application that connects to the remote host.

Few examples

If your setup was made correctly you shouldn’t be prompted for a password:

connect to srv2:

$ ssh [email protected]

copy something to srv2

$ scp myfile [email protected]:

scp is very handy to copy a file or a directory but it lacks features. For example if you want to make your backups to or from srv2 rsync will be much more suited (resume failed transfers, match files using complex filters, recursively crawl remote directories, …), so here’s how it can be used:

rsync -avz -e "ssh -o StrictHostKeyChecking=no" --progress [email protected]:source_dir dest_dir/


Gentoo doc, SSH jump host
OpenSSH man page
OpenSSH Client Configuration Files
Restrict SSH logins to a single command
Rsync homepage
Scp or rsync with a jump host between the source and the destination

Hope you enjoyed it,



  1. great article.
    so if i copy files from home1 to home2 with rsync I must have the active. But I wonder if it could be possible to copy files directly without using, to avoid using its bandwith ?
    Thanks in advance

  2. thanks for this great article.
    I understand is necessary to establish the link between home1 and home2. But once the connextion is established, is it possible to communicate between home1 and home2 directy to avoid using bandwith ?

Leave a Reply

Fill in your details below or click an icon to log in: Logo

You are commenting using your account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s