web-dev-qa-db-fra.com

Le proxy inverse de Nginx vers Heroku échoue avec l'établissement de la liaison SSL

Malheureusement, je ne suis pas un administrateur système et je suis tombé sur un problème qui me fait me cogner la tête contre le mur.

La nouvelle est que j'utilise Nginx sur EC2 (Ubuntu 14.04.4 LTS) pour (a) héberger le site marketing de mon entreprise ( https://example.com , qui est d'ailleurs Wordpress) et (b) servir de proxy inverse à notre application Rails s'exécutant sur Heroku (https: // app.example.com), pour certains chemins. Nous utilisons le même certificat SSL pour example.com et app.example.com. Tout cela a bien fonctionné pendant 8 à 10 mois, mais j'ai récemment remplacé l'addon SSL payant de Heroku par la nouvelle offre SSL gratuite. Notre proxy inverse est désormais en panne.

En vérifiant les journaux d’erreur Nginx, je vois ce qui suit:

SSL_do_handshake () a échoué (SSL: erreur: 14094438: routines SSL : SSL3_READ_BYTES: erreur interne de l'alerte tlsv1: numéro d'alerte SSL 80) lors de l'établissement d'une liaison SSL en amont, client: ipaddress1, serveur: example.com, request: "GET/proxiedpath/proxiedpage HTTP/1.1", en amont: "https: // ipaddress2: 443/proxiedpath/proxiedpage", hôte: "exemple .com "

J'ai essayé de chercher des conseils supplémentaires - j'ai mis à niveau Nginx (1.10.1) et OpenSSL (1.0.2h) sans succès. Je soupçonnais que le problème pouvait être dû à l'utilisation de SNI par Heroku dans la nouvelle fonctionnalité SSL gratuite ( https://devcenter.heroku.com/articles/ssl-beta ), mais je n'ai pas été en mesure de comprendre pourquoi. pourrait être un problème.

Quelques points supplémentaires sur mon exploration à ce point:

  • Lorsque je suis passé au nouveau SSL gratuit Heroku, j'ai modifié notre enregistrement DNS app.example.com pour qu'il pointe vers app.example.com.herokudns.com, comme indiqué par la documentation. L'application est accessible normalement via app.example.com et lorsque je lance nslookup sur app.example.com et app.example.com.herokudns.com, je récupère la même adresse IP. Toutefois...

  • Je ne peux pas accéder à l'application via l'adresse IP renvoyée par nslookup ou par app.example.com.herokudns.com. Je soupçonne que c'est normal et prévu, mais je ne sais pas assez pour dire exactement pourquoi. Et...

  • L'adresse IP renvoyée par nslookup n'est PAS identique à l'adresse IP référencée dans le message d'erreur du journal ci-dessus ("ipaddress2"). En fait, "ipaddress2" n'est pas cohérent dans tous les journaux - il semble changer régulièrement. Encore une fois, je ne sais pas assez pour savoir ce que je ne sais pas ... équilibrer la charge du côté de Heroku?

Et enfin, mon proxy inverse Nginx est configuré comme suit dans nginx.conf:

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/;
        }

    }

}

Toute aide est grandement appréciée - merci beaucoup!

9
Bart

J'ai pu résoudre ce problème aujourd'hui et je voulais poster la solution au cas où d'autres rencontreraient le même problème.

Il se trouve que le problème était lié à SNI après tout. J'ai trouvé ce billet sur nginx.org:

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

Ce qui m'a amené à la directive proxy_ssl_server_name:

http://nginx.org/r/proxy_ssl_server_name

En activant "on" dans votre configuration, vous pourrez utiliser un proxy pour héberger des hôtes en amont à l'aide de SNI.

Merci à tous ceux qui ont commenté avec des suggestions!

16
Bart

Pour les autres utilisateurs, Heroku impose que le champ Hôte doit correspondre au nom de domaine personnalisé.

Donc, en plus de proxy_ssl_server_name, vous pouvez également définir une ligne comme celle-ci:

proxy_set_header Host mycustomdomain.com;

Bien entendu, cela ne s'applique que si le champ Host entrant dans le serveur est différent du domaine dans lequel réside votre serveur.

L'erreur spécifique que vous obtenez est:

Erreur de certificat SSL

Il existe des informations conflictuelles entre la connexion SSL, son certificat et/ou les requêtes HTTP incluses.

2
Jason Axelson