很简单,初始需求仅仅是拥有一个自有域名的邮箱,然而企业邮箱是越来越贵了, 完全超出本穷承受能力。在翻阅大量网文后,终成此文。

文中很多设定,完全可以参考官方文档,逐条理解,但毕竟本人也非靠此吃饭谋生,往往是遇见问题时,才会到官网去看看为什么,尤其是 psotfix & dovecot & opendkim 的设定,十分复杂。言尽于此,感谢其他作者给到我的帮助,大部分设定甚至可以说是抄袭照搬也不为过,权当记录备忘之用。 

1. 检查环境

我们自己建立的邮件服务器,总是希望能够顺利收发为目的。说起来只是一句话,在系统运转之前,一些必要性的检查工作是不可或缺的。总结一句话,原则就是: PTR 必须有,黑名单不能有,IP信任度中立。限于篇幅,以下仅仅介绍检查的项目以及必要性说明:

1.1. MX 记录设定

邮件服务高度依赖 DNS 中的 mx 记录,至于怎么设置 mx 记录,这里就不多言。好比吃饭需要张嘴,不张嘴没有饭吃,不设置 mx 记录,就不要尝试邮件服务器了,再见。

1.2. PTR 记录检查

PTR记录只能被 ISP 建立,你可以理解为你的 vps 厂商才能建立。有些厂商平台,可以自行建立 PTR 记录,大部分则需要自行发工单申请,国内大厂 xx云 & yy云,基本上不要想这事,即使能成,我相信他们的 Policy 变更频率也是让你难以长久信赖。 

那么 PTR 是什么呢, 主要用于电子邮件发送过程中的反向地址解析,换句简单的话来说,你发出去的邮件,接收方在正式接收之前,会根据你服务器 IP 反查一个 DNS 记录,这个记录就是 PTR,如果没有,抱歉,退回邮件。这也就解释了很多人邮件被GOOGLE,微软,腾讯,网易拒收的原因了。当然这仅仅是原因之一。

总而言之, PTR 必须有,没有的话,放弃吧,不要做无谓的努力,因为你无论如何努力,被退信的几率接近 sin(90度)。

无论你是自行设定还是 ISP 帮助设定,都需要检查一下是否成功,一般来说,24小时生效。下面介绍两种方法

 

a) Linux 环境下,执行一下命令可查阅:

dig -x 你的IP

 

在返回的 ";; ANSWER SECTION: "段,会显示 PTR 名称

 

b) Windows 环境下, 执行一下命令可查阅:

nslookup 你的IP

直接返回 PTR 名称

 

3)  各大网站查询

推荐使用 mxtoolbox 查询,这是个非常专业的邮件服务检查的网站,在后面还会多次提到。

 

 

1.3. 黑名单检查

因为各种原因,你的服务器 IP 或者域名 被反垃圾邮件组织列入黑名单,那么很不幸,要么放弃,要么去申诉。如果是 IP 段被反垃圾邮件组织拉黑的话,你还得请 ISP 去申诉,这个难度与意愿,自行判断吧。

推荐 mxtoolbox 网站去检查 

 

或者 spamhaus 的网站去检查 

 

1.4. IP 信任度检查

推荐去 cyren 或者 senderscore 检查,只要不是 low 等级,问题不大,起码说明之前没有滥发邮件的黑历史。只要你做好了本文中的其他设置,比如: PTR, Blacklist, SPF, DKIM, DMARC ,将来也不会滥发邮件,那么这个 IP 信誉度问题不大,前提是不要是 LOW 。最多被大厂商扔进垃圾箱,而不会拒收。

 

 

1.5. 操作系统环境检查

 

a) 修改 hosts 文件

vi /etc/hosts

增加或者修改:
127.0.1.1 DNS 中的 mx 记录
你的IP DNS 中的 mx 记录

 

 b) 修改 hostname 文件

vi /etc/hostname

增加或修改:
DNS 中的 mx 记录

 

2. 更新系统 

apt-get update
apt-get dist-upgrade

 

3. 安装 MYSQL

 参考本站前文: https://crossfw.com/linux/9-ubuntu-18-04-mysql.html 

 

4. 邮箱数据库设置

-- 创建邮件数据库
CREATE DATABASE mx CHARACTER SET utf8 COLLATE utf8_general_ci;

-- 创建虚拟域
CREATE TABLE `virtual_domains` (
`id`  INT NOT NULL AUTO_INCREMENT,
`name` VARCHAR(50) NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

-- 插入一条记录
insert into virtual_domains values(1,'你的域名');


-- 创建用户表
CREATE TABLE `virtual_users` (
`id` INT NOT NULL AUTO_INCREMENT,
`domain_id` INT NOT NULL,
`password` VARCHAR(106) NOT NULL,
`email` VARCHAR(120) NOT NULL,
PRIMARY KEY (`id`),
UNIQUE KEY `email` (`email`),
FOREIGN KEY (domain_id) REFERENCES virtual_domains(id) ON DELETE CASCADE
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

-- 插入两个用户,以md5加密
insert into virtual_users values(1,1,md5('邮箱密码'),'user1@你的域名');
insert into virtual_users values(2,1,md5('邮箱密码'),'user2@你的域名');


-- 创建别名表
CREATE TABLE `virtual_aliases` (
`id` int(11) NOT NULL auto_increment,
`domain_id` int(11) NOT NULL,
`source` varchar(100) NOT NULL,
`destination` varchar(100) NOT NULL,
PRIMARY KEY (`id`),
FOREIGN KEY (domain_id) REFERENCES virtual_domains(id) ON DELETE CASCADE)
ENGINE=InnoDB DEFAULT CHARSET=utf8;

-- 插入数据,所有发给first的邮件都会自动转发给second
insert into virtual_aliases values(1,1,'user1@你的域名','user2@你的域名');

 

5. 安装 Postfix+Dovecot+Opendkim

apt-get install postfix postfix-mysql dovecot-core dovecot-pop3d dovecot-imapd dovecot-lmtpd dovecot-mysql  opendkim opendkim-tools

 

 

 

6. 安装 SSL 证书

 参考本站前文,安装 Let's Encrypt 证书

 https://crossfw.com/linux/4-let-s-encrypt.html

最简单的方式就是使用系统自带的  openssl 生成证书:

# 通过 openssl 生成私钥key
openssl genrsa -out server.key 2048

# 根据私钥生成证书申请文件csr
openssl req -new -key server.key -out server.csr

# 生成有效期10年的证书文件crt
openssl x509 -req -in server.csr -out server.crt -signkey server.key -days 3650

 建议使用 Let's Encrypt 证书, Openssl 自带证书并不好使.

 

7. 配置 postfix 

 编辑 postfix 基本配置文件:

vi /etc/postfix/main.cf

7.1 变更证书路径

找到 # TLS parameters 段,将证书变更为步骤6中的证书

# TLS parameters
smtpd_tls_cert_file=/你的证书路径/证书名.cer
smtpd_tls_key_file=/你的证书路径/证书名.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

 

7.2 使用 Dovecot 认证

在 7.1 段落后追加一下这一段:

smtpd_sasl_type = dovecot
smtpd_sasl_path = private/auth
smtpd_sasl_auth_enable = yes
smtpd_recipient_restrictions = permit_sasl_authenticated,permit_mynetworks,reject_unauth_destination

 

7.3 虚拟域设定

配置文件最后加入以下这一段

# 配置虚拟域
virtual_transport = lmtp:unix:private/dovecot-lmtp
virtual_mailbox_domains = mysql:/etc/postfix/mysql-virtual-mailbox-domains.cf
virtual_mailbox_maps = mysql:/etc/postfix/mysql-virtual-mailbox-maps.cf
virtual_alias_maps = mysql:/etc/postfix/mysql-virtual-alias-maps.cf

 保存 postfix 配置文件后退出

 

  • 创建虚拟域配置文件
vi /etc/postfix/mysql-virtual-mailbox-domains.cf
user = mysql 用户名,比如: root
password = mysql 用户密码
port = 3306
hosts = 127.0.0.1
dbname = 你的数据名称
query = SELECT 1 FROM virtual_domains WHERE name='%s'
  • 创建邮箱用户配置文件
vi /etc/postfix/mysql-virtual-mailbox-maps.cf
user = mysql 用户名,比如: root
password = mysql 用户密码
port = 3306
hosts = 127.0.0.1
dbname = 你的数据库名称
query = SELECT 1 FROM virtual_users WHERE email='%s'
  •  创建邮箱用户别名配置文件
vi /etc/postfix/mysql-virtual-alias-maps.cf
user = mysql 用户名,比如: root
password = mysql 用户密码
port = 3306
hosts = 127.0.0.1
dbname = 你的数据库名称
query = SELECT destination FROM virtual_aliases WHERE source='%s'
  •  测试以上三个配置文件正确性
#重启 postfix
service postfix restart

#测试虚拟域配置,返回 1 表明配置正确
postmap -q 你的域名 mysql:/etc/postfix/mysql-virtual-mailbox-domains.cf

#测试邮箱用户配置,返回 1 表明配置正确
postmap -q 你的邮箱 mysql:/etc/postfix/mysql-virtual-mailbox-maps.cf

#测试邮箱用户别名配置,返回 user2@你的域名 表明配置正确
postmap -q user1@你的域名 mysql:/etc/postfix/mysql-virtual-alias-maps.cf

 

7.4 变更邮件发送端口

为什么不使用 25 端口?465/587区别?不在本文讨论范围

vi /etc/postfix/master.cf 

 分别将下图中的注释取消即可:

 

 

 重启 postfix 之后, 可发现端口 465/587 被启用.

service postfix restart
netstat -tln

 

8. 配置 Dovecot

8.1 基本配置

vi /etc/dovecot/dovecot.conf

确认以下行注释被取消

!include conf.d/*.conf

文件末端加入下行, 配置邮件通讯支持的协议:

protocols = imap lmtp pop3

对于 dovecot 2.2.25+以上版本, 配置文件夹: 已发送,草稿,垃圾邮件, 存档..., 在该配置文件最下端加入以下代码即可:

namespace inbox {
  # the namespace prefix isn't added again to the mailbox names.
  #prefix = INBOX.
  inbox = yes
  # ...

  mailbox Trash {
    auto = no
    special_use = \Trash
  }
  mailbox Drafts {
    auto = no
    special_use = \Drafts
  }
  mailbox Sent {
    auto = subscribe # autocreate and autosubscribe the Sent mailbox
    special_use = \Sent
  }
  mailbox "Sent Messages" {
    auto = no
    special_use = \Sent
  }
  mailbox Spam {
    auto = create # autocreate Spam, but don't autosubscribe
    special_use = \Junk
  }
  mailbox virtual/All { # if you have a virtual "All messages" mailbox
    auto = no
    special_use = \All
  }
}

 

8.2 配置邮箱目录

vi /etc/dovecot/conf.d/10-mail.conf

 更改 mail_location 为以下值:

mail_location = maildir:/var/mail/vhosts/%d/%n

 取消 mail_privileged_group  注释, 并复制为:

mail_privileged_group = mail

 

8.3 变更邮箱目录权限

groupadd -g 5000 vmail
useradd -g vmail -u 5000 vmail -d /var/mail
chown -R vmail:vmail /var/mail

 

8.4 配置邮件认证方式

vi /etc/dovecot/conf.d/10-auth.conf

找到以下行,取消注释:

disable_plaintext_auth = yes

找到以下行, 赋值如下:

auth_mechanisms = plain login

 适用 sql 认证, 找到以下行, 参考以下值,注释或取消注释以下行

#!include auth-system.conf.ext
!include auth-sql.conf.ext

 

8.5 配置 SQL 认证参数1

vi /etc/dovecot/conf.d/auth-sql.conf.ext

 找到 userdb 段, 参考以下值, 注释或增加释以下行

userdb {
#  driver = sql
#  args = /etc/dovecot/dovecot-sql.conf.ext
  driver = static
  args = uid=vmail gid=vmail home=/var/mail/vhosts/%d/%n
}

 

8.6 配置 SQL 认证参数2

vi /etc/dovecot/dovecot-sql.conf.ext

增加以下行

driver = mysql
connect = host=127.0.0.1 port=3306 dbname=mx user=root password=root密码
default_pass_scheme = MD5
password_query = SELECT email as user, password FROM virtual_users WHERE email='%u';

 

8.7. 变更 dovecot 目录权限

chown -R vmail:dovecot /etc/dovecot
chmod -R o-rwx /etc/dovecot

 

8.8 配置邮件通讯协议

vi /etc/dovecot/conf.d/10-master.conf
  •  禁用 imap/pop3 非 ssl 通讯,将端口设置为 0
service imap-login {
  inet_listener imap {
    port = 0
  }
  inet_listener imaps {
    #port = 993
    #ssl = yes
  }
#...
#...
}

  

service pop3-login {
  inet_listener pop3 {
    port = 0
  }
  inet_listener pop3s {
    #port = 995
    #ssl = yes
  }
}

 

  • 设置 service lmtp 段
service lmtp {
  unix_listener /var/spool/postfix/private/dovecot-lmtp {
    mode = 0600
    user = postfix
    group = postfix
  }
}

 

  •  设置 service auth 段
service auth {
unix_listener /var/spool/postfix/private/auth {
    mode = 0666
    user = postfix
    group = postfix
  }

  unix_listener auth-userdb {
    mode = 0600
    user = vmail
    #group =
  }

  user = dovecot
}

 

  •  设置 service auth-worker 段
service auth-worker {
  user = mail
}

 

8.9 SSL 配置

vi /etc/dovecot/conf.d/10-ssl.conf
ssl = yes
ssl_cert = </你的证书路径/证书名.cer
ssl_key = </你的证书路径/证书名.key

 

重启 postfix & dovecot

service postfix restart
service dovecot restart

 

9. 配置 opendkim

9.1 创建 dkim 密匙

mkdir -p /etc/opendkim/你的域名
cd /etc/opendkim/你的域名
opendkim-genkey -t -s mail -d 你的域名

9.2. 配置 opendkim

  •  编辑基本配置文件
vi /etc/opendkim.conf

 在文件底部加入下列行

Socket    inet:8891@localhost
KeyTable           /etc/opendkim/KeyTable
SigningTable       refile:/etc/opendkim/SigningTable

 

  •  编辑 KeyTable
vi /etc/opendkim/KeyTable

 加入下行

mail._domainkey.你的域名 你的域名:mail:/etc/opendkim/你的域名/mail.private

 

  •  编辑 SigningTable
vi /etc/opendkim/SigningTable

 加入下行

你的域名 mail._domainkey.你的域名

 

  •  编辑 postfix 配置
vi /etc/postfix/main.cf 

 在文件底部加入下列行

milter_default_action = accept
milter_protocol = 2
smtpd_milters = inet:localhost:8891
non_smtpd_milters = inet:localhost:8891

 

  •  设置 opendkim 监控 8891 端口
vi /etc/default/opendkim

 注释其他 SOCKET, 加入下行

SOCKET="inet:8891@localhost"

 

  • 变更权限
chown -R opendkim:opendkim /etc/opendkim

 

  • 重启 postfix & dovecot & opendkim
service postfix restart
service dovecot restart
service opendkim restart

 

10. DNS中邮件相关记录

如果你的 DNS 中没有设置 spf,dkim,_dmarc 记录,大概率会被各大厂商退信,至于什么是 spf, dkim,_dmarc ?不在本文讨论范围,必须设置就对了。

 这三条 DNS 记录都是 TXT 型,手动自行添加即可。

10.1 spf 示例

TXT 记录名称: 你的域名

v=spf1 a mx ip4:服务器IP ~all

 

10.2 dkim 示例

查看在 9.1 段中产生的密匙文件内容

cat /etc/opendkim/你的域名/mail.txt 

可获知 TXT 记录名称为: mail._domainkey,值为 TXT("") 中双引号中的内容

v=DKIM1; k=rsa; t=y; p=xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx

10.3 _dmarc 示例

TXT 记录名称: _dmarc

v=DMARC1;p=reject;pct=100;rua=mailto:你的邮箱

 

11. 邮件发送测试

 

11.1 gmail 简单测试

设置完毕后,可以发送一封测试邮件到 gmail,通过查看原始邮件,可知 spf, dkim, _dmarc 均已生效

 

 

11.2 mail-tester 测试

mail-tester 是个被广泛用于测试邮件发送是否合规的网站,

 

11.3 mxtoolbox 测试

mxtoolbox 同样强大,细节在此不表

 

 

11.4 日志检查

日志是非常重要的工具, 基本上不可能一步到位的配置成功,

也许我运气不错,基本上只检查过 cat /var/log/mail.log,如 mysql 连接失败一类的。

 

12. 多虚拟域配置

以上那么多纷杂的配置都做完,多个域名使用同一台邮件服务器,很显然非常简单:

  • 步骤4中增加对应的域名记录,邮箱记录,别名记录
  • 步骤9中产生新域名的密匙,然后针对 KeyTable & SigningTable 分别增加对应记录,再到 DNS 中设置 dkim/spf/dmarc 记录即可

 当然重启 postfix, dovecot, opendkim 是必须的.

 

 本文行文仓促,随着时间推移,或会慢慢调整。