15.4 Access Controls

A typically configured surrogate accepts HTTP requests from the whole Internet. This doesn't mean, however, that you can forget about access controls. In particular, you'll want to make sure Squid doesn't accept requests belonging to foreign origin servers. The exception is when you have httpd_accel_with_proxy enabled.

For a surrogate-only configuration, use one of the destination-based access controls. For example, the dst type accomplishes the task:

acl All src 0/0

acl TheOriginServer dst 192.168.3.2

http_access allow TheOriginServer

http_access deny All

Alternatively, you can use a dstdomain ACL if you prefer:

acl All src 0/0

acl TheOriginServer dstdomain www.squidbook.org

http_access allow TheOriginServer

http_access deny All

Note that enabling httpd_accel_single_host somewhat bypasses the access control rules. This is because the origin server location (i.e., the httpd_accel_host value) is then set after Squid performs the access control checks.

Access controls become really tricky when you combine surrogate and proxy modes in a single instance of Squid. You can no longer simply deny all requests to foreign origin servers. You can, however, make sure that outsiders aren't allowed to make proxy requests to random origin servers. For example:

acl All src 0/0

acl ProxyUsers src 10.2.0.0/16

acl TheOriginServer dst 192.168.3.2

http_access allow ProxyUsers

http_access allow TheOriginServer

http_access deny All

You can also use the local port number in your access control rules. It doesn't really protect you from malicious activity, but does ensure, for example, that user-agents send their proxy requests to the appropriate port. This also makes it easier for you to split the service into separate proxy- and surrogate-only systems later. Assuming you configure Squid to listen on ports 80 and 3128, you might use:

acl All src 0/0

acl ProxyPort myport 3128

acl ProxyUsers src 10.2.0.0/16

acl SurrogatePort myport 80

acl TheOriginServer dst 192.168.3.2

http_access allow ProxyUsers ProxyPort

http_access allow TheOriginServer SurrogatePort

http_access deny All

Unfortunately, these access control rules don't prevent attempts to poison your cache when you enable httpd_accel_single_host, httpd_accel_uses_host_header, and httpd_accel_with_proxy simultaneously. This is because the valid proxy request:

GET http://www.bad.site/ HTTP/1.1

Host: www.bad.site

and the bogus surrogate request:

GET / HTTP/1.1

Host: www.bad.site

have the same access control result but are forwarded to different servers. They have the same access control result because, after Squid rewrites the surrogate request, it has the same URI as the proxy request. However, they don't get sent to the same place. The surrogate request goes to the server defined by httpd_accel_host because httpd_accel_single_host is enabled.

You can take steps towards solving this problem. Make sure your backend server generates an error for unknown server names (e.g., when the Host header refers to a nonlocal server). Better yet, don't run Squid as a surrogate and proxy at the same time.



    Appendix A. Config File Reference