
<chapt>安装以后

<p>系统安装完成后您还需要做一系列的工作来使系统更安全; 可以采取本章描述的一些步骤. 
当然这取决于您的设定, 为了防止被物理访问，你需要参阅 <ref id="bios-boot">,<ref id="lilo-passwd">,<ref
id="kernel-root-prompt">, <ref id="floppy-boot">, <ref
id="restrict-console-login">, 和 <ref id="restrict-reboots">.

<p>在连入任何网络前, 特别是将要连入公网之前, 至少应该执行一次安全更新(参阅 <ref id="security-update">).
最好, 您能对系统进行系统快照(参阅 <ref id="snapshot">).

<sect id="debian-sec-announce">订阅 Debian 安全公告邮件列表

<p>您可以通过订阅 debian-security-announce 邮件列表，接收 Debian 的安全公告(DSAs), 
关于 Debian 安全小组的更多内容, 参阅 <ref id="debian-sec-team">. 如何订阅邮件列表参见 
<url id="http://lists.debian.org">.

<p>由 Debian 安全小组签署的 DSAs 也可以从 <url id="http://security.debian.org"> 处获取.

<p>您还应该考虑订阅 <url
id="http://lists.debian.org/debian-security" name="debian 安全邮件列表"> 以获取对 Deian 操作系统的一般性安全问题讨论. 您可以与列表里的其他系统管理员, Debian 开发者, 安全工具软件上游开发者, 取得联系，他们可以回答您的问题，并提供建议.

<p>FIXME: 增加知识点?

<sect id="security-update">进行安全更新

<p>当软件包中发现新的安全问题时, Debian的维护者与软件开发者一般会在几天甚至几个小时内将其修复. 
问题修复后，新的软件包可以从 <url
name="http://security.debian.org" id="http://security.debian.org"> 得到.

<p>如果您安装了一个 Debian 的发行版, 必须考虑到, 这个版本发行后可能因为安全问题进行了多次更新. 
并且，还可能发行了些包括更新软件包的次发行版(Debian2.2 <em>potato</em> 有7个次发行版). 

<p>应当注意可移动介质(如果你使用了的话)的制作日期, 并检查安全站点有无更新. 
如果在系统连入互联网之前(你还没有连入互联网，不是吗?), 不能从别的系统下载安全更新包, 
(如果您没有外部防火墙的保护)可以考虑增加防火墙规则, 使之只能访问 security.debian.org, 进行更新. 
<ref id="fw-security-update"> 提供了一个示例配置.

<p><em>注:</em>从 Debian woody 3.0 开始, 安装完成后, 系统提供一个安全更新的提示. 
如果回答'是', 安装系统将给出相应步骤为您的系统添加安全更新的源. 如果您可以连入互联网, 
就可以下载并进行安全更新. 如果您升级的 Debian 是一个早期版本或者您没有要求系统进行更新, 
您应该采取下边的步骤.

<p>手工更新系统, 将下边一行加入您的 <file>sources.list</file>. 
这样每当您更新您的系统时, 您将自动的进行安全更新.

<example>
  deb http://security.debian.org/ stable/updates main contrib non-free
</example>

<p>然后，您可以使用 <package>apt</package> 或
<package>dselect</package> 进行升级:

<list>
<item>使用 <package>apt</package>, 做如下操作:
<example>
# apt-get update
# apt-get upgrade
</example>
<item>如果使用 <package>dselect</package>, 那么, 首先[U]pdate,
然后 [I]nstall 最后, [C]onfigure the installed/upgraded packages.
</list>

<p>如果愿意, 您也可以在 <file>/etc/apt/sources.list</file> 中加入 deb-src 行. 更多内容参阅 
<manref name="apt" section="8">.

<p>注: 您 <em>不</em> 必加入如下行:

<example>
  deb http://security.debian.org/debian-non-US stable/non-US main contrib non-free
</example>
<p>这是因为 security.debian.org 位于 non-US 站点上, 并且没有单独的 non-US 内容.

<sect id="bios-boot">修改 BIOS (再次)

<p>还记得 <ref id="bios-passwd"> 吗? 很好, 当你不必从可移动介质启动的时候, 
应当更改 BIOS 的默认设置，使之<em>只能</em>从硬盘引导. 确保不会丢失 BIOS 密码, 否则, 
硬盘启动失败的时候您将不能回到 BIOS 和更改设置, 例如从 CD-ROM 启动.

<p>其它不太安全但很方便的方式是, 设置系统从硬盘引导, 失败后则尝试从可移动介质引导. 
通常是这样设置的, 因为 BIOS 密码不常使用, 很容易忘记.

<sect id="lilo-passwd">设置 LILO 或 GRUB 密码
<p>
任何人都能很容易的通过在启动提示符后输入 <tt>&lt;name-of-your-bootimage&gt; init=/bin/sh</tt> 
来获取 root-shell, 并修改您的密码. 修改密码后, 重新启动, 就获取了 root 权限, 
可以对您的系统做任何想做的事情. 设置 LILO 或 GRUB 密码后, 不是 root 登录系统, 就不会获取 root 密码.
<p>
您应该为启动加载器设置一个密码以确保这类事情不会发生. 您可以选择设置全局密码或为某个影像设置密码.
<p>
对于LILO 您需要编辑配置文件文件 <file>/etc/lilo.conf</file> 增加 <tt>password</tt> 和 <tt>restricted</tt>, 如下所示.

<example>
  image=/boot/2.2.14-vmlinuz
     label=Linux
     read-only
     password=hackme
     restricted
</example>

<p>
然后重新运行 lilo. 这样启动时, lilo 总是提示输入密码, 不管是否使用了启动参数. 
缺省 <file>/etc/lilo.conf</file> 的权限是 root 可读写，root 组只读.

<p>
如果您使用 GRUB 代替 LILO, 则要编辑 <file>/boot/grub/menu.lst</file>, 在顶部加入下边两行(当然, 用您的密码替换hackme).
这样可以防止用户编辑起动选项. <tt>timeout 3</tt> 是指 <prgn>grub</prgn> 使用默认启动选项前仅有3秒延迟.

<example>
  timeout 3
  password hackme
</example>

<p>您可以加密存储密码, 来更进一步强化密码. <prgn>grub-md5-crypt</prgn> 工具可以生成密码的hash值, 
它与grub的加密算法(md5)相兼容. 
使用如下方法在 <prgn>grub</prgn> 中指定使用 md5 格式密码:
<example>
  timeout 3
  password --md5 $1$bw0ez$tljnxxKLfMzmnDVaQWgjP0
</example>

--md5 参数通知 <prgn>grub</prgn> 执行 md5 认证过程. 后边的密码是 hackme 的 md5 转换. 
使用 md5 加密方法相对于明码通讯是一个很好的选择. 更多关于 <prgn>grub</prgn> 密码的信息可以从 <package>grub-doc</package> 软件包找到.

<sect id="kernel-root-prompt">取消 root 的提示等待

<p>Linux2.4 kernel 在加载了 cramfs 文件系统后, 提供一个访问 root shell 的方法, 
加载cramf文件系统后, 将要启动的时候, 出现提示信息, 此时允许管理员输入具有 root 
权限的可执行 shell 命令, 通常用于自动检测失败后手动装载模块. 缺省为 <prgn>initrd</prgn> 的 
<file>linuxrc</file>. 随后出现如下信息:
<example>
  Press ENTER to obtain a shell (waits 5 seconds)
</example>

<p>可以通过编辑 <file>/etc/mkinitrd/mkinitrd.conf</file> 做如下设置, 来修改这一特性:
<example>
  # DELAY  The  number  of seconds the linuxrc script should wait to
  # allow the user to interrupt it before the system is brought up
  DELAY=0
</example>
<p>然后重新生成您的 ramdisk image. 例如您可以这样做:
<example>
  # cd /boot
  # mkinitrd -o initrd.img-2.4.18-k7 /lib/modules/2.4.18-k7
</example>
<p>或 (推荐):
<example>
  # dpkg-reconfigure -plow kernel-image-2.4.x-yz
</example>
<p>注意，Debian3.0 woody 允许用户安装 2.4 kernel(根据<em>喜好</em>选择), 
<em>但是</em> 缺省 kernel 是 2.2 (除了在某些平台上没有移植 kernel2.2). 
如果您认为这是一个 Bug, 提交前参见 <url id="http://bugs.debian.org/145244" name="Bug 145244">.

<sect id="floppy-boot">禁用软盘启动
<p>
在 Debian2.2 以前, 缺省 MBR 并不是主要引导方式, 并且有一个很容易进入系统:

<list>
<item>引导时按下 shift 键, 出现 MBR 提示符

<item> 然后按 F, 这样您的系统将从软盘引导. 这样就可作为root登录.
</list>

<p>如下命令可以改变这一特性:

<example>
  lilo -b /dev/hda
</example>

<p>现在 LILO 被装入MBR.  在 <file>lilo.conf</file> 中加入 <tt>boot=/dev/hda</tt> 可以达到同样效果. 
还有其他的方法完全禁用 MBR 提示符:

<example>
  install-mbr -i n /dev/hda
</example>

<p>另一方面, 这个"后门", 许多人还没有意识到, may save your skin as well if you run into deep trouble with your installation for whatever reasons.

<p>FIXME 检查是否适用于2.2或2.1?
INFO: Debian 2.2 的引导盘确实没有安装 mbr, 而仅仅安装了 LILO.


<sect id="restrict-console-login">限制控制台登录 

<p>一些安全策略或许强制管理员通过控制台用普通用户/密码登录系统, 然后变成超级用户(通过<prgn>su</prgn> 或 <prgn>sudo</prgn>). 
可以通过编辑 <file>/etc/login.defs</file>文件实现此策略, 当使用 PAM 时则是 <file>/etc/securetty</file> 文件:

<list>

<item><file>login.defs</file>, 编辑 CONSOLE 变量, 为终端定义一个允许 root 
登录文件或列表

<item><file>securetty</file> 
<footnote>
<file>/etc/securetty</file> 是 <package>login</package> 软件包的配置文件.
</footnote>
通过添加/移除它的终端来完成配置. 如果您希望只允许本地终端登录, 那么您需要 <em>console</em>,<em>ttyX</em> 
<footnote>
或 <em>ttyvX</em> 对于 GNU/FreeBSD 来说, 在 GNU/KNetBSD 中则是 <em>ttyE0</em> .
</footnote>
和 <em>vc/X</em> (如果使用 <em>devfs</em> 设备), 您可能还想添加 <em>ttySX</em> 
<footnote>
或 <em>comX</em> 对于 GNU/Hurd 来说, GNU/FreeBSD 中则是 <em>cuaaX</em> , 
GNU/KNetBSD 中是 <em>ttyXX</em>.
</footnote>
如果您使用串行终端进行本地访问(这里的 X 是一个整数, 根据您在 <file>/etc/inittab</file><footnote>搜索 <em>getty</em> 调用calls.</footnote> 中定义的虚拟终端的数量, 您可以有多个实例 
<footnote>
在 <em>woody</em> 中缺省配置包括 12 个本地 tty 和 vc 控制台, 也就是 <em>控制台</em> 设备, 但是不允许远程登录. 在<em>sarge</em> 中, 缺省配置为 tty 和 vc console 提供 64 个控制台,如果您用不了这么多控制台, 将其删除也没有问题.
</footnote>). 有关终端设备的更多信息F参阅
<url id="http://tldp.org/HOWTO/Text-Terminal-HOWTO-6.html" name="Text-Terminal-HOWTO">

</list>

<p>使用 PAM 时, 可以通过配置 <file>/etc/pam.d/login</file> 文件来完成对于登录过程的其他更改, 
这可能包括用户和组给定时间的约束. 很重要的一个特性是, 可以禁止空密码. 这一特性可以通过把下行中的 <em>nullok</em> 删除来实现:

<example>
  auth       required   pam_unix.so nullok
</example>

<sect id="restrict-reboots"> 限制系统通过控制台重起

<p>如果您的系统配有一个键盘, 任何人(是的 <em>任何人</em>)都可以用它重启系统, 
并不一定要登入系统. 这也许符合, 或违背了您的安全策略. 如果你想对此有所限制, 
则必须检查 <file>/etc/inittab</file> 文件中含有 ctrlaltdel 并带有 <tt>-a</tt> 选项
(记得文件修改后运行 <tt>init q</tt>). 在Debian中缺省包含此选项:

<example>
  ca:12345:ctrlaltdel:/sbin/shutdown -t1 -a -r now
</example>

<p>现在, 为了允许 <em>一些</em> 用户可以关闭系统, 如<manref section="8" name="shutdown">
中所述，您需要创建 <file>/etc/shutdown.allow</file> 文件, 并包括那些能启动系统用户的名字. 
当使用 <em>三指礼</em>(即 ctrl+alt+del)时, 系统就会检查用户列表, 如果用户不在列表中, <prgn>shutdown</prgn>关机<em>不会</em>重起系统.
 
</sect>

<sect>正确的挂接分区
<p>
当挂接 ext2 分区时, 有些附加选项您可以 mount 时使用, 或写入 <file>/etc/fstab</file>. 
例如，这是我的fstab中 <file>/tmp</file> 分区部分:

<example>
  /dev/hda7    /tmp    ext2    defaults,nosuid,noexec,nodev    0    2
</example>

<p>
注意选项部分的不同, 选项 <tt>nosuid</tt> 将完全忽略 setuid 和 setgid 位, 
<tt>noexec</tt> 禁止任一个程序在挂接点上运行, <tt>nodev</tt> 则忽略设备. 这听起来很棒, 但是这
<list>
<item>只适用于 ext2 文件系统
<item>很容易绕过
</list>

<p>选项 <tt>noexec</tt>, 禁止二进制程序直接执行, 但很容易绕过:

<example>
  alex@joker:/tmp# mount | grep tmp
  /dev/hda7 on /tmp type ext2 (rw,noexec,nosuid,nodev)
  alex@joker:/tmp# ./date
  bash: ./date: Permission denied
  alex@joker:/tmp# /lib/ld-linux.so.2 ./date
  Sun Dec  3 17:49:23 CET 2000
</example>

<p>然而, 很多脚本小子会在 <file>/tmp</file> 目录下创建和执行文件. 如果找不到别的线索, 
他们会利用这个 pit. 换句话说, 用户将不会被欺骗在 <file>/tmp</file> 目录下执行一个木马程序, 
例如偶尔将 <file>/tmp</file> 加入他的PATH中.

<p>并且事先说明，一些脚本可能依赖于 <file>/tmp</file> 执行. 特别是，Debconf 就有(有过?)这样的问题, 更多信息参见
<url id="http://bugs.debian.org/116448" name="116448">.

<p>
下边是一个更加详尽的例子. 注意, 虽然: <file>/var</file> 可以被设为 noexec, 但一些软件<footnote>这包括软件包管理工具 <package>dpkg</package> 因为安装 (post,pre) 和删除 (post,pre) 脚本在 <file>/var/lib/dpkg/</file> 下 和 Smartlist</footnote>把它们的程序存放在 <file>/var</file> 目录下. nosuid 选项也是一样.

<example>
/dev/sda6       /usr            ext2    defaults,ro,nodev       0       2
/dev/sda12      /usr/share      ext2    defaults,ro,nodev,nosuid        0       2
/dev/sda7       /var            ext2    defaults,nodev,usrquota,grpquota          0       2
/dev/sda8       /tmp            ext2    defaults,nodev,nosuid,noexec,usrquota,grpquota    0       2
/dev/sda9       /var/tmp        ext2    defaults,nodev,nosuid,noexec,usrquota,grpquota    0       2
/dev/sda10      /var/log        ext2    defaults,nodev,nosuid,noexec    0       2
/dev/sda11      /var/account    ext2    defaults,nodev,nosuid,noexec    0       2
/dev/sda13      /home           ext2    rw,nosuid,nodev,exec,auto,nouser,async,usrquota,grpquota                0       2
/dev/fd0        /mnt/fd0        ext2    defaults,users,nodev,nosuid,noexec      0       0
/dev/fd0        /mnt/floppy     vfat    defaults,users,nodev,nosuid,noexec      0       0
/dev/hda        /mnt/cdrom      iso9660 ro,users,nodev,nosuid,noexec            0       0
</example>

<sect1>将 <file>/tmp</file> 设为 noexec
<p>如果将 <file>/tmp</file> 设为 noexec 您想要安装新软件时应当小心, 
因为一些程序可能使用它进行安装. <package>apt</package> 就是这样一个程序
(参见 <url id="http://bugs.debian.org/116448">)是否正确配置了 
<tt>APT::ExtractTemplates::TempDir</tt> (参见<manref name="apt-extracttemplates" section="1">). 
您可以在 <file>/etc/apt/apt.conf</file> 中设置此变量为有执行权限的其他目录.

<!-- This is a duplicate of the example a few paragraphs up -->
<p>关于 noexec, 请注意它可能会影响到您的安全. 
考虑一下:
<example>
  $ cp /bin/date /tmp
  $ /tmp/date
  (does not execute due to noexec)
  $/lib/ld-linux.so.2 /tmp/date
  (works since date is not executed directly)
</example>

<sect1>设置 /usr 为只读
<p>如果将 <file>/usr</file> 设为只读, 就不能在您的 Debian GNU/Linux 系统中安装新软件了. 
您必须首先以读写方式重新挂接, 安装软件, 然后以只读方式重新挂接. 最新版的 <package>apt</package>(Debian 3.0 'woody') 可以设为在安装软件之前之后运行命令, 因此您也许想正确的设置它.

<p>修改 <file>/etc/apt/apt.conf</file> 并加入:
<example>
  DPkg
  {
      Pre-Invoke  { "mount /usr -o remount,rw" };
      Post-Invoke { "mount /usr -o remount,ro" };
  };
</example>

<p>注意 Post-Invoke 也许会失败并给出 "/usr busy" 错误信息. 这主要因为在更新过程中, 您使用了被更新的文件. 
不要太在意. 确定不再被使用并且手工手动运行.

<sect>提供安全的用户访问

<sect1 id="auth-pam">用户认证: PAM

<p>PAM (可插入认证模块) 允许系统管理员选择应用程序如何认证用户. 
注意只有在编译应用程序时加入 PAM 支持才可能起作用. Debian 2.2 中的大多数应用程序是内建支持的. 
此外, Debian 在2.2版本以前并不支持 PAM. 当前任何一个 PAM-enabled 服务的默认设置都是仿照 UNIX 认证
(关于 Debian 中 PAM 服务的更多信息见 <file>/usr/share/doc/libpam0g/Debian-PAM-MiniPolicy.gz</file>).


<p>每个带有PAM支持的服务在 <file>/etc/pam.d/</file> 下都有一个配置文件, 
可以通过修改它来完成配置:

<list>
<item>认证使用什么样的后端.
<item>会话使用什么样的后端.
<item>如何进行密码检测.
</list>

<p>
下边扯的远了点, 如果要更多了解您可以阅读<url id="http://www.kernel.org/pub/linux/libs/pam/Linux-PAM-html/pam.html"
name="Linux PAM 系统管理员的指南"> (在 <url id="http://www.kernel.org/pub/linux/libs/pam/" name="PAM主发行站点">), 
此文档在 <package>libpam-doc</package> 中也有提供.

<p>PAM 为您提供了在没有用户信息的情况下进行分步认证的可能. 您可以依靠伯克利数据库和普通的<file>passwd</file>文件, 
并且用户只有两个都通过认证才能登录. 您可以对 PAM 作更多限制, 以使您的系统更加宽松. 如过这样您要小心. 
一条典型的配置行有控制域作为其第二个元素.
<!-- Second in mine (old Debian v2.0 though), check this! (FIXME) (era) -->
通常这是<tt>必需的</tt>, 当一个模块失败后，返回一个认证错误.
<!-- Lots of fields in mine are "required", please elaborate? (FIXME) (era) -->

<p>我喜欢首先对 PAM 应用加入 MD5 支持, 因为这有助于免受字典攻击(使用MD5密码可以更长). 
应该将以下两行加入 <file>/etc/pam.d/</file> 下的所有文件中, 以控制对机器的访问, 如<tt>login</tt>和<tt>ssh</tt>.

<example>
  # Be sure to install libpam-cracklib first or you will not be able to log in
  password   required     pam_cracklib.so retry=3 minlen=12 difok=3
  password   required     pam_unix.so use_authtok nullok md5
</example>


<p>这样, 有什么作用? 第一行加载 cracklib PAM 模块, 提供密码强力检查, 
提示对于一个新密码最短为12个字符, 至少有3个字符与旧口令不同, 允许3次尝试. 
这个软件包依赖于 wordlist (譬如 
<package>wenglish</package>, <package>wspanish</package>, 
<package>wbritish</package>...), 确保您安装适合您的语言的(否则它也许根本不起作用).
<footnote>
然而, 在 Debian 3.0中软件包的依赖关系还没有修复. 请参阅 <url id="http://bugs.debian.org/112965" name="Bug #112965">.
</footnote>
第二行说明标准认证模块带有 MD5 密码支持并且允许零长度密码. <tt>use_authtok</tt> 
直接从前边的模块接收密码. 
<p>可以在 <file>/etc/pam.d/login</file> 中加入一下行, 以确保 root 用户只能从本地终端登录:

<example>
  auth     requisite  pam_securetty.so
</example>

<p>然后, 您需要在 <file>/etc/securetty</file> 中修改 root 用户可以直接登录的终端列表. 您也可以, 
启用 <tt>pam_access</tt> 模块, 修改允许更常用的 <file>/etc/security/access.conf</file>, 以进行
 fine-tuned 的访问控制, 但是(很不幸)这缺少合适的日志信息(使用 PAM 登录不是标准化的, 特别是对于无益问题的处理).
过一会我们还会回来配置 <file>access.conf</file>.
  	 
<p>
最后, 但不是最不重要, 应当在 <file>/etc/pam.d/login</file> 中启用下边的内容, 以进行用户资源限制.
然后您应该在 <file>/etc/security/access.conf</file> 中增加用户 root 可以登录到系统的终端. 
最后如果您要设置用户限制, 至少要设置一下行.

<example>
  session  required   pam_limits.so
</example>

<p>这样就可以限制用户允许使用的系统资源(参见后面的 <ref id="user-limits">). 
例如, 您可以限制同时登录用户的数量(一个指定的用户组，或系统范围), 进程数量, 内存容量...

<p>现在, 编辑 <file>/etc/pam.d/passwd</file>, 更改第一行. 您使用 MD5 密码需加入 "md5" 选项, 
将密码的最小长度由4改为6(或更长), 并设置最大长度,如果需要的话. 例似如下行:

<example>
  password   required   pam_unix.so nullok obscure min=6 max=11 md5
</example>

<p>如果您想要保护 su, 以便使得只有一些用户可以使用它成为 root 用户, 
您需要在系统里增加一个新组"wheel" (这是最干净的方式, 因为没有文件有这样的组许可). 
添加 root 和其他应当能使用 <prgn>su</prgn> 的用户到这个组. 然后在 <file>/etc/pam.d/su</file> 中加入如下行:

<example>
  auth        requisite   pam_wheel.so group=wheel debug
</example>

<p>以确保只有组 "wheel" 的用户可以使用 <prgn>su</prgn> 成为root. 
其它用户不能成为 root. 事实上如果他们试图成为 root 将会得到一条拒绝信息.

<p>如果您只要某些用户需要 PAM 服务的认证, 使用文件存储允许(或拒绝)登录的用户列表非常容易做到这一点.
假设你只允许用户 'ref' 使用 <prgn>ssh</prgn> 登录. 把他加入到 <file>/etc/sshusers-allowed</file> 文件,
并把如下行加入<file>/etc/pam.d/ssh</file>:

<example>
  auth        required    pam_listfile.so item=user sense=allow file=/etc/sshusers-allowed onerr=fail
</example>

<p>最后，但不是至少，创建 <file>/etc/pam.d/other</file> 文件并加入如下内容:

<example>
  auth     required       pam_securetty.so
  auth     required       pam_unix_auth.so
  auth     required       pam_warn.so
  auth     required       pam_deny.so
  account  required       pam_unix_acct.so
  account  required       pam_warn.so
  account  required       pam_deny.so
  password required       pam_unix_passwd.so
  password required       pam_warn.so
  password required       pam_deny.so
  session  required       pam_unix_session.so
  session  required       pam_warn.so
  session  required       pam_deny.so
</example>

<p>这些内容为所有的支持 PAM 的应用程序提供了很不错的默认设置(默认访问拒绝).


<sect1 id="user-limits">资源的限制使用: <file>limits.conf</file> 文件

<p>
您应该仔细的研究一下这个文件. 您可以在此处定义用户资源限制. 如果您使用PAM, 
应该使用 <file>/etc/security/limits.conf</file> 而不是 <file>/etc/limits.conf</file>.

<p>如果您不限制资源使用, <em>任何</em>可以获取合法 shell 的用户(甚至攻击您的系统的入侵者) 
都可以耗尽系统可能提供资源如 CPU, 内存, 堆栈, 等等. 这种<em>资源耗尽</em>问题只能通过 PAM 来解决. 
注意, 还有别的方法对一些 shell 设置资源限制(例如, <prgn>bash</prgn> 有 <prgn>ulimit</prgn>, 参阅 <manref section="1" name="bash">)， 
但因为这些 shell 提供的限制方法不同且用户有可能更换 shell(参阅 <manref section="1" name="chsh">)， 
最好的方法还是使用 PAM 模块.

<p>更多信息请阅读:
<list>

<item><url
id="http://www.samag.com/documents/s=1161/sam0009a/0009a.htm"
name="配置文章">.

<item> <url
id="http://seifried.org/security/os/linux/20020324-securing-linux-step-by-step.html"
name="Seifried 的 Securing Linux Step by Step"> 中 <em>用户限制概述</em> 部分.

<item><url id="http://seifried.org/lasg/users/" name="LASG"> 的 
<em>限制与监测用户</em> 部分.

</list>

<p>FIXME: 在这里提供一个经典的 <file>limits.conf</file> 文件

<sect1>用户登录: 编辑 <file>/etc/login.defs</file>
<p>
下一步就是编辑基本的配置以影响用户登录.

<p>这个变量可以设的更大一点, 以增强终端登录的安全性. 注意这个文件不是 PAM 配置的一部分, 它是 
<tt>login</tt> 和 <tt>su</tt> 程序的一个配置文件, 因此, 它不是针对这两个程序被间接调用时的协调工作的
(<prgn>getty</prgn>程序提供初始 login 提示附对 <prgn>login</prgn> 的调用).


<example>
  FAIL_DELAY          10
</example>

如果键入了一个错误的密码, 
可能是攻击者(或正常用户!)必须等待10 秒才能得到新的登录提示, 如果您(手工)测试密码这将相当费时. 
注意这样一个事实, 如果您使用 getty 以外的程序, 如 <prgn>mingetty</prgn>, 则这个设置并没有什么作用.

<example>
  FAILLOG_ENAB        yes
</example>

如果您使用这个变量, 将会记录失败的登录. 这对跟踪尝试暴力攻击者非常重要.

<example>
  LOG_UNKFAIL_ENAB    yes
</example>

<p>如果您设置变量 <var>FAILLOG_ENAB</var> 为 yes, 您也应该将这个变量设为 yes. 
这将记录登录失败的未知用户名. 如果这样设置, 要确保日志文件设置了正确的访问权限(例如 640，和适当的组设定， 如 adm),
因为有时用户会把密码当作用户名输入, 你当然不希望别人看到这些内容.

<example>
  SYSLOG_SU_ENAB      yes
</example>

<p>启用这个参数将在 <file>syslog</file> 中记录试图 <prgn>su</prgn> 的操作. 
对于重要的机器这相当重要, 同时也要注意这可能引起保密性问题.

<example>
  SYSLOG_SG_ENAB      yes
</example>

<p>与 <var>SYSLOG_SU_ENAB</var> 相同，但用于 <prgn>sg</prgn> 程序.

<example>
  MD5_CRYPT_ENAB      yes
</example>

<p>如上述, MD5 密码极大的减少了字典攻击问题, 因为您可以使用更长的密码. 
如果您使用 slink，使用这个选项前请阅读MD5的相关文档. 否则在PAM中设置这一选项

<example>
  PASS_MAX_LEN        50
</example>

<p>如果在 PAM 配置中启用 MD5 密码选项, 这个变量值应该其设置相同.


<sect1>限制ftp: 编辑 <file>/etc/ftpusers</file>
<p>
文件 <file>/etc/ftpusers</file> 包含不允许使用 ftp 登录主机的用户名单. 
如果你真的想允许 ftp 就使用这个文件(通常不推荐使用, 因为它使用明文传送密码).
如果您的守护进程支持 PAM, 您也可用它来定义某些服务对用户的允许和拒绝.

<p>FIXME(BUG): 这是一个缺陷，Debian 中缺省的 <file>ftpusers</file> 
不包括所有管理员用户(在 <package>base-passwd</package> 中).

<sect1>使用 su

<p>
如果您真的需要系统中的用户变为超级用户, 例如, 安装软件包或增加用户, 您可以使用 <prgn>su</prgn> 
命令来改变身份. 您应该设法避免任何人使用 root 登录系统, 而应当使用su. 实际上, 
最好的解决办法是删除 <prgn>su</prgn>, 而是使用 <prgn>sudo</prgn>, 因为它比 <prgn>su</prgn> 有更多特点. 
但是, <prgn>su</prgn> 在类unix系统上 更具通用性.


<sect1>使用 sudo

<p>
<prgn>sudo</prgn> 允许用户执行以其他用户身份定义的命令, 甚至是 root. 
如果用户被加入 <file>/etc/sudoers</file> 并且通过认证, 它就能运行 <file>/etc/sudoers</file> 定义的命令. 
违规, 如密码不正确, 或者试图运行没有授权的程序, 将被记录下来, 并邮寄给 root.

<sect1>禁止管理员远程访问
<p>您应当修改 <file>/etc/security/access.conf</file> 以禁止管理员远程登录. 
这样用户就需要使用 <prgn>su</prgn> (或 <prgn>sudo</prgn>), 无论本地用户什么时候使用管理员权限, 就都可以进行跟踪了. 

<p>您需要在 <file>/etc/security/access.conf</file> 中加入如下行, 缺省的 Debian 配置文件中这一行被注释掉了:
<example>
   -:wheel:ALL EXCEPT LOCAL
</example>


<sect1 id="user-restrict">限制用户访问
<p>记住, 在<file>/etc/pam.d/</file> 中对所有服务启用 <tt>pam_access</tt> 模块(或使用默认配置), 如果您希望自己的修改对 <file>/etc/security/access.conf</file> 产生影响.

<p>有时候您也许认为需要创建本地用户以执行特定的服务(pop3 邮件服务或 ftp). 
动手前, 首先记得, Debian GNU/Linux 系统中的 PAM 工具允许使用各种外部地址服务器提供的 libpam 软件包来认证用户(radius, ldap, 等等).

<p>如果需要建立此类用户, 且考虑到用户有可能远程访问系统. 则可以通过给用户指定一个空(<file>/dev/null</file>)shell(需要在 <file>/etc/shells</file> 中列出) 
来对此作出修正. 如果您想允许用户访问系统但要限制其访问范围, 则可以使用 <file>/bin/rbash</file>, 
这与 <prgn>bash</prgn> 加入 <tt>-r</tt> 选项等效 (<em>RESTRICTED SHELL</em> 参见<manref name="bash"
section="1">). 请注意即使是受限的 shel, 用户访问交互式程序(可能允许一个执行 subshell), 也能绕过shell的限制.

<p>Debian 当前的 unstable 版本(也许在下一个稳定版中)提供了 <file>pam_chroot</file> 模块(在<package>
libpam-chroot</package>中). 除此之外的另一种选择是对提供远程登录的服务进行<prgn>chroot</prgn> 
(<prgn>ssh</prgn>, <prgn>telnet</prgn>).
<footnote><package>Libpam-chroot</package> 还未经过完整测试, 其用于 <prgn>login</prgn>, 但是为其他程序配置环境十分麻烦</footnote>

<p>如果您要对通过 ssh 访问你的系统的用户有所限制, 可以按照自己的需求来编辑
<file>/etc/security/access.conf</file> .

<p>关于 <prgn>chroot</prgn> 用户如何通过 <prgn>ssh</prgn> 服务访问系统的内容参见<ref
id="chroot-ssh-env">.

<sect1>用户检测

<p>
如果您是个偏执狂, 也许希望添加一个系统范围的配置文件来来检测用户在您的系统里所做的操作.
本部分提供一些不同工具使用的小窍门.
<sect2>输入输出检测脚本
  	 
  	 <P>您可以使用本 <prgn>script</prgn> 命令来审核用户运行的命令和这些命令的输出. 您不能把 <prgn>script</prgn> 配置为一个 shell(即使您把它添加到 <file>/etc/shells</file> 中). 但是您可以配置 shell 的初始化程序运行下边的内容:
  	 
  	 <example>
umask 077
exec script -q -a "/var/log/sessions/$USER
  	 </example>
  	 
  	 <p>当然, 如果您要在系统范围内设置, 那就意味着 shell不嗯个连续的读取个人初始化文件(因为 
	shell已经被 <prgn>script</prgn> 修改). 另一种可用的方法是在用户的初始化文件中完成这一工作(但, 
	这样的话用户就可能将其删除, 参阅下边的内容)
  	 </p>
  	 
  	 <p>您还需要在检测目录中(这个例子中是 <file>/var/log/sessions/</file>)配置此文件,
	这样用户就可写入内容, 但是不能删除. 例如, 可以通过预先创建用户会话文件, 并用 <prgn>chattr</prgn>
	设置 <em>append-only</em> 标志来完成这一配置.
  	 </p>
  	 
  	 <p>另一个对系统管理有用的方案, 其包括日期信息:
  	 
  	 <example>
umask 077
exec script -q -a "/var/log/sessions/$USER-`date +%Y%m%d`"
  	 </example>
  	 
  	 <sect2>使用 shell 的历史记录文件
  	 
  	 <p>如果您想回顾一下您在 shell 中键入的内容(不是它们的输出), 则可以配置系统范围的
	<file>/etc/profile</file> 配置环境将所有的命令保存到 <tt>history</tt> 文件.
  	 这个系统范围的配置需要确保用户不能将这种检测删除. 这就需要您确保所有的用户都使用同样的 shell.</p>
  	 
  	 <p>例如, 对于 bash, <file>/etc/profile</file> 文件应作类似下边的设置
  	 <footnote>
  	 设置 HISTSIZE 为一个较大的数字对于某些shell可能会引起一些问题, 因为 history 会保存在用于每个用户的会话内存中.
	 所以您应当估计一个比较合适的值, 并备份用户的 history 文件 (如果因为某种原因需要保存所有用户的 history)
  	 </footnote>
  	 :
<example>
  HISTFILE=~/.bash_history
  HISTSIZE=10000
  HISTFILESIZE=999999
  # Don't let the users enter commands that are ignored
  # in the history file
  HISTIGNORE=""
  HISTCONTROL=""
  readonly HISTFILE
  readonly HISTSIZE
  readonly HISTFILESIZE
  readonly HISTIGNORE
  readonly HISTCONTROL
  export HISTFILE HISTSIZE HISTFILESIZE HISTIGNORE HISTCONTROL
</example>

<p>这样, 用户只能在 <file>.bash_history</file> 文件中增加附加信息. 
您<em>还</em>需要使用 <prgn>chattr</prgn> 程序将 <file>.bash_history</file> 设为对所有的用户都是 <em>append-only</em>.
<footnote>
没有只能添加标志,用户将可以通过运行 <prgn>  >.bash_history</prgn> 清空历史文件
</footnote>.

<p>注意, 您应当在每个用户的 <file>.profile</file> 文件引入上边的配置. 但另一方面, 您应当设置正确的权限, 
以防止用户修改此文件. 这包括: 使用户的主目录并 <em>不</em> 隶属于用户(否则, 他就可以删除这个文件), 
但同时又要使他对于 <file>.profile</file> 配置文件有读权限, 并对 <file>.bash_history</file> 文件有写权限. 

<sect2>使用帐号工具完成用户检测
  	 
<p>前边的例子是一个配置用户检测的简单方法, 但是对于复杂系统或用户根本就不(或很少)使用 shell 的系统, 用处不大.
如果碰到这种情况, 您需要求助于<package>acct</package>, 这个帐号检测工具. 这个工具会在空闲磁盘上记录用户或系统进程运行的所有命令.
  	 
<p>当启用的帐号, 所有的有关进程和用的信息保存在 <file>/var/account/</file> 目录下, 更确切的是在 
<file>pacct</file> 中. 这个帐号软件包包括一些分析这些数据的工具(<prgn>sa</prgn> 和 <prgn>ac</prgn>).
  	 
<sect2>其它的用户检测方法


为 <file>.profile</file> 文件设置 <em>inmutable</em> 标志位(同样用到 <prgn>chattr</prgn>)是个不错的选择

<p>如果您非常的偏执, 想要验证用户的每个命令, 您可以编辑 <prgn>bash</prgn> 的源码,
 使其将用户所有的输入写入其他的文件. 或者使用 <package>ttysnoop</package> 频繁监听每个新的 ttys
<footnote>tty 是用于本地登录或通过 ssh 和 telnet 远程登录的</footnote>
并输入到一个文件. <package>snoopy</package>(参见 <url id="http://sourceforge.net/projects/snoopylogger/" name="the project page">)
是另一个有用的程序, 其对用户透明，作为一个库，提供一个 <var>execve()</var> 调用 wrapper, 
任何执行的命令都通过 <tt>authpriv</tt> 工具被 <prgn>syslogd</prgn> 记录(通常被存放在 <file>/var/log/auth.log</file>).

<sect1>检查用户的 profile

<p>如果您要<em>查看</em>用户通常在做些什么, 可以在用户连入时使用包括所有登录信息的 <file>wtmp</file> 数据库. 
有几个工具可以处理这个文件, 其中 <prgn>sac</prgn> 可以对每个用户产生一个 profile 文件，显示此用户经常登录的时间段.

<p>如果您启用了记账系统, 您还可以用其提供的工具来确定用户的登录时间和执行的命令. 

<sect1>设置用户的 umask

<p>根据您的用户策略, 您也许想修改用户间分享信息的方法, 即新建文件的默认权限. 
这可以通过正确设定所有用户的 <tt>umask</tt> 来实现. 您可以在 <file>/etc/limits.conf</file>,
<file>/etc/profile</file>, <file>/etc/csh.cshrc</file>,
<file>/etc/csh.login</file>, <file>/etc/zshrc</file> 或者其他的配置文件(依赖与您系统中安装的shell)中设定 <var>UMASK</var>.
这些文件最后一个装载的优先级最高. 顺序是: PAM 的 <file>limits.conf</file>，用户 shell 的系统缺省设置,
用户的shell(他的 <file>~/.profile</file>,
<file>~/.bash_profile</file>...)

<p>Debian 的缺省 <tt>umask</tt> 设置是 022, 这意味着, 文件(和目录)可由组用户和系统里的其他用户读取和访问. 
如果您觉得对于系统来说这样太过宽松, 则需要修改所有 shell (和PAM)的 umask 设定, 不要忘记修改 <file>/etc/skel/</file> 
下的文件, 因为这些是使用 <prgn>adduser</prgn> 创建用户的默认设置.

<p>注, 但是只要用户愿意, 他们可以修改自己的 <tt>umask</tt> 设置, 使得限制更宽松，或更加苛刻.

<sect1>限制用户查看/访问的内容

<P>FIXME: 需要丰富内容. 讲述升级对于软件包权限的影响 (顺便加入:偏执型的管理员应当 <prgn>chroot</prgn> 
他的用户).

<p>如果您需要授予用户通过 shell 访问系统的权限, 应该仔细考虑清楚. 
一个用户, 除非是在非常苛刻的环境下(如 <tt>chroot</tt> jail) ，可以查看有关您系统的许多信息，包括:

<list>

<item><file>/etc</file> 下的一些配置文件. 然而, Debian 对于一些敏感文件的默认权限, 
将防止对重要文件(它们也许, 例如包含密码)的访问. 要查看哪些文件只允许root用户访问，
例如以超级用户的身份运行 <tt>find /etc -type f -a -perm 600 -a -uid 0</tt> .

<item>通过查看软件包数据库, 或者查看<file>/usr/share/doc</file>目录, 或通过查看您系统中的二进制文件和库, 
来猜测您所安装的软件包.

<item>一些 <file>/var/log</file> 下的日志文件. 注意, 一些日志文件只允许 root 和 <tt>adm</tt> 组成员访问
(试试 <tt>find /var/log -type f -a -perm 640</tt>),一些甚至只有root有权限
(试试 <tt>find /var/log -type f -a -perm
600 -a -uid 0</tt>0).

</list>


<p>一个用户在您的系统里可以看到什么? 可能许多东西, 试试这个(先做一下深呼吸):
<example>
  find / -type f -a -perm +006 2>/dev/null  
  find / -type d -a -perm +007 2>/dev/null  
</example>

<p>输出的为用户可以<em>看到</em>的文件列表和可以访问的目录.

<sect2 id="limit-user-perm">限制用户对于其他用户信息的访问

<p>如果您允许用户通过 shell 访问, 但是想限制其对于其他用户信息的查看. 
用户通过 shell 访问会在其主目录下产生很多文件: 邮箱, 个人文件, X/GNOME/KDE 应用程序的配置文件...


<p>在Debian中每个用户创建是都产生一个附加组, 并且没有两个用户属于同一个组. 
这是缺省设置: 当 userX 创建时, 产生一个他所属的名为 userX 组. 这样可以避免因为<em>用户</em>组的概念, 
难以对其他用户隐藏信息.

<p>然而, 用户的 <var>$HOME</var> 目录创建时的权限是0775(组成员可读, 其他成员可读). 
组权限不会有问题, 因为用户是这个组的唯一成员, 然而根据您的本地策略, 其他权限可能(或不)存在问题.

<p>您可以修改规则, 使得创建的用户 <var>$HOME</var> 权限不同. 修改这种规则, 
改变 <file>/etc/adduser.conf</file> 中变量 <em>DIR_MODE</em> 的值为0750 (其他用户不可读)即可.

<p>用户仍然可以分享信息, 但不能直接访问他们的 <var>$HOME</var> 目录, 除非修改其权限.

<p>注意, 如果网络服务器存在的话, 这将会影响用户设置个人主页(<file>~userX</file>), 
因为网络服务器将不能读取 <var>$HOME</var> 目录, 而 <file>public_html</file> 目录就在它下面. 
如果您想允许用户在他们的 <file>~userX/public_html</file> 目录下发布 HTML 页面，则需要将 <em>DIR_MODE</em> 修改为 0751. 
这将允许网络服务器访问 <file>public_html</file> 目录(其权限应该是0755)和用户发布的内容.
当然, 我们在这里只是讨论默认设置; 用户可以使用他们喜欢模式, 或者您可以将 web 内容放到不是用户 <var>$HOME</var> 目录的子目录其它的地方. 

<sect1 id="user-pwgen">生成用户密码

<p>很多情况下, 管理员需要创建多个账号, 并为其设置密码. 当然, 管理员可以简单的将其设为与用户账号相同, 
但是这是非常不明智的. 一个比较好的办法是使用密码生成程序. Debian提供了 
<package>makepasswd</package>, <package>apg</package> 和 <package>pwgen</package> 软件包(程序名与包名相同).
<prgn>Makepasswd</prgn> 可以产生注重于安全而不是可读性的真正的随机密码, 
<prgn>pwgen</prgn> 则试图产生无意义但具有可读性的密码. <prgn>apg</prgn> 则同时提供了这两种算法
(这个程序还有个C/S版本, 但其并不在 Debian 软件包中提供).

<p><prgn>Passwd</prgn> 并不允许密码的非交互式分配(因为它直接通过 tty 访问). 
当你创建了很多用户时, 如果要修改其密码, 可以创建使用 <prgn>adduser</prgn> 带 <tt>--disabled-login</tt> 
选项进行创建, 然后使用 <prgn>chpasswd</prgn> <footnote>
<prgn>Chpasswd</prgn> 通常不能处理 MD5 密码, 因此使用时需要加上 <tt>-e</tt> 选项以给其输入加密的密码.
</footnote>
(在您已经安装的 <package>passwd</package> 软件包中). 
如果您要使用一个包含所有信息的文件进行批量创建用户的话, 也许使用 <prgn>newusers</prgn> 会更好.

<sect1>用户密码检查

<p>有时用户密码可能是一个特定系统的安全中<em>最弱的</em>一环. 这归结于一些用户为他们的账户选择了弱密码
(越弱，则被攻击的可能性越大). 既使您创建了使用 cracklib PAM 模块的检测和密码限制，如在 <ref id="auth-pam"> 
中所述. 用户仍然可以使用弱密码. 因为访问也许包括远程 shell 访问(<prgn>ssh</prgn>, 希望是), 
一个远程攻击(在他们用其他的方法做过用户枚举之后)无法猜测用户密码是非常重要的, 特别是如果他们不知什么原因收集到了类似用户名甚至 <file>passwd</file> 和 <file>shadow</file> 文件本身等重要信息.

<p>系统管理员必须检查大数量用户的密码是否与本地安全策略相一致. 如何检查? 就象真正的攻击者一样去破解, 
如果他可以访问经过hash的密码(<file>/etc/shadow</file> 文件). 

<p>管理员可以使用 <package>john</package> 或 <package>crack</package> (都是暴力密码破解器)
和一个合适的字典(wordlist), 来检测用户的密码, 并对检测出的密码采取相应的对策.
您可以使用 <prgn>apt-cache search wordlist</prgn> 搜索可能提供字典的软件包. 还可以从网上的很多ftp中找到字典, 参阅 <url id="ftp://ftp.ox.ac.uk/pub/wordlists"> 或
<url id="ftp://ftp.cerias.purdue.edu/pub/dict">.

<sect1 id="idle-logoff">注销闲置的用户

<p>闲置用户通常是一个安全隐患, 用户闲置, 可能因为他外出午餐, 或远程连接断掉, 
但是没有重新建立. 无论什么原因，闲置用户可能导致系统受到威胁:

<list>
<item>因为用户的控制台或许没有锁定，可能被入侵者所利用.  

<item>因为攻击者能重新加入一个关闭的网络连接并把命令发送到远端shell
(如果远端shell不是被加密的，如<prgn>telnet</prgn>，这相当容易做到).
</list>

<p>一些远程系统甚至因为闲置的(分离的)<prgn>屏幕</prgn>而受到威胁.

<p>强制断开闲置的用户是本地安全策略的一部分. 有以下几种方式:

<list>
<item>如果用户使用 <prgn>bash</prgn> shell, 系统管理员可以设置 <tt>TMOUT</tt> 
缺省值(参见 <manref section="1" name="bash">), 使得shell自动断开远程的闲置用户. 
注意设置时必需使用 <tt>-o</tt> 选项, 或者用户可以自行(或者不)设定.

<item>安装 <package>timeoutd</package> 并根据您的本地安全策略配置 <file>/etc/timeouts</file>. 
守护进程将监视闲置用户，在 shell 之外对其记时.

<item>安装 <package>autolog</package> 并配置其删除闲置用户.

</list>

<p>使用 <prgn>timeoutd</prgn> 或 <prgn>autolog</prgn> 守护进程是不错的方法, 
因为, 终究, 用户可以修改其缺省 shell，或运行默认 shell 以后，切换到其他的(未受控制的) shell.


<sect id="tcpwrappers">使用 tcpwrappers 

<p>TCP wrappers 用于满足当包过滤器不存在时的访问控制的需求. 同时, 也很有趣和有用. TCP wrappers 
允许你设定对于一个主机或域服务访问的允许或拒绝和定义一个默认规则(这些都是在应用程序级别完成的)。更多信息见
<manref name="hosts_access" section="5">.

<p>Debian 中安装的很多服务可以:

<list>
<item>通过 tcpwrapper(<file>tcpd</file>)服务加载
<item>通过编入libwrapper 来内建支持.
</list>

<p>一方面, 如果通过 <file>/etc/inetd.conf</file>配置服务(这包括 <prgn>telnet</prgn>, 
<prgn>ftp</prgn>, <prgn>netbios</prgn>, <prgn>swat</prgn>
和 <prgn>finger</prgn>), 则您会看到配置文件首先执行 <prgn>/usr/sbin/tcpd</prgn>. 
另一方面, 既使服务没有通过 <prgn>inetd</prgn> 守护进程加载, 仍可将对 tcp wrapper 规则的支持编译进服务. 
在 Debian 系统中可以编译进 tcp wrapper 的服务包括 <prgn>ssh, portmap, in.talk, rpc.statd, rpc.mountd, gdm, oaf</prgn>
(GNOME的激活精灵),<prgn>nessus</prgn> 等等很多. 

<p>查看使用tcpwrappers的软件包:

<example>
  $ apt-cache showpkg libwrap0 | egrep '^[[:space:]]' | sort -u | \
        sed 's/,libwrap0$//;s/^[[:space:]]\+//'
</example>


<p>考虑到 <prgn>tcpchk</prgn>(非常有用的 CP wrappers 配置文件规则和符号检查器)的运行. 
当您在 <file>hosts.deny</file> 和 <file>hosts.allow</file> 文件中添加独立的服务时(它们时 wrapper 库的符号连接),
<prgn>tcpdchk</prgn>会因找不到那些服务而发出警告, 因为它通过 <file>/etc/inetd.conf</file> 查找(联机手册 不是很准确).

<p>现在, 有一个小小的把戏, 或许可以得到一个最小入侵检测系统. 通常, 
您应当有一条不错的防火墙规则作为第一行, tcp wrappers 作为防御的第二行. 
这个小把戏就是在 <file>/etc/hosts.deny</file> 中设置一条 <var>SPAWN</var><footnote>在这里要确保使用了大写, 因为 <em>spawn</em> 不会起作用</footnote> 命令, 每当一个被拒绝的服务触发 wrappers 时, 就会发送邮件给 root:

<example>
  ALL: ALL: SPAWN ( \
    echo -e "\n\
    TCP Wrappers\: Connection refused\n\
    By\: $(uname -n)\n\
    Process\: %d (pid %p)\n\
    User\: %u\n\
    Host\: %c\n\
    Date\: $(date)\n\
  " | /usr/bin/mail -s "Connection to %d blocked" root) &
</example>

<p><em>当心</em>: 上边的例子对于短时间内建立许多连接的 Dos 攻击是开放的. 
很多邮件就意味着很少的数据包就会浪费大量的文件 I/O.

<!--
# Could this example be more interesting? 
# It also relates to the next section (jfs)
#
# era: cf hosts_access(5) manual page,
# and why are you not using logger(1) here? (FIXME?)
#
#&lt;example&gt;
#ALL: ALL: SPAWN ( \
#  /usr/local/sbin/send_syslog %u %c %d )
#&lt;example&gt;

#  With send_syslog as:
##!/usr/bin/perl -w
#
#use Sys::Syslog qw(:DEFAULT setlogsock);
#
#$user=shift(@ARGV) || 'unknown';
#$host=shift(@ARGV) || 'unknown';
#$service=shift(@ARGV) || 'unknown';
#setlogsock('unix');
#openlog("alert",'', 'user');
#syslog('warning', 'Connection from %s at %s to %s blocked.', ($user, $host, $service) );
#closelog();
#
#exit 0;
-->

<sect id="log-alerts">日志与警告的重要性

<p>显而易见, 日志和警告对于一个安全的系统非常重要. 假设一个系统配置的非常完美并且 99% 的安全, 
当 1% 的攻击发生时, 如果没有到位的安全工具, 首先, 检测到, 其次, 发出警告, 那么这个系统根本就不安全.

<p>Debian GNU/Linux 提供一些完成日志分析的工具，著名的 <package>swatch</package>, <footnote>这里有篇 <url id="http://www.spitzner.net/swatch.html" name="Lance Spitzner"> 撰写的很棒的文档
</footnote> <package>logcheck</package> 或 <package>log-analysis</package>(需要一些相关信息, 并删除多余的). 
如果系统就在旁边, 将系统日志信息输出到虚拟终端也非常有用. 这是很有用的, 因为您能看到系统是否正常.
Debian 的 <file>/etc/syslog.conf</file> 中注释掉了默认的配置; 去掉注释, 重起 <prgn>syslogd</prgn>, 就可生效了(
<tt>/etc/init.d/syslogd restart</tt>):

<example>
  daemon,mail.*;\
        news.=crit;news.=err;news.=notice;\
        *.=debug;*.=info;\
        *.=notice;*.=warn       /dev/tty8
</example>

如果想得到菜色的警告信息, 可以求助于 <package>colorize</package>, <package>ccze</package> 和 <package>glark</package>. 它们能转换日志的大部分, 但不是全部. 
<url name="Log Analysis" id="http://www.loganalysis.org/">是不错的资料.  无论如何, 
没有任何分析工具可以和最佳的分析工具相媲美: 您的脑子. 

<!-- FIXME: Check information on SHARP, the 'syslog heuristic analysis
and response program'.  The paper is at
http://www.csis.gvsu.edu/sharp/. Is it free-software? packaged? -->

<sect1 id="custom-logcheck">使用和定制 <prgn>logcheck</prgn>

<p>在 Debian中, <prgn>logcheck</prgn> 分为三部分, <package>logcheck</package>(主程序), 
<package>logcheck-database</package>(程序的正则表达式库)和 <package>logtail</package> (打印未读的日志内容).
在 Debian 中缺省(<file>/etc/cron.d/logcheck</file>)<prgn>logcheck</prgn> 系统空闲时每小说运行一次和系统重起时运行一次.

<p>如果配置合适, 这个工具可能对于管理员发现系统的异常事件相当有用. 
<prgn>Logcheck</prgn> 可以设置为, 从日志中发现值得注意的事件, 并发送邮件. 
默认安装的profile忽略事件和违规策略, 分为三种不同的设定 (workstation, server, paranoid). 
Debian的软件包包括一个<file>/etc/logcheck/logcheck.conf</file>, 源自程序,用于定义检查给哪些用户发送邮件. 
它还为软件包在以下目录下实现新的策略提供了一种方法: <file>/etc/logcheck/cracking.d/_packagename_</file>,
<file>/etc/logcheck/violations.d/_packagename_</file>,
<file>/etc/logcheck/violations.ignore.d/_packagename_</file>,
<file>/etc/logcheck/ignore.d.paranoid/_packagename_</file>,
<file>/etc/logcheck/ignore.d.server/_packagename_</file>, 和
<file>/etc/logcheck/ignore.d.workstation/_packagename_</file>. 
但是, 并非当前的包都是如此. 如果您有一种对其他用户有用的策略. 请将其作为对应软件包的一个问题报告提交
(作为一个<em>wishlist</em>问题). 更多信息请参阅<file>/usr/share/doc/logcheck/README.Debian</file>.

<p>最佳的配置 <prgn>logcheck</prgn> 的方式是安装后, 编辑其配置文件 <file>/etc/logcheck/logcheck.conf</file>
将缺省用户(root)修改为邮件接收者. 您还需要设置报告级别:<package>logcheck-database</package>有三种报告级别:
workstation, server, paranoid. "server" 为缺省级别, paranoid 只有在运行着尽可能少的服务的高安全性机器上才需要, 
workstation 使用于, 受保护的安全性不高的机器. 如果您想补充日志文件, 将其加入<file>/etc/logcheck/logcheck.logfiles</file>即可. 
这对于默认的 syslog 安装来说是适宜的.

<p>一旦设置完成, 你也许想检查一下发送的最初几 天/周/月 的邮件. 如果您发现发送了你不希望收到的邮件, 
在 <file>/etc/logcheck/ignore.d.<var>reportlevel</var>/local</file> 中添加对应于这些消息的正则表达式
(参见<manref name="regex" section="7"> and <manref name="egrep" section="1">)即可. 在 
<file>/usr/share/doc/logcheck-database/README.logcheck-database.gz</file> 中有关于如何编写规则的解释.
这是一个不断调整的过程; 一旦发送的消息都是相关的, 即可认为您的调整完成. 注意, 如果 <prgn>logcheck</prgn> 
没有在您的系统中发现什么相关事件它是不会给您发送邮件的，即使其在运行中(因此您也许只是每周得到一封邮件, 如果您很幸运话).


<sect1>配置警告发送地

<p>Debian 带有一个标准的 <tt>syslog</tt> 配置(在 
<file>/etc/syslog.conf</file> 中), 其根据系统配置, 在适当的文件中写入日志信息. 
您应该对此熟悉了; 如果不是, 请浏览一下 <file>syslog.conf</file> 文件和对应文档. 
如果要维护一个安全系统, 您应当知道日志信息发送到什么地方才不会被忽视.

<p>例如, 发送信息至控制台就是一个很棒的设定, 对生产系统很有用. 
但是为多个这种系统增加一台设备作为日志主机(即从其他系统接收日志)也是非常重要.

<p>也应当被考虑 root 的邮件, 许多安全控制台(象 <package>snort</package>) 发送警告信息到 root 的邮箱. 
这个邮箱通常是指系统创建的第一个用户(检查 <file>/etc/aliases</file>). 
注意要把 root 的邮件发送到他能接收的地方(本地或远程).

<p>在您的系统里还有其他的角色账号和别名. 在一个小型系统里, 
将所有这类别名指向 root 账号并将给 root 的邮件转送的系统管理员的个人邮箱应当非常简单.

<p>FIXME: 讲述 Debian 系统接收/发送与安全相关的 SNMP 陷阱一定非常有趣. 
检查:<package>snmptraglogd</package>, <package>snmp</package> 和
<package>snmpd</package>.


<sect1>使用日志主机

<p>loghost 就是收集网络中的远程系统日志的主机. 如果您的一台机器被攻击, 
入侵者无法消除其痕迹, 除非他也攻占了日志主机. 因此, 日志主机应当是特别安全的.
做一台日志主机非常简单. 只需要以 <tt>syslogd -r</tt> 方式启动 <prgn>syslogd</prgn>, 
一台新的 loghost 就建成了. 在 Debian 系统中, 通过编辑 <file>/etc/init.d/sysklogd</file> 
并修改一下内容即可完成永久配置:

<!-- FIXME: The following could also be interesting -->
<!-- How to hide the logging server on the network i.e. by not giving -->
<!-- it an IP address and adding a static ARP entry on the hosts using -->
<!-- the remote syslog server (only if on the same hub); if the remote -->
<!-- syslog server would be on a separate network, the default gateway -->
<!-- should be configured accordingly -->

<example>
  SYSLOGD=""
</example>
改为 
<example>
  SYSLOGD="-r"
</example>

其次, 配置其它机器发送数据到日志主机. 在<file>/etc/syslog.conf</file> 中增加如下类似内容:

<example>
  facility.level            @your_loghost
</example>

查找文献, 看用什么可以替代 <em>facility</em> 和 <em>level</em> (它们不应当象这样逐字输入). 
如果您要纪录远程的所有信息, 仅需这样写:

<example>
  *.*                       @your_loghost
</example>

到您的 <file>syslog.conf</file> 文件. 远程纪录同本地纪录一样是很好的解决方案
(攻击者也许假定通过删除本地日志文件来掩盖的它的痕迹). 更多信息见 <manref name="syslog"
section="3">, <manref name="syslogd" section="8"> 和 <manref
name="syslog.conf" section="5"> 联机手册.


<sect1>日志文件的权限

<p>不仅确定如何使用警告信息很重要, 谁对日志文件(如果使用远程日志主机)有读取/修改许可也不可忽视. 
在入侵事件中攻击者可以修改和禁用的安全警告没有什么价值. 并且, 
您必需考虑到也许日志文件向攻击者泄漏了有关您的系统的很多信息, 如果可以对其访问的话.

<!--  It should be explained why after installation this is not
 already done, jfs -->

<p>系统安装后, 一些日志文件的权限并不理想(但这当然取决于你的本地安全策略). 
首先 <file>/var/log/lastlog</file> 和 <file>/var/log/faillog</file> 对于普通用户不应当是可读的. 
在 <file>lastlog</file> 文件中您会看到最近谁登录了, 在 <file>faillog</file> 中, 
您则能看到失败的登录列表. 作者推荐修改两个文件<prgn>chmod 660</prgn>. 
检查一下您的日志文件，然后谨慎的确定对哪个 UID 不为0且不属于 'adm' 或 'root' 组的用户设置 可读/可写 权限. 
您可以简单运行下边的命令, 对您的系统做出检查:

<example>
  #  find /var/log -type f -exec ls -l {} \; | cut -c 17-35 |sort -u
  (查看/var/log 属于哪些用户)
  #  find /var/log -type f -exec ls -l {} \; | cut -c 26-34 |sort -u
  (查看/var/log 下的文件属于什么组)
  # find /var/log -perm +004
  (哪些文件对所有用户可读)
  #  find /var/log \! -group root \! -group adm -exec ls -ld {} \;
  (查看哪些文件不属于root 或 adm 组)
</example>

<p>为了定制日志文件的创建, 您可能需要定制生成它们的程序. 如果日志文件是轮换的, 
您则需要定制创建和轮换性能.

<!-- This is no longer true, check apache's logrotate
<p>
I want to emphasize that the apache log file permissions are really
screwed due to the fact that the apache user owns the apache log
files. If a user gets a shell with a back door in apache, they can
easily remove the log files.
-->

<sect id="kernel-patches">增加内核补丁
<!-- last edited by Fr閐閞ic Sch黷z <schutz@mathgen.ch> -->


<p>Debian GNU/Linux 为 Linux 内核提供了一些增强其安全性的补丁。 它们包括:

<list>

<item>Linux 入侵监测(在  <package>lids-2.2.19</package> 包中),
由 Huagang Xie 和 Philippe Biondi 制作. 这个内核补丁通过允许您限制, 隐藏, 保护甚至是源自 root 的进程, 
使得加固您的 linux 系统更加简单. 还允许您保护或隐藏某些文件, 这样即使是 root 也不能修改它们. 
此外, 还能设置对某些特定进程的支持. 这是偏执型系统管理员不可缺少的一个补丁. 主页:
<url id="http://www.lids.org" name="http://www.lids.org">

<item><em>Linux版的 POSIX 访问控制列表 (ACLs) </em> (在
<package>kernel-patch-acl</package> 包中). 这个内核补丁增加了访问控制列表, 
一个高级的控制文件访问权限的方法. 允许您控制对文件和目录的细粒度访问. 这个补丁加进了 kernel 2.5 开发版, 
并将缺省加入 kernel 2.6. 主页: <url
name="http://acl.bestbits.at/" id="http://acl.bestbits.at/">

<item>Linux Trustees (在 <package>trustees</package> 包中).
这个补丁为您的内核增加一个不错的权限管理系统. 每个文件或目录都绑定特定的对象(叫做委托人), 
并存放在内核内存中, 允许快速查询所有权限主页: <url name="http://trustees.sourceforge.net/"
id="http://trustees.sourceforge.net/">

<item>NSA Enhanced Linux (在 <package>selinux</package> 包中,也可从 
<url id="http://www.coker.com.au/selinux/" name="开发者的网站">处获得)

<item><package>kernel-patch-2.2.18-openwall</package>, Solar
Designer 制作. 这是个很有用的内核限制设定, 就象一个限制连接, <file>/tmp</file> 
目录下的 FIFO, 一个受限制的<file>/proc</file>文件系统, 专用文件描述处理, 非可执行用户堆栈区和其他. 主页: <url
name="http://www.openwall.com/linux/"
id="http://www.openwall.com/linux/">

<item><package>kernel-patch-2.4-grsecurity</package>: Grsecurity补丁，仅用于kernel 2.4 
<footnote>
注意, 依赖于 kernel2.4 源码包, 您可能会碰到一些给内核源码打补丁的问题. 也许您需要使用 stock vanilla kernel.
下边的步骤可以完成这一任务:
<example>
# apt-get install kernel-source-2.4.22 kernel-patch-debian-2.4.22
# tar xjf /usr/src/kernel-source-2.4.22.tar.bz2
# cd kernel-source-2.4.22
# /usr/src/kernel-patches/all/2.4.22/unpatch/debian
</example>
<p>更多信息参阅<url id="http://bugs.debian.org/194225"
name="#194225">, <url id="http://bugs.debian.org/199519"
name="#199519">, <url id="http://bugs.debian.org/206458"
name="#206458">, <url id="http://bugs.debian.org/203759"
name="#203759">, <url id="http://bugs.debian.org/204424"
name="#204424">, <url id="http://bugs.debian.org/210762"
name="#210762">, <url id="http://bugs.debian.org/211213"
name="#211213">, 和 <url
id="http://lists.debian.org/debian-devel/2003/debian-devel-200309/msg01133.html"
name="discussion at debian-devel">
</footnote>
, 实现了命令访问控制, 提供缓冲溢出保护, ACLs, 网络随机性(使提取操作系统指纹更加困难) 和<url
id="http://www.grsecurity.net/features.php" name="许多其它特性">.


<item><package>kernel-patch-2.2.19-harden</package>. <em>FIXME</em>
增加内容.

<item>IPSEC 内核支持 (在
<package>kernel-patch-freeswan</package> 包中). 
如果您想在 linux 下使用 IPsec 协议, 则需要这个补丁. 
有了这个补丁, 您创建 VPN 相当容易, 即使是对 windows 计算机, 因为 IPsec 是一个通用标准. 
kernel 2.5 开发版中加入了对 IPSec 的支持, 这个特性将在 kernel 2.6 中成为缺省.
主页: <url id="http://www.freeswan.org">.

<em>FIXME</em>: Debian 提供的最新的 kernel 2.4 包括了从2.5中移植过来的 IPSEC 代码. 相关评论.

<item><package>cryptoapi-core-source</package>. 这个补丁增加了 Linux 内核的密码支持, 
如密码和 digest 功能. 此功能通常用于文件系统和交换数据的加密.  注意自 2.5.45 版后, 
在官方 Linux 内核源码中加入了相似的功能. 因此在将来的 kernel 2.6 中可能不再需要这个补丁了. 
<em>注</em>: 在Debian的先前版本 <url id="http://www.debian.org/releases/sarge/" name="Sarge">
中没有这个补丁. 主页: <url name="http://www.kerneli.org/" id="http://www.kerneli.org/">

<item><package>cryptoloop-source</package>. 这个补丁允许您使用<package>crytoapi-core-source</package>
包的功能创建 loopback 设备的加密文件系统.

<item><package>kernel-patch-int</package>. 这个补丁也为 Linux 内核增加了密码支持, 
在 Debian 的 Potato 发行版中得到了应用. 在 Woody 中不支持, 如果使用 Sarge 或更新版本, 
您应该使用最新的 <package>cryptoapi-core-source</package>.


</list>

<p>FIXME: 增加更多内容, 解释使用 kernel-2.x.x-patch-XXX 软件包如何将特定补丁装入 Debian 系统.
</p>

<P>FIXME: 区分只适用于 kernel 2.2 和只适用于 kernel 2.4 的补丁, 以及都适用的.

<!-- Make the entries coherent: should the package names be links to the
relevant package pages ? -->

<p>然而, 一些补丁仍未在 Debian 中提供. 如果您觉得应该包含其中的一些, 
请到 <url name="Work Needing and Prospective Packages"
id="http://wnpp.debian.org"> 查找. 其中一些是:
<!-- http://wnpp.debian.org unreachable in the last two days... -->

<list>

<item><url id="http://pageexec.virtualave.net/" name="
PaX patch">

<item>
<url name="HAP patch"
id="http://www.theaimsgroup.com/~hlein/hap-linux/">

<item>
<url name="Stealth patch"
id="http://www.energymech.net/madcamel/fm/">

<item><em>SubDomain</em>. 内核外围设计提供最少特权以减少对不安全程序的引入. 
SubDomain 完善和扩大本地存取控制. 类似于一个 <prgn>chroot</prgn> 环境, 
它声称更加容易构建并且比 <prgn>chroot</prgn> 环境更加灵活. 
<item><em>Contexts (ctx) patch</em>. 一个实现虚拟专用网的内核扩展设计.
这与 BSD 中的 <prgn>jail</prgn>相似. 主页:
<url name="http://www.immunix.org/subdomain.html"
id="http://www.immunix.org/subdomain.html">

<item><em>UserIPAcct</em>. 这并不是真正的安全补丁, 但确实允许为您系统上的每个用户创建流量配额, 
并可用于统计用户的流量. 主页: <url id="http://ramses.smeyers.be/useripacct">.

</list>


<sect>保护免受缓冲溢出

<p><em>缓冲溢出</em> 是一种利用程序的边界检查缺陷(程序的问题, 通常为 C 语言), 
通过程序输入来执行机器代码的对软件<footnote>很常见, 事实上, 它们占每年报告的安全漏洞的 20%, 这是由 
<url id="http://icat.nist.gov/icat.cfm?function=statistics"
name="statistics from ICAT's vulnerability database"> 提供的</footnote>
的普通攻击. 此种攻击是针对监听远程连接的服务器软件和针对可以授予用户更高特权 
(<tt>setuid</tt> 或 <tt>setgid</tt>) 的本地软件, 进行指定系统的攻击.

<p>主要有四中方法保护免受缓冲溢出:

<list>

<item>给内核打补丁, 以防止堆栈的执行(可以使用 OpenWall 或 Grsecurity 补丁)

<!-- FIXME: add a link to libsafe to the main place -->

<item>使用库, 譬如 <url
id="http://www.research.avayalabs.com/project/libsafe/"
name="libsafe">, 重写易受攻击的部分, 并引入适当的检查(安装 libsafe 的方法参阅 <url
id="http://www.Linux-Sec.net/harden/libsafe.uhow2.txt" name="这里">).

<item>使用工具查找源码中易受攻击的片断, 并修正它.

<item>重新编译源码, 引入适当的防止溢出的检查, 使用, 例如<url
id="http://www.immunix.org/stackguard.html" name="StackGuard">
StackGuard(通常由<url id="http://www.immunix.org" name="Immunix">使用)
或者打了<url
id="http://www.research.ibm.com/trl/projects/security/ssp/" name="Stack
Smashing Protector (SSP)">补丁的GCC(通常由  <url
id="http://www.adamantix.org" name="Adamantix">使用)

</list>

<p>Debian GNU/Linux, 如 3.0 发行版, 提供了引入以上方法的软件, 这不包括对源代码的保护(但已在 <url
id="http://bugs.debian.org/213994" name="Bug #213994"> 中提交).

<p>注意既使 Debian 提供了带有 堆栈/缓冲 溢出保护的编辑器，所有的软件也都要需要重新编译，才能引入这些特性. 
实际上, Adamantix 确实如此(包括其它一些特性). 此特性对于软件稳定性的影响仍未得到确定(某些程序或处理器构架会因此崩溃).

<p>应当清楚, 在某些情况下, 即使这样也无法防止缓存溢出, 因为有很多方法可以绕过它们, 
如 phrack杂志<url name="第58期"
id="http://packetstorm.linuxsecurity.com/mag/phrack/phrack58.tar.gz">，或在CORE的  Advisory
<url id="http://online.securityfocus.com/archive/1/269246"
name="Multiple vulnerabilities in stack smashing protection technologies"> 中所描述的. 

<sect1>内核补丁对缓冲溢出的保护

<p>与缓冲溢出有关的内核补丁包括 kernel 2.2 中提到的免受内核溢出的 Openwall 补丁. 
至于 kernel 2.4 您则需要 Grsecurity 补丁(在 <package> kernel-patch-2.4-grsecurity</package> 包中)
其包括 Openwall 补丁, 和更多 <url id="http://www.grsecurity.net/features.php" name="特性">
(包括ACLs和网络随机性使得其使用远程网络指纹更加困难), 或 Linux 安全模块(在 
<package>kernel-patch-2.4-lsm</package> 和
<package>kernel-patch-2.5-lsm</package> 包中). 有关使用这些软件包的更多内容, 参阅<ref
id="kernel-patches">.

<sect1>Libsafe 保护

<p>使用 <package>libsafe</package> 保护一个 Debian GNU/Linux 系统相当容易. 
安装软件包和回答 <em>Yes</em> 以预载library即可. 然而, 应当注意, 因为这样可能会致使软件崩溃(特别是, 
与旧版 <prgn>libc5</prgn> 连接的程序)，因此首先要阅读 <url
id="http://bugs.debian.org/libsafe" name="错误报告">, 
并使用 <prgn>libsafe</prgn> wrapper 程序在您的系统上对关键程序进行测试.

<p><em>重要提示</em>: Libsafe 保护当前也许不再如<url id="http://bugs.debian.org/173227"
name="173227">所述有效. 考虑到以前测试使用的运行环境, 并不能完全依赖它来保护您的系统.

<sect1>程序的溢出测试

<p>使用工具来检测溢出是有必要的, 不管怎样, 即使可以依靠来编程经验修正(和重新编译) 代码. 
Debian 提供, 例如: <package>bfbtester</package>(通过命令行和环境溢出进行暴力检测的缓冲溢出测试器)
和<package>njamd</package>. <package>rats</package>, <package>pscan</package>
  	 <package>flawfinder</package> 和 <package>splint</package>是另外一些相关的软件包.
 	 

<sect>文件的安全传送 

<p>在正常系统管理过程中, 通常需要从安装的系统传输文件. 从一个主机向其他主机复制文件的安全方式是使用 <package>sshd</package> 服务器软件包. 
另一个可能的方式是使用<package>ftpd-ssl</package>, 使用<em>
加密套接字协议层</em>加密传输的 ftp 服务器.

<p>当然, 这些方法都需要特殊的客户端. Debian 提供了这类客户端，如 <package>ssh</package> 
提供了 <prgn>scp</prgn>. 其使用如 <prgn>rcp</prgn>, 但是是完全加密的, 因此那些<em>坏家伙</em>
甚至不能发现您在复制什么. 还有一个对应的服务器的 <package>ftp-ssl</package> 客户端软件包. 
您可以找到这些软件的客户端, 甚至是基于其他操作系统(非Unix), <prgn>putty</prgn> 和 <prgn>winscp</prgn>
是基于微软操作系统任何版本的安全复制工具.

<p>注意, 用户可以使用 <prgn>scp</prgn> 对所有文件系统进行访问, 除非使用了如<ref
id="ssh-chroot">中描述的 <prgn>chroot</prgn>. FTP访问可以设置为 <prgn>chroot</prgn>，
基于您选择的守护进程或许更容易，如<ref
id="ftp-secure">中所述. 如果担心用户浏览您的本地文件, 并想进行加密通讯, 您可以使用带有 SSL 支持的 ftp 守护进程, 
或结合明码通信的 ftp 和 VPN 的设定(参阅 <ref id="vpn">).


<sect>文件系统的限制和控制

<sect1>使用配额

<p>
有一个好的配额策略是很重要的，因为它可以防止用户填满硬盘.
<p>
您可以使用两个不同的配额系统: 用户配额和组配额. 就象您所猜到的, 用户配额是指限制用户磁盘空间的占用量, 
组配额则是限制组的. 在你设置配额时这一点要记清楚.

<p>在设置配额时有几个需要考虑的关键点:

<list>
<item>使得配额尽量小, 防止用户吃光您的硬盘空间.

<item>使得配额足够大，防止用户抱怨或邮件配额使他们可以长时间的保留邮件.

<item>在所有用户可写范围内使用配额, <file>/home</file> 以及 <file>/tmp</file>.
</list>

<p>用户具有完全写权限的每个分区和目录都应该启用配额设置. 结合实用性和安全性, 
来计算和分配这些分区和目录的可用配额大小.

<p>那么, 现在您想使用配额了. 首先, 需要检查您是否在内核中启用配额支持. 如果没有, 您需要重新编译内核. 
然后, 是否安装了控制 <package>quota</package> 的软件包. 如果没有请安装.

<!-- FIXME: how to check for quota support? What to tweak when
recompiling? -->

<p>
为每个文件系统启用配额非常简单, 仅需在 <file>/etc/fstab</file> 文件中修改
<tt>defaults</tt>为 <tt>defaults,usrquota</tt> 即可. 如果你需要组配额, 用 <tt>grpquota</tt> 替换<tt>usrquota</tt>.
也可以同时使用. 然后在要启用配额的文件系统的根目录下创建空文件 quota.user 和 quota.group 
(如为 <file>/home</file> 文件系统 <tt>touch
/home/quota.user /home/quota.group</tt> ).

<p>
通过运行 <tt>/etc/init.d/quota stop;/etc/init.d/quota
start</tt> 重起 quota. 现在配额已经运行，可以设置配额大小了.

<p>
可以运行 <tt>edquota -u ref</tt>, 为一个指定用户(叫做'ref')设置配额. 
可以运行 <tt>edquota -g
&lt;group&gt;</tt> 设置组配额. 然后设定缓冲值和限定值, 和/或 节点值, 如果需要的话.

<p>
关于配额的更多信息, 参阅配额的联机手册，和配额的
mini-howto(<file>/usr/share/doc/HOWTO/en-html/mini/Quota.html</file>).

<p>您可能喜欢或者不喜欢 <package>lshell</package>, 因为其违背 FHS. 并且考虑到 pam_limits.so 能够提供相同的功能, 
<package>lshell</package> 当前是处于 <url id="http://bugs.debian.org/93894" name="orphaned"> 状态的. 

<sect1 id="ext2attr">ext2 文件系统的特定属性(chattr/lsattr) 
<!-- section last edited by Fr閐閞ic Sch黷z <schutz@mathgen.ch> -->

<p>
除了通常Unix的权限, ext2 和 ext3 文件系统还提供了一套特别的属性用于控制您的文件和系统. 
不同于基本的权限, 这些属性并不能通过 <prgn>ls -l</prgn> 命令显示出来, 也不能使用<prgn>chmod</prgn>命令修改, 
您需要额外的两个工具 <prgn>lsattr</prgn> 和 <prgn>chattr</prgn> (在<package>e2fsprogs</package> 包中)来管理它们. 
注意, 这意味着, 您在备份系统时, 通常不能保存这些属性, 所以, 如果您对它们做了任何修改, 也许可以将其有价值部分
对应的<prgn>chattr</prgn>命令写入脚本, 这样就可以在以后必需恢复系统时重新设置.

<p>
在所有的属性中, 对于增强安全性最有价值的是参考字符 'i' 和 'a', 它们只能由超级用户设定(或删除):

<list>
<item>'i' 属性 ('immutable'): 带有此属性的文件, 不能被修改, 删除或重命名, 建立连接, 即使是超级用户也不能.

<item>'a' 属性 ('append'):  除了您能以附加的方式打开此文件外,此属性与 immutable 属性具有同样的效果. 
这意味着, 您仍可以在文件中增加更多的内容, 但是不能修改以前的内容. 这个属性对于存储于 <file>/var/log/</file>
目录的日志文件特别有用, 尽管应该考虑到有时候根据日志循环脚本, 它们有可能被移动.
</list>

<p>
也可以为目录设置这些属性, 这样任何人都没有修改这个目录的内容的权限(即, 重命名或删除一个文件, ...). 
当用于目录时, append 属性仅允许创建文件.

<p>
很容易看出 'a' 属性对于系统安全的改善, 给由非超级用户运行的程序以向文件中添加内容的权限, 
而不赋予修改以前内容的权限. 另一方面, 'i' 属性看上去似乎并不那么有趣:
终究, 超级用户已经可以使用基本的 Unix 权限来限制对于一个文件的访问, 入侵者可以获取超级用户权限后总能使用 <prgn>chattr</prgn>
程序删除此属性. 因此, 入侵者当发现不能删除一个文件时, 可能有点不知所措, 但是您不应当假设他是个瞎子, 
毕竟他进入了您的系统! 一些手册中(包括本文档的一个早期版本)建议从系统中删除 <prgn>chattr</prgn> 和 <prgn>lsattr</prgn>
以增加安全性, 但是这种做法, 也叫做"含糊的安全性(security by obscurity)", 应当绝对避免, 因为它提供的是假安全感.

<p>
这个问题一个安全解决方法是使用 Linux 内核能力特征, 如 <ref id="proactive"> 所述. 
这里我们所关心的是 <tt>CAP_LINUX_IMMUTABLE</tt>: 如果您从能力约束集中将其删除
(例如使用命令 <tt>lcap CAP_LINUX_IMMUTABLE</tt>), 将不再可能更改您系统中的任何 'a' 或 'i' 属性, 即使是超级用户! 
如下是一个完整的操作:

<enumlist>
  <item> 对您选定的文件设置 'a' and 'i' 属性;
  <item> 在一个启动脚本中添加命令 <tt>lcap CAP_LINUX_IMMUTABLE</tt> (也可以是
         <tt>lcap CAP_SYS_MODULE</tt>, 如在 <ref id="proactive"> 中所建议的);
<!-- Is there anything interesting in :
http://lists.debian.org/debian-security/2001/debian-security-200107/msg00024.html -->
  <item> 为此脚本和其他配置文件设置'i'属性, 包括 <prgn>lcap</prgn> 二进制文件本身;
  <item> 手工执行上述命令(或重新起动您的系统确定一切如设想的一样运行).
</enumlist>

<p>
现在能力已从系统取消了, 入侵者不改变任何被保护文件的属性了, 因此不能更改或删除这些文件. 
如果他强制机器重起(这是唯一恢复能力约束集的方法), 将很容易被察觉, 并且当系统完成启动后, 能力将再次被删除. 
唯一更改被保护文件的方法是以单用户模式引导系统或者使用其他的引导盘引导, 这两种方法都需要物理接触机器 !

<!-- Add a note about the fact that it is not widely used -->

<sect1 id="check-integ">文件系统的完整性检查

<p>几个月后, 您能肯定硬盘上的 <file>/bin/login</file> 仍然是您安装的那个吗? 
如果是一个被黑的版本, 其将输入的密码存储到隐藏的文件中, 或者以明文方式通过邮件发送到网上呢?

<p>
唯一的方法是选择一种保护措施, 每 小时/天/月(我推荐每天) 检查您现在文件的 md5sum 与以前的是否一致. 
两个文件不可能有相同的 md5sum(MD5为128bit 强度, 两个不同文件有相同 md5sum 的几率大概是 1/3.4e3803), 
这样即可确保您的站点安全, 除非有人也黑了那台机器上的生成 md5sum 的算法. 这非常困难, 几乎是不可能的. 
认真考虑这种对于文件审核的方式非常重要, 这是发现您的文件被修改的非常简单的办法. 常用的工具有
<package>sXid</package>, <package>AIDE</package>(高级入侵监测环境), <package>TripWire</package>
(non-free;新的版本将是符合GPL), <package>integrit</package> 和 <package>samhain</package>.

<p>安装 <prgn>debsums</prgn> 对检查文件系统的完整性很有帮助, 
通过比较每个文件的 md5sum 与对应的debian软件包中的 md5sum.
但当心, 那些文件很容易被修改.

<p>您允许想用 <prgn>locate</prgn> 来索引整个文件系统, 如果这样, 您就需要考虑一下其内涵. 
Debian 的 <package>locate</package> 软件包以 nobody 用户运行, 因此只能索引所有用户都可见的文件.
如果您需要索引整个文件系统(不仅仅是 nobody 用户可见的), 可以用 <package>slocate</package> 替代 
<package>locate</package>. slocate 号称是 GNU 的 locate 的安全改进版, 事实上只是提供了附加的 文件-定位 功能,
用户只能看到他真正可以访问的文件, slocate 软件包以比 locate 更高的 privledges 运行其更新了的进程, 进行文件索引. 这样用户就可以快速的查找其可见的所有文件. slocate 并不能查看新文件; 并基于用户的 UID 过滤输出.

<p>FIXME: 加入安装后的参考截图.
<p>FIXME: 增加有关软件包不提供所安装程序的 debsums 的备注(不是必须的).

<sect1>设置 setuid 检查

<p>
Debian 在 <file>/etc/cron.daily/standard</file> 中提供了一个每日运行 <prgn>cron</prgn> 任务. 
此 <prgn>cron</prgn> 任务将会运行 <prgn>/usr/sbin/checksecurity</prgn> 脚本, 以存储对应改变的信息.

<!-- FIXME: What is the default for this in cron package? jfs -->

<p>您必需在 <file>/etc/checksecurity.conf</file> 中设置 <tt>CHECKSECURITY_DISABLE="FALSE"</tt> 
才能进行这个检查. 注意, 这是默认设置, 除非您修改了某些东西, 这选项已经被设为 "FALSE".

<p>默认设置并不给超级用户发送邮件, 而是在 <file>/var/log/setuid.changes</file> 中保存每日修改的拷贝. 
您应当设置 CHECKSECURITY_EMAIL 变量(在 <file>/etc/checksecurity.conf</file> 中)值为 'root', 
使得其向 root 用户发送信息. 更多配置信息参见<manref
name="checksecurity" section="8">.

<sect id="network-secure">安全的网络访问

<p>FIXME. 需要更多的(Debian相关)内容


<sect1 id="kernel-conf">配置内核的网络特性

<p>FIXME: 内容丢失

<p>内核的许多特性都是可以通过回送信息到 <file>/proc</file> 下的对应文件或使用 <prgn>sysctl</prgn> 在运行过程中修改的. 
通过运行 <tt>/sbin/sysctl -A</tt> 可以看到可以配置的内容和可以使用的参数, 
并可通过 <tt>/sbin/sysctl -w variable=value</tt>(参阅 <manref
section="8" name="sysctl">)修改. 只有在很少的情况下, 需要您编辑对应的东西, 但是这样可以增加安全性. 例如:

<!-- FIXME: Should the prefix on all of these be /proc/sys/? era -->

<example>
net/ipv4/icmp_echo_ignore_broadcasts = 1
</example>

<p>这是一个 <em>Windows emulator</em> 仿真器,  因为如果这个选项设为1, 
它的动作就象 Windows 里的广播 ping. ICMP_ECHO 将会忽略接收的广播请求, 即什么也不做.

<p>如果您想拦截系统里所有的 ICMP 回送请求, 启用这个配置选项:

<example>
net/ipv4/icmp_echo_ignore_all = 0
</example>

<p>记录您网络中的地址不可用的数据包(由于错误路由):

<example>
/proc/sys/net/ipv4/conf/all/log_martians = 1
</example>

<p>有关对 <file>/proc/sys/net/ipv4/*</file> 操作的更多信息, 参见 
<file>/usr/src/linux/Documentation/filesystems/proc.txt</file>.  
<file>/usr/src/linux/Documentation/networking/ip-sysctl.txt</file>中有所有选项的详尽描述
<footnote>在 Debian 中 <package>kernel-image</package> 软件包在 <file>/usr/src/kernel-souce-2.X.X</file>下安装源代码, 以取代指向所安装内核的 <em>linux</em></footnote>.

<sect1 id="tcp-syncookies">配置 Syncookies


<p>这个选项是一把双刃剑. 一方面它保护您的系统免受 syn 湮灭; 另一方面它违背了定义的标准(RFCs).

<!-- What does this mean? (jfs)
This option is quite dumb as it floods the
other side like it floods you, so the other side is also busy. 
-->

<example>
net/ipv4/tcp_syncookies = 1
</example>

<p>如果您想要每次内核运行时都改变这个选项, 则需要在 <tt>/etc/network/options</tt> 
中设置 <tt>syncookies=yes</tt>. 此设置在 <tt>/etc/init.d/networking</tt> 再次运行后起作用. 
而下边的设置只对当前运行的内核有效:

<example>
echo 1 > /proc/sys/net/ipv4/tcp_syncookies 
</example>

<p>此选项只有编译内核时启用 <tt>CONFIG_SYNCOOKIES</tt> 才会有效. 所有的
 Debian 内核都是内置此选项编译的, 您可以运行下边的命令来确认:

<example>
$ sysctl -A |grep syncookies
net/ipv4/tcp_syncookies = 1
</example>

<p>有关 TCP syncookies 的更多信息, 参阅 
<url id="http://cr.yp.to/syncookies.html">.

<sect1 id="net-harden">增强启动时网络的安全性

<p>当设置了您需要的内核网络选项后, 那么每次重起时这些参数都会被加载. 
下边的例子启用了很多前边提到的选项和其他有用的选项.

<p><em>FIXME</em> 为 <file>sysctl.conf</file> 提供一个实例配置文件, 而不仅仅是这个脚本(参阅: <manref section="5"
name="sysctl.conf">). 并将此作为字典错误提交给 procps 软件包.

<p>在<file>/etc/network/interface-secure</file>(这个名字仅仅是个例子)中创建此脚本, 
并从 <file>/etc/network/interfaces</file> 中调用, 如下:

<example>
auto eth0
iface eth0 inet static
        address xxx.xxx.xxx.xxx
        netmask 255.255.255.xxx
        broadcast xxx.xxx.xxx.xxx
        gateway xxx.xxx.xxx.xxx
        pre-up /etc/network/interface-secure
</example>

<example>
# Script-name: /etc/network/interface-secure
# Modifies some default behaviour in order to secure against 
# some TCP/IP spoofing & attacks
#
# Contributed by Dariusz Puchalak  
#
echo 1 > /proc/sys/net/ipv4/icmp_echo_ignore_broadcasts 
                                           # broadcast echo protection enabled
echo 0 > /proc/sys/net/ipv4/ip_forward     # ip forwarding disabled
echo 1 > /proc/sys/net/ipv4/tcp_syncookies # TCP syn cookie protection enabled
echo 1 >/proc/sys/net/ipv4/conf/all/log_martians # Log strange packets
# (this includes spoofed Packets, source routed Packets, redirect Packets)
                         # but be careful with this on heavy loaded web servers
echo 1 > /proc/sys/net/ipv4/ip_always_defrag 
                                           #  defragging protection always enabled
echo 1 > /proc/sys/net/ipv4/icmp_ignore_bogus_error_responses 
                                           # bad error message protection enabled

# now ip spoofing protection
echo 1 > /proc/sys/net/ipv4/conf/all/rp_filter

# and finally some more things:
# Disable ICMP Redirect Acceptance
echo 0 > /proc/sys/net/ipv4/conf/all/accept_redirects
echo 0 > /proc/sys/net/ipv4/conf/all/send_redirects

# Disable Source Routed Packets
echo 0 > /proc/sys/net/ipv4/conf/all/accept_source_route


echo 1 > /proc/sys/net/ipv4/conf/all/log_martians
</example>

<p>您还可以创建一个 <tt>init.d</tt> 脚本, 并使其在系统引导时运行(使用 <prgn>update-rc.d</prgn> 创建对应的 <tt>rc.d</tt> 链接) .

<sect1 id="kernel-fw">配置防火墙 

<p>为了获得防火墙支持, 保护本地系统或其他处于其<em>后</em>的系统, 
您需要在编译内核将其启用。标准的 Debian 2.2 kernel(也是 2.2 )提供了过滤数据包的 <prgn>ipchains</prgn> 防火墙, 
标准的 Debian 3.0 kernel(kernel 2.4) 提供了 <em>stateful</em> 数据包过滤的 <prgn>iptables</prgn>(netfilter)防火墙. 
更旧的 Debian 版本则需要对应的内核补丁( Debian 2.1 使用 kernel 2.0.34).

<p>无论如何, 使用一个与 Debian 提供的不同的内核并不是一件难事. 您可以找到预编译的内核包, 
然后简单的把它安装到 Debian 系统中. 您也可以通过下载 <package>kernel-source-X</package> 获取内核源码, 
然后使用 <package>make-kpkg</package> 构建内核软件包.

<p>在 <ref id="firewall-setup"> 处有关于在 Debian 中配置防火墙的更详细的讨论.


<sect1 id="limit-bindaddr">禁用弱客户主机问题

<p>系统可能配置了不止一个接口在不同的网络上提供服务, 因此它们可能绑定到一个指定的IP地址上. 
这通常可以防止指定的地址的服务请求. 但是, 这并不意味着(尽管这是普遍的误解, 包括我在内)
服务绑定到了指定的<em>硬件</em>地址(网卡).
<footnote>
复制(例子由 Felix von Leitner 在 bugtraq 邮件列表中提供):
<example>
   host a (eth0 connected to eth0 of host b):
     ifconfig eth0 10.0.0.1
     ifconfig eth1 23.0.0.1
     tcpserver -RHl localhost 23.0.0.1 8000 echo fnord

   host b:
     ifconfig eth0 10.0.0.2
     route add 23.0.0.1 gw 10.0.0.1
     telnet 23.0.0.1 8000
</example>
<p>然而, 这看起来对绑定于 127.0.0.1 的服务不起作用, 您可能需要使用 raw sockets 来写这个测试.</p>
</footnote>

<p>这不是 ARP 问题, 也不是 RFC 问题(它在 <url id="ftp://ftp.isi.edu/in-notes/rfc1122.txt" name="RFC1122">, 
3.3.4.2部分称作<em>weak end host</em>).

记住, IP 地址与物理接口无关.

<p>在 2.2 (和更早)的内核中, 可以做如下修正:
<example>
# echo 1 > /proc/sys/net/ipv4/conf/all/hidden
# echo 1 > /proc/sys/net/ipv4/conf/eth0/hidden
# echo 1 > /proc/sys/net/ipv4/conf/eth1/hidden
.....
</example>
<p>在最新的内核中, 还可以做如下操作:
<list>
<item>iptables 规则.
<item>恰当的配置路由.
<footnote>
事实上, 这一特性可以通过路由修改, 如 Matthew G. Marsh 在 bugtraq 中所述:
<example>
eth0 = 1.1.1.1/24
eth1 = 2.2.2.2/24

ip rule add from 1.1.1.1/32 dev lo table 1 prio 15000
ip rule add from 2.2.2.2/32 dev lo table 2 prio 16000

ip route add default dev eth0 table 1
ip route add default dev eth1 table 2
</example>
</footnote>
<item>内核补丁.
<footnote>
有一些用于这一特性的补丁, 如 bugtraq 的
<url id="http://www.linuxvirtualserver.org/~julian/#hidden">
和 <url id="http://www.fefe.de/linux-eth-forwarding.diff"> 中所描述的.
</footnote>
</list>
<p>根据本文, 将会有许多内容描述如何配置一些服务( sshd 服务, apache, 打印服务...), 
使其监听指定的地址, 读者应该考虑到, 这里没有给定修正，修正不会阻止同一(本地)网络内部的访问.
<footnote>
在配置了 IP 地址绑定以后, 如果和被攻击主机不是位于同一广播域(同一网络), 攻击者试图访问就会有很多麻烦. 如果工具通过一个路由器, 那么信息的返回是相当困难的.
</footnote>

<p>FIXME: 有关 bugtraq 的评论表明有 某种 Linux 方法可以绑定到一个指定的接口.

<p>FIXME: 提交一个 netbas 的错误, 使得 routing fix 成为Debian标准的动作?


<sect1>保护系统免受 ARP 攻击

<p>当您不再信任您的局域网内(经常会出现这种情况, 因为这才是安全的态度)的其他系统时, 
您需要保护自己免受各种各样的 ARP 攻击.

<p>如您所知, ARP 协议用于 IP 地址和 MAC 地址的转换. (更多细节参阅<url name="RFC826"
id="ftp://ftp.isi.edu/in-notes/rfc826.txt">). 当您向某个IP地址发送数据包时, 
arp 将其解析(首先查询本地ARP缓存, 如果此IP在缓存中不存在, 则进行查询广播), 
得到其物理地址. 所有的 ARP 攻击都是试图欺骗您的主机, 认为主机 B 的 IP 对应于入侵者的主机的 MAC 地址; 
那么, 所有的您发送给对应主机 B 的 IP 的数据包都被发送给入侵者的主机...

<p>
这些攻击(Cache poisonning，ARP 欺骗...)允许攻击者嗅探数据传输即使是在交换网上, 
很容易的捕获连接, 将任何一个主机从网络上断开...  Arp 攻击强度很高, 并且实施简单, 有这么几个工具: 
arpspoof
(在最近的 <package>dsniff</package> 包中), <url name="arpmim"
id="http://www.team-teso.net/releases/arpmim-0.2.tar.gz">, <url
name="arpoison" id="http://web.syr.edu/~sabuer/arpoison/">...
<!-- ~sabuer broken and unavailable in the new web site provided -->

<p>但是, 总有一个解决办法:

<list>

<item>使用静态 arp 缓存. 对您的arp缓存设置 "static" 选项:

<example>
arp -s host_name hdwr_addr 
</example> 

<p>对每个您网络中的重要的主机作如此设置, 
确保没有人会 创建/修改 这些主机的一个(假的)记录(static 记录不会到期, 也不能修改), 
这样 arp 欺骗就可以被忽略.


<item>检查可疑的 ARP 通讯. 您可以使用 <package>arpwatch</package>, <package>karpski</package>
或其它的可以监测可疑的 arp 通讯的 IDS
(<package>snort</package>, <url name="prelude"
id="http://www.mandrakelinux.com/prelude">...).

<item>实行确认主机MAC地址的IP通讯过滤.
</list>


<sect id="snapshot">生成系统快照

<p>在系统投入使用以前, 您最好生成系统快照. 此快照可用于系统被攻击的情况下(参见 <ref id="after-compromise">). 
然后您应该重新升级, 不管您是否进行了升级, 特别是如果您升级到了 Debian 新的发行版.

<p>你应该使用可以设为只读的可写式移动介质保存快照, 这可能是软盘(使用后设置写保护), 
或光盘(您可以使用刻录机, 这样您就可以备份不同时间的 md5sum).

<p>下边的脚本将创建这样的快照:

<example>
#!/bin/bash
/bin/mount /dev/fd0 /mnt/floppy
/bin/cp /usr/bin/md5sum /mnt/floppy
echo "Calculating md5 database"
>/mnt/floppy/md5checksums.txt
for dir in /bin/ /sbin/ /usr/bin/ /usr/sbin/ /lib/ /usr/lib/
do
   find $dir -type f | xargs /usr/bin/md5sum >>/mnt/floppy/md5checksums-lib.txt
done
/bin/umount /dev/fd0
echo "post installation md5 database calculated"
</example>

<p>注意将 md5sum 程序放到软盘上, 这样就可用于以后的系统程序的检查(防止置入木马)

<p>快照不包括 <file>/var/lib/dpkg/info</file> 下的文件, 它们的 md5 哈希值包含在安装包中 
(以 .md5sums 为扩展名的文件中). 您也可以复制这些信息，但是应当注意到:

<list>
<item> Debian 软件包提供的 md5sums 为其所有文件的值, 这使数据库更大
(5Mbs ～600kbs 带有图形系统的 Debian 系统，大约有 2.5G 的软件被安装)

<item>不是所有的 Debian 软件包都为其安装的文件提供 md5sums, 因为这不(当前)是代理策略.

</list>

<p>一旦生成了快照完, 您应当确保其被存储于只读介质上. 您也可以存储其备份, 
将其置于磁盘上,用于每晚的 <prgn>cron</prgn> 检查比较.


<sect>其它建议
<sect1>不要使用基于 svgalib 的软件

<p>
SVGAlib 非常受控制台爱好者的喜爱, 比如我. 但是, 过去它已被多次证明是不安全的. 
发布的基于 <prgn>zgv</prgn> 的 Exploits, 很容易获取root权限. 只要可能尽量避免使用 SVGAlib 程序 .  

<!-- FIXME: move this to policy section if there ever is one? -->


