15.2 Configuring Squid

Technically, a single configuration file directive is all it takes to change Squid from a caching proxy into a surrogate. Unfortunately, life is never quite that simple. Due to the myriad of ways that different organizations design their web services, Squid has a number of directives to worry about.

15.2.1 http_port

Most likely, Squid is acting as a surrogate for your HTTP server on port 80. Use the http_port directive to make Squid listen on that port:

http_port 80

If you want Squid to act as surrogate and a caching proxy at the same time, list both port numbers:

http_port 80

http_port 3128

You can configure your clients to send their proxy requests to port 80 as well, but I strongly discourage that. By using separate ports, you'll find it easier to migrate the two services to separate boxes later if it becomes necessary.

15.2.2 https_port

You can configure Squid to terminate encrypted HTTP (SSL and TLS) connections. This feature requires the enable-ssl option when running ./configure. In this mode, Squid decrypts SSL/TLS connections from clients and forwards unencrypted requests to your backend server. The https_port directive has the following format:

https_port [host:]port cert=certificate.pem [key=key.pem] [version=1-4]

           [cipher=list] [options=list]

The cert and key arguments are pathnames to OpenSSL-compatible certificate and private key files. If you omit the key argument, the OpenSSL library looks for the private key in the certificate file.

The (optional) version argument specifies your requirements for various SSL and TLS protocols to support: 1=automatic, 2=SSLv2 only, 3=SSLv3 only, 4=TLSv1 only.

The (optional) cipher argument is a colon-separated list of ciphers. Squid simply passes it to the SSL_CTX_set_cipher_list( ) function. For more information, read the ciphers(1) manpage on your system or try running: openssl ciphers.

The (optional) options argument is a colon-separated list of OpenSSL options. Squid simply passes these to the SSL_CTX_set_options( ) function. For more information, read the SSL_CTX_set_options(3) manpage on your system.

Here are a few example https_port lines:

https_port 443 cert=/usr/local/etc/certs/squid.cert

https_port 443 cert=/usr/local/etc/certs/squid.cert version=2

https_port 443 cert=/usr/local/etc/certs/squid.cert cipher=SHA1

https_port 443 cert=/usr/local/etc/certs/squid.cert options=MICROSOFT_SESS_ID_BUG

15.2.3 httpd_accel_host

This is where you tell Squid the IP address, or hostname, of the backend server. If you use the loopback trick described previously, you write:


Squid then prepends this value to partial URIs that get accelerated. It also changes the value of the Host header.[1] For example, if the client makes this request:

[1] Technically, the Host header is changed only in requests Squid forwards to the backend server (cache misses).

GET /index.html HTTP/1.1

Host: squidbook.org

Squid turns it into this request:



As you can see, the request no longer contains any information that indicates the request is for squidbook.org. This shouldn't be a problem as long as the backend server isn't configured for virtual hosting of multiple domains.

If you want Squid to use the origin server's hostname, you can put it in the httpd_accel_host directive:

httpd_accel_host squidbook.org

Then the request is as follows:

GET http://squidbook.org/index.html HTTP/1.1

Host: squidbook.org

Another option is to enable the httpd_accel_uses_host_header directive. Squid then inserts the Host header value into the URI for most requests, and the httpd_accel_host value is used only for requests that lack a Host header.

When you use a hostname, Squid goes through the normal steps to look up its IP address. Because you want the hostname to resolve to two different addresses (one for clients connecting to Squid and another for Squid connecting to the backend server), you should also add a static DNS entry to your system's /etc/hosts file. For example:       squidbook.org

You might want to use a redirector instead. For example, you can write a simple Perl program that changes http://squidbook.org/... to See Chapter 11 for the nuts and bolts of redirecting client requests.

The httpd_accel_host directive has a special value. If you set it to virtual, Squid inserts the origin server's IP address into the URI when the Host header is missing. This feature is useful only when using HTTP interception, however.

15.2.4 httpd_accel_port

This directive tells Squid the port number of the backend server. It is 80 by default. You won't need to change this unless the backend server is running on a different port. Here is an example:

httpd_accel_port 8080

If you are accelerating origin servers on multiple ports, you can use the value 0. In this case, Squid takes the port number from the Host header.

15.2.5 httpd_accel_uses_host_header

This directive controls how Squid determines the hostname it inserts into accelerated URIs. If enabled, the request's Host header value takes precedence over httpd_accel_host.

The httpd_accel_uses_host_header directive goes hand in hand with virtual domain hosting on the backend server. You can leave it disabled if the backend server is handling only one domain. If, on the other hand, you are accelerating multiple origin server names, turn it on:

httpd_accel_uses_host_header on

If you enable httpd_accel_uses_host_header, be sure to install some access controls as described later in this chapter. To understand why, consider this configuration:

httpd_accel_host does.not.exist

httpd_accel_uses_host_header on

Because most requests have a Host header, Squid ignores the httpd_accel_host setting and rarely inserts the bogus does.not.exist name into URIs. This essentially turns your surrogate into a caching proxy for anyone smart enough to fake an HTTP request. If I know that you are using Squid as a surrogate without proper access controls, I can send a request like this:

GET /index.html HTTP/1.1

Host: www.mrcranky.com

If you've enabled httpd_accel_uses_host_header and don't have any destination-based access controls, Squid should forward my request to www.mrcranky.com. Read Section 15.4 and install access controls to ensure that Squid doesn't talk to foreign origin servers.

15.2.6 httpd_accel_single_host

Whereas the httpd_accel_uses_host_header directive determines the hostname Squid puts into a URI, this one determines where Squid forwards its cache misses. By default (i.e., with httpd_accel_single_host disabled), Squid forwards surrogate cache misses to the host in the URI. If the URI contains a hostname, Squid performs a DNS lookup to get the backend server's IP address.

When you enable httpd_accel_single_host, Squid always forwards surrogate cache misses to the host defined by httpd_accel_host. In other words, the contents of the URI and the Host header don't affect the forwarding decision. Perhaps the best reason to enable this directive is to avoid DNS lookups. Simply set httpd_accel_host to the backend server's IP address. Another reason to enable it is if you have another device (load balancer, virus scanner, etc.) between Squid and the backend server. You can make Squid forward the request to this other device without changing any aspect of the HTTP request.

Note that enabling both httpd_accel_single_host and httpd_accel_uses_host_header is a dangerous combination that might allow an attacker to poison your cache. Consider this configuration:

httpd_accel_single_host on


httpd_accel_uses_host_header on

and this HTTP request:

GET /index.html HTTP/1.0

Host: www.othersite.com

Squid forwards the request to your backend server at but stores the response under the URI http://www.othersite.com/index.html. Since isn't actually www.othersite.com, Squid now contains a bogus response for that URI. If you enable httpd_accel_with_proxy (next section) or your cache participates in a hierarchy or mesh, it may give out the bad response to unsuspecting users. To prevent such abuse, be sure to read Section 15.4.

Server-side persistent connections may not work if you use the httpd_accel_single_host directive. This is because Squid saves idle connections under the origin server hostname, but the connection-establishment code looks for an idle connection named by the httpd_accel_host value. If the two values are different, Squid fails to locate an appropriate idle connection. The idle connections are closed after the timeout, without being reused. You can avoid this little problem by disabling server-side persistent connections with the server_persistent_connections directive (see Appendix A).

15.2.7 httpd_accel_with_proxy

By default, whenever you enable the httpd_accel_host directive, Squid goes into strict surrogate mode. That is, it refuses proxy HTTP requests and accepts only surrogate requests, as though it were truly an origin server. Squid also disables the ICP port (although not HTCP, if you have it enabled). If you want Squid to accept both surrogate and proxy requests, enable this directive:

httpd_accel_with_proxy on

    Appendix A. Config File Reference