Bij DomainKey Identified Mail, kortweg DKIM, worden e-mails die namens jou worden verzonden ondertekend met een digitale handtekening. Deze handtekening stelt de ontvangende partij in de gelegenheid om te controleren of binnenkomende mail ook écht van jou afkomstig is of dat deze afkomstig is van een partij die zich als jou voordoet. Door gebruik van DKIM te maken kun je e-mailspoofing voorkomen.

De handtekening wordt aan de bron van het e-mailbericht toegevoegd door OpenDKIM als milter te installeren in Postfix. De handtekening wordt dan als message-headers toegevoegd aan de e-mail. Vergelijkbaar met SSL (gebruikt voor HTTPS), dient er een public-key beschikbaar gemaakt te worden (dit gaat d.m.v. een DNS-record, hiermee bewijs je dat je eigenaar bent van het betreffende domein) en een private-key, welke alleen beschikbaar is op de mailserver.

OpenDKIM installeren

Gezien er van OpenDKIM gebruik wordt gemaakt, kun je deze via de standaard packagemanager installeren

apt-get install opendkim opendkim-tools

Vervolgens kun je onderaan het bestand /etc/opendkim.conf het volgende toevoegen:

# MANUAL CONFIG

Mode sv
# Using "Canonicalization relaxed/relaxed" is slightly less strict,
# Using "Canonicalizattion simple/simple" is stricter but might cause false positives, therefore slightly discouraged
Canonicalization        relaxed/simple

AutoRestart Yes
AutoRestartRate 10/1h
UMask 002
Syslog yes
SyslogSuccess Yes
Logwhy Yes

ExternalIgnoreList refile:/etc/opendkim/TrustedHosts
InternalHosts refile:/etc/opendkim/TrustedHosts
KeyTable refile:/etc/opendkim/KeyTable
SigningTable refile:/etc/opendkim/SigningTable

PidFile /var/run/opendkim/opendkim.pid
SignatureAlgorithm rsa-sha256

UserID opendkim

SubDomains no
Background yes
DNSTimeout 5
# Using "X-Header yes" causes a "X-DKIM" header with information about OpenDKIM to be added
X-Header no

DomainKeys genereren (domein toevoegen aan OpenDKIM)

Door middel van de tools in het pakket opendkim-tools, kunnen we een domainkey genereren d.m.v. opendkim-genkey:

mkdir -p /etc/opendkim/keys/mydomain.tld
opendkim-genkey -r -D /etc/opendkim/keys/mydomain.tld -d mydomain.tld

Vervang in bovenstaande opdracht mydomain.tld door het juiste domein zodat de bestanden default.txt en default.private worden gegenereerd, respectievelijk met het DNS-record en de private-key voor ondertekening.

Vervolgens dient deze sleutel aan OpenDKIM gekoppeld te worden, door deze aan de bestanden TrustedHosts, KeyTable en SigningTable toe te voegen:

echo "default._domainkey.mydomain.tld mydomain.tld:default:/etc/opendkim/keys/mydomain.tld/default.private" >> /etc/opendkim/KeyTable
echo "*@mydomain.tld default._domainkey.mydomain.tld" >> /etc/opendkim/SigningTable
echo "*.mydomain.tld" >> /etc/opendkim/TrustedHosts

Vervang in bovenstaande opdracht mydomain.tld door het domein dat je in de vorige stap hebt gekozen. Het domein is nu geconfigureerd in OpenDKIM. Als laatste dienen de rechten (voor de zekerheid) goed gezet te worden en dient de nieuwe configuratie in OpenDKIM geladen te worden:

chown -R opendkim:opendkim /etc/opendkim
chmod -R 700 /etc/opendkim
service opendkim reload

DomainKey aan DNS toevoegen

Het publieke deel van de DomainKey, de public-key, dient handmatig als DNS-record te worden toegevoegd aan het betreffende domein. Als je gebruik hebt gemaakt van bovenstaand stappenplan, dan staat deze publieke sleutel in het default.txt-bestand. Gebruik het deel tussen aanhalingstekens — zonder aanhalingstekens dus — dat begint met "v=DKIM1; k=rsa; k=…" om een TXT-record te maken voor default._domainkey.mydomain.tld. Je kunt vervolgens met dig controleren of je het record goed hebt toegevoegd:

dig +short TXT default._domainkey.mydomain.tld

Gebruik geen DKIM records terwijl DKIM nog niet juist werkt

Dit kan zorgen dat jouw mail door de ontvanger wordt geweigerd. Ik heb zelf ervaren dat alleen Microsoft zich hier schuldig aan maakt.

DomainKey selector aanpassen

Wanneer je een eigen e-mailserver hebt en bijvoorbeeld een extern e-mailmarketing systeem gebruikt, kortom als jouw e-mail door meerdere partijen afgehandeld wordt, dan heb je ook meerdere DomainKeys nodig. Anders zou je de private-key met deze partijen moeten delen, niet de bedoeling dus. Hiervoor kun je de standaard selector — default — aanpassen naar eigen inzicht.

Voeg om dit te doen de selector expliciet toe bij het genereren van de key:

opendkim-genkey -r -D /etc/opendkim/keys/mydomain.tld -s myselector -d mydomain.tld

Bovenstaande snippet genereert de bestanden myselector.txt en myselector.private (in plaats van default.txt en default.private). Houdt er tevens rekening mee dat het de selector "default" ook veranderd dient te worden om de key juist in opendkim te configureren:

echo "myselector._domainkey.mydomain.tld mydomain.tld:myselector:/etc/opendkim/keys/mydomain.tld/myselector.private" >> /etc/opendkim/KeyTable
echo "*@mydomain.tld myselector._domainkey.mydomain.tld" >> /etc/opendkim/SigningTable
echo "*.mydomain.tld" >> /etc/opendkim/TrustedHosts

Als laatste dient het dns-record uiteraard ook voorzien te worden van de juiste selector, dus myselector._domainkey.mydomain.tld.

DomainKey automatisch genereren met een script

Door bovenstaande opdrachten in een simpel bash-script te plaatsen, kun je het genereren van een nieuwe key vergemakkelijken. Als basis is het script van matoski.com gebruikt en is er alleen een aanvulling gemaakt om de selector aan te kunnen passen.

Script downloaden

Pas na het downloaden eventueel de waarde van selector aan en gebruik het script op de volgende manier:

bash ./dkim.sh mydomain.tld

De juiste bestanden worden gegenereerd en ze worden meteen in opendkim geregistreerd.

OpenDKIM testen

Wanneer je DKIM volgens bovenstaande stappen hebt geïnstalleerd, kun je zien dat DKIM als proces op de achtergrond draait (DKIM is dus niet beschikbaar als TCP connectie, maar als socket). Dit kun je met onderstaande opdracht controleren:

ps aux | grep dkim | grep -v 'grep'

OpenDKIM key testen

Door gebruik te maken van opendkim-testkey, kun je controleren of de instellingen juist zijn gemaakt. Wanneer onderstaande opdracht geen output oplevert heb je het goed gedaan:

opendkim-testkey -d mydomain.tld -s default

OpenDKIM aan Postfix koppelen

Nu OpenDKIM als Linux socket beschikbaar is, kan deze als milter (samenvoeging van "mail filter") aan Postfix gekoppeld worden. Gezien elke mail door Postfix aan het milter wordt doorgegeven, wordt elke mail door OpenDKIM ondertekend en vervolgens aan Postfix teruggegeven voor verdere bewerking/verzending.

OpenDKIM socket instellen

Postfix is chrooted naar /var/spool/postfix — deze map is voor Postfix de "root" map — waardoor de service met de standaardconfiguratie niet bij de socket van OpenDKIM kan. De juiste socket-locatie kan ingesteld worden in /etc/default/opendkim:

SOCKET="local:/var/spool/postfix/opendkim/opendkim.sock"

Wanneer er eventueel nog een "Socket"-regel aanwezig is in /etc/opendkim.conf, wordt deze door bovenstaande overschreven. Vervolgens dient deze nieuwe socket-map nog maken en OpenDKIM herstarten om de nieuwe instellingen te laten werken:

mkdir -p /var/spool/postfix/opendkim
chown opendkim:opendkim /var/spool/postfix/opendkim
service opendkim restart

Postfix milter instellen

Voeg onderstaande regels toe aan /etc/postfix/main.cf:

milter_protocol = 6
milter_default_action = accept
smtpd_milters = unix:opendkim/opendkim.sock
non_smtpd_milters = $smtpd_milters

Wanneer je gebruik maakt van een oudere versie van Postfix, gebruik dan milter_protocol = 2. Gebruik eventueel het commando postconf -v | grep 'mail_version' om dit te controleren.

De regel "milter_default_action = accept" zorgt dat er geen bounces worden gegenereerd als OpenDKIM niet juist functioneert. De mail wordt dus altijd geaccepteerd, in het ergste geval alleen niet ondertekend.

OpenDKIM ondertekent mails meerdere keren

OpenDKIM kan meerdere keren de DKIM-signature-header toevoegen aan e-mails, wanneer je gebruik maakt van aparte services als ClamSMTP, Amavisd of Spamassassin. Dit komt omdat de milters voor elke aparte service opnieuw worden aangeroepen.

Om dit op te lossen dient aan deze extra services de optie "no_milters" als receive_override_options te worden toegevoegd in /etc/postfix/master.cf:

smtp      inet  n     -     -     -     -     smtpd
  -o receive_override_options=no_address_mappings,no_milters

Deze regel kan onder elke extra service worden toegevoegd om bij die betreffende service de milters uit te schakelen. Herstart Postfix na deze aanpassing met "service postfix restart".

Conclusie

Door gebruik te maken van DKIM, bewijs je dat de afzender van een e-mail ook daadwerkelijk de echte afzender is, dat de e-mail via jouw eigen mailservers is verzonden en door de ontvangende partij vertrouwd kan worden. Vervolgens kan de ontvangende partij hierop reageren, bijvoorbeeld door het spamfilter minder strict te laten reageren op e-mail die met DKIM ondertekend is.

DKIM is o.a. bedacht om mail spoofing of identity spoofing tegen te gaan. Het nadeel is echter dat het aan de ontvangende partij is wat hij/zij hiermee doet. Een extreem geval van Microsoft (e-maildomeinen als hotmail.com, live.com en outlook.com) blokkeert e-mail in z'n geheel als deze geen DKIM ondertekening heeft, weer andere partijen zorgen dat spamassassin één punt minder op de spamscore registreert.

Omdat je niet direct kunt zien of DKIM juist is ingesteld of dat er partijen zijn die zich als jou voordoen, werkt DKIM het beste als er tevens gebruik gemaakt wordt van DMARC. DMARC verstuurt eens per dag een e-mail met een overzicht welke servers namens jouw domein e-mail hebben verzonden en of deze juist verifiëren d.m.v. DKIM. Wanneer je hier ook nog SPF aan toevoegt maak je jouw e-mails bijna onmogelijk te spoofen.

Bronnen

  1. OpenDKIM configuratie:
    https://help.ubuntu.com/community/Postfix/DKIM
    http://manpages.ubuntu.com/manpages/precise/man5/opendkim.conf.5.html
  2. Uitleg hoe opendkim-genkey te gebruiken:
    http://askubuntu.com/questions/438756/using-dkim-in-my-server-for-multiple-domains-websites
  3. OpenDKIM testen:
    https://www.linode.com/docs/email/postfix/configure-spf-and-dkim-in-postfix-on-debian-8
  4. OpenDKIM socket juist instellen
    1. Postfix is chrooted
      https://cppoon.wordpress.com/2013/10/02/my-experience-of-setting-up-dkim-and-spf-with-postfix-and-ubuntu-for-sending-email/
    2. Juiste socket locatie:
      https://petermolnar.net/howto-spf-dkim-dmarc-postfix/
  5. Postfix milter:
    1. Juiste milter_protocol:
      https://redmine.froxlor.org/issues/1026
    2. Postfix versie bepalen:
      https://www.howtoforge.com/faq/how-to-find-out-the-postfix-version