- iptables参考
- iptables功能
- 1. 数据包过滤 (Filter Table)
- 链(Chains):
- 示例:
- 2. 网络地址转换 (NAT Table)
- 功能:
- 链(Chains):
- 示例:
- 3.策略路由
- 3.1 示例场景:双网卡/双网关策略路由
- 3.2 开启 IP 转发
- 3.3 创建一个新的路由表
- 3.4 使用 iptables mangle 标记数据包
- 3.5 使用 ip rule 将标记与路由表关联
- 4. iptables的tproxy
- 4.0 适用场景
- 4.1 TPROXY 深入理解
- 4.2 ptables 规则 (使用 mangle 表)
- 4.3 策略路由 (ip rule 和 ip route)
- 4.4 代理程序支持 (IP_TRANSPARENT 套接字选项)
- 常用命令
- 自定义链
iptables参考
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