如何允许附加到单个 SecurityGroup 的所有 EC2 实例使用它们的 ElasticIP 而不是它们的 PrivateIP 相互通信

How to allow all EC2 instances attached to a single SecurityGroup to talk to each other using their ElasticIPs instead of their PrivateIPs

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

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

用例: 我想使用 ElasticIP 9.8.7.1 从互联网通过 SSH 连接到 DevOps 实例。然后我想从 DevOps 实例使用他们的 ElasticIPs 9.8.7.2 / 9.8.7.3(不使用他们的 PrivateIPs)通过 SSH 进入 PHP/Python 实例。此外,我的 PHP 应用程序应该能够通过 ElasticIP 与 Python 应用程序通信,反之亦然 - 因为 ElasticIPs 是我们应用程序源代码中的内容。

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

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

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

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 描述地址。
这将为每个弹性 ip 提供相应的字段,包括实例 ID(如果关联)。将所有实例 ID 与 EIP 一起放入列表中。该列表将如下所示:
[(EIP1, instanceId1), (EIP2,InstanceId2),..].
现在遍历列表并检查列表中的 instanceId 是否存在于您的字典中 SG2_Instances。如果是,那么您可以使用相应的EIP添加1)中提到的规则。

最简单的解决方案是使用 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 CNAME devops.example.com 指向 devops 机器的弹性地址的主机名,你将获得外部 IP 如果你访问它在外部,但如果您在内部访问它,则为内部 IP。

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

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

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