Accept cookies for analytics, social media, and advertising, or learn more and adjust your preferences. These cookies are on by default for visitors outside the UK and EEA. Privacy Notice.
認証バックエンドとして imap/pop プロキシと同じサーバで nginx-embedded-perl モジュールを使用する
注意
この解決方法は、ユーザ情報をDBから読み込む時にNGINXワーカー全体をブロックするため、実際の使用にはお勧めしません。
この解決方法はISPで 35000+ のメールボックスで2年間今でも使われています。恥ずべき広告が必要であれば、そのISPは Worldsoft です(http://www.worldsoft.info)
IMAP プロキシの例の設定から始めます。異なる設定パラメータについての詳細な情報は、ngx_mail_core_moduleドキュメントを見てください。
組み込みのPerlとメールを使ったNGINXの設定
./configure --with-http_perl_module --with-mail
nginx/conf/nginx.conf
:
user nobody;
worker_processes 1;
error_log logs/error.log info;
pid logs/nginx.pid;
events {
worker_connections 1024;
multi_accept on;
}
http {
perl_modules perl/lib;
perl_require mailauth.pm;
server {
location /auth {
perl mailauth::handler;
}
}
}
mail {
auth_http 127.0.0.1:80/auth;
pop3_capabilities "TOP" "USER";
imap_capabilities "IMAP4rev1" "UIDPLUS";
server {
listen 110;
protocol pop3;
proxy on;
}
server {
listen 143;
protocol imap;
proxy on;
}
}
超高速NGINXベースのauthentifier, nginx/perl/lib/mailauth.pm
:
package mailauth;
use nginx;
use DBI;
my $dsn="DBI:mysql:database=DBNAME;host=HOSTNAME";
our $dbh=DBI->connect_cached($dsn, 'dbusername', 'dbpass', {AutoCommit => 1});
our $sth=$dbh->prepare("select password,mail_server from mailaccounts where username=? limit 1");
our $auth_ok;
our $mail_server_ip={};
our $protocol_ports={};
$mail_server_ip->{'mailhost01'}="192.168.1.22";
$mail_server_ip->{'mailhost02'}="192.168.1.33";
$protocol_ports->{'pop3'}=110;
$protocol_ports->{'imap'}=143;
sub handler {
my $r = shift;
$auth_ok=0;
$sth->execute($r->header_in("Auth-User"));
my $hash=$sth->fetchrow_hashref();
# assuming that the query results password and mail_server
# assuming that the password is in crypt format
if (crypt($r->header_in("Auth-Pass"), $hash->{'password'}) eq $r->header_in("Auth-Pass")){
$auth_ok=1;
}
if ($auth_ok==1){
$r->header_out("Auth-Status", "OK") ;
$r->header_out("Auth-Server", $mail_server_ip->{$hash->{'mail_server'}});
$r->header_out("Auth-Port", $protocol_ports->{$r->header_in("Auth-Protocol")});
} else {
$r->header_out("Auth-Status", "Invalid login or password") ;
}
$r->send_http_header("text/html");
return OK;
}
1;
__END__