6

Is there a way on Linux (CentOS if that matters) to enable regular users to use ports below 1024? (open listening TCP socket on that port)

Currently I understand that only root has privileges to use those ports.

1
  • There was a proposed patch for the linux kernel to enable this via sysctl, but it got voted down because there already are functions aviable to suid wrap it (like the posts below suggest). Opening 1-1024 for all users could be a potential security breach, as someone could hijack your SSHD (or pretend to be a telnet service).
    – pauska
    Nov 13, 2009 at 13:29

6 Answers 6

13

Not on CentOS 3/4/5 (Lack of filesystem capabilities):

You can set the CAP_NET_BIND_SERVICE capability to the program that needs to open this port. Root will set the capability on the executable, then any user may run that executable, it will be able to use ports <1024.

To set the capability on the executable:

setcap cap_net_bind_service=+ep /path/to/program
1
  • Cool idea. I think this should work on CentOS5 / RHEL5 also at least: the documentation of libcap speaks specifically about CAP_NET_BIND_SERVICE.
    – wzzrd
    Nov 13, 2009 at 13:02
5

IIRC this is not possible, or if it is it is not recommended for security reasons.

But if you want users to be able to listen on a specific port you could always use a TCP forwarder like rinetd or iptables rules to redirect connections to that port to one they can listen on and have them set their service to listen on that higher port.

For instance the line

aa.bb.cc.dd    80      127.0.0.1   8000

in rinetd's configuration would forward connections to port 80 on address aa.bb.cc.dd to localhost port 8000 which a non privileged user can listen on. An equivalent iptables rule would be something like

/sbin/iptables -t nat -A PREROUTING -p tcp -d aa.bb.cc.dd --dport 80 -j DNAT --to 127.0.0.1:8000

Either way gives you much more fine grained control than letting any user listen on any port.

The iptables approach has the advantage that the listening application will see the IP address of the calling client (with the rinetd method it would see all connections as coming from the local host). The iptables method would also allow for UDP as well as TCP.

2
  • +1 the iptables approach has worked well for me, minimal performance impact.
    – bobince
    Nov 13, 2009 at 12:33
  • iptables ftw, although -j REDIRECT --to-port 8000 is easier to read, IMAO.
    – womble
    Nov 14, 2009 at 1:32
4

You could create a wrapper which runs SUID and drops privileges after opening the port.

2
  • 2
    More work that you would think: scripts cannot be suid on most unixes afaik, so one would have to dive into writing a little C program, which just isn't for everyone. (Admittedly, a setuid wrapper is a really little C program, which one could just grab any of a kazillion website, but still.)
    – wzzrd
    Nov 13, 2009 at 13:08
  • I know, but the question was very unspecific. If you just want a few fixed ports you could look into redirecting the port from userspace with socat, netcat or tcpserver. If you have a specific application instead look into suid or a wrapper.
    – ko-dos
    Dec 3, 2009 at 20:45
1

authbind rocks.

capabilities is great stuff, but it requires properly configured certain kernel versions. some programs, like sun java, do not with capabilieis. authbind works on all linux versions.

authbind, however, supports only IPv4.

-1

Are these totally out of context, or am I missing something fundamental ? http://smarden.org/runit/chpst.8.html & http://cr.yp.to/daemontools/setuidgid.html

2
  • 1
    Ugh, my bad. Didn't realize that it was the inherent nature of programs such as tinydns, dnscache etc, to run as normal users. and in that case, probably biding to 53 is made possible by chpst. I could use some clarification here, without steering too much from the original question. Sep 10, 2010 at 18:28
  • tinydns and dnscache start as root, bind to port 53, and then switch uids to the ones passed in by chpst (or whatever) using environment variables. Sep 2, 2014 at 22:08
-2

http://isptools.sourceforge.net/suid-wrap.html

This will do all the work for you.

1
  • 1
    This gives considerably more privilege to the process than simply allowing the binding of low ports; this is equivalent to handing the user in question root, and you might as well use something a little more widely adopted in a case where that isn't a problem, such as sudo.
    – esm
    Nov 13, 2009 at 16:28