fixed site

This commit is contained in:
2026-03-29 17:20:43 +02:00
parent c9e3d971c4
commit d433869348
153 changed files with 6766 additions and 1653 deletions
@@ -0,0 +1,126 @@
+++
date = '2025-08-01T10:03:15+02:00'
draft = false
title = 'Blocking Invalid Recipients Before They Reach Your Exchange Server'
[cover]
image = "/imgs/email-route.jpg"
alt = "Email App icon on blue background"
caption = ""
+++
Recently, I had to deal with a serious problem: **backscatter**.
One of our mail gateways ended up listed on the **backscatter.org** blacklist for sending bounce messages to forged senders.
After checking the logs, I quickly realized that our system wasn't actually protected against backscatter attacks, so I had to do something about it.
## What Even Is Backscatter?
Backscatter is unwanted email that your mail server sends **after** receiving a message, usually in the form of a **non-delivery report (NDR)** or **bounce** to a **forged sender address**.
It happens when:
- A spammer sends email with a **fake "From" address** (often an innocent third party).
- Your mail server **accepts** the message first, but later discovers its undeliverable.
- Your server sends a **bounce** to the forged address, hitting an innocent person instead of the spammer.
This makes your server appear to be sending spam, even though you're just bouncing bad mail.
## The Problem in Our Setup
Our mail gateway mostly relays mail to multiple internal Exchange Server clusters.
We have a list of valid domains configured, so Postfix will only accept mail for those domains.
**The problem?**
Postfix didn't know which individual recipients were valid on the downstream Exchange servers.
That meant it would happily accept messages for **nonexistent users**, only to later bounce them, classic backscatter behavior.
## The Goal
We needed to reject mail **during the SMTP session**, ideally right after the `RCPT TO` command, if the recipient didn't exist on the Exchange servers.
That way, the sending server would get the rejection immediately, and we would never have to generate a bounce message.
## Possible Solutions I Considered
### **1. relay_recipient_maps**
This would require maintaining a **full list of valid recipients** in a Postfix lookup table.
It works well, but means writing and maintaining a script to **sync the list from Active Directory** on a regular basis.
For us, this was too much custom scripting, too fragile, and too messy to maintain.
### **2. virtual_mailbox_maps with LDAP**
Another approach would be using **LDAP lookups** directly against Active Directory to verify recipients in real-time.
This can work in some setups, but:
- It adds complexity and dependencies.
- It can introduce security concerns.
- It didnt fit well with our environment.
So I ruled it out.
## The Solution: `reject_unverified_recipient`
While reading through the **Postfix Address Verification Howto**, I came across the `reject_unverified_recipient` option - bling! - exactly what I needed.
### **How It Works**
When an incoming SMTP session reaches the `RCPT TO` stage:
1. Postfix checks if `reject_unverified_recipient` is enabled for the recipient domain.
2. If yes, it temporarily **probes the downstream mail system** to see if the recipient address exists.
3. If the downstream system says:
- **User exists** → Postfix continues processing.
- **User does not exist** → Postfix **rejects immediately** with:
```
550 5.1.1 <user@example.de>: Recipient address rejected: User unknown
```
Because the rejection happens **during SMTP**, no bounce is generated, and backscatter is avoided entirely.
## Implementation in ISPConfig
In our case, the mail gateways run **Postfix** with **ISPConfig** as the management interface.
I implemented a new configuration option in ISPConfig for **per-domain control** of `reject_unverified_recipient`, along with a **validation server** to specify for the downstream validation server.
### Specifying a Validation Server for Recipient Verification
One important detail is that Exchange servers cannot validate recipients over the default SMTP transport on port `25`. To enable recipient validation, you need to activate it on the Exchange server and use the Hub Transport service, which by default runs on port `2525`.
Make sure to restrict access to this port, as it requires anonymous login specifically for recipient validation, you don't want that exposed broadly.
> **Note:** This setup does not affect your regular mail flow. Only the SMTP probes used for verifying recipients are sent to this validation server.
> Postfix enables this behavior with the `address_verify_transport_maps` option.
To optimize performance and reduce unnecessary verification probes for addresses that have already been checked, I configured a local cache on the mail gateway using the `address_verify_map` option. This way, repeated probes for the same recipient are avoided.
Now, for domains that need recipient verification, we can enable it in the panel and point Postfix to the appropriate **validation transport**.
## The Result
After enabling `reject_unverified_recipient` and pointing it at the Exchange clusters, the backscatter stopped completely.
We were no longer accepting messages for invalid recipients.
## Conclusion
If your Postfix server is acting as a relay for Exchange (or any downstream mail system) and you're struggling with **backscatter spam**, enabling `reject_unverified_recipient` can be a clean and effective fix.
It avoids maintaining large static recipient maps, works dynamically, and ensures that invalid mail is rejected **before** it ever gets into your system.