nginx 1.18.0 implicitly enables TLS 1.3 (with only "ssl_protocols TLSv1.2; " in nginx.conf config)

Sergey Kandaurov pluknet at nginx.com
Tue Dec 1 12:40:18 UTC 2020


> On 1 Dec 2020, at 11:11, Andreas Bartelt <nginx at bartelt.name> wrote:
> 
> On 11/30/20 11:39 PM, Maxim Dounin wrote:
>> Hello!
>> On Mon, Nov 30, 2020 at 06:41:18PM +0100, Andreas Bartelt wrote:
>>> On 11/30/20 4:07 PM, Maxim Dounin wrote:
>>>> Hello!
>>>> 
>>>> On Sun, Nov 29, 2020 at 04:01:07PM +0100, nginx at bartelt.name wrote:
>>>> 
>>>>> I've noticed that nginx 1.18.0 always enables TLS 1.3 even if not
>>>>> configured to do so. I've observed this behavior on OpenBSD with (nginx
>>>>> 1.18.0 linked against LibreSSL 3.3.0) and on Ubuntu 20.04 (nginx 1.18.0
>>>>> linked against OpenSSL 1.1.1f). I don't know which release of nginx
>>>>> introduced this bug.
>>>>> 
>>>>>   From nginx.conf:
>>>>> ssl_protocols TLSv1.2;
>>>>> --> in my understanding, this config statement should only enable TLS
>>>>> 1.2 but not TLS 1.3. However, the observed behavior is that TLS 1.3 is
>>>>> implicitly enabled in addition to TLS 1.2.
>>>> 
>>>> As long as "ssl_protocols TLSv1.2;" is the only ssl_protocols in
>>>> nginx configuration, TLSv1.3 shouldn't be enabled.  Much like when
>>>> there are no "ssl_protocols" at all, as TLSv1.3 isn't enabled by
>>>> default (for now, at least up to and including nginx 1.19.5).
>>>> 
>>> 
>>> I've just retested this with my Ubuntu 20.04 based nginx test instance
>>> from yesterday (nginx 1.18.0 linked against OpenSSL 1.1.1f) and noticed
>>> that it works there as intended (i.e., "ssl_protocols TLSv1.2;" only
>>> enables TLS 1.2 but not TLS 1.3). I don't know what I did wrong there
>>> yesterday -- sorry for this.
>>> 
>>> However, the problem persists on OpenBSD current with nginx 1.18.0
>>> (built from ports with default options which links against LibreSSL
>>> 3.3.0 from base). Setting "ssl_protocols TLSv1.2;" enables TLS 1.2 as
>>> well as TLS 1.3 there.
>> I don't see any problems when testing with LibreSSL 3.3.0 as
>> available on libressl.org and the very same configuration.  So
>> it's probably something specific to your system.
>> Some possible reasons for the behaviour you are seeing, in no
>> particular order:
>> - Given that OpenBSD current and LibreSSL from base implies some
>>   arbitrary version of LibreSSL, this might be something with the
>>   changes present on your system but not in LibreSSL 3.3.0
>>   release.
>> - There may be something with the port you are using to compile
>>   nginx.  Consider testing nginx compiled manually.
>> - You are testing the wrong server (the name resolves to a
>>   different IP address, or the IP address is routed to a different
>>   server).  Make sure you are seeing connection on nginx side,
>>   something like "return 200 $ssl_protocol;" in the appropriate
>>   server block and making a "GET / HTTP/1.0" request in s_client
>>   would be a good test.
>> - The nginx version running differs from the one on disk, and you
>>   are running an nginx version older than 1.15.6 built with an old
>>   LibreSSL without TLSv1.3 but running with LibreSSL 3.3.0 with
>>   TLSv1.3 enabled.  Check the "Server" header in the above test.
>> - There might be something wrong with headers on your system.  The
>>   behaviour observed might happen if SSL_OP_NO_TLSv1_3, TLS1_3_VERSION,
>>   and SSL_CTX_set_min_proto_version/SSL_CTX_set_max_proto_version are
>>   not defined, yet TLSv1.3 is present in the library.
> 
> I've just tested the same nginx.conf on two freshly installed OpenBSD based test systems:
> 1) release 6.8 (with nginx 1.18.0 / LibreSSL 3.2.2)
> 2) snapshot from today (with nginx 1.18.0 / LibreSSL 3.3.0 + more recent commits since it's a snapshot)
> 
> Both instances were installed from scratch with the official OpenBSD binary tarballs and the nginx binary package from ports, respectively.
> 
> Release 6.8 interprets "ssl_protocols TLSv1.2;" correctly. However, the snapshot instance enables TLS 1.2 and 1.3, i.e., this looks like a bug which has been recently introduced into OpenBSD current.
> 
> Although OpenBSD 6.8 and the snapshot both use nginx 1.18.0, it's built differently on current:
> # cvs diff -r 1.145 -r 1.146 ports/www/nginx/Makefile
> Index: ports/www/nginx/Makefile
> ===================================================================
> RCS file: /cvs/ports/www/nginx/Makefile,v
> retrieving revision 1.145
> retrieving revision 1.146
> diff -u -p -r1.145 -r1.146
> --- ports/www/nginx/Makefile	27 Jul 2020 14:33:15 -0000	1.145
> +++ ports/www/nginx/Makefile	23 Oct 2020 15:20:30 -0000	1.146
> @@ -1,4 +1,4 @@
> -# $OpenBSD: Makefile,v 1.145 2020/07/27 14:33:15 sthen Exp $
> +# $OpenBSD: Makefile,v 1.146 2020/10/23 15:20:30 robert Exp $
> 
> BROKEN-hppa=	src/core/ngx_rwlock.c:116:2: error: \#error ngx_atomic_cmp_set() is not defined!
> 
> @@ -21,7 +21,7 @@ VERSION=	1.18.0
> DISTNAME=	nginx-${VERSION}
> CATEGORIES=	www
> 
> -REVISION-main=	0
> +REVISION-main=	1
> REVISION-xslt=	0
> 
> VERSION-rtmp=	1.2.1
> @@ -122,6 +122,8 @@ SUBST_VARS=	NGINX_DIR
> .for i in ${MODULE_PACKAGES}
> PREFIX$i=	${NGINX_DIR}/modules
> .endfor
> +
> +CFLAGS+=	-DTLS1_3_VERSION=0x0304
> 

That is a culprit.
It hijacks an established API expected in nginx, don't do that.

Defining TLS1_3_VERSION forces nginx to maximize a maximum supported
protocol version to TLSv1.3.  By default it is not set, and if libssl
supports the corresponding API, then it is set to TLSv1.2.

The presence of TLS1_3_VERSION implies SSL_OP_NO_TLSv1_3, which is not
actually defined in this particular case.  That's why disabling TLSv1.3
(or, not enabling) in the nginx configuration doesn't have an effect.

Enabling TLSv1.3 this way[1] looks wrong.
[1] http://cvsweb.openbsd.org/cgi-bin/cvsweb/ports/www/nginx/Makefile#rev1.146

The port maintainer should probably examine a different way
to do this.  For example, such as defining LIBRESSL_HAS_TLS1_3
as seen in include/openssl/opensslfeatures.h comments of LibreSSL.

-- 
Sergey Kandaurov



More information about the nginx mailing list