这两天解决了几个开发中遇到的疑难杂症,特此篆文记录。
无论在软件项目的实施,还是系统的开发甚至只是编写一小段代码,经常会遇到一些让人白思不得其解的问题,耗费了大量的时间,用尽了办法却位能解决。感觉就有点得了疑难杂症,便访天下名医却不得根治一样。
但最后发现这些问题的症结,往往都是很小小的问题,却不为人所注意,或者隐藏得非常深入,常人难以发现。
Maildrop 的0x0B故障分析及解决
使用maildrop作为VDA/MDA的用户为数不少,绝大多数用户使用maildrop都是因为其过滤能力强,过滤语言灵活,支持Quota,并可与MySQL/LDAP及小型dbm对接,可外挂各种程序,如SpamAssassin,杀毒软件,甚至SMS等,实现复杂的功能。
但是maildrop常见的一个问题就是经常会遇到0x0B的意外退出问题。除了编译器(使用的Gcc c++版本问题)和编译优化指令太高(如高于O2等)的问题外,还有少数问题是不为人们所注意的。
在自己开发一个全新的webmail系统中,maildrop的投递uid/gid都是250,这样的配置跑了几年都没任何问题,工作得非常可靠。但是由于webmail需要直读Maildir,按常规的方法必须设置成setuid/gid程序,或将apache的User/Group设置成250,这样非常麻烦,尤其在新的SELinux下会造成诸多不便,为此使用了Suexec的配置,但是Suexec的RPM包默认UID_MIN >= 500,于是将user/group从250/250改成了1000/1000,结果问题就来了。
投递邮件时,maildrop死活都返回0x0B错误,无论我将user/group改成多少也好,包括mysql里的uidnumber/gidnumber、maildropmysql.config里的default等都改了,完全没有任何效果。
后来再试验su成uid=1000的用户呼叫maildrop发现也是0x0B错误,只有在root权限下没问题,于是又查了maildrop的INSTALL甚至看了source!都是无任何迹象显示与这个错误有关,于是只有google了。但也没什么有效的解决办法。
后来偶然看到一个法文的邮件列表上,看到有人在讨论maildrop的mysql配置,忽然想到,自己的maildrop rpm包自动设置了/etc/maildropmysql.config文件属性是uid=250, gid=250的,于是ls -l /etc/maildropmysql.config一看,原来症结就在这里!
我改了所有该改的地方,就是没有对配置文件的owner/group进行修改,而配置文件原本的属性是600,这样导致了maildrop换成其他uid/gid运行时无法读取配置文件,导致了0x0B错误。执行:
chown -R 1000.1000 /etc/maildropmysql.config
之后一切问题就迎刃而解了。
Webmail解决setuid/gid问题
昨天正在着手解决全新设计的webmail系统setuid/gid的问题,以适应在SELinux下的应用。自己怕麻烦,暂时不想去做相应的policy,所以只有动脑筋了。
幸好RHEL/CentOS/FC3等自带的policy都支持suexec,因此就决定利用suexec来实现与apache不同的运行uid/gid,以达到直接访问Maildir的目的。
在虚拟主机中的配置:
..... SuexecUserGroup vuser vgroup Alias /extmail/ /var/www/cgi-bin/extmail/ <Location "/extmail/cgi"> SetHandler cgi-script Options +ExecCGI </Location> .......
注意: 之所以将cgi程序放到/var/www下是因为Suexec的docroot限制在了这里,详细的suexec编译参数可以通过Suexec -V查看,以下是CentOS 4.1的结果:
-D AP_DOC_ROOT="/var/www" -D AP_GID_MIN=100 -D AP_HTTPD_USER="apache" -D AP_LOG_EXEC="/var/log/httpd/suexec.log" -D AP_SAFE_PATH="/usr/local/bin:/usr/bin:/bin" -D AP_UID_MIN=500 -D AP_USERDIR_SUFFIX="public_html"
最后,将程序及模板等属性全部改为要运行的uid/gid即可:
chown -R vuser.vgroup /var/www/cgi-bin/extmail
重新启动httpd,通过/var/log/httpd/suexec.log可以看到如下的信息:
[2005-07-26 20:55:51]: uid: (1000/vuser) gid: (1000/1000) cmd: folders.cgi
证明配置成功,这样webmail就不必再设置为setuid了,而且apahce也不必以1000/1000的id来运行了。
chdir()引起的模板问题之解决
开发Webmail时,引入了模板机制,这将大大提高了用户修改的便捷程度,也缩短了开发人员的工作周期。但是这几天遇到了一个问题,在调用了Storage::Maildir模块之后,模板的解析就无论如何都不正常了,总说file not found,但明明文件没有任何错误。
而如果先于呼叫Storage::Maildir之前解析模板则完全没问题,开始怀疑是SELinux的问题,但kernel日志里又无任何不妥。
后来通过一点一点分析,包括对template解析库的修改等都印证了各种代码都没有问题。最后将目光放到了Storage::Maildir,该模块在use的时候会利用chdir()初始化当前工作路径,这样做之后,将使cgi程序的工作路径和之前不同了,对于没使用绝对路径进行模板解析的应用,自然会遇到问题。
代码分析:
my $tpl = Ext::Template->new("../html/");
my $mm = Ext::Storage::Maildir;
$tpl->assign(TEST => 1);
restore_path(); # XXX recover working directory
$tpl->process("index.html");
$tpl->print;
....
sub restore_path {
my $src=$ENV{SCRIPT_FILENAME};
$src=~s#(.*)/[^\/]+$#$1#;
chdir($src);
}
上述代码中,在进行模板解析之前,呼叫restore_path(),将工作路径恢复到调用Storage::Maildir之前的原始状态。这样解析就不再有问题了。
自由广告区 |
分类导航 |
邮件新闻资讯: IT业界 | 邮件服务器 | 邮件趣闻 | 移动电邮 电子邮箱 | 反垃圾邮件|邮件客户端|网络安全 行业数据 | 邮件人物 | 网站公告 | 行业法规 网络技术: 邮件原理 | 网络协议 | 网络管理 | 传输介质 线路接入 | 路由接口 | 邮件存储 | 华为3Com CISCO技术 | 网络与服务器硬件 操作系统: Windows 9X | Linux&Uinx | Windows NT Windows Vista | FreeBSD | 其它操作系统 邮件服务器: 程序与开发 | Exchange | Qmail | Postfix Sendmail | MDaemon | Domino | Foxmail KerioMail | JavaMail | Winwebmail |James Merak&VisNetic | CMailServer | WinMail 金笛邮件系统 | 其它 | 反垃圾邮件: 综述| 客户端反垃圾邮件|服务器端反垃圾邮件 邮件客户端软件: Outlook | Foxmail | DreamMail| KooMail The bat | 雷鸟 | Eudora |Becky! |Pegasus IncrediMail |其它 电子邮箱: 个人邮箱 | 企业邮箱 |Gmail 移动电子邮件:服务器 | 客户端 | 技术前沿 邮件网络安全: 软件漏洞 | 安全知识 | 病毒公告 |防火墙 攻防技术 | 病毒查杀| ISA | 数字签名 邮件营销: Email营销 | 网络营销 | 营销技巧 |营销案例 邮件人才:招聘 | 职场 | 培训 | 指南 | 职场 解决方案: 邮件系统|反垃圾邮件 |安全 |移动电邮 |招标 产品评测: 邮件系统 |反垃圾邮件 |邮箱 |安全 |客户端 |