根本原因是Linux内核默认arp_ignore=0,导致任意网卡响应本机所有IP的ARP请求;必须设为1(仅响应本接口主IP)或2(响应本接口所有IP),并按网卡单独配置arp_ignore与arp_announce=2,再清理ARP缓存。

在多网卡同网段环境下,ARP响应冲突的根本原因是Linux内核默认允许任意网卡响应本机所有IP的ARP请求。这会导致交换机ARP表反复刷新、流量误发、连接抖动甚至中断。解决的关键不是禁用ARP,而是让每块网卡“只认自己名下的IP”。
为什么必须设 arp_ignore=1 或 2
默认值 arp_ignore=0 表示:只要目标IP属于本机(不管配在哪个接口),收到ARP请求的任意网卡都会应答。比如 eth0 配了 192.168.1.10,eth1 配了 192.168.1.11,当外部主机问“谁是 .11?”,eth0 也会抢答——结果交换机把 .11 的流量发到 eth0,但 eth0 并不处理该IP,包就被丢弃。
设为 1:仅当ARP请求进来的接口上,目标IP是其主IP(ip addr show dev eth0 中 inet 行无 secondary 标记的)才响应;
设为 2:只要目标IP配置在该接口(含 ip addr add ... label 添加的 secondary IP)就响应。
生产环境推荐用 1,更严格;只有明确用了 secondary IP 且需响应时,才考虑 2。
按网卡单独配置,不能只改 all
必须针对每块实际使用的网卡逐个设置,路径是 /proc/sys/net/ipv4/conf/网卡名/arp_ignore。写成 conf/all/arp_ignore 是全局兜底,但会被单接口设置覆盖——而你真正要约束的是具体网卡行为。
- 临时生效(重启失效):
echo 1 > /proc/sys/net/ipv4/conf/eth0/arp_ignoreecho 1 > /proc/sys/net/ipv4/conf/eth1/arp_ignore - 永久生效:在
/etc/sysctl.conf或/etc/sysctl.d/99-arp-fix.conf中添加net.ipv4.conf.eth0.arp_ignore = 1net.ipv4.conf.eth1.arp_ignore = 1
然后运行sysctl -p - 验证是否生效:
sysctl net.ipv4.conf.eth0.arp_ignore应返回1
arp_ignore 必须搭配 arp_announce=2
只限制响应还不够。当本机主动发包(如 ping 网关),内核可能从错误网卡发出ARP请求,导致源IP和出口网卡不匹配,引发非对称路由——中间防火墙或策略路由设备可能直接丢弃返回流量。
arp_announce=2 的作用是:发送ARP请求时,优先选择与目标IP最匹配的本地地址所在的接口。例如,eth0 上有 192.168.1.10,访问 192.168.1.1 时,就只会从 eth0 发ARP,不会错误地走 eth1。
- 同步设置(临时):
echo 2 > /proc/sys/net/ipv4/conf/eth0/arp_announceecho 2 > /proc/sys/net/ipv4/conf/eth1/arp_announce - 永久配置追加到 sysctl 文件:
net.ipv4.conf.eth0.arp_announce = 2net.ipv4.conf.eth1.arp_announce = 2
配置后还需验证和清理残留
参数生效后,并不自动清除已错乱的ARP缓存。外部设备(包括网关、交换机、其他主机)仍可能保留旧的错误映射。
- 在本机清空本地ARP表:
ip neigh flush all(比arp -d -a更彻底,覆盖IPv4/IPv6邻居表) - 在交换机或网关上手动清除对应条目(如 Cisco 的
clear arp-cache,华为的reset arp) - 用
tcpdump -i eth0 -nn arp抓包观察:现在只有目标IP属于 eth0 时,eth0 才会回复 “Reply”;eth1 收到问 .10 的请求,应完全静默


















