X11 VNC On demand
I have the peculiarity that I dislike laptops. While they are great for on the go, I still prefer a standard desktop tower machine for my regular work. However, as I’m traveling to my girlfriend each weekend, I won’t be able to work behind my tower. Next, being the chaotic person I am, I actually tend to forget to move files or sometimes I need functionality only available on my own machine. So I was investigating the most convenient way of reaching my machine remotely.
x11vnc
I’ve already worked with x11vnc in the past. Mostly to assist people remotely without requiring a closed-source propriety piece of software like TeamViewer. It works great and would help get into my desktop. I was already aware of security implications (VNC not being encrypted) so generally I was doing:
And next VNC’ing in
This works, but still requires me to type in x11vnc
.
systemd
While there is a lot of debate whether systemd
is a good or bad thing. However, I personally appreciate all its features it provides. While I understand separation of concerns and realize that exploding systemd
back into init
, inetd
, cron
might improve stability, I don’t really experience that much issues from this complexity.
I recently learned about user services, so I thought of having that as basis to autostart x11vnc
:
Next enabling it:
This will remove the need to launch x11vnc ...
. But, it’s not ideal. Because now x11vnc
will always run in the background.
systemd.socket
systemd
again to the rescue (together with a feature from x11vnc
). In the olden days, people used inetd
or xinetd
. It would allow one daemon which accepts connections and then spawn the respective program to handle the actual protocol. x11vnc
supports that with its -inetd
flag. Before starting (x)inetd, systemd
already supports sockets on its own. So, by creating a new config file and slightly tweaking the existing one, we can turn it into an on-demand service:
Next we should rename xvnc.service
to xvnc@.service
as required by socket activation, and edit it:
Now, systemd will automatically spawn x11vnc
when necessary, and bind the socket to its standard input and output. However, localhost may be used by anyone with access on this host. Now, for me this isn’t an issue as I’m the sole user, but as I like to reuse my stuff sometimes, I want to be on the safe side. Thankfully this is very easy.
Unix sockets and SSH
Many might not realize it (I didn’t) but since OpenSSH 6.7, SSH can forward unix domain sockets. This can even translate between regular TCP sockets. So it’s possible to forward local port 5900 to a remote unix-socket! So with a small adaptation:
This will create a /home/dsonck/.xvnc
socket (based on the username). This actually gives a few benefits:
- Access of
.xvnc
can be limited to the owning user (only allow me to connect to my desktop - Multiple users each have their own private
.xvnc
file whereas the old solution hardcoded5900
as port
It does require a slight adaption of the ssh command:
Which, to me, even looks cleaner: I want port 5900 to forward xvnc.
Conclusion
So, with the addition of two systemd
configuration files in /etc/systemd/user
, it’s possible to have x11vnc
automatically launch when necessary. Together with unix domain sockets it’s possible to add permissions to this socket to limit others from interfering. And OpenSSH allows us to connect our local vncviewer via a port to this remote unix domain socket.