in howto

Wake-on-LAN werkend krijgen

Wake-on-LAN klinkt op papier doodsimpel. Je stuurt een "magic packet" naar het MAC-adres van een uitgeschakelde machine en de netwerkkaart wekt de PC. In de praktijk loop je hier toch vaak op stuk, en de foutmeldingen helpen je niet altijd verder. Ik liep er onlangs zelf tegenaan en schrijf hieronder op hoe ik het stap voor stap heb uitgezocht.

De situatie

Twee machines in hetzelfde netwerk (192.168.1.0/24). De eerste, ik noem hem hier pc-a (192.168.1.50), is de machine waarmee ik het magic packet wil versturen. De tweede, pc-b (192.168.1.99), is de machine die ik wil wekken. De BIOS van pc-b ondersteunt Wake-on-LAN.

Beide tools stonden al op het systeem.

which wol ether-wake
# /usr/bin/wol
# /usr/bin/ether-wake

Toch deed geen van beide iets.

Het MAC-adres opzoeken

Via de ARP-tabel van pc-a kom ik aan het MAC-adres van pc-b.

ip neigh show
# 192.168.1.99 dev eno1 lladdr aa:bb:cc:dd:ee:ff DELAY

Een kanttekening: een MAC-adres identificeert een specifieke netwerkkaart, net zo herleidbaar als een IP-adres. Deel het dus niet zomaar in logs of screenshots. In dit artikel heb ik het adres vervangen door aa:bb:cc:dd:ee:ff.

Eerste fout: verkeerd gebruik van wol

De voor de hand liggende aanpak gaf meteen een foutmelding.

$ wol -i eno1 aa:bb:cc:dd:ee:ff
wol: Invalid IP address given: Ongeldig argument

De vergissing zat in mijn aanname over de -i vlag. Die heet bij wol ook --ipaddr en dat zegt het eigenlijk al: het is geen interface optie. Het programma verwacht een broadcast IP adres, geen interfacenaam zoals eno1. De juiste aanroep stuurt het pakket naar het broadcastadres van het subnet.

wol -h 192.168.1.255 aa:bb:cc:dd:ee:ff
# Waking up aa:bb:cc:dd:ee:ff with 192.168.1.255:40000...

Tweede fout: ether-wake wil root

$ ether-wake -i eno1 aa:bb:cc:dd:ee:ff
ether-wake: This program must be run as root.

ether-wake stuurt rauwe link layer frames en heeft daarvoor verhoogde rechten nodig.

Met deze twee dingen rechtgezet liepen beide commando's zonder fouten. Alleen werd pc-b nog steeds niet wakker. Dus moest het probleem aan de ontvangende kant zitten.

Bewijs zoeken op de doelmachine

Mijn eerste reflex was de kernel log doorzoeken op iets dat op een wake event leek.

journalctl -k -b 0 | grep -i -E "wake|PME|magic"

Dat leverde regels op zoals deze.

pci 0000:00:1c.0: PME# supported from D0 D3hot D3cold
PM:   Magic number: 14:624:239

Goed om te weten: dit zijn standaard ACPI en PCI capability meldingen die bij elke boot verschijnen, ook als er nooit een magic packet binnenkwam. Het is dus geen bewijs van iets. De meeste netwerkdrivers, denk aan r8169, igb of e1000e, loggen een daadwerkelijke wake via magic packet niet expliciet in dmesg of journalctl.

Wat wel iets zegt:

last reboot laat zien wanneer de machine voor het laatst opstartte, zodat je dat tijdstip kunt vergelijken met het moment waarop je het commando stuurde. ethtool <interface> | grep Wake-on bevestigt of WOL überhaupt staat ingeschakeld in de driver. En op serverhardware met een BMC vind je in ipmitool sel list | grep -i power vaak letterlijk de melding "Power on via WOL".

De echte oorzaak

$ sudo ethtool enp3s0
...
Supports Wake-on: pumbg
Wake-on: d

Daar stond het. De netwerkkaart ondersteunt magic packet wake, te zien aan de g in pumbg, maar de instelling zelf stond op d, disabled. De BIOS stond goed, de Linux driver had het gewoon uitgeschakeld.

WOL inschakelen

sudo ethtool -s enp3s0 wol g
sudo ethtool enp3s0 | grep Wake-on
# Wake-on: g

Dit werkt meteen, maar is niet blijvend. De meeste drivers zetten deze instelling bij elke boot terug op d.

Persistent maken met systemd

Een kleine oneshot service die deze instelling bij elke boot herstelt.

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

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

[Install]
WantedBy=multi-user.target
sudo systemctl daemon-reload
sudo systemctl enable --now wol@enp3s0.service

Klein zijpaadje over een valkuil die ik tegenkwam bij het aanmaken van dit bestand. Ik plakte het via een heredoc, sudo tee ... <<'EOF' ... EOF, en de terminal bleek elke regel automatisch te laten inspringen bij het plakken. Daardoor herkende bash de afsluitende EOF niet meer en bleef de shell wachten met een > prompt. Uiteindelijk stonden er overal voorloopspaties in het bestand, en dat kan systemd parsing van de sectiekoppen laten mislukken. De oplossing was het bestand regel voor regel opbouwen met losse echo commando's, zodat er geen multi line paste meer nodig is.

sudo sh -c '> /etc/systemd/system/wol@.service'
sudo sh -c 'echo "[Unit]" >> /etc/systemd/system/wol@.service'
sudo sh -c 'echo "Description=Enable Wake-on-LAN for %i" >> /etc/systemd/system/wol@.service'
# enzovoort

Waarom werkt dit als de machine uit staat?

Dit vond ik zelf de lastigste vraag. De systemd service draait alleen wanneer de machine aan staat. Hoe helpt dat dan bij het wekken vanuit een uitgeschakelde toestand?

Het antwoord zit in de timing. Terwijl de machine aanstaat, zet de oneshot service bij het opstarten de vlag wol g in de NIC driver. Die vlag zegt eigenlijk: als je straks wordt uitgeschakeld, blijf luisteren naar magic packets. Wanneer de machine vervolgens wordt afgesloten, leest de netwerkdriver die vlag tijdens het shutdown proces en zet de fysieke netwerkchip in een energiezuinige modus die blijft monitoren op binnenkomende frames.

De voeding levert via de standby rail, de 5V lijn die altijd actief is zolang de stekker in het stopcontact zit, een klein beetje stroom aan het moederbord en de netwerkkaart, ook als de machine verder uit staat. Komt er een magic packet binnen met het juiste MAC adres, dan stuurt de netwerkkaart een PME signaal naar het moederbord. Functioneel is dat hetzelfde als het indrukken van de aan uit knop.

De instelling moet dus actief zijn op het moment van uitschakelen, niet erna. Omdat drivers die instelling bij elke boot resetten, moet de systemd service bij elke boot opnieuw draaien zodat de instelling altijd klaarstaat voor de volgende keer dat je de machine afsluit. BIOS en OS driver moeten het overigens allebei toestaan. Blokkeert een van de twee, dan krijgt de netwerkkaart nooit de stroom of toestemming om in die luistermodus te blijven.

Resultaat

sudo ethtool enp3s0 | grep Wake-on
# Supports Wake-on: pumbg
# Wake-on: g

Vanaf pc-a:

wol -h 192.168.1.255 aa:bb:cc:dd:ee:ff

En pc-b start weer op.

Checklist als WOL bij jou niet werkt

Loop dit gewoon van boven naar onder af. Klopt de syntax van je tool? Bij wol gebruik je -h met een broadcastadres, niet -i met een interfacenaam, en ether-wake draai je met sudo. Staat Wake-on-LAN aan in de BIOS of UEFI, soms heet het iets als "Power on by PCI-E"? Geeft ethtool <interface> | grep Wake-on een g terug en geen d? Overleeft die instelling een reboot, of moet je daar een systemd service voor inzetten zoals hierboven? Gaat het om een kabel of WiFi verbinding, want WOL werkt vrijwel nooit over WiFi? En tot slot, heeft je switch agressieve instellingen zoals IGMP snooping of poortstroombesparing die broadcastframes naar slapende poorten kunnen blokkeren?

linuxnetworkingwake-on-lansystemd

Nog geen reacties

Reactie plaatsen

Reacties worden na moderatie gepubliceerd.