tomcat ip白名单(二)openshift无法同时支持http和https tunnel(http+tcp),方案一流产

1 openshift 背景,为什么项目二(http springboot用https域名访问)与项目一(双向ssl透传)可以共存

 

 

 

* edge - TLS termination is done by the router and http is used to communicate with the backend (default) * passthrough - Traffic is sent straight to the destination without the router providing TLS termination * reencrypt - TLS termination is done by the router and https is used to communicate with the backend

 

对于本身http的springboot,用edge,对于需要双向ssl的,用passthrough,让它原封不动传递tcp pack,像f5负载均衡

 

2.1 虚拟机暴露20000到外部,原服务为http springboot起在20001

2.2 用passthrough后再关掉tls

对http非CONNECT包,认定为原服务,把http流量转发到localhost 20001——内网外网均成功,通过浏览器访问http。。。成功

image

对http CONNECT包,认定为代理请求,拿下host和port保存在channelHandler——外网失败,内网成功

image

对tcp包,认定为代理请求后续包,转发——测不到,网关为http模式,即使CONNECT成功了,后续估计也会拦截了它认不出的tcp包

 

3 openshift和haproxy层面解决方案

3.0 原因

开passthough,http协议不支持,https可以访问原服务,代理CONNECT无反应

关https,https协议不支持,http可以访问原服务,https代理没反应,连CONNECT都没收到,第一层应该就被拦截了

推测为haproxy原生不支持connect协议,就像nginx要装一个东西 (正向代理

同时,开启https后,网关可能希望第一个包是ClientHello,而Connect没有这个 

 

3.1 实际需求一

https://stackoverflow.com/questions/62166972/is-there-a-way-to-use-a-forwarding-proxy-as-a-backend-including-authentication

Is there a way to use a forwarding proxy as a backend (including authentication) in HAProxy?

I am quite new to HAProxy and want to achieve the following setup / packet flow:

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

I would like to have encrypted connections with TLS/SSL from the Client -> HAProxy and from HAProxy -> server.example.com

This means, that the forwarding proxy needs to support the HTTP CONNECT method, to establish a TCP tunnel and transmits packets without trying to interpret them. Over this TCP port I should be able to send bytes to server.example.com - TLS/SSL encrypted, so HTTPS.

Furthermore it could be, that authentication against the forwarding proxy is needed e.g. HTTP Basic authentication.

The software stack of my test setup is as follows:

Client Firefox 76.0.1
HA-Proxy version 1.6.3 2015/12/25
Squid Cache: Version 3.5.27

I have setup this HAProxy configuration:

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

In my test setup I use a Squid server as a forwarding proxy with the following configuration:

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

Using the Squid forwarding proxy in a regular browser on the same subnet including authentication works fine.

So when the first request comes in from the Client at the HAProxy it gets forwarded via the backend backend-proxy to the Forward Proxy (Squid). The CONNECT succeeds, as I see in the Squid log.

1591166403.966  60146 192.168.1.10 TCP_TUNNEL/200 39 CONNECT server.example.com:443 test HIER_DIRECT/6.7.8.9 -

(IP addresses were replaced with generic values)

The HAProxy log shows, that the correct backend is used:

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 addresses were replaced with generic values)

So far so good. But I am unable to establish a successful communication to server.example.com from my Client. I think I have to use a second/other backend, which will not mangle the requests any more (exchange method and path) but instead use the given TCP port from the forwarding proxy to transmit the request.

How can I save the 'state' of the communication to my backend / proxy server in HAProxy, so the request could be resend to another backend?

How to extract and use the TCP port from the response of the Forwarding Proxy?

Is there a way to check, if the TCP tunnel on the Forwarding Proxy is still opened or do I need to request it using CONNECT every time before I want to use it?

EDIT: I solved the situation by using stunnel as an intermediary to handle the TCP tunnel creation with CONNECT against the Forwarding Proxy.

 

If you have an upstream HTTP proxy (like squid) (not a socks proxy) and you want to have haproxy accept connections and open the tunnel thru the upstream proxy (such that the haproxy clients do not support doing so themselves via http/CONNECT method) on behalf of the clients, then this functionality does not exist in haproxy today.

I crated a branch that does this via server keyword proxy-tunnel.

The below example config will behave such that clients of haproxy that connect to port 20025 (haproxy) will result in haproxy establishing a http/CONNECT tunnel via the upstream proxy 172.16.0.99:50443 to 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

 

 

3.2 另一个实例

https://blog.csdn.net/weixin_34062469/article/details/91523508

stunnel+haproxy SSL以及问题记录

最近在用stunnel做透明代理,配合haproxy做ssl方案,在用户和原有的反向代理之间加入stunnel,这样可以让用户和stunnel之间走ssl,stunnel之后的真实web就不用负担https的开销

首先先去stunnel官网上获取安装包,因为要给stunnel打haproxy的补丁,而haproxy官方提供的补丁目前版本是4.32的,所以stunnel选择4.32版本,官方提供的ftp上可以找

 

 

 

4 方案二

要自己在https的标准框架下实现CONNECT协议,key在于在双方握手的第一步中,把host和port拿到

 

 

 

 

 

两篇比较全的文章

https://halfrost.com/https-extensions/ HTTPS 温故知新(六) —— TLS 中的 Extensions

TLS 没有为 Client 提供一种机制来告诉 Server 它正在建立链接的 Server 的名称。Client 可能希望提供此信息以促进与在单个底层网络地址处托管多个“虚拟”服务的 Server 的安全连接。

当 Client 连接 HTTPS 网站的时候,解析出 IP 地址以后,就能创建 TLS 连接,在握手完成之前,Server 接收到的消息中并没有 host HTTP 的头部。如果这个 Server 有多个虚拟的服务,每个服务都有一张证书,那么此时 Server 不知道该用哪一张证书。

 

https://blog.csdn.net/xichenguan/article/details/81283029 HTTPS & TLS Extensions

 

 所以侵入点在哪儿,随机数,SNI,还是其他extensions?

 

5 remote addr做文章

 host显然不能伪造,不然直接突破4层白名单了

posted on 2023-10-17 00:08  silyvin  阅读(61)  评论(0编辑  收藏  举报