本站首页 返回顶部 关于博主

使用Poste自建邮件服务器

PDF版

背景

      小程序 扫码签到工具 需要通过邮箱给用户发送签到二维码与签到详情。小程序每天发送的邮件数在 300 到 500 封左右。在选取邮箱服务商时,我使用了腾讯企业邮箱。由于腾讯的企业邮箱每天允许的邮件上限是 500 封,为了避免因用户暴增导致邮件数达到上限,我创建了3个企业邮箱(不是在一个域名下创建3个邮箱,而是分别使用3个域名创建企业邮箱),让3个邮箱轮换给用户发邮件。

      在使用腾讯企业邮箱过程中,当小程序发邮件频率比较高的时候,经常收到提示,需要输入验证码才能发送邮件。次数多了,我就开始犹豫,是否应该考虑其他的方案了,如 SendCloud、Amazon SES、Mailgun、SendGrid,甚至自建邮箱。

      周六上午,小程序频繁地出现邮件发送失败的情况,失败信息为 550 Sender frequency limited。我立即分别申请了 sohu、163 邮箱,在发送邮件时,分别轮换这几个邮箱向用户发送邮件,让腾讯邮箱稍作休息。

      出现这么严重的问题,是时候考虑其他的解决方案了。

方案

可选方案

      有两种解决方案:1. 选用第三方的邮件推送服务;2.自建邮箱服务器。

      扫码签到工具 小程序的用户绝大部分在国内,使用 QQ 邮箱的比例超过 50%。

      关于方案一,第三方邮件推送服务。基本上可以忽略 Amazon SES、Mailgun、SendGrid,根本用户的反馈来看,xQQ 邮箱基本收不到来自这些服务商的邮件,这样就只剩下 SendCloud 这一个选项了。

      至于方案二,如果选择国外的 VPS,一方面担心不经意之间被墙,另一方面连接速度比较慢,只能考虑国内的 VPS。至于国内的 VPS,最大的两家阿里与腾讯,都疯掉了 25 端口,这就意味着 VPS 基本行不通。

      回到方案一,那就考虑 SendCloud 吧。读了文档之后,粗估还需要不少工作量。考虑到即将上线的另外一个小程序也需要改造,算了,放弃吧。

      那退而求其次,考虑国外的 VPS 吧。在正式实施之前,我先拿局域网内的服务器试验性地尝试下。

最终方案

      先把内网服务器上与邮件收发相关的端口能对外通信,然后在内网的服务器上安装邮箱服务器即可。当然,最重要的是,必须保证发送出的邮件不会被其他邮箱 (尤其是QQ邮箱) 服务器拒收。

      经过权衡,我选择了 Poste,这是一个轻量的免费邮箱服务器。

实施步骤

1. 对外网开放服务器与邮件相关的端口。

      我的路由器是小米,先使用路由器的端口转发功能,把邮箱收发相关的端口转发到局域网中的服务器。需要转发的端口包括 25、80、443、110、143、465、587、993、995。

      以下是端口转发的部分截图。

小米路由器转发

      由于小米路由器的管理网页占用了80端口,在添加80端口转发之前,需要把它释放出来,可参见这篇文章:小米路由器修改80端口占用

      Poste用到的这几个端口的说明如下:

端口目的
25SMTP – 邮箱服务器接收邮件
80HTTP – 会重定向到https(但这个端口必须开放,用于安装Let’s Encrypt证书)
110POP3 – 访问邮箱的标准协议,在邮件客户端认证之前需要支持 STARTTLS。
143IMAP – 访问邮箱的标准协议,在邮件客户端认证之前需要支持 STARTTLS。
443HTTPS – 通过 Web 网页访问管理页面与邮件客户端页面。
465SMTPS – 较老的SMTPs 端口。
587MSA – 在STARTTLS与认证之后,邮箱客户端通信的 SMTP 端口。
993IMAPS – 加密的 IMAP 端口
995POP3S – 加密的 POP3 端口。

2. 配置 DNS。

      配置 DNS 完全按照参见官方文档 Configuring DNS, 不赘述。

3. 安装 Poste。

1) 下载Docker Image。打开网页 https://hub.docker.com/r/analogic/poste.io ,运行:

docker pull analogic/poste.io

2) 运行 Docker。当然,在创建之前先应创建目录 /home/ubuntu/poste/data 供 docker 共享。

sudo docker run \
-p 25:25 \
-p 80:80 \
-p 443:443 \
-p 110:110 \
-p 143:143 \
-p 465:465 \
-p 587:587 \
-p 993:993 \
-p 995:995 \
-v /etc/localtime:/etc/localtime:ro \
-v /home/ubuntu/poste/data:/data \
–name “posteServer” \
-h “mail.xxx.cn” \
-t analogic/poste.io

      运行完成之后,就可以打开首页 http://mail.xxx.cn 了。

4. 配置 Poste。

      在打开首页 http://mail.xxx.cn 时,它会自动重定向到 https://mail.xxx.cn。

      先配置登录名,之后登录。

在 Vitrual Domains 里,点击域名,然后生成 DKIM 记录,把它填到 DNS 记录中。

生成DKIM
生成DKIM

      然后点击 Server Settings,选择 TLS Certificate 页,在此页面生成 SSL 证书,此证书由 Let’s Encrypt 颁发。在生成证书过程中,会现在服务器上创建一个文件,然后尝试通过 http 请求访问它,以此验证此域名的归属。由于此 http 请求的端口是 80,所以在创建过程中,必须确保 80 端口开放。

      当然,如果有现成的证书可用,不必保证 80 端口可用。

试用

      配置完毕之后,等 2 个小时之后再试用吧。2个小时不是必须的,是为了确保 DNS 在配置之后有足够的时间在全球生效。

      在内网给自己发邮件,发送成功,接收成功。

      分别在内网、外网,发送邮件给 hotmail、gmail、qq。hotmail、qq能收到,不过 hotmail 的邮件进了垃圾箱,gmail收不到一封邮件。但是,我在服务器上运行 wget https://www.google.com,能够获取 google 的首页内容。至于为什么发送给 Gmail 的邮件全收不到,原因未知。

      先通过 hotmail 、qq、gmail 向邮箱服务器发邮件,可以收到。

      可是,当我使用 Laravel 自带邮件代码以 SMTP 协议连上邮件服务器给 QQ 发邮件时,直接收到 550 Mail content denied 的退信。于是,我尝试先通过 QQ 邮箱给服务器发邮件,然后在服务器的web网页上回复邮件,增加邮箱的可信度。再发邮件就没问题了。

总结

      到此为止,Poste 创建的邮箱服务器就可以工作,用来作为邮件服务器为小程序发送邮件了。毕竟是自己家里的服务器,为了保证万一服务器宕机时仍旧能正常发邮件,在系统中,我加进了一段代码,确保邮箱服务器宕掉时,系统立即切换到腾讯邮箱。

后续计划

      下一步,申请国外的 VPS, 代替这台局域网内的邮箱服务器。发邮件的速度可能会慢些,但能保证全球都能收到邮件。与此同时,即将发布的小程序还能共享这台邮箱服务器。

参考资料




请你留言