HAProxy as loadbalancer for Squid

I’m new to HAProxy and fairly new to Squid, but I’ve seen that people seem to use HAProxy as a loadbalancer for Squid.

In my test environment I’ve got it working with Squid as forward proxy for a client, and I’ve got it working so that I can see in the HAProxy logs the websites I visit but it doesn’t seem to forward them to squid because I get “Can’t reach this page”.

HAproxy.cfg:

frontend proxy
        bind <IP of HAProxy>:8081

backend squidservers
        server squid01 <IP of SQUID>:8082 send-proxy-v2

Squid.conf:

http_port 8082 require-proxy-header
acl loadbalancers src <IP of HAProxy>
proxy_protocol_access allow loadbalancers

Client is configured with proxy: <IP of HAProxy>:8081
Squid logs (access.log) doesn’t show either IP of the client or the loadbalancer (haproxy).

HAproxy logs show:
2025-07-16T14:09:57.342989+02:00 haproxy01 haproxy[3706]: <IP of Client>:52333 [16/Jul/2025:14:09:57.342] proxy proxy/<NOSRV> -1/-1/-1/-1/0 503 216 - - SC-- 1/1/0/0/0 0/0 "CONNECT www.microsoft.com:443 HTTP/1.0"

What am I missing?

Is the loadbalancers ACL really correct?

Are you sure Squid support version 2 of the proxy protocol? Try not using v2 by using send-proxy instead of send-proxy-v2.

Not sure if the settings are correct, I based them on this link How configure HAProxy’s Proxy Protocol in Squid.

There’s no difference however when removing -v2 in the haproxy settings.

My understanding is that send-proxy-v2 makes it so that the squid server would see the client IP instead of the haproxy IP, but even when trying to simplify it and removing send-proxy entirely I still get the same issue: website not loading and squid logs not showing any hits for either IP.

One thing I’ve noticed is that when using http I get
"GET http://google.com/ HTTP/1.1"
while with https it says “CONNECT” instead, but maybe that’s normal behaviour?
"CONNECT google.com:443 HTTP/1.0"

Also, is it normal that it says “proxy proxy/<NOSRV>” in haproxy log?

You will have to share you complete haproxy config.

It’s the default settings for except for 3.2.3 except for those already mentioned.

global
        log /dev/log    local0
        log /dev/log    local1 notice
        chroot /var/lib/haproxy
        stats socket /run/haproxy/admin.sock mode 660 level admin
        stats timeout 30s
        user haproxy
        group haproxy
        daemon

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

        # See: https://ssl-config.mozilla.org/#server=haproxy&server-version=2.0.3&config=intermediate
        ssl-default-bind-ciphers ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384
        ssl-default-bind-ciphersuites TLS_AES_128_GCM_SHA256:TLS_AES_256_GCM_SHA384:TLS_CHACHA20_POLY1305_SHA256
        ssl-default-bind-options ssl-min-ver TLSv1.2 no-tls-tickets

defaults
        log     global
        mode    http
        option  httplog
        option  dontlognull
        timeout connect 5000
        timeout client  50000
        timeout server  50000
        errorfile 400 /etc/haproxy/errors/400.http
        errorfile 403 /etc/haproxy/errors/403.http
        errorfile 408 /etc/haproxy/errors/408.http
        errorfile 500 /etc/haproxy/errors/500.http
        errorfile 502 /etc/haproxy/errors/502.http
        errorfile 503 /etc/haproxy/errors/503.http
        errorfile 504 /etc/haproxy/errors/504.http


frontend proxy
        bind <IP of HAProxy>:8081

backend squidservers
        server squid01 <IP of SQUID>:8082 send-proxy-v2
        #server squid01 <IP of SQUID>:8082 id 2 weight 100 check port 8082 inter 4000 rise 2 fall 2 slowstart 8000 minconn 0 maxconn 0 on-marked-down shutdown-sessions send-proxy-v2 check-send-proxy

I’ve only got one NIC on the HAProxy server, would I need to have a separate for “normal”/management trafic and for the frontend?

I would suggest you switch to TCP mode.

mode http
mode httplog

mode tcp
mode tcplog

You really don’t need http mode in haproxy here.

If it doesn’t change anything, you will have to tcpdump the traffic between haproxy and squid. And please stick to send-proxy instead of send-proxy-v2 for now, even if it doesn’t fix your problem. There is no reason for v2 in your configuration and you don’t need binary encoding of the proxy protocol (which is what v2 does), especially when you need to troubleshoot on the wire.

Doesn’t seem to help. Only difference I noticed is when trying to visit a http site before changing we got

# 503 Service Unavailable
No server is available to handle this request.

and after changing to tcp we get Can’t reach this page like we did before for https as well.

You say setting tcp in haproxy doesn’t change anything, but just to make it clear we don’t have squid configured for https caching (https_port) right now, if that affects anything for haproxy.

Since there really isn’t much configuration needed in haproxy my guess is there is something wrong/missing in the squid conf?

Like I said, at this point you have to tcpdump the traffic between haproxy and squid and analyse it.

This is all that tcpdump provides, related to the https request.

11:44:21.337767 IP client.domain.local.53761 > haproxy.domain.local.tproxy: Flags [SEW], seq 3942403364, win 65535, options [mss 1460,nop,wscale 8,nop,nop,sackOK], length 0
11:44:21.337784 IP haproxy.domain.local.tproxy > client.domain.local.53761: Flags [S.], seq 218519462, ack 3942403365, win 64240, options [mss 1460,nop,nop,sackOK,nop,wscale 7], length 0
11:44:21.337913 IP client.domain.local.53761 > haproxy.domain.local.tproxy: Flags [.], ack 1, win 1024, length 0
11:44:21.337974 IP client.domain.local.53761 > haproxy.domain.local.tproxy: Flags [P.], seq 1:289, ack 1, win 1024, length 288
11:44:21.337978 IP haproxy.domain.local.tproxy > client.domain.local.53761: Flags [.], ack 289, win 501, length 0
11:44:21.338068 IP haproxy.domain.local.tproxy > client.domain.local.53761: Flags [F.], seq 1, ack 289, win 501, length 0
11:44:21.338151 IP client.domain.local.53761 > haproxy.domain.local.tproxy: Flags [.], ack 2, win 1024, length 0
11:44:21.338173 IP client.domain.local.53761 > haproxy.domain.local.tproxy: Flags [F.], seq 289, ack 2, win 1024, length 0
11:44:21.338179 IP haproxy.domain.local.tproxy > client.domain.local.53761: Flags [.], ack 290, win 501, length 0

The traffic between haproxy and squid is relevant, however the tcpdump only shows traffic between client and haproxy.

Never mind, found the issue. After adding default_backend squidservers to frontend proxy it started working, had missed adding that so it never forwarded to the backend.

1 Like