Cloud Linux for Chrome

Overview

ChromeOS is getting increasingly more powerful, and for many users, it can already do most of their everyday tasks. But on occasion, it is convenient to have access to a full Linux desktop environment. If you remembered to leave your PC running, you can always connect to it with Chrome Remote Desktop, but what do you do if you don't have a PC or it you don't normally leave it powered on? Wouldn't it be useful to have a virtual server that can be reached from anywhere on the internet?

Getting a virtual server

Many users, even if they don't have an "always-on" Linux desktop, do have at least temporary access to a PC. And that's a great choice for executing the commands in this tutorial. But thanks to the magic of Termux, all you really need is your ChromeOS device. You might consider installing an Ubuntu chroot though, as it gives access to more command line utilities than plain Termux does.

Before you can do anything, you obviously have to get a virtual Linux machine. You can cheaply rent one from a multitude of different hosting providers. But for the purposes of this tutorial, we'll configure an LXD container instance instead.

You do not necessarily need to perform these steps, if you already have access to a (virtual) machine that you want to use, and if you don't want to run LXD to further partition that server.

On the other hand, since LXD is available for many different distributions. You can follow this tutorial and install an Ubuntu container, even if the host runs a different Linux distribution. Note, these days it is strongly recommended to install LXD in the form of a snap package, if possible.

These commands must be executed on the server that is going to host your container.

sudo snap install lxd
sudo lxd init

lxc launch ubuntu:16.04 cloud-linux

Configuring the virtual server

For the rest of this tutorial, we'll use lxc exec cloud-linux -- ... to run commands inside of our container. Of course, if you have a different type of virtual environment, ssh might the appropriate command instead.

Also, LXD defaults to creating an ubuntu user in addition to root. This user can use sudo to gain elevated privileges without having to enter another password. If your virtual machine is configured differently, you might need to make adjustments.

Temporary VNC access

In order to be able to turn on Chrome Remote Desktop, we already need a working X Windows desktop environment that runs inside of the container. While this sounds like a Catch 22, there fortunately are ways to temporarily give us a working X Windows environment.

We install the XFCE desktop environment, as its default configuration doesn't have any expensive graphical effects. This works better over slow internet links. But you can always substitute your favorite desktop environment instead, if your network is fast enough:

lxc exec cloud-linux -- apt-get update
lxc exec cloud-linux -- apt-get -y dist-upgrade

lxc exec cloud-linux -- \
    apt-get -y install xfce4 vnc4server \
                       chromium-browser gnome-keyring gksu

lxc exec cloud-linux -- sudo -iu ubuntu mkdir -p /home/ubuntu/.vnc
lxc exec cloud-linux -- \
    sudo -iu ubuntu ln -s /bin/true /home/ubuntu/.vnc/xstartup

lxc exec cloud-linux -- sudo -iu ubuntu vncserver
You will require a password to access your desktops.
Password: Pick any arbitrary password here
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 cloud-linux:1
Creating default startup script /home/ubuntu/.vnc/xstartup
Starting applications specified in /home/ubuntu/.vnc/xstartup
Log file is /home/ubuntu/.vnc/cloud-linux:1.log

lxc exec cloud-linux -- env DISPLAY=:1 \
    sudo -iu ubuntu /etc/xdg/xfce4/xinitrc

Tunneling VNC

The next step depends a lot on your choice of virtual container environment. If there is no firewall between you and services running inside your container, then you don't have to do anything special at this point.

On the other hand, if you can only contact your container through the lxc command, then you should forward the port that is used by VNC:

lxc exec cloud-linux -- apt-get -y install netcat

nc -l -p 5901 -c 'lxc exec cloud-linux -- \
                  su -c "nc 127.0.0.1 5901" ubuntu'

On the other hand, if you access your virtual machine through SSH, you might want to try something along these lines instead:

ssh -L 5901:127.0.0.1:5901 -N cloud-linux

You should now be able to connect to your container from any VNC Client. Simply tell it to establish a connection to localhost on port 5901. Please note that this is not the default port (that would be 5900). When prompted, enter the VNC password that you picked earlier.

Installing Google Chrome…

In your newly-configured virtual Linux environment, open the Chromium browser by finding it in the application menu (most likely located in the top left-hand corner). Go to https://www.google.com/chrome/browser/desktop/ and download the Chrome installer for Ubuntu 64bit. You can now close Chromium.

Open a terminal window and type the following commands; when you install Chrome with dpkg -i, there might be an error message, that you can safely ignore.

sudo dpkg -i ~/Downloads/google-chrome-stable_current_amd64.deb
sudo apt-get -y install -f

Open Applications↦Internet↦Google Chrome. Make sure that you are logged into your Google account in this browser. Then find the Chrome Remote Desktop extension in the Web Store, and install it. Launch the newly installed Chrome Remote Desktop app.

You'll have to click away a couple of informational messages until you see an option that reads Remote Assistance: User-to-user screen sharing. Select that option, then click on Share this computer for another user to see and control. Allow Chrome to download the Chrome Remote Desktop installer.

Once the package has completed downloading, close all browser windows.

…and Friends

From within the terminal window, install the package that you just downloaded. At this point, we also make a couple of configuration changes that the installer forgets to do:

echo 'exec /etc/xdg/xfce4/xinitrc' \
     >/home/ubuntu/.chrome-remote-desktop-session
chmod 755 /home/ubuntu/.chrome-remote-desktop-session

echo 'export CHROME_REMOTE_DESKTOP_DEFAULT_DESKTOP_SIZES=3840x2560' |
  tee -a /home/ubuntu/.profile

sudo dpkg -i ~/Downloads/chrome-remote-desktop_current_amd64.deb
dpkg: dependency problems prevent configuration of chrome-remote-desktop:
 chrome-remote-desktop depends on xvfb-randr | xvfb; however:
  Package xvfb-randr is not installed.
  Package xvfb is not installed.
 chrome-remote-desktop depends on xbase-clients; however:
  Package xbase-clients is not installed.
 chrome-remote-desktop depends on python-psutil; however:
  Package python-psutil is not installed.
Errors were encountered while processing:
 chrome-remote-desktop

sudo apt-get -y install -f
sudo adduser ubuntu chrome-remote-desktop

Launch Applications↦Chrome Apps↦Chrome Remote Desktop. If you see an item that reads Access your computer from anywhere, click on the Get Started button. This option sometimes doesn't show. That's OK. But in either case, click on Enable remote connections when you see it.

You'll be prompted to pick a PIN for this computer. Pick something that you can remember. You'll need it each time you want to connect with a new Remote Desktop client.

Finishing up

Restart your container and try connecting to it with Chrome Remote Desktop. From this point forward, you no longer need VNC. So, let's clean up all temporarily used resources:

lxc restart cloud-linux

lxc exec cloud-linux -- \
    apt-get remove --purge -y vnc4server chromium-browser
lxc exec cloud-linux -- apt-get autoremove --purge -y
lxc exec cloud-linux -- apt-get clean

lxc exec cloud-linux -- rm -rf \
  /home/ubuntu/.vnc \
   /home/ubuntu/.config/chromium \
  /home/ubuntu/Downloads/google-chrome-stable_current_amd64.deb \
  /home/ubuntu/Downloads/chrome-remote-desktop_current_amd64.deb
Now you are all set, and if you feel like it, you can open a terminal window and install your favorite desktop applications:
sudo apt-get -y install libreoffice
sudo apt-get clean