最後更新: 2018-12-18
介紹
Run outside the MTA to inspect SMTP events ( All this happens before mail is queued )
目錄
Install
apt-get install opendkim opendkim-tools # Debian
yum install opendkim # Centos 7 (epel)
dnf install opendkim opendkim-tools # Centos 8
Create Key & DNS Setting
Create key and dns record
# 建立了 mail.private (opendkim load 它) mail.txt (在 DNS Server 上設定它)
DOMAIN=datahunter.org
mkdir /etc/opendkim/keys/$DOMAIN -p
cd $_
# 獲得 dkim.private (key) 及 dkim.txt (dns record)
opendkim-genkey -s dkim -d $DOMAIN
# keys referenced by the KeyTable must always be accessible for read by the unprivileged user.
- chown root.opendkim dkim.private
- chmod 640 dkim.private
cat dkim.txt # dns record
DKIM DNS Record Rormat
SELECTOR._domainkey IN TXT ...
當 "opendkim-genkey -s dkim ..." 時, SELECTOR 就係 dkim
Verify DNS Record
dig -t txt dkim._domainkey.${DOMAIN}
# -d domain ; -s selector ; -k keypath
opendkim-testkey -d $DOMAIN -s dkim -k dkim.private
# 失敗:
opendkim-testkey: 'mail._domainkey.example.com' record not found
# 成功
echo $? # 成功是 0
SigningTable 與 KeyTable
grep -e KeyTable -e SigningTable /etc/opendkim
SigningTable
/etc/opendkim/signing.table
# lists the signatures to apply to a message based on the address found in the From: header field
# domain short name for the domain
*@datahunter.org datahunter
KeyTable
/etc/opendkim/key.table
maps key names to signing keys
Format
example DOMAIN_NAME:SELECTOR:KEY_FILE
i.e.
datahunter datahunter.org:dkim:/etc/opendkim/keys/datahunter.org/dkim.private
Setup opendkim
設定(Centos 7)
/etc/opendkim.conf
AutoRestart Yes AutoRestartRate 10/1h UMask 002 Syslog yes SyslogFacility mail SyslogSuccess Yes LogWhy Yes SoftwareHeader Yes Canonicalization relaxed/relaxed # Map domains in From addresses to keys used to sign messages KeyTable /etc/opendkim/key.table SigningTable refile:/etc/opendkim/signing.table # Hosts to ignore when verifying signatures ExternalIgnoreList /etc/opendkim/TrustedHosts InternalHosts /etc/opendkim/TrustedHosts Mode sv PidFile /var/run/opendkim/opendkim.pid SignatureAlgorithm rsa-sha256 UserID opendkim:opendkim #設定 Socket, 詳見下一 Part # 方式1 Socket inet:8891@localhost # 方式2 #Socket local:/var/spool/postfix/opendkim/opendkim.sock #Umask 000
AutoRestart
Auto restart the filter on failures
AutoRestartRate
Specifies the filter's maximum restart rate, if restarts begin to happen faster than this rate, the filter will terminate;
10/1h - 10 restarts/hour are allowed at most
UMask
gives all access permissions to the user group defined by UserID
and allows other users to read and execute files,
in this case it will allow the creation and modification of a Pid file.
SoftwareHeader
To add an "DKIM-Filter" header field indicating the presence of this filter
Canonicalization
Select canonicalizations to use when signing.
Valid values for each are "simple" and "relaxed"
- simple: allows almost no modification
- relaxed: one tolerates minor changes such as whitespace replacement;
relaxed/simple - the message header will be processed with the relaxed algorithm and the body with the simple one
refile
regular expression file
Mode
Default 只有 verifier (v)
declares operating modes; in this case the milter acts as a signer (s) and a verifier (v)
TrustedHosts
/etc/opendkim/TrustedHosts
127.0.0.1 localhost # mx1 IP # mx2 IP
Enable Service
systemctl start opendkim --now
Checking
[方式 1]
# Socket inet:8891@localhost
netstat -tnlp | grep 8891
OR
# Socket local:/var/spool/postfix/opendkim/opendkim.sock
ls /var/spool/postfix/opendkim/opendkim.sock
[方式 2] 在有 "Syslog yes" 及 "SyslogFacility mail" 設定時可以到 /var/log/mail.log 查看
grep opendkim /var/log/maillog
... opendkim[5358]: OpenDKIM Filter: mi_stop=1 ... opendkim[5358]: OpenDKIM Filter v2.0.1 terminating with status 0, errno = 0 ... opendkim[5380]: OpenDKIM Filter v2.0.1 starting (args: ... )
設定 Socket
[方案 A] TCP Socket <- 最簡單的做法, 不用理 postfix 的 chroot 及 permission
/etc/opendkim.conf
Socket inet:8891@localhost
[方案 B] Unix Socket
mkdir -p /var/spool/postfix/var/run/opendkim
chown opendkim.postfix /var/spool/postfix/var/run/opendkim
chmod 770 /var/spool/postfix/var/run/opendkim
[Centos] /etc/opendkim.conf
SOCKET="local:/var/spool/postfix/var/run/opendkim/opendkim.sock" Umask 000
* chrooted postfix path
ls -l /var/spool/postfix/opendkim/opendkim.sock
srwxrwxrwx 1 opendkim opendkim 0 Aug 13 10:39 /var/spool/postfix/opendkim/opendkim.sock
Postfix 設定
[方案 A] 使用 TCP port (最簡單)
/etc/postfix/main.cf
# opendkim setup smtpd_milters = inet:localhost:8891 non_smtpd_milters = $smtpd_milters milter_default_action = accept milter_protocol = 6
[方案 B] unix socket
grep ^smtp /etc/postfix/master.cf
smtp inet n - n - - smtpd smtp unix - - n - - smtp
* 沒有 chroot
/etc/postfix/main.cf
# opendkim setup smtpd_milters = unix:/var/spool/postfix/opendkim/opendkim.sock non_smtpd_milters = $smtpd_milters milter_default_action = accept milter_protocol = 6
service postfix restart
出/收信的 log
出信的 log
# opendkim-2.11.0
tail -f /var/log/maillog | grep opendkim
... opendkim[25507]: 741FA53F63: DKIM-Signature field added (s=dkim, d=datahunter.org)
收信的 log
# opendkim-2.11.0
... opendkim[32548]: 342661533: mail-ot1-f43.google.com [209.85.210.43] not internal ... opendkim[32548]: 342661533: not authenticated # (1) ... opendkim[32548]: 342661533: DKIM verification successful # (2)
(1) the OpenDKIM milter thinks the mail was not submitted by an authenticated user
(2) 來信沒有 dkim 時: "no signature data"
Remark
當 remote login 後出信時見到
"... opendkim[32548]: 342661533: not authenticated"
OpenDKIM decides whether a message is authenticated or not based on the presence or absence of the {auth_type} macro
postconf milter_mail_macros
milter_mail_macros = i {auth_type} {auth_authen} {auth_author} {mail_addr} {mail_host} {mail_mailer}
- "i" (the envelope ID, also known as the job ID or the queue ID), which is used for logging;
- "auth_type", which is used to determine whether or not the SMTP client authenticated to the MTA
postfix 解釋
smtpd_milters (default: empty)
一共有兩類:
- SMTP mail filters (arrives via the Postfix smtpd server )( smtpd_milters=... )
- non-SMTP mail filters ( arrives via the Postfix sendmail(CLI) --> cleanup )( non_smtpd_milters=... )
milter_default_action:
The default action is to respond with a temporary error status
Specify "accept" if you want to receive mail as if the filter does not exist
milter_protocol (default: 6)
2 Use Sendmail 8 mail filter protocol version 2
(default with Sendmail version 8.11 .. 8.13 and Postfix version 2.3 .. 2.5).
6 Use Sendmail 8 mail filter protocol version 6
(default with Sendmail version 8.14 and Postfix version 2.6).
Doc
before-queue Milter: http://www.postfix.org/MILTER_README.html
man opendkim.conf
zcat /usr/share/doc/opendkim/examples/opendkim.conf.sample.gz