暂无图片
暂无图片
暂无图片
暂无图片
暂无图片

nginx配置proxy_set_header

爱可可的人生记录仪 2019-08-10
1904


上回我们讲到,因为nginx反向代理x_forward_for的设置,导致grafana请求头的ip字节过长,无法获取zabbix的数据。


先看官方对proxy_set_header的解释:

Allows redefining or appending fields to the request header passed to the proxied server. (允许重新定义或者追加传递到proxy server的header )

An unchanged “Host” request header field can be passed like this:

proxy_set_header Host       $http_host;
复制

However, if this field is not present in a client request header then nothing will be passed. In such a case it is better to use the $host variable - its value equals the server name in the “Host” request header field or the primary server name if this field is not present:

proxy_set_header Host       $host;
复制

$proxy_add_x_forwarded_for

the “X-Forwarded-For” client request header field with the $remote_addr variable appended to it, separated by a comma. If the “X-Forwarded-For” field is not present in the client request header, the $proxy_add_x_forwarded_for variable is equal to the $remote_addr variable.($proxy_add_x_forwarded_for是客户端X-Forwarded-For的值, 如果客户端header中没有设置, 则$proxy_add_x_forwarded_for 等于$remote_addr)

We use proxy_set_header directives to pass relevant information to the WAP servers, and also so we can capture it in the logs:

The X-Real-IP header contains the source (client's) IP address as captured in the $remote_addr variable.

The X-Forwarded-For conveys that header from the client request, with the client’s IP address appended to it (or just that address if the client request doesn’t have the header).(X-Real-IP包含客户端原始的IP,可以被$remote_addr捕获,X-Forwarded-For 代表客户端header中标记的IP, 它可以被$proxy_add_x_forward_for捕获, 如果header没有X-Forwarded-For 则它和$remoter_addr是相同的)


我们直接看实验,看完你就明白了:

我准备了3台nginx和一台windows(作为客户端访问)

windows:192.168.2.1

nginx1:192.168.2.2

    user root;
    worker_processes auto;
    events {
    worker_connections 1024;
    }
    http {
        log_format  main  'host:$host | http_host:$http_host |'
        'proxy_host:$proxy_host | remote_addr:$remote_addr |'
        'realip:$http_x_real_ip | $status |'
        'xforward:$http_x_forwarded_for';
    access_log tmp/access.log main;
    server {
    listen 801;
    location ^~ {
    proxy_pass http://192.168.2.128/;
    #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;
    }
    }
        }
    复制

    nginx2:192.168.2.128

      user root;
      worker_processes auto;
      events {
      worker_connections 1024;
      }
      http {
      log_format main 'host:$host | http_host:$http_host |'
      'proxy_host:$proxy_host | remote_addr:$remote_addr |'
      'realip:$http_x_real_ip | $status |'
      'xforward:$http_x_forwarded_for';
      access_log tmp/access.log main;
      server {
      listen 80;
      location ^~ {
      proxy_pass http://192.168.2.4/;
      #proxy_set_header Host $host;
      #proxy_set_header X-Real-IP $remote_addr;
      #proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
      }
      }
      }
      复制

      nginx3:192.168.2.4

        user root;
        worker_processes auto;
        events {
        worker_connections 1024;
        }
        http {
        log_format main 'host:$host | http_host:$http_host |'
        'proxy_host:$proxy_host | remote_addr:$remote_addr |'
        'realip:$http_x_real_ip | $status |'
        'xforward:$http_x_forwarded_for';
        access_log tmp/access.log main;
        server {
        listen 80;
        location ^~ {
        root "/var/www/html";
        index index.html;
        #proxy_set_header Host $host;
        #proxy_set_header X-Real-IP $remote_addr;
        #proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        }
        }
        }
        复制
        $host                    #HTTP请求行的主机名
        复制

        $remote_addr             #客户端地址

        $status                  #HTTP响应代码
        复制

        $http_host               #请求地址,即浏览器中你输入的地址(IP或域名)

        $proxy_add_x_forwarded_for#变量包含客户端请求头中的"X-Forwarded-For",与$remote_addr两部分,他们之间用逗号分开。


        访问流程:windows——>nginx1——>nginx2——>nginx3

        先全部注释掉proxy_set_header的配置,访问日志如下:

        nginx1(192.168.2.2)

          host:192.168.2.2 | http_host:192.168.2.2:801 | proxy_host:192.168.2.128 | remote_addr:192.168.2.1 | realip:| 304 | xforward:-
          复制

          nginx2(192.168.2.128)

            host:192.168.2.128 | http_host:192.168.2.128 | proxy_host:192.168.2.4 | remote_addr:192.168.2.2 | realip:| 304 | xforward:-
            复制

            nginx3(192.168.2.4)

              host:192.168.2.4 | http_host:192.168.2.4 | proxy_host:| remote_addr:192.168.2.128 | realip:| 304 | xforward:-
              复制

              从日志可以看到,除了作为流量入口nginx1(2.2)的日志有分析价值外,其他的都没什么用。

              开启配置后再看:

              nginx1(192.168.2.2)

                host:192.168.2.2 | http_host:192.168.2.2:801 | proxy_host:192.168.2.128 | remote_addr:192.168.2.1 | realip:| 304 | xforward:-
                复制

                nginx2(192.168.2.128)

                  host:192.168.2.2 | http_host:192.168.2.2:801 | proxy_host:192.168.2.4 | remote_addr:192.168.2.2 | realip:192.168.2.1 | 304 | xforward:192.168.2.1
                  复制

                  nginx3(192.168.2.4)

                    host:192.168.2.2 | http_host:192.168.2.2 | proxy_host:| remote_addr:192.168.2.128 | realip:192.168.2.2 | 304 | xforward:192.168.2.1192.168.2.2
                    复制

                    对比之后,效果很明显。我想你应该清楚了,简单地说,proxy_set_header可以修改发往后端服务器的请求头,让后端了解前端的真实信息,当存在多层代理的时候,合理的配置可以让信息更漂亮。比如,这边的nginx3的realip其实是有问题的,我想聪明的你应该已经找到解决办法了。



                    部分内容摘自网络,如有侵权,请联系作者删除。

                    文章转载自爱可可的人生记录仪,如果涉嫌侵权,请发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。

                    评论