Chinaunix首页 | 论坛 | 博客
  • 博客访问: 33261
  • 博文数量: 8
  • 博客积分: 0
  • 博客等级: 民兵
  • 技术积分: 10
  • 用 户 组: 普通用户
  • 注册时间: 2015-04-21 16:04
文章分类
文章存档

2016年(1)

2015年(7)

我的朋友

分类: 服务器与存储

2015-05-02 22:09:37

    本文主要说明了通过Sendmail+Dovecot+Openwebmail+procmail搭建邮件服务器的方法,并包括简单的备份策略和一个上传备份邮件的程序MailUpload。

    Sendmail实现协议,是邮件传输代理程序,作为发送邮件服务器

     Dovecot 是一个开源的 和 邮件服务器,支持 Linux/Unix 系统,作为接收邮件服务器  

    Openwebmail是一个perl语言编写的web邮件系统。

    Procmail是一个可以自定义的强大的邮件过滤工具。

  操作系统:more /etc/redhat-release  显示:Red Hat Enterprise Linux Server release 6.3 (Santiago)


1.安装配置sendmail

查询是否已经安装sendmail

    为避免与已经安装的sendmail产生冲突,在安装之前用rpm命令查询一下服务器是否已经安装了sendmail

    rpm –qa | grep sendmail

    不同的系统可能缺少的包不一样,我安装时包括以下包

    hesiod-3.1.0-19.el6.x86_64.rpm(hesiod是与名称服务(name service)相关的一个包,一般系统都默认已经安装了的)

    sendmail-8.14.4-8.el6.x86_64.rpm

    sendmail-cf-8.14.4-8.el6.noarch.rpm(sendmail-cf是sendmail的配置文件)

    由于sendmail的配置文件(sendmail.cf)是由模板文件(sendmail.mc)生成的,其生成要用到m4工具,所以需要安装m4这个工具。

配置/etc/mail/sendmail.mc

    sendmail.mc是模板文件,通过配置sendmail.mc然后用m4命令生成最后的配置文件,sendmail.mc需要修改的地方有两处:


    5253行:

    dnl TRUST_AUTH_MECH(`EXTERNAL DIGEST-MD5 CRAM-MD5 LOGIN PLAIN’)dnl

    dnl define(`confAUTH_MECHANISMS’, `EXTERNAL GSSAPI DIGEST-MD5 CRAM-MD5 LOGIN PLAIN')dnl

    改成

    TRUST_AUTH_MECH(`EXTERNAL DIGEST-MD5 CRAM-MD5 LOGIN PLAIN’)dnl

    define(`confAUTH_MECHANISMS’, `EXTERNAL GSSAPI DIGEST-MD5 CRAM-MD5 LOGIN PLAIN')dnl

    (去掉前面的dnl)

 

    116 行:

    DAEMON_OPTIONS(`Port=smtp,Addr=127.0.0.1, Name=MTA')dnl

    改成

    DAEMON_OPTIONS(`Port=smtp,Addr=0.0.0.0, Name=MTA')dnl

    ( 127.0.0.1改成0.0.0.0)

    其中dnl是配置文件中的m4宏,它表示丢弃直到下一个换行为止的字符(包括那个换行符)的意思。这里sendmail.mc文件修改的第一处如果不修改的话,后面发送邮件会发送失败;第二处如果不改动话系统只监听本机的127.0.0.1这个lo接口,修改之后将监听的接口开启到整个internet上,否则无法接收来自Internet的信件。


生成/etc/mail/sendmail.cf


    sendmail.mc是模板文件,sendmail.cf才是真正的配置文件,但是sendmail.cf配置文件比较复杂,一般不直接修改sendmail.cf文件而是通过sendmail.mc文件来生成sendmail.cf文件。sendmail.mc文件修改好之后,通过

m4 /etc/mail/sendmail.mc > /etc/mail/sendmail.cf命令来生成sendmail.cf文件


   sendmail.cf文件生成之后,直接启动sendmail服务的话,会报错,提示sendmail.cf文件第39行有错误。定位到39行之后,发现其实第39行就是一空行,直接删掉该行即可。



修改/etc/mail/local-host-names文件


   如果要收到形如xxx@abc.com、abc@mail.hzly.com的邮件的话,就要设置正确的主机名,主机名的设置在/etc/mail/local-host-names文件里添加:

   mail.hzly.com

   配置文件设置完毕后,即可启动sendmail服务了,用service sendmail start命令来启动

2.安装配置dovecot

    查询是否安装用rpm -qa | grep dovecot命令来检查,如果安装了的话则会显示已经安装的版本。

修改/etc/dovecot/conf.d/10-mail.conf

   修改邮箱位置,如果不修改的话,后面在发邮件的时候会提示跟mail_location相关的错误,修改操作如下:

25行:

#   mail_location = mbox:~/mail:INBOX=/var/mail/%u

修改成 

mail_location = mbox:~/mail:INBOX=/var/mail/%u

(去掉前面的#)

修改/etc/dovecot/conf.d/10-auth.conf 

   修改是否允许简单信息验证,如果不修改的话,后面发邮件会提示验证错误而不能通过验证,操作如下:

9行:

#disable_plaintext_auth = yes

修改成

disable_plaintext_auth = no

(去掉前面的#号,将yes改成no

修改/etc/dovecot/conf.d/10-ssl.conf

   修改是否使用ssl验证,如果不修改的话,同样在发送邮件的时候会提示不能通过验证,操作如下:

6行:

#ssl = yes

修改成

ssl = no

(去掉前面的#yes改成no

添加用户

   用useradd 用户名(如useradd userone)添加用户,用passwd 用户名(如 passwd userone)来修改密码,这样就添加了一个叫userone的用户。

创建/home/userone/mail/.imap/INBOX目录

    添加用户之后,需要在用户目录下建立INBOX文件夹,否则后面在收信的时候会报错。切换到userone用户下,然后用mkdir /home/userone/mail/.imap/INBOX -p命令创建文件夹。

修改/etc/skel/.bash_profile

    为了方便避免每新建一个用户就要建一个INBOX文件夹,可以在/etc/skel/.bash_profile文件中添加脚本来自动建立INBOX文件夹,如下所示:

在末尾添加:


if [ ! -d ~/mail/.imap/INBOX ];then
     mkdir -p ~/mail/.imap/INBOX
fi


启动dovecot

    配置文件修改完毕后,就可以启动dovecot服务了。用service dovecot start命令启动

3.foxmail客户端连接

    sendmaildovecot都安装完毕,服务都启动好了之后,这时一个基本的邮件服务器搭建完成,可以用foxmail客户端来进行连接。 

4.安装配置openwebmail

    openwebmailrpm包可以到上下载,同样,openwebmail安装是也有依赖关系,它是依赖如下两个包:perl-Text-Iconv-1.7-6.el6.x86_64.rpmperl-suidperl-5.10.1-119.el6_1.1.x86_64.rpm,因此要先安装这两个包后才能安装openwebmail,当然运行openwebmail还需要perl环境,一般系统都默认安装了perl环境,如果没有安装就要先装perl环境了。

修改dbm.conf配置文件

    在初始化之前要修改/var/www/cgi-bin/openwebmail/etc/defaults/dbm.conf这个配置文件,如果不修改该文件的话,在后面运行openwebmail-tool.pl --init初始化的时候会报错,修改如下:

30行:

dbm_ext                 .db

修改成

dbm_ext             .pag

初始化

    安装好了之后,修改dbm.conf配置文件之后,就开始初始化,输入/var/www/cgi-bin/openwebmail/openwebmail-tool.pl --init命令进行初始化操作

修改openwebmail.conf配置文件

    初始化之后,还需要修改/var/www/cgi-bin/openwebmail/etc/openwebmail.conf文件,主要是修改openwebmail的语言以及邮件使用的域名修改如下:

62行:

修改为zh_CN.GB2312

85行:

修改为Cool3D.Chinese.Simplified

12行:

修改为邮件使用的域

修改openwebmail.conf

    修改/var/www/cgi-bin/openwebmail/etc/defaults/openwebmail.conf

26行:

smtpserver要改为相应的主机名或ip 

启动http服务

    安装好openwebmail之后,就可以启动http服务来访问了。需要注意的是,openwebmail是依赖于http服务的,所以服务器必须要安装http服务才行。如果httpd装好了,只需要用service httpd start命令启动即可。

修改系统的SELinux设置

    在访问openwebmail之前,需要disable系统的SELinux设置。

访问openwebmail

    打开浏览器,在浏览器中输入:

    即可访问openwebmail了。


5.安装配置procmail

   首先确定系统已安装procmail。

创建相关的目录

mkdir /etc/procmail

touch /var/log/procmail.log

mkdir /var/mail/backup

创建/etc/procmailrc

    内容如下:


MAILDIR=/var/mail
VERBOSE=off
PATH=/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin
LOGFILE=/var/log/procmail.log
INCLUDERC=/etc/procmail/rc.localcopy 


创建/etc/procmail/rc.localcopy

    rc.localcopy内容如下   

:0c
/var/mail/backup/


收发的邮件就会备份到/var/mail/backup/目录下面,里面还有子目录,具体可以看一下

MailUpload是一个可以将备份的邮件上传到指定服务器的小程序,服务器端通过一个jsp解析出主题和内容,然后插入数据库以供查询。下面贴出MailUpload的代码,主要是监测指定目录的文件变化情况,然后通过curl提交数据。


#include 
#include 
#include 
#include 
#include 
#include 
#include 

#define ERROR(text) error(1, errno, "%s", text)

struct EventMask {
	int        flag;
	const char *name;

};

int freadsome(void *dest, size_t remain, FILE *file)
{
	char *offset = (char*)dest;
	while (remain) {
		int n = fread(offset, 1, remain, file);
		if (n==0) {
			return -1;
		}

		remain -= n;
		offset += n;
	}
	return 0;
}

int main(int argc, char *argv[])
{
	const char *target;
	if (argc == 1) {
		target = ".";
	} else {
		target = argv[1];
	}

	struct EventMask event_masks[] = {
           {IN_ACCESS        , "IN_ACCESS"}        ,  
           {IN_ATTRIB        , "IN_ATTRIB"}        ,  
           {IN_CLOSE_WRITE   , "IN_CLOSE_WRITE"}   ,  
           {IN_CLOSE_NOWRITE , "IN_CLOSE_NOWRITE"} ,  
           {IN_CREATE        , "IN_CREATE"}        ,  
           {IN_DELETE        , "IN_DELETE"}        ,  
           {IN_DELETE_SELF   , "IN_DELETE_SELF"}   ,  
           {IN_MODIFY        , "IN_MODIFY"}        ,  
           {IN_MOVE_SELF     , "IN_MOVE_SELF"}     ,  
           {IN_MOVED_FROM    , "IN_MOVED_FROM"}    ,  
           {IN_MOVED_TO      , "IN_MOVED_TO"}      ,  
           {IN_OPEN          , "IN_OPEN"}          ,  

           {IN_DONT_FOLLOW   , "IN_DONT_FOLLOW"}   ,  
           //{IN_EXCL_UNLINK   , "IN_EXCL_UNLINK"}   ,  
           {IN_MASK_ADD      , "IN_MASK_ADD"}      ,  
           {IN_ONESHOT       , "IN_ONESHOT"}       ,  
           {IN_ONLYDIR       , "IN_ONLYDIR"}       ,  

           {IN_IGNORED       , "IN_IGNORED"}       ,  
           {IN_ISDIR         , "IN_ISDIR"}         ,  
           {IN_Q_OVERFLOW    , "IN_Q_OVERFLOW"}    ,  
           {IN_UNMOUNT       , "IN_UNMOUNT"}       ,  
	};

	int monitor = inotify_init();
	if ( -1 == monitor ) {
		ERROR("monitor");
	}

	int watcher = inotify_add_watch(monitor, target, IN_ALL_EVENTS);
	if ( -1 == watcher  ) {
		ERROR("inotify_add_watch");
	}

	FILE *monitor_file = fdopen(monitor, "r");
	char last_name[1024];
	char name[1024];

	/* event:inotify_event -> name:char[event.len] */
	//while (true) {
	while (1) {
		struct inotify_event event;
		if ( -1 == freadsome(&event, sizeof(event), monitor_file) ) {
			ERROR("freadsome");
		}
		if (event.len) {
			freadsome(name, event.len, monitor_file);
		} else {
			sprintf(name, "FD: %d\n", event.wd);
		}

		if (strcmp(name, last_name) != 0) {
			puts(name);
                        //int ret = system("ls -l");
			strcpy(last_name, name);
		}

		/* 显示event的mask的含义 */
                int i;
		for (i=0; i




阅读(3686) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~