其实现在关于如何避免套了CDN的服务器发送邮件导致IP泄露的方案很多,最直接的方式就是用各种邮件服务商提供的服务来发邮件,邮件接收方查不到你的服务器IP,但邮件服务商可以,所以如果想进一步隐藏IP,可以用Cloudflare Worker来充当一个邮件服务器(实际上算是Serverless),所需成本只有一个域名(Cloudflare上面几美元一个),搭配Cloudflare的各种免费存储和日志功能,还要啥独立邮件服务器
这里的邮件服务以Mailgun为例,首先注册一个Mailgun账号

激活账号后,在左侧工具栏找到Sending,然后New Domain,添加你的域名

接着需要在域名设置下生成一个Sending key,用于调用发送邮件API时的身份验证

完事之后在Domain Settings里面可以看到需要添加的DNS记录

把上面的内容都添加到Cloudflare的域名下的DNS记录


如果你用的是域名下的子域名的话,别忘了为子域名本身加DNS记录

至此其实可以直接调用Mailgun的API发送邮件了,不过这里我们再加一层Cloudflare Worker
新建一个Worker,以Hello World为模板

点击编辑代码,直接在页面内编辑Worker的代码,不需要用wrangler那么麻烦

这里贴出一份Claude写的代码,注意由于Mailgun我选的是欧洲区,所以Mailgun的域名里面带eu:
export default {
async fetch(request, env, ctx) {
if (request.method !== 'POST') {
return new Response('Method not allowed', { status: 405 });
}
// CORS
const corsHeaders = {
'Access-Control-Allow-Origin': '*', // 可以改成你的实际域名
'Access-Control-Allow-Methods': 'POST',
'Access-Control-Allow-Headers': 'Content-Type, Authorization',
};
if (request.method === 'OPTIONS') {
return new Response(null, { headers: corsHeaders });
}
try {
const emailData = await request.json();
if (!emailData.to || !emailData.subject || !emailData.content) {
return new Response(JSON.stringify({
success: false,
error: 'Missing required fields: to, subject, content'
}), {
status: 400,
headers: { 'Content-Type': 'application/json', ...corsHeaders }
});
}
const authKey = request.headers.get('Authorization');
if (!authKey || authKey !== env.AUTH_SECRET) {
return new Response(JSON.stringify({
success: false,
error: 'Missing or invalid Authorization header'
}), {
status: 401,
headers: { 'Content-Type': 'application/json', ...corsHeaders }
});
}
const mailgunDomain = env.MAILGUN_DOMAIN;
const mailgunApiKey = env.MAILGUN_API_KEY;
const mailgunUrl = `https://api.eu.mailgun.net/v3/${mailgunDomain}/messages`;
const formData = new FormData();
formData.append('from', emailData.from || `${env.FROM_NAME || 'Store Notification'} <noreply@${mailgunDomain}>`);
formData.append('to', emailData.to);
formData.append('subject', emailData.subject);
if (emailData.html) {
formData.append('html', emailData.html);
}
if (emailData.text || emailData.content) {
formData.append('text', emailData.text || emailData.content);
}
if (emailData.cc) formData.append('cc', emailData.cc);
if (emailData.bcc) formData.append('bcc', emailData.bcc);
if (emailData.reply_to) formData.append('h:Reply-To', emailData.reply_to);
formData.append('o:tracking', 'true');
formData.append('o:tag', emailData.tag || 'store-notification');
const mailgunResponse = await fetch(mailgunUrl, {
method: 'POST',
headers: {
'Authorization': `Basic ${btoa(`api:${mailgunApiKey}`)}`
},
body: formData
});
const mailgunResult = await mailgunResponse.json();
if (mailgunResponse.ok) {
return new Response(JSON.stringify({
success: true,
message: 'Email sent successfully',
mailgun_id: mailgunResult.id,
timestamp: new Date().toISOString()
}), {
status: 200,
headers: { 'Content-Type': 'application/json', ...corsHeaders }
});
} else {
console.error('Mailgun error:', mailgunResult);
return new Response(JSON.stringify({
success: false,
error: 'Failed to send email',
details: mailgunResult.message || 'Unknown Mailgun error'
}), {
status: 500,
headers: { 'Content-Type': 'application/json', ...corsHeaders }
});
}
} catch (error) {
console.error('Worker error:', error);
return new Response(JSON.stringify({
success: false,
error: 'Internal server error',
details: error.message
}), {
status: 500,
headers: { 'Content-Type': 'application/json', ...corsHeaders }
});
}
}
};
代码中用了四个环境变量,AUTH_SECRET 相当于调用这个Worker时需要提供的密码,FROM_NAME 和MAILGUN_DOMAIN 使用你的域名,MAILGUN_API_KEY 则是前面创建的Mailgun的Sending key
下一步就是在Worker的设置中添加这四个变量

最后不要忘了添加worker路由,把域名跟worker绑定

用以下命令测试一下worker:

很快就收到了

Worker再搭配Cloudflare的日志和存储功能其实能搭建一个相当好用的邮件服务器,不过这里就不介绍了
4324

被折叠的 条评论
为什么被折叠?



