Squid FAQ: common problems, questions and fixes
Most Squid problems come down to three things: the order of http_access rules, content that is not cacheable in the first place, and HTTPS, which Squid passes through without reading. The answers below cover the questions that come up most, with the exact directives to check.
Access and connections
Why do clients get “Access Denied”?
An http_access rule refused the request. Squid reads the rules from the top and stops at the first one that matches. If no rule matches, it does the opposite of the last rule. Common causes:
- Your
http_access allow localnetline sits belowhttp_access deny all, so it never runs. - The client’s address is not in your
localnetACL (check the subnet and mask). - You put two different addresses on one line, such as
http_access allow pcA pcB. Elements on one line are combined with AND, so no single request can match both. Put both addresses in one ACL instead; values inside one ACL are combined with OR.
To see why a request was refused, add debug_options ALL,1 33,2, run squid -k reconfigure, and read cache.log: it then shows a line for every access decision. Remove the line afterwards, as it is noisy.
Clients cannot connect to the proxy at all. What should I check?
Check, in order: Squid is running (systemctl status squid); it listens where you think (ss -ltnp | grep 3128); the host firewall lets the port in (on RHEL, firewall-cmd --permanent --add-port=3128/tcp then firewall-cmd --reload); and on SELinux systems a non-standard port has the squid_port_t type (semanage port -a -t squid_port_t -p tcp 8080).
Is it safe to allow all addresses for a quick test?
No. An open proxy on a public address is found by scanners quickly and used to send spam and attacks that look like they came from you. Allow only your own networks, and keep the default deny !Safe_ports and deny CONNECT !SSL_ports lines above your allow rules.
Caching
Why does access.log show TCP_MISS for everything?
Usually because the traffic cannot be cached:
- It is HTTPS. Most traffic today is encrypted. Squid relays it through a tunnel (logged as
TCP_TUNNEL) and cannot see or store it. - The server forbids it.
Cache-Control: no-storeorprivateresponses must not be stored by a shared cache such as Squid. - The URL looks dynamic. The default
refresh_pattern -i (/cgi-bin/|\?) 0 0% 0line treats URLs with/cgi-bin/or a?as never fresh unless the server says otherwise. - There is no disk cache. Without a
cache_dirline Squid keeps objects in memory only, so they vanish on restart.
Test with a plain-HTTP static file and request it twice: curl -sI -x http://proxy:3128 http://example.org/image.png. The second request should log TCP_HIT, TCP_MEM_HIT or TCP_REFRESH_UNMODIFIED (Squid checked with the server and got 304 Not Modified). See how web caching works for the rules servers use.
Can I make Squid cache things the server says not to?
refresh_pattern has options such as override-expire, ignore-reload, ignore-no-store and ignore-private. The Squid documentation warns that they break the HTTP rules and that you are responsible for what goes wrong, such as users seeing someone else’s private page. Use them only for content you control.
HTTPS and CONNECT
How does Squid handle HTTPS?
A browser configured to use a proxy sends CONNECT example.com:443. Squid checks the request against http_access, opens a TCP connection to the server, and then copies encrypted bytes in both directions. It sees the host name and port, but not the URL path or the content, and it cannot cache anything. The default rule http_access deny CONNECT !SSL_ports stops clients from tunnelling to ports other than 443.
Decrypting HTTPS needs the SSL-Bump feature, a certificate authority installed on every client, and a clear legal basis. It is covered in our interception guide.
Logs
What do the fields in access.log mean?
The native format has ten fields: time (Unix seconds with milliseconds), elapsed time in milliseconds, client address, result code/HTTP status (for example TCP_MISS/200), bytes sent to the client, method, URL, user name (or -), hierarchy code/peer (for example HIER_DIRECT/203.0.113.5), and content type.
Can I log in Apache “combined” format?
Yes. common and combined are built-in format names, so you can write:
access_log daemon:/var/log/squid/access.log combined
Most web-log analyzers read that format directly. For rotation, either run squid -k rotate from cron with logfile_rotate set to the number of old files to keep, or set logfile_rotate 0 and let logrotate handle it.
Memory and restarts
Why does Squid use far more memory than cache_mem?
cache_mem (default 256 MB) only sets the space for hot objects in RAM. It is not a limit on the process. Squid also keeps an index of every object on disk: roughly 14 MB per GB of cache_dir on a 64-bit build. The Squid wiki’s rule of thumb is that cache_mem is about a third of total use.
Example: a 100 GB disk cache needs about 100 × 14 = 1,400 MB of index, plus 256 MB of cache_mem, plus overhead: around 1.7 GB. The wiki recommends at least twice that in physical RAM. If the machine starts swapping, Squid slows to a crawl; shrink the cache_dir rather than raising cache_mem.
Should I reconfigure or restart after editing squid.conf?
Run squid -k parse first to catch typos. Then squid -k reconfigure re-reads the file in the running process; that is enough for ACLs, rules and most settings. Do a full stop and start (systemctl restart squid) when you remove a cache_dir, and run squid -z after adding one so Squid creates its directory structure.
How do I remove one object from the cache?
Allow the PURGE method from the proxy itself only, then send a PURGE request:
acl PURGE method PURGE
http_access allow localhost PURGE
http_access deny PURGE
curl -s -o /dev/null -w '%{http_code}\n' -X PURGE -x http://127.0.0.1:3128 http://example.org/old.css
200 means the object was removed; 404 means it was not in the cache. There is no wildcard purge: each URL has to be purged on its own.
Authentication
How do I require a user name and password?
Use the Basic scheme with the NCSA helper and an htpasswd file (the path below is the Debian and Ubuntu location of the helper):
auth_param basic program /usr/lib/squid/basic_ncsa_auth /etc/squid/passwords
auth_param basic children 5
auth_param basic realm Proxy
auth_param basic credentialsttl 2 hours
acl authenticated proxy_auth REQUIRED
http_access deny !authenticated
http_access allow localnet authenticated
http_access deny all
Create users with htpasswd -c /etc/squid/passwords alice (drop -c for the second user onward). Basic authentication sends the password as cleartext, so use it only on a trusted network. Authentication does not work on intercept or tproxy ports, because the browser does not know a proxy is there.
Sources
- Access controls FAQ, Squid wiki
- refresh_pattern directive, Squid configuration reference
- Squid log files FAQ, Squid wiki
- Log format, Squid wiki
- logformat directive, Squid configuration reference
- Squid memory FAQ, Squid wiki
- cache_mem directive, Squid configuration reference
- Operating Squid FAQ, Squid wiki
- NCSA authentication example, Squid wiki
- http_port directive, Squid configuration reference
- RFC 7617: The Basic HTTP Authentication Scheme, IETF
- Configuring the Squid caching proxy server, Red Hat