it-swarm.com.de

nginx-Weiterleitung zum Docker-Container

bevor ich meine Ausgabe poste, möchte ich wissen, ob es überhaupt möglich ist, das zu erreichen, was ich will.

Ich habe, sagen wir mal, myserver.com einen Docker-Container mit nginx & letsencrypt. Auf demselben Server befinden sich zwei weitere Docker-Container, auf denen Websites ausgeführt werden.

Im Moment wird alles in Ordnung umgeleitet, also wechselt www.myserver.com zu Docker 1 und site2.myserver.com zu Docker 2.

Ich möchte, dass die gesamte Kommunikation über HTTPS läuft, aber hier beginnt das Problem. Meine Frage ist also: Kann der Docker mit nginx und letsencrypt mit den Zertifikaten von letsencrypt eine Verbindung zu einem anderen Docker herstellen? Für mich scheint es eine Art Man-in-the-Middle-Attacke zu sein. Ein bisschen schematischer:

Navigieren Sie zu http: // site2.myserver.com -> nginx leitet zu https: // site2.myserver.com um -> stellen Sie über Port 80 eine Verbindung zu Container 2 (192.168.0.10) her. Oder eine andere Option: Navigieren Sie zu http: // site2.myserver.com -> Nginx leitet auf https://site2.myserver.com um -> Verbindung zu Container 2 (192.168.0.10) auf Port 443 mit den site2.myserver.com-Zertifikaten herstellen.

Wenn es nicht geht, was ist dann die Lösung? Kopieren der Zertifikate in die Docker-Container und Ausführen von https, sodass eine http-Anforderung an den https-Port dieses Containers umgeleitet wird?

Navigieren Sie zu http: // site2.myserver.com -> Nginx-Weiterleitungsanforderung -> Stellen Sie eine Verbindung zu Container 2 (192.168.0.10) auf Port 443 her, der über die site2.myserver.com-Zertifikate verfügt.

Danke, Greggy

4
Greggy

Soweit ich weiß, befindet sich Ihr Nginx-Reverse-Proxy im selben Netzwerk wie die Container. Daher muss die Verbindung zwischen ihnen nicht unbedingt mit TLS gesichert werden (da dies ein privates Netzwerk ist und ein Angreifer Zugriff auf dieses Netzwerk hat) Zugriff auf den Server und alle unverschlüsselten Daten).

Wenn Sie unbedingt gültige Zertifikate zum Sichern der Verbindungen in Ihrem lokalen Netzwerk benötigen, können Sie zusätzliche Unterdomänen erstellen, die in die lokalen IPs aufgelöst werden. Dann müssen Sie die manuelle DNS-Option verwenden, um Ihr Zertifikat zu erhalten (dies ist eine Certbot-Option, bei der Sie einen Schlüssel als TXT -Eintrag für Ihre Domain manuell eingeben müssen).

Beispiel einer Nginx-Konfiguration zum Umleiten von http zu https

server {
    listen 80;

    server_name example.com;
    return 301 https://example.com/;
}
server{
    listen 443 ssl http2;

    server_name  example.com;

    ssl_certificate /etc/letsencrypt/live/example.com/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/example.com/privkey.pem;
    ssl_trusted_certificate /etc/letsencrypt/live/example.com/fullchain.pem;

    location / {
        proxy_pass http://container:8080/;
        proxy_set_header Host $Host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto $scheme;
    }

    include tls.conf;
}
5
Paul Trehiou

Hier ist mein Weg, das zu tun:

NGINX-Konfigurationsdatei (default.conf)

Mit dem Docker-Image von https://github.com/KyleAMathews/docker-nginx habe ich die benutzerdefinierte Standarddatei wie folgt erstellt:

server {
    root /var/www;
    index index.html index.htm;

    server_name localhost MYHOST.COM;

    # Add 1 week expires header for static assets
    location ~* \.(js|css|png|jpg|jpeg|gif|ico)$ {
        expires 1w;
    }

    location / {
        # First attempt to serve request as file, then
        # as directory, then fall back to redirecting to index.html
        try_files $uri $uri/ @root;

        return 301 https://$Host$request_uri;
    }

    # If nginx can't find a file, fallback to the homepage.
    location @root {
        rewrite .* / redirect;
    }

    include /etc/nginx/basic.conf;
}

Dockerfile

Hier ist meine Docker-Datei, wenn man bedenkt, dass sich mein statischer Inhalt unter html/directory befindet.

COPY conf/default.conf /etc/nginx/sites-enabled/default

ADD certs/myhost.com.crt /etc/nginx/ssl/server.crt
ADD certs/myhost.com.key /etc/nginx/ssl/server.key
RUN ln -s /etc/nginx/sites-available/default-ssl /etc/nginx/sites-enabled/default-ssl

COPY html/ /var/www

CMD 'nginx'

Testen

Ändern Sie für einen lokalen Test die Datei/etc/hosts, indem Sie myhost.com zu 127.0.0.1 hinzufügen und den folgenden Befehl ausführen:

locken -I http://www.myhost.com/

Ergebnis

HTTP/1.1 301 Moved Permanently
Server: nginx
Date: Sun, 04 Mar 2018 04:32:04 GMT
Content-Type: text/html
Content-Length: 178
Connection: keep-alive
Location: https://www.myhost.com/
X-UA-Compatible: IE=Edge

Ich würde mit der Out-of-the-Box-Lösung gehen:

JWilder Nginx + Lets Encrypt.

Zuerst starten wir NGINX Container als Reverse Proxy:

docker run -d -p 80:80 -p 443:443 \
    --name nginx-proxy \
    -v /path/to/certs:/etc/nginx/certs:ro \
    -v /etc/nginx/vhost.d \
    -v /usr/share/nginx/html \
    -v /var/run/docker.sock:/tmp/docker.sock:ro \
    jwilder/nginx-proxy

Als nächstes starten wir den Lets Encrypt Container:

docker run -d \
-v /path/to/certs:/etc/nginx/certs:rw \
--volumes-from nginx-proxy \
-v /var/run/docker.sock:/var/run/docker.sock:ro \
jrcs/letsencrypt-nginx-proxy-companion

Für Ihre Websites müssen einige Umgebungsvariablen festgelegt werden:

docker run -d \
--name website1 \
-e "VIRTUAL_Host=website1.com" \
-e "LETSENCRYPT_Host=website1.com" \
-e "[email protected]" \
tutum/Apache-php

Der Nginx-Container erstellt einen neuen Eintrag in seiner Konfiguration, und der lets encrypt-Container fordert ein Zertifikat an (und führt die Erneuerung durch).

Mehr: Nginx + LetsEncrypt

1
opHASnoNAME

Gut, ich konnte endlich das bekommen, was ich wollte, indem ich die Antworten von opHASnoNAME und Paul Trehiou zusammenführte. Was ich als Extra für die Antwort von opHASnoNAME getan habe, ist, ein Dateisystem zwischen dem Docker nginx und letsencrypt zu mounten. Es ermöglicht die Verknüpfung der Konfigurationsdateien von nginx mit den richtigen Zertifikaten (siehe später).

Das habe ich gemacht:

docker run --name nginx-prod --restart always -d -p 80:80 -p 443:443 -v /choose/your/dir/letsencrypt:/etc/nginx/certs:ro -v /etc/nginx/vhost.d -v /usr/share/nginx/html -v /var/run/docker.sock:/tmp/docker.sock:ro -e DEFAULT_Host=myserver.com jwilder/nginx-proxy

docker run --name letsencrypt --restart always -d -v /choose/your/dir/letsencrypt:/etc/nginx/certs:rw --volumes-from nginx-prod -v /var/run/docker.sock:/var/run/docker.sock:ro jrcs/letsencrypt-nginx-proxy-companion

Führen Sie dann einen beliebigen Container mit einem Webserver aus. Die LETSENCRYPT-Variablen müssen nicht gesetzt werden. Meine aktuellen Container sind erreichbar, ohne sie einzustellen.

Der jwilder/nginx-Proxy listet alle laufenden Container in /etc/nginx/conf.d/default.conf auf. Fügen Sie dieser Datei nichts hinzu, da diese beim nächsten Neustart überschrieben wird. Erstellen Sie für jeden Webserver eine neue .conf-Datei im selben Verzeichnis. Diese Datei enthält die von Paul Trehiou vorgeschlagenen https-Informationen. Ich habe zum Beispiel site2.conf erstellt:

server{
    listen 443 ssl http2;
    server_name  site2.myserver.com;
    ssl_certificate /etc/nginx/certs/live/myserver.com/fullchain.pem;
    ssl_certificate_key /etc/nginx/certs/live/myserver.com/privkey.pem;
    ssl_trusted_certificate /etc/nginx/certs/live/myserver.com/fullchain.pem;

    location / {
        proxy_pass http://192.168.0.10/;
        proxy_set_header Host $Host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto $scheme;
    }
}

Die proxy_pass-Adresse können Sie der Datei default.conf entnehmen. Die IP-Adressen werden dort für jeden Container aufgelistet. Um diese .conf-Dateien sichern zu können, erstelle ich meinen Nginx-Container neu und mounte ein lokales Dateisystem in /etc/nginx/conf.d. Es erleichtert auch das Leben, wenn der Container aufgrund eines Fehlers in den .conf-Dateien nicht gestartet wird.

Vielen Dank an alle für eure Beiträge, das Puzzle ist jetzt komplett ;-)

0
Greggy