70.1.5. pepsi-stage-srs¶
rewrite the envelope sender with the Sender Rewriting Scheme
- Manual section:
1
70.1.5.1.1. Name¶
pepsi-stage-srs - SRS envelope-sender rewriting stage of the Pepsi pipeline.
70.1.5.1.2. Synopsis¶
pepsi-stage-srs [GLOBAL-OPTIONS] worker
pepsi-stage-srs [GLOBAL-OPTIONS] forward ADDRESS
pepsi-stage-srs [GLOBAL-OPTIONS] reverse ADDRESS
70.1.5.1.3. Description¶
This stage defaults to FUSION = yes: when stage fusion is enabled ([pepsi]
ALLOW_FUSION, the default) and this stage is folded into the unified pepsi
binary, a predecessor may run it in its own worker process instead of
dispatching it separately. See pepsi-dispatch(1) and pepsi.conf(5).
pepsi-stage-srs is a stage program run by pepsi-dispatch(1) as a persistent worker reading message ids on standard input. It implements the Sender Rewriting Scheme (SRS).
When Pepsi forwards a message it keeps the body intact but relays it from its own
IP addresses. The next hop’s SPF check then sees Pepsi sending mail whose
envelope sender is still the original sender’s domain, which does not authorise
Pepsi’s IPs, and the check fails. SRS solves this by rewriting the envelope
sender (MAIL FROM) into a local address of a Pepsi-controlled domain
(SRS_DOMAIN) that encodes — and HMAC-signs — the original sender:
SRS0=HHHH=TT=origin.example=alice@srs.example.org
SPF at the next hop now checks srs.example.org, which legitimately sends from
Pepsi’s IPs. The body and its DKIM signatures are untouched. The stage then
advances the message to its NEXT_STAGE (the delivery stage). It changes only
the envelope sender, leaving the row’s state — including any RFC 3461
state.dsn parameters — untouched for later stages to honour.
The null sender (<>, i.e. a returning bounce) is never rewritten, and a
sender already in SRS_DOMAIN is left unchanged (rewriting is idempotent). A
sender that is already an SRS address — the message reached Pepsi through
another forwarder — is re-signed in the compact SRS1 form rather than being
nested, so a bounce hops back one forwarder at a time.
70.1.5.1.3.1. Reverse direction¶
The other half of SRS — recognising a bounce returned to an SRS address,
verifying its signature and timestamp, decoding the original sender and relaying
the bounce there — is performed by pepsi-ingress(1) at RCPT time, not
by this program. A recipient in SRS_DOMAIN whose local-part is a valid SRS
token is accepted and rewritten back to the original sender (even though that
sender’s domain is not one Pepsi serves — the valid signature authorises the
relay); a forged or expired token is rejected with 550. Both directions read
the same shared [pepsi-srs] configuration, so the secret and domain match.
70.1.5.1.4. Configuration¶
The stage needs only a NEXT_STAGE in its own [stage-<name>] section
(PROGRAM = pepsi-stage-srs); the SRS parameters (SRS_DOMAIN,
SECRET/SECRET_FILE, MAX_AGE_DAYS) live in the shared [pepsi-srs]
section it shares with pepsi-ingress(1). All are documented in
pepsi.conf(5). Omitting [pepsi-srs] disables SRS: the stage refuses to
run and pepsi-ingress(1) treats SRS-looking recipients as ordinary
addresses.
70.1.5.1.5. State¶
Inputs: none — the stage operates on the mail_from column, not on
state.
Outputs: state.srs.original, the envelope sender the rewrite replaced.
Nothing else in state is touched — state.dsn and the rest are preserved
unchanged. The state layout is described in pepsi.state(7).
That one key exists for a DSN Pepsi originates after this stage has run, which is every DSN on a relaying path: this stage necessarily precedes the delivery stage, so pepsi-stage-bounce(1) would otherwise address the report to our own SRS alias and make it take a round trip out to the next hop and back in through our MX to be decoded. The bounce stage reads this instead of reversing the alias, which keeps the SRS secret out of a stage that only composes mail. It is written only when absent, so a message rewritten twice keeps the address that names a real correspondent rather than the intermediate alias.
Transitions: always advances to NEXT_STAGE, whether the envelope sender
was SRS-rewritten or passed through unchanged (a null sender, or one already in
SRS_DOMAIN). There is no branch; the stage never pauses, fails, reroutes or
finishes.
70.1.5.1.6. Commands¶
Run as a worker, the program rewrites each message’s envelope sender and advances it. The subcommands are operator tools:
- forward ADDRESS
Print the SRS rewrite of ADDRESS (the forward direction) and exit. Useful for inspecting what a given sender becomes.
- reverse ADDRESS
Decode and verify ADDRESS (an SRS address or bare local-part) and print the original sender, or fail if it is not a valid SRS address.
70.1.5.1.7. Global Options¶
- -c FILE, –config FILE
Read the configuration from FILE instead of the default search path.
- -L LOGLEVEL, –log LOGLEVEL
Set the logging verbosity (
error,warn,info,debug,trace; defaultinfo).- -h, –help
Print a usage summary and exit.
- -V, –version
Print the version and exit.
70.1.5.1.8. Exit Status¶
- 0
The message was rewritten and advanced (or the subcommand succeeded).
- 1
An error occurred (misconfiguration, the message is not in the expected state, or a database error). The reason is written to the log.
70.1.5.1.9. Examples¶
Show what a sender is rewritten to:
pepsi-stage-srs -c /etc/pepsi/pepsi.conf forward alice@origin.example
Decode a returned bounce address:
pepsi-stage-srs -c /etc/pepsi/pepsi.conf reverse 'SRS0=HHHH=TT=origin.example=alice@srs.example.org'
70.1.5.1.10. See Also¶
pepsi-config(1), pepsi-stage-relay-to-smarthost(1), pepsi-stage-relay-to-internet(1), pepsi-stage-bounce(1), pepsi-stage-dkim-sign(1), pepsi-dispatch(1), pepsi-ingress(1), pepsi.conf(5), pepsi.state(7), pepsi-setup(1)
70.1.5.1.11. Bugs¶
Report bugs to the Pepsi issue tracker.