본문 바로가기

Other Service

[실습] Amazon SES와 postfix 통합하고, mailx 이용하여 메일 발송하기

반응형

안녕하세요 서후아빠입니다. ^_^
이번 세션은 Amazon SES(Simple Email Service)을 사용하는 방법에 대해서 실습해 보도록 하겠습니다. 메일 발송 프로세스는 mailx(CentOS 기준)을 사용하였고, postfix는 SES와 통합하여 Relay 역할을 수행하도록 구성하였습니다.

개발자가 송신 메일 서버를 코딩하는 경우는 SMTP 포트(587 or 25)를 사전에 정의하고, 1, 3단계만 진행한 후, 3단계에서 다운로드한 Credentials csv파일을 개발자에게 전달하기만 하면 됩니다. 만약 개발자가 SMTP 포트를 25를 사용한다고 하면 AWS Support에 Port 25 허용 요청을 별도로 진행해야 하기 때문에 가급적 협의하여 Port 25를 사용하지 않는 방향으로 진행하시기를 권고드립니다.


구성도

[Amazon SES와 postfix 통합하여 구성하는 경우]
[개발자 코딩하여 EC2를 송신 메일서버로 구성하는 경우]

1단계 : 샌드박스 해제

Amazon SES > Account dashboard > Request production access

Mail type Website URL Use case description Additional contacts Preferred contact language
Marketing (or Transactional) URL  입력 메일 발송 목록을 어떻게 작성하거나 만들 계획인가요? 서비스 DB에 등록된 관리자 대상으로 발송할 계획
반송 메일과 수신 거부를 어떻게 처리할 계획인가요? AWS의 SNS에 Topic을 생성하고 Topic에서 생성된 요청을 구독 취소와 연결해서 치리할 계획
수신자가 귀하가 보내는 이메일을 수신 거부하는 방법은 무엇입니까? 수신 거부를 할 수 있는 링크 제공 
이 요청에서 귀하가 지정한 송신률 또는 발신 할당량을 어떻게 선택하셨습니까? 송신률은 95% 생각하며, 발신 할당량은 하루에 500건 예상
admin@sample.com English (or Japanese)
Amazon SES는 샌드박스 환경에서 작동합니다.
 - 샌드박스 : 고객을 도용/침해 등으로부터 보호하고 ISP/이메일 수신자에게 신뢰를 줄 수 있도록 SES에서  제약사항 두는 것
 - 제약사항 예시 
   1) 인증된 메일주소로만 전송
   2) 하루 최대 200개 등
- 제약사항 및 해제에 대한 AWS 가이드 : https://docs.aws.amazon.com/ko_kr/ses/latest/dg/request-production-access.html 

Mail type 
- Marketing : 마케팅/홍보 콘텐츠 등을 고객에게 1:N 방식 전송 시 선택
- Transactional : 일반적인 사용자 작업(ex : 암호 재설정)으로 인한 1:1 방식 전송 시 선택

Website URL 
- SES를 사용하는 서비스에 대한 URL 입력 (AWS에서 접속하여 검토하기 위함)

Additional contacts : AWS와 소통하기 위한 담당자 메일 주소 (최대 4개, 쉼표로 구분)

2단계 : 도메인 소유권 혹은 메일주소 확인

[도메인 소유권 확인하는 경우]

Amazon SES > Verified identities > Create identity 

Identity type Domain
Domain sample.com

Amazon SES > Verified identities > sample.com 선택 > Authentication(tab) > Publish DNS records에서 CNAME(3개) 복사

CNAE(3개) 예시
 - ocxy3._domainkey.sample.com / ocxy3.dkim.amazonses.com
 - 3cj5w._domainkey.sample.com / 3cj5w.dkim.amazonses.com
 - ibl4k._domainkey.sample.com / ibl4k.dkim.amazonses.com

복사한 3개의 내용을 관리중인 DNS 레코드에 등록 > 일정 시간 대기

Amazon SES > Verified identities > sample.com > Identity status컬럼에서 Verified 확인

sample.com이 Route 53에 등록된 경우는 레코드가 자동 등록되고, 즉시 인증까지 완료됨

[메일주소 확인하는 경우]

Amazon SES > Verified identities > Create identity 

Identity type Email address
Email address sender@sample.com
Email address receive@test.com

메일 로그인(sender@sample.com or receive@test.com) > 수신 메일 확인 > 링크 클릭 시 즉시 인증

제목 : Amazon Web Services – Email Address Verification Request in region Asia Pacific (Seoul)
링크 예시 : https://email-verification.ap-northeast-2.amazonaws.com/?Context=111111111111&X-Amz-Date=20230307T074100Z&Identity.IdentityName=sender@sample.com&X-Amz-Algorithm=AWS4-HMAC-SHA256&Identity.IdentityType=EmailAddress&X-Amz-SignedHeaders=host&X-Amz-Credential=AKI%2Fap-northeast-2%2Fses%2Faws4_request&Operation=ConfirmVerification&Namespace=Bacon&X-Amz-Signature=d0

샌드 박스 해제하지 않은 상태에서 메일 발송 테스트를 하기 위해서는 송신자, 수신자 모두 메일 인증을 받아야 합니다.

3단계 : SMTP 자격 증명

Amazon SES > SMTP Settings > Create My SMTP Credentials > IAM User Name (수동입력 or 빈칸으로 진행 시 자동생성) > Download Credentials

다운받은 Credentials 내용 예시
- IAM User Name : ses-smtp-user.20230307-144808
- Smtp Username : AKIA2Y
- Smtp Password : BEjSp2

Amazon SES > SMTP Settings > SMTP endpoint 확인 (ex : email-smtp.ap-northeast-2.amazonaws.com)

리전별로 SMTP endpoint가 다르므로 주의하시기 바랍니다.

4단계 : postfix 구성 (EC2 생성 및 SSH 접속 설명은 SKIP)

# postfix 설치 확인
rpm -qa postfix

# postfix 상태 확인
postfix-2.10.1-6.amzn2.0.3.x86_64
systemctl status postfix | grep Active
   Active: active (running) since Tue 2023-03-07 05:56:19 UTC; 5min ago

# postfix 구동 확인
systemctl list-unit-files -t service | grep postfix
postfix.service    enabled

# main.cf 설정 (리전에 맞게 입력)
sudo postconf -e "relayhost = [email-smtp.ap-northeast-2.amazonaws.com]:587" \
"smtp_sasl_auth_enable = yes" \
"smtp_sasl_security_options = noanonymous" \
"smtp_sasl_password_maps = hash:/etc/postfix/sasl_passwd" \
"smtp_use_tls = yes" \
"smtp_tls_security_level = encrypt" \
"smtp_tls_note_starttls_offer = yes"

# master.cf 설정 (-o smtp_fallback_relay= 항목은 주석 처리)
sudo cat /etc/postfix/master.cf | grep "smtp_fallback_relay"

# sasl_passwd 입력 ([SMTP endpoint]:Smtp_Port Smtp_Username:Smtp_Password)
sudo vi /etc/postfix/sasl_passwd
[email-smtp.ap-northeast-2.amazonaws.com]:587 AKIA2Y:BEjSp2

# sasl_passwd 해시 처리
sudo postmap hash:/etc/postfix/sasl_passwd 

# sasl_passwd 파일 확인
ls -1 /etc/postfix/sasl_passwd*
/etc/postfix/sasl_passwd
/etc/postfix/sasl_passwd.db

# sasl_passwd 권한 조정
sudo chown root:root /etc/postfix/sasl_passwd /etc/postfix/sasl_passwd.db
sudo chmod 0600 /etc/postfix/sasl_passwd /etc/postfix/sasl_passwd.db

# sasl_passwd 권한 조정 결과 확인
ls -l /etc/postfix/sasl_passwd*
-rw------- 1 root root   111 Mar  7 06:24 /etc/postfix/sasl_passwd
-rw------- 1 root root 12288 Mar  7 06:33 /etc/postfix/sasl_passwd.db

# CA인증서 확인
ls /etc/ssl/certs/ca-bundle.crt
/etc/ssl/certs/ca-bundle.crt

# CA인증서 설정
sudo postconf -e 'smtp_tls_CAfile = /etc/ssl/certs/ca-bundle.crt'

# postfix 재구동
sudo postfix reload
postfix/postfix-script: refreshing the Postfix mail system
SMTP 포트를 587가 아닌 25로 설정하는 경우 EC2에서 아웃바운드 허용해달라고 AWS에 Support 요청을 해야 합니다.
AWS는 25포트에 대해서 EC2 아웃바운드는 무조건 막혀 있기 때문입니다.
조 : https://aws.amazon.com/ko/premiumsupport/knowledge-center/ec2-port-25-throttle/

송신 메일 서버에서 SMTP 포트가 587인지 25인지 확인하여 설정해야 합니다.
※ 사용 가능한 SMTP 포트 정보 확인 : Amazon SES > SMTP Settings > STARTTLS Port

6단계 : mailx 설치 및 메일 보내기

# mailx 설치 
sudo yum update -y
sudo yum install -y mailx

# 메일 보내기 
echo "Test Message" | mail -s "Test Subject" -r "sender@sample.com" receive@test.com

# 메일 로그 보기 (Smtp Username 혹은 Smtp Password가 틀린 경우)
sudo cat /var/log/maillog
Mar  8 04:15:48 ip-10-0-5-161 postfix/cleanup[2418]: 9E5614544E8: message-id=<20230308041548.9E5614544E8@ip-10-0-5-161.ap-northeast-2.compute.internal>
Mar  8 04:15:48 ip-10-0-5-161 postfix/qmgr[2238]: 9E5614544E8: from=<root@ip-10-0-5-161.ap-northeast-2.compute.internal>, size=532, nrcpt=1 (queue active)
Mar  8 04:15:49 ip-10-0-5-161 postfix/smtp[2420]: 9E5614544E8: SASL authentication failed; server email-smtp.ap-northeast-2.amazonaws.com[15.164.147.83] said: 535 Authentication Credentials Invalid
Mar  8 04:15:52 ip-10-0-5-161 postfix/smtp[2420]: 9E5614544E8: to=<receive@test.com>, relay=email-smtp.ap-northeast-2.amazonaws.com[52.78.161.94]:587, delay=3.4, delays=0.02/0.04/3.3/0, dsn=4.0.0, status=deferred (SASL authentication failed; server email-smtp.ap-northeast-2.amazonaws.com[52.78.161.94] said: 535 Authentication Credentials Invalid)

# 메일 로그 보기 (발신자 메일이 확인되지 않은 경우)
sudo cat /var/log/maillog
Mar  8 04:19:32 ip-10-0-5-161 postfix/cleanup[2457]: BC43F4544EF: message-id=<20230308041932.BC43F4544EF@ip-10-0-5-161.ap-northeast-2.compute.internal>
Mar  8 04:19:32 ip-10-0-5-161 postfix/qmgr[2449]: BC43F4544EF: from=<root@ip-10-0-5-161.ap-northeast-2.compute.internal>, size=532, nrcpt=1 (queue active)
Mar  8 04:19:33 ip-10-0-5-161 postfix/smtp[2459]: BC43F4544EF: to=<receive@test.com>, relay=email-smtp.ap-northeast-2.amazonaws.com[15.164.147.83]:587, delay=0.29, delays=0.02/0.02/0.12/0.13, dsn=5.0.0, status=bounced (host email-smtp.ap-northeast-2.amazonaws.com[15.164.147.83] said: 554 Message rejected: Email address is not verified. The following identities failed the check in region AP-NORTHEAST-2: root <root@ip-10-0-5-161.ap-northeast-2.compute.internal>... (in reply to end of DATA command))

# 메일 로그 보기 (정상 발송)
sudo cat /var/log/maillog
Mar  8 05:27:44 ip-10-0-5-161 postfix/cleanup[2890]: C3C9F406290: message-id=<64081cd0.Q6/Mc7gLgDLJT8s/%sender@sample.com>
Mar  8 05:27:44 ip-10-0-5-161 postfix/qmgr[2449]: C3C9F406290: from=<sender@sample.com>, size=459, nrcpt=1 (queue active)
Mar  8 05:27:45 ip-10-0-5-161 postfix/smtp[2892]: C3C9F406290: to=<receive@test.com>, relay=email-smtp.ap-northeast-2.amazonaws.com[52.78.161.94]:587, delay=0.29, delays=0.02/0.01/0.12/0.14, dsn=2.0.0, status=sent (250 Ok 010c0186bfb09048-70150c1a-6005-448a-9480-493eb98da3b9-000000)
mailx 옵션 : -s (메일 제목), -r (발신자 주소), -c (참조), -b (숨은 참조), -a (첨부파일)

[수신 메일 예시]

기타 : 반송 메일 대책

[Bounce rate]

Amazon SES > Reputation metrics > Account-level (tab) Bounce rate

구분 내용
용어 바운스 (Bounce) : 수신 메일서버에서 메시지를 거부하여 메일 전송이 완료되지 못하는 것
 - Soft bounce : 수신자 메일 사서함 Full 혹은 일시적으로 사용할 수 없는 경우
 - Hard bounce : 수신자 메일 주소가 유효하지 않는 경우 (ex : 계정 삭제, 스팸 처리)
이탈율 (Bounce rate) : Bounce (Soft, Hard) 횟수를 전송 횟수로 나눈 값, 일반적으로 10% 미만이 양호하다고 판단
지표 Warning : 그래프 하단 (5% 라인)
Account at risk : 그래프 상단 (10% 라인)

[SNS 알림]

Amazon SNS > Topics > Create topic (유형(표준), 이름(mytopic), 상세 설명은 SKIP)

Amazon SES > Verified identities >  sample.com 선택 (바운스 처리가 필요한 Identitie 선택) > Notifications (tab) >  Email feedback forwarding (Enabled) 확인

Amazon SES > Verified identities >  sample.com 선택 (바운스 처리가 필요한 Identitie 선택) > Notifications (tab) >  Feedback notifications > Edit 

Bounce feedback Complaint feedback Delivery feedback
mytopic - -
SNS 연결 구조는 https://sh-t.tistory.com/106 참고하시기 바랍니다.
반송 메일 이벤트를 통해 관리(ex : 수신자 메일 계정 발송 중지)를 하도록 합니다.

참조

Amazon SES와 postfix 통합 : https://docs.aws.amazon.com/ko_kr/ses/latest/dg/postfix.html

Amazon SES에서 반환하는 SMTP 응답 코드 : https://docs.aws.amazon.com/ko_kr/ses/latest/dg/troubleshoot-smtp.html

반응형