Inviare un messaggio WOL per eseguire uno script


In questa pagina descriverò come inviare un messaggio Wake-On-Lan tramite la rete per eseguire uno script su un router (Asus RT-AC56U) - useremo alcuni pacchetti di Entware, pertanto fate riferimento a questa pagina su come installare Entware su un router.
Partiamo dalla premessa che usare un messaggio Wake-On-Lan non è certamente consigliato poiché chiunque può inviare questo messaggio, basta sapere l'indirizzo IP del destinatario, l'indirizzo MAC del dispositivo di rete da accendere e la porta di destinazione. Come se non bastasse, il protocollo Wake-On-Lan non prevede una password. Useremo quindi questa tecnica solo per inviare messaggi non importanti, ad esempio per eseguire uno script che permette di attivare una funzionalità secondaria.
Per inviare il messaggio Wake-On-Lan possiamo usare un qualunque programma che supporta il Wake-On-Lan (fare riferimento a questa pagina per usare la mia applicazione per il sistema operativo Android), per ricevere invece il suddetto messaggio Wake-On-Lan sul router useremo un pacchetto Entware denominato "socat".


Come installare il pacchetto "socat" sul router

Allo scopo di installare il daemon "socat" con i pacchetti Entware, dobbiamo eseguire il seguente comando :
opkg install socat coreutils-od
Il pacchetto "socat" contiene soltanto il daemon "/opt/bin/socat", che andremo in seguito ad analizzare. Mentre il pacchetto "coreutils-od" contiene il comando "/opt/bin/od" usato dallo script che andremo in seguito ad analizzare.


Come impostare il programma per l'invio del messaggio Wake-On-Lan

Il programma che invia il messaggio Wake-On-Lan dovrà essere impostato usando i seguenti parametri:

  • Indirizzo MAC : useremo questo parametro non per "svegliare" un dispositivo di rete, ma lo useremo come codice univoco per eseguire una determinata azione all'interno dello script sul router. Consiglio comunque di usare un indirizzo MAC ben progettato, anche per questioni di sicurezza.
  • Indirizzo IP : qui metteremo l'indirizzo IP del router (eventualmente usando un indirizzo DDNS se dobbiamo accedere al router al di fuori della Rete Locale);
  • Porta : qui metteremo il numero di porta che useremo nel router come parametro del daemon "socat". Consiglio di evitare di usare le porte standard usate dai servizi Internet, ancor più sconsiglio di usare le porte 7 e 9 usate dal protocollo Wake-On-Lan.

Come impostare uno script usato dal daemon "socat"

Come vedremo in seguito, il daemon "socat" passerà il messaggio Wake-On-Lan ricevuto ad uno script e questo script dovrà essere in grado di interpretare il messaggio Wake-On-Lan ed eseguire determinate azioni. Qui di seguito vediamo un esempio di script, gli diamo il nome "wol_script.sh" (ricordarsi di impostare opportunamente le proprietà di esecuzione del suddetto script usando il comando "chmod +x wol_script.sh" altrimenti il daemon "socat" non potrà eseguirlo):

#!/bin/bash

read MESSAGE
echo "PID: $$"
echo "$MESSAGE"

hexvar=$(echo $MESSAGE | /opt/bin/od -t x1)
echo $hexvar

# execute action 1
if echo $hexvar | grep -q -i "ff ff ff ff ff ff 11 22 33 44 55 66"; then
    # WOL message is received, we run a command
    echo "1 String contains hex is true."
else
    echo "1 String contains hex is not true."
fi

# execute action 2
if echo $hexvar | grep -q -i "ff ff ff ff ff ff 11 77 88 99 AA BB"; then
    # WOL message is received, we run a command
    echo "2 String contains hex is true."
else
    echo "2 String contains hex is not true."
fi

Come si evince dal suddetto script, eseguiamo le seguenti operazioni:

  • con il comando "read MESSAGE" andiamo a leggere il messaggio passatoci dal daemon "socat" sullo standard input e inseriamo il suddetto messaggio nella variabile "$MESSAGE";
  • tramite il comando "/opt/bin/od", la variabile "$MESSAGE" viene convertita in formato esadecimale e il contenuto viene inserito nella variabile "$hexvar";
  • quindi controlliamo tramite un'istruzione "if" se la suddetta variabile "$hexvar" inizia con la stringa "ff ff ff ff ff ff 11 22 33 44 55 66". Questa stringa non è altro che la stringa iniziale "ff ff ff ff ff ff" di ogni messaggio Wake-On-Lan, oltre all'indirizzo MAC "11 22 33 44 55 66" fittizio che dovremo inserire nel programma che invia il messaggio Wake-On-Lan; se il confronto ha successo, allora possiamo eseguire un qualunque comando, ad esempio eseguire un altro script, eseguire un'istruzione, ecc...

Le istruzioni "echo" incluse nello script sono usate solo per questioni di debugging, potranno essere eliminate una volta capito il procedimento.
Ovviamente potremo inserire più istruzioni "if" con diversi indirizzi MAC, ricordandoci di usare un carattere spazio tra un numero esadecimale e il successivo. All'atto pratico, nel programma che deve inviare il messaggio Wake-On-Lan, potremo aggiungere più voci Wake-On-Lan, ma l'unica cosa che cambierà sarà il valore dell'indirizzo MAC fittizio, i valori dell'indirizzo IP del router e della porta rimarranno sempre gli stessi.


Come eseguire il daemon "socat" per ricevere il messaggio Wake-On-Lan

Una volta impostato il programma che deve inviare il messaggio Wake-On-Lan ed una volta impostato lo script che dovrà ricevere il messaggio Wake-On-Lan, andiamo ad eseguire il daemon "socat". Una tipica istruzione che possiamo eseguire è la seguente:
/opt/bin/socat -u -T1 UDP-LISTEN:25000,fork system:/opt/etc/wol_script.sh
Nella suddetta istruzione abbiamo i seguenti parametri (per maggiori informazioni sul daemon "socat" fare riferimento a questa pagina su Internet):

  • con ill parametro "-u" impostiamo il daemon "socat" nella modalità unidirezionale, quindi avremo una prima parte di lettura, ed una seconda parte di scrittura;
  • con il parametro "-T1" impostiamo il timeout di inattività, ovvero quando il "socat" sta trasferendo dati e non succede nulla per N secondi (in questo caso 1 secondo), allora esso termina;
  • con il parametro "UDP-LISTEN:25000" mettiamo il "socat" nella condizione di "ascoltare" la porta UDP 25000. Questa è la stessa porta che dovremo utilizzare nel programma che invia il messaggio Wake-On-Lan;
  • con il parametro "fork" diciamo al "socat" di creare un nuovo processo "figlio" ogni qualvolta riceve una connessione e contemporaneamente il processo "padre" del "socat" continua ad accettare altre connessioni;
  • con il parametro "system:/opt/etc/wol_script.sh" diciamo al "socat" di creare un sottoprocesso, tramite il suddetto parametro "fork", che esegue lo script "/opt/etc/wol_script.sh". Il "socat", dopo aver avviato lo script, scrive i dati sullo standard input del processo figlio (questi dati verranno letti dallo script, come evidenziato nel precedente paragrafo) e legge i dati dallo standard output.

La suddetta istruzione, se eseguita nel terminale del router, verrà eseguita in modalità di debugging come utente "root". Per questioni di sicurezza, consiglio di eseguire il daemon "socat" tramite l'utente "nobody" (ovviamente anche lo script verrà eseguito come utente "nobody", e così anche tutti i comandi eseguiti all'interno dello script). Per fare questo, bisogna usare il comando "daemonize", comando che si può installare tramite un pacchetto Entware con l'istruzione "opkg install daemonize".
Il daemon "socat" potrà essere quindi eseguito con la seguente istruzione:
daemonize -u nobody /opt/bin/socat -u -T1 UDP-LISTEN:25000,fork system:/opt/etc/wol_script.sh