This is an old revision of the document!
Table of Contents
OpenDKIM on Postfix with virtual domains
In this article we will install OpenDKIM on a GNU/Linux mail server based on Debian 11 Buster. The mail service is provided by Postfix configured for virtual domains using virtual_alias_domains.
apt install opendkim opendkim-tools
Create the keys in /etc/dkimkeys/
The canonical directory to keep the keys is /etc/dkimkeys/. For each domain we can have more than one key (e.g. when a key is to be renewed, etc.), so each key is identified by the domain name and by an arbitrary selector; it is a common practice to use the current year as the selector.
We create one subdirectory for each virtual domain:
DOMAIN='rigacci.org' SELECTOR='2022' mkdir /etc/dkimkeys/"$DOMAIN" chown opendkim:opendkim /etc/dkimkeys/"$DOMAIN" chmod 700 /etc/dkimkeys/"$DOMAIN" sudo -u opendkim opendkim-genkey -D /etc/dkimkeys/"$DOMAIN" -d "$DOMAIN" -s "$SELECTOR"
This will create two files:
- /etc/dkimkeys/$DOMAIN/$SELECTOR.private - The RSA private key.
- /etc/dkimkeys/$DOMAIN/$SELECTOR.txt - The public key, already in TXT format to be inserted into the DNS zone.
Add the private key in /etc/dkimkeys/keytable
It is necessary to tell OpenDKIM what is the private key to use when it wants to sign a mail from a domain. We must add one line for each domain into /etc/dkimkeys/keytable:
[SELECTOR]._domainkey.[DOMAIN] [DOMAIN]:[SELECTOR]:/etc/dkimkeys/[DOMAIN]/[SELECTOR].private
Add the public key into the DNS zone
Now it is necessary to publish the public key into the DNS. Just copy and paste the .txt file into the zone file:
2022._domainkey IN TXT ( "v=DKIM1; h=sha256; k=rsa; " "p=MIIBIjANBgkqhkiG9w0BAQ..." "W0CdtxNd+xRgCopJCp93CLiD..." ) ; ----- DKIM key 2022 for rigacci.org
Configure OpenDKIM
Into the /etc/opendkim.conf file we infor OpenDKIM to look into a KeyTable to find keys and into a SigningTable to know which domains require signing. The service will listen on port 8891/TCP (should use Unix domain socket instead? Better performances? More painfull because Postfix runs in chroot).
# We use virtual domains, so we use KeyTable and SigningTable KeyTable file:/etc/dkimkeys/keytable SigningTable file:/etc/dkimkeys/signingtable # Match a list of hosts whose messages will be signed. # By default, only localhost is considered as internal host. #InternalHosts refile:/etc/dkimkeys/trustedhosts # Socket for the MTA connection (required). Socket inet:8891@localhost
Test the OpenDKIM configuration
Reload the DNS Bind service and test that OpenDKIM can properly use the keys (it is not necessary to reload the OpenDKIM service):
# opendkim-testkey -v -v opendkim-testkey: using default configfile /etc/opendkim.conf opendkim-testkey: record 0 for '2022._domainkey.rigacci.org' retrieved opendkim-testkey: checking key '2022._domainkey.rigacci.org' opendkim-testkey: key 2022._domainkey.rigacci.org not secure opendkim-testkey: 1 keys checked; 1 pass, 0 fail
Signing message test
cat message.txt \ | opendkim-testmsg -d "$DOMAIN" -k "/etc/dkimkeys/$DOMAIN/$SELECTOR.private" -s "$SELECTOR.$DOMAIN"
Configure Postfix
To tell Postfix to use the mail filter provided by OpenDKIM, we use the non_smtpd_milters option into the file /etc/postfix/main.cf. Non smtpd means that messages filtered are the ones not received by the SMTP daemon, i.e. local submissions via sendmail command line, submissions to the qmqpd, (Quick Mail Queuing Protocol daemomn), re-injected mails.
# Filter locally generated mails with OpenDKIM. non_smtpd_milters = inet:localhost:8891 # Default action for non working milter is tempfail, can be accept or reject. #milter_default_action = tempfail