
iptables 如何用 time 模块限制访问时段
iptables 本身不直接支持时间控制,必须加载 xt_time 模块(内核模块),否则所有带 --timestart 的规则都会报错 iptables: No chain/target/match by that name。确认模块已加载是第一步,不是可选项。
实操建议:
- 运行
lsmod | grep xt_time,无输出就说明没加载;执行sudo modprobe xt_time临时启用 - 要永久生效,把
xt_time加进/etc/modules(Debian/Ubuntu)或/etc/sysconfig/modules/iptables.modules(RHEL/CentOS) -
xt_time默认只支持 UTC 时间,本地时区需换算——比如你在北京想封 22:00–06:00,得写成--timestart 14:00 --timestop 22:00(UTC+8)
封禁外网访问的典型规则写法
目标是“禁止本机主动连外网”,不是封入站流量,所以规则必须加在 OUTPUT 链,且匹配协议和目标地址范围。只封 INPUT 或只封 192.168.0.0/16 这类内网段毫无意义。
实操建议:
- 基础命令:
sudo iptables -A OUTPUT -m time --timestart 22:00 --timestop 06:00 --kerneltz -d ! 10.0.0.0/8 -j DROP -
--kerneltz是关键:告诉模块用系统时区而非 UTC,避免手动换算出错 -
-d ! 10.0.0.0/8表示“非内网地址”,可根据实际调整为! 172.16.0.0/12或! 192.168.0.0/16,但别漏掉!否则会封死自己 - 务必加
-m time,不能写成-m timer或-m datetime——那些不存在
规则顺序和持久化容易踩的坑
iptables 规则按顺序匹配,一旦某条规则放行了流量,后面的 DROP 就无效。常见错误是把 time 限制规则插在默认 ACCEPT 规则之后,结果形同虚设。
实操建议:
- 用
sudo iptables -L OUTPUT --line-numbers查看当前 OUTPUT 链顺序,确保 time 规则在最前面(或至少在任何 ACCEPT 之前) - 重启后规则消失?别用
iptables-save > /etc/iptables/rules.v4硬写——某些发行版(如 Ubuntu 22.04+)默认用 nftables 后端,iptables命令只是兼容层,保存需用sudo netfilter-persistent save - 测试时先用
-C检查规则是否存在:sudo iptables -C OUTPUT -m time --timestart 22:00 --timestop 06:00 --kerneltz -d ! 10.0.0.0/8 -j DROP,避免重复添加
time 模块的边界行为和替代思路
xt_time 对跨日时段(如 22:00–06:00)的支持是可靠的,但它不处理“每周几”或“节假日”,也不支持毫秒级精度。如果你需要周一到周五封网、周末放开,就得靠外部调度(比如 cron + iptables 启停)。
实操建议:
- 跨日写法合法:
--timestart 22:00 --timestop 06:00会被正确解析,不用拆成两条规则 - 如果发现规则“有时生效有时不”,先检查系统时间是否同步:
timedatectl status,NTP 失效会导致 time 模块判断失准 - 真要按星期控制?写两个脚本:
disable-internet.sh和enable-internet.sh,用crontab -e在对应时间点调用sudo iptables -D或-A
time 模块看似简单,但时区、链位置、模块加载、持久化这四点只要漏一个,规则就静默失效——它不会报错,只会让你以为“好像没封住”。











