Termuxからメールを送れるようにするには?

じゃんくはっく
じゃんくはっく

コマンドラインからメールを送れるようにしたいね!

え?メール送れないの?

ぴー
ぴー
じゃんくはっく
じゃんくはっく

今のところはね。よさげなアプリを物色中〜!

てか、最近Lineばっかりでメールあんまりしてないな。

ぴー
ぴー

さて、今回はメールを取り扱います。ですが、別にメールサーバを作るわけではないです。やりたい事は、こんな感じ。

・コマンドラインからメールを送れるようにしたい
・WordPressのプラグインからメールを送れるにしたい
・Cronとかの結果をメールできるようにしたい
・配送先はgmail!

Termux環境でお手軽にメールを送るには?

メールを取り扱うってことは、いろいろ用意する必要がありますが、今回はメールを他のサーバに送るだけです。Termuxでメールを受信したり、imapのメールを読み書きして送受信したり、あるいは他のサーバからリレーしたりということは今回はしません。内部配送もtermux は1ユーザしかいないのでしません。このあたり、MTAとかMUAとかMDAとか用語がありますが、興味のあるかたはここがわかりやすいです。

メール転送エージェント (MTA)

https://wa3.i-3-i.info/word11120.html

そんなこたぁーわかっとる! っていうベテランも改めてどうぞw

メール設定で最初につまずく『SMTP』『POP』『IMAP』 その意味&設定方法は?

https://time-space.kddi.com/ict-keywords/kaisetsu/20170824/2081

つまりは、SMTPクライアントだけあればいいんです。

お手軽なSMTPクライアント!msmtp

一般的なLinuxなら、postfixとかsendmailとかありますよね。でもTermuxのバイナリにはありません。でも、SMTPクライアントならあります。

msmtp

https://marlam.de/msmtp/

これ、実は今まで知りませんでした! 一応、メールサーバ関連はsendmailや、qmailや、postfixはさわった事があるのですが msmtpってのは取り扱う機会もなくて、こんなのがあったのかという印象です。機能は、こんな感じ!

  • Sendmail互換インターフェイス(コマンドラインオプションと終了コード)
  • 複数のアカウントのサポート
  • クライアント証明書を含むTLS / SSLサポート
  • 国際化ドメイン名(IDN)のサポート
  • 多くの認証方法
  • コマンドパイプラインを使用した高速SMTP実装
  • DSN(配信ステータス通知)のサポート
  • SOCKSプロキシサポート

ステップ1 とにかく入れてみる!

まずは、使ってみましょう。インストールは簡単です。

$ pkg install msmtp

このあたりに入るようです。

$ find $PREFIX -name *msmtp*
/data/data/com.termux/files/usr/bin/msmtpd
/data/data/com.termux/files/usr/bin/msmtp
/data/data/com.termux/files/usr/var/lib/dpkg/info/msmtp.list
/data/data/com.termux/files/usr/var/lib/dpkg/info/msmtp.md5sums
/data/data/com.termux/files/usr/share/doc/msmtp
/data/data/com.termux/files/usr/share/info/msmtp.info
/data/data/com.termux/files/usr/share/man/man1/msmtp.1.gz
/data/data/com.termux/files/usr/share/man/man1/msmtpd.1.gz

ステップ2 設定

ここの説明がわかりやすかったです。参考にしました。

msmtp – ArchWiki

https://wiki.archlinux.jp/index.php/Msmtp

つまりは、以下の設定ファイルを書けばOKです。システム全体は etc 配下に書きますが、今回はホームディレクトリ直下です。gmailのsmtpを使います。

~/.msmtprc
------------------
# Set default values for all following accounts.
defaults
auth           on
tls            on
tls_trust_file /data/data/com.termux/files/usr/etc/tls/cert.pem
logfile        ~/.msmtp.log

# Gmail
account        gmail
host           smtp.gmail.com
port           587
from           username@gmail.com
user           username
password       plain-text-password

# Set a default account
account default : gmail

デフォルトのCA証明書は、opensslがどっかに持っていると思い、どこにあるかわからなかったので以下のように調べました。直接ダウンロードしてどこかに保存しておいても良いのですが。

$ which openssl
/data/data/com.termux/files/usr/bin/openssl
$ ldd /data/data/com.termux/files/usr/bin/openssl
libssl.so.1.1
libcrypto.so.1.1
libc.so

$ find $PREFIX -name libcrypto.so
/data/data/com.termux/files/usr/lib/libcrypto.so
$ ls -l /data/data/com.termux/files/usr/lib/libcrypto.so
lrwxrwxrwx 1 u0_a364 u0_a364 18 Sep 30 05:12 /data/data/com.termux/files/usr/lib/libcrypto.so -> libcrypto.so.1.1

$ cd $PREFIX/lib
$ strings libssl.so | grep -P '^/\w+/'
/data/data/com.termux/files/usr/lib

$ strings libcrypto.so | grep -P '^/\w+/'
/data/data/com.termux/files/usr/lib
/data/data/com.termux/files/usr/etc/tls/ct_log_list.cnf
/data/data/com.termux/files/usr/lib/engines-1.1
/dev/urandom
/dev/random
/dev/hwrng
/dev/srandom
/dev/tty
/data/data/com.termux/files/usr/etc/tls/private
/data/data/com.termux/files/usr/etc/tls
/data/data/com.termux/files/usr/etc/tls/certs
/data/data/com.termux/files/usr/etc/tls/cert.pem

$ tree -N /data/data/com.termux/files/usr/etc/tls
/data/data/com.termux/files/usr/etc/tls
 ├── cert.pem
 └── openssl.cnf

今回必須ではないですが、このサーバのIPをSPFテキストレコードに追加しておきました。MTAをビルドしてテストするかもしれません。この機会に書いておきます。

$ dig -t txt gpl.jp
::
;; ANSWER SECTION:
gpl.jp.			3599	IN	TXT	"v=spf1 +ip4:124.41.83.243 +ip4:106.185.159.254 +ip4:116.58.181.140 +a:www.gpl.jp +a:mail.gpl.jp include:aspmx.googlemail.com include:_spf.google.com ~all"

ステップ3 送信テスト

とりあえず、送信テストです。

$ msmtp -t
To: who@example.jp
Subject: Hello World.

Hi.
これはテストメールです。

認証でエラーが出る場合は、Gmailの以下を確認してみてください。

安全性の低いアプリのアクセス

https://myaccount.google.com/lesssecureapps

これをOnにすれば、認証に通りメール送信できます。ちゃんと届いていました!gmailはUTF-8でも文字化けしませんね。

SPFもパスしていて、問題ないようでした。

DKIMは、googleのやつです。

ステップ4 コマンドラインでメール!

当初やりたかったことの1つです。コマンドラインの結果などをメールしたかったんです。例えば、lsの結果をメールしておきたい場合とか、

$ ls -l /system/etc | msmtp junkhack@gpl.jp

topの結果を送っておきたいとか、

$ top -b -d 1 -n 30 | msmtp junkhack@gpl.jp

なにかの設定ファイルを送っておきたいとか、

$ cat php-fpm.conf | msmtp junkhack@gpl.jp

こんな感じです。題名のないメールですが送れます。同じようにcrontab にもパイプしておけばメールが飛んできます。cronをシステムワイドに設定する方法は詳細を省きますが、いろいろ試してうまく行きませんでした。

ステップ5 PHP でメールを送信

自作のメールフォームを作ることはないかもしれませんが、PHPの設定をしておくと何かと便利かなと。php.ini に以下を記載。termux のphp.ini は自分で作成です。

パスは、/data/data/com.termux/files/usr/lib/php.ini

[mail function]
sendmail_path = "/data/data/com.termux/files/usr/bin/msmtp -C /data/data/com.termux/files/home/.msmtprc -t"

php-fpm を再起動して、テスト用のphpで確認しておきます。

<?php
     mail("hoge@example.jp", "Test email from PHP", "msmtp as sendmail for PHP");
?>

ブラウザーから、このPHPを叩くとメールが送られるはずです。届いたメールヘッダーは、SPFもDKIMもPASSです。

他、以下のサンプルコード(mb_send_mail関数)とかも問題なく動作します。

誰でも実装できる!PHPでメール送信を行う方法【初心者向け】

https://techacademy.jp/magazine/11629

ステップ6 WordPress でメールを送信

WordPressのプラグインからメールするっていうことはPHPの設定をそのまま引き継ぐと思っていたのですが、実際にやってみるとWordPressは、PHPMailerを使って、直接MXへ配送しているようです。

PHPMailer 6.1.6 (https://github.com/PHPMailer/PHPMailer) 

なので、php.ini のsendmail_pathを使った配送にはならないのがデフォルトの挙動のようです。ヘッダーには、SPFもDKIMもありません。これだと、迷惑メールフォルダに分類されてしまいます。

なので、WP Mail SMTPプラグインを使った方法でやっておきます。これは、SMTPクライアントの機能を持っています。つまりは、msmtpと同じようなことができます。この辺りはいくらでも情報があるので省略です。

まとめ

今回、なんとなくわかったのは以下となります。

・msmtpは、お手軽でスマホで作るサーバにはぴったりのSMTPクライアント
・gmailにTLSで送れる
・コマンドラインからパイプでメールが送れるようになった
・cron にも、パイプしておけばメールは飛んでくる
・php.ini のsendmail_path にmsmtpを指定しておけばPHPプログラムのmail関数から配送可能
・しかし、WordPressは、PHPMailerを使って直接MXへ配送しているようだ
・なので、とりあえずWP Mail SMTPプラグインを使う
・直接、WordPressからphp.ini のsendmail_path に配送するにはどうしたらいいだろう?
・機会があれば、wp_mail()を上書きするプラグインを作ってみる

あとがき

とりあえず、やりたいことはほぼ満たせました。msmtpは、スマホで動作するTermux環境にぴったりですね。ただ、配送に失敗した場合などキューにたまらない設計だと思いますので、そのあたりいろいろ考えると面倒です。が、今回は割り切って使うことにします。

著者にメッセージ

コメントじゃなくて、個人的にやりとりしたい場合はこちらからどうぞ。お返事が遅くなるときもありますが、ご了承を。

間違いのご指摘など、コメントじゃなくて、個人的にやりとりしたい場合はこちらからどうぞ。お返事が遅くなるときもありますが、ご了承を。