HA proxy upstream proxy support

Note: These are my notes during the creation of upstream proxy support, others in the HAProxy team have since picked up the work here.

The feature I have added to haproxy is to support opening a TCP tunnel to an upstream HTTP proxy which supports creating the tunnel on behalf of the client via http CONNECT method.

I have a working branch that works against an upstream squid proxy and runs in a serious production environment handling operations critical to people and business.

The configuration line would look like the following:

> server TEST_SERVERVIA_PROXY 172.16.0.2:2023 proxy-tunnel 172.16.0.99:50443

There are a few things I don’t need but happy to add if there is acceptance of this feature.

  1. Authentication support

  2. Stricter compliance with rfc7231 (Host field, response headers)

  3. Testing compatibility with proxy v1/v2 header flags

  4. Any other questions or suggestions from the haproxy people

  5. Identify performance improvement and potentially reusing the socks4 connection status flags

  6. Documentation

Why do I want this:

In my environment, There is a http proxy (squid) which is the only authorized egress to the internet and I have a legacy application that does not support making its own connections via a proxy. I want to “proxify” similar to the change that implemented socks4/5 proxy backend support. authorization is done on the upstream proxy.

I understand there are a dozen other ways to do this with tools like nc, socat, however haproxy is almost universally available, has service installation, good logging, statistics and management interface and a well understood and documented configuration language.

Is there a user led demand for this?

In 2020 a user posted this as yet unanswered on StackOverflow.

Implementation notes

The socks4 config line is the closes thing to what we want here.

socat
TCP4-LISTEN:2023,fork,reuseaddr, STDOUT
strace -e trace=network pproxy -l http+socks4+socks5://:50443/ -d -v

How does the socks4 config statement behave:

Observations from testing show that Telnet to 20025 will cause haproxy to open connection on 50443 There is no attempt to connect to 2023 (since I did not start a socks proxy on 50443) So the conifg statement can be read as Connect to 172.16.0.2:2023 VIA socks4 172.16.0.2:50443

listen SMTP-20025
   bind 0.0.0.0:20025
   mode tcp
   option tcplog
   maxconn 2000
   timeout connect 5000
   timeout client  50000
   timeout server  50000
   option tcp-check
   server SMTPS2_Via_SocksProxy1 172.16.0.2:2023 socks4 172.16.0.2:50443 check-via-socks4

TCP Packet structure:

\_ss_padding: (in the con-\> dst struct) First 2 byts is the port number (X7e7
= 2023) next 4 bytes is the ip (Xac100002 = 172.16.0.2)

> 07 e7 ac 10 00 02 00 00 00 00 00 00 00 00 │ ················ │ 00 00 00 00 00
> 00 00 00 00 00 00 00 00 00 00 00 │ ················ │ 00 00 00 00 00 00 00 00
> 00 00 00 00 00 00 00 00 │ ················ │ 00 00 00 00 00 00 00 00 00 00 00
> 00 00 00 00 00 │ ················ │ 00 00 00 00 00 00 00 00 00 00 00 00 00 00
> 00 00 │ ················ │ 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 │
> ················ │ 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 │
> ················ │ 00 00 00 00 00 00 00 00

Proxy:

strace -s1000 -v -e trace=network pproxy -l http+socks4+socks5://:2023/ -d -v

Dummy Server

python -m http.server 50443

Comments

comments powered by Disqus