Nginx
代理轉發在 Nginx、Laravel、彈性負載均衡器上不起作用
我有一個 AWS 彈性負載均衡器,它接收域 (bunny.misite.dev) 的 https 請求,請求通過 http 發送到伺服器 Nginx,Laravel 應用程序回答請求。
我遇到的問題是 Laravel 沒有將請求辨識為 Https,而是將請求辨識為 http。
為了解決這個問題,Laravel 提供了一個我使用過的“可信代理”中間件:
<?php namespace App\Http\Middleware; use Fideloper\Proxy\TrustProxies as Middleware; use Illuminate\Http\Request; class TrustProxies extends Middleware { /** * The trusted proxies for this application. * * @var array|string|null */ protected $proxies = '*'; /** * The headers that should be used to detect proxies. * * @var int */ protected $headers = Request::HEADER_X_FORWARDED_FOR | Request::HEADER_X_FORWARDED_HOST | Request::HEADER_X_FORWARDED_PORT | Request::HEADER_X_FORWARDED_PROTO | Request::HEADER_X_FORWARDED_AWS_ELB; }
我的 nginx 配置是
server { listen 80 ; listen [::]:80 ; server_name bunny.misite.dev; server_tokens off; error_log /home/main/logs/nginx/bunny-master_error.log; access_log /home/main/logs/nginx/bunny-master_access.log main buffer=16k; access_log /var/log/nginx-rc/bunny-master_traffic.log traffic; client_max_body_size 256m; add_header X-Frame-Options "SAMEORIGIN"; add_header X-XSS-Protection "1; mode=block"; add_header X-Content-Type-Options "nosniff"; root /home/main/webapps/bunny-master/live/public; index index.php index.html index.htm; location / { proxy_send_timeout 60; proxy_read_timeout 60; proxy_buffer_size 128k; proxy_buffers 4 256k; proxy_busy_buffers_size 256k; proxy_temp_file_write_size 256k; proxy_connect_timeout 30s; proxy_set_header Host $http_host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Server-Addr $server_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header X-Forwarded-Proto $scheme; proxy_set_header X-Forwarded-Port $server_port; proxy_pass http://backend; } location ~ /\. { deny all; access_log off; log_not_found off; } location = /favicon.ico { log_not_found off; } location @proxy { proxy_send_timeout 60; proxy_read_timeout 60; proxy_buffer_size 128k; proxy_buffers 4 256k; proxy_busy_buffers_size 256k; proxy_temp_file_write_size 256k; proxy_connect_timeout 30s; proxy_set_header Host $http_host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Server-Addr $server_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header X-Forwarded-Proto $scheme; proxy_pass http://backend; } }
Laravel >= 5.5 已經使用
fideloper/TrustedProxies
,所以它應該尊重X-Forwarded-Proto
header 來決定客戶端請求是使用 HTTP 還是 HTTPS。您的 nginx 配置仍然指定
X-Forwarded-Proto
為,http
因為:
- 您指定
proxy_set_header X-Forwarded-Proto
to$scheme
,這是 AWS ELB 在客戶端請求時使用的 URL 方案,並且- nginx 只接收來自 AWS ELB 而不是 HTTPS 的 HTTP 請求。
要解決此問題,您可以:
- 配置您的 nginx 以接收 HTTPS 請求,或者
- 將您的設置
proxy_set_header X-Forwarded-Proto
為$http_x_forwarded_proto
. AWS ELB應該X-Forwarded-Proto
在進行轉發請求時將請求標頭從客戶端發送到 nginx。如果您確定 AWS ELB 將始終只轉發 HTTPS 請求,您甚至可以設置proxy_set_header X-Forwarded-Proto
為https
.