我有一个运行 Linux 的机器人,带有有线和无线适配器。当我启动时,它可以正常连接到无线。当我为有线分配 IP(静态或使用 DHCP)时,它看起来可以正常工作。例如,ifconfig
显示正确的 IP 并route
显示正确的路由。但是,当我对有线 IP 执行 ARP 请求时,ARP 回复包含无线 MAC。
??? 机器人上没有运行桥,那么为什么我无法获取有线 MAC???
当有线断线的时候,有线IP回复ping......
为什么机器人通过无线接口回复有线上的 IP 请求???
编辑:有线和无线适配器都在同一个 IP 子网上。我从同一 IP 子网上的计算机(尝试过不同的计算机)发出 ARP 请求。
相关的 ifconfig 输出:
eth0 Link encap:Ethernet HWaddr 00:01:C0:04:BD:F7
inet addr:192.168.0.110 Bcast:192.168.0.255 Mask:255.255.255.0
UP BROADCAST MULTICAST MTU:1500 Metric:1
RX packets:0 errors:0 dropped:0 overruns:0 frame:0
TX packets:0 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:1000
RX bytes:0 (0.0 B) TX bytes:0 (0.0 B)
ra0 Link encap:Ethernet HWaddr 24:3C:20:06:3E:6D
inet addr:192.168.0.101 Bcast:192.168.0.255 Mask:255.255.255.0
UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1
RX packets:0 errors:59 dropped:0 overruns:0 frame:0
TX packets:0 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:1000
RX bytes:31023598 (29.5 MiB) TX bytes:85640627 (81.6 MiB)
相关路线输出:
Destination Gateway Genmask Flags Metric Ref Use Iface
192.168.0.0 0.0.0.0 255.255.255.0 U 0 0 0 ra0
192.168.0.0 0.0.0.0 255.255.255.0 U 0 0 0 eth0
这是一个非常精简的 Linux,所以我没有像 artptables、iptables、sysctl、brctl 等工具。
编辑:按要求提供图表
编辑:我正在转储流量并查看 ARP 表。192.168.0.110 的 ARP 请求返回包含 24:3C:20:06:3E:6D 的 ARP 回复。ARP 回复数据包的源 MAC 也是 24:3C:20:06:3E:6D。我尝试摆弄 _filter、_ignore 和 _announce,如上所述这里,但无济于事。
编辑:设置网关(在任一接口上)没有区别(因为它不应该)。
编辑:这在以前版本的操作系统(基于 openembedded)上运行良好。他们有可能改变了一些东西吗?
答案1
当您在同一网络上有两个接口时,您看到的是正常行为。这篇 LWN 文章。
答案2
当您说收到错误接口的 ARP 响应时,您实际上是在转储流量还是只是查看生成的 ARP 表?您可能收到的是两个都接口...
无论如何,我相信您的问题的答案在于正确操作rp_filter
和arp_filter
。每个文档都包含在下面。
我建议首先尝试一下这个:
echo 1 > /proc/sys/net/ipv4/conf/all/arp_filter
你可能也需要进行此更改:
echo 0 > /proc/sys/net/ipv4/conf/all/rp_filter
rp_filter - 布尔值 1 - 通过反向路径进行源验证,如 RFC1812 中所述 针对单宿主机和末梢网络的推荐选项 路由器。可能会给复杂的(非无环路)路由器带来麻烦 运行缓慢且不可靠的协议(类似 RIP)的网络, 或使用静态路由。 0 – 无源验证。 conf/all/rp_filter 也必须设置为 TRUE 才能进行源验证 在界面上 默认值为 0。请注意,某些发行版启用了它 在启动脚本中。 arp_filter - 布尔值 1 - 允许您在同一个网络上拥有多个网络接口 子网,并回答每个接口的 ARP 根据内核是否路由来自 该接口的 ARP IP(因此你必须使用源 基于路由的路由)。换句话说,它允许控制 其中哪些卡(通常为 1 个)将响应 arp 请求。 0-(默认)内核可以用地址来响应 arp 请求 从其他界面。这看起来可能不对,但通常 这是有意义的,因为它增加了成功沟通的机会。 IP 地址在 Linux 上属于完整主机,而不是 特定接口。仅适用于更复杂的设置,如加载 平衡,这种行为是否会导致问题。 如果至少有一个 conf/{all,interface}/arp_filter 设置为 TRUE, 否则将被禁用
如需更彻底的治疗,请参阅本文:
答案3
我知道这是一个老问题,但我最近在嵌入式设备上遇到了完全相同的情况。该设备同时具有以太网和 wifi 接口,要求两个接口都可以处于活动状态并随时处于同一网络上,但网络流量必须通过“首选”接口路由。
大多数用户不会以这种方式配置他们的设备,但理论上这是可能的。
我们首先发现 Netgear 路由器存在问题,因为它们会报告 IP 地址冲突 - 2 个 MAC 地址共享一个 IP。显然,在这种情况下,路由器会开始出现问题并扰乱用户网络。
我创建了一个仅包含路由器(以太网 + wifi)、Windows 笔记本电脑(仅以太网)和嵌入式设备(以太网 + wifi)的私有网络。使用设备上的 wireshark、tcpdump 和 Windows 上的 arp,我可以看到以下行为:
- 设备上的 Ifconfig 显示不同的 wln 和以太网 IP 以及不同的 MAC 地址
- 有时(很少见)
arp –a
窗口会显示正确的 IP-MAC 组合。 - 大多数情况下,
arp –a
windows 显示 wln 和 eth0 具有相同的 MAC 地址 - 从 Windows ping wln 或 eth0 时,ping 响应来自 wln,很少来自 eth0。tcpdump 显示 wln 仅响应了 4 次 ping 中的 1 次(例如)
- 当 Windows 针对 eth0 IP 发送 arp“谁有”消息时,eth0 和 wln 接口都会响应说它们有该 IP
我认为第 3 项是由第 5 项引起的。arp 表被搞乱了,因为 wln 正在响应只有 eth0 才应该响应的 arp 消息。我认为第 4 项也是由第 5 项引起的。Ping 是基于 MAC 地址发送的,由于收到的最后一条 arp 消息来自 wln,表示它有 eth0 IP,因此 ping 被错误地路由到 wln 接口。
经过大量挖掘和测试后,解决方案实际上非常简单。请参阅本文 -https://chrisdietri.ch/post/preventing-arp-flux-on-linux/
Linux 内核网络驱动程序的配置方式是,当收到已知接口的 arp 请求时(即使是在另一个接口上收到),它也会响应 arp。
此设置可解决该问题:
echo 1 > /proc/sys/net/ipv4/conf/wln/arp_ignore
echo 1 > /proc/sys/net/ipv4/conf/eth0/arp_ignore
解释:
arp_ignore - INTEGER
Define different modes for sending replies in response to
received ARP requests that resolve local target IP addresses:
0 - (default): reply for any local target IP address, configured
on any interface
1 - reply only if the target IP address is local address
configured on the incoming interface
2 - reply only if the target IP address is local address
configured on the incoming interface and both with the
sender's IP address are part from same subnet on this interface
3 - do not reply for local addresses configured with scope host,
only resolutions for global and link addresses are replied
答案4
跟进 Insyte 的评论。
让我们做一些命名:
- PC1 - 右上
- PC2 - 左上角
- PC3 - 左下
因为您的机器人可以通过有线和无线媒体从 3 台 PC 访问。由于它们位于同一子网中,因此您无法确定有线媒体的 arp 请求是通过哪种方式进行的。我的意思是,当交换机广播 arp 请求时,您的机器人会在两个接口上接收它 [参考您的图表],因此它会在有线媒体上接收 IP 的 arp 请求无线媒体很有可能它回复的是无线媒体的物理地址,因为盒子中确实配置了该 IP
我以前也遇到过这个问题,虽然和你遇到的不完全一样,但很相似。默认情况下,无论 IP 配置在哪个接口上,linux 都会回复它接收 arp 请求的接口的物理地址。因此,在你的情况下,将 PC3 直接连接到机器人的 eth0 接口并对 192.168.0.101 执行 arp 请求,它会回复你 eth0 接口的物理地址,而不是 ra0。
我的部署场景是:
[RTR] |------------eth0---[服务器]
|--------| switch1 |-----eth1-----[服务器]
两个接口都连接到同一个交换机。希望这对您有所帮助。
路由器在其接口上为服务器上两个不同接口上的两个不同网络配置了主 IP 地址和辅助 IP 地址。但在 eth1 上收到针对 eth0 IP 地址的 arp 请求时,它确实回复了 eth1 的物理地址
为了防止这种情况发生,到目前为止,以下方法对我有效
# echo 2 > /proc/sys/net/ipv4/conf/eth0/arp_announce
# echo 1 > /proc/sys/net/ipv4/conf/eth0/arp_ignore
# echo 2 > /proc/sys/net/ipv4/conf/ra0/arp_announce
# echo 1 > /proc/sys/net/ipv4/conf/ra0/arp_ignore
将它放在你的机器人的某个地方,以便你可以在启动时应用它。
建议:我建议您配置两个不同的子网(例如 ra0 上的 192.168.1.x/24 和 eth0 上的 192.168.2.x/24),您可以在 PC 上使用 IP 别名,并且您的机器人可以通过这两个 IP 中的任何一个访问。您不能在同一台主机上的同一子网拥有两条出站路径。除非有某种原因让您的机器人更喜欢一条路径。您的机器人只能采用一条路径将数据包发送出去。
一些阅读材料: arp_anounce 函数, arp_ignore