Is there a way for non-root processes to bind to privileged ports on Linux?
Okay, thanks to the people who pointed out the capabilities system and CAP_NET_BIND_SERVICE
capability. If you have a recent kernel, it is indeed possible to use this to start a service as non-root but bind low ports. The short answer is that you do:
setcap 'cap_net_bind_service=+ep' /path/to/program
And then anytime program
is executed thereafter it will have the CAP_NET_BIND_SERVICE
capability. setcap
is in the debian package libcap2-bin
.
Now for the caveats:
- You will need at least a 2.6.24 kernel
- This won't work if your file is a script. (i.e. 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 anyprogram
that has elevated privileges likesetcap
orsuid
. So if yourprogram
uses its own.../lib/
, you might have to look into another option like port forwarding.
Resources:
- capabilities(7) man page. Read this long and hard if you're going to use capabilities in a production environment. There are some really tricky details of how capabilities are inherited across exec() calls that are detailed here.
- setcap man page
- "Bind ports below 1024 without root on GNU/Linux": The document that first pointed me towards
setcap
.
Note: RHEL first added this in v6.
What's the standard way of dealing with apps that need to access privileged ports 1024?
You can assign the CAP_NET_BIND_SERVICE
capability
to the binary, or run as root
to acquire the port and immediately drop permissions.
Related Topics
How to Use Variables in Bash Sed Command, Specific Example
How to Symlink a File in Linux
./Configure: /Bin/Sh^M: Bad Interpreter
"Unable to Find Remote Helper For 'Https'" During Git Clone
Sorting Multiple Keys With Unix Sort
Setting Environment Variables in Linux Using Bash
"/Usr/Bin/Ld: Cannot Find -Lz"
Extract File Basename Without Path and Extension in Bash
How to Disassemble Raw 16-Bit X86 Machine Code
How to Change the Default Browser Used by the Ipython/Jupyter Notebook in Linux
How to Change the Number of Open Files Limit in Linux
Read Values into a Shell Variable from a Pipe
How to Parse Xml Using Shellscript
How to Get Docker Linux Container Information from Within the Container Itself
How to Configure Apache 2 to Run Perl Cgi Scripts