Using Wake on LAN with Linux

By Rainer Wichmann rainer@nullla-samhna.de    (last update: Mar 20, 2022)

Due to the ongoing Covid-19 pandemic, there has been a shift towards working from home in many workplaces. As a result, there are workplaces where PCs are quietly humming - and consuming energy - just because people need to be able to access them from home eventually, and nobody is around to switch them on.

This is one of the scenarios where Wake-on-LAN (WoL) can be helpful to save energy. WoL means that the machine can be woken from suspend / poweroff by sending it a message over the network. It is probably safe to say that (almost?) all current PCs support Wake-on-LAN, and have so for years. Unfortunately, that does not mean that there aren't any issues along the way if you want to make use of this capability.

Here I'll discuss the steps needed to successfully wake up a Linux machine from suspend / poweroff. This is tested on Ubuntu, but other Linux variants like RHEL might be not much different.

Step 1) Enable Wake-on-LAN in the BIOS

While the WoL capability usually exists, it is rarely enabled by default. Rather, it has to be switched on in the BIOS:

  1. Reboot the machine an get into the BIOS (usually by pressing the F2 key at the appropriate moment during reboot)
  2. Look for the power management options. These are usually called something like "Power", "APM", or "Power management". On ASUS mainboards, you need to switch to "Advanced" first.
  3. There are two power management setting that you need to pay attention to.
    1. First ist the Wake-on-LAN setting. On ASUS mainboards, this is named "Wake on PCI/PCI-E", just to add some confusion I guess. You want to set this to enabled.
    2. Second is the deep sleep option. This option does not exist in all BIOS variants, but where it exists, it is usually enabled by default and will prevent WoL from working. If there is an option for deep sleep, you need to set it to disabled.
  4. Save the modified settings and exit the BIOS to boot the machine.

Step 2) Enable Wake-on-LAN on the network interface

The next step is to check whether the network interface is set to have WoL enabled, and enable it if neccessary. This requires the ethtool command, which may not be part of the base installation, so you want to install it first:
sudo apt install ethtool

Next, you need the name of the network interface. The command to find the interface used to connect to a remote host is: ip route get <remote IP address>
Example:

bash$ ip route get 8.8.8.8
8.8.8.8 via <gateway address> dev eno1 src <eno1 address> uid <your user id>
Here, the name of the network interface is eno1.

You can now check that network interface with the command sudo ethtool <interface name>. The important lines to look for are:


	Supports Wake-on: <letters>
	Wake-on: <letter>
where the first line says what capabilities the interface has, and the second one, what it is currently set to. Note that the first line (Supports Wake-on) must contain 'g' among <letters>, and the second line (Wake-on) must contain 'g' and NOT 'd'.
Here is an example with Wake-on-LAN supported and enabled:

	Supports Wake-on: pumbg
	Wake-on: g

If the interface supports WoL, but it is not enabled by default, you can enable it with this command:
ethtool -s <interface name> wol g.
However, the interface will usually get reset on boot, i.e. the setting will get lost. To avoid this, you need to re-enable WoL after boot. There several different ways to achieve this:

(A) Oldschool and configuration independent

Create a file /etc/rc.local and make it executable:


	sudo touch /etc/rc.local
	sudo chmod +x /etc/rc.local
Then, edit the file with your preferred editor, e.g. vi or nano, so that it contains the following three lines:

#!/bin/sh -e
ethtool -s <interface name> wol g
exit 0

A slight disadvantage of this method is that it only runs the ethtool command at boot, not when you turn off/on the interface while the system is running.

(B) Modern but netplan-specific

Ubuntu 20+ uses netplan to manage network interfaces. Netplan doesn't currently support post-up scripts to run after the interface has been brought up. However, you can use networkd-dispatcher for that:


	sudo touch /etc/networkd-dispatcher/routable.d/50-wol-enable
	sudo chmod +x /etc/networkd-dispatcher/routable.d/50-wol-enable
Then, edit /etc/networkd-dispatcher/routable.d/50-wol-enable to fill it with the same three lines as shown in the preceding section for /etc/rc.local.
Note that it's up to you how you name the script, but the name must consist entirely of upper and lower case letters, digits, underscores, and hyphens. E.g. you can't name the script foobar.sh because that would have a dot in the name.

The slight disadvantage of this method is that it is specific to netplan, and there is a tendency among Linux distributions to replace system configuration tools - as soon as they are somewhat mature - with new tools. Which will eventually get replaced again once they are mature and working well ;-).

(C) Slightly less modern and ifupdown-specific

The ifupdown facility is an older method to bring a network interface up or down. At least on Ubuntu, it has been superseded by netplan.

With ifupdown, you can write a script to run after the interface has been brought up, just as for netplan (see preceding section), but the script now needs to be placed into the directory /etc/network/if-up.d/.

Alternatively, you can locate the stanza for the network interface in the file /etc/network/interfaces, and add a line up ethtool -s <interface name> wol g to it, as shown in the following example (note that the stanza for each interface begins with the line iface <interface name> ..., eventually followed by options given on subsequent lines in the stanza):


auto eno1

iface eno1 inet dhcp
    up ethtool -s eno1 wol g

Step 3) Test that wake-on-lan actually works

Wake on LAN is performed by sending a 'magic packet' to the computer you want to wake. This 'magic packet' needs to contain the hardware (MAC) address of the network interface, which therefore must be known. You can find the MAC address e.g. with the command
cat /sys/class/net/<interface name>/address
or with
ip link show <interface name>.

On Ubuntu, there are two tools available for sending the 'magic packet' to wake up a computer, both of which have some issue:

A) etherwake

With etherwake, you can use hostnames instead of MAC addresses if you have a file /etc/ethers that contains a mapping of MAC addresses to hostnames, one line for each host:
MAC hostname
Unfortunately, etherwake seems to have problems sending the 'magic packet' across a network switch (this might depend on the configuration of the switch, but at least you can't rely on it).

B) wakeonlan

The wakeonlan command can reliably send the 'magic packet' across a network switch, but inconveniently doesn't use the /etc/ethers file. Also, the most reliable way to send the packet is to specify both the host IP address (rather than broadcasting the packet) and the MAC address:


sh$ sudo wakeonlan -i <IP address> <MAC address>

Your mileage may vary, e.g. you might be able to use the gateway IP address instead of the IP address of the host you want to wake.

Creative Commons License
This work is licensed under a Creative Comm ons Attribution-NonCommercial-ShareAlike 2.0 Germany License.