Oracle Cloud上のOralce Linux 8インスタンスでは、postfixやsendmailではなく、esmtpがインストールされている。
esmtpはRHEL8やCentOS8でも用意されているが、実際に使用している情報があまりない。
esmtp公式ページを見ると「THIS PROJECT IS NO LONGER BEING MAINTAINED. IF IT DOESN’T WORK FOR YOU SEE THESE LINKS.」と書いてあり、本来は利用推奨ではないようだ。
ざっと見たところ日本語情報としてまとまっているのは2010年に書かれた 本を読む の「軽量MTA「esmtp」を試してみた」だった。
esmtpはデーモンではなく、ポート25での待受もせず、/usr/lib/sendmailや/usr/bin/mail を実行する形でのメール送信が実行できるようにするためのソフトウェアです。
ローカルのUNIXユーザ宛にメールを届けたい場合は別途 procmailパッケージをインストールする必要があります。
他のサーバ宛にメールを送りたい場合は、外部のSMTPサーバのアカウント情報を登録し、SMTP AUTHを利用したメール送信が可能です。
難点は、メール送信に関するログがどこにも保存されない、ということ。
設定に失敗してメールが送信できなかった場合でもどう調べればいいのか分からない、という問題点も・・・
また、SMTP AUTHに使うパスワードを平文で設定ファイルに書く必要があるというのも、なかなかな問題点です。
とはいえ、期待通りに動けば簡単に外部SMTPを使用してメール送信ができるし、各サーバに同じ設定を入れておくとシステム系メールの送信元メールアドレスを全て同じにする、ということも容易な感じです。
設定
esmtpの設定は、システム全体に適用される /etc/esmtprc と、各UNIXユーザごとの~/.esmtprc で行います。
とりあえずシステム系メールを送りたいだけであれば /etc/esmtprc を設定しておけばいい感じです。
/etc/esmtprc は用意されていないので /usr/share/doc/esmtp/sample.esmtprc にあるサンプルをコピーして使うか、必要なものだけを書きます。
sample.esmtprcの内容
# Sample configuration file for ESMTP.
#
# Jose Fonseca
# Set SMTP host and service (port)
#
hostname = localhost:25
# Set the user name
#
username = "USERNAME"
# Set the password
password = "PASSWORD"
# Use the Starttls
#
#starttls = disabled
#
# It can be one of "enabled", "disabled" or "required". It defaults to
# disabled.
# Set the certificate passphrase
#
#certificate_passphrase = "CERTIFICATE_PASSPHRASE"
# Command to run before contacting the SMTP server
#
#preconnect = "ssh -f -L 2025:mail.isp.com:25 user@shell.isp.com 'sleep 5'"
# Same as above but for a different identity which can be selected with the
# '-f' flag. You can have as many you like.
#
identity = myself@somewhere.com
hostname = smtp.somewhere.com:25
username = "myself"
password = "secret"
#starttls = disabled
#
# NOTE: the default indentity settings aren't shared by the other identities.
# Everything (username, password, etc.) must be specified for every identity
# even if they don't differ from the default identity.
# Set the Mail Delivery Agent (MDA)
#
mda = "/usr/bin/procmail -d %T"
#
# Some possible MDAs are "/usr/bin/procmail -d %T", "/usr/bin/deliver" or
# "/usr/lib/mail.local %T".
これを使ってもいいのですが、必要なものだけを書いた方が簡単ですね。
外部のSMTPサーバを使って送信する設定例
Net@ddressというかれこれ20年以上使っているメールサービスのアカウントを使用してメール送信する設定です。
hostname=smtp.postoffice.net:25
username="ユーザ名@usa.net"
password="パスワード"
mda "/usr/bin/procmail -d %T"
これを /etc/esmtprc に書いたサーバから mailコマンドを使って送信したメールは全て「ユーザ名@usa.net」が発信元となって送られることになります。
また、「mda “/usr/bin/procmail -d %T”」という設定を入れているので、ローカルユーザ宛のメールであれば /var/spool/mail/ に配送されるようにしています。
SMTP送信時にstarttlsが必要な場合は「starttls=enabled」を追加すればいいようなのですが、下記の手順でやったのですが、送信されませんでした。
$ mkdir ~/.authenticate
$ chmod 0700 ~/.authenticate
$ wget http://curl.haxx.se/ca/cacert.pem
$ mv cacert.pem ~/.authenticate/ca.pem
$ chmod 0600 ~/.authenticate/ca.pem
$ mailx メール送り先@ドメイン名
Subject: test mail 5
test mail 5
.
EOT
$ 0 (null)
メール送り先@ドメイン名: 0 (null)
0 (null)
メール送り先@ドメイン名: 0 (null)
メール送り先@ドメイン名: 0 (null)
procmail: Unknown user "-r"
0 (null)
メール送り先@ドメイン名: 0 (null)
メール送り先@ドメイン名: 0 (null)
procmail: Unknown user "-r"
とりあえずstarttls対応は保留ですね。
なお、 /etc/esmtprcでは、下記の様な書式を使うこともできます。
identity ユーザ名@usa.net
hostname smtp.postoffice.net:25
username "ユーザ名@usa.net"
password "パスワード"
default
mda "/usr/bin/procmail -d %T"
ユーザによってアカウントを変える場合はこれを使うようです。
2021/07/02追記
さて、Oracle Linux 7環境でesmtpを設定してみたところ、cronで送られてくるメールが送信できていないようだ。
/etc/cron.daily/0logwatch:
You have old files in your logwatch tmpdir (/var/cache/logwatch):
logwatch.idrC25J0
logwatch.Hb7DUNNO
The directories listed above were most likely created by a
logwatch run that failed to complete successfully. If so, you
may delete these directories.
/bin/mktemp: failed to create directory via template '/root/.esmtp_queue/XXXXXXX
X': Permission denied
unable to create tempdir inside /root/.esmtp_queue
/etc/cron.daily/0yum-daily.cron:
root宛に上記のような一時ファイルが作れないというエラーメールが届いていた。
/var/log/audit/audit.log 内を esmtp で検索してみると、下記の様にSELinuxの権限問題で書き込みが阻止されていた。
# grep esmt /var/log/audit/audit.log
type=AVC msg=audit(1623953887.619:18168): avc: denied { write } for pid=23636 comm="mktemp" name=".esmtp_queue" dev="sda3" ino=2567447 scontext=system_u:system_r:logwatch_t:s0-s0:c0.c1023 tcontext=unconfined_u:object_r:mail_home_rw_t:s0 tclass=dir permissive=0
#
/root/.esmtp_queue のSELinuxコンテキストを確認すると、mail_home_rw_tとなっている。要求はlogwatch
# ls -ldZ /root/.esmtp_queue
drwxr-xr-x. root root unconfined_u:object_r:mail_home_rw_t:s0 /root/.esmtp_queue
#
関係しそうな事例を発見
「Bug 1366173 – /root/.esmtp_queue has bad context when created from a cron job」
「Bug 1592083 – SELinux is preventing touch from ‘create’ accesses on the archivo mail.」
「Bug 1295923 – SELinux is preventing sendmail from ‘read’ accesses on the directory .esmtp_queue.」
「Bug 1303305 – errors from esmtp in /var/log/messages every time my cron job runs」
「Bug 1149164 – SELinux is preventing esmtp from ‘read’ accesses on the file /.esmtp_queue/4PVJsKZY/mail.」
ただ、上記は調査方法や解決方法に関して直接の記載がない。
また、Bug 1303305 には、esmtpはローカル配送にのみ使え、なんて書かれている。
Fedora MaillingList「Trying to use mailx for logwatch」に確認してくヒントがあった。
まず、「logwatch_t」で設定されている内容の確認してみる
# sesearch -T -s logwatch_t
Found 12 semantic te rules:
type_transition logwatch_t postfix_postdrop_t : process logwatch_mail_t;
type_transition logwatch_t abrt_helper_exec_t : process abrt_helper_t;
type_transition logwatch_t ntpd_exec_t : process ntpd_t;
type_transition logwatch_t postfix_postqueue_exec_t : process postfix_postqueue_t;
type_transition logwatch_t sendmail_exec_t : process logwatch_mail_t;
type_transition logwatch_t var_lock_t : file logwatch_lock_t;
type_transition logwatch_t courier_exec_t : process logwatch_mail_t;
type_transition logwatch_t mdadm_exec_t : process mdadm_t;
type_transition logwatch_t tmp_t : dir logwatch_tmp_t;
type_transition logwatch_t tmp_t : file logwatch_tmp_t;
type_transition logwatch_t exim_exec_t : process logwatch_mail_t;
type_transition logwatch_t var_run_t : file logwatch_var_run_t;
#
ターゲット側が mail_home_rw_t なものを調べて見ると
# sesearch -T | grep mail_home_rw_t
type_transition cups_pdf_t user_home_dir_t : dir mail_home_rw_t "Maildir";
type_transition cinder_backup_t user_home_dir_t : dir mail_home_rw_t "Maildir";
type_transition conman_unconfined_script_t admin_home_t : file mail_home_rw_t ".esmtp_queue";
<略>
type_transition samba_unconfined_script_t user_home_dir_t : dir mail_home_rw_t ".esmtp_queue";
type_transition vmtools_unconfined_t admin_home_t : dir mail_home_rw_t ".maildir";
# sesearch -T |grep mail_home_rw_t |wc
886 6202 72157
#
886個設定されているようだ。
「logwatch」が関連しているものに限定してみると
# sesearch -T |grep mail_home_rw_t |grep logwatch
type_transition logwatch_mail_t admin_home_t : dir mail_home_rw_t ".esmtp_queue";
type_transition logwatch_mail_t user_home_dir_t : file mail_home_rw_t ".esmtp_queue";
type_transition logwatch_mail_t user_home_dir_t : dir mail_home_rw_t ".maildir";
type_transition logwatch_mail_t admin_home_t : dir mail_home_rw_t ".maildir";
type_transition logwatch_mail_t user_home_dir_t : dir mail_home_rw_t "Maildir";
type_transition logwatch_mail_t admin_home_t : file mail_home_rw_t ".esmtp_queue";
type_transition logwatch_mail_t user_home_dir_t : dir mail_home_rw_t ".esmtp_queue";
type_transition logwatch_mail_t admin_home_t : dir mail_home_rw_t "Maildir";
#
ソースターゲットが logwatch_mail_t でいろいろ設定されているようなので、「logwatch_mail_t」で調べて見る
# sesearch -T -s logwatch_mail_t
Found 15 semantic te rules:
type_transition logwatch_mail_t postfix_etc_t : file etc_aliases_t;
type_transition logwatch_mail_t postfix_postqueue_exec_t : process postfix_postqueue_t;
type_transition logwatch_mail_t abrt_helper_exec_t : process abrt_helper_t;
type_transition logwatch_mail_t tmp_t : file logwatch_mail_tmp_t;
type_transition logwatch_mail_t postfix_etc_t : lnk_file etc_aliases_t;
type_transition logwatch_mail_t tmp_t : dir logwatch_mail_tmp_t;
type_transition logwatch_mail_t var_log_t : file sendmail_log_t;
type_transition logwatch_mail_t postfix_showq_exec_t : process postfix_showq_t;
type_transition logwatch_mail_t postfix_etc_t : sock_file etc_aliases_t;
type_transition logwatch_mail_t qmail_inject_exec_t : process qmail_inject_t;
type_transition logwatch_mail_t exim_exec_t : process exim_t;
type_transition logwatch_mail_t postfix_postdrop_exec_t : process postfix_postdrop_t;
type_transition logwatch_mail_t postfix_etc_t : dir etc_aliases_t;
type_transition logwatch_mail_t qmail_queue_exec_t : process qmail_queue_t;
type_transition logwatch_mail_t postfix_etc_t : fifo_file etc_aliases_t;
Found 14 named file transition filename_trans:
type_transition logwatch_mail_t admin_home_t : dir mail_home_rw_t ".esmtp_queue";
type_transition logwatch_mail_t user_home_dir_t : file mail_home_rw_t ".esmtp_queue";
type_transition logwatch_mail_t user_home_dir_t : dir mail_home_rw_t ".maildir";
type_transition logwatch_mail_t admin_home_t : dir mail_home_rw_t ".maildir";
type_transition logwatch_mail_t user_home_dir_t : file mail_home_t "dead.letter";
type_transition logwatch_mail_t user_home_dir_t : dir mail_home_rw_t "Maildir";
type_transition logwatch_mail_t user_home_dir_t : file mail_home_t ".mailrc";
type_transition logwatch_mail_t admin_home_t : file mail_home_t "dead.letter";
type_transition logwatch_mail_t admin_home_t : file mail_home_rw_t ".esmtp_queue";
type_transition logwatch_mail_t user_home_dir_t : dir mail_home_rw_t ".esmtp_queue";
type_transition logwatch_mail_t admin_home_t : file mail_home_t ".forward";
type_transition logwatch_mail_t admin_home_t : dir mail_home_rw_t "Maildir";
type_transition logwatch_mail_t admin_home_t : file mail_home_t ".mailrc";
type_transition logwatch_mail_t user_home_dir_t : file mail_home_t ".forward";
#
最初に実行した sesearch -T -s logwatch_t の結果内にいくつか logwatch_mail_t への定義が描かれているがcronからのメール送信には適用されていない?
仕方がないので /var/log/audit/audit.log* の出力結果から書き込みなどの操作エラーの発生対象である mail_home_rw_t について抜き出す
# grep deni /var/log/audit/audit.log*|grep mail_home_rw_t
<略>
/var/log/audit/audit.log.4:type=AVC msg=audit(1623953887.619:18168): avc: denied { write } for pid=23636 comm="mktemp" name=".esmtp_queue" dev="sda3" ino=2567447 scontext=system_u:system_r:logwatch_t:s0-s0:c0.c1023 tcontext=unconfined_u:object_r:mail_home_rw_t:s0 tclass=dir permissive=0
/var/log/audit/audit.log.4:type=AVC msg=audit(1624041848.311:27261): avc: denied { add_name } for pid=5082 comm="mktemp" name="PcKUa8QZ" scontext=system_u:system_r:logwatch_t:s0-s0:c0.c1023 tcontext=unconfined_u:object_r:mail_home_rw_t:s0 tclass=dir permissive=0
/var/log/audit/audit.log.4:type=AVC msg=audit(1624126686.899:34916): avc: denied { add_name } for pid=15196 comm="mktemp" name="jiIjNaug" scontext=system_u:system_r:logwatch_t:s0-s0:c0.c1023 tcontext=unconfined_u:object_r:mail_home_rw_t:s0 tclass=dir permissive=0
#
これをaudit2allowコマンドでSELinuxのモジュール化して、読み込む。
# grep deni /var/log/audit/audit.log*|grep mail_home_rw_t
#============= logwatch_t ==============
#!!!! This avc is allowed in the current policy
allow logwatch_t mail_home_rw_t:dir create;
allow logwatch_t mail_home_rw_t:file create;
# grep deni /var/log/audit/audit.log*|grep mail_home_rw_t | audit2allow -M mktemp
******************** IMPORTANT ***********************
To make this policy package active, execute:
semodule -i mktemp.pp
# semodule -i mktemp.pp
# semodule -l | mktemp
mktemp 1.0
#
ただ、1回だけではだめで、何回か追加を繰り替えすことになった。
最終的に作成された mktemp.te ファイルは下記となった。
module mktemp 1.0.8;
require {
type logwatch_t;
type mail_home_rw_t;
class file { create link open read setattr unlink write };
class dir { add_name create read remove_name rmdir write };
}
#============= logwatch_t ==============
#!!!! This avc is allowed in the current policy
allow logwatch_t mail_home_rw_t:dir { add_name create read remove_name rmdir write };
#!!!! This avc is allowed in the current policy
allow logwatch_t mail_home_rw_t:file { create link open read setattr unlink write };
こうやって作成したテキストのteファイルを modファイル経由で pp形式に出力
# checkmodule -M -m -o mktemp.mod mktemp.te
checkmodule: loading policy configuration from mktemp.te
checkmodule: policy configuration loaded
checkmodule: writing binary representation (version 19) to mktemp.mod
# semodule_package -o mktemp.pp -m mktemp.mod
#
現在のモジュール状況を確認して、読み込み
# semodule -l | grep mktemp
mktemp 1.0.7
# semodule -i mktemp.pp
# semodule -l | grep mktemp
mktemp 1.0.8
#
モジュールのバージョンが変更されたことを確認。
なお、不要になったモジュールは「semodule -r モジュール名」で削除できる。