邮件系统概念

基本概念

MUA(Mail User Agent)接收邮件所使用的邮件客户端,使用IMAP或POP3协议与服务器通信;

MTA(Mail Transfer Agent) 通过SMTP协议发送、转发邮件;

MDA(Mail Deliver Agent)将MTA接收到的邮件保存到磁盘或指定地方,通常会进行垃圾邮件及病毒扫描;在许多情况下,MDA 实际上是一个本地交付代理 (LDA);

MRA(Mail Receive Agent)负责实现IMAP与POP3协议,与MUA进行交互;

SMTP(Simple Mail Transfer Protocol)传输发送邮件所使用的标准协议;

IMAP(Internet Message Access Protocol)接收邮件使用的标准协议之一;

POP3(Post Office Protocol 3) 接收邮件使用的标准协议之一。

一套邮件系统服务端,基本由MTA、MDA(LDA)、MRA组件组成。

邮件发送和接收过程

1.假设邮件服务器为mail.imaginefei.com,发件人为user1@imaginefei.com,收件人为user2@imaginefei.com,用户使用邮件客户端foxmail发送一封邮件,客户端foxmail(MUA)会使用smtp协议与邮件服务器Postfix(MTA)mail.imaginefei.com通信,完成认证后,即将邮件信息给到了MTA。

2.MTA收到邮件后,会查询收件人域imaginefei.com的dns mx记录,如果是发往邮件服务器自己当前域的邮件,则会放在本地,给到MDA去投递,通常这个MDA会是LDA服务;如果收件人不是本域的,则会使用smtp协议,将邮件转发到mx记录指定的邮件服务器,让外域的MTA进行邮件的投递。

3.MDA从MTA处取到邮件,将邮件投递到收件人的邮箱中,这样,收件人的信箱中就有了一封未读邮件了。MDA大多数情况下都是一个本地交付代理(LDA),如在使用Dovecot中,就有dovecot-lda的工具或lmtp服务,两者的区别只是每次调用dovecot-lda命令还是以lmtp socket的形式发布出来,提供给MTA调用而已,这里需要注意的是,MDA可以是其他软件(procmail、dropmail),一般Dovecot只是一个MRA角色,只是工具包中提供了LDA工具。

4.用户user2@imaginefei.com使用邮件客户端foxmail,使用IMAP或POP3协议,与MRA(Dovecot)通信,将信箱中的邮件同步到本地,即可完成邮件的读取。

邮件格式和存储

电子邮件格式标准:https://www.ietf.org/rfc/rfc2822.txt

mbox类型:https://www.ietf.org/rfc/rfc4155.txt

常见的邮件存储格式有:

1.mbox:Mbox将大量的邮件存放在一个文件中。

2.Maildir:Maildir则是将每封邮件都存放在单独的文件当中。

3.Dovecot还支持其他格式存储,如:obox,dbox,imapc,pop3c。

方案架构

方案

本次环境搭建方案,将选用postfix作为MTA组件,Dovecot作为MRA组件,Dovecot-lda作为MDA组件,postfixadmin作为MTA的可视化管理工具。其中smtp认证也是通过dovecot完成,通常网络上的很多教程,都是使用saslauthd这个软件的,为了减少部署复杂度和理解,这里就只使用postfix和dovecot两个软件就可以了。

因为是用类树莓派的设备,所以操作系统使用的是debian9。

Postfix虚拟域

Postfix虚拟域类型官方文档:https://www.postfix.org/VIRTUAL_README.html

刚开始接触Postfix,会被它支持的虚拟域解决方案搞晕,这里就简单梳理一下,各种方案之间的区别:

1.共享域和共享操作系统账户:因为postfix支持同时管理多个邮件域,该方案支持将多个邮件域的收件人邮件,都由postfix自己投递到本地操作系统账户的信箱中,smtp认证也是使用操作系统的账号密码,通常配置是/etc/postfix/main.cf文件中的mydestination字段指定的域名。如user1@imaginefei.comuser1@abc.com两个域都是被当前邮件服务器管理的,Postfix收到邮件后,会将这两个域的邮件让$local_transport指定的LDA,将邮件都投递到操作系统用户user1的信箱中。

2.单独域和共享操作系统用户:使用virtual_alias_domains和virtual_alias_maps配置,将不同域的投递规则单独配置,但是smtp认证和用户邮箱,都是共享本地操作系统用户的。这里需要注意的是,使用了单独域(虚拟域),就不要将域名添加到mydestination字段当中了,网上很多教程都是复制粘贴,并没有去阅读官方文档和理解配置项的作用。为什么不能放在mydestination中,是因为mydestination中配置的域名,是通过$local_transport字段配置的LDA(/var/spool/postfix/private/local)去完成邮件投递,这个LDA会从/etc/passwd 和 /etc/aliases文件中查找收件人。virtual_alias_domains和virtual_alias_maps配置项是由virtual_transport指定的LDA(/var/spool/postfix/private/virtual)去处理的,所以需要根据这个关联关系,让LDA去完成邮件的路由和投递。

3.单独域和虚拟用户:该方案使用虚拟用户,即不需要在操作系统中创建一模一样的账户,通过Maildir路径配置,将不同的虚拟用户信箱,都放在Maildir路径当中,域的管理smtp认证的账户信息,就需要在认证工具中配置了,如saslauthd。

4.非Postfix存储、单独域和虚拟用户:这个是本次采用的方案,该方案postfix只是管理虚拟域和虚拟用户之间的关系,和投递规则,但不负责投递,即LDA是指定第三方去负责,配置项virtual_transport = dovecot
或virtual_transport = lmtp:unix:private/dovecot-lmtp。举个例子,postfix就是个邮局,具体邮差叔叔的工作,都外包给其他第三方公司去做了,让第三方去负责派送邮件。

系统搭建

环境初始化

操作系统用户初始化

1
2
3
4
groupadd -g 5000 vmail && mkdir -p /opt/vmail
useradd -r -u 5000 -g vmail -d /opt/vmail -s /sbin/nologin -c "Virtual Mail User" vmail
chmod -R 770 /opt/vmail
chown -R vmail:vmail /opt/vmail

数据库初始化

这里为了节省资源,使用的是sqlite3,有条件的可以使用mysql或pg。

1
2
# 安装
apt-get install dbconfig-common sqlite3

Nginx+Php环境初始化

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
# 安装php
apt-get install php-imap php-mbstring php-fpm php-mysql php-sqlite3 php-cli php-common

# 配置php-fpm
vim /etc/php/7.3/fpm/pool.d/www.conf
[www]
user = www-data
group = www-data
listen = /run/php/php7.3-fpm.sock
listen.owner = www-data
listen.group = www-data
pm = dynamic
pm.max_children = 5
pm.start_servers = 2
pm.min_spare_servers = 1
pm.max_spare_servers = 3


# 安装nginx
apt install nginx

# 配置nginx
vim /etc/nginx/sites-available/mail.zhongjin.io
server {
listen 8443 ssl;
listen [::]:8443 ssl;
server_name mail.zhongjin.io;
root /opt/postfixadmin-3.3.11/public;
index index.html index.htm index.php;
charset utf-8;

ssl_certificate "/etc/letsencrypt/live/zhongjin.io/fullchain.pem";
ssl_certificate_key "/etc/letsencrypt/live/zhongjin.io/privkey.pem";

# 缓存有效期
ssl_session_cache shared:SSL:10m;
ssl_session_timeout 10m;

# 安全链接可选的加密协议,不填写默认为TLSv1 TLSv1.1 TLSv1.2
ssl_protocols TLSv1 TLSv1.1 TLSv1.2;

# openssl ciphers命令列出
# openssl ciphers -V 'HIGH:!aNULL:!MD5'
ssl_ciphers HIGH:!aNULL:!MD5;

# 使用服务器端的首选算法
ssl_prefer_server_ciphers on;

location / {
try_files $uri $uri/ /index.php$is_args$args;
}

location ~ \.php$ {
fastcgi_pass unix:/run/php/php7.3-fpm.sock;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
include fastcgi_params;
fastcgi_split_path_info ^(.+\.php)(/.+)$;
fastcgi_index index.php;
fastcgi_intercept_errors off;
fastcgi_buffer_size 16k;
fastcgi_buffers 4 16k;
fastcgi_connect_timeout 600;
fastcgi_send_timeout 600;
fastcgi_read_timeout 600;
}

error_page 404 /404.html;
location = /404.html {
root /usr/share/nginx/html;
}

error_page 500 502 503 504 /50x.html;
location = /50x.html {
root /usr/share/nginx/html;
}

}

ln -s /etc/nginx/sites-available/mail.zhongjin.io /etc/nginx/sites-enabled/mail.zhongjin.io

软件安装

Postfixadmin安装和配置

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
# 安装postfixadmin
tar -xvf postfixadmin-postfixadmin-3.3.11.tar.gz
mv postfixadmin-postfixadmin-3.3.11.tar.gz /opt/postfixadmin-3.3.11
cd /opt/postfixadmin-3.3.11
# 创建templates_c目录
mkdir -p /opt/postfixadmin-3.3.11/templates_c

# 编辑全局配置文件
vim config.inc.php
$CONF['default_language'] = 'cn';

####################################################################
# 编辑本地配置文件
vim config.local.php
# 使用MYSQL时的配置
#<?php
#$CONF['database_type'] = 'mysqli';
#$CONF['database_user'] = 'postfix';
#$CONF['database_password'] = 'postfix';
#$CONF['database_name'] = 'postfix';
#$CONF['database_host'] = '127.0.0.1';
#$CONF['database_port'] = '3306';
#$CONF['configured'] = true;
#$CONF['setup_password'] = 'xxxxxxxxx';
#?>

# 使用Sqlite3时候的配置
<?php
$CONF['configured'] = true;
$CONF['database_type'] = 'sqlite';
$CONF['database_name'] = '/opt/vmail/db/postfixadmin.db';
?>
####################################################################

# 授权
chown -R www-data:www-data /opt/postfixadmin-3.3.11
touch /opt/vmail/db/postfixadmin.db
chown -R vmail:vmail /opt/vmail/
chmod -R 770 /opt/vmail
usermod -a -G vmail www-data

# 配置postfixadmin
# 访问https://mail.zhongjin.io:8443/setup.php
# 填写setup_password
setup_password: xxxxxxxxxx

# 将配置段设置到config.local.php文件中
$CONF['setup_password'] = 'xxxxxxxx';

# 使用setup_password登录,添加Superadmin账号
xxxxxx@zhongjin.io/xxxxxxxx

# 去https://mail.zhongjin.io:8443/login.php登录
# 创建域和账号
xxxxxx@zhongjin.io/xxxxxxxx

# 完成配置后,可以把config.inc.php其余配置补充完
vim config.inc.php
$CONF['default_language'] = 'cn';
$CONF['admin_email'] = 'xxxxxx@zhongjin.io';
$CONF['admin_smtp_password'] = 'xxxxxxx';
$CONF['smtp_server'] = 'mail.zhongjin.io';
$CONF['smtp_port'] = '25';
#$CONF['encrypt'] = 'dovecot:CRAM-MD5';

Postfix安装和配置

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
# 安装
apt-get install postfix postfix-mysql postfix-sqlite

mkdir -p /etc/postfix/sql

# sqlite_virtual_domains_maps
vim /etc/postfix/sql/sqlite_virtual_domains_maps.cf
dbpath = /opt/vmail/db/postfixadmin.db
query = SELECT domain FROM domain WHERE domain='%s' AND active = '1'
# end sqlite_virtual_domains_maps

# 添加配置和检验配置
postconf -e virtual_mailbox_domains=sqlite:/etc/postfix/sql/sqlite_virtual_domains_maps.cf
postmap -q zhongjin.io sqlite:/etc/postfix/sql/sqlite_virtual_domains_maps.cf


# sqlite_virtual_mailbox_maps
vim /etc/postfix/sql/sqlite_virtual_mailbox_maps.cf
dbpath = /opt/vmail/db/postfixadmin.db
query = SELECT maildir FROM mailbox WHERE username='%s' AND active = '1'
# end sqlite_virtual_mailbox_maps

# 添加配置和检验配置
postconf -e virtual_mailbox_maps=sqlite:/etc/postfix/sql/sqlite_virtual_mailbox_maps.cf
postmap -q xxxxxx@zhongjin.io sqlite:/etc/postfix/sql/sqlite_virtual_mailbox_maps.cf


# sqlite_virtual_alias_maps
vim /etc/postfix/sql/sqlite_virtual_alias_maps.cf
dbpath = /opt/vmail/db/postfixadmin.db
query = SELECT goto FROM alias WHERE address='%s' AND active = '1'
# end sqlite_virtual_alias_maps

# 添加配置和检验配置
postconf -e virtual_alias_maps=sqlite:/etc/postfix/sql/sqlite_virtual_alias_maps.cf
postmap -q abuse@zhongjin.io sqlite:/etc/postfix/sql/sqlite_virtual_alias_maps.cf

# 授权
chgrp postfix /etc/postfix/sql/sqlite_*.cf
cp /etc/postfix/main.cf /etc/postfix/main.cf.bk
vim /etc/postfix/main.cf
####################################################################################
smtpd_banner = ESMTP $mail_name
biff = no
append_dot_mydomain = no
readme_directory = no
compatibility_level = 2
smtpd_tls_cert_file=/etc/ssl/certs/mail.zhongjin.io.crt
smtpd_tls_key_file=/etc/ssl/private/mail.zhongjin.io.key
smtpd_use_tls=yes
smtpd_tls_auth_only=yes
smtpd_tls_session_cache_database = btree:${data_directory}/smtpd_scache
smtp_tls_session_cache_database = btree:${data_directory}/smtp_scache
smtpd_sasl_type=dovecot
smtpd_sasl_path=private/auth
smtpd_sasl_auth_enable=yes
smtpd_sasl_security_options=noanonymous
smtpd_sender_restrictions=permit_sasl_authenticated
smtpd_recipient_restrictions=permit_mynetworks permit_sasl_authenticated permit_auth_destination reject_unauth_destination
smtpd_relay_restrictions = permit_mynetworks permit_sasl_authenticated permit_auth_destination reject_unauth_destination
myhostname = mail.zhongjin.io
alias_maps = hash:/etc/aliases
alias_database = hash:/etc/aliases
myorigin = /etc/mailname
mydestination = localhost.localdomain, localhost
relayhost =
mynetworks = 0.0.0.0
mailbox_size_limit = 0
recipient_delimiter = +
inet_interfaces = all
inet_protocols = all
virtual_mailbox_domains = sqlite:/etc/postfix/sql/sqlite_virtual_domains_maps.cf
virtual_mailbox_maps = sqlite:/etc/postfix/sql/sqlite_virtual_mailbox_maps.cf
virtual_alias_maps = sqlite:/etc/postfix/sql/sqlite_virtual_alias_maps.cf
virtual_transport = lmtp:unix:private/dovecot-lmtp
####################################################################################

cp /etc/postfix/master.cf /etc/postfix/master.cf.bk
vim /etc/postfix/master.cf
####################################################################################
smtp inet n - y - - smtpd
submission inet n - y - - smtpd
-o syslog_name=postfix/submission
-o smtpd_tls_security_level=encrypt
-o smtpd_sasl_auth_enable=yes
-o smtpd_tls_auth_only=yes
-o smtpd_reject_unlisted_recipient=no
-o smtpd_client_restrictions=permit_sasl_authenticated,reject
-o smtpd_recipient_restrictions=permit_sasl_authenticated,reject
-o milter_macro_daemon_name=ORIGINATING
smtps inet n - y - - smtpd
-o syslog_name=postfix/smtps
-o smtpd_tls_wrappermode=yes
-o smtpd_sasl_auth_enable=yes
-o smtpd_client_restrictions=permit_sasl_authenticated,reject
-o milter_macro_daemon_name=ORIGINATING
pickup unix n - y 60 1 pickup
cleanup unix n - y - 0 cleanup
qmgr unix n - n 300 1 qmgr
tlsmgr unix - - y 1000? 1 tlsmgr
rewrite unix - - y - - trivial-rewrite
bounce unix - - y - 0 bounce
defer unix - - y - 0 bounce
trace unix - - y - 0 bounce
verify unix - - y - 1 verify
flush unix n - y 1000? 0 flush
proxymap unix - - n - - proxymap
proxywrite unix - - n - 1 proxymap
smtp unix - - y - - smtp
relay unix - - y - - smtp
-o syslog_name=postfix/relay
showq unix n - y - - showq
error unix - - y - - error
retry unix - - y - - error
discard unix - - y - - discard
local unix - n n - - local
virtual unix - n n - - virtual
lmtp unix - - y - - lmtp
anvil unix - - y - 1 anvil
scache unix - - y - 1 scache
maildrop unix - n n - - pipe
flags=DRhu user=vmail argv=/usr/bin/maildrop -d ${recipient}
uucp unix - n n - - pipe
flags=Fqhu user=uucp argv=uux -r -n -z -a$sender - $nexthop!rmail ($recipient)
ifmail unix - n n - - pipe
flags=F user=ftn argv=/usr/lib/ifmail/ifmail -r $nexthop ($recipient)
bsmtp unix - n n - - pipe
flags=Fq. user=bsmtp argv=/usr/lib/bsmtp/bsmtp -t$nexthop -f$sender $recipient
scalemail-backend unix - n n - 2 pipe
flags=R user=scalemail argv=/usr/lib/scalemail/bin/scalemail-store ${nexthop} ${user} ${extension}
mailman unix - n n - - pipe
flags=FR user=list argv=/usr/lib/mailman/bin/postfix-to-mailman.py
${nexthop} ${user}
####################################################################################

# 检查配置文件是否正确
postconf -n
systemctl restart postfix
systemctl enable postfix

Dovecot安装和配置

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
# 安装
apt-get install dovecot-imapd dovecot-lmtpd dovecot-pop3d dovecot-sqlite

cd /etc/dovecot/conf.d/
vim /etc/dovecot/conf.d/10-mail.conf
####################################################################################
mail_location = maildir:/opt/vmail/mailbox/%d/%n
namespace inbox {
separator = /
inbox = yes
}
mail_uid = vmail
mail_gid = vmail
mail_privileged_group = mail
first_valid_uid = 5000
last_valid_uid = 5000
protocol !indexer-worker {
}
####################################################################################



vim /etc/dovecot/conf.d/10-auth.conf
####################################################################################
auth_mechanisms = plain login
#!include auth-system.conf.ext
!include auth-sql.conf.ext
####################################################################################



vim /etc/dovecot/dovecot-sql.conf.ext
####################################################################################
driver = sqlite
connect = /opt/vmail/db/postfixadmin.db
default_pass_scheme = MD5-CRYPT
password_query = \
SELECT username as user, password, '/opt/vmail/mailbox/%d/%n' as userdb_home, \
'maildir:/opt/vmail/mailbox/%d/%n' as userdb_mail, 5000 as userdb_uid, 5000 as userdb_gid \
FROM mailbox WHERE username = '%u' AND active = '1'
user_query = \
SELECT '/opt/vmail/mailbox/%d/%n' as home, 'maildir:/opt/vmail/mailbox/%d/%n' as mail, \
5000 AS uid, 5000 AS gid, printf('dirsize:storage=%d', quota) AS quota \
FROM mailbox WHERE username = '%u' AND active = '1'
####################################################################################


vim /etc/dovecot/conf.d/10-ssl.conf
####################################################################################
ssl = yes
####################################################################################


vim /etc/dovecot/conf.d/15-lda.conf
####################################################################################
postmaster_address = xxxxx@zhongjin.io
####################################################################################


vim /etc/dovecot/conf.d/10-master.conf
####################################################################################
service lmtp {
unix_listener /var/spool/postfix/private/dovecot-lmtp {
mode = 0600
user = postfix
group = postfix
}
}
service auth {
unix_listener /var/spool/postfix/private/auth {
mode = 0666
user = postfix
group = postfix
}
unix_listener auth-userdb {
mode = 0600
user = vmail
#group = vmail
}
user = dovecot
}
service auth-worker {
user = vmail
}
####################################################################################


# 添加邮箱过时自动删除策略
vim /etc/dovecot/conf.d/15-mailboxes.conf
####################################################################################
namespace inbox {
mailbox Drafts {
special_use = \Drafts
}
mailbox Junk {
special_use = \Junk
autoexpunge = 30d
}
mailbox Trash {
special_use = \Trash
autoexpunge = 30d
}
mailbox Sent {
special_use = \Sent
}
mailbox "Sent Messages" {
special_use = \Sent
}
}
####################################################################################


# 授权
chown -R vmail:dovecot /etc/dovecot
chmod -R o-rwx /etc/dovecot

systemctl enable dovecot
systemctl restart dovecot

邮件系统端口梳理

1
2
3
4
5
6
7
8
9
10
11
发件协议和端口:
25端口 (SMTP非加密)
465端口 (SMTPS: SMTP SSL)
587端口 (SMTP-MSA: Message submission agent)

收件协议和端口:
109端口 (POP2非加密)
110端口 (POP32非加密)
143端口 (IMAP非加密)
993端口 IMAP SSL(IMAP-over-SSL)
995端口 POP3 SSSL(POP3-over-SSL)

邮件系统安全之DKIM、DMARC和SPF

这块内容比较多,有空再补充完整

SPF(Sender Policy Framework)

百度百科参考:https://baike.baidu.com/item/%E5%8F%91%E9%80%81%E6%96%B9%E7%AD%96%E7%95%A5%E6%A1%86%E6%9E%B6/381991?fr=aladdin

维基百科参考:https://en.wikipedia.org/wiki/Sender_Policy_Framework

1
2
配置域名@ txt记录:
v=spf1 mx mx:zhongjin.io ~all

DKIM(DomainKeys Identified Mail)

百度百科参考:https://baike.baidu.com/item/DKIM/152526?fr=aladdin

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
# 安装
apt install opendkim opendkim-tools

mkdir /etc/dkimkeys/zhongjin.io
# 生成密钥
opendkim-genkey -D /etc/dkimkeys/zhongjin.io -d zhongjin.io -s default
chown -R opendkim /etc/dkimkeys/zhongjin.io
ln -s /etc/dkimkeys/zhongjin.io/default.private /etc/dkimkeys/default.private

# 配置
$ egrep -v "^#|^$" /etc/opendkim.conf
Syslog yes
UMask 007
KeyFile /etc/dkimkeys/default.private
Selector default
Canonicalization relaxed/relaxed
Socket inet:8891@localhost
PidFile /var/run/opendkim/opendkim.pid
OversignHeaders From
TrustAnchorFile /usr/share/dns/root.key
UserID opendkim
KeyTable file:/etc/dkimkeys/keytable
SigningTable refile:/etc/dkimkeys/signingtable
InternalHosts refile:/etc/dkimkeys/trustedhosts

# /etc/dkimkeys/keytable
vim /etc/dkimkeys/keytable
default._domainkey.zhongjin.io zhongjin.io:default:/etc/dkimkeys/zhongjin.io/default.private


# /etc/dkimkeys/signingtable
vim /etc/dkimkeys/signingtable
# Domain yourdomain.org
*@zhongjin.io default._domainkey.zhongjin.io
# You can specify multiple domains
# Example.net www._domainkey.example.net


# /etc/dkimkeys/trustedhosts
vim /etc/dkimkeys/trustedhosts
127.0.0.1


# 重启opendkim
systemctl restart opendkim
systemctl enable opendkim


# 配置postfix
vim /etc/postfix/main.cf
smtpd_milters = inet:127.0.0.1:8891
non_smtpd_milters = $smtpd_milters
milter_default_action = accept
milter_protocol = 2

# postconf -n
postconf -n

# 重启postfix
systemctl restart postfix.service


# 未来有多个域名,可以新增加证书
mkdir /etc/opendkim/keys/mydomain.com
opendkim-genkey -D /etc/opendkim/keys/mydomain.com/ -r -d mydomain.com
chown -R opendkim: /etc/opendkim/keys/mydomain.com

# 测试
opendkim-testkey -v -v

或访问https://www.mail-tester.com/

DMARC(Domain-based Message Authentication, Reporting and Conformance)

百度百科参考:https://baike.baidu.com/item/dmarc?fromModule=lemma_search-box

1
2
加dns txt记录:_dmarc.zhongjin.io
RR值:v=DMARC1; p=quarantine; rua=mailto:xxxxx@zhongjin.io; ruf=mailto:xxxxx@zhongjin.io

关于反向代理

在使用frp proxy protocol v2协议代理postfix和dovecot的过程,要获取原始客户端IP,需要增加以下字段。

postfix的master.cf配置文件,新增-o smtpd_upstream_proxy_protocol=haproxy

1
2
3
4
5
6
submission inet n       -       y       -       -       smtpd
...
-o smtpd_upstream_proxy_protocol=haproxy
smtps inet n - y - - smtpd
...
-o smtpd_upstream_proxy_protocol=haproxy

dovecot的dovecot.conf配置文件,新增login_trusted_networks 和 haproxy_trusted_networks

1
2
login_trusted_networks = x.x.x.x/8 x.x.x.x
haproxy_trusted_networks = x.x.x.x/8 x.x.x.x

dovecot的10-master.conf配置文件,新增haproxy = yes

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
service imap-login {
inet_listener imap {
#port = 143
}
inet_listener imaps {
#port = 993
#ssl = yes
haproxy = yes
}

# Number of connections to handle before starting a new process. Typically
# the only useful values are 0 (unlimited) or 1. 1 is more secure, but 0
# is faster. <doc/wiki/LoginProcess.txt>
#service_count = 1

# Number of processes to always keep waiting for more connections.
#process_min_avail = 0

# If you set service_count=0, you probably need to grow this.
#vsz_limit = $default_vsz_limit
}