[LINUX] I want to do Wake On LAN fully automatically

This article is the 7th day article of KLab Engineer Advent Calendar 2019. I was late when I was having trouble debugging ...

The topic of systemd, TCP proxies and Wake On LAN.

Motivation and synopsis

I'm a Mac user, but sometimes I use my Windows machine at home via Remote Desktop.

This Windows machine is usually put to sleep, so if you want to use it, you must first throw a Wake On LAN magic packet to wake it up [^ 1].

image.png

[^ 1]: It's a remote desktop dedicated machine and it's out of reach because it's not normally used.

However, it is not uncommon to forget the MAC address of a Windows machine or forget the command to throw a magic packet in the first place.

Of course, the commands I used before are recorded in the history, so I can manage it, but in the first place, it seems to be troublesome to manually throw magic packets every time.

So, I configured a TCP proxy with systemd and created a mechanism to automatically throw magic packets before connecting to the proxy. I have a Raspberry Pi that is always running in my house, so I decided to operate a TCP proxy here.

image.png

This eliminates the hassle of throwing magic packets on your Mac, and allows you to log on to Windows simply by selecting the connection destination from the GUI of the remote desktop.

This article will introduce the details of this mechanism. Since there is no protocol-dependent part, it should be possible to use it other than remote desktop.

Throw a magic packet from systemd

systemd is a high-performance service management program used in recent Linux.

First, I will introduce the process of throwing a magic packet. This was written in the oneshot service template.

/etc/systemd/system/[email protected]


[Unit]
Description = Sending Wake on LAN packet (oneshot)
After = network-online.target
Wants = network-online.target

[Service]
Type = oneshot
ExecStart = /usr/sbin/etherwake %i

A service template is a mechanism that converts a part of the service name (instance character string) into a variable character string and passes it to the service. Here, the MAC address is specified as the instance string and used.

$ sudo systemctl start wol@00:00:5e:00:53:01.service

This will send a magic packet to the MAC address 00: 00: 5e: 00: 53: 01.

Throw magic packets before connecting with TCP proxy

Next, we will create a TCP proxy with systemd. This is a 2-file structure.

/etc/systemd/system/rdp-proxy.socket


[Unit]
Description = Socket for RDP (Remote Desktop Protocol) proxy

[Socket]
ListenStream = 0.0.0.0:3389
Accept = yes

[Install]
WantedBy = sockets.target

After installing the above file, enable automatic startup.

$ sudo systemctl enable rdp-proxy.socket
$ sudo systemctl start rdp-proxy.socket

By setting ListenStream =, it listens on TCP 3389 and passes it to the service [^ 2]. Also, if ʻAccept = yes`, you need to create a service template with the same name.

[^ 2]: You can also use ListenDatagram = to listen on UDP.

/etc/systemd/system/[email protected]


[Unit]
Description = Server for RDP (Remote Desktop Protocol) Proxy
Requires = wol@00:00:5e:00:53:01.service
After = network-online.target wol@00:00:5e:00:53:01.service
Wants = network-online.target

[Service]
Type = simple
ExecStartPre = /usr/bin/timeout 60 /bin/sh -c 'until /bin/nc -w 5 -z 192.0.2.1 3389; do sleep 1; done'
ExecStart = /bin/nc -q 10 192.0.2.1 3389
StandardInput = socket
StandardOutput = socket
StandardError = journal

Requires specifies the service that throws the magic packet created earlier.

The main process is proxying using netcat. One process will be started for each connection.

However, simply proxying with netcat did not work as expected. Because there is a time lag between throwing the magic packet and the remote desktop server going into the listen state, you have to wait for a while before you can connect. Therefore, before connecting, I used ʻExecStartPre` to check if TCP connection was possible, and proxyed after it became possible to connect.

The IP address and MAC address are for example only, so change them as appropriate when using the above settings.

Try it out

When I actually used it, it was more practical than I expected. I'm using Raspberry Pi 2 as a proxy, but there seems to be no performance problem (because I had enough CPU load and network bandwidth as far as I experimented).

By the way, in my environment, there is a time lag of about 30 seconds from connecting to the proxy to connecting to the sleeping Windows by remote desktop. It's not unbearable, but I think it's too late, so there may be some improvements.

Summary

I made a TCP proxy with systemd and showed that any external command can be executed before its connection. This time, I threw a Wake On LAN magic packet with an external command, but it seems that it can also be applied such as connecting after launching an AWS instance.

Anyway, systemd can do anything ...

Reference URL

Recommended Posts

I want to do Wake On LAN fully automatically
I want to do pyenv + pipenv on Windows
I want to do ○○ with Pandas
I want to develop Android apps on Android
I want to do Dunnett's test in Python
Library for "I want to do that" of data science on Jupyter Notebook
Even beginners want to say "I fully understand Python"
I want to find a popular package on PyPi
I want to fully understand the basics of Bokeh
I want to AWS Lambda with Python on Mac!
I want to use OpenJDK 11 on Ubuntu Linux 18.04 LTS / 18.10
[ML Ops] I want to do multi-project with Python
I want to send a business start email automatically
I want to restart CentOS 8 on time every day.
I want to do something in Python when I finish
I want to solve Sudoku (Sudoku)
I want to automatically generate a modern metal band name
I want to automatically attend online classes with Python + Selenium!
I want to disable interrupts on Raspberry Pi (≒ DI / EI)
I want to announce my graduation thesis on IPython Notebook
[Django] I want to log in automatically after new registration
[AWS EC2] Settings you want to do on Amazon Linux 2
I want to automatically find high-quality parts from the videos I shot
I want to understand systemd roughly
MacBookPro Setup After all I want to do a clean installation
I want to automatically operate Chrome on Windows from a virtual machine (ubuntu) started using Vagrant
I want to know if you install Python on Mac ・ Iroha
I want to do a full text search with elasticsearch + python
I want to automatically answer Google Form at 5 o'clock every morning
I want to scrape images to learn
I want to copy yolo annotations
I want to debug with Python
I want to tweet on Twitter with Python, but I'm addicted to it
I want to format and check Python code to my liking on VS Code
I want to do a monkey patch only partially safely in Python
I want to pin Spyder to the taskbar
I want to output to the console coolly
I want to print in a comprehension
I want to scrape them all together.
I want to handle the rhyme part1
I want to know how LINUX works!
I want to handle the rhyme part3
I want to use jar from python
Enable WOL (Wake On LAN) on Manjaro KDE
I want to analyze logs with Python
I was addicted to Flask on dotCloud
I want to play with aws with python
I want to use IPython Qt Console
I want to make an automation program!
Let's summarize what you want to do.
I want to handle the rhyme part2
I want CAPTCHA to say HIWAI words
I want to visualize the transfer status of the 2020 J League, what should I do?
I want to drop a file on tkinter and get its path [Tkinter DnD2]
I want to do machine learning even without a server --Time Series Edition -
I want to convert horizontal text to vertical text and post it on Twitter etc.
I want to realize something like AutoHotkey with AutoKey on Ubuntu (Kali Linux)
I want to be notified when the command operation is completed on linux!
I want to make matplotlib a dark theme
I want to connect to PostgreSQL from various languages
I want to have recursion come to my mind