Release Notes
New and/or improved features in HAProxy Enterprise 2.4r1 include:
Enterprise Suite
Advanced WAF
ModSecurity WAF
- Global Profiling Engine
-
The Global Profiling Engine is a drop-in replacement for the Stick Table Aggregator, with the ability to aggregate stick table data from across a cluster of load balancers in real time. It can also aggregate historical data over a timespan. For example, you can store the average HTTP request rate over an entire day and then calculate statistics from it automatically, such as averages and percentiles, which enables you to alter rate limiting thresholds dynamically based on average traffic load at a given time of day. This simplifies the task of setting rate limit thresholds, making the experience more adaptive and turnkey.
- Improved reloading of map files
-
Map files now reload faster.
- Arm packages
-
Packages that target Arm processors on Ubuntu 20.04 were added.
Core
Protocol support
- HTTP/2 WebSockets
-
Support for the WebSocket protocol over HTTP/2 through the extended CONNECT HTTP method, which is outlined in RFC 8441, allows multiple WebSocket tunnels to share a single TCP connection.
- Financial Information eXchange (FIX)
-
HAProxy Enterprise can now accept, validate, and route FIX protocol messages. FIX is an open standard that has become the de facto protocol in the Fintech world. HAProxy Enterprise can also inspect tag values within the Logon message sent by the client, which you can use to make authorization and routing decisions using ACLs.
- MQTT
-
MQTT is a lightweight messaging protocol typically used for communicating with Internet of Things (IoT) devices. you can use the
mqtt_is_valid
converter to check whether the first message sent by the client (a CONNECT message) or by the server (a CONNACK message) is a valid MQTT packet. You can also read the fields in those initial messages to perform an authorization check and/or initialize session persistence to a server. Also, themqtt_field_value
converter reads a field from a CONNECT or CONNACK message.
Load Balancing
- DNS TCP resolution
-
The
resolvers
section now allows listing DNS servers over TCP, which supports larger DNS responses. HAProxy Enterprise will accept TCP responses as large as 65,535 bytes. Prefix the nameservers addresses withtcp@
. - Circuit breaking
-
New stick table counters named
http_fail_cnt
andhttp_fail_rate
track server-side, HTTP 5xx errors. You can use these in circuit breaking to disable a backend server if it returns too many errors.
SSL/TLS improvements
- Dynamic SSL Certificate Storage (Server side)
-
The Runtime API commands
show ssl cert
,set ssl cert
, andcommit ssl cert
can now be applied to certificates referenced byserver
lines in a backend. You can now also take advantage ofssl-load-extra-files
andssl-load-extra-del-ext
directives in your backend section to allow storing your certificate’s private key in a separate file from the certificate itself. - Connection reuse improvements
-
When a connection is handled over TLS, many connections need to be marked private (for example, when sending SNI) to prevent reusing the wrong information (e.g. wrong SNI). That prevents a connection from being reused in many cases. With this release, connections to backend servers can now be reused even when the SNI is calculated dynamically, such as from the request’s Host header (e.g.
sni req.hdr(host)
). - SSL/TLS statistics
-
When you add
stats show-modules
to your stats frontend, it adds a new column called Extra modules to the page that shows HTTP/2 related statistics. HAProxy Enterprise 2.4 adds more fields there for tracking SSL/TLS handshake and session statistics.You will find the following new fields, which are also displayed when you call the Runtime API’s
show stat
command, given you have at least onebind
statement that terminates SSL:Name
Description
ssl_sess
Total number of SSL sessions established
ssl_reused_sess
Total number of SSL sessions reused
ssl_failed_handshake
Total number of failed handshake
Observability
- Built-in OpenTracing
-
OpenTracing is now compiled directly into the core codebase.
- Prometheus metrics
-
State values for frontends, backends, and servers (up, down, maint, etc.) have been changed from being gauge values to being labels, making it easier to group by this criteria.
New metrics have been added to report on listeners, stick tables, and backend/server weight information, which we list below:
haproxy_process_uptime_seconds
haproxy_process_recv_logs_total
haproxy_process_build_info
haproxy_listener_current_sessions
haproxy_listener_max_sessions
haproxy_listener_limit_sessions
haproxy_listener_sessions_total
haproxy_listener_bytes_in_total
haproxy_listener_bytes_out_total
haproxy_listener_requests_denied_total
haproxy_listener_responses_denied_total
haproxy_listener_request_errors_total
haproxy_listener_status
haproxy_listener_denied_connections_total
haproxy_listener_denied_sessions_total
haproxy_listener_failed_header_rewriting_total
haproxy_listener_internal_errors_total
haproxy_backend_uweight
haproxy_server_uweight
haproxy_sticktable_size
haproxy_sticktable_used
Cache
- Vary header
-
This release brings support for the Vary header via a new keyword
process-vary
, which is set to on or off. It defaults to being off, which means that a response containing a Vary header will simply not be cached. It will also automatically normalize the accept-encoding header to improve the use of the cache.Also, a new directive
max-secondary-entries
allows you to control the maximum number of cached entries with the same primary key. For example, if you cache based on URL, but vary on the user-agent, you may create a lot of slightly different cached entries for the same URL. This prevents the cache from being filled with duplicates of the same resource. It requiresprocess-vary
to be on and it defaults to 10.
Configuration
- Conditionals
-
New, nestable, preprocessor-like directives allow you to include or skip some blocks of configuration markup.
The following directives have been introduced to form conditional blocks:
.if <condition> ... .endif
.elif <condition>
.else
.diag
.notice
.warning
.alert
The
.if
and.elif
statements are followed by a function name, such as:.if version_atleast(2.4) # include configuration lines .endif
Available functions are:
Function
Description
defined(<name>)
returns true if an environment variable <name> exists, regardless of its contents
feature(<name>)
returns true if feature <name> is listed as present in the features list reported by haproxy -vv
streq(<str1>,<str2>)
returns true if the two strings are equal
strneq(<str1>,<str2>)
returns true if the two strings differ
version_atleast(<ver>)
returns true if the current HAProxy version is at least as recent as <ver> otherwise false
version_before(<ver>)
returns true if the current HAProxy version is strictly older than <ver> otherwise false
Also, the following pre-processor directives can be placed inside a conditional block:
Directive
Description
.diag "message"
emit this message only when in diagnostic mode (-dD)
.notice "message"
emit this message at level NOTICE
.warning "message"
emit this message at level WARNING
.alert "message"
emit this message at level ALERT
- Default path
-
A new global directive
default-path
allows you to specify the path from which you would like HAProxy Enterprise to load additional files, such as map and ACL files. It accepts one of the following options:Option
Description
current
Relative file paths are loaded from the directory the process was started in. This is the default.
config
Relative file paths are loaded from the directory containing the configuration file.
parent
Relative file paths should be loaded from the parent directory above the configuration file directory.
origin <path>
Relative file paths should be loaded from the designated path.
- Pseudo variables
-
Pseudo-variables have been added, which can be helpful when troubleshooting.
Variable
Description
.FILE
the name of the configuration file currently being parsed.
.LINE
the line number of the configuration file currently being parsed, starting at one.
.SECTION
the name of the section currently being parsed, or its type if the section doesn’t have a name (e.g. "global")
- Named defaults sections
-
You can now assign a name to a
defaults
section and inherit its settings specifically in a frontend or backend.defaults http-defaults # default settings ... frontend fe_http from http-defaults # inherits the settings
You can also extend a named defaults section from another defaults section:
defaults tcp-defaults mode tcp timeout connect 5s timeout client 5s timeout server 5s default http-defaults from tcp-defaults mode http
- Dynamic server timeouts
-
You can change the
timeout server
andtimeout tunnel
settings dynamically using thehttp-request set-timeout
directive. You can use this to set custom timeouts on a per-host or per-URI basis, pull a timeout value from an HTTP header, or change timeouts using a Map file.The following fetches are available:
Variable
Description
be_server_timeout
Returns the configuration value in millisecond for the server timeout of the current backend
be_tunnel_timeout
Returns the configuration value in millisecond for the tunnel timeout of the current backend
cur_server_timeout
Returns the currently applied server timeout in millisecond for the stream
cur_tunnel_timeout
Returns the currently applied tunnel timeout in millisecond for the stream
- HTTP protocol upgrade
-
The new
tcp-request content switch-mode
directive upgrades a mode tcp connection to mode http dynamically. Combined with the built-inHTTP
ACL, you can switch to mode http if the traffic is HTTP.frontend fe_main mode tcp tcp-request inspect-delay 5s tcp-request content switch-mode http if HTTP
- Header deletion with pattern matching
-
The
http-request del-header
,http-response del-header
, andhttp-after-response del-header
directives now support the argument-m <method>
to delete a header based on a matched pattern. - HTTP request conditional body wait time
-
The new
http-request wait-for-body
andhttp-response wait-for-body
directives allow you to conditionally wait for and buffer a request or response body. These actions may be used as a replacement foroption http-buffer-request
.In the snippet below, HAProxy Enterprise waits one second at most to receive the POST body of the request, or until it gets at least 1,000 bytes:
http-request wait-for-body time 1s at-least 1k if METH_POST
New fetches and converters
- Fetches
-
This table lists new fetches:
Name
Description
baseq
Returns the concatenation of the first Host header and the path part of the request with the query-string, which starts at the first slash
bc_dst
This is the destination ip address of the connection on the server side, which is the server address HAProxy connected to.
bc_dst_port
Returns an integer value corresponding to the destination TCP port of the connection on the server side, which is the port HAProxy connected to.
bc_src
This is the source ip address of the connection on the server side, which is the server address haproxy connected from.
bc_src_port
Returns an integer value corresponding to the TCP source port of the connection on the server side, which is the port HAProxy connected from.
be_server_timeout
Returns the configuration value in millisecond for the server timeout of the current backend
be_tunnel_timeout
Returns the configuration value in millisecond for the tunnel timeout of the current backend
cur_server_timeout
Returns the currently applied server timeout in millisecond for the stream
cur_tunnel_timeout
Returns the currently applied tunnel timeout in millisecond for the stream
fe_client_timeout
Returns the configuration value in millisecond for the client timeout of the current frontend
sc_http_fail_cnt(<ctr>[,<table>]
Returns the cumulative number of HTTP response failures from the currently tracked counters. This includes the both response errors and 5xx status codes other than 501 and 505.
sc_http_fail_rate(<ctr>[,<table>])
Returns the average rate of HTTP response failures from the currently tracked counters, measured in amount of failures over the period configured in the table. This includes the both response errors and 5xx status codes other than 501 and 505. See also
src_http_fail_rate
.ssl_c_der
Returns the DER formatted certificate presented by the client when the incoming connection was made over an SSL/TLS transport layer
- Converters
-
The following converters have been added:
Name
Description
json_query(<json_path>,[<output_type>])
The json_query converter supports the JSON types string, boolean and number.
xxh3
Hashes a binary input sample into a signed 64-bit quantity using the XXH3 64-bit variant of the XXhash hash function
ub64dec
This converter is the base64url variant of b64dec converter. base64url encoding is the “URL and Filename Safe Alphabet” variant of base64 encoding. It is also the encoding used in JWT (JSON Web Token) standard.
ub64enc
This converter is the base64url variant of base64 converter.
url_enc
Takes a string provided as input and returns the encoded version as output
Runtime API
This version includes the following changes to the Runtime API:
- Help filtering
-
The
help
command will attempt to display information for partially spelled commands.Also if you enter an incorrect command, the API will suggest alternatives.
- Commands
-
This release adds two new Runtime API commands.
Name
Description
set server <backend>/<server> agent-port <port>
Change the port used for agent checks.
set server <backend>/<server> check-addr <ip4 | ip6> [port <port>]
Change the IP address used for server health checks. Optionally, change the port used for server health checks.
set server <backend/server> ssl on
Activates SSL on outgoing connections to a server at runtime.
prepare acl
Begin a transaction for adding ACLs. This returns a number, which you would then reference in the
add acl
command.commit acl
Commit the transaction to add new ACLs.
Lua
Lua has been extended to support multithreading. A new global directive, lua-load-per-thread
, has been added to aid with this. For Lua scripts that require threading, this should be used as it will launch the Lua code as an independent state in each thread. The existing lua-load
keyword still exists and should be used for Lua modules meant to cover the entire process, such as jobs registered with core.register_task
.
Miscellaneous
There are the following miscellaneous changes:
The
tune.chksize
directive has been deprecated.During a reload, processes are closed sooner, rather than waiting for idle frontend connections to timeout.
During a reload, idle backend connections are actively killed.
TCP log outputs now automatically create a ring buffer.
Layer 7 retries now support 401 and 403 HTTP status codes.
The
http-check send
directive now supports adding a Connection header.The global section now supports setting process level variables.
A new macro HTTP_2.0 has been added, which will return true for HTTP/2 requests.
The
server-state-file-name
directive has a new argument,use-backend-name
, that allows you to load the state file using the name of the backend. This only applies when the directiveload-server-state-from-file
is set to local.A new srvkey parameter has been added to the
stick-table
directive. This allows you to specify how a server is identified. It accepts either name, which will use the current defined name of the server or addr, which will use the current network address including the port. addr is useful when you are using service discovery to generate the addresses.A new log-format parameter, %HPO, was added, which allows logging of the request path without the query string.
Next up
Getting Started