Opt-In Software Blog

Software, dvelopment, and practical insights

Configure SPF, DKIM, and DMARC for a Linux Mail Server

Read in: English | Русский

If you need to send email from your own domain without using third-party SMTP services, you can rent a Linux VPS. Postfix or Exim are commonly used as the mail transfer agent (MTA).

Before buying a VPS, contact the hosting provider and ask: “Is outbound SMTP port 25 open?” Many hosting providers block it by default to prevent spam. If the port is blocked, sending email directly to remote mail servers may not be possible.


1. Preparation: Network and DNS Settings

To make sure your mail is delivered correctly, you need to configure several basic DNS records for your domain:

  1. Hostname. Set the server hostname to something like mail.yourdomain.com.

  2. A record. Point mail.yourdomain.com to the IP address of your VPS.

  3. MX record. Specify which server handles email for your domain. The record looks like this:

    @ MX 10 mail.yourdomain.com.
  4. PTR record (Reverse DNS). Maps the server’s IP address back to its hostname. It is configured in your VPS provider’s control panel rather than at your domain registrar.

    A PTR record is important for email delivery. Many mail servers check the reverse DNS record of the sending IP address, and a missing or inconsistent PTR record can result in messages being rejected or sent to spam.

    It is recommended to keep the forward and reverse DNS records consistent:

    1.2.3.4 → mail.yourdomain.com
    mail.yourdomain.com → 1.2.3.4

2. Configuring SPF

SPF is a DNS record that specifies which servers are authorized to send email on behalf of your domain.

Create a TXT record:

  • Record type: TXT

  • Host/Name: @ (or leave it empty, depending on your DNS provider)

  • Value:

    v=spf1 ip4:1.2.3.4 ~all

    Replace 1.2.3.4 with the IP address of your server.

What does ~all mean?

~all means SoftFail: messages sent from IP addresses not listed in the SPF record receive a soft-failure result. The receiving server decides how to handle such messages.

After testing your configuration, you can use -all if all legitimate sources that send email for your domain are listed in the SPF record.


3. Generating DKIM Keys with OpenSSL

DKIM is a digital signature mechanism that helps verify the authenticity of the sender and the integrity of an email. The server signs the message with a private key, and the recipient verifies the signature using the public key published in DNS.

To generate a key pair, connect to the server over SSH and run the following commands.

3.1. Generate a 2048-bit private key

openssl genrsa -out dkim.private 2048

3.2. Generate the public key

openssl rsa -in dkim.private -pubout -out dkim.public

3.3. Display the public key

cat dkim.public

The terminal will display something like:

-----BEGIN PUBLIC KEY-----
MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8A...
-----END PUBLIC KEY-----

For the DNS record, take only the Base64-encoded content between the headers and combine it into a single line without spaces or line breaks.

Then create a TXT record named dkim._domainkey (dkim is the selector name).

  • Record type: TXT

  • Host/Name: dkim._domainkey

  • Value:

    v=DKIM1; k=rsa; p=YOUR_COPIED_PUBLIC_KEY

If your DNS provider supports splitting long TXT records into multiple strings, use that option for keys that do not fit into a single string.


4. Connecting DKIM to the Mail Server

Option A: If You Use Exim

In the Exim configuration file (the exact path depends on the distribution and installation method), find the transport responsible for sending mail to external servers. It is usually called remote_smtp.

Example configuration:

remote_smtp:
  driver = smtp
  dkim_domain = yourdomain.com
  dkim_selector = dkim
  dkim_private_key = /etc/exim/dkim.private
  dkim_canon = relaxed

Give the user running Exim permission to read the private key. The username depends on the distribution. For example, some systems use exim, while Debian may use Debian-exim.

Example for a system using the exim user:

chown exim:exim /etc/exim/dkim.private
chmod 600 /etc/exim/dkim.private

Restart the service:

systemctl restart exim4
# or
systemctl restart exim

Make sure that the Exim user actually has access to the private key.


Option B: If You Use Postfix

Postfix uses the external OpenDKIM utility to add DKIM signatures to outgoing messages.

1. Install the packages

apt install opendkim opendkim-tools

2. Configure OpenDKIM

Open /etc/opendkim.conf and add or configure the following settings:

Syslog                 yes
RequiredHeaders        yes
Mode                   sv
SubDomains             no
Socket                 inet:8891@localhost
KeyTable               /etc/opendkim/KeyTable
SigningTable           /etc/opendkim/SigningTable
ExternalIgnoreList     /etc/opendkim/TrustedHosts
InternalHosts          /etc/opendkim/TrustedHosts

3. Connect OpenDKIM to Postfix

Add the following lines to the end of the main Postfix configuration file, /etc/postfix/main.cf:

milter_protocol = 6
milter_default_action = accept
smtpd_milters = inet:localhost:8891
non_smtpd_milters = inet:localhost:8891

4. Configure the OpenDKIM tables

This example uses a single domain and a single DKIM key. The key name in KeyTable is mail._domainkey.yourdomain.com.

/etc/opendkim/KeyTable

This file maps the key name to the domain, selector, and private key path:

mail._domainkey.yourdomain.com yourdomain.com:mail:/etc/opendkim/keys/dkim.private

Here:

  • mail._domainkey.yourdomain.com — the key name in the table.
  • yourdomain.com — the domain that will appear in the DKIM signature (d=).
  • mail — the selector (s=).
  • /etc/opendkim/keys/dkim.private — the path to the private key.

/etc/opendkim/SigningTable

This file maps the sender domain to the key name from KeyTable:

yourdomain.com mail._domainkey.yourdomain.com

If you need to use a pattern for sender addresses from the domain, you can specify:

*@yourdomain.com mail._domainkey.yourdomain.com

The wildcard form requires the corresponding refile: table type to be configured in the SigningTable directive. This guide uses the simple domain-based mapping without refile.

/etc/opendkim/TrustedHosts

Add localhost and the IP address of your server:

127.0.0.1
localhost
1.2.3.4

5. Move the private key and restart the services

Create the directory for the keys:

mkdir -p /etc/opendkim/keys/

Move the private key:

mv dkim.private /etc/opendkim/keys/

Set the owner and permissions:

chown -R opendkim:opendkim /etc/opendkim/
chmod 600 /etc/opendkim/keys/dkim.private

Restart the services:

systemctl restart opendkim postfix

Check their status:

systemctl status opendkim
systemctl status postfix

If necessary, check the OpenDKIM log:

journalctl -u opendkim -n 50 --no-pager

5. Configuring DMARC

DMARC is a mechanism that allows a domain to tell receiving mail servers how to handle messages that fail the required SPF and DKIM checks, including the alignment of the domains involved with the domain in the From header.

Create a TXT record:

  • Record type: TXT

  • Host/Name: _dmarc

  • Initial value:

    v=DMARC1; p=none; rua=mailto:admin@yourdomain.com

What does this mean?

  • p=none — monitoring mode. The domain asks the receiving server not to apply a special action to messages that fail DMARC. You can monitor the results and collect reports.
  • rua=mailto:... — the address to which mail services can send aggregate reports about authentication checks.
  • p=quarantine — asks the receiving server to treat messages that fail DMARC as suspicious, for example by placing them in the spam folder.
  • p=reject — asks the receiving server to reject messages that fail DMARC. The actual action is determined by the receiving server.

After testing and fixing the configuration, you can change the policy from p=none to p=quarantine or p=reject.


6. How to Check DNS Records from the Terminal

You can check whether the DNS settings have been updated using dig or nslookup.

Check SPF

dig yourdomain.com TXT +short

Or:

nslookup -type=TXT yourdomain.com

Check DKIM

The query uses the name of your selector:

dig mail._domainkey.yourdomain.com TXT +short

Or:

nslookup -type=TXT mail._domainkey.yourdomain.com

Check DMARC

dig _dmarc.yourdomain.com TXT +short

Or:

nslookup -type=TXT _dmarc.yourdomain.com

Check PTR (Reverse DNS)

dig -x 1.2.3.4 +short

Or:

nslookup 1.2.3.4

Check the server hostname:

hostname -f

Make sure that the hostname is consistent with the A and PTR records.

The recommended setup is:

Hostname: mail.yourdomain.com
A:        mail.yourdomain.com → 1.2.3.4
PTR:      1.2.3.4 → mail.yourdomain.com

The hostname used by the server and the reverse DNS record should be configured consistently.

Search