Update IPv6-Präfix bei spDYN

Wenn ich mich über das Mobilfunknetz per SSH auf meinen Heimrechner verbinden möchte, wird IPv6 verwendet. Da sich mein Präfix regelmäßig ändert, erstelle ich mir einen dynamischen DNS-Service.
IPv6
Python
Heimserver
Jean Pütz
Autor:in

Joe Slam

Veröffentlichungsdatum

3. Oktober 2023

Mein Heimserver ist seit Jahren über eine dynamische-DNS-Adresse von spDYN per SSH erreichbar. Da ich einer der letzten glücklichen kleinen Lichter bin, die noch eine echte IP4-Adresse erhalten (und keine genattete), konnte ich mich so immer von überall auf meine Kiste einloggen.

Letztens hatte ich folgendes Problem: aus dem Mobilnetz konnte ich keine Verbindung zum Server herstellen, stattdessen bekam ich die Fehlermeldung 1005 EACCESS permission denied.

Nach etwas hin und her habe ich die Ursache gefunden:

Lösung:

Das geht bei oben genanntem Service recht einfach. Das Update erfolgt über einen HTML-Aufruf nach dem Muster

https://update.spdyn.de/nic/update?hostname=DEIN-NAME.spdns.org&myip=DIE-NEUE-IPv6

IPv6 automatisch finden

Um herauszufinden, welche IPv6 der Heimserver aktuell besitzt, verwende ich folgenden Befehl:

wget -qO- http://ipecho.net/plain

2a02:908:1d48:abcd:9a48:c080:6fcd:4f8c

Ich benötige nur die ersten 4 Blöcke (die ersten 3 gehören zu Vodafon, der 4. ist mein zugewiesenes Präfix (in diesem Beispiel abcd)). Alles dahinter “gehört mir” bzw. meinen Clients. Ich habe alle Geräte so eingerichtet, dass sie sich - neben den temporären Adressen - immer auch eine “feste” IPv6 anhand des Präfixes generieren. Mein Heimserver hat beispielsweise immer eine IPv6 mit der Endung ::4, und so generiert er sich - neben den temporären Adressen - aus dem vorgegebenen Präfix automatisch die dauerhafte IPv6 2a02:908:1d48:abcd::4.

Ich müsste also regelmäßig ein kleines Script laufen lassen, welches

  • Eine aktuelle IPv6 mittels wget -qO- http://ipecho.net/plain ermittelt
  • davon die ersten 4 Blöcke ausschneidet
  • und ::4 hintendranhängt
  • diese “neu” erzeugte IPv6 an spDYN meldet.

Das Script

Das Script nenne ich mal spdyn-ipv6.py und schreibe es in Python.

touch spdyn-ipv6.py
chmod +x spdyn-ipv6.py
nano spdyn-ipv6.py

Mit folgendem Inhalt:

#!/usr/bin/env python3
import subprocess
from datetime import datetime
import requests

# Wohin speichern?
# (um zu schauen, ob das Präfix neu ist)
txtfile = "/home/produnis/Nextcloud/Dokumente/ipv6-server.txt"

# Wie lautet die spDYN-Url?
spdynurl = "DEIN_SERVER.spdns.org"
spdynuser = "DEIN-USERNAME"
spdynpwd = "SUPER SECRET"


### ab hier muss nichts mehr geändert werden
# Timestamp
dt = str(datetime.now())

# Hole aktuelles ipv6 Präfix
proc = subprocess.Popen(["wget -qO- http://ipecho.net/plain"], stdout=subprocess.PIPE, shell=True)
(out, err) = proc.communicate()

# wandle in String um
wert = str(out)

# Schneide die ersten 4 Blöcke ab und hänge ::4 an
ipv6wert = ''.join(wert[2:20]) + '::4'

print("Dies ist mein aktueller Stand:", "\nIP6:", ipv6wert, "\nTimestamp:", dt)
fuer_txt_datei = "%s\n%s" % (ipv6wert, dt)


# ist es neu?
with open(txtfile) as f:
    oldipv6 = f.readline().strip('\n')

if oldipv6 != ipv6wert:
    print("Präfix stimmt nicht mit Textdatei überein. Schreibe neues Präfix in Textdatei.")
    # In Datei speichern
    with open(txtfile, "w") as text_file:
        text_file.write(fuer_txt_datei)
    # update spdns
    myurl = "https://update.spdyn.de/nic/update?hostname=%s&myip=%s" % (spdynurl, ipv6wert)
    print("Versuche nun spDYN zu updaten.")
    print(myurl)
    r = requests.get(myurl, auth=(spdynuser, spdynpwd))
    print(r.text)
else:
    print("Keine Veränderung.")

In den Zeilen 8-13 des Scipts müsst ihr entsprechend eure Daten eintragen.

Das Script kann nun direkt gestartet werden:

/pfad/zu/spdyn-ipv6.py

systemd

Ich verwende systemd, um das Script regelmäßig aufzurufen. So sieht meine ipv6-spdyn.service aus:

sudo nano /etc/systemd/system/ipv6-spdyn.service
[Unit]
Description=aktuelle IPv6 herausfinden und nach spDYN senden

[Service]
Type=oneshot
ExecStart=/sbin/python '/Pfad/zu/ipv6hsp.py'

[Install]
WantedBy=multi-user.target

In Zeile 6 muss der Pfad auf das Script ipv6hsp.py angepasst werden.

Jetzt benötigen wir noch den entsprechenden ipv6-spdyn.timer:

sudo nano /etc/systemd/system/ipv6-spdyn.timer
[Unit]
Description=stuendlich nach IPv6 von Heimserver schauen

[Timer]
# Run hourly
OnCalendar=*-*-* *:00:00
Persistent=true
Unit=ipv6-spdyn.service

[Install]
WantedBy=timers.target

Anschließend muss systemd die daemon-files reloaden und der Dienst kann aktiviert werden:

sudo systemctl daemon-reload 
sudo systemctl start ipv6-spdyn.service
sudo systemctl enable ipv6-spdyn.timer

Funktioniert hier nun bestens.

Aber mittlerweile mache ich das alles per ddclient.