개인 프로젝트(혹은 매우 영세한 인디 및 스타트업)를 진행하다 보면, 프로젝트를 완성하기 위해서는 코드를 짜는 것 이외에도 해야 할 일이 많습니다. 그중 가장 큰 비중을 차지하는 것 중 하나가 인프라 구성입니다. 인프라 담당 따로, 개발 담당 따로가 존재하는 일반적인 회사와는 달리 이 모든 것을 본인이 책임져야 하는 경우가 종종 있고, 그러한 이유로, 전 인프라 세팅은 딱히 전문가는 아니지만, 서버 세팅을 종종 하곤 합니다…
이번에는 서버 요구 사항 중 하나가 메일 전송 기능입니다. 메일 전송은 잘 모르지만, 잘 알려진 SMTP 프로토콜이 있으니! 그걸 쓰면 쉽게 할 수 있겠구나 생각을 했습니다.
물론 쉽게 되는 일은 없고, 언제나 그렇듯 문제가 발생하는데… 이 문제의 원인을 추적해 본 내용을 정리한 게 주된 내용입니다.
SMTP 프로토콜로 메일 전송하기
하지만 메일 전송하는 일은 생각보다 복잡한 부분이 있습니다. 이는 클라이언트가 직접 메일을 전송하는 역할을 하지 않기 때문입니다.
SMTP 프로토콜에서 메일 전송이 이루어지는 과정을 보면,
이미지 출처: https://gona.tistory.com/65
- MUA(client) 에서 MTA로 메일을 전달함.
- MTA가 메일을 외부로 보낼지, 내부로 보낼지 결정함 ⇒ 내부 메일일 경우 MDA 에 보관
- 외부 메일인 것을 확인했다면, DNS의 MX 레코드를 가져오고, 해당 주소(도메인)으로 메일을 전달
e.g. test@abcd.com 이면, abcd.com의 MX 레코드를 가져옴
- 메일은 SMTP 프로토콜에 맞는 적절한 형태로 변환이 된다.
그리고 credential 정보가 필요하다면 메일서버가 이를 관리해주는 역할도 수행한다.
또한, 상대 측에서 프로토콜을 제대로 수신하지 못했을 경우, 필요하다면 재전송도 수행한다.
4. 수신자의 서버에서 전달받은 SMTP 프로토콜을 적절하게 잘 처리하여, 상대방이 메일을 확인할 수 있게 된다
이처럼 메일 관련하여 이런저런 작업이 필요하기 때문에, 어플리케이션에서 직접 메일을 보내는 것이 아니라, 클라이언트가 메일서버에 작업을 위임하는 방식으로 만들어져 있습니다.
흔히 쓰이는 간단한 메일 서버는 sendmail
이 있습니다. AWS linux가 deb/yum 을 사용하고 있으므로, 아래 명령어로 적절히 설치해 봅니다.
yum install sendmail sendmail-cf m4
vi /etc/mail/sendmail.mc
# 필요한 내용을 적절하게 수정 ...
systemctl start sendmail
SMTP 테스트 및 트러블슈팅
이제 실제 잘 보내지는지 테스트를 해 봅니다.
# check 25 port is opened by sendmail
netstat -nlp | grep sendmail
# connecting to 25 port
telnet localhost 25
# manually send mail
mail from: ..@test.com
rcpt to: ..@.....
data
subject: title
body
.
클라이언트상에서는 문제가 없는 것처럼 보이는데, 메일이 감감 무소식입니다. systemctl status sendmail
로 로그를 까보니 문제가 있습니다.
이미 25번 포트는 열어 놨는데도 메일이 안 날아갑니다. 가능성은 2가지입니다.
- 수신자측에서 특정 조건이 맞지 않은 관계로 메일을 씹어버림
- 가능성이 높지는 않습니다. 보통은 invalid request나 internal error 라도 답장을 보내주고, 아무리 상대 서버에서 연결을 거부한다 하더라도 연결을 그냥 끊고 말지 5분간 커넥션 미수락이다? 가능성이 거의 없습니다.
- 수신자측에서 SMTP 포트(25)를 막았거나, ISP 측에서 25 포트를 막아버림
후자를 확인하기 위해서 직접 텔넷으로 주어진 메일서버에 접속해 봅니다.
telnet 25 alt4.gmail-smtp-in.l.google.com
테스크탑에선 접속이 잘 되는데, AWS EC2 에서는 접속이 안 됩니다. 범인 발견! AWS에서 SMTP 프로토콜 사용을 막고 있던 것이었습니다. 25번 포트를 쓰려면 별도로 인가를 받아야 하는데, 스팸 방지를 위해 막은 것으로 보여, 대책없이 포트를 뚫어달라고 하는 것은 아무래도 좋은 방법이 아닌 것 같습니다.
정리하면
- sendmail 설치 완료하고, SMTP 프로토콜도 정상 작동을 확인함
- 하지만AWS ISP 측에서 port 25 제한중 ⇒ 스팸의 문제
- 따라서 587 / 465 포트를 이용하여 TLS/SSL 프로토콜로 이메일 전송해야 함
참고) 587 및 465 포트의차이: https://velog.io/@ragnarok_code/587번-포트와-465번-포트의-차이
따라서 TLS/SSL로 암호화하여 보내야 할 것 같습니다.
암호화된 이메일 보내기
방법은 2가지가 있습니다.
- 메일서버 자체에서 암호화 된 이메일을 보내도록 해야 함. (SMTPS 프로토콜)
- (메일을 보내는 서버 자체가 믿을 수 있는 서버인지를 검증하기 위함이다. 도메인도 없는 서버가 무턱대고 보내는 메일은 십중팔구 스팸일 테니.)
- https://www.sslcert.co.kr/guides/Sendmail-SSL-Certificate-Install
- 이메일 릴레이를 시켜야 함. (gmail 같은 서버에서 이메일을 날릴 수 있도록 해야 함)
- 임시로 회사 대표 계정 같은 것을 만들어서 할 수도 있을 것
- https://access.redhat.com/solutions/60803
그래서, 결국 도메인 세팅이 먼저 해야 할 일이 되었습니다. 역시 모든 사업은 시작하기 전에 도메인부터 사 놓아야 …
FYI: 이처럼 당장 이메일 서버를 사용할 수 없다면, 테스트가 어려울 수 있기 때문에, 정보 전달을 위한 다른 대안을 생각해야 할 수 있을 겁니다. (테스트 API 제공 등…)
'개발 > Infra' 카테고리의 다른 글
AWS 호스팅 및 메일 설정기 (0) | 2022.07.26 |
---|---|
terraform 경험기 (0) | 2022.07.18 |
AWS를 이용하여 클라우드 아키텍처 구성하기 (0) | 2022.05.08 |