zoukankan      html  css  js  c++  java
  • Linux之ARP——种种

    Linux ARP缓存配置和状态查看命令

    • 查看Linux ARP缓存老化时间

    cat /proc/sys/net/ipv4/neigh/eth0/base_reachable_time
    同目录下还有一个文件gc_stale_time,官方解释如下:
    Determines how often to check for stale neighbour entries. 
    When a neighbour entry is considered stale it is resolved again before sending data to it. 
    Defaults to 60 seconds.

    • 查看Linux ARP缓存状态

    arp -a    #代码对应于ioctl(s, SIOCGARP, &arpreq),没法看到每条缓存的状态是REACHABLE还是STALE

    /isam/slot_1101/run # arp -a
    ? (135.251.197.136) at 00:19:8f:5f:bd:87 [ether] on eth0
    ? (135.251.196.1) at 00:e0:b1:ca:5a:48 [ether] on eth0

    ip neigh show    #实现上是通过另一种系统调用netlink来获取的

    /proc/sys/net/ipv4/neigh/eth0 # ip neigh
    135.251.197.136 dev eth0 lladdr 00:19:8f:5f:bd:87 REACHABLE
    135.251.196.1 dev eth0 lladdr 00:e0:b1:ca:5a:48 STALE

    • 应用程序如何触发arp缓存的添加和刷新呢?

    经过一系列测试,结论如下:

    执行arping命令,无法添加新的arp缓存。但是可以把STALE的缓存刷新为REACHABLE状态。

    arping有如下选项,是不是我少加了什么选项呢?注释符#后面的解释是man命令里面摘过来的。

    arping -I eth0 135.251.196.1 -c 10

    /isam/slot_default/run # arping -h
    arping: invalid option -- 'h'
    BusyBox v1.22.1 (2015-07-11 21:41:15 CEST) multi-call binary.

    Usage: arping [-fqbDUA] [-c CNT] [-w TIMEOUT] [-I IFACE] [-s SRC_IP] DST_IP

    Send ARP requests/replies

    -f Quit on first ARP reply    #Finish after the first reply confirming that target is alive.
    -q Quiet    #Quiet output. Nothing is displayed.
    -b Keep broadcasting, don't go unicast    #Send only MAC level broadcasts. Normally arping starts from sending broadcast, and switch to unicast after reply received.
    -D Duplicated address detection mode    #Duplicate address detection mode (DAD). See RFC2131, 4.4.1.  Returns 0, if DAD succeeded i.e. no replies are received    #如果是DAD模式,则原源主机地址一直没有设置,那么就意味着源地址为0.0.0.0。这样当目的主机接到之后,就会向0.0.0.0发送回复,就相当于广播给以太网中所有的主机。因为进行D重复地址检测模式的原因很可能是由于源主机的IP地址没有设置,从而想设置自身的IP地址。在IP地址没有设置的时候,主机只能接受到地址为0.0.0.0的广播信号。
    -U Unsolicited ARP mode, update your neighbors    #Unsolicited ARP mode to update neighbours<80><99> ARP caches.  No replies are expected.    #为了更新以太网邻居的ARP快速缓存而主动进行的ARP。也就是免费ARP(gratuitous ARP),即请求自己的ip地址的mac地址。
    -A ARP answer mode, update your neighbors    #与-U选项类似,但是发送的是ARP 回复报文,而不是ARP请求报文。
    -c N Stop after sending N ARP requests
    -w TIMEOUT Time to wait for ARP reply, seconds
    -I IFACE Interface to use (default eth0)
    -s SRC_IP Sender IP address
    DST_IP Target IP address

    从以上选项可以看出,我们并没有漏掉什么选项,所以内核就是这么设计的。


    linux双网卡服务器配置同一网段IP的ping问题 

    问题是这样的,我有一台服务器,两个网口分别配置了同一网段的IP,然后将一个网口的网线拔掉,发现该网卡的IP仍然能够ping通,但是arp -a却发现该IP地址返回的确是另一块网卡的mac。百思不得其解。最后发现居然是linux内核的问题。解释如下。
    arp_announce/arp_ignore sysctl
    The arp_announce/arp_ignore sysctl on interfaces is available at the Linux official kernel since 2.6.4 and 2.4.26. The description about arp_announce/arp_ignore taken from kernel documentation is as follows: 

    Linux 官方内核自2.6.4和2.4.26开始,interface上的arp_announce/arp_ignore系统调用就可用了。下面是内核文档中关于arp_announce/arp_ignore的描述:

    arp_announce - INTEGER
    Define different restriction levels for announcing the local source IP address from IP packets in ARP requests sent on interface:


    0 - (default) Use any local address, configured on any interface

    1 - Try to avoid local addresses that are not in the target's subnet for this interface. This mode is useful when target hosts reachable via this interface require the source IP address in ARP requests to be part of their logical network configured on the receiving interface. When we generate the request we will check all our subnets that include the target IP and will preserve the source address if it is from such subnet. If there is no such subnet we select source address according to the rules for level 2.

    2 - Always use the best local address for this target. In this mode we ignore the source address in the IP packet and try to select local address that we prefer for talks with the target host. Such local address is selected by looking for primary IP addresses on all our subnets on the outgoing interface that include the target IP address. If no suitable local address is found we select the first local address we have on the outgoing interface or on all other interfaces, with the hope we will receive reply for our request and even sometimes no matter the source IP address we announce. The max value from conf/{all,interface}/arp_announce is used. Increasing the restriction level gives more chance for receiving answer from the resolved target while decreasing the level announces more valid sender's information.

    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-7 - reserved
    8 - do not reply for all local addresses


    The max value from conf/{all,interface}/arp_ignore is used when ARP request is received on the {interface}
    Disable ARP for VIP
    To disable ARP for VIP at real servers, we just need to set arp_announce/arp_ignore sysctls at the interface connected to the VIP network. For example, real servers have eth0 connected to the VIP network with the VIP at interface lo, we will have the following commands.

    echo 1 > /proc/sys/net/ipv4/conf/eth0/arp_ignore
    echo 2 > /proc/sys/net/ipv4/conf/eth0/arp_announce
    Or, if /etc/sysctl.conf is used in the system, we have this config in /etc/sysctl.conf

    net.ipv4.conf.eth0.arp_ignore = 1
    net.ipv4.conf.eth0.arp_announce = 2
    Note that the arp_announce/arp_ignore sysctls must be setup correctly, before the VIP address is brought up at a logical interface at real servers.
    ---------------------

    arp 静态绑定Mac地址

     

    首先,做两个对比试验:

    root@firewall root]# arp -a
    ? (192.168.100.83) at 00:15:58:A2:13: D0 [ether] on eth0
    ? (192.168.100.81) at 00:15:C5:E1:D1:58 [ether] on eth0

    [root@firewall bin]# arp -s 192.168.100.81 00:15:C5:E1:D1:58

    [root@firewall bin]# arp -a
    ? (192.168.100.83) at 00:15:58:A2:13: D0 [ether] on eth0
    ? (192.168.100.81) at 00:15:C5:E1: D1:58 [ether] PERM on eth0

    发现没有?多了一个PERM!

    或者
    [root@firewall bin]# cat /proc/net/arp
    IP address  HWtype  Flags  HWaddress  Mask  Device
    192.168.100.83  0x1  0x2  00:15:58:A2:13:D0  *  eth0
    192.168.100.81  0x1  0x6  00:15:C5:E1:D1:58  *  eth0

    [root@firewall bin]# arp -s 192.168.100.83 00:15:58:A2:13:D0

    [root@firewall bin]# cat /proc/net/arp
    IP address  HW type  Flags  HW address  Mask  Device
    192.168.100.83  0x1  0x6  00:15:58:A2:13:D0  *  eth0
    192.168.100.81  0x1  0x6  00:15:C5:E1: D1:58  *  eth0

    发现没有?Flags改变了!

    所以我们可以用两种方法找到arp的静态绑定地址:

    #arp -a | grep PERM   或者

    #cat /proc/net/arp | grep 0x6

    但建议用后者比较快。

    利用静态ARP表进行控制

    我们知道,ARP(Address Resolution Protocol,地址转换协议)被当作底层协议,用于IP地址到物理地址的转换。在以太网中,所有对IP的访问最终都转化为对网卡MAC地址的访问。 

    不妨设想一下,如果主机A的ARP列表中,到主机B的IP地址与MAC地址对应不正确,由A发往B数据包就会发向错误的MAC地址,当然无法顺利到达B,结 果是A与B根本不能进行通信。Linux可以通过arp命令控制ARP转换,即IP到MAC的转换。因此,也能利用这一功能对用户MAC地址进行匹配。下面我们就来看看arp命令的用法。 
    输入arp将显示当前所有ARP转换记录,类似于这样: 

    Address  HWtype  HWaddress  Flags  Mask  Iface 
    www.baidu.com ether  00:06:29:57:16:F5  C  eth0 
    218.200.80.177  ether  00:01:30:F4:32:40  C  eth1 
    192.168.100.25  ether  00:02:1E:F1:92:C2  C  eth0 

    由此可以看到,当前系统保留的IP地址与MAC地址一一对应,并指明了硬件类型(Hwtype)和通信所使用的接口(Iface)。不过这些都是动态生成的,无需手工干预。我们要做的恰恰是手工干预这一过程。 

    我们需要用到arp命令的另一重要功能,就是手工更改这一对应关系。此外,该命令还可以读取文本文件中的ARP记录,其默认文件是/etc/ethers。也就是说,当输入ARP-f的时候,系统就会读取/etc/ethers这个文件,并以其中的项目取代系统当前的ARP记录。假设/etc/ethers 文件内容如下: 

    192.168.100.25 00:02:01:50:BB:53

    然后执行命令arp –f

     
    这时,我们查看系统ARP表,会发现无论192.168.100.25原来对应的MAC地址是什么,都会被新的所取代: 

    www.baidu.com ether  00:06:29:57:16:F5  C  eth0 
    218.200.80.177  ether  00:01:30:F4:32:40  C  eth1 
    192.168.100.25  ether  00:02:01:50:BB:53  C  eth0

    此时,本机发往192.168.100.25的数据包目标MAC地址将由原来的00:02:1E:F1:92:C2改为00:02:01:50:BB:53 显然,如果192.168.100.25所在网卡的MAC地址并非00:02:01:50:BB:53,数据包就无法到达正确的目的地,那么它们也就无法通信了,这样也达到了识别非法用户的目的。 

    当然,控制MAC地址的方法还不止这些,例如可以利用交换机的端口管理功能识别用户。根据交换机的原理,它是直接将数据发送到相应端口,那么就必须保有一个数据库,包含所有端口所连网卡的MAC地址,由此可见,控制每个端口使用的MAC地址理论上是完全可行的。大部分中高端交换机如3Com SuperStack系列等,都具有这种功能。具体操作与交换机型号有关,这里就不赘述。 

    最后,提醒一下,MAC地址控制并非绝对保险。正如这个世界上没有绝对解不开的密码一样,所谓安全都是相对于特定的环境而言。现在,很多网卡都支持MAC地址的软件修改,Linux和Windows本身也都有办法修改这一物理地址。不过由于这种方式相对稳定,摒弃了繁琐的客户端设置,对用户完全透明,而且具备很强的可操作性,所以在某种程度上说是安全的。

    我们先看一下linux下的arp命令(如果开始arp表中的内容为空的话,需要先对某台主机进行一个连接,例如ping一下目标主机来产生一个arp项

    Linux Arp命令显示和修改地址解析协议(ARP)使用的“IP 到物理”地址转换表。
    ARP -s inet_addr eth_addr [if_addr]
    ARP -d inet_addr [if_addr]
    ARP -a [inet_addr] [-N if_addr] [-v]
    -a            通过询问当前协议数据,显示当前ARP项。如果指定inet_addr,则只显示指定计算机的IP地址和物理地址。如果不止一个网络接口使用ARP,则显示每个ARP表的项。
    -g            与-a相同。
    -v            在详细模式下显示当前ARP项。所有无效项和环回接口上的项都将显示。
    inet_addr     指定Internet地址(IP地址)。
    -N if_addr    显示if_addr指定的网络接口的ARP项。
    -d            删除inet_addr指定的主机。inet_addr可以是通配符*,以删除所有主机。
    -s            添加主机并且将Internet地址inet_addr与物理地址eth_addr相关联。物理地址是用连字符分隔的6个十六进制字节。该项是永久的。
    eth_addr      指定物理地址。
    if_addr       如果存在,此项指定地址转换表应修改的接口的 Internet 地址。如果不存在,则使用第一个适用的接口。
     
    示例:
    添加静态项。这个很有用,特别是局域网中中了arp病毒以后
    # arp -s 123.253.68.209 00:19:56:6F:87:D2
    # arp -a   .... 显示 ARP 表。
    但是arp -s设置的静态项在用户登出之后或重起之后会失效,如果想要任何时候都不失效,可以将ip和mac的对应关系写入arp命令默认的配置文件/etc/ethers中
     
    例如:
     
     
    引用
    root@ubuntu:/# vi /etc/ethers
    211.144.68.254 00:12:D9:32:BF:44
    写入之后执行下面的命令就好了
     
    引用
    arp -f /etc/ethers
    为保证重起之后绑定仍然有效,需要把上述命令写入/etc/ethers
     
    ARP(Address Resolution Protocol),或称地址解析协议。
    本地机向"某个IP地址 -- 目标机IP地址"发送数据时,先查找本地的ARP表,如果在ARP表中找到"目标机IP地址"的ARP表项,(网络协议)将把"目标机IP地址"对应的"MAC地址"放到MAC包的"目的MAC地址字段"直接发送出去;
    如果在ARP表没有找到"目标机IP地址"的ARP表项,则向局域网发送广播ARP包("目的MAC地址字段" == FF:FF:FF:FF:FF:FF),目标机将向本地机回复ARP包(包含目标机的MAC地址)
     
     

    Linux内核参数之arp_ignore和arp_announce

     

     

    一、arp_ignore和arp_announce介绍

      arp_ignore和arp_announce参数都和ARP协议相关,主要用于控制系统返回arp响应和发送arp请求时的动作。这两个参数很重要,特别是在LVS的DR场景下,它们的配置直接影响到DR转发是否正常。
    首先看一下Linux内核文档中对于它们的描述:
    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-7 - reserved
    8 - do not reply for all local addresses
    The max value from conf/{all,interface}/arp_ignore is used
    when ARP request is received on the {interface}
      arp_ignore参数的作用是控制系统在收到外部的arp请求时,是否要返回arp响应。
      arp_ignore参数常用的取值主要有0,1,2,3~8较少用到:
    0:响应任意网卡上接收到的对本机IP地址的arp请求(包括环回网卡上的地址),而不管该目的IP是否在接收网卡上。
    1:只响应目的IP地址为接收网卡上的本地地址的arp请求。
    2:只响应目的IP地址为接收网卡上的本地地址的arp请求,并且arp请求的源IP必须和接收网卡同网段。
    3:如果ARP请求数据包所请求的IP地址对应的本地地址其作用域(scope)为主机(host),则不回应ARP响应数据包,如果作用域为全局(global)或链路(link),则回应ARP响应数据包。
    4~7:保留未使用
    8:不回应所有的arp请求
      sysctl.conf中包含all和eth/lo(具体网卡)的arp_ignore参数,取其中较大的值生效。

    arp_announce - INTEGER
    Define different restriction levels for announcing the local
    source IP address from IP packets in ARP requests sent on
    interface:
    0 - (default) Use any local address, configured on any interface
    1 - Try to avoid local addresses that are not in the target's
    subnet for this interface. This mode is useful when target
    hosts reachable via this interface require the source IP
    address in ARP requests to be part of their logical network
    configured on the receiving interface. When we generate the
    request we will check all our subnets that include the
    target IP and will preserve the source address if it is from
    such subnet. If there is no such subnet we select source
    address according to the rules for level 2.
    2 - Always use the best local address for this target.
    In this mode we ignore the source address in the IP packet
    and try to select local address that we prefer for talks with
    the target host. Such local address is selected by looking
    for primary IP addresses on all our subnets on the outgoing
    interface that include the target IP address. If no suitable
    local address is found we select the first local address
    we have on the outgoing interface or on all other interfaces,
    with the hope we will receive reply for our request and
    even sometimes no matter the source IP address we announce.
    The max value from conf/{all,interface}/arp_announce is used.
      arp_announce的作用是控制系统在对外发送arp请求时,如何选择arp请求数据包的源IP地址。(比如系统准备通过网卡发送一个数据包a,这时数据包a的源IP和目的IP一般都是知道的,而根据目的IP查询路由表,发送网卡也是确定的,故源MAC地址也是知道的,这时就差确定目的MAC地址了。而想要获取目的IP对应的目的MAC地址,就需要发送arp请求。arp请求的目的IP自然就是想要获取其MAC地址的IP,而arp请求的源IP是什么呢? 可能第一反应会以为肯定是数据包a的源IP地址,但是这个也不是一定的,arp请求的源IP是可以选择的,控制这个地址如何选择就是arp_announce的作用)
      arp_announce参数常用的取值有0,1,2。
    0:允许使用任意网卡上的IP地址作为arp请求的源IP,通常就是使用数据包a的源IP。
    1:尽量避免使用不属于该发送网卡子网的本地地址作为发送arp请求的源IP地址。
    2:忽略IP数据包的源IP地址,选择该发送网卡上最合适的本地地址作为arp请求的源IP地址。
      sysctl.conf中包含all和eth/lo(具体网卡)的arp_ignore参数,取其中较大的值生效。

    二、arp_ignore和arp_announce参数示例

     

    (1)当arp_ignore参数配置为0时,eth1网卡上收到目的IP为环回网卡IP的arp请求,但是eth1也会返回arp响应,把自己的mac地址告诉对端。

    (2)当arp_ignore参数配置为1时,eth1网卡上收到目的IP为环回网卡IP的arp请求,发现请求的IP不是自己网卡上的IP,不会回arp响应。

    (3)当arp_announce参数配置为0时,系统要发送的IP包源地址为eth1的地址,IP包目的地址根据路由表查询判断需要从eth2网卡发出,这时会先从eth2网卡发起一个arp请求,用于获取目的IP地址的MAC地址。该arp请求的源MAC自然是eth2网卡的MAC地址,但是源IP地址会选择eth1网卡的地址。

     

    (4)当arp_announce参数配置为2时,eth2网卡发起arp请求时,源IP地址会选择eth2网卡自身的IP地址。

    三、arp_ignore和arp_announce参数在DR模式下的作用

      1. arp_ignore

      因为DR模式下,每个真实服务器节点都要在环回网卡上绑定虚拟服务IP。这时候,如果客户端对于虚拟服务IP的arp请求广播到了各个真实服务器节点,如果arp_ignore参数配置为0,则各个真实服务器节点都会响应该arp请求,此时客户端就无法正确获取LVS节点上正确的虚拟服务IP所在网卡的MAC地址。假如某个真实服务器节点A的网卡eth1响应了该arp请求,客户端把A节点的eth1网卡的MAC地址误认为是LVS节点的虚拟服务IP所在网卡的MAC,从而将业务请求消息直接发到了A节点的eth1网卡。这时候虽然因为A节点在环回网卡上也绑定了虚拟服务IP,所以A节点也能正常处理请求,业务暂时不会受到影响。但时此时由于客户端请求没有发到LVS的虚拟服务IP上,所以LVS的负载均衡能力没有生效。造成的后果就是,A节点一直在单节点运行,业务量过大时可能会出现性能瓶颈。

      所以DR模式下要求arp_ignore参数要求配置为1。

      2. arp_announce

       每个机器或者交换机中都有一张arp表,该表用于存储对端通信节点IP地址和MAC地址的对应关系。当收到一个未知IP地址的arp请求,就会再本机的arp表中新增对端的IP和MAC记录;当收到一个已知IP地址(arp表中已有记录的地址)的arp请求,则会根据arp请求中的源MAC刷新自己的arp表。
      如果arp_announce参数配置为0,则网卡在发送arp请求时,可能选择的源IP地址并不是该网卡自身的IP地址,这时候收到该arp请求的其他节点或者交换机上的arp表中记录的该网卡IP和MAC的对应关系就不正确,可能会引发一些未知的网络问题,存在安全隐患。
      所以DR模式下要求arp_announce参数要求配置为2。

    四、arp_ignore和arp_announce参数的配置方法

    arp_ignore和arp_announce参数分别有all,default,lo,eth1,eth2...等对应不同网卡的具体参数。当all和具体网卡的参数值不一致时,取较大值生效。

    一般只需修改all和某个具体网卡的参数即可(取决于你需要修改哪个网卡)。下面以修改lo网卡为例:

     1. 修改/etc/sysctl.conf文件,然后sysctl -p刷新到内存。

     net.ipv4.conf.all.arp_ignore=1
     net.ipv4.conf.lo.arp_ignore=1
     net.ipv4.conf.all.arp_announce=2
     net.ipv4.conf.lo.arp_announce=2

     2. 使用sysctl -w直接写入内存:

     sysctl -w net.ipv4.conf.all.arp_ignore=1
     sysctl -w net.ipv4.conf.lo.arp_ignore=1
     sysctl -w net.ipv4.conf.all.arp_announce=2
     sysctl -w net.ipv4.conf.lo.arp_announce=2

     3. 修改/proc文件系统:

     echo "1">/proc/sys/net/ipv4/conf/all/arp_ignore
     echo "1">/proc/sys/net/ipv4/conf/lo/arp_ignore
     echo "2">/proc/sys/net/ipv4/conf/all/arp_announce
     echo "2">/proc/sys/net/ipv4/conf/lo/arp_announce
     
     
     
  • 相关阅读:
    键盘过滤驱动
    多线程和多进程的差别(小结)
    Android UI设计规则
    怎样使用SetTimer MFC 够具体
    Chord算法(原理)
    POJ 1384 Piggy-Bank 背包DP
    Bulk Insert命令具体
    hibernate官方新手教程 (转载)
    教你用笔记本破解无线路由器password
    转换流--OutputStreamWriter类与InputStreamReader类
  • 原文地址:https://www.cnblogs.com/liuhongru/p/11057506.html
Copyright © 2011-2022 走看看