DKIM

<p>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.</p> <h1>Procedure</h1> <ol> <li> <p>Install OpenDKIM, its tools, and a library providing MySQL backend support:</p> <pre><code class="language-shell">apt install opendkim opendkim-tools libopendbx1-mysql</code></pre> </li> <li> <p>Add following MySQL table to store DKIM signatures in relation to their domains:</p> <pre><code class="language-sql">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;</code></pre> </li> <li> <p>Edit <code>/etc/opendkim.conf</code> to 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:</p> <pre><code class="language-diff"> # 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:&lt;MYSQL PASSWORD&gt;@127.0.0.1/mailserver/table=dkim?keycol=domain?datacol=id + KeyTable dsn:mysql://mailadmin:&lt;MYSQL PASSWORD&gt;@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:8892@127.0.0.1 - Socket local:/var/run/opendkim/opendkim.sock + #Socket local:/var/run/opendkim/opendkim.sock</code></pre> <p>:warning: Replace <code>&lt;MYSQL PASSWORD&gt;</code> by the password defined during <a href="/mailserver/email-acceptance/dkim/Mail-server_Database-preparation">database preparation</a>.</p> </li> <li> <p>Tell postfix to use opendkim:</p> <pre><code class="language-shell">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"</code></pre> </li> <li> <p>Restart both opendkim and postfix to effectuate the changes:</p> <pre><code class="language-shell">service opendkim restart service postfix restart</code></pre> </li> <li> <p>Generate DKIM key for each hosted domain that has to be signed:</p> <pre><code class="language-shell"># 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</code></pre> <blockquote> <p>:warning: Replace <code>example.org</code> by your domain.</p> <p>:warning: Ensure to follow instructions on-screen and update your DNS settings as instructed!</p> </blockquote> </li> <li> <p>Create <code>/etc/systemd/system/opendkim.service.d/opendkim_mysql_dep.conf</code> to ensure Opendkim will wait for MariaDB to be available before starting up:</p> <pre><code class="language-diff">+ [Unit] + After=network.target nss-lookup.target mysqld.service</code></pre> <blockquote> <blockquote> <blockquote> <blockquote> <blockquote> <p>Create the directory structure should directories be missing.</p> </blockquote> </blockquote> </blockquote> </blockquote> </blockquote> </li> </ol> <h1>References</h1> <p>https://fossies.org/linux/opendkim/opendkim/README.SQL</p> <!-- REFERENCES -->