Disable privileged ports security theatre on Linux instead of using setcap
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.
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) ;)
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).
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.
sudo setcap 'cap_net_bind_service=+ep' `which node`
sudo sysctl -w net.ipv4.ip_unprivileged_port_start=0
- Document that Site.js disables privileged ports on Linux to bring it in line with macOS and Windows.