<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 TRANSITIONAL//EN">
<HTML>
<HEAD>
  <META HTTP-EQUIV="Content-Type" CONTENT="text/html; CHARSET=UTF-8">
  <META NAME="GENERATOR" CONTENT="GtkHTML/4.6.6">
</HEAD>
<BODY>
Hey All,<BR>
<BR>
So....here's what I have for filtering http and https in the same instance.  This is using iptables with -j REDIRECT lines.  Below is my entire squid.conf, documented as well as I can:<BR>
<BR>
<TT>#allow local network to connect to squid</TT><BR>
<TT>acl localnet src 192.168.1.0/24</TT><BR>
<BR>
<TT>#safe ports are 80 and 443 in one acl, port 443 is another acl</TT><BR>
<TT>acl SSL_ports port 443</TT><BR>
<TT>acl Safe_ports port 80</TT><BR>
<TT>acl Safe_ports port 443</TT><BR>
<BR>
<TT>#allow the http CONNECT method</TT><BR>
<TT>acl CONNECT method CONNECT</TT><BR>
<BR>
<TT>#our regex list of sites and domains that we allow ie, www\.apple\.com and \.google\.com</TT><BR>
<TT>acl allowed_http_sites url_regex "/opt/etc/squid/http_url.txt"</TT><BR>
<BR>
<TT>#we don't want to allow anything besides port 80 and port 443</TT><BR>
<TT>http_access deny !Safe_ports</TT><BR>
<BR>
<TT>#we don't want CONNECT if we're not going to port 443</TT><BR>
<TT>http_access deny CONNECT !SSL_Ports</TT><BR>
<BR>
<TT>#since we may not know the https site we're going to (ie connect direct by IP), we must initially allow all https</TT><BR>
<TT>http_access allow SSL_ports</TT><BR>
<BR>
<TT>#we allow http, but only sites and domains in our regex http_url.txt list above</TT><BR>
<TT>http_access allow allowed_http_sites</TT><BR>
<BR>
<TT>#drop any other http requests that are not in our regex http_url.txt list above</TT><BR>
<TT>http_access deny all</TT><BR>
<BR>
<TT>#break out the ssl_bump process by steps</TT><BR>
<TT>acl step1 at_step SslBump1</TT><BR>
<TT>acl step2 at_step SslBump2</TT><BR>
<TT>acl step3 at_step SslBump3</TT><BR>
<BR>
<TT>#look for site or domain name either by SNI in request (step1), or server subject in certificate in response (step2)</TT><BR>
<TT>ssl_bump peek step1 all</TT><BR>
<TT>ssl_bump peek step2 all</TT><BR>
<BR>
<TT>#see if the server name we obtained from the previous peek's above are in our http_url.txt list above</TT><BR>
<TT>acl allowed_https_sites ssl::server_name_regex "/opt/etc/squid/http_url.txt"</TT><BR>
<BR>
<TT>#if the server name is in our http_url.txt, allow it </TT><BR>
<TT>ssl_bump splice step3 allowed_https_sites</TT><BR>
<BR>
<TT>#if the server name is not in our http_url.txt terminate the handshake it</TT><BR>
<TT>ssl_bump terminate all</TT><BR>
<BR>
<TT>#cert path and allow all the ssl options</TT><BR>
<TT>sslproxy_capath /etc/ssl/certs</TT><BR>
<TT>sslproxy_options ALL</TT><BR>
<BR>
<TT>#standard crtdaemon options</TT><BR>
<TT>sslcrtd_program /opt/libexec/ssl_crtd -s /opt/var/ssl_db -M 4MB</TT><BR>
<TT>sslcrtd_children 5</TT><BR>
<BR>
<TT>#intercept 3128 for port 80, and 3129 for port 443.  Cert, cacert (these are the same, read on the list this fixed an issue), and key, generate ssl certs</TT><BR>
<TT>http_port 3128 intercept</TT><BR>
<TT>https_port 3129 intercept ssl-bump cert=/opt/etc/squid/certs/sslsplit_ca_cert.pem cafile=/opt/etc/squid/certs/sslsplit_ca_cert.pem key=/opt/etc/squid/certs/sslsplit_ca_key.pem  generate-host-certificates=on dynamic_cert_mem_cache_size=4MB sslflags=NO_SESSION_REUSE</TT><BR>
<BR>
<TT>#normal-ish log format, but we want to see the SNI, server cert subject, and how we are bumping</TT><BR>
<TT>logformat mine %>a %[ui %[un [%tl] "%rm %ru HTTP/%rv" %ssl::>sni %ssl::>cert_subject %>Hs %<st %Ss:%Sh %ssl::bump_mode </TT><BR>
<BR>
<TT>#log the above format name (mine) to syslog</TT><BR>
<TT>access_log syslog:daemon.info mine</TT><BR>
<BR>
<TT>refresh_pattern -i (cgi-bin|\?)       0       0%      0</TT><BR>
<TT>refresh_pattern .             0       20%     4320</TT><BR>
<BR>
<TT>coredump_dir /opt/var </TT><BR>
<BR>
One caveat I've seen so far is that I have only seen is I only ever see peek in the logs, though I know it's been spliced as shown below:<BR>
<BR>
<TT>[09:35:19 <A HREF="mailto:jlay@gateway">jlay@gateway</A>:/opt/etc/squid$] grep textnow http_url.txt </TT><BR>
<TT>api\.textnow\.me</TT><BR>
<BR>
<TT>[09:34:57 <A HREF="mailto:jlay@gateway">jlay@gateway</A>:~$] dig api.textnow.me</TT><BR>
<snip><BR>
<TT>;; ANSWER SECTION:</TT><BR>
<TT>api.textnow.me.               600     IN      A       209.59.180.48</TT><BR>
<BR>
>From the client:<BR>
<TT>[09:34:27 <A HREF="mailto:jlay@analysis">jlay@analysis</A>:~/dev/squid$] openssl s_client -connect 209.59.180.48:443</TT><BR>
<TT>CONNECTED(00000003)</TT><BR>
<TT>depth=1 C = US, ST = Arizona, L = Scottsdale, O = "GoDaddy.com, Inc.", OU = <A HREF="http://certificates.godaddy.com/repository,">http://certificates.godaddy.com/repository,</A> CN = Go Daddy Secure Certification Authority, serialNumber = 07969287</TT><BR>
<TT>verify error:num=20:unable to get local issuer certificate</TT><BR>
<TT>verify return:0</TT><BR>
<TT>---</TT><BR>
<TT>Certificate chain</TT><BR>
<TT> 0 s:/OU=Domain Control Validated/CN=*.textnow.me</TT><BR>
<TT><snip></TT><BR>
<BR>
<TT>GET / HTTP/1.1</TT><BR>
<BR>
<TT>HTTP/1.1 200 OK</TT><BR>
<TT>Server: nginx</TT><BR>
<TT>Date: Thu, 11 Jun 2015 15:36:54 GMT</TT><BR>
<TT>Content-Type: text/plain</TT><BR>
<TT>Transfer-Encoding: chunked</TT><BR>
<TT>Connection: keep-alive</TT><BR>
<TT>X-Powered-By: PHP/5.5.16</TT><BR>
<TT>Expires: Thu, 01 Jan 1970 00:00:00 GMT</TT><BR>
<TT>Cache-Control: no-cache, no-store, must-revalidate, max-age=0</TT><BR>
<BR>
Server Squid log entry:<BR>
<TT>Jun 11 09:36:55 gateway (squid-1): 192.168.1.6 - - [11/Jun/2015:09:36:55 -0600] "CONNECT 209.59.180.48:443 HTTP/1.1" - - 200 364 TCP_TUNNEL:ORIGINAL_DST peek</TT><BR>
<BR>
I also notice that the CN does not show up in the logs...it WAS spliced however because it matches our http_url.txt.  From the above, it appears that only the step1 is getting logged.   The below log entry was used with wget (sends SNI by default):<BR>
<TT>Jun 11 08:51:05 gateway squid: 192.168.1.6 - - [11/Jun/2015:08:51:05 -0600] "CONNECT 23.211.252.28:443 HTTP/1.1" <A HREF="http://www.apple.com">www.apple.com</A> - 200 14388 TCP_TUNNEL:ORIGINAL_DST peek</TT><BR>
<BR>
The above shows that I logged and retrieved my SNI at step1....the subsequent splice was not logged.  I still note that terminates do not get logged ( I have a bug open for that but I think the core bug may be that when using atStep you only see step1 regardless, but I could be wrong).  I'm enclosing an image of what a https terminate looks like from the server and the client (msn.com isn't in the http_url.txt), and also what an https allow looks like (apple.com is in the list).<BR>
<BR>
That's it.  I can verify that the above works for a single list of allowed hosts(<A HREF="http://www.apple.com">www.apple.com</A>) and domains (google.com).  If there's something I missed...something wrong...ways to improve...ANYTHING for the betterment of Squid users please don't hesitate to jump in here.  Thank you. <BR>
<BR>
James<BR>
<BR>
</BODY>
</HTML>