# how to enable tls1.3  in nginx ?

## sabitov

Hi! 

Could anybody help me to find my mistake? Even if set the only 'ssl_protocols TLSv1.3' in nginx, it works in TLSv1.2 and does not activate TLSv1.3! (Both, ssllabs.com and my FF shows it).

Thanx!

My https related settings are:

```

        ssl_stapling            on;

        ssl_certificate         /etc/letsencrypt/domain.com/fullchain.cer;

        ssl_certificate_key     /etc/letsencrypt/domain.com/domain.com.key;

        ssl_trusted_certificate /etc/letsencrypt/lets-encrypt-r3.pem;

        ssl_dhparam             /etc/letsencrypt/dh2048.pem;

        ssl_protocols           TLSv1.3 TLSv1.2;

#       ssl_protocols           TLSv1.3;

        ssl_ciphers             "TLS-CHACHA20-POLY1305-SHA256:TLS-AES-256-GCM-SHA384:TLS-AES-128-GCM-SHA256:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384:DHE-RSA-CHACHA20-POLY1305:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES128-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES256-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-RSA-CHACHA20-POLY1305:TLS_AES_128_GCM_SHA256:TLS_AES_256_GCM_SHA384:TLS_CHACHA20_POLY1305_SHA256";

```

USE-flags and versions for nginx && openssl are:

```
#walnut # emerge -p nginx openssl 

These are the packages that would be merged, in reverse order:

Calculating dependencies  .... done!

[ebuild   R    ] www-servers/nginx-1.20.1-r2::gentoo  USE="aio debug http http2 http-cache ipv6 pcre ssl threads vim-syntax -libatomic -pcre-jit -rtmp (-selinux)" LUA_SINGLE_TARGET="luajit" NGINX_MODULES_HTTP="access addition auth_basic autoindex browser cache_purge charset empty_gif fancyindex fastcgi geo geoip gunzip gzip gzip_static headers_more limit_conn limit_req map memcached metrics proxy realip referer rewrite slowfs_cache spdy split_clients ssi stub_status userid uwsgi -auth_ldap -auth_pam -auth_request -brotli -dav -dav_ext -degradation -echo -flv -geoip2 -grpc -image_filter -javascript -lua -memc -mirror -mogilefs -mp4 -naxsi -perl -push_stream -random_index -scgi -secure_link -security -slice -sticky -sub -upload_progress -upstream_check -upstream_hash -upstream_ip_hash -upstream_keepalive -upstream_least_conn -upstream_zone -vhost_traffic_status -xslt" NGINX_MODULES_MAIL="-imap -pop3 -smtp" NGINX_MODULES_STREAM="-access -geo -geoip -geoip2 -javascript -limit_conn -map -realip -return -split_clients -ssl_preread -upstream_hash -upstream_least_conn -upstream_zone" 1 182 KiB

[ebuild   R    ]  dev-libs/openssl-1.1.1l:0/1.1::gentoo  USE="asm -bindist -rfc3779 -sctp -sslv3 -static-libs -test -tls-compression -tls-heartbeat -vanilla" ABI_X86="32 (64) (-x32)" CPU_FLAGS_X86="(sse2)" 9 604 KiB

Total: 2 packages (2 reinstalls), Size of downloads: 10 785 KiB

```

----------

## Banana

see nothing wrong here at a first look.

Did you reaload the config and even rebuild openssl / nginx after adding the support?

----------

## sabitov

Yes, it was reloaded many-many times.

----------

## pingtoo

Not sure what let you believe it is not working. Can you set your nginx configuration with TLS1.3 only than test 

```
user$ curl -vL --tlsv1.3 https://<your-enginx-site>/
```

 and share the output of above curl code. Thanks.

edit -- Forget to ask what is your nginx version?

```
user$ nginx -V

user$ nginx -t
```

----------

## sabitov

 *Quote:*   

> what let you believe it is not working

 

TLS test using curl:

```

#sabitov@dog $ curl -vL --tlsv1.3 https://site.domain.ru/ 

*   Trying 1.2.3.4:443...

* Connected to site.domain.ru (1.2.3.4) port 443 (#0)

* ALPN, offering h2

* ALPN, offering http/1.1

* successfully set certificate verify locations:

*  CAfile: /etc/ssl/certs/ca-certificates.crt

*  CApath: /etc/ssl/certs

* TLSv1.3 (OUT), TLS handshake, Client hello (1):

* TLSv1.3 (IN), TLS alert, protocol version (582):

* error:1409442E:SSL routines:ssl3_read_bytes:tlsv1 alert protocol version

* Closing connection 0

curl: (35) error:1409442E:SSL routines:ssl3_read_bytes:tlsv1 alert protocol version

```

TLS test using openssl:

```

#sabitov@dog $ openssl s_client -connect site.domain.ru:443 -servername site.domain.ru 

CONNECTED(00000003)

depth=2 C = US, O = Internet Security Research Group, CN = ISRG Root X1

verify return:1

depth=1 C = US, O = Let's Encrypt, CN = R3

verify return:1

depth=0 CN = domain.ru

verify return:1

---

Certificate chain

 0 s:CN = domain.ru

   i:C = US, O = Let's Encrypt, CN = R3

 1 s:C = US, O = Let's Encrypt, CN = R3

   i:C = US, O = Internet Security Research Group, CN = ISRG Root X1

 2 s:C = US, O = Internet Security Research Group, CN = ISRG Root X1

   i:O = Digital Signature Trust Co., CN = DST Root CA X3

---

Server certificate

-----BEGIN CERTIFICATE-----

MIIFYjCCBEqgAwIBAgISBFWdyIsGBIC2m7dA1J0u5L7bMA0GCSqGSIb3DQEBCwUA

MDIxCzAJBgNVBAYTAlVTMRYwFAYDVQQKEw1MZXQncyBFbmNyeXB0MQswCQYDVQQD

EwJSMzAeFw0yMTEyMDExOTIwMDJaFw0yMjAzMDExOTIwMDFaMBUxEzARBgNVBAMT

CnNhYml0b3YucnUwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDjVQ0d

mD3iQ+LI2DWetK3I/9QZjiW+fd6kMrT8yRjuYAc4v2vm06gGlxpOHTXnAszCz5Uj

/jAuXNrIFlGSYBJWsDCjt+l4Cryp1xJ+ypckQwWXV7uqXAj24Gqj2Avfl9KbssUd

FCzQBUkjT/jT0DrFvL1VU/t4Qc1OseiPrrfPqBDKNg336tyy5Ib/rSzdop+sdPwh

FVTd0P0DOoE+nxevNmhe2aXhTGyhMGvvrRmVw2hQc2XhGiSrN3GWLwf9UZOQQLkj

bPifdhz2tQGZaANpU6p9QjXPhdpOkKWglsClYyFpPQon6salr+FSGegLIFDe6Oz3

RBHy9JJ2Y4xJVWrtAgMBAAGjggKNMIICiTAOBgNVHQ8BAf8EBAMCBaAwHQYDVR0l

BBYwFAYIKwYBBQUHAwEGCCsGAQUFBwMCMAwGA1UdEwEB/wQCMAAwHQYDVR0OBBYE

FJcydlM2eA6PhQRlHF+JEAK5iYLsMB8GA1UdIwQYMBaAFBQusxe3WFbLrlAJQOYf

r52LFMLGMFUGCCsGAQUFBwEBBEkwRzAhBggrBgEFBQcwAYYVaHR0cDovL3IzLm8u

bGVuY3Iub3JnMCIGCCsGAQUFBzAChhZodHRwOi8vcjMuaS5sZW5jci5vcmcvMF0G

A1UdEQRWMFSCDyouc2FiaXRvdi5wcC5ydYIMKi5zYWJpdG92LnJ1ggwqLnNhYml0

b3Yuc3WCDXNhYml0b3YucHAucnWCCnNhYml0b3YucnWCCnNhYml0b3Yuc3UwTAYD

VR0gBEUwQzAIBgZngQwBAgEwNwYLKwYBBAGC3xMBAQEwKDAmBggrBgEFBQcCARYa

aHR0cDovL2Nwcy5sZXRzZW5jcnlwdC5vcmcwggEEBgorBgEEAdZ5AgQCBIH1BIHy

APAAdQBGpVXrdfqRIDC1oolp9PN9ESxBdL79SbiFq/L8cP5tRwAAAX13p3L8AAAE

AwBGMEQCIDgexYjyC1ZNaO4nbUvaJ7YxHj1tRj4NTfDdAg8R0bnjAiA4FniVjjhV

mp1LaNRTiv8Za+JuVm+KpCPN4lXiG4636gB3AG9Tdqwx8DEZ2JkApFEV/3cVHBHZ

AsEAKQaNsgiaN9kTAAABfXenc+oAAAQDAEgwRgIhALLERPxsgnRlOxxQU/5+aucL

2N0DiJJQ4WAEhsU+KWRHAiEAjN74MizKlUwlV2d+eOAXIVeLNxGwZx5pEQWr9mco

DgUwDQYJKoZIhvcNAQELBQADggEBAIC+TJ5pdF93Xh5wdq+MkfAxmp4osjpc+ndA

UoFm+rWJqaLgYF5AowVt981oV1Xqlf3O2kUcxmA4/hBxuwOPsf5xSr4eXzSwzv9/

7LRtBL9oHb8wERFtziDthiAV2JNh2JFlL3+NZQhKsGugOIWvf60eljnzayjBmWbu

1HIuxG6l7HC8lHJvV5Zh7lO8dIlZ7CyGFw/Zm1+ONdr0bXdqF7gaglFRKUEitk9h

tsPy+gadDIwFxGNv+b2Ubis2tumAa9VYD0tQSxUnjLzJf0f9+1d0Ge8OueOWCFBu

SCB4XxllPKaTI8/LqsO/Ish2U0tLm40TLQsZql52r3eq3EoYyH0=

-----END CERTIFICATE-----

subject=CN = domain.ru

issuer=C = US, O = Let's Encrypt, CN = R3

---

No client certificate CA names sent

Peer signing digest: SHA256

Peer signature type: RSA-PSS

Server Temp Key: DH, 2048 bits

---

SSL handshake has read 5226 bytes and written 635 bytes

Verification: OK

---

New, TLSv1.2, Cipher is DHE-RSA-AES128-GCM-SHA256

Server public key is 2048 bit

Secure Renegotiation IS supported

Compression: NONE

Expansion: NONE

No ALPN negotiated

SSL-Session:

    Protocol  : TLSv1.2

    Cipher    : DHE-RSA-AES128-GCM-SHA256

    Session-ID: 877F9B7035932DF8E0559CD7A8359694BF968BAF3456650E519A062EAFA36B60

    Session-ID-ctx: 

    Master-Key: 31548A68AB877AD8423D8C9F4164F3D30E2DE0FDFFC8928F3111CFCDE0F0E5CC70E685055F49D98A906595806324BD40

    PSK identity: None

    PSK identity hint: None

    SRP username: None

    TLS session ticket lifetime hint: 86400 (seconds)

    TLS session ticket:

    0000 - 0b 64 a3 e3 7b 79 b9 e0-3c 31 a4 e7 b4 9e 3e 85   .d..{y..<1....>.

    0010 - 00 1d 48 d8 d9 65 b7 8a-a7 f6 2d 19 97 e8 0d 17   ..H..e....-.....

    0020 - 22 cb 42 86 39 05 8e 60-41 75 bd 43 93 63 b7 15   ".B.9..`Au.C.c..

    0030 - 18 9b 80 2f e4 81 b7 78-95 8e 9d a8 6f 25 d6 4a   .../...x....o%.J

    0040 - 45 5c 74 a9 6c 2f 2f ff-1b 62 d9 dc 28 e3 ef 0a   E\t.l//..b..(...

    0050 - 9e f7 ed 91 77 99 9c f4-28 b1 19 ee f4 6e fb b2   ....w...(....n..

    0060 - 25 72 8f a6 e3 71 04 58-91 c8 95 8c 2b ee 3c ba   %r...q.X....+.<.

    0070 - fc ea a9 28 cc f7 dc 79-a8 af b9 d3 cd 0a 9d d8   ...(...y........

    0080 - 13 3f d8 99 ea cd 95 69-9a 58 ba ef 55 60 77 2c   .?.....i.X..U`w,

    0090 - 32 83 dc 20 86 b5 85 5a-86 c6 21 fe b7 e3 3e 6a   2.. ...Z..!...>j

    00a0 - d5 f2 2e 23 78 9d 77 1d-e5 78 49 a7 3f 60 f1 c0   ...#x.w..xI.?`..

    00b0 - 3c 3f 36 26 9a dc 1e ce-cd 93 da 57 2b b5 7a 2e   <?6&.......W+.z.

    00c0 - cb 12 7b 20 29 91 2d 0b-27 f3 aa 2e 10 50 c1 79   ..{ ).-.'....P.y

    Start Time: 1639326306

    Timeout   : 7200 (sec)

    Verify return code: 0 (ok)

    Extended master secret: yes

---

GET / HTTP/1.1

Host: site.domain.ru

 

HTTP/1.1 302 Found

Server: nginx

```

Nginx version and config test:

```
#✓/etc/nginx/sites                                                                                   

#wolf # nginx -t 

nginx: the configuration file /etc/nginx/nginx.conf syntax is ok

nginx: configuration file /etc/nginx/nginx.conf test is successful

#✓/etc/nginx/sites                                                                                   

#wolf # nginx -V

nginx version: nginx/1.20.1

built with OpenSSL 1.1.1l  24 Aug 2021

TLS SNI support enabled

configure arguments: --prefix=/usr --conf-path=/etc/nginx/nginx.conf --error-log-path=/var/log/nginx/error_log --pid-path=/run/nginx.pid --lock-path=/run/lock/nginx.lock --with-cc-opt=-I/usr/include --with-ld-opt=-L/usr/lib64 --http-log-path=/var/log/nginx/access_log --http-client-body-temp-path=/var/lib/nginx/tmp/client --http-proxy-temp-path=/var/lib/nginx/tmp/proxy --http-fastcgi-temp-path=/var/lib/nginx/tmp/fastcgi --http-scgi-temp-path=/var/lib/nginx/tmp/scgi --http-uwsgi-temp-path=/var/lib/nginx/tmp/uwsgi --with-compat --with-file-aio --with-http_v2_module --with-pcre --with-threads --without-http_grpc_module --without-http_mirror_module --without-http_scgi_module --without-http_upstream_hash_module --without-http_upstream_ip_hash_module --without-http_upstream_keepalive_module --without-http_upstream_least_conn_module --without-http_upstream_zone_module --with-http_addition_module --with-http_dav_module --with-http_geoip_module --with-http_gunzip_module --with-http_gzip_static_module --with-http_realip_module --with-http_stub_status_module --with-http_xslt_module --with-http_realip_module --add-module=external_module/headers-more-nginx-module-0.33 --add-module=external_module/ngx_cache_purge-2.3 --add-module=external_module/ngx_slowfs_cache-1.10 --add-module=external_module/ngx-fancyindex-0.4.4 --add-module=external_module/ngx_metrics-0.1.1 --add-module=external_module/nginx-dav-ext-module-3.0.0 --with-http_ssl_module --without-stream_access_module --without-stream_geo_module --without-stream_limit_conn_module --without-stream_map_module --without-stream_return_module --without-stream_split_clients_module --without-stream_upstream_hash_module --without-stream_upstream_least_conn_module --without-stream_upstream_zone_module --without-mail_imap_module --without-mail_pop3_module --without-mail_smtp_module --user=nginx --group=nginx

```

Nginx TLS related settings:

```

        listen 443 ssl http2;

        listen [::]:443 ssl http2;

        ssl_stapling            on;

        ssl_certificate         /etc/letsencrypt/domain.ru/fullchain.cer;

        ssl_certificate_key     /etc/letsencrypt/domain.ru/domain.ru.key;

        ssl_trusted_certificate /etc/letsencrypt/lets-encrypt-r3.pem;

        ssl_dhparam             /etc/letsencrypt/dh2048.pem;

        ssl_protocols        TLSv1.3;

        ssl_ciphers             "TLS-CHACHA20-POLY1305-SHA256:TLS-AES-256-GCM-SHA384:TLS-AES-128-GCM-SHA256:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384:DHE-RSA-CHACHA20-POLY1305:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES128-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES256-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-RSA-CHACHA20-POLY1305:TLS_AES_128_GCM_SHA256:TLS_AES_256_GCM_SHA384:TLS_CHACHA20_POLY1305_SHA256";

        ssl_prefer_server_ciphers on;

        add_header Content-Security-Policy-Report-Only  "default-src https:; script-src https: 'unsafe-eval' 'unsafe-inline'; style-src https: 'unsafe-inline'; img-src https: data:; font-src https: data:; report-uri /csp-report";

        add_header Strict-Transport-Security    "max-age=15768000; includeSubDomains; preload;";

        add_header X-Content-Type-Options       nosniff;

        add_header X-Frame-Options              "SAMEORIGIN";

        add_header X-XSS-Protection             "1; mode=block";

        add_header X-Robots-Tag                 none;

```

----------

## pingtoo

Not sure why your openssl test work. I expect it will fail just same as curl test.

I suggest use a simpler nginx setting to begin than add more restriction later, i.e cipher

so, take out ssl_ciphers and ssl_prefer_server_ciphers temporarily. restart/reload nginx and try curl and/or openssl again.

I am guessing you listed more ciphers than TLS1.3 allow.

On my machine openssl only have 3 ciphers

```
user ~ $ openssl version

OpenSSL 1.1.1k  25 Mar 2021

user ~ $ openssl ciphers -v |grep TLSv1.3

TLS_AES_256_GCM_SHA384  TLSv1.3 Kx=any      Au=any  Enc=AESGCM(256) Mac=AEAD

TLS_CHACHA20_POLY1305_SHA256 TLSv1.3 Kx=any      Au=any  Enc=CHACHA20/POLY1305(256) Mac=AEAD

TLS_AES_128_GCM_SHA256  TLSv1.3 Kx=any      Au=any  Enc=AESGCM(128) Mac=AEAD
```

----------

## sabitov

 *Quote:*   

> Not sure why your openssl test work.

 

No, it fails also!  :Smile: 

```
SSL handshake has read 5226 bytes and written 635 bytes

Verification: OK

---

New, TLSv1.2, Cipher is DHE-RSA-AES128-GCM-SHA256 
```

It's funny! It's allowed the only tls 1.3 in nginx config, but it uses tls 1.2 

I commented out ssl_ciphers and ssl_prefer_server_ciphers, restarted nginx and nothing changed  :Sad: 

```
#sabitov@dog $ curl -vL --tlsv1.3 https://......./ 

*   Trying ............:443...

* Connected to ............... (..................) port 443 (#0)

* ALPN, offering h2

* ALPN, offering http/1.1

* successfully set certificate verify locations:

*  CAfile: /etc/ssl/certs/ca-certificates.crt

*  CApath: /etc/ssl/certs

* TLSv1.3 (OUT), TLS handshake, Client hello (1):

* TLSv1.3 (IN), TLS alert, protocol version (582):

* error:1409442E:SSL routines:ssl3_read_bytes:tlsv1 alert protocol version

* Closing connection 0

curl: (35) error:1409442E:SSL routines:ssl3_read_bytes:tlsv1 alert protocol version
```

----------

## sabitov

Wow! It works now!  :Smile: 

----------

## Hu

What did you change to get it to work?

----------

## sabitov

It was a very stupid bug  :Sad: 

My main config of nginx includes several config files, one per site (virtual host). 

Each of them includes file called `SSL_SETTINGS`. This file contains SSL/TLS related settings, 

so if I change something there, it will apply to all sites. But for some historical

(unknown in real  :Wink:  ) reasons one of site-configs does not include SSL_SETTINGS and has its 

own TLS configuration. AND this site config is included BEFORE any other. And, yes, there was 

no TLSv1.3  :Sad: 

If another site config is included before this one, the problem solves. 

If this site config is modified to include SSL_SETTINGS, the problem solves.

The problem was solved, and I found that a half of Inet describes this bug   :Shocked: 

pingtoo, thank you very much! Your advice kicked me to right path, really!  :Smile: 

----------

