Debian OSからのメール送信

Debianでは、9(stretch)あたりから、eximが標準でインストールされなくなったようです。

ログイン時にYou Have Mailという通知がくることもなくなりすっきりしたのですが、なんらかの通知メールを送信したい時にどういう構成にしたらいいか迷ったので、Debianのメール関連のパッケージについてをここにまとめておきます。

メールはなじみがありますが、あらためて理解しようとするとわりと複雑な構造になっています。

MTA

メールは MTA が運びます。

MTA はMail Transfer Agentの略で、文字通りメールを運ぶ役割を担うアプリの総称です。メールを運ぶプロトコルに SMTP があり、それに順じてメールの送信を受け付けるサーバーがSMTPサーバーと呼ばれます。それを担う代表的なアプリが postfix です。

また、かつてDebian に採用されていた exim も postfix と同様の機能を提供しますが、設定の手間や日本語資料の量からSMTPサーバーには postfix を使う人が多いのではないかと思います。筆者もこれまで exim はほぼ無視してでここまできました。

mailコマンド

また、eximが標準インストールされていた頃には mail コマンドでメールを読み書きできましたが、これらの機能は exim とは別物でした。

メールの読み書きはMUA(Mail User Agent)に分類されます。

Debianでは、mailutilsをインストールすると mailコマンドが使えるようになり、メールを読み書きできます。ただこのパッケージは、MUAを中心としたツール群でメールの送信はできません。

送信メールの受付

MTAの説明で「メールを運ぶ」としたのは、書き終えたメールを運ぼうとした時、そのメールを受け付けるというは別の機能として定義されているからです。

この機能を受け持つ部分は MSA(Mail Submission Agent)と呼ばれます。メール送信者の認証やメールの正規化等を行います。いっぽうの MTA は配送・再送の役割を担います。

postfix も exim もこの MSA の機能を持っているので分かりにくいですが、近代のメールの設計思想ではMUA、MSA、MTAの3つは分かれています。

Submission の日本語訳は「提出」で、メール設定時のサブミッションポート(587)のサブミッションです。

ちなみに、サブミッションポートで受け付けられたメールは、受け付け後は25番ポートで転送されます。

MUA に mailutils の mailを使い、MSA+MTAに postfix または exim を使うことでOSからメールの送信が可能になります。ただこれはメールを送るためにSMTPサーバーを在駐させるようなもので、オーバースペックなのでもう少しスマートな方法がないか考えます。

DovecotやMailDropって

少し話はそれますが、postfix がでてくると対になるのが Dovecot だと思います。知っての通り DovecotはPOP/IMAPサーバーです。先のMUA、MSA、MTAのうちのどれでもありません。

Dovecotは保存されたメールデータをPOP/IMAPプロトコルで提供するというかかわり方をします。クライアントがPOPやIMAPで受信したデータはクライアントのMUAで読むことができます。

あとメールの振り分けは行うので、MDA(Mail Delivery Agetnt)という肩書きがついています。ちなみにpostfixにもMDA機能はあります。

MailDrop もMDAです。現在は開発が終了している procmail もこれにあたります。これらは純粋なMDAでPOPやIMAPサーバーとしては動きません。

sendmail

exim がインストールされていない Debian では sendmailコマンドも使えないと思いますが、この位置づけも理解しにくいものです。

かつての sendmail は MSA の役割が確立していなかった頃のパッケージ名でMTAに当たります。かつては MSU は sendmail にメールを渡すことで送信を実現していました。つまり MSAを介さずにメールを送信していたということになります。

現時点の sendmailは、決まったパッケージではなく postfix や exim などが提供する互換コマンドを呼び出すためのメタコマンドとなっています。

その場合の機能の位置づけは MUA と MSA の間にある「投入口」です。

かつて sendmailでメールをおくるという構造が普及していたため、互換としてsendmailコマンドが今も存在しています。

Mutt は MUA にあたるものでメールの編集ができますが、これも通常 sendmail 経由でメールを送信します。互換sendmailでメールを送る場合 MSA は 通信先の(SMTP)サーバーとなります。

また cron がデフォルトでエラーをメール配信する際にも sendmailコマンドが使われます。

直接 MSA にデータを渡すことができる MUA なら sendmailコマンドは不要です。さきほどのMuttもそのひとつで、設定次第ではSMTPクライアントとして稼働できます。

その場合もMSAは接続先の(SMTP)サーバーとなります。

実は、sendmail の正当な後継がaptの標準レポジトリに sendmail-bin という名前で存在しています。MSAの機能を持ちMTAとしてデーモンとして在駐します。旧時代のコードをベースにしていて潜在的な脆弱性もあるので、特に意図がなければ選択しない方がいいと思います。

Debianからメールの送信

前置きがながくなりましたが、Debian OSから通知メールを投げたい時にどうすればいいかという本題に入ります。

先ほど少し書きましたように、exim や postfix をインストールすれば、sendmail が使えるようになりますので、インストールしてリレーホスト(postfixの場合)の設定をすれば、メール送信は可能です。

これらがオーバースペックであると感じる人に向けた代替案としては msmtp があげられます。

msmtp はSMTPクライアントで、デーモンとして在駐しません。また、補助パッケージが必要ですがsendmailコマンドも互換できます。

msmtp はコマンドが呼ばれた際に /etc/msmtprc か ~/.msmtprc を読み込みますのでここにメールの接続情報をそこへ記載しておきます(詳細は後述します)。

規則に則った文字列を標準入力で msmtpに渡し、引数にアドレスを渡すことでメールが送信できます。

printf "Subject: title\n\nbody\n" | msmtp user@example.net

sendmail コマンドを使いたい場合は、msmtp-mta をインストールします。これにより sendmail互換機能(sendmailコマンド)が提供されます。パッケージ名にmtaを含みますが正式には MTAではありません。

.msmtprc

msmtpの設定は、ユーザーホームの .msmtprcか /etc/msmtprc へ保存しておけます。

おおむね次のようにすることでSMTPクライアントの設定が可能です。

/etc/msmtprc

# デフォルト設定
defaults
auth           on
tls            on
tls_starttls   on
# 証明書のパス
tls_trust_file /etc/ssl/certs/ca-certificates.crt
logfile        ~/.msmtp.log

# 接続用アカウント設定
# 設定名
account        setting1
host           mailserver.com
port           587
from           [FROMメールアドレス]
user           [ユーザーアカウント]
password       [パスワード]

# デフォルトで使用するアカウントの指定
account default : setting1

msmtpでできないこと

msmtpは ユーザー名@ホスト名 のメールは送信できないので(postfixなら可能)、cronでエラートラップをする際はMAILTOでアドレスを指定しておく必要があります。

もうひとつ postfix系のメールサーバーならキュー管理ができるので、メール送信に失敗しても再送が可能ですが、msmtpを使う場合はメール送信に失敗したら、ユーザーホームに dead.letter を作成して処理が終わります。

日本語等、拡張設定

英数だけで通知だけを目的としたシンプルなメールなら、ここまでの設定で処理が可能ですが、メールのフォーマットを気にせずにメッセージを設定したかったり、日本語(MIME)に対応させたかたったり、添付ファイルを送信したかったりする場合は別途 MUAが必要です。

先ほども紹介した mailutils をインストールすると mail コマンドが利用できるようになり、これはMIMEに対応しています。送信時はに sendmailコマンドが呼ばれ先ほどの mstmp の設定で送信が可能です。

mailutils インストール時の注意ですが、msmtp とmsmtp-mta がインストールされていないと、mailutilsインストール時に依存の自動解決で postfix や exim がインストールされることがあります。

別のMIME対応の MUAに s-nail があり。こちらはそのような依存のチェーンが少ないので、こちらで紹介します。

s-nail も最終的に sendmail を呼びます。

s-nailは標準入力で本文、-s でタイトル、-a で添付ファイルを受け取ります。

詳しくはmanページを参照して欲しいと思います。

echo "資料を送ります" | s-nail -s "資料送付" -a document.pdf recipient@example.com

直接送信設定

ちなみに、mailutilsでも、s-nailでもSMTPクライアントとして、直接 MSAとやりとりすることができ、その場合は sendmail(msmtp)を介さずメール送信ができます。

s-nail で単にメールを送りたいだけなら、このあと紹介する設定を入力しておけば、msmtpも不要です。ただしその場合、sendmailの互換設定がありません。cronのエラーをメール送信したければ、自分でエラーリダイレクトから s-nailを呼ぶようにしないといけません。

ユーザーホームの .s-nailrc か /etc/s-nail.rc に設定ファイル置き次のように記述します。s-nail が呼ばれると先にこちらの設定が読み込まれ、SMTPクライアントの設定がされていたら、sendmailコマンドは使わずに直接送信という流れになります。

/etc/s-nail.rc

# v15の設定を使う明示 s-nailのバージョン14でもセット
set v15-compat

# 1. サーバー、ポート、ユーザー、パスワードを一つのURL(mta)にまとめます
# 形式: smtp://[ユーザー]:[パスワード]@[ホスト]:[ポート]
# 同ユーザー名は特殊文字が含まれたらURLエンコードが必要です。たとえば@は%40とします
# パスワードに特殊記号が含まれる場合は、URLエンコードするかダブルクォートで囲みます
set mta=smtp://[ユーザー名]:[パスワード]@mailserver.ne.jp:587

# 2. SMTP認証方式の指定
set smtp-auth=login

# 3. SSL/TLS設定
set smtp-tls-verify=strict
set smtp-tls-ca-file=/etc/ssl/certs/ca-certificates.crt

# 4. 送信元アドレス
set from="[表示名] <[メールアドレス]>"

ちなみに、URLエンコードするコマンドが s-nail にも用意されています。

この時、$が含まれる場合は、\$とシェル用にエスケープしないといけません。

$ s-nail -X "urlcodec enc &\$@" -X quit %26%24%40

参考

ちなみに、s-nail は MUA なので、メールを読むこともできます。/var/mail/ユーザー名にメールがあれば、s-nail と単体でコマンドを打つことでメールが表示されます。

-f メールDIRとすれば、メールDIR形式のファイルも読み込めます。

POSIX mailx互換でコマンドが使えます。

  • h:メールヘッダ一覧
  • 数値:指定のメールを開く
  • d:削除 -を使ってレンジ指定可能
  • u:削除取り消し
  • r:返信作成
  • q:確定終了
  • x:キャンセル終了

既読メールを読む場合は、通常ユーザーホームのmboxに移動しますので、-fコマンドで指定します。

人気の投稿