curl
curl copied to clipboard
SSL Connect Error
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
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.
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.
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?
I suppose this only happens against one particular host or does it reproduce against other and public hosts you can tell us about?
This is happening on about more than at least 100 machines.
My money is still on a server problem or a networking gateway/firewall/proxy issue.
@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
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: /
@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?
You can:
- try curl built with another TLS backend to see if it works/gives another/better error message
- try against other servers and see if the problem continues or how it changes and try to figure out why
- try running your code from other machines/networks to see if that changes anything
- wireshark the TLS handshake and check what happens in detail
- work on a way for others to reproduce the problem to be able to help
@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
I would consider trying it out with a build using OpenSSL as that's the most commonly used TLS backend in curl.
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
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
trace:43 == Info: Closing connection 0
SendReport:474 Failed sending curl request with error:SSL connect error
https://github.com/curl/curl/issues/10165 is this the same issue? @bagder @icing
@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.
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.
We cannot reproduce and this is a suspected user error/problem.
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?
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.