我无法通过VPN将mysql客户端连接到RDS

时间:2019-08-31 12:10:33

标签: aws-lambda amazon-cloudformation amazon-rds serverless-framework openvpn

我一直在努力使用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}

2 个答案:

答案 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

我已经用最新的更改更新了要点。