最稳妥的做法是分层设防:优先用 openssh 的 allowusers 在认证前白名单控制,再用 iptables 网络层兜底;需严格按格式配置、重启服务、保存规则并验证生效。

限制 SSH 访问来源 IP,最稳妥的做法是分层设防:优先用 OpenSSH 原生机制做第一道拦截,再用 iptables 作网络层兜底。这样既保证规则生效可靠,又避免因防火墙配置失误导致锁死自己。
首选方案:用 sshd_config 的 AllowUsers 精准控制
这是当前最推荐、最可靠的限制方式。OpenSSH 8.0+ 默认不启用 TCP Wrappers(/etc/hosts.allow 已基本失效),而 AllowUsers 是内建白名单,认证前就匹配,效率高且无依赖。
- 格式必须严格:用户名@IP 或用户名@CIDR,中间不能有空格,不支持通配符(如
192.168.1.*无效,要写成192.168.1.0/24) - 示例:只允许 admin 从两个固定 IP 登录:
AllowUsers admin@203.0.113.15 admin@2001:db8::2 - 若只按 IP 限制、不限用户,可写:
AllowUsers *@192.168.10.0/24 - 修改后必须重启服务:
sudo systemctl restart sshd;操作前确保有控制台或备用会话
补充防线:iptables 设置网络层白名单
iptables 不替代 SSH 配置,而是作为第二道屏障——防止绕过 SSH 服务本身(如端口扫描、暴力试探)的流量到达服务进程。
- 规则顺序关键:先放行可信 IP,再拒绝所有 SSH 流量。用
-I插入顶部,避免被后续规则覆盖 - 正确写法(以允许 192.168.5.100 为例):
iptables -I INPUT -p tcp --dport 22 -s 192.168.5.100 -j ACCEPTiptables -A INPUT -p tcp --dport 22 -j DROP - 支持 CIDR 和 IP 范围:
-s 10.20.30.0/24或-m iprange --src-range 172.16.1.10-172.16.1.20 - 务必保存规则:
iptables-save > /etc/iptables/rules.v4(Debian/Ubuntu)或service iptables save(RHEL/CentOS)
避坑提醒:别踩这些常见错误
很多“配置了却没生效”的问题,其实源于几个细节疏忽。
-
/etc/hosts.allow在现代系统中大概率不生效——检查ldd /usr/sbin/sshd | grep wrap,返回空即说明未链接 libwrap - 执行
iptables -P INPUT DROP前,一定要留好逃生通道(比如另一个终端保持连接,或设置 30 秒自动回滚:(sleep 30; iptables -P INPUT ACCEPT && iptables -F) &) - 不要混用
-A和-I:放行规则必须在拒绝规则之前,用-I插入开头比用-A追加更可控 - IPv6 流量默认不受 IPv4 规则影响,如需限制,单独加
-p tcp -s 2001:db8::/64 --dport 22 -j ACCEPT
验证是否生效
改完别急着关窗口,立刻验证:
- 查 SSH 配置是否加载:
sshd -T | grep allowusers - 看 iptables 规则顺序:
iptables -nvL INPUT --line-numbers | grep :22 - 从非授权 IP 尝试连接:
ssh user@server_ip应直接超时或拒绝,而非提示密码 - 从授权 IP 连接应正常,且
last -i中登录来源 IP 显示正确











