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

Asked
Active3 hr before
Viewed126 times

10 Answers

90%

The standard way is to make them "setuid" so that they start up as root, and then they throw away that root privilege as soon as they've bound to the port but before they start accepting connections to it. You can see good examples of that in the source code for Apache and INN. I'm told that Lighttpd is another good example.,OK, I've figured it out (for real this time), the answer to this question, and this answer of mine is also a way of apologizing for promoting another answer (both here and on twitter) that I thought was "the best", but after trying it, discovered that I was mistaken about that. Learn from my mistake kids: don't promote something until you've actually tried it yourself!,There is also the 'djb way'. You can use this method to start your process as root running on any port under tcpserver, then it will hand control of the process to the user you specify immediately after the process starts. ,Another example is Postfix, which uses multiple daemons that communicate through pipes, and only one or two of them (which do very little except accept or emit bytes) run as root and the rest run at a lower privilege.

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
load more v
88%

Install authbind using your favorite package manager.,Configure it to grant access to the relevant ports, e.g. to allow 80 and 443 from all users and groups:,Option 2: Use authbind to grant one-time access, with finer user/group/port control: ,With this you can grant permanent access to a specific binary to bind to low-numbered ports via the setcap command:

With this you can grant permanent access to a specific binary to bind to low-numbered ports via the setcap command:

sudo setcap CAP_NET_BIND_SERVICE = +eip / path / to / binary

Configure it to grant access to the relevant ports, e.g. to allow 80 and 443 from all users and groups:

sudo touch / etc / authbind / byport / 80
sudo touch / etc / authbind / byport / 443
sudo chmod 777 / etc / authbind / byport / 80
sudo chmod 777 / etc / authbind / byport / 443

Now execute your command via authbind (optionally specifying --deep or other arguments, see the man page):

authbind--deep / path / to / binary command line args

E.g.

authbind--deep java - jar SomeServer.jar
load more v
72%

The standard way is to make them "setuid" so that they start up as root, and then they throw away that root privilege as soon as they've bound to the port but before they start accepting connections to it. You can see good examples of that in the source code for Apache and INN. I'm told that Lighttpd is another good example.,Another example is Postfix, which uses multiple daemons that communicate through pipes, and only one or two of them (which do very little except accept or emit bytes) run as root and the rest run at a lower privilege.,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:,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.

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
load more v
65%

How to bind a privileged port below 1024 from a non-root user account?,There are two methods to open a privileged ports below 1024 by non-root user account.,Open network TCP/UDP ports below 1024 by non-root account.,How to open ports below 1024 by a regular non-root user?

  • How to bind a privileged port below 1024 from a non-root user account?
  • How to open ports below 1024 by a regular non-root user?
  • How to start an application with a TCP/UDP port below 1024 by a non-root user?
  • How to start HTTPD service by a non-root user?
  • How to open TCP/UDP port 80/443 by a non-root account?
  • Open network TCP/UDP ports below 1024 by non-root account.
  • Getting permission denied while opening a port below 1024.
$ nc - l 80
Ncat: bind to 0.0 .0 .0: 80: Permission denied.QUITTING.
load more v
75%

I want syslog to run as a non-root user on my linux box. That makes it impossible for it to bind to port 514 - because that's a privileged port. Is there any way I can grant non-admin user "foo" the ability to listen on port 514?,Just found a very good discussion of this here: https://stackoverflow.com/questions/413807/is-there-a-way-for-non-root-processes-to-bind-to-privileged-ports-1024-on-li,This will only work for TCP connections though. If you need to support UDP (or anything else) this way as well as or instead of TCP, then you can use iptables translation rules to achieve the same effect., Horror short story told through a collection of postcards about a man killed by an ancient snake goddess

setcap 'cap_net_bind_service=+ep' / path / to / syslogd
40%

There is only a single iptables rule you need to create in order to do local port forwarding.,There are multiple approaches to allowing a process to run as a non-root user but still provide access to privileged ports (<1024).,In this article I will show how to run Tomcat as a non-privileged user on port 8080, and then use an iptables local redirect rule to forward traffic from the privileged port on 80 to Tomcat.,Ubuntu: Using iptables to forward tcp and udp requests

First install Tomcat7, which is available in the main repository on both Ubuntu trusty and xenial.

$ sudo apt - get install tomcat7
load more v
22%

The well-known ports ranging from 0 to 1024 is often referred to as privileged ports. Most Linux operating systems will prevent non-root users from binding privileged ports. Running a service as root should never be an option as bugs or weaknesses in the service can give an attacker full control of your system. ,Assuming that your are running ubuntu, and have not yet installed authbind, you must start with:,Any user having execution privileges on mywebserver can run it on privileged ports.,The permission to bind to the port can now be granted by simply giving ownership tho this file, in this example it will be the user named webuser.

One option is to run mywebserver on a high port, lets say port 8080, and use port forwarding rules to forwarded the standard port 80 to port 8080. This can typically be done by using iptables (for local host request and requests from external hosts):

sudo iptables -t nat -I OUTPUT -p tcp -d 127.0.0.1 --dport 80 -j REDIRECT --to-ports 8080
sudo iptables -t nat -I PREROUTING -p tcp --dport 80 -j REDIRECT --to-ports 8080

sudo iptables - t nat - I OUTPUT - p tcp - d 127.0 .0 .1--dport 80 - j REDIRECT--to - ports 8080

One option is to run mywebserver on a high port, lets say port 8080, and use port forwarding rules to forwarded the standard port 80 to port 8080. This can typically be done by using iptables (for local host request and requests from external hosts):

sudo iptables -t nat -I OUTPUT -p tcp -d 127.0.0.1 --dport 80 -j REDIRECT --to-ports 8080
sudo iptables -t nat -I PREROUTING -p tcp --dport 80 -j REDIRECT --to-ports 8080

sudo iptables - t nat - I PREROUTING - p tcp--dport 80 - j REDIRECT--to - ports 8080
load more v
60%

You will need at least a 2.6.24 kernel,You will need kernel 3.7+,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.,This has the advantage of working with script servers, and being very simple.

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
load more v
48%

Install authbind using your favorite package manager.,Configure it to grant access to the relevant ports, e.g. to allow 80 and 443 from all users and groups:,Option 2: Use authbind to grant one-time access, with finer user/group/port control:,With this you can grant permanent access to a specific binary to bind to low-numbered ports via the setcap command:

With this you can grant permanent access to a specific binary to bind to low-numbered ports via the setcap command:

sudo setcap CAP_NET_BIND_SERVICE = +eip / path / to / binary

Configure it to grant access to the relevant ports, e.g. to allow 80 and 443 from all users and groups:

sudo touch / etc / authbind / byport / 80
sudo touch / etc / authbind / byport / 443
sudo chmod 777 / etc / authbind / byport / 80
sudo chmod 777 / etc / authbind / byport / 443

Now execute your command via authbind (optionally specifying --deep or other arguments, see the man page):

authbind--deep / path / to / binary command line args

E.g.

authbind--deep java - jar SomeServer.jar
load more v
23%

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?,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.,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),"Bind ports below 1024 without root on GNU/Linux": The document that first pointed me towards setcap.

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
load more v

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