70.1.38. pepsi-tlsrpt¶
SMTP TLS Reporting (RFC 8460) daily reports
- Manual section:
1
70.1.38.1.1. Name¶
pepsi-tlsrpt - daily SMTP TLS Reporting (RFC 8460) aggregate reports.
70.1.38.1.2. Synopsis¶
pepsi-tlsrpt [GLOBAL-OPTIONS] report [–date YYYY-MM-DD] [–dry-run]
pepsi-tlsrpt [GLOBAL-OPTIONS] prune [–older-than DAYS]
70.1.38.1.3. Description¶
pepsi-tlsrpt is the sender side of SMTP TLS Reporting (RFC 8460). As Pepsi
delivers outbound mail, the relay stages
(pepsi-stage-relay-to-internet(1) and pepsi-stage-relay-to-smarthost(1))
record the outcome of each TLS session — a success, or a classified failure
(starttls-not-supported, certificate-host-mismatch,
certificate-expired, certificate-not-trusted, validation-failure,
sts-policy-invalid) — as an aggregate counter in the pepsi.tls_session
table, keyed by UTC day, recipient (policy) domain, applied policy type
(tlsa/sts/no-policy-found), MX host and result. This recording is
enabled by [pepsi-tlsrpt] SEND_REPORTS and is skipped for a report message
itself (the state.tlsrpt loop guard), so a report that hits a TLS error never
spawns a report about a report.
Run once a day from cron, pepsi-tlsrpt report compiles a day’s counters into
one RFC 8460 aggregate report per recipient domain, looks up that domain’s
advertised reporting address (the rua field of its _smtp._tls TXT record)
and ships the gzip-compressed JSON report there: by e-mail for a mailto:
target (the report is injected into the pipeline at REPORT_STAGE so it is
DKIM-signed and relayed like any other message), or by HTTPS POST (with
Content-Type: application/tlsrpt+gzip) for an https: target. Once a
domain’s report is shipped, that day’s counters for it are deleted, so re-running
for the same day is safe.
It connects to the shared database through the [pepsi-postgres] section and
is configured by [pepsi-tlsrpt] (see pepsi.conf(5)). It is not
a stage. Being a cron job it is normally started as root, in which case it
continues as the pepsi service account; see Running as root.
The advertising half — publishing our own _smtp._tls TXT record so other
senders report their TLS results toward our domains to us — is handled by
pepsi-setup(1), which prints the record from [pepsi-tlsrpt] RUA.
70.1.38.1.4. Commands¶
- report [–date YYYY-MM-DD] [–dry-run]
Compile and ship the reports for one UTC day, defaulting to yesterday.
- –date YYYY-MM-DD
Report on this UTC day instead of yesterday.
- –dry-run
Print each report’s JSON to standard output instead of sending it, and retain the counters (nothing is deleted). Useful for inspection.
- prune [–older-than DAYS]
Delete
pepsi.tls_sessioncounters older than the retention window. With no flag the window is[pepsi-tlsrpt] RETAIN_DAYS(default 7). Reported days are already cleared by report; this only sweeps days that were never reported (e.g. a domain that advertises norua).- –older-than DAYS
Override the retention window for this run.
70.1.38.1.5. Running as root¶
Pepsi gives every component its own PostgreSQL role, authenticated over the local
socket by the operating-system account it runs as, and root is deliberately
not one of them — which matters here because the daily job normally runs from
root’s crontab. Rather than fail to connect, the tool detects that it was
started as root and becomes the unprivileged pepsi service account —
which owns pepsi.tls_session and may inject the report messages — before it
connects. A crontab entry therefore needs no sudo -u pepsi.
The configuration file (and any @inline-secret@ fragment it references) is
read before the switch, so a root-only configuration is still loaded normally.
If the pepsi account does not exist — an uninstalled source tree, a test rig —
the identity is left untouched, a warning is logged, and the connection is
attempted as the invoking user, so a setup in which root can reach the
database keeps working.
70.1.38.1.6. Global Options¶
These global options precede the subcommand (a trailing flag is rejected).
- -c FILE, –config FILE
Read the configuration from FILE instead of searching the default locations.
- -L LOGLEVEL, –log LOGLEVEL
Set the logging verbosity. LOGLEVEL is one of
error,warn,info,debugortrace(default:info).- -v, –verbose
Show log messages from all sources, including third-party libraries.
- -h, –help
Print a usage summary and exit.
- -V, –version
Print the version and exit.
70.1.38.1.7. Exit Status¶
- 0
Successful completion. Per-domain delivery problems (a lookup failure, an unreachable HTTPS endpoint) are logged and the run continues; the affected day’s counters are retained for the next run.
- 1
An error occurred: a malformed configuration, a missing required option (
REPORT_FROM), or a failed database connection or query.
70.1.38.1.8. Examples¶
Send yesterday’s reports (typical cron invocation):
pepsi-tlsrpt -c /etc/pepsi/pepsi.conf report
Inspect what would be sent for a specific day without sending:
pepsi-tlsrpt -c /etc/pepsi/pepsi.conf report --date 2026-06-14 --dry-run
Prune counters older than 30 days:
pepsi-tlsrpt -c /etc/pepsi/pepsi.conf prune --older-than 30
A daily crontab entry (after midnight UTC, reporting the day just ended):
17 1 * * * pepsi pepsi-tlsrpt -c /etc/pepsi/pepsi.conf report && pepsi-tlsrpt -c /etc/pepsi/pepsi.conf prune
70.1.38.1.9. See Also¶
pepsi-setup(1), pepsi.conf(5), pepsi-stage-relay-to-internet(1), pepsi-stage-relay-to-smarthost(1), pepsi-config(1)
70.1.38.1.10. Bugs¶
Report bugs to the Pepsi issue tracker.