By Rainer Wichmann rainer@
la-samhna.de (last update: Aug 06, 2023)Due to the Covid 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:
- Reboot the machine an get into the BIOS (usually by pressing the
F2
key at the appropriate moment during reboot) - 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.
- There are two power management setting that you need to
pay attention to.
- 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
. - 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
.
- 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
- 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. You can send the packet either to the host IP address, or broadcast it
vi the gateway IP address:
sh$ sudo wakeonlan -i <IP address> <MAC address>
sh$ sudo wakeonlan -i <gateway IP address> <MAC address>
Wake-on-lan not working from remote
If you want to wake a remote host (e.g. wake your office machine from home...), you may find that wake-on-lan has problems. In particular, network equipment like switches may not cooperate:
If you send the 'magic packet' directly to the IP address of the host you want to wake, and that host has been off for some time, the switch may have "forgotten" (dropped) the routing information. I.e. your packet will not arrive because the switch doesn't know where to send it.
The obvious solution would appear to broadcast the 'magic packet', i.e. send it to the gateway IP address. Unfortunately, broadcasting arbitrary packets arriving from other network segments isn't a great idea in general, and hence switches are usually configured to disallow it. It is quite likely that broadcast will work only within the local subnet.
One possible solution to this problem would be to have at least one host in the subnet that is always on, and can be used to broadcast wake-on-lan 'magic packets' to other hosts in the same subnet on demand.
This work is licensed under a Creative Comm ons Attribution-NonCommercial-ShareAlike 2.0 Germany License.