Pound Proxy For Flexibility And Security

Pound Proxy For Flexibility And Security

Pound proxy is a great solution for adding a bit of a security layer, flexibility or scalability to your web server(s). If you're doing anything much more complex than hosting a blog, Pound may have some added value for you.

What Pound Is

Pound is a reverse proxy - that means you put it on the server end in front of your web services, not in front of your clients who need to connect to the general Internet. It takes web requests from end-users and distributes them among several web servers or services you may be running. Pound is also load balancing, so you can run multiple servers that look to the outside world as if they are just one, allowing you to spread the workload around.

What Pound Is Not

Pound proxy is NOT a caching proxy. By itself it won't help to speed up your server or network, but there is a lot of flexibility in Pound that will help you overall.

In Ubuntu, installing and using Pound is very easy. Simply install it and configure two files and you're off and running.

apt-get install pound
To enable Pound, you must edit the following file:
/etc/default/pound

Change it from startup=0 to startup=1. Before doing this, Pound will refuse to start.

The primary configuration file is located here:

/etc/pound/pound.cfg
There's a good deal of customization you can do with pound, but here's a few neat tricks you can do. Redirect all HTTP traffic to an SSL url It's easy to have pound do browser redirects for you. For instance, if your server farm is going to require SSL connections, you can automatically redirect any of the non-ssl connection attempts to the proper URL:
ListenHTTP
     Address 192.168.1.5
     Port    80
     Service
          Redirect "https://my.example.com/"
     End
End

The above configuration tells Pound to listen on port 80 and redirect all incoming traffic to "https://my.example.com/".

Handle SSL at the proxy

If your server farm will be using SSL but you will have multiple servers on the backend which might make handling SSL certificates a bit sketchy, you can have Pound do the SSL encryption/decryption as the traffic leaves your LAN, and use standard HTTP requests within your local network:

ListenHTTPS
     Address 192.168.1.5
     Port    443
     Cert    "/etc/apache2/ssl/mycertificate.pem"
     Service
           BackEnd
                  Address 192.168.1.80
                  Port 80
           End
           BackEnd
                  Address 192.168.1.81
                  Port 80
           End
     End
End

Notice you specify the SSL certificate to Pound, and it handles all the encryption work for you. I now have two separate load-balanced failover servers that will handle the requests as if they are one SSL enabled server. Each "BackEnd" section describes a single server that is used in the load balancing. If that server fails, Pound will automatically stop sending it requests until it comes back online.

Redirect image and css requests to a separate server

Another cool trick with Pound is to send all your static content to one server like LightTPD while pulling your PHP DB enabled content from Apache. That's easily done with URL matching:

Service
     URL "/(images|js|css)/"
     BackEnd
          Address 192.168.1.80
          Port    81  #This is where LightTPD is running
     End
End

The above "Service" example will send any traffic with a URL containing images, js or css to a specific IP and port for handling, but any other requests would be handled by another Service block. You can have multiple Service blocks in a Listen section, and multiple BackEnd's in a Service block.

Redirect requests to a different service on the same machine

Pound will also allow you to pull from a different port on the same machine by just using 127.0.0.1 as the Address and specfying a different port, so perhaps you have LightTPD running on your Pound machine and pass the PHP off to different servers, Pound can do that for you as well.

Filter traffic based on headers

Another neat trick is to filter your end-users based on headers provided by the client. For instance, say your website should never be contacted by anything except an actual browser and you're concerned with the possibility of people writing programs to pull data from the site, you can add a Service that filters them out:

Service
     HeadRequire "User-Agent:.*Microsoft URL Control.*"
     Redirect "http://www.microsoft.com"
End

Filter traffic based on destination DNS name

Or perhaps you're hosting more than one domain on the same IP and want traffic for one of those to go to another server:

Service
     HeadRequire "Host:.*myotherdomain.com.*"
     BackEnd
          Address 192.168.1.8
          Port 80
     End
End

One thing to note - the IP address of all web requests will now show as the Pound server to all of your various web services. Pound will add an HTTP_X_FORWARDED_FOR header to the request that includes the original IP address. In PHP you can access this using:

$clientip = array_pop(explode(',', $_SERVER['HTTP_X_FORWARDED_FOR']));
As you can see it's a very powerful utility to help you scale your services or simply provide better management features. Pound proxy is a staple for much of the development my team does these days.
Posted by Tony on Jan 27, 2009 | Servers