详细的网络协议之ARP请求

对于 ARP 协议,你想知道的,可能包括以下几点:

  • ARP 是啥

  • 为啥需要 ARP

  • ARP 是怎么工作的

  • ARP 报文格式长啥样

  • ARP 安全吗

  • 有哪些命令可以操作 ARP

  • ARP 有哪些内核配置参数

带着这些问题,下面我们就来一一解答。

 

ARP 是啥


ARP 全称为 Address Resolution Protocol ,即地址解析协议,主要用于根据 IP 地址求出主机所对应的物理地址(或者叫 MAC 地址)。

它还有个孪生兄弟叫 RARP(Reverse ARP),即反向地址解析协议,也就是根据主机 MAC 地址求出对应的 IP 地址,但是这个协议不常用,通常只用在无盘系统中。

ARP 只用于 IPv4,IPv6 使用邻居发现协议( Neighbor Discovery Protocol, NDP) 来代替 ARP 的功能。

为啥需要 ARP


在网络通信中,主机和主机之间的通信需要根据 OSI 模型进行数据包的封装和解封装,这里面不仅需要封装源目的 IP 地址,也需要源目的 MAC 地址,那么 MAC 地址从哪里来呢,一般情况下,上层应用只知道 IP 地址,而并不关心 MAC 地址,所以就需要通过一个协议来获知目的 MAC 地址,完成数据的封装,这个协议就是 ARP 协议该干的活。

ARP 是怎么工作的


在介绍 ARP 如何工作之前,需要知道一个概念 ARP 缓存表 。在每台安装有 TCP/IP 协议的电脑或网络设备里都有一个 ARP 缓存表,表中记录的是 IP 地址和 MAC 地址的映射关系,比如:

以上表中的主机 A 向主机 B 发送数据为例,说一下 ARP 的工作流程:

  1. 当发送数据时,主机 A 会在自己的 ARP 缓存表中寻找是否有目标 IP 地址,如果找到,就把对应的目标 MAC 地址封装进帧里进行发送。

  2. 如果没有找到,主机 A 就会向网络中发送一个广播(ARP request),和主机 A 同网段内的所有主机都会收到这个请求,该请求的目标 MAC 地址是"FF.FF.FF.FF.FF.FF",目标 IP 是主机 B 的 IP。

  3. 只有主机 B 会接收这个请求,并且向主机 A 做出回应(ARP response),而其他主机接收到请求之后发现目标 IP 不是自己,就会选择丢弃。主机 B 从请求中获得主机 A 的 MAC 地址和 IP 地址,所以会以单播的方式进行回应,同时更新自己的 ARP 缓存表。

  4. 主机 A 接收到主机 B 的响应之后,也会更新自己的 ARP 缓存,下次再访问主机 B 时,就直接从 ARP 缓存里查找即可。

ARP缓存超时: 既然是缓存表,意味着有时效性。ARP 缓存表采用老化机制,在一段时间内如果表中的某一条目没有使用,就会被删除,这样可以减少缓存表的长度,加快查询速度。

缓存时间,一般是 20 分钟 ,但 RFC 也有规定一些不完整条目是 3 分钟,什么是不完整条目,比如下面这条,对一个不存在的主机执行了一次 ARP 请求,就是一条不完整的条目:

 
  1. # arp -a

  2. ?(10.0.0.99) at <incomplete> on eth0

ARP 报文格式长啥样


首先看一个以太网帧中,ARP 报文处在一个什么位置。

以下是一个以太网帧的简化图,这里只是为了说明 ARP 报文在整个以太网帧中所处的位置,所以这个以太网帧并不是完整的。

我们看到,以太网帧通过一个 2 字节的帧类型来表示它后面的数据负载(payload)部分具体是什么类型的数据,如果帧类型是 16进制的 0x0800,则表示 payload 是 IP 报文,如果是 0x0806,就表示 ARP 报文,包括 ARP 请求报文和应答报文。当然,这里还有其他类型的数据,比如 ARAP,我们就不一一列出了。

下面,继续走进 ARP 报文内部,看看它包含哪些字段:

  • 硬件类型:指出硬件地址类型,对于以太网,该值是 1

  • 协议类型:指出网络层协议类型,对于 IPv4,该值是 0x0800

  • 硬件大小和协议大小:分别指出后面的硬件地址和协议地址的大小,对于使用 IPv4 的 ARP 报文,该值分别是 6 和 4

  • Op:指出该报文是 ARP 请求(值为 1)、ARP 应答(2)、RARP 请求(3) 或 RARP 应答(4)

  • 后面的 4 个字段和前面 4 个字段对应,分别表示源目的 MAC 和源目的 IP 地址

我们通过 Wireshark 抓包看看。

ARP 请求报文:

ARP 应答报文:

可以看到 Op 字段,对于 ARP 请求和应答报文分别为 1 和 2,其他字段大家也可以看看,比较直观。

有哪些命令可以操作 ARP


① arp

用法:

 
  1. # arp (选项)(参数)

  2. -a <主机IP>:显示 arp 缓冲区中的所有条目

  3. -e:以 Linux 的显示风格显示 arp 缓冲区中的条目

  4. -v:显示详细的 arp 缓冲区条目,包括缓冲区条目的统计信息

  5. -i <接口>:显示指定接口的 arp 缓存条目

  6. -s <主机IP><MAC>:配置主机的 IP 地址与 MAC 地址的静态映射

  7. -d <主机>:删除 arp 条目

  8. -f <文件>:从文件 /etc/ethers(默认)或者指定文件中记录的 arp 条目配置静态映射

② ip neigh

ip neigh 是和 arp 相同功能但不同用法的另一套命令,全称为 ip neighbour

用法:

 
  1. # ip neigh help

  2. ip neigh { add | del | change | replace }

  3. { ADDR [ lladdr LLADDR ] [ nud STATE ] | proxy ADDR } [ dev DEV ]

  4. ip neigh { show | flush } [ proxy ] [ to PREFIX ] [ dev DEV ] [ nud STATE ][ vrf NAME ]

  5. # 其中几个选项的意思解释

  6. - to ADDR: 协议地址,指定主机的 IP 地址

  7. - dev DEV: 指定网口

  8. - lladdr LLADDR: 指定 MAC 地址

  9. - nud STATE: 状态值,有以下几个值:

  10. - permanent:永久有效

  11. - noarp:有效,不会验证此条目,但可以在其生命周期到期时将其删除

  12. - reachable:有效,直到可达性超时到期

  13. - stale:有效但可疑

  14. - all:列出所有状态

  15. # 常用操作

  16. 1. 列出所有 arp 条目

  17. # ip neigh show

  18. 2. 添加 arp 静态条目

  19. # ip neigh add 192.168.10.11 lladdr 00:01:02:03:04:05 dev eth0

  20. 3. 删除指定 IP 或者网口的 arp 条目

  21. # ip neigh del 192.168.10.11 dev eth0

  22. 4. 刷新 arp 表

  23. # ip neigh flush 192.168.10.11

  24. # 此外还有两个命令,可以更改 arp 条目

  25. # ip neighbour change - 更改

  26. # ip neighbour replace - 添加新的或更改

③ arping

arping 和 ping 相似,主要是通过发送 ARP 请求查看 IP 和 MAC 的映射关系,以及探测 IP 的冲突问题。更多的用法可以参见这篇文章 xxx

④ arpwatch

arpwatch 主要用于监听网络中的 ARP 数据的变化关系并记录,可以将监听到的变化通过 E-mail 发送。

用法:

 
  1. # arpwatch [-d][-f <记录文件>][-i <接口>][-r <记录文件>]

  2. 监听 eth0 的 ARP 信息

  3. # arpwatch -i eth0

  4. 将监听到的 ARP 记录存储到文件

  5. # arpwatch -i eth0 -f /var/arpwatch/arp.dat

  6. 从指定文件中读取 ARP 记录,而不是从网络中监听

  7. # arpwatch -r /var/arpwatch/arp.dat

 

ARP 有哪些内核配置参数


从上文我们知道,ARP 是一个无状态协议,就是说它不管自己是否发过请求,也不管应答是否合理,再加上广播的特性,有时候通信上会出现一些匪夷所思的问题,系统会通过以下几个配置参数来规避这些问题。

要说清楚这些参数,我们先上个图:

在这样一个局域网的图示中,B 向 A 的 eth0 接口发送 ARP 请求,由于是广播,并且 IP 地址针对的是整个主机,而不是特定的某个接口,所以,A 的两个口 eth0 和 eth1 都会接收请求并发出应答,而 B 则以最后应答的 MAC 地址为准。

这就会带来第一个问题,如果 B 本来想获取 eth0 的 MAC 地址,但却得到 eth1 的,这就会导致后续发送数据的不准确。

解决这个问题可以用两个内核参数,这两个参数都是在 ARP 应答上做文章,让它能够正确应答。

① arp_ignore

  • 0 - (默认值): 回应任何网络接口(网卡)上对任何本机IP地址的arp查询请求。比如eth0=192.168.0.1/24,eth1=10.1.1.1/24,那么即使eth0收到来自10.1.1.2这样地址发起的对10.1.1.1 的arp查询也会给出正确的回应;而原本这个请求该是出现在eth1上,也该有eth1回应的。
  • 1 - 只回答目标IP地址是本机上来访网络接口(网卡)IP地址的ARP查询请求 。比如eth0=192.168.0.1/24,eth1=10.1.1.1/24,那么即使eth0收到来自10.1.1.2这样地址发起的对192.168.0.1的查询会回应,而对10.1.1.1 的arp查询不会回应。
  • 2 -只回答目标IP地址是本机上来访网络接口(网卡)IP地址的ARP查询请求,且来访IP(源IP)必须与该网络接口(网卡)上的IP(目标IP)在同一子网段内 。比如eth0=192.168.0.1/24,eth1=10.1.1.1/24,eth1收到来自10.1.1.2这样地址发起的对192.168.0.1的查询不会回应,而对192.168.0.2发起的对192.168.0.1的arp查询会回应。
  • 3 - do not reply for local addresses configured with scope host,only resolutions for global and link addresses are replied。(不知道怎么翻译合适,网上有一个参考但我认为无法理解它的含义:不回应该网络界接口的arp请求,而只对设置的唯一和连接地址做出回应)
  • 4-7 - 保留未使用
  • 8 -不回应所有(本机地址)的arp查询

在设置参数的时候将arp_ignore 设置为1,意味着当别人的arp请求过来的时候,如果接收的网络接口卡上面没有这个ip,就不做出响应。默认是0,只要这台机器上面任何一个设备上面有这个ip,就响应arp请求,并发送mac地址。

在内核参数中,除了每个网口都有自己的 arp_ignore 配置外,还有两个(一个是默认 default,一个是全局 all),如下。一般,如果网口自身的 arp_ignore 不配置的情况下,使用 default 的配置,如果 all 和网口自身都配置的情况下,使用两者中较大的那一个。

 
  1. # sysctl -a | grep arp_ignore

  2. net.ipv4.conf.default.arp_ignore=1

  3. net.ipv4.conf.all.arp_ignore=1

  4. net.ipv4.conf.lo.arp_ignore=1

  5. net.ipv4.conf.eth0.arp_ignore=1

  6. net.ipv4.conf.eth1.arp_ignore=1

关于配置这块,有临时生效和永久生效的配置方式,文末有进一步说明。

② arp_filter

这个参数和 arp_ignore能够达到相同的目的,但 arp_filter会更严格一些,它在选网口应答的时候会按照路由来选。它是一个 bool 值,具体为:

  • 0:默认值,所有网口都可以响应 ARP 请求

  • 1:会根据本机路由表来验证哪个网口应该进行应答,优先选择在路由表前面的网口,也就是会有一个反向路由验证的过程。

同样,他也有以下的参数:

 
  1. $ sysctl -a | grep arp_filter

  2. net.ipv4.conf.all.arp_filter = 0

  3. net.ipv4.conf.default.arp_filter = 0

  4. net.ipv4.conf.eth0.arp_filter = 0

  5. net.ipv4.conf.eth1.arp_filter = 0

  6. net.ipv4.conf.lo.arp_filter = 0

上面两个参数解决的是 ARP 应答方向上的问题,而下面的 arp_announce 是解决 ARP 请求方向上的问题。它可以控制本机发出的 ARP 请求中的源 IP 地址使用哪个网口的地址。

③ arp_announce

它有以下 3 个整数值:

  • 0:默认值,可以在任意网口上发送 ARP 请求,但是请求的源 IP 地址与当前发送的网口没有关系。也就是说如果源 IP 地址与当前发送网口的地址不同(使用其他网口作为源 IP 地址),使用原本的源 IP 地址。

  • 1:要求尽量避免使用不在当前发送网口子网段内的 IP 地址作为 ARP 请求的源 IP 地址,也就是说系统会遍历所有网口的 IP,然后看哪个网口的 IP 和 ARP 请求包中的源 IP 在同一个网段内,优先选择哪个进行发送,如果都不在,就采用下面级别 2 的方式来选择。

  • 2:1 是看源 IP 地址,这种方式是看目标 IP 地址,选择与目标 IP 地址在同一个网段内的网口 IP 作为 ARP 请求的源 IP 地址,如果还是没找到,则直接选择当前网口的 IP 或者能够接受到 ARP 回应的网口 IP 来发送 ARP 请求,并设源 IP 为发送网口的 IP。

此外,还有两个参数:

④ arp_accept

默认对不在 ARP 表中的 IP 地址发出的 APR 包的处理方式

  • 0:不在 ARP 表中创建对应 IP 地址的表项

  • 1:在 ARP 表中创建对应 IP 地址的表项

⑤ arp_notify

ARP 通知链操作

  • 0:不做任何操作

  • 1:当设备或硬件地址改变时自动产生一个 ARP 请求

修改方法


临时修改方法:

 1. 修改/proc文件系统:

 
  1. echo "1">/proc/sys/net/ipv4/conf/all/arp_ignore

  2. echo "1">/proc/sys/net/ipv4/conf/eth0/arp_ignore

  3. echo "2">/proc/sys/net/ipv4/conf/all/arp_announce

  4. echo "2">/proc/sys/net/ipv4/conf/eth0/arp_announce

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

 
  1. sysctl -w net.ipv4.conf.all.arp_ignore=1

  2. sysctl -w net.ipv4.conf.eth0.arp_ignore=1

  3. sysctl -w net.ipv4.conf.all.arp_announce=2

  4. sysctl -w net.ipv4.conf.eth0.arp_announce=2

永久修改需要写入配置文件:

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

 
  1. net.ipv4.conf.all.arp_ignore=1

  2. net.ipv4.conf.eth0.arp_ignore=1

  3. net.ipv4.conf.all.arp_announce=2

  4. net.ipv4.conf.eth0.arp_announce=2

备注:arp_ignore和arp_announce参数分别有all,default,lo,eth0等对应不同网卡。当all和具体网卡的参数值不一致时,配置为较大值的生效。一般只需修改all和某个具体网卡的参数即可。

然后一定记得执行 sysctl -p 使之生效。

详细的网络协议之ARP请求-CSDN博客

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
ARP(Address Resolution Protocol)是一种计算机网络协议,用于将网络层的IP地址映射到物理层的MAC地址。它的主要功能是在局域网中根据IP地址获取对应的MAC地址,以便数据的正常传输。 ARP协议的工作原理如下: 当一个主机发送数据到另一台主机时,首先会检查自己的ARP缓存表,如果已经有目标主机的IP地址和MAC地址的映射关系,则直接将数据封装成数据帧发送给目标主机。 如果ARP缓存表中没有目标主机的映射关系,发送主机就会在局域网内广播一个ARP请求报文,包含目标主机的IP地址。所有的主机都会收到这个请求报文,但只有目标主机会响应。目标主机收到这个ARP请求后,会发送一个ARP响应报文给发送主机,包含自己的IP地址和MAC地址。 当发送主机收到目标主机的ARP响应报文后,就会将这个映射关系添加到自己的ARP缓存表中,并将数据封装成数据帧发送给目标主机。 如果在一段时间内没有数据传输,ARP缓存表中的映射关系会过期,发送主机再次发送数据时会重新进行ARP请求ARP协议的重要性在于它提供了网络层和物理层之间的映射关系,使得IP地址能够正常转换为MAC地址,实现数据的准确传输。但同时也存在一些安全隐患,比如ARP欺骗攻击,攻击者可以伪造IP地址和MAC地址的映射关系,导致数据被发送到错误的目标主机。 综上所述,ARP协议在计算机网络中起着至关重要的作用,通过IP地址和MAC地址的映射关系,实现了网络通信的正常运行。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值