我正在尝试根据值 $host 变量对 proxy_pass 规则使用不同的 scheme。
然而它似乎不起作用,这是我们观察到的行为。
如果我们将 proxy_pass 设置为像这样的常量方案
proxy_pass https://$upstream;
一切正常,但如果我们尝试用自定义变量替换硬编码方案值 (https) 然后使用 proxy_pass $myscheme://$upstream;
Nginx 似乎忽略 $myscheme并尝试在不使用方案的情况下解析 $upstream,这显然失败了。
即使我们像这样设置变量也会发生这种情况
set $myscheme https;
.
这种行为正常吗?我们做错了什么?有没有办法根据运行时设置的变量值使用不同的方案?
当前(不工作)配置
根据我们的测试,看起来(至少我们正在运行的版本)Nginx 实际上并没有替换 proxy_pass
中的变量worker_processes 4;
worker_rlimit_nofile 100000;
events {
worker_connections 100000;
multi_accept on;
use epoll;
}
http {
log_format timed_combined '$remote_addr - $remote_user [$time_local] '
'"$request" $status $body_bytes_sent '
'"$http_referer" "$http_user_agent" '
'$request_time $upstream_response_time';
server {
listen 443;
server_name myservername;
ssl on;
ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
ssl_certificate /etc/letsencrypt/live/xxx;
ssl_certificate_key /etc/letsencrypt/live/xxx;
gzip on;
gzip_comp_level 2;
gzip_min_length 1000;
gzip_proxied expired no-cache no-store private auth;
gzip_types application/json text/json text/plain application/x-javascript text/xml text/css application/xml;
access_log /var/log/nginx/access.log timed_combined;
set $myscheme https;
set $myhost myhostname;
location / {
proxy_pass $myscheme://$myhost;
}
}
}
NGINX 版本:1.10.3
这有效,并且刚刚使用 Nginx 1.23.3 进行了测试。
upstream @test { server 127.0.0.1; }
server {
listen 127.0.0.1:80;
listen 127.0.0.1:443 ssl http2;
include conf.d/includes/security.conf; # TLS certs
default_type "text/plain";
return 200 "scheme: $scheme\n";
}
server {
listen 127.0.0.1:8080;
set $pxy_proto $arg_proto;
set $pxy_host 127.0.0.1;
add_header x-proto $pxy_proto always;
location / {
proxy_pass $pxy_proto://$pxy_host;
}
}
$ curl -si http://localhost:8080/?proto=http
HTTP/1.1 200 OK
Content-Type: text/plain
Content-Length: 13
x-proto: http
scheme: http
$ curl -si http://localhost:8080/?proto=https
HTTP/1.1 200 OK
Content-Type: text/plain
Content-Length: 14
x-proto: https
scheme: https