The Pound program is a reverse proxy, load balancer and HTTPS front-end for Web server(s). Pound was developed to enable distributing the load among several Web-servers and to allow for a convenient SSL wrapper for those Web servers that do not offer it natively. Pound is distributed under the GPL – no warranty, it’s free to use, copy and give away.
WHAT POUND IS:
- a reverse-proxy: it passes requests from client browsers to one or more back-end servers.
- a load balancer: it will distribute the requests from the client browsers among several back-end servers, while keeping session information.
- an SSL wrapper: Pound will decrypt HTTPS requests from client browsers and pass them as plain HTTP to the back-end servers.
- an HTTP/HTTPS sanitizer: Pound will verify requests for correctness and accept only well-formed ones.
- a fail over-server: should a back-end server fail, Pound will take note of the fact and stop passing requests to it until it recovers.
- a request redirector: requests may be distributed among servers according to the requested URL.
Pound is a very small program, easily audited for security problems. It can run as setuid/setgid and/or in a chroot jail. Pound does not access the hard-disk at all (except for reading the certificate file on start, if required) and should thus pose no security threat to any machine.
WHAT POUND IS NOT:
- Pound is not a Web server: by itself, Pound serves no content – it contacts the back-end server(s) for that purpose.
- Pound is not a Web accelerator: no caching is done – every request is passed “as is” to a back-end server.
As of release 1.0 Pound is declared to be production-quality code.
Quite a few people have reported using Pound successfully in production environments. The largest volume reported to date is a site with an average of about 30M requests per day, peaking at over 600 requests/sec.
Pound was successfully used in production with a variety of Web servers, including Apache, IIS, Zope, WebLogic, Jakarta/Tomcat, iPlanet, etc. In general Pound passes requests and responses back and forth unchanged, so we have no reason to think that any web server would be incompatible.
Client browsers that were tested:
- IE 5.0/5.5 (Windows) HTTP/HTTPS
- Netscape 4.7 (Windows/Linux) HTTP/HTTPS
- Mozilla (Windows/Linux) HTTP/HTTPS
- Konqueror (Linux) HTTP/HTTPS
- Galleon (Linux) HTTP/HTTPS
- Opera (Linux/Windows) HTTP/HTTPS
- Lynx (Linux) HTTP
Given that Pound is in production and no problems were reported, we have no reason to believe that other browsers would present a problem. A few issues were observed with problematic SSL implementations, most notably with Opera 6, but these should be OK in the present version.
Probably the easiest way to install Pound is to use a pre-compiled package if you can find one. While Apsis offers no such packages, they are available for quite a few systems (SuSE Linux,Debian and derivatives such as Ubuntu, as well as some private packages:
- RPMs for RedHat are available at http://www.invoca.ch/pub/packages/pound/
- A nice FreeBSD live-CD distribution is available at http://www.targeted.org/files/fbsd71_pound244.iso.gz, including a Pound binary.
- Packages for CRUX Linux are available from http://ports.sterneck.asia/shin/#pound.
Please note that these sites are not affiliated with Apsis, and they are not responsible for the contents.
Failing that you should install from sources:
- Pound was tested on Linux, Solaris and OpenBSD, but it should work unchanged on just about any modern Unix-like system. You will require OpenSSL and the native threads library. The PCRE package and the tcmalloc (or Hoard) libraries are strongly recommended.
Warning: as Pound is a multi-threaded program it requires a version of OpenSSL with thread support. This is normally the case on Linux and Solaris (for example) but not on *BSD. If your system has the wrong library please download, compile and install OpenSSL (from http://www.openssl.org) with threads support.
If the PCRE, tcmalloc (from the Google perftools package) and/or Hoard are available Pound will link against them. This will provide a significant performance boost and is highlyrecommended.
- Download the latest version Pound-2.5.tgz file and unpack it. The archive is signed.
Alternately see below for experimental versions.
- Unpack. Do the usual thing:
- The following options are available for the configure script:
--with-ssl=ssl_dir -- OpenSSL home directory --disable-super -- disable supervisor process (default: enabled) --with-t_rsa=nnn -- timeout of the RSA ephemeral keys regeneration (default: 30 minutes). --with-owner=owner -- name of installed binaries owner (default is system-dependent). --with-group=group -- name of installed binaries group (default is system-dependent).
- Check that the resulting Makefile is correct and possibly adjust flags as needed on your system. Compile:
- If it works, you may want to do some testing before installing.
- Install the executable somewhere (it’s likely that /usr/local/sbin would make a good choice), as well as the manual page (pound.8 -> /usr/local/man/man8). The supplied Makefile will do it for you.
- Make sure Pound gets started on boot. Read the man page for available options and examples.
VIRTUAL HOSTS (IN GENERAL)
Some people asked about the possibility of redirecting requests to back-ends as per some virtual hosts definition. While I believe this is not Pound‘s job, it can be done. As of version 0.10,Pound supports filtering requests based not only on the request URL, but also on the presence or absence of certain headers.
Let’s assume that you have internal server 192.168.0.10 that is supposed to serve the needs of virtual host www.server0.com and 192.168.0.11 that serves www.server1.com. You want Poundto listen on address 188.8.131.52 and separate the requests to each host. The config file would look something like this:
ListenHTTP Address 184.108.40.206 Port 80 Service HeadRequire "Host: .*www.server0.com.*" BackEnd Address 192.168.0.10 Port 80 End End Service HeadRequire "Host: .*www.server1.com.*" BackEnd Address 192.168.0.11 Port 80 End End End
(add whatever else is necessary) or, if you want even safer filtering:
ListenHTTP Address 220.127.116.11 Port 80 Service HeadRequire "Host: .*www.server0.com.*" HeadDeny "Host: .*www.server1.com.*" BackEnd Address 192.168.0.10 Port 80 End End Service HeadRequire "Host: .*www.server1.com.*" HeadDeny "Host: .*www.server0.com.*" BackEnd Address 192.168.0.11 Port 80 End End End
This is NOT recommended (I personally believe that virtual hosts should be implemented in the back-end servers – putting this in a proxy is a major security kludge) but it works.
VIRTUAL HOSTS AND HTTPS
Quite often we get inquiries about Pound‘s ability to do virtual hosting with HTTPS. In order to lay this matter to rest, let me say:
HTTPS does not allow virtual hosting
This is not a limitation of Pound, but of HTTPS – no Web server or proxy are able to do it due to the nature of the beast.
In order to see why this is the case we need to look at the way HTTPS works. Basically there are three stages in any HTTPS connection:
- Connection negotiation – the client (your browser) and the server (Web server or proxy) negotiate the basic parameters: ciphers to use, session key, etc.
- Connection authentication: at the very least the server presents the client with a certificate that says “I am server www.encrypted.com – and certificate.authority.org will verify that”. The client may also present a certificate of its own at this stage.
- Request/response cycle: normal HTTP is sent (through the encrypted channel) back and forth.
The vital point to notice here is that connection authentication takes place BEFORE any request was issued.
On the other hand, the way virtual hosting works is for the client to specify in the request to which server it would like to talk. This is accomplished via a Host header:
GET /index.html HTTP/1.1 Host: http://www.virthost.com
Combining the two we get to an impasse: on connection setup the server will reply with the certificate for “www.realhost.com”, but the request is really for “www.virthost.com” – and most browsers will scream blue murder (as well they should) if the two do not match.
There is a new twist on this however: some of the newer browsers will accept so-called “wild-card certificates”. This is a specially crafted certificate that is not issued to a host, but rather to a domain. The result is that on setting-up a new SSL connection, the server replies not with “I am www.encrypted.com“, but with “I am *.encrypted.com“. If the browser is capable of processing this type of certificate then the connection is set up and normal HTTPS (with www.encrypted.com or special.encrypted.com or even some.other.server.encrypted.com or whatever other name matches) proceeds as usual. Pound supports these certificates and you can use virtual hosts in the normal way.
Update June 2010: starting with with the 2.6 series, Pound has SNI support, if your OpenSSL version supports it. Basically you supply Pound with several certificates, one for each virtual host (wild card certificates – as described above – are allowed). On connecting the client signals to which server it wants to talk, and Pound searches among its certificates which would fit. Not all versions of OpenSSL and not all clients support this mode, but if available it allows for virtual hosts over HTTPS.
An additional option is to use a semi-official TLS extension, the so called alternate subject name. If your version of OpenSSL supports it you may specify in one certificate several alternate server names. This requires support for a special TLS feature, and nor all clients accept it.
VIRTUAL HOSTS IN ZOPE
For reasons I can’t quite grasp, it seems that a lot of Zope users are convinced that virtual hosts are only possible through the Apache/VHM combination and that it requires some kind of magic incantation at midnight in order to work (I won’t even start on the virgin sacrifices).
The simple fact is that VHM and the Apache VirtualHost directives (as well as various tricks through mod_rewrite and mod_proxy) are (almost) mutually exclusive: they perform exactly the same functions and, leaving aside the logging issues, are used independently of each other. Let me repeat that: you may use the VHM without Apache – just click on the VHM mappings tab and add whatever virtual host you wish. From this moment on any request to that host will be mapped back and forth by Zope to the required URL. This works if you access Zope directly or via any number of proxies on the way, Pound included.
To test: add a new host name to your /etc/hosts file, making it an alias for localhost – something like:
127.0.0.1 localhost www.testhost.mine
Add a mapping in VHM from www.testhost.mine to some Zope folder (Examples is already there). Point your browser to http://localhost and you get the normal Zope start page; point it to http://www.testhost.mine and you’ll see the Examples starting page. All requests are mapped correctly, and the URLs in the pages (such as base or absoluteURL) are translated correctly in the response.
Pound has the ability to keep track of sessions between a client browser and a back-end server. Unfortunately, HTTP is defined as a stateless protocol, which complicates matters: many schemes have been invented to allow keeping track of sessions, none of which works perfectly. Even worse, sessions are critical in order to allow web-based applications to function correctly – it is vital that once a session is established all subsequent requests from the same browser be directed to the same back-end server.
Six possible ways of detecting a session have been implemented in Pound (hopefully the most useful ones): by client address, by Basic authentication, by URL parameter, by cookie, by HTTP parameter and by header value.
- by client address: in this scheme Pound directs all requests from the same client IP address to the same back-end server. Put the line:
Session Type IP TTL 300 End
in the configuration file to achieve this effect. The value indicates what period of inactivity is allowed before the session is discarded.
- by Basic Authentication: in this scheme Pound directs all requests from the same user (as identified in the Basic Authentication header ) to the same back-end server. Put the lines:
Session Type Basic TTL 300 End
in the configuration file to achieve this effect. The value indicates what period of inactivity is allowed before the session is discarded. WARNING: given the constraints of the HTTP protocol it may very well be that the authenticated request will go to a different back-end server than the one originally requesting it. Make sure all your servers support the same authentication scheme!
- by URL parameter: quite often session information is passed through URL parameters (the browser is pointed to something like http://xxx?id=123). Put the lines:
Session Type URL ID "id" TTL 300 End
to support this scheme and the sessions will be tracked based on the value of the “id” parameter.
- by cookie value: applications that use this method pass a certain cookie back and forth. Add the lines:
Session Type Cookie ID "sess" TTL 300 End
to your configuration file – the sessions will be tracked by the value of the “sess” cookie.
- by HTTP parameter value: applications that use this method pass a parameter (http://x.y/z;parameter) back and forth. Add the lines:
Session Type PARM TTL 300 End
to your configuration file – the sessions will be tracked by the value of the “sess” cookie.
- by header value: applications that use this method pass a certain header back and forth. Add the lines:
Session Type Header ID "X-sess" TTL 300 End
to your configuration file – the sessions will be tracked by the value of the “X-sess” header.
Please note the following restrictions on session tracking:
- session tracking is always associated with a certain Service. Thus each group may have other methods and parameters.
- there is no default session: if you have not defined any sessions no session tracking will be done.
- only one session definition is allowed per Service (this may change in a future version). If your application has alternative methods for sessions you will have to define a separate Service for each method.
A note on cookie injection: some applications have no session-tracking mechanism at all but would still like to have the client always directed to the same back-end time after time. Some reverse proxies use a mechanism called “cookie injection” in order to achieve this: a cookie is added to the back-end responses and tracked by the reverse proxy.
Pound was designed to be as transparent as possible, and this mechanism is not supported. If you really need this sort of persistent mapping use the client address session mechanism (Session Type IP), which achieves the same result without changing the contents in any way.
REPOSTED FROM http://www.apsis.ch/pound/ ALL CREDITS TO Apsis