zoukankan      html  css  js  c++  java
  • 七层LB-NGINX 客户端获取协议Proxy Protocol介绍

    协议诞生背景

      在Web分布式系统中,一般会搭建复杂的load blance系统来提供高性能的web服务。

      7层的SLB 有基于nginx/淘宝变种tengine的。后端RS会无法获取真实客户端IP。

    为了解决此问题,HAProxy的作者Willy Tarreau于2010年开发和设计的一个Internet协议,通过为tcp添加一个很小的头信息,来方便的传递客户端信息(协议栈、源IP、目的IP、源端口、目的端口等),在网络情况复杂又需要获取用户真实IP时非常有用。其本质是在三次握手结束后由代理在连接中插入了一个携带了原始连接四元组信息的数据包。

    截止2018年10月份 proxy protocol有两个版本,v1仅支持human-readable报头格式(ASCIII码),v2需同时支持human-readable和二进制格式,即需要兼容v1格式。

    proxy protocol的接收端必须在接收到完整有效的 proxy protocol 头部后才能开始处理连接数据。因此对于服务器的同一个监听端口,不存在兼容带proxy protocol包的连接和不带proxy protocol包的连接。如果服务器接收到的第一个数据包不符合proxy protocol的格式,那么服务器会直接终止连接。

    协议实现

    在三次握手之后,会增加一个TCP payload包,包payload长度48字节。如图:

    示例,如下图所示的第四个包就是proxy protocol的包。

    proxy protocol 格式

    version 1 header

      • 每个字段中间为空格(x20)
    // PROXY AF L3_SADDR L3_DADDR L4_SADDR L4_DADDR
     
    PROXY TCP4 202.112.144.236 10.210.12.10 5678 80
    
    PROXY TCP6 2001:da8:205::100 2400:89c0:2110:1::21 6324 80
    
    PROXY UKNOWN
    

    version 2 header

      • 12字节的固定signature 
      • x0Dx0Ax0Dx0Ax00x0Dx0Ax51x55x49x54x0A
      • 4bits 协议版本号
      • x2 // v2
      • 4bits 
      • x0 // LOCAL
        x1 // PROXY
      • 4bits 地址族
      • x0 // AF_UNSPEC
        x1 // AF_INET
        x2 // AF_INET6
        x3 // AF_UNIX
      • 4bits transport protocol 
      • x0 // UNSPEC
        x1 // STREAM
        x2 // DGRAM
      • 2字节地址长度字段(网络字节序),指接下来剩余的报头长度

      • L3 S_ADDR

      • L3 D_ADDR

      • L4 S_ADDR (如果有)

      • L4 D_ADDR (如果有)

    Tips

      • 目前nginx的v2版本的读取只支持 cmd 为 PROXY,transport protocol 为 STREAM
      • v2版本支持了很多新特性,详情可参考官方文档(见reference)

    nginx proxy protocol 配置

    • 1.5.12 support accept for http
    • 1.9.3 support TCP write
    • 1.11.4 support accept for tcp
    • 1.13.11 support v2 read

    proxy protocol 插入配置

    stream {
    
        server {
            listen              12345;
    
            proxy_pass          backend.example.com:8080;
            proxy_protocol      on;
        }
    
    }

    proxy protocol 接收配置

    http {
        log_format elb_log '$proxy_protocol_addr';
    
        server {
    
            listen 8080 proxy_protocol;
            root /usr/local/nginx/html;
            index index.html index.htm;
    
            server_name hello-world.com;
            set_real_ip_from 192.168.10.0/24;
            real_ip_header  proxy_protocol;
        }
    
        location / {
            try_files $uri $uri/ /index.html;
    
            proxy_pass http://backend.example2.com:8088;
            proxy_set_header X-Forwarded-For $proxy_protocol_addr;
        }
    
        access_log /usr/local/nginx/stream.log elb_log;
    }
    参考协议发布者:https://www.haproxy.org/download/1.8/doc/proxy-protocol.txt
    参考NGINX:https://docs.nginx.com/nginx/admin-guide/load-balancer/using-proxy-protocol/
    参考简书:https://www.jianshu.com/p/cc8d592582c9
    参考:https://www.cnblogs.com/hugetong/p/10901359.html
  • 相关阅读:
    python3.6下安装wingIDE破解方法
    Python 列表list 和 字符串str 互转
    c# 读取txt文件并分隔
    基础连接已经关闭: 未能为 SSL/TLS 安全通道建立信任关系
    Jquery ajax动态更新下拉列表的内容
    vs2015使用技巧-------- 查看类关系图
    Dapper 批量操作sql
    Linq批量建表
    WebRequest的get及post提交
    git -- 常用命令
  • 原文地址:https://www.cnblogs.com/zhangmingda/p/12672588.html
Copyright © 2011-2022 走看看