In my previous post Managing SSH Logins The Way You Are Supposed To I talked about how you should use the SSH config file to manage your SSH login details. The lab example that we used is 1 SSH client and 2 SSH servers which are both 1 hop from the client. 1 hop in a sense that both can be accessed directly from the client. There is nothing standing in between any of them.
However what if let's say one of the servers happen to sit behind others? This tells us that we will have to jump from one server to another to get access. This scenario is actually quite common in production. Some implementations would call this a bastion host setup. However, in our case we will just do the bare minimum setup.
Here is the vagrant file I used for this lab scenario.
# -*- mode: ruby -*- # vi: set ft=ruby : Vagrant.configure("2") do |config| config.vm.box = "centos/7" config.vm.provider "virtualbox" do |vb| vb.memory = "4096" end config.vm.define "ssh-client" do |sshc| sshc.vm.host_name = "ssh-client" sshc.vm.network "private_network", ip: "10.99.12.1", virtualbox__intnet: "1-2" end config.vm.define "ssh-server-1" do |sshs1| sshs1.vm.host_name = "ssh-server-1" sshs1.vm.network "private_network", ip: "10.99.12.2", virtualbox__intnet: "1-2" sshs1.vm.network "private_network", ip: "10.99.23.1", virtualbox__intnet: "2-3" end config.vm.define "ssh-server-2" do |sshs2| sshs2.vm.host_name = "ssh-server-2" sshs2.vm.network "private_network", ip: "10.99.23.2", virtualbox__intnet: "2-3" end end
And below is how it will look like. Basically, there are 2 network segments. So ssh-client will have to go through ssh-server-1 to get to ssh-server-2. If you don't use vagrant then just create 3 Linux hosts and configure a similar setup.
What we will do is we will give ssh-client access to ssh-server-1 and ssh-server-2. We will generate ssh-client's key pair and use the same keys both for ssh-server-1 and ssh-server-2 which will be hop 1 and hop 2 respectively. I won't be repeating the same content in my post How To Configure SSH Key-based Authentication on Linux so go ahead and follow the steps there and apply it to ssh-client and ssh-server-1.
Once that is done then apply the step no. 2 procedure to ssh-server-2 as well. We won't be able to test it yet at this point. However, I assume you would be able to access ssh-server-1 at least having followed the steps. You should have similar results as below.
[vagrant@ssh-client ~]$ ssh email@example.com Last login: Mon Apr 16 09:13:08 2018 from 10.99.12.1 [vagrant@ssh-server-1 ~]$
Now, let's go ahead and proceed with our own steps here.
Step 1. Try accessing ssh-server-2 via ssh-server-1 using SSH Agent Forwarding.
[vagrant@ssh-client ~]$ ssh firstname.lastname@example.org -A Last login: Mon Apr 16 09:19:52 2018 from 10.99.12.1 [vagrant@ssh-server-1 ~]$ ssh email@example.com Last login: Mon Apr 16 08:04:54 2018 from 10.0.2.2 [vagrant@ssh-server-2 ~]$ exit logout Connection to 10.99.23.2 closed. [vagrant@ssh-server-1 ~]$ exit logout Connection to 10.99.12.2 closed. [vagrant@ssh-client ~]$
The -A option tells SSH to use Agent Forwarding. What this means is that when you SSH to ssh-server-1 (our hop 1) and then try to SSH to ssh-server-2 (our hop 2), the SSH key challenge will be brought all the way back to the original client. In our case, it will be ssh-client.
NOTE: If you ommit the -A option or Agent Forwarding you won't be able to access ssh-server-2. Go ahead and try it.
Step 2. Configure the SSH client config file.
Let's open the SSH config file using the vi editor. (Or you may use your preferred editor)
[vagrant@ssh-client ~]$ vi ~/.ssh/config
Under insert mode type the following:
Host ssh-server-1 Hostname 10.99.12.2 User vagrant Host ssh-server-2 Hostname 10.99.23.2 User vagrant Proxycommand ssh ssh-server-1 -W %h:%p
Then save and quit the editor.
They key thing here is Proxycommand. What we are telling SSH to do here is if we are trying to access ssh-server-2, we should access ssh-server-1 first and then initiate the connection from there.
Now let's try if our connection to ssh-server-2 will work.
[vagrant@ssh-client ~]$ ssh ssh-server-2 Last login: Mon Apr 16 09:57:52 2018 from 10.99.23.1 [vagrant@ssh-server-2 ~]$
Great! it works. Also, It's worthing noting that Agent Forwarding is also being taken care of for us.
That's all there is to it. Now there is an obvious disadvantage to this kind of setup which I plan to address in a future blog post.