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
Hostname 192.168.1.10
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.
Best Answer
Method 1 – onion (nested tunnels)
With OpenSSH 7.3 and later:
The same via command line:
Alternatively (also with 7.3; don't mix this and above):
With older versions – mostly identical (but doesn't automatically copy options like
ssh -v
):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
This method initiates connections hop by hop, running
ssh
on each hop to connect to the next one. Therefore a ssh-agent andForwardAgent
must be enabled (orGSSAPIDelegateCredentials
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.)