SSH: Create a tunnel-only user for reverse tunnels

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 (ssh -R)

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
Published 2017-04-06