Post

SMTP 테스트

SMTP 테스트

이메일 SMTP 발송 순서 및 테스트

이메일을 발송 할 수 있는 방법은 SMTP, POP3, IMAP 방식이 존재한다.
이 글에서는 SMTP 프로토콜을 이용해 발송하는걸 다룬다.
SMTP는 Simple Mail Transfer Protocol 의 약자이다.

큰 흐름은 아래와 같다.

  1. 수신자 이메일의 도메인을 통해 메일 수신서버(mx) 정보(IP 또는 도메인)를 알아온다.
  2. 수신 서버 IP 와 메일 표준 포트를 이용해 telnet으로 연결한다.
  3. 서버와 연결 되었다면 SMTP 표준 명령어들을 이용해 발신자-수신자-내용-종료 순으로 통신한다.
  4. 위 과정에서 수신 서버는 발신 서버가 발신자 도메인의 서버가 맞는지 검증한다.
  5. 수신 서버는 발신 서버의 검증이 올바르고 수신자 정보가 올바르며, 메일 내용에 문제가 없는지 등을 검사하여 수신자에게 전달해준다.


수신자 이메일로 메일 수신서버 알아오기

nslookup 을 통해 mx 레코드 조회 설정으로 수신자 도메인의 수신 서버 정보를 가져온다.
mx 레코드는 Mail Exchange 레코드를 뜻한다.


수신자 이메일의 도메인이 daum이라면 daum.net의 mx 서버 정보를 조회했을 때
mx2.hanmail.net, mx4.hanmail.net. mx1.hanmail.net, mx3.hanmail.net 총 4개가 조회됐다.
조회 결과는 IP가 나올 수도 있고 위처럼 도메인이 나올 수 도 있으며 한 개 또는 여러 개가 나올 수 있다.

수신 서버와 통신하기

mx 서버를 알았으니 이제 서버와 연결 후 메일을 전달해본다.

1
2
3
4
5
6
telnet {수신 MX 서버} {통신포트}

telnet mx2.hanmail.net 25
# 연결 시 아래와 같이 연결 성공 코드를 받는다.
# 메시지는 모두 다르나 통신에 사용되는 코드 중 세자리는 표준 규격이다.
220 dmail-rmail-pgvm40 ESMTP welcome to HanMail.Net(tm) ready

이때 통신 포트는 25 외에도 587도 존재한다.
다만 보안을 위해 존재하는 포트이기 때문에 오래된 메일 서버는 해당 포트로 서비스가 되지 않을 수 있기에 25번 포트를 이용했다.

1
2
3
4
5
6
7
8
9
10
11
12
13
EHLO {발신자 도메인}

EHLO naver.com
# 아래 응답 중 STARTTLS 가 존재하면 해당 명령어를 통해 보안 통신이 가능하다
250-dmail-rmail-pgvm40 Hello [210.206.96.219], pleased to meet you
250-SIZE 71680000
250-STARTTLS
250 ENHANCEDSTATUSCODES

STARTTLS
# tls를 이용한 보안 통신 시작을 요청한 뒤 성공 응답을 받을 수 있다.
# 단 현재 테스트하는 로컬은 기본적인 도메인 레코드 등록들이 되어있지 않아 TLS로는 통신이 불가능하다.
220 2.0.0 Go ahead

EHELO {발신자 도메인} 또는 HELO {발신자 도메인} 을 입력한다.
HELO 는 클라이언트가 자신을 식별하며, EHLO는 HELO의 확장판이다.
뒤에서 다루지만 최근 메일 시스템에서는 TLS통신을 권장하기 때문에 이제는 EHLO를 기본으로 시작한다.

EHLO로 시작 한 경우 응답 중 STARTTLS가 존재한다면 STARTTLS를 입력하여 tls 통신을 시작한다.

1
2
HELO naver.com
250 dmail-rmail-pgvm12 Hello [210.206.96.219], pleased to meet you

다만 cmd로 테스트 하는 경우에는 tls통신이 불가능 하므로 HELO 로 진행한다.

1
2
3
4
5
6
7
8
MAIL FROM: senderName<sender@naver.com>
# 발신자 정보를 전달 후 응답 받는다.
250 2.1.0 senderName<sender@naver.com>... Sender ok

RCPT TO: receiverName<receiver@daum.net>
# 수신자 정보를 전달 후 응답 받는다.
# 이때 수신자 정보가 올바르지 않으면 수신자가 올바르지 않다는 응답을 받을 수 있다.
250 2.1.5 receiverName<receiver@daum.net>... Recipient ok

위와 같이 발신자, 수신자 정보를 보낸다.

1
2
3
4
5
6
7
8
9
DATA
354 Enter mail, end with "." on a line by itself
# 아래와 같이 내용을 작성한다. 내용은 Mime 방식으로 인코딩 되어야한다.
hi hi
# 내용을 다 작성한 뒤 <Enter>(\r\n) 입력 후 마침표(.)를 입력해 내용의 끝을 알린다.
.
# 내용의 header가 올바르지 않아 오류가 난 모습이다.
# 내용 작성 시 header를 올바르게 작성 하며, mime 방식으로 인코딩 하면 정상적으로 메일이 발송될 것이다.
554 5.6.0 DHFR1 210.206.96.219: Message requires 'From' header

위와 같이 발송하고자 하는 내용을 작성할 수 있다.

1
2
3
4
5
QUIT
# 운영해보니 QUIT 에 대한 응답 코드는 정상이 아닐 경우가 존재했다.
# QUIT에 대한 응답 코드가 정상이 아니어도 내용이 정상적으로 전달되는 경우가 많아 QUIT의 응답 코드는 무시했다.
221 2.0.0 dmail-rmail-pgvm12 closing connection
Connection closed by foreign host.

이후 모든 통신의 종료를 알린다.

위 과정을 정리하면 아래와 같다.

1
2
3
4
5
6
7
8
9
> telnet {mxServer} 25
> EHELO {senderDomain}
> STARTTLS
> MAIL FROM: {senderName}<{senderMail}>
> RCPT TO: {receiverName}<{receiverMail}>
> DATA
> 내용 (MimeType 인코딩)
> .
> QUIT



응답 코드

매 통신마다 응답 코드를 받는데 이 중
220, 221, 250, 354 코드만 정상 응답으로 취급한다.
단, QUIT 에 대한 응답 코드는 간혹 정상 통신에도 오류 코드가 응답 될때가 있어 무시한다.

본문 내용 작성

java MimeMessage 라이브러리를 이용해 mime 타입으로 인코딩하여 발송하여야한다.
기본적으로는 7bit ASCII 코드만이 전송이 가능하기 때문에 일반적인 binary는 전송이 불가능 하기 때문이다.

서비스 중 마주쳤던 문제들

기본적인 서버 레코드 등록

수신 서버는 발신 서버가 발신자의 도메인에 등록된 레코드 서버인지 확인하는 과정을 거친다.
(EHLO {도메인} 또는 HELO {도메인} 이때 조회하는 듯 하다.)
수신 서버를 조회하고 통신해서 메일을 발송하는건 어렵지 않다.
내가 테스트 서버를 하나 구축한 뒤 발신자 도메인을 공공기관 도메인으로 사칭하여 메일을 발송한다면 문제가 되기 때문이다.
때문에 수신 서버는 발신자의 도메인을 SPF, PTR 레코드로 조회하여 현재 통신하고있는 IP가 DNS에 등록되어 있는지 검증하고,
만약 존재하지 않는다면 메일을 아예 받아주지 않거나, 받아 주더라도 수신자에게 해당 메일이 검증된 IP에서 발송된 것이 아니므로 주의 하라고 표시해준다. (스팸함으로 직행하기도 한다.)

이를 방지하기 위해 메일 발송 이전에 SPF, PTR 레코드를 등록한다.

추가로 DKIM 서명이 되어있지 않아도 메일이 스팸함에 빠지거나 인증되지 않은 메일이라고 뜰 수 있다.

연결 횟수 초과로 인한 차단

초창기 발송 텀 조절 실패로 인해 다음 메일에 블랙 리스트로 등록된 적이 있었다.
서버의 공격을 막기 위해 보통 연결 횟수가 특정 횟수를 넘으면(ex. 0시간동안 00회 이상) 해당 IP를 블랙리스트로 올려 연결을 차단해버리는 듯 하다.
다음 메일에 문의하기를 통해 우리 발송 서버 IP의 블랙리스트 해제를 요청 한 뒤 이상하게 간헐적으로 발송에 실패하는 경우들이 생겼다.
해당 수신 서버 IP를 로깅하고 있었기에 서버 IP와 응답 값을 다시 문의 해 본 결과 블랙리스트 갱신이 제대로 되지 않은 서버가 존재하여 생기는 문제라는 답변을 받았다.
특정 서버만 갱신이 안된 상태라 우리쪽에서는 간헐적으로 생기는 문제로 보였던 것.

국내 대형 포털 화이트리스트 등록

국내 대형 포털은 kisa가 관리하는 화이트 리스트로 등록해 두면 대랑 메일 발송 시 오차단을 줄일 수 있었다.
그러나 확인해보니 해당 서비스는 2024년 6월 중단된 것으로 보인다.
https://spam.kisa.or.kr/spam/na/ntt/selectNttInfo.do?mi=1019&nttSn=2361&bbsId=1001

스팸 등록으로 인한 발송 불가 또는 스팸메일 분류

스팸 하우스라는 사이트에서 스팸 의심 IP 또는 도메인을 블랙리스트로 관리한다.
메일 수신 서버에서는 자체적인 블랙리스트 외 기본적으로 이 사이트의 블랙리스트를 조회하는 듯 히다.
때문에 스팸으로 인한 차단 오류 코드가 지속적으로 조회 될 경우 아래 사이트에서 IP
또는 도메인을 검색하여 블랙리스트 목록에 존재하는지 확인이 필요하다.
https://check.spamhaus.org/

이 스팸하우스에 등록되는 분류는 SBL, PBL, XBL 등 다양한데,
단순 해제 요청만 클릭해도 되는 경우가 있는 반면
해당 도메인의 메일로 인증하여 블랙리스트 해제를 해야하는 경우도 있다.

즉시 해제되지 않으며, 스팸하우스 목록을 수신메일 시스템들이 재조회 하는데까지 시간이 좀 걸리기 때문에 이후 모니터링이 필요하다.

전송 실패 코드

통신 중 코드는 220, 550 등과 같이 첫번째 3자리 코드는 통일이나,
뒤의 상세 코드는 수신 메일 서버 별로 다르기도 하다.
ex. 220 x.x.x

아래 사이트에서 사이트별 코드를 상세 조회할 수 있다.
https://smtpfieldmanual.com/

내용 본문 잘림 현상

메일 내용이 [전체보기] 버튼으로 대체되며 html이 랜딩되지 못하고 텍스트 그대로 나오는 경우가 생겼다.
검색해 본 결과 gmail에서 구체적인 본문 사이즈를 언급하진 않은 듯 하지만,
메일 본문 용량이 102KB 를 넘어가면 자동으로 생기는 듯 하였다.

email 본문 내용에 이미지를 바이너리로 넣으면서 생긴 문제로 이미지를 업로드 된 link로 대체한 뒤 해결

그 외 본문 내용이 25MB로 제한된다는 얘기가 있기 때문에 첨부파일의 크기 또한 제한이 필요함.


메일 발송 점수 확인 및 테스트 사이트

아래 사이트에서 임시 수신 메일을 발급 받아 해당 서버로 SMTP 발송 테스트를 진행 할 수 있다.
발송 이후 사이트에서 버튼을 클릭하면 해당 메일에 대한 점수를 확인 할 수 있다.

https://www.mail-tester.com/
단 하루 3건만 무료로 발송 가능, 이외의 다른 메일 검증 사이트들이 존재하나 아래와 같이 간단하게 테스트 했을 땐 수신 되지 않는 듯 하다.



This post is licensed under CC BY 4.0 by the author.