BATV
Bounce Tag Address Validation (BATV, [draft-levine-smtp-batv-01]) provides a cryptographic mechanisms to verify the integrity of a bounced message in order to prevent backscatter. BATV works by rewriting the sender (MAIL FROM) address to a unique (yet valid for X days) address while allowing bounced in a time window. If a bounced message (MAIL FROM: <>) is received to an address with a (RCPT TO: <prvs=signature=localpart@domain>) BATV tag, it is possible to validate that the tag was created by you less than X days ago. If a bounce is received to an address without a/invalid/expired BATV tag it should be rejected.
Contents |
How to deploy BATV with Halon VSP/SPG
All BATV function are core functions.
Requirements
You must use the VSP/SPG for both sending and receiving e-mail in order to sign/add and verify/strip the BATV tag.
Verify BATV tags
In your Flows → Recipient Flow → Your active Recipient Flow. Add the following
if (($sender == "" or $sender =~ "/^mailer-daemon@/i") and batv_verify($recipient, array(0 => "secret key")) != "pass")
{
Reject("Invalid Bounce");
}
You may need to strip the BATV tag before calling your lookup function using the batv_strip() function. If simples block are used, copy the lookup code and replace $recipient with batv_strip($recipient) in appropriate places.
In your Flow → Content Flow → Incoming (or active scanning script). Add the following
SetRecipient(batv_strip($recipient));
Add BATV tag
In your Flow → Content Flow → Outgoing (or active outgoing script). Add the following
SetSender(batv_sign(batv_strip($sender), "secret key"));
Note: batv_strip is needed if multiple recipients are processed, or else $sender would obtain multiple batv_signatures (prvs=sign=prvs=sign=user@domain)
Key rotation
BATV keys should be rotated when needed or every 1000th day for good security. When need might be considered as when you start to receive bounces that actually goes through the verification process. It could mean that someone know the key, and sends forged messages with that key in use, but that is very unlikely to happen.
→ First key
| Content Flow → Signing | batv_sign($sender, "myfirstkey"); |
| Recipient Flow → Verifying | batv_verify($recipient, array(0 => "myfirstkey")); |
→ Second key
| Content Flow → Signing | batv_sign($sender, "mysecondkey", array("keyid" => 1)); |
| Recipient Flow → Verifying | batv_verify($recipient, array(0 => "myfirstkey", 1 => "mysecondkey")); |
→ Second key (but seven days later, the old first key can be removed)
| Recipient Flow → Verifying | batv_verify($recipient, array(1 => "mysecondkey")); |