Skip to content

filipnet/postfix-bounce-report

Repository files navigation

Postfix Compatible Perl interpreter

Postfix Bounce Report

Logo

This script generates an HTML report based on rejected messages. Another script continuously writes "recipient addresses" to a list. If an incoming message is rejected and the recipient is present in the list, the subject of the email is adjusted.

Features

  • build_submission_recipients.sh: Analyzes the Postfix mail log for outgoing emails and continuously creates a recipient list.
  • postfix-bounce-report.sh: Analyzes the Postfix log file for bounced emails due to DDNS blacklist, optionally validates/matches the FROM value with the submission list. The script also generates an HTML report and sends it via sendmail.
  • The default subject is "[INFO] Postfix Bounce Report". A threshold can be set to change the subject to [WARNING]. If there is a match with the submission recipient list, [CRITICAL] is set.

⚠️ Important Notice
This script has undergone significant changes in the latest version (2025-07-18).
If you have used a previous version, please consult the updated CHANGELOG.md before upgrading.
Existing setups may require adaptation to the new format and template handling.

Example

The following screenshot shows a sample HTML report generated by the script.
All personal or sensitive data has been anonymized for demonstration purposes.

This example illustrates the typical layout, formatting, and information structure included in the bounce report email.

Postfix Bounce Report HTML Example

Installation

Install Perl (Required Dependency)

The script relies on basic Perl tools like perl or perl-compatible regular expressions (PCRE). These are not always pre-installed, especially on minimal or container-based systems.

Red Hat-based distributions (RHEL, CentOS, AlmaLinux, Rocky, Fedora)

To install Perl:

sudo dnf install perl

On older systems, use yum instead of dnf.

Debian-based distributions (Ubuntu, Debian, etc.)

To install Perl:

sudo apt update
sudo apt install perl

Most full Ubuntu/Debian installations already include Perl by default. Use the command above if not present.

Check Perl version:

  • After installation, check the Perl version with perl -v.

Clone the Repository

  • Change to your home directory: cd ~
  • Clone the repository: git clone https://github.com/filipnet/postfix-bounce-report.git
  • A new folder "postfix-bounce-report" will appear in your home directory.
  • Make the scripts executable before first use: chmod +x ~/*.sh

Configuration

Note: Configuration is now done via a simple .conf file. The previous config.xml.sample is no longer used.

  1. Rename the file postfix-bounce-report.conf.example to postfix-bounce-report.conf.
  2. Adjust the variables in this file to match your system environment.
cd ~/postfix-bounce-report
cp postfix-bounce-report.conf.example postfix-bounce-report.conf
vim postfix-bounce-report.conf

Using a .conf file eliminates the need for additional XML parser dependencies. The script can be run directly on a standard Linux system.

Configuration via .conf File

The script reads its settings from a configuration file. Below is a list of supported options:

Variable Description Example Value(s)
LC_ALL Locale setting for consistent date/time and string formatting during script execution. "de_DE.utf8"
RED ANSI escape code for red terminal text. "\033[0;31m"
GREEN ANSI escape code for green terminal text. "\033[0;32m"
YELLOW ANSI escape code for yellow terminal text. "\033[0;33m"
NC ANSI escape code to reset terminal color. "\033[0m"
TEMPLATE_BASENAME Basename (without extension) of the HTML/CSS template files used for the report. "template.custom"
MAILLOG Path to the Postfix mail log file to be analyzed. "/var/log/maillog"
MAILLOG_PERIOD Time range in hours to scan for relevant log entries. "24"
MAILLOG_PATTERN Regular expression to match relevant log lines (e.g. bounces or rejections). "blocked "
LOGMAIL_FROM Email address used as sender of the bounce report. "[email protected]"
LOGMAIL_TO Email address of the recipient who will receive the report. "[email protected]"
LOGMAIL_SUBJECT Subject line for the report email. "Postfix Bounce Report"
RECIPIENTS_CHECK Enables verification of sender addresses against a known list when set to true. "true" or "false"
RECIPIENTS_LIST Path to file with one valid recipient address per line. "/etc/postfix/submission_recipient"
SEVERETY_THRESHOLD Numeric threshold to classify bounce severity (e.g. highlight known spoof attempts). "50"
DOMAINS Pipe-separated list of trusted internal domains for spoof detection. "example.com"

Output Formatting Options

The script supports two options to control the formatting of the HTML report:

Variable Description
ONELINE="true" Displays each bounce in a single unwrapped row. Long lines are not broken – horizontal scrolling may be required. Useful for fast scanning or compact overviews.
GROUP_BY_FROM="true" Groups all bounces by sender address (from). Each sender is shown with the total number of bounces, followed by a detailed list of individual bounces including timestamp, recipient, IP, and rejection reason. Ideal for clustered analysis of problematic senders.

Example Use Cases:

  • Set ONELINE="true" to review a high number of bounces quickly in a compact layout.
  • Set GROUP_BY_FROM="true" to identify which senders cause the most issues and inspect grouped bounce details.
  • Combine both for a condensed, grouped summary view – or set both to false for the full expanded format.

Scheduled Execution (Cron)

You can run the script automatically once per day using one of the two options below.

Option A: User Crontab (crontab -e)

Run the script as a specific user (e.g., root):

sudo crontab -e

Add the following line:

0 0 \* \* \* /root/postfix-bounce-report/postfix-bounce-report.sh > /dev/null 2>&1

This executes the script every day at midnight. To log output for debugging, use:

0 0 \* \* \* /root/postfix-bounce-report/postfix-bounce-report.sh >> /var/log/bounce-report.log 2>&1

Option B: System-wide Cron File (/etc/crontab)

Edit the system crontab file:

sudo vim /etc/crontab

Add the following line (note the required root user field):

0 0 \* \* \* root /root/postfix-bounce-report/postfix-bounce-report.sh > /dev/null 2>&1

This also executes the script daily at midnight.

Log Rotation Compatibility

The script postfix-bounce-report.sh always analyzes log entries from the previous calendar day (yesterday) based on the system time.
It uses tools like date and grep to extract matching lines from /var/log/maillog (or another specified log file).

Make sure the following conditions are met:

  • Your log rotation (e.g., via logrotate) does not rotate the log file before midnight if the bounce report is scheduled at 00:00.
  • Rotated logs (e.g., maillog.1) are still available and readable when the script runs.
  • If your system compresses logs immediately (e.g., .gz), the script will not find entries from yesterday unless you extend it to support compressed files.

Recommendation:
Schedule the bounce report script shortly after midnight, e.g., 00:05, and ensure that log rotation (e.g., via logrotate) occurs later, e.g., 01:00.

You can check the logrotate schedule via:

cat /etc/cron.daily/logrotate

Or if your system uses systemd timers:

systemctl list-timers --all | grep logrotate

Sender Marking (optional)

For detailed information about how bounced emails are marked as resent or spoofing, and how the known senders list is generated and used, see the separate documentation file SENDER_MARKING.md.

Contributions

Contributions are welcome! If you would like to improve this project, please feel free to submit a pull request. All contributions, bug reports, and feature suggestions are appreciated.

License

postfix-bounce-report and all individual scripts are under the BSD 3-Clause license unless explicitly noted otherwise. See the LICENSE file for more details.