Skip to main content

SSH Reverse Tunnels

344 words·2 mins·

All you need to know about SSH tunneling

What
#

The Secure Shell SSH protocol sets up encrypted connections for remote logins and file transfers between computers. SSH also enables tunneling.

Why
#

  1. SSH Tunneling is used to create cyphered connections between hosts. The use of this virtual network allows to avoid some access restrictions.
  2. Secured access to remote hosts

How
#

Grant ssh access on <remote_host> from <local_host>

Server side (<remote_host>)

Check /etc/ssh/sshd_config values:

AllowAgentForwarding yes
AllowTcpForwarding yes
GatewayPorts yes
TCPKeepAlive yes

Restart sshd with systemctl restart sshd command

Create an account for the sshtunnel user but restrict it so that shell logins and remote commands are not allowed. The server will only allow the remote sshtunnel user to set up port forwarding

sudo useradd -m -s /bin/true sshtunnel
sudo mkdir -p ~sshtunnel/.ssh

Make sure permissions are set as ssh requires them:

sudo mkdir ~sshtunnel/.ssh
sudo touch ~sshtunnel/.ssh/authorized_keys
sudo chown -R sshtunnel:sshtunnel ~sshtunnel/.ssh
sudo chmod 700 ~sshtunnel/.ssh
sudo chmod 600 ~sshtunnel/.ssh/authorized_keys

Client side <local_host>

Generate certificates on client:

sudo ssh-keygen -qN "" -f /etc/sshtunnel/id_rsa

Install client certificate as an authorized_key on the server with this command:

  • Copy client’s public certificate /etc/sshtunnel/id_rsa.pub into server’s sshtunnel ~sshtunnel/.ssh/authorized_keys:

    sudo cat /etc/sshtunnel/id_rsa.pub | ssh root@<remote-server> -T "cat  >> /home/sshtunnel/.ssh/authorized_keys"
    

    Check if key has been copied to `authorized_keys" properly:

    ssh root@<remote-server> "cat /home/sshtunnel/.ssh/authorized_keys"
    

    From the client, check you remote ssh to server with sshtunnel user:

    sudo ssh -i /etc/sshtunnel/id_rsa sshtunnel@<remote-server>
    
    Warning Connection will be closed because sshtunnel user does not have a shell

SSH Tunneling
#

Command

ssh -qN -i /etc/sshtunnel/id_rsa -R <remote_port>:<local_host>:<local_port> <remote_user>@<remote_host> -p <remote_ssh_port>

SSH Tunnel Service
#

Create/paste the following systemd service file in /etc/systemd/system/sshtunnel.service and then edit it as needed for your specific server and ports:


[Unit]
Description=Service to maintain an ssh reverse tunnel
Wants=network-online.target
After=network-online.target
StartLimitIntervalSec=0

[Service]
Type=simple
ExecStart=/usr/bin/ssh -qNn \
-o ServerAliveInterval=30 \
-o ServerAliveCountMax=3 \
-o ExitOnForwardFailure=yes \
-o StrictHostKeyChecking=no \
-o UserKnownHostsFile=/dev/null \
-i /etc/sshtunnel/id_rsa \
-R <remote_port>:<local_host>:<local_port> \
sshtunnel@server.net -p 443

Restart=always
RestartSec=60

[Install]
WantedBy=multi-user.target

Enable and start the new service:

sudo systemctl enable sshtunnel.service
sudo systemctl start sshtunnel.service