Maddy 是一款用 Go 语言开发的邮件服务器,部署方便,资源占用少,是一款适合个人使用的邮箱服务器。
在我的 CloudCone 1C1G 机 docker 搭建后查看容器,CPU 使用 0.03%,内存使用 20M,所以 1C1G 跑起来毫无压力。
准备
- 一台 VPS,支持开启 25 (
telnet smtp.qq.com 25
) 端口和 rDNS - 一个域名,支持管理 A/AAAA 记录、MX 记录、TXT 记录等
- 邮箱域名的证书和密钥(使用 Certbot 申请)
安装 docker
docker-compose.yml 的内容如下
version: "3.8"
services:
maddy:
image: foxcpp/maddy:0.8.1
container_name: maddy
restart: always
ports:
- 25:25
- 143:143
- 587:587
- 465:465
- 993:993
volumes:
- ${APP_CONF}/maddy:/data
- ${APP_CONF}/certbot/config/live/mail.example.com/fullchain.pem:/data/local_certs/cert.pem:ro
- ${APP_CONF}/certbot/config/live/mail.example.com/privkey.pem:/data/local_certs/key.pem:ro
environment:
- TZ=Asia/Shanghai
- MADDY_HOSTNAME=mail.example.com
- MADDY_DOMAIN=example.com
# VARIABLE=value #comment
WEB_ROOT=/var/www/html
APP_CONF=/opt/docker/data
APP_DATA=/opt/appdata
启动后开放的端口及作用
Port | Usage | Security | Note |
---|---|---|---|
25 | SMTP MTA | PLAIN/TLS | 用于接收和发送邮件 |
|
IMAP | STARTTLS | 收信,tls://imap.example.com:143 |
993 | IMAP | TLS | ssl://imap.example.com:993 |
|
SMTP MTA | STARTTLS | 发信,tls://smtp.example.com:587 |
465 | SMTP Submission | TLS | ssl://smtp.example.com:465 |
TLS 通常比 SSL 更安全,且是现代通信中偏好的选项。
使用 ssl://
,意味着将以 SSL 直接加密整个连接。
使用 tls://
,则通常是在初始连接时使用普通的明文连接,然后通过 STARTTLS 命令将其升级为加密连接。
建议尽可能使用 tls://
,因其安全性更高且是当前的标准。如果您的邮件服务器支持 TLS,通常优先考虑它。
获取 tls 证书
安装 Certbot
# Ubuntu/Debian
sudo apt-get install certbot
# Centos
sudo yum install certbot
获取 tls 证书:
sudo certbot certonly --standalone -d mail.example.com
按照提示操作,将获得证书和私钥,存储在 /etc/letsencrypt/live/mail.example.com/
目录下。
配置 maddy
# https://github.com/foxcpp/maddy/blob/master/maddy.conf
配置 nginx(可选)
启动 maddy
docker compose up -d
创建 maddy 用户
# 进入容器
docker exec -it maddy /bin/sh
# 创建邮箱
# maddy -h
maddy creds create [email protected]
maddy imap-acct create [email protected]
maddy creds password –password PASSWORD [email protected]
maddy creds list
maddy imap-acct list
# 密码生成器
maddy hash
# # 本地凭据和 IMAP 存储账户
# 本地凭据(用户名和密码)通常用于用户身份验证。
# IMAP 账户,主要涉及邮件存储和操作,关联到邮件数据的实际存储位置,通常对应于用户的邮箱。
# 本地凭据和 IMAP 存储账户通过用户名来关联:
# 用户登录:当用户尝试通过 IMAP 客户端登录时,Maddy 首先会检查本地凭据(通过 maddy creds 管理)来验证用户名和密码。
# 账户操作:一旦用户凭据验证通过,Maddy 会根据用户名从 IMAP 存储账户配置(通过 maddy imap-acct 管理)来获取相应的邮件# 数据存储信息。
获取 DKIM 的公钥
/ # cat data/dkim_keys/*.dns
v=DKIM1; k=rsa; p=MIIBIjANBgkqhkiG...zAuhVJKPYUPTnJ3yTIzi4R2XbzfwIDAQAB
复制保存,将在设置 DNS 记录使用
设置 DNS 记录
- A 记录,将邮箱域名(
mail.example.com
)指向你的服务器 IP 地址 - MX(Mail Exchange)记录指向你的邮件服务器地址,确保可以接收邮件。将邮件域(
[email protected]
,其中example.com
就代表邮件域)指向第一步的邮箱域名,优先级默认为 10(数字越低,优先级越高) - PTR 记录(或者叫 rDNS),可以通过 ip 地址反向解析出邮箱域名。不设置也没关系,但是会被某些服务器标记为垃圾邮件
- SPF(Sender Policy Framework)是用来指定哪些服务器有权限代表你的域名发送邮件
- DMARC(Domain-based Message Authentication, Reporting, and Conformance) 用于指定邮件的处理策略,以及接收未通过验证的邮件报告
- DKIM(DomainKeys Identified Mail) 用于对邮件进行数字签名,验证邮件是否被篡改
DNS 验证
# install dig
apt-get install dnsutils
# 验证 MX 记录
$ dig +short MX example.com
mail.example.com
# 验证 A 记录
$ dig +short A mail.example.com
71.2.3.1
# 验证 rDNS(PTR) 记录
$ dig +short -x 71.2.3.1
mail.example.com
以 mail.example.com
为邮件服务器的域名为例
序号 | 名称 | 类型 | 内容 | 说明 |
---|---|---|---|---|
1 | A | 71.2.3.1 |
A | |
2 | AAAA | 2607:b102::e |
||
3 | smtp | CNAME | mail.example.com |
CNAME |
4 | imap | CNAME | mail.example.com |
|
5 | @ | MX | mail.example.com |
MX |
6 | @ | TXT | v=spf1 mx ~all |
SPF |
7 | TXT | v=spf1 mx ~all |
||
8 | _dmarc | TXT | v=DMARC1; p=quarantine; ruf=mailto:[email protected] |
DMARC |
9 | default._domainkey | TXT | v=DKIM1; k=rsa; p=MIIBIjANBgkqhkiG...zAuhVJKPYUPTnJ3yTIzi4R2XbzfwIDAQAB |
DKIM |
最终,我在 cloudflare 新添加的 DNS 记录如下
测试检查
测试自建邮件服务器 mail.example.com
,邮箱 [email protected]
收发邮件情况。
我们使用 Mailspring —— 一个支持 Mac、Linux 和 Windows 的、开源的,邮件客户端来操作。
使用 [email protected]
连接后
- 往自己的 Gmail 邮箱发邮件,检查能否收到邮件。
- Gmail 收到邮件后,在 Gmail 邮箱后回复,检查在邮件客户端 Mailspring 能否收到邮件。
如上图,可以正常收发邮件。
最后,mail-tester 测试下得分 9.5,这是未针对内容调整,调整后估计分值可以加高。
邮件通知到 Telegram(可选)
在 maddy.conf 中,找到 storage.imapsql local_mailboxes,添加一个 imap_filter :
storage.imapsql local_mailboxes {
driver sqlite3
dsn imapsql.db
imap_filter {
command /data/script/notice.sh {sender} {original_rcpt_to} {subject}
}
}
邮件通知的脚本内容:
邮件 Web 客户端(可选)
使用 web 管理邮件,进行收发邮件。
version: "3.8"
services:
roundcube:
image: roundcube/roundcubemail:1.6.10-apache
container_name: roundcube
restart: unless-stopped
volumes:
#- ${WEB_ROOT}/roundcube:/var/www/html
- ${WEB_ROOT}/roundcube/opt:/opt
ports:
- 127.0.0.1:8080:80
environment:
- ROUNDCUBEMAIL_DB_TYPE=mysql
- ROUNDCUBEMAIL_DB_HOST=x.x.x.x
- ROUNDCUBEMAIL_DB_PORT=3306
- ROUNDCUBEMAIL_DB_USER=root
- ROUNDCUBEMAIL_DB_PASSWORD=xxxx
- ROUNDCUBEMAIL_DB_NAME=app_roundcube
- ROUNDCUBEMAIL_SKIN=elastic
- ROUNDCUBEMAIL_DEFAULT_HOST=ssl://imap.196000.xyz
- ROUNDCUBEMAIL_DEFAULT_PORT=993
- ROUNDCUBEMAIL_SMTP_SERVER=ssl://smtp.196000.xyz
- ROUNDCUBEMAIL_SMTP_PORT=465
# VARIABLE=value #comment
WEB_ROOT=/var/www/html
APP_CONF=/opt/docker/data
APP_DATA=/opt/appdata
使用前面创建的账号 [email protected]
和密码登入即可。
安全事项
- 推荐运行启用 DNSSEC 验证的自己的 DNS 解析器。
- 建议使用 MTA-STS 策略,使得发信服务器在发送电子邮件到接收服务器时,强制使用经过身份验证的 TLS 连接,以防止主动的网络攻击。
- 推荐设置 TLSA (DANE) 记录。
- 注释 maddy 常用端口,只通过 roundcubemail 提供的网页端访问。
在线工具
- 垃圾邮件匹配度检测 https://www.mail-tester.com/?lang=zh
- MxtoolBox,查询 MX 记录,DKIM 等用于检查是否配置正确 https://mxtoolbox.com/SuperTool.aspx