Introduction to Squid Proxy Security Hardening
Squid is one of the most widely deployed caching and forwarding HTTP proxies in the world. Originally released in 1996, it powers everything from enterprise content filters to ISP-level caching infrastructure. However, a default Squid installation is not secure. Out of the box, it may expose management interfaces, allow open relay behavior, log sensitive data, and run with overly permissive access controls. This tutorial walks through a complete security hardening strategy for Squid Proxy, covering configuration hardening, access control, authentication, TLS inspection, logging hygiene, and operational best practices.
What Is Squid Proxy?
Squid is an open-source proxy server and web cache daemon. It supports HTTP, HTTPS, FTP, and (with extensions) other protocols. Squid sits between clients and origin servers, forwarding requests, caching responses, and optionally filtering traffic based on rules. It can operate as a forward proxy (serving internal users) or a reverse proxy (accelerating inbound traffic to backend servers).
Because Squid handles untrusted network traffic and often has broad network reach, it is a high-value target. Misconfigurations can lead to open proxies, data exfiltration, credential leakage, and lateral movement within a network.
Why Squid Hardening Matters
A poorly configured Squid instance can cause serious security incidents:
- Open proxy abuse: Attackers use your proxy to relay malicious traffic, hiding their origin and consuming your bandwidth.
- Data exfiltration: Without filtering, insiders can tunnel sensitive data through allowed ports.
- Credential exposure: Weak or missing authentication lets anyone on the network use the proxy.
- Logging risks: Verbose logs may capture URLs containing tokens, session IDs, or PII.
- Service disruption: Resource exhaustion from unbounded connections or large uploads.
Hardening Squid reduces these risks and aligns the deployment with security frameworks such as CIS Benchmarks, NIST SP 800-81, and OWASP infrastructure guidance.
Installing and Preparing Squid
Before hardening, install Squid from your distribution's package manager. The examples in this tutorial use Squid 6.x on a Linux host, but most directives apply to Squid 4.x and 5.x as well.
# Debian/Ubuntu
sudo apt update
sudo apt install squid squid-langpack
# RHEL/CentOS/Rocky
sudo dnf install squid
# Verify version
squid -v
Create a dedicated configuration directory for include files. Splitting configuration makes hardening rules easier to audit and version control.
sudo mkdir -p /etc/squid/conf.d
sudo chown -R root:squid /etc/squid/conf.d
sudo chmod 750 /etc/squid/conf.d
Core Configuration Hardening
The main configuration file is /etc/squid/squid.conf. Replace the default file with a minimal, hardened baseline. The default file ships with many permissive examples that should not be used in production.
Minimal Hardened Baseline
# /etc/squid/squid.conf
# Hardened baseline - replace default config entirely
# ---- Global options ----
http_port 127.0.0.1:3128
https_port 127.0.0.1:3129 intercept ssl-bump \
cert=/etc/squid/ssl_cert/squid.crt \
key=/etc/squid/ssl_cert/squid.key \
generate-host-certificates=on dynamic_cert_mem_cache_size=16MB
# ---- DNS ----
dns_v4_first on
dns_nameservers 1.1.1.1 9.9.9.9
hosts_file /etc/hosts
# ---- Access log hygiene ----
access_log /var/log/squid/access.log squid
cache_log /var/log/squid/cache.log
coredump_dir /var/spool/squid
# Strip sensitive query strings from logs
strip_query_terms on
# ---- Resource limits ----
maximum_object_size 32 MB
maximum_object_size_in_memory 512 KB
cache_mem 256 MB
memory_replacement_policy heap GDSF
# Connection limits
client_lifetime 2 hours
connect_timeout 30 seconds
read_timeout 5 minutes
request_timeout 1 minute
persistent_request_timeout 1 minute
# ---- Include hardening snippets ----
include /etc/squid/conf.d/*.conf
Binding to the Correct Interface
Never bind Squid to 0.0.0.0 unless you have a specific reason. Bind only to the interface that should receive proxy traffic. If Squid runs on a host with multiple interfaces, specify each explicitly.
# Internal LAN only
http_port 10.0.0.5:3128
# If using a reverse proxy, bind to the public interface
# http_port 203.0.113.10:80 accel defaultsite=example.com
Access Control Lists (ACLs)
ACLs are the heart of Squid security. They define what traffic the proxy will handle. The golden rule: default deny, explicitly allow.
Defining Source and Destination ACLs
# /etc/squid/conf.d/acls.conf
# Trusted internal networks
acl localnet src 10.0.0.0/8
acl localnet src 172.16.0.0/12
acl localnet src 192.168.0.0/16
# Loopback
acl localhost src 127.0.0.1/32 ::1
# Safe ports - restrict to common web ports
acl safe_ports port 80 # HTTP
acl safe_ports port 443 # HTTPS
acl safe_ports port 21 # FTP
acl safe_ports port 70 # Gopher
acl safe_ports port 210 # wais
acl safe_ports port 1025-65535 # unregistered ports
acl safe_ports port 280 # http-mgmt
acl safe_ports port 488 # gss-http
acl safe_ports port 591 # filemaker
acl safe_ports port 777 # multiling http
# SSL ports - tightly restricted
acl ssl_ports port 443
acl ssl_ports port 8443
# Protocol methods
acl allowed_methods method GET POST HEAD OPTIONS PUT DELETE
acl connect_method method CONNECT
# Block dangerous destinations
acl blocked_domains dstdomain "/etc/squid/lists/blocked_domains.txt"
acl malware_domains dstdomain "/etc/squid/lists/malware_domains.txt"
Applying ACLs with http_access
Order matters. Squid evaluates http_access rules top to bottom and stops at the first match. Always place deny rules before allow rules, and end with a final deny.
# /etc/squid/conf.d/access.conf
# Deny non-safe ports
http_access deny !safe_ports
# Deny CONNECT to non-SSL ports (prevents tunneling)
http_access deny connect_method !ssl_ports
# Block known malicious domains
http_access deny malware_domains
http_access deny blocked_domains
# Allow only localhost and localnet
http_access allow localhost
http_access allow localnet
# Default deny - MUST be last
http_access deny all
Blocking Specific Domains
Maintain a flat file of blocked domains. Squid reloads these files on squid -k reconfigure.
# /etc/squid/lists/blocked_domains.txt
.facebook.com
.twitter.com
.tiktok.com
.doubleclick.net
.googlesyndication.com
Use leading dots to match subdomains. A line without a dot matches only the exact domain.
Authentication and Authorization
Anonymous proxy access should never be allowed in production. Squid supports several authentication helpers, including LDAP, PAM, RADIUS, and basic file-based authentication.
Basic File-Based Authentication
For small deployments, use the basic_ncsa_auth helper with an htpasswd-style file.
# Install apache2-utils for htpasswd
sudo apt install apache2-utils
# Create password file owned by the squid user
sudo htpasswd -c /etc/squid/passwords alice
sudo htpasswd /etc/squid/passwords bob
sudo chown root:squid /etc/squid/passwords
sudo chmod 640 /etc/squid/passwords
# /etc/squid/conf.d/auth.conf
auth_param basic program /usr/lib/squid/basic_ncsa_auth /etc/squid/passwords
auth_param basic children 5
auth_param basic realm "Squid Proxy - Authentication Required"
auth_param basic credentialsttl 2 hours
auth_param basic casesensitive on
acl authenticated proxy_auth REQUIRED
# Require authentication before any allow rule
http_access allow authenticated localnet
http_access deny all
LDAP Authentication
For Active Directory or OpenLDAP environments, use basic_ldap_auth.
# /etc/squid/conf.d/ldap_auth.conf
auth_param basic program /usr/lib/squid/basic_ldap_auth \
-b "dc=example,dc=com" \
-D "cn=squid-svc,ou=service-accounts,dc=example,dc=com" \
-w "REPLACE_WITH_LDAP_PASSWORD" \
-f "(&(objectClass=user)(sAMAccountName=%s)(memberOf=cn=proxy-users,ou=groups,dc=example,dc=com))" \
-h ldap.example.com -p 389
auth_param basic children 10
auth_param basic realm "Corporate Proxy - LDAP Auth"
auth_param basic credentialsttl 1 hour
acl authenticated proxy_auth REQUIRED
http_access allow authenticated
http_access deny all
Store the LDAP bind password in a protected file with restricted permissions, or use a secrets file referenced by -W instead of -w.
TLS/HTTPS Inspection (SSL Bump)
To inspect HTTPS traffic, Squid must terminate and re-encrypt TLS sessions. This requires a trusted CA certificate deployed to all client machines. TLS inspection raises privacy and compliance concerns; ensure you have legal authorization before enabling it.
Generating the Squid CA Certificate
sudo mkdir -p /etc/squid/ssl_cert
sudo chown -R root:squid /etc/squid/ssl_cert
sudo chmod 750 /etc/squid/ssl_cert
cd /etc/squid/ssl_cert
sudo openssl genrsa -out squid.key 4096
sudo openssl req -new -x509 -days 3650 -key squid.key \
-out squid.crt -subj "/CN=Squid Proxy CA/O=Example Corp"
sudo chown root:squid squid.key squid.crt
sudo chmod 640 squid.key squid.crt
Distribute squid.crt to client trust stores. On Linux clients, copy it to /usr/local/share/ca-certificates/squid.crt and run update-ca-certificates. On Windows, import it into the Trusted Root Certification Authorities store via Group Policy.
Configuring SSL Bump
# /etc/squid/conf.d/ssl_bump.conf
# Initialize dynamic certificate generation
sslcrtd_program /usr/lib/squid/security_file_certgen -s /var/lib/ssl_db -M 16MB
sslcrtd_children 8
# Step 1: Peek at the SNI during ClientHello
# Step 2: Bump (intercept) the connection
# Step 3: Terminate if the cert is invalid
acl step1 at_step SslBump1
acl step2 at_step SslBump2
acl step3 at_step SslBump3
ssl_bump peek step1 all
ssl_bump bump step2 all
ssl_bump splice step3 all
# Never bump traffic to banking and healthcare domains
acl no_bump_domains dstdomain "/etc/squid/lists/no_bump.txt"
ssl_bump splice no_bump_domains
# Block TLS connections with invalid certificates
sslproxy_cert_error deny all
Excluding Domains from Inspection
Some domains must be excluded from TLS inspection for legal, functional, or security reasons. Banking, healthcare, and certificate pinning applications should be spliced, not bumped.
# /etc/squid/lists/no_bump.txt
.bank.com
.wellsfargo.com
.chase.com
.paypal.com
.apple.com
.google.com
.github.com
Content Filtering and URL Rewriting
Squid can integrate with external content filters such as squidGuard, ufdbGuard, or DansGuardian. These tools categorize URLs and enforce policy based on categories like gambling, social media, or malware.
Integrating squidGuard
sudo apt install squidguard
# /etc/squid/conf.d/squidguard.conf
url_rewrite_program /usr/bin/squidGuard -c /etc/squidguard/squidGuard.conf
url_rewrite_children 8
url_rewrite_access allow localnet
# /etc/squidguard/squidGuard.conf
dbhome /var/lib/squidguard/db
logdir /var/log/squidguard
src localnet {
ip 10.0.0.0/8
172.16.0.0/12
192.168.0.0/16
}
dest adult {
domainlist adult/domains
urllist adult/urls
}
dest malware {
domainlist malware/domains
}
acl {
localnet {
pass !adult !malware all
redirect http://proxy.example.com/blocked.html
}
default {
pass none
redirect http://proxy.example.com/blocked.html
}
}
Rate Limiting and DoS Protection
Unbounded connections can exhaust Squid's file descriptors and memory. Use connection limits and delay pools to prevent abuse.
Connection Limits per Client
# /etc/squid/conf.d/limits.conf
# Maximum 20 concurrent connections per client IP
acl maxconn maxconn 20
http_access deny localnet maxconn
# Limit CONNECT method usage
acl connect_method method CONNECT
acl connect_max maxconn 5
http_access deny connect_method connect_max
Delay Pools for Bandwidth Throttling
# /etc/squid/conf.d/delay_pools.conf
# Define delay pools
delay_pools 1
delay_class 1 2
delay_parameters 1 -1/-1 256000/256000
delay_access 1 allow localnet
delay_access 1 deny all
This configuration limits each client to 256 Kbps after an initial burst. Adjust values based on your bandwidth budget.
Logging and Monitoring
Logs are critical for incident response and compliance, but they also pose privacy risks. Configure logging carefully.
Log Format and Privacy
# /etc/squid/conf.d/logging.conf
# Custom log format that excludes query strings
logformat secure %tl %>a %Ss/%03>Hs %
Forwarding Logs to a SIEM
For centralized monitoring, forward Squid logs to syslog and then to a SIEM such as Splunk, Elastic Stack, or Wazuh.
# /etc/rsyslog.d/30-squid.conf
local4.* @@siem.example.com:514
sudo systemctl restart rsyslog
Monitoring with Prometheus
Use the squid_exporter to expose Squid metrics to Prometheus.
# Run the exporter as a systemd service
# /etc/systemd/system/squid-exporter.service
[Unit]
Description=Squid Prometheus Exporter
After=network.target
[Service]
ExecStart=/usr/local/bin/squid_exporter -squid-hostname localhost -squid-port 3128
Restart=always
User=squid
[Install]
WantedBy=multi-user.target
sudo systemctl daemon-reload
sudo systemctl enable --now squid-exporter
File System and OS Hardening
Squid runs as a service account, typically squid or proxy. Ensure the process runs with least privilege.
Service Account and Permissions
# Verify the squid user exists
id squid
# Ensure cache directories are owned correctly
sudo chown -R squid:squid /var/spool/squid
sudo chmod 750 /var/spool/squid
# Protect configuration files
sudo chown -R root:squid /etc/squid
sudo chmod 640 /etc/squid/squid.conf
sudo chmod 640 /etc/squid/conf.d/*.conf
sudo chmod 640 /etc/squid/passwords
Systemd Sandboxing
If Squid runs under systemd, add sandboxing directives to the service unit file.
# /etc/systemd/system/squid.service.d/override.conf
[Service]
NoNewPrivileges=yes
ProtectSystem=strict
ProtectHome=yes
PrivateTmp=yes
PrivateDevices=yes
ProtectKernelTunables=yes
ProtectKernelModules=yes
ProtectControlGroups=yes
ReadWritePaths=/var/spool/squid /var/log/squid /var/lib/ssl_db
RestrictAddressFamilies=AF_INET AF_INET6 AF_UNIX
LockPersonality=yes
MemoryDenyWriteExecute=yes
RestrictRealtime=yes
RestrictSUIDSGID=yes
sudo systemctl daemon-reload
sudo systemctl restart squid
Firewall Rules
Restrict inbound access to the proxy port using a host firewall. Only allow traffic from trusted internal subnets.
# nftables example
table inet filter {
chain input {
type filter hook input priority 0; policy drop;
iif "lo" accept
iif "eth0" ip saddr 10.0.0.0/8 tcp dport 3128 accept
iif "eth0" ip saddr 172.16.0.0/12 tcp dport 3128 accept
ct state established,related accept
}
}
Validating Configuration
Always validate the configuration before applying changes. A syntax error can prevent Squid from starting.
# Check syntax
sudo squid -k parse
# Test configuration without starting the daemon
sudo squid -k reconfigure
# Check for warnings
sudo squid -k check
If validation passes, reload Squid:
sudo systemctl reload squid
Best Practices Summary
- Default deny: Always end
http_accessrules withdeny all. - Bind to specific interfaces: Never bind to
0.0.0.0unless intentionally exposing the proxy. - Require authentication: Use LDAP, RADIUS, or at minimum file-based auth for all proxy access.
- Restrict ports: Only allow
safe_portsandssl_ports. Deny CONNECT to non-SSL ports. - Limit connections: Use
maxconnACLs and delay pools to prevent resource exhaustion. - Protect logs: Strip query terms, restrict log file permissions, and forward to a SIEM.
- Use TLS inspection carefully: Only with legal authorization, and exclude sensitive domains.
- Run as least privilege: Use systemd sandboxing and strict file permissions.
- Keep Squid updated: Subscribe to security advisories and patch promptly. CVEs in Squid have included cache poisoning and denial of service issues.
- Audit configuration regularly: Use version control for
squid.confand review ACL changes in code review. - Monitor actively: Set up alerts for unusual traffic patterns, authentication failures, and blocked domain hits.
- Backup configuration: Maintain offline copies of configuration, certificates, and password files.
Conclusion
Squid Proxy is a powerful and flexible tool, but its default configuration is not safe for production use. By following the hardening steps in this tutorial—binding to specific interfaces, enforcing default-deny ACLs, requiring authentication, restricting ports, limiting connections, protecting logs, sandboxing the service, and carefully managing TLS inspection—you can deploy Squid as a robust, secure proxy that protects both your users and your network perimeter. Security is not a one-time task; revisit your Squid configuration regularly as new threats emerge, keep the software patched, and continuously monitor logs for signs of abuse. A hardened Squid deployment is a strong layer in a defense-in-depth strategy, but it must be maintained with the same discipline applied to any other security-critical infrastructure component.