AlpineLinuxのCron(busybox)でMAILTOを指定してもメールが届かない件

crontab -e の中で「MAILTO=alert@example.com」を設定すると、cronの結果がメールで届くようになりますが、Alpine(dockerコンテナ)経由だと送信できませんでした。

ただroot宛には届くので、外部ネットワーク経由のみNGみたい。ということでソースを見てみたら sendmailで From が設定されてないっぽい?のでエラーが発生している模様。

fdprintf(mailFd, "To: %s\nSubject: cron: %s\n\n", line->cl_mailto,

ということで、Alpine Linux の cron でアラートメールを受け取る方法をまとめます。

「cron」に届いたメールをスクリプトに食わせる

postfixの場合、aliasesファイルの最後に以下追記。こうすれば crontab -e で 「MAILTO=cron」を設定しておくことで、/path/aliases_cron.sh が実行されるようになります。

# シェルを間に噛ませる
cron:       |"sh /path/aliases_cron.sh"

「/path/aliases_cron.sh(777)」を作成する

以下のファイルをパーミッション777で作成。docker用なので適宜修正してください。

#!/bin/sh

# パーミッションは777にすること
# 以下のスクリプトを参考にしました。
# https://qiita.com/oikyn/items/2c10a5ae20388e8c9750

################################
# postfixユーザーは環境変数読めないっぽいので
# 事前に作成してあるsourceファイルから設定する
################################
. /etc/postfix/.globalip
from="cron@${globalip} <cron@${globalip}>"
. /etc/postfix/.alertemail
to=${alertemail}

# 自動返信をスキップする
# Fromのアドレスを正規表現で
invalid_address="MAILER-DAEMON"

# テンプレート関数
mail_tpl () {
subject2=`echo $subject`
body2=`echo "$body"`

mail=`cat << EOF
From: $from
To: $1
Subject: $subject2

$body2
EOF
`
echo "$mail"
}

################################
# 標準入力有無の判別
################################
if [ -p /dev/stdin ]; then

###############
# 標準入力取得
###############
in=$(cat -)

###############
# subject抽出
###############
subject=`echo "${in}" | egrep -i "^Subject:" | sed -e "s/Subject: cron: \s*\(.*\)/\1/g"`

###############
# body抽出
###############
flag=0; body=""; while read line; do
if [ $flag = 1 ]; then
    if [ "${body}" = "" ]; then body="${line}";
    else
body="${body}
${line}"; fi
fi
if [ "${line}" = "" ]; then flag=1; fi
done <<END
$in
END

###############
# スキップ判別
###############
invalid_num=`echo $to | egrep -i $invalid_address | wc -c`
if [ $invalid_num -gt 0 ]; then
    exit
fi

###############
# メール送信
###############
echo "`mail_tpl \"$to\"`" | /usr/sbin/sendmail -f ${alertemail} -it

################################
# それ以外
################################
else echo "no stdin"; fi

crontab -e して MAILTO=cron を設定して完了

crontab -e
MAILTO=cron

追記:AlpineLinuxでは受信者名を指定できない

busyboxのsendmailは、受信者名にメールアドレスしか指定ができないようです。

To: sendmail@example.net
はOKのなのですが、
To: sendmail user sendmail@example.net
では送信ができないのです。
https://qiita.com/idani/items/e703b8810db219bd57fa#sendmail%E3%81%AB%E5%95%8F%E9%A1%8C%E3%81%8C20190616-%E8%BF%BD%E8%A8%98