Linux无法通过/etc/hosts.allow实现IP黑名单,因其仅支持白名单且依赖TCP Wrappers;现代OpenSSH默认禁用该功能;可靠方式是使用iptables/nftables内核级过滤,或确认sshd编译支持libwrap后谨慎配置hosts.deny。

Linux 限制特定 IP 访问,不能靠 /etc/hosts.allow 做“黑名单”——它只支持白名单逻辑,且仅对支持 TCP Wrappers 的服务生效(如 sshd、vsftpd),现代系统中很多服务(如新版 OpenSSH)已默认不编译 TCP Wrappers 支持。
hosts.allow 和 hosts.deny 实际是白名单+默认拒绝机制
很多人误以为在 /etc/hosts.deny 里写 ALL: 192.168.1.100 就能“拉黑”该 IP,但实际行为是:只要没在 hosts.allow 中显式允许,hosts.deny 的规则才生效;而 hosts.allow 优先级更高。也就是说:
- 如果
/etc/hosts.allow是空的或没匹配项,/etc/hosts.deny的ALL: 192.168.1.100才会起作用 - 但如果
sshd在hosts.allow中写了sshd: ALL,那hosts.deny对 SSH 完全无效 - OpenSSH 从 8.8p1 开始默认禁用 TCP Wrappers(configure 时未加
--with-libwrap),sshd -V | grep wrap输出为空即表示不支持
真正可靠的方式是用 iptables 或 nftables
这是内核级过滤,对所有协议、所有服务都生效,且不受应用层是否支持 Wrappers 影响。以 iptables 为例(CentOS 7 / Ubuntu 18.04 及更早):
iptables -A INPUT -s 203.0.113.45 -j DROP
注意要点:
- 规则顺序很重要:
-A是追加到链末尾,若前面已有ACCEPT规则放行了该 IP,这条DROP就不会触发 - 临时规则重启后丢失,需保存:
iptables-save > /etc/iptables/rules.v4(Debian/Ubuntu)或service iptables save(RHEL/CentOS 6) - 若使用
ufw,应避免混用:ufw deny from 203.0.113.45更安全,ufw 会自动管理底层 iptables
systemd 服务级限制(如仅限 SSH)
如果只想限制某个服务(例如只封 SSH 的恶意 IP),且确认 sshd 编译时启用了 libwrap(ldd $(which sshd) | grep libwrap 有输出),可安全使用 TCP Wrappers:
编辑 /etc/hosts.deny:
sshd: 203.0.113.45, 2001:db8::1
然后确保 /etc/hosts.allow 中没有覆盖性规则(比如没写 sshd: ALL)。验证方式:
- 从目标 IP 尝试 SSH,应看到连接被拒绝(不是密码错误)
- 检查
journalctl -u sshd | grep "refused connect",若有tcpd相关日志,说明生效 - 注意 IPv6 地址需用方括号格式写进
hosts.deny(但实际多数老版本不支持,建议优先用 iptables/nftables)
真正要封 IP,别纠结 hosts.allow 黑名单——它不存在。优先用 iptables 或 nftables,其次确认服务是否真支持 TCP Wrappers 再考虑 hosts.deny。最容易被忽略的是:OpenSSH 新版本默认不认 hosts.deny,连试都不试。










