AWS

AWS SES 사용하기

알쓸개잡 2023. 7. 31.
AWS SES (Amazon Simple Email Service) 란 (공식문서 인용)
Amazon 간편 이메일 서비스(SES)는 자신의 이메일 주소와 도메인을 사용하여 쉽고 비용 효율적인 방식으로 이메일을 주고받을 수 있는 이메일 플랫폼입니다.예를 들어 특별 행사 등의 마케팅 이메일, 주문 확인 등의 거래 이메일, 뉴스레터 등의 기타 유형의 서신을 보낼 수 있습니다. Amazon SES를 사용하여 메일을 수신하는 경우 이메일 자동 응답기, 이메일 수신 거부 시스템, 수신 이메일에서 고객 지원 티켓을 생성하는 애플리케이션과 같은 소프트웨어 솔루션을 개발할 수 있습니다.

 

SES 의 특징은 아래와 같다

  • SES 를 사용하여 이메일을 발송하려면 보낼 이메일 주소와 함께 도메인을 소유하고 있어야 한다.
  • SES 의 SMTP 를 통해 이메일이 발송되며 이메일을 보내는데 사용되는 자격증명(mail from 도메인) 은 AWS 리전 마다 고유하다.
  • 다른 AWS 리전의 확인된 자격증명에 대해 동일한 사용자 지정 MAIL FROM 도메인을 사용할 수 있다.
    • MAIL FROM 도메인의 DNS 서버에 하나의 MX 레코드만 게시하면 된다.

 

SES 이메일 발송 흐름은 아래와 같다.

출처: https://docs.aws.amazon.com/ses/latest/dg/send-email-concepts-process.html

 

 

AWS SES identity 계정 만들기

AWS SES 를 사용하기 위해서는 발송 도메인 혹은 발송 메일 계정에 대한 자격증명을 만들어 인증을 받아야 한다.

Amazon SES > Configuration: Verified identities > Create identity 로 이동하여 identity 를 생성한다.

SES Identity 등록 페이지

 

Domain 은 소유한 도메인을 입력하고, Email address 는 소유한 email 주소를 입력한다. Domain 은 지정된 도메인에 속한 어떠한 계정으로도 발송이 가능한 것으로 보여진다. (실제 Domain 으로 해보진 않음)

소유도메인이 route53 에 등록된 경우 DKIM 도메인 인증을 위한 TXT 레코드를 자동 등록하여 준다.

Email address 의 경우에는 소유한 도메인의 특정 email address 를 지정하면 해당 메일 주소로 확인 메일이 전송되어 검증절차를 거친 후 SES identity 로 등록이 된다.

 

SES 사용을 위한 IAM 계정 권한부여

ses 사용을 위해서는 IAM 계정에 사용 권한이 있어야 한다.

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

 

AWS SES 를 통해 메일을 보낼 때 제공해야 하는 이메일 정보는 SES 를 호출하는 방법에 따라 다르다.

  • SES API 를 직접 호출하는 경우 SendEmail 또는 SendRawEmail API 를 호출한다.
    • SendEmail
      • source address, destination address, subject, body 정보를 셋팅한다.
    • SendRawEmail

 

template 사용

https://docs.aws.amazon.com/ses/latest/dg/send-personalized-email-api.html 참조

본문의 내용은 고정된 형태이지만 수신자에 맞춰 일부 변경되어야 할 내용이 있는 경우에는 template 를 활용하는 것이 좋다.

 

템플릿은 JSON 형태로 제공한다.

{
  "Template": {
    "TemplateName": "test-template",
    "SubjectPart": "Greetings, {{name}}!",
    "HtmlPart": "<p>user email: {{customer-email}}</p><p>exipration date: {{expiration}}</p>",
    "TextPart": "user email: {{customer-email}}\nexipration date: {{expiration}}"
  }
}

위 json 파일명이 my-template.json 이라고 했을 때 AWS CLI 를 통한 템플릿 처리 명령은 아래와 같다. 템플릿명은 test-template

* aws ses 템플릿 리스트
aws ses list-templates

* aws ses 템플릿 등록
aws ses create-template --cli-input-json file://my-template.json

* 특정 ses 템플릿의 내용 보기
aws ses get-template --template-name test-template

* aws ses 템플릿 수정
aws ses update-template --cli-input-json file://my-template.json

* aws ses 템플릿 삭제
aws ses delete-template --template-name test-template

SES sdk 사용시 위 템플릿 json 예시로 지정된 {{name}}, {{customer-email}}, {{expiration}} 은 placeholder 역할을 한다.

{
    name: <이름>,
    customer-email: <고객이메일>,
    expiration: <만료날짜> 
}

와 같은 데이터를 셋팅하여 SES 호출해야 한다.

 

template 를 사용하는 경우 template 변환 실패시 SNS 를 통한 알림 받기

SES SDK 호출상 성공 리턴을 받았지만 SES 에서 발송 처리도중 template 변환이 실패한 경우 메일 발송이 안될 수 있다. template 변환이 실패했는지 여부를 확인하려면 SNS 토픽과 연결을 하여 메일 발송 결과에 대한 알림을 받도록 하는 것이 좋다.

  • SNS topic 생성 (fifo 형식은 지원하지 않음. Standard 로 생성)
  • SNS topic 에 subscription 생성. (수신 타입은 email 로 지정하고 endpoint 는 SNS 알림을 수신할 email 주소를 입력)
    • endpoint 로 지정된 email address 로 확인을 위한 메일이 전송된다.
  • SES configuration set 생성 및 SNS topic 연결
    • SES configuration set 은 이름만 지정하고 나머지는 default 로 사용
    • 생성된 configuration set 에서 Event destination 설정 진입 및 SNS topic 연결 설정

SES configuration 생성

  • SNS topic 에서 권한 설정
    • Access policy 로 이동 후 아래의 권한을 추가
{
  "Effect": "Allow",
  "Principal": {
    "Service": "ses.amazonaws.com"
  },
  "Action": "sns:Publish",
  "Resource": "<sns-topic-arn>",
  "Condition": {
    "StringEquals": {
      "AWS:SourceAccount": "<aws account id>",
      "AWS:SourceArn": "<ses configuration set arn>"
    }
  }
}

template 변환 실패시 SNS 를 통한 알림을 받기 위한 참고 문서는 아래 링크 참조

https://docs.aws.amazon.com/ses/latest/dg/monitor-using-event-publishing.html

https://docs.aws.amazon.com/ses/latest/dg/event-publishing-add-event-destination-sns.html

 

 

SES sandbox 에서 벗어나기

기본적으로 SES 는 sandbox 모드에서 동작하는데 이는 몇가지 제약사항이 있다.

  • 확인된 이메일 주소 및 도메인 또는 Amazon SES 사서함 시뮬레이터로만 메일을 보낼 수 있다.
  • 24시간 동안 최대 200개의 메시지를 보낼 수 있다.
  • 초당 최대 1건의 메시지를 보낼 수 있다.
  • 전송 권한이 있는 경우 본인이나 위임 보낸 사람 모두 인증되지 않은 이메일 주소로 이메일을 보낼 수 없다.
  • 계정 수준 차단의 경우 차단 목록 관리와 관련된 대량 작업 및 SES API 호출이 비활성화 된다.

예를 들어 서비스 제공자가 구독 가입 사용자에게 가입 알림 메일을 발송하는 경우 sandbox 모드의 경우에는 구독 가입 사용자의 메일 주소는 SES 의 identity 에 등록된 메일 주소가 아니기 때문에 수신자에게 메일을 발송 할 수 없다.

위와 같은 문제를 해결하기 위해서는 sandbox 모드를 벗어나야 하는데 이를 위해서는 AWS 측에 sandbox 모드 해제 요청을 한 뒤 AWS 로부터 승인을 받아야 한다. 이를 위해서는 AWS 지원담당자와 질의응답 과정을 몇 번 거쳐야 할 수 있다.

관련 기술문서 링크는 아래와 같다.

https://docs.aws.amazon.com/ses/latest/dg/request-production-access.html?icmpid=docs_ses_console

 

 

Office 365 에서 SES 로부터 전달된 메일이 정크메일로 분류되는 현상

  • AWS SES 를 통해서 메일이 발송될 때 Envelope From(Mail From) 의 도메인은 @amazonses.com 의 서브도메인 계정으로 발송된다.
  • 메일 원문의 헤더는 SES identity 에 등록된 address 혹은 domain 이 셋팅된다. ex) sender@test.ses.com
  • Office365 에서 정크메일로 분류된 메일의 헤더를 살펴보면 아래와 같은 헤더가 있다.
Authentication-Results-Original: spf=pass (sender IP is xx.xxx.xxx.xx)
smtp.mailfrom=ap-northeast-2.amazonses.com; dkim=pass (signature was verified)
header.d=amazonses.com; dmarc=none action=none
header.from=test.ses.com; compauth=fail reason=601
=================================================================
X-Forefront-Antispam-Report:
CIP:xx.xxx.xxx.xx; ..... CAT:SPOOF;SFS:;DIR:INB;

X-Forefront-Antispam-Report 헤더에서 CAT:SPOOF 라고 표시된 경우에는 송신자 인증과 관련된 것을 알 수 있다.

Envelope From 도메인(Mail From) 도메인 (ap-northeast-2.amazonses.com) 과 Header From 도메인 (test.ses.com) 도메인의 불일치로 인하여 Office 365 에서는 정크메일로 분류되는 경우라고 할 수 있다.

 

해결책은?

SES 에서 메일을 발송 할 때 Mail From 도메인을 변경하여 발송하도록 설정할 수 있다.

AWS 웹 콘솔에서 Amazon SES > Configuration > Verified Identities > Identity 선택

Custom MAIL FROM domain 설정의 Edit 버튼으로 설정 페이지로 진입 한다.

Custom MAIL FROM domain 설정 페이지

MAIL FROM domain 에는 예시에서 사용된 test.ses.com 의 subdomain 을 지정한다. ex) send.test.ses.com

설정 후 Custom MAIL FROM domain 섹션 항목 우측의 Publish DNS records to Route53 을 수행한다.

Publish DNS records to Route53 이 성공적으로 수행되면 지정된 MAIL FROM domain (send.test.ses.com) 에 대해서 MX, TXT 레코드가 route53 에 등록된다.

 

이후 SES 를 통해서 Office365 로 메일을 전송했을 때 정크메일로 분류되지 않은 메일에 대한 헤더를 살펴보면

Authentication-Results: spf=pass (sender IP is xx.xxx.xxx.xx)
smtp.mailfrom=send.test.ses.com; dkim=pass (signature was verified)
header.d=amazonses.com; dmarc=bestguesspass action=none
header.from=test.ses.com; compauth=pass reason=109
============================================================
X-Forefront-Antispam-Report:
CIP:xx.xxx.xxx.xx; ..... CAT:NONE;SFS:;DIR:INB;

와 같이 셋팅된다면 정상적으로 동작한 것이다.

 

위 기재된 도메인은 설명을 위한 가칭 도메인이다.


AWS SES SDK 사용 관련 참고 링크

https://docs.aws.amazon.com/ses/latest/dg/sdk-general-information-section.html

https://github.com/awsdocs/aws-doc-sdk-examples/tree/main/javav2/example_code/ses/src/main/java/com/example/sesv2

 

댓글

💲 추천 글