pound - HTTP/HTTPS reverse-proxy and load-balancer

NAME  SYNOPSIS  DESCRIPTION  GENERAL PRINCIPLES  REQUEST BALANCING  WORKER MODEL  OPTIONS  CONFIGURATION FILE  GLOBAL DIRECTIVES  Control socket  HTTP Listener  String expansion  Modification directives  Compatibility directives  HTTPS Listener  Service  Service Matching Directives  Compatibility directives  Negation  Match statement  Modification directives  Backend definitions  Other directives  ACME  Backend  Global and per-service backends  Emergency  Session  Metrics  HIGH-AVAILABILITY  REQUEST MODIFICATION DIRECTIVES  BUILT-IN HEADERS  Forwarded Headers  HTTPS Headers  RESPONSE MODIFICATION  BASIC AUTHENTICATION  REQUEST LOGGING  Format specification  Built-in formats  SECURITY  DEPRECATED FEATURES  Configuration statements  Redirect request hack  Multiple redirect backends  ADDITIONAL NOTES  EXAMPLES  FILES  AUTHOR  REPORTING BUGS  COPYRIGHT 

NAME

pound − HTTP/HTTPS reverse-proxy and load-balancer

SYNOPSIS

pound

[−FVcehv] [−W [no−]FEATURE] [−f CONF-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 (backends). These requests may be passed to backends as plain HTTP or re-encrypted as HTTPS.

If more than one backend server is defined, pound chooses one of them randomly, based on the requested balancing algorithm and backend priorities. By default, pound keeps track of associations between clients and backend servers (sessions).

GENERAL PRINCIPLES

In general pound needs three types of objects defined in order to function: listeners, services and backends.
Listeners

A listener is a definition of how pound receives requests from the clients (browsers). Listeners of two types are supported: regular HTTP listeners and HTTPS listeners. In the simplest case, a listener must define the address and port to listen on, with additional requirements for HTTPS listeners.

Services

A service routes requests to backends. Services may be defined within a listener or in global scope. When a request is received, pound attempts to match it to each service in turn, starting with the services defined in the listener itself and, if needed, continuing with those defined at the global level. Services may define their own conditions as to which requests they can answer: typically this involves certain URLs (images only, or a certain path) or specific headers (such as the Host header). A service may also define a session mechanism: if so, future requests from a given client will always be answered by the same backend.

Backends

Backends are the actual servers for the content requested. By itself, pound supplies no responses - all contents must be received from a "real" web server. A backend defines how the server should be contacted.

Several types of backends are defined:
Regular backend

Regular backends are the most often used type of backends and the raison d’etre of pound. A regular backend passes received requests to a backend server, waits for it to respond and sends the response back to the requesting client.

Redirect backend

A redirect backend responds to each request with a redirect response. See Redirect, below.

ACME backend

A special backend designed to handle ACME challenges. Backends of this type are used to handle HTTP-01 authorization when re-issuing LetsEncrypt certificates.

See the ACME section below.

Error backend

An error backend creates and returns an HTTP status response.

Emergency backend

A special case of regular backend which will be used only if all other regular backends fail to respond.

Multiple backends may be defined within a service, in which case pound will balance the load between the available backends.

Two types of load-balancing strategies are implemented: random balancing (default), and interleaved weighted round-robin balancing.

If a backend fails to respond, it will be considered "dead", in which case pound will stop sending requests to it. Dead backends are periodically checked for availability, and once they respond again they are "resurrected" and requests are sent again their way. If no backends are available (none were defined, or all are "dead"), then pound will reply with "503 Service Unavailable", without checking additional services.

Normally, the connection between pound and its backends is via plain HTTP. It is, however, possible to use HTTPS as well.

A working pound configuration may define multiple listeners and services. They can be identified either by 0-based ordinal number within the configuration (or, for services, within the listener) or by their symbolic name. Backends are identified by their ordinal number within service.

REQUEST BALANCING

Load balancing strategy defines algorithm used to distribute incoming requests between multiple regular backends. Two such strategies are implemented:
Weighted Random Balancing

This is the default strategy. Each backend is assigned a numeric priority between 0 and 9 (inclusive). The backend to use for each request is determined at random taking into account backend priorities, so that backends with numerically greater priorities have proportionally greater chances of being selected than the ones with lesser priorities. The share of requests a backend handles can be estimated as:

Pi / S(P),

where Pi is priority of the backend with index i, and S(P) is sum of all priorities.

Interleaved Weighted Round Robin Balancing

Requests are assigned to each backend in turn. Backend priorities, or weights are used to control the share of requests handled by each backend. The greater the weight, the more requests will be sent to this backend. In general, the share of requests assigned to a backend is calculated by the following relation:

(Pi + 1) / (N + S(P)),

where N is the number of backends, Pi and S(P) as discussed above.

WORKER MODEL

Each incoming request is processed by a specific worker, i.e. a thread in the running program. The number of running workers is controlled by three configuration parameters. WorkerMinCount defines the minimum number of workers that should always be running (5, by default). Another parameter, WorkerMaxCount sets the upper limit on the number of running workers (it defaults to 128).

At each given moment, a worker can be in one of two states: idle or active (processing a request). If an incoming request arrives when all running workers are active, and total number of workers is less than WorkerMaxCount, a new thread is started and the new request is handed to it. If the number of active workers has already reached maximum, the new request is added to the request queue, where it will wait for a worker to become available to process it.

The third parameter, WorkerIdleTimeout, specifies maximum time a thread is allowed to spend in the idle state. If a worker remains idle longer than that and total number of workers is greater than the allotted minimum (WorkerMinCount), the idle worker is terminated.

OPTIONS

The following command line options are available:

−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.

−e

Log to standard error (standard output for LOG_DEBUG and LOG_INFO severity levels). This option implies foreground mode (−F) and overrides the LogLevel configuration setting.

−F

Foreground mode. The program will not detach from the controlling terminal and will remain in foreground after startup. This overrides the Daemon configuration setting. The log stream (syslog facility or stderr) requested in the configuration remains in effect. See also the −e option, above.

−f FILE

Location of the configuration file (see below for a full description of the format). Default is $sysconfdir/pound.cfg, where $sysconfdir stands for the system configuration directory, as determined at build time. Most often it is either /usr/local/etc, or /etc.

−h

Print short command line usage summary and exit.

−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. See the description of PIDFile statement in the GLOBAL DIRECTIVES section below, for a detailed discussion of this file.

−v

Verbose mode: during startup, error messages will be sent to stderr (stdout for LOG_DEBUG and LOG_INFO severity levels). If pound was configured to log to syslog, error diagnostics will be duplicated there as well. After startup the configuration settings take effect.

−V

Print version: pound will exit immediately after printing the current version, licensing terms, and configuration flags.

−W [no−]FEATURE

Enable or disable (if prefixed with no−) additional pound features. As of this version, the following FEATUREs are implemented:
[no−]dns

Resolve host names found in configuration file. This is the default. You can disable it if your configuration file refers to backends only by their IP addresses, in order to suppress potentially lengthy network host address lookups.

no−include−dir

Don’t set the include directory to the system configuration directory. This means that each relative filename used in arguments to the directives in the configuration file will be looked up in the current working directory. This feature is useful mainly in testsuite.

include−dir=DIR

Override the default include directory setting. Set it to DIR. See the discussion of the IncludeDir directive in section GLOBAL DIRECTIVES, below.

CONFIGURATION FILE

Each line in the file is considered a complete configuration directive. Empty lines and comments are ignored. Comments are introduced with a # sign and extend to the end of line on which it appears.

There are three types of directives: global directives (they affect the settings for the entire program instance), listener directives (they define which requests pound will listen for), and service directives (they affect only a specific group of requests).

In general, a directive consists of a keyword and one or more values, separated by any amount of whitespace. Leading and trailing whitespace is ignored. Keywords are case-insensitive. A value can be:
Numeric

A decimal number.

Boolean

The words yes, true, on, or 1 indicating true, and no, false, off, or 0 indicating false. All words are case-insensitive.

String

Any sequence of characters between double-quotes. A backslash is treated as an escape character: if it is followed by a double-quote or another backslash, it is removed and the character after it is read literally. If it is followed by any other character, a warning message is printed.

Identifier

A sequence of characters starting with an ASCII letter and consisting of letters, digits and underscores.

IP address

An IPv4 or IPv6 address in numeric form, or a hostname.

Unless specified otherwise, directives may appear in any order.

GLOBAL DIRECTIVES

Global directives may appear anywhere at the top level within the configuration file, although it is customary for them to be at the start.
User
"user_name"

Specify the user pound will run as (must be defined in the system user database).

Group "group_name"

Specify the group pound will run as (must be defined in the system group database).

RootJail "directory"

Specify the directory that pound will chroot to at runtime.

HeaderOption opt...

Sets default options for header addition. opt is one of: none to disable additional headers, forwarded to enable adding X−Forwarded−For, X−Forwarded−Proto, and X−Forwarded−Port headers, and ssl to enable passing information about SSL certificates in various X−SSL−* headers. The default is

HeaderOption forwarded ssl

This setting can be overridden on a per-listener basis. See the description of HeaderOption directive in HTTP Listener section, and section BUILT-IN HEADERS, for a detailed discussion of various header modification directives and their effect.

Balancer random | iwrr

Defines the load-balancing strategy to use. Possible arguments are: random, to use weighted random balancing algorithm. an iwrr, meaning interleaved weighted round robin balancing. See REQUEST BALANCING, above, for a detailed discussion of these balancing strategies.

The Balancer statement in global scope applies to all Service directives that don’t contain Balancer definitions of their own.

Daemon bool

Have pound run in the foreground (if false) or as a daemon (if true). 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.

Supervisor bool

When running in daemon mode, start a supervisor process first. This process will monitor the subordinate pound process, restarting it if it fails.

WorkerMinCount N

Sets minimum number of worker threads that must always be running. The default is 5. See the section WORKER MODEL above for a detailed discussion.

WorkerMaxCount N

Sets maximum number of worker threads. The default is 128. See the section WORKER MODEL above for a detailed discussion.

WorkerIdleTimeout SEC

Sets idle timeout for a worker thread. Default is 30 seconds. See the section WORKER MODEL above for a detailed discussion.

Threads N

This statement, retained for backward compatibility with previous versions of pound, is equivalent to:

WorkerMinCount N
WorkerMaxCount N

LogFacility ident

Specify the log facility to use. The ident is one of the following: auth, authpriv, cron, daemon, ftp, kern, lpr, mail, news, syslog, user, uucp, local0 through local7. The default value is daemon. Using a (dash) for the facility name causes pound to log to stdout/stderr.

LogFormat "name" "format_def"

Define HTTP log format. Name is a string uniquely identifying this format. Format_def is the format string definition. See below, section REQUEST LOGGING, for a detailed description.

LogLevel n

Specify the logging level using built-in format indices: 0 for no logging, 1 (default) for regular logging, 2 for extended logging (show chosen backend server as well), 3 for Apache-like format (Combined Log Format with Virtual Host), 4 (same as 3 but without the virtual host information) and 5 (same as 3 but with information about the Service and Backend used). This value can be overridden for specific listeners.

See below, section REQUEST LOGGING, for a detailed description.

LogLevel "name"

Select a named format for logging HTTP requests. Name can be either one of five built-in format names (null, regular, extended, vhost_combined, combined, or detailed), or a format name defined earlier via the LogFormat directive. See section REQUEST LOGGING, for a detailed discussion.

ForwardedHeader name

Defines the name of the HTTP header that carries the list of proxies the request has passed through. It is used to report the originator IP address when logging. See the description of %a specifier in REQUEST LOGGING. The default is X−Forwarded−For.

TrustedIP

Defines a list of trusted proxy IP addresses, which is used to determine the originator IP. See the description of %a specifier in REQUEST LOGGING, for a detailed discussion.

This statement is a special form of ACL statement, described below. It can appear as a section or directive. When used as a section, it is followed by a list of one or more CIDRs each appearing on a separate line. The End keyword terminates the statement, e.g.:

TrustedIP
"127.0.0.1/8"
"10.16.0.0/16"
End

In directive form, this statement takes single argument, the name of an access control list defined earlier using the ACL statement, e.g.

TrustedIP "proxy_addresses"

IgnoreCase bool

Ignore case when doing regex matching (default: false). This directive sets the default for the following service matching directives: URL, Path, QueryParam, Query, StringMatch, as well as for the DeleteHeader modification directive. Its value can be overridden for specific services.

This statement is deprecated and will be removed in future versions. Please, use the −icase option to the service matching directive instead. See the discussion of options in Service Matching Directives section below.

Alive n

Specify how often pound will check for resurrected backend hosts (default: 30 seconds). In general, it is a good idea to set this as low as possible - it will find resurrected hosts faster. However, if you set it too low it will consume resources - so beware.

Client n

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. This value can be overridden for specific listeners.

TimeOut n

How long should pound wait for a response from the backend (in seconds). Default: 15 seconds. This value can be overridden for specific backends.

ConnTO n

How long should pound wait for a connection to the backend (in seconds). Default: the TimeOut value. This value can be overridden for specific backends.

WSTimeOut n

How long should pound wait for data from either backend or client in a connection upgraded to a WebSocket (in seconds). Default: 600 seconds. This value can be overridden for specific backends.

Grace n

How long should pound continue to answer existing connections after a receiving a INT or HUP signal (default: 30 seconds). The configured listeners are closed immediately. You can bypass this behaviour by stopping pound with a TERM or QUIT signal, in which case the program exits without any delay.

SSLEngine "name"

Use an OpenSSL hardware acceleration card called name. Available only if OpenSSL-engine is installed on your system.

ECDHcurve "name"

Use the named curve for elliptical curve encryption (default: prime256v1).

Control "pathname"

Set the control socket path. See the Control socket section below, for a detailed description of this feature.

IncludeDir "dir"

Sets the include directory. This is the directory where pound looks for relative file names that appear in other configuration directives (e.g. Include). The default value is the system configuration directory as set at compile time (you can check its value in the output of pound -V). This initial value can be changed in the command line using the −W include−dir=name option or reset to the current working directory using the −W no−include−dir option (see the discussion of −W below).

Include "file"

Include the file as though it were part of the configuration file. If file is a relative file name, it will be looked in the include directory (see above).

This directive is allowed both at topmost level and in any subsections of the configuration file.

Anonymise

(alternative spelling Anonymize also accepted) Replace the last byte of the client address with 0 for logging purposes. Default: log the client address in full.

ACL "name"

Define a named access control list (ACL). An ACL is a list of network addresses in CIDR notation, one address per line, terminated with an End directive on a line by itself. E.g.:

ACL "secure"
"192.0.2.0/26"
"203.0.113.0/24"
End

The Include directive is allowed within ACL.

Named ACLs can be used in Service definitions to make services available from certain IP addresses only.

PIDFile "filename"

Sets the name of the file where to store program PID. It can be overridden by the −p command line option.

Notice the following:

1.

When running with a supervisor, this file holds PID of the supervisor process. Otherwise, it holds PID of the main pound process. This means it is always suitable for signalling the program using the traditional kill ‘cat filename‘ technique.

2.

Before shutting down, pound removes this file. However, this may be not possible if it switches to privileges of another user after startup (at least one of User or Group are set in the configuration file) and the file is stored in a directory whose permissions forbid write access for that user.

Control socket

Pound can be instructed to listen on a UNIX socket for management requests, which will allow you to obtain information about the running instance, change state of configured listeners, services, and backends, etc. These requests may be issued by using the poundctl(8) utility.

The use of this control socket is configured via the Control statement. This statement has two forms. In inline form, the statement takes a single argument, specifying the name of the UNIX socket file to create and listen on. For example:

Control "/run/pound.sock"

The file will be owned by the user that started pound (normally root) and will have mode 0600.

The block form allows you to specify file mode and, to certain extent, the socket file ownership:

Control
Socket "/run/pound.sock"
Mode 660
ChangeOwner true
End

The substatements are:
Socket
filename

Specifies the name of the socket file to use. This is the only mandatory statement in the block form.

Mode octal

Sets the mode of the socket file.

ChangeOwner bool

This statement takes effect if at least one of User or Group global statements is used. When set to true it will change the owner of the socket file to that specified by those two statements.

HTTP Listener

An HTTP listener defines an address and port that pound will listen on for HTTP requests. The listener declaration begins with the keyword ListenHTTP on a separate line. The keyword may be followed by a quoted string supplying listener name. This name is a unique label that identifies the listener.

All configuration directives enclosed between ListenHTTP and End are specific to a single HTTP listener. At the very least you must specify IP address and port for each listener. The following directives are available:
Address
address

The address that pound will listen on. This can be a numeric IP address, or a symbolic host name that must be resolvable at run-time, or a full pathname of a UNIX socket. Either this parameter or SocketFrom (see below) must be present. The address 0.0.0.0 may be used as an alias for ’all available addresses on this machine’.

Port port

The port number or service name that pound will listen on. This parameter must be present if the Address parameter contains an IPv4 or IPv6 address.

SocketFrom "pathname"

Read the socket to listen on from the UNIX socket given as argument. If this parameter is supplied, neither Address nor Port may be used. This parameter is intended for testing pound.

xHTTP n

Defines which HTTP verbs are accepted. The possible values are:

0 (default) accept only standard HTTP requests (GET, POST, HEAD).

1 additionally allow extended HTTP requests (PUT, PATCH, DELETE).

2 additionally allow standard WebDAV verbs (LOCK, UNLOCK, PROPFIND, PROPPATCH, SEARCH, MKCOL, MOVE, COPY, OPTIONS, TRACE, MKACTIVITY, CHECKOUT, MERGE, REPORT).

3 additionally allow MS extensions WebDAV verbs (SUBSCRIBE, UNSUBSCRIBE, NOTIFY, BPROPFIND, BPROPPATCH, POLL, BMOVE, BCOPY, BDELETE, CONNECT).

Client n

Override the global Client time-out value.

CheckURL "pattern"

Define a pattern that must be matched by each request sent to this listener. A request that does not match is considered to be illegal. By default pound accepts all requests (i.e. the pattern is ".*"), but you are free to limit it to something more reasonable. Please note that this applies only to the request path - pound will still check that the request is syntactically correct.

Err400 "filename"

A file with the text to be displayed if an Error 400 occurs.

Err401 "filename"

A file with the text to be displayed if an Error 401 occurs.

Err403 "filename"

A file with the text to be displayed if an Error 401 occurs.

Err404 "filename"

A file with the text to be displayed if an Error 404 occurs.

Err413 "filename"

A file with the text to be displayed if an Error 413 occurs. Default text: "Request too large.".

Err414 "filename"

A file with the text to be displayed if an Error 414 occurs.

Err500 "filename"

A file with the text to be displayed if an Error 500 occurs.

Err501 "filename"

A file with the text to be displayed if an Error 501 occurs.

Err503 "filename"

A file with the text to be displayed if an Error 503 occurs.

MaxRequest n

Maximum allowed size of incoming request. All requests will be limited to these many bytes. If a request contains more data than allowed, an error 413 is returned. Default: unlimited.

RewriteLocation 0|1|2

If set to 1, force pound to change the Location: and Content-location: headers in responses. If they point to the backend itself or to the listener (but with the wrong protocol), the response will be changed to show the virtual host in the request. Default: 1 (active). If the value is set to 2, only the backend address is compared; this is useful for redirecting a request to an HTTPS listener on the same server as the HTTP listener.

RewriteDestination bool

If set to true, force pound to change the "Destination:" header in requests. The header is changed to point to the backend itself with the correct protocol. Default: false.

LogLevel n

Log HTTP requests using built-in format n. This statement configures logging specific for this listener, overriding the global LogLevel setting. See REQUEST LOGGING, for a detailed discussion.

LogLevel "name"

Select a named format for logging HTTP requests. Name can be either one of five built-in format names (null, regular, extended, vhost_combined, combined, or detailed), or a format name defined earlier via the LogFormat directive.

This statement configures logging specific for this listener, overriding the global LogLevel setting. See section REQUEST LOGGING, for a detailed discussion.

ForwardedHeader name

Defines the name of the HTTP header that carries the list of proxies the request has passed through. It is used to report the originator IP address when logging. See the description of %a specifier in REQUEST LOGGING. This statement overrides the ForwardedHeader directive from the global scope.

The default is X−Forwarded−For.

TrustedIP

Defines a list of trusted proxy IP addresses, which is used to determine the originator IP. See the description of %a specifier in REQUEST LOGGING, for a detailed discussion.

This statement overrides the TrustedIP directive from the global scope.

Service [ "name" ]

This defines a private service (see below for service definition syntax). This service will be used only by this listener. Optional name supplies the label, that can be used in poundctl(8) requests to identify the service. This label must be unique among all services within the enclosing listener, or, for global services, within the configuration.

ACME "directory"

Serve ACME challenge requests from the given directory. See section ACME below.

HeaderOption opt...

Modifies global header addition options for this listener. Global options are set by the HeaderOption directive in the global scope and default to forwarded ssl. opt is one of:

all

Enable all additional headers.

none

Disable all additional headers.

forwarded

Enable adding X−Forwarded−For, X−Forwarded−Proto, and X−Forwarded−Port headers.

ssl

Enable passing information about SSL certificates in various X−SSL−* headers.

Each option except none can be prefixed with no− to revert its meaning.

For example, to disable adding the X−SSL−* headers for a listener, one would use:

HeaderOption no−ssl

See the description of HeaderOption directive in GLOBAL DIRECTIVES section, and section BUILT-IN HEADERS, for a detailed discussion of various header modification directives and their effect.

String expansion

Some of the statements described below take as their arguments string values that undergo several expansions before use. These expansions are as follows:
Backreference expansion

Backrefence is a construct that refers to a parenthesized group within a regular expression matched by one of service matching directives described above. During backreference expansion, each occurrence of such construct in a string is replaced with the actual value of that parenthesized group.

Syntactically backreference can take two forms. The construct $N (N is a decimal number) refers to Nth parenthesized subexpression of the most recently matched statement, and $N(M) refers to Nth parenthesized subexpression of Mth recently matched statement. Numbering of subexpressions starts at 1 ($0 refers to the entire matching string). Numbering of matches starts at 0.

For example, given the following statements

Host -re "www\.(.+)"
Header -re -icase "ˆContent-Type: *(.*)"
Path "ˆ/static(/.*)?"

$1 refers to the subgroup of Path, $1(1) - to that of Header, and $1(2) - to that of Host.

Curly braces may be used to avoid incorrectly parsing text fragment that follows the reference as being its part. This is useful if the reference is immediately followed by a decimal digit or opening parenthesis, as in: "${1}(text)".

To insert a literal dollar or percent sign in url, use $$ or $%, correspondingly.

Request accessor interpretation

Request accessor is %[name], where name denotes part of the incoming request to access. Accessors are interpreted and replaced with the corresponding part of the request. Some accessors take an argument, which is specified after accessor name and is delimited from it by one or more whitespace characters.

The following accessors are defined:

url

Request URL.

path

Request path.

query

Query part.

param NAME

The value of the query parameter NAME.

header NAME

The value of HTTP header NAME.

host

Hostname part of the Host header. If the latter does not include port number, it is equivalent to %[header host]. port If the value of the Host header includes port number, %[port] evaluates to port number with the leading colon character. Otherwise, it evaluates to empty string.

Modification directives

The following directives modify the incoming request prior to passing it to the selected service. These are discussed in detail in section REQUEST MODIFICATION, below.
DeleteHeader
"header: pattern"

Remove certain headers from the incoming requests. All occurrences of the matching header will be removed. The argument is treated verbatim.

SetHeader "header: value"

Add header to the request passed to the backend server. Argument undergoes string expansion as described above. The expanded value must be a valid header line.

SetURL "value"

Sets the URL part of the request. Argument is subject to string expansion.

SetPath "value"

Sets the path part of the request. Argument is subject to string expansion.

SetQuery "value"

Sets the query part of the request. Argument is subject to string expansion.

SetQueryParam "name" "value"

Modifies the query. Sets the query parameter name to value. The value argument is subject to string expansion.

Rewrite [request|response] ... [ Else ... ] End

Conditionally modify request or response depending on whether it matches certain conditions. If the argument is omitted, request is assumed.

Request modification is described in detail in section REQUEST MODIFICATION DIRECTIVES .

Response modification is covered by section RESPONSE MODIFICATION.

Compatibility directives

The following directives are retained for compatibility with previous versions of pound. They will be removed in future releases.
HeaderAdd
"header: value"

Same as SetHeader.

AddHeader "header: value"

Same as SetHeader.

HeaderRemove "pattern"

Same as DeleteHeader.

HeadRemove "pattern"

Same as DeleteHeader.

HTTPS Listener

HTTPS listener defines an address and port that pound will listen on for HTTPS requests. The listener declaration begins with the keyword ListenHTTPS on a separate line. The keyword may be followed by a quoted string supplying listener name. This name is a unique label that identifies the listener.

All configuration directives enclosed between ListenHTTPS and End are specific to a single HTTPS listener. At the very least you must specify an address, a port and a server certificate for each listener. All directives defined for HTTP listeners are applicable to HTTPS listeners as well. The following additional directives are also available:
Cert
"filename"

Specify the server certificate. The certificate file is the file containing the certificate, possibly a certificate chain and the signature for this server. This directive is mandatory for HTTPS listeners.

Please note that multiple Cert directives are allowed if your OpenSSL version supports SNI. In such cases, the first directive is the default certificate, with additional certificates used if the client requests them.

The ordering of the directives is important: the first certificate where the CN matches the client request will be used, so put your directives in the most-specific-to-least specific order (i.e. wildcard certificates after host-specific certificates).

Cert directives must precede all other SSL-specific directives.

ClientCert 0|1|2|3 depth

Ask for the client’s HTTPS certificate: 0 - don’t ask (default), 1 - ask, 2 - ask and fail if no certificate was presented, 3 - ask but do not verify. Depth is the depth of verification for a client certificate (up to 9). The default depth limit is 9, allowing for the peer certificate and additional 9 CA certificates that must be verified.

Disable SSLv2|SSLv3|TLSv1|TLSv1_1|TLSv1_2

Disable the protocol and all lower protocols as well. This is due to a limitation in OpenSSL, which does not support disabling a single protocol. For example, Disable TLSv1 would disable SSLv2, SSLv3 and TLSv1, thus allowing only TLSv1_1 and TLSv1_2.

Ciphers "cipher_list"

This 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).

SSLHonorCipherOrder bool

If set to true, the server will broadcast a preference to use ciphers in the order supplied in the Ciphers directive. If the value is false, the server will accept any cipher from the Ciphers list. Default value is false.

SSLAllowClientRenegotiation 0|1|2

If this value is 0, client initiated renegotiation will be disabled. This will mitigate DoS exploits based on client renegotiation, regardless of the patch status of clients and servers related to "Secure renegotiation". If the value is 1, secure renegotiation is supported. If the value is 2, insecure renegotiation is supported, with unpatched clients. This can lead to a DoS and a Man in the Middle attack! The default value is 0.

CAlist "filename"

Set the list of "trusted" CA’s for this server. The filename is the name of 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 "filename"

Set the CA (Certificate Authority). The filename is a file that contains the CA root certificates (in PEM format).

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.

CRLlist "filename"

Set the CRL (Certificate Revocation List) file. The filename is a file that contains the CRLs (in PEM format).

NoHTTPS11 0|1|2

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.

Service

A service is a definition of which backend servers pound will use to reply to incoming requests. A service may be defined as part of a listener (in which case it will be used only by that listener), or globally (which makes it available to all listeners). Pound selects a listener based on user-supplied conditions that analyze the incoming request URL and/or headers. It will always scan listener-specific services first. If none matches, it will try the global ones. Services are tried in the same order as they are defined in configuration.

All configuration directives enclosed between Service and End are specific to a single service. They can be subdivided into two categories: service matching directives and backend definitions.

Service Matching Directives

These directives determine whether a particular request should be handled by this service. When a request arrives, each service is considered in turn (first services defined within the listener that received the request, then the ones defined in global scope). First service that matches the request will be used. If no service matches, a 503 "Service unavailable" error is returned.

Unless explicitly stated in the configuration file, all matching directives are joined by a boolean AND.

A service with no matching directives always matches.
ACL
"name"

Match the source IP address against the named ACL. The ACL must have been defined earlier (see the ACL statement in GLOBAL DIRECTIVES section above). If the IP doesn’t match, then this service will be skipped and next one tried.

ACL

This statement defines an unnamed ACL to match the source IP against. This line must be followed by one or more lines defining CIDRs, as described in the GLOBAL DIRECTIVES section above. The ACL definition is finished with a End keyword on a line by itself.

Semantically it is equivalent to the named ACL reference described above.

BasicAuth "filename"

Evaluates to true if the incoming request passes basic authorization as described in RFC 7617. filename is the name of a plain text file containing usernames and passwords, created with htpasswd(1) or similar utility. Unless it starts with a slash, it is taken relative to the IncludeDir directory. The file is cached in the memory on the first authorization attempt, so that further authorizations do not result in disk operations. The file will be rescanned if Pound notices that its modification time has changed.

See the section entitled BASIC AUTHENTICATION, for a detailed discussion.

Header [options] "pattern"

The request must contain at least one header matching the given pattern. By default, pattern is treated as case-insensitive extended regular expression. This can be changed by options, described below.

Host [options] "hostname"

The request must contain a Host header whose value matches hostname. In the absence of options, case-insensitive exact match is assumed, i.e. this construct is equivalent to

Header "Host:[[:space:]]*qhost"

where qhost is the "hostname" argument in quoted form, i.e. with all characters that have special meaning in regular expressions escaped.

See below for the discussion of options and their effect on matching.

This statement is provided to facilitate handling of virtual hosts. See the EXAMPLES section.

Path [options] "pattern"

Match the path part of the incoming request.

Query [options] "pattern"

Match the query part of the incoming request. The argument must be properly percent-encoded, if it contains whitespace or other non-printable characters.

QueryParam "name" [options] "pattern"

Match the value of the query parameter name.

StringMatch "string" [options] "pattern"

Expand string as described in String expansion (see below) and match the resulting value against pattern.

URL [options] "pattern"

Match the URL of the incoming request. By default, pattern is treated as case-sensitive extended regular expression. This can be changed by options, described below.

The options argument in the above directives can be used to select the comparison method. It consists of zero or more option flags from the following list:

−re

Use regular expression matching.

−exact

Use exact string matching.

−beg

Exact match at the beginning of string (prefix match).

−end

Exact match at the end of string (suffix match).

−case

Case-sensitive comparison.

−icase

Case-insensitive comparison.

−file

Treat pattern as the name of a file to read patterns from. If the name is relative, it will be looked up in the include directory (see the discussion of the IncludeDir directory above). Patterns are read from the file line by line. Leading and trailing whitespace is removed. Empty lines and comments (lines starting with #) are ignored.

For example, the following will match any request whose Host header begins with "www." (case-insensitive):

Host -icase -beg "www."

Compatibility directives

The following directives are provided for backward compatibility with older versions of pound. They will be removed in future versions.
HeadRequire
"pattern"

Same as Header.

HeadDeny "pattern"

A shortcut for

Not header "pattern"

In other words: the request may not contain any header matching the given pattern. See the Negation section, below.

Negation

Prefixing any of the directives discussed above with not will revert the sense of comparison. For example,

Not url "ˆ/static/"

will match any request, whose URL does not begin with "/static/".

Negating compound statements is allowed as well, e.g.:

Not ACL
"192.0.2.0/26"
"203.0.113.0/24"
End

Match statement

A Match statement allows you to group matching directives using arbitrary boolean operations. The syntax is:

Match OP
directives
...
End

where OP is AND to use boolean and, and OR (case-insensitive) to use boolean or, and directives stand for any number of matching directives discussed above (including the Match directive).

Prefixing Match directive with a word not reverts its result.

Match directives can be nested to any depth.

Technically, an implicit Match AND block is created around unenclosed matching directives on the top level of a Service block.

Modification directives

The following directives modify the incoming request prior to passing it to the selected backend. These are discussed in detail in the section REQUEST MODIFICATION, below.
DeleteHeader
"header: pattern"

Remove matching headers from the incoming requests.

SetHeader "header: value"

Add the defined header to the request passed to the backend server.

SetURL "value"

Sets the URL part of the request.

SetPath "value"

Sets the path part.

SetQuery "value"

Sets the query part.

SetQueryParam "name" "value"

Modifies the query. Sets the query parameter name to value.

Rewrite [request|response] ... [ Else ... ] End

Conditionally modify request or response depending on whether it matches certain conditions. If the argument is omitted, request is assumed.

Request modification is described in detail in section REQUEST MODIFICATION DIRECTIVES .

Response modification is covered by section RESPONSE MODIFICATION.

Backend definitions

Balancer random | iwrr

Defines the load-balancing strategy to use. Possible arguments are: random, to use weighted random balancing algorithm. an iwrr, meaning interleaved weighted round robin balancing. See REQUEST BALANCING, above, for a detailed discussion of these balancing strategies.

This directive overrides the Balancer directive in global scope.

Backend

Directives enclosed between Backend and the following End directives define a single backend server (see below for details). You may define multiple backends per service, in which case pound will attempt to load-balance between them.

Redirect [code] "url"

This is a special type of backend. Instead of sending the request to a backend pound replies immediately with a redirection to the given URL.

It is allowed to define multiple redirectors in a service, as well as mixing them with regular backends, but there is little if any justification for such usage, so it is deprecated.

Optional code can be one of: 301, 302 (the default), 303, 307, or 308.

The redirection destination is determined by the actual url you specify. It is expanded as described in String expansion above.

For compatibility with previous pound versions, if no $N references are found in url, the following logic is used: if it is a "pure" host (i.e. with no path) then the client will be redirected to the host you specified, with the original request path appended. If your url does contain a path, then the request path is ignored.

Examples: the following swaps the first two path components of the original URL:

Service
Host -re "(.+)"
URL "ˆ/([ˆ/]+)/([ˆ/]+)(/.*)?"
Redirect "http://$0(1)/$2/$1$3"
End

Notice the use of Host to supply hostname part for the redirect.

Using request accessors, the above example can be rewritten as:

Service
URL "ˆ/([ˆ/]+)/([ˆ/]+)(/.*)?"
Redirect "http://%[header host]/$2/$1$3"
End

Compatibility syntax: if you specified

Redirect "http://abc.example"

and the client requested http://xyz/a/b/c then it will be redirected to http://abc.example/a/b/c, but if you specified

Redirect "http://abc.example/index.html"

it will be sent to http://abc.example/index.html.

Error STATUS [FILE]

Special case of backend that returns HTTP error page. The STATUS argument supplies HTTP status code. Optional FILE argument is the name of a disk file with the error page content (HTML). If not supplied, the text is determined as usual: first the ErrSTATUS statement for the enclosing listener is consulted. If it is not present, the default error page is used.

The Error directive is useful in a catch-all service, which outputs an error page if no service matching the incoming request was found. See the EXAMPLES section for details.

Emergency

Directives enclosed between Emergency and the following End directives define an emergency backend server (see below for details). You may define only one emergency server per service, which pound will attempt to use if all backends are down.

Metrics

Special backend type that implements Openmetrics protocol output. See the section Metrics below for a detailed discussion.

Session

Directives enclosed between Session and the following End directives define a session-tracking mechanism for the current service. See below for details.

Other directives

IgnoreCase bool

Override the global IgnoreCase setting.

This statement is deprecated and will be removed in future versions. Please, use the −icase option to the URL directive instead. See the discussion of options in Service Matching Directives section above.

Disabled bool

Start pound with this service disabled (true) or enabled (false). If started as disabled, the service can be later enabled with poundctl(8).

ForwardedHeader name

Defines the name of the HTTP header that carries the list of proxies the request has passed through. It is used to report the originator IP address when logging. See the description of %a specifier in REQUEST LOGGING. This statement overrides the ForwardedHeader directive from the listener scope.

The default is X−Forwarded−For.

TrustedIP

Defines a list of trusted proxy IP addresses, which is used to determine the originator IP. See the description of %a specifier in REQUEST LOGGING, for a detailed discussion.

This statement overrides the TrustedIP directive from the listener scope.

LogSuppress class

Suppresses HTTP logging for requests that resulted in status codes from the specified class. Valid status classes are:
info
or 1

1xx response codes.

success or 2

2xx response codes.

redirect or 3

3xx response codes.

clterr or 4

4xx response codes.

srverr or 5

5xx response codes.

all

All response codes.

Multiple arguments are allowed.

This statement is designed for services that receive a constant stream of similar HTTP requests from a controlled set of IP addresses, such as e.g. Openmetric services. See the Metric section below for an example.

ACME

This statement creates a service specially crafted for answering ACME HTTP-01 challenge requests (see https://letsencrypt.org/docs/challenge-types/#http-01-challenge). It takes a single argument specifying a directory where ACME challenges are stored. The argument is subject to string expansion (see the subsection String expansion, above).

It is supposed that another program is started periodically, which checks for certificates approaching their expiration, issues renewal requests and stores the obtained ACME challenges in that directory.

Backend

A backend is a definition of a single backend server pound will use to reply to incoming requests. Backends are defined via a Backend statement. There are two forms of this statement: service-specific and global (or named) backend. These will be discussed later in this section. All configuration directives enclosed between Backend and End are specific to a single backend.

The following directives are available:
Address
address

The address that pound will connect to. This can be a numeric IP address, a symbolic host name that must be resolvable at run-time, or a full pathname of a UNIX socket. If the name cannot be resolved to a valid address, pound will assume that it represents the path for a Unix-domain socket. This is a mandatory parameter.

Port port

The port number or service name that pound will connect to. This is a mandatory parameter for non Unix-domain backends.

HTTPS

The backend is using HTTPS.

Cert "filename"

Specify the certificate that pound will use as a client. The filename is the file containing the certificate, possibly a certificate chain and the signature. This directive may appear only after the HTTPS directive.

Disable SSLv2|SSLv3|TLSv1|TLSv1_1|TLSv1_2

Disable the protocol and all lower protocols as well. This is due to a limitation in OpenSSL, which does not support disabling a single protocol. For example, Disable TLSv1 would disable SSLv2, SSLv3 and TLSv1, thus allowing only TLSv1_1 and TLSv1_2. This directive may appear only after the HTTPS directive.

Ciphers "cipherlist"

This 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). This directive may appear only after the HTTPS directive.

Priority n

The priority of this backend (between 1 and 9, 5 is default). Higher priority backends will be used more often than lower priority ones, so you should define higher priorities for more capable servers.

TimeOut n

Override the global TimeOut value.

ConnTO n

Override the global ConnTO value.

WSTimeOut n

Override the global WSTimeOut value.

Disabled bool

Start pound with this backend disabled (1) or enabled (0). If started as disabled, the backend can be later enabled with poundctl(8).

Global and per-service backends

A Backend definition can appear as a part of the service, i.e. in a Service section. or globally. In the latter case, the Backend keyword must be followed by a symbolic name assigned to this backend, e.g.:

Backend "name"
...
End

This name must uniquely identify the backend among other globally defined backends. A global backend is attached to a service using the UseBackend statement. It takes the symbolic name of the backend as its argument. The statement

UseBackend "name"

has essentially the same effect as if full backend definition appeared instead of it in this place. A substantial difference between the use of service-specific and global backends is that a single global backend can be used in multiple services. In a way, UseBackend statement expands to a backend definition within the service.

Furthermore, you can also adjust the Priority and Disabled parameters of the global backend definition for use in a particular service. To do so, use the following syntax:

Backend "name"
Priority 3
Disabled no
End

In this form, the Backend statement acts as UseBackend. Two directives can appear within such Backend statement: Priority, and Disabled. They override the settings defined in the global backend "name".

Notice, that in spite of their similarity, the two named forms of the Backend statement serve different purposes: when used in global scope, a named Backend defines a backend for further use in various services, and when used within a service, it creates a copy of the backend defined elsewhere and attaches it to this service.

The actual global definition may appear before as well as after service or services it is used in.

Emergency

The emergency server will be used once all existing backends are "dead". All configuration directives enclosed between Emergency and End are specific to a single service. The following directives are available:
Address
address

The address that pound will connect to. This can be a numeric IP address, or a symbolic host name that must be resolvable at run-time. If the name cannot be resolved to a valid address, pound will assume that it represents the path for a Unix-domain socket. This is a mandatory parameter.

Port port

The port number that pound will connect to. This is a mandatory parameter for non Unix-domain backends.

Additionally, the following directives are also supported: TimeOut, WSTimeOut, ConnTO, HTTPS, Cert, Ciphers, Disable. These have the same meaning as in the Backend section, which see.

Session

Defines how a service deals with possible HTTP sessions. All configuration directives enclosed between Session and End are specific to a single service. Once a session is identified, pound will attempt to send all requests within that session to the same backend server.

The following directives are available:
Type
IP|BASIC|URL|PARM|COOKIE|HEADER

What kind of sessions are we looking for: IP (the client address), BASIC (basic authentication), URL (a request parameter), PARM (a URI parameter), COOKIE (a certain cookie), or HEADER (a certain request header). This is a mandatory parameter.

TTL n

How long can a session be idle (in seconds). A session that has been idle for longer than the specified number of seconds will be discarded. This is a mandatory parameter.

ID "name"

The session identifier. This directive is permitted only for sessions of type URL (the name of the request parameter we need to track), COOKIE (the name of the cookie) and HEADER (the header name).

See below for some examples.

Metrics

The following service definition enables Openmetric telemetry output on endpoint /metrics:

Service
URL "/metrics"
Metrics
End

To control access to the telemetry endpoint, use the ACL statement.

The LogSuppress directive can be used in openmetric services to suppress logging of served HTTP requests.

For example:

Service
URL "/metrics"
Metrics
ACL "secure"
LogSuppress success
End

The metrics output is sufficiently self-documented by # HELP descriptor lines.

HIGH-AVAILABILITY

Pound attempts to keep track of active backend 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 initiated 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 resurrected servers at the earliest possible time. The default value of 30 seconds is probably a good choice.

The clients that happen to hit a dead backend server will just receive a 503 Service Unavailable message.

REQUEST MODIFICATION DIRECTIVES

Several statements are provided to modify the incoming requests prior to passing them to the backend. These statements can be present both in ListenHTTP (ListenHTTPS) and in Service sections.

Basic request modification directives are:
SetURL
"value"

Set the URL of the incoming request to value.

SetPath "value"

Set the path part of the URL to the given string.

SetQuery "value"

Set the query part of the URL to the given string. value must be a valid query with the special characters properly encoded using percent encoding.

SetQueryParam "name" "value"

Set the query parameter name to the value. Value must be properly encoded if it contains reserved characters.

SetHeader "name: value"

Sets the HTTP header. If the header name already exists, it will be overwritten. Otherwise, new header will be added to the end of the header list.

DeleteHeader [options] "pattern"

Remove from the request all headers matching pattern. By default, pattern is treated as extended POSIX regular expression. One or more options can be supplied to modify the default behavior. The options argument in the above directives can be used to select the comparison method. It consists of zero or more option flags from the following list:

−re

Use regular expression matching.

−exact

Use exact string matching.

−beg

Exact match at the beginning of string (prefix match).

−end

Exact match at the end of string (suffix match).

−case

Case-sensitive comparison.

−icase

Case-insensitive comparison.

The value argument in the above directives is subject to string expansion. Refer to subsection String expansions, for details.

The Rewrite block statement is used to associate one or more of the above directives with request matching directives (discussed in the subsection Service Matching Directives above), so that request modification takes place only when the request matches certain conditions.

Syntactically, a Rewrite block is:

Rewrite [request]
.
.
.
Else

.
.
.
End

where dots stand for any number of request matching and request modification statements. The Else part is optional; any number of Else blocks can be supplied, thus providing for conditional branching. The following concocted example illustrates it:

Rewrite
Path "\.(jpg|gif)$"
SetPath "/images%[path]"
Else
Match AND
Host "example.org"
Path "\.[ˆ.]+$"
End
SetPath "/static%[path]"
Else
Path "\.[ˆ.]+$"
SetPath "/assets%[path]"
End

Here, if a path ends with a filename with suffix ".jpg" or ".gif", "/images" is prepended to it (notice that path always starts with a slash, hence it should not be used explicitly). If the path ends with any other extension, the action depends on the host being addressed. The path is prefixed with "/static" if the host is "example.org", and with "/assets" otherwise.

To illustrate the effects of string expansion, here’s the the above example rewritten using backreference expansion instead of request accessors:

Rewrite
Path ".*\.(jpg|gif)$"
SetPath "/images$0"
Else
Match AND
Host "example.org"
Path ".*\.[ˆ.]+$"
End
SetPath "/static$0"
Else
Path ".*\.[ˆ.]+$"
SetPath "/assets$0"
End

Request modification directives are applied in the same order as they appear in the configuration file.

BUILT-IN HEADERS

In addition to the SetHeader and DeleteHeader directives discussed above, the HeaderOption directive controls insertion of the built-in headers:
HeaderOption
opt...

There are two kinds of such headers: forwarded headers that convey information about original destination of the request, and ssl headers (for HTTPS connections), that hold information about server and client SSL certificates. These are discussed in detail below.

By default, both kinds of built-in additional headers are enabled. This default can be changed by using the HeaderOption directive. Placed in global scope, this directive sets global options. Used within a ListenHTTP or ListenHTTPS block, it affects only settings for that listener.

The opt values passed to the directive are:

none

Disable both kinds of additional headers.

forwarded

Enable forwarded headers.

no−forwarded

Disable forwarded headers.

ssl

Enable ssl headers.

no−ssl

Disable ssl headers.

The built-in headers are added before request modification directives are applied. Thus, you can use DeleteHeader and SetHeader to trim down headers added by HeaderOptions.

Forwarded Headers

The headers in the forwarded header group are:
X−Forwarded−For

The IP address of the HTTP client that sent the request,

X−Forwarded−Proto

The protocol (http or https) that the client used to connect to pound.

X−Forwarded−Port

Destination port that the client used to connect to pound.

HTTPS Headers

If a client browser connects to pound via HTTPS and the ssl header group is enabled, then the following header is added:
X−SSL−Cipher

Contains SSL version followed by a slash and active cipher algorithm.

Additionally, if the client presented its certificate, the following headers are added that describe the client certificate:
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−Certificate

The full client certificate (PEM-format multi-line)

RESPONSE MODIFICATION

Headers in the response obtained from a regular backend or generated with a Error backend can be modified before sending them back to the requesting server. A special form of the Rewrite directive is provided for this purpose:

Rewrite response
.
.
.
Else

.
.
.
End

where dots stand for any number of response matching and modification statements. The Else part is optional; any number of Else blocks can be supplied, thus providing for conditional branching.

This directive can be used in ListenHTTP, ListenHTTPS, and Service definitions.

Response matching statements are:
Header
[options] "pattern"

Matches if the response contains at least one header matching the given pattern.

StringMatch "string" [options] "pattern"

Expand string as described in String expansion (see below) and match the resulting value against pattern.

By default, pattern is treated as case-insensitive extended regular expression. This can be changed by options, as described in section Service Matching Directives, above.

Match

The Match statement is as described in section Match statement, except that only directives described above are allowed within it.

Not

Placed before any of the above directives, reverts its result.

Following response modification statements are defined:
DeleteHeader
"header: pattern"

Remove matching headers from the response.

SetHeader "header: value"

Add header to the response. Argument undergoes string expansion as described above. The expanded value must be a valid header line.

BASIC AUTHENTICATION

To limit access to a service or services to certain authenticated users, use a combination of BasicAuth matching and response modification.

The BasicAuth matching directive evaluates to true, if the incoming request contains Authorization header with scheme "Basic", such that user name and password obtained from it match a line in the given disk file. The file must be a plain-text file created with htpasswd(1) or similar utility, i.e. each non-empty line of it must contain username and password hash separated by a colon. Password hash can be one of:

1.

Password in plain text.

2.

Hash created by the system crypt(3) function.

3.

Password hashed using SHA1 algorithm and encoded in base64. This hash must be prefixed by {SHA}.

4.

Apache-style apr1 hash.

Combined with the response rewriting described above, this can be used to implement basic HTTP authentication in Pound as shown in the following example:

Service "auth"
Not BasicAuth "/etc/pound/htpass"
Rewrite response
SetHeader "WWW-Authenticate: Basic realm=\"Restricted access\""
End
Error 401
End

Placing this service definition before others ensures that services defined below it will be tried only if the incoming request passes basic authentication.

REQUEST LOGGING

Logging of HTTP requests and responses is controlled by LogLevel directive. This directive can appear either in global scope, in which case it affects all listeners defined below it, or in listener scope, in which case it affects only this listener, overriding the global setting.

Argument to the LogLevel directive can be either an integer number in range 0 through 5 (inclusive), or a quoted string. Numeric value identifies one of the built-in log formats, described later in this section. String value refers either to a built-in format name, or to a user-defined format name. In the latter case, the named format must be defined earlier using the LogFormat statement.

Format specification

The syntax of the LogFormat statement is:

LogFormat "name" "format_string"

First argument, name, is a unique identifier for this format, which will be used later to refer to it. Format_string is a character string composed of ordinary characters (not %), which are copied unchanged to the resulting log message, and conversion specifications, each of which are replaced by a corresponding piece of information about the request or reply.

Conversion specifications are single characters prefixed with a percent sign. Depending on the specification, an optional conversion argument in curly brackets may appear between % and conversion character.

The following conversion characters are defined:

%%

Replaced with the percent sign.

%a

Originator IP address of the request. If the request contains the X−Forwarded−For header and TrustedIP ACL is defined, the value of the header is consulted to obtain the IP address. The value must be a comma-delimited list of intermediate useragent IP addresses. To determine the actual useragent IP, the list is traversed from right to left, until an IP is found that is not listed in TrustedIP ACL.

If X−Forwarded−For header is not present, or TrustedIP is not defined, or the above algorithm does not return an IP address, %a expands to the actual remote IP address the request came from (same as %h).

The TrustedIP ACL can be defined in global scope, or in ListenHTTP (ListenHTTPS) section, or in Service section. Most-specific ACL overrides least-specific ones, that is TrustedIP defined in Service will be used, if it is defined. If not, the one defined in listener will be used, etc. The syntax of the TrustedIP statement is the same as that of ACL, i.e.

TrustedIP "name"

refers to the named ACL name (which must be defined earlier), and

TrustedIP
"CIDR0"
"CIDR1"
...
End

defines the list of trusted IPs in place.

ForwardedHeader statement defines the name of the header to use instead of X−Forwarded−For. As TrustedIP, this statement can appear in global, listener, or in service scope.

%A

Local IP address of the listener.

%B

Size of response in bytes, excluding headers.

%b

Same as %B, but in CLF format, i.e. a dash is used when response size is zero.

%D

The time taken to serve the request, in microseconds.

%h

Client IP address of the request.

%H

The request protocol.

%{VARNAME}i

The contents of VARNAME: header line in the request. Changes made by header modification directives affect this.

%{VARNAME}I

Same as %i, except that if no such header is present in the request, a dash is substituted.

%{OBJNAME}L

Location of the Pound object that is involved in handling the request. Valid values for OBJNAME are: listener, service, and backend. The location gives position in the configuration file where the object was defined, and is formatted as

NAME:LN1.COL1-LN2.COL2

where NAME is the configuration file name, LN1 and COL1 are number of line and column where the object definition begins, and LN2 and COL2 are number of line and column where it ends. Line and column numbers start with 1.

%m

The request method.

%{OBJNAME}N

Name of the Pound object that is involved in handling the request. Valid values for OBJNAME are: listener, service, and backend.

%P

Thread ID of the serving thread.

%q

The query string prepended with a ? if it exists, otherwise an empty string.

%r

First line of request.

%s

Response status code.

%>s

First line of the response.

%t

Time the request was received, in the format [18/Sep/2011:19:18:28 -0400]. The last number indicates the timezone offset from UTC.

%{format}t

Time the request was received, in the format specified by the argument (strftime(3)). If the format starts with begin: (default) the time is taken at the beginning of the request processing. If it starts with end: it is the time after the response from the backend has been sent back to the requester. In addition to strftime(3) formats, the following specifications are recognized:

sec

Number of seconds since the Epoch.

msec

Number of milliseconds since the Epoch.

usec

Number of microseconds since the Epoch.

msec_frac

Millisecond fraction of the time.

usec_frac

Microsecond fraction of the time.

%T

The time taken to process the request, in seconds.

%{UNIT}T

The time taken to process the request, in a time unit given by UNIT. Valid units are ms for milliseconds, us for microseconds, s for seconds, and f for seconds with fractional part. Using s gives the same result as %T without any format; using us gives the same result as %D.

%u

Remote user if the request was authenticated.

%U

The URL path requested. This is affected by request modification directives.

%v

The listener name.

Built-in formats

There are five built-in formats. These can be identified either by their numeric index in the format table, or by symbolic name. The table below describes each built-in format using the format specification string:
0
, null

No request logging at all.

1, regular

"%a %r − %>s"

2, extended

"%a %r − %>s (%{Host}i/%{service}N −> %{backend}N) %{f}T sec"

3, vhost_combined

(Split in two lines for readability)
"%{Host}I %a - %u %t \"%r\" %s %b \"%{Referer}i\" \
\"%{User−Agent}i\""

4, combined

"%a − %u %t \"%r\" %s %b \"%{Referer}i\" \"%{User−Agent}i\""

5, detailed

(Split in two lines for readability)
"%{Host}I %a - %u %t \"%r\" %s %b \"%{Referer}i\" \
\"%{User−Agent}\" (%{service}N −> %{backend}N) %{f}T sec"

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 sanitize all HTTP/HTTPS requests: the request itself, the headers and the contents are checked for conformance to the RFCs and only valid requests are passed to the backend 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.

DEPRECATED FEATURES

Configuration statements

The following configuration statements are retained for backward compatibility with earlier pound versions. They will disappear from future releases:
HeadRequire

Use Header instead. See Service Matching Directives, for details.

HeadDeny

Use Not Header. For details, see the Negation subsection in Service Matching Directives.

AddHeader and HeaderAdd

Use SetHeader instead. See the section REQUEST MODIFICATION DIRECTIVES, for details.

IgnoreCase

Use the −icase option to the URL directive instead. See the discussion of options in the Service Matching Directives section.

Redirect request hack

The use of the redirect request hack in the Redirect statement is deprecated as well. Instead of relying on the trailing slash to append the original URL to the redirect location, use URL backreferences. For example, instead of

Redirect "http://example.org/"

use:

URL ".*"
Redirect "http://example.org$0"

Multiple redirect backends

Use of multiple Redirect backends in a single service is deprecated, as well as using Redirect backends together with regular ones. If you know of any valid usage for such configuration, please drop a note to the authors (see REPORTING BUGS, below).

ADDITIONAL NOTES

Pound uses the system log for messages (default facility LOG_DAEMON). If using rsyslog, you can use the following configuration fragment to redirect pound messages to a separate file:

:programname, startswith, "pound" {
/var/log/pound.log
stop
}

The format requested by LogLevel 3 is understood by most log analyzers.

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. Pound tries to handle this by adding various X−Forwarded−* and X−SSL−* headers. See HEADER MODIFICATION above, for a detailed discussion.

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 backend 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 needs a functioning resolver of some kind (be it /etc/hosts, DNS or something else). However, the use of DNS can be disabled using the −W no−dns command line option.

EXAMPLES

To translate HTTPS requests to a local HTTP server (assuming your network address is 192.0.2.1):

ListenHTTPS
Address 192.0.2.1
Port 443
Cert "/etc/pound/server.pem"
Service
Backend
Address 127.0.0.1
Port 80
End
End
End

To distribute the HTTP/HTTPS requests to three Web servers, where the third one is a newer and faster machine:

ListenHTTP
Address 192.0.2.1
Port 80
End

ListenHTTPS
Address 192.0.2.1
Port 443
Cert "/etc/pound/server.pem"
End

Service
Backend
Address 192.168.0.10
Port 80
End

Backend
Address 192.168.0.11
Port 80
End

Backend
Address 192.168.0.12
Port 80
Priority 3
End
End

To separate between image requests and other Web content and send all requests for a specific URL to a secure server:

ListenHTTP
Address 192.0.2.1
Port 80
End

# Images server(s)
Service
URL ".*.(jpg|gif)"
Backend
Address 192.168.0.12
Port 80
End
End

# redirect all requests for /forbidden

Service
Url -beg "/forbidden"
Redirect "https://xyzzy.com"
End

# Catch-all server(s)
Service
Backend
Address 192.168.0.10
Port 80
End

Backend
Address 192.168.0.11
Port 80
End

Session
Type BASIC
TTL 300
End
End

Here is a more complex example: assume your static images (GIF/JPEG) are to be served from a single backend 192.168.0.10. In addition, 192.168.0.11 is to do the hosting for www.myserver.com with URL-based sessions. Two backends, 192.168.0.20 and 192.168.0.21, will handle the rest of requests (cookie-based sessions). Among these, the latter (192.168.0.21) is less powerful than the former, so care should be taken that it gets less requests. The logging will be done by backend servers. All plain HTTP requests are to be redirected to HTTPS and all requests directed to myserver.com - to www.myserver.com. The configuration file may look like this:

User "nobody"
Group "nogroup"
RootJail "/var/pound/jail"
Alive 60
LogLevel 0

# HTTP: redirect all requests to the corresponding HTTPS server.
ListenHTTP
Address 192.0.2.1
Port 80
Client 10
Service
Host -re ".+"
URL ".*"
Redirect 301 "https://$0(1)$0"
End
End

ListenHTTPS
Address 192.0.2.1
Port 443
Cert "/etc/pound/pound.pem"
Client 20
End

# Image server
Service
URL ".*.(jpg|gif)"
Backend
Address 192.168.0.10
Port 80
End
End

# Virtual host www.myserver.com
Service
URL ".*sessid=.*"
Host "www.myserver.com"
Backend
Address 192.168.0.11
Port 80
End

Session
Type URL
ID "sessid"
TTL 120
End
End

# Virtual host myserver.com - redirects to www.
Service
Host "myserver.com"
URL ".*"
Redirect 301 "https://www.myserver.com$0"
End

# Virtual host server1.com and www.server1.com
Service
Host -re "ˆ(www.)?server1.com$"
Backend
Address 192.168.0.20
Port 80
Priority 5
End

Backend
Address 192.168.0.21
Port 80
Priority 4
End

Session
Type COOKIE
ID "userid"
TTL 180
End
End

# Return custom error page if no matching service was found.
Service
Error 404 "/var/lib/pound/notfound.html"
End

FILES

/var/run/pound.pid

This is where pound will attempt to record its process id. The exact location is determined at compile time by the value of the −−localstatedir configuration switch. It can be changed at runtime using the −p command line option. Use pound −V to inspect the actual default.

/etc/pound.cfg

The default configuration file. The exact location is determined at compile time by the value of the −−sysconfdir configuration switch. It can be changed at runtime using the −f command line option. Use pound −V to inspect the actual default.

/usr/local/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), and Sergey Poznyakoff.

REPORTING BUGS

Report bugs to <[email protected]>. You may also use github issue tracker at https://github.com/graygnuorg/pound/issues.

COPYRIGHT

Copyright © 2002-2010 Apsis GmbH.
Copyright © 2018-2023 Sergey Poznyakoff

License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>

This is free software: you are free to change and redistribute it. There is NO WARRANTY, to the extent permitted by law.


Updated 2024-01-29 - jenkler.se | uex.se