knockd配合iptables是最稳定、兼容性最好的ssh隐形门禁方案,它通过动态增删iptables规则,使22端口对外呈现closed或filtered状态,彻底规避扫描与暴力攻击。

直接上结论:用 knockd 配合 iptables 是目前最稳定、兼容性最好、无需改 SSH 服务本身的方式。它不依赖应用层响应,不暴露日志,扫描器扫不到 22 端口——不是“藏得深”,而是“根本不存在”。
为什么不能只靠改 SSH 端口或加 fail2ban
改端口(比如换到 2222)后,nmap -p- 192.168.1.38 依然能扫出开放端口;fail2ban 要等攻击者连上、输错密码才触发封禁,属于“被打了再还手”。而端口碰撞是“门还没装把手”,没敲对序列,iptables 规则里压根没放行那条链,22 端口对外就是 CLOSED 状态,nmap 显示 filtered 或直接无响应。
常见错误现象:service knockd start 启动失败但没报错;nmap -p 7000,8000,9000 192.168.1.38 扫出来全是 closed 却仍无法开门——大概率是网卡名没配对、tcpflags = syn 没生效,或 iptables 规则顺序冲突。
-
knockd默认监听eth0,但 Ubuntu 22.04+、CentOS 8+ 多为ens33、enp0s3等,必须显式在/etc/knockd.conf中写interface = ens33 - 如果服务器开了
ufw,得先ufw disable,否则iptables规则会被绕过 -
seq_timeout是指整个序列完成的总时限(非单个端口间隔),设太小(如 5 秒)容易因网络抖动失败;建议初试设为25
配置 /etc/knockd.conf 的关键参数
一个能跑通的最小可用配置,重点在可复现、少踩坑:
[options] UseSyslog interface = ens33 logfile = /var/log/knockd.log <p>[openSSH] sequence = 7000,8000,9000 seq_timeout = 25 command = /sbin/iptables -I INPUT -s %IP% -p tcp --dport 22 -j ACCEPT tcpflags = syn</p><p>[closeSSH] sequence = 9000,8000,7000 seq_timeout = 25 command = /sbin/iptables -D INPUT -s %IP% -p tcp --dport 22 -j ACCEPT tcpflags = syn</p>
说明:
-
%IP%自动替换为敲门来源 IP,精准授权,不影响其他客户端 -
-I INPUT是插入最前,确保规则优先于DROP;用-A可能被后续DROP吃掉 - 两个
[openSSH]和[closeSSH]必须序列严格相反,否则关门命令会失败(iptables -D找不到对应规则) - 别用
localhost或127.0.0.1测试,本地回环不走INPUT链,永远不触发
敲门测试必须用真实外网 IP + 正确工具链
在另一台机器(如 Kali 或任意 Linux 客户端)操作,不能在本机测。常见失败原因:用错了协议、漏了 -v、没等够超时时间。
- 推荐用
knock命令(比nmap更干净):knock -v 192.168.1.38 7000 8000 9000——-v能看到每个包是否发出,避免静默失败 - 若只有
nmap,必须加--packet-trace并确认输出含Sent 1 SYN,且三个端口都显示tcpwrapped或filtered(不是closed) - 敲完立刻
ssh -o ConnectTimeout=5 bask@192.168.1.38,别等太久;cmd_timeout默认是 0(永不过期),但实际应配合iptables的--seconds或用knockd的cmd_timeout参数控制 - 验证是否生效:
iptables -nvxL INPUT | grep 22,应看到一条带源 IP 的ACCEPT记录
最容易被忽略的防火墙初始化和权限问题
很多配置看似对,但 knockd 启动后毫无反应——根源常在系统级约束。
-
/etc/default/knockd中必须设START_KNOCKD=1,否则systemctl start knockd实际不加载任何配置 -
knockd进程需读取/proc/net/ip_tables_names,普通用户启动会 Permission Denied;务必用 root 启动:sudo systemctl start knockd - Ubuntu 20.04+ 默认用
nftables,但knockd写死调用/sbin/iptables,需确认iptables-legacy已安装并设为默认:update-alternatives --config iptables - 生产环境务必加
cmd_timeout = 30到[openSSH]段,否则一旦敲门成功却未登录,22 端口将长期暴露
复杂点在于:敲门序列本身不加密,中间人能看到端口访问顺序;真正需要高安全场景,得上 SPA(Single Packet Authorization),但那是另一套机制了——knockd 解决的是“让扫描器找不到门”,不是“防流量分析”。











