April 18, 2021

Managing family computers remotely

In my spare time, I (really) dislike being disturbed by people who notice problems on their computers. It also applies to printers. But worse, I hate doing remote support only by phone. As you can't see the screen, it takes hours to do a very trivial task. That was the issue I had to solve after installing Linux on computers, for my whole family (two computers so far).

This problem has arisen on several occasions and my first attempt to fix it, was to set up Skype. It allows screen sharing in addition to the basic Internet call. I thought it would do the trick… Disclaimer, it didn't. Many times, lauching or using Skype was very difficult for my parents. Here is a summary of the common complains :

Usually, we got stuck for 20 minutes, before I could actually debug the issue. I was quite annoyed or frustated. Another personal gripe I had with myself was related to using a service owned by a company, widely known to not respect privacy.

Making use of Firefox and WebRTC screen sharing was not possible (too complicated). Dozens of free or paid softwares could satisfy my need, but there are all opaque. You do not know what is done behind your back. Some of them encrypt communications with flawed and closed source cryptography. So what to do ?

Use OpenSSH. It's probably my favorite software. Unfortunately, the remote IP address is dynamic, it changes from time to time. Thankfully, ssh client can remotely forward local port with -R, allowing you to create a tunnel between a server and the dynamic IP client. I could also do it with WireGuard, but at that time, I had more experience with ssh. I used remote forward for years, mostly to connect to highly critical networks, unavailable from outside. Here an example from the client :

$ ssh -R <LOCAL_PORT>:localhost:22 <SERVER>

In my case, the server can be reached from anywhere. Then, how to connect without typing a password ? I'll use a dedicated user with its dedicated ed22519 key and I'll restrict it to tunneling only, no shell will be available. It is a security if the computer gets stolen (even if the data are encrypted) or the key compromised. In the remote server authorized_keys for tunneldude user, I write this line :

$ cat .ssh/authorized_keys
command="",no-agent-forwarding,no-pty,no-user-rc,no-X11-forwarding,permitlisten="<LOCAL_PORT>" ssh-ed25519 <PUBLIC_CLIENT_KEY>

The password-less key is forbidden to do anything, except to listen to the specified port. /sbin/nologin shell is also defined for tunneldude in /etc/passwd.

The next question is how and when the client will connect to the server ? I started to use autossh but two other matters appeared : even if my family trusts me, I could potentially always connect to the computer, without asking for consent. That's not good. You should always ask for consent, especially in your private life. And due to network instability, the server was often spammed by new incoming TCP connections from us. Then, the firewalls were sometimes blacklisting the IP. I couldn't really create a solid rule, as the address constantly changes. Therefore, I quickly abandon that idea.

Besides autossh daemon, a simple script written by me was added at an obvious location on the computer. I did it as a safety plan, in case autossh was unable to work as intended and it became the only tool used for the connection. I called it VPN.sh despite not being a real VPN as we know it, because it is easier for my family to remember the name. Like "can we do a VPN session ?" or "could you launch the VPN script please ?", compared to "please launch the you_know_script_thatconnects_us" or "we need to do a session with your magic thing, I don't remember the name". You probably understand if you do IT support. And they feel secure as they start the script by themselves, only when they have to.

It includes ssh options like -4, -C, -N, -T or -o "TCPKeepAlive yes". There is almost nothing else. Soon after, I launch this command and I have a shell on the client :

$ ssh -J <REMOTE_SERVER> <USER>@127.0.0.1 -p <LOCAL_PORT>

Since the tunnel is perfectly initiated, it means we can forward some content inside it. VNC, here we go ! During COVID lockdowns, I strangely came back to it (at work particularly), it's convenient and easy to use. I can control the distant keyboard and the mouse as well. It will be helpful in that case. The next step was what server to use. I want to see the current X session, not create a new one. The choice was simple, it is x11vnc. On the remote client, I launch it with :

$ x11vnc -usepw -localhost -display :0; pkill x11vnc; shred -u ~/.vnc/passwd

x11vnc will accept connection from 127.0.0.1 only, will prompt me for a password and will stop by itself after I close the connection. Just in case, I then apply pkill and also remove the password file. It won't leak and I can change it for the next session.

On my side, I run this command :

$ ssh -i <SECRET_KEY> -C -L 9999:localhost:5900 -J <REMOTE_SERVER> <USER>@127.0.0.1 -p <LOCAL_PORT>

My local 9999 port will be redirected to remote 5900 port (the one used by VNC). That command gives a shell to initiate VNC using previous x11vnc snippet and creates the tunnel. As I'm getting old, my local VNC client is Remmina. It provides cool features like screenshot, keyboard grabbing even with Wayland, quick connect, stream quality, few dependencies and a friendly UI. For the vocal communication, I just use my phone and call the person. This entire solution is applied on the other computer.

On both computers, we operated as described here for months. The performance were good (from "Poor" to "Best" quality in Remmina), my parents were not lost and we swiftly fixed what we had to. I'm really happy of this setup, as it combines different protocols and softwares, we control the whole chain and the security aspect is not forgotten. In the future, I may add Wireguard support. Performance could be better due to the kernel module and UDP.