Squid Proxy on Ubuntu 24.04: Install, Auth and squid.conf

Published:

14 minute read

Acar Diveroli
Written by: Acar Diveroli
Isometric tower of cache cubes with a blue HIT cube in the middle; orbits carry ACL, AUTH and PARENT PEER tags, port 3128

A five-person data team wants its test servers to download packages from one place and to reach a supplier's API from the same IP address every time. Someone installs Squid on a small VPS in ten minutes. A week later, access.log is full of addresses nobody recognises: the configuration came from a forum post ending in http_access allow all, and strangers now send their traffic out through the team's IP.

This guide installs Squid on Ubuntu 24.04 without that mistake. It covers what Squid is, the order in which it checks a request and what one server can and cannot give you. Then comes one complete configuration file with an IP allowlist, a login, a disk cache and header settings, a parent proxy with cache_peer, and the commands that test it.

What is a Squid proxy?

Squid is an open-source caching proxy server. A proxy server sends requests on your behalf and passes the answers back (What Is a Proxy Server?). Squid usually runs as a forward proxy that works for the clients behind it, not as a reverse proxy in front of a website (Forward Proxy vs Reverse Proxy). It carries HTTP, HTTPS through CONNECT tunnels and FTP, with access rules, login helpers, a cache and a request log.

The Squid project's current stable release is 7.7, published on 24 August 2026, and its developers support only the latest stable release. Ubuntu 24.04 ships Squid 6.14, package 6.14-0ubuntu0.24.04.4 in noble-updates, and its security fixes arrive through normal Ubuntu updates. This guide uses that package.

How does Squid handle a request?

The order of these steps explains most configuration mistakes.

  1. The client connects to the port in http_port, 3128 in Ubuntu's configuration.
  2. Squid reads the http_access lines from top to bottom. The first line whose conditions all match decides. The http_access documentation adds that when no line matches, Squid does the opposite of the last line, so every list should end with http_access deny all.
  3. A rule that needs a login asks for one. When Squid reaches a proxy_auth condition without valid credentials, it answers 407 Proxy Authentication Required (Proxy Authentication Methods).
  4. Plain HTTP is looked up in the cache. A fresh stored copy is a hit and never leaves the server; anything else is a miss and is fetched from the site.
  5. HTTPS becomes a tunnel. After CONNECT example.com:443 succeeds, Squid only relays encrypted bytes. RFC 9110 calls this "blind forwarding of data", so Squid can neither cache the page nor add headers inside the tunnel.
  6. A parent proxy takes over if you set one with cache_peer and never_direct.
  7. Squid writes one line to access.log with the client, result code, size, URL and username.

What does your own Squid server give you, and what doesn't it?

QuestionYour own Squid (one VPS)Commercial datacenter proxyResidential or rotating pool
Exit IPThe VPS's single data center IPThe provider's data center IPs, several if neededHome connection IPs, per request or session
LocationThe city where the server runsA choice of the provider's countriesA country, sometimes a city
MaintenanceYou: updates, rules, passwords, logsThe provider; you manage credentialsThe provider; you manage credentials
Cache and access controlHTTP cache, rules, one central logNo cache; users in a dashboardNo cache; users in a dashboard

Squid gives you control over who connects, what gets cached and what gets logged. It cannot give you a second address: a site that sees hundreds of requests a minute from that one data center IP will slow it down or block it (Residential vs Datacenter Proxy).

How do you install Squid on Ubuntu 24.04?

apache2-utils adds htpasswd for the password file. Keeping a read-only copy of the original configuration follows the official Ubuntu Server guide.

bash
sudo apt update
sudo apt install squid apache2-utils
squid -v | head -n 1                       # the installed version
systemctl status squid --no-pager          # should say "active (running)"

sudo cp /etc/squid/squid.conf /etc/squid/squid.conf.original
sudo chmod a-w /etc/squid/squid.conf.original

# where will your own rules be read?
grep -n "include /etc/squid/conf.d" /etc/squid/squid.conf
grep -n "^http_access deny all" /etc/squid/squid.conf

Put your settings in a file under /etc/squid/conf.d/, so package upgrades leave them alone. The Debian packaging that Ubuntu builds on places include /etc/squid/conf.d/*.conf under the comment INSERT YOUR OWN RULE(S) HERE: after the rules that block unsafe ports, before http_access allow localhost and http_access deny all. The include line number from grep must be smaller than the deny all one; if not, put your lines into squid.conf at that comment. The folder's debian.conf sets logfile_rotate 0, because logrotate handles the logs.

A complete team.conf for a locked-down proxy

Save this as /etc/squid/conf.d/team.conf. Replace the documentation network 203.0.113.0/24 with your office network or your team's fixed IPs.

text
# /etc/squid/conf.d/team.conf
# Read inside the http_access list of squid.conf, above "http_access deny all".
# Never add "http_access allow all": it turns this server into an open proxy.

# 1. Which networks may connect
acl team_net src 203.0.113.0/24

# 2. Username and password from /etc/squid/passwords.
#    Keep the auth_param lines above the proxy_auth ACL.
auth_param basic program /usr/lib/squid/basic_ncsa_auth /etc/squid/passwords
auth_param basic children 5 startup=5 idle=1
auth_param basic realm Team proxy
auth_param basic credentialsttl 2 hours
acl team_users proxy_auth REQUIRED

# 3. Allow only when BOTH match: the right network AND a valid login.
#    Everything else falls through to "http_access deny all".
http_access allow team_net team_users

# 4. Do not pass client addresses in plain HTTP requests
forwarded_for delete
via off

# 5. Cache: memory, largest object to store, then the disk cache
cache_mem 512 MB
maximum_object_size 512 MB
cache_dir ufs /var/spool/squid 10000 16 256

Then add users, check the syntax, restart once and open the port only to known addresses:

bash
sudo htpasswd -c /etc/squid/passwords team1   # -c creates the file: first user only
sudo htpasswd /etc/squid/passwords team2      # later users: without -c
sudo chown root:proxy /etc/squid/passwords
sudo chmod 640 /etc/squid/passwords

sudo squid -k parse                           # prints errors and warnings, if any
sudo systemctl restart squid                  # once, for the new cache_dir
sudo tail -n 20 /var/log/squid/cache.log      # startup messages

sudo ufw allow OpenSSH                        # keep your SSH session reachable
sudo ufw allow from 203.0.113.0/24 to any port 3128 proto tcp
sudo ufw enable

How do you write the acl and http_access rules?

An acl line names a condition; an http_access line combines names into a decision. Conditions on one line must all match, so allow team_net team_users means "from our network and logged in". Separate lines are alternatives: for a second office, add acl office2 src 198.51.100.0/24 and http_access allow office2 team_users.

Position matters as much as content. An allow below http_access deny all is never reached, and every client gets 403. Leave the rules above the include untouched: deny CONNECT !SSL_ports lets tunnels reach only port 443. RFC 9110 advises limiting CONNECT to known ports, because a proxy that tunnels to any port can be used to relay spam to port 25.

To change the port, edit the existing http_port 3128 line in squid.conf instead of adding a second one, and update the firewall. A new port protects nothing; the ACL and the firewall do. What 3128 and 8080 mean is in Port 8080 and Other Proxy Ports.

How do you add a username and password?

htpasswd stores one line per user with a hashed password. Its default hash is MD5, which Squid's basic_ncsa_auth helper reads; on Ubuntu the helper is /usr/lib/squid/basic_ncsa_auth. It runs as the proxy user, hence the file's proxy group. The auth_param lines start up to five helpers, set the login prompt text and let Squid trust a correct login for two hours before checking the file again.

Squid's auth_param documentation states that a client is asked for credentials only when an http_access rule evaluates a proxy_auth ACL. Configure auth_param without using team_users in http_access, and Squid never asks for a password.

Basic authentication sends the password Base64-encoded, not encrypted, in every Proxy-Authorization header between client and Squid. Anyone watching that path can read it, which is why the allowlist stays next to the password. Reading a 407 is covered in Proxy Authentication Methods.

How do you set up caching and read the logs?

cache_mem sets the memory for hot objects (default 256 MB). cache_dir ufs /var/spool/squid 10000 16 256 adds up to 10,000 MB of disk cache in 16 first-level and 256 second-level folders; Squid's documentation warns against entering the whole disk size. maximum_object_size defaults to 4 MB, which leaves larger package files uncached, so raise it. It sets the default size limit for every cache_dir, which is why the file above puts it first.

squid -z creates the cache folders, and Ubuntu's service file runs squid --foreground -z before every start, so the restart builds them. For later rule or user changes, sudo systemctl reload squid sends the same signal as squid -k reconfigure.

The cache only helps plain HTTP. Ubuntu's mirrors usually use http:// addresses and apt checks package signatures, so CI machines that point apt at Squid download each package once (Linux Proxy Settings). HTTPS never produces a hit. Opening it for caching (SSL bump) needs Squid's certificate on every client and the separate squid-openssl package, and is outside this guide.

/var/log/squid/access.log has one line per request, and cache.log holds startup messages and errors; logrotate rotates both daily and keeps two old copies. The result code tells you what happened:

Result codeMeaning
TCP_MISS/200Fetched from the site
TCP_HIT/200, TCP_MEM_HIT/200Served from the disk or memory cache
TCP_TUNNEL/200HTTPS tunnel; Squid saw only host and port
TCP_DENIED/407No login or a wrong one
TCP_DENIED/403Refused by http_access: wrong network or rule order

How do you remove the Via and X-Forwarded-For headers?

By default Squid appends the client's IP to X-Forwarded-For (forwarded_for on) and adds a Via header (via on). forwarded_for delete removes the header, off writes unknown instead of the address, and via off drops Via. Both work only on plain HTTP; inside a tunnel Squid adds nothing anyway. To check the result with an echo request, see Anonymous Proxy Levels.

One exit for the team: cache_peer with a parent proxy

A team on a commercial proxy may not want its password on every laptop and CI job. Squid can sit in between: people log in to Squid with their own accounts, and only the server knows the commercial credentials. Add to team.conf:

text
# Send every request through the parent proxy. Clients never see its password.
cache_peer pr.proxynet.io parent 8000 0 no-query default login=user:pass
never_direct allow all

Following the cache_peer documentation: host, type parent, proxy port 8000, and ICP port 0 because the peer answers no ICP queries. no-query turns those queries off, default makes it the last-resort parent, and login= sends the parent's credentials; write a % in the password as %%.

Without never_direct allow all, Squid may fetch some requests directly from the VPS's own IP. For HTTPS, Squid passes the CONNECT to the parent. In access.log, the hierarchy field then names the parent with a code such as DEFAULT_PARENT instead of HIER_DIRECT.

A password change is now one line and a reload, every request is logged with the member's username, and plain HTTP is still cached. With a Rotating Proxy as parent, the provider changes the exit IP while Squid keeps one address (IP Rotation Explained). The chain manages credentials; it does not hide who you are, and the provider's terms and each site's rules still apply.

How do you connect a client and test it?

Run this from a machine in the allowed network; 198.51.100.20 stands for your server.

bash
# 1. Without a login: Squid asks for one
curl -x http://198.51.100.20:3128 https://httpbin.org/ip
# curl: (7) CONNECT tunnel failed, response 407

# 2. With a login: the answer shows the server's IP, not yours
curl -x http://team1:pass@198.51.100.20:3128 --retry 3 https://httpbin.org/ip

# 3. On the server: the last three requests
sudo tail -n 3 /var/log/squid/access.log

We ran the curl side with curl 8.21 against a local test proxy that requires a login: the first command printed the line above, the second returned the proxy's exit address. --retry 3 repeats after a timeout or a transient HTTP code such as 429 or 503, never after a 407. More in cURL with a Proxy and How to Test a Proxy.

What do you use your own proxy server for?

  • A fixed exit IP for an API: only the API traffic goes through Squid (Static IP for API Access).
  • Office web access control: dstdomain ACLs and access.log, with employees told beforehand (Proxy vs Firewall).
  • Office browser settings: a PAC file tells each browser when to use Squid (PAC File).
  • A package cache for CI machines: apt fetches each plain HTTP package once (Linux Proxy Settings).
  • Not for data work across countries: price checks and scraping by location need many addresses (data scraping).

Common mistakes

  • http_access allow all. An open proxy, whose IP soon lands on block lists (IP Blacklist).
  • auth_param without proxy_auth in http_access. No password is ever asked.
  • An allow below deny all. Never reached; everyone gets 403.
  • 3128 open to the internet. A password alone invites guessing, and basic auth sends it unencrypted.
  • Expecting HTTPS cache hits. Tunnels are never cached.
  • Skipping squid -k parse. A typo stops the service; journalctl -u squid shows why.
  • maximum_object_size left at 4 MB for a package cache, or a cache_dir bigger than the free disk.
  • Heavy scraping from the VPS IP. Sites answer 429, then block (HTTP Status Codes in Web Scraping).

Decision guide

NeedRecommendation
The team must reach an API from one IPSquid on a fixed-IP VPS with allowlist and login, or a Static Proxy
CI machines download the same packages again and againSquid with cache_dir and a larger maximum_object_size; gains come from HTTP mirrors
The office wants to see and limit visited sitesdstdomain ACLs and access.log; inform employees first
The commercial proxy password should stay on one serverSquid for clients, cache_peer to the provider, never_direct allow all
You need IPs in other countries, or many IPsNot your own Squid: a datacenter proxy, or a residential and rotating pool
You want HTTPS pages cachedNot with the default package; cache plain HTTP sources only

Frequently asked questions

Which port does Squid use?

Ubuntu's configuration sets http_port 3128, so Squid listens on 3128 after installation. You can change that line and the firewall rule together, but a different port adds no protection; the network ACL, the login and the firewall do. What the common proxy port numbers mean is explained in our port 8080 guide.

Can Squid cache HTTPS sites?

Not in its default setup. An HTTPS request arrives as a CONNECT tunnel, and Squid relays encrypted bytes without seeing the page, so there is nothing to store. SSL bump, which opens the traffic, needs a Squid certificate on every client device and the squid-openssl package, and is outside this guide.

How do I apply squid.conf changes without stopping the service?

Run sudo squid -k parse first, so a typo cannot take the proxy down. Then run sudo systemctl reload squid, which sends the same signal as squid -k reconfigure and keeps the service running. After adding or moving a cache_dir, restart once instead, so the service creates the cache folders.

Where are the Squid logs, and how do I read them?

On Ubuntu they are in /var/log/squid/: access.log has one line per request, cache.log has startup messages and errors. In access.log, read the result code: TCP_HIT came from the cache, TCP_MISS from the site, TCP_TUNNEL is HTTPS, and TCP_DENIED with 407 or 403 means refused.

What is the difference between Squid and Tinyproxy?

Tinyproxy describes itself as a light-weight HTTP and HTTPS proxy daemon for systems too small for a full proxy, and its configuration manual lists no cache settings. Squid adds a memory and disk cache, detailed ACLs, several login helpers and parent proxy chains. For plain forwarding on a small device, Tinyproxy may be enough.

Does my own Squid server hide my identity?

Only partly. Sites see the VPS's IP instead of your home address, and forwarded_for delete with via off removes the proxy headers from plain HTTP. But that IP belongs to a data center, is rented in your name and always comes from one place. Squid is a tool for access control and a shared exit, not for anonymity.

Summary

Squid gives you your own forward proxy with access control, a cache for plain HTTP and one log for every request. A safe setup keeps three things in order: a network ACL, a proxy_auth login used in http_access, and http_access deny all at the end, with the firewall open only to known addresses. The limit is the address: one server is one data center IP in one place. When a job needs more addresses or other countries, a Datacenter Proxy or a Residential Proxy fills the gap, and our proxy services page compares the options.

Ask ChatGPTAsk Claude