$linuxjunkies
>

Set Up Squid as a Caching Web Proxy

Install and configure Squid as a forward caching proxy on Linux — covering ACLs, cache tuning, firewall rules, and explicit vs transparent intercept mode.

IntermediateUbuntuDebianFedoraArch9 min readUpdated June 7, 2026

Before you start

  • A Linux server with a static IP address on your network
  • sudo or root access
  • Basic familiarity with editing text files and systemd service management

Squid is a mature, high-performance caching proxy that can dramatically cut bandwidth usage and speed up repeated web requests on your network. This guide walks through a production-ready forward proxy setup: installing Squid, tuning cache and memory, opening the right firewall ports, and choosing between explicit (client-configured) and transparent (intercept) mode. Commands are shown for Debian/Ubuntu, Fedora/RHEL family, and Arch.

Install Squid

Debian / Ubuntu

sudo apt update && sudo apt install squid -y

Fedora / RHEL / Rocky Linux

sudo dnf install squid -y

Arch Linux

sudo pacman -S squid

After installation, enable and start the service:

sudo systemctl enable --now squid

Confirm it is running:

sudo systemctl status squid

Output will show active (running) if everything started cleanly.

Understand the Default Configuration

The main configuration file is /etc/squid/squid.conf. It is heavily commented by default — useful as reference, but dense. Before making changes, take a backup:

sudo cp /etc/squid/squid.conf /etc/squid/squid.conf.orig

Key defaults to know:

  • Squid listens on port 3128 (TCP) by default.
  • Only localhost is allowed to use the proxy out of the box via the localnet ACL.
  • The disk cache directory is /var/spool/squid (Debian/Ubuntu) or /var/spool/squid (RHEL/Arch) with a modest default size.

Configure Access Control

Squid uses ACL rules to decide who can use the proxy. Open /etc/squid/squid.conf and locate the ACL section. Add your local network:

sudo nano /etc/squid/squid.conf

Find the existing localnet ACL definitions and add or adjust the line that matches your subnet:

# Replace 192.168.1.0/24 with your actual LAN subnet
acl localnet src 192.168.1.0/24

Then ensure the http_access allow localnet line appears before the http_access deny all line. A minimal, safe block looks like this:

acl localnet src 192.168.1.0/24
acl SSL_ports port 443
acl Safe_ports port 80
acl Safe_ports port 443
acl Safe_ports port 21
acl CONNECT method CONNECT

http_access deny !Safe_ports
http_access deny CONNECT !SSL_ports
http_access allow localhost manager
http_access deny manager
http_access allow localnet
http_access allow localhost
http_access deny all

The CONNECT method ACL is critical: without restricting it to SSL ports, clients could tunnel arbitrary traffic through your proxy.

Tune Cache Size and Memory

The defaults are conservative. Adjust these directives in squid.conf to match your server's resources:

# Disk cache: size in MB, path, and storage format
cache_dir ufs /var/spool/squid 4096 16 256

# RAM used for hot objects (aim for ~256 MB on a mid-range server)
cache_mem 256 MB

# Maximum object size stored on disk
maximum_object_size 64 MB

# Maximum object kept in RAM
maximum_object_size_in_memory 512 KB

The four numbers after the path in cache_dir are: total size in MB, first-level subdirectory count, second-level subdirectory count. The defaults (16 256) are fine for most deployments — only change them if Squid documentation explicitly recommends it for your load.

If you changed cache_dir to a new path or a larger size, initialise the cache structure before restarting:

sudo squid -z

Set the Listening Port

The default port 3128 is conventional and fine for most setups. If you need to change it:

http_port 3128

For transparent / intercept mode (traffic redirected by the firewall, no client configuration required), add a second listener:

http_port 3129 intercept

Transparent mode requires firewall rules to redirect traffic — covered in the next section. Note that transparent proxying only works for plain HTTP. HTTPS requires SSL-bump (TLS inspection), which is a significantly more complex setup with legal and trust implications; it is out of scope here.

Open Firewall Ports

ufw (Debian / Ubuntu)

sudo ufw allow 3128/tcp comment 'Squid explicit proxy'
# If using transparent mode:
sudo ufw allow 3129/tcp comment 'Squid transparent proxy'

firewalld (Fedora / RHEL / Rocky)

sudo firewall-cmd --permanent --add-port=3128/tcp
# If using transparent mode:
sudo firewall-cmd --permanent --add-port=3129/tcp
sudo firewall-cmd --reload

nftables (Arch or manual setup)

sudo nft add rule inet filter input tcp dport { 3128, 3129 } accept

Make nftables rules persistent by saving them to your ruleset file (/etc/nftables.conf) and ensuring the service is enabled.

Transparent mode: redirect traffic with nftables

If using intercept mode, redirect outbound port 80 from your LAN interface to Squid's intercept port. Run this on the Squid host acting as the gateway, replacing eth0 with your LAN-facing interface:

sudo nft add table ip nat
sudo nft add chain ip nat PREROUTING { type nat hook prerouting priority -100 \; }
sudo nft add rule ip nat PREROUTING iifname "eth0" tcp dport 80 redirect to :3129

Apply Configuration and Restart

Parse the configuration for syntax errors before restarting:

sudo squid -k parse

If no errors are reported, reload gracefully (preserves existing connections) or restart for a full reset:

# Graceful reload
sudo systemctl reload squid

# Full restart
sudo systemctl restart squid

Configure Clients (Explicit Proxy Mode)

For explicit proxy, clients must be told to use the proxy. Point them to your Squid server's IP and port 3128.

Browser / system-level

Set the HTTP proxy to http://<squid-server-ip>:3128 in system or browser network settings. Most desktop environments on both X11 and Wayland honour the system proxy setting.

Command-line tools

export http_proxy="http://192.168.1.10:3128"
export https_proxy="http://192.168.1.10:3128"
export no_proxy="localhost,127.0.0.1,192.168.1.0/24"

Add these to /etc/environment for system-wide persistence.

Automatic configuration (PAC / WPAD)

For larger deployments, serve a PAC file and configure DHCP option 252 or DNS-based WPAD to distribute proxy settings automatically. This is the preferred approach for managing more than a handful of clients.

Verify Caching Is Working

Fetch a URL twice through the proxy and inspect the headers for a cache hit:

curl -x http://192.168.1.10:3128 -I http://example.com
curl -x http://192.168.1.10:3128 -I http://example.com

On the second request, look for X-Cache: HIT from <hostname> in the response headers. You can also tail the access log in real time:

sudo tail -f /var/log/squid/access.log

A cache hit line will contain TCP_HIT; a miss shows TCP_MISS. Check overall cache statistics:

sudo squidclient -h 127.0.0.1 mgr:info | grep -E 'Hits|Misses|Memory'

Troubleshooting

  • "Access Denied" on every request: Your client's source IP is not matched by an acl localnet line, or the http_access allow localnet rule is positioned after http_access deny all. ACL order in squid.conf is evaluated top-down and stops at the first match.
  • Squid won't start after cache_dir change: Run sudo squid -z to initialise the new directory structure. Ensure the directory is owned by the squid user (sudo chown -R squid:squid /var/spool/squid).
  • Transparent mode not intercepting traffic: Confirm IP forwarding is enabled (sysctl net.ipv4.ip_forward should return 1; enable with sudo sysctl -w net.ipv4.ip_forward=1 and persist in /etc/sysctl.d/). Double-check the nftables PREROUTING rule matches your actual interface name.
  • HTTPS sites fail through transparent proxy: Expected. Transparent interception of TLS without SSL-bump is not possible. For HTTPS to work transparently you need SSL-bump with a custom CA, which is a separate, complex configuration.
  • High memory use: Squid's cache_mem is a soft limit; actual process memory will exceed it. Leave headroom on the host — a server with 2 GB RAM should not exceed cache_mem 512 MB.
tested on:Ubuntu 24.04Debian 12Rocky 9Arch rolling

Frequently asked questions

What is the difference between explicit and transparent proxy mode in Squid?
In explicit mode, clients are configured (manually or via PAC/WPAD) to send requests to the proxy address. In transparent mode, the firewall redirects outbound traffic to Squid without any client configuration, but this only works reliably for plain HTTP — not HTTPS without SSL-bump.
Can Squid cache HTTPS traffic?
Not by default. Squid tunnels HTTPS via the CONNECT method without inspecting or caching the content. To cache HTTPS you need SSL-bump with a custom CA certificate installed on all clients, which is a complex setup with privacy and legal considerations.
How do I check how much disk space Squid's cache is using?
Run sudo squidclient -h 127.0.0.1 mgr:storedir to see cache directory usage and fill levels, or simply check with du -sh /var/spool/squid.
Does changing squid.conf take effect immediately on reload?
Most directives take effect on a graceful reload (systemctl reload squid), which re-reads the config without dropping existing connections. Changes to cache_dir require a full restart and sometimes squid -z to reinitialise the cache structure.
How do I stop Squid from logging specific domains or clients?
Use the access_log directive with ACL conditions, or add a no_cache ACL combined with cache deny to prevent storing content from specific domains. Use cache_access_log none for clients or destinations you want to exclude from logging.

Related guides