Chrome Remote Desktop into a GCE Ubuntu VM

Warning: This post brought to you by the miracle that is in-flight WiFi. As such, it includes an uncomfortably high number of TODOs.

I think it would be awesome to have a one-click virtual (and potentially extremely powerful) workstation (Linux in this case, though other OSes would be nice as well) that offered easy-to-use remote desktop support from a lightweight client machine. I haven’t figured out how to get there in one click, but the steps below did get me to the point of being able to use Chrome Remote Desktop from my Chromebook to connect to an Ubuntu VM running on Google Compute Engine.

There are a lot of ways that this could be improved (e.g., via coding it up so that some or all of these explicit commands can be automated away), but I’ve deemed it coherent enough to write down as-is.

Prepare the client system (a Chromebook)

  1. Install the Chrome Remote Desktop extension
  2. Configure the Secure Shell client as described in a Previous Post
    • Note that the web-based SSH client integated with is not sufficient as we will be forwarding ports to setup a secure VNC connection to interact with Chrome on the server system. I would love to find a way to avoid the need for this.
  3. Install the Chrome VNC Client

Prepare the server system to be able to create a VNC-based desktop environment and run its own instance of Chrome (which will be the server in our ultimate Chrome Remote Desktop sessions)

  1. Add Google’s apt package signature verification public key
    wget -q -O - | sudo apt-key add -
    sudo sh -c 'echo "deb [arch=amd64] stable main" >> /etc/apt/sources.list.d/google.list'
  2. Install Chrome, a VNC server, a window manager (using xfce4 here), and the chrome-remote-desktop native Linux package
    sudo apt-get update
    sudo apt-get install google-chrome-stable tightvncserver psmisc xfce4
    # **TODO(jonmccune)**: Use gnome and not xfce4
    sudo apt-get install chrome-remote-desktop xvfb xbase-clients python-psutil    
  3. Open TCP ports 443 and 5222

    See this stack overflow post.

Establish a VNC-over-SSH connection to the server (this is intended to be one-time, since in the future we’ll use Chrome Remote Desktop)

  1. SSH to the VM using the Secure Shell extension, but include -L 5900:localhost:5900 in the SSH Arguments: field. The behavior of that argument is explained in another Previous Post.

  2. On the server, start a VNC server that only listens for connections from localhost: vncserver :1 -localhost. This prompts for a password, though we’re relying on SSH for our security. TODO(jonmccune): how to disable the VNC-specific password?

    • On your client device, open the VNC client and connect to localhost:5900. (You may be prompted for your VNC-specifc password.)

Continue setting up the server via the VNC connection

  1. Open Google Chrome, and sign in to the Google account that you plan to use for Chrome Remote Desktop.

  2. Install the Chrome Remote Desktop extension
    TODO(jonmccune): Enable sharing of the current machine, choose a PIN, etc.

    1. I ran into an issue where the option to enable sharing the current machine was not visible. Returning to the SSH connection, the following commands allowed me to make progress. I’m not sure if I somehow missed an installer step or if this is some quirk of using a particular Linux distro.
    sudo groupadd chrome-remote-desktop
    sudo usermod -a -G chrome-remote-desktop jonmccune
  3. Now open Chrome Remote Desktop on your client system (the Chromebook). If all has gone well, you’ll see your VM instance listed there. Victory!
    TODO(jonmccune): Will Chrome Remote Desktop auto-start when the VM is rebooted?

Using a dedicated Google account

My motivation for setting all of this up is in service of collaboration with others, and so I didn’t want to put my personal Google account credentials in the VM.

The steps above don’t make any mention of using multiple Google accounts, but in practice I’ve set this up using a shared Google account that is dedicated to the purpose of the collaboration. The most convenient approach for me turned out to be to add the collaborative Google account as another user on my Chromebook and take advantage of the multi-user sign-in abilities of ChromeOS. Beware that your collaborators may be able to cause the installation of arbitrary Chrome extensions, but that rathole goes down a long way and is a topic for another day.


Setting up SSH Keys with the Chrome OS Secure Shell Extension

For this exercise the client system is a Chromebook, and the server system is an Ubuntu VM running on Google Compute Engine.

The SSH client of choice on Chrome OS devices is Secure Shell. Per its own documentation, it is possible to use public key-based authentication with the Secure Shell client. However, Secure Shell cannot generate its own keys. My goal here is to be able to SSH into a Google Compute Engine VM running Ubuntu Linux, so I generated the keypair on the target Linux VM using the browser-based SSH client offered by, and then imported them into Secure Shell on my Chromebook. This is appealing because it avoids the need to configure passwords for SSH altogether.

Security note: Generating the keypair on the target machine into which possession of that keypair authorizes access is reasonable. If an attacker already has a foothold in that system, you already lose. However, once that keypair is imported into Secure Shell on one’s client device, it can be convenient to use that key for access to other systems. Consider how much you trust the VM image where ssh-keygen executes before deciding whether to use the same keypair to authorize access to any other systems. Also consider the note about HTML5 filesystems being a relatively young technology in the above link to the Secure Shell documentation about SSH keys. A topic for another day is how to integrate with a physical hardware token like a Yubikey, so that the private SSH key is never exposed to any client device software.

# don’t allow the private key to be written to disk
cd /dev/shm
# generate the actual keypair
ssh-keygen -f gce-instance-ssh
# to SSH into the system where keys are being generated,
# authorize the public key
cat >> ~/.ssh/authorized_keys

This creates files gce-instance-ssh and Both of these files need to be copied onto the Chromebook for importing into Secure Shell. I decided to do this using cat gce-instance-ssh and cat and then copy-pasting the contents of each. The destination was a Chrome extension that can create and edit plain text files. Secure Shell requires that both gce-instance-ssh and be available to import a keypair. I shift-clicked when selecting the files for the Import (to the right of the Identity: field in the Secure Shell connection dialog) dialog box. When selecting only the private key file, there seems to be little or no UI feedback that anything has happened at all.

If successful, the drop-down next to Identity: will have a new entry, whose name appears to be the basename of the imported key files. In this case, gce-instance-ssh.