Currently, as per normal procedure, we have a bastion server in each public subnet within a cloud network and we attempt to access it via the following config -

Host webserverA
    User myuser
    ForwardAgent yes
    Port 22
    ProxyCommand ssh -q bastionA nc %h %p
    IdentityFile ~/webserver.pem

Is there a way for me to extend this model to having another bastion server?

BastionB -> BastionA -> WebserverA ?

The reasoning is that I'd like to treat this as a Chain of Trust. Remove something when a rather bad event occurs.

By CoT I mean, if a set of users leaves, we can change the first set of keys so that we can block their further access.

  • 2
    I'm not sure I understand the "chain of trust" part. Commented Sep 9, 2016 at 8:34
  • @grawity - basically in plain terms, pull a key out to block a whole set of unwanted users.
    – A23
    Commented Sep 9, 2016 at 8:45

1 Answer 1


Method 1 – onion (nested tunnels)

With OpenSSH 7.3 and later:

Host webserverA
    ProxyJump bastionA,bastionB

The same via command line:

$ ssh -J bastionA,bastionB webserverA

Alternatively (also with 7.3; don't mix this and above):

Host webserverA
    ProxyJump bastionB

Host bastionB
    ProxyJump bastionA

With older versions – mostly identical (but doesn't automatically copy options like ssh -v):

Host webserverA
    ProxyCommand ssh bastionB -W %h:%p

Host bastionB
    ProxyCommand ssh bastionA -W %h:%p

This method initiates all connections locally, setting up a ssh -W tunnel to each step. Therefore authentication happens locally (ForwardAgent and GSSAPIDelegateCredentials are not required) and your local .ssh/config applies to each step as well. Server-side, only basic "TCP forwarding" support is needed, same as when using -W or -L.

However, each layer adds extra overhead, since it ends up carrying SSH in SSH in SSH in SSH.

Note that each host, except for the outermost one, lists a ProxyCommand through the server immediately before it. If you had 3 servers, you would use [webserverA via bastionC], [bastionC via bastionB], and [bastionB via bastionA].

Method 2 – hop by hop

Host webserverA
    ProxyCommand ssh bastionA -A ssh bastionB -W %h:%p

This method initiates connections hop by hop, running ssh on each hop to connect to the next one. Therefore a ssh-agent and ForwardAgent must be enabled (or GSSAPIDelegateCredentials if you use Kerberos); any other special .ssh/config settings must be copied to all bastion hosts.

On the other hand, it incurs less protocol overhead (max. two layers at every step).

(Edit: added -A to always request agent forwarding.)

  • Note that ssh <host> -W is functionally nearly identical to ssh <host> nc ..., except not depending on any external tools. (Instead it uses the same 'tunnel' feature as ssh -L or ssh -D.) Commented Sep 9, 2016 at 8:43

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .