本文适用于:需要自建域名邮箱来注册平台账号、接收验证码的场景。全程命令行, 不用写 Python 脚本也能收码。

只讲收信。 对外发信要额外处理 rDNS、DKIM、DMARC 和 IP 信誉, 自建服务器发出去的信大概率进垃圾箱,那是另一件事。


一、背景说明

很多平台注册账号时会要求填写邮箱地址并接收验证码。为了批量注册或控制邮箱来源,一些用户希望自建域名邮箱系统,从而:

  • 自己控制域名和邮箱地址
  • 本地接收邮件,免费无限用
  • 配合脚本自动抽取验证码

二、工作环境准备

1. 需要的条件

项目 说明
一台 VPS Ubuntu 20.04+,25 端口必须能入站。多数云厂商默认封 25,要向主机商申请解封
一个可配置 DNS 的域名 如 mail.example.com

2. 安装必要软件

apt update
apt install postfix dovecot-core dovecot-imapd -y
  • postfix = SMTP 邮件服务器,用于接收邮件
  • dovecot = IMAP 邮箱读取服务器,允许脚本/网页读邮件

三、配置 DNS 记录

到域名控制面板(如 Cloudflare、阿里云、Namecheap)添加以下 DNS 记录:

类型 主机记录 值
A mail VPS IP
MX @ mail.example.com (10)
TXT @ v=spf1 mx ~all

说明:MX 是接收邮件的域名服务器,SPF 是为了防止邮件被伪造,非必但建议配置


四、配置 Postfix + Dovecot

配置 Postfix

编辑 /etc/postfix/main.cf ,加入或确保:

myhostname = mail.example.com
mydestination = $myhostname, localhost.$mydomain, localhost, example.com
home_mailbox = Maildir/
smtpd_tls_cert_file=/etc/ssl/certs/ssl-cert-snakeoil.pem
smtpd_tls_key_file=/etc/ssl/private/ssl-cert-snakeoil.key
smtpd_use_tls=yes
inet_interfaces = all

几个关键项的含义:

配置项 作用 写错的后果
myhostname 这台机器对外自称的名字 对方服务器可能拒收
mydestination 哪些域名的信算「本机的」并投递到本地 域名不在这个列表里,Postfix 会当成中转请求拒掉
home_mailbox = Maildir/ 用 Maildir 格式,一封信一个文件 默认是 mbox(整个邮箱一个大文件),后面按文件取信的命令全都用不了
inet_interfaces = all 监听所有网卡 默认只听 localhost,外面的信根本进不来

ssl-cert-snakeoil 是系统自带的自签证书,用于收信足够了;要用正式证书就换成 Let’s Encrypt 签发的路径。

配置 Dovecot

编辑 /etc/dovecot/conf.d/10-mail.conf:

mail_location = maildir:~/Maildir

这一行必须和 Postfix 的 home_mailbox 对上。 Postfix 按 Maildir 格式写信、 Dovecot 却按 mbox 格式找,结果就是「信收到了,但客户端里一封都看不到」—— 两边都不报错,最难查的就是这种。


五、创建邮箱用户

每个 Linux 用户 = 一个邮箱地址

adduser code   # 即创建 code@example.com

重启服务:

systemctl restart postfix dovecot

六、测试接收

  1. 用你的 Gmail/QQ/163,给 code@example.com 发一封邮件
  2. 在服务器上查看
ls /home/code/Maildir/new
cat /home/code/Maildir/new/文件名
  1. 接收成功,表明邮箱配置已成功

七、命令行接收验证码

提取最新邮件:

cd /home/code/Maildir/new
latest=$(ls -t | head -n1)
cat "$latest"

只看正文:

sed -n '/^$/,$p' "$latest"

提取6位数验证码:

sed -n '/^$/,$p' "$latest" | grep -oE '\b[0-9]{6}\b'

八、收不到信时按这个顺序查

现象 先查什么
发过去直接退信 MX 记录解析对不对:dig MX example.com
没退信也没收到 25 端口通不通:从别的机器 telnet 你的IP 25
Postfix 收到了但目录是空的 mail_location 和 home_mailbox 格式是否一致
都正常但就是没有 tail -f /var/log/mail.log,Postfix 的日志写得很清楚

小结

环节 用什么
收信 Postfix(SMTP)
读信 Dovecot(IMAP)
存储格式 Maildir,一封信一个文件,落在 /home/用户名/Maildir/new/
DNS A + MX + SPF
抽验证码 sed 取正文 + grep -oE 匹配 6 位数字

走完这一遍就有了一套自己可控的收信系统:接验证码、配合脚本自动注册、把抽到的码 推给 API 都可以。

一台服务器要接多个域名的话,不再靠系统用户,改用虚拟邮箱——参考 Postfix 官方的 VIRTUAL_README。

附录:用到的 Shell 命令

本节整理了一些在邮件接收流程中用到的常见命令及参数说明,方便读者理解并活用。

命令 示例 说明
ls -t ls -t | head -n1 -t 表示按修改时间排序,配合 head -n1 获取最新邮件文件名
head -n1 head -n1 获取输出的第一行(如最新文件名)
cat cat 文件名 查看文件全部内容,包括邮件头和正文
sed -n '/^$/,$p' sed -n '/^$/,$p' "$latest" sed -n 不自动打印;/^$/,$ 表示从空行开始到文件结尾;p 表示打印匹配的部分;用于提取邮件正文
grep -oE '\b[0-9]{6}\b' grep -oE '\b[0-9]{6}\b' -o 只输出匹配内容,-E 使用扩展正则;\b[0-9]{6}\b 匹配完整的 6 位数字验证码
adduser 用户名 adduser code 创建 Linux 系统用户,对应邮箱 code@example.com