误用 ipset + iptables 白名单致自锁时,唯一出路是预埋绕过 INPUT 链拦截的自解封脚本(如 iptables -I INPUT 1 -s IP -j ACCEPT),并通过 at 或 systemd-run 在2分钟内触发,且须用绝对路径、避免网络依赖与 ipset 条件判断。

误用 ipset + iptables 白名单规则后,自己被锁在服务器外是高频事故。没有带外管理通道(如 VPS 控制台、IDC KVM)时,靠定时任务或预设命令自解封是唯一出路——但必须确保命令本身不依赖已失效的网络路径,且触发时机精准。
自解封命令必须绕过 iptables INPUT 链拦截
常见错误是把解封命令写成 iptables -D ... 或 ipset del ...,然后丢进 crontab,却没意识到:这些命令执行时,shell 进程仍受当前 iptables 规则约束。如果 INPUT 链已拒绝你的 IP,连本地回环发起的请求(比如 cron 调用的 curl)都可能失败,更别说修改规则。
- 解封操作必须在 netfilter 规则生效前完成,即:放在
INPUT链匹配逻辑之前 - 最可靠方式是用
iptables -I INPUT 1 -s YOUR_IP -j ACCEPT插入最高优先级放行,且该命令需由 root 在无网络依赖环境下运行 - 避免用
ipset命令做条件判断(如ipset test),它本身会触发 netlink 查询,可能被规则阻断 - 不要把解封脚本放在
/tmp或 NFS 挂载点,防止因权限或挂载问题无法执行
预埋自解封脚本 + 系统级触发机制
不能等出事再写命令。应在配置白名单前,就把解封逻辑固化进系统调度链路中:
- 写一个最小化脚本(例如
/root/unlock.sh),只含:iptables -I INPUT 1 -s 203.0.113.42 -j ACCEPT && ipset del whitelist 203.0.113.42 2>/dev/null - 用
at命令设定 2 分钟后执行:echo "/root/unlock.sh" | at now + 2 minutes(比 cron 更快、不依赖 daemon 状态) - 若
atd未启用,改用systemd-run --on-active=120 --scope /root/unlock.sh(适用于 systemd 系统) - 所有命令必须使用绝对路径:
/sbin/iptables、/usr/sbin/ipset,避免 PATH 失效导致找不到命令
ipset 白名单规则中容易忽略的匹配顺序陷阱
ipset 本身不决定封禁逻辑,真正起作用的是 iptables 中引用它的那条规则。很多人以为 “加到 set 就放行”,其实取决于规则位置和跳转目标:
- 典型白名单写法是:
iptables -A INPUT -m set --match-set whitelist src -j ACCEPT,这条必须出现在所有 DROP 规则之前,否则无效 - 如果用了
-j REJECT或-j DROP在前,哪怕 IP 在 whitelist 里,也会被提前拦截 - 检查顺序用:
iptables -L INPUT -n --line-numbers,确认 whitelist 规则序号小于所有拒绝类规则 - 临时调试可加一条日志规则:
iptables -I INPUT 1 -s YOUR_IP -j LOG --log-prefix "UNLOCK-TEST: ",看内核日志是否命中
真正危险的不是不会加规则,而是加完不验证、不设退路。自解封不是补救手段,是上线白名单前必须完成的防御前置动作——尤其当 ipset 和 iptables 规则混用时,一条 -I 和 -A 的差别,就决定了你能不能 ssh 回来。










