============================== Postfix + Cyrus IMAPD + LDAP ============================== $Id: postfix+imapd+ldap.txt,v 1.1 2001/04/20 18:11:51 hurd Exp $ $Author: hurd $ $Date: 2001/04/20 18:11:51 $ 간단히 말하자면, 이 문서는 UNIX 환경에서, 분산가능한, 대용량, 대규모 메일 처리 시스템을 구축하기 위해 생각해 볼 수 있는 한 가지 방법으로 LDAP을 활용하는 구체적인 경험을 정리한 것입니다. 몇 해전부터 업무상의 필요 때문에 관련 자료를 수집, 분석하여 적용해 본 결과 얻은 결과물들을 정리해 놓은 것이기도 합니다. '정리'라고 표현하긴 했지만, 그간의 로그들을 짜깁기 해 놓은 것에 불과하기 때문에, 완성도는 떨어집니다. 허접하게 설명을 추가하긴 했지만, 급조한 것이라 조악하기 그지 없습니다. 이 주제에 관해 더 체계적이고 풍부한 설명서를 만들어 낸다는 것은 꽤 많은 시간과 노력을 필요로 하는 일일 것입니다. (앞으로 좀 더 시간을 내어 보다 구체적이고 체계적인 HowTo 급의 문서를 만들어 보는 것도 생각해볼 만한 일이겠죠 :-) 필요한 소프트웨어들 =================== - SMTP: postfix snapshot ftp://postfix.webweaver.net/experimental/snapshot-20010228.tar.gz 정식 릴리즈 버젼을 사용해도 상관없습니다만, LMTP 를 사용하여 SMTP를 메일 저장소와 분리하여 사용하려면 스냅샷이 좋습니다. - POP3/IMAP: Cyrus IMAPD ftp://ftp.andrew.cmu.edu/pub/cyrus-mail/cyrus-imapd-1.6.24.tar.gz Cyrus IMAPD 는 서버측 메일 필터링 언어인 sieve 와 메일박스 분산등을 지원합니 다. 또 opepnssl 을 이용한 pop3s, imaps 등을 지원합니다. - LDAP: openldap ftp://ftp.OpenLDAP.org/pub/OpenLDAP/openldap-release/openldap-2.0.7.tgz Netscape 디렉토리서버를 사용해도 됩니다만, 여기서는 openldap 을 기준으로 설명드립니다. - PAM_LDAP: nss_ldap, pam_ldap, migrationtools http://www.padl.com/download/nss_ldap.tgz http://www.padl.com/download/pam_ldap.tgz http://www.padl.com/download/MigrationTools.tgz /etc/passwd, /etc/group 등을 LDAP으로 대체하는데 필요합니다. - DBM: Berkeley DB 3.2.x http://www.sleepycat.com/update/3.2.9/db-3.2.9.tar.gz sasl, openldap 등에서 필요로 합니다. gdbm 을 사용해도 되지만, 여기서는 berkeley db 를 사용하는 것으로 가정하고 설명하겠습니다. - SASL: Cyrus SASL ftp://ftp.andrew.cmu.edu/pub/cyrus-mail/cyrus-sasl-1.5.24.tar.gz 사전 준비 작업 ============== 본격적으로 postfix 와 imapd 를 설치하기 전에 필요한 환경을 준비하도록 하죠. o Berkeley DB 3.2.x ------------------- Berkeley DB 는 OpenLDAP, SASL 에서 사용하게됩니다. GDBM 에 비해 여러가지 확장 기능을 가지고 있으므로 특별한 이유가 없는한 이를 사용하시기 바랍니다. 우선 웹사이트로부터 최신 버전을 가져옵니다.(아래와 버전이 다를 수 있습니다.) $ wget http://www.sleepycat.com/update/3.2.9/db-3.2.9.tar.gz 압축을 풀어야겠죠. $ gzip -dc db-3.2.9.tar.gz | tar xvf - 컴파일을 합니다. --enable-shared 옵션을 포함시켜 공유라이브러리를 생성하도록 합니다. $ cd db-3.2.9 $ cd build_unix $ ../dist/configure --enable-shared $ make 컴파일이 오류없이 끝났다면 시스템의 적절한 곳으로 설치합니다. $ su # make install 기본적으로 /usr/local/BerkeleyDB.3.2 이하에 복사됩니다. 버전에 따라 이름이 다를 수 있습니다. 이제 GNU의 linker인 ld 가 제대로 라이브러리를 찾을 수 있도록 LD_LIBRARY_PATH 에 추가해 주어야 합니다. 여기서는 간단히 /etc/ld.so.conf 를 수정하도록 합니다. # vi /etc/ld.so.conf /usr/local/BerkeleyDB.3.2/lib --> 제일 윗줄에 추가(*중요*) 이 줄은 맨 윗줄에 위치하여야 합니다. 그렇지 않으면 glibc 에 기본적으로 포함된 dbm 라이브러리를 찾게 되는 일이 발생합니다.(redhat 계열의 경우 /usr/lib/libdb.so) 저도 여러번의 삽질 끝에 알게된 사실인데, 이 별거 아닌 것 같은 처리를 제대로 해주지 않으면 cyrus imapd 가 별다른 오류메시지 없이 이상하 게 동작합니다. 오류메시지가 없으니 당연히 원인도 알기 힘듭니다... -_-; 이제 변경사항을 적용해야겠죠. # ldconfig o Cyrus SASL ------------ 최신버전을 받아옵니다. $ wget ftp://ftp.andrew.cmu.edu/pub/cyrus-mail/cyrus-sasl-1.5.24.tar.gz 압축을 풀고 컴파일을 위한 준비를 합니다. $ gzip -dc cyrus-sasl-1.5.24.tar.gz | tar xvf - $ cd cyrus-sasl-1.5.24 $ env CFLAGS="-O6" \ CPPFLAGS="-I/usr/local/BerkeleyDB.3.2/include" \ LDFLAGS="-s -L/usr/local/BerkeleyDB.3.2/lib" \ ./configure \ --prefix=/usr \ --enable-static \ --enable-shared \ --enable-login \ --with-dblib=berkeley \ --disable-krb4 \ --without-rc4 \ --disable-cram 위에서 BerkeleyDB.3.2 관련 사항은 자신의 시스템 상황에 맞게 고쳐주세요. 다시한번 얘기하지만, dbm 이 서로 달라 발생하는 문제는 정말 찾아내기 힘듭니다. 별문제 없이 끝났다면, 이제 컴파일을 합니다. $ make 컴파일이 끝났다면 sasl이 berkeley DB와 함께 컴파일 되었는지 확인해 봅니다. 별거 아닌것 같지만, 저처럼 고생하지 않으시려면 반드시 확인해 보세요. $ strings -n4 utils/.libs/saslpasswd |grep "libdb" 이 때 libdb-3.xxx 같은 식의 결과가 출력되어야 합니다. libdb.so.3 과 같은 식으로 출력되면 문제가 있는 것입니다. 앞서 얘기했듯이 그런 경우 imapd 가 이유없이 이상하게 동작합니다. 제 경우는 사용자 인증이 제대로 안되는 증상이 발생했었습니다. 그래서, LDAP의 사용자 엔트리에 문제가 있는 것으로보고 몇 일동안 LDAP 과 씨름했죠.. ㅠ.ㅠ 나중에 dbm 문제였다는 사실을 알아내고는 얼마나 허무하던지.. 흑... ㅠ.ㅠ 자, 말씀드린대로 컴파일이 오류없이 끝났다면 설치해줍니다. $ su # make install # chmod 755 /usr/lib/sasl/* # chmod 755 /usr/lib/libsasl.la # chmod 755 /usr/lib/libsasl.so.* # /sbin/ldconfig 앞으로 SASL 인증방식을 사용할 계획이라면 라이브러리 수준에서 로그를 남기는 것이 보안상 좋겠죠. syslog 설정에 다음과 같이 새로운 동작을 추가합니다. # vi /etc/syslog.conf ... auth.debug /var/log/auth.log ... 로그파일을 생성해주고 syslog 데몬을 다시 시작합니다. # umask 027 # touch /var/log/auth.log # umask 022 # killall -HUP syslogd o OpenLDAP ---------- 이제 LDAP 을 설치할 차례입니다. 여기서는 openldap 을 사용합니다. 만일 LDAP 서버를 다른 기계에서 돌리고 싶고, 준비된 LDAP 서버가 있다면, 그냥 라이브러리만 만들어도 됩니다. (**** 필요한 라이브러리만 만드는 방법 ****) $ wget ftp://ftp.OpenLDAP.org/pub/OpenLDAP/openldap-release/openldap-2.0.7.tgz $ gzip -dc openldap-2.0.7.tgz |tar xvf - $ cd openldap-2.0.7 $ env CFLAGS="-O6 -fomit-frame-pointer" \ ./configure \ --prefix=/usr \ --sysconfdir=/etc \ --without-kerberos \ --without-cyrus-sasl \ --disable-slapd \ --disable-slurpd \ --enable-static \ --without-tls $ make depend $ make $ su # make install 이렇게 하면, redhat 계열의 디렉토리 정책을 따른 /usr 이하에 설치됩니다. 여기서는 kerberos 인증과 tls 를 제외했지만, 자신의 설정에 맞게 고쳐주세요. (**** 서버를 돌리기 위한 설치방법 ****) 준비된 LDAP 서버가 없다면 바로 지금이 만들기 적당한 기회입니다. $ wget ftp://ftp.OpenLDAP.org/pub/OpenLDAP/openldap-release/openldap-2.0.7.tgz $ gzip -dc openldap-2.0.7.tgz |tar xvf - $ cd openldap-2.0.7 $ env CFLAGS="-O6 -fomit-frame-pointer" \ ./configure \ --prefix=/usr \ --sysconfdir=/etc \ --without-kerberos \ --without-cyrus-sasl \ --enable-static \ --disable-wrappers \ --disable-rlookups \ --enable-ldbm \ --enable-localstatedir=/var/run \ --libexecdir=/usr/sbin \ --without-tls $ make depend $ make $ su # make test # make install 위에서 말씀드린대로 옵션들은 적절히 변경하세요.(잘 모르겠다면, 그냥 저처럼 사용해도 됩니다.) 아참, ldap 의 경우 백앤드 디비를 굳이 berkeley db 를 사용하지 않아도 문제가 발생하지는 않습니다. 그러나, berkeley 를 사용하는 것이 좋겠죠. config.log 를 잘 살펴보면 autoconf 가 어떤 dbm을 백앤드 디비로 포착했는지 알 수 있습니다. 이렇게 LDAP 서버가 마련되었습니다. 이제 slapd.conf 를 손볼 때입니다. 이미 잘 사용하시던 분이라면 아시겠지만, slapd.conf 의 rootdn 을 위한 패스워드를 만들어야 합니다. 제 경우는 직접 간단한 프로그램을 만들어서 사용합니다. # cat /usr/local/bin/mksha 요기부터...----------------------------------------------------------- #!/usr/bin/python import sys import sha import base64 if not sys.argv[1:]: print "Usage: %s passwd" % sys.argv[0] else: password = sys.argv[1] res = sha.new(password) password = res.digest() print "{SHA}%s" % base64.encodestring(password) 요기까지...----------------------------------------------------------- 혹시 아직 clean 패스워드를 사용한다면 위의 간단한 스크립트를 경로에 걸어두세요. 만일 'test1234'를 패스워드로 사용하고 싶다면, $ mksha test1234 와 같이 사용하면됩니다. 위의 경우 출력은 다음과 같습니다. {SHA}m8NFSdVl2VBbKH3gzSCsd74dPyw= 이것을 긁어다가 붙여넣으면 되죠. 다음은 /etc/slapd.conf 의 한 예입니다.(제가 사용하는 것에서 약간만 고친 것입니다.) 여기부터...---------------------------------------------------------- include /etc/openldap/schema/core.schema include /etc/openldap/schema/cosine.schema include /etc/openldap/schema/inetorgperson.schema include /etc/openldap/schema/nis.schema include /etc/openldap/schema/xmail.schema defaultaccess read loglevel 256 idletimeout 0 # ver1.2 인경우 생략 sizelimit 1000 timelimit 3600 backend ldbm # ver1.2 인경우 생략 pidfile /usr/var/slapd.pid argsfile /usr/var/slapd.args ####################################################################### # ldbm database definitions ####################################################################### database ldbm readonly off suffix "dc=mydomain,dc=co.kr" rootdn "cn=root,dc=mydomain,dc=co.kr" rootpw "{SHA}m8NFSdVl2VBbKH3gzSCsd74dPyw=" directory /usr/local/ldap index uid,cn,maildrop,mailacceptinggeneralid pres,eq,sub index userPassword pres,eq index objectClass pres,eq index uidNumber,gidNumber pres,eq access to attr=userPassword by self write by anonymous auth by dn="cn=root,dc=mydomain,dc=co.kr" write by * none access to * by self write by dn="cn=root,dc=mydomain,dc=co.kr" write by * read --------------- 여기까쥐... ----------------- 위 내용이 하나도 이해되지 않는다면 ldap 공부를 더 하세요. 앞으로 시간이 좀 되면 좀더 자세한 설명을 해드리겠습니다. 주의하실 것은 다음과 같은 라인입니다. include /etc/openldap/schema/xmail.schema ... index uid,cn,maildrop,mailacceptinggeneralid pres,eq,sub xmail.schema 는 maildrop 과 mailacceptinggeneralid 를 정의해 놓은 스키마 파일입니다. 스키마 검사를 하지 않는다면 문제없지만, 저처럼 스키마 검사를 생략하는 것을 대단히 찜찜하게 여기신다면, 꼭 포함시켜야 합니다. xmail.schema 는 바로 아래에서 보여드릴 것입니다. maildrop 과 mailacceptinggeneralid 를 인덱싱해두는 것은 상당히 중요합니다. 그렇지 않으면 메일을 주고받을 때 상당히 버벅댑니다.. -_-; 물론, dc=mydomain,dc=co.kr 은 자신의 basedn 으로 변경해 주셔야겠죠. $ cat /etc/openldap/schema/xmail.schema 요기부터...----------------------------------------------------- attributetype ( 1.3.6.1.4.1.7290.2.1.1 NAME 'maildrop' DESC 'address to where admin domain MTA forwards this entrys email' SUP mail SINGLE-VALUE ) attributetype ( 1.3.6.1.4.1.7290.2.1.2 NAME 'mailacceptinggeneralid' DESC 'username for mailbox or mail aliasing' SUP uid ) objectclass ( 1.3.6.1.4.1.7290.2.2.1 NAME 'xMail' DESC 'LDAP-based routing of SMTP message' SUP top MUST uid MAY (maildrop $ mailacceptinggeneralid) ) 요기까지....---------------------------------------------------------- 보시다시피, xMail 이라는 objectclass, maildrop 과 mailacceptinggeneralid 속성을 정의하고 있습니다.(위의 OID를 그대로 사용하시려면 절대로 변경하지 마세요.) 여기까지 일차적인 LDAP 설정은 끝났습니다. 이제 /etc/passwd 를 LDAP으로 대체 하고 메일 관련 데몬들을 설치해주는 일만 남았습니다. PAM_LDAP ======== PAM_LDAP 은 말그대로 LDAP을 사용하는 PAM입니다. PAM이 뭔지 잘 모르신다면 http://www.kernel.org/pub/linux/libs/pam/ 를 읽어 보세요. NSS_LDAP 에 관해서는 RFC 2307(http://www.faqs.org/rfcs/rfc2307.html)를 읽어보세요. o NSS_LDAP ---------- 최신버전을 PADL Software 로부터 가져옵니다. $ wget http://www.padl.com/download/nss_ldap.tgz 압축을 풀고 컴파일합니다. 아래 버전은 몇 달전의 버전이므로 지금은 다를 것입니다. 적당히 바꿔서 이해해주세요. $ gzip -dc nss_ldap.tgz |tar xvf - $ cd nss_ldap-144 $ ./configure --with-ldap-lib=openldap $ make 컴파일시 몇 개의 warning 이 나타날 수 있는데, 별로 중요한 것은 아닙니다. 그냥 무시하셔도 됩니다. 컴파일이 오류 없이 끝났다면 설치해줍니다. $ su # make install o PAM_LDAP ---------- PAM_LDAP 의 경우도 NSS_LDAP과 유사합니다. $ wget http://www.padl.com/download/pam_ldap.tgz $ gzip -dc pam_ldap.tgz |tar xvf - $ cd pam_ldap-101 $ ./configure --with-ldap-lib=openldap $ make $ make check $ su # make install 이렇게 하면, /lib/security/ 아래에 pam_ldap.so 파일이 설치됩니다. 또, /etc/ldap.conf 파일이 설치됩니다. 이 파일은 pam_ldap 이 사용하는 설정 파일입니다. 따라서, 적절히 수정하는 작업이 필요합니다. 다음은 /etc/ldap.conf 의 설정 내용 예제입니다. # cat /etc/ldap.conf 요기부터..----------------------------------------------------------- host 127.0.0.1 base dc=mydomain,dc=co.kr binddn cn=root,dc=mydomain,dc=co.kr bindpw test1234 port 389 scope one crypt sha pam_filter objectclass=posixAccount pam_login_attribute uid 요기까지..----------------------------------------------------------- 아마 버전에 따라 몇개의 옵션이 더 있을 것입니다. 주석을 잘 읽어보시면, 각 옵션이 의미하는 바가 뭔지를 쉽게 알 수 있습니다. 적절히 고쳐주세요. 위의 예에서는 LDAP 서버가 localhost 에 있는 것으로 가정하고 있습니다. Base DN 은 dc=mydomain,dc=co.kr 입니다. 자신의 /etc/openldap/slapd.conf 내용에 따라 적절히 바꾸어 줍니다. 여기까지 마쳤다면 한가지 결정할 사항이 있습니다. pam_ldap 인증을 사용할 서비스를 결정하는 것입니다. pam_ldap 소스디렉토리의 pam.d 디렉토리를 살펴보시면 알만한 이름을 가진 파일들이 보이실 겁니다. 원하는 파일만 /etc/pam.d 로 옮겨주시면 됩니다. 여기서는 imap 과 pop3 에서만 사용할 것이므로 다음과 같이 복사해줍니다. # cp -f pam.d/imap /etc/pam.d/ # cp -f pam.d/pop /etc/pam.d/ 각 파일의 내용을 이해하시려면 앞서 언급한 PAM 관련 URL을 참조하세요. o Migration ----------- pam_ldap 인증과 관련하여 남은 일은 LDAP 디렉토리를 만들어 주는 것입니다. PADL Software 의 Migration 툴을 이용할 수도 있습니다. 2년전에 펄로된 그 툴을 사용해보고 너무 실망한 나머지(당시에는 상당히 문제가 많았습니다) 그냥 python 으로 직접 만들어 사용해 오다가 몇 달 전 최신 버전을 다시 한번 사용해 보았는데, 몇 줄만 고쳐주면 꽤 쓸만하더군요. 각설하고, Migration 툴을 받아와서 압축을 풀어 놓습니다. $ wget http://www.padl.com/download/MigrationTools.tgz $ gzip -dc MigrationTools.tgz |tar xvf - $ cd MigrationTools-37 일반적인 설정사항을 고쳐줍니다. $ vi migrate_common.ph ----------------------------------------------------------- $DEFAULT_MAIL_DOMAIN = "mydomain.co.kr"; $DEFAULT_BASE = "dc=mydomain,dc=co.kr"; $DEFAULT_MAIL_HOST = "mail.mydomain.co.kr"; ----------------------------------------------------------- 대충 보시면 아시겠지만, 이 설정사항이 다른 스크립트들에서 사용됩니다. 다음은 우리의 관심사항인 /etc/passwd 을 LDAP 디렉토리로 옮겨 넣는 스크립트를 적절히 수정합니다. $ vi migrate_passwd.pl ----------------------------------------------------------- print $HANDLE "objectClass: account\n"; print $HANDLE "objectClass: posixAccount\n"; print $HANDLE "objectClass: xMail\n"; print $HANDLE "objectClass: top\n"; ... print $HANDLE "maildrop: $user@","$DEFAULT_MAIL_DOMAIN\n"; print $HANDLE "mailacceptinggeneralid: $user\n"; print $HANDLE "\n"; ----------------------------------------------------------- 보시다시피, xMail, maildrop, mailaccepting 등을 추가해 넣은 것 외에는 변동사항이 없습니다. 이 스크립트가 하는 일은 /etc/passwd 를 읽어서 LDIF 형식의 파일로 변환하는 것입니다. 다음과 같이 /etc/passwd 와 /etc/group 을 변환하도록 합니다. $ ./migrate_passwd.pl /etc/passwd passwd.ldif $ ./migrate_group.pl /etc/group group.ldif 만약, NIS 전반에 걸쳐 LDAP 으로 마이그레이션하려면 http://www.padl.com/tools.html 를 읽어보신 후 적절히 처리하시면 됩니다.(이 경우 반드시 root 권한의 콘솔을 한 개 정도 열어두신 후 하세요. 자칫하면 로그인이 아예 안됩니다.) 위에서 생성한 LDIF 파일은 곧장 디렉토리에 써넣을 수 없습니다. LDAP 디렉토리를 초기화하는 작업이 필요하죠. 이미 초기화되어 있고, ou=People,dc=mydomain,dc=co.kr 과 같은 엔트리가 만들어져 있다면 몰라도.. $ cat init.ldif ----------------------------------------------------------- # Organization for MyDomain Organization dn: dc=mydomain,dc=co.kr objectClass: dcObject objectClass: organization dc: mydomain o: Coredump Organization description: The Coredump Organization # Organizational Role for Directory Manager dn: cn=root,dc=mydomain,dc=co.kr objectClass: organizationalRole cn: root description: Directory Manager # for /etc/passwd dn: ou=People,dc=mydomain,dc=co.kr ou: People objectClass: top objectClass: organizationalUnit # for /etc/group dn: ou=Group,dc=mydomain,dc=co.kr ou: Group objectClass: top objectClass: organizationalUnit # for 'cyrus' IMAP Admin Account dn: uid=cyrus,ou=People,dc=mydomain,dc=co.kr objectClass: top objectClass: account objectClass: posixAccount objectClass: shadowAccount objectClass: xMail uid: cyrus cn: cyrus userPassword: {SHA}//diwldksl2dVzyhz0z02fLc= loginShell: /bin/bash uidNumber: 76 gidNumber: 12 homeDirectory: /usr/local/cyrus/imap maildrop: hurd@hurd.coredump.co.kr mailacceptinggeneralid: hurd ----------------------------------------------------------- 위와 같은 모습이 되겠군요. dc=mydomain,dc=co.kr 은 적절히 변경해 주셔야겠죠. 마지막의 cyrus 엔트리는 이후 IMAP의 어드민 user 를 미리 생성해주는 부분입니다. userPassword 와 maildrop 등을 적절히 고쳐주셔야 합니다. 초기화 엔트리를 정의할 파일을 이제 디렉토리에 옮겨 씁니다. $ ldapadd -f init.ldif -x -D "cn=root,dc=mydomain,dc=co.kr" -W 성공적으로 디렉토리가 만들어졌다면, passwd 와 group 를 마이그레이션합니다. $ ldapadd -f passwd.ldif -x -D "cn=root,dc=mydomain,dc=co.kr" -W $ ldapadd -f group.ldif -x -D "cn=root,dc=mydomain,dc=co.kr" -W 이제 ldapsearch 등으로 확인해 보면 /etc/passwd 내용이 올바르게 옮겨졌는지 확인할 수 있을 것입니다. 아.. GQ 와 같은 GUI 프로그램을 써도 되겠군요 :) PAM_LDAP 과 관련하여 한가지 더 /etc/nsswitch.conf 를 수정해 주어야 합니다. # vi /etc/nsswitch.conf 와 같이 파일을 열어서 passwd, shadow, group 등에 ldap 을 추가해 줍니다. ----------------------------------------------------------- passwd: files ldap shadow: files ldap group: files ldap ----------------------------------------------------------- nisplus 나 nis 를 사용한다면 그 것도 추가해 주세요. Postfix ======= Postfix 의 안정버전을 사용하셔도 됩니다만, 여기서는 스냅샷을 사용하기로 하겠습니다. 제 경험에 의하면 말이 스냅샷이지 거의 아무 문제없이 잘 돌아갑니다. 최신 버전을 다운로드 받습니다. (버전을 다를 수 있으니 웹페이지를 확인하고 받으세요.) ** 주의 ** 반드시 소스에 포함된 문서들을 읽어보세요!!!!!! $ wget ftp://postfix.webweaver.net/experimental/snapshot-20010228.tar.gz $ tar xvzf snapshot-20010228.tar.gz $ cd snapshot-20010228 $ make tidy 메일주소 룩업에 LDAP을 사용하도록 합니다.(자세한 것은 소스트리의 LDAP_README 를 읽어보세요.) $ make makefiles CCARGS="-DHAS_LDAP -DUSE_SASL_AUTH" \ AUXLIBS="-lldap -llber -lsasl" 위에서는 SASL 도 사용할 수 있도록 했으나 필요 없다면 생략해도 됩니다. 다만, LMTP를 사용하는 경우라면 반드시 포함시켜야 합니다. 별다른 문제가 없다면 컴파일합니다. $ make 만약 sendmail 이 설치되어 있다면 제거하거나, 다음과 같이 사용하지 않도록 처리합니다. $ su # mv /usr/sbin/sendmail /usr/sbin/sendmail.OFF # mv /usr/bin/newaliases /usr/bin/newaliases.OFF # mv /usr/bin/mailq /usr/bin/mailq.OFF # chmod 755 /usr/sbin/sendmail.OFF /usr/bin/newaliases.OFF \ /usr/bin/mailq.OFF Postfix 의 각종 데몬들이 사용할 사용자와 그룹을 생성해 줍니다. # useradd -M -s /bin/false postfix # groupadd maildrop 이제 설치해줄 차례입니다. INSTALL.sh 스크립트를 실행해주고 질문에 적절히 대답해 주면 됩니다. # sh INSTALL.sh 대부분은 그냥 디폴트값을 사용하면 됩니다. 그러나, 다음과 같이 setgid 는 maildrop 을 사용하도록 해줘야 합니다. setgid: [no] maildrop <--- 중요 이렇게 하면 기본 설정파일들은 /etc/postfix/ 디렉토리 아래에 설치되고 각종 바이너리들은 /usr/sbin 등에 복사됩니다. 설치가 성공적으로 끝났다면 앨리어스 설정도 변경해줍니다. # cat /etc/postfix/aliases ----------------------------------------------------------- MAILER-DAEMON: postmaster postmaster: root bin: root daemon: root games: root ingres: root nobody: root system: root toor: root uucp: root manager: root dumper: root operator: root decode: root postfix: root root: hurd ----------------------------------------------------------- # ln -s /etc/postfix/aliases /etc/ # /usr/bin/newaliases 이제 Postfix 메일시스템의 환경설정을 해 주어야 합니다. 다음은 환경설정 파일의 중요한 변경사항만 간추린 것입니다. # cat /etc/postfix/main.cf ----------------------------------------------------------- myhostname = mydomain.co.kr myorigin = $myhostname mydestination = $myhostname relay_domains = $mydestination, /etc/postfix/relay-domains alias_maps = ldap:ldapsource ########################################### # LDAP lookup ########################################### ldapsource_server_host = 127.0.0.1 ldapsource_search_base = ou=People,dc=mydomain,dc=co.kr ldapsource_timeout = 10 ldapsource_bind = yes #ldapsource_bind_dn = cn=root,dc=mydomain,dc=co.kr #ldapsource_bind_pw = your_rootdn_passwd ldap_query_filter = (&(mailacceptinggeneralid=%s)(!(|(maildrop="*|*")(maildrop="*:*")))) ldap_query_filter = (&(mailacceptinggeneralid=%s)(!(maildrop="*|*"))) biff = no ############################################ # 각종 제한 설정 ############################################ bounce_size_limit = 50000 command_time_limit = 1000 default_process_limit = 50 deliver_lock_attempts = 5 deliver_lock_delay = 1 duplicate_filter_limit = 1000 fork_attempts = 5 fork_delay = 1 header_size_limit = 102400 # 메시지 크기 제한 # 20M 로 설정 message_size_limit = 20971520 qmgr_message_active_limit = 1000 qmgr_message_recipient_limit = 1000 queue_minfree = 209715200 stale_lock_time = 500 transport_retry_time = 60 보다 상세한 설정 내용은 www.postfix.org 의 문서들을 참조하세요. 앞으로 계속 Postfix 를 사용하실 계획이라면 반드시 읽어보셔야 합니다. 이렇게 하면 일단 대충의 설정작업은 끝난셈입니다. 한 번 다음과 같이 메일을 보내보세요. ------------------------------------------------------------ $ telnet mail.coredump.co.kr 25 Trying 210.97.227.131... Connected to coredump.co.kr. Escape character is '^]'. 220 coredump.co.kr ESMTP Postfix mail from: 250 Ok rcpt to: 250 Ok data 354 End data with . Subject: Test mail... From: z3n0 To: sleepycat Hello Postfix!!!! -.-;; . 250 Ok: queued as D6D2787F0 quit 221 Bye Connection closed by foreign host. ------------------------------------------------------------ 위 테스트가 잘 안된다면 이전 과정 어딘가에 문제가 있는 것입니다. Postfix 문서를 잘 읽어보신 후 이전 과정들을 다시 시도해 보세요. Cyrus IMAPD =========== 여기서는 cyrus imapd 1.6.24 버전을 예로 설명드리겠습니다. 이 버전은 좀 오래된 버전이라 사실 권장하고 싶지는 않습니다. 저는 2.0.12 를 사용합니다만, 2.0.x 는 설치가 상당히 까다롭습니다. 설명해야할 것이 너무 많아 다음 기회로 미루기로 하죠. -_-;; 조만간 시간을 내서 정리하도록 하겠습니다. $ wget ftp://ftp.andrew.cmu.edu/pub/cyrus-mail/cyrus-imapd-1.6.24.tar.gz $ gzip -dc cyrus-imapd-1.6.24.tar.gz | tar xvf - $ cd cyrus-imapd-1.6.24 $ cd makedepend $ ./configure $ make $ export PATH=`pwd`:$PATH $ cd .. 위의 내용은 대충 아시는 내용일 것입니다. 이제 본격적인 설치과정이 남아있는데, 주의할 것이 있습니다. cyrus imapd 는 메시지 헤더에 7비트 문자만 허용하도록 되어 있습니다. 7비트 이외에 다른 문자가 왔을 경우 아예 메일을 reject 하거나, 'X'로 대체해 버립니다. 때문에, Subject: 에 한글 제목이 들어가거나, From: 이나 To:, Cc: 등에 한글 이름등이 base64 인코딩없이 들어갈 경우, 문제가 생깁니다. 이를 해결하기 위해서는 다음과 같이 소스를 약간 고쳐주어야 합니다. $ vi imap/message.c ----------------------------------------------------------- 다음 네 줄을 주석 처리합니다. } else { /* We have been configured to munge all mail of this form. */ *p = 'X'; ----------------------------------------------------------- 이제 컴파일을 준비합니다. $ env CC="gcc" \ CFLAGS="-O6" \ LDFLAGS="-s" \ ./configure \ --with-cyrus-prefix=/usr/cyrus \ --with-cyrus-user=cyrus \ --with-cyrus-group=mail \ --with-statedir=/var \ --with-sasldir=/usr \ --with-auth=unix \ --without-notify \ --without-inn \ --without-krb \ --with-tcl=/usr 여기서 곧장 컴파일할 경우 레드햇 계열의 시스템에서는 에러가 발생할 것입니다. 문제는 com_err.h 를 include 하는 부분에 기인하는데 다음과 같이 소스를 수정해 주면 해결 됩니다. (음.. 저는 redhat 을 사용하지 않기 때문에 확실치는 않군요.. 좀 오래전에 작성했던 부분이라... -_-; 혹시 한번 해 보시고 틀리다면 저에게 알려주시기 바랍니다.) $ perl -p -i -e 's/com_err\.h/et\/com_err\.h/g' imap/*.c $ perl -p -i -e 's/com_err\.h/et\/com_err\.h/g' timsieved/*.c 이제 컴파일하면 되겠죠. $ make depend $ make 컴파일이 제대로 되지 않는다면, config.log 등을 잘 살펴보고 혹시 필요한 라이브러리 등이 설치되어 있지 않는지 확인해 보세요. IMAPD 의 수퍼유저를 생성해 줍니다. $ su # /usr/sbin/useradd -c "Cyrus imapd owner" -d /no/where -g mail \ -s /bin/bash -u 76 -r cyrus 인스톨합니다. # make install 이 버전의 cyrus imapd 는 설치후 퍼미션등을 자동으로 변경해 주지 않습니다. (지금 확인해보지는 않았지만, tools/mkimap 스크립트가 아래에서 퍼미션 및 디렉토리 생성해 주는 과정 등을 자동으로 해주는 걸로 알고 있습니다. 그러나, 한번쯤 수동으로 만들어보는 것도 도움이 되리라 생각됩니다.) cyrus 가 설치된 디렉토리의 퍼미션 변경해 줍니다. 이 과정을 생략하면, Postfix 가 받은 메일을 Cyrus 에게 전달하는 과정에서 에러가 발생합니다. # chmod -R o+rx /usr/cyrus # chmod 4555 /usr/cyrus/bin/deliver Cyrus IMAPD 의 기본 설정파일을 만들어 줍니다. 여기서는 /usr/local/cyrus 이하를 사용하도록 하고 있지만, Cyrus 문서에서 설명하고 있는 /var/imap 등을 사용해도 됩니다. 다만, 그럴 경우 아래의 설명 중 디렉토리 부분을 적절히 변경하셔야 합니다. # vi /etc/imapd.conf ----------------------------------------------------------- configdirectory: /usr/local/cyrus/imap partition-default: /usr/local/cyrus/spool admins: cyrus allowanonymouslogin: no umask: 077 quotawarn: 80 timeout: 30 autocreatequota: 10240 logtimestamps: no sasl_maximum_layer: 256 sasl_minimum_ldyer: 0 sasl_pwcheck_method: PAM sasl_auto_transition: no sieveusehomedir: false sievedir: /usr/local/cyrus/sieve sieve_maxscriptsize: 100 sieve_maxscripts: 5 ----------------------------------------------------------- 주목하실 부분은 sasl_pwcheck_method: PAM 라고 된 부분입니다. 바로 이 항목 때문에 Cyrus IMAPD 의 기본 인증 라이브러리인 SASL 이 PAM 을 사용하게 되는 것입니다. 또, PAM_LDAP 을 설치하면서, IMAP 과 POP3 는 LDAP 인증을 사용하도록 했으므로, SASL --> PAM --> LDAP 와 같이 결과적으로 LDAP을 통해 인증절차를 거치게 됩니다. SASL 에서 Cyrus 관련 인증을 어떻게 처리할지도 설정해 줍니다. # vi /usr/lib/sasl/Cyrus.conf ----------------------------------------------------------- pwcheck_method:PAM ----------------------------------------------------------- # touch /etc/sasldb # chown cyrus:mail /etc/sasldb # chmod 644 /etc/sasldb 좀 부수적인 내용이긴 하지만, 로그 관련 설정도 해 줍니다. # vi /etc/logrotate.d/cyrus-imapd ----------------------------------------------------------- /var/log/imapd.log { nocompress } ----------------------------------------------------------- # vi /etc/syslog.conf ----------------------------------------------------------- local6.debug /var/log/imapd.log ----------------------------------------------------------- # killall -HUP syslogd # touch /var/log/imapd.log # chmod 640 /var/log/imapd.log # vi /etc/cron.daily/cyrus-imapd ----------------------------------------------------------- #!/bin/sh su cyrus -s /bin/sh -c '/usr/cyrus/bin/deliver -E 3' ----------------------------------------------------------- # chmod +x /etc/cron.daily/cyrus-imapd 위와 같이 하여 로그 설정 및 로그로테이트까지 마쳤습니다. 이제 tools/mkimap 스크립트가 대행 주는 일을 수동으로 처리해 보죠. # mkdir /usr/local/cyrus # mkdir /usr/local/cyrus/imap # chown cyrus:mail /usr/local/cyrus/imap # chmod 750 /usr/local/cyrus/imap # cd /usr/local/cyrus/imap # true >> mailboxes # mkdir user quota proc log msg deliverdb # cd quota # mkdir a b c d e f g h i j k l m n o p q r s t u v w x y z # cd .. # chown -R cyrus:mail * # cd /usr/local/cyrus # mkdir spool # chown cyrus:mail spool # chmod 750 spool # ln -s /usr/cyrus/bin/imapd /usr/sbin/imapd # ln -s /usr/cyrus/bin/pop3d /usr/sbin/ipop3d # mkdir /usr/sieve # cd /usr/sieve # mkdir a b c d e f g h i j k l m n o p q r s t u v w x y z # chown -R cyrus:mail /usr/local/cyrus/sieve 여기까지 끝났다면 기본적인 설정은 모두 끝난 셈입니다. 나머지는 데몬을 구동하는 설정을 해주고, Postfix 가 받은 메일을 사용자의 메일박스로 전달하기 위해 Cyrus 의 deliver 를 이용하도록 조율하는 일만 남았습니다. Cyrus IMAP 2.0.x 은 독립실행형 데몬방식이기 때문에 inetd 를 사용하지 않지만, 1.6.x 까지는 inetd 를 통해 데몬을 실행합니다. 여기서는 전통적인 inetd 보다는 요새 인기를 얻고 있지만, cyrus 의 문서에서는 설명하지 않고 있는 xinetd 를 이용해 설정하는 방법을 보여드리겠습니다. ----------------------------------------------------------- # vi /etc/xinetd.d/imap ----------------------------------------------------------- service imap { socket_type = stream wait = no user = cyrus server = /usr/sbin/tcpd server_args = imapd log_on_success += USERID log_on_failure += USERID } ----------------------------------------------------------- # vi /etc/xinetd.d/ipop3 ----------------------------------------------------------- service ipop3d { socket_type = stream wait = no user = cyrus server = /usr/sbin/tcpd server_args = ipop3d log_on_success += USERID log_on_failure += USERID } ----------------------------------------------------------- # vi /etc/xinetd.d/sieve (xinetd 인 경우) ----------------------------------------------------------- service sieve { socket_type = stream wait = no user = cyrus server = /usr/cyrus/bin/timsieved server_args = timsieved } ----------------------------------------------------------- 다음과 같이 /etc/services 에 각 항목들을 추가해 줍니다. 서비스가 이미 존재한다면 변경해줄 필요는 없습니다. # vi /etc/services ----------------------------------------------------------- pop3 110/tcp imap 143/tcp imsp 406/tcp sieve 2000/tcp ----------------------------------------------------------- 이제 Postfix 의 master.cf 와 main.cf 를 수정하여 메시지의 로컬 전달 매카니즘을 조율합니다. # vi /etc/postfix/master.cf ----------------------------------------------------------- cyrus unix - n n - - pipe flags=R user=cyrus argv=/usr/cyrus/bin/deliver -e \ -m ${extension} ${user} ----------------------------------------------------------- # vi /etc/postfix/main.cf ----------------------------------------------------------- mailbox_transport = cyrus ----------------------------------------------------------- Postfix 의 데몬이 /usr/cyrus/bin/deliver 를 제대로 실행할 수 있도록 mail 그룹에 postfix 를 추가합니다. # vi /etc/group ----------------------------------------------------------- mail:x:12:mail,postfix ----------------------------------------------------------- 이제 관련된 모든 데몬들을 다시 시작합니다. # killall -HUP slapd # /usr/sbin/postfix reload # /etc/rc.d/init.d/xinetd restart Cyrus IMAP 가 자동으로 사용자의 메일박스를 생성해 주지 않기 때문에 제공되는 콘솔 관리툴인 cyradm 을 이용하여 메일박스를 생성해 줍니다. $ /usr/local/bin/cyradm -user cyrus localhost ----------------------------------------------------------- Password: localhost> cm user.hurd localhost> sq user.hurd 10000 localhost> quit ----------------------------------------------------------- $ /usr/local/bin/cyradm -user hurd localhost ----------------------------------------------------------- Password: localhost> cm INBOX.OUTBOX localhost> cm INBOX.TRASH localhost> cm INBOX.TEMP 여기서는 간단한 예로 hurd 라는 사용자를 생성하고 기본 쿼타를 10MB 로 제한하고 다시 hurd 권한으로 로그인한 후 몇 개의 폴더를 생성해 주었습니다. Cyrus IMAP 에 기본적으로 포함되어 있는 서버측 메일 필터링 언어인 Sieve 도 테스트해 봅시다.(저는 개인적으로 sieve 를 굉장히 좋아합니다 :-) $ vi myscript.script ----------------------------------------------------------- require ["reject", "fileinto"]; if address :contains :all "From" "hurd@mydomain.co.kr" { reject "Testing.."; } ----------------------------------------------------------- $ /usr/local/bin/installsieve -m PLAIN -u hurd -i myscript.script localhost Please enter your password: $ /usr/local/bin/installsieve -l -m PLAIN -u hurd localhost Please enter your password: Authentication succeeded. You have the following scripts on the server: myscript <- Active Sieve Script 이렇게 확인한 다음 hurd@mydomain.co.kr 에서 메일을 보내서 reject 되는지 확인합니다. 여기서 다루지 않았지만 앞으로 다루고 싶은 것들 ============================================== - Cyrus 2.0.x 버전 대의 설치 방법 - SSL + Cyrus IMAPD - LMTP 를 이용한 SMTP, IMAPD 분산 처리 - Cyrus Murder 를 이용한 메일박스 분산 처리 - Sieve 필터링 언어에 관한 보다 풍부한 설명