我有一台带有两个 ISP 连接的服务器(ubuntu/debian)。这两个 WAN 连接都有多个公共 IP 地址。
(big pipe)----eth0-->\
> server ---eth2--(internal)
(cable pipe)--eth1-->/
在 eth0 上,我被分配了 4 个 IP,它们是更宽泛的 /24 子网的一部分。24.xxx.xxx.xxx/24 在 eth1 上,我被分配了 5 个 IP,但在这里我是唯一一个在 /29 上的 IP(第 6 个 IP 是我命中的网关)71.xxx.xxx.xxx/29
我的目标是设置基于源/策略的路由,以便各个内部子网上的虚拟机/客户端(eth2 上有多个实际的 VLAN)可以通过任何指定的 WAN IP 路由到互联网。
以下是我目前所做的事情。
首先,我在接口文件中配置了 eth0 和 eth1。
auto eth0
iface eth0 inet static
address 24.xxx.xxx.66
netmask 255.255.255.0
network 24.xxx.xxx.0
broadcast 24.xxx.xxx.255
gateway 24.xxx.xxx.1
dns-nameservers 8.8.8.8
up /etc/network/rt_scripts/i_eth0
auto eth1
iface eth1 inet static
address 71.xxx.xxx.107
netmask 255.255.255.248
network 71.xxx.xxx.105
broadcast 71.xxx.xxx.111
up /etc/network/rt_scripts/i_eth1
然后 BigPipe 上的 macvlan 设备
#!/bin/sh
#iface BigPipe67
ip link add mac0 link eth0 address xx:xx:xx:xx:xx:3c type macvlan
ip link set mac0 up
ip address add 24.xxx.xxx.67/24 dev mac0
#iface BigPipe135
ip link add mac1 link eth0 address xx:xx:xx:xx:xx:3d type macvlan
ip link set mac1 up
ip address add 24.xxx.xxx.135/24 dev mac1
#iface BigPipe136
ip link add mac2 link eth0 address xx:xx:xx:xx:xx:3e type macvlan
ip link set mac2 up
ip address add 24.xxx.xxx.136/24 dev mac2
/etc/network/rt_scripts/t_frontdesk
/etc/network/rt_scripts/t_pubwifi
/etc/network/rt_scripts/t_mail1
/etc/network/rt_scripts/t_scansrvc
CBL 连接。缺失的第 5 个 IP(71.xxx.xxx.106)是位于建筑物内的另一个路由器。
#!/bin/sh
ip route add xxx.xxx.xxx.xxx/20 via 71.xxx.xxx.105 dev eth1
ip route add xxx.xxx.xxx.xxx/20 via 71.xxx.xxx.105 dev eth1
#iface CBL108
ip link add mac3 link eth1 address xx:xx:xx:xx:xx:c5 type macvlan
ip link set mac3 up
ip address add 71.xxx.xxx.108/29 dev mac3
#iface CBL109
ip link add mac4 link eth1 address xx:xx:xx:xx:xx:c6 type macvlan
ip link set mac4 up
ip address add 71.xxx.xxx.109/29 dev mac4
#iface CBL110
ip link add mac5 link eth1 address xx:xx:xx:xx:xx:c7 type macvlan
ip link set mac5 up
ip address add 71.xxx.xxx.110/29 dev mac5
/etc/network/rt_scripts/t_jenkins4
/etc/network/rt_scripts/t_skynet
/etc/network/rt_scripts/t_lappy386
您会注意到,当我在 eth1 上设置 macvlan 接口时,主表上指定了几个路由。我在与主服务器相同的电缆提供商上还有几个其他路由器。它们通过 VPN 返回主服务器,而 BigPipe 用于其他所有操作(在主表上)。
“t_”脚本用于为使用 macvlan 接口设置的 IP 的各种服务/客户端设置单独的规则和表。
简化后,它们看起来有点像这样。
#!/bin/sh
ip rule add from 172.23.1.6 table scansrvc
ip route add default via 24.xxx.xxx.1 dev mac0 table scansrvc
ip route add 24.xxx.xxx.0/24 dev mac0 table scansrvc
ip route add 172.23.0.0/20 dev br1 table scansrvc
综上所述,作为快速回顾,我让主服务器使用 8 个公共 IP(BigPipe 上有 4 个,CBL 上有 4 个)。其中一个 BigPipe IP 和其中一个 CBL IP 用于 VPN 服务,有效地创建了一个“贫民区互联网交换”。该路由配置存在于主表中。
然后剩下的 6 个 IP 由各种服务或客户端使用,这些表是 frontdesk、pubwifi、mail1、scansrvc、jenkins4、skynet 和 lappy386。
我将所有公共 IP 伪装成各个内部子网。
这让我很惊讶...一切都很顺利,直到它不顺利。这意味着,当我启动服务器时,一切都设置正确,我能够看到路由策略正在做它们应该做的事情。
因此,在 scansrvc 上,它是主服务器上的一个虚拟机,但具有内部 IP(172.23.1.6/20)
waffle@scansrvc:~$ dig +short myip.opendns.com @resolver1.opendns.com
24.xxx.xxx.67
但是,过了一段时间,数据包就无法返回主服务器后面的虚拟机了。我可以在 iptables 防火墙统计数据中看到,它们离开了我的网络,但无法返回。
当它工作时,我从外部扫描,我可以看到服务端口,但是它死机后,iptables 甚至也看不到数据包进入。
此外,通过搜索,我开始阅读有关火星数据包的信息。所以我通过 sysctl 启用了这些数据包的日志记录。哇。我从 BigPipe 记录了大量火星数据包,但没有从 CBL 记录任何数据包,也许是因为 BigPipe 我不是该子网上唯一的一个?
以下是片段
Nov 22 08:59:03 srv3 kernel: [ 271.747016] net_ratelimit: 497 callbacks suppressed
Nov 22 08:59:03 srv3 kernel: [ 271.747027] IPv4: martian source 24.xxx.xxx.43 from 24.xxx.xxx.1, on dev mac0
Nov 22 08:59:03 srv3 kernel: [ 271.747035] ll header: 00000000: ff ff ff ff ff ff cc 4e 24 9c 1d 00 08 06 .......N$.....
Nov 22 08:59:03 srv3 kernel: [ 271.747046] IPv4: martian source 24.xxx.xxx.43 from 24.xxx.xxx.1, on dev mac2
Nov 22 08:59:03 srv3 kernel: [ 271.747052] ll header: 00000000: ff ff ff ff ff ff cc 4e 24 9c 1d 00 08 06 .......N$.....
Nov 22 08:59:03 srv3 kernel: [ 271.747061] IPv4: martian source 24.xxx.xxx.43 from 24.xxx.xxx.1, on dev mac1
Nov 22 08:59:03 srv3 kernel: [ 271.747066] ll header: 00000000: ff ff ff ff ff ff cc 4e 24 9c 1d 00 08 06 .......N$.....
Nov 22 08:59:03 srv3 kernel: [ 271.796429] IPv4: martian source 24.xxx.xxx.211 from 24.xxx.xxx.1, on dev mac0
Nov 22 08:59:03 srv3 kernel: [ 271.796440] ll header: 00000000: ff ff ff ff ff ff cc 4e 24 9c 1d 00 08 06 .......N$.....
Nov 22 08:59:03 srv3 kernel: [ 271.796450] IPv4: martian source 24.xxx.xxx.211 from 24.xxx.xxx.1, on dev mac2
根据我目前对火星人的了解,我的假设是,在同一个子网上有多个接口可能会导致不适用于某个接口的数据包被发送到该接口......不知何故......(我认为,由于它们有不同的 MAC 地址,这种情况会得到缓解)
是什么原因造成的?为什么当我刚启动系统和 VMS 时,设置会一直运行,直到一段时间后突然死机?(例如,如果我让 scansrvc VM 上的 8.8.8.8 保持 ping 运行,我会在死机前收到 100-1000 个响应)这可能是 ARP 缓存的问题吗?我并没有在运行过程中将任何 IP 重新分配给不同的 MAC 地址。
我陷入了困境。我将开始学习一些 tcpdump 技能,尝试阐明我可能遗漏的一些内容。如果有谁更精通网络设置,可以指出我遗漏的任何内容,那将非常有帮助!:)
答案1
错误消息是由数据包来源验证引起的(请参阅内核代码)。
我可以假设,您设置的主路由表中只有一条直连重叠子网的路由。当您通过其他接口(不是通过主路由表中的接口)收到来自直连子网的数据包时,该数据包被识别为 martian。
如何排除故障:
- 使用“ip route get 24.xxx.xxx.1”命令查找此数据包源的路由,并将路由的接口与数据包到达的接口进行比较。它们可能不同。
如何解决问题:
- 如果您使用具有多个路由表的 PBR,请将通过相应接口的直连路由添加到每个路由表中。也许您应该重新制定 PBR 规则以避免路由不匹配。
- 检查 rp_filter 并禁用它,或者最好将其切换到松散模式(参见sysctl 变量)
- 丢弃 macvlan 接口并使用接口上的多个地址(这是困难的,但我认为在思想上更正确)。
答案2
感谢 Anton 的见解!我非常感谢这些链接。
发帖记录:
我最终按照建议在所有接口 (net.ipv4.conf.all.rp_filter) 上将 rp_filter 设置为松散模式,我发现使用自己的路由表的客户端立即表现得符合预期。但是,使用主表的路由将不再与 eth0 上的 24.xxx.xxx.0/24 之外进行通信,即使设置了默认路由也是如此。使用 .default 而不是 .all 以及在 .default 上启用 arp_filter(我敢发誓我之前已经启用了它)产生了所需的结果,包括消除火星人。
.default 与 .all 对我来说很特别,我必须仔细研究才能更清楚地理解。我很高兴它能正常工作!
我最初选择 macvlan 是因为我认为内核处理虚拟接口的方式。我熟悉的在单个接口上设置多个 IP 的方式是虚拟的,即在接口文件中声明 eth0:0。启动一个完全独立的接口让我可以更轻松地使用 iproute2。但是,也许有一种更简洁的方式,我很想知道。
再次感谢您的帮助!