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!
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:
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