+ -
当前位置:首页 → 问答吧 → Nginx 使用 Perl 进行 IMAP 的认证

Nginx 使用 Perl 进行 IMAP 的认证

时间:2011-01-19

来源:互联网

首先要使用以下编译参数引入 perl 和邮件模块

./configure --with-http_perl_module --with-mail


[代码] nginx.conf
  1. user  nobody;
  2. worker_processes  1;
  3. error_log  logs/error.log  info;
  4. pid        logs/nginx.pid;

  5. events {
  6.   worker_connections  1024;
  7.   multi_accept on;
  8. }

  9. http {
  10.   perl_modules  perl/lib;
  11.   perl_require  mailauth.pm;

  12.   server {
  13.     location /auth {
  14.       perl  mailauth::handler;
  15.     }
  16.   }
  17. }

  18. mail {
  19.   auth_http  127.0.0.1:80/auth;

  20.   pop3_capabilities  "TOP"  "USER";
  21.   imap_capabilities  "IMAP4rev1"  "UIDPLUS";

  22.   server {
  23.     listen     110;
  24.     protocol   pop3;
  25.     proxy      on;
  26.   }

  27.   server {
  28.     listen     143;
  29.     protocol   imap;
  30.     proxy      on;
  31.   }
  32. }
复制代码
[代码] mailauth.pm
  1. package mailauth;
  2. use nginx;
  3. use DBI;
  4. my $dsn="DBI:mysql:database=DBNAME;host=HOSTNAME";
  5. our $dbh=DBI->connect_cached($dsn, 'dbusername', 'dbpass', {AutoCommit => 1});
  6. our $sth=$dbh->prepare("select password,mail_server from mailaccounts where username=? limit 1");

  7. our $auth_ok;
  8. our $mail_server_ip={};
  9. our $protocol_ports={};
  10. $mail_server_ip->{'mailhost01'}="192.168.1.22";
  11. $mail_server_ip->{'mailhost02'}="192.168.1.33";
  12. $protocol_ports->{'pop3'}=110;
  13. $protocol_ports->{'imap'}=143;

  14. sub handler {
  15.   my $r = shift;
  16.   $auth_ok=0;

  17.   $sth->execute($r->header_in("Auth-User"));
  18.   my $hash=$sth->fetchrow_hashref();
  19.   # assuming that the query results password and mail_server
  20.   # assuming that the password is in crypt format

  21.   if (crypt($r->header_in("Auth-Pass"), $hash->{'password'}) eq $r->header_in("Auth-Pass")){
  22.     $auth_ok=1;
  23.   }
  24.   if ($auth_ok==1){
  25.     $r->header_out("Auth-Status", "OK") ;
  26.     $r->header_out("Auth-Server", $mail_server_ip->{$hash->{'mail_server'}});
  27.     $r->header_out("Auth-Port", $protocol_ports->{$r->header_in("Auth-Protocol")});
  28.   } else {
  29.     $r->header_out("Auth-Status", "Invalid login or password") ;
  30.   }

  31.   $r->send_http_header("text/html");

  32.   return OK;
  33. }

  34. 1;
  35. __END__
复制代码

作者: lockend   发布时间: 2011-01-19

nginx作为mail的反向代理,设计上就有问题。
它非得加个强行认证,其实将认证信息转发给realserver由后端realserver来认证不就得了么?
个人觉得很少有需求再在nginx这里设置一层认证,不管是LDAP还是啥也好。
结果,在需要nginx的mail反向代理时,不得不多此一举自己搞个认证模块。
我上次就非常恼怒的写了一个认证代码全部加起来不到5行,一路返回OK骗过nginx这个SB设置就行。

作者: 兰花仙子   发布时间: 2011-01-19