Wake On Lan für VirtualBox

Es geht doch!

Es gibt immer wieder die Frage ob man nicht auch eine Virtualisierung per WOL (Wake On Lan) aufwecken kann. Die Antwort ist Nein (bis jetzt).

Es gibt immer wieder Ansätze dies zu umgehen; man stößt aber immer wieder auf die gleichen Probleme das die virtuelle Netzwerkkarte eben kein WOL unterstützt.

Wie geht das ganze denn?

Bei einem normalen Rechner der WOL unterstützt wird dies durch die Netzwerkkarte bereitgestellt. Dazu wird diese noch mit Strom versorgt wenn der Rechner ausgeschaltet ist. Wird nun eine bestimmte Sequenz an die Netzwerkkarte gesendet die die Mac-Addresse der Netzwerkkarte enthält, 'betätigt' die Netzwerkkarte den Ein-Schalter. Dazu muß der Rechner der aufwecken will nur ein Datenpaket an den Rechner senden der geweckt werden soll. Ab den 6. Byte wird die Macadresse, des Rechners der aufgeweckt werden soll, immer wieder wiederholt. Es spielt dabei keine Rolle welche Art das Datenpaket hat. Ob dies nun TCP, UDP, ARP oder sonst einen Header hat, ist nicht von Bedeutung. Es hat sich eingebürgert UDP Pakete auf den Port 9 zu senden. Einige Programme senden auch auf Port 7. UDP wird verwendet weil dieses Protokoll keine Bestätigung erwartet.

Wie geht das nun bei einer Virtualisierung?

Hierzu starte ich ein Programm das auf die Ports 7 und 9 'lauscht'. Wenn dort ein Paket eintrifft, wird nachgesehen welche Mac-Addresse gesendet wird. Ist es eine Mac-Addresse die dem Programm bekannt ist, löst es ein Befehl aus. Damit man eine Virtuallisierung nicht mehrfach starten kann, wird vor jedem Start nachgesehen ob das Programm nicht schon aktiv ist. Damit dies auch nicht mehrfach gestartet weren kann bevor der Rechner die Virtuallisierung aufgerufen hat, kann auch ein Timeout definiert werden, in der keine Pakete angenommen werden.

Das ganze funktioniert nicht nur mit einer Virtuallisierung, sondern mit jedem Programm. Man kann seinen Rechner also 'Fernsteuern' über definierte WOL-pakete. Dazu können Funktionen gestartet oder beendet werden die beliebig definierbar sind.

Leider gibt es zu dieser eingebürgerten Vorgehensweise die Pakete per UDP zu senden auch Ausnahmen. Eine dieser Ausnahmen ist das tool etherwake. Dieses sendet ein Paket mit einem 'eigenen' Header der es nicht ermöglicht die 'üblichen' Methoden zu nutzen um auf bestimmte Pakete zu Lauschen. Die einzige Methode die dies ermöglichen würde wäre das Sniffen aller Daten. Da bei Virtuallisierungen aber oft große Datenmengen über ein Interface gehen, würde das sehr viel Rechenleitung vergeuden. Da es Alternativen zu etherwake gibt die auch UDP versenden, habe ich mir nicht die Mühe gemacht um das Sniffen zu implementieren.

Gibt es alternativen?

Ja, wenn man anderen Methoden verwendet (z.B. knock) kann man das auch anders realisieren, leider nicht mehr mit den Tools die auf allen Rechnern verfügbar sind.

Wie wird das installiert?

Das ganze ist in einem TGZ-File untergebracht. Dies muß entpackt werden und übersetzt werden. Noch ein bischen Kopieren und alles ist fertig zum Start.

tar -xzvf wol_srv.tgz
cd wol_srv
make
cp -a wol_srv /usr/bin/
cp -a wol_srv.sh /etc/init.d/wol_srv
cp -a wol_srv.conf /etc/

Nun kann die Datei /etc/wol_srv.conf mit einem Editor der Wahl bearbeitet werden. Ich habe das ganze auf einem Ubuntu-LTS-System installiert. Mit ein bischen Anpassung an den Startscript (wol_srv.sh) kann dies auf jeder Distribution installaiert werden.

Die Config-Datei:

# config file for wol_srv

# pidfile (if needed)
pidfile = "/run/wol_srv.pid"

# enable daemon-mode
daemon = on

# list of ports to listen
udp-ports =

# set debug-messages to on
debug = on

# accept only one packet from the same connection
only-one-packet = on

# section for every programm to start

srv Win7DvbFab

 

In einigen Distributionen sind die PID-Files unter /var/run/ untergebracht. Dies muß entsprechend angepaßt werden. Wird kein pidfile angegeben, wird auch keines erzeugt. Die Mechanismen für das erkenen von bereits gestarteten Prozessen wird dann nicht funktionieren.

daemon = on
Dies bedeutet das das Programm im Background läuft. Wird off angegeben, kann man sehen was empfangen wird.

debug = on
Ist Debug on, wird werden einige Statusmeldung ausgegeben. Dies ist sehr hilfreich wenn man sehen will ob ein WOL-Paket überhaupt am rechner ankommt.

udp-ports =
Hier werden die Ports angegeben auf die wol_srv lauschen soll. Für jeden Port wird ein eigener Prozess gestartet.

only-one-packet = on
Einige Programme (z.B. wol2.exe unter Windows) senden mehrere Pakete über die gleiche Verbindung. Ist hier 'on' eingetragen, werden zusätzliche Pakete ignoriert. Das minimiert die Anzahl der Logeinträge für Ignorierte Pakete.

srv Win7DvbFab
Dies sind die Einträge für jeden Server der gestartet werden soll. Nach dem Bezeichner für diese Konfiguratuion (srv) wird eine frei wählbarer Name erwartet. Diese Wird verwendet um in den Logfiles die Zuordnungen zu vereinfachen.

In den geschweiften Klammern werden dann die Daten für den Server angegeben.

timeout = 3
Wird ein weiteres Paket innerhalb der timeout-zeit auf diesem Port gesendet, wird dies Ignoriert.

mac = "08:00:27:6c:32:49"
Dies ist die Mac-Adresse des Rechners der aufgeweckt werden soll. Dies kann eine Mac-Adresse sein oder ein beliebiger Text. Es wird auf beides verglichen. Die WOL-Software sendet meist aber nur die entsprechenden HEX-Daten. Es ist hier wichtig das auf Klein/Groß-Schreibung für die Hex-Zahlen geachtet wird. Hier wird konsequent die Kleinschreibung verwendet.

ignore-start = "startvm d618fcde-9d4c-45e4-b9f3-8e8749fd2e15"
Wir ein Befehl zum Starten gesendet, wird dieser nicht ausgeführt wenn es in der Prozessliste die angegebenen Zeichenkette gibt. Mit 'ps -ax' aknn ermittelt werden wie ein bereits gestartetes Programm zu identifizieren ist. Wird dies weggelassen, dann wird auch nicht geprüft ob der Prozess bereits gestartet wurde.

start = "su vboxusers -c 'VBoxManage startvm Win7DvbFab --type headless'"
Das ist der Befehl der zum 'Starten' ausgeführt wird. Im falle der VBox kann dies so aussehen. Das Programm muß so gestartet werden das es die shell auch wieder verläßt. Geht das Prgramm nicht in den Hintergrund muß >/dev/null 2>/dev/null & mit angegeben werden.

Es können bis zu 100 srv definiert werden.... das sollte wohl reichen ;-)

Noch zum Aufbau des Programms ein paar Worte.
Das Projekt wäre nicht so schnell umsetzbar gewesen, hätte ich nicht auf auf ein Tool zum parsen der Config-Dateien zurückgegriffen. Verwendet habe ich confuse in der Version 2.7. Ursprünglich ist das eine Library die auf dem System erst installiert werden muß. Damit dies nicht zu einem Hinderniss wird, habe ich die Sourcen hiervon mit eingebunden. Die entsprechenden README usw. habe ich zu den Quellen zugefügt. Hier noch ein dank an Martin Hedenfalk und Josh Myer die confuse erstellt haben.

Und hier ist mein Werk zum Download.

Ich hoffe Ihr habt Spaß ;-)