Oracle CloudのOracle Linux 8で標準選択されているesmtpでメールを送信する

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 モジュール名」で削除できる。

コメントを残す

メールアドレスが公開されることはありません。 が付いている欄は必須項目です

このサイトはスパムを低減するために Akismet を使っています。コメントデータの処理方法の詳細はこちらをご覧ください