POUND(8)

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. Each backend is assigned a priority -- a positive number indicating its relative weight among other backends. 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.

Two balancing strategies are implemented:

Weighted Random Balancing
    This is the default strategy. 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.

Interleaved Weighted Round Robin Balancing
    This strategy cycles over all active backends, considering each one in its turn. An integer ordinal number is assigned to each round, which is incremented (modulo number of backends) each time a new round is started. A backend is assigned a request only if its priority is greater than the round number.

    This strategy offers several advantages compared with the previous one. First, it results in a more even distribution of the requests. Secondly, the resulting distribution is predictable.

Within each Service, multiple backends are grouped in balancer groups. Each such group is assigned a unique integer priority, which defines the order in which the groups are tried. When selecting a backend, a group with the numerically lesser priority is selected and a suitable backend is looked up among backends defined in the group, using one of the balancing strategies discussed above. If no backend can be selected (e.g. all backends are unavailable), next group is tried. The process continues until either a backend is chosen or the list of balancer groups is exhausted.

By default, backends declared using the Backend keyword are assigned to the balancer group 0. These are backends used during normal operation. Backends declared using the Emergency keyword are assigned to the balancer group 65535. These backends form a pull of high availability backends, which will be tried only if all of the normal backends fail.

More backend groups can be added using dynamic backends, discussed below.

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-]warn-deprecated
        Warn if any deprecated statements are used in configuration file.

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

LogTag "string"
    Sets the string to tag log messages with. This is used when log output goes to syslog. Default is the name with which pound was started.

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.

CombineHeaders ... End
    Declare names of the headers that can appear multiple times in a message, and that should be combined into one value. Header names must appear one per line between CombineHeaders and End.

    See the section MULTI-VALUE HEADERS, for a detailed discussion 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:

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

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

RegexType posix | pcre | perl
    Sets the type of regular expressions to use in request matching statements. posix selects POSIX extended regular expressions and pcre or perl select Perl-compatible regular expressions. The latter requires compile-time support. The selected regular expression type remains in effect until next RegexType statement or end of the configuration file, whichever occurs first.

  Control socket
Pound can be instructed to listen 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.

Usually, a UNIX socket is used to communicate with the management interface. It 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.

It is also possible to have pound listen for management requests on an INET or INET6 address. See below, the section Backend definitions, description of the Control statement.

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 full pathname of a UNIX socket. If neither this directive nor SocketFrom (see below) is given, ::0 is assumed.

Port port
    The port number or service name that pound will listen on. If not given, default port number is assumed, i.e. 80, for ListenHTTP, and 443, for ListenHTTPS (see below).

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.

ErrorFile NNN "filename"
    Read the content to be returned along with the HTTP status code NNN from the file filename. The file will be read exactly once, at the program startup.

    Allowed values for NNN are: 400, 401, 404, 405, 413, 414, 500, 501, 503.

ErrNNN "filename"
    This statement is equivalent to

        ErrorFile NNN "filename"

    It is provided for compatibility with previous versions of the program.

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.

MaxURI n
    Maximum allowed length of an URI. If the URI of a request is longer than n bytes, an error 414 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
    Backreference 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 a 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. Filename is either a certificate file name, or the name of a directory containing certificate files.

    Certificate file is a file containing the certificate, possibly a certificate chain and the signature for this server, in that order.

    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.

ClientCert "filename"
    Evaluates to true if the client presented the certificate matching that from the file filename (PEM format).

    This conditional cannot be used in standalone services (i.e. services that are defined in global scope), or if the ListenHTTPS section that hosts the service has the ClientCert statement on its own.

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:

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

-case
    Case-sensitive comparison.

-contain
    Match substring.

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

-exact
    Exact string match.

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

-icase
    Case-insensitive comparison.

-pcre or -perl
    Use Perl-compatible regular expression (requires compilation-time support). This overrides global RegexType settings.

-posix
    Use POSIX extended regular expression. This overrides global RegexType settings.

-re Use regular expression matching, as set by the RegexType statement.

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.

Control
    Enables a special control backend -- a management interface that returns information about the running pound server, makes it possible to change state of configured listeners, services and backends, and provides other management facilities. The management interface is discussed in detail in section Control socket, above. The Control backend provides remote access to this interface. Be careful to properly protect the control interface by use of HTTPS, ACLs and/or basic authorization, e.g.:

        ListenHTTPS
            Address 192.0.2.1
            Port 443
            Cert "/etc/ssl/priv/example.pem"
            Service
                Not BasicAuth "pound/htpasswd"
                Rewrite response
                    SetHeader "WWW-Authenticate: Basic realm=
                End
                Error 401
            End
            Service
                ACL "secure"
                Control
            End
        End

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 ErrorFile STATUS 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 any number of emergency servers. A backend will be selected from emergency backends if all regular 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.

ServerName "name"
    Specify the name to use for server name identification (SNI). This directive also rewrites the Host: header for this particular backend. This means you don't have to use SetHeader in addition to it.

    This directive may appear only after the HTTPS directive.

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. Higher priority backends will be used more often than lower priority ones, so you should define higher priorities for more capable servers. Exact scheduling and allowed values for this keyword depend on the load balancing strategy in use (see the section REQUEST BALANCING, above). For weighted random balancing, allowed values for Priority are between 0 and 9, inclusive. For interleaved weighted round robin balancing, allowed range is 0 to 65535, inclusive.

    Default value is 5.

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

  Dynamic backends
Dynamic backends are created and updated on the fly based on the information from DNS. A backend is declared as dynamic by the Resolve statement. Its value defines what type of DNS record is used to generate dynamic backends:

first
    Resolve the symbolic host name from the Address directive and use first IP from the DNS response as the address of the created dynamic backend. Thus, at most one dynamic backend will be produced.

all Resolve the symbolic host name from the Address directive and create one backend for each address from the DNS response. This enables load balancing between created backends. Each backend will be assigned the same priority.

srv Obtain SRV records for the host name and use them to generate backends. Each record produces new dynamic backend of the Resolve all type, which produces regular backends as described above. The weight field of the SRV record is mapped to the priority field of each generated backend. The SRV priority field identifies the balancer group where the backend will be hosted.

The following directives further configure dynamic backends:

Family any | inet | inet6
    Selects the family of the addresses to look for:

    any Use all address families available. This is the default.

    inet
        Use only IPv4 addresses (A DNS RRs).

    inet6
        Use only IPv6 addresses (AAAA DNS RRs).

IgnoreSRVWeight bool
    When using SRV records, ignore their weight fields and assign priorities for the generated backends from the priority of the producing backend. This directive is valid when used together with Resolve srv.

OverrideTTL N
    Query DNS each N seconds for possible changes in configuration of the existing dynamic backends. If this statement is not used, the TTL value returned with the DNS response will be used instead.

RetryInterval N
    Retry failed DNS queries each N seconds. Default is 600.

  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.

Resolver
The Resolver section controls DNS lookups for dynamic backend generation (see above). It can contain the following directives:

CNAMEChain N
    Maximum allowed length of a CNAME chain. CNAME chains are formed by DNS CNAME records pointing to another CNAME. Although prohibited by the RFC, such usage does occur sometimes. By default, pound does not accept CNAME chains. If you work with nameserver that returns them, set this statement to a small integer value, defining maximum number of CNAMEs in the chain that can be accepted. The value of 2 or 3 should suffice in most cases.

ConfigFile "FILE"
    Read the resolver configuration from FILE, instead of the default /etc/resolv.conf.

ConfigText ... End
    Alternative way to supply resolver configuration. The material within this section is read verbatim and used as the content of the resolver configuration file.

    If both ConfigFile and ConfigText are used, the last used statement wins.

debug bool
    Whether to enable DNS debugging info.

RetryInterval N
    Interval in seconds, after which to retry failed DNS queries or queries that returned no RRs. This value is used unless the backend defines its own retry interval value.

Emergency
Emergency servers will be used once all existing backends are "dead". All configuration directives enclosed between Emergency and End are specific to a single service. For the list of directives allowed for use in Emergency sections, refer to the description of Backend.

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. The options argument can be used to change this behavior. It consists of zero or more option flags from the following list:

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

    -case
        Case-sensitive comparison.

    -contain
        Match substring.

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

    -exact
        Use exact string matching.

    -icase
        Case-insensitive comparison.

    -pcre or -perl
        Use Perl-compatible regular expression (requires compilation-time support). This overrides global RegexType settings.

    -posix
        Use POSIX extended regular expression. This overrides global RegexType settings.

    -re Use regular expression matching, as set by the RegexType statement.

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 from ListenHTTP (or ListenHTTPS) section are applied first, followed by directives from the Service section. Directives appearing within a single section 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 modification directives from the Service section are applied first, followed by directives from the ListenHTTP (or ListenHTTPS) section. Directives appearing within a single section are applied in the same order as they appear in the configuration file.

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.

MULTI-VALUE HEADERS
HTTP protocol allows for certain headers to appear in the message multiple times. Namely, multiple headers with the same header name are permitted if that header field is defined as a comma-separated list. The standard specifies that such fields can be combined in a single header: value pair, by appending each subsequent field value to the previous one, each separated by a comma.

Pound is able to perform such combining both on incoming requests and on responses. To enable this feature, declare names of headers that can be combined using the CombineHeaders section statement. This statement must be followed by header names, each on a separate line, and terminated with an End statement. E.g.:

    CombineHeaders
        "Accept"
        "Allow"
        "Forwarded"
    End

You can also store header names in a file, and include that file after CombineHeaders, e.g.:

    CombineHeaders
        Include "multivalue.txt"
    End

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:

.   Password in plain text.

.   Hash created by the system crypt(3) function.

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

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

HeaderRemove and HeadRemove
    Use DeleteHeader 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.

ErrNNN
    (where NNN is one of: 400, 401, 403, 404, 413, 414, 500, 501, 503)

    Use the ErrorFile directive, described in the section HTTPListener, above.

  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 <gray@gnu.org>. You may also use github issue tracker at https://github.com/graygnuorg/pound/issues.

COPYRIGHT
Copyright © 2002-2010 Apsis GmbH.
Copyright © 2018-2025 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.