Wake a host on a different subnet or VLAN with OPNSense

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.

OPNSense web interface showing the Wake On Lan system priveleges

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.

The OPNSense web UI showing an interface, LAN1, with its technical ID, opt3
The technical ID of the LAN1 interface given here is opt3, and this should be used in the 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