[squid-dev] form PROXY header for cache_peer requests

Alex Rousskov rousskov at measurement-factory.com
Thu Apr 16 13:45:40 UTC 2026


On 2026-04-16 07:51, Anthony Pankov wrote:

> I didn't find how to instruct Squid to form PROXY header for request
> going to parent cache_peer.


Official Squid code does not support PROXY protocol on cache_peer 
connections. Factory has implemented the required changes, but the 
corresponding proxy_protocol_outgoing feature is currently stuck in 
Squid Project backlog. Squid core developers cannot find a way to 
collaborate on clearing that growing backlog, so there is no ETA.


> AI said: ... proxy-out option ...
There is no such option. FWIW, I have quoted current unofficial/draft 
documentation of the backlogged proxy_protocol_outgoing feature below.


HTH,

Alex.

 > proxy_protocol_outgoing
 >
> Determines which Squid-to-peer connections start with a PROXY protocol
> header and defines the composition of the PROXY protocol header sent.
> 
>         proxy_protocol_outgoing <header-field>... [if [!]<acl>...]
> 
> Squid makes the first decision to send a PROXY protocol header before
> selecting the next forwarding hop for the request. Thus, at the
> decision-making time, the origin server hostname is known, but the next
> hop details (e.g., cache_peer name and source/destination IP addresses of
> a Squid-to-peer connection) are unknown. The decision is remade every time
> Squid has to reforward the request to a different hop (e.g., another
> cache_peer).
> 
> When deciding, Squid checks proxy_protocol_outgoing directives in their
> configuration order. After an `if` clause matches, the corresponding PROXY
> protocol header configuration is used and no further directives are
> checked. A directive without the optional `if` clause always matches when
> checked. If no directives match, a PROXY protocol header is not sent.
> 
> For now, Squid only sends PROXY protocol v2 headers.
> 
> For now, Squid does not reuse idle persistent connections for
> transactions matching a proxy_protocol_outgoing rule. In other words,
> a proxy_protocol_outgoing match guarantees that Squid will open a
> fresh connection to the peer even when there are suitable idle
> persistent connections available for communicating with that peer. >
> For now, PROXY protocol header is sent unencrypted, even for
> connections to TLS origin servers and cache_peers with "tls" option.
> This allows some network services to extract PROXY protocol header
> information before switching to forwarding of encrypted bytes. Future
> enhancements may support optional encryption of PROXY protocol bytes.
> 
> Depending on request routing rules, it may be difficult to configure Squid
> to send different PROXY protocol headers to different cache_peers because
> forwarding route selection happens after PROXY protocol header generation.
> To accommodate more use cases, we may have to delay PROXY protocol
> header-generation/sending decision until after the next hop selection.
> 
> When opening a CONNECT tunnel through a cache_peer, Squid sends the
> PROXY protocol header before sending CONNECT request. PROXY protocol
> header bytes and CONNECT request header bytes may share the same TCP
> packet.
> 
> Normally, Squid sends a "PROXY" command, but when sending a request
> generated internally by Squid (instead of forwarding a request received
> from a client), Squid sends a "LOCAL" command and ignores (i.e. does not
> 
> TLV values as opaque strings. A configured logformat value of "-" and an
> evaluated format value of "-" are not treated specially -- Squid sends a
> TLV field with a dash value.
> 
> Squid failure to "compile" a configured TLV format specification is a
> fatal configuration error (e.g., 239="%"). If a TLV value cannot be
> computed at header construction time or the computed value exceeds 65535
> bytes in length, Squid does not send the affected field and records a
> level-1 WARNING to cache.log.
> 
> Squid does not yet support sending well-known TLVs like PP2_TYPE_CRC32C.
> 
> Optional TLVs are sent in the order they are specified by this directive.
> Using one TLV type multiple times is allowed, but identical (at
> configuration interpretation time, before logformat %code substitution)
> type=value entries lead to fatal configuration errors.
> 
> Details that apply to both address block fields and TLVs:
> 
> Header field values (i.e. logformat format specifications) must be quoted
> using "double quotes". Squid removes quotes before using the quoted value.
> 
> Logformat evaluation is subject to log_uses_indirect_client directive. In
> most cases, Squid-to-peer connection and response-related details are not
> available during this evaluation because Squid has not opened the
> corresponding connection to the peer yet.
> 
> Example:
> 
>         acl toPeerThatExpectsConnectionTags dstdomain -n example.com
>         proxy_protocol_outgoing \
>             src_addr="%>a" \
>             dst_addr="::" \
>             src_port="%>p" \
>             dst_port="-" \
>             224="%proxy_protocol::>h{224}" \
>             225="%note{myConnectionTag_}" \
>             239="" \
>             if toPeerThatExpectsConnectionTags
> 
> This clause only supports fast acl types.
> See https://wiki.squid-cache.org/SquidFaq/SquidAcl for details.



More information about the squid-dev mailing list