tools

iptables 完整详解

·12 分钟阅读·4552 字
📋 目录

iptables 完整详解

核心概念 iptables 是 Linux 用户态命令行工具,基于内核 netfilter 子系统的 5 个钩子点位实现数据包过滤、NAT 和转发。

1. 底层基础:Netfilter 框架

iptables 只是用户态命令行工具,真正处理数据包的是 Linux 内核 netfilter 子系统。
netfilter 在数据包进出内核协议栈时预埋了 5 个钩子点位(hook),数据包经过对应点位时匹配规则、执行放行/丢弃/NAT。

1.1. 五大钩子(处理顺序固定)

  1. PREROUTING:数据包刚进入网卡,还未做路由判断
    用途:DNAT、目的地址转换
  2. INPUT:路由判定目标是本机进程(访问本机端口)
    用途:本机防火墙拦截、放行ssh/80端口
  3. FORWARD:路由判定需要跨网卡转发(容器、网关、LVS流量)
    用途:跨机器/容器转发流量过滤
  4. OUTPUT:本机程序向外发出的数据包
    用途:本机出站管控、本地DNAT
  5. POSTROUTING:数据包即将离开网卡
    用途:SNAT、源地址伪装

2. 四大表(优先级从高到低)

表是规则集合,数据包按 raw → mangle → nat → filter 顺序依次匹配每张表。

2.1. raw(最高优先级)

作用:标记数据包是否跳过连接跟踪 conntrack,极少业务使用。
内置链:PREROUTING、OUTPUT

2.2. mangle

作用:修改数据包内容(TTL、DSCP流量标记、QoS),做流量优先级。
全五钩子都存在该表链:PREROUTING/INPUT/FORWARD/OUTPUT/POSTROUTING

2.3. nat(地址转换专用,只处理新建连接首包)

仅对连接第一个包生效,已建立连接不再重复匹配nat规则。

  • PREROUTING:DNAT 目的端口转发(docker -p端口映射、端口代理)
  • OUTPUT:本机出站DNAT
  • POSTROUTING:SNAT/MASQUERADE 源地址转换(容器访问外网)

2.4. filter(默认表,最常用,包过滤)

管控流量放行/拒绝,安全策略全部写在此表。
内置三条核心链:

  • INPUT:外部访问本机
  • FORWARD:跨主机转发流量
  • OUTPUT:本机对外访问

3. 链、表、钩子三者关系

  1. 表 = 规则分类;链 = 绑定在某个钩子上的一组规则;
  2. 每条规则绑定 表.链,数据包过钩子时遍历该链所有规则;
  3. 匹配规则从上到下顺序执行,匹配成功执行动作,不再往下匹配。

4. 规则匹配动作 target(-j 参数)

  1. ACCEPT:放行数据包,继续传输
  2. DROP:直接丢弃,不返回任何响应,客户端超时(隐蔽,公网推荐)
  3. REJECT:丢弃并返回ICMP拒绝包,客户端立刻提示连接失败,内网调试用
  4. SNAT:固定公网出口IP源地址转换
  5. MASQUERADE:动态源地址伪装(宽带、云主机出口IP不固定)
  6. DNAT:目的IP/端口转发
  7. LOG:打印日志到 /var/log/messages,不中断流量,仅记录
  8. RETURN:跳出当前链,回到上层链继续匹配

5. 连接跟踪 conntrack(配套核心模块)

内核跟踪所有 TCP/UDP 连接状态,规则可按状态批量放行响应包,不用双向配置端口。
四种连接状态:

  1. NEW:新建连接第一个包
  2. ESTABLISHED:正常双向传输的连接
  3. RELATED:关联附属连接(FTP被动端口、ICMP错误响应)
  4. INVALID:非法畸形数据包

标准通用放行规则(所有服务器必配):

# 放行所有已建立、关联连接的响应包
iptables -A INPUT -m state --state RELATED,ESTABLISHED -j ACCEPT

5.1. conntrack 常见故障

连接数打满上限 nf_conntrack_max,新建TCP连接直接丢弃,业务大量超时;
调优内核参数:

net.netfilter.nf_conntrack_max = 1048576
net.netfilter.nf_conntrack_tcp_timeout_time_wait = 30

查看当前连接总数:

cat /proc/sys/net/netfilter/nf_conntrack_count

6. 完整命令语法

iptables [-t 表名] 操作命令 [匹配条件] -j 动作

6.1. 常用操作命令

  1. -L -n --line-numbers:列出规则、数字端口、显示行号
  2. -A 链:追加规则到链末尾
  3. -I 链 序号:插入规则到指定行,优先匹配
  4. -D 链 序号:删除指定行规则
  5. -F [链]:清空链所有规则
  6. -P 链 动作:设置链默认策略(DROP/ACCEPT)

6.2. 常用匹配条件

  1. -p tcp/udp/icmp 指定协议
  2. --dport 80 目标端口;--sport 22 源端口
  3. -s 192.168.1.0/24 源网段;-d x.x.x.x 目标地址
  4. -i eth0 入网卡;-o eth1 出网卡
  5. -m state --state xxx 连接状态匹配
  6. -m iprange --src-range 10.0.0.1-10.0.0.100 IP区间
  7. -m multiport --dports 80,443,8080 多端口批量匹配

7. 标准生产配置示例

7.1. 示例1:本机基础防火墙(filter INPUT)

# 清空原有规则
iptables -F
iptables -t nat -F

# 放行本地回环lo,本机进程互通必备
iptables -A INPUT -i lo -j ACCEPT

# 放行响应流量
iptables -A INPUT -m state --state RELATED,ESTABLISHED -j ACCEPT

# 放行内网网段访问22、80、443
iptables -A INPUT -s 192.168.0.0/16 -p tcp --dport 22 -j ACCEPT
iptables -A INPUT -p tcp --dport 80 -j ACCEPT
iptables -A INPUT -p tcp --dport 443 -j ACCEPT

# 默认拒绝所有入站流量
iptables -P INPUT DROP
# FORWARD默认拒绝(无网关转发需求)
iptables -P FORWARD DROP
# OUTPUT全部放行,本机随便对外访问
iptables -P OUTPUT ACCEPT

7.2. 示例2:容器SNAT外网访问(nat POSTROUTING)

容器网段 10.244.0.0/16,访问外网自动伪装宿主机IP

iptables -t nat -A POSTROUTING -s 10.244.0.0/16 -j MASQUERADE

7.3. 示例3:端口转发 DNAT(宿主机9000转发到容器10.244.1.10:80)

iptables -t nat -A PREROUTING -p tcp --dport 9000 -j DNAT --to-destination 10.244.1.10:80
# 配套放行转发流量
iptables -A FORWARD -d 10.244.1.10 -p tcp --dport 80 -j ACCEPT

8. 规则持久化(重启失效问题)

iptables规则内存生效,服务器重启丢失,分系统保存:

  1. CentOS7+/RHEL:
# 保存
service iptables save
# 加载
service iptables reload
  1. Ubuntu/Debian:
# 导出规则到文件
iptables-save > /etc/iptables/rules.v4
# 开机加载
iptables-restore < /etc/iptables/rules.v4

9. 核心缺陷(生产大规模痛点)

  1. 线性链表匹配 O(n) 性能灾难
    每条数据包从头到尾遍历整条链所有规则;K8s上千Service会生成上万条规则,CPU软中断%soft飙升,延迟增大。
  2. 强依赖 nf_conntrack,高并发短连接极易打满连接跟踪表丢包。
  3. 无原生集合,批量黑白名单需要配合 ipset 优化,配置繁琐。
  4. 仅四层,无法解析HTTP域名、URL、Cookie,七层分流能力缺失。
  5. 新一代系统底层默认 nftables,iptables逐步被淘汰。

10. iptables vs nftables 简单区分

  1. iptables:四表五链,线性规则,语法繁琐,老旧兼容;
  2. nftables:统一框架,无多表区分,内置set集合,树形匹配性能更好,RHEL9、Debian11默认底层。

11. 容器/K8s场景底层依赖

  1. Docker -p 端口映射 = nat表 PREROUTING DNAT;
  2. 容器访问外网自动添加 POSTROUTING MASQUERADE;
  3. kube-proxy iptables模式:每个Service生成多条DNAT规则,集群规模变大性能暴跌;
  4. Calico/旧版NetworkPolicy:转换大量filter表FORWARD拦截规则,拉高软中断;
  5. 替代方案:IPVS(优化Service转发性能)、eBPF Cilium(完全脱离iptables)。

12. 高频排查命令

# 完整查看规则,数字端口+行号
iptables -L -n --line-numbers

# 只看nat表
iptables -t nat -L -n

# 删除第3行INPUT规则
iptables -D INPUT 3

# 追踪数据包匹配流程(调试必备)
iptables -t raw -A PREROUTING -p tcp --dport 80 -j LOG --log-prefix "IN_80:"

13. 面试速记核心总结

  1. 底层基于netfilter,五大钩子PREROUTING/INPUT/FORWARD/OUTPUT/POSTROUTING;
  2. 四表优先级 raw > mangle > nat > filter,filter负责防火墙,nat负责端口映射SNAT/DNAT;
  3. conntrack连接跟踪区分NEW/ESTABLISHED/RELATED,简化双向放行规则;
  4. 数据包线性遍历规则,大规模集群上万规则会造成性能瓶颈;
  5. Docker、K8s早期kube-proxy、Calico网络策略均依赖iptables;
  6. 核心动作:ACCEPT放行、DROP静默丢弃、REJECT主动拒绝、DNAT端口转发、MASQUERADE源地址伪装;
  7. 规则存内存,重启丢失,需iptables-save持久化保存。

关联文档