fragen stichworte

Nginx Reverse Proxy-Client-Zertifikat durchlaufen

Ich versuche, einen Load Balancer über einen Nginx-Reverse-Proxy einzurichten. Meine Anwendung verwendet Client-Zertifikate zur Authentifizierung von Clients. Ich möchte, dass mein Reverse Proxy das Client-Zertifikat an meine Back-End-Server weiterleitet. Ich habe diese Zeile der Konfiguration meines Reverse-Proxys hinzugefügt, um die Client-Zertifikatinformationen in einem benutzerdefinierten HTTP-Header zu speichern:

proxy_set_header X-SSL-CERT $ssl_client_cert

$ssl_client_cert verwendet jedoch mehrere Zeilen zum Speichern des Zertifikats, und mein Back-End-Nginx-Server erkennt dies nicht ordnungsgemäß als einen HTTP-Header. Wie kann ich meine Client-Zertifikate am besten weiterleiten?

Diese Frage wurde 2013 in diesem Forum gestellt, aber bisher keine echte Lösung: https://forum.nginx.org/read.php?2,236546,236546

Danke!

antworten

Ich habe also eine Lösung gefunden. Ich entferne alle Zeilenumbrüche im Zertifikat und sende sie als einen einzelnen HTTP-Header vom Proxy zum Back-End, ähnlich wie hier erklärt:

https://forum.nginx.org/read.php?2,236546,236546

In meinem Backend rekonstruiere ich das Zertifikat, indem ich alle 64 Zeichen eine neue Zeile hinzufüge. Der aktualisierte Code für den Reverse-Proxy ist der folgende und funktioniert bis zu 26 Zeilen:

map $ssl_client_raw_cert $a {
   "~^(-.*-\\n)(?<st>[^\\n]+)\\n((?<b>[^\\n]+)\\n)?((?<c>[^\\n]+)\\n)?((?<d>[^\\n]+)\\n)?((?<e>[^\\n]+)\\n)?((?<f>[^\\n]+)\\n)?((?<g>[^\\n]+)\\n)?((?<h>[^\\n]+)\\n)?((?<i>[^\\n]+)\\n)?((?<j>[^\\n]+)\\n)?((?<k>[^\\n]+)\\n)?((?<l>[^\\n]+)\\n)?((?<m>[^\\n]+)\\n)?((?<n>[^\\n]+)\\n)?((?<o>[^\\n]+)\\n)?((?<p>[^\\n]+)\\n)?((?<q>[^\\n]+)\\n)?((?<r>[^\\n]+)\\n)?((?<s>[^\\n]+)\\n)?((?<t>[^\\n]+)\\n)?((?<v>[^\\n]+)\\n)?((?<u>[^\\n]+)\\n)?((?<w>[^\\n]+)\\n)?((?<x>[^\\n]+)\\n)?((?<y>[^\\n]+)\\n)?((?<z>[^\\n]+)\\n)?(-.*-)$" $st;
}

server {
   location/{
      proxy_set_header X-cert $a$b$c$d$e$f$g$h$i$j$k$l$m$n$o$p$q$r$s$t$v$u$w$x$y$z;
      proxy_pass http://localhost:8000;
   }
}

(Beachten Sie, dass ich die Variable, beginnend mit einer Zahl, entfernt habe.) Obwohl diese Lösung nicht ideal ist, funktioniert sie in diesem Moment für mich. Eine andere Lösung wäre, nur die DN-Information des Zertifikats zu senden, die eine einzelne Zeile ist. Dies funktioniert derzeit nicht für mich, da ich nicht jeden DN in meiner Datenbank gespeichert habe.

Es sieht so aus, als ob neuere Versionen von nginx alle \\n auf \\t für Sie in der Variable $ssl_client_cert ändern. Die Variable $ssl_client_raw_cert steht zur Verfügung, wenn diese Transformation nicht angewendet werden soll.

Siehe: http://nginx.org/en/docs/http/ngx_http_ssl_module.html#variables

Ich sehe 2 Lösungen hier:

  1. Aktivieren Sie LUA-Skripting und formatieren Sie die Zeichenfolge in einem Format ohne End-of-Line.
  2. Verwenden Sie das Set Misc Plugin und verwenden Sie base64_encode für diese Variable.

Hier ist die LUA-Lösung, die für mich funktioniert hat:

set_by_lua $client_cert "return ngx.var.ssl_client_raw_cert and ngx.var.ssl_client_raw_cert:gsub('\\\\n',' ') or nil";
proxy_set_header X-SSL-CERT $client_cert;

Wenn Sie Ubuntu verwenden, hat nginx-extra standardmäßig ein LUA-Plugin, so dass keine zusätzliche Konfiguration erforderlich ist:  https://stackoverflow.com/questions/22193852/running-lua-in-nginx-config