欢迎访问陈同学博客原文
Tip: keep the Host header via nginx proxy_pass
List of HTTP header fields
背景
今天在调试一项 nginx 配置时手贱不小心注释掉了 proxy_set_header Host $host;
配置,导致所有请求都503。
请求路径如下:
请求 -> nginx1 -> nginx2 -> haproxy -> 后端服务
nginx1是所有流量入口;nginx2负责处理一个产品的流量;haproxy为容器编排工具 Rancher 自带的LB。
注释掉 nginx2 中的 proxy_set_header Host $host;
后,所有API调用都 503,请求无法穿过 haproxy。
起初还以为是 Rancher 网络又出问题(Rancher网络出过很多幺蛾子),检查后发现问题没问题,没想到是 Host 导致。
关于Host
Request header 中的 Host 指定了所请求资源的主机和端口。由于一个IP地址可以对应多个域名,为主机分配IP地址后,主机上可以部署N个站点,可以根据基于域名的 虚拟主机 来处理请求。
RFC 2616 HTTP/1.1 中规定,在所有HTTP/1.1 请求中,client 必须包含 Host header;如果headers中没有Host,所有 HTTP/1.1 proxy 必须返回 400(Bad Request)。
proxy_pass 与 Host
在 nginx proxy_pass 指令中,若不做任何配置,会使用后面的 URL 重写的Host。
下面为两个示例配置,将请求从8080转到9097。
server {
listen 8080;
server_name demo.chenyongjun.vip;
location / {
proxy_pass http://127.0.0.1:9097;
}
}
server {
listen 9097;
server_name demo.chenyongjun.vip;
location / {
proxy_pass http://127.0.0.1:9098;
}
}
请求经过后,Host将由 demo.chenyongjun.vip 变为 127.0.0.1。像最上面的问题,由于nginx处理后 Host 变成了 127.0.0.1,导致 haproxy 无法处理该请求,因此所有请求都503。
在设置 proxy_set_header Host $host; 后,Host都将变为 demo.chenyongjun.vip。
欢迎关注陈同学的公众号,一起学习,一起成长