Last updated: 2026-06-25
Squid TLS/SSL Configuration Guide
This guide provides recommended TLS/SSL settings for the Squid caching proxy. Squid can terminate HTTPS connections on the front end, encrypt connections to backend origin servers, and optionally intercept HTTPS traffic via SSL bumping.
Prerequisites
- Squid 7.0 or later (compiled with
--with-openssl); Squid 6 reached end of support in July 2025 - OpenSSL 1.1.1 or later
- A valid TLS certificate and private key
Verify Squid was built with TLS support:
squid -v 2>&1 | grep -- '--with-openssl'
HTTPS Termination
Listening on HTTPS
Configure Squid to accept HTTPS connections using https_port:
https_port 443 cert=/etc/squid/ssl/server.crt key=/etc/squid/ssl/server.key
TLS Protocol Versions
Restrict to TLS 1.2 and above:
https_port 443 \
cert=/etc/squid/ssl/server.crt \
key=/etc/squid/ssl/server.key \
tls-min-version=1.2 \
options=NO_SSLv3,NO_TLSv1,NO_TLSv1_1,NO_TICKET
Cipher Suites
Specify strong cipher suites. Note that TLS 1.3 cipher suites are managed by OpenSSL automatically and cannot be set via the cipher= option:
https_port 443 \
cert=/etc/squid/ssl/server.crt \
key=/etc/squid/ssl/server.key \
tls-min-version=1.2 \
cipher=ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305 \
options=NO_SSLv3,NO_TLSv1,NO_TLSv1_1,NO_TICKET
DH Parameters
Generate and configure DH parameters for forward secrecy. With an ECDHE-only cipher list (as recommended above) DH parameters are not used, but they are needed if you add any DHE ciphers:
openssl dhparam -out /etc/squid/ssl/dhparam.pem 2048
https_port 443 \
cert=/etc/squid/ssl/server.crt \
key=/etc/squid/ssl/server.key \
dhparams=/etc/squid/ssl/dhparam.pem \
tls-min-version=1.2 \
cipher=ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305 \
options=NO_SSLv3,NO_TLSv1,NO_TLSv1_1,NO_TICKET
Cache Peer TLS (Backend Encryption)
Encrypt connections to upstream origin servers or parent proxies:
cache_peer backend.example.com parent 443 0 \
tls \
sslcert=/etc/squid/ssl/client.crt \
sslkey=/etc/squid/ssl/client.key \
sslcafile=/etc/squid/ssl/ca-bundle.crt \
tls-min-version=1.2
For general origin server connections, set default TLS options:
tls_outgoing_options min-version=1.2 cipher=ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305 options=NO_SSLv3,NO_TLSv1,NO_TLSv1_1
Important: All
tls_outgoing_optionsparameters must be on a single line. Eachtls_outgoing_optionsline replaces the previous one entirely; splitting them across multiple lines causes only the last line to take effect.
HTTPS Interception (SSL Bump)
SSL bumping allows Squid to intercept, decrypt, and inspect HTTPS traffic. This requires generating certificates dynamically for each destination.
SSL bumping breaks end-to-end encryption. Use it only where required by policy and ensure clients trust the Squid CA certificate.
Certificate Authority Setup
Generate a CA certificate for dynamic certificate generation:
openssl req -new -newkey rsa:2048 -days 3650 -nodes -x509 \
-keyout /etc/squid/ssl/squidCA.key \
-out /etc/squid/ssl/squidCA.crt \
-subj "/CN=Squid Proxy CA"
Initialize the certificate database:
/usr/lib64/squid/security_file_certgen -c -s /var/lib/squid/ssl_db -M 64MB
chown squid:squid -R /var/lib/squid/ssl_db
Note: The path to security_file_certgen is /usr/lib64/squid/security_file_certgen on RHEL/CentOS and /usr/lib/squid/security_file_certgen on Debian/Ubuntu.
SSL Bump Configuration
# Dynamic certificate generation
# The helper binary is security_file_certgen (named ssl_crtd in Squid 3.x)
sslcrtd_program /usr/lib64/squid/security_file_certgen \
-s /var/lib/squid/ssl_db -M 64MB
# Intercept port
http_port 3129 intercept
https_port 3130 intercept ssl-bump \
cert=/etc/squid/ssl/squidCA.crt \
key=/etc/squid/ssl/squidCA.key \
generate-host-certificates=on \
dynamic_cert_mem_cache_size=16MB \
tls-min-version=1.2
# Bump rules
acl step1 at_step SslBump1
ssl_bump peek step1
ssl_bump bump all
Selective Bumping
Bypass bumping for specific domains (e.g., banking sites):
acl no_bump_sites ssl::server_name .bank.example.com .finance.example.com
ssl_bump splice no_bump_sites
ssl_bump peek step1
ssl_bump bump all
Mutual TLS (mTLS)
Standard TLS authenticates only the server. Mutual TLS adds client authentication, requiring the connecting client to also present a certificate. For Squid, mTLS appears in two directions: Squid presenting its own certificate to an upstream server (outbound mTLS, covered in Cache Peer TLS above), and Squid requesting certificates from clients connecting to the proxy itself (inbound mTLS).
For inbound client certificate verification on the HTTPS listener, add cafile= to the https_port options:
https_port 443 \
cert=/etc/squid/ssl/server.crt \
key=/etc/squid/ssl/server.key \
cafile=/etc/squid/ssl/client-ca.crt \
tls-min-version=1.2 \
options=NO_SSLv3,NO_TLSv1,NO_TLSv1_1,NO_TICKET
- cafile - CA certificate used to verify client certificates. When set, Squid requests and verifies a client certificate during the TLS handshake.
Squid's native support for strictly requiring client certificates (rejecting connections that don't present one) is limited compared to dedicated reverse proxies. If hard enforcement is needed, place Nginx or HAProxy in front of Squid to handle certificate validation and pass only verified traffic downstream.
See RFC 8446 ยง4.3.2 for the TLS Certificate Request specification, and Wikipedia: Mutual authentication for a general overview.
Complete Configuration
# HTTPS termination
https_port 443 \
cert=/etc/squid/ssl/server.crt \
key=/etc/squid/ssl/server.key \
dhparams=/etc/squid/ssl/dhparam.pem \
tls-min-version=1.2 \
cipher=ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305 \
options=NO_SSLv3,NO_TLSv1,NO_TLSv1_1,NO_TICKET
# HTTP port (redirect to HTTPS or for internal use)
http_port 3128
# Outgoing TLS settings (all parameters must be on one line)
tls_outgoing_options min-version=1.2 cipher=ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305 options=NO_SSLv3,NO_TLSv1,NO_TLSv1_1
# Access controls
acl localnet src 10.0.0.0/8 172.16.0.0/12 192.168.0.0/16
acl localnet src fc00::/7 fe80::/10
http_access allow localnet
http_access deny all
# Cache settings
cache_dir ufs /var/spool/squid 10000 16 256
maximum_object_size 256 MB
# Logging
access_log /var/log/squid/access.log squid
cache_log /var/log/squid/cache.log
Security Notes
The cipher suite and protocol configuration in this guide addresses the following known TLS vulnerabilities:
- POODLE (CVE-2014-3566, 2014): SSL 3.0 is disabled. TLS_FALLBACK_SCSV was added in OpenSSL 1.0.1j / 1.0.2 (October 2014); SSL 3.0 disabled by default in OpenSSL 1.1.0 (August 2016).
- BEAST (CVE-2011-3389, 2011): Mitigated by recommending TLS 1.2 as the minimum; AEAD-only ciphers eliminate the CBC padding oracle.
- CRIME (CVE-2012-4929, 2012): TLS compression is off by default in OpenSSL 1.1.0+; do not enable it.
- Lucky13 (2013): AEAD-only cipher list eliminates CBC padding timing side-channels entirely.
- FREAK (CVE-2015-0204, 2015): EXPORT-grade ciphers are excluded from the cipher string. Removed from OpenSSL 1.1.0 (August 2016).
- LOGJAM (CVE-2015-4000, 2015): Short-key DHE is excluded; only ECDHE key exchange is recommended.
- Sweet32 (CVE-2016-2183, 2016): 3DES is excluded from the cipher string.
- ROBOT (2017): Static RSA key exchange is excluded; only ECDHE is recommended.
- Downgrade attacks: TLS_FALLBACK_SCSV prevents protocol version rollback.
- Renegotiation injection (CVE-2009-3555, 2009): Secure renegotiation is enforced by default in OpenSSL 0.9.8m+; TLS 1.3 removes renegotiation entirely.
The following are not addressable through TLS configuration alone:
- Heartbleed (CVE-2014-0160, 2014): A memory disclosure bug in OpenSSL 1.0.1 through 1.0.1f. Fixed in OpenSSL 1.0.1g (April 7, 2014). Addressed by patching OpenSSL, not by TLS configuration.
- BREACH (CVE-2013-3587, 2013): Exploits HTTP-level response compression (gzip/deflate on responses). Mitigated at the application layer by disabling HTTP compression or using BREACH countermeasures; TLS configuration cannot prevent it.
- DROWN (CVE-2016-0800, 2016): Requires SSLv2 to be enabled on any server sharing the same private key. Ensure SSLv2 is disabled on all services that use the same certificate and key pair.
Verification
Test the configuration syntax:
squid -k parse
Start or reload Squid:
systemctl restart squid
Verify TLS is working:
openssl s_client -connect localhost:443 -tls1_2
openssl s_client -connect localhost:443 -tls1_3
Check the negotiated protocol and cipher:
echo | openssl s_client -connect localhost:443 2>/dev/null | grep -E 'Protocol|Cipher'
Test through the proxy:
curl -x https://proxy.example.com:443 https://www.example.com