在 UNIX/Linux 系统的自动化管理中,利用脚本自动发送邮件的功能对系统监控的工作来说是非常重要的。系统管理人员可以利用 cron 或者 RMC 来创建监控脚本,一旦触发条件被满足,操作系统就会自动创建电子邮件,将相关的状态信息发送到指定的邮箱。通过电子邮件系统,系统管理人员就能够及时得获取被管理系统的状态,进而采取相应的措施。这种方式可以显著地节省系统管理人员的工作强度,并能够提高系统的可维护性。
Unix/Linux 邮件系统组成简介
在传统的 UNIX 和 Linux 系统中,电子邮件系统的主要组成部分包括邮件用户代理 (MUA -- mail user agent)、邮件传输代理(MTA -- mail transfer agent)、邮件提交代理 (MSA -- mail submission agent)、邮件投递代理 (MDA -- mail delivery agent) 和邮件访问代理 (MAA -- mail access agent)。在日常工作中,系统管理人员经常接触的主要有邮件用户代理 (MUA) 和邮件传输代理 (MTA)。在 AIX 系统中,一个典型的邮件系统如图 1 所示。
邮件用户代理(MUA)是一个用来读写 mail 的程序,实际上就是邮件系统的客户端程序。它提供了阅读,发送和接受电子邮件的用户接口。最常用的邮件用户代理有 mutt,mail,elm,pine,它们都是随基本系统安装的 简单邮件应用程序。
邮件传输代理(MTA)是一个在两个主机之间或者本地同一主机内传送邮件的程序,它负责邮件的存储和转发,并决定传送邮件到目的地的路线。UNIX/Linux 系统的标准 MTA 是 sendmail,其他的 MTA 还有 qmail, exim 和微软的 Exchange。MTA 会监视用户代理的请求,根据电子邮件的目标地址找出对应的邮件服务器,在服务器之间传输邮件并将接收到的邮件进行缓冲。
邮件投递代理(MDA)通常被 MTA 用来投递邮件到接收者的邮箱中。它能够从 MTA 接收邮件,并根据指定的规则来进行本地投递;它可以把邮件投递到本地用户、邮件列表、文件或者应用程序。UNIX/Linux 系统中常用的 MDA 包括 maildrop、procmail、postfix 和 delivermail 等。Postfix 用一个或多个 MDA 来递送邮件 , procmail 是另外一个有名的 MDA.
邮件提交代理(MSA)负责消息发送之前的所有必须完成的准备工作和错误检测。MSA 就如同在 MUA 和 MTA 之间的一个头脑清醒的检测人员,它会对所有的主机名和从 MUA 得到的信息头等信息进行检测。
MAA 邮件访问代理(MAA)将用户连接到邮件系统,并通过 POP 或 IMAP 协议来收取邮件。UNIX/Linux 系统中,常用的 MAA 有 UW-IMAP、Cyrus-IMAP、COURIER-IMAP 等;当邮件向目的地址进行传输时,一旦源地址和目的地址都不是本地系统,那么本地系统就会作为邮件的中继。
对于大多数邮件用户来说,利用邮件客户端来接收、查看和发送电子邮件是最常用的功能。接收和查看邮件比较简单,但是电子邮件的发送则相对复杂。在下面的章节里面,本文将根据不同的操作系统来具体介绍如何配置邮件服务器。
发送邮件代理配置及自动化发送
Linux 的 sendmail 配置
配置文件
在 Linux 系统中,Sendmail 包括如下配置文件:
/etc/sendmail.cf
/etc/mail/access
/etc/mail/aliases
/etc/mail/local-host-names
/etc/mail/mailertable
/etc/mail/virtusertable
/etc/mail/domaintable
~/.forward
我们将会 在下面的章节中详细介绍这些配置文件。
/etc/sendmail.cf
/etc/sendmail.cf 是 sendmail 的主配置文件。该文件存储了正在运行的 mailer 程序的类型信息,定义了重写邮件地址的规则和 sendmail 命令的操作环境。因为 sendmail.cf 的语法比较复杂,我们一般不建议手动修改该配置文件。安装了 sendmail 的 UNIX/Linux 系统都会带有 sendmail.cf,而且该配置文件在大多数情况下都不需要修改就可以使用。如果用户确实需要修改 sendmail.cf 配置文件 , 一般建议用户基于 sendmail.mc 宏文件,利用 m4 程序来生成新的 sendmail.cf 文件。
在 RedHat Linux 系统中,sendmail.mc 宏文件位于 /etc/mail/ 目录。
而 SuSE Linux 系统并没有 sendmail.mc 文件,相应的,它提供了 /etc/mail/linux.mc ( 或者 /etc/mail/linux.nullclient.mc) 替代 sendmail.mc。/etc/mail/linux.mc 是 SuSEconfig 使用 /etc/rc.config 和 /etc/rc.config.d/sendmail.rc.config (SuSE <= 7.3) 或者 /etc/sysconfig/sendmail (SuSE >= 8.0) 的参数而生成的宏文件。SuSEconfig 执行 /sbin/conf.d/SuSEconfig.sendmail 脚本来构建 .mc 文件,并执行 m4 来生成 sendmail.cf 配置文件。用户可以依照清单 1 所示的 SuSEconfig.sendmail 命令来生成配置文件。
清单 1. 使用 SuSEconfig.sendmail 命令生成配置文件
/ sbin/conf.d/SuSEconfig.sendmail -m4 > sendmail.mc
在 sendmail.mc 配置文件中经常出现如下的 m4 命令:
define:
用于定义配置文件中变量的值
divert:
用于定向 m4 进程的输出。
divert 被设置为 -1 时 , 取消输出。如果 divert(-1) 在一个文本块的前面出现,这段文本将不会再 sendmail.cf 中出现 . divert 被设置为 0 时来定向数据流的输出,如 sendmail.cf,
VERSIONID:
配置文件定义版本控制信息。
dnl:
注释掉后面的所有字符。
dnl 出现在行尾,表示将清除掉不想要的空白行;dnl 出现在行首,表示这一行将被当成注释。
DOMAIN:
选择传输邮件的域。
FEATURE:
识别配置文件中一个特性 (Feature)。
MAILER:
识别包含在 sendmail.cf 一套邮件传输方法。
OSTYPE:
定义宏所使用的操作系统,它允许 m4 程序增加同相关操作系统相关的文件。
undefine:
清除配置文件中的变量值。
需要注意的是,m4 宏处理器生成的 sendmail.cf 文件必须放在 /etc/ 目录 , 而非 /etc/mail。具体的操作如清单 2 所示。
清单 2.m4 命令生成配置文件 sendmail.cf
cp /etc/sendmail.cf /etc/sendmail.cf.bak
m4 sendmail.mc > sendmail.cf
在用户修改完成 sendmail.cf 配置文件以后,最后一步操作是重新启动 sendmail 服务,具体的操作如清单 3 所示:
清单 3. 重启 sendmail 服务
service sendmail restart
/etc/mail/access 和 access.db
access 数据库是由 sendmail V8.9 版本引入的特性, 并在 V8.10 重得到很好的发展。它提供了一个单一集中管理的访问规则数据库;它可以基于发信者的姓名、地址或者 IP 来判断是否接受 (OK)、转发 (RELAY)、拒绝 (REJECT) 或者取消 (DISCARD)。sendmail 会在接收邮件时进行规则判断,默认情况下只接受本机发送的邮件。
对本地设置来说,/etc/mail/access 和 access.db 并不是必需的;只有在建立中央邮件集中服务器来处理所有邮件的时候才需要这两个文件。
access 数据库的配置主要有三个步骤,具体操作如下所示。
修改 /etc/mail/access 文件;修改后的内容如清单 4 所示。
清单 4./etc/mail/access 文件内容
localhost.localdomain RELAY
localhostRELAY
127.0.0.1RELAY
192.168.1RELAY
利用 /etc/mail/access 创建数据库映射文件 access.db,命令如清单 5 所示。
清单 5. 生成数据库映射文件 access.db
1
makemap hash /etc/mail/access.db < /etc/mail/access
重启 sendmail, 读取 access.db,具体的命令如清单 3 所示。
service sendmail restart
/etc/mail/aliases 和 aliases.db
aliases 是 sendmail 邮件系统的别名数据库。它可以定义邮递列表,在机器之间转发邮件,或者允许用多个名字指定一个用户。因为 Aliases 别名处理的规则是递归的,所以一个别名指向的目的地也可以是别名。对于每个信封,sendmail 都会在别名文件中查找本地用户的收件人名称。由于 Sendmail 的可能要在 aliases 文件中搜索数以千计的收件人名称,所以一个以 DB 数据库格式存储的 aliases 文件副本被创建,并用来提高查询的速度。
同样,这两个配置文件也不是必需的。如果 sendmail 是使用中央服务器的邮件处理中心处理所有邮件的话,安装在邻居服务器或客户机的 aliases 和 aliases.db 文件就不需要了。 aliases 数据库的配置主要有三个步骤,如下所示。
1.修改 /etc/mail/aliases。修改后的内容如清单 6 所示。
清单 6. 修改后的 aliases 文件
# Basic system aliases that MUST be present.
postmaster: root
mailer-daemon: postmaster
# amavis
virusalert: root
2.根据 /etc/mail/ aliases 来创建数据库映射文件 aliases.db,该命令如清单 7 所示。
清单 7. 创建数据库映射文件 aliases.db
makemap hash /etc/mail/aliases.db < /etc/mail/aliases
3.重启 sendmail,读取 aliases.db,具体的命令如清单 3 所示。
service sendmail restart
其他配置文件
除了上文中介绍的配置文件以外,sendmail 还使用了其他的一些配置文件,本节将逐一介绍这些配置文件。
/etc/mail/local-host-names
设置服务器提供服务的域名,即本地主机名的主机名列表。该文件被修改后,sendmail 必须重新启动来更新设置;
/etc/mail/virtusertable 和 virtusertable.db
virtusertable 数据库用于映射虚拟域到新的地址。这个特性可以使网络上的虚拟域邮件被投递到本地系统、远程系统或者单一用户地址。/etc/mail/virtusertable 被修改以后,我们可以使用 makemap 命令来生成 /etc/mail/virtusertable.db。 同样,该文件被修改后,sendmail 必须重新启动来更新设置。
/etc/mail/domaintable 和 domaintable.db
domaintable 数据库用于映射旧域名到新域名。这个特性使得网络上多个域名可以由旧域名重写到新域名中。/etc/mail/domaintable 文件被修改后,我们可以利用 makemap 命令来生成 /etc/mail/domaintable.db。同样,该文件被修改后,sendmail 必须重新启动来更新设置。
/etc/mail/mailertable 和 mailertable.db
mailertable 数据库通过一种特殊的邮寄程序,把寻址到特定主机(或域)的邮件重定向到替代的目的地。这个特性使得网络上的邮件可以通过特殊的投递代理被投递到一个新的本地域名或远程域名。/etc/mail/mailertable 被修改后,我们可以利用 makemap 命令生成 /etc/mail/mailertable.db。同样,该文件被修改后,sendmail 必须重新启动来更新设置。
~/.forward
普通用户可以通过主目录下的 .forward 文件来实现邮件的别名和转发等功能。
验证 sendmail 服务
我们可以通过 telnet 程序来访问 localhost 的 25 端口,从而可以验证 sendmail 服务是否正常启动。如果能够登陆成功,则说明 sendmail 服务已经成功启动。具体的验证过程如清单 8 所示。
清单 8. 验证 sendmail 服务
linux:~ # telnet localhost 25
Trying 127.0.0.1...
Connected to localhost.
Escape character is '^]'.
220 linux ESMTP Sendmail 8.13.6/8.13.6/SuSE Linux 0.8; Sat, 12 Sep 2009 14:37:24 -0700
ehlo localhost
250-linux Hello localhost [127.0.0.1], pleased to meet you
250-ENHANCEDSTATUSCODES
250-PIPELINING
250-8BITMIME
250-SIZE
250-DSN
250-ETRN
250-DELIVERBY
250 HELP
自动发送邮件的脚本实现
在 SLES11 系统中,sendmail-8.13.6-9.15 已经被默认安装,清单 9 所示的 Perl 脚本可以实现从本地主机自动发送邮件到远程邮箱的功能,发送的邮件将包含发送者的 mail 地址、接收者的 mail 地址、邮件主题、邮件的内容以及两个附件。
清单 9. 自动发送邮件的 Perl 脚本
#!/usr/bin/perl
# 将要使用 sendmail 来发送邮件
my $mailprog = "/usr/sbin/sendmail";
# 发送者的邮件地址
my $ senderemail = "sender\@cn.ibm.com";
# 发送者的名字
my $sender = "sender";
# 发送时的时间
my $datestring=`date +%m.%d.%Y`;
# 接收者的 email 地址
my $email = "receiver\@cn.ibm.com";
# Send file to user in email
open(MAIL, "|$mailprog -f $sender -t $senderemail") or die;
# 创建发送邮件的头
print MAIL "From: $sender\n";
print MAIL "To: $email\n";
# 主题
print MAIL "Subject: Automation test on SELS $datestring\n";
#email 的信件内容
print MAIL "Hi All\nthis is the automation test result on $datestring. Please check
the attached files.\n";
# 第一个附件
$file = "/tmp/28279.txt";
open(FILE, "uuencode $file $file |") or die;
print MAIL <FILE>;
close(FILE);
# 第二个附件
$file="/tmp/28280.txt";
open(FILE, "uuencode $file $file |") or die;
while( <FILE>) { print MAIL; };
close(FILE);
# 完成邮件发送
close(MAIL);
AIX 的 sendmail 配置
AIX 的 mail 系统中最重要的三个组成部分是用户接口 (the user interface)、消息路由程序 (the message routing program) 和消息投递程序 (the message delivery program) 或 mailer。AIX 系统中的 mail 程序就是所谓的用户接口 (the user interface),它对应上文提到的邮件用户代理 MUA;sendmail 程序就是所谓的消息路由程序 (the message routing program),它对应前面所说的邮件传输代理 MTA。在传递邮件的时后,如有必要,sendmail 命令将与远程系统建立 TCP/IP 连接 , 然后使用 SMTP 传递邮件到远程系统。
AIX 邮件系统的工作原理和配置,和 Linux 基本都相同,特殊的地方有以下几点。
生成配置文件的脚本的位置
/usr/samples/tcpip/sendmail/cf/aixsample.mc 被用来生成 sendmail 相应的配置文件。
sendmail daemon 启动和关闭的方式
启动 sendmail:
startsrc -s sendmail
关闭 sendmail:
stopsrc -s sendmail
通过 SMTP 服务器发 Internet 邮件
在使用 SMTP 代理的情况下,sendmail 需要对 /etc/sendmail.cf 配置文件中的 DS 项进行修改。DS 项是指被用来转发邮件的主机。注意,该配置项修改以后,sendmail daemon 必须重启才能生效。/etc/sendmail.cf 文件的具体的修改内容如清单 10 所示。
清单 10./etc/sendmail.cf 文件的修改内容
# "Smart" relay host (may be null)
DS[SMTP 的主机 IP]
自动发送邮件的脚本实现
在 AIX6100-03 操作系统中,sendmail version AIX6.1/8.13.4 已经被默认安装。在这样的配置环境中,本节将给出两个实现不同功能的 Perl 脚本。
清单 11 中的 Perl 脚本实现了邮件带主题和附件的功能。
清单 11. 带有附件的邮件自动化发送邮件脚本
#!/usr/bin/perl
# 接受者的邮件系统
my $email = "receiver\@cn.ibm.com";
# 将作为附件发送出去的两个文件
my $file1="/tmp/1.txt";
my $file2="/tmp/2.txt";
# 将要使用的邮件发送程序
my $mailprog = "/usr/bin/mail";
# 记录发送时间
my $datestring=`date +%m\/%d\/%Y`;
chomp($datestring);
#email 的主题
my $subject= "\"Subject: Test on AIX $datestring with attachment\"";
# 产生发送邮件命令
my $cmd_sendmail = "uuencode $file1 \"1.txt\" $file2 \"2.txt\" |";
$cmd_sendmail .= "$mailprog -s $subject $email ";
# 执行发送命令
system($cmd_sendmail);
清单 12 中的 Perl 脚本实现了不带附件、有邮件内容的自动化发送邮件的功能。
清单 12. 不带附件的邮件自动发送邮件的脚本实现
#!/usr/bin/perl
# 接受者的邮件系统
my $email = "receiver\@cn.ibm.com";
# 记录发送时间
my $datestring=`date +%m\/%d\/%Y`;
chomp($datestring);
#email 的主题
my $subject= "\"Subject: Test on AIX $datestring \"";
# 产生发送邮件命令
my $cmd_sendmail = "echo $message |";
$cmd_sendmail .= "$mailprog -s $subject $email";
# 执行发送命令
`$cmd_sendmail`;
不依赖邮件客户端配置的实现
利用 Perl 模块实现邮件的发送
我们同样可以借助许多现有的 Perl 模块来实现电子邮件的发送功能。从 CPAN 网站上的如下链接 (http://search.cpan.org/modlist/Mail_and_Usenet_News/Mail) 中,我们可以找到许多与 Mail 配置、传输相关的 Perl 模块,比如 Mail::Mailer,Mail::POP3Client, Mail::Postfix, Mail::Internet, Mail::Sendmail, Mail::Sender 等等。
CPAN 网站上有如此众多的 Perl 模块可供选择,我们最终选择了 Mail::Mailer。Mail::Mailer 是由 Mark Overmeer <mark@overmeer.net> 开发的,已经被集成进 MailTools 模块。目前 Mail::Mailer 版本为 2.04,用户可以在如下的链接地址上找着详细的介绍信息:http://search.cpan.org/~markov/MailTools-2.04/lib/Mail/Mailer.pod。总体上来说,Mail::Mailer 的实现很简洁,虽然它提供了很少的编程接口,但对于邮件的发送来说已经足够。
Mail::Mailer 的安装
我们可以通过 CPAN 来安装 Mail::Mailer。不过需要注意的是,在使用 CPAN 安装 Mail::Mailer 之前,我们需要确保计算机可以连接到 Internet 网络。
我们可以在 Linux/UNIX 终端下输入清单 13 中的命令进入 CPAN 的操作界面。CPAN 的命令行界面如清单 14 所示。
清单 13. 进入 CPAN 操作界面
perl -MCPAN -e shell
清单 14.CPAN 的命令行界面
cpan shell -- CPAN exploration and modules installation (v1.9205)
ReadLine support available (maybe install Bundle::CPAN or Bundle::CPANxxl?)
cpan[1]>
其中,cpan[1]>是 CPAN shell 的提示符;我们可以在它后面输入相应的 CPAN 命令来完成特定的功能。最后,我们可以通过在 CPAN 的操作界面中输入清单 15 中的命令来安装 Mail::Mailer。CPAN 会自动连接到 CPAN 网站搜索并下载 Mail::Mailer 相关的包,并最终完成 Mail::Mailer 的安装。
清单 15. 安装 Mail::Mailer
cpan[1]> install Mail::Mailer
Mail::Mailer 的接口
Mail::Mailer 提供的是面向对象的接口。它非常简单,除了 Mail::Mailer 对象构造和析构的方法以外,只有一个 open 方法需要介绍。
使用 new 来构造 Mail::Mailer 对象的方法如清单 16 所示。
清单 16.Mail:Mailer 对象的构造方法
Mail::Mailer->new(TYPE, ARGS)
其中,TYPE 是指后台的邮件发送程序,而 ARGS 是指传递给该后台邮件发送程序的参数列表。目前可用的 TYPE 值有 sendmail,smtp,qmail 和 testfile。
sendmail:
它会调用系统中已安装的 sendmail 做为邮件发送程序;
smtp:
它会通过 Net::SMTP 模块去投递邮件;
qmail:
它就会使用 qmail 的 qmail-inject 程序去发送邮件;
testfile:
用来调试的参数,它会将相关的数据写入日志文件。
另外需要说明的方法是 $obj->open(),它的声明和参数说明如清单 17 所示。
清单 17.Mail::Mailer 对象的 open() 方法
$obj->open(HASH)
当通过 Mail::Mailer->new(TYPE, ARGS)成功创建 Mail::Mailer 对象以后,我们就可以通过 open() 方法来构建邮件。这里 HASH 类型的参数包含一系列的 key 和对应的 value;注意,这些 key 值必须是邮件的 head 域所包含的值,比如 To,From,Replyto,Subject,Cc,Bcc 等等;而 value 必须是这些 key 所对应的值。
Mail::Mailer 发送邮件的脚本实现
我们将给出一个使用 Mail::Mailer 来发送电子邮件到指定邮箱的实例,如清单 18 所示。我们使用 sendmail 作为后台的邮件发送程序。
清单 18. 使用 Mail::Mailer 发送邮件
#!/usr/bin/perl – w
use Mail::Mailer;
# 构造 Mail::Mailer 对象
my $mail = Mail::Mailer->new( ‘ sendmail ’ )
or die “Couldn ’ t create Mail::Mailer object!\n”;
# 构建邮件
$mail_headers->open(
{
From => 'root@root-desktop',
To => 'yourname@yourmail.com',
Subject => 'Mail::Mailer is used',
}
);
# 发送邮件
print $mail “This is the body part of the message you can write your message here”;
$mail->close($mail_headers);
exit 0;
结合 cron 的系统监控功能实现
系统管理人员可以结合 cron 与电子邮件的自动发送功能,实现系统状态的自动监控功能。cron 是一个定时调度任务的守护进程,它可以根据时间、日期、月份、星期的组合来调度任务。关于 cron 的详细教程,读者可以参考在 developerworks 上的教程《 使用 cron 进行自动维护》,或者参考 Internet 上的相关文章。
监控系统 CPU 利用率(LINUX)
我们首先实现一个可以获取当前系统 CPU 使用率的 Perl 脚本。它可以获取当前的 CPU 使用率,一旦获取到的 CPU 使用率超过 85%,该脚本就会自动发送电子邮件给指定的用户。注意,该脚本只能运行于 Linux 平台。
具体的 Perl 脚本内容可以参考清单 19。
清单 19. 监控系统 CPU 利用率的脚本
#!/usr/bin/perl
use Mail::Mailer;
sub get_cpu_stat {
my @stats;
my $fh;
#Linux 系统,从 /proc/stat 来获取 CPU 信息
open($fh, "cat /proc/stat |") or die "$!";
while (<$fh>) {
#get the cpu stat
if (/^cpu .*/) {
@stats = split;
}
}
close $fh;
#then, we parse the cpu stat information;
#the information from "man proc",
#the format is for Linux 2.6.11 or higher
#cpu user nice system idle iowait irq softirq steal
#cpu 628808 1642 61861 24978051 22640 349 3086 0 0
# 数据格式如上所示,更详细的信息请参考 proc 的 manpage
my $total = $stats[1] + $stats[2] + $stats[3] + $stats[4];
my $idle = $stats[4];
# 返回当前 CPU 的 total 和 idle 时间片计数
return ($total, $idle);
}
my $mailer = Mail::Mailer->new('sendmail');
my ($t1, $i1) = get_cpu_stat();
sleep 5;
my ($t2, $i2) = get_cpu_stat();
my $total = $t2 - $t1;
my $idle = $i2 - $i1;
# 计算获取 5 秒钟之内的 CPU 利用率
my $per = 100 * ($total - $idle) / $total;
if( $per > 85) {
# 如果 CPU 利用率大于 85%
my $msg = sprintf("!!!Attention\nThe CPU usage on your server is %.2f"
. "% right now!\nPlease check it right now!\n", $per);
#send mail to the assigned user
# 发送邮件给指定的用户
$mailer->open(
{
From => 'root@minjun-desktop',
To => 'minjun.xi@cn.ibm.com',
Subject => 'Attention for your cluster',
})
or die "Mail::Mailer failed!\n";
print $mailer $msg;
$mailer->close();
}
配置 cron 任务
我们可以利用“crontab”命令来配置 cron 任务;在本文中,我们设定每个小时的第 30 分钟运行一下监控系统 CPU 利用率的脚本。我们使用”crontab – e”命令来编辑当前用户的 cron 任务,编辑的内容如清单 20 所示,其中 mon.pl 是清单 19 中 Perl 脚本的名称,/path/to/ 是指 mon.pl 脚本的路径。
清单 20. 配置 cron 任务
30 * * * * perl /path/to/mon.pl
小结
本文是 Unix/Linux 系统管理自动化系列中的一篇,主要讲述 UNIX/Linux 的邮件系统的配置,并讲述了如何使用 Perl 脚本来实现邮件的自动发送和接收;最后,本文把自动发送邮件的功能与 cron 系统结合在一起,给出了监控系统 CPU 利用率的脚本实现。系统管理人员可以利用类似的功能来实现系统的自动化管理,从而减轻自己的工作强度,并且提高系统的可维护性。