Opened 3 years ago

Closed 3 years ago

Last modified 2 years ago

#2071 closed defect (wontfix)

ssl_reject_handshake on introduced in nginx 1.19.4 works but disables TLSv1.3?

Reported by: i81b4u@… Owned by:
Priority: minor Milestone:
Component: documentation Version: 1.19.x
Keywords: TLSv1.3 ssl_reject_handshake Cc:
uname -a: Linux linuxhost 5.4.0-21-generic #25-Ubuntu SMP Sat Mar 28 13:10:28 UTC 2020 x86_64 x86_64 x86_64 GNU/Linux
nginx -V: nginx version: nginx/1.19.4
built by gcc 9.3.0 (Ubuntu 9.3.0-17ubuntu1~20.04)
built with OpenSSL 1.1.1h 22 Sep 2020
TLS SNI support enabled
configure arguments: --with-cc-opt='-g0 -O2 -fstack-protector-strong -Wformat -Werror=format-security -fPIC -Wdate-time -march=native -pipe -flto -funsafe-math-optimizations --param=ssp-buffer-size=4 -D_FORTIFY_SOURCE=2' --with-ld-opt='-Wl,-Bsymbolic-functions -Wl,-z,relro -Wl,-z,now -fPIC' --prefix=/opt/nginx --conf-path=/opt/nginx/etc/nginx.conf --sbin-path=/opt/nginx/sbin/nginx --http-client-body-temp-path=/var/tmp/client_body_temp --lock-path=/var/lock/nginx.lock --pid-path=/run/nginx.pid --http-log-path=/var/log/nginx/access.log --error-log-path=/var/log/nginx/error.log --modules-path=/opt/nginx/lib/modules --http-fastcgi-temp-path=/opt/nginx/lib/fastcgi --http-proxy-temp-path=/opt/nginx/lib/proxy --http-scgi-temp-path=/opt/nginx/lib/scgi --http-uwsgi-temp-path=/opt/nginx/lib/uwsgi --user=www-data --group=www-data --with-openssl=/usr/src/openssl --with-openssl-opt='enable-tls1_3 enable-ec_nistp_64_gcc_128' --add-module=/usr/src/ngx_brotli --with-pcre-jit --with-http_ssl_module --with-http_stub_status_module --with-http_realip_module --with-http_auth_request_module --with-http_v2_module --with-http_dav_module --with-http_slice_module --with-threads --with-http_addition_module --with-http_geoip_module=dynamic --with-http_gunzip_module --with-http_gzip_static_module --with-http_image_filter_module=dynamic --with-http_sub_module --with-http_xslt_module=dynamic --with-stream=dynamic --with-stream_ssl_module --with-mail=dynamic --with-mail_ssl_module

Description

After "adding ssl_reject_handshake on;" to my configuration, everything seemed to work as intended, but after closer inspection I found that TLSv1.3 was no longer used.

After disabling the first server directive and restarting nginx, TLSv1.3 started working again:
server {

listen 443 ssl http2;
listen [::]:443 ssl http2;

ssl_reject_handshake on;

}

server {

listen 443 ssl http2;
listen [::]:443 ssl http2;

server_name test.server;

# logging
access_log /var/log/nginx/access.log;
error_log /var/log/nginx/error.log warn;

set $base /var/www/default;
root $base;

# SSL
ssl_certificate /opt/nginx/etc/ssl/certs/test.server.pem;
ssl_certificate_key /opt/nginx/etc/ssl/keys/test.server.key;

# index.html
index index.html;

# limit HTTP methods
location / {

limit_except GET POST {

deny all;

}

}

location ~* (mp3|mp4|m4v)$ {

add_header Content-Disposition "attachment";

}

}

The ssl-config is as follows:

ssl_session_timeout 1d;
ssl_session_cache shared:SSL:10m;
ssl_session_tickets off;
ssl_dyn_rec_enable on;
ssl_ecdh_curve X25519:secp521r1:secp384r1:prime256v1;
ssl_prefer_server_ciphers on;
ssl_buffer_size 4k;

ssl_protocols TLSv1.2 TLSv1.3;
ssl_ciphers ECDHE+AESGCM;

Change History (9)

comment:1 by Sergey Kandaurov, 3 years ago

Resolution: wontfix
Status: newclosed

Thank you for your report. This is a known issue.

OpenSSL checks server supported versions while processing
ClientHello and before its extensions such as server_name.
So that OpenSSL uses a default context for that check.
Then, OpenSSL removes TLSv1.3 version support since there's
no certificates loaded. For details, see its libssl function
is_tls13_capable().

This is believed to be a bug in OpenSSL, since it checks
for supported protocol versions before switching context,
and nginx can't influence it.
For comparison, BoringSSL works here as expected.

As a workaround, you may want to specify certificates
in the server block that has ssl_reject_handshake, too,
or switch to BoringSSL if that's an option.

comment:2 by i81b4u@…, 3 years ago

Thanks a lot for your quick response. Much appreciated!

In the mean time I submitted a bug report with openssl and after recompiling nginx with boringssl support, ssl_reject_handshake works like a charm. Cool!

comment:4 by Maxim Dounin, 3 years ago

See also #2073.

comment:5 by IlyaIndigo@…, 3 years ago

Then in the description of the option it is necessary to mention "For BoringSSL only!".

Version 1, edited 3 years ago by IlyaIndigo@… (previous) (next) (diff)

comment:6 by i81b4u@…, 3 years ago

Hmmm, a member of the OpenSSL development team did write a fix (master: https://github.com/openssl/openssl/pull/13304 and 1.1.1: https://github.com/openssl/openssl/pull/13305). Its state is "hold: need otc decision", but I can tell you that it fixes the problem, because I now have everything working with nginx and openssl 1.1.1h including that fix.

The way I see it, the development team faces an almost philosophical question. Will they follow the pragmatic track and approve the fix "as is" (exception management), or will they rewrite part of the code in a way that no exception is needed.

If you ask me, I would implement the current fix and put the task of rewriting part of the code on the (already extensive) to-do list. But that's just my view on the matter and I'm not a member of the otc.

Last edited 3 years ago by i81b4u@… (previous) (diff)

comment:7 by i81b4u@…, 3 years ago

FYI: I saw today that the code that fixes the problem made it into both the master branch as well as the 1_1_1 branch of openssl.

comment:8 by Maxim Dounin, 3 years ago

comment:9 by Maxim Dounin, 2 years ago

See also #2305.

Note: See TracTickets for help on using tickets.