1
Web Proxy Filtering and Caching / Squid Proxy: Parsing https header values for specific values
« on: June 24, 2024, 06:34:26 am »
My Squid proxy has a `external_acl_type` script: `token_auth.py` that parses header values and if the header contains `X-My-Header: target-value` we allow the request through, otherwise, deny it. Akin to a token authorization system.
token_auth.py:
We can test that this works fine:
✅ Allowed Through:
curl -x http://localhost:3128 -H "X-My-Header: target-value" http://www.example.com
❌ Not Allowed Through (this is good):
curl -x http://localhost:3128 -H "X-My-Header: WRONG-target-value" http://www.example.com
The problem:
However, if we change the `example.com` url to a `HTTPS` url:
sudo curl -v -x http://172.17.2.200:3128 -H "X-My-Header: target-value" --cacert /etc/squid/bump.crt https://www.example.com
Even though, yes, it's denied, we did provide the correct header value "X-My-Header: target-value", so it shouldn't be denied!
What I am almost positive is happening is that my `token_auth.py` script cannot parse https encrypted headers. I have tried SSL bumping, but no difference. Adding some logging to my python script I cannot see the Header or URL:
I have been stuck here for 3 days now. I am not sure what to do. How can I parse https headers through a external_acl_type helper? Can anyone point me in the right direction?
Please, please help. Thank you.
squid.conf:
token_auth.py:
Code: [Select]
#!/usr/bin/env python3
import sys
while True:
line = sys.stdin.readline().strip()
if not line:
break
parts = line.split()
header_value = parts[2]
target_value = "target-value"
# Check if the target header value is present
if header_value == target_value:
sys.stdout.write("OK\n")
else:
sys.stdout.write("ERR\n")
sys.stdout.flush()
We can test that this works fine:
✅ Allowed Through:
curl -x http://localhost:3128 -H "X-My-Header: target-value" http://www.example.com
❌ Not Allowed Through (this is good):
curl -x http://localhost:3128 -H "X-My-Header: WRONG-target-value" http://www.example.com
The problem:
However, if we change the `example.com` url to a `HTTPS` url:
sudo curl -v -x http://172.17.2.200:3128 -H "X-My-Header: target-value" --cacert /etc/squid/bump.crt https://www.example.com
Even though, yes, it's denied, we did provide the correct header value "X-My-Header: target-value", so it shouldn't be denied!
Code: [Select]
<hr>
<div id="footer">
<p>Generated Mon, 24 Jun 2024 04:12:05 GMT by sven-u (squid/5.7)</p>
<!-- ERR_ACCESS_DENIED -->
</div>
</body></html>
What I am almost positive is happening is that my `token_auth.py` script cannot parse https encrypted headers. I have tried SSL bumping, but no difference. Adding some logging to my python script I cannot see the Header or URL:
Code: [Select]
2024-06-23 23:56:06,750 Client IP: 172.17.2.200, Method: CONNECT, URL: -, Header: -
2024-06-23 23:56:06,750 Header did not match: -
I have been stuck here for 3 days now. I am not sure what to do. How can I parse https headers through a external_acl_type helper? Can anyone point me in the right direction?
Please, please help. Thank you.
squid.conf:
Code: [Select]
# External ACL for intermediate certificate fetching
acl intermediate_fetching transaction_initiator certificate-fetching
http_access allow intermediate_fetching
# SSL certificate generator program
sslcrtd_program /usr/lib/squid/security_file_certgen -s /var/lib/squid/ssl_db -M 20MB
# Handle SSL certificate errors
sslproxy_cert_error allow all
# Define SSL bumping steps
acl step1 at_step SslBump1
acl step2 at_step SslBump2
acl step3 at_step SslBump3
# Bumping steps
ssl_bump peek step1
ssl_bump bump step2
ssl_bump bump step3
# Define SSL ports
acl SSL_ports port 443
# SSL bump configuration
http_port 3128 tcpkeepalive=60,30,3 ssl-bump generate-host-certificates=on dynamic_cert_mem_cache_size=20MB tls-cert=/etc/squid/bump.crt tls-key=/etc/squid/bump.key cipher=HIGH:MEDIUM:!LOW:!RC4:!SEED:!IDEA:!3DES:!MD5:!EXP:!PSK:!DSS options=NO_TLSv1,NO_SSLv3,SINGLE_DH_USE,SINGLE_ECDH_USE tls-dh=prime256v1:/etc/squid/bump_dhparam.pem
# Custom log format to include X-My-Header
logformat custom_log %{%Y-%m-%d %H:%M:%S}tl %>a:%>p %Ss/%03>Hs "%rm %ru HTTP/%rv" %>Hs %<st %tr "%{User-Agent}>h" "%{Referer}>h" "%{X-My-Header}>h"
access_log /var/log/squid/access.log custom_log
# External ACL configuration for header checks
external_acl_type check_headers_helper %SRC %METHOD %<h{X-My-Header} /etc/squid/COOKIE_AUTH/token_auth.py
acl check_headers external check_headers_helper
# Allow access only if headers contain the specific value
http_access allow check_headers
# Deny all other access
http_access deny all
# Handle SSL certificate errors
acl BadSite ssl_error SQUID_X509_V_ERR_DOMAIN_MISMATCH
sslproxy_cert_error allow BadSite
sslproxy_cert_error deny all
# Squid normally listens to port 3128
http_port 3128 intercept
# PID file configuration
pid_filename none
# Header and logging configuration
via off
reply_header_access X-Cache deny all
reply_header_access X-Cache-Lookup deny all
follow_x_forwarded_for allow localhost
follow_x_forwarded_for deny all
request_header_access X-Forwarded-For deny all
# Disk cache directory
cache_dir ufs /var/spool/squid 100 16 256
# Leave coredumps in the first cache dir
coredump_dir /var/spool/squid
# Add any of your own refresh_pattern entries above these
refresh_pattern ^ftp: 1440 20% 10080
refresh_pattern -i (/cgi-bin/|\?) 0 0% 0
refresh_pattern . 0 20% 4320