本文基于《Linux 策略路由与 NAT 转发指南》的通用技术,聚焦于 GRE 隧道场景。
一、背景
1.1 基本参数
1.2 前置条件
✅ GRE 隧道已建立(参考《GRE 隧道配置》)
✅ A 侧路由已配置(指定哪些流量走隧道)
1.3 本文目标
A 的流量到达 B 后,B 需要根据目标地址做出不同处理:
二、B 侧 NAT 转发配置
以下命令均已在通用指南中详细解释,此处只给具体参数。
放行 FORWARD 回包:
# 查看 FORWARD 当前默认策略
iptables -L FORWARD | head -1
# 若为 Chain FORWARD (policy DROP), 需显式放行回包
iptables -A FORWARD -m state --state ESTABLISHED,RELATED -j ACCEPT2.1 A 访问 B 所在 VPC 内网
目标:A 访问 192.168.0.0/20 的流量到达 B 后,B 将其转发到内网。
# 放行 FORWARD(放行 A 的请求包(二选一))
# 仅内网转发
iptables -A FORWARD -d 192.168.0.0/20 -j ACCEPT
# 内网+公网转发(推荐)
iptables -A FORWARD -s 172.18.0.0/20 -j ACCEPT验证:
# 在 A 上执行
ping 192.168.0.1
curl http://192.168.0.100:802.2 A 通过 B 访问公网
目标:A 访问公网的流量到达 B 后,B 做 MASQUERADE,将源 IP 改为 B 的公网 IP,访问互联网。
# 放行 FORWARD(放行 A 的请求包)
iptables -A FORWARD -s 172.18.0.0/20 -j ACCEPT
# 做 MASQUERADE
iptables -t nat -A POSTROUTING -s 172.18.0.0/20 -j MASQUERADE验证:
# 在 A 上执行(数据包从 tun1 出去,并且协议是 IPv4)
curl -4 --interface tun1 http://www.baidu.com2.3 端口转发
将来自 A 访问 B 特定端口的流量,转发到 B 本机的其他端口或内网其他服务器。
详细配置方法请参考《Linux 策略路由与 NAT 转发完全指南》DNAT / REDIRECT 章节。
三、抓包验证
3.1 内网转发抓包
隧道入口(B 侧):
tcpdump -i tun1 -nn src 172.18.0.0/20 and dst 192.168.0.0/20预期输出:
172.18.0.6 > 192.168.0.1: ICMP echo request
172.18.0.6 > 192.168.0.100.80: Flags [S]3.2 公网转发抓包
隧道入口(B 侧):
tcpdump -i tun1 -nn src 172.18.0.0/20公网出口(B 侧):
# 183.2.172.177 是不指定 host 抓包看到的百度 IP
tcpdump -i eth0 -nn host 183.2.172.177
# GRE 封装抓包
tcpdump -i eth0 -nn 'ip proto 47'
tcpdump -i eth0 -nn proto gre预取输出:tun1 能看到 A 的请求(源 IP 172.18.0.6),eth0 能看到 MASQUERADE 后的包(源 IP 变为 B 的公网 IP)。
3.3 连接跟踪验证(验证 NAT)
# 在 B 上执行
conntrack -L | grep 172.18.0.6输出解读:
[ASSURED]:双向通信正常 -> ✅ NAT 生效
[UNREPLIED]:只有请求无回包 -> ❌ 检查 FORWARD 或路由
无记录:包没到 B 或没出 B -> ❌ 检查 FORWARD 是否放行
四、排障专题
通用排障方法(FORWARD 放行、rp_filter、云环境特殊配置等)请参考《Linux 策略路由与 NAT 转发指南》排障章节。
附:OpenWrt 配置说明
若在 OpenWrt 22.03+(fw4/nftables)上配置,请参考《Linux 策略路由与 NAT 转发指南》的 OpenWrt 配置章节。
简要步骤:
1. 创建 GRE 隧道所属的防火墙区域(zone)
2. 放行转发规则(gre_zone → lan)
3. 配置 NAT(MASQUERADE)