Virtual Network Computing or VNC makes it possible to remotely access the graphical desktop environment of another machine. There are a number of projects out there that implement the VNC protocol. Typically, these projects provide two applications: a VNC server and a VNC client. The remote target machine runs the VNC server program. A VNC client instance connects to the target’s VNC server. The client application is a GUI application that renders the graphical display of the remote target. The image below illustrates the concept:
In this article, you’ll see how to setup a VNC server and client on Linux using TigerVNC.
Prerequisites and Assumptions
This article assumes you are on an Arch Linux machine with an Internet connection. That said, the instructions that follow should work for any Linux distro though the package installation commands will certainly need tweaking.
Step-By-Step
TigerVNC is the recommended VNC implementation. TigerVNC provides both the client and server application. To install TigerVNC, run the following command:
pacman -S tigervnc
VNC Server Setup
Create a password by running
vncpasswd
. The password file saves to$XDG_CONFIG_HOME/tigervnc/passwd
. Make surepasswd
has its permissions set to0600
.Add users by editing
/etc/tigervnc/vncserver.users
. User entries consist of both a display number and username. You can spawn multiple server instances, one per display. Note, the display number is automatically associated with a TCP port. For example, display:1
binds to port \(5900 + 1 = 5901\), display:2
binds to port \(5900 + 2 = 5902\), etc. Below is an examplevncserver.users
file containing a single user:
# TigerVNC User assignment
#
# This file assigns users to specific VNC display numbers.
# The syntax is <display>=<username>. E.g.:
:1=ieg
- Start one or more server instances using systemd. Load the VNC server service
for one or more displays. For example, to start the server for display
:1
:
sudo systemctl start vncserver@:1.service
VNC Client Setup
- Connect to the VNC server using the
vncviewer
application. The syntax isvncviewer HOSTNAME::PORT
.HOSTNAME
is the hostname or IPv4 address of the remote machine.PORT
is the TCP port exposed by the server. The TCP port is always the display number plus \(5900\). As an example, suppose the VNC server is running on a machine with hostnamefoo
. On the machine hosting the server, the VNC server systemd service is running for display:1
. To connect the client to the server:
vncviewer foo::5901
Type your VNC password into the password prompt.
Optionally, adjust client settings by clicking the client window and then pressing
F8
.
Note, certain keystrokes aren’t registered by the client. In particular, the mod
key (AKA windows/command key) is always intercepted by the host system. This is
particularly annoying if the remote’s desktop environment is a window manager
like i3. The best solution at this time is to rebind the function of the mod key
on the remote host to some other key (for example, Alt
).
Secure Connections
Following the steps in the last section gives you a working VNC connection. However, that connection is insecure! In TigerVNC, you can improve the security of your connection by tunneling traffic through SSH. The benefit here is that all VNC traffic travels through the port used by SSH. Of course, to connect via SSH you have to authenticate with the machine hosting the VNC server.
The next two sections describe the server and client side changes you need to make to tunnel VNC traffic through SSH.
Server Side Changes
- Create
$XDG_CONFIG_HOME/tigervnc/config
. Below is an example configuration. Setsession
to the desktop environment installed on the server system. Setgeometry
to your desired screen dimensions. Thelocalhost
option makes it so only connections from localhost get to the server. This setting then implies only users SSH’ed to the VNC server host can establish a VNC session.
session=i3
geometry=1920x1080
localhost
alwaysshared
- Restart your VNC server service using systemd. For example:
sudo systemctl restart vncserver@:1.service
Client Side Changes
The server at this point only accepts connections from localhost. On the client side, you want to SSH to the remote host and connect to the server’s VNC port. The port used by SSH and the VNC port differ. However, it’s possible to tunnel traffic between the two ports. The following command does the trick:
vncviewer -via 10.1.10.2 localhost::5901
10.1.10.2 is the IP address of the remote machine. 5901 is the VNC port of the
server running on the remote. Adjust these values for your setup. The -via
switch creates an encrypted TCP tunnel to the remote machine. It does a bit of
magic in the background and is customizable via the VNC_VIA_CMD
environment
variable. See the docs for the full details.