我无法通过 VPN 将 mysql 客户端连接到 RDS
I can't connect mysql client to RDS through VPN
我一直在努力使用 AWS RDS。所有网络配置的事情真的很痛苦,因为我没有网络技能,我也不喜欢它。
我的目标是在 RDS 上创建我的 mysql 数据库,以便能够通过任何 mysql 客户端连接到它,运行 我的 SQL 脚本来创建数据库并执行我的 lambda 以将数据插入此数据库。
所以,
mysql 客户端 --> RDS (mysql) <-- lambdas
它们都需要相互连接。
经过数周的研究试图了解 AWS 周围的所有网络事物,从一个地方到另一个地方复制示例。
我遇到了以下情况:
我有一个 VPC,public 和私有子网、安全组、EIP、RDS 和 VPN 都在我的云形成模板中。
我可以部署一切正常,似乎一切正常。
我可以连接到我的VPN并ping通我的EIP的私有IP。
但我仍然无法将我的 mysql 客户端连接到我的 RDS。所以,我无法 运行 我的 SQL 脚本,我也无法测试我的 lambda 以查看它们是否真的连接到我的 RDS。
这是我配置的一部分,我猜这可能与问题有关,但正如您想象的那样,我缺乏网络知识使它变得更加困难。
我唯一想到的是 VPN 和 RDS 不属于同一子网。
完整配置:https://gist.github.com/serraventura/ec17d9a09c706e7ace1fd3e3be9972aa
RouteTableDB 始终仅连接到私有子网,而 VPN (ec2) 仅连接到 public 子网。
SubnetRouteTableAssociationPrivateDB1:
Type: AWS::EC2::SubnetRouteTableAssociation
Properties:
RouteTableId:
Ref: RouteTableDB
SubnetId:
Ref: SubnetDBPrivate1
SubnetRouteTableAssociationPrivateDB2:
Type: AWS::EC2::SubnetRouteTableAssociation
Properties:
RouteTableId:
Ref: RouteTableDB
SubnetId:
Ref: SubnetDBPrivate2
SubnetRouteTableAssociationPrivate1:
Type: AWS::EC2::SubnetRouteTableAssociation
Properties:
RouteTableId:
Ref: RouteTableDB
SubnetId:
Ref: SubnetPrivate1
SubnetRouteTableAssociationPrivate2:
Type: AWS::EC2::SubnetRouteTableAssociation
Properties:
RouteTableId: !Ref RouteTableDB
SubnetId: !Ref SubnetPrivate2
RDS、VPN
RDSMySQL:
Type: AWS::RDS::DBInstance
Properties:
AllocatedStorage: ${self:custom.infra.allocatedStorage}
DBInstanceClass: ${self:custom.infra.dbInstanceClass}
Engine: ${self:custom.infra.engine}
DBInstanceIdentifier: ${self:custom.app.dbName}
DBName: ${self:custom.app.dbName}
MasterUsername: ${self:custom.app.dbUser}
MasterUserPassword: ${self:custom.app.dbPass}
DBSubnetGroupName:
Ref: myDBSubnetGroup
MultiAZ: ${self:custom.infra.multiAZ}
PubliclyAccessible: true
StorageType: gp2
VPCSecurityGroups:
- Ref: RDSSecurityGroup
DeletionPolicy: Delete
VPNEIP:
Type: AWS::EC2::EIP
Properties:
InstanceId:
Ref: VPNEC2Machine
Domain: vpc
VPNEC2Machine:
Type: AWS::EC2::Instance
Properties:
KeyName: ${self:custom.infra.ec2KeyPairName.${self:provider.region}}
ImageId: ${self:custom.infra.openVPNAMI.${self:provider.region}}
InstanceType: ${self:custom.infra.instanceType}
AvailabilityZone: ${self:provider.region}a
Monitoring: true
SecurityGroupIds:
- Ref: VPNSecurityGroup
SubnetId:
Ref: SubnetPublic1
Tags:
- Key: Name
Value: ${self:custom.companyName} OpenVPN ${self:provider.stage}
VPNRouteRecordSet:
Type: AWS::Route53::RecordSet
DependsOn:
- VPNEC2Machine
- VPNEIP
Properties:
HostedZoneName: ${self:custom.domains.base}.
Comment: Record for the VPN subdomain
Name: vpn-${self:provider.stage}.${self:custom.domains.base}.
Type: A
TTL: 60
ResourceRecords:
- Ref: VPNEIP
VPNSecurityGroup:
Type: AWS::EC2::SecurityGroup
Properties:
GroupDescription: Allow Access From machines to the VPN and Private Network
VpcId:
Ref: VPCStaticIP
SecurityGroupIngress:
- IpProtocol: tcp
FromPort: ${self:custom.app.dbPort}
ToPort: ${self:custom.app.dbPort}
CidrIp: 0.0.0.0/0
Description: 'Postgres Port'
- IpProtocol: tcp
FromPort: 22
ToPort: 22
CidrIp: 0.0.0.0/0
Description: 'SSH Port'
- IpProtocol: udp
FromPort: 1194
ToPort: 1194
CidrIp: 0.0.0.0/0
Description: 'OpenVPN Server Access Port'
- IpProtocol: tcp
FromPort: 443
ToPort: 443
CidrIp: 0.0.0.0/0
Description: 'OpenVPN HTTPS Admin Port'
- IpProtocol: tcp
FromPort: 943
ToPort: 943
CidrIp: 0.0.0.0/0
Description: 'OpenVPN Server Port'
Tags:
- Key: Name
Value: ${self:custom.companyName} VPN SG ${self:provider.stage}
您的 RDS 实例正在 3306 上接受来自 LambdaSecurityGroup 的入站连接,这对于任何附加了 LambdaSecurityGroup SG 的东西都很好,但您还需要允许来自您的 VPNSecurityGroup 的连接。
将您的 RDSSecurityGroupBlock 更改为如下所示,这应该允许您从 VPN 连接到 RDS:
RDSSecurityGroup:
Type: AWS::EC2::SecurityGroup
Properties:
GroupDescription: Allow My SQL access from lambda subnets
VpcId:
Ref: VPCStaticIP
SecurityGroupIngress:
- IpProtocol: tcp
FromPort: '3306'
ToPort: '3306'
SourceSecurityGroupId:
Ref: LambdaSecurityGroup
- IpProtocol: tcp
FromPort: '3306'
ToPort: '3306'
SourceSecurityGroupId:
Ref: VPNSecurityGroup
Tags:
- Key: Name
Value: RDSSecurityGroup
附带说明一下,VPNSecurityGroup 正在接受来自任何地方的 3306、22、1194、443、943 连接。这可能是有意为之,但考虑到这些是出于管理目的公开的,这不是最佳做法。您应该认真考虑将这些端口的 CidrIp 的范围限定为受信任的 CidrIp 源,以避免任何潜在的不必要的暴露。您还可以考虑从那里一起删除 3306 块,因为似乎没有必要在 VPN 本身上打开该端口。
编辑 根据 OP 的评论,除了上述之外,您还需要将 PubliclyAccessible 更改为 False 以解决问题。
我想给出问题的完整答案,因为标题暗示了 mysql 客户端无法连接 RDS 的问题。
随着@hephalump 的改变,我不得不做更多的两个改变来让我的 lambdas 连接到 RDS,现在我能够连接 mysql 客户端和 lambdas。
我必须为我的 lambda 表达式创建一个新的 IAM 角色
LambdaRole:
Type: AWS::IAM::Role
Properties:
Path: '/'
RoleName: LambdaRole
AssumeRolePolicyDocument:
Version: '2012-10-17'
Statement:
- Effect: Allow
Principal:
Service:
- lambda.amazonaws.com
Action: sts:AssumeRole
Policies:
- PolicyName: ec2LambdaPolicies
PolicyDocument:
Version: '2012-10-17'
Statement:
- Effect: Allow
Action:
- ec2:CreateNetworkInterface
- ec2:DescribeNetworkInterfaces
- ec2:DetachNetworkInterface
- ec2:DeleteNetworkInterface
Resource: "*"
- PolicyName: 'AllowInvoke'
PolicyDocument:
Version: '2012-10-17'
Statement:
- Effect: 'Allow'
Action: 'lambda:InvokeFunction'
Resource: '*'
ManagedPolicyArns:
- arn:aws:iam::aws:policy/service-role/AWSLambdaBasicExecutionRole
- arn:aws:iam::aws:policy/service-role/AWSLambdaVPCAccessExecutionRole
这里解决问题的重要一点似乎是:
ManagedPolicyArns:
- arn:aws:iam::aws:policy/service-role/AWSLambdaBasicExecutionRole
- arn:aws:iam::aws:policy/service-role/AWSLambdaVPCAccessExecutionRole
然后我不得不从我的提供商那里删除我的 iamRoleStatements 并添加新角色 role: LambdaRole.
现在我需要将我的 lambda 添加到正确的安全组。
因此,我将供应商上的 VPC 更改为:
vpc:
securityGroupIds:
- Ref: LambdaSecurityGroup
subnetIds:
- Ref: SubnetPrivate1
我已经用最新的更改更新了要点。
我一直在努力使用 AWS RDS。所有网络配置的事情真的很痛苦,因为我没有网络技能,我也不喜欢它。
我的目标是在 RDS 上创建我的 mysql 数据库,以便能够通过任何 mysql 客户端连接到它,运行 我的 SQL 脚本来创建数据库并执行我的 lambda 以将数据插入此数据库。
所以,
mysql 客户端 --> RDS (mysql) <-- lambdas
它们都需要相互连接。
经过数周的研究试图了解 AWS 周围的所有网络事物,从一个地方到另一个地方复制示例。
我遇到了以下情况:
我有一个 VPC,public 和私有子网、安全组、EIP、RDS 和 VPN 都在我的云形成模板中。
我可以部署一切正常,似乎一切正常。
我可以连接到我的VPN并ping通我的EIP的私有IP。
但我仍然无法将我的 mysql 客户端连接到我的 RDS。所以,我无法 运行 我的 SQL 脚本,我也无法测试我的 lambda 以查看它们是否真的连接到我的 RDS。
这是我配置的一部分,我猜这可能与问题有关,但正如您想象的那样,我缺乏网络知识使它变得更加困难。
我唯一想到的是 VPN 和 RDS 不属于同一子网。
完整配置:https://gist.github.com/serraventura/ec17d9a09c706e7ace1fd3e3be9972aa
RouteTableDB 始终仅连接到私有子网,而 VPN (ec2) 仅连接到 public 子网。
SubnetRouteTableAssociationPrivateDB1:
Type: AWS::EC2::SubnetRouteTableAssociation
Properties:
RouteTableId:
Ref: RouteTableDB
SubnetId:
Ref: SubnetDBPrivate1
SubnetRouteTableAssociationPrivateDB2:
Type: AWS::EC2::SubnetRouteTableAssociation
Properties:
RouteTableId:
Ref: RouteTableDB
SubnetId:
Ref: SubnetDBPrivate2
SubnetRouteTableAssociationPrivate1:
Type: AWS::EC2::SubnetRouteTableAssociation
Properties:
RouteTableId:
Ref: RouteTableDB
SubnetId:
Ref: SubnetPrivate1
SubnetRouteTableAssociationPrivate2:
Type: AWS::EC2::SubnetRouteTableAssociation
Properties:
RouteTableId: !Ref RouteTableDB
SubnetId: !Ref SubnetPrivate2
RDS、VPN
RDSMySQL:
Type: AWS::RDS::DBInstance
Properties:
AllocatedStorage: ${self:custom.infra.allocatedStorage}
DBInstanceClass: ${self:custom.infra.dbInstanceClass}
Engine: ${self:custom.infra.engine}
DBInstanceIdentifier: ${self:custom.app.dbName}
DBName: ${self:custom.app.dbName}
MasterUsername: ${self:custom.app.dbUser}
MasterUserPassword: ${self:custom.app.dbPass}
DBSubnetGroupName:
Ref: myDBSubnetGroup
MultiAZ: ${self:custom.infra.multiAZ}
PubliclyAccessible: true
StorageType: gp2
VPCSecurityGroups:
- Ref: RDSSecurityGroup
DeletionPolicy: Delete
VPNEIP:
Type: AWS::EC2::EIP
Properties:
InstanceId:
Ref: VPNEC2Machine
Domain: vpc
VPNEC2Machine:
Type: AWS::EC2::Instance
Properties:
KeyName: ${self:custom.infra.ec2KeyPairName.${self:provider.region}}
ImageId: ${self:custom.infra.openVPNAMI.${self:provider.region}}
InstanceType: ${self:custom.infra.instanceType}
AvailabilityZone: ${self:provider.region}a
Monitoring: true
SecurityGroupIds:
- Ref: VPNSecurityGroup
SubnetId:
Ref: SubnetPublic1
Tags:
- Key: Name
Value: ${self:custom.companyName} OpenVPN ${self:provider.stage}
VPNRouteRecordSet:
Type: AWS::Route53::RecordSet
DependsOn:
- VPNEC2Machine
- VPNEIP
Properties:
HostedZoneName: ${self:custom.domains.base}.
Comment: Record for the VPN subdomain
Name: vpn-${self:provider.stage}.${self:custom.domains.base}.
Type: A
TTL: 60
ResourceRecords:
- Ref: VPNEIP
VPNSecurityGroup:
Type: AWS::EC2::SecurityGroup
Properties:
GroupDescription: Allow Access From machines to the VPN and Private Network
VpcId:
Ref: VPCStaticIP
SecurityGroupIngress:
- IpProtocol: tcp
FromPort: ${self:custom.app.dbPort}
ToPort: ${self:custom.app.dbPort}
CidrIp: 0.0.0.0/0
Description: 'Postgres Port'
- IpProtocol: tcp
FromPort: 22
ToPort: 22
CidrIp: 0.0.0.0/0
Description: 'SSH Port'
- IpProtocol: udp
FromPort: 1194
ToPort: 1194
CidrIp: 0.0.0.0/0
Description: 'OpenVPN Server Access Port'
- IpProtocol: tcp
FromPort: 443
ToPort: 443
CidrIp: 0.0.0.0/0
Description: 'OpenVPN HTTPS Admin Port'
- IpProtocol: tcp
FromPort: 943
ToPort: 943
CidrIp: 0.0.0.0/0
Description: 'OpenVPN Server Port'
Tags:
- Key: Name
Value: ${self:custom.companyName} VPN SG ${self:provider.stage}
您的 RDS 实例正在 3306 上接受来自 LambdaSecurityGroup 的入站连接,这对于任何附加了 LambdaSecurityGroup SG 的东西都很好,但您还需要允许来自您的 VPNSecurityGroup 的连接。
将您的 RDSSecurityGroupBlock 更改为如下所示,这应该允许您从 VPN 连接到 RDS:
RDSSecurityGroup:
Type: AWS::EC2::SecurityGroup
Properties:
GroupDescription: Allow My SQL access from lambda subnets
VpcId:
Ref: VPCStaticIP
SecurityGroupIngress:
- IpProtocol: tcp
FromPort: '3306'
ToPort: '3306'
SourceSecurityGroupId:
Ref: LambdaSecurityGroup
- IpProtocol: tcp
FromPort: '3306'
ToPort: '3306'
SourceSecurityGroupId:
Ref: VPNSecurityGroup
Tags:
- Key: Name
Value: RDSSecurityGroup
附带说明一下,VPNSecurityGroup 正在接受来自任何地方的 3306、22、1194、443、943 连接。这可能是有意为之,但考虑到这些是出于管理目的公开的,这不是最佳做法。您应该认真考虑将这些端口的 CidrIp 的范围限定为受信任的 CidrIp 源,以避免任何潜在的不必要的暴露。您还可以考虑从那里一起删除 3306 块,因为似乎没有必要在 VPN 本身上打开该端口。
编辑 根据 OP 的评论,除了上述之外,您还需要将 PubliclyAccessible 更改为 False 以解决问题。
我想给出问题的完整答案,因为标题暗示了 mysql 客户端无法连接 RDS 的问题。
随着@hephalump 的改变,我不得不做更多的两个改变来让我的 lambdas 连接到 RDS,现在我能够连接 mysql 客户端和 lambdas。
我必须为我的 lambda 表达式创建一个新的 IAM 角色
LambdaRole:
Type: AWS::IAM::Role
Properties:
Path: '/'
RoleName: LambdaRole
AssumeRolePolicyDocument:
Version: '2012-10-17'
Statement:
- Effect: Allow
Principal:
Service:
- lambda.amazonaws.com
Action: sts:AssumeRole
Policies:
- PolicyName: ec2LambdaPolicies
PolicyDocument:
Version: '2012-10-17'
Statement:
- Effect: Allow
Action:
- ec2:CreateNetworkInterface
- ec2:DescribeNetworkInterfaces
- ec2:DetachNetworkInterface
- ec2:DeleteNetworkInterface
Resource: "*"
- PolicyName: 'AllowInvoke'
PolicyDocument:
Version: '2012-10-17'
Statement:
- Effect: 'Allow'
Action: 'lambda:InvokeFunction'
Resource: '*'
ManagedPolicyArns:
- arn:aws:iam::aws:policy/service-role/AWSLambdaBasicExecutionRole
- arn:aws:iam::aws:policy/service-role/AWSLambdaVPCAccessExecutionRole
这里解决问题的重要一点似乎是:
ManagedPolicyArns:
- arn:aws:iam::aws:policy/service-role/AWSLambdaBasicExecutionRole
- arn:aws:iam::aws:policy/service-role/AWSLambdaVPCAccessExecutionRole
然后我不得不从我的提供商那里删除我的 iamRoleStatements 并添加新角色 role: LambdaRole.
现在我需要将我的 lambda 添加到正确的安全组。
因此,我将供应商上的 VPC 更改为:
vpc:
securityGroupIds:
- Ref: LambdaSecurityGroup
subnetIds:
- Ref: SubnetPrivate1
我已经用最新的更改更新了要点。