[原]一个有关arp_ignore 的实验

    用户报障,说在一台安装了Asianux 3.0 的机器上测试网络时,发现拔掉某网卡的网线后,该网卡上的IP 地址仍可继续ping 通,怀疑硬件或系统配置有问题。经查证,这实际上是因为核心中arp_ignore 参数的默认设置导致的。月初时,我才写了一篇有关arp_ignore 与arp_announce 参数的设置的文章,这次为了更清晰的说明问题,特模拟一个实验。

一、实验环境
实验环境很简单,两台机器,设置如下:

引用
A机:Asianux 3.0 双网卡,并设定两个同网段的IP地址:
eth0:192.168.228.161
eth1:192.168.228.162
B机:Windows 平台,作为测试客户端,IP是192.168.228.221

※ 经测试,若两台机器都是Linux 平台,不会发生下面的情况。
下面是A 机上的IP 和MAC 地址配置信息:

引用
# ifconfig|grep -A1 eth
eth0      Link encap:Ethernet  HWaddr 00:11:5B:D1:0E:F8
          inet addr:192.168.228.161  Bcast:192.168.228.255  Mask:255.255.255.0

eth1      Link encap:Ethernet  HWaddr 00:F0:BF:70:00:EE
          inet addr:192.168.228.162  Bcast:192.168.228.255  Mask:255.255.255.0

二、默认参数下的测试情况
首先,我们在保持系统默认参数的环境下进行测试。
1、清空B 机的arp 表缓存信息
Win 7 使用下面的命令清空arp 缓存:

arp -d *

2、从B机分别ping A机上的两个IP 地址

引用
C:\Users\linuxing>ping -n 1 192.168.228.161
正在 Ping 192.168.228.161 具有 32 字节的数据:
来自 192.168.228.161 的回复: 字节=32 时间<1ms TTL=64
C:\Users\linuxing>ping -n 1 192.168.228.162
正在 Ping 192.168.228.162 具有 32 字节的数据:
来自 192.168.228.162 的回复: 字节=32 时间<1ms TTL=64

此时的arp 表如下(忽略其他IP地址的MAC信息,下同):

引用
C:\Users\linuxing>arp -a
接口: 192.168.228.221 — 0xc
  Internet 地址         物理地址              类型
  192.168.228.161       00-11-5b-d1-0e-f8     动态
  192.168.228.162       00-f0-bf-70-00-ee     动态

3、测试
ping A机上的192.168.228.162,同时,禁用eth1网卡,B机显示的结果如下:

引用
C:\Users\linuxing>ping 192.168.228.162 -t

正在 Ping 192.168.228.162 具有 32 字节的数据:
来自 192.168.228.162 的回复: 字节=32 时间<1ms TTL=64
来自 192.168.228.162 的回复: 字节=32 时间<1ms TTL=64
请求超时。
来自 192.168.228.162 的回复: 字节=32 时间<1ms TTL=64
来自 192.168.228.162 的回复: 字节=32 时间<1ms TTL=64192.168.228.162 的 Ping 统计信息:
    数据包: 已发送 = 11,已接收 = 10,丢失 = 1 (9% 丢失),
往返行程的估计时间(以毫秒为单位):
    最短 = 0ms,最长 = 0ms,平均 = 0ms
Control-C
^C

※ A机上用ifconfig eth1 down 禁用网卡,或拔去eth1的网线。
再看看B机的arp 表:

引用
C:\Users\linuxing>arp -a
接口: 192.168.228.221 — 0xc
  Internet 地址         物理地址              类型
  192.168.228.161       00-11-5b-d1-0e-f8     动态
  192.168.228.162       00-11-5b-d1-0e-f8     动态

可见,A机上的两块网卡的IP地址都指向了同一个MAC 地址(即eth0)。在ping 的过程中虽然发生过短暂的中断,但恢复后,IP 与MAC 的指向就改变了。后面再ping 162的地址,都是成功的(因为eth0 是连接的),成功模拟用户提到的问题。

三、解决问题
产生该问题的主要原因是,Linux 核心中的一个arp_ignore 参数,该参数默认值为0。即对ARP请求时,只要该IP在本地的机器任意网卡设备上存在都会响应。详细可参考下面的文档:

引用
/usr/share/doc/kernel-doc-2.6.18/Documentation/networking/ip-sysctl.txt

或有关arp_ignore 与arp_announce 参数的设置一文。
正如这些资料中提到的,如果把arp_ignore 设置为1时,当别人的arp请求过来的时候,如果接收的设备上面没有这个ip,就不响应。
我们在A 机上进行该操作:

# echo 1 > /proc/sys/net/ipv4/conf/eth0/arp_ignore

若同时在B 机上测试,会有如下的结果:

引用
C:\Users\linuxing>ping 192.168.228.162 -t
正在 Ping 192.168.228.162 具有 32 字节的数据:

来自 192.168.228.162 的回复: 字节=32 时间<1ms TTL=64
来自 192.168.228.162 的回复: 字节=32 时间<1ms TTL=64
来自 192.168.228.221 的回复: 无法访问目标主机。
来自 192.168.228.221 的回复: 无法访问目标主机。

这说明,A机的eth0设备不再响应对192.168.228.162 的请求,因此,无法连通。此时,B机上该IP的arp 缓存也会被删掉。问题解决。

四、备注
1、对那个网卡设定
由于arp 上的缓存信息与交换机有很大的关系,因此,获取IP 对应的MAC 地址顺序不同,可能arp 缓存的结果也不一样。例如,B 机上初始的状态可能是这样的:

引用
C:\Users\linuxing>arp -a
接口: 192.168.228.221 — 0xc
  Internet 地址         物理地址              类型
  192.168.228.161       00-f0-bf-70-00-ee     动态
  192.168.228.162       00-f0-bf-70-00-ee     动态

这时,你设置eth0上的arp_ignore将没什么作用,需设置eth1的参数。所以,考虑到随机性,为避免该参数的影响,应在所有端口上配置该参数,这可写入/etc/sysctl.conf 文件中。

2、客户端的影响
不单Windows 客户端有影响,Linux 客户端同样也会出现,例如,下面的arp 缓存表:

引用
# arp -a
? (192.168.228.161) at 00:11:5B:D1:0E:F8 [ether] on eth0
? (192.168.228.162) at 00:11:5B:D1:0E:F8 [ether] on eth0

当我们ping 161,同时禁用eth0,就会变成:

引用
# arp -a
? (192.168.228.161) at 00:F0:BF:70:00:EE [ether] on eth0
? (192.168.228.162) at 00:F0:BF:70:00:EE [ether] on eth0

但Linux 上arp 的缓存时间较短,出现的几率少点。

3、Linux 上如何清空arp 缓存信息
Linux 的arp -d 不支持通配符,需用下面的方式执行,才能清空arp 缓存信息:

for HOST in `arp | sed '/Address/d' | awk '{ print $1}'` ; do arp -d $HOST; done

4、如何避免
除了调整上面提到的arp_ignore参数外,在日常的系统配置中,我们也应该尽量避免在同一台机器,不同网卡上配置相同网段的IP地址。特殊情况下,如LVS 环境、链路有环路等,这需考虑arp_ignore 与arp_announce 的参数。

有关arp_ignore 与arp_announce 参数的设置

Tags: arp

原创文章,作者:ItWorker,如若转载,请注明出处:https://blog.ytso.com/104183.html

(0)
上一篇 2021年8月25日
下一篇 2021年8月25日

相关推荐

发表回复

登录后才能评论