curl icon indicating copy to clipboard operation
curl copied to clipboard

SSL Connect Error

Open Bab95 opened this issue 2 years ago • 12 comments
trafficstars

I have been working on a application which uses curl for communication to server. Sometimes i get SSL Connect error.

I did this

I tried to increase verbosity on a machine where this issue is occurring and got a ssl handshake error. Code for Increasing verbosity:

static int trace(CURL* handle, curl_infotype type, char* data, size_t size, void* userp)
{
    switch (type)
    {
        case CURLINFO_TEXT:
            CLIENT_LOG_DEBUG("== Info: %s", data);
            break;
        default:
            return 0;
        case CURLINFO_HEADER_OUT:
            CLIENT_LOG_DEBUG("=> Send header: %s", data);
            break;
        case CURLINFO_DATA_OUT:
            CLIENT_LOG_DEBUG("=> Send data: %s", data);
            break;
        case CURLINFO_SSL_DATA_OUT:
            CLIENT_LOG_DEBUG("=> Send SSL data: %s", data);
            break;
        case CURLINFO_HEADER_IN:
            CLIENT_LOG_DEBUG("<= Recv header: %s", data);
            break;
        case CURLINFO_DATA_IN:
            CLIENT_LOG_DEBUG("<= Recv data: %s", data);
            break;
        case CURLINFO_SSL_DATA_IN:
            CLIENT_LOG_DEBUG("<= Recv SSL data: %s", data);
            break;
    }
    return 0;
}




/// at caller method:

     CLIENT_LOG_INFO("TRACE_LEVEL_HIGH");
    curl_easy_setopt(curl, CURLOPT_DEBUGFUNCTION, trace);
    curl_easy_setopt(curl, CURLOPT_DEBUGDATA, 1L);
    curl_easy_setopt(curl, CURLOPT_VERBOSE, 1);

/// Other curl options set while making connection:

curl_easy_setopt(curl, CURLOPT_HTTPHEADER, headers);
curl_easy_setopt(curl, CURLOPT_URL, url.c_str());
curl_easy_setopt(curl, CURLOPT_CUSTOMREQUEST, "PUT");
curl_easy_setopt(curl, CURLOPT_POSTFIELDS, payload.c_str());
curl_easy_setopt(curl, CURLOPT_POSTFIELDSIZE, payload.size());

#ifndef PLATFORM_UNIX
curl_easy_setopt(curl, CURLOPT_CAINFO, "curl-ca-bundle.crt");
#endif

curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, WriteResponseCallback);
curl_easy_setopt(curl, CURLOPT_WRITEDATA, &response);
curl_easy_setopt(curl, CURLOPT_TIMEOUT, 20L);

curl::SendRequest:314 TRACE_LEVEL_HIGH trace:45 == Info: Trying <IP>:443...

trace:45 == Info: Connected to <URI> (<IP>) port 443 (#0)

trace:45 == Info: schannel: disabled automatic use of client certificate

trace:45 == Info: ALPN: offers http/1.1

trace:45 == Info: schannel: failed to receive handshake, SSL/TLS connection failed

trace:45 == Info: Closing connection 0

curl::SendRequest:387 Failed sending curl request with error:SSL connect error

I expected the following

I am only getting CUL_INFO_TEXT logs neither, no header out, data out etc.

curl/libcurl version

7.86 [curl -V output]

operating system

Windows

Bab95 avatar Dec 20 '22 19:12 Bab95

curl_easy_setopt(curl, CURLOPT_VERBOSE, 1);

This should pass in a long, not an int.

trace:45 == Info: schannel: failed to receive handshake, SSL/TLS connection failed

An encrypted connection couldn't even be made to the site, so the headers and data were never sent.

dfandrich avatar Dec 20 '22 20:12 dfandrich

Okay. I should pass it as long. But that seems irrelevant here. Binary’s working fine.

what could be the reason for the connection not made. This issue is occurring on some machines only not all the machines running application.

Bab95 avatar Dec 20 '22 20:12 Bab95

It might well be an issue with the server, not the client. "failed to receive handshake" sounds like the server isn't starting TLS properly. Does it still happen if you switch to another TLS back-end?

dfandrich avatar Dec 20 '22 21:12 dfandrich

I suppose this only happens against one particular host or does it reproduce against other and public hosts you can tell us about?

bagder avatar Dec 20 '22 22:12 bagder

This is happening on about more than at least 100 machines.

Bab95 avatar Dec 21 '22 05:12 Bab95

My money is still on a server problem or a networking gateway/firewall/proxy issue.

dfandrich avatar Dec 21 '22 05:12 dfandrich

@dfandrich is there a way to confirm this that the issue has been happening because of some firewall user applied? Any tool that can confirm and pinpoint in this direction?

User is able to ping to the server. It was tested with Test-NetConnection Powershell.

test-NetConnection -ComputerName -Port 443 -InformationLevel Detailed

Result ComputerName : server-url

RemoteAddress : server-ip

RemotePort : 443

NameResolutionResults : server-ip

MatchingIPsecRules :

NetworkIsolationContext : Internet

InterfaceAlias : Ethernet

SourceAddress : source-ip

NetRoute (NextHop) : some-ip

TcpTestSucceeded : True

Bab95 avatar Dec 21 '22 07:12 Bab95

Working scenario situation is like below:

trace:43 == Info: Connected to SERVER_URL (IP) port 443 (#0)

trace:43 == Info: schannel: disabled automatic use of client certificate

trace:43 == Info: ALPN: offers http/1.1

trace:43 == Info: schannel: added 138 certificate(s) from CA file 'curl-ca-bundle.crt'

trace:43 == Info: schannel: connection hostname (SERVER_URL) did not match against certificate name (JUMBLED_URL)

trace:43 == Info: schannel: connection hostname (SERVER_URL) validated against certificate name (*.SUFFIX)

trace:43 == Info: ALPN: server did not agree on a protocol. Uses default.

trace:48 => Send header: PUT /something?api-version=2020-03-31-preview HTTP/1.1

Host: SERVER_URL

Accept: /

Bab95 avatar Dec 21 '22 16:12 Bab95

@bagder Is there a way to debug why this issue has been happening? why handshake is failing? If it's because of firewalls is there a way to confirm it by putting some debugging logs?

Bab95 avatar Dec 28 '22 18:12 Bab95

You can:

  1. try curl built with another TLS backend to see if it works/gives another/better error message
  2. try against other servers and see if the problem continues or how it changes and try to figure out why
  3. try running your code from other machines/networks to see if that changes anything
  4. wireshark the TLS handshake and check what happens in detail
  5. work on a way for others to reproduce the problem to be able to help

bagder avatar Dec 28 '22 22:12 bagder

@bagder any suggestion on curl built with TLS backend? what are the different options? As i explained earlier this error is not consistent. but it's happening on some machines

Bab95 avatar Dec 29 '22 20:12 Bab95

I would consider trying it out with a build using OpenSSL as that's the most commonly used TLS backend in curl.

bagder avatar Dec 30 '22 15:12 bagder

After building with openssl I recieve OpenSSL SSL_connect: SSL_ERROR_SYSCALL error. Following are the logs. trace:43 == Info: Trying ...

trace:43 == Info: Connected to () port 443 (#0)

trace:43 == Info: ALPN: offers http/1.1

trace:43 == Info: CAfile: curl-ca-bundle.crt

trace:43 == Info: CApath: none

trace:54 => Send SSL data: trace:43 == Info: [CONN-0-0][CF-SSL] TLSv1.3 (OUT), TLS handshake, Client hello (1):

trace:54 => Send SSL data: trace:43 == Info: OpenSSL SSL_connect: SSL_ERROR_SYSCALL in connection to :443

trace:43 == Info: Closing connection 0

SendReport:474 Failed sending curl request with error:SSL connect error

Bab95 avatar Jan 16 '23 03:01 Bab95

https://github.com/curl/curl/issues/10165 is this the same issue? @bagder @icing

Bab95 avatar Jan 16 '23 10:01 Bab95

@Bab95 https://github.com/curl/curl/issues/10165 only applies to configurations where the haproxy protocol is explicitly enabled. I do not see that in your examples.

icing avatar Jan 16 '23 10:01 icing

I think it's unlikely this is a curl issue. I second @bagder's suggestion to use Wireshark to monitor the sessions. My guess is the remote is resetting the connection.

jay avatar Jan 17 '23 04:01 jay

We cannot reproduce and this is a suspected user error/problem.

bagder avatar Jan 29 '23 10:01 bagder

just an update on this. There was firewalls which had been blocking the service url's client sent hello but server never received it and connection dropped.

But in this situation is the error code correct? may be it could be made more clear?

Bab95 avatar Feb 02 '23 16:02 Bab95

Sorry no. "Failed to receive handshake" is right to the point.

edit: That error message is from the Schannel backend. The OpenSSL backend is more generic with SSL_ERROR_SYSCALL. It does not tell us the state of the handshake in the error message but you can enable verbose mode to debug the connection.

jay avatar Feb 02 '23 21:02 jay