Tag Archive for 'postfix'

一个Python脚本,让OpenVPN使用postfix邮箱帐号进行身份认证

这几天配置OpenVPN,使用了用户名密码的身份认证方式,借助已有的postfix邮箱帐号,省去了再为每个人设置用户名密码的麻烦。

原理很简单,OpenVPN服务器配置里有这样一句:

auth-user-pass-verify /etc/openvpn/auth-postfix-mailbox.py via-env

就是说要用/etc/openvpn/auth-postfix-mailbox.py这个脚本来验证用户名和密码。用户名和密码如何传递给它呢?via-env,环境变量。

脚本如下:

  1. #!/usr/bin/env python
  2.  
  3. import os
  4. import sys
  5. from MySQLdb import *
  6. import md5crypt
  7.  
  8. def auth(username, password):
  9.   conn = connect (host = 'localhost',
  10.                   user = 'dbuser',
  11.                   passwd = 'dbpasswd',
  12.                   db = 'postfix')
  13.   cursor = conn.cursor()
  14.   cursor.execute("""
  15.       select password from mailbox
  16.       where username=%s
  17.       and active=1
  18.     """, (username))
  19.   row = cursor.fetchone()
  20.   if row == None:
  21.     return 1
  22.   crypt = md5crypt.md5crypt(password, row[0])
  23.   cursor.execute("""
  24.       select * from mailbox
  25.       where username=%s
  26.       and password=%s
  27.       and active=1
  28.    """, (username,crypt))
  29.   row = cursor.fetchone()
  30.   cursor.close()
  31.   conn.close()
  32.   if row == None:
  33.     return 1
  34.   return 0
  35.  
  36. def main():
  37.   status = 0
  38.   try:
  39.     username = os.environ['username']
  40.     password = os.environ['password']
  41.     status = auth(username, password)
  42.   except:
  43.     sys.exit(1)
  44.  
  45.   sys.exit(status)
  46.  
  47. if __name__ == "__main__":
  48.   main()

由于postfix使用md5认证,所以需要用md5crypt这个模块,从这里可以下载到。

postfix和postgrey问题

公司的邮件服务器收不到外来邮件了,日志里有这样的错误:

554 Service unavailable; Client host [xxx.xxx.xxx.xxx] blocked using relays.ordb.org; ordb.org was shut down on December 18, 2006. Please remove from your mailserver.;

对应main.cf里的配置是这样的:

smtpd_client_restrictions = permit_mynetworks, warn_if_reject reject_rbl_client sbl.spamhaus.org, warn_if_reject reject_rbl_client relays.ordb.org, warn_if_reject reject_rbl_client blackholes.easynet.nl, warn_if_reject reject_rbl_client dnsbl.njabl.org

改成只保留smtpd_client_restrictions = permit_mynetworks, 又有新信息出现:

postfix/smtpd[16212]: warning: problem talking to server 127.0.0.1:60000: Connection timed out

127.0.0.1:60000是postgrey工作的端口,用ps和netstat 发现postgrey进程还在,但top命令发现它占用了99%的CPU,而且用/etc/init.d/postgrey stop停不掉,只好kill掉,并改postfix里相应的设置,去掉postgrey检查:

smtpd_recipient_restrictions = reject_unauth_pipelining, permit_mynetworks,permit_sasl_authenticated, reject_non_fqdn_recipient,reject_unauth_destination, check_policy_service inet:127.0.0.1:60000,permit

重启postfix,邮件可以收到了。再恢复smtpd_client_restrictions的配置,去掉relays.ordb.org检查,邮件可以收到。顺便搞清楚了warn_if_reject的含义:有它在时并不真正的拒绝邮件。

postgrey的问题还没找到解决办法,不知道为什么会hang在那里,暂时不用它了。

==== 2008-05-14 ====
补充: 将Berkeley DB由原来的4.3升级到4.4以后,postgrey正常了。
搜索到的相关信息:

bugs.debian.org/cgi-bin/bugreport.cgi?bug=441069

bugs.edge.launchpad.net/ubuntu/gutsy/+source/db4.4…

升级系统导致Postfix的SMTP认证失败(Cyrus-SASL + MySQL)

日志里这样的错误信息:
warning: SASL authentication problem: unable to open Berkeley db /etc/sasldb2: No such file or directory

最终发现原因:main.cf里smtpd_sasl_path的设置错误,可能是更新修改的。
把smtpd_sasl_path=/etc/postfix/sasl:/usr/lib/sasl2改成smtpd_sasl_path=smtpd后,重启postfix和courier-authdaemon,问题解决。

让Postfix使用保存在MySQL中的加了密的密码字段(Ubuntu 6.06 TLS)

这两天在Ubuntu下折腾Postfix + Courier-IMAP + Cyrus-SASL + MySQL + PostfixAdmin,主要参考这个Howto(flurdy.com/docs/postfix/)
配置了Postfix Admin,所以邮件用户的密码用了md5的加密方式存放在MySQL数据库中的(不想用明文)。这样一来,IMAP服务器可以支持加密的密码字段,认证没有问题,但SMTP服务器不行。

Google了好久,发现网上大多数都是使用明文密码的,也有用saslauthd的pam认证方式来做的。我一开始是用明文的,觉得不好(能看到用户的密码,心里不安),又试了pam方式但没成功(不知道为什么,没深究)。最后终于找到牛人给Cyrus-SASL写的patch(针对2.1.19版本的),安装步骤参考 blog.matroid.org/display/26

$ cd ~
$ apt-get source libsasl2
$ sudo apt-get build-dep libsasl2
下载这个为Debian修改过的patch文件
$ wget http://blog.matroid.org/files/20060116-crypted-passwords-for-couriour-and-postfix-in-mysql/cyrus-sasl-2.1.19-checkpw.c.patch_mgr
$ cd cyrus-sasl-2.1.19.dfsg1
$ tar xvzf cyrus-sasl-2.1.19.dfsg1.tar.gz
$ ln -s cyrus-sasl-2.1.19.dfsg1 cyrus-sasl-2.1.19.orig
$ cp ../cyrus-sasl-2.1.19-checkpw.c.patch_mgr debian/patches/28_cyrus-sasl-2.1.19-checkpw.c.patch
做些修改,将patch文件里的cyrus-sasl-2.1.19.org替换为cyrus-sasl-2.1.19.dfsg1,不然会patch会失败。改好后,编译
$ fakeroot debian/rules binary
成功后,安装生成的deb包
$ cd ..
$ sudo dpkg -i *.deb

配置/etc/postfix/sasl/smptd.conf

pwcheck_method: auxprop
auxprop_plugin: sql
allowanonymouslogin: no
allowplaintext: yes
mech_list: PLAIN LOGIN
srp_mda: md5

srvtab: /dev/null
opiekeys: /dev/null

password_format: crypt

sql_user: username
sql_passwd: password
sql_hostnames: sql.example.org
sql_database: database_name
sql_select: SELECT password FROM mailbox WHERE username = '%u@%r'

重启Postfix就可以了。




This work by wolfg is licensed under a Attribution-Noncommercial-Share Alike 2.5 China Mainland.