🖥 Webserver g50zeiten — Administrations-Doku

Diese Anleitung deckt zwei Hauptaufgaben ab: Die ipv64 DNS-Update-Skripte und das System-Update von Ubuntu. Sie ist als Schritt-für-Schritt-Anleitung geschrieben, sodass Sie sie auch noch nach Monaten Pause wieder benutzen können.

ℹ️ Wichtig: Diese Anleitung gilt für das System mit der IP 192.168.178.132 (VM: 132-Webserver-nginx, Ubuntu 24.04 LTS).

⭐ Schnellanleitung: Neue Website in 10 Minuten

Du willst eine neue Subdomain wie meinedienst.rusti.ipv64.net öffentlich erreichbar machen? Hier die 5 Schritte auf einen Blick. Details siehe weiter unten.

SchrittWasWoDauer
1 App vorbereiten (Verzeichnis, DB, config.php, Apache-Site) VM .122 5 min
2 DNS-Record bei ipv64 anlegen (A-Record mit Präfix) ipv64.net Web 1 min
3 DNS-Update-URL aus Anker ⚓ kopieren und in Cron-Skript einfügen VM .132 2 min
4 NPM Proxy Host anlegen mit Let's Encrypt SSL NPM auf .131:81 1 min
5 Im Browser testen → https://meinedienst.rusti.ipv64.net Browser 1 min

Schritt 1 — App auf .122 vorbereiten

Falls eine reine statische Seite reicht (kein PHP/DB), nur Verzeichnis + Apache-Site:

ssh root@192.168.178.122

# Verzeichnis anlegen
mkdir -p /var/www/meinedienst
chown -R www-data:www-data /var/www/meinedienst

# Test-Datei
echo "<h1>Hello meinedienst</h1>" > /var/www/meinedienst/index.html

# Apache-VirtualHost
cat > /etc/apache2/sites-available/meinedienst.conf <<'EOF'
<VirtualHost *:80>
    ServerName meinedienst.rusti.ipv64.net
    DocumentRoot /var/www/meinedienst
    DirectoryIndex index.html

    SetEnvIf X-Forwarded-Proto "https" HTTPS=on

    Header always set X-Frame-Options "SAMEORIGIN"
    Header always set X-Content-Type-Options "nosniff"
    Header always set Referrer-Policy "strict-origin-when-cross-origin"

    <Directory /var/www/meinedienst>
        Options -Indexes +FollowSymLinks
        AllowOverride All
        Require all granted
    </Directory>

    ErrorLog ${APACHE_LOG_DIR}/meinedienst_error.log
    CustomLog ${APACHE_LOG_DIR}/meinedienst_access.log combined
</VirtualHost>
EOF

a2ensite meinedienst.conf
apache2ctl configtest
systemctl reload apache2
⚠️ Wichtig: ServerName ist Pflicht! Ohne diese Zeile fällt Apache auf die alphabetisch erste Site zurück und alle Subdomains landen bei der falschen App. Siehe Apache-VHost-Bug.

Schritt 2 — DNS-Record bei ipv64

  1. ipv64.net aufrufen und einloggen
  2. Domain rusti.ipv64.net öffnen → Edit domain
  3. "Add entry": Präfix = meinedienst · TTL = 10 · Typ = A · Ziel = aktuelle Heim-IP (oder leer lassen, ipv64 erkennt sie)
  4. Klick auf das Anker-Symbol ⚓ beim neuen Record → URL aus Adresszeile kopieren (Cmd+L, Cmd+C)
🚨 Sicherheit: Die URL enthält deinen Record-Token. Niemals in öffentliche Chats, GitHub, Logs posten! Bei versehentlicher Veröffentlichung sofort regenerieren.

Schritt 3 — Update-URL ins Cron-Skript

ssh root@192.168.178.132

# Backup nicht vergessen
cp /websitesscript/websites-upd-cronjob.sh \
   /websitesscript/websites-upd-cronjob.sh.bak

# Bearbeiten
nano /websitesscript/websites-upd-cronjob.sh

Eine neue Zeile in das urls=()-Array einfügen (4 Leerzeichen, Anführungszeichen, KEIN Komma):

    "https://ipv4.ipv64.net/nic/update?key=DEIN_KEY&domain=rusti.ipv64.net"

Speichern (Ctrl+O → Enter → Ctrl+X) und testen:

bash -n /websitesscript/websites-upd-cronjob.sh && echo "✓ Syntax OK"
bash /websitesscript/websites-upd-cronjob.sh && echo "✓ Lief durch"

# Direkt-Test aller URLs
for url in $(grep '"https' /websitesscript/websites-upd-cronjob.sh | sed 's/.*"\(https[^"]*\)".*/\1/'); do
    key=$(echo "$url" | grep -oP "(?<=key=)[A-Za-z0-9]+" | head -1)
    echo -n "Key=...${key: -4}: "
    curl -sS "$url"
    echo ""
done

Erwartung pro URL: {"info":"good","status":"success"} oder {"info":"nochg","status":"success"}

Schritt 4 — NPM Proxy Host anlegen

Browser: http://192.168.178.131:81

  1. Hosts → Proxy Hosts → Add Proxy Host
  2. Details:
    • Domain Names: meinedienst.rusti.ipv64.net
    • Scheme: http
    • Forward Hostname/IP: 192.168.178.122
    • Forward Port: 80
    • ☑️ Block Common Exploits
    • ☑️ Websockets Support
  3. SSL-Tab:
    • SSL Certificate: Request a new SSL Certificate
    • ☑️ Force SSL
    • ☑️ HTTP/2 Support
    • ☑️ HSTS Enabled
    • ☑️ Agree to Terms
  4. Save klicken → Let's Encrypt holt das Zertifikat (~30-60 Sek)
⚠️ Let's-Encrypt-Rate-Limit: Pro Hauptdomain (ipv64.net) max. 5 Zertifikate pro Woche. Falls "Internal Error" kommt — später nochmal probieren.

Schritt 5 — Testen

# DNS-Auflösung weltweit prüfen
dig +short meinedienst.rusti.ipv64.net @8.8.8.8

# HTTP-Header prüfen (sollte UTF-8 und HTTPS-Header zeigen)
curl -sI https://meinedienst.rusti.ipv64.net/

# Im Browser:
# https://meinedienst.rusti.ipv64.net

Wenn alles passt: 🎉 Fertig! Die Subdomain ist weltweit erreichbar mit HTTPS.

📋 Cheatsheet — alle wichtigen Befehle

SSH-Zugriff

VMBefehlZweck
.121ssh root@192.168.178.121CoolDB-Catta
.122ssh root@192.168.178.122Apps (Stunden/Abos/Treckertreff)
.131NPM-Web-UI http://192.168.178.131:81Reverse-Proxy + SSL
.132ssh root@192.168.178.132DNS-Update-Cronjobs

DNS-Skripte

BefehlZweck
ls /websitesscript/Alle DNS-Update-Skripte auflisten
nano /websitesscript/websites5-upd-cronjob.shSkript bearbeiten
chmod +x /websitesscript/websites5-upd-cronjob.shAusführbar machen
bash /websitesscript/websites5-upd-cronjob.shSkript jetzt ausführen
crontab -lGeplante Jobs anzeigen
crontab -eJobs bearbeiten
grep CRON /var/log/syslog | tailLetzte Cron-Aufrufe sehen

Apache (auf .122)

BefehlZweck
ls /etc/apache2/sites-enabled/Aktive Sites
apachectl -t -D DUMP_VHOSTSAlle VHosts mit ServerName
a2ensite NAME.confSite aktivieren
a2dissite NAME.confSite deaktivieren
apache2ctl configtestConfig-Syntax prüfen
systemctl reload apache2Config neu einlesen (kein Downtime)
systemctl restart apache2Apache komplett neu starten
tail -f /var/log/apache2/*_error.logAlle Error-Logs live

ipv64 Test-Antworten verstehen

AntwortBedeutung
{"info":"good", ...}✅ IP wurde aktualisiert
{"info":"nochg", ...}✅ IP war schon korrekt
{"info":"badauth", ...}❌ Key ungültig — Record neu anlegen oder URL prüfen
HTML-Fehlerseite❌ URL kaputt — sollte /nic/update sein

⚠️ Apache-VHost-Bug — falsche App bei richtigen URL

Symptom: Du rufst stunden.rusti.ipv64.net auf, siehst aber die Abo-App. Oder andersrum.

Ursache: Bei einer der Apache-Site-Configs fehlt der ServerName. Apache nimmt dann die alphabetisch erste Site (abos.conf) für ALLE Subdomains ohne Match.

Diagnose

apachectl -t -D DUMP_VHOSTS

Erwartet: Jede Site mit korrektem ServerName:

port 80 namevhost abos.rusti.ipv64.net (.../abos.conf:1)
port 80 namevhost stundng50.rusti.ipv64.net (.../stunden.conf:1)
port 80 namevhost tbrt.rusti.ipv64.net (.../treckertreff.conf:1)

Wenn dort statt einer der Subdomains nur der VM-Hostname (z.B. g50zeiten) steht → ServerName fehlt in dieser Config!

Fix

# Backup
cp /etc/apache2/sites-available/STUNDEN.conf /root/STUNDEN.conf.bak

# ServerName direkt nach <VirtualHost *:80> einfügen
sed -i '/<VirtualHost \*:80>/a\    ServerName stundng50.rusti.ipv64.net' \
  /etc/apache2/sites-available/STUNDEN.conf

# Verifizieren + neu laden
apache2ctl configtest
systemctl reload apache2
apachectl -t -D DUMP_VHOSTS

System-Architektur — wer macht was?

Die Stundenabrechnung und andere Services sind weltweit über HTTPS erreichbar. Damit das funktioniert, arbeiten mehrere Komponenten zusammen:

KomponenteAufgabe
FritzBox Empfängt eingehende Anfragen aus dem Internet auf Port 80/443 und leitet sie an die NPM-VM 192.168.178.131 weiter
ipv64.net DNS-Dienst: löst Subdomains wie stundng50.rusti.ipv64.net auf die aktuelle öffentliche IP des Heimanschlusses auf
Cron-Skripte (.132) Sagen ipv64 regelmäßig „Die aktuelle IP von rusti.ipv64.net ist X" — falls sich die öffentliche IP ändert
NPM (.131) Nginx Proxy Manager auf Docker-Debian — verteilt eingehende HTTPS-Anfragen auf die einzelnen App-VMs und kümmert sich um Let's-Encrypt-Zertifikate
App-VMs Die tatsächlichen Anwendungen, z.B. 122-g50zeiten für die Stundenabrechnung

Beteiligte VMs

IPVMService
192.168.178.121121-CoolDB-Catta(andere App)
192.168.178.122122-g50zeitenStundenabrechnung (Apache + MariaDB)
192.168.178.131131-Docker-DebianNPM (Nginx Proxy Manager) + Reverse-Proxy
192.168.178.132132-Webserver-nginxStatus-Seiten + DNS-Update-Cronjobs

Was machen die DNS-Update-Skripte?

Da Sie einen privaten Internetanschluss haben, ändert sich Ihre öffentliche IP gelegentlich (z.B. nach Router-Neustart, Provider-Reconnect). Wenn das passiert, würden Ihre Subdomains ins Leere zeigen — bis ein Update den DNS-Eintrag aktualisiert.

Auf der VM 132-Webserver-nginx liegen vier Cron-Skripte im Verzeichnis /websitesscript/, die diese Updates regelmäßig durchführen.

UhrzeitSkriptFunktion
06:00 CESTwebsites-upd-cronjob.shUpdate-Slot 1
06:15 CESTwebsites2-upd-cronjob.shUpdate-Slot 2
06:30 CESTwebsites3-upd-cronjob.shUpdate-Slot 3
07:00 CESTwebsites4-upd-cronjob.shUpdate-Slot 4

Jedes Skript enthält ein Array mit Update-URLs. Pro URL wird ein ipv64-DNS-Record aktualisiert.

ℹ️ Warum 4 Skripte? Historisch gewachsen. Sie können alle Records in einem Skript zusammenfassen — Cron behandelt jedes Skript wie eine eigenständige Datei. Praktisch ist die Aufteilung, wenn Sie Services in Gruppen verwalten möchten (z.B. „Heim-Services" vs. „Arbeits-Services").

Symbole im ipv64-Dashboard

Beim Record-Eintrag sehen Sie rechts 5 Symbole. Hier deren Bedeutung:

SymbolFunktionVorsicht
🔗 Externer Link Öffnet Detail-Seite zum Record Harmlos
⚓ Anker Sofort-Update: setzt die IP des Anfragenden in den DNS-Record Wirkt sofort! Klick aus dem Büro = Büro-IP wird gesetzt
↻ Doppelpfeil Token regenerieren: erzeugt einen neuen Key, alter wird ungültig Vorher Cron-Skripte anpassen!
✏️ Stift Record bearbeiten (Präfix, TTL, Typ, Ziel) Harmlos
🗑 Mülltonne (rot) Record komplett löschen Subdomain ist sofort weg!

Token-Sicherheitsstufen bei ipv64

ipv64 bietet drei verschiedene Token-Typen mit unterschiedlichen Berechtigungen:

StufeTypWirkungsbereichEmpfehlung
3 / High ★★★ Record-Token Nur dieser einzelne DNS-Record Verwenden!
2 / Mid ★★ Domain-Token Alle Records dieser Domain Nur wenn nötig
1 / Low ★ Account-Token ALLE Records des Accounts Niemals verwenden!
💡 Empfehlung: Verwenden Sie immer den Record-Token (Stufe 3). Wenn dieser Key versehentlich geleakt wird, kann ein Angreifer nur diesen einzelnen Record manipulieren — alle anderen sind unberührt.

Skript-Syntax — exakte Form

Jedes der vier Update-Skripte hat dieselbe Struktur:

#!/bin/bash
# Update-URLs fuer ipv64.net DNS-Records
urls=(
    "https://ipv4.ipv64.net/nic/update?key=DERKEY&domain=rusti.ipv64.net"
    "https://ipv4.ipv64.net/nic/update?key=ANDERKEY&domain=rusti.ipv64.net"
)
for url in "${urls[@]}"; do
    curl -sS "$url" >/dev/null
done

Wichtige Syntax-Regeln

RegelBegründung
URL in doppelten Anführungszeichen "Bash würde sonst das & als Steuerzeichen interpretieren
Kein Komma am ZeilenendeDas ist ein Bash-Array, nicht JSON! Komma macht Fehler.
4 Leerzeichen Einrückung (oder Tab) am ZeilenanfangKosmetisch, hilft beim Lesen
URL komplett auf einer ZeileKeine Zeilenumbrüche innerhalb einer URL
Trennzeichen in URL ist &, nicht =So sind Query-Parameter aufgebaut: ?a=1&b=2&c=3

Anatomie der ipv64-Update-URL

https://ipv4.ipv64.net/nic/update?key=ABC123&domain=rusti.ipv64.net
        └──────────────┘└────────┘└───────┘└──────────────────────┘
              Host          Pfad      Key             Domain

Die URL bekommen Sie automatisch von ipv64, wenn Sie auf den Anker ⚓ klicken — sie steht dann in der Browser-Adresszeile.

⚠️ Häufiger Fehler: Die URL endet mit =rusti.ipv64.net statt &domain=rusti.ipv64.net. Wenn so etwas in Ihrem Skript steht, hat beim Kopieren etwas nicht geklappt — die URL ist kaputt und ipv64 wird mit Unauthorized antworten.

📝 NEUE Website hinzufügen — Schritt für Schritt

Vorgehensweise wenn Sie eine neue Subdomain wie meinedienst.rusti.ipv64.net einrichten möchten und der DNS-Eintrag automatisch aktualisiert werden soll.

1 Im ipv64-Dashboard anmelden

Browser öffnen: https://ipv64.net → oben rechts auf „Login" → einloggen.

2 Domain rusti.ipv64.net öffnen

Im Dashboard die Domain anklicken → „Edit domain" öffnet sich mit der DNS-Record-Liste.

3 Neuen A-Record anlegen

Im Eingabeformular oben:

  • Präfix: Name der Subdomain, z.B. meinedienst
  • Domain: rusti.ipv64.net (vorgegeben)
  • TTL: 10 (Standard, geht in der Sekunde, wenn IP wechselt)
  • Typ: A
  • Ziel: Ihre aktuelle öffentliche IP — wird oft automatisch erkannt

„Add entry" klicken. Der Record erscheint in der Liste mit einem grünen „Valid"-Status.

4 Update-URL aus dem Anker holen

Beim neuen Record auf das Anker ⚓ klicken (zweites Symbol von links). Der Browser öffnet eine Seite, auf der eine JSON-Antwort steht:

{"info":"nochg","status":"success","ip":{"ipv4":"84.149.178.189"}}

In der Adresszeile steht jetzt die fertige Update-URL:

https://ipv4.ipv64.net/nic/update?key=ABC...XYZ&domain=rusti.ipv64.net

Cmd+L markiert die Adresszeile, Cmd+C kopiert.

🚨 Sicherheit: Die URL enthält Ihren Record-Token. Diese URL niemals in öffentliche Chats, GitHub, Logs etc. posten! Wer sie hat, kann den DNS-Record umlenken.
5 Per SSH auf die Webserver-VM

Im Mac-Terminal:

ssh root@192.168.178.132
6 Backup des Skripts machen

Bevor wir etwas ändern, eine Sicherung erstellen:

cp /websitesscript/websites-upd-cronjob.sh \
   /websitesscript/websites-upd-cronjob.sh.bak

(Den Skript-Namen passend zu Ihrem Wunsch wählen — siehe Hinweis unten.)

7 Skript bearbeiten
nano /websitesscript/websites-upd-cronjob.sh

Im Editor: Cursor mit Pfeiltasten ans Ende der letzten URL-Zeile (vor der schließenden )) navigieren. Enter drücken für neue Zeile. Dann die Update-URL einfügen — Format:

    "https://ipv4.ipv64.net/nic/update?key=IHR_KEY&domain=rusti.ipv64.net"

Wichtig: 4 Leerzeichen am Anfang, dann Anführungszeichen, URL, Anführungszeichen. Kein Komma am Ende!

Speichern: Ctrl+OEnterCtrl+X

8 Syntax-Check
bash -n /websitesscript/websites-upd-cronjob.sh
echo "Syntax-Exit: $?"

Erwartet: Syntax-Exit: 0 — bedeutet keine Syntaxfehler.

Falls Fehler kommt: nochmal nano öffnen und die neu eingefügte Zeile prüfen (Anführungszeichen, kein Komma, kein Zeilenumbruch in der URL).

9 Test-Aufruf — funktioniert der Key?
for url in $(grep '"https' /websitesscript/websites-upd-cronjob.sh | sed 's/.*"\(https[^"]*\)".*/\1/'); do
    key=$(echo "$url" | grep -oP "(?<=key=)[A-Za-z0-9]+" | head -1)
    echo -n "Key=...${key: -4}: "
    curl -sS "$url"
    echo ""
done

Sollte für jeden Key eine Erfolgs-Meldung von ipv64 zeigen (nochg oder good). Siehe Tabelle ipv64-Antworten verstehen.

10 Skript komplett ausführen wie Cron es tut
bash /websitesscript/websites-upd-cronjob.sh
echo "Exit: $?"

Erwartet: Exit: 0

11 DNS-Auflösung aus Sicht der Welt prüfen
dig +short meinedienst.rusti.ipv64.net @8.8.8.8

Sollte Ihre Heim-IP zeigen (z.B. 84.149.178.189). Falls noch eine andere IP kommt: ein paar Sekunden warten und nochmal probieren — DNS-Caches brauchen Zeit.

📦 Welches Skript wählen? Bei nur wenigen Subdomains reicht es, alles in websites-upd-cronjob.sh zu packen. Die anderen drei sind Reserve-Slots.

Token neu generieren — wenn ein Key geleakt ist

Wenn Sie einen Key versehentlich veröffentlicht haben (z.B. in einer E-Mail, Forum, GitHub-Commit), müssen Sie ihn ungültig machen.

1 Im ipv64-Dashboard auf den Record

Beim entsprechenden Record das ↻ Doppelpfeil-Symbol klicken.

2 Bestätigen

ipv64 zeigt einen Bestätigungs-Dialog. Bestätigen → ein neuer Key wird erzeugt, der alte ist sofort ungültig.

3 Neue URL holen und in Skript ersetzen

Beim Record auf den Anker ⚓ klicken → neue URL aus Adresszeile kopieren → in nano das alte URL durch das neue ersetzen → speichern.

4 Testen wie bei "Neue Website" Schritt 8-10
⚠️ Reihenfolge wichtig: Wenn Sie den Key im ipv64-Dashboard regenerieren bevor Sie das Cron-Skript anpassen, scheitert das nächste Cron-Update (mit alter URL) am Unauthorized-Fehler. Bei statischer FritzBox-IP kein Drama; bei wechselnder IP könnte die DNS-Auflösung kurz veraltet sein.

Website entfernen

Wenn Sie einen Service nicht mehr nutzen, sollten Sie sowohl den DNS-Record als auch das Cron-Skript bereinigen.

1 Erst Cron-Skript bereinigen

Im Skript die entsprechende URL-Zeile löschen. nano: Cursor auf die Zeile setzen, Ctrl+K schneidet die ganze Zeile.

2 Dann im ipv64-Dashboard löschen

Beim Record auf 🗑 Mülltonne klicken → bestätigen. Record ist weg.

💡 Reihenfolge: Andersherum — erst Record löschen, dann Skript bereinigen — geht auch, hat aber zur Folge, dass der nächste Cron-Lauf eine Fehler-Antwort von ipv64 bekommt. Bei sauberer Reihenfolge bleibt das Log fehlerfrei.

Wann werden die Skripte aufgerufen?

Die geplanten Ausführungszeiten sehen Sie mit:

crontab -l

Standardmäßig sind die vier Skripte zwischen 06:00 und 07:00 morgens CEST geplant.

Zeitzone überprüfen

Cron nutzt die Systemzeit der VM. Diese sollte Europe/Berlin sein:

timedatectl

Wenn dort UTC steht, läuft das System 1-2 Stunden „hinterher" — die 6:00-Skripte würden dann erst um 8:00 deutscher Zeit ausgeführt. Umstellen:

timedatectl set-timezone Europe/Berlin
systemctl restart cron

Cron-Job-Zeit ändern

crontab -e

Die Zeile entsprechend anpassen. Cron-Syntax:

m h dom mon dow command
│ │ │   │   │   └─ Befehl
│ │ │   │   └───── Wochentag (0-7, 0 oder 7 = Sonntag)
│ │ │   └───────── Monat (1-12)
│ │ └───────────── Tag im Monat (1-31)
│ └─────────────── Stunde (0-23)
└───────────────── Minute (0-59)

Beispiele:

Cron-EintragBedeutung
0 6 * * *Täglich um 06:00
*/15 * * * *Alle 15 Minuten
0 */4 * * *Alle 4 Stunden
0 6,12,18 * * *3× täglich (6, 12, 18 Uhr)
0 8 * * 1-5Mo-Fr um 8 Uhr

Test-Workflow nach jeder Änderung

Nach jeder Änderung an einem Skript diese vier Tests durchlaufen:

Test 1: Syntax-Check

bash -n /websitesscript/websites-upd-cronjob.sh
echo "Syntax-Exit: $?"

Syntax-Exit: 0 = OK.

Test 2: Skript läuft

bash /websitesscript/websites-upd-cronjob.sh
echo "Exit: $?"

Exit: 0 = OK.

Test 3: ipv64-Antworten prüfen

for url in $(grep '"https' /websitesscript/websites-upd-cronjob.sh | sed 's/.*"\(https[^"]*\)".*/\1/'); do
    key=$(echo "$url" | grep -oP "(?<=key=)[A-Za-z0-9]+" | head -1)
    echo -n "Key=...${key: -4}: "
    curl -sS "$url"
    echo ""
done

Test 4: DNS-Auflösung

dig +short stundng50.rusti.ipv64.net @8.8.8.8

Sollte Ihre aktuelle öffentliche IP zeigen.

Cron-Simulation in 2 Minuten

Um zu testen, ob Cron das Skript wirklich ausführen kann:

date

Aktuelle Zeit notieren, z.B. 21:23. Dann:

crontab -e

Test-Zeile einfügen (2 Minuten in der Zukunft, also 21:25):

25 21 * * * /websitesscript/websites-upd-cronjob.sh

Speichern, dann warten. Um 21:25 prüfen:

grep CRON /var/log/syslog | tail -5

Sie sollten einen Eintrag wie CMD (/websitesscript/websites-upd-cronjob.sh) sehen.

Danach mit crontab -e die Test-Zeile wieder entfernen.


System-Update — Übersicht

Ubuntu erhält regelmäßig Sicherheits-Updates. Diese sollten Sie etwa einmal im Monat einspielen. Längere Pausen sind nicht ratsam, weil sich Sicherheits-Lücken ansammeln.

ℹ️ Wann ist ein guter Zeitpunkt? Wenn keine kritischen Vorgänge laufen — z.B. nicht während Sie wichtige Stunden-Einträge bearbeiten. Die laufenden Services können wegen Restart von nginx, ssh und Co. für wenige Sekunden ausfallen.

Was kann passieren?

Update-TypAuswirkung
Sicherheits-Patches (Library, Systemd, etc.)Restart einzelner Services nötig — meist im laufenden Betrieb
nginx-UpdateWebserver-Restart, ~1 Sekunde Downtime
openssh-server-UpdateSSH-Restart — bestehende Session bleibt, neue Logins kurz nicht möglich
Kernel-UpdateReboot nötig (Datei /var/run/reboot-required erscheint)
Konfigurations-KonfliktEingreifen erforderlich — siehe unten

🔄 Update Step-by-Step

1 Backup über Proxmox sicherstellen

Im Proxmox-Web-UI: VM 132-Webserver-nginx auswählen → links auf „Backup" → ggf. ein aktuelles Backup erstellen (oder prüfen, ob schon eines weniger als 24h alt ist). Damit haben Sie im Notfall einen Rollback-Punkt.

2 Per SSH einloggen
ssh root@192.168.178.132
3 Paketquellen aktualisieren
apt update

Dauert wenige Sekunden, lädt nur die Paketlisten herunter — verändert nichts am System.

4 Aufkommende Updates sehen
apt list --upgradable

Zeigt alle Pakete, die ein Update bekommen würden. Bei 50-200 Paketen ist alles normal.

5 Updates installieren
apt upgrade -y

Das -y beantwortet Standard-Rückfragen mit „Ja". Aber Achtung: Bei Konfigurations-Konflikten wird trotzdem gefragt — siehe nächster Abschnitt!

6 Aufräumen
apt autoremove -y
apt autoclean

Entfernt nicht mehr benötigte Pakete und alte Versionen aus dem Paket-Cache.

7 Reboot-Check
[ -f /var/run/reboot-required ] && echo "🔁 Reboot empfohlen" || echo "✅ Kein Reboot nötig"

Wenn „Reboot empfohlen": reboot ausführen (SSH-Session wird getrennt, einfach in 30-60 Sekunden neu verbinden).

8 Services prüfen
systemctl is-active nginx ssh.socket cron apache2

Alle relevanten Services sollten active sein.

⚠️ Wichtig: Bei Ubuntu 24.04 wird SSH als ssh.socket aktiviert (nicht mehr als ssh.service). Wenn systemctl is-active ssh „inactive" zeigt, ist das OK — solange ssh.socket aktiv ist!

9 Funktionstest der Anwendungen

Stunden-App im Browser aufrufen — Login klappt? Reverse-Proxy auf .131 lebt? Falls es Probleme gibt: Notfall-Wiederherstellung.

Konfigurations-Konflikte richtig behandeln

Wenn das Update fragt:

Configuration file '/etc/...'
 ==> Modified (by you or by a script) since installation.
 ==> Package distributor has shipped an updated version.
   What would you like to do about it?
    Y or I  : install the package maintainer's version
    N or O  : keep your currently-installed version (default)
      D     : show the differences between the versions
      Z     : start a shell to examine the situation
*** ... (Y/I/N/O/D/Z) [default=N] ?

Immer „N" oder einfach Enter drücken (Default). Damit bleibt Ihre angepasste Konfiguration erhalten. Wenn Sie versehentlich „Y" wählen, wird Ihre Konfiguration durch die Standard-Version überschrieben — und Ihre Anpassungen (Sites, Cron-Skripte, etc.) sind weg.

🚨 Niemals „Y" wählen wenn Sie nicht 100% sicher sind. Konfigurations-Dateien von Webservern, SSH und Cron können dabei zerstört werden.

Reboot oder nicht?

Folgende Updates erfordern einen Reboot:

Folgende Updates erfordern nur einen Service-Restart:

Ubuntu sagt Bescheid, ob ein Reboot nötig ist:

[ -f /var/run/reboot-required ] && cat /var/run/reboot-required.pkgs

Cron-Log lesen

Cron schreibt jede Ausführung in das System-Log:

grep CRON /var/log/syslog | tail -20

Beispielausgabe:

May 20 06:00:01 Webserver-nginx CRON[1759]: (root) CMD (/websitesscript/websites-upd-cronjob.sh)
May 20 06:15:01 Webserver-nginx CRON[1870]: (root) CMD (/websitesscript/websites2-upd-cronjob.sh)

Live mitschauen:

journalctl -u cron -f

Beenden mit Ctrl+C.

DNS-Auflösung prüfen

BefehlWas er macht
dig +short HOSTAuflösung über System-DNS
dig +short HOST @8.8.8.8Auflösung über Google-DNS (Sicht „der Welt")
dig +short HOST @1.1.1.1Auflösung über Cloudflare-DNS
nslookup HOSTKlassisches Tool, mehr Infos

Aktuelle öffentliche IP des Anschlusses ermitteln:

curl -sS https://ifconfig.me
curl -sS https://api.ipify.org

ipv64-Antworten verstehen

Wenn Sie das Update-Skript testen, antwortet ipv64 mit JSON. Hier die häufigsten:

AntwortBedeutungAktion
{"info":"good", "status":"success"} ✅ IP wurde gerade aktualisiert Nichts
{"info":"nochg", "status":"success"} ✅ IP war schon richtig (kein Update nötig) Nichts
{"info":"badauth", "status":"401 Unauthorized"} ❌ Key war mal gültig, gehört aber zu gelöschtem oder umbenanntem Record Key aus Skript entfernen oder Record neu anlegen
{"info":"Unauthorized", "status":"401 Unauthorized"} ❌ Key syntaktisch falsch oder URL kaputt URL im Skript prüfen (richtige Anführungszeichen, &domain= richtig?)
HTML-Fehlerseite ❌ Endpunkt-URL falsch (z.B. /showip statt /nic/update) URL korrigieren

Services prüfen

BefehlZweck
systemctl is-active SERVICEKurzcheck: active/inactive/failed
systemctl status SERVICE --no-pagerVoller Status mit letzten Log-Zeilen
systemctl restart SERVICEService neu starten
systemctl reload SERVICEKonfiguration neu laden (sanfter als Restart)

Wichtige Services auf der Webserver-VM:


API-Keys richtig schützen

Notfall-Wiederherstellung

Skript versehentlich kaputt gemacht

Wenn Sie ein .bak-Backup haben:

cp /websitesscript/websites-upd-cronjob.sh.bak \
   /websitesscript/websites-upd-cronjob.sh
chmod +x /websitesscript/websites-upd-cronjob.sh

Apache-Konfig kaputt

Wenn nach einem Update Apache nicht mehr startet:

apache2ctl configtest

Zeigt die fehlerhafte Zeile. Reparieren mit nano /etc/apache2/sites-available/....

Nichts hilft mehr — Rollback der VM

Im Proxmox-Web-UI:

  1. VM 132-Webserver-nginx auswählen
  2. Links auf „Backup"
  3. Das letzte funktionierende Backup auswählen
  4. „Zurückspielen" klicken
  5. VM startet neu auf dem Stand des Backups

⚠️ Achtung: Damit gehen ALLE Änderungen seit dem Backup verloren — auch Daten in Anwendungen, die seitdem entstanden sind.


Webserver-Doku Stand: 20.05.2026
Für IP 192.168.178.132 / Ubuntu 24.04 LTS / nginx + cron-Updates für ipv64.net