Kapitel 3/Premium Rohtext.md aktualisiert
This commit is contained in:
@@ -14,8 +14,6 @@ Wir kümmern uns um die Themen, die im Alltag den entscheidenden Unterschied mac
|
||||
Schutz für sensible Oberflächen (z. B. Pi-hole oder NPM selbst) mit Login-Schutz.
|
||||
- **Advanced Nginx Config**
|
||||
Eigene Weiterleitungen, Header-Anpassungen und Sicherheitsregeln direkt in der Oberfläche.
|
||||
- **Optimierungen für IPv6 & DS-Lite**
|
||||
Strategien für den sicheren Betrieb, wenn der Provider keine volle öffentliche IPv4 vergibt.
|
||||
- **Monitoring & Logging**
|
||||
Mehr Überblick, um Angriffe und Fehlerquellen schnell zu erkennen.
|
||||
|
||||
@@ -23,3 +21,395 @@ Wir kümmern uns um die Themen, die im Alltag den entscheidenden Unterschied mac
|
||||
> Der Premium-Bereich baut direkt auf dem Free-Teil auf.
|
||||
> Du musst nichts neu installieren – wir erweitern nur die bestehenden Funktionen und holen das Maximum aus NPM heraus.
|
||||
|
||||
## DynDNS-Updates für mehrere Anbieter gleichzeitig
|
||||
|
||||
Im Premium-Teil automatisieren wir die Aktualisierung unserer DynDNS-Einträge bei **DuckDNS** und **Strato** in einem Rutsch.
|
||||
So bleiben sowohl Test-Hostnamen (DuckDNS) als auch produktive Subdomains (Strato) zuverlässig auf der aktuellen IP – inklusive **IPv6**.
|
||||
|
||||
Wir legen dazu ein kleines Skript an, das beide Provider nacheinander aktualisiert und die Ergebnisse protokolliert.
|
||||
Öffne hierzu wieder das Teminal oder Putty über WinSCP, logge dich auf den NPM ein und gibt:
|
||||
|
||||
```bash
|
||||
nano /usr/local/bin/dyndns_update.sh
|
||||
```
|
||||
ein.
|
||||
Füge folgenden Inhalt ein **(Beispieldaten – im Produktivbetrieb ersetzen!)**:
|
||||
|
||||
```bash
|
||||
#!/bin/bash
|
||||
#
|
||||
# dyndns_update.sh
|
||||
# - Updates für DuckDNS und Strato
|
||||
# - IPv4 + globale IPv6
|
||||
# - Logging nach /var/log/dyndns_update.log
|
||||
#
|
||||
|
||||
NOW=$(date '+%d.%m.%Y %X')
|
||||
LOGFILE="/var/log/dyndns_update.log"
|
||||
IFACE="eth0" # ggf. anpassen (z. B. ens18)
|
||||
|
||||
# IPv4 und IPv6 ermitteln
|
||||
IPV4=$(curl -s https://ipv4.icanhazip.com)
|
||||
IPV6=$(ip -6 addr show dev "$IFACE" scope global 2>/dev/null \
|
||||
| grep inet6 \
|
||||
| grep -v "fd00" \
|
||||
| awk '{print $2}' \
|
||||
| cut -d/ -f1 \
|
||||
| head -n1)
|
||||
|
||||
echo "[$NOW] DynDNS Update gestartet – IPv4: ${IPV4:-<none>} / IPv6: ${IPV6:-<none>}" >> "$LOGFILE"
|
||||
|
||||
##################################
|
||||
# DuckDNS
|
||||
##################################
|
||||
DUCKDNS_TOKEN="DEIN_DUCKDNS_TOKEN"
|
||||
DUCKDNS_SUBDOMAINS=("sub1" "sub2")
|
||||
|
||||
for SUB in "${DUCKDNS_SUBDOMAINS[@]}"; do
|
||||
RESULT=$(curl -s "https://www.duckdns.org/update?domains=$SUB&token=$DUCKDNS_TOKEN&ip=$IPV4&ipv6=$IPV6&verbose=true")
|
||||
echo "[$NOW] DuckDNS: $SUB.duckdns.org → $RESULT" >> "$LOGFILE"
|
||||
done
|
||||
|
||||
##################################
|
||||
# Strato
|
||||
##################################
|
||||
STRATO_DOMAIN="beispiel-domain.de"
|
||||
STRATO_PASS="DEIN_DYNDNS_PASSWORT"
|
||||
STRATO_SUBDOMAINS=("sub1" "sub2" "sub3")
|
||||
|
||||
for SUB in "${STRATO_SUBDOMAINS[@]}"; do
|
||||
HOST="$SUB.$STRATO_DOMAIN"
|
||||
RESULT=$(curl -s --user "$STRATO_DOMAIN:$STRATO_PASS" \
|
||||
"https://dyndns.strato.com/nic/update?hostname=$HOST&myip=$IPV4,$IPV6")
|
||||
echo "[$NOW] Strato: $HOST → $RESULT" >> "$LOGFILE"
|
||||
done
|
||||
```
|
||||
|
||||
Datei speichern und ausführbar machen:
|
||||
|
||||
```bash
|
||||
chmod +x /usr/local/bin/dyndns_update.sh
|
||||
```
|
||||
|
||||
Jetzt richten wir die Ausführung per Cron ein, damit die Einträge regelmäßig aktualisiert werden:
|
||||
|
||||
```bash
|
||||
crontab -e
|
||||
```
|
||||
|
||||
Eintragen:
|
||||
|
||||
```bash
|
||||
*/5 * * * * /usr/local/bin/dyndns_update.sh
|
||||
```
|
||||
|
||||
> [!NOTE]
|
||||
> **Interface prüfen:** In LXC-Containern heißt die Netzwerkschnittstelle meist `eth0`.
|
||||
> Falls bei dir ein anderer Name angezeigt wird (z. B. `ens18`), passe `IFACE="eth0"` entsprechend an.
|
||||
> Prüfen kannst du das mit:
|
||||
> ```bash
|
||||
> ip -6 addr show
|
||||
> ```
|
||||
|
||||
> [!TIP]
|
||||
> **Log ansehen:**
|
||||
> ```bash
|
||||
> tail -n 50 /var/log/dyndns_update.log
|
||||
> ```
|
||||
> Typische Rückmeldungen:
|
||||
> • DuckDNS: `OK` / `KO` / `NOCHANGE`
|
||||
> • Strato: `good <IPv4> <IPv6>` (aktualisiert) oder `noch aktuell` (keine Änderung).
|
||||
> Wenn Strato `badauth` meldet, ist fast immer das **DynDNS-Passwort** im Strato-Panel nicht korrekt hinterlegt (nicht mit dem normalen Kunden-Login verwechseln).
|
||||
|
||||
> [!TIP]
|
||||
> Mit diesem Ansatz veröffentlichen wir direkt die **globale IPv6 des Containers**.
|
||||
> Damit umgehen wir Router-seitige IPv6-Filterungen (z. B. Fritz!Box), da die Verbindung nicht am Router hängenbleibt, sondern direkt auf die Adresse des Containers zeigt.
|
||||
> Wichtig: Stelle sicher, dass der Container tatsächlich eine **globale IPv6** besitzt (keine `fd00::` ULA) und dass Nginx Proxy Manager auch auf IPv6 lauscht (`[::]:443`).
|
||||
|
||||
---
|
||||
|
||||
## Erweiterte SSL-Konfiguration
|
||||
|
||||
Standard-Zertifikate in Nginx Proxy Manager (NPM) sind schnell eingerichtet.
|
||||
Für den dauerhaften und professionellen Betrieb empfiehlt sich die Einrichtung von **Wildcard-Zertifikaten**.
|
||||
Damit werden nicht nur einzelne Subdomains, sondern die gesamte Domain (`*.example.com`) mit einem Zertifikat abgesichert.
|
||||
|
||||
Zusätzlich härten wir die HTTPS-Verbindungen mit modernen Cipher-Suites und stellen sicher, dass Zertifikate automatisch erneuert werden.
|
||||
|
||||
### Wildcard-Zertifikat anlegen
|
||||
|
||||
1. Melde dich in der NPM-Weboberfläche an.
|
||||
2. Klicke links im Menü auf **SSL-Zertifikate**.
|
||||
3. Oben rechts: **+ Hinzufügen**.
|
||||
4. Wähle im Dialog **Let’s Encrypt**.
|
||||
5. Aktiviere die Checkbox **Wildcard-Zertifikat**.
|
||||
6. Trage deine Hauptdomain ein, z. B. `example.com`.
|
||||
7. Wähle als Validierungsmethode **DNS Challenge**.
|
||||
8. Wähle deinen Provider aus der Liste.
|
||||
|
||||
#### Beispiel: Cloudflare (automatisch)
|
||||
|
||||
1. Logge dich bei [Cloudflare](https://dash.cloudflare.com/) ein.
|
||||
2. Klicke auf dein Profil (oben rechts) → **Mein Profil**.
|
||||
3. Gehe zu **API-Tokens**.
|
||||
4. Klicke auf **API-Token erstellen**.
|
||||
5. Wähle die Vorlage **Zone:DNS Edit**.
|
||||
6. Setze die Berechtigungen: **Zone → DNS → Bearbeiten**.
|
||||
7. Wähle die Zone (Domain), für die der Token gilt.
|
||||
8. Klicke auf **Token erstellen** und kopiere den Wert.
|
||||
9. In NPM → Feld **API Key** einfügen.
|
||||
10. Auf **Speichern** klicken.
|
||||
|
||||
👉 *Screenshot geeignet: Cloudflare API-Token-Erstellung und NPM-Eingabemaske mit „DNS Challenge“.*
|
||||
|
||||
Ab jetzt erneuert NPM das Zertifikat automatisch, ohne dass du eingreifen musst.
|
||||
|
||||
#### Beispiel: Strato (manuell)
|
||||
|
||||
1. Wähle in NPM bei DNS-Provider **Strato (Manual)**.
|
||||
2. Klicke auf **Speichern**.
|
||||
3. NPM zeigt dir nun einen TXT-Eintrag an, der im DNS gesetzt werden muss.
|
||||
- Beispiel: `_acme-challenge.example.com`
|
||||
- Wert: zufällig generierter Token (z. B. `p8xj8HsD2sN...`)
|
||||
4. Logge dich in das [Strato-Kundenportal](https://www.strato.de/) ein.
|
||||
5. Gehe zu **Domainverwaltung → DNS-Einstellungen**.
|
||||
6. Füge den angezeigten TXT-Eintrag hinzu.
|
||||
7. Speichere die Änderungen.
|
||||
8. Warte einige Minuten, bis der Eintrag weltweit verfügbar ist.
|
||||
9. Gehe zurück in NPM → klicke auf **Bestätigen**.
|
||||
|
||||
👉 *Screenshot geeignet: NPM mit angezeigtem TXT-Record, Strato-DNS-Einstellungen mit eingetragenem TXT-Eintrag.*
|
||||
|
||||
#### Verlängerung kontrollieren
|
||||
|
||||
**In der NPM-Oberfläche:**
|
||||
|
||||
1. Öffne **SSL-Zertifikate**.
|
||||
2. Suche den Eintrag für dein Wildcard-Zertifikat (z. B. `*.example.com`, Anbieter: Let’s Encrypt).
|
||||
3. Prüfe in der Tabelle **Ablaufdatum** und die **Resttage**.
|
||||
4. Klicke den Eintrag, um die Details zu öffnen. Bei Problemen blendet NPM oben einen Hinweis ein (z. B. fehlgeschlagene DNS-Challenge).
|
||||
5. Falls nötig, löse die Verlängerung über das Aktionsmenü des Zertifikats **manuell** aus.
|
||||
|
||||
> [!TIP]
|
||||
> Startet die Verlängerung nicht oder schlägt sie fehl, prüfe die **DNS-Challenge**: API-Token gültig, Berechtigungen („DNS edit“) und richtige Zone.
|
||||
> Bei **manuellen Providern** (z. B. Strato) musst du den von NPM angezeigten **TXT-Record** zur Erneuerung erneut setzen.
|
||||
|
||||
**Optional – nur wenn NPM als Docker-Container läuft (auf dem NPM-LXC in der Shell):**
|
||||
```bash
|
||||
# Container-Namen ermitteln:
|
||||
docker ps
|
||||
|
||||
# Certbot-/Renew-Meldungen prüfen:
|
||||
docker logs <container-name> 2>&1 | grep -i -E "renew|success|invalid|challenge|error"
|
||||
```
|
||||
|
||||
> [!NOTE]
|
||||
> Ohne Docker-Betrieb entfallen die Log-Befehle – nutze ausschließlich die GUI unter **SSL-Zertifikate**.
|
||||
|
||||
👉 *Screenshot geeignet: Log-Auszug mit erfolgreicher Erneuerung.*
|
||||
|
||||
### Sichere Cipher-Suites aktivieren
|
||||
|
||||
1. Öffne im NPM-Menü **Einstellungen → SSL-Einstellungen**.
|
||||
2. Entferne die Häkchen bei **TLS 1.0** und **TLS 1.1**.
|
||||
3. Aktiviere nur **TLS 1.2** und **TLS 1.3**.
|
||||
4. Stelle den Cipher-Suite-Level auf **Intermediate (Mozilla)**.
|
||||
|
||||
> [!WARNING]
|
||||
> „Modern“ ist sicherer, aber viele ältere Clients (Smart-TVs, alte Android-Geräte) funktionieren dann nicht mehr.
|
||||
|
||||
Referenz: [Mozilla SSL Configuration Generator](https://ssl-config.mozilla.org/)
|
||||
|
||||
👉 *Screenshot geeignet: NPM SSL-Einstellungen mit aktivierten TLS-Versionen.*
|
||||
|
||||
|
||||
### Ergebnis
|
||||
|
||||
- Mit einem einzigen Zertifikat sind alle Subdomains geschützt.
|
||||
- Dank API-Challenge erneuert NPM das Zertifikat automatisch.
|
||||
- Die HTTPS-Verbindung ist nach aktuellen Standards gehärtet.
|
||||
|
||||
Damit sparst du Verwaltungsaufwand und erhöhst die Sicherheit deines gesamten Setups.
|
||||
|
||||
---
|
||||
|
||||
## Access Lists & Authentifizierung
|
||||
|
||||
Manche Oberflächen im UCC sollten nicht frei über das Internet erreichbar sein.
|
||||
Beispiele: die Admin-Oberfläche von Pi-hole, der Proxy-Manager selbst oder interne Tools.
|
||||
Mit Access Lists in NPM sichern wir diese Dienste zusätzlich ab.
|
||||
|
||||
### Neue Access List erstellen
|
||||
|
||||
1. Melde dich in der NPM-Oberfläche an.
|
||||
2. Klicke links im Menü auf **Access Lists**.
|
||||
3. Oben rechts: **+ Hinzufügen**.
|
||||
4. Vergib einen eindeutigen Namen, z. B. `Pi-hole-Admin`.
|
||||
5. Unter **Authorization**:
|
||||
- Aktiviere **Access**.
|
||||
- Trage einen Benutzernamen und ein starkes Passwort ein.
|
||||
- Klicke auf **+ Add** für weitere Nutzer.
|
||||
6. Optional: Unter **Client Access** kannst du einzelne IP-Adressen oder ganze Netze erlauben oder sperren.
|
||||
- Beispiel: Zugriff nur aus dem Heimnetz `192.168.50.0/24` erlauben.
|
||||
7. Klicke auf **Speichern**.
|
||||
|
||||
👉 *Screenshot geeignet: NPM-Formular „Access List hinzufügen“ mit Benutzer und Passwort.*
|
||||
|
||||
### Access List auf Proxy-Host anwenden
|
||||
|
||||
1. Gehe in der NPM-Oberfläche zu **Proxy Hosts**.
|
||||
2. Bearbeite den Eintrag für den gewünschten Dienst (z. B. `pi-hole.example.com`).
|
||||
3. Wechsel auf den Tab **Access List**.
|
||||
4. Wähle die zuvor erstellte Liste (z. B. `Pi-hole-Admin`).
|
||||
5. Speichern.
|
||||
|
||||
Ab sofort ist die gewählte Oberfläche nur noch nach Eingabe von Benutzername und Passwort erreichbar.
|
||||
|
||||
> [!TIP]
|
||||
> Es empfiehlt sich, für sensible Dienste **zwei Schichten** einzurichten:
|
||||
> - Einmal die interne Login-Maske des Dienstes selbst (z. B. Pi-hole oder Nextcloud).
|
||||
> - Zusätzlich die vorgeschaltete Authentifizierung in NPM.
|
||||
> Das erhöht die Sicherheit erheblich.
|
||||
|
||||
### Ergebnis
|
||||
|
||||
- Ohne Login kommt niemand mehr auf die geschützte Oberfläche.
|
||||
- Zugriff kann zusätzlich auf bestimmte IPs eingeschränkt werden.
|
||||
- Angriffe von außen werden deutlich erschwert.
|
||||
|
||||
## Advanced Nginx Config
|
||||
|
||||
Manche Anwendungen im UCC – wie z. B. Nextcloud – weisen im Admin-Dashboard Sicherheitswarnungen aus.
|
||||
Typisch ist die Meldung: *„Die Sicherheits- und Datenschutz-Header sind nicht korrekt gesetzt“.*
|
||||
Nginx Proxy Manager (NPM) bietet dafür keine eigene Einstellung – aber über den **Advanced-Tab** können wir solche Header selbst ergänzen.
|
||||
|
||||
### Problem
|
||||
Nextcloud meldet im Dashboard:
|
||||
- **Fehlender X-Frame-Options-Header** → Schutz vor Clickjacking fehlt.
|
||||
- **Fehlender X-Content-Type-Options-Header** → Browser könnten Dateien in falschem MIME-Typ interpretieren.
|
||||
- **Fehlende Referrer-Policy** → Browser geben mehr Informationen weiter als nötig.
|
||||
|
||||
Ohne diese Header bleibt die Warnung dauerhaft sichtbar.
|
||||
|
||||
### Lösung
|
||||
Wir tragen die fehlenden Header direkt in NPM ein.
|
||||
So werden sie bei jeder HTTPS-Verbindung automatisch hinzugefügt.
|
||||
|
||||
### Umsetzung Schritt für Schritt
|
||||
|
||||
1. Öffne die **NPM-Weboberfläche**.
|
||||
2. Gehe links auf **Proxy Hosts**.
|
||||
3. Wähle deinen Nextcloud-Host (z. B. `cloud.deine-domain.de`) → **Bearbeiten**.
|
||||
4. Wechsel auf den Tab **Advanced**.
|
||||
5. Trage im Feld **Custom Nginx Configuration** Folgendes ein:
|
||||
|
||||
```nginx
|
||||
add_header X-Frame-Options "SAMEORIGIN";
|
||||
add_header X-Content-Type-Options "nosniff";
|
||||
add_header Referrer-Policy "no-referrer-when-downgrade";
|
||||
```
|
||||
|
||||
6. Klicke auf **Speichern**.
|
||||
7. Starte den Proxy-Host einmal neu, falls die Änderungen nicht sofort greifen.
|
||||
|
||||
👉 *Screenshot geeignet: Proxy-Host „Nextcloud bearbeiten“ → Tab Advanced mit den drei Header-Zeilen.*
|
||||
|
||||
### Überprüfung
|
||||
|
||||
1. Öffne deine Nextcloud im Browser.
|
||||
2. Gehe ins **Admin-Dashboard**.
|
||||
- Die Warnung zu den fehlenden Headern sollte verschwunden sein.
|
||||
3. Alternativ: Browser-Entwicklertools (F12 → Netzwerk → Header einer Anfrage ansehen).
|
||||
- Dort müssen die drei neuen Header sichtbar sein:
|
||||
- `X-Frame-Options: SAMEORIGIN`
|
||||
- `X-Content-Type-Options: nosniff`
|
||||
- `Referrer-Policy: no-referrer-when-downgrade`
|
||||
|
||||
👉 *Screenshot geeignet: Nextcloud-Adminbereich ohne Warnmeldung.*
|
||||
|
||||
### Mehrwert
|
||||
|
||||
- **Nextcloud zeigt keine Sicherheitswarnung mehr an.**
|
||||
- Schutz vor **Clickjacking-Angriffen** und fehlerhafter MIME-Interpretation.
|
||||
- Mehr **Datenschutz**, da Browser weniger Referrer-Daten weitergeben.
|
||||
- Änderungen betreffen nur diesen Proxy Host – andere Dienste bleiben unberührt.
|
||||
|
||||
---
|
||||
## Monitoring & Logging
|
||||
|
||||
Die Logs in Nginx Proxy Manager sind eine wertvolle Quelle, um Fehler früh zu erkennen.
|
||||
Im Standard (Free) musst du sie aber manuell durchsuchen – das ist unpraktisch, wenn du mehrere Dienste laufen hast.
|
||||
|
||||
Im Premium-Teil richten wir uns deshalb ein **komfortables Monitoring** ein: Du bekommst automatisch eine tägliche Übersicht, ob alles sauber läuft oder ob Fehler aufgetreten sind.
|
||||
|
||||
### Problem
|
||||
- Logs sind in der Oberfläche zwar sichtbar, aber schnell unübersichtlich.
|
||||
- Zertifikats-Fehler oder nicht erreichbare Container fallen erst auf, wenn man sie zufällig entdeckt.
|
||||
- Ein manuelles Durchsehen kostet jeden Tag Zeit.
|
||||
|
||||
### Lösung
|
||||
Wir erstellen einen **Tagesreport**, den dein UCC automatisch für dich ablegt.
|
||||
Darin siehst du übersichtlich:
|
||||
- wie viele Anfragen erfolgreich waren,
|
||||
- ob Fehler aufgetreten sind (z. B. 502 = Ziel nicht erreichbar),
|
||||
- ob Zertifikate Probleme hatten.
|
||||
|
||||
So erkennst du in Sekunden, ob Handlungsbedarf besteht.
|
||||
|
||||
### Umsetzung Schritt für Schritt
|
||||
|
||||
1. **Reports-Ordner anlegen**
|
||||
- Melde dich auf deinem NPM-LXC an.
|
||||
- Lege einen Ordner für die Tagesberichte an:
|
||||
```bash
|
||||
mkdir -p /srv/ucc/reports
|
||||
```
|
||||
|
||||
2. **Skript für den Tagesreport erstellen**
|
||||
- Öffne eine neue Datei:
|
||||
```bash
|
||||
nano /usr/local/bin/npm_logreport.sh
|
||||
```
|
||||
- Füge folgenden Inhalt ein:
|
||||
```bash
|
||||
#!/bin/bash
|
||||
LOGDIR="/data/logs"
|
||||
REPORT="/srv/ucc/reports/report-$(date '+%Y-%m-%d').txt"
|
||||
|
||||
echo "NPM Logreport - $(date '+%d.%m.%Y %H:%M')" > $REPORT
|
||||
echo "------------------------------------" >> $REPORT
|
||||
echo "Fehler 5xx: $(grep -h -E ' 5[0-9]{2} ' $LOGDIR/*.log | wc -l)" >> $REPORT
|
||||
echo "Fehler 4xx: $(grep -h -E ' 4[0-9]{2} ' $LOGDIR/*.log | wc -l)" >> $REPORT
|
||||
echo "Erfolgreich 2xx: $(grep -h -E ' 2[0-9]{2} ' $LOGDIR/*.log | wc -l)" >> $REPORT
|
||||
```
|
||||
- Datei speichern und ausführbar machen:
|
||||
```bash
|
||||
chmod +x /usr/local/bin/npm_logreport.sh
|
||||
```
|
||||
|
||||
3. **Automatische Ausführung einrichten**
|
||||
- Cronjob öffnen:
|
||||
```bash
|
||||
crontab -e
|
||||
```
|
||||
- Folgende Zeile eintragen, damit das Skript jeden Abend läuft:
|
||||
```
|
||||
0 23 * * * /usr/local/bin/npm_logreport.sh
|
||||
```
|
||||
|
||||
### Überprüfung
|
||||
- Am nächsten Tag findest du im Ordner `/srv/ucc/reports/` eine Datei, z. B. `report-2025-10-03.txt`.
|
||||
- Öffne sie:
|
||||
```bash
|
||||
cat /srv/ucc/reports/report-2025-10-03.txt
|
||||
```
|
||||
- Der Inhalt zeigt dir auf einen Blick die Anzahl erfolgreicher Anfragen und Fehler.
|
||||
|
||||
👉 *Screenshot geeignet: Beispiel-Report im Terminal mit Fehleranzahlen.*
|
||||
|
||||
### Mehrwert
|
||||
- **Kein tägliches Suchen mehr** – du hast eine fertige Übersicht.
|
||||
- **Schnelles Erkennen von Problemen** – 5xx-Fehler springen sofort ins Auge.
|
||||
- **Archiv** – du kannst zurückschauen, ob Fehler regelmäßig auftreten.
|
||||
|
||||
So bekommst du ein schlankes, aber wirkungsvolles Monitoring direkt im UCC – ohne externe Tools oder ständiges Nachsehen in der NPM-GUI.
|
||||
|
||||
Reference in New Issue
Block a user