也不知道发生了什么
本来只是想获取一下 he.net ipv6 认证 然后发现要求使用一个具有IPv6的邮箱来收发邮件, 也不知道哪家公司支持, 就打算自己建立一个自己的域名邮箱, 这也是早有打算。那就开干吧。
环境
选用了国外的VPS,自己安装了新的ubuntu 16.04.3,1G内存 25G的空间
预先配置好了docker
系统 : Ubuntu 16.04.3 LTS
内存 :1G
参考文章来源
https://linode.com/docs/email/
https://www.digitalocean.com/community/search?q=mail
构思
docker 上有看到一个很好的项目,虽然web界面不怎么样,但是看它的说明,看挺安全的 poste 这个自己跑过了,然后看到另外一个 mailu 这个一直运行不了 很迷,但是看着挺好看的,官方提供了一个测试页面。
但我决定自己搭建一个 从头开始,以后再考虑使用第三方的,第三方也只是使用他的 webmail 界面,也许可以考虑自己写一个。
现在大部分都是使用 postifx + Dovecot + mysql,然后使用第三方的邮箱客户端进行收取邮件 以后可能会加上web界面,使用 MySQL 是便于管理,如果 用户集 使用系统的用户集我觉得不大合适
postfix 作为 MTA 使用
Dovecot 提供POP3/SMTP/IMAP服务
使用SSL TLS 加密 客户端与邮件服务器的通讯,获取 SSL 证书可查看我站文章 用上Let’s Encrypt的HTTPS证书
域名解析
配置 BIND 可见文章 权威DNS(造轮子……
给自己的域名添加 以下解析项
@ IN MX 10 mail.example.com.
mail IN A 0.0.0.0
mail IN AAAA ::1
pop IN CNAME mail.example.com.
pop3 IN CNAME mail.example.com.
smtp IN CNAME mail.example.com.
imap IN CNAME mail.example.com.
在网络不是很大型的情况下,可以多种服务部署到同一台服务器上上,并做CNAME解析,如果服务使用人数众多,则建议将每个服务单独放在一台服务器上,并做好DNS解析.
建议服务器的IP做好反向解析,减少发信被拒的情况
安装所需软件包
sudo apt install postfix postfix-mysql \
dovecot-core dovecot-imapd dovecot-pop3d \
dovecot-lmtpd dovecot-mysql mysql-server
根据提示 输入mysql root 的密码 ,以及选择postfix 的环境和 服务器名称
配置
Mysql
登录MySQL 服务器 增加新数据库以及新用户
mysql -u root -p
#增加新数据库
create database mailserver;
#新增mailuser 并授权 其 mailserver 权限
GRANT SELECT ON mailserver.* TO 'mailuser'@'127.0.0.1' IDENTIFIED BY 'mailuserpass';
刷新权限表 FLUSH PRIVILEGES;
创建 邮箱虚拟名称表
CREATE TABLE `virtual_domains` (
`id` int(11) NOT NULL auto_increment,
`name` varchar(50) NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
创建 邮箱表
CREATE TABLE `virtual_users` (
`id` int(11) NOT NULL auto_increment,
`domain_id` int(11) NOT NULL,
`password` varchar(1024) NOT NULL,
`email` varchar(100) 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;
创建 别名列表
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;
添加邮箱虚拟名称
INSERT INTO `mailserver`.`virtual_domains`
(`id` ,`name`)
VALUES
('1', 'example.com'),
('2', 'hostname.example.com'),
('3', 'hostname'),
('4', 'localhost.example.com');
新增用户
INSERT INTO `mailserver`.`virtual_users`
(`id`, `domain_id`, `password` , `email`)
VALUES
('1', '1', ENCRYPT('password', CONCAT('$6$', SUBSTRING(SHA(RAND()), -16))), 'email1@example.com'),
('2', '1', ENCRYPT('password', CONCAT('$6$', SUBSTRING(SHA(RAND()), -16))), 'email2@example.com');
password 请根据实际修改
添加用户别名
INSERT INTO `mailserver`.`virtual_aliases`
(`id`, `domain_id`, `source`, `destination`)
VALUES
('1', '1', 'alias@example.com', 'email1@example.com');
查询一下是否添加成功
SELECT * FROM mailserver.virtual_domains;
SELECT * FROM mailserver.virtual_users;
SELECT * FROM mailserver.virtual_aliases;
添加数据请根据实际情况
POSTFIX
- 备份默认配置
cp /etc/postfix/main.cf /etc/postfix/main.cf.backup
详细配置可见 postfix 上的叙述,我这里只添加
virtual_transport = lmtp:unix:private/dovecot-lmtp
用来告诉postfix 将本域邮件处理交给 Dovecot’s LMTP
- 安全
smtpd_tls_auth_only = yes
smtp_tls_security_level = may
smtpd_tls_security_level = may
- 用户验证
虚拟用户的查询方式以及查询的配置
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
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,
mysql:/etc/postfix/mysql-virtual-email2email.cf
三个文件的配置 写在下面
如果您使用了不同的用户名, 密码, 数据库名称, 数据库字段名,甚至数据库不在本地服务器上,请根据实际情况修改.
/etc/postfix/mysql-virtual-mailbox-domains.cf
user = mailuser
password = mailuserpass
hosts = 127.0.0.1
dbname = mailserver
query = SELECT 1 FROM virtual_domains WHERE name='%s'
/etc/postfix/mysql-virtual-mailbox-maps.cf
user = mailuser
password = mailuserpass
hosts = 127.0.0.1
dbname = mailserver
query = SELECT 1 FROM virtual_users WHERE email='%s'
/etc/postfix/mysql-virtual-alias-maps.cf
user = mailuser
password = mailuserpass
hosts = 127.0.0.1
dbname = mailserver
query = SELECT destination FROM virtual_aliases WHERE source='%s'
/etc/postfix/mysql-virtual-email2email.cf
user = mailuser
password = mailuserpass
hosts = 127.0.0.1
dbname = mailserver
query = SELECT email FROM virtual_users WHERE email='%s'
修改完成后sudo service postfix restart
重启postfix,然后执行测试
postmap -q example.com mysql:/etc/postfix/mysql-virtual-mailbox-domains.cf
postmap -q email1@example.com mysql:/etc/postfix/mysql-virtual-mailbox-maps.cf
postmap -q alias@example.com mysql:/etc/postfix/mysql-virtual-alias-maps.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_relay_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_relay_restrictions=permit_sasl_authenticated,reject
-o milter_macro_daemon_name=ORIGINATING
sudo service postfix restart
重启 postfix,这样postfix 就配置完成了
Dovecot
- 备份原有配置
sudo cp -a /etc/dovecot /etc/dovecot.backup
- 启用协议
修改文件##### /etc/dovecot/dovecot.conf增加
protocols = imap pop3 lmtp
以启用 imap pop3 lmtp 协议
- 建立邮件存储文件夹
修改/etc/dovecot/conf.d/10-mail.conf
maildir:/var/mail/vhosts/%d/%n
mail_privileged_group = mail
maildir 为存储位置 %d表示域名, %n 表示邮箱全名, %u 表示用户名,可根据需要修改
ls -ld /var/mail
新建用户 并修改 /var/mail所有者
sudo groupadd -g 5000 vmail
sudo useradd -g vmail -u 5000 vmail -d /var/mail
sudo chown -R vmail:vmail /var/mail
建立文件夹
mkdir -p /var/mail/vhosts/example.com
chown -R mail /var/mail/
- 用户身份验证
/etc/dovecot/conf.d/10-auth.conf
#停止使用明文验证
disable_plaintext_auth = yes
#修改登录验证机制
auth_mechanisms = plain login
停止使用系统账户登录 !include auth-system.conf.ext
前加入 # 注释掉语句
去掉 #!include auth-sql.conf.ext
前的 # 以启用 MySQL 验证身份
验证身份文件/etc/dovecot/conf.d/auth-sql.conf.ext
passdb {
driver = sql
args = /etc/dovecot/dovecot-sql.conf.ext
}
userdb {
driver = static
args = uid=vmail gid=vmail home=/var/mail/vhosts/%d/%n
}
sql身份验证配置,修改以下文件的行段/etc/dovecot/dovecot-sql.conf.ext
driver = mysql
connect = host=127.0.0.1 dbname=mailserver user=mailuser password=mailuserpass
default_pass_scheme = SHA512-CRYPT
password_query = SELECT email as user, password FROM virtual_users WHERE email='%u';
- 连接配置
由于我们还未配置安全证书,所以暂不开放与安全有关的端口
去掉以下行段的注释并根据需要修改
inet_listener imap {
port = 143
}
inet_listener pop3 {
port = 110
}
unix_listener lmtp {
mode = 0666
}
unix_listener auth-userdb {
mode = 0666
}
service lmtp {
unix_listener /var/spool/postfix/private/dovecot-lmtp {
mode = 0600
user = postfix
group = postfix
}
}
unix_listener /var/spool/postfix/private/auth {
mode = 0666
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
}
user = dovecot
}
service auth-worker {
user = vmail
}
这里 有整份文档的全部内容
重启 sudo service dovecot restart
这样就配置完成了,来修 bug 吧~
测试以及修复奇怪的bug
没加密的情况下 outlook 一直连接不上Orz, 然后查了好久 在 /etc/dovecot/dovecot.conf 里加上
disable_plaintext_auth = no
ssl_disable = no
这时候,能接受邮件,但是不一定发得出去,得看服务器提供商的设置,是否开放了25端口,大部分已经不开放了……垃圾邮件这么多,谁也不想毁了自己的名誉。我当时发了一个工单,很快就给开通了。
如何确保你和服务器之间的连接是安全可靠的呢?见文章 搭建自己的邮件系统——SSL安全