For the past month or so, I’ve been coding and doing some small development projects: learning Python, setting my Jekyll-based GitHub Pages personal site up, etc. And all of this has been taking place on a completely bone-stock, stable channel Samsung Chromebook Pro.
I’ve had my toes in the ChromeOS ecosystem ever since I picked up the Acer C720 back in 2013. I’ve always thought it a great tool for basic web browsing and cloud-based activities, but not much more. Though I saw people were getting great flexibility out of the budget laptop, it was mostly by way of Developer Mode, dual booting with BIOS changes, and other things that eroded the “convenience” and “it just works” value propositions that made Chromebooks so great for me.
As an early adopter to the recently launched 2017 Samsung Chromebook Pro, I was interested in finding what new ways existed for getting extra mileage out of ChromeOS and was pleasantly surprised…
The How: The “Termux Secret Sauce”
My $169 development Chromebook
In the last year while talking to respected security-focused engineers & developers, I've come to fully appreciate…
In his detailed post, Kenn White not only sets forth the intellectual case for avoiding the “Developer Mode” + Crouton approach (which to be fair, certainly has its advantages and advocates!), but he also provides the step-by-step process to do so — especially for someone with only basic command line fluency.
The short-version of the story is that by leveraging Android app capabilities on the Chromebooks with Android support, one can run Termux and have a secure Linux-like environment and terminal interface. The contributors to Termux have put together many of the packages one would normally rely on for Linux, making it easy to add applications like Python.
While this is technically workable as-is, using the Termux interface within the ChromeOS Android app window isn’t ideal (Android app window management is still a work in progress, small fonts, only a single terminal session, local web servers will require an Android Chrome browser window, etc.). Kenn’s solution? Spin up an SSH server in Termux and then use one of the several Chrome SSH apps to SSH in!
Edit: Regarding small Termux fonts, as Kevin Young helpfully notes, simply pinch to zoom! *smacks forehead* Duh!
This opens up the universe of font color and size adjustment, copy pasting code snippets in as you’re finding solutions on StackOverflow, flexible window resize, multiple terminal windows, etc.
It’s best to go directly to the source on this (I won’t recount all the well-documented steps from Kenn’s post). But, here are a several of my observations and learnings that I picked up along the way of actually using this Chromebook-Termux-Frankenstein:
Making Termux part of your regular routine
After following the initial Kenn provides, the next step is to make launching Termux and starting the SSH server part of your regular routine.
Kenn provides an approach to running the necessary commands when launching Termux in the epilogue of his guide and here. However it’s worth noting that since publishing his guide, the behavior of
termux-chroot has changed and now the process is now listed as
proot, breaking the pgrep conditional part of the script. See this comment on modifying the script to
pgrep -f proot. At the moment, I now just type in both commands manually as it’s not a huge deal to me.
Also since publication of Kenn’s guide, the developer of Termux has launched a Termix:Boot add on app. Though it is paid, it’s a great way to support Fredrik for his work on Termux! I’ve only spent a little bit of time seeing if I can use it for starting
sshd, but am finding that
termux-chroot doesn’t appear to be a running process while the SSH server seems to start ok. Some people look like they’re running into issues with Termux:Boot loading certain commands correctly, so it may still need a little polish.
I previously noted here that I didn’t fully understand the importance of starting with
termux-chroot. After experimenting with it some, I see now that (and I will probably get the terms of art a bit wrong here) it allows certain OS resources to be made available to the chroot/proot session as if it were a privileged user, obviating the need for actual privileged use. It’s a definite requirement here, and I found that some of my Rails apps failed to properly load without it.
Use Secure Shell to get around tricky file permissions
When using Termux within ChromeOS, there are a few layers of sandboxing and file access that made things tricky — ideally, the Termux Android app has the same file access that a Chrome application (like the amazing Sublime-text-esque Caret text editor) does.
I found that Termux generally only has access to its own file space, with the limited exception of the Android
Download folder, where the full path is:
This folder shares the same contents as the ChomeOS
Downloads folder, is readily accessed by the Chrome File Manager, and so is an okay place for getting data between Chrome and Android. However, I found that while the file permissions allow for the mutual access of data here, certain other write operations fail in this space (e.g., when I tried to set up a Rail webserver in this folder
rails new demo, the process fails if attempted in in
The trick here lies in Google’s Secure Shell Chrome app: Secure FTP Mount! By setting up Secure Shell to SSH into Termux, one can also mount the Termux file space, and it ends up looking like another folder in Chrome’s File Explorer and any other Chrome application! This way I can keep all my data within Termux’s file space and still edit with Caret, do some basic file management with the File Explorer GUI, and…
Accessing an Android localhost web server from ChromeOS
Per Kenn’s documentation (see step 4 of Setup Shell), the internal Android instance in ChromeOS has its own private IP within your Chromebook. Again, the sandboxed nature of things means that the easiest way to view any localhost web server is to do so within the same sandbox Android plays in: through an Android web browser. This happens to be slightly less than ideal given that well, ChromeOS already happens to have a great web browser. *cough*
In some cases, you can configure the local web server to host on
0.0.0.0, and accessing the server in ChromeOS is just a matter of visiting the IP address of the internal Android instance.
However, you may run into problems trying to set the host to
0.0.0.0 like I did when trying to get my Jekyll blog generator local server started. Changes to this application meant that if running Jekyll locally, it would ignore the user config file and default to certain localhost options. It’s very possible I missed an obvious way to set things up, but several hours of experimenting later, I was coming up empty handed.
SSH tunneling/proxy server!
The approach I eventually arrived at was to set up an SSH tunnel with Secure Shell and proxy in (an approach I learned separately when experimenting with trying to get Jupyter Notebook running on a Google Cloud Compute instance).
Following the instructions in this How To Geek article, the first step is to start your Secure Shell session with the
-D SSH argument (for SSH forwarding), followed by a port of your choice.
Next, you’ll need to configure a SOCKS5 proxy for Chrome to use the tunnel as a proxy. Here, the How To Geek article is a little bit dated, and the Chrome extension mentioned, Proxy SwitchSharp, is no longer maintained. Instead, I found SwitchyOmega to be more actively supported and worked well for me. In the same way as the instructions, you just need to configure a proxy server in SwitchyOmega with the SOCKS5 protocol, with
localhost as the server, and with whatever port you specified in your Secure Shell SSH argument.
When you enable the proxy, if you visit your Android instance private IP, you should see the localhost! Once this is working, SwitchyOmega has some pretty decent options for configuring an autoswitch setup where it only activates the proxy when trying to visit a localhost.
Setting up Python and coding
I made it through OneMonth’s Python course (almost entirely) on this Chromebook/Termux mashup. Step one?
pkg install python
This gets a copy of Python 3.6.2 up and ready to go (packages for
python2 , and
python2-dev also exist and are installed in the same way). From here, I could use
pip install ... to install any coursework packages I needed from the Python Package Index (Google Finance, weather, and Twilio APIs, Flask, etc.)
With this setup I was about to learn the basics of Python and write scripts that accessed public APIs. In particular, I took on the challenge of trying to write a script that accessed the New York subway APIs to let me know when the next subway home would be.
A quick note on Flask: to see the server in ChromeOS, remember to either run Flask with the
--host=0.0.0.0 flag, or use the SSH tunnel approach I outlined above.
The biggest challenge I had was trying to get Jupyter Notebook set up. Even though I came across some well documented guides including this one, I couldn’t get all the dependencies right and couldn’t get the Jupyter Notebook web server to load. I ended up getting Jupyter Notebook running on a free instance of Google Cloud Compute. I’ll probably look to revisit this, perhaps on a clean Termux install to see if I can follow the steps more closely.
Setting up Ruby on Rails
Settings up Ruby on Rails also has its fair share of dependency hurdles. It took me a few tries, but ended up finding that using a combination of the approaches in this guide by the Termux maintainer and this other guide got things going.
Of note, start with Fedrik Fornwall’s guide first. It will get you as far as setting up a new Rails project, i.e.,
rails new blog where it will fail here.
Then go to Marius Bobin’s guide, starting with
gem install bundler and follow the steps (I excluded the specific rails version referenced, and also because we followed Fedrik’s steps, we already have a project in
/blog/ instead of “demo.” Of note, you should see that when you try setting up a new Rails project, it will succeed this time. However, when you get to the end, and actually try to start the Rails project, you’ll see that the
rails server command will fail.
Soooo… go back to where you left off Fedrik’s guide, by entering into your project directory, and running
termux-fix-shebang bin/rails and the rest of the steps. This time when attempting to run the rails server, things should work this time!
I concede that there are a bunch of overlapping steps between the two guides, and perhaps when I have the opportunity to wipe and start with a clean Termux install, I might try to test things out out, consolidate the steps, and update this post.
Thus far, I’ve been able to build and deploy a Jekyll-powered blog in this way and learn Rails development on a Pinterest-style project.
There are three reasons that drive my efforts to jumping through all these hoops in order to maintain a stock ChromeOS Chromebook. First, as a person with enough knowledge about security to get myself into trouble, I think it makes good sense to follow the path set by others. I’ve read good things about the ChromeOS security model, and I don’t want to do away with it by choosing Developer Mode without really a solid understanding of the risks.
Also, though Termux requires jumping through a bunch of hoops, the steps are pretty simple and can be easily repeated. For me, one of the big hurdles I have to experimenting and coding is the aversion to breaking things. The Termux approach is nice in that I can wipe the whole app (which I’ve done) and start fresh without ruining the other parts of my Chromebook experience (logins, windows, tabs, etc.) The ease of starting fresh also makes it a good pattern for learning and keeping my install lean.
Finally, Termux happens to be kind of a fun challenge to get going, and it seems like the small, but thoughtful community around Termux thinks so too. Googling whatever I need + “Termux” ends up yielding very specific, helpful resources that I know will be relevant to whatever is I’m trying to do. All these resources have been great!
I put this together to help reinforce my own learnings and to create something tangible of the hours spent Googling and experimenting with things. As may be obvious, I’m pretty new to this, so if there’s something I’ve done, advised, or said that isn’t a best practice or if I’ve used a term of art incorrectly (especially this!), please do feel free to provide that feedback!