HTTPS ueber die blanke IP: Standard-Server statt abgelehntem Handshake
https://<IP>/cmk/ endete im Browser mit ERR_SSL_UNRECOGNIZED_NAME_ALERT, waehrend dieselbe Adresse ueber http funktionierte. Die Ursache liegt nicht beim Zertifikat: RFC 6066 laesst in der SNI-Erweiterung keine IP-Adressen zu, der Browser schickt bei einer IP also gar keinen Namen. nginx kann den Server-Block dann nicht ueber den Namen waehlen und faellt auf den Standard-Server zurueck - bei NPM ist das der Block aus /etc/nginx/conf.d/default.conf mit "ssl_reject_handshake on". Ueber HTTP faellt das nicht auf, dort entscheidet der Host-Kopf, und der traegt die IP. Nachgeprueft am Image jc21/nginx-proxy-manager:2 (2.15.1): der Block steht dort in Zeile 36, und nginx.conf liest conf.d/*.conf vor den Proxy-Hosts ein - damit wird er zum Standard-Server, obwohl keiner der Bloecke "default_server" gesetzt hat. Mit einem eigenen Block, der das Kennzeichen ausdruecklich traegt, ist der Fall entschieden; Aufrufe mit Namen gehen unveraendert an ihren Proxy-Host. Neu ist "proxy default": proxy default Stand anzeigen proxy default --domain X Proxy-Host X spiegeln proxy default --off Spiegelung entfernen --restart Proxy Manager gleich neu starten Gespiegelt wird ueber die API: Ziel, Zertifikat und die zusaetzlichen Pfade des Proxy-Hosts landen in einem Standard-Server-Block in der Zusatzkonfiguration. Fuehrt das Zertifikat die IP nicht als Alternativnamen, sagt der Befehl das vorher - bei Lets Encrypt geht es prinzipbedingt nicht. Dabei aufgefallen: die Zusatzkonfiguration liegt im Datenverzeichnis des Proxy Managers und gehoert dem Container. Ohne Schreibrecht scheiterte bisher nur ein nacktes "touch" - jetzt sagt npm_conf_writable, woran es liegt, und nennt den sudo-Aufruf. Das gilt auch fuer "npm-port". Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -1224,6 +1224,8 @@ erzwingen, HTTP/2 und Websockets einschalten und den empfohlenen
|
||||
| `proxy add …` | Proxy-Host anlegen (`--update` ersetzt einen vorhandenen) |
|
||||
| `proxy show --domain X` | Einzelheiten samt zusätzlicher Pfade |
|
||||
| `proxy del --id N` | Proxy-Host löschen |
|
||||
| `proxy default --domain X` | HTTPS über die blanke IP ermöglichen (spiegelt X in einen Standard-Server) |
|
||||
| `proxy default --off` | diese Spiegelung wieder entfernen |
|
||||
|
||||
Optionen von `proxy add`:
|
||||
|
||||
@@ -1459,6 +1461,68 @@ Einbinden:
|
||||
Die ncurses-Oberfläche bietet denselben Ablauf unter *„Selbstsigniertes
|
||||
Zertifikat erzeugen“*.
|
||||
|
||||
### 10.8 HTTPS über die blanke IP
|
||||
|
||||
Ruft man den Server als `https://172.0.250.82/cmk/` auf, endet das im Browser
|
||||
mit **`ERR_SSL_UNRECOGNIZED_NAME_ALERT`** – über `http://` funktioniert
|
||||
dieselbe Adresse. Das liegt nicht am Zertifikat.
|
||||
|
||||
Der Grund steckt in TLS: Der Browser teilt dem Server beim Verbindungsaufbau
|
||||
mit, welchen Namen er sprechen will (*SNI*). Laut RFC 6066 dürfen dort **keine
|
||||
IP-Adressen** stehen, also sendet der Browser bei einer IP gar nichts. nginx
|
||||
kann den passenden Server-Block dann nicht über den Namen auswählen und fällt
|
||||
auf seinen Standard-Server zurück. Bei NPM ist das dieser Block aus
|
||||
`/etc/nginx/conf.d/default.conf`:
|
||||
|
||||
```nginx
|
||||
server {
|
||||
listen 443 ssl;
|
||||
server_name localhost;
|
||||
ssl_reject_handshake on; # <- genau das meldet der Browser
|
||||
return 444;
|
||||
}
|
||||
```
|
||||
|
||||
Über HTTP fällt es nicht auf, weil nginx den Server-Block dort am `Host`-Kopf
|
||||
erkennt – und der trägt die IP.
|
||||
|
||||
Abhilfe ist ein eigener Standard-Server, der diese namenlosen Aufrufe annimmt:
|
||||
|
||||
```bash
|
||||
sudo ./scripts/cmk-manage.sh proxy default --domain checkmk.example.local --restart
|
||||
```
|
||||
|
||||
Der Befehl liest den genannten Proxy-Host über die API aus und spiegelt ihn –
|
||||
Ziel, Zertifikat und **alle zusätzlichen Pfade** – in einen Block mit
|
||||
`default_server`, der in die Zusatzkonfiguration geschrieben wird. Aufrufe mit
|
||||
Namen bleiben unberührt: nginx wählt weiterhin zuerst nach SNI aus, der
|
||||
Standard-Server greift nur, wenn kein Name passt. Keiner der von NPM erzeugten
|
||||
Blöcke setzt `default_server` selbst, deshalb gibt es darum keinen Streit.
|
||||
|
||||
| Befehl | Wirkung |
|
||||
|---|---|
|
||||
| `proxy default` | zeigt, ob eingerichtet, und welchen Proxy-Host es spiegelt |
|
||||
| `proxy default --domain X` | Proxy-Host `X` spiegeln |
|
||||
| `proxy default --off` | Spiegelung entfernen |
|
||||
| `--restart` | den Proxy Manager gleich neu starten |
|
||||
|
||||
In der Oberfläche liegt das unter **Proxy-Hosts → HTTPS über die blanke IP
|
||||
(ohne Namen) ermöglichen**.
|
||||
|
||||
Zwei Dinge sind zu beachten:
|
||||
|
||||
- Das **Zertifikat muss die IP als Alternativnamen führen**, sonst meldet der
|
||||
Browser einen Namensfehler (anklickbar, aber unschön). `cmk-manage.sh cert`
|
||||
und `proxy add --cert self` tragen die IP des Hosts von sich aus ein; bei
|
||||
einem Let's-Encrypt-Zertifikat geht das prinzipbedingt nicht – dafür gibt es
|
||||
keine Zertifikate auf IP-Adressen. Der Befehl prüft das und sagt es.
|
||||
- Die Zusatzkonfiguration liegt im Datenverzeichnis des Proxy Managers, und das
|
||||
gehört dem Container. Deshalb **mit `sudo`** aufrufen.
|
||||
|
||||
Die saubere Alternative bleibt ein Name: ein DNS-Eintrag oder eine Zeile in der
|
||||
`hosts`-Datei der Clients genügt, damit der Browser SNI sendet und der
|
||||
Proxy-Host ganz normal greift.
|
||||
|
||||
---
|
||||
|
||||
## 11. Proxy Manager lokal einrichten (Terminal-Browser)
|
||||
@@ -2628,6 +2692,7 @@ Checkmk-Werksnotizen (Werks/Release Notes) lesen.
|
||||
|
||||
| Symptom | Ursache / Lösung |
|
||||
|---|---|
|
||||
| `ERR_SSL_UNRECOGNIZED_NAME_ALERT` beim Aufruf über `https://<IP>/` | Der Browser sendet bei einer IP kein SNI, nginx fällt auf seinen Standard-Server zurück und lehnt ab. `cmk-manage.sh proxy default --domain <name>` – siehe [Kapitel 10.8](#108-https-über-die-blanke-ip) |
|
||||
| `Port 80/443 already in use` | Auf dem Host läuft bereits ein Webserver: `ss -tlnp \| grep ':80'` → `systemctl disable --now apache2 nginx httpd` |
|
||||
| Nach Reboot laufen die Container nicht (Podman) | systemd-Unit fehlt: `./install.sh --with-systemd` bzw. `--quadlet`, danach `systemctl is-enabled checkmk-stack` |
|
||||
| `omd restore`: *version is not installed* | passendes Image holen: `cmk-manage.sh image pull --edition <ed> --version <v>`, dann `up` |
|
||||
|
||||
Reference in New Issue
Block a user