Commit Graph

6918 Commits

Author SHA1 Message Date
Roman Arutyunyan
3a97111adf HTTP/3: graceful shutdown on keepalive timeout expiration.
Previously, the expiration caused QUIC connection finalization even if
there are application-terminated streams finishing sending data.  Such
finalization terminated these streams.

An easy way to trigger this is to request a large file from HTTP/3 over
a small MTU.  In this case keepalive timeout expiration may abruptly
terminate the request stream.
2025-04-15 19:01:36 +04:00
Roman Arutyunyan
2b8b70068a QUIC: graph-friendly congestion control logging.
Improved logging for simpler data extraction for plotting congestion
window graphs.  In particular, added current milliseconds number from
ngx_current_msec.

While here, simplified logging text and removed irrelevant data.
2025-04-15 19:01:36 +04:00
Sergey Kandaurov
b6e7eb0f57 SSL: external groups support in $ssl_curve and $ssl_curves.
Starting with OpenSSL 3.0, groups may be added externally with pluggable
KEM providers.  Using SSL_get_negotiated_group(), which makes lookup in a
static table with known groups, doesn't allow to list such groups by names
leaving them in hex.  Adding X25519MLKEM768 to the default group list in
OpenSSL 3.5 made this problem more visible.  SSL_get0_group_name() and,
apparently, SSL_group_to_name() allow to resolve such provider-implemented
groups, which is also "generally preferred" over SSL_get_negotiated_group()
as documented in OpenSSL git commit 93d4f6133f.

This change makes external groups listing by name using SSL_group_to_name()
available since OpenSSL 3.0.  To preserve "prime256v1" naming for the group
0x0017, and to avoid breaking BoringSSL and older OpenSSL versions support,
it is used supplementary for a group that appears to be unknown.

See https://github.com/openssl/openssl/issues/27137 for related discussion.
2025-04-10 18:51:10 +04:00
Sergey Kandaurov
6c3a9d5612 Upstream: fixed passwords support for dynamic certificates.
Passwords were not preserved in optimized SSL contexts, the bug had
appeared in d791b4aab (1.23.1), as in the following configuration:

    server {
        proxy_ssl_password_file password;
        proxy_ssl_certificate $ssl_server_name.crt;
        proxy_ssl_certificate_key $ssl_server_name.key;

        location /original/ {
            proxy_pass https://u1/;
        }

        location /optimized/ {
            proxy_pass https://u2/;
        }
    }

The fix is to always preserve passwords, by copying to the configuration
pool, if dynamic certificates are used.  This is done as part of merging
"ssl_passwords" configuration.

To minimize the number of copies, a preserved version is then used for
inheritance.  A notable exception is inheritance of preserved empty
passwords to the context with statically configured certificates:

    server {
        proxy_ssl_certificate $ssl_server_name.crt;
        proxy_ssl_certificate_key $ssl_server_name.key;

        location / {
            proxy_pass ...;

            proxy_ssl_certificate example.com.crt;
            proxy_ssl_certificate_key example.com.key;
        }
    }

In this case, an unmodified version (NULL) of empty passwords is set,
to allow reading them from the password prompt on nginx startup.

As an additional optimization, a preserved instance of inherited
configured passwords is set to the previous level, to inherit it
to other contexts:

    server {
        proxy_ssl_password_file password;

        location /1/ {
            proxy_pass https://u1/;
            proxy_ssl_certificate $ssl_server_name.crt;
            proxy_ssl_certificate_key $ssl_server_name.key;
        }

        location /2/ {
            proxy_pass https://u2/;
            proxy_ssl_certificate $ssl_server_name.crt;
            proxy_ssl_certificate_key $ssl_server_name.key;
        }
    }
2025-04-10 17:27:45 +04:00
Sergey Kandaurov
a813c63921 Charset filter: improved validation of charset_map with utf-8.
It was possible to write outside of the buffer used to keep UTF-8
decoded values when parsing conversion table configuration.

Since this happened before UTF-8 decoding, the fix is to check in
advance if character codes are of more than 3-byte sequence.  Note
that this is already enforced by a later check for ngx_utf8_decode()
decoded values for 0xffff, which corresponds to the maximum value
encoded as a valid 3-byte sequence, so the fix does not affect the
valid values.

Found with AddressSanitizer.
Fixes GitHub issue #529.
2025-04-09 19:37:51 +04:00
Sergey Kandaurov
d313056537 Slice filter: improved memory allocation error handling.
As uncovered by recent addition in slice.t, a partially initialized
context, coupled with HTTP 206 response from stub backend, might be
accessed in the next slice subrequest.

Found by bad memory allocator simulation.
2025-03-10 19:32:07 +03:00
Sergey Kandaurov
d16251969b SSL: removed stale comments.
It appears to be a relic from prototype locking removed in b0b7b5a35.
2025-02-26 17:40:03 +04:00
Sergey Kandaurov
311c390377 SSL: improved logging of saving sessions from upstream servers.
This makes it easier to understand why sessions may not be saved
in shared memory due to size.
2025-02-26 17:40:03 +04:00
Sergey Kandaurov
9124592202 SSL: raised limit for sessions stored in shared memory.
Upstream SSL sessions may be of a noticeably larger size with tickets
in TLSv1.2 and older versions, or with "stateless" tickets in TLSv1.3,
if a client certificate is saved into the session.  Further, certain
stateless session resumption implemetations may store additional data.

Such one is JDK, known to also include server certificates in session
ticket data, which roughly doubles a decoded session size to slightly
beyond the previous limit.  While it's believed to be an issue on the
JDK side, this change allows to save such sessions.

Another, innocent case is using RSA certificates with 8192 key size.
2025-02-26 17:40:03 +04:00
Sergey Kandaurov
3d7304b527 SSL: using static storage for NGX_SSL_MAX_SESSION_SIZE buffers.
All such transient buffers are converted to the single storage in BSS.

In preparation to raise the limit.
2025-02-26 17:40:03 +04:00
Sergey Kandaurov
b11ae4cfc9 SSL: style. 2025-02-26 17:40:03 +04:00
batmanfr
67b26d8238
Add rate limit per hour "r/h"
Add the opportunity to apply rate limit by hour.
2025-02-24 17:30:16 +01:00
Sergey Kandaurov
d25139db01 Improved ngx_http_subrequest() error handling.
Some checks failed
buildbot / buildbot (push) Has been cancelled
Previously, request might be left in inconsistent state in case of error,
which manifested in "http request count is zero" alerts when used by SSI
filter.

The fix is to reshuffle initialization order to postpone committing state
changes until after any potentially failing parts.

Found by bad memory allocator simulation.
2025-02-21 00:04:12 +04:00
Piotr Sikora
9a4090f02a Core: fix build without libcrypt.
libcrypt is no longer part of glibc, so it might not be available.

Signed-off-by: Piotr Sikora <piotr@aviatrix.com>
2025-02-18 16:18:10 +03:00
Sergey Kandaurov
f274b3f72f Version bump. 2025-02-18 15:49:18 +04:00
Sergey Kandaurov
46b9f5d389 SNI: added restriction for TLSv1.3 cross-SNI session resumption.
In OpenSSL, session resumption always happens in the default SSL context,
prior to invoking the SNI callback.  Further, unlike in TLSv1.2 and older
protocols, SSL_get_servername() returns values received in the resumption
handshake, which may be different from the value in the initial handshake.
Notably, this makes the restriction added in b720f650b insufficient for
sessions resumed with different SNI server name.

Considering the example from b720f650b, previously, a client was able to
request example.org by presenting a certificate for example.org, then to
resume and request example.com.

The fix is to reject handshakes resumed with a different server name, if
verification of client certificates is enabled in a corresponding server
configuration.
2025-02-05 20:11:42 +04:00
Roman Arutyunyan
22a2a225ba Added "keepalive_min_timeout" directive.
Some checks are pending
buildbot / buildbot (push) Waiting to run
The directive sets a timeout during which a keepalive connection will
not be closed by nginx for connection reuse or graceful shutdown.

The change allows clients that send multiple requests over the same
connection without delay or with a small delay between them, to avoid
receiving a TCP RST in response to one of them.  This excludes network
issues and non-graceful shutdown.  As a side-effect, it also addresses
the TCP reset problem described in RFC 9112, Section 9.6, when the last
sent HTTP response could be damaged by a followup TCP RST.  It is important
for non-idempotent requests, which cannot be retried by client.

It is not recommended to set keepalive_min_timeout to large values as
this can introduce an additional delay during graceful shutdown and may
restrict nginx from effective connection reuse.
2025-02-05 13:08:01 +03:00
Aleksei Bavshin
64d0795ac4 QUIC: added missing casts in iov_base assignments.
Some checks failed
buildbot / buildbot (push) Has been cancelled
This is consistent with the rest of the code and fixes build on systems
with non-standard definition of struct iovec (Solaris, Illumos).
2025-01-28 08:00:42 -08:00
Pavel Pautov
5ab4f32e9d Upstream: fixed --with-compat build without SSL, broken by 454ad0e.
Some checks failed
buildbot / buildbot (push) Has been cancelled
2025-01-23 10:50:13 -08:00
Sergey Kandaurov
5d5d9adccf SSL: avoid using mismatched certificate/key cached pairs.
Some checks failed
buildbot / buildbot (push) Has been cancelled
This can happen with certificates and certificate keys specified
with variables due to partial cache update in various scenarios:
- cache expiration with only one element of pair evicted
- on-disk update with non-cacheable encrypted keys
- non-atomic on-disk update

The fix is to retry with fresh data on X509_R_KEY_VALUES_MISMATCH.
2025-01-17 04:37:46 +04:00
Sergey Kandaurov
454ad0ef33 Upstream: caching certificates and certificate keys with variables.
Caching is enabled with proxy_ssl_certificate_cache and friends.

Co-authored-by: Aleksei Bavshin <a.bavshin@nginx.com>
2025-01-17 04:37:46 +04:00
Sergey Kandaurov
4b96ad14f3 SSL: cache revalidation of file based dynamic certificates.
Revalidation is based on file modification time and uniq file index,
and happens after the cache object validity time is expired.
2025-01-17 04:37:46 +04:00
Sergey Kandaurov
0e756d67aa SSL: caching certificates and certificate keys with variables.
A new directive "ssl_certificate_cache max=N [valid=time] [inactive=time]"
enables caching of SSL certificate chain and secret key objects specified
by "ssl_certificate" and "ssl_certificate_key" directives with variables.

Co-authored-by: Aleksei Bavshin <a.bavshin@nginx.com>
2025-01-17 04:37:46 +04:00
Sergey Kandaurov
7677d5646a SSL: encrypted certificate keys are exempt from object cache.
SSL object cache, as previously introduced in 1.27.2, did not take
into account encrypted certificate keys that might be unexpectedly
fetched from the cache regardless of the matching passphrase.  To
avoid this, caching of encrypted certificate keys is now disabled
based on the passphrase callback invocation.

A notable exception is encrypted certificate keys configured without
ssl_password_file.  They are loaded once resulting in the passphrase
prompt on startup and reused in other contexts as applicable.
2025-01-17 04:37:46 +04:00
Sergey Kandaurov
8311e14ae6 SSL: object cache inheritance from the old configuration cycle.
Memory based objects are always inherited, engine based objects are
never inherited to adhere the volatile nature of engines, file based
objects are inherited subject to modification time and file index.

The previous behaviour to bypass cache from the old configuration cycle
is preserved with a new directive "ssl_object_cache_inheritable off;".
2025-01-17 04:37:46 +04:00
Daniel Vasquez Lopez
47f862ffad Slice filter: log the expected range in case of range error.
Some checks are pending
buildbot / buildbot (push) Waiting to run
2025-01-16 21:09:59 +04:00
Sergey Kandaurov
57d54fd922 Gzip: compatibility with recent zlib-ng 2.2.x versions.
Some checks failed
buildbot / buildbot (push) Has been cancelled
It now uses 5/4 times more memory for the pending buffer.

Further, a single allocation is now used, which takes additional 56 bytes
for deflate_allocs in 64-bit mode aligned to 16, to store sub-allocation
pointers, and the total allocation size now padded up to 128 bytes, which
takes theoretically 200 additional bytes in total.  This fits though into
"4 * (64 + sizeof(void*))" additional space for ZALLOC used in zlib-ng
2.1.x versions.  The comment was updated to reflect this.
2025-01-09 17:19:24 +04:00
Roman Arutyunyan
e3a9b6ad08 QUIC: fixed accessing a released stream.
Some checks failed
buildbot / buildbot (push) Has been cancelled
While trying to close a stream in ngx_quic_close_streams() by calling its
read event handler, the next stream saved prior to that could be destroyed
recursively.  This caused a segfault while trying to access the next stream.

The way the next stream could be destroyed in HTTP/3 is the following.
A request stream read event handler ngx_http_request_handler() could
end up calling ngx_http_v3_send_cancel_stream() to report a cancelled
request stream in the decoder stream.  If sending stream cancellation
decoder instruction fails for any reason, and the decoder stream is the
next in order after the request stream, the issue is triggered.

The fix is to postpone calling read event handlers for all streams being
closed to avoid closing a released stream.
2024-12-27 16:14:14 +04:00
Roman Arutyunyan
a52ba8ba0e QUIC: ignore version negotiation packets.
Some checks are pending
buildbot / buildbot (push) Waiting to run
Previously, such packets were treated as long header packets with unknown
version 0, and a version negotiation packet was sent in response.  This
could be used to set up an infinite traffic reflect loop with another nginx
instance.

Now version negotiation packets are ignored.  As per RFC 9000, Section 6.1:

  An endpoint MUST NOT send a Version Negotiation packet in response to
  receiving a Version Negotiation packet.
2024-12-26 18:58:05 +04:00
nandsky
930caed3bf QUIC: fixed client request timeout in 0-RTT scenarios.
Some checks failed
buildbot / buildbot (push) Has been cancelled
Since 0-RTT and 1-RTT data exist in the same packet number space,
ngx_quic_discard_ctx incorrectly discards 1-RTT packets when
0-RTT keys are discarded.

The issue was introduced by 58b92177e7.
2024-12-10 17:17:20 +04:00
Roman Arutyunyan
e28ef42b97 Version bump.
Some checks failed
buildbot / buildbot (push) Has been cancelled
2024-11-27 20:07:29 +04:00
Sergey Kandaurov
ce88b17123 Mail: handling of LOGIN IMAP command untagged response.
Some checks are pending
buildbot / buildbot (push) Waiting to run
In particular, an untagged CAPABILITY response as described in the
interim RFC 3501 internet drafts was seen in various IMAP servers.
Previously resulted in a broken connection, now an untagged response
is proxied to client.
2024-11-26 19:07:17 +04:00
Roman Arutyunyan
b2a67d2614 Realip: allowed square brackets with portless IPv6 address.
When client address is received, IPv6 address could be specified without
square brackets and without port, as well as both with the brackets and
port.  The change allows IPv6 in square brackets and no port, which was
previously considered an error.  This format conforms to RFC 3986.

The change also affects proxy_bind and friends.
2024-11-26 18:27:07 +04:00
Sergey Kandaurov
3f755b5a9e QUIC: got rid of memory copy when initializing constant values. 2024-11-26 17:41:21 +04:00
Sergey Kandaurov
9a025219f6 QUIC: constified nonce parameter of crypto functions.
This follows OpenSSL and BoringSSL API, and gives a hint to compiler
that this parameter may not be modified.
2024-11-26 17:41:21 +04:00
Sergey Kandaurov
a448dd52ee Upstream: disallow empty path in proxy_store and friends.
Some checks are pending
buildbot / buildbot (push) Waiting to run
Renaming a temporary file to an empty path ("") returns NGX_ENOPATH
with a subsequent ngx_create_full_path() to create the full path.
This function skips initial bytes as part of path separator lookup,
which causes out of bounds access on short strings.

The fix is to avoid renaming a temporary file to an obviously invalid
path, as well as explicitly forbid such syntax for literal values.

Although Coverity reports about potential type underflow, it is not
actually possible because the terminating '\0' is always included.

Notably, the run-time check is sufficient enough for Win32 as well.
Other short invalid values result either in NGX_ENOENT or NGX_EEXIST
and "MoveFile() .. failed" critical log messages, which involves a
separate error handling.

Prodded by Coverity (CID 1605485).
2024-11-25 17:37:11 +04:00
Roman Arutyunyan
0864cca4d7 QUIC: prevented BIO leak in case of error. 2024-11-25 16:22:40 +04:00
Sergey Kandaurov
476d6526b2 SSL: a new macro to set default protocol versions.
Some checks failed
buildbot / buildbot (push) Has been cancelled
This simplifies merging protocol values after ea15896 and ebd18ec.

Further, as outlined in ebd18ec18, for libraries preceeding TLSv1.2+
support, only meaningful versions TLSv1 and TLSv1.1 are set by default.

While here, fixed indentation.
2024-11-22 13:47:22 +04:00
Roman Arutyunyan
569948aa12 Mp4: prevent chunk index underflow.
Some checks are pending
buildbot / buildbot (push) Waiting to run
When cropping stsc atom, it's assumed that chunk index is never 0.
Based on this assumption, start_chunk and end_chunk are calculated
by subtracting 1 from it.  If chunk index is zero, start_chunk or
end_chunk may underflow, which will later trigger
"start/end time is out mp4 stco chunks" error.  The change adds an
explicit check for zero chunk index to avoid underflow and report
a proper error.

Zero chunk index is explicitly banned in ISO/IEC 14496-12, 8.7.4
Sample To Chunk Box.  It's also implicitly banned in QuickTime File
Format specification.  Description of chunk offset table references
"Chunk 1" as the first table element.
2024-11-21 16:08:48 +04:00
Roman Arutyunyan
d1a02451c3 Mp4: unordered stsc chunks error for the final chunk.
Currently an error is triggered if any of the chunk runs in stsc are
unordered.  This however does not include the final chunk run, which
ends with trak->chunks + 1.  The previous chunk index can be larger
leading to a 32-bit overflow.  This could allow to skip the validity
check "if (start_sample > n)".  This could later lead to a large
trak->start_chunk/trak->end_chunk, which would be caught later in
ngx_http_mp4_update_stco_atom() or ngx_http_mp4_update_co64_atom().

While there are no implications of the validity check being avoided,
the change still adds a check to ensure the final chunk run is ordered,
to produce a meaningful error and avoid a potential integer overflow.
2024-11-21 16:08:48 +04:00
Roman Arutyunyan
6ec099a378 Mp4: fixed handling an empty run of chunks in stsc atom.
A specially crafted mp4 file with an empty run of chunks in the stsc atom
and a large value for samples per chunk for that run, combined with a
specially crafted request, allowed to store that large value in prev_samples
and later in trak->end_chunk_samples while in ngx_http_mp4_crop_stsc_data().
Later in ngx_http_mp4_update_stsz_atom() this could result in buffer
overread while calculating trak->end_chunk_samples_size.

Now the value of samples per chunk specified for an empty run is ignored.
2024-11-21 16:08:48 +04:00
Nathan Mentze
cb1857407b Fixed missing double quote.
Some checks failed
buildbot / buildbot (push) Has been cancelled
2024-11-20 15:30:05 +04:00
Sergey Kandaurov
0ebc3242d9 SSL: error message default in object caching API.
Some checks are pending
buildbot / buildbot (push) Waiting to run
This change initializes the "err" variable, used to produce a meaningful
diagnostics on error path, to a good safe value.
2024-11-19 21:37:03 +04:00
Andy Pan
7cd60cd475 On DragonFly BSD 5.8+, TCP_KEEPIDLE and TCP_KEEPINTVL are in secs.
Some checks are pending
buildbot / buildbot (push) Waiting to run
2024-11-19 00:30:47 +04:00
Sergey Kandaurov
d10bf73eba Uwsgi: added create_loc_conf comments. 2024-11-12 17:21:22 +04:00
Sergey Kandaurov
1ac6a18585 SCGI: added create_loc_conf comments. 2024-11-12 17:21:22 +04:00
Sergey Kandaurov
a5e152b3d9 FastCGI: fixed create_loc_conf comments after 05b1a8f1e. 2024-11-12 17:21:22 +04:00
蕭澧邦
ea15896c1a SSL: fixed MSVC compilation after ebd18ec181.
Some checks are pending
buildbot / buildbot (push) Waiting to run
MSVC generates a compilation error in case #if/#endif is used in a macro
parameter.
2024-11-11 22:29:55 +04:00
Mini Hawthorne
29aec5720f Upstream: copy upstream zone DNS valid time during config reload.
Previously, all upstream DNS entries would be immediately re-resolved
on config reload.  With a large number of upstreams, this creates
a spike of DNS resolution requests.  These spikes can overwhelm the
DNS server or cause drops on the network.

This patch retains the TTL of previous resolutions across reloads
by copying each upstream's name's expiry time across configuration
cycles.  As a result, no additional resolutions are needed.
2024-11-07 07:57:42 -08:00
Vladimir Homutov
ea4654550a Upstream: per-upstream resolver.
The "resolver" and "resolver_timeout" directives can now be specified
directly in the "upstream" block.
2024-11-07 07:57:42 -08:00
Ruslan Ermilov
5ebe7a4122 Upstream: pre-resolve servers on reload.
After configuration is reloaded, it may take some time for the
re-resolvable upstream servers to resolve and become available
as peers.  During this time, client requests might get dropped.

Such servers are now pre-resolved using the "cache" of already
resolved peers from the old shared memory zone.
2024-11-07 07:57:42 -08:00
Ruslan Ermilov
1524c5e3fc Core: inheritance of non-reusable shared memory zones.
When re-creating a non-reusable zone, make the pointer to the old zone
available during the new zone initialization.
2024-11-07 07:57:42 -08:00
Dmitry Volyntsev
9fe119b431 Upstream: construct upstream peers from DNS SRV records. 2024-11-07 07:57:42 -08:00
Ruslan Ermilov
db6870e06d Upstream: re-resolvable servers.
Specifying the upstream server by a hostname together with the
"resolve" parameter will make the hostname to be periodically
resolved, and upstream servers added/removed as necessary.

This requires a "resolver" at the "http" configuration block.

The "resolver_timeout" parameter also affects when the failed
DNS requests will be attempted again.  Responses with NXDOMAIN
will be attempted again in 10 seconds.

Upstream has a configuration generation number that is incremented each
time servers are added/removed to the primary/backup list.  This number
is remembered by the peer.init method, and if peer.get detects a change
in configuration, it returns NGX_BUSY.

Each server has a reference counter.  It is incremented by peer.get and
decremented by peer.free.  When a server is removed, it is removed from
the list of servers and is marked as "zombie".  The memory allocated by
a zombie peer is freed only when its reference count becomes zero.

Co-authored-by: Roman Arutyunyan <arut@nginx.com>
Co-authored-by: Sergey Kandaurov <pluknet@nginx.com>
Co-authored-by: Vladimir Homutov <vl@nginx.com>
2024-11-07 07:57:42 -08:00
Sergey Kandaurov
ebd18ec181 SSL: disabled TLSv1 and TLSv1.1 by default.
TLSv1 and TLSv1.1 are formally deprecated and forbidden to negotiate due
to insufficient security reasons outlined in RFC 8996.

TLSv1 and TLSv1.1 are disabled in BoringSSL e95b0cad9 and LibreSSL 3.8.1
in the way they cannot be enabled in nginx configuration.  In OpenSSL 3.0,
they are only permitted at security level 0 (disabled by default).

The support is dropped in Chrome 84, Firefox 78, and deprecated in Safari.

This change disables TLSv1 and TLSv1.1 by default for OpenSSL 1.0.1 and
newer, where TLSv1.2 support is available.  For older library versions,
which do not have alternatives, these protocol versions remain enabled.
2024-10-31 19:49:00 +04:00
nandsky
3f6d94d888 QUIC: prevent deleted stream frame retransmissions.
Since a2a513b93c, stream frames no longer need to be retransmitted after it
was deleted.  The frames which were retransmitted before, could be stream data
frames sent prior to a RESET_STREAM. Such retransmissions are explicitly
prohibited by RFC 9000, Section 19.4.
2024-10-08 19:55:14 +04:00
Sergey Kandaurov
144778aee6 Version bump. 2024-10-08 18:29:01 +04:00
Sergey Kandaurov
5917e9de5a SSL: caching CA certificates.
This can potentially provide a large amount of savings,
because CA certificates can be quite large.

Based on previous work by Mini Hawthorne.
2024-10-01 17:59:24 +04:00
Sergey Kandaurov
61314518de SSL: caching CRLs.
Based on previous work by Mini Hawthorne.
2024-10-01 17:59:24 +04:00
Sergey Kandaurov
7ea2fb6cb1 SSL: caching certificate keys.
EVP_KEY objects are a reference-counted container for key material, shallow
copies and OpenSSL stack management aren't needed as with certificates.

Based on previous work by Mini Hawthorne.
2024-10-01 17:59:24 +04:00
Sergey Kandaurov
78ed123e71 SSL: caching certificates.
Certificate chains are now loaded once.

The certificate cache provides each chain as a unique stack of reference
counted elements.  This shallow copy is required because OpenSSL stacks
aren't reference counted.

Based on previous work by Mini Hawthorne.
2024-10-01 17:59:24 +04:00
Sergey Kandaurov
7d7e8d2cb8 SSL: object caching.
Added ngx_openssl_cache_module, which indexes a type-aware object cache.
It maps an id to a unique instance, and provides references to it, which
are dropped when the cycle's pool is destroyed.

The cache will be used in subsequent patches.

Based on previous work by Mini Hawthorne.
2024-10-01 17:59:24 +04:00
Sergey Kandaurov
f36ff3550a SSL: moved certificate storage out of exdata.
Instead of cross-linking the objects using exdata, pointers to configured
certificates are now stored in ngx_ssl_t, and OCSP staples are now accessed
with rbtree in it.  This allows sharing these objects between SSL contexts.

Based on previous work by Mini Hawthorne.
2024-10-01 17:59:24 +04:00
tzssangglass
51857ce404 Fixed a typo of bpf makefile debug option. 2024-09-24 18:58:30 +04:00
Sergey Kandaurov
18afcda938 SSL: optional ssl_client_certificate for ssl_verify_client.
Starting from TLSv1.1 (as seen since draft-ietf-tls-rfc2246-bis-00),
the "certificate_authorities" field grammar of the CertificateRequest
message was redone to allow no distinguished names.  In TLSv1.3, with
the restructured CertificateRequest message, this can be similarly
done by optionally including the "certificate_authorities" extension.
This allows to avoid sending DNs at all.

In practice, aside from published TLS specifications, all supported
SSL/TLS libraries allow to request client certificates with an empty
DN list for any protocol version.  For instance, when operating in
TLSv1, this results in sending the "certificate_authorities" list as
a zero-length vector, which corresponds to the TLSv1.1 specification.
Such behaviour goes back to SSLeay.

The change relaxes the requirement to specify at least one trusted CA
certificate in the ssl_client_certificate directive, which resulted in
sending DNs of these certificates (closes #142).  Instead, all trusted
CA certificates can be specified now using the ssl_trusted_certificate
directive if needed.  A notable difference that certificates specified
in ssl_trusted_certificate are always loaded remains (see 3648ba7db).

Co-authored-by: Praveen Chaudhary <praveenc@nvidia.com>
2024-09-20 14:43:00 +04:00
Sergey Kandaurov
1a64c196a7 Proxy: proxy_pass_trailers directive.
The directive allows to pass upstream response trailers to client.
2024-09-13 16:47:56 +04:00
Sergey Kandaurov
fb89d50eeb Stream: OCSP stapling. 2024-08-22 14:57:46 +04:00
Sergey Kandaurov
581cf22673 Stream: client certificate validation with OCSP. 2024-08-22 14:57:45 +04:00
Sergey Kandaurov
48ac1ee9c6 Version bump. 2024-08-20 21:18:30 +04:00
Roman Arutyunyan
88955b1044 Mp4: rejecting unordered chunks in stsc atom.
Unordered chunks could result in trak->end_chunk smaller than trak->start_chunk
in ngx_http_mp4_crop_stsc_data().  Later in ngx_http_mp4_update_stco_atom()
this caused buffer overread while trying to calculate trak->end_offset.
2024-08-12 18:20:45 +04:00
Roman Arutyunyan
7362d01658 Mp4: fixed buffer underread while updating stsz atom.
While cropping an stsc atom in ngx_http_mp4_crop_stsc_data(), a 32-bit integer
overflow could happen, which could result in incorrect seeking and a very large
value stored in "samples".  This resulted in a large invalid value of
trak->end_chunk_samples.  This value is further used to calculate the value of
trak->end_chunk_samples_size in ngx_http_mp4_update_stsz_atom().  While doing
this, a large invalid value of trak->end_chunk_samples could result in reading
memory before stsz atom start.  This could potentially result in a segfault.
2024-08-12 18:20:43 +04:00
Sergey Kandaurov
0fa8434957 Stream ssl_preread: do not reallocate a parsed SNI host.
We own this memory from the session pool.
2024-08-09 19:12:26 +04:00
Sergey Kandaurov
504c78fc6d QUIC: zero out existing keying material only.
Previously, this used to have extra ngx_explicit_memzero() calls
from within ngx_quic_keys_cleanup(), which might be suboptimal.
2024-08-09 19:12:26 +04:00
Sergey Kandaurov
58b92177e7 QUIC: discarding 0-RTT keys.
For simplicity, this is done on successful decryption of a 1-RTT packet.
2024-08-09 19:12:25 +04:00
Sergey Kandaurov
6ecc4e3807 Version bump. 2024-08-09 18:01:42 +04:00
Kasei Wang
145b228530 HTTP/2: close connections initialized during graceful shutdown.
In some rare cases, graceful shutdown may happen while initializing an HTTP/2
connection.  Previously, such a connection ignored the shutdown and remained
active.  Now it is gracefully closed prior to processing any streams to
eliminate the shutdown delay.
2024-07-18 17:43:25 +04:00
Roman Arutyunyan
788e462c5b Stream: allow servers with no handler.
Previously handlers were mandatory.  However they are not always needed.
For example, a server configured with ssl_reject_handshake does not need a
handler.  Such servers required a fake handler to pass the check.  Now handler
absence check is moved to runtime.  If handler is missing, the connection is
closed with 500 code.
2024-06-27 17:29:56 +04:00
Sergey Kandaurov
34bd899287 HTTP/3: fixed handling of zero-length literal field line.
Previously, st->value was passed with NULL data pointer to header handlers.
2024-05-28 17:20:45 +04:00
Roman Arutyunyan
9ddc6a08f4 QUIC: ngx_quic_buffer_t use-after-free protection.
Previously the last chain field of ngx_quic_buffer_t could still reference freed
chains and buffers after calling ngx_quic_free_buffer().  While normally an
ngx_quic_buffer_t object should not be used after freeing, resetting last_chain
field would prevent a potential use-after-free.
2024-05-28 17:19:21 +04:00
Roman Arutyunyan
6f8c520f49 QUIC: ignore CRYPTO frames after handshake completion.
Sending handshake-level CRYPTO frames after the client's Finished message could
lead to memory disclosure and a potential segfault, if those frames are sent in
one packet with the Finished frame.
2024-05-28 17:19:08 +04:00
Roman Arutyunyan
cca5655dd9 HTTP/3: fixed dynamic table overflow.
While inserting a new entry into the dynamic table, first the entry is added,
and then older entries are evicted until table size is within capacity.  After
the first step, the number of entries may temporarily exceed the maximum
calculated from capacity by one entry, which previously caused table overflow.

The easiest way to trigger the issue is to keep adding entries with empty names
and values until first eviction.

The issue was introduced by 987bee4363d1.
2024-05-28 17:18:50 +04:00
Roman Arutyunyan
0fd59c8b56 HTTP/3: decoder stream pre-creation.
Previously a decoder stream was created on demand for sending Section
Acknowledgement, Stream Cancellation and Insert Count Increment.  If conditions
for sending any of these instructions never happen, a decoder stream is not
created at all.  These conditions include client not using the dynamic table and
no streams abandoned by server (RFC 9204, Section 2.2.2.2).  However RFC 9204,
Section 4.2 defines only one condition for not creating a decoder stream:

   An endpoint MAY avoid creating a decoder stream if its decoder sets
   the maximum capacity of the dynamic table to zero.

The change enables pre-creation of the decoder stream at HTTP/3 session
initialization if maximum dynamic table capacity is not zero.  Note that this
value is currently hardcoded to 4096 bytes and is not configurable, so the
stream is now always created.

Also, the change fixes a potential stack overflow when creating a decoder
stream in ngx_http_v3_send_cancel_stream() while draining a request stream by
ngx_drain_connections().  Creating a decoder stream involves calling
ngx_get_connection(), which calls ngx_drain_connections(), which will drain the
same request stream again.  If client's MAX_STREAMS for uni stream is high
enough, these recursive calls will continue until we run out of stack.
Otherwise, decoder stream creation will fail at some point and the request
stream connection will be drained.  This may result in use-after-free, since
this connection could still be referenced up the stack.
2024-05-28 17:18:28 +04:00
Sergey Kandaurov
683e304e8b QUIC: client transport parameter data length checking. 2024-05-28 17:17:19 +04:00
J Carter
71ca978a35 Upstream: variables support in proxy_limit_rate and friends. 2023-11-25 21:57:09 +00:00
Roman Arutyunyan
ea8270c614 Optimized chain link usage (ticket #2614).
Previously chain links could sometimes be dropped instead of being reused,
which could result in increased memory consumption during long requests.

A similar chain link issue in ngx_http_gzip_filter_module was fixed in
da46bfc484ef (1.11.10).

Based on a patch by Sangmin Lee.
2024-05-23 19:15:38 +04:00
Roman Arutyunyan
489e1e6191 Stream pass: disabled passing from or to udp.
Passing from udp was not possible for the most part due to preread buffer
restriction.  Passing to udp could occasionally work, but the connection would
still be bound to the original listen rbtree, which prevented it from being
deleted on connection closure.
2024-05-03 20:26:05 +04:00
Sergey Kandaurov
6f7494081a SSL: fixed possible configuration overwrite loading "engine:" keys.
When loading certificate keys via ENGINE_load_private_key() in runtime,
it was possible to overwrite configuration on ENGINE_by_id() failure.
OpenSSL documention doesn't describe errors in details, the only reason
I found in the comment to example is when the engine is not available.
2024-05-03 20:29:01 +04:00
Sergey Kandaurov
a7e3cd52e0 HTTP/3: fixed handling of malformed request body length.
Previously, a request body larger than declared in Content-Length resulted in
a 413 status code, because Content-Length was mistakenly used as the maximum
allowed request body, similar to client_max_body_size.  Following the HTTP/3
specification, such requests are now rejected with the 400 error as malformed.
2024-05-03 20:28:32 +04:00
Sergey Kandaurov
3f0fe15a98 Version bump. 2024-05-03 20:28:22 +04:00
Roman Arutyunyan
bf3e6538b9 Stream pass: limited the number of passes per connection.
Previously a cycle in pass configuration resulted in stack overflow.
2024-04-11 11:37:30 +04:00
Vladimir Khomutov
92f9968571 QUIC: fixed close timer processing with early data.
The ngx_quic_run() function uses qc->close timer to limit the handshake
duration.  Normally it is removed by ngx_quic_do_init_streams() which is
called once when we are done with initial SSL processing.

The problem happens when the client sends early data and streams are
initialized in the ngx_quic_run() -> ngx_quic_handle_datagram() call.
The order of set/remove timer calls is now reversed; the close timer is
set up and the timer fires when assigned, starting the unexpected connection
close process.

The fix is to skip setting the timer if streams were initialized during
handling of the initial datagram.  The idle timer for quic is set anyway,
and stream-related timeouts are managed by application layer.
2024-04-10 09:38:10 +03:00
Piotr Sikora
1bc19fe2db Detect cache line size at runtime on macOS.
Notably, Apple Silicon CPUs have 128 byte cache line size,
which is twice the default configured for generic aarch64.

Signed-off-by: Piotr Sikora <piotr@aviatrix.com>
2024-02-26 20:00:40 +00:00
Piotr Sikora
eff2ea1d69 Win32: fixed unique file index calculations.
The old code was breaking strict aliasing rules.

Signed-off-by: Piotr Sikora <piotr@aviatrix.com>
2024-02-26 20:00:35 +00:00
Piotr Sikora
2f9e8431e6 Rewrite: fixed "return" directive without response text.
Previously, the response text wasn't initialized and the rewrite module
was sending response body set to NULL.

Found with UndefinedBehaviorSanitizer (pointer-overflow).

Signed-off-by: Piotr Sikora <piotr@aviatrix.com>
2024-02-26 20:00:28 +00:00
Sergey Kandaurov
3d5a356abb Fixed undefined behaviour with IPv4-mapped IPv6 addresses.
Previously, it could result when left-shifting signed integer due to implicit
integer promotion, such that the most significant bit appeared on the sign bit.

In practice, though, this results in the same left value as with an explicit
cast, at least on known compilers, such as GCC and Clang.  The reason is that
in_addr_t, which is equivalent to uint32_t and same as "unsigned int" in ILP32
and LP64 data type models, has the same type width as the intermediate after
integer promotion, so there's no side effects such as sign-extension.  This
explains why adding an explicit cast does not change object files in practice.

Found with UndefinedBehaviorSanitizer (shift).

Based on a patch by Piotr Sikora.
2024-03-18 17:14:30 +04:00
Piotr Sikora
d3d64cacb3 Geo: fixed uninitialized memory access.
While copying ngx_http_variable_value_t structures to geo binary base
in ngx_http_geo_copy_values(), and similarly in the stream module,
uninitialized parts of these structures are copied as well.  These
include the "escape" field and possible holes.  Calculating crc32 of
this data triggers uninitialized memory access.

Found with MemorySanitizer.

Signed-off-by: Piotr Sikora <piotr@aviatrix.com>
2024-03-14 18:37:20 +04:00
Sergey Kandaurov
5e79d98a59 Stream: $server_name. 2024-03-22 18:39:50 +04:00
Roman Arutyunyan
45e166b4a4 Stream: moved fastopen compatibility check.
The move makes the code look similar to the corresponding code in http module.
2024-01-18 19:12:38 +04:00
Sergey Kandaurov
bd190d825c Stream: the "setfib" parameter of the "listen" directive.
The FreeBSD SO_SETFIB support.
2024-03-22 14:53:19 +04:00
Sergey Kandaurov
04b9bfe55d Stream: the "accept_filter" parameter of the "listen" directive.
The FreeBSD accept filters support.
2024-03-22 14:53:19 +04:00