搜尋此網誌

2026年11月13日 星期五

Linux Wake On LAN

緣起:


    之後會去台中一段時間,新的工作,在那邊做為期 1~2 個月的教育訓練,要住在他們的員工宿舍。我想要人在外頭時還能存取我家裡的那些電腦,我的 raspberry pi 有裝 zero-tier vpn,就靠 pi 來當跳板機,讓我能透過它再連區網內其它電腦。

    pi 的功耗低,給它整天開著都不是問題,但桌電的話就不太行,我之前有大概量過,閒置時的功耗為 60 ~ 75 瓦左右,感覺讓它一直開著很浪費,不用時就讓它休眠,但電腦休眠後要怎麼再次喚醒呢?之前查過,可以用 Ethernet 的 Wake On LAN 功能,讓電腦的網口收到特殊封包後醒來。

    之前其實有稍微研究一下,但在 BIOS 查看時一直找不到相關的設定,所以就擱置在一旁了。現在非常需要這功能,所以就花了點時間在嘗試,後來也成功了,所以寫個文章來記錄。


BIOS:


    設定的名稱因主機板而異,claude 說會有 Wake on LAN、Power On By PCI-E、Resume by PCI Device,但我那片 gigabyte 的主機板進 BIOS 後,我怎麼找也看不到這幾個東西,但 ErP 倒是有看到,claude 說需要把 ErP 或 Deep Sleep 之類的功能關掉,以免睡眠後網卡斷電。


啟用網卡 WoL:


    安裝 ethtool 工具,查看網卡的 WoL 狀態

sudo ethtool enp5s0 | grep Wake-on


    如果 Wake-on 顯示 d (disable),要把它改成 g (magic packet)。

sudo ethtool -s enp5s0 wol g

    這個設定在重開機後會被重置,所以要再多一步設定,用 NetworkManager,先找出連線名稱

nmcli connection show

    我自己電腦上的是 Wired connection 2,改它


sudo nmcli connection modify "Wired connection 2" 802-3-ethernet.wake-on-lan magic

    用 ethtool 再確認一次網卡的 Wake-On 狀態,是 g 的話就 ok 了。


發送 magic packet:


    要先用 ip addr 查一下網路卡的 MAC 位置,之後用工具喚醒時會用到,然後在同 switch 下的另一台電腦安裝工具 (裝 debian 的 N100 電腦),我一開始是使用 wakeonlan

sudo apt install wakeonlan
wakeonlan aa:bb:cc:dd:ee:ff

    我把我桌電休眠,然後在 N100 電腦上執行指令,沒反應 (!?),所以開始除錯,先是確認桌電的網卡能不能正常收到 magic packet,在桌電上安裝 tcpdump 

    然後跑

sudo tcpdump -i enp5s0 ether proto 0x0842 or udp port 9

    為什麼參數是這樣下?claude 說 -i 是指定網卡介面,ether proto 0x0842 是只顯示乙太網路層協定為 0x0842 的封包,這是 WoL 專用的 EtherType。or udp port 9,或者顯示 UDP 9 port 的封包,很多 WoL 工具是把 magic packet 包在 UDP 裡,送到 9 port。

    我在桌電跑 tcpdump,然後 N100 用 wakeonlan 送封包,tcpdump 完全沒抓到什麼。我後來再去試試 claude 推薦的其它功具,etherwake,執行它需要 root 權限,安裝完後

sudo etherwake -i enp3s0 aa:bb:cc:dd:ee:ff

    用 -i 指定要送出 magic packet 的網路介面,我那台 N100 電腦是 enp3s0,送出指令後,tcpdump 那裡確實有收到 magic packet


    把桌電休眠,然後用 etherwake 送 magic packet,電腦確實成功被喚醒!!


休眠指令:


    在 linux 上要用 terminal 給電腦休眠,可以用 systemctl


    不過用 ssh 連進電腦後下休眠指令,會碰上個問題,就是電腦休眠時不會正常結束 ssh,所以 terminal 會卡住。可以

sudo systemd-run --on-active=5 systemctl suspend
exit

    延遲個 5 秒後再執行 suspend,在這期間內 exit 就行了。


寫成腳本:


    喚醒要記 MAC 位置,然後休眠要打的指令也蠻長的,所以我想說把它們寫成 shell script,放在 Raspberry Pi 裡,這樣比較方便。

    習慣上會把自己用的腳本放在 ~/.local/bin 裡,但我發現我的 Pi 上預設沒有,所以就自己建 + 設定 PATH

mkdir -p ~/.local/bin

    編輯 ~/.bashrc,加入

export PATH="$HOME/.local/bin:$PATH"

    新增 ~/.local/bin/wake-gigabyte 檔,內容

#!/usr/bin/env bash

sudo etherwake -i eth0 aa:bb:cc:dd:ee:ff

    還有 ~/.local/bin/suspend-gigabyte,內容

#!/usr/bin/env bash

ssh birdshiu@192.168.3.3 'sudo systemctl suspend'

    可以用 ssh 主機@ip '指令',ssh 連進去後執行完指令就斷線,這樣也不用再用那個 systemd-run 來多等幾秒。

    用 chmod 把兩個檔案的權限都改成 755,之後就可以直接呼叫 wake-gigabyte 來喚醒桌電、suspend-gigabyte 來休眠桌電。


沒有留言:

張貼留言