There are two elements to access control: classes and operators. Classes are defined with the acl squid.conf tag, while the names of the operators vary: the most common operator used is http_access.
Classes. A class normally refers to a set of users. (A class can also refer to a list of destination domains, filename extensions and more, but for now let's start with the basics!). If you have 50 people that are allowed Internet access, you could put all of their IP addresses in a list, and use that list as a "class of IP addresses that have Internet access".
Operators. It's often useful to use one set of ACLs for ICP and another for HTTP. This way you can apply different sets of rules for different protocols; this comes in very useful when you have a number of peering arrangements. Most ISP's do not want their caches to be SNMP-queried by all of their customers: they do, however, want all their customers to have access to browser access. In short, you want one set of acls to apply to HTTP traffic, another to apply to SNMP - and that's exactly what you get. For each protocol there is a different acl-operator, examples include the http_access, icp_access and snmp_access tags. It's very important to note that there is a not an ftp_access type. FTP requests are passed to the cache using the HTTP format (it's just a different format URL that gets sent to the cache server). The proto acl type (discussed shortly, with examples!) allows you to deny access to the cache if it's FTP, HTTP, SSL etc.
Let's work through the below example line-by-line. Here, a systema administrator is in the process of installing a cache, and doesn't want other staff to access it while it's being installed, since it's likely to ping-pong up and down during the installation. Once the administrator is happy with the config, the whole network will be allowed access. The admin's PC is at the IP 10.0.0.3.
Example 7-1. Explicit allow, explicit deny (do not use this!, see later text for reasons)
acl myIP src 10.0.0.3/255.255.255.255 acl myNet src 10.0.0.0/255.255.0.0 http_access allow myIP http_access deny myNet
If the admin connects to the cache from the PC, Squid does the following:
Accepts the (HTTP) connection and reads the request
Checks the line that reads http_access allow myIP.
Since your IP address matches the IP defined in the myIP acl, access is allowed. Remember that Squid drops out of the operator list on the first match.
If you connect from a different PC (on the 10.0.*.* network) things are very similar:
Accepts the connection and reads the request
The source of the connection doesn't match the myIP acl, so the next http_access line is checked.
The myNet acl matches the source of the connection, so access is denied. An error page is returned to the user instead of the requested page.
If someone reaches your cache from another netblock (from, say, 192.168.*.*), the above access list will not block access. The reason for this is quite complicated. If Squid works through a set of acl-operators and finds no match, it defaults to using the opposite of the last match (if the previous operator is an allow, the default is to deny; if it's a deny, the default is to allow). This seems a bit strange at first, but let's look at an example where this behaviour is used: it's more sensible than it seems.
The following acl example is nice and simple: it's something a first-time cache admin could create.
Example 7-2. Only an allow acl-operator
acl myNet src 10.0.0.0/255.255.0.0 http_access allow myNet
A config file with no access lists will allow cache access without any restrictions. An administrator using the above access lists obviously wishes to allow only his network access to the cache. Given the Squid behavior of inverting the last decision, we have an invisible line reading
Inverting the last decision is a simple (if not immediately obvious) solution to one of the most common acl mistakes: not adding a final deny all to the end of your acl list.
http_access deny all
With this new knowledge, have a look at the first example in this chapter: you will see why I said not to use it in your configs. Given that the last operator denies the local network, local people will not be able to access the cache. The remainder of the Internet, however, will! As discussed in chapter 1, the simplest way of creating a catch-all acl is to match requests when they come from any IP address. When programs do netmask arithmetic a subnet of all zeros will match any IP address. A corrected version of the first example dispenses with the myNet acl.
Example 7-3. Corrected example 6-1, explicit deny all
acl myIP src 10.0.0.3/255.255.255.255 acl all src 0.0.0.0/0.0.0.0 http_access allow myIP http_access deny all
Once the cache is considered stable and is moved into production, the config would change. http_access lines do add a very small amount of overhead, but that's not the only reason to have simple access rulesets: the less rulesets, the easier your setup is to understand. The below example includes a deny all rule although it doesn't really need one: you may know of the automatic inversion of the last rule, but someone else working on the cache may not.
Example 7-4. Example 6-1 once the cache is considered stable
acl myNet src 10.0.0.0/255.255.0.0 acl all src 0.0.0.0/0.0.0.0 http_access allow myNet http_access deny all
You should always end your access lists with an explicit deny. In Squid-2.1 the default config file does this for you when you insert your HTTP acl operators in the appropriate place.