由于开放计算机的网络访问涉及到许多安全风险,应用程序被设计用来防范多种类型的攻击。然而,某些安全功能可能存在缺陷(RTM 互联网蠕虫事件最显著地证明了这一点,它利用了许多程序中的漏洞,包括旧版本的 sendmail 邮件守护进程),或者无法区分安全主机(接受来自这些主机的特定服务请求)和不安全主机(应该拒绝来自这些主机的请求)。我们已经简要讨论过 finger 和 tftp 服务。网络管理员可能希望将对这些服务的访问限制为仅限“受信任的主机”,这在通常的设置中是不可能的,因为 inetd 要么向所有客户端提供此服务,要么完全不提供。
一个用于管理特定主机访问的有用工具是 tcpd,通常被称为守护进程“包装器”。[1] 对于您想要监控或保护的 TCP 服务,它会被调用来代替服务器程序。tcpd 检查远程主机是否被允许使用该服务,只有当检查成功时,它才会执行真正的服务器程序。tcpd 还会将请求记录到 syslog 守护进程。请注意,这不适用于基于 UDP 的服务。
例如,要包装 finger 守护进程,您必须更改以下文件中的相应行inetd.conf从以下内容
# unwrapped finger daemon finger stream tcp nowait bin /usr/sbin/fingerd in.fingerd |
# wrap finger daemon finger stream tcp nowait root /usr/sbin/tcpd in.fingerd |
在不添加任何访问控制的情况下,这对客户端来说将表现得像通常的 finger 设置一样,只是所有请求都会被记录到 syslog 的 auth 功能中。
两个名为以下的文件/etc/hosts.allow和/etc/hosts.deny实现访问控制。它们包含允许和拒绝访问特定服务和主机的条目。当 tcpd 处理来自名为 biff.foobar.com 的客户端主机对诸如 finger 之类的服务的请求时,它会扫描hosts.allow和hosts.deny(按此顺序)查找与服务和客户端主机都匹配的条目。如果在hosts.allow中找到匹配的条目,则访问被授予,并且 tcpd 不会再查阅hosts.deny文件。如果在hosts.allow文件中未找到匹配项,但在hosts.deny中找到匹配项,则通过关闭连接来拒绝请求。如果根本没有找到匹配项,则接受请求。
访问文件中的条目看起来像这样
servicelist: hostlist [:shellcmd] |
服务列表是来自/etc/services的服务名称列表,或关键字 ALL。要匹配除 finger 和 tftp 之外的所有服务,请使用 ALL EXCEPTfinger, tftp.
主机列表是主机名、IP 地址或关键字 ALL、LOCAL、UNKNOWN 或 PARANOID 的列表。ALL 匹配任何主机,而 LOCAL 匹配不包含点的域名。[2] UNKNOWN 匹配任何名称或地址查找失败的主机。PARANOID 匹配任何主机名无法反向解析回其 IP 地址的主机。[3] 以点号开头的名称匹配所有域名等于此名称的主机。例如,.foobar.com 匹配 biff.foobar.com,但不匹配 nurks.fredsville.com。以点号结尾的模式匹配任何 IP 地址以提供的模式开头的主机,因此 172.16. 匹配 172.16.32.0,但不匹配 172.15.9.1。以下形式的模式n.n.n.n/m.m.m.m 被视为 IP 地址和网络掩码,因此我们可以将之前的示例指定为 172.16.0.0/255.255.0.0。最后,任何以“/”字符开头的模式都允许您指定一个文件,该文件被假定包含主机名或 IP 地址模式的列表,其中任何一个都允许匹配。因此,看起来像 /var/access/trustedhosts 的模式将导致 tcpd 守护进程读取该文件,并测试其中的任何行是否与连接的主机匹配。
要拒绝除本地主机之外的所有主机访问 finger 和 tftp 服务,请将以下内容放入/etc/hosts.deny并将/etc/hosts.allow留空
in.tftpd, in.fingerd: ALL EXCEPT LOCAL, .your.domain |
可选的shellcmd字段可能包含一个 shell 命令,该命令在条目匹配时被调用。这对于设置可能暴露潜在攻击者的陷阱很有用。以下示例创建一个日志文件,列出连接的用户和主机,如果主机不是 vlager.vbrew.com,它会将对该主机的 finger 命令的输出附加到日志文件中
in.ftpd: ALL EXCEPT LOCAL, .vbrew.com : \ echo "request from %d@%h: >> /var/log/finger.log; \ if [ %h != "vlager.vbrew.com:" ]; then \ finger -l @%h >> /var/log/finger.log \ fi |
%h 和 %d 参数由 tcpd 展开为客户端主机名和服务名称。请参阅hosts_access(5)手册页以获取详细信息。
[1] | 由 Wietse Venema 编写,wietse@wzv.win.tue.nl。 |
[2] | 通常只有从/etc/hosts文件中查找获得的本地主机名不包含点号。 |
[3] | 虽然它的名称暗示它是一种极端的措施,但 PARANOID 关键字是一个很好的默认设置,因为它保护您免受恶意主机伪装成非其身份的主机的攻击。并非所有 tcpd 都内置了 PARANOID;如果您的 tcpd 没有内置,则需要重新编译 tcpd 才能使用它。 |