CygwinでHTTPS接続できないときはca-certificatesをチェックしよう

何度かブログで触れている気がするdropbox-apiスクリプト

https://github.com/s-aska/dropbox-api-command

いつの頃からか(今思えばCygwinパッケージをアップグレードした辺りからか・・・)エラーになった。

$ dropbox-api ls /sync
2018-05-28T16:51:48 [WebService::Dropbox] [ERROR] https://api.dropboxapi.com/2/files/list_folder {"path":"/sync"} -> [500] Can't connect to api.dropboxapi.com:443

なんやねん、dropboxが落ちてるのかAPIが終了になったのか・・・と思ってcurlでチェックしてみるとAPIは問題なく動作してるっぽい。

$ curl -k -X POST https://api.dropboxapi.com/2/files/list_folder \
>     --header "Authorization: Bearer $ACCESS_TOKEN" \
>     --header "Content-Type: application/json" \
>     --data "{\"path\": \"/sync\"}"

ちなみに-kをつけないとcertificateのエラーが出る(これも伏線)。

curl: (77) error setting certificate verify locations:
  CAfile: /etc/pki/tls/certs/ca-bundle.crt
  CApath: none

小一時間悩んで、そもそもPerlHTTPSアクセスができないのでは・・・と思って簡単なスクリプトでチェックしてみたらビンゴっぽい。

use strict;
use warnings;
use LWP::UserAgent;
use HTTP::Request;

my $ua = LWP::UserAgent->new;
my $req = HTTP::Request->new( GET => 'https://www.flickr.com/');
my $response = $ua->request($req);

### $response
### $response: bless( {
###                     _content => 'Can\'t connect to www.flickr.com:443',
..
###                     _msg => 'Can\'t connect to www.flickr.com:443',
###                     _rc => 500,

PerlというかLWPでHTTPSのコンテンツが取得できない、ってわりと良くある割に分かりにくい問題で、一昔前ならNet::SSLeayをインストールしましょうみたいなのがテンプレだったのだけど。

PerlでSSL(https)のサイトのコンテンツが取得できない - ノウハウブログ - カンタローCGI

一通り必要そうなモジュールをチェックしてみたけど導入済みだし、何やろうなあ。

"perl https 500 error"で検索したら最初に出てくるサイト。

perl - 500 error with LWP:UserAgent - Stack Overflow

"verify_hostname=0" ねえ・・・そういや上のcurlでも証明書のエラーが出てたな、と思って試してみたら動くではないか。

というわけで、当初の問題は環境変数 PERL_LWP_SSL_VERIFY_HOSTNAME=0 を指定すれば解決。

$ PERL_LWP_SSL_VERIFY_HOSTNAME=0 dropbox-api ls /sync

・・・解決はするけど、毎度毎度証明書を無視するオプションを付けるのは面倒だしセキュリティ的にもいかがなものかと思うので、もう少し調べる。

と、Cygwinでは ca-certificates パッケージが証明書ファイルを持っているようなので再インストールしてみると環境変数を指定しなくても動くようになった。

よかったよかった。それにしてもHTTPSというかSSLというか証明書周りは面倒くさいなあ・・・。