Proxy für den Websocket WQHD Videostream

Q: Ich habe eine 9008 und 9408 in Betrieb. Bei der 9008 konnte ich schon immer via Apache Proxy den MJPG Stream mit einer beliebigen Domain versehen. Ist es generell nicht mehr möglich den Stream über via Proxy zu nutzen?

A: Sie können die folgende NGINX-Proxy-Konfiguration verwenden, um den Videostream Ihrer Kameras sicher zum Internet durchzuleiten. Beginnen Sie mit dem Herunterladen oder Klonen des Repositorys:

git clone https://github.com/mpolinowski/docker_ws_video_proxy.git

NGINX Konfiguration

Die wichtigsten Dateien in diesem Repository sind:

.
├── certs
│   ├── nginx-selfsigned.crt
│   └── nginx-selfsigned.key
├── conf.d
│   ├── mjpeg-proxy.conf
│   ├── ws-proxy.conf
│   └── wss-proxy.conf
├── nginx.conf

TLS Zertifikate

Beachten Sie, dass das Repository ein selbstsigniertes TLS-Zertifikat und einen Schlüssel enthält. Dieses kann zum Testen verwendet werden - oder erzeugen Sie einfach ein neues mit dem OpenSSL CLI-Tool:

cd docker_ws_video_proxy/certs
openssl req -new -newkey rsa:4096 -x509 -sha256 -days 365 -nodes -out nginx-selfsigned.crt -keyout nginx-selfsigned.key

Beachten Sie aber auch, dass Google Chrome ein selbstsigniertes Zertifikat für Websocket-Verbindungen ablehnt. Sie müssen sie durch von einer Zertifizierungsstelle signierte Zertifikate ersetzen, wenn Sie eine sichere Verbindung herstellen wollen.

NGINX Hauptkonfiguration

Die wichtigste Konfigurationsdatei für den NGINX-Proxy ist nginx.conf. Hier können Sie wählen, welche Art von Proxy Sie einrichten möchten - kommentieren Sie hier alle Konfigurationsdateien aus, die Sie nicht verwenden möchten:

docker_ws_video_proxy/nginx.conf

# MJPEG proxy
include /etc/nginx/conf.d/mjpeg-proxy.conf;
# Secure MJPEG proxy
# include /etc/nginx/conf.d/mjpeg-secure-proxy.conf;
# Websocket proxy
# include /etc/nginx/conf.d/ws-proxy.conf;
# Secure websocket proxy
# include /etc/nginx/conf.d/wss-proxy.conf;

Server Konfiguration

Als nächstes folgen die Serverkonfigurationsdateien selbst - zum Beispiel der MJPEG Proxy-Server:

docker_ws_video_proxy/conf.d/mjpeg-proxy.conf

Hier ist der "Upstream"-Host immer die lokale IP-Adresse oder der Domänenname Ihrer IP-Kamera, gefolgt von dem HTTP-Port - z.B. "192.168.2.120:80":

upstream mjpeghost {
    # IP and http port of your camera
    server 192.168.2.120:80;
}

Mit dem Server Block können Sie den Port festlegen, auf dem NGINX das Video Ihrer Kamera streamen soll, z. B. 8888. Der "Server-Name" ist die IP-Adresse oder der Domain-Name des NGINX-Host-Systems. In dem Beispiel unten streame ich das Video zu localhost - auf diese Weise ist es nur auf dem NGINX-Host selbst unter der Adresse http://127.0.0.1:8888 zugänglich. Und schließlich gibt es noch den proxy_pass, mit dem Sie die MJPEG-URL nach Ihren Bedürfnissen anpassen können. Das Beispiel verwendet den Stream "13", der am kleinsten ist. Ändern Sie ihn bei Bedarf in /12 oder /11. Und natürlich müssen Sie Ihren eigenen Benutzernamen und Ihr Passwort hinzufügen:

server {
    listen 8888;

    # IP of your proxy server or localhost
    server_name 127.0.0.1;

    location    / {
        proxy_pass http://mjpeghost/livestream/13?action=play&media=mjpeg&user=admin&pwd=instar;
        proxy_http_version 1.1;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection "upgrade";
        proxy_set_header Host $host:$server_port;
        proxy_set_header X-Forwarded-Proto $scheme;
        proxy_set_header X-Forwarded-For $remote_addr;
        proxy_set_header X-Forwarded-Port $server_port;
        proxy_set_header X-Request-Start $msec;
    }
}

Ausführen des MJPEG-Proxys

Verwenden Sie einen Volume-Mount in den NGINX-Container, um die Standardkonfiguration zu überschreiben. Stellen Sie sicher, dass /path/to/docker_ws_video_proxy auf das heruntergeladene Repository zeigt:

docker run --rm --network host -v /path/to/docker_ws_video_proxy:/etc/nginx --name proxy nginx:alpine

Dadurch wird der an Ihr Terminal angehängte Container ausgeführt und beim Beenden des Containers zerstört. Der NGINX-Proxy ist so konfiguriert, dass er seine Protokolle an STDOUT sendet - Sie werden also alle Zugriffsversuche und Fehlermeldungen in Ihrem Terminal sehen. Sie können den Container auch losgelöst von Ihrer Konsole ausführen:

docker run -d --network host -v /path/to/docker_ws_video_proxy:/etc/nginx --name proxy nginx:alpine

Um zu testen, ob es funktioniert, öffnen Sie einen Browser auf Ihrem Host-Rechner und besuchen Sie http://127.0.0.1:8888 - Sie sollten den MJPEG-Stream Ihrer Kamera sehen können - ohne dass Sie sich anmelden müssen. Dies ist eine viel sicherere Methode, das Video Ihrer Kamera auf einer öffentlichen Webseite zu veröffentlichen, da der Benutzer, der auf diesen Stream zugreift, nicht in der Lage ist, die Anmeldedaten zu sehen oder CGI-Befehle an Ihre Kamera zu senden.

Sicherer MJPEG Proxy

Nachdem wir nun den einfachen MJPEG-Streaming-Proxy eingerichtet und zum Laufen gebracht haben, wollen wir ihn etwas komplizierter machen, indem wir TLS-Verschlüsselung hinzufügen. Wie oben erwähnt, enthält das Repository ein selbstsigniertes TLS-Zertifikat und einen Schlüssel. Ersetzen Sie diese durch Ihre eigenen - oder noch besser - besorgen Sie sich ein von einer CA signiertes Zertifikat, z. B. von Let's Encrypt.

Die Änderungen, die wir an der NGINX-Konfiguration vornehmen müssen, sind recht einfach. Beginnen Sie mit der Auswahl der richtigen Konfigurationsdatei:

docker_ws_video_proxy/nginx.conf

# MJPEG proxy
# include /etc/nginx/conf.d/mjpeg-proxy.conf;
# Secure MJPEG proxy
include /etc/nginx/conf.d/mjpeg-secure-proxy.conf;
# Websocket proxy
# include /etc/nginx/conf.d/ws-proxy.conf;
# Secure websocket proxy
# include /etc/nginx/conf.d/wss-proxy.conf;

Öffnen Sie nun die Konfigurationsdatei und fügen Sie Ihre Informationen hinzu - genau wie in dem einfachen MJPEG-Beispiel oben - aber beachten Sie, dass der Server Block nun die Zertifikats- und Schlüsseldatei enthält (die Sie durch Ihre eigene ersetzen sollten - aber das mitgelieferte Zertifikat wird zum Testen funktionieren):

# your SSL configuration
# ssl_certificate /opt/letsencrypt/live/my.domain.com/fullchain.pem;
# ssl_certificate_key /opt/letsencrypt/live/my.domain.com/privkey.pem;
ssl_certificate /etc/nginx/certs/nginx-selfsigned.crt; # Replace with the 2 lines above when using CA Cert
ssl_certificate_key /etc/nginx/certs/nginx-selfsigned.key;

Stoppen Sie nun den NGINX-Container - falls er noch läuft - und starten Sie ihn neu:

docker run --rm --network host -v /path/to/docker_ws_video_proxy:/etc/nginx --name proxy nginx:alpine

Jetzt müssen Sie HTTPS verwenden, um auf das Live-Video Ihrer Kamera https://127.0.0.1:8888/ zuzugreifen. Wenn Sie ein selbstsigniertes Zertifikat verwenden, wird Ihr Browser Sie darüber warnen - klicken Sie einfach auf "Akzeptieren".

Websocket Proxy

Sowohl die grundlegende als auch die sichere Websocket-Proxy-Konfiguration sind weitgehend identisch mit den obigen Beispielen. Sie sollten also keine Probleme mehr haben, die Konfigurationsdateien zu bearbeiten.

Für den Zugriff auf den Websocket-Videostream benötigen Sie jedoch einen Websocket-Client - wie den hier bereitgestellten:

Diesen können Sie in Ihre Webseite einbetten und darüber den Stream von Ihrem NGINX Proxy entgegennehmen:

Wie bereits im Abschnitt TLS erwähnt, akzeptiert Ihr Browser keine Websocket-Verbindung (wss) mit einem selbstsignierten Zertifikat. Sie müssen ein Tool wie certbot verwenden, um ein von einer Zertifizierungsstelle signiertes Zertifikat und einen Schlüssel für Ihren Proxy zu generieren, damit er mit dem sicheren Websocket-Stream Ihrer Kamera arbeiten kann.