Nginx-Client-SSL-Authentifizierung

8

Ich habe Nginx nur als Proxy für eine Vielzahl von Webservern ausgeführt. Einer unserer Clients hat uns gebeten, Client-Zertifikate zu verwenden, und uns 3 Zertifikate für die 3 verschiedenen Computer bereitgestellt, die eine Verbindung zu einem Webservice herstellen, der auf einem der Proxyserver ausgeführt wird.

Nachdem ich dies noch nie zuvor getan hatte, fand ich die relevanten Nginx-Einstellungen und erstellte eine Site-Konfiguration (relevanter Teil unten).

      server {
        listen                  443 ssl; 
        server_name             service.domain.com;
        ssl_certificate         /etc/nginx/ssl/wildcard/server.crt; 
        ssl_certificate_key     /etc/nginx/ssl/wildcard/server.key; 
        ssl_client_certificate  /etc/nginx/ssl/client.certificates/client_package.cer;
        ssl_verify_client on;

Ich habe die 3 Client-Zertifikate sowie ein von einem Entwickler erstelltes Zertifikat (dieses wurde selbst signiert) verkettet, der während der Entwicklung auf die Site zugreifen musste, in die oben erwähnte einzelne Datei.

Der Client hat nun versucht, auf die Site zuzugreifen, kann dies jedoch nicht. Als Test der Konfiguration habe ich das Entwicklerzertifikat aus der verketteten Zertifikatdatei entfernt und bestätigt, dass er nicht auf die Site zugreifen konnte. Nachdem ich sein Zertifikat wieder in die verkettete Datei eingefügt hatte, konnte er (Entwickler) wieder korrekt auf die Site zugreifen.

Ich habe den Zugriff auf Debug-Ebene im Fehlerprotokoll aktiviert und als der Client versuchte, eine Verbindung herzustellen, wurde der folgende Fehler angezeigt.

2015/08/13 11:57:41 [info] 27601 # 0: * 1963 Client hat während der Verarbeitung von SPDY kein erforderliches SSL-Zertifikat gesendet, Client: 1x.xx.xx.xx, Server: service.domain.com, Anfrage: " GET /test.cfm HTTP / 1.1 ", Host:" service.domain.com "

Wie Sie der obigen Konfiguration entnehmen können, ist SPDY nicht aktiviert (aber auf anderen Websites), und der Client stellt sicher, dass er die Client-Zertifikate sendet. Da dies das erste Mal ist, dass ich dies tue, möchte ich sicherstellen, dass, bevor ich zurückgehe und in meinen Protokollen sage, dass Sie kein Client-Zertifikat senden, alles richtig ist.

In Bezug auf die Zertifikate, die mir zugesandt wurden: Alle 3 sind von derselben öffentlichen Zertifizierungsstelle unterzeichnet. Ich habe jedoch nicht die gesamte Kette in einer verketteten Datei. Welche Guides, die ich online gefunden habe, erwähnen, dass sie auch die Root-Ca haben, aber alle sprechen von selbstsigniert, was keines davon ist. Ich bin mir also nicht sicher, ob das zutrifft.

Zur Verdeutlichung versuche ich auch nicht, das Client-Zertifikat an den Proxyserver zu übergeben.

nginx version: nginx / 1.8.0
openssl version: OpenSSL 1.0.1k 8 Jan 2015

Wenn weitere Informationen benötigt werden, lassen Sie es mich bitte wissen

Drifter104
quelle

Antworten:

1

Ihre Konfiguration ist tatsächlich korrekt. Stellen Sie jedoch sicher, dass Sie KEINE tatsächlichen Client-Zertifikate in die client_package.cerDatei aufnehmen. Diese Datei sollte nur vertrauenswürdige CA-Zertifikate enthalten, tatsächlich sollte sie die gesamte (n) Kette (n) enthalten. Sie sollten alle Stamm- und Zwischenzertifikate von Ihrem Client anfordern, wenn dieser sie nicht bereitgestellt hat.

Es gibt auch einige Fallstricke im Zusammenhang mit dem Standard-Server-Setup. Bitte lesen Sie dies und stellen Sie sicher, dass es Sie nicht betrifft.

dtoubelis
quelle
Also habe ich das client_package.cermit dem CA-Stammzertifikat und den Zwischenzertifikaten aktualisiert , aber ich bekomme immer noch das gleiche Problem. Nun, ich sage den gleichen Fehler, in der Nachricht wird SPDY nicht mehr erwähnt. Um zu bestätigen, dass client_package.cer die Client-Zertifikate nicht mehr enthält
Drifter104
Ich habe eine Konfiguration genau wie Ihre auf einem meiner Server. Stellen Sie sicher , dass Sie auf den Link habe ich gelesen , zur Verfügung gestellt und Sie können auch so etwas wie dieses hinzuzufügen gist.github.com/dtoubelis/2e0813103ec089d6d9f1 zu Ihrem /etc/nginx/sites-available/defaultnur um das Problem zu isolieren.
Dtoubelis
Oh, noch eine Sache. Ich hatte das gleiche Problem, als ich das OCP-Heften aktiviert hatte, aber vergessen hatte, vertrauenswürdige Zertifikate bereitzustellen. Hier ist ein Ausschnitt aus meiner aktuellen Arbeitskonfiguration gist.github.com/dtoubelis/562108c860df32f9b8cc
dtoubelis
... und so können Sie es mit opensslopenssl s_client -servername example.com -connect example.com:443 -key client-cert.key -cert client-cert.crt
dtoubelis
Endlich behoben und das Problem sieht so aus, als ob sich die Zertifizierungsstelle nicht in der ursprünglichen Kette befindet. Ich habe mich darüber gewundert, als ich die Frage gestellt habe, aber ich konnte nichts finden, um sie zu klären.
Drifter104
0

Verwenden Sie die ssl_trusted_certificateDirektive anstelle von ssl_client_certificate. Siehe Dokumente http://nginx.org/en/docs/http/ngx_http_ssl_module.html#ssl_trusted_certificate .

Trotzdem würde ich empfehlen, alle Client-Zertifikate mit ONE ROOT CA zu signieren und zu überprüfen, ob das Client-Zertifikat mit dieser CA signiert ist.

Wenn es Ihr Problem gelöst hat, akzeptieren Sie es bitte als Antwort.

mvorisek
quelle
Vielleicht vermisse ich hier etwas verstanden. Ich habe die Direktive wie vorgeschlagen geändert und dieselbe PEM-Datei verwendet. Ich musste entfernen, ssl_verify_client onweil es mit dieser Direktive nicht gültig ist. Dies ermöglicht nur jedem den Zugriff auf die Site.
Drifter104
Verwenden Sie Caching auf diesem Server? Wenn nein, können Sie ifmit Vertrauen verwenden (andernfalls sind ifstatemens böse) und das Client-Zertifikat mit einer Nginx-Variablen ($ ssl_client_fingerprint, $ ssl_client_raw_cert, ...) überprüfen. Siehe das Ende der Dokumentation nginx.org/en/docs/http/ngx_http_ssl_module.html .
Mvorisek
Diese Antwort ist nicht korrekt, siehe hier nginx.org/en/docs/http/…
dtoubelis
@dtoubelis siehe meine Kommentare, ich benutze nginx oft, wenn es ein Problem gibt und ich es nicht herausfinden kann, protokolliere ich immer alle verwandten Variablen und wenn ich sehe, dass die Variable Produkt korrektes Ergebnis ist, verwende ich einfach ifund das Problem ist gelöst.
Mvorisek
1
@Mvorisek, der einzige Unterschied zwischen ssl_trusted_certificateund ssl_client_sertificatebesteht darin, dass letzteres dazu führt, dass nginx eine Liste akzeptabler Zertifizierungsstellen an den Client sendet (um das Popup im Browser mit Zertifikatauswahlfeld anzuzeigen) und das andere nicht. Menschen wählen aus Datenschutzgründen eine über die andere, aber dies hat nichts mit dem Problem zu tun, das @ Drifter104 hat.
Dtoubelis
-1

SSL-Zertifikate sind Platzhalter oder Single Domain? Möglicherweise versucht der Entwickler, auf die URL der Website zuzugreifen, z. B. test.myapp.com, aber das Zertifikat wird nur für myapp.com oder www.myapp.com ausgestellt

x86fantini
quelle
Das Problem liegt nicht beim Entwickler. Er verwendet die gleiche URL und seine Arbeiten funktionieren
einwandfrei