[PHP]CurlでのSSL接続をOpenSSL方式に変更する

curlでsslを接続する際に、opensslを利用した接続になっていなかったために接続出来ない事例があったのだが、curlを入れ替えてopensslを利用するようにしたら接続出来たのでそのメモ。

前提

接続をしている環境は以下とする。

  • CnetOS 5.6
  • PHP 5.3

この環境で、SalesforceへRestAPIを利用して接続をする。
接続する際の認証は以下のクラスを利用している。

自作の /sample/loginのエンドポイントへ接続するものとする。
接続に利用しているPHP。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
<?php
require_once('oauth.php');

define('CLIENT_ID', 'xxx');
define('CLIENT_SECRET', 'xxx');
define('CALLBACK_URL', 'http://localhost/');
define('LOGIN_URL', 'https://test.salesforce.com');
define('USERNAME', 'xxx');
define('PASSWORD', 'xxx');

$oauth = new oauth(CLIENT_ID, CLIENT_SECRET, CALLBACK_URL, LOGIN_URL);
$oauth->auth_with_password(USERNAME, PASSWORD, 120);
$url = "$oauth->instance_url/services/apexrest/sample/login";
$curl = curl_init($url);
$POST_DATA = array(
    'email' => 'sample',
    'passwd' => 'password'
);

curl_setopt($curl, CURLOPT_POST, TRUE);
curl_setopt($curl, CURLOPT_POSTFIELDS, http_build_query($POST_DATA));
curl_setopt($curl, CURLOPT_HEADER, false);
curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
curl_setopt($curl, CURLOPT_HTTPHEADER, array('Content-type: application/x-www-form-urlencoded;charset=UTF-8', "Authorization: OAuth " . $oauth->access_token));
$output= curl_exec($curl);
curl_close($curl);
$response = json_decode($output, true);

echo $output;

この辺詳しくは以下をどうぞ。
[Salesforce]apex Rest APIでPOSTでデータを送信する

失敗する

このまま送信をすると、以下のようなエラーが出て失敗する。
ちなみに、ログイン履歴には残っている。

1
2
3
4
5
6
[
  {
      message: "この組織では TLS 1.0 が無効になりました。HTTPS を使用して Salesforce に接続するには、TLS 1.1 以降を使用してください。",
      errorCode: "UNSUPPORTED_CLIENT"
  }
]

TLS

ssl通信をする時の暗号化規格で、TLS1.0は暗号化のレベルが低い、とかで1.1以上が推奨されているよう。
SSL/TLS 1.0 はいつまでに無効化しなければならないか? | NTTデータ先端技術株式会社
それに伴って、Salesforceでは、TLS1.0での接続を無効に切り替えていっている。
変更内容など詳しくは公式で。

組織の設定から明示的に有効にする事も可能だが、強制的に切り替えが行われるタイミングは以下。

  • Sandbox 組織 – 2016 年 6 月 25 日、午前 9:30 (太平洋夏時間) (16:30 UTC)
  • 本番組織 – 2017 年 3 月 4 日、午前 9:30 (太平洋標準時) (17:30 UTC)

今回は、Sandboxでの設定が適用されたために接続が出来なくなったよう。

ちなみにTLSについて調べていて、現状、SSLと呼んでいるものは全てTLSによる接続になっているらしい。

SSLはバージョン1.0と2.0は既に脆弱性で消えていたが、2014(平成26)年10月14日、GoogleのセキュリティチームによりSSL 3.0の深刻な脆弱性「POODLE」が発見されたことでSSLは全バージョンに脆弱性が発覚、これをもってSSLは現役を退いた。
http://www.wdic.org/w/WDIC/TLS

原因

上記環境で原因を探ってみると、curlでエンドポイントへ投げる際にNSSという方式が使われている事が原因となっている事がわかった。

NSS FAQ | MDN

NSSのバージョンは3.14だが、このバージョンでは一応TLS1.1には対応しているとリリースノートには書かれていたが…。詳細は不明。
NSS 3.14 release notes – Mozilla | MDN

対処

というわけで、これをNSSではなく、OpenSSL方式で接続するように変更する。
といっても、設定変更で済むわけではなく、curlのインストールし直し、となる。

作業内容は以下のサイトをそのまま利用させてもらった。
wordpressの引っ越し | 紅い夕陽

作業

サーバー側での作業となる。
今回はvagrant環境で作業をしたので、$ vagrant sshでsshログインして作業した。
また、ルートログインしておく。

・必要なモジュールをインストール

1
2
3
4
# yum install gcc
# yum -y install openssl-devel
# yum -y install wget
# yum -y install lbzip2

・curlを取得して展開(curlは少し前のバージョン)

1
2
3
4
# wget http://curl.haxx.se/download/curl-7.37.0.tar.bz2
# tar xf curl-7.37.0.tar.bz2
# cd curl-7.37.0
# ./configure --enable-libcurl-option

・コンパイルしてインストール

1
2
# make
# make install

・ライブラリを登録

1
# vi /etc/ld.so.conf.d/curl-x86_64.conf

内容

1
/usr/local/lib

・ライブラリを更新

1
# ldconfig -v

最後に、apacheを再起動しておく。

1
# service httpd restart

これでOpensslを使うように変更できた。

この状態で再度冒頭のPHPでアクセスすると、無事、接続することが出来た。

参考

   このエントリーをはてなブックマークに追加