User Tools

Site Tools


doc:appunti:linux:sa:postfix_opendkim

This is an old revision of the document!


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

Add the domain to be signed

Into the file /etc/dkimkeys/signingtable we declare that mails originating from that domain must be signed:

*@[DOMAIN] [SELECTOR]._domainkey.[DOMAIN]

NOTICE: The use of the wildcard (to indicate all the senders from a domain) is possibile if signingtable is declared with refile (regular expression file) into the configuration file. Otherwise you have to specify every single sender address where signing is to be applied.

Remember to reload OpenDKIM after changing the signingtable:

systemctl reload opendkim.service

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  refile:/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

NOTICE: refile means that the file contains regular expressions (e.g. asterisk wildcard to indicate all the mail addresses into a domain).

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.

# Locally generated mails are filtered with OpenDKIM.
non_smtpd_milters = inet:localhost:8891
# Mails received via SMTP protocol are filtered with OpenDKIM.
# This does not include messages received by "postfix/submission/smtpd",
# for that use mua_milters instead?
#smtpd_milters = inet:localhost:8891

FIXME This configuration does not sign messages sent to the Postfix service via the smtp or submission port!

Web References

doc/appunti/linux/sa/postfix_opendkim.1653293807.txt.gz · Last modified: 2022/05/23 10:16 by niccolo