Send a wake on lan packet from a docker container
Asked Answered
R

3

13

I have a docker container running a python uwsgi app. The app sends a wake on lan broadcast packet to wake a pc in the local network.

It works fine without the use of docker (normal uwsgi app directly on the server), but with docker it won't work.

I exposed port 9/udp and bound it port 9 of the host system.

What am I missing here? Or with other words, how can I send a wake on lan command from a docker container to the outside network?

Roane answered 13/10, 2015 at 11:33 Comment(6)
Does it work with --net=host?Sosthina
@AdrianMouat - that will work. So I cannot use privileged ports in the default bridged mode?Roane
It will be to do with the bridged network, but not privileged ports. I suspect it's to do with broadcast, but I don't know anything about your "magic packet", so I can't say anything more.Sosthina
@AdrianMouat it is a wake on lan broadcast packet - commonly named magic packetRoane
Yeah, so I think you need to look into the details of how the Docker bridge is implemented to get that to work. You have to remember that containers are effectively on their own LAN, but maybe you just need to twiddle the IP tables settings. Otherwise use --net=host to use the host's LAN.Sosthina
FYI to anyone user docker on a mac, --net=host does not work on a mac and silently will not work as expected. github.com/docker/for-mac/issues/2716Hitherto
H
3

It seems that UDP broadcast from docker isn't being routed properly (possibly only broadcasted in the container itself, not on the host).

You can't send UDP WoL messages directly, as the device you're trying to control is 'offline' it doesn't show up in your router's ARP table and thus the direct message can't be delivered.

You may try setting (CLI) --network host or (compose) network_mode: host.

If you feel this may compromise security (since your container's/host network are more directly 'connected') or otherwise interferes with your container; you may create/use a separated 'WoL' container.

Hooker answered 9/4, 2021 at 9:11 Comment(0)
Q
1

There are a couple of other options you can consider to send the WoL packet outside of the docker private network if you don't want to expose the container to the host network using the already mentioned --network host approach.

The first option is to specify the network you want to broadcast to (i.e., 192.168.1.0/24), and use the corresponding broadcast address to send the packet, like this:

$ wakeonlan -i 192.168.1.255 aa:bb:cc:dd:ee:ff
Sending magic packet to 192.168.1.255:9 with aa:bb:cc:dd:ee:ff

The requirement for this method to work is the docker network adapter must be configured for the broadcast (see this article for more details).

The other option is easier, and the only requirement is your target machine has a static IP. In that case, you can specify the IP and MAC address and don't need to do any specific configuration to the docker network.

$ wakeonlan -i 192.168.1.10 aa:bb:cc:dd:ee:ff
Sending magic packet to 192.168.1.10:9 with aa:bb:cc:dd:ee:ff

Note: wakeonlan uses port 9 by default, but it's not used in any case so you can use whatever port you prefer. You will see programs using 7, 4000, or other ports. 7 for me it's cleaner because it's usually a Discard service, but it's really not important.

Quadruple answered 30/10, 2023 at 19:9 Comment(1)
The magic packet was successfully sent to the specified network with the adapter configuration that you linked.Farrel
X
0

There's a mix of partially correct answers in the above comments. You do want to send your packet to port 9 on the host but:

  • It's the NIC that listens on port 9, not the OS. In other words, you need to configure the system's NIC to listen for magic packets. When the NIC receives the packet (on port 9, containing its own MAC address), the NIC will start the system by sending a signal via the PCI bus.
  • You don't need need to set up a service to listen on port 9. That's built into most NICs instead.
  • The "sender" of the magic packet needs to be on the same network segment as the target. This means that your Docker container will need to be built with "--network host". This makes your host machine the sender (even though it's coming from a Docker container) and the Docker host must be in the same network segment as the target (i.e., their broadcast addresses match).
  • There's no need to map port 9 between the container and the host. That said, you may run into issues with "--network host" and accessing the app if it tries to use a port that another service is already using. Experimentation is needed. You might need to configure the web server to listen on a different port.
Xantho answered 20/11, 2022 at 16:18 Comment(1)
Oh, and, of course, using "--network host" is considered a security issue. It's fine for a home lab but you'll probably not want to use it in a production environment.Xantho

© 2022 - 2024 — McMap. All rights reserved.