Squid as a reverse proxy

Say you want to run multiple hosts off a single IP address. The answer is what is known as a reverse proxy. The reverse proxy will forward requests to other servers and ports. Several reverse proxy services exist.

I happeneded to be running Squid version 3.1 on Ubuntu as a reverse proxy. This is how I went about configuring that setup.

Installation

For starters you can install squid with sudo apt-get install squid3.

This will install the service squid3 that can be stopped and started with sudo service squid3 start and sudo service squid3 stop respectively.

It will also install the configuration in /etc/squid3/squid.conf. This configuration can be modified to turn Squid into a reverse proxy.

Configuration

Note, this configuration was for 3.1 of squid, some of the configuration options have since been deprecated or are no longer necessary to configure.

Step 1: Define the listening port as a reverse proxy

The first thing you need to do is set the listening port

http_port 80 accel defaultsite=www.example.com  

The http_port option takes the port number to listen to as the first parameter.

The accel parameter is used to indicate it is a reverse proxy. As of version 3.2 this always defaulted to true.

The defaultsite parameter supplies a site if the host value is not provided.

For more information on configuring the listening port, refer the squid documentation on http_port.

Step 2: Configure your network

The next step is configuring the servers inside your network. These are the machines and ports that you want to forward requests to.

cache_peer 192.168.0.157 parent 80 0 proxy-only name=ubuntu-lmr  
cache_peer 192.168.0.150 parent 80 0 proxy-only name=desktop1  
cache_peer 192.168.0.153 parent 2368 0 proxy-only name=ghost  
cache_peer 192.168.0.152 parent 8080 0 proxy-only name=linux-dev  

This option takes the form:
cache_peer hostname type proxy_port icp_port options

Specify the hostname or IP address of the server you wish to proxy connections to. Then specify the port, and the options.

The proxy-only indicates that caching will not be performed.

The name parameter is used to uniquely name the peer and will be used in subsequent steps.

More information about cache_peer is available on the Squid site.

Step 3: Map domains to specify peers

Now we can map domains to a specific peer by doing the folowing
1) Create an access control list (ACL) for a domain
2) granting http access to the ACL
3) mapping an ACL to a specific peer

# *.derpturkey.com -> matches all *.derpturkey.com
acl derpturkey_acl dstdomain .derpturkey.com  
http_access allow derpturkey_acl  
cache_peer_access ghost allow derpturkey_acl  

You see from the above example that we create an ACL called derpturkey_acl for the destination domain *.derpturkey.com. We then grant http access to the derpturkey_acl. Finally, we grant the access to the cache peer called ghost, defined in step 2, to our derpturkey_acl.

Now any request for *.derpturkey.com will get forwarded to the ghost peer, which happens to point to 192.168.0.153:2368.

Additional rules can be defined using a similar formula.

Step 4: Additional configuration

There are few more configurations you need to specify to get things securely running. In my environment, I disable all caching, since I'm only using Squid as a reverse proxy.

# Additional ACL definitions
acl all src all  
acl manager proto cache_object  
acl localhost src 127.0.0.1/32  
acl to_localhost dst 127.0.0.0/8 0.0.0.0/32  
acl purge method PURGE  
acl CONNECT method CONNECT

# Restrictions
http_access allow manager localhost  
http_access deny manager  
http_access allow purge localhost  
http_access deny purge  
http_access deny all

# Disable caching
cache deny all  

Full Config Example

Below is a full configuration file

# Define the listening port and default site
# Declare that virtual hosts will be used for allowing
#   the reverse proxy
http_port 80 accel vhost defaultsite=www.example.com

# First we will configure the servers in our system
cache_peer 192.168.0.157 parent 80 0 proxy-only name=ubuntu-lmr  
cache_peer 192.168.0.150 parent 80 0 proxy-only name=desktop1  
cache_peer 192.168.0.153 parent 2368 0 proxy-only name=ghost  
cache_peer 192.168.0.152 parent 8080 0 proxy-only name=linux-dev

# Create an additional ACL for local network access
acl localip src 192.168.0.0/24

# Next we will map domains to the specific systems
# 1) This is done by creating an ACL for the domain
# 2) Then granting http access to it to allow the connection
# to get through.
# 3) Then mapping an acl to the specific server

# .derpturkey.com -> matches all *.derpturkey.com
acl ghost_acl dstdomain .derpturkey.com  
http_access allow ghost_acl  
cache_peer_access ghost allow ghost_acl

# dev.listmill.com
acl listmill_acl dstdomain dev.listmill.com  
http_access allow listmill_acl localip  
cache_peer_access desktop1 allow listmill_acl

# linux development restricted to local network only
acl plerp_acl dstdomain plerp.listmill.com  
http_access allow plerp_acl localip  
cache_peer_access linux-dev allow plerp_acl



# Additional ACL definitions
acl all src all  
acl manager proto cache_object  
acl localhost src 127.0.0.1/32  
acl to_localhost dst 127.0.0.0/8 0.0.0.0/32  
acl purge method PURGE  
acl CONNECT method CONNECT

# Restrictions
http_access allow manager localhost  
http_access deny manager  
http_access allow purge localhost  
http_access deny purge  
http_access deny all

# Disable caching
cache deny all  
comments powered by Disqus