[Ach] Some testing with ACH Cipherstrings and HTTP/2 on nginx

Pepi Zawodsky pepi.zawodsky at maclemon.at
Thu Nov 5 16:43:47 CET 2015


HTTP/2 test tools show mostly incorrect results. Do NOT rely on them at all!
Browser errors regarding HTTP/2 are misleading bullshit and not helpful.
HTTP/2 really IS fast.
We must do a substantial update to ACH for HTTP/2 with TLS 1.2.


I’ve been learning about HTTP/2 in the recent months and now that nginx officially support ngx_mod_http2 I thought, I’d finally implement it on my own sites. (Did some playing around with h2o but not on a “production site”.)

For my tests I was using our current (as of 2015-11-05) CipherStrings with nginx 1.9.6 +http2 linked against OpenSSL 1.0.2d 9 Jul 2015 (on OS X Mavericks 10.9.5).

A few observations:
SSLLabs excellent test gets quite confused when it comes to HTTP/2. You can NOT rely on most of the results.

Like info about Common DH-Params telling you there are no DHE cipher suites active, when there actually are some configured and the handshake simulation even shows you that some browsers use them.
Also you get Browser handshakes that say, TLS 1.2 with such and such cipher when the actual Browser balks with an error and doesn’t connect at all.

Chromium will show an ERR_SPDY_INADEQUATE_TRANSPORT_SECURITY (even though it’s using HTTP/2)
Firefox simply displays a blank page and nothing else.
Safari happily connects and doesn’t make any statement about the protocol or ciphers in use.

Just be aware that you cannot rely on the test results/score when HTTP/2 is configured on the server.

I’ve already contacted Ivan Ristić about this and he has confirmed that the test does not take h2 into consideration. This affects especially handshake simulation and DH-Params warnings.


Test results:

Using ACH: 1bf7762 (2015-10-22 19:04:09 +0200) Aaron Zauner

$ openssl version
OpenSSL 1.0.2d 9 Jul 2015 on OS X 10.9.5 (Mavericks) YMWV!

$ nginx -V
nginx version: nginx/1.9.6
built with OpenSSL 1.0.2d 9 Jul 2015
TLS SNI support enabled
--with-ipv6 --with-http_flv_module --with-http_gzip_static_module --with-http_ssl_module --with-http_v2_module --with-http_mp4_module --with-http_secure_link_module

CipherString A:

expands to
$ openssl ciphers 'EDH+aRSA+AES256:EECDH+aRSA+AES256:!SSLv3'

This cipher string is NOT HTTP/2 spec compliant!
It doesn’t matter which ECDHE curve is selected.

Chrome, Canary, Chromium, Firefox, Aurora do NOT connect to a site configured with this cipher string.
Safari 9 does (which makes me wonder if Safari/OS X does some (illegal) protocol fallback here.)


CipherString B:

expands to


This cipherstring seems to work with HTTP/2.
It doesn’t matter which ECDHE curve is selected.

Chrome, Canary, Chromium, Firefox, Aurora, Safari DO connect to a site configured with this cipher string without showing errors.


HTTP/2 blacklisted ciphers:

Quoting form HTTP/2 spec:

“The black list includes the cipher suite that TLS 1.2 makes mandatory, which means that TLS 1.2 deployments could have non-intersecting sets of permitted cipher suites. To avoid this problem causing TLS handshake failures, deployments of HTTP/2 that use TLS 1.2 MUST support TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 [TLS-ECDHE] with the P-256 elliptic curve [FIPS186].”


Regarding ECDHE Curve selection:
Our recommendation has been to use NIST Curve secp384r1. (Which is supported across all clients capable of ECDHE)

HTTP/2 requires that webserver MUST support TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 with prime256v1.

For nginx this means:
ssl_ecdh_curve          prime256v1; # HTTP/2 mandatory curve

Interestingly enough all browsers I’ve tested did connect fine with HTTP/2 TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 and curve secp384r1, though this should be out of spec for HTTP/2.

I did not test ANY IE/Edge browsers as I don’t have access to them.

I’ve only tested with nginx 1.9.6 so far, but may get the (questionable) opportunity to dig into Apache 2.4.17 with mod_h2 in the near future.


Typical symptoms for non-compliant cipher suites configs with HTTP/2:

Chromium: Version 48.0.2539.0 (64-bit)
Chrome Canary: Version 48.0.2555.0 canary (64-bit)

Chromium balks at the connection with: ERR_SPDY_INADEQUATE_TRANSPORT_SECURITY and no further explanation or details. Yes, it really says SPDY.

The webpage at https://maclemon.at/ might be temporarily down or it may have moved permanently to a new web address. (Which is bullshit.)


Firefox 41.0.2
Firefox 42.0
Firefox Developer Edition (Aurora) 44.0a2 (2015-11-05)

Your connection is not secure

The owner of maclemon.at has configured their website improperly. To protect your information from being stolen, Firefox has not connected to this website.
Advanced info: ssl_error_no_cypher_overlap

Using the Advanced Button reveals this bit:
maclemon.at uses security technology that is outdated and vulnerable to attack. An attacker could easily reveal information which you thought to be safe.
(Not secure) Try loading maclemon.at using outdated security

cypher with y. :-) They could’ve said no cyber overlap as well.
The wording is pretty much bogus, given that its TLS 1.2 with GCM suites, or maybe Mozilla knows something we don’t.


Upon trying to reload the page “using outdated security”:

Secure Connection Failed

An error occurred during a connection to maclemon.at. The server rejected the handshake because the client downgraded to a lower TLS version than the server supports. (Error code: ssl_error_inappropriate_fallback_alert)

    The page you are trying to view cannot be shown because the authenticity of the received data could not be verified.
    Please contact the website owners to inform them of this problem.

You’re given the option to report the page in question to Mozilla so they can identify malware sites.



Short term:
We must add a note to the guide that our recommendations do not work with HTTP/2.

Longer term:
We must update the cipher suites for HTTP/2 use.
We must update curve selection once more to match HTTP/2.

I don’t see any way we can still provide one or two one-cipherstring-fits-all solution working for HTTP/1.1, HTTP/2 and across TLS 1.0, 1.1 and 1.2.

Actually you’d want to be able to configure different cipher suites for each protocol to get the best security and performance.

Actually actually you’d want to server different cipher suites depending on the existence and contents of NPN and ALPN headers in the client_hello. I’ll hopefully get a chance to look at nghttpx to look into that.

A suite generator similar to mozilla’s is necessary.


Error messages given by Browsers are horribly unhelpful and maybe even harmful.

All the web services claiming to test for SPDY and/or HTTP/2 compliance are do not work at all, or give completely bogus results. SSLLabs also is NOT to be relied on for webservers using HTTP/2.

Most honest and correct message I got was:

Something went wrong on our end.


Hope this helps someone!
I’ll keep experimenting!

Best regards
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 801 bytes
Desc: Message signed with OpenPGP using GPGMail
URL: <http://lists.cert.at/pipermail/ach/attachments/20151105/b7e0c6be/attachment.sig>

More information about the Ach mailing list