Wake-on-LAN da Guacamole in docker
Il servizio Guacamole permette di lanciare un pacchetto “Wake on LAN” (WOL) prima di collegarsi alla macchina con VNC o RDP. Purtroppo per impostazione di default di Docker, le reti configurate come bridge
non permettono di inviare in uscita i pacchetti broadcast (anche se diretti a una subnet specifica). Questo impedisce l’utilizzo di WOL e Guacamole. Resta la possibilità di configurare il container guacd
sulla rete host
, ma questa soluzione ha problemi di sicurezza.
Cercando in rete ho trovato questo post dal quale ho sfruttato lo script. Io mi sono limitato a descrivere meglio i passaggi da eseguire.
Prima di tutto
Nel post si propone di usare uno script presente su Github, ma per poterlo eseguire prima si deve installare un pacchetto:
sudo apt install jq -y
Poi è possibile scaricare lo script in locale e renderlo eseguibile
wget https://github.com/dhutchison/container-images/raw/master/homebridge/configure_docker_networks_for_wol.sh
chmod +x configure_docker_networks_for_wol.sh
Prima di lanciarlo si deve modificare DOCKER_NETWORK
con il proprio valore, nel mio caso guacd è collegato alla rete net_guacamole_db
.
Attenzione
Se la rete è stata creata con docker-compose
si deve aggiungere un suffisso.
Con il comando seguente è possibile visualizzare tutte le reti configurate in docker:
sudo docker network ls
Dopo aver modificato e salvato lo script è possibile eseguirlo e riavviare il computer.
sudo ./configure_docker_networks_for_wol.sh
sudo reboot
Come testare
Si può aprire Wireshark su un computer collegato alla rete e catturare il traffico di rete. Basta applicare il filtro udp.port==9
per visualizzare solo i pacchetti WOL.
Creare un container di test collegato alla rete scelta in precedenza
sudo docker run --name testcontainer -d -it python:3-alpine
In Portainer cambiare la rete alla quale è collegato il container e aprire la console (si deve scegliere l’opzione /bin/sh
).
Installare awake
e inviare alcuni pacchetti WOL di test. Se tutto funziona è possibile ricevere i pacchetti su Wireshark.
pip3 install awake
awake -b 192.168.3.255 aa:bb:cc:dd:ee:ff #192.68.3.255 è l'indirizzo broadcast del mio subnet
Copy of the script
#!/bin/bash
##############
#
# This script will set the required kernel network settings to
# allow broadcast traffic to be sent from a docker network
# to another network.
#
# This sets using both "sysctl -w" as well as configuring a file in
# "/etc/sysctl.d/" so the change will persist a reboot.
#
##############
# The name of the network the docker container will be connected to
DOCKER_NETWORK=traefik-backend
# Disable the setting to ignore echo broadcasts
sudo sysctl -w net.ipv4.icmp_echo_ignore_broadcasts=0
echo '# Disable the setting to ignore echo broadcasts' | sudo tee /etc/sysctl.d/97-docker-broadcast.conf
echo 'net.ipv4.icmp_echo_ignore_broadcasts=0' | sudo tee -a /etc/sysctl.d/97-docker-broadcast.conf
# Enabling broadcast forwarding for "all" interfaces,
# although it seems this needs used in combination with specific interfaces
sudo sysctl -w net.ipv4.conf.all.bc_forwarding=1
echo '# Enabling broadcast forwarding for "all" interfaces' | sudo tee -a /etc/sysctl.d/97-docker-broadcast.conf
echo 'net.ipv4.conf.all.bc_forwarding=1' | sudo tee -a /etc/sysctl.d/97-docker-broadcast.conf
# Find the subnet for the docker network
subnet=$(docker network inspect "$DOCKER_NETWORK" | jq --raw-output .[0].IPAM.Config[0].Subnet)
if [ ! -z subnet ]; then
echo "Got subnet $subnet"
# Find the network interface
interface=$(ip route | grep "$subnet" | cut -d ' ' -f3)
if [ ! -z interface ]; then
echo "Got interface $interface"
# Check the setting value to check we are substituting correctly
sudo sysctl -w net.ipv4.conf.${interface}.bc_forwarding=1
echo '# Check the setting value to check we are substituting correctly' | sudo tee -a /etc/sysctl.d/97-docker-broadcast.conf
echo "net.ipv4.conf.${interface}.bc_forwarding=1" | sudo tee -a /etc/sysctl.d/97-docker-broadcast.conf
else
echo "Could not determine the network interface for $subnet"
fi
else
echo "Could not determine the subnet for $DOCKER_NETWORK"
fi
Credits Foto di Steve Buissinne da Pixabay