Externe IPv6 Addresse der Fritzbox

Begonnen von Sailor, 21 Oktober 2022, 20:48:06

Vorheriges Thema - Nächstes Thema

Sailor

Ein herzerfrischendes Moin vom achtern Diek vorweg!

Hat Jemand von Euch eine Möglichkeit gefunden, aus fhem heraus die externe IPv6 Adresse der FritzBox auszulesen, unter der die FritzBox von außen zu erreichen ist?

Also die Adresse, die in der FritzBox unter "Internet" -> "Freigaben" -> "Fritz!Box" - Dienste" -> "Internet-Adresse Ihrer FRITZ!Box" ganz unten zu finden ist.

Mit dem Modul "FRITZBOX" bekomme ich mit "box_ipExtern" nur die externe IPv4 - Adresse die aufgrund meines DualStack seitens Deutsche Glasfaser nicht zu gebrauchen ist.

Danke für die Hilfe!

Gruß
    Sailor
******************************
Man wird immer besser...

justme1968

keine fertige lösung, aber eine möglichkeit an die daten zu kommen die dir vielleicht auch weiter hilft...

da ich keine fritzbox als router habe ;) mache ich mache das nicht über die fritzbox sondern mit (einem angepassten) httpmod und einem der externen 'was ist meine ip' dienste. statt den beiden die ich genommen habe geht das mit der entsprechenden änderung an der jeweiligen regex auch mit jedem anderen.

wenn du in deiner fhem installation useInet6 setzen kannst und dir die ipv6 reicht sollte die ipv6 variante unten direkt gehen.

wenn du useInet6 nicht setzen kannst/willst und/oder du ipv4 und ipv6 brauchst sind vorher noch zwei dinge nötig:
- eine HttpUtils version neuer als 1.5.2022 (siehe hier: https://forum.fhem.de/index.php/topic,127464.0.html)
- du musst in HTTPMOD dafür sorgen das beim HttpUtils aufruf try6 je nach device passend gesetzt ist.
   ich wollte eigentlich einen patch für HTTPMOD fertig machen, bin aber noch nicht dazu gekommen.

das timestamp-on-change-reading ist gesetzt um im reading/log den zeitpunkt der änderung zu haben. damit zeige ich im speedtest plot an ob sich die ip (wegen fallback auf den zweiten anschluss) geändert hat.

für ipv6 z.b.:defmod myIPv6 HTTPMOD http://ipv6.icanhazip.com/ 60
attr myIPv6 enableControlSet 1
attr myIPv6 event-on-change-reading .*
attr myIPv6 reading01Name IP
attr myIPv6 reading01Regex (\d.*\d)\n
attr myIPv6 room 8.3 Netzwerk
attr myIPv6 stateFormat IP
attr myIPv6 timeout 5
attr myIPv6 timestamp-on-change-reading .*
attr myIPv6 webCmd reread


für ipv4 z.b.:defmod myIP HTTPMOD http://checkip.dyndns.com/ 60
attr myIP comment dig +short txt ch whoami.cloudflare @1.0.0.1
attr myIP event-on-change-reading .*
attr myIP reading01Name IP
attr myIP reading01Regex ([0-9]+\.[0-9]+\.[0-9]+\.[0-9]+)
attr myIP room 8.3 Netzwerk
attr myIP stateFormat IP
attr myIP timeout 5
attr myIP timestamp-on-change-reading .*
attr myIP webCmd reread
hue, tradfri, alexa-fhem, homebridge-fhem, LightScene, readingsGroup, ...

https://github.com/sponsors/justme-1968

Otto123

Hallo in den Norden,

so was ganz kurzes - völlig unabhängig vom Router usw.

{qx(wget -q -O - https://v6.ident.me/)}

Geht auch mit v4 ;)

Gruß Otto
Viele Grüße aus Leipzig  ⇉  nächster Stammtisch an der Lindennaundorfer Mühle
RaspberryPi B B+ B2 B3 B3+ ZeroW,HMLAN,HMUART,Homematic,Fritz!Box 7590,WRT3200ACS-OpenWrt,Sonos,VU+,Arduino nano,ESP8266,MQTT,Zigbee,deconz

justme1968

das hat aber den nachteil das fhem blockieren kann wenn das wget z.b. wegen einem internet problem hängen bleibt.

wenn man den weg über das system geht ist es vermutlich besser in fhem "..." zu verwenden und den externen aufruf gleich in ein script zu packen das nach beenden den wert an fhem pushed.

je nach anwendung kann es auch einen unterschied machen ob die system routinen und eine bestimmte http implementierung (über das wget) oder die fhem internen (per HTTPMOD) zur namensauflösung und verbindungsaufbau verwendet werden. da ein fallback (oder das fehlen des selben) dazu führen das das ganze im fehlerfall unterschiedlich reagiert.
hue, tradfri, alexa-fhem, homebridge-fhem, LightScene, readingsGroup, ...

https://github.com/sponsors/justme-1968

Otto123

Hast ja Recht, leider bin ich zu doof das in httpmod zu gießen. Die Seite liefert ja einfach nur Text zurück.
Von daher ist das von allen Seiten, die ich kenne, die mit dem geringsten Overhead.
Viele Grüße aus Leipzig  ⇉  nächster Stammtisch an der Lindennaundorfer Mühle
RaspberryPi B B+ B2 B3 B3+ ZeroW,HMLAN,HMUART,Homematic,Fritz!Box 7590,WRT3200ACS-OpenWrt,Sonos,VU+,Arduino nano,ESP8266,MQTT,Zigbee,deconz

justme1968

die beiden seiten die ich oben im beispiel verwendet habe liefern auch nur die ip ohne alles und von der ipv6 adresse gibt es ebenfalls eine ipv4  version. deine adressen sollten also direkt auch mit der httpmod variante funktionieren. die oben beschriebene handarbeit bleibt dabei genauso nötig wenn man ipv4 und ipv6 httpmod abfragen will.
hue, tradfri, alexa-fhem, homebridge-fhem, LightScene, readingsGroup, ...

https://github.com/sponsors/justme-1968

Sailor

#6
Hallo justme

Zitat von: justme1968 am 21 Oktober 2022, 21:49:55
keine fertige lösung, aber eine möglichkeit an die daten zu kommen die dir vielleicht auch weiter hilft...
da ich keine fritzbox als router habe ;) mache ich mache das nicht über die fritzbox sondern mit (einem angepassten) httpmod und einem der externen 'was ist meine ip' dienste. statt den beiden die ich genommen habe geht das mit der entsprechenden änderung an der jeweiligen regex auch mit jedem anderen.
wenn du in deiner fhem installation useInet6 setzen kannst und dir die ipv6 reicht sollte die ipv6 variante unten direkt gehen.

Mit Deiner Version bekomme ich nur die IPv6-Adresse des hosts (fhem-Server) angezeigt.
Nicht jedoch die IPv6 = Adresse unter der die Fritz!Box im Internet zu erreichen ist.

Die obige Variante bekommst du übrigens mit Bordmitteln ohne ins Internet gehen zu muessen:

use Net::DNS;
use NetAddr::IP;

$Hostname = "FhemServerName"
$name = "SubGetHostIPv6Address";

### Open a new resolver object
my $res   = Net::DNS::Resolver->new;
my $query;

### Start query for IPv6 address
eval {
$query = $res->query($Hostname, "AAAA")
};

### Log Entry for debugging purposes
Log3 $name, 5, " :  IPv6 ErrorString                                 : " . $res->errorstring;

### If error message appered
if ($res->errorstring ne "NOERROR") {
Log3 $name, 5, " :  IPv6 ErrorString                                 : " . $res->errorstring;
}

### If no error message appeared and therefore host exists
else {
eval {
foreach my $rr (grep { $_->type eq 'AAAA' } $query->answer) {
Log3 $name, 5, " :  v6                                               : " . $rr->address;
}
}
}

my $Ipv6_SubDomainFull;

eval{
my $ip = NetAddr::IP->new($rr->address);
$Ipv6_SubDomainFull = $ip->full;
};

### Log Results
Log3 $name, 1, $name. " :  Full IPv6                                        : " . $Ipv6_SubDomainFull;

return($Ipv6_SubDomainFull);


Das funktioniert aber nur mit den internen Ip-Adressen.
Wenn man das mit der "fritz.box" als Hostnamen machen würde, kommt dabei nur die interne IPv6 des Routers zum Vorschein.

Gruß
     Sailor

******************************
Man wird immer besser...

Otto123

#7
Hi Sailor,

womit Du Recht hast  :-[
IPv6 ist ein echt hartes Brot - ich kaue wieder mal seit Tagen um das ein bisschen zu verstehen.

Eine Variante die funktioniert ist: dyndns (bzw. myfritz) einrichten und per host dyndns bzw myfritz Adresse abfragen. Da bekommt man die IPv6 Adresse die bei mir auf der Online-Monitor Seite zu lesen ist.

Ich suche gerade ob mit tr064 was geht.
Laut Beschreibung https://avm.de/fileadmin/user_upload/Global/Service/Schnittstellen/IGD1.pdf gibt es
WANIPConnection:1 wanipconnection1 X_AVM_DE_GetExternalIPv6Address

Ich bekommen das aber mit dem Fritzbox Modul nach mir bekanntem Schema nicht ausgelesen. Es gibt ein paar Scripte im Internet mit php und shell. Die funktionieren bei mir auch nicht.

Edit: mit folgendem Argument im FB Modul get tr064Command geht es bei mir. Aber es sieht aus, als liest er hier Infos von der myfritz.net Konfiguration aus.
X_AVM-DE_AppSetup:1 x_appsetup GetAppRemoteInfo

Gruß Otto
Viele Grüße aus Leipzig  ⇉  nächster Stammtisch an der Lindennaundorfer Mühle
RaspberryPi B B+ B2 B3 B3+ ZeroW,HMLAN,HMUART,Homematic,Fritz!Box 7590,WRT3200ACS-OpenWrt,Sonos,VU+,Arduino nano,ESP8266,MQTT,Zigbee,deconz

justme1968

@Sailor: ja. du hast recht und beim drüber nachdenken ist mir gerade auch nicht klar warum das bei meinen tests so funktioniert hat.

dein bordmittel beispiel das die systemroutinen verwendet hat wieder genau das problem des blockierens. deshalb gibt es in fhem die HttpUtils_gethostbyname variante die das komplett selber macht und nicht blockiert.

ob eine lokale dns abfrage aber überhaupt deinen lokalen host namen auflösen kann hängt von deiner netzwerk konfiguration ab und funktioniert durch den fallback auf den jeweiligen nächsten resolver auch nicht unbedingt ohne zugriff aufs internet.

und wie du bemerkt hast liefert sie nur die interne ip.

übrigens ist mir noch ein problem mit dem weg über die externen webseiten aufgefallen: normalerweise hat ein host mehrere ipv6 adressen. unter anderem eine durch die ipv6 privacy extensions. die zum aufbau von verbindungen nach aussen verwendet wird und diese wechselt regelmässig.


aktuell denke ich das der weg über eine der dyndns varianten der zuverlässigste sein müsste. in verbindung mit HttpUtils_gethostbyname damit es im problem fall nicht blockiert.
hue, tradfri, alexa-fhem, homebridge-fhem, LightScene, readingsGroup, ...

https://github.com/sponsors/justme-1968

JoWiemann

Hallo,

ich habe jetzt mal das Auslesen der IPv6 in meinen Fork integriert. Das ganze läuft leider noch über qx, gibt aber die selbe Adresse aus, wie auf der FritzBox Web Seite.

Grüße Jörg

Jörg Wiemann

Slave: RPi B+ mit 512 MB, COC (868 MHz), CUL V3 (433.92MHz SlowRF); FHEMduino, Aktuelles FHEM

Master: CubieTruck; Debian; Aktuelles FHEM

Sailor

#10
Hi justme

Zitat von: justme1968 am 24 Oktober 2022, 13:39:01
aktuell denke ich das der weg über eine der dyndns varianten der zuverlässigste sein müsste. in verbindung mit HttpUtils_gethostbyname damit es im problem fall nicht blockiert.

Mangels WIKI - Eintrag für "HttpUtils_gethostbyname" Ich habe versucht die Subroutine wie folgt aufzurufen

##START###### Define Subfunction for gethostbyname REQUEST ####################################################START####
### https://wiki.fhem.de/wiki/HttpUtils#HttpUtils_NonblockingGet
sub IONOSAPI_GetHostByName($) {
my ($hash) = @_;

### Obtain values from hash
my $name = $hash->{NAME};

### Call Get Host by name
HttpUtils_gethostbyname($hash, "fhemHomeServer", 1, "IONOSAPI_GetHostByName_Parse" );

return;
}

sub IONOSAPI_GetHostByName_Parse($) {
my ($param, $err, $data) = @_;
    my $hash = $param->{hash};

### Obtain values from hash
    my $name = $hash->{NAME};

### Log Entry for debugging purposes
### Log Entry for debugging purposes
Log3 $name, 1, $name. " : IONOSAPI_GetHostByName_Parse _____________________________________________________";
Log3 $name, 1, $name. " : IONOSAPI_GetHostByName_Parse - err                 : " . $err           if (defined($err  ));
Log3 $name, 1, $name. " : IONOSAPI_GetHostByName_Parse - length data         : " . length($data)  if (defined($data ));
Log3 $name, 1, $name. " : IONOSAPI_GetHostByName_Parse - data                : " . $data          if (defined($data ));
Log3 $name, 1, $name. " : IONOSAPI_GetHostByName_Parse - Dumper data         : " . Dumper($data)  if (defined($data ));
# Log3 $name, 5, $name. " : IONOSAPI_GetHostByName_Parse - param               : " . join("\n", @{[%{$param}]}) if (defined($param));

return;
}
####END####### Define Subfunction for gethostbyname REQUEST ####################################################END#####


Dies sorgt aber mit folgernder Fehlermeldung für einen fhem-Absturz...
Can't use string ("IONOSAPI_GetHostByName_Parse") as a subroutine ref while "strict refs" in use at FHEM/HttpUtils.pm line 242.

Kannst du mir einen Hinweis geben, wie ich die folgende Zeile korrigieren muss?
HttpUtils_gethostbyname($hash, "fhemHomeServer", 1, "IONOSAPI_GetHostByName_Parse" );

Danke!

Gruss
    Sailor
******************************
Man wird immer besser...

rudolfkoenig

Ueber die Definition von HttpUtils_gethostbyname in HttpUtils.pm gibt es einen Beispiel-Aufruf:
Zitat# { HttpUtils_gethostbyname({timeout=>4}, "fhem.de", 1,
#   sub(){my($h,$e,$a)=@_;; Log 1, $e ? "ERR:$e": ("IP:".ip2str($a)) }) }

Dein Aufruf muesste so ausschauen:
HttpUtils_gethostbyname($hash, "fhemHomeServer", 1, \&IONOSAPI_GetHostByName_Parse );

Die Ausgabe von $data duerfte aber ohne Konvertierung nicht lesbar sein.

Sailor

#12
Hallo Rudi

Zitat von: rudolfkoenig am 24 Oktober 2022, 16:54:16
Ueber die Definition von HttpUtils_gethostbyname in HttpUtils.pm gibt es einen Beispiel-Aufruf:
Dein Aufruf muesste so ausschauen:
HttpUtils_gethostbyname($hash, "fhemHomeServer", 1, \&IONOSAPI_GetHostByName_Parse );

Danke klappt ohne Fehlermeldung oder Absturz!

Zitat von: rudolfkoenig am 24 Oktober 2022, 16:54:16
Die Ausgabe von $data duerfte aber ohne Konvertierung nicht lesbar sein.

Habe ich gemerkt. Als was ist das denn kodiert bzw. wie lautet der Decoder?

2022.10.24 17:15:11.014 1:  : IONOSAPI_GetHostByName_Parse _____________________________________________________
2022.10.24 17:15:11.014 1:  : IONOSAPI_GetHostByName_Parse - length data         : 4
2022.10.24 17:15:11.014 1:  : IONOSAPI_GetHostByName_Parse - data                :
2022.10.24 17:15:11.015 1:  : IONOSAPI_GetHostByName_Parse - Dumper data         : $VAR1 = '';


bzw. von einem anderen Host

2022.10.24 17:21:25.822 1:  : IONOSAPI_GetHostByName_Parse _____________________________________________________
2022.10.24 17:21:25.823 1:  : IONOSAPI_GetHostByName_Parse - length data         : 16
2022.10.24 17:21:25.823 1:  : IONOSAPI_GetHostByName_Parse - data                : *` E�����X�
2022.10.24 17:21:25.823 1:  : IONOSAPI_GetHostByName_Parse - Dumper data         : $VAR1 = '*` E�����X�';


bzw. mit einem absichtlich falschen Hostnamen

2022.10.24 17:26:19.689 1:  : IONOSAPI_GetHostByName_Parse _____________________________________________________
2022.10.24 17:26:19.690 1:  : IONOSAPI_GetHostByName_Parse - err                 : gethostbyname Test failed


Gruß
    Sailor
******************************
Man wird immer besser...

rudolfkoenig

ZitatHabe ich gemerkt. Als was ist das denn kodiert ...
Als Bytefolge, damit man bei den nachfolgenden Funktionen (sockaddr_in, etc) einfacher hat.

Zitat...bzw. wie lautet der Decoder?
In HttpUtils.pm gibt es eine ip2str Funktion, steht auch im zitierten Beispiel-Aufruf drin :)

Etwas Off-Topic: mit { HttpUtils_dumpDnsCache() } kann man den DNS-Cache-Inhalt ausgeben.

Sailor

Hallo Rudi

Zitat von: rudolfkoenig am 25 Oktober 2022, 12:15:44
Als Bytefolge, damit man bei den nachfolgenden Funktionen (sockaddr_in, etc) einfacher hat.
In HttpUtils.pm gibt es eine ip2str Funktion, steht auch im zitierten Beispiel-Aufruf drin :)

Ach Mensch, wer lesen kann ist klar im Vorteil.
Danke!

Für einen Fremdhost hat das schon mal geklappt!
IONOSAPI_GetHostByName_Parse - data                : $VAR1 = '[2a00:6020:4588:1e00:ed00:a7c0:c758:e91]';

Bei dem eigenen Rechner (lokaler Host) spuckt die Funktion leider
IONOSAPI_GetHostByName_Parse - data                : $VAR1 = '127.0.1.1';
aus.

Trotz des Aufrufs mit "1" bei "IP6"
HttpUtils_gethostbyname($hash, "FhemHomeServer", 1, \&IONOSAPI_GetHostByName_Parse );


Gibt es eine Möglichkeit beim lokalen Hostnamen trotzdem die Ausgabe der IPv6-Adresse zu erzwingen?

Gruß
    Matthias
******************************
Man wird immer besser...