Dhcp

DHCP & macvlan:只有第一個虛擬介面適用於單播 DHCPREQUEST

  • July 14, 2020

我想做什麼?

我正在嘗試通過 DHCP 在單個物理 ISP 上行電纜上獲取 3 個公共 IP 地址。

出了什麼問題?

續訂有點不對勁。從介面來看,virtual0 在嘗試通過與 DHCP 伺服器的單播連接進行更新時工作得很好。virtual1 和 virtual2 介面因單播而失敗。他們進入備份模式以使用廣播並成功使用廣播,但垃圾日誌中充滿了不好的東西。我正在執行 Debian 8 和 isc-dhcp-client v. 4.3.1 。

我在啟動時設置了這樣的介面:

IF_VIRTUAL_BASE=eth0
IF_PUB0=虛擬0
IF_PUB1=虛擬1
IF_PUB2=虛擬2
IF_LAN=eth2

ifconfig "$IF_VIRTUAL_BASE" 向上
ip link add link "$IF_VIRTUAL_BASE" 地址 00:90:0b:ff:10:5b "$IF_PUB0" type macvlan
ip 連結設置“$IF_PUB0”
ip link add link "$IF_VIRTUAL_BASE" 地址 00:90:0b:ff:11:5b "$IF_PUB1" type macvlan
ip 連結設置“$IF_PUB1”
ip link add link "$IF_VIRTUAL_BASE" 地址 00:90:0b:ff:12:5b "$IF_PUB2" type macvlan
ip 連結設置“$IF_PUB2”

# 啟用轉發
迴聲 1 > /proc/sys/net/ipv4/ip_forward

unset new_routers在為 virtual1 和 virtual2 完成 dhcprequest 時,我也會這樣做。

猜猜看,這種怪物的作品:

7 月 11 日 20:45:43 gw dhclient:虛擬 0 上的 DHCPREQUEST 到 255.255.255.255 埠 67
7 月 11 日 20:45:43 gw dhclient:virtual1 上的 DHCPREQUEST 到 255.255.255.255 埠 67
7 月 11 日 20:45:43 gw ifup [582]:虛擬 0 到 255.255.255.255 埠 67 上的 DHCPREQUEST
7 月 11 日 20:45:43 gw ifup [592]:虛擬 1 上的 DHCPREQUEST 到 255.255.255.255 埠 67
7 月 11 日 20:45:43 gw dhclient:virtual2 上的 DHCPREQUEST 到 255.255.255.255 埠 67
7 月 11 日 20:45:43 gw ifup [634]:虛擬 2 上的 DHCPREQUEST 到 255.255.255.255 埠 67
7 月 11 日 20:45:46 gw dhclient:virtual1 上的 DHCPREQUEST 到 255.255.255.255 埠 67
7 月 11 日 20:45:46 gw ifup [592]:虛擬 1 上的 DHCPREQUEST 到 255.255.255.255 埠 67
7 月 11 日 20:45:46 gw dhclient:來自 88.113.75.2 的 DHCPACK
7 月 11 日 20:45:46 gw ifup [592]:來自 88.113.75.2 的 DHCPACK
7 月 11 日 20:45:46 gw logger: virtual1 (REBOOT): IP: -> 88.113.75.59; GW:-> 88.113.75.1

7 月 11 日 20:45:47 gw dhclient:virtual0 上的 DHCPREQUEST 到 255.255.255.255 埠 67
7 月 11 日 20:45:47 gw ifup [582]:虛擬 0 上的 DHCPREQUEST 到 255.255.255.255 埠 67
7 月 11 日 20:45:47 gw dhclient:來自 88.113.75.2 的 DHCPACK
7 月 11 日 20:45:47 gw ifup [582]:來自 88.113.75.2 的 DHCPACK
7 月 11 日 20:45:47 gw logger: virtual0 (REBOOT): IP: -> 88.113.75.65; GW:-> 88.113.75.1

7 月 11 日 20:45:50 gw dhclient:virtual2 上的 DHCPREQUEST 到 255.255.255.255 埠 67
7 月 11 日 20:45:50 gw ifup [634]:虛擬 2 上的 DHCPREQUEST 到 255.255.255.255 埠 67
7 月 11 日 20:45:50 gw dhclient:來自 88.113.75.2 的 DHCPACK
7 月 11 日 20:45:50 gw ifup[634]:來自 88.113.75.2 的 DHCPACK
7 月 11 日 20:45:50 gw logger: virtual2 (REBOOT): IP: -> 88.113.75.61; GW:-> 88.113.75.1

所以他們工作了,對吧?它們是廣播請求。好的,快進一個小時左右,我們得到了這樣的戰利品:

7 月 11 日 21:45:09 gw dhclient:virtual2 上的 DHCPREQUEST 到 195.74.6.55 埠 67
7 月 11 日 21:45:11 gw dhclient:virtual1 上的 DHCPREQUEST 到 195.74.6.55 埠 67
7 月 11 日 21:45:22 gw dhclient:虛擬 2 上的 DHCPREQUEST 到 195.74.6.55 埠 67
7 月 11 日 21:45:25 gw dhclient:virtual1 上的 DHCPREQUEST 到 195.74.6.55 埠 67
7 月 11 日 21:45:32 gw dhclient:virtual1 上的 DHCPREQUEST 到 195.74.6.55 埠 67
7 月 11 日 21:45:43 gw dhclient:虛擬 2 上的 DHCPREQUEST 到 195.74.6.55 埠 67
7 月 11 日 21:45:46 gw dhclient:virtual1 上的 DHCPREQUEST 到 195.74.6.55 埠 67
7 月 11 日 21:45:56 gw dhclient:virtual2 上的 DHCPREQUEST 到 195.74.6.55 埠 67
7 月 11 日 21:46:05 gw dhclient:virtual1 上的 DHCPREQUEST 到 195.74.6.55 埠 67
7 月 11 日 21:46:11 gw dhclient:虛擬 2 上的 DHCPREQUEST 到 195.74.6.55 埠 67
7 月 11 日 21:46:21 gw dhclient:virtual1 上的 DHCPREQUEST 到 195.74.6.55 埠 67
7 月 11 日 21:46:30 gw dhclient:虛擬 2 上的 DHCPREQUEST 到 195.74.6.55 埠 67
7 月 11 日 21:46:33 gw dhclient:virtual1 上的 DHCPREQUEST 到 195.74.6.55 埠 67
7 月 11 日 21:46:42 gw dhclient:virtual2 上的 DHCPREQUEST 到 195.74.6.55 埠 67
7 月 11 日 21:46:47 gw dhclient:virtual1 上的 DHCPREQUEST 到 195.74.6.55 埠 67
7 月 11 日 21:47:00 gw dhclient:virtual2 上的 DHCPREQUEST 到 195.74.6.55 埠 67
7 月 11 日 21:47:01 gw dhclient:virtual1 上的 DHCPREQUEST 到 195.74.6.55 埠 67
7 月 11 日 21:47:09 gw dhclient:virtual1 上的 DHCPREQUEST 到 195.74.6.55 埠 67

virtual1 和 virtual2 介面拼命嘗試通過單播連接到以前的 DHCP 伺服器 195.74.6.55 來更新它們的 IP。他們失敗了單播。但是接下來發生了一些有趣的事情,最後他們切換到廣播作為備份並成功了!

7 月 11 日 22:30:41 gw dhclient:virtual1 上的 DHCPREQUEST 到 195.74.6.55 埠 67
7 月 11 日 22:30:47 gw dhclient:virtual2 上的 DHCPREQUEST 到 195.74.6.55 埠 67
7 月 11 日 22:30:52 gw dhclient:virtual1 上的 DHCPREQUEST 到 255.255.255.255 埠 67
7 月 11 日 22:30:52 gw dhclient:來自 88.113.75.2 的 DHCPACK
7 月 11 日 22:30:52 gw logger: virtual1 (RENEW): IP: 88.113.75.59 -> 88.113.75.59; GW: 88.113.75.1 -> 88.113.75.1

7 月 11 日 22:30:58 gw dhclient:虛擬 2 上的 DHCPREQUEST 到 255.255.255.255 埠 67
7 月 11 日 22:30:58 gw dhclient:來自 88.113.75.2 的 DHCPACK
7 月 11 日 22:30:59 gw logger: virtual2 (RENEW): IP: 88.113.75.61 -> 88.113.75.61; GW: 88.113.75.1 -> 88.113.75.1

觀察 virtual0 介面:

7 月 11 日 22:38:17 gw dhclient:虛擬 0 上的 DHCPREQUEST 到 195.74.6.55 埠 67
7 月 11 日 22:38:18 gw dhclient:來自 195.74.6.55 的 DHCPACK
7 月 11 日 22:38:18 gw logger: virtual0 (RENEW): IP: 88.113.75.65 -> 88.113.75.65; GW: 88.113.75.1 -> 88.113.75.1

結論是,對於 virtual0 介面,單播 (dhclient) DHCP 請求有效,而對於 virtual1 和 virtual2,僅廣播 DHCP 更新有效。所以,一定是路由問題吧?以下是典型啟動後 ip route 顯示的內容:

root@gw:~# ip 路由
預設通過 88.113.75.1 dev virtual0
88.113.75.0/24 dev virtual0 proto 核心範圍連結 src 88.113.75.65
88.113.75.0/24 dev virtual1 proto 核心範圍連結 src 88.113.75.59
88.113.75.0/24 dev virtual2 proto 核心範圍連結 src 88.113.75.61
172.16.8.0/28 via 172.16.8.2 dev tun0 # 對於 openvpn
172.16.8.0/24 dev eth2 proto kernel scope link src 172.16.8.254 # For LAN
172.16.8.2 dev tun0 proto kernel scope link src 172.16.8.1 #For openvpn

如何使基於 macvlan 的介面 virtual1 和 virtual2 上的 dhclient 正確路由其單播續訂請求並正確接收響應?

我已經完成了大量的Google搜尋,試圖觸發許多設置,包括防火牆策略、基於策略的路由、eth0 promisc 模式和 sysctl 變數、剝離通用網路設置等。我目前正在 dhclient 上進行 strace。這些設置的一種組合必須有效。如果需要更多資訊,我很樂意提供。

EDIT1:dhclient strace 已準備就緒。

這發生在一開始:

綁定(5, {sa_family=AF_PACKET, proto=0x7669, if1635087474, pkttype=PACKET_HOST, addr(0)={12652, }, 16) = 0
綁定(6, {sa_family=AF_INET, sin_port=htons(68), sin_addr=inet_addr("0.0.0.0")}, 16) = 0
sendto(5, "......", 342, 0, {sa_family=AF_PACKET, proto=0x7669, if1635087474, pkttype=PACKET_HOST, addr(0)={12652, }, 18) = 342

據我了解,“sendto(5”) 是第一個成功的基於廣播的 dhclient 發送。

然後,稍後第一個失敗的單播發送:

sendto(6, "......", 300, 0, {sa_family=AF_INET, sin_port=htons(67), sin_addr=inet_addr("195.74.6.55")}, 16) = 300

並且下一個成功的廣播發送:

sendto(5, "......", 342, 0, {sa_family=AF_PACKET, proto=0x7669, if1635087474, pkttype=PACKET_HOST, addr(0)={12652, }, 18) = 342

我能夠修復它!以一種非正統的方式,但仍然如此。

那我做了什麼?**我只是解除安裝了 isc-dhcp-client 4.3.1 並安裝了 dhcpcd 6.0.5(由 Roy Marples,debian 包名稱 dhcpcd5)。**就是這樣。

我在大約 23:00 重新啟動機器並檢查所有介面是否正常,然後設置 tcpdump 執行。在 00:02 左右,其中一個 DHCP 計時器到期,所有 3 個介面都整齊地獲得了它們的 IP 地址,沒有提出任何問題:

https://i.stack.imgur.com/xGQpq.png

基本上我不需要更改 /etc/dhcpcd.conf 中的任何內容。似乎 dhcpcd 的建構方式比 dhclient 更智能。至少在我的情況下。

(旁注:我必須說從 isc-dhcp-client 遷移到 dhcpcd 非常容易。Debian 8 具有內置支持;似乎如果您安裝 dhcpcd5 並刪除 isc-dhcp-client 並重新啟動,系統會選擇自動新客戶端。關於腳本,似乎沒有 dhcpcd 的腳本目錄,但所有進入掛鉤的單個文件和所有退出掛鉤的單個文件。文件名為:/etc/dhcpcd.enter-hook 和 /etc/dhcpcd。 exit-hook 。如果您將 dhclient 掛鉤腳本放入這些文件中,它們無需修改即可工作。我印象深刻!)

引用自:https://serverfault.com/questions/1025085