Saya memiliki server nginx 1.6.2 yang berjalan sebagai backend di belakang load balancer yang melakukan terminasi SSL. Semua komunikasi ke server backend melewati HTTP.
Diagram dari apa yang terjadi:
/--http---> frontend:80 --\
client --+ +--http---> backend:8000
\--https--> frontend:443 --/
LOAD BALANCER BACKENDS
Untuk tujuan pengujian saya hanya memiliki satu backend saat ini. Penyeimbang beban menjalankan HAProxy 1.5, yang saya kendalikan.
Saya memiliki try_files
arahan yang cukup khas di server
blok saya di konfigurasi nginx backend:
server {
server_name frontend;
...
try_files $uri $uri/ =404;
...
}
Sekarang, secara default, ketika saya mengakses direktori tanpa garis miring, misalnya https://frontend/somedir
, nginx ingin mengirim HTTP 301 redirect ke URL absolut seperti http://frontend:8000/somedir/
.
Saya dapat membuat nginx menghilangkan nomor port 8000 menggunakan port_in_redirect off
.
Namun saya tidak bisa memperbaiki http://
skema di awal nginx redirect yang dihasilkan. Yang terbaik yang bisa saya dapatkan dari nginx adalah pengalihan dari https://frontend/somedir
ke http://frontend/somedir/
, secara efektif menghapus SSL!
Penyeimbang beban mengirim X-Forwarded-Proto
tajuk tetapi saya tidak melihat cara apa pun untuk nginx untuk berkonsultasi ketika menyusun pengalihannya; sebenarnya ada jawaban 2012 yang mengatakan nginx langsung tidak bisa melakukan ini, dan solusinya adalah mengganti load balancer dengan nginx. IMHO ini hal yang terlalu sepele untuk menjamin perubahan tumpukan yang drastis.
Apakah ada yang berubah sejak 2012 di sini? Saya tidak benar-benar ingin menulis ulang pengalihan ini di tingkat HAProxy: HTTPS disengaja yang sebenarnya ke pengalihan HTTP dari aplikasi web mungkin mendapatkan "HTTPSed kembali" jika saya selalu selalu menulis ulang skema untuk Location:
header respons yang sama dengan skema permintaan dibuat dengan.
EDIT:
Ini adalah konfigurasi diminimalkan yang menunjukkan nginx menghasilkan Location:
URL absolut . Perhatikan tidak ada penulisan ulang.
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;
}
}
}
Dan jika Anda menggunakan ikal untuk melihat header - perhatikan saya telah membuat direktori di testdir
bawah /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 tidak melakukan itu kecuali Anda memiliki aturan penulisan ulang yang eksplisit untuk melakukannya - tolong tunjukkan konfigurasi lengkap Anda.Location:
header karena nginx tidak tahu apa itu protokol asli.Jawaban:
Maju cepat ke 2019 dan Anda dapat:
Dari dokumen untuk
absolute_redirect
:sumber
Anda perlu memberitahu penyeimbang beban untuk menulis ulang
http
kehttps
dalam permintaan seperti:sumber