I've checked quite a few StackOverflow posts, and still can't find a solution. I'm working with the Dropbox PHP API, but I believe that is irrelevant. What seems to be the issue is that cURL refuses to use the CAPATH or specific certificate provided by Dropbox for connecting to the API, and just gives up. After a series of debugging tests, this is what I got for output from CURLOPT_VERBOSE:
* Adding handle: conn: 0x252c110
* Adding handle: send: 0
* Adding handle: recv: 0
* Curl_addHandleToPipeline: length: 1
* - Conn 2 (0x252c110) send_pipe: 1, recv_pipe: 0
* About to connect() to api.dropbox.com port 443 (#2)
* Trying 108.160.167.19...
* Connected to api.dropbox.com (108.160.167.19) port 443 (#2)
* Initializing NSS with certpath: sql:/etc/pki/nssdb
* Unable to initialize NSS database
* Initializing NSS with certpath: none
* Unable to initialize NSS
* Closing connection 2
The dropbox API code sets CURLOPT_CAINFO and CURLOPT_CAPATH. I have checked that PHP can access the directory, and that file. I don't understand why cURL says Initializing NSS with certpath: none when I explicitly provided one... Any help would be appreciated.
I had this problem on Amazon ec2 instance (Amazon linux), restarting apache fixed it.
restarting using apachectl was not helpful
so do this using
/etc/init.d/httpd restart
Related
I have a PHP script that quickly sends a bunch of requests to the Apple API (APNs). Sometimes 10k requests are sent totally fine (just for the record, it takes ~30sec). However, when the API returns some non-200 codes, establishing new connections to this API throws the following error:
curl: (35) OpenSSL SSL_connect: SSL_ERROR_SYSCALL in connection to api.push.apple.com:443
With the debug mode enabled I get strange results:
When everything is fine:
* Found bundle for host api.push.apple.com: 0x55eba8b11660 [serially]
* Found bundle for host api.push.apple.com: 0x55eba8b11660 [serially]
* Trying 17.188.140.151...
* TCP_NODELAY set
* Hostname 'api.push.apple.com' was found in DNS cache
* Trying 17.188.140.151...
...
...
(full output is here).
After the issue happened:
* Found bundle for host api.push.apple.com: 0x561d83bb1f00 [serially]
* Server doesn't support multiplex (yet)
* Connection #0 is still name resolving, can't reuse
* Found bundle for host api.push.apple.com: 0x561d83bb1f00 [serially]
* Server doesn't support multiplex (yet)
* Connection #0 is still name resolving, can't reuse
* Connection #1 is still name resolving, can't reuse
* Trying 17.188.156.30:443...
* TCP_NODELAY set
* Hostname 'api.push.apple.com' was found in DNS cache
* Trying 17.188.156.30:443...
...
...
(full output is here).
So the IP is changed and something about multiplexing.
After it happens, sending requests to this API using the cli curl also stops working:
$ curl -v -I https://api.push.apple.com
* Trying 17.188.156.30:443...
* TCP_NODELAY set
* Connected to api.push.apple.com (17.188.156.30) port 443 (#0)
* ALPN, offering h2
* ALPN, offering http/1.1
* successfully set certificate verify locations:
* CAfile: /etc/ssl/certs/ca-certificates.crt
CApath: none
* TLSv1.3 (OUT), TLS handshake, Client hello (1):
* OpenSSL SSL_connect: SSL_ERROR_SYSCALL in connection to api.push.apple.com:443
* Closing connection 0
curl: (35) OpenSSL SSL_connect: SSL_ERROR_SYSCALL in connection to api.push.apple.com:443
(full output is here).
The error may disappear after a few minutes, may not. The code runs in a docker container (php:7.3-cli-alpine), restarting the container usually resets the issue until some future requests get non-200 codes. Performing restarts isn't an option.
Presumably, curl somehow stores opened connections and tries to re-use them, but for some reason something is broken inside the curl and it doesn't allow curl to correctly re-use the connections.
While curl stops working, openssl works fine:
$ openssl s_client -connect api.push.apple.com:443
CONNECTED(00000003)
write:errno=0
---
no peer certificate available
---
No client certificate CA names sent
---
SSL handshake has read 0 bytes and written 320 bytes
Verification: OK
---
New, (NONE), Cipher is (NONE)
Secure Renegotiation IS NOT supported
No ALPN negotiated
Early data was not sent
Verify return code: 0 (ok)
---
Software versions:
$ curl --version
curl 7.67.0 (x86_64-alpine-linux-musl) libcurl/7.67.0 OpenSSL/1.1.1d zlib/1.2.11 nghttp2/1.40.0
Release-Date: 2019-11-06
Protocols: dict file ftp ftps gopher http https imap imaps pop3 pop3s rtsp smb smbs smtp smtps telnet tftp
Features: AsynchDNS HTTP2 HTTPS-proxy IPv6 Largefile libz NTLM NTLM_WB SSL TLS-SRP UnixSockets
$ openssl version
OpenSSL 1.1.1d 10 Sep 2019
Looks like a curl issue, but how to fix it?
Any help will be appreciated
Just in case it's helpful to you or someone else, the "one error breaks things for a long time" nature of this (and the re-use of Curl connections) reminded me a bit of the Curl bug:
https://github.com/curl/curl/issues/3966
Not sure whether the fix for that is in your Curl version though - from the date it might well be.
I have a valid wildcard CA Certificate for my sites:
myapp.example.com
qamyapp.example.com
I need consume a rest service using php 5.6 curl.
When try to execute php curl calling qamyapp.example.com, show the next error:
* Trying xx.xxx.xxx.xx...
* Connected to qamyapp.example.com (xx.xxx.xxx.xx) port 443 (#0)
* ALPN, offering http/1.1
* Cipher selection:
ALL:!EXPORT:!EXPORT40:!EXPORT56:!aNULL:!LOW:!RC4:#STRENGTH
* successfully set certificate verify locations:
* CAfile: /etc/ssl/certs/ca-certificates.crt
CApath: /etc/ssl/certs
* SSL certificate problem: unable to get local issuer certificate
* Closing connection 0
But when curl call myapp.example.com work fine.
How a can update the ca-certificates.crt file.
I have found the solution. In qamyapp.example.com server, is necesary concat to certificate.crt file, the content of bundle.crt file, to NGinx.
I am trying to curl the below location;
Curl::to('https://serp.webshed.co/')->enableDebug('/uploads/log/logFile.txt')->get();
When I load the URL directly in my browser it works fine, when I try curling it from my local dev it works fine. When I try and curl it from my actual system online it times out, the error I get is;
* Trying 46.101.38.201...
* Connected to serp.webshed.co (46.101.38.201) port 443 (#0)
* ALPN, offering http/1.1
* Cipher selection: ALL:!EXPORT:!EXPORT40:!EXPORT56:!aNULL:!LOW:!RC4:#STRENGTH
* successfully set certificate verify locations:
* CAfile: /etc/ssl/certs/ca-certificates.crt
CApath: /etc/ssl/certs
* Operation timed out after 0 milliseconds with 0 out of 0 bytes received
* Closing connection 0
Does anyone know what the issue could be?
I have been fighting this issue for a while and cannot seem to get it right. To preface, this is my first experience having to work with SSL. The server I am working on is using PHP 5.6.30 and Laravel 5.1.46, and I'm trying to use GuzzleHttp 6.2.3 to post JSON to a third party. Up until now, I've been disabling ssl verification by specifying 'verify' => false within the client, and have been able to get successful responses. The third party provided me with a certificate to use, and gave me both .pem and .cer formats. They stated the certificate is not password protected since it is the public key. According to GuzzleHttp's documentation, my request should look like this:
$response = $client->request('POST', $endpoint, [
'cert' => /path/to/new/cert.pem,
'headers' => [
'Content-type' => 'application/json'
],
'body' => $request_body,
'connect_timeout' => 5,
]);
I cannot connect using this method, and unfortunately I can't get the low level error detail due to the design of the server I'm working on (it's a large pre-existing codebase I'm having to update, it will hopefully eventually be completely rewritten).
In order to get more detail, I decided to send the request using cURL. First I sent the request without the certificate:
// REQUEST
curl -v -H "Content-Type: application/json" -X POST -d '{"some_json_request": "value"}' https://sometargeturl.com:8443/dosomething
// OUTPUT
* Trying 204.71.178.10...
* TCP_NODELAY set
* Connected to sometargeturl.com (204.71.178.10) port 8443 (#0)
* Initializing NSS with certpath: sql:/etc/pki/nssdb
* CAfile: /etc/pki/tls/certs/ca-bundle.crt
CApath: none
* Server certificate:
* subject: CN=sometargeturl.com,OU=OU,O="Some Company Name, Inc",L=Pleasanton,ST=California,C=US
* start date: May 13 00:00:00 2016 GMT
* expire date: May 14 23:59:59 2018 GMT
* common name: sometargeturl.com
* issuer: CN=Symantec Class 3 Secure Server CA - G4,OU=Symantec Trust Network,O=Symantec Corporation,C=US
* NSS error -8179 (SEC_ERROR_UNKNOWN_ISSUER)
* Peer's Certificate issuer is not recognized.
* Curl_http_done: called premature == 1
* Closing connection 0
curl: (60) Peer's Certificate issuer is not recognized.
Then, with the certificate:
// REQUEST
curl -v --cert /path/to/the/cert.pem -H "Content-Type: application/json" -X POST -d '{"some_json_request": "value"}' https://sometargeturl.com:8443/dosomething
// OUTPUT
* Trying 204.71.178.10...
* TCP_NODELAY set
* Connected to sometargeturl.com (204.71.178.10) port 8443 (#0)
* Initializing NSS with certpath: sql:/etc/pki/nssdb
* CAfile: /etc/pki/tls/certs/ca-bundle.crt
CApath: none
* unable to load client key: -8178 (SEC_ERROR_BAD_KEY)
* NSS error -8178 (SEC_ERROR_BAD_KEY)
* Peer's public key is invalid.
* Curl_http_done: called premature == 0
* Closing connection 0
curl: (58) unable to load client key: -8178 (SEC_ERROR_BAD_KEY)
I've done a ton of research and have not been able to find a solution. I'm really just unsure of next steps at this point. I ultimately will need to use GuzzleHttp to send the request, but I don't what I'm missing. I have read about adding the new cert to an existing CA bundle, however I'm not sure if that is the right solution/how I would do that if so. Any help would be appreciated, thanks!
what are you exactly trying to do ?
Verifying remote server certificate with 'verify' => true
Authenticating yourself by presenting your certificate to remote ?
That being said, your curl is compiled against NSS and not openssl.
The NSS error -8178 (SEC_ERROR_BAD_KEY) comes from NSS that does not support providing the private key as a file
I'm trying to create a php script that will put a file on a remote server.
The following line will work from the CLI:
curl -u username:pass -T myfile.jpg sftp://my.domain.com/dir/
However, if I take this into PHP and try to run it through 'system' like:
<? system('curl -u username:pass -T myfile.jpg sftp://my.domain.com/dir/'); ?>
I get an error:
curl: (7) Failed to connect to xxx.xxx.xx.xx: Permission denied
Also, to complicate things, this is going from a RHEL to a Windows Server. Anyone have a suggestion or a fix?
Below is the result from the PHP cURL library.
* About to connect() to my.domain.com port 22 (#0)
* Trying xxx.xxx.xx.xx... * connected
* Connected to my.domain.com (xxx.xxx.xx.xx) port 22 (#0)
* SSH authentication methods available: publickey,password
* Initialized password authentication
* Authentication complete
* Upload failed: Permission denied (3/-31)
* Connection #0 to host my.domain.com left intact
* Closing connection #0
PHP has it's own cURL library that you should probably use. php cURL
Your problem is that system() doesn't allow curl to ask you for a password.
Consider other authentication methods.