Linux运维第三阶段(十)postfix

postfix

 

mail-server:

SMTP(simple mail transfer protocol):功能简陋,无法实现用户认证、邮件存储、检索邮件等,所以功能简单,仅负责将邮件从发送方传输到目的方,能实现传输路由功能,TCP/25port

SMTPS(secure安全版)

ESMTP(entended SMTP):仅实现检测用户身份,无法实现认证,功能增强版

POP3(post office protocol):邮局协议version3TCP/110port

IMAP4(internet mail access protocol):互联网邮件访问协议,TCP/143port,功能与pop3近似,比pop3要强大,但消耗资源多,所以众多站点用pop3

UUCP(unix to unix protocol)UNIX主机复制文件的协议,功能简陋

SASL(simple authentication secure layer):简单认证安全层,提供安全认证框架,服务名saslauthd,现使用V2,软件cyrus-saslcourier-authlib

注:smtppop3imap4均明文plaintext方式工作(可借助ssl加密传输,如smtps,pop3s,imaps仅能保证传输过程加密,例:smtp-->smtps并不能真正保证邮件的安全性,起码要保证两段,其中本地MUA-->smtpd-->smtp,本地到远端smtp-->smtpd(dst),远端smtpd-->MDA-->邮箱,若远端的邮箱可被其它人访问,也是不安全的)

S/MIME(secure/multi internet mail extended)USER<-->USER,每个用户都有一个独立的证书(用户证书,公信的CA颁发)

(写好一封mail,用单向加密算法生成指纹finger print(hash),使用自己的私钥加密指纹,用一次性会话密钥加密前面数据,再用对方的公钥加密总的数据,传至对方)

opensslGPG(软件GNU privacyguard)PGP(privacy guard protocol)的一种实现

 

MUA(mail user agent)muttlinux文本界面)、mail命令(linux)outlook(windows)foxmailthunderbirdevolution

MTA(mail transfer agent)SMTP服务器、sendmail(主流地位,互联网邮件服务的鼻祖,UUCP、单体结构、SUID、配置文件语法m4编写)、qmail(比sendmail效率快近20倍)、postfix(目前流行,模块化设计、安全、与sendmail兼容、不使用SUID、效率比sendmail快至少4倍)、exim(英国剑桥)、exchangewin下使用,异步消息协作平台)

MDA(mail delivery agent):邮件投递代理,软件:procmailmaildrop(独立的服务,抽取邮件文本信息的特征码实现垃圾邮件过滤)

MRA(mail retrieval agent):邮件检索(取回)代理(pop3imap4协议),软件:cyrus-imapdovecot(鸽子笼)

Webmailopenwebmail(perl)squinelmail(php)Extmail,Extman(extmanager,centosEMOS)

 

注:每个主机都有client(smtp发邮件)server(smtpd接收邮件);用MUA编辑好邮件通过SMTP协议发送至smtpd,若收件方是本地域,smtpd则直接投递至邮件中转站(邮箱)中,若是远程主机则smtpd转至smtpsmtp向远端服务器的smtpd传送;一个服务器若有多个MX记录,找优先级高的;借助于认证工具实现要提供帐号密码才可发送邮件(协议使用SASL

 

open-relay:开放式中继,是本地的接收,不是本地的都转发,源到目的不是中继,open-relay这种方式保证了邮件就算被误传了最终也能放到真正的目的地,但垃圾邮件就此开始了,而且这有被滥用的风险(例如某用户编辑了1000封邮件,放至你的服务器发送,则其它服务器都认为你的邮件服务器是垃圾制造者),一般关闭开放式中继,仅允许本地用户中继

(举例tom@magedu.com发邮件至clair@b.net开启转发功能,则会将邮件正确发送至b.netb.net看到的是a.org发来的邮件(与他建立连接的是a.org),,仅主机是a.org,发件人和主机间没有必然联系)

 

LDAP(lightweight directory access protocol):轻量级目录访问协议,存放帐号密码,把数据结构进行组织,速度无与伦比的快,缺点(读快写慢,还不成熟),适合场景(大规模用户账号系统,资源系统,服务信息检索系统,一次写入多次读取),放帐号密码至LDAP比放mysql快至少10倍,win-serverLDAP支持很好,redhat中介绍LDAP用了一本书讲解

就算用户量不大也应该采取mysql存放账号密码,与系统中的用户账号密码区别开来(/etc/{passwd,shadow}),避免***OSmysql中存放的账号密码仅用于访问某服务的数字标识(虚拟用户)

pop3自身有mysql访问驱动、LDAP访问驱动,来完成账号密码验证;而smtp是借助于SASLSASL本身是在/etc/passwd中找),给SASL附加一个工具让其可以到mysql中检索数据

 

 

www.postfix.org

注:redhat提供postfixrpm包安装,但不支持sasl认证(虚拟用户),redhat5默认安装sendmail(系统中任务计划管理需要邮件提示用户执行情况),redhat6默认安装postfix

 

准备环境:

本例:centos5.8-x86_64mysql5.5.45(二进制包安装,参照文档<理解LAMP>)、postfix2.9

安装软件组:Development LibrariesDevelopment ToolsLegacy Software DevelopmentX SoftwareDevelopment

安装软件包:httpd, tcl, tcl-devel, libart_lgpl, libart_lgpl-devel, libtool-ltdl,libtool-ltdl-devel, expect

注:redhat中编译某一软件,若编译的这个软件依赖于某包,则依赖的包的devel包一定要装上(提供开发库和头文件),例如:编译postfix时依赖sasl包,那么sasl-devel包就一定要装上;编译httpd时依赖openssl,则openssl-devel包一定要装上。

注:编辑修改某一配置文件时,最好先备份一份再修改,修改时要复制一行再改动。

 

#service sendmail  stop

#chkconfig sendmail  off

#rpm -e  --nodeps  sendmail

#yum list  all  | grep  cyrus-sasl(确保devel包和plain包已安装)

确保mysql已安装

#service saslauthd  start

#chkconfig saslauthd  on

#tar xf  postfix-2.9-20110116.tar.gz

#cd  postfix-2.9-20110116

#less INSTALL

#groupadd -g  2525  postfix

#groupadd -g  2526  postdrop

#useradd -u  2525  -g postfix  -s  /sbin/nologin postfix

#useradd -u  2526  -g postdrop  -s  /sbin/nologin postdrop

#make makefiles 'CCARGS=-DHAS_MYSQL -I/usr/local/mysql/include -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指定头文件,AUXLIBS指定库文件)

#make

#make install(所有要指定的目录按默认,/usr/sbin下是命令脚本,/usr/libexec/postfix服务器进程,/var/spool/postfix队列进程)

#newaliases(生成别名二进制文件)

postfix提供sysv脚本(见此文档尾)

#service postfix  start

#netstat -tnlp0.0.0.0:25所有地址,且是master进程)

#tail /var/log/maillog

 

#vim /etc/postfix/master.cf(主进程配置文件,模块化设计,有主进程、辅助进程)

#vim /etc/postfix/main.cf(功能配置文件;格式:参数 = 值)

注:每行参数要顶格写,若前面有空格则表示上一行的延续

myhostname = mail.magedu.com(邮件服务器自己的主机名,#hostname的结果)

mydomain = magedu.com

myorigin = magedu.com(邮件地址伪装,会自动修改为root@magedu.com;发邮件时只写用户名不写@后内容,则会自动补上此行的值)

mydestination = $myhostname, localhost.$mydomain,localhost, $mydomain(允许使用$PARAMETER;发邮件时@后的内容是此处设定的值时才接收邮件,否则就要中继)

mynetworks = 192.168.101.0/24, 127.0.0.0/8(设置允许给哪些主机中继,一般设为本地网络;若只写127.0.0.0/8,则发往本网络其它主机邮件的地址会被当作外网地址)

 

#man postconf(命令行配置工具)

#postconf -d(显示默认配置信息Print default parameter settings instead of actual settings

#postconf -n(显示更改的配置Print  parameter  settings that are not left at their built-in default value, because they areexplicitly specified in main.cf

#postconf -m(显示支持的查找表类型List the names of all supported lookup table types

#postconf -A(客户端支持的SASL插件类型List the available SASL client plug-in types

#postconf -a(服务端支持的SASL插件类型List the available SASL server plug-in types.

#postconf -e  PARAMETER=VALUE(更改某参数的配置信息并保存至main.cf中)

 

smtp状态码:1XX纯信息;2XX正确类信息;3XX上一步操作尚未完成,需要继续补充;4XX暂时性错误;5XX永久性错误

 

smtp协议命令(原语):

helo(以smtp协议向对方发送信息)

ehlo(以esmtp协议)

mail from:

rcpt to:(至关重要,根据此处信息,服务器来判断是接收还是中继)

data(回车后,输入主题Subject和正文,另起一行以点结束表示发送)

 

举例:用mail命令给本地用户发送邮件

#telnet localhost  25

ehlo

mail from:obama@whitehouse.com

rcpt to:hadoop(不写@会自动补上main.cfmyorigin设置的值,表示本地域)

data

Subject:How are you?

postfix test!!!

.

quit

#tail /var/log/maillog(注意statussent状态)

注:在互联网上,邮件服务器依赖DNS,且必须要有PTR记录,否则互联网上的其它服务器会将其视为垃圾,拒收该服务器邮件

 

aliaspostfix依赖邮件别名,来判别用户是否在)

#newaliasesrebuild the database for the mail aliases file,此命令可将/etc/aliases-->hash-->/etc/aliases.db散列成.db格式的hash数据库(键值对数据库),这样检索效率会快得多,最适合查找单个匹配条目,mysql中也有hash索引相关概念)

#vim /etc/aliases(可编辑别名文件,格式如:redhat:  hadoop

redhat   hadoop(注意冒号)

  postmaster@magedu.com的邮件都将转至postmaster@magedu.com

#postaliase /etc/aliases(将此文件转为hash格式,或用命令#newaliases

注:postfix默认把本机的IP地址所在网段视为本地网络,为之中继邮件

测试:给redhat用户发邮件,再查看redhathadoop的邮件情况

 

dovecotMRA

rpm包方式安装dovecot(依赖于mysql,支持四种协议pop3,pops,imap4,imaps;当用户登录,dovecot/etc/passwd检索,不依赖于SASLdovecot自身就能实现用户认证,虽然它能调用SASL

邮件格式(dovecot两种格式都支持)

mbox(一个文件存储所有邮件,redhat默认,dovecot默认)

maildir(一个文件存储一封邮件,所有邮件存储在一目录中)

#yum -y  install  dovecot

#rpm -ql  dovecot

#vim /etc/dovecot.conf

#service dovecot  start

#netstat -tnlp110143,提供两种不同方式)

 

举例:

winoutlook发邮件

#telnet mail.magedu.com  110(在服务端收邮件)

USER obama(用户名在/etc/passwd中要有记录)

PASS obama(密码)

LIST   (查看是否有邮件)

RETR #(输入序号查看邮件)

#tail /var/log/maillog

 

以上不能实现验证用户身份,仅基于IP就能发邮件

 

 

 

客户端的访问控制:

 

#postconf -m(可列出支持的查询表类型,有hash,mysql等)

#vim /etc/postfix/accessPostfix SMTP server access table访问控制文件,格式为:PATTERN  ACTION

   REJECT(拒绝)

microsoft.com   OK(允许)

192.168.1.225  REJECTPATTERN可以是邮件格式,域名,IPNETWORK/NETMASK等)

#postmap /etc/postfix/access(将文件转换为hash格式的数据库,/etc/postfix/access.db

#ls /etc/postfix/access*(确保accessaccess.db文件都在)

 

#vim /etc/postfix/main.cf(每个参数后可跟访问控制文件,也可跟内置的限定条件)

smtpd_client_restrictions =check_client_access hash:/etc/postfix/accessconnection阶段控制,此处hash:后的文件不写.dbhash就表示access.db的文件)

smtpd_helo_restrictions = check_helo_accessmysql:/etc/postfix/mysql_userhelo阶段控制,限定谁可以发送helo指令)

smtpd_sender_restrictions =check_sender_access hash:/PATH/TO/FILEmail from:阶段)

smtpd_recipient_restrictions =permit_mynetworks, reject_unauth_destination(允许本地转发,从而关闭openrelay功能,rcpt to:此阶段是必须定义的项,所有的信息都在这段才能真正显示出来能否发送,permit_mynetworks为内置的限定条件)

smtpd_data_restriction = data阶段)

 

举例:禁止192.168.101.106在服务器上发邮件

#vim /etc/postfix/access

192.168.101.106  REJECT

#postmap /etc/postfix/access

#vim /etc/postfix/main.cf

smtpd_client_restrictions =check_client_access hash:/etc/postfix/access

#service postfix  restart

#postconf -n

winIP106的主机上给root@magedu.com发邮件,会有提示:The message could not be sent because one of the recipients wasrejected by the server. The rejected e-mail address was 'root@magedu.com'.Subject 'test3', Account: '192.168.101.154', Server: '192.168.101.154',Protocol: SMTP, Server Response: '554 5.7.1 <unknown[192.168.101.106]>:Client host rejected: Access denied', Port: 25, Secure(SSL): No, Server Error:554, Error Number: 0x800CCC79

 

 

举例:禁止@whitehouse.com这个域的所有用户发邮件

#vim /etc/postfix/access

whitehouse.com  REJECT(注意无@

#postmap !$

#vim /etc/postfix/main.cf

smtpd_sender_restrictions =check_sender_access hash:/etc/postfix/access

#!service

#telnet mail.magedu.com  25

mail from:obama@whitehouse.com

rcpt to:root@magedu.com

554 5.7.1 <obama@whitehouse.com>:Sender address rejected: Access denied

 

举例:禁止openstack@在本地服务器所有域上接收邮件(本地域的所有主机都不能给hadoop发邮件)

#vim /etc/postfix/recipient

openstack@ REJECT

#postmap /etc/postfix/recipient

#vim /etc/postfix/main.cf

smtpd_recipient_restrictions = check_recipient_accesshash:/etc/postfix/recipient permit_mynetworks, reject_unauth_destination(注意次序,默认的后两个都要有)

#service postfix  restart

mail from:root@magedu.com

250 2.1.0 Ok

rcpt to:hadoop  

554 5.7.1 <hadoop>: Recipient address rejected:Access denied

 

 

postfix开启基于cyrus-sasl的认证功能

#vim /etc/sysconfig/saslauthd

MECH=shadowMechanism to usewhen checking passwords更改此项,默认为pam

#saslauthd -v(显示支持哪种认证机制authentication mechanisms: getpwent kerberos5 pam rimap shadow ldap

#testsaslauthd  -h

#testsaslauthd  -u hadoop  -p  hadoop(显示0: OK"Success."

#postconf -a(确保有cyrus

#vim /etc/postfix/main.cf(添加如下内容)

############################CYRUS-SASL############################

broken_sasl_auth_clients = yes

smtpd_recipient_restrictions=permit_mynetworks,permit_sasl_authenticated,reject_invalid_hostname,reject_non_fqdn_hostname,reject_unknown_sender_domain,reject_non_fqdn_sender,reject_non_fqdn_recipient,reject_unknown_recipient_domain,reject_unauth_pipelining,reject_unauth_destination

smtpd_sasl_auth_enable = yes

smtpd_sasl_local_domain = $myhostname

smtpd_sasl_security_options = noanonymous

smtpd_sasl_application_name = smtpd

smtpd_banner = Welcome to our $myhostnameESMTP,Warning: Version not Available!

#vim /usr/lib/sasl2/smtpd.conf

pwcheck_method: saslauthd(说明sasl基于哪种方式认证)

mech_list: PLAIN  LOGIN(两种认证机制,outlook基于LOGIN

#service postfix  restart

#service saslauthd  restart

#telnet mail.magedu.com  25(测试时将主配置文件main.cf中改mynetworks= 127.0.0.0/8

ehlo mail.magedu.com(确保有以下两行)

250-AUTH PLAIN CRAM-MD5 DIGEST-MD5 LOGIN

250-AUTH=PLAIN CRAM-MD5 DIGEST-MD5 LOGIN

mail from:root@magedu.com

rcpt to:hadoop@aol.comhadoop是本地用户但域不是本地域,提示554 5.7.1 <hadoop@aol.com>: Relay access denied

rcpt to:hello@aol.com(用户和域都不在本地:提示554 5.7.1 <hello@aol.com>: Relay access denied

rcpt to:bbb@magedu.com(用户不在本地,则提示:550 5.1.1 <bbb@magedu.com>: Recipient address rejected: Userunknown in local recipient table

 

 

mutt的使用(The Mutt MailUser Agent):

#mutt -f  PROTOCOL://USERNAME@SERVER

#mutt -f  pop://hadoop@mail.magedu.com

#mutt -f  pop://hadoop@192.168.101.154

i键返回,r回复,q退出

 

httpd若要用虚拟主机则要注释中心主机;一台邮件服务器也可以为多个域收发邮件(中心域参数:mydestination,mydomain,myorigin),若要使用虚拟域至少要注释掉mydomain

mydomain = a.org,b.net,c.com……(域要是很多,则可使用查找表,将域名放到一文本文件中,用命令#postmap  FILE,将之转换为hash数据库.db格式,缺陷(每次增删时都要使用命令执行);但通过其它程序接口操作更麻烦,建议使用mysql,将账号密码放至库中的表,开发一php网页在页面上对mysql中的账号密码进行操作(在线注册),提交至mysql(或LDAP

虚拟域<--->用户别名(建立关联关系)

用户账号(虚拟账号):如果给系统账号,别人可以尝试登录服务器,不安全,因此要把账号密码放在非/etc/{passwd,shadow}中,使之仅能访问某服务,而不能登录系统

基于虚拟用户的虚拟域邮件系统架构:如下方附图

 

 

附:/etc/rc.d/init.d/postfixsysv风格启动脚本):

#!/bin/bash

#

# postfix      Postfix Mail Transfer Agent

#

# chkconfig: 2345 80 30

# description: Postfix is a Mail TransportAgent, which is the program \

#              that moves mail from one machineto another.

# processname: master

# pidfile:/var/spool/postfix/pid/master.pid

# config: /etc/postfix/main.cf

# config: /etc/postfix/master.cf

 

# Source function library.

. /etc/rc.d/init.d/functions

 

# Source networking configuration.

. /etc/sysconfig/network

 

# Check that networking is up.

[ $NETWORKING = "no" ] &&exit 3

 

[ -x /usr/sbin/postfix ] || exit 4

[ -d /etc/postfix ] || exit 5

[ -d /var/spool/postfix ] || exit 6

 

RETVAL=0

prog="postfix"

 

start() {

         #Start daemons.

         echo-n $"Starting postfix: "

       /usr/bin/newaliases >/dev/null 2>&1

         /usr/sbin/postfixstart 2>/dev/null 1>&2 && success || failure $"$progstart"

         RETVAL=$?

         [$RETVAL -eq 0 ] && touch /var/lock/subsys/postfix

       echo

         return$RETVAL

}

 

stop() {

  #Stop daemons.

         echo-n $"Shutting down postfix: "

         /usr/sbin/postfixstop 2>/dev/null 1>&2 && success || failure $"$progstop"

         RETVAL=$?

         [$RETVAL -eq 0 ] && rm -f /var/lock/subsys/postfix

         echo

         return$RETVAL

}

 

reload() {

         echo-n $"Reloading postfix: "

         /usr/sbin/postfixreload 2>/dev/null 1>&2 && success || failure $"$progreload"

         RETVAL=$?

         echo

         return$RETVAL

}

 

abort() {

         /usr/sbin/postfixabort 2>/dev/null 1>&2 && success || failure $"$progabort"

         return$?

}

 

flush() {

         /usr/sbin/postfixflush 2>/dev/null 1>&2 && success || failure $"$progflush"

         return$?

}

 

check() {

         /usr/sbin/postfixcheck 2>/dev/null 1>&2 && success || failure $"$progcheck"

         return$?

}

 

restart() {

         stop

         start

}

 

# See how we were called.

case "$1" in

 start)

         start

         ;;

 stop)

         stop

         ;;

 restart)

         stop

         start

         ;;

 reload)

         reload

         ;;

 abort)

         abort

         ;;

 flush)

         flush

         ;;

 check)

         check

         ;;

 status)

       status master

         ;;

 condrestart)

         [-f /var/lock/subsys/postfix ] && restart || :

         ;;

  *)

         echo$"Usage: $0{start|stop|restart|reload|abort|flush|check|status|condrestart}"

         exit1

esac

 

exit $?

 

# END

 

 

 

 

 

以上是学习《马哥网络视频》做的笔记。