Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is there a way for non-root processes to bind to "privileged" ports on Linux?

It's very annoying to have this limitation on my development box, when there won't ever be any users other than me.

I'm aware of the standard workarounds, but none of them do exactly what I want:

  1. authbind (The version in Debian testing, 1.0, only supports IPv4)
  2. Using the iptables REDIRECT target to redirect a low port to a high port (the "nat" table is not yet implemented for ip6tables, the IPv6 version of iptables)
  3. sudo (Running as root is what I'm trying to avoid)
  4. SELinux (or similar). (This is just my dev box, I don't want to introduce a lot of extra complexity.)

Is there some simple sysctl variable to allow non-root processes to bind to "privileged" ports (ports less than 1024) on Linux, or am I just out of luck?

EDIT: In some cases, you can use capabilities to do this.

like image 741
Jason Creighton Avatar asked Jan 05 '09 17:01

Jason Creighton


People also ask

What is port binding in Linux?

The ports that a Linux service binds to are categorically defined as either untrusted or trusted ports. The ports defined under TCP and UDP are considered “trusted ports”. A user can communicate with a trusted port through an untrusted port.

What are privileged ports in Linux?

Priviliged portsThe TCP/IP port numbers below 1024 are special in that normal users are not allowed to run servers on them. This is a security feaure, in that if you connect to a service on one of these ports you can be fairly sure that you have the real thing, and not a fake which some hacker has put up for you.

What is Setcap Cap_net_bind_service?

The capability we need to add is CAP_NET_BIND_SERVICE , which is explicitly defined as the capacity for an executable to bind to a port less than 1024. You need to be root to do that, so first, be root. Then, add the capability to the httpd binary: root@myhost # setcap cap_net_bind_service=+ep /usr/sbin/httpd.


1 Answers

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:

  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.

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.

like image 111
Jason Creighton Avatar answered Oct 05 '22 15:10

Jason Creighton