如何在 CloudFormation 中正确外部化 SecurityGroupEgress 和 SecurityGroupIngress
How correctly externalize SecurityGroupEgress and SecurityGroupIngress in CloudFormation
使用下面的 CloudFormation 模板,我可以通过 SSH 连接到 EC2 实例。
PublicSecurityGroup:
Type: AWS::EC2::SecurityGroup
Properties:
GroupName: PublicSecurityGroup
GroupDescription: Public Security Group
VpcId:
Ref: Vpc
SecurityGroupEgress:
- IpProtocol: "-1"
FromPort: 0
ToPort: 65535
CidrIp: 0.0.0.0/0
SecurityGroupIngress:
- IpProtocol: tcp
FromPort: 22
ToPort: 22
CidrIp: 0.0.0.0/0
PublicEc2Instance:
Type: AWS::EC2::Instance
Properties:
ImageId:
Ref: ImageId
InstanceType:
Ref: InstanceType
KeyName:
Ref: KeyName
SecurityGroupIds:
- Fn::GetAtt:
- PublicSecurityGroup
- GroupId
SubnetId:
Ref: PublicSubnet
Tags:
- Key: Name
Value: PublicEc2Instance
当我将 SecurityGroup
定义更改为以下结构时
PublicSecurityGroup:
Type: AWS::EC2::SecurityGroup
Properties:
GroupName: PublicSecurityGroup
GroupDescription: Public Security Group
VpcId:
Ref: Vpc
PublicOutboundRule1:
Type: AWS::EC2::SecurityGroupEgress
Properties:
GroupId: !Ref PublicSecurityGroup
SourceSecurityGroupId: !Ref PublicSecurityGroup
IpProtocol: "-1"
FromPort: 0
ToPort: 65535
PublicInboundRule1:
Type: AWS::EC2::SecurityGroupIngress
Properties:
GroupId: !Ref PublicSecurityGroup
SourceSecurityGroupId: !Ref PublicSecurityGroup
IpProtocol: tcp
FromPort: 22
ToPort: 22
我无法再在 EC2 实例中使用 SSH。
为什么 SecurityGroupEgress
和 SecurityGroupIngress
的外部化会阻止对 EC2 的 SSH 访问?
谢谢!
您将入口规则中的流量限制为以下行中的 PublicSecurityGroup
:
SourceSecurityGroupId: !Ref PublicSecurityGroup
而不是 SourceSecurityGroupId
指定您在上面的 yaml 片段中使用的 CIDR 块:
PublicSecurityGroup:
Type: AWS::EC2::SecurityGroup
Properties:
GroupName: PublicSecurityGroup
GroupDescription: Public Security Group
VpcId:
Ref: Vpc
PublicOutboundRule1:
Type: AWS::EC2::SecurityGroupEgress
Properties:
GroupId: !Ref PublicSecurityGroup
IpProtocol: "-1"
FromPort: 0
ToPort: 65535
CidrIp: 0.0.0.0/0
PublicInboundRule1:
Type: AWS::EC2::SecurityGroupIngress
Properties:
GroupId: !Ref PublicSecurityGroup
IpProtocol: tcp
FromPort: 22
ToPort: 22
CidrIp: 0.0.0.0/0
请注意,我也从您的 Egress 规则中删除了 SourceSecurityGroupId
,因为 Egress 规则不期望源,它们期望目的地(其他 SG、CIDR 块),因为它们就是出口 :)。
您没有在 AWS::EC2::SecurityGroup 和 AWS::EC2::SecurityGroupIngress/AWS::EC2::SecurityGroupEgress
之间建立正确的关系
在您的第一个描述中,您允许从任何位置访问 22 端口:
SecurityGroupIngress:
- IpProtocol: tcp
FromPort: 22
ToPort: 22
CidrIp: 0.0.0.0/0
但是在您的第二个定义中,您定义的是仅从同一安全组访问端口 22,因为参数 SourceSecurityGroupId 指定了允许访问的 Amazon EC2 安全组的 ID,而您希望从 0.0.0.0 授予访问权限/, 不一样:
SourceSecurityGroupId: !Ref PublicSecurityGroup
IpProtocol: tcp
FromPort: 22
ToPort: 22
您需要删除 SourceSecurityGroupId 参数
使用下面的 CloudFormation 模板,我可以通过 SSH 连接到 EC2 实例。
PublicSecurityGroup:
Type: AWS::EC2::SecurityGroup
Properties:
GroupName: PublicSecurityGroup
GroupDescription: Public Security Group
VpcId:
Ref: Vpc
SecurityGroupEgress:
- IpProtocol: "-1"
FromPort: 0
ToPort: 65535
CidrIp: 0.0.0.0/0
SecurityGroupIngress:
- IpProtocol: tcp
FromPort: 22
ToPort: 22
CidrIp: 0.0.0.0/0
PublicEc2Instance:
Type: AWS::EC2::Instance
Properties:
ImageId:
Ref: ImageId
InstanceType:
Ref: InstanceType
KeyName:
Ref: KeyName
SecurityGroupIds:
- Fn::GetAtt:
- PublicSecurityGroup
- GroupId
SubnetId:
Ref: PublicSubnet
Tags:
- Key: Name
Value: PublicEc2Instance
当我将 SecurityGroup
定义更改为以下结构时
PublicSecurityGroup:
Type: AWS::EC2::SecurityGroup
Properties:
GroupName: PublicSecurityGroup
GroupDescription: Public Security Group
VpcId:
Ref: Vpc
PublicOutboundRule1:
Type: AWS::EC2::SecurityGroupEgress
Properties:
GroupId: !Ref PublicSecurityGroup
SourceSecurityGroupId: !Ref PublicSecurityGroup
IpProtocol: "-1"
FromPort: 0
ToPort: 65535
PublicInboundRule1:
Type: AWS::EC2::SecurityGroupIngress
Properties:
GroupId: !Ref PublicSecurityGroup
SourceSecurityGroupId: !Ref PublicSecurityGroup
IpProtocol: tcp
FromPort: 22
ToPort: 22
我无法再在 EC2 实例中使用 SSH。
为什么 SecurityGroupEgress
和 SecurityGroupIngress
的外部化会阻止对 EC2 的 SSH 访问?
谢谢!
您将入口规则中的流量限制为以下行中的 PublicSecurityGroup
:
SourceSecurityGroupId: !Ref PublicSecurityGroup
而不是 SourceSecurityGroupId
指定您在上面的 yaml 片段中使用的 CIDR 块:
PublicSecurityGroup:
Type: AWS::EC2::SecurityGroup
Properties:
GroupName: PublicSecurityGroup
GroupDescription: Public Security Group
VpcId:
Ref: Vpc
PublicOutboundRule1:
Type: AWS::EC2::SecurityGroupEgress
Properties:
GroupId: !Ref PublicSecurityGroup
IpProtocol: "-1"
FromPort: 0
ToPort: 65535
CidrIp: 0.0.0.0/0
PublicInboundRule1:
Type: AWS::EC2::SecurityGroupIngress
Properties:
GroupId: !Ref PublicSecurityGroup
IpProtocol: tcp
FromPort: 22
ToPort: 22
CidrIp: 0.0.0.0/0
请注意,我也从您的 Egress 规则中删除了 SourceSecurityGroupId
,因为 Egress 规则不期望源,它们期望目的地(其他 SG、CIDR 块),因为它们就是出口 :)。
您没有在 AWS::EC2::SecurityGroup 和 AWS::EC2::SecurityGroupIngress/AWS::EC2::SecurityGroupEgress
之间建立正确的关系在您的第一个描述中,您允许从任何位置访问 22 端口:
SecurityGroupIngress:
- IpProtocol: tcp
FromPort: 22
ToPort: 22
CidrIp: 0.0.0.0/0
但是在您的第二个定义中,您定义的是仅从同一安全组访问端口 22,因为参数 SourceSecurityGroupId 指定了允许访问的 Amazon EC2 安全组的 ID,而您希望从 0.0.0.0 授予访问权限/, 不一样:
SourceSecurityGroupId: !Ref PublicSecurityGroup
IpProtocol: tcp
FromPort: 22
ToPort: 22
您需要删除 SourceSecurityGroupId 参数