aboutsummaryrefslogtreecommitdiff
path: root/src/stream/ngx_stream_proxy_module.c
Commit message (Collapse)AuthorAge
* Upstream: fixed passwords support for dynamic certificates.Sergey Kandaurov2025-04-10
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | 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; } }
* Upstream: caching certificates and certificate keys with variables.Sergey Kandaurov2025-01-17
| | | | | | Caching is enabled with proxy_ssl_certificate_cache and friends. Co-authored-by: Aleksei Bavshin <a.bavshin@nginx.com>
* SSL: caching certificates and certificate keys with variables.Sergey Kandaurov2025-01-17
| | | | | | | | 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>
* SSL: a new macro to set default protocol versions.Sergey Kandaurov2024-11-22
| | | | | | | | | 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.
* SSL: fixed MSVC compilation after ebd18ec1812b.蕭澧邦2024-11-11
| | | | | MSVC generates a compilation error in case #if/#endif is used in a macro parameter.
* Upstream: re-resolvable servers.Ruslan Ermilov2024-11-07
| | | | | | | | | | | | | | | | | | | | | | | | | 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>
* SSL: disabled TLSv1 and TLSv1.1 by default.Sergey Kandaurov2024-10-31
| | | | | | | | | | | | | | | 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.
* SSL: enabled TLSv1.3 by default.Maxim Dounin2023-03-24
|
* SSL: fixed ngx_ssl_recv() to reset c->read->ready after errors.Maxim Dounin2022-12-01
| | | | | | | | | | | | With this change, behaviour of ngx_ssl_recv() now matches ngx_unix_recv(), which used to always reset c->read->ready to 0 when returning errors. This fixes an infinite loop in unbuffered SSL proxying if writing to the client is blocked and an SSL error happens (ticket #2418). With this change, the fix for a similar issue in the stream module (6868:ee3645078759), which used a different approach of explicitly testing c->read->error instead, is no longer needed and was reverted.
* Increased maximum read PROXY protocol header size.Roman Arutyunyan2022-11-02
| | | | | | | | Maximum size for reading the PROXY protocol header is increased to 4096 to accommodate a bigger number of TLVs, which are supported since cca4c8a715de. Maximum size for writing the PROXY protocol header is not changed since only version 1 is currently supported.
* Upstream: optimized use of SSL contexts (ticket #1234).Maxim Dounin2022-06-29
| | | | | | | | | | | | To ensure optimal use of memory, SSL contexts for proxying are now inherited from previous levels as long as relevant proxy_ssl_* directives are not redefined. Further, when no proxy_ssl_* directives are redefined in a server block, we now preserve plcf->upstream.ssl in the "http" section configuration to inherit it to all servers. Similar changes made in uwsgi, grpc, and stream proxy.
* Stream: don't flush empty buffers created for read errors.Aleksei Bavshin2022-05-23
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | When we generate the last_buf buffer for an UDP upstream recv error, it does not contain any data from the wire. ngx_stream_write_filter attempts to forward it anyways, which is incorrect (e.g., UDP upstream ECONNREFUSED will be translated to an empty packet). This happens because we mark the buffer as both 'flush' and 'last_buf', and ngx_stream_write_filter has special handling for flush with certain types of connections (see d127837c714f, 32b0ba4855a6). The flags are meant to be mutually exclusive, so the fix is to ensure that flush and last_buf are not set at the same time. Reproduction: stream { upstream unreachable { server 127.0.0.1:8880; } server { listen 127.0.0.1:8998 udp; proxy_pass unreachable; } } 1 0.000000000 127.0.0.1 → 127.0.0.1 UDP 47 45588 → 8998 Len=5 2 0.000166300 127.0.0.1 → 127.0.0.1 UDP 47 51149 → 8880 Len=5 3 0.000172600 127.0.0.1 → 127.0.0.1 ICMP 75 Destination unreachable (Port unreachable) 4 0.000202400 127.0.0.1 → 127.0.0.1 UDP 42 8998 → 45588 Len=0 Fixes d127837c714f.
* Upstream: handling of certificates specified as an empty string.Sergey Kandaurov2022-06-07
| | | | | | | Now, if the directive is given an empty string, such configuration cancels loading of certificates, in particular, if they would be otherwise inherited from the previous level. This restores previous behaviour, before variables support in certificates was introduced (3ab8e1e2f0f7).
* Stream: added half-close support.Vladimir Homutov2021-09-22
| | | | | | The "proxy_half_close" directive enables handling of TCP half close. If enabled, connection to proxied server is kept open until both read ends get EOF. Write end shutdown is properly transmitted via proxy.
* SSL: ciphers now set before loading certificates (ticket #2035).Maxim Dounin2021-08-16
| | | | | | | To load old/weak server or client certificates it might be needed to adjust the security level, as introduced in OpenSSL 1.1.0. This change ensures that ciphers are set before loading the certificates, so security level changes via the cipher string apply to certificate loading.
* Upstream: variables support in certificates.Maxim Dounin2021-05-06
|
* Changed complex value slots to use NGX_CONF_UNSET_PTR.Maxim Dounin2021-05-06
| | | | | | | | | | | With this change, it is now possible to use ngx_conf_merge_ptr_value() to merge complex values. This change follows much earlier changes in ngx_conf_merge_ptr_value() and ngx_conf_set_str_array_slot() in 1452:cd586e963db0 (0.6.10) and 1701:40d004d95d88 (0.6.22), and the change in ngx_conf_set_keyval_slot() (7728:485dba3e2a01, 1.19.4). To preserve compatibility with existing 3rd party modules, both NULL and NGX_CONF_UNSET_PTR are accepted for now.
* SSL: fixed build by Sun C with old OpenSSL versions.Maxim Dounin2021-03-05
| | | | | Sun C complains about "statement not reached" if a "return" is followed by additional statements.
* Stream: proxy_ssl_conf_command directive.Maxim Dounin2020-10-22
| | | | | | | | | Similarly to ssl_conf_command, proxy_ssl_conf_command can be used to set arbitrary OpenSSL configuration parameters as long as nginx is compiled with OpenSSL 1.0.2 or later, when connecting to upstream servers with SSL. Full list of available configuration commands can be found in the SSL_CONF_cmd manual page (https://www.openssl.org/docs/man1.1.1/man3/SSL_CONF_cmd.html).
* Stream: fixed processing of zero length UDP packets (ticket #1982).Vladimir Homutov2020-06-08
|
* Variables support in proxy_upload_rate and proxy_download_rate.Ruslan Ermilov2019-04-24
|
* SSL: fixed potential leak on memory allocation errors.Maxim Dounin2019-03-03
| | | | | | | | | If ngx_pool_cleanup_add() fails, we have to clean just created SSL context manually, thus appropriate call added. Additionally, ngx_pool_cleanup_add() moved closer to ngx_ssl_create() in the ngx_http_ssl_module, to make sure there are no leaks due to intermediate code.
* Stream: do not split datagrams when limiting proxy rate.Roman Arutyunyan2018-12-27
| | | | | | | | | | | Previously, when using proxy_upload_rate and proxy_download_rate, the buffer size for reading from a socket could be reduced as a result of rate limiting. For connection-oriented protocols this behavior is normal since unread data will normally be read at the next iteration. But for datagram-oriented protocols this is not the case, and unread part of the datagram is lost. Now buffer size is not limited for datagrams. Rate limiting still works in this case by delaying the next reading event.
* Prevented scheduling events on a shared connection.Roman Arutyunyan2019-01-14
| | | | | | | | | | | | | | | | A shared connection does not own its file descriptor, which means that ngx_handle_read_event/ngx_handle_write_event calls should do nothing for it. Currently the c->shared flag is checked in several places in the stream proxy module prior to calling these functions. However it was not done everywhere. Missing checks could lead to calling ngx_handle_read_event/ngx_handle_write_event on shared connections. The problem manifested itself when using proxy_upload_rate and resulted in either duplicate file descriptor error (e.g. with epoll) or incorrect further udp packet processing (e.g. with kqueue). The fix is to set and reset the event active flag in a way that prevents ngx_handle_read_event/ngx_handle_write_event from scheduling socket events.
* Upstream: revised upstream response time variables.Vladimir Homutov2018-11-21
| | | | | | | | | Variables now do not depend on presence of the HTTP status code in response. If the corresponding event occurred, variables contain time between request creation and the event, and "-" otherwise. Previously, intermediate value of the $upstream_response_time variable held unix timestamp.
* Stream: proxy_requests directive.Vladimir Homutov2018-11-12
| | | | | | | | | | | The directive allows to drop binding between a client and existing UDP stream session after receiving a specified number of packets. First packet from the same client address and port will start a new session. Old session continues to exist and will terminate at moment defined by configuration: either after receiving the expected number of responses, or after timeout, as specified by the "proxy_responses" and/or "proxy_timeout" directives. By default, proxy_requests is zero (disabled).
* Stream: session completion check code moved to a separate function.Vladimir Homutov2018-11-12
| | | | | The code refactored to simplify the ngx_stream_proxy_process() function and facilitate adding new session termination conditions.
* Upstream: proxy_socket_keepalive and friends.Vladimir Homutov2018-10-03
| | | | | The directives enable the use of the SO_KEEPALIVE option on upstream connections. By default, the value is left unchanged.
* SSL: save sessions for upstream peers using a callback function.Sergey Kandaurov2018-07-17
| | | | | | | | | | | | | In TLSv1.3, NewSessionTicket messages arrive after the handshake and can come at any time. Therefore we use a callback to save the session when we know about it. This approach works for < TLSv1.3 as well. The callback function is set once per location on merge phase. Since SSL_get_session() in BoringSSL returns an unresumable session for TLSv1.3, peer save_session() methods have been updated as well to use a session supplied within the callback. To preserve API, the session is cached in c->ssl->session. It is preferably accessed in save_session() methods by ngx_ssl_get_session() and ngx_ssl_get0_session() wrappers.
* Stream: udp streams.Roman Arutyunyan2018-06-04
| | | | | | | | | | | | | | | | | Previously, only one client packet could be processed in a udp stream session even though multiple response packets were supported. Now multiple packets coming from the same client address and port are delivered to the same stream session. If it's required to maintain a single stream of data, nginx should be configured in a way that all packets from a client are delivered to the same worker. On Linux and DragonFly BSD the "reuseport" parameter should be specified for this. Other systems do not currently provide appropriate mechanisms. For these systems a single stream of udp packets is only guaranteed in single-worker configurations. The proxy_response directive now specifies how many packets are expected in response to a single client packet.
* Stream: set action before each recv/send while proxying.Roman Arutyunyan2018-03-22
| | | | | Now it's clear from log error message if the error occurred on client or upstream side.
* Retain CAP_NET_RAW capability for transparent proxying.Roman Arutyunyan2017-12-13
| | | | | | | | The capability is retained automatically in unprivileged worker processes after changing UID if transparent proxying is enabled at least once in nginx configuration. The feature is only available in Linux.
* Fixed worker_shutdown_timeout in various cases.Maxim Dounin2017-11-20
| | | | | | | | | | | | | | | | | | 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.
* Stream: fixed logging UDP upstream timeout.Roman Arutyunyan2017-09-12
| | | | | | | | | Previously, when the first UDP response packet was not received from the proxied server within proxy_timeout, no error message was logged before switching to the next upstream. Additionally, when one of succeeding response packets was not received within the timeout, the timeout error had low severity because it was logged as a client connection error as opposed to upstream connection error.
* Stream: relaxed next upstream condition (ticket #1317).Roman Arutyunyan2017-09-11
| | | | | | | | | | | | | | | | | When switching to a next upstream, some buffers could be stuck in the middle of the filter chain. A condition existed that raised an error when this happened. As it turned out, this condition prevented switching to a next upstream if ssl preread was used with the TCP protocol (see the ticket). In fact, the condition does not make sense for TCP, since after successful connection to an upstream switching to another upstream never happens. As for UDP, the issue with stuck buffers is unlikely to happen, but is still possible. Specifically, if a filter delays sending data to upstream. The condition can be relaxed to only check the "buffered" bitmask of the upstream connection. The new condition is simpler and fixes the ticket issue as well. Additionally, the upstream_out chain is now reset for UDP prior to connecting to a new upstream to prevent repeating the client data twice.
* Introduced ngx_tcp_nodelay().Ruslan Ermilov2017-05-26
|
* SSL: added support for TLSv1.3 in ssl_protocols directive.Sergey Kandaurov2017-04-18
| | | | Support for the TLSv1.3 protocol will be introduced in OpenSSL 1.1.1.
* Stream: avoid infinite loop in case of socket read error.Vladimir Homutov2017-01-11
|
* Stream: speed up TCP peer recovery.Roman Arutyunyan2016-12-26
| | | | | | | | | | | | | Previously, an unavailable peer was considered recovered after a successful proxy session to this peer. Until then, only a single client connection per fail_timeout was allowed to be proxied to the peer. Since stream sessions can be long, it may take indefinite time for a peer to recover, limiting the ability of the peer to receive new connections. Now, a peer is considered recovered after a successful TCP connection is established to it. Balancers are notified of this event via the notify() callback.
* Upstream: do not unnecessarily create per-request upstreams.Ruslan Ermilov2016-10-31
| | | | | | | | | If proxy_pass (and friends) with variables evaluates an upstream specified with literal address, nginx always created a per-request upstream. Now, if there's a matching upstream specified in the configuration (either implicit or explicit), it will be used instead.
* Upstream: added the ngx_http_upstream_resolved_t.name field.Ruslan Ermilov2016-10-31
| | | | | | | | | | | | | | | | | | | | | | This fixes inconsistency in what is stored in the "host" field. Normally it would contain the "host" part of the parsed URL (e.g., proxy_pass with variables), but for the case of an implicit upstream specified with literal address it contained the text representation of the socket address (that is, host including port for IP). Now the "host" field always contains the "host" part of the URL, while the text representation of the socket address is stored in the newly added "name" field. The ngx_http_upstream_create_round_robin_peer() function was modified accordingly in a way to be compatible with the code that does not know about the new "name" field. The "stream" code was similarly modified except for not adding compatibility in ngx_stream_upstream_create_round_robin_peer(). This change is also a prerequisite for the next change.
* Upstream: removed unnecessary condition in proxy_eval() and friends.Ruslan Ermilov2016-10-31
| | | | | The first condition added in d3454e719bbb should have just replaced the second one.
* SSL: compatibility with BoringSSL.Maxim Dounin2016-10-19
| | | | | | | | | BoringSSL changed SSL_set_tlsext_host_name() to be a real function with a (const char *) argument, so it now triggers a warning due to conversion from (u_char *). Added an explicit cast to silence the warning. Prodded by Piotr Sikora, Alessandro Ghedini.
* Upstream: introduced u->upstream.Maxim Dounin2016-09-22
| | | | | It holds upstream{} block configuration, including ones selected via run-time lookup using variables.
* Stream: filters.Roman Arutyunyan2016-09-15
|
* Stream: upstream response time variables.Vladimir Homutov2016-09-02
| | | | | The $upstream_connect_time, $upstream_first_byte_time and $upstream_session_time variables keep corresponding times.
* Stream: $upstream_bytes_sent and $upstream_bytes_received.Vladimir Homutov2016-09-02
|
* Stream: the $upstream_addr variable.Vladimir Homutov2016-09-02
| | | | | | Keeps the full address of the upstream server. If several servers were contacted during proxying, their addresses are separated by commas, e.g. "192.168.1.1:80, 192.168.1.2:80".
* Stream: the $status variable.Roman Arutyunyan2016-08-11
| | | | | | | | | | The stream session status is one of the following: 200 - normal completion 403 - access forbidden 500 - internal server error 502 - bad gateway 503 - limit conn
* Stream: fixed build without stream_ssl_module (ticket #1032).Vladimir Homutov2016-07-26
|