最新ubuntu搭建公网个人邮件服务器(基于postfix,dovecot,mysql)
<p> 最近做了一个应用,需要用邮件发通知,但是免费的邮箱每天发信数量是有限制的,所以呢就想着搭建一个自己的邮件服务器,能够实现邮件的发送和接收即可,其中大概花了一个星期找资料,测试,终于成功了,写个教程分享给大家。</p><p> 本教程基于 ubuntu 18.04(其他的 linux 理论上也是可以的,只是安装的软件包不一样)。用到的主要软件为:postfix,dovecot,mysql.废话不多说,下面是教程:</p>
<h1 id="前置条件">前置条件</h1>
<ul>
<li>mysql 数据库。本教程中使用 mysql 存储域名,用户信息等。</li>
<li>域名。需要有域名才能实现向公网发邮件/收邮件。这里以 test.com 为例。</li>
<li>ssl 证书。有不少免费的 ssl 证书提供商,或者使用自签证书,百度即可。</li>
</ul>
<h1 id="安装环境">安装环境</h1>
<h2 id="安装软件">安装软件</h2>
<p> 切换到 root 用户下,执行以下命令:</p>
<pre><code class="language-bash">apt update
apt install postfix postfix-mysql dovecot-core dovecot-pop3d dovecot-imapd dovecot-lmtpd dovecot-mysql
</code></pre>
<p>安装过程中 postfix 会弹出提示:</p>
<p><img src="https://raw.githubusercontent.com/FleyX/files/master/blogImg/20190425132019.png" alt="选择类别" loading="lazy"></p>
<p>这里我们选择第二项:Internet Site。<br>
接着会有如下提示:</p>
<p><img src="https://raw.githubusercontent.com/FleyX/files/master/blogImg/20190425132348.png" alt="域名" loading="lazy"></p>
<p>这里填入:<code>test.com</code></p>
<h2 id="配置-mx-解析">配置 mx 解析</h2>
<p> 在域名提供商增加以下解析:</p>
<ul>
<li>MX 记录:<code>test.com</code> 指向 <code>服务器IP</code></li>
<li>A 记录:<code>pop3.test.com</code> 指向 <code>服务器IP</code></li>
<li>A 记录:<code>smtp.test.com</code> 指向 <code>服务器IP</code></li>
</ul>
<h2 id="创建-mysql-数据库">创建 mysql 数据库</h2>
<p> 新建一个数据库 mailserver,管理账号为:admin/123456</p>
<p> 创建虚拟域表,作为认证域。该表是邮件服务器用以接收邮件的域名:</p>
<pre><code class="language-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')
</code></pre>
<p> 创建用户表,用于用户身份认证。</p>
<pre><code class="language-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');
</code></pre>
<p> 创建别名表.该表作用相当于当 source 收到邮件时,该邮件会自动转发到 destination 上。</p>
<pre><code class="language-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')
</code></pre>
<h2 id="生成-ssl-证书">生成 ssl 证书</h2>
<p> 生成 ssl 证书可参考这一篇https://www.jianshu.com/p/b47d862bceeb.为 test.com 生成 ssl 证书,<strong>假设</strong>证书存放地址为:</p>
<ul>
<li>公钥 /etc/letsencrypt/live/test.com/fullchain.pem;</li>
<li>私钥 /etc/letsencrypt/live/test.com/privkey.pem;</li>
</ul>
<h1 id="配置-postfix">配置 postfix</h1>
<p> 首选备份 postfix 的默认配置文件,然后编辑<code>main.cf</code></p>
<pre><code class="language-bash">cp /etc/postfix/main.cf /etc/postfix/main.cf.bak
vim /etc/postfix/main.cf
</code></pre>
<p> 注释下面的配置:<br>
<img src="https://raw.githubusercontent.com/FleyX/files/master/blogImg/20190425135857.png" alt="注释" loading="lazy"></p>
<p>然后加入如下的配置:</p>
<pre><code class="language-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
</code></pre>
<p>修改 myhostname,myorigin 为如下的值:</p>
<pre><code class="language-properties">myhostname = test.com
myorigin = $myhostname
</code></pre>
<p>修改 mydestination 值为 localhost,以启动 mysql 中的虚拟域。:</p>
<pre><code class="language-properties">mydestination = localhost
</code></pre>
<p>在配置文件的最后加入以下行,确保将邮件投递给 mysql 表中列出的虚拟域。</p>
<pre><code class="language-properties">virtual_transport = lmtp:unix:private/dovecot-lmtp
</code></pre>
<p>最后加入以下三项参数,告知 Postfix 配置虚拟域、用户和别名</p>
<pre><code class="language-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
</code></pre>
<p> 接下来创建上面最后加入的三项参数对应的文件。</p>
<p> 创建<code>/etc/postfix/mysql-virtual-mailbox-domains.cf</code>,内容如下:</p>
<pre><code class="language-properties">user = admin
password = 123456
port = 3306
hosts = 127.0.0.1
dbname = mailserver
query = SELECT 1 FROM virtual_domains WHERE name='%s'
</code></pre>
<p>接着重启 postfix,并测试 postfix 能否找到域,如果成功返回 1:</p>
<pre><code class="language-bash">service postfix restart
postmap -q test.com mysql:/etc/postfix/mysql-virtual-mailbox-domains.cf
</code></pre>
<p> 创建<code>/etc/postfix/mysql-virtual-mailbox-maps.cf</code>,内容如下:</p>
<pre><code class="language-properties">user = admin
password = 123456
port = 3306
hosts = 127.0.0.1
dbname = mailserver
query = SELECT 1 FROM virtual_users WHERE email='%s'
</code></pre>
<p>接着重启 postfix,并测试其能否找到邮箱地址,成功返回 1:</p>
<pre><code class="language-shell">service postfix restart
postmap -q first@test.com mysql:/etc/postfix/mysql-virtual-mailbox-maps.cf
</code></pre>
<p> 最后创建<code>/etc/postfix/mysql-virtual-alias-maps.cf</code>,内容如下:</p>
<pre><code class="language-properties">user = admin
password = 123456
port = 3306
hosts = 127.0.0.1
dbname = mailserver
query = SELECT destination FROM virtual_aliases WHERE source='%s'
</code></pre>
<p>同样重启 postfix,验证能否正确找到别名,并返回:</p>
<pre><code class="language-bash">service postfix restart
postmap -q first@test.com mysql:/etc/postfix/mysql-virtual-mailbox-maps.cf
</code></pre>
<p> 如果响应使用 587 端口来进行俺的 smtp 通信,需修改/etc/postfix/master.cf 文件:<br>
取消以下行的注释:<br>
<img src="https://raw.githubusercontent.com/FleyX/files/master/blogImg/20190425144459.png" alt="" loading="lazy"></p>
<h1 id="配置-dovecot">配置 dovecot</h1>
<p> postfix 配置完毕,现在来配置 dovecot,首先编辑主配置文件<code>/etc/dovecot/dovecot.conf</code>:</p>
<p>首先确保下面一行是启用的:</p>
<pre><code class="language-conf">!include conf.d/*.conf
</code></pre>
<p>然后在配置文件的最后加入如下配置,启用各协议:</p>
<pre><code>protocols = imap lmtp pop3
</code></pre>
<p> 修改<code>/etc/dovecot/conf.d/10-mail.conf</code>,确保存在以下两个配置:</p>
<pre><code class="language-properties">mail_location = maildir:/var/mail/vhosts/%d/%n
mail_privileged_group = mail
</code></pre>
<p>上面的配置将邮件存放目录设置在/var/mail 中,因此将该文件夹的所属人改为 vmail/vmail.命令如下:</p>
<pre><code class="language-bash">groupadd -g 5000 vmail
useradd -g vmail -u 5000 vmail -d /var/mail
chown -R vmail:vmail /var/mail
</code></pre>
<p> 修改<code>/etc/dovecot/conf.d/10-auth.conf</code>。首先确保如下两个配置存在且值正确:</p>
<pre><code class="language-properties">disable_plaintext_auth = yes
auth_mechanisms = plain login
</code></pre>
<p>然后修改配置以禁用系统用户登陆,并开启 mysql 支持,如下图所示:<br>
<img src="https://raw.githubusercontent.com/FleyX/files/master/blogImg/20190425150413.png" alt="启用mysql支持" loading="lazy"></p>
<p> 修改<code>/etc/dovecot/conf.d/auth-sql.conf.ext</code>文件,将内容改成下面的内容:</p>
<pre><code class="language-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
}
</code></pre>
<p> 修改<code>/etc/dovecot/dovecot-sql.conf.ext</code>:<br>
首选取消 driver 参数注释并设置为 mysql</p>
<pre><code class="language-properties">driver = mysql
</code></pre>
<p>然后取消 connect 行注释并设置为如下内容:</p>
<pre><code class="language-properties">connect = host=127.0.0.1 port=3306 dbname=mailserver user=admin password=123456
</code></pre>
<p>接着取消 default_pass_scheme 行的注释并改为 MD5</p>
<pre><code class="language-properties">default_pass_scheme = MD5
</code></pre>
<p>接着取消 password_query 行的注释并设置为以下信息:</p>
<pre><code class="language-properties">password_query = SELECT email as user, password FROM virtual_users WHERE email='%u';
</code></pre>
<p>最后将<code>/etc/dovecot</code>的拥有者改为 vmail:dovecot</p>
<pre><code class="language-bash">chown -R vmail:dovecot /etc/dovecot
chmod -R o-rwx /etc/dovecot
</code></pre>
<p> 修改<code>/etc/dovecot/conf.d/10-master.conf</code>:</p>
<p>首先将 imap-login , pop3-login 下第一个的 port 设置为 0,以禁用非 ssl 加密的 imap 和 pop3 协议,如下图所示:<br>
<img src="https://raw.githubusercontent.com/FleyX/files/master/blogImg/20190425153728.png" alt="" loading="lazy"></p>
<p>然后找到<code>service lmtp</code>将其修改为如下:</p>
<pre><code>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 =
#}
}
</code></pre>
<p>然后找到<code>service auth</code>将其内容修改为如下:</p>
<pre><code>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
}
</code></pre>
<p>最后找到<code>service auth-worker</code>改为如下内容:</p>
<pre><code>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
}
</code></pre>
<p> 最后要改的就是<code>/etc/dovecot/conf.d/10-ssl.conf</code>,以开启 ssl 认证.</p>
<p>首先将 ssl 参数改为 required:</p>
<pre><code class="language-properties">ssl = required
</code></pre>
<p>然后设置 ssl 证书路径就 ok 了,还是用之前的 ssl 证书:</p>
<pre><code class="language-properties">ssl_cert = </etc/letsencrypt/live/test.com/fullchain.pem
ssl_key = </etc/letsencrypt/live/test.com/privkey.pem
</code></pre>
<p> 到这里所有的配置都 OK,重启 postfix,dovecot 后就可以用邮箱客户端(比如 foxmail)连接了。</p>
<pre><code>service postfix restart
service dovecot restart
</code></pre>
<h1 id="结束">结束</h1>
<p> 配合一个邮件客户端看似很简单,实际上还是有很多坑的,看看上面那么多的配置项就知道了,一定要耐心。</p>
<p> 如果无法登陆,可以看看 postfix 和 dovecot 的日志报错情况,再去修改。日志位置在<code>/var/log</code></p>
<p><strong>注意</strong>:<br>
被这个问题困扰了好几天,未找到解决办法,最后放弃.</p>
<p> 目前很多主机厂商都不支持和其他服务器的 25 端口通信,已知的有(谷歌云,阿里云),这样就导致在这些机器上搭建的 postfix 邮件服务器,无法向其他的外网邮箱发送邮件,因为无法和其他 smtp 服务器的 25 端口建立连接。貌似是为了避免有人恶意搭建邮件服务器向其他的邮件服务器发送大量的垃圾邮件,从而导致此服务器 IP 被反垃圾邮件组织列入 SML。</p>
<p><strong>本博客原创发布于:</strong>http://tapme.top/blog/detail/2019-04-05</p>
</div>
<div id="MySignature" role="contentinfo">
本文原创发布于:https://blog.fleyx.com,转载请保留来源!<br/>
<span style="font-size:1.2em">都看到这里了,不妨了解下我的个人开源项目云书签管理,使用地址:bm.fleyx.com</span>
<div class="h-center">
<b>我的个人博客,欢迎关注!</b>blog.fleyx.com<br>
如果本篇文章对您有帮助欢迎打赏哦!
<div style="display:flex;justify-content: space-around;padding-top:1em;width:100%">
<img width="110px" height="110px" src="https://files.cnblogs.com/files/wuyoucao/weixin.ico" alt="微信打赏"/>
<img width="110px" height="110px" src="https://files.cnblogs.com/files/wuyoucao/alipay.ico" alt="支付宝打赏"/>
</div>
</div><br><br>
来源:https://www.cnblogs.com/wuyoucao/p/11136430.html
頁:
[1]