Suppose you have a machine (like a Raspberry Pi) that lives behind a home router or on another inaccessible network.
Or, maybe this machine occasionally changes it's IP address.
This repo will set up a tunnel from the machine (called the local machine) to another machine (called remote) that has a reliable internet-connectible address.
You will be able to reliably connect to local by first connecting to remote and then jumping from remote to local via the configured remote_port.
Make sure the remote machine is reliably online.
I use a server with a static IP address, but you can also use a dynamic DNS name.
Create a remote_user for the tunnel; here, I use pitunnel.
Replace <ssh_key> with the SSH key you create in the Local setup section.
$ sudo useradd -m pitunnel
$ sudo su - pitunnel
$ mkdir ~/.ssh
$ chmod 700 ~/.ssh
$ echo <ssh_key> > .ssh/authorized_keys
$ chmod 600 .ssh/authorized_keys
$ exitThis user is only used for tunnels, so we can deny it interactive access.
$ tee /etc/ssh/sshd_config.d/pitunnel << DONE
Match User pitunnel
AllowTcpForwarding yes
X11Forwarding no
PermitTunnel yes
AllowAgentForwarding no
PermitTTY no
ForceCommand /usr/sbin/nologin
DONEYou should also configure the SSH service to time out stale connections.
Edit /etc/ssh/sshd_config and make add a section like so:
# disconnect idle clients after a minute
ClientAliveInterval 20s
ClientAliveCountMax 3
This will cause the SSH server to ping connected clients every 20 seconds, and disconnect if 3 pings fail.
Make sure your sshd_config is still valid by running:
$ sudo sshd -t && echo 'looks good' || echo 'sshd config is invalid'If it outputs looks good then you can go ahead and restart sshd:
$ sudo systemctl reload sshdFirst, install autossh:
$ sudo apt-get install -y autosshNext, create an SSH key for your tunnel. Don't specify a password.
$ ssh-keygen -t ed25519
$ cat ~/.ssh/id_ed25519.pub
<ssh_key>Copy the output (<ssh_key>) and paste it into the /home/<remote_user>/.ssh/authorized_keys file on remote.
Next, clone this repo and edit tunnel.sh.
You will need to customize these variables:
remote_host-- the hostname or IP of theremoteserverremote_port-- the port on theremoteserver wherelocalwill be availableremote_user-- the user you created in the remote setup section
If you're not running on a Raspberry Pi, you should also edit tunnel.service and customize this line:
User=pi
Replace pi with the local username (output of whoami).
Once configured, you can run install.sh:
$ sudo ./install.shThis will begin running the SSH tunnel.
To connect to the local machine, first connect to remote.
Then, on remote, run:
$ ssh pi@localhost -p <remote_port>Replace pi with your local username (whatever you put as User= in local setup.
So long as local can communicate with remote, the tunnel will be re-created if it does for any reason.
It might take a minute or two for existing connections to time out, so keep trying if it doesn't work at first.
To check on the status of the tunnel, you can run:
$ systemctl status tunnel