sendmail

更新时间:2024-02-21 16:03

sendmail,计算机用语,是一种最重要的邮件传输代理程序。

简介

人们在互联网上最常使用的就是电子邮件,很多企业用户也经常使用免费电子邮件系统。本文就以step by step的方式引导用户从sendmail源代码开始构建一个可以满足基本工作需要的邮件系统

程序介绍

sendmail是最重要的邮件传输代理程序。理解电子邮件的工作模式是非常重要的。一般情况下,我们把电子邮件程序分解成用户代理,传输代理和投递代理。用户代理用来接受用户的指令,将用户的信件传送至信件传输代理,如:outlook expressfoxmail等。而投递代理则从信件传输代理取得信件传送至最终用户的邮箱,如:procmail。

当用户试图发送一封电子邮件的时候,他并不能直接将信件发送到对方的机器上,用户代理必须试图去寻找一个信件传输代理,把邮件提交给它。信件传输代理得到了邮件后,首先将它保存在自身的缓冲队列中,然后,根据邮件的目标地址,信件传输代理程序将找到应该对这个目标地址负责的邮件传输代理服务器, 并且通过网络将邮件传送给它。对方的服务器接收到邮件之后,将其缓冲存储在本地,直到电子邮件的接收者查看自己的电子信箱。

显然,邮件传输是从服务器到服务器的,而且每个用户必须拥有服务器上存储信息的空间(称为信箱)才能接受邮件(发送邮件不受这个限制)。可以看到,一个邮件传输代理的主要工作是监视用户代理的请求,根据电子邮件的目标地址找出对应的邮件服务器,将信件在服务器之间传输并且将接收到的邮件缓冲或者 提交给最终投递程序。有许多的程序可以作为信件传输代理,但是sendmail是其中最重要的一个,事实证明它可以支持数千甚至更多的用户,而且占用的系统资源相当少。不过,sendmail的配置十分复杂,因此,也有人使用另外的一些工具,如qmail、postfix等等。

当sendmail程序得到一封待发送的邮件的时候,它需要根据目标地址确定将信件投递给对应的服务器,这是通过DNS服务实现的。例如一封邮件的目标地址是ideal@linuxaid.com.cn,那么sendmail首先确定这个地址是用户名(ideal)+机器名(linuxaid.com.cn)的格式,然后,通过查询DNS来确定需要把信件投递给某个服务器。

DNS数据中,与电子邮件相关的是MX记录,例如在linuxaid.com.cn这个域的DNS数据文件中有如下设置:

IN MX 10 mail

IN MX 20 mail1

mail IN A 202.99.11.120

mail1 IN A 202.99.11.121

显然,在DNS中说明linuxaid.com.cn有两个信件交换(MX)服务器,于是,sendmail试图将邮件发送给两者之一。一般来说,排在前面的的MX服务器的优先级别比较高,因此服务 器将试图连接mail.linuxaid.com.cn的25端口,试图将信件报文转发给它。如果成功,你的smtp服务器的任务就完成了,在这以后的任务,将由mail.linuxaid.com.cn来完成。在一般的情况下,mail换器会自动把信件内容转交给目标主机,不过,也存在这样的情况,目标主机(比如linuxaid.com.cn)可能并不存在,或者不执行smtp服务,而是由其mx交换器来执行信件的管理,这时候,最终的信件将保存在mx机器上,直到用户来察看它。

如果DNS查询无法找出对某个地址的MX记录(通常因为对方没有信件交换主机),那么sendmail将是试图直接与来自邮件地址的主机对话并且发送邮件。例如,test@aidgroup.linuxaid.com.cnDNS中没有对应的MX记录,因此sendmail在确定MX交换器失败后,将从DNS取得对方的IP地址并直接和对方对话试图发送邮件。

工作环境

假设用户希望在园区网环境中架设一个电子邮件服务器,为本单位用户提供邮件服务。该服务器拥有一个合法的IP地址202.99.11.200和一个合法的域名mail.linuxaid.com.cn,并且DNS的MX记录也指向该域名(注:这里示例域名和IP地址均为伪造域名和地址)。为了满足域名需求,DNS的域数据文件应该包含以下内容:

IN MX 10 mail

mail IN A 202.99.11.200

试验环境为:redhat6.2、sendmail.8.11.4、qpopper4.0.3。

安装

Sendmail是目前使用最为广泛的一种E-mail服务器。当前其最新的稳定版本为8.14.3。下载得到tar.gz格式的压缩包以后,将其存放在/usr/src目录下。我们以8.11.4为例。

解压软件包:

[root@email src]# tar xvfz sendmail.8.11.4.tar.gz

[root@email src]# cd sendmail-8.11.4

编译安装:

[root@email sendmail-8.11.4]# cd sendmail

[root@email sendmail]# sh Build

生成配置文件:

[root@email sendmail]#cd /usr/src/sendmail-8.11.4/cf/cf/

一般该目录下应该有config.mc的文件,如果没有则创建新文件config.mc,内容为:

divert(-1)

dnl This is the macro config file used to generate the /etc/sendmail.cf

dnl file. If you modify thei file you will have to regenerate the

dnl /etc/sendmail.cf by running this macro config through the m4

dnl preprocessor:

dnl m4 /etc/sendmail.mc > /etc/sendmail.cf

dnl You will need to have the Sendmail-cf package installed for this to work.

include(`/usr/src/sendmail-8.11.4/cf')

define(`confDEF_USER_ID',`8:12')

OSTYPE(`linux')

undefine(`UUCP_RELAY')

undefine(`BITNET_RELAY')

define(`confAUTO_REBUILD')

define(`confTO_CONNECT', `1m')

define(`confTRY_NULL_MX_LIST',true)

define(`confDONT_PROBE_INTERFACES',true)

define(`PROCMAIL_MAILER_PATH',`/usr/bin/procmail')

FEATURE(`smrsh',`/usr/sbin/smrsh')

FEATURE(`mailertable',`hash -o /etc/mail/mailertable')

FEATURE(`virtusertable',`hash -o /etc/mail/virtusertable')

FEATURE(redirect)

FEATURE(always_add_domain)

FEATURE(use_cw_file)

FEATURE(local_procmail)

MAILER(smtp)

MAILER(procmail)

FEATURE(`access_db')

FEATURE(`blacklist_recipients')

dnl We strongly recommend to comment this one out if you want to protect

dnl yourself from spam. However, the laptop and users on computers that do

dnl not hav 24x7 DNS do need this.

FEATURE(`accept_unresolvable_domains')

dnl FEATURE(`relay_based_on_MX')

然后运行:

[root@email cf]# sh Build config.cf

该命令将在该目录下生成config.cf文件。然后安装sendmail:

[root@email sendmail]# sh Build install

将config.cf拷贝到/etc/mail目录下,并改名为sendmail.cf:

[root@email mail]#cp /usr/src/sendmail-8.11.4/cf/cf/config.cf /etc/mail/sendmail.cf

在/etc/mail目录下创建access文件,内容如下:

127.0.0.1RELAY

202.99.11 RELAY

这里表示允许本机和202.99.11.0网段中的机器通过该邮件服务器的转发邮件。其中202.99.11应该是你拥有的局域网络IP网段的IP地址,只需要写网络部分即可。比如说你的用户有多个网段,只需要在其中设置多个网段即可:

127.0.0.1RELAY

202.99.11 RELAY

200.200.201 RELAY

然后对access文件生成易于检索的库文件格式:

[root@email mail]# makemap hash access.db < access

创建文件/etc/mail/local-host-names,其内容为本机的拥有的域名信息,因为在上面的DNS配置文件中该服务器有一个域名:email.linuxaid.com.cn,并且MX记录也指向该域名,因此该服务器就有两个域名,一个为email.linuxaid.com.cn及linuxaid.com.cn,这样用户才可以使用someone@linuxaid.com.cn.这样的地址收发邮件,故该文件应该包含如下内容:

linuxaid.com.cn.

mail.linuxaid.com.cn.

最后还要创建别名数据库。在/etc/mail/aliases目录下创建文件aliases,内容如下:

MAILER-DAEMON: postmaster

postmaster: root

bin: root

daemon: root

nobody: root

然后生成aliases库:

[root@email mail]# newaliases

然后,就可以启动Sendmail了:

[root@email mail]# /usr/sbin/sendmail -bd -q20m

在第一次启动时可能出现如下的错误信息:

不要紧张,只需要使用vi编辑器将这些行删除即可,其实41、60等行都是空白行而已。删除以后再重新启动就应该没有问题了。

安装配置

qpopper是Unix/Linux环境下的pop3服务器,该软件配合sendmail使用。其主要是实现支持用户通过pop3接收信件。

创建从/usr/mail指向/var/spool/mail/的链接:

[root@email src]# ln -s /var/spool/mail/ /usr/mail

解压qpopper软件包:

[root@email src]# tar xvfz qpopper4.0.3.tar.gz

[root@email src]# cd qpopper4.0.3

编译安装qpopper:

[root@email qpopper4.0.3]# ./configure

[root@email qpopper4.0.3]# make

[root@email qpopper4.0.3]# make install

安装成功以后,qpopper将会被安装在目录/usr/local/sbin/目录下。设置inetd启动qpopper。编辑/etc/inetd.conf,查找pop内容的一行,在其前面添加#号,然后在改行后面添加如下内容:

pop-3 stream tcp nowait root /usr/local/sbin/popperqpopper-s

然后查找inetd进程ID号:

[root@email qpopper4.0.3]# ps ax|grep inetd

336 ? S 0:00 inetd

16872 pts/0 S 0:00 grep inetd

找到inetd进程号为226。然后重新启动inetd进程,重新读取配置文件:

[root@www qpopper4.0.3]# kill -HUP 336

这时候查看系统服务端口号:

[root@email qpopper4.0.3]# netstat -ln|grep 110

tcp 0 0 0.0.0.0:110 0.0.0.0:* LISTEN

则说明110端口已经开始正常服务。

安装测试

实现对IMAP的支持非常简单,只需要安装IMAP软件包的RPM包:

[root@email RPM]# rpm -ivhimap-4.7-5.i386.rpm (这里是在6.2环境下,如果在7.x环境下需要安装更高版本的imap)

然后确保/etc/inetd.conf文件中imap所在行如下所示:

imapstream tcp nowait root /usr/sbin/tcpd imapd

然后重新启动inetd以更新配置:

[root@email /]# kill -HUP 379 (这里379是inetd的进程号)

然后查看imap是否成功启动:

[root@email /]# netstat -ln|grep 143

注:(对于6.2版本的imap-4.7来说 支持imap2,所以是143端口。RH7.x的imap-2000会支持imap3,因此可能还会监听220端口)

这时候就可以在outlook express中添加账号进行测试了。

测试

接下来是测试邮件服务器的邮件发送/接收功能,注意:测试时,不要在只对本地用户进行测试,如:你的域为abc.com,测试时,不要只在邮件服务器上通过mail、elm等程序测试user1@abc.com用户。因为,此时user1是本地用户,所以邮件服务器可以对其进行Relay。你应该从局域网上的另一台机器使用Outlook等邮件客户端对服务器进行收发测试。

这种配置对于IP固定用户没有问题,只需要在access文件中指定其固定IP即可,而对于需要支持流动用户,如拨号用户的应用则不大适合,因为如果完全打开RELAY功能可能导致邮件服务器的称为垃圾邮件的转发站。

解决用户IP不固定问题有两种方案,一种为采用SMTP认证,即用户发送邮件以前,邮件服务器进行用户身份认证,通过则服务器为其发送邮件,否则拒绝发信;第二种方案是采用动态转发授权控制(Dynamic Relay authorization control),其工作原理为:拨号用户拨号上网后,首先收邮件,如果用户能正确收邮件,则DRAC自动在access.db中加入刚才收邮件用户的IP,并允许此IP可以发信。不过,30分钟内,此IP不发/收邮件的话,DRAC将从access.db中删除此IP。此种机制保证拨号用户在没有SMTP认证的情况下,也可以通过远程邮件服务器发送E-mail。 这些技术将在以后的文章内讨论。

使用技巧

1、为什么不能配置邮件服务器为open relay的?

如果系统管理员将自己的邮件服务器设置为open relay,将会导致一些垃圾邮件发送者将你的邮件服务器作为转发垃圾邮件的中继站,这将使垃圾邮件的接收者将矛头对准你,可能会导致报复性的邮件炸弹;垃圾邮件还能消耗你大量的资源,占用你的带宽。更为糟糕的事情可能是你的名字可能会上了黑名单,成为其他邮件接收者共同抵制的目标,你的邮件将被这些接收者所拒绝。

2、什么是邮件转发(mail relay)

设置好一个email服务器以后,该服务器将具有一个或若干个域名,这时email服务器将监听25号端口,等待远程的发送邮件的请求。网络上其他的mail服务器或者请求发送邮件的MUA(Mail User Agent,如outlook expressfoxmail等等)会连接email服务器的25号端口,请求发送邮件,SMTP会话过程一般是从远程标识自己的身份开始,过程如下:

HELO remote.system.domainname

250 qmailserver.domain

MAIL FROM:user@somewherer.net

250 OK

RCPT TO: user1@elsewhere.net

邮件的接收者user1@elsewhere.net中的域名并不一定是本地域名,这时候本地系统可能有两种回答,接受它:

250 OK

或者拒绝接受它:

553 sorry,.that domain isnot in my domain list of allowed recphosts

第一种情况下,本地email服务器是允许relay的,它接收并同意传递一个目的地址不属于本地域名的邮件;而第二种情况则不接收非本地邮件。

email一般都有一个配置文件,其决定了是否接受一个邮件。只有当一个RCPT TO命令中的接收者地址的域名存在于该文件中时,才接受该邮件,否则就拒绝该邮件。若该文件不存在,则所有的邮件将被接受。当一个邮件服务器不管邮件接收者和邮件接收者是谁,而是对所有邮件进行转发(relay),则该邮件服务器就被称为开放转发(open relay)的。当email服务器没有设置转发限制时,其是开放转发的。

3、sendmail如何限制邮件转发

因为Send Mail 为了怕变成广告信转信站所以安装后只线本机上的使用者寄信,要让它为你转信需要修改一点东西。 修改 /etc/mail/access 档案在里面增加下面几行。

localhost RELAY

192.168.1 RELAY

就可以将 192.168.1 网域里的信转出去了。

安全环境

sendmail是在Unix环境下使用最广泛的实现邮件发送/接受的邮件传输代理程序。 由于sendmail邮件服务器的特点是功能强大而复杂,因此为保证Sendmail的安全性,需要作以下一些工作。

第一步:

决定smrsh可以允许sendmail运行的命令列表。缺省情况下应当包含以下命令,但不局限于这些命令:

注意:不可在命令列表里包括命令解释程序,例如sh(1),csh(1),perl(1),uudecode(1)及流编辑器sed(1)。

第二步:

[root@deep]# cd /etc/smrsh

[root@deep]# ln -s /bin/mail mail

[root@deep]# cd /etc/smrsh

[root@deep]# ln -s /usr/bin/procmail procmail

第三步

例如:

Mprog, P=/bin/sh, F=lsDFMoqeu9, S=10/30, R=20/40, D=:/, T=X-Unix, A=sh -c

应该被改为:

Mprog, P=/usr/sbin/smrsh, F=lsDFMoqeu9, S=10/30, R=20/40, D=:/, T=X-Unix, A=sh -c

当前用以下命令手工重起sendmail进程:

[root@deep]# /etc/rc.d/init.d/sendmail restart

/etc/aliases

[root@deep]# /usr/bin/newaliases

编辑别名文件(vi /etc/aliases)并删除以下各行:

# Basic system aliases -- these MUST be present.

MAILER-DAEMON: postmaster

postmaster: root

# General redirections for pseudo accounts.

bin: root

daemon: root

games: root?? 删除这一行

ingres: root ?? 删除这一行

nobody: root

system: root ?? 删除这一行

toor: root?? 删除这一行

uucp: root ?? 删除这一行

# Well-known aliases.

manager: root ?? 删除这一行

dumper: root ?? 删除这一行

operator: root ?? 删除这一行

# trap decode to catch security attacks

decode: root ?? 删除这一行

# Person who should get root's mail

#root: marc

3、避免你的Sendmail被未授权的用户滥用

最新版本的Sendmail (8.9.3)加入了很强的防止欺骗的特性。它们可以防止你的邮件服务器

O PrivacyOptions=authwarnings

改为:

O PrivacyOptions=authwarnings,noexpn,novrfy

4、SMTP的问候信息

当 sendmail接受一个SMTP连接的时候,它会向那台机器发送一个问候信息,这些信息作为本台主机的标识,而且它所做的第一件事就是告诉对方它已经准备好了。

O SmtpGreetingMessage= Sendmail /;

改为:

O SmtpGreetingMessage= Sendmail /; NO UCE C=xx L=xx

如今手工重起一下sendmail进程,使刚才所做的更改生效:

[root@deep]# /etc/rc.d/init.d/sendmail restart

5、限制可以审核邮件队列内容的人员

O PrivacyOptions=authwarnings,noexpn,novrfy

改为:

O PrivacyOptions=authwarnings,noexpn,novrfy,restrictmailq

如今我们更改邮件队列目录的权限使它被完全保护起来:

[root@deep]# chmod 0700 /var/spool/mqueue

任何一个没有特权的用户如果试图查看邮件队列的内容会收到下面的信息:

$ /usr/bin/mailq

You are not permitted to see the queue

O PrivacyOptions=authwarnings,noexpn,novrfy,restrictmailq

改为:

O PrivacyOptions=authwarnings,noexpn,novrfy,restrictmailq,restrictqrun

任何一个没有特权的用户如果试图处理邮件队列的内容会收到下面的信息:

$ /usr/sbin/sendmail -q

You do not have permission to process the queue

7、在重要的sendmail文件上设置不可更改位

chattr

[root@deep]#chattr+i /etc/sendmail.cf

[root@deep]#chattr+i /etc/sendmail.cw

[root@deep]#chattr+i /etc/sendmail.mc

[root@deep]# chattr +i /etc/null.mc

其他方法

如果您是使用 Red Hat 7.3 以前的版本,例如 Red Hat 7.1, 7.2, 7.3 ,或者是 Open Linux Server 3.1.1 的话,那么请先确定一下底下的套件是否已经安装上去了呢?

[root@test root]# rpm -qa | grep sendmail

sendmail-cf-8.11.6-3

sendmail-8.11.6-3

# 若有属性相依的问题时,请将您的原版安装光盘拿出来, mount 上去后,

# 仔细的,一个一个的将相依的套件安装上去啰! ^_^

[root@test root]# rpm -qa | grep m4

m4-1.4.1-5

[root@test root]# rpm -q mailx

mailx-8.1.1-22

那个sendmail 就是主要的邮件服务器程序,sendmail-cf 是一些设定档案,这两个套件是『一定』要安装的!至于那个 m4 的套件,则是转换 sendmail 设定文件的一支程序啰!也要安装喔!而那个mailx 就是提供最简单的mail 这支寄信与收信的套件啦!由于我的测试系统是 Red Hat 7.2 ,所以使用的算是比较旧一点点的 sendmail 8.11.6 版,如果您想要换装新版的 sendmail 8.12.xx 的话,

疑难解答

1、sendmail如何设置虚拟域?

如同Apache一样,sendmail也允许使用虚拟主机功能,这是通过在mc文件中FEATURE(virtusertable)功能实现的,而虚拟主机的文件缺省是/etc/mail/virtusertable.db,它用/etc/mail/virtusertable文件生成,这个文件的形式类似于aliases文件,即左地址 右地址,中间用Tab键分开。例如:

someone@linuxaid.net.cn localuser

这样一行意味着本来应该发送给someone@otherdomain.com的邮件如今要发送给本机的用户localuser。当然,这意味着:第一,你的DNS记录中,本机应该是otherdomain.com的MX交换器;第二,你的本机sendmail.cw文件或local-host-names应该包含otherdomain.com这个名字。

当然纯粹的这样的域意义不大,但是sendmail还支持邮件虚拟域的参数翻译。例如:

@testdomain.com test@linuxaid.com.cn

意味着所有发往xxx@testdomain的邮件都会被发送到test@linuxaid.com.cn。而

@testdomain.com %1test@linuxaid.com.cn

则代表参数转义,例如user1@testdomain.com的邮件被发送到user1test@linuxaid.com.cn,

user2@testdomain.com被发送到user2test@linuxaid.com.cn。同样,这样的功能也要通过MX记录和CW文件加上去。

建立virtusertable的方法与建立access的办法是一样的:

makemap hash virtusertable.db < virtusertable

然后重新启动sendmail。

2、如何设定用户别名?

用户的别名是由文件/etc/mail/aliases来设定的。最简单的情况是需要作信件分发的情况。例如,一般情况下,电子邮件出现问题的时候,我们需要把出错的邮件头发送到本机的postmaster用户,但是也许你的系统上有多个系统管理员,因此每个人都需要得到一份这个邮件头的拷贝。这种情况下就需要使用用户别名文件了。

aliases文件的格式是 邮件别名:实际用户名,如果一个别名有多个用户就用逗号分开,每个别名一行。例如,要把发给postmaster的信件发送给supervisor和manager,需要写上这样一行:

postmaster:supervisor,manager

别名还可以用在这样的情况,即定义自动的邮件转发。例如,某个用户以前在你的系统上接受电子邮件,如今他有了一个新的电子邮件,希望发到你的机器上的邮件自动被转发到他新的电子邮件地址上,那么,可以使用类似这样的别名方式:(假设你的机器是joe@linuxaid.com.cn)

joe:joe@xxxxx.com

以后发给joe@linuxaid.com.cn的电子邮件就自动中转到joe@newaddr.com。注意左边自动加上你的机器名字,所以左边只能是账号名字,不能是全限定邮件地址。

另一个常用的办法是重定向。如果你在模板文件中定义了REDIRECT特性,那么可以使用这个功能。例如,某个人在你的机器上开了一个账户user1,后来迁移到user2@server2.com。那么,你可以将其别名写成

user1: user2@server2.com.REDIRECT

以后当有人向这个地址发信的时候,你的sendmail会将其退回,并且返回一个551 User not local; please try user2@server2.com的信息。

在使用别名的时候,必须注意的是不要造成循环,例如user1转发给user2,user2又将其转发给user1....如此循环。在这种情况下,转发17次后,sendmail将把它退还给发信人。最常见的错误发生在你试图在转发邮件的同时在本地保留备份的情况下,例如:

user1: user1,user2

就构成了一个循环。

要在本地保留备份,使用转义符号,例如

user1: user1,user2

建立了别名文件之后,需要将其初始化,这可以通过newaliases命令完成:

[root@mail mail]# newaliases

/etc/aliases: 17 aliases, longest 31 bytes, 241 bytes total

也可以使用sendmail -bi命令:

[root@mail mail]# sendmail -bi

/etc/aliases: 17 aliases, longest 31 bytes, 241 bytes total

两种方式实际是完全一样的。

类似于通过aliases文件进行邮件转发,用户也可以使用自己的转发文件,例如,某个用户user1想让发送给自己的邮件全部转发到xxxxx@xxxxxx.com,但是又不希望建立全局的用户别名,那么可以在自己的宿主目录下面建立一个.forward文件,内容只要一行:

xxxxxx@xxxxx.com

就可以了。 这种技术可以让每个用户自己管理自己的邮件别名。

免责声明
隐私政策
用户协议
目录 22
0{{catalogNumber[index]}}. {{item.title}}
{{item.title}}