AWS:使用自定义networkingACL访问Internet时出错

我一直被困在看我的屏幕大约2小时,试图找出为什么这是行不通的。 我正在build立一个私有和公有子网的典型VPC,并尽可能地locking它。 我有几个安全小组,但是我知道问题出在NACL上,好像我放松了规则,一切正常。

我入境的NACL是 入站ACL

而出境是 在这里输入图像说明

我遇到的问题是,我无法从公共或专用子网中的任何EC2实例内访问互联网(端口80和443)。 我知道“问题规则”是入站没有1000,它允许从10.0.0.0/16所有临时端口。 如果我改变这个规则适用于所有的来源( 0.0.0.0/0 ),我可以从两个子网中的所有ec2实例访问互联网(我通过运行不同的应用程序来testing这个;大多数是curl和yum。

我只是努力了解这种行为,因为入站规则应该允许任何ec2实例打开一个短暂的端口,并与路由器通话,然后路由器可以与任何主机的端口80和443通话。 我有我缺less简单的感觉,但关键点在这里:)。

编辑

在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 ),以确保谷歌没有返回数据forms的临时端口。 我已经使用数据包标志删除了额外的数据,并且可以将-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和谷歌(prg03s06-in-f4.1e100.net)从端口80(日志中的http)回复。

回答

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

以下是networkingACL规则的部分:

  • 规则编号。 规则从最低编号的规则开始评估。 只要规则匹配stream量,它就会被应用,而不pipe任何可能与之相抵触的更高编号的规则。
  • 协议。 您可以指定任何具有标准协议号的协议。 有关更多信息,请参阅协议号码。 如果将ICMP指定为协议,则可以指定任何或全部ICMPtypes和代码。
  • [仅限入站规则] stream量源 (CIDR范围)和目标(侦听)端口或端口范围
  • [仅限出站规则]stream量目标(CIDR范围)和目标端口或端口范围。
  • 允许或拒绝指定stream量的选项。

当您在端口80(或任何端口上的任何守护进程)上build立连接时,连接将切换到高端口端口以保持端口80空闲以接受新的连接。 这些被称为临时端口 。

您需要允许传入这些高端端口的stream量,根据维基百科,这是32768到61000.如果您提供了一个Web服务器,你可能也需要允许它们传出 – 你有规则100。

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

这里还有另外一个解释。

如果我已经正确地阅读了这个问题,当您将入站规则1000更改为0.0.0.0/0而不是10.0.0.0/16时,则从EC2实例到Internet的连接工作。 我觉得这对我有点意义。

当stream量进入Inbound并由NACL(与您的Instances所在子网相关)传递时,源不是10.0.0.0/16子网,而是您已连接的Web服务上的任何IP地址。 这就是为什么0.0.0.0/0有效,10.0.0.0/16不能