I was recently trying out Squid Proxy. I have heard of it before, can't remember where, but never got around to using it
This time my team wanted to use Squid Proxy as a way to expose and access some internal services. The Squid Proxy would be accessible only from within our company VPN - that is any device which has one of the IP addresses of our VPN can access it
Quick introduction to proxies - in this case, we are using Squid Proxy as a forward proxy, where we want the proxy to access resources on behalf of us. So, we are trying to access resources indirectly, through Squid Proxy, and not directly. Why? In this case it's because the resources are not directly accessible, as they are internal resources with internal IP addresses in an internal private network, and our users, developers, will be in public networks, the Internet.
There's also another kind of proxy called reverse proxy, where the client / user accesses the reverse proxy to get some resources, but the client doesn't know any details about the servers/services responding back to give the resources. The reverse proxy hides details about the services/servers (backends) behind it, from which it gets the resources. Usually reverse proxies also do load balancing, to balance the request load on the different instances of the service behind the reverse proxy. Usually there's more than one instance of the service, for scalability
Let's look at how I tried out Squid Proxy in my local machine :)
I'm on a MacBook Pro, with macOS Monterey version 12.7.1. I used Homebrew to install Squid Proxy in my local machine
brew install squid
I installed version 6.6
of Squid Proxy. You can see this with brew
and also with squid
CLI
$ brew info squid
==> squid: stable 6.6 (bottled), HEAD
Advanced proxy caching server for HTTP, HTTPS, FTP, and Gopher
http://www.squid-cache.org/
/usr/local/Cellar/squid/6.6 (179 files, 8.7MB) *
Poured from bottle using the formulae.brew.sh API on 2024-01-08 at 16:32:34
From: https://github.com/Homebrew/homebrew-core/blob/HEAD/Formula/s/squid.rb
License: GPL-2.0-or-later
==> Dependencies
Required: openssl@3 ✔
==> Options
--HEAD
Install HEAD version
==> Caveats
To start squid now and restart at login:
brew services start squid
Or, if you don't want/need a background service you can just run:
/usr/local/opt/squid/sbin/squid -N -d\ 1
==> Analytics
install: 1,314 (30 days), 3,145 (90 days), 8,114 (365 days)
install-on-request: 1,314 (30 days), 3,145 (90 days), 8,114 (365 days)
build-error: 0 (30 days)
$ squid --version
Squid Cache: Version 6.6
Service Name: squid
This binary uses OpenSSL 3.2.0 23 Nov 2023. configure options: '--disable-debug' '--disable-dependency-tracking' '--prefix=/usr/local/Cellar/squid/6.6' '--localstatedir=/usr/local/var' '--sysconfdir=/usr/local/etc' '--enable-ssl' '--enable-ssl-crtd' '--disable-eui' '--enable-pf-transparent' '--with-included-ltdl' '--with-gnutls=no' '--with-nettle=no' '--with-openssl' '--enable-delay-pools' '--enable-disk-io=yes' '--enable-removal-policies=yes' '--enable-storeio=yes' 'CC=clang' 'LDFLAGS=-lresolv' 'CXX=clang++' 'PKG_CONFIG_PATH=/usr/local/opt/openssl@3/lib/pkgconfig' 'PKG_CONFIG_LIBDIR=/usr/lib/pkgconfig:/usr/local/Homebrew/Library/Homebrew/os/mac/pkgconfig/12' --enable-ltdl-convenience
Now to try out Squid Proxy, I used Firefox Browser and also my terminal, the CLI, to see if it works there too
Let's start with how I did it in Firefox Browser. I'm using Firefox Browser in my Mac machine, and the version I'm using is Version 121.0 (64-bit)
Go to Settings
> Network Settings
> Settings
button > Configure Proxy Access to the Internet
> Manual proxy configuration
Here, I added proxy configuration for accessing http://
URLs under HTTP Proxy
and used the same proxy configuration for accessing https://
URLs too by checking the box that said Also use this proxy for HTTPS
. The configuration I added was -
Hostname: localhost
Port: 3128
It would look like this -
Once you are done configuring, ensure you press OK
to save the configuration
Now, I tried to access some websites, say, for example Google
It gives this error
It says -
The proxy server is refusing connections
An error occurred during a connection to www.google.com.
- Check the proxy settings to make sure that they are correct.
- Contact your network administrator to make sure the proxy server is working.
Now, this error means that for some reason the proxy server is refusing connections, that is, not accepting connections
Now, the reason for this error here is because I never started the Squid Proxy server in my local machine. But this is a good test to see if the browser is using the proxy we configured, or if it's just not using the proxy and instead directly accessing the website we type in the URL bar
Next thing to do is, run Squid Proxy, so that Firefox is able to access the proxy server and is able to access resources using the proxy server
Before running Squid Proxy, I would recommend checking out it's help section and just skimming through it, just to get an idea of the different flags it has
$ squid --help
Usage: squid [-cdzCFNRVYX] [-n name] [-s | -l facility] [-f config-file] [-[au] port] [-k signal]
-h | --help Print help message.
-v | --version Print version details.
-a port Specify HTTP port number (default: 3128).
-d level Write debugging to stderr also.
-f file Use given config-file instead of
/usr/local/etc/squid.conf
-k reconfigure|rotate|shutdown|restart|interrupt|kill|debug|check|parse
Parse configuration file, then send signal to
running copy (except -k parse) and exit.
-n name Specify service name to use for service operations
default is: squid.
-s | -l facility
Enable logging to syslog.
-u port Specify ICP port number (default: 3130), disable with 0.
-z Create missing swap directories and then exit.
-C Do not catch fatal signals.
-D OBSOLETE. Scheduled for removal.
-F Don't serve any requests until store is rebuilt.
-N Master process runs in foreground and is a worker. No kids.
--foreground
Master process runs in foreground and creates worker kids.
--kid role-ID
Play a given SMP kid process role, with a given ID. Do not use
this option. It is meant for the master process use only.
-R Do not set REUSEADDR on port.
-S Double-check swap during rebuild.
-X Force full debugging.
Add -d9 to also write full debugging to stderr.
-Y Only return UDP_HIT or UDP_MISS_NOFETCH during fast reload.
Squid Proxy requires configuration for it to work. My installation came with a default configuration file, which is at /usr/local/etc/squid.conf
according to the help section. I used the default configuration since I was just playing with it and trying it out for the first time. In my case, the default configuration, along with an extra line I added, looks like this -
#
# Recommended minimum configuration:
#
# Example rule allowing access from your local networks.
# Adapt to list your (internal) IP networks from where browsing
# should be allowed
acl localnet src 0.0.0.1-0.255.255.255 # RFC 1122 "this" network (LAN)
acl localnet src 10.0.0.0/8 # RFC 1918 local private network (LAN)
acl localnet src 100.64.0.0/10 # RFC 6598 shared address space (CGN)
acl localnet src 169.254.0.0/16 # RFC 3927 link-local (directly plugged) machines
acl localnet src 172.16.0.0/12 # RFC 1918 local private network (LAN)
acl localnet src 192.168.0.0/16 # RFC 1918 local private network (LAN)
acl localnet src fc00::/7 # RFC 4193 local private network range
acl localnet src fe80::/10 # RFC 4291 link-local (directly plugged) machines
acl SSL_ports port 443
acl Safe_ports port 80 # http
acl Safe_ports port 21 # ftp
acl Safe_ports port 443 # https
acl Safe_ports port 70 # gopher
acl Safe_ports port 210 # wais
acl Safe_ports port 1025-65535 # unregistered ports
acl Safe_ports port 280 # http-mgmt
acl Safe_ports port 488 # gss-http
acl Safe_ports port 591 # filemaker
acl Safe_ports port 777 # multiling http
#
# Recommended minimum Access Permission configuration:
#
# Deny requests to certain unsafe ports
http_access deny !Safe_ports
# Deny CONNECT to other than secure SSL ports
http_access deny CONNECT !SSL_ports
# Only allow cachemgr access from localhost
http_access allow localhost manager
http_access deny manager
# This default configuration only allows localhost requests because a more
# permissive Squid installation could introduce new attack vectors into the
# network by proxying external TCP connections to unprotected services.
http_access allow localhost
# The two deny rules below are unnecessary in this default configuration
# because they are followed by a "deny all" rule. However, they may become
# critically important when you start allowing external requests below them.
# Protect web applications running on the same server as Squid. They often
# assume that only local users can access them at "localhost" ports.
http_access deny to_localhost
# Protect cloud servers that provide local users with sensitive info about
# their server via certain well-known link-local (a.k.a. APIPA) addresses.
http_access deny to_linklocal
#
# INSERT YOUR OWN RULE(S) HERE TO ALLOW ACCESS FROM YOUR CLIENTS
#
# For example, to allow access from your local networks, you may uncomment the
# following rule (and/or add rules that match your definition of "local"):
# http_access allow localnet
# And finally deny all other access to this proxy
http_access deny all
# Squid normally listens to port 3128
http_port 3128
# Uncomment and adjust the following to add a disk cache directory.
#cache_dir ufs /usr/local/var/cache/squid 100 16 256
# Leave coredumps in the first cache dir
coredump_dir /usr/local/var/cache/squid
#
# Add any of your own refresh_pattern entries above these.
#
refresh_pattern ^ftp: 1440 20% 10080
refresh_pattern -i (/cgi-bin/|\?) 0 0% 0
refresh_pattern . 0 20% 4320
cache_mgr admin@gmail.com
I think the only thing I added here was cache_mgr admin@gmail.com
which is a configuration to tell the Squid Proxy the email ID of the proxy's administrator so that it can tell it's clients / users whom to contact in case there's an issue with the proxy - using it, accessing it etc
So, I ran the Squid Proxy in foreground in the terminal (CLI) like this -
$ squid --foreground
Killing Squid Proxy when it's a foreground process is easy, just press Ctrl
+ C
, the usual keyboard shortcut to kill a running command (process)
To use Squid Proxy in the background, just do this -
$ squid
To be able to see the Squid Proxy process, use ps aux
command with grep
$ ps aux | grep --color squid
karuppiah.n 81093 0.0 0.0 33589096 280 s000 R+ 1:44PM 0:00.00 grep --color squid
karuppiah.n 81089 0.0 0.1 34201172 13368 ?? S 1:44PM 0:00.05 (squid-1) --kid squid-1
karuppiah.n 81087 0.0 0.0 34182540 2084 ?? Ss 1:44PM 0:00.00 squid
Killing Squid Proxy when it's in the background, just kill the parent process, which you can find from the ps aux
command. In this case, the parent process is the command squid
, and it's child is (squid-1) --kid squid-1
. Even when Squid Proxy runs as a foreground process, it has a child process, which you can see like this -
$ ps aux | rg squid
karuppiah.n 81167 0.0 0.1 34238612 10348 s000 S+ 1:47PM 0:00.42 (squid-1) --kid squid-1 --foreground
karuppiah.n 81165 0.0 0.0 34174396 5800 s000 S+ 1:47PM 0:00.03 squid --foreground
karuppiah.n 82179 0.0 0.0 33595048 12 s001 S+ 3:44PM 0:00.00 rg squid
To find if the two squid
processes are related and are parent and child, use the following in Mac
$ ps axj | rg squid
karuppiah.n 81165 68772 81165 0 1 S+ s000 0:00.03 squid --foreground
karuppiah.n 81167 81165 81165 0 1 S+ s000 0:00.42 (squid-1) --kid squid-1 --foreground
karuppiah.n 82177 71007 82176 0 2 S+ s001 0:00.00 rg squid
The j
in ps axj
gives parent process ID information
-j Print information associated with the following keywords: user, pid, ppid, pgid, sess, jobc, state, tt, time, and command.
Finally, check if the proxy works in your Firefox browser
Now, the Google website would work. Let's try the same in the terminal. First kill the proxy, and try this -
$ export http_proxy=http://localhost:3128
$ export https_proxy=http://localhost:3128
This sets up the proxy configuration for accessing http://
links and https://
links
Now, try to access Google website using curl
. Ensure the Squid Proxy is not running, hence, curl
shouldn't work. This way, we know the proxy configuration is being used
$ curl google.com
curl: (7) Failed to connect to localhost port 3128 after 6 ms: Couldn't connect to server
Now, we see the error and it clearly says that it's not able to connect to the proxy server. This is because we killed the proxy server
Let's start the Squid Proxy server and try to do the curl
again :)
$ curl google.com
<HTML><HEAD><meta http-equiv="content-type" content="text/html;charset=utf-8">
<TITLE>301 Moved</TITLE></HEAD><BODY>
<H1>301 Moved</H1>
The document has moved
<A HREF="http://www.google.com/">here</A>.
</BODY></HTML>
Now it all works :)
So, that's how one can configure proxy in terminal, in Firefox and test it out using Squid Proxy, for trying out forward proxy servers
MacOS also has a System Wide Proxy configuration, which is used by Google Chrome browser. But I didn't notice this to work in Chrome. I mean, when this proxy was on, but proxy server was not running, the terminal and Google Chrome browser were able to access Google website for example. Not sure if it didn't even consider the proxy configuration, or if it considered but noticed it to be down, and hence tried to access the resource (Google website etc) directly. I gotta check how to do that check, maybe using ngrep or something
Above is the System Wide Proxy looks for when configuring Proxy for a given WiFi endpoint, through Advanced settings
That's all for now ! Looking forward to learn more, write more and share more :) Let me know what you felt about the post in the comments :)