Spring Fargate 无法连接到 AWS SES

Spring on Fargate can't connect to AWS SES

我正在尝试通过我 运行 在 Fargate 容器上的 Java 应用程序发送电子邮件。我的容器 运行 在 API 网关后面的 VPC 中,与外部服务的连接是通过 VPC 端点建立的。

所有基础设施都是使用 Terraform 部署的。 Java 应用程序在本地运行正常,但在部署到 AWS 时却不行,所以我认为缺少一个配置。

Java 应用遵循此处的 AWS 指南:

https://docs.aws.amazon.com/ses/latest/dg/send-email-raw.html

以下是 Terraform 代码的一些 spinets:

# SECURITY GROUPS
resource "aws_security_group" "security_group_containers" {
  name   = "security_group_containers_${var.project_name}_${var.environment}"
  vpc_id = var.vpc_id

  ingress {
    protocol         = "-1"
    from_port        = 0
    to_port          = 0
    cidr_blocks      = ["0.0.0.0/0"]
    ipv6_cidr_blocks = ["::/0"]
    self             = true
  }

  egress {
    protocol         = "-1"
    from_port        = 0
    to_port          = 0
    cidr_blocks      = ["0.0.0.0/0"]
    ipv6_cidr_blocks = ["::/0"]
  }

  tags = {
    Name        = "security_group_containers_${var.project_name}_${var.environment}"
  }
}

resource "aws_security_group" "security_group_ses" {
  name        = "security_group_ses_${var.project_name}_${var.environment}"
  vpc_id      = var.vpc_id

  ingress {
    protocol    = "-1"
    from_port   = 0
    to_port     = 0
    cidr_blocks      = ["0.0.0.0/0"]
    ipv6_cidr_blocks = ["::/0"]
  }

  egress {
    protocol    = "-1"
    from_port   = 0
    to_port     = 0
    cidr_blocks = ["0.0.0.0/0"]
  }

  tags = {
    Name = "security_group_ses_${var.project_name}_${var.environment}"
  }
}

# VPC

resource "aws_vpc" "main" {
    cidr_block           = var.cidr
    enable_dns_support   = true
    enable_dns_hostnames = true
  }

resource "aws_subnet" "private_subnet" {
    vpc_id            = aws_vpc.main.id
    cidr_block        = var.private_subnets[0]
    availability_zone = "us-east-1b"

    tags = {
        Name= "private_subnet_${var.project_name}_${var.environment}"
    }
}


# VPC ENDPOINT
resource "aws_vpc_endpoint" "ses_endpoint" {
  security_group_ids  = [aws_security_group.security_group_ses]
  service_name        = "com.amazonaws.${var.aws_region}.email-smtp"
  vpc_endpoint_type   = "Interface"
  subnet_ids          = [aws_subnet.private_subnet.id]
  private_dns_enabled = true
  tags = {
    "Name" = "vpc_endpoint_ses_${var.project_name}_${var.environment}"
  }
  vpc_id = aws_vpc.main.id
}

如果缺少任何重要的服务,请告诉我,以便我添加。

如您所见,我保持所有流量畅通,因此 here 找到的解决方案对我不起作用。当应用程序尝试发送电子邮件时,出现以下错误:

software.amazon.awssdk.core.exception.SdkClientException: Unable to execute HTTP request: Connect to email.us-east-1.amazonaws.com:443 [email.us-east-1.amazonaws.com/52.0.170.238, email.us-east-1.amazonaws.com/54.234.96.52, email.us-east-1.amazonaws.com/34.239.37.81, email.us-east-1.amazonaws.com/18.208.125.60, email.us-east-1.amazonaws.com/52.204.223.71, email.us-east-1.amazonaws.com/18.235.72.5, email.us-east-1.amazonaws.com/18.234.10.182, email.us-east-1.amazonaws.com/44.194.249.132] failed: connect timed out

我认为我缺少一些使 java awssdk 使用 VPC 端点的配置。

编辑 01 - 添加执行策略:

arn:aws:iam::aws:policy/AmazonSESFullAccess

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Action": [
                "ses:*"
            ],
            "Resource": "*"
        }
    ]
}

arn:aws:iam::aws:policy/AmazonECS_FullAccess(太大)

arn:aws:iam::aws:policy/service-role/AmazonECSTaskExecutionRolePolicy

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Action": [
                "ecr:GetAuthorizationToken",
                "ecr:BatchCheckLayerAvailability",
                "ecr:GetDownloadUrlForLayer",
                "ecr:BatchGetImage",
                "logs:CreateLogStream",
                "logs:PutLogEvents"
            ],
            "Resource": "*"
        }
    ]
}

编辑 02 - 更改为使用 SMTP 库:

可以找到使用的代码here

SMTP 一切正常

您已经为 SES SMTP API 创建了一个 VPC 端点,但是您收到的错误消息 email.us-east-1.amazonaws.com:443 是针对 AWS SES 服务 API 的。可以看到两组APIs here。如果您在 Java 应用程序中使用 AWS SDK 与 SES 交互,则需要将 VPC 端点更改为 service_name = "com.amazonaws.${var.aws_region}.email"

如果您将 Java 应用程序配置为使用 SMTP(例如 JavaMail API),则您当前的端点配置将起作用。