I know there are several posts about this topic but I've tried a lot and nothing has worked.
curl_setopt($ch, CURLOPT_URL, "https://127.0.0.1:2288");
curl_setopt($ch, CURLOPT_HTTPAUTH, CURLAUTH_DIGEST);
curl_setopt($ch, CURLOPT_USERPWD, $this->username . ":" . $this->password);
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS, $pRequest);
curl_setopt($ch, CURLOPT_HTTPHEADER, array('Content-type: application/json'));
curl_setopt($ch, CURLOPT_ENCODING, 'gzip,deflate');
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt ($ch, CURLOPT_CAINFO, "/etc/ssl/certs/cacert.pem");
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, '2');
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, true);
When I execute it on Ubuntu 20.04 machine, i get this error:
Fatal error: Uncaught RuntimeException: Unable to connect to https://127.0.0.1:2288/ Error: SSL certificate problem: self signed certificate
The certificate is the current version from curl.se/docs/caextract.html
php.ini:
extension=curl
extension=php_curl.dll
curl.cainfo="/etc/ssl/certs/cacert.pem"
What else can I do without prohibiting curl ssl connections?
CodePudding user response:
If you are using self-signed certificates you either have to add it to your trusted certificates or you have to turn validation off. For the second case just switch the CURLOPT_SSL_VERIFYPEER to false.
CodePudding user response:
You are connecting securely to localhost on Ubuntu and, as your error indicates, your server is responding with a self-signed certificate. Your code specifies that curl should attempt to verify the host it's connecting to (localhost, in your case):
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, '2');
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, true);
According to the docs, that value of 2
in your code for CURLOPT_SSL_VERIFYHOST
is documented thusly:
2 to verify that a Common Name field or a Subject Alternate Name field in the SSL peer certificate matches the provided hostname. 0 to not check the names. 1 should not be used. In production environments the value of this option should be kept at 2 (default value).
If you want to strictly follow the documentation's recommendation, you'd have to map some domain onto localhost and install a cert for that domain on your server. AFAIK, you cannot get a cert for 127.0.0.1 because that special IP address always refers to localhost...sort of a long story but it makes no sense for anyone to sign such a cert.
Your other option is to set CURLOPT_SSL_VERIFYHOST
to zero:
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 0);
That tells curl not to bother validating the certificate. This should be fairly safe if your are in control of your own server and if your server hasn't been compromised somehow.
EDIT I would add that downloading the cert extract from curl.se just grabs a bundle of widely trusted signatures/certificates that happens to be the bundle used by Firefox. This cert bundle is used to check any domain that you might visit by comparing the signature on that domain's certificate to some big/important certificates that have been signed by supposedly trustworthy organizations. It will never be helpful in validating a self-signed certificate. For more information about this elaborate concept, try reading about Web of Trust.
I should also mention that you might be able to use a few commands to grab the certificate that your local machine coughs up and configure your curl code to use that certificate, HOWEVER, the CURLOPT_SSL_VERIFYHOST
setting of 2
instructs curl to check the Common Name
field of this certificate against the IP address or domain to which you are connecting. On my ubuntu workstation, the certificate's Common Name is 'Ubuntu' -- and that won't match either localhost or 127.0.0.1. For this approach to work, you'll either have to generate a new cert for your machine with a Common Name that matches the address to which you connect (localhost or 127.0.0.1) OR you'll need to set up something to name your machine 'ubuntu' on your local network.