为什么不能直接嵌套
在编辑 nginx.conf 时,我们常有一种场景,即需要给所有服务一个通用的 proxy_set_header 集合,对于一些需要特殊处理的服务,定制一些独特的 proxy_set_header。
此时,你可能会这么写:
http {
##
# Virtual Host Configs
##
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header X-Forwarded-Host $host;
proxy_set_header X-Forwarded-Port $server_port;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header Host $host;
server {
listen 443 ssl;
server_name demo.domain.com;
ssl_certificate /etc/nginx/cert_file/fullchain.pem;
ssl_certificate_key /etc/nginx/cert_file/key.pem;
location / {
proxy_pass http://127.0.0.1:11001/;
proxy_set_header Host special.domain.com;
}
error_page 497 https://$host:$server_port$request_uri;
}
}
但运行起来后,你会发现,在外层设置的 proxy_set_header 全部没有生效。原因是 nginx 仅在里层没有配置任何 proxy_set_header 时,才会继承外层的 proxy_set_header 设置。详见 Nginx 官方文档
正确方法
如果你仔细看过 nginx 的 /etc/nginx 目录,便会发现 nginx 给你默认创建了一个文件 proxy_params。
proxy_set_header Host $http_host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
在实际使用时,你可以复用并修改这个文件,或者创建一个类似的新文件,并在每个服务中增加一行include /etc/nginx/proxy_params
,在需要定制 header 时,在 include 行的上方增加定制的内容,即可实现继承通用 header 的功能。
http {
##
# Virtual Host Configs
##
server {
listen 443 ssl;
server_name demo.domain.com;
ssl_certificate /etc/nginx/cert_file/fullchain.pem;
ssl_certificate_key /etc/nginx/cert_file/key.pem;
location / {
proxy_pass http://127.0.0.1:11001/;
proxy_set_header Host special.domain.com;
include /etc/nginx/proxy_params;
}
error_page 497 https://$host:$server_port$request_uri;
}
}