Iptables

將 UDP 單播數據包轉換為廣播?

  • September 29, 2020

我們需要從 Internet 喚醒我們內部 LAN 上的一些電腦。

我們有一個有點封閉的路由器,配置它的方法很少。

我想使用 netfilter (iptables) 來做到這一點,因為它不涉及守護程序或類似的,但其他解決方案都可以。

我的想法是:

  • 外部電腦向公共 IP 地址發出 WOL(Wake-On-LAN)數據包(內部帶有正確的 MAC)
  • 路由器上打開了正確的埠(比如 1234),將數據重定向到 Linux 機器
  • Linux機器將UDP單播包轉換為廣播包(內容完全相同,只是目的地址修改為255.255.255.255或192.168.0.255)
  • 多播數據包到達每個 NIC,並且所需的電腦現在處於喚醒狀態

為此,一個非常簡單的 netfilter 規則是:

iptables --table nat --append PREROUTING --in-interface eth+ --protocol udp --destination-port 1234 --jump DNAT --to-destination 192.168.0.255

唉,netfilter 似乎忽略了向廣播的轉換。192.168.0.255 和 255.255.255.255 什麼也沒有。還使用 192.168.0.0 和 0.0.0.0 進行了測試,

我使用 tcpdump 來查看會發生什麼:僅此

tcpdump -n dst port 1234

13:54:28.583556 IP www.xxx.yyy.zzz.43852 > 192.168.0.100.1234: UDP, length 102

而已。我應該有第二行,例如:

13:54:28.xxxxxx IP www.xxx.yyy.zzz.43852 > 192.168.0.255.1234: UDP, length 102

如果我重定向到非多播地址,一切正常。我有 2 條預期的線路。但顯然這不適用於 WOL。

有沒有辦法告訴 netfilter 發出廣播數據包?

我想到的其他方法:

  • 使用 iptables 匹配所需的數據包,記錄它們,並使用守護程序監控日誌文件並觸發廣播數據包
  • 使用 iptables 將所需的數據包重定向到本地守護程序,該守護程序會觸發廣播數據包(更簡單)
  • 使用 socat(如何?)

socat是一個殺手級實用程序。把它放在你的初始化腳本的某個地方:

socat -u -T1 UDP-LISTEN:1234,fork,range=<ip address of source>/32 UDP-DATAGRAM:255.255.255.255:5678,broadcast

一些使用者在使用 UDP-LISTEN 時遇到問題,因此使用 UDP-RECV 似乎更好(警告:可能會在無限循環中發送廣播數據包):

socat -u UDP-RECV:1234 UDP-DATAGRAM:255.255.255.255:5678,broadcast
  • fork允許socat繼續監聽下一個數據包。
  • T1將分叉子程序的生命週期限制為 1 秒。
  • range``socat只監聽來自這個源的數據包。假設這是另一台電腦而不是socat正在執行的電腦,這有助於它socat不收聽自己的廣播數據包,這將導致無限循環。
  • 255.255.255.255比 更一般192.168.0.255。讓您只需複制粘貼即可,無需考慮目前的網路結構。警告:這可能會將廣播的數據包發送到每個介面。

正如您一樣,我注意到 WOL 適用於任何埠。我想知道這是否可靠。很多文件只討論埠 0、7 和 9。

這允許使用非 pileged 埠,因此您可以socat使用 user執行nobody

感謝@lgeorget @Hauke Laging 和@Gregory MOUSSAT 參與了這個答案。

引用自:https://unix.stackexchange.com/questions/77874