This tutorial will tell you how to set up a rendezvous server which you can use to connect to your Linux servers without needing to open ports on your home network.
I will be using a Digital Ocean server as the rendezvous server but this should work on any Ubuntu 16.04 server.
Setting up the server end
So the first step is to setup the server end.
Add sslh to server
This is so that you can ssh into the server using port 443. This means you can connect to it from behind strict firewalls.
For information on sslh see their github page
$ apt install sslh
When the ncurses interface pops up choose standalone
After install you will need to edit a config file:
$ sed -i 's/RUN=no/RUN=yes/g' /etc/default/sslh
$ sed -i 's/<change-me>/0.0.0.0/g' /etc/default/sslh
If you want to double check the config file it should look something like the following:
$ cat /etc/default/sslh
# Default options for sslh initscript
# sourced by /etc/init.d/sslh
# Disabled by default, to force yourself
# to read the configuration:
# - /usr/share/doc/sslh/README.Debian (quick start)
# - /usr/share/doc/sslh/README, at "Configuration" section
# - sslh(8) via "man sslh" for more configuration details.
# Once configuration ready, you *must* set RUN to yes here
# and try to start sslh (standalone mode only)
RUN=yes # THE IMPORTANT LINE
# binary to use: forked (sslh) or single-thread (sslh-select) version
# systemd users: don't forget to modify /lib/systemd/system/sslh.service
DAEMON=/usr/sbin/sslh
DAEMON_OPTS="--user sslh --listen 0.0.0.0:443 --ssh 127.0.0.1:22 --ssl 127.0.0.1:443 --pidfile /var/run/sslh/sslh.pid"
Now restart the service:
$ systemctl restart sslh
$ systemctl status sslh
● sslh.service - SSL/SSH multiplexer
Loaded: loaded (/lib/systemd/system/sslh.service; enabled; vendor preset: enabled)
Active: active (running) since Wed 2018-04-04 23:24:21 UTC; 3s ago
Main PID: 1670 (sslh)
Tasks: 2
Memory: 184.0K
CPU: 1ms
CGroup: /system.slice/sslh.service
├─1670 /usr/sbin/sslh --foreground --user sslh --listen 0.0.0.0 443 --ssh 127.0.0.1 22 --ssl 127.0.0.1 443 --pidfile /var/run/sslh/sslh.pid
└─1672 /usr/sbin/sslh --foreground --user sslh --listen 0.0.0.0 443 --ssh 127.0.0.1 22 --ssl 127.0.0.1 443 --pidfile /var/run/sslh/sslh.pid
Apr 04 23:24:21 ubuntu-sshl-tutorial systemd[1]: Stopped SSL/SSH multiplexer.
Apr 04 23:24:21 ubuntu-sshl-tutorial systemd[1]: Started SSL/SSH multiplexer.
Apr 04 23:24:21 ubuntu-sshl-tutorial sslh[1670]: sslh-fork 1.17-2 started
If the service says it is not running double check your config file and try again.
Test SSLH
Now it’s time to test by trying to connect to it through 443:
$ ssh -p 443 root@server-ip
If the above was successful then it has all been setup correctly.
Nice to have
It is also recommended that you disable password authentication for more information on how to do this see the digital ocean tutorial
Add a user for other machines to ssh into
All you need to do is make sure you have a user that all these machines will connect to. It is recommended that you don’t use the root account.
Commands to add new user:
$ adduser ssh-user
Adding user `ssh-user' ...
Adding new group `ssh-user' (1000) ...
Adding new user `ssh-user' (1000) with group `ssh-user' ...
Creating home directory `/home/ssh-user' ...
Copying files from `/etc/skel' ...
Enter new UNIX password:
Retype new UNIX password:
passwd: password updated successfully
Changing the user information for ssh-user
Enter the new value, or press ENTER for the default
Full Name []: SSH User
Room Number []:
Work Phone []:
Home Phone []:
Other []:
Is the information correct? [Y/n]
Now change into the new user and create an ssh folder:
$ su ssh-user
$ cd ~
$ ssh-keygen # Hit enter for all the prompts
$ ls -la .ssh/
total 16
drwx------ 2 ssh-user ssh-user 4096 Apr 5 01:57 .
drwxr-xr-x 3 ssh-user ssh-user 4096 Apr 5 01:57 ..
-rw------- 1 ssh-user ssh-user 1679 Apr 5 01:57 id_rsa
-rw-r--r-- 1 ssh-user ssh-user 411 Apr 5 01:57 id_rsa.pub
It’s good to make sure that the permissions on the files are correct so that you don’t encounter errors.
Add your ssh-key so that you can login to the new user
$ cat ~/.ssh/id_rsa.pub | ssh -p 443 root@server-ip "cat >> /home/ssh-user/.ssh/authorized_keys && chown ssh-user:ssh-user /home/ssh-user/.ssh/authorized_keys"
Now make sure you can ssh into your new user:
$ ssh -p 443 ssh-user@server-ip
Setup client side
Now to set up the client side
Copy ssh key from client computer to server:
$ ssh ssh-user@client-ip "cat ~/.ssh/id_rsa.pub" | ssh -p 443 ssh-user@server-ip "cat >> ~/.ssh/authorized_keys"
Setup autossh on the client
Auto ssh is a great tool that allows a computer to maintain an ssh connection to another server even if that server comes on and offline.
Enter the following into your users crontab:
# Bind ssh port
@reboot autossh -f -NR 12345:localhost:22 ssh-user@server-ip
Now either run the command manually or reboot the client machine.
Check the client has connected to the server
Make sure your logged into the server.
When you run the following command you should get something similar to output shown below it.
$ ss -t -a | grep 1234 Tue 26 Jun 2018 06:58:30 PM UTC
LISTEN 0 128 127.0.0.1:12345 *:*
LISTEN 0 128 ::1:12345 :::*
SSH into the client from a third machine
In one terminal ssh into the server using the following commnd:
$ ssh -p 443 ssh-user@server-ip -L 23456:localhost:12345
Now in a second terminal window ssh into the client:
$ ssh -p 23456 client-user@localhost
But I only want to have one terminal open
If you don’t want to have an ssh session open just for port binding you can do the following to .ssh/config
Host server-ip
ControlPath ~/.ssh/cm_sockets/%r@%h:%p
ControlMaster auto
Port 443
Make the cm_sockets
directory:
$ mkdir -p ~/.ssh/cm_sockets
Now to login to the client from a third machine the following steps are taken:
$ ssh -fNT ssh-user@server-ip -L 23456:localhost:12345
$ ssh -O check ssh-user@server-ip # Note this is just to check the computer is connected to the server
Master running (pid=5810)
$ ssh -p 23456 client-user@localhost
Now when you want disconnect from the client you should also close your port binding session running in the background.
$ ssh -O exit ssh-user@server-ip
Exit request sent.
References
https://www.unixmen.com/sslh-a-sslssh-multiplexer-for-linux/
https://superuser.com/questions/277218/ssh-access-to-office-host-behind-nat-router