2016-07-14 40 views
7

Ich bin leider nicht viel von einem Systemadministrator und habe ein Problem, das mich mit dem Kopf gegen die Wand schlug.Nginx Reverse Proxy zu Heroku schlägt fehl SSL-Handshake

Die kurze Geschichte ist, dass ich Nginx auf EC2 (Ubuntu 14.04.4 LTS) laufen lasse, um (a) die Marketing-Seite meines Unternehmens (https://example.com, die übrigens Wordpress ist) zu hosten und (b) als Reverse-Proxy zu dienen Unsere Rails-App läuft auf Heroku (https: // app.example.com) für bestimmte Pfade. Wir verwenden das gleiche SSL-Zertifikat für example.com und app.example.com. All das hat 8-10 Monate lang gut funktioniert, aber ich habe kürzlich von Herokus bezahlten SSL-Addon auf das neue kostenlose SSL-Angebot umgestellt, und jetzt ist unser Reverse-Proxy defekt.

die Nginx Fehlerprotokolle Bei der Überprüfung, sehe ich folgendes:

SSL_do_handshake() failed (SSL: error:14094438:SSL routines:SSL3_READ_BYTES:tlsv1 alert internal error:SSL alert number 80) while SSL handshaking to upstream, client: ipaddress1, server: example.com, request: "GET /proxiedpath/proxiedpage HTTP/1.1", upstream: "https:// ipaddress2:443/proxiedpath/proxiedpage", host: "example.com"

Ich habe schon seit einiger zusätzliche Anleitung zu suchen versucht - ich habe Nginx (1.10.1) und OpenSSL aktualisiert (1.0. 2h) ohne Glück. Ich vermutete, dass das Problem auf Herokus Verwendung von SNI in der neuen kostenlosen SSL-Funktion (https://devcenter.heroku.com/articles/ssl-beta) zurückzuführen ist, konnte aber nicht feststellen, warum dies ein Problem sein könnte.

Ein paar zusätzliche Punkte auf meiner Exploration auf diesen Punkt:

  • Als ich zum neuen freien Heroku SSL geschaltet, änderte es unseren app.example.com DNS-Eintrag zu app.example.com-zu-Punkt .herokudns.com, wie von den Dokumenten angewiesen. Auf die Anwendung kann normal über app.example.com zugegriffen werden und wenn ich ein nslookup auf app.example.com und app.example.com.herokudns.com ausführen, bekomme ich die gleiche IP-Adresse zurück. Jedoch ...

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

  • Die von nslookup zurückgegebene IP-Adresse stimmt NICHT mit der IP-Adresse überein, auf die in der Fehlermeldung des Protokolls ("ipaddress2") verwiesen wird. In der Tat ist "ipaddress2" in den Logs nicht konsistent - es scheint sich regelmäßig zu ändern. Wieder weiß ich nicht genug, um zu wissen, was ich nicht weiß ... Lastausgleich auf Herokus Seite? sehr viel Dank -

    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:

Und schließlich ist mein Nginx Reverse-Proxy konfiguriert ist, wie in nginx.conf folgt!

+0

Sind Ihre 2 Websites auf demselben Server gehostet? Können Sie uns 'app.mycompany.com's Config zeigen? Denn wenn sie sich auf demselben Server befinden, könnten Sie 301 https: //app.mycompany.com/proxiedpath/; 'zurückgeben und nginx die Anfrage mit dem Servernamen" app.mycompany.com "mit dem gleichen Zertifikat bearbeiten. –

+0

Leider sind sie völlig getrennt - der Proxy-Server ist auf AWS (wo ich die volle Kontrolle über die Konfiguration habe) eingerichtet und der Anwendungsserver ist auf Heroku gehostet (wo ich relativ wenig Kontrolle oder sogar Einblick in die Konfiguration habe). Es funktionierte jedoch schon vor dieser Änderung, also weiß ich, dass es eine ziemlich kleine Sache sein muss. – Bart

+0

Auch wollte hinzufügen - es ist uns aus SEO-Gründen wichtig, dass diese Seiten auf mycompany.com im Gegensatz zu auf app.mycompany.com angezeigt werden, wo sie tatsächlich bedient werden. – Bart

Antwort

10

Ich konnte das heute lösen und wollte die Lösung posten, falls andere auf das gleiche Problem stoßen.

Es stellt sich heraus, dass das Problem immerhin mit SNI verbunden war. Ich fand dieses Ticket auf nginx.org:

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

Was mich zu der proxy_ssl_server_name Richtlinie führte:

http://nginx.org/r/proxy_ssl_server_name

Durch die Einstellung auf "on" in der Config, werden Sie in der Lage sein, Proxy für Upstream-Hosts mithilfe von SNI.

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

+0

Es ist dasselbe wie http://stackoverflow.com/questions/25329941/nginx-caching-proxy-fails-with-ssl23-get-server-hellosslv3-alert -handshake-fail/25330027 # 25330027 Die einzige Sache ist, dass Sie auch TLS1.0 oder höher erzwingen sollten, sonst wird SNI nicht verwendet. – gubble

+0

Danke für diese Antwort. Ich dachte, diese Antwort zu finden wäre einfach, aber Google hat das nicht gedacht –

0

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

So zusätzlich zu proxy_ssl_server_name Sie können auch eine Linie setzen wie:

proxy_set_header Host mycustomdomain.com; 

Natürlich nur gilt, wenn das Host-Feld in den Sever eingehende aus der Domäne unterscheidet, die den Server in befindet.

der spezifische Fehler, den Sie erhalten, ist:

SSL certificate error

There is conflicting information between the SSL connection, its certificate and/or the included HTTP requests.