LoginSignup
0
0

【Postfix】指定回数バウンスしたメールアドレスを抽出して送信しないように自動更新する

Last updated at Posted at 2023-11-08

概要

  • 送れないメールアドレスに送り続けてdnsbl登録されるのを避けたい
  • メールログからバウンス情報を抽出し、指定回数以上バウンスしたアドレスを抽出
  • 特定のディレクトリに指定日数保存
  • 保存されたディレクトリ内のアドレスをまとめて送信拒否リストを作成
  • postfix をリロードし送信拒否リストを読み込む
  • cron 等で一日一回実行することを想定

環境

  • postfix 2.6

Postfix設定準備

  • main.cf 送信拒否リストをチェックするように設定 (check_recipient_access)
main.cf
...
smtpd_recipient_restrictions =
        check_recipient_access hash:/etc/postfix/bounce/recipient_access,
        permit_mynetworks,
        permit_sasl_authenticated,
        reject_unauth_destination,
...

シェルプログラム

manage-bounce.sh
#!/bin/bash
#
# Postfix bounce management shell
#

# メールログファイルのパス
BOUNCE_LOG="/var/log/maillog"
# バウンスログの保存ディレクトリ
SAVE_DIR="/etc/postfix/bounce"
# バウンスの閾値
BOUNCE_THRESHOLD=10
# 保存期間(日数)
SAVE_DAYS=14
# 除外文字列
EXCLUDE_WORD='@mycompany.com'

# バウンス情報を抽出し、回数が多い順にソートして出力する関数
extract_and_save_bounces() {
    local datestamp=$(date +%Y%m%d)
    local output_file="${SAVE_DIR}/${datestamp}_bounces.txt"
    awk -v threshold="${BOUNCE_THRESHOLD}" -v word="${EXCLUDE_WORD}" '
        BEGIN { FS = "[<>]" }
        /status=bounced/  {
            email = $2
            reason = $0
            gsub("^.*said: +", "", reason)
            bounces[email]++
            bounce_reasons[email] = reason
        }
        END {
            for (email in bounces) {
                if (!index(email, word) && bounces[email] >= threshold) {
                    #print bounces[email], email, bounce_reasons[email]
                    print email
                }
            }
        }
    ' "${BOUNCE_LOG}" | sort > "${output_file}"

    echo "Bounce list saved to ${output_file}"
}

# 古いバウンスログファイルを削除する関数
cleanup_old_bounces() {
    find "${SAVE_DIR}" -type f -name "*_bounces.txt" -mtime +${SAVE_DAYS} -delete
    echo "Old bounce files removed"
}

# 重複を排除した宛先メールアドレスリストを作成する関数
create_recipient_access() {
    local recipient_access="${SAVE_DIR}/recipient_access"
    awk '!a[$0]++ {print $0, "REJECT"}' ${SAVE_DIR}/*_bounces.txt > "${recipient_access}"
    /usr/sbin/postmap ${recipient_access}
    if [[ $? != 0 ]]; then
        echo "postmap command failed, proccess quit!"
        exit 1
    fi
    echo "Recipient access list created at ${recipient_access}"
}

# Postfixをリロードする関数
reload_postfix() {
    /etc/init.d/postfix reload
    echo "Postfix reloaded"
}

# メインの処理
main() {
    mkdir -p "${SAVE_DIR}"

    extract_and_save_bounces
    cleanup_old_bounces
    create_recipient_access
    reload_postfix
}

main

以上、お疲れさまでした!

こちらもどうぞ

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0