回答

回答

我已经盯着屏幕看了大约 2 个小时,试图弄清楚为什么这不起作用。我正在构建具有私有和公共子网的典型 VPC,并尝试尽可能地锁定它。我有几个安全组,但我知道问题出在 NACL 中,因为如果我放宽规则,一切都会正常。

我的入站 NACL 是 入站 ACL

出站是 在此处输入图片描述

我遇到的问题是,我无法从公有子网或私有子网中的任何 EC2 实例内部访问互联网(端口 80 和 443)。我知道“问题规则”是入站编号 1000,它允许来自 的所有临时端口10.0.0.0/16。如果我将此规则更改为应用于所有源(0.0.0.0/0),我可以从两个子网中的所有 ec2 实例访问互联网(我正在通过运行不同的应用程序来测试这一点;主要是 curl 和 yum。

我只是很难理解这种行为,因为入站规则应该允许任何 ec2 实例打开临时端口并与路由器通信,然后路由器可以与任何主机的端口 80 和 443 通信。我感觉我在这里忽略了简单但关键的一点 :)。

编辑

在 ASCII 艺术中,这是我对规则的理解

EC2 instance does a curl on www.google.com (port 80) 

SYN Packet out to stablish the connection (ephemeral port on VM to port 80)
EC2 vm (somewhere in 10.0.0.0/16:ephemeral)
 -> SG 
 -> NACL in (in rule 1000 - ALLOW source 10.0.0.0/16 on ports 1024-65535) 
 -> NACL out (out rule 200 - ALLOW destination 0.0.0.0/0 on port 80)
 -> IGW 
 -> Google (172.217.23.14:80)

SYN + ACK Packet in to continue the connection handshake
Google (172.217.23.14:80)
  -> IGW 
  -> NACL in (in rule 100 - ALLOW source 0.0.0.0/0 on port 80) 
  -> NACL out (out rule 100 - ALLOW destination 0.0.0.0/0 on port 1024-65535) 
  -> SG 
  -> EC2 vm (somewhere in 10.0.0.0/16:ephemeral)

编辑2

运行 tcpdump ( sudo tcpdump -i eth0 -s 1500 port not 22) 以确保 google 不会从临时端口返回数据。我已使用数据包标志删除了多余的数据,您可以添加-X标志以查看每个数据包中的实际数据。

18:28:56.919335 IP ip-10-112-7-114.eu-west-1.compute.internal.40174 > prg03s06-in-f4.1e100.net.http:
18:28:56.949105 IP prg03s06-in-f4.1e100.net.http > ip-10-112-7-114.eu-west-1.compute.internal.40174:
18:28:56.949119 IP ip-10-112-7-114.eu-west-1.compute.internal.40174 > prg03s06-in-f4.1e100.net.http:
18:28:56.949219 IP ip-10-112-7-114.eu-west-1.compute.internal.40174 > prg03s06-in-f4.1e100.net.http:
18:28:56.979089 IP prg03s06-in-f4.1e100.net.http > ip-10-112-7-114.eu-west-1.compute.internal.40174:
18:28:57.010155 IP prg03s06-in-f4.1e100.net.http > ip-10-112-7-114.eu-west-1.compute.internal.40174:
18:28:57.010178 IP ip-10-112-7-114.eu-west-1.compute.internal.40174 > prg03s06-in-f4.1e100.net.http:
18:28:57.010308 IP ip-10-112-7-114.eu-west-1.compute.internal.40174 > prg03s06-in-f4.1e100.net.http:
18:28:57.041100 IP prg03s06-in-f4.1e100.net.http > ip-10-112-7-114.eu-west-1.compute.internal.40174:
18:28:57.041110 IP ip-10-112-7-114.eu-west-1.compute.internal.40174 > prg03s06-in-f4.1e100.net.http:

从那里你可以看到 curl 打开了端口 40174 并且 google(prg03s06-in-f4.1e100.net)从端口 80 进行回复(日志中的 http)。

回答

感谢 Tim 和 Michael-sqlbot。答案有点埋在评论中。但问题是对入站规则的工作方式存在误解。端口范围入境规则请参阅目的端口,而不是源端口。来自 AWS 文档

以下是网络 ACL 规则的组成部分:

  • 规则编号。规则从编号最低的规则开始评估。只要某条规则与流量匹配,就会应用该规则,而不管是否有编号更高的规则与之相抵触。
  • 协议。您可以指定任何具有标准协议号的协议。有关更多信息,请参阅协议号。如果指定 ICMP 作为协议,则可以指定任何或所有 ICMP 类型和代码。
  • [仅限入站规则]流量来源(CIDR 范围)和目标(侦听)端口或端口范围
  • [仅限出站规则] 流量的目标(CIDR 范围)和目标端口或端口范围。
  • 对于指定的流量,选择允许或拒绝。

答案1

当你在端口 80 上建立连接(或与任何端口上的任何守护进程建立连接)时,该连接将移交给高端端口,以保持端口 80 可以自由接受新连接。这些被称为临时端口

您需要允许传入流量到这些高范围端口,根据 Wikipedia,这些端口是 32768 到 61000。如果您正在提供 Web 服务器,您可能还需要允许它们传出 - 您将其作为规则 100。

更新/扩展 NACL 是无状态的,这意味着您需要允许数据需要流动的每个方向的端口。当您连接到端口 80 上的 Web 服务器时,他们的 Web 服务器会说“连接已接受,继续在端口(例如)50000 上进行此交换”。这就是为什么您需要允许高范围端口传入以允许传出流量的原因。

还有另一种解释这里

答案2

如果我没看错的话,当你将入站规则 1000 更改为 0.0.0.0/0 而不是 10.0.0.0/16 时,从 EC2 实例到互联网的连接就可以正常工作。我认为这对我来说有点道理。

当流量进入入站并经过 NACL(与您的实例所在的子网相关联)时,源不是 10.0.0.0/16 子网,而是您连接到的 Web 服务上的任何 IP 地址。这就是为什么 0.0.0.0/0 有效而 10.0.0.0/16 无效的原因

相关内容