Öffentliche IP-Adresse: Unterschied zwischen den Versionen
(Öffentliche IPv4 und IPv6 ermitteln, Wie in Snippet https://forum.fhem.de/index.php?topic=141872.0 besprochen) |
|||
(6 dazwischenliegende Versionen desselben Benutzers werden nicht angezeigt) | |||
Zeile 6: | Zeile 6: | ||
defmod PublicIP HTTPMOD https://ipwho.de/json/ 600 | defmod PublicIP HTTPMOD https://ipwho.de/json/ 600 | ||
attr PublicIP extractAllJSON 1 | attr PublicIP extractAllJSON 1 | ||
</syntaxhighlight>Ein Abfrageintervall von 300 bis 600 Sekunden (5 bis 10 Minuten) wird empfohlen – häufigere Abfragen | </syntaxhighlight>Ein Abfrageintervall von 300 bis 600 Sekunden (5 bis 10 Minuten) wird empfohlen – häufigere Abfragen belasten die externen Dienste unnötig. | ||
=== Weitere Dienste === | === Weitere Dienste === | ||
Zeile 41: | Zeile 41: | ||
== Fritzbox nutzen == | == Fritzbox nutzen == | ||
=== Reguläres Device nutzen === | |||
Wird eine Fritzbox als Router in das Internet verwendet, kann man die öffentliche IP sehr einfach vom Router abfragen. Der Vorteil dieser Lösung besteht darin, dass kein externer Dienst abgefragt werden muss:<syntaxhighlight lang="perl"> | Wird eine Fritzbox als Router in das Internet verwendet, kann man die öffentliche IP sehr einfach vom Router abfragen. Der Vorteil dieser Lösung besteht darin, dass kein externer Dienst abgefragt werden muss:<syntaxhighlight lang="perl"> | ||
defmod Fritzbox FRITZBOX 192.168.123.123 | defmod Fritzbox FRITZBOX 192.168.123.123 | ||
Zeile 52: | Zeile 55: | ||
<code>box_ipv6_Extern</code> | <code>box_ipv6_Extern</code> | ||
<code>box_ipv6_Prefix</code> | <code>box_ipv6_Prefix</code> | ||
=== Spezielle Abfrage der Fritzbox für Sonderfälle === | |||
In einigen Fällen stellt das Fritzbox Device nicht die passenden Readings bereit (zum Beispiel bei einer FB 6660 cable). Da in solchen Fällen CGNAT/DS-Lite eine IPv4 Abfrage vom Internet aus auf FHEM verhindert ist nur die öffentlich erreichbare IPv6 Adresse von Interesse (=GUA). | |||
Es steht zur Zeit nur ein BASH Skript bereit ({{Link2Forum|Topic=141872|Message=1343341|LinkText=Quelle}}):<syntaxhighlight lang="bash"> | |||
#!/bin/bash | |||
FRITZ_USER="<USER>" | |||
FRITZ_PASS="<PASS>" | |||
FRITZ_HOSTNAME="<HOST>" | |||
FRITZ_IPV6_GUA=$(curl -s --max-time 10 \ | |||
--anyauth --user "${FRITZ_USER}:${FRITZ_PASS}" \ | |||
http://${FRITZ_HOSTNAME}:49000/upnp/control/wanipconnection1 \ | |||
-H "Content-Type: text/xml; charset="utf-8"" \ | |||
-H "SoapAction:urn:dslforum-org:service:WANIPConnection:1#GetExternalIPAddress" \ | |||
-d "<?xml version='1.0' encoding='utf-8'?> <s:Envelope s:encodingStyle='http://schemas.xmlsoap.org/soap/encoding/' xmlns:s='http://schemas.xmlsoap.org/soap/envelope/'> <s:Body> <u:GetExternalIPAddress xmlns:u='urn:dslforum-org:service:WANIPConnection:1'></u:GetExternalIPAddress> </s:Body> </s:Envelope>" | egrep -o "(::)?[0-9a-fA-F]{1,4}(::?[0-9a-fA-F]{1,4}){1,7}(::)?") | |||
if [ -z "$FRITZ_IPV6_GUA" ]; then | |||
echo "Error! Can't get IPv6 GUA from FRITZ!Box" | |||
exit 0 | |||
else | |||
echo "FRITZ!Box IPv6 GUA is: $FRITZ_IPV6_GUA" | |||
fi | |||
</syntaxhighlight> | |||
== STUN Server nutzen == | == STUN Server nutzen == | ||
STUN Server | Alternativ kann ein STUN-Server zur Ermittlung der externen IP genutzt werden. Beispiel-Snippet (Perl):<syntaxhighlight lang="perl"> | ||
sub myip { | |||
use STUN::Client; | |||
my $stun_client = STUN::Client->new; | |||
$stun_client->stun_server('stun.ekiga.net'); | |||
my (undef, $result) = $stun_client->get; | |||
return $result->{'attributes'}->{'0001'}->{'address'}; | |||
} | |||
</syntaxhighlight>Hinweis: Das Perl-Modul <code>STUN::Client</code> ist ggf. nicht in jeder Distribution verfügbar und muss über CPAN installiert werden. | |||
Weitere Details und Diskussion: https://forum.fhem.de/index.php?topic=141872.msg1343225#msg1343225 | |||
== IPs des FHEM Servers ermitteln (ohne Link-Local, Docker, etc) == | |||
Sofern der FHEM Server bereits eine öffentliche IP hat, kann man diese von den lokalen Netzwerkinterfaces abfragen. Mit wenigen Abhängigkeiten geht dies unter typischen Linux-Distributionen wie Debian Buster, Bullseye, Bookworm oder aktueller mit:<syntaxhighlight lang="perl"> | |||
define LocalIPs at +*00:01:00 { | |||
my $hash = $defs{$SELF}; | |||
my (@ipv4, @ipv6); | |||
#Abfragen der IP Adressen mittels CLI: | |||
my $json = qx(ip -j addr show scope global); | |||
my $data = decode_json($json); | |||
for my $iface (@$data) { | |||
for my $addr (@{$iface->{addr_info} || []}) { | |||
next unless $addr->{local}; | |||
if ($addr->{family} eq 'inet') { | |||
push @ipv4, $addr->{local}; | |||
} elsif ($addr->{family} eq 'inet6') { | |||
push @ipv6, $addr->{local}; | |||
} | |||
} | |||
} | |||
readingsBeginUpdate($hash); | |||
readingsBulkUpdate($hash, "allIPv4", join(',', @ipv4)); | |||
readingsBulkUpdate($hash, "allIPv6", join(',', @ipv6)); | |||
readingsEndUpdate($hash, 1); | |||
} | |||
attr LocalIPs alignTime 00:00:00 | |||
attr LocalIPs event-on-change-reading .* | |||
attr LocalIPs stateFormat IPv4: allIPv4<br />IPv6: allIPv6 | |||
</syntaxhighlight> |
Aktuelle Version vom 17. Juni 2025, 07:27 Uhr
Einleitung
In FHEM kann die aktuell verwendete öffentliche IP-Adresse (IPv4/IPv6) auf verschiedene Arten ermittelt werden. Eine Methode ist der Abruf über externe Webdienste. Es kann auch auf lokale Router-Informationen (z. B. Fritzbox) oder systemnahe Module (z.B. STUN) zurückgegriffen werden.
HTTPMOD-Definition zum ermitteln der öffentlichen IPv4 und IPv6 via HTTPS-Webdienst
Die öffentliche IP kann man mit Webdiensten ermitteln, die einem die IPv4 und/oder IPv6 anzeigen mit der die Seite abgerufen wird:
defmod PublicIP HTTPMOD https://ipwho.de/json/ 600
attr PublicIP extractAllJSON 1
Ein Abfrageintervall von 300 bis 600 Sekunden (5 bis 10 Minuten) wird empfohlen – häufigere Abfragen belasten die externen Dienste unnötig.
Weitere Dienste
Anbieter | Adresse | Zuletzt erfolgreich getestet im Jahr |
---|---|---|
ipify.org
|
https://api64.ipify.org/?format=json | 2025 |
ipwho.de
|
https://ipwho.de/json/ | 2025 |
ipinfo.io
|
https://ipinfo.io/json/ | 2025 |
myip.com
|
https://api.myip.com/ | 2025 |
ident.me
|
https://a.ident.me/json | 2025 |
Fritzbox nutzen
Reguläres Device nutzen
Wird eine Fritzbox als Router in das Internet verwendet, kann man die öffentliche IP sehr einfach vom Router abfragen. Der Vorteil dieser Lösung besteht darin, dass kein externer Dienst abgefragt werden muss:
defmod Fritzbox FRITZBOX 192.168.123.123
attr Fritzbox INTERVAL 300
attr Fritzbox boxUser <dein Fritzbox User>
attr Fritzbox nonblockingTimeOut 100
Hierbei sind die Attribute wie die IP Adresse und Nutzername auf der Fritzbox anzupassen.
Die IPv4 und IPv6 der Fritzbox, als auch das IPv6 Prefix des lokalen Netzes sind als Readings direkt abfragbar:
box_ipv4_Extern
box_ipv6_Extern
box_ipv6_Prefix
Spezielle Abfrage der Fritzbox für Sonderfälle
In einigen Fällen stellt das Fritzbox Device nicht die passenden Readings bereit (zum Beispiel bei einer FB 6660 cable). Da in solchen Fällen CGNAT/DS-Lite eine IPv4 Abfrage vom Internet aus auf FHEM verhindert ist nur die öffentlich erreichbare IPv6 Adresse von Interesse (=GUA).
Es steht zur Zeit nur ein BASH Skript bereit (Quelle):
#!/bin/bash
FRITZ_USER="<USER>"
FRITZ_PASS="<PASS>"
FRITZ_HOSTNAME="<HOST>"
FRITZ_IPV6_GUA=$(curl -s --max-time 10 \
--anyauth --user "${FRITZ_USER}:${FRITZ_PASS}" \
http://${FRITZ_HOSTNAME}:49000/upnp/control/wanipconnection1 \
-H "Content-Type: text/xml; charset="utf-8"" \
-H "SoapAction:urn:dslforum-org:service:WANIPConnection:1#GetExternalIPAddress" \
-d "<?xml version='1.0' encoding='utf-8'?> <s:Envelope s:encodingStyle='http://schemas.xmlsoap.org/soap/encoding/' xmlns:s='http://schemas.xmlsoap.org/soap/envelope/'> <s:Body> <u:GetExternalIPAddress xmlns:u='urn:dslforum-org:service:WANIPConnection:1'></u:GetExternalIPAddress> </s:Body> </s:Envelope>" | egrep -o "(::)?[0-9a-fA-F]{1,4}(::?[0-9a-fA-F]{1,4}){1,7}(::)?")
if [ -z "$FRITZ_IPV6_GUA" ]; then
echo "Error! Can't get IPv6 GUA from FRITZ!Box"
exit 0
else
echo "FRITZ!Box IPv6 GUA is: $FRITZ_IPV6_GUA"
fi
STUN Server nutzen
Alternativ kann ein STUN-Server zur Ermittlung der externen IP genutzt werden. Beispiel-Snippet (Perl):
sub myip {
use STUN::Client;
my $stun_client = STUN::Client->new;
$stun_client->stun_server('stun.ekiga.net');
my (undef, $result) = $stun_client->get;
return $result->{'attributes'}->{'0001'}->{'address'};
}
Hinweis: Das Perl-Modul STUN::Client
ist ggf. nicht in jeder Distribution verfügbar und muss über CPAN installiert werden.
Weitere Details und Diskussion: https://forum.fhem.de/index.php?topic=141872.msg1343225#msg1343225
IPs des FHEM Servers ermitteln (ohne Link-Local, Docker, etc)
Sofern der FHEM Server bereits eine öffentliche IP hat, kann man diese von den lokalen Netzwerkinterfaces abfragen. Mit wenigen Abhängigkeiten geht dies unter typischen Linux-Distributionen wie Debian Buster, Bullseye, Bookworm oder aktueller mit:
define LocalIPs at +*00:01:00 {
my $hash = $defs{$SELF};
my (@ipv4, @ipv6);
#Abfragen der IP Adressen mittels CLI:
my $json = qx(ip -j addr show scope global);
my $data = decode_json($json);
for my $iface (@$data) {
for my $addr (@{$iface->{addr_info} || []}) {
next unless $addr->{local};
if ($addr->{family} eq 'inet') {
push @ipv4, $addr->{local};
} elsif ($addr->{family} eq 'inet6') {
push @ipv6, $addr->{local};
}
}
}
readingsBeginUpdate($hash);
readingsBulkUpdate($hash, "allIPv4", join(',', @ipv4));
readingsBulkUpdate($hash, "allIPv6", join(',', @ipv6));
readingsEndUpdate($hash, 1);
}
attr LocalIPs alignTime 00:00:00
attr LocalIPs event-on-change-reading .*
attr LocalIPs stateFormat IPv4: allIPv4<br />IPv6: allIPv6