It\'s very annoying to have this limitation on my development box, when there won\'t ever be any users other than me.
I\'m aware of the standard workarounds, but non
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.
#!/bin/sh
UID=$(id -u username)
GID=$(id -g username)
exec tcpserver -u "${UID}" -g "${GID}" -RHl0 0 port /path/to/binary &
For more info, see: http://thedjbway.b0llix.net/daemontools/uidgid.html
Or patch your kernel and remove the check.
(Option of last resort, not recommended).
In net/ipv4/af_inet.c
, remove the two lines that read
if (snum && snum < PROT_SOCK && !capable(CAP_NET_BIND_SERVICE))
goto out;
and the kernel won't check privileged ports anymore.
Linux supports capabilities to support more fine-grained permissions than just "this application is run as root". One of those capabilities is CAP_NET_BIND_SERVICE
which is about binding to a privileged port (<1024).
Unfortunately I don't know how to exploit that to run an application as non-root while still giving it CAP_NET_BIND_SERVICE
(probably using setcap, but there's bound to be an existing solution for this).
My "standard workaround" uses socat as the user-space redirector:
socat tcp6-listen:80,fork tcp6:8080
Beware that this won't scale, forking is expensive but it's the way socat works.
With systemd, you just need to slightly modify your service to accept preactivated sockets.
You can later use systemd socket activate.
No capabilities, iptables or other tricks are needed.
This is content of relevant systemd files from this example of simple python http server
File httpd-true.service
[Unit]
Description=Httpd true
[Service]
ExecStart=/usr/local/bin/httpd-true
User=subsonic
PrivateTmp=yes
File httpd-true.socket
[Unit]
Description=HTTPD true
[Socket]
ListenStream=80
[Install]
WantedBy=default.target
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.