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
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
Using systemd (preferred)
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:
systemdCopy
|
|
Uncommenting these two lines was all I had to do for Gitea.
Using setcap
You can add CAP_NET_BIND_SERVICE
to the executable directly using setcap
,
allowing it to bind to any port. Run the following command2:
bashCopy
|
|
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 caveats3:
- 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.
Comments
If you provide an email address, you can enable notifications for replies to your comment. It will not be shown publicly.