3. Further Squid configuration

In many cases, the basic configuration we've seen in the previous chapter can be sufficient for accelerating web access and protecting the network, but Squid can do much more. Below are just a few of the many things Squid can do.

3.1 More on Access Control Lists

Though most people implement only very basic access control, Squid's access system is very powerful and flexible, allowing for in-depth filtering of access to cache resources. So far we have mainly dealt with ACLs that filter based on source IP address or destination port, but there are many other ACL types. In this paragraph, we will take a brief look at the main ones, just to get an idea of what Squid ACLs can do; for a more detailed and comprehensive description of Squid ACLs, please refer to the documentation.

A Squid ACL is made up of at least four fields: the acl keyword, followed by a (possibly descriptive) unique name, the ACL type and one or more decision strings. Thus, the overall syntax of Squid ACLs looks like:

acl name type (string|"filename") [string2] [string3] ["filename2"]

An ACL containing multiple decision strings will return true if any of the decision strings matches (i.e. decision strings are ORed together). To avoid cluttering the configuration file with hundreds of ACL lines, you can specify the full pathname of a file (in double quotes) containing the decision strings one per line.

Listed below are the most commonly used ACL types:

Source/Destination IP address
Filtering based on source IP address (src type) or destination IP address (dst type). Both the traditional "IP/Netmask" and CIDR "IP/Bits" notations are allowed. E.g.:
# "Traditional" notation
acl  myNet1  src 192.168.0.0/255.255.255.0

# Address range with CIDR notation
acl  myNet2  src 172.16.0.0-172.16.2.0/24

# Filtering on destination address
acl  badNet  dst 10.0.0.0/24
Source/Destination Domain
Squid can allow/deny requests to or from specific domains (dstdomain and srcdomain types, respectively). If you want to deny access to a site, don't forget to also deny access to its IP address, or the rule will be easily bypassed. E.g.:
# Match a specific site
acl  badDomain   dstdomain  forbidden.site

# Match the IP address of "forbidden.site"
acl  badDomainIP dst        1.2.3.4
Regular expressions can also be used for checking the source domain (srcdom_regex type) and destination domain (dstdom_regex type) of a request. E.g.:
# Match domains containing the word "sex" and a ".com" TLD (the match is case
# insensitive because of the '-i' flag)
acl  badSites  dstdom_regex -i sex.*\.com$
Words in the requested URL
Squid can use regular expressions to filter URLs matching specific patterns (url_regex type); if you don't care about the URL-type and the hostname, you can use the urlpath_regex type instead.
# Match the most common video files extensions
acl  movies  urlpath_regex -i  \.avi$ \.mpg$ \.mpeg$ \.wmv$ \.asf$ \.mov$

# Match JPG images from URLs containing the word "sex"
acl  sexImg  url_regex -i  sex.*\.jpg$
Current day/time
Squid can allow/deny access to specific sites by time. The syntax is:
acl name time [day-list] [start_hour:minute-end_hour:minute]
where day-list is a list of single characters representing the days that the acl applies to (Sunday, Monday, Tuesday, Wednesday, THhursday, Friday, SAturday). E.g.:
acl workhours time  MTWHF 08:00-18:00
acl weekend   time  SA
acl morning   time  07:00-13:00
Destination port
Squid can filter based on destination ports. E.g:
acl SSL_ports  port  443 563
acl Safe_ports port  80 21 443 563 70 210 280 488 591 777 1024-65535
Protocol (FTP, HTTP, SSL)
The proto acl type allows Squid to allow/deny access based on the request protocol. E.g.:
acl www proto HTTP SSL
acl ftp proto FTP
Method (HTTP GET, POST or CONNECT)
The method ACL type allows you to restrict access based on the request HTTP method, i.e. GET (used for downloading), POST (used for uploading) and CONNECT (used for SSL data transfers). E.g.:
# Deny CONNECT to other than SSL ports
acl connect method CONNECT
http_access deny connect !SSL_ports
It is very important that you stop CONNECT type requests to non-SSL ports. The CONNECT method allows data transfer in any direction at any time, regardless of the transport protocol used. As a consequence, a malicious user could telnet(1) to a (very) badly configured proxy, enter something like:
$ telnet bad.proxy.tld 3128
Trying 1.2.3.4...
Connected to bad.proxy.tld.
Escape character is '^]'.
CONNECT telnet.server.tld:23 HTTP/1.1

and end up connected to the remote server, as if the connection was originated from the proxy.
Browser type
The browser acl type allows you to specify a regular expression that can be used to allow/deny access based on the User-Agent header. E.g.:
# Deny access to MS Internet Explorer
acl MSIE browser MSIE
http_access deny MSIE
Username/Password pair
User authentication allows you to track Internet usage and collect per-user statistics. The simplest authentication scheme is the basic scheme, with username/password pairs stored in a file. To create this file, you can use the htpasswd(1) command:
# /usr/bin/htpasswd -c /etc/squid/squid.passwd danix
New password: dAn1x
Re-type new password: dAn1x
Adding password for user danix
#
Authentication parameters are set using the auth_param tag; then, to actually activate authentication, you need to make use of ACLs based on login name in http_access (proxy_auth or proxy_auth_regex) or external_acl_type with %LOGIN used in the format tag. E.g.:
# Configure traditional (basic) proxy authentication
auth_param basic program /usr/local/libexec/ncsa_auth /etc/squid/squid.passwd

# Number of authenticator processes to spawn
auth_param basic children 5

# Realm to be reported to the client
auth_param basic realm Squid proxy-caching web server

# Usernames are case insensitive
auth_param basic casesensitive off

# Credentials time to live
auth_param basic credentialsttl 12 hours

# Using REQUIRED will accept any valid username
acl AUTH proxy_auth REQUIRED

# Don't require authentication to localhost
http_access allow localhost

# Only allow authenticated requests coming from the LAN
http_access allow AUTH lan

# Default deny
http_access deny all
SNMP Community
Squid can restrict SNMP queries based on the requested SNMP community. E.g.:
# Address of the cache administrator
acl snmpManager  src  172.16.0.100

# Non-sensitive information
acl SNMPPublic  snmp_community public

# Allow any request from the cache administrator
snmp_access  allow  snmpManager

# Clients on the LAN can only query non-sensitive information
snmp_access  allow  SNMPPublic lan

# Default deny
snmp_access  deny  all

3.2 Http-accelerator mode (reverse proxy)

According to the documentation, enabling Squid's Accelerator Mode can be useful only in a limited set of circumstances:

Besides these cases, enabling the accelerator mode is strongly discouraged. The configuration is very simple; below is a sample configuration of a Squid server accelerating requests to a slow web server.

/etc/squid/squid.conf
# In accelerator mode, Squid usually listens on the standard www port
http_port 80 accel vhost 

# Do the SSL work at the accelerator level. To create the certificates, run:
#   openssl req -x509 -newkey rsa:2048 -keyout squid.key -out squid.crt \
#   -days 365 -nodes
https_port  443 cert=/etc/ssl/squid.crt key=/etc/ssl/private/squid.key

# Accelerated server address and port
cache_peer 172.16.1.217 parent 80 0 no-query originserver

# Do not rewrite 'Host:' headers
url_rewrite_host_header off
# Process multiple requests for the same URI as one request
collapsed_forwarding    on

# Allow requests when they are to the accelerated machine AND to the
# right port
acl webSrv    dst   172.16.1.217
acl webPrt    port  80
acl all       src   all
http_access   allow webSrv webPrt
http_access   allow all
always_direct allow webSrv

3.3 Transparent caching

Transparent caching means having a filtering device, such as a router or a firewall, silently redirecting web traffic to the cache server. Clients ignore the presence of the proxy between them and the web server and think they're talking directly to the server.

As a consequence, transparent caching doesn't require any configuration on the client side, thus making maintenance much easier and faster. On the other hand, however, a transparently intercepting proxy can't use authentication or transparently proxy the HTTPS protocol.

Before configuring Squid, we will need to enable web traffic redirection on our firewalls (the involved firewalls are those between the LAN, where clients reside, and the DMZ, where the cache server is placed). Below are some sample rules for the pf.conf(5) file:

/etc/pf.conf
[...]
# LAN interface
lan_if     = rl1

# Cache server and port
cache_srv  = proxy.kernel-panic.it
cache_port = 3128

# Transparently redirect web traffic to the cache server
pass in on $lan_if proto tcp from $lan_if:network to any port www \
     rdr-to $cache_srv port $cache_port
[...]

Squid configuration is quite simple:

/etc/squid/squid.conf
# Port on which connections are redirected
http_port  3128 transparent

3.4 SNMP

SNMP is a set of protocols for network management and monitoring. If you installed the "snmp" flavor of the Squid package, the proxy will be able to serve statistics and status information via SNMP.

SNMP configuration is rather simple:

/etc/squid/squid.conf
# By default, Squid listens for SNMP packets on port 3401, to avoid conflicting
# with any other SNMP agent listening on the standard port 161.
snmp_port  3401

# Address to listen on (0.0.0.0 means all interfaces)
snmp_incoming_address 0.0.0.0

# Address to reply on (255.255.255.255 means the same as snmp_incoming_address)
# Only change this if you want to have SNMP replies sent using another address
# than where Squid listens for SNMP queries.
# snmp_incoming_address and snmp_outgoing_address can't have the same value
# since they both use port 3401.
snmp_outgoing_address 255.255.255.255

# Configuring access control is strongly recommended since some SNMP
# information is confidential
acl  all              src             all
acl  lan              src             172.16.0.0/24
acl  snmpManager      src             172.16.0.100
acl  publicCommunity  snmp_community  public
snmp_access           allow           snmpManager
snmp_access           allow           publicCommunity lan
snmp_access           deny            all

You can test whether SNMP is working with the snmpwalk program (snmpwalk is part of the NET-SNMP project). E.g.:

# snmpwalk -c public -v 1 proxy.kernel-panic.it:3401 .1.3.6.1.4.1.3495.1.1
SNMPv2-SMI::enterprises.3495.1.1.1.0 = INTEGER: 356
SNMPv2-SMI::enterprises.3495.1.1.2.0 = INTEGER: 744
SNMPv2-SMI::enterprises.3495.1.1.3.0 = Timeticks: (540791) 1:30:07.91
#

Please refer to the documentation for a detailed explanation of the output from the snmpwalk command.