Wake-on-LAN: Proxyο
- OS:
πͺ Platform-independent
In proxy mode, Desomnia runs on an always-on device β such as a Raspberry Pi, a NAS, or any other machine that remains powered around the clock. From there, it monitors traffic across the entire network and wakes sleeping hosts on behalf of any device that tries to reach them, without requiring any software or configuration changes on the connecting devices.
If you do not have a suitable always-on device, the Wake-on-LAN: Client guide describes an alternative that achieves the same result by running Desomnia on each machine you connect from.
Hint
The configuration for both modes is nearly identical. The only structural difference is a single attribute on the <NetworkMonitor> element. If you have already worked through the client mode guide, everything you have learned applies here as well.
Attention
Only one Desomnia instance may run in proxy mode on a given local subnet at a time. On startup, Desomnia broadcasts a beacon to detect any running proxy instance. If another instance in proxy mode is present, it responds, and the secondary instance exits with an error that includes the MAC address of the conflicting instance.
Two Desomnia instances operating on different subnets, or where only one is in proxy mode, are not affected by this restriction.
Work in progress
Running two proxy instances for redundancy requires a more involved coordination mechanism β both instances would continuously respond to each otherβs address resolution queries, making each appear permanently online to the other. This is tracked for a future release.
Before you beginο
Make sure the following are in place before writing your first configuration:
Desomnia is installed on the always-on device β not on the machines you connect from. Refer to the Installation section of this documentation for the appropriate platform.
The always-on device must remain continuously online. Combining proxy mode with local sleep management on the same machine is not recommended, as suspending the proxy would prevent it from waking other hosts.
Wake-on-LAN is enabled on each target host. This requires enabling it in the BIOS / UEFI firmware and ensuring the network adapter remains powered while the system is suspended. The exact setting is often labelled Wake-on-LAN, Wake on Magic Packet, or Power On By PCI-E, depending on the firmware vendor.
You have the MAC address of each target host. If a host is currently awake, run
arp -afrom any machine on the same network, or look it up in your routerβs device list.The always-on device must be on the same network segment as the hosts it will wake. Wake-on-LAN Magic Packets do not cross routers by default.
Verifying Wake-on-LAN capabilitiesο
To verify that Wake-on-LAN is working on a target host independently of Desomnia, you can send a Magic Packet manually using the wakeonlan utility, available for Linux and macOS via common package managers:
# Debian / Ubuntu
sudo apt install wakeonlan
# macOS
brew install wakeonlan
wakeonlan 00:1A:2B:3C:4D:5E
If the host wakes up, its firmware and network adapter are configured correctly. If it does not, the issue lies with the target hostβs configuration rather than with Desomnia.
Minimum working configurationο
The configuration for proxy mode is identical to client mode, with one addition: watchMode="promiscuous" on the <NetworkMonitor> element.
<?xml version="1.0" encoding="UTF-8"?>
<SystemMonitor version="1">
<NetworkMonitor watchMode="promiscuous">
<RemoteHost name="server" MAC="00:1A:2B:3C:4D:5E" IPv4="192.168.1.10" />
</NetworkMonitor>
</SystemMonitor>
Replace 00:1A:2B:3C:4D:5E with the MAC address of your target host and 192.168.1.10 with its IP address.
Setting watchMode="promiscuous" switches Desomnia from monitoring only outgoing traffic of the local machine to monitoring connection attempts between any two hosts on the network. When a client tries to reach a sleeping host, Desomnia detects the attempt and sends the Magic Packet on its behalf. Read more about how this works in Promiscuous mode.
As in client mode, the <NetworkMonitor> element without an interface or network attribute automatically binds to all interfaces with a default gateway configured. See Interface selection if you need to target a specific interface, and Auto-configuration to learn how to remove static address mappings from your configuration once you have a working baseline.
Note
In promiscuous mode, Desomnia observes traffic from every device on the network. Without any filters, it will react to any connection attempt directed at "server" β including traffic from your router, smart home devices, or the proxy device itself. The sections below explain how to bring this under control.
Verifying it worksο
Start the Desomnia service on the always-on device, then try connecting to a service on a target host from any machine on the network while it is suspended. Desomnia logs a message each time it detects a connection attempt and each time it sends a Magic Packet.
To see the full detail of what is being detected, enable debug-level logging β see Logging.
If the host does not wake up, check the following:
Wake-on-LAN is enabled in the BIOS / UEFI settings of the target host.
The network adapter on the target host is configured to remain powered while suspended.
The MAC address and IP address in the configuration match the target host exactly.
The always-on device is on the same network segment as the target host.
Desomnia is monitoring the correct network interface β confirm with Interface selection.
Filtering unwanted wake-upsο
With the minimal configuration in place, Desomnia reacts to any connection directed at the watched hostβs IP address. Depending on your operating system and running applications, background traffic β such as network discovery, address resolution, or periodic health checks β can occasionally match and trigger an unwanted wake-up.
The following sections explain how to narrow this down to the connections you actually care about.
Filter by serviceο
The most reliable way to prevent unwanted wake-ups is to restrict Desomnia to specific services by port number. Adding a <ServiceFilterRule> with type="Must" makes it an inclusive filter: only connections to that specific port will trigger a wake-up.
<RemoteHost name="server" MAC="00:1A:2B:3C:4D:5E" IPv4="192.168.1.10">
<ServiceFilterRule name="SSH" port="22" type="Must" />
</RemoteHost>
This configuration wakes "server" only when a TCP connection to port 22 is detected. All other connections to that host are ignored.
To react to multiple services, add one rule per port:
<RemoteHost name="server" MAC="00:1A:2B:3C:4D:5E" IPv4="192.168.1.10">
<ServiceFilterRule name="SSH" port="22" type="Must" />
<ServiceFilterRule name="SMB" port="445" type="Must" />
<ServiceFilterRule name="RDP" port="3389" type="Must" />
<ServiceFilterRule name="HTTP" port="80" type="Must" />
</RemoteHost>
As long as at least one inclusive rule is present, any connection to a port not listed is automatically ignored.
For UDP-based services, set protocol="UDP" explicitly:
<ServiceFilterRule name="DNS" protocol="UDP" port="53" type="Must" />
Hint
The name attribute on a <ServiceFilterRule> is optional and purely descriptive. It appears in log output and helps identify which rule triggered an event.
Excluding specific servicesο
If only a small number of services cause unwanted noise, you may prefer the opposite approach: leave the default behaviour in place β wake on any connection β and explicitly exclude the services you want to ignore using type="MustNot":
<RemoteHost name="server" MAC="00:1A:2B:3C:4D:5E" IPv4="192.168.1.10">
<ServiceFilterRule name="Monitoring" port="8080" type="MustNot" />
</RemoteHost>
Connections to port 8080 are ignored; all other connections to this host can still trigger a wake-up.
Note
type="MustNot" is the default for all filter rules when no type is set explicitly. The two approaches β whitelisting with type="Must" and blacklisting with type="MustNot" β can be mixed, but the interaction can be difficult to reason about: as soon as at least one type="Must" rule is present, the filter switches to whitelist mode and type="MustNot" rules act only as exclusions within that whitelist.
Shorter notation with <Service>ο
When all your rules use type="Must", the <Service> shorthand is equivalent and less verbose:
<RemoteHost name="server" MAC="00:1A:2B:3C:4D:5E" IPv4="192.168.1.10">
<Service name="SSH" port="22" />
<Service name="SMB" port="445" />
<Service name="RDP" port="3389" />
<Service name="HTTP" port="80" />
</RemoteHost>
Each <Service> element is equivalent to a <ServiceFilterRule> with type="Must".
Work in progress
In a future version of Desomnia, declared services will be advertised via mDNS while the host is suspended, enabling full compatibility with Appleβs Sleep Proxy protocol. Currently the main benefit of <Service> over <ServiceFilterRule> is the shorter notation.
Filter by source hostο
In client mode, all observed traffic originates from a single machine β your own. In proxy mode, Desomnia sees connection attempts from every device on the network. This makes source host filtering an important tool for reducing noise.
The most common sources of unwanted wake-ups in proxy mode are the router and the proxy device itself.
Declaring the routerο
Adding a <Router> element to your configuration tells Desomnia about your gateway. Traffic originating from the router is ignored by default, which eliminates the most common source of background noise β periodic reachability checks that many routers perform.
<NetworkMonitor watchMode="promiscuous">
<Router name="gateway" MAC="B0:F2:08:0A:D1:14" IPv4="192.168.1.1" />
<RemoteHost name="server" MAC="00:1A:2B:3C:4D:5E" IPv4="192.168.1.10" />
</NetworkMonitor>
Replace the MAC and IP address values with those of your own router.
Excluding specific hostsο
To exclude the proxy device itself or any other always-on host from triggering wake-ups, add a <HostFilterRule>:
<NetworkMonitor watchMode="promiscuous">
<Router name="gateway" MAC="B0:F2:08:0A:D1:14" IPv4="192.168.1.1" />
<HostFilterRule name="proxy" IPv4="192.168.1.2" type="MustNot" />
<RemoteHost name="server" MAC="00:1A:2B:3C:4D:5E" IPv4="192.168.1.10" />
</NetworkMonitor>
A <HostFilterRule> at the <NetworkMonitor> level applies to all watched hosts. To limit a rule to a specific host, place it inside the corresponding <RemoteHost> element instead.
If the same host is referenced in multiple places, you can define it once as a <Host> element and refer to it by name:
<NetworkMonitor watchMode="promiscuous">
<Router name="gateway" MAC="B0:F2:08:0A:D1:14" IPv4="192.168.1.1" />
<Host name="proxy" IPv4="192.168.1.2" />
<HostFilterRule name="proxy" type="MustNot" />
<RemoteHost name="server" MAC="00:1A:2B:3C:4D:5E" IPv4="192.168.1.10">
<HostFilterRule name="proxy" type="MustNot" />
</RemoteHost>
</NetworkMonitor>
Excluding address rangesο
To exclude an entire subnet β for example, a VLAN of IoT devices that should never wake your server β use a <HostRangeFilterRule> with CIDR notation:
<HostRangeFilterRule network="192.168.2.0/24" />
You can also specify a range by first and last address:
<HostRangeFilterRule firstIP="192.168.1.100" lastIP="192.168.1.200" />
As with <HostFilterRule>, range rules can be placed at the <NetworkMonitor> level to apply to all hosts, or inside a <RemoteHost> to apply only there. A named <HostRange> element can be defined once and referenced by name in multiple places, similar to declaring a <Host> and referencing it by name by <HostFilterRule>.
Allowing external connectionsο
By default, Desomnia ignores traffic that has been routed through your gateway β requests originating from outside your local network. This is intentional: without additional controls, the internet would be free to trigger wake-ups via any open port on your router.
If you want to allow specific external sources β such as a known static IP address at your workplace β to trigger wake-ups, set allowWakeByProxy="true" on your router declaration and add a <ForeignHostFilterRule>:
<NetworkMonitor watchMode="promiscuous">
<Router name="gateway" MAC="B0:F2:08:0A:D1:14" IPv4="192.168.1.1" allowWakeByProxy="true" />
<ForeignHostFilterRule>
<HostFilterRule IPv4="203.0.113.42" type="MustNot" />
</ForeignHostFilterRule>
<RemoteHost name="server" MAC="00:1A:2B:3C:4D:5E" IPv4="192.168.1.10" />
</NetworkMonitor>
Desomnia automatically infers your local subnet from the network interface and protects it from interference β local devices continue to function as configured.
Note
Setting type="MustNot" on the nested <HostFilterRule> to allow a host may seem counterintuitive. The reason is that <ForeignHostFilterRule> is itself an exclusion β it blocks all traffic originating from outside the local network. A nested type="MustNot" rule creates an exception to that exclusion, effectively permitting the specified host through. See more about the logic of compound filters under the next heading.
If you do not know the external IP address in advance β for example, when connecting from a mobile connection or a location with a changing IP β see the Remote Access guide for how to authenticate dynamic addresses using Single Packet Authorization.
Filter ping trafficο
Some operating systems and network tools send ICMP echo requests (pings) to check whether a host is reachable. These operate at the IP layer, before any TCP or UDP connection is established, and can trigger an unwanted wake-up if they happen to target a watched host.
If you have already configured at least one type="Must" service filter, or used <Service> declarations, ping traffic is automatically excluded β no further configuration is needed.
Without any inclusive service filter, you can suppress pings explicitly:
<NetworkMonitor>
<PingFilterRule />
<RemoteHost name="server" MAC="00:1A:2B:3C:4D:5E" IPv4="192.168.1.10" />
</NetworkMonitor>
Placing the rule at the <NetworkMonitor> level applies it to all watched hosts. To limit it to a specific host, place the rule inside the corresponding <RemoteHost> element.
Caution
When using a <PingFilterRule> in promiscuous mode, Desomnia needs to spoof the addresses of watched hosts in order to intercept and inspect ping requests. If you have already configured type="Must" service filters (or <Service> declarations), a <PingFilterRule> is not needed β ping traffic is excluded automatically.
Combining service and host filtersο
Service filters and host filters can be nested to express more precise conditions. The type of a nested rule is always interpreted relative to its parent. The following example demonstrates the possible combinations:
<RemoteHost name="server" MAC="00:1A:2B:3C:4D:5E" IPv4="192.168.1.10">
<ServiceFilterRule name="SSH" port="22" type="Must">
<HostFilterRule name="workstation" IPv4="192.168.1.20" type="Must" />
</ServiceFilterRule>
<ServiceFilterRule name="RDP" port="3389" type="Must">
<HostFilterRule name="proxy" IPv4="192.168.1.2" type="MustNot" />
</ServiceFilterRule>
<ServiceFilterRule name="SMB" port="445" type="MustNot">
<HostFilterRule name="backup-agent" IPv4="192.168.1.50" type="Must" />
</ServiceFilterRule>
<PingFilterRule type="MustNot">
<HostFilterRule name="monitor" IPv4="192.168.1.99" type="MustNot" />
</PingFilterRule>
</RemoteHost>
<ServiceFilterRule>= Must Γ<HostFilterRule>= MustOnly wake for connections to this service, and only when they originate from the specified host.
<ServiceFilterRule>= Must Γ<HostFilterRule>= MustNotOnly wake for connections to this service, but never when they originate from the specified host.
<ServiceFilterRule>= MustNot Γ<HostFilterRule>= MustIgnore connections to this service in general, but only when they originate from the specified host. Connections from all other hosts are still allowed.
<PingFilterRule>= MustNot Γ<HostFilterRule>= MustNotIgnore ping traffic in general, but not when it originates from the specified host β that hostβs pings will still be allowed through.