原文更新:2004年5月13日
内容简介:本指南循序渐进地引导您强化Gentoo Linux的安全性。

1. 简介


 

       本指南适用于在基于服务器的环境中使用Gentoo Linux和其他有意增强安全性的用户。

注释: 阅读完本指南后如果感觉意犹未尽,请移架到强化Gentoo计划

2. 安装前的考虑


 

物理安全 

       如果攻击者可以使用你的机器,任何安全措施都可以轻松绕过。确保你的硬件不能随意接触。比如可以放在加锁的壁橱里。加锁的机箱也不错。要达到最高级别的安全,应设置BIOS使之只可从你的硬驱引导,而不允许从光驱软驱引导。对缺乏安全感的人,启用BIOS密码是个不错的主意。对笔记本用户亦然。

守护程序/服务规划 

       为机器上应该或打算运行的服务做好文档。这样有助于你为系统构成更好的分区方案,亦可简化入侵检测策略。当然如果只有一台或为数不多的机台电脑,你又是唯一使用它们的人,那文档就大可不必了。例如,如果该机将用作防火墙,那它除了可能sshd外,不应运行任何其他服务。

       记下这点及sshd的当前版本,这样在他人发现了sshd的安全漏洞时有助于你追踪需要升级的系统。也可帮你决定哪些人应该有权访问系统。

分区方案 

       黄金法则:

根用户[root] 

       root是系统中至关重要的用户,应在确属必须时才使用。如果攻击者获得root访问权限,系统就不可靠了,只有重装一途。

       root用户黄金法则

       Gentoo对一般用户使用su有总体上的防范。默认的PAM设置规定wheel组的成员才可使用su。

安全政策 

       需要安全政策有几个方面的理由。

       为不止一个用户的系统建立安全政策及教育用户的重要性说的很清楚了吧?

       安全政策是一份或几分文档,它回答了诸如何人、何处、为何及如何的问题。系统/网络的每个用户都必须通读、理解及在上面签字。花时间帮助用户理解政策、需要他们签字的原因及违反政策的可能后果(安全政策也应该说明这点)非常重要。这点应每年至少重复一次,一方面政策可能改变,另一方面也算对用户的提醒。

注释: 建立的政策应该易懂、切题。

       政策中的大部分可以在操作系统中或通过防火墙直接实施。

       安全政策至少应包含如下主题:

       对IT员工的政策可能与普通用户稍有不同。

       安全政策可能变得庞大而关键信息反而容易被遗忘。 IT员工的政策可能包含对一般用户属于机密的信息,将其分割为较小的多个政策较为明智,即: 允许的使用政策、密码政策、电邮政策和远程访问政策。

       可在SANS安全政策计划找到示范政策。如果网络较小嫌这个太复杂,可以看看网站安全手册.

3. 安装期和安装后强化安全


 

USE标志 

       make.conf文件包含用户定义的USE标志, /etc/make.profile/make.defaults包含了Gentoo Linux的默认USE标志。对本指南而言重要的标志有pam (Pluggable Authentication Modules 可插入鉴证模块), tcpd (TCP包装)和ssl (Secure Socket Layer 加密套接字协议层)。这些都在默认的USE标志集中。

GRUB密码 

       Grub支持两种不同的给其配置文件(/boot/grub/grub.conf)加入密码限制的方法。一种是纯文本密码,一种是md5+salt加密。

代码 3.1: /boot/grub/grub.conf

timeout 5
password changeme

       这将加上密码 changeme 。如果没有输入密码,将只使用默认引导设置。

       要加md5密码,需要将密码转换为crypt格式(man crypt),该格式与/etc/shadow相同。详情参man crypt。加密后的密码changeme看起来与这个差不多$1$T7/dgdIJ$dJM.n2wZ8RG.oEiIOwJUs。

       或者这个你可以直接在grub的shell中直接转化:

代码 3.2: md5crypt in grub shell

#/sbin/grub

    GRUB  version 0.92  (640K lower / 3072K upper memory)

   [ Minimal BASH-like line editing is supported.  For the first word, TAB
     lists possible command completions.  Anywhere else TAB lists the possible
     completions of a device/filename. ]

grub> md5crypt

Password: ********// Typed changeme
Encrypted: $1$T7/dgdIJ$dJM.n2wZ8RG.oEiIOwJUs.

grub> quit

       然后将密码拷贝粘贴到/boot/grub/grub.conf.

代码 3.3: /boot/grub/grub.conf

timeout 5
password --md5 $1$T7/dgdIJ$dJM.n2wZ8RG.oEiIOwJUs.

       如果是远程系统要不通过键盘交互重启的话,5秒超时非常方便。执行info grub学习更多grub密码方面的知识。

LILO密码 

       LILO也支持两种处理密码的方式:全局和每映像,都是未加密的文本。

       全局密码在配置文件的开始设定:

代码 3.4: /etc/lilo.conf

password=changeme
restricted
delay=3

       否则只要加到某个映像的设置中。

代码 3.5: /etc/lilo.conf

image=/boot/bzImage
      read-only
      password=changeme
      restricted

       若没有输入restricted选项,则LILO每次都会提示输入密码。

       要把新信息存入lilo.conf,需要运行/sbin/lilo.

限制控制台的使用 

       /etc/securetty文件允许你指明root可以从那些tty (终端)设备登录。

       建议你把除 vc/1 外的其他行都注释掉。这样可以保证root仅可登录一次而且只能使从一个终端上。

注释: wheel组中用户还是可以在其他TTY上 su - 为root。

代码 3.6: /etc/securetty

vc/1

4. 更多的日志


 

       应该加上额外的日志以捕获可以提醒你正在发生攻击或已被攻破的警告和错误消息。攻击者攻击前常常先扫描或探测网络。

       日志文件的易读和易管理性也很关键。安装时Gentoo Linux允许你从三种不同的日志程序中选择。

日志: Syslogd 

       Syslogd是Linux和Unix整体而言上最常用的日志程序。它并不自带日志至循环,这一功能可以通过定时任务运行/usr/sbin/logrotate 处理,在/etc/logrotate.conf中配置。运行日志循环的频度应取决于系统负载。

       下面是增加了一些功能的标准syslog.conf。我们注释掉了 cron and tty 几行,增加了远程日至服务器。为了进一步提高安全性,可以在两个地方保留日志。

代码 4.1: /etc/syslog.conf

#  /etc/syslog.conf     syslogd配置文件.
#
#                       参考syslog.conf(5) man手册页以获取更多的信息
#                       取自Debian, 目前我们使用这个
#                       Daniel Robbins, 5/15/99

#
# 首先,一些标准的日志文件。由工具记录
#

auth,authpriv.*                 /var/log/auth.log
*.*;auth,authpriv.none          -/var/log/syslog
cron.*                         /var/log/cron.log
daemon.*                        -/var/log/daemon.log
kern.*                          -/var/log/kern.log
lpr.*                           -/var/log/lpr.log
mail.*                          /var/log/mail.log
user.*                          -/var/log/user.log
uucp.*                          -/var/log/uucp.log
local6.debug                    /var/log/imapd.log

#
# 邮件系统日志。将其分开以便编写脚本分析这些文件
#
mail.info                       -/var/log/mail.info
mail.warn                       -/var/log/mail.warn
mail.err                        /var/log/mail.err

# INN新闻系统日志
#
news.crit                       /var/log/news/news.crit
news.err                        /var/log/news/news.err
news.notice                     -/var/log/news/news.notice

#
# 一些 `照单全收' 的日志文件。
#
*.=debug;\
        auth,authpriv.none;\
        news.none;mail.none     -/var/log/debug
*.=info;*.=notice;*.=warn;\
        auth,authpriv.none;\
        cron,daemon.none;\
        mail,news.none          -/var/log/messages

#
# 紧急情况和提醒发送给已登录的所有用户
#
*.emerg                         *
*.=alert                        *

#
# 我喜欢把消息显示在终端上,不过只在一个我通常不用的虚终端上
#
daemon,mail.*;\
       news.=crit;news.=err;news.=notice;\
       *.=debug;*.=info;\
       *.=notice;*.=warn       /dev/tty8

# 设置远端日志服务器
*.*                        @logserver

# /dev/xconsole命名管道用于`xconsole'工具。要使用它,
# 必须以`-file'选项调用`xconsole':
#
#    $ xconsole -file /dev/xconsole [...]
#
# 备注: 调整下面的列表,否则网站够忙时, 你就麻烦缠身了
#
# daemon.*,mail.*;\
#       news.crit;news.err;news.notice;\
#       *.=debug;*.=info;\
#       *.=notice;*.=warn       |/dev/xconsole

local2.*                -/var/log/ppp.log

       攻击者非常可能想编辑或删除日志文件掩盖其行踪。在不同机器上的一或多个日至服务器上记录日志可以增加其难度。可以通过执行man syslog了解更多syslogd的知识。

Metalog 

       Frank Dennis的Metalog 不可写入远端服务器,但在性能和记录的灵活性方面独擅胜场。它可按程序名、紧急度和设施(如syslogd)记录日志,自带正则表达式匹配,还可在发现特定模式后启动外部脚本。特别便于在需要时采取行动。

       标准配置基本够用。如果想在发生密码失败时收到邮件通知,使用如下脚本。

       对postfix:

代码 4.2: postfix的/usr/local/sbin/mail_pwd_failures.sh

#! /bin/sh
echo "$3" | mail -s "Warning (program : $2)" root

       对qmail:

代码 4.3: qmail的/usr/local/sbin/mail_pwd_failures.sh

#!/bin/sh
echo "To: root
Subject:Failure (Warning: $2)
$3
" | /var/qmail/bin/qmail-inject -f root

       记得通过调用/bin/chmod +x /usr/local/sbin/mail_pwd_failures.sh 使这个脚本可执行。

       然后去掉/etc/metalog/metalog.conf中`密码失败'下命令行的注释,像这样:

代码 4.4: /etc/metalog/metalog.conf

command  = "/usr/local/sbin/mail_pwd_failures.sh"

Syslog-ng 

       Syslog-ng提供了一些与syslog和metalog相同的功能,有少许差别。它可按级别和内容(类似于metalog)过滤消息,提供了和syslog相似的远程日志,处理来自syslogd的日志(甚至是来自Solaris的流),写到TTY, 执行程序,还可充当日志服务器。基本而言兼有其他两个之长,并有高级的配置功能。

       稍加修改的一个经典配置文件

代码 4.5: /etc/syslog-ng/syslog-ng.conf

options { long_hostnames(off); sync(0); };

# 读取日志的源
source src { unix-stream("/dev/log"); internal(); };
source kernsrc { file("/proc/kmsg"); };

# 定义目的地
destination authlog { file("/var/log/auth.log"); };
destination syslog { file("/var/log/syslog"); };
destination cron { file("/var/log/cron.log"); };
destination daemon { file("/var/log/daemon.log"); };
destination kern { file("/var/log/kern.log"); };
destination lpr { file("/var/log/lpr.log"); };
destination user { file("/var/log/user.log"); };
destination mail { file("/var/log/mail.log"); };

destination mailinfo { file("/var/log/mail.info"); };
destination mailwarn { file("/var/log/mail.warn"); };
destination mailerr { file("/var/log/mail.err"); };

destination newscrit { file("/var/log/news/news.crit"); };
destination newserr { file("/var/log/news/news.err"); };
destination newsnotice { file("/var/log/news/news.notice"); };

destination debug { file("/var/log/debug"); };
destination messages { file("/var/log/messages"); };
destination console { usertty("root"); };
destination console_all { file("/dev/tty12"); };
destination xconsole { pipe("/dev/xconsole"); };

# 创建过滤器
filter f_auth { facility(auth); };
filter f_authpriv { facility(auth, authpriv); };
filter f_syslog { not facility(authpriv, mail); };
filter f_cron { facility(cron); };
filter f_daemon { facility(daemon); };
filter f_kern { facility(kern); };
filter f_lpr { facility(lpr); };
filter f_mail { facility(mail); };
filter f_user { facility(user); };
filter f_debug { not facility(auth, authpriv, news, mail); };
filter f_messages { level(info..warn)
	and not facility(auth, authpriv, mail, news); };
filter f_emergency { level(emerg); };

filter f_info { level(info); };
filter f_notice { level(notice); };
filter f_warn { level(warn); };
filter f_crit { level(crit); };
filter f_err { level(err); };
filter f_failed { match("failed"); };
filter f_denied { match("denied"); };

# 把过滤器和目的地连接起来
log { source(src); filter(f_authpriv); destination(authlog); };
log { source(src); filter(f_syslog); destination(syslog); };
log { source(src); filter(f_cron); destination(cron); };
log { source(src); filter(f_daemon); destination(daemon); };
log { source(kernsrc); filter(f_kern); destination(kern); };
log { source(src); filter(f_lpr); destination(lpr); };
log { source(src); filter(f_mail); destination(mail); };
log { source(src); filter(f_user); destination(user); };
log { source(src); filter(f_mail); filter(f_info); destination(mailinfo); };
log { source(src); filter(f_mail); filter(f_warn); destination(mailwarn); };
log { source(src); filter(f_mail); filter(f_err); destination(mailerr); };

log { source(src); filter(f_debug); destination(debug); };
log { source(src); filter(f_messages); destination(messages); };
log { source(src); filter(f_emergency); destination(console); };

# 默认日志
log { source(src); destination(console_all); };

       容易配置也容易在配置文件中漏掉些东西,因为它太大了。作者还承诺了诸如加密、鉴证、压缩和MAC(强制访问控制)的一些额外功能。加上这些选项,可说是网络日志的极品。因为攻击者无法偷窥日志了。

       而syslog-ng还有其他长处: 无需以root来运行。

5. 挂载分区


 

       挂载ext2、ext3 或reiserfs 分区时,可在/etc/fstab 中施加几个选项。它们是:

       不幸的是这些设置可以通过执行间接路径轻松绕过。然而把 /tmp 设为noexec可以阻止约99%的有害脚本,因为它们被设计成直接从/tmp执行才能为害。

代码 5.1: /etc/fstab

/dev/sda1 /boot ext2 noauto,noatime 1 1
/dev/sda2 none swap sw 0 0
/dev/sda3 / reiserfs notail,noatime 0 0
/dev/sda4 /tmp reiserfs notail,noatime,nodev,nosuid,noexec 0 0
/dev/sda5 /var reiserfs notail,noatime,nodev 0 0
/dev/sda6 /home reiserfs notail,noatime,nodev,nosuid 0 0
/dev/sda7 /usr reiserfs notail,noatime,nodev,ro 0 0
/dev/cdroms /cdrom0 /mnt/cdrom iso9660 noauto,ro 0 0
proc /proc proc defaults 0 0

警告: 把 /tmp 设为 noexec 模式可能会妨碍某些脚本正常执行。

注释: 磁盘配额参配额部分.

注释: 我没有设 /var 为 noexec 或 nosuid 尽管通常从不从这个挂载点执行。理由是qmail安装在 /var/qmail,它必须执行及访问一个SUID文件。我把/usr设为只读,因为除更新Gentoo外我从不往那里写入任何东西。这样我把文件系统重挂为读写模式,更新,再重挂。

注释: 就算你不用qmail, Gentoo还是需要你设置 /var/tmp 的执行位,因为ebuilds在那里完成。如果你坚持要把 /var 设为 noexec 模式,可以设置一个替代的路径。

6. 用户/组限制


 

/etc/security/limits.conf 

       要防止本地DoS或处理一个组或用户的最大登录数,控制资源限制是一个非常有效的途径。

代码 6.1: /etc/security/limits.conf

*    soft core      0
*    hard core      0
*    hard nproc     15
*    hard rss       10000
*    -    maxlogins 2
@dev hard core      100000
@dev soft nproc     20
@dev hard nproc     35
@dev -    maxlogins 10

       如果发现自己想设 nproc 或 maxlogins 为0,可能还不如删掉这个用户。上面的例子设定了 dev 组的进程,核心文件和maxlogins的设置。其他的设为一个默认值

注释:/etc/security/limits.conf 是PAM包的一部分,仅适用于使用了PAM的包。

/etc/limits 

       /etc/limits 与限制文件/etc/security/limits.conf非常相似。唯一的区别在于格式,仅对用户或通配符起作用(对组无效)。看看得体的配置:

代码 6.2: /etc/limits

*   L2 C0 U15 R10000
kn L10 C100000 U35

       这里我们设定了默认设置并为用户kn采用了特定的设置。限制是sys-apps/shadow包的一部分。如果在 make.conf 禁用了pam 或者没有恰当的配置PAM,在这个文件中设定限制就没有必要了。

配额 

警告: 确保你采用文件系统支持配额。ReiserFS就不支持。

       在文件系统上施加限额可以避免用户塞满磁盘甚至根本不许写入。限额在内核中启用并加入挂载点。该内核选项在内核配置的File systems->Quota support下打开。采用如下的设置,重建内核并重启到新内核。

       敲入 emerge quota 开始安装配额。然后修改 /etc/fstab 给你想限制磁盘使用的分区增加usrquota和grpquota,如下例:

代码 6.3: /etc/fstab

/dev/sda1 /boot ext2 noauto,noatime 1 1
/dev/sda2 none swap sw 0 0
/dev/sda3 / reiserfs notail,noatime 0 0
/dev/sda4 /tmp ext3 notail,noatime,nodev,nosuid,noexec,usrquota,grpquota 0 0
/dev/sda5 /var ext3 notail,noatime,nodev,usrquota,grpquota 0 0
/dev/sda6 /home ext3 notail,noatime,nodev,nosuid,usrquota,grpquota 0 0
/dev/sda7 /usr reiserfs notail,noatime,nodev,ro	0 0
/dev/cdroms/cdrom0 /mnt/cdrom iso9660 noauto,ro 0 0
proc /proc proc defaults 0 0

       在开启了配额的每个分区上创建配额文件(quota.user和quota.group),将其放在分区的根目录中。

代码 6.4: Creating the quota files

# touch /tmp/quota.user
# touch /tmp/quota.group
# chmod 600 /tmp/quota.user
# chmod 600 /tmp/quota.group

       这一步必须在启用了配额的每个分区上完成。增加和配置配额文件后,还要把quota脚本加入到引导运行级。

代码 6.5: Adding quota to the boot runlevel

# rc-update add quota boot

       现在我们配置系统以每周检查配额一次,在 /etc/crontab 中加入下行:

代码 6.6: Adding quota check to crontab

0 3 * * 0 /sbin/quotacheck -avug.

       重启,是时候设置用户和组配额了。edquota -u kn 将打开$EDITOR中定义的编辑器 (默认是nano)让你编辑用户kn的配额。edquota -g大体相同,编辑组配额。

代码 6.7: Setting up quota's for user kn

Quotas for user kn:
/dev/sda4: blocks in use: 2594, limits (soft = 5000, hard = 6500)
         inodes in use: 356, limits (soft = 1000, hard = 1500)

       进一步的细节参考 man edquota 或 配额小指南.

/etc/login.defs 

       如果政策要求用户每两周改变一次密码,把 PASS_MAX_DAYS 的值改为14, PASS_WARN_AGE 改为7。建议使用密码龄因为暴力方法可以找出任何密码,只是迟早的问题。鼓励将 LOG_OK_LOGINS 设为yes。

/etc/login.access 

       login.access 文件也是sys-apps/shadow包的一部分,给出了登录访问控制表。该表用于根据用户名,组名或主机名控制谁可以谁不能登录。按默认所有系统的用户都可以登录,所以该文件全部由注释和示例组成。无论是服务器还是工作站,我们建议设置该文件以免除你 (管理员)之外的其他人访问控制台。

注释: 这个设置不适用于root。

代码 6.8: /etc/login.access

-:ALL EXCEPT wheel sync:console
-:wheel:ALL EXCEPT LOCAL .gentoo.org

重要: 配置这些选项时要小心,如果你没有root访问权限,一旦出错你将无法访问机器。

注释: 这些设置不适用于SSH,因为默认SSH并不执行/bin/login。可以在 /etc/ssh/sshd_config 中使用 UseLogin yes 来打开。这样SSH就会使用login,设置对其就生效了。

       这样设置登录访问使wheel组成员既可本地登录亦可从gentoo.org域登录。可能过于杞人忧天了,不过有备无患啊!

7. 文件访问权限


 

其他人可读 

       一般用户不可拥有配置文件或密码的访问权。攻击者可能从数据库或网站偷窃密码利用密码歪曲甚而删除资料。这正是访问权限正确的重要性之所在。如果你能肯定某个文件仅为root使用,设置其访问权限为0600,并通过chown将此文件指派给正确的用户。

其他人/组成员可写 

代码 7.1: Finding world-writable files and directories

# /usr/bin/find / -type f \( -perm -2 -o -perm -20 \) \
   -exec ls -lg {} \; 2>/dev/null >writable.txt
# /usr/bin/find / -type d \( -perm -2 -o -perm -20 \) \
   -exec ls -ldg {} \; 2>/dev/null >>writable.txt

       这将创建一个包含了所有组成员或其他人有写权限的文件的巨大文件。检查权限,在这些文件上执行/bin/chmod o-w 以消除其他人的写权限。

SUID/SGID文件 

       设了SUID或SGID位的文件允许以文件所有者或组而不是运行者的权限来执行。通常这些位用于必须以root权限运行才能完成功能的文件。这些文件可能导致本地root安全泄漏 (如果其包含安全漏洞)。这样非常危险,要不惜一切代价避免带SUID或SGID位的文件。如果你不用它们,对他们chmod 0或者干脆unmerge包含它们的包(用qpkg -f 检查它们所属的包。如果还没有qpkg, 只需emerge gentoolkit)。否则的话只有用 chmod -s 关闭SUID位。

代码 7.2: Finding setuid files

# /usr/bin/find / -type f \( -perm -004000 -o -perm -002000 \) \
  -exec ls -lg {} \; 2>/dev/null >suidfiles.txt

       这会创建一个包含所有SUID/SGID文件列表的文件。

代码 7.3: List of setuid binaries

/bin/su
/bin/ping
/bin/mount
/bin/umount
/var/qmail/bin/qmail-queue
/usr/bin/chfn
/usr/bin/chsh
/usr/bin/crontab
/usr/bin/chage
/usr/bin/expiry
/usr/bin/sperl5.6.1
/usr/bin/newgrp
/usr/bin/passwd
/usr/bin/gpasswd
/usr/bin/procmail
/usr/bin/suidperl
/usr/lib/misc/pt_chown
/usr/sbin/unix_chkpwd
/usr/sbin/traceroute
/usr/sbin/pwdb_chkpwd

       默认情况下Gentoo Linux没有太多SUID文件(取决于你装的是什么),但你可能会得到类似上面的列表。对ping, mount, umount, chfn, chsh, newgrp, suidperl, pt_chown 和 traceroute 每个文件运行chmod -s以关闭SUID位。不要移去su, qmail-queue 或 unix_chkpwd的SUID位,否则你不能SU或接收邮件了。移去SUID位后,普通用户(或者攻击者)就不可能通过它们来获取root访问权限了。

       我的系统中有SUID位的文件只有 su, passwd, gpasswd, qmail-queue, unix_chkpwd 和 pwdb_chkpwd。如果你运行X的话,可能会有更多,因为X需要该权限。

8. PAM (可插入鉴证模块)


 

       PAM是一套共享库,它提供了在程序中进行鉴证的一种可供选择的途径。pam USE标志默认是打开的。因此Gentoo Linux中的PAM设置一般已相当合理,当然百尺竿头,还可更进一步。首先安装cracklib。

代码 8.1: Installing cracklib

# emerge cracklib

代码 8.2: /etc/pam.d/passwd

auth	 required pam_unix.so shadow nullok
account	 required pam_unix.so
password required pam_cracklib.so difok=3 retry=3 minlen=8 dcredit=2 ocredit=2 
password required pam_unix.so md5 use_authtok
session	 required pam_unix.so

       这样加入cracklib。cracklib保证用户密码不少于8位、至少两位数字、两位其他并与前次的密码至少有3位不同。这样促使用户选择好的密码(密码政策)。检查 PAM文档以获取更多的选项。

代码 8.3: /etc/pam.d/sshd

auth	 required pam_unix.so nullok 
auth     required pam_shells.so
auth	 required pam_nologin.so
auth	 required pam_env.so
account	 required pam_unix.so
password required pam_cracklib.so difok=3 retry=3 minlen=8 dcredit=2 ocredit=2 use_authtok
password required pam_unix.so shadow md5
session	 required pam_unix.so
session	 required pam_limits.so

       在/etc/pam.d中没有配置PAM文件的服务将使用 /etc/pam.d/other中的规则。默认设置是deny,这是妥当的。不过我喜欢多一点日志,这正是我加上pam_warn.so的原因。最后的配置是 pam_limits,它受/etc/security/limits.conf控制。参 /etc/security/limits.conf section 以了解更多这些设置方面的内容。

代码 8.4: /etc/pam.d/other

auth     required pam_deny.so
auth     required pam_warn.so
account  required pam_deny.so
account  required pam_warn.so
password required pam_deny.so
password required pam_warn.so
session  required pam_deny.so
session  required pam_warn.so

9. TCP包装


 

       是一种控制对通常由inetd运行的服务的访问的方式。Gentoo没有inetd,但xinetd和其他服务也可以使用它。

注释: 此服务在其服务器参数(xinetd中)应执行tcpd。参关于xinetd的章节以获取更多信息。

代码 9.1: /etc/hosts.deny

ALL:PARANOID

代码 9.2: /etc/hosts.allow

ALL: LOCAL @wheel
time: LOCAL, .gentoo.org

       容易发现其格式与/etc/login.access非常相似。Tcpd支持特定的服务,它们在安全的不同领域发挥作用。这些设置只适用于使用tcp包装的服务。

       也可能在访问服务时(可在激活拨入用户的中继时使用)执行命令,但不推荐这样做,因为常常人们在张罗着解决问题时却制造了更多的问题。比如你配置一个脚本,每当拒绝规则触发时发送邮件,可攻击者可以通过不断触发这个拒绝规则发起DoS(拒绝服务)攻击。大量I/O和邮件应劫而生,所以不要这样做。参阅 man 5 hosts_access 以获取更多的信息。

10. 内核安全


 

除去一些功能 

       配置内核的基本原则是不需要的通通清除。内核更紧凑,可能隐藏在设备驱动和其他功能中的弱点也消除了。

       也要考虑关闭可加载模块支持。尽管没有这个功能也可能加入模块(root工具包),但普通攻击者经由内核模块安装root工具包要困难些。

/proc (内核旗标) 

       许多内核参数都可通过 /proc 文件系统或使用 sysctl 修改。

       要运行中动态更改内核参数你必须在内核中定义 CONFIG_SYSCTL 。这是标准 2.4 内核的默认设置。

代码 10.1: Drop ping packets

# /bin/echo "1" > /proc/sys/net/ipv4/icmp_echo_ignore_all

       这会使内核忽略所有又称为ICMP类型0消息的ping消息。这样做的原因是带有ICMP消息的IP包可能包含你意想不到的其他信息的有效负载。管理员用ping作为诊断工具,如果不能ping他们会抱怨。外来者没有理由可以ping。但是有时内部用户可以ping很方便。这可以通过在防火墙中禁止ICMP类型0消息来解决。

代码 10.2: Ignore broadcast pings

# /bin/echo "1" > /proc/sys/net/ipv4/icmp_echo_ignore_broadcasts

       这禁止响应ICMP广播,可以避免Smurf攻击。 Smurf攻击的原理是往一个网络的广播地址发送一个ICMP类型0(ping)消息。攻击者一般使用伪装的源地址。该网络上的所有电脑都会应答这个ping消息,这样就淹没了被伪装的主机。

代码 10.3: Disable source routed packets

# /bin/echo "0" > /proc/sys/net/ipv4/conf/all/accept_source_route

       不要接受源路由包。攻击者可能利用源路由来产生伪装成产生于你的网络内部的通信量,而实际上它是在反向路由回产生的地方,这样攻击者可以危及你网络的安全。源路由极少用于合法用途,因此禁用之。

代码 10.4: Disable redirect acceptance

# /bin/echo "0" > /proc/sys/net/ipv4/conf/all/accept_redirects

       禁用ICMP重定向。它可用于修改你的路由表,可能是恶意的。

代码 10.5: Protect against bad error messages

# /bin/echo "1" > /proc/sys/net/ipv4/icmp_ignore_bogus_error_responses

       启用响应伪错误信息保护。

代码 10.6: Enable reverse path filtering

# for i in /proc/sys/net/ipv4/conf/*; do
        /bin/echo "1" > $i/rp_filter
done

注释: 如果打开IP转发,也会得到这个结果。

       打开逆向路径过滤。这可以保证包使用合法源地址,它自动拒绝源地址的路由表项与进入的网络接口不匹配的入包。这样可以防止IP伪装,有安全优势。

警告: 但是如果使用不对称路由(从你到你某个主机的包与从该主机到你的包采用不同的路径) 或者你使用不同接口上有几个IP地址的无路由主机,启用逆向路径过滤会有问题。

代码 10.7: Log all spoofed, source routed and redirect packets

# /bin/echo "1" > /proc/sys/net/ipv4/conf/all/log_martians

       记录IP伪装的包、源路由包和重定向包。

代码 10.8: Deactivate IP forwarding

# /bin/echo "0" > /proc/sys/net/ipv4/ip_forward

       确保关闭了IP转发。只有对多宿主主机我们才需要它。

       机器重启后所有这些设置都会被重设,因此建议把它们加入 /etc/sysctl.conf。 /etc/init.d/bootmisc 初始化脚本会自动运行它。

       /etc/sysctl.conf 的语法很直白。从前面提到的路径中剥去 /proc/sys/,用.替换掉 / 就可以了:

代码 10.9: Translating to sysctl.conf

(Manual using echo):
/bin/echo "0" > /proc/sys/net/ipv4/ip_forward

(Automatic in sysctl.conf:)
net.ipv4.ip_forward = 0

Grsecurity 

       Grsecurity的不定是Gentoo内核源代码的标准,但默认是禁用的。用通常的方式配置内核,配置Grsecurity选项。可用的Grsecurity选项(1.9版)的详细说明在 强化Gentoo 项目网页上。

       最新的grsec-sources提供了Grsecurity的2.*版。关于改进了的Grsecurity补丁集的更多信息,请参阅此处的文档 Grsecurity主页.

Kerneli 

       Kerneli是给现有内核增加加密的一个补丁。打了不定后会得到如Cryptographic ciphers、摘要算法和加密环过滤等新选项。

警告: 对最新的内核该补丁目前尚为不稳定版本,使用时多家加小心。

其他内核补丁 

       可能还有更多。

11. 加强服务的安全


 

Apache 

       Apache (1.3.26) 自带的配置文件相当不错,同样,还可改进一些地方。比如绑定到一个地址防止泄露信息。这些是你可以在配置文件中采用的选项。

       如果安装apache前在/etc/make.conf中没有禁用 ssl,你应该有了一个可使用SSL的服务器。只需加入下行启用之:

代码 11.1: /etc/conf.d/apache

HTTPD_OPTS="-D SSL"

代码 11.2: /etc/apache/conf/apache.conf

#Make it listen on your ip
Listen 127.0.0.1
BindAddress 127.0.0.1
#It is not a good idea to use nobody or nogroup - 
#for every service not running as root 
#(just add the user apache with group apache)
User apache
Group apache
#Will keep apache from telling about the version
ServerSignature Off
ServerTokens Prod

       Apache是以--enable-shared=max 和 --enable-module=all编译的。这样默认会启用所有模块,所以应在LoadModule节(LoadModule and AddModule) 注释掉所有你不用的模块。执行/etc/init.d/apache restart重启服务。

       可在http://www.apache.org找到相关文档。

Bind 

       可在Internet Software Consortium找到文档BIND 9 管理员参考手册也在 doc/arm 里面.

       较新的BIND ebuilds 支持chroot到本机以外。Emerge bind 后按这些简答的指示:

代码 11.3: 改换BIND根目录

ebuild /var/db/pkg/net-dns/bind-9.2.2-r2/bind-9.2.2-r2.ebuild config\`"
// 执行以上命令前可能要改变/etc/conf.d/named中的chroot目录,
否则会使用/chroot/dns。// 可能需要用当前版本号替换上面的版本号

Djbdns 

       Djbdns是一个DNS实现,起作者愿意对它的安全性 赌彩。其工作于Bind 9大有不同,但值得一试。从 http://www.djbdns.org 可以获得更多的信息。

FTP 

       一般而言,使用 FTP (文件传输协议) 不太好。它使用未加密数据,监听2个端口(通常为端口20和21),采用攻击者爱用的匿名登录。因为FTP协议包含了几个安全问题(如密码以明文发送),你应该使用sftp或HTTP。如果不得不用,尽可能增强服务的安全,做好准备。

Mysql 

       如果只需要本地应用访问 mysql 数据库,去掉下面行的注释。

代码 11.4: 禁止网络访问

skip-networking

       禁止使用LOAD DATA LOCAL INFILE 命令:

代码 11.5: 在[mysqld]区禁止 LOAD DATA LOCAL INFILE 命令的使用

set-variable=local-infile=0

       mysql 的默认安装设置的 root 密码为空。

代码 11.6: 设定 root 密码

/usr/local/mysql/bin/mysql -u root 
mysql> SET PASSWORD FOR root@localhost=PASSWORD('new_password');

注释: 不从命令行[如使用mysqladmin password命令]改变密码是好的做法。服务器上还有其他用户使用时这点尤为重要。那样密码很容易通过用如 ps aux 命令和查看历史文件(~/.history,~/.bash_history etc)而暴露。

       接着必须删除示例数据库(test)及除本地root外的所有帐户。

代码 11.7: 删除示例数据库和非必需用户

mysql> drop database test;
mysql> use mysql;
mysql> delete from db;
mysql> delete from user where not (host="localhost" and user="root");
mysql> flush privileges;

警告: 如果已配置好用户帐户,进行上步时要多加小心。

Proftpd 

       Proftpd有过几个安全问题,不过似乎多数已被修补好。还是采用一些改进措施:

代码 11.8: /etc/proftpd/proftpd.conf

ServerName "My ftp daemon"
#不显示服务器身份
ServerIdent on "Go away"

#便于创建虚用户
RequireValidShell off

#使用替代的密码和组文件(passwd采用加密格式)
AuthUserFile "/etc/proftpd/passwd"
AuthGroupFile "/etc/proftpd/group"

# 权限
Umask 077

# 超时和限制
MaxInstances 30
MaxClients 10 "Only 10 connections allowed"
MaxClientsPerHost 1 "You have already logged on once"
MaxClientsPerUser 1 "You have already logged on once"
TimeoutStalled 10

TimeoutNoTransfer 20
TimeoutLogin 20

# Chroot 每个人
DefaultRoot ~

# 不要以root运行
User  nobody
Group nogroup

# 记录每次传输
TransferLog /var/log/transferlog

# 使用通配符的问题
DenyFilter \*.*/

       可在 http://www.proftpd.org 找到文档。

Pure-ftpd 

       Pure-ftpd 是原来的 trollftpd 一个分枝。Frank Dennis基于安全和功能上的考虑做了修改。

       启用 AUTH 选项使用虚用户(觉不要使用系统帐户)。把它设为 -lpuredb:/etc/pureftpd.pdb 并用 /usr/bin/pure-pw 创建用户。

代码 11.9: /etc/conf.d/pure-ftpd

AUTH="-lpuredb:/etc/pureftpd.pdb"

## Misc. Others ##
MISC_OTHER="-A -E -X -U 177:077 -d -4 -L100:5 -I 15"

       并配置 MISC_OTHER 设置为不允许匿名(-E),chroot每个人(-A), 用户不可读写以.(小数点)开头的文件(-X), 最大空闲时间(-I), 限制递归(-L), 及合理的 umask.

警告:不要 使用 -w 或 -W 选项! 如果想建 warez 网站,您还是别往下看了!

       可在 http://www.pureftpd.org 找到文档。

Qmail 

       Qmail被认为是最安全的邮件服务器。它是带着安全考虑(甚至是过虑)写成的。默认它不允许中继,从1996年起就没有过安全漏洞。只需 emerge qmail 然后去配置!

Samba 

       Samba 是与Microsoft/Novell网络共享文件的协议,不可在互联网上使用。尽管如此还是要考虑安全问题。

代码 11.10: /etc/samba/smb.conf

[global]
  # 绑定到接口
  interfaces = eth0 10.0.0.1/32

  # 确保使用加密口令
  encrypt passwords = yes
  directory security mask = 0700

  #允许来自 10.0.0.* 的通信
  hosts allow = 10.0.0.

  # 启用用户认证 
  #( 不要使用共享模式 )
  security = user
  
  # 不允许特权帐户
  invalid users = root @wheel

  # smb显示给共享的最大值 (不是限制)
  max disk size = 102400

  # 捍卫密码政策
  min password length = 8
  null passwords = no

  # 使用( 如果加入了支持 )
  obey pam restrictions = yes
  pam password change = yes

       要确保每个共享上的权限正确设置,记得看 文档.

       重启服务器,加入应有访问权的用户。通过 /usr/bin/smbpasswd 命令代 -a 参数来完成。

ssh 

       OpenSSH需要的唯一安全强化是打开基于公密钥加密的一种更强的鉴证。太多的网站(如http://www.sourceforge.net, http://www.php.nethttp://www.apache.org) 的系统由于口令泄露或口令不好而遭受非法入侵。

代码 11.11: /etc/ssh/sshd_config

# 只启用版本 2
Protocol 2

# 禁止 root 登录。用户必须su为root
PermitRootLogin no

# 打开公密钥鉴证
PubkeyAuthentication yes
AuthorizedKeysFile      .ssh/authorized_keys

# 禁止 .rhost 和常规密码鉴证
RhostsAuthentication no
PasswordAuthentication no
PermitEmptyPasswords no

AllowHosts *.gentoo.org

# 只允许 wheel 或 admin 组的用户登录
AllowGroups wheel admin

# 只允许那些组中的如下用户
AllowUsers kn bs

# 日志 
SyslogFacility AUTH
LogLevel INFO

ListenAddress 127.0.0.1

       现在你的用户们只需要用如下命令创建一个密钥(在他们想从其登录的机器上):

代码 11.12: 创建 DSA 密钥对

# /usr/bin/ssh-keygen -t dsa

       键入密码

代码 11.13: ssh-keygen的输出

Generating public/private dsa key pair.
Enter file in which to save the key (/home/kn/.ssh/id_dsa):[Press enter]
Created directory '/home/kn/.ssh'.
Enter passphrase (empty for no passphrase): [Enter passphrase]
Enter same passphrase again: [Enter passphrase again]
Your identification has been saved in /home/kn/.ssh/id_dsa.
Your public key has been saved in /home/kn/.ssh/id_dsa.pub.
The key fingerprint is:
07:24:a9:12:7f:83:7e:af:b8:1f:89:a3:48:29:e2:a4 kn@knielsen

       这会在你的~/.ssh/目录中加入两个文件,名字是 id_dsa 和 id_dsa.pub。 id_dsa 文件是你的私钥不可让他人接触。另一个文件 id_dsa.pub 要派发给你有访问权的每个服务器。在~/.ssh/authorized_keys中把该密钥加入用户的主目录,这样用户应该就可以登录了。

       现在用户们要看好这个私钥。放在他们可以随身携带的介质上或者他们的工作站上 (把这点写入密码政策中).

       若需要更多信息,请移架 OpenSSH 网址。

使用 xinetd 

       xinetd 取代互联网服务守护程序inetd (Gentoo没用这个)。它支持基于远程主机地址和访问时间的访问控制。它还提供了扩展日志能力,包括服务开始时间、远程主机地址、远端用户名、服务运行时间和请求的动作。

       与其他服务相同,好的默认配置非常重要。但是因为 xinetd 是以root运行的而且支持多种你可能不知为何物的协议,我们建议你不要使用它。如果还是决定使用,这是加入一些安全措施的办法:

代码 11.14: 安装l xinetd

# emerge xinetd tcp-wrappers

       编辑配置文件:

代码 11.15: /etc/xinetd.conf

defaults
{
 only_from      = localhost
 instances      = 10
 log_type       = SYSLOG authpriv info
 log_on_success = HOST PID
 log_on_failure = HOST
 cps            = 25 30
}

# 将以如下设定经由xinetd设置 pserver (cvs):
# 最多 10 个实例 (一次 10 个连接)
# 限制 pserver 只用 tcp 
# 使用用户 cvs 运行本服务
# 把接口只绑定到一个ip上
# 允许来自 10.0.0.* 的连接
# 现在开发人员使用cvs的时间从早8点到晚5点
# 使用 tpcd 包装 ( 访问控制在
# /etc/hosts.allow和/etc/hosts.deny中)
# 该机 max_load 设为 1.0
# disable 标志默认设为no, 但我还是加上了 
# 以策安全
service cvspserver
{
 socket_type    = stream
 protocol       = tcp
 instances      = 10
 protocol       = tcp
 wait           = no
 user           = cvs
 bind           = 10.0.0.2
 only_from      = 10.0.0.0
 access_times   = 8:00-17:00
 server         = /usr/sbin/tcpd
 server_args    = /usr/bin/cvs --allow-root=/mnt/cvsdisk/cvsroot pserver
 max_load       = 1.0
 log_on_failure += RECORD
 disable        = no
}

       如需更多信息,参阅 man 5 xinetd.conf.

Vsftpd 

       Vsftpd (非常安全的ftp的缩写)是一个小型的ftp守护程序,运行的默认配置文件相当合理。程序很单纯,没有pureftp和proftp那么多功能(比如虚用户)

代码 11.16: /etc/vsftpd

anonymous_enable=NO
local_enable=YES

#read only
write_enable=NO

#enable logging of transfers
xferlog_std_format=YES

idle_session_timeout=20
data_connection_timeout=20
nopriv_user=nobody

chroot_list_enable=YES
chroot_list_file=/etc/vsftpd/chrootlist

ls_recurse_enable=NO

       可以看出该服务没办法单个设置权限也没有默认的chroot动作。但说道匿名设置,它相当出色。有时需要匿名ftp服务器(用于开源共享),这是vsftpd的拿手绝活。

       按默认XFree配置成充当X服务器。这可能非常危险,因为X使用未加密的TCP连接监听X客户。

重要: 如果不需要这个服务,禁用之!

       但如果你需要把你的工作站用作X服务器,要慎重使用/usr/X11R6/bin/xhost命令。如果你需要不同机器上的X程序而通过网络是唯一办法是,这个就很好用了。语法是: /usr/X11R6/bin/xhost +hostname

警告: 绝对不要使用 xhost + 功能! 这会允许任何客户连入并控制你的X。如果攻击者能访问X,他就可以记录下你的键盘动作并控制你的桌面。如果不能不用,一定记得指定主机。

       更安全的办法通过用startx -- -nolisten tcp 启动X彻底禁用它,或者在配置文件中永久性的禁用它。

代码 11.17: /usr/X11R6/bin/startx

defaultserverargs="-nolisten tcp"

       为了保证emerge新版的XFree时 startx 不被覆盖,必须保护它。把下面一行加入 /etc/make.conf:

代码 11.18: /etc/make.conf

CONFIG_PROTECT_MASK="/usr/X11R6/bin/startx"

       如果使用图形登录管理器,办法有所不同。

       对 gdm (Gnome 显示管理器)

代码 11.19: /etc/X11/gdm/gdm.conf

[server-Standard]
command=/usr/X11R6/bin/X -nolisten tcp

       对 xdm (X 显示管理器) 和 kdm (Kde 显示管理器)

代码 11.20: /etc/X11/xdm/Xservers

:0 local /usr/bin/X11/X -nolisten tcp 

12. Chroot和虚用户


 

Chroot 

       Chroot服务是限制(或用户)环境使之只可访问必要内容而不访问可能导向root访问权内容的一种限制。通过以其他用户而非root (nobody, apache, named) 来运行服务,攻击者只能以该用户的权限来访问文件。意味着即使服务有安全缺陷,攻击者也不能获得 root 访问权。

       有些服务,如 pure-ftpd 和 bind,有choot功能,有些没有。如果服务支持,使用它;否则只好自己摸索创建一个。我们看看如何创建一个choot, 以便理解choot工作的基本原理,我们用 bash来测试之(最佳学习方法)。

       用mkdir chroot建立/chroot目录。搞清 bash 编译所用的动态库 (如果是用-static选项编译的,这一步就不必了):

       下面的命令会产生bash所用库的列表。

代码 12.1: 取得使用库的列表

# ldd /bin/bash
  libncurses.so.5 => /lib/libncurses.so.5 (0x4001b000)
  libdl.so.2 => /lib/libdl.so.2 (0x40060000)
  libc.so.6 => /lib/libc.so.6 (0x40063000)
  /lib/ld-linux.so.2 => /lib/ld-linux.so.2 (0x40000000)

       现在建立 bash 的环境变量。

代码 12.2: 为bash建立 chroot 环境

# mkdir /chroot/bash
# mkdir /chroot/bash/bin
# mkdir /chroot/bash/lib

       下一步把 bash (/lib) 使用的文件复制到 chroot 后的 lib 并将 bash命令复制到chroot厚的 bin目录。这样会建立完全相同的环境,只是功能少一点。复制完成后试着: chroot /chroot/bash。如果提示说 /就对了! 否则,可能会告诉你缺少了什么文件。有些共享库互相依赖。

       注意到在chroot内除了echo什么都不能用了吗?这是因为在我们的chroot环境中除 bash外什么命令都没有,echo 是bash的内建功能。

       基本而言,要建立chroot的服务方法相同。唯一的区别服务有时依赖于设备和/etc中配置文件。只需将他们复制到chroot后的环境 (设备可用 cp -a 复制),编辑 init 脚本以在执行前使用 chroot。有时很难搞清服务使用了的设备和配置文件。这时 strace 命令九派上用场了。用 /usr/bin/strace bash 启动服务,查找open, read, stat可能还有connect。这可以给你要拷贝那些文件的线索。但多数情况下只需复制passwd文件(编辑该拷贝,删除与本服务无关的用户), /dev/zero, /dev/log 和 /dev/random.

虚拟服务器 

       通过虚拟服务器环境是建立更安全的环境的又一途径,它建立现有Linux的一个拷贝,在虚拟模式中引导之。意味着如果该服务器被攻破,攻破的并非实际的安装,而只是该虚拟服务器。

       虚拟服务器的示例:

13. 防火墙


 

防火墙 

       人们常常认为防火墙提供了终极安全,错了。大多数情况下配置不良的防火墙比没有防火墙更不安全。防火墙也是软件,应该象对待其他软件一样对待它,因为它同样可能包含bug。

       所以实施前要想清楚! 是否真有必要?如果是,要写出它如何工作方式,类型,操作人员的政策。还是现读完本指南。

       防火墙用于两种目的:

       基本而言有三种类型的防火墙:

       防火墙应是专用机器,没有运行任何服务(或者只运行 sshd ),且用本指南推荐的方法强化安全。

包过滤 

       所有网络交通都是以包的形式。大量的通讯也分割成小的包以便于处理并在到达目的地后重新组装起来。 每个包的包头中办好了如何投递及投递到那里的信息。包过滤防火墙正是使用这些信息。过滤基于:

       基本而言过滤的依据是包头中的所有数据而非包内容。

       弱点:

       长处:

       Linux上自由/免费包过滤程序举例:

回路中继 

       或称回路层网关,是在允许数据交换前先验证连接的一种防火墙。这意味着不是根据包头来放行或拒绝包,而是在开始会话允许数据交换前,根据可配置的规则验证两端之间的连接的有效性。过滤基于:

       所有通讯都被验证、监视,不想要的通讯会被丢掉。

       弱点:

应用网关 

       应用层网关应用程序的代理,它代表客户程序与远端系统交换数据。它远离大众,安处DMZ(非军事区: 通过防火墙可见的私有网络部分)或不允许外部连接的防火墙之后。他的过滤依据是:

       长处:

       弱点:

       应用网关被认为是最安全的解决办法,因为它无须以root运行,其后的主机无法从互联网进入。

       自由/免费应用网关的实例:

Iptables 

       必须在内核中启用,iptables才可工作。我把它们加为模块 (iptables 命令会在需要是装入它们) 并重新编译了内核。如何配置iptables的更多信息,请移架 Iptables 教程第二章: 准备。编译新内核后(或编译时), 需要加入 iptables 命令。 只需 emerge iptables 应该就可以了。

       运行 iptables -L 测试是否正常工作。如果失败,一定是什么地方搞错了,只好在检查一遍配置文件了。

       Iptables是Linux 2.4.x内核中新的极大改进了的包过滤器。是以前的Linux 2.2.x内核中的ipchains的后继。重大改进之一是iptables可完成有状态的包过滤。有状态包过滤使管理每个已建立的TCP连接成为可能。

       一个 TCP 连接由一系列的包含源IP地址,目的IP地址,序号信息的包组成,这样包可以重新组装起来而不会遗漏数据。与无连接的UDP相对应,TCP是一种面向连接的协议。

       通过检查TCP包头,有状态包过滤器可以判断接收到的包是否已建立连接的一部分,从而决定是否接受该包。

       通过在TCP包头做手脚欺骗无状态包过滤器接受应该丢弃的包是完全可能的。可以改动TCP头的SYN或其他标志来做到。而有状态包过滤器则可能丢弃这些包,因为他们不是已建立连接的一部分。"隐形扫描"也没了可能,因为这样的包不会属于任何已建立的连接。

       Iptables提供了诸如NAT(网络地址转换)和限速的一些其他功能。对防范比如SYN洪水一类的某些DoS(拒绝服务)攻击,限速极其有用。

       TCP连接通过所谓的三次握手建立。建立TCP连接是,客户端向服务器发送一个设置了SYN标志的包。收到SYN包后,服务器向客户端回送SYN+ACK包。客户端收到SYN+ACK后用第三个ACK包应答,确认连接的建立。

       SYN洪水攻击通过发SYN包但不应答SYN+ACK包来进行。客户端可以编造一个代假源IP地址的包,反正它根本不需要回复。服务器方系统收到SYN包后会在半开连接队列中加入一项,等到最后的 ACK后在把该项从队列中删除。队列的容量有限,填满后就无法打开新的连接了。在指定的超时过后如果没有收到ACK, 该项将自动从队列中被删除。超时设定可以变化但大致在30-60秒,甚至更多。客户方发起攻击的方法是,尽可能快地伪造大量不同源IP地址的SYN包发往目标IP地址,以填满半开连接队列,从而使其他用户不能与服务器建立起合法的连接。

       限速在这里派上用场。可以通过使用 -m limit --limit 1/s 来限制接受SYN包的速度。这样会限制SYN包接受数目为每秒一个,从而限制了我方资源上的SYN洪水。

       现在来点实际的东西!

       内核装入iptables时有5个钩子可以放你的规则。他们是 INPUT, OUTPUT, FORWARD, PREROUTING 和 POSTROUTING。每个成为一个链,有一组规则组成。每个规则指明如果包长得这样,就这样处置它。如果规则不匹配,就查看该链中的现一个规则。

       可以直接在5个主链中放入规则,也可以建立新的链,作为一条规则加入现有的链中。 Iptables 支持如下选项:

选项:说明:
-A追加
-D删除
-I插入
-R替换
-L列示
-F删除链中的所有规则或所有链
-Z链或所有链中的计数器归零
-C在链上测试该包
-N创建新的用户定义链
-X删除用户定义链
-P改变链上的政策为目标
-E改变链名
-p协议
-s源地址/掩码
-d目标地址/掩码
-i输入名 (以太网名)
-o输出名 (以太网名)
-j跳到 (目标找规则)
-m扩展匹配 (可能使用扩充)
-n地址和端口的数字输出
-t操作的表
-v详细提示模式
-x扩展数字 (显示确切值)
-f只匹配第二个或更多的片段
-V包版本
--line-numbers列示时打印行号

       首先我们试着阻止到我们的机器上的所有ICMP包,就为了搞熟iptables。

代码 13.1: 阻止所有 ICMP 包

# iptables -A INPUT -p icmp -j DROP

       首先指定要加入的链,接着是协议,然后是目标。目标可以是用户指定的链名,也可以是如下特殊目标之一: ACCEPT, DROP, REJECT, LOG, QUEUE, MASQUERADE。本例中我们使用了DROP,它不响应客户,直接丢弃包。

       现在试着 ping localhost。不会得到应答,因为iptable丢弃了所有进入的ICMP报文。也ping不到其他机器因为回复的ICMP会被丢弃。现在刷新链,以便可以再得到ICMP流。

代码 13.2: 刷新所有规则

# iptables -F

       现在看看iptables中的有状态包过滤。如果想要对从eth0进入包进行有状态的检查,可以发出如下命令启用它:

代码 13.3: 接受产生自已经建立的连接的包

# iptables -A INPUT -i eth0 -m state --state ESTABLISHED,RELATED -j ACCEPT

       这会接受任何来自已建立连接或与在INPUT链中有关的包。可在此前发出iptables -A INPUT -i eth0 -m state --state INVALID -j DROP 以丢弃不在状态表中的包。这样通过装如扩展状态启用了iptables中的有状态包过滤。如果想允许他人连接到你的机器,可以使用 --state NEW。iptables包含一些用于不同目的的模块。其中的一些是:

模块/匹配说明扩展选项
mac入包mac地址匹配扩展--mac-source
state打开带状态检查--state (states为ESTABLISHED,RELATED, INVALID, NEW)
limit速度匹配限制--limit, --limit-burst
owner尝试匹配包建立这的各种特征--uid-owner userid --gid-owner groupid --pid-owner processid --sid-owner sessionid
unclean对包的各种随机理性检查

       我们来试试建立用户定义链并将其应用到一个现有的链中:

代码 13.4: 创建用户定义链

// 创建一个只有一条规则的新链
# iptables -X mychain
# iptables -N mychain
# iptables -A mychain -i eth0 -m state --state ESTABLISHED,RELATED -j ACCEPT// 默认政策是允许所有流出的通讯,丢弃进入的。
# iptables -P OUTPUT ACCEPT
# iptables -P INPUT DROP// 将其加入 INPUT 链
# iptables -A INPUT -j mychain

       把该规则应用到输入链后我们得到这样的政策:允许所有流出包,丢弃所有流入包。

       可在 Netfilter/iptables 文档 找到文档。

       看看一个完整的例子。这个例子下我的防火墙和网关的政策是这样的:

代码 13.5: /etc/init.d/firewall

#!/sbin/runscript
IPTABLES=/sbin/iptables
IPTABLESSAVE=/sbin/iptables-save
IPTABLESRESTORE=/sbin/iptables-restore
FIREWALL=/etc/firewall.rules
DNS1=212.242.40.3
DNS2=212.242.40.51
#内部
IIP=10.0.0.2
IINTERFACE=eth0
LOCAL_NETWORK=10.0.0.0/24
#外部
OIP=217.157.156.144
OINTERFACE=eth1

opts="${opts} showstatus panic save restore showoptions rules"

depend() {
  need net
}

rules() {
  stop
  ebegin "Setting internal rules"

  einfo "Setting default rule to drop"
  $IPTABLES -P FORWARD DROP
  $IPTABLES -P INPUT   DROP
  $IPTABLES -P OUTPUT  DROP

  #默认规则
  einfo "Creating states chain"
  $IPTABLES -N allowed-connection
  $IPTABLES -F allowed-connection
  $IPTABLES -A allowed-connection -m state --state ESTABLISHED,RELATED -j ACCEPT
  $IPTABLES -A allowed-connection -i $IINTERFACE -m limit -j LOG --log-prefix \ 
      "Bad packet from ${IINTERFACE}:"
  $IPTABLES -A allowed-connection -j DROP

  #ICMP通迅
  einfo "Creating icmp chain"
  $IPTABLES -N icmp_allowed
  $IPTABLES -F icmp_allowed
  $IPTABLES -A icmp_allowed -m state --state NEW -p icmp --icmp-type \ 
      time-exceeded -j ACCEPT
  $IPTABLES -A icmp_allowed -m state --state NEW -p icmp --icmp-type \ 
      destination-unreachable -j ACCEPT
  $IPTABLES -A icmp_allowed -p icmp -j LOG --log-prefix "Bad ICMP traffic:"
  $IPTABLES -A icmp_allowed -p icmp -j DROP

  #进入通讯
  einfo "Creating incoming ssh traffic chain"
  $IPTABLES -N allow-ssh-traffic-in
  $IPTABLES -F allow-ssh-traffic-in
  #Flood protection
  $IPTABLES -A allow-ssh-traffic-in -m limit --limit 1/second -p tcp --tcp-flags \ 
      ALL RST --dport ssh -j ACCEPT
  $IPTABLES -A allow-ssh-traffic-in -m limit --limit 1/second -p tcp --tcp-flags \ 
      ALL FIN --dport ssh -j ACCEPT
  $IPTABLES -A allow-ssh-traffic-in -m limit --limit 1/second -p tcp --tcp-flags \ 
      ALL SYN --dport ssh -j ACCEPT
  $IPTABLES -A allow-ssh-traffic-in -m state --state RELATED,ESTABLISHED -p tcp --dport ssh -j ACCEPT

  #外出通讯
  einfo "Creating outgoing ssh traffic chain"
  $IPTABLES -N allow-ssh-traffic-out
  $IPTABLES -F allow-ssh-traffic-out
  $IPTABLES -A allow-ssh-traffic-out -p tcp --dport ssh -j ACCEPT

  einfo "Creating outgoing dns traffic chain"
  $IPTABLES -N allow-dns-traffic-out
  $IPTABLES -F allow-dns-traffic-out
  $IPTABLES -A allow-dns-traffic-out -p udp -d $DNS1 --dport domain \ 
      -j ACCEPT
  $IPTABLES -A allow-dns-traffic-out -p udp -d $DNS2 --dport domain \ 
     -j ACCEPT

  einfo "Creating outgoing http/https traffic chain"
  $IPTABLES -N allow-www-traffic-out
  $IPTABLES -F allow-www-traffic-out
  $IPTABLES -A allow-www-traffic-out -p tcp --dport www -j ACCEPT
  $IPTABLES -A allow-www-traffic-out -p tcp --dport https -j ACCEPT

  #捕获端口扫描
  einfo "Creating portscan detection chain"
  $IPTABLES -N check-flags
  $IPTABLES -F check-flags
  $IPTABLES -A check-flags -p tcp --tcp-flags ALL FIN,URG,PSH -m limit \ 
      --limit 5/minute -j LOG --log-level alert --log-prefix "NMAP-XMAS:" 
  $IPTABLES -A check-flags -p tcp --tcp-flags ALL FIN,URG,PSH -j DROP
  $IPTABLES -A check-flags -p tcp --tcp-flags ALL ALL -m limit --limit \ 
      5/minute -j LOG --log-level 1 --log-prefix "XMAS:"
  $IPTABLES -A check-flags -p tcp --tcp-flags ALL ALL -j DROP
  $IPTABLES -A check-flags -p tcp --tcp-flags ALL SYN,RST,ACK,FIN,URG \ 
      -m limit --limit 5/minute -j LOG --log-level 1 --log-prefix "XMAS-PSH:"
  $IPTABLES -A check-flags -p tcp --tcp-flags ALL SYN,RST,ACK,FIN,URG -j DROP
  $IPTABLES -A check-flags -p tcp --tcp-flags ALL NONE -m limit \ 
      --limit 5/minute -j LOG --log-level 1 --log-prefix "NULL_SCAN:"
  $IPTABLES -A check-flags -p tcp --tcp-flags ALL NONE -j DROP
  $IPTABLES -A check-flags -p tcp --tcp-flags SYN,RST SYN,RST -m limit \ 
      --limit 5/minute -j LOG --log-level 5 --log-prefix "SYN/RST:"
  $IPTABLES -A check-flags -p tcp --tcp-flags SYN,RST SYN,RST -j DROP
  $IPTABLES -A check-flags -p tcp --tcp-flags SYN,FIN SYN,FIN -m limit \ 
      --limit 5/minute -j LOG --log-level 5 --log-prefix "SYN/FIN:"
  $IPTABLES -A check-flags -p tcp --tcp-flags SYN,FIN SYN,FIN -j DROP

  # 向链中应用并加入无效状态
  einfo "Applying chains to INPUT"
  $IPTABLES -A INPUT -m state --state INVALID -j DROP
  $IPTABLES -A INPUT -j icmp_allowed 
  $IPTABLES -A INPUT -j check-flags
  $IPTABLES -A INPUT -i lo -j ACCEPT
  $IPTABLES -A INPUT -j allow-ssh-traffic-in
  $IPTABLES -A INPUT -j allowed-connection

  einfo "Applying chains to FORWARD"
  $IPTABLES -A FORWARD -m state --state INVALID -j DROP
  $IPTABLES -A FORWARD -j icmp_allowed 
  $IPTABLES -A FORWARD -j check-flags
  $IPTABLES -A FORWARD -o lo -j ACCEPT
  $IPTABLES -A FORWARD -j allow-ssh-traffic-in
  $IPTABLES -A FORWARD -j allow-www-traffic-out
  $IPTABLES -A FORWARD -j allowed-connection

  einfo "Applying chains to OUTPUT"
  $IPTABLES -A OUTPUT -m state --state INVALID -j DROP
  $IPTABLES -A OUTPUT -j icmp_allowed
  $IPTABLES -A OUTPUT -j check-flags
  $IPTABLES -A OUTPUT -o lo -j ACCEPT
  $IPTABLES -A OUTPUT -j allow-ssh-traffic-out
  $IPTABLES -A OUTPUT -j allow-dns-traffic-out
  $IPTABLES -A OUTPUT -j allow-www-traffic-out
  $IPTABLES -A OUTPUT -j allowed-connection

  #允许客户通过NAT(网路地址转换)路由
  $IPTABLES -t nat -A POSTROUTING -o $IINTERFACE -j MASQUERADE 
  eend $?
}

start() {
  ebegin "Starting firewall"
  if [ -e "${FIREWALL}" ]; then
    restore
  else
    einfo "${FIREWALL} does not exists. Using default rules."
    rules
  fi
  eend $?
}

stop() {
  ebegin "Stopping firewall"
  $IPTABLES -F
  $IPTABLES -t nat -F
  $IPTABLES -X
  $IPTABLES -P FORWARD ACCEPT
  $IPTABLES -P INPUT   ACCEPT
  $IPTABLES -P OUTPUT  ACCEPT
  eend $?
}

showstatus() {
  ebegin "Status"
  $IPTABLES -L -n -v --line-numbers
  einfo "NAT status"
  $IPTABLES -L -n -v --line-numbers -t nat
  eend $?
}

panic() {
  ebegin "Setting panic rules"
  $IPTABLES -F
  $IPTABLES -X
  $IPTABLES -t nat -F
  $IPTABLES -P FORWARD DROP
  $IPTABLES -P INPUT   DROP
  $IPTABLES -P OUTPUT  DROP
  $IPTABLES -A INPUT -i lo -j ACCEPT
  $IPTABLES -A OUTPUT -o lo -j ACCEPT
  eend $?
}

save() {
  ebegin "Saving Firewall rules"
  $IPTABLESSAVE > $FIREWALL
  eend $?
}

restore() {
  ebegin "Restoring Firewall rules"
  $IPTABLESRESTORE < $FIREWALL
  eend $?
}

restart() {
  svc_stop; svc_start
}

showoptions() {
  echo "Usage: $0 {start|save|restore|panic|stop|restart|showstatus}"
  echo "start)      will restore setting if exists else force rules"
  echo "stop)       delete all rules and set all to accept"
  echo "rules)      force settings of new rules"
  echo "save)       will store settings in ${FIREWALL}"
  echo "restore)    will restore settings from ${FIREWALL}"
  echo "showstatus) Shows the status" 
}

       建立防火墙的免费建议:

  1. 实施前建立好防火墙政策
  2. 尽量简单
  3. 了解协议工作原理(阅读 RFC(征求意见稿))
  4. 记住防火墙不过是又一个以root运行的软件
  5. 测试防火墙

       如果认为 iptables 难于理解,设置好的防火墙费时,可以使用 Shorewall。基本而言它使用 iptables 来产生 防火墙规则,但重心放在规则而不是特定协议上。

Squid 

       Squid 是一款非常强大的代理服务器软件,它可基于时间、路径/URI上的正则表达式,源/目的 IP地址、域、浏览器、鉴证过的用户名、MIME类型和端口号(协议)对通讯过滤。可能漏说了一些功能,不过要把它的完整的功能列表面面俱到太难了。

       下面的例子中我加入了条幅过滤器而不是色情网站过滤器。因为 Gentoo.org not 应该列入色情网站。我可不想费劲给你找几个好的网站。

       本例中我的政策是这样的:

       用 简单 的四个步骤来实施。

代码 13.6: /etc/squid/squid.conf

# 保定到一个 IP和端口
http_port 10.0.2.1:3128

# 标准配置
hierarchy_stoplist cgi-bin ?
acl QUERY urlpath_regex cgi-bin \?
no_cache deny QUERY

# 加入基本访问控制列表
acl all src 0.0.0.0/0.0.0.0
acl manager proto cache_object
acl localhost src 127.0.0.1/255.255.255.255

# 加入可以访问代理服务器的人员
acl localnet src 10.0.0.0/255.255.0.0

# 及端口
acl SSL_ports port 443
acl Safe_ports port 80
acl Safe_ports port 443
acl purge method PURGE

# 加入基于URL内的正则表达式的访问控制列表
acl archives urlpath_regex "/etc/squid/files.acl"
acl url_ads url_regex "/etc/squid/banner-ads.acl"

# 加入基于时间和日期的访问控制列表
acl restricted_weekdays time MTWHF 8:00-17:00
acl restricted_weekends time A 8:00-13:00

acl CONNECT method CONNECT

#允许manager从localhost访问
http_access allow manager localhost
http_access deny manager

# 只允许来自localhost(本地主机)的purge(清洗)请求
http_access allow purge localhost
http_access deny purge

# 拒绝对位置端口的请求
http_access deny !Safe_ports

# 就觉对SSL以外端口的CONNECT(连接)
http_access deny CONNECT !SSL_ports

# 我自己的规则

# 加入删除广告条幅后要显示的页
deny_info NOTE_ADS_FILTERED url_ads

# 可以拒绝它们了
http_access deny url_ads

# 拒绝所有的 archives(档案)
http_access deny archives

# 仅限于工作时间访问
http_access allow localnet restricted_weekdays
http_access allow localnet restricted_weekends

# 剩下的全部拒绝
http_access deny all

       接着是files中不希望你的用户下载的文件。我加入了zip, viv, exe, mp3, rar, ace, avi, mov, mpg, mpeg, au, ra, arj, tar, gz 和 z 文件。

代码 13.7: /etc/squid/files.acl

\.[Zz][Ii][pP]$
\.[Vv][Ii][Vv].*
\.[Ee][Xx][Ee]$
\.[Mm][Pp]3$
\.[Rr][Aa][Rr]$
\.[Aa][Cc][Ee]$
\.[Aa][Ss][Ff]$
\.[Aa][Vv][Ii]$
\.[Mm][Oo][Vv]$
\.[Mm][Pp][Gg]$
\.[Mm][Pp][Ee][Gg]$
\.[Aa][Uu]$
\.[Rr][Aa]$
\.[Aa][Rr][Jj]$
\.[Tt][Aa][Rr]$
\.[GgZz]$
\.[Zz]$

注释: 请注意[]中每个字母的大小写。这样做是为了避免有人骗过它访问AvI而不是avi文件

       下一步加入鉴定广告条幅的正则表达式。很可能你比我更有创意哦:

代码 13.8: /etc/squid/banner-ads.acl

/adv/.*\.gif$
/[Aa]ds/.*\.gif$
/[Aa]d[Pp]ix/
/[Aa]d[Ss]erver
/[Aa][Dd]/.*\.[GgJj][IiPp][FfGg]$
/[Bb]annerads/
/adbanner.*\.[GgJj][IiPp][FfGg]$
/images/ad/
/reklame/
/RealMedia/ads/.*
^http://www\.submit-it.*
^http://www\.eads.*
^http://ads\.
^http://ad\.
^http://ads02\.
^http://adaver.*\.
^http://adforce\.
adbot\.com
/ads/.*\.gif.*
_ad\..*cgi
/Banners/
/SmartBanner/
/Ads/Media/Images/
^http://static\.wired\.com/advertising/
^http://*\.dejanews\.com/ads/
^http://adfu\.blockstackers\.com/
^http://ads2\.zdnet\.com/adverts
^http://www2\.burstnet\.com/gifs/
^http://www.\.valueclick\.com/cgi-bin/cycle
^http://www\.altavista\.com/av/gifs/ie_horiz\.gif

       最后一步,希望删除条幅后显示这个文件。基本而言这是一个有4x4透明gif图像的半HTML文件。

代码 13.9: /etc/squid/errors/NOTE_ADS_FILTERED

<HTML>
<HEAD>
<META HTTP-EQUIV="REFRESH" CONTENT="0; URL=http://localhost/images/4x4.gif">
<TITLE>ERROR: The requested URL could not be retrieved</TITLE>
</HEAD>
<BODY>
<H1>Add filtered!</H1>

注释: 不要关闭 <HTML> <BODY> 标签,交给squid吧。

       可以看出,squid有很多可能性,它在过滤和代理上都非常有效。在非常大的网络上它甚至可以使用替代squid代理来扩展。我这里列出的配置主要适于1-20个用户的小网络。

       但是组合使用包过滤(iptables)和应用网关(squid)可能是最佳方案。即使squild处于不可从外部访问的安全场所也是如此。内部攻击者也不可不防啊。

       现在要配置你的客户的浏览器使用该代理服务器。网关可以可以阻止用户不通过代理直接与外部接触。

注释: Mozilla中在Edit->Preferences->Advanced->Proxies设置。

       也可使用iptables把流出的通讯转发给squid代理来透明的完成。在网关上加入转发/预路由规则来做到这点。

代码 13.10: 启用到我们的代理服务器的端口转发

# iptables -t nat -A PREROUTING -p tcp --dport 80 -j DNAT --to proxyhost:3128
# iptables -t nat -A PREROUTING -p tcp --dport 443 -j DNAT --to proxyhost:3128

至此我们学到了些什么? 

       我们学到了:

  1. 防火墙本身也可能是一种风险。配置不当的防火墙有不如无。
  2. 如何设置基本的网关和透明代理
  3. 好的防火墙的关键在于了解你想放行的协议
  4. IP通讯并不总是包含合法数据,即,ICMP包可能包含有效负载。
  5. 如何防止 SYN 攻击
  6. 过滤HTTP通讯,删除令人不快的图片并防止下载病毒。
  7. 组合使用包过滤和应用网关提过了更好的控制。

       现在如果你确有需要,去建立一个满足你的需要的防火墙吧。

14. 入侵检测


 

AIDE (高级入侵检测环境) 

       AIDE 是一种基于主机的入侵检测系统 ( Tripwire的免费替代品)。如果你已经知道 Tripwire,学习AIDE的配置配置文件不在话下。

       配置文家基于文件和目录的正则表达式、宏和规则。我们有如下啊的宏:

简述语法
ifdef如果定义了@@ifdef "name"
ifndef如果未定义@@ifndef "name"
define定义变量 @@define "name" "value"
undef取消变量的定义@@undef "name"
ifhost如果是 "hostname"@@ifhost "hostname"
ifnhost如果非 "hostname"@@ifnhost "hostname"
endif上面除define和undef外的其他宏之后都要使用endif @@endif

       如果有不止一个Gentoo机器想在它们上都用AIDE而机器上运行的服务甚至用户不完全相同, 这些宏就非常有用了。

       下一步我们要检测文件和目录上的几套标志。这些是权限组合、文件属性和加密哈希/校验和

标志简述
p权限
i索引节点[inode]
n连接数目
u用户
g
s大小
b块数
m最近修改时间[mtime]
a最近访问时间[atime]
c索引节点修改时间[ctime]
S检查大小增长
md5md5校验和
sha1sha1校验和
rmd160rmd160校验和
tigertiger校验和
Rp+i+n+u+g+s+m+c+md5
Lp+i+n+u+g
E空组
>增大日志文件 p+u+g+i+n+S

       如果 AIDE 编译时加入了 mhash 支持,还有其他几个功能:

标志简述
havalhaval校验和
gostgost校验和
crc32crc32校验和

       现在可以组合这些标志创建你自己的规则了,如:

代码 14.1: 创建 AIDE 规则集

All=R+a+sha1+rmd160
Norm=s+n+b+md5+sha1+rmd160

       建立自己的配置文件还差最后一步,如何把规则加入某个文件或目录。基本而言只需敲入文件或目录名及规则。除非另外指明,AIDE会递归地加入所有文件。

标志简述
!不加入该文件或目录。
=加入该目录,但不要管其子目录。

       好了,我们来观摩一个完整的例子

代码 14.2: /etc/aide/aide.conf

@@ifndef TOPDIR 
@@define TOPDIR /
@@endif

@@ifndef AIDEDIR 
@@define AIDEDIR /etc/aide
@@endif

@@ifhost smbserv
@@define smbactive
@@endif

# 要读的数据库的位置。
database=file:@@{AIDEDIR}/aide.db

# 要写入的数据库的位置。
database_out=file:aide.db.new

verbose=20
report_url=stdout

# 定义规则
All=R+a+sha1+rmd160
Norm=s+n+b+md5+sha1+rmd160

@@{TOPDIR} Norm
!@@{TOPDIR}etc/aide
!@@{TOPDIR}dev
!@@{TOPDIR}proc
!@@{TOPDIR}root
!@@{TOPDIR}tmp
!@@{TOPDIR}var/log
!@@{TOPDIR}var/run
!@@{TOPDIR}usr/portage
@@ifdef smbactive
!@@{TOPDIR}etc/smb/private/secrets.tdb
@@endif
=@@{TOPDIR}home Norm

       上例中我们用一些宏指明了topdir开始的位置和AIDE目录的位置。AIDE 检查文家完整性时检查 /etc/aide/aide.db文件。但更新或创建新文件时存入 /etc/aide/aide.db.new。这么做是为了避免自动覆盖旧数据库文件。report_URL 选项还没有完成,不过作者的意图是它应可以email甚至执行脚本。

       编辑配置后应执行 aide -i 以创建db文件,并把文件 /etc/aide/aide.db.new 复制到 /etc/aide/aide.db, 并以root执行crontab -e 把该检查加入 cron。

注释: 取决于cpu, 磁盘访问(速度)和设定的文件访问标志,这个过程可能要花一些时间。 take some time.

代码 14.3: 安排 aide 为 cron 工作

0 3   * * * /usr/bin/aide -u

注释: 记得设好可收到root的邮件,否则就无法知道 aide 报告的内容。

       本例中每天早3点运行一次。这么做是不想影响用户的工作。注意我使用 -u (更新)选项而不是 -C (检查)。因为 -u 也检查文件而且不会改写原来地 db文件。这样节省了时间,因为只需复制测出变动了的文件。只需在复制前检查是你还是攻击者作出的改变!

       现在把db文件存在本地还有问题,因为攻击者肯定会(如果他们发现安装了aide)想修改、更新db文件,或者修改 /usr/bin/aide。所以你应该创建一个CD或者别的媒体,放入.db文件和aide 二进制文件的副本。

       可在 AIDE 项目主页找到信息。

Snort 

       Snort 是一种网络入侵检测系统 (NIDS)。使用下例安装、配置snort。

代码 14.4: 向系统中加入用户snort

# useradd snort -d /var/log/snort -s /dev/null
# chown -R snort /var/log/snort

代码 14.5: /etc/conf.d/snort

PIDFILE=/var/run/snort_eth0.pid
MODE="full"
NETWORK="10.0.0.0/24"
LOGDIR="/var/log/snort"
CONF=/etc/snort/snort.conf
SNORT_OPTS="-D -s -u snort -dev -l $LOGDIR -h $NETWORK -c $CONF"

代码 14.6: /etc/snort/snort.conf

// 第一步
var HOME_NET 10.0.0.0/24
var EXTERNAL_NET any
var SMTP $HOME_NET
var HTTP_SERVERS $HOME_NET
var SQL_SERVERS $HOME_NET
var DNS_SERVERS [10.0.0.2/32,212.242.40.51/32]
var RULE_PATH ./

// 第二步
preprocessor frag2
preprocessor stream4: detect_scans detect_state_problems detect_scans disable_evasion_alerts
preprocessor stream4_reassemble: ports all
preprocessor http_decode: 80 8080 unicode iis_alt_unicode double_encode iis_flip_slash full_whitespace
preprocessor rpc_decode: 111 32771
preprocessor bo: -nobrute
preprocessor telnet_decode

// 第三步
include classification.config

// 第四步
include $RULE_PATH/bad-traffic.rules
include $RULE_PATH/exploit.rules
include $RULE_PATH/scan.rules
include $RULE_PATH/finger.rules
include $RULE_PATH/ftp.rules
include $RULE_PATH/telnet.rules
include $RULE_PATH/smtp.rules
include $RULE_PATH/rpc.rules
include $RULE_PATH/rservices.rules
include $RULE_PATH/dos.rules
include $RULE_PATH/ddos.rules
include $RULE_PATH/dns.rules
include $RULE_PATH/tftp.rules
include $RULE_PATH/web-cgi.rules
include $RULE_PATH/web-coldfusion.rules
include $RULE_PATH/web-iis.rules
include $RULE_PATH/web-frontpage.rules
include $RULE_PATH/web-misc.rules
include $RULE_PATH/web-attacks.rules
include $RULE_PATH/sql.rules
include $RULE_PATH/x11.rules
include $RULE_PATH/icmp.rules
include $RULE_PATH/netbios.rules
include $RULE_PATH/misc.rules
include $RULE_PATH/attack-responses.rules
include $RULE_PATH/backdoor.rules
include $RULE_PATH/shellcode.rules
include $RULE_PATH/policy.rules
include $RULE_PATH/porn.rules
include $RULE_PATH/info.rules
include $RULE_PATH/icmp-info.rules
include $RULE_PATH/virus.rules
# include $RULE_PATH/experimental.rules
include $RULE_PATH/local.rules

代码 14.7: /etc/snort/classification.config

config classification: not-suspicious,Not Suspicious Traffic,3
config classification: unknown,Unknown Traffic,3
config classification: bad-unknown,Potentially Bad Traffic, 2
config classification: attempted-recon,Attempted Information Leak,2
config classification: successful-recon-limited,Information Leak,2
config classification: successful-recon-largescale,Large Scale Information Leak,2
config classification: attempted-dos,Attempted Denial of Service,2
config classification: successful-dos,Denial of Service,2
config classification: attempted-user,Attempted User Privilege Gain,1
config classification: unsuccessful-user,Unsuccessful User Privilege Gain,1
config classification: successful-user,Successful User Privilege Gain,1
config classification: attempted-admin,Attempted Administrator Privilege Gain,1
config classification: successful-admin,Successful Administrator Privilege Gain,1

# 新的分类
config classification: rpc-portmap-decode,Decode of an RPC Query,2
config classification: shellcode-detect,Executable code was detected,1
config classification: string-detect,A suspicious string was detected,3
config classification: suspicious-filename-detect,A suspicious filename was detected,2
config classification: suspicious-login,An attempted login using a suspicious username was detected,2
config classification: system-call-detect,A system call was detected,2
config classification: tcp-connection,A TCP connection was detected,4
config classification: trojan-activity,A Network Trojan was detected, 1
config classification: unusual-client-port-connection,A client was using an unusual port,2
config classification: network-scan,Detection of a Network Scan,3
config classification: denial-of-service,Detection of a Denial of Service Attack,2
config classification: non-standard-protocol,Detection of a non-standard protocol or event,2
config classification: protocol-command-decode,Generic Protocol Command Decode,3
config classification: web-application-activity,access to a potentially vulnerable web application,2
config classification: web-application-attack,Web Application Attack,1
config classification: misc-activity,Misc activity,3
config classification: misc-attack,Misc Attack,2
config classification: icmp-event,Generic ICMP event,3
config classification: kickass-porn,SCORE! Get the lotion!,1

       Snort网站有更多的信息。

15. 保持更新


 

       成功安装了系统并实施了较好级别的安全,不是就可以睡大觉了。安全是一个不断前进的过程,必须不断更新系统,与最新的安全补丁同步。

       如果安装了 portage 的近期版本, 可以首先用 emerge sync 同步portage树,然后发出 glsa-check --list 命令检查系统在安全方面是否是最新的。

代码 15.1: glsa-check -l输出示例

# glsa-check -l

警告:glsa-check 还是试验性质的,如果安全是你的首要问题,明智的做法是将该列表与其他途径核对。

       所有有[A] 和 [U] 的行可以安全地忽略掉,因为系统不受这个GLSA的影响。

       有些人还是更喜欢用 emerge 包名 而不是 glsa-check -f 这样所有的 GLSA 都列为 [N].

       如果想在每次有新的GLSA发布是收到邮件同志,预订 gentoo-announce 邮件列表。加入该列表及很多其他不错的邮件列表的方法,可以在 Gentoo Linux 邮件列表总揽 找到.

       另外一个很不错的安全资源是 Bugtraq 邮件列表.