If you need to wake a machine that exists on a different VLAN or subnet, it’s often not possible to do so easily as the UDP broadcast may not be routed across the subnet or VLAN boundary.
One option is to use a UDP broadcast relay, but this can be fiddly to configure and from past experience, not particularly reliable.
The solution I have landed on is to make use of the WOL API that’s built into OPNSense. In addition to solving the routing issue, it also allows you to configure access control, restricting the ability to wake to recognised actors.
Configure a user for the WOL API
First off, you need to create a user with access to the WOL API in OPNSense. You could use an administrator/root account, but I highly recommend creating a dedicated user.
From the OPNSense Web UI, navigate to System -> Access -> Users, and press the + icon to begin creating a new user. As we don’t need to be able to log in as the user, you can choose the option to “Generate a scrambled password to prevent local database logins for this user.”
Press the Save button.
Under Effective Privileges, press the edit button. On the resulting page, enter “wol” into the filter box, tick the box for “Services: Wake on LAN” and press Save.
Under API keys, press the + button to create a new API key. This will add a new key to the list, and also generate a .txt file containing the key and secret, which will be automatically downloaded. Keep this file safe as you will need the information in here to issue the API request; there is no way to download it again without creating a new API key.
Press Save to apply changes.
Creating an API request
The WOL API is really simple and you should be able to make a request in any framework of your choosing.
Endpoint: https://<opnsense_ip>/api/wol/wol/set
Method: POST
Headers: Content-Type: application/json
The API is protected using Basic Auth, where the username is the API key and the password is the API secret. You can get both of these from the key file downloaded when the key was added in the OPNSense UI.
The payload is a simple JSON document structured as follows:
{
"wake": {
"interface": "<interface identifier>",
"mac": "<target mac address separated by :>"
}
}
The interface provided is NOT the name of the interface, but is the technical identifier of the interface. You can find this in OPNSense by navigating to Interface -> Assignments. The technical ID is given in brackets, and this is the one you must use in the request payload.
If successful then the API will return a 200 OK status, with a body containing: {"status":"OK"}
Example
An example request sent using cURL might look like:
curl -s -k -d '{"wake":{"interface":"opt3", "mac":"11:22:33:44:55:66"}}' --user "ABvOcLeQ7++dMh5+HgzR8KClVIGMbxTL7sQvEVOdipsAaHK+7UJRTcZBYP3l8RXq4yGWZU7oZvBBIOaS:JPU3YJW6t2LVd5calpoS2SDWduuTGA/afuS5sVOJA2pb51Fu3iCOozWM49cwOrp5nQZpvTB8L2LmSATx" -H 'Content-Type: application/json' https://10.0.32.1/api/wol/wol/set
Leave a Reply