메일을 보낼때 검토받아서 보내는 부분은 보류되었습니다. 역시나 하나가 끝나면 하나가 다시 오는법… 검토는 하지않지만 주고받은 메일을 archiving하는 것으로 선회했습니다. moderation은 영 정말로 껄그럽지만, archiving은 그보다는 좀 낫네요.
가장 간단한 방법은 모든 always_bcc으로 모든 메일 메시지를 특정 계정으로 보내면 됩니다. archiving용 계정 하나 만들고 모두 보내면 되니깐 편하겠지요.
그런데 모든 메일입니다. archiving에 필요없는 메시지도 가는 것이지요. 뭐 메일 root@로 날아오는 관리일이나 각종 보안 검사메일, cron 명령 메일등등 이런것을 굿이 archiving할 필요가 없는데 말입니다. 그래서 가장 간단하지만 always_bcc를 사용하지 않기로하고, 그런 다음에 눈에 들어온게 content_filter입니다.
content_filter를 만들어서 거기서 메일을 저장하면 되겠지요. 간단한 내용이지만 이거 메커니즘 이해하느라 상당히 고생했습니다. postfix 샘플대로 하니 안됩니다. 계속 loop를 돌아서 에러를… ㅡㅜ;
설정
archiver 필터를 archiver라고 하면
main.cf:
content_filter = archiver
이제 모든 메시지는 archiver 서비스를 통해서 전달됩니다.
master.cf:
archiver unix - n n - 10 pipe
flags=Rq user=whitekid null_sender=
argv=/usr/local/bin/python /home/whitekid/work/postfix-archiver/archiver.py 127.0.0.1 20026 ${sender} ${recipient}
127.0.0.1:20026 inet n - - - - smtpd
-o content_filter=
-o receive_override_options=no_unknown_recipient_checks,no_header_body_checks,no_milters
-o smtpd_helo_restrictions=
-o smtpd_client_restrictions=
-o smtpd_sender_restrictions=
-o smtpd_recipient_restrictions=permit_mynetworks,reject
-o mynetworks=127.0.0.0/8
-o smtpd_authorized_xforward_hosts=127.0.0.0/8
- archiver 서비스에서 필터를 실행합니다.
- 그리고 파라미터들은 필터를 처리하고 난 다음의 action들을 지정하는데 archiver 필터를 처리한 후 127.0.0.1:20026 서비스를 호출하기 위해 파라미터를 전달해줍니다. 이 파라미터는 archiver.py에서 받아서 다음 서비스에 전달합니다. 아래 서비스가 smtpd이므로 smtp로 메일을 보내는 것 처럼 합니다.
content_filter -(pipe)-> archiver -(smtp)-> 127.0.0.1:20026 의 순서로 메시지가 전달됩니다.
archiver.py
이제 archiver.py의 대략적인 소스를 보면…
import sys
import smtplib
import email
EX_OK = 0
EX_TEMPFAIL = 75
EX_UNAVAILABLE = 69
def main():
host, port, sender, recipient = sys.argv[1], int(sys.argv[2]), sys.argv[3], sys.argv[4:]
msg = email.message_from_string(sys.stdin.read())
msg['X-Archive-Status'] = 'Archived'
server = smtplib.SMTP(host, port)
for r in recipient:
server.sendmail(sender, r, msg.as_string())
server.quit()
if __name__ == '__main__':
try:
main()
sys.exit(EX_OK)
except Exception, e:
print e
sys.exit(EX_TEMPFAIL)
내용은 아주 간단합니다. stdin에서 받은 내용에서 약간의 메시지 조작을 하고, 그 메시지를 다시 파라미터로 받은 smtp로 연결해서 넘김니다. 자 이렇게고 maillog를 보면
Aug 24 14:23:39 freebsd postfix/qmgr[22880]: 537F51705A: from=<root@freebsd.woosum.net>, size=1013, nrcpt=1 (queue active)
Aug 24 14:23:39 freebsd postfix/pipe[22890]: 3D3E217030: to=<whitekid@freebsd.woosum.net>, relay=archiver, delay=0.1, delays=0.01/0.01/0/0.09, dsn=2.0.0, status=sent (delivered via archiver service)
Aug 24 14:23:39 freebsd postfix/qmgr[22880]: 3D3E217030: removed
Aug 24 14:23:39 freebsd postfix/local[22894]: 537F51705A: to=<whitekid@freebsd.woosum.net>, relay=local, delay=0.01, delays=0.01/0/0/0, dsn=2.0.0, status=sent (delivered to mailbox)
Aug 24 14:23:39 freebsd postfix/qmgr[22880]: 537F51705A: removed
음 archiver 서비스를 이용해서 mailbox가지 간게 보이나요? 보이면 OK!
amavisd-new와 공존
amavisd도 content_filter를 사용합니다. 그런데 이게 2개가 적용되지 않습니다. content_filter는 1개인것이고, 이게 chain으로 역여서 돌아가는 것이지요. 이렇게 chain에 넣어야하는데, 그건 간단하게…
amavis unix - - - - 2 smtp
-o smtp_data_done_timeout=1200
-o smtp_send_xforward_command=yes
127.0.0.1:10025 inet n - - - - smtpd
-o content_filter=archiver
처럼 content_filter에 archiver를 넣어주면 됩니다.