Why you want to do that?

I have a spare ThinkPad that I turned into a little headless home box. It sits on a shelf with the lid closed, plugged into ethernet, and I ssh into it whenever I need a Linux machine that isn’t my Mac; for builds, for running something overnight, for keeping a service alive.

The problem is I don’t want it running 24/7. It sips power for no reason most of the day, and leaving a laptop pinned at full charge forever isn’t great for the battery either. But if I shut it down, I then have to physically walk over, open the lid and press the power button to bring it back. For a machine that is supposed to be “headless”, that’s annoying.

Wake-on-LAN (WoL) fixes exactly this. The network card stays awake even when the machine is off, listening for a special “magic packet”. Send that packet from any other device on the network and the machine boots itself. Pair that with a plain ssh ... poweroff to shut it back down, and I can power the ThinkPad on and off from my Mac without ever touching it.

Prerequisite

  • A ThinkPad (or any machine, really) with an ethernet port. WoL over Wi-Fi is finicky and I wouldn’t rely on it, so this whole guide assumes a wired connection.
  • Arch Linux using NetworkManager to manage that connection (this is the default on a lot of setups).
  • The laptop plugged into AC. This matters, more on that in a second.
  • Another machine on the same local network to send the magic packet from. Mine is a Mac.
  • SSH already set up so you can log in to shut the machine back down.

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

The network card can only listen for the magic packet if the firmware keeps it powered while the machine is off, so this has to be turned on in the BIOS first.

Reboot the ThinkPad and mash Enter (or F1) to get into the BIOS, then head to:

Config → Network → Wake On LAN

You’ll usually get a few options. I picked AC Only, which means the machine will only respond to WoL when it’s running on AC power, not on battery. This is the sane choice for a laptop; you don’t want a stray packet draining your battery while it’s unplugged in a bag somewhere. It’s also why the laptop being plugged in matters, on battery it simply won’t listen.

Save and exit. While you’re in there, there’s one more thing to fix, and if you skip it the machine will wake but won’t actually boot your OS.

Step 1.5: Put the internal disk first in the boot order

The first time I woke the ThinkPad over the network, it powered on happily and then dumped me at:

Start PXE over IPv4

That’s the machine trying to network boot (PXE) instead of booting from the internal disk. It makes a twisted kind of sense; the thing that just woke the laptop was a network event, so the firmware tries the network adapter first. The fix is to make sure your SSD/NVMe sits above the network adapter in the boot priority list.

In the BIOS, go to:

Startup → Boot

and reorder the list so your internal drive is first and the network/PXE entries are last (or disable PXE boot entirely if you never use it). Save and exit.

Now a WoL wake goes straight into Arch instead of hunting for a boot server that doesn’t exist.

Step 2: Find your interface and MAC address

Back in Arch, we need two things: the name of the wired interface and its MAC address. The magic packet is addressed to the MAC, so this is the number your Mac will target later.

$ ip link

Look for the wired interface. On ThinkPads it’s typically something like enp0s31f6:

2: enp0s31f6: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 ...
    link/ether 8c:16:45:xx:xx:xx brd ff:ff:ff:ff:ff:ff

That link/ether 8c:16:45:xx:xx:xx is the MAC address. Write it down.

Step 3: Check the card actually supports WoL

Before configuring anything, let’s confirm the hardware supports it. That’s what ethtool is for:

$ sudo pacman -S ethtool
$ sudo ethtool enp0s31f6

The two lines you care about are:

	Supports Wake-on: pumbg
	Wake-on: d

Supports Wake-on lists the modes the card can do. The one we want is g, which stands for “wake on magic packet”. As long as g shows up in the supported list, you’re good.

Wake-on: d means it’s currently disabled. That’s what we’re about to fix.

Step 4: Make WoL stick with NetworkManager

You could enable WoL right now with sudo ethtool -s enp0s31f6 wol g, but that setting is lost on the next reboot, which defeats the entire purpose. Since NetworkManager owns this connection, we let it set WoL every time the interface comes up, so it survives reboots.

First find the connection name:

$ nmcli -f NAME,DEVICE connection show
NAME                DEVICE
Wired connection 1  enp0s31f6

Then tell that connection to enable the magic-packet wake mode:

$ sudo nmcli connection modify "Wired connection 1" 802-3-ethernet.wake-on-lan magic
$ sudo nmcli connection up "Wired connection 1"

The 802-3-ethernet.wake-on-lan magic property is the whole trick. NetworkManager stores it in the connection profile and re-applies it on every boot and every time the cable is plugged back in, so you set it once and forget about it.

Now verify it took effect:

$ sudo ethtool enp0s31f6 | grep Wake-on
	Supports Wake-on: pumbg
	Wake-on: g

Wake-on: g — that’s the magic-packet mode enabled. The card is now listening.

Step 5: Wake it up from the Mac

On the Mac, install the wakeonlan tool via Homebrew:

$ brew install wakeonlan

Now shut the ThinkPad down (sudo systemctl poweroff, or just close whatever you were doing). Once it’s fully off, fire the magic packet from the Mac using the MAC address from Step 2:

$ wakeonlan 8c:16:45:xx:xx:xx
Sending magic packet to 255.255.255.255:9 with 8c:16:45:xx:xx:xx

A second or two later the ThinkPad’s fan spins up and it boots. The magic packet is just a small UDP broadcast on port 9, so as long as the Mac and the ThinkPad are on the same subnet, there’s nothing else to configure.

Step 6: Shutting it back down

Waking is the hard half; shutting down is the easy half, because the machine is running and reachable over SSH. From the Mac:

$ ssh [email protected] 'sudo systemctl poweroff'

If you don’t want to type a sudo password every time, add a narrow sudoers rule on the ThinkPad that lets your user run only the poweroff command without a password:

$ echo 'subhash ALL=(ALL) NOPASSWD: /usr/bin/systemctl poweroff' | sudo tee /etc/sudoers.d/poweroff

At this point I have two one-liners on my Mac; one to boot the ThinkPad, one to shut it down. I wrapped them in a couple of shell aliases (pion and pioff) and now the laptop genuinely behaves like a machine I can toggle from my desk.

Troubleshooting

If the magic packet doesn’t wake it, a few usual suspects:

  • It’s on battery. With the AC Only BIOS setting, the card won’t listen unless the charger is plugged in. This got me once.
  • Wake-on reset to d after reboot. That means the setting isn’t persistent. Double-check you set it via nmcli on the connection (Step 4) and not just with a one-off ethtool -s.
  • Wrong “off” state. Some boards only wake from suspend, not a full shutdown, or the reverse. If wake-from-poweroff doesn’t work, try systemctl suspend and see if that wakes; then adjust the BIOS WoL option accordingly.
  • It boots to Start PXE over IPv4. The wake worked, but the firmware is trying to network boot instead of your disk. Fix the boot order so the internal drive comes before the network adapter (Step 1.5).
  • Different subnet. WoL is a broadcast on the local network. If your Mac and ThinkPad are on different VLANs/subnets it won’t cross the router without extra work, so keep them on the same network.

Bonus: ditch the graphical login entirely

Since I only ever reach this machine over SSH, there’s no reason to boot into a full desktop and burn RAM on a login screen nobody looks at. So I disabled the display manager:

$ sudo systemctl disable gdm

That stops GDM (and the whole graphical session behind it) from starting at boot. On the next boot the ThinkPad comes up to a plain text console, uses less memory, and gets to a state where sshd is ready a bit quicker.

If you want to be thorough about it, you can also tell systemd to boot into the multi-user (non-graphical) target by default, which is the “proper” way to make a box headless:

$ sudo systemctl set-default multi-user.target

Either way, the laptop now spends its whole life as a text-only machine I talk to over the network, exactly what I wanted. And if I ever do need the desktop back, it’s one systemctl enable --now gdm away.

Wrapping up

None of the individual pieces here are complicated, it’s one BIOS toggle, one nmcli property, and one small tool on the Mac. But together they turn a spare laptop into something that behaves like a proper remote box: off when I don’t need it, on within seconds when I do, and I never have to get up to touch it.

For an old ThinkPad that would otherwise be collecting dust, that’s a very satisfying little upgrade.