nginx try_files chuyển hướng sử dụng sơ đồ sai khi đứng sau bộ cân bằng tải chấm dứt SSL (haproxy)


8

Tôi có một máy chủ nginx 1.6.2 đang chạy như một phụ trợ phía sau bộ cân bằng tải có chức năng chấm dứt SSL. Tất cả thông tin liên lạc đến các máy chủ phụ trợ đều đi qua HTTP.

Sơ đồ những gì đang diễn ra:

          /--http---> frontend:80  --\
client --+                            +--http---> backend:8000
          \--https--> frontend:443 --/

                      LOAD BALANCER                BACKENDS

Đối với mục đích thử nghiệm, tôi chỉ có một phụ trợ vào lúc này. Bộ cân bằng tải chạy HAProxy 1.5, mà tôi có một số quyền kiểm soát.

Tôi có một lệnh khá điển hình try_filestrong serverkhối của mình trong cấu hình nginx phụ trợ:

server {
    server_name frontend;
    ...
    try_files $uri $uri/ =404;
    ...
}

Bây giờ, theo mặc định, khi tôi truy cập vào một thư mục không có dấu gạch chéo, ví dụ https://frontend/somedir, nginx muốn gửi chuyển hướng HTTP 301 đến một URL tuyệt đối như thế nào http://frontend:8000/somedir/.

Tôi có thể làm cho nginx bỏ qua số cổng 8000 bằng cách sử dụng port_in_redirect off.

Tuy nhiên, tôi dường như không thể sửa http://sơ đồ khi bắt đầu chuyển hướng nginx đang tạo. Điều tốt nhất tôi có thể có được nginx để làm là chuyển hướng từ https://frontend/somedirđến http://frontend/somedir/, tước hiệu quả SSL!

Bộ cân bằng tải đang gửi một X-Forwarded-Prototiêu đề nhưng tôi không thấy cách nào để nginx tham khảo ý kiến ​​đó khi chế tạo chuyển hướng của nó; trong thực tế, có một câu trả lời năm 2012 nói rằng nginx hoàn toàn không thể làm điều này và giải pháp là thay thế bộ cân bằng tải bằng nginx. IMHO đây là một điều quá tầm thường để đảm bảo một sự thay đổi mạnh mẽ như vậy.

Có gì thay đổi kể từ năm 2012 ở đây? Tôi thực sự không muốn viết lại các chuyển hướng này ở cấp độ HAProxy: HTTPS có chủ ý thực sự chuyển hướng HTTP từ ứng dụng web có thể nhận được "re-HTTPSed" nếu tôi luôn luôn viết lại lược đồ cho Location:tiêu đề phản hồi giống như lược đồ yêu cầu được thực hiện với.

BIÊN TẬP:

Đây là một cấu hình thu nhỏ cho thấy nginx tạo ra Location:các URL tuyệt đối . Lưu ý không có viết lại.

user nobody nobody;
worker_processes auto;
worker_rlimit_nofile 4096;
error_log /var/log/nginx/error.log warn;
pid /var/run/nginx.pid;

events {
    worker_connections 1024;
    multi_accept on;
}

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

    log_format  main  '$remote_addr - $remote_user [$time_local] "$request" '
                      '$status $body_bytes_sent "$http_referer" '
                      '"$http_user_agent" "$http_x_forwarded_for"';

    access_log  /var/log/nginx/access.log  main;

    sendfile on;
    tcp_nopush on;
    tcp_nodelay on;

    # TODO: Tune fastcgi_buffers/other buffers

    # Configure keepalive connections
    keepalive_timeout 15;
    keepalive_requests 1000;

    # Hide server version.
    server_tokens off;

    # Do not allow any directory indexes anywhere.
    # This is the default, but it is here for extra paranoia.
    autoindex off;

    # gzip text content.
    gzip on;
    gzip_vary on;
    gzip_disable "msie6";
    gzip_comp_level 2;
    gzip_min_length 1024;
    gzip_types  text/css
                text/plain
                text/xml
                application/json
                application/javascript;

    server {
        listen 8000 default_server;

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

        server_name localhost;

        location / {
            try_files $uri $uri/ =404;
        }
    }
}

Và nếu bạn sử dụng curl để xem các tiêu đề - lưu ý tôi đã tạo một thư testdirmục trong /usr/share/nginx/html:

[myuser@dev nginx]$ curl -i http://localhost:8000/testdir
HTTP/1.1 301 Moved Permanently
Server: nginx
Date: Thu, 26 Mar 2015 14:35:49 GMT
Content-Type: text/html
Content-Length: 178
Location: http://localhost:8000/testdir/
Connection: keep-alive

<html>
<head><title>301 Moved Permanently</title></head>
<body bgcolor="white">
<center><h1>301 Moved Permanently</h1></center>
<hr><center>nginx</center>
</body>
</html>

nginx wants to send an HTTP 301 redirect to an absolute URL- nginx không làm điều đó trừ khi bạn có quy tắc viết lại rõ ràng để làm như vậy - vui lòng hiển thị cấu hình đầy đủ của bạn.
AD7six

Tôi đã thêm cấu hình, cắt giảm để chỉ minh họa vấn đề này. Tôi không làm bất kỳ viết lại rõ ràng.
mutron

1
Bạn nên cấu hình bộ cân bằng của mình để thay thế giao thức trong Location:tiêu đề vì nginx không biết giao thức gốc là gì.
Alexey Ten

2
@AlexeyTen bạn có muốn đăng nó như một câu trả lời để tôi có thể phê duyệt không? Tôi cũng không tìm thấy cách nào để làm điều này trong nginx, vì vậy một sự thay đổi ở bộ cân bằng tải thực sự dường như là cách duy nhất.
mutron

1
Đây vẫn là một lỗi với bản phát hành nginX mới nhất! Có ai biết nếu đã có một báo cáo lỗi chưa? Không thể tìm thấy một.
Roel van Duijnhoven

Câu trả lời:



-1

Bạn cần phải cho cân bằng tải để viết lại httpđể httpstrong các yêu cầu như sau:

proxy_redirect http:// $scheme://;
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.