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_files
trong server
khố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-Proto
tiê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ư testdir
mụ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>
Location:
tiêu đề vì nginx không biết giao thức gốc là gì.
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.