为什么1024以下端口是特权端口?

79

我听说这是一种安全功能,但它常常似乎成为了一个安全问题。如果我想编写一个使用特权端口的服务器,我不仅要担心我的代码是否安全,还必须特别担心我是否正确地使用了setuid并且放弃了权限。


7
似乎更多是超级用户的事情。也许转移这个问题? - Martijn
在Linux中,如果你使用了CAP_NET_BIND_SERVICE来设置程序,那么即使以其他用户的身份运行,该程序也能够监听特权端口。请参考setcap手册。 - Rahly
在 UN*X 上发现了 http://yaws.hyber.org/privbind.yaws 的缺陷,该端口低于1024,需要解决方法。 - Devon
1
问题是,我们不必担心是否正确使用setuid。例如,我们可以只说“我的进程将假定在启动时,文件描述符3是您要我侦听的相关套接字”,然后我们可以有一个单一的简单标准的经过验证的程序来降低权限,然后执行命令,然后另一个简单标准的经过验证的程序只需侦听套接字并将该套接字放在给定的文件描述符上。 - mtraceur
2个回答

81

没错,但也意味着与你交谈的任何人都知道你必须拥有root权限才能运行该服务器。当你通过端口22(例如)登录到服务器时,你知道你正在与一个由root运行的进程交谈(除了安全问题),所以你会信任它来保护系统密码或其他可能不会信任任何系统用户账户的信息。

参考资料:http://www.w3.org/Daemon/User/Installation/PrivilegedPorts.html

编辑以详细说明原因:许多最重要的网络服务 - telnet(是的,它仍然经常被使用)、SSH、许多HTTP服务、FTP等等 - 都涉及在网络上传输重要数据(如密码)。在安全设置中,某种类型的加密技术,无论是协议本身包含的(SSH),还是封装在其中的(stunnel、IPSec),都可以保护这些数据免受在线窃听,但所有这些保护措施都在服务器端停止。

为了正确保护您的数据,您需要确信您与"真正的"服务器交流。今天,安全证书是在Web上(及其他地方)实现此目标最重要的方法:您假定只有"真正的"服务器可以访问证书,因此如果您验证与您交流的服务器拥有该证书,那么您就会信任它。
特权端口的工作方式非常相似:只有root用户才能访问特权端口,因此如果您与特权端口交流,您就知道您正在与root用户交谈。这在现代Web上并不是非常有用:重要的是服务器的标识,而不是其IP地址。在其他类型的网络中,情况并非如此:例如,在学术网络中,服务器通常由受信任的工作人员在安全房间内控制,但学生和工作人员却具有相当自由的用户权限。在这种情况下,通常可以安全地假定始终可以信任root用户,因此可以登录到特权端口并安全地发送私人数据。如果普通用户可以监听所有端口,则需要一个额外的层来验证特定程序是否可以信任某些数据。


9
哎,这似乎是一个很微小的原因来限制这么烦人的事情。 - num1
11
相反,这是一个非常重要的原因 - 很明显我之前解释得不够清楚。 - jimw
2
如果你知道一个服务器正在以root身份运行,那么这不会让它更容易受到黑客攻击吗?任何“客户端”都不应该假设或知道你是以root身份运行的。初始密码应该总是被更改,这就是为什么SSH具有安全功能,可以知道一个服务器是否与我之前连接过的相同。仅仅因为它是root,并不意味着它比其他服务更安全或不安全,因为该服务可能已经被黑客攻击并以root身份运行,以窃取你的密码。即使像Linux这样的服务器也允许非root用户监听特权端口(需要root授权)。 - Rahly
5
你的假设是错误的:只有 root 用户可以启动监听特权端口的服务。但一旦服务被启动,通常会放弃 root 权限并以一个受限用户(例如 www-data)的身份运行,正如你提到的那样,这是出于安全原因。因此,在特权端口上运行的服务必须由 root 授权,但通常不会以 root 特权身份运行。 - Dreamer
2
在我的Ubuntu上,以下进程以root身份运行:nginx主进程、smbd、sshd、cupsd、cups-browsed、nmbd、dhclient。这些进程会降低权限:lighttpd、dnsmasq、exim4、mongod、mysqld、avahi-daemon、dictd ntpd。所以你们两个都错了,我是说对的。 - joeytwiddle
显示剩余12条评论

14

您没有说明使用的平台,但至少在Linux上,您可以使用capabilities(特别是CAP_NET_BIND_SERVICE)允许非root进程监听低于1024的端口。例如,请参见如何在Linux上让非root进程绑定到“特权”端口?

另一种选择是设置iptables规则,将特权端口的流量转发到非特权端口(我在生产环境中使用过这种方法,它相当简单并且效果很好)。它也在上述链接中有所描述。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接