# How to authenticate mail from a custom or self-hosted server

On this page, we provide instructions on how to authenticate mail sent from your own mail server or application without relying on a third-party service like Google or Microsoft.

This applies to setups such as:

- Mail servers: [Postfix](https://www.postfix.org/), [Sendmail](https://en.wikipedia.org/wiki/Sendmail), [Exim](https://www.exim.org/)
- Self-hosted suites: [Mailcow](https://mailcow.email/), [Mail-in-a-Box](https://mailinabox.email/), [Stalwart](https://stalw.art/)
- Direct application mail: Web servers sending via PHP `mail()`, Python, Node.js, or cron scripts
- On-premises infrastructure: Microsoft Exchange server, internal relays, and network appliances

Here is how to set up DKIM, SPF, and DMARC for your own server.

## Allow list your server IP addresses in SPF

Find your server’s public IPv4 (and IPv6, if supported) address, and add it using the ip4 or ip6 mechanism like so:

Block Field

If your mail server both sends and receives mail you can **allow list your receiving server** to send mail as well without repeating IP addresses in DNS:

Block Field

## Set up DKIM signing on your server

DKIM works with key pairs: your mail server holds a private key to cryptographically sign outgoing messages, and you publish the corresponding public key in a TXT record at `<selector>._domainkey.example.com` so inbox providers can verify that signature. The selector acts as an identifier to differentiate between multiple DKIM key pairs.

Because every mail server handles key generation and signing differently, refer to the setup steps for your specific software.

<details>
<summary>Set up DKIM with Postfix and Sendmail</summary>

Postfix and Sendmail don’t sign DKIM keys natively. Use a milter (mail filter) to handle key generation, signing, and DNS record formatting:

- [Rspamd](https://docs.rspamd.com/tutorials/dkim_signing_guide/) (recommended for modern setups)
- [OpenDKIM](http://www.opendkim.org/)
</details>

<details>
<summary>Set up DKIM with Mailcow, Stalwart, or Mail-in-a-Box</summary>

Use the admin interface or CLI tool to generate the key pair and retrieve the exact DNS TXT records to publish.
</details>

<details>
<summary>Set up DKIM with Exim or application libraries</summary>

If you use Exim or send mail directly from code libraries (like PHPMailer or Nodemailer), you provide your own key pair:

1. Generate an RSA key pair (using OpenSSL or your library’s built-in key generator).
2. Choose a selector (such as `default`) and provide the selector and private key in your code or Exim config.
3. Publish the public key in a DNS TXT record at `<selector>._domainkey.example.com`.
</details>

## Align your domain for DMARC

For outgoing mail to be considered DMARC compliant, the [header from](https://dmarced.eu/en/learn/basics/concepts#header-from) domain must match:

- The domain in your DKIM signature (`d`)
- The domain in your [envelope from](https://dmarced.eu/en/learn/basics/concepts#envelope-from) used when your mail server sends mail via SMTP

Even if your server config looks right, real-world delivery can still run into subtle alignment issues. The only way to know for sure is to ask [receiving providers](https://dmarced.eu/en/learn/basics/concepts#receiving-provider) for feedback using a monitoring DMARC record.

Block Field

## Set up reverse DNS

While not strictly part of DMARC, most receiving providers will reject or quarantine mail sent from servers without valid reverse DNS.

[Forward-confirmed reverse DNS (FCrDNS)](https://en.wikipedia.org/wiki/Forward-confirmed_reverse_DNS) proves your server is who it claims to be:

1. Forward lookup: Your server’s hostname (such as `mail.example.com`) points to your server’s IP address via an `A` or `AAAA` record.
2. Reverse lookup: Your server’s IP address points back to that same hostname via a `PTR` record.

Because IP addresses belong to the network provider, you configure `PTR` records through your server hosting provider or ISP rather than your domain registrar. Look for “Reverse DNS” or “PTR” settings in your server provider’s control panel, and set the value to match your mail server’s fully qualified hostname (the same name your server uses in its `HELO`/`EHLO` greeting).