← Back to DevBytes

Squid Proxy Security Hardening and Best Practices

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:

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_access rules with deny all.
  • Bind to specific interfaces: Never bind to 0.0.0.0 unless intentionally exposing the proxy.
  • Require authentication: Use LDAP, RADIUS, or at minimum file-based auth for all proxy access.
  • Restrict ports: Only allow safe_ports and ssl_ports. Deny CONNECT to non-SSL ports.
  • Limit connections: Use maxconn ACLs 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.conf and 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.

🛠 Tools from DevBytes

Inventory Tracker Pro — Excel inventory system, low-stock alerts · $19
AI Dev Kit for Mac — local AI dev environment templates · $9.99
KeyMapper for Mac — custom keyboard shortcut toolkit · $7.99

← Back to all articles