【问题标题】:Unable to connect to AWS Keyspaces from a Lambda in a VPC无法从 VPC 中的 Lambda 连接到 AWS Keyspaces
【发布时间】:2021-01-07 20:37:37
【问题描述】:

我已按照说明 here 并创建了我认为我需要使用 Terraform 的基础架构。但是,尝试连接时出现此错误:

{
  "errorType": "AggregateException",
  "errorMessage": "One or more errors occurred. (All hosts tried for query failed (tried 172.31.41.121:9142: AuthenticationException 'The remote certificate is invalid according to the validation procedure.'; 172.31.18.20:9142: AuthenticationException 'The remote certificate is invalid according to the validation procedure.'))",
  "stackTrace": [
    "at lambda_method(Closure , Stream , Stream , LambdaContextInternal )"
  ],
  "cause": {
    "errorType": "NoHostAvailableException",
    "errorMessage": "All hosts tried for query failed (tried 172.31.41.121:9142: AuthenticationException 'The remote certificate is invalid according to the validation procedure.'; 172.31.18.20:9142: AuthenticationException 'The remote certificate is invalid according to the validation procedure.')",
    "stackTrace": [
      "at Cassandra.Connections.Control.ControlConnection.Connect(Boolean isInitializing)",
      "at Cassandra.Connections.Control.ControlConnection.InitAsync()",
      "at Cassandra.Tasks.TaskHelper.WaitToCompleteAsync(Task task, Int32 timeout)",
      "at Cassandra.Cluster.Init()",
      "at Cassandra.Cluster.ConnectAsync(String keyspace)"
    ]
  },
  "causes": [
    {
      "errorType": "NoHostAvailableException",
      "errorMessage": "All hosts tried for query failed (tried 172.31.41.121:9142: AuthenticationException 'The remote certificate is invalid according to the validation procedure.'; 172.31.18.20:9142: AuthenticationException 'The remote certificate is invalid according to the validation procedure.')",
      "stackTrace": [
        "at Cassandra.Connections.Control.ControlConnection.Connect(Boolean isInitializing)",
        "at Cassandra.Connections.Control.ControlConnection.InitAsync()",
        "at Cassandra.Tasks.TaskHelper.WaitToCompleteAsync(Task task, Int32 timeout)",
        "at Cassandra.Cluster.Init()",
        "at Cassandra.Cluster.ConnectAsync(String keyspace)"
      ]
    }
  ]
}

我创建了一个aws_vpc_endpoint_service,所以我很惊讶这不起作用。

# Security group for resources that want to access Keyspaces from the VPC
resource "aws_security_group" "keyspaces_endpoint_vpc_access" {
  name   = "keyspaces-endpoint-access"
  vpc_id = aws_default_vpc.default.id
}

resource "aws_security_group" "keyspaces_endpoint" {
  name   = "keyspaces-endpoint"
  vpc_id = aws_default_vpc.default.id

  ingress {
    from_port       = 9142
    to_port         = 9142
    protocol        = "tcp"
    security_groups = [ aws_security_group.keyspaces_endpoint_vpc_access.id ]
  }
}

data "aws_vpc_endpoint_service" "keyspaces" {
  service = "cassandra"
}

resource "aws_vpc_endpoint" "keyspaces_endpoint" {
  vpc_id              = aws_default_vpc.default.id
  vpc_endpoint_type   = "Interface"
  service_name        = data.aws_vpc_endpoint_service.keyspaces.service_name
  security_group_ids  = [ aws_security_group.keyspaces_endpoint.id ]
  private_dns_enabled = true

  subnet_ids = [
    data.aws_subnet.selected.id,
    aws_default_subnet.subnet_a.id,
    aws_default_subnet.subnet_b.id
  ]

  policy  = <<EOF
      {
        "Statement": [
          {
            "Sid": "keyspaces-full-access",
            "Principal": "*",
            "Action": "cassandra:*",
            "Effect": "Allow",
            "Resource": "*"
          }
        ]
      }
    EOF
}

resource "aws_security_group" "my_func" {
  vpc_id      = aws_default_vpc.default.id

  egress {
    from_port   = 0
    to_port     = 65535
    protocol    = "tcp"
    cidr_blocks = [ "0.0.0.0/0" ]
  }

  lifecycle {
    create_before_destroy = true
  }
}

resource "aws_lambda_function" "my_func" {
  runtime          = "dotnetcore3.1"
  timeout          = 900
  memory_size      = 512

  # etc.

  vpc_config {
    subnet_ids         = [ data.aws_subnet.selected.id ]
    security_group_ids = [
      aws_security_group.my_func.id,
      aws_security_group.keyspaces_endpoint_vpc_access.id
    ]
  }
}

我在这里做错了什么?

【问题讨论】:

  • 尝试使用 DER 格式的 Amazon CA 根证书。使用 openssl openssl x509 -outform der -in AWSCA.pem -out your-cert.crt 将 pem 转换为 crt 或从此处下载 DER 格式证书。 amazontrust.com/repository/AmazonRootCA1.cer。不要忘记使用新的证书格式更新您的功能代码。 :-)
  • keyspaces_endpoint_vpc_access 安全组没有列出任何明确的egress 规则。 Terraform 是否为其提供默认的“所有出站”访问权限? (您可以在部署后通过查看安全组进行检查。)
  • @JohnRotenstein 似乎没有什么不同。
  • @SRATH 我尝试过使用.cer,但我得到了同样的错误

标签: amazon-web-services terraform terraform-provider-aws amazon-keyspaces


【解决方案1】:

问题在于 Lambda 代码中的 SSL 配置。

调用SetHostNameResolver 至关重要,但显然只有在 VPC 内部时:

    let sslOptions =
      SSLOptions()
        .SetCertificateCollection(certCollection)
        .SetHostNameResolver (fun _ -> sprintf "cassandra.%s.amazonaws.com" region)

【讨论】:

    猜你喜欢
    • 2020-03-02
    • 2017-10-12
    • 2020-11-22
    • 2020-08-08
    • 2018-10-20
    • 2019-11-02
    • 2021-08-11
    • 2021-06-10
    • 2019-11-08
    相关资源
    最近更新 更多