#2071 closed defect (wontfix)
ssl_reject_handshake on introduced in nginx 1.19.4 works but disables TLSv1.3?
Reported by: | 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 , 4 years ago
Resolution: | → wontfix |
---|---|
Status: | new → closed |
comment:2 by , 4 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:5 by , 4 years ago
Then in the description of the option it is necessary to mention "For BoringSSL only!".
comment:6 by , 4 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.
comment:7 by , 4 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.
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.