28. pepsi-ingress¶
The inbound SMTP server (MTA) and the entry point of the pipeline.
28.1. Role¶
pepsi-ingress runs the SMTP server that receives mail, authenticates it at
the boundary, and stores each accepted message as one pepsi.workqueue row at
stage = init before notifying the dispatcher. It is the only component that
talks to external sending clients; everything downstream operates on the stored
row. The exhaustive option reference is pepsi-ingress(1) /
pepsi.conf(5).
28.2. Features¶
28.2.1. Reception (RFC 5321)¶
SMTP/ESMTP server with per-listener transport: cleartext, STARTTLS upgrade (RFC 3207) and implicit TLS (RFC 8314); listeners bind TCP, UNIX or systemd-activated sockets.
Message bodies via DATA or CHUNKING/BDAT (RFC 3030).
Advertises SIZE (enforcing
MAX_MESSAGE_SIZE→552), PIPELINING, ENHANCEDSTATUSCODES, 8BITMIME (RFC 6152), SMTPUTF8 (RFC 6531) and DSN (RFC 3461).Accepts mail only for
ACCEPTED_DOMAINS(others →550relaying); always accepts the domainless<Postmaster>(RFC 5321 §4.5.1).Durable acceptance: returns
250only after the row commits; a database outage yields a transient451.Connection concurrency bounded by
MAX_CONNECTIONSand aMAX_OPEN_SOCKETSfile-descriptor budget; per-source rate limiting (CONN_RATE_PER_SECOND) and, under pressure, eviction of the longest-idle connection in the greediest source range guard against connection abuse.Per-command read timeouts (
COMMAND_TIMEOUT/DATA_TIMEOUT, RFC 5321 §4.5.3.2) close slow or stalled sessions, including a hungSTARTTLShandshake.Lenient line lengths. The RFC 5321 §4.5.3.1.4/§4.5.3.1.6 limits (512-octet command lines, 1000-octet text lines) bind senders; per the same section’s guidance that receivers be liberal, ingress accepts longer lines. The internal
MAX_CMD_LINE/MAX_DATA_LINEcaps are memory-exhaustion guards only — a line with no terminator that grows past the cap drops the connection — not conformance enforcement.
28.2.2. Trace header¶
Prepends an RFC 5321 §4.4
Received:header before authentication (so the ARC seal covers it), recording the client (HELO/EHLO, reverse-DNS, IP), this server, the transmission typeSMTP/ESMTP/ESMTPS/ESMTPA/ESMTPSA(RFC 3848) and the time; aforclause is added for single-recipient transactions. For an encrypted session the negotiated TLS version and cipher are appended as a(version=… cipher=…)comment after theESMTPSkeyword (RFC 8314 §4.3).
28.2.3. Authentication (recorded at the boundary)¶
SPF (RFC 7208), DKIM verification (RFC 6376 / RFC 8463) and DMARC (RFC 7489), plus iprev/FCrDNS (RFC 8601).
Prepends an Authentication-Results header (RFC 8601) with the ingress
HOSTNAMEasauthserv-id; the verdicts are also stored understate.auth(spf/dkim/dmarc/arc).Fail-open: only a definite DMARC failure under
DMARC_ENFORCErejects (550); DNS/parse errors are recorded and the mail accepted.ARC verify/seal is not done here — it is the pepsi-stage-arc stage, so ingress holds no ARC keys. Ingress records the session context the ARC stage needs under
state.origin.
28.2.4. Submission (RFC 6409)¶
A listener with
SUBMISSION = yesmakes client authentication mandatory and applies the submission fixups (a missingDate:/Message-ID:is added). Any of four mechanisms authenticates a session: a peer address inMYNETWORKS, UNIX-socket peer credentials (AUTH_PEERCRED, the default on a UNIX listener and rejected on TCP), a SASLAUTHexchange (SASL_TYPE = dovecot, offered only over TLS) or a pinned TLS client certificate (TLS_AUTH_CLIENT). An authenticated session is recorded withstate.local_origin = true;USERNAME_MAPdecides which addresses the authenticated identity may send as.Submission requires a TLS-protected
MODE, except on a local UNIX-domain socket, where the kernel supplies the identity and there is no transport to protect.The local submission socket used by pepsi-sendmail needs no listener section at all: ingress synthesises one for
[pepsi-sendmail] SOCKETunless an explicit section already serves that path.SOCKET = noneis the only switch that turns it off; failing to bind it is fatal.
28.2.5. Mailbox quota¶
When a mailbox quota policy is in force, a recipient whose measured usage is over its limit is refused at
RCPT(452 4.2.2or552 5.2.2, per[pepsi] MAILBOX_OVER_QUOTA). Ingress only ever readspepsi.mailbox_quota, and refuses only on a measurement younger thanMAILBOX_QUOTA_MAX_AGE; every uncertainty (no row, a stale or absent measurement, a database error) accepts.MAILBOX_QUOTA_RCPT_CHECK = no(defaultyes) moves all enforcement to delivery time. See pepsi-quota.
28.2.6. DSN intake (RFC 3461)¶
Validates and stores
RET/ENVID(MAIL FROM) andNOTIFY/ORCPT(RCPT TO) understate.dsn; malformed values are rejected501.
28.2.7. Internationalised / 8-bit intake¶
Accepts raw 8-bit bodies and UTF-8 headers/envelope; records the
BODY=declaration understate.origin.body_8bit.BINARYMIMEis rejected (501). Per-hop re-advertising/downgrading happens later in the relay stages.
28.2.8. SRS reverse decode¶
A recipient in
SRS_DOMAINwhose local-part is a valid SRS token is decoded to the original sender and accepted for relay there (even outside served domains — the HMAC authorises it); a forged/expired token is rejected (550). This is how bounces return to original senders. See pepsi-stage-srs.
28.2.9. Storage and notification¶
Stores the message split into
headersandbodycolumns, with the envelope, parsedFrom:/Subject:and the verdicts; inserts atstage = init/status = pending.Wakes the dispatcher out of band and coalesced, at most once per
DISPATCH_WAKE_INTERVAL(default 5 ms), after the row has committed. The admission transaction itself carries noNOTIFY: PostgreSQL holds a database-wide lock from the moment a transaction queues a notification until it commits, so a notifying insert cannot group-commit. A lost wake-up costs only the dispatcher’sPOLL_INTERVALof latency.
28.3. Configuration¶
Read from [pepsi-ingress] (acceptance policy, limits, timeouts, DNS), the
[pepsi-ingress-listener-*] sockets (transport and client authentication,
per listener), and the shared
[pepsi-postgres], [pepsi], [pepsi-sendmail] and [pepsi-srs]
sections. The database configuration overlay is applied on top. Full reference:
pepsi.conf(5) and Configuration.
28.4. Outputs to the pipeline¶
Seeds the row’s state with origin (SMTP provenance), auth (the
SPF/DKIM/DMARC verdicts), local_origin, spam = false for a message whose
sole recipient is <Postmaster>, and, when requested, dsn (RFC 3461
parameters). See Architecture for the state model.
28.5. See also¶
pepsi-dispatch, pepsi-stage-arc, pepsi-stage-srs, Supported Features, pepsi-ingress(1), pepsi.conf(5).