用户报障,说在一台安装了Asianux 3.0 的机器上测试网络时,发现拔掉某网卡的网线后,该网卡上的IP 地址仍可继续ping 通,怀疑硬件或系统配置有问题。经查证,这实际上是因为核心中arp_ignore 参数的默认设置导致的。月初时,我才写了一篇的文章,这次为了更清晰的说明问题,特模拟一个实验。
一、实验环境实验环境很简单,两台机器,设置如下:
引用
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=64
192.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 设置为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 的参数。
服务器为RHEL5
双网卡,eth0
为234
,eth1
为233
,我本地客户机为172
。
RHEL
: ifconfig
如下:
[root@server1 ~]# ifconfig
eth0
Link encap:Ethernet
HWaddr
00:0C:29:A55:A3
inet addr:
60.232.83.233
Bcast:60.232.83.255
Mask:255.255.255.128
略。。。。。。。
eth1
Link encap:Ethernet
HWaddr
00:0C:29:A55:AD
inet addr:
60.232.83.234
Bcast:60.232.83.255
Mask:255.255.255.128
略。。。。。。。。。
lo
Link encap:Local Loopback
inet addr:127.0.0.1
Mask:255.0.0.0
略。。。。。。。。。
在客户机XP
上ping
两个地址,都是通的。
C:\ >ping 60.232.83.233
Pinging 60.232.83.233 with 32 bytes ofdata:
Reply from 60.232.83.233: bytes=32 time=9msTTL=64
Reply from 60.232.83.233: bytes=32time<1ms TTL=64
C:\ >ping 60.232.83.234
Pinging 60.232.83.234 with 32 bytes ofdata:
Reply from 60.232.83.234: bytes=32time<1ms TTL=64
Reply from 60.232.83.234: bytes=32time<1ms TTL=64
此时用arp –a
在本地查看
C:\ >arp -a
Interface: 60.232.83.172 --- 0x20005
Internet Address
PhysicalAddress
Type
60.232.83.129
00-04-96-1a-ca-60
dynamic
60.232.83.233
00-0c-29-a5-d5-a3
dynamic
60.232.83.234
00-0c-29-a5-d5-a3
dynamic
发现两个网卡的MAC
地址一样,也就是eth0
的mac
地址。
现在我们[root@server1 ~]# ifconfig eth1 down
来禁止eth1
,结果ping 233
和234
的地址都是通的。
这里可以这样理解,arp –a
看到本地解析到得两块网卡mac
地址是一样的,局域网是通过2
层寻址的不可能涉及到ip
这样的3
层协议,因此mac
地址相同ping
哪个都应该是通的,但是为什么本地会出现不同的IP
相同的mac
地址呢?在Linux
上看到的明明是不同的MAC
地址00:0C:29:A55:A3,00:0C:29:A55:AD
继续测试,现在把eth0
禁止。
[root@server1 ~]# ifconfig eth0 down
[root@server1 ~]# ifconfig
eth1
Link encap:Ethernet
HWaddr00:0C:29:A5
5:AD
inet addr:60.232.83.234
Bcast:60.232.83.255
Mask:255.255.255.128
inet6 addr: fe80::20c:29ff:fea5:d5ad/64 Scope:Link
略。。。。。
lo
Link encap:Local Loopback
inet addr:127.0.0.1
Mask:255.0.0.0
inet6 addr: ::1/128 Scope:Host
略。。。。
本地先arp –d
清除一下缓存。然后再ping
两块网卡的IP
地址,依然可以ping
通两个地址。
Arp –a
后发现:
C:\>arp -a
Interface: 60.232.83.172 --- 0x20005
Internet Address
Physical Address
Type
60.232.83.129
00-04-96-1a-ca-60
dynamic
60.232.83.233
00-0c-29-a5-d5-ad
dynamic
60.232.83.234
00-0c-29-a5-d5-ad
dynamic
Mac
地址成为另一块也就是eth1
的mac
地址。
然后开启eth0
,然后再ping
测试一下。结果如下:
C:\>arp -a
Interface: 60.232.83.172 --- 0x20005
Internet Address
PhysicalAddress
Type
60.232.83.129
00-04-96-1a-ca-60
dynamic
60.232.83.233
00-0c-29-a5-d5-a3
dynamic
60.232.83.234
00-0c-29-a5-d5-ad
dynamic
这才是一张正常的地址表。
这时候再关闭eth0
,结果就ping
不通了,因为这时候缓存里的233
的mac
地址已经关闭。
Arp –d
之后就可以ping
通了,此时eth0
依然处于关闭状态,只是清楚了一下缓存表,这样再起ping233
地址,可以ping
通了,得出的结果是234
的mac
地址。
C:\>arp -a
Interface: 60.232.83.172 --- 0x20005
Internet Address
PhysicalAddress
Type
60.232.83.129
00-04-96-1a-ca-60
dynamic
60.232.83.233
00-0c-29-a5-d5-ad
dynamic
60.232.83.234
00-0c-29-a5-d5-ad
dynamic
此时开启eth0
,现在本地缓存中的两个IP
依然对应的还是234
的mac
地址。Arp –d
清除一下,这次先ping 234
再ping 233
,结果两个都是233
的既eth0
的mac
地址。
实验做到这里脑子有点乱,把这台Linux
服务器换成Windows Server 2003
,就没有这问题出现。
C:\Documents andSettings\Administrator>ipconfig /all
Windows IP Configuration
Host Name . . . . . . . . . . . . : newxyz-yz5l2clv
Primary Dns Suffix
. . . . . . .:
Node Type . . . . . . . . . . . . : Unknown
IPRouting Enabled. . . . . . . . : No
WINS Proxy Enabled. . . . . . . . : No
Ethernet adapter
本地连接 3:
Connection-specific DNS Suffix
.:
Description . . . . . . . . . . . : VMware Accelerated AMD PCNet Adapter#2
Physical Address. . . . . . . . . :
00-0C-29-68-03-AF
DHCP Enabled. . . . . . . . . . . : No
IPAddress. . . . . . . . . . . . :
60.232.83.251
Subnet Mask . . . . . . . . . . . : 255.255.255.128
Default Gateway . . . . . . . . . :
Ethernet adapter
本地连接 2:
Connection-specific DNS Suffix
.:
Description . . . . . . . . . . . : VMware Accelerated AMD PCNet Adapter
Physical Address. . . . . . . . . :
00-0C-29-68-03-A5
DHCP Enabled. . . . . . . . . . . : No
IPAddress. . . . . . . . . . . . :
60.232.83.250
Subnet Mask . . . . . . . . . . . : 255.255.255.128
Default Gateway . . . . . . . . . :
本地ping
两块网卡之后显示如下:
C:\Documents andSettings\Administrator>arp -a
Interface: 60.232.83.198 --- 0x10005
Internet Address
PhysicalAddress
Type
60.232.83.129
00-04-96-1a-ca-60
dynamic
60.232.83.250
00-0c-29-68-03-a5
dynamic
60.232.83.251
00-0c-29-68-03-af
dynamic
关闭任何一个网卡都是无法ping
的。
所以在Linux
下网卡可能采用一些机制,比如说,首先,问题属于双网卡同一网段linux
系统网卡自动路由的问题。
2
、如果系统有两个独立网卡,并且这两个网卡的IP
属于同一个子网,那么后面这个网卡的IP
将自动路由到前面一个网卡上。
也就是说数据将自动路由到前面的那个网卡上。在不加任何设置的情况下,如果前面的网卡断线或者故障了(
拔掉网线或者网卡指坏了)
,必须用命令down
调后面的网卡然后再up
,这时后面的网卡才能启用。此时两个IP
又同时路由到后面的网卡上,也就是说后面的网卡又具有两个IP
地址。
当然两块网卡设置成同一网段是不合理的。
我的技术实在有限,这些都是实验后的猜测,就当抛砖引玉,希望有人能给解释一下。谢谢