setcap 'cap_net_bind_service=+ep' /path/to/program
this will work for specific processes. But to allow a particular user to bind to ports below 1024 you will have to add him to sudoers.
Have a look at this discussion for more.
(Some of these methods have been mentioned in other answers; I’m giving several possible choices in rough order of preference.)
You can redirect the low port to a high port and listen on the high port.
iptables -t nat -A PREROUTING -p tcp --dport 80 -j REDIRECT --to-ports 1080
You can start your server as root and drop privileges after it’s started listening on the privileged port. Preferably, rather than coding that yourself, start your server from a wrapper that does the job for you. If your server starts one instance per connection, start it from
inetd (or a similar program such as
inetd, use a line like this in
http stream tcp nowait username:groupname /path/to/server/executable argv argv…
If your server listens in a single instance, start it from a program such as
authbind. Either create an empty file
/etc/authbind/byport/80 and make it executable to the user running the server; or create
/etc/authbind/byuid/1234, where 1234 is the UID running the server, containing the line
If your server executable is stored on a filesystem that supports capabilities, you can give it the
cap_net_bind_service capability. Beware that capabilities are still relatively new and still have a few kinks.
setcap cap_net_bind_service=ep /path/to/server/executable
Authbind, @Gilles already mentioned it, but I’d like to expand on it a bit.
It has convenient access control (details in man page): you can filter access by port, interface address, uid, ranges of address or port and combination of these.
It has very useful parameter
Causes authbind to affect programs which are levels deep in the calling graph.
The default is 1.
“Levels deep” means when a script (or program), runs another script it descends a level. So if you have
--depth 5 it means on levels 1 (or is it 0?) through 5 you have permission to bind, whereas on level 6 and on, you don’t. Useful when you want a script to have access, but not programs that it runs with or without your knowledge.
To illustrate, you could have something like this: for sake of security, you have a user
java that is meant to only run java and you want to give him access to port 80:
echo > /etc/authbind/byport/80 chown root:java /etc/authbind/byport/80 chmod 710 /etc/authbind/byport/80
I’ve created the
../byport/80 file, given it to
java users group (each user has it’s own group), and made it executable by group, which means it’s executable by
java user. If you’re giving access by port, the file has to be executable by the user that should have access, so we did that.
This might be enough for the average Joe, but because you know how to use the
--depth parameter, you run (as
authbind --depth [depth] my_web_app's_start_script starting at
--depth 1 and working your way up until you find the smallest depth that works and use that.
Read the man page for details.