讲个真事儿:前阵子帮朋友排查一台云服务器,现象很怪——SSH连得上,Nginx页面也开得起,但业务接口就是间歇性超时。折腾了两小时,最后发现是他在安全组和 iptables 两层各加了一条白名单规则,端口倒是放开了,却没放行回包方向,导致响应报文被自己的防火墙吞掉。这种问题说出来轻描淡写,经历过的人都知道有多恶心。
iptables 这东西,劝退过很多人。满屏的-A、-t、-j,看起来像某种古老咒语。但只要你搞懂它背后“链、表、规则顺序”这套骨架子,再回头去看那些命令,就真的只是“照着清单填参数”而已。这篇东西不打算讲什么高深内核,就按我实际干活的路子走:先拆原理,再怼实战配置,然后把双机热备、IPS/WAF 联动这些“全栈链路”上的事儿说清楚,最后附上我踩过的一堆坑和排查速查表。适合正在学 Linux 网络、被防火墙折腾到崩溃、或者想在简历上写“全栈运维”却对 iptables 心里没底的同学。
1. 先把 iptables 的骨架子搭明白:五链四表与数据包旅程
1.1 数据包从进门到出门,经过的是一条固定流水线
理解 iptables 最怕的就是背命令。红帽系的考试题让你背-A INPUT -p tcp --dport 22 -j ACCEPT,你背下来了,但换个场景就懵。真正的底层逻辑是:每一个数据包在 Linux 内核里走的路是固定的,iptables 只是在这条路上的几个检查点放了一堆规则。
这条路由顺序是这样的:
- 一个数据包从网卡进来,第一站是
PREROUTING链。这里通常做 DNAT 端口映射、改目的地址。 - 接着内核做路由判断:这个包是发给本机的,还是需要转发的?
- 发给本机的包,走
INPUT链,检查通过后交给本地进程。 - 本机进程发出的包,走
OUTPUT链,出去之前还要经过POSTROUTING。 - 需要转发的包(比如你拿 Linux 当路由器),走
FORWARD链,然后到POSTROUTING做 SNAT / 伪装上网。
这五条链,就是 iptables 的“五脏六腑”。你可以把这张图和生活中的快递流程对应起来:PREROUTING是驿站分拣台,INPUT是你家门口的保安,OUTPUT是你寄件时的门卫,FORWARD是小区之间的中转站,POSTROUTING是快递出城前的最后一道关卡。一个包从进来到出去,每一步都有对应的检查点,漏掉任何一个,配置就会出幺蛾子。
我在给新手讲的时候,一直强调一个观点:先画数据流,再写命令。你连这个包是“本机访问”还是“转发经过”都没搞清,就直接抄网上的命令,大概率会出问题。最常见的例子就是:明明想放行内网机器访问外网,结果你只在INPUT链加规则,完全没动FORWARD,转发当然不通。
1.2 四张表各管一摊事:filter、nat、mangle、raw
链是数据流的路由,表则是不同职责的分工。iptables 之所以叫“iptables”,是因为规则都存在表(table)里。这张关系表是我每次培训都要画的:
| 表名 | 主要职责 | 常见用途 | 与哪些链关联 |
|---|---|---|---|
filter | 允许/拒绝数据包 | 黑白名单、端口管控,最常用 | INPUT、FORWARD、OUTPUT |
nat | 修改数据包源/目的地址 | SNAT 上网伪装、DNAT 端口映射 | PREROUTING、OUTPUT、POSTROUTING |
mangle | 修改 TOS、TTL 等特殊标记 | QoS 标记、策略路由辅助 | 全部五条链 |
raw | 决定是否跳过连接追踪 | 高流量场景免除 conntrack 开销 | PREROUTING、OUTPUT |
一般人日常操作 90% 都在filter表,再加一点nat表就够用了。mangle 和 raw 属于进阶项目,新手期不用硬啃。但你必须知道它们存在,不然上网搜资料时会看懵——别人写-t mangle,你以为是多此一举,实际上那是做特殊标记用的。
这里我建议养成一个习惯:每一条规则前面都显式加上-t参数。虽然 iptables 默认是 filter 表,你不写也能跑,但一旦写复杂了,-A INPUT到底是加在 filter 还是 nat 里?你自己回头看都容易懵。写清楚是哪张表,后续维护省心十倍。
1.3 规则的“排队检查”机制:第一条命中即生效
iptables 的规则是顺序敏感的。内核拿到数据包后,会从该链的第一条规则开始逐条匹配,一旦某条规则匹配成功并且动作是ACCEPT或DROP,后面的规则就不再看了。这就是“首条匹配即生效”。
这个特性特别像公司门禁:保安手里有一叠放行名单,从上往下翻,翻到谁算谁。名单第一条写着“不准穿黑色衣服的人进”,那门口排队的客人里穿黑衣服的直接被拒,后面再有什么“放行 VIP”都轮不到他。规则顺序写反,后果就是这么无辜又致命。
我见过最经典的翻车现场:网上的教程让你先写iptables -A INPUT -j DROP作为兜底,你照着抄,然后又想放行 80 端口——-A INPUT -p tcp --dport 80 -j ACCEPT。因为兜底 DROP 在第一条,端口放行排在后面,结果HTTP永远不通。正确做法是用-I INPUT 1把新规则插到最前面,或者把兜底 DROP 放到最后。这条经验,值不少钱。
除了顺序,还要理解“链默认策略”。如果链上没有任何规则命中,最终由默认策略(policy)决定。默认策略一般是ACCEPT或DROP。安全加固时,大家喜欢把INPUT的默认策略改成DROP,但这一步必须搭配放行规则一起操作,否则你会亲手把自己锁在服务器外面。
2. 日常高频场景:黑白名单、端口放行与出站管控
2.1 黑白名单的落地思路:先拒绝一切,再精确放行
防火墙黑白名单这事儿,说起来就四个字——“默认拒绝”。但落地时很多人犹豫:万一漏了规则,服务不就挂了吗?所以现实里最常见的折中做法是:临时测试环境用“默认允许 + 黑名单”,正式环境用“默认拒绝 + 白名单”。
以一台公网 Web 服务器为例,我一般这样配置:
# 1. 先把 INPUT 链默认策略改成 DROP,这是所有防线的基石 iptables -P INPUT DROP # 2. 放行本地回环,别把自己系统内部通信搞死 iptables -A INPUT -i lo -j ACCEPT # 3. 放行已建立的连接和关联连接,这是最重要的回包通道 iptables -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT # 4. 再放行具体服务端口 iptables -A INPUT -p tcp --dport 22 -j ACCEPT iptables -A INPUT -p tcp --dport 80 -j ACCEPT iptables -A INPUT -p tcp --dport 443 -j ACCEPT # 5. 最后兜底拒绝,并把没被规则处理的包日志记录一下,方便排查 iptables -A INPUT -j LOG --log-prefix "IPT-DROP: " --log-level 4 iptables -A INPUT -j DROP这套配置的核心思路就是**“先默认拒绝,再撕开口子”**。顺序上,放行回包必须放在列表前面,否则你连 SSH 登录都维持不住——因为服务器回应你的 SSH 流量属于 ESTABLISHED 状态,如果状态放行规则排在 DROP 后面,那这些回包同样会被扔掉。这条经验是无数人踩过之后才记住的:放行 ESTABLISHED,RELATED 的回包规则,请永远放在同一条链的靠前位置。
黑名单模式就简单多了,适合低风险内网环境:
# 默认全部允许 iptables -P INPUT ACCEPT # 但要屏蔽某个恶意 IP 的访问 iptables -A INPUT -s 203.0.113.5 -j DROP # 或者屏蔽某个 IP 段 iptables -A INPUT -s 203.0.113.0/24 -j DROP强调一下:黑名单模式省心,但千万别用在公网服务器上。互联网上的扫描器是无差别攻击的,默认 ACCEPT 意味着你每开一个端口都暴露在全网面前,被扫到是迟早的事。
2.2 想让某个程序彻底断网,iptables 能管到进程吗?
热词里有个“屏蔽 acrobat.exe 联网”的需求,这类问题几乎天天有人问。先说结论:iptables 工作在 IP 层,它不认识 exe,也不认识进程名。但换个思路,它认识“这个包是谁发出的”。
Linux 下可以用owner模块按进程的用户 ID(UID)或组 ID(GID)匹配:
# 创建一个专用用户,比如叫 appno useradd appno # 以 appno 身份运行那个程序 sudo -u appno /opt/someapp/someapp & # 禁止 appno 发出的出站包 iptables -A OUTPUT -m owner --uid-owner appno -j REJECT这个方案的关键是让目标程序以独立用户身份运行。如果程序是 root 启动的,那你不能直接用--uid-owner root去限制,因为 root 下所有进程都受影响,很容易误伤系统服务。实际生产里我会配合 systemd 服务配置里的User=字段来指定运行用户,再把 OUTPUT 链的对应规则加进去。
不过这种方案有一个天然的边界:它只对本机自己发出的包有效(OUTPUT 链路经)。如果是别的机器上跑的 Windows 程序,Linux 的 iptables 鞭长莫及,你需要在源机器或网关设备上按 IP、按端口、按时段做管控。比如公司网络里禁止某台 PC 访问特定网站,最靠谱的办法是在路由器 / 防火墙上按源 IP 和目标地址做匹配,而不是追着进程名跑。
2.3 “反向允许”到底是什么,以及怎么落地
“iptables 反向允许”这个热词经常出现在各种讨论里,但大家说的往往不是同一件事。我拆成两种最容易遇到的场景:
场景一:出站默认拒绝,但得允许访问外部白名单。这种是“反向”的典型——别人做防火墙都是管“谁进来”,你要管的是“谁出去”:
iptables -P OUTPUT DROP # 允许本机访问外部 DNS、HTTP、HTTPS iptables -A OUTPUT -p udp --dport 53 -j ACCEPT iptables -A OUTPUT -p tcp --dport 53 -j ACCEPT iptables -A OUTPUT -p tcp --dport 80 -j ACCEPT iptables -A OUTPUT -p tcp --dport 443 -j ACCEPT # 允许回包:已经建立连接的应答流量必须放行 iptables -A OUTPUT -m state --state ESTABLISHED,RELATED -j ACCEPT这样配置后,服务器可以主动访问白名单端口,但其他外联全被掐断。如果程序还偷偷走 8080 之类的端口往外发数据,直接就被拦了。很多安全加固要求里的“最小化出站”就是这么干的。
场景二:内网服务映射到公网后,“允许外部访问进来的同时,也要允许内网服务器响应回去”。这句话看起来像废话,但配置 NAT 时经常有人漏了。内网 Web 服务器响应公网用户请求时,数据包是要经过 FORWARD 链的:
# 响应公网用户的回包,属于 ESTABLISHED,在 FORWARD 链放行它 iptables -A FORWARD -m state --state ESTABLISHED,RELATED -j ACCEPT如果你做了端口映射但 FORWARD 链没有这条放行,外部用户就会卡在“能发出请求,但收不到响应”的诡异状态。这个坑在 DNAT 配置里非常高频,后面我在 NAT 实战里还会再提。
2.4 NAT 隐藏与端口转发,家里的内网服务器出公网靠它
NAT 是整个 iptables 里最容易被误解的部分。很多人只知道“上网要开 NAT”,但对 SNAT 和 DNAT 的区别模模糊糊。
SNAT 解决的是“从内网出去的数据包,怎么带公网地址回来”。以家庭宽带为例:运营商只给你一个公网 IP,但家里手机、电脑、服务器都要上网。这些内网地址(192.168.x.x)到了互联网上没法路由,必须在出口把源地址换成运营商分配的公网 IP:
iptables -t nat -A POSTROUTING -s 192.168.1.0/24 -o eth0 -j MASQUERADE如果公网地址是动态的(拨号上网会变),用MASQUERADE最省心——它每次连接都会自动读取出口网卡当前 IP。如果公网 IP 是固定的,用SNAT性能更好、也更明确:
iptables -t nat -A POSTROUTING -s 192.168.1.0/24 -o eth0 -j SNAT --to-source 203.0.113.10DNAT 解决的是“外部访问公网某端口,怎么转发给内网某台机器”。比如你想在外网通过203.0.113.10:8080访问家里192.168.1.10的 80 端口:
iptables -t nat -A PREROUTING -d 203.0.113.10 -p tcp --dport 8080 -j DNAT --to-destination 192.168.1.10:80别忘了同时开启内核转发,并放行 FORWARD 链:
sysctl -w net.ipv4.ip_forward=1 echo "net.ipv4.ip_forward = 1" >> /etc/sysctl.conf iptables -A FORWARD -p tcp -d 192.168.1.10 --dport 80 -j ACCEPT iptables -A FORWARD -m state --state ESTABLISHED,RELATED -j ACCEPT说个实战教训:有次我在朋友家帮他配端口转发,公网 IP 填的是路由器自己拨号拿到的地址,然后 PREROUTING 把 8000 端口转发给内网群晖。配完发现外网还是打不开。排查到最后才发现,流量虽然进了路由器,但内网群晖回包到路由器后,路由器不知道要把回包重新转回公网——因为我没在 POSTROUTING 里加 MASQUERADE,导致回包源地址是 192.168.1.10,公网客户端根本不认。
这就是回程路由问题。解决办法是在同一台路由器上加一条 SNAT(或 MASQUERADE),把内网服务器的回包源地址也改成公网出口 IP。很多人不理解为什么做了 DNAT 还要配合 SNAT,其实就是因为数据包改了一次地址,回程必须要再改一次,不然两边就无法对应上。记住一句话:NAT 从来不是一个单向动作,它是一进一出的闭环。
3. 全栈视角:两台设备、双机热备与安全设备联动
3.1 双机热备的核心:VIP 漂移、规则同步与连接状态
看完标题里的“防火墙双机热备”“以上方案所用设备均为2套”,我猜不少人是奔着高可用部署来的。Linux 上用 iptables 做双机热备,通常不是靠 iptables 本身,而是靠keepalived(VRRP)在外层做“虚拟 IP 漂移”。原理并不复杂:
- 两台设备配置相同的 iptables 规则,一个当主(MASTER),一个当备(BACKUP)。
- 主备之间通过 VRRP 协议互相探活。
- 主设备挂了,备设备接管虚拟 IP(VIP),流量自动切到备机。
- 硬件只有一套?那你需要的是单机冗余,不在本文讨论里。双机热备的前提就是两套设备再加一个虚拟 IP。
keepalived 的配置骨架大致长这样(这是全局思路,具体参数按你的网段调整):
vrrp_instance VI_1 { state MASTER interface eth0 virtual_router_id 51 priority 100 advert_int 1 virtual_ipaddress { 192.168.100.10 } }重点来了:VRRP 只解决 IP 漂移,不解决规则同步。主备两台机器的 iptables 规则必须自己保持一致。我建议把整套 iptables 规则放到一个 shell 脚本里,用 Git 管理,然后用 Ansible 或简单 cron + scp 同步到两台机器。不要每次手动敲,人总会漏。
还有一个最容易忽略的点:连接状态同步。如果主设备上有一堆已建立的 SSH 会话、数据库长连接,主设备宕机后 VIP 漂到备设备,这些连接在备机上根本不存在。客户端会发现自己明明连着 VIP,却突然卡死。解决思路是使用conntrackd将连接追踪表实时同步到备用节点,这样漂移后已建连接还能维持。不过 conntrackd 配置有些繁琐,生产环境如果对会话保持要求极高,建议直接考虑商业硬件防火墙或云平台的 HA 方案。
3.2 IPS/WAF/防火墙自动切换,链路上到底谁说了算
“各种故障情况下的防火墙 IPS WAF 自动切换原理?”——这个问题背后是一条完整的安全链路。典型的部署顺序是:防火墙(L3/L4)→ IPS(L4/L7 检测)→ WAF(L7 Web 防护)→ 后端业务。它们各管一层,联动才是关键。
自动切换的本质是什么?是健康检查 + 调度策略。跟 iptables 有什么关系?如果你自己搭一套轻量级方案,iptables 就是那个“根据健康检查结果执行切换动作”的执行器。比如你有一个后端服务跑在192.168.1.10,备用节点在192.168.1.11,你可以写一个脚本:
#!/bin/bash # 每 5 秒探测一次主后端 80 端口 if ! curl -m 3 -s http://192.168.1.10/healthz >/dev/null 2>&1; then echo "Primary down. Failover to backup." # 把原本转发到 .10 的规则删掉,改成转发到 .11 iptables -t nat -D PREROUTING -p tcp --dport 80 -j DNAT --to-destination 192.168.1.10:80 iptables -t nat -A PREROUTING -p tcp --dport 80 -j DNAT --to-destination 192.168.1.11:80 iptables -t nat -D FORWARD -d 192.168.1.10 -p tcp --dport 80 -j ACCEPT iptables -t nat -A FORWARD -d 192.168.1.11 -p tcp --dport 80 -j ACCEPT fi这个思路可以跑,但我要泼两盆冷水:
第一,脚本要加“连续失败 N 次才切换 + 切换后自动恢复检测”的阈值逻辑,否则一次瞬时超时就把整个业务切来切去,导致抖动。简单说就是把“单次失败”和“持续失败”区分开。
第二,生产环境不要轻易自己写这种 failover 脚本。专业的负载均衡器(Nginx、HAProxy、云 LB)本身就具备健康检查和故障摘除能力,处理得比手写脚本好得多。iptables 在真正的企业架构里更多时候是“第一道闸门”,而不是“调度核心”。
3.3 防火墙关了会怎样、开着为啥服务还异常?
关于“关闭防火墙有影响吗”——我的态度很明确:除非你在做离线测试或内网隔离实验,否则别关。很多人在云服务器上遇到网络不通,第一反应是systemctl stop firewalld或清空 iptables,一通操作后问题确实“解决”了。但你要明白,你只是把伤口上的绷带撕了,不是把病治好了。攻击面全开之后,迟早会出事。
“防火墙关了还是提示服务异常”这个现象,听起来矛盾,实际上很常见。原因往往不是防火墙本身,而是:
- 服务进程没起来,或监听地址是
127.0.0.1而不是0.0.0.0——本机都连不上的服务,防火墙放行了也没用。 - 安全组 / 网络 ACL 层面拦截,那和本机 iptables 无关,你关 iptables 当然没效果。
- SELinux / AppArmor 拦了端口绑定或文件访问,这种问题在 CentOS 上尤其多。遇到服务异常,先执行
getenforce,如果是 Enforcing,试试临时setenforce 0看看能否恢复,再决定是调整策略还是重新配置。 - 数据库、Redis 类的服务只监听内网网卡,你从外网测试端口不通是预期的,不用慌。
我常跟同事说:防火墙只是网络排查的起点,别把所有锅都甩给它。系统日志journalctl -u 服务名 -e通常比防火墙日志更快告诉你真相。
4. 故障排查与常见问题速查实录
4.1 开启防火墙后 ping 不通,问题出在哪几层?
“开启防火墙后 ping 不通”是出现频率最高的求助,我按排查路径一条条说:
先确认 ICMP 协议有没有放行。iptables 对 ping 的处理和 TCP/UDP 类似,它属于 ICMP 协议。有的默认策略直接把所有 INPUT 都 DROP 了,而你又没加 ICMP 放行规则,自然 ping 不通:
iptables -I INPUT -p icmp --icmp-type echo-request -j ACCEPT注意这里用的是-I(插到前面),不是-A。如果链尾挂着 DROP 兜底,-A加的规则永远轮不到执行。检查顺序时用:
iptables -L INPUT -n --line-numbers每行前面的数字就是规则序号,你一眼就能看出 ACCEPT 规则和 DROP 规则哪个在前。如果 ICMP 放行了还不通,再用tcpdump -i eth0 icmp抓包看请求到底有没有到本机。如果请求压根没到,问题在上游路由、安全组或物理网络,别继续折腾服务器防火墙了。
如果 ping 通了但 TCP 端口不通,那就是应用层的问题偏多。先ss -lntp看端口是否在监听,再确认监听地址是不是0.0.0.0或::。监听在127.0.0.1的话,外网当然进不来,这跟防火墙半毛钱关系没有。
4.2 服务一直报“无法连接 / 异常”,多半是这些规则细节
这类问题可以总结成几句口诀:“放入了没放出,放通了没放过,放过了没放好。”且听我细说。
所谓“放入了没放出”,是指只加了 INPUT 链放行,忘了回包也要放行。比如你在一台默认 OUTPUT DROP 的机器上开放了 Web 服务,外部请求能进来,但服务器回应的 HTTP 响应包在 OUTPUT 链直接被拒了——因为 OUTPUT 默认 DROP,而你没有加ESTABLISHED,RELATED的放行规则。这个场景在安全加固后的机器上非常常见。
“放通了没放过”,指的是 NAT 环境里的 FORWARD 链问题。前面讲的 DNAT 端口映射,外层端口通了、内层 FORWARD 规则没放行,数据包根本进不了内网机器。
“放过了没放好”,就是规则顺序和匹配精度的问题。比如你想封192.168.1.100的访问,把规则加成了-s 192.168.1.0/24,那整个网段都进不来了。这类低级错误,用iptables -L -n -v仔细核对源地址、目的地址、端口就能发现。
排查时还有一个高频体检项:连接跟踪表满了没有。执行sysctl net.netfilter.nf_conntrack_max和conntrack -L | wc -l对比一下。如果连接数顶到上限,新连接会被内核直接丢弃,现象就是“服务时好时坏,过一会儿又没响应”。这时要么调大nf_conntrack_max,要么减少不必要的追踪。实在紧急的时候可以conntrack -F清空表,但你要做好心理准备——所有现有连接全断。
4.3 规则重启即丢、改了不生效,先检查这两件事
用手敲的 iptables 规则是“内存态”的,重启后全部归零。这是设计如此,不是 bug。想让规则持久化,必须手动导出:
# 保存当前规则 iptables-save > /etc/sysconfig/iptables # 或者恢复到文件里的规则 iptables-restore < /etc/sysconfig/iptables上面是 RHEL / CentOS 系的做法。Debian / Ubuntu 系列通常用netfilter-persistent:
netfilter-persistent save netfilter-persistent reload如果在 CentOS 7 及以上用了 firewalld 作为前端管理工具,而你直接写 iptables 规则,两者会发生冲突。firewalld 启动时会重置 iptables 规则,你手敲的在重启后照样没影。要么统一走 firewalld 的富规则,要么把 firewalld 停掉、直接用 iptables-services,别混着来。
“改了不生效”的另一个常见原因是规则顺序。我建议每次添加重要规则前先备份:
iptables-save > /root/iptables-backup-$(date +%F).bak这样改错了还能快速恢复。别看这命令简单,关键时刻能救命。
4.4 常用自查命令与典型问题速查表
把日常排查用到的命令整理成了一份清单,每次出问题我基本按这个顺序过一遍:
| 目的 | 命令 |
|---|---|
| 查看所有 filter 规则及序号 | iptables -L -n --line-numbers |
| 查看 nat 表规则 | iptables -t nat -L -n --line-numbers |
| 查看规则命中计数 | iptables -L -n -v |
| 查看某条链的默认策略 | iptables -S INPUT |
| 查看端口监听状态 | ss -lntp |
| 抓包确认数据包去向 | tcpdump -i eth0 -nn port 80 |
| 查看连接跟踪表 | conntrack -L(或cat /proc/net/nf_conntrack) |
| 实时跟踪防火墙日志 | tail -f /var/log/messages(取决于系统日志配置) |
再给一张我压箱底的“问题-原因-解法”速查表,基本覆盖了 90% 的日常求助:
| 现象 | 常见原因 | 快速处理建议 |
|---|---|---|
| 开启防火墙后 SSH 连不上 | INPUT 默认 DROP,未放行 22 端口 | 通过 VNC/救援模式或云控制台登录,执行iptables -I INPUT -p tcp --dport 22 -j ACCEPT,再保存规则 |
| ping 不通但业务正常 | 默认策略拦截了 ICMP | iptables -I INPUT -p icmp --icmp-type echo-request -j ACCEPT |
| 端口映射后外网访问无效 | 缺 FORWARD 放行或回程 SNAT | 补FORWARD规则,并在POSTROUTING加MASQUERADE |
| 服务时好时坏,大量超时 | 连接跟踪表满了 | 调大nf_conntrack_max或conntrack -F应急 |
| 规则重启后消失 | 未保存持久化 | iptables-save > /etc/sysconfig/iptables |
| 外联被全部掐断 | OUTPUT 默认 DROP 未放行回包 | 确认ESTABLISHED,RELATED放行规则在 OUTPUT 链靠前位置 |
| 安全组 / 公有云端口不通 | 云平台控制台安全组规则限制 | 去云控制台查看入站/出站规则,跟本机 iptables 无关 |
我看到过太多人在“ping 不通”这个最简单的现象上浪费两小时。先看防火墙规则里 ICMP 的状态,再看有没有安全组拦截,然后再去翻路由,顺序不要乱。
最后再分享一个我自己的使用习惯:改规则之前永远先备份一份当前规则,改完之后用iptables-save持久化,再用iptables -L -n -v检查每条规则的命中次数。命中计数是很好的验证手段——规则加了但如果长期是 0,说明它根本没有被走到,通常就是顺序问题。另外,如果你真的只希望某个软件临时不要联网,用owner模块限制它的启动用户是最优雅的路径,但别忘了同时管住 DNS 解析和代理端口,否则程序绕道走 53 端口出网,你的规则就成了摆设。
这行命令看起来简单,背后藏的东西并不少。能把 iptables 用明白,网络层面很多莫名其妙的故障,你都会比别人更快定位。希望这篇内容对你有用。