2016-07-14 32 views
7

Tôi không may là không có nhiều người quản trị hệ thống và đã gặp phải vấn đề khiến tôi đập đầu vào tường.Nginx đảo ngược proxy để Heroku không bắt tay SSL

Câu chuyện ngắn là tôi đang chạy Nginx trên EC2 (Ubuntu 14.04.4 LTS) để (a) lưu trữ trang web tiếp thị của công ty tôi (https://example.com, ngẫu nhiên là Wordpress) và (b) phục vụ như một proxy ngược ứng dụng Rails của chúng tôi chạy trên Heroku (https: // app.example.com), đối với một số đường dẫn nhất định. Chúng tôi sử dụng cùng một chứng chỉ SSL cho cả example.com và app.example.com. Tất cả điều này đã làm việc rất tốt trong 8-10 tháng, nhưng gần đây tôi đã chuyển từ addon SSL trả phí của Heroku sang cung cấp SSL miễn phí mới, và bây giờ proxy ngược của chúng tôi bị hỏng.

Trong kiểm tra các bản ghi lỗi Nginx, tôi thấy như sau:

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"

Tôi đã cố gắng để tìm kiếm xung quanh cho một số hướng dẫn bổ sung - Tôi đã nâng cấp Nginx (1.10.1) và OpenSSL (1.0. 2h) không có may mắn. Tôi nghi ngờ vấn đề có thể là do việc sử dụng SNI của Heroku trong tính năng SSL miễn phí mới (https://devcenter.heroku.com/articles/ssl-beta), nhưng không thể xác định tại sao điều này có thể là một vấn đề.

Một vài điểm bổ sung thăm dò của tôi đến thời điểm này:

  • Khi tôi chuyển sang miễn phí mới Heroku SSL, tôi đã thay đổi bản ghi DNS app.example.com của chúng tôi để trỏ đến app.example.com .herokudns.com, theo hướng dẫn của các tài liệu. Ứng dụng có thể được truy cập bình thường thông qua app.example.com và khi tôi chạy một nslookup trên app.example.com và app.example.com.herokudns.com, tôi nhận được cùng một địa chỉ IP. Tuy nhiên ...

  • Tôi không thể truy cập ứng dụng thông qua địa chỉ IP được trả lại từ nslookup hoặc app.example.com.herokudns.com. Tôi nghi ngờ điều này là bình thường và mong đợi nhưng không biết đủ để nói chính xác lý do tại sao điều này xảy ra. Và ...

  • Địa chỉ IP được trả lại từ nslookup KHÔNG giống với địa chỉ IP được tham chiếu trong thông báo lỗi của nhật ký ở trên ("ipaddress2"). Trên thực tế, "ipaddress2" không nhất quán trong suốt nhật ký - dường như thay đổi thường xuyên. Một lần nữa tôi không biết đủ để biết những gì tôi không biết ... cân bằng tải trên mặt của Heroku?

Và cuối cùng, Nginx reverse proxy của tôi được cấu hình như sau trong 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/; 
     } 

    } 

} 

Any help is appreciated rất nhiều - cảm ơn rất nhiều!

+0

Are 2 trang web của bạn được lưu trữ trên cùng một máy chủ? Bạn có thể hiển thị cấu hình 'app.mycompany.com' cho chúng tôi không? Bởi vì nếu chúng ở trên cùng một máy chủ thì bạn có thể trả về 301 https: //app.mycompany.com/proxiedpath/; 'và có nginx xử lý yêu cầu bằng tên máy chủ' app.mycompany.com' với cùng một chứng chỉ. –

+0

Thật không may, chúng hoàn toàn tách biệt - máy chủ proxy được thiết lập trên AWS (nơi tôi có toàn quyền điều khiển cấu hình) và máy chủ ứng dụng được lưu trữ trên Heroku (nơi tôi có ít điều khiển hoặc thậm chí thông tin chi tiết về cấu hình). Nó hoạt động trước sự thay đổi này, vì vậy tôi biết nó phải là một điều khá nhỏ. – Bart

+0

Ngoài ra, muốn thêm - điều quan trọng đối với chúng tôi là vì lý do SEO mà các trang này xuất hiện trên mycompany.com thay vì trên app.mycompany.com, nơi chúng thực sự được phân phối. – Bart

Trả lời

10

Tôi đã có thể giải quyết vấn đề này ngay hôm nay và muốn đăng giải pháp trong trường hợp người khác gặp sự cố tương tự.

Cuối cùng, vấn đề liên quan đến SNI. Tôi tìm thấy vé này trên nginx.org:

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

nào dẫn tôi đến chỉ thị proxy_ssl_server_name:

http://nginx.org/r/proxy_ssl_server_name

Bằng cách thiết lập để "vào" trong cấu hình của bạn, bạn sẽ có thể để proxy cho các máy chủ lưu trữ ngược sử dụng SNI.

Nhờ tất cả những ai đã nhận xét với đề xuất!

+0

Giống như http://stackoverflow.com/questions/25329941/nginx-caching-proxy-fails-with-ssl23-get-server-hellosslv3-alert -handshake-fail/25330027 # 25330027 Điều duy nhất là bạn cũng nên thực thi TLS1.0 trở lên, nếu không SNI sẽ không được sử dụng. – gubble

+0

Cảm ơn câu trả lời này. Tôi nghĩ rằng việc tìm kiếm câu trả lời này sẽ dễ dàng nhưng Google không nghĩ vậy –

0

Như một lưu ý cho người khác một điều kiện liên quan mà Heroku áp đặt là trường HOST phải khớp với tên miền tùy chỉnh.

Vì vậy, ngoài việc proxy_ssl_server_name bạn cũng có thể muốn thiết lập một dòng như:

proxy_set_header Host mycustomdomain.com; 

Tất nhiên điều này chỉ áp dụng nếu các lĩnh vực chủ incoming vào sever khác với tên miền mà máy chủ của bạn nằm trong.

các lỗi cụ thể mà bạn nhận được là:

SSL certificate error

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

Các vấn đề liên quan