Accessing Privileged Ports from HTTP/2 Server
The secret incantation for granting network capabilities
In this episode Ivana learns how to grant Node.js network capabilities so that she can use port 443 for her HTTP/2 Server. Previously on Tangled Web Services, Devin learned how to set up LetsEncrypt certificates that never expire.
Ivana just put the finishing touches on the custom website she developed for the art supply store Rock Paper Scissors. She was ready to put it into production.
Over the past couple of months everything had been developed and tested on her staging server which was configured to listen on port 8443. Browser access to the staging area was through the URL:
Ivana needed to make the server available to the general public on port 443 instead of port 8443. But she knew that ports 0 through 1023 are well-known system ports and that access to them was forbidden by unprivileged software.
The HTTP/2 Server that she was deploying is a Node.js server. Any Node.js server started as a non-root user, runs as a userland process, and is not allowed to access system ports. This is true whether it is executing from a terminal window in the foreground, or with a background daemon using
PM2, or directly under the control of
There was no way she would entertain the possibility of starting the server as
root. There were just too many inherent risks.
Ivana researched what it would take to allow Node.js to directly listen on port 443 as user rwserve. She learned that the Linux command to override the restriction is the set capabilities command
setcap. And the magic incantation to give Node.js network privileges is:
setcap 'cap_net_bind_service=+ep' /usr/bin/node
cap_net_bind_service is the capability to bind a socket to privileged ports; the value
+ep says to add the capabilities "effective" and "permitted"; and the target is the Node.js executable, located at
This did the trick. Now she could access Rock Paper Scissors’ website at
https://rock-paper-scissors.com using the well-known port 443.