Access DH APIs from CURL (PHP)


#1

Hi All,

To update the IP addresses of various domains I use the DH APIs.

I have a PHP script that does that, and it has been working for at least a couple of years.
It uses CURL to contact https://api.dreamhost.com and retrieve the list of all domains and IPs I have setup.

If any IP changes, it updates DH.

Unfortunately sometimes last week it stopped working (I believe after an update to some ssl libraries on my side).

Here is the important part of the script (I removed some bits to keep it as short as possible):

[php]

<?php //[..] //setup variables for script //[..] define('API_KEY', 'XXXXXXXXXXXXXXXX'); define('FORMAT', 'json'); define('PUBLIC_IP_SERVICE', 'http://myip.thewebisfree.com'); define('DREAMHOST_API', 'https://api.dreamhost.com'); $publicIp = file_get_contents(PUBLIC_IP_SERVICE); //[..] //check that "PUBLIC_IP_SERVICE" is up and/or $publicIp is a "valid IP" //[..] // Use your API url $apiCall = DREAMHOST_API.'/?key='.API_KEY.'&cmd=dns-list_records&format='.FORMAT; $command = 'curl'; $ch = curl_init(); curl_setopt($ch, CURLOPT_URL, $apiCall); curl_setopt($ch, CURLOPT_HEADER, 0); curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, 0); curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); curl_setopt($ch, CURLOPT_SSLVERSION, 3); //needed to force the SSL version after a php upgrade $data = curl_exec($ch); echo curl_error($ch); //decode JSON $data = json_decode($data); //[..] //with $data retrieved check that the IP hasn't changed, if it has update dreamhost... //[..] ?>

[/php]

The errors I get are:

  1. Unknown SSL protocol error in connection to api.dreamhost.com:443 (printed by “echo curl_error($ch);”)
  2. PHP Notice: Trying to get property of non-object in scriptName.php on line 49 (which basically is “$data = json_decode($data);”)

If I enter “https://api.dreamhost.com/?key=XXXXXXXXXXXXXXXX&cmd=dns-list_records&format=json” in the browser I get the expected JSON list of domains;
How can I fix my curl commands to achieve the same result?

Any help/tip would be greatly appreciated.

Cheers,
Andrea


#2

[php]curl_setopt($ch, CURLOPT_SSLVERSION, 3); //needed to force the SSL version after a php upgrade[/php]

Remove this line. For security reasons, our public web services (including the API) no longer support SSLv3.


#3

I have the same problem with the API using a PHP curl script. I tried removing that same line that forces SSLv3 and the script still fails. Has anyone been able to get this working? This is quite frustrating.


#4

Hi,

I agree with titleistfour.
I tried removing that line but I’ve got the same error: “Unknown SSL protocol error in connection to api.dreamhost.com:443”.

By the way, I remember adding that line much later having finished that script (something like 6/12 months ago).
Judging from my comment on that line, at the time I thought the script started to fail after a php upgrade and that line fixed it.
Unfortunately now it is failing again…

Any other ideas?

Thanks,
Andrea


#5

Anyone have any suggestions?


#6

cURL would use OpenSSL, and there appears to be an update for security fixes: OpenSSL Security Advisory [15 Oct 2014]

So I’m thinking either the curl extension needs to be recompiled against an updated openssl library, or one somehow needs to configure the curl extension to use TLS instead of SSL v3. And possibly have it output errors/handshake information to see if there is more detail about the protocol error. I haven’t tried to troubleshoot this myself.


#7

SSL v3 has been disabled at dreamhost.


#8

Right, I know SSLv3 is disabled. The issue is what DOES work instead. I can’t get my scripts to work with any version of SSL or TLS at the moment.


#9

Did you try CURL_SSLVERSION_DEFAULT ?


#10

I changed the line
curl_setopt($ch, CURLOPT_SSLVERSION, 3);
with
curl_setopt($ch, CURLOPT_SSLVERSION, 0);
which is what is needed to use “CURL_SSLVERSION_DEFAULT” as explained at http://php.net/manual/en/function.curl-setopt.php but still no luck.

The error is always the same one: “Unknown SSL protocol error in connection to api.dreamhost.com:443

PHP.net says:
“CURLOPT_SSLVERSION: One of 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) or CURL_SSLVERSION_TLSv1_2 (6).
Note: Your best bet is to not set this and let it use the default. Setting it to 2 or 3 is very dangerous given the known vulnerabilities in SSLv2 and SSLv3.”

In the end I tried them all and the only one that worked was “CURL_SSLVERSION_TLSv1”.
This means I replaced the above line with:
curl_setopt($ch, CURLOPT_SSLVERSION, 1);

Yuhuu! Thanks guys! :slight_smile:

Is “CURL_SSLVERSION_TLSv1” safe?

Cheers,
Andrea


#11

Congrats! I think you applied brute force on this until you were able to get it working. :slight_smile:


#12

I know… I hacked it! :stuck_out_tongue:


#13

This is good news. Would you mind posting all the CURL options you are using? I tried all versions of SSL and TLS and my scripts still don’t work when connecting to api.dreamhost.com.

Maybe it’s the PHP version I’m using. What version of PHP are you using on what OS?

Thanks,
Jay


#14

In the end I have not changed anything in my script apart from that line.

As stated in my first post the php/curl code looks like this (here is the fixed version):

[php]
$ch = curl_init();

curl_setopt($ch, CURLOPT_URL, $apiCall);
curl_setopt($ch, CURLOPT_HEADER, 0);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, 0);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_SSLVERSION, 1);

$data = curl_exec($ch);
//echo curl_error($ch);

//decode JSON
$data = json_decode($data);
[/php]

Hope it helps.
Andrea


#15

oh sorry titleistfour I had not read your second question.

The script is running on a Proxmox 3.2 server.
$php -v
PHP 5.4.4-14+deb7u14 (cli) (built: Aug 21 2014 08:36:44)
Copyright © 1997-2012 The PHP Group
Zend Engine v2.4.0, Copyright © 1998-2012 Zend Technologies

Hope this helps.
Andrea


#16

Thanks. I’m on a Debian 7 server too, same php version. Still have a problem. Must be somewhere else, an update I installed during the Poodle/SSLv3 patching. Oh well…


#17

I had the same problem last week. I tried to use andrea’s code but still nothing. I still received:
Unknown SSL protocol error in connection to api.dreamhost.com:443

Eventually I found the following example on php site: http://php.net/manual/ro/function.curl-setopt.php#114958

I’ve appended to my code:

$arrayCiphers = array(
‘DHE-RSA-AES256-SHA’,
‘DHE-DSS-AES256-SHA’,
‘AES256-SHA:KRB5-DES-CBC3-MD5’,
‘KRB5-DES-CBC3-SHA’,
‘EDH-RSA-DES-CBC3-SHA’,
‘EDH-DSS-DES-CBC3-SHA’,
‘DES-CBC3-SHA:DES-CBC3-MD5’,
‘DHE-RSA-AES128-SHA’,
‘DHE-DSS-AES128-SHA’,
‘AES128-SHA:RC2-CBC-MD5’,
‘KRB5-RC4-MD5:KRB5-RC4-SHA’,
‘RC4-SHA:RC4-MD5:RC4-MD5’,
‘KRB5-DES-CBC-MD5’,
‘KRB5-DES-CBC-SHA’,
‘EDH-RSA-DES-CBC-SHA’,
‘EDH-DSS-DES-CBC-SHA:DES-CBC-SHA’,
‘DES-CBC-MD5:EXP-KRB5-RC2-CBC-MD5’,
‘EXP-KRB5-DES-CBC-MD5’,
‘EXP-KRB5-RC2-CBC-SHA’,
‘EXP-KRB5-DES-CBC-SHA’,
‘EXP-EDH-RSA-DES-CBC-SHA’,
‘EXP-EDH-DSS-DES-CBC-SHA’,
‘EXP-DES-CBC-SHA’,
‘EXP-RC2-CBC-MD5’,
‘EXP-RC2-CBC-MD5’,
‘EXP-KRB5-RC4-MD5’,
‘EXP-KRB5-RC4-SHA’,
‘EXP-RC4-MD5:EXP-RC4-MD5’
);

curl_setopt($ch, CURLOPT_SSL_CIPHER_LIST, implode(’:’, $arrayCiphers));

… and now everything is working.


#18

Wow pictoru you rock! That fixed my issue! Guess api.dreamhost.com was limiting the cipher list and we must have been trying an invalid cipher by default. Thank you!