下一页 上一页 目录

3. 详细技巧

3.1 在 Linux 和 Windows 之间共享交换分区。 Tony Acero, ace3@midway.uchicago.edu

  1. 将分区格式化为 DOS 分区,并在其上创建 Windows 交换文件,但暂时不要运行 Windows。(您希望现在保持交换文件完全为空,以便它可以很好地压缩)。
  2. 启动 Linux 并将分区保存到一个文件。例如,如果分区是 /dev/hda8
    dd if=/dev/hda8 of=/etc/dosswap
    
  3. 压缩 dosswap 文件;由于它实际上全部是 0,因此可以很好地压缩
    gzip -9 /etc/dosswap
    
  4. 将以下内容添加到 /etc/rc 文件中,以准备和安装 Linux 下的交换空间:XXXXX 是交换分区中的块数
    mkswap /dev/hda8 XXXXX
    swapon -av   
    
    确保在您的 /etc/fstab 文件中为交换分区添加条目
  5. 如果您的 init/reboot 包支持 /etc/brc 或 /sbin/brc,请将以下内容添加到 /etc/brc,否则当您想要启动到 dos|os/2 并希望将交换分区转换回 dos/windows 版本时,请手动执行此操作
swapoff -av
zcat /etc/dosswap.gz | dd of=/dev/hda8 bs=1k count=100
# 请注意,这仅将前 100 个块写回分区。我凭经验发现这已足够

>> 这样做有什么优点和缺点?

优点:您可以节省大量的磁盘空间。

缺点:如果步骤 5 不是自动的,您必须记住手动执行,并且它会使重启过程减慢十亿分之一秒 :-)

3.2 绝望的取消删除。Michael Hamilton, michael@actrix.gen.nz

这是一个我不得不使用几次的技巧。

绝望的人的文本文件取消删除。

如果您不小心删除了一个文本文件,例如,一些电子邮件,或者深夜编程会话的结果,那么一切可能还没有丢失。如果该文件曾经被写入磁盘,即它存在超过 30 秒,则其内容可能仍然在磁盘分区中。

您可以使用 grep 命令在原始磁盘分区中搜索文件的内容。

例如,最近,我不小心删除了一封电子邮件。因此,我立即停止了任何可能修改该分区的活动:在这种情况下,我只是避免保存任何文件或进行任何编译等。在其他情况下,我实际上已经费力地将系统降至单用户模式,并卸载了文件系统。

然后我在磁盘分区上使用了 egrep 命令:在我的情况下,电子邮件消息在 /usr/local/home/michael/ 中,因此从 df 的输出中,我可以看到它在 /dev/hdb5 中

  sputnik3:~ % df
    Filesystem         1024-blocks  Used Available Capacity Mounted on
    /dev/hda3              18621    9759     7901     55%   /
    /dev/hdb3             308852  258443    34458     88%   /usr
    /dev/hdb5             466896  407062    35720     92%   /usr/local

    sputnik3:~ % su
    Password:
    [michael@sputnik3 michael]# egrep -50 'ftp.+COL' /dev/hdb5 > /tmp/x
 
现在我在摆弄磁盘分区时非常小心,所以我暂停了一下,以确保在按下回车键之前我理解了命令语法。在这种情况下,电子邮件包含单词“ftp”,后跟一些文本,然后是单词“COL”。该消息大约 20 行长,所以我使用了 -50 来获取短语周围的所有行。过去,我曾使用 -3000 来确保我获得了某些源代码的所有行。我将 egrep 的输出定向到不同的磁盘分区 - 这防止了它覆盖我正在查找的消息。

然后我使用 strings 来帮助我检查输出

   strings /tmp/x | less
 
果然,电子邮件就在那里。

这种方法不能被依赖,全部或部分磁盘空间可能已经被重新使用。

这个技巧可能只在单用户系统上有效。在磁盘活动频繁的多用户系统上,您释放的空间可能已经被重用。而且,当我们需要恢复文件时,我们大多数人都不能直接从用户那里抢走机器。

在我的家用系统上,这个技巧在过去几年中大约派上了三次用场 - 通常是在我不小心删除了当天的一些工作时。如果我正在做的事情能够存活到我觉得我取得了重大进展的程度,它就会备份到软盘上,所以我并不经常需要这个技巧。

3.3 如何使用不可变标志。Jim Dennis, jadestar@rahul.net

使用不可变标志

在您安装和配置系统之后,立即浏览 /bin、/sbin/、/usr/bin、/usr/sbin 和 /usr/lib(以及其他一些常见的目录),并大量使用 'chattr +i' 命令。还要将其添加到 root 中的内核文件。现在 'mkdir /etc/.dist/' 将 /etc/ 下的所有内容复制到该目录中(我分两步完成,使用 /tmp/etcdist.tar 以避免递归)。(可选地,您可以只创建 /etc/.dist.tar.gz)-- 并将其标记为不可变。

所有这些的原因是为了限制以 root 用户身份登录时可能造成的损害。您不会使用错误的重定向运算符覆盖文件,也不会因为 'rm -fr' 命令中出现错误的空格而使系统无法使用(您可能仍然会对您的数据造成很多损害 -- 但您的 libs 和 bins 会更安全)。

这也使得各种安全漏洞和拒绝服务攻击变得不可能或更困难(因为它们中的许多都依赖于通过某些 *不提供任意 shell 命令* 的 SUID 程序的动作来覆盖文件)。

这样做的唯一不便是当您构建并在各种系统二进制文件上执行 'make install' 时。另一方面,它也阻止了 'make install' 覆盖文件。当您忘记阅读 Makefile 并 chattr -i 要覆盖的文件(以及您要添加文件的目录)时 -- make 失败,您只需使用 chattr 命令并重新运行它。您也可以借此机会将旧的 bin、libs 或任何东西移动到 .old/ 目录中,或者重命名或 tar 它们或任何东西。

3.4 关于将新内容放在哪里的建议。 Jim Dennis, jadestar@rahul.net

所有新内容都从 /usr/local! 或 /usr/local/`hostname` 开始

如果您的发行版使 /usr/local 为空,那么只需创建您的 /usr/local/src、/usr/local/bin 等并使用它。如果您的发行版将内容放在 /usr/local 树中,那么您可能需要 'mkdir /usr/local/`hostname`' 并给 'wheel' 组 +w 权限(我还将其设置为 SUID 和 SGID,以确保 wheel 组的每个成员只能处理他们自己的文件,并且所有创建的文件都将属于 'wheel' 组)。

现在约束自己 *始终!始终!始终!* 将新软件包放在 /usr/local/src/.from/$WHEREVER_I_GOT_IT/ 下(对于 .tar 或任何文件),并在 /usr/local/src(或 .../$HOSTNAME/src)下构建它们。确保它安装在本地层次结构下。如果 *绝对必须* 安装回 /bin 或 /usr/bin 或其他地方 -- 从本地层次结构到任何其他地方的每个元素都放置一个符号链接。

这样做的原因 -- 即使它更麻烦 -- 是它有助于隔离在从发行版媒体(现在通常是 CD)完全重新安装时必须备份和还原或重新安装的内容。通过使用 /usr/local/.from 目录,您还可以保留一个非正式日志,记录您的来源来自何处 -- 这在您查找新更新时很有帮助 -- 并且在监视安全公告列表时可能至关重要。

我在家中的一个系统(我正在使用的系统)是在我为自己采用这些策略之前组装的。我仍然不“知道”它与出厂“已安装”系统的所有不同之处。尽管事实上我对我的家用系统的配置做得很少,而且我是 *唯一* 使用它的人。

相比之下,我在工作中设置的系统(当我被推到系统管理员的角色时)都以这种方式配置 -- 由许多承包商和其他 MIS 人员管理,并且进行了大量的升级和软件包安装。尽管如此,我非常清楚哪些精确的元素是在初始安装和配置 *之后* 放入的。

3.5 将目录中的所有文件转换为小写。Justin Dossey, dossey@ou.edu

我注意到第 12 期 2c 技巧部分推荐了一些过于困难或不必要的程序。由于不止一个,我把它发送给您


#!/bin/sh
         # lowerit
         # convert all file names in the current directory to lower case
         # only operates on plain files--does not change the name of directories
         # will ask for verification before overwriting an existing file
         for x in `ls`
           do
           if [ ! -f $x ]; then
             continue
             fi
           lc=`echo $x  | tr '[A-Z]' '[a-z]'`
           if [ $lc != $x ]; then
             mv -i $x $lc
           fi
           done

哇。那是一个很长的脚本。我不会编写脚本来做这件事;相反,我会使用这个命令
for i in * ; do [ -f $i ] && mv -i $i `echo $i | tr '[A-Z]' '[a-z]'`;
done;
在命令行上。

贡献者说他编写脚本的方式是为了易于理解(见下文)。

在下一个技巧中,这个关于添加和删除用户的技巧,Geoff 在最后一步之前做得很好。重启?天哪,我希望他每次删除用户时都不会重启。您只需要执行前两个步骤。无论如何,该用户会运行什么样的进程?一个 irc 机器人?用一个简单的命令杀死进程

kill -9 `ps -aux |grep ^<username> |tr -s " " |cut -d " " -f2`
示例,用户名是 foo
kill -9 `ps -aux |grep ^foo |tr -s " " |cut -d " " -f2`
处理完这个问题后,让我们转到忘记的 root 密码。

Gazette 中给出的解决方案是最通用的解决方案,但不是最简单的解决方案。使用 LILO 和 loadlin,可以提供引导参数“single”以直接引导到默认 shell,而无需登录或密码提示。从那里,可以在输入“init 3”以启动多用户模式之前更改或删除任何密码。重启次数:1 另一种方式 重启次数:2

Justin Dossey

3.6 如何升级 Sendmail Paul Anderson, paul@geeky1.ebtech.net

我们从原始、干净的源代码开始。首先,获取 sendmail 源代码。我已经下载了 8.9.0 版本,您会注意到,这是前沿版本。我从 ftp.sendmail.org:/pub/sendmail/sendmail.8.9.0.tar.gz 获取了它

它大约 1Meg,考虑到我正在运行 8.7.6,我认为这值得努力。如果这有效,您无疑会听到消息,否则我无法在没有电子邮件的情况下发布新的 HOWTO 版本 :)

现在,一旦您下载了源代码,请解压缩它。它将在当前目录中创建一个名为 sendmail-8.9.0 的目录。更改到该目录,阅读 README 和 RELEASE_NOTES 文件(并对他们所做的更新感到惊讶)。现在,cd 进入 src。这是您大部分工作将要完成的地方。

快速说明:Sendmail 是一个小型、强大且编写良好的程序。sendmail 二进制文件本身在我的 5x86 133 和 32Megs RAM 上编译时间不到 5 分钟!整个编译和安装(不包括配置)花费不到 15 分钟!

我通常不在我的系统上运行 BIND,所以我找到了以下行


# ifndef NAMED_BIND
#  define NAMED_BIND    1       /* use Berkeley Internet Domain Server */
# endif

并将 1 更改为 0,如下所示


# ifndef NAMED_BIND
#  define NAMED_BIND    0       /* use Berkeley Internet Domain Server */
# endif

在 Debian 1.3.1 上,db.h 默认安装在 /usr/include/db 中,而不是 sendmail 希望找到它的 /usr/include 中。更改到 src、mailstats、makemap、praliases、rmail 和 smrsh 目录并执行以下命令

 ./Build -I/usr/include/db

完成此操作后,cd .. 并键入 make install。好了!Sendmail 8.9.0 版本现在应该已安装!当然,这是假设您已经有了原始配置。为了使一切在我的系统上顺利运行,因为我为使用 majordomo 的人托管免费邮件列表,我必须将以下内容添加到我的 /etc/sendmail.cf 的开头


O DontBlameSendmail=forwardfileinunsafedirpath, forwardfileinunsafedirpathsafe

Sendmail 8.9.0 现在对目录和文件权限相当迂腐,并且会抱怨别名或 .forward 文件中组或世界可写的文件和目录。虽然禁用这种迂腐不是一个好主意,但我只是在控制台上与一个人一起运行,并且我觉得允许这个小的安全漏洞是可以的。YMMV。

3.7 给新系统管理员的一些技巧。 Jim Dennis, jadestar@rahul.net

创建和维护 /README.`hostname` 和/或 /etc/README.`hostname` [或者可能是 /usr/local/etc/README.`hostname` - 维护。]

当然,从管理系统的 *第一天* 开始,就在在线日志文件中做笔记。您可以将 "vi /README.$(hostname)" 作为 root 的  /bash_logout 中的一行。另一种方法是编写一个 su 或 sudo 脚本,执行类似的操作

                function exit \
                        { unset exit; exit; \
                          cat ~/tmp/session.$(date +%y%m%d) \
                          >> /README.$(hostname) && \
                          vi /README.$(hostname)
                          }
                script -a ~/tmp/session.$(date +%y%m%d)
                /bin/su.org -

(使用 typescript 命令创建会话日志,并创建一个函数来自动化日志的追加和更新)。

我承认我还没有实施这种策略自动化 -- 到目前为止,我只是依靠自律。但是,我一直在考虑这个想法(甚至到了对脚本和 shell 函数进行原型设计的程度,正如您所见)。阻止我这样做的一件事是 'script' 命令本身。我认为我必须获取源代码并添加几个命令行参数(从命令行暂停/停止脚本记录),然后才能承诺使用它)。

我的最后一个建议(本轮)

Root 的路径应包含 'PATH= /bin'

就是这样。root 的路径上没有其他内容。root 所做的一切都由来自  /bin 的符号链接或别名或 shell 函数提供,或者是  /bin 中的脚本或二进制文件,或者是使用显式路径键入的。

这使任何以 root 身份运行的人意识到(有时甚至是痛苦地)他或她是如何信任二进制文件的。多用户主机的明智管理员将定期查看他或她的  /bin 和  /.*history 文件,以查找模式和漏洞。

真正有动力的管理员会发现可以自动化的序列、可以插入健全性检查的位置以及应该临时避免“root”权限的任务(启动编辑器、MTA 和其他具有复杂脚本功能的大型交互式程序,这些功能 *可能* 嵌入在透明或数据文件中 -- 例如臭名昭著的 vi ./.exrc 和 emacs ./.emacs 以及更阴险的 $EXINIT 和嵌入的页眉/页脚宏)。自然地,这些类型的命令可以使用类似以下的方式运行

                cp $data $some_users_home/tmp
                su -c $origcommand $whatever_switches
                cp $some_users_home/tmp $data
(...其中具体细节取决于命令)。

在大多数情况下,这些最后的预防措施对于家庭或“单用户”工作站来说是过分的 -- 但对于多用户(特别是公开暴露的系统,如 netcom 的系统)的管理员来说,它们是非常好的策略。

3.8 如何配置 xdm 的选择器以进行主机选择。Arrigo Triulzi, a.triulzi@ic.ac.uk

  1. 编辑启动 xdm 的文件(最可能是 /etc/rc/rc.6 或 /etc/rc.local),使其在 xdm 启动部分包含以下行。
            
    /usr/bin/X11/xdm
    exec /usr/bin/X11/X -indirect hostname
    
  2. 编辑 /usr/lib/X11/xdm/Xservers 并注释掉在本地机器上启动服务器的行(即以 0: 开头的行)
  3. 重启机器,您就可以远程工作了。

我添加这个是因为当我拼命尝试为我自己的子网设置它时,我花了一个星期才弄清楚所有问题。

注意:对于旧的 SLS (1.1.1),由于某些原因,您可以在 xdm 行之后保留 -nodaemon -- 这对以后的版本 不起作用


下一页 上一页 目录