FreeBSD 13.1, nginx and TLS 1.3 not working?

Hi,
I had a few FreeBSD 13 nginx server running TLS1.2 and TLS1.3 for a year or so. A week ago I updated them to 13.1, all good. Today I updated my certificate and run a test on SSLlabs.. and see that TLS1.3 is not working anymore!

I tested some settings, but no luck.
Is there something I miss regarding FreeBSD13.1 and nginx to support TLS1.3?

Versions:
Code:
FreeBSD 13.1-RELEASE FreeBSD 13.1-RELEASE releng/13.1-n250148-fc952ac2212 GENERIC amd64
nginx version: nginx/1.20.2
built with OpenSSL 1.1.1k-freebsd  24 Aug 2021 (running with OpenSSL 1.1.1o-freebsd  3 May 2022)

Here is some of my ssl-settings in /usr/local/etc/nginx/vhosts/domain.conf (worked on FreeBSD13.0):
Code:
ssl_certificate         /etc/ssl/certs/domain.chained.crt;
ssl_certificate_key     /etc/ssl/private/domain.key;
ssl_trusted_certificate /etc/ssl/certs/domain.chained.crt;
ssl_dhparam             /etc/ssl/certs/dhparam.pem;

ssl_protocols TLSv1.2 TLSv1.3;
ssl_prefer_server_ciphers off;
ssl_conf_command Options PrioritizeChaCha;
ssl_conf_command Ciphersuites TLS_CHACHA20_POLY1305_SHA256:TLS_AES_256_GCM_SHA384;
ssl_ecdh_curve secp521r1:secp384r1;
ssl_ciphers ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384;

ssl_session_cache shared:SSL:5m;
ssl_session_timeout 5m;
ssl_buffer_size 4k;

ssl_stapling on;
ssl_stapling_verify on;
resolver 10.35.40.100 10.35.40.101 10.35.40.102;
 
Hello,

It was working before?

Do a simple test, and check if there show any errors:

openssl s_client -tls1_3 -connect your.domain.xxx:443
 
Yes, it worked perfectly under 13.0. Also SSLLabs made A++ and everything was good under both TLS1.2 and 1.3. So it worked.. until I update the server (didn't noticed the TLS1.3 problem). And I was so good so I updated all webservers. :)

I checked from this computer:
Code:
$ uname -a
FreeBSD s1 13.0-RELEASE-p7 FreeBSD 13.0-RELEASE-p7 #0: Mon Jan 31 18:24:03 UTC 2022

And got this:
Code:
$ openssl s_client -tls1_3 -connect domain.com:443
CONNECTED(00000004)
34374492160:error:1409442E:SSL routines:ssl3_read_bytes:tlsv1 alert protocol version:/usr/src/crypto/openssl/ssl/record/rec_layer_s3.c:1603:SSL alert number 70
---
no peer certificate available
---
No client certificate CA names sent
---
SSL handshake has read 7 bytes and written 236 bytes
Verification: OK
---
New, (NONE), Cipher is (NONE)
Secure Renegotiation IS NOT supported
Compression: NONE
Expansion: NONE
No ALPN negotiated
Early data was not sent
Verify return code: 0 (ok)
---

tlsv1 alert protocol?? Is this from the test computer? Can't be from the server, only TLS1.2 and 1.3 is supported. SSLLabs only see TLS 1.2 also on all the webbservers with FreeBSD 13.1.

I tested $ openssl s_client -tls1_2 -connect domain.com:443 there everything worked.
 
what is the output of nginx -t and openssl ciphers -s -tls1_3

On my test machine openssl for tls1_3 give me:
TLS_AES_256_GCM_SHA384:TLS_CHACHA20_POLY1305_SHA256:TLS_AES_128_GCM_SHA256

Instead of listing all ciphers in your nginx.conf you can use the alias name "HIGH" like in the sample nginx.conf so after your next upgrade of openssl it will include only the supported ciphers.

...
ssl_ciphers HIGH:!aNull:!MD5;
...

All the TLSv1.3 ciphersuites also appear in the HIGH ciphersuite alias. The CHACHA20, AES, AES128, AES256, AESGCM, AESCCM and AESCCM8 ciphersuite aliases include a subset of these ciphersuites as you would expect based on their names. Key exchange and authentication properties were part of the ciphersuite definition in TLSv1.2 and below. This is no longer the case in TLSv1.3 so ciphersuite aliases such as ECDHE, ECDSA, RSA and other similar aliases do not contain any TLSv1.3 ciphersuites.


ciphers(1)
 
Here is the results from one webserver (FreeBSD 13.1):

Code:
# nginx -t
nginx: the configuration file /usr/local/etc/nginx/nginx.conf syntax is ok
nginx: configuration file /usr/local/etc/nginx/nginx.conf test is successful

# openssl ciphers -s -tls1_3
TLS_AES_256_GCM_SHA384:TLS_CHACHA20_POLY1305_SHA256:TLS_AES_128_GCM_SHA256
 
I just installed a brand new VM with FreeBSD 13.1 and nginx etc. More or less a clone of all the other webserver that I updated from 13.0 -> 13.1 (copied the same vhost nginx file, change the subdomain - nginx.conf is original with some changes on the 13.1 VM). Made a subdomain in the DNS on one domain as I wanted so real test as possibly.

And that server worked!! With TLS 1.3 and 1.2.
I tested the server with SSLLabs, and everything was good there.

I also noted that I got “Session resumption (caching) No (IDs assigned but not accepted)” from the updated server (13.0->13.1). I didn’t had that before and I tried some settings to fix it, no luck. I don’t have that on the new FreeBSD13.1 VM.

Interesting!
I will look at the config files on both servers and see if I can find something.
But it’s something is different between 13.0 and 13.1.

I have updated several web server from 13.0 -> 13.1 with difrent domains and subdomain, same on all. So it not just one server, all of them. :/

So don’t update you nginx web server jet if you use TLS1.3. :)


(BTW: ssl_ciphers is for TLS1.2. For TLS1.3 it’s: ssl_conf_command Ciphersuites)
 
does it work when you set the ssl_ciphers to HIGH in nginx.conf?
I just did this test, not working.
Also checked with SSLLabs and.. the server started TLS1.0 and TLS1.1!! I only have ssl_protocols TLSv1.3 TLSv1.2 on the server.

Did the same test om the new 13.1 VM, did not started TLS1.0 and TLS1.1.
It’s something strange with nginx and FreeBSD13.0->13.1 update.

ssl_ciphers is for TLS1.2 and ssl_conf_command Ciphersuites is for TLS1.3.
 
don't set ssl_conf_command it change the default Ciphersuites for tls1_3 for your openssl it's better to remove it and use the default one which is TLS_AES_256_GCM_SHA384:TLS_CHACHA20_POLY1305_SHA256:TLS_AES_128_GCM_SHA256 specified by openssl

Note that configuring OpenSSL directly might result in unexpected behavior.

Changing ssl_ciphers should not enable the TLS1.0 or TLS1.1

Double check that your "ssl_protocols TLSv1.2 TLSv1.3;" is inside the right server {} in the nginx.conf whiteout nginx will not enable TLSv1.3 and will give you the following error:
34389172224:error:1409442E:SSL routines:ssl3_read_bytes:tlsv1 alert protocol version:/usr/src/crypto/openssl/ssl/record/rec_layer_s3.c:1603:SSL alert number 70

Code:
    server {
        listen       443 ssl;
        server_name  localhost;

        ssl_protocols TLSv1.2 TLSv1.3;
        ssl_certificate      server.crt;
        ssl_certificate_key  server.key;

        ssl_session_cache    shared:SSL:1m;
        ssl_session_timeout  5m;

        ssl_ciphers  HIGH:!aNULL:!MD5;
        ssl_prefer_server_ciphers  on;

        location / {
            root   html;
            index  index.html index.htm;
        }
    }
 
Ok, a loot more tests..

There is some small different between 13.0 and 13.1 and nginx when you use more domains in vhosts and just ”copy” the old web-config-files to the new one. Can’t say what.. I installed a new 13.1 VM as my base for ”web install server”. Inserted all domains.. and got same bad results as before. Put around 4 hours yesterday in the config files (nginx and php) and got it to work with TLS1.2 and 1.3, A+ at SSLLabs. Did so many changes and configs changes so I lost the track what the problem was (more than one). I have more security stuff in my files, so it’s not original clean that 13.1/nginx don’t like (but worked in 13.0/nginx). I also have php81 instead of php74, but that doesn’t matter in this case.

I notest one thing (witch I did not lost track off). I have a generated a self sign cert that I have in nginx.conf to a return 444; as I don’t want people to connect to the IP and get the original cert/domain in the cert-error file. I get an SNI error at SSLlabs (don’t matter) but TLS1.3 worked in 13.0 for all domains but not in 13.1. So I did a lots of tests in nginx.conf with the old/new ssl_X configs and got that to work. New day and know I will spend some hours to actually understan what I did to fix it.. :)

One thing, if you use the same (main) cert for you main-domain (in vhost/domain.conf) and have the same cert-configs in nginx.conf you do not get the TLS1.3 error I got. But if you do as I do above, the 13.1/nginx do some strange stuff there you need to change the ssl_X configs in nginx.conf. This is payed certs, I don’t know how lets encrypt cert works in this case.

Well.. that’s it..!
 
Back
Top