Here's a quick tutorial on how to make unprivileged programs listen on privileged ports. The trick here is to make the unprivileged program to listen on an unprivileged port and redirect the privileged port to the unprivileged through iptables.

Here's a concrete example. Let's say you want to run a web server (on port 80) but don't want to run it as root as it has security implications. What you do instead is run your web server on port 8080 (or any other unprivileged port) and redirect port 80 to 8080 with iptables.

You'll need at least 2 iptables rules to set it up. The first rule will redirect all incoming traffic on all public interfaces from port 80 to port 8080:

iptables -A PREROUTING -t nat -p tcp --dport 80 -j REDIRECT --to-port 8080

The second rule will redirect all localhost traffic from port 80 to port 8080:

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

You might also need a third rule that will redirect all localhost traffic directed to the public IP (or hostname) of the service:

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

If you're unfamiliar with iptables, see the the frozen tux iptables tutorial. It's the best iptables tutorial out there.


Bob Permalink
October 27, 2013, 23:53

This is cool but I don't have iptables. How can you do this with pf or ipfw?

Klickback Permalink
October 28, 2013, 06:21

@Bob: With pf on FreeBSD, I use something like this:

# Let's assume your public-facing interface is called "re0" and
# public IP is "". Substitute your own values here

# Let's say you have nginx running on port 8080
# Forward nginx's port 8080 to external IP port 80
rdr on $ext_if proto tcp from any to $ext_addr/32 port 80 tag nginx -> $ext_addr port 8080

#Allow visitors to Nginx on port 8080
pass in quick on $ext_if proto tcp from any to $ext_addr port 8080 tagged nginx
bob Permalink
October 29, 2013, 00:10

Cool, thanks!

October 28, 2013, 08:49

Under Linux you can also use authbind to selectively enable the usage of low (< 1024) ports by non-root programs.

logoff Permalink
October 28, 2013, 14:37

It is a good solution, but it has security implications too. You can create a unprivileged program that uses privileg ports. It sounds obvoius, but need to be considered anyway.

Thank you for the iptables trick!

Peter Permalink
November 13, 2013, 20:46

Sweet! I was doing this using Apache (pushing port 80 to a VM, but the VM manager was not running as root), but this is much better. I had to modify the approach somewhat because I'm using ufw (
Here's what I did to make it work:

Turn on forwarding for ufw first:
edit /etc/default/ufw
edit /etc/ufw/sysctl.conf
  uncomment net/ipv4/ip_forward=1

Then add the forwarding rules to /etc/ufw/before.rules
(to the top of the file just after the header comments):
#nat Table rules
-A PREROUTING -p tcp --dport 80 -j REDIRECT --to-port 8080

Save changes and bounce ufw:
sudo ufw disable && sudo ufw enable

Allow the unprivileged port through the firewall:
sudo ufw allow 8080 
November 15, 2013, 00:33

Notice that you can also send file descriptors through unix domain sockets, using sendmsg(2). So you can open the listening socket using a root process that passes it through a unix domain socket to your non-root process.

(Btw, you should get comment-rss-feeds for your comment threads.)

seth Permalink
November 20, 2013, 12:03

You can use capabilities to enable the same thing.

setcap 'cap_net_bind_service=+ep' /path/to/program

December 02, 2013, 01:00

Yes, but only under Linux. The other possibility works on other Unix-Systems too.

June 11, 2015, 14:46

This works really well thank you for posting.

Leave a new comment

(why do I need your e-mail?)

(Your twitter name, if you have one. (I'm @pkrumins, btw.))

Type the word "computer_396": (just to make sure you're a human)

Please preview the comment before submitting to make sure it's OK.