首页/安全/安全加固速查/TCP Wrappers(hosts.allow/deny)历史配置清理
服务与端口收敛50 条

TCP Wrappers(hosts.allow/deny)历史配置清理

老系统靠 /etc/hosts.allow 做访问控制:新版本已弱化该机制,容易产生“以为管控了实则没有”的假象,统一迁到防火墙。

安全加固速查安全更新于 2026-10-13

hosts.allow 是什么

TCP Wrappers 是上世纪 90 年代的访问控制机制:服务程序接受连接后,通过 libwrap 查询 /etc/hosts.allow 与 /etc/hosts.deny,按「守护进程名 + 客户端来源」决定是否放行。匹配顺序是:先看 hosts.allow,命中即放行;未命中再看 hosts.deny,命中即拒绝;两边都没命中则默认放行(除非启用 paranoid 模式),所以残留的放行规则优先级最高。

为什么会「写了不生效」

libwrap 不是内核能力,也不是防火墙能力,而是服务程序自己编译链接进去的。主流发行版的 OpenSSH 包早已不再链接 libwrap,写在 hosts.allow 里的 sshd 规则对它完全没有作用;仍有个别老服务(某些构建的 vsftpd、xinetd 托管的明文服务)保留了支持。结果就是同一台机器上,一份文件对一部分服务有效、对另一部分无效,只能逐服务实测确认。

基本信息

机制TCP Wrappers(libwrap)
配置文件/etc/hosts.allow 放行、/etc/hosts.deny 拒绝
规则语法daemon[@host]: client_list
生效前提服务二进制链接了 libwrap
现状主流发行版的 OpenSSH 已不再链接 libwrap
现代替代sshd_config 的 AllowUsers/AllowGroups + 防火墙默认拒绝 + SELinux

典型使用场景

  • 老系统基线核查:检查项里仍有 hosts.allow,但结论必须靠实测而非读文件
  • 系统整改:把老机制的控制意图转写成 sshd 侧限制与防火墙规则
  • 异常排查:同网段 A 服务可连、B 服务连不上,先看两者是否都链接了 libwrap
  • 服务下线:移除相关旧组件前,先盘清还有哪些服务依赖它

核查现状

核查现状
ls -l /etc/hosts.allow /etc/hosts.deny     # 文件是否存在、最后修改时间
grep -Ev '^#|^$' /etc/hosts.allow /etc/hosts.deny   # 看实际写下的规则
ldd /usr/sbin/sshd | grep -i wrap          # 有输出才说明 sshd 受 hosts.allow 约束
sshd -T | grep -iE 'allowusers|allowgroups|denyusers'   # sshd 侧当前生效的控制

转写为现代写法

转写为现代写法
# 老写法:来源用 netmask 形式,不是防火墙习惯的 CIDR
# /etc/hosts.allow
# sshd: 192.168.1.0/255.255.255.0
# 现代写法一:限制可登录的账号与来源
# /etc/ssh/sshd_config
AllowGroups ops-admins
AllowUsers deploy@10.20.0.*
# 现代写法二:防火墙限源
firewall-cmd --permanent --add-rich-rule='rule family=ipv4 source address=192.168.1.0/24 port port=22 protocol=tcp accept'
sshd -t && systemctl reload sshd   # 改 sshd 配置先做语法检查再重载

老机制与现代做法对照

老写法现代等价做法注意事项
sshd: 10.0.0.0/255.0.0.0防火墙限源 + sshd 侧账号限制老写法是 netmask,照抄成 CIDR 到防火墙会失效
sshd: ALL防火墙默认拒绝策略老机制默认放行,语义与防火墙默认拒绝不同
hosts.deny 里 ALL: ALL默认拒绝 + 服务最小化只在服务链接 libwrap 时生效,覆盖面不可靠
telnetd、in.ftpd 等老服务改用 SSH、sftp、scp 隧道明文协议本身就该被淘汰,不必为新机制保留
不同发行版对 tcp_wrappers 相关软件包的取舍不同,个别发行版已不再提供。先确认系统里是否还有 libwrap 及其依赖,再判断哪些服务仍然受影响。
最危险的假象是「文件里配了访问控制」:检查若只读文件内容就下结论,实际可能毫无防护。必须从非允许网段实测一次连接来验证,实测不通过就等于没配。
如果确实要保留老机制,规则写成 daemon: client 形式,来源用 netmask;同时仍应在防火墙上做第二道限制,避免单点依赖。

易错点

  • 把 hosts.allow 当成生效中的访问控制,而目标服务根本没链接 libwrap:合规结论失真,实际防护为零
  • 只删 hosts.deny 却留下 hosts.allow:放行规则先匹配且优先级最高,陈旧规则会直接覆盖预期限制,清理必须成对进行
  • 迁移到防火墙时照抄混合了账号与来源的规则:防火墙只认 IP,账号维度必须落到 sshd_config,漏掉就等于开了口子
  • 移除 tcp_wrappers 相关包前没盘清依赖:个别老服务随后拒绝了原本允许的来源,故障在升级后才暴露
  • 把 hosts.allow 当作唯一控制手段:它只覆盖少数链接了 libwrap 的服务,数据库、Web 等端口完全不受其约束

数据来源与参考

  • hosts_access(5) 手册(历史)
  • OpenSSH 发行说明(libwrap 移除)

相关工具

​‌‌​​‌​​​‌‌​‌‌‌‌​‌‌​​​‌‌​‌‌‌​​‌‌​​‌​‌‌‌​​‌‌‌​​​‌​‌‌​‌​​‌​‌‌‌​​​‌​‌‌​‌​​‌​‌‌​​​‌‌​‌‌‌​‌​​​‌‌​‌‌‌‌​​‌​‌‌‌​​‌‌​​​‌‌​‌‌​‌‌‌‌​‌‌​‌‌​‌