This page is a step by step page that will show you how to sign outgoing email with the DKIM specification.
OpenDKIM will sign the email passed by Postfix and every receiver can check the email authenticity through the public key published in the DNS record of the domain.
The signature is added in the email in an header field. Example:
DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=bytle.net;
s=vps748761.ovh.net; t=1591988898;
bh=WBggpZrfs7F0OzQkyE7LiZPHyfFFhl7N4CNav2f5YVw=;
h=Date:To:Subject:From:From;
b=ByN4Iw4U9RP8bzaPK0n3HJbFlvI60ett+V9pkoli+UNtdAcSdq/ANc3hL71PzjrT4
3yyTjK3MC5e2f/k+BAnIaAgnradAK/1CbMF4vMZVD6WoVIx7KTZlfWsW39Ir8PhqYQ
4TKvPpDUx8ToxUz1gwQlxJoExYW3McXJ2WdvUAf8=
The configuration is done with OpenDkim installed as a milter software of Postfix (for the MTA) on a CentsOS (Redhat) linux box.
To install opendkim as a milter to an MTA, you need to perform the following steps:
If you want to install it from the source. See the install doc
yum install -y opendkim
The opendkim-genkey will:
The private key signs the message (ie encrypt) and the public key can decrypt it.
As there is only one public key that can decrypt a message encrypted by the private key, the authenticity of the sender can then be verified.
This is a feature of the Public Key Cryptography system.
Syntax:
opendkim-genkey -s SELECTOR -d DOMAIN
# example with your brand name
opendkim-genkey -s brandName -d example.com
where:
If you want to test it, you can add the --testmode argument.
testmode tells the verifiers that they should not take any real action based on success or failure of the use of this key after verifing a message.
In the generated TXT record, you will find back a t=y that you can remove to enter in production mode.
Two files should have been generated:
Verification of the file existence:
cat brandName.txt
yourSelector._domainkey IN TXT ( "v=DKIM1; k=rsa; "
"p=MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDQUtHxTD63yxwq5fmjJ3RtXw2NP5/QEiSq3Xx85faTHnnj3/PA/igwWaueDsoeUuZOpkL74gDNGWBoQPecRaFrAXdPoEKGDYNBeMXzIkWQOth9Oaq4N+38LV08Ui86so8B2BhcvgXiqpACsrPur0hbDQWI183tZve7MKMPs3KPIQIDAQAB" ) ; ----- DKIM key vps748761.ovh.net for bytle.net
ll brandName.private
-rw------- 1 root root 887 Jun 12 12:03 vps748761.ovh.net.private
The next step is to publish the public key by creating a TXT DNS record with the help of the generated TXT file.
The TXT record value generated has the form:
"v=DKIM1; k=rsa; " "p=public key"
where :
If the DNS interface of your provider supports TXT input, you can just take the input of the TXT file and add it at the end.
Then you should see a TXT record with a DKIM value. Example with a snapshot of the DNS manager of my domain provider
where the public key DNS record should appear as a TXT resource record as:
SELECTOR._domainkey.DOMAIN
# in the snapshot
vps748761.ovh.net._domainkey.bytle.net.
where:
DOMAIN may also be specified:
You can verify that the key matches the private key with opendkim-testkey
opendkim-testkey -d DOMAIN -s $(hostname) -k $(hostname).private
# example
opendkim-testkey -d bytle.net -s $(hostname) -k $(hostname).private
If you got no message and an exit code of zero, that's all good.
echo $?
0
The key should be stored in a safe place.
mv $(hostname).private /etc/opendkim/keys
# The opendkim was created with the package installation
chown opendkim:opendkim /etc/opendkim/keys/ # should already by the case
chown opendkim:opendkim /etc/opendkim/keys/$(hostname).private
chmod 0700 /etc/opendkim/keys # 0=rwx
chmod 0600 /etc/opendkim/keys/$(hostname).private # o=rw
The minimal configuration for OpenDKIM defines:
FYI: The global configuration file can be found at:
/etc/opendkim.conf
The MTA and your opendkim filter communicate over a socket connection.
You can choose to use:
In case of a tcp socket, for selinux, the following command will need to be executed as the superuser, which declares the chosen port to be a milter application port:
# to see if SELINUX is enable
# cat /etc/selinux/config | grep -i SELINUX=
# if yes then
semanage port -a -t milter_port_t -p tcp <port>
The actual socket configuration of OpenDKIM is
## Create a socket through which your MTA can communicate.
Socket inet:8891@localhost
OpenDKIM find the private keys with the KeyTable lookup file. It's a file that maps key names to signing keys. (private key)
Conf:
KeyTable refile:/etc/opendkim/KeyTable
SELECTOR._domainkey.DOMAIN DOMAIN:SELECTOR:/path/to/my/key
# or with this actual step by step
SELECTOR._domainkey.DOMAIN DOMAIN:SELECTOR:/etc/opendkim/keys/SELECTOR.private
It requires SigningTable be enabled.
This SigningTable is a file that maps:
Conf:
SigningTable refile:/etc/opendkim/SigningTable
# Wild card example (refile scheme)
*@DOMAIN SELECTOR._domainkey.DOMAIN
The operating modes are:
You need to change it at minimal to s in order to sign the email.
Mode sv
Optional
If you wish to sign mail that comes from sources other than the localhost address (127.0.0.1), include these in CIDR notation in the configuration file for the InternalHosts configuration option.
## Identifies a set "internal" hosts whose mail should be signed rather than verified.
InternalHosts refile:/etc/opendkim/TrustedHosts
## Identifies a set of "external" hosts that may send mail through the server as one
## of the signing domains without credentials as such.
ExternalIgnoreList refile:/etc/opendkim/TrustedHosts
Syntax:
smtpd_milters = inet:localhost:portnumber ...other filters...
With the OpenDkim Socket configuration of this tutorial (the default)
smtpd_milters = inet:localhost:8891
The non-SMTP Milter applications handle mail that arrives via:
non_smtpd_milters = inet:localhost:8891
Optional
The milter_default_action property defines what to do in case of errors.
The following value can be chosen:
milter_default_action = tempfail
Restart the services
systemctl restart opendkim
systemctl restart postfix
To test, we need to send an email and to see if the DKIM header was added.
If the test does not work, check the diagnostic section.
We show two ways to test:
The client mail used is mail that you can install with the mailx package
yum install -y mailx
It's possible to send email with the sendmail command line of postfix
The first easy method to test is to send an email to the mail-tester website. They will then analyze it and give you a score.
echo "Body: This is a test mail. Hallo Charlie" | mail -s "Subject: A big test" [email protected]
Gmail allows you to see:
Send an email to your Gmail address
echo "Body: This is a test mail. Hallo Charlie" | mail -s "Subject: A big test" [email protected]
You can then verify the signing:
opendkim-testkey -d DOMAIN -s $(hostname) -k /etc/opendkim/keys/$(hostname).private
tail -f /var/log/maillog
Jun 12 20:57:17 vps748761 postfix/pickup[22362]: D572A1FBE8: uid=0 from=<root>
Jun 12 20:57:17 vps748761 postfix/cleanup[23285]: D572A1FBE8: message-id=<[email protected]>
Jun 12 20:57:17 vps748761 opendkim[23276]: D572A1FBE8: DKIM-Signature field added (s=vps748761.ovh.net, d=bytle.net)
Jun 12 20:57:17 vps748761 postfix/qmgr[22361]: D572A1FBE8: from=<[email protected]>, size=521, nrcpt=1 (queue active)
Jun 12 20:57:18 vps748761 postfix/smtp[23288]: D572A1FBE8: to=<[email protected]>, relay=gmail-smtp-in.l.google.com[173.194.76.27]:25, delay=0.57, delays=0.06/0/0.35/0.16, dsn=2.0.0, status=sent (250 2.0.0 OK 1591988238 r8si6848556wrn.39 - gsmtp)
Jun 12 20:57:18 vps748761 postfix/qmgr[22361]: D572A1FBE8: removed
netstat -tulpn|grep 8891
tcp 0 0 127.0.0.1:8891 0.0.0.0:* LISTEN 21636/opendkim
postconf -h smtpd_milters # inet:localhost:8891
postconf -h non_smtpd_milters # inet:localhost:8891
This page was created with the help of the following references: