应优先使用sshd_config的DenyUsers或iptables封禁SSH访问,因/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-save配合 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 只适合老系统或临时测试,生产环境别依赖它。


















