Get-FritzMACTable
Bei meinen IoT-Experimenten war es mir auf Dauer zu nervig, die Fritz!Box immer auf MAC-Adressen per Browser zu durchsuchen. Das hier vorgestellte PowerShell-Script nutzt die TR064-Schnittstelle, um eine Liste der MAC-Adressen zu ermitteln. Vielleicht wird irgendwann ja auch mal eine Tray-App draus.
Die Seite findet sich aber unter dem Bereich "PRTG - Monitoring für den KMU", weil über einen Schalter damit auch die Aktiven/Passiven Hosts oder sogar jede MAC-Adresse als Kanal in PRTG abgebildet werden kann.
Quellen-Studium
Leider unterstützt die Fritz!Box kein SNMP. Aber per TR-064 kommt man auch recht weit, zumal AVM die Schnittstellen auf https://avm.de/service/schnittstellen/ sehr ausführlich dokumentiert.
- Entwicklersupport
https://avm.de/service/schnittstellen/ - Beschreibung zu den Hosts
https://avm.de/fileadmin/user_upload/Global/Service/Schnittstellen/hostsSCPD.pdf - AVM TR-064 – First Steps Supported by
AVM
https://avm.de/fileadmin/user_upload/Global/Service/Schnittstellen/AVM_TR-064_first_steps.pdf
Einige andere Vorarbeiten zu meiner Fritz!Box habe ich ja schon veröffentlicht:
Damit war eigentlich klar, dass ich eigentlich nur den Service "urn:LanDeviceHosts-com:serviceId:Hosts1" unter der URL "/upnp/control/hosts" abfragen muss
Interessant sind hier die URLs und die weitere Definition der "Service Controlled Protocol Descriptions" (SCPD)
API-Beschreibung
Aus der ersten XML ergibt sich eine Url für die Servicebeschreibung. Sie übernehmen einfach den Wert aus "SCPDUTL" und hängen ihn an den Hostnamen und TR-064-Port an
http://fritz.box:49000/hostsSCPD.xml
Wenn Sie die Daten nicht per Brower parsen wollen, dann hilft ihnen die PowerShell auch hier:
$hostsSCPD = Invoke-WebRequest http://fritz.box:49000/hostsSCPD.xml ([xml]$hostsSCPD.Content).scpd.actionList.action name argumentList ---- ------------ GetHostNumberOfEntries argumentList GetSpecificHostEntry argumentList GetGenericHostEntry argumentList X_AVM-DE_GetChangeCounter argumentList X_AVM-DE_SetHostNameByMACAddress argumentList X_AVM-DE_GetAutoWakeOnLANByMACAddress argumentList X_AVM-DE_SetAutoWakeOnLANByMACAddress argumentList X_AVM-DE_WakeOnLANByMACAddress argumentList X_AVM-DE_GetSpecificHostEntryByIP argumentList X_AVM-DE_HostsCheckUpdate X_AVM-DE_HostDoUpdate argumentList X_AVM-DE_GetHostListPath argumentList X_AVM-DE_GetMeshListPath argumentList
Jetzt kennen Sie alle "Funktionsaufrufe", die diese Schnittstelle anbietet. Sie sind hier auch beschrieben:
TR-064 Support – Hosts
https://avm.de/fileadmin/user_upload/Global/Service/Schnittstellen/hostsSCPD.pdf
Der Anfang ist dabei die Funktion "X_AVM-DE_GetHostListPath" zu dem die Dokumentation schreibt:
Gets a path to a lua script file, which
generates an XML structured list of hosts. A generated xml
example is shown in 4.1 Host List Contents
Required rights : PhoneRight, AppRight
Ich muss also den Service "urn:dslforum-org:service:Hosts:1" anfordern und die Funktion "X_AVM-DE_GetHostListPath" aufrufen. Allerdings sind diese Abfragen nicht mehr "anonym" möglich. Ich muss also das Kennwort der Fritz!Box zusammen mit dem Benutzernamen "admin" übermitteln.
-
PS Passwort / Kennwort
Achten Sie auf ihre Kennwort, wenn Sie es im Code hinterlegen
Wireshark
Es war dann nicht sonderlich schwer, daraus ein PowerShell-Script zu bauen ,welches die Daten bezieht. Allerdings gibt es schon zwei Besonderheiten zu beachten, die mit Wireshark bei Nutzung einer unverschlüsselten Verbindung über Port 49000 einfach zu sehen sind:
- Authentifizierung
Man kann nicht schon mit dem ersten Request die Benutzername/Kennwort-Information mit senden. Der erste Request erfolgt anonym und die Fritz!Box bietet dann Digest an
- Zweiter Request liefert nur Download-URL
Nach einer gültigen Anmeldung per "Digest" liefert die Box eine URL zum Download der eigentlichen Information
- Anonymer Download
Die gewünschte Information selbst gibt es dann wieder anonym. Die "sid" ist eine Sitzungskennung, die nur kurz gültig ist. Das ist dann eine XML-Struktur
Ergebnis
Die XML-Datei lässt sich natürlich recht einfach ausgeben. Das Skript gibt dazu direkt die Liste mit folgender Zeile an die Pipeline aus
$devicehostlist.List.Item.GetEnumerator()
Ohne weitere Formatierung bekommt Sie die Daten als Liste. Jeder Datensatz hat dabei folgende Felder:
Index : 55 IPAddress : 192.168.178.2 MACAddress : 70:4F:57:23:1A:19 Active : 1 HostName : TPLink-T2600-28 InterfaceType : Ethernet X_AVM-DE_Port : 3 X_AVM-DE_Speed : 1000 X_AVM-DE_UpdateAvailable : 0 X_AVM-DE_UpdateSuccessful : unknown X_AVM-DE_InfoURL : X_AVM-DE_Model : X_AVM-DE_URL : http://192.168.178.2 X_AVM-DE_Guest : 0 X_AVM-DE_WANAccess : granted X_AVM-DE_Disallow : 0
Leider ist nicht zu sehen, wann ein Gerät das letzte mal aktiv war oder wie alt der Eintrag in der MAC-Tabelle ist. Allerdings gibt es ein Feld "Active", welche bei inaktiven Geräten auf "0" steht. Anscheinend löscht die Fritz!Box aber keine einmal gelernte Geräte.
Sie können die Liste damit einfach auf die Console als Liste oder als Tabelle ausgeben lassen
.\get-fritzmactable.ps1 | ft MACAddress,IPAddress,Active,HostName,X_AVM-DE_Port
Dann sehen Sie sehr schnell alle Geräte.
Die aktiven Geräte können Sie auch schnell filtern.
.\get-fritzmactable.ps1 | ?{$_.active -eq 1}| ft MACAddress,IPAddress,Active,HostName,X_AVM-DE_Port
Die Ports 1-4 entsprechen den Ethernet-Ports. Geräte, die per WLAN (2,4 oder 5 GHz) angebunden sind, erscheinen aber als Port 0. Eine Unterscheidung nach der Frequenz gibt es nicht. Wie sich die Geräte hinter einem Mesh-Netzwerk ausgeben, kann ich mangels Repeater nicht testen.
Das Skript
Sie können das folgende PowerShell-Skript einfach in ein Verzeichnis herunterladen und aufrufen. Denken Sie daran, dass Sie als Parameter mindestens das Kennwort für ihre Fritz!Box angeben müssen. Getestet habe ich das mit meiner FB7950 und Firmware 7.x aber die verwendete API ist schon viel älter und sollte daher auch mit früheren Versionen nutzbar sein.
get-fritzmactable.20201122.ps1
Das Skript nutzt die PowerShell-Commandlets "Invoke-RestMethod" und da die Fritzbox kein öffentlich vertrauenswürdiges Zertifikat hat, muss ich den Parameter "SkipCertificateCheck" addieren, der aber erst ab PowerShell 7.0 verfügbar ist. Leider gibt es in PRTG aktuell keine Option eine bestimmte Shell aufzurufen. Ich nutze daher immer eine CMD-Datei, die dann die gewünschte Powershell mit dem Skript als Parameter startet.
REM Startet das PS1-Skript mit der richtigen Powershell und Parametern "C:\Program Files\PowerShell\7\pwsh.exe" ^ -nologo ^ -NonInteractive ^ -command "& ""C:\Program Files (x86)\PRTG Network Monitor\Custom Sensors\EXEXML\get-fritzmactable.ps1"" -FBKennwort:""geheimeskennwort"" -prtg"
Alternativ können Sie den Abruf von HTTPS über Port 49443 auf http und Port 49000 umstellen und den Parameter SkipCertificateCheck entfernen.
- Invoke-RestMethod
https://docs.microsoft.com/en-us/powershell/module/microsoft.powershell.utility/invoke-restmethod?view=powershell-7 - Guide for PowerShell-based Custom sensors
https://kb.paessler.com/en/topic/71356-guide-for-powershell-based-custom-sensors
PRTG
Natürlich gibt es in dem Code auch zwei Schalter, die eine PRTG-kompatible Ausgabe liefern:
- -prtg
Liefert eine kleine XML mit der Anzahl der aktiven und passiven Hosts - -prtgdetail
Liefert neben der Anzahl auch jede MAC-Adresse als eigener Kanal mit dem individuellen Status. Beachten Sie, das PRTG maximal 50 Kanäle offiziell unterstützt. Durch IoT-Geräte und Gäste kann dies sehr schnell erreicht sein.
Das Skript funktioniert auf jeder PRTG-Probe und liefert die Ergebnisse per STDOUT an die aufrufende Instanz aus. Denken Sie an die Angabe des Parameters und des Kennworts in der Konfiguration.
Weiterentwicklung
Aktuell habe ich keine Weiterentwicklung geplant. Interessant könnte es aber schon sein, eine Tray-App zu nutzen, die regelmäßig den Status abfrage und Sie über neue Geräte informiert. Die gleiche Schnittstelle kann übrigens auch genutzt werden, um z.B. die Präsenz eines Geräts zu überwachen. Dazu wäre es natürlich besser, eine "Push-Funktion" zu haben anstatt die Daten immer wieder abzurufen.
Weitere Links
- Fritz!Box Monitoring
- PRTG Fritz!Box
- PowerShell und SOAP
- PS Passwort / Kennwort
- PRTG - Custom Sensor
- PowerShell Parameter
- Invoke-RestMethod
https://docs.microsoft.com/en-us/powershell/module/microsoft.powershell.utility/invoke-restmethod?view=powershell-7.1
- Entwicklersupport
https://avm.de/service/schnittstellen/ - Beschreibung zu den Hosts
https://avm.de/fileadmin/user_upload/Global/Service/Schnittstellen/hostsSCPD.pdf - AVM TR-064 – First Steps Supported by
AVM
https://avm.de/fileadmin/user_upload/Global/Service/Schnittstellen/AVM_TR-064_first_steps.pdf - Powershell: FritzBox über TR-064 im
Netzwerk konfigurieren und auslesen
https://administrator.de/tutorial/powershell-fritzbox-tr-064-netzwerk-konfigurieren-auslesen-303474.html - Fritz eingeseift Fritzbox per Skript
fernsteuern
https://www.heise.de/ct/ausgabe/2015-6-Fritzbox-per-Skript-fernsteuern-2550325.html