My $169 development Chromebook

How Chrome OS, Termux, YubiKey & Duo Mobile make for great usable security

final desktop


Update

I'll give this a proper update in the coming days, but much of this post is no longer needed. First class support for native VMs and containers have landed in Dev & Canary channels for Chrome OS — including budget models like the Samsung Chromebook 3 discussed below. Full Wayland support, bi-directional copy/paste between guest & host, and VM network passthrough to the Chrome browser supported. The default VM is a full-on Debian 9 build. Some highlights in thread and replies here: https://twitter.com/kennwhite/status/1028505652749062144?s=21

Backstory

In the last year while talking to respected security-focused engineers & developers, I've come to fully appreciate Google's Chrome OS design. The architecture benefited from a modern view of threat modeling and real-world attacks. For example, Trusted Platform Module (TPM) hardware chips are built into every Chromebook and deeply incorporated into the OS. The design documents go into some detail on the specific protections that TPM provides, particularly around critical encryption functions.

I also learned that Chromebook is the daily driver for many of Google's own senior developers and security engineers. In short, the combination of the underlying Chromebook hardware with the OS architecture makes for a pretty compelling secure development environment.

Fast forward to March. In the past, I'd never given much thought to bringing my notebook with me while on travel — it was just something I did as a matter of course. Now, though, with the changing landscape of airline restrictions and seemingly ad hoc draconian rules for what can and can't be brought on board, I've had to seriously reconsider my routine. There is zero chance I am willing to bag check my beloved Macbook Pro or Purism Librem, especially given carriers' long history of indifference to ground crews playing hacky-sack with luggage. Who can forget United Breaks Guitars? And let's not even get into brazen theft.

The point of this exercise is to retain the hardened posture of the platform and have a flexible, safe development environment without depending on the crutch of privileged access.

It's pretty neat to consider the possibility of pre-travel "power washing" (resetting everything clean to factory settings) on an inexpensive Chromebook and later securely restore over the air once at my destination. Since there is a wide range in Chromebook prices, the engineering challenge here was to find something powerful enough to comfortably use exclusively for several days of coding, writing, and presenting, but also cheap enough that should it get lost/stolen/damaged, I wouldn't lose too much sleep. The threat model here does not include recovery from physical tampering; if the machine were somehow confiscated or otherwise out of my custody, I could treat it as a burner and move on.

After two weeks dogfooding this as my exclusive machine, here's what I came up with. And honestly, I'm pretty happy with the results. But it wasn't easy to get here. Nearly every how-to and blog post I've found on "Chromebooks for developers" essentially starts with either: "Boot into Developer Mode" or "Install Debian/Ubuntu as the main OS". I'll just say it: This is bad advice. It would be akin to recommending that friends jailbreak their shiny new iPhone.

You're obviously free to do as you wish with your own gear, but recognize that at Step 1, you'll have lost most of the core security features of Chromebook, not to mention virtually inviting bad development habits. As far as Debian/Ubuntu (and crouton), that's fine as far as it goes, but then you don't end up with a Chromebook, just a cheap mini-notebook with flaky drivers. The whole point of this exercise is to retain the hardened posture of the platform and have a flexible, safe development environment without depending on the crutch of privileged access.

Goals

  • A very modest budget (ideally <$200 USD, all in)
  • 8-10 hour real-world battery life
  • A first-class, local/non-connected dev environment for my current toolchain:
    • go, c/c++, node.js, git, curl, nginx, postgres...
  • Standard network tools (openssl cli, nmap, tcpdump...)
  • Strong hardware-backed verification & mutual auth
  • Open source, actively developed software whenever possible
  • Bonus: secure messaging, voice, video chat, Netflix

Anti-Features

The finished environment should not:

  • bypass core OS security
  • disable Verified Boot
  • require sudo/root for dev environment
  • rely on Crouton or Ubuntu
  • require (or assume) an always-on network

Supported Gear

Google announced a major development in the Chromebook roadmap recently and it seems to have been overlooked by many in the industry: over the past few months, several models have been updated to work with Play Store apps. In theory, this will open the door to many of the 3+ million Android apps. In practice, there's still a fair amount of work to do to "optimize" existing app display layouts and fix other UX quirks. But crucially for our purposes, this opens the way to a killer app called Termux.

The official list of Chromebooks supporting Android apps (and the timeline for those planned in 2017) is here:
https://sites.google.com/a/chromium.org/dev/chromium-os/chrome-os-systems-supporting-android-apps

While never explicitly stated, I take inclusion on this list as a rough proxy for commitment by manufacturers (and Google product engineering) to support these models.

After reading an absurd number of reviews and forum posts, I eventually settled on the Samsung Chromebook 3. It's lightweight (a little over 2 lbs), comes with 4GB RAM and a 16GB solid state drive (expandable via MicroSD to 256GB), and uses a low-power Intel x86-64 dual core N3060 1.6/2.4 GHz processor. Other goodies include USB 2/3 ports, HDMI, 720p webcam, and a water-resistant keyboard.

You would definitely notice the performance boost if you bumped up to 8GB of memory or an m5/i5 CPU, but prices at that tier start at $800 and rise quickly (see note¹ below on Amazon). There's no shortage of high end Chromebooks available, but in my testing of the "serviceable, but won't-cry-if-I-lose-it" category, 4GB of RAM and a non-ARM processor seem to be the sweet spot. If you are tempted to save $40 and opt for the super cheap 2GB models, don't expect to open more than a handful of browser tabs before hitting a tar pit.

Hardware

Prerequisites

  • A good 2-Factor Authentication app (installed on your phone, not your Chromebook). Personally, I trust the Duo Mobile app, available for free on iOS and Android. Many people also like Google Authenticator.

The Build: Authentication and Security

  1. If necessary, wipe the Chromebook to factory settings via Powerwash
  2. Boot and set up a new Google account to manage your device (this will help segment your data, and if you need it you can still access your existing gmail accounts). Choose: Other Options > Create New Account. You'll likely be asked for a recovery/SMS phone number, but you can remove it in a few minutes.
  3. Ensure the latest OS & app updates are installed:
    • Account photo / gear icon / Settings dropdown / About Chrome OS / Check for Updates
  4. Set up mutual authentication with the YubiKey. Open Security settings in the new Google account (https://myaccount.google.com/security#signin) and click 2-Step Verification. You'll be prompted for your password. Follow the prompts for "Add a Security Key". Once confirmed by logging out then back in using your YubiKey, continue to the next step below.
  5. Add a 2FA authentication fallback option. Navigate back to the Settings menu above, then:
    • 2-Step Verification / Authenticator App / Setup (choose Google Authenticator; the QR codes are universal) / Next / QR code should display
    • On your phone, open Duo Mobile then: Begin Setup / Scan barcode / Next
    • On your Chromebook, type the code you see in Duo Mobile into the text box / Verify / Done
  6. Verify that the authenticator is working correctly. The 2FA authenticator verification is an access safety mechanism should you lose the YubiKey:
    • Log out then log back in. Ignore the prompt to insert your security key, and instead click on the link at the bottom of the login page Having Trouble?. Choose Get a verification code from the Google Authenticator app.
    • On Duo Mobile app, click the Google account key icon and enter the 2FA code into the browser.
    • Save or print out the backup codes, should you lose both your mobile phone (or at least the secret TOTP seeds in your 2FA app) and your YubiKey.
    • Note: for both the 2-Step Verification and Authenticator login paths, you may want to consider unchecking Don't ask again on this computer.
  7. With two step verification set up, it is safe to remove the phone number you supplied earlier from the account recovery menu

The Build: Privacy & Cloud Sync

  1. Set privacy and tracking configuration. Depending on your use case, you will probably want to limit the ad data that Google collects.
    • Navigate to https://myaccount.google.com (the 3x3 box in the top right corner in Gmail) > Personal Info & Privacy > Your personal info > Ad settings
  2. Set cloud sync preferences.
    • Chromebook settings > People > Sync
    • I recommend enabling: Apps, Extensions, and Settings, but not Autofill, History, and Open Tabs. Also — crucially — note that allowing Apps and Extension sync will likely mirror sensitive content including credentials, keys, API tokens, passwords & password manager vaults, and other secrets stored locally on your notebook. This could be a huge convenience or utterly catastrophic if left unencrypted, depending on your threat model and risk tolerance. You mileage will definitely vary.
  3. If you plan to use Chrome to manage passwords, you should probably set a Sync Passphrase so that Google servers won't store your passwords in plaintext.

Android Apps

  1. Set Update Channel from Stable to Beta (some models already officially support Android apps in Stable)
  • Profile picture in lower right > Settings > About Chrome OS (bottom of drop down menu) > Check for Updates.
  • Settings > About Chrome OS > Detailed Build Information > Channel > Change Channel > Beta > Change Channel > Restart
  1. Enable Chromebook Android apps
  • Activate Play Store on your Chromebook: Bottom profile photo > gear icon > Settings > Play Store > Turn on
  • Start the (now) pre-installed "Play Store (Beta)" Android app, not the Play Store web site to accept the terms. Once that's done, your device should be registered. This part is a little wonky -- you can't start in the Play Store web site until this is done, but once it is, you don't have to use the clunky Play Store Beta app.
  • Navigate to Play Store (web) Settings: https://play.google.com/settings/. Alternatively, from Gmail: top right 3x3 square icon > Play Store > top right gear icon > Settings
  • Verify your device is registered, e.g.: "No carrier Samsung Chromebook 3" and give it a memorable name. If you hit any problems, see the official detailed how-to on enabling Android apps on Chromebook
google play registration

The Termux Secret Sauce

termux

This is the killer app that makes flexible dev shell access possible as an unprivileged user. Termux is a terrific project developed & led by Fredrik Fornwall and has been under active development for the past two years (https://github.com/termux/termux-app). It runs in non-root userspace and provides a chroot-like option to present a conventional linux filesystem. In most respects it feels like a modern Debian-based distro, with the latest i686 stable versions of widely used development & system tools including:

  • apache 2.4
  • bash 4.4
  • clang 4.0.1
  • erlang 19.3
  • git 2.13
  • gnupg 2.1
  • golang 1.8.3
  • libgcc 4.9
  • libsodium 1.0.13
  • lighttpd 1.4
  • llvm 4.0
  • lua 5.3
  • mariadb 10.2
  • mosh 1.3
  • nginx 1.12
  • nmap 7.50
  • nodejs 6.11
  • python 2.7.13 & 3.6.1
  • redis 3.2.9
  • ruby 2.4.1
  • sqlite 3.19
  • sslscan 1.11
  • tcpdump 4.8
  • tor 0.3.0.9
  • transmission 2.92

Install the Termux Android app from Play Store:
https://play.google.com/store/apps/details?id=com.termux.

Start up Termux (see Epilog below for customizing) and install base packages :

    apt update   
    apt upgrade
    apt install coreutils
    pkg upgrade
    pkg install termux-tools proot util-linux net-tools 
    pkg install openssh tracepath tree git

If Go or Node are your jam:

    pkg install golang nodejs 

For the full list of current packages (Go, Node, Python, etc):

    pkg list-all 

Create symlinks & permissions for typical Android filesystems
(Downloads, Audio, Images, SD Card, etc). This can safely be run again if something goes wrong:

    termux-setup-storage

Set up shell

  1. Install a desktop SSH app. I recommend FireSSH; GitHub source here, or Google's terminal emulator & SSH client based on NaCl, NaSSH app; GitHub source here.

Invoke chroot environment (do a pgrep -f on chroot to ensure you don't call this multiple times; see Epilog below for setting this to autostart on boot). This is a critical step:

    termux-chroot
  1. From Termux, create a local ssh keypair (assumes you're in chroot):

     mkdir -p /storage/emulated/0/Download/devbox/ssh   
     ln -s /storage/emulated/0/Download/devbox /home/devbox
     ssh-keygen -t rsa -b 4096 -C "your_email@example.com"
    

and follow the prompts:

    Generating public/private rsa key pair.
    Enter file in which to save the key: /home/devbox/ssh/id_rsa
    Enter passphrase (empty for no passphrase): 
    Enter same passphrase again:
    Your identification has been saved in /home/devbox/ssh/id_rsa.
    Your public key has been saved in /home/devbox/ssh/id_rsa.pub.
    The key fingerprint is:
    SHA256:yzwrsYbtfJGe6b9o9UVXLvAs96HbSjyhWTGwiL3V1YI your_email@example.com
     The key's randomart image is:
     +---[RSA 4096]----+
     |           . . ..|
     |        o . E o o|
     |       . o o B o.|
     |          o . O.o|
     |        So   *.+.|
     |      .oo.. =.o .|
     |     o +== + =o  |
     |    ..= *+  o... |
     |     oo=+.o. ..  |
     +----[SHA256]-----+
  1. Add your public key to the Termux ssh user host file. This is a little unorthodox, but remember the service is listening and on a local NAT interface only, bound to a reserved private IP address; ssh in this context is purely a local tty console. If an attacker compromised your notebook enough to recover your localhost key, you have much bigger problems.

     cat /home/devbox/ssh/id_rsa.pub >> /home/.ssh/authorized_keys
    
  2. Find your userid and your Termux private IP number -- you will need this for any localhost web & ssh servers

     $ whoami    
     u0_a49  # <== your value may differ
     $ ifconfig arc0 | awk '/inet /{print $2}'
     100.115.92.2  # <== your value may differ 
    
  3. Start the ssh server inside a chroot (it will be running on 8022)

     $ termux-chroot
     $ sshd
    
  4. Connect with the FireSSH or NaSSH app to the reserved IP address displayed earlier as the current user over port 8022, e.g.: u0_a49@ 100.115.92.2:8022 using the private key just created at /Downloads/devbox/ssh/id_rsa. The Termux sshd server configs can be found at: /data/data/com.termux/files/usr/etc/ssh

Optional, but highly recommended

  • uBlock Origin high-performance ad blocker extension
  • Cog System Viewer app [GitHub]
  • Caret desktop editor, a solid Sublime clone app [GitHub]
  • Zed, a highly configurable desktop code & markdown editor [GitHub]. The UI is purposely non-intrusive, but the minimalism can be a bit confusing at first. Check out the docs here.
  • Signal Desktop app, the standard in secure messaging. Fully supports documents & group chats. More info at Whisper Systems
  • Wire Desktop Android app, supports secure text, video & voice calls [GitHub]. I ended up installing Wire because the Signal Desktop app doesn't support voice calls. Note: Consider signing out of the app when not in use, as the background memory use can substantial.
  • DOM Distiller this is one of my favorite apps. It calls Chrome's reader mode via the Distiller component. Here's an example. GitHub repo

Business software

  • HP Print app If you have an HP, you'll thank me.
  • Native Microsoft documents app by Google to edit & view Word, Excel, Powerpoint files (docx, xlsx, pptx)
  • Google Docs: native app Option A; more stable, offline by default, but could use a little polish.
  • Google Docs: web app Option B; requires connectivity to start, quasi-offline capable. Set config to Open in Window & Pin to Shelf.

Dessert

Netflix. Once installed, from Launcher (the O button on the bottom left menu bar) > Netflix > right click > Open in Window > Pin to Shelf. (This, by the way, is very useful for most Chrome web apps)

netflix

Quake (because why not?)

quake

Optional/Niche

  • Brave Android native app GitHub. Possibly useful to segregate web traffic, but presents as a mobile browser
  • Mosh persistent mobile SSH shell (useful for working with intermittent connectivity, e.g., remote VMs) GitHub

Epilog: Working with Termux


Kill/restarting shell

When things get completely borked (which in two weeks of heavy use only happened a couple of times for me), you can kill & restart Termux. There might be a more elegant way to do this, but here's the blunt hammer method:

  • Slow press on the Termux app > More > Kill Process > OK > close window

  • Open Launcher (the O button on the bottom far left menu bar) > right click > App Info > Force Stop > OK

  • Relaunch Termux

termux-chroot (PRoot)

You will probably want to have chroot & sshd autostart. It's important to call chroot before starting sshd so that new sessions will see the more familiar filesystem layout. Termux-chroot itself is a script which spawns a new shell, so if you call it from a script, the remainder of code won't execute until PRoot exits. There is a Termux:Boot add-on in the works, but in the meantime, here's my simple work around. The logic flow is explained here.

# Create/append to: ~/.bash_profile

if ! pgrep -f "termux-chroot" >/dev/null ; then echo "[Starting chroot...]" && termux-chroot; else echo "[chroot is running]"; fi

if ! pgrep "sshd" >/dev/null ; then echo "[Starting sshd...]" && sshd && echo "[OK]"; else echo "[ssh is running]"; fi

termux-wake-lock
This is useful option to avoid sleep & network weirdness

Epilog: Chromebook tips & quirks

  • The built-in Chrome developer shell crosh is somewhat useful, but is fairly restricted. Worth checking out the help-advanced options.

  • The physical file system location for Downloads outside of Termux is: /home/chronos/user/Downloads/, or in a browser as: file:///home/chronos/user/Downloads/

  • To switch between open apps: Alt + Tab

  • Ctrl+Alt +/- resizes the native Termux app fonts

  • Shift+Ctrl +/- resizes the Chromebook display (1366x768 is optimal/native mode on the Samsung)

  • Shift+Esc is a cool shortcut to the OS task viewer (able to see per-tab browser processes)

  • chrome://about/ is a thing, and if you really want to drill into the inner workings of the system: chrome://system/ (this will take a few seconds to populate -- it's a huge page)

  • If an Android native app goes full screen (i.e., loses the resize buttons in the top right corner, slow press or right click to get a context menu which includes full-screen toggle off

  • To share local files easier with other apps, create a transfer folder in Termux to the /Downloads directory, eg:

      mkdir -p /storage/emulated/0/Downloads/code
      ln -s /storage/emulated/0/Downloads/code /home/code
      cd ~/code
    

or simply save to an external MicroSD card (the 64GB models are around $25).

**Important caveat:** You can create and edit files & code under a symlink to Downloads as shown above (e.g.: /home/code/hello.go) or the SD Card (via Caret or Zed accessing the Chrome OS-level fs) but you can't execute from there because of security restrictions. Instead, build and edit where you wish, but save & run executables from your Termux directories (for example: /home/localbuild, etc).<br /> 
  • Carefully consider sync settings:
    Picture (bottom right) > Settings > People:Sync > (probably want custom)

  • Screenshots: Normally you would use the keyboard (ctrl+Desktop icon), but if using an external keyboard, from Chrome: click the menu icon ⋮ > More Tools > Take Screenshot

  • The bottom bar on the desktop is referred to several ways, sometimes menu, sometimes as task bar, but officially it's called "the shelf".

  • You will make heavy use of the "Launcher" - the ◯ symbol on the far left of the bottom menu bar.

  • Pressing the magnifying glass icon 🔍 above the shift key opens the Launcher, defaulting to the most recently used apps

  • You can't customize the first screen in the Launcher -- it's always the most recently used apps, plus a few others installed, and then a button to "All Apps". You will be clicking that button a lot.

  • You can customize the shelf several ways. Either right click or two-finger tap the touchpad on each of the apps to see more.
    Fix Chrome Apps, Android apps, or even favorite web pages to the shelf by "pinning".

  • For nearly all cases, you will want apps & websites on the Shelf to open "in a Window"; besides feeling more like a typical app, the UI is much more svelte.

  • To bring up a cool map of all keyboard shortcuts, press: Ctrl + Alt + ? (once it's up, hold down the Shift, Alt, or Ctrl keys -- or combinations of, say, Shift and Ctrl -- to see the different shortcut mappings. You can actually press to invoke the desired behavior). Hit Esc to dismiss the map once you're done exploring.

  • To quickly lock your Chromebook: 🔍 + L

  • To toggle caps lock (the built-in keyboard doesn't have one): Alt + 🔍

  • If you really prefer to have a caps lock, you can swap the 🔍 key to make it a proper caps lock: Settings > devices > keyboard > Search > (select Caps Lock in drop down)

  • More info on customizing the Desktop here: https://support.google.com/chromebook/answer/3113576?hl=en

That glowing key is your new best friend:

security key yubikey

Special thanks to Nick, Jonathan, Joe, Wendy, Filippo, Stephan, Tim, and Rob for reviewing an earlier draft of this post.


¹Disclosure: Be wary of 3rd-party sellers offering "open box" and "refurbished" products. These often have poor (or no) warranties, and typically have higher return rates. Links to Amazon were carefully researched to ensure the items are as listed in the descriptions. I receive a small referral credit from purchases made through this post.