我有一个有趣的问题,希望有人能帮忙解决。我正在尝试在 2 个路由器(运行 Linux Ubuntu 12.04)之间创建 GRE 隧道,并通过此隧道在 2 个子网之间传递流量。
我想要实现的目标可以通过以下设置来简化,想象 4 台计算机(如下图所示),2 台是路由器,2 台是连接到网关的个人电脑……
|----------------------| |----------------------|
SUBA--+--ETH0 ETH1--+----------- --+--ETH0 ETH1--+--SUBB
|----------------------| |----------------------|
PC1 as router PC2 as router
现在,如果图表看起来不对,让我解释一下。我有 2 台 PC 配置为路由器 ( ip_forwarding=1, proxy_arp=1
)。每台作为路由器的 PC 都有 2 个接口,每个接口都有自己的 IP。
图表左侧(PC1 作为路由器)
SUBA=192.165.13.25
- PC1 上的 ETH0 作为路由器
=192.165.13.254
(SUBA 的网关) - PC1 上的 ETH1 作为路由器
= 192.168.6.40
(地址由服务提供商提供) -> 这是 PC1 作为路由器的默认网关。
图表右侧(PC2 作为路由器)
SUBB=192.160.20.25
- PC2 上的 ETH0 作为路由器
=192.168.20.41
(地址由服务提供商提供) - PC2 上的 ETH1 作为路由器
=192.160.20.254
(SUBB 的网关)
两端的路由都非常简单,可以用文字描述。
在作为路由器的 PC1 上:
- 要访问 192.165.13.0/24,请使用 eth0
- 要访问 192.168.6.0/24,请使用 eth1
- 默认网关是 192.168.6.40 => 这是 eth1
在作为路由器的 PC2 上:
- 要访问 192.160.20.0/24,请使用 eth1
- 要访问 192.168.20.0/24,请使用 eth0
- 默认网关是 192.168.20.41 => 这是 eth0
在此设置中,无需任何额外的 IPTABLES 规则,每个人都可以 ping 每个人。我很好。SUBA 可以 ping SUBB,反之亦然。
现在我在 PC1 作为路由器 eth1 和 PC2 作为路由器 eth0 隧道之间创建一个 GRE 隧道,PC1 上的路由器具有带有本地 =192.168.6.40
和远程 =的 GRE 隧道,当然,我在另一台路由器上具有对称性,PC2 上的隧道与路由器具有带有本地 =和远程 = 的192.168.20.41
GRE 隧道...192.168.20.41
192.168.6.40
我修改了 PC2 上的路由(添加一条规则)作为路由器,只是为了强制流量进入隧道:访问192.165.13.0/24
使用 GRE 隧道。
没做其他事。
现在 SUBB 正在尝试 ping SUBA,但没有成功,尝试 ping SUBA 的 GW(即作为路由器的 PC1 的第二个接口)也没有成功
以下是我使用 wireshark 或 tcpdump 看到的结果:
- 流量进入 PC2 上的隧道接口作为路由器
- 流量从 PC1 上的隧道接口流出,作为路由器
- 作为路由器,流量永远不会到达 PC1 的 eth0 接口。
因此我深入挖掘并在 IP 表中添加了几条规则来查看发生了什么:
每个 ping 请求都计入:
mangle prerouting
nat prerouting
但是 ping 不计入 mangle 转发(如果尝试转发到 SUBA)或 mangle 输入。似乎内核在路由中默默地丢弃了数据包,我不知道为什么。在我看来,我不应该修改 iptables,因为在创建 GRE 表之前我不需要这样做……
如果您能提供任何关于可能发生的情况、如何让内核报告数据包或丢弃数据包的原因的帮助,我们将不胜感激。