From 85943c38d91bb85a8c9052bafc5654c68bd1662e Mon Sep 17 00:00:00 2001 From: robott Date: Fri, 27 Mar 2026 19:31:07 +0100 Subject: [PATCH] Update README.md --- README.md | 252 ++++++++++++++++++++++++++++++++---------------------- 1 file changed, 151 insertions(+), 101 deletions(-) diff --git a/README.md b/README.md index b8354f3..8b3e968 100644 --- a/README.md +++ b/README.md @@ -1,141 +1,191 @@ -# 📬 Postfix Mail Summary Script +# Postfix Mail Summary Script -A hardened, production-ready Bash script for analyzing Postfix mail logs with a **clean, readable output format**. +![License](https://img.shields.io/badge/license-MIT-green) -Designed with **security, performance, and portability** in mind. +Hardened, secure, and memory-safe Bash script for summarizing **Postfix** mail logs with filtering and detail views. --- -## 🚀 Features +## Table of Contents -- 📊 **Clean, formatted output** (with optional colors) -- 🔍 **Filter by**: - - Sender (`--from`) - - Recipient (`--to`) - - Queue ID (`--id`) - - Date (`--date`) -- ⚡ **Optimized log reading** (avoids full log parsing when possible) -- 🛡️ **Hardened against**: - - Command injection - - Regex/ReDoS attacks - - Memory leaks - - Log-based DoS -- 🧠 **Smart parsing** of Postfix logs (including `NOQUEUE` rejects) -- 🎯 **Portable** across Linux distributions +* [Overview](#overview) +* [Features](#features) +* [Requirements](#requirements) +* [Installation](#installation) +* [Usage](#usage) +* [Options](#options) +* [Examples](#examples) +* [Security & Hardening](#security--hardening) +* [Notes](#notes) +* [License](#license) --- -## 📦 Requirements +## Overview -- Bash (>= 4.x recommended) -- Standard Linux utilities: - - `awk` - - `grep` - - `sed` - - `tail` - - `find` - - `zcat` +This script parses and summarizes Postfix log files located in `/var/log/`. It supports filtering by sender, recipient, queue ID, and date. The output can be a concise summary table or a detailed per-message view. + +The script is hardened with: + +* Resource limits +* Safe temporary file handling +* Single-instance locking +* Secure parsing and memory-safe processing --- -## ⚙️ Installation +## Features + +* Summarizes Postfix logs with **color-coded output**. +* Filters by: + + * Sender (`from`) + * Recipient (`to`) + * Queue ID (`id`) + * Date (`date`) + + * **Use `-d ""` to search across all logs without date filtering** +* Displays summary or detailed view per message. +* Handles compressed logs (`.gz`) automatically. +* Safely deletes old temporary files. +* Avoids displaying internal local deliveries (`127.0.0.1`) unless explicitly filtered. +* Highlights **deferred**, **rejected**, and **greylisted** emails with color. +* Limits memory, CPU time, and file usage for safety. + +--- + +## Requirements + +* Linux or Unix-like system +* Bash 4.x+ +* Postfix logs under `/var/log/` (e.g., `maillog*`, `mail.log*`) +* `awk`, `zcat`, `grep`, `find`, `sed` installed + +--- + +## Installation + +Clone or copy the script to your preferred location, e.g.: ```bash -git clone https://git.robott.sk/robott/mail-status.git -cd mail-status -chmod +x mail-status.sh -▶️ Usage -sudo ./mail-status.sh [OPTIONS] -📖 Options -Option Description --h, --help Show help message --l, --list NUMBER Show last X records (default: 10, max: 1000) --f, --from Filter by sender (substring match) --t, --to Filter by recipient (substring match) --i, --id Filter by Queue ID --d, --date "MMM DD" Filter by date (e.g. "Mar 27") +sudo cp postfix_summary.sh /usr/local/bin/postfix_summary +sudo chmod +x /usr/local/bin/postfix_summary +``` -Search across all logs for a specific user: +No additional dependencies are required. -sudo ./mail-status.sh -f user@example.com -d "" +--- -Or search for a specific date: +## Usage -sudo ./mail-status.sh -f user@example.com -d "Mar 23" -📌 Examples +```bash +postfix_summary.sh [OPTIONS] +``` -Show last 10 records +By default, it shows the **last 10 mail log records** from today. -sudo ./mail-status.sh +--- -Show last 50 records +## Options -sudo ./mail-status.sh -l 50 +| Option | Description | +| ------------------------- | ------------------------------------------------ | +| `-h, --help` | Show this help message | +| `-l, --list NUMBER` | Show the last X records (default: 10, max: 1000) | +| `-f, --from EMAIL/DOMAIN` | Filter by sender email or domain | +| `-t, --to EMAIL/DOMAIN` | Filter by recipient email or domain | +| `-i, --id QUEUE_ID` | Show detail view for a specific queue ID | +| `-d, --date "MMM DD"` | Filter by date (e.g., `"Mar 27"`) | -Filter by sender +* **Use `-d ""` to search across all logs without date filtering** | -sudo ./mail-status.sh -f gmail.com +--- -Filter by recipient +## Examples -sudo ./mail-status.sh -t example.com +Show last 20 emails: -Filter by Queue ID +```bash +postfix_summary.sh -l 20 +``` -sudo ./mail-status.sh -i 3F2A12345 +Filter emails from a specific sender: -Filter by date +```bash +postfix_summary.sh -f "example@domain.com" +``` -sudo ./mail-status.sh -d "Mar 27" -🖥️ Output Example -DATE-TIME ID CLIENT_IP SENDER RECIPIENT STATUS REASON -Mar-27-12:00:01 3F2A12345 192.168.1.10 user@gmail.com admin@example.com sent [OK] -Mar-27-12:01:05 NOQUEUE 45.12.34.56 spam@bad.com user@example.com REJECT [Policy] -🔐 Security Design +Filter emails sent to a specific recipient: -This script is designed with security-first principles: +```bash +postfix_summary.sh -t "recipient@domain.com" +``` -✅ Protected Against: +Show detailed view of a specific queue ID: -Command injection -AWK injection -Regex-based DoS (ReDoS) -Malicious filenames -Memory exhaustion -Log flooding +```bash +postfix_summary.sh -i 3F2A4B1C0 +``` -🔒 Key Techniques: +Filter by a specific date: -Input length limiting -Substring matching (index() instead of regex) -Safe file handling (find -print0, arrays) -Temporary file isolation (mktemp) -Automatic cleanup (trap) -No use of eval -⚡ Performance Optimizations -Reads only last 50,000 lines by default -Full log scan only when necessary (--date, --id) -Avoids unnecessary process spawning -Efficient AWK parsing with memory cleanup -🎨 Color Output -Automatically enabled when running in a terminal -Disabled when piping output (e.g., | less, | grep) -⚠️ Notes -Must be run as root (required for log access) -Works with standard Postfix logs: -/var/log/maillog -Rotated logs (maillog.*, .gz) -🛠️ Future Improvements (Optional) -Real-time monitoring (tail -f) -JSON export for SIEM tools (ELK, Splunk) -Fail2ban integration (auto-block IPs) -Spam pattern detection -📄 License +```bash +postfix_summary.sh -d "Mar 27" +``` -MIT License +Search across all logs without date filtering: -👨‍💻 Author +```bash +postfix_summary.sh -d "" +``` -robott GitHub: https://github.com/robott +--- -Powered by Gitea \ No newline at end of file +## Security & Hardening + +The script applies multiple security measures: + +1. **Resource Limits** + Prevents excessive CPU or memory usage: + + ```bash + ulimit -t 15 # CPU time + ulimit -v 500000 # Virtual memory (kB) + ulimit -f 102400 # Max file size + ``` + +2. **Single Instance Locking** + Prevents multiple simultaneous executions using `/tmp/postfix_summary.lock`. + +3. **Temporary File Safety** + Uses `mktemp` to create secure temporary files and cleans them on exit. + +4. **Safe Argument Handling** + Limits input length and validates required arguments. + +5. **Memory-Safe Log Parsing** + Skips overly long or short lines to prevent potential buffer abuse. + +6. **Old Temp File Cleanup** + Deletes stale files older than 10 minutes to prevent clutter or accidental data leak. + +--- + +## Notes + +* The script ignores local Postfix deliveries (`127.0.0.1`) in summary mode. +* Supports `.gz` compressed logs for backward compatibility. +* Detail view (`--id`) provides full information including: + + * Date/Time + * Client IP + * Sender + * Recipient + * Status + * Reason + +--- + +## License + +MIT License – feel free to use, modify, and distribute.