amavisd-new DKIM Howto

Abstract

amavisd-new kann seit langem DKIM-Signaturen in eingehenden Nachrichten erkennen und verifizieren sowie Policies abhängig vom Ergebnis der Verifzierung anwenden. Weniger bekannt ist, dass amavisd-new auch sehr einfach DKIM-Signaturen auf ausgehende Nachrichten anbringen kann. In diesem Blog zeige ich, wie alle drei genannten Funktionen aktiviert und genutzt werden.

Eine DKIM-Signatur etabliert die digitale Identität einer Sender-Domain. Sie ist die Grundlage für reputationsbasierte E-Mail-Policies und hilft Spam wie Phishing effektiv zu erkennen und von den Anwendern fernzuhalten.

amavisd-new kann seit langem DKIM-Signaturen in eingehenden Nachrichten erkennen und verifizieren sowie Policies abhängig vom Ergebnis der Verifizierung anwenden. Weniger bekannt ist, dass amavisd-new auch sehr einfach DKIM-Signaturen auf ausgehende Nachrichten anbringen kann. In diesem Blog zeige ich, wie alle drei genannten Funktionen aktiviert und genutzt werden.

DKIM-Signaturen verifizieren

DKIM-Signaturen machen Veränderungen an Header und Body erkennbar

amavisd-new verlässt sich auf die Perl-Bibliothek Mail-DKIM von Jason Lang, um eine DKIM-signierte Nachricht zu erkennen und die Gültigkeit ihrer Signatur zu überprüfen. Unter Debian ist sie einfach zu installieren:

$ sudo apt-get install libmail-dkim-perl

Note

Neuere amavisd-new-Versionen aktivieren die Verifikation von DKIM-Signaturen standardmäßig. Es kann also durchaus sein, dass die Mail-DKIM-Bibliothek bereits als Abhängigkeit während der Installation von amavisd-new aufgelöst und installiert wurde.

Um die DKIM-Verifizierung explizit zu aktivieren, muss in der Konfigurationsdatei – /etc/amavisd.conf oder /etc/amavis/conf.d/50-user auf Debian – folgender Parameter gesetzt werden:

$enable_dkim_verification = 1;

Nach dem Neuststart überprüft amavisd-new von nun an die Signaturen DKIM-signierter E-Mails auf ihre Gültigkeit. Das Prüfergebnis vermerkt es im dafür vorgesehenen Header Authentication-Results: :

Authentication-Results: mail.sys4.de (amavisd-new); dkim=pass (1024-bit key)
        header.d=example.com
...
DKIM-Signature: v=1; a=rsa-sha256; c=simple/simple; d=example.com; s=mail;
        t=1378023161; bh=cDhLKw7xbii5H41D4ljCDX3wo8z1PPdSY5LI8gNj0Lg=;
        h=References:In-Reply-To:Mime-Version:Content-Type:
        Content-Transfer-Encoding:Message-Id:Cc:From:Subject:Date:To;
        b=KYyZ6V7A2zOoxTk29KVKvLBby4kKMLC9QQ3GVT0pVUUJHmp99rbHU3siZY5U29u6W
        rT+g+UNr3AiLr2rpJ7M7WX4SMVZyUe6DFEzYQJaQFrNPgMkImp2Yv3i4up3zzeMdOe
        7UIQYiASDHBAQt1NThBaIDE1UDyrZXn8Pxvf1Phk=

Falls amavisd-new bei DKIM-signierten Nachrichten keine Authentication-Results:-Header einfügt, kann es daran liegen, dass diese Funktion explizit deaktiviert wurde:

$allowed_added_header_fields{lc('Authentication-Results')} = 0;

Falls keine anderen Gründe dagegen sprechen, aktivieren Sie die Funktion durch setzen der 1 statt der 0 wieder.

amavisd-new Policies mit DKIM steuern

Auf gültige Signaturen dürfen Policies angewendet werden, auf ungültige nicht. Grund für die ungültige Signatur könnte ein Verarbeitungsfehler und kein Phishing-Versuch auf Senderseite sein.

Note

Das ist ähnlich wie bei SPF: Stimmt das in SPF angekündigte Routing, kann man das für den Sender nutzen. Stimmt es nicht, sollte man die Abweichung nicht gegen den Sender verwenden.

Findet amavisd-new eine gültige DKIM-Signatur, prüft es in @author_to_policy_bank_maps, ob der Sender oder die Sender-Domain dort mit einer Policy gelistet sind:

@author_to_policy_bank_maps = ( {
    'python.org'              => 'WHITELIST,NOBANNEDCHECK,NOVIRUSCHECK',
    'amavis.org'              => 'WHITELIST,NOBANNEDCHECK,NOVIRUSCHECK',
    'p@sys4.de'               => 'WHITELIST,NOBANNEDCHECK,NOVIRUSCHECK',
    'postfix.org'             => 'NOBANNEDCHECK',
} );

Sender oder Sender-Domain verweisen auf $policy_banks, die bestimmte Funktionen aktivieren oder deaktivieren:

$policy_bank{'WHITELIST'} = {
  bypass_spam_checks_maps => [1],
  spam_lovers_maps => [1],
};

$policy_bank{'NOVIRUSCHECK'} = {
  bypass_decode_parts => 1,
  bypass_virus_checks_maps => [1],
  virus_lovers_maps => [1],
};

$policy_bank{'NOBANNEDCHECK'} = {
  bypass_banned_checks_maps => [1],
  banned_files_lovers_maps  => [1],
};

Note

Die im Beispiel genannten $policy_banks müssen manuell angelegt werden. Sie sind nicht Bestandteil einer Standardinstallation.

DKIM-Signaturen auf ausgehende Nachrichten anbringen

Das DKIM-Signieren einer Nachricht setzt ein x509-Schlüsselpaar voraus. Der Private Key wird an amavisd-new zum Unterschreiben der DKIM-Signaturen übergeben. Der Public Key wird über DNS veröffentlicht – so können ihn die Content-Filter auf Empfängerseite leicht herunterladen und für das Verifizieren der Signatur verwenden.

amavisd-new bringt eigene Kommandos mit, um x509-Schlüsselpaare zu erzeugen, sie auszugeben und um zu prüfen, ob sie grundsätzlich genutzt werden können. Beginnen wir damit, ein Schlüsselpaar zu erzeugen. Das folgende Kommando generiert ein Schlüsselpaar für die Sender-Domain example.com mit einer Schlüssellänge von 2048 Bits:

% amavisd-new genrsa /var/lib/amavis/db/example.com 2048
Private RSA key successfully written to file "/var/lib/amavis/db/example.com" \
  (2048 bits, PEM format)

Note

Schlüssel sollten immer eine Länge von wenigstens 1024 Bits haben. Alles darunter kann in endlicher Zeit missbraucht werden (s.a. Mathematiker entlarvt schwache DKIM-Schlüssel und die darauffolgende Vulnerability Note VU#268267).

Ist das Schlüsselpaar generiert, muss der Private Key in der Konfigurationsdatei von amavisd-news für die Sender-Domain deklariert werden:

$enable_dkim_signing = 0;
dkim_key('example.com', 'mail201309', '/var/lib/amavis/db/example.com');
@dkim_signature_options_bysender_maps = (
    { '.' =>
        {
                ttl => 21*24*3600,
                c => 'relaxed/simple'
        }
    }
);

Important

$enable_dkim_signing erst aktivieren, wenn auch der Public Key veröffentlicht und getestet worden ist. Andernfalls signiert amavisd-new ausgehende Nachrichten bereits, während Empfänger die Signatur noch nicht prüfen können. Das kann zu Rejects und Bounces führen!

Nun lässt sich auch der Public Key ausgeben. amavisd-new generiert dabei gleich den passenden ZONE-Eintrag für einen bind-Nameserver. Der TXT-Record listet auch die optionalen DKIM-Angaben, die in @dkim_signature_options_bysender_maps gemacht wurden:

% amavisd-new showkeys example.com
; key#1, domain example.com, /var/lib/amavis/db/example.com
mail201309._domainkey.example.com.      3600 TXT (
  "v=DKIM1; p="
  "MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAvrqQssP4rC6bo22YzzpX"
  "zd0OCBRrcN6uPpRrvPq69Nn/i/B3dSzu639OWt622QXdUBS8e5xFZnZslPMMIRDl"
  "QIJx/HFoYY6wgUm4B8Nb83SJK0aLGtlMwxhlGEkSX8gNlmMsA28LWeEIQhJyA9+D"
  "7j7DcA0aGJU3JzFgG/YHBYL8+6RWAKf+vgGQNmGYBPCb3Mm5LQqAzqE55yW+iL06"
  "cYHs+7niLWyAbosRhfCea0i+WqBIrclH32mXwNt/FO43lDlnPdy+gaHaE4fnqNqN"
  "3jK5YnslEd3mHJd/a20eaHjwjXSP6F48KKsQuL+rezohlG5QKQF9qIZbHHEHp4Yn"
  "AwIDAQAB")

Dieser TXT-Eintrag muss nun im ZONE-File der Sender-Domain (hier: example.com) eingetragen werden. Nach einen reload der Zone kann amavisd-new prüfen, ob der Public Key erreichbar ist und die Schlüssel zueinander passen:

% amavisd testkeys sys4.de
TESTING#1: mail201309._domainkey.example.com     => pass

Liefert der Test ein pass, ist alles im grünen Bereich.

Damit amavisd-new nun auch beginnt, ausgehende Nachrichten zu signieren, muss nicht nur das bereits eingetragene $enable_dkim_signing aktiviert werden. amavisd-new muss auch wissen, welche Nachrichten ausgehend sind.

Ausgehende Nachrichten werden in amavisd-new über den Parameter ORIGINATING gekennzeichnet. Dieser ist standardmäßig nicht gesetzt. Er muss kontrolliert, d.h. nur auf vertraute Netze und Submission-Sender angewendet werden. In einer $policy_bank für Submission-Sender sieht das etwa so aus:

$policy_bank{'SUBMISSION'} = {
    originating => 1,
    bypass_spam_checks_maps   => [1],
    bypass_banned_checks_maps => [1],
    final_virus_destiny => D_REJECT,
    final_bad_header_destiny => D_PASS,
    terminate_dsn_on_notify_success => 0,
    warnbadhsender => 1,
};

Nach einem Reload wird amavisd-new ausgehende Nachrichten mit DKIM-Signaturen versehen.

Note

Mehr zu $policy_banks und Senderichtungen habe ich in E-Mail Content Policies mit amavis steuern beschrieben.

Patrick Koetter, 02. September 2013