如何配置EC2入站规则,仅允许AWS SNS访问Tomcat的8080端口?
我太懂这个痛点了——AWS SNS的请求来源IP根本没有固定范围,直接封端口收不到消息,加固定IP又不管用,还得防着端口扫描。下面给你一套靠谱的解决方案,既能让SNS正常触发你的Tomcat代码,又能把无关访问全挡在安全组外面。
核心思路:用VPC PrivateLink让SNS走内网访问你的EC2
既然公网IP没法固定,那我们就绕开公网,让SNS通过AWS内网(VPC端点)来访问你的Tomcat,这样就能在安全组里精准限制流量来源。
步骤1:确认EC2在VPC里
首先确保你的Tomcat EC2实例是部署在AWS VPC子网中的(现在新创建的EC2默认都是VPC,除非你用了老的EC2-Classic,那得先迁移到VPC)。
步骤2:创建SNS的VPC Interface Endpoint
- 打开AWS VPC控制台,找到左侧菜单的「端点」,点击「创建端点」
- 服务类别选「AWS服务」,搜索框输入
SNS,选择和你EC2同区域的SNS服务(注意看服务名称里的区域标识,比如com.amazonaws.us-east-1.sns) - 选择你的EC2所在的VPC,再选EC2所在的子网(或者同一个VPC里的可信子网)
- 给这个端点分配一个安全组:这个安全组只需要允许出站访问EC2的8080端口就行(后面我们会在EC2的安全组里反过来允许这个端点的流量)
- 保持「启用DNS名称」勾选状态(默认是开的,这样SNS能通过内网DNS找到这个端点)
步骤3:配置EC2安全组的入站规则
编辑你的Tomcat EC2的安全组,添加一条入站规则:
- 类型:自定义TCP
- 端口范围:
8080 - 来源:选「自定义」,然后输入刚才创建的SNS VPC端点的安全组ID(或者如果你VPC里全是可信资源,也可以直接填VPC的CIDR范围)
这样一来,只有来自SNS内网端点的请求能打到8080端口,公网的端口扫描直接就被安全组拦截了。
步骤4:更新SNS订阅的端点URL
把你原来的公网URL换成EC2的内网IP或者内网DNS名称,比如http://10.0.1.100:8080/your-sns-endpoint,这样SNS就会通过VPC端点的内网路径发送请求,完全不走公网。
额外加固:在Tomcat层验证SNS签名
就算安全组把大部分垃圾流量挡住了,还是建议在你的Tomcat代码里加一层SNS请求签名验证——毕竟安全组只是第一道防线,代码层验证能确保收到的请求真的是AWS SNS发的。你可以用AWS SDK里的工具类(比如Java的SnsMessageValidator)来简化验证,核心是检查请求头里的X-Amz-Signature和对应的证书是否合法。
为啥之前的方法没用?
若限制为EC2内网或公网IP,同样无法接收消息
因为SNS的公网请求来源IP是动态生成的,AWS也不会公开这些IP的固定范围,所以直接加IP/IP段到安全组根本抓不住正确的来源。而用VPC端点之后,SNS的请求会从VPC内部的IP发出,这部分流量我们就能通过安全组精准控制了。
内容的提问来源于stack exchange,提问作者Joseph Janos

