Use Canonical's Multipass to display Linux desktop on macOS desktop and VNC

; Date: April 18, 2020

Tags: Ubuntu »»»» Multipass

Even though macOS has an excellent command-line environment, we sometimes need to run a real Linux system. Multipass is an excellent way to run Ubuntu on macOS (or Windows, for that matter) but it doesn't easily support running a Linux desktop. In this article we demonstrating setting up a VNC server on a Multipass Ubuntu instance, and displaying it on the macOS desktop using a VNC viewer. The same techniques should work on Windows, and even with a remote Ubuntu VPS on a cloud hosting provider.

VNC is a system for remotely accessing desktop GUI sessions from another computer. The VNC display protocol runs across the network, and allows a client program (the half that displays the remote desktop) to connect to a VNC server (the half that creates the remote desktop). There are several vendors making both VNC server and VNC client programs.

A common case for VNC is when one has installed a computer at a remote site, and to be able to manage that computer without driving to the site. You instead ensure the computer is on the Internet, then use VNC to access its desktop.

In this case we're aiming to use VNC to control an Ubuntu Linux desktop running in a virtual machine managed by Multipass. The same instructions will work for any Ubuntu instance such as a VPS rented from a web hosting provider. I'll make sure to intersperse comments on how to implement this for a remote Ubuntu instance on a VPS provider.

While many of the open source Linux GUI programs are also available for macOS, some are not. Therefore it is sometimes useful to be able to use a Linux desktop even if your primary computer is running macOS - or Windows for that matter.

I wrote an earlier article about running a single application and displaying on XQuartz, the X11 server for macOS. This article differs in that we're looking to run a whole desktop UI rather than a single application. For that article see Use Canonical's Multipass to display Linux GUI applications on macOS desktop

Setting up a Multipass virtual machine

For more details on what Multipass is, and an introduction, see: Use Canonical's Multipass to display Linux GUI applications on macOS desktop

Run this to launch a Multipass/Ubuntu instance

$ multipass launch --name vncxfce4
Launched: vncxfce4                                     

This command launches the default Ubuntu image, at the time of this writing that is Ubuntu 18.04. The name for the image will be vncxfce4 because we will configure this image to run VNC and the XFCE4 desktop.

There are a number of commands to customize this, such as increasing the memory allocation.

Once it launches you can run this to start a Bash shell inside the instance:

$ multipass shell vncxfce4
Welcome to Ubuntu 18.04.4 LTS (GNU/Linux 4.15.0-96-generic x86_64)

 * Documentation:  https://help.ubuntu.com
 * Management:     https://landscape.canonical.com
 * Support:        https://ubuntu.com/advantage

  System information as of Fri Apr 17 08:53:09 PDT 2020
...
ubuntu@vncxfce4:~$ 

If instead you are using a different Ubuntu instance like a remote VPS, simply launch that instance in the appropriate way. In either case you'll have an Ubuntu system to work with.

As is typical we then update the system:

ubuntu@vncxfce4:~$ sudo apt update
...
ubuntu@vncxfce4:~$ sudo apt upgrade
...

These commands will be the same irregardless of what kind of Ubuntu instance you have. They cause an update of information about packages, and updates any packages that are currently out of date.

Installing VNCServer and Xfce4

Now that the system is set up we can proceed to setting up VNC and a desktop environment. For the desktop environment we are installing Xfce4 because it is light weight.

The commands in this section will be the same irregardless of where the Ubuntu instance is running, whether it is inside Multipass or a remote server.

$ sudo apt install xfce4 xfce4-goodies tightvncserver

We'll be able to, later, install a whole slew of other Linux GUI programs. But this will give us a good start.

When I ran this it installed well over 500 packages, so expect this to take awhile.

Once all that is installed we can run vncserver once to initialize the configuration files.

ubuntu@vncxfce4:~$ vncserver

You will require a password to access your desktops.

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

New 'X' desktop is vncxfce4:1

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

ubuntu@vncxfce4:~$ 
ubuntu@vncxfce4:~$ vncserver -kill :1
Killing Xtightvnc process ID 15560

This does initial setup, giving the VNC session a password, and so forth.

It set up a not-very-useful desktop environment, however, so we need to kill the VNC server to edit the startup script.

Next use your favorite text editor to edit ~/.vnc/xstartup

$ nano ~/.vnc/xstartup

The result will be:

#!/bin/sh

xrdb $HOME/.Xresources
startxfce4 &
#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

The commented-out lines is what vncserver provided to us. The uncommented lines starts up the xrdb server and the Xfce4 environment.

It is useful to make this file executable:

ubuntu@vncxfce4:~$ sudo chmod +x ~/.vnc/xstartup

The chmod program changes permissions on files, and chmod +x make a file executable.

Starting the VNC server for real

Now that we have the VNC environment configured to launch the Xfce4 desktop, it's time to take it for a spin for real.

ubuntu@vncxfce4:~$ vncserver

New 'X' desktop is vncxfce4:1

Starting applications specified in /home/ubuntu/.vnc/xstartup
Log file is /home/ubuntu/.vnc/vncxfce4:1.log

This launches VNC with the display number 1. What this means is the client program must be instructed to connect with port 5901 on the host.

The other thing to determine is the IP address of the Multipass instance.

$ multipass list
Name                    State             IPv4             Image
firefox                 Stopped           --               Ubuntu 18.04 LTS
vncxfce4                Running           192.168.64.11    Ubuntu 18.04 LTS

This is run in the macOS command-line environment rather than inside the Multipass instance. We see that the vncxfce4 Multipass instance has the IP address shown here.

In this case we are getting the IP address from Multipass. If your Ubuntu instance is on some other service, like a remote VPS provider, then you'll be told an IP address by that service. Or maybe instead you'll be told a domain name, in which case you would use the domain name instead of the IP address.

Connecting a VNC client to the VNC server in the Multipass instance

On macOS there is a built-in VNC client that Apple wants us to use for Screen Sharing between macOS computers. It is a simple VNC client and the primary downside is that it does not support encryption.

In another tutorial, I wrote up how to implement VNC on a regular Linux/Ubuntu computer, turn off the encryption, and use the macOS Screen Sharing application to connect with that Ubuntu session. See: How to set up remote desktop on Ubuntu, access it from macOS

While we could probably configure this vncserver installation to turn off encryption, let's instead look at using a VNC client that supports encryption.

The VNC server we installed is actually tightvncserver and the team behind this server also has a Java client that will work. See (www.tightvnc.com) the TightVNC website for information.

One navigates to the Download page, and downloads the TightVNC java Viewer JAR in a ZIP Archive package. As of this writing that is marked Version 2.8.3.

There is also documentation on this, but that documentation seems to be incorrect.

To run the VNC client:

$ java -jar ~/Downloads/tvnjviewer-2.8.3-bin-gnugpl/tightvnc-jviewer.jar 
Apr 17, 2020 11:39:56 AM com.glavsoft.viewer.Viewer <init>
INFO: TightVNC Viewer version 2.8.3

Running this we get:

We enter the IP address, or the domain name, for the Remote Host and because the session is on VNC server 1, we enter 5901 as the port number.

After entering the password, we connect like so:

We have a full Xfce4 session running on a Multipass instance on our laptop. Very good. The only problem with this is it is slow.

Apple's Screen Sharing surprisingly works

I wanted to record the error message when Screen Sharing failed to connect, but it just worked. Plus, the Screen Sharing app has better performance than the TightVNC Java client.

To access Screen Sharing, click on the Spotlight icon in the toolbar and enter Screen Sharing. It will show you the Screen Sharing.app icon, and you double-click on it to launch the application.

Then you enter the host connection parameters. Click on Connect and you'll be shown a password dialog. After which it will connect, and we can see this:

To prove that both clients work, we have the TightVNC Java client on the left, and Apple's Screen Sharing on the right. The latter gives much better performance.

Setting up VNCServer as a Service on Ubuntu

That's fine to set this up on an ad-hoc basis. But what if we want to have this image as a dedicated Xfce4 environment we can launch and go with at any time? Therefore we want the VNC Server to automatically launch when the instance starts.

There is a file to create to describe a Service to Systemd, and then we tell Systemd to manage this service.

Let's create a new file, /etc/systemd/system/vncserver@.service, using your favorite text editor:

$ sudo nano /etc/systemd/system/vncserver@.service

The file should contain:

[Unit]
Description=Start TightVNC server at startup
After=syslog.target network.target

[Service]
Type=forking
User=ubuntu
Group=ubuntu
WorkingDirectory=/home/ubuntu

PIDFile=/home/ubuntu/.vnc/%H:%i.pid
ExecStartPre=-/usr/bin/vncserver -kill :%i > /dev/null 2>&1
ExecStart=/usr/bin/vncserver -depth 24 -geometry 1280x800 :%i
ExecStop=/usr/bin/vncserver -kill :%i

[Install]
WantedBy=multi-user.target

This service description makes sense for the Multipass instance. That's because the login user name is ubuntu and therefore this file shows that user name in several places. If your setup is different, substitute a different user name.

Then we have a series of commands to run:

ubuntu@vncxfce4:~$ sudo systemctl daemon-reload

This makes Ubuntu aware of the new service

ubuntu@vncxfce4:~$ sudo systemctl enable vncserver@1.service
Created symlink /etc/systemd/system/multi-user.target.wants/vncserver@1.service → /etc/systemd/system/vncserver@.service.

Then we enable the service. The 1 after the @ character is the display number to use.

ubuntu@vncxfce4:~$ vncserver -kill :1
Killing Xtightvnc process ID 1119

Then we need to kill the existing VNC server process.

ubuntu@vncxfce4:~$ sudo systemctl start vncserver@1

Then we start the installed VNCserver process.

ubuntu@vncxfce4:~$ sudo systemctl status vncserver@1vncserver@1.service - Start TightVNC server at startup
   Loaded: loaded (/etc/systemd/system/vncserver@.service; indirect; vendor preset: enabled)
   Active: active (running) since Fri 2020-04-17 12:42:41 PDT; 8s ago
  Process: 1501 ExecStart=/usr/bin/vncserver -depth 24 -geometry 1280x800 :1 (code=exited, status=0/SUCCESS)
  Process: 1487 ExecStartPre=/usr/bin/vncserver -kill :1 > /dev/null 2>&1 (code=exited, status=2)
 Main PID: 1511 (Xtightvnc)
    Tasks: 62 (limit: 1152)

And we can check the status.

It's important to also test that the VNC server does automatically start when the Multipass instance starts.

$ multipass stop vncxfce4 
$ multipass start vncxfce4 

The stop command shuts down a Multipass instance. This is just like shutting down any Ubuntu computer, in that messages will be printed on logged-in terminals, and the VNC Client will disconnect.

If you're using the macOS Screen Sharing app, it will show a Reconnecting message while the instance is rebooting.

Once the instance is rebooted feel free to connect a VNC client again. Or, if you're using the Screen Sharing app, the client will automatically reconnect.

Ensuring encryption is enabled for VNC sessions over the public Internet

For a VNC session within our laptop encryption isn't so necessary. But for a VNC session running over the Internet, encryption is a very good idea.

There are paid VNC clients for macOS that support encryption and claim to have blazing fast performance. I don't know, since I haven't used those apps.

In case you wish to implement encryption, it is possible to use an SSH tunnel.

$ ssh -L 5901:127.0.0.1:5901 -C -N -l ubuntu YOUR-SERVER-IP-ADDRESS

This sets up a port 5901 on the local host (127.0.0.1) that is connected via an SSH tunnel to the computer at YOUR-SERVER-IP-ADDRESS. It uses SSH to make this connection, and connects to the user name ubuntu at that IP address (or domain name).

Needless to say you should supply password-less connection credentials. For example you should have previously set up an SSH key between the computers enabling you to login using SSH without a password. If the remote instance is an AWS EC2 instance, then you'll need to use the PEM key file supplied by AWS.

With the SSH tunnel, you tell the VNC client to connect with the VNC server at 127.0.0.1:5901. SSH will take care of communicating data with the remote VNC server, and encrypting that data while it is traversing the Internet.

The SSH tunnel trick comes from (www.digitalocean.com) How to Install and Configure VNC on Debian 9

About the Author(s)

David Herron : David Herron is a writer and software engineer focusing on the wise use of technology. He is especially interested in clean energy technologies like solar power, wind power, and electric cars. David worked for nearly 30 years in Silicon Valley on software ranging from electronic mail systems, to video streaming, to the Java programming language, and has published several books on Node.js programming and electric vehicles.