ユーザ用ツール

サイト用ツール


プログラム言語:php:imap関数:imap_open_で_couldn_t_open_stream_エラーが出る

差分

このページの2つのバージョン間の差分を表示します。

この比較画面にリンクする

プログラム言語:php:imap関数:imap_open_で_couldn_t_open_stream_エラーが出る [2020/07/15 18:14] (現在)
humolife 作成
行 1: 行 1:
 +====== 【PHP】imap_open で「Couldn't open stream」エラーが出る ======
 +メールサーバを自作し、imap_open でメールサーバにある受信メールを取得するプログラムを作成していた際に遭遇したエラーとその対処法について。\\
 +==== 遭遇したエラー ====
 +SSL / TLS を使用して POP3 / IMAP でメールを取得しようとしたところエラーが発生。
 +=== Laravel でのエラー表示 ===
 +> ErrorException
 +> imap_open(): Couldn't open stream {localhost:993/imap/ssl}INBOX
  
 +=== PHP エラーログ上の表示 ===
 +> PHP Fatal error:  Uncaught ErrorException: Unknown: Certificate failure for localhost: Server name does not match certificate: /CN=example.com (errflg=2) in Unknown:0
 +> Stack trace:
 +> #0 [internal function]: Illuminate\Foundation\Bootstrap\HandleExceptions->handleError()
 +> #1 {main}
 +>   thrown in Unknown on line 0
 +
 +=== /var/log/maillog の内容 ===
 +> dovecot: imap-login: Disconnected (no auth attempts in 0 secs): user=<>, rip=127.0.0.1, lip=127.0.0.1, TLS, session=<XXXXXXXXXXXXXXX>
 +
 +==== 現象 ====
 +Postfix と Dovecot に SSL/TLS を導入する前は imap_open が成功していました。
 +(POP3:110番ポート、IMAP:143番ポート)
 +<code>
 +$account = 'mail@example.com';
 +$password = 'PASSWORD';
 +
 +# POP3 で接続(成功)
 +$mailbox = '{localhost:110/pop3/notls}INBOX';
 +$mbox = imap_open($mailbox, $account, $password)
 +    or die('接続エラー: ' . imap_last_error());
 +imap_close($mbox);
 +
 +# IMAP で接続(成功)
 +$mailbox = '{localhost:143/imap/notls}INBOX';
 +$mbox = imap_open($mailbox, $account, $password)
 +    or die('接続エラー: ' . imap_last_error());
 +imap_close($mbox);
 +</code>
 +ところが、SSL/TLS を導入後 imap_open でエラーが出るようになりました。
 +(POP3S:995番ポート、IMAP4S:993番ポート)
 +<code>
 +# POP3S で接続(失敗)
 +$mailbox = '{localhost:995/pop3/ssl}INBOX';
 +$mbox = imap_open($mailbox, $account, $password)
 +    or die('接続エラー: ' . imap_last_error());
 +imap_close($mbox);
 +
 +# IMAP4S で接続(失敗)
 +$mailbox = '{localhost:993/imap/ssl}INBOX';
 +$mbox = imap_open($mailbox, $account, $password)
 +    or die('接続エラー: ' . imap_last_error());
 +imap_close($mbox);
 +</code>
 +==== 解決方法 ====
 +「/novalidate-cert」を付けるだけ。。。
 +<code>
 +# POP3S で接続(成功)
 +$mailbox = '{localhost:995/pop3/ssl/novalidate-cert}INBOX';
 +$mbox = imap_open($mailbox, $account, $password)
 +    or die('接続エラー: ' . imap_last_error());
 +imap_close($mbox);
 +
 +# IMAP4S で接続(成功)
 +$mailbox = '{localhost:993/imap/ssl/novalidate-cert}INBOX';
 +$mbox = imap_open($mailbox, $account, $password)
 +    or die('接続エラー: ' . imap_last_error());
 +imap_close($mbox);
 +</code>
 +デバッグ情報を表示するようにしたり、色々試した結果、最終的には [[https://www.php.net/manual/ja/function.imap-open.php#95959|PHPの公式ドキュメントにあるコメント]] の記述に助けられ、無事動くようになりました。
 +
 +公式ドキュメントには「/novalidate-cert」オプションは、自己証明書を使っている際に必要、とあったので、Let's Encrypt を使用していた今回は関係ないと思っていたのですが、原理は分からないままなものの、このオプションを付けることで成功するようになりました。
 +
 +ちなみに、Thunderbird などのメールソフトでは正常に送受信に成功しているので、証明書が間違っているということはありません。\\
 +なぜだ。。。
プログラム言語/php/imap関数/imap_open_で_couldn_t_open_stream_エラーが出る.txt · 最終更新: 2020/07/15 18:14 by humolife