Nginx反向代理下的proxy_set_header Host字段有什么用
proxy_set_header 中的host字段的默认值为下
proxy_set_header Host $proxy_host;
假设有如下的location配置:
server {
listen 80;
server_name localhost;
access_log /tmp/access_log.log;
error_log /tmp/error_log.log;
location ^~ /pic/ {
proxy_pass http://img.cherryml.com/;
proxy_set_header Host $proxy_host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header REMOTE-HOST $remote_addr;
}
那么Host中的$proxy_host就表示proxy_pass
中的img.cherryml.com
而proxy_set_header Host
允许给后端服务器重写Host请求头
通常有两种写法:
proxy_set_header Host $host;
proxy_set_header Host $http_host;
如果请求头中没有设置Host,则$http_host
为空,而$host
为server_name
,即location
,如果server_name
也没有指定,则自动从上级别继承,继承顺序为:http
、 server
、location
。
那么说这么多,有什么实际的意义呢?当然有!今天在配置nginx反代的时候出现了问题,来记录一下:
起因
本博客一直缺少一个图床,在综合考虑后选择了七牛云做存储。毕竟每个月有10G的免费流量。为了不掉绿锁(在https协议下发起http请求,浏览器会提示此网站并不完全安全),打算通过nginx把七牛做反代。 于是最初的nginx配置文件是这样的:
server {
listen 80;
server_name localhost;
access_log /tmp/access_log.log;
error_log /tmp/error_log.log;
location / {
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_pass http://localhost:1234;
}
location ^~ /pic/ {
proxy_pass http://thirdqq.qlogo.cn/;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header REMOTE-HOST $remote_addr;
}
location ^~ /qiniu/ {
proxy_pass http://img.cherryml.com/;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header REMOTE-HOST $remote_addr;
}
重启nginx后发现,同时请求三张图片,路径分别为:
http://img.cherryml.com/1557415617708_2.jpeg
https://cherryml.com/qiniu/1557415617708_2.jpeg
https://cherryml.com/pic/g?b=sdk&k=0MYvEHqBWuYQO7ZrA1ZtAA&s=100
第一张图片直接引用,自然可以正常显示,也自然掉了绿锁。 第二张图片死活显示不出来,看了一眼控制台:服务器返回了403 第三章图片显示正常
一个大写懵逼写在脸上:
图2和图3都是一样的配置,一样做反代,为什么图3可以图2就显示不了!!!
在百度了N久,看了好多千篇一律,你抄我我抄你的csdn、简书依然一无所获。
看来还得靠自己。我开始一段段的注释/qiniu
下的nginx配置文件,终于发现了问题:
如果设置proxy_set_header Host $host;
则图二就显示不出来。
如果注释去掉则正常显示了。
原因
说到这里,刚开始的proxy_set_header
介绍就能很好的作出解释了:
在/qiniu
的配置项里面,
proxy_set_header Host $host;
那么对img.cherryml.com
来说,请求头里面的Host字段不是它本身的proxy_pass (img.cherryml.com)
而是继承了它上一层的server下的server_name字段,也就是localhost
host是什么
那么又有新问题了:为什么/pic
下面反代qq头像就不会有问题呢。
这里有要引出一个概念:http请求头中,Host字段有什么作用?
百度过后做了下总结:
如果一个ip就对应一个域名,那么就会造成极大的浪费。为了解决此问题,就出现了虚拟机和Host的概念。 一个真实机器上可以对应放多个虚拟机,通过host来指定我到底访问的是这个ip下哪台服务器。具体配置文件可以参考windows和mac系统下都有的host文件。
那么就很好解释了,我的域名 img.cherryml.com 是在七牛里面注册绑定的。那么七牛肯定通过host 解析到了我这个域名。
而我在请求图片的时候,Host错误的设置成了localhost而不是img.cherryml.com
,那么对于七牛来说,我只能让你在服务器上访问你自己的域名下的东西,七牛自己的localhost当然是做了限制不准我访问的。因此很明显报了403 forbidden。
至于为什么qq头像服务器没有做限制,我想thirdqq.qlogo.cn
应该是作为一个通用的api服务器在运行吧。
话已至此,此章已毕,寡人欲休,我们下期再见~