opendkim.sh

OpenDKIM installation and configuration for DKIM email signing with Postfix. Generates 2048-bit RSA keys per domain with automatic DNS record output, Postfix milter integration, and support for multi-server deployments.

On This Page

Overview

DKIM (DomainKeys Identified Mail) is an email authentication method that allows the receiving mail server to verify that an email was sent and authorized by the owner of the domain. The Centmin Mod opendkim.sh addon installs and configures OpenDKIM as a Postfix milter, generating 2048-bit RSA signing keys per domain and outputting the DNS TXT record to publish.

The addon is located at /usr/local/src/centminmod/addons/opendkim.sh and is supported on CentOS 7, AlmaLinux 8/9/10, Rocky Linux 8/9/10, and other RHEL-compatible distributions.

Key Features

  • 2048-bit RSA DKIM key generation per domain
  • Automatic selector naming: default2026 (year-based)
  • Postfix milter integration on inet:127.0.0.1:8891
  • Sign & Verify mode (sv) with relaxed/simple canonicalization
  • Automatic DNS TXT record output — ready to copy and paste
  • Key backup to /etc/centminmod/dkim_backups/
  • Force re-generation of keys with --force flag
  • Multi-domain support — run per domain as needed

Email Authentication Stack: DKIM works best alongside SPF and DMARC. Set up an SPF TXT record for your domain and a DMARC policy (_dmarc.yourdomain.com) to form a complete email authentication chain. See the Email Setup Guide for complete SPF, DMARC, and DNS configuration.

Related Guides


Installation

The opendkim.sh addon installs OpenDKIM, configures the Postfix milter, and generates DKIM keys for the server's primary hostname. To install for the server hostname:

bash
# Install opendkim and configure for server hostname
/usr/local/src/centminmod/addons/opendkim.sh

To install and configure DKIM for a specific domain (e.g., a virtual host added via Centmin Mod):

bash
# Install/configure DKIM for a specific domain
addons/opendkim.sh yourdomain.com

The installer will:

  1. Install the opendkim and opendkim-tools packages
  2. Generate a 2048-bit RSA key pair for the domain
  3. Configure /etc/opendkim.conf and the key/signing tables
  4. Configure Postfix to use OpenDKIM as a milter
  5. Enable and start the opendkim service
  6. Print the DNS TXT record to add to your DNS provider

Available Subcommands

Subcommand Description
opendkim.sh [domain] Install & configure DKIM (uses server hostname if no domain given)
opendkim.sh --force [domain] Force regenerate keys for domain (overwrites existing keys)
opendkim.sh check Check OpenDKIM status and display current configuration
opendkim.sh wipe [domain] Remove DKIM keys and config entries for a domain
opendkim.sh clean Clean up temporary files and remove unused config entries

Key Generation

The addon generates 2048-bit RSA keys using opendkim-genkey. The DKIM selector is automatically set to defaultYEAR (e.g., default2026), making it easy to rotate keys annually.

Key Storage Locations

File Purpose
/etc/opendkim/keys/yourdomain.com/default2026 Private signing key (chmod 600, owner opendkim)
/etc/opendkim/keys/yourdomain.com/default2026.txt Public key DNS TXT record (copy to DNS provider)
/etc/centminmod/dkim_backups/ Backup copies of all generated keys

Force Key Regeneration

Use --force to regenerate keys for a domain (e.g., after annual rotation). The old keys are backed up before replacement:

bash
# Force regenerate keys (backs up old keys first)
addons/opendkim.sh --force yourdomain.com

Important: After forcing key regeneration, you must update your DNS TXT record with the new public key and wait for DNS propagation before the new keys become active. Keep the old DNS record live until propagation is confirmed.


DNS TXT Record Setup

After running the addon, a DNS TXT record must be added at your DNS provider. The installer prints the exact record — it is also stored in the .txt file in the key directory.

Record Format

The DNS record name follows the format selector._domainkey.yourdomain.com:

dns zone
# DNS TXT record name (Host/Name field)
default2026._domainkey.yourdomain.com

# DNS TXT record value
"v=DKIM1; h=sha256; k=rsa; p=MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMII..."

Reading the Generated Public Key

View the full DNS TXT record from the key directory:

bash
cat /etc/opendkim/keys/yourdomain.com/default2026.txt

The file output shows the zone file format. When entering into your DNS provider's web UI, combine the quoted string parts into a single value without the leading/trailing quotes on each segment.

DNS Provider Notes: Some providers (Cloudflare, cPanel) automatically handle the zone suffix — enter only default2026._domainkey as the host/name. Other providers require the full FQDN. Check your provider's documentation for the correct format.


Configuration Files

OpenDKIM uses several configuration files managed by the addon:

/etc/opendkim.conf — Main Configuration

Key settings configured by the addon:

/etc/opendkim.conf
Mode                    sv
Canonicalization        relaxed/simple
SignatureAlgorithm      rsa-sha256
Socket                  inet:8891@127.0.0.1
KeyTable                /etc/opendkim/KeyTable
SigningTable            refile:/etc/opendkim/SigningTable
ExternalIgnoreList      refile:/etc/opendkim/TrustedHosts
InternalHosts           refile:/etc/opendkim/TrustedHosts

/etc/opendkim/KeyTable

Maps a key name to the domain, selector, and private key path:

/etc/opendkim/KeyTable
# format: key-name  domain:selector:keyfile
default2026._domainkey.yourdomain.com  yourdomain.com:default2026:/etc/opendkim/keys/yourdomain.com/default2026

/etc/opendkim/SigningTable

Maps domain names to the key table entries that should sign their email:

/etc/opendkim/SigningTable
# format: domain  key-name
yourdomain.com  default2026._domainkey.yourdomain.com

/etc/opendkim/TrustedHosts

Hosts that are trusted to send mail through OpenDKIM without verification (typically localhost and the server itself):

/etc/opendkim/TrustedHosts
127.0.0.1
::1
localhost
yourhostname.yourdomain.com

Postfix Milter Configuration

The addon configures Postfix to pass outgoing mail through the OpenDKIM milter:

bash
# Postfix settings configured automatically
smtpd_milters = inet:127.0.0.1:8891
non_smtpd_milters = inet:127.0.0.1:8891
milter_default_action = accept

Testing & Verification

Check OpenDKIM Status

Use the built-in check subcommand to display current OpenDKIM configuration and service status:

bash
addons/opendkim.sh check

# Check service status directly
systemctl status opendkim

Verify DNS Propagation

After adding the DNS TXT record, verify it has propagated using dig or nslookup. Compare the DNS output against the public key stored at /etc/opendkim/keys/yourdomain.com/default2026.txt:

bash
# Query DNS for the DKIM TXT record
dig +short default2026._domainkey.yourdomain.com TXT

# Expected output (public key will differ)
"v=DKIM1; h=sha256; k=rsa; p=MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMII..."

Test Email Signing

Send a test email and check the received headers for the DKIM-Signature header. You can also use online SPF and DKIM DNS testing tools to verify your records:

  • dmarcian DKIM Inspector — validates your DKIM DNS TXT record and key format
  • MXToolbox — comprehensive email DNS lookup (SPF, DKIM, DMARC, MX records)
  • Kitterman SPF Validator — tests SPF record syntax and DNS lookup limits
  • whatsmydns.net — check DNS propagation across global resolvers
  • learndmarc.com — interactive DMARC testing and analysis
  • addons/opendkim.sh check — built-in Centmin Mod command to verify DKIM DNS records

See the Email Setup — DNS Verification & Testing Tools section for detailed usage of each tool.

bash
# Send test email
echo "DKIM test $(date)" | mail -s "DKIM Test" recipient@example.com

# Check Postfix mail log for signing activity
tail -f /var/log/maillog | grep -i dkim

A successful DKIM-signed email will show a header similar to:

email header
DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=yourdomain.com;
        s=default2026; t=1741910400;
        bh=47DEQpj8HBSa+/TImW+5JCeuQeRkm5NMpJWZG3hSuFU=;
        h=From:To:Subject:Date:Message-ID;
        b=abc123...

Adding Domains

To add DKIM signing for additional virtual hosts created via Centmin Mod, run the addon for each domain. The OpenDKIM configuration is automatically updated to include the new domain in the KeyTable and SigningTable:

bash
# Add DKIM signing for additional domains
addons/opendkim.sh domain1.com
addons/opendkim.sh domain2.com
addons/opendkim.sh domain3.com

# Each domain gets its own key directory
# /etc/opendkim/keys/domain1.com/default2026
# /etc/opendkim/keys/domain2.com/default2026
# /etc/opendkim/keys/domain3.com/default2026

After adding each domain, publish the corresponding DNS TXT record to that domain's DNS zone. The generated .txt file in each key directory contains the exact record to add.

Remove a Domain

To remove DKIM signing for a domain and clean up its keys:

bash
# Remove DKIM config and keys for a domain
addons/opendkim.sh wipe yourdomain.com

Multi-Server Setup

When running multiple servers (e.g., a primary and a secondary clone sharing the same hostname), DKIM requires special consideration. Running opendkim.sh on two servers with the same domain will generate two different private keys — but DNS can only hold one public key per selector, causing verification failures on one server.

There are two approaches to handle this scenario:

Option A — Share the Private Key (Recommended)

Copy the private key from the primary server to the secondary server. Both servers use the same key material, matching the single DNS record.

bash
# On primary: copy private key to secondary server
rsync -av /etc/opendkim/keys/yourdomain.com/ \
  root@secondary-server:/etc/opendkim/keys/yourdomain.com/

# On secondary: also run opendkim.sh to set up config/milter
# (keys already present — installer skips key generation)
addons/opendkim.sh yourdomain.com

Option B — Use a Unique Selector per Server

Override the default selector on the secondary server so it generates a unique key and requires its own DNS TXT record. Both DNS records must be published.

bash
# On secondary server: use a custom selector suffix
SELECTOR="default2026sec" addons/opendkim.sh yourdomain.com

# Verify the secondary server's config
addons/opendkim.sh check

# Verify the secondary DNS record propagated
dig +short default2026sec._domainkey.yourdomain.com TXT

With this approach, two DNS records are required: default2026._domainkey (primary) and default2026sec._domainkey (secondary).

Clone Server Scenario: See FAQ: DKIM on Secondary/Clone Servers for detailed guidance on setting up DKIM when a secondary server shares the same hostname as the primary.