popとimap
# apt-get install courier-pop-ssl courier-imap-ssl
でcourier-pop(-ssl)、courier-imap(-ssl)がインストールされます。
そのままではldapアカウントはログイン対象になりませんので、
# vi /etc/pam.d/pop および imap
auth sufficient pam_ldap.so
account sufficient pam_ldap.so
password sufficient pam_ldap.so
auth required pam_unix.so nullok use_first_pass
account required pam_unix.so
password required pam_unix.so try_first_pass
session required pam_unix.so
とすればpam経由でldapアカウントにログインできます。
pam経由で認証するので、この使い方においては
courier-ldapを導入する必要はありません。
なお、pop-ssl、imap-sslは外部に公開できますが、
imapでないsslはパスワードに平文が流れるので外部に公開しないようにします。
popも外部に公開しない方がいいのですが、
sslやpptpをサポートしないクライアントのために、
APOPを追加してパスワードを隠匿するようにします。
APOPの追加
slapdはAPOP認証対応に改造しておいてください。
% apt-get source courier-pop Courierメールサーバ全部が入ります
% cd courier-0.37.3
% vi imap/pop3login.c
...
int main(int argc, char **argv)
{
char *user=0;
char *p;
char buf[BUFSIZ];
int c;
const char *ip=getenv("TCPREMOTEIP");
unsigned char cred[BUFSIZ+8];
const char b64[]=
"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
...
if (authmoduser(argc, argv, 60, 5))
{
fprintf(stderr, "INFO: Connection, ip=[%s]\n", ip);
// printf("+OK Hello there.\r\n");
sprintf(buf, "MYSECRET%d%d", getpid(), time(0));
md5_digest(buf, strlen(buf), cred+17);
cred[16]= '<';
for(c= 17; c<17+16; c++) cred[c]= b64[cred[c]&0x3f];
p= getenv("TCPLOCALIP");
if(p==0) p= "";
snprintf(cred+17+16, sizeof(cred)-17-16, "@%s>", p);
cred[sizeof(cred)-1]= 0;
printf("+OK Hello there. %s\r\n", cred+16);
}
...
} else if (strcmp(p, "PASS") == 0)
{
p=strtok(0, "\t\r");
if(getenv("POP3NOPLAIN")&&getenv("POP3NOPLAIN")[0]) p= 0;
if (!user || p == 0)
{
printf("-ERR USER/PASS required.\r\n");
fflush(stdout);
continue;
}
authmod_login(argc-1, argv+1, "pop3", user, p);
} else if (strcmp(p, "APOP") == 0) {
char *pass;
int i;
p=strtok(0, " \t\r");
if(p==0) {
printf("-ERR user/hash required.\r\n");
fflush(stdout);
continue;
}
if(user) free(user);
if((user= malloc(strlen(p)+1))==0) {
printf("-ERR Server out of memory, aborting connection.\r\n");
fflush(stdout);
perror("malloc");
exit(1);
}
strcpy(user, p);
p= strtok(0, "\t\r");
if(p) {
for(i= 0; i<32; i++) {
c= p[i];
if(!(c>='0'&&c<='9'||c>='A'&&c<='F'
||c>='a'&&c<='f')) { p= 0; break; }
}
}
if(p==0) {
printf("-ERR user/hash required.\r\n");
fflush(stdout);
continue;
}
for(i= 0; i<16; i++) {
sscanf(p+i*2, "%2x", &c);
cred[i]= c;
}
c= strlen(cred+16)+16;
if((pass= malloc(6+(c+2)/3*4+1))==0) {
printf("-ERR Server out of memory, aborting connection.\r\n");
fflush(stdout);
perror("malloc");
exit(1);
}
strcpy(pass, "{APOP}");
p= pass+6;
for(i= 0; i<c; i+=3) {
int e0, e1, e2;
e0= cred[i];
e1= i+1<c?cred[i+1]:0;
e2= i+2<c?cred[i+2]:0;
*p++= b64[e0>>2];
*p++= b64[e0<<4&0x30|e1>>4];
*p++= i+1<c?b64[e1<<2&0x3c|e2>>6]:'=';
*p++= i+2<c?b64[e2&0x3f]:'=';
}
*p= 0;
authmod_login(argc-1, argv+1, "pop3", user, pass);
free(pass);
}
...
% vi imap/pop3dcapa.c
...
printf("TOP\r\nUSER\r\nAPOP\r\nLOGIN-DELAY 10\r\nPIPELINING\r\nUIDL\r\nIMPLEMENTATION Courier Mail Server\r\n.\r\n");
...
修正はこれだけです。MYSECRETはプロセスIDを推察されないためなのでそのままでもまあいいです。コンパイルしてインストールします。
# dpkg-buildpackage
(この時に出るコンパイルに必要なパッケージ群はapt-get installで取ってきます。)
# cd ..
# dpkg -i courier-pop_0.37.3-xxx.deb
入れ替えるのは/usr/lib/courier/courier/courierpop3loginだけですので、
% debian/rules build
# /etc/init.d/courier-pop stop
# /etc/init.d/courier-pop-ssl stop
# cd imap
# strip pop3login; cp pop3login /usr/lib/courier/courier/courierpop3login
# /etc/init.d/courier-pop start
# /etc/init.d/courier-pop-ssl start
でもかまいません。
いずれにせよapt-get upgradeされないようにhold-stateにしておくか、
upgradeかかったら再コピーすることを忘れずに。
サイト内部のみ平文ログインを許可
この改造で、環境変数POP3NOPLAINが空文字以外に設定されていると、
平文ログインを受け付けないようになります。
これを利用して、couriertcpdの-accessオプションと組み合わせることにより、
サイト外部からのログインはapopしか許可せずに、
サイト内部からは通常の平文ログインを許可するようにできます。
(sslの場合は外部からでも平文ログインを許可しておいて安全です。)
# cd /etc/courier
# vi pop3d
...
POP3AUTH="" AUTH使うPOPクライアントは少ないですが、LOGINは書かないようにします
...
TCPDOPTS="-nodnslookup -noidentlookup -access=/etc/courier/pop3daccess.dat"
...
# vi pop3d-ssl
... pop3dでの設定をオーバライドし、平文ログインを許可します
TCPDOPTS="-nodnslookup -noidentlookup"
...
# vi pop3daccess
127.0.0.1 allow,POP3NOPLAIN 許可するものを空文字に設定します
10 allow,POP3NOPLAIN IPアドレスとの間はタブ文字1つです
192.168 allow,POP3NOPLAIN
172.16 allow,POP3NOPLAIN
...
172.31 allow,POP3NOPLAIN
* allow,POP3NOPLAIN=1 許可しないものは何か設定します
# makedat -src=pop3daccess -tmp=pop3daccess.tmp -file=pop3daccess.dat
# /etc/init.d/courier-pop restart
なお、/etc/courier/pop3daccessを書き換えたらmakedatの実行および
popデーモンの再起動が必要です。