benoitc / hackney

simple HTTP client in Erlang
Other
1.34k stars 427 forks source link

SSL Problem with valid cert #253

Closed bipthelin closed 8 years ago

bipthelin commented 8 years ago

We're seeing strange problems with Hackney. We've been using 0.13.0 for a long time and decided to upgrade. We rolled a new release of our sw using Hackney 1.3.2 but immediately started seeing weird issues with SSL, we get a {error,{tls_alert,"certificate unknown"}} when we try to connect to our internal https-service. The site in questions serves well over curl and what we found is that if you do a httpc:request(get, url) hackney will start giving correct responses for a while until (we guess) some cache is evicted and hackney goes back to giving the same errors. Here's an example:

1> hackney:request(get, <<"https://foo.bar">>).
{error,{tls_alert,"certificate unknown"}}
2> httpc:request("https://foo.bar").         
{ok,{{"HTTP/1.1",404,"Not Found"},
     [{"connection","keep-alive"},
      {"date","Mon, 26 Oct 2015 18:57:16 GMT"},
      {"server","nginx"},
      {"content-length","100"},
      {"content-type","text/html; charset=UTF-8"}],
     "<html><body><h2>404 Not found</h2>The requested route [/] has not been mapped in Spark</body></html>"}}
3> hackney:request(get, <<"https://foo.bar">>).
{ok,404,
    [{<<"Server">>,<<"nginx">>},
     {<<"Date">>,<<"Mon, 26 Oct 2015 18:57:20 GMT">>},
     {<<"Content-Type">>,<<"text/html; charset=UTF-8">>},
     {<<"Content-Length">>,<<"100">>},
     {<<"Connection">>,<<"keep-alive">>}],
    #Ref<0.0.1.85148>}

And this also applies to external services:

4> hackney:request(get, <<"https://www.google.com">>).
{error,{tls_alert,"certificate unknown"}}

But after a httpc:request/2 it works for a while.

bipthelin commented 8 years ago

Also, this is on erlang 17.5 and the error messages indicates this line: https://github.com/erlang/otp/blob/OTP-17.5/lib/ssl/src/ssl_handshake.erl#L438

benoitc commented 8 years ago

@bipthelin it's probably due to an issue under erlang 17.5. With OTP 18:

[hackney] erl -pa _build/default/lib/*/ebin                                                                                   10:59:04  ☁  master ☀
Erlang/OTP 18 [erts-7.0.3] [source] [64-bit] [smp:4:4] [async-threads:10] [kernel-poll:false]

Eshell V7.0.3  (abort with ^G)
1> application:ensure_all_started(hackney).
{ok,[crypto,asn1,public_key,ssl,idna,mimerl,certifi,
     hackney]}
2> hackney:request(get, <<"https://www.google.com">>).
{ok,302,
    [{<<"Cache-Control">>,<<"private">>},
     {<<"Content-Type">>,<<"text/html; charset=UTF-8">>},
     {<<"Location">>,
      <<"https://www.google.fr/?gfe_rd=cr&ei=NUsvVvLMKYnf8geP1ZOYDQ">>},
     {<<"Content-Length">>,<<"259">>},
     {<<"Date">>,<<"Tue, 27 Oct 2015 10:00:21 GMT">>},
     {<<"Server">>,<<"GFE/2.0">>},
     {<<"Alternate-Protocol">>,<<"443:quic,p=1">>},
     {<<"Alt-Svc">>,
      <<"quic=\"www.google.com:443\"; p=\"1\"; ma=600,quic=\":443\"; p=\"1\"; ma="...>>}],
    #Ref<0.0.4.67>}

Maybe you can upgrade your version of Erlang. Another way to do it is using the "insecure" setting when doing a request. It should bypass the verification.

benoitc commented 8 years ago

bump.

bipthelin commented 8 years ago

Let's close this issue. We downgraded Hackney and now everything is working. We'll try upgrading again when we can move to 18

benoitc commented 8 years ago

hrm do you mean you downgraded Hackney? Why not simply using the insecure option?

Stratus3D commented 6 years ago

I'm experiencing this with Hackney 1.0.6 and Erlang 18.2. Very odd, if I switch my code to use httpc for a minute and then switch back to hackney it works fine.

Stratus3D commented 6 years ago

It looks like in my case httpc wasn't doing hostname checking at all. Whereas hackney was trying to. Configuring httpc to verify hostnames results in the same error as hackney, so clearly my issue is with my CA file the clients are using or the cert on the server I'm trying to connect to.