雅云 Email 服务搭建

Update

由于运营商的限制,暂未开放此服务。

背景

工作中偶尔会用上邮件,基本上都是用QQ邮箱。领导想使用自有域名yacloud.net作为邮件域名,但是舍不得花钱购买企业邮箱,更不用说找开发团队来研发。于是折中一下选用开源项目来搭建:

  • 邮件服务器:docker-mailserver

  • 邮件客户端:roundcube

邮件系统经历了几十年的发展已经非常成熟,选用的开源项目文档也比较齐全(英文),但邮件系统属于比较老旧的技术,配置繁琐且生涩难懂,最为重要的还是安全问题。截止到目前,我对于邮件的安全也只是略知一二,对于雅云的邮件系统也只是依赖于防火墙以及WAF。前后断断续续折腾了两三个月,终于成功将邮件系统与雅云LDAP整合部署。

Step 1.理解邮件系统

  • 要正确部署Email,必须对整个邮件系统的组成有必要的了解,以及需要用到的对外端口号(这部分尤为重要,基于许多历史原因以及安全因素,除了25端口外新增了多个端口以实现不同协议的安全连接,非常奇葩)

  • 参考:docker-mailserver官方文档关于邮件系统的介绍(只有英文,啃起来费劲)

  • 核心概念:

    邮件系统是基于C/S架构的,这里的C还包含了B(browser,即浏览器)。完整的邮件投递链至少包含以下三大组件:

    • 用户端:Mail User AgentMUA

      • 用户通过该软件(或网站)可以发送、接收邮件,比如QQ邮箱网站、微软的Outlook软件、iOS上的Mail App;
    • 邮件转发代理系统:Mail Transfer AgentMTA

      • 邮件系统中的关键组件,通常作为邮件服务器运行,负责在发送者和接收者之间传输邮件,该过程叫中继relay);比如通过163邮箱发送邮件至QQ邮件,实际上是163 MTA将邮件发送至QQ MTA

      • 处理邮件的接收、排队、路由、转发;

      • 集成垃圾邮件过滤、病毒扫描、安全隐私保护(TSL/SSL、SPF、DKIM、DMARC)等附加功能;

      • 支持协议:SMTP(25端口,在docker-mailserver中默认启用显示TLS)、ESMTP(464、587端口);

      • docker-mailserver使用的MTA:Postfix

    • 邮件投递代理系统:Mail Delivery AgentMDA

      • 负责将邮件投递到用户的邮箱中,即存储用户的邮件(存储方式可以是文件、数据库等);

      • 邮件查询、索引、检索等

      • 最终的邮件过滤、访问控制等;

      • 支持协议:IMAP(143端口)、IMAP4(993端口)、POP3(110端口)、POP3S(995端口)

      • docker-mailserver使用的MDA:Dovecot

    邮件发送/接收简单示例:

    【MUA1-邮件发送者】—投递邮件—>【MTA1】—relay—>【MTA2】—接收邮件—>【MUA2-邮件接收者】

  • 理解端口

    • 25 - 传统的SMTP端口,在此基础上添加了显式的TLS
    • 110 - POP3 (explicit TSL => STARTTLS)
    • 143 - IMAP4 (explicit TLS => STARTTLS)
    • 465 - ESMTP (implicit TLS)
    • 587 - ESMTP (explicit TLS => STARTTLS)
    • 993 - IMAP4 (implicit TLS)
    • 995 - POP3S (implicit TLS)

Step 2.准备部署

  • 服务器硬件配置:雅云平台创建8核8G主机,并添加一块500G磁盘作为数据盘使用,挂载至/data目录;

  • 服务器环境:系统采用Ubuntu 22.04.4 LTS Server 64位,并安装最新版docker以及docker compose插件;

# 使用雅云镜像服务进行加速下载,注意使用root用户或使用sudo
export DOWNLOAD_URL="https://mirrors.yacloud.net/docker-ce"

使用curl:

curl -fsSL https://mirrors.yacloud.net/docker-ce/get-docker.sh | sh

使用wget:

wget -O- https://mirrors.yacloud.net/docker-ce/get-docker.sh | sh
  • 域名:mail.yacloud.net

  • SSL证书:通过acme.shZeroSSL获取上述域名的免费证书:mail.yacloud.net.crt, mail.yacloud.net.key

  • 邮件服务器(MTA+MDA):源码:docker-mailserver | 官方docker镜像:docker-mailserver

  • 邮件客户端(MUA):源码:roundcube | 官方docker镜像:roundcube

Step 3.目录设置

  • 配置源文件:所有配置文件放到了yacloud工程mail目录下,具体可登录雅云git查看;

  • 工作目录:/root/yacloud/mail(yacloud目录使用git克隆至本地,克隆前通过服务器生成的公钥对git库有访问权限)

  • 数据目录:/data

    • /data/mailserver 邮件系统的根目录
    • /data/mailserver/log 邮件系统日志目录
    • /data/config 邮件系统需要持久化的目录
    • /data/mailstate
    • /data/roundcube roundcube持久化目录
    • /data/roundcube/config roundcube配置文件(暂时为空,如果有需要持久化的目录,优先在yacloud库中添加再进行映射)
    • /data/roundcube/db roundcube数据库目录
    • /data/roundcube/html roundcube前端页面目录,用于nginx反向代理

Step 4.通过docker compose部署

  • 在git库中查看所有文件配置:(https://git.yacloud.net/yacloud/yacloud/src/branch/main/mail)

    • mailserver开放端口情况:

      • 25 IMAP协议,显式TSL
      • 465 ESMTP协议,隐式TSL
      • 993 IMAP4协议,隐式TSL
    • 由于需要用到雅云LDAP,除了环境变量要设置外,还需要配置dovecot的10-mail.conf文件,作用是由LDAP认证的用户具有对应邮件文件夹读写的权限:

      mail_uid = 5000
      mail_gid = 5000
      mail_privileged_group = docker
      first_valid_uid = 1
      first_valid_gid = 1
  • 第一次启动,生成DKIM_KEY:

    docker exec -it mailserver setup config dkim

    然后在/data/mailserver/config/opendkim/keys/yacloud.net目录下查看mail.txt,这个文件的内容将用于DNS中DKIM配置

  • 重启mailserver服务,查看服务运行情况,正常情况下会监听:25、80、465、993端口

Step 5.配置WAF,使mail.yacloud.net能访问80端口;

Step 6.阿里云DNS配置

  • mail.yacloud.net A 125.64.33.83
  • @ MX mail.yacloud.net|10
  • @ TXT v=spf1 ip4:125.64.33.83 ~all
  • mail._domainkey TXT 【Step 4中生成的DKIM信息】
  • _dmarc TXT v=DMARC1; p=none; rua=mailto:szgs@yacloud.net; ruf=mailto:szgs@yacloud.net

Step 7.反向解析

雅云不提供递归域名解析服务,正在向上级运营商(电信)申请该项服务。