我一直在努力使用AWS RDS。因为我没有网络技能,也不喜欢它,所以所有网络配置的事情都让人感到非常痛苦。
我的目标是在RDS上创建我的mysql数据库,使其能够通过任何mysql客户端连接到它,运行我的SQL脚本来创建DB,并执行我的lambda将数据插入到该DB中。
所以
mysql客户端-> RDS(mysql)<-lambdas
它们都需要相互连接。
经过数周的研究,我们试图了解AWS周围的所有网络事物,并从一个地方复制另一个例子。
我有以下情况:
我的云形成模板中都有VPC,公共和私有子网,安全组,EIP,RDS和VPN。
我可以部署所有内容,一切似乎都正常。
我可以连接到我的VPN并ping我的EIP的专用IP。
但是我仍然无法将mysql客户端连接到我的RDS。因此,我无法运行我的SQL脚本,也无法测试我的lambda,以查看它们是否确实连接到了我的RDS。
这是我的配置的一部分,我想这可能与问题有关,但是正如您可以想象的那样,由于缺乏网络知识,这使工作变得更加困难。
我唯一想到的是VPN和RDS不是同一子网的一部分。
完整配置:https://gist.github.com/serraventura/ec17d9a09c706e7ace1fd3e3be9972aa
RouteTableDB始终仅连接到私有子网,而VPN(ec2)仅连接到公共子网。
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}
答案 0 :(得分:2)
您的RDS实例正在接受LambdaSecurityGroup在3306上的入站连接,这对于连接了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才能解决问题。
答案 1 :(得分:0)
我想对这个问题给出完整的答案,因为标题仅暗示了MySQL客户端无法连接RDS的问题。
在进行@hephalump更改的同时,我还不得不做两个更改,以使我的lambda能够连接到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 并添加新角色角色:LambdaRole 。
现在我需要将lambda添加到正确的安全组。
因此,我将提供程序上的VPC更改为:
vpc:
securityGroupIds:
- Ref: LambdaSecurityGroup
subnetIds:
- Ref: SubnetPrivate1
我已经用最新的更改更新了要点。