1,搭建邮件系统之前,先介绍邮件系统的原理。邮件系统大致由以后五个部分组成
(1)MTA:mail transfer agent 邮件传输代理:在服务端与客户之前传输邮件。常用的软件postfix,sendmail
(2)MDA:mail delivery agent 邮件投递代理:将邮件投递到用户的邮箱里。常用的软件有procmail,maildrop
(3)MRA:mail retrieval agent邮件取回代理:从用户的邮箱里收取邮件。常用的软件dovecot。
(4)MUA: mail user agent 用户邮件代理,现在用得不多,已经出现webmail, 其实就是之前用的outlook,thunderbird。
(5)MSA:mail submission agent邮件提交代理:检查邮件安全性与垃圾等,处理额外的工作。
2,smtp会话建立的步骤:先进行tcp的三次会话,然后开始下面的步骤
(1)客户端:先发送helo询问对方在不在线
(2)服务端:如果在线则回应对方,回应信息为250的正常响信息
(3)客户端:告诉对方邮件的来源者是谁
(4)服务端:收到之后如果能发送,就回应对方正常响应信息,也是250的。否则就返回错误信息
(5)客户端:发送邮件接收者的地址
(6)服务端:回应对方可以发送
(7)客户端:通过data命令,开始写邮件,写完之后在单独的一行输入一个点结束
(8)服务端:回应对方,你的邮件已经接受,并发送。
(9)发送方:发送结束命令 quit,结束这个会话。
邮件改送完之后就开始tcp的四次会话断开。
3,上面简单了说明了邮件系统的组成与发送。下面编译postfix,并提供webmail的功能,那么此时就需要DNS,MYSQL,http,php因此先安装好这四个软件。此次实验基于redhat 5.8。
(1)安装与配置DNS,用rpm安装的bind97,如果原系统有bind软件请先卸载。详细过程请参考前面DNS的博文。下面是我正向区域与反向区域里的记录,如果测试能够正常解析。
(2),安装与配置LAMP,请参考lamp博文,安装完之后启动服务
(4)下面开始编译postfix,postfix只能限于收发邮件,运行postfix软件必须是postfix 的普通用户,且postfix的uid必须大于1000以上,postdrop这个组只限于投递邮件。gid也是必须大于1000以上。因此先创建两个用户
useradd -u 2525 postfix -s /sbin/nologin -M
useradd -u 2525 postdrop -s /sbin/nologin -M
(5)解压postfix的源码之后,开始编译,postfix不用./configure,直接用make makefiles 'CCARGS=-DHAS_MYSQL -I/usr/include/mysql -DUSE_SASL_AUTH -DUSE_CYRUS_SASL -I/usr/include/sasl -DUSE_TLS ' 'AUXLIBS=-L/usr/local/mysql/lib -lmysqlclient -lz -lm -L/usr/lib/sasl2 -lsasl2 -lssl -lcrypto'(CCARGS表示编译器gcc参数是有些,-DHAS_MYSQL表示启用postfix支持MYSQL的功能,AUX表示辅助的,LIBS表示库文件,AUXLIBS表示辅助的库文件,指定MYSQL库文件的路径,并查找mysqlclient的客户端,-lz启用压缩工具,-lm启用编码工具,sasl2的库文件,-lsasl2表示启用这个库,-lssl表示启用openssl加密,-lcrypto表示启用crypto库。mysql是自己用源码安装,因此并不是在/usr/lib/mysql下)
(6)make,make install时会提示以下信息
install_root:[/]:install_root表示根的路径(中括内表示默认路径),根可以在别的路径下,但是要让postfix工作在chroot的模型下,这里直接使用真正的根。直接按回车键
tempdir:[/root/postfix-2.9.3]临时文件目录,使用默认路径就ok。其中有一项html_directory:[no]要不要使用postfix的网页格式的帮助文档,如果需要可以在指定到httd的默认主页目录下。如果不想使用则直接按回车,下面都使用默认路径。直接按回车。
(7)make install没有提示错误则此时postfix安装已经成功。需要到别的主机上复制postfix的脚本过来,没有特别需要修改的,因此只要将脚本加到chkconfig中,chkconfig --add postfix,chmod +x postfix,service postfix start,如果出错则查看日志/var/log/maillog。
(8)修改postfix的配置文件/etc/postfix/main.cf中启用下面五项:
myhostname = mail.bingo.com(指定运行postfix邮件系统的主机的主机名,在DNS中已经定义了mail.bingo.com,myhostname)
mydomain = bingo.com(指定postfix自己所负责的域)
myorigin = $mydoamin (指明发件人所在的域名,即做发件地址伪装)
mydestination = $myhostname,localhost....(指定postfix接收邮件时收件人的域名,允许postfix接收到哪些域名的邮件)
inet_interfaces = $myhostname,local(指定postfix系统监听的网络接口) mynetworks = 172.16.0.0/24,127.0.0.1/8(指定自己所在的网络的网络地址,postfix系统根据其值来区别用户是远程的还是本地的,如果是本地网络用户则允许其访问)
(9)重启postfix服务,测试能否收发邮件,先添加两个用户redhat与gentoo,
(9)上面表示在命令行下测试发邮件,250,354,221,表示服务器商返回的状态信息,这时可以su - gentoo下,执行mail命令能否收到邮件。如果能,则postfix已经能够正常收发邮件。
4,为postfix服务开启用户别名支持:
(1)在配置文件开启基于hash的别名文件支持
在main.cf中,启用alias_maps = hash:/etc/aliases(经过hash编码的格式)
(2)编辑/etc/aliases,在最后一行添加一行,跟上面格式一样,如下面所示
redhat: gentoo(表示发送给redhat的邮件,将会发给gentoo)
(3)将/etc/aliases转换为hash格式:postalias /etc/aliases
(4)重启服务,并测试。
5、实现postfix基于客户端的访问控制
基于客户端的访问控制概览,postfix内置了多种反垃圾邮件的机制,其中就包括“客户端”发送邮件限制。客户端判别机制可以设定一系列客户信息的判别条件:
(1)smtpd_client_restrictions(client表示对客户端限制)
(2)smtpd_data_restrictions (data表示对发数据的限制)
(3)smtpd_helo_restrictions (对helo信息发送的限制)
(4)smtpd_recipient_restrictions =permit mynetworks,reject_unauth_destination(对收件人的限制规则自左向右匹配)
(5)smtpd_sender_restrictions(对sender的限制 )
前面的每一项参数分别用于检查SMTP会话过程中的特定阶段,即客户端提供相应信息的阶段,如当客户端发起连接请求时,postfix就可以根据配置文件中定义的smtpd_client_restrictions参数来判别此客户端IP的访问权限。相应地,smtpd_helo_restrictions则用于根据用户的helo信息判别客户端的访问能力等等。如果DATA命令之前的所有内容都被接受,客户端接着就可以开始传送邮件内容了。邮件内容通常由两部分组成,前半部分是标题(header),其可以由header_check过滤,后半部分是邮件正文(body),其可以由check_body过滤。这两项实现的是邮件“内容检查”。
postfix的默认配置如下:查看postfix的默认配置postconf -d
我只截了部分图 postconf -d |grep "^smtpd",而我们需要用到下面的基本上都没定义
(1)smtpd_client_restrictions =
(2)smtpd_data_restrictions =
(3)smtpd_helo_restrictions =
(4)smtpd_recipient_restrictions =permit_mynetworks,reject_unauth_destination
这限制了只有mynetworks参数中定义的本地网络中的客户端才能通过postfix转发邮件,其它客户端则不被允许,从而关闭了开放式中继(open relay)的功能。
(5)smtpd_sender_restrictions =
Postfix有多个内置的限制条件,如上面的permit_mynetworks和reject_unauth_destination,但管理员也可以使用访问表(access map)来自定义限制条件。自定义访问表的条件通常使用check_client_access, check_helo_access, check_sender_access, check_recipient_access进行,它们后面通常跟上type:mapname格式的访问表类型和名称。其中,check_sender_access和check_recipient_access用来检查客户端提供的邮件地址,因此,其访问表中可以使用完整的邮件地址,如admin@bingo.com;也可以只使用域名,如bingo.com;还可以只有用户名的部分,如redhat@。
(6)限制172.16.150.10这台主机通过172.16.150.1的postfix发送邮件。先编辑 /etc/postfix/access文件,在最后一行添加 172.16.150.10 REJECT,然后将/etc/postfix转换成hash格式,postmap /etc/postfix/access。编辑main.cf,在最后一行添加下面参数:
smtpd_client_restrictions = check_client_access hash:/etc/postfix/access
重启postfix测试。
(7)禁止向163.com域发送邮件,文件使用hash的格式。先新建一个/etc/postfix/denydomain的文件(文件名可以任意取),在里面定义一行:
163.com REJECT
将此文件转换成hash格式,postmap /etc/postfix/denydomains,在main.cf中最后添加一行smtpd_recipient_restrictions = check_recipient_access hash:/etc/postfix/denydstdomains, permit_mynetworks, reject_unauth_destination(这三行是一行内容,并不独立的三行,最好写在同一行中,或者在写第二行时,需要先用空白字符,然后在接着,这样才会当作跟上一行为同一行。)最后重启服务并测试。
6,安装dovecot接收邮件
yum -y install dovecot
修改dovecot的配置文件,只修改其中一个protocols=pop3,目前只用pop3来测试
重启dovecot服务。service dovecot start。配置window 上的outlook或thunderbird进行收发邮件测试,测试的用户在linux需要已存在。
7,安装courier authentication library
(1)courier简介:courier-authlib是Courier组件中的认证库,它是courier组件中一个独立的子项目,用于为Courier的其它组件提供认证服务。其认证功能通常包括验正登录时的帐号和密码、获取一个帐号相关的家目录或邮件目录等信息、改变帐号的密码等。而其认证的实现方式也包括基于PAM通过/etc/passwd和/etc/shadow进行认证,基于GDBM或DB进行认证,基于LDAP/MySQL/PostgreSQL进行认证等。因此,courier-authlib也常用来与courier之外的其它邮件组件(如postfix)整合为其提供认证服务。
(2)先安装一些必要的库文件
yum -y install tcl tcl-devel libart_lgpl libart_lgpl-devel libtool-ltdl libtool-ltdl-devel expect
(3)下载courier-authlib-0.62.4.tar.bz
编译./configure --prefix=/usr/local/courier-authlib --sysconfdir=/etc --without-authpam --without-authshadow --without-authvchkpw --without-authpgsql --with-authmysql --with-mysql-libs=/usr/local/mysql/lib --with-mysql-includes=/usr/local/mysql/include --with-redhat --with-authmysqlrc=/etc/authmysqlrc --with-authdaemonrc=/etc/authdaemonrc --with-mailuser=postfix --with-mailgroup=postfix --with-ltdl-lib=/usr/lib --with-ltdl-include=/usr/include
成功后make,make install
(4)修改编译生成的chmod 755 /usr/local/courier-authlib/var/spool/authdaemon在/etc/authdaemonrc中已经定义好这个路径
cp /etc/authdaemonrc.dist /etc/authdaemonrc 提供的配置文件
cp /etc/authmysqlrc.dist /etc/authmysqlrc
(5)修改/etc/authdaemonrc 文件
authmodulelist="authmysql" 只保留authmysql,下面也一样
authmodulelistorig="authmysql"
daemons=10启用认证请求的个数,并发认证的个数与CPU有关,如果cpu没那么多,启用太多也是没有作用的。
下面还有DEBUG_LOGIN默认没启用,正常情况下,不需要启用,因此每发一封一邮件都会记录一个,只有需要调试错误的时候才开启。
(6)修改/etc/authmysqlrc
MYSQL_SERVER localhost
MYSQL_PORT 3306 (指定你的mysql监听的端口,这里使用默认的0)
MYSQL_USERNAME extmail (这时为后文要用的数据库的所有者的用户名)
MYSQL_PASSWORD extmail (密码,实际中要修改)
MYSQL_SOCKET /tmp/mysql.sock(如果源码安装则在/tmp/mysql.sock,在/etc/my.cnf中指定了)
MYSQL_DATABASE extmail
MYSQL_USER_TABLE mailbox
MYSQL_CRYPT_PWFIELD password
MYSQL_UID_FIELD 2525(是postfix的用户的uid)
MYSQL_GID_FIELD 2525
MYSQL_LOGIN_FIELD username
MYSQL_HOME_FIELD concat('/var/mailbox/',homedir)映射虚拟用户有家目录
MYSQL_NAME_FIELD name
MYSQL_MAILDIR_FIELD concat('/var/mailbox/',maildir) 邮箱目录
(7)提供courier-authlib的服务脚本,在解压完的目录中已提供了
cp courier-authlib.sysvinit /etc/rc.d/init.d/courier-authlib
chmod 755 /etc/init.d/courier-authlib
chkconfig --add courier-authlib
chkconfig courier-authlib on
添加库文件echo "/usr/local/courier-authlib/lib/courier-authlib" >> /etc/ld.so.conf.d/courier-authlib.conf
ldconfig -v 让系统更新库文件
service courier-authlib start
8,配置postfix和courier-authlib
(1)新建虚拟用户邮箱所在的目录,并将其权限赋予postfix用户:
mkdir –pv /var/mailbox
chown –R postfix /var/mailbox
(2)接下来重新配置SMTP 认证,编辑 /usr/lib/sasl2/smtpd.conf(如果没有则新建) ,确保其为以下内容:
pwcheck_method: authdaemond
log_level: 3 日志级别
mech_list:PLAIN LOGIN
authdaemond_path:/usr/local/courier-authlib/var/spool/authdaemon/socket
9,让postfix支持虚拟域和虚拟用户
(1)编辑/etc/postfix/main.cf,最后一行添加如下内容:后面括号里的汉字要删除
########################Virtual Mailbox Settings########################
virtual_mailbox_base = /var/mailbox
virtual_mailbox_maps = mysql:/etc/postfix/mysql_virtual_mailbox_maps.cf
virtual_mailbox_domains = mysql:/etc/postfix/mysql_virtual_domains_maps.cf
virtual_alias_domains =
virtual_alias_maps = mysql:/etc/postfix/mysql_virtual_alias_maps.cf
virtual_uid_maps = static:2525
virtual_gid_maps = static:2525
virtual_transport = virtual(MDA邮件投递用户,明确说明是虚拟的)
maildrop_destination_recipient_limit = 1
maildrop_destination_concurrency_limit = 1
##########################QUOTA Settings########################
message_size_limit = 14336000(单个邮件的大小)
virtual_mailbox_limit = 20971520(用户邮箱容量大小)
virtual_create_maildirsize = yes
virtual_mailbox_extended = yes
virtual_mailbox_limit_maps = mysql:/etc/postfix/mysql_virtual_mailbox_limit_maps.cf
virtual_mailbox_limit_override = yes(允许覆盖上面的限制,因为在exmail中也可以设置,以这里了为准)
virtual_maildir_limit_message = Sorry, the user's maildir has overdrawn his diskspace quota, please Tidy your mailbox and try again later.
virtual_overquota_bounce = yes
(2)下载extman-1.1.tar.gz,使用extman源码目录下docs目录中的extmail.sql和init.sql建立数据库:
cd extman-1.1/docs
mysql 5.5以后不在使用TYPE=MyISAM存储引擎,需要将exmail.sql和init.sql的TYPE修改成ENGINE
sed -i 's@TYPE=MyISAM@ENGINE=MyISAM’ exmail.sql与init.sql或者直接用vim修改
mysql -u root -p < extmail.sql(执行行extmail.sql脚本,创建extmail数据库与表)或者连接数据库之后执行source exmail.sql,因为在当前路径登录到mysql的
mysql -u root -p < init.sql
cp mysql* /etc/postfix/
(3)授予用户extmail访问extmail数据库的权限
mysql> GRANT all privileges on extmail.* TO extmail@localhost IDENTIFIED BY 'extmail';
mysql> GRANT all privileges on extmail.* TO extmail@127.0.0.1 IDENTIFIED BY 'extmail';
说明:启用虚拟域以后,需要取消中心域,即注释掉, mydestination(这个一定要去掉), mydomain, myorigin几个指令;当然,你也可以把mydestionation的值改为你自己需要的。