Nginx-Proxy zum Back-End mit SSL-Client-Zertifikatauthentifizierung

13

Ich habe zwei Server, beide haben Nginx. Server A hört 443 ab und ist für die Authentifizierung mit einem Client-SSL-Zertifikat konfiguriert.

Server B verfügt über einen internen Prozess, der über nginx mit Server A kommunizieren muss.

Ich möchte Nginx auf Server B konfigurieren, das 8080 (keine Verschlüsselung, da alles lokale Kommunikation ist) und proxy_pass an ServerA: 443 abhört.

Die Frage ist, wie ich ein Client-Zertifikat injiziere. Ich habe keine proxy_xxxx-Funktion gefunden, die das tun würde.

Ich weiß, wie man mit socat ein Äquivalent dazu macht, aber meine Anforderung ist, Nginx zu verwenden.

Bastien974
quelle
2
Wenn man sich die Anweisungen im Proxy-Modul von nginx ansieht, scheint es nicht möglich zu sein, einen Nginx-Server dazu zu bringen, ein Zertifikat zur Authentifizierung zu verwenden: nginx.org/en/docs/http/ngx_http_proxy_module.html Apache unterstützt diese Funktion jedoch.
NuTTyX
Davor hatte ich Angst ... eine Idee, ob es ein benutzerdefiniertes Modul gibt oder etwas, das diese Funktion erfüllen kann? Diese Art von Funktion muss existieren!
Bastien974
Ich habe ein Dienstprogramm zum Migrieren von Konfigurationsdateien von Apache nach Nginx gefunden ( github.com/nhnc-nginx/apache2nginx ), also habe ich es heruntergeladen, eine Dummy-Datei apache.conf erstellt und durch das Tool geleitet, aber ich habe dieses Ergebnis erhalten :### Section 2: Unconverted directives ### # Flag Description # [S] Unsupported directives. # In conf file: dummy.conf # Line 32: SSLProxyMachineCertificateFile /path/to/cert (mod_ssl.c) # [S] SSLProxyMachineCertificateFile: No relevant directive in Nginx.
NuTTyX

Antworten:

20

Ist es ausreichend, die Client-Zertifikatdetails durchlaufen zu lassen?

Du kannst hinzufügen

proxy_set_header X-SSL-CERT $ssl_client_escaped_cert;

zu Ihrer Konfiguration und dann stehen die Zertifikatinformationen Server B über einen X-SSL-Cert-Header zur Verfügung.

jwilkins
quelle
1
Wie comented hier bewusst sein , wenn Ihr Backend ersetzen kann \tmit \ndiesem Header einmal readed.
Lucasvc
3
Gemäß der Dokumentation von nginx ist die $ssl_client_certVariable veraltet. Die $ssl_client_escaped_certVariable sollte stattdessen verwendet werden.
Dubek
1
@dubek guter Fang, ich würde die Antwort in solchen Fällen direkt aktualisieren.
Chris Stryczynski
Ich habe diese Lösung ausprobiert, aber sie scheint das Zertifikat nur dann weiterzuleiten, wenn die Zertifikatsüberprüfung aktiviert ist. Ich möchte es nicht einschalten. Gibt es eine Möglichkeit, es zum Laufen zu bringen, ohne die Validierung zu aktivieren?
Juhako
5

Anscheinend ist dies das, wonach Sie suchen: http://nginx.org/en/docs/http/ngx_http_proxy_module.html#proxy_ssl_certificate Verfügbar seit Version 1.7.8.

location / {
    ...
    proxy_pass     the_other_nginx;
    proxy_ssl_certificate  the_certificate.pem;
    ...
}
Nicolas Malbran
quelle
1
Das ist falsch. Dadurch wird dem Proxy ein Client-Zertifikat zugewiesen, das für die Anforderungen an das Backend verwendet werden soll. Aber die Befragten sagten, dass diese Kommunikation nur lokal unverschlüsselt ist, so dass keine Überprüfung des Client-Zertifikats erfolgt. Die Antwort von Jwilkins funktioniert gut.
Kenyakorn Ketsombut
@ KenyakornKetsombut Ich glaube, Sie haben die Frage falsch verstanden. Server B hat keine Verschlüsselung (lauscht auf 8080), muss jedoch mit Server A kommunizieren (lauscht auf 443 mit Verschlüsselung). Daher muss B das Client-Zertifikat zur Authentifizierung an A senden. Sie können dazu proxy_ssl_certificate verwenden. jwilkins antwortet, leitet das an B erteilte Zertifikat an A weiter. Beide können je nach Bedarf funktionieren.
Nicolas Malbran
Hallo Nicolas. Ich habe versucht zu sagen: Wenn Server B keine Verschlüsselung verwendet (auf Port 8080), verwendet er nichts wie HTTPS / SSL oder wie auch immer Sie es nennen. Client-Zertifikate sind Teil von SSL, daher kann dieser Teil nicht von Server B ausgeführt werden. B kann kein Client-Zertifikat senden oder empfangen.
Kenyakorn Ketsombut
1
Ich erhalte nginx: [emerg] no "proxy_ssl_certificate_key" definiert für Zertifikat "certs / Roro_Client.pem" nginx: Konfigurationsdatei /etc/nginx/nginx.conf Test nicht bestanden , wenn ich versuche , diese mit 1.8.0
Wolfgang Fahl
4

Das Problem scheint weitgehend versionabhängig zu sein. Unter Ubuntu 14.04 LTS ist der Standard-Nginx ein veralteter 1.4. Zuerst müssen Sie eine PPA-basierte Version installieren

https://leftshift.io/upgrade-nginx-to-the-latest-version-on-ubuntu-servers

zeigt, wie man das macht mit:

sudo add-apt-repository ppa:nginx/stable
sudo aptitude safe-upgrade

Sie sollten am Ende haben mit:

nginx -v
nginx version: nginx/1.8.0

Die Konfiguration von @ xatr0z Antwort /server//a/636455/162693, die auf http://www.senginx.org/en/index.php/Proxy_HTTPS_Client_Certificate verweist, funktioniert nicht:

nicht funktionierender Vorschlag

backend {
    server some-ip:443;
}

server {
    listen 80;


    location / {
        proxy_ssl_certificate        certs/client.crt;
        proxy_ssl_certificate_key    certs/client.key;


        proxy_pass https://backend;
    }
}

funktioniert nicht sofort mit 1.8.0. Es ist wahrscheinlich nur als Hinweis gedacht und darf nicht als Konfigurationsdatei als solche verwendet werden oder hängt von einer anderen Version ab.

Ich teste mit einem Apache2-basierten Backend-Server A mit aktiviertem SSL und selbstsignierten Client-Zertifikaten. Die Apache-Konfigurations-SSLOptions sind wie folgt festgelegt:

SSLOptions +ExportCertData +FakeBasicAuth + StdEnvVars

Dies erleichtert das Debuggen der Situation, da ein phpinfo () - Skript auf der Backend-Seite die Server- und Client-Seite-Informationen anzeigt.

Um dies zu überprüfen, habe ich verwendet:

https: // backend / test / phpinfo

Wenn das SSL-Zertifikat im Browser installiert ist, erhalte ich folgende Abschnitte: SSL_SERVER_S_DN_CN für das Serverzertifikat und SSL_CLIENT_S_DN_CN für das Clientzertifikat.

Als ersten Start habe ich (füllen Sie die Teile in Klammern aus) verwendet, um nginx auf dem Frontend-Server B zu konfigurieren:

server {
  listen 8080;
  server_name <frontend>;

  location / {
    proxy_buffering off;
    proxy_pass https://<backend>;
    #proxy_ssl_certificate      certs/<SSL Client Certificate>.crt;
    #proxy_ssl_certificate_key  certs/<SSL Client Certificate>.key;
  }
}

Deaktivieren des bestimmten Teils des SSL-Client-Zertifikats, um zu überprüfen, ob der Reverse-Proxy selbst funktioniert.

nginx -t
nginx: the configuration file /etc/nginx/nginx.conf syntax is ok
nginx: configuration file /etc/nginx/nginx.conf test is successful
service nginx restart
nginx stop/waiting
nginx start/running, process 8931

Jetzt funktioniert http: // frontend: 8080 / test / phpinfo.php

SSL_SERVER_S_DN_CN für das Serverzertifikat wird angezeigt und SSL_CLIENT_S_DN_CN für das Clientzertifikat wird (noch) nicht angezeigt

Jetzt nach dem Kommentieren:

server {
  listen 8080;
  server_name <frontend>;

  location / {
    proxy_buffering off;
    proxy_pass https://<backend>;
    proxy_ssl_certificate      certs/<SSL Client Certificate>.crt;
    proxy_ssl_certificate_key  certs/<SSL Client Certificate>.key;
  }
}

und Überprüfen / Neustarten

nginx -t
nginx: the configuration file /etc/nginx/nginx.conf syntax is ok
nginx: configuration file /etc/nginx/nginx.conf test is successful
service nginx restart
nginx stop/waiting
nginx start/running, process 8931

http: // frontend: 8080 / test / phpinfo.php funktioniert und

SSL_SERVER_S_DN_CN für das Serverzertifikat wird angezeigt und SSL_CLIENT_S_DN_CN für das Clientzertifikat wird angezeigt

Jetzt funktionieren die Dinge wie gewünscht.

Bitte beachten Sie den Fehler https://trac.nginx.org/nginx/ticket/872#ticket

Wolfgang Fahl
quelle
Vielleicht möchten Sie auf die Neuverhandlung von ruby-forum.com/topic/6875137 achten, die die Show verderben könnte
Wolfgang Fahl
1

Es gibt einen ziemlich ordentlichen Artikel über Nginx- und SSL-Client-Zertifikate. Es verwendet PHP mit FastCGI als Beispiel, aber ich denke, Sie können dies an ein Reverse-Proxy-Setup anpassen:

server {
    listen        443;
    ssl on;
    server_name example.com;

    ssl_certificate      /etc/nginx/certs/server.crt;
    ssl_certificate_key  /etc/nginx/certs/server.key;
    ssl_client_certificate /etc/nginx/certs/ca.crt;
    ssl_verify_client optional;

    location / {
        root           /var/www/example.com/html;
        fastcgi_pass   127.0.0.1:9000;
        fastcgi_param  SCRIPT_FILENAME /var/www/example.com/lib/Request.class.php;
        fastcgi_param  VERIFIED $ssl_client_verify;
        fastcgi_param  DN $ssl_client_s_dn;
        include        fastcgi_params;
    }
}

Quelle http://nategood.com/client-side-certificate-authentication-in-ngi

Erik Kaplun
quelle