22. pepsi-ingress

The inbound SMTP server (MTA) and the entry point of the pipeline.

22.1. Role

pepsi-ingress runs the SMTP server that receives mail, authenticates it at the boundary, and stores each accepted message as one pepsi.ingress 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).

22.2. Features

22.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_SIZE552), PIPELINING, ENHANCEDSTATUSCODES, 8BITMIME (RFC 6152), SMTPUTF8 (RFC 6531) and DSN (RFC 3461).

  • Accepts mail only for ACCEPTED_DOMAINS (others → 550 relaying); always accepts the domainless <Postmaster> (RFC 5321 §4.5.1).

  • Durable acceptance: returns 250 only after the row commits; a database outage yields a transient 451.

  • Connection concurrency bounded by MAX_CONNECTIONS and a MAX_OPEN_SOCKETS file-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 hung STARTTLS handshake.

  • 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_LINE caps are memory-exhaustion guards only — a line with no terminator that grows past the cap drops the connection — not conformance enforcement.

22.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 type SMTP/ESMTP/ESMTPS (RFC 3848) and the time; a for clause is added for single-recipient transactions. For an encrypted session the negotiated TLS version and cipher are appended as a (version=… cipher=…) comment after the ESMTPS keyword (RFC 8314 §4.3).

22.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 HOSTNAME as authserv-id; the verdicts are also stored under state.auth (spf/dkim/dmarc/arc).

  • Fail-open: only a definite DMARC failure under DMARC_ENFORCE rejects (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.

22.2.4. DSN intake (RFC 3461)

  • Validates and stores RET/ENVID (MAIL FROM) and NOTIFY/ORCPT (RCPT TO) under state.dsn; malformed values are rejected 501.

22.2.5. Internationalised / 8-bit intake

  • Accepts raw 8-bit bodies and UTF-8 headers/envelope; records the BODY= declaration under state.origin.body_8bit. BINARYMIME is rejected (501). Per-hop re-advertising/downgrading happens later in the relay stages.

22.2.6. SRS reverse decode

  • A recipient in SRS_DOMAIN whose 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.

22.2.7. Storage and notification

  • Stores the message split into headers and body columns, with the envelope, parsed From:/Subject: and the verdicts; inserts at stage = init / status = pending and issues NOTIFY ingress.

22.3. Configuration

Read from [pepsi-ingress] (acceptance policy and DNS), the [pepsi-ingress-listener-*] sockets, the shared [pepsi-postgres], [pepsi] and [pepsi-srs] sections. Full reference: pepsi.conf(5) and Configuration.

22.4. Outputs to the pipeline

Seeds the row’s state with origin (SMTP provenance) and, when requested, dsn (RFC 3461 parameters). See Architecture for the state model.

22.5. See also

pepsi-dispatch, pepsi-stage-arc, pepsi-stage-srs, Supported Features, pepsi-ingress(1), pepsi.conf(5).