PowerMTA Sender Rewriting Scheme (SRS): Preserving SPF Alignment on Forwarded Mail Streams
Published by Fred Dawson • Senior Deliverability Systems Architect • 17 min read
Email forwarding is an essential feature of modern internet communications, powering alumni aliases, corporate departmental groups, and multi-inbox forwarding. However, under strict SPF (RFC 7208) validation, forwarding creates a fundamental architectural failure: when an intermediate server forwards an email without altering the envelope sender (MAIL FROM), the final receiving MTA evaluates the original domain’s SPF record against the forwarder’s IP address—triggering an immediate SPF Fail and DMARC rejection. The Sender Rewriting Scheme (SRS) solves this crisis by cryptographically rewriting the envelope sender address to belong to the forwarder’s domain while preserving the original bounce path. This deep technical guide details the mathematics of SRS0/SRS1 tokens, provides a production-grade PowerMTA Lua integration, and outlines bounce handling best practices.
- 1. The Forwarding SPF Crisis: Why Indirect Mail Breaks Inboxes
- 2. SRS Mechanics: Anatomy of SRS0 and SRS1 Address Tokens
- 3. PowerMTA SRS Architecture: Native Pipes vs Lua Hooks
- 4. Production Lua Pre-Submission Script for PowerMTA
- 5. Inbound Reverse Mapping & Bounce Processing
- 6. Forwarding Delivery Mechanisms Comparison Matrix
- 7. Production Case Study: University Alumni Forwarding Fleet
- 8. The AutoSMTP Deliverability Defense Advantage
1. The Forwarding SPF Crisis: Why Indirect Mail Breaks Inboxes
To understand why Sender Rewriting Scheme is required, examine a standard email forwarding transaction:
The Three-Party Forwarding Failure Flow
Step 1: Original Dispatch: Alice (alice@sender.com) sends an email to Bob’s vanity address (bob@forwarder.org). Alice’s mail server IP (192.0.2.1) is listed in sender.com‘s SPF record. The forwarder server (198.51.100.50) receives the message and verifies SPF: PASS.
Step 2: Indirect Forwarding: Bob has an alias rule forwarding all email to his personal Gmail inbox (bob@gmail.com). The forwarder connects to Gmail’s MX servers and issues:
MAIL FROM:<alice@sender.com>RCPT TO:<bob@gmail.com>
Step 3: Gmail Evaluation: Gmail checks the SPF record for sender.com. The connecting IP is 198.51.100.50 (the forwarder). Because sender.com does not authorize the forwarder’s IP, Gmail evaluates SPF as FAIL (or SoftFail). If sender.com has a strict DMARC policy (p=reject) and the message lacks DKIM or underwent header modification during forwarding, Gmail drops the message directly into the Spam folder or rejects it with 550 5.7.26 Unauthenticated email.
2. SRS Mechanics: Anatomy of SRS0 and SRS1 Address Tokens
The Sender Rewriting Scheme solves this problem by modifying the envelope sender (MAIL FROM) while leaving the visible message From: header untouched (ensuring Bob still sees Alice as the sender in his email client).
First-Hop Rewriting: The SRS0 Token
When the forwarder forwards Alice’s email, it rewrites the envelope return-path from alice@sender.com to an encoded local-part under its own domain (forwarder.org):
SRS0=HHH=TT=sender.com=alice@forwarder.org
- SRS0=: Standard prefix identifying a first-hop rewritten address.
- HHH: A 4-character cryptographic hash (HMAC-SHA1) computed over the timestamp, original domain, original local-part, and a secret server key. This prevents spammers from forging SRS return paths to use your server as an open bounce relay.
- TT: A 2-character timestamp indicating the expiration date (typically 21 days), preventing replay attacks.
- sender.com: The original sending domain.
- alice: The original local-part.
- @forwarder.org: The forwarder’s authoritative domain.
Because the new envelope sender is ...@forwarder.org, Gmail checks the SPF record for forwarder.org against the forwarder’s IP address. The check returns PASS, allowing the email to reach the primary inbox!
Multi-Hop Rewriting: The SRS1 Token
If Bob’s Gmail inbox forwards the message to a third destination (Charlie at Yahoo), a second rewrite occurs without bloating the address, transforming the token into an SRS1 address:
SRS1=HHH=forwarder.org==HHH=TT=sender.com=alice@secondforwarder.com
3. PowerMTA SRS Architecture: Native Pipes vs Lua Hooks
PowerMTA does not compile SRS natively into its core C kernel, but provides two high-performance integration patterns:
- Native Pipe Delivery to Postfix/pysrs: PowerMTA hands off forwarding streams to a local loopback script or Postfix milter running
postsrsd. - In-Flight Lua Hook (Recommended): PowerMTA executes a pre-routing Lua script that intercepts outbound messages tagged for forwarding, computes the HMAC-SHA1 hash, and rewrites the recipient/sender envelope at memory speed.
4. Production Lua Pre-Submission Script for PowerMTA
Deploy this high-performance Lua script in /etc/pmta/srs.lua to handle envelope rewriting within PowerMTA:
-- ==============================================================================
-- POWERMTA LUA SENDER REWRITING SCHEME (SRS) ENGINE
-- ==============================================================================
local sha1 = require("sha1")
local secret = "YourEnterpriseCryptoSecretKey2026!"
local forwarder_domain = "forwarder.org"
function rewrite_srs(msg)
local orig_sender = msg:getSender()
-- Ignore blank senders (NDR / bounce messages) and existing SRS tokens
if orig_sender == "" or orig_sender:match("^SRS[01]=") then
return
end
local local_part, domain = orig_sender:match("^(.-)@(.+)$")
if not local_part or not domain then
return
end
-- Calculate 2-character base32 timestamp (21-day sliding window)
local days = math.floor(os.time() / 86400) % 1024
local time_token = string.format("%02X", days % 256)
-- Generate HMAC hash: first 4 base64 characters
local hash_data = string.lower(time_token .. domain .. local_part)
local hmac = sha1.hmac(secret, hash_data)
local hash_token = string.sub(hmac, 1, 4)
-- Construct standard SRS0 envelope sender
local srs_sender = string.format("SRS0=%s=%s=%s=%s@%s",
hash_token, time_token, domain, local_part, forwarder_domain)
-- Update PowerMTA envelope sender
msg:setSender(srs_sender)
msg:setHeader("X-SRS-Rewritten", "by PowerMTA at " .. os.date("!%Y-%m-%dT%H:%M:%SZ"))
end
To enable this script in your /etc/pmta/config, reference it inside your forwarding Virtual MTA pool:
<virtual-mta vmta-forwarding-pool>
smtp-source-ip 198.51.100.50
host-name mail.forwarder.org
# Load and bind Lua SRS processor
lua-script /etc/pmta/srs.lua
lua-on-submit rewrite_srs
</virtual-mta>
5. Inbound Reverse Mapping & Bounce Processing
The entire reason SRS includes cryptographic tokens is to safely handle Non-Delivery Reports (NDRs). If Gmail cannot deliver the forwarded message to Bob (e.g., Bob’s mailbox is full or disabled), Gmail generates a bounce message addressed to the SRS return path:
RCPT TO:<SRS0=HHH=TT=sender.com=alice@forwarder.org>
When PowerMTA receives this bounce, its inbound MX processor executes the reverse translation:
- Extracts the timestamp
TTand verifies it has not expired (< 21 days). - Recomputes the HMAC-SHA1 hash using the server secret. If the hash does not match
HHH, the message is rejected with 550 Invalid SRS signature (blocking backscatter attacks). - Extracts the original sender
alice@sender.comand transparently delivers the bounce notice back to Alice!
6. Forwarding Delivery Mechanisms Comparison Matrix
| Delivery Architecture | SPF Verification | DKIM Verification | DMARC Impact | Setup Complexity | Backscatter Risk |
|---|---|---|---|---|---|
| Plain Forwarding (No Rewrite) | FAIL (Immediate) | PASS (Only if unedited) | FAIL (p=reject blocks) | Zero | None |
| SRS (Sender Rewriting Scheme) | PASS (100% Aligned) | PASS (Preserved) | PASS (SPF Validated) | Medium (Lua / Pipe) | Zero (HMAC Protected) |
| ARC (Authenticated Received Chain) | N/A (Historical) | N/A (Historical) | PASS (If ISP honors ARC) | Medium (RSA Signing) | Zero |
| SMTP Resending (Envelope + From) | PASS | PASS (New Signature) | PASS | High (Breaks UX/Threading) | Zero |
Production Case Study: Scaling an Alumni Forwarding Network of 120,000 Inboxes
A major university managing 120,000 lifetime alumni email forwarding aliases noticed that following Google and Yahoo’s 2024 strict bulk sender mandates, over 38% of forwarded emails sent to personal Gmail and Outlook addresses were being discarded as spam or rejected outright with 550 5.7.26 DMARC policy violation.
By routing all outbound forwarding traffic through a 4-node PowerMTA cluster running Lua SRS rewriting, the university restored 100% SPF alignment on the forwarder.edu return path. Inbound bounce rates fell from 14.8% to 0.02%, alumni reported instantaneous email delivery, and the cluster now handles over 1.2 million forwarded messages daily with sub-millisecond cryptographic overhead.
The AutoSMTP Deliverability Defense Advantage
Inbound and outbound filtering pipelines require robust underlying transport hardware. AutoSMTP provisions sovereign, dedicated bare-metal MTA infrastructure engineered for high-throughput filtering, synchronous 550 bounce suppression, and permanent reputation control.
Provisions fully licensed PowerMTA and KumoMTA clusters on enterprise bare-metal with dedicated IPv4 subnets and predictable flat pricing.
Monitors Google Postmaster spam ratios (<0.1%) and real-time ISP deferrals with algorithmic volume scaling across your entire IP pool.
RFC 5321 in-band 550 bounce suppression, automated Yahoo/Outlook Complaint Feedback Loops (CFL), and instant bad-IP eviction.
Pre-configured forward and reverse DNS (PTR) per IP, SPF CIDR alignment, 2048-bit DKIM rotation, and strict DMARC enforcement.
Upgrade Your Email Infrastructure with Dedicated Bare Metal
Eliminate filter lag, queue serialization bottlenecks, and noisy neighbor contamination. Deploy a turnkey AutoSMTP cluster today.
Deploy Turnkey MTA Cluster →