I'm using cURL to send some data using CURLOPT_POST. Same code was working fine before but after moving to a new server cURL is not working anymore via https. The guys from the other site (domain.com) sent me the log files and nothing was received by them. Then I tried to get an error with curl_error() and I was faced with a SSL problem but don't know how to fix it.
Code:
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL,'https://track.domain.com/api.php');
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_1);
curl_setopt($ch, CURLOPT_POSTFIELDS, $param);
curl_exec($ch);
$error = curl_error($ch);
curl_close($ch);
The error is:
SSL certificate problem, verify that the CA cert is OK. Details:
error:14090086:SSL routines:SSL3_GET_SERVER_CERTIFICATE:certificate verify failed
I searched for this on Google but couldn't understand what the problem is.
Do I need SSL certificate for our domain? I'm not sure if there was SSL in the old server. Is you can see from the code, I don't need return. So, should I have SSL, too, in this case?
Do I need domain.com's certificate?
Do I need contacting the hosting company for recompiling cURL with SSL support?
Any ideas?
Note: I don't want a workaround by setting CURLOPT_SSL_VERIFYPEER and CURLOPT_SSL_VERIFYHOST to false.
curl_version():
Array
(
[version_number] => 464896
[age] => 3
[features] => 34333
[ssl_version_number] => 0
[version] => 7.24.0
[host] => i686-pc-linux-gnu
[ssl_version] => OpenSSL/0.9.8b
[libz_version] => 1.2.3
[protocols] => Array
(
[0] => dict
[1] => file
[2] => ftp
[3] => ftps
[4] => gopher
[5] => http
[6] => https
[7] => imap
[8] => imaps
[9] => pop3
[10] => pop3s
[11] => rtsp
[12] => smtp
[13] => smtps
[14] => telnet
[15] => tftp
)
)
downloaded Mozilla's bundle file, named it mozilla.pem
curl_setopt($ch,CURLOPT_SSL_VERIFYPEER,true);
curl_setopt($ch,CURLOPT_CAINFO,'mozilla.pem');
The issue is your CA (Certificate Authority) list doesn't have the issuer of the remote site certificate. This method will not fix if your trying to connect to a server who has a self singed certificate.
Related
I'm running mariadb 10.2 in ubuntu 16.04. The mariadb will perform external authentication using freeipa (ldap+kerberos). I can connect mariadb server with mariadb client, using freeipa credential. Everything work as usual. The /etc/pam.d/mariadb as below:
auth required pam_unix.so
account required pam_unix.so
auth required pam_user_map.so
However, when I'm connect using php7 mysqli (command line or web), it return:
(
[affected_rows] =>
[client_info] =>
[client_version] => 50012
[connect_errno] => 2054
[connect_error] => The server requested authentication method unknown to the client
[errno] =>
[error] =>
[error_list] =>
[field_count] =>
[host_info] =>
[info] =>
[insert_id] =>
[server_info] =>
[server_version] =>
[stat] =>
[sqlstate] =>
[protocol_version] =>
[thread_id] =>
[warning_count] =>
)
From lot of research I'm notice that php mysql driver doesn't support PAM authentication well. There is online resources http://www.sheeri.org/ldap-with-auth_pam-and-php/ tell me that there is a way to overcome it, but it too rough. Can somebody tell me how to rebuild for ubuntu with libmariadbclient? I can't find /usr/bin/mysql_config anyway.
Thanks
I'd greatly simplified the solution, I'd create basic bash script for ubuntu. It will use default apache2/php/percona server/client by only override mysqli.so, pdo_mysql.so.
https://gist.github.com/kstan79/367ef928e44523904fb36b67a92decdd
My curl version:
Array
(
[version_number] => 470785
[age] => 3
[features] => 524809
[ssl_version_number] => 0
[version] => 7.47.1
[host] => x86_64-pc-linux-gnu
[ssl_version] =>
[libz_version] => 1.2.8
[protocols] => Array
(
[0] => dict
[1] => file
[2] => ftp
[3] => gopher
[4] => http
[5] => imap
[6] => pop3
[7] => rtsp
[8] => smtp
[9] => telnet
[10] => tftp
)
)
how can I enable this protocol smb ?
curl_setopt($ch, CURLOPT_PROTOCOLS, CURLPROTO_SMB); //not working
libcurl supports SMB since 7.40.0.
Make sure you install a libcurl version where the protocol wasn't disabled. The supported protocols list you show indicates you have a limited set. An ordinary libcurl installed from a popular Linux distro will support many more protocols, including the TLS based ones that are missing in your protocol list (HTTPS, FTPS, POP3S, IMAPS etc)
Also make sure that you build your libcurl (if you build it yourself) with a TLS library, as the SMB code needs NTLM support and the NTLM code only works using some crypto functions from one of the TLS libraries libcurl supports.
When that is done, you don't need to use CURLOPT_PROTOCOLS and CURLPROTO_SMB at all, as then libcurl will support it out of the box by default.
Fixed in 7.40.0 - January 8 2015
Changes:
http_digest: Added support for Windows SSPI based authentication
version info: Added Kerberos V5 to the supported features
Makefile: Added VC targets for WinIDN
config-win32: Introduce build targets for VS2012+
SSL: Add PEM format support for public key pinning
smtp: Added support for the conversion of Unix newlines during mail send
smb: Added initial support for the SMB/CIFS protocol
Added support for HTTP over unix domain sockets, via CURLOPT_UNIX_SOCKET_PATH and --unix-socket
sasl: Added support for GSS-API based Kerberos V5 authentication
File read not working or i dont know how to use
ok i i installed 7.43 libcurl and
Array
(
[version_number] => 469760
[age] => 3
[features] => 968605
[ssl_version_number] => 0
[version] => 7.43.0
[host] => x86_64-pc-linux-gnu
[ssl_version] => OpenSSL/1.0.2d
[libz_version] => 1.2.8
[protocols] => Array
(
[0] => dict
[1] => file
[2] => ftp
[3] => ftps
[4] => gopher
[5] => http
[6] => https
[7] => imap
[8] => imaps
[9] => ldap
[10] => ldaps
[11] => pop3
[12] => pop3s
[13] => rtmp
[14] => rtsp
[15] => smb
[16] => smbs
[17] => smtp
[18] => smtps
[19] => telnet
[20] => tftp
)
)
i can get file content from smb but how to get catalog list files ?
In my PHP app I use PHP's CURL and openssl, to connect and talk using SOAP.
Until now, remote server supported SSL and TLS but because of "poodle" bug, admin decided to disable SSL and use TLS only.
SSL is supported until the end of January.
I changed my code by adding:
curl_setopt($objCurl, CURLOPT_SSLVERSION, CURL_SSLVERSION_TLSv1_2);
That in theory should force curl to use TLSv1.2.
But that's theory - I need to verify that it actually uses TLS - is there any method for that?
There is a method called curl_getinfo(), but info it returns is not useful for me:
[url] => https://www.example.com/soap/MessagingPort
[content_type] => text/xml;charset=utf-8
[http_code] => 200
[header_size] => 293
[request_size] => 882
[filetime] => -1
[ssl_verify_result] => 0
[redirect_count] => 0
[total_time] => 0.164487
[namelookup_time] => 3.4E-5
[connect_time] => 3.4E-5
[pretransfer_time] => 0.000122
[size_upload] => 604
[size_download] => 178
[speed_download] => 1082
[speed_upload] => 3672
[download_content_length] => 178
[upload_content_length] => 604
[starttransfer_time] => 0.164477
[redirect_time] => 0
Short Answer
Make a request with curl to https://www.howsmyssl.com/
<?php
$ch = curl_init('https://www.howsmyssl.com/a/check');
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
$data = curl_exec($ch);
curl_close($ch);
$json = json_decode($data);
echo $json->tls_version;
that should output what TLS version was used to connect.
Digging Deeper
Curl relies on the underlying OpenSSL (or NSS) library to do the negotiation of the secure connection. So I believe the right question to ask here is what is the OpenSSL library capable of. If it can handle a TLS connection, then curl can handle a TLS connection.
So how to figure out what the openssl (or NSS) library is capable of?
<?php
$curl_info = curl_version();
echo $curl_info['ssl_version'];
which is going to dump out something like
OpenSSL/1.0.1k
Then you can go and have a look at the release notes for that version and see if it includes TLS support.
OpenSSL Release notes - https://www.openssl.org/news/changelog.html
NSS Release notes - https://developer.mozilla.org/en-US/docs/Mozilla/Projects/NSS/NSS_Releases
Spoiler Alert
openssl includes support for TLS v1.1 and TLS v1.2 in OpenSSL 1.0.1
[14 Mar 2012]
NSS included support for TLS v1.1 in 3.14
NSS included
support for TLS v1.2 in 3.15
Use https://tlstest.paypal.com:
For example:
$ curl https://tlstest.paypal.com/
ERROR! Connection is using TLS version lesser than 1.2. Please use TLS1.2
$ ./src/curl https://tlstest.paypal.com/
PayPal_Connection_OK
If you want to test which protocol is being used for a specific url (like a payment api endpoint) you can log curl's verbose output and see it there. Here's a quick example:
$url = 'https://example.com/';
$ch = curl_init($url);
$out = fopen('php://temp', 'w+');
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_VERBOSE, true);
curl_setopt($ch, CURLOPT_STDERR, $out);
curl_exec($ch);
curl_close($ch);
rewind($out);
$debug = stream_get_contents($out);
if (preg_match('/SSL connection.*/', $debug, $match)) {
echo '<pre>' . $url . PHP_EOL . $match[0];
}
For me that gives output like:
https://example.com/
SSL connection using TLSv1.3 / TLS_AES_256_GCM_SHA384
I'm using curl library (with NSS) in PHP to connect to my other server. Everything was fine until last week, when the destination server stoped supporting SSLv3 due to poodle vulnerability (CloudFlare by the way). Now, I'm trying to make connection using TLS, but I'm still getting "SSL connect error".
There is sample code, I'm using:
$ch = curl_init();
curl_setopt_array( $ch, array(
CURLOPT_URL => 'https://www.lumiart.cz',
CURLOPT_RETURNTRANSFER => true,
CURLOPT_SSLVERSION => 1,
CURLOPT_SSL_VERIFYPEER => false,
CURLOPT_VERBOSE => true
) );
$output = curl_exec( $ch );
echo $output;
print_r( curl_getinfo( $ch ) );
echo 'error:' . curl_error( $ch );
curl_close($ch);
From my understanding, setting CURLOPT_SSLVERSION to 1 should force connection via TLS.
Note: I have CURLOPT_SSL_VERIFYPEER => false just for debuging and I'm not meaning to leave it there, once I figure this problem out.
This is output:
Array
(
[url] => https://www.lumiart.cz
[content_type] =>
[http_code] => 0
[header_size] => 0
[request_size] => 0
[filetime] => -1
[ssl_verify_result] => 0
[redirect_count] => 0
[total_time] => 0
[namelookup_time] => 2.3E-5
[connect_time] => 0.005777
[pretransfer_time] => 0
[size_upload] => 0
[size_download] => 0
[speed_download] => 0
[speed_upload] => 0
[download_content_length] => -1
[upload_content_length] => -1
[starttransfer_time] => 0
[redirect_time] => 0
[certinfo] => Array
(
)
[primary_ip] => 2400:cb00:2048:1::681c:86f
[redirect_url] =>
)
error:SSL connect error
I have all of this at shared hosting provider, so I can't change any php.ini configuration or update any components. All I have is phpinfo(). I've checked for TLS support on these components version and it should be fine. Here is excerpt of phpinfo:
PHP Version 5.4.32
System Linux wl42-f262 2.6.32-431.5.1.el6.x86_64 #1 SMP Wed Feb 12 00:41:43 UTC 2014 x86_64
curl:
cURL support enabled
cURL Information 7.19.7
Age 3
Features
AsynchDNS No
Debug No
GSS-Negotiate Yes
IDN Yes
IPv6 Yes
Largefile Yes
NTLM Yes
SPNEGO No
SSL Yes
SSPI No
krb4 No
libz Yes
CharConv No
Protocols tftp, ftp, telnet, dict, ldap, ldaps, http, file, https, ftps, scp, sftp
Host x86_64-redhat-linux-gnu
SSL Version NSS/3.15.3
ZLib Version 1.2.3
libSSH Version libssh2/1.4.2
I think, that problem is usage of SSLv3 instead of TLS, but I'm not 100% sure. All I'm getting is "SSL connect error" and I don't know, how to find out, which SSL version was used to connect.
Is there a way, how to check, which SSL version is used for connection? Or am I missing something?
That's an interesting problem.
If you query SSLLabs for this site you will see, that it only supports various ECDHE-ECDSA-* ciphers and no other ciphers. But, in the version history of curl you will find a bug with ECC ciphers and the NSS library (which you use) which is only fixed in curl version 7.36 "nss: allow to use ECC ciphers if NSS implements them".
Since you are using curl 7.19.7 your curl is too old to use the necessary ciphers together with the NSS library. This means you need to upgrade your curl library.
I have Curl 7.21.7 and PHP 5.4.34, and this seemed to do the trick for me:
curl_setopt($curl_request, CURLOPT_SSLVERSION, CURL_SSLVERSION_TLSv1);
More info here, although it doesn't say when CURL_SSLVERSION_TLSv1 was introduced.
The answer for me was to use an integer value instead of a string.. i.e.:
Change:
curl_setopt($ch, CURLOPT_SSLVERSION_TLSv1_2);
To:
curl_setopt($ch, CURLOPT_SSLVERSION, 6);
Or for tlsv1_1:
curl_setopt($ch, CURLOPT_SSLVERSION, 5);
Here's the full list:
CURL_SSLVERSION_DEFAULT (0)
CURL_SSLVERSION_TLSv1 (1)
CURL_SSLVERSION_SSLv2 (2)
CURL_SSLVERSION_SSLv3 (3)
CURL_SSLVERSION_TLSv1_0 (4)
CURL_SSLVERSION_TLSv1_1 (5)
CURL_SSLVERSION_TLSv1_2 (6)
I'm running the following by the way:
curl-7.19.7-46.el6.x86_64
nss-3.21.0-0.3.el6_7.x86_64
Duplicate answer SSL error can not change to TLS proposed :
Try adding CURLOPT_SSL_CIPHER_LIST => 'TLSv1' to your PPHttpConfig.php.
( and discussed here Update PHP cURL request from SSLv3 to TLS..? too ).
As usefully commented, this apply to openssl curl library, not to nss.
I'm experiencing strange timeouts using cURL with PHP when trying to access Amazon Cloudfront. This seems to affect all invalidation requests, creating distributions etc. cURL either reports receiving 0 bytes, or very few bytes, and then time-out:
Operation timed out after 120000 milliseconds with 88 out of 619 bytes received.
Extending the timeout settings does not seem to make a difference.
Putting a trace using CURLOPT_VERBOSE produces this output:
* About to connect() to cloudfront.amazonaws.com port 443 (#0)
* Trying 72.21.215.67... * connected
* Connected to cloudfront.amazonaws.com (72.21.215.67) port 443 (#0)
* skipping SSL peer certificate verification
* SSL connection using SSL_RSA_WITH_RC4_128_MD5
* Server certificate:
* subject: CN=cloudfront.amazonaws.com,O=Amazon.com Inc.,L=Seattle,ST=Washington,C=US
* start date: Jul 30 00:00:00 2010 GMT
* expire date: Jul 29 23:59:59 2013 GMT
* common name: cloudfront.amazonaws.com
* issuer: CN=VeriSign Class 3 Secure Server CA - G2,OU=Terms of use at https://www.verisign.com/rpa (c)09,OU=VeriSign Trust Network,O="VeriSign, Inc.",C=US
> POST /2010-11-01/distribution/E1CIM4A92QFD98/invalidation HTTP/1.1
User-Agent: S3/php
Accept: */*
Host: cloudfront.amazonaws.com
Date: Wed, 07 Mar 2012 14:31:58 GMT
Content-Type: application/xml
Authorization: AWS ************************
Content-Length: 200
< HTTP/1.1 201 Created
< x-amzn-RequestId: 4c2d0d3f-6862-11e1-ac27-5531ac8c967f
< Location: https://cloudfront.amazonaws.com/2010-11-01/distribution/E1CIM4A92QFD98/invalidation/I35KLNROKA40FU
* Operation timed out after 120000 milliseconds with 0 bytes received
* Closing connection #0
This seems similar to this question. However, it looks like in my case curl does in fact get a response, but somehow ignores it and times-out? From what I see, the response is received (201 Created...), and there are no SSL errors. So why does curl time-out??
cURL version info
[version_number] => 463623
[age] => 3
[features] => 1597
[ssl_version_number] => 0
[version] => 7.19.7
[host] => x86_64-unknown-linux-gnu
[ssl_version] => NSS/3.12.7.0
[libz_version] => 1.2.3
[protocols] => Array ( [0] => tftp [1] => ftp [2] => telnet [3] => dict [4] => ldap [5] => ldaps [6] => http [7] => file [8] => https [9] => ftps [10] => scp [11] => sftp )
Still not entirely sure why this version of curl behaves this way (it looks like a bug), but the solution was to compile a different version of curl and php (more or less following these instructions)
It would help to see how you're setting up your curl session. Are you doing things like:
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, true);
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 2);
curl_setopt($ch, CURLOPT_CAINFO, getcwd() . "/CAcerts/BuiltinObjectToken-EquifaxSecureCA.crt");
The quick test to see if you're having an SSL verify problem is:
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);