在封禁SSH访问时,应当优先选用sshd_config的DenyUsers或iptables。原因在于,/etc/hosts.allow在OpenSSH 8.0+以及主流的新系统中,默认是不生效的。DenyUsers能够支持IP与用户的组合进行精准拦截,并且在认证之前就生效;iptables则是在网络层进行硬拦截,更为可靠。

直接改 /etc/ssh/sshd_config 里的 DenyUsers 或用 iptables,别碰 /etc/hosts.allow —— 它在现代系统上基本不生效。
为什么 /etc/hosts.allow 多数时候没用
OpenSSH 8.0+ 版本默认就不链接 libwrap.so 了。怎么判断呢?运行 ldd /usr/sbin/sshd | grep wrap,要是返回空,那就说明TCP Wrappers根本没启用。像CentOS/RHEL 8+、Ubuntu 20.04+这些主流的发行版,都已经默认禁用这个机制了。所以啊,就算你在 sshd: 192.168.1.100 这里写了规则,它也不会触发,可别以为这样就“已经拦住了”,那只是个错觉。
用 sshd_config 的 DenyUsers 精准封禁 IP+用户组合
这是原生支持、认证前拦截、语义明确的方式,适合临时封禁或细粒度控制。
DenyUsers优先级高于AllowUsers:哪怕用户在AllowUsers里,只要同时出现在DenyUsers中,照样拒绝- 格式必须严格:
username@ip_address或username@cidr_net,中间不能有空格;多个条目用空格分隔 - 支持 CIDR(如
admin@203.0.113.0/24),但不支持通配符(admin@192.168.1.*是无效的) - 若只想封某个 IP 的所有用户,写成
DenyUsers *@192.168.1.100
示例:
DenyUsers deploy@203.0.113.45 root@192.168.5.0/24
改完后必须运行 sudo systemctl restart sshd,否则不生效。注意:重启会断开当前连接,务必留一个控制台会话或 VNC 备用。
用 iptables 在网络层硬拦截(最底层、最可靠)
不依赖 SSH 进程,直接在内核 netfilter 层 drop 包,防暴力扫描和端口探测效果最好,适合长期封禁或高危 IP。
- 规则顺序很重要:先
-A INPUT放行可信 IP,再-A INPUT拒绝 22 端口全部流量 - 不要用
iptables -F清空规则——可能瞬间锁死自己;建议先加一条放行当前 IP 的规则,再操作 - 保存规则:Debian/Ubuntu 写入
/etc/iptables/rules.v4,RHEL/CentOS 用iptables-sa ve配合 systemd service
最小可行命令(仅封一个 IP):
sudo iptables -A INPUT -p tcp --dport 22 -s 203.0.113.45 -j DROP
这条规则立即生效,且比任何 SSH 层配置都早一步拦截。
真正难的是判断封禁层级:单个恶意 IP 用 DenyUsers 快速响应;批量扫段或已知攻击源网段,必须上 iptables;而 /etc/hosts.allow 只适合老系统或临时测试,生产环境别依赖它。