Sandboxing data crunches, chapter 3: containerize

User namespace

First comes CLONE_NEWUSER. This makes the Step process run as root … but not the real root! It’s a fake root that only exists for the Step process. As far as the Renderer process is concerned, “root” for the Step process is really UID 100000 — it’s effectively “nobody”, so it can’t access files that aren’t world-readable.

“Easy” namespaces

Many namespaces are fire-and-forget. We enable CLONE_NEWUTS and presto — the Step process can’t change our hostname, even if it somehow manages to become root.

Mount Namespace

How do we prevent a rogue Step process from reading /app/secrets/twitter-oauth-secret.json?

The overlayfs-chroot filesystem restricts a process to only read files we supply and only write to a single file.
Steps to create our chroot filesystem

Network Namespace

How can Renderer read and write our database, without giving Step the same privilege?

  • Good thing we used chroot (though unmount would be better): now Step can have a different /etc/resolv.conf. (Workbench’s Step process uses external DNS: 1.1.1.1 and 8.8.8.8.)
  • Good thing we disallow concurrent Step processes per Renderer: now we can hard-code a network-interface name. (Network-interface names must be unique in the Renderer network namespace.)
  • Good thing we made an init script for setting up our chroot. That init script is the perfect place to write our iptables rules. (The rules never change because we hard-coded our network-interface names.)
The crux of Workbench’s network-namespace logic

--

--

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store
Adam Hooper

Adam Hooper

Journalist, ex software engineer