C语言 将 Web 服务器绑定到端口 80,而不是 root 用户



我用C编写了自己的Web服务器。如何在不成为 root 用户的情况下将其绑定到端口 80,以免安全性受到损害(缓冲区溢出等(?

我是否应该简单地转发来自在端口 80 上运行的另一个"稳定"服务器的任何流量?

使用转发代理确实是最简单和最推荐的解决方案。它还具有在严重无效的请求到达您自己编写的服务器之前过滤它们的优点。
如果您的应用程序使用用户的 IP 地址,请记住从您的 Web 服务器使用的任何标头(X-Client-IP等(中检索它。但是,仅对真正来自您的 Web 服务器的请求执行此操作,否则用户可能会欺骗其 IP。您可以通过检查请求是否来自您的 IP 并在这种情况下仅检查标头或简单地将您的应用程序绑定到 localhost 来做到这一点。

另一种解决方案是授予程序CAP_NET_BIND_SERVICE功能。这需要 root 使用setcap cap_net_bind_service=ep /path/to/the/executable - 由于该标志存储在文件系统属性中,因此在将文件复制到另一个系统或重新编译应用程序时,它将丢失。

当然,您也可以将程序设置为root,然后在调用bind()后立即切换到非特权用户。但是,根据您的程序的工作方式和作用,这可能不是一个好主意 - 例如,如果由于某种原因需要关闭并重新打开侦听套接字,则需要完全重新启动该过程。

以 root 身份调用 bind() 然后删除权限的另一种方法是让根进程创建套接字并绑定它,然后使用 SCM_RIGHTS 消息通过 UNIX 域套接字连接将侦听套接字传递给非特权进程。

众所周知,

Unix 中 1024 以下的所有端口都需要 root 权限才能打开。在 Unix 系统上,您不希望使用根权限运行尽可能少的应用程序。这是并将永远是一个很大的安全风险。

另一种方法是使用 iptables 将端口 80 流量重定向到更无害的端口(如 8080(。 以下是有关如何设置它的说明。

Iptables 不是最容易设置的工具,但一旦你掌握了它,它就非常有用和强大(而且安全(。

如果要将服务器绑定到端口80,则必须以root身份执行此操作,然后删除权限。

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));

如何在不成为root的情况下将其绑定到端口80,以免安全性受到损害(缓冲区溢出等(

不以 root 身份运行不会使您的系统更安全,它只是增加了另一层来利用。因此,与其考虑如何不以root身份运行,请确保不使用任何已知的不安全函数,如strcpy()sprintf()等,而是使用strncpy()snprintf()等。

我在这个问题上工作了相当长的一段时间,得出的结论是systemd + iptables是解决方案,而不是功能,正如这里详细阐述的那样。

相关内容

最新更新