Feature: Squid-in-the-middle SSL Bump
Goal: Enable ICAP inspection of SSL traffic.
Developer: AlexRousskov, Christos Tsantilas
Squid-in-the-middle decryption and encryption of straight CONNECT and transparently redirected SSL traffic, using configurable CA certificates. While decrypted, the traffic can be analyzed, blocked, or adapted using regular Squid features such as ICAP and eCAP.
By default, most user agents will warn end-users about a possible man-in-the-middle attack.
WARNING: HTTPS was designed to give users an expectation of privacy and security. Decrypting HTTPS tunnels without user consent or knowledge may violate ethical norms and may be illegal in your jurisdiction. Squid decryption features described here and elsewhere are designed for deployment with user consent or, at the very least, in environments where decryption without consent is legal. These features also illustrate why users should be careful with trusting HTTPS connections and why the weakest link in the chain of HTTPS protections is rather fragile. Decrypting HTTPS tunnels constitutes a man-in-the-middle attack from the overall network security point of view. Attack tools are an equivalent of an atomic bomb in real world: Make sure you understand what you are doing and that your decision makers have enough information to make wise choices.
Squid becomes responsible for handling server certificate validation errors
When an HTTP client receives the invalid origin server certificate it can use agent features to handle validation errors. For example, many browsers warn and allow the user to examine the invalid certificate and optionally ignore the error for this or even future connections.
This powerful functionality is currently not available because Squid makes the ultimate decision on whether to ignore the validation error. The HTTP client always receives a valid certificate generated by Squid and not the invalid certificate from the origin server. We are considering adding code to mimic server certificate errors when generating a fake certificate, giving back the user an option to examine and bypass the error. Quality patches or sponsorships are welcomed.
Here is a sample squid.conf excerpt with SSL Bump-related options:
Enabling SSL Bump
Example of how to configure the HTTP port to bump CONNECT requests
http_port 3128 ssl-bump cert=/usr/local/squid3/etc/site_priv+pub.pem # Bumped requests have relative URLs so Squid has to use reverse proxy # or accelerator code. By default, that code denies direct forwarding. # The need for this option may disappear in the future. always_direct allow all
ssl_bump is used to prevent some requests being bumped.
acl broken_sites dstdomain .example.com ssl_bump deny broken_sites ssl_bump allow all
acl broken_sites dstdomain .example.com ssl_bump none broken_sites ssl_bump client-first all
However Squid-3.3 and later provide the server-first algorithm which can be used in place of client-first in the above rules and is better for bumping HTTPS as it avoided the problems below.
Certain certificate errors may occur which are not really problems. Such as an internal site with self-signed certificates, or an internal domain name for a site differing from its public certificate name.
Squid-3.3 and later
The server-first bumping algorithm with certificate mimicing allows Squid to transparently pass on these flaws to the client browser for a more accurate decision about safety to be made there.
The sslproxy_cert_error directive and the ssl_error ACL type allow these domains to be accepted despite the certificate problems.
SECURITY WARNING: ignoring certificate errors is a security flaw. Doing it in a shared proxy is an extremely dangerous action. It should not be done lightly or for domains which you are not the authority owner (in which case please try fixing the certificate problem before doing this).
Allow access to website sending bad certificates
# ignore errors with certain cites (very dangerous!) acl TrustedName url_regex ^https://weserve.badcerts.example.com/ sslproxy_cert_error allow TrustedName sslproxy_cert_error deny all
Allow access to websites attempting to use certificates belonging to another domain.
# ignore certain certificate errors (very dangerous!) acl BadSite ssl_error SQUID_X509_V_ERR_DOMAIN_MISMATCH sslproxy_cert_error allow BadSite sslproxy_cert_error deny all
Warning: Unlike the rest of this page at the time of writing, this section applies to Squid-3.3 and possibly later code capable of dynamic SSL certificate generation and origin server certificate mimicking. The current section text is intended primarily for developers and early adopters facing excessive memory consumption in certain SslBump environments. These notes may be relocated elsewhere if a better location is found.
Current documentation is specific to bump-server-first configurations.
Squid talking to SSL clients
If generate-host-certificates is "on" (which it is by default for ssl-bump http*_ports), then Squid uses one SSL context (SSL_CTX) per true SSL server certificate (see ConnStateData::getSslContextStart). That SSL context is configured with the fake certificate for the corresponding SSL server. That fake certificate comes either from the ssl_crtd helper or is generated ad hoc by Squid. Fake certificates (or, to be precise, their contexts) may be cached in a Squid context cache. The cache key includes subject name, common name (CN), valid after, valid before, and other true certificate properties. An SSL context storing a full certificate chain may consume a few MBs of RAM. Since Squid usually talks to lots of servers, the total certificate cache capacity may have to exceed several GBs to avoid capacity misses. Please see dynamic_cert_mem_cache_size and Squid bug 4005 on why the configured cache limit does not currently work as intended. Squid does not empty its context cache during reconfiguration (although contexts for no-longer-used or no-longer-caching ports are deleted in recent Squids).
If generate-host-certificates is "off", then Squid uses one SSL context (SSL_CTX) per http_port / https_port for all transactions on that port, regardless of their destination (see PortCfg::staticSslContext). That SSL context is configured using http_port options. This is done before Squid starts (or resumes) handling traffic so no server certificate mimicking is possible with this context. The context is recreated during reconfiguration. At the time of writing, there are several bugs (with pending port leak patches) that may prevent this cleanup in some Squid.
Squid talking to SSL servers
When talking to SSL origin servers, Squid uses one SSL context for all servers (or one SSL_CTX per peer if a cache_peer is used; see Config.ssl_client.sslContext and FwdState::initiateSSL()). That SSL context is configured using various sslproxy_* directives (or cache_peer ssl* options) in squid.conf.
OpenSSL will automatically load and cache (inside the SSL context) certificates and CRLs necessary to validate true server certificates received by Squid. A single CRL may consume a few MBs. Since Squid usually talks to lots of servers, the total internal OpenSSL cache size may exceed several GBs. OpenSSL does not limit its internal cache size, and there are no knobs to do so using OpenSSL API.
The SSL context used for talking directly to SSL servers is freed and recreated on reconfigure. In theory, that should clear the internal OpenSSL certificate and CRL cache when the last SSL connection using the old context is gone. At the time of writing, there are several bugs (with pending patches) that may prevent this cleanup in some Squids.