开源邮件系统安全

转自: http://blog.donews.com/Shan/archive/category/email。上面有很多收集的资料。

第一章 电子邮件基础知识

系统组成

1、邮件分发代理(mail delivery agent MDA)
在本地邮件服务器上将邮件分发给用户。邮件文件/var/spool/mail or $home/mail or邮件目录。可进行自动邮件过滤,自动回复,自动触发程序等功能。开源的MDA程序有:binmail(is mail),procmail

2、邮件传送代理(mail transfer agent MTA)
负责邮件的传送和接收。开源MTA有:sendmail,qmail,postfix。

3、邮件用户代理(mail user agent MUA)
在unix邮件模型中,用户使用一个本地邮箱来存放自已的邮件。MUA程序向用户提供了读取存在他们邮箱中邮件的操作界面。它并不接收邮件,它只是显示已经有用户邮箱中存在的邮件。开源的MUA程序,文本方式的binmail,图形方式的pine,kmail。

邮件安全

避免开放式转发,防止垃圾邮件,防范病毒。

第二章 SMTP协议

基本命令

1、HELO   
HELO hostname 从客户端打开问候信息,使用SMTP服务器识别客户机的身份。但客户机可随意修改这个hostname。存在安全问题,如果真要知道客户机的身份,可使用反向域名解析系统,根据客户机的IP地址查询其DNS名字。如果不符可拒绝访问。
2、MAIL   
标识发件人,MAIL FROM:[email protected]
3、RCPT   
标识收件人,RCPT TO:[email protected]
4、DATA   
标识邮件开始,命令后的所有内空为邮件的正文。以单行的“.”号为结束标记。
5、SEND   
直接把邮件发送到登录用户的终端,只在用户登录进来时有用,通常会弹出一条信息。有点类似于UNIX的write命令。该命令有一个很大的安全隐患,外部使用者使用该命令不需登录进计算机就可以知道有哪些用户登录进了系统。黑客利用这一点在互联网上搜录受害者ID和登录时间而不被发觉。绝大多数SMTP软件都不再支持这个命令。
6、SOML(SEND OR MAIL)
发送或邮寄。如果接收都当前登录到系统上,就执行SEND,如果不在就执行MAIL,同样有以上安全问题,通常禁用。
7、SAML(SEND AND MAIL)
发送和邮寄。同时完成两个功能。同样有以上安全问题,通常禁用。
8、RSET
即重置。如果客户机在接收服务器的响应时出现了混乱,认为当前的SMTP连接不再同步,就可以通过发该命令使连接回到HELO状态。
9、VRFY
在进入SMTP模式前,可以使用这个命令来判断一个SMTP服务器是否能将邮件发送到某个接收者。VRFY username。它是一个很好的故障排除工具。但存在可被黑客和垃圾邮件发送者利用的缺陷,因此很多站点都禁用这个命令。
10、EXPN
即扩展,用来向SMTP服务器查询邮件列表和别名。邮件列表是一种只使用一个地址向一群人发送邮件的快捷方式。EXPN address。通常禁用。
11、HELP
帮助命令。
12、NOOP
什么都不做,只是返回一个大于零的应答码。通常用于检测连接是否能建立。
13、QUIT
退出系统。
14、TURN
允许两台计算机在一个TCP连接中进行双向邮件传输。有安全问题,通常禁用。在ESMTP中有ETRN命令。

服务器应答

1、错误返回码
500    语法错误
501    参数中语法错误
502    不支持该命令
503    命令序列错误
504    不支持该命令参数
2、信息返回码
211    系统状态,或系统帮助
214    帮助信息
3、服务返回码
220    服务已准备好
221    服务正在关闭传输通道
421    服务不可用
4、操作返回码
250    所请求的邮件操作已进行完毕
251    非本地用户,需要发送至<forward-path>
354    开始邮件输入,以单行“.”号结束。
450    所请求的邮件操作未进行,邮箱不可用。
451    所请求的操作被中止,发生处理错误。
452    所请求的操作未进行,系统存储空间不足。
550    所请求的操作未进行,邮箱不可用。
551    非本地用户,请尝试<forward-path>
552    所请求的邮件操作被中止,超过存储空间。
553    所请求的操作未进行,邮箱名被禁止使用。
554    事务处理失败。

详情可参见:MTA的错误信息代码

1982年RFC821定义第一版的SMTP协议,1995年RFC1869定义了一套扩展SMTP功能的方法。使用扩展SMTP的标志是把最初版本中的问候命令HELO用新的问候命令EHLO代替。一旦服务器接收到这条命令,它意识到客户机有能力发送扩展的SMTP命令。新的命令有:
1、DSN(Delivery Status Notification),用来提示用户某封特定邮件的状态。
2、ETRN。允许客户端请求同服务器建立另一条smtp连接来传送邮件。它仅仅开始另一个会话,并不用原来的已经存在的会话传输数据。这样SMTP服务器就可以用DNS域名解析方法同客户进行联系。不依赖于客户声明的身份。
3、AUTH。它允许SMTP客户机使用用户ID AND PASSWORD或其他认证技术向服务器正确标识自己的身份。认证机制参数如下:
PLAIN                        使用文本方式的用户名和认证id和口令。
LOGIN                    使用基于64位密钥加密的用户名和口令。
GRAM-MD5            使用基于MD5加密的用户名和口令。
DIGEST-MD5        使用基于MD5加密的用户名和口令的摘要值。
KERBEROS_V4    使用基于Kerberos认证密钥。
GSSAPI                    使用普通安全服务(Generic Security  Service,GSS)认证密钥。

邮件格式(RFC822规范定义)

Received段            用来标识将邮件从最初发送者到目的地进行中间转发的SMTP服务器
from host name
by host name
via physical-path
with protocol
id message-id
for final e-mail destination
Return-path:route        标识邮件发送到目的地服务器所经过和路径
Reply to:address         邮件发出的地址
From: Sender:              标识原始邮件的作者
Date:date-time             邮件的时间

Destination段
to:address                     接收方地址   
Cc:address                   抄送方地址
Bcc:address                 密送方地址

option段
Message-ID:Message-id
Resent-Message-ID:Message-id
In-Reply-To:message-id
References:message-id
Keywords:text-list
Subject:text
Comments:text
Encrypted:word

Resent段     由于某种原因需从客户端再次发送,该段内容在信头的原始字段前面加上resent。
resend-reply-to
resent-from
resent-sender
resent-cc
resent-to
resent-bcc
resent-date

第三章 pop3协议

RFC1939定义了一个颇为流行的允许客户机从远程服务器上收取邮件的协议。称为邮局协议(post office protocol,pop)。现在使用的是该协议的第3版本,通常称之为POP3。端口110

user/pass命令用于登录pop服务器,但它是以ASCII码格式明文传送的,存在安全问题。apop命令登录时是用MD5加密的。命令格式:apop name digest AUTH命令,AUTH mechanism(PLAIN,LOGIN,SKEY,GSSAPI,KERBEROS)


客户端命令
STAT        显示邮箱当前状态
LIST         显示邮箱内容列表
RETR       从邮箱取回单个邮件的文本内容,参数是LIST命令返回的邮件号
DELE       删除邮箱中的邮件,参数是LIST命令返回的邮件号,按QUIT退出时邮件才真正删除。
UIDL        唯一的邮件ID列表。
TOP         可选安装的命令,它允许客户机以手工方式来获取邮箱邮件的概要信息 top msg n,
                top 10 5,表示显示第10封5行的概要信息

NOOP     什么都不做,用于查看服务器的状态响应情况。
RSET      重置
QUIT       退出

pop协议还存在一些缺陷,因此,近年来有一种开发更高级邮件收取协议的趋势,例如IMAP.

第四章 IMAP

IMAP(Interactive Message Access Protoclo)是由华盛顿大学开发的交互邮件访问协议。端口143

它允许使用者从多个地点访问邮箱而不会把邮件分割在不同计算机上,它把邮箱都存在服务器上。供客户随时随地取用。


LOGIN,文本方式的认证方法,存在安全问题

AUTHENTICATE命令 (PLAIN,LOGIN,SKEY,GSSAPI,KERBEROS)

IMAP客户端协议
IMAP提供了一系列命令对服务器上不同邮箱的邮件进行读取,转移和删除。记住,IMAP把所有的邮件都存放在服务器端,下载纯粹是为了显示。用户的缺省邮箱称为INBOX,所有的新邮件都出现在INBOX中。用户可以创建新邮箱,把INBOX中的邮件转移到其它地方。邮箱中的每条邮件都有一个唯一的ID,ID在不同会话中保护不变,以便客户端正确标识邮件。每个邮箱都有一个唯一的有效性标志(UIDVALIDITY),只要邮件的UID不发生变化,邮箱的有效性标志(UIDVALIDITY)也不会变化。如果邮箱中出现了不同的UID,那么下一次连接时的有效性标志(UIDVALIDITY)就会变大,用户就可以迅速知道有新邮件。

IMAP邮件标志
/Seen            已被阅读
/Answered   已被回复
/Flagged      标识为紧急
/Delete         标识为已删除
/Draft            草稿
/Recent        新邮件

IMAP客户端命令
select              选择一个邮箱操作
examine         以只读方式打开邮箱
create             创建邮箱,默认在$home目录下
delete             删除邮箱,而不是邮件
rename          邮箱改名
subscribe      在客户机的活动邮箱列表中增加一个邮箱
unsubscribe 在客户机的活动邮箱列表中去掉一个邮箱
list                   显示客户机可用的邮件列表 list reference mailbox,
                        reference是邮箱路径参数相关的目录名,如果是“”,则表示用户登录目录。
                        可列出所有文件,包括不是邮箱文件,存在安全问题,可以lsub。

lsub                只列出用subscribe设定为活动的邮箱。
status            查询邮箱当前状态
messages    邮箱中的邮件总数
recent             邮箱中标志为/recent的邮件数
uidnext           可以分配给新邮件的下一个UID
uidvalidity      邮箱的UID有效性标志
unseen          邮箱中没有被标志为/SEEN的邮件数
append         向某个邮箱发送邮件。不安全,最好不要使用
check            在邮箱中设置一个检查点,任何未完成的操作,都会被做完以保护邮箱的一致性。
                       同unix系统的sync

close             关闭邮箱,所有/delete标志邮件就会被物理删除,
                       在打开另一个邮箱时, 当前邮箱隐式地调用close。

expunge        在不关闭邮箱的情况下删除所有标志为删除的邮件。
search          搜索邮件,有很多搜索关键字,书上有,笔记没列出,可查询相关资料。
fetch              用于读取邮件,fetch messageset datanames(ALL,BODY AND BODY[section])。
                       BODY[section]会设置/seen标志。           
                       BOOY.PEEK[section]不会设置/seen标志。

store              用来修改邮件相关的信息。store messageset dataname datavalue。
                       例如:store 1 +flags /deleted设置删除标志。

copy               把邮件从一个邮箱复制到另一个邮箱。copy messageset mailboxname。
uid                  同fetch,copy,store or search一起使用,以标识uid号。
capability      返回请求返回imap服务器支持的功能列表。
noop              什么都不做,用来向服务器发送自动命令,防止因长时间处于不活动状态而导至连接中断。
logout            退出并关闭所有邮箱。任何作了/deleted标志的邮件将在这个时候被删除。


第五章 MIME协议

向互联网上的远程主机传输二进制数据的最流行的编码方法是uuencode and MMIE(Multipurpose Internet Mail Extension多用途互联网邮件扩展)格式。

Unencode—在smtp出现几年前,unix系统管理员向调制解调器线路发送二进制数据时首先将其转换为ASCII文本,然后嵌入邮件中,这种把二进制数据转换成ASCII文本数据的方法称为uuencode,其中uu代表unix to unix,是unix系统间复制协议组(UNIX TO UNIX COPY PROTOCOL)的一部份。

使用uuencode编码/解码
编码:uuencode [file] name  
example:uuencode hello hello>hello.uue     
default input is stdin;
default output is stdout.

解码:uudecode [-o outfile] name   
example:uudecode hello.uue
可以用-o选项输出另外一个文件名。


MMIE
很多新开发的邮件软件都不使用uuencode,因为出了一种对二进制数据进行编码的互联网标准。MMIE,MMIE的报文格式在RFC2045 AND RFC2046定义。功能把UUENCODE丰富,它将关于文件的附加信息也同时传送给解码器。使解码器可以自动检测不同类型的二进制文件并解码。

MMIE头字段
MIME-Version                             所使用的MMIE版本
Content-Transfer-Encoding    将二进制数据编码为ASCII文本使用的编码方案,7种:
                                                      7bit    标准的7位ASCII文本(default)
                                                      8bit    标准的8位ASCII文本
                                                      binary    原始二进制数据
                                                      quoted-printable    将数据编码成US-ASCII字符集中的可打印字符。
                                                      base64    每6位二进制数据转换成1个8位的可打印字符。
                                                      ietf-token    RFC定义的扩展令牌编码。
                                                      x-token    两人字符X- or x-跟随,没有任何令牌产生的分隔空格
Content-ID                                  邮件内容部份的唯一标识,通过该标识mmie的内容可被其它mmie邮件引用
Content-Description                 邮件内容部份的简短描述
Content-Type:tyep/subtype(必须)        编码数据中的内容类型
                                                    type为基本类型
                                                    1、text文本类型
                                                        plain子类型:表示没有格式的普通ASCII文件
                                                        html子类型:表示使用标准的html标记来格式化文本
                                                        enriched子类型:表示文本的格式类似于很多字处理软件中的丰富文本格式.                                                                                          RTF(有下划线,粗体等)。
                                                        还应该使用字符集参数charset明确指明数据编码时采用的字符集。如:
                                                        Content-Type:text/plain;charset=us-ascii
                                                    2、message报文类型,允许邮件软件在一条邮件发送多条RFC822邮件
                                                        rfc822子类型:表示嵌入的是一条普通的RFC822邮件
                                                        partial子类型:表示被分成几部份的一段长邮件
                                                        external-body子类型:表示指向邮件外某位置的指针
                                                    3、image图像类型,jpeg and gif。
                                                     事实上需用Content-Type-Encoding字段中定义的标准MIME编码方式来编码。
                                                    4、video视频类型,mpeg,同上需用Content-Type-Encoding
                                                    5、audio声音类型,basic,
                                                        采用8kHz采样频率编码的单信道综合服务数字网mu-law。

                                                       6、application应用程序类型。
                                                            postscript子类型:定义以附录格式出现的打印文档。
                                                            octet-stream子类型:定义包含任意二进制数据的邮件。
                                                        7、multipart混合类型
                                                            可包含多种数据类型,每种数据类型用Conten-Type来定义。
                                                            每种定义间用边界标识符来分隔

                                                            example:    Conten-Type:mulipart/mixed;boundary=bounds2
                                                                    –bounds2                 分隔符
                                                                    Conten-Type:text/plain;charset=us-ascii
                                                                    –bounds2
                                                                    …
                                                                    –bounds2–          结束符
                                                           类型有四种:
                                        mixed:表示各部份间互相独立,应该按照它们在邮件中嵌入的顺序向接收者显示。
                                        parallel:表示各部份间互相独立,可按任意顺序向接收者显示。
                                        alternative:表示各部份都是同一数据的不同表示方式,只需要使用最合适的显示方式显示其中一部份
                                           digest:表示同mixed一样的方式,但是邮件体总是rfc822格式。

S/MIME 安全MIME协议
在S/MIME Multipart中加入一个signed子类型,邮件由两部份组成,标准邮件部份和数字签名。数字签名方法允许发信人使用唯一的代码来“签发”邮件,其他人可以使用公钥来验证该代码。这种方法并不对邮件进行加密。人们创建pkcs7-mime应用子类型来提供一些邮件安全功能。每种功能使用pkcs7-mime子类型中的一个单独的参数,通过smime-type标志来确定。
example:Conten-Type:multipart/signed;
    protocol="application/pkcs7-signature";
    micalg=sha1;boundary=bound1
    –bound1
    Conten-Type:text/plain
        this is a clear-signed message
    –bound1
    Conten-Type:application/pkcs7-signature;name=smime.p7s
    Conten-Transfer-Encoding:base64
    Content-Disposition:attachment;filename=smime.p7s
    …
    –bound1–

pkcs7/mime功能
data            未加密的邮件文本在其它Content-Type部份中表示邮件内容使用了安全服务措施,但是在pkcs7-mime类型中包含的使用data功能定义的数据不被加密。

encrypted-data        加密的邮件文本在其它Content-Type部份中表示邮件内容已经加密,数据是使用公钥加密方法加密的,加密后的数据使用某种标准的MIME编码方法,例如base-64,转换成ASCII文本。

signed-data        未加密的邮件文本和数字签名???????同multipart/signed方法类似,允许发送方将普通的文本邮件连同数字签名一起发送,不同的是application/signed-data方法使用公钥加密方式对原始邮件进行加密和签名。结果经base-64编码后通过smtp发送。接收端邮件阅读软件必须能够将邮件解密供收信人阅读。

enveloped-data        加密的邮件文本向邮件提供邮件加密服务,但是不提供认证服务。

signed-and-enveloped-data    加密的邮件文本和数字签名在一封邮件中包含了公钥加密服务和数字签名服务,接收端软件必须能够将邮件和数字签名解密。这样收信人不但能能够看到邮件内容,同时也可以判断是谁发出的邮件。
digest-data        用来认证原始邮件的经过散列运算的邮件文本用于认证邮件内容,邮件发送时,发送人使用自已的数字签名对邮件进行散列运算。散列函数根据事先确定的算法计算出一个散列值,放到digest-data部份,该部份被加进普通邮件部份,收信人使用数字签名对收到的邮件进行散列运算,比较结果和digest-data中的值,如果相等就认为邮件是可信的。

其中data,signed-data,enveloped-data是必须支持的S/MIME功能。

在S/MIME中加密邮件和生成数字签名,你必须有一个有效的,唯一的数字标识密钥。有几家公司提供这种密钥,通常是收费的。关于获得数字标识密钥的更多信息可以浏览verisign网站。

unix 上常用的MIME邮件处理工具:metamail and reformime

小结

使用smtp发送二进制数据是一件复杂的事,现在有二种方法可以实现,一个用uuencode程序,将二进制数据转换成ASCII文件,收信人用uudecode解码还原。另一种是用mime协议在邮件发送前转换并标记二进制数据。MIME格式的邮件包含若干独立的部份,封装了不同类型的发送数据。普通文本不用编码直接包含进来,二进制数据,例如图像和可执行文件,通过base-64编码后作为独立部份包含在邮件中。各部份的定义存放在一个MIME邮件头字段中,这样接收邮件服务器就可以将各部份解码。

S/MIME是在标准的MIME中加进了安全功能。人们通过增加几种MIME邮件头格式来标识签名的邮件和加密后的邮件,邮件加密过程使用商业数字密钥实现的。接收者邮件服务器必须能够识别用来加密邮件的数字密钥。
S/MIME的另一种使用方法是采用外部加密软件,pgp程序给用户提供了一种在邮件发送前进行加密和签名的方法。收件人知道发信人的数字密钥才能正确认证并解密邮件。

第六章 读取邮件头

to: and from:字段是代表收信人和发信人的邮件地址,但它们是可以伪造的。to:错了邮件是不会被发送到错误的地方的。因为RCPT命令用来通知远程邮件服务器将邮件发给谁,服务器使用该命令的信息而不是邮件头中的to:字段信息来发送邮件。对于垃圾邮件,发信人使用软件篡改了邮件头中的to:字段,将正常的收件人地址放到了Bcc:字段或RCPT命令中。通过篡改to:字段,发信人就可以把一封同样的邮件群发给成千上万的顾客。决窍不在于to:字段被篡改,而在于邮件没有使用标准的MTA程序发送。垃圾邮件发送人使用了一个特殊的MTA程序,从目标地址列表中读取邮件地址,然后把它们放到BCC: OR SMTP中的RCPT命令中,而不是使用通常的TO:字段。

received:字段
垃圾邮件发送人的邮件主机依赖于远程的支持开放式转发的邮件服务器,每经一部服务器,就要在邮件顶端加一个received:字段。记录时间戳,可以查询邮件经过服务器的时间。

message-id:字段
该字段常常也能发现最初的发信人。它由最初发送邮件的服务器产生,通常包括服务器主机名。

使用dns程序追查邮件主机
whois     nslookup     dig(A 互联网地址,SOA 从正式信息开始,NS  名称服务器,MX 邮件服务器)

利用外部防垃圾邮件的服务
SpamCop网站
Sam Spade网站

第七章 保护UNIX服务器安全

利用syslogd日志程序

安装防火墙(iptables)

利用Bastille工程加固linux安全

入侵检测,安装Tripwire。

第八章 Sendmail邮件软件

sendmail            组成部份
sendmail            从本地和远程接收邮件并决定怎样进行发送
sendmail.cf        控制sendmail程序运行的配置文件
sendmail.cw        包含sendmail收取邮件的域名列表
sendmail.ct        包含可以控制sendmail的信任用户列表
aliases            包含可以把邮件重定向给其它用户,文件或程序的有效本地邮件地址列表
newaliases        从文本文件中创建一个新的别名数据库文件
mailq            检查邮件队列,显示所有信息
mqueue            存放待发送邮件的队列
mailertable        用来覆盖向指定域的路由
domaintable        用来把旧域名映射互新域名
virtusertable        用来把用户和域名映射到其它地址
relay-domains        用来允许特定主机通过sendmail程序转发邮件
access            用来拒绝或允许来自某个域的邮件

sendmail.cf文件包含用来分析每条邮件,并决定怎样处理的规则集。它是由一系列的类(定义常用词组,帮助规则集指定特定的邮件类型),宏(为减少配置文件中长字符串的输入而设定的值),选项(定义sendmail运行的参数)和规划集组成。

sendmail    配置文件中使用的字符
C    定义文本的类
D    定义宏
F    定义包含文本类的文件
H    定义邮件头字段和动作
K    定义包含查询文本的数据库
M    定义发件人
O    定义sendmail选项
P    定义sendmail优先值
R    定义解析地址的规则集
S    定义规则集组

D行
Dx value    example:DnMAILER-DAEMON 它把字符串MAILER-DAEMON分配给了宏n,规则集就可以使用宏$n来代替字符串MAILER-DAEMON。

C行
Cc phrase1 phrase2 …,c是类名,phrase1,phrase2等是希望归为一组的单词。example:Cwlocalhost sadrach。这个例子把单词localhost,shdrach归为w类,在规则集中使用$w变量时,sendmail就将会用这两个单词来替换该变量。

F行
Fc filename,和C行类似。但F行指向包含类中所有用来单词列表的文件。c是单字符类名,filename是包含单词列表的全路径名文件。

K行
定义sendmail中用来查询不同类型信息的特殊的映射数据库。Kmapname mapclass arguments。mapname是配置文件中使用的数据库名,mapclass是生成的数据库类型(dbm,btree,hash等)grguments用来帮助sendmail创建数据库。可以用makemap命令从文本文件中创建映射数据库,不同的unix版本使用不同的默认映射库,目前,linux的makemap只支持btree and hash类型的映射类。地者中hash常用。命令例子:makemap mapclass outputfile < textfile

H行
定义sendmail加到邮件中的邮件头中的行的格式。H[?mflags?]hname:htemplate,mflags是宏标志,必须定义。hname是邮件头中行的名字,htemplate是使用宏的邮件头行的格式。

M行
定义一个sendmail用来发送邮件的发送程序。每种不同类型的发送程序都必须有一个M行定义,这样sendmail才知道怎样使用它们。Mprog,[field=value]…。prog是发送程序的名字,每个field=value对定义sendmail使用该发送程序所需要的属性。

P行
定义优先值。每个RFC822格式的邮件都可以使用邮件头中的Precedence:字段来定义邮件的紧急程序。Ptext=value。text是Precedence:中的字符串,value是sendmail根据Precedence中的文本字符串分配数字优先值。Pfirst-class=0;Pspecial-delivery=100;Plist=-30。

O行
定义控制sendmail运行的选项。这些选项也可以在sendmail程序启动时用-O or -o设置。
O option=value。
规则集行是配置文件的核心,它们指示sendmail怎样获取接收邮件并决定怎样将邮件发给相应的接收人。规则集使用R 和 S行。R行定义对邮件进行的实际操作,S行定义规则集分组。

R行
R行用令牌处理发来的邮件,以确定正确的收件人和将邮件发给收件人的方法,每一个R行代表一个独立的规则。每条规则由两部份组成,左手边(left-hand side,LHS)和右手边(right-hand side,RHS),LHS定义在发来的邮件中寻找哪些令牌或单词,RHS定义怎样基于LHS发现的令牌重写地址。格式如下:Rlhs    rhs    comments字段间至少使用一个制表符分隔。规则集中使用的任何宏和类都被展开以匹配获取的信息。LHS定义特殊的符号来分析邮件,

LHS    符号
$*    匹配0个或更多个令牌
$+    匹配1个或更多个令牌
$-    只匹配1个令牌
$@    匹配0个令牌
$=x    匹配x类中的所有条目
$-x    匹配所有不在x类中的条目

RHS        重写邮件时所使用的符号
$n        从LHS中替代令牌n
$[name$]        主机的正式域名(FQDN)
$(map key $@ arguments $:Default $)    通用的密钥映射功能
$>n        “调用”规则集n
$#mailer        解析邮件发送程序名
$@host        指定主机
$:user        指定用户

S行
标识一组通常用数字表示的组成规则集规则。sendmail共有六个标准的规则集,分别是:
0        解析邮件发送程序,主机和用户
1        应用于所有发件人地址
2        应用于所有的收件人地址
3        把地址转换成正式的域名格式
4        将内部地址翻译为外部地址
5        应用于所有没有别名的本地地址

典型的邮件通过标准规则集的路径:所有邮件都首先通过规则集3,把主机名转换成FQDN格式,将地址“清除”。通过规则集3后,规则集0从地址中解析出发件人,主机名和用户名。然后邮件被交给由M行定义的相应的邮件系统。同样,规则集1用来改写发送人地址,规划集2用来改写收件人地址。这些信息然后被交给规则集4,用来把地址转换成外部格式。可用-bt选项来运行sendmail,以监视不同规则的动作。

m4预处理器
m4预处理器用来从一组宏文件中创建sendmail配置文件。宏文件作为输入被读进来。宏被展开,然后写到一个输出文件。
sendmail            宏定义
divert(n)            为m4定义一个缓冲动作,当n=1时缓冲被删除,n=0时开始一个新缓冲
OSTYPE            定义宏所使用的操作系统,该宏允许m4程序增加同相关操作系统相关的文件
Domain            定义MTA将使用哪些域来传输邮件
Feature            定义配置文件中使用的一个特定的功能集
Define            定义配置文件中的一个特定的选项值
MASQUERADE_AS    定义sendmail来应答邮件的其它主机名
MAILER            定义sendmail使用的邮件传输方法

启动sendmail。sendmail -bd -q30m  该命令以后台进程方式(-bd)运行,并使其每隔30分钟(-q30m)轮询一次未发送邮件队列,检查是否有新邮件。

保障sendmail安全
文件权限
正确设置文件权限是sendmail系统重要的一部份,如果文件、目录或用户的权限设置不当,会给黑客有机可乘。如果违背了sendmail的文件权限策略,sendmail将会产生警告信息。现在的sendmail程序中对文件和目录又增加了很多新约束,绝大多数限制都归结为以下两种常常被忽视的情况:
1、对于同组中用户或全局用户可写的文件sendmail不能读、写和执行。
2、对于同组中用户或全局用户可写的目录下的文件sendmail不能读,写和执行。
这两种情况覆盖了绝大多数缺乏经验的邮件管理员所遇到的问题。
如果必须存在组可写或全局用户可写的文件或目录的邮件环境,你可以使用sendmail.cf配置文件中的DonBlamesendmail选项参数禁止sendmail发出警告。O DonBlamesendmail = option。option是你所希望开放程度的一个或多个参数名,缺省值为safe。表示严格的策略。
如果希望sendmail访问位于组可写目录下的文件,可以用如下格式:
O DonBlamesendmail=GroupWritableDirPathSafe(注意,故障排除时可用该选项,正式工作服务器不应该这样设置)

sendmail用户
sendmail能识别三种特殊用户,这三种用户在sendmail.cf文件中被定义成选项值:
TrustedUser
DefaultUser
RunAsUser

缺省情况下,sendmail假定root用户将被用来运行sendmail并拥有所有特殊的sendmail文件。如sendmail.cf and sendmail.cw。可以使用以下选项来修改sendmail使用的用户值。
TrustedUser选项允许你指定一个或多个用户作为sendmail访问的文件属主,可以用T行来设置信任用户Troot,Tdaemon等,也可以用Ft行来定义。DefaultUser允许sendmail使用root以外的用户名来运行独立的邮件程序。如(procmail)。
缺省时,sendmail将会以mailnull来运行所有的邮件程序。除非它在系统中找不到该用户名时才会使用root来启动邮件程序。RunAsUser选项指定了运行sendmail的用户名的权限。
sendmail必须用root用户启动才能访问smtp端口,此后,它可以使用setuid功能转变为系统中的另一个用户。这个用户必须能访问下面列出的服务器上的同sendmail相关的区域。1、对/var/spool/mqueue目录有写权限;2、对/var/log/maillog文件有写权限;3、对sendmail.cf 文件以及其它用来的sendmail列表有读权限。

受信应用
作为更高级别安全控制,sendmail允许你在基于别名或.forward文件发送邮件时指定所使用的可执行的程序。使用受限shell(smrsh)。

第九章 qmail


第十章 postfix

第十一章 防止开放式转发

配置选择性转发
sendmail 8.9版本以后,sendmail在缺省配置时禁止进行开放式转发,你需要指定哪些主机、网络或域被允许通过你的邮件服务器转发邮件。下面介绍通过配置sendmail进行选择性转发。
1、使用访问列表
sendmail允许你创建一张访问列表,记录可以访问你的邮件服务器的主机。host active。Host可以是主机,子网或域名。active可以是Ok–远程主机可以向你的邮件服务器发送邮件;
RELAY–允许中转;REJECT–不能向你的邮件服务器发邮件和不能中转;DISCARD–发来的邮件将被丢弃,同时并不向发送者返回错误信息。nnn text– 发来的邮件将被丢弃,但sendmail将会向发送者返回nnn确定的smtp代码和text变量确定的文本描述。
下面是一个访问列表的例子:
192.168 RELAY
XXX.NET    OK
XXX.COM REJECT
XXX.COM    550 SORRY,WE DON’T ALLOW SPAMMERS HERE
XXX.ORG    DISCARD
2、在配置中加进访问列表
如果使用m4宏预处理器,把以下命令加进sendmail.mc脚本。FEATURE(`access_db’)。如果没有m4,你必须手工添加一条K配置行来定义访问列表。Kaccess hash /etc/mail/access。
3、创建访问列表
makemap /etc/mail/access < /etc/mail/access.txt
4、其它选择式转发选项
可在m4的FEATURE命令中配置
relay_host_only        只允许访问列表中的列出的主机
relay_entrie_domain    允许所有声明是你的域中的远程服务器进行转发
relay_base_on_MX    允许向主机维护的域中转发
relay_local_from    允许来自本地网络中所有主机的转发
loose_relay_check    不进行对邮件主机的祥细的路由检查
promiscuous_relay    进行开放式转发
注意:使用relay_entrie_domain 和relay_local_from时要小心,黑客很容易对SMTP会话地址进行伪装。

避免开发式转发
比好的做法是既不作开放式转发,也不接收来自已知开发转发服务器的邮件。很多MTA软件都有办法使邮件服务器与MAPS RBL(邮件滥用预防系统的实时黑洞列表)相连接,确定某个远程邮件服务器是否为开放式转发,如果列表中发现了该主机地址,那么来自该主机的邮件将被认为是垃圾邮件,并被挡在服务器之外。

配置sendmail使用MAPS RBL
如果使用m4,加入以下条目:FEATURE(‘DNSBL’,'HOST’)。host指向另一个rbl服务器,如果你希望使用标准的RBL服务器,可以忽略该参数。

第十二章 阻挡垃圾邮件

有三种方法比较流行
1、拒收来自已知主机的邮件。建立访问列表,具体设置见上文。
2、对由远程主机提供的SMTP会话信息进行确认。通过DNS查询以确定客户的正确性。
在sendmail 8.9.3版起,增加了以下smtp验证规则,默认已配置好。
如果MAIL FROM:命令参数是未解析的域名则拒收邮件。
如果MAIL FROM:命令参数不FQDN格式则拒收邮件。
拒收来自发送空的HELO OR EHLO命令的主机的邮件可以通过以下命令修改:
FEATURE(‘accept_unresolvable_domains’)dnl
FEATURE(‘accept_unqualified_senders’)dnl
define(‘confALLOW_BOGUS_HELO’,'True’)dnl
3、通过查找已知的垃圾邮件的记号来过滤进入的信息。
创建规则集,对进入的每一个邮件头进行检查过滤。用H行定义,一个常用方法是创建包含在邮件Subject:的头字段中可找到的垃圾邮件词语的文件,bad_subject文件,包含一些垃圾邮件常用的主题词。接着配置sendmail对,该文件中的词语进行过滤。首先在H行尾加一句:HSubject:$>Check_Subject。下一步是创建规则集。这需要加入三行。一个S行确定规则,一个F行确定bad_subject文件路径,一个R行确定所要采取的实际动作。例如
SCheck_Subject
F{Header}/etc/mail/bad_subject
R$={Header} $* $#error $: 553 we don’t like spam here

第十三章 过滤病毒

有两种较流行的方法
1、基于已知短语的过滤。(方法同过滤垃圾邮件)
2、对附件进行扫描。步骤较多,一般有以下几步
判定该信件是否含有MIME或者未编码附件;
提取出MIME或者未编码文件的二进制文档;
确定这个二进制文档是否已被压缩,如果是压缩,将其取出;
扫描所有的未压缩文件,寻找已知病毒;
如果没病毒,就让信息如常发送,如果有病毒,通知发信者、本地邮件管理员和可能的接收者。

设置病毒扫描
除常规MTA程序外,还需要两个程序
1、用于发现和取出信件中的二进制文档附件的软件;
2、用于检查二进制文件中是否具有已知病毒的软件。
AMaViS(A MAIL VIRUS SCANNER)是一个著名的且被广泛使用的开源软件。它能取出信件中的附件文档,解压任何压缩文档,并且用反病毒软件对它们进行扫描。在unix平台上暂时还没有开源的防病毒软件,要使用商用软件。

配置sendmail使用amavis
define(‘LOCAL_MAILER_PATH’,'/usr/sbin/amavis’)dnl
define(‘LOCAL_MAILER_ARGS’,CONCAT(‘amavis $f$u/usr/bin/’,LOCAL_MAILER_ARGS))dnl
MODIFY_MAILER_FLAGS(‘LOCAL’,'-m’)dnl

第十四章 使用邮件防火墙

关闭一些SMTP命令,建立邮件防火墙,可使邮件服务器免受探查和攻击。

禁用VRFY AND EXPN命令。O option PrivacyOptions = novrfy,noexpn。如果是M4:
define(‘confPRIVACY_FLAGS’,'novrfy,noexpn’)

使用邮件防火墙,它是一台专用的邮件服务器,专门用来转发发往你的内部邮件服务器和从其发出邮件。经过配置,邮件防火墙接收发往你的域中的邮件,将它们直接发给通常在内部的网络中的真正的域邮件服务器。同样,邮件防火墙也转发从内部邮件服务器发往互联网的邮件,理想状态下,邮件防火墙不应该接收所有发往内部任何用户的邮件,也不应该禁止所有发往内部邮件服务器的邮件。如果邮件服务器失效,黑客也不能访问用户的邮箱。如果你决定使用邮件防火墙,有3个地方可以放置。位于网络防火墙的机器中,位于DMZ中,位于内网。不管邮件防火墙放在什么地方,它的配置都是一样的。它必须从外部网络接收邮件然后发给内部邮件服务器,真正的用户邮箱位于其上。反过来,内部邮件服务器也必须被配置成将所有的外发邮件都交给由邮件防火墙来转发。

sendmail防火墙
配置sendmail邮件防火墙时,使用称为虚拟用户列表的对照表将本地域的邮件地址映射到内部邮件服务器。虚拟用户列表为文本文件,包含你的邮件环境中需要的地址映射关系。内部的邮件服务器必须配置成使用邮件防火墙作为转发主机。增加一条指向新表的记录,如果使用M4,则:FEATURE(‘virtusertable’,'db[options]‘),db是数据库映射类型,选项中默认的数据库文件位置为/etc/mail/virtusertable。如果手工添加:Kvirtuser hash /etc/mail/virtusertable。数据库文本文件格式如下:alias  location。文件中,alias是邮件防火墙接收邮件用的虚拟别名,location是sendmail转发邮件至的内部邮件服务器的主机名或邮件地址。为了把所有发给ispnet1.net域中用户的邮件重新定向给内部邮件服务器上的同一个用户,可以使用下面的表记录:@ispnet1.net    %[email protected]。所有接收到的发给ispnet1.net域中用户的邮件都被转发给mailserver.ispnet1.net主机上的同一个用户,邮件防火墙上不储存任何邮件。生成虚拟用户列表后,要通过以下方法转换:makemap hash /etc/mail/access < /etc/mail/access.txt。完成配置以后,还必须在/etc/mail/local-host-names文件中加入你用来接收邮件的域名(在这个例子中是ispnet1.net)。该文件用来定义sendmail接收邮件的主机。

配置内部邮件服务器。将所有邮件都通过邮件防火墙转发,通过配置智能主机实现。如果使用m4,可以这样配置:define(‘SMART_HOST’,'firewall.ispnet1.net’)dnl,也可以用ip。配置智能主机后,还要配置回信地址指向域名而不是内部邮件服务器。配置如下:
MASQUERADE_AS(domain)
FEATURE(‘masquerade_envelope’)

第十五章 使用SASL

SASL(简单认证和安全层协议)定义了一套任何网络应用程序都可用来对远程用户进行认证的机制。很多开源MTA都用它来实现AUTH命令。
要sendmail支持SASL需重新编译sendmail。编译前要修改源码的位置配置文件。
site.config.m4位于源码目录树的devtools/Site。文件中应包含以下行:
APPENDDEF(`confENVDEF’,`-DSASL’)
APPENDDEF(`conf_sendmail_LIBS’,`-lsasl’)
APPENDDEF(`confLIBDIRS’,`-L/usr/local/lib’)
APPENDDEF(`confINCDIRS’,`-I/usr/local/include’)
前二行指示sendmail在可执行程序中包含SASL支持,后两行定义SASL库文件和头文件位置。接着可以进行编译。下一步是在sendmail配置文件中加入SASL支持。
TRUST_AUTH_MECH(`LOGIN PLAIN CRAM-MD5′)dnl
define(`confAUTH_MECHANISMS’,`LOGIN PLAIN CRAM-MD5′)dnl
如果是手工编辑sendmail.cf文件,则加入:
C{TrustAuthMech}LOGIN PLAIN CRAM-MD5
O AuthMechanisms=LOGIN PLAIN CRAM-MD5

为确保CYRUS-SASL函数库知道怎样验证所收来的SASL认证请求,必须创建一个SASL的配置文件来把MTA程序定义成一个SASL应用。配置文件名为Sendmail.conf,位于/usr/lib/sasl目录下,在该文件中你必须定义你希望使用的认证数据库方法:pwcheck_method:PAM,这个例子使用PAM系统用户名数据库来验证认证请求。

第十六章 安全的pop3 and imap服务器

使用ssl协议,允许网络主机在发送数据之前将其加密,在接收端由接收主机将数据解密成正常格式。
生成证书:openssl req -new -x509 -nodes -out imapd.pem -keyout imapd.pem -days 3650
这个命令创建了一个名为imapd.pem的x509证书,(记住证书名需与应用名匹配),将证书和私钥放于同一文件中,并保证其在10年内有效。运行命令时,会提几个问题,其中Common name应该键入主机名。否则一些客户端要么警告用户这个证书不是发给服务器的,要么拒绝接受该证书。生成证书后,要应用于不同程序。需要拷贝
cp imapd.pem /usr/local/ssl/certs/imapd.pem
cp imapd.pem /usr/local/ssl/certs/ipop3.pem

在ssl基础上使用UW IMAP.
=====================================================
作者:肥肥世家(http://www.ringkee.com/)
原文地址:http://www.ringkee.com/jims/read_folder/books/OpensoureMailSecurity
=====================================================

你可能感兴趣的:(开源邮件系统安全)