Introduction
The typical steps to make your Ubuntu server wake on LAN are:
- Find your network card interface name
- Check your network card capabilities
- Use ethtool to set “Wake-on” option to “g” value
And that’s all, then you put your server in suspend or hibernate mode and wake it up remotely. It works like a charm, but then you try a second time, you hibernate the server again and… it doesn’t wake remotely.
What happened, is that you didn’t repeat the third step to set again the “Wake-on” option to “g” value. The value you set for the network interface is volatile and you have to repeat the third step on each boot… unless you make it sticky.
Setup the network interface to work just once
1.- Find your network card interface name
sudo ip a
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000 link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00 inet 127.0.0.1/8 scope host lo valid_lft forever preferred_lft forever inet6 ::1/128 scope host valid_lft forever preferred_lft forever 2: enp3s0: <NO-CARRIER,BROADCAST,MULTICAST,UP> mtu 1500 qdisc fq_codel state DOWN group default qlen 1000 link/ether e8:94:f6:08:5a:60 brd ff:ff:ff:ff:ff:ff 3: eno1: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc fq_codel state UP group default qlen 1000 link/ether c8:9c:dc:2b:aa:48 brd ff:ff:ff:ff:ff:ff inet 192.168.16.126/24 brd 192.168.16.255 scope global noprefixroute eno1 valid_lft forever preferred_lft forever inet6 fe80::ca9c:dcff:fe2b:aa48/64 scope link valid_lft forever preferred_lft forever
In my case, the server has three interfaces:
1: lo (the local loopback)
2: enp3s0: one 100Mbps ethernet card (not being used)
3: eno1: one 1Gbs ethernet card (this is the one I want to use to wake the system remotely, as it is the one configured to connect to my LAN). I will copy two values:
Interface name: eno1 (be aware of one (1) and lowercase L (l)). Usually interface name ends with a number, not a letter.
MAC address: e8:94:f6:08:5a:60
Now we know the interface name, we will check the Wake-on capabilities:
sudo ethtool eno1
Settings for eno1: Supported ports: [ TP ] Supported link modes: 10baseT/Half 10baseT/Full 100baseT/Half 100baseT/Full 1000baseT/Full Supported pause frame use: No Supports auto-negotiation: Yes Supported FEC modes: Not reported Advertised link modes: 10baseT/Half 10baseT/Full 100baseT/Half 100baseT/Full 1000baseT/Full Advertised pause frame use: No Advertised auto-negotiation: Yes Advertised FEC modes: Not reported Speed: 1000Mb/s Duplex: Full Port: Twisted Pair PHYAD: 1 Transceiver: internal Auto-negotiation: on MDI-X: off (auto) Supports Wake-on: pumbg Wake-on: d Current message level: 0x00000007 (7) drv probe link Link detected: yes
Take a look at the last lines. We are looking for two different lines:
Supports Wake-on: pumbg
and
Wake-on: d
The “Wake-on” mode configured by default is “d”, which means that the network card will not switch on the server when it receives a magic packet but, as the network interface supports “g” mode (it is one the letters in pumbg) we can set the value of “Wake-on” to “g”.
We will use ethtool for this. If it is not already installed on your system, do it:
sudo ethtool -s eno1 wol g
Now, if you repeat the step to check your network card capabilities (ethtool eno1) you shoud see the “Wake-on” option set to “g” value.
That means your server is ready to sleep and wake remotely.
Put the server into hibernation mode:
sudo systemctl hibernate
And now wake it remotely using one of the many available tools. Depending on the platform you will use an Android, Windows, Linux, … tool for this purpose and the only thing you will need is the MAC address you copied some steps above.
If everything went right, your server has woken, but what if you repeat the previous steps? (hibernate – remotely wake) It doesn’t work.
As I mentioned in the introduction, the value you configure in the “Wake-on” option of your network card is volatile. Each time you reboot your server it resets its value (usually to “d”).
Make your configuration sticky
We will create a system service to set the “Wake-on” value to “g” each time the server boots or restart.
There are a lot of recipes for these, but most of them didn’t work in my case. I’ll tell you one configuration line that did the trick for me.
1.- Create the .service file using your favourite editor
sudo nano /etc/systemd/system/wol.service
Now, copy the next content inside the file (change the name of the interface card and set the description you prefer):
[Unit] Description=Activate WOL on eno1 network card After=network-online.target [Service] Type=oneshot ExecStart=/sbin/ethtool -s eno1 wol g [Install] WantedBy=basic.target
Save the file (^O + ENTER + ^X)
Now we will start the service for the first time
sudo service wol start
And check its status
sudo service wol status ● wol.service - Activate Wake On LAN Loaded: loaded (/etc/systemd/system/wol.service; enabled; vendor preset: enabled) Active: inactive (dead) since Sat 2020-05-09 12:55:26 CEST; 2min 8s ago Process: 1706 ExecStart=/sbin/ethtool -s eno1 wol g (code=exited, status=0/SUCCESS) Main PID: 1706 (code=exited, status=0/SUCCESS) may 09 12:55:26 estudios-srv systemd[1]: Starting Activate Wake On LAN... may 09 12:55:26 estudios-srv systemd[1]: wol.service: Succeeded. may 09 12:55:26 estudios-srv systemd[1]: Started Activate Wake On LAN.
You will notice the service is dead or inactive. This is normal because it is not actually a service and it is not running like a daemon, it starts, do whatever it has to do and finishes.
If we restart the server now, our service entry will not run at startup because we haven’t enabled it. To do so:
sudo systemctl enable wol.service
Now, you can restart the server and it will wake remotely because “Wake-on: g” should be already set when it boots.
The explanation to “TRULY sticky”
But, why did I titled my post with a “TRULY sticky”?. Well, the reason is that all the recipes I’ve found to do this didn’t work. After rebooting, always the “d” value was set for the “Wake-on” option.
In fact it is not a problem of executing the configuration or not. Although the service entry run on every reboot, it was doing it before the network card was available to be configured.
So, the problem is when to run the network card configuration.
That’s the reason you should put this line in you .service file:
After=network-online.target
To make sure it configures the network card when it’s really available.
I hope it to work for you too.