Prefix
This is my second fact-collecting blog of the squid caching server series. Again, most of them will be collected from the web and reposted here, giving credit where credit is due of course.
About
- Squid is a very powerful proxy server app with very little and awful documentation.
- The google might not be your friend for this, because, caution: some config directives may be outdated.
Installation
Just install through your package manager. Check your version e.g. 3.5.4
. Enable with systemctl enable --now squid
. Check if it crashed with systemctl status squid
since it won't display any info in the command line. Check logs in /var/log/squid
- they only show up once squid has started.
Your magic command will be squid -k reconfigure
which reloads the config file after any changes.
Setting up
The key is getting the config file /etc/squid/squid.conf
right. It's like black magic with very little feedback.
The config file consists of directives. They do 3 things:
- Who and how can access the proxy, and what they can access:
-
acl
: define access control lists (source, destination, protocol etc.), -
http_access
: control access for ACLs (checked in order, first rejection rejects request)
-
- How the proxy can be reached and what it actually does to incoming requests:
-
http_port, https_port
: where the proxy listens -
ssl_bump
: splice, peek and bump (intercept/inspect) some SSL connections -
cache_peer
: forward some requests to another (caching) proxy
-
- Misc I/O, caching & debugging stuff:
-
logformat, access_log
: specify logging -
refresh_pattern, cache_dir
: configure caching -
debug_options
: additional debug logging
-
Modes of use
- Normal forward proxy: clients connect to the internet through this. Squid:
http_port
- Reverse / acceleator proxy: sits in front of servers to cache and route data. Squid:
http_port accel
- Transparent / intercepting proxy: requests are routed to this with a firewall / iptables without the client knowing. Squid:
http_port intercept, https_port ssl_bump intercept
Obtaining SSL key
Install openssl
. Then:
mkdir -p /etc/squid/cert/
cd /etc/squid/cert/
# This puts the private key and the self-signed certificate in the same file
openssl req -new -newkey rsa:4096 -sha256 -days 365 -nodes -x509 -keyout myCA.pem -out myCA.pem
# This can be added to browsers
openssl x509 -in myCA.pem -outform DER -out myCA.der
Then assign the above files and folders to the squid user.
Initialize SSL database
With the below config, Squid will generate a new 'fake' self-signed certificate for each bumped SSL connection (that the clients will hate). These will be cached in a folder.
On Fedora 29, it can be done with:
sudo -u squid /usr/lib64/squid/security_file_certgen -c -s /var/spool/squid/ssl_db -M 4MB
(This is the default directory. If you try to start Squid with SSL signing without initializing this folder, it will crash, and you can get some guidance with systemctl status squid
)
Fix clients
Clients hate self-signed certs for good reasons.
- Browsers: use the
myCA.der
file to import the certificate. - Linux: copy the cert files to
/etc/pki/ca-trust/source/anchors
and then runupdate-ca-trust
or whatever you have on your distribution, YMMV. - Node.js: Node will hate self-signed certs and you will have to modify the default HTTPS agent (locally or globally) or each request's options. You have 2 options:
- Read the PEM file and add the
Buffer
to theca
option. - Set
rejectUnauthorized
tofalse
- this is unsafe, allows man-in-the-middle attacks. - If using the
request
library, setstrictSSL
tofalse
.
- Read the PEM file and add the
- Headless Chrome (Puppeteer): start Chromium with
--ignore-certificate-errors
, start Puppeteer withignoreHTTPSErrors
set totrue
.
Divert traffic to the transparent proxy with iptables
From other computers, we use the PREROUTING
chain, specifying the source with -s
:
iptables -t nat -A PREROUTING -s 192.168.0.0/2 -p tcp --dport 80 -j REDIRECT --to-port 3129
iptables -t nat -A PREROUTING -s 192.168.0.0/2 -p tcp --dport 443 -j REDIRECT --to-port 3130
On localhost
this is a tougher issue since we want to avoid forwarding loops (packet is diverted to Squid but it should be sent to the Internet when Squid done its thing). Fortunately iptables
can differentiate between packet owner users. We need to use the OUTPUT chain for locally-generated packets. So we allow packets by root
and squid
through and divert everything else to Squid.
iptables -t nat -A OUTPUT -p tcp -m tcp --dport 80 -m owner --uid-owner root -j RETURN
iptables -t nat -A OUTPUT -p tcp -m tcp --dport 80 -m owner --uid-owner squid -j RETURN
iptables -t nat -A OUTPUT -p tcp -m tcp --dport 80 -j REDIRECT --to-ports 3129
iptables -t nat -A OUTPUT -p tcp -m tcp --dport 443 -m owner --uid-owner root -j RETURN
iptables -t nat -A OUTPUT -p tcp -m tcp --dport 443 -m owner --uid-owner squid -j RETURN
iptables -t nat -A OUTPUT -p tcp -m tcp --dport 443 -j REDIRECT --to-ports 3130
Debugging
In the config, set debug_options
. E.g. some general debug logs and detailed ACL info:
debug_options ALL,2 28,9
Links
Here are lots of good links:
Omitted. See the original article
Credits
- This blog is mostly taken from here, published in January 2019 under the CC-BY-SA license, with much condensing and slight editing on my own.
- The cover image is taken from squid-cache.org
Top comments (0)