postal
Simple and modern NixOS-powered personal mail server
rad:z4BpZanfWMDaFcyZYqQtkAKjQDPT
Visibility
public
Delegates
did:key:z6MkrQYcTUznMypUnPaM7SYJcL94idTSa9xNFoMvC1QAYMiD
Default branch
master → e00df6ea70f2412130810763b6a923d25c2bd7a2 (Thu Aug 21 12:17:19 2025)
Threshold
1
README.md
# Postal

Simple NixOS-powered personal mail server.


## Basic server setup

1)  **Decide on a FDQDN for your mail server** , e.g. `smtp.example.net`
1)  **Create an A record for your mail server's FQDN** and point it to it's
    public IP.
    > The FQDN plays an important role in the SMTP protocol. It's a good idea
    > to setup a reverse `PTR` record from your server's primary IP to the FQDN.


## Adding a new domain

Here we're adding the `example.com` domain to a server with FQDN
`smtp.example.net`:

1)  **Add the domain to `postal.domains`**

    E.g. `config.postal.domains = [ "example.com" ];`
1)  **Publish a SPF `TXT` record** for your domain that includes your server
    and disallows others. See http://www.open-spf.org/ for details.

    E.g. `example.com.  1800 IN TXT "v=spf1 mx a -all"`
1)  **Generate & publish your [DKIM](https://en.wikipedia.org/wiki/DomainKeys_Identified_Mail) public keys**:
    1)  Generate a DKIM signing keypair for the domain. The default configuration
        uses the fqdn of the mail server as the DKIM selector (passed to
        `opendkim-genkey` the `-s` argument), substituting `.` with `_` (e.g.
        `smtp_example_net`).

        E.g. `opendkim-genkey -b 2048  -d example.com -s $(hostname -f|sed 's/\./_/g')`
    1)  Copy the resulting private key, with the filename `<selector>.private`, to
        `/var/lib/opendkim/keys/` and give *only* opendkim permission to read it.

        E.g. `sudo install -o opendkim -g milters -m 0400 -t /var/lib/opendkim/keys $(hostname -f|sed 's/\./_/g').private`
    1)  Publish the resulting public key in your DNS, under
        `<selector>._domainkey.example.com`.
        The public key can be found in the form of a (bind format) DNS record in
        `<selector>.txt`.

        E.g. `cat $(hostname -f|sed 's/\./_/g').txt`
1)  **Publish a [DMARC](https://en.wikipedia.org/wiki/DMARC) TXT record** under
    `_dmarc.example.com` that tells receivers your preferred SPF & DKIM policy. The
    following example asks receivers to reject 100% of mail that doesn't pass SPF &
    DKIM check, sending an *aggregate* report once a day to
    dmarcreports@example.com:

    `_dmarc.example.com.    1800 IN TXT v=DMARC1;p=reject;pct=100;rua=mailto:dmarcreports@example.com`
1)  **Publish a MTA-STS CNAME record** under `mta-sts.example.com` and point it
    to your mail server's FQDN.

    E.g. `mta-sts.example.com.  1800 IN CNAME smtp.example.net.`
1)  **Publish a MTA_STS TXT record** under `_mta-sts.example.com`. It's `id` value should
    increase when the FQDN of your mail server changes because then the previous
    STS config served from *https://mta-sts.example.com/.well-known/mta-sts.txt* is
    out-of-date).

    E.g. `_mta-sts.example.com.     1800 IN TXT "v=STSv1; id=202508180200Z"`