是否可以檢查 TCP 連接主機的 MAC 地址(在同一 LAN 上)?
我有一個帶有許多主機的乙太網 LAN (192.168.1.0/24),它們都是由路由器通過 DHCP 分配的地址。由於 DHCP 的設置方式,特定設備的 IP 地址可能會以不可預知的方式發生變化;這是我無法控制的。
有一些程式碼在客戶端主機上執行,它定期通過 TCP 輪詢執行在每個其他主機上的伺服器程序,以從每個主機收集一些指標。客戶端需要能夠可靠地辨識它正在與哪些伺服器通信 - 由於動態 IP 分配,唯一可靠的辨識是基於它們的 MAC 地址。
我已經採取了通常的步驟來獲取每個主機的 MAC->IP 映射:
- 我定期使用 nmap 執行網路掃描,以確保填充 ARP 記憶體
- 在建立與伺服器的每個連接之前,我會在客戶端的 ARP 記憶體中查找 MAC->IP 映射(通過類似這樣的方法)。如果 ARP 記憶體中不存在 MAC,我會強制重新掃描網路。
這在大多數情況下都有效,但由於主機切換 IP 地址,我仍然偶爾會遇到問題。
例如,有一段時間主機 A 的 IP 地址為 192.168.1.101,而主機 B 的 IP 地址為 192.168.1.102。根據 ARP 記憶體和他們的 MAC 地址的知識,我可以分辨出哪個是哪個並相應地輪詢。但偶爾會在刷新 DHCP 租約時重新分配 IP,主機 A 最終將位於 192.168.1.102,而主機 B 現在位於 192.168.1.101。發生這種情況時,客戶端的 ARP 記憶體將不正確。基於上述方法,客戶端仍然會連接到 192.168.1.101,認為它正在讀取主機 A 的指標,而實際上它現在正在與主機 B 交談。
我需要消除這種情況。
我想到了以下三種可能的方法:
- 選項 A:就在連接到主機之前,讓客戶端 ping 它認為它所在的 IP,以強制 ARP 刷新。使用它來檢查它是否即將連接到正確的主機/MAC。
- 選項 B:在 TCP 連接和讀出之後,讓客戶端再次檢查 ARP 表,以確保它實際連接到它認為連接到的 MAC 地址。(據我所見,ARP記憶體應該已經通過連接更新)
- 選項 C:當自己進行 TCP 連接時,檢查客戶端正在連接的遠端 MAC
我很欣賞這是一個冗長的介紹,但我基本上想知道是否有實現選項 C 的實用方法?
如果我檢查 TCP 連接期間主機之間交換的數據包,則會發現各自的 MAC 地址作為乙太網幀的源和目標。所以理論上 - 至少在某種程度上 - 客戶端設備確實知道它正在與之交談的伺服器的特定 MAC。但是有沒有辦法將它暴露給啟動 TCP 連接的程式碼?
在我的上下文中,我有 Python 程式碼在 Linux 主機上使用內置
socket
庫創建連接。我很欣賞答案可能在很大程度上取決於實際環境 - 但我很想听聽有關 MAC 地址如何(或不)暴露於啟動 TCP 連接的程序的任何一般指導。事實上,任何關於基於 MAC 地址連接到主機的可靠方式的指南。
第 3 層和第 4 層的套接字 API 看不到第 2 層 MAC 地址。這需要調查鄰居發現記憶體。(而且您的網路堆棧完全涉及 MAC 地址。儘管 LAN 上的 Linux 機器可能會,但乙太網無處不在。)
ARP 也不是 IPv6 網路的東西。您還應該查看鄰居發現記憶體。不同的事情,即使查詢它的介面是相似的。
MAC 地址在主機表中的主鍵很差,它們不是最穩定或唯一的標識符。主機有多個 NIC。硬體網卡被替換。複製 VM 時,應重新編號來賓 NIC。可能缺少重複項,但不確定。
而是使用長的主機特定標識符。比如一個 UUID,它極有可能是唯一的。例如,systemd 系統具有
/etc/machine-id
.