In SSH terms you often talk about a bastion host or jump server - a single machine (typically in your DMZ) that accepts incoming SSH connections and from which you can then make a SSH connection to the actual systems you manage.
==> | Server1 |
_________ ___________ / ---------
| user PC | ===(SSH on port 22)===> | jump host | ===(SSH on port 22)== ==+> | Server2 |
_________ ___________ \ _________
==> | Server3 |
Often for improved security the jump server will require dual-factor authentication and/or will only accept incoming SSH sessions after establishing a VPN connection.
Rather than first logging on to the jump host and from the command prompt there starting the second SSH session OpenSSH allows you to configure that in a single command
I prefer to set all settings explicitly in my ~/.ssh/config with a short alias for each host. That way I won't need to use any commandline flags and can simply type less and use ssh Destination and be done with.
Host jumphost
Hostname jumphost.example.com
User serverfault
ForwardAgent yes
AddKeysToAgent yes
UseKeychain yes # Specific to OS X
IdentityFile ~/.ssh/id_rsa.jumphost
Host server1
Hostname server1.int.example.com
User hbruijn
ForwardAgent yes
AddKeysToAgent yes
UseKeychain yes # Specific to OS X
IdentityFile ~/.ssh/id_rsa.int.example.com
ProxyJump jumphost
ProxyJump is a relatively new setting that I find somewhat more intuitive to use then a ProxyCommand. Now ssh server1 will do exactly what you need, first create a session using serverfault@jumphost.example.com as a first hop from which you tunnel to your next hop with optionally a different ssh key and a different username hbruijn@server1.int.example.com.
You can also use the ProxyJump command directly in from the command line :
ssh -J serverfault@jumphost.example.com hbruijn@server1.int.example.com
A different approach is discussed in this Q&A