LWP::UserAgent
モジュールを使って、Facebook の API を叩いている時に出くわした現象の対応メモ。Facebook では API のリクエストを HTTPS で行うのですが、この時、クライアントにインストールされている SSL 証明書と、Facebook で使用している証明書の不整合か何かでエラーになってしまうというものです。
例えば、次のような Perl スクリプトを書いて HTTPS で公開されている URL にアクセスしようとします。
use LWP::UserAgent; my $ua = LWP::UserAgent->new or die; my $res = $ua->get( 'https://www.example.com/hoge.txt' ) or die;
この時、インストールされている Crypt::SSLeay
の持っている認証局の一覧に、www.example.com
の SSL 証明書が掲載されていなかったりして、ルート証明書まで辿り着けなかったりすると、次のようなエラーが生成されます。
500 Can't verify SSL peers without knowning which Certificate Authorities to trust
環境変数 PERL_LWP_SSL_VERIFY_HOSTNAME
を 0 に設定するか、LWP::UserAgent
の通信オプションを設定することで、証明書のホスト名による検証を抑制します。ただ、この方法だと SSL 通信をしている意味が半分なくなってしまうので、実験目的などに限って使うくらいで。
$ENV{'PERL_LWP_SSL_VERIFY_HOSTNAME'} = 0; # または $ua->ssl_opts( verify_hostname => 0 );
LWP::UserAgent
の通信オプションで、認証に用いる CA 証明書を明示する方法です。多分、こっちのが安全。Mozilla::CA
モジュールは、CPAN を使ってサクサクッとインストールできます。
use LWP::UserAgent; use Mozilla::CA; my $ua = LWP::UserAgent->new or die; $ua->ssl_opts( SSL_ca_file => Mozilla::CA::SSL_ca_file()); my $res = $ua->get( 'https://www.example.com/hoge.txt' ) or die;