Disable privileged ports security theatre on Linux instead of using setcap
Summary
Currently, we’re using setcap
to grant the CAP_NET_BIND_SERVICE
privilege to allow Node.js (during development and testing) and the Site.js binary (during deployment) to bind to the “privileged” web ports (80 and 443).
Given that using setcap
has undesirable side-effects that have recently started affecting Site.js and given that the privileged ports feature in Linux is outdated security theatre (also read this) we will be moving to disabling privileged ports in the kernel on Linux systems by setting the net.ipv4.ip_unprivileged_port_start
value to zero using sysctl
when Site.js is run.
Background
Privileged ports is an archaic security feature that dates from the days of mainframe computers and dumb terminals that is not helpful (and actually leads to certain more dangerous security practices, like badly-designed server processes being run as root). They’ve been obsolete for quite a while, macOS removed them as of Mojave, and there’s no comparable concept on Windows either. Heck, they even cause climate change, apparently (a good read, seriously) ;)
Use case
While the setcap
method has been working fine so far, the latest version of nyc (the code coverage tool I’m using) does not work when Node.js has the CAP_NET_BIND_SERVICE
privilege set. Apparently, setcap
disables certain functionality while granting said privilege.
While researching this, I found out that modern Linux kernels (4.11 onwards) have an option to set the number where unprivileged ports start. Setting this to zero effectively removes the concept of privileged ports (and good riddance; this should be the default on Linux distributions in 2020).
Implementation details
Replace the use of setcap
with a single call to start unprivileged ports at port 80 (which is the one we need) at the start of processing.
Old
sudo setcap 'cap_net_bind_service=+ep' `which node`
New
sudo sysctl -w net.ipv4.ip_unprivileged_port_start=0
TODO
-
Implement -
Document that Site.js disables privileged ports on Linux to bring it in line with macOS and Windows.