Here’s the situation: your colleague is working on laptop C. They need to get into server A. Server A is behind a firewall, and can create outbound connections, but inbound connections are not allowed. You have access to an internet server B, but you don't want to allow full shell access on there to your colleague.
The solution is to create two restricted users on server B, let’s call them alex
and casey
. Server A will then SSH out to server B as user alex
, and open a port listening on server B that forwards back to SSH on server A. Your colleague will then SSH from laptop C as user casey
, using server B as a jumphost back to itself, and from there on to server A.
Confused? It’s not quite as complicated as it sounds. Here are the practical steps you need to take.
On server B
Create two users:
adduser alex --shell=/bin/true --disabled-password
adduser casey --shell=/bin/rbash --disabled-password
(Note: with --disabled-password
, you will need to set up SSH keys for the two users. This is a simple process but is outside the scope of this article. Its advantages are that it’s more secure than a password, and also more convenient to users as it doesn’t require typing two passwords on every connection attempt. Alternatively just leave this option out and you can use passwords for authentication.)
Add the following section at the end of /etc/ssh/sshd_config
:
Match User alex
AllowAgentForwarding no
AllowTcpForwarding yes
X11Forwarding no
PermitTunnel yes
GatewayPorts no
ForceCommand /bin/true
Match User casey
AllowAgentForwarding no
AllowTcpForwarding yes
X11Forwarding no
PermitOpen 127.0.0.1:12345 [::1]:12345
PermitTunnel yes
GatewayPorts no
ForceCommand echo 'This account can only be used for ProxyJump (ssh -J)'
Restart sshd:
systemctl restart sshd.service
On server A
ssh -R 12345:localhost:22 -N alex@serverB
(Note: you probably want to run this command inside screen
or something similar, so that it will keep running without needing to leave the terminal open.)
On laptop C
ssh -p 12345 user@127.0.0.1 -J casey@serverB
(Here user
is the user account on server A that your colleague needs to access. It is unrelated to alex
and casey
, which are accounts on server B only)
Done! You colleague should now have an SSH connection open on server A. The restrictions on the user accounts mean that your colleague can’t do anything on server B, and anyone connecting out from server A can’t do anything on server B either.
References
https://gist.github.com/smoser/3e9430c51e23e0c0d16c359a2ca668ae
https://serverfault.com/questions/891142/how-to-specify-multiple-destinations-in-openssh-servers-permitopen-directive
https://unix.stackexchange.com/questions/14312/how-to-restrict-an-ssh-user-to-only-allow-ssh-tunneling