SMTP(Simple Mail Transfer Protocol)는 메일을 보낼 때 사용하는 프로토콜이다. TCP/IP 모델에서 어플리케이션 계층에서 작동하는 프로토콜로, HTTP보다 더 오래된 역사 깊은 프로토콜이다.
보통의 경우 HTTP로 웹에 접속하여 메일을 보내기 때문에 직접 SMTP를 사용하여 메일을 보내는 경우는 없지만 자체적으로 메일 서버를 구축하거나 메일 송신이 필요한 프로그램을 개발할 때 사용한다.
이번에는 다음 메일에서 제공하는 기능을 이용해서 직접 메일을 보내보고자 한다.
1. 메일 보내기 테스트
파이썬의 aiosmtpd라는 테스트용 메일 디버깅 서버를 이용하여 SMTP 요청을 테스트해 볼 수 있다.
python3 -m aiosmtpd -n -l localhost:1025
우선 위 명령어로 테스트 서버를 띄운다.

그러면 위와 같이 커서가 깜박이는 상태로 대기하게 되는데 해당 터미널 창은 놔두고 새 터미널 창을 열어서 다음 명령어를 실행한다.
telnet localhost 1025
telnet은 간단한 연결 테스트에는 편하지만 암호화 지원을 하지 않기 때문에 실제 서비스 테스트에는 적합하지 않다. 요즘에는 SSL/TLS를 기본으로 요구하므로 telnet으로 접근하면 테스트가 불가능할 것이다.
지금은 로컬 환경의 테스트이기에 사용해도 괜찮다.
그런데 macOS에서는 telnet이 삭제되어 사용할 수 없는데 이 때는 다음 명령어를 사용하여 테스트한다.
nc -c localhost 1025
-c는 CRLF를 위해 지정하는 옵션으로 macOS나 리눅스의 경우 줄바꿈을 LF로 사용하기 때문에 SMTP에서 표준으로 사용하는 CRLF로 변환하기 위해 지정한다.

위와 같이 화면이 뜨면 정상 동작이다.
이제 다음 명령어들을 한 줄 씩 입력하면서 어떤 응답이 오는지 확인해 보자.
HELO localhost
MAIL FROM:<test@sender.com>
RCPT TO:<test@receiver.com>
DATA
Subject: Local Mail Test
Hello megamaker!!!
.
QUIT

주로 사용하는 SMTP 명령어는 크게 다섯 가지가 있다.
| HELO | 서버에 접속 및 인사 |
| MAIL FROM | 발신자 지정 |
| RCPT TO | 수신자 지정 |
| DATA | 본문 작성 시작 |
| QUIT | 연결 종료 |
다른 것들은 보면 어떤 의미인지 알기 쉽지만 DATA 부분은 약간의 설명이 필요하다.
Subject: 는 메일 제목을 지정하는 헤더이다. 이는 SMTP 명령어와는 다른 것으로, 본문 내에 작성하는 것이다.
다른 헤더들도 있으니 궁금하면 찾아보면 좋다.
그리고 본문의 마지막은 .을 작성하여 끝이라는 것을 알리게 되는데 응답되는 설명에서 앞서 말했던 CRLF로 개행을 지정해야 함을 확인할 수 있다.
2. 다음 메일로 실제로 메일 보내보기
이제는 테스트 말고 실제로 메일이 보내서 테스트해보자.
다음 메일을 이용해서 테스트해볼 것인데 먼저 설정해야 하는 부분이 있다.

다음 메일 설정에서 우측 하단의 앱 비밀번호가 생성되어 있는지 확인해야 한다.
비밀번호가 없다면 하나 생성하고 비밀번호를 복사해 둔다.

다음 메일의 경우 SSL/TLS 절차가 있기 때문에 telnet을 사용하지 못한다.
openssl s_client -connect smtp.daum.net:465 -crlf
openssl을 이용하여 테스트해볼 수 있다.
그런데 직접 해보니까 보안 때문에 연결이 너무 빨리 끊기고 중간에 오류가 발생해서 그냥 파이썬 코드를 작성해서 진행하기로 했다.
import smtplib
from email.mime.text import MIMEText
# === 여기만 내 정보로 수정 ===
daum_id = "내 다음 이메일"
app_password = "앱 비밀번호"
receiver = "받는 메일 주소"
# ==================================
# 메일 본문 및 제목 설정
msg = MIMEText("안녕하세요! 파이썬 스크립트로 보낸 메일입니다.")
msg['Subject'] = "메일 보내기 테스트"
msg['From'] = daum_id
msg['To'] = receiver
try:
# Daum SMTP SSL 연결 (포트 465)
print("Daum SMTP 서버에 연결 중...")
with smtplib.SMTP_SSL("smtp.daum.net", 465) as server:
# 서버와의 송수신 내용이 실시간으로 출력
server.set_debuglevel(1)
print("\n--- [ SMTP 서버와의 실시간 대화 시작 ] ---")
# 로그인 인증 (내부적으로 EHLO와 AUTH LOGIN을 수행)
server.login(daum_id, app_password)
# 메일 발송 (MAIL FROM, RCPT TO, DATA 과정 수행)
server.sendmail(daum_id, receiver, msg.as_string())
print("--- [ SMTP 서버와의 실시간 대화 종료 ] ---\n")
print("[성공] 네이버 메일로 정상 발송되었습니다!")
except Exception as e:
print(f"\n[실패] 에러 발생: {e}")
위 코드를 작성하고 실행해 본다.
다음 이메일, 앱 비밀번호, 수신자는 직접 작성해야 한다.
참고로 첫 연결 시 HELO가 아닌 EHLO를 사용하는 이유는 HELO는 SMTP 초기에 사용하던 명령어로 너무 오래됐기 때문에 현재 사용하는 인증 절차나 멀티미디어 등 추가 기능들을 사용할 수 없기 때문이다. 그렇기 때문에 Extended라는 의미를 포함한 ESMTP에서 해당 명령어가 변경되었다.
위 코드를 실행하면 실제로 메일이 보내지는 것을 확인할 수 있다.

참고로 SMTP는 메일 전송용 프로토콜이기 때문에 메일을 클라이언트 에이전트에서 수신하려면 POP3나 IMAP과 같은 프로토콜을 사용해야 하는데 이 프로토콜을 직접 사용하지 않으려면 그냥 웹으로 접속해서 확인하면 된다.

직접 그림 그리려고 했는데 오래 걸릴 거 같아서 만들어달라고 하니 잘 만들어준다...
'공부 > 네트워크' 카테고리의 다른 글
| [네트워크] TCP / IP (0) | 2024.04.02 |
|---|---|
| [네트워크] REST API와 성숙도 모델 (0) | 2024.03.08 |
| [네트워크] OSI 7계층 (0) | 2024.01.12 |
| [네트워크] Web Server와 Web Application Server(WAS) (0) | 2023.09.23 |