Nginx and ephemeral Diffie-Hellman keys

I’ve been fighting with this all do so hopefully someone can help shed
some light.

I have a site configured to use SSL and it current does successfully
negotiate SSL. However, I am not able for the life of me to get nginx to
offer up DH keys/ciphers.

What I am able to get negotiated is AES256-SHA. What I would like to be
able to see is DHE-RSA-AES256-SHA

The following is that I have set currently.

ssl_prefer_server_ciphers on;
ssl_protocols SSLv3 TLSv1;

# Set the ciphers to use. See


ssl_ciphers
DHE-RSA-AES256-SHA:DHE-RSA-AES128-SHA:EDH-RSA-DES-CBC3-SHA:AES256-SHA:DES-CBC3-SHA:AES128-SHA:RC4-SHA:RC4-MD5;

Using http://www.serversniff.net/sslcheck.php and vurbu.com:443, it
looks like only RSA key exchanges are successful.

I have concatenated the DH params to the certificate with no effect.
dhparams was created with the following command

openssl dhparam -dsaparam -out dh1024dsa.pem -5 1024

Also looking at the nginx error log files, I see a lot of

SSL23_GET_CLIENT_HELLO:unknown protocol
SSL3_GET_CLIENT_HELLO:no shared cipher

yet the odd thing is I am able to successfully access https://vurbu.com/

nginx was compiled using the following flags.

~/src/nginx-0.7.1$ ./configure --with-http_ssl_module
–add-module=…/nginx-upstream-fair/ --with-http_gzip_static_module

Any suggestions would be welcome.

On Fri, Jun 13, 2008 at 04:54:45AM +0200, Jauder Ho wrote:

The following is that I have set currently.
looks like only RSA key exchanges are successful.

yet the odd thing is I am able to successfully access https://vurbu.com/

nginx was compiled using the following flags.

~/src/nginx-0.7.1$ ./configure --with-http_ssl_module
–add-module=…/nginx-upstream-fair/ --with-http_gzip_static_module

Any suggestions would be welcome.

nginx does not support DH keys.
The attached patch adds ssl_dhparam directive:

  ssl_dhparam   /path/to/PEM_DHparam;

Igor,

Thanks much! I just applied the patch (to 0.7.1) and tried it out. The
patch works as expected and supports both strong prime and DSA style DH
keys.

For the record, the DH keys were generated with the following commands
(with the dsaparam being more efficient but less secure. see dhparam man
page).

openssl dhparam -out dh1024.pem -5 1024
openssl dhparam -dsaparam -out dh1024dsa.pem -5 1024

–Jauder

Igor S. wrote:

nginx does not support DH keys.
The attached patch adds ssl_dhparam directive:

  ssl_dhparam   /path/to/PEM_DHparam;

On a separate note, in testing with
http://www.serversniff.net/sslcheck.php

It is noted that nginx only partially supports TLS closures. See section
2.2 of http://tools.ietf.org/html/rfc2818

–Jauder

On Fri, Jun 13, 2008 at 01:52:35PM +0200, Jauder Ho wrote:

Thanks much! I just applied the patch (to 0.7.1) and tried it out. The
patch works as expected and supports both strong prime and DSA style DH
keys.

For the record, the DH keys were generated with the following commands
(with the dsaparam being more efficient but less secure. see dhparam man
page).

openssl dhparam -out dh1024.pem -5 1024
openssl dhparam -dsaparam -out dh1024dsa.pem -5 1024

I’m going to use some hardcoded pregenerated DH parameters (as Apache
does)
and allow to override them using the ssl_dhparam directive.

On Fri, Jun 13, 2008 at 01:55:21PM +0200, Jauder Ho wrote:

On a separate note, in testing with
http://www.serversniff.net/sslcheck.php

It is noted that nginx only partially supports TLS closures. See section
2.2 of http://tools.ietf.org/html/rfc2818

I do not know what they means under partially support of TLS closures,
however, nginx sends TLS close notify alert, but does not wait it from
client because many browsers including MSIE does not send this alert.

On Fri, Jun 13, 2008 at 06:06:37PM +0400, Igor S. wrote:

openssl dhparam -out dh1024.pem -5 1024
openssl dhparam -dsaparam -out dh1024dsa.pem -5 1024

I’m going to use some hardcoded pregenerated DH parameters (as Apache does)
and allow to override them using the ssl_dhparam directive.

Here is updated patch.

Looking at the RFC text, if nginx sends TLS close notify, and does not
wait, does it reuse the session?

The other test case would be of premature close (if client closes
connection without sending alert), session must be abandoned and not
reused.

Igor S. wrote:

On Fri, Jun 13, 2008 at 01:55:21PM +0200, Jauder Ho wrote:

On a separate note, in testing with
http://www.serversniff.net/sslcheck.php

It is noted that nginx only partially supports TLS closures. See section
2.2 of http://tools.ietf.org/html/rfc2818

I do not know what they means under partially support of TLS closures,
however, nginx sends TLS close notify alert, but does not wait it from
client because many browsers including MSIE does not send this alert.

On Fri, Jun 13, 2008 at 10:53:29PM +0200, Jauder Ho wrote:

Looking at the RFC text, if nginx sends TLS close notify, and does not
wait, does it reuse the session?

Yes, nginx allows to reuse sessions.
However, you should use cache shared across workers:
http://wiki.codemongers.com/NginxHttpSslModule#ssl_session_cache

The other test case would be of premature close (if client closes
connection without sending alert), session must be abandoned and not
reused.

No, nginx nevertheless allows to reuse these sessions,
otherwise all MSIE connections will require SSL handshake.

Igor S. wrote:

Yes, nginx allows to reuse sessions.
However, you should use cache shared across workers:
http://wiki.codemongers.com/NginxHttpSslModule#ssl_session_cache

Ah yes. I did not see that parameter previously. Enabled…

The other test case would be of premature close (if client closes
connection without sending alert), session must be abandoned and not
reused.

No, nginx nevertheless allows to reuse these sessions,
otherwise all MSIE connections will require SSL handshake.

I have not looked closely at the code but do you differentiate between
SSL and non SSL sessions? That could be one way of figuring which
session to dump.

Patch applied and testing now.

From reading the patch, it looks like the key is generated once. I did
some more digging and reference
http://mail-archives.apache.org/mod_mbox/httpd-cvs/200205.mbox/[email protected]>

Key should be changed out every so often.

  • o Diffie-Hellman-Parameters for temporary keys are hardcoded in
  • ssl_engine_dh.c, while the comment in ssl_engine_kernel.c says:
  • "it is suggested that keys be changed daily or every 500
  • transactions, and more often if possible."

Igor S. wrote:

Here is updated patch.

On Fri, Jun 13, 2008 at 11:24:04PM +0200, Jauder Ho wrote:

connection without sending alert), session must be abandoned and not
reused.

No, nginx nevertheless allows to reuse these sessions,
otherwise all MSIE connections will require SSL handshake.

I have not looked closely at the code but do you differentiate between
SSL and non SSL sessions? That could be one way of figuring which
session to dump.

What you mean “SSL and non SSL sessions” ? There is no “non SSL
sessions”
in SSL terms.

On Sat, Jun 14, 2008 at 08:09:13AM +0400, Igor S. wrote:

Key should be changed out every so often.

  • o Diffie-Hellman-Parameters for temporary keys are hardcoded in
  • ssl_engine_dh.c, while the comment in ssl_engine_kernel.c says:
  • "it is suggested that keys be changed daily or every 500
  • transactions, and more often if possible."

Nevertheless Apache still uses hardcoded DH parameters and does not allow
to override them.

Looking in Apache repo: modern DH params in Apache/2 are 3 years old,
Apache’s 1.3 DH params are 9 years old.

It’s seems thare is no need to override them using ssl_dhparam.

Having the option would still beneficial since the capability is already
there.

Igor S. wrote:

On Sat, Jun 14, 2008 at 08:09:13AM +0400, Igor S. wrote:

Key should be changed out every so often.

  • o Diffie-Hellman-Parameters for temporary keys are hardcoded in
  • ssl_engine_dh.c, while the comment in ssl_engine_kernel.c says:
  • "it is suggested that keys be changed daily or every 500
  • transactions, and more often if possible."

Nevertheless Apache still uses hardcoded DH parameters and does not allow
to override them.

Looking in Apache repo: modern DH params in Apache/2 are 3 years old,
Apache’s 1.3 DH params are 9 years old.

It’s seems thare is no need to override them using ssl_dhparam.

On Fri, Jun 13, 2008 at 11:13:37PM +0200, Jauder Ho wrote:

Patch applied and testing now.

From reading the patch, it looks like the key is generated once. I did

No, not key itself but DH parameters, those will be used to generate DH
keys.

some more digging and reference
http://mail-archives.apache.org/mod_mbox/httpd-cvs/200205.mbox/[email protected]>

Key should be changed out every so often.

  • o Diffie-Hellman-Parameters for temporary keys are hardcoded in
  • ssl_engine_dh.c, while the comment in ssl_engine_kernel.c says:
  • "it is suggested that keys be changed daily or every 500
  • transactions, and more often if possible."

Nevertheless Apache still uses hardcoded DH parameters and does not
allow
to override them.

Actually both nginx and Apache use
SSL_CTX_set_options(SSL_OP_SINGLE_DH_USE)
and OpenSSL generate new DH key during the negotiation.

BTW, while RSA-only case the only keys used in negotiation are
server certificate keys, those are not changed one year.

On Sat, Jun 14, 2008 at 05:15:09PM +0200, Luca M. wrote:

Igor S. wrote:

On Fri, Jun 13, 2008 at 06:06:37PM +0400, Igor S. wrote:
Here is updated patch.

I just tried the patch on an nginx 0.5.32, it applied correclty but i
have to change the ngx_conf_full_name(cf->cycle, file, 1) call into
ngx_conf_full_name(cf->cycle, file) to make it compile.

I tried the server and it seems to work correctly, but i am a bit
dubious about the change i have done. Do you think it’s ok?

Yes, it’s ok.

Igor S. wrote:

On Fri, Jun 13, 2008 at 06:06:37PM +0400, Igor S. wrote:
Here is updated patch.

I just tried the patch on an nginx 0.5.32, it applied correclty but i
have to change the ngx_conf_full_name(cf->cycle, file, 1) call into
ngx_conf_full_name(cf->cycle, file) to make it compile.

I tried the server and it seems to work correctly, but i am a bit
dubious about the change i have done. Do you think it’s ok?

thanks!
Luca