November 2025 · POWERMTA TECHNICAL REFERENCE

PowerMTA DKIM Signing Configuration — Key Generation, DNS Setup, Multi-Domain, and Key Rotation

November 2025 PowerMTA 6.x PowerMTA DKIM Signing

DKIM (DomainKeys Identified Mail) signing is a required component of any production email infrastructure. Gmail's 2024 bulk sender requirements mandate DKIM for all senders over 5,000 daily messages. Microsoft enforces DMARC which relies on DKIM alignment. Yahoo requires DKIM for FBL configuration enrollment. Beyond these mandatory requirements, DKIM is one of the core signals that ISPs use to build sender reputation — messages signed with a consistent key from a domain with clean reputation receive preferential treatment over unsigned messages from the same IP.

Section 1

How DKIM Signing Works in PowerMTA

PowerMTA performs DKIM signing at message acceptance time — when a message is injected via SMTP and accepted into the spool. The signing operation adds a DKIM-Signature header to the message before it enters the delivery queue. The private key used for signing is stored on disk; the corresponding public key is published in DNS and used by receiving MTAs to verify the signature.

# DKIM flow:
# 1. Message injected into PowerMTA via SMTP
# 2. PowerMTA reads private key from /etc/pmta/dkim/yourdomain.private
# 3. Computes cryptographic hash of specified headers + message body
# 4. Signs hash with private key → DKIM-Signature header added to message
# 5. Message enters delivery queue with DKIM-Signature attached
# 6. Receiving MTA retrieves public key from DNS: s1._domainkey.yourdomain.com
# 7. Verifies signature — result: dkim=pass or dkim=fail in Authentication-Results

# The signing domain must match the From: domain for DMARC alignment configuration
# from: noreply@yourdomain.com + d=yourdomain.com in DKIM-Signature = aligned
Section 2

DKIM Key Generation

# Generate 2048-bit RSA DKIM key (recommended standard)
mkdir -p /etc/pmta/dkim
openssl genrsa -out /etc/pmta/dkim/yourdomain.private 2048

# Extract public key for DNS publication
openssl rsa -in /etc/pmta/dkim/yourdomain.private -pubout -out /etc/pmta/dkim/yourdomain.public

# Format public key for DNS TXT record
# Remove the header/footer lines and newlines:
grep -v "^-" /etc/pmta/dkim/yourdomain.public | tr -d '\n'

# Set correct permissions — private key must be readable by pmta user
chmod 640 /etc/pmta/dkim/yourdomain.private
chown root:pmta /etc/pmta/dkim/yourdomain.private

# Verify key can be read
pmta check-dkim --domain=yourdomain.com --selector=s1
# Should return: DKIM key OK — 2048 bits
Section 3

DNS TXT Record Publication

# DNS TXT record format for DKIM public key
# Record name: [selector]._domainkey.[domain]
# Example: s1._domainkey.yourdomain.com

# TXT record value format:
"v=DKIM1; k=rsa; p=[BASE64_PUBLIC_KEY]"

# Full example DNS record:
s1._domainkey.yourdomain.com. 3600 IN TXT "v=DKIM1; k=rsa; p=MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA..."

# Verify DNS publication:
dig TXT s1._domainkey.yourdomain.com
# Should return the TXT record with your public key

# Test DKIM via external tool (mxtoolbox.com/dkim.aspx)
# Or send a test message and check the Authentication-Results header:
# Authentication-Results: mx.google.com; dkim=pass header.d=yourdomain.com
Section 4

PowerMTA DKIM Configuration

# DKIM configuration in virtual-mta block (signs all messages from this virtual MTA)
<virtual MTA pool configuration-ip-1>
    smtp-source-host 185.x.x.10 mail1.yourdomain.com
    dkim-sign domain="yourdomain.com" \
              key-file="/etc/pmta/dkim/yourdomain.private" \
              selector="s1" \
              header-list="From:To:Subject:Date:Message-ID:Content-Type:MIME-Version"


# Domain-level override (useful if different domains need different keys)

    # Override DKIM for Gmail — use Gmail-specific selector if desired
    dkim-sign domain="yourdomain.com" \
              key-file="/etc/pmta/dkim/yourdomain.private" \
              selector="s1"


# header-list — specify which headers are included in the DKIM signature
# Minimum: From:To:Subject:Date:Message-ID
# Recommended extended: From:To:Subject:Date:Message-ID:Content-Type:MIME-Version:Reply-To
Section 5

Multi-Domain and Multi-Key Configuration

# Different DKIM key per brand / sending domain

    smtp-source-host 185.x.x.10 mail1.brand-a.com
    dkim-sign domain="brand-a.com" \
              key-file="/etc/pmta/dkim/brand-a.private" \
              selector="s1"



    smtp-source-host 185.x.x.20 mail1.brand-b.com
    dkim-sign domain="brand-b.com" \
              key-file="/etc/pmta/dkim/brand-b.private" \
              selector="s1"


# Subdomain signing (sending from notifications.yourdomain.com)

    smtp-source-host 185.x.x.30 notif1.yourdomain.com
    dkim-sign domain="notifications.yourdomain.com" \
              key-file="/etc/pmta/dkim/notifications-yourdomain.private" \
              selector="n1"

# DNS record: n1._domainkey.notifications.yourdomain.com TXT "v=DKIM1; k=rsa; p=..."
# DMARC alignment: From: domain must match signing domain
# For From: alerts@notifications.yourdomain.com → d=notifications.yourdomain.com
Section 6

Verifying DKIM Signatures in Production

# Method 1: Check Authentication-Results header in received messages
# Send a test to a Gmail account and inspect the raw headers:
# Authentication-Results: mx.google.com;
#   dkim=pass header.i=@yourdomain.com header.s=s1 header.b=AbCdEfGh

# Method 2: Check PowerMTA accounting log format
# DKIM result appears in the accounting log dkim field
grep "dkim" /var/log/pmta/accounting-YYYYMMDD.csv | head -5

# Method 3: Use MXToolbox DKIM validator
# https://mxtoolbox.com/dkim.aspx
# Enter: domain=yourdomain.com, selector=s1

# Common DKIM failures:
# dkim=fail (body hash mismatch) — message body modified in transit
# dkim=fail (signature expired) — sending time wrong / signature-expiry too short
# dkim=temperror — DNS lookup failure for public key record
# dkim=none — signing not configured or signature header missing
Section 7

DKIM key rotation Without Downtime

# Key rotation procedure — zero-downtime approach

# Step 1: Generate new key with new selector
openssl genrsa -out /etc/pmta/dkim/yourdomain-s2.private 2048
chmod 640 /etc/pmta/dkim/yourdomain-s2.private && chown root:pmta /etc/pmta/dkim/yourdomain-s2.private

# Step 2: Publish new public key in DNS
# s2._domainkey.yourdomain.com TXT "v=DKIM1; k=rsa; p=[NEW_PUBLIC_KEY]"
# Wait for DNS propagation (24-48 hours)

# Step 3: Update PowerMTA config to use new selector

    dkim-sign domain="yourdomain.com" \
              key-file="/etc/pmta/dkim/yourdomain-s2.private" \
              selector="s2"    # Changed from s1 to s2


pmta reload  # Apply new signing configuration

# Step 4: Keep old s1 DNS record for 7 days
# Messages signed with s1 during the transition are still valid
# After 7 days: remove s1._domainkey.yourdomain.com DNS record
# After 30 days: delete old private key file
FAQ

Frequently Asked Questions

What DKIM key size does PowerMTA support? +
Can PowerMTA sign with multiple DKIM keys for different domains? +
How do I rotate DKIM keys in PowerMTA without downtime? +
What headers should be included in the DKIM signature? +
Does DKIM signing affect PowerMTA performance? +

Operating PowerMTA at production volume?

We manage PowerMTA environments for high-volume senders — configuration, IP warming schedule, daily reputation monitoring, and operational response. Fully managed. No self-service.

Need a Managed PowerMTA Environment?

Cloud Server for Email operates fully managed PowerMTA infrastructure from EU-based dedicated servers. Daily monitoring, per-ISP domain block optimization, IP warming management, and incident response included.

Need PowerMTA support?

Our team works with PowerMTA daily. Contact us for a technical consultation on your specific configuration.