FB 7390:DSL-Daten über UPnP auf Shell-Ebene auslesen

Fischers Freetz

Mitglied
Mitglied seit
16 Jun 2008
Beiträge
327
Punkte für Reaktionen
1
Punkte
18
Hallo!

Ich würde gerne die DSL-Daten (Geschwindigkeit, Downstream/Upstream) meiner FB auslesen, aber auf Shell-Ebene (Linux), also ohne GUI.

Das OS auf der FB hat den allerneuesten Stand: 6.23.

Weiß jemand, ob und wie das geht?
 
Schau mal unter http://avm.de/service/schnittstellen/, da gibts eine Reihe von Dokumenten, die die API-Schnittstelle zum Auslesen verschiedener Daten beschreiben. Wenn die Oberfläche der Box passwortgeschützt ist, brauchst du ein (PHP)-Script, das die Anmeldung bewerkstelligt.
 
Ich würde gerne die DSL-Daten (Geschwindigkeit, Downstream/Upstream) meiner FB auslesen, aber auf Shell-Ebene (Linux), also ohne GUI.
Klingt auf den ersten Blick zwar logisch, läßt aber schon noch Fragen offen. Meinst Du mit "Shell-Ebene" eine externe Shell oder die Telnet-Shell der FRITZ!Box? Heißt "ohne GUI", daß es auch kein "wget"-Kommando sein darf?

Wie oft willst Du das denn machen? Wenn es regelmäßig passieren soll und sich die Anwendung dann jedesmal neu anmeldet, ist schnell das Log vollgeschrieben und es gehen u.U. wichtige Meldungen verloren.

Nachdem ab 06.23 wohl auch überall kein nc mehr vorhanden ist, ist es etwas komplizierter ... ansonsten ist z.B. eine Ausführung von
Code:
nc -ll -p 999 -e /sbin/showdsldstat
auf der FRITZ!Box eine Möglichkeit und die läßt sich dann von jedem anderen Rechner (im LAN!) mit "nc fritz.box 999" problemlos abfragen. Natürlich kann man anstelle des "nc"-Kommandos auch "telnetd" verwenden:
Code:
telnetd -l /sbin/showdsldstat -b 192.168.178.1 -p 999
(Hallo AVM, wenn schon dann richtig! - Ob man den Angriff mit dem telnetd oder mit nc startet, ist eher nebensächlich.)

Dann fragt man eben auch die Daten mit "telnet" ab:
Code:
telnet fritz.box 999
Genauso gut kann man natürlich auch gleich auf der FRITZ!Box nur ein Skript starten lassen (egal ob nc oder telnetd), das genau die gewünschten Daten ausgibt ... wo man das Parsen machen läßt, ist Geschmackssache und eine Frage dessen, was man am Ende erreichen will. Wenn 5 Clients dieselben Daten brauchen, ist es schlauer, das bereits vor der Ausgabe zu machen, braucht jeder davon andere Informationen aus der gesamten Ausgabe, wären 5 verschiedene Dienste mit 5 passenden Ausgaben sicherlich die schlechtere Variante.

Wenn man das ohne Dienst auf der FRITZ!Box machen will, geht das auch irgendwie. Wie gesagt, das Vollschreiben des Eventlogs wäre ein Nachteil, also muß man oft genug abfragen (mindestens 1x pro Stunde, sonst Timeout) und sich die Session-ID nach einmaliger Anmeldung merken (die schlechtere Lösung in meinen Augen, weil unsicherer).

Dann kann man die Daten entweder über die TR-064-Schnittstelle oder auch über "query.lua" abfragen (das geht auch bei unmodifizierten Boxen), wie genau, hängt davon ab, was man exakt wissen will. Einige Daten lassen sich über die IGD-Schnittstelle auch ohne Anmeldung auslesen, wenn man das in der Oberfläche entsprechend einstellt.
 
Zuletzt bearbeitet:
Ich würde gerne die DSL-Daten (Geschwindigkeit, Downstream/Upstream) meiner FB auslesen, aber auf Shell-Ebene (Linux), also ohne GUI.

Hallo.

Der 7490 lassen sich die Werte per UPnP mit diesem Python-Progrämmchen entlocken:

Code:
#!/usr/bin/python3
from pysimplesoap.client import SoapClient

location = 'http://fritz.box:49000/igdupnp/control/WANCommonIFC1'
namespace = 'urn:schemas-upnp-org:service:WANCommonInterfaceConfig:1'
action = 'urn:schemas-upnp-org:service:WANCommonInterfaceConfig:1#'

debug = False  # display http/soap requests and responses

client = SoapClient(location, action, namespace, trace=debug)

response = client.GetCommonLinkProperties()
upspeed = int(response.GetCommonLinkPropertiesResponse.NewLayer1UpstreamMaxBitRate)
downspeed = int(response.GetCommonLinkPropertiesResponse.NewLayer1DownstreamMaxBitRate)

response2 = client.GetAddonInfos()
newbytesendrate = int(response2.GetAddonInfosResponse.NewByteSendRate)
newbytereceiverate = int(response2.GetAddonInfosResponse.NewByteReceiveRate)

print(upspeed, downspeed, newbytesendrate, newbytereceiverate)

Beispielausgabe:

Code:
$ ./upnp.py 
40776000 92527000 1534543 42845
(d.h. aktuell 40MBit Upstream, 92MBit Downstream, Verkehr ausgehend mit aktuell ~ 1.5MB/s und ein paar kB/s eingehend)

Voraussetzung ist, dass auf dem System python3 und pysimplesoap für Python 3 installiert sind. In der Fritzbox muss die Statusabfrage per UPnP aktiviert sein (nehme ich an).

Die verfügbaren Aktionen und Parameter des Dienstes (hier: "WANCommonInterfaceConfig") sind unter http://fritz.box:49000/igdicfgSCPD.xml abrufbar. Es gibt auch noch weitere Dienste (siehe http://fritz.box:49000/igddesc.xml).

Grüße
 
Zuletzt bearbeitet:
Klingt auf den ersten Blick zwar logisch, läßt aber schon noch Fragen offen. Meinst Du mit "Shell-Ebene" eine externe Shell oder die Telnet-Shell der FRITZ!Box?

Eine Shell auf einem Rechner, nicht der FB.


Heißt "ohne GUI", daß es auch kein "wget"-Kommando sein darf?

wget ist ein Kommando, das ohne GUI läuft. ;)


Wie oft willst Du das denn machen? Wenn es regelmäßig passieren soll und sich die Anwendung dann jedesmal neu anmeldet, ist schnell das Log vollgeschrieben und es gehen u.U. wichtige Meldungen verloren.

Ich möchte ein Programm/Skript schreiben, das regelmäßig die Daten ausließt und als Zahlwert wiedergibt.
 
Hallo.

Der 7490 lassen sich die Werte per UPnP mit diesem Python-Progrämmchen entlocken:

Die Chancen stehen gut, daß es auf der 7390 auch läuft. :)

Allerdings fehlt mir das simplesoap. Woher bekomme ich das? Als fertiges Paket für Debian/Ubuntu kann ich es leider nicht finden.
 
PHP:
<?php

$fritzbox_Adresse = 'fritz.box';
//$fritzbox_Adresse = '192.168.178.1';
$fritzbox_Username = '';
$fritzbox_Password = '0000';

$client = new SoapClient(
    null,
    array(
        'location'   => 'http://'.$fritzbox_Adresse.':49000/upnp/control/WANCommonIFC1',
        'uri'        => 'urn:schemas-upnp-org:service:WANCommonInterfaceConfig:1',
    	'noroot'     => True,
//        'login'      => $fritzbox_Username,
//        'password'   => $fritzbox_Password,
        'trace'      => True,
        'exceptions' => 0
    )
);


$action = 'GetCommonLinkProperties';

$result = $client->{$action}();

if(is_soap_fault($result))
{
 print(" Fehlercode: $result->faultcode | Fehlerstring:
         $result->faultstring");
}
else
{
 print "{$result['NewLayer1DownstreamMaxBitRate']}\n";
 print "{$result['NewLayer1UpstreamMaxBitRate']}\n";
}

var_dump ($result);

$action = 'GetTotalBytesSent';
$result = $client->{$action}();

if(is_soap_fault($result))
{
 print(" Fehlercode: $result->faultcode | Fehlerstring:
         $result->faultstring");
}
else
{
 print "{$result}\n";
}

var_dump ($result);

$action = 'GetTotalBytesReceived';
$result = $client->{$action}();

if(is_soap_fault($result))
{
 print(" Fehlercode: $result->faultcode | Fehlerstring:
         $result->faultstring");
}
else
{
 print "{$result}\n";
}

var_dump ($result);

?>

Na ja per PHP geht es auch oder.

Es könnte sein dass bei dir hier:
PHP:
'location'   => 'http://'.$fritzbox_Adresse.':49000/upnp/control/WANCommonIFC1',
die Zeile so sein muss:
PHP:
'location'   => 'http://'.$fritzbox_Adresse.':49000/igdupnp/control/WANCommonIFC1',

;)
 
wget ist ein Kommando, das ohne GUI läuft. ;)
Sicher?

Ich meinte tatsächlich, daß man mit wget ohne Verrenkungen nun mal nur auf das GUI der FRITZ!Box zugreifen kann, nicht mal auf TR-064. Und da das beim GUI mit einigem Aufwand (Anmeldung, einen Pferdefuß dieses Vorgehens habe ich schon aufgezeigt) verbunden ist, dachte ich tatsächlich, das wäre Dir bekannt und Du wolltest genau diesen Zugriff auf das GUI der FRITZ!Box vermeiden.

Wie auch immer: Wenn Dir die Angaben des IGD-Interfaces ausreichen, die man auch ohne Anmeldung auslesen kann, dann haben andere Dir ja schon praktikable Lösungen angeboten, da braucht es keine weitere ... das wollte ich in #3 im letzten Satz vermitteln.
 
Welche PHP-Pakete benötige ich dafür alles? Und wie rufe ich das manuell auf?
 
Allerdings fehlt mir das simplesoap. Woher bekomme ich das? Als fertiges Paket für Debian/Ubuntu kann ich es leider nicht finden.

pysimplesoap lässt sich mit pip3 nachinstallieren (Paket python3-pip): sudo pip3 install pysimplesoap
 
Python 2 und Python 3 sind unterschiedliche Schienen mit jeweils eigenem Paketbestand. Ich zitiere mal die pip-Manpage:

"On Debian, pip is the command to use when installing packages for Python 2, while pip3 is the command to use when installing packages for Python 3."
 
Ja, der Unterschied zwischen python 2 und 3 ist bekannt. :) Mit "finde ich nicht" wollte ich zum Ausdruck bringen, daß ich für python3 kein Paket namens python3-pip in den Repositories finden kann.
 
Ah, ich hab des Rätsels Lösung: für meine Ubuntu-Version 12.04 wurde python3-pip nie angeboten. Dann eben auf die gute altmodische Art:


sudo apt-get install python3-setuptools
sudo easy_install3 pip
sudo pip3 install pysimplesoap

So weit, so gut. Aber jetzt gibt Dein Skript Fehlermeldungen aus, mit denen ich nichts anfangen kann:

Code:
 ./down_and_up_stream.py 
Traceback (most recent call last):
  File "./down_and_up_stream.py", line 12, in <module>
    response = client.GetCommonLinkProperties()
  File "/usr/local/lib/python3.2/dist-packages/pysimplesoap/client.py", line 179, in <lambda>
    return lambda self=self, *args, **kwargs: self.call(attr, *args, **kwargs)
  File "/usr/local/lib/python3.2/dist-packages/pysimplesoap/client.py", line 268, in call
    operation = self.get_operation(method)
  File "/usr/local/lib/python3.2/dist-packages/pysimplesoap/client.py", line 325, in get_operation
    for service_name, service in self.services.items():
AttributeError: 'NoneType' object has no attribute 'items'
 
Vermutlich heißt es, das die angefragte Schnittstelle nicht zur Verfügung stand. Ist in der Fritzbox "Statusinformationen über UPnP übertragen" aktiviert? (Unter Heimnetz / Netzwerkeinstellungen)

Setze im Script die Variable debug mal auf True. Dann wird ausgegeben was die Fritzbox antwortet. Wenn die Schnittstelle nicht vorhanden (und/oder abgeschaltet) ist oder der Fritzbox die Anfrage nicht gefällt, dann kommt hier so etwas zurück:

Code:
DEBUG:pysimplesoap.client:content-length: 433
status: 500
connection: keep-alive
date: Mon, 09 Feb 2015 22:20:58 GMT
server: Router UPnP/1.0 AVM FRITZ!Box 7490 113.06.20
content-type: text/xml; charset="utf-8"
DEBUG:pysimplesoap.client:b'<?xml version="1.0"?>\n<s:Envelope xmlns:s="http://schemas.xmlsoap.org/soap/envelope/" s:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/">\n<s:Body>\n<s:Fault>\n<faultcode>s:Client</faultcode>\n<faultstring>UPnPError</faultstring>\n<detail>\n<UPnPError xmlns="urn:schemas-upnp-org:control-1-0">\n<errorCode>401</errorCode>\n<errorDescription>Invalid Action</errorDescription>\n</UPnPError>\n</detail>\n</s:Fault>\n</s:Body>\n</s:Envelope>'

(Stichwörter "UPnPError" und "Invalid Action")

PS: Zum fehlenden Paket - okay, hatte die Rechnung ohne den "Long Term Support" gemacht, die 12.04er wird ja noch zwei Jahre unterstützt. (Hier Stand ursprünglich die Empfehlung doch mal ein Upgrade zu machen.)
 
Zuletzt bearbeitet:
Ah, UPnP... das war's. Das hatte ich wohl deaktiviert, weil ich letztens noch was über Sicherheitsprobleme damit gelesen habe.

Aber jetzt läuft's. Danke für Deine Hilfe! :)

Ich musste nur etwas mit den Zahlen jonglieren, die ich da zurückbekomme: die Maximalwerte sind nämlich kbit/s, die momentanen Werte aber kbyte/s. Da ist etwas inkonsequent von der FB. Aber nachdem ich das kapiert hatte, wunderte ich mich auch nicht mehr über die seltsame Ergebnisse.
 
Ah, UPnP... das war's. Das hatte ich wohl deaktiviert, weil ich letztens noch was über Sicherheitsprobleme damit gelesen habe.
Das, was ich in #3 zu den UPnP-Einstellungen geschrieben habe, bezog sich aber nur auf "Informationen bereitstellen", keinesfalls auf "Sicherheitseinstellungen ändern". Dahinter verbirgt sich dann tatsächlich die Möglichkeit für interne Geräte, ihre eigenen eingehenden Internet-Verbindungen (aka Portforwardings) zu etablieren und das kann eine Sicherheitslücke sein.

Andererseits ist die Schadsoftware, die sich auf diesem Weg von außen erreichbar machte, meines Wissens inzwischen "in the wild" fast ausgestorben, da es heutzutage einfach leichter ist (bei always-on-Verbindungen), wenn man gleich eine unauffällige ausgehende UDP-Verbindung (oder auch eine TCP-basierte IRC-Verbindung zu einem C&C-Server) aufbauen und dauerhaft aufrecht erhalten kann. Da braucht es keine eingehenden Verbindungen mehr, höchstens noch, um weitere Dienste im Netzwerk angreifbar zu machen (aber eine ordentliche Implementierung erlaubt auch nur Freigaben auf den Host, von dem der TR-064-Request ausgeht).
 
Holen Sie sich 3CX - völlig kostenlos!
Verbinden Sie Ihr Team und Ihre Kunden Telefonie Livechat Videokonferenzen

Gehostet oder selbst-verwaltet. Für bis zu 10 Nutzer dauerhaft kostenlos. Keine Kreditkartendetails erforderlich. Ohne Risiko testen.

3CX
Für diese E-Mail-Adresse besteht bereits ein 3CX-Konto. Sie werden zum Kundenportal weitergeleitet, wo Sie sich anmelden oder Ihr Passwort zurücksetzen können, falls Sie dieses vergessen haben.