将无法从互联网访问的机器放置在公共子网中被认为是不好的做法,因为这种拓扑除了在逻辑上是错误的(面向互联网的子网中的私有实例)之外,还会将机器暴露在公共互联网上。
如果我们谈论的是内部环境,那么这非常适合。公共机器应该位于 DMZ 中,而私有机器应该位于单独的私有网络中并受到防火墙的保护。
但在 AWS 等云环境中,我们有安全组。因此,虽然在公共子网中拥有私有实例在逻辑上当然是错误的,但有没有客观的在 AWS 等云中不这样做的原因是什么?使用安全组隔离机器是否更不安全?
我之所以问这个问题,是因为在较小的环境中将所有机器放在公共子网中具有各种优势,例如:
- 降低成本,您可以使用现有的互联网网关来节省私有子网所需的 NAT 网关费用
- 允许来自互联网的流量到特定实例要容易得多。比如说,如果你想只允许某个外部供应商访问一台机器,你可以简单地在安全组中为特定 IP 添加一条规则,然后通过某种自动化方式使用指向机器公共 DNS 的 CNAME,或者使用动态域名解析。
- 从机器到机器的流量仍然在 AWS 内部,因此我仍然获得更低成本的优势。
- 我仍然可以进行 VPC 对等连接,因此如果我想连接到另一个帐户中的 VPC,仍然可以不通过公共互联网进行连接。
- 我可以有更具体的每个实例安全性
那么,虽然从逻辑上讲这是错误的,但有什么客观理由不这样做呢?
我们正在与一位同事进行这样的对话,当被问及为什么 EC2 实例不应该公开,我只是回答说这在逻辑上是错误的,而且容易造成更多的混乱,但我仍然怀疑为什么不应该这样做,这实际上是错误的做法。
以下是我发现的一些缺点:
- 每个网络接口的安全组限制为 5 个
- 如果公共 IP 是非静态的,则无需付费,但会与您拥有的机器数量绑定(每台机器只能有 1 个 IP)。但这个限制可以提高。
- IP 反弹有成本。似乎前 100 个 IP 是免费的,但是一旦超过该限制,每个 IP 刷新将收取 0.20 美元。
一些相关主题:
上述线程详细阐述了该主题,但除了安全隐患之外,没有提供足够的客观理由来解释为什么它是错误的(再次忽略了使用 Terraform 正确配置安全组以避免更多错误配置的事实)。
答案1
使用私有子网的原因之一是纵深防御。
例如,假设您有一个位于公共子网中的 EC2 服务器。一名初级管理员试图授予该实例端口 22 上的出站访问权限,以便它可以从 github 提取代码,但却意外打开了端口 22 的入站访问权限。现在,您在互联网上拥有一个受证书或用户名和密码保护的私有服务器。如果该实例位于私有子网中,则无关紧要,因为它无法从互联网访问。假设这是端口 443 而不是端口 22,则内部应用程序现在可能在互联网上。
总而言之,人都会犯错,因此采取多种保护措施来防止错误配置是一种很好的做法。
安全组的作用
本地服务器通常使用子网进行隔离。企业可能有数百或数千个子网。在 AWS 中,我认为这不是必需的,因为安全组可以履行部分职责。我仍然认为公共子网和私有子网很重要,但我倾向于使用安全组进行分层/角色划分。
例如,对于三层系统我将有以下内容:
- 负载均衡器位于公共子网中,具有自己的安全组。它只能访问 Web 服务器 SG。
- Web 服务器位于私有子网中,具有自己的安全组。它允许从负载均衡器 SG 进行访问,并且可以访问应用程序服务器 SG。
- 应用服务器位于私有子网中,拥有自己的安全组。它允许从 Web 服务器 SG 进行访问,并且可以访问 DB SG。
- DB 服务器位于私有子网中,具有自己的安全组。它允许从应用服务器 SG 进行访问,并且不允许传出访问。
在此设置中,我将有六个子网 - 三个公共子网和三个私有子网。