Allow Non Root Processes to Bind to Privileged Ports
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
Using systemd (preferred)
The best way is to tell systemd to give
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.
You can add
CAP_NET_BIND_SERVICE to the executable directly using
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.
- You will need at least a 2.6.24 kernel
- 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.
- 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.
https://github.com/go-gitea/gitea/blob/3416e2a82586fca4cd452b93237b979300f55d62/contrib/systemd/gitea.service#L69 and https://stackoverflow.com/a/47065825 ↩︎