如何让AWS SNS主题订阅请求访问仅开放特定IP的服务器
解决AWS SNS无法推送退信至listmonk服务器的问题
核心原因
你的虚拟主机配置仅允许单个IP访问,而AWS SNS的推送请求来自AWS官方IP段,不在允许列表内,导致被服务器拒绝。
解决步骤
1. 获取AWS SNS的IP地址范围
AWS SNS的请求来自官方维护的IP段,你可以通过以下方式获取对应区域的IP:
- 运行AWS CLI命令导出SNS服务的IP范围:
(如果没有jq工具,可直接查看AWS发布的IP范围JSON文件,筛选SNS相关条目)aws ip-ranges --output json | jq '.prefixes[] | select(.service=="SNS") | .ip_prefix' - 注意:要选择你SES/SNS所在区域对应的IP段,避免添加不必要的IP。
2. 修改虚拟主机IP限制配置
根据你使用的Web服务器(Apache/Nginx),针对性修改配置:
针对Apache服务器
找到站点的虚拟主机配置文件(通常在/etc/apache2/sites-available/或/etc/httpd/conf.d/目录下),优先针对listmonk的SES webhook路径单独设置允许规则,避免放开整个站点:
# 针对SES webhook路径配置IP允许列表 <Location "/webhooks/service/ses"> # 保留原有的单个允许IP Require ip 你的原允许IP # 添加获取到的AWS SNS IP段,示例如下 Require ip 52.0.0.0/14 Require ip 54.192.0.0/16 # 更多SNS IP段... </Location>
如果之前是针对整个目录限制,也可以修改目录规则:
<Directory /path/to/your/site> Require ip 你的原允许IP Require ip 52.0.0.0/14 # 其他SNS IP段... </Directory>
修改后重启Apache:
# Ubuntu/Debian sudo systemctl restart apache2 # CentOS/RHEL sudo systemctl restart httpd
针对Nginx服务器
找到站点的虚拟主机配置文件(通常在/etc/nginx/sites-available/或/etc/nginx/conf.d/目录下),同样针对webhook路径单独配置:
# 单独配置SES webhook的IP允许规则 location /webhooks/service/ses { allow 你的原允许IP; # 添加AWS SNS IP段 allow 52.0.0.0/14; allow 54.192.0.0/16; # 更多SNS IP段... deny all; # 保留listmonk的反向代理配置(根据实际情况调整) proxy_pass http://localhost:9000; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; } # 原有站点其他路径仍保留单个IP限制 location / { allow 你的原允许IP; deny all; # 其他原有配置... }
修改后验证配置有效性并重启Nginx:
sudo nginx -t sudo systemctl restart nginx
3. 验证配置是否生效
- 触发一次AWS SES退信(比如发送邮件到无效邮箱),查看服务器日志(Apache查看
/var/log/apache2/error.log,Nginx查看/var/log/nginx/error.log),确认不再出现client denied by server configuration错误; - 或者使用AWS SNS控制台的「发布消息」功能,给目标主题发送测试消息,检查listmonk是否接收到该webhook请求。
注意事项
AWS的IP范围可能会定期更新,建议定期检查官方IP列表,或者用自动化脚本(比如结合AWS CLI)定时更新虚拟主机的IP允许规则,避免后续再次出现访问被拒的问题。
内容的提问来源于stack exchange,提问作者Ambika Sharma
相关产品推荐
相关产品推荐

