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
vncserver
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
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
#!/bin/sh
#Uncomment the following two lines for normal desktop:
unset SESSION_MANAGER
#exec /etc/X11/xinit/xinitrc
unset DBUS_SESSION_BUS_ADDRESS
#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/startup.sh
Note that if you want to make anything start up with the system simply place it into /home/vncuser/autostart/startup.sh
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
#!/bin/bash
### BEGIN INIT INFO
# 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
### END INIT INFO
unset VNCSERVERARGS
VNCSERVERS=""
[ -f /etc/vncserver/vncservers.conf ] && . /etc/vncserver/vncservers.conf
prog=$"VNC server"
start() {
. /lib/lsb/init-functions
REQ_USER=$2
echo -n $"Starting $prog: "
ulimit -S -c 0 >/dev/null 2>&1
RETVAL=0
for display in ${VNCSERVERS}
do
export USER="${display##*:}"
if test -z "${REQ_USER}" -o "${REQ_USER}" == ${USER} ; then
echo -n "${display} "
unset BASH_ENV ENV
DISP="${display%%:*}"
export VNCUSERARGS="${VNCSERVERARGS[${DISP}]}"
sudo -u ${USER} -H sh -c "cd ~${USER} && [ -f .vnc/passwd ] && vncserver :${DISP} ${VNCUSERARGS}"
fi
done
}
stop() {
. /lib/lsb/init-functions
REQ_USER=$2
echo -n $"Shutting down VNCServer: "
for display in ${VNCSERVERS}
do
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
fi
done
echo -e "\n"
echo "VNCServer Stopped"
}
case "$1" in
start)
start $@
;;
stop)
stop $@
;;
restart|reload)
stop $@
sleep 3
start $@
;;
condrestart)
if [ -f /var/lock/subsys/vncserver ]; then
stop $@
sleep 3
start $@
fi
;;
status)
status Xvnc
;;
*)
echo $"Usage: $0 {start|stop|restart|condrestart|status}"
exit 1
esac
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.
Thanks for the great post