只要是Linux系统,不管使用的发行版本、网络配置以及系统全局设计有什么不同,都有如下几个核心系统服务:init、inetd、syslogd和cron。这些服务提供的功能比较简单,但同时它们也是其他操作的基础。如果没有它们,Linux就不会有现在的威力。
本文将对每一个核心系统服务、相应的配置文件以及推荐的应用方式(如果有的话)逐个进行介绍。我们强烈推荐:务必要花上一些时间熟悉这些服务的实现原理。通过使用这些服务,人们已经设计出了许多富有创意的问题解决方案。
init服务
init进程是所有进程的发起者和控制者。因为在任何基于Unix的系统(比如Linux)中,它都是第一个运行的进程,所以init进程的编号(Process ID,PID)永远是1。如果init出现了问题,系统的其余部分也就随之而垮掉了。
init进程有两个作用。第一个作用是扮演终结父进程的角色。因为init进程永远不会被终止,所以系统总是可以确信它的存在,并在必要的时候以它为参照。如果某个进程在它衍生出来的全部子进程结束之前被终止,就会出现必须以init为参照的情况。此时那些失去了父进程的子进程就都会以init作为它们的父进程。快速执行一下ps -af 命令,可以列出许多父进程ID(Parent Process ID,PPID)为1的进程来。
init的第二个角色是在进入某个特定的运行级别(Runlevel)时运行相应的程序,以此对各种运行级别进行管理。它的这个作用是由/etc/inittab文件定义的。
1. /etc/inittab文件
/etc/inittab文件中包括了所有init启动运行级别所必须的信息。这个文件中的每一行语句的格式如下所示:
id : runlevels: action : process
注意:以#开始的语句是注释语句。看看你自己的/etc/inittab文件就可以发现其中充斥了大量的注释语句。如果确实需要对/etc/inittab文件进行什么改动(一般不会出现这种情况的),记住加上一些注释语句,解释为什么要做那些修改。
2. Telinit命令
通知init在什么时候切换系统运行级别的神秘力量实际上就是Telinit命令。这个命令有两个命令行参数:一个参数用来通知init准备切换过去的运行级别;另外一个是-tsec,其中的sec是在通知init之前需要等待的、以秒计算的时间。
注意:init是否真的切换运行级别是由它自己决定的。很明显,它经常切换,否则这个命令就不会那么有用了。在大多数Unix操作系统的具体实现(包括Linux)中,Telinit命令实际上只是一个对init程序的符号链接。基于此,许多人更喜欢使用init直接切换到他们想去的运行级别而不是使用Telinit。就个人而言,我发现使用Telinit切换运行级别更便于理解和记忆。
inetd进程
inetd程序是一个守护进程。您可能已经知道守护进程是一些特殊的程序:它们在被启动之后,自愿放弃对调用自己终端的控制权。守护进程与系统其余部分的接口只有依靠进程间通信(Interprocess Communication,IPC)通道、或者依靠向系统全局性日志文件(Log File)才能发送数据项。
inetd的角色是作为Telnet和FTP等与网络服务器相关的进程的“超级服务器”。这是一个简单的道理:并不是全部的服务器进程(包括那些接受新的Telnet和FTP连接的进程)都会如此频繁地被调用,以至于必须要有一个程序随时运行在内存中。因此为了避免出现可能有几十种服务都运行在内存中准备被使用的情况,它们都列在inetd的配置文件/etc/inetd.conf中。而代替它们的是inetd监听着进入的连接。这样只需要有一个进程在内存中就可以了。
inetd的另外一个优点是程序员并不想把需要网络连接的进程都编写到系统中去。inetd程序将处理网络代码,并把进入的网络数据流作为各个进程的标准输入(Standard-In,即Stdin)传递到其中。这些进程的输出(Stdout)将会被送回连接到该进程的主机去。
注意:除非你正在进行编程,否则是不需要连接到inetd的Stdin/Stdout功能上。从另一方面来说,如果有人打算编写一个简单的命令脚本程序并让它出现在网络中,就值得深入研究这个极为强大的功能。
1.etc/inetd.conf文件
etc/inetd.conf文件是inetd的配置文件。它的结构很简单:每一行语句代表一种服务。服务定义语句的格式如下所示:
srvce_name sock_type protocol [no]wait user srvr_prog srvr_prog_args
2.安全性与inetd.conf文件
你将会发现在大多数的Linux安装中,许多服务在缺省的情况下是打开的。如果你的系统将向因特网开放(包括通过拨号点对点协议被连通),你想做的第一件事就会是把一切都关闭!决不要假设因为你的系统没有对公众进行宣传,别人就不会找到它。从相反的方向看,寻找存在安全性攻击隐患系统的工具软件是既容易找到又容易使用的。
关闭服务的第一个步骤是把etc/inetd.conf文件里所有用不着的服务性说明语句都改为注释语句。
一般来说,你会发现下面的方法更容易使用:先把全部东西都改为注释语句(彻底关闭网络服务),再有选择地打开需要的服务。
在完成对etc/inetd.conf文件的修改之后,需要向守护进程报告其配置文件已经被修改了。这是通过向该守护进程发送HUP信号来实现的。先使用下面的命令找出inetd.conf对应的进程ID:
[ root@ford /root ] # ps auxw | grep inetd | grep -v grep
这个命令的输出类似于下面的内容:
root 359 0.0 0.1 1232 168 ? S Jun21 0 : 00 inetd
输出中的第二列告诉我们进程ID号(这里就是359)。为了发送HUP信号,我们需要使用Kill命令(把这个程序叫做Kill多少有些误导。实际上,它只是向进程发送信号而已。缺省的情况下,它会发出请求某个程序终止运行的信号)。
下面是使用Kill命令发送HUP信号的方法:
$ kil -1 359
应该把上面命令中的359换成从你的系统上得到的进程编号。
syslogd守护进程
在同一时间会发生许许多多的事情,而在终端窗口中断开连接的网络服务就更是如此了。因此,提供一个记录特殊事件和消息的标准机制就非常有必要了。Linux使用syslogd守护进程来提供这个服务。
syslogd守护进程提供了一个对系统活动和消息进行记录的标准方法。许多其他种类的Unix操作系统也使用了兼容的守护进程。这就提供了一个在网络中跨平台记录的方法。在大型的网络环境里,这更具有价值。因为在那样的环境里,集中收集各种记录数据以获得系统运转的准确情况是很有必要的。你可以把这种记录功能子系统比作Windows NT的SystemLogger。
syslogd保存数据用的记录文件都是简明的文本文件,一般都存放在/var/log子目录中。每个数据项构成一行,包括日期、时间、主机名、进程名、进程的PID,以及来自该进程的消息。标准C函数库中的一个全局性的函数提供了生成记录消息的简单机制。如果不喜欢编写程序代码,但是又想在记录文件中生成数据项,可以选择使用Logger命令。可以想象,像syslogd这样重要的工具应该是作为开机引导命令脚本程序的一部分来启动的。你准备在服务器环境中使用的任何一个Linux发行版本都已经为你设置好了。
1.调用syslogd
如果需要手动启动syslogd,或者需要修改开机引导时启动它的命令脚本程序,你就必须注意syslogd的命令行参数,请大家参看有关书籍,这里不做详细介绍。
2./etc/syslog.conf文件
/etc/syslog.conf文件包含了syslogd需要运行的配置信息。这个文件的格式有些不寻常,但是现有的缺省配置文件将足以满足使用需要了,除非你需要在特定的文件中查找特定的信息,或者需要把这些信息发送到远程记录计算机去。
● 记录信息分类
在我们掌握/etc/syslog.conf文件格式本身之前,需要先了解记录消息是如何分类的。每个消息都有一个功能值(Facility)和一个优先权值(Priority)。功能值告诉我们这条消息是由哪个子系统产生的,而优先权值则告诉我们这个消息有多重要。这两个值由句号分隔而且都有等价的字符串,从而容易记忆。
● /etc/syslog.conf文件的格式
下面是配置文件里各语句的格式:
facility/priority combinations separated by commas file
/process/host to log to
举例如下:
kern.info /ver/log/kerned
syslogd还可以灵活地把记录消息发送到多种不同的保存目的地去。它可以把消息保存为文件、把消息发送到FIFO队列、发送到一组用户、或者(在大型站点集中记录消息的情况下)发送到一个中心记录主机中。为了区分这些目的地,在目的地入口使用了下面的规则:
◆ 如果保存目的地的开始字符是斜杠字符(/),消息将发送到某个文件。
◆ 如果保存目的地的开始字符是垂直字符(|),消息将发送到某个FIFO队列。
◆ 如果保存目的地的开始字符是“@”字符,消息将发送到某个主机。
cron程序
cron程序允许系统中的任一用户安排某个程序在任何日期、时间准时运行,时间可以精确到分钟。使用cron是一个极为有效的方法,可以使你的系统自动化、周期性地生成报告以及执行其它定期任务。和我们在本文中已经讨论的其它服务一样,cron是由开机引导命令脚本程序启动的,并且应该是已经配置好了的。对进程清单的一个快速检查就可以看到它默默地在后台运行着。cron服务的工作原理是:每隔一分钟唤醒一次,检查每个用户的Crontab文件。这个文件的内容是该用户希望在某些特定时刻执行的活动清单。任何匹配当前日期和时间的活动都将被调入执行。
cron命令本身并不需要任何命令行参数,也不需要什么信号来表明其状态的改变。用来编辑由cron调入执行的设置项工具是Crontab。它的原理是:验证你是否有修改cron设置项的权限,然后调入一个文本编辑器让你进行修改。修改完成后,Crontab会把文件放到正确的位置,并把你带回到提示符下。
你是否具有适当的权限是由Crontab通过检查/etc/cron.allow和/etc/cron.deny这两个文件来决定的。不管这两个文件中的哪一个存在,只有当你明确地列在其中的时候才能使你的操作生效。举例来说,如果/etc/cron.allow文件存在,那么只有当你的用户名列在这个文件中的时候才能允许你编辑cron数据项。另一方面,如果/etc/cron.deny文件存在而/etc/cron.allow文件不存在,那么只要你的用户名没有出现在这个文件中,就表明允许你编辑你的cron数据项。
Cronjobs文件(通常即指crontab文件)的格式如下所示: Minute Hour Day Month DayOfWeek Command,所有数值都必须是整数。
如果打算在某一栏上设置多个数值(比如:打算在早晨4 : 00、中午12 : 00和下午5 : 00三次运行同一个程序),就需要将这些时间数据用逗号在相应的栏里分隔开,但是在该栏中不能添加任何空格。对需要在早晨4 : 00、中午12 : 00和下午5 : 00三次运行同一个程序的情况,Hour栏的数据项应该是4、12、17。
在DayOf Week数据项里,数值0表示星期天、1表示星期一,以此类推,直到6表示星期六。如果某个数据项中出现了一个星号(*)通配符,就表示相应栏中任意的分钟、小时、日期、月份或者星期几都匹配。当文件中的日期和时间满足当前日期和时间的时候,这一行语句中设置的命令就会以设置该数据项用户的身份运行,所生成的任何输出都会以电子邮件E-mail的方式返回到那个用户。很明显,这可能会引起邮箱中的消息爆满,所以对邮件报告作出迅速反应是很重要的。对消息量加以控制的一个好办法是:只输出出错情况,而那些不可避免的其他输出就发送到/dev/null设备中去。
我们来看一些例子。下面的数据项每隔四个小时运行一次/usr/bin/ping zaphod命令:
0 0,4,8,12,16,20 * * * /usr/bin/ping zaphod
下面的数据项在每个星期五晚上的10 : 00运行程序/usr/local/scripts/backup-level-0:
0 22 * * 5 /usr/local/scripts/backup_level_0
最后,下面的数据项在四月一日(不管那是星期几)早晨4 : 01分发出一封电子邮件:
1 4 1 4 * /bin/mail dad@domain.com < /home/sshah/joke
本文讨论了每一个Linux系统都必须具备的四种核心服务。这些服务并不要求网络支持,并且会随着主机的不同而有不同的变化。这就使它们具有很高的使用价值,因为它们不管计算机系统本身是否在多用户模式下都可以工作得很好。