Windows: Wake on LAN über VPN

Wake on LAN (WoL) funktioniert über das Internet nicht, das gilt gleichfalls für VPN-Verbindungen bzw. generell alles außerhalb des (Ziel-)Subnetzes. Abhilfe kann man sich schaffen, in dem von einem (Dauer-)laufenden System aus z.B. der Arbeitsplatz gestartet wird.

Damit man nicht extra beispielsweise aus dem Web-Interface einer Securepoint UTM, einem bereits laufenden PC oder von einem Server aus der eigentliche Ziel-Rechner gestartet werden muss kann man sich relativ leicht behelfen. Vor Jahren habe ich eine Lösung für einen Kunden gebaut, die bis heute läuft und in der Zwischenzeit auch bei anderen Kunden sowie Kollegen Anwendung findet.

Der Ablauf ist dabei simple:

Auf dem sowieso immer laufenden Server wird ein Webserver betrieben. Mittels (automatischen) Aufruf eines Skripts nach dem Herstellen der VPN-Verbindung wird der zu startende Computer über diesen Webserver per WoL eingeschaltet.

Am Bespiel von Apache (die Variante von Apache Lounge) sieht das so aus:

Unter “C:\Apache24\cgi-bin” wird folgendes Batch-Skript und die wol.exe von Gammadyne hinterlegt:

@echo off

cd "C:\Apache24\cgi-bin"

REM echo %date% %time% - hello world >> test.txt

wol.exe <MAC-Adresse>

echo Content-type: text/plain

echo.

Wenn man erstmal nur testen möchte, kann man zunächst nur ein Protokoll schreiben lassen und die Zeile mit “wol …” auskommentieren.

Ruft man mit einem Browser nun folgende URL auf:

http://<IP-des-Servers>/cgi-bin/<Skriptname>.cmd

wird das Skript ausgeführt. Eine weitere Konfiguration des Apache ist nicht notwendig.

Damit das Ganze vom VPN-Client aus anwenderfreundlicher ist, kommen ein paar kleine Skripte ins Spiel:

Der VPN-Client startet nach dem Aufbau der Verbindung automatisch das Skript “vwr.cmd”, dieses wiederum startet die “vwr.exe”:

@echo off

cd C:\VPN
vwr.exe

Die “vwr.exe” ist ein kompiliertes AutoIt-Skript.

Der Original-Quellcode findet sich hier:

Zum Aufklappen anklicken.
; AutoIt TrayIcon ausblenden

#NoTrayIcon

; Include-Dateien

#include <GUIConstantsEx.au3>

; Konfiguration einlesen

$Host = IniRead("vwr.ini", "VPN", "Host", "error")
$Countdown = IniRead("vwr.ini", "VPN", "Time", "error")
$WoL = IniRead("vwr.ini", "VPN", "WoL", "error")

If ($Host="error") or ($Countdown="error") or ($WoL="error") then
MsgBox(16, "VPN", "Fehler beim Lesen der Konfiguration")
Exit
EndIf

; Wartezeit in Sekunden umrechnen
; 60000 ms = 60 Sekunden = 1 Min

$Countdown = $Countdown*60000/1000

; Prüfen, ob der Ziel-Host erreichbar ist, andernfalls diesen per WoL starten und warten

$Pong = Ping($Host, 1000)

If $Pong = 0 Then

; WoL auslösen
InetGet($WoL, "")

; Countdown-Timer
; Fenster erzeugen
GUICreate("VPN", 268, 55)
GUISetState(@SW_SHOW)
GUICtrlCreateLabel("Bitte warten, bis das der Arbeitsplatz-PC gestartet ist:", 10, 10)

While 1
GUICtrlCreateLabel ( $Countdown & " Sekunden", 10, 30)
$Countdown=$Countdown-1
If $Countdown=0 Then ExitLoop
; Pause von einer Sekunde
sleep(1000)
WEnd

; Fenster schliessen
GUIDelete()

EndIf

; Remotedesktopverbindung aufbauen

Run("mstsc.exe arbeitsplatz.rdp")

In der “vwr.ini”-Datei wird die IP-Adresse des Ziel-Computers hinterlegt und der Webserver-Aufruf. Beispiel:

[VPN]
Host=192.168.2.36
Time=2
WoL=http://192.168.2.10:8080/cgi-bin/pc01.cmd

VWR steht übrigens für VPN, Wake on LAN und RDP.

Zunächst wird der Ziel-Computer angepingt, kommt keine Antwort, kann man davon ausgehen, das dieser heruntergefahren ist. Daraufhin wird der “WoL-Aufruf” durchgeführt, eine vordefinierte Zeit (Time, 1-2 Minuten bei Version 1, 30 Sekunden bei Version 2) gewartet und dann die RDP-Verbindung initiiert.

Während auf das Starten des Ziel-Computers gewartet wird, läuft ein sichtbarer Countdown ab.

In der Zwischenzeit ist eine leicht aktualisierte Version entstanden, die nicht mehr mit Minuten, sondern Sekunden arbeitet. Version 1 stammt noch aus der Zeit der Festplatten als Computer noch durchaus mehrere Minuten zum Starten benötigt haben. Version 2 trägt der Verbreitung von SSDs sowie neueren Windows-Versionen Rechnung, da ein modernes System meist in 20 – 30 Sekunden einsatzbereit ist.

Im nachfolgenden downloadbaren ZIP-Archiv befindet sich der Quellcode beider Versionen sowie entsprechend kompilierte vwr.exe-Dateien, alle anderen Skripte wie *.ini und *.cmd sowie Beispiel-*.rdp-Dateien:

VWR.zip

Als leichtgewichtigen Webserver nutze ich mittlerweile den TinyWeb Server, der mittels NSSM als Dienst eingerichtet wird.

Nebenbei bemerkt: Es gibt noch eine ältere Variante, bei der PHP zum Einsatz kam, evtl. reiche ich diese bei Gelegenheit nach. Das Ganze dürfte sich zudem leicht z.B. auf Linux adaptieren lassen.

Update 13.06.2019

Hier also nun die PHP-Variante:

Apache oder anderer Webserver samt PHP muss (natürlich) eingerichtet sein. Dann eine Datei beispielsweise mit dem Namen “wol-pc01.php” anlegen und folgenden Inhalt einfügen:

<?php

exec ("wol.exe <MAC-Adresse>");

?>

Via vwr wird’s in der Ini dann z.B. so aufgerufen:

WoL=http://192.168.2.10:8080/wol-pc01.php

Neben der Variante aus PHP heraus einen Befehl auszuführen gibt es die Möglichkeit, die für Wake-on-LAN benötigten Magic Pakets auch direkt aus PHP heraus zu versenden:

PHP.de – Wake-on-Lan mit PHP (gelöst)

Synology – Wiki – Wake on LAN (WOL) nur mit PHP, auch über das Internet

Das habe ich allerdings nie getestet.

Unter Linux kann man statt der “wol.exe” z.B. die Befehle “wakeonlan” (Debian & Co.) oder “wol” (RedHat & Co.) verwenden.

Update 05.10.2022

Den Beitrag überarbeitet, einen Download hinzugefügt und um Version 2 ergänzt.

Vielen Dank an Alex für den Auftrag, der dieses Update möglich gemacht hat.

13 Kommentare

  • Hallo,
    ich wäre sehr an einer PHP variante interessiert, und würde mich freuen wen Sie diese nachreichen würden.

    Mit freundlichen Grüßen

    Max

  • Hallo Max,

    danke für dein Kommentar. Habe den Beitrag soeben ergänzt.

  • Hallo,

    ich bekomme beim Ausführen der “vwr.exe” die Mitteilung, dass diese App auf dem System nicht ausgeführt werden kann? Ist das Script eventuell unter 64bit OS nicht lauffähig?

    Gruß
    Frank

  • Hallo Frank,

    bei mir hat das bislang immer funktioniert, gerade erst vor einer Woche wieder bei einem Kunden implementiert.
    Das AutoIt-Skript an sich macht ja nichts besonderes, das nun irgendwie 32- oder 64-bit abhängig wäre.
    Ob es eine 32- oder 64-bit Exe ist kann man beim Kompilieren festlegen.
    Grundsätzlich funktioniert die 32-bit Exe allerdings auch auf 64-bit Windows.

    Erfahrungsgemäß würde ich zunächst auf den Virenscanner tippen, da diese ganz gerne mal mit UPX-gepackten Dateien so ihre Schwierigkeiten haben. Siehe dazu auch:

    Kompilierte AutoIt-Skripte und die Virenscanner

  • Hallo Andy,

    das klingt sehr interessant als Ansatz für einen Kunden von mir. da geht es um 5-10 Home-Arbeitsplätze. Gerade jetzt in der Energiekrise wäre das interessant. Können wir hier ggf. zusammenarbeiten auf Bezahl-Ebene? Ich bin da leider Ressourcenmässig sehr ausgelastet.

    Mit freundlichen Grüßen

    Alex

  • Hallo Alex,

    da lässt sich was machen. Es gibt mittlerweile sogar einen zweiten (imho) einfacheren Weg mit einem anderen Webserver.
    Einfach direkt bei mir in der Firma melden: https://www.its-weber.de/
    Dann machen wir etwas aus.

    Beste Grüße,

    Andy

  • Hallo,

    ich versuche gerade mit dem TinyWeb Server Wake on Lan umzusetzen. Allerdings klappt es mit der .cmd Datei und dem Aufruf über den Browser nicht. Statt den Wake on LAN Befehl auszuführen wird der Inhalt der .cmd Datei angezeigt:

    @echo off

    cd “C:TinyWebwwwcig-bin”

    REM echo %date% %time% – hello world >> test.txt

    wol.exe 00:11:32:61:fd:f2

    echo Content-type: text/plain

    echo.

    Rufe ich sie direkt aus dem Windows-Verzeichnis auf klappt es.
    Was mache ich da falsch?

    Viele Grüße
    Matthias

  • Dann ist dieser Beitrag hilfreich:

    TinyWeb Server – Extrem kompakter und portabler Webserver für Windows

    Vmtl. liegt es daran, das beim Tiny der “cgi-bin”-Ordner im Wurzelverzeichnis, also z.B. “C:TinyWebwwwcgi-bin”, sein muss.

  • Hallo Andy,

    vielen Dank für die schnelle Antwort.
    Leider liegt es daran nicht. Der “cig-bin”-Ordner liegt genau in dem Verzeichnis.

    Deinen Beitrag zum TinyWeb Server hatte ich mir schon durchgelesen und mich auch an die Ordnerstruktur gehalten.
    Mal sehen vielleicht finde ich die Ursache noch, sonst muss ich mir eine andere Möglichkeit einfallen lassen.

    Viele Grüße
    Matthias

  • > Der “cig-bin”-Ordner liegt genau in dem Verzeichnis.

    Du meinst “cgi-bin”? Nicht dass das Ganze an einem Schreibfehler hängt.

    Ich hab’ vorige Woche erst einen TinyWeb für WoL über VPN eingerichtet und das läuft wie es soll.
    Die obligatorische “index.html” gibt es ebenfalls?
    Sicher das die *.cmd nicht noch auf *.txt endet?
    Nicht das es am Ende an den per Standard ausgeblendeten Dateierweiterungen in Windows scheitert.

  • Hallo Andy,

    wie war das mit den Bäumen und dem Wald?
    Du hast natürlich recht. Ich hatte das Verzeichnis tatsächlich “cig-bin” statt “cgi-bin” benannt und da konnte es nicht gehen!

    Rufe ich die .cmd-Datei jetzt auf klappt auch WOL.

    Im Browser erscheint aber “CGI script /cgi-bin/Start.cmd returned nothing”
    mit “500 Internal Server Error” als Titel.

    Fällt dir dazu noch etwas ein?

    Vielen Dank!

    Viele Grüße
    Matthias

  • Die Meldung ist ok, da in der Tat dieses Skript nichts brauchbares für den Webserver ausgibt.

  • Hallo Andy,

    perfekt dann funktioniert es jetzt wie gewünscht.
    Vielen Dank noch mal für deine Hilfe bei der “Fehlersuche”.

    Viele Grüße
    Matthias

Schreibe einen Kommentar

Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind mit * markiert