メール送信テストツールMailHogの設定
はじめに
先日、LinuxサーバーにMailHogをインストール、設定する機会がありました。
インターネット上に参考情報があるため、MailHogをインストールして起動すること自体はそれほど難しくなかったのですが、サーバーの運用としては、少し工夫が必要でしたので、ここにまとめておきます。
MailHogは、アプリケーションから送信したメールを確認するためのテストツールです。
・MailHog – GitHub MailHog
https://github.com/mailhog/MailHog
受信メール確認のWebUIと、そのテスト用メールボックスに送信するためのSMTP機能を備えており、インターネットへのリアルメール送信が難しいPCの開発環境で使用されることが多いでしょう。
今回は、Linuxサーバー上にMailHogをインストール、設定します。
OSは、AlmaLinux 9です。
設定手順
インストール、設定手順としては、以下を参考にしました。
ありがとうございます。
・Mailhog_installation.md – GitHub dipenparmar12
https://gist.github.com/dipenparmar12/4e6cd50d8d1303d5e914742f62659116
・MailHog をリバースプロキシに通したら Error during WebSocket handshake: Unexpected response code: 400 と怒られたときに読むページ – Qiita
https://qiita.com/yokra9/items/2094626f3339cca5c5b8
- MailHogのインストール
- Systemdのサービスとして登録、起動
- ログ出力設定
- Apacheのリバースプロキシ設定
1. MailHogのインストール
GitHubからビルド済み MailHog のバイナリをダウンロードするのが手っ取り早いでしょう。
・MailHog Releases – GitHub MailHog
https://github.com/mailhog/MailHog/releases
※そうすれば、Goをインストールする必要もありません。
今回は、wgetコマンドでダウンロードして、/usr/local/bin/mailhog としてインストールし、実行権限を付与します。
# wget https://github.com/mailhog/MailHog/releases/download/v1.0.1/MailHog_linux_amd64 \ -O /usr/local/bin/mailhog # chmod +x /usr/local/bin/mailhog # ls -l /usr/local/bin/mailhog -rwxr-xr-x 1 root root 13367472 12月 7 2021 /usr/local/bin/mailhog
一時的に MailHog を起動してみます。
# mailhog 2024/12/13 16:24:05 Using in-memory storage 2024/12/13 16:24:05 [SMTP] Binding to address: 0.0.0.0:1025 [HTTP] Binding to address: 0.0.0.0:8025 2024/12/13 16:24:05 Serving under http://0.0.0.0:8025/ Creating API v1 with WebPath: Creating API v2 with WebPath:
↑起動時のメッセージ出力から、MailHogは
SMTPはTCP/1025ポート
WebUIはTCP/8025ポート
を使用していることがわかります。
サーバーのWebブラウザコマンドから管理画面にアクセスしてみます。
ここでは、lynxを使用していますが、wgetやcurlでダウンロードして、index.html を確認しても構いません。
$ lynx http://0.0.0.0:8025/ MailHog MailHog ____________________ Find messages containing {{ searchText }} Find messages to {{ searchText }} Find messages from {{ searchText }} * GitHub GitHub * {{ hasEventSource ? 'Connected' : 'Disconnected' }} * Inbox ({{totalMessages}}) * Delete all messages ...
それっぽいページが表示されることを確認できたら、mailhogコマンドを起動したターミナルで、Ctl-Cで、mailhogを終了します。
2. Systemdのサービスとして登録、起動
サーバー上で管理しやすいよう、MailHog を Systemd のサービスとして登録します。
Unitファイルを作成します。
※参考記事では、ExecStart で mailhog を起動するコマンドの先頭に /usr/bin/env が付与されているものもありますが、そうすると、この後のrsyslog設定でログを扱う際のプログラム名が env となってしまうため、ここでは付与しません。
# vim /etc/systemd/system/mailhog.service -- [Unit] Description=Mailhog After=network.target [Service] Type=simple ExecStart=/usr/local/bin/mailhog > /dev/null 2>&1 & [Install] WantedBy=multi-user.target --
MailHogサービスを起動、自動起動設定します。
# systemctl enable --now mailhog -- Created symlink /etc/systemd/system/multi-user.target.wants/mailhog.service → /etc/systemd/system/mailhog.service. -- # systemctl status mailhog | less -- ● mailhog.service - Mailhog Loaded: loaded (/etc/systemd/system/mailhog.service; enabled; vendor preset: disabled) Active: active (running) since Fri 2024-12-13 17:07:43 JST; 1s ago Main PID: 1520799 (mailhog) Tasks: 4 (limit: 5742) Memory: 2.4M CGroup: /system.slice/mailhog.service mq1520799 /usr/local/bin/mailhog > /dev/null 2>&1 & 12月 13 17:07:43 hostname systemd[1]: Started Mailhog. 12月 13 17:07:43 hostname mailhog[1520799]: 2024/12/13 17:07:43 Using in-memory storage 12月 13 17:07:43 hostname mailhog[1520799]: 2024/12/13 17:07:43 [SMTP] Binding to address: 0.0.0.0:1025 12月 13 17:07:43 hostname mailhog[1520799]: [HTTP] Binding to address: 0.0.0.0:8025 12月 13 17:07:43 hostname mailhog[1520799]: 2024/12/13 17:07:43 Serving under http://0.0.0.0:8025/ 12月 13 17:07:43 hostname mailhog[1520799]: Creating API v1 with WebPath: 12月 13 17:07:43 hostname mailhog[1520799]: Creating API v2 with WebPath: --
プログラム名「mailhog」としてログが出力されています。
「Creating API v1 with WebPath:」とあるので、無事起動したようです。
3. ログ出力設定
MailHogサービスを無事起動できましたが、このままでは、/var/log/messages に毎分以下のようなログが出力されます。
# less /var/log/messages Dec 13 17:08:43 hostname mailhog[1520799]: [APIv1] KEEPALIVE /api/v1/events Dec 13 17:09:43 hostname mailhog[1520799]: [APIv1] KEEPALIVE /api/v1/events Dec 13 17:10:43 hostname mailhog[1520799]: [APIv1] KEEPALIVE /api/v1/events
このままでは、/var/log/messages の重要なメッセージが検出しにくいため、rsyslogの設定で、MailHogサービスのログは、専用の /var/log/mailhog に出力するようにします。
※Systemd Unit設定の ExecStart で /usr/bin/env を指定しなかったことで、「programname が mailhog であれば~」というログフィルター設定が可能となります。
# vim /etc/rsyslog.d/mailhog.conf -- :programname, isequal, "mailhog" /var/log/mailhog.log & stop --
rsyslogを再起動して反映し、正しく起動したことを確認します。
※rsyslogの設定が間違っていると、rsyslogが停止し、syslogが全く出力されないこともあるため、注意しましょう。
# systemctl restart rsyslog # systemctl status rsyslog -- ● rsyslog.service - System Logging Service Loaded: loaded (/usr/lib/systemd/system/rsyslog.service; enabled; vendor pre> Active: active (running) since Fri 2024-12-13 17:14:10 JST; 3s ago Docs: man:rsyslogd(8) https://www.rsyslog.com/doc/ Main PID: 1521247 (rsyslogd) Tasks: 3 (limit: 5742) Memory: 9.6M CGroup: /system.slice/rsyslog.service mq1521247 /usr/sbin/rsyslogd -n 12月 13 17:14:10 hostname systemd[1]: Starting System Logging Service... 12月 13 17:14:10 hostname systemd[1]: Started System Logging Service. 12月 13 17:14:10 hostname rsyslogd[1521247]: [origin software="rsyslogd" swVers> 12月 13 17:14:10 hostname rsyslogd[1521247]: imjournal: journal files changed, --
MailHogサービスのログが /var/log/mailhog.log に出力され、/var/log/messages には出力されないことを確認します。
# less /var/log/mailhog.log Dec 13 17:14:43 hostname mailhog[1520799]: [APIv1] KEEPALIVE /api/v1/events Dec 13 17:15:43 hostname mailhog[1520799]: [APIv1] KEEPALIVE /api/v1/events # less /var/log/messages
/var/log/maillog.log のログローテートを設定します。
以下は、週次でローテートし、1年間保存する例です。
# vim /etc/logrotate.d/mailhog -- /var/log/mailhog.log { weekly rotate 52 compress missingok notifempty sharedscripts delaycompress postrotate /bin/systemctl restart mailhog > /dev/null 2>/dev/null || true endscript } --
4. Apacheのリバースプロキシ設定
受信メール確認のWebUIを、インターネット経由でアクセスできるようにします。
ここでは、WebUIのURLは、以下とします。
https://example.jp/mailhog/
ドメイン example.jp の Apache VirtualHost Config で、URLパス /mailhog/ へのアクセスを MailHog WebUI のTCP/8025ポートへ転送するリバースプロキシ設定を追記します。
MailHogは WebSocket を使用しているため、リバースプロキシでも WebSocket を通すよう、proxy_wstunnel モジュールを使用するのがポイントです。
(ws:// を含む行。)
# vim /etc/httpd/conf.d/vhost_ssl_example.jp.conf -- ... # MailHog WebUI ProxyPass /mailhog/api/v2/websocket ws://0.0.0.0:8025/api/v2/websocket ProxyPassReverse /mailhog/api/v2/websocket ws://0.0.0.0:8025/api/v2/websocket ProxyPass /mailhog/ http://0.0.0.0:8025/ ProxyPassReverse /mailhog/ http://0.0.0.0:8025/ ... --
mod_proxy, mod_proxy_http, mod_proxy_wstunnel モジュールのLoadが有効となっていることを確認します。
# vim /etc/httpd/conf.modules.d/00-proxy.conf -- ... LoadModule proxy_module modules/mod_proxy.so ... LoadModule proxy_http_module modules/mod_proxy_http.so ... LoadModule proxy_wstunnel_module modules/mod_proxy_wstunnel.so ... --
Apacheを再起動して反映します。
# apachectl configtest # systemctl restart httpd
第三者にアクセスされないよう、必要に応じて、BASIC認証やアクセス元IPアドレスの制限を追加しておくとよいでしょう。
ちなみに、Nginxの場合は、こんな設定になります。
こちらも、リバースプロキシでもWebSocketを通すようにするのがポイントです。
# MailHog WebUI location /mailhog/ { chunked_transfer_encoding on; proxy_pass http://0.0.0.0:8025/; proxy_set_header X-NginX-Proxy true; proxy_set_header Upgrade $http_upgrade; proxy_set_header Connection "upgrade"; proxy_http_version 1.1; proxy_redirect off; proxy_buffering off; }
(参考)
・MailHog not working when using nginx proxy pass – GitHub MailHog
https://github.com/mailhog/MailHog/issues/117
Apache(もしくはNginx)の設定が完了したので、WebブラウザからWebUIにアクセスしてみます。
https://example.jp/mailhog/
以下のようなWebUIページが表示されればOKです。
メール送信テスト
PHPアプリケーションからのメール送信テストを実施します。
(参考)
・Docker ComposeでMailHogコンテナを組み合わせてメール送信の動作確認
https://zenn.dev/qljmssqh/articles/5e38a3c9123018
・DockerでMailHogを使ってPHPのメール送信確認をする
https://qiita.com/ran/items/0dede7d3f28601b2ad96
まず、PHPからのメール送信でMailHogのSMTPに送信するよう、php.ini の sendmail_path パラメータを変更し、Linuxサーバーのsendmailコマンドではなく、MailHogコマンドを使用して送信するようにします。
# vim /etc/php.ini -- ;sendmail_path = /usr/sbin/sendmail -t -i sendmail_path = /usr/local/bin/mailhog sendmail --
PHP-FPMを再起動して反映します。
# systemctl restart php-fpm
サーバーに、メール送信テスト用PHPページを設置します。
# vim <DocumentRoot>/sendmail_test.php -- <?php $from = 'from@example.jp'; $to = 'to@example.com'; $subject = 'テストメール'; $body = 'MailHogのメール送信テストです。'; $header = "From: ".$from."\r\n"; $ret = mb_send_mail($to, $subject, $body, $header); var_dump($ret); --
ブラウザからメール送信テスト用PHPページのURLにアクセスすることで、PHPを実行します。
https://example.jp/sendmail_test.php
MailHogのWebUIページで、受信メールを確認します。
↑無事、メールが届いたことと、メールの内容を確認できました。
うまくいかない場合は、MailHogのログや、Apacheのアクセスログ、エラーログを確認、調査するとよいでしょう。
なお、php.ini で、
mbstring.language = Japanese
を設定している場合、メール送信時の文字コードが ISO-2022-JP となりますが、MailHogは ISO-2022-JP に非対応のようで、WebUIでメールの日本語が文字化けして表示されます。
この場合は、メール送信テストのPHPで、UTF-8で送信するよう工夫が必要なようです。
以下などを参考にするとよいでしょう。
(参考)
・mb_send_mailで送ったメールをMailHogで受け取ると文字化けする – teratail
https://teratail.com/questions/318732
・PHPマニュアル mb_language
https://www.php.net/manual/ja/function.mb-language.php
おわりに
メール送信テストツールMailHogをLinuxサーバーにインストール、設定する手順をまとめました。
PCの開発環境で動作させる場合と違い、インターネット上のLinuxサーバーで運用する場合は、Webのリバースプロキシ設定や、ログ出力設定で、少し工夫が必要です。