Anyone who works with Linux servers will have used SSH. It’s the stable of server management and cannot beat a GUI.The only downside with SSH is when you’re on a slow or intermittent connection, and your SSH connection keeps droppingout or locking up. It’s not fun at all…
Enter Mosh. Mosh replaces SSH and allows connections to disconnect and lag without affectingthe user. It doesn’t lock up, and tells you when you’ve lost server connection – so you know what’s going on.When it gets connection back, so do you. It runs in the local account on both sides of the connection, which meansyou don’t need an extra service running, and any user on the machine can use it. SSH is used for the initialauthentication, so all your password, keys, and port forwards will still work.
Mosh has one downside: it uses a unique UDP port for each connection, and by default expects UDP ports
60000 - 61000to be open and ready to be used. It doesn’t reserve them, it just uses them when it needs to.From a security point of view, this isn’t good. It’s not that I think Mosh has security vulnerabilities, but if Iopen up those 1,000 ports on my server – anything else on the server can pick one and bypass my firewall…which is bad.
So, what can we do about it?
Since I use UFW as my firewall of choice on a Ubuntu server, I decided to see if I could write a script thatautomatically opens the ports that Mosh needs when it needs them, and closes them again when it’s finished.
Something like this should do the trick:
What the script does is quite simple:
- It checks what ports are open for
- Loops through each of the open port numbers (line 8).
- For each port, it checks if the port is allowed in UFW (line 10).
- If it’s not, then it allows it (line 13).
- Then it loops through each of the UFW allowed ports (line 18).
- Checks if there is a
mosh-servprocess that has it open (line 23).
- If not, it closes the port through UFW (line 26).
The result is that only the active Mosh ports are open.
This could be run via cron every minute, but you’d need to get lucky when starting a Mosh connection, so it’s farbetter to run it on each user login. However, there is a problem with this… notice the
sudo commands?The user doesn’t want to type their sudo password on each login, so we need to get creative here.
Save the script somewhere global, such as
/usr/local/bin/mosh-allow-ufw, and then add a line into
valorin ALL=(ALL:ALL) NOPASSWD: /usr/local/bin/mosh-allow-ufw
Follow it up with an entry into your
~/.bashrc file, which will trigger it on each login:
In theory, you should now be able to Mosh into a server, and the server will automatically open the ports,and then Mosh will run. The only open ports will be those in use by Mosh.Rather than 1,000 ports open, we will only have one per connection.
Finally, to sum it all up, and because I am a big Ansible fan, we can automate the entire process.
There we have it: Mosh and UFW, without needing 1,000 ports open! 🙂