无法与我的 EC2 实例建立 Internet 连接 [使用 terraform 部署,并为 ACL、安全组、Internet GW 打开了 80 个 http 端口]

Posted

技术标签:

【中文标题】无法与我的 EC2 实例建立 Internet 连接 [使用 terraform 部署,并为 ACL、安全组、Internet GW 打开了 80 个 http 端口]【英文标题】:Can't establish internet connection to my EC2 instance [deployed with terraform and 80 http port opened for ACL, Security Group, Internet GW] 【发布时间】:2021-11-21 13:58:21 【问题描述】:

我已经使用 terraform aws 提供程序创建了一个 EC2 实例。实例是免费层 t2.micro 的 Ubuntu 服务器。

即使我遵循了所有关于网络 ACL、安全组、路由表、互联网网关的 Amazon 指南,我仍然无法执行简单的命令,例如

sudo apt-get update

当我从 ssh 端口 (22) 登录到我的实例并执行上面的 sudo 命令时,我收到此消息:

0% [连接到 us-east-2.ec2.archive.ubuntu.com (52.15.159.198)]

我关注的资源:

    https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/ec2-instance-connect-set-up.html?icmpid=docs_ec2_console#ec2-instance-connect-setup-security-group

    https://docs.aws.amazon.com/vpc/latest/userguide/VPC_Internet_Gateway.html#vpc-igw-internet-access

    https://docs.aws.amazon.com/vpc/latest/userguide/vpc-network-acls.html#nacl-rules

    https://docs.aws.amazon.com/vpc/latest/userguide/VPC_SecurityGroups.html#AddRemoveRules

还有很多 SO 问题。

请注意,我使用 ssh 连接到端口 22 并 ping ec2 实例的公共 IP。我还创建了一个路由表,其中有一个连接到网络接口的 Internet 网关。

网络规则:

安全组规则:

附加到我的实例的路由表

我唯一担心的是我使用的 vpc 有一个主 acl 网络(如默认),这不是我使用的那个(上面屏幕截图中具有许多规则的那个)。但是,主路由表会引导到正确的子网,该子网也连接到正确的 acl 网络。我猜这是因为在 terraform 中我使用 aws_network_acl 资源而不是 aws_default_network_acl

因此,我唯一担心的可能是我的 vpc 连接了错误的 acl 网络,但即使该 acl 网络允许所有入站 - 出站流量。所以访问http不应该带来问题。由于我无法从我的 ec2 实例下载任何内容,我相信其他问题是我的问题的根源。

提前感谢任何帮助。

Terraform code

【问题讨论】:

请不要使用图片。 您认为可以发布您使用的 Terraform 代码吗? @MarkoE 是的,我知道它变成了 TLDR,我会保留那张纸条。 一般来说,在出站安全组上“全部允许”是个好主意,因为您应该信任在实例上运行的软件。保留 NACL(入站和出站)上的默认“全部允许”设置也是一个好主意,除非您有非常特定的安全需求(例如创建 DMZ)。正是这些配置中的一种或两种配置阻止了您的命令完成所需的出站连接。 您的出站安全组规则屏幕截图仅显示列出的某些端口。 每个端口上的默认值通常是“全部允许”。这对于一些使用多个端口范围的服务(例如 FTP)很有用。您可以连接到实例,但实例在向外连接时遇到问题,这表明问题出在出站安全组或 NACL 中。 【参考方案1】:

安全组是有状态的。这意味着如果允许一个方向的流量,则允许返回响应返回。例如,您可以打开端口 80 到入站流量,然后即使安全组中没有出站规则,Web 服务器也可以响应请求。

相比之下,网络访问控制列表 (NACL) 是无状态的。这意味着向一个方向发送请求不会自动允许向另一个方向作出响应。

当向 Internet 向 Web 服务器发出 Web 请求时,它会转到远程服务器上的端口 80。但是,返回流量来自端口 80。相反,您对远程端口 80 的请求来自您自己计算机上的随机端口。因此,NACL 必须允许返回到该随机端口的流量。这可能是阻止响应您下载软件的网络请求的原因。

我以前觉得这个概念很难理解。我一直认为端口 80 的请求必须来自来自我的端口 80。但这不是它的工作原理。对 Internet 的 Web 请求永远不会来自端口 80,因为该端口与该计算机上的 Web 服务器相关联。这实际上是有道理的,因为例如,假设计算机 A 在 Web 浏览器中打开两个选项卡并向 google.com:80facebook.com:80 发送请求。每个服务器的返回流量需要返回到不同的端口,以便浏览器知道在每个选项卡中显示哪个响应。

是的,打开所有 NACL 端口是安全的。在传统网络中,安全性仅在子网之间的路由器中实施。这种安全性反映在 NACL 中。但是,云通过使用安全组来提供额外的安全层,这些安全组分别充当每个资源上的防火墙。这比传统的网络安全更强大。因此,在 NACL 级别允许所有流量是很正常的,除非您有非常特定的安全需求,例如创建 DMZ 或阻止进入网络的特定类型的流量。

【讨论】:

非常感谢您的详细回答以及对我的问题的回复。简而言之,我的最终解决方案允许所有流量用于我的 ACL 网络中的入站和出站路由。并且 80 http 流量仅用于安全组的出站路由。安全组的入站规则仅包括来自我的两个显式 IP 地址的 SSH 流量。

以上是关于无法与我的 EC2 实例建立 Internet 连接 [使用 terraform 部署,并为 ACL、安全组、Internet GW 打开了 80 个 http 端口]的主要内容,如果未能解决你的问题,请参考以下文章

如何查看哪些 EC2 实例与我的 Elastic Beanstalk 应用程序相关联?

无法从 EC2 实例连接到 RDS 实例

无法连接到 EC2 上的 cassandra 服务器?

无法连接到端口 8080 上的 EC2 Windows 实例

无法从私有子网中的实例连接到 Internet

在将ssh尝试到实例时关闭AWS EC2连接