Filtering Domains with Squid Proxy

Contents

Introduction

Squid is a web proxy with caching and forwarding capabilities, however, this post will not be concerned with caching web content. The focus will be on using Squid to control which domains are accessible to a user, either through blacklisting or whitelisting.

This can be useful for blocking undesired domains, such as those associated with malware or advertisements. On the other hand it can be use to limit what a set of computers in a network can connect to which can potently mitigate the impacts of an attack.

HTTP Proxies

Lets go over quickly how HTTP proxies work. There are three components here, the Proxy Client, the Proxy Server, and the destination server that the client wants to connect to.

The following lists the steps taken to request content through an HTTP proxy:

  1. The client will send a HTTP CONNECT request to the Proxy Server in order to notify it of the destination it wants to connect to. If it is a domain the Proxy Server will resolve this into an IP address, and will attempt to establish a initial TCP connection to the destination.

  2. If the Proxy Server successfully establishes a connection to the destination it will send back a HTTP CONNECTION ESTABLISHED message to the Proxy Client.

  3. Now that there is a connection established the Proxy Client will send a HTTP GET Request wrapped in a HTTP message that holds the target destination, target port, and the contents to the Proxy Server. This message will then be forwarded to the destination by the Proxy Server.

  4. Lastly, the Proxy Server will receive the response from the destination. It will then return the response to the Proxy Client.

Installing Squid

Most distributions have Squid in their repositories, for this I will be using CentOS 7. Squid can be installed using the following command:

1
[user@SquidServer ~]$ sudo yum install -y squid

Replace the package manager and package name for your distribution and it should also work.

Blacklisting Domains

In order to blacklist a collection of domains a list must be made which will contain them. In this example we will be blacklisting all the subdomains related to google.com. This can be done by writing it out as .google.com, where the . represents a wildcard. This means that google.com and maps.google.com will be blacklisted.

As can be seen below a list has been created with this declaration.

1
2
3
[user@SquidServer ~]$ cat /etc/squid/domain_list.txt
.google.com
[user@SquidServer ~]$

Now a configuration file must be created for Squid. The configuration file listed below has the following requirements met:

  • Only allow access to port 80 and 443.
  • Block domains listed in /etc/squid/domain_list.txt.
  • Block access to web content through IP addresses.

These requirements are fairly strict and can be removed if needed. The regular expression will match any numbers that appear to be an IP address and block access to it. However, it is done in a lazy way and will match invalid IP addresses as well.

In the settings caching has also been disabled with cache deny all, you can also disable access logs by uncommenting the access_log none field.

This configuration file must be placed in /etc/squid/squid.conf.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
### ACL ###

acl safe_ports port 80 443
acl url_list dstdomain "/etc/squid/domain_list.txt"
acl home src 10.0.0.0/24
acl ip_url url_regex -i ^(http://)?[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}(:443)?

### ACTIONS ###

http_access deny ip_url       # Prevent connections to IPs through proxy
http_access deny url_list     # Block all domains in URL list
http_access deny !safe_ports  # Block all connections that are NOT in safe_ports
http_access allow home        # Allow from home subnet
http_access deny all          # Block all else

### CONFIG OPTIONS ###

http_port 3128                # Squid normally listens to port 3128
coredump_dir /var/spool/squid # Leave coredumps in the first cache dir
dns_v4_first on               # IPV4, not IPV6
cache deny all                # Prevent Squid from caching any response
#access_log none              # Disable access logging

After the confiration file has been setup start the Squid proxy.

1
 [user@SquidServer ~]$ sudo systemctl start squid

Now that the Squid proxy is up and running configure a system to use the proxy and browse to a domain you know is blacklisted. You will be greeted with a web page similar to the following.

Whitelisting Domains

In order to whitelist domains two changes need to be made. First, http_access deny !home was changed in order to deny traffic that is not from the home subnet. The ! will negate the expression. Secondly, the http_access deny url_list was set to allow in order to allow the domains that have been specified in the list.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
### ACL ###

acl safe_ports port 80 443
acl url_list dstdomain "/etc/squid/domain_list.txt"
acl home src 10.0.0.0/24
acl ip_url url_regex -i ^(http://)?[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}(:443)?

### ACTIONS ###

http_access deny ip_url       # Prevent connections to IPs through proxy
http_access deny !safe_ports  # Block all connections that are NOT in safe_ports
http_access deny !home        # Block subnets NOT from home network
http_access allow url_list    # Allow all domains in URL list
http_access deny all          # Block all else

### CONFIG OPTIONS ###

http_port 3128                # Squid normally listens to port 3128
coredump_dir /var/spool/squid # Leave coredumps in the first cache dir
dns_v4_first on               # IPV4, not IPV6
cache deny all                # Prevent Squid from caching any response
#access_log none              # Disable access logging

After making the appropriate changes restart Squid.

1
 [user@SquidServer ~]$ sudo systemctl restart squid

Now the only domains that should be accessible are those that are in the domain_list.txt file.