OpenDKIM Setup Guide for Sendmail on Rocky Linux 9Configure Sendmail with OpenDKIM and use a separate DKIM key for each email domain. Scope: This guide describes a multi-domain OpenDKIM configuration for Sendmail on Rocky Linux 9. Each domain has its own private/public DKIM key pair.
1 Install OpenDKIMEnable EPEL and install OpenDKIM and its utilities: dnf install epel-release -y
dnf install opendkim opendkim-tools -y
Verify the installation: rpm -qa | grep opendkim
2 Create the DKIM Key DirectoriesCreate a separate directory for every domain that will send email. For example: mkdir -p /etc/opendkim/keys/cylinux.com
mkdir -p /etc/opendkim/keys/example.com
mkdir -p /etc/opendkim/keys/example.net
The resulting structure should look like: /etc/opendkim/keys/
βββ cylinux.com/ βββ example.com/ βββ example.net/ 3 Generate a DKIM Key for Each DomainGenerate a separate 2048-bit RSA key pair for each domain. The selector used in this example is mail2026. cylinux.comopendkim-genkey -b 2048 -d cylinux.com -D /etc/opendkim/keys/cylinux.com -s mail2026
example.comopendkim-genkey -b 2048 -d example.com -D /etc/opendkim/keys/example.com -s mail2026
example.netopendkim-genkey -b 2048 -d example.net -D /etc/opendkim/keys/example.net -s mail2026
Each command creates two files: mail2026.private mail2026.txt
Important: The private key must remain on the mail server and must never be published in DNS. The mail2026.txt file contains the public key that will be published in DNS.
4 Configure the KeyTableEdit: vi /etc/opendkim/KeyTable
Add one entry for every domain: mail2026._domainkey.cylinux.com cylinux.com:mail2026:/etc/opendkim/keys/cylinux.com/mail2026.private
mail2026._domainkey.example.com example.com:mail2026:/etc/opendkim/keys/example.com/mail2026.private
mail2026._domainkey.example.net example.net:mail2026:/etc/opendkim/keys/example.net/mail2026.private
The format is: KEY-NAME DOMAIN:SELECTOR:PRIVATE-KEY
This configuration tells OpenDKIM which private key must be used for each domain. 5 Configure the SigningTableEdit: vi /etc/opendkim/SigningTable
Add: *@cylinux.com mail2026._domainkey.cylinux.com
*@example.com mail2026._domainkey.example.com
*@example.net mail2026._domainkey.example.net
This determines which DKIM key is used according to the sender's domain. 6 Configure OpenDKIMEdit: vi /etc/opendkim.conf
Make sure the following settings are present: Mode sv
KeyTable refile:/etc/opendkim/KeyTable
SigningTable refile:/etc/opendkim/SigningTable
ExternalIgnoreList refile:/etc/opendkim/TrustedHosts
InternalHosts refile:/etc/opendkim/TrustedHosts
Mode sv enables both DKIM signing and verification. Important: If an older single-domain configuration contains directives such as KeyFile, Selector, or Domain, review them carefully. They may conflict with the multi-domain KeyTable/SigningTable configuration.
7 Configure TrustedHostsEdit: vi /etc/opendkim/TrustedHosts
At minimum, include: 127.0.0.1
localhost
If mail is submitted from a trusted internal network, the appropriate internal subnet can also be added. For example: 192.168.1.0/24
Security note: Do not add arbitrary public IP ranges to TrustedHosts. Only trusted systems that are permitted to submit mail through your server should be included.
8 Set File PermissionsOpenDKIM needs permission to read the private keys, while the private keys themselves should be protected from other users. chown -R opendkim:opendkim /etc/opendkim/keys
chmod 700 /etc/opendkim/keys
find /etc/opendkim/keys -type d -exec chmod 750 {} \;
find /etc/opendkim/keys -name "*.private" -exec chmod 600 {} \;
find /etc/opendkim/keys -name "*.txt" -exec chmod 644 {} \;
Verify: ls -lR /etc/opendkim/keys
9 Publish the DKIM Public Keys in DNSDisplay the generated public key for a domain: cat /etc/opendkim/keys/cylinux.com/mail2026.txt
The output will contain a TXT record similar to: mail2026._domainkey IN TXT ( "v=DKIM1; k=rsa; " "p=MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8A..." )
Create a DNS TXT record for: mail2026._domainkey.cylinux.com
Example TXT value (one line): "v=DKIM1; k=rsa; p=MIIBIjANBgkqhkiG9w0BAQEFAAOCA234234234kjshdfljkhler84rlhfklsjdfhldkfhgsldkfghsldfgh5hkhgdklfjghdkjfghIdeQMA7DZS71rkpTXEr/oz9Cd6pFNQhGEvRyBSbQjTO0vdHqVH4vF5iLeBDehXIVE74W+E/TmnvxFxOmbNdHGcluj4+cMRVy0kdDBoLZhqgGyc79eUqAek7eG9XkkZ6M4TP5zq1Rd07e+b7i//AXnBAYygfOwH1IP3LEetrpot+DjfcSmFpivKzjin2wU2wvu7a8Lk1SmaGR8Q7/H974jjxLbxShEhppU9AL/SMkUl8WjNrJYZj01s8bVTmaKVTQviPHRRMnKzshrC/m0G4495hnviUY0Cwk2GXe9RQIDAQAB"
Repeat the process for every domain: mail2026._domainkey.example.com
mail2026._domainkey.example.net
DNS record: The public DKIM key belongs in DNS. Never publish the contents of a .private file.
10 Verify the DNS RecordUse: dig TXT mail2026._domainkey.cylinux.com
or: nslookup -type=TXT mail2026._domainkey.cylinux.com
The response should contain a value beginning with: v=DKIM1; k=rsa; p=...
11 Test the DKIM KeyBefore connecting OpenDKIM to Sendmail, test the DNS record and private key: opendkim-testkey -d cylinux.com -s mail2026 -vvv
A successful test should report: key OK
Repeat for the other domains: opendkim-testkey -d example.com -s mail2026 -vvv
opendkim-testkey -d example.net -s mail2026 -vvv
12 Connect OpenDKIM to SendmailEdit: vi /etc/mail/sendmail.mc
Add the OpenDKIM milter configuration: INPUT_MAIL_FILTER(`opendkim', `S=local:/run/opendkim/opendkim.sock')
This tells Sendmail to pass outgoing messages through the OpenDKIM milter local socket. 13 Rebuild Sendmail ConfigurationRebuild the Sendmail configuration: cd /etc/mail make
Alternatively, the configuration can be generated directly with: m4 /etc/mail/sendmail.mc > /etc/mail/sendmail.cf
14 Start and Enable OpenDKIMsystemctl enable --now opendkim
systemctl restart sendmail
Check the services: systemctl status opendkim
systemctl status sendmail
15 Send a Test EmailSend an email using one of your configured domains: echo "DKIM test from cylinux.com" | mail -s "DKIM TEST" recipient@example.com
Inspect the headers of the received message. You should see a header similar to: DKIM-Signature: v=1; a=rsa-sha256; d=cylinux.com; s=mail2026; ...
For an email sent from another configured domain, the d= and s= values should correspond to that domain and selector. Multi-Domain Configuration
Using the same selector name for different domains is acceptable because the selector is evaluated within the domain. Each domain should still have its own key pair. DKIM Key RotationDKIM keys do not have a built-in expiration date. Nevertheless, periodic key rotation is recommended as a security practice. For example, a future selector can be introduced: mail2027._domainkey.cylinux.com
The general rotation process is:
Do not remove the old DNS key immediately. Messages signed using the old selector may still need the old public key for verification.
Important: DKIM DNS Record vs. DKIM SigningA DKIM TXT record in DNS does not force a mail server to sign messages. It only publishes the public key used to verify messages signed with that selector. If OpenDKIM is temporarily unavailable, outgoing mail may be sent without a DKIM-Signature header. Whether that affects delivery depends on the receiving system and the domain's SPF and DMARC configuration. Check DMARC carefully. If your domain uses a strict DMARC policy such as p=reject, ensure that SPF and/or DKIM authentication and alignment are working correctly before relying on the configuration in production.
Recommended Final ConfigurationA clean multi-domain installation should have a structure similar to: /etc/opendkim/
βββ opendkim.conf βββ KeyTable βββ SigningTable βββ TrustedHosts βββ keys/ βββ cylinux.com/ β βββ mail2026.private βββ example.com/ β βββ mail2026.private βββ example.net/ βββ mail2026.private Configuration checklist:
|
OpenDKIM Setup Guide for Sendmail on Rocky Linux 9Configure Sendmail with OpenDKIM and use a separate DKIM key for each email domain. Scope: This guide describes a multi-domain OpenDKIM configuration for Sendmail on Rocky Linux 9. Each domain has its own private/public DKIM key pair.
1 Install OpenDKIMEnable EPEL and install OpenDKIM and its utilities: dnf install epel-release -y
dnf install opendkim opendkim-tools -y
Verify the installation: rpm -qa | grep opendkim
2 Create the DKIM Key DirectoriesCreate a separate directory for every domain that will send email. For example: mkdir -p /etc/opendkim/keys/cylinux.com
mkdir -p /etc/opendkim/keys/example.com
mkdir -p /etc/opendkim/keys/example.net
The resulting structure should look like: /etc/opendkim/keys/
βββ cylinux.com/ βββ example.com/ βββ example.net/ 3 Generate a DKIM Key for Each DomainGenerate a separate 2048-bit RSA key pair for each domain. The selector used in this example is mail2026. cylinux.comopendkim-genkey -b 2048 -d cylinux.com -D /etc/opendkim/keys/cylinux.com -s mail2026
example.comopendkim-genkey -b 2048 -d example.com -D /etc/opendkim/keys/example.com -s mail2026
example.netopendkim-genkey -b 2048 -d example.net -D /etc/opendkim/keys/example.net -s mail2026
Each command creates two files: mail2026.private mail2026.txt
Important: The private key must remain on the mail server and must never be published in DNS. The mail2026.txt file contains the public key that will be published in DNS.
4 Configure the KeyTableEdit: vi /etc/opendkim/KeyTable
Add one entry for every domain: mail2026._domainkey.cylinux.com cylinux.com:mail2026:/etc/opendkim/keys/cylinux.com/mail2026.private
mail2026._domainkey.example.com example.com:mail2026:/etc/opendkim/keys/example.com/mail2026.private
mail2026._domainkey.example.net example.net:mail2026:/etc/opendkim/keys/example.net/mail2026.private
The format is: KEY-NAME DOMAIN:SELECTOR:PRIVATE-KEY
This configuration tells OpenDKIM which private key must be used for each domain. 5 Configure the SigningTableEdit: vi /etc/opendkim/SigningTable
Add: *@cylinux.com mail2026._domainkey.cylinux.com
*@example.com mail2026._domainkey.example.com
*@example.net mail2026._domainkey.example.net
This determines which DKIM key is used according to the sender's domain. 6 Configure OpenDKIMEdit: vi /etc/opendkim.conf
Make sure the following settings are present: Mode sv
KeyTable refile:/etc/opendkim/KeyTable
SigningTable refile:/etc/opendkim/SigningTable
ExternalIgnoreList refile:/etc/opendkim/TrustedHosts
InternalHosts refile:/etc/opendkim/TrustedHosts
Mode sv enables both DKIM signing and verification. Important: If an older single-domain configuration contains directives such as KeyFile, Selector, or Domain, review them carefully. They may conflict with the multi-domain KeyTable/SigningTable configuration.
7 Configure TrustedHostsEdit: vi /etc/opendkim/TrustedHosts
At minimum, include: 127.0.0.1
localhost
If mail is submitted from a trusted internal network, the appropriate internal subnet can also be added. For example: 192.168.1.0/24
Security note: Do not add arbitrary public IP ranges to TrustedHosts. Only trusted systems that are permitted to submit mail through your server should be included.
8 Set File PermissionsOpenDKIM needs permission to read the private keys, while the private keys themselves should be protected from other users. chown -R opendkim:opendkim /etc/opendkim/keys
chmod 700 /etc/opendkim/keys
find /etc/opendkim/keys -type d -exec chmod 750 {} \;
find /etc/opendkim/keys -name "*.private" -exec chmod 600 {} \;
find /etc/opendkim/keys -name "*.txt" -exec chmod 644 {} \;
Verify: ls -lR /etc/opendkim/keys
9 Publish the DKIM Public Keys in DNSDisplay the generated public key for a domain: cat /etc/opendkim/keys/cylinux.com/mail2026.txt
The output will contain a TXT record similar to: mail2026._domainkey IN TXT ( "v=DKIM1; k=rsa; " "p=MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8A..." )
Create a DNS TXT record for: mail2026._domainkey.cylinux.com
Example TXT value (one line): "v=DKIM1; k=rsa; p=MIIBIjANBgkqhkiG9w0BAQEFAAOCA234234234kjshdfljkhler84rlhfklsjdfhldkfhgsldkfghsldfgh5hkhgdklfjghdkjfghIdeQMA7DZS71rkpTXEr/oz9Cd6pFNQhGEvRyBSbQjTO0vdHqVH4vF5iLeBDehXIVE74W+E/TmnvxFxOmbNdHGcluj4+cMRVy0kdDBoLZhqgGyc79eUqAek7eG9XkkZ6M4TP5zq1Rd07e+b7i//AXnBAYygfOwH1IP3LEetrpot+DjfcSmFpivKzjin2wU2wvu7a8Lk1SmaGR8Q7/H974jjxLbxShEhppU9AL/SMkUl8WjNrJYZj01s8bVTmaKVTQviPHRRMnKzshrC/m0G4495hnviUY0Cwk2GXe9RQIDAQAB"
Repeat the process for every domain: mail2026._domainkey.example.com
mail2026._domainkey.example.net
DNS record: The public DKIM key belongs in DNS. Never publish the contents of a .private file.
10 Verify the DNS RecordUse: dig TXT mail2026._domainkey.cylinux.com
or: nslookup -type=TXT mail2026._domainkey.cylinux.com
The response should contain a value beginning with: v=DKIM1; k=rsa; p=...
11 Test the DKIM KeyBefore connecting OpenDKIM to Sendmail, test the DNS record and private key: opendkim-testkey -d cylinux.com -s mail2026 -vvv
A successful test should report: key OK
Repeat for the other domains: opendkim-testkey -d example.com -s mail2026 -vvv
opendkim-testkey -d example.net -s mail2026 -vvv
12 Connect OpenDKIM to SendmailEdit: vi /etc/mail/sendmail.mc
Add the OpenDKIM milter configuration: INPUT_MAIL_FILTER(`opendkim', `S=local:/run/opendkim/opendkim.sock')
This tells Sendmail to pass outgoing messages through the OpenDKIM milter local socket. 13 Rebuild Sendmail ConfigurationRebuild the Sendmail configuration: cd /etc/mail make
Alternatively, the configuration can be generated directly with: m4 /etc/mail/sendmail.mc > /etc/mail/sendmail.cf
14 Start and Enable OpenDKIMsystemctl enable --now opendkim
systemctl restart sendmail
Check the services: systemctl status opendkim
systemctl status sendmail
15 Send a Test EmailSend an email using one of your configured domains: echo "DKIM test from cylinux.com" | mail -s "DKIM TEST" recipient@example.com
Inspect the headers of the received message. You should see a header similar to: DKIM-Signature: v=1; a=rsa-sha256; d=cylinux.com; s=mail2026; ...
For an email sent from another configured domain, the d= and s= values should correspond to that domain and selector. Multi-Domain Configuration
Using the same selector name for different domains is acceptable because the selector is evaluated within the domain. Each domain should still have its own key pair. DKIM Key RotationDKIM keys do not have a built-in expiration date. Nevertheless, periodic key rotation is recommended as a security practice. For example, a future selector can be introduced: mail2027._domainkey.cylinux.com
The general rotation process is:
Do not remove the old DNS key immediately. Messages signed using the old selector may still need the old public key for verification.
Important: DKIM DNS Record vs. DKIM SigningA DKIM TXT record in DNS does not force a mail server to sign messages. It only publishes the public key used to verify messages signed with that selector. If OpenDKIM is temporarily unavailable, outgoing mail may be sent without a DKIM-Signature header. Whether that affects delivery depends on the receiving system and the domain's SPF and DMARC configuration. Check DMARC carefully. If your domain uses a strict DMARC policy such as p=reject, ensure that SPF and/or DKIM authentication and alignment are working correctly before relying on the configuration in production.
Recommended Final ConfigurationA clean multi-domain installation should have a structure similar to: /etc/opendkim/
βββ opendkim.conf βββ KeyTable βββ SigningTable βββ TrustedHosts βββ keys/ βββ cylinux.com/ β βββ mail2026.private βββ example.com/ β βββ mail2026.private βββ example.net/ βββ mail2026.private Configuration checklist:
|

Login