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