Persistent SSH Tunnels
Persistent SSH Tunnels
The following is how to create a persistent SSH Tunnel between two systems. This is handy if you want to secure data flowing across networks, or even setup a tunnel without messing with VPN configuration.
Create User/Generate SSH key
First you will create the user you will use for the tunnel. This will allow you to forward non-privileged ports over 1024.
Note: This user does not have a password assigned or a shell. This will prevent user logins to the system.
useradd -m -s /bin/false autossh
Now switch to the user and generate an SSH key:
su -s /bin/bash useradd cd ~ ssh-keygen -b 4096
Note: Leave password blank
Once done, exit back to your normal user shell
exit
Copy public key to target system
You will need to copy id_rsa.pub file from /home/useradd/.ssh/ to the authorized_keys file on the remote system you want to connect to for the tunnel.
Note: It is recommended that you also create a normal user on the remote system and not use root.
Install autossh
You will need to install the autossh program on the system that will initiate the SSH tunnel. Autossh automatically restarts the SSH tunnel when it exits.
apt-get install autossh
Setup script
Copy the following script, making the necessary changes as specified between the <> and place on the system that will initiate the tunnel (usually /opt):
#!/bin/sh # # Uses autossh to establish a tunnel to allstarlink.org for the Graylog Collector Sidecar # on seal to pass data. su -s /bin/sh autossh -c 'autossh -M 0 -N -o "ServerAliveInterval 30" -o "ServerAliveCountMax 3" -o "ExitOnForwardFailure=yes" -f -T -R localhost:<target port>:<local IP or localhost>:<local port> <user>@<domain>'
Parameter | Description |
---|---|
localhost | localhost or IP address on target system |
<target port> | port on target system |
<local IP or localhost> | localhost or IP address on system initiating tunnel |
<local port> | port on system initiating tunnel |
<user@domain> | username and domain to use when SSHing to target system |
An example of this command is:
su -s /bin/sh autossh -c 'autossh -M 0 -N -o "ServerAliveInterval 30" -o "ServerAliveCountMax 3" -o "ExitOnForwardFailure=yes" -f -T -R localhost:3306:localhost:3306 joe@blow.com'
This would allow the target (remote) system to access the local (system initiating the SSH tunnel) system's MySQL server over the tunnel.
You can also use -L to change the direction of the port forwarding from Remote to Local and have the initiating system forward data over the tunnel the the remote.
Make script executable
Make sure you mark the script as executable with:
chmod +x <name_of_script>.sh
Tunnel at startup
To have this tunnel automatically start if the system is rebooted, add a call to the script to rc.local.
/opt/<name_of_script>.sh
Note: You may have to enable rc.local on Ubuntu and Debian based systems via systemd. Refer to your distribution's documentation for information on how to enable it.