典型的 UNIX® 管理员拥有一套经常用于辅助管理过程的关键实用工具、诀窍和系统。存在各种用于简化不同过程的关键实用工具、命令行链和脚本。其中一些工具来自于操作系统,而大部分的诀窍则来源于长期的经验积累和减轻系统管理员工作压力的要求。本系列文章主要专注于最大限度地利用各种 UNIX 环境中可用的工具,包括简化异构环境中的管理任务的方法。
在您完成管理任务的过程中可能会注意到,由于磁盘空间的原因,系统变得运行缓慢。如果这是个非常重要的系统,那么不大可能关闭计算机并添加更多的存储设备,而且您可能已经采用了配额系统以防止个别用户占用过多的磁盘空间。最合适的方法是查找那些可以删除的、存档到另一个系统的、或脱机存储的内容。
为了实现这个目的,日志文件通常首当其冲,因为常常对 /tmp 和 /var 文件系统设置了有限的空间。(清单 1 向您显示了我的 iBook 上的 /tmp 和 /var,这台计算机上并没有运行任何繁忙的 服务。)某些服务,如 Web 服务器、Java™2 Enterprise Edition (Java EE) Web 应用程序和数据库,都可能创建大量的日志,特别是在有人将其配置为调试模式的情况下。
清单 1. /tmp 和 /var 中可能堆积了大量的数据,即使在个人工作站上
chrish@Bender [530]$ sudo du -sh /tmp/ /var/ 44K /tmp/ 1.0G /var/ |
在证实了没有人需要这些日志数据之后,您可以快速地使用 rm 命令删除它们。但是这样做,您无法重新获得任何磁盘空间。如果不熟悉 UNIX 文件系统的语义学,您可能会认为需要重新启动计算机并且执行非常耗时的文件系统完整性检查(在单用户模式中使用 fsck 命令)。
在标准的 UNIX 文件系统中,您可以在文件打开或写入的时候删除它。这将从文件系统中删除该文件的名称,当使用该文件的程序关闭它时,操作系统可以重新获得其存储空间。许多程序常常使用这种特性来创建临时文件,它们可以创建文件、打开文件并删除文件。如果程序崩溃或正常退出,则将自动删除相应的文件,所以程序员不需要关闭文件或稍后对其进行删除操作。
因为服务器保持打开相应的日志文件以便写入数据,而这些日志文件占用了大量的空间,所以这种情况是非常不利的。删除这样的文件只是从文件系统中删除了它的名称,而无法重新获得任何磁盘空间,直到相应的进程退出或关闭该文件。
要解决这个问题,您可以重新启动拥有这个日志文件的服务,不过该服务的中断可能会引起一些不必要的麻烦。另一种选择是对日志文件重命名,然后告诉相应的进程重新加载其配置文件。任何现有的处理过程将会继续,使用打开的日志文件直到正常完成,而任何新的请求将会记录到使用旧的名称创建的新日志文件中。
根据约定,当您发送一个挂起信号(信号 1 或 HUP)时,大多数服务器进程(所有常用的进程)都会进行复位操作并重新加载它们的配置文件。清单 2 显示了向所有正在运行的 Web 服务器进程发送挂起信号的一种方法。
清单 2. 告诉 Web 服务器重新加载其配置文件并对文件进行复位操作
chrish@Bender [507]$ ps -A | grep httpd | grep -v grep | \
awk '{ print $1; }' | xargs -L 1 sudo kill -HUP
Password:
|
上面的命令中包含了很多的操作,所以让我们来仔细地看一下管道的每个部分。ps 和 grep 命令用来在所有的进程中搜索 httpd(并且忽略用来搜索 httpd 进程的 grep 进程)。接下来,awk 只显示输出结果中的进程 ID,并将它传递给 xargs。然后,xargs 命令接受每个进程 ID(因为使用了 -L 1 以便一次提取一行内容),并使用 sudo kill -HUP 向相应的进程发送一个挂起信号。
意外地删除工作系统中的一些关键文件,肯定会对系统造成损坏。尤其是对于共享库、可执行文件或重要的系统配置文件,很有可能意外地出现这种误操作。
避免这个问题的方法之一是,不要以 root 用户登录到系统中(请参见以 root 用户登录部分)。常规的用户无法破坏重要的系统文件,除非您破坏了标准的权限设置。
另一种方法是通过删除写入位,将相关目录设置为只读(请参见清单 3)。
清单 3. 将重要的目录设置为只读
chrish@Bender [541]$ cd /etc chrish@Bender [542]$ sudo find -d . -type d | xargs sudo chmod -w |
您可以使用 find -d 选项对目录进行深度优先搜索(还指定了 -type d),然后使用 xargs 和 chmod 删除写入位,使每个目录变成只读。这可以防止任何人创建新的文件,更重要的是可以防止删除现有的文件。它不会阻止具有合适权限的用户(即您自己)对现有的文件进行编辑。
使用这种方法时应当小心!如果有一个设计糟糕的应用程序,它需要一个可写入的目录,那么它可能会执行失败,并生成一些令人奇怪的错误消息。大多数程序都将其自动文件创建和删除限制于 /tmp 和 /var 目录。请记住,在安装需要把配置文件或其他内容放入到只读目录中的新软件时,您将不得不重新写入位置位(可以使用相同的处理方法,但使用 u+w 而不是清单 3 命令中的 -w)。
有许多情况都可能对系统造成损坏,但其中大多数都需要访问系统控制台以修复相关内容。
如果由于失控进程而损坏了系统(请参阅本系列中的文章“监视运行缓慢的系统”,在参考资料部分提供了相应的链接),消耗了所有的可用进程槽,或者占用了过多的内存而导致计算机将所有的时间花费在与硬盘的交换中,那么您需要终止那些损害系统的进程,或者如果根本无法登录并执行 kill 命令的话,直接重新启动该计算机。
如果您可以访问该系统,但由于某种原因而无法终止损害系统的进程,可以切换到单用户模式,这将停止所有非关键的服务以及任何用户运行的进程。
要让计算机进入单用户模式,在基于 System V 的 UNIX 中可以使用 telinit 命令 (sudo telinit 1) 或者在来源于 Berkeley Software Distribution (BSD) 的操作系统中使用 shutdown 命令 (sudo shutdown now)。
当您在单用户模式中完成了修复任务之后,重新回到正常状态的最简单的方法是重新启动该计算机;同样,根据系统的具体情况,可以使用 telinit (telinit 6) 或 shutdown (shutdown -r now) 实现重新启动。
在最坏的情况下,您的系统可能遭受了很大程度的损坏,以致于您不得不从操作系统安装媒介或修复盘进行启动。它们通常提供了最基本的单用户环境,您可以使用这个环境进行磁盘检查 (fsck)、系统安全漏洞检查,或者从备份恢复受损的文件。
您手头有备份,对吧?当事情变得一团糟时,好的备份策略将为您省去大量的工作,并且它非常适合于那些不够细心的用户(他们总是会不小心删除自己的重要文件)。
有时,仅保存文件还不够,您可能需要最近的版本或上个星期的版本。这种情况很可能会出现,比如人力资源部门有人覆盖了工资处理文件的唯一副本,或者更糟糕,覆盖了重要的系统配置文件。
保存系统中重要(以及用户)文件的增量备份是防止这种灾难出现的一种重要方法。您曾经删除或覆盖过重要的文件吗?这很容易解决,您只需要从增量备份中提取昨晚的版本即可。
清单 4(在我的系统中,我称其为 newer-archive.sh)向您介绍了一个简单的 Shell 脚本,它用来创建比指定的文件更新的存档文件。您可以使用该脚本为那些比最近增量备份更新的文件创建增量备份。
清单 4. 一个简单的增量存档脚本
#!/bin/sh
#
# Make an incremental archive containing files that have been
# modified since the last archive was created.
#
# Usage:
#
# newer-archive.sh -o new-file.tar -nt old-file files
old_file=""
new_file=""
files=""
archiver="tar -T - -czpsSf"
while [ "$1" != "" ] ; do
case $1 in
-o)
new_file=$2
shift
;;
-nt)
old_file=$2
shift
;;
*)
files="$files $1"
;;
esac
shift
done
for path in $files ; do
find $path -newer $old_file
done | $archiver $new_file
|
-o 选项指定了输出文件,而 -nt 选项指定了用作基准的文件,任何比该文件更新的文件都将添加到存档中。在列出需要进行存档的选项、文件或目录之后,您需要将它们全部添加到输出文件。
您可以对这个脚本进行修改,以便使用任何种类的存档工具,假定您找到了一种通过管道传递需要进行存档的文件列表的方法。如果您的系统中没有安装 GNU 的 tar,那么您可能还需要调整其中的 tar 选项。
您可以将这个脚本与 date 命令组合在一起使用(请参见清单 5),以创建包含当前日期和时间的存档。
清单 5. 使用 date 来指定备份存档的名称
chrish@Bender [525]$ sudo ~/bin/newer-archive.sh -o incremental-$(date +%Y-%m-%d-%H.%M.%S).tar.gz -nt incremental-2006-09-06-11.15.03.tar.gz /Users |
通过在 date 命令中使用 + 选项指定不同的输出格式 (year-month-day-hour.minute.second),您可以创建包含当前日期和时间的文件名,使用最近的增量备份(该备份已经过了一个月,对于备份之间的间隔来说太长了)作为引用的旧 文件,备份所有更新的或修改过的用户数据。
另一种选择是使用 RCS 的 ci 和 co 命令为每个文件创建更改的历史。您还可以使用 ci 签入 文件。这将创建一个历史文件(ci 加上文件名将创建另一个包含文件历史及其较早修订版本的文件名),并将该文件设置为只读。使用 co -l 签出 该文件并重新将其设置为可写的。在完成了相应的更改之后,使用有意义的更改日志消息再次签入该文件(请参见清单 6)。
清单 6. 使用 RCS 跟踪文件版本
chrish@Bender [536]$ ci -u points.txt points.txt,v <-- points.txt enter description, terminated with single '.' or end of file: NOTE: This is NOT the log message! >> important points to cover in the article >> . initial revision: 1.1 done chrish@Bender [537]$ dir points.txt -r--r--r-- 1 chrish chrish 170 Oct 6 14:34 points.txt chrish@Bender [538]$ co -l points.txt points.txt,v --> points.txt revision 1.1 (locked) done chrish@Bender [539]$ vi points.txt chrish@Bender [540]$ ci -u points.txt points.txt,v <-- points.txt new revision: 1.2; previous revision: 1.1 enter log message, terminated with single '.' or end of file: >> added another important point >> . done |
ci 命令的 -u 选项可以在签入文件的时候自动地签出该文件的一个只读版本。co 命令的 -l 选项可以锁定该文件,以便您(并且只有您)可以对其进行编辑。
RCS 只能够处理纯文本文件,如果您需要为二进制文件保存较早的版本,可以使用其他功能更加强大的工具,如 Subversion(请参见参考资料部分)。
在大多数系统中,添加新用户或组似乎只需要使用最喜欢的文本编辑器修改 /etc/passwd 文件(以及 shadow 密码文件,它用来保存密码)或 /etc/group 文件。这种方法很容易记住,而该文件的格式也并不复杂,可以很快地完成这项任务。
但是出于很多的原因,您不应该这样做,这也正是大多数 UNIX 系统,特别是最新的 UNIX 系统,提供专门用于创建新用户和组的工具的原因。
编辑这些重要的系统文件可能会带来麻烦。虽然这些文件的确很简单,但还是有可能受到其他因素的影响并把事情弄得一团糟。可能您的编辑器会在编辑这些文件的时候对其进行锁定,而这将会使得其他用户在您编辑这些文件的时候无法登录。
在手动添加了用户之后,您还有一大堆的工作需要完成。您需要创建一个新的 home 目录,使用标准 home 目录中的内容填充该目录,将用户添加到所有合适的组中,并创建一些系统级的内容,如新用户所使用的邮件缓冲。
为什么要自找麻烦呢?可以使用用户和组的创建工具,这将为您节省时间和精力(并且可以确保不会将事情弄得一团糟,这将帮助您维持权威的声誉)。
大多数标准的 UNIX 系统都为管理员提供了 adduser(或 useradd)和 addgroup(或 groupadd)命令。许多 Linux® 分发版提供了易于使用的图形化工具(如 Fedora Core 的 User Manager),而 FreeBSD 的功能全面的 sysinstall 实用程序也可以完成用户和组的创建。在 Mac OS X 中,您可以使用 Accounts preferences 来创建用户,可以使用 NetInfo Manager 来创建新的组。
正如您所知道的,root 用户在 UNIX 系统中具有所有的权限。root 用户可以执行任何操作,正如常说的,“能力越强,责任越大”。仍然有一些用户坚持以 root 用户登录系统,即使他们所执行的操作并不需要用到其中所有的权限。
在任何具有管理员权限的系统中,您应该始终为自己创建(并使用!)一个常规的用户帐户。而在执行需要 root 权限的操作时,使用系统中的 su(请参见清单 7)或 sudo(请参见清单 8)命令(可以使用您的系统中所提供的任何一个)临时切换到 root 用户。
清单 7. 使用 su 命令临时切换到 root 用户
chrish@Bender [514]$ su - Password: # |
清单 8 使用了 sudo 命令,以 root 用户的身份运行一个命令。
清单 8. 使用 sudo 命令,以 root 用户的身份运行一个命令
chrish@Bender [517]$ sudo id Password: uid=0(root) gid=0(wheel) groups=0(wheel), 1(daemon), 2(kmem), 3(sys), 4(tty), 29(certusers), 5(operator), 80(admin), 20(staff) |
为什么要避免以 root 用户运行呢?错误的 rm 命令、或不小心将 tar 文件释放到错误的位置,这都可能对您的系统造成损坏,并需要大量的修复工作。
需要确保网络中所有系统的安全,这是毫无疑问的。保留服务器或路由器中的缺省密码,这无异于邀请那些不择手段的(甚至仅仅只是好奇的)人侵入系统。入侵者可能有意地或无意地对系统造成损害,使系统遭受破坏,或者更糟,利用系统中的漏洞偷偷地对其进行修改,以便分发垃圾邮件、盗版软件或其他的东西。
确保系统安全的一个好的策略是拒绝任何操作,而不是允许任何操作。具体来说,关闭所有并不真正需要的网络服务,阻塞除了需要向 Internet(或您的局域网 (LAN),假设您位于防火墙的保护下)上其他的用户提供服务的网络端口之外的其他进入的网络端口,并且删除并不真正使用该系统的所有用户。
在此基础上,您可以重新部署服务、打开网络端口并添加所需的用户。这看上去是额外的工作,但使得您可以确切地了解系统中所发生的事情。
在可能的情况下,合理的密码策略也可以增强安全性。许多企业环境都具有相应的密码策略,通常需要定期地更换密码,这样做实际上反而鼓励了不好的密码行为。如果用户本来具有一个强密码,让他们频繁地更改密码可能会使得他们忘记新密码(因此必须请求您的帮助,从而增加了您的工作)或者将密码写在纸上并放在计算机附近。您可能会感到惊讶,许多的用户会将自己最重要的密码写在键盘或鼠标垫下面的胶粘便签上。
相关的工具,如功能强大的 crack,它是一种基于字典的密码测试程序(请参见参考资料部分中相关的 Wikipedia 条目),还可以通过测试密码文件或其他的存储库中的单词,帮助您清除弱密码、常见的单词拼写错误(如 l33t)并执行其他的单词处理算法(请参见清单 9)。
清单 9. 使用 crack 检查弱密码
chrish@Bender [503]$ cp /etc/passwd . chrish@Bender [504]$ sudo crack passwd |
请注意,您所操作的是密码文件的副本(您系统中的密码可能存储在 /etc/shadow 中或网络上的集中式存储库中),而不是这个活动的 文件。您永远无法知道什么时候会出现问题!
本文向您介绍了一些处理系统管理陷阱的方法,并解释了对于某个问题来说,最直观的解决方案未必是正确的解决方案。现在,您应该可以冷静地处理常见的灾难,并通过增量备份和确保系统安全的措施为将来的问题做好准备。通过利用 UNIX 系统中所提供的各种工具,可以为您节省时间。
学习
- 您可以参阅本文在 developerWorks 全球站点上的 英文原文 。
- 系统管理员工具包:查看本系列中的其他部分。
- Crack:阅读关于经典的 UNIX 密码测试程序的 Wikipedia 条目。
- Subversion:访问 Tigris 站点,以了解更多关于 Subversion 项目的内容。
- “监视运行缓慢的系统”(developerWorks,2006 年 6 月):了解如何识别和诊断导致 UNIX 系统运行缓慢的原因。
- Solaris to Linux Migration: A Guide for System Administrators:不同的系统使用不同的工具,这本 IBM 红皮书帮助您识别一些重要工具。
- “探索 Linux 内存模型”(developerWorks,2006 年 1 月):理解 Linux 如何使用内存和交换空间,以及如何在两者之间交换页面和进程。
- “在 Bash shell 中工作”(developerWorks,2006 年 5 月):该教程提供了使用 Bourne Again Shell 进行所有工作的指南,包括自定义和扩展环境的方法。
- Bash:Bash 是标准 Bourne Shell 的替代 Shell,并且与之具有类似的语法,但同时具备大量的新特性,包括别名、作业控制以及文件和目录名自动完成。
- AIX® and UNIX:访问 developerWorks 的“AIX and UNIX”专区以拓展您的 UNIX 技能。
- AIX and UNIX 新手入门:访问“AIX and UNIX 新手入门”页面以了解更多关于 AIX 和 UNIX 的内容。
- developerWorks 技术事件和网络广播:跟踪最新的 developerWorks 技术事件与网络广播。
- 播客:收听播客并与 IBM 技术专家保持同步。
获得产品和技术
- IBM 试用软件:使用 IBM 软件开发您的下一个项目,可直接从 developerWorks 下载这些试用软件。
讨论
- 参与“AIX and UNIX”论坛:
- 参与 developerWorks 博客,从而参加到 developerWorks 社区中来。