热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

Sendmail的安全配置

安全与sendmail随着Internet的爆炸性增长,像sendmail这样接受用户所提供的任意输入并把它投递给本地用户、文件或shell的应用常常会为黑客们提供一条实施攻击的坦途。sendmail和DNS甚至IP,正在尝试把身份验证和加密作为内建的解决方案以解决一些基本的安全

安全与sendmail

随着Internet的爆炸性增长,像sendmail这样接受用户所提供的任意输入并把它投递给本地用户、文件或shell的应用常常会为黑客们提供一条实施攻击的坦途。sendmail和DNS甚至IP,正在尝试把身份验证和加密作为内建的解决方案以解决一些基本的安全性问题。

最近美国关于加密技术的出口法规开始松动,这使得sendmail在发布时可以内建对加密功能的挂接接口。版本8.11及其后继版本都支持用SSL(Secure Socket Layer,安全套接口协议层)进行SMTP身份验证和加密,SSL也称为TLS(Transport Layer Security,传输层加密)。sendmail在这里使用术语TLS,并且已经把它作为对SMTP协议的一种扩展?STARTTLS?实现了。TLS给它带来了6个用于鉴定文件和给文件上锁的新配置选项。对访问数据库进行匹配的新操作要求身份验证必须先取得成功。

在本节中,我们将描述sendmail的权限模型、所有权和隐私保护的演变。然后简要讨论SASL(Simple Authentication and Security Layer,简单身份验证和加密层协议)和它在sendmail中的使用。

随着时间的推移,sendmail已经逐渐加强了它的安全性,现在,在它相信一个文件(比如说.forward或aliases)之前,它对文件权限是非常挑剔的。虽然这种安全性的加强通常会受到欢迎,但有时也有必要放松强硬的新规则。为了达到这个目的,sendmail引入了DontBlameSendmail选项,这样命名是希望这个名字会提醒系统管理员,他们正在做被大家认为是不安全的事情。

这一选项有许多可能的值?最新统计有55种之多。默认值是safe。值的完整列表请参见sendmail软件发布里的doc/op/op.ps这个文件。还是继续把这个选项设置为safe吧。


所有权

在sendmail世界中有3个用户账号很重要:DefaultUser、TrustedUser和RunAsUser。

默认情况下,除非邮寄程序的标志位另行指定,否则所有sendmail的邮寄程序都作为DefaultUser运行。如果在/etc/passwd文件中存在用户mailnull、sendmail或者daemon,那它就是DefaultUser了。否则,它默认为UID 1和GID 1。我们推荐使用mailnull账号和一个mailnull组。把它添加到/etc/passwd中,用一个星号作为口令,没有有效的shell,没有主目录,默认属组为“nogroup”。您也要在/etc/group文件里加上mailnull。Mailnull账号不应该拥有任何文件。如果sendmail不是以root身份运行的,那么邮寄程序必须设置setuid位。

如果设置了RunAsUser,那么sendmail会忽略DefaultUser的值,而以RunAsUser的身份完成所有工作。如果您正在以setgid(到smmsp)方式运行sendmail,那么提交邮件的sendmail只是通过SMTP把消息传递给真正的sendmail。真正的sendmail没有设置它的setuid位,但它的启动脚本需以root身份运行。

sendmail的TrustedUser可以拥有映射和别名文件。TrustedUser可以启动守护进程或重建aliases文件。之所以存在这个功能多是为了支持sendmail的GUI界面,需要这样的界面来向有些用户提供受限的管理控制权。如果您设置了TrustedUser,那么就要保护好它所指向的账号,因为这个账号很容易被利用,得到root权限。TrustedUser不同于称为TRUSTED_USERS的sendmail类,后者决定谁可以重写消息的From行 。

sendmail打开到端口25的套接口连接之后,以RunAsUser作为UID来运行。编号小于1024的端口只能由超级用户打开,因此,sendmail最初必须作为root运行。不过,执行完这项操作之后,sendmail可以切换到另一个UID。如果sendmail被欺骗做一些不好的事,这种切换就降低了损害或访问的风险。不要在支持用户账号或者其他服务的机器上使用RunAsUser功能,它是只供防火墙或者堡垒主机使用的。

在默认情况下,sendmail不切换身份并继续作为root运行。如果您把RunAsUser改为不是root的其他身份,那么还必须修改其他几个地方。
RunAsUser必须拥有邮件队列,能够读取所有的映射和包含文件,能够运行程序等。估计要花几个小时才能找出所有必须修改的文件和目录的所有权关系。


权限

文件和目录权限对sendmail的安全性十分重要。请使用表18.14中列出的设置以确保安全。

表18.14 sendmail相关目录的属主和权限

路    径

属    主

模    式

内    容

/var/spool/clientmqueue

smmsp

770

初始提交的邮件队列a

/var/spool/mqueue

RunAsUser

700

邮件队列目录

/, /var, /var/spool

root

755

mqueue的路径

/etc/mail/*

TrustedUser

644

映射、配置文件、别名

/etc/mail

TrustedUser

755

映射文件的父目录

/etc

root

755

Mail目录的路径

a.8.12及以后版本。

sendmail不会读取权限过于宽松的文件(例如,任何组或任何人都可写的文件,或者位于任何组或任何人都可写的目录中的文件)。sendmail对所有权和权限很严格的部分原因,是有一些操作系统允许用户用chown将自己的文件转让出去(那样的操作系统大多都是从System V演变而来的)。

Linux系统默认都有一个健全版本的chown,它们不允许转让文件。不过,在代码中设置一个预编译指令#ifdef就可以让chown采用System V的语义(CAP_CHOWN)。您还要重新编译内核。但是这种做法并不好,不要迫使您原本合理的Linux的chown按照有缺陷的System V的方式来运行。
特别地,sendmail对任何别名(aliases)文件或者转发(forward)文件的完整路径非常挑剔。这么挑剔的话,有时会和站点管理Majordomo邮递列表别名的方式发生冲突。例如,如果Majordomo列表位于/usr/local,那么整个路径必须是可信的,路径的各个部分都没有组写权。这项限制让列表的所有者更难以管理别名文件。要看看在sendmail对于权限的考虑上,您做得如何,可以运行:

 define(‘LUSER_RELAY',  ‘error:No  such  user')
-bi标志初始化别名数据库,如果权限不对就向您发出警告。

如果到某个文件的目录路径是不安全的(权限过于宽松),sendmail将不再读取链接数大于1的.forward文件。这条规则在最近就让Evi碰上了,因为她的.forward文件在把她的邮件从她不会收到太多邮件的小站点转发过来时一声不响地就失败了,这个文件在一般情况下是到.forward.to.boulder或.forward.to.sandiego的一个硬链接。过了好几个月她才意识到并明白过来,“我从没收到过您的信”是她的错,并且再也不是一个说得过去的借口了。

可以用DontBlameSendmail选项关掉上面提到的许多限制文件访问的规则。但是不要那么做。


发到文件和程序的可靠邮件

我们建议您使用smrsh代替/bin/sh作为您的邮寄程序(mailer),并用mail.local代替/bin/mail作为本地邮寄程序。这两个程序都包含在sendmail的软件发布中。为了把它们合并到您的配置中,请把以下两行:

 FEATURE(‘smrsh',  ‘path-to-smrsh')
FEATURE(‘local_lmtp',  ‘path-to-mail.local')

添加到您的.mc文件中。如果省略了明确的路径,就认为命令位于/usr/libexec下。您可以使用sendmail的confEBINDIR选项把二进制程序的默认位置改为您需要的任何地方。Red Hat的默认安装根本就没有提供mail.local。SUSE把它放在/usr/lib/sendmail.d/bin下,而Debian和Ubuntu把它们藏在了/usr/lib/sm.bin里。

smrsh是一个受限的shell,它只执行一个目录中包含的程序(默认情况下是/usr/adm/sm.bin)。Red Hat和Fedora把smrsh这个二进制程序安装在/usr/sbin下,SUSE把它放在/usr/lib/sendmail.d/bin下,而Debian和Ubuntu把它放在/usr/lib/sm.bin里。smrsh忽略用户指定的路径,并试图在它自己已知是安全的目录中找到要求执行的任何命令。smrsh还禁止使用某些shell元字符,比如“<”,即输入重定向符。在sm.bin中允许用符号链接,所以您不需要给允许使用的程序做副本 。

下面是一些shell命令的例子,以及smrsh给它们可能的解释:

 vacation  eric                      #  执行 /usr/adm/sm.bin/vacation  eric
cat  /etc/passwd                   #  被拒绝,在sm.bin里没有cat命令
vacation  eric  <  /etc/passwd  #  被拒绝,不允许有<
在电子邮件被一个aliases或者.forward文件重定向到一个文件的时候,sendmail的SafeFileEnvironment选项控制着可以把文件写到什么地方。它会让sendmail执行一次chroot系统调用,让文件系统的根不再是/而是/safe,或者您在SafeFileEnvironment选项中指定的任何路径。例如,把邮件重定向到/etc/passwd文件的别名实际上是写入了/safe/etc/passwd。

SafeFileEnvironment选项也能通过只允许写入普通文件的做法,保护设备文件、目录和其他的特殊文件。除了提高安全性之外,这个选项还有助于缓解用户犯错所造成的影响。有些站点把这个选项设为/home,在禁止进入系统文件的时候,能够访问用户的主目录。

邮寄程序(mailer)也可以进入被chroot过的目录。目前必须在邮寄程序的定义中指定该选项,但它应该很快就能通过m4来配置了。


隐私选项

sendmail还具有隐私选项,可控制:

哪些外部人员可以由SMTP来测定您的站点;
您对SMTP连接的另一端主机有什么要求;
您的用户是否可以看到或者运行邮件队列。

表18.15列出了在撰写本书的时候隐私选项可能的值,关于当前的信息请参见软件发布中的doc/op/op.ps文件。

我们建议您保守一些,请把:

 define(‘confPRIVACY_OPTIONS', “goaway,  authwarnings,  restrictmailq,
restrictqrun")
用在.mc文件中。sendmail隐私选项所用的默认值是authwarnings,上面这一行将重置该值。请注意有两组引号,某些版本的m4需要用它们把隐私选项值列表中的逗号括起来。Red Hat和Fedora默认选authwarnings,而SUSE、Debian和Ubuntu默认选authwarnings,needmailhelo、novrfy、noexpn和noverb。

表18.15 PrivacyOption变量的值

含    义

Public

不作隐私/安全检查

Needmailhelo

要求有SMTP HELO(识别远程主机)

Noexpn

不允许SMTP EXPN命令

Novrfy

不允许SMTP VRFY命令

Needexpnhelo

不扩展没有HELO的地址(EXPN)

Needvrfyhelo

不验证没有HELO的地址(VRFY)

noverba

不允许EXPN使用详细(verbose)模式

Restrictmailq

只允许mqueue目录的属组看到队列

Restrictqrun

只允许mqueue目录的属主运行队列

Restrictexpand

-bv-v标志限制显示的信息b

noetrnc

不运行异步方式运行排队操作

Authwarnings

添加Authentication-Warning(身份验证警告)信头(这是默认值)

Noreceipts

关闭成功回执的DSN(delivery status notification,投递状态通知)

Nobodyreturn

不在DSN中返回消息主体

Goaway

禁止所有的SMTP状态查询(EXPN、VRFY等)

a.在发出EXPN命令的时候,详细模式会根据.forward文件,提供有关用户邮件行踪的更多信息。在任何向外界暴露的机器上,应使用noverb,当然noexpn更好。
b.除非由root或者TrustedUser执行。
c.ETRN是一条ESMTP命令,它是专为拨号主机的使用而设计的。它要求只对到该主机的消息运行排队操作。


运行chroot后的sendmail

如果您担心sendmail会访问您的文件系统,那么可以在由chroot建成的“监管环境(jail)”中启动它。在监管环境中构造一个最小的文件系统,包括/dev/null、/etc的要素(passwd、group、resolv.conf、sendmail.cf、所有映射文件、mail/*)、sendmail需要的共享库、sendmail二进制文件、邮件队列目录、以及所有日志文件。您可能不得不手忙脚乱半天才能彻底解决问题。使用chroot命令启动一个受监控的sendmail。例如:

 #  chroot  /jail  /usr/sbin/sendmail  -bd  -q30m


拒绝服务攻击

要防止拒绝服务攻击(denial of service,DoS)是很困难的,因为没有一种方法可以预先知道一则消息是一个攻击还是一份有效的电子邮件。攻击者可以尝试各种卑鄙的招数,包括用假连接淹没SMTP端口,用巨大的消息填满磁盘分区,阻塞向外的连接,以及邮件炸弹。sendmail有一些配置参数可以帮助减慢或限制一次拒绝服务攻击的冲击,但是这些参数也会妨碍合法的邮件传输。邮件过滤库(milter)可能会帮助系统管理员对抗一次长时间的拒绝服务攻击。

MaxDaemonChildren选项可以限制sendmail进程的数目。它能防止系统被sendmail的任务压跨,但也让攻击者能够非常容易地关闭SMTP服务。MaxMessageSize选项有助于防止邮件队列目录被填满,但如果把它设置得太小,合法邮件将被弹回(您可以向用户说明这项限制,这样当邮件被弹回时他们就不会感到惊讶。无论如何我们建议把限制设得高一些,因为一些合法的邮件也很大)。ConnectionRateThrottle选项限制的是每秒钟内允许的连接数目,它可以大大减缓, 连接速度。最后,可以设置MaxRcptsPerMessage,它控制一则消息中允许收件人的最大数目,这可能会有所帮助。

sendmail一直能够根据系统的平均负载来拒绝链接(REFUSE_LA选项)或者把电子邮件排入队列(QUEUE_LA选项)。在8.12版的sendmail引入了一种变化(DELAY_LA选项),它能让邮件继续流动,但是速度却被降低了。参考18.12.3节关于性能的详细说明。

尽管这一切都致力于保护您的邮件系统,但用邮件轰炸您的人还是会妨碍合法的邮件传输。邮件炸弹是相当卑鄙的。

科罗拉多大学为每个学生(大约有25000人)提供了一个电子邮件账户,pine是默认的邮件阅读器。几年前,一位学生在本地的计算机商店获得了一份新工作,他的雇主说服他提供口令文件的一个副本。然后这家公司给口令文件中的每个人都发送了一则广告,大约分成每次1000个收件人(这使得To: 行非常长)这样来发。

pine是把默认的回复模式设置为对所有的收件人和发件人作出答复来编译的。许多学生用这样的问题来做答复:“为什么您给我发送这封垃圾?”。当然这样的信发给了To: 行中的其他所有人。结果是服务器拒绝所有服务?无论是电子邮件还是任何其他使用。sendmail接管了所有的CPU计算周期,邮件队列庞大无比,所有正在进行的工作都被暂停。唯一的解决方案是让这台机器下线,进入每个用户的邮件缓冲区,并删除讨厌的消息(也已经用了对标题[Subject]行进行信头检查的方法)。


伪造

伪造电子邮件在过去是小事一桩。在8.10以前,任何用户都可以伪造邮件,使得它看上去就像出自您所在的域。从sendmail 8.10开始包含SMTP身份验证,可以验证发送方机器的身份。必须用AuthMechanisms选项打开身份检查功能。遗憾的是,sendmail的身份验证功能不是端到端的,而只是在相邻的服务器之间。如果一则消息是由几台服务器处理的,那么虽然身份验证有帮助,但却不能保证不会出现伪造的消息。

类似地,在邮件消息中模仿任何用户也同样是可能的。如果邮件消息是您所在单位用于钥匙、访问卡和金钱等事情的权威传达媒介,那就要小心了。您应该用这一事实警告负责管理的用户,并建议如果他们见到的可疑邮件似乎出自某个权威人士,就应该验证该消息的有效性。如果这则消息要求把不合理的特权授予某个不寻常的人,就更要加倍小心了。如果邮件把重要的钥匙给了一个尚未毕业的大学生,这就很可疑!

authwarnings隐私选项可以标记出本地的伪造企图,它给看上去像是伪造的发出邮件添加一个Authentication-Warning信头。不过,许多用户代理程序在默认情况下会隐藏这个信头。

如果伪造的邮件出自您所控制的机器,那么您完全可以做点儿工作来阻止它。可以使用identd守护进程验证发件人的真实登录名。sendmail回叫发送的主机,要求在那台主机上运行的identd查找那个发送邮件的用户的登录名。如果远程主机上没有运行identd,sendmail将一无所获。如果远程机器是一台单用户的工作站,其拥有者就可以把identd配置成返回虚假的回答。但是如果远程主机是一台多用户机器,比如许多大学的计算中心建立的那种机器,identd就会返回该用户的真实登录名,以便sendmail把它插入到消息的信头中。

许多站点不会运行identd,它也常常被防火墙所阻挡。identd只在网点内部才真正有用,因为在您控制之外的机器可以说谎。在有某些不负责任的用户的大型网点(例如,某所大学)上,这种方法效果非常好?但是也会降低sendmail的性能。

几年前,当我们第一次试用identd时,我们站点上的一个学生对他所在高级项目组的成员感到灰心失望。他企图扮成自己的指导教师给他的队友发邮件,告诉他们他知道他们没有尽心尽力,应该工作得更卖力些。很遗憾,他犯了个语法错误,这则消息被弹回给了指导教师。sendmail使用的IDENT协议告诉了我们他是谁。sendmail在弹回的消息中包含如下几行:

 The original message was received  at  Wed,  9  Mar  1994  14:51  -0700  from
student@benji.Colorado.EDU  [128.138.126.10]
但是消息信头本身却说的另一番故事:
From:  instructor@cs.Colorado.EDU
教训:在偷偷摸摸干坏事时要避免语法错误。根据我们针对伪造邮件的政策,这个学生的登录名在那个学期的余下时间中被禁用,这刚好满足了他的愿望。他不能继续干那个项目了,他的伙伴们不得不打起精神好好工作。


消息的隐私

除非您使用外部加密软件包,比如PGP(Pretty Good Privacy)或者S/MIME,否则基本上是保证不了消息隐私的。默认情况下,所有邮件在发送时都不加密。端到端的加密要求得到邮件用户代理的支持才行。有关PGP的更多信息请参见20.11.2节。

S/MIMI和PGP都是在RFC的系列文档中说明的,S/MIME则处于标准系列。不过,我们更偏向PGP,它的使用范围更广,而且是由一位优秀的密码学专家Phil Zimmermann设计的,我们都信任他。这些行将出现的标准为邮件的机密性、身份验证、保证消息的完整性、以及发件来源的认可方面提供了一个基础。因为信头和信封仍然是以明文来发送的,所以还可以进行流量分析。

告诉您的用户,如果他们想要让自己的邮件保密,就必须自行加密。


SASL:简单的身份验证和安全层

sendmail 8.10和后继版本都支持RFC2554中定义的SMTP身份验证。它基于SASL(Simple Authentication and Security Layer,简单的身份验证和加密协议层)。SASL是一种共享秘密的系统,一般用于主机对主机的验证,您必须在彼此互相要验证对方身份的每一对服务器上明确地进行配置。

SASL是一种通用的身份验证机制,可以集成到各种协议中去。sendmail、Cyrus的imapd、Netscape、Outlook、Thunderbird和Eudora的某些版本都可以用它。SASL框架(它是一个库)有两个基本概念:一个授权标识符和一个身份验证标识符。它可以把这些标识符映射到文件权限、账号口令、Kerberos tickets等上面。SASL同时包含身份验证组件和加密组件。要配合sendmail使用SASL的话,可以从asg.web.cmu.edu/sasl获得Cyrus SASL。

TLS是在RFC2487中制定的另一种加密/验证系统。它在sendmail中是作为一种对SMTP的扩展来实现的,这叫做STARTTLS。甚至您可以SASL和TLS两者都用。

TLS设置起来要稍微困难的一点儿,它要求有证书服务。您可以向VeriSign支付一大笔钱来发布您自己的证书(标识一个实体的签名公钥),或者建立一个您自己的证书服务。它用更强的验证手段代替了主机名或者IP地址,作为授权中转邮件主机或者接受主机链接的标记。在access_db中像下面这样的配置项:

TLS_Srv:secure.example.com    ENCR:112
TLS_Clt:laptop.example.com    PERM+VERIFY:112

指出要使用STARTTLS,发送到secure.example.com这个域的邮件都必须用至少112位的密钥进行加密。从laptop.example.com这个域内的主机发来的邮件只有客户机本身通过身份验证才能接受。

Sendmail,Inc.公司的另一位员工Gregory Shapiro编写了一些有关安全和sendmail的教程,它们很不错,从www.sendmail.org/~gshapiro可以得到它们。


推荐阅读
  • 2012年7月30日,语言岛团队宣布其智能记单词软件V0.3.4.554版本正式开源。该版本不仅支持跨平台使用,还引入了多项创新功能,旨在帮助用户更高效地记忆单词。 ... [详细]
  • 在编译BSP包过程中,遇到了一个与 'gets' 函数相关的编译错误。该问题通常发生在较新的编译环境中,由于 'gets' 函数已被弃用并视为安全漏洞。本文将详细介绍如何通过修改源代码和配置文件来解决这一问题。 ... [详细]
  • 本文详细介绍了如何在Ubuntu的Enlightenment (E17) 桌面环境中管理和优化桌面图标及根菜单。通过本文,您将了解这些功能的作用及其配置方法。 ... [详细]
  • 本文详细介绍了 Linux 系统中用户、组和文件权限的设置方法,包括基本权限(读、写、执行)、特殊权限(SUID、SGID、Sticky Bit)以及相关配置文件的使用。 ... [详细]
  • 本文介绍了如何在 Ubuntu 18.10 Cosmic 停止官方支持后,通过更换软件源来解决 `apt update` 失败的问题。 ... [详细]
  • 本文探讨了为何相同的HTTP请求在两台不同操作系统(Windows与Ubuntu)的机器上会分别返回200 OK和429 Too Many Requests的状态码。我们将分析代码、环境差异及可能的影响因素。 ... [详细]
  • 版本控制工具——Git常用操作(下)
    本文由云+社区发表作者:工程师小熊摘要:上一集我们一起入门学习了git的基本概念和git常用的操作,包括提交和同步代码、使用分支、出现代码冲突的解决办法、紧急保存现场和恢复 ... [详细]
  • 精选多款高效实用软件及工具推荐
    本文介绍并推荐多款高效实用的软件和工具,涵盖系统优化、网络加速、多媒体处理等多个领域,并提供安全可靠的下载途径。 ... [详细]
  • 创邻科技成功举办Graph+X生态合作伙伴大会,30余家行业领军企业共聚杭州
    9月22日,创邻科技在杭州举办“Graph+X”生态合作伙伴大会,汇聚了超过30家行业头部企业的50多位企业家和技术领袖,共同探讨图技术的前沿应用与发展前景。 ... [详细]
  • Java多重继承的替代方案及设计考量
    本文探讨了Java为何不支持多重继承,并深入分析了其背后的原理和替代方案。通过理解Java的设计哲学,开发者可以更好地利用接口和其他特性来实现复杂的类结构。 ... [详细]
  • 本文深入探讨了UNIX/Linux系统中的进程间通信(IPC)机制,包括消息传递、同步和共享内存等。详细介绍了管道(Pipe)、有名管道(FIFO)、Posix和System V消息队列、互斥锁与条件变量、读写锁、信号量以及共享内存的使用方法和应用场景。 ... [详细]
  • 本文深入探讨了 Delphi 中类对象成员的核心概念,包括 System 单元的基础知识、TObject 类的定义及其方法、TClass 的作用以及对象的消息处理机制。文章不仅解释了这些概念的基本原理,还提供了丰富的补充和专业解答,帮助读者全面理解 Delphi 的面向对象编程。 ... [详细]
  • 本文详细探讨了Java命令行参数的概念、使用方法及在实际编程中的应用,包括如何通过命令行传递参数给Java程序,以及如何在Java程序中解析这些参数。 ... [详细]
  • 在使用 iOS 应用时,遇到网络请求错误是常见的问题。本文将探讨两种常见的错误代码 -1003 和 -1001,并提供详细的解释和解决方案。 ... [详细]
  • 部署新的ASP.NET Web应用程序构建(主要涉及DLL文件更改)后,服务器上的CPU使用率每几秒就会飙升至100%,问题似乎源自lsass.exe进程。这一现象与应用程序部署之间是否存在直接关联? ... [详细]
author-avatar
mobiledu2502925687
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有