왠지 모르게 점점 마이너 한 것들만 사용하게 되네요. postfix 나 exim 을 사용해보니 여러가지 장점이 눈에 보이는데 막상 how to 문서같은게 그리 잘 나와있질 않다보니 사람들이 사용하기를 꺼리는 것 같아 처음으로 howto 문서를 하나 작성해려 합니다.
이 문서는 젠투에서 exim 을 사용하는 방법을 기준으로 설명하고 있습니다.
Table of Contents
- 기본 구성
- 필요한 소프트웨어 설치하기
- 가상호스트 설정하기
- 바이러스 필터 설정
- 스팸 필터 설정
- dovecot 설정하기
- smtp 인증 설정하기
- 다른 배포판을 사용할 때 유의점
기본 구성
Mail Transfer Agent 로는 exim, 스팸 필터로는 bogofilter, 바이러스 필터는 clamav, pop3/imap server 로는 dovecot 을 사용하기로 하겠습니다. dovecot 이나 exim 이나 기본 적으로 실행하는 프로세스들이 많지 않기 때문에 프로세스 리스트를 확인할 때 깔끔해서 좋더군요.
필요한 소프트웨어 설치하기
저 같은 경우는 대강 다음과 같은 USE 플래그를 이용해서 설치를 진행했습니다.
1 2 3 4 5 6 7 8 9 |
emerge -pv exim bogofilter clamav dovecot procmail These are the packages that would be merged, in order: Calculating dependencies... done! [ebuild R ] mail-mta/exim-4.69 USE="domainkeys dovecot-sasl exiscan exiscan-acl gnutls ipv6 pam perl sasl spf sqlite srs ssl syslog tcpd -X -dnsdb -ldap -lmtp -mailwrapper -mbox -mbx -mysql -nis -postgres -radius" 0 kB [ebuild R ] mail-filter/bogofilter-1.1.6 USE="berkdb sqlite -gsl" 0 kB [ebuild R ] app-antivirus/clamav-0.92.1-r1 USE="bzip2 crypt milter nls -mailwrapper (-selinux)" 14,927 kB [ebuild R ] net-mail/dovecot-1.0.13-r1 USE="ipv6 pam pop3d ssl -debug -doc -kerberos -ldap -managesieve -mbox -mysql -postgres -sieve -suid -vpopmail" 0 kB [ebuild R ] mail-filter/procmail-3.22-r7 USE="-mbox (-selinux)" 222 kB Total: 5 packages (5 reinstalls), Size of downloads: 15,149 kB |
domainkeys 는 야후나 구글에서 사용하고 있는 domain key 를 제대로 검증하기 위한 USE 플래그가 되겠구요, dovecot-sasl 은 smtp 인증에 dovecot 을 이용하기 위한 플래그입니다.
spf, srs, domainkey 같은 플래그는 해당 기능을 사용하지 않겠다면 빼주셔도 무방합니다. CentOS 등에서는 dovecot-sasl 도 기본으로 지원이 안되더라구요. 하튼 관련해서 자세한 건 뒤에서 설명하도록 하겠습니다.
살펴보니 별로 특이한 플래그를 사용하지는 않네요. -_;; 젠투 유져라면 다들 아시겠지만 실제 설치는 위의 예제에서 -pv 를 제거하고 실행시키시면 됩니다.
가상호스트 설정하기
설치가 무사히 끝났다면 가상호스트를 설정해봅시다. 젠투에서는 기본으로 설정파일을 만들어주지 않습니다. 그렇기 때문에 우선 /etc/exim/exim.conf.dist 를 복사해서 exim.conf 를 만들어줍니다.
# cp /etc/exim/exim.conf.dist /etc/exim/exim.conf
그런 다음 자신이 좋아하는 편집기를 이용해서 exim.conf 파일을 열고, 아래와 같은 부분을 찾아서 자신의 환경에 맞게 수정을 한 뒤
1 2 3 4 |
primary_hostname = unfix.net domainlist local_domains = @ : localhost : dsearch;/etc/exim/virtual domainlist relay_to_domains = hostlist relay_from_hosts = 127.0.0.1 |
router 부분에서 system_alias 바로 아래에 다음 코드를 추가해줍니다.
1 2 3 4 5 6 7 8 9 |
virtual: driver = redirect allow_fail allow_defer domains = dsearch;/etc/exim/virtual data = ${expand:${lookup{$local_part}lsearch*@{/etc/exim/virtual/$domain}}} retry_use_local_part file_transport = address_file pipe_transport = address_pipe |
주 도메인이 있는 경우 localhost 대신 unfix.net 같은 도메인을 사용해도 무방합니다. 만약 위의 예제에서 localhost 대신 unfix.net 을 설정해주면 로컬에 있는 모든 계정은 id@unfix.net 형태의 메일계정으로 사용이 가능해집니다. 주 도메인이 여러개라면 @ : localhost : mydomain1 : mydomain2 식으로 콜론(:) 을 이용해서 여러 개를 모두 적어주면 되겠습니다.
이젠 가상 호스트를 설정해봅시다. 만약 test.com 과 test.net 을 위한 가상호스트를 설정하려 한다면 다음과 같이 하면 됩니다.
1 2 3 |
# mkdir /etc/exim/virtual # vi /etc/exim/virtual/test.com # vi /etc/exim/virtual/test.net |
위에서 dsearch; … 으로 설정해놓은 디렉토리 안에다가 호스트 이름을 이용해서 alias 파일을 만들어주면 되니까 간단하죠? 각 파일에 들어가는 내용은 다음과 같습니다.
# test.com
test: aqua@localhost
melong: test@gmail.com
# test.net
aqua: test@localhost
test.com 파일에 들어가 있는 test: aqua@localhost 는 test@test.com 으로 온 메일을 aqua@localhost 로 포워드를 시키라는 거에요. 워낙 간단하니 다른 것들은 따로 설명 안해도 될 것 같네요. 단 위에서 localhost 대신 myhost.net 을 사용했다면 aqua@myhost.net 처럼 설정해줘야 합니다.
여기까지 따라하셨다면 가상 호스트 설정은 끝! 가상 호스트 파일을 수정했을 때는 alias 를 수정했을 때와 달리 newalias 를 실행시키실 필요가 없습니다.
바이러스 필터 설정
바이러스 필터로는 clamav 를 사용할 건데, USE 플래그로 exiscan 과 exiscan-acl 을 사용해서 설치했다면 clamd 와 연동하는건 아주 간단합니다.
exim.conf 에서 다음과 같은 줄을 찾아서 주석을 해제시키세요.
1 |
av_scanner = clamd:/var/run/clamav/clamd.sock |
끝! clamd.sock 위치는 배포판에 따라 다를 수 있습니다. 자세한건 /etc/clamd.conf 를 참조하세요.
스팸 필터 설정
SPF
Exim에는 기본으로 SPF와 관련된 코드가 있으므로 SPF를 사용하기 위해선 EXPERIMENTAL_SPF=yes 환경변수와 함께 exim을 빌드하면 됩니다.
설정은 global 섹션에서 acl_smtp_rcpt 로 등록되어 있는 것에 다음과 같은 설정을 넣어주면 됩니다.
1 2 3 4 5 6 7 8 9 10 11 12 13 |
# Query the SPF information for the sender address domain, if any, # to see if the sending host is authorized to deliver its mail. # If not, reject the mail. # deny message = [SPF] $sender_host_address is not allowed to send mail \ from $sender_address_domain log_message = SPF check failed. spf = fail # Add a SPF-Received: header to the message warn message = $spf_received |
젠투에선 acl_smtp_rcpt가 acl_check_rcpt로 되어 있기 떄문에 acl_check_rcpt 부분에 위 설정을 추가해줬습니다.
만약 warn message = $spf_received 를 넣어주지 않으면 헤더에 SPF결과를 출력하지 않게됩니다. SPF헤더를 붙일 경우에는 SMTP Auth를 이용해서 메일을 보내는 경우에도 SPF헤더가 붙는 문제가 있습니다. 이를 피하기 위해 설정을 아래처럼 수정해주도록 합시다.
1 2 3 4 |
# Add a SPF-Received: header to the message warn message = $spf_received !authenticated = * |
SRS
SRS를 설정하기 위해 우선 global 섹션에 다음과 같은 내용을 추가해줍니다.
1 |
srs_config = somesecretkey |
여기서 somesecretkey는 본인이 원하는 임의의 문자열을 넣으면 되겠습니다. 그 후 다음과 같이 userforward에 ‘srs=forward’를 넣어주면 됩니다. 간단하죠.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
userforward: driver = redirect srs = forward check_local_user # local_part_suffix = +* : -* # local_part_suffix_optional file = $home/.forward # allow_filter no_verify no_expn check_ancestor file_transport = address_file pipe_transport = address_pipe reply_transport = address_reply |
Bogofilter
스팸 필터로는 베이시안 룰 기반의 스팸 필터인 bogofilter를 사용해봅시다.
bogofilter를 MTA와 연동시키는 데는 procmail을 이용할 수도 있지만, procmail은 로컬 유져에 한해서만 사용이 가능하고, alias 나 .forward 를 사용하게 되는 경우에는 사용할 수 없으므로 exim의 transport와 router를 이용해보겠습니다.
우선 transport를 다음과 같이 설정합니다.
1 2 3 4 5 6 7 8 9 10 11 12 |
bogofilter: driver = pipe command = /usr/sbin/exim -oMr bogodone -bS use_bsmtp = true transport_filter = /usr/bin/bogofilter -d /etc/bogofilter/ -e -p log_output = true return_path_add = false temp_errors = * home_directory = "/tmp" current_directory = "/tmp" message_prefix = "" message_suffix = "" |
그리고 이 transport 를 이용하는 router를 만들어야 합니다. 참고로 router 는 순서에 민감하므로 삽입할 위치를 잘 선택해야 합니다. 저같은 경우는 system_alias 다음에다가 넣어두었습니다.
1 2 3 4 5 6 |
bogofilter: domains = +local_domains no_verify condition = ${if !eq {$received_protocol}{bogodone} {1}{0}} driver = accept transport = bogofilter |
여기까지만 하게 되면 bogofilter가 각각의 메일 헤더에 ‘이 메일이 스팸/햄이다.’ 라는 정보만을 넣어줄 뿐 스팸/햄을 다른 메일박스로 분류해주는 동작은 하질 않습니다.
그러므로 자동 분류를 위한 transport 와 router 를 또 추가해주도록 합니다.
transport 먼저…
1 2 3 4 5 6 7 |
spam_delivery: driver = appendfile directory = /home/$local_part/.maildir/.Spam maildir_format delivery_date_add envelope_to_add return_path_add |
이렇게 하면 자신의 홈 디렉토리의 .maildir 아래 .Spam 이란 디렉토리를 만들고, 그 디렉토리에 스팸 메일을 저장하게 됩니다.
IMAP 으로 접속하면 Spam 메일들을 확인할 수 있기 때문에 이렇게 했는데, POP3 만 사용하는 거라면 그냥 제목에 [Spam] prefix 를 붙이게 하는 것도 나쁘지 않을 것 같습니다.
그 다음엔 이 transport 를 이용하는 router를 설정해야하는데, 이 때도 위치를 잘 생각해야 합니다. 저같은 경우엔 bogofilter router 바로 아래에 위치시켜 놓았습니다..
1 2 3 4 5 |
removingspam: driver = accept check_local_user condition = ${if match {$h_X-Bogosity:} {Spam, tests=bogofilter} {1}{0}} transport = spam_delivery |
스팸 메일은 bogofilter 에 의해 X-Bogosity: Spam, test=bogofilter … 식의 헤더가 추가되기 때문에 이렇게 할 경우 스팸을 쉽게 분류해낼 수 있습니다.
dovecot 설정하기
우선 /etc/dovecot.conf 파일을 열어서 서비스할 프로토콜 리스트를 적어주세요. 그 다음에 plaintext 로 로그인할 수 있도록 설정해주고, pop3 나 imaps 를 위해 ssl 을 사용할거라고 명시해주고, 마지막으로 dovecot-sasl 을 사용할 수 있도록 auth-client 를 활성화시켜주세요.
이를 종합해보면 다음과 같은 설정파일이 만들어집니다. 볼드로 표시한 부분이 제가 수정한 부분이에요. 주석을 제거하고 보니 정말 간단하네요. -_-;
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 |
protocols = imap imaps pop3 pop3s listen = [::] disable_plaintext_auth = no ssl_disable = no ssl_cert_file = /etc/ssl/private/unfix.net.crt ssl_key_file = /etc/ssl/private/unfix.net.key mail_location = maildir:~/.maildir protocol imap { } protocol pop3 { pop3_uidl_format = %08Xu%08Xv } protocol lda { postmaster_address = postmaster@example.com } auth default { mechanisms = plain login passdb pam { args = "*" } userdb passwd { } user = root socket listen { client { path = /var/run/dovecot/auth-client mode = 0666 } } } |
그리고 /etc/pam.d 로 가서 smtp 파일이 있는지를 체크해보시고 만약 없다면 system-login 이나 pop 등을 복사해서 smtp 파일을 만들어주세요. 이것 때문에 어제 혈압이 올랐던걸 생각하면 …!!!
여기까지 설정하셨음 90% 는 끝난겁니다.
smtp 인증 설정하기
자 다시 exim.conf 로 돌아와서 smtp 인증을 설정해봅시다. exim.conf 에서 authenticators 파트를 찾아서 아래와 같은 내용을 추가해줍시다.
1 2 3 4 5 6 7 8 9 10 11 12 |
plain: driver = dovecot public_name = PLAIN server_socket = /var/run/dovecot/auth-client server_set_id = $1 server_advertise_condition = 1 login: driver = dovecot public_name = LOGIN server_socket = /var/run/dovecot/auth-client server_set_id = $1 server_advertise_condition = 1 |
이걸로 설정은 끝! 다음엔 데몬들을 띄워서 제대로 되나 확인을 해보세요.
1 2 |
# /etc/init.d/dovecot start # /etc/init.d/exim start |
다른 배포판을 사용할 때 유의점
제가 이것저것 확인해본 건 아니라 정확하게 알려드릴 순 없지만 CentOS 에서는 spf, srs, dovecot-sasl, domainkeys 등을 사용할 수가 없습니다. 그렇기 때문에 dovecot-auth 대신 saslauthd 를 사용해야 해요. saslauthd 를 사용할 때의 authenticator 파트는 다음과 같습니다.
1 2 3 4 5 6 7 8 9 10 11 12 |
PLAIN: driver = plaintext public_name = PLAIN server_condition = ${if saslauthd{{$1}{$2}{smtp}}{1}{0}} server_set_id = $1 server_advertise_condition = true LOGIN: driver = plaintext public_name = LOGIN server_condition = ${if saslauthd{{$1}{$2}{smtp}}{1}{0}} server_set_id = $1 server_advertise_condition = true |
server_condition 을 다음처럼 하면 pam 만으로도 인증을 할 수 있습니다. 하지만 pam_auth 모듈에서 auth request를 보낸 사용자의 uid와 username을 가지고 확인하는 절차가 있기 때문에 exim을 root 권한으로 실행시키지 않으면 제대로 인증이 되지 않습니다.
1 |
server_condition = "${if pam{$2:$3}{1}{0}}" |
참고로 인증을 saslauthd 를 통해서 하려는 경우 saslauthd 가 실행 중에 있어야 합니다.