
Self-Hosting Mail Behind Residential Internet Without Pretending the Network Is Reliable
Self-hosting mail is mostly a reliability and reputation problem. Running an SMTP server is straightforward. Receiving mail consistently, authenticating it correctly, recovering from outages, and proving a migration did not lose attachments is the real project.
My residential connection added a hard constraint: inbound TCP port 25 is filtered before it reaches the home router. Rather than hide that limitation, I designed around it.
Put the unstable boundary behind a queue
A small public VPS runs hardened Postfix as the internet-facing SMTP edge. It accepts mail for an explicit list of domains and recipients, then forwards it to the home platform through a WireGuard tunnel initiated from inside the home network.
The edge is a queue, not the source of truth. If the tunnel or home connection is unavailable, Postfix retains mail and retries. That converts a temporary residential outage from a rejected message into delayed delivery.
The tunnel also carries the outbound path. The edge trusts only the expected private tunnel identity for relay, and normal internet clients cannot use it as an open relay.
Keep the mail core highly available
Inside the cluster, Stalwart runs across three replicas. A highly available PostgreSQL tier stores durable state, and redundant coordination services support application behavior. Roundcube provides separate webmail replicas.
Public mail protocols use dedicated listeners and proxy-aware routing. Internal clients connect through private service paths while still verifying the public certificate name. This avoids weakening TLS validation just because two services share a cluster.
Authentication is part of delivery
SPF, DKIM, and DMARC are deployed together and verified at external receivers. Authenticated submission uses scoped identities. Automatic client configuration is exposed only on the exact paths required by mail clients.
Monitoring checks more than whether a TCP socket opens. Protocol probes validate TLS handshakes and the behavior expected on each endpoint. Certificate expiration, queue failures, database health, and external delivery are separate signals.
Verify migrations with hashes
Mailbox import counts are necessary and insufficient. A system can report the right number of messages while attachments or MIME bodies are damaged.
After importing the legacy mail archives, I exported the destination independently. Message counts, role counts, blob lengths, and SHA-256 hashes matched the source. For another mailbox migration, every exported MIME blob matched byte-for-byte.
That level of verification turns “the import looked okay” into evidence that the stored messages and attachments survived.
Accept the operational cost
Self-hosted mail is not automatically cheaper or simpler than a hosted mailbox. It is worthwhile here because the project exercises public networking, transport security, queueing, high availability, DNS authentication, migration, monitoring, and disaster recovery as one system.
The architectural lesson applies beyond email: when a network boundary is unreliable, place a durable queue at the boundary and verify data after it crosses.
