• haproxy透明代理验证


    一、代理协议简介

    代理协议即 PROXY protocol, 是 haproxy 的作者 Willy Tarreau 于 2010 年开发和设计的一个 Internet 协议,通过为 tcp 添加一个很小的头信息,来方便的传递客户端信息(协议栈、源 IP、目的 IP、源端口、目的端口等),在网络情况复杂又需要获取客户 IP 时非常有用。如:

    • 多层 NAT 网络
    • TCP 代理(四层)或多层 tcp 代理
    • https 反向代理 http (某些情况下由于 Keep-alive 导致不是每次请求都传递 x-forword-for)

    代理协议分为 v1 和 v2 两个版本,v1 人类易读,v2 是二进制格式,方便程序处理。Proxy protocol 是比较新的协议,但目前已经有很多软件支持,如 haproxy、nginx、apache、squid、mysql 等等,要使用 proxy protocol 需要两个角色 sender 和 receiver,sender 在与 receiver 之间建立连接后,会先发送一个带有客户信息的 tcp header, 因为更改了 tcp 协议,需 receiver 也支持 proxy protocol,否则不能识别 tcp 包头,导致无法成功建立连接。

    https://www.haproxy.com/blog/haproxy/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 cmd
    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反向代理mysql验证tcp协议的透明代理

    haproxy配置

    # Configuration for wuzstest
    global
        daemon
        user nobody
        group haproxy
        log /dev/log local0 debug alert
        log /dev/log local1 notice alert
        stats socket /var/lib/neutron/lbaas/v2/0908ffd2-23ed-408b-ab30-46b3cb548785/haproxy_stats.sock mode 0666 level user
    defaults
        log global
        retries 3
        option redispatch
        timeout connect 5000
        timeout client 50000
        timeout server 50000
    frontend 85e95497-3708-4712-bb50-265eb0a794b3
        option tcplog
        maxconn 2000
        bind 192.168.88.16:3307
        mode tcp
        default_backend 8081356a-1048-4b30-b1a9-81b29898a363
    backend 8081356a-1048-4b30-b1a9-81b29898a363
        mode tcp
        balance roundrobin
        server 3b5c2019-d2a1-4b7d-b2db-a591b110c21e 192.168.88.11:3307 weight 1 send-proxy
        server 8dfb5733-3336-466c-a92d-827b703daf50 192.168.88.15:3307 weight 1 send-proxy
        server ffbd967e-eaaa-4be8-9f31-e6d052c8794a 192.168.88.5:3307 weight 1 send-proxy
    

    nginx配置

    user nginx;
    worker_processes auto;
    error_log /var/log/nginx/error.log;
    pid /run/nginx.pid;
    include /usr/share/nginx/modules/*.conf;
    events {
        worker_connections 1024;
    }
    http {
        log_format  main  '$proxy_protocol_addr - $remote_addr - $remote_user [$time_local] "$request" '
                          '$status $body_bytes_sent "$http_referer" '
                          '"$http_user_agent" "$http_x_forwarded_for"';
    
        access_log  /var/log/nginx/access.log  main;
        sendfile            on;
        tcp_nopush          on;
        tcp_nodelay         on;
        keepalive_timeout   65;
        types_hash_max_size 2048;
    
        include             /etc/nginx/mime.types;
        default_type        application/octet-stream;
        include /etc/nginx/conf.d/*.conf;
    
        server {
            listen       80 default_server proxy_protocol;
            server_name  _;
            root         /usr/share/nginx/html;
            include /etc/nginx/default.d/*.conf;
    
            location / {
            }
            error_page 404 /404.html;
            location = /404.html {
            }
            error_page 500 502 503 504 /50x.html;
            location = /50x.html {
            }
        }
    }
    stream {
    log_format proxy '$proxy_protocol_addr -- $remote_addr [$time_local] '
                     '$protocol $status $bytes_sent $bytes_received '
                     '$session_time "$upstream_addr" '
                     '"$upstream_bytes_sent" "$upstream_bytes_received" "$upstream_connect_time"';
        access_log /var/log/nginx/tcp-access.log proxy ;
    server {
           listen 3307   proxy_protocol;
           proxy_pass db;
        }
        upstream db {
           server localhost:3306;
        }
    }
    

    配置文件主要注意2部分

    1.日志格式log_format proxy,添加$proxy_protocol_addr

    2.监听添加代理协议支持,listen 3307 proxy_protocol;

    测试结果:

    四、http协议监听的透明代理

    haproxy配置

    # Configuration for 测试http
    global
        daemon
        user nobody
        group haproxy
        log /dev/log local0 debug alert
        log /dev/log local1 notice alert
        stats socket /var/lib/neutron/lbaas/v2/9863eccc-93f9-4cdd-99f8-60add1b7b0c1/haproxy_stats.sock mode 0666 level user
    defaults
        log global
        retries 3
        option redispatch
        timeout connect 5000
        timeout client 50000
        timeout server 50000
    frontend 38e3ce31-2c64-4d78-bbc7-f4319198fc5a
        option tcplog
        maxconn 2000
        option forwardfor
        bind 192.168.88.19:80
        mode http
        default_backend 67c28ff7-7782-484f-a5ca-84800c8a3837
    backend 67c28ff7-7782-484f-a5ca-84800c8a3837
        mode http
        balance roundrobin
        cookie SRV insert indirect nocache
        timeout check 5s
        server 07d9f74e-1f19-4ee3-a441-6adff505b09d 192.168.88.15:80 weight 1 check inter 10s fall 3 cookie 07d9f74e-1f19-4ee3-a441-6adff505b09d send-proxy
        server 6ab8aac8-5bea-4a0d-b73a-1007935da3d6 192.168.88.5:80 weight 1 check inter 10s fall 3 cookie 6ab8aac8-5bea-4a0d-b73a-1007935da3d6 send-proxy
        server dd5d3b4b-763a-49cd-8a5c-40ff19d69dcf 192.168.88.11:80 weight 1 check inter 10s fall 3 cookie dd5d3b4b-763a-49cd-8a5c-40ff19d69dcf send-proxy
    

    nginx配置:

    user nginx;
    worker_processes auto;
    error_log /var/log/nginx/error.log;
    pid /run/nginx.pid;
    include /usr/share/nginx/modules/*.conf;
    events {
        worker_connections 1024;
    }
    http {
        log_format  main  '$proxy_protocol_addr - $remote_addr - $remote_user [$time_local] "$request" '
                          '$status $body_bytes_sent "$http_referer" '
                          '"$http_user_agent" "$http_x_forwarded_for"';
    
        access_log  /var/log/nginx/access.log  main;
        sendfile            on;
        tcp_nopush          on;
        tcp_nodelay         on;
        keepalive_timeout   65;
        types_hash_max_size 2048;
    
        include             /etc/nginx/mime.types;
        default_type        application/octet-stream;
        include /etc/nginx/conf.d/*.conf;
    
        server {
            listen       80 default_server proxy_protocol;
            server_name  _;
            root         /usr/share/nginx/html;
            include /etc/nginx/default.d/*.conf;
    
            location / {
            }
            error_page 404 /404.html;
            location = /404.html {
            }
            error_page 500 502 503 504 /50x.html;
            location = /50x.html {
            }
        }
    }
    

    验证结果

    参考:https://www.nixops.me/articles/PROXY_protocol_pass_client_ip.html
    https://www.jianshu.com/p/cc8d592582c9

  • 相关阅读:
    一文带你快速认识“华为3D内容平台”!
    [论文解读] 阿里DIEN整体代码结构
    [论文阅读]阿里DIEN深度兴趣进化网络之总体解读
    [阿里DIN] 从论文源码学习 之 embedding层如何自动更新
    [阿里DIN]从论文源码学习 之 embedding_lookup
    [阿里DIN] 深度兴趣网络源码分析 之 整体代码结构
    [阿里DIN] 深度兴趣网络源码分析 之 如何建模用户序列
    aspell命令
    买卖股票的最佳时机含手续费
    grep命令
  • 原文地址:https://www.cnblogs.com/mrwuzs/p/13905821.html
Copyright © 2020-2023  润新知