Wake-on-LAN

出自 Arch Linux 中文维基

網絡喚醒(Wake-on-LAN,WoL)是一個通過網絡來打開計算機的功能。

硬體設置[編輯 | 編輯原始碼]

網絡喚醒只在滿足以下前提條件時有效:

  1. 目標計算機的主板和網卡支持網絡喚醒。
  1. 目標計算機必須物理地連接(使用線纜)到一台路由器或者源計算機才能讓網絡喚醒正常工作,除非你的無線網卡支持無線喚醒(WoWLAN或WoW)。

你需要在你的BIOS或UEFI中準備:

  1. 啟用網絡喚醒功能。不同的主板製造商使用稍微不同的語言來描述這項功能。查找像是「PCI Power up」「Allow PCI wake up event」或「Boot from PCI/PCI-E」的術語。
  1. 如果在BIOS/UEFI中可用,確保ErP禁用的,否則你的網卡將不會有電並且將不會從其他設備受到任何網絡喚醒包。
注意:
  • 有些主板在關機狀態下支持網絡喚醒,但有的主板只在睡眠或掛起狀態下支持網絡喚醒。
  • 一些主板受到一個Bug的影響,導致當BIOS的網絡喚醒功能啟用時立刻或隨機在關機後喚醒。

軟體設置[編輯 | 編輯原始碼]

在網卡上啟用網絡喚醒[編輯 | 編輯原始碼]

根據硬體的不同,網卡驅動可能默認關閉網絡喚醒。

要查詢或更改這項設置,安裝ethtool,確定網絡配置#網絡接口的名字,並用以下命令來查詢:

# ethtool interface | grep Wake-on
Supports Wake-on: pumbag
Wake-on: d

Wake-on定義了觸發喚醒的活動:d(禁用)、p(PHY活動)、u(單播活動)、m(多播活動)、b(廣播活動)、a(ARP活動)和g(魔術包活動)。 網絡喚醒工作需要值為g,如果不是,使用以下命令啟用網卡驅動的網絡喚醒功能:

# ethtool -s interface wol g
注意: 為了啟用該功能,可能還需要設置umb中的一個以及g

此命令的操作在下一次重啟之後可能不會保留,在這種情況下,必須通過某種機制來重複執行。下面列出了常見的解決方案。

讓其持久[編輯 | 編輯原始碼]

systemd.link[編輯 | 編輯原始碼]

可以通過systemd-networkd#link文件進行link-level配置。實際配置由udevnet_setup_link內置程序執行。向網絡link文件中添加WakeOnLan

/etc/systemd/network/50-wired.link
[Match]
MACAddress=aa:bb:cc:dd:ee:ff

[Link]
NamePolicy=kernel database onboard slot path
MACAddressPolicy=persistent
WakeOnLan=magic

另請參閱systemd.link(5)以獲取更多信息。

注意:
  • 僅應用第一個匹配的文件。必須包括systemd附帶的連結文件/usr/lib/systemd/network/99-default.link的內容,否則接口可能配置錯誤。
  • 需要考慮的是,文件名應該按順序放在默認的99-default.link之前,例如50-wired.link就可以。
  • 此配置僅適用於link級別,並且獨立於像是NetworkManagersystemd-networkd這樣的network級別守護程序。
  • Match部分,OriginalName=也可以用於識別接口。

systemd service[編輯 | 編輯原始碼]

這相當於前面的systemd.link選項,但使用獨立的systemd服務。

/etc/systemd/system/wol@.service
[Unit]
Description=Wake-on-LAN for %i
Requires=network.target
After=network.target

[Service]
ExecStart=/usr/bin/ethtool -s %i wol g
Type=oneshot

[Install]
WantedBy=multi-user.target

或者安裝wol-systemdAUR,然後啟動激活這個新服務wol@接口.service

udev[編輯 | 編輯原始碼]

udev能夠在設備可見時立即運行任何命令。以下規則將在名稱與en*匹配的所有網絡接口上打開網絡喚醒。文件名很重要,它必須以81到99之間的數字開頭,這樣它才能在80-net-setup-link.rules之後運行,後者用可預測的名稱重命名接口,否則NAME將未定義,規則將不會運行。

/etc/udev/rules.d/81-wol.rules
ACTION=="add", SUBSYSTEM=="net", NAME=="en*", RUN+="/usr/bin/ethtool -s $name wol g"

$name占位符將替換為匹配設備的NAME變量的值。

cron[編輯 | 編輯原始碼]

每次使用crontab中的"@reboot"重啟計算機時,都可以運行一個命令。首先,確保啟用cron,然後為root用戶編輯含以下行的crontab:

@reboot /usr/bin/ethtool -s interface wol g

netctl[編輯 | 編輯原始碼]

如果使用netctl,可以通過添加以下netctl配置文件使此設置永久化:

/etc/netctl/profile
ExecUpPost='/usr/bin/ethtool -s interface wol g'

NetworkManager[編輯 | 編輯原始碼]

NetworkManager提供網絡喚醒支持。通過魔術包啟用網絡喚醒的一種方式是通過nmcli

首先,搜索有線連接的名稱:

# nmcli con show
NAME    UUID                                  TYPE            DEVICE
wired1  612e300a-c047-4adb-91e2-12ea7bfe214e  802-3-ethernet  enp0s25

通過以下操作可以查看網絡喚醒設置的當前狀態:

# nmcli c show "wired1" | grep 802-3-ethernet.wake-on-lan
802-3-ethernet.wake-on-lan:             default
802-3-ethernet.wake-on-lan-password:    --

在連接上啟用魔術包網絡喚醒:

# nmcli c modify "wired1" 802-3-ethernet.wake-on-lan magic

然後重啟,可能是兩次。要禁用網絡喚醒,使用ignore替換magic

使用nm-connection-editorGUI也可以更改網絡喚醒設置。

你可以通過添加一個專用的配置文件來為所有連接永久禁用網絡喚醒:

/etc/NetworkManager/conf.d/wake-on-lan.conf
[connection]
ethernet.wake-on-lan = ignore
wifi.wake-on-wlan = ignore

在TLP啟用網絡喚醒[編輯 | 編輯原始碼]

當使用TLP進行掛起或休眠時,/etc/tlp.conf中的WOL_DISABLE設置必須設置為N來允許使用網絡喚醒來恢復電腦。

觸發喚醒[編輯 | 編輯原始碼]

要觸發目標設備的網絡喚醒,必須知道它的MAC地址。要獲取它,在設備商執行下面的命令:

$ ip link
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default
   link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
2: enp1s0: <BROADCAST,MULTICAST,PROMISC,UP,LOWER_UP> mtu 1500 qdisc fq_codel master br0 state UP group default qlen 1000
    link/ether 48:05:ca:09:0e:6a brd ff:ff:ff:ff:ff:ff

這裡的MAC地址是48:05:ca:09:0e:6a

在最簡單的形式中,網絡喚醒將魔術包作為乙太網幀進行廣播,其中包含當前網絡子網中IP協議層下方的MAC地址。不需要了解IP位址,因為它在第二層(數據鏈路層)上運行。

如果用於通過網際網路或其它子網喚醒計算機,通常依賴路由器中繼數據包並進行廣播。在這種情況下,路由器的外部IP位址必須是已知的。請記住,作為安全措施,大部分路由器默認情況下不會中繼子網定向廣播,需要明確告知這樣做。

能夠為網絡喚醒發送魔術包的應用程式:

  • gWakeOnLAN — 通過網絡喚醒功能來喚醒關閉的電腦的GTK程序。
https://www.muflone.com/gwakeonlan/english/ || gwakeonlan
  • wol — 在一個小的程序中實現區域網喚醒功能。它喚醒服從魔術包的硬體。注意:此應用程式需要需要使用-p參數將埠默認值(40000)改為9。
https://sourceforge.net/projects/wake-on-lan/ || wol
  • wol_qt — 具有集成ARP掃描的Qt程序,用於查找MAC地址和批量發送區域網喚醒數據包。
https://github.com/stefmitropoulos/wol_qt || wol_qtAUR

在同一區域網中[編輯 | 編輯原始碼]

如果你通過網絡線纜直接連接到另一台電腦,或者區域網內的通信沒有防火牆,那麼使用網絡喚醒會很簡單,因為無需擔心埠重定向。

在最簡單的情況下,使用默認廣播地址225.225.225.225

$ wol 目标的MAC地址

要僅將魔術包廣播到特定的子網或主機,請使用-i

$ wol -i target_IP target_MAC_address

通過網際網路[編輯 | 編輯原始碼]

當源計算機和目標計算機被NAT路由器分隔時,可以設想不同的解決方案:

  • 如果路由器支持網絡喚醒,則可以通過它將數據包正確廣播到本地網絡。

否則可以通過埠轉發實現區域網喚醒。路由器需要使用以下兩個選項之一進行配置:

  • 將不同的埠轉發到目標計算機。這需要每台目標計算機在它的區域網有一個靜態的IP。
  • 將單個埠轉發到廣播地址。大多數路由器不允許轉發到廣播,但是你可以通過telnet、SSH、串口(console)或其它方式獲得訪問路由器的shell的權限,並運行下面的命令:
$ ip neighbor add 192.168.1.254 lladdr FF:FF:FF:FF:FF:FF dev net0

此示例假設網絡為192.168.1.0/24,並使用net0作為網絡接口。現在,將UDP埠9轉發到192.168.1.254。該解決方案已在運行Tomato的Linksys WRT54G和Verizon FIOS ActionTec路由器上成功測試。有關如何在具有DD-WRT固件上的路由器執行此操作的說明,請參見這個教程;對於具有OpenWrt固件的路由器,請參閱這個教程

在任何情況下,從源計算機運行以下命令以觸發喚醒:

$ wol -p forwarded_port -i router_IP target_MAC_address

雜項[編輯 | 編輯原始碼]

檢查魔術包的接受情況[編輯 | 編輯原始碼]

為了確保網絡喚醒數據包到達目標計算機,可以監聽UDP埠,通常是埠9,以獲取魔術包。魔術包的幀預計會包含6位元組的FF,之後是目標計算機的16個重複(每個6位元組),總共102位元組。

使用netcat[編輯 | 編輯原始碼]

這可以通過在目標計算機上安裝gnu-netcat並使用以下命令來執行:

# nc --udp --listen --local-port=9 --hexdump

然後等待傳入流量出現在nc終端裡。

注意: 電腦本身的防火牆不需要打開即可網絡喚醒(接口的處理發生在NIC中,在防火牆之前)。但是,為了使用netcat進行調試,你仍然需要臨時打開該埠。

使用ngrep[編輯 | 編輯原始碼]

在目標設備上安裝ngrep並執行下面的命令:

# ngrep '\xff{6}(.{6})\1{15}' -x port 9

網絡喚醒腳本示例[編輯 | 編輯原始碼]

下面是一個說明了在不同的機器上使用網絡喚醒的示例:

#!/bin/bash

# definition of MAC addresses
monster=01:12:46:82:ab:4f
ghost=01:1a:d2:56:6b:e6

echo "Which PC to wake?"
echo "m) monster"
echo "g) ghost"
echo "q) quit"
read input1
case $input1 in
  m)
    /usr/bin/wol $monster
    ;;
  g)
    # uses wol over the internet provided that port 9 is forwarded to ghost on ghost's router
    /usr/bin/wol --port=9 --host=ghost.mydomain.org $ghost
    ;;
  Q|q)
    break
    ;;
esac

故障排除[編輯 | 編輯原始碼]

NetworkManager[編輯 | 編輯原始碼]

網絡適配器在關機時處於斷電狀態[編輯 | 編輯原始碼]

如果通過nmcli配置了網絡喚醒,並且網絡適配器在關機時處於斷電狀態,則將自動協商設置為yes可能會有所幫助。設置使用它:


# nmcli c modify "wired1" 802-3-ethernet.auto-negotiate yes

在關機後喚醒[編輯 | 編輯原始碼]

眾所周知,一些主板會受到一個Bug的影響,無論何時啟用BIOS的網絡喚醒功能(例如這裡所討論的),該錯誤都會導致關機後立即或隨即喚醒。

使用BIOS修復[編輯 | 編輯原始碼]

BIOS首選項中的以下操作可以解決某些主板的問題:

  1. 禁用USB設置中所有對xHCI的引用(注意,這也會在啟動時禁用USB3.0)。
  1. 如果EuP 2013『』是一個明確的選項,禁用它。
  1. 可選地啟用鍵盤喚醒操作。
注意: 對於上面第三條的值,有各種各樣的意見,它可能取決於主板。

通過內核修復[編輯 | 編輯原始碼]

這個問題也可以通過添加xhci_hcd.quirks=270336內核參數來解決。這會激活:

  • XHCI_SPURIOUS_REBOOT
  • XHCI_SPURIOUS_WAKEUP

電池排空的問題[編輯 | 編輯原始碼]

一些筆記本電腦在關機後會出現電池耗盡的問題[1]。這可能由啟用網絡喚醒導致。要解決這個問題,像上面提到的一樣禁用網絡喚醒:

# ethtool -s net0 wol d

瑞昱[編輯 | 編輯原始碼]

使用基於瑞昱8168 8169 8101 8111(C)的NIC(網卡和板載網卡)時,可能會注意到NIC在啟動時似乎被禁用,並且沒有指示燈。請參閱網絡配置/乙太網#Realtek_沒有連接/網絡喚醒故障

如果網絡交換機上的鏈路指示燈在計算機關閉但網絡喚醒仍不工作時啟用,則至少使用r8168內核模塊引導系統一次,然後切換回內核中包含r8169的內核模塊似乎至少可以在以下配置中解決該問題:

  • MSI B85M-E45主板, BIOS版本V10.9, 板載Realtek 8111G 晶片組

對於r8168模塊,你可能需要設置 s5wol=1內核模塊#配置模塊參數 來啟用網絡喚醒功能。

alx驅動支持[編輯 | 編輯原始碼]

對於一些較新的基於Atheros的NIC(如Atheros AR8161和Killer E2500),由於一個導致意外喚醒的Bug,主線alx模塊中的網絡喚醒支持已被禁用(請參閱該討論)。可以使用補丁(使用alx-wol-dkmsAUR包安裝一個dkms模塊),該補丁不僅恢復了網絡喚醒支持,還修復了潛在的錯誤,如這裡所述。

另請參閱預修復補丁的原始碼[2]