|
1 | | -# postfix-bounce-report |
2 | | -The script generates an HTML report based on rejected messages. Another script continuously writes "recipient addresses" into a list. If an incoming message is rejected and is present in the list of "recipients", the subject of email is changing. |
| 1 | + |
| 2 | + |
| 3 | + |
| 4 | +# Postfix Bounce Report |
| 5 | + |
| 6 | +<img src="images/logo-postfix-bounce-report.png" alt="Logo" width="30%" align="right" hspace="30" vspace="20"/> |
| 7 | +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. |
3 | 8 |
|
4 | 9 | <!-- TOC --> |
5 | 10 |
|
6 | | -- [postfix-bounce-report](#postfix-bounce-report) |
7 | | - - [FEATURES](#features) |
8 | | - - [EXAMPLE](#example) |
9 | | - - [HOW TO INSTALL](#how-to-install) |
10 | | - - [PREREQUISITES PERL INTERPRETER AND XML EXTENSION](#prerequisites-perl-interpreter-and-xml-extension) |
11 | | - - [CLONE REPOSITORY](#clone-repository) |
12 | | - - [HOW TO USE](#how-to-use) |
13 | | - - [CONFIGURATION](#configuration) |
14 | | - - [CREATE SCHEDULED TASKS](#create-scheduled-tasks) |
15 | | - - [ADDITIONAL INFORMATION](#additional-information) |
16 | | - - [LICENSE](#license) |
| 11 | +- [Postfix Bounce Report](#postfix-bounce-report) |
| 12 | + - [Features](#features) |
| 13 | + - [Example](#example) |
| 14 | + - [Installation](#installation) |
| 15 | + - [Install Perl (Required Dependency)](#install-perl-required-dependency) |
| 16 | + - [Red Hat-based distributions (RHEL, CentOS, AlmaLinux, Rocky, Fedora)](#red-hat-based-distributions-rhel-centos-almalinux-rocky-fedora) |
| 17 | + - [Debian-based distributions (Ubuntu, Debian, etc.)](#debian-based-distributions-ubuntu-debian-etc) |
| 18 | + - [Check Perl version:](#check-perl-version) |
| 19 | + - [Clone the Repository](#clone-the-repository) |
| 20 | + - [Configuration](#configuration) |
| 21 | + - [Configuration via `.conf` File](#configuration-via-conf-file) |
| 22 | + - [Scheduled Execution (Cron)](#scheduled-execution-cron) |
| 23 | + - [Option A: User Crontab (crontab -e)](#option-a-user-crontab-crontab--e) |
| 24 | + - [Option B: System-wide Cron File (/etc/crontab)](#option-b-system-wide-cron-file-etccrontab) |
| 25 | + - [Log Rotation Compatibility](#log-rotation-compatibility) |
| 26 | + - [Contributions](#contributions) |
| 27 | + - [License](#license) |
17 | 28 |
|
18 | 29 | <!-- /TOC --> |
19 | 30 |
|
20 | | -## FEATURES |
21 | | -- build_submission_recipients.sh : Analyzes the postfix maillog for outgoing e-mails and continuously creates a list of recipients |
22 | | -- postfix-bounce-report.sh : Analyzes the postfix logfile for bounced emails by DDNS blacklist, optionaly validate/cross check FROM-value against submission list. Script also generates HTML report and send via sendmail |
23 | | -- The subject is regular "[INFO] Postfix Bounce Report", a threshold value can be parameterized where the subject is changed to [WARNING]. For a match with the submission recipients list a [CRITIAL] is created |
24 | | -- Since a spoofed e-mail address would lead to a CRITICAL, the definition of toplevel domains has been implemented in version 1.1.2. Spoofed addresses are thus recognized and marked accordingly in the HTML report. |
| 31 | +## Features |
| 32 | + |
| 33 | +- `build_submission_recipients.sh`: Analyzes the Postfix mail log for outgoing emails and continuously creates a recipient list. |
| 34 | +- `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. |
| 35 | +- 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. |
| 36 | + |
| 37 | +> ⚠️ **Important Notice** |
| 38 | +> This script has undergone **significant changes** in the latest version (2025-07-11). |
| 39 | +> If you have used a previous version, please consult the updated [CHANGELOG.md](./CHANGELOG.md) before upgrading. |
| 40 | +> Existing setups may require adaptation to the new format and template handling. |
| 41 | +
|
| 42 | +## Example |
| 43 | + |
| 44 | +The following screenshot shows a **sample HTML report** generated by the script. |
| 45 | +All personal or sensitive data has been **anonymized** for demonstration purposes. |
| 46 | + |
| 47 | +This example illustrates the typical layout, formatting, and information structure included in the bounce report email. |
25 | 48 |
|
26 | | -## EXAMPLE |
27 | 49 | <img src="images/postfix-bounce-report-html-example.png" alt="Postfix Bounce Report HTML Example" width="100%"/> |
28 | 50 |
|
29 | | -## HOW TO INSTALL |
| 51 | +## Installation |
| 52 | + |
| 53 | +### Install Perl (Required Dependency) |
| 54 | + |
| 55 | +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. |
30 | 56 |
|
31 | | -### PREREQUISITES PERL INTERPRETER AND XML EXTENSION |
| 57 | +#### Red Hat-based distributions (RHEL, CentOS, AlmaLinux, Rocky, Fedora) |
32 | 58 |
|
33 | | -Install XML library to read the XML files |
34 | | -- Once System is fully updated, you can install libxml2-utils package through command: |
35 | | - - RedHat-based: ```dnf install perl libxml2-utils``` |
36 | | - - Debian-based: ```apt install perl libxml2-utils``` |
| 59 | +To install Perl: |
37 | 60 |
|
38 | | -Check Perl Version |
39 | | -- Since the package is installed now, you can check the Perl version through ```perl -v``` command. |
| 61 | +```bash |
| 62 | +sudo dnf install perl |
| 63 | +``` |
40 | 64 |
|
41 | | -### CLONE REPOSITORY |
42 | | -Change to the root-directory of your linux-system: ```cd ~``` |
| 65 | +On older systems, use yum instead of dnf. |
43 | 66 |
|
44 | | -Clone the repository to this directory: ```git clone https://github.com/filipnet/postfix-bounce-report.git``` |
45 | | -Afterwards you will find a new folder called "postfix-bounce-report" inside your root-directory |
46 | | -To make the scripts universally applicable, some settings like email addresses are stored in a separate ```config.xml``` and must be adjusted here, the existing ```config.xml.sample``` renamed and adjusted before. |
47 | | -Please note that the scripts must be made executable before the first use. ```chmod +x ~/*.sh``` |
| 67 | +#### Debian-based distributions (Ubuntu, Debian, etc.) |
48 | 68 |
|
49 | | -## HOW TO USE |
| 69 | +To install Perl: |
50 | 70 |
|
51 | | -### CONFIGURATION |
52 | | -Rename the file ```config.xml.sample``` to ```config.xml``` and adapt it to your system environment. |
| 71 | +```bash |
| 72 | +sudo apt update |
| 73 | +sudo apt install perl |
53 | 74 | ``` |
| 75 | + |
| 76 | +Most full Ubuntu/Debian installations already include Perl by default. Use the command above if not present. |
| 77 | + |
| 78 | +#### Check Perl version: |
| 79 | + |
| 80 | +- After installation, check the Perl version with `perl -v`. |
| 81 | + |
| 82 | +### Clone the Repository |
| 83 | + |
| 84 | +- Change to your home directory: `cd ~` |
| 85 | +- Clone the repository: `git clone https://github.com/filipnet/postfix-bounce-report.git` |
| 86 | +- A new folder "postfix-bounce-report" will appear in your home directory. |
| 87 | +- Make the scripts executable before first use: `chmod +x ~/*.sh` |
| 88 | + |
| 89 | +## Configuration |
| 90 | + |
| 91 | +> **Note:** Configuration is now done via a simple `.conf` file. The previous `config.xml.sample` is no longer used. |
| 92 | +
|
| 93 | +1. Rename the file `postfix-bounce-report.conf.example` to `postfix-bounce-report.conf`. |
| 94 | +2. Adjust the variables in this file to match your system environment. |
| 95 | + |
| 96 | +```bash |
54 | 97 | cd ~/postfix-bounce-report |
55 | | -cp config.xml.sample config.xml |
56 | | -vim/nano config.xml |
| 98 | +cp postfix-bounce-report.conf.example postfix-bounce-report.conf |
| 99 | +vim postfix-bounce-report.conf |
| 100 | +``` |
| 101 | + |
| 102 | +Using a `.conf` file eliminates the need for additional XML parser dependencies. The script can be run directly on a standard Linux system. |
| 103 | + |
| 104 | +### Configuration via `.conf` File |
| 105 | + |
| 106 | +The script reads its settings from a configuration file. Below is a list of supported options: |
| 107 | + |
| 108 | +| Variable | Description | Example Value(s) | |
| 109 | +| -------------------- | ---------------------------------------------------------------------------------------------- | ------------------------------------- | |
| 110 | +| `LC_ALL` | Locale setting for consistent date/time and string formatting during script execution. | `"de_DE.utf8"` | |
| 111 | +| `RED` | ANSI escape code for red terminal text. | `"\033[0;31m"` | |
| 112 | +| `GREEN` | ANSI escape code for green terminal text. | `"\033[0;32m"` | |
| 113 | +| `YELLOW` | ANSI escape code for yellow terminal text. | `"\033[0;33m"` | |
| 114 | +| `NC` | ANSI escape code to reset terminal color. | `"\033[0m"` | |
| 115 | +| `TEMPLATE_BASENAME` | Basename (without extension) of the HTML/CSS template files used for the report. | `"template.custom"` | |
| 116 | +| `MAILLOG` | Path to the Postfix mail log file to be analyzed. | `"/var/log/maillog"` | |
| 117 | +| `MAILLOG_PERIOD` | Time range in hours to scan for relevant log entries. | `"24"` | |
| 118 | +| `MAILLOG_PATTERN` | Regular expression to match relevant log lines (e.g. bounces or rejections). | `"blocked "` | |
| 119 | +| `LOGMAIL_FROM` | Email address used as sender of the bounce report. | `"do-not-reply@example.com"` | |
| 120 | +| `LOGMAIL_TO` | Email address of the recipient who will receive the report. | `"user@example.com"` | |
| 121 | +| `LOGMAIL_SUBJECT` | Subject line for the report email. | `"Postfix Bounce Report"` | |
| 122 | +| `RECIPIENTS_CHECK` | Enables verification of sender addresses against a known list when set to `true`. | `"true"` or `"false"` | |
| 123 | +| `RECIPIENTS_LIST` | Path to file with one valid recipient address per line. | `"/etc/postfix/submission_recipient"` | |
| 124 | +| `SEVERETY_THRESHOLD` | Numeric threshold to classify bounce severity (e.g. highlight known spoof attempts). | `"50"` | |
| 125 | +| `ONELINE` | Disables line wrapping and enables horizontal scrolling in the HTML report when set to `true`. | `"true"` or `"false"` | |
| 126 | +| `DOMAINS` | Pipe-separated list of trusted internal domains for spoof detection. | `"example.com"` | |
| 127 | + |
| 128 | +## Scheduled Execution (Cron) |
| 129 | + |
| 130 | +You can run the script automatically once per day using one of the two options below. |
| 131 | + |
| 132 | +### Option A: User Crontab (crontab -e) |
| 133 | + |
| 134 | +Run the script as a specific user (e.g., root): |
| 135 | + |
| 136 | +```bash |
| 137 | +sudo crontab -e |
| 138 | +``` |
| 139 | + |
| 140 | +Add the following line: |
| 141 | + |
| 142 | +```bash |
| 143 | +0 0 \* \* \* /root/postfix-bounce-report/postfix-bounce-report.sh > /dev/null 2>&1 |
| 144 | +``` |
| 145 | + |
| 146 | +This executes the script every day at midnight. |
| 147 | +To log output for debugging, use: |
| 148 | + |
| 149 | +```bash |
| 150 | +0 0 \* \* \* /root/postfix-bounce-report/postfix-bounce-report.sh >> /var/log/bounce-report.log 2>&1 |
| 151 | +``` |
| 152 | + |
| 153 | +### Option B: System-wide Cron File (/etc/crontab) |
| 154 | + |
| 155 | +Edit the system crontab file: |
| 156 | + |
| 157 | +```bash |
| 158 | +sudo vim /etc/crontab |
| 159 | +``` |
| 160 | + |
| 161 | +Add the following line (note the required root user field): |
| 162 | + |
| 163 | +```bash |
| 164 | +0 0 \* \* \* root /root/postfix-bounce-report/postfix-bounce-report.sh > /dev/null 2>&1 |
57 | 165 | ``` |
58 | 166 |
|
59 | | -### CREATE SCHEDULED TASKS |
| 167 | +This also executes the script daily at midnight. |
60 | 168 |
|
61 | | -Create a new file in ```/etc/cron.d/``` directory: |
| 169 | +### Log Rotation Compatibility |
62 | 170 |
|
63 | | -``` touch /etc/cron.d/postfix-bounce-report ``` |
| 171 | +The script `postfix-bounce-report.sh` always analyzes log entries **from the previous calendar day** (`yesterday`) based on the system time. |
| 172 | +It uses tools like `date` and `grep` to extract matching lines from `/var/log/maillog` (or another specified log file). |
64 | 173 |
|
65 | | -The content should be: |
| 174 | +Make sure the following conditions are met: |
66 | 175 |
|
| 176 | +- Your log rotation (e.g., via `logrotate`) **does not rotate the log file before midnight** if the bounce report is scheduled at `00:00`. |
| 177 | +- Rotated logs (e.g., `maillog.1`) are still **available and readable** when the script runs. |
| 178 | +- 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. |
| 179 | + |
| 180 | +**Recommendation:** |
| 181 | +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`. |
| 182 | + |
| 183 | +You can check the logrotate schedule via: |
| 184 | + |
| 185 | +```bash |
| 186 | +cat /etc/cron.daily/logrotate |
67 | 187 | ``` |
68 | | -# https://github.com/filipnet/postfix-bounce-report |
69 | | -# Hourly script that collects the recipients for the report |
70 | | -@hourly root /root/postfix-bounce-report/postfix-build-submission-recipients.sh > /dev/null |
71 | | -# Daily script that sens out the report as an e-mail |
72 | | -@daily root /root/postfix-bounce-report/postfix-bounce-report.sh > /dev/null |
| 188 | + |
| 189 | +Or if your system uses systemd timers: |
| 190 | + |
| 191 | +```bash |
| 192 | +systemctl list-timers --all | grep logrotate |
73 | 193 | ``` |
74 | 194 |
|
75 | | -Description |
76 | | -- The script ```postfix-build-submission-recipients.sh``` scans the mail log every hour for sent e-mails, extracts the recipient's address and adds it to the list ```/etc/postfix/submission_recipients``` if not already present. |
77 | | -- The script ```postfix-bounce-report.sh``` is executed once a day, returns as content an HTML table with cross-check to the submission list, sends it via e-mail. |
| 195 | +## Contributions |
| 196 | + |
| 197 | +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. |
78 | 198 |
|
79 | | -## ADDITIONAL INFORMATION |
80 | | -Please note that the script ```postfix-bounce-report.sh``` always generates the day before. Note if there are no conflict with your log-rotation jobs. |
| 199 | +## License |
81 | 200 |
|
82 | | -## LICENSE |
83 | | -postfix-bounce-report and all individual scripts are under the BSD 3-Clause license unless explicitly noted otherwise. Please refer to the LICENSE |
| 201 | +postfix-bounce-report and all individual scripts are under the BSD 3-Clause license unless explicitly noted otherwise. See the [LICENSE](LICENSE) file for more details. |
0 commit comments