HTTP源地址获取规范

HTTP源地址获取规范代理和获取规范原则F5第一层代理,Nginx作为第二层代理,最终到web应用,如示例:F5->Nginx->Web第一层代理需要把源IP设置到X-Real-IP,二级代理需把一级代理地址写入X-Forwarded-For名词解释X-Real-IP:自定义请求头中字段X-Fo

大家好,欢迎来到IT知识分享网。HTTP源地址获取规范

  1. 代理和获取规范

    • 原则

      1. F5第一层代理,Nginx作为第二层代理,最终到web应用,如示例:F5->Nginx->Web
      2. 第一层代理需要把源IP设置到X-Real-IP,二级代理需把一级代理地址写入X-Forwarded-For
    • 名词解释

      1. X-Real-IP: 自定义请求头中字段
      2. X-Forwarded-For:一个 HTTP 扩展头部,各大 HTTP 代理、负载均衡等转发服务广泛使用,并被写入 RFC 7239(Forwarded HTTP Extension)标准之中
    • 定义规范的背景

      1. X-Real-IP和X-Forwarded-For都可以被客户端随意伪造,但是自定义X-Real-IP只能存在一个值,X-Forwarded-For字段可以存在多个以逗号分割,代理服务器只能追加,不能确定源IP地址写入的具体顺序
      2. Remote Address 无法伪造,因为建立 TCP 连接需要三次握手,如果伪造了源 IP,无法建立 TCP 连接,更不会有后面的 HTTP 请求
      3. 基于以上2点,需要一级代理服务器把源IP写入X-Real-IP,各级代理需把上级代理地址写入X-Forwarded-For中,追踪代理调用链
    • F5地址转换规范

      1. 在F5配置界面中,把源 IP写入参数: X-Real-IP
    • Nginx地址转换配置模板:

      Nginx配置
      server {
             
      # 监听端口
             
      listen        7777;
             
      server_name   localhost;
             
      charset           utf-8;
             
      location /{
                 
      # 转发地址
                 
      proxy_pass  http://10.19.205.58:7777;
                 
      proxy_set_header Host $host;
                 
      # 只有一层代理时候开启,源地址放入X-Real-Ip
                 
      # proxy_set_header X-Real-IP $remote_addr;
                 
      # Nginx作为代理必须开启,源地址和代理服务器代理地址放入X-Forwarded-For字段
                 
      proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
             
      }
         
      }

    • java代码获取源地址

      public
      String getRealIp(HttpServletRequest request){
              
      // 1. 获取真实地址
              
      String realIp = request.getHeader(
      "X-Real-IP"
      );
              
      // 2. 非正常地址或者异常调用
              
      if
      (isIlegalHost(realIp)) {
                  
      // 2.1 获取X-Forwarded-For地址组
                  
      String forwardIps= request.getHeader(
      "X-Forwarded-For"
      );
                  
      if
      (forwardIps !=
      null
      ){
                      
      String[] forwardIpArray =  forwardIps.split(
      ","
      );
                      
      // 2.2 循环X-Forwarded-For 的地址,返回第一个正常的地址
                      
      for
      (String forwardIp : forwardIpArray){
                          
      if
      (!isIlegalHost(forwardIp)){
                              
      return
      forwardIp;
                          
      }
                      
      }
                  
      }
                  
      //2.3 X-Forwarded-For不存在正常地址,则取远程地址
                  
      realIp = request.getRemoteAddr();
                  
      // 防止Nginx和web同一台无法获取地址
                  
      if
      (
      "127.0.0.1"
      .equals(realIp)) {
                      
      try
      {
                          
      // 2.4 如果是本机,则尝试获取网卡配置的IP
                          
      realIp = InetAddress.getLocalHost().getHostAddress();
                      
      }
      catch
      (UnknownHostException e) {}
                  
      }
              
      }
              
      return
      realIp;
          
      }
       
          
      public
      boolean
      isIlegalHost(String ip){
              
      if
      (ip ==
      null
      || ip.length() ==
      0
      ||
      "unknown"
      .equalsIgnoreCase(ip)) {
                  
      return
      true
      ;
              
      }
              
      return
      false
      ;
          
      }

2.场景分析

      1. 场景一:Nginx->Web;F5->Web

        1. F5只需界面操作,配置源地址写入:X-Real-IP
        2. Nginx配置

          server {
              
          # 监听端口
              
          listen        7777;
              
          server_name   localhost;
              
          charset           utf-8;
              
          location /{
                  
          # 转发地址
                  
          proxy_pass  http://10.19.205.58:7777;
                  
          proxy_set_header Host $host;
                  
          # 源地址放入X-Real-Ip
                  
          proxy_set_header X-Real-IP $remote_addr;
                  
          # 调用地址增加到X-Forwarded-For字段
                  
          proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
              
          }
          }

        3. 实例结果:

          # 访问路径:http:
          //10.19.205.60:7777/express
          # 客户端地址:
          10.20
          .
          23.50
          # Nginx地址:
          10.19
          .
          205.60
          # web应用地址:
          10.19
          .
          205.58
          # 代码:request.getRemoteAddr()+
          "|"
          +request.getHeader(
          "X-Real-IP"
          )+
          "|"
          + request.getHeader(
          "X-Forwarded-For"
          )+
          "|"
          +getRealIp();
          # 返回结果:Remote Addr:
          10.19
          .
          205.60
                      
          X-Real-IP:
          10.20
          .
          23.50
                      
          X-Forwarded-For:
          10.20
          .
          23.50
                      
          getRealIp():
          10.20
          .
          23.50

        4. 异常情况分析
          1. 异常情况:直接调用web地址,解决方法:java示例代码行注释2
             

            # 返回结果:Remote Addr:10.20.23.50
                        
            X-Real-IP:null
                        
            X-Forwarded-For:null
                        
            getRealIp():10.20.23.50

             

      2. 场景二:F5->Nginx->Web

        1. F5只需界面操作,配置源地址写入:X-Real-IP

        2. Nginx配置:
          server {
              
          # 监听端口
              
          listen        7777;
              
          server_name   localhost;
              
          charset           utf-8;
              
          location /{
                  
          # 转发web应用地址
                  
          proxy_pass  http://10.19.205.58:7777;
                  
          proxy_set_header Host $host;
                  
          # F5调用地址增加到X-Forwarded-For字段
                  
          proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
              
          }
          }

        3. 实例结果:
          # 访问路径:http:
          //10.19.18.51:7777/express
          # 客户端地址:
          10.20
          .
          23.50
          # F5虚拟地址:
          10.19
          .
          18.51
          # Nginx地址:
          10.19
          .
          205.59
          # web应用地址:
          10.19
          .
          205.58
          # 代码:request.getRemoteAddr()+
          "|"
          +request.getHeader(
          "X-Real-IP"
          )+
          "|"
          + request.getHeader(
          "X-Forwarded-For"
          )+
          "|"
          +getRealIp();
          # 返回结果:Remote Addr:
          10.19
          .
          205.59
                      
          X-Real-IP:
          10.20
          .
          23.50
                      
          X-Forwarded-For:
          10.19
          .
          18.254
          (F5实际地址)
                      
          getRealIp():
          10.20
          .
          23.50

        4. 异常情况分析
          1. 异常情况一:直接调用nginx地址,解决方案:java示例代码行注释2

            # 返回结果:Remote Addr:
            10.19
            .
            205.59
                        
            X-Real-IP:
            null
                        
            X-Forwarded-For:
            10.20
            .
            23.50
                        
            getRealIp():
            10.20
            .
            23.50

          2. 异常情况二:直接调用web地址,解决方法:java示例代码行注释2.3

            # 返回结果:Remote Addr:
            10.20
            .
            23.50
                        
            X-Real-IP:
            null
                        
            X-Forwarded-For:
            null
                        
            getRealIp():
            10.20
            .
            23.50

      3. Nginx->Nginx->Web

        1. 第一层 Nginx配置:

          server {
           
          # 监听端口
           
          listen       
          7777
          ;
           
          server_name   localhost;
           
          charset           utf-
          8
          ;
           
          location /{
               
          # 转发web应用地址
               
          proxy_pass  http:
          //10.19.205.58:7777;
               
          proxy_set_header Host $host;
               
          # 源地址放入X-Real-Ip
               
          proxy_set_header X-Real-IP $remote_addr;
               
          # 调用地址增加到X-Forwarded-For字段
               
          proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
           
          }

        2. 第二层 Nginx配置:

          server {
              
          # 监听端口
              
          listen       
          7777
          ;
              
          server_name   localhost;
              
          charset           utf-
          8
          ;
              
          location /{
                  
          # 转发web应用地址
                  
          proxy_pass  http:
          //10.19.205.58:7777;
                  
          proxy_set_header Host $host;
                  
          # 第一层调用地址增加到X-Forwarded-For字段
                  
          proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
              
          }
          }

           

        3. 实例结果:

          # 访问路径:http:
          //10.19.205.69:7777/express
          # 客户端地址:
          10.20
          .
          23.50
          # 第一层Nginx地址:
          10.19
          .
          205.69
          # 第二层Nginx地址:
          10.19
          .
          205.59
          # web应用地址:
          10.19
          .
          205.58
          # 代码:request.getRemoteAddr()+
          "|"
          +request.getHeader(
          "X-Real-IP"
          )+
          "|"
          + request.getHeader(
          "X-Forwarded-For"
          )+
          "|"
          +getRealIp();
          # 返回结果:Remote Addr:
          10.19
          .
          205.59
                      
          X-Real-IP:
          10.20
          .
          23.50
                      
          X-Forwarded-For:
          10.20
          .
          23.50
          ,
          10.19
          .
          205.69
                      
          getRealIp():
          10.20
          .
          23.50

           

        4. 异常情况分析
          1. 异常情况一:直接调用第二层nginx地址,解决方案:java示例代码行注释2

            # 返回结果:Remote Addr:
            10.19
            .
            205.59
                        
            X-Real-IP:
            null
                        
            X-Forwarded-For:
            10.20
            .
            23.50
                        
            getRealIp():
            10.20
            .
            23.50

          2. 异常情况二:直接调用web地址,解决方法:java示例代码行注释2.3

            # 返回结果:Remote Addr:
            10.20
            .
            23.50
                        
            X-Real-IP:
            null
                        
            X-Forwarded-For:
            null
                        
            getRealIp():
            10.20
            .
            23.50

             

免责声明:本站所有文章内容,图片,视频等均是来源于用户投稿和互联网及文摘转载整编而成,不代表本站观点,不承担相关法律责任。其著作权各归其原作者或其出版社所有。如发现本站有涉嫌抄袭侵权/违法违规的内容,侵犯到您的权益,请在线联系站长,一经查实,本站将立刻删除。 本文来自网络,若有侵权,请联系删除,如若转载,请注明出处:https://yundeesoft.com/32276.html

(0)

相关推荐

发表回复

您的电子邮箱地址不会被公开。 必填项已用 * 标注

关注微信