When running an email service that handles multiple client domains, the standard DKIM setup fails because:
- Gmail and other providers validate DKIM signatures against the
From:
domain - Traditional configs only sign for your primary domain's DNS records
- Postfix's default DKIM implementation doesn't handle dynamic selector generation
We need three key components working together:
Postfix → OpenDKIM → Dynamic DNS Records
1. Modify OpenDKIM Configuration
Edit /etc/opendkim.conf
:
# KeyTable and SigningTable need to be files (not regex)
KeyTable /etc/opendkim/keytable
SigningTable /etc/opendkim/signingtable
# Enable loose signing mode
RequireSafeKeys no
ExternalIgnoreList refile:/etc/opendkim/trustedhosts
InternalHosts refile:/etc/opendkim/trustedhosts
2. Create Dynamic Key Management Files
/etc/opendkim/keytable
:
# Format: domain selector:path/to/key
* default:/etc/opendkim/keys/default.private
client1.com client1:/etc/opendkim/keys/client1.private
client2.net client2:/etc/opendkim/keys/client2.private
/etc/opendkim/signingtable
:
# Wildcard catch-all first
* default
# Then specific domains
@client1.com client1
@client2.net client2
3. Generate DKIM Keys for Each Domain
For each client domain:
opendkim-genkey -b 2048 -s client1 -d client1.com
mv client1.private /etc/opendkim/keys/
chown opendkim:opendkim /etc/opendkim/keys/client1.*
4. Configure Postfix Integration
Edit /etc/postfix/main.cf
:
# DKIM milter configuration
milter_default_action = accept
milter_protocol = 6
smtpd_milters = inet:localhost:8891
non_smtpd_milters = inet:localhost:8891
For a newsletter service, you'll need a script to handle new clients:
#!/bin/bash
# add_dkim_client.sh
DOMAIN=$1
SELECTOR="s${RANDOM}"
opendkim-genkey -b 2048 -s $SELECTOR -d $DOMAIN
mv $SELECTOR.private /etc/opendkim/keys/$SELECTOR.private
chown opendkim:opendkim /etc/opendkim/keys/$SELECTOR.private
echo "$DOMAIN $SELECTOR:/etc/opendkim/keys/$SELECTOR.private" >> /etc/opendkim/keytable
echo "@$DOMAIN $SELECTOR" >> /etc/opendkim/signingtable
systemctl restart opendkim postfix
echo "DKIM record for DNS (TXT):"
cat $SELECTOR.txt
Use these commands to test your setup:
# Verify OpenDKIM is running
sudo systemctl status opendkim
# Test email signing
echo "Test message" | mail -s "DKIM Test" -a "From: test@clientdomain.com" recipient@example.com
# Verify DKIM signature (on receiving server)
apt install opendkim-tools
opendkim-testkey -d clientdomain.com -s client1 -k /etc/opendkim/keys/client1.private
- DNS Propagation: New TXT records may take 24-48 hours
- Key Permissions: Ensure
opendkim
user can read private keys - Selector Mismatch: The signing table must match the key table exactly
- SPF Alignment: Combine with proper SPF records for DMARC compliance
For high-volume services:
- Implement a Redis cache for key lookups
- Use a database-backed signing table instead of flat files
- Monitor signing failures with
opendkim-stats
- Rotate keys quarterly using your automation script
Remember to update your DNS records whenever adding new client domains or rotating keys. Each client will need to add the generated DKIM TXT record to their domain's DNS.
When setting up DKIM for a multi-tenant email service, we need the server to properly sign messages regardless of the sender's domain in the From header. The default configuration typically only signs emails matching the server's primary domain.
First, edit the main DKIM configuration file:
# /etc/dkim-filter.conf
Domain *
KeyFile /etc/dkimkeys/%d/mail.private
Selector mail
Socket inet:8891@localhost
Then modify the Postfix configuration:
# /etc/postfix/main.cf
milter_default_action = accept
milter_protocol = 2
smtpd_milters = inet:localhost:8891
non_smtpd_milters = inet:localhost:8891
For each client domain, you'll need to create a TXT record:
mail._domainkey.clientdomain.com. IN TXT "v=DKIM1; k=rsa; p=MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQC..."
Here's a bash script to generate keys for new domains:
#!/bin/bash
DOMAIN=$1
mkdir -p /etc/dkimkeys/$DOMAIN
cd /etc/dkimkeys/$DOMAIN
openssl genrsa -out mail.private 1024
openssl rsa -in mail.private -out mail.public -pubout -outform PEM
To test your configuration:
telnet localhost 25
EHLO example.com
MAIL FROM:<test@clientdomain.com>
RCPT TO:<check-auth@verifier.port25.com>
DATA
Subject: DKIM Test
From: Test User <test@clientdomain.com>
To: Tester <check-auth@verifier.port25.com>
This is a test message
.
If verification fails:
- Check DNS propagation with
dig TXT mail._domainkey.clientdomain.com
- Verify the private key matches the public key in DNS
- Ensure proper permissions on key files (600)
- Check mail logs:
tail -f /var/log/mail.log