Mail server_DKIM signing - SomethingWithHorizons/mailserver GitHub Wiki
DKIM is an Internet Standard that enables a person or organisation to associate a domain name with an email message. This, in effect, serves as a method of claiming responsibility for a message. At its core, DKIM is powered by asymmetric cryptography. The sender's Mail Transfer Agent (MTA) signs every outgoing message with a private key. The recipient retrieves the public key from the sender's DNS records and verifies if the message body and some of the header fields were not altered since the message signing took place.
Procedure
-
Install OpenDKIM, its tools, and a library providing MySQL backend support:
apt install opendkim opendkim-tools libopendbx1-mysql -
Add following MySQL table to store DKIM signatures in relation to their domains:
CREATE TABLE `mailserver`.`dkim` ( `id` INT(10) UNSIGNED NOT NULL auto_increment, `domain` VARCHAR(63) COLLATE utf8_unicode_ci NOT NULL, `selector` VARCHAR(127) COLLATE utf8_unicode_ci NOT NULL DEFAULT 'mail', `private_key` TEXT COLLATE utf8_unicode_ci NOT NULL, `public_key` TEXT COLLATE utf8_unicode_ci NOT NULL, PRIMARY KEY (`id`), INDEX (`domain`), UNIQUE (`domain`, `selector`), CONSTRAINT `dkim_domain_domains_name` FOREIGN KEY (`domain`) REFERENCES `domains` (`name`) ON DELETE CASCADE ON UPDATE CASCADE ) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci; -
Edit
/etc/opendkim.confto enable MySQL retrieval of IDs (linked to the individual domains) from the DKIM table and relate them to the corresponding key. Also the default (local file based) communication socket is swapped for an ip based socket as an entry point for postfix' signature key requests:# Sign for example.com with key in /etc/dkimkeys/dkim.key using # selector '2007' (e.g. 2007._domainkey.example.com) #Domain example.com #KeyFile /etc/dkimkeys/dkim.key #Selector 2007 + SigningTable dsn:mysql://mailadmin:<MYSQL PASSWORD>@127.0.0.1/mailserver/table=dkim?keycol=domain?datacol=id + KeyTable dsn:mysql://mailadmin:<MYSQL PASSWORD>@127.0.0.1/mailserver/table=dkim?keycol=id?datacol=domain,selector,private_key # Socket smtp://localhost # # ## Socket socketspec # ## # ## Names the socket where this filter should listen for milter connections # ## from the MTA. Required. Should be in one of these forms: # ## # ## inet:port@address to listen on a specific interface # ## inet:port to listen on all interfaces # ## local:/path/to/socket to listen on a UNIX domain socket # - #Socket inet:8892@localhost + Socket inet:[email protected] - Socket local:/var/run/opendkim/opendkim.sock + #Socket local:/var/run/opendkim/opendkim.sock:warning: Replace
<MYSQL PASSWORD>by the password defined during database preparation. -
Tell postfix to use opendkim:
postconf -e "milter_protocol = 2" postconf -e "milter_default_action = accept" postconf -e "smtpd_milters = inet:127.0.0.1:8892" postconf -e "non_smtpd_milters = inet:127.0.0.1:8892" -
Restart both opendkim and postfix to effectuate the changes:
service opendkim restart service postfix restart -
Generate DKIM key for each hosted domain that has to be signed:
# Download https://raw.githubusercontent.com/SomethingWithHorizons/mailserver/master/generate-dkim.sh wget -O /usr/local/bin/generate-dkim.sh https://raw.githubusercontent.com/SomethingWithHorizons/mailserver/master/generate-dkim.sh # generate key bash /usr/local/bin/generate-dkim.sh --domain=example.org:warning: Replace
example.orgby your domain.:warning: Ensure to follow instructions on-screen and update your DNS settings as instructed!
-
Create
/etc/systemd/system/opendkim.service.d/opendkim_timeout_workaround.confto prevent Opendkim start-up failure due to MariaDB not being available at the time of opendkim service start-up:+ [Service] + RestartSec=5:warning: WARNING: This regards a "quick fix". A more solid solution would be to configure Opendkim to explicitly wait on as successful MariaDB servic start-up!