Nginx 代理协议与SSL

Nginx 代理协议与SSL,nginx,haproxy,proxy-protocol,Nginx,Haproxy,Proxy Protocol,我有以下配置: HAProxy->NGinx->后端 (HAProxy用于负载平衡,NGinx用于SSL终止) 无法更改配置 我正在尝试使用代理协议将源IP传递到后端。 在没有SSL的情况下工作,一切正常。将SSL添加到等式中,要么SSL握手失败,要么我看不到让NGinx将代理协议传递到后端的方法 示例配置1: 代理协议在非ssl连接上传递良好,但对于ssl连接,ssl握手中断 HAProxy: listen HTTP-TCP_8090 bind :8090 server ng

我有以下配置:

HAProxy->NGinx->后端

(HAProxy用于负载平衡,NGinx用于SSL终止) 无法更改配置

我正在尝试使用代理协议将源IP传递到后端。 在没有SSL的情况下工作,一切正常。将SSL添加到等式中,要么SSL握手失败,要么我看不到让NGinx将代理协议传递到后端的方法

示例配置1:

代理协议在非ssl连接上传递良好,但对于ssl连接,ssl握手中断

HAProxy:

listen HTTP-TCP_8090
    bind :8090

    server nginx nginx:8090 send-proxy

listen HTTPS-TCP_8092
    bind :8092

    server nginx nginx:8092 send-proxy
listen HTTP-TCP_8090
    bind :8090

    server nginx nginx:8090 send-proxy

listen HTTPS-TCP_8092
    bind :8092

    server nginx nginx:8092 send-proxy
NGinx:

stream {
    upstream some_backend {
         server some_host:8090;
    }

    server {
        listen                8090;
        listen                8092 ssl;
        proxy_pass            some_backend;
        proxy_protocol        on;

        ssl_certificate       /etc/ssl/server.crt;
        ssl_certificate_key   /etc/ssl/server.key;
        ssl_protocols         SSLv3 TLSv1 TLSv1.1 TLSv1.2;
        ssl_ciphers           HIGH:!aNULL:!MD5;
        ssl_session_cache     shared:SSLTCP:20m;
        ssl_session_timeout   4h;
        ssl_handshake_timeout 30s;
    }
}
stream {
    upstream some_backend {
         server some_host:8090;
    }

    server {
        listen                8090 proxy_protocol;
        listen                8092 proxy_protocol ssl;
        proxy_pass            some_backend;

        ssl_certificate       /etc/ssl/server.crt;
        ssl_certificate_key   /etc/ssl/server.key;
        ssl_protocols         SSLv3 TLSv1 TLSv1.1 TLSv1.2;
        ssl_ciphers           HIGH:!aNULL:!MD5;
        ssl_session_cache     shared:SSLTCP:20m;
        ssl_session_timeout   4h;
        ssl_handshake_timeout 30s;
    }
}
示例配置2:

ssl和not这两种连接都可以正常工作,但在这两种情况下,代理协议头都不会传递到后端

HAProxy:

listen HTTP-TCP_8090
    bind :8090

    server nginx nginx:8090 send-proxy

listen HTTPS-TCP_8092
    bind :8092

    server nginx nginx:8092 send-proxy
listen HTTP-TCP_8090
    bind :8090

    server nginx nginx:8090 send-proxy

listen HTTPS-TCP_8092
    bind :8092

    server nginx nginx:8092 send-proxy
NGinx:

stream {
    upstream some_backend {
         server some_host:8090;
    }

    server {
        listen                8090;
        listen                8092 ssl;
        proxy_pass            some_backend;
        proxy_protocol        on;

        ssl_certificate       /etc/ssl/server.crt;
        ssl_certificate_key   /etc/ssl/server.key;
        ssl_protocols         SSLv3 TLSv1 TLSv1.1 TLSv1.2;
        ssl_ciphers           HIGH:!aNULL:!MD5;
        ssl_session_cache     shared:SSLTCP:20m;
        ssl_session_timeout   4h;
        ssl_handshake_timeout 30s;
    }
}
stream {
    upstream some_backend {
         server some_host:8090;
    }

    server {
        listen                8090 proxy_protocol;
        listen                8092 proxy_protocol ssl;
        proxy_pass            some_backend;

        ssl_certificate       /etc/ssl/server.crt;
        ssl_certificate_key   /etc/ssl/server.key;
        ssl_protocols         SSLv3 TLSv1 TLSv1.1 TLSv1.2;
        ssl_ciphers           HIGH:!aNULL:!MD5;
        ssl_session_cache     shared:SSLTCP:20m;
        ssl_session_timeout   4h;
        ssl_handshake_timeout 30s;
    }
}

你知道我该如何创建一个配置,它既能感知SSL连接上的代理协议,又能将头传递给后端吗?

好吧,看来NGinx文档不是很好

如果希望nginx接受代理协议,则需要在listen指令中添加proxy_protocol参数

listen 8090 proxy_protocol;
如果希望nginx发送代理协议,则需要在server部分中添加proxy_protocol指令

proxy_protocol on;
如果您希望nginx接受代理协议并在其另一端传递接受的头,则需要同时添加这两者! 听起来合乎逻辑,对吗?正确的。但它没有很好的记录。很容易理解,当处理非http的流量时,只需在服务器部分中设置proxy_protocol指令即可在连接的两端启用它。 最后,这是一个有效的配置:

stream {
    upstream some_backend {
         server some_host:8090;
    }

    server {
        listen                8090 proxy_protocol;
        listen                8092 proxy_protocol ssl;
        proxy_pass            some_backend;
        proxy_protocol        on;

        ssl_certificate       /etc/ssl/server.crt;
        ssl_certificate_key   /etc/ssl/server.key;
        ssl_protocols         SSLv3 TLSv1 TLSv1.1 TLSv1.2;
        ssl_ciphers           HIGH:!aNULL:!MD5;
        ssl_session_cache     shared:SSLTCP:20m;
        ssl_session_timeout   4h;
        ssl_handshake_timeout 30s;
    }
}

恩,看来NGinx文档不是很好

如果希望nginx接受代理协议,则需要在listen指令中添加proxy_protocol参数

listen 8090 proxy_protocol;
如果希望nginx发送代理协议,则需要在server部分中添加proxy_protocol指令

proxy_protocol on;
如果您希望nginx接受代理协议并在其另一端传递接受的头,则需要同时添加这两者! 听起来合乎逻辑,对吗?正确的。但它没有很好的记录。很容易理解,当处理非http的流量时,只需在服务器部分中设置proxy_protocol指令即可在连接的两端启用它。 最后,这是一个有效的配置:

stream {
    upstream some_backend {
         server some_host:8090;
    }

    server {
        listen                8090 proxy_protocol;
        listen                8092 proxy_protocol ssl;
        proxy_pass            some_backend;
        proxy_protocol        on;

        ssl_certificate       /etc/ssl/server.crt;
        ssl_certificate_key   /etc/ssl/server.key;
        ssl_protocols         SSLv3 TLSv1 TLSv1.1 TLSv1.2;
        ssl_ciphers           HIGH:!aNULL:!MD5;
        ssl_session_cache     shared:SSLTCP:20m;
        ssl_session_timeout   4h;
        ssl_handshake_timeout 30s;
    }
}

想知道Haproxy和Nginx之间是否存在连接池?据我所知,代理协议并不是试图将ip信息预先添加到每个数据包中。它只为每个连接预先设置ip,这意味着如果Haproxy和Nginx之间有连接池,Nginx将认为两个客户端来自同一ip,如果两个请求使用从Haproxy到Nginx的相同连接。你是如何解决这个问题的?我没有,因为这只是一个假设,连接池存在,在挖掘了一点之后,因为对于layer4代理,没有连接池,因为数据包没有解密。所以连接无法真正重用。想知道Haproxy和Nginx之间是否存在连接池?据我所知,代理协议并不是试图将ip信息预先添加到每个数据包中。它只为每个连接预先设置ip,这意味着如果Haproxy和Nginx之间有连接池,Nginx将认为两个客户端来自同一ip,如果两个请求使用从Haproxy到Nginx的相同连接。你是如何解决这个问题的?我没有,因为这只是一个假设,连接池存在,在挖掘了一点之后,因为对于layer4代理,没有连接池,因为数据包没有解密。所以连接不能被真正重用。