Introduction

系统环境: ubuntu 16.04, 腾讯云

有时候我们有如下的需求:

  • 给公司搭建一个邮件服务器, 目前该需求已经大部分被企业邮箱代替了.
  • 批量注册一批邮箱账号, 已进行某些网站的批量注册功能

这时候我们就需要搭建一个自己的个人邮件服务器以解决如上的功能.

系统环境输出:

1
2
3
4
5
root@mail:~# lsb_release -idrc
Distributor ID: Ubuntu
Description: Ubuntu 16.04.1 LTS
Release: 16.04
Codename: xenial

VPS 网络配置: 在安装软件过程中, 参考的国外友人的配置, 很多源或者包都是国外的, 此时就会导致安装过程非常之慢, 如果
不是使用 docker 安装ExmMail的外, 则需要先安装 VPS, 参考以前的文章SSR-PAC.

配置 DNS

域名解析

在已经拥有一台邮件服务器和域名的前提下, 我们需要先配置 DNS, 配置一个邮件域名mail.unusebamboo.top.
配置如下:

  • 添加一个 A 记录, 将mail.unusebamboo.top指向指定的服务器真实 IP
  • 添加一个 MX 记录, 其中主机记录为@, 指向mail.unusebamboo.top记录值
  • 添加 3 条 A 记录, 分别将smtp.unusebamboo.top, pop.unusebamboo.top, imap.unusebamboo.top指向真实 IP

至此, 所有邮件服务参与到的 DNS 域名查询解析服务都已经配置完成.

反向解析

RDNS(反向解析), 将 IP 解析成域名, 已告知某一个 IP 是合法的, 被认可. RDNS 在邮件系统中使用非常广泛, 以进行垃圾邮件过滤, 其中目标 MDA 会查询来源 IP 的域名是否为目标邮箱, 如果不是, 则会拒绝收取邮件.

配置 FQDN

在配置完 DNS 解析之后, 还需要在邮件服务器上进行FQDNhostname的配置工作, 下面的参考文件讲述了如何命令
邮件主机名, FQDN 的含义等.

设置 hostname: echo "mail" > /etc/hostname

重启 hostname 服务: service hostname restart 或者 hostnamectl set-hostname mail

设置本地 FQDN, 编辑/etc/hosts文件:

1
2
3
127.0.0.1	localhost.localdomain	localhost
127.0.1.1 mail.unusebamboo.top mail
公网IP mail.unusebamboo.top mail

检查 FQDN 值: hostname -f

参考:
FQDN
A 和 MAX 记录

docker 安装

exmail

安装应用, 搭建环境, 第一个想到的当然是 docker 环境, 一开始我使用palidin/exmail
镜像来安装配置邮件服务, 但是后续出现了问题, 无法发送邮件服务, 因为目前所有的公有云都不提供 25 端口开放服务, 以避免垃圾邮件的泛滥导致的 IP 信誉度下降.

但是, 如果仅仅有接收邮件的请求的话, 那么使用 docker 一下就完事, 方便快捷, 安全保障.

1
2
3
4
5
6
7
8
9
10
11
# 安装docker
apt-get install docker.io
docker --version

# 安装docker compose
curl -L https://github.com/docker/compose/releases/download/1.18.0/docker-compose-`uname -s`-`uname -m` -o /usr/local/bin/docker-compose
chmod +x /usr/local/bin/docker-compose
docker-compose --version

# 创建邮件目录
mkdir -p ~/workspace/exmail

编辑创建 docker-compose.yml 文件:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
version: '3'
services:
mail:
image: palidin/extmail:latest
hostname: mail.unusebamboo.top
container_name: extmail
restart: always
ports:
- '25:25'
- '10:110'
- '143:143'
- '80:80'
- '3306:3306'
privileged: true
environment:
#EXTMAIL_LANG: en_US
EXTMAIL_LANG: zh_CN
volumes:
- /data/mail/vmail:/home/domains
- /data/mail/database:/var/lib/mysql/extmail

注意更改里面的邮件hostname值. 配置完成之后, 直接下载安装, 运行镜像:

1
docker-compose up -d

此时你再次访问 WEB 服务https://mail.unusebamboo.top就会进入到 extmail 邮件首页.
但是正如上面所描述的那样, 腾讯云, 阿里云, AWS都不支持邮件服务器以出口25端口进行垃圾邮件的发送, 一旦被查出来,则解封
的 25 端口就会被永久限制, 这时候就需要配置993, 465端口.

管理, 登录管理后台https://mail.unusebamboo.top/extman, 初始账户:

1
2
root@extmail.org
extmail*123*

另外, 如果对方邮件服务器仅仅支持 25 端口, 则不能使用阿里云和腾讯云, 可以购买 vultr vps 主机, 你需要给客服发送unbolock 25端口的邮件, 然后将公司名称, 邮件用途, 每天邮件限制数量都告诉对方就可以了, 客服反馈非常快速方便, 邮件例子:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
Hello,
1. Business Name: xx有限公司(China)
2. Organization URL: https://www.xxx.com/
3. Email Function: We are a travel agency, we want to register some accounts for XXX. Only send 1~10 emails to a@bifeng.com every email account.
4. The volume of email: Less than 50 per day.

Thanks.

官网反馈很快:
Hello,

Thank you for the information provided!

We have removed the default SMTP block on your account. Please re-start your instances via https://my.vultr.com, for the change to take effect (re-starting the server itself _will_not_ work).

If you need further assistance, please do not hesitate to contact us. Our support staff is here and happy to assist you.

If you have any additional questions our team is happy to further assist you.

Thank you for your understanding.

David P.
Customer Support
www.VULTR.com

另外, 由于服务器在海外, 使用 mysql 连接的时候, 会出现shakehand失败, 此时就需要使用 SSH 来进行 MySQL 连接:

1
2
3
4
连接方法: 选择Standard TCP/IP over SSH
输入ssh账户和证书: 用户名和公钥证书
输入mysql账户
输入mysql数据库

参考

roundcubemail

使用 roundcubemail 镜像安装邮件服务, 类似 exmail:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
docker run -p 80:80 -h mail.unusebamboo.top -e ROUNDCUBEMAIL_DEFAULT_HOST=mail.unusebamboo.top \
-e ROUNDCUBEMAIL_SMTP_SERVER=smtp.unusebamboo.top \
-e ROUNDCUBEMAIL_DB_HOST=172.17.0.11 -e ROUNDCUBEMAIL_DB_TYPE=mysql \
-e ROUNDCUBEMAIL_DB_USER=mail -e ROUNDCUBEMAIL_DB_PASSWORD=Mail,123456 \
-e ROUNDCUBEMAIL_DB_NAME=mailserver \
roundcube/roundcubemail


docker run -d -p 80:80 -h mail.unusebamboo.top -e ROUNDCUBEMAIL_DEFAULT_HOST=mail.unusebamboo.top \
-e ROUNDCUBEMAIL_SMTP_SERVER=smtp.unusebamboo.top \
-e ROUNDCUBEMAIL_DB_HOST=172.17.0.11 -e ROUNDCUBEMAIL_DB_TYPE=mysql \
-e ROUNDCUBEMAIL_DB_USER=mail -e ROUNDCUBEMAIL_DB_PASSWORD=Mail,123456 \
-e ROUNDCUBEMAIL_DB_NAME=mailserver \
roundcube/roundcubemail

其中 roundcubemail 的配置说明见: roundcubemail

others

其他邮件 docker 服务器, 例如: docker-mailserver

参考:
install docker
docker compose

安装 LAMP

参考:
Install Mysql on ubuntu
Configure LAMP on Ubuntu
Secure Apache with Letsencrypt

安装 mysql

安装 Mysql 并配置默认的 root 密码:

1
2
3
4
5
6
7
8
9
# 安装
apt-get update
apt-get install mysql-server
mysql_secure_installation
# 查看
systemctl status mysql.service
mysqladmin -p -u root version
# 配置完成之后, 登录mysql
mysql -uroot -p

设置本地用户可登陆:

1
2
3
4
create database mailserver CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
- 这条命令危险
GRANT all privileges ON mailserver.* TO 'mail'@'%' IDENTIFIED BY 'password';
flush privileges;

更改 mysql 配置文件: ```bind-address=0.0.0.0`

安装 apache

安装 WEB 静态服务器 apache:

1
2
3
4
5
# 安装
apt-get update
apt-get install apache2
# 测试
apache2ctl configtest

编辑配置文件/etc/apache2/apache2.conf, 添加 ServerName:

1
ServerName mail.unusebamboo.top

重新测试并重启 apache:

1
2
apache2ctl configtest
systemctl restart apache2

如果存储 ufw 防火墙配置, 则设置路由通过规则:

1
2
3
ufw app list
ufw app info "Apache Full"
ufw allow in "Apache Full"

此时就可以访问https://mail.unusebamboo.top查看 apache 是否安装完成.

安装 PHP

安装 PHP 服务: apt-get install php libapache2-mod-php php-mcrypt php-mysql

配置 apache 以支持 PHP, 编辑/etc/apache2/mods-enabled/dir.conf文件:

1
2
3
<IfModule mod_dir.c>
DirectoryIndex index.php index.html index.cgi index.pl index.xhtml index.htm
</IfModule>

重启 apache 并重新测试:

1
2
systemctl restart apache2
systemctl status apache2

至此整个 LAMP 基本完成, 至于其他 PHP 的模块检查见参考文件.

Encrypt

对网站添加免费的 TLS 证书, 以支持 HTTPS 服务, 其中如何在 ubuntu 上对 nginx 进行证书配置见
secure nginx on ubuntu的详细说明, 这里主要讲解
对 apache 进行 TLS/SSL 的加密配置工作. 注意, 在安装下面的证书包时, 最好配置一个 VPS, 以加快
包的安装速度.

1
2
3
4
5
# 添加源
apt-get update
# 安装certbot
apt install certbot
apt-get install python-certbot-apache

添加加密证书: certbot certonly --apache -d mail.unusebamboo.top

测试网站: https://www.ssllabs.com/ssltest/analyze.html?d=mail.unusebamboo.top

加入定时任务, 确保自动定时的刷新证书: certbot renew --dry-run

MX 配置

参考: postfix, dovecot

邮件术语

在完成上述的域名解析, LAMP 服务, TLS/SSL 加密支持之后, 现在让我们正式开始进行邮件服务的搭建, 在进行邮件服务
搭建之前, 最后先去了解一下:

  • 什么是 MUA? 什么是 MDA? 什么是 MRA? 什么是 MDA?
  • 什么是 SMTP?什么是 IMAP? 什么是 POP3?
  • 每一个账号的邮件都存储在邮件服务器的什么地方? 什么是 Mailbox?
  • 邮件的发送过程是怎样的? 邮件的接收是怎样的?
  • 在客户端是如何配置, 才能收到邮件服务器, 才能发送邮件?
  • 什么是 MSA?

整个邮件发送接收系统结构如下:

email-system

其中 MUA(Mail User Agent, 邮件发送代理)作为个人电脑上的客户端软件, 通过 STMP, IMAP, POP3 来进行邮件通信:

  • 通过 SMTP 协议来发送邮件, 使用端口 25, 994/465, 基于 STARTTLS 的 587, 大部分邮箱不支持使用 25 端口直接发送邮件, 避免大规模的发送垃圾邮件;
  • 通过 IMAP 协议来接收邮件, 使用端口为 143, 993, 目前一般都是用 993 来发送 TLS 邮件;
  • 通过 POP3 协议来接收邮件(离线协议), 使用端口为 110, 993, 目前一般使用 995 来发送 TLS 邮件

其中 POP3 是电子邮件离线协议标准, 在客户端收到邮件并进行删除移动之后的操作不会同步到邮件服务器上, 而 IMAP 提供了 WebMail 和客户端之间的双向通信, 客户端的操作都会即时的同步到服务器上.三者的英文全称分别是:

  • SMTP: Simple Mail Transfer Protocol, 简单邮件传输协议
  • POP3: Post Office Protocol 3, 邮局协议第三个版本
  • IMAP: Internet Mail Access Protocol, 交互式邮件存取协议

MTA(Mail Transfer Agent, 邮件传送代理)作为主要的邮件服务器, 负责接收邮件, 发送邮件. 对发送邮件, 首先通过 MDA 进行反垃圾检查, 然后通过查询 DNS, 找到目的MTA并传递邮件. 对接收邮件, 通过进行反垃圾检查以及账号查询, 最后通过 MRA 将邮件推送给 MUA 目标用户客户端.

MDA(Mail Delivery Agent, 邮件递送代理)依托于 MTA, 对收到的邮件表头进行分析以决定该邮件的去处, 即转递功能, 对于以 MTA 为目标的邮件, MDA 会将该邮件存储到使用者的信箱(mailbox)中, 如果不是, 则进行转发. 另外, MDA 还会根据表头以及邮件体来判断邮件是否为垃圾邮件.

Mailbox(电子信箱)即某个账号的所有邮件归档目录, 其中 Linux 默认信箱为/var/spool/mail/使用者, 不过建议使用 mysql 或者 mongodb, 这样能够更好的进行邮箱账号管理.

MSA(Mail Submmission Agent, 邮件提交代理)位于 MUA/MTA 之间, 作为发送邮件的检查器存在, MRA 则是收邮件时生效, MSA 会完成所有的检查
工作和错误检测, 默认使用 587 端口.

发送邮件

那么, 一封邮件是如何发送到对方邮箱的呢? 在知道了整个邮件系统的基础架构之后, 我们至少了解一份邮件通过 SMTP 发送的目标邮箱所属的 MTA 上, 然后使用 IMAP/POP3 同步到对方邮箱客户端上, 现在我们就详细的讲解一下邮件的发送过程.

步骤 1: 配置客户端并获取权限

我们首先得配置客户端以能够使用 SMTP 来正常的发信, 使用 IMAP/POP3 同 MRA 进行正常的同步工作, 然后登录账号密码以获取同步权限

步骤 2: 发送邮件

在使用 SMTP 将邮件发送给 MTA 之后, MDA 开始分析邮件, 判断邮件的权限等, 如果目标邮件为当前邮件服务器, 则直接将邮件发送到对应账户的 Mailbox 中.

如果目标邮件为其他 MTX, 则此时需要查询 DNS MX 记录, 然后利用 MTA 将邮件传递给下一个 MTA, 至此整个邮件发送在本 MTX 的操作全部完成.

接收邮件

MTX 在收到邮件之后, 会先让 MDA 判断目标邮箱是否存在, 目标邮件是否为垃圾邮件, 如果以上都验证通过, 那么 MDA 就会将邮件放入指定的 Mailbox 中, 至此, 整个邮件从发件人电脑上到达目标服务器.

但是, 我们会发现此时邮件并未到达收件人客户端所在电脑上, 接下来我么那就来讲解客户端如何通过 POP3/IMAP 来同步邮件服务器上的信箱.

MUA 会定时的向 MRA 发送同步邮件请求, 当然对于 POP3/IMAP, 请求内容还有有一些区别的, MRA 在接收到同步请求之后, 会到使用者的 Mailbox 下获取新建并同步.

邮件服务器搭建

参考:

configure-mail-server

架构

根据上面的 MX 配置可知, 如果需要配置邮件服务器, 我们需要一下几个东西:

  • MTA, MDA: 使用 postfix 来实现
  • MRA: 使用 dovecot 来实现
  • DNS 配置解析, FQDN 配置
  • 邮箱的存储: 使用 MYSQL 来进行邮箱存储

其中 mysql 的安装见第四章介绍, DNS解析第二章介绍, 下面我们主要讲解 postfix 的安装配置, dovecot 的安装配置, 以及如何配合 MYSQL, DNS 解析, 完成一个加密邮件的发送.

安装包, 以支持后续的所有配置工作:

1
apt-get install apache2 postfix dovecot-core dovecot-imapd dovecot-pop3d dovecot-lmtpd dovecot-mysql spamassassin clamav clamav-daemon clamav-base php phpmyadmin

postfix

知识点

postfix-邮件传输代理软件, 快速, 管理简单, 兼容 UNIX 老版本的 sendmail 应用, 提供更加优质的邮件代理服务. 其中 postfix 中两个重要的配置文件:

  • master.cf: 定义了启用哪些 Postfix 服务以及客户端如何连接它们
  • main.cf: 主配置文件

其他相关配置文件以及配置项说明见 postfix 官网说明. postfix 在交付邮件的时候有两种不同的交付用户方式: 系统本地用户,
虚拟用户, 其中前者仅仅向本地系统用户(在/etc/passwd中存在)发送邮件, 此时前者的配置一般如下:

1
2
3
4
5
6
myhostname = localhost
mydomain = localdomain
mydestination = $myhostname, localhost.$mydomain, $mydomain
inet_interfaces = $myhostname, localhost
mynetworks_style = host
default_transport = error: outside mail is not deliverable

虚拟用户邮件则需要配合数据库来存储用户账户, 此方式就是通常意义上的邮件账户.

TLS

默认情况下, postfix 不支持TLS, secure mail, 默认为 25 端口, 在存在 MSA 的前提下, 为了支持STARTTLS, 587, 需要做如下配置:

编辑/etc/postfix/main.cf:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
# tls支持
smtpd_tls_security_level = may
smtpd_tls_auth_only = yes
smtpd_tls_cert_file = /etc/letsencrypt/live/mail.unusebamboo.vip/cert.pem
smtpd_tls_key_file = /etc/letsencrypt/live/mail.unusebamboo.vip/key.pem

# sasl支持, 使用587进行通信
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
smtpd_relay_restrictions =
permit_mynetworks,
permit_sasl_authenticated,
defer_unauth_destination

# 其他配置见下文

配置支持 STARTTLS 邮件传输(开启 587 端口), 在证书存在的前提下, 增加配置: /etc/postfix/master.cf:

1
2
3
4
5
6
# 取消注释
submission inet n - - - - smtpd
-o syslog_name=postfix/submission
-o smtpd_tls_security_level=encrypt
-o smtpd_sasl_auth_enable=yes
-o smtpd_client_restrictions=permit_sasl_authenticated,reject

为了支持加密方式传输邮件(开启 465 端口), 以支持smtps SSL加密传输, 在已经存在证书的前提下, 增加配置/etc/postfix/master.cf:

1
2
3
4
5
6
7
8
9
# 465加密传输
smtps inet n - n - - smtpd
-o syslog_name=postfix/smtps
-o smtpd_tls_wrappermode=yes
-o smtpd_sasl_auth_enable=yes
-o smtpd_reject_unlisted_recipient=no
-o smtpd_recipient_restrictions=
-o smtpd_relay_restrictions=permit_sasl_authenticated,reject
-o milter_macro_daemon_name=ORIGINATING

配置

在了解上面的一些邮件的基本知识点之后, 现在让我们开始准备进行邮件服务器的配置工作吧, 在这之前, 你首先必须确保你的服务器已经
完成如下的几个工作:

  • FQDN 配置解析工作
  • 安装已经支持 TSL 的 web 静态服务器, 以便支持后续的 webmail
  • 完成数据库的配置工作, 这里我们以 MySQL 为例子

a) 让我们创建一个专门的虚拟用户邮件数据库, 以便支持后续的其他操作:

1
2
3
4
5
6
# 安装
apt-get install postfix postfix-mysql dovecot-core dovecot-imapd dovecot-lmtpd dovecot-mysql
# 创建数据库
mysqladmin -p create servermail
# 登录
mysql -uroot -p

创建邮件关联的表结构, 以便进行简单的测试工作, 在引入 webmail 第三方框架之后, 这些表仍旧需要使用,因为 webmail 框架是依赖于 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
-- 1 设置用户和密码: usermail, "Mail,123456"
GRANT SELECT ON servermail.* TO 'usermail'@'127.0.0.1' IDENTIFIED BY 'Mail,123456';
FLUSH PRIVILEGES;

-- 2 创建表结构
USE servermail;

-- 创建特定的授权域名表
CREATE TABLE `virtual_domains` (
`id` INT NOT NULL AUTO_INCREMENT,
`name` VARCHAR(50) NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

-- 虚拟邮件账户表
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;

-- 别名, 以支持转发, 邮件别名可以参考163邮箱, 多个账号共用一个邮箱
CREATE TABLE `virtual_aliases` (
`id` INT NOT NULL AUTO_INCREMENT,
`domain_id` INT 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;

b) 导入测试数据到数据库中
增加白名单 FDQN 到表中:

1
2
3
4
5
INSERT INTO `servermail`.`virtual_domains`
(`id` ,`name`)
VALUES
('1', 'unusebamboo.vip'),
('2', 'mail.unusebamboo.vip');

添加虚拟邮箱账户

1
2
3
4
5
6
/* SHA521密码加密 */
INSERT INTO `servermail`.`virtual_users`
(`domain_id`, `password` , `email`)
VALUES
('2', ENCRYPT('superman123', CONCAT('$6$', SUBSTRING(SHA(RAND()), -16))), 'bifeng@unusebamboo.vip'),
('2', ENCRYPT('superwoman123', CONCAT('$6$', SUBSTRING(SHA(RAND()), -16))), 'xiaoyuan@unusebamboo.vip');

添加虚拟邮箱账户别名

1
2
3
4
5
INSERT INTO `servermail`.`virtual_aliases`
(`domain_id`, `source`, `destination`)
VALUES
('2', 'bamboo@unusebamboo.vip', 'bifeng@unusebamboo.vip'),
('2', 'stupid@unusebamboo.vip', 'bifeng@unusebamboo.vip');

再添加完这些测试之后, 退出 mysql, 进入下一阶段配置工作, 后续会使用到这些数据用以验证邮件服务器是否正常运行.

c) 配置 postfix
注意, 我们需要配置 postfix 以达到通过MySQL数据库中的邮箱账户进行发送邮件, 接收邮件的目的, 下面是整个 postfix 发送邮件
的配置工作.

备份: cp /etc/postfix/main.cf /etc/postfix/main.cf.orig

编辑/etc/postfix/main.cf, 以增加 TLS 支持, 其中证书在第四章已经配置并生成.

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
# TLS支持
smtpd_tls_cert_file=/etc/letsencrypt/live/mail.unusebamboo.vip/fullchain.pem
smtpd_tls_key_file=/etc/letsencrypt/live/mail.unusebamboo.vip/privkey.pem
smtpd_use_tls=yes
smtpd_tls_auth_only = yes

# 使用devecot来作为MRA, 支持SASL, 以使用587端口发送
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
smtpd_relay_restrictions =
permit_mynetworks,
permit_sasl_authenticated,
defer_unauth_destination

# 增加虚拟用户支持
#mydestination = example.com, hostname.example.com, localhost.example.com, localhost
mydestination = localhost
# FQDN
myhostname = mail.unusebamboo.vip

# 增加devecot对所有在数据库中的virtual domains的支持
virtual_transport = lmtp:unix:private/dovecot-lmtp

# 告知postfix, 如何从邮箱数据库中提取virtual domains, user, alias user信息, 类似一个sql语句
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

编辑/etc/postfix/master.cf增加 TLS/SAS 等支持:

1
2
3
4
5
6
# 支持587
submission inet n - - - - smtpd
-o syslog_name=postfix/submission
-o smtpd_tls_security_level=encrypt
-o smtpd_sasl_auth_enable=yes
-o smtpd_client_restrictions=permit_sasl_authenticated,reject

这三个配置文件的内容分别如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
# 域名: /etc/postfix/mysql-virtual-mailbox-domains.cf
user = usermail
password = Mail,123456
hosts = 127.0.0.1
dbname = servermail
query = SELECT 1 FROM virtual_domains WHERE name='%s'

# 用户: /etc/postfix/mysql-virtual-mailbox-maps.cf
user = usermail
password = Mail,123456
hosts = 127.0.0.1
dbname = servermail
query = SELECT 1 FROM virtual_users WHERE email='%s'

# 别名: /etc/postfix/mysql-virtual-alias-maps.cf
user = usermail
password = Mail,123456
hosts = 127.0.0.1
dbname = servermail
query = SELECT destination FROM virtual_aliases WHERE source='%s'

在完成上述配置之后, 需要重启 postfix, 并进行 postfix 和 mysql 的连通测试:

1
2
3
4
5
6
7
8
# 重启
systemctl restart postfix
systemctl status postfix

# 测试, 结果一般都是1/2
postmap -q unusebamboo.vip mysql:/etc/postfix/mysql-virtual-mailbox-domains.cf
postmap -q bifeng@unusebamboo.vip mysql:/etc/postfix/mysql-virtual-mailbox-maps.cf
postmap -q bamboo@unusebamboo.vip mysql:/etc/postfix/mysql-virtual-alias-maps.cf

在完成上述测试之后, postfix(MTU)的配置大体完成.

dovecot

知识点

配置

a) 备份配置文件

1
2
3
4
5
6
cp /etc/dovecot/dovecot.conf /etc/dovecot/dovecot.conf.orig
cp /etc/dovecot/conf.d/10-mail.conf /etc/dovecot/conf.d/10-mail.conf.orig
cp /etc/dovecot/conf.d/10-auth.conf /etc/dovecot/conf.d/10-auth.conf.orig
cp /etc/dovecot/dovecot-sql.conf.ext /etc/dovecot/dovecot-sql.conf.ext.orig
cp /etc/dovecot/conf.d/10-master.conf /etc/dovecot/conf.d/10-master.conf.orig
cp /etc/dovecot/conf.d/10-ssl.conf /etc/dovecot/conf.d/10-ssl.conf.orig

b) 更改/etc/dovecot/dovecot.conf配置文件

1
2
3
4
5
# 取消注释
!include conf.d/*.conf
# 支持POP3
!include_try /usr/share/dovecot/protocols.d/*.protocol
protocols = imap lmtp

c) 更改/etc/dovecot/conf.d/10-mail.conf配置文件

1
2
3
# 更改
mail_location = maildir:/var/mail/vhosts/%d/%n
mail_privileged_group = mail

d) 更改和设置权限, 创建邮件用户以及组, 确保相关目录的访问权限

1
2
3
4
5
6
7
8
9
10
# 查看/var/mail是否仍然属于root用户组
ls -ld /var/mail
# 创建vhosts
mkdir -p /var/mail/vhosts/unusebamboo.vip
# 添加vmail用户, 组
groupadd -g 5000 vmail
useradd -g vmail -u 5000 vmail -d /var/mail
chown -R vmail:vmail /var/mail
#
ls -ld /var/mail

e) 更改认证配置/etc/dovecot/conf.d/10-auth.conf:

1
2
3
4
5
6
# 取消注释, 禁用明文
disable_plaintext_auth = yes
auth_mechanisms = plain login
# 设置mysql认证支持
#!include auth-system.conf.ext
!include auth-sql.conf.ext

f) 设置/etc/dovecot/conf.d/auth-sql.conf.ext 数据库认证配置

1
2
3
4
5
6
7
8
passdb {
driver = sql
args = /etc/dovecot/dovecot-sql.conf.ext
}
userdb {
driver = static
args = uid=vmail gid=vmail home=/var/mail/vhosts/%d/%n
}

g) 设置数据库连接信息/etc/dovecot/dovecot-sql.conf.ext:

1
2
3
4
5
6
7
# 取消注释
driver = mysql
# 连接数据库的密码
connect = host=127.0.0.1 dbname=servermail user=usermail password=Mail,123456
# 使用SHA512加密
default_pass_scheme = SHA512-CRYPT
password_query = SELECT email as user, password FROM virtual_users WHERE email='%u';

h) 设置 dovecot 配置目录权限

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

i) dovecot 主配置/etc/dovecot/conf.d/10-master.conf:

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
service imap-login {
inet_listener imap {
port = 0
}

#Create LMTP socket and this configurations
service lmtp {
unix_listener /var/spool/postfix/private/dovecot-lmtp {
mode = 0600
user = postfix
group = postfix
}
#inet_listener lmtp {
# Avoid making LMTP visible for the entire internet
#address =
#port =
#}
}
service auth {

unix_listener /var/spool/postfix/private/auth {
mode = 0666
user = postfix
group = postfix
}

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

#unix_listener /var/spool/postfix/private/auth {
# mode = 0666
#}

user = dovecot
}

service auth-worker {
# Auth worker process is run as root by default, so that it can access
# /etc/shadow. If this isn't necessary, the user should be changed to
# $default_internal_user.
user = vmail
}

j) 证书配置/etc/dovecot/conf.d/10-ssl.conf

1
2
3
4
ssl = required
# 证书, 注意<括号
ssl_cert = </etc/letsencrypt/live/mail.unusebamboo.vip/fullchain.pem
ssl_key = </etc/letsencrypt/live/mail.unusebamboo.vip/privkey.pem

测试

完成上述配置之后, 重启 dovecot 配置: systemctl status dovecot; systemctl restart dovecot

测试 telnet 是否正常: telnet mail.unusebamoo.vip 993

SpamAssassin

知识点

配置

a) 安装: apt-get install spamassassin spamc

b) 创建用户: adduser spamd --disabled-login

c) 编辑/etc/default/spamassassin:

1
2
3
4
5
6
7
ENABLED=1

SPAMD_HOME="/home/spamd/"
OPTIONS="--create-prefs --max-children 5 --username spamd --helper-home-dir ${SPAMD_HOME} -s ${SPAMD_HOME}spamd.log"

PIDFILE="${SPAMD_HOME}spamd.pid"
CRON=1

d) 编辑/etc/spamassassin/local.cf设置规则

1
2
3
4
5
6
7
8
9
10
rewrite_header Subject ***** SPAM _SCORE_ *****
report_safe 0
required_score 5.0
use_bayes 1
use_bayes_rules 1
bayes_auto_learn 1
skip_rbl_checks 0
use_razor2 0
use_dcc 0
use_pyzor 0

e) 将 spamassassin 加入到 postfix 中, 编辑/etc/postfix/master.cf:

1
2
3
4
5
6
smtp      inet  n       -       -       -       -       smtpd
-o content_filter=spamassassin

spamassassin unix - n n - - pipe
user=spamd argv=/usr/bin/spamc -f -e
/usr/sbin/sendmail -oi -f ${sender} ${recipient}

f) 重启:

1
2
3
systemctl start spamassassin
systemctl restart dovecot
systemctl restart postfix

至此, 我们就可以使用 IMAP(993), SMTP(25/587)来进行邮件的发送和接收.

注意, 在客户端设置邮件收发的时候, 服务器配置中对于 993, 587 端口, 都需要设置密码登录, 而不是无密码登录.

在完成上述的配置, 并且客户端能够正常的收发邮件之后, 实际上整个邮件服务器就已经配置完成, 只不过此时没有 web 端以便他人简便的操作而已. 即使配置 webmail, 上面的所有配置都必须保留, webmail 仅仅是对 postfix 的封装.

配置

所有配置文件如下: 邮件配置

Webmail

docker

在第三章我们已经介绍了extmail, roundcubemail等邮件服务器的 docker 安装方式, 在运行 container, 只要配置得当, 一般都会默认开启 80 端口服务, 直接使用 IP 就可以访问 webmail 服务, 只不过默认情况下 extmail 支持 25 端口罢了.

roundcube

在配置完上面的邮件服务之后, 已经可以使用邮件客户端进行邮件的收发, 但是大部分情况需要增加webmail 支持以便能够更方便的使用邮件服务, 这里我们通过roundcubepostfix邮件服务结合, 提供一个 webmail 支持. 注意, 前提条件是已经完成 postfix 的配置工作.

a) 安装并设置 mysql 密码, 确保密码符合 mysql 的安全规则, 否则会创建数据库失败

1
2
3
4
5
# 设置数据库密码, 会自动创建所有相关表
aptitude update && aptitude install roundcube

# 如何创建表格失败, 则可以手动重新创建
mysql -u root -p RoundCube_db < /usr/share/roundcubemail/SQL/mysql.initial.sql

b) 配置 roundcube 服务

备份配置: cp -p /etc/roundcube/defaults.inc.php /etc/roundcube/config.inc.php

配置数据库, 编辑/etc/roundcube/config.inc.php文件:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
# 连接roundcube数据库
$config['db_dsnw'] = 'mysql://roundcube:XXXXXX@localhost/roundcube';
# 配置端口
$config['default_host'] = 'ssl://mail.unusebamboo.vip';
$config['default_port'] = 143;
$config['smtp_server'] = 'ssl://mail.unusebamboo.vip';
$config['smtp_port'] = 587;
$config['smtp_user'] = '%u';
$config['smtp_pass'] = '%p';
$config['smtp_auth_type'] = 'LOGIN';

# 连接postfix配置的数据库服务, 这是不同于roundcube的数据库
$config['plugins'] = array('virtuser_query');
$config['virtuser_query'] = "SELECT Email FROM servermail.virtual_users WHERE email = '%u'";

c) 编辑 apache 配置文件/etc/roundcube/apache.conf

1
2
3
4
5
6
7
# 增加配置
Alias /webmail /var/lib/roundcube
#
<IfVersion >= 2.3>
Require ip AAA.BBB.CCC.DDD
Require all granted
</IfVersion>

d) 重启

1
systemctl restart apache2

e) 访问https://mail.yourdomain.com/webmail

其中账号就是之前通过 postfix 配置的几个邮箱.

参考:

setup-postfix-mail-server-and-dovecot-with-mariadb-in-centos

TLS_README

postfix-question