ssl - 有没有办法在 HAProxy 中使用转发代理作为后端(包括身份验证)?

标签 ssl proxy haproxy

我对 HAProxy 很陌生,想实现以下设置/数据包流:

Client -> HAProxy (as reverse proxy) -> Forwarding Proxy (HAProxy, IIS, Squid...) -> Internet -> server.example.com


我想从 Client -> HAProxy 使用 TLS/SSL 进行加密连接来自 HAProxy -> server.example.com这意味着,转发代理需要支持 HTTP CONNECT 方法,以建立 TCP 隧道并传输数据包而不尝试解释它们。通过这个 TCP 端口,我应该能够向 server.example.com 发送字节。 - TLS/SSL 加密,所以 HTTPS。
此外,可能需要针对转发代理的身份验证,例如HTTP 基本身份验证。
我的测试设置的软件堆栈如下:
Client Firefox 76.0.1
HA-Proxy version 1.6.3 2015/12/25
Squid Cache: Version 3.5.27
我已经设置了这个 HAProxy 配置:
global
        # Standard settings                                                                                                                                                                                        
        log /dev/log    local0
        log /dev/log    local1 notice
        chroot /var/lib/haproxy
        user haproxy
        group haproxy
        daemon

        # Tuning                                                                                                                                                                                                   
        maxconn 2000

        # Default SSL material locations                                                                                                                                                                           
        ca-base /etc/ssl/certs
        crt-base /etc/ssl/private

        ssl-default-bind-options no-sslv3

        # Ensure a secure enough DH paramset                                                                                                                                                                       
        tune.ssl.default-dh-param 2048


defaults
        log     global
        mode    http
        option  httplog
        option  dontlognull
        # Redispatch 503 errors on backends, reducing the number of 503 reaching clients                                                                                                                           
        option  redispatch
        # We want to stall clients for as long as possible, before giving                                                                                                                                          
        # up with 503:                                                                                                                                                                                             
        timeout connect 5m
        # Clients must be acceptably responsive                                                                                                                                                                    
        timeout client  1m
        # Server not as much...                                                                                                                                                                                    
        timeout server  5m


# HTTPS server                                                                                                                                                                                                     

frontend https-in                      
        bind :443 ssl crt-ignore-err all crt /etc/haproxy/ssl/certkey.pem

        # Don't serve HTTP directly, but redirect to same URL in https                                                                                                                                             
        redirect scheme https code 301 if !{ ssl_fc }

        default_backend backend-proxy

backend backend-proxy
        # Create the Authorization / Proxy-Authorization header value                                                                                                                                              
        # echo -n "user:password" | base64                                                                                                                                                                         

        http-request add-header Proxy-Authorization "Basic dXNlcjpwYXNzd29yZA=="
                                                                                                                                                                         
        # We need to use the CONNECT method                                                                                                                                                                        
        http-request set-method CONNECT

        # The proxyserver needs to know the full server name                                                                                                                                                       
        http-request set-path server.example.com:443

        server proxy 192.168.1.1:8080

在我的测试设置中,我使用 Squid服务器作为转发代理,配置如下:
acl SSL_ports port 443

acl Safe_ports port 80          # http
acl Safe_ports port 443         # https

acl CONNECT method CONNECT

http_access deny !Safe_ports
http_access deny CONNECT !SSL_ports
http_access allow localhost manager
http_access deny manager
http_access allow localhost

auth_param basic program /usr/lib/squid3/basic_ncsa_auth /etc/squid/squid-passwd
acl basic_client proxy_auth REQUIRED
http_access deny !basic_client
http_access allow basic_client
http_access deny all

http_port 8080

coredump_dir /var/spool/squid
使用 Squid在同一子网上的常规浏览器中转发代理,包括身份验证工作正常。
所以当第一个请求来自 ClientHAProxy它通过 backend backend-proxy 转发到Forward Proxy (Squid) . CONNECT 成功,正如我在 Squid 中看到的那样日志。
1591166403.966  60146 192.168.1.10 TCP_TUNNEL/200 39 CONNECT server.example.com:443 test HIER_DIRECT/6.7.8.9 -
(IP 地址被替换为通用值)HAProxy日志显示,使用了正确的后端:
Jun  3 08:39:57 localhost haproxy[3547]: 192.168.1.20:39398 [03/Jun/2020:08:38:56.855] https-in~ backend-proxy/proxy 154/0/13/209/60375 200 39 - - ---- 0/0/0/0/0 0/0 "GET /someurl HTTP/1.1"
(IP 地址被替换为通用值)
到目前为止,一切都很好。但是我无法与 server.example.com 建立成功的通信。来自我的Client .我想我必须使用第二个/其他后端,它不会再破坏请求(交换 methodpath ),而是使用转发代理的给定 TCP 端口来传输请求。
如何将通信的“状态”保存到 HAProxy 中的后端/代理服务器,以便可以将请求重新发送到另一个后端?
如何从 Forwarding Proxy 的响应中提取和使用 TCP 端口?
有没有办法检查 Forwarding Proxy 上的 TCP 隧道仍处于打开状态,或者我需要使用 CONNECT 请求它吗?每次之前我都想使用它?
编辑:
我通过使用 stunnel 解决了这种情况作为中间人使用 CONNECT 针对转发代理处理 TCP 隧道创建。

最佳答案

如果您有上游 HTTP 代理(如 squid)(不是 socks 代理)并且您希望 haproxy 接受连接并通过上游代理打开隧道(这样 haproxy 客户端不支持通过 http/CONNECT 方法自己这样做) 代表客户,那么今天的 haproxy 中不存在此功能。
我装了一个 branch通过服务器关键字 proxy-tunnel 执行此操作.
下面的示例配置将表现为连接到端口 20025 的 haproxy 客户端(haproxy) 将导致 haproxy 通过上游代理 172.16.0.99:50443 建立 http/CONNECT 隧道至172.16.0.2:2023 :

listen SMTP-20025
    bind 0.0.0.0:20025
    server TEST_SERVERVIA_PROXY 172.16.0.2:2023 proxy-tunnel 172.16.0.99:50443

关于ssl - 有没有办法在 HAProxy 中使用转发代理作为后端(包括身份验证)?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/62166972/

相关文章:

java - tomcat如何知道提供哪个证书

html - IE8 代理 CSS 兼容性

java - 使用Java SDK 0.9.7通过代理服务器连接到Azure服务总线

sockets - HAProxy 无法启动,无法绑定(bind) UNIX 套接字 [/run/haproxy/admin.sock]

url-rewriting - 根据 Haproxy 中的路径重定向到新域

xmpp - 是否可以使用私钥解密我的 XMPP 服务器流量?

ssl - 如何从 keystore.jks 和 truststore.jks 文件创建证书

ssl - SSL/TLS 客户端对没有 DN 的证书请求消息的正确响应?

bash - 使用镜像 URL 自动替换 URL

apache - Haproxy "send-proxy"未知协议(protocol)——不是说 SSL 到 HTTPS 端口吗?