1

什么应该是适当的安全组规则以允许附加到单个 SecurityGroup 的所有 EC2 实例使用它们的 ElasticIP 而不是它们的 PrivateIP 相互通信

在此处输入图像描述

上图说明 我在AmazonVPC中有一个公共子网。该子网有 3 个或更多 EC2 实例:DevOps 实例、PHP 实例、Python 实例等。DevOps 实例附加到 2 个安全组 SG1 和 SG2。PHP/Python 实例仅附加到 1 个安全组 SG2。鉴于表中所示的 SG1 & SG2 规则: DevOps 实例只能通过 SSH 端口:22 从世界访问;PHP/Python 实例只能通过 HTTP 端口:80 从世界访问;只能从附加到同一安全组的所有 EC2 实例访问所有 DevOps/PHP/Python 实例中的所有端口。

用例:我想使用其 ElasticIP 9.8.7.1 从 Internet SSH 到 DevOps 实例。然后从 DevOps 实例,我想使用他们的 ElasticIP 9.8.7.2 / 9.8.7.3(不使用他们的 PrivateIP)通过 SSH 连接到 PHP/Python 实例。此外,我的 PHP 应用程序应该能够通过 ElasticIP 与 Python 应用程序通信,反之亦然——因为 ElasticIP 是我们在应用程序源代码中所拥有的。

问题 1:鉴于表中显示的安全组规则,目前我能够通过仅使用它们的 PrivateIP 而不是使用它们的 ElasticIP 从 DevOps 实例 SSH 到 PHP/Python 实例。

问题 2:我的 PHP/Python 实例也无法通过它们的 ElasticIP 相互通信。

约束:我们会定期从新的/更新的 AMI 为我们的 PHP/Python 应用程序启动新实例。每次我们启动一个新实例时,PrivateIP 都会发生变化。但我需要通过不变的东西(即 ElasticIP)进行定期通信。我们在 DevOps 实例中保留了一个 ~/.ssh/config 文件,以便轻松地通过 SSH 进入应用程序实例。在 ssh 配置文件中,我们将 ElasticIPs 保留为 PHP/Python/Other 实例的 IP 地址。每次将应用实例替换为新实例时,都无法将 ssh 配置文件中的 IP 地址更改为新的 PrivateIP 地址。

4

2 回答 2

4

最简单的解决方案是使用 IP 地址的主机名,而不是直接使用 IP 地址,因为 VPC 为您做了一些神奇的映射。

以这个弹性 IP 为例:

$ nslookup 203.0.113.50

50.113.0.203.in-addr.arpa       name = ec2-203-0-113-50.compute-1.amazonaws.com.

在同一 VPC 内部,此主机名不会解析回弹性 IP。相反,它解析为私有 IP。

$ nslookup  ec2-203-0-113-50.compute-1.amazonaws.com.

Name:   ec2-203-0-113-50.compute-1.amazonaws.com.
Address: 172.31.10.25 # returns the private IP of the attached instance

然而,从 VPC 外部,它的解析更像您所期望的:

$ nslookup ec2-203-0-113-50.compute-1.amazonaws.com.

Name:   ec2-203-0-113-50.compute-1.amazonaws.com.
Address: 203.0.113.50 # returns the elastic IP

然后,通过扩展,如果您要配置 DNS CNAMEdevops.example.com 指向 devops 机器的弹性地址的主机名,如果您从外部访问它,您将获得外部 IP,但如果您访问,则获得内部 IP它在内部。

由于内部请求将使用私有 IP,因此不需要异常的安全组配置。

额外的动机:如果您将实例配置为使用同一可用区内的弹性 IP 进行通信,您需要为离开 VPC 并返回的流量付费,每个方向 0.01 美元/GB,但在使用私有 IP 时则不需要。请参阅数据传输定价。可能差异是因为您使用更多的 AWS 网络硬件来转换和重新转换流量,当您使用弹性 IP 时,流量会遍历 Internet 网关两次。

上面的示例是我网络中的一个真实示例,我的 EIP 替换为RFC-5737中的占位符。

于 2015-10-28T17:51:57.777 回答
0

1) 您可以手动为 SG2 添加入站规则,例如:1) AllPorts EIP1 2) AllPorts EIP2

2) 对脚本执行以下操作:
使您的脚本使用 aws cli 或 API 获取安全组中的实例。
示例:
aws ec2 describe-instances --filter "Name=instance.group-name,Values=SG2"

这将获得安全组 SG2 中的所有实例。将实例 ID 保存在名为 SG2_Instances 的字典中。

然后运行:aws ec2 describe-addresses。
这将为每个弹性 IP 提供相应的字段,包括实例 ID(如果关联)。将所有实例 ID 与 EIP 一起放在一个列表中。该列表将如下所示:
[(EIP1, instanceId1), (EIP2,InstanceId2),..]。
现在遍历列表并检查列表中的 instanceId 是否存在于您的 dict SG2_Instances 中。如果是,那么您可以使用相应的 EIP 添加如 1) 中所述的规则。

于 2015-10-28T14:16:31.553 回答