From 2372ab6a595aa6584e117ed948e93925c2111904 Mon Sep 17 00:00:00 2001 From: fanxb Date: Thu, 25 Apr 2019 17:17:57 +0800 Subject: [PATCH] =?UTF-8?q?=E6=96=B0=E5=A2=9E=E9=82=AE=E4=BB=B6=E6=9C=8D?= =?UTF-8?q?=E5=8A=A1=E5=99=A8=E6=90=AD=E5=BB=BA=E6=95=99=E7=A8=8B=20=03=03?= =?UTF-8?q?=20;?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- 其他各种/5.linux公网搭建邮件服务器.md | 400 +++++++++++++++++++++++++- 数据库/基础/3.mysql高性能索引.md | 43 +++ 2 files changed, 436 insertions(+), 7 deletions(-) create mode 100644 数据库/基础/3.mysql高性能索引.md diff --git a/其他各种/5.linux公网搭建邮件服务器.md b/其他各种/5.linux公网搭建邮件服务器.md index 5ba725e..7d88ee3 100644 --- a/其他各种/5.linux公网搭建邮件服务器.md +++ b/其他各种/5.linux公网搭建邮件服务器.md @@ -1,11 +1,397 @@ --- -id: "2019-04-02-10-58" -date: "2019/04/02 10:58" -title: "最新linux搭建公网个人邮件服务器" -tags: ["smtp","linux","ubuntu","邮件服务器"] +id: "2019-04-05" +date: "2019/04/25 10:58" +title: "最新ubuntu搭建公网个人邮件服务器(基于postfix,dovecot,mysql)" +tags: ["smtp", "linux", "ubuntu", "邮件服务器", "postfix", "dovecot"] -categories: -- "其他" +categories: + - "搭建服务" --- -如题,待续。 +  最近做了一个应用,需要用邮件发通知,但是免费的邮箱每天发信数量是有限制的,所以呢就想着搭建一个自己的邮件服务器,能够实现邮件的发送和接收即可,其中大概花了一个星期找资料,测试,终于成功了,写个教程分享给大家。 + +  本教程基于 ubuntu 18.04(其他的 linux 理论上也是可以的,知识安装的软件包不一样)。用到的主要软件为:postfix,dovecot,mysql.废话不多说,下面是教程: + +# 前置条件 + +- mysql 数据库。本教程中使用 mysql 存储域名,用户信息等。 +- 域名。需要有域名才能实现向公网发邮件/收邮件。这里以 test.com 为例。 +- ssl 证书。有不少免费的 ssl 证书提供商,或者使用自签证书,百度即可。 + +# 安装环境 + +## 安装软件 + +  切换到 root 用户下,执行以下命令: + +```bash +apt update +apt install postfix postfix-mysql dovecot-core dovecot-pop3d dovecot-imapd dovecot-lmtpd dovecot-mysql +``` + +安装过程中 postfix 会弹出提示: + +![选择类别](https://raw.githubusercontent.com/FleyX/files/master/blogImg/20190425132019.png) + +这里我们选择第二项:Internet Site。 +接着会有如下提示: + +![域名](https://raw.githubusercontent.com/FleyX/files/master/blogImg/20190425132348.png) + +这里填入:`test.com` + +## 配置 mx 解析 + +  在域名提供商增加以下解析: + +- MX 记录:`test.com` 指向 `服务器IP` +- A 记录:`pop3.test.com` 指向 `服务器IP` +- A 记录:`smtp.test.com` 指向 `服务器IP` + +## 创建 mysql 数据库 + +  新建一个数据库 mailserver,管理账号为:admin/123456 + +  创建虚拟域表,作为认证域。该表是邮件服务器用以接收邮件的域名: + +```sql +-- 建立表 +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,'test.com') +``` + +  创建用户表,用于用户身份认证。 + +```sql +-- 创建用户表 +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加密密码,实际应用中应该选择强度更高的算法,md5目前以及不安全了 +insert into virtual_users values(1,1,md5('123456'),'first@test.com'); +insert into virtual_users values(2,1,md5('123456'),'second@test.com'); +``` + +  创建别名表.该表作用相当于当 source 收到邮件时,该邮件会自动转发到 destination 上。 + +```sql +-- 创建表 +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,'first@test.com','second@test.com') + +``` + +## 生成 ssl 证书 + +  生成 ssl 证书可参考这一篇[https://www.jianshu.com/p/b47d862bceeb](https://www.jianshu.com/p/b47d862bceeb).为 test.com 生成 ssl 证书,**假设**证书存放地址为: + +- 公钥 /etc/letsencrypt/live/test.com/fullchain.pem; +- 私钥 /etc/letsencrypt/live/test.com/privkey.pem; + +# 配置 postfix + +  首选备份 postfix 的默认配置文件,然后编辑`main.cf` + +```bash +cp /etc/postfix/main.cf /etc/postfix/main.cf.bak +vim /etc/postfix/main.cf +``` + +  注释下面的配置: +![注释](https://raw.githubusercontent.com/FleyX/files/master/blogImg/20190425135857.png) + +然后加入如下的配置: + +```properties +# 使用自己的ssl证书 +smtpd_tls_cert_file=/etc/letsencrypt/live/test.com/fullchain.pem +smtpd_tls_key_file=/etc/letsencrypt/live/test.com/privkey.pem +smtpd_use_tls=yes +smtpd_tls_auth_only = yes +# 使用dovecot来做身份认证 +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 +``` + +修改 myhostname,myorigin 为如下的值: + +```properties +myhostname = test.com +myorigin = $myhostname +``` + +修改 mydestination 值为 localhost,以启动 mysql 中的虚拟域。: + +```properties +mydestination = localhost +``` + +在配置文件的最后加入以下行,确保将邮件投递给 mysql 表中列出的虚拟域。 + +```properties +virtual_transport = lmtp:unix:private/dovecot-lmtp +``` + +最后加入以下三项参数,告知 Postfix 配置虚拟域、用户和别名 + +```properties +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/mysql-virtual-mailbox-domains.cf`,内容如下: + +```properties +user = admin +password = 123456 +port = 3306 +hosts = 127.0.0.1 +dbname = mailserver +query = SELECT 1 FROM virtual_domains WHERE name='%s' +``` + +接着重启 postfix,并测试 postfix 能否找到域,如果成功返回 1: + +```bash +service postfix restart +postmap -q test.com mysql:/etc/postfix/mysql-virtual-mailbox-domains.cf +``` + +  创建`/etc/postfix/mysql-virtual-mailbox-maps.cf`,内容如下: + +```properties +user = admin +password = 123456 +port = 3306 +hosts = 127.0.0.1 +dbname = mailserver +query = SELECT 1 FROM virtual_users WHERE email='%s' +``` + +接着重启 postfix,并测试其能否找到邮箱地址,成功返回 1: + +```shell +service postfix restart +postmap -q first@test.com mysql:/etc/postfix/mysql-virtual-mailbox-maps.cf +``` + +  最后创建`/etc/postfix/mysql-virtual-alias-maps.cf`,内容如下: + +```properties +user = admin +password = 123456 +port = 3306 +hosts = 127.0.0.1 +dbname = mailserver +query = SELECT destination FROM virtual_aliases WHERE source='%s' +``` + +同样重启 postfix,验证能否正确找到别名,并返回: + +```bash +service postfix restart +postmap -q first@test.com mysql:/etc/postfix/mysql-virtual-mailbox-maps.cf +``` + +  如果响应使用 587 端口来进行俺的 smtp 通信,需修改/etc/postfix/master.cf 文件: +取消以下行的注释: +![](https://raw.githubusercontent.com/FleyX/files/master/blogImg/20190425144459.png) + +# 配置 dovecot + +  postfix 配置完毕,现在来配置 dovecot,首先编辑主配置文件`/etc/dovecot/dovecot.conf`: + +首先确保下面一行是启用的: + +```conf +!include conf.d/*.conf +``` + +然后在配置文件的最后加入如下配置,启用各协议: + +``` +protocols = imap lmtp pop3 +``` + +  修改`/etc/dovecot/conf.d/10-mail.conf`,确保存在以下两个配置: + +```properties +mail_location = maildir:/var/mail/vhosts/%d/%n +mail_privileged_group = mail +``` + +上面的配置将邮件存放目录设置在/var/mail 中,因此将该文件夹的所属人改为 vmail/vmail.命令如下: + +```bash +groupadd -g 5000 vmail +useradd -g vmail -u 5000 vmail -d /var/mail +chown -R vmail:vmail /var/mail +``` + +  修改`/etc/dovecot/conf.d/10-auth.conf`。首先确保如下两个配置存在且值正确: + +```properties +disable_plaintext_auth = yes +auth_mechanisms = plain login +``` + +然后修改配置以禁用系统用户登陆,并开启 mysql 支持,如下图所示: +![启用mysql支持](https://raw.githubusercontent.com/FleyX/files/master/blogImg/20190425150413.png) + +  修改`/etc/dovecot/dovecot-sql.conf.ext`文件,将内容改成下面的内容: + +```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 +} +``` + +  修改`/etc/dovecot/dovecot-sql.conf.ext`: +首选取消 driver 参数注释并设置为 mysql + +```properties +driver = mysql +``` + +然后取消 connect 行注释并设置为如下内容: + +```properties +connect = host=127.0.0.1 port=3306 dbname=mailserver user=admin password=123456 +``` + +接着取消 default_pass_scheme 行的注释并改为 MD5 + +```properties +default_pass_scheme = MD5 +``` + +接着取消 password_query 行的注释并设置为以下信息: + +```properties +password_query = SELECT email as user, password FROM virtual_users WHERE email='%u'; +``` + +最后将`/etc/dovecot`的拥有者改为 vmail:dovecot + +```bash +chown -R vmail:dovecot /etc/dovecot +chmod -R o-rwx /etc/dovecot +``` + +  修改`/etc/dovecot/conf.d/10-master.conf`: + +首先将 imap-login , pop3-login 下第一个的 port 设置为 0,以禁用非 ssl 加密的 imap 和 pop3 协议,如下图所示: +![](https://raw.githubusercontent.com/FleyX/files/master/blogImg/20190425153728.png) + +然后找到`service lmtp`将其修改为如下: + +``` +service lmtp { + unix_listener /var/spool/postfix/private/dovecot-lmtp { + mode = 0600 + user = postfix + group = postfix + } + + # Create inet listener only if you can't use the above UNIX socket + #inet_listener lmtp { + # Avoid making LMTP visible for the entire internet + #address = + #port = + #} +} +``` + +然后找到`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 { + # 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 +} +``` + +  最后要改的就是`/etc/dovecot/conf.d/10-ssl.conf`,以开启 ssl 认证. + +首先将 ssl 参数改为 required: + +```properties +ssl = required +``` + +然后设置 ssl 证书路径就 ok 了,还是用之前的 ssl 证书: + +```properties +ssl_cert = + 和索引列中的所有列进行匹配。比如查询`name='abc' and age=12`,这里用到了第一列和第二列 +- 匹配最左前列
+ 只是用索引的开头部分,比如查询`name='ggg'`只使用索引的第一列,查询`name='ggg' and age=12`是用索引的第一、二列。 +- 匹配列前缀
+ 也可以只匹配某一列的开头部分,比如查询`name lik 'g%'`,查询 name 以 g 开头的记录。这里用到了第一列 +- 匹配范围值
+ 可用于匹配范围值,比如查询`name > 'abc' and ` + \ No newline at end of file