退信地址

电子邮件和安全
无法传递电子邮件时用于非传递报告(退回)的返回地址。
← 返回词汇表

什么是退信地址?

退信地址也称 Return-Path 或信封发件人,是在邮件无法投递时接收非投递报告(NDR)的邮箱地址。它与收件人可见的“From”地址分开,仅用于接收自动投递通知。

退信地址如何工作

邮件传输会使用两组地址:

标头 From(收件人可见):
From: John Doe <[email protected]>
信封 From(SMTP 层使用,用于退信):
MAIL FROM: <[email protected]>

投递失败时,收件服务器会把退信发送给信封发件人,而不是标头 From 地址。

SMTP 会话示例

Client: MAIL FROM: <[email protected]>

Server: 250 OK

Client: RCPT TO: <[email protected]>

Server: 550 No such user here

Client: QUIT

# Later, server sends bounce to [email protected]

邮件退信的类型

硬退信

永久性投递失败:

处理方式:立即从邮件列表中移除该地址。

软退信

暂时性失败:

处理方式:重试投递,多次软退信后再移除地址。

封锁退信

与送达性有关的问题:

处理方式:调查发件人信誉和身份验证配置。

退信地址配置

在邮件标头中设置 Return-Path

PHP(mail 函数)
$to = "[email protected]";

$subject = "Test Email";

$message = "Email body";

$headers = "From: [email protected]\r\n";

$headers .= "Return-Path: [email protected]\r\n";

mail($to, $subject, $message, $headers, "-f [email protected]");

PHPMailer
$mail = new PHPMailer();

$mail->From = "[email protected]";

$mail->Sender = "[email protected]"; // Return path

$mail->addAddress("[email protected]");

$mail->Subject = "Test Email";

$mail->send();

Postfix(SMTP)
# /etc/postfix/main.cf

sender_canonical_maps = hash:/etc/postfix/sender_canonical

# /etc/postfix/sender_canonical

@example.com [email protected]

# Apply changes

postmap /etc/postfix/sender_canonical

systemctl reload postfix

专用退信处理服务

大多数邮件服务商都提供退信管理:

Amazon SES
{

"Message": {

"Subject": "Test",

"From": "[email protected]",

"ReturnPath": "[email protected]"

}

}

SendGrid
const msg = {

to: '[email protected]',

from: '[email protected]',

replyTo: '[email protected]',

return_path: '[email protected]',

subject: 'Test Email',

text: 'Email body'

};

退信地址的命名约定

子域名方式

[email protected]           # General bounces

[email protected] # No-reply emails

[email protected] # Returns/receipts

按活动区分

按营销活动跟踪退信:

[email protected]

[email protected]

[email protected]

可变信封返回路径(VERP)

把收件人编码进退信地址:

Sending to: [email protected]

Return path: [email protected]

When bounce arrives at bounces+*, parse to identify failed recipient

处理退信邮件

自动解析退信

Python 示例
import email

from email import policy

def parse_bounce(raw_email):

msg = email.message_from_string(raw_email, policy=policy.default)

# Extract bounce type

if "550" in msg.get_payload():

return "hard_bounce"

elif "452" in msg.get_payload():

return "soft_bounce"

# Extract failed recipient

for part in msg.walk():

if part.get_content_type() == "message/delivery-status":

# Parse delivery status

pass

return bounce_info

# Integrate with mailing list to remove hard bounces

基于 Webhook 的退信处理

现代 ESP 提供 Webhook:

SendGrid Webhook
POST /bounce-webhook

{

"email": "[email protected]",

"event": "bounce",

"reason": "550 5.1.1 User unknown",

"type": "blocked",

"status": "5.0.0"

}

处理方式:更新数据库,将邮件标记为已退信。

SPF 与退信地址

SPF 检查信封发件人(退信地址),而不是 From 标头:

Message:

From: [email protected] (header)

Return-Path: [email protected] (envelope)

SPF Check:

Queries: mail-server.com TXT record (not example.com)

Must include sending IP in mail-server.com's SPF

退信域名的 SPF 配置

bounces.example.com.    IN    TXT    "v=spf1 include:_spf.sendgrid.net ~all"

确保退信子域名具有适用于发信基础设施的 SPF 记录。

退信地址最佳实践

使用专用退信地址

不要使用主邮箱接收退信:

# Bad

Return-Path: [email protected]

# Good

Return-Path: [email protected]

监控退信率

退信率评估处理方式
< 2%健康继续监控
2-5%需关注审查邮件列表质量
5-10%较差立即清理列表
> 10%严重送达性面临风险

实施退信处理

自动移除硬退信:

-- Mark emails with hard bounces

UPDATE mailing_list

SET status = 'bounced', bounce_count = bounce_count + 1

WHERE email IN (SELECT email FROM recent_hard_bounces);

-- Remove after 3 hard bounces

DELETE FROM mailing_list

WHERE bounce_count >= 3;

分开处理事务邮件和营销邮件退信

[email protected]  # Order confirmations, receipts

[email protected] # Newsletters, campaigns

两类邮件的退信率预期不同。

设置自动退信处理

Cron 任务示例
#!/bin/bash

# Process bounces every hour

# Fetch bounces from IMAP

fetchmail -c /etc/fetchmailrc

# Parse and update database

/usr/local/bin/process-bounces.py

# Clean up processed bounces older than 30 days

find /var/mail/bounces -mtime +30 -delete

反向散射与退信安全

反向散射问题

服务器接受垃圾邮件后再发送退信,就可能把邮件发给伪造的地址:

1. Spammer sends email with forged From

2. Your server accepts it

3. Your server realizes it's spam/invalid

4. Your server bounces to forged From address

5. Innocent party receives bounce (backscatter)

解决方案:在 SMTP 阶段拒绝邮件,不要先接受再退信:
# Postfix: Reject unknown users at SMTP time

smtpd_recipient_restrictions = reject_unauth_destination

local_recipient_maps = hash:/etc/postfix/local_recipients

伪造退信

攻击者可以伪造退信来:

验证方式

常见退信场景

场景 1:所有邮件都退信

原因:SPF 失败、IP 被列入黑名单或服务器信誉不佳 检查:SPF 记录、发件 IP 信誉和 DMARC 报告

场景 2:收不到退信

原因:退信地址配置错误或地址不存在 检查:退信域名的 MX 记录和邮箱是否存在

场景 3:软退信率很高

原因:收件服务器过载、速率限制或邮件过大 检查:发送速率、邮件大小和收件服务器错误

场景 4:退信循环

原因:退信地址触发自动回复,自动回复又触发另一封退信 检查:关闭退信地址上的自动回复

测试退信处理

向无效收件人发送测试邮件
# Test bounce to invalid address

swaks --to [email protected] \

--from [email protected] \

--server mx.test-domain.com

# Check if bounce arrives at [email protected]

验证退信域名的 SPF
dig bounces.example.com TXT

# Should show SPF record with authorized senders

正确管理退信地址对于维护发件人信誉、保持列表卫生和提高邮件送达率至关重要。

将知识付诸实践

使用 DomScan 的 API 检查域名可用性、健康状态等。