I’m trying to get communication between an H2 TLS client (lwt-unix) and an etcd server but am coming across the following error from the connection:
Prohibited TLS 1.2 Cipher Suite: 9d
with the code ‘INADEQUATE_SECURITY (0xc)’ returned too. I’m not too sure if this may be an issue on my side, in ocaml-tls or in etcd somehow but if anyone has ideas I’d be grateful to hear.
The HTTP/2 specification contains a list of prohibited ciphersuites. You’re most likely using one of those via OCaml-TLS.
Sounds like 9d refers to TLS_RSA_WITH_AES_256_GCM_SHA384
I so far did not use “h2-lwt”, but you can always decide to pass in your custom subset of ciphersuites to use for TLS connections on constructing the client (see https://mirleft.github.io/ocaml-tls/doc/tls/Tls/Config/index.html#val-client), a list of ciphersuites (polyvars) is available at https://mirleft.github.io/ocaml-tls/doc/tls/Tls/Ciphersuite/index.html#type-ciphersuite
From the list posted by @anmonteiro, it looks to me you’d like to avoid the non-foward secure ones, maybe using https://mirleft.github.io/ocaml-tls/doc/tls/Tls/Config/Ciphers/index.html#val-fs is sufficient? (i.e.
let client = Tls.Config.client ~ciphers:Tls.Config.Ciphers.fs () in ...) Do you have some example code and a remote host to test with available? May be worth to implement a
val Tls.Config.Ciphers.http2 : Tls.Ciphersuite.ciphersuite list if the above
fs is not sufficient (it looks like HTTP2 disallows block cipher mode DHE_RSA_AES_128_CBC_SHA etc.).
Thanks for the thorough reply!
It seems h2 uses gluten which handles the Tls client config so that might need a patch to allow the right suites to be passed.
I’ll have a look at the allowed ciphersuites and compare what seems to be allowed or not, if not then a new value in ocaml-tls would be nice.
I have some in progress code but am just testing with a local dockerised etcd.
thanks for your PR to OCaml-TLS, this is released as tls 0.12.7 (now PRed to opam-repository).
Thanks! I’ve made some changes in gluten and ocaml-h2 for testing this and have created https://github.com/jeffa5/ocaml-h2-tls-test to test things. The Prohibited suites message has gone but now I’m getting a Handshake failure alert from peer.
From what I can see in the logs and using openssl against etcd, etcd has the following ciphers:
and the client has
which I think would overlap so I’m not sure how else the handshake could be failing.
That’s good, there is some progress What “Handshake failure alert from peer” do you get, something more verbose? (Tls_lwt since 0.12.4 registers printers for Tls_alert and Tls_failure (see https://github.com/mirleft/ocaml-tls/blob/fff4c964c0018fa60908a3dcb0310d8c1ca81890/lwt/tls_lwt.ml#L267) that should lead to a more verbose error message.
I tested locally (without gluten / h2 – the reason being that you mentioned a TLS problem, so I’d like to reproduce this without extra dependencies (h2/…)) in the following way: I installed etcd 3.4.13, and established TLS connections using:
- openssl s_client -connect 127.0.0.1:2379 -alpn h2 | hexdump
- _build/default/lwt/examples/http_client.exe 127.0.0.1 2379 NONE (with a modified http_client.ml that sends “h2” as alpn_protocols – even not using
And both are able to establish TLS connections, and receive from the server:
00 00 18 04 00 00 00 00 00 00 05 00 10 00 00 00
03 00 00 00 fa 00 06 00 10 01 40 00 04 00 10 00
Any idea how to configure my etcd to be able to reproduce the issue you encounter? Which etcd version do you use? I start it with
etcd --cert-file=/home/hannes/mirage/ocaml-tls/certificates/server.pem --key-file=/home/hannes/mirage/ocaml-tls/certificates/server.key --advertise-client-urls=https://localhost:2379 --listen-client-urls=https://localhost:2379 --log-level=debug
Thanks for taking another look, the full error was
exception TLS alert from peer: HANDSHAKE_FAILURE
Here: https://github.com/jeffa5/ocaml-h2-tls-test I’ve got the config to launch etcd in a container and generate the certs using cfssl.
make etcd should generate the certs and launch an etcd (available on localhost:2379), version is 3.4.13 and the args look similar.
openssl s_client command seems to connect ok before etcd closes the connection (I guess due to not sending any data after a timeout).
Trying the ocaml-tls example client with those modifications I get the following:
Prohibited TLS 1.2 Cipher Suite: 9d++ done.
which seems to be consistent with the initial error, so adding the
~ciphers option for http2 I get:
(TLS ALERT (remote end): HANDSHAKE_FAILURE)
Fatal error: exception TLS alert from peer: HANDSHAKE_FAILURE
which again seems consistent.
I’d guess that it might be a non-overlapping set of ciphersuites whereas openssl has some others that overlap? But from my previous post I think there should be some overlap anyway.
Sorry, I’m still unable to reproduce this issue locally. Tls provides extensive logging via the Logs library on the debug level – so in your application if you setup a log reporter and the log level to debug, you should be able to observe the exchanged handshake frames (the lwt/examples/echo_client.ml does this, you can supply
-vv to see logging at the debug level).
But it looks like it’s the server side (etcd) which bails on the TLS connection, so you may need to setup logging/tracing there to observe whether etc has more detailed information than HANDSHAKE_FAILURE.
Thanks, strange you can’t reproduce it.
I’ve put the logs here for both the executable and etcd (with debug on) https://gist.github.com/jeffa5/eb323d720f0f2ecae3c30e192ca40505
Indeed it seems that etcd doesn’t like the suites
tls: no cipher suite supported by both client and server
Even if I set
--cipher-suites TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 on etcd it complains with the same error, despite that being advertised in the tls logs? It is even one of the ones mentioned here https://github.com/etcd-io/etcd/blob/170af891d692391d283cc21ac65c712279ff64ab/Documentation/op-guide/security.md so it should be supported by etcd. Really not sure where the negotiation is going wrong.
Unfortunately etcd doesn’t have very verbose logging…
Dear @jeffa5, after some more code reading, debugging, and attempting at reconfiguring “etcd”, I was able to get such an error eventually (thanks for pointing to
--cipher-suites – though I still have not figured out what values are accepted for this command line option).
Anyways, I prepared https://github.com/mirleft/ocaml-tls/pull/424 which re-adds the client and server hello extension ECPointfFormats (deprecated in https://tools.ietf.org/html/rfc8422 - but it looks like Go requires it for unknown reasons). Now, a client hello with <TLS1.3 support and any ECC cipher will add a “ECPointFormats [ Uncompressed ]” hello extension (and the server hello will include the same upon a <TLS1.3 client that sent such an extension when a ECC ciphersuite was selected). Would you mind to pin your tls with
opam pin add tls git+https://github.com/hannesm/ocaml-tls.git#ecc-go-tls-1-2 and report back whether this fixes your issue above (the “tls: no cipher suite supported by both client and server”)? If this works fine for you, I’ll run some more interoperability tests and prepare a next release of tls.
Thanks for your valuable input of your issue & your debugging and tracing.
Hi @hannes, great to hear it wasn’t just a strange configuration issue on my end!
No, I find the values for that option very obscure and only found them through some searching on their issues.
I’ve added the pin and tested again. It works! The tls connection gets established without errors.
Thanks for filtering through the logs and helping with this! The etcd team seem to be keeping an eye on some security things but I guess this may have missed them.
thanks for confirmation, this is now PRed to opam-repository as tls 0.12.8 https://github.com/ocaml/opam-repository/pull/17795