Skip to content →

How to set up a remote desktop session on Debian Linux via VNC (tightvncserver)

Sometimes it is necessary to have a graphical user environment on a remote machine. Windows server instances can sometimes be too expensive for the given usage scenario. This guide will walk through the process of setting a remote desktop environment on Debian Linux.

Optionally install sudo

 apt-get install sudo

Update your apt-cache and packages using

sudo apt-get update && sudo apt-get upgrade

Install the following packages for a smooth desktop environment

sudo apt install xfce4 xfce4-goodies xorg dbus-x11 x11-xserver-utils gnome-icon-theme gnome-panel metacity nautilus gnome-settings-daemon

To enable copy-paste functionality please also install

sudo apt install autocutsel

Now to create a VNC specific user, as some applications like Google Chrome may by default refuse to run under root

adduser vncuser

Optionally you may wish to remove the restriction on password-complexity for your system as at times it can enforce a set of password restrictions that are not compatible with our version of VNC

nano /etc/pam.d/common-password

Remove enforce_for_root

Now we need to add the new user to sudoers group

gpasswd -a vncuser sudo

Install TightVNCServer (I will avoid TigerVNC, and Vnc4Server for now as they both have their respective issues)

sudo apt-get install tightvncserver

Start the VNC server using the following command


Now to setup both a regular password as well as a view-only password

Let’s kill the server using the following command

vncserver -kill :1

At this point we’ll want to do the same for our created user so

su vncuser
vncserver -kill :1

Setup both passwords again for vncuser this time and kill it as we did last time

Either upload or via your favorite text editor create the files /root/.vnc/xstartup and /home/vncuser/.vnc/xstartup and add the following contents whilst ensuring that the files are owned by their respective users

#Uncomment the following two lines for normal desktop:
#exec /etc/X11/xinit/xinitrc
#Uncomment this line to enable copy-paste (note that VNC is not secure by itself!)
#autocutsel -fork &
startxfce4 &
[ -x /etc/vnc/xstartup ] && exec /etc/vnc/xstartup
[ -r $HOME/.Xresources ] && xrdb $HOME/.Xresources
xsetroot -solid grey
vncconfig -iconic &
gnome-panel &
gnome-settings-daemon &
metacity &
nautilus &
gnome-terminal &
exec /home/vncuser/autostart/

Note that if you want to make anything start up with the system simply place it into /home/vncuser/autostart/

Now to make VNC server a system service, first create the directory for the config files

mkdir /etc/vncserver

Now upload or edit in the following as the file /etc/vncserver/vncservers.conf

VNCSERVERS="1:root 2:vncuser"
VNCSERVERARGS[1]="-geometry 1920x1080 -depth 24"
VNCSERVERARGS[2]="-geometry 1920x1080 -depth 24"

Now to create the actual service, upload or edit in the following as the file /etc/init.d/vncserver


# Provides:		vncserver
# Required-Start:	$remote_fs $syslog
# Required-Stop:	$remote_fs $syslog
# Default-Start:	2 3 4 5
# Default-Stop:		
# Short-Description:	VNC Service for Remote Desktop

[ -f /etc/vncserver/vncservers.conf ] && . /etc/vncserver/vncservers.conf
prog=$"VNC server"

start() {
        . /lib/lsb/init-functions
        echo -n $"Starting $prog: "
        ulimit -S -c 0 >/dev/null 2>&1
        for display in ${VNCSERVERS}
                export USER="${display##*:}"
                if test -z "${REQ_USER}" -o "${REQ_USER}" == ${USER} ; then
                        echo -n "${display} "
                        unset BASH_ENV ENV
                        export VNCUSERARGS="${VNCSERVERARGS[${DISP}]}"
                        sudo -u ${USER} -H sh -c "cd ~${USER} && [ -f .vnc/passwd ] && vncserver :${DISP} ${VNCUSERARGS}"

stop() {
        . /lib/lsb/init-functions
        echo -n $"Shutting down VNCServer: "
        for display in ${VNCSERVERS}
                export USER="${display##*:}"
                if test -z "${REQ_USER}" -o "${REQ_USER}" == ${USER} ; then
                        echo -n "${display} "
                        unset BASH_ENV ENV
                        export USER="${display##*:}"
                        su ${USER} -c "vncserver -kill :${display%%:*}" >/dev/null 2>&1
        echo -e "\n"
        echo "VNCServer Stopped"

case "$1" in
start $@
stop $@
stop $@
sleep 3
start $@
if [ -f /var/lock/subsys/vncserver ]; then
stop $@
sleep 3
start $@
status Xvnc
echo $"Usage: $0 {start|stop|restart|condrestart|status}"
exit 1

Now to make the service executable, add it the startup and start it

sudo chmod +x /etc/init.d/vncserver
sudo update-rc.d vncserver defaults
sudo update-rc.d vncserver enable
sudo service vncserver start

Congratulations! You should now have a working VNC server and you can test it by connecting to the default VNC port and :1 :2 respectively. (eg: SERVER-IP:2 will connect you to vncuser‘s desktop)

A few important notes:

VNC is unencrypted by default and vulnerable to a man-in-the-middle attack (that means don’t send any important data over the link because it will be open for viewing to the public internet).

If you wish to make it secure you may need to tunnel using either OpenSSH/VPN/SOCKS5 or any other kind of tunneling.

A simple way to is to tunnel over SSH, this can be done on any Linux client by doing the following (where the 1 in the 5901 refers to the desktop number eg 1 for root, 2 for vncuser in our example):

ssh -L 5901:localhost:5901 USER@REMOTE_IP

Now in order to connect to VNC you just need to point your VNC client to localhost:5901 and you will automatically be tunneled over ssh to your Remote IP!

Should you want to change the port VNC is running on (which I highly recommend unless you want to get spammed with bad logins by IP scanners), please change the following file on the line indicated by the command (and restart):

grep -n vncPort /usr/bin/vncserver

If you’re using Linux on your client machines; there is a far better alternative to VNC called
X2Go that you may wish to look into.

Published in Uncategorized

One Comment

Leave a Reply

Your email address will not be published. Required fields are marked *