Linux 核心引數 arp_ignore & arp_announce 詳解

ido發表於2018-05-17

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
來源:簡書
著作權歸作者所有。商業轉載請聯絡作者獲得授權,非商業轉載請註明出處。

相關文章