基于iptables -m recent实现端口敲门:按12345→23456→34567顺序在20秒内敲门,成功后5分钟内允许该ip访问ssh 22端口,全程静默丢弃、无响应,彻底隐藏服务。

要实现基于 iptables -m recent 的动态“敲门”认证(Port Knocking),核心思路是:不暴露 SSH 端口,只有按特定顺序、在指定时间窗口内向一组“敲门端口”发送探测包,才会临时放行源 IP 访问 22 端口。整个过程对攻击者完全静默——没敲对,连端口都扫不到;敲错了或超时,规则自动失效。
这不是替代 SSH 密钥或双因素认证,而是加在最外层的“隐形门禁”,显著降低暴力破解和自动化扫描的命中率。
? 基本原理:用 recent 模块做状态记忆
-m recent 不保存完整会话,只记录源 IP 及其最近触发时间。它通过一个内存中的哈希表(默认最多存 20 个条目)跟踪 IP 行为,配合 --set、--rcheck、--update、--seconds、--hitcount 等参数,可构建多步时序逻辑。
关键点:
-
--name指定独立的规则组名称(如KNOCK1、KNOCK2、KNOCK3) -
--rcheck --seconds 30 --hitcount 1:30 秒内该 IP 是否在KNOCK1表中出现过 1 次? -
--update --seconds 30:若匹配上一步,就把该 IP 在KNOCK2表中更新时间戳(并重置计时器) - 所有敲门端口必须是未监听的端口(如 12345、23456、34567),避免被服务占用或误响应
?️ 四步配置:从零搭建敲门链
假设敲门序列是 12345 → 23456 → 34567,全部 TCP,三步需在 20 秒内完成,成功后允许该 IP 在 5 分钟内访问 SSH(22)。
1. 清理旧规则,设置默认策略(安全基线)
iptables -P INPUT DROP iptables -A INPUT -m conntrack --ctstate ESTABLISHED,RELATED -j ACCEPT iptables -A INPUT -i lo -j ACCEPT
⚠️ 务必先加
ESTABLISHED,RELATED和本地回环,否则自己会被锁死。
2. 创建敲门专用链,提高可维护性
iptables -N KNOCKING iptables -A INPUT -p tcp -m multiport --dports 12345,23456,34567 -j KNOCKING
所有敲门包先进入 KNOCKING 链统一处理,不影响主 INPUT 流程。
3. 定义三步敲门逻辑(严格顺序 + 时间窗)
# 第一敲:12345 → 记入 KNOCK1 表 iptables -A KNOCKING -p tcp --dport 12345 -m recent --name KNOCK1 --set -j DROP # 第二敲:23456 → 要求 KNOCK1 表中存在且 ≤20 秒内,成功则记入 KNOCK2 iptables -A KNOCKING -p tcp --dport 23456 -m recent --name KNOCK1 --rcheck --seconds 20 --hitcount 1 -m recent --name KNOCK2 --set -j DROP # 第三敲:34567 → 要求 KNOCK2 表中存在且 ≤20 秒内,成功则记入 OPENSSH iptables -A KNOCKING -p tcp --dport 34567 -m recent --name KNOCK2 --rcheck --seconds 20 --hitcount 1 -m recent --name OPENSSH --set -j DROP
✅ 每步都用
-j DROP静默丢弃,不返回 RST,外部扫描器无法感知端口是否开放。
4. 在 INPUT 主链中启用“开门”规则(放在 SSH 规则之前)
iptables -A INPUT -p tcp --dport 22 -m recent --name OPENSSH --rcheck --seconds 300 --hitcount 1 -j ACCEPT
✅ 仅当 IP 出现在
OPENSSH表中、且最近一次敲门成功发生在 300 秒(5 分钟)内,才允许连接 22。
? 验证与调试技巧
- 查看 recent 表内容(需 root):
cat /proc/net/xt_recent/OPENSSH cat /proc/net/xt_recent/KNOCK1
- 测试敲门(本地执行,替换
your-server-ip):nc -zvw1 your-server-ip 12345 && sleep 1 && nc -zvw1 your-server-ip 23456 && sleep 1 && nc -zvw1 your-server-ip 34567 ssh user@your-server-ip # 此时应能连上
- 查看实时匹配情况(加
-v显示计数器):iptables -L KNOCKING -v -n
? 注意事项与加固建议
- 不要用常用端口敲门:避开 80/443/22/21 等,防止与业务冲突或被 IDS 误标。
-
避免规则顺序错位:
-A INPUT -p tcp --dport 22 ...必须放在OPENSSH规则之后,否则默认 DROP 会拦截。 -
recent 条目上限为 20:若并发敲门用户多,考虑增大内核参数(
echo 100 > /sys/module/xt_recent/parameters/ip_list_tot),但需权衡内存开销。 - 搭配 fail2ban 更稳妥:即使敲门成功,后续 SSH 登录仍受 fail2ban 监控,形成双重防护。
-
定期清理 stale 条目:recent 表不会自动 GC,长期运行后可用脚本定时清空过期项(如
find /proc/net/xt_recent/ -mmin +30 -delete 2>/dev/null)。
这套机制不依赖外部服务或用户态守护进程,纯内核级实现,轻量、可靠、低延迟。只要敲门序列不泄露,攻击者几乎无法发现 SSH 服务的存在。











