Debian 區域網路喚醒包轉發?
我有一個解開框(下面是 debian 10),我試圖將 WOL 數據包從一個子網中的主機轉發到另一個子網中的主機。
我最初的解決方案是使用 knockd,在一個子網上的一個介面上偵聽 syn 數據包,然後在另一個子網上執行 etherwake 命令以喚醒主機。我將使用 netcat 從第一個子網中的 linux 伺服器發送 syn 數據包,將數據包發送到網關 IP(解開框)。
問題是,發往 FW 本身的流量最初是在未定址的 vlan 介面上處理的。有點奇怪,syn 數據包只在未定址的介面上看到,然後所有其他數據包都在實際定址的 vlan 介面上看到。我已經用 tcpdump 確認了這一點。它打破了我使用 knockd 的計劃,因為 knockd 拒絕在沒有 IP 地址的介面上偵聽。
我可以看到 syn 數據包通過 tcpdump 進入未定址的介面,並且 knockd 在後台使用 tcpdump。那麼有沒有辦法強制敲門聽一個未定址的介面呢?
如果 knockd 完全不可能,您將如何在 Debian 10 上實現 WOL 數據包轉發器?
喚醒主機的問題是要向它發送數據包,網路堆棧必須知道 NIC 的 MAC 地址。通常它由ARP動態處理。如果 MAC 條目已從路由器的 ARP 表中逐出,則當主機處於睡眠狀態時,它無法回答 ARP 查詢,因此路由器無法獲得到達睡眠主機所需的 MAC 地址以向其發送 WOL 魔術包™ 即使此類數據包在其有效負載中包含該 MAC 地址的 16 倍。
這裡有兩種方法可以克服這個問題,只依賴於網路堆棧(以及iptables或tc之類的伙伴)。
永久ARP
由於路由器上有控制權,因此可以在路由器上為休眠的主機設置一個永久的 ARP 條目。這樣之前的問題就不會發生了。路由器現在可以輕鬆發送或轉發 WOL Magic Packet™,而無需在任何地方使用任何廣播。使用 NAT 來“埠轉發”,遠端主機可以使用
wakeonlan
命令(而不是etherwake
命令,因為它可以更改 UDP 埠)。因此,休眠的主機需要一個靜態地址(或一個具有永久 DHCP 租約的地址)。假設路由器上的 WAN 地址是wan0上的 192.0.2.2 ,路由器上的 LAN 端是介面lan0上的 192.168.1.1/24 和 MAC 地址為 12:34:56 的介面上的睡眠主機 192.168.1.101/24 :78:9a:bc。
在路由器上:
ip neighbour replace 192.168.1.101 lladdr 12:34:56:78:9a:bc dev lan0 nud permanent
由於不清楚 NIC 接收到的數據包是否會被消耗或仍然正確地可供喚醒主機使用,因此通常選擇埠 9,因為這是丟棄服務,以防它“執行”並且兩者都相同。如果需要,請選擇 9 以外的其他埠。休眠主機上的這個埠最好是未使用和防火牆(丟棄數據包),或者實際執行丟棄服務。當一個埠映射到一個目標時,如果有多個 WOL 主機,每個主機應該有一個不同的埠。
通過選擇不是lan0介面的所有介面來解決第一個數據包到達 OP 描述中其他地方的問題。
所以仍然在路由器上,使用iptables,做 DNAT 並允許重定向的數據包:
iptables -t nat -I PREROUTING ! -i lan0 -p udp --dport 9 -j DNAT --to-destination 192.168.1.101 iptables -I FORWARD -m conntrack --ctstate DNAT -d 192.168.1.101 -j ACCEPT
Internet 上的遠端主機現在可以這樣做來喚醒休眠的主機:
wakeonlan -i 192.0.2.2 -p 9 12:34:56:78:9a:bc
系統集成取決於用於網路配置的方法。例如,如果它配置了
interfaces
ifupdown *,*這兩個iptables
命令可以作為pre-up
命令添加到iface lan0 ...
節中(並在命令中刪除down
)和ip neighbour
asup
命令。定向子網廣播(自核心 4.19 起)
工具總是可以選擇使用廣播數據包,這些數據包最終會作為廣播乙太網幀到達所有主機,包括目標主機。
這可以在路由時完成,但涉及更多風險(包括參與反射攻擊)。使用前請考慮安全性。
定向子網廣播必須在全域範圍內且在接收 WAN 介面(而不是目標 LAN 介面)上啟用。如果可能有多個 WAN 介面(OP 描述的數據包首先到達一個介面,然後是另一個),請在所有相關人員上啟用它。
sysctl -w net.ipv4.conf.all.bc_forwarding=1 sysctl -w net.ipv4.conf.wan0.bc_forwarding=1
添加 NAT 和 FORWARD 規則:
iptables -t nat -I PREROUTING ! -i lan0 -p udp --dport 9 -j DNAT --to-destination 192.168.1.255 iptables -I FORWARD -m conntrack --ctstate DNAT -d 192.168.1.255 -j ACCEPT
作為限制風險的一種選擇,最後使用tc將 IPv4 乙太網幀(ethertype 0x800)轉換為用於 WOL 的事實上的 ethertype 0x842 ,因此網路堆棧(但不會被 WOL NIC)忽略結果。可以使用 iptables 設置的標記,或者這裡只考慮 IP 目標和 UDP 目標埠 9。如果 Untangle 使用前一種方法會與標記發生衝突,如果 Untangle 使用tc進行 QoS,任何一種方法都會發生衝突。
tc qdisc add dev lan0 root handle 1: prio # simple classful qdisc used only to enable filters tc filter add dev lan0 parent 1: protocol ip basic match ' cmp (u32 at 16 layer network eq 0xc0a801ff) and cmp (u8 at 9 layer network eq 17) and cmp (u16 at 2 layer transport eq 9) ' action skbmod set etype 0x842
以上,
- u32 在 16 層網路 eq 0xc0a801ff 表示 IP 地址目標 192.168.1.255,
- u8 在 9 層網路 eq 17 表示 UDP,
- u16 at 2 layer transport eq 9 表示目的埠 9。
- 並且由此產生的動作是將 ethertype 更改為 0x842
同樣,Internet 上的遠端主機現在可以這樣做來喚醒睡眠主機:
wakeonlan -i 192.0.2.2 -p 9 12:34:56:78:9a:bc
但它每次都會針對整個 LAN,因此當有多個睡眠 WOL 主機時,保持相同的埠並僅更改 MAC 地址就足夠了。
其他需要考慮的方法:
fwknopd
安裝在服務端和fwknop
安裝在客戶端實現了加密的單包授權機制來觸發命令。它可以用來觸發路由器上的執行wakeonlan
/ 。etherwake