I've written my own web server in C. How can I bind it to port 80 without being root so that the security is not being compromised (buffer overflows etc.)?
Should I simply forward any traffic from another "stable" server that runs on port 80?
I've written my own web server in C. How can I bind it to port 80 without being root so that the security is not being compromised (buffer overflows etc.)?
Should I simply forward any traffic from another "stable" server that runs on port 80?
Using a forward proxy is indeed the easiest and most recommended solution. It also has the advantage of filtering horribly invalid requests before they even reach your self-written server.
In case your application uses the user's ip address for something remember to retrieve it from whatever header your webserver uses (X-Client-IP
etc.). However, only do so for requests that really come from your webserver, otherwise users can spoof their IP. You can do so by checking if the request came from your IP and only check the header in this case or simply make your application bind to localhost.
Another solution would be granting the program the CAP_NET_BIND_SERVICE
capability. This requires root to use setcap cap_net_bind_service=ep /path/to/the/executable
- since the flag is stored in a filesystem attribute, it will be lost when copying the file to another system or recompiling the application.
Of course you could also make your program setuid root and then switch to an unprivileged user right after calling bind()
. However, depending on how your program works and what it does this might not be a good idea - for example, if it needs to close and reopen the listening socket for some reason it would require a full restart of the process.
An alternative to calling bind()
as root, then dropping privileges, is to have a root process that creates the socket and binds it, and then passes the listening socket to the unprivileged process over a UNIX-domain socket connection using a SCM_RIGHTS
message.
Well as you know all ports under 1024 in Unix require root privileges to open. On a Unix system you do not want as few applications as possible running with root privileges. It is and will always be a big safety risk.
An alternative is to use iptables to redirect the port 80 traffic to a more harmless port like 8080. Here is a description on how to set it up.
Iptables is not the easiest tool to setup, but once you have mastered it, it is very useful and powerful (and secure).
if you want to bind your server to port 80 you must do that as root and afterwards drop the privileges.
bind(sockfd, addr, addrlen);
/* process is running as root, drop privileges after bind*/
if (setgid(groupid) != 0)
errx(1, "setgid: Unable to drop group privileges: %s", strerror(errno));
if (setuid(userid) != 0)
errx(1, "setuid: Unable to drop user privileges: %S", strerror(errno));
How can I bind it to port 80 without being root so that the security is not being compromised (buffer overflows etc.)
not running as root does not make your system more secure it just adds another layer to exploit.
So instead of thinking about how not to run as root, please ensure that you do not use any known-insecure functions like strcpy()
, sprintf()
, etc. but instead use strncpy()
, snprintf()
, etc.
I worked on this problem for quite some time and came to the conclusion that systemd
+ iptables
is the solution, and not Capabilities, as elaborated in great detail here.