平台: Blueonyx 5.6 + OpenWebmail 2.5.1
下载最新版本的 BlueOnyx , 这套系统还是免费的,前身就是大名鼎鼎的 Sun Cobalt ,当时开发出来是给 ICP 作为 Web host用,系统包括Email Server(SMTP/POP3/IMAP)、FTP Server 、DNS Server、Web Server 全部包括,最适用于ICP主机出租业务了; 介绍就到这里,继续安装。
- 安装OpenWebmail
Blueonyx 的安装就不再说明了,因为就是光盘安装的很简单,只要稍懂英文真的没有什么难度了! 系统是“定制”版本的 CentOS5 ,所以安装软件与CentOS安装没有什么区别,简单点就是取得“软件源库” repo 文件,然后 yum install xxxxxx 即可,跟”大便“的 apt-get 一样很给力的
其实系统自带有 webmail 了,就是SquirrelMail , 但小弟用了Openwebmail快10年了,感觉很顺手,界面也很友好,功能也全部好用,所以先入为主吧,还是需要在这个系统上使用,所以才post该文!
下文内容参考自: http://coding.infoconex.com/page/Installing-OpenWebmail-on-BlueOnyx-server.aspx
1) Grab the latest install of openwebmail from: http://openwebmail.acatysmoof.com/
- Note that I am installing version 2.5.3 however there are 2 versions currently available
2) 下载 openwebmail文件包到 /var/www
- cd /var/www
- wget http://openwebmail.acatysmoof.com/download/release/openwebmail-2.53.tar.gz 或者从 openwebmail 的官网下载最新的版本
- http://openwebmail.org/openwebmail/download/release/openwebmail-2.53.tar.gz
3) 解压文件包
- tar -xvzf openwebmail-2.53.tar.gz
- This will extract files to 2 different directories
- /var/www/cgi-bin/openwebmail
- /var/www/da
ta/openwebmail
4) 更改目录权限为 root:mail
- chown root:mail /var/www/cgi-bin/openwebmail
- chown root:mail /var/www/da
ta/openwebmail
5) 安装Text::Iconv perl模块
- yum install perl-Text-Iconv
或者直接下载rpm包安装
- http://openwebmail.org/openwebmail/download/redhat/rpm/packages/centos5/
下载 perl-Text-Iconv/ 的rpm包到 Blueonyx 中,然后执行
# rpm -i perl-Text-Iconv.xx.xxx.rpm
6) 新建apache配置文件
- 新建 /etc/httpd/conf.d/httpd_openwebmail.conf
- 贴上以下内容或者直接下载该文件: http_openwebmail.conf
### Begin – Added for openwebmail ###
ScriptAlias /webmail “/var/www/cgi-bin/openwebmail/openwebmail.pl”
ScriptAlias /openwebmail “/var/www/cgi-bin/openwebmail/”
Alias /data “/var/www/da ta” <Directory /var/www/cgi-bin/openwebmail>
AllowOverride None
Options +ExecCGI
Order allow,deny
Allow from all
AddHandler cgi-script .cgi .pl
</Directory><Directory “/var/www/da
ta/openwebmail”>
ExpiresActive On
ExpiresByType image/gif A86400
ExpiresByType image/png A86400
ExpiresByType image/jpg A86400
ExpiresByType application/x-javascript A86400
</Directory>### End ###
7) 修改两个openwebmail.conf文件的参数
- vi /var/www/cgi-bin/openwebmail/etc/openwebmail.conf
再者就是
vi /var/www/cgi-bin/openwebmail/etc/default/openwebmail.conf
两个文件里的对应参数都必须按以下修改 -
- auth_module auth_pam_cobalt.pl
- ow_cgidir /var/www/cgi-bin/openwebmail
- ow_cgiurl /openwebmail
- ow_htmldir /var/www/da
ta/openwebmail - ow_htmlurl /da
ta/openwebmail 这里的 auth_pam_cobalt.pl 里 Sun Cobalt 公司专用的验证程序
程序代码来自: http://cobaltfaqs.com/index.php?title=Auth_pam_cobalt.pl&redirect=no以上内容请在 /var/www/cgi-bin/openwebmail/auth 目录下创建
#*************************** auth_pam_cobalt.pl ********************************
package ow::auth_pam_cobalt; use strict; # # auth_pam.pl - authenticate user with PAM # # 2002/08/01 webmaster.AT.pkgmaster.com # add check for nologin, validshell, cobaltuser # based on work from Trevor.Paquette.AT.TeraGo.ca # 2001/10/05 tung.AT.turtle.ee.ncku.edu.tw # # The co
de of check_userpassword and change_userpassword is from # the example co de of Authen::PAM by Nikolay Pelov <nikip.AT.iname.com> # Webpage is available at http://www.cs.kuleuven.ac.be/~pelov/pam # ########## No configuration required from here ################### use Authen::PAM; use Fcntl qw(:DEFAULT :flock); require "modules/filelock.pl"; require "modules/tool.pl"; my %conf; if (($_=ow::tool::find_configfile('etc/auth_pam.conf', 'etc/defaults/auth_pam.conf')) ne '') { my ($ret, $err)=ow::tool::load_configfile($_, \%conf); die $err if ($ret<0); } my $servicename = $conf{'servicename'} || "login"; my $passwdfile_plaintext = $conf{'passwdfile_plaintext'} || "/etc/passwd"; my $check_nologin = $conf{'check_nologin'} || 'no'; my $check_shell = $conf{'check_shell'} || 'no'; my $check_cobaltuser = $conf{'check_cobaltuser'} || 'no'; ########## end init ############################################## # routines get_userinfo() and get_userlist still get da ta from a passwdfile # instead of PAM, you may have to rewrite if it does notfit your requirement # 0 : ok # -2 : parameter format error # -3 : authentication system/internal error # -4 : user doesn't exist sub get_userinfo { my ($r_config, $user)=@_; return(-2, 'User is null') if ($user eq ''); my ($uid, $gid, $realname, $homedir); if ($passwdfile_plaintext eq "/etc/passwd") { ($uid, $gid, $realname, $homedir)= (getpwnam($user))[2,3,6,7]; } else { if ($passwdfile_plaintext=~/\|/) { # maybe NIS, try getpwnam first ($uid, $gid, $realname, $homedir)= (getpwnam($user))[2,3,6,7]; } if ($uid eq "") { # else, open file directly ($uid, $gid, $realname, $homedir)= (getpwnam_file($user, $passwdfile_plaintext))[2,3,6,7]; } } return(-4, "User $user doesn't exist") if ($uid eq ""); # get other gid for this user in /etc/group while (my @gr=getgrent()) { $gid.=' '.$gr[2] if ($gr[3]=~/\b$user\b/ && $gid!~/\b$gr[2]\b/); } # use first field on ly $realname=(split(/,/, $realname))[0]; # guess real homedir under sun's automounter $homedir="/export$homedir" if (-d "/export$homedir"); return(0, "", $realname, $uid, $gid, $homedir); } # 0 : ok # -1 : function not supported # -3 : authentication system/internal error sub get_userlist { # on ly used by openwebmail-tool.pl -a my $r_config=$_[0]; my @userlist=(); my $line; # a file should be locked on ly if it is local accessable if ( -f $passwdfile_plaintext) { ow::filelock::lock($passwdfile_plaintext, LOCK_SH) or return (-3, "Couldn't get read lock on $passwdfile_plaintext", @userlist); } open(PASSWD, $passwdfile_plaintext); while (defined($line=<PASSWD>)) { next if ($line=~/^#/); chomp($line); push(@userlist, (split(/:/, $line))[0]); } close(PASSWD); ow::filelock::lock($passwdfile_plaintext, LOCK_UN) if ( -f $passwdfile_plaintext); return(0, "", @userlist); } # globals passed to inner function to avoid closure effect use vars qw($pam_user $pam_password $pam_newpassword $pam_convstate); # 0 : ok # -2 : parameter format error # -3 : authentication system/internal error # -4 : password incorrect sub check_userpassword { my $r_config; local ($pam_user, $pam_password); # localized global to make reentry safe ($r_config, $pam_user, $pam_password)=@_; return (-2, "User or password is null") if ($pam_user eq '' || $pam_password eq ''); sub checkpwd_conv_func { my @res; while ( @_ ) { my $co de = shift; my $msg = shift; my $ans = ""; if ($co de == PAM_PROMPT_ECHO_ON() ) { $ans = $pam_user; } elsif ($co de == PAM_PROMPT_ECHO_OFF() ) { $ans = $pam_password; } push @res, (PAM_SUCCESS(),$ans); #ow::tool::log_time("co de:$co de, msg:$msg, ans:$ans\n"); # debug } push @res, PAM_SUCCESS(); return @res; } # disable SIG CHLD since authsys in PAM may fork process local $SIG{CHLD}; undef $SIG{CHLD}; my ($pamh, $ret, $errmsg); if ( ref($pamh = new Authen::PAM($servicename, $pam_user, \&checkpwd_conv_func)) ) { my $tty_name = ""; my $error=$pamh->pam_set_item(PAM_TTY(), $tty_name); $error=$pamh->pam_authenticate(); if ($error==0) { ($ret, $errmsg)= (0, ""); } else { ($ret, $errmsg)= (-4, "pam_authticate() err $error, ".pam_strerror($pamh, $error)); } } else { ($ret, $errmsg)= (-3, "PAM init error $pamh"); } $pamh = 0; # force Destructor (per docs) (invokes pam_close()) return($ret, $errmsg) if ($ret<0); # emulate pam_nologin.so if ($check_nologin=~/yes/i && -e "/etc/nologin") { return (-4, "/etc/nologin found, all logins are suspended"); } # emulate pam_shells.so if ($check_shell=~/yes/i && !has_valid_shell($pam_user)) { return (-4, "user $pam_user doesn't have valid shell"); } # valid user on cobalt ? if ($check_cobaltuser=~/yes/i) { my $cbhttphost=$ENV{'HTTP_HOST'}; $cbhttphost=~s/:\d+$//; # remove port number my $cbhomedir="/home/sites/$cbhttphost/users/$pam_user"; if (!-d $cbhomedir) { return (-4, "This cobalt user $pam_user doesn't has homedir $cbhomedir"); } } return (0, ""); } # 0 : ok # -1 : function not supported # -2 : parameter format error # -3 : authentication system/internal error # -4 : password incorrect sub change_userpassword { local ($pam_user, $pam_password, $pam_newpassword); # localized global to make reentry safe my $r_config; ($r_config, $pam_user, $pam_password, $pam_newpassword)=@_; return (-2, "User or password is null") if ($pam_user eq '' || $pam_password eq '' || $pam_newpassword eq ''); local $pam_convstate=0; # localized global to make reentry safe sub changepwd_conv_func { my @res; while ( @_ ) { my $co de = shift; my $msg = shift; my $ans = ""; if ($co de == PAM_PROMPT_ECHO_ON() ) { $ans = $pam_user; } elsif ($co de == PAM_PROMPT_ECHO_OFF() ) { if ($pam_convstate>1 || $msg =~ /new/i ) { $ans = $pam_newpassword; } else { $ans = $pam_password; } $pam_convstate++; } push @res, (PAM_SUCCESS(),$ans); #ow::tool::log_time("co de:$co de, msg:$msg, ans:$ans\n"); # debug } push @res, PAM_SUCCESS(); return @res; } # disable SIG CHLD since authsys in PAM may fork process local $SIG{CHLD}; undef $SIG{CHLD}; my ($pamh, $ret, $errmsg); if (ref($pamh = new Authen::PAM($servicename, $pam_user, \&changepwd_conv_func)) ) { my $error=$pamh->pam_chauthtok(); if ( $error==0 ) { ($ret, $errmsg)= (0, ""); } else { ($ret, $errmsg)= (-4, "pam_authtok() err $error, ".pam_strerror($pamh, $error)); } } else { ($ret, $errmsg)= (-3, "PAM init error $pamh"); } $pamh = 0; # force Destructor (per docs) (invokes pam_close()) return($ret, $errmsg); } ########## misc support routine ################################## # this routine is slower than system getpwnam() but can work with file # other than /etc/passwd. ps: it always return '*' for passwd field. sub getpwnam_file { my ($user, $passwdfile_plaintext)=@_; my ($name, $passwd, $uid, $gid, $gcos, $dir, $shell); return("", "", "", "", "", "", "", "", "") if ($user eq ""); open(PASSWD, "$passwdfile_plaintext"); while(<PASSWD>) { next if (/^#/); chomp; ($name, $passwd, $uid, $gid, $gcos, $dir, $shell)=split(/:/); last if ($name eq $user); } close(PASSWD); if ($name eq $user) { return($name, "*", $uid, $gid, 0, "", $gcos, $dir, $shell); } else { return("", "", "", "", "", "", "", "", ""); } } sub has_valid_shell { my $user=$_[0]; my ($name, $shell); if ($passwdfile_plaintext eq "/etc/passwd") { $shell = (getpwnam($user))[8]; } else { if ($passwdfile_plaintext=~/\|/) { # maybe NIS, try getpwnam first ($name, $shell)= (getpwnam($user))[0,8]; } if ($name eq "") { # else, open file directly ($name, $shell) = (getpwnam_file($user, $passwdfile_plaintext))[0,8]; } } return 0 if ($shell eq ''); my $validshell = 0; if (open(ES, "/etc/shells")) { while(<ES>) { chomp; if( $shell eq $_ ) { $validshell = 1; last; } } close(ES); } return 0 if (!$validshell); return 1; } 1; #*************************** auth_pam_cobalt.pl ********************************
- Here is a complete example file that is from my system that reflects not on
ly the above changes but other changes I make from the default to support our current user preferences. - openwebmail.conf
- Note if you enable spell check like my above example configuration make sure you install the aspell library
- yum install aspell
- You should open /var/www/cgi-bin/openwebmail/etc/openwebmail.conf.help if you want to understand all the possible settings that can be made
以上是openwebmail.conf的配置说明,大家可以从网上找到很多关于openwebmail默认配置实例,这里就不再重申了!
8) 修改 db.conf
- nano -w /var/www/cgi-bin/openwebmail/etc/defaults/dbm.conf
- 修改为以下内容
dbm_ext .db
dbmopen_ext .db
dbmopen_haslock no
9) 重启 httpd 服务
- /etc/init.d/httpd restart
10) 执行以下命令
- /var/www/cgi-bin/openwebmail/openwebmail-tool.pl –init
11) 完成全部安装及配置过程
- http://server_ip_address/webmail
多域名時用戶跟隨域名:
openwebmail.conf 裡增加參數,寄件人地址會跟隨訪問OPENWEBMAIL使用的域名
domainoverride yes
——————-
增加用户邮箱 quota 功能
# vi /var/www/cgi-bin/openwebmail/etc/openwebmail.conf
在文件最后加入以下代码,即限制用户邮箱空间为60M
############################################
# Quota System (limit in KB and threshold in %)
1 MB = 1,024 KB
10 MB = 10,240 KB
100 MB = 102,400 KB
1 GB = 1,024 MB = 1,048,576 KB
# uncomment following lines if you wish to enable Quota System for 10 Mb
quota_module quota_du.pl <– 如果使用 quota_unixfs.pl 將會跟隨系統對每個用戶的限額
spool_limit 61440
quota_limit 61440
quota_threshold 0
delmail_ifquotahit yes
delfile_ifquotahit yes
# vi /var/www/cgi-bin/openwebmail/etc/defaults/auth_unix.conf
a. set passwdfile_encrypted to ‘/etc/shadow’
b. set passwdmkdb to ‘none’
不然用户使用openwebmail无法登录