Skip to content

Releases: graygnuorg/pound

Version 4.16

13 Jan 07:56
v4.16
Compare
Choose a tag to compare

A bug fixing release. Noteworthy changes:

  • Fix backend probing when compiled without support for dynamic backends.

  • Reject requests with oversized chunk bodies.

  • Handle errors that occur during evaluation of conditionals.

Version 4.15

17 Nov 13:17
v4.15
Compare
Choose a tag to compare

Noteworthy changes in this release

  • New configuration statement: IgnoreSRVWeight

    Instructs pound to ignore weight value of an SRV record when generating new backend from it. Priority of the generated backend will be copied from its matrix backend.

  • New configuration statement: OverrideTTL

    When used with dynamic backends, instructs pound to use its argument rather than the TTL value returned in DNS response, to calculate the expiration time of the new backend.

  • Load balancing code revisited

    Removed arbitrary limit on backend priority value. The allowed range is now 1..65535.
    Remove priority mapping for SRV-generated backends. SRV weights are assigned to backend priorities verbatim.

  • Fix access to freed memory in session handling code.

    1. Improve testsuite
    2. Check for missing perl modules and skip tests if needed.
    3. DNS-based tests are disabled by default, due to their experimental nature. Use --enable-dns-tests to enable them.
    4. The poundharness.pl script runs a self-test when invoked with the --fakedns option, to avoid spurious test failures.

Version 4.14

13 Oct 09:51
v4.14
Compare
Choose a tag to compare

Dynamic backends

Dynamic backends are created and updated on the fly based on the information from DNS. To declare backend as dynamic, use a symbolic host name in its Address statement and add the Resolve statement with one of the following values:

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

  • all
    Resolve the symbolic host name 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 regular backends. Each record produces new dynamic backend of Resolve all type, which creates 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 determines the balancing group (see below) where the backend will be hosted.

By default, both IPv4 and IPv6 addresses are looked for. You can select the specific address family using the Family statement. Its allowed values are:

  • any
    Use all address families available. This is the default.
  • inet
    Use only IPv4 addresses.
  • inet6
    Use only IPv6 addresses.

For example:

  Backend
      Address "be0.example.net"
      Port 8080
      Resolve first
      Family inet
  End

Dynamic backends will be updated periodically, when the TTL of the corresponding DNS records expires. If the hostname cannot be resolved or a DNS failure occurs, next update will be scheduled in 600 seconds after the failure. This interval can be configured using the RetryInterval statement in the Backend section, or globally, in the Resolver section.

The Resolver section allows you to control how DNS lookups are performed. It can contain the following directives:

  • CNAMEChain integer
    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 occurs sometimes in the wild. By default, pound does not accept CNAME chains. If you work with a nameserver that uses them, set this statement to a small integer value, defining maximum number of CNAMEs in the chain that pound will accept. The value of 2 or 3 should suffice in most cases.

  • ConfigFile string
    Name of the resolver configuration file. Defaults to /etc/resolv.conf.

  • ConfigText
    This is a compound statement:

      ConfigText
         ...
      End 
    

    The material between ConfigText and End is read verbatim and used as the content of the resolver configuration file.

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

  • Debug boolean
    Whether to enable DNS debugging info.

  • RetryInterval integer
    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.

Dynamic backends can be controlled using poundctl. For example, consider the following output from poundctl list:

  1. Listener http://192.0.2.1:80 enabled
      0. Service active (5)
          0. matrix "be0.example.com" 2 0 active
          1. backend http 198.51.100.15:8081 5 alive active
	  2. backend http 203.0.113.121:8081 5 alive active
          3. backend http 192.0.2.203:8081 5 alive active

The backend 0 ("matrix") refers to the Backend statement in the configuration file that produced the other three dynamic backends. Disabling it (poundctl disable /1/0/0) causes the dynamic ones to be removed. Enabling it will create them again. In a pinch, this can be used to force backend re-creation prior to TTL expiration.

Compiling

To enable dynamic backend support, you will need the adns library. On debian-based systems, it is installed by the following command

  apt-get install libadns1-dev

If all preconditions necessary for enabling dynamic backends are met, the output from configure will end with the following status line:

  Dynamic backends .............................. yes
  *******************************************************************

When compiled with the dynamic backend support, the output of pound -V will contain the following line in the Built-in defaults section:

  Dynamic backends:           enabled

Backend groups

Backend groups are a new pound feature, that extends the idea of regular and emergency backends used in previous versions. Any number of backend groups can be associated with a service. Each group is assigned an integer number (weight). The groups are ordered by weight (in ascending order) and are tried in that order when looking for a backend to serve the request. The look up starts with the first group. The balancing algorithm configured for the service is applied. If no backend can be selected, next group will be tried, and so on.

In the static configuration, regular backends are hosted in backend group of weight 0 and emergency (high availability) backends are stored in group of weight 65535. One consequence of this is that any number of Emergency backend declarations are now allowed in a service. More backend groups can be allocated when using dynamic backends of srv resolve type (see above).

Emergency backends

Any number of emergency backends can be defined. Usual request balancing algorithm applies when selecting an emergency backend.

All statements valid within a Backend section are also valid within an emergency backend declaration.

Listener address configuration

Both Address and Port statements are now optional. If Address is omitted, pound will listen on all available interfaces. If Port is omitted (and not listening on a UNIX socket), default port number for this kind of listener will be used: 80, for ListenHTTP, and 443, for ListenHTTPS.

New request matching conditional: ClientCert

The syntax is:

   ClientCert "FILENAME"

The conditional evaluates to true if the client presented the certificate matching that from the given file (PEM format).

It cannot be used in standalone services (i.e. services that are defined in global scope). It also cannot be used if the ListenHTTPS section that hosts the service has the ClientCert statement of its own.

Remote access to the management interface

A new backend type Control is introduced to make it possible to access the management interface remotely. The example below shows how to configure pound to expose the management interface on http://192.0.2.1:3434:

  ListenHTTP
      Address 192.0.2.1
      Port 3434
      Service
          ACL "secure"
	  Control
      End
  End

poundctl

Changes in poundctl functionality reflect those in the management interface. First of all, the -s option accepts URL as its argument:

  poundctl -s https://user:password@hostname:8080/path

Additionally, the following new options are implemented:

  • -C FILE
    Load CA certificates from FILE. If FILE is a directory, all PEM files will be loaded from it.

  • -K FILE
    Load client certificate and key from FILE. During TLS handshake, send them to the peer for authentication.

  • -k
    Insecure mode: disable peer verification.

  • -S NAME
    Take settings for server NAME from the poundctl configuration file (see below).

.poundctl

The file .poundctl in user home directory provides configuration settings for the poundctl command. Syntactically, it is similar to pound.cfg. Upon startup, poundctl first checks if ~/.poundctl exists and reads it if so. If the program cannot determine the URL of the control socket from it (possibly using the argument to the -S option, if given), it scans the pound configuration file (if it exists), looking for Control statement. Finally, if neither method determines the URL, poundctl requires the user to supply the -s option.

The default name and location of the poundctl configuration file can be changed using the environment variable POUNDCTL_CONF. Setting it to empty string disables the configuration mechanism altogether.

configure

Removed historic --with-owner and --with-group options.

Version 4.13

24 Aug 11:51
Compare
Choose a tag to compare

Support for pcre and pcre2 rewritten

The pcre2posix (or pcreposix) layer is no longer used. Instead, pound uses the native API of the corresponding library. This provides for the additional speed-up and (in case of pcre2) avoids coredumps under high load.

Use of POSIX and Perl-compatible regular expressions

In contrast to previous versions, both types of regular expressions can be used simultaneously in the configuration file. The flavour of the regex to use can be specified either individually with each request matching statement (such as URL, Header, etc.), or globally.

To set it globally, use the RegexType statement. The type of regular expression set by it will be used in all matching statements that appear below that statement, unless they declare regex type explicitly. It remains in effect until next RegexType statement or end of file is encountered, whichever occurs first. For example, to use PCRE by default, add the following statement somewhere near the beginning of your pound.cfg file:

  RegexType pcre

To change the default back to POSIX regexps, do

  RegexType posix

Regular expression type can also be specified with each matching statement individually. For example, the -pcre option indicates that Perl-compatible regular expression is given as argument, e.g.:

  Host -pcre -icase "(?<!www\\.)example.org"

Similarly, the -posix option indicates that POSIX extended regular expression is used. Use these options to override the default for a single statement.

New matching option: -contain

The -contain option enables substring match. E.g. the following will match if URL contains the word "user" (case-insensitive):

  URL -contain -icase "user"

New configuration statement: LogTag

Sets a string to tag syslog messages with. By default, the name used to start the program is assumed.

Bugfixes

  • Fix infinite recursion on reporting an out of memory condition.
  • Fix deadlock in session expiration handling.
  • Fix RewriteLocation functionality.

v4.12

26 Apr 05:37
v4.12
Compare
Choose a tag to compare

Manual in texinfo format included

Change in the order of applying rewrites to responses

When rewriting a response, rules defined in the service section are applied first, followed by the ones defined in the listener.
When rewriting incoming requests, the order is opposite: first the rules in the listener, then the ones in the service.

Fixes in handling of Transfer-Encoding

  • Requests with unrecognized Transfer-Encoding are rejected
  • Requests containing both Transfer-Encoding and Content-Length are rejected

Deprecated configuration statements

Pound issues a warning for each deprecated statement used in the configuration file. The warning message contains a suggestion on what to use instead of the offending statement. You are advised to replace each occurrence of deprecated statements in accordance with these suggestions, since such statements will be removed in future releases.

If it is not feasible to do so for a while, you can suppress these messages by using the -W no-warn-deprecated command line option.

ServerName directive is allowed in the Emergency section

New configuration statement: ErrorFile

  ErrorFile NNN "FILENAME"

This statement defines content of the response page returned with the HTTP status NNN from the file FILENAME. It obsoletes the Err400 - Err503 statements used in previous versions. These statements are still supported for backward compatibility, although their use is discouraged.

New configuration statement: MaxURI

This statement sets the maximum allowed length of the request URI. It can be used in ListenHTTP and ListenHTTPS sections.

Bugfixes

  • Don't try to access the include directory, unless needed by configuration.
  • Fix handling of session deletion/addition on request from poundctl.

Version 4.11

03 Jan 15:29
v4.11
Compare
Choose a tag to compare

Combining 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 on incoming requests as well as on responses. To enable this feature, declare names of headers that can be combined using the CombineHeader statement, e.g.:

    CombineHeaders
	"Accept"
	"Allow"
	"Forwarded"
    End

Pound distribution includes file mvh.inc which declares all multiple-value headers in a form suitable for inclusion to the main
pound configuration file. This file is installed in the package data directory, which is normally /usr/local/share/pound or
/usr/share/pound, depending on the installation prefix used.

SNI in HTTPS backends

New directive ServerName is provided for use in Backend section after the HTTPS statement. This directive sets the host name to be used in server name identification (SNI). Its argument is a quoted string specifying the host name. This directive also rewrites the Host: header accordingly. Example usage:

    Backend
	HTTPS
	Address 192.0.2.1
	Port 443
	ServerName "www.example.org"
    End

Cert statement in ListenHTTPS section

Argument to the Cert statement in ListenHTTPS section can be the name of a directory containing certificate files. All files from that directory will be loaded.

Version 4.10

13 Oct 08:34
v4.10
Compare
Choose a tag to compare

Global Backend definitions

A Backend statement is allowed to appear in global scope. In this case it must be followed by a symbolic name, as in:

  Backend "name"
    ...
  End

The "name" must uniquely identify this backend among other backends defined in global scope.

Global backend definitions can be used in services using the UseBackend statement:

  UseBackend "name"

A single globally defined backend can be used in multiple services. Its actual global definition may appear before as well as after the service or services it is used in.

The named form of Backend statement is also allowed for use in Service sections. In this case it acts as UseBackend statement, except that statements between Backend and End modify parameters of the backend for use in this particular service. Only two statements are allowed in such named form: Priority and Disabled. The following example attaches the globally defined backend "assets" to the service and modifies its priority:

  Backend "assets"
    Priority 8
  End

Response header modification

The Rewrite statement accepts optional argument specifying whether it applies to the incoming request, or to the response. The following statement applies to requests and is exactly equivalent to Rewrite without argument:

  Rewrite request
    ...
  End

In contrast, the following statement:

  Rewrite response
    ...
  End

applies to responses (as received from regular backends or generated by error backends). In this form, the set of statements that can appear inside the section (denoted by ellipsis above) is limited to the following: Not, Match, Header, StringMatch, SetHeader, and DeleteHeader. For example:

  Rewrite response
    Match
      Header "Content-Type: text/(.*)"
    End
    SetHeader "X-Text-Type: $1"
  End

The same applies to Else branches.

Basic authentication

New request matching statement BasicAuth is implemented. Its syntax is:

  BasicAuth "FILE"

It evaluates to true, if the incoming request contains Authorization: header with scheme Basic, such that the user name and password obtained from it match a line in the given disk file. FILE must be a plain-text file created with htpasswd 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 technique described above, this can be used to implement basic HTTP authentication in pound as shown in the example below:

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

Unless file name starts with a slash, it is taken relative to the IncludeDir directory. The file is cached in memory on the first authorization attempt, so that further authorizations do not result in disk i/o operations. It will be rescanned if pound notices that the file's modification time has changed.

Bugfixes

  • The Host statement assumes exact match by default.
  • Fix detection of duplicate Transfer-Encoding headers.

Version 4.9

22 Aug 14:56
v4.9
Compare
Choose a tag to compare

HTTP request logging

In addition to six built-in log formats, you can define your own named formats and use them in LogLevel directive. Log formats are defined using the following statement:

  LogFormat "name" "FormatString"

The "name" argument specifies a string uniquely identifying this format. "FormatString" is the format specification. It is
modelled after Apache's LogFormat string. For example, the built-in format 3 is defined as:

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

The LogLevel directive has been extended to take symbolic format name as argument. For example:

  LogLevel "my_format"

The traditional built-in formats are assigned the following symbolic names:

  • 0 - "null"
  • 1 - "regular"
  • 2 - "extended"
  • 3 - "vhost_combined"
  • 4 - "combined"
  • 5 - "detailed"

So, instead of

  LogLevel 3

one may write

  LogLevel "vhost_combined"

New statements: ForwardedHeader and TrustedIP

These statements control how the %a log format conversion specifier determines the originator IP address:

  • ForwardedHeader "name"

    Defines the name of HTTP header that carries the list of proxies the request has passed through. It is used to report the originator IP address when logging.

    The default value is "X-Forwarded-For". This statement can be used in global, listener, and service scope.

  • TrustedIP

    Defines a list of trusted proxy IP addresses, which is used to determine the originator IP. This is a special form of the ACL
    statement and, as the latter, it can appear in two forms: directive and section.

    In directive form, it takes a single argument referring to a named access control list, which must have been defined previously using the ACL statement.

    In section form, it is followed by a list of one or more CIDRs each appearing on a separate line. The End directive on a separate line terminates the statement.

    This statement can be used in global, listener, and service scope.

New service statement: LogSuppress

Suppresses HTTP logs for requests that resulted in response status codes from a particular group or groups. The statement takes one or more arguments specifying status code groups to suppress log messages for:

  • info or 1

    1xx status codes

  • success or 2

    2xx status codes

  • redirect or 3

    3xx status codes

  • clterr or 4

    4xx status codes

  • srverr or 5

    5xx status codes

  • all

    all status codes

Suggested usage is for special services that are likely to process large numbers of similar requests, such as Openmetrics services. For example:

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

New request matching directive: StringMatch

The syntax is:

  StringMatch "SUBJECT" [OPTIONS] "PATTERN"

OPTIONS are usual matcher options. The directive matches if SUBJECT, after backreference expansion and accessor interpretation, matches PATTERN.

This directive allows you to build complex service selection criteria. For example:

  Service
      Host "^foobar\.(.+)$"
      StringMatch "$1" -file "domain.list"
      ...
  End

The service above will be used for requests whose Host header value is "foobar." followed by a domain name from the file "domain.list".

New request accessors: host and port

The %[host] accessor returns the hostname part of the Host header value. The %[port] accessor returns port number with leading column character. If no explicit port number is given in the Host value, %[port] returns empty string.

Bugfixes

  • Fix the QueryParam statement.
  • Improve testsuite and documentation.

Version 4.8

28 May 11:00
v4.8
Compare
Choose a tag to compare

Support for libpcre2-posix

The configure script checks for both libpcreposix2 and legacy libpcreposix. Version 2 is preferred, if available. To force compiling with the older libpcreposix, use --enable-pcreposix=pcre1.

Bugfixes

  • Fix coredump on -c -v
  • poundctl: ignore empty lines in pound.cfg

v4.7

17 Apr 16:50
v4.7
Compare
Choose a tag to compare

Default include directory

Configuration directives that take filenames as their argument search for files in the include directory (unless the filename is absolute). Initial value of the include directory is set to the system configuration directory, as configured at compile time. It can be changed:

  1. From the command line, using the -Winclude-dir=DIR or -Wno-include-dir options.
    The latter form resets it to the current working directory.
  2. From the configuration file, using the IncludeDir configuration statement.

The Include directive

The Include directive can appear not only at the topmost level, but also in any sections (ListenHTTP, Service, ACL, etc.). In short - anyplace where a statement is allowed.

Reading patterns from file

All request matching directives (Header, Host, URL, etc.) take an additional option -file. When this option is specified, the argument to the directive is treated as the name of a file to read patterns from. If the filename is relative, it is looked up in the include directory (see above). For example:

   Service
      Host -file "pound/webhosts"
      ...
   End

Patterns are read from the file line by line, empty lines and comments are ignored.

Early pthread_cancel probe

Pound calls pthread_cancel(3p) during its shutdown sequence. In GNU libc, a call to this function involves loading the libgcc_s.so.1 shared library. In previous versions of pound, this would fail if pound was running in chrooted environment (RootJail), unless that library had previously been copied to the chroot directory. The following diagnostics would be printed

   libgcc_s.so.1 must be installed for pthread_cancel to work

and the program would abort. That means that normal pound shutdown sequence would not be performed properly. Starting with this version, pound will create and cancel a dummy thread right before doing chroot. This ensures that libgcc_s.so.1 is loaded early, so that pthread_cancel will run successfully even when chrooted later.

This early probe is enabled if pound is linked with GNU libc. The --enable-pthread-cancel-probe configure option is available to forcefully enable or disable it, if the need be.

PID file and control socket are properly removed when in RootJail mode.

This doesn't cover the case where the privileges of the user the program runs at (as set by the User and Group configuration statements) forbid to remove the file.

Control socket ownership and mode

The Control configuration directive has two forms: inline and section. The inline form is the same as in previous versions. The Control section allows you to manage file mode and ownership of the socket file. Its syntax is:

  Control
    Socket "FILE"
    Mode OCTAL
    ChangeOwner BOOL
  End

The Socket statement sets the name of the UNIX socket file. This is the only mandatory statement in the Control section. The Mode statement sets the mode of the socket file (default is 600). Finally, if ChangeOwner is true, the ownership of the socket file will be changed to the user defined by the User and/or Group statements in global scope.