为什么我的 AWS ECS 应用程序需要 "weird" 个 TCP 端口才能从 ECR 中提取数据?

Why are "weird" TCP ports required for my AWS ECS app to pull from ECR?

我正在使用前面带有 NLB 的 ECS。 ECS 正在从 ECR 拉取镜像。我无法理解的是为什么 ECS 要求我打开所有 TCP 端口才能从 ECR 中拉取?

2 621567429603 eni-0f5e97a3c2d51a5db 18.136.60.252 10.0.12.61 443 55584 6 13 6504 1537798711 1537798719 ACCEPT OK
2 621567429603 eni-0f5e97a3c2d51a5db 10.0.12.61 54.255.143.131 44920 443 6 13 5274 1537798711 1537798719 ACCEPT OK
2 621567429603 eni-0f5e97a3c2d51a5db 54.255.143.131 10.0.12.61 443 44952 6 13 6504 1537798711 1537798719 ACCEPT OK
2 621567429603 eni-0f5e97a3c2d51a5db 10.0.12.61 18.136.60.252 55584 443 6 15 5378 1537798711 1537798719 ACCEPT OK
2 621567429603 eni-0f5e97a3c2d51a5db 10.0.12.61 18.136.60.252 55612 443 6 15 5378 1537798711 1537798719 ACCEPT OK
2 621567429603 eni-0f5e97a3c2d51a5db 52.219.36.183 10.0.12.61 443 51892 6 19 11424 1537798711 1537798719 ACCEPT OK
2 621567429603 eni-0f5e97a3c2d51a5db 10.0.12.61 54.255.143.131 44908 443 6 14 1355 1537798711 1537798719 ACCEPT OK
2 621567429603 eni-0f5e97a3c2d51a5db 52.219.36.183 10.0.12.61 443 51912 6 31807 44085790 1537798711 1537798719 ACCEPT OK
2 621567429603 eni-0f5e97a3c2d51a5db 18.136.60.252 10.0.12.61 443 55612 6 12 6452 1537798711 1537798719 ACCEPT OK

上面是我的流日志。 10.0.0.0/8 是我的 VPC 私有地址。注意第一次说 SRC: 18.136.60.252:443 is accessing 10.0.12.61:55584 why this destination port?

然后下一行2 621567429603 eni-0f5e97a3c2d51a5db 10.0.12.61 54.255.143.131 44920 443 6 13 5274 1537798711 1537798719 ACCEPT OK。为什么我的 ECS 使用源端口 44920 请求数据。我在问,所以我知道如何打开正确的端口。目前因为端口太随机了,我需要打开所有东西

我只是根据ECS出站网络经验在这里补充一下我的想法。您的 ECS EC2 具有 ecs-agent 运行,它与 ECS、CloudWatch API 不断交互。 ecs-agent 不断通知 EC2 主机状态,docker 容器 运行 并将代理日志发送到上述 API。

ecs-agent 进程在特定时间间隔内与上述 AWS API(443) 交互,这就是源端口不断变化的原因。这是我的 EC2 服务器 netstat 日志的输出。

命令 - netstat -tcp

Proto Recv-Q Send-Q Local Address           Foreign Address         State       PID/Program name    
tcp        0      0 ip-172-31-86-188.:47364 52.46.132.80:https      ESTABLISHED 4188/agent          
tcp        0      0 ip-172-31-86-188.:57190 52.46.132.44:https      ESTABLISHED 4188/agent 

Proto Recv-Q Send-Q Local Address           Foreign Address         State       PID/Program name    
tcp        0      0 ip-172-31-86-188.:57190 52.46.132.44:https      ESTABLISHED 4188/agent          
tcp        0      0 ip-172-31-86-188.:60646 52.46.128.101:https     ESTABLISHED 4188/agent    

为了从 ECR 拉取镜像,您的 EC2 只需要 ECR 端点的 443 端口。所有其他流量都是 ecs-agent 特定于集群维护的内容。根据您的 EC2 TCP 日志以及哪个进程对此负责,让我知道您的想法。

肯定是你的ECS配置了动态端口映射。它具有从 4915365535 的默认临时端口范围,通常,32768 以下的端口不在临时端口范围内,因此 TCP 连接中主机端口的随机性。你确实有较低的端口值,但这一定是由于你的实例配置(ip_local_port_range的默认值大多数时候是32768 - 61000

请从here, and the exact point where the port setting is set can be found here

阅读有关如何配置的详细信息

It is possible to configure or set a single port using either set a single port for all connectivity, or edit your port range through /proc/sys/net/ipv4/ip_local_port_range, though it is not recommended to deviate from default range.

当它说 18.136.60.252:443 is accessing 10.0.12.61:55584 时,我不会说 18.136.60.252 正在“访问”您的本地 VPC IP。我宁愿说“18.136.60.252”正在向您的本地 VPC IP 发送响应,发送到 OS 分配的随机 SRC 端口,以通过已经建立的 TCP 连接(已启动在您的实例中由 ecs-agent 执行)。

您无需关注应该允许哪个源端口。您宁愿告诉 OS (防火墙)“让响应进入已建立的连接”。在 iptables 中是这样的:

从实例到网络,访问远程443端口:

iptables -A OUTPUT -o eth0 -p tcp -m multiport --dports 80,443 -j ACCEPT

从远程主机到您的实例,让响应返回:

iptables -A INPUT -i eth0 -p tcp -m multiport --sports 80,443 -m state --state RELATED,ESTABLISHED -j ACCEPT
.                                               ^ source port          ^ the rule only applies to already established connections

在这里你可以找到一些更好的解释:

https://unix.stackexchange.com/q/323546/18256

https://superuser.com/a/1171322/131073

Why is my ECS requesting data using source port 44920

OS是把这些端口分配给ECS代理作为源端口的那个,它只是一个免费的,随机选择的。


OP澄清后编辑自学

So in AWS NACL level I should allow all ephemeral port range?

根据AWS NACL docs

In practice, to cover the different types of clients that might initiate traffic to public-facing instances in your VPC, you can open ephemeral ports 1024-65535. However, you can also add rules to the ACL to deny traffic on any malicious ports within that range. Ensure that you place the DENY rules earlier in the table than the ALLOW rules that open the wide range of ephemeral ports.

但要考虑到:

You might set up network ACLs with rules similar to your security groups in order to add an additional layer of security to your VPC. (emphasis mine)

.

And at OS level do that? If I am using docker I need to do that via Dockerfile?

我的建议是通过安全组进行管理,因为它们是“有状态的”,这意味着它们会跟踪建立的每个连接,自动允许对临时端口的“响应”,而无需配置这些规则。例如,您可以“拒绝”所有入站流量,并允许出站流量使用 TCP 443。这确实 not 意味着响应无法到达临时端口,它们确实可以(尽管拒绝所有入站流量),因为安全组会记住连接。查看更多信息 here:

Security group: Is stateful: Return traffic is automatically allowed, regardless of any rules

Network ACL: Is stateless: Return traffic must be explicitly allowed by rules <-- this is answering the previous question, about ephemeral ports

关于 OS 和 iptables,我会首先探索更易于配置和维护的安全组,至少对于当前用例而言。