Linux 内核参数 arp_ignore & arp_announce 详解
arp_ignore定义了对目标地址为本机IP的ARP询问的不同应答模式。
arp_announce对网络接口(网卡)上发出的ARP请求包中的源IP地址作出相应的限制;主机会根据这个参数值的不同选择使用IP数据包的源IP或当前网络接口卡的IP地址作为ARP请求包的源IP地址。
arp_ignore
在内核参数中除了每个网卡都有自己的arp_ignore配置外,还有两个(一个是默认default,一个是全局all)需要用到arp_ignore配置。所有配置项如下面的代码段:
net.ipv4.conf.all.arp_ignore
net.ipv4.conf.default.arp_ignore
net.ipv4.conf.lo.arp_ignore
net.ipv4.conf.eth0.arp_ignore
net.ipv4.conf.eth1.arp_ignore
net.ipv4.conf.eth2.arp_ignore
……
如果某个的网络接口(网卡)上没有配置arp_ignore参数的值则会把default上配置的arp_ignore应用到该网络接口上。而在所有网络接口上实际生效的值是 all 和 对应网络接口上配置的arp_ignore参数值中较大的那个值。
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_announce
和arp_ignore一样,在内核参数中除了每个网卡都有自己的arp_announce配置外,还有两个(一个是默认default,一个是全局all)需要用到arp_announce配置。所有配置项如下面的代码段:
arp_announce 对网络接口(网卡)上发出的ARP请求包中的源IP地址作出相应的限制;主机会根据这个参数值的不同选择使用IP数据包的源IP或当前网络接口卡的IP地址作为ARP请求包的源IP地址。
net.ipv4.conf.all.arp_announce
net.ipv4.conf.default.arp_announce
net.ipv4.conf.lo.arp_announce
net.ipv4.conf.eth0.arp_announce
net.ipv4.conf.eth1.arp_announce
net.ipv4.conf.eth2.arp_announce
……
如果某个的网络接口(网卡)上没有配置arp_announce参数的值则会把default上配置的arp_announce应用到该网络接口上。而在所有网络接口上实际生效的值是 all 和 对应网络接口上配置的arp_announce参数值中较大的那个值。
arp_announce参数的值及其含义如下:
- 0 - (默认) 在任意网络接口(eth0,eth1,lo)上使用任何本机地址进行ARP请求。也就是说如果IP数据包中的源IP与当前发送ARP请求的网络接口卡IP地址不同时(但这个IP依然是本主机上其他网络接口卡上的IP地址),ARP请求包中的源IP地址将使用与IP数据包中的 源IP相同的本主机上的IP地址,而不是使用当前发送ARP请求的网络接口卡的IP地址。
- 1 -尽量避免使用不在该网络接口(网卡)子网段内的IP地址做为arp请求的源IP地址。当接收此ARP请求的主机要求ARP请求的源IP地址与接收方IP在同一子网段时,此模式非常有用。此时会检查IP数据包中的源IP是否为所有网络接口上子网段内的ip之一。如果找到了一个网络接口的IP正好与IP数据包中的源IP在同一子网段,则使用该网络接口卡进行ARP请求。如果IP数据包中的源IP不属于各个网络接口上子网段内的ip,那么将采用级别2的方式来进行处理。
- 2 - 始终使用与目标IP地址对应的最佳本地IP地址作为ARP请求的源IP地址。在此模式下将忽略IP数据包的源IP地址并尝试选择能与目标IP地址通信的本机地址。首要是选择所有网络接口中子网包含该目标IP地址的本机IP地址。如果没有合适的地址,将选择当前的网络接口或其他的有可能接受到该ARP回应的网络接口来进行发送ARP请求,并把发送ARP请求的网络接口卡的IP地址设置为ARP请求的源IP。
对arp_announce
参数更详细的说明
假设一个Linux服务器X有三个网络接口,分别为:eth0,eth1和eth2。每个接口都有一个IP地址,分别为:IP0,IP1和IP2。当本地应用程序尝试通过eth2发送IP0的IP数据包时。如果目标节点的mac地址没有解析。这个Linux服务器X将发送ARP请求来获取目标(或网关)的mac地址。在这种情况下,ARP请求包的源IP地址是什么呢?IP0(IP数据包的中的源IP)或IP2(发送ARP请求包的网络接口eth2的IP)?其实对于大部分路由器来说ARP请求包中的源IP地址使用发送ARP请求包的网络接口上配置的IP地址(在上面的例子中为IP2)。但是,linux服务器的行为是点不同。在Linux服务器中通过Linux的内核数据arp_announce
,ARP请求中源地址的选择是完全可配置。 如果我们想在ARP请求中使用IP2而不是IP0,我们应该把arp_announce
的值改为1或2。默认值为0 - 允许使用IP0作为ARP请求包中的源IP。
其实arp_announce是为了解决Linux服务器作为路由器时的arp问题,因为路由器一般是动态学习ARP包的(一般动态配置DHCP的话)。当内网的Linux机器要发送一个到外部的ip包,那么它就会请求路由器的Mac地址,发送一个arp请求,这个arp请求里面包括了自己的ip地址和Mac地址。而linux默认是使用ip数据包的源ip地址作为arp里面的源ip地址,而不是使用发送设备上面网络接口卡的ip地址 (默认arp_announce
的值为0)。这样在lvs架构下,所有arp请求包的源地址都是同一个VIP地址,那么arp请求就会包括VIP地址和设备 Mac。而路由器收到这个arp请求就会更新自己的arp缓存,这样就会造成ip欺骗了,VIP被抢夺,所以就会有问题。
arp缓存为什么会更新了,什么时候会更新呢?为了减少arp请求的次数,当主机接收到询问自己的arp请求的时候,就会把源ip和源Mac放入自 己的arp表里面,方便接下来的通讯。如果收到不是询问自己的包(arp是广播的,所有人都收到),就会丢掉,这样不会造成arp表里面无用数据太多导致 有用的记录被删除。
配置方式
要配置Linux内核中的 arp_ignore & arp_announce 参数有多种配置方式可供选择,下面分别介绍。
临时生效的配置方式
临时生效的配置方式,在系统重启,或对系统的网络服务进行重启后都会失效。这种方式可用于临时测试、或做实验时使用。
使用 sysctl 指令配置
sysctl 命令的 -w 参数可以实时修改Linux的内核参数,并生效。所以使用如下命令可以修改Linux内核参数中的arp_ignore & arp_announce 。
sysctl -w net.ipv4.conf.default.arp_ignore=1
sysctl -w net.ipv4.conf.all.arp_ignore=1
sysctl -w net.ipv4.conf.lo.arp_ignore=1
sysctl -w net.ipv4.conf.eth0.arp_ignore=1
sysctl -w net.ipv4.conf.eth1.arp_ignore=1
……
sysctl -w net.ipv4.conf.default.arp_announce =1
sysctl -w net.ipv4.conf.all.arp_announce =1
sysctl -w net.ipv4.conf.lo.arp_announce =1
sysctl -w net.ipv4.conf.eth0.arp_announce =1
sysctl -w net.ipv4.conf.eth1.arp_announce =1
……
有关 sysctl 指令的更详细介绍,请参见Linux的系统man手册(man sysctl),或其他有关sysctl指令详细介绍的文章。
修改内核参数的映射文件
在Linux文件系统映射出的内核参数配置文件中记录了Linux系统中网络接口ARP请求和响应配置参数 arp_ignore & arp_announce 的值。可使用vi编辑器修改文件的内容,也可以使用如下指令修改文件内容:
echo 1 > /proc/sys/net/ipv4/conf/default/arp_ignore
echo 1 > /proc/sys/net/ipv4/conf/all/arp_ignore
echo 1 > /proc/sys/net/ipv4/conf/lo/arp_ignore
echo 1 > /proc/sys/net/ipv4/conf/eth0/arp_ignore
echo 1 > /proc/sys/net/ipv4/conf/eth1/arp_ignore
……
echo 1 > /proc/sys/net/ipv4/conf/default/arp_announce
echo 1 > /proc/sys/net/ipv4/conf/all/arp_announce
echo 1 > /proc/sys/net/ipv4/conf/lo/arp_announce
echo 1 > /proc/sys/net/ipv4/conf/eth0/arp_announce
echo 1 > /proc/sys/net/ipv4/conf/eth1/arp_announce
……
永久生效的配置方式
永久生效的配置方式,在系统重启、或对系统的网络服务进行重启后还会一直保持生效状态。这种方式可用于生产环境的部署搭建。
修改/etc/sysctl.conf 配置文件可以达到永久生效的目的。
在sysctl.conf配置文件中有一项名为可以添加如下面代码段中的配置项,用于配置Linux内核中的各网络接口的 arp_ignore & arp_announce 参数。
net.ipv4.conf.default.arp_ignore=1
net.ipv4.conf.all.arp_ignore=1
net.ipv4.conf.lo.arp_ignore=1
net.ipv4.conf.eth0.arp_ignore=1
net.ipv4.conf.eth1.arp_ignore=1
……
net.ipv4.conf.default.arp_announce =1
net.ipv4.conf.all.arp_announce =1
net.ipv4.conf.lo.arp_announce =1
net.ipv4.conf.eth0.arp_announce =1
net.ipv4.conf.eth1.arp_announce =1
……
需要注意的是,修改sysctl.conf文件后需要执行指令sysctl -p 后新的配置才会生效。
有关 sysctl 指令和sysctl.conf配置文件的更详细介绍,请参见Linux的系统man手册(man sysctl和man sysctl.conf),或其他有关sysctl指令和sysctl.conf配置文件的文章。
说明
此文是作者在互联网上阅读了大量有关 arp_ignore & arp_announce 的文章后,根据自己的理解进行的总结。由于个人水平限制,难免有所失误。如果您在阅读时发现谬误之处,还望指出,以期共同进步。
作者:JSON_NULL
链接:https://www.jianshu.com/p/a682ecae9693
來源:简书
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
Linux 内核参数 arp_ignore & arp_announce 详解的更多相关文章
- Linux内核数据结构之kfifo详解
本文分析的原代码版本: 2.6.24.4 kfifo的定义文件: kernel/kfifo.c kfifo的头文件: include/linux/kfifo.h kfifo是内核里面的一个First ...
- Linux内核中kzalloc函数详解
**************************************************************************************************** ...
- Linux内核线程kernel thread详解--Linux进程的管理与调度(十)
内核线程 为什么需要内核线程 Linux内核可以看作一个服务进程(管理软硬件资源,响应用户进程的种种合理以及不合理的请求). 内核需要多个执行流并行,为了防止可能的阻塞,支持多线程是必要的. 内核线程 ...
- Linux内核线程kernel thread详解--Linux进程的管理与调度(十)【转】
转自:http://blog.csdn.net/gatieme/article/details/51589205 日期 内核版本 架构 作者 GitHub CSDN 2016-06-02 Linux- ...
- Linux内核之页面换出详解
kswap线程主要用于页面的定期换出,接下来说说kswap线程的实现 首先kswap线程的初始化时,需要根据物理内存的大小设置一个page_cluster变量的值,这个值表示预读数目 (比如本来只读一 ...
- Linux内核中container_of函数详解
http://www.linuxidc.com/Linux/2016-08/134481.htm
- Linux内核源代码目录结构详解
http://blog.csdn.net/u013014440/article/details/44024207
- Linux进程上下文切换过程context_switch详解--Linux进程的管理与调度(二十一)
1 前景回顾 1.1 Linux的调度器组成 2个调度器 可以用两种方法来激活调度 一种是直接的, 比如进程打算睡眠或出于其他原因放弃CPU 另一种是通过周期性的机制, 以固定的频率运行, 不时的检测 ...
- (转)Linux内核参数设置sysctl命令详解
Linux内核参数设置sysctl命令详解 原文:https://www.zhukun.net/archives/8064 sysctl是一个允许您改变正在运行中的Linux系统的接口. 它包含一些 ...
随机推荐
- Qt: 数据库操作;
QT的数据库操作有两种方式: 一) 使用QsqlTableModel类, 可以配合QTableView进行界面显示并进行数据库操作, 这种方法比较方便快捷: 二) 使用原始SQL语言, 利用INSE ...
- 【机器学习】BP & softmax求导
目录 一.BP原理及求导 二.softmax及求导 一.BP 1.为什么沿梯度方向是上升最快方向 根据泰勒公式对f(x)在x0处展开,得到f(x) ~ f(x0) + f'(x0)(x-x0) ...
- EF CodeFirst系列(9)---添加初始化数据和数据库迁移策略
1.添加初始化数据(Seed) 我们可以在初始化数据库的过程中给数据库添加一些数据.为了实现初始化数据(seed data)我们必须创建一个自定义的数据库初始化器(DB initializer),并重 ...
- Windows下配置eclipse写WordCount
1 下载插件 hadoop-eclipse-plugin-2.7.2.jar github上下载源码后需要自己编译.这里使用已经编译好的插件即可 2 配置插件 把插件放到..\eclipse\plug ...
- HDU 5984(求木棒切割期望 数学)
题意是给定一长为 L 的木棒,每次任意切去一部分直到剩余部分的长度不超过 D,求切割次数的期望. 若木棒初始长度不超过 D,则期望是 0.000000: 设切割长度为 X 的木棒切割次数的期望是 F( ...
- 2.6 if嵌套
if嵌套 通过学习if的基本用法,已经知道了 当需要满足条件去做事情的这种情况需要使用if 当满足条件时做事情A,不满足条件做事情B的这种情况使用if-else 想一想: 坐火车或者地铁的实际情况是: ...
- MySQL数据库学习2 - 数据库的操作
一.系统数据库 二.创建数据库 三.数据库相关操作 四.了解内容 一.系统数据库 执行如下命令,查看系统库 show databases; information_schema: 虚拟库,不占用磁盘空 ...
- ADO五大对象
ADO.NET五大对象, 1. Connection:与数据源建立连接. 2. Command:对数据源执行SQL命令并返回结果. 3. DataReader:读取数据源的数据,只允许对将数据源以只 ...
- mysql之concat concat_ws group_concat
concat.concat_ws.group_concat都可以用来连接字符串. concat和concat_ws用来连接同一行中不同列的数据,group_ws用来连接同一列的数据. 格式如下: co ...
- PLSQL安装、PLSQL汉化、激活
前言 新版PLSQL连接Oracle时,不需要Oracle客户端为32位了,安装完Oracle后也不需要在单独安装客户端. 一.准备工作 1.点击下载PLSQL,本次安装的PLSQL版本为12.0.7 ...