### 1. 安装 opensmtpd

先卸载所有先有的 MTA 和 MDA。

# apt install opensmtpd

会弹出 CUI 配置界面: 1. 主机名 2. 接收 root, admin, postmaster 等管理邮件时使用的用户账户,由于我们平时不收邮件, 可以填自己的普通权限账户。

随后我们需要手工配置,这个自动配置向导基本上没什么用。

### 2. 安装 DKIMProxy

# apt install dkimproxy

会自动生成 RSA-1024 密钥。

### 3. 卸载 amavisd-new

不知道为什么会自动捆绑安装一个查毒软件,不知道打包者怎么想的,卸载。

# apt purge amavisd-new

### 4. 配置 DKIMProxy

RSA-1024 太弱了,重新生成 RSA-2048。

# cd /var/lib/dkimproxy/
# openssl genpkey -algorithm RSA -out private.key -pkeyopt rsa_keygen_bits:2048
# openssl rsa -pubout -in private.key -out public.key
# chmod 644 public.key
# chmod 640 private.key

明明 dkimproxy 已经加入 ssl-cert 用户组,但依然无法读取 private.key,不知道这又是什么 打包的 bug,修改

# chown root:dkimproxy public.key private.key

编辑配置文件 /etc/dkimproxy/dkimproxy_out.conf,清空并改写为:

# specify what address/port DKIMproxy should listen on
listen    127.0.0.1:10028

# specify what address/port DKIMproxy forwards mail to
relay     127.0.0.1:10029

# specify what signatures to add
signature dkim(c=relaxed,a=rsa-sha256)
signature domainkeys(c=nofws,a=rsa-sha1)

# specify the selector (i.e. the name of the key record put in DNS)
selector  42

selector 是任意的一个名称或 ID,用来区分同一主机名的不同 DKIM 签名服务器。

编辑配置文件 /etc/default/dkimproxy,修改:

DKIM_HOSTNAME="example.com"
DOMAIN="example.com"

默认是 `hostname -d`,注意不要忘记修改引号,不然字符串会成为命令,然后就会出现配置文件 无效的错觉……

编辑启动脚本 /etc/init.d/dkimproxy,修改 DKIMPROXY_OUT_ARGS,去除一些在配置文件里修改过 的硬编码参数,最终如下:

DKIMPROXY_OUT_ARGS="--domain=${DOMAIN} --conf_file=${DKOUT_CONF} --keyfile=${DKIMPROXY_OUT_PRIVKEY} ${COMMON_ARGS} --pidfile=${PIDDKIMPROXY_OUT} --min_servers=${DKIMPROXY_OUT_MIN_SERVERS}"

### 5. 配置 opensmtpd 主机名

# echo example.com > /etc/mailname

编辑 /etc/smtpd.conf,填写:

# This is the smtpd server system-wide configuration file.
# See smtpd.conf(5) for more information.

# To accept external mail, replace with: listen on all
listen on lo

# DKIM signature.
# We forward all outgoing mail to the DKIMProxy relay at 10028,
# and receive it again from 10029.
listen on lo port 10029 tag DKIM
accept tagged DKIM for any relay
accept from local for any relay via smtp://127.0.0.1:10028

# Some hacks, only use in case you need

# 1. if IPv6 doesn't function properly on the server. 
# limit mta inet4    
# 2. sometimes Gmail labels mails from IPv6 server as spam no matter how
#    properly configurated it is.
# limit mta for domain gmail.com inet4
# limit mta for domain googlemail.com inet4 

# If you edit the file, you have to run "smtpctl update table aliases"
table aliases file:/etc/aliases

# Uncomment the following to accept external mail for domain "example.org"
#accept from any for domain "example.org" alias <aliases> deliver to mbox

accept for local alias <aliases> deliver to mbox

### 6. 配置 DNS 记录

#### A. IP 的反向 DNS

在服务器管理处设置为 example.com。

#### B. SPF 记录

给 example.com 设置 TXT 记录,内容为

v=spf1 mx a include:example.com ~all

表示接收 example.com 的 MX 与 A 记录对应之 IP 地址,并拒绝(~,即 not)其他一切(all) 服务器。

#### C. DKIM 记录

给 42._domainkey.example.com 设置 TXT 记录,内容使用以下 Shell 命令生成:

# echo "v=DKIM1; k=rsa; h=sha256; p=`cat /var/lib/dkimproxy/public.key | grep -v -- "-----" | tr -d "\n"`"

给 _domainkey.example.com 设置 TXT 记录,内容为

o=~

将 o 参数设置为 ~,代表全部发出邮件均使用了 DKIM。

#### D. DMARC 记录

给 _dmarc.example.com 设置 TXT 记录,内容为

v=DMARC1; p=reject;

将 p 参数设置为 reject,代表要求其他服务器拒收不合格邮件。

### 6. 测试

# sendmail -f root@example.com -F "The Example Organization" receive@gmail.com
To: <receive@gmail.com>
Subject: This is a test.

This is just a test.
^D

打开 GMail 查看原始邮件,应看到:

主题:	This is a test.
SPF:	PASS
DKIM:	'PASS'
DMARC:	'PASS'

DKIM-Signature: v=1; a=rsa-sha256; c=relaxed;
DomainKey-Signature: a=rsa-sha1;
<code>

说明配置正确。

注:DKIM-Signature 是 RFC 标准的 DKIM 规范,而 DomainKey-Signature 是早年 Yahoo 提出的
规范,不支持 sha256,留着可以保证最大程度的兼容性。

并且 localhost, localdomain 等 local 内部保留主机名不得在除了

<code>
    Received: from example.com (localhost [127.0.0.1])

以外的地方出现。否则说明某些服务的主机名没有进行配置。

至今配置正确。