AWSの2011 Xmas企画「サンタに願いを」(#サンタクラウド)の準備をしてる際に起きたエラーを紹介します。
$response = $s3->create_object("www.suz-lab.com", "santacloud/tweet.json", array( "body" => json_encode($ranking), "acl" => AmazonS3::ACL_PUBLIC, "contentType" => "text/javascript" ));
通常通り、上記のコードでS3にファイルをアップロードしようとしたところ、下記のようなエラーが発生してしまいました。
PHP Fatal error: Uncaught exception 'RequestCore_Exception' with message 'cURL resource: Resource id #10; cURL error: SSL: certificate subject name '*.s3-ap-northeast-1.amazonaws.com' does not match target host name 'www.suz-lab.com.s3-ap-northeast-1.amazonaws.com' (51)' in /opt/aws/php/1.4.2.1/lib/requestcore/requestcore.class.php:824 Stack trace: #0 /opt/aws/php/1.4.2.1/services/s3.class.php(723): RequestCore->send_request() #1 /opt/aws/php/1.4.2.1/services/s3.class.php(1230): AmazonS3->authenticate('www.suz-lab.com', Array) #2 /opt/suzuki/bin/twitter(38): AmazonS3->create_object('www.suz-lab.com', 'santacloud/twee...', Array) #3 {main} thrown in /opt/aws/php/1.4.2.1/lib/requestcore/requestcore.class.php on line 824
「*.s3-ap-northeast-1.amazonaws.com」の証明書では、「www.suz-lab.com.s3-ap-northeast-1.amazonaws.com」にはマッチしない、というエラーです。
「suz-lab.s3-ap-northeast-1.amazonaws.com」なら問題ないようですが、バケット名に「.」がある場合は、上記のエラーが発生してしまうようです。
回避方法は下記のように、証明書の検証をしないようにcURLのオプション(CURLOPT_SSL_VERIFYPEER => false)を付与する方法です。
$response = $s3->create_object("www.suz-lab.com", "santacloud/tweet.json", array( "body" => json_encode($ranking), "acl" => AmazonS3::ACL_PUBLIC, "contentType" => "text/javascript", "curlopts" => array(CURLOPT_SSL_VERIFYPEER => false) ));
少し調べてみると、このオプションは下記とのことです。
cURL 7.10 以降、デフォルト値は TRUE です。
また、 cURL 7.10 以降、デフォルトでインストールされています。
実際にバージョンを調べてみると、下記の通りでした。
# curl --version curl 7.19.7 (i686-pc-linux-gnu) libcurl/7.19.7 NSS/3.12.7.0 zlib/1.2.3 libidn/1.18 libssh2/1.2.2 Protocols: tftp ftp telnet dict ldap ldaps http file https ftps scp sftp Features: GSS-Negotiate IDN IPv6 Largefile NTLM SSL libz
以前このオプション無しでエラーにならなかったのは、このcURLのバージョンが古かったからだと思います。