Ubuntu Cloud Desktop: Adding GUI to Your Cloud Server Instance

When you are going to install Ubuntu on a local machine, there are always two versions to choose: desktop or server. Whereas if you want to deploy Ubuntu on the cloud, most cloud service providers only provide server version. This makes sense due to cloud computing paradigm such as on-demand resource, etc better suites to server application workloads.

There are cases though that you may need to run desktop applications such as browsers, office suites, etc on the cloud. Few service providers provide DaaS (Desktop as a Service) or VDI (Virtual Desktop Infrastructure) Service. But if you are already familiar with setting up a cloud Ubuntu server, actually it is quite straightforward to set-up your own cloud desktop.

The main difference in Ubuntu desktop and Ubuntu server is the desktop environment. While Ubuntu desktop includes a GUI (Graphical User Interface), Ubuntu server does not. Most servers run headless i.e: instead of using a traditional keyboard, mouse, and monitor setup to interact with the machine, servers are usually remotely managed using CLI (Command Line Interface) via SSH.

The nice thing with Ubuntu, actually applies to Linux in general,  these differences are not fixed and you can customize the desktop version to the server version, and vice versa, by installing and removing software packages. To set-up an Ubuntu cloud desktop from an Ubuntu cloud server, therefore you only need to do the following 2 steps:

  1. Install graphical remote access such as VNC or RDP. This is a client-server software so you need to install both the server and client component.
  2. Install Ubuntu desktop environment. The challenge, there are many Ubuntu (and Linux) desktop environments that are confusing especially for a beginner. To make life easier as a start, you are recommended to choose from these 3 Ubuntu desktop environments: LXDE, XFCE, and MATE Desktop.

One more thing from the security point of view, production cloud servers are mostly running business-critical applications and they are security hardened. So it is bad practice to add a desktop environment package to these servers because it is potentially opening up security holes. You should only do the above two steps to non-production or new Ubuntu server that never meant to be running production server workload.

Prerequisites

This guide assumes that you already have:

  • An Ubuntu 18.04 cloud server.
  • A local computer or device with a VNC viewer/client installed:
    • TightVNC  runs on Windows, Linux, and multi-platform Java
    • RealVNC runs on Windows, macOS, Linux, Android, iOS, Chrome browser, etc
    • noVNC runs well in any modern browser including mobile browsers (iOS and Android)
    • There are many others that you can search on the Internet like UltraVNC for Windows, Remmina for Linux, built-in Screen Sharing program in macOS, etc

Step 1 – Install VNC Server

By default, an Ubuntu 18.04 server does not come with a VNC server installed, so you’ll begin by installing it. In this guide, you’ll use TightVNC, a fast and lightweight remote control package. The TightVNC package is available in the official Ubuntu repository.

$ sudo apt-get update
$ sudo apt-get install tightvncserver xfonts-75dpi xfonts-100dpi gsfonts-x11

To start the VNC server,  use the vncserver command:

$ vncserver

When VNC is first set up, it will also set up a secure password and create the initial configuration files:

You’ll be prompted to enter and verify a password to access your machine remotely:

You will require a password to access your desktops.

Password:
Verify:

The password must be between six and eight characters long. Passwords more than 8 characters will be truncated automatically.

Once you verify the password, you’ll have the option to create a view-only password. Users who log in with the view-only password will not be able to control the VNC instance with their mouse or keyboard. This is a helpful option if you want to demonstrate something to other people using your VNC server, but this isn’t required.

The process then creates the necessary default configuration files and connection information for the server:

Would you like to enter a view-only password (y/n)? n
xauth: file /home/your_userid/.Xauthority does not exist

New 'X' desktop is your_hostname:1

Creating default startup script /home/your_userid/.vnc/xstartup
Starting applications specified in /home/your_userid/.vnc/xstartup
Log file is /home/your_userid/.vnc/your_hostname:1.log

Please note that when VNC is first set up, it launches a default server instance on port 5901. This port is called a display port and is referred to by VNC as :1. VNC can launch multiple instances on other display ports, like :2, :3, and so on by executing another vncserver command.

One alternative to VNC is X2Go which is described in the following article.

Step 2 – Install Ubuntu Desktop Environment

As mentioned before, you are suggested to install one of the following popular lightweight desktop environment, which takes fewer resources, and does not demand graphics hardware acceleration.

LXDE  (Lightweight X11 Desktop Environment)

LXDE is known as one of the lightest desktop environments available for GNU/Linux. It is extremely minimalistic and comes with very little to no special effects, or resource hungry applications and tools. LXDE is bland and boring so if you want something fancy, full of bells and whistles and animations and flashy animations; you probably shouldn’t be using LXDE.

LXDE is used in Lubuntu as default desktop environment.

To install LXDE, run the following commands in your cloud server’s terminal:

$ sudo apt-get update
$ sudo apt-get install lxde

Make sure the VNC server is started. Point your VNC Client to  the  <cloud_server_address>:1, you’ll see a window like this:

XFCE

Xfce is another desktop environment that aims to be fast and light-weight, and yet offers a lite but modern, visually appealing and user-friendly interface. It comes with all the basic features you’ll need along with a decent set of applications.

Manjaro Linux and Xubuntu has Xfce as default desktop environment

To install Xfce, run the following commands in your cloud server’s terminal:

$ sudo apt-get update
$ sudo apt-get install xfce4 xfce4-goodies

For XFCE Desktop, you need to make a minor change to the default VNC server’s xstartup configuration. If the VNC server is already started, you need to stop the running server instance:

$ vncserver -kill :1

Edit the xstartup file:

$ nano ~/.vnc/xstartup

Comment out the export XKL_XMODMAP_DISABLE=1 statement:

#!/bin/sh
xrdb $HOME/.Xresources
xsetroot -solid grey
#x-terminal-emulator -geometry 80x24+10+10 -ls -title "$VNCDESKTOP Desktop" &
#x-window-manager &
# Fix to make GNOME work
#export XKL_XMODMAP_DISABLE=1
/etc/X11/Xsession

Save the xstartup file and start the VNC server instance.  Point your VNC Client to  the  <cloud_server_address>:1, you’ll see a window like this:

MATE Desktop

The MATE Desktop Environment is the continuation of GNOME 2. MATE was initially developed for the users who were disappointed with the latest iteration of GNOME shell – GNOME 3. It provides an intuitive and attractive desktop environment using traditional metaphors for Linux and other Unix-like operating systems. MATE comes with a collection of basic applications, most of which are forks of GNOME 2 applications.

Ubuntu MATE  uses MATE Desktop as its default desktop environment.

To install MATE, run the following commands in your cloud server’s terminal:

$ sudo apt-get update
$ sudo apt-get install ubuntu-mate-core

For MATE Desktop, you need to change the default VNC server’s xstartup configuration first. If the VNC server is already started, you need to stop the running server instance:

$ vncserver -kill :1

You can then save the current xstartup file under a different name for backup and edit a new xstartup file:

$ mv ~/.vnc/xstartup ~/.vnc/xstartup.bak
$ nano ~/.vnc/xstartup

In the new xstartup file, put the following entries:

#!/bin/sh
unset DBUS_SESSION_BUS_ADDRESS
[ -x /etc/vnc/xstartup ] && exec /etc/vnc/xstartup
[ -r $HOME/.Xresources ] && xrdb $HOME/.Xresources
xsetroot -solid grey
vncconfig -iconic &
x-terminal-emulator -geometry 80x24+10+10 -ls -title "$VNCDESKTOP Desktop" &
x-window-manager &
mate-session &

Save the xstartup file and start the VNC server instance.  Point your VNC Client to  the  <cloud_server_address>:1, you’ll see a window like this:

VNC Optional Miscellaneous  Configurations

Securing VNC Connection

VNC itself doesn’t use secure protocols when connecting. But you can use an SSH tunnel to connect securely between VNC server and VNC client. You can do this by creating an SSH connection on your local computer that securely forwards to the localhost connection for VNC with the following command:

$ ssh -L 5901:127.0.0.1:5901 -C -N -l your_userid your_server_ip

The -L switch specifies the port bindings. In this case, you are binding port 5901 of the remote connection to port 5901 on your local machine. The -C switch enables compression, while the -N switch tells ssh that you don’t want to execute a remote command. The -l switch specifies the remote login name. Your_userid and your_server_ip is username and IP address of your server.

Once the tunnel is running,  now point your VNC client to localhost:5901 instead of <cloud_server_address>:1.

However, this protection alone still doesn’t protect you from the brute-force attack to the VNC access itself. If you receive this message:

VNC conenction failed: vncserver too many security failures

It means that someone, on the internet,  tried to access your VNC with incorrect credentials too frequently within a specified period of time and this may happen frequently. This is troublesome because every time you need to restart your VNC server to be able to restore the access again.

Since you already have the SSH tunneling, the easiest method to prevent this brute-force attack is to only allow access from localhost.  Start VNC server instance with ‘-localhost’ parameter:

$ vncserver -localhost

You can only use localhost:5901 in your VNC client, using <cloud_server_address>:1 will not establish VNC connection anymore. Of course, the hacker could also try the SSH tunneling but there are many guides that you can find on the internet on how to protect your SSH like this one or this other one.

Working with Clipboard

If you can not simply copy-paste text between your local machine and cloud server over VNC then one of the solutions is to use autocutsel. Install autocutsel in the cloud server:

$ sudo apt-get install autocutsel

Afterward, modify your existing VNC configuration file, xstartup:

$ nano ~/.vnc/xstartup

Insert the ‘autocutsel -fork’ instruction just after the ‘xsetroot -solid grey’ line:

#!/bin/sh
xrdb $HOME/.Xresources
xsetroot -solid grey
autocutsel -fork
#x-terminal-emulator -geometry 80x24+10+10 -ls -title "$VNCDESKTOP Desktop" &
-------------------------------------------

Save the xstartup file and restart the VNC server instance:

$ vncserver -kill :1

$ vncserver

Copy-paste for text should now work between your local machine and cloud server over VNC connection.

noVNC

noVNC is a browser-based VNC client implemented using HTML5 Canvas and WebSockets that doesn’t require any VNC client installation. You still need to install and run the VNC server as described above, in addition, you just need to install websockify and create self-signed certificate to enable encrypted communication using https.

$ sudo apt-get install novnc websockify python-numpy

You will be asked to enter information that will be incorporated into your certificate request below

$ cd /etc/ssl
/etc/ssl $ sudo openssl req -x509 -nodes -newkey rsa:2048 -keyout novnc.pem -out novnc.pem -days 365
/etc/ssl $ sudo chmod 644 novnc.pem

Make sure that vncserver is already running and start the websocket:

$ sudo websockify -D --web=/usr/share/novnc/ --cert=/etc/ssl/novnc.pem 6080 localhost:5901

 Point your browser to https://(server’s hostname or IP address):6080/vnc.html and login with VNC password.

You are then connected to your cloud server.