Run Node.js apps on low ports without running as root

Dec 17 2012

On Linux (and UNIX), to open a port with a number less than or equal to 1024, traditionally a program must run as the root user. This impacts web applications, which use ort 80 (HTTP) and port 443 (HTTPS) to do business. Many programs (Apache being a great example) use this by running a master process as the root user, and farming work off to helper processes that run with lower privileges. But Node.js is designed to work on a single-process model. So how do you run Node.js apps on low ports without running the script as root?

I looked at a number of solutions, and one suggested by my company's security team seems to be the best solution: For operating systems that support capabilities setting (like Ubuntu 12.04 and later), you can configure the operating system to allow non-privileged apps to listen on low ports. Here I show how to do it, and then briefly explain what is going on. <!--break-->

How to do it

Here's how to do it in three easy steps:

  1. Install the capabilities tools
  2. Explicitly grant Node.js the capability to listen on low ports
  3. Run your app as a non-privileged user

These steps look like this (running as a non-privileged user with sudo access):

$ sudo apt-get install libcap2-bin
$ sudo setcap cap_net_bind_service=+ep /usr/bin/node
$ node foo.js

Note that sudo access is only required for granting the capability. You can run the server with an even lower-privileged user.

What's happening?

How does this work? In a nutshell, recent versions of Ubuntu and other Linux distributions provide access to the kernel's capabilities subsystem, which allows system administrators to grant finer grained permissions to do things that once required root access.

What we are doing above is installing the appropriate user-land tools to talk to this system, and then requesting that /usr/bin/node be allowed to bind services on low ports. While this configuration is not entirely risk free, from a security standpoint, it certainly is superior to running Node as a privileged user.

To learn more, man capabilities (or read the online man page).