it-swarm.com.de

Nginx Reverse Proxy für Heroku schlägt fehl, SSL-Handshake

Ich bin leider kein großer Systemadministrator und bin auf ein Problem gestoßen, das mich mit dem Kopf gegen die Wand schlagen lässt.

Die Kurzgeschichte ist, dass ich Nginx auf EC2 (Ubuntu 14.04.4 LTS) verwende, um (a) die Marketing-Site meines Unternehmens zu hosten ( https://example.com , die übrigens Wordpress ist) und (b) dient als Reverse-Proxy für unsere Rails-App, die auf Heroku (https://app.example.com) für bestimmte Pfade ausgeführt wird. Wir verwenden dasselbe SSL-Zertifikat für example.com und app.example.com. All das hat 8-10 Monate gut funktioniert, aber ich habe vor kurzem von Herokus kostenpflichtigem SSL-Addon auf das neue kostenlose SSL-Angebot umgestellt, und jetzt ist unser Reverse-Proxy defekt.

Beim Überprüfen der Nginx-Fehlerprotokolle sehe ich Folgendes:

SSL_do_handshake () ist fehlgeschlagen (SSL: Fehler: 14094438: SSL Routinen: SSL3_READ_BYTES: tlsv1-Warnungsinterner Fehler: SSL-Warnungsnummer 80) während des SSL-Handshakes zum Upstream, Client: ipaddress1, server: example.com, Anforderung: "GET/proxiedpath/proxiedpage HTTP/1.1", Upstream: "https: // ipaddress2: 443/proxiedpath/proxiedpage", Host: "Beispiel .com "

Ich habe versucht, nach zusätzlichen Hinweisen zu suchen - ich habe Nginx (1.10.1) und OpenSSL (1.0.2h) ohne Erfolg aktualisiert. Ich hatte den Verdacht, dass das Problem möglicherweise auf die Verwendung von SNI durch Heroku in der neuen kostenlosen SSL-Funktion ( https://devcenter.heroku.com/articles/ssl-beta ) zurückzuführen ist, konnte jedoch nicht feststellen, warum dies der Fall war könnte ein problem sein.

Einige zusätzliche Punkte zu meiner Erkundung bis zu diesem Punkt:

  • Als ich auf das neue kostenlose Heroku-SSL umgestiegen bin, habe ich unseren app.example.com-DNS-Eintrag so geändert, dass er auf app.example.com.herokudns.com verweist, wie in den Dokumenten angegeben. Auf die Anwendung kann normalerweise über app.example.com zugegriffen werden. Wenn ich nslookup auf app.example.com und app.example.com.herokudns.com ausführte, erhalte ich dieselbe IP-Adresse zurück. Jedoch...

  • Ich kann nicht über die von nslookup oder app.example.com.herokudns.com zurückgegebene IP-Adresse auf die Anwendung zugreifen. Ich vermute, das ist normal und erwartet, weiß aber nicht genug, um genau zu sagen, warum das so ist. Und...

  • Die vom nslookup zurückgegebene IP-Adresse stimmt NICHT mit der IP-Adresse überein, auf die in der obigen Fehlermeldung des Protokolls verwiesen wird ("ipaddress2"). Tatsächlich ist "ipaddress2" in den Protokollen nicht konsistent - es scheint sich regelmäßig zu ändern. Wieder weiß ich nicht genug, um zu wissen, was ich nicht weiß ... Lastverteilung auf Herokus Seite?

Schließlich ist mein Nginx-Reverse-Proxy in der nginx.conf wie folgt konfiguriert:

http {

    client_max_body_size 500M;

    sendfile on;
    tcp_nopush on;
    tcp_nodelay on;
    keepalive_timeout 65;
    types_hash_max_size 2048;

    server_names_hash_bucket_size 64;

    include /etc/nginx/mime.types;
    default_type application/octet-stream;

    access_log /var/log/nginx/access.log;
    error_log /var/log/nginx/error.log;

    gzip on;
    gzip_disable "msie6";

    server {

        listen 443 default_server;
        server_name example.com;

        root /usr/share/nginx/html;
        index index.php index.html index.htm;

        ssl on;
        ssl_certificate mycompanycert.crt;
        ssl_certificate_key mycompanykey.key;

        ssl_session_timeout 5m;

        ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
        ssl_ciphers "HIGH:!aNULL:!MD5 or HIGH:!aNULL:!MD5:!3DES";
        ssl_prefer_server_ciphers on;

        error_page 404 /404.html;
        error_page 500 502 503 504 /50x.html;

        location / {
            try_files $uri $uri/ /index.php?q=$uri&$args;
        }

        location ^~ /proxiedpath/ {
            proxy_set_header X-Real-IP $remote_addr;
            proxy_set_header X-Forwarded-Proto https;
            proxy_pass https://app.example.com/proxiedpath/;
        }

    }

}

Jede Hilfe wird sehr geschätzt - vielen Dank!

9
Bart

Ich konnte dieses Problem heute lösen und wollte die Lösung veröffentlichen, falls andere das gleiche Problem haben.

Es stellt sich heraus, dass das Problem schließlich mit SNI zusammenhängt. Ich habe dieses Ticket auf nginx.org gefunden:

https://trac.nginx.org/nginx/ticket/229

Was mich zu der Direktive proxy_ssl_server_name geführt hat:

http://nginx.org/r/proxy_ssl_servername

Wenn Sie in Ihrer Konfiguration auf "Ein" setzen, können Sie über SNI auf Upstream-Hosts zugreifen.

Vielen Dank an alle, die mit Vorschlägen kommentiert haben!

16
Bart

Als Hinweis für andere ist eine verwandte Bedingung, die Heroku auferlegt, dass das Feld "Host" mit dem benutzerdefinierten Domänennamen übereinstimmen muss.

Neben proxy_ssl_server_name können Sie auch eine Zeile wie folgt setzen:

proxy_set_header Host mycustomdomain.com;

Dies gilt natürlich nur, wenn sich das in den Server eingehende Host-Feld von der Domäne unterscheidet, in der sich Ihr Server befindet.

Der spezifische Fehler, den Sie erhalten, ist:

SSL-Zertifikatfehler

Es gibt widersprüchliche Informationen zwischen der SSL-Verbindung, ihrem Zertifikat und/oder den enthaltenen HTTP-Anforderungen.

2
Jason Axelson