My nginx is:
nginx version: nginx/1.11.5
built by gcc 4.8.4 (Ubuntu 4.8.4-2ubuntu1~14.04.1)
built with OpenSSL 1.1.0c 10 Nov 2016
TLS SNI support enabled
configure arguments: --add-module=../ngx_brotli --add-module=../nginx-ct-1.3.1 --with-openssl=../openssl --with-http_v2_module --with-http_ssl_module --with-http_gzip_static_module --with-cc-opt=-Wno-deprecated-declarations
My openssl is 1.1.0c
My cert is ECC384 from let's encrypt
lines from nginx.conf are below:
# hide the nginx version to make it more safe
server_tokens off;
# sslv3 is not safe , so not supproted , but not supporting sslv3 may cause the fact that low version browser can not visit this site
ssl_protocols TLSV1.1 TLSv1.2;
ssl_prefer_server_ciphers on;
# ssl ciphers
ssl_ciphers ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384;
# this is a param used in ECDHE , by default it is 256
#ssl_ecdh_curve secp384r1; # Requires nginx >= 1.1.0
# for some reason, using X25519 instead of secp384r1
ssl_ecdh_curve X25519;
resolver 8.8.8.8 8.8.4.4 valid=300s;
resolver_timeout 5s;
I found a strange thing:
if I specify ssl_ecdh_curve X25519; in Nginx conf file , my chrome(55 x64) and firefox will not be albe to visit my site:

Howerver, if I comment the line ssl_ecdh_curve X25519;, it will work , and the chrome says it is X25519:

but the firefox:

A little bit strange why 2 different browser will give different results.
So I want to figure out two questions:
This should really have been a question on the openssl-users mailing list...
This is a known issue in OpenSSL 1.1.0. When you explicitly specify
the list of supported curves (by selecting an explicit ecdhe curve)
this limits the set of curves supported in certificates, and in particular,
the the secp384r1 cert is not matched.
Correct behaviour would be to restrict only ECDHE to X25519, and for
certificate selection still use secp384r1 if no other certificate is
available.
That said, OpenSSL 1.1.0 by default supports a list of algorithms with
X25519 preferred over P-384, so not setting the curves explicitly is
likely better.
For the record, this is a duplicate of #2033
My understanding:
ECC cert use a curve and the key exchange procedure also use a curve.
These two can be different.
However, if you set
ssh_ecdh_curve X25519;
into the Nginx under openssl 1.1.0c
the Nginx/openssl will use X25519 to both the two places above .which is not correct because X25519 can only be used in key exchange.
My solution is (only suitable for my config):
ssh_ecdh_curve X25519:spec384r1; this is perfect for me because chrome and other browsers forked from chrome(I mean use similar kernel will prefer X25519) explicitly set ssh_ecdh_curve X25519:spec384r1;
Sorry to comment on this rather old issue. But shouldn't it be ssl_ecdh_curve X25519:secp384r1 instead?
NGINX does not have a directive that starts with ssh and the curve is not spec384r1 but secp384r1.
Most helpful comment
My understanding:
ECC cert use a curve and the key exchange procedure also use a curve.
These two can be different.
However, if you set
ssh_ecdh_curve X25519;into the Nginx under openssl 1.1.0c
the Nginx/openssl will use X25519 to both the two places above .which is not correct because X25519 can only be used in key exchange.
My solution is (only suitable for my config):
ssh_ecdh_curve X25519:spec384r1;this is perfect for me because chrome and other browsers forked from chrome(I mean use similar kernel will prefer X25519)