본문 바로가기

전자공학을 즐겁게/누구나 취미전자공학

Outgoing SMTP 서버 만들기 - 라즈베리 파이에서 postfix

728x90
반응형

사무실에 새로운 사무용 복합기를 들였습니다. 요즘 복합기는 이더넷(Ethernet)으로 연결되니까 사무실 네트워크에만 연결되어 있으면, 인쇄를 하든 팩스를 보내든 많이 자유로워졌죠. 그런데, 문제는 문서 스캔입니다. 이게 제조사마다 방식이 다 다르네요. 이번엔 여러 방법 중에 이메일로 보내 주는 방식이 있는데, 문제는 이것이 메일을 보낼 수 있는 Outgoing SMTP를 설정해 주어야 합니다. 그런데, 복합기에 설정할 Outgoing SMTP가 없네요. 정확하게 말하자면 Outgoing SMTP를 설정하자니 메일 계정 하나가 필요해지는데, 복합기에 주자고 메일 계정을 하나 만들 수가 없는 노릇입니다. 그래서, 적당하게 단순한 Outgoing SMTP를 하나 만들면 어떨까 생각이 들었습니다. 필요한 것은 메일을 받을 필요도 없고, 단순히 메일을 보낼 수 있게만 해 주는 Outgoing 서버입니다.
 

SMTP가 뭐지

SMTP(Simple Mail Transfer Protocol)는 인터넷을 통하여 이메일을 주고받을 수 있도록 하는 규약인데, 이 규약을 이용해서 메일을 보낼 수 있게 해 주는 것이 메시지 전송 에이전트(MTA; Message Transfer Agent)입니다. 
그래서 메일을 받거나 보낼 수 있게 해 주는 메일 서버를 보통 SMTP 서버라고 하고, 메일을 보내기 위한 서비스를 하는 서버를 Outgoing SMTP 서버라고 합니다.
 
하는 역할을 보니 인터넷 되는 컴퓨터 하나만 있으면 만들 수 있을 것 같은데요.
그럼 시작해 보겠습니다.
 

서버 하드웨어/소프트웨어 준비

라즈베리파이(Raspberry Pi) SD 카드 만들기

사용할 라즈베리파이를 준비합니다.

사용할, 인터넷 되는 컴퓨터, 라즈베리파이를 준비합니다. 뒤져 보니 오래된 라즈베리 파이 2가 있군요. 이 정도면 되지 않을까요? 데스크톱 환경도 필요 없으니 RASPBERRY PI OS LITE를 사용합니다. 
라즈베리 파이의 셋업 과정은 "라즈베리 파이(Rsapberry Pi) 셋업(Set-up)하기" 포스트를 참조하세요.
데스크탑 환경은 사용하지 않을 것이니까 VNC를 설정할 필요 없이 SSH 접속만 가능하게 하면 되겠습니다.
 

라즈베리파이(Raspberry Pi) 초기 설정

SD 카드가 만들어졌으면, 라즈베리파이에 SD 카드를 장착하고 전원을 켭니다. 이더넷이든 WiFi든 라즈베리파이가 연결이 되었는지 확인하세요. 
SSH를 통하여 라즈베리파이에 접속합니다. 저는 우분투를 사용하기 때문에 이렇게 커맨드로 연결했지만, Windows를 사용하는 분들은 WinSCP 같은 클라이언트 프로그램을 사용하시면 됩니다. 

ssh pi@raspberrypi.local

인증서 어쩌구 나오면 yes 하고, 사용자 이름/암호 넣고 접속합니다.
 
라즈베리파이를 처음 실행한 것이니 업데이트 먼저 해야죠. 

sudo apt update && sudo apt upgrade -y

 
그리고, Time Zone 설정하는 것 잊지 마세요. 어떻게 하는지는 아시죠? raspi-config에서 Localisation으로 가세요.

sudo raspi-config

 
이제 사용할 하드웨어 라즈베리 파이가 준비되었습니다. 본격적으로 서버 구성에 들어갑니다.
 

Postfix 설치

Postfix는 유닉스(Unix) 계열의 시스템에서 실행되는 메일서버 프로그램입니다. 많은 사람들이 사용하고 있는 것으로 보여서 이것을 이용하기로 했습니다.
 
라즈베리파이에 postfix를 설치합니다. mailutils는 꼭 필요한 것은 아니고 나중에 시험을 위해서 사용하기 위하여 함께 설치합니다.

sudo apt install postfix mailutils

 
설치하다 보면 뜬금없이 설정창이 나타납니다. 

설치 중에 설정창이 나타납니다.

라즈베리 파이는 이렇게 보기 좋게 설정 화면이 나오지만, 다른 리눅스 배포판은 같은 내용이 다른 모양으로 나올 수 있습니다.
이때 정확히 설정하지 않아도 되고, 지금 제가 사용하고자 하는 용도에도 크게 영향을 주지는 않습니다. 기본 설정으로 두고 진행해도 지장은 없습니다. 
 
왼쪽에 나와 있는 창은 posftfix가 기본적으로 어떻게 동작할지 선택하는 것입니다. 여러 번 시행착오를 거치면서 해 보니 Internet Site로 선택하는 것이 나중에 편한 것 같습니다. No configuration을 선택하면 아무것도 만들어지는 것 없이 나중에 완전히 수작업으로 설정을 해야 하니 좀 난해한 면이 있습니다. 
오른쪽 창은 메일을 보낼 때, @ 뒤에 붙는 도메인 명 같은 것인데, 그냥 hostname을 그대로 두어도 됩니다. 나중에 충분히 수정도 가능합니다. 별로 중요치 않습니다.
 

Postfix 설정 파일

Postfix의 설정 파일은 /etc/postfix 디렉터리에 있습니다. 어떤 파일들이 있는지 살펴보세요.

cd /etc/postfix
ls -l

/etc/postfix 디렉트리의 파일들입니다.

 
뭔지 모를 파일들이 있지만, 여기에서 중요한 것은 main.cf와 master.cf입니다. 
Postfix는 기본적으로 TCP Port 25를 사용하는데, 만약 이런 것을 변경하는 것이 아니라면, master.cf도 손댈 필요는 없습니다. 그냥 main.cf만 설정 조정을 해 주는 것만으로도 내가 원하는 설정을 할 수 있습니다. main.cf를 텍스트 에디터로 열어 봅니다. 
 
저는 vim이 좋더라구요. 설치 안 되어 있을 테니, 일단 vim 설치하고, main.cf 열어 봅니다. vim 싫은 분들은 nano 사용하셔도 됩니다. 꼭 sudo 잊지 마세요. 이 설정 파일은 root가 소유자니까 sudo로 실행해야 합니다.

sudo apt install vim
sudo vim main.cf

 
지금까지의 시행착오의 결론으로 보자면 다른 부분은 그대로 두어도 지장은 없을 것 같습니다. 열어 보면 아래쪽 부근에 다음과 같은 부분이 나오는데, 이 부분이 실제로 우리가 관심 있는 부분입니다.

smtpd_relay_restrictions = permit_mynetworks permit_sasl_authenticated defer_unauth_destination
myhostname = raspberrypi
alias_maps = hash:/etc/aliases
alias_database = hash:/etc/aliases
mydestination = $myhostname, raspberrypi, localhost.localdomain, , localhost
relayhost = 
mynetworks = 127.0.0.0/8 [::ffff:127.0.0.0]/104 [::1]/128
mailbox_size_limit = 0
recipient_delimiter = +
inet_interfaces = all
inet_protocols = all

Postfix의 기본적인 설정에 대한 것은 Postfix Basic Configuration 페이지에 있습니다. 
그런데, 이것을 모두 읽기 싫어서 찾아오신 것일 테니, 제가 이해하는 데로 필요한 것만 간략히 적어 보겠습니다.

  • smtp_relay_restrictions: 이것은 수신자의 지정을 누가 할 수 있느냐에 대한 설정으로 보면 됩니다. 내 네트워크에서만(permit_mynetworks), 인증된 경우(permit_sasl_authenticated) 등 이 이외에도 옵션이 많습니다.
  • myhostname: 현재 로컬 머신의 이름이죠. 기본적으로는 로컬 주소에서 메일을 보내는 계정의 도메인 이름으로 사용됩니다.
  • mydestination: 이것은 메일을 받을 때, 사용될 도메인입니다. 이 서버의 사용자는 어떤 도메인을 갖는 메일 주소를 가지느냐를 설정하는 것으로 보면 됩니다만, 저는 메일을 받을 일이 없으니 큰 관심은 아닙니다.
  • mynetworks: 내 로컬 네트워크를 지정합니다. permint_mynetworks에서 말하는 mynetworks를 지정합니다. 기본적으로 현재 컴퓨터의 주소만 해당합니다. 다시 말하면, 디폴트로 postfix를 설치한 라즈베리파이만 내 로컬 네트워크라고 간주하는 것입니다.
  •  inet_protocols: ipv4, ipv6를 말합니다. "all" == "ipv4,ipv6" 디폴트는 all이지만, ipv4만 사용하여도 될 것 같네요.

시행착오를 하다 보니 실제로 사용하는 데에는 설정을 조정할 할 것은 한 두 항목 정도입니다. 대세에 지장이 없어 보이는 항목은 굳이 적으려고 애쓰지 않았습니다. 더 관심이 있다면 Postfix Configuration Parameters를 살펴보세요. 
 
수정할 것이 하나 더 있는데, /etc/aliases 파일입니다.

sudo vim /etc/aliases

 
이 파일은 root나 postmaster가 수신하는 메일을 누가 받느냐를 지정합니다. 그냥 내가 받는 것으로 하면 되죠.

# See man 5 aliases for format
postmaster:    pi
root:          pi

 
/etc/aliases를 수정하였다면 적용을 위해서 반드시 newaliases를  실행해 주어야 합니다. 

sudo newaliases

 
Postfix의 설정, main.cf 또는 master. cf 등을 수정한 이후에는 반드시 서비스를 다시 시작해야 합니다.

sudo systemctl reload postfix
sudo systemctl restart postfix

 

시험

메일 송신 시험

Postfix는 설치했는데, 메일이 보내어지는지 확인을 해 봐야죠. 이때 사용하는 것이 postfix와 같이 설치한 mailutils입니다. 다음 커맨드로 시험용 메일을 보낼 수 있습니다. <your email address> 대신 메일을 받아 볼 주소를 넣어 보세요.

echo "This is a test" | mail -s "Test message" <your email address>

그런데, 우리가 일반적으로 사용하는 Gmail, Outlook, 다음메일 같은 메일 시스템에서는 스팸으로 처리하거나 아예 원천적으로 막아 버리는 경우가 많은 것 같습니다. 저와 같은 경우에는 outlook.com의 제 메일 주소로 보냈더니, Junk Mail 폴더로 들어가더라고요. 그도 그럴 것이 어디 등록도 되어 있지 않은 서버에서 메일이 왔으니 그럴 만도 하지요. 어쨌든 다른 이상이 없는 한 이 명령이 성공한다면 postfix의 설치와 설정은 일단 동작하고 있는 것입니다. 
 
문제가 있다면 log 파일들이 /var/log 디렉터리에 있습니다. mail.log, mail.info, mail.err과 같은 파일들이 있으니 문제가 있다면 로그 내용에 다른 이상이 있었는지 확인해 보세요.
 

Port 25를 통한 SMTP 시험

앞에서 postfix는 기본적으로 TCP Port 25를 사용한다고 했습니다. 이 Port로 접속한 다음 SMTP 명령어를 보내서 시험을 해 볼 수 있습니다. 개인적으로는 이 시험을 통해서 어렴풋이 어떤 일이 일어난다는 감을 잡을 수 있었습니다.
 
Port 25로 접속하기 위해서는, 요즘은 보안상의 이유로 거의 사용하지 않지만, telnet을 사용합니다. 라즈베리파이에 telnet server와 client를 모두 설치합니다. 로컬 머신에 접속하지만, TCP Port를 열어야 하기 때문에 telnet server도 함께 설치해야 합니다.
 
다음 명령어를 실행하면 필요한 것은 모두 설치가 됩니다. telnet을 설치한 후, 로컬 머신의 Port 25에 접속합니다.

sudo apt install telnet telnetd
telnet localhost 25

 
다음에 나오는 화면처럼 진행이 됩니다. 굵은 글씨로 되어 있는 부분들이 사용자가 직접 입력해 주는 부분이고, 나머지 부분은 SMTP 서버의 응답입니다.

Port 25 접속을 통한 SMTP 시험

HELO, EHLO, MAIL FROM, RCPT TO, DATA, QUIT 등이 SMTP 명령어입니다. DATA 명령에서 Subject와 메시지 본문 사이에는 한 줄 간격이 있어야 합니다. 첫 컬럼에 .(마침표)를 쓰면 DATA 명령을 사용한 메일 작성이 끝나는 것입니다. 여기에서도 <your email address>에는 메일을 받게 될 이메일 주소를 적어 주세요.
명령어의 진행을 보면 알겠지만, 메일을 보내는 주소, 여기에서는 hello@example.com은 꼭 현재 서버가 운영되는 컴퓨터에 있는 계정이 아니어도 된다는 것을 알 수 있습니다. 물론 설정에 의해서 이런 여러 가지에 제한을 걸 수 있습니다.
 

리모트 컴퓨터에서의 접속

이제는 다른 컴퓨터에서 SMTP 서버로 사용하고 있는 라즈베리파이에 접속하는 시험을 해 봅니다. telnet을 지원하는 어떤 클라이언트를 사용해도 상관없습니다. 라즈베리파이의 IP 주소를 확인하고, 해당 IP 주소를 이용하여 telnet 접속을 시도합니다.

telnet <raspberrypi ip address> 25

로컬에서 했던 것과 똑같이 시험할 수 있습니다. 
문제가 있는 경우에는 /var/log/mail.err, /var/log/mail.info, /var/log/mail.log 등의 Log 파일을 참고하면서 문제의 원인을 찾으면 됩니다. 이 시점에서 아마 한 번에 성공하지는 못할 것이라고 생각합니다. 
 
/etc/postfix/main.cf에서 수정을 해 주어야 할 것입니다.

mynetworks = 127.0.0.0/8 [::ffff:127.0.0.0]/104 [::1]/128 192.168.0.0/24

내 네트워크에 대해서 제한이 걸려 있기 때문에 현재 라즈베리파이와 같은 공유기를 사용하는 컴퓨터들을 내 네트워크에 포함시켜 주거나, 내 컴퓨터의 IP 주소를 포함시켜 주어야 합니다. 
192.168.0.0/24는 192.168.0.x의 IP 주소를 갖는 컴퓨터를 의미합니다. 만약 오로지 하나의 컴퓨터만 추가한다면, 192.168.0.xx/32와 같이 추가해 주면 됩니다.
라즈베리파이에서 직접 로컬 접속하여 얻은 결과와 동일하다면 원격으로도 접속하는 데에 성공한 것입니다.
 

이메일 클라이언트를 이용한 시험 - Thunderbird

telnet을 사용하여 원격으로 접속 시험을 하고 나니, 이메일 클라이언트를 사용해서 메일을 보내는 것을 시험해 볼 수 있지 않을까 하는 생각이 들었습니다. 물론 가능할 것 같습니다.
저는 Thunderbird를 사용하는데, 여기에 Outgoing SMTP Server를 추가하면 시험해 볼 수 있습니다. 
 

Thunderbird 이메일 클라이언트 프로그램에서 Outgoing Server에 추가해서 시험해 볼 수 있습니다.

  1. Thunderbird의 설정으로 가면, Account Setting > Outgoing Server (SMTP)가 있습니다. 여기에 라즈베리파이의 IP 주소를 이용하여 서버를 추가합니다. 사용자 이름을 사용하여 접속도 하지 않으니, 보안 옵션이나 사용자 이름은 없는 것으로 하면 됩니다.
  2. 현재 사용하고 있는 이메일 계정을 하나 선택하고, 아래쪽에 보면 Manage Identities...가 있습니다. 하나의 메일 주소로 여러 이름을 사용하거나 할 때 사용하는 것인데, 여기에 Identity 하나를 추가합니다.
  3. 나머지 사항은 그대로 똑같이 하고, Outgoing Server (SMTP)만 1)에서 추가한 Outgoing Server를 사용하도록 하면 됩니다. 이렇게 하면 받는 것은 기존 설정대로 하고, 보내는 Outgoing Server만 내가 구성한 것을 사용하게 됩니다.

 
이제 시험용 메일을 보내 보세요.
 

실전 투입

이제는 라즈베리파이를 사무실에 설치하고 원하는 대로 복합기와 연동하는지 확인합니다.
 

설정의 조정

한 번에 그냥 되지는 않습니다. 마지막 조정을 해 주었습니다.

smtpd_relay_restrictions = permit_mynetworks defer_unauth_destination
smtpd_client_restrictions = permit_mynetworks, reject
myhostname = raspberrypi
alias_maps = hash:/etc/aliases
alias_database = hash:/etc/aliases
mydestination = $myhostname, raspberrypi, localhost.localdomain, , localhost
relayhost = 
mynetworks = 127.0.0.0/8 192.168.xx,xx/24
mailbox_size_limit = 0
recipient_delimiter = +
inet_interfaces = all
inet_protocols = ipv4
  1. smtpd_relay_restrictions에서 로컬 네트워크를 제외하고 인증에 따라 허용하고 할 여지도 없기 때문에, permit_mynetworksdefer_unauth_destination만 남겼습니다.
  2. mynetworks에서 로컬 머신 이외에 로컬 네트워크를 추가하기 위하여 192.168.xx.xx/24를 추가하고, IPV6 주소들은 모두 지웠습니다. 192.168.xx.xx는   내 로컬 네트워크에 맞는 알맞은 값은 넣으세요. xx.xx로 설정하는 것 아닙니다.
  3. inet_protocols는 ipv6는 사용할 일이 없어 그냥 ipv4만 남겼습니다.
  4. smtpd_client_restrictions는 로컬 네트워크에서만 SMTP 서버 접속을 허용하기 위하여 추가하였습니다.

복합기에서 Outgoing SMTP를 설치된 라즈베리파이의 IP 주소로 설정하고, Port를 25로 맞춰 준 다음, 메일 보내는 사람 이메일 주소는 대충 넣었더니 SMTP 접속이 성공하였습니다. 이후에는 원하는 대로 문서 스캔하고 이메일 주소 지정했더니 잘 보내어지네요.
 

로그 확인

/var/log/mail.log가 메일을 보낼 때 어떻게 나타나는지 살펴보았습니다.
 

tail -f /var/log/mail.log

 

tail -f /var/log/mail.log

흰색 사각형으로 표시한 부분이 하나의 메일을 보내는 과정입니다. 
소켓을 열고, 마지막에 닫을 때까지 과정이 나타납니다. 눈여겨본 부분이 노란 사각형으로 표시한 내용입니다. helo, mail, rcpt, data, quit. 많이 낯익은 단어입니다. 그렇습니다. 위에서 telnet 접속으로 시험할 때 사용했던 SMTP 커맨드들입니다.
복합기가 Outgoing SMTP 서버에 접속해서 메일을 보내는 과정을 개략적으로 알 수가 있었습니다.
 

맺음말

처음에는 이렇게까지 내용이 길어질 것이라고 생각하지 않았는데, 생각보다 길어진 것 같습니다. 역시 메일을 보내기만 하는 Outgoing SMTP 서버 하나도 한순간에 구성을 할 수 있는 것은 아니네요.
Outgoing SMTP 서버는 메일을 보낼 수 있게 해 줍니다. 단순히 메일을 보낼 수 있게만 하더라도 다른 애플리케이션에서 이메일로 알림을 줄 수 있도록 할 수가 있습니다.
현재 구성한 Outgoing SMTP 서버도 계속 모니터링하면서 설정을 조금씩 조정을 하겠지만, SMTP를 통하여 메일을 보내는 과정을 이해하는 것으로, 이메일 알림을 주는 애플리케이션에 대한 이해를 하는 기회가 되었습니다.
 

참고


문서 Update 이력

  • 2023.10.8: 최초 발행
  • 2023. 10. 10: main.cf에 smtpd_client_restrictions를 추가하였습니다.
728x90
반응형