Squid on FreeBSD: Caching Proxy Server Review
Squid is a caching proxy server that has been in production since 1996. It handles HTTP, HTTPS, and FTP traffic, provides access control, and caches content to reduce bandwidth usage and improve response times. On FreeBSD, Squid is well-packaged and integrates with the OS's networking stack for transparent proxying. This review covers installation, caching configuration, ACLs, SSL/TLS interception, transparent proxy setup, and performance tuning specific to FreeBSD.
Where Squid Fits Today
In an era of HTTPS-everywhere and CDNs, Squid's role has evolved. Caching HTTPS content requires SSL bumping, which is operationally complex and raises trust concerns. But Squid remains valuable for:
- Corporate networks: Enforcing access policies, logging web usage, and filtering content
- ISPs and shared networks: Reducing bandwidth on expensive links
- Development environments: Caching package repositories (apt, pkg, pip) to speed up builds
- Reverse proxy: Accelerating and protecting backend web servers
- Air-gapped or bandwidth-constrained environments: Caching software updates for distribution
Installation
Binary Package
shpkg install squid
Ports
shcd /usr/ports/www/squid make config make install clean
The ports build lets you enable or disable SSL/TLS support (for SSL bumping), ICAP support, and authentication backends.
Initial Setup
sh# Create cache directories squid -z # Enable the service sysrc squid_enable="YES" # Start Squid service squid start
The main configuration file is /usr/local/etc/squid/squid.conf. The default configuration is a good starting point but needs customization for production.
Cache Configuration
Disk Cache
Squid stores cached objects on disk. The default ufs storage type works but rock and aufs provide better performance.
sh# /usr/local/etc/squid/squid.conf # UFS cache: 10 GB, 16 L1 directories, 256 L2 directories cache_dir ufs /var/squid/cache 10000 16 256 # Or use aufs for async I/O (better performance) cache_dir aufs /var/squid/cache 10000 16 256
Memory Cache
sh# RAM cache for hot objects cache_mem 512 MB # Maximum object size in memory maximum_object_size_in_memory 2 MB # Maximum object size on disk maximum_object_size 100 MB # Minimum object size (skip tiny objects) minimum_object_size 1 KB
Cache Behavior
sh# Refresh patterns control cache lifetime # Format: refresh_pattern regex minimum_age percentage maximum_age # Package repositories (cache aggressively) refresh_pattern -i \.pkg$ 1440 100% 10080 refresh_pattern -i \.txz$ 1440 100% 10080 refresh_pattern -i \.rpm$ 1440 100% 10080 refresh_pattern -i \.deb$ 1440 100% 10080 # Default refresh pattern refresh_pattern . 0 20% 4320
ZFS Considerations
On ZFS, place the cache directory on a dedicated dataset:
shzfs create -o compression=off -o atime=off -o recordsize=64k zpool/squid-cache
Disable compression: Squid stores already-compressed content (gzip, brotli). Compressing it again wastes CPU. Set recordsize to 64K to match Squid's typical I/O pattern. Disable atime for reduced metadata overhead.
Access Control Lists (ACLs)
ACLs are Squid's policy engine. Every request is evaluated against ACLs to determine if it should be allowed, denied, or modified.
Basic ACL Structure
sh# Define ACLs acl localnet src 10.0.0.0/8 acl localnet src 172.16.0.0/12 acl localnet src 192.168.0.0/16 acl SSL_ports port 443 acl Safe_ports port 80 443 21 70 210 1025-65535 acl CONNECT method CONNECT # Apply rules (order matters - first match wins) http_access deny !Safe_ports http_access deny CONNECT !SSL_ports http_access allow localnet http_access deny all
Time-Based ACLs
shacl business_hours time MTWHF 08:00-18:00 acl social_media dstdomain .facebook.com .twitter.com .instagram.com http_access deny social_media business_hours
URL Filtering
sh# Block specific domains acl blocked_sites dstdomain "/usr/local/etc/squid/blocked_sites.txt" http_access deny blocked_sites # Block by URL regex acl blocked_urls url_regex -i "/usr/local/etc/squid/blocked_urls.txt" http_access deny blocked_urls
The blocklist files contain one entry per line:
sh# /usr/local/etc/squid/blocked_sites.txt .malware-domain.com .phishing-site.net
Authentication
Squid supports multiple authentication backends. For LDAP authentication:
shauth_param basic program /usr/local/libexec/squid/basic_ldap_auth \ -b "dc=example,dc=com" \ -f "uid=%s" \ -h ldap.example.com auth_param basic children 5 startup=5 idle=1 auth_param basic realm Corporate Proxy auth_param basic credentialsttl 2 hours acl authenticated proxy_auth REQUIRED http_access allow authenticated
SSL Bumping (HTTPS Interception)
SSL bumping lets Squid decrypt, inspect, cache, and re-encrypt HTTPS traffic. This is controversial and requires deploying a CA certificate to all clients.
Generate a CA Certificate
shmkdir -p /usr/local/etc/squid/ssl_cert cd /usr/local/etc/squid/ssl_cert openssl req -new -newkey rsa:4096 -sha256 -days 3650 -nodes \ -x509 -keyout squid-ca-key.pem -out squid-ca-cert.pem \ -subj "/C=US/ST=State/L=City/O=Org/CN=Squid Proxy CA" cat squid-ca-cert.pem squid-ca-key.pem > squid-ca-cert-key.pem chmod 400 squid-ca-key.pem squid-ca-cert-key.pem chown squid:squid squid-ca-cert-key.pem
Initialize the SSL Database
sh/usr/local/libexec/squid/security_file_certgen -c -s /var/squid/ssl_db -M 20MB chown -R squid:squid /var/squid/ssl_db
Configure SSL Bumping
sh# /usr/local/etc/squid/squid.conf http_port 3128 ssl-bump \ cert=/usr/local/etc/squid/ssl_cert/squid-ca-cert-key.pem \ generate-host-certificates=on \ dynamic_cert_mem_cache_size=20MB sslcrtd_program /usr/local/libexec/squid/security_file_certgen \ -s /var/squid/ssl_db -M 20MB # Bump all HTTPS traffic acl step1 at_step SslBump1 ssl_bump peek step1 ssl_bump bump all # Or selectively bump (inspect banking/health sites might be unwanted) acl nobump dstdomain .bank.com .healthcare.com ssl_bump splice nobump ssl_bump bump all
Deploy the CA Certificate
The CA certificate (squid-ca-cert.pem) must be installed on all client machines. Without it, browsers will show certificate errors. This is the operational cost of SSL bumping -- you are running a man-in-the-middle proxy, and clients must trust your CA.
Transparent Proxy
A transparent proxy intercepts traffic without requiring client configuration.
FreeBSD PF Configuration
sh# /etc/pf.conf ext_if = "em0" int_if = "em1" # Redirect HTTP traffic to Squid rdr on $int_if proto tcp from any to any port 80 -> 127.0.0.1 port 3128 # For HTTPS transparent interception (requires SSL bump) rdr on $int_if proto tcp from any to any port 443 -> 127.0.0.1 port 3129
Squid Configuration for Transparent Mode
sh# HTTP transparent http_port 3128 intercept # HTTPS transparent (requires SSL bump) https_port 3129 intercept ssl-bump \ cert=/usr/local/etc/squid/ssl_cert/squid-ca-cert-key.pem \ generate-host-certificates=on \ dynamic_cert_mem_cache_size=20MB
Enable IP forwarding:
shsysrc gateway_enable="YES" sysctl net.inet.ip.forwarding=1
WCCP Alternative
If you use a Cisco router, Squid supports WCCP (Web Cache Communication Protocol) for redirecting traffic to the proxy without PF rules. This is an enterprise deployment pattern.
Reverse Proxy (Accelerator) Mode
Squid can act as a reverse proxy in front of web servers:
shhttp_port 80 accel vhost cache_peer backend1.internal parent 8080 0 no-query originserver name=web1 cache_peer backend2.internal parent 8080 0 no-query originserver name=web2 cache_peer_access web1 allow all
This is useful for caching static assets in front of application servers. However, for pure reverse proxy workloads, nginx or HAProxy are typically better choices. Squid's strength is in its caching logic, not load balancing.
Performance Tuning for FreeBSD
File Descriptors
Squid needs many file descriptors under load. FreeBSD defaults are often too low:
sh# /etc/sysctl.conf kern.maxfiles=65536 kern.maxfilesperproc=32768 # /etc/login.conf - increase for the squid user # Or in /boot/loader.conf for system-wide effect
Check Squid's FD usage:
shsquidclient mgr:info | grep "File descriptor"
Network Tuning
sh# /etc/sysctl.conf net.inet.tcp.sendspace=131072 net.inet.tcp.recvspace=131072 net.inet.tcp.sendbuf_max=16777216 net.inet.tcp.recvbuf_max=16777216
DNS Resolution
Squid handles DNS internally. Configure it to use local resolvers:
sh# /usr/local/etc/squid/squid.conf dns_nameservers 10.0.0.1 10.0.0.2 dns_timeout 10 seconds positive_dns_ttl 6 hours negative_dns_ttl 1 minute
Worker Processes
For multi-core systems, Squid can run multiple worker processes:
shworkers 4
Each worker handles a portion of the traffic. This is the primary horizontal scaling mechanism.
Monitoring
Squid's built-in cache manager provides detailed statistics:
sh# Allow cache manager access from localhost http_access allow localhost manager http_access deny manager # Query statistics squidclient mgr:info squidclient mgr:5min squidclient mgr:storedir
Logging
sh# Standard access log access_log daemon:/var/log/squid/access.log squid # Or JSON format for log analysis logformat json {"time":"%{%Y-%m-%dT%H:%M:%S}tl","client":"%>a","method":"%rm","url":"%ru","status":%>Hs,"size":%<st,"cache":"%Ss"} access_log daemon:/var/log/squid/access.json json # Rotate logs logfile_rotate 7
Set up log rotation:
sh# /usr/local/etc/newsyslog.conf.d/squid.conf /var/log/squid/access.log squid:squid 640 7 * @T00 BC /var/run/squid/squid.pid 30
Practical Deployment: Package Repository Cache
One of the most useful Squid deployments on FreeBSD is caching package repositories:
sh# Cache pkg, apt, yum repositories refresh_pattern -i \.pkg$ 10080 100% 43200 override-expire override-lastmod refresh_pattern -i \.txz$ 10080 100% 43200 override-expire override-lastmod refresh_pattern -i \.deb$ 10080 100% 43200 override-expire override-lastmod refresh_pattern -i \.rpm$ 10080 100% 43200 override-expire override-lastmod # Large maximum object size for package files maximum_object_size 500 MB
Point your FreeBSD clients at the proxy:
sh# /usr/local/etc/pkg.conf PKG_ENV: { HTTP_PROXY: "http://proxy.internal:3128" }
This dramatically reduces bandwidth on repeated pkg install and pkg upgrade operations across multiple servers.
Verdict
Squid is a mature, battle-tested proxy server that works reliably on FreeBSD. The caching engine is powerful, ACLs are flexible, and the transparent proxy integration with PF works well.
The downsides are real: configuration syntax is dense and error-prone, SSL bumping is complex to deploy and maintain, and the documentation -- while extensive -- is scattered. Modern HTTPS-heavy traffic patterns reduce the value of a caching proxy unless you deploy SSL bumping.
For package caching, content filtering, and reverse proxy acceleration, Squid is still a solid choice. For pure load balancing or simple reverse proxying, look at nginx or HAProxy instead.
Rating: 7/10 -- Powerful but showing its age. The caching engine and ACL system are excellent. The configuration complexity and SSL bumping overhead drag it down.
Frequently Asked Questions
Does Squid cache HTTPS content without SSL bumping?
No. Without SSL bumping, Squid can only see the CONNECT tunnel. It forwards the encrypted traffic without inspecting or caching it. You get access control (allow/deny based on domain) but no content caching.
How much RAM does Squid need?
Minimum 256 MB for a small deployment. For production with 10,000+ users, allocate 2-4 GB for cache_mem plus memory for the URL and DNS caches. The formula is roughly: cache_mem + 14 bytes per cached object on disk + 100 bytes per hot object in memory.
Can I run Squid in a FreeBSD jail?
Yes. Squid runs well in a jail. For transparent proxy mode, the jail needs access to PF or IPFW rules, which requires cooperation from the host. A simpler approach is running Squid in a jail with explicit proxy configuration on clients.
How do I clear the Squid cache?
shservice squid stop rm -rf /var/squid/cache/* squid -z service squid start
Or purge specific URLs:
shsquidclient -m PURGE http://example.com/path/to/cached/file
How do I see cache hit rates?
shsquidclient mgr:5min | grep -i "hit"
Healthy cache hit rates for HTTP traffic range from 20-40%. With package repository caching, hit rates of 80%+ are common.
Can Squid integrate with pfBlockerNG or similar blocklists?
Squid's ACL system natively supports blocklists. Use dstdomain ACLs with external files. Tools like SquidGuard provide more sophisticated URL categorization if you need content-category-based filtering.