如何排查当我将一个 HTTP(S) 端点订阅到我的 Amazon SNS 主题时遇到的问题?
上次更新时间:2021 年 6 月 21 日
当我将 HTTP 或 HTTPS 端点订阅到某个 Amazon Simple Notification Service(Amazon SNS)主题时,我无法收到订阅确认通知。
解决方法
在将 HTTP(S) 端点订阅到某个 SNS 主题之前,您必须首先确认该 HTTP(S) 端点已做好处理 Amazon SNS 消息的准备。
注意:以下步骤也适用于 HTTP(S) 订阅处于已确认状态,但仍未收到通知的情况。
在订阅 SNS 主题之前,验证是否可以公开访问您的 HTTP(S) 端点
Amazon SNS 不支持私有 HTTP(S) 端点。当您将 HTTP(S) 端点订阅到某个 SNS 主题时,Amazon SNS 会通过公共互联网向您的端点发出一个 HTTP POST 请求。有关更多信息和示例 POST 请求,请参阅解析消息格式。
要检查是否可公开访问您的端点,请从本地计算机发出一个示例 POST 请求。例如:
curl -X POST your_HTTPS_endpoint -H "Content-Type:text/plain; charset=UTF-8" --data {"x":"y"} -v
如果可以公开访问您的端点,则该命令将返回以下 HTTP 状态代码:
200 OK
如果您要将无法公开访问的 HTTP 端点订阅到某个 SNS 主题,则会收到以下错误消息:
An error occurred (InvalidParameter) when calling the Subscribe operation: Invalid parameter: Unreachable Endpoint
重要提示:主机名不能包含下划线。例如,不允许使用下面的主机名:your_hostname
验证端点的响应标头
根据您使用的身份验证类型完成以下步骤:基本或摘要式访问身份验证。确保您的端点为 'https',并且支持 HTTP/1.1 401 未经授权标头响应。
基本访问身份验证:
当您的端点收到未通过身份验证的请求时,其应返回 HTTP/1.1 401 未经授权标头响应,以及一个“WWW-Authenticate”标头。标头的值应包含关键词“Basic”以及 RFC 2617 中支持的其他可选参数(来自 RFC 编辑器网站)。例如:
WWW-Authenticate: Basic
摘要式访问身份验证:
当您的端点收到未通过身份验证的请求时,其应返回一个 HTTP/1.1 401 未经授权标头响应,以及一个“WWW-Authenticate”标头。标头的值应包含关键词“Digest”、一个随机生成的一次性使用值(称为“nonce”)、一个身份验证域,以及 RFC 2617 中支持的其他可选参数(来自 RFC 编辑器网站)。例如:
WWW-Authenticate: Digest realm="testrealm@host.com",
qop="auth,auth-int",
nonce="dcd98b7102dd2f0e8b11d0f600bfb0c093",
opaque="5ccc069c403ebaf9f0171e9517f40e41"
设置传输状态日志记录
sns/your_aws_region/your_account_ID/your_topic_name/Failure
注意:要了解订阅确认通知传输失败的原因,请检查 Amazon CloudWatch 传输状态日志中的 providerResponse。
检查 HTTPS 端点的 SSL 证书
如果您使用的是 HTTPS 端点,请完成以下问题排查步骤:
1. 确认端点返回的 SSL 证书有效,并且是由 Amazon SNS 信任的证书颁发机构签名的。
2. 验证您的端点是否返回了完整的证书链。完整的证书链包括所有中间证书。
注意:您可以使用第三方工具来验证端点返回的 SSL 证书是否受信任且完整。例如,您可以使用 SSL Labs 网站上的 SSL 服务器测试。
您还可以运行以下 OpenSSL 命令来验证端点返回的 SSL 证书是否受信任且完整:
openssl s_client -connect yourHostname:443 -servername yourHostname -showcerts
如果端点返回的 SSL 证书不可信或不完整,那么您可能会在 CloudWatch 日志中看到以下 providerResponse:
{
"notification": {
"messageId": "...",
"topicArn": "arn:aws:sns:ap-northeast-1:***:***",
"timestamp": "2021-05-12 06:41:20.778"
},
"delivery": {
"deliveryId": "***",
"destination": "https://***",
"providerResponse": "SSLPeerUnverifiedException in HttpClient",
"dwellTimeMs": 66171,
"attempts": 4
},
"status": "FAILURE"
}
检查防火墙是否阻止了您的 HTTP(S) 端点
如果防火墙阻止向您的 HTTP(S) 端点发送 SNS 订阅确认通知,请允许 AWS 区域特定的 IP 地址。
检查您的 HTTP(S) 端点是否配置了订阅筛选策略
如果您的端点处于已订阅状态但没有收到主题通知,请完成以下步骤:
1. 检查您的端点是否配置了订阅筛选策略。如果您的 HTTP(S) 订阅配置了筛选策略,则可能会过滤通知。
2. 要确认您的 SNS 消息是否已被过滤,请检查以下 CloudWatch 指标:NumberOfNotificationsFilteredOut、NumberOfNotificationsFilteredOut-InvalidAttributes、和 NumberOfNotificationsFilteredOut-NoMessageAttributes。