Raspberry Piで何かイベントが起きた時に外部にメールで通知できると便利ですよね。 今回は、有名なメールサーバーのPostfixをRaspberry Piへインストールし、Gmailへの中継用に使うことで、外部にメール送信してみました。
ちなみにここではGmailを使っていますが、他のメールサービスも同じように使えます。ただし、最初のセクションのGmail側の設定は不要だったり、別の方法があったりしりますので、利用したいメールサービスのマニュアルに従ってください。
Gmail側の設定
Gmailはセキュリティにとても気を使っており、Googleが定めるセキュリティ標準(OAuth2.0の使用など)を満たしたアプリ以外からのアクセスはブロックされます。Raspberry Piのような画面のないデバイスからOAuth2.0なども使わずにGmailにアクセスするには、準備が必要です。
2つの選択肢がありますので、どちらかを実行してください。
アプリパスワードを発行する
アプリパスワードを使用すると、2 段階認証プロセスに対応していないデバイス上のアプリからGoogle アカウントにログインできるようになります。アプリパスワードを利用するには、あらかじめ2段階認証を有効にしておく必要があります。以下のGoogleアカウントのページから設定できます。
Googleアカウントのページにログインしたら、メニューからセキュリティを選びます。
2段階認証を有効にしていると、アプリパスワードというメニューが見えるはずです。 2段階認証を使っていない場合は、ここから有効にできます。
アプリパスワードのメニューを開くと、このような画面が出ます。「アプリ パスワードを生成するアプリとデバイスを選択してください」のところで、それぞれ「メール」「その他」を選びます。名前の入力欄が出ますので、何かわかりやすい名前を付けてください。私はraspberrypi
としました。
生成ボタンを押すと、このように16文字のパスワードが出てきます。4文字ごとにスペースが空いていますが、空白(スペース)文字は入れずにアルファベット16文字を続けたものがパスワードになります。
このパスワードは1度しか表示されませんが、メモしたりせず、Raspberry Piに入力した後は閉じてしまいましょう。 もし忘れた場合は、発行済みパスワードを無効化して再度新しく発行し直してください。
なお、このスクリーンショットのパスワードは私が生成したものですが、既に無効になっていますのでご安心(?)ください。
生成したパスワードはこのように一覧で見られます。横のゴミ箱アイコンをクリックするとパスワードを無効化できます。
安全性の低いアプリからのアクセスを有効にする
2段階認証を有効にしていない場合、もう1つの手段として「安全性の低いアプリからのアクセスを有効にする」という方法があります。
このメニューからアクセスを有効化(非推奨)を選んで有効化できます。 これをすると、どんなアプリからも「メールアドレス」と「パスワード」でログインできるようになるのだろうと思います。 セキュリティは低下しますので、よく考えて行ってください。
Postfixのインストール・設定
インストール
まずはメールサーバーのPostfixをインストールします。
Gmailの場合送信にTLSを使うためlibsasl2-modules
も必要なようです。
$ sudo apt install postfix libsasl2-modules
Postfixの設定
Postfixの設定ファイルは/etc/postfix/main.cf
です。このファイルをvimなどで編集します。
まず、外部からのメール中継要求を受け付けないようにします。
inet_interfaces = loopback-only # 変更
続いて、Gmailを中継サーバーに設定します。Gmailのメール送信サーバーはsmtp.gmail.com
の587番ポートです。
relayhost = [smtp.gmail.com]:587 # 変更
続いて、SMTP認証やTLSに関する設定をします。ファイルの末尾に次の設定を追加します。
# 追加 smtp_sasl_auth_enable = yes smtp_tls_security_level = encrypt smtp_sasl_security_options = noanonymous smtp_sasl_password_maps = hash:/etc/postfix/sasl/sasl_passwd smtp_tls_CAfile = /etc/ssl/certs/ca-certificates.crt
これでこのファイルを保存します。
Gmail認証の設定
Gmailにメール送信してもらうには、アカウント情報が必要です。
/etc/postfix/sasl/sasl_passwd
というファイルを新規作成し、アカウント情報を書き込みます。
メールアドレスがexample@gmail.com
、パスワードがpassword
の場合の例はこのようになります。
[smtp.gmail.com]:587 example@gmail.com:password
このファイルはこの1行だけでOKです。
アプリパスワードを発行した場合はアプリパスワードを、そうでない場合(安全性の低いアプリからのアクセスを有効にした場合)はGmailアカウントのパスワードを記入してください。
パスワードを平文で書くことになるので、流出には十分注意してください。
ファイルを保存したら、これをPostfixが扱える形式に変換します。postmap
というコマンドを使います。
$ sudo postmap /etc/postfix/sasl/sasl_passwd $ sudo rm /etc/postfix/sasl/sasl_passwd
1行目を実行すると、/etc/postfix/sasl/sasl_passwd.db
というファイルができます。
元ファイルは不要なので、2行目で削除します。
ちなみにこのdbファイルは暗号化されているわけではありませんので、流出には十分注意してください。
設定を反映
以上で設定は終わりです。Postfixを再起動して設定を反映します。
$ sudo systemctl restart postfix
動作確認
コマンドライン編
Postfixにはsendmail
というコマンドが付属しており、メールの送信ができます。
昔デファクトスタンダードだったメールサーバーsendmailのコマンドと互換になっているそうです。
$ sendmail example@gmail.com Subject: This is a test mail Hello from Raspberry Pi .
あて先メールアドレスをsendmail
コマンドの引数にして起動します。
起動すると何もメッセージも出ず入力待ちになるので、1行目にSubject:
と書いてからメールのタイトルを、2行目以降にメールの本文を書きます。書き終わったら次の行に.
(ピリオド)のみ書いてEnterを押します。最後のピリオドは送信されませんのでご安心ください。
うまくメールが届きましたでしょうか?届かなかった場合は後述のトラブルシューティングを見てくださいね。
Python編
Pythonに標準で付属しているsmtplib
を使ってメール送信ができます。次のようにします。
import smtplib fromaddr = "from@gmail.com" toaddr = "to@gmail.com" subject = "This is a test mail" body = """\ Hello from Raspberry Pi! This is a test mail. """ server = smtplib.SMTP('localhost') msg = "Subject: {}\n{}".format(subject, body) server.sendmail(fromaddr, toaddr, msg) server.quit()
これをmailtest.py
などとファイルに保存して、実行します。
$ python mailtest.py
同じように送信できるはずです。
トラブルシューティング
実は私は上の手順ではメール送信ができませんでした。メールが送れないな?と思ったら、ログを見てみましょう。
デフォルトでは/var/log/syslog
にログが書かれています。postfixで検索するとよいでしょう。
Network is unreachable
私の場合、こんなログが出ていました。
Sep 2 11:29:54 raspberrypi postfix/smtp[1620]: connect to smtp.gmail.com[2404:6800:4008:c04::6d]:587: Network is unreachable
smtp.gmail.comに繋がらない(Network is unreachable)というログです。 よく見ると、アドレスがIPv6アドレスです。実は私の家のインターネット回線は未だにIPv6に対応していないので、これでは繋がりません。
このような場合は、強制的にIPv4を使います。Postfixの設定ファイル/etc/postfix/main.cf
の、次の行を変更します。
inet_protocols = ipv4 # 変更
これでPostfixを再起動すると、IPv4が使われて、メールが送れるようになりました。
このように、環境依存のエラーが出る場合があります。エラーログを見て検索するなどして問題を解決し、メールが送れるようにがんばってください!