Linux iptables 深度解析:从规则匹配到 NAT 转发实战
摘要iptables 是 Linux 内核 Netfilter 框架的用户空间管理工具通过五链PREROUTING/INPUT/FORWARD/OUTPUT/POSTROUTING和三表filter/nat/mangle实现包过滤、地址转换与流量控制。本文从 Netfilter 架构出发详解 iptables 规则匹配、NAT 原理、连接追踪、限速防护等核心机制并给出防 SSH 暴力破解、端口转发等实战脚本最后对比 iptables 与 nftables 的差异帮助读者系统掌握 Linux 防火墙底层原理。提到 Linux 防火墙很多人第一反应是ufw或firewalld。但真正在生产环境摸爬滚打过的都知道底层真正干活的是iptables。理解 iptables不仅是掌握一个命令更是理解 Linux 网络栈的流量控制机制。Netfilter 架构iptables 的底层支撑iptables 不是一个独立的防火墙而是 Netfilter 框架的用户空间管理工具。Netfilter 在内核协议栈中植入了 5 个钩子HookPREROUTING → INPUT → [本机进程] → OUTPUT → POSTROUTING ↓ ↑ FORWARD ─────────┘这五个钩子点构成了五链PREROUTING数据包进入网卡后、路由判断前INPUT数据包目标是本机进入前OUTPUT本机发出的数据包路由判断后FORWARD数据包经过本机转发POSTROUTING数据包离开网卡前每个钩子点可以挂载多条规则规则按顺序匹配匹配即执行动作ACCEPT/DROP/REJECT。三表分工filter/nat/mangleiptables 默认三张表各司其职filter 表默认表包过滤控制放行还是丢弃# 拒绝来自 192.168.1.100 的所有连接iptables-AINPUT-s192.168.1.100-jDROP# 只允许 SSH 和 HTTPiptables-AINPUT-ptcp--dport22-jACCEPT iptables-AINPUT-ptcp--dport80-jACCEPT iptables-AINPUT-jDROP# 默认拒绝nat 表网络地址转换控制源地址或目标地址改写# SNAT内网出口伪装MASQUERADE 动态获取出口 IPiptables-tnat-APOSTROUTING-s10.0.0.0/24-oeth0-jMASQUERADE# DNAT端口转发外部访问 8080 转发到内网 192.168.1.50:80iptables-tnat-APREROUTING-ieth0-ptcp--dport8080-jDNAT --to-destination192.168.1.50:80mangle 表修改 IP 头字段TTL/TOS/DSCP用于 QoS 或特殊路由策略# 降低 P2P 流量优先级iptables-tmangle-AFORWARD-ptcp--dport6881:6889-jMARK --set-mark 0x1规则匹配从简单到复杂iptables 的强大在于丰富的匹配条件基础匹配# 协议匹配-ptcp,-pudp,-picmp,-pall# 地址匹配-s192.168.1.0/24# 源地址-d10.0.0.1# 目标地址# 端口匹配需配合 -p tcp/udp--sport1024:65535# 源端口范围--dport80# 目标端口# 网卡匹配-ieth0# 入口网卡INPUT/PREROUTING/FORWARD-oeth1# 出口网卡OUTPUT/POSTROUTING/FORWARD扩展匹配状态检测state模块基于连接追踪conntrack识别连接状态# 只允许已建立连接和相关连接被动模式 FTPiptables-AINPUT-mstate--stateESTABLISHED,RELATED-jACCEPT# 拒绝无效包可能被篡改iptables-AINPUT-mstate--stateINVALID-jDROP四种状态NEW新连接的第一个包ESTABLISHED双向通信已建立RELATED与已有连接相关如 FTP 数据连接、ICMP 错误响应INVALID无法识别状态扩展匹配限速防护limit模块实现令牌桶算法# 限制 SSH 登录尝试每分钟最多 3 次 burst 5iptables-AINPUT-ptcp--dport22-mstate--stateNEW\-mlimit--limit3/minute --limit-burst5-jACCEPT iptables-AINPUT-ptcp--dport22-mstate--stateNEW-jDROP扩展匹配字符串过滤string模块匹配应用层数据# 阻止包含特定关键词的 HTTP 请求iptables-AFORWARD-ptcp--dport80-mstring--stringbadword--algobm-jDROP--algo bm使用 Boyer-Moore 算法比 kmp 快。NAT 原理SNAT vs DNATSNAT源地址转换场景内网机器共享一个公网 IP 上网# 网关服务器配置iptables-tnat-APOSTROUTING-s192.168.0.0/16-oeth0-jSNAT --to-source203.0.113.10# 或者用 MASQUERADE动态 IP 场景如拨号上网iptables-tnat-APOSTROUTING-oppp0-jMASQUERADE工作流程内网机器192.168.1.50发包到公网8.8.8.8经过网关PREROUTING 链记录源地址POSTROUTING 链将源地址改为203.0.113.10回包到达网关查 conntrack 表还原目标地址为192.168.1.50DNAT目标地址转换场景公网访问内网服务# 外网访问网关 80 端口转发到内网 Web 服务器iptables-tnat-APREROUTING-ieth0-ptcp--dport80-jDNAT --to-destination192.168.1.100:8080工作流程外网请求到达网关203.0.113.10:80PREROUTING 链将目标地址改为192.168.1.100:8080回包经过 POSTROUTING源地址改为网关 IPconntrack 确保会话一致性端口转发完整示例需求外网通过网关2222端口 SSH 到内网服务器192.168.1.50:22# DNAT修改目标地址iptables-tnat-APREROUTING-ieth0-ptcp--dport2222-jDNAT --to-destination192.168.1.50:22# FORWARD 链放行iptables-AFORWARD-ptcp-d192.168.1.50--dport22-jACCEPT# 开启 IP 转发echo1/proc/sys/net/ipv4/ip_forward实战防 SSH 暴力破解#!/bin/bash# 防护脚本限制 SSH 登录频率 封禁暴力破解 IP# 清空现有规则iptables-Fiptables-X# 默认策略iptables-PINPUT DROP iptables-PFORWARD DROP iptables-POUTPUT ACCEPT# 允许回环iptables-AINPUT-ilo-jACCEPT# 允许已建立连接iptables-AINPUT-mstate--stateESTABLISHED,RELATED-jACCEPT# SSH 限速每分钟最多 4 次新连接iptables-AINPUT-ptcp--dport22-mstate--stateNEW\-mrecent--nameSSH--setiptables-AINPUT-ptcp--dport22-mstate--stateNEW\-mrecent--nameSSH--rcheck--seconds60--hitcount5-jDROP iptables-AINPUT-ptcp--dport22-jACCEPT# 允许 HTTP/HTTPSiptables-AINPUT-ptcp--dport80-jACCEPT iptables-AINPUT-ptcp--dport443-jACCEPT# 允许 ICMPpingiptables-AINPUT-picmp --icmp-type echo-request-jACCEPTrecent模块记录最近访问的 IP--rcheck --seconds 60 --hitcount 5表示 60 秒内超过 5 次新连接即丢弃。常见陷阱1. 规则顺序iptables 规则按顺序匹配匹配即停止# 错误先放行所有后面的 DROP 永不执行iptables-AINPUT-jACCEPT iptables-AINPUT-s192.168.1.100-jDROP# 正确先拒绝再放行其他iptables-AINPUT-s192.168.1.100-jDROP iptables-AINPUT-jACCEPT2. conntrack 表溢出高并发场景连接追踪表满了会导致丢包# 查看当前连接数cat/proc/sys/net/netfilter/nf_conntrack_count# 查看表大小上限cat/proc/sys/net/netfilter/nf_conntrack_max# 调大上限临时echo262144/proc/sys/net/netfilter/nf_conntrack_max# 永久生效echonet.netfilter.nf_conntrack_max 262144/etc/sysctl.conf3. NAT 后服务器看不到真实 IPDNAT 后内网服务器看到的是网关 IP不是真实客户端 IP# 方案 1HTTP 层面用 X-Forwarded-For需反向代理支持# 方案 2改用透明代理TPROXY但配置复杂4. 规则不持久化重启后规则丢失需要保存# 保存规则Ubuntu/Debianiptables-save/etc/iptables/rules.v4# 恢复规则iptables-restore/etc/iptables/rules.v4# 或者安装 iptables-persistent 包aptinstalliptables-persistentiptables vs nftablesLinux 内核 3.13 引入了 nftables旨在替代 iptables。对比特性iptablesnftables规则语法分散-A/-D/-I统一add/delete性能线性匹配字典/集合 O(1)灵活性固定链/表可自定义向后兼容-iptables-translate 转换新项目建议学习 nftables但生产环境维护的 iptables 规则短期不会消失。总结iptables 难在理解 Netfilter 架构和包流转流程规则语法反而不难。核心记忆五链PREROUTING/INPUT/FORWARD/OUTPUT/POSTROUTING三表filter过滤、nat地址转换、mangle修改 IP 头规则顺序匹配即停止注意顺序连接追踪state 模块是防御利器持久化别忘了保存规则更多 iptables 规则示例和实践案例可以参考 Linux iptables 命令详解。相关工具IP 子网计算器 | 端口检测器