Running a web-service that binds to port 80 usually doesn't require sudoer privileges. Since ports 80/443 are system ports, meaning they can only be used by privileged users, how come those services are still able to bind to these ports?


There are basically two different approaches:

  1. Initially start running as root, bind to the privileged port, and then drop down to an unprivileged user.

  2. inetd, or xinetd runs privileged, and forwards the requests to web server running unprivileged.

  • 3
    On Linux you can also apply CAP_NET_BIND_SERVICE capability to the program or you can use iptables to redirect a system port to a regular port. – Zan Lynx Jan 19 '15 at 2:00
  • 10
    and just to clarify for OP: the reason that option #1 works is because when processes drop privileges, they're allowed to retain open file descriptors - even if they wouldn't be allowed to open them a second time. – strugee Jan 19 '15 at 7:53
  • There's also Authbind. – Boris the Spider Jan 19 '15 at 12:12

Since port 80/443 are system ports, meaning they can only be used by privileged users

I think you have it wrong. Anyone can use these ports. Binding to them is a privileged operation.

The rationale here is that some user Joe shouldn't be able to write a malicious web server and then make some host on which he doesn't have any administrative rights. Of course this is a pretty weak model there's usually nothing preventing Joe from putting his own computer on the network, and he could have administrative rights to any machine to which he has physical access.

I'll do a demonstration with netcat.

As an ordinary user, I can't bind to port 80:

$ nc -l -p 80
Can't grab with bind : Permission denied

I can bind to port 8080:

$ nc -l -p 8080

Meanwhile in another terminal, I can connect to port 80 and send some data, and see it appear at the server end I just started:

$ nc 8080 <<<"Hello world"

If I want to bind to port 80, I need to be root:

$ sudo nc -l -p 80

Or I can assign the CAP_NET_BIND_SERVICE capability to the nc binary:

$ cp `which nc` .
$ sudo setcap 'cap_net_bind_service=+ep' ./nc
$ ./nc -l -p 80

Another option is to write the server program such that after it's called listen() it drops root privileges. This is a pretty common solution, and you will see it with most daemons. Apache, for example, gets started from init as root, and then drops root privileges and becomes the user www-data or something similar once it's bound to port 80. Try running /etc/init.d/apache start as not root and Apache will probably fail to start.

  • The question says "bind to these ports". Why do you think he has it wrong? – Barmar Jan 21 '15 at 15:14

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.