Wake-on-LAN: Remote Power Management for Your Homelab
Running servers 24/7 when you only need them occasionally wastes power. A machine that idles at 15 watts costs about $16 per year — multiply that by several servers and it adds up. Wake-on-LAN lets you power machines on remotely when you actually need them, and leave them off the rest of the time.
Photo by William Fonteneau on Unsplash
The concept is straightforward: you send a special network packet (the "magic packet") to the machine's network card, the card recognizes its MAC address in the packet, and it signals the motherboard to power on — even with the machine fully off. The network card stays powered via the 5V standby rail as long as the machine is plugged in.
Requirements
Wake-on-LAN requires support at three levels:
- Power supply: The machine must be plugged in (and PSU switch on). WoL uses standby power from the wall.
- BIOS/UEFI: The WoL option must be enabled. It's usually in Power Management settings.
- Network card: Must support WoL. Almost all modern Intel, Realtek, and Broadcom NICs do.
- Operating system: Must leave the NIC configured to listen for magic packets on shutdown.
Wireless cards technically support WoL but it's unreliable in practice. Use a wired connection.
BIOS/UEFI Configuration
Boot into your BIOS (usually Del, F2, or F12 during POST). Look for a setting named:
- "Wake on LAN"
- "Power On By PCI-E" (if the NIC is PCIe)
- "Resume By LAN"
- "ErP / EuP Ready" — if this is enabled, it disables standby power to USB and PCIe devices, which breaks WoL. Set it to Disabled.
Save and reboot. The setting location varies by motherboard — consult your manual if you can't find it.
On Intel NUCs and some mini-PCs, WoL is enabled by default with no BIOS option exposed.
Linux Configuration
After the BIOS is configured, the OS needs to leave the NIC in WoL mode on shutdown. Use ethtool to check and configure this.
First, identify your interface name:
ip link show
Common names: eth0, enp3s0, eno1. Avoid using the loopback (lo).
Check current WoL status:
ethtool enp3s0 | grep Wake-on
Output example:
Supports Wake-on: pumbg
Wake-on: d
The Wake-on: d means WoL is currently disabled. The supported modes are:
p— PHY activityu— unicastm— multicastb— broadcastg— magic packet (this is what you want)d— disabled
Enable magic packet mode:
sudo ethtool -s enp3s0 wol g
Verify:
ethtool enp3s0 | grep Wake-on
# Should show: Wake-on: g
Making it persistent: This setting resets on reboot. To make it permanent, use a systemd service or network manager configuration.
With systemd:
# /etc/systemd/system/wol.service
[Unit]
Description=Enable Wake-on-LAN
After=network.target
[Service]
Type=oneshot
ExecStart=/sbin/ethtool -s enp3s0 wol g
RemainAfterExit=yes
[Install]
WantedBy=multi-user.target
sudo systemctl enable wol.service
sudo systemctl start wol.service
With NetworkManager (common on Ubuntu/Fedora desktops):
nmcli connection modify "Wired connection 1" 802-3-ethernet.wake-on-lan magic
This persists through NetworkManager reconnections and reboots.
Like what you're reading? Subscribe to HomeLab Starter — free weekly guides in your inbox.
Sending a Magic Packet
The magic packet is a broadcast frame containing the target MAC address repeated 16 times, preceded by 6 bytes of 0xFF. Several tools can send it.
Install wakeonlan (Debian/Ubuntu):
sudo apt install wakeonlan
wakeonlan AA:BB:CC:DD:EE:FF
Install etherwake:
sudo apt install etherwake
sudo etherwake -i enp3s0 AA:BB:CC:DD:EE:FF
Using Python (no dependencies):
import socket
def wake_on_lan(mac_address):
mac = mac_address.replace(':', '').replace('-', '')
payload = bytes.fromhex('F' * 12 + mac * 16)
with socket.socket(socket.AF_INET, socket.SOCK_DGRAM) as s:
s.setsockopt(socket.SOL_SOCKET, socket.SO_BROADCAST, 1)
s.sendto(payload, ('<broadcast>', 9))
wake_on_lan('AA:BB:CC:DD:EE:FF')
Port 9 is the standard WoL port, though most NICs accept packets on any port.
Finding the MAC Address
On Linux (the target machine, before shutting it down):
ip link show enp3s0 | grep link/ether
Note the MAC address. You'll use this when sending wake packets.
Store it somewhere accessible — your notes, a config file on your router, or a wake script. You can't retrieve it once the machine is powered off.
Sending WoL Over the Internet
Magic packets are broadcast frames and don't route across the internet by default. To wake a machine from outside your network, you need one of:
1. Always-on machine (Raspberry Pi): Keep a low-power device running that can receive an SSH connection from outside and send the magic packet locally. This is the most reliable approach.
# SSH in, then run:
wakeonlan AA:BB:CC:DD:EE:FF
2. Port forwarding to the broadcast address: Forward an external UDP port to 255.255.255.255 (or your subnet broadcast address like 192.168.1.255) on port 9. Some routers support this.
3. VPN with access to your LAN: If you have a VPN server on your network (WireGuard, OpenVPN), connect to it and send the magic packet as if you were local.
4. Directed broadcast: If your router supports it, send the magic packet to your subnet's broadcast address from outside. Often blocked by ISPs.
For most homelabs, option 1 (Raspberry Pi as a wake server) is the most reliable. A Pi Zero 2 W uses about 1W idle — negligible compared to the machines it manages.
Automating Startup Sequences
If you run services that depend on each other (NAS → NFS clients, for example), you may want to automate bringing them up in order.
A simple approach: a shell script that sends WoL packets with delays and verifies the machine came up before continuing:
#!/bin/bash
wakeonlan AA:BB:CC:DD:EE:FF # NAS
# Wait for NAS to respond to ping (max 2 minutes)
for i in $(seq 1 24); do
if ping -c1 -W2 192.168.1.50 &>/dev/null; then
echo "NAS is up"
break
fi
sleep 5
done
# Start dependent services
ssh server2 "sudo mount -a"
Troubleshooting
Packet is sent but machine doesn't wake:
- Confirm WoL is enabled in BIOS — recheck, this is the most common issue
- Confirm
ethtoolshowsWake-on: g(magic packet) immediately before shutting down - Check whether the NIC requires
gorGmode — case matters on some drivers - Ensure the machine is connected by wire, not Wi-Fi
- Try
etherwake -bto send as a broadcast frame instead of directed - Check if the power supply switches off completely at the wall (some surge protectors kill standby)
Works locally but not from internet:
- Verify the magic packet is arriving (capture with
tcpdumpon a machine that stays on) - Check firewall rules on the always-on device aren't blocking UDP port 9
Works once, stops working:
Some NICs drop out of WoL mode if the machine crashes or hard-powers off. Add a power-on script that re-runs ethtool -s enp3s0 wol g on boot to ensure it's always set.
Energy Savings
With WoL in place, you can leave servers off by default and power them on only when needed. At 15W idle and $0.12/kWh:
- 24/7: ~$16/year per machine
- 8 hours/day: ~$5/year
- On-demand (2 hours/day average): ~$1.30/year
For a homelab with five machines, on-demand power management could save $50-70/year while maintaining full remote access.
