bbaovanc’s Website

world icon

Allow non root processes to bind to privileged ports in Linux

tag icon guide, linux
Table of Contents
Table of Contents

In Linux, processes cannot bind to privileged ports (<=1024) unless they are running as root. Here’s how to allow any process to bind to privileged ports.

Introduction link icon

In Linux, processes cannot bind to privileged ports (<=1024) unless they are running as root. I learned about this when I was trying to add SSH cloning to my Gitea instance. This can be bypassed by giving CAP_NET_BIND_SERVICE capabilities to either the systemd service, or the executable itself.

Giving CAP_NET_BIND_SERVICE capabilities link icon

Using systemd (preferred) link icon

The best way is to tell systemd to give CAP_NET_BIND_SERVICE capabilities to the service. In fact, the Gitea systemd service has two lines1 that are commented out:


Uncommenting these two lines was all I had to do for Gitea.

Using setcap link icon

You can add CAP_NET_BIND_SERVICE to the executable directly using setcap, allowing it to bind to any port. Run the following command2:

setcap 'cap_net_bind_service=+ep' /path/to/program

Note that this means that anyone with permission to run this program will be able to run it and bind to any privileged ports.

Other caveats2:

  1. You will need at least a 2.6.24 kernel
  2. This won’t work if your file is a script. (ie, uses a #! line to launch an interpreter). In this case, as far I as understand, you’d have to apply the capability to the interpreter executable itself, which of course is a security nightmare, since any program using that interpreter will have the capability. I wasn’t able to find any clean, easy way to work around this problem.
  3. Linux will disable LD_LIBRARY_PATH on any program that has elevated privileges like setcap or suid. So if your program uses its own …/lib/, you might have to look into another option like port forwarding.

  1. and ↩︎

  2. ↩︎

See also

chevron-up icon