在本地部署信号:PowerMTA 集成
鸟
2019年8月30日
电子邮件
1 min read

关键要点
目的:本指南解释了如何将PowerMTA 5.0+与SparkPost Signals集成,以便将事件和参与数据(退信、打开、点击、垃圾邮件投诉)从本地MTAs直接流入SparkPost分析层。
核心配置:
添加enable-signals true并定义您的SparkPost ingest endpoint(https://api.sparkpost.com/api/v1/ingest/events或EU等效端点)。
使用具有“Incoming Events: Write”权限的有效API key。
指定customer-id,并可选地设置自定义跟踪域以改善投递能力。
跟踪设置:PowerMTA的Engagement Tracking会自动将打开和点击像素注入HTML邮件中。您可以使用data-msys-clicktrack="0"属性来逐链接禁用跟踪。
选择性报告:Signals可以在全球范围内启用,也可以仅限于某些VirtualMTAs、池或发件人域,以实现精细的数据控制。
测试与验证:使用Signals Integration仪表板和PowerMTA日志来确认事件摄取,并实时跟踪Health Scores、退信和参与度指标。
投递调优:
使用有意义的VirtualMTA和Job名称——这些名称直接映射到SparkPost报告中的IP Pools和Campaign IDs。
配置DKIM签名、TLS强制和适当的中继规则以防止未经授权的注入。
高级设置:本文还包括适用于FBL & out-of-band bounce handling、authenticated SMTP injection (port 587)的现成代码片段,以及用于X-Job头清理以确保兼容的Python代码。
Q&A 精华
Signals 集成实际有什么作用?
它会自动将 PowerMTA 的消息事件(注入、投递、退信、参与)上传到您的 SparkPost 帐户中,以便您可以访问健康评分、延迟报告和 Spam Trap Monitoring 等仪表板。
为什么将 Signals 与本地 MTA 集成?
许多企业出于合规原因运行自托管邮件基础设施,但仍希望使用SparkPost的分析和监控功能。Signals桥接了这个差距,而无需将邮件传输迁移到云端。
如何验证事件是否流向SparkPost?
检查 PowerMTA 日志中的
Signals: Transferred ... successfully,并在 SparkPost 的Signals → Events Search下确认事件条目。我可以使用我自己的 tracking domain 吗?
是的 — 配置一个CNAME,例如
track.mycompany.com → pmta.spgo.io(美国) 或pmta.eu.spgo.io(欧洲),然后在SparkPost中注册和验证它,以保持品牌和声誉一致性。数据隐私或磁盘使用如何?
min-free-space指令在磁盘空间不足时自动删除旧的 JSON 事件文件,防止本地堆积遥测数据。最后的“bonus feature”是什么?
一个Python regex工具 (
pmtaSafeJobID),确保活动/工作名称仅使用在PowerMTAX-Job头格式中有效的字符,用下划线替换不安全的字符。
让我们深入了解如何为 SparkPost Signals 设置 PowerMTA 的细节。
让我们深入了解为 SparkPost Signals 设置 PowerMTA 的详细信息。您需要:
一个用于运行最新版本 PowerMTA 的主机 - 可以是新机器,也可以是现有机器
一个具有“Incoming Events: Write”API 密钥权限的 SparkPost 账户 具体描述请见此处
我们将设置 PowerMTA 以将事件流传输到您的 SparkPost 账户,然后您即可使用以下功能:
首先,按照 常规 v5.0 安装说明安装(或升级)到 PowerMTA 5.0 r4 或更高版本,这些步骤都相当简单。然后我们将按以下步骤操作:
配置 PowerMTA 连接到 SparkPost Signals
设置具有自定义跟踪域的 Engagement Tracking
选择要报告给 Signals 的 PowerMTA 流量流
测试您的事件是否到达 Signals
查看如何使用在报告中显示效果良好的有意义名称。
我们还将介绍在 Signals 演示中使用的其他特定 PowerPMTA 设置方面:
FBL 事件(垃圾邮件投诉)和远程(带外)反弹
包括 DKIM 的注入配置
FBL 和 OOB 配置
VirtualMTA 设置和命名(以及这如何出现在您的 SparkPost Signals 报告中)
最后,提供一个“额外功能”,其中包含确保您的活动名称与 PowerMTA X-Job 名称约定兼容的代码。
让我们深入了解为 SparkPost Signals 设置 PowerMTA 的详细信息。您需要:
一个用于运行最新版本 PowerMTA 的主机 - 可以是新机器,也可以是现有机器
一个具有“Incoming Events: Write”API 密钥权限的 SparkPost 账户 具体描述请见此处
我们将设置 PowerMTA 以将事件流传输到您的 SparkPost 账户,然后您即可使用以下功能:
首先,按照 常规 v5.0 安装说明安装(或升级)到 PowerMTA 5.0 r4 或更高版本,这些步骤都相当简单。然后我们将按以下步骤操作:
配置 PowerMTA 连接到 SparkPost Signals
设置具有自定义跟踪域的 Engagement Tracking
选择要报告给 Signals 的 PowerMTA 流量流
测试您的事件是否到达 Signals
查看如何使用在报告中显示效果良好的有意义名称。
我们还将介绍在 Signals 演示中使用的其他特定 PowerPMTA 设置方面:
FBL 事件(垃圾邮件投诉)和远程(带外)反弹
包括 DKIM 的注入配置
FBL 和 OOB 配置
VirtualMTA 设置和命名(以及这如何出现在您的 SparkPost Signals 报告中)
最后,提供一个“额外功能”,其中包含确保您的活动名称与 PowerMTA X-Job 名称约定兼容的代码。
让我们深入了解为 SparkPost Signals 设置 PowerMTA 的详细信息。您需要:
一个用于运行最新版本 PowerMTA 的主机 - 可以是新机器,也可以是现有机器
一个具有“Incoming Events: Write”API 密钥权限的 SparkPost 账户 具体描述请见此处
我们将设置 PowerMTA 以将事件流传输到您的 SparkPost 账户,然后您即可使用以下功能:
首先,按照 常规 v5.0 安装说明安装(或升级)到 PowerMTA 5.0 r4 或更高版本,这些步骤都相当简单。然后我们将按以下步骤操作:
配置 PowerMTA 连接到 SparkPost Signals
设置具有自定义跟踪域的 Engagement Tracking
选择要报告给 Signals 的 PowerMTA 流量流
测试您的事件是否到达 Signals
查看如何使用在报告中显示效果良好的有意义名称。
我们还将介绍在 Signals 演示中使用的其他特定 PowerPMTA 设置方面:
FBL 事件(垃圾邮件投诉)和远程(带外)反弹
包括 DKIM 的注入配置
FBL 和 OOB 配置
VirtualMTA 设置和命名(以及这如何出现在您的 SparkPost Signals 报告中)
最后,提供一个“额外功能”,其中包含确保您的活动名称与 PowerMTA X-Job 名称约定兼容的代码。
配置 PowerMTA 连接器
Signals 配置在 5.0 用户指南第 10.1 节 中进行了描述。这里我们将从“用例 #2”开始,该用例启用此 PowerMTA 主机的所有流量信号,并启用 SparkPost 的参与跟踪。
# # SparkPost Signals # <signals> api-key ##my ingest API key here## upload-url https://api.sparkpost.com/api/v1/ingest/events log-verbose true min-free-space 1G engagement-tracking sparkpost # this turns on the open and click tracking in PowerMTA customer-id 123 # Your SparkPost account number here </signals> enable-signals true
这是每个属性的作用:
api-key
这是您 SparkPost 账户特有的,是您之前从 SparkPost 获得的值。
upload-url
这需要匹配您的 SparkPost API 服务地址,无论是美国还是欧洲。有关更多信息,请参见此处。常用值是:
SparkPost(美国):https://api.sparkpost.com/api/v1/ingest/events
SparkPost 欧洲: https://api.eu.sparkpost.com/api/v1/ingest/events
log-verbose
此指令是可选的,启用后,在 pmta.log 文件中提供更多信息,这在设置过程中确认一切是否正常运行时非常有用。每分钟,即使没有流量,您也会看到:
2019-07-26 11:47:57 Signals: Discovered 0 files
有了流量,您会看到类似这样的内容:
2019-07-26 11:50:57 Signals: Discovered sp1-0000000000003FBD.json 2019-07-26 11:50:57 Signals: Transferred sp1-0000000000003FBD.json successfully. 2019-07-26 11:50:57 Signals: Discovered 1 file, transferred 1 file successfully
min-free-space
这告诉 PowerMTA 在磁盘空间不足时开始删除旧 SparkPost JSON 事件文件,以腾出空间存放新文件的磁盘空间阈值。
enable-signals
这告诉 PowerMTA 上传到 Signals,通常是针对所有流量进行上传(更多信息 此处,适用于 v5.0)。如果您愿意,可以更选择性地选择上传哪些流量流。
您还可以标记特定 PowerMTA 流量以报告为属于 SparkPost 的 子账户 – 这是区分一个特定流量流与另一个流量流的方式。
engagement-tracking, customer-id
PowerMTA 的 Engagement Tracking 解决方案默认为 SparkPost 美国托管服务的跟踪域。您需要指定您的 SparkPost 数字客户 ID;以下是 找到它的说明。
tracking-domain
对于 SparkPost 欧洲账户,添加以下行:
tracking-domain pmta.eu.spgo.io # 这是 SparkPost 欧洲的终端点
自定义跟踪域
如果您希望使用自己的跟踪域(从送达能力的角度来看更好),请执行以下操作:
通过在您的 DNS 提供商处创建 CNAME 记录,创建跟踪域。这通常是顶级域的子域,例如 track.mycompany.com 。
track.mycompany.com CNAME pmta.spgo.io # if you have a SparkPost US account track.mycompany.com CNAME pmta.eu.spgo.io # if you have a SparkPost EU account
您还可以使用 HTTPS 跟踪域,尽管这更复杂(请参见 SparkPost 关于 HTTPS 跟踪域的配置步骤)。
在您的 SparkPost 帐户中注册跟踪域,并验证它。在尝试之前,请等待几分钟,以便您的 DNS 更改能够在互联网上传播,这取决于您的 DNS 提供商。
配置 PowerMTA 使用该域而不是默认域,使用以下命令:
tracking-domain yourdomain.com # 在这里填入您自己的域名
您可以通过查看邮件的内部结构(在 Gmail 中,使用右上方的菜单选择“显示原始”)来检查您的已发邮件中是否添加了“开放像素”,以及链接是否已包装。

您会注意到电子邮件 HTML 开始和结束时有开放像素。每个 HTML 链接也更改为包含指向跟踪域的 REF。

这就是让 SparkPost Signals 与 PowerMTA 的内置参与跟踪一起正常工作的全部内容。
防止特定链接在您的 html 邮件中被跟踪
您可以通过设置自定义属性 data-msys-clicktrack 为“0”来防止 PowerMTA 跟踪特定链接 :
<a href="#" data-msys-clicktrack="0">Example</a>
PowerMTA 将不会包装链接。它还将在向您的收件人传递消息之前移除该属性。
Signals 配置在 5.0 用户指南第 10.1 节 中进行了描述。这里我们将从“用例 #2”开始,该用例启用此 PowerMTA 主机的所有流量信号,并启用 SparkPost 的参与跟踪。
# # SparkPost Signals # <signals> api-key ##my ingest API key here## upload-url https://api.sparkpost.com/api/v1/ingest/events log-verbose true min-free-space 1G engagement-tracking sparkpost # this turns on the open and click tracking in PowerMTA customer-id 123 # Your SparkPost account number here </signals> enable-signals true
这是每个属性的作用:
api-key
这是您 SparkPost 账户特有的,是您之前从 SparkPost 获得的值。
upload-url
这需要匹配您的 SparkPost API 服务地址,无论是美国还是欧洲。有关更多信息,请参见此处。常用值是:
SparkPost(美国):https://api.sparkpost.com/api/v1/ingest/events
SparkPost 欧洲: https://api.eu.sparkpost.com/api/v1/ingest/events
log-verbose
此指令是可选的,启用后,在 pmta.log 文件中提供更多信息,这在设置过程中确认一切是否正常运行时非常有用。每分钟,即使没有流量,您也会看到:
2019-07-26 11:47:57 Signals: Discovered 0 files
有了流量,您会看到类似这样的内容:
2019-07-26 11:50:57 Signals: Discovered sp1-0000000000003FBD.json 2019-07-26 11:50:57 Signals: Transferred sp1-0000000000003FBD.json successfully. 2019-07-26 11:50:57 Signals: Discovered 1 file, transferred 1 file successfully
min-free-space
这告诉 PowerMTA 在磁盘空间不足时开始删除旧 SparkPost JSON 事件文件,以腾出空间存放新文件的磁盘空间阈值。
enable-signals
这告诉 PowerMTA 上传到 Signals,通常是针对所有流量进行上传(更多信息 此处,适用于 v5.0)。如果您愿意,可以更选择性地选择上传哪些流量流。
您还可以标记特定 PowerMTA 流量以报告为属于 SparkPost 的 子账户 – 这是区分一个特定流量流与另一个流量流的方式。
engagement-tracking, customer-id
PowerMTA 的 Engagement Tracking 解决方案默认为 SparkPost 美国托管服务的跟踪域。您需要指定您的 SparkPost 数字客户 ID;以下是 找到它的说明。
tracking-domain
对于 SparkPost 欧洲账户,添加以下行:
tracking-domain pmta.eu.spgo.io # 这是 SparkPost 欧洲的终端点
自定义跟踪域
如果您希望使用自己的跟踪域(从送达能力的角度来看更好),请执行以下操作:
通过在您的 DNS 提供商处创建 CNAME 记录,创建跟踪域。这通常是顶级域的子域,例如 track.mycompany.com 。
track.mycompany.com CNAME pmta.spgo.io # if you have a SparkPost US account track.mycompany.com CNAME pmta.eu.spgo.io # if you have a SparkPost EU account
您还可以使用 HTTPS 跟踪域,尽管这更复杂(请参见 SparkPost 关于 HTTPS 跟踪域的配置步骤)。
在您的 SparkPost 帐户中注册跟踪域,并验证它。在尝试之前,请等待几分钟,以便您的 DNS 更改能够在互联网上传播,这取决于您的 DNS 提供商。
配置 PowerMTA 使用该域而不是默认域,使用以下命令:
tracking-domain yourdomain.com # 在这里填入您自己的域名
您可以通过查看邮件的内部结构(在 Gmail 中,使用右上方的菜单选择“显示原始”)来检查您的已发邮件中是否添加了“开放像素”,以及链接是否已包装。

您会注意到电子邮件 HTML 开始和结束时有开放像素。每个 HTML 链接也更改为包含指向跟踪域的 REF。

这就是让 SparkPost Signals 与 PowerMTA 的内置参与跟踪一起正常工作的全部内容。
防止特定链接在您的 html 邮件中被跟踪
您可以通过设置自定义属性 data-msys-clicktrack 为“0”来防止 PowerMTA 跟踪特定链接 :
<a href="#" data-msys-clicktrack="0">Example</a>
PowerMTA 将不会包装链接。它还将在向您的收件人传递消息之前移除该属性。
Signals 配置在 5.0 用户指南第 10.1 节 中进行了描述。这里我们将从“用例 #2”开始,该用例启用此 PowerMTA 主机的所有流量信号,并启用 SparkPost 的参与跟踪。
# # SparkPost Signals # <signals> api-key ##my ingest API key here## upload-url https://api.sparkpost.com/api/v1/ingest/events log-verbose true min-free-space 1G engagement-tracking sparkpost # this turns on the open and click tracking in PowerMTA customer-id 123 # Your SparkPost account number here </signals> enable-signals true
这是每个属性的作用:
api-key
这是您 SparkPost 账户特有的,是您之前从 SparkPost 获得的值。
upload-url
这需要匹配您的 SparkPost API 服务地址,无论是美国还是欧洲。有关更多信息,请参见此处。常用值是:
SparkPost(美国):https://api.sparkpost.com/api/v1/ingest/events
SparkPost 欧洲: https://api.eu.sparkpost.com/api/v1/ingest/events
log-verbose
此指令是可选的,启用后,在 pmta.log 文件中提供更多信息,这在设置过程中确认一切是否正常运行时非常有用。每分钟,即使没有流量,您也会看到:
2019-07-26 11:47:57 Signals: Discovered 0 files
有了流量,您会看到类似这样的内容:
2019-07-26 11:50:57 Signals: Discovered sp1-0000000000003FBD.json 2019-07-26 11:50:57 Signals: Transferred sp1-0000000000003FBD.json successfully. 2019-07-26 11:50:57 Signals: Discovered 1 file, transferred 1 file successfully
min-free-space
这告诉 PowerMTA 在磁盘空间不足时开始删除旧 SparkPost JSON 事件文件,以腾出空间存放新文件的磁盘空间阈值。
enable-signals
这告诉 PowerMTA 上传到 Signals,通常是针对所有流量进行上传(更多信息 此处,适用于 v5.0)。如果您愿意,可以更选择性地选择上传哪些流量流。
您还可以标记特定 PowerMTA 流量以报告为属于 SparkPost 的 子账户 – 这是区分一个特定流量流与另一个流量流的方式。
engagement-tracking, customer-id
PowerMTA 的 Engagement Tracking 解决方案默认为 SparkPost 美国托管服务的跟踪域。您需要指定您的 SparkPost 数字客户 ID;以下是 找到它的说明。
tracking-domain
对于 SparkPost 欧洲账户,添加以下行:
tracking-domain pmta.eu.spgo.io # 这是 SparkPost 欧洲的终端点
自定义跟踪域
如果您希望使用自己的跟踪域(从送达能力的角度来看更好),请执行以下操作:
通过在您的 DNS 提供商处创建 CNAME 记录,创建跟踪域。这通常是顶级域的子域,例如 track.mycompany.com 。
track.mycompany.com CNAME pmta.spgo.io # if you have a SparkPost US account track.mycompany.com CNAME pmta.eu.spgo.io # if you have a SparkPost EU account
您还可以使用 HTTPS 跟踪域,尽管这更复杂(请参见 SparkPost 关于 HTTPS 跟踪域的配置步骤)。
在您的 SparkPost 帐户中注册跟踪域,并验证它。在尝试之前,请等待几分钟,以便您的 DNS 更改能够在互联网上传播,这取决于您的 DNS 提供商。
配置 PowerMTA 使用该域而不是默认域,使用以下命令:
tracking-domain yourdomain.com # 在这里填入您自己的域名
您可以通过查看邮件的内部结构(在 Gmail 中,使用右上方的菜单选择“显示原始”)来检查您的已发邮件中是否添加了“开放像素”,以及链接是否已包装。

您会注意到电子邮件 HTML 开始和结束时有开放像素。每个 HTML 链接也更改为包含指向跟踪域的 REF。

这就是让 SparkPost Signals 与 PowerMTA 的内置参与跟踪一起正常工作的全部内容。
防止特定链接在您的 html 邮件中被跟踪
您可以通过设置自定义属性 data-msys-clicktrack 为“0”来防止 PowerMTA 跟踪特定链接 :
<a href="#" data-msys-clicktrack="0">Example</a>
PowerMTA 将不会包装链接。它还将在向您的收件人传递消息之前移除该属性。
选择要向Signals报告的PowerMTA流量流
您可以选择 Signals 为活动状态:
全局(这就是我们在上述示例中使用的)
适用于某些 Virtual MTAs 而非其他
适用于某些 Virtual MTA 池而非其他
适用于由 PowerMTA 转发的特定“Sender”或“From”地址,结合 Virtual MTA / Virtual MTA 池选择
该配置非常强大,并在用户指南中通过一系列示例用例(v5.0)进行说明。
您可以选择 Signals 为活动状态:
全局(这就是我们在上述示例中使用的)
适用于某些 Virtual MTAs 而非其他
适用于某些 Virtual MTA 池而非其他
适用于由 PowerMTA 转发的特定“Sender”或“From”地址,结合 Virtual MTA / Virtual MTA 池选择
该配置非常强大,并在用户指南中通过一系列示例用例(v5.0)进行说明。
您可以选择 Signals 为活动状态:
全局(这就是我们在上述示例中使用的)
适用于某些 Virtual MTAs 而非其他
适用于某些 Virtual MTA 池而非其他
适用于由 PowerMTA 转发的特定“Sender”或“From”地址,结合 Virtual MTA / Virtual MTA 池选择
该配置非常强大,并在用户指南中通过一系列示例用例(v5.0)进行说明。
测试您的事件是否到达Signals
这是 SparkPost Signals 的视图,连接到 PowerMTA。您可以看到健康评分在变化。

活动名称可作为报告方面提供,以及子账户、IP 池、邮箱提供商和发送域。
除了查看 PowerMTA 日志之外,您还可以通过查看 Signals 集成屏幕来检查事件数据是否正在到达 SparkPost。

在您的 SparkPost Events 搜索屏幕中,您应该在几分钟内看到事件出现。这些将包括 Injection 和 Delivery 事件,以及 Bounce,可能还有 Out-of-Band Bounce 和 Spam Complaint 事件,如果您已经配置了 PowerMTA 来为您处理这些事件。
如果您启用了参与度跟踪,您还会看到 open、initial_open 和 click 事件。
这是 SparkPost Signals 的视图,连接到 PowerMTA。您可以看到健康评分在变化。

活动名称可作为报告方面提供,以及子账户、IP 池、邮箱提供商和发送域。
除了查看 PowerMTA 日志之外,您还可以通过查看 Signals 集成屏幕来检查事件数据是否正在到达 SparkPost。

在您的 SparkPost Events 搜索屏幕中,您应该在几分钟内看到事件出现。这些将包括 Injection 和 Delivery 事件,以及 Bounce,可能还有 Out-of-Band Bounce 和 Spam Complaint 事件,如果您已经配置了 PowerMTA 来为您处理这些事件。
如果您启用了参与度跟踪,您还会看到 open、initial_open 和 click 事件。
这是 SparkPost Signals 的视图,连接到 PowerMTA。您可以看到健康评分在变化。

活动名称可作为报告方面提供,以及子账户、IP 池、邮箱提供商和发送域。
除了查看 PowerMTA 日志之外,您还可以通过查看 Signals 集成屏幕来检查事件数据是否正在到达 SparkPost。

在您的 SparkPost Events 搜索屏幕中,您应该在几分钟内看到事件出现。这些将包括 Injection 和 Delivery 事件,以及 Bounce,可能还有 Out-of-Band Bounce 和 Spam Complaint 事件,如果您已经配置了 PowerMTA 来为您处理这些事件。
如果您启用了参与度跟踪,您还会看到 open、initial_open 和 click 事件。
使用在报告中显示良好的有意义名称
设置 PowerMTA VirtualMTA 池名称和作业名称,使其有意义且易于阅读,这是非常值得的。这些会直接显示在您的 SparkPost Signals 分面和摘要报告中。
如前所述,您无需在 SparkPost 帐户中创建这些池。SparkPost 会从您的 PowerMTA 配置中获取它们。
以下是 PowerMTA 配置术语如何转换为 SparkPost 术语。
PowerMTA 术语SparkPost 报告 / Signals 术语收件人域
(domain portion of “rcpt” field in Accounting file).Recipient Domain The domain portion of the “Sender” or “From” header in the message relayed by PowerMTA. (domain portion of “orig” in Accounting file).Sending Domain VirtualMTA (name)—VirtualMTA Pool (name) (“vmtaPool” in accounting file)IP Pool (name) smtp-source-host a.b.c.d (“dlvSourceIp” in accounting file)Sending IP a.b.c.d Job (name) (“jobId” in accounting file)Campaign ID (name)—Template (name) “Subaccount” is not a native PowerMTA concept
然而,PowerMTA 可以为虚拟 MTA、虚拟 MTA 池或发件人或来源域添加子账户 ID,以用于 SparkPost 报告。
Subaccount ID (number) FBL (event) Spam Complaint (event) Remote Bounce (event) Out-of-Band bounce (event)
设置至少一个 smtp-source-host 地址还可以使 SparkPost 正确识别发送 IP 地址,以便它显示在注入和传递事件中,以及在摘要报告视图中。
作业名称通过注入消息中的头文件在 PowerMTA 中设置。除了启用单独的作业控制(暂停/恢复等)非常有用之外,PowerMTA 还将名称传递给 SparkPost Signals 报告为“活动 ID”。请参阅用户指南 v5.0 部分 12.8 “使用 JobID 在 PowerMTA 中跟踪活动”。
有几点需要注意的有关作业命名的事项。虽然 SparkPost(使用 JSON 格式和 JSON 转义)允许在活动名称中使用例如 <SPACE> 的字符,但邮件头限制更多。X-Job 头中允许的有效字符有:
A-Za-z0-9!#$%&'()*+,-./:;<=>?@[\]^_{|}~
换句话说,不允许的字符包括 <SPACE>、双引号“ 和反引号`。如果您习惯于使用 X-Job 名称,这不会令人惊讶,而且您的活动 ID 名称在 SparkPost 报告上会“正常工作”。如果像我一样先学习 SparkPost,您可能需要一个工具来确保 X-Job 值的安全;请参阅本文末尾的附加功能。
设置 PowerMTA VirtualMTA 池名称和作业名称,使其有意义且易于阅读,这是非常值得的。这些会直接显示在您的 SparkPost Signals 分面和摘要报告中。
如前所述,您无需在 SparkPost 帐户中创建这些池。SparkPost 会从您的 PowerMTA 配置中获取它们。
以下是 PowerMTA 配置术语如何转换为 SparkPost 术语。
PowerMTA 术语SparkPost 报告 / Signals 术语收件人域
(domain portion of “rcpt” field in Accounting file).Recipient Domain The domain portion of the “Sender” or “From” header in the message relayed by PowerMTA. (domain portion of “orig” in Accounting file).Sending Domain VirtualMTA (name)—VirtualMTA Pool (name) (“vmtaPool” in accounting file)IP Pool (name) smtp-source-host a.b.c.d (“dlvSourceIp” in accounting file)Sending IP a.b.c.d Job (name) (“jobId” in accounting file)Campaign ID (name)—Template (name) “Subaccount” is not a native PowerMTA concept
然而,PowerMTA 可以为虚拟 MTA、虚拟 MTA 池或发件人或来源域添加子账户 ID,以用于 SparkPost 报告。
Subaccount ID (number) FBL (event) Spam Complaint (event) Remote Bounce (event) Out-of-Band bounce (event)
设置至少一个 smtp-source-host 地址还可以使 SparkPost 正确识别发送 IP 地址,以便它显示在注入和传递事件中,以及在摘要报告视图中。
作业名称通过注入消息中的头文件在 PowerMTA 中设置。除了启用单独的作业控制(暂停/恢复等)非常有用之外,PowerMTA 还将名称传递给 SparkPost Signals 报告为“活动 ID”。请参阅用户指南 v5.0 部分 12.8 “使用 JobID 在 PowerMTA 中跟踪活动”。
有几点需要注意的有关作业命名的事项。虽然 SparkPost(使用 JSON 格式和 JSON 转义)允许在活动名称中使用例如 <SPACE> 的字符,但邮件头限制更多。X-Job 头中允许的有效字符有:
A-Za-z0-9!#$%&'()*+,-./:;<=>?@[\]^_{|}~
换句话说,不允许的字符包括 <SPACE>、双引号“ 和反引号`。如果您习惯于使用 X-Job 名称,这不会令人惊讶,而且您的活动 ID 名称在 SparkPost 报告上会“正常工作”。如果像我一样先学习 SparkPost,您可能需要一个工具来确保 X-Job 值的安全;请参阅本文末尾的附加功能。
设置 PowerMTA VirtualMTA 池名称和作业名称,使其有意义且易于阅读,这是非常值得的。这些会直接显示在您的 SparkPost Signals 分面和摘要报告中。
如前所述,您无需在 SparkPost 帐户中创建这些池。SparkPost 会从您的 PowerMTA 配置中获取它们。
以下是 PowerMTA 配置术语如何转换为 SparkPost 术语。
PowerMTA 术语SparkPost 报告 / Signals 术语收件人域
(domain portion of “rcpt” field in Accounting file).Recipient Domain The domain portion of the “Sender” or “From” header in the message relayed by PowerMTA. (domain portion of “orig” in Accounting file).Sending Domain VirtualMTA (name)—VirtualMTA Pool (name) (“vmtaPool” in accounting file)IP Pool (name) smtp-source-host a.b.c.d (“dlvSourceIp” in accounting file)Sending IP a.b.c.d Job (name) (“jobId” in accounting file)Campaign ID (name)—Template (name) “Subaccount” is not a native PowerMTA concept
然而,PowerMTA 可以为虚拟 MTA、虚拟 MTA 池或发件人或来源域添加子账户 ID,以用于 SparkPost 报告。
Subaccount ID (number) FBL (event) Spam Complaint (event) Remote Bounce (event) Out-of-Band bounce (event)
设置至少一个 smtp-source-host 地址还可以使 SparkPost 正确识别发送 IP 地址,以便它显示在注入和传递事件中,以及在摘要报告视图中。
作业名称通过注入消息中的头文件在 PowerMTA 中设置。除了启用单独的作业控制(暂停/恢复等)非常有用之外,PowerMTA 还将名称传递给 SparkPost Signals 报告为“活动 ID”。请参阅用户指南 v5.0 部分 12.8 “使用 JobID 在 PowerMTA 中跟踪活动”。
有几点需要注意的有关作业命名的事项。虽然 SparkPost(使用 JSON 格式和 JSON 转义)允许在活动名称中使用例如 <SPACE> 的字符,但邮件头限制更多。X-Job 头中允许的有效字符有:
A-Za-z0-9!#$%&'()*+,-./:;<=>?@[\]^_{|}~
换句话说,不允许的字符包括 <SPACE>、双引号“ 和反引号`。如果您习惯于使用 X-Job 名称,这不会令人惊讶,而且您的活动 ID 名称在 SparkPost 报告上会“正常工作”。如果像我一样先学习 SparkPost,您可能需要一个工具来确保 X-Job 值的安全;请参阅本文末尾的附加功能。
FBL 事件 (Spam Complaints) 和远程 (out-of-band) bounces
Injection 配置
我们将使用端口 587 来处理注入消息,这些消息将通过公共互联网从另一个主机发送过来。我们需要防止不良行为者发现和滥用此服务,因此我们应用了用户名/密码身份验证和可选的 TLS,类似于 SparkPost SMTP 注入端点。
我们希望能够从经过适当身份验证的来源向任何目的地发送消息。我们还希望在端口 25 上设置一个单独的监听器用于 FBL 和不需要身份验证的远程退回响应。
# IP address(es) and port(s) on which to listen for incoming SMTP connections smtp-listener 0.0.0.0:587 smtp-listener 0.0.0.0:25
在以下<source>声明中,我们使用用户名/密码身份验证和可选的 TLS 来防御恶意消息注入。我们还设置了对失败密码尝试的连接的速率限制。
您的设置可能不同;例如,如果注入器和 PowerMTA 之间有一个专用网络,则不需要密码身份验证。
# One source rule for all injection, internal or external. Enforce auth, except for bounces and FBLs # <source 0/0> log-connections false log-commands false # WARNING: verbose! just for dev log-data false # WARNING: even more verbose! smtp-service true # allow SMTP service smtp-max-auth-failure-rate 1/min allow-unencrypted-plain-auth false allow-starttls true rewrite-list mfrom </source> <source {auth}> always-allow-relaying yes # only if the auth succeeds default-virtual-mta default process-x-job true </source>
<source {auth}>声明(参见此处。 v5.0)适用于一旦通过身份验证的情况。这里它允许转发中继,设置要使用的默认虚拟 MTA 组,并添加 X-Job 标头(这将由 SparkPost Signals 报告为campaign_id)。
重写列表将注入的消息映射到使用特定的 MAIL FROM 域(又称为退回域或 Return-Path:)。
# # Rewrite the MAIL FROM address to match the bounce domain # <rewrite-list mfrom> mail-from *@pmta.signalsdemo.trymsys.net *@bounces.pmta.signalsdemo.trymsys.net </rewrite-list>
然后我们根据TLS 配置和有关当前建议的指南设置我们的 SMTP 用户名/密码。
# # Secure the inbound service with username, password and TLS. SMT 2020-06-15 # smtp-server-tls-certificate /etc/pmta/pmtasignalsdemo.pem smtp-server-tls-allow-tlsv1 false smtp-server-tls-allow-tlsv1.1 false smtp-server-tls-allow-tlsv1.2 true smtp-server-tls-allow-tlsv1.3 true # # SMTP users (authenticated via SMTP AUTH) # <smtp-user SMTP_Injection> password ##PUT YOUR PASSWORD HERE## authentication-method password </smtp-user>
我们可以使用我喜欢的 SMTP 测试工具swaks检查 TLS v1.0(已弃用且不安全)不被接受。
swaks --server pmta.signalsdemo.trymsys.net --port 587 \ --to test@trymsys.net \ --from any@sparkpost.com \ --tls \ --tls-protocol tlsv1
我们可以看到:
*** TLS startup failed (connect(): error:00000000:lib(0):func(0):reason(0)) *** STARTTLS attempted but failed
对于–tls-protocol tlsv1_1也是如此。
让我们也对我们发送的消息应用 DKIM 签名,因为它是一个好习惯(我遵循这些说明来设置密钥)。
# # DKIM # domain-key mypmta, pmta.signalsdemo.trymsys.net, /etc/pmta/mypmta.pmta.signalsdemo.trymsys.net.pem
我们将使用端口 587 来处理注入消息,这些消息将通过公共互联网从另一个主机发送过来。我们需要防止不良行为者发现和滥用此服务,因此我们应用了用户名/密码身份验证和可选的 TLS,类似于 SparkPost SMTP 注入端点。
我们希望能够从经过适当身份验证的来源向任何目的地发送消息。我们还希望在端口 25 上设置一个单独的监听器用于 FBL 和不需要身份验证的远程退回响应。
# IP address(es) and port(s) on which to listen for incoming SMTP connections smtp-listener 0.0.0.0:587 smtp-listener 0.0.0.0:25
在以下<source>声明中,我们使用用户名/密码身份验证和可选的 TLS 来防御恶意消息注入。我们还设置了对失败密码尝试的连接的速率限制。
您的设置可能不同;例如,如果注入器和 PowerMTA 之间有一个专用网络,则不需要密码身份验证。
# One source rule for all injection, internal or external. Enforce auth, except for bounces and FBLs # <source 0/0> log-connections false log-commands false # WARNING: verbose! just for dev log-data false # WARNING: even more verbose! smtp-service true # allow SMTP service smtp-max-auth-failure-rate 1/min allow-unencrypted-plain-auth false allow-starttls true rewrite-list mfrom </source> <source {auth}> always-allow-relaying yes # only if the auth succeeds default-virtual-mta default process-x-job true </source>
<source {auth}>声明(参见此处。 v5.0)适用于一旦通过身份验证的情况。这里它允许转发中继,设置要使用的默认虚拟 MTA 组,并添加 X-Job 标头(这将由 SparkPost Signals 报告为campaign_id)。
重写列表将注入的消息映射到使用特定的 MAIL FROM 域(又称为退回域或 Return-Path:)。
# # Rewrite the MAIL FROM address to match the bounce domain # <rewrite-list mfrom> mail-from *@pmta.signalsdemo.trymsys.net *@bounces.pmta.signalsdemo.trymsys.net </rewrite-list>
然后我们根据TLS 配置和有关当前建议的指南设置我们的 SMTP 用户名/密码。
# # Secure the inbound service with username, password and TLS. SMT 2020-06-15 # smtp-server-tls-certificate /etc/pmta/pmtasignalsdemo.pem smtp-server-tls-allow-tlsv1 false smtp-server-tls-allow-tlsv1.1 false smtp-server-tls-allow-tlsv1.2 true smtp-server-tls-allow-tlsv1.3 true # # SMTP users (authenticated via SMTP AUTH) # <smtp-user SMTP_Injection> password ##PUT YOUR PASSWORD HERE## authentication-method password </smtp-user>
我们可以使用我喜欢的 SMTP 测试工具swaks检查 TLS v1.0(已弃用且不安全)不被接受。
swaks --server pmta.signalsdemo.trymsys.net --port 587 \ --to test@trymsys.net \ --from any@sparkpost.com \ --tls \ --tls-protocol tlsv1
我们可以看到:
*** TLS startup failed (connect(): error:00000000:lib(0):func(0):reason(0)) *** STARTTLS attempted but failed
对于–tls-protocol tlsv1_1也是如此。
让我们也对我们发送的消息应用 DKIM 签名,因为它是一个好习惯(我遵循这些说明来设置密钥)。
# # DKIM # domain-key mypmta, pmta.signalsdemo.trymsys.net, /etc/pmta/mypmta.pmta.signalsdemo.trymsys.net.pem
我们将使用端口 587 来处理注入消息,这些消息将通过公共互联网从另一个主机发送过来。我们需要防止不良行为者发现和滥用此服务,因此我们应用了用户名/密码身份验证和可选的 TLS,类似于 SparkPost SMTP 注入端点。
我们希望能够从经过适当身份验证的来源向任何目的地发送消息。我们还希望在端口 25 上设置一个单独的监听器用于 FBL 和不需要身份验证的远程退回响应。
# IP address(es) and port(s) on which to listen for incoming SMTP connections smtp-listener 0.0.0.0:587 smtp-listener 0.0.0.0:25
在以下<source>声明中,我们使用用户名/密码身份验证和可选的 TLS 来防御恶意消息注入。我们还设置了对失败密码尝试的连接的速率限制。
您的设置可能不同;例如,如果注入器和 PowerMTA 之间有一个专用网络,则不需要密码身份验证。
# One source rule for all injection, internal or external. Enforce auth, except for bounces and FBLs # <source 0/0> log-connections false log-commands false # WARNING: verbose! just for dev log-data false # WARNING: even more verbose! smtp-service true # allow SMTP service smtp-max-auth-failure-rate 1/min allow-unencrypted-plain-auth false allow-starttls true rewrite-list mfrom </source> <source {auth}> always-allow-relaying yes # only if the auth succeeds default-virtual-mta default process-x-job true </source>
<source {auth}>声明(参见此处。 v5.0)适用于一旦通过身份验证的情况。这里它允许转发中继,设置要使用的默认虚拟 MTA 组,并添加 X-Job 标头(这将由 SparkPost Signals 报告为campaign_id)。
重写列表将注入的消息映射到使用特定的 MAIL FROM 域(又称为退回域或 Return-Path:)。
# # Rewrite the MAIL FROM address to match the bounce domain # <rewrite-list mfrom> mail-from *@pmta.signalsdemo.trymsys.net *@bounces.pmta.signalsdemo.trymsys.net </rewrite-list>
然后我们根据TLS 配置和有关当前建议的指南设置我们的 SMTP 用户名/密码。
# # Secure the inbound service with username, password and TLS. SMT 2020-06-15 # smtp-server-tls-certificate /etc/pmta/pmtasignalsdemo.pem smtp-server-tls-allow-tlsv1 false smtp-server-tls-allow-tlsv1.1 false smtp-server-tls-allow-tlsv1.2 true smtp-server-tls-allow-tlsv1.3 true # # SMTP users (authenticated via SMTP AUTH) # <smtp-user SMTP_Injection> password ##PUT YOUR PASSWORD HERE## authentication-method password </smtp-user>
我们可以使用我喜欢的 SMTP 测试工具swaks检查 TLS v1.0(已弃用且不安全)不被接受。
swaks --server pmta.signalsdemo.trymsys.net --port 587 \ --to test@trymsys.net \ --from any@sparkpost.com \ --tls \ --tls-protocol tlsv1
我们可以看到:
*** TLS startup failed (connect(): error:00000000:lib(0):func(0):reason(0)) *** STARTTLS attempted but failed
对于–tls-protocol tlsv1_1也是如此。
让我们也对我们发送的消息应用 DKIM 签名,因为它是一个好习惯(我遵循这些说明来设置密钥)。
# # DKIM # domain-key mypmta, pmta.signalsdemo.trymsys.net, /etc/pmta/mypmta.pmta.signalsdemo.trymsys.net.pem
FBL 和 OOB 配置
现在……最后……我们声明哪些特定域名开放用于远程反弹和FBL响应。我们不想将这些转发到其他地方(以防止反向散射攻击),只是内部处理这些响应。
# # Enable Bounce and FBL processing on specific domains # relay-domain pmta.signalsdemo.trymsys.net relay-domain bounces.pmta.signalsdemo.trymsys.net relay-domain fbl.pmta.signalsdemo.trymsys.net <bounce-processor> deliver-unmatched-email no deliver-matched-email no <address-list> domain pmta.signalsdemo.trymsys.net domain bounces.pmta.signalsdemo.trymsys.net </address-list> </bounce-processor> <feedback-loop-processor> deliver-unmatched-email no deliver-matched-email no <address-list> domain fbl.pmta.signalsdemo.trymsys.net </address-list> </feedback-loop-processor>
您可以看到我设置了两个反弹域名,因为我在试验使用/不使用mfrom改写规则。
FBL域通常会注册到像Microsoft SNDS这样的外部服务;更多信息请参见这篇文章。在这个演示中,FBL将来自Bouncy Sink,因此无需注册。
现在……最后……我们声明哪些特定域名开放用于远程反弹和FBL响应。我们不想将这些转发到其他地方(以防止反向散射攻击),只是内部处理这些响应。
# # Enable Bounce and FBL processing on specific domains # relay-domain pmta.signalsdemo.trymsys.net relay-domain bounces.pmta.signalsdemo.trymsys.net relay-domain fbl.pmta.signalsdemo.trymsys.net <bounce-processor> deliver-unmatched-email no deliver-matched-email no <address-list> domain pmta.signalsdemo.trymsys.net domain bounces.pmta.signalsdemo.trymsys.net </address-list> </bounce-processor> <feedback-loop-processor> deliver-unmatched-email no deliver-matched-email no <address-list> domain fbl.pmta.signalsdemo.trymsys.net </address-list> </feedback-loop-processor>
您可以看到我设置了两个反弹域名,因为我在试验使用/不使用mfrom改写规则。
FBL域通常会注册到像Microsoft SNDS这样的外部服务;更多信息请参见这篇文章。在这个演示中,FBL将来自Bouncy Sink,因此无需注册。
现在……最后……我们声明哪些特定域名开放用于远程反弹和FBL响应。我们不想将这些转发到其他地方(以防止反向散射攻击),只是内部处理这些响应。
# # Enable Bounce and FBL processing on specific domains # relay-domain pmta.signalsdemo.trymsys.net relay-domain bounces.pmta.signalsdemo.trymsys.net relay-domain fbl.pmta.signalsdemo.trymsys.net <bounce-processor> deliver-unmatched-email no deliver-matched-email no <address-list> domain pmta.signalsdemo.trymsys.net domain bounces.pmta.signalsdemo.trymsys.net </address-list> </bounce-processor> <feedback-loop-processor> deliver-unmatched-email no deliver-matched-email no <address-list> domain fbl.pmta.signalsdemo.trymsys.net </address-list> </feedback-loop-processor>
您可以看到我设置了两个反弹域名,因为我在试验使用/不使用mfrom改写规则。
FBL域通常会注册到像Microsoft SNDS这样的外部服务;更多信息请参见这篇文章。在这个演示中,FBL将来自Bouncy Sink,因此无需注册。
测试 SMTP listener
重要的是要测试您的SMTP监听程序是否要求授权用于任何通用目的地,拒绝未特别发送到FBL和远程反弹域的任何邮件。
swaks --server pmta.signalsdemo.trymsys.net \ --port 25 \ --to test@strange.pmta.signalsdemo.trymsys.net \ --from any@sparkpost.com
响应如预期所示,表明转发被拒绝:
550 5.7.1 转发拒绝,收件人在“RCPT TO:<test@strange.pmta.signalsdemo.trymsys.net>
(演示设置描述结束)。
重要的是要测试您的SMTP监听程序是否要求授权用于任何通用目的地,拒绝未特别发送到FBL和远程反弹域的任何邮件。
swaks --server pmta.signalsdemo.trymsys.net \ --port 25 \ --to test@strange.pmta.signalsdemo.trymsys.net \ --from any@sparkpost.com
响应如预期所示,表明转发被拒绝:
550 5.7.1 转发拒绝,收件人在“RCPT TO:<test@strange.pmta.signalsdemo.trymsys.net>
(演示设置描述结束)。
重要的是要测试您的SMTP监听程序是否要求授权用于任何通用目的地,拒绝未特别发送到FBL和远程反弹域的任何邮件。
swaks --server pmta.signalsdemo.trymsys.net \ --port 25 \ --to test@strange.pmta.signalsdemo.trymsys.net \ --from any@sparkpost.com
响应如预期所示,表明转发被拒绝:
550 5.7.1 转发拒绝,收件人在“RCPT TO:<test@strange.pmta.signalsdemo.trymsys.net>
(演示设置描述结束)。
VirtualMTA 设置和命名
PowerMTA VirtualMTAs(和VirtualMTA池)是管理消息流的强大功能,并且PowerMTA / SparkPost Signals的报告功能在这些功能处于活动状态时效果最佳。
# # Route all outgoing traffic through this virtual mta / pool. # # Declare the delivery IP address here, so that SparkPost signals ingest injection (aka "reception") events # will carry the correct sending_IP attribute # <virtual-mta mta1> smtp-source-host 172.31.25.101 pmta.signalsdemo.trymsys.net </virtual-mta> <virtual-mta-pool default> virtual-mta mta1 <domain *> max-smtp-out 20 # max. connections *per domain* bounce-after 4d12h # 4 days, 12 hours retry-after 10m # 10 minutes dkim-sign yes </domain> </virtual-mta-pool>
在SparkPost中,virtual-mta-pool设置报告为“IP池”,并作为SparkPost Signals报告的一个方面可用(图表下方的下拉菜单)。

汇总报告还显示IP池作为“分组依据”报告方面。

如本文前面提到的,设置至少一个smtp-source-host地址也使SparkPost能够正确识别发送IP地址,因此它会显示在注入和发送事件以及汇总报告中:

这就是你所需的让PowerMTA与SparkPost Signals之间的基本集成工作所需的一切。你会在这里找到完整的配置文件示例。
在你离开之前,这就是我提到的奖励功能。
PowerMTA VirtualMTAs(和VirtualMTA池)是管理消息流的强大功能,并且PowerMTA / SparkPost Signals的报告功能在这些功能处于活动状态时效果最佳。
# # Route all outgoing traffic through this virtual mta / pool. # # Declare the delivery IP address here, so that SparkPost signals ingest injection (aka "reception") events # will carry the correct sending_IP attribute # <virtual-mta mta1> smtp-source-host 172.31.25.101 pmta.signalsdemo.trymsys.net </virtual-mta> <virtual-mta-pool default> virtual-mta mta1 <domain *> max-smtp-out 20 # max. connections *per domain* bounce-after 4d12h # 4 days, 12 hours retry-after 10m # 10 minutes dkim-sign yes </domain> </virtual-mta-pool>
在SparkPost中,virtual-mta-pool设置报告为“IP池”,并作为SparkPost Signals报告的一个方面可用(图表下方的下拉菜单)。

汇总报告还显示IP池作为“分组依据”报告方面。

如本文前面提到的,设置至少一个smtp-source-host地址也使SparkPost能够正确识别发送IP地址,因此它会显示在注入和发送事件以及汇总报告中:

这就是你所需的让PowerMTA与SparkPost Signals之间的基本集成工作所需的一切。你会在这里找到完整的配置文件示例。
在你离开之前,这就是我提到的奖励功能。
PowerMTA VirtualMTAs(和VirtualMTA池)是管理消息流的强大功能,并且PowerMTA / SparkPost Signals的报告功能在这些功能处于活动状态时效果最佳。
# # Route all outgoing traffic through this virtual mta / pool. # # Declare the delivery IP address here, so that SparkPost signals ingest injection (aka "reception") events # will carry the correct sending_IP attribute # <virtual-mta mta1> smtp-source-host 172.31.25.101 pmta.signalsdemo.trymsys.net </virtual-mta> <virtual-mta-pool default> virtual-mta mta1 <domain *> max-smtp-out 20 # max. connections *per domain* bounce-after 4d12h # 4 days, 12 hours retry-after 10m # 10 minutes dkim-sign yes </domain> </virtual-mta-pool>
在SparkPost中,virtual-mta-pool设置报告为“IP池”,并作为SparkPost Signals报告的一个方面可用(图表下方的下拉菜单)。

汇总报告还显示IP池作为“分组依据”报告方面。

如本文前面提到的,设置至少一个smtp-source-host地址也使SparkPost能够正确识别发送IP地址,因此它会显示在注入和发送事件以及汇总报告中:

这就是你所需的让PowerMTA与SparkPost Signals之间的基本集成工作所需的一切。你会在这里找到完整的配置文件示例。
在你离开之前,这就是我提到的奖励功能。
Bonus feature: X-Job 名称检查/过滤
为确保任何字符字符串可安全用作 PowerMTA X-Job 名称,这里有一个简单的 Python 函数将任何不安全的字符映射为下划线“_”
import re def pmtaSafeJobID(s): """ :param s: str :return: str Map an arbitrary campaign ID string into allowed chars for PMTA X-Job header. See https://download.port25.com/files/UsersGuide-5.0.html#tracking-a-campaign-in-powermta-with-a-jobid Specifically disallow <sp> " ` but allow through most other chars. """ # Note have to escape ' - [ ] and double-escape \ - see https://docs.python.org/3/library/re.html disallowedChars = '[^A-Za-z0-9!#$%&\'()*+,\-./:;<=>?@$begin:math:display$\\\\\\\\$end:math:display$^_{|}~]' return re.sub(disallowedChars, '_', s)
这使用Python 正则表达式以特定方式声明不允许的字符集,使用“集合补”运算符 ^ 而不是列出所有允许的字符。这意味着我们捕获(并使其安全)超过常用 7 位集的字符。我们可以使用以下测试片段展示这一点:
s='' for i in range(32, 256): s += chr(i) print(pmtaSafeJobID(s))
输出
!#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^abcdefghijklmnopqrstuvwxyz{|}~_________________________________________________________
您可以看到<SPACE>、双引号“,和反引号`,以及所有超出~的字符都被映射为下划线。
为确保任何字符字符串可安全用作 PowerMTA X-Job 名称,这里有一个简单的 Python 函数将任何不安全的字符映射为下划线“_”
import re def pmtaSafeJobID(s): """ :param s: str :return: str Map an arbitrary campaign ID string into allowed chars for PMTA X-Job header. See https://download.port25.com/files/UsersGuide-5.0.html#tracking-a-campaign-in-powermta-with-a-jobid Specifically disallow <sp> " ` but allow through most other chars. """ # Note have to escape ' - [ ] and double-escape \ - see https://docs.python.org/3/library/re.html disallowedChars = '[^A-Za-z0-9!#$%&\'()*+,\-./:;<=>?@$begin:math:display$\\\\\\\\$end:math:display$^_{|}~]' return re.sub(disallowedChars, '_', s)
这使用Python 正则表达式以特定方式声明不允许的字符集,使用“集合补”运算符 ^ 而不是列出所有允许的字符。这意味着我们捕获(并使其安全)超过常用 7 位集的字符。我们可以使用以下测试片段展示这一点:
s='' for i in range(32, 256): s += chr(i) print(pmtaSafeJobID(s))
输出
!#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^abcdefghijklmnopqrstuvwxyz{|}~_________________________________________________________
您可以看到<SPACE>、双引号“,和反引号`,以及所有超出~的字符都被映射为下划线。
为确保任何字符字符串可安全用作 PowerMTA X-Job 名称,这里有一个简单的 Python 函数将任何不安全的字符映射为下划线“_”
import re def pmtaSafeJobID(s): """ :param s: str :return: str Map an arbitrary campaign ID string into allowed chars for PMTA X-Job header. See https://download.port25.com/files/UsersGuide-5.0.html#tracking-a-campaign-in-powermta-with-a-jobid Specifically disallow <sp> " ` but allow through most other chars. """ # Note have to escape ' - [ ] and double-escape \ - see https://docs.python.org/3/library/re.html disallowedChars = '[^A-Za-z0-9!#$%&\'()*+,\-./:;<=>?@$begin:math:display$\\\\\\\\$end:math:display$^_{|}~]' return re.sub(disallowedChars, '_', s)
这使用Python 正则表达式以特定方式声明不允许的字符集,使用“集合补”运算符 ^ 而不是列出所有允许的字符。这意味着我们捕获(并使其安全)超过常用 7 位集的字符。我们可以使用以下测试片段展示这一点:
s='' for i in range(32, 256): s += chr(i) print(pmtaSafeJobID(s))
输出
!#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^abcdefghijklmnopqrstuvwxyz{|}~_________________________________________________________
您可以看到<SPACE>、双引号“,和反引号`,以及所有超出~的字符都被映射为下划线。



