Saturday, October 31, 2015

Building a Virtual Desktop Server

Every so often the business world cycles through the idea that end-users don't need computers on their desk and they can use thin clients instead. Inevitably, this fails because the user experience is inadequate. Powerful applications won't run very well or at all. This can include those big Excel spreadsheets that finance people need to use. Even when things do run, the screen updates horribly slowly. So, in the end, everyone has a desktop or laptop back.

However, the virtual desktop doesn't quite die because it still has some uses. System administrators like them for remote management of servers. They can be adapted to function as a sort of remote connection for end-users who are outside the office but don't have a company issued laptop. The technology that makes virtual desktops work is used by help desk staff for remote control of end-user computer. There are many edge cases that keep the technology alive.

Since everything that will be used in this process is not a part of the core operating system, these instruction should work with very little modification on almost any UNIX or UNIX like operating systems. The testing and quoted configurations in this journal entry are from FreeBSD 10.2.


It is common practice in the UNIX world to use VNC as a remote desktop client for UNIX systems running X11 where the client computer does not have an X11 server installed. It is even further common practice to tunnel the VNC traffic through ssh. This is so common that there is a modified version of the TightVNC client with the SSH capabilities built in (called ssvnc). This standard identifies the specific packages and configuration needed to support a multi-user environment with SSH, VNC, and XDM.
  • VNC run through inetd. Allows for up to 64 dynamically assigned virtual desktops without VNC screen sharing.
  • XDM runs as a daemon through the rc system. The server does not need to have a GUI enable or an X11 server installed.
  • The VNC password must be shared BUT users are still required authenticate individually.
  • Two-factor authentication and network session security are provided by SSH.


With this configuration, a user is able to log-in using SSH to the command-line interface and bypass the XDM login screen. However, the user did have to authenticate the ssh connection using certificates. If there is a passphrase on the certificate, then the user still performed two-factor authentication. This may be consider as flexibility provided to users who are comfortable with the UNIX command prompt while not hindering users who are not as comfortable.


  1. When the system first boots, it can take several seconds for inetd to fully start-up. This may result in the system appearing to be down or non-responsive when connecting immediately after startup. Wait a few seconds and try again.
  2. The OSX VNC client (called Screen Sharing) does not gracefully exit. This can result in the XDM daemon delaying reset for the affected desktop. When this happens the login screen will not be presented to the end-user for several seconds (until Xvnc attempts to re-try the query). The easiest solution is to advise users to re-try connecting if they fail to get a login prompt.
  3. The XDM and TightVNC binary packages for FreeBSD do not identify all pre-requisites needed for those packages to function fully. A list of the missing packages is identified in this document.
  4. The SSH match group section (at the bottom) has not been tested. It may not function as intended with this setup.


The following packages must be installed. All are available a pre-built binaries in the FreeBSD package repository.

Pre-requisites Packages

  • xrdb - a prerequisite of VNC that is not identified in the VNC server package.
  • xset - a prerequisite of VNC that is not identified in the VNC server package.
  • sessreg - a prerequisite to XDM that is not identified by the package.
  • xorg-fonts - pre-requisite of XDM that is not identified in the package.
  • xsetroot - optional: used to make the login desktop look nicer.
  • xterm - optional: prerequisites of the VNC server however, that functionality is not used in this setup.
  • twm - optional: prerequisites of the VNC server however, that functionality is not used in this setup.
  • xlsfonts - optional: helps with debugging font problems.
  • xfotnsel - optional: helps with debugging font problems.
Other packages will get installed automatically as pre-requisites of the main packages. The ones listed above should be but aren't by default.

Packages to Install

  • xdm - the X11 Display Manger used to present the user with a login screen.
  • tightvnc - the Virtual Network Client that provides a remote desktop display (since remote X11 is not always available).

Pre-requisite Services

A working SSH server must be installed and running on the server. It needs to be configured to allow port forwarding from clients. The default SSH server included with FreeBSD is configured this way and should be enabled in the rc subsystem already (if not, add the line sshd_enable="YES").


VNC and Inetd

In order for OSX (Apple Mac users) to connect, the VNC server must present a password. We will therefore create a simple VNC password file to be used. This password will need to be shared among all users. It is not for security purposes, it is used due to a technical limitation. DO NOT USE THE ROOT PASSWORD or your own. If in doubt, use the word "password". The following steps are used to create this password:
cp ~/.vnc/passwd /etc/vncpasswd.nobody
chmod 0600 /etc/vncpasswd.nobody
chown nobody /etc/vncpasswd.nobody


By running the VNC server through inetd, we are able to dynamically assign X11 desktops to users as they connect. This creates an service very similar to a Citrix VDI solution.
vnc stream tcp nowait  nobody /usr/local/bin/Xvnc Xvnc -inetd -query localhost -localhost -once -desktop VictorVM -geometry 1280x720  -depth 24 -rfbauth /etc/vncpasswd.nobody
All users will have a screen size of 1280x720 as defined by the -geometry parameter. This may be changed but it must be the same for all users. Note that the most common laptop screen resolution is currently 1366x768. Higher values may cause problems for some users.


The pre-packaged XDM is poorly set-up and not intended to operate the way we are setting it up, as such there are several steps that must be taken.


Normally xdm is run from /etc/ttys on virtual terminal 8 but this would require a local graphical console. Instead we will run it as a daemon process. Create a daemon control script for the service manager subsystem. The script should be placed in the file /usr/local/etc/rc.d/xdm, owned by root, and executable by root.


# PROVIDE: xdm
# KEYWORDS: shutdown

. /etc/rc.subr


load_rc_config $name
run_rc_command "$1"


Comment out the last line of the Xservers file to prevent xdm from trying to start a local X server on the console.
# Comment out the local line so that we are only providing XDMCP support
#:0 local /usr/local/bin/X :0 


Enable the XDMCP listener functionality of xdm. By adding a line to the end of the file:


For some reason the default Xresources file attempts to make use of fonts that are not available to XDM when it is run as a daemon. There is probably a way to add those fonts with additional configuration of Xvnc but it is easier to modify this file to make user of fonts that are available. The following are the lines that need to be changed.
xlogin*greetFont: -sony-fixed-medium-r-normal--24-170-100-100-c-120-iso8859-1
xlogin*font:       -sony-fixed-medium-r-normal--16-120-100-100-c-80-iso8859-1
xlogin*promptFont: -sony-fixed-medium-r-normal--16-120-100-100-c-80-iso8859-1
xlogin*failFont: -misc-fixed-bold-r-normal--14-130-75-75-c-70-iso8859-1
xlogin*greetFace:       Fixed-24
xlogin*face:            Fixed-16
xlogin*promptFace:      Fixed-16
xlogin*failFace:        Fixed-14:bold
Note: in the default file, these lines appear twice and the specific set selected depends on the screen resolution. It is safes to simply change both.


Comment out the link that disable XDMCP. It should be the last line in the file. It is the resource defined by DisplayManger.requrestPort.
! Comment out this line if you want to manage X terminals with xdm
!DisplayManager.requestPort: 0


Once everything else is configured, the rc system can be configured to start the daemons on system startup. The following lines should be added to /etc/rc.conf:
inetd_enable="YES" # running VNC server through INETD
xdm_enable="YES" # try to start xdm for the VNC server(s)

End User Desktop Setup

The choice of end-user desktop environment will be very purpose dependent. There are a great many choices available. The setup presented here is intended for basic testing only. A more modern desktop environment should be chosen and configured.


Each user with X11 (GUI) access should have a .xsession file in his/her home directory. Here is a very basic setup intended for testing only.

xrdb $HOME/.Xresources
xsetroot -solid grey
xterm -geometry 80x24+10+10 -ls -title "$VNCDESKTOP Desktop" &
When the window manager (twm) exits, the user is logged out and the XDM login screen should reappear.

Optional: Two-factor Authentication

If this service is to be provided over the Internet, it is advisable to enforce two-factor authentication. This can be achieved by enforcing the user of certificate based authentication for SSH. Note: the two factors are the ssh certificate (something-you-have) and the passphrase on that certificate (something you know). The VNC password and the unix password for xdm are not needed.


To enforce the use of certificate authentication with SSH requires some minor changes to the default configuration. The following identifies only the lines that need changing within that file:
# It is strongly advised to not allow direct remote-root login on all publicly facing servers
PermitRootLogin no

# enable RSA and DSA certificate authentication
RSSAuthentication yes
PubkeyAuthentication yes

# prevent ~/.rhosts authentication
IgnoreRhosts yes

# prevent username & password authentication
ChallengeResponseAuthentication no

Since the passphrase on the ssh certificate cannot be technically enforced, it may be desirable to restrict users so that they are only able to use the VNC tunnel. Additions are needed to the sshd_config file:
Match User limited-user
   #AllowTcpForwarding yes
   #X11Forwarding no
   #PermitTunnel no
   #GatewayPorts no
   AllowAgentForwarding no
   PermitOpen localhost:5900
   ForceCommand echo 'This account can only be used for SSH+VNC access.'

A group called 'limited-user' will need to be created and all users that should not have ssh shell access added to that group. Note: This will not prevent the user xterm or other methods of gaining shell access through the GUI provided.

Configuring the Client(s)

OpenSSH and VNC are available for almost every current operating system in use today on desktops, tablets, and smart phones. Several of them have one or both of these included with the operating system.

Connecting from Windows

We will need to install two applications on our Windows desktop: Putty (for SSH) and TightVNC. Windows installers for both are available from their respective websites. Anyone who is attempting to complete the steps outlined in this article should be able to perform the software installation without difficulty.
  • Putty for Windows
  • TightVNC for Windows
There are alternatives to both Putty and TightVNC some commercial and some free. These are freely available and what I choose to use on Windows.

PortableApps on Windows

PortableApps is a collection of freely available software for Windows that have been configured to be run directly from a USB thumb drive or other portable media. This option is handy because you can load the appropriate applications on to your thumb drive and keep it in your pocket. Thus any available Windows computer that you can run the application from becomes useful as a client for your virtual desktop server.

Connecting from Apple OSX (iMac, Mac Mini, Macbook, and friends)

The SSH and VNC clients are part of the base operating system. No additional software needs to be installed.

Connecting from Apple iOS (iPad and iPhone)

Guess what? There is an app for that. There are in fact many apps for it. This example will use the iSSH app. It may not be the best. It was the first one I ran across that was free, worked, and didn't display ads.

Connecting from Chrome OS (Chromebook)

Although Google tries desperately to hide it from the user, the fact is that Chrome OS is built on Linux and you can simply use ssh X11 tunnelling exactly like it is described in the FreeBSD and Linux section (below). The only hard part is getting to the ssh client.

Connecting from FreeBSD and Linux

FreeBSD and Linux are both UNIX-like operating systems and as such will most likely be using the X-Window System for their graphical user interface. While one could install the TightVNC client and configure the ssh tunnel in the same manner as described in the Apple OSX section, it is probably far less troublesome to simply tunnel the X11 protocol (used by the X-Window System) through the ssh connection directly instead of having the VNC intermediary.

ssh -X remotehostname path/to/application 

That's all there is to it. The -X (that's a capital X) tells SSH to tunnel the X11 protocol. For consistency, the setup and use of the TightVNC client is described below. It would be use when connecting to a MS Windows or Apple OSX server remotely.

What about Android?

I haven't found a decent combination of SSH and VNC that work adequately on Android. The small screen size makes it worse. It is probably best to use the Android phone as a WiFi access point and connect using something with a bigger screen.


It is somewhat ironic that the X Window System can be run on all the client operating systems listed in this article (except perhaps Android). In fact, the software needed is freely available. However, VNC has the advantage that you can install the VNC server on Windows and it's already a part of OSX. VNC has the other advantage that it can be configured to mirror the actual desktop which helps with remote support.

No comments:

Post a Comment