🖥 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.
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.
| Schritt | Was | Wo | Dauer |
|---|---|---|---|
| 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
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
- ipv64.net aufrufen und einloggen
- Domain
rusti.ipv64.netöffnen → Edit domain - "Add entry": Präfix =
meinedienst· TTL =10· Typ =A· Ziel = aktuelle Heim-IP (oder leer lassen, ipv64 erkennt sie) - Klick auf das Anker-Symbol ⚓ beim neuen Record → URL aus Adresszeile kopieren (Cmd+L, Cmd+C)
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
- Hosts → Proxy Hosts → Add Proxy Host
- Details:
- Domain Names:
meinedienst.rusti.ipv64.net - Scheme:
http - Forward Hostname/IP:
192.168.178.122 - Forward Port:
80 - ☑️ Block Common Exploits
- ☑️ Websockets Support
- Domain Names:
- SSL-Tab:
- SSL Certificate: Request a new SSL Certificate
- ☑️ Force SSL
- ☑️ HTTP/2 Support
- ☑️ HSTS Enabled
- ☑️ Agree to Terms
- Save klicken → Let's Encrypt holt das Zertifikat (~30-60 Sek)
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
| VM | Befehl | Zweck |
|---|---|---|
| .121 | ssh root@192.168.178.121 | CoolDB-Catta |
| .122 | ssh root@192.168.178.122 | Apps (Stunden/Abos/Treckertreff) |
| .131 | NPM-Web-UI http://192.168.178.131:81 | Reverse-Proxy + SSL |
| .132 | ssh root@192.168.178.132 | DNS-Update-Cronjobs |
DNS-Skripte
| Befehl | Zweck |
|---|---|
ls /websitesscript/ | Alle DNS-Update-Skripte auflisten |
nano /websitesscript/websites5-upd-cronjob.sh | Skript bearbeiten |
chmod +x /websitesscript/websites5-upd-cronjob.sh | Ausführbar machen |
bash /websitesscript/websites5-upd-cronjob.sh | Skript jetzt ausführen |
crontab -l | Geplante Jobs anzeigen |
crontab -e | Jobs bearbeiten |
grep CRON /var/log/syslog | tail | Letzte Cron-Aufrufe sehen |
Apache (auf .122)
| Befehl | Zweck |
|---|---|
ls /etc/apache2/sites-enabled/ | Aktive Sites |
apachectl -t -D DUMP_VHOSTS | Alle VHosts mit ServerName |
a2ensite NAME.conf | Site aktivieren |
a2dissite NAME.conf | Site deaktivieren |
apache2ctl configtest | Config-Syntax prüfen |
systemctl reload apache2 | Config neu einlesen (kein Downtime) |
systemctl restart apache2 | Apache komplett neu starten |
tail -f /var/log/apache2/*_error.log | Alle Error-Logs live |
ipv64 Test-Antworten verstehen
| Antwort | Bedeutung |
|---|---|
{"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:
| Komponente | Aufgabe |
|---|---|
| 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
| IP | VM | Service |
|---|---|---|
192.168.178.121 | 121-CoolDB-Catta | (andere App) |
192.168.178.122 | 122-g50zeiten | Stundenabrechnung (Apache + MariaDB) |
192.168.178.131 | 131-Docker-Debian | NPM (Nginx Proxy Manager) + Reverse-Proxy |
192.168.178.132 | 132-Webserver-nginx | Status-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.
| Uhrzeit | Skript | Funktion |
|---|---|---|
| 06:00 CEST | websites-upd-cronjob.sh | Update-Slot 1 |
| 06:15 CEST | websites2-upd-cronjob.sh | Update-Slot 2 |
| 06:30 CEST | websites3-upd-cronjob.sh | Update-Slot 3 |
| 07:00 CEST | websites4-upd-cronjob.sh | Update-Slot 4 |
Jedes Skript enthält ein Array mit Update-URLs. Pro URL wird ein ipv64-DNS-Record aktualisiert.
Symbole im ipv64-Dashboard
Beim Record-Eintrag sehen Sie rechts 5 Symbole. Hier deren Bedeutung:
| Symbol | Funktion | Vorsicht |
|---|---|---|
| 🔗 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:
| Stufe | Typ | Wirkungsbereich | Empfehlung |
|---|---|---|---|
| 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! |
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
| Regel | Begründung |
|---|---|
URL in doppelten Anführungszeichen " | Bash würde sonst das & als Steuerzeichen interpretieren |
| Kein Komma am Zeilenende | Das ist ein Bash-Array, nicht JSON! Komma macht Fehler. |
| 4 Leerzeichen Einrückung (oder Tab) am Zeilenanfang | Kosmetisch, hilft beim Lesen |
| URL komplett auf einer Zeile | Keine 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.
=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.
Browser öffnen: https://ipv64.net → oben rechts auf „Login" → einloggen.
Im Dashboard die Domain anklicken → „Edit domain" öffnet sich mit der DNS-Record-Liste.
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.
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.
Im Mac-Terminal:
ssh root@192.168.178.132
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.)
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+O → Enter → Ctrl+X
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).
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.
bash /websitesscript/websites-upd-cronjob.sh
echo "Exit: $?"
Erwartet: Exit: 0
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.
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.
Beim entsprechenden Record das ↻ Doppelpfeil-Symbol klicken.
ipv64 zeigt einen Bestätigungs-Dialog. Bestätigen → ein neuer Key wird erzeugt, der alte ist sofort ungültig.
Beim Record auf den Anker ⚓ klicken → neue URL aus Adresszeile kopieren →
in nano das alte URL durch das neue ersetzen → speichern.
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.
Im Skript die entsprechende URL-Zeile löschen. nano: Cursor auf die Zeile setzen,
Ctrl+K schneidet die ganze Zeile.
Beim Record auf 🗑 Mülltonne klicken → bestätigen. Record ist weg.
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-Eintrag | Bedeutung |
|---|---|
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-5 | Mo-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.
nginx, ssh und Co. für wenige Sekunden ausfallen.
Was kann passieren?
| Update-Typ | Auswirkung |
|---|---|
| Sicherheits-Patches (Library, Systemd, etc.) | Restart einzelner Services nötig — meist im laufenden Betrieb |
nginx-Update | Webserver-Restart, ~1 Sekunde Downtime |
openssh-server-Update | SSH-Restart — bestehende Session bleibt, neue Logins kurz nicht möglich |
| Kernel-Update | Reboot nötig (Datei /var/run/reboot-required erscheint) |
| Konfigurations-Konflikt | Eingreifen erforderlich — siehe unten |
🔄 Update Step-by-Step
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.
ssh root@192.168.178.132
apt update
Dauert wenige Sekunden, lädt nur die Paketlisten herunter — verändert nichts am System.
apt list --upgradable
Zeigt alle Pakete, die ein Update bekommen würden. Bei 50-200 Paketen ist alles normal.
apt upgrade -y
Das -y beantwortet Standard-Rückfragen mit „Ja". Aber Achtung:
Bei Konfigurations-Konflikten wird trotzdem gefragt — siehe nächster Abschnitt!
apt autoremove -y
apt autoclean
Entfernt nicht mehr benötigte Pakete und alte Versionen aus dem Paket-Cache.
[ -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).
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!
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.
Reboot oder nicht?
Folgende Updates erfordern einen Reboot:
- Kernel (
linux-image-*) - Standardbibliothek
libc6(technisch nicht zwingend, aber sicherheitshalber empfohlen) - Systemd (manchmal)
Folgende Updates erfordern nur einen Service-Restart:
nginx,apache2— Webserver neu startenphp8.3-fpm— PHP neu startenopenssh-server— bestehende Session bleibt- OpenSSL-Bibliotheken — abhängige Services brauchen 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
| Befehl | Was er macht |
|---|---|
dig +short HOST | Auflösung über System-DNS |
dig +short HOST @8.8.8.8 | Auflösung über Google-DNS (Sicht „der Welt") |
dig +short HOST @1.1.1.1 | Auflösung über Cloudflare-DNS |
nslookup HOST | Klassisches 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:
| Antwort | Bedeutung | Aktion |
|---|---|---|
{"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
| Befehl | Zweck |
|---|---|
systemctl is-active SERVICE | Kurzcheck: active/inactive/failed |
systemctl status SERVICE --no-pager | Voller Status mit letzten Log-Zeilen |
systemctl restart SERVICE | Service neu starten |
systemctl reload SERVICE | Konfiguration neu laden (sanfter als Restart) |
Wichtige Services auf der Webserver-VM:
nginx— Webserverssh.socket— SSH (in Ubuntu 24.04)cron— Zeitgesteuerte Jobsufw— Firewall
API-Keys richtig schützen
- Niemals Keys in öffentlichen Chats, Issue-Trackern, GitHub-Commits posten
- Wenn ein Key versehentlich öffentlich wurde: sofort regenerieren (siehe Token-Rotation)
- Skripte mit Keys nur für Root lesbar machen:
chmod 700 /websitesscript/*.sh chown root:root /websitesscript/*.sh - Backup-Dateien (
.sh.bak) nicht in öffentliche Verzeichnisse legen
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:
- VM
132-Webserver-nginxauswählen - Links auf „Backup"
- Das letzte funktionierende Backup auswählen
- „Zurückspielen" klicken
- 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