sSMTP から msmtp へ
現在メールを受け取らずメールを送信するだけのホストではsSMTPをよく使っています.MTAはeximやPostfix等でも良いのですが,デーモンが起動しないのでその分セキュアで設定も楽です.
しかし,sSMTPは最近メンテされていません,Debian などのディストリビューションではまだメンテナンスされていますが新機能が入ったりはしないでしょう.
ssmtp is unmaintained. Consider using something like msmtp instead.
$ w3m -dump https://packages.qa.debian.org/s/ssmtp.html|grep versions -A11 versions ... ...pool o-o-stable save 2.64-7 oldstable save 2.64-8 stable save 2.64-8 unstable save 2.64-8 Ubuntu 2.64-8ubuntu2 $ apt show ssmtp 2>/dev/null |grep Homepage Homepage: http://packages.qa.debian.org/s/ssmtp.html
そこで,alternativeto.net で挙げられている msmtp を試してみました.
以下では色々試していますが,システムメールを送るだけなら msmtp
, msmtp-mta
pkg を導入,/etc/msmtprc
の設定だけでokです.
msmtp の導入
Debian sid/Ubuntu 18.04 LTS などではパッケージがあったのでこれを導入しました.
$ sudo apt install msmtp
mstpの設定
設定例が /usr/share/doc/msmtp/examples/
以下にあるので
システム設定の場合は msmtprc-system.example
を `/etc/msmtprc
にcpして設定.
ユーザ設定の場合は msmtprc-user.example
を ~/.msmtprc
にcpして設定する.
システムでの設定例
以下の例では root が読み書きできて,一般ユーザのmatokenアカウントは読み込みが可能な設定ファイル /etc/msmtprc
を作成している.
defaults セクションに共通設定を書き,account セクションにメールサーバ固有の設定を書く.account セクションは複数書けて,account default
に規定account を指定する.以下の例ではgmail が規定値となる.
$ sudo install /dev/null /etc/msmtprc -o root -g root -m 600 $ sudo setfacl -m u:matoken:r /etc/msmtprc $ getfacl /etc/msmtprc getfacl: Removing leading '/' from absolute path names # file: etc/msmtprc # owner: root # group: root user::rw- user:matoken:r-- group::--- mask::r-- other::--- $ sudo vi /etc/msmtprc $ sudo grep -v ^# /etc/msmtprc defaults syslog on aliases /etc/aliases tls on tls_trust_file /etc/ssl/certs/ca-certificates.crt auth on syslog LOG_MAIL account gmail host smtp.gmail.com port 587 from example@gmail.com user example password porseypacdoadwif account default : gmail
※gmailの多要素認証を利用している場合は以下からアプリパスワードを生成する.(使い回しができちゃうけれど流出したときの影響を考えて設定毎に発行する)
ユーザでの設定
ユーザの設定ファイルは`~/.msmtprc` 若しくは $XDG_CONFIG_HOME/msmtp/config
でシステムと違い,alias file と log を適当なファイルにした.
アカウントも増やしてみた.
gmailのアプリパスワードも新たに発行した.
$ install /dev/null ~/.msmtprc -o matoken -g matoken -m 600 $ vi ~/.msmtprc $ grep -v ^# ~/.msmtprc defaults logfile ~/.msmtp.log aliases ~/.msmtp.aliases tls on tls_trust_file /etc/ssl/certs/ca-certificates.crt auth on syslog LOG_MAIL account gmail host smtp.gmail.com port 587 from example@gmail.com user example password igeinleedafchygy account yandex tls_starttls off host smtp.yandex.com port 465 from example@yandex.com user example password throjfeekdewxeib account nifty tls_starttls off host smtp.nifty.com port 465 from example@nifty.com user aaa99999 password 9Z#9999X account default : gmail
送信テスト
msmtp コマンドで送信テストが出来る.
-a
オプションでアカウントが指定できる.
-C
オプションで設定ファイルが指定できる.(システムとユーザの設定を両方テストする)
$ echo "hello system msmtp" | msmtp -C /etc/msmtprc matohara@gmail.com $ echo "hello user msmtp" | msmtp -C ~/.msmtprc -a gmail matohara@gmail.com
大抵のMTAでは .
でmail body 終了となるが,msmtpでは`.`は普通にbody に含まれる.Ctrl + d で終了.
$ msmtp -a gmail matohara@gmail.com Subject: hello msmtp test . dot では終了にならない Ctrl+d で終了 ^d
aliases file
msmtp設定ファイルの alias で設定できる.
$ grep alias ~/.msmtprc aliases ~/.msmtp.alias $ sudo grep alias /etc/msmtprc aliases /etc/aliases
このalias fileは通常のaliases ファイルと同じ形式の plain text で newaliases コマンドでの変換は不要.
メールアドレスは複数指定できる.default
という名前は規定アドレスとなる.
root: hoge@example.com, fuga@example.com default: piyo@example.com
以前のaliases ファイルを流用して以下のようにしてみたところ,
# /etc/aliases mailer-daemon: postmaster postmaster: root nobody: root hostmaster: root usenet: root news: root webmaster: root www: root ftp: root abuse: root noc: root security: root root: matohara@gmail.com default: matohara@gmail.com
以下のようにエラーとなった.alias先はユーザ名ではエラーとなるよう.
$ echo hello | sudo msmtp -C /etc/msmtprc root msmtp: /etc/aliases: line 2: invalid address 'postmaster'
以下のようにそれぞれにメールアドレスを指定すると期待した動作となった.
$ sudo sed -i -e 's/ root$\| postmaster$/matohara@gmail.com/' /etc/aliases $ cat /etc/aliases # /etc/aliases mailer-daemon:matohara@gmail.com postmaster:matohara@gmail.com nobody:matohara@gmail.com hostmaster:matohara@gmail.com usenet:matohara@gmail.com news:matohara@gmail.com webmaster:matohara@gmail.com www:matohara@gmail.com ftp:matohara@gmail.com abuse:matohara@gmail.com noc:matohara@gmail.com security:matohara@gmail.com root: matohara@gmail.com default: matohara@gmail.com
パスワードをGnuPG暗号化ファイルに格納して利用する
パスワードをgpgで暗号化したファイルに格納することが可能.この場合アカウントごとにファイルが必要なのが少し面倒.
password porseypacdoadwif
の場合 porseypacdoadwif
部分だけを暗号化してファイルに格納する.(はじめpassword も含めてしまい失敗した)
$ grep ^password\ ~/.msmtprc | head -1 | awk {'print $2'} | gpg2 --default-recipient-self -e - > ~/.msmtp-password-gmail.gpg $ grep ^password\ ~/.msmtprc | head -2 | tail -1 | awk {'print $2'} | gpg2 --default-recipient-self -e - > ~/.msmtp-password-yandex.gpg $ grep ^password\ ~/.msmtprc | tail -1 | awk {'print $2'} | gpg2 --default-recipient-self -e - > ~/.msmtp-password-nifty.gpg
msmtprc の password
を削除して,代わりに passwordeval gpg2 --no-tty -q -d 暗号ファイル
と設定を変更する.
$ grep ^passworde ~/.msmtprc passwordeval gpg2 --no-tty -q -d ~/.msmtp-password-gmail.gpg passwordeval gpg2 --no-tty -q -d ~/.msmtp-password-yandex.gpg passwordeval gpg2 --no-tty -q -d ~/.msmtp-password-nifty.gpg
後はこれまでのようにmsmtpを呼ぶとgpg-agentが起動する.
※システム側はシステムメールが送れなくなるのでこの設定をしないほうがいいと思う.
パスワードをopenssl暗号化ファイルに格納
システムメールでgpg agentを利用するのは多分無理なのでopensslで暗号化してみる.パスワードはNICのmac addressにしてある.気休めレベルだけど試しに設定.
マシンが乗っ取られた場合はどうしようもないけれど /etc/msmtprc, /etc/msmtp-password ファイル流出時の時間稼ぎくらいにはなる?
NIC が使っていないものも含め増減したり変更になった場合は復元できなくなるので注意.
$ umask 0077; grep ^password\ /etc/msmtprc | head -1 | awk {'print $2'} | sudo openssl enc -e -md sha256 -aes-256-cbc -a -A -salt -pbkdf2 -in /dev/stdin -out /etc/msmtp-password -pass pass:`hwinfo --network | grep 'Permanent HW Address' | sed 's/^.*: //' | sort -n | tr -d '\n'`
$ sudo openssl enc -d -md sha256 -aes-256-cbc -a -A -salt -pbkdf2 -in /etc/msmtp-password -pass pass:`hwinfo --network | grep 'Permanent HW Address' | sed 's/^.*: //' | sort -n | tr -d '\n'` igeinleedafchygy
$ grep passworde /etc/msmtprc passwordeval openssl enc -d -md sha256 -aes-256-cbc -a -A -salt -pbkdf2 -in /etc/msmtp-password -pass pass:`hwinfo --network | grep 'Permanent HW Address' | sed 's/^.*: //' | sort -n | tr -d '\n'`
※ifconfigやiproute2を使わずhwinfoを使ってPermanent HW Addressを使っているのはmac address偽装対策
MTA パッケージの導入
msmtp コマンドでメールが送信できるようになったら,msmtp-mta
pkg を導入する.これでsendmailコマンドにシンボリックリンクが張られて同様に利用できるようになる.システムメールも飛ぶようになる.
$ sudo apt install msmtp-mta $ ls -l /usr/sbin/sendmail lrwxrwxrwx 1 root root 12 11月 29 2016 /usr/sbin/sendmail -> ../bin/msmtp
オフライン時にmsmtpを利用する
msmtpはオフライン時に実行するとエラーとなる.通常は常にオンラインなので問題はないが,持ち運びNotePCなどではオフラインオンラインが発生してメールの送信に失敗することがある.
$ echo 'hoge' | msmtp -a gmail matoken@gmail.com msmtp: cannot locate host smtp.gmail.com: 名前またはサービスが不明です msmtp: could not send mail (account gmail from /etc/msmtprc)
/usr/share/doc/msmtp/examples/
以下の msmtpq
若しくは msmtpqueue
に格納されているscriptを利用することでオフライン時にキューとして貯めておいてオンライン時に送信といったことが出来る.
どちらもsendmailと置き換えが可能なので,ネットワークダウン時に`/usr/sbin/sendmail`をこれに置き換えてオンライン時に戻してqueueをフラッシュするようにするといいかもしれない.
Debian/Ubuntuなら以下のあたりで,
-
/etc/network/if-down.d/
/usr/sbin/sendmail を msmtpq or msmtpqueue に向ける -
/etc/network/if-pre-up.d/
/usr/sbin/sendmail を msmtp に向ける -
/etc/network/if-up.d/
queueをフラッシュ
NetworkManagerだと /etc/NetworkManager/dispatcher.d/
以下で同じことが出来る.
msmtpq
$ sudo gunzip /usr/share/doc/msmtp/examples/msmtpq/msmtpq.gz $ sudo chmod 755 /usr/share/doc/msmtp/examples/msmtpq/msmtpq
$ sudo ln -s /usr/share/doc/msmtp/examples/msmtpq/msmtpq /usr/local/bin/msmtpq $ sudo ln -s /usr/share/doc/msmtp/examples/msmtpq/msmtp-queue /usr/local/bin/msmtp-queue
$ install -d -m 700 ~/.msmtp.queue $ install -d -m 700 ~/log
$ echo 'msmtpq' | msmtpq -C ~/.msmtprc -a gmail matoken@gmail.com mail for [ -C /home/matoken/.msmtprc -a gmail matoken@gmail.com ] : couldn't be sent - host not connected enqueued mail as : [ 2018-09-18-06.21.48 ] ( -C /home/matoken/.msmtprc -a gmail matoken@gmail.com ) : successful
$ msmtp-queue -d mail num=[ 1 ] id=[ 2018-09-18-06.21.18 ] mail num=[ 2 ] id=[ 2018-09-18-06.21.48 ]
$ msmtp-queue -r mail [ 1 ] [ 2018-09-18-06.21.18 ] from queue ; send was successful ; purged from queue mail [ 2 ] [ 2018-09-18-06.21.48 ] from queue ; send was successful ; purged from queue $ msmtp-queue -d no mail in queue
msmtpqueue
$ sudo ln -s /usr/share/doc/msmtp/examples/msmtpqueue/msmtp-enqueue.sh /usr/local/bin/msmtp-enqueue.sh $ sudo ln -s /usr/share/doc/msmtp/examples/msmtpqueue/msmtp-listqueue.sh /usr/local/bin/msmtp-listqueue.sh ~$ sudo ln -s /usr/share/doc/msmtp/examples/msmtpqueue/msmtp-runqueue.sh /usr/local/bin/msmtp-runqueue.sh
$ echo 'queue' | msmtp-enqueue.sh -C ~/.msmtprc -a gmail matoken@gmail.com
$ msmtp-listqueue.sh No mail in queue
egrep -s --colour -h '(^From:|^To:|^Subject:)' "$i" || echo "No mail in queue";
$ ls -lA ~/.msmtpqueue/ 合計 8 -rw------- 1 matoken matoken 7 9月 18 00:15 2018-09-18-00.15.53.mail -rw------- 1 matoken matoken 53 9月 18 00:15 2018-09-18-00.15.53.msmtp
$ msmtp-listqueue.sh No mail in queue Subject: offline><
$ msmtp-runqueue.sh *** Sending 2018-09-18-00.15.53.mail to -C /home/matoken/.msmtprc -a gmail matoken@gmail.com ... 2018-09-18-00.15.53.mail sent successfully *** Sending 2018-09-18-00.27.21.mail to -C /home/matoken/.msmtprc -a gmail matoken@gmail.com ... 2018-09-18-00.27.21.mail sent successfully
#sudoの場合も ~root/.msmtpqueue/ だった.
tips
$ echo "hello msmtp" | sudo msmtp -a gmail matohara@gmail.com msmtp: envelope from address matohara@gmail.com not accepted by the server msmtp: server message: 530 5.7.0 Must issue a STARTTLS command first. k126-v6sm14991126pgk.26 - gsmtp msmtp: could not send mail (account gmail from /etc/msmtprc)
msmtp: network read error: 接続が相手からリセットされました msmtp: could not send mail (account nifty from /etc/msmtprc)
試した環境
$ dpkg-query -W msmtp msmtp-mta gnupg2 openssl gnupg2 2.1.18-8~deb9u2 msmtp 1.6.6-1 msmtp-mta 1.6.6-1 openssl 1.1.0f-3+deb9u2 $ lsb_release -d Description: Raspbian GNU/Linux 9.4 (stretch) $ uname -m armv7l
$ dpkg-query -W msmtp msmtp-mta gnupg2 openssl gnupg2 2.2.4-1ubuntu1.1 msmtp 1.6.6-1 msmtp-mta 1.6.6-1 openssl 1.1.0g-2ubuntu4.1 $ lsb_release -d Description: Ubuntu 18.04.1 LTS $ uname -m x86_64
$ dpkg-query -W msmtp msmtp-mta gnupg2 openssl gnupg2 2.2.10-1 msmtp 1.6.7-1 msmtp-mta openssl 1.1.1-1 $ lsb_release -d Description: Debian GNU/Linux unstable (sid) $ uname -m x86_64