man pound (Administration système) - HTTP/HTTPS reverse-proxy and load-balancer
NAME
pound - HTTP/HTTPS reverse-proxy and load-balancer
SYNOPSIS
- pound
- [-v] [-c] [-f config_file] [-p pid_file]
DESCRIPTION
Pound is a reverse-proxy load balancing server. It accepts requests from HTTP/HTTPS clients and distributes them to one or more Web servers. The HTTPS requests are decrypted and passed to the back-ends as plain HTTP.
If more than one back-end server is defined, Pound chooses one of them randomly, based on defined priorities. By default, Pound keeps track of associations between clients and back-end servers (sessions).
OPTIONS
Options available (see also below for configuration file options):
- -v
- Verbose mode: error messages will be sent to stdout even if Pound was configured to log to syslog. This applies only to startup messages, before Pound puts itself in the background. Normal operational messages will still go to syslog.
- -c
- Check only: Pound will exit immediately after parsing the configuration file. This may be used for running a quick syntax check before actually activating a server.
- -f config_file
- Location of the configuration file (see below for a full description of the format). Default: /etc/pound/pound.cfg
- -p pid_file
- Location of the pid file. Pound will write its own pid into this file. Normally this is used for shell scripts that control starting and stopping of the daemon. Default: /var/run/pound.pid
In general, any number of back-end servers may be specified. Use the priority to affect the load distribution among unequal-performance servers.
One (or more) copies of Pound should be started at boot time. Use "big iron" if you expect heavy loads: while Pound is as light-weight as I know how to make it, with a lot of simultaneous requests it will use quite a bit of CPU and memory. Multiple CPUs are your friend.
CONFIGURATION FILE
Each line in the file is considered a complete configuration directive. The directives are case-insensitive. Empty lines or lines starting in '#' are ignored. There are two types of directives: global directives (they affect the settings for the entire program instance), and group directives (they affect only a specific group of requests).
GLOBAL DIRECTIVES
Global directives may appear anywhere within the configuration file, though it is customary for them to be at the start. They may appear in any order.
- ListenHTTP host,port
- Specify the address and port number where Pound will listen for HTTP requests. Multiple directives imply listening on multiple ports. A host name of "*" implies listening on all available interfaces (but be careful: no checks are made for conflicting definitions).
- ListenHTTPS host,port cert_file [ciphers]
- Specify the address and port number where Pound will listen for HTTPS requests. cert_file is the file containing the certificate, possibly a certificate chain and the signature for this port; the same file may be specified for multiple ports (as above - multiple directives imply listening on multiple ports). A host name of "*" implies listening on all available interfaces. If specified, ciphers is the list of ciphers that will be accepted by the SSL connection; it is a string in the same format as in OpenSSL ciphers(1) and SSL_CTX_set_cipher_list(3). Both ListenHTTP and ListenHTTPS may be specified as may times as required.
- HTTPSHeaders cert "header"
- Add HTTPS-specific headers. By default, Pound passes requests unchanged to the back-end server(s). If the header is not empty it represents the value of a header to be added to the request. The cert tells Pound what to do about client certificates: 0 - don't ask (default), 1 - ask, 2 - ask and fail if no certificate was presented, 3 - ask but do not verify.
- CAlist CAcert_file Set the list of "trusted" CA's for this server. The CAcert_file is a file containing a sequence of CA certificates (PEM format). The names of the defined CA certificates will be sent to the client on connection.
- VerifyList Verify_file verify_depth Set the CA (Certificate Authority) and CRL (Certificate Revocation List). The Verify_file is a file that contains the CA root certificates and CRL (in PEM format). Verify_depth is the depth of verification for a client certificate (up to 9). A value of 0 (the default) implies no verification at all.
- Please note: there is an important difference between the CAlist and the VerifyList. The CAlist tells the client (browser) which client certificates it should send. The VerifyList defines which CAs are actually used for the verification of the returned certificate.
- User user_name
- Specify the user Pound will run as (must be defined in /etc/passwd).
- Group group_name
- Specify the group Pound will run as (must be defined in /etc/group).
- RootJail directory_path_and_name
- Specify the directory that Pound will chroot to at runtime. Please note that OpenSSL requires access to /dev/urandom, so make sure you create a device by that name, accessible from the root jail directory.
- ExtendedHTTP value
- if value is 1, allow extended HTTP requests (PUT, DELETE). By default, Pound only allows GET, POST and HEAD.
- WebDAV value
- if value is 1, allow WebDAV requests (LOCK, UNLOCK and if compiled with MS support: SUBSCRIBE, PROPFIND, PROPPATCH, SEARCH, POLL, MKCOL, MOVE, COPY, DELETE, BDELETE, CONNECT, OPTIONS, TRACE, MKACTIVITY, CHECKOUT, MERGE, REPORT). This, as far as I can tell, is what Microsoft needs in its private WebDAV version. Whether my understanding of their semantics is correct is debatable. Whether their understanding of their semantics is correct is also debatable (they had to patch their own proxy several times in order to support WebDAV). MS support is also required for Subversion (see http://subversion.tigris.org for details) access.
- LogFacility value
- Specify the log facility to use. value (default: daemon) must be one of the symbolic facility names defined in syslog.h. This facility shall be used for logging (if Pound was compiled with support for syslog).
- LogLevel value
- Specify the logging level: 0 for no logging, 1 (default) for regular logging, 2 for extended logging (show chosen backend server as well), 3 for Apache-like format (Common Log Format with Virtual Host) and 4 (same as 3 but without the virtual host information).
- NoHTTPS11 value
- Behave like an HTTP/1.0 server for HTTPS clients. If this value is 0 disable the check. If the value is 1 do not allow multiple requests on SSL connections. If the value is 2 (default) disable multiple requests on SSL connections only for MSIE clients. Required work-around for a bug in certain versions of IE.
- NoDaemon
- Have Pound run in the foreground. By default Pound runs as a daemon (detaches itself from the controlling terminal and puts itself in the background). By specifying this option you can force Pound to work like a regular process. Useful for debugging or if you want to use something like daemontools.
- Alive value
- Specify how often Pound will check for resurected back-end hosts (default: 30 seconds). In general, it is a good idea to set this as low as possible - it will find resurected hosts faster. However, if you set it too low it will consume resources - so beware.
- Server value
- Specify for how long Pound will wait for a server response. After this long has passed without the server sending any data Pound will consider the response finished and abort the connection. A value of 0 (default) implies waiting forever. Set it higher if your server(s) occasionally time-out on a slow network or are over-loaded.
- Client value
- Specify for how long Pound will wait for a client request (default: 10 seconds). After this long has passed without the client sending any data Pound will close the connection. Set it higher if your clients time-out on a slow network or over-loaded server, lower if you start getting DOS attacks or run into problems with IE clients.
- SSLEngine name
- Use an OpenSSL hardware acceleration card called "name". Available only if OpenSSL-engine is installed on your system.
- Err500 "filename"
- A file with the text to be displayed if an Error 500 occurs. Default: "An internal server error occurred. Please try again later.".
- Err501 "filename"
- A file with the text to be displayed if an Error 501 occurs. Default: "This method may not be used.".
- Err503 "filename"
- A file with the text to be displayed if an Error 503 occurs. Default: "The service is not available. Please try again later.".
- Err414 "filename"
- A file with the text to be displayed if an Error 414 occurs. Default: "Request URI is too long.".
- RewriteRedirect value
- If value is 1 (default) check the responses from the back-end servers. If a response is a redirect to a back-end managed by Pound the response is modified to be a redirect to Pound itself. A value of 0 disables this behaviour. A value of 2 will also ignore the ports and check only on host name identity.
- CheckURL value
- If value is 1 check the requested URL for correct syntax. If value is 0 (default) no checking is performed, and additional CSsegment or similar directives are quietly ignored.
- CSsegment chars
- The allowed character set for the segment part of the request. Same for CSparameter, CSqid, CSqval and CSfragment. See below for details on URL matching.
- MaxRequest nnn
- Request maximal size. All requests will be limited to these many bytes. If a request contains more data than allowed an error is returned. Default: unlimited.
- HeadRemove "header"
- Remove certain headers from the incoming requests. All occurences of the matching specified header will be removed. Please note that this filtering is done prior to other checks (such as HeadRequire or HeadDeny), so you should not try to check for these headers in later matches. Multiple directives may be specified in order to remove more than one header, and the header itself may be a regular pattern (though this should be used with caution).
GROUP DIRECTIVES
Group directives apply to a specific group of requests. The order of the group directives is important - incoming requests will be matched against the given patterns in the order they appear in the file, and the first group that matches wins.
If a request does not match any of the defined groups it will not be sent anywhere (there is no default server). This can come in handy if you want to block a specific kind of requests, though it would be better style to do this with a catch-all group with no servers.
- UrlGroup "pattern"
- Specify a group of backend servers based on a URL pattern. All requests fitting the pattern will be served by the defined servers. Pattern is a regular pattern as specified in regex(7) - extended version. The patterns are tested in order of definition, so the last pattern should usually be a catch-all .* The group ends with a EndGroup directive.
- BackEnd address,port,priority[,ha_port]
- Specify a backend server: address and port. Priority is 1 to 9 and defines a weighting - higher priority servers get used more often. May only be used in an UrlGroup directive. If no servers are specified, then the specified URLs will be simply blocked.
- Session TYPE [id] seconds
- Specify the time (in seconds) that a session will be kept. May be used exactly once and only in an UrlGroup directive. TYPE is one of:
- IP - the session is kept based on client IP address. No id is allowed. The time may be negative, in which case Pound will use sticky sessions: instead of keeping a normal session the client IP address is always mapped (hashed) to the same back-end.
- BASIC - the session is kept based on Basic Authentication data. No id is allowed.
- URL - the session is kept based on the value of a parameter in the request URL. The id indicates which parameter will be checked.
- COOKIE - the session is kept based on a cookie (in the request or the response). The id indicates which cookie will be checked.
- HeadRequire header "pattern"
- Specifiy header(s) that must appear in the request. Only requests that include the specified HTTP header will match. May only be used in an UrlGroup directive. The headers will be checked against the "^header: *pattern$" regular pattern. As many HeadRequire directives as necessary may appear in a single group.
- HeadDeny header "pattern"
- Specifiy headers that may not appear in the request. Only requests that do not include the specified HTTP header will match. May only be used in an UrlGroup directive. The headers will be checked against the "^header: *pattern$" regular pattern. As many HeadDeny directives as necessary may appear in a single group.
See below for some examples.
HIGH-AVAILABILITY
Pound attempts to keep track of active back-end servers, and will temporarily disable servers that do not respond (though not necessarily dead: an overloaded server that Pound cannot establish a connection to will be considered dead). However, every Alive seconds, an attempt is made to connect to the dead servers in case they have become active again. If this attempt succeeds, connections will be innitiated to them again.
In general it is a good idea to set this time interval as low as is consistent with your resources in order to benefit from resurected servers at the earliest possible time. The default value of 30 seconds is probably a good choice.
Set the interval to 0 to disable this feature. The clients that happen upon a dead backend server will just receive a 503 Service Unavailable message.
The ha_port parameter specifies an additional port that is used only for viability checks: if this port is specified in a BackEnd directive, Pound will attempt periodically (every Alive seconds) to connect to this port. If the port does not respond the server is considered dead. It never makes sense to have the ha_port identical to the main back-end port: this would only generate extra, unncecessary activity (CPU, network traffic) for no good reason whatsoever. The ha_port is meant for applications that offer an additional health monitoring port or for installations that wish to take servers off-line in a controlled manner.
URL MATCHING
Pound attempts to filter out illegal request URLs. In general a URL is defined as
{ / segment [; parameter] } [? qid [ = [ qval ] ] { & qid [ = [ qval ] ] } ] [ # fragment ]
Each of the elements is matched against the allowed character set. By default, the parts are defined as:
CSsegment - ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789_.!~*'():@&=+$,%-
CSparameter - ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789_.!~*'():@&=+$,%-
CSqid - ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789_.!~*'(),%-
CSqval - ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789/_.!~*'(),%-+
CSfragment - ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789_.!~*'(),%-
If Pound was compiled with support for MS DAV the segment part includes, in addition, the characters {}<>".
This mechanism comes in handy should you need to define some other "legal" URLs. A common occurence is that PHP programmers use unencoded parameters in their requests such as /xxx?id[2]=abc. For such cases define:
CSqid ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789_.!~*'(),%-[]
in your config file. Additionally this can be useful for accented characters and other non-RFC conformant requests.
Please be aware that each of these additional definitions may introduce security problems - use them at your own risk.
HTTPS HEADERS
If a client browser connects to Pound via HTTPS and if it presents a client certificate and if HTTPSHeaders is set (HTTPSHeaders 1 "value"), Pound adds the following headers to the request it issues to the server:
- value
- The value, if present, is added to the headers.
- X-SSL-Subject
- Details about the certificate owner.
- X-SSL-Issuer
- Details about the certificate issuer (Certificate Authority).
- X-SSL-notBefore
- Starting date of certificate validity.
- X-SSL-notAfter
- Ending date of certificate validity.
- X-SSL-serial
- Certificate serial number (decimal).
- X-SSL-cipher
- The cipher currently in use.
- X-SSL-certificate
- The full client certificate (PEM-format multi-line)
It is the application's responsibility to actually use these headers - Pound just passes this information without checking it in any way (except for signature and encryption correctness).
SECURITY
In general, Pound does not read or write to the hard-disk. The exceptions are reading the configuration file and (possibly) the server certificate file(s) and error message(s), which are opened read-only on startup, read, and closed, and the pid file which is opened on start-up, written to and immediately closed. Following this there is no disk access whatsoever, so using a RootJail directive is only for extra security bonus points.
Pound tries to sanitise all HTTP/HTTPS requests: the request itself, the headers and the contents are checked for conformance to the RFC's and only valid requests are passed to the back-end servers. This is not absolutely fool-proof - as the recent Apache problem with chunked transfers demonstrated. However, given the current standards, this is the best that can be done - HTTP is an inherently weak protocol.
ADDITIONAL NOTES
Pound uses the system log for messages (default facility LOG_DAEMON). The format is very similar to other web servers, so that if you want to use a log tool:
- fgrep pound /var/log/messages | your_log_tool
Translating HTTPS to HTTP is an iffy proposition: no client information is passed to the server itself (certificates, etc) and the backend server may be misled if it uses absolute URLs. A patch for Zope is included in the distribution to address this issue - for other Web servers you are on your own. May the source be with you.
Pound deals with (and sanitizes) HTTP/1.1 requests. Thus even if you have an HTTP/1.0 server, a single connection to an HTTP/1.1 client is kept, while the connection to the back-end server is re-opened as necessary.
Pound attempts to resolve the names of the hosts that appear in various requests and/or responses. That means it need a functioning resolver of some kind (be it /etc/hosts, DNS or something else).
EXAMPLES
To translate HTTPS requests to a local HTTP server (assuming your network address is 123.123.123.123):
-
ListenHTTPS 1.2.3.4,443 /etc/pound/server.pem
UrlGroup ".*"
BackEnd 127.0.0.1,80,1
EndGroup
To distribute the HTTP/HTTPS requests to three read-only Web servers, where the third one is a newer and faster machine:
-
ListenHTTP 123.123.123.123,80
ListenHTTPS 1.2.3.4,443 /etc/pound/server.pem
UrlGroup ".*"
BackEnd 192.168.0.10,80,1
BackEnd 192.168.0.11,80,1
BackEnd 192.168.0.12,80,3
EndGroup
To distribute the HTTP/HTTPS requests to two Web servers with long session times; also change the uid/gid of the running program and do a chroot:
-
ListenHTTP 123.123.123.123,80
ListenHTTP 123.123.123.123,8080
ListenHTTPS 1.2.3.4,443 /etc/pound/server.pem
User www
Group www
RootJail /var/pound
UrlGroup ".*"
BackEnd 192.168.0.10,80,1
BackEnd 192.168.0.11,80,1
Session IP 600
EndGroup
To separate between image requests and other Web content and block all requests for a specific URL:
-
ListenHTTP 123.123.123.123,80
# Images server(s)
UrlGroup ".*.(jpg|gif)"
BackEnd 192.168.0.12,80,1
EndGroup
# Block all requests for /forbidden
UrlGroup "/forbidden.*"
EndGroup
# Catch-all server(s)
UrlGroup ".*"
BackEnd 192.168.0.10,80,1
BackEnd 192.168.0.11,80,1
Session BASIC 300
EndGroup
Here is a more complex example: assume your static images (GIF/JPEG) are to be served from a single back-end 192.168.0.10. In addition, 192.168.0.11 is to do the hosting for www.myserver.com with URL-based sessions, and 192.168.0.20 (a 1GHz PIII) and 192.168.0.21 (800Mhz Duron) are for all other requests (cookie-based sessions). The logging will be done by the back-end servers. The configuration file may look like this:
-
# Main listening ports
ListenHTTP 1.2.3.4
ListenHTTPS 1.2.3.4,443 /etc/pound/pound.pem
User nobody
Group nogroup
RootJail /var/pound/jail
Client 15
Alive 60
HTTPSHeaders 1 ""
LogLevel 0
# Image server
UrlGroup ".*.(jpg|gif)"
BackEnd 192.168.0.10,80,1
EndGroup
# Virtual host www.myserver.com
UrlGroup ".*sessid=.*"
HeadRequire Host ".*www.myserver.com.*"
BackEnd 192.168.0.11,80,1
Session URL sessid 120
EndGroup
# Everybody else
UrlGroup ".*"
BackEnd 192.168.0.11,20,5
BackEnd 192.168.0.11,21,4
Session COOKIE userid 180
EndGroup
FILES
- /var/run/pound.nnn
- this is where Pound will attempt to record its process id.
- /etc/pound/pound.cfg
- the default configuration file (the location may be changed when compiling - see the F_CONF flag in the Makefile).
- /etc/pound/cert.pem
- the certificate file(s) for HTTPS. The location must be defined in the configuration file - this is only a suggestion. The file must contain a PEM-encoded certificate, optionally a certificate chain from a known Certificate Authority to your server certificate and a PEM-encoded private key (not password protected). See OpenSSL(1) for details. This file should be well protected, lest someone gets your server private key.
AUTHOR
Written by Robert Segall, Apsis GmbH.
REPORTING BUGS
Report bugs to <roseg@apsis.ch>.
COPYRIGHT
Copyright © 2002 Apsis GmbH.
This is free software; see the source for copying conditions. There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.