第零步:确认 DNS A 记录
请确保您已经为 mail.xxx.com
设置了正确的 A 记录:
类型 (Type):
A
名称 (Name):
mail
内容 (Content):
89.183.126.152
类型 (Type):
A
名称 (Name):
*
内容 (Content):
89.183.126.152
类型 (Type):
A
名称 (Name):
@
内容 (Content):
89.183.126.152
类型 (Type):
mx
名称 (Name):
xxx.com
内容 (Content):
89.183.126.152
第一步:服务器基础环境准备
登录到您重装好的服务器,执行以下操作。
更新系统软件包:
apt updateapt upgrade -y
2.安装 Python 和相关工具:
apt install python3 python3-pip python3-venv -y
第二步:安装并运行 MailHog
MailHog 将作为我们独立的邮件接收服务。
下载 MailHog:
# 切换到 Home 目录cd ~
# 从 GitHub 下载 MailHog 的二进制文件
wget https://github.com/mailhog/MailHog/releases/download/v1.0.1/MailHog_linux_amd64
赋予执行权限:
chmod +x MailHog_linux_amd64
3.让 MailHog 在后台运行:
nohup ./MailHog_linux_amd64 > mailhog.log 2>&1 &
第三步:配置网络和防火墙
这是连接外部世界和 MailHog 的关键。
配置 VPS 提供商的防火墙 (最重要) 请登录到您的 VPS 提供商的管理后台网页,找到这台服务器的网络安全组(Security Group),并添加入站规则(Inbound Rules)来放行以下三个端口的 TCP 流量:
25
(SMTP,接收邮件用)8025
(MailHog 的网页界面和 API)2099
(我们自己的 Python API)
在服务器内部设置端口转发 由于 MailHog 监听
1025
端口,我们需要将标准的邮件端口25
转发过去。
iptables -t nat -A PREROUTING -p tcp --dport 25 -j REDIRECT --to-port 1025
第四步:部署 Python API 服务
这个服务将作为我们读取邮件的接口。
创建项目目录和虚拟环境:
Bash
mkdir -p /opt/mail_api cd /opt/mail_api python3 -m venv venv
激活虚拟环境并安装依赖包:
Bash
source venv/bin/activate # 注意:这次我们一次性把所有需要的包装好 pip install Flask Gunicorn requests
创建 API 脚本:
Bash
nano mail_reader.py
将下面的全部代码粘贴进去,然后按
Ctrl+X
,Y
,Enter
保存退出。Python
# -*- coding: utf-8 -*- from flask import Flask, request, Response import requests import re app = Flask(__name__) MAILHOG_API = "http://localhost:8025/api/v2/messages" VALID_TOKEN = "2088" @app.route("/Mail") def get_mail(): token = request.args.get("token") # 这现在是我们要精确查找的目标邮箱地址 mail_address_to_find = request.args.get("mail") if token != VALID_TOKEN: return "❌ 无效的 token!", 401 if not mail_address_to_find: return "❌ 参数错误:请提供需要查找的 mail 地址。", 400 try: # 获取最新的50封邮件,增加找到目标邮件的概率 response = requests.get(MAILHOG_API, params={'limit': 50}) response.raise_for_status() data = response.json() messages = data.get('items', []) if not messages: return "❌ MailHog 中没有任何邮件。", 404 subject_expected_1 = "Verify your email address" subject_expected_2 = "验证您的电子邮件地址。" # 遍历所有近期邮件,寻找收件人匹配的那一封 for msg in messages: headers = msg.get('Content', {}).get('Headers', {}) # 提取收件人地址 # To 字段是一个列表,我们取第一个。可能包含 "Name <email@addr>" 格式 to_header_list = headers.get('To', []) if not to_header_list: continue recipient_in_mailhog = to_header_list[0] # 检查收件人地址是否匹配 if mail_address_to_find not in recipient_in_mailhog: continue # 如果收件人不匹配,跳过这封邮件 # --- 收件人匹配成功后,才开始检查主题 --- subject = headers.get('Subject', [""])[0] if subject_expected_1.lower() not in subject.lower() and subject_expected_2 not in subject: continue # 如果主题不匹配,也跳过 # --- 收件人和主题都匹配成功,才开始提取验证码 --- body = msg.get('Content', {}).get('Body', "") match = re.search(r"\b(\d{6})\b", body) if match: # 找到了!删除邮件并返回内容 #msg_id = msg.get('ID') #if msg_id: #try: #requests.delete(f"http://localhost:8025/api/v1/messages/{msg_id}") #except requests.RequestException: #pass return Response(body, mimetype="text/html; charset=utf-8") # 如果循环结束了还没找到,说明没有符合所有条件的邮件 return f"❌ 未找到发送给 <{mail_address_to_find}> 且主题为“{subject_expected_1}”或“{subject_expected_2}”并包含验证码的邮件。", 404 except requests.RequestException as e: return f"❌ 请求 MailHog API 出错:{e}", 500 except Exception as e: return f"❌ 处理邮件时发生未知错误:{e}", 500 if __name__ == "__main__": app.run(host="0.0.0.0", port=2099)
第五步:启动服务并进行最终测试
启动您的 Python API 服务: 确保您还在 /opt/mail_api
目录下,并且虚拟环境 (venv)
已激活。
Bash
gunicorn --workers 2 --bind 0.0.0.0:2099 mail_reader:app
保持这个终端窗口在前台运行,以便观察日志。
发送测试邮件: 从您的个人邮箱,发送一封测试邮件到
test@mail.xxx.com
。主题:
Verify your email address
内容: 包含一个6位数字,例如
Your code is 987654
。
调用 API: 等待半分钟,然后在您的本地电脑上,打开终端并执行
curl
命令(注意使用您的新域名和真实IP):Bash
curl "http://89.128.116.153:2099/Mail?token=2088&mail=test@mail.xxx.com"