iptables防火墙实战指南:从四表五链到规则集维护

发布时间:2026/11/2 12:11:11
iptables防火墙实战指南:从四表五链到规则集维护 防火墙这东西刚接触运维那会儿我总觉得它离我很远直到有天凌晨两点被业务告警叫醒——一台对外服务的机器被人扫端口扫到飞起日志里全是各种畸形包。那次之后我才老老实实把 iptables 从头啃了一遍。这篇就聊聊 iptables 防火墙这套东西它本质上是什么、能干什么、适合谁来啃。简单说iptables 是 Linux 内核里 netfilter 框架的用户态配置工具负责数据包的过滤、转发、地址转换和端口映射。它解决的问题很直接谁能进、谁能出、谁能穿过我这台机器。适合谁看刚上手 Linux 运维的朋友、需要给服务器做基础加固的后端开发、以及想搞明白为什么我的服务明明起来了却连不上的排查型选手。下面这些内容都是我这些年踩坑踩出来的不是照本宣科念手册。1. 先搞清楚 iptables 到底在管什么1.1 四表五链不是背出来的是理解出来的很多人一上来就被四表五链劝退其实你把它想成一个快递分拣中心就通了。数据包就是包裹链就是分拣流水线上的几个检查站表就是不同职责的检查员。包裹从进站到出站会依次经过不同的检查站每个站点的检查员只关心自己那摊事。filter 表是最常用的负责放行还是丢弃绝大多数防火墙规则说的就是它。nat 表管地址转换做端口映射、内网共享上网靠它。mangle 表改数据包的一些标记字段普通场景基本用不上但做策略路由、打连接标记时会用到。raw 表优先级最高用来在连接跟踪之前做处理一般只在特殊需求下碰。链这块记住数据包的走向比死记名字有用得多。一个从外部进来、发给本机的包走的是PREROUTING → INPUT本机发出去的包走OUTPUT → POSTROUTING而需要转发的包走PREROUTING → FORWARD → POSTROUTING。这个流向图在脑子里过一遍后面写规则时该往哪条链上挂自然就清楚了。提示新手最容易犯的错是把本该挂 FORWARD 的规则挂到 INPUT 上结果转发流量死活不通。先判断这个包是给本机的还是路过的再决定链。1.2 规则匹配的顺序逻辑决定了你的规则怎么写iptables 的规则是从上往下逐条匹配命中即停。这个特性决定了规则顺序极其重要。你把一条 DROP 规则放在 ACCEPT 前面那后面的 ACCEPT 就永远轮不上了。我见过有人把拒绝所有写在最上面然后下面写了一堆放行规则结果全废——因为第一个包就被拒了根本走不到下面。所以写规则的基本心法是具体的、范围小的放前面宽泛的、兜底的放后面。比如先放行已建立的连接再放行特定端口最后才是默认策略。这个顺序不是随便定的是匹配机制逼出来的。另外要理解状态匹配conntrack。加了-m state --state ESTABLISHED,RELATED的规则能让已经建立的连接的回包自动放行不用为每个方向都写规则。这是让规则集保持精简的关键技巧后面实操部分会详细展开。1.3 默认策略那道最后的闸门每条链都有一个默认策略policy当所有规则都没匹配上时就按这个策略处理。常见做法是把 INPUT 和 FORWARD 的默认策略设成 DROPOUTPUT 设成 ACCEPT。为什么因为进来的和路过的流量风险更高出去的一般是自家程序发起的限制太死反而容易把自己坑了。但这里有个大坑你在远程连着的机器上千万别在规则没配好之前就把默认策略改成 DROP。一旦改完发现自己把自己关在门外那就只能去机房或者走带外管理了。正确姿势是先写好放行规则尤其是放行你当前 SSH 端口和已建立连接确认无误最后再动默认策略。这个顺序我强调一百遍都不嫌多。2. 规则写法与核心参数拆解2.1 一条规则由哪些部分组成一条完整的 iptables 规则拆开看就是几个要素哪张表、哪条链、匹配什么条件、匹配后做什么动作。举个最常见的例子iptables -t filter -A INPUT -p tcp --dport 22 -j ACCEPT逐段读-t filter指定表不写默认就是 filter-A INPUT表示追加到 INPUT 链末尾-p tcp匹配协议--dport 22匹配目标端口-j ACCEPT是动作放行。这一条的意思就是允许外部访问本机的 22 端口。动作target常用的就几个ACCEPT放行、DROP静默丢弃不给对方任何回应、REJECT拒绝并回一个错误包、LOG记日志但不影响后续匹配、SNAT/DNAT做地址转换。DROP 和 REJECT 的区别值得说一下DROP 是对外装死扫描器会觉得这个端口没开REJECT 会明确告诉对方此路不通。做安全加固时我更倾向 DROP减少信息暴露。2.2 常用匹配条件速查匹配条件是规则的筛子筛得越准规则越安全。下面这张表是我平时写规则时脑子里过的清单匹配维度参数写法典型用途协议-p tcp/udp/icmp区分 TCP、UDP、ICMP源地址-s 192.168.1.0/24限制来源网段目标地址-d 10.0.0.5限定目标源端口--sport 1024:65535匹配高端口来源目标端口--dport 80放行具体服务入接口-i eth0限定从哪块网卡进出接口-o eth1限定从哪块网卡出连接状态-m state --state NEW/ESTABLISHED/RELATED状态跟踪多端口-m multiport --dports 80,443,8080一次匹配多个端口限速-m limit --limit 10/min防暴力破解、防日志刷屏端口范围用冒号表示比如--dport 1000:2000表示 1000 到 2000 这个区间。多端口匹配用 multiport 模块比写多条规则清爽得多性能上也更友好。2.3 状态匹配为什么是规则集的心脏如果只能记住一个进阶技巧那就是状态匹配。没有它你得为每个服务写进和出两条规则规则集臃肿且容易漏。有了它一条ESTABLISHED,RELATED就能兜住所有已建立连接的回包。iptables -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT这条规则的含义是只要是已建立连接的一部分或者是与之相关的连接比如 FTP 的数据连接、ICMP 的错误回包一律放行。它通常放在 INPUT 链靠前的位置作为老朋友免检通道。这样你只需要为 NEW 状态的新连接写放行规则规则数量能砍掉一大半。注意状态匹配依赖内核的 conntrack 模块连接跟踪表有容量上限。高并发场景下要关注nf_conntrack_max这个值表满了会导致新连接被丢表现为服务时好时坏。这个坑我在压测时踩过排查了半天才发现是连接跟踪表爆了。3. 从零搭一套可用的防火墙规则3.1 动手前的准备与清场正式写规则前先看看现状。iptables -L -n -v列出当前所有规则-n不解析域名快-v显示包计数能看出哪条规则在生效。如果机器上已经有别的防火墙管理工具在跑先确认它们不会互相打架否则你改的规则可能被覆盖。清场用iptables -F清空所有链的规则iptables -X删除自定义链。但清场前务必确认你有带外管理手段或者本地终端在手别在纯远程会话里一把梭。我一般会先开一个screen或tmux会话再操作万一断线规则还在不至于失联。3.2 一套最小可用规则集的完整落地下面这套规则是我给一台普通对外服务器做基础加固时常用的模板逻辑清晰、够用、不易把自己锁死。按顺序执行# 1. 清空现有规则和自定义链 iptables -F iptables -X # 2. 放行本地回环这条永远第一条 iptables -A INPUT -i lo -j ACCEPT iptables -A OUTPUT -o lo -j ACCEPT # 3. 放行已建立连接和相关连接 iptables -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT # 4. 放行 ICMPping按需可关 iptables -A INPUT -p icmp --icmp-type echo-request -j ACCEPT # 5. 放行 SSH建议限定来源网段 iptables -A INPUT -p tcp --dport 22 -s 203.0.113.0/24 -j ACCEPT # 6. 放行 Web 服务 iptables -A INPUT -p tcp -m multiport --dports 80,443 -j ACCEPT # 7. 设置默认策略最后做 iptables -P INPUT DROP iptables -P FORWARD DROP iptables -P OUTPUT ACCEPT这套规则读下来逻辑是回环必通 → 老朋友免检 → 必要服务放行 → 其余全拒。第 5 步限定来源网段是个好习惯SSH 暴露在公网被爆破是常态能限来源就限。如果 SSH 端口改过记得把 22 换成实际端口。执行完立刻验证另开一个终端测试 SSH 能否连上、Web 端口是否可达、ping 是否通。验证这一步绝对不能省规则写错导致服务不可达是家常便饭。确认无误后再考虑持久化。3.3 规则持久化重启不丢才是真落地iptables 的规则默认存在内存里重启就没了。持久化方式因发行版而异常见的有iptables-save配合iptables-restore或者用iptables-persistent这类工具。核心思路就一句把当前规则导出成文件开机时再导回去。# 导出当前规则 iptables-save /etc/iptables/rules.v4 # 开机恢复可写入启动脚本或对应服务的配置 iptables-restore /etc/iptables/rules.v4我习惯在每次改完规则、验证通过后立刻iptables-save一次形成改-测-存的肌肉记忆。有次改完规则忘了存第二天机器重启加固全白做那种感觉相当酸爽。4. 实战排查那些让人抓狂的典型问题4.1 服务起来了却连不上先怀疑防火墙这是最高频的场景。服务进程在跑、端口在监听ss -tlnp能看到但外部就是连不上。排查顺序我总结成一条链先看本机能不能连自己curl 127.0.0.1:端口能连说明服务没问题再看防火墙规则有没有放行这个端口iptables -L -n逐条看最后看云厂商的安全组如果是在云上。这三层任何一层没放行表现都是连不上。有个细节容易被忽略规则里的-i入接口写错了。比如机器有多块网卡规则限定了-i eth0但流量实际从eth1进来那规则永远匹配不上。排查时用iptables -L -n -v看规则的包计数如果某条本该命中的规则计数一直是 0八成是匹配条件写错了。4.2 常见问题速查表现象可能原因排查与解决改完规则 SSH 断了默认策略先于放行规则生效带外恢复重来一遍注意顺序转发流量不通规则挂错链或未开 ip_forward检查 FORWARD 链确认net.ipv4.ip_forward1服务时好时坏conntrack 表满调大nf_conntrack_max观察表使用率规则不生效被其他管理工具覆盖检查是否有别的防火墙服务在跑端口映射不工作nat 表规则链挂错DNAT 挂 PREROUTINGSNAT 挂 POSTROUTING日志刷屏拖垮磁盘LOG 规则无限速加-m limit限速4.3 几个我踩过的坑和私房技巧坑一DROP 和 REJECT 混用导致排查困难。早期我图省事全用 REJECT结果对外服务被扫描时回了一堆拒绝包反而暴露了端口存在。后来统一改成 DROP扫描器扫过去一片无响应信息暴露少了很多。但内部排查时又希望有明确反馈所以我的做法是对外 DROP对内网调试临时用 REJECT 并配合 LOG。坑二LOG 规则放错位置。LOG 是记录但不拦截匹配到 LOG 后会继续往下走。所以 LOG 规则要放在对应 DROP 规则的前面才能记录到被拒的包。放后面就永远轮不到。而且 LOG 一定要限速-m limit --limit 5/min是标配否则被扫时日志能把磁盘写满。技巧用注释给规则打标签。-m comment --comment allow-ssh-from-office能给规则加备注iptables -L时能直接看到。规则一多没注释的规则集就是天书过俩月自己都看不懂当初为啥这么写。技巧改规则前先备份。iptables-save backup.rules出问题一条iptables-restore backup.rules回滚。这个习惯救过我无数次尤其是批量改规则的时候。5. 进阶场景NAT 与端口转发5.1 SNAT 与 DNAT 的区别与选择NAT 这块SNAT 改的是源地址典型场景是内网机器共享一个公网出口上网DNAT 改的是目标地址典型场景是把公网请求转发到内网某台机器。两者方向相反挂的链也不同DNAT 在 PREROUTING包刚进来就改目标SNAT 在 POSTROUTING包要出去时改源。做端口转发比如把公网 8080 转到内网 80用的是 DNAT# 开启转发 sysctl -w net.ipv4.ip_forward1 # 公网 8080 转到内网 10.0.0.5 的 80 iptables -t nat -A PREROUTING -p tcp --dport 8080 -j DNAT --to-destination 10.0.0.5:80 # 放行转发流量 iptables -A FORWARD -p tcp -d 10.0.0.5 --dport 80 -j ACCEPT这里有个高频遗漏点只写了 DNAT 规则忘了放行 FORWARD 链。DNAT 只改了目标地址包还是要经过 FORWARD 链的过滤FORWARD 默认 DROP 的话转发照样不通。这个坑几乎每个做端口转发的人都踩过。5.2 内网共享上网的 SNAT 配置内网机器通过一台网关机上网网关机上配 SNATiptables -t nat -A POSTROUTING -s 192.168.1.0/24 -o eth0 -j MASQUERADEMASQUERADE是 SNAT 的一种特殊形式会自动把源地址改成出口网卡的地址适合出口 IP 不固定的场景比如拨号。如果出口 IP 固定用-j SNAT --to-source 公网IP性能更好因为不用每次查网卡地址。同样别忘了ip_forward和 FORWARD 链放行。提示做 NAT 的机器net.ipv4.ip_forward必须为 1否则内核根本不转发包规则写得再对也没用。这个参数是 NAT 和转发类场景的总开关。6. 规则集维护与性能意识6.1 规则顺序影响性能别不当回事iptables 是逐条匹配的规则越多每个包要过的关卡越多。一台高流量机器上堆几百条规则性能损耗是实打实的。优化思路有两条一是把命中率高的规则往前放比如 ESTABLISHED 那条让大部分包尽早命中二是合并同类规则用 multiport、ipset 这类工具减少规则条数。ipset 是个好东西把大量 IP 或网段存成一个集合规则里引用集合名匹配效率比逐条写高得多。比如要封禁几千个恶意 IP用 ipset 一条规则搞定而不是写几千条。这个在防大规模扫描、做黑名单时特别有用。6.2 定期审计规则集规则集是会腐烂的。临时加的调试规则、过期的放行、没人记得用途的条目时间一长就堆成垃圾场。我习惯每隔一段时间做一次审计iptables -L -n -v看每条规则的包计数计数长期为 0 的规则要么删掉要么查清楚为什么没命中对照业务梳理哪些端口还需要开放把注释补全。审计时特别关注那些范围过大的规则比如-s 0.0.0.0/0全放行某端口确认是不是真的需要全网开放。很多安全事故的根源就是一条图省事写下的宽泛规则。6.3 关于这套东西的定位iptables 这套工具能力很强但它的规则语法确实不算友好维护复杂规则集时容易出错。现在也有 nftables 这类新一代工具在逐步替代它语法更清晰、性能更好。但 iptables 的存量极大大量现网机器还在用理解它的表链模型和匹配逻辑对看懂任何一代 Linux 防火墙都有帮助——因为底层的 netfilter 框架是共通的换的只是上层配置工具。我个人在实际操作中的体会是iptables 的难点从来不在语法而在想清楚数据包该走哪条链、规则该按什么顺序排。把这两件事想明白了剩下的就是查参数。每次改规则前问自己三个问题——这个包是给谁的、它走哪条链、我的规则会不会误伤自己能避开绝大多数坑。最后再分享一个小习惯任何一次规则变更先在测试机或者用tmux会话里演练一遍验证通过再上生产这个习惯比任何技巧都值钱。

关于本文作者

来自尧图内容编辑团队

尧图内容编辑团队 内容团队

尧图内容编辑团队

本文由尧图网络内容编辑团队执笔。团队由资深项目经理、前端工程师与设计师组成,所有内容均来自亲手交付的真实项目,先讲清问题、再给出可落地的解法。尧图深耕北京网站建设十年,服务过京华建材集团、智造科技等各行业客户,把一线经验沉淀为可复用的行业观察。

  • 十年建站经验,覆盖建材、制造、服务、文创等
  • 项目经理把关选题与事实准确性
  • 工程师与设计师联合撰写专业细节
  • 统一编辑规范,保证文风与排版一致
  • 每月复盘转化数据,迭代选题方向

延伸阅读

相关资讯与近期热门内容

深度阅读推荐

建站决策前值得细读的三篇

网站改版的5个关键决策
2024-08-12

网站改版的5个关键决策

什么时候该改版、改到什么程度、如何避免流量掉光,京华建材集团改版复盘给出答案。

获取专属建站方案

看完文章,把您的行业与预算告诉我们,免费获取一份量身定制的官网建设方案与报价。

立即免费咨询