Commit graph

26570 commits

Author SHA1 Message Date
William Lallemand
f8a6fcc7a8 fixup build
Some checks failed
Contrib / build (push) Has been cancelled
alpine/musl / gcc (push) Has been cancelled
VTest / Generate Build Matrix (push) Has been cancelled
Windows / Windows, gcc, all features (push) Has been cancelled
VTest / (push) Has been cancelled
2026-03-30 18:04:04 +02:00
William Lallemand
e15afd423b fixup acme-t.h 2026-03-30 17:55:13 +02:00
William Lallemand
cc1f23d5fe 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 17:46:11 +02:00
William Lallemand
c44baf3886 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 11:54:05 +02:00
William Lallemand
5b3ffb7a2a 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-27 16:44:27 +01:00
William Lallemand
82d5479b82 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-27 16:21:09 +01:00
William Lallemand
56b74b7ea2 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-27 16:21:09 +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.
Some checks are pending
Contrib / build (push) Waiting to run
alpine/musl / gcc (push) Waiting to run
VTest / Generate Build Matrix (push) Waiting to run
VTest / (push) Blocked by required conditions
Windows / Windows, gcc, all features (push) Waiting to run
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
Some checks are pending
Contrib / build (push) Waiting to run
alpine/musl / gcc (push) Waiting to run
VTest / Generate Build Matrix (push) Waiting to run
VTest / (push) Blocked by required conditions
Windows / Windows, gcc, all features (push) Waiting to run
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
Some checks failed
Contrib / build (push) Has been cancelled
alpine/musl / gcc (push) Has been cancelled
VTest / Generate Build Matrix (push) Has been cancelled
Windows / Windows, gcc, all features (push) Has been cancelled
VTest / (push) Has been cancelled
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'
Some checks are pending
Contrib / build (push) Waiting to run
alpine/musl / gcc (push) Waiting to run
VTest / Generate Build Matrix (push) Waiting to run
VTest / (push) Blocked by required conditions
Windows / Windows, gcc, all features (push) Waiting to run
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
Christopher Faulet
82afd36b6c DOC: config: Add missing 'status-code' param for 'http-check expect' directive
In the documentation of 'http-check expect' directive, the parameter
'status-code' was missing. Let's add it.

This patch could be backported to all stable versions.
2026-03-23 14:02:43 +01:00
Christopher Faulet
ada33006ef MINOR: proxy: Add use-small-buffers option to set where to use small buffers
Thanks to previous commits, it is possible to use small buffers at different
places: to store the request when a connection is queued or when L7 retries
are enabled, or for health-checks requests. However, there was no
configuration parameter to fine tune small buffer use.

It is now possible, thanks to the proxy option "use-small-buffers".
Documentation was updated accordingly.
2026-03-23 14:02:43 +01:00
Christopher Faulet
163eba5c8c DOC: config: Fix alphabetical ordering of external-check directives
external-check directives were not at the right place. Let's fix it.
2026-03-23 14:02:43 +01:00
Christopher Faulet
61d68f14b2 DOC: config: Fix alphabetical ordering of proxy options
external-check and idle-close-on-response options were not at the right
place. Let's fix it.
2026-03-23 14:02:43 +01:00
Christopher Faulet
125cbecfa9 MINOR: proxy: Review options flags used to configure healthchecks
When healthchecks were configured for a proxy, an enum-like was used to
sepcify the check's type. The idea was to reserve some values for futur
types of healthcheck. But it is overkill. I doubt we will ever have
something else than tcp and external checks. So corresponding PR_O2 flags
were slightly reviewed and a hole was filled.

Thanks to this change, some bits were released in options2 bitfield.
2026-03-23 14:02:43 +01:00
Christopher Faulet
a61ea0f414 MEDIUM: tcpcheck: Use small buffer if possible for healthchecks
If support for small buffers is enabled, we now try to use them for
healthcheck requests. First, we take care the tcpcheck ruleset may use small
buffers. Send rules using LF strings or too large data are excluded. The
ability to use small buffers or not are set on the ruleset. All send rules
of the ruleset must be compatible. This info is then transfer to server's
healthchecks relying on this ruleset.

Then, when a healthcheck is running, when a send rule is evaluated, if
possible, we try to use small buffers. On error, the ability to use small
buffers is removed and we retry with a regular buffer. It means on the first
error, the support is disabled for the healthcheck and all other runs will
use regular buffers.
2026-03-23 14:02:43 +01:00
Christopher Faulet
cd363e0246 MEDIUM: mux-h2: Stop dealing with HTX flags transfer in h2_rcv_buf()
In h2_rcv_buf(), HTX flags are transfer with data when htx_xfer() is
called. There is no reason to continue to deal with them in the H2 mux. In
addition, there is no reason to set SE_FL_EOI flag when a parsing error was
reported. This part was added before the stconn era. Nowadays, when an HTX
parsing error is reported, an error on the sedesc should also be reported.
2026-03-23 14:02:43 +01:00
Christopher Faulet
d257dd4563 Revert "BUG/MEDIUM: mux-h2: make sure to always report pending errors to the stream"
This reverts commit 44932b6c41.

The patch above was only necessary to handle partial headers or trailers
parsing. There was nothing to prevent the H2 multiplexer to start to add
headers or trailers in an HTX message and to stop the processing on error,
leaving the HTX message with no EOH/EOT block.

From the HTX API point of view, it is unexepected. And this was fixed thanks
to the commit ba7dc46a9 ("BUG/MINOR: h2/h3: Never insert partial
headers/trailers in an HTX message").

So this patch can be reverted. It is important to not report a parsign error
too early, when there are still data to transfer to the upper layer.

This patch must be backport where 44932b6c4 was backported but only after
backporting ba7dc46a9 first.
2026-03-23 14:02:43 +01:00
Christopher Faulet
39121ceca6 MEDIUM: tree-wide: Rely on htx_xfer() instead of htx_xfer_blks()
htx_xfer() function replaced htx_xfer_blks(). So let's use it.
2026-03-23 14:02:43 +01:00
Christopher Faulet
c9a9fa813b MEDIUM: stconn: Use a small buffer if possible for L7 retries
Whe L7 retries are enabled and the request is small enough, a small buffer
is used instead of a regular one.
2026-03-23 14:02:43 +01:00
Christopher Faulet
181cd8ba8a MEDIUM: stream: Try to use small buffer when TCP stream is queued
It was performed when an HTX stream was queued. Small requests were moved in
small buffers. Here we do the same but for TCP streams.
2026-03-23 14:02:42 +01:00
Christopher Faulet
5acdda4eed MEDIUM: stream: Try to use a small buffer for HTTP request on queuing
When a HTX stream is queued, if the request is small enough, it is moved
into a small buffer. This should save memory on instances intensively using
queues.

Applet and connection receive function were update to block receive when a
small buffer is in use.
2026-03-23 14:02:42 +01:00
Christopher Faulet
92a24a4e87 MEDIUM: chunk: Add support for small chunks
In the same way support for large chunks was added to properly work with
large buffers, we are now adding supports for small chunks because it is
possible to process small buffers.

So a dedicated memory pool is added to allocate small
chunks. alloc_small_trash_chunk() must be used to allocate a small
chunk. alloc_trash_chunk_sz() and free_trash_chunk() were uppdated to
support small chunks.

In addition, small trash buffers are also created, using the same mechanism
than for regular trash buffers. So three thread-local trash buffers are
created. get_small_trash_chunk() must be used to get a small trash buffer.
And get_trash_chunk_sz() was updated to also deal with small buffers.
2026-03-23 14:02:42 +01:00
Christopher Faulet
467f911cea MINOR: http-ana: Use HTX API to move to a large buffer
Use htx_move_to_large_buffer() to move a regular HTX message to a large
buffer when we are waiting for a huge payload.
2026-03-23 14:02:42 +01:00
Christopher Faulet
0213dd70c9 MINOR: htx: Add helper functions to xfer a message to smaller or larger one
htx_move_to_small_buffer()/htx_move_to_large_buffer() and
htx_copy_to_small_buffer()/htx_copy_to_large_buffer() functions can now be
used to move or copy blocks from a default buffer to a small or large
buffer. The destination buffer is allocated and then each blocks are
transferred into it.

These funtions relies in htx_xfer() function.
2026-03-23 14:02:42 +01:00
Christopher Faulet
5ead611cc2 MEDIUM: htx: Add htx_xfer function to replace htx_xfer_blks
htx_xfer() function should replace htx_xfer_blks(). It will be a bit easier to
maintain and to use. The behavior of htx_xfer() can be changed by calling it
with specific flags:

  * HTX_XFER_KEEP_SRC_BLKS: Blocks from the source message are just copied
  * HTX_XFER_PARTIAL_HDRS_COPY: It is allowed to partially xfer headers or trailers
  * HTX_XFER_HDRS_ONLY: only headers are xferred

By default (HTX_XFER_DEFAULT or 0), all blocks from the source message are moved
into to the destination mesage. So copied in the destination messageand removed
from the source message.

The caller must still define the maximum amount of data (including meta-data)
that can be xferred.

It is no longer necessary to specify a block type to stop the copy. Most of
time, with htx_xfer_blks(), this parameter was set to HTX_BLK_UNUSED. And
otherwise it was only specified to transfer headers.

It is important to not that the caller is responsible to verify the original
HTX message is well-formated. Especially, it must be sure headers part and
trailers part are complete (finished by EOH/EOT block).

For now, htx_xfer_blks() is not removed for compatiblity reason. But it is
deprecated.
2026-03-23 14:02:42 +01:00
Christopher Faulet
41c89e4fb6 MINOR: config: Report the warning when invalid large buffer size is set
When an invalid large buffer size was found in the configuration, a warning
was emitted but it was not reported via the error code. It is now fixed.
2026-03-23 14:02:42 +01:00
Christopher Faulet
b71f70d548 MINOR: config: Relax tests on the configured size of small buffers
When small buffer size was greater than the default buffer size, an error
was triggered. We now do the same than for large buffer. A warning is
emitted and the small buffer size is set to 0 do disable small buffer
allocation.
2026-03-23 14:02:42 +01:00
Christopher Faulet
01b9b67d5c MINOR: quic: Use b_alloc_small() to allocate a small buffer
Rely on b_alloc_small to allocate a small buffer.
2026-03-23 14:02:42 +01:00
Christopher Faulet
f8c96bf9cb MINOR: dynbuf: Add helper functions to alloc large and small buffers
b_alloc_small() and b_alloc_large() can now be used to alloc small or larger
buffers. For now, unlike default buffers, buffer_wait lists are not used.
2026-03-23 14:02:42 +01:00
Christopher Faulet
4d6cba03f2 MINOR: buffers: Move small buffers management from quic to dynbuf part
Because small buffers were only used by QUIC streams, the pool used to alloc
these buffers was located in the quic code. However, their usage will be
extended to other parts. So, the small buffers pool was moved into the
dynbuf part.
2026-03-23 14:02:42 +01:00
Amaury Denoyelle
1c379cad88 BUG/MINOR: http_htx: fix null deref in http-errors config check
http-errors parsing has been refactored in a recent serie of patches.
However, a null deref was introduced by the following patch in case a
non-existent http-errors section is referenced by an "errorfiles"
directive.

  commit 2ca7601c2d
  MINOR/OPTIM: http_htx: lookup once http_errors section on check/init

Fix this by delaying ha_free() so that it is called after ha_alert().

No need to backport.
2026-03-23 13:55:48 +01:00
William Lallemand
3d9865a12c BUG/MINOR: acme/cli: wrong argument check in 'acme renew'
Argument check should be args[2] instead of args[1] which is always
'renew'.

Must be backported to 3.2 and later.
2026-03-23 11:58:53 +01:00
William Lallemand
d72be950bd BUG/MINOR: acme: wrong error when checking for duplicate section
The cfg_parse_acme() function checks if an 'acme' section is already
existing in the configuration with cur_acme->linenum > 0. But the wrong
filename and line number are displayed in the commit message.

Must be backported to 3.2 and later.
2026-03-23 11:58:53 +01:00
William Lallemand
5a0fbbf1ca BUG/MINOR: acme: leak of ext_san upon insertion error
This patch fixes a leak of the ext_san structure when
sk_X509_EXTENSION_push() failed. sk_X509_EXTENSION_pop_free() is already
suppose to free it, so ext_san must be set to NULL upon success to avoid
a double-free.

Must be backported to 3.2 and later.
2026-03-23 11:58:53 +01:00
Amaury Denoyelle
c6fc53aa99 MEDIUM: proxy: remove http-errors limitation for dynamic backends
Use proxy_check_http_errors() on defaults proxy instances. This will
emit alert messages for errorfiles directives referencing a non-existing
http-errors section, or a warning if an explicitely listed status code
is not present in the target section.

This is a small behavior changes, as previouly this was only performed
for regular proxies. Thus, errorfile/errorfiles directives in an unused
defaults were never checked.

This may prevent startup of haproxy with a configuration file previously
considered as valid. However, this change is considered as necessary to
be able to use http-errors with dynamic backends. Any invalid defaults
will be detected on startup, rather than having to discover it at
runtime via "add backend" invokation.

Thus, any restriction on http-errors usage is now lifted for the
creation of dynamic backends.
2026-03-23 11:14:07 +01:00