PHPMailer での送信エラー 「stream_socket_enable_crypto(): Peer certificate CN=`*.example.com’ did not match 」
cron で動かす社内用スケジューラ(メール通知)のテストでハマッた現象。
SSLではなくTLS、共用サーバで動かす予定なのだけれども、どうも動かない。
いろいろ試すと、PHP 7 から php 5.3 にバージョンダウンしてみると期待の動作になったので、ここらへんに原因があるのだろうと調べると、PHPMailer とは違う話なのですが、次のような情報があり助かりました。
これはPHP5.6になってOPEN SSLのアップデートがあったため。
PHP5.6 からはピア証明書が必須になったようで・・・
これがないと証明書の検証に失敗しました的なエラーが発生します。
https://github.com/PHPMailer/PHPMailer/wiki/Troubleshooting
対策はphp.iniの変更か、証明書を作るか、PHP5.5.x系を使うかと行った所です。
PHP5.6ではSMTPメールが送れない – iT-STUDIO | 仙台のフリーランスWORDPRESSホームページ制作チーム
WordPress で SMTP 関連のプラグインが動く場合と動かない場合があり悩んでたんですが、その謎が一気に解けました、おまえだったのか。
PHP 5.6.x における OpenSSL 関連の変更
詳細は下記のとおりでした。
暗号化されたすべてのクライアントストリームで、ピア検証がデフォルトで有効になりました。 デフォルトでは、OpenSSL のデフォルト CA バンドルを使ってピア証明書を検証します。 たいていの場合は、正しい SSL 証明書を持つサーバーと通信するならこれを変更する必要はありません。 OpenSSL が、よく知られた CA バンドルを使うように設定されているからです。
PHP: PHP 5.6.x における OpenSSL 関連の変更 – Manual
というわけで file_get_contents なども通信でエラーが出るようになります。stream_get_meta_data() や stream_context_get_options() で $context を変更し対処するようですが、PHPMailerだとどうするのでしょう?
PHP 5.6 certificate verification failure
PHPMailerライブラリの内部にかかわってくるので、コアハックで対処はいやだな、オプションないのかな、と思って探した所、でてきました SMTP Options。
1 2 3 4 5 6 7 |
$mail->SMTPOptions = array( 'ssl' => array( 'verify_peer' => false, 'verify_peer_name' => false, 'allow_self_signed' => true ) ); |
Troubleshooting · PHPMailer/PHPMailer Wiki · GitHub
結局はエラー時に表示されるトラブルシューティング内に答えがありました、そういうところで答えを見つけたためしがなかったので、どうせ無いだろうとたかをくくって時間を食う、無念。
verify_peer
SSL サーバー証明書の検証を要求するかどうか。(初期値TRUE)
verify_peer_name
ピア名の検証を要求するかどうか。(初期値TRUE)
allow_self_signed
自己証明の証明書を許可するかどうか。
verify_peer が必要。(初期値FALSE)
自作の証明書を php.ini で追加するのが王道のような気がするけど、別にメールフォームを公開しててそこから飛ばしてるわけでもないので、PHPMailer 側で対処でいいやっていう
