Commit Graph

438 Commits

Author SHA1 Message Date
Maxim Dounin
8772a0e089 SSL: passwords support for dynamic certificate loading.
Passwords have to be copied to the configuration pool to be used
at runtime.  Also, to prevent blocking on stdin (with "daemon off;")
an empty password list is provided.

To make things simpler, password handling was modified to allow
an empty array (with 0 elements and elts set to NULL) as an equivalent
of an array with 1 empty password.
2019-02-25 16:42:23 +03:00
Maxim Dounin
6e5a731edb SSL: variables support in ssl_certificate and ssl_certificate_key.
To evaluate variables, a request is created in the certificate callback,
and then freed.  To do this without side effects on the stub_status
counters and connection state, an additional function was introduced,
ngx_http_alloc_request().

Only works with OpenSSL 1.0.2+, since there is no SSL_CTX_set_cert_cb()
in older versions.
2019-02-25 16:42:05 +03:00
Maxim Dounin
dce5823f59 Style. 2019-02-25 16:41:08 +03:00
Maxim Dounin
53803b4780 SSL: fixed segfault on renegotiation (ticket #1646).
In e3ba4026c02d (1.15.4) nginx own renegotiation checks were disabled
if SSL_OP_NO_RENEGOTIATION is available.  But since SSL_OP_NO_RENEGOTIATION
is only set on a connection, not in an SSL context, SSL_clear_option()
removed it as long as a matching virtual server was found.  This resulted
in a segmentation fault similar to the one fixed in a6902a941279 (1.9.8),
affecting nginx built with OpenSSL 1.1.0h or higher.

To fix this, SSL_OP_NO_RENEGOTIATION is now explicitly set in
ngx_http_ssl_servername() after adjusting options.  Additionally, instead
of c->ssl->renegotiation we now check c->ssl->handshaked, which seems
to be a more correct flag to test, and will prevent the segmentation fault
from happening even if SSL_OP_NO_RENEGOTIATION is not working.
2018-10-02 17:46:18 +03:00
Maxim Dounin
e4a3211e2f Fixed socket leak with "return 444" in error_page (ticket #274).
Socket leak was observed in the following configuration:

    error_page 400 = /close;

    location = /close {
        return 444;
    }

The problem is that "return 444" triggers termination of the request,
and due to error_page termination thinks that it needs to use a posted
request to clear stack.  But at the early request processing where 400
errors are generated there are no ngx_http_run_posted_requests() calls,
so the request is only terminated after an external event.

Variants of the problem include "error_page 497" instead (ticket #695)
and various other errors generated during early request processing
(405, 414, 421, 494, 495, 496, 501, 505).

The same problem can be also triggered with "return 499" and "return 408"
as both codes trigger ngx_http_terminate_request(), much like "return 444".

To fix this, the patch adds ngx_http_run_posted_requests() calls to
ngx_http_process_request_line() and ngx_http_process_request_headers()
functions, and to ngx_http_v2_run_request() and ngx_http_v2_push_stream()
functions in HTTP/2.

Since the ngx_http_process_request() function is now only called via
other functions which call ngx_http_run_posted_requests(), the call
there is no longer needed and was removed.
2018-09-21 15:59:30 +03:00
Maxim Dounin
278be041dd Lingering close changed to handle NGX_AGAIN.
The "do { c->recv() } while (c->read->ready)" form used in the
ngx_http_lingering_close_handler() is not really correct, as for
example with SSL c->read->ready may be still set when returning NGX_AGAIN
due to SSL_ERROR_WANT_WRITE.  Therefore the above might be an infinite loop.

This doesn't really matter in lingering close, as we shutdown write side
of the socket anyway and also disable renegotiation (and even without shutdown
and with renegotiation it requires using very large certificate chain and
tuning socket buffers to trigger SSL_ERROR_WANT_WRITE).  But for the sake of
correctness added an NGX_AGAIN check.
2018-09-10 18:57:13 +03:00
Maxim Dounin
1456129902 SSL: fixed SSL_clear_options() usage with OpenSSL 1.1.0+.
In OpenSSL 1.1.0 the SSL_CTRL_CLEAR_OPTIONS macro was removed, so
conditional compilation test on it results in SSL_clear_options()
and SSL_CTX_clear_options() not being used.  Notably, this caused
"ssl_prefer_server_ciphers off" to not work in SNI-based virtual
servers if server preference was switched on in the default server.

It looks like the only possible fix is to test OPENSSL_VERSION_NUMBER
explicitly.
2018-07-16 17:47:20 +03:00
Ruslan Ermilov
527cac2979 Allow resetting connections closed by "return 444" (ticket #905).
If reset_timedout_connection is on, TCP connections closed by
"return 444" will be reset instead of a normal close.
2018-07-12 12:50:20 +03:00
Ruslan Ermilov
f11a9cbdd0 Added r->schema.
For HTTP/1, it keeps scheme from the absolute form of URI.
For HTTP/2, the :scheme request pseudo-header field value.
2018-06-07 20:01:41 +03:00
Ruslan Ermilov
70b6e7a299 Removed extraneous check while processing request line. 2018-06-07 19:53:43 +03:00
Maxim Dounin
76be1ea9de SSL: detect "listen ... ssl" without certificates (ticket #178).
In mail and stream modules, no certificate provided is a fatal condition,
much like with the "ssl" and "starttls" directives.

In http, "listen ... ssl" can be used in a non-default server without
certificates as long as there is a certificate in the default one, so
missing certificate is only fatal for default servers.
2018-04-24 15:29:01 +03:00
Maxim Dounin
6a0d9e5b2d gRPC: special handling of the TE request header.
According to the gRPC protocol specification, the "TE" header is used
to detect incompatible proxies, and at least grpc-c server rejects
requests without "TE: trailers".

To preserve the logic, we have to pass "TE: trailers" to the backend if
and only if the original request contains "trailers" in the "TE" header.
Note that no other TE values are allowed in HTTP/2, so we have to remove
anything else.
2018-03-17 23:04:25 +03:00
Ruslan Ermilov
8a84dd4f32 Expose more headers with NGX_HTTP_HEADERS. 2018-02-15 17:51:26 +03:00
Sergey Kandaurov
57dde2ab37 SSL: using default server context in session remove (closes #1464).
This fixes segfault in configurations with multiple virtual servers sharing
the same port, where a non-default virtual server block misses certificate.
2018-01-30 17:46:31 +03:00
Maxim Dounin
b32cb6b610 Fixed worker_shutdown_timeout in various cases.
The ngx_http_upstream_process_upgraded() did not handle c->close request,
and upgraded connections do not use the write filter.  As a result,
worker_shutdown_timeout did not affect upgraded connections (ticket #1419).
Fix is to handle c->close in the ngx_http_request_handler() function, thus
covering most of the possible cases in http handling.

Additionally, mail proxying did not handle neither c->close nor c->error,
and thus worker_shutdown_timeout did not work for mail connections.  Fix is
to add c->close handling to ngx_mail_proxy_handler().

Also, added explicit handling of c->close to stream proxy,
ngx_stream_proxy_process_connection().  This improves worker_shutdown_timeout
handling in stream, it will no longer wait for some data being transferred
in a connection before closing it, and will also provide appropriate
logging at the "info" level.
2017-11-20 16:31:07 +03:00
Piotr Sikora
cfdce50657 Added support for trailers in HTTP responses.
Example:

   ngx_table_elt_t  *h;

   h = ngx_list_push(&r->headers_out.trailers);
   if (h == NULL) {
       return NGX_ERROR;
   }

   ngx_str_set(&h->key, "Fun");
   ngx_str_set(&h->value, "with trailers");
   h->hash = ngx_hash_key_lc(h->key.data, h->key.len);

The code above adds "Fun: with trailers" trailer to the response.

Modules that want to emit trailers must set r->expect_trailers = 1
in header filter, otherwise they might not be emitted for HTTP/1.1
responses that aren't already chunked.

This change also adds $sent_trailer_* variables.

Signed-off-by: Piotr Sikora <piotrsikora@google.com>
2017-03-24 03:37:34 -07:00
Roman Arutyunyan
d1d48ed844 Fixed background requests with asynchronous operations.
If the main request was finalized while a background request performed an
asynchronous operation, the main request ended up in ngx_http_writer() and was
not finalized until a network event or a timeout.  For example, cache
background update with aio enabled made nginx unable to process further client
requests or close the connection, keeping it open until client closes it.

Now regular finalization of the main request is not suspended because of an
asynchronous operation in another request.

If a background request was terminated while an asynchronous operation was in
progress, background request's write event handler was changed to
ngx_http_request_finalizer() and never called again.

Now, whenever a request is terminated while an asynchronous operation is in
progress, connection error flag is set to make further finalizations of any
request with this connection lead to termination.

These issues appeared in 1aeaae6e9446 (not yet released).
2017-05-29 23:33:38 +03:00
Maxim Dounin
2db69fed2c SSL: set TCP_NODELAY on SSL connections before handshake.
With OpenSSL 1.1.0+, the workaround for handshake buffer size as introduced
in a720f0b0e083 (ticket #413) no longer works, as OpenSSL no longer exposes
handshake buffers, see https://github.com/openssl/openssl/commit/2e7dc7cd688.
Moreover, it is no longer possible to adjust handshake buffers at all now.

To avoid additional RTT if handshake uses more than 4k we now set TCP_NODELAY
on SSL connections before handshake.  While this still results in sub-optimal
network utilization due to incomplete packets being sent, it seems to be
better than nothing.
2017-05-29 16:34:29 +03:00
Ruslan Ermilov
b66c18d2d5 Introduced ngx_tcp_nodelay(). 2017-05-26 22:52:48 +03:00
Roman Arutyunyan
8644d9491a Background subrequests for cache updates.
Previously, cache background update might not work as expected, making client
wait for it to complete before receiving the final part of a stale response.
This could happen if the response could not be sent to the client socket in one
filter chain call.

Now background cache update is done in a background subrequest.  This type of
subrequest does not block any other subrequests or the main request.
2017-05-25 15:57:59 +03:00
Ruslan Ermilov
8ae2bc9320 Don't pretend we support HTTP major versions >1 as HTTP/1.1. 2017-04-25 23:39:13 +03:00
hucongcong
9ac9fe2f3e Fixed type. 2017-04-03 14:29:40 +08:00
Maxim Dounin
5d5f0dcac4 Moved handling of wev->delayed to the connection event handler.
With post_action or subrequests, it is possible that the timer set for
wev->delayed will expire while the active subrequest write event handler
is not ready to handle this.  This results in request hangs as observed
with limit_rate / sendfile_max_chunk and post_action (ticket #776) or
subrequests (ticket #1228).

Moving the handling to the connection event handler fixes the hangs observed,
and also slightly simplifies the code.
2017-04-02 14:32:29 +03:00
Maxim Dounin
77bac4d57c Fixed CPU hog while freeing hc->busy after e662cbf1b932 (1.11.11).
Reported by Richard Stanway,
http://mailman.nginx.org/pipermail/nginx/2017-March/053296.html.
2017-03-24 16:26:12 +03:00
Maxim Dounin
fca26c2e53 Converted hc->busy/hc->free to use chain links.
Most notably, this fixes possible buffer overflows if number of large
client header buffers in a virtual server is different from the one in
the default server.

Reported by Daniil Bondarev.
2017-03-07 18:49:31 +03:00
Maxim Dounin
4abafc85d6 SSL: fixed ssl_buffer_size on SNI virtual hosts (ticket #1192).
Previously, buffer size was not changed from the one saved during
initial ngx_ssl_create_connection(), even if the buffer itself was not
yet created.  Fix is to change c->ssl->buffer_size in the SNI callback.

Note that it should be also possible to update buffer size even in non-SNI
virtual hosts as long as the buffer is not yet allocated.  This looks
like an overcomplication though.
2017-02-02 20:29:16 +03:00
Valentin Bartenev
46336296e4 Fixed an error log message. 2016-06-07 17:44:20 +03:00
Valentin Bartenev
f7673bb50f HTTP/2: the "421 Misdirected Request" response (closes #848).
Since 4fbef397c753 nginx rejects with the 400 error any attempts of
requesting different host over the same connection, if the relevant
virtual server requires verification of a client certificate.

While requesting hosts other than negotiated isn't something legal
in HTTP/1.x, the HTTP/2 specification explicitly permits such requests
for connection reuse and has introduced a special response code 421.

According to RFC 7540 Section 9.1.2 this code can be sent by a server
that is not configured to produce responses for the combination of
scheme and authority that are included in the request URI.  And the
client may retry the request over a different connection.

Now this code is used for requests that aren't authorized in current
connection.  After receiving the 421 response a client will be able
to open a new connection, provide the required certificate and retry
the request.

Unfortunately, not all clients currently are able to handle it well.
Notably Chrome just shows an error, while at least the latest version
of Firefox retries the request over a new connection.
2016-05-20 18:41:17 +03:00
Maxim Dounin
099d74cf3d Dav: return 501 on PUT with ranges (ticket #948). 2016-05-16 20:37:23 +03:00
Valentin Bartenev
12f4367189 Improved EPOLLRDHUP handling.
When it's known that the kernel supports EPOLLRDHUP, there is no need in
additional recv() call to get EOF or error when the flag is absent in the
event generated by the kernel.  A special runtime test is done at startup
to detect if EPOLLRDHUP is actually supported by the kernel because
epoll_ctl() silently ignores unknown flags.

With this knowledge it's now possible to drop the "ready" flag for partial
read.  Previously, the "ready" flag was kept until the recv() returned EOF
or error.  In particular, this change allows the lingering close heuristics
(which relies on the "ready" flag state) to actually work on Linux, and not
wait for more data in most cases.

The "available" flag is now used in the read event with the semantics similar
to the corresponding counter in kqueue.
2016-05-13 17:19:23 +03:00
Sergey Kandaurov
00ef9ff5f0 Fixed logging. 2016-03-31 02:33:57 +03:00
Valentin Bartenev
f72bcf8285 HTTP/2: implemented per request timeouts (closes #626).
Previously, there were only three timeouts used globally for the whole HTTP/2
connection:

 1. Idle timeout for inactivity when there are no streams in processing
    (the "http2_idle_timeout" directive);

 2. Receive timeout for incomplete frames when there are no streams in
    processing (the "http2_recv_timeout" directive);

 3. Send timeout when there are frames waiting in the output queue
    (the "send_timeout" directive on a server level).

Reaching one of these timeouts leads to HTTP/2 connection close.

This left a number of scenarios when a connection can get stuck without any
processing and timeouts:

 1. A client has sent the headers block partially so nginx starts processing
    a new stream but cannot continue without the rest of HEADERS and/or
    CONTINUATION frames;

 2. When nginx waits for the request body;

 3. All streams are stuck on exhausted connection or stream windows.

The first idea that was rejected was to detect when the whole connection
gets stuck because of these situations and set the global receive timeout.
The disadvantage of such approach would be inconsistent behaviour in some
typical use cases.  For example, if a user never replies to the browser's
question about where to save the downloaded file, the stream will be
eventually closed by a timeout.  On the other hand, this will not happen
if there's some activity in other concurrent streams.

Now almost all the request timeouts work like in HTTP/1.x connections, so
the "client_header_timeout", "client_body_timeout", and "send_timeout" are
respected.  These timeouts close the request.

The global timeouts work as before.

Previously, the c->write->delayed flag was abused to avoid setting timeouts on
stream events.  Now, the "active" and "ready" flags are manipulated instead to
control the processing of individual streams.
2016-02-24 15:58:07 +03:00
Valentin Bartenev
1d294eea3e Fixed buffer over-read while logging invalid request headers.
Since 667aaf61a778 (1.1.17) the ngx_http_parse_header_line() function can return
NGX_HTTP_PARSE_INVALID_HEADER when a header contains NUL character.  In this
case the r->header_end pointer isn't properly initialized, but the log message
in ngx_http_process_request_headers() hasn't been adjusted.  It used the pointer
in size calculation, which might result in up to 2k buffer over-read.

Found with afl-fuzz.
2016-02-24 16:01:23 +03:00
Sergey Kandaurov
79fcf261d0 SSL: fixed possible segfault on renegotiation (ticket #845).
Skip SSL_CTX_set_tlsext_servername_callback in case of renegotiation.
Do nothing in SNI callback as in this case it will be supplied with
request in c->data which isn't expected and doesn't work this way.

This was broken by b40af2fd1c16 (1.9.6) with OpenSSL master branch and LibreSSL.
2015-12-08 16:59:43 +03:00
Ruslan Ermilov
5ea66922d9 Style: unified request method checks. 2015-11-06 15:22:43 +03:00
Valentin Bartenev
93aef089b4 SSL: only select HTTP/2 using NPN if "http2" is enabled.
OpenSSL doesn't check if the negotiated protocol has been announced.
As a result, the client might force using HTTP/2 even if it wasn't
enabled in configuration.
2015-11-05 15:01:09 +03:00
Valentin Bartenev
ee37ff613f The HTTP/2 implementation (RFC 7240, 7241).
The SPDY support is removed, as it's incompatible with the new module.
2015-09-11 20:13:06 +03:00
Valentin Bartenev
0d3b15729c Limit recursive subrequests instead of simultaneous. 2015-08-23 21:03:32 +03:00
Roman Arutyunyan
4404c3fd6d Core: renamed ngx_proxy_protocol_parse to ngx_proxy_protocol_read.
The new name is consistent with the ngx_proxy_protocol_write function.
2015-06-16 13:45:19 +03:00
Vladimir Homutov
df555ffce6 Core: the ngx_set_connection_log() macro.
The http and stream versions of this macro were identical.
2015-04-25 22:44:02 +03:00
Ruslan Ermilov
33b8e5bc06 Removed the obsolete rtsig module. 2015-04-23 14:17:40 +03:00
Ruslan Ermilov
c1882d9f3f Removed the obsolete aio module. 2015-04-22 18:57:32 +03:00
Maxim Dounin
2743bb68ee Request body: unbuffered reading.
The r->request_body_no_buffering flag was introduced.  It instructs
client request body reading code to avoid reading the whole body, and
to call post_handler early instead.  The caller should use the
ngx_http_read_unbuffered_request_body() function to read remaining
parts of the body.

Upstream module is now able to use this mode, if configured with
the proxy_request_buffering directive.
2015-03-23 21:09:19 +03:00
Roman Arutyunyan
46a2236f22 SSL: reset ready flag if recv(MSG_PEEK) found no bytes in socket.
Previously, connection hung after calling ngx_http_ssl_handshake() with
rev->ready set and no bytes in socket to read.  It's possible in at least the
following cases:

 - when processing a connection with expired TCP_DEFER_ACCEPT on Linux
 - after parsing PROXY protocol header if it arrived in a separate TCP packet

Thanks to James Hamlin.
2015-03-02 21:15:46 +03:00
Maxim Dounin
10345663c8 Upstream: improved subrequest logging.
To ensure proper logging make sure to set current_request in all event
handlers, including resolve, ssl handshake, cache lock wait timer and
aio read handlers.  A macro ngx_http_set_log_request() introduced to
simplify this.
2014-12-02 05:54:54 +03:00
Maxim Dounin
c01481a4cb Fixed possible buffer overrun in "too long header line" logging.
Additionally, ellipsis now always added to make it clear that
the header logged is incomplete.

Reported by Daniil Bondarev.
2014-10-08 17:16:04 +04:00
Valentin Bartenev
c425f19daa SPDY: avoid setting timeout on stream events in ngx_http_writer().
The SPDY module doesn't expect timers can be set on stream events for reasons
other than delaying output.  But ngx_http_writer() could add timer on write
event if the delayed flag wasn't set and nginx is waiting for AIO completion.
That could cause delays in sending response over SPDY when file AIO was used.
2014-08-27 20:44:11 +04:00
Maxim Dounin
88d9289f82 Reset of r->uri.len on URI parsing errors.
This ensures that debug logging and the $uri variable (if used in
400 Bad Request processing) will not try to access uninitialized
memory.

Found by Sergey Bobrov.
2014-07-18 20:02:11 +04:00
Roman Arutyunyan
0b5f329784 Added server-side support for PROXY protocol v1 (ticket #355).
Client address specified in the PROXY protocol header is now
saved in the $proxy_protocol_addr variable and can be used in
the realip module.

This is currently not implemented for mail.
2014-03-17 17:41:24 +04:00
Piotr Sikora
ab3c0f9250 Use ngx_socket_errno where appropriate.
Signed-off-by: Piotr Sikora <piotr@cloudflare.com>
2014-02-03 14:17:17 -08:00