26596 Commits

Author SHA1 Message Date
William Lallemand
6a862009be DOC: configuration: update tune.ssl.keylog URL to IETF draft
Replace the Mozilla NSS key log format link with the IETF draft:
https://tlswg.org/sslkeylogfile/draft-ietf-tls-keylogfile.html
2026-04-01 16:28:49 +02:00
William Lallemand
c8bfd06b57 MINOR: ssl/log: add keylog format variables and env vars
Add keylog_format_fc and keylog_format_bc global variables containing
the SSLKEYLOGFILE log-format strings for the frontend (client-facing)
and backend (server-facing) TLS connections respectively. These produce
output compatible with the SSLKEYLOGFILE format described at:
https://tlswg.org/sslkeylogfile/draft-ietf-tls-keylogfile.html

Both formats are also exported as environment variables at startup:
  HAPROXY_KEYLOG_FC_LOG_FMT
  HAPROXY_KEYLOG_BC_LOG_FMT

These variables contains \n so they might not be compatible with syslog
servers, using them with stderr or a sink might be required.

These can be referenced directly in "log-format" directives to produce
SSLKEYLOGFILE-compatible output, usable by network analyzers such as
Wireshark to decrypt captured TLS traffic.
2026-04-01 16:28:49 +02:00
Olivier Houchard
e264523112 MINOR: servers: Don't update last_sess if it did not change
Check that last_sess actually changed before attempting to set it, as it
should only change once every second, that will avoid a lot of atomic
writes on a busy cache line.
2026-04-01 15:06:55 +02:00
Olivier Houchard
eaf42ee886 MINOR: backends: Don't update last_sess if it did not change
Check that last_sess actually changed before attempting to set it, as it
should only change once every second, that will avoid a lot of atomic
writes on a busy cache line.
2026-04-01 14:58:59 +02:00
Olivier Houchard
397530b1e9 MEDIUM: stats: Hide the version by default and add stats-showversion
Reverse the default, to hide the version from stats by default, and add
a new keyword, "stats show-version", to enable them, as we don't want to
disclose the version by default, especially on public websites.
2026-04-01 14:39:28 +02:00
Christopher Faulet
7c73b08a98 BUG/MINOR: http_act: Properly handle decoding errors in *-headers-bin actions
When binary headers are decoded, return value of decode_varint() function is
not properly handled. On error, it can return -1. However, the result is
inconditionnaly added to an unsigned offset.

Now, a temporary variable is used to be abl to test decode_varint() return
value. It is added to the offset on success only.

No backport needed.
2026-04-01 07:49:40 +02:00
Cody Ohlsen
ee95a7539e BUG/MEDIUM: mux-h1: Don't set MSG_MORE on bodyless responses forwarded to client
When h1_snd_buf() inherits the CO_SFL_MSG_MORE flag from the upper layer, it
unconditionally propagates it to H1C_F_CO_MSG_MORE, which eventually sets
MSG_MORE on the sendmsg() call. For bodyless responses (HEAD, 204, 304), this
causes the kernel to cork the TCP connection for ~200ms waiting for body data
that will never be sent.

With an H1 frontend and H2 backend, this adds ~200ms of latency to many or
all bodyless responses. The 200ms corresponds to the kernel's tcp_cork_time
default. H1 backends are less affected because h1_postparse_res_hdrs() sets
HTX_FL_EOM during header parsing for bodyless responses, but H2 backends
frequently deliver the end-of-stream signal in a separate scheduling round,
leaving htx_expect_more() returning TRUE when headers are first forwarded.

The fix guards H1C_F_CO_MSG_MORE so it is only set when the connection is a
backend (H1C_F_IS_BACK) or the response is not bodyless
(!H1S_F_BODYLESS_RESP). This ensures bodyless responses on the front
connection are sent immediately without corking.

This should be backported to all stable branches.

Co-developed-by: Billy Campoli <bcampoli@meta.com>
Co-developed-by: Chandan Avdhut <cavdhut@meta.com>
Co-developed-by: Neel Raja <neelraja@meta.com
2026-03-31 19:56:28 +02:00
Nenad Merdanovic
daf378d2b4 MEDIUM: Add set-headers-bin, add-headers-bin and del-headers-bin actions
These actions allow setting, adding and deleting multiple headers from
the same action, without having to know the header names during parsing.
This is useful when doing things with SPOE.
2026-03-31 19:56:28 +02:00
Amaury Denoyelle
b134065ea8 DOC: configuration: mention QUIC server support
Adds 'quic4@' / 'quic6@' as prefixes available for server addresses.
This is explicitely listed as experimental for now.

This must be backported up to 3.3.
2026-03-31 17:50:20 +02:00
William Lallemand
94d2f69b93 BUG/MEDIUM: map/cli: CLI commands lack admin permission checks
The CLI commands (get|add|del|clear|commit|set) | (acl|map) does not
contain a permission check on admin level.

Must be backported to 3.3. This can be a breaking change for some users.

Initially reported by Cameron Brown.
2026-03-31 12:34:33 +02:00
William Lallemand
66965a60ba BUG/MEDIUM: ssl/ocsp: ocsp commands are missing permission checks
'set ssl ocsp-response', 'update ssl ocsp-response', 'show ssl
ocsp-response', 'show ssl ocsp-updates' are lacking permissions checks
on admin level.

Must be backported in 3.3. This can be a breaking change for some users.

Initially reported by Cameron Brown.
2026-03-31 12:18:26 +02:00
William Lallemand
453a01387b BUG/MEDIUM: ssl/cli: tls-keys commands are missing permission checks
Both 'set ssl tls-key' and 'show tls-keys' command are missing the
permission checks so the commands can be used only in admin mode.

Must be backported to 3.3. This can be a breaking change for some users.

Initially reported by Cameron Brown.
2026-03-31 12:18:26 +02:00
William Lallemand
25366f6dc1 BUG/MEDIUM: map/cli: map/acl commands warn when accessed without admin level
This commit adds an ha_warning() when map/acl commands are accessed
without admin level. This is to warn users that these commands will be
restricted to admin only in HAProxy 3.3.

Must be backported in every stable branches.

Initially reported by Cameron Brown.
2026-03-31 12:18:26 +02:00
William Lallemand
d47415624b BUG/MEDIUM: ssl/ocsp: ocsp commands warn when accessed without admin level
This commit adds an ha_warning() when OCSP commands are accessed without
admin level. This is to warn users that these commands will be
restricted to admin only in HAProxy 3.3.

Must be backported in every stable branches.

Initially reported by Cameron Brown.
2026-03-31 12:18:26 +02:00
William Lallemand
14a4168a84 BUG/MEDIUM: ssl/cli: tls-keys commands warn when accessed without admin level
This commit adds an ha_warning() when 'show tls-keys' or 'set ssl
tls-key' are accessed without admin level. This is to warn users that
these commands will be restricted to admin only in HAProxy 3.3.

Must be backported in every stable branches.

Initially reported by Cameron Brown.
2026-03-31 12:18:26 +02:00
Willy Tarreau
226bb4bd28 SCRIPTS: git-show-backports: list new commits and how to review them with -L
The new "-L" option is convenient for quick backport sessions, but it
doesn't list the commit subjects nor the review command. Let's just add
these to ease backport sessions. However we don't do it in quiet mode
(-q) because the output is sometimes parsed by automatic backport
scripts.
2026-03-31 09:21:49 +02:00
William Lallemand
ad87ab1f2e DOC: configuration: document challenge-ready and dns-delay options for ACME
Add documentation for two new directives in the acme section:

- challenge-ready: configures the conditions that must be satisfied
  before notifying the ACME server that a dns-01 challenge is ready.
  Accepted values are cli, dns and none. cli waits for an operator
  to signal readiness via the "acme challenge_ready" CLI command. dns
  performs a DNS pre-check against the "default" resolvers section,
  not the authoritative name servers. When both are combined, HAProxy
  waits for the CLI confirmation before triggering the DNS check.

- dns-delay: configures the delay before the first DNS resolution
  attempt and between retries when challenge-ready includes dns.
  Default is 300 seconds.
2026-03-30 18:24:28 +02:00
William Lallemand
2b0c510aff MEDIUM: acme: new 'challenge-ready' option
The previous patch implemented the 'dns-check' option. This one replaces
it by a more generic  'challenge-ready' option, which allows the user to
chose the condition to validate the readiness of a challenge. It could
be 'cli', 'dns' or both.

When in dns-01 mode it's by default to 'cli' so the external tool used to
configure the TXT record can validate itself. If the tool does not
validate the TXT record, you can use 'cli,dns' so a DNS check would be
done after the CLI validated with 'challenge_ready'.

For an automated validation of the challenge, it should be set to 'dns',
this would check that the TXT record is right by itself.
2026-03-30 18:24:28 +02:00
William Lallemand
631fd5f99b MEDIUM: acme: add dns-01 DNS propagation pre-check
When using the dns-01 challenge type, TXT record propagation across
DNS servers can take time. If the ACME server verifies the challenge
before the record is visible, the challenge fails and it's not possible
to trigger it again.

This patch introduces an optional DNS pre-check mechanism controlled
by two new configuration directives in the "acme" section:

  - "dns-check on|off": enable DNS propagation verification before
    notifying the ACME server (default: off)
  - "dns-delay <time>": delay before querying DNS (default: 300s)

When enabled, three new states are inserted in the state machine
between AUTH and CHALLENGE:

  - ACME_RSLV_WAIT: waits dns-delay seconds before starting
  - ACME_RSLV_TRIGGER: starts an async TXT resolution for each
    pending authorization using HAProxy's resolver infrastructure
  - ACME_RSLV_READY: compares the resolved TXT record against the
    expected token; retries from ACME_RSLV_WAIT if any record is
    missing or does not match

The "acme_rslv" structure is implemented in acme_resolvers.c, it holds
the resolution for each domain. The "auth" structure which contains each
challenge to resolve contains an "acme_rslv" structure. Once
ACME_RSLV_TRIGGER leaves, the DNS tasks run on the same thread, and the
last DNS task which finishes will wake up acme_process().

Note that the resolution goes through the configured resolvers, not
through the authoritative name servers of the domain. The result may
therefore still be affected by DNS caching at the resolver level.
2026-03-30 18:24:28 +02:00
William Lallemand
5dcfbc5fad MINOR: acme: store the TXT record in auth->token
In case of dns-01 challenge, replace the token by the TXT record which
is more pertinent and could be used later to verify if the record is
correct.
2026-03-30 18:24:28 +02:00
William Lallemand
e418e828aa MINOR: resolvers: basic TXT record implementation
This patch adds support for TXT records. It allows to get the first
string of a TXT-record which is limited to 255 characters.
The rest of the record is ignored.
2026-03-30 18:24:28 +02:00
Willy Tarreau
50446c35a7 BUILD: net_helper: fix unterminated comment that broke the build
Latest commit a336c467a0 ("BUG/MINOR: net_helper: fix length controls
on ip.fp tcp options parsing") was malformed and broke the build. This
should be backported wherever the fix above is backported.
2026-03-30 18:23:12 +02:00
Emeric Brun
a336c467a0 BUG/MINOR: net_helper: fix length controls on ip.fp tcp options parsing
If opt len is truncated by tcplen we may read 1 Byte after the
tcp header.

There is also missing controls parsing MSS and WS we may compute
invalid values on fingerprint reading after the tcp header in
case of truncated options.

This patch should be backported on versions including ip.fp
2026-03-30 18:10:29 +02:00
Willy Tarreau
e375f1061a MINOR: mux-h2: report glitches on early RST_STREAM
We leverage the SE_FL_APP_STARTED flag to detect whether the application
layer had a chance to run or not when an RST_STREAM is received. This
allows us to triage RST_STREAM between regular ones and harmful ones,
and to count glitches for them. It reveals extremely effective at
detecting fast HEADERS+RST pairs.

It could be useful to backport it to 3.2, though it depends on these
two previous patches to be backported first (the first one was already
planned and the second one is harmless, though will require to drop
the haterm changes):

  BUG/MINOR: stconn: Always declare the SC created from healthchecks as a back SC
  MINOR: stconn: flag the stream endpoint descriptor when the app has started
2026-03-30 16:32:21 +02:00
Willy Tarreau
cf3173d92b MINOR: stconn: flag the stream endpoint descriptor when the app has started
In order to improve our ability to distinguish operations that had
already started from others under high loads, it would be nice to know
if an application layer (stream) has started to work with an endpoint
or not. The use case typically is a frontend mux instantiating a stream
to instantly cancel it. Currently this info will take some time to be
detected and processed if the applcation's task takes time to wake up.
By flagging the sedesc with SE_FL_APP_STARTED the first time a the app
layer starts, the lower layers can know whether they're cancelling a
stream that has started to work or not, and act accordingly. For now
this is done unconditionally on the backend, and performed early in the
only two app layers that can be reached by a frontend: process_stream()
and process_hstream() (for haterm).
2026-03-30 16:27:53 +02:00
Christopher Faulet
5280130343 BUG/MINOR: stconn: Always declare the SC created from healthchecks as a back SC
The SC created from a healthcheck is always a back SC. But SC_FL_ISBACK
flags was missing. Instead of passing it when sc_new_from_check() is called,
the function was simplified to set SC_FL_ISBACK flag systematically when a
SC is created from a healthcheck.

This patch should be backported as far as 2.6.
2026-03-30 15:47:36 +02:00
Christopher Faulet
d4eee1f206 CLEANUP: stconn: Remove usless sc_new_from_haterm() declaration
This function does not exist. Let's remove its declaration.
2026-03-30 15:47:05 +02:00
Amaury Denoyelle
08cc37a554 BUG/MINOR: quic: close conn on packet reception with incompatible frame
RFC 9000 lists each supported frames and the type of packets in which it
can be present.

Prior to this patch, a packet with an incompatible frame is dropped.
However, QUIC specification mandates that the connection is immediately
closed with PROTOCOL_VIOLATION error code. This patch completes
qc_parse_frm() to add such connection closure.

This must be backported up to 2.6.
2026-03-30 09:52:10 +02:00
Ilia Shipitsin
b7d1c2f91d CLEANUP: fix typos and spelling in comments and documentation
Corrected multiple spelling mistakes across CLI scripts, documentation,
and source comments (e.g. "Specifiy" → "Specify", "explicitely" → "explicitly",
"transfert" → "transfer", "resetted" → "reset", etc.). These changes
improve readability and consistency without altering functionality.
2026-03-30 09:24:19 +02:00
Ilia Shipitsin
20ae1eb79d CI: github: fix tag listing by implementing proper API pagination
The GitHub API silently caps per_page at 100, so passing per_page=200
was silently returning at most 100 tags. AWS-LC-FIPS tags appear late
in the list, causing version detection to fail.

Replace the single-page fetch in get_all_github_tags() with a loop that
iterates all pages.

Could be backported in previous branches.
2026-03-30 09:16:35 +02:00
Christopher Faulet
4fd5cafe27 BUG/MEDIUM: htx: Fix htx_xfer() to consume more data than expected
When an htx DATA block is partially transfer, we must take care to remove
exactly the copied size. To do so, we must save the size of the last block
value copied and not rely on the last data block after the copy. Indeed,
data can be merged with an existing DATA block, so the last block size can
be larger than the last part copied.

Because of this issue, it is possible to remove more data than
expected. Worse, this could lead to a crash by performing an integer
overflow on the block size.

No backport needed.
2026-03-27 17:19:12 +01:00
William Lallemand
d26bd9f978 BUG/MINOR: acme: fix task allocation leaked upon error
Fix a leak of the task object in acme_start_task() when one of the
condition in the function failed.

Fix issue #3308.

Must be backported to 3.2 and later.
2026-03-27 16:58:49 +01:00
Olivier Houchard
506cfcb5d4 MINOR: connections: Enhance tune.idle-pool.shared
There are two settings to control idle connection sharing across
threads.
tune.idle-pool.shared, that enables or disables it, and then
tune.takeover-other-tg-connections, which lets you or not get idle
connections from other thread groups.
Add a new keyword for tune.idle-pool.shared, "full", that lets you get
connections from other thread groups (equivalent to "full" keyword for
tune.takeover-other-tg-connections). The "on" keyword now will be
equivalent to the "restrict" one, which allowed getting connection from
other thread groups only when not doing it would result in a connection
failure (when reverse-http or when strict-macxonn are used).
tune.takeover-other-tg-connections will be deprecated.
2026-03-27 16:14:53 +01:00
Mia Kanashi
418f0c0bbe BUG/MEDIUM: acme: skip doing challenge if it is already valid
If server returns an auth with status valid it seems that client
needs to always skip it, CA can recycle authorizations, without
this change haproxy fails to obtain certificates in that case.
It is also something that is explicitly allowed and stated
in the dns-persist-01 draft RFC.

Note that it would be better to change how haproxy does status polling,
and implements the state machine, but that will take some thought
and time, this patch is a quick fix of the problem.

See:
https://github.com/letsencrypt/boulder/issues/2125
https://github.com/letsencrypt/pebble/issues/133

This must be backported to 3.2 and later.
2026-03-27 14:41:11 +01:00
Christopher Faulet
27d7c69e87 BUG/MINOR: http-ana: Only consider client abort for abortonclose
When abortonclose option is enabled (by default since 3.3), the HTTP rules
can no longer yield if the client aborts. However, stream aborts were also
considered. So it was possible to interrupt yielding rules, especially on
the response processing, while the client was still waiting for the
response.

So now, when abortonclose option is enabled, we now take care to only
consider client aborts to prevent HTTP rules to yield.

Many thanks to @DirkyJerky for his detailed analysis.

This patch should fix the issue #3306. It should be backported as far as
2.8.
2026-03-27 11:18:40 +01:00
Christopher Faulet
d1c7e56585 BUG/MINOR: config: Properly test warnif_misplaced_* return values
warnif_misplaced_* functions return 1 when a warning is reported and 0
otherwise. So the caller must properly handle the return value.

When parsing a proxy, ERR_WARN code must be added to the error code instead
of the return value. When a warning was reported, ERR_RETRYABLE (1) was
added instead of ERR_WARN.

And when tcp rules were parsed, warnings were ignored. Message were emitted
but the return values were ignored.

This patch should be backported to all stable versions.
2026-03-27 07:35:25 +01:00
Christopher Faulet
4e99cddde4 BUG/MINOR: config: Warn only if warnif_cond_conflicts report a conflict
When warnif_cond_conflicts() is called, we must take care to emit a warning
only when a conflict is reported. We cannot rely on the err_code variable
because some warnings may have been already reported. We now rely on the
errmsg variable. If it contains something, a warning is emitted. It is good
enough becasue warnif_cond_conflicts() only reports warnings.

This patch should fix the issue #3305. It is a 3.4-dev specific issue. No
backport needed.
2026-03-27 07:35:25 +01:00
Olivier Houchard
0e36267aac MEDIUM: server: remove a useless memset() in srv_update_check_addr_port.
Remove a memset that should not be there, and tries to zero a NULL pointer.
2026-03-26 16:43:48 +01:00
Olivier Houchard
1b0dfff552 MEDIUM: connections: Enforce mux protocol requirements
When picking a mux, pay attention to its MX_FL_FRAMED. If it is set,
then it means we explicitely want QUIC, so don't use that mux for any
protocol that is not QUIC.
2026-03-26 15:09:13 +01:00
Olivier Houchard
d3ad730d5f MINOR: protocols: Add a new proto_is_quic() function
Add a new function, proto_is_quic(), that returns true if the protocol
is QUIC (using a datagram socket but provides a stream transport).
2026-03-26 15:09:13 +01:00
Olivier Houchard
cca9245416 MINOR: checks: Store the protocol to be used in struct check
When parsing the check address, store the associated proto too.
That way we can use the notation like quic4@address, and the right
protocol will be used. It is possible for checks to use a different
protocol than the server, ie we can have a QUIC server but want to run
TCP checks, so we can't just reuse whatever the server uses.
WIP: store the protocol in checks
2026-03-26 15:09:13 +01:00
Olivier Houchard
07edaed191 BUG/MEDIUM: check: Don't reuse the server xprt if we should not
Don't assume the check will reuse the server's xprt. It may not be true
if some settings such as the ALPN has been set, and it differs from the
server's one. If the server is QUIC, and we want to use TCP for checks,
we certainly don't want to reuse its XPRT.
2026-03-26 15:09:13 +01:00
William Lallemand
1c1d9d2500 BUG/MINOR: acme: permission checks on the CLI
Permission checks on the CLI for ACME are missing.

This patch adds a check on the ACME commands
so they can only be run in admin mode.

ACME is stil a feature in experimental-mode.

Initial report by Cameron Brown.

Must be backported to 3.2 and later.
2026-03-25 18:37:47 +01:00
William Lallemand
47987ccbd9 BUG/MINOR: ech: permission checks on the CLI
Permission checks on the CLI for ECH are missing.

This patch adds a check for "(add|set|del|show) ssl ech" commands
so they can only be run in admin mode.

ECH is stil a feature in experimental-mode and is not compiled by
default.

Initial report by Cameron Brown.

Must be backported to 3.3.
2026-03-25 18:37:06 +01:00
William Lallemand
33041fe91f BUILD: tools: potential null pointer dereference in dl_collect_libs_cb
This patch fixes a warning that can be reproduced with gcc-8.5 on RHEL8
(gcc (GCC) 8.5.0 20210514 (Red Hat 8.5.0-28)).

This should fix issue #3303.

Must be backported everywhere 917e82f283 ("MINOR: debug: copy debug
symbols from /usr/lib/debug when present") was backported, which is
to branch 3.2 for now.
2026-03-23 21:52:56 +01:00
William Lallemand
8e250bba8f BUG/MINOR: acme/cli: fix argument check and error in 'acme challenge_ready'
Fix the check or arguments of the 'acme challenge_ready' command which
was checking if all arguments are NULL instead of one of the argument.

Must be backported to 3.2 and later.
2026-03-23 14:39:55 +01:00
William Lallemand
c7564c19a2 BUG/MINOR: acme: replace atol with len-bounded __strl2uic() for retry-after
Replace atol() by _strl2uic() in cases the input are ISTs when parsing
the retry-after header. There's no risk of an error since it will stop
at the first non-digit.

Must be backported to 3.2 and later.
2026-03-23 14:39:55 +01:00
William Lallemand
efbf0f8ed1 BUG/MINOR: acme: free() DER buffer on a2base64url error path
In acme_req_finalize() the data buffer is only freed when a2base64url
succeed. This patch moves the allocation so it free() the DER buffer in
every cases.

Must be backported to 3.2 and later.
2026-03-23 14:39:55 +01:00
William Lallemand
52d8ee85e7 BUG/MINOR: acme: NULL check on my_strndup()
Add a NULL check on my_strndup().

Must be backported to 3.2 and later.
2026-03-23 14:39:55 +01:00
Christopher Faulet
38a7d8599d DOC: config: Reorder params for 'tcp-check expect' directive
Order of parameters for the 'tcp-check expect' directive is changed to be
the same than 'http-check expect'.
2026-03-23 14:02:43 +01:00