自建邮件服务器踩坑实录
0 条评论在 Debian 12 + Docker + FRP 环境下,用 本地自签名证书 打造一台可 双向收发外网邮件 的个人/小团队邮件服务器。
全程无 Let’s Encrypt,5 分钟上线,5 分钟排坑。
| 组件 | 说明 |
|---|---|
| 宿主机 | 内网 PC(192.168.100.9) |
| 外网入口 | FRP → 101.43.11.156:25/587/993… |
| 外发 IP | 36.163.145.138(NAT) |
| 域名 | owin.work |
| 镜像 | mailserver/docker-mailserver:latest |
2 一键部署流程
# 2.1 创建持久目录
mkdir -p {config,maildata,maillogs}
mkdir -p config/ssl/demoCA
# 2.2 手动生成自签名证书
mkdir -p config/ssl
openssl req -x509 -newkey rsa:4096 -nodes \
-keyout config/ssl/mail.owin.work-key.pem \
-out config/ssl/mail.owin.work-cert.pem \
-days 365 -subj "/CN=mail.owin.work"
touch config/ssl/demoCA/cacert.pem # 占位文件
# 2.3 启动容器(映射全部端口)
docker run -d \
--name mailserver \
--hostname mail.owin.work \
--restart=always \
-e TZ=Asia/Shanghai \
-e SSL_TYPE=manual \
-e SSL_CERT_PATH=/tmp/docker-mailserver/ssl/mail.owin.work-cert.pem \
-e SSL_KEY_PATH=/tmp/docker-mailserver/ssl/mail.owin.work-key.pem \
-e ENABLE_CLAMAV=0 \
-e ENABLE_FAIL2BAN=0 \
-p 25:25 -p 143:143 -p 465:465 -p 587:587 \
-p 993:993 -p 995:995 -p 110:110 -p 4190:4190 \
-v "$PWD/config:/tmp/docker-mailserver" \
-v "$PWD/maildata:/var/mail" \
-v "$PWD/maillogs:/var/log/mail" \
mailserver/docker-mailserver:latest
3 账号管理
# 新增
docker exec mailserver setup email add user@owin.work 密码
# 列表
docker exec mailserver setup email list
# 删除
docker exec mailserver setup email del user@owin.work
4 DKIM(降垃圾箱必备)
# 生成密钥
docker exec mailserver setup config dkim
# 复制 TXT 记录
docker exec mailserver cat /tmp/docker-mailserver/opendkim/keys/owin.work/mail.txt
DNS 加一条 TXT:
主机名: mail._domainkey
值: v=DKIM1; h=sha256; k=rsa; p=MIIBIjANBgkq…(整段)
TTL: 600
5 DNS 总览
| 记录 | 主机名 | 值 | TTL |
|---|---|---|---|
| A | mail.owin.work | 101.43.11.15 | 600 |
| TXT | @ | v=spf1 ip4:36.16.15.138 ~all |
600 |
| TXT | mail._domainkey | DKIM 公钥 | 600 |
| MX | @ | mail.owin.work 10 | 600 |
6 客户端配置
| 协议 | 服务器 | 端口 | 加密 | 用户名 |
|---|---|---|---|---|
| SMTP | mail.owin.work | 587 | STARTTLS | user@owin.work |
| IMAP | mail.owin.work | 993 | SSL | user@owin.work |
7 关闭入站 SPF 检查(避免 回信被拒)
docker-mailserver 默认启用 policyd-spf,会把外部来信(如 163)当外网 IP 做 SPF 比对,导致误拒。
一键关闭即可:
docker exec -it mailserver bash -c \
"postconf -e 'policyd-spf_time_limit = 3600' && \
postconf -e 'smtpd_recipient_restrictions = permit_mynetworks, permit_sasl_authenticated, reject_unauth_destination' && \
postfix reload"
8 一键重启脚本(保存为 restart.sh)
#!/bin/bash
docker rm -f mailserver
docker run -d \
--name mailserver \
--hostname mail.owin.work \
--restart=always \
-e TZ=Asia/Shanghai \
-e SSL_TYPE=manual \
-e SSL_CERT_PATH=/tmp/docker-mailserver/ssl/mail.owin.work-cert.pem \
-e SSL_KEY_PATH=/tmp/docker-mailserver/ssl/mail.owin.work-key.pem \
-e ENABLE_CLAMAV=0 \
-e ENABLE_FAIL2BAN=0 \
-p 25:25 -p 143:143 -p 465:465 -p 587:587 \
-p 993:993 -p 995:995 -p 110:110 -p 4190:4190 \
-v "$PWD/config:/tmp/docker-mailserver" \
-v "$PWD/maildata:/var/mail" \
-v "$PWD/maillogs:/var/log/mail" \
mailserver/docker-mailserver:latest
保存后 chmod +x restart.sh,随时一键重建。
9 踩坑 & 解决一览
| 阶段 | 现象 | 原因 | 解决 |
|---|---|---|---|
| 发信 | 550 SPF | 外发 IP≠SPF | TXT 写真实外发 IP |
| 收信 | 550 SPF | 入站 SPF 误拒 | 关闭 policyd-spf |
| 证书 | 530 STARTTLS | 证书缺失 | 本地自签名 + SSL_TYPE=manual |
| 账号 | 535 Auth | 未创建用户 | setup email add |
| DKIM | 550 Content | 无签名 | 加 DKIM TXT |
10 验证
发信:Foxmail → 163 → 日志出现 250 OK
收信:163 → 你的服务器 → Foxmail 实时收到
邮件服务器 双向收发完成!
证书对齐
进入持久卷目录
cd config/ssl
建立软链接(不改原文件,只让内部路径对齐)
ln -sf mail.owin.work-cert.pem cert.pem
ln -sf mail.owin.work-key.pem key.pem
重启容器让脚本重新加载证书
docker restart mailserver
