Nginx 在配置代理时,以下 2 种方式完全一样
方式1:

  1. proxy_pass http://internal.foo.com:80;

方式2:

  1. proxy_set_header Host internal.foo.com;
  2. proxy_pass http://192.168.0.20:80;

本质上来讲,proxy_pass 相当于发起了一个 curl 请求,而 proxy_set_header 则是设置请求头的。

  1. # 相当于方式1
  2. curl http://internal.foo.com:80
  3. # 等价于方式2
  4. curl http://192.168.0.20:80 \
  5. -H 'Host: internal.foo.com'

除了 Host Header 之外,其他来自于上游的 HTTP Header 都会被转发。下面就此结论进行相应的实验验证

架构图

  1. 192.168.0.10 (Nginx LB) ---> 192.168.0.20 (Nginx Backend)

Nginx LB

foo.com LB 站点配置

  1. server {
  2. listen 80;
  3. server_name foo.com;
  4. location / {
  5. # 以下两种配置方法效果完全一致
  6. # proxy_pass http://internal.foo.com:80;
  7. proxy_set_header Host internal.foo.com;
  8. proxy_pass http://192.168.0.20:80;
  9. }
  10. }

/etc/hosts 添加以下解析

  1. 192.168.0.20 internal.foo.com

Nginx Backend

internal.foo.com 后端站点配置

  1. server {
  2. listen 80;
  3. server_name internal.foo.com;
  4. index index.html index.htm;
  5. root /www/web/foo.com;
  6. location / {
  7. try_files $uri $uri/ =404;
  8. }
  9. }

为了观察转发后 Host 的变化,在日志中添加 http_host

  1. log_format main '$remote_addr - $remote_user [$time_local] "$request" '
  2. '$status $body_bytes_sent "$http_referer" '
  3. '"$http_user_agent" "$http_x_forwarded_for" '
  4. '[$http_host] ';

/www/web/foo.com 的内容

  1. root@f76414963a73:# cat /www/web/foo.com/index.html
  2. hello, foo.com

测试

测试主机 /etc/hosts 添加以下解析

  1. 192.168.0.10 foo.com

访问 foo.com 站点

  1. suhua@g7-7588:~$ curl http://foo.com
  2. hello, foo.com

查看后端 internal.foo.com 访问日志

  1. 192.168.0.10 - - [07/Sep/2020:10:28:34 +0800] "GET / HTTP/1.0" 200 15 "-" "curl/7.58.0" "-" [internal.foo.com]

注意事项

以下配置方式会丢失 Host,后端收到的 Host 会是 192.168.0.10,即代理服务器的 IP。

  1. proxy_pass http://192.168.0.20:80;