Squid Transparent Proxy Certificate Mimic Problem
-
Hi,
Just curious is there a bug in the current squid package when using transparent proxy?When the transparent proxy is enabled, the certs served by the squid package do not contain proper common names and altdns names but only ip address as CN.
This creates certificate errors on the browsers.However, when the proxy is set manually, it works normally.
My config with transparent proxy enabled:
# This file is automatically generated by pfSense # Do not edit manually ! http_port 192.168.100.1:3128 ssl-bump generate-host-certificates=on dynamic_cert_mem_cache_size=100MB cert=/usr/local/etc/squid/serverkey.pem tls-cafile=/usr/local/share/certs/ca-root-nss.crt capath=/usr/local/share/certs/ cipher=EECDH+ECDSA+AESGCM:EECDH+aRSA+AESGCM:EECDH+ECDSA+SHA384:EECDH+ECDSA+SHA256:EECDH+aRSA+SHA384:EECDH+aRSA+SHA256:EECDH:EDH+aRSA:!RC4:!aNULL:!eNULL:!LOW:!3DES:!SHA1:!MD5:!EXP:!PSK:!SRP:!DSS tls-dh=prime256v1:/etc/dh-parameters.2048 options=NO_SSLv3,NO_TLSv1,NO_TLSv1_1 http_port 192.168.26.1:3128 http_port 192.168.99.1:3128 ssl-bump generate-host-certificates=on dynamic_cert_mem_cache_size=100MB cert=/usr/local/etc/squid/serverkey.pem tls-cafile=/usr/local/share/certs/ca-root-nss.crt capath=/usr/local/share/certs/ cipher=EECDH+ECDSA+AESGCM:EECDH+aRSA+AESGCM:EECDH+ECDSA+SHA384:EECDH+ECDSA+SHA256:EECDH+aRSA+SHA384:EECDH+aRSA+SHA256:EECDH:EDH+aRSA:!RC4:!aNULL:!eNULL:!LOW:!3DES:!SHA1:!MD5:!EXP:!PSK:!SRP:!DSS tls-dh=prime256v1:/etc/dh-parameters.2048 options=NO_SSLv3,NO_TLSv1,NO_TLSv1_1 http_port 127.0.0.1:3128 intercept ssl-bump generate-host-certificates=on dynamic_cert_mem_cache_size=100MB cert=/usr/local/etc/squid/serverkey.pem tls-cafile=/usr/local/share/certs/ca-root-nss.crt capath=/usr/local/share/certs/ cipher=EECDH+ECDSA+AESGCM:EECDH+aRSA+AESGCM:EECDH+ECDSA+SHA384:EECDH+ECDSA+SHA256:EECDH+aRSA+SHA384:EECDH+aRSA+SHA256:EECDH:EDH+aRSA:!RC4:!aNULL:!eNULL:!LOW:!3DES:!SHA1:!MD5:!EXP:!PSK:!SRP:!DSS tls-dh=prime256v1:/etc/dh-parameters.2048 options=NO_SSLv3,NO_TLSv1,NO_TLSv1_1 https_port 127.0.0.1:3129 intercept ssl-bump generate-host-certificates=on dynamic_cert_mem_cache_size=100MB cert=/usr/local/etc/squid/serverkey.pem tls-cafile=/usr/local/share/certs/ca-root-nss.crt capath=/usr/local/share/certs/ cipher=EECDH+ECDSA+AESGCM:EECDH+aRSA+AESGCM:EECDH+ECDSA+SHA384:EECDH+ECDSA+SHA256:EECDH+aRSA+SHA384:EECDH+aRSA+SHA256:EECDH:EDH+aRSA:!RC4:!aNULL:!eNULL:!LOW:!3DES:!SHA1:!MD5:!EXP:!PSK:!SRP:!DSS tls-dh=prime256v1:/etc/dh-parameters.2048 options=NO_SSLv3,NO_TLSv1,NO_TLSv1_1 icp_port 0 digest_generation off dns_v4_first on pid_filename /var/run/squid/squid.pid cache_effective_user squid cache_effective_group proxy error_default_language en icon_directory /usr/local/etc/squid/icons visible_hostname localhost cache_mgr admin@localhost access_log /var/squid/logs/access.log cache_log /var/squid/logs/cache.log cache_store_log none netdb_filename /var/squid/logs/netdb.state pinger_enable on pinger_program /usr/local/libexec/squid/pinger sslcrtd_program /usr/local/libexec/squid/security_file_certgen -s /var/squid/lib/ssl_db -M 4MB -b 2048 tls_outgoing_options cafile=/usr/local/share/certs/ca-root-nss.crt tls_outgoing_options capath=/usr/local/share/certs/ tls_outgoing_options options=NO_SSLv3,NO_TLSv1,NO_TLSv1_1 tls_outgoing_options cipher=EECDH+ECDSA+AESGCM:EECDH+aRSA+AESGCM:EECDH+ECDSA+SHA384:EECDH+ECDSA+SHA256:EECDH+aRSA+SHA384:EECDH+aRSA+SHA256:EECDH:EDH+aRSA:!RC4:!aNULL:!eNULL:!LOW:!3DES:!SHA1:!MD5:!EXP:!PSK:!SRP:!DSS tls_outgoing_options flags=DONT_VERIFY_PEER sslcrtd_children 50 sslproxy_cert_error allow all sslproxy_cert_adapt setValidAfter all sslproxy_cert_adapt setValidBefore all sslproxy_cert_adapt setCommonName all logfile_rotate 10 debug_options rotate=10 shutdown_lifetime 3 seconds # Allow local network(s) on interface(s) acl localnet src 192.168.100.0/24 192.168.99.0/24 192.168.26.0/24 forwarded_for on uri_whitespace strip dns_nameservers 192.168.100.1 acl dynamic urlpath_regex cgi-bin \? cache deny dynamic cache_mem 2048 MB maximum_object_size_in_memory 256 KB memory_replacement_policy heap GDSF cache_replacement_policy heap LFUDA minimum_object_size 0 KB maximum_object_size 4 MB cache_dir ufs /var/squid/cache 1000 16 256 offline_mode off cache_swap_low 90 cache_swap_high 95 cache allow all # Add any of your own refresh_pattern entries above these. refresh_pattern ^ftp: 1440 20% 10080 refresh_pattern ^gopher: 1440 0% 1440 refresh_pattern -i (/cgi-bin/|\?) 0 0% 0 refresh_pattern . 0 20% 4320 #Remote proxies # Setup some default acls # ACLs all, manager, localhost, and to_localhost are predefined. acl allsrc src all acl safeports port 21 70 80 210 280 443 488 563 591 631 777 901 3128 3129 1025-65535 acl sslports port 443 563 acl purge method PURGE acl connect method CONNECT # Define protocols used for redirects acl HTTP proto HTTP acl HTTPS proto HTTPS # SslBump Peek and Splice # http://wiki.squid-cache.org/Features/SslPeekAndSplice # http://wiki.squid-cache.org/ConfigExamples/Intercept/SslBumpExplicit # Match against the current step during ssl_bump evaluation [fast] # Never matches and should not be used outside the ssl_bump context. # # At each SslBump step, Squid evaluates ssl_bump directives to find # the next bumping action (e.g., peek or splice). Valid SslBump step # values and the corresponding ssl_bump evaluation moments are: # SslBump1: After getting TCP-level and HTTP CONNECT info. # SslBump2: After getting TLS Client Hello info. # SslBump3: After getting TLS Server Hello info. # These ACLs exist even when 'SSL/MITM Mode' is set to 'Custom' so that # they can be used there for custom configuration. acl step1 at_step SslBump1 acl step2 at_step SslBump2 acl step3 at_step SslBump3 acl allowed_subnets src 10.0.0.0/8 172.16.0.0/12 192.168.0.0/16 acl whitelist dstdom_regex -i "/var/squid/acl/whitelist.acl" acl sslwhitelist ssl::server_name_regex -i "/var/squid/acl/whitelist.acl" http_access allow manager localhost http_access deny manager http_access allow purge localhost http_access deny purge http_access deny !safeports http_access deny CONNECT !sslports # Always allow localhost connections http_access allow localhost request_body_max_size 0 KB delay_pools 1 delay_class 1 2 delay_parameters 1 -1/-1 -1/-1 delay_initial_bucket_level 100 delay_access 1 allow allsrc # Reverse Proxy settings # Custom options before auth # Always allow access to whitelist domains http_access allow whitelist ssl_bump peek step1 ssl_bump splice sslwhitelist ssl_bump bump all # Setup allowed ACLs # Allow local network(s) on interface(s) http_access allow allowed_subnets http_access allow localnet # Default block all to be sure http_access deny allsrcIt only works properly if I uncheck the transparent proxy and manually enter the proxy details in the clients.
-
@Laxarus have you tried to manually do tproxy on it?
https://wiki.squid-cache.org/Features/Tproxy4
also are you using Certificate Adapt??
-
@Laxarus your bumping...
When ssl_bump bump all triggers, Squid terminates the original secure connection, decrypts the traffic, and generates a fake server certificate on the fly using your local Certificate Authority (CA) key stored at /usr/local/etc/squid/serverkey.pem.
change it to splice all it will work for transparent you can not bump with transparent if you do you have to use certs on devices. Try tproxy if you dont want certs but I think you still need them with any bump use
-
Hey @JonathanLee
I am using my ADCS CA with private key, so it is trusted on the clients and I have the private key installed on the pfsense. When I disable transparent proxy and enter the proxy settings manually, it works without a problem.
HTTPS is intercepted and certs are generated correctly.

But when I enable transparent proxy, the certs generated by the squid is still with my ADCS CA but common names are all ip addresses so there is something going wrong there.
And I want squid to bump tls not tunnel it.
-
@Laxarus
I addressed the issues with transparent mode here
https://forum.netgate.com/topic/200785/guide-to-squid-web-filtering-ssl-mitm-dns-and-caching-with-pfsense-2.8.1have a read through and let me know how you go.
-
@Laxarus you could set up a wpad server on a raspberry pi zero I did that. After that I set everything to auto and it works. It is a bit more complex to set up but for me it is easy to use my laptop at the University and go home and it works on my secure network. This is my wpad I use. I am sure you know it's basically just a script that the computer calls to know where the proxy is and what goes into it and what goes direct.
I have ULA ipv6 traffic going direct. I had to use a host name for my proxy so it will resolve ipv6 and ipv4 as my network is a dual stacked network for educational higher level understanding. But again you can make it very basic, Netgate has a doc on how to make one on the system even if you want to have it on the firewall, I was told it is easier to just do it on a raspberry pi and it is more secure that way also.
/* Highly Optimized Dual-Stack WPAD/PAC Script Features: - Fast regex validation prevents slow, blocking DNS lookups inside isInNet(). - Comprehensive loop protection for WPAD and admin endpoints. - Safe dual-stack handling via FindProxyForURLEx for modern browsers. */ function FindProxyForURL(url, host) { host = host.toLowerCase(); // Normalize IPv6 brackets var cleanHost = (host.charAt(0) === '[' && host.charAt(host.length - 1) === ']') ? host.substring(1, host.length - 1) : host; // WPAD loop protection & local admin endpoints if ( host === "wpad" || host === "wpad.local" || host === "wpad.localdomain" || host === "wpad.home.arpa" || cleanHost === "192.168.1.6" || cleanHost === "2001:db8:8052:a::6" || // Placeholder Admin IP cleanHost === "192.168.1.1" || cleanHost === "192.168.1.2" || cleanHost === "2001:db8:8052:a::1" || host === "localhost" || cleanHost === "127.0.0.1" || cleanHost === "::1" ) { return "DIRECT"; } // Plain hostnames (e.g. http://pfsense/) if (isPlainHostName(host)) { return "DIRECT"; } // Local internal domains if ( dnsDomainIs(host, ".local") || dnsDomainIs(host, ".lan") || dnsDomainIs(host, ".localdomain") || dnsDomainIs(host, ".home.arpa") ) { return "DIRECT"; } // IPv4 private ranges (literal addresses only) if (/^[0-9.]+$/.test(cleanHost)) { if ( isInNet(cleanHost, "10.0.0.0", "255.0.0.0") || isInNet(cleanHost, "127.0.0.0", "255.0.0.0") || isInNet(cleanHost, "169.254.0.0", "255.255.0.0") || isInNet(cleanHost, "172.16.0.0", "255.240.0.0") || isInNet(cleanHost, "192.168.1.0", "255.255.255.224") // Custom limited subnet /27 ) { return "DIRECT"; } } // IPv6 ULA and link-local (literal addresses only) if (cleanHost.indexOf(":") !== -1) { if ( cleanHost.indexOf("fe80:") === 0 || cleanHost.indexOf("fc00:") === 0 || cleanHost.indexOf("fd00:") === 0 ) { return "DIRECT"; } } // ========================================================= // DEFAULT ROUTING RULE FOR PUBLIC TRAFFIC // ========================================================= return "PROXY proxy.home.arpa:3128"; } function FindProxyForURLEx(url, host) { host = host.toLowerCase(); // Use extended IPv6-aware functions if available (Edge/Windows) if (typeof isInNetEx === 'function' && typeof dnsResolveEx === 'function') { var cleanHost = (host.charAt(0) === '[' && host.charAt(host.length - 1) === ']') ? host.substring(1, host.length - 1) : host; if (isInNetEx(cleanHost, "fe80::/10") || isInNetEx(cleanHost, "fc00::/7")) { return "DIRECT"; } // Change the prefix below to match your local public IPv6 assignment if (isInNetEx(cleanHost, "2001:db8:8052:a::/64")) { return "DIRECT"; } } return FindProxyForURL(url, host); }
Privacy Policy · Cookie Policy