Zum Inhalt

OpenDKIM

Inhalt

  • OpenDKIM 2.10.3
  • DKIM-Signing als Milter für Postfix
  • 2048 Bit RSA
  • KeyTable, SigningTable, TrustedHosts
  • VBR-Unterstützung im Paket, in diesem HowTo aber nicht separat konfiguriert

Einleitung

Dieses HowTo beschreibt die Installation und Konfiguration von OpenDKIM auf FreeBSD 15+.

OpenDKIM wird in diesem Setup als Milter für Postfix verwendet und signiert ausgehende E-Mails per DKIM. Der aktuelle FreeBSD-Port mail/opendkim steht bei 2.10.3 und beschreibt OpenDKIM als DKIM-Bibliothek plus milter-basierte Filteranwendung. Das Paket enthält außerdem Unterstützung für VBR, dieses HowTo konzentriert sich aber bewusst auf DKIM-Signing mit 2048-Bit-RSA.


Voraussetzungen

Zu den Voraussetzungen für dieses HowTo siehe bitte: Hosting System

Zusätzlich wird vorausgesetzt:

  • Postfix ist bereits installiert und für Milter vorbereitet.
  • Die Absenderdomain example.com ist bereits produktiv in Verwendung.
  • DNS-Änderungen für example.com können veröffentlicht werden.
  • Der Server versendet E-Mails über Postfix.
  • Für dieses HowTo wird example.com als Beispiel verwendet und muss an den passenden Stellen ersetzt werden.

Vorbereitungen

DNS Records

Für dieses HowTo müssen zuvor folgende DNS-Records angelegt werden, sofern sie noch nicht existieren, oder entsprechend geändert werden, sofern sie bereits existieren.

Text Only
mail.example.com.        IN  A       __IPADDR4__
mail.example.com.        IN  AAAA    __IPADDR6__

Der eigentliche DKIM-Selector-Record wird erst nach der Schlüsselerzeugung veröffentlicht, weil er direkt aus dem generierten öffentlichen Schlüssel entsteht. opendkim-genkey erzeugt dafür bereits eine passende TXT-Datei. (FreeBSD Manual Pages)

Gruppen / Benutzer / Passwörter

Für dieses HowTo müssen keine zusätzlichen Systemgruppen, Systembenutzer oder Passwörter angelegt werden.

Bash
pw groupshow opendkim >/dev/null 2>&1 || pw groupadd -n opendkim -g 5118
id -u opendkim >/dev/null 2>&1 || \
  pw useradd -n opendkim -u 5118 -i 5118 -g opendkim -c 'OpenDKIM User' -d /var/run/opendkim -s /usr/sbin/nologin -w no
pw groupmod opendkim -m postfix

Das FreeBSD-rc-Skript verwendet standardmäßig den Benutzer und die Gruppe mailnull. (GitHub)

Verzeichnisse / Dateien

Für dieses HowTo müssen zuvor folgende Verzeichnisse angelegt werden, sofern sie noch nicht existieren, oder entsprechend geändert werden, sofern sie bereits existieren.

Bash
mkdir -p /var/spool/postfix/opendkim
chown opendkim:opendkim /var/spool/postfix/opendkim
chmod 770 /var/spool/postfix/opendkim

mkdir -p /usr/local/etc/mail/keys
chown opendkim:opendkim /usr/local/etc/mail/keys
find /usr/local/etc/mail/keys -type d -exec chmod 500 {} \;
find /usr/local/etc/mail/keys -type f -exec chmod 400 {} \;

Für diese HowTos müssen zuvor folgende Dateien angelegt werden, sofern sie noch nicht existieren, oder entsprechend geändert werden, sofern sie bereits existieren.

Bash


Installation

Wir installieren mail/opendkim und dessen Abhängigkeiten.

Bash
mkdir -p /var/db/ports/mail_opendkim
cat <<'EOF' > /var/db/ports/mail_opendkim/options
_OPTIONS_READ=opendkim-2.10.3
_FILE_COMPLETE_OPTIONS_LIST=FILTER CURL GNUTLS JANSSON LDNS LMDB LUA MEMCACHED  BDB_BASE OPENDBX OPENLDAP POPAUTH QUERY_CACHE SASL DOCS STOCK_RESOLVER UNBOUND ALLSYMBOLS CODECOVERAGE DEBUG ADSP_LISTS ATPS DB_HANDLE_POOLS  DEFAULT_SENDER DIFFHEADERS IDENTITY_HEADER  LDAP_CACHING POSTGRES_RECONNECT_HACK  RATE_LIMIT RBL REPLACE_RULES REPRRD  REPUTATION RESIGN SENDER_MACRO  SOCKETDB STATS STATSEXT VBR
OPTIONS_FILE_SET+=FILTER
OPTIONS_FILE_SET+=CURL
OPTIONS_FILE_UNSET+=GNUTLS
OPTIONS_FILE_UNSET+=JANSSON
OPTIONS_FILE_SET+=LDNS
OPTIONS_FILE_SET+=LMDB
OPTIONS_FILE_UNSET+=LUA
OPTIONS_FILE_UNSET+=MEMCACHED
OPTIONS_FILE_UNSET+=BDB_BASE
OPTIONS_FILE_UNSET+=OPENDBX
OPTIONS_FILE_UNSET+=OPENLDAP
OPTIONS_FILE_UNSET+=POPAUTH
OPTIONS_FILE_SET+=QUERY_CACHE
OPTIONS_FILE_UNSET+=SASL
OPTIONS_FILE_UNSET+=DOCS
OPTIONS_FILE_UNSET+=STOCK_RESOLVER
OPTIONS_FILE_SET+=UNBOUND
OPTIONS_FILE_UNSET+=ALLSYMBOLS
OPTIONS_FILE_UNSET+=CODECOVERAGE
OPTIONS_FILE_UNSET+=DEBUG
OPTIONS_FILE_SET+=ADSP_LISTS
OPTIONS_FILE_UNSET+=ATPS
OPTIONS_FILE_UNSET+=DB_HANDLE_POOLS
OPTIONS_FILE_UNSET+=DEFAULT_SENDER
OPTIONS_FILE_UNSET+=DIFFHEADERS
OPTIONS_FILE_SET+=IDENTITY_HEADER
OPTIONS_FILE_UNSET+=LDAP_CACHING
OPTIONS_FILE_UNSET+=POSTGRES_RECONNECT_HACK
OPTIONS_FILE_UNSET+=RATE_LIMIT
OPTIONS_FILE_UNSET+=RBL
OPTIONS_FILE_UNSET+=REPLACE_RULES
OPTIONS_FILE_UNSET+=REPRRD
OPTIONS_FILE_UNSET+=REPUTATION
OPTIONS_FILE_UNSET+=RESIGN
OPTIONS_FILE_UNSET+=SENDER_MACRO
OPTIONS_FILE_UNSET+=SOCKETDB
OPTIONS_FILE_UNSET+=STATS
OPTIONS_FILE_UNSET+=STATSEXT
OPTIONS_FILE_UNSET+=VBR

EOF

portmaster -w -B -g -U --force-config mail/opendkim -n

Dienst in rc.conf eintragen

Der Dienst wird mittels sysrc in der rc.conf eingetragen und dadurch beim Systemstart automatisch gestartet.

Bash
sysrc milteropendkim_enable="YES"
sysrc milteropendkim_cfgfile="/usr/local/etc/mail/opendkim.conf"
sysrc milteropendkim_uid="opendkim"
sysrc milteropendkim_gid="opendkim"
sysrc milteropendkim_socket="local:/var/spool/postfix/opendkim/opendkim.sock"
sysrc milteropendkim_socket_perms="0770"

Das FreeBSD-rc-Skript verwendet den Dienstnamen milter-opendkim, die rc.conf-Variable heißt aber milteropendkim_enable. Die Standard-Konfigurationsdatei liegt unter /usr/local/etc/mail/opendkim.conf. Das Socket-Verzeichnis für lokale Sockets wird vom rc-Skript beim Start selbst angelegt, sofern milteropendkim_socket gesetzt ist. Eine separate milteropendkim_pidfile-Variable ist im rc-Skript dagegen nicht vorgesehen; das Skript liest PidFile aus der Konfiguration oder fällt auf /var/run/milteropendkim/pid zurück. (GitHub)


Konfiguration

Konfigurationsdatei

Bash
cat <<'EOF' > /usr/local/etc/mail/opendkim.conf
AlwaysAddARHeader       yes
AuthservID              mail.example.com
AutoRestart             Yes
AutoRestartRate         10/1h
BaseDirectory           /var/run/opendkim
BodyLengthDB            refile:/usr/local/etc/mail/bodylengthdb.cfg
Canonicalization        relaxed/simple
LogWhy                  Yes
Mode                    sv
On-BadSignature         reject
OversignHeaders         From
PidFile                 /var/run/opendkim/opendkim.pid
ReportAddress           "DKIM Error Postmaster" <postmaster@example.com>
ReportBccAddress        admin@example.com
SendReports             Yes
SignatureAlgorithm      rsa-sha256
SMTPURI                 smtp://localhost
Socket                  local:/var/spool/postfix/opendkim/opendkim.sock
SubDomains              Yes
Syslog                  Yes
SyslogFacility          mail
SyslogSuccess           Yes
TrustAnchorFile         /usr/local/etc/unbound/root.key
UMask                   007
UserID                  opendkim
KeyTable                file:/usr/local/etc/mail/keytable
SigningTable            refile:/usr/local/etc/mail/signingtable
InternalHosts           refile:/usr/local/etc/mail/trustedhosts
ExternalIgnoreList      refile:/usr/local/etc/mail/trustedhosts
MacroList               dameon_name|ORIGINATING
EOF

cat <<'EOF' > /usr/local/etc/mail/bodylengthdb.cfg
.*
.*
EOF

Signing-Key erzeugen

opendkim-genkey erzeugt sowohl den privaten Schlüssel als auch direkt die passende DNS-TXT-Datei. Standardmäßig wären 1024 Bit voreingestellt; für dieses Setup werden bewusst 2048 Bit verwendet. Mit -r wird der Schlüssel auf E-Mail-Signing beschränkt. (FreeBSD Manual Pages)

Bash
mkdir -p /usr/local/etc/mail/keys/example.com

opendkim-genkey \
  --append-domain \
  --bits=2048 \
  --directory=/usr/local/etc/mail/keys/example.com \
  --domain=example.com \
  --hash-algorithms=sha256 \
  --note=example.com \
  --restrict \
  --selector=20260321 \
  --verbose

KeyTable anlegen

Bash
cat <<'EOF' > /usr/local/etc/mail/keytable
20260321._domainkey.example.com    example.com:20260321:/usr/local/etc/mail/keys/example.com/20260321.private
EOF

SigningTable anlegen

Bash
cat <<'EOF' > /usr/local/etc/mail/signingtable
*@example.com      20260321._domainkey.example.com
*@*.example.com    20260321._domainkey.example.com
EOF

TrustedHosts anlegen

Bash
cat <<'EOF' > /usr/local/etc/mail/trustedhosts
::1
127.0.0.1
fe80::/10
10.0.0.0/8
__IPADDR4__/32
__IPADDR6__/64
localhost
example.com
*.example.com
EOF

# Standard-Interface ermitteln
DEF_IF="$(route -n get -inet default | awk '/interface:/ {print $2}')"

# Primäre IPv4-Adresse ermitteln
IP4="$(ifconfig "$DEF_IF" inet | awk '/inet / && $2 !~ /^127\./ {print $2}' | head -n 1)"
[ -n "$IP4" ] && sed -e "s|__IPADDR4__|$IP4|g" -i '' /usr/local/etc/mail/trustedhosts

# Primäre globale IPv6-Adresse ermitteln
IP6="$(ifconfig "$DEF_IF" inet6 | awk '/inet6 / && $2 !~ /^fe80:/ && $2 !~ /^::1/ {print $2}' | head -n 1)"
[ -n "$IP6" ] && sed -e "s|__IPADDR6__|$IP6|g" -i '' /usr/local/etc/mail/trustedhosts

Rechte setzen

opendkim-testkey meldet ausdrücklich, wenn eine private Schlüsseldatei für andere Benutzer lesbar ist. Deshalb sollten die Schlüsseldateien nicht unnötig offen liegen. (FreeBSD Manual Pages)

Bash
chown -R opendkim:opendkim /usr/local/etc/mail/keys
find /usr/local/etc/mail/keys -type d -exec chmod 500 {} \;
find /usr/local/etc/mail/keys -type f -exec chmod 400 {} \;

DNS-TXT-Record veröffentlichen

opendkim-genkey erzeugt den passenden TXT-Record bereits selbst in der Datei 20260321.txt. Diese Datei wird als Grundlage für den DNS-Eintrag veröffentlicht. (FreeBSD Manual Pages)

Es muss noch ein DNS-Record angelegt werden, sofern er noch nicht existiert, oder entsprechend geändert werden, sofern er bereits existiert.

Bash
/usr/local/bin/openssl pkey -pubout -outform pem -in /usr/local/etc/mail/keys/example.com/20260321.private | \
    awk '\!/^-----/ {printf $0}' | awk 'BEGIN{n=1}\
        {printf "\n20260321._domainkey.example.com.    IN  TXT    ( \"v=DKIM1; h=shs256; k=rsa; s=*; t=*; p=\"";\
            while(substr($0,n,98)){printf "\n        \"" substr($0,n,98) "\"";n+=98};printf " )\n"}'

Die Ausgabe sieht ungefähr so aus und muss als DNS-Record für die Domain veröffentlicht werden:

Text Only
#
# The output should look similar to this one, which will be the DNS-Record to publish
#
# Note: The folding of the pubkey is necessary as most nameservers have a line-length limit
#       If you use a DNS-Provider to publish your records, then use their free-text fields
#       to insert the record into their form
#
20260321._domainkey.example.com.    IN  TXT    ( "v=DKIM1; h=shs256; k=rsa; s=*; t=*; p="
        "MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA1Up5Z0TkPpE0mNAc9lf7Uug7P/n28Kk6fXC1V8m93dE+NPgsTKp4k+"
        "t2S3EujANO7J8WyBppE+aTbyQjU5TtaIPC8TS3sBg/6JX/QAw73+Hv03lieutmZ0GO4uuvj+QbOuDqNwHR/DZih3BrV7Mtit4F"
        "bILcz+V1QbJ7YssRQRaZ/LTGZ0Q6QLGr6BG9h3Ro4g1bTirFIuvbaVUuzDK/KxHKRAuAhIB7mmrpPRDQlFjgva9vQYsQUcQtVh"
        "Y/z6YvcGNvEWhme3gaTWzdG20aLTxut4Il17OSWiCbF0wdnUn0bnKins14YeHjkDhOhMoEagd3lWWs0k2KNxnbYljPQwIDAQAB" )

Konfiguration prüfen

Vor dem ersten Start sollte die Konfiguration immer geprüft werden. opendkim-testkey ist genau für diesen Zweck gedacht: Es prüft Domain, Selector, öffentlichen DNS-Key und bei Bedarf auch den privaten Schlüssel. (FreeBSD Manual Pages)

Bash
opendkim-testkey -d example.com -s 20260321 -k /usr/local/etc/mail/keys/example.com/20260321.private -vvv
service milter-opendkim start
sockstat -4 -6 -l | egrep 'opendkim|milter'

Datenbanken

Für dieses HowTo sind keine Datenbanken erforderlich.


Zusatzsoftware

Mögliche Zusatzsoftware wird hier installiert und konfiguriert.

Für dieses HowTo ist keine zusätzliche Software erforderlich.

OpenDKIM selbst enthält laut Portbeschreibung zwar auch VBR-Unterstützung, dieses HowTo richtet aber nur die DKIM-Signatur für ausgehende E-Mails ein. (FreshPorts)


Aufräumen

Überflüssige oder temporäre Verzeichnisse und Dateien entsorgen.

Zusatzsoftware Installation

Nicht erforderlich.

Zusatzsoftware Konfiguration

Nicht erforderlich.


Abschluss

OpenDKIM kann nun gestartet werden.

Bash
service milter-opendkim start

Für spätere Änderungen:

Bash
service milter-opendkim reload
service milter-opendkim restart

Referenzen

  • FreshPorts: mail/opendkim
  • FreeBSD Ports rc-Skript: milter-opendkim
  • FreeBSD Manpage: opendkim(8)
  • FreeBSD Manpage: opendkim-genkey(8)
  • FreeBSD Manpage: opendkim-testkey(8)
  • OpenDKIM Dokumentation: opendkim.conf(5)