iptables参考

  1. 参考iptables调试iptables调试
  2. iptables扩展模块扩展模块说明
  3. iptables指南
  4. iptables arch 指南

iptables功能

1. 数据包过滤 (Filter Table)

这是 iptables 最基本也是最常用的功能,用于决定数据包是否允许通过。
功能: 充当防火墙,基于源/目的 IP 地址、端口、协议、网络接口等条件来允许或阻止流量。

链(Chains):

INPUT: 控制目标地址是本机的数据包。
OUTPUT: 控制源地址是本机发出的数据包。
FORWARD: 控制通过本机进行路由转发的数据包(例如,作为路由器时)。

示例:

iptables -A INPUT -p tcp –dport 22 -j ACCEPT:允许进入本机的 SSH 流量。
iptables -A FORWARD -s 192.168.1.0/24 -j REJECT:阻止 192.168.1.x 网段的流量通过本机转发。

2. 网络地址转换 (NAT Table)

NAT 表用于修改数据包的源或目的 IP 地址和端口号,这是实现网络共享和代理转发的关键。

功能:

  • SNAT (Source NAT): 修改数据包的源地址。最常见的用法是互联网连接共享(Masquerading),让局域网内部的私有 IP 能够访问互联网。
  • DNAT (Destination NAT): 修改数据包的目的地址。这是实现端口转发(Port Forwarding)或透明代理的基础。

链(Chains):

PREROUTING: 数据包刚到达时修改目的地址(例如,将外部请求转发给内部服务器)。
POSTROUTING: 数据包即将离开本机时修改源地址(例如,Masquerading)。

示例:

Masquerading (SNAT): iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE:共享 eth0 接口的互联网连接。
端口转发 (DNAT): iptables -t nat -A PREROUTING -p tcp –dport 80 -j DNAT –to-destination 192.168.1.100:80:将 80 端口的请求转发到内部服务器 192.168.1.100。

3.策略路由

演示如何使用 iptables 的 mangle 表来标记特定流量,并利用 Linux 内核的策略路由(Policy Routing)功能,将这些标记过的数据包发送到不同的路由表或通过不同的网络接口。
这个场景常用于:将特定用户(例如 IP 地址为 192.168.1.10)的流量,强制使用另一个默认网关(例如 10.0.0.1)上网。

3.1 示例场景:双网卡/双网关策略路由

我们有两张网卡和两个网关:

  • eth0: 连接主网络,网关 192.168.1.1
  • eth1: 连接备用/VPN 网络,网关 10.0.0.1

目标: 让源 IP 为 192.168.1.10 的设备的所有流量,都走 eth1 网关。

3.2 开启 IP 转发

确保 Linux 系统开启了转发功能:

sudo sysctl net.ipv4.ip_forward=1

3.3 创建一个新的路由表

Linux 内核默认使用 main 路由表。我们需要创建一个名为 alternate 的新路由表(ID 为 100)。
将备用网关 10.0.0.1 的默认路由添加到这个新表中:

# 添加默认路由到备用表
sudo ip route add default via 10.0.0.1 dev eth1 table 100

3.4 使用 iptables mangle 标记数据包

现在,我们使用 iptables 的 mangle 表来识别目标流量(源 IP 为 192.168.1.10 的数据包),并给它们打上一个独特的标记(例如标记 ID 为 1)。
我们使用 MARK 目标和 –set-mark 参数。这个操作发生在数据包刚进入系统时(PREROUTING 链)。

# 规则解释:
# -t mangle      : 使用 mangle 表
# -A PREROUTING  : 添加到 PREROUTING 链
# -s 192.168.1.10: 匹配源 IP 为 192.168.1.10 的数据包
# -j MARK        : 跳转到 MARK 目标
# --set-mark 1   : 给数据包打上标记 1
sudo iptables -t mangle -A PREROUTING -s 192.168.1.10 -j MARK --set-mark 1

3.5 使用 ip rule 将标记与路由表关联

最后一步是使用 ip rule 命令告诉内核:“凡是带有标记 1 的数据包,都不要查阅 main 路由表,而是去查阅我们刚刚创建的 alternate (ID 100) 路由表。”

# 规则解释:
# add        : 添加一条规则
# fwmark 1   : 如果防火墙标记是 1
# lookup 100 : 则去查找路由表 100 (即 alternate 表)
sudo ip rule add fwmark 1 lookup 100

4. iptables的tproxy

TPROXY 是 iptables 中一个非常高级和强大的目标(Target),用于实现完全透明代理,尤其是在处理需要保留原始客户端 IP 地址和原始目标地址的场景中。

4.0 适用场景

TPROXY 是高性能和复杂网络架构的首选方案:

  • 服务网格(Service Mesh): Istio 等服务网格技术广泛使用 TPROXY 将所有进出应用程序的流量透明地重定向到 Sidecar 代理(如 Envoy),以实现流量管理和安全策略,而无需修改应用代码。
  • 高性能负载均衡: 替代传统的 NAT 负载均衡器。
  • 透明防火墙/IDS/IPS: 允许安全设备在不改变网络拓扑的情况下检查流量。

4.1 TPROXY 深入理解

TPROXY 是 Netfilter 框架中的一个目标(Target),属于 mangle 表。其全称是 Transparent Proxy。

  • 核心优势:保留原始信息
  • 传统代理方式(如使用 DNAT/REDIRECT)会修改数据包的目的地址和端口。当数据包到达代理服务器时,代理服务器只知道自己被请求了,需要额外的机制才能知道客户端最初想访问谁。TPROXY 解决了这个问题:
  • 它不修改 IP 头部的源/目的地址或端口。
  • 它使用策略路由将数据包“拦截”到本地代理端口,同时保持数据包“原封不动”。
  • 代理服务器可以在不解密、不修改数据包的情况下,看到原始客户端的 IP 地址和原始的目标服务器地址。这对于日志记录、身份验证和应用层的决策至关重要。

4.2 ptables 规则 (使用 mangle 表)

这是触发透明代理的起点。TPROXY 只能用于 PREROUTING 或 OUTPUT 链。

# 示例:拦截目标端口为 80 和 443 的 TCP 流量
sudo iptables -t mangle -A PREROUTING -p tcp -m multiport --dports 80,443 \
    -j TPROXY --on-port 8080 --tproxy-mark 0x1/0x1

–on-port 8080:指定本地代理程序监听的端口。
–tproxy-mark 0x1/0x1:给数据包打上一个标记(Mark 1),这个标记在策略路由中至关重要。

4.3 策略路由 (ip rule 和 ip route)

这是 TPROXY 的魔术所在。它告诉内核带有标记 1 的数据包不要走常规的路由查找,而是走我们指定的特殊路径。

# 1. 创建一个新的路由表,命名为 TPROXY_TABLE (ID 100)
echo 100 TPROXY_TABLE | sudo tee -a /etc/iproute2/rt_tables

# 2. 为 TPROXY_TABLE 添加路由规则:本地流量都使用回环接口 lo
#    'local' 路由类型确保内核将这些包视为目标是本地的包,从而发送给本地应用
sudo ip route add local default dev lo table 100

# 3. 添加 IP 规则:所有带有防火墙标记 1 的包都去查阅 TPROXY_TABLE
sudo ip rule add fwmark 1 lookup 100

4.4 代理程序支持 (IP_TRANSPARENT 套接字选项)

标准的代理程序无法处理 TPROXY 流量,因为数据包的目的 IP 不是代理程序本身的 IP。代理软件必须在绑定端口时设置 IP_TRANSPARENT 套接字选项。
支持 TPROXY 的程序示例: HAProxy, Envoy (Istio 的核心代理), Nginx (使用特定补丁或模块), Squid (较新版本)。
非透明代理程序(例如 Nginx 标准版、Tinyproxy)无法直接接收 TPROXY 流量。

特性 DNAT (通常使用 REDIRECT) TPROXY
Iptables 表 nat mangle
修改目的 IP? 是(修改为代理服务器 IP) 否(保持原始目标 IP)
代理程序看到的目的 IP 代理服务器自己的 IP 原始目标服务器的 IP
原始信息保留 差(需额外机制获取原始目标) 好(天然保留原始源/目的 IP)
支持的协议 TCP 为主,UDP 较复杂 TCP 和 UDP 都支持
代理程序要求 标准程序即可(如 Apache, Nginx) 需要支持 IP_TRANSPARENT 特性

常用命令

自定义链

# 创建dnat
iptables -t nat -A PREROUTING -p tcp --dport 10000 -j DNAT --to-destination 192.168.0.5:443

# 删除dnat 将-A换成-D
iptables -t nat -D PREROUTING -p tcp --dport 10000 -j DNAT --to-destination 192.168.0.5:443

# 创建自定义链
iptables -t nat -N IN_WEB
# 重命名自定义链
iptables -E IN_WEB WEB
# 添加规则到自定义链
iptables -t nat -A WEB -p tcp --dport 80 -j DNAT --to-destination 192.168.0.5:443
# 引用自定义链
iptables -t nat -A PREROUTING -p tcp --dport 80 -j WEB
# 清空自定义链
iptables -t nat  -F WEB
# 删除自定义链应用
iptables -t nat -D PREROUTING -p tcp --dport 80 -j WEB
# 删除自定义链
iptables -t nat -X WEB

允许连接本机443,22。 允许本机访问39.100.90.231。允许本机访问dns 服务。

iptables -A INPUT -i lo -j ACCEPT; \
iptables -A OUTPUT -o lo -j ACCEPT; \
iptables -A OUTPUT   -m state --state ESTABLISHED,RELATED  -j ACCEPT;\
iptables -A INPUT   -m state --state ESTABLISHED,RELATED -j ACCEPT;\
iptables -A INPUT -p tcp --dport 443 -j ACCEPT; \
iptables -A INPUT -p tcp --dport 22 -j ACCEPT; \
iptables -A OUTPUT  -p udp  --dport 53 -j ACCEPT; \
iptables -A OUTPUT -d 39.100.90.231 -j ACCEPT; \
iptables -P INPUT DROP; \
iptables -P OUTPUT DROP; \
iptables -P FORWARD DROP

清空链恢复默认

iptables -P INPUT ACCEPT; \
iptables -P OUTPUT ACCEPT; \
iptables -P FORWARD ACCEPT; \
iptables -F&&iptables -X&&iptables -Z