Squid Proxy Leaking Your IP? Check HTTP Headers First
Cover Image

If an HTTP endpoint sees your client address in X-Forwarded-For, check Squid's forwarded_for setting. On supported versions, forwarded_for delete removes that header. Start by confirming where the address appears: the destination's request headers, its connection logs, or a response returned to your client.
Those are different observations. A changed exit IP doesn't prove that identifying headers are gone, and clean headers don't make a session anonymous. This guide focuses on diagnosing unintended address disclosure in a proxy you administer.
Key Takeaways
Test plain HTTP separately from HTTPS tunneling. Check your installed Squid version before changing directives. Compare destination-side observations before and after the change, and keep authentication and access controls intact.
Understand Which Traffic Squid Can Inspect
For an ordinary HTTP forward-proxy request, Squid processes the HTTP message and can alter its headers. For HTTPS carried through a normal CONNECT tunnel without TLS interception, the application request is encrypted between the client and destination. Squid cannot rewrite the headers inside that encrypted request.
This is why an HTTPS echo test alone cannot establish whether forwarded_for works for plain HTTP. A deployment using TLS interception has a different processing path and needs its own checks. Review the protocol behavior in RFC 9110's CONNECT section.
Also distinguish a client address from the proxy's public exit address. The destination normally sees the exit address as the connection source; that isn't evidence that Squid exposed the client's address.
Check Version and Configuration Before Editing
If you need the underlying setup first, see the Ubuntu proxy installation guide. For a pool, repeat these checks for each exit path configured in the Squid rotation guide.
The linked Squid references document these directives through version 7 and mark them unavailable in version 8. Confirm the documentation matches your installation. Don't paste this configuration into an unsupported release.
squid -v
systemctl cat squid
The first command reports version and build information. Inspect the service definition and any startup options to identify the configuration actually loaded, including a custom -f path. Back up that configuration before editing. The commands below assume an Ubuntu-style service named squid; adjust the service and configuration path for your installation.
Remove X-Forwarded-For on Supported Versions
Squid's forwarded_for reference distinguishes removing the header from replacing its value. Add this to the active configuration when removing the full chain is appropriate for your deployment:
forwarded_for delete
off substitutes unknown; it does not remove the header. transparent leaves an existing value unchanged, while truncate replaces the chain with the client's address. Neither is an alternative to deletion when the goal is to remove the field.
A parent proxy can add a new header later. Test at the final destination, not just at the first hop, and inspect every proxy in the chain if the address remains visible.
Treat Via and Other Headers Separately
Via describes intermediary handling; its presence alone doesn't establish a client-IP leak. Squid's via documentation lists a build requirement for changing this behavior. Disabling it affects protocol visibility and should not be described as having no side effects.
# Optional: only after reviewing build support and proxy-chain requirements.
via off
Use specific filtering only when observations show another request field contains unwanted information. The request_header_access reference covers outbound HTTP request fields and requires a compatible build. Removing arbitrary fields can break applications.
By contrast, reply_header_access changes responses going back to the client. Removing Server from a reply doesn't remove your client address from the request the origin already received. Diagnose that direction separately instead of treating every header as an outbound leak.
Validate, Apply, and Test Both Protocols
Parse the same configuration your service uses before applying changes. If parsing fails, fix the error first.
sudo squid -k parse && sudo systemctl reload squid
sudo systemctl status squid --no-pager
If the service uses a custom configuration, pass its path to the parse command with -f. Confirm that your service supports reload; otherwise follow its documented restart procedure. Check the logs for errors after applying the change.
Use an echo endpoint you control that records request headers and the connection source address. Set the variables below to your actual proxy and endpoint addresses. These examples assume the proxy is reachable over a trusted connection. An HTTP proxy connection does not encrypt proxy authentication credentials.
# Set these to your own endpoints before running the tests.
PROXY_URL='http://127.0.0.1:3128'
PROXY_USER='testuser'
HTTP_ECHO_URL='http://echo.example.test/headers'
HTTPS_ECHO_URL='https://echo.example.test/headers'
# Direct HTTP baseline; explicitly bypass proxy environment settings.
curl --noproxy '*' --fail --show-error "$HTTP_ECHO_URL"
# Proxied HTTP; curl prompts for the proxy user's password.
curl --noproxy '' --proxy "$PROXY_URL" --proxy-user "$PROXY_USER" \
--fail --show-error "$HTTP_ECHO_URL"
# Separate HTTPS CONNECT test.
curl --noproxy '' --proxy "$PROXY_URL" --proxy-user "$PROXY_USER" \
--fail --show-error "$HTTPS_ECHO_URL"
The example.test names are placeholders and will not resolve to a working echo service. Keep sensitive cookies, tokens, and production data out of diagnostic requests. If your proxy uses source-address access controls rather than user authentication, omit the proxy-user option.
For the proxied HTTP request, check that X-Forwarded-For is absent at the controlled origin after deletion. Record the connection source separately. For HTTPS, verify the tunnel's exit address and check whether the client application itself supplied identifying headers. Don't interpret an echo service's own load-balancer headers as proof of what Squid sent.
If Your Address Still Appears
First confirm that the request reached Squid by inspecting its access log. Then check the active configuration path, reload errors, and parent proxies. Inspect client-supplied fields such as Forwarded or X-Real-IP rather than assuming every address comes from X-Forwarded-For.
For normal HTTPS tunnels, investigate the client or other TLS-terminating components if an application header exposes the address. Squid cannot delete a field it cannot decrypt. If another proxy product is in the path, use its own version-specific documentation instead of assuming Squid directives apply.
Finally, keep the result narrow: a successful test shows what that endpoint observed for that request. Accounts, cookies, application identifiers, and network behavior remain separate sources of identification. Repeat the protocol-specific checks after configuration or version changes.
