mb_send_mailでメールが送れない時に行ったPostfixの設定

こんにちわ。よこやんです。
今回は、Linux(Red hat)サーバにてmb_send_mailでメールが送れない時に、Postfixで行った設定についてまとめました。
以下、至った経緯です。

実は納品済みのWeb予約システムがあるのですが、
ある日お客様から、一部メールアドレス(gmail、icloud等)に予約通知メールが送信されないと問い合わせがありました。

どうやら導入当初かららしく、1年以上経ってるのによく我慢したなと…
前々から問い合わせしてたようで、どうやら対応していなかったみたいです…
ほんと前任者の責任感は終わってます。ほったらかして退職しやがって。

プログラムを確認すると、どうやらPHPでmb_send_mailを使ってメール送信をしているようでした。

さすがに対応しなきゃまずいということで、一部のメールアドレス宛にメール送信ができない理由を調べたところ、Postfixの設定をすればできるかもしれないということがわかりました。

・Postfixとは

Postfix(ポストフィックス)は、UNIX系OS向けに開発されたオープンソースのメール転送エージェント(MTA:Mail Transfer Agent)です。主に電子メールの送信や中継を担当し、SMTP(Simple Mail Transfer Protocol)プロトコルを使用してメールを配送します。

特徴
・セキュリティと安定性
 Postfixは、セキュリティと安定性を重視して設計されており、外部からの攻撃
 に対して堅牢な構造を持っています。

・高速な処理性能
 効率的な設計により、大量のメールを高速に処理することが可能です。

・設定の容易さ
 設定ファイルがシンプルで、初心者でも比較的簡単に扱うことができます。

・モジュール構造
 複数の独立したデーモン(常駐プログラム)で構成されており、各デーモンが
 特定の機能を担当することで、柔軟な運用が可能です。

参考
ウィキペディア-Postfix
Postfix入門:初心者のためのわかりやすいガイド
【入門】Postfixとは?メールサーバー構築方法と基本設定
SMTPサーバの内部はどのように動いているのか?
e-words Postfix

・メールが送れてなかった原因

PHPのソースを確認すると、予約時にmb_send_mailでメール送信をしていました。
ただ「var/log/maillog」に以下のようなログが大量に出力されていました。

Sender address rejected: Domain not found (in reply to RCPT TO command))

これは、メールサーバ側で存在しないドメインからのメール通信を許可していないと、出力されるログのようです。
ログを見ると、「apache@localhost.localdomain」からメールを送信しているようでした。

参考
【Postfix】553 5.1.8 Sender address rejected: Domain not found (in reply to RCPT TO command) の原因と対処法【備忘】

・Postfix設定

Postfixは初めからインストールされていることが多いらしく、私の環境でも初めからありました。
インストールされていると、/etc/postfix/にファイルがあります。
この中の「main.cf」に以下を追記します。

・relayhost = [mail.example.com]:587
 Postfixが外部宛にメールを送信する際に、直接相手のサーバーに送る代わりに
 mail.example.comのSMTPサーバー(ポート587)をリレーサーバーとして使う
 という指定です。

・smtp_sasl_auth_enable = yes
 SMTPリレーサーバーに接続するときに、
 SMTP認証(SASL認証)を有効にするという設定です。

・smtp_sasl_password_maps = hash:/etc/postfix/sasl_passwd
 リレーサーバーに接続する際に使う「ユーザー名とパスワード」を
 どこから読み込むかを指定します。
 
・smtp_sasl_security_options = noanonymous
 SASL認証時に「匿名認証(anonymous認証)」は許可しない、
 つまり必ずユーザー名とパスワードを使わせる設定です。

・smtp_use_tls = yes
 リレーサーバーにメールを送るときに、TLS暗号化を使うように指示します。
 (メールの盗聴防止・改ざん防止のため)

・smtp_tls_security_level = encrypt
 encryptを指定すると、必ずTLSを使って通信します。
 TLSが使えないなら通信しないという動作になります。
 
・smtp_generic_maps = hash:/etc/postfix/generic
 送信元アドレスを変換する際に使う「メールアドレス」を
 どこから読み込むかを指定します。

参考
Postfix SASL Howto
Postfix Configuration Parameters

ちなみに、genericとsasl_passwdの中身は以下になります。

generic
左に変換前、右に変換後のメールアドレスを指定します。

sasl_passwd
送信メールアドレスの認証情報を入力します。
左からSMTPサーバ、ポート、メールアドレス、パスワードになります。

上記の設定が完了したら、Postfixのサービスを再起動します。

・まとめ

今回は、PHPでmb_send_mailを使ってメールが送信できない時に、Postfixの設定を行うことで送信ができるようになりました。

納品済みのサーバでは認証の設定が全くされていなかったため、ポート25番でメールを送信しようとし、gmailやicloudのようなセキュリティの高いドメインにはじかれていたのかなと思います。

メールの仕組みがしっかりわかっていないため、間違ったことが記載されていましたら、指定いただけると幸いです。

導入当初からという話で、複数メールアドレスの受信テストしてなかったのが問題ですね。
また1つ賢くなれたということで、今日はこの辺で!
よこやんでした。

コメント

タイトルとURLをコピーしました