Based on Debian 11 "Bullseye" environment.


OpenDKIM will sign outgoing emails and verify incoming emails as one of the milters.

Please note that DKIM works with DNS system. You need to have access to your domain DNS records if you want to sign the mail. (Verification can be done only with OpenDKIM.)


# apt install opendkim opendkim-tools
  • The package "opendkim-tools" is required to generate the signing key.

DKIM signing Key


To sign emails, generate the key pair. The following command will generate the private key file and the DNS record into /etc/dkimkeys.

# opendkim-genkey -D /etc/dkimkeys -s key01
  • By default, opendkim-genkey will generate sha256 2048bits key. If your DNS provider doesn't accept the TXT record longer than 255 characters, make the 1024bits key by adding "-b 1024" to the command above.

DNS record

Copy & paste the whole content of the /etc/dkimkeys/key01.txt to the DNS TXT record (and tweak a little ).

key01._domainkey.mail     IN      TXT     ( "v=DKIM1; h=sha256; k=rsa; t=y;"
          "y6OwU6..." )  ; ----- DKIM key default for localhost
  • If the key is for a subdomain (in this case "mail"), add it after _domainkey.
  • For the declaration of testing, I recommend adding "t=y" to see if your DKIM works well for a while. (Don't forget to delete it after you confirm it's ok.)
  • ADSP record used to be set with DKIM, but it's already declared "Historic" in 2013.
  • The key is too long for 1 line that it's already divided.

It's recommended to rotate (renew) the key twice a year for security. It may be a good idea to name the selector 202001, YYYYMM to see when this key should be expired.

DNS record test

Check if the TXT record is added to the domain by checking the answer from DNS servers.

$ dig TXT
* snip *
;; ANSWER SECTION: 86400 IN   TXT     "v=DKIM1; h=sha256; k=rsa; t=y;" "p=MIIB..."



Configure /etc/opendkim.conf to use the generated private key for the signing.

  • To sign multiple domains, write all domains separated by comma
  • Change the socket location to Postfix chroot
# Signing domain, selector, and key (required). For example, perform signing
# for domain "" with selector "2020" (,
# using the private key stored in /etc/dkimkeys/example.private. More granular
# setup options can be found in /usr/share/doc/opendkim/README.opendkim.
Domain        ,
Selector                key01
KeyFile                 /etc/dkimkeys/key01.private

* snip *

# Socket for the MTA connection (required). If the MTA is inside a chroot jail,
# it must be ensured that the socket is accessible. In Debian, Postfix runs in
# a chroot in /var/spool/postfix, therefore a Unix socket would have to be
# configured as shown on the last line below.
#Socket                 local:/run/opendkim/opendkim.sock  # Comment out this line
#Socket                 inet:8891@localhost
#Socket                 inet:8891
Socket                  local:/var/spool/postfix/opendkim/opendkim.sock  # Uncomment this line

Prepare the socket.

  • OpenDKIM doesn't make sockets automatically.
  • Add postfix user to opendkim group for the socket access.
  • Restart OpenDKIM with updated configurations
# mkdir /var/spool/postfix/opendkim
# chown opendkim:opendkim /var/spool/postfix/opendkim/
# adduser postfix opendkim
# systemctl restart opendkim


Edit /etc/postfix/ to use OpenDKIM as a milter.

# milter
smtpd_milters =

Restart Postfix.

# systemctl restart postfix


Receive an email with the valid DKIM signature, e.g. from Gmail. You should find the mail header related to DKIM verification.

	dkim=pass (2048-bit key; unprotected) header.a=rsa-sha256 header.s=20210112 header.b=WniUsjzg;

Reply to the mail above to see if your email has a DKIM key header and is verified by Gmail.

It should have DKIM signature.

DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple;;
	s=key01; t=1632041939;

This DKIM signature should be valid.

       dkim=pass (test mode) header.s=key01 header.b=U+L3Kgbm;
       spf=pass ( domain of...

If everything works fine, get rid of the test flag in the DNS record.

Update History


  • Update to Bullseye version