SSH tunnels are an incredibly useful resource, allowing easy port forwarding both for accessing remote services and opening them on a remote host. In this short tutorial, I'll show you how to configure this to setup a user who is only allowed to establish a remote tunnel, only on a certain port. This is especially useful for remote product access and maintenance.
Step 1 - Create user
sudo useradd -m tun-user
Step 2 - Customise the SSH config for that user.
sudo nano /etc/ssh/sshd_config
Add this section at the bottom. This restricts an SSH login to do the following:
AllowAgentForwarding no Disables ssh-agent forwarding
PasswordAuthentication no Only allow the user to authenticate using keys (prevents dictionary attacks)
X11Forwarding no Disables X11 forwarding
GatewayPorts no Makes it so that the user can only remotely open ports on localhost (i.e. not accessible over the network)
PermitTunnel no Disables using the
tun device for SSH forwarding.
ForceCommand echo... Ignores any shell commands from the client, instead executing the following statement.
AllowStreamLocalForwarding no Disables Unix Socket forwarding
AllowTcpForwarding remote Only allows remote SSH forwarding (
PermitOpen localhost:3456 Only permits TCP port forwarding to localhost:3456
Match User tun-user AllowAgentForwarding no PasswordAuthentication no X11Forwarding no GatewayPorts no PermitTunnel no ForceCommand echo 'This account can only be used for forwarding' AllowStreamLocalForwarding no AllowTcpForwarding remote PermitOpen localhost:3456
All sshd_config related information can be found in better detail from the manpage https://www.freebsd.org/cgi/man.cgi?sshd_config(5)
Step 3 - Generate SSH keys and authorise them
[email protected]:~$ sudo su tun-user
[email protected]:~$ ssh-keygen Generating public/private rsa key pair. Enter file in which to save the key (/home/tun-user/.ssh/id_rsa): Enter passphrase (empty for no passphrase): Enter same passphrase again: Your identification has been saved in id_rsa. Your public key has been saved in id_rsa.pub. The key fingerprint is: SHA256:XXXXXXXXXXXXXXXXXXXXXXXXXXXX [email protected] The key's randomart image is: +---[RSA 2048]----+ ... (etc) ...
cp ~/.ssh/id_rsa.pub ~/.ssh/authorized_keys
And now, copy
~/.ssh/id_rsa or a different keyfile if you used that, to the remote machine which you will be forwarding from.
Step 4 - SSH and forward
On the remote machine from which you will be establishing the tunnel, SSH into the gateway box, forwarding the relevant ports.
ssh -i ~/id_rsa [email protected] -R 80:localhost:3456 -N
You may notice that if
-N is omitted, the connection closes with the message This account can only be used for forwarding as previously set in the config. You may also notice that if you try to forward any other port, locally or remotely, it fails with the message channel 1: open failed: administratively prohibited: open failed.
The SSH session which tun-user can create has been locked down to only allowing remote forwarding on port 3456.
Step 5 (optional) - Use autossh for persistance
Download and install autossh with the command
sudo apt install autossh, and use it instead of SSH for a persistent connection.
Connect to your tunnel with the following command (place this in crontab or similar to ensure it executes on restart)
autossh -M 0 -o "ServerAliveInterval 30" -o "ServerAliveCountMax 3" -i ~/id_rsa [email protected] -R 80:localhost:3456 -N