요 며칠 삽질기 -_-! with Exim

어째 요새 관리해야할 서버가 늘어버렸네요. (전 언픽스 하나로 족한데 ㅠ.ㅠ) 하여튼!! 요 며칠 사이 gentoo + exim + procmail + spf + srs + clamav + bogofilter + dovecot 를 시도해봤습니다.

사실 계속 제가 맡아서 할 게 아니라 길어야 일 년 정도 만져줄 서버기 때문에 젠투가 아닌 다른 배포판을 생각했었는데, spf 와 srs 를 지원할 수 있도록 하면서 기본으로 제공되는 패키지를 이용할 수 있는 조합이 몇 가지 되질 않더군요. exim 에서 spf 와 srs 는 experimental 로 되어 있기 때문에 바이너리 배포판에선 기본으로 적용이 되어 있질 않고, postfix + milter 조합에서는 srs 를 제공할 수 없기 때문에 남은 선택은 sendmail + milter 조합 밖에 없는데 sendmail 을 사용하기는 싫었거든요.

하여튼! exim 에 procmail 을 붙이는 방법은 아래와 같습니다.

procmail: driver = accept transport = procmail domains = +local_domains check_local_user # emulate OR with "if exists"-expansion require_files = /usr/bin/procmail no_verify no_expn

router 파트의 localuser: 룰 앞에 위와 같은 코드를 추가하고

procmail: driver = pipe path = "/bin:/usr/bin:/usr/local/bin" command = "/usr/bin/procmail" return_path_add delivery_date_add envelope_to_add

transpotes 에 router 에서 정의한 procmail transpote 를 정의해 주면 되죠. procmail 을 이용한 스팸 필터야 예전부터 잘 사용해오던 게 있으니 그걸 사용하면 됐구요.

그 다음은 smtp 설정!! 기본으로 /etc/exim/auth_conf.sub 란 파일이 있길래 그냥 자동으로 smtp 인증 설정이 되어있는줄 알았는데 smtp 인증을 사용하려면 저 안에 있는 내용을 /etc/exim/exim.conf 에 추가해줘야합니다.

plain: driver = plaintext public_name = PLAIN server_condition = "${if pam{$2:$3}{1}{0}}"   login: driver = plaintext public_name = LOGIN server_prompts = "Username:: : Password::" server_condition = "${if pam{$1:${sg{$2}{:}{::}}}{1}{0}}"

그 내용은 위와 같았구요. 하지만 여기서 또 문제가 발생! 예전 시스템이 오래 전에 설치된 것이었는지 비밀번호 암호화를 md5 로 사용하질 않고 있었는데, /etc/pam.d/system-auth 에서 md5 를 제거함으로써 다른 데몬들에선 문제가 해결됐지만 exim 의 stmp 에서만 인증 실패가 나오는겁니다. -_-!

참고로 smtp auth 가 어떤 과정으로 이뤄지는지는 아래 인용된 내용을 참고하세요. 테스트할 때 알아두면 편합니다.

$ telnet localhost 25
EHLO localhost
AUTH LOGIN
base64로인코딩한아이디
base64로인코딩한비밀번호

여담이지만 smtps 나 pop3, imaps 를 꼭 사용하세요. 위에서 처럼 비밀번호가 그냥 넘어갑니다. 패킷이 악의적인 라우터를 지날 경우 아이디/비밀번호가 줄줄 셀 수 있습니다.

하여튼 비굴하게 saslauthd 를 사용해서 우회시켜봤지만 요놈도 마찬가지로 인증 실패 -_-! 아예 다 안되면 모르겠는데 우리 사랑스런 dovecot 은 로그인이 아주! 잘 됩니다. exim 만 나쁜 놈이란 거죠.

saslauthd 라거나 pwcheck 같이 다른 곳에서 잘 사용도 안되는 데몬을 띄우는 게 좀 꺼림찍했는데 잘됐다 싶어서 dovecot-auth 를 활용해봤습니다. dovecot-auth 를 활용하려면 아래와 같이 dovecot.conf 파일을 수정해줘야 합니다.

auth default { mechanisms = plain login passdb pam { args = "*" } userdb passwd { } user = root   socket listen { client { path = /var/run/dovecot/auth-client mode = 0666 } } }

그리고 위에 써있는 auth-client 소켓을 이용해서 로그인하도록 exim.conf 를 고쳐줍시다.

login: driver = dovecot public_name = LOGIN server_socket = /var/run/dovecot/auth-client

이제 끝!! 드디어 smtp 인증이 정상적으로 되기 시작합니다. 휴;;

뭐 대강 다 됐는데, 한 가지 아쉬운 점이라면 .forward 나 alias 를 이용할 경우 procmail 을 거치지 않기 떄문에 스팸 필터링이 안되는 것 정도? 이건 어떻게 해야할 지 별로 답이 안나오네요.

그렇다고 bogofilter, clamav 등이 다 procmail 에서 호출되는데 이걸 spamassassin + clamd 조합으로 새로 설정하긴 완전 귀찮고 (사실 어떻게 하는지도 모르고) 약간 쀍입니다.

그 외에 mailman 과 관련된 삽질이 조금 더 있었고, seliunx 가 적용되어 있는 CentOS 랑 관련된 것도 있었는데 또 언제 시간날 때 관련된 것들을 포스팅해봐야겠습니다.

사실 요새 포스팅 하고 싶은 내용은 많은데 내용이 길어져서 귀차니즘이 발동해버렸네요.

Sender Rewrite Scheme

spf 는 예전에 써놨던 글에서 충분히 설명해놨듯이 메일의 도메인값과 발송지 값을 이용해 스팸을 필터링해내기 위한 기술입니다. 예를 들어 From address 에 nospam@mytears.org 가 있을 경우 mytears.org 도메인의 txt 정보를 읽어오고, 거기에 적혀있는 61.109.245.78 에서 온 메일만을 정상적인 메일로 판단하게 되는데, 이렇게 spf 가 적용되어 있는 경우 .forward 나 alias 등을 이용해서 메일을 포워딩 시킬 경우 문제가 있을 수 있습니다.

.forwards 를 통해 nospam@mytears.org 를 nospam@gmail.com 으로 리다이렉션을 시킨 경우를 생각해봅시다.

  1. sender@somedomain 에서 nospam@mytears.org 로 메일을 보냄
  2. mytears 메일 서버에서 nospam@mytears.org 사용자에 대한 .forward 파일을 읽어서 거기 적혀있는 nospam@gmail.com 으로 메일을 포워딩 시킴
  3. gmail 메일 서버에서 from address 인 somedomain 의 txt 에서 spf 정보를 읽어옴
  4. spf 로 지정된 아이피와 메일을 포워딩시킨 서버의 아이피가 동일하지 않으므로 spf 정보가 맞지 않다고 판단함
  5. spf 정책에 따라 다르겠지만 대부분 스팸이라고 판단하게 됨
  6. 결국 제대로 메일이 전해지지 않음

이걸 해결하기 위한 방법으로 srs 라는 게 있습니다. 이걸 적극적으로 적용한 예로는 구글이 있습니다.

exim 의 경우 기본적으로 spf, srs 를 지원하기 때문에 빌드할 때 옵션을 잘 조절해주면 쉽게 적용할 수 있습니다. sendmail 의 경우 milter 를 이용하면 srs 를 적용할 수 있구요. 하지만 postfix 에서는 이를 사용할 수 없는 방법이 없습니다. (구버젼의 postfix 라면 패치를 통해 사용할 수 있지만 이 패치가 계속 유지되질 않고 있습니다.)

참고
spf: http://www.openspf.org/
srs: http://www.openspf.org/SRS

p.s) 그나저나 spf 가 나온지 꽤 오랜 시간이 흘렀음에도 대학 메일 서버들 중에 spf 를 지원하는 곳은 별로 없군요.