前置き
目的
PHPのmb_send_mailを使用してメールを送信したい。
送信元のアドレスは手持ちのGmailアドレスで。
これ、プログラム自体は簡単なんですが、送信を成功させるまでの事前準備が結構面倒でした。
(Postfix側の設定の問題で、送信できてなくてもmb_send_mailの戻り値はtrueを返すし。)
<?php
//言語と文字コードの使用宣言
mb_language("ja");
mb_internal_encoding("UTF-8");
// 送信情報をセット
$to = "宛先のメールアドレス@example.com";
$from = "送信元アドレス@gmail.com";
$subject = "メールの送信テスト";
$message = "こちらはテストメールです";
$header = "From: " . $from;
//メール送信
mb_send_mail($to, $subject, $message, $header);
ちなみに、送信元のアドレスは、ケースによって自前ドメインのアドレスの方が良いのだろうけど、今回は自分宛にアラートを送信するのが目的のシステムだったのと、SMTPサーバを構築/運用するのが面倒なので、Gmail経由としました。
MTAについて
今回、MTAはPostfixを使用しますが、設定方法を調べる過程でsendmailとかとごっちゃになった(自分だけかも)ので前知識として少しだけ整理。
MTAとは(Mail Transfer Agent)の略。メールを転送・配送するソフトウェア。
メールサーバの役割・機能の分類の一つで電子メールを配信/転送するソフトウェアのこと。
MTAにはいくつか種類、特徴がある。
MTA | 速度 | セキュリティ | 設定難易度 | 特徴 |
---|---|---|---|---|
postfix | ◎ | ○ | ○ | ・CentOS7では初期インストールされている。 ・sendmailとの互換性があり。 ・1999年の公開後から現在に至るまでの間、開発も活発に行われている。 |
sendmail | × | × | × | ・最も古いMTAの1つ。 ・標準ソフトウェアと広くしたが、最近はセキュリティ面や性能面から、他のMTAの利用が増えている状況。 |
qmail | ○ | ◎ | ○ | ・動作が高速で、セキュリティも非常に強固な特徴あり。設定ファイルも簡単。 しかし、qmail本体のソースコードは1998年のリリースが最後で、それ以降は開発が止まっている。 |
必要な設定
ここからが本題です。
PostfixからGmailを経由させてメールを送信するために必要な設定事項があります。
1) Gmailアカウントの2段階承認の有効化
2) Gmailアカウントのアプリパスワードを発行
3) 発行したアプリパスワードを元に、Gmailを経由させてメールを送信するためのPostfix側の設定(リレー設定)をする
これら3点の手順を以下に展開します。
Gmailアカウント側の設定
2段階承認の有効化
最近ではGoogleアカウントのセキュリティが強化されているため、以前のように、2段階認証なしでは「安全性が低いアプリ」と判定されてしまいメール送信ができなくなってしまったようです。
そのため2段階認証を有効化をしておきます。
まず、 Googleアカウントの管理画面 にアクセスします。
(送信元GmailのアカウントとなるGoogleアカウントにログインしていなければログインもしておきましょう。)
Googleアカウントの管理画面 にて「セキュリティ」=>「2段階承認プロセス」をクリックします。
すると、以下画面に遷移すると思います。
「使ってみる」のボタンをクリックします。
ログイン画面が表示されるので、ログインします。
紐づけられているスマホを確認して、「続行」ボタンをクリックします。
※一覧に利用スマホがない場合、「デバイスが一覧にない場合」をクリックして設定をしてください。
紐づけられているスマホの電話番号を指定(黒で塗りつぶされている箇所)して、「送信」をクリックします。
スマホ端末に認証コードがSMSで送られてくるので、入力して「次へ」をクリックします。
内容を確認して、問題なければ「有効にする」をクリックします。
これで2段階承認が有効になりました!
アプリパスワードを発行
アプリパスワードとは、普段のGmailの認証に使用しているパスワードとは別物で、今回のメール送信で使用するためのパスワードとなります。
引き続き、Googleアカウントの管理画面 から設定をしていきます。
Googleアカウントの管理画面 にて「セキュリティ」=>「アプリパスワード」をクリックします。
※「アプリパスワード」は2段階承認設定が完了していないと表示されません。
ログイン画面が表示されるので、ログインします。
アプリを選択で「メール」を選択します。
デバイスを選択で「その他(名前を入力)」を選択します。
適当なデバイス名を入力して「生成」をクリックします。
16文字のアプリパスワードが生成されるので控えておきます。
ここまで来たらGmailアカウント側の設定は完了となります。
Postfix側の設定
PostfixからGmailを経由(リレー)させてメールを送信できるように設定します。
パスワードファイルの作成
生成したアプリパスワードを元に、GmailのSMTP認証情報ファイルを作成します。
「gmail_passwd」というファイルを新規作成しました。
# sudo vi /etc/postfix/gmail_passwd
[smtp.gmail.com]:587 <Gmailのアドレス>:<Gmailのアプリパスワード>
例として、Gmailのアドレスが「sample@gmail.com」で、アプリパスワードが「123456789」の場合、パスワードファイルの中身は以下のようになります。
[smtp.gmail.com]:587 sample@gmail.com:123456789
オーナーのみアクセスできるようにパーミッションを設定しておきます。
# sudo chmod 600 /etc/postfix/gmail_passwd
Postfix用のDBファイルを生成します。
# postmap /etc/postfix/gmail_passwd
/etc/postfixフォルダを見てみるとgmail_passwd というファイルが作成されていることを確認できます。
# ls -l /etc/postfix/
total 160
-rw-r--r--. 1 root root 20876 Nov 4 2010 access
-rw-r--r--. 1 root root 11883 Apr 1 2020 canonical
-rw-r--r--. 1 root root 10106 Apr 1 2020 generic
-rw-------. 1 root root 61 Oct 3 19:15 gmail_passwd
-rw-------. 1 root root 12288 Oct 3 19:24 gmail_passwd.db
-rw-r--r--. 1 root root 21545 Sep 4 2012 header_checks
-rw-r--r--. 1 root root 27453 Oct 9 02:21 main.cf
-rw-r--r--. 1 root root 6105 Apr 1 2020 master.cf
-rw-r--r--. 1 root root 6816 Mar 27 2007 relocated
-rw-r--r--. 1 root root 12549 Nov 22 2009 transport
-rw-r--r--. 1 root root 12696 Apr 1 2020 virtual
パスワードファイルの登録
作成したパスワードファイルをPostfixの設定ファイルで指定します。
最終行に以下の設定を追加します。
sudo vi /etc/postfix/main.cf
relayhost = [smtp.gmail.com]:587
smtp_sasl_auth_enable = yes
smtp_sasl_password_maps = hash:/etc/postfix/gmail_passwd
smtp_sasl_security_options = noanonymous
smtp_sasl_tls_security_options = noanonymous
smtp_sasl_mechanism_filter = plain
smtp_use_tls = yes
設定を反映させるためにPostfixを再起動します。
# sudo systemctl reload postfix
または
# postfix reload
どちらでも再起動できるかと思います。
補足
これだけでも送信できるようになるかと思いますが、送信時に以下のような「Network is unreachable」エラーが出ることがあります。
localhost postfix/smtp[8709]: connect to alt1.gmail-smtp-in.l.google.com[2607:f8b0:4023:c0b::1a]:25: Network is unreachable
これも綺麗にしたいので、Postfixの設定ファイル内の「inet_protocols」の設定値を以下のように「ipv4」に変更しておきます。
sudo vi /etc/postfix/main.cf
#inet_protocols = all
inet_protocols = ipv4
ipv6でつなぎにいっているようで、そもそも不要のため、ipv4と指定することで回避できます。
確認
PHPプログラムで確認
テーマのゴール地点となります。
冒頭で触れたサンプルプログラムを改めて実行してみましょう。
<?php
//言語と文字コードの使用宣言
mb_language("ja");
mb_internal_encoding("UTF-8");
// 送信情報をセット
$to = "宛先のメールアドレス@example.com";
$from = "送信元アドレス@gmail.com";
$subject = "メールの送信テスト";
$message = "こちらはテストメールです";
$header = "From: " . $from;
//メール送信
mb_send_mail($to, $subject, $message, $header);
宛先のメールアドレスにメールが届けば成功です!
お疲れさまでした!
header引数について
mb_send_mailのheader引数についてです。
今回のプログラムの用途でいえば「From: 送信元アドレス@gmail.com」の形式で代入しておけば問題ありません。
$from = "送信元アドレス@gmail.com";
$header = "From: " . $from;
しかし、送信するメールがスパム判定にならないよう、しっかり指定したほうがよい場合もあるそうです。
header引数について分かりやすく書いている記事は以下サイト様でした。
補足
mailコマンドで送信テスト
ssh上からmailコマンドでメールを送信することも可能です。
Postfixの設定疎通の確認等で使えると思います。
# echo 件名 | mail -s "本文" 宛先のメールアドレス@example.com
メールコマンドがnot foundで実行できない場合は以下でインストールできます。
# sudo yum install mailx
■参考サイト
Postfixの設定ファイルやコマンド
■設定ファイルの場所
# vi /etc/postfix/main.cf
■ログの場所
# view /var/log/maillog
■Postfix再起動
# systemctl restart postfix
または
# postfix reload