循序渐进安全化

下边是安装完成后, 来循序渐进的增强 Debian 2.2 GNU/Linux 系统的安全性. 对于增强网络服务的安全性, 这是一种可行的方法. 这包括展示您的整个配置过程. 更多信息参见 . 安装系统时, 应当注意分区有关的信息, 包括本文档前边提到的. 完成基本安装后, 进入定制安装阶段. 不要 select task packages. 应当使用 shadow 密码. 使用 dselect, 删除在前边使用 [I]nstall 时安装了但是并不需要的软件包. 使得系统安装的软件包最少. 如前边 阐明的, 从 security.debian.org 更新所有的软件包. 实现本手册前边提出的建议, 特边是用户限额, 登录定义和 lilo 构建一个系统当前运行服务的列表. 尝试:

$ ps -aux $ netstat -pn -l -A inet # /usr/sbin/lsof -i | grep LISTEN
执行第三行命令(以 root 运行), 您需要安装 `lsof-2.2`. 应当注意, lsof 可以将 LISTEN 换做您的本地设定... 为了删除多余的服务, 首先应当确定服务是由什么软件包提供的, 它是如何启动的. 这可以通过检查程序监听的 socket 来确定. 下边使用了 lsof 和 dpkg 程序的脚本可以完成这一任务:
#!/bin/sh # FIXME: this is quick and dirty; replace with a more robust script snippet for i in `sudo lsof -i | grep LISTEN | cut -d " " -f 1 |sort -u` ; do pack=`dpkg -S $i |grep bin |cut -f 1 -d : | uniq` echo "Service $i is installed by $pack"; init=`dpkg -L $pack |grep init.d/ ` if [ ! -z "$init" ]; then echo "and is run by $init" fi done
一旦发现了您不需要的任务, 删除相关软件包(使用 dpkg --purge), 或使用 update-rc.d(参阅 ) 禁止服务在启动时自动运行. 对于 inetd 服务(由超级用户装入的), 检查在 /etc/inetd.conf 中启用了哪些服务:
$ grep -v "^#" /etc/inetd.conf | sort -u
然后通过注释掉 /etc/inetd.conf 中的对应行, 将其禁用, 删除对应软件包, 或使用 update-inetd. 如果您使用了 wrapped 服务(它们使用 /usr/sbin/tcpd), 根据您的服务策略, 检查 /etc/hosts.allow 和 /etc/hosts.deny 文件的配置. 如果服务器使用了多个外部接口, 根据服务, 您可以限制服务只监听特定的接口. 例如, 如果您只允许内网访问 FTP, 那么就配置 FTP 守护进程只监听您管理的接口, 而不是所有接口(即, 0.0.0.0:21). 重启计算机, 或使用下边的命令由单用户模式切换到多用户模式:
$ init 1 (....) $ init 2
检查现在的服务, 并, 如果需要, 重复上边的步骤. 现在, 安装所需服务, 如果, 您还没有做好, 正确的配置它们... 使用下边的 shell 命令, 确定服务是以什么用户运行的:
$ for i in `/usr/sbin/lsof -i |grep LISTEN |cut -d " " -f 1 |sort -u`; \ > do user=`ps -ef |grep $i |grep -v grep |cut -f 1 -d " "` ; \ > echo "Service $i is running as user $user"; done
考虑用指定的用户/组运行这些服务, 为了增强安全性, 也可为它们设置 chroot. 您可以通过修改启动服务的脚本 /etc/init.d 达到这个目的. Debian 中许多服务使用 start-stop-daemon, 它们都有完成这种设置的选项 (`--change-uid` 和 `--chroot`). 有关为服务设置 chroot 的警告信息: 您可能需要将服务对应软件包(使用 dpkg -L)所安装的所有文件, 以及其依赖的软件包, 置于 chroot 环境中. 有关配置 ssh 的 chroot 环境的信息, 参阅 . 重复上边的步骤, 直至只有所希望的服务运行, 并且与希望的用户/组绑定. 测试安装的服务是否与期望相符. 使用漏洞评估扫描器(如 `nessus`)检查系统, 是否存在漏洞(即, 错误的配置, 旧版服务, 或不需要的服务). 安装基于网络或主机的入侵检测工具, 如 `snort` 和 `logsentry`. 重复进行网络扫描和入侵检测校验, 直至确定系统运行正常.

下边是更加偏执的做法: 提高系统防火墙的性能, 只接受对所提供服务的连入访问, 并限制连出访问, 只允许授权的连接通行. 使用网络扫描器, 再次对系统进行漏洞评估. 使用网络扫描器, 检查系统指向外部站点的出站连接, 确保没有多余的连出连接.

FIXME: 这个过程只是考虑增强服务的安全性, 而不是在用户级别上增强系统的安全性, 包括检查用户权限的信息, SETUID 文件和使用 ext2 文件系统的冻结修改.

配置清单

本附录以精简清单的形式简要地重申本手册中其它部分的一些内容. 这只是为那些已经阅读本文档的人做个快速的总结. 它还包括其它一些不错的清单, 如 和 .

FIXME: 这些内容基于手册的 1.4 版, 也许需要更新了.. 限制物理访问和启动 启用 BIOS 密码 禁用 floppy/cdrom/... 启动 设置 LILO 或 GRUB 密码(/etc/lilo.conf 或 /boot/grub/menu.lst, 分别); 检查LILO 或 GRUB 配置文件是否为只读保护. 重写 MBR, 禁止 MBR 软驱启动后门(可能不是?) 分区 用户可写数据, 非系统数据, 和运行时频繁改变的数据与安装分区分离. 在 /etc/fstab 中对 ext2 分区, 如 /tmp 设置 `nosuid, noexec, nodev mount` 选项. 密码学和登陆安全 设置一个好的 root 密码 对密码启用 shadow 和 MD5 安装并使用 PAM 增加PAM 对 MD5 的支持, 并确保(一般而言) /etc/pam.d/ 下的文件中授权对机器的访问条目, 第二个域设为 `requisite` 或 `required` 调整 /etc/pam.d/login 以使只允许本地 root 登陆. 在 /etc/security/access.conf 中标记 authorized tty:s ,通常配置此文件以尽量限制 root 登录. 如果要对每个用户设置限制, 增加 pam_limits.so. 调整 /etc/pam.d/passwd: 增大密码的最小长度设置(可能为 6 字符) 并启用 MD5 如果需要, 在 /etc/group 中增加 wheel 组; 在 /etc/pam.d/su 中增加 pam_wheel.so group=wheel条目 适当的使用 pam_listfile.so 条目, 以习惯每个用户的控制 增加 /etc/pam.d/other 文件, 以设置更高的安全性. 配置 /etc/security/limits.conf(注意 如果您使用 PAM, 则/etc/limits不会被使用) 配置 /etc/login.defs; 还有, 如果您启用了 MD5 和/或 PAM, 确保在对应处也做了修改 在 /etc/ftpusers 中禁止 root 的 ftp 访问 禁止 root 的网络登录; 使用 或 .(考虑安装 `sudo`) 使用 PAM 登录时强制附加另外的限制? 其它本地安全问题 调整内核(参见 ) 内核补丁(参见 ) 限制日志文件的访问(/var/log/{last,fail}log, Apache 日志) 确保在 /etc/checksecurity.conf 中启用了 SETUID 检查 考虑为一些日志文件设置只添加属性, 使用 chattr 设置配置文件为不可修改(只适于 ext2 文件系统) 文件的完整性设置(参见 ). 安装 `debsums` 使用本地打印机记录日志? 将您的配置烧录到可引导 CD 上并 boot off that? 禁用内核模块? 网络访问限制 安装和配置 ssh(建议在 /etc/ssh/sshd_config 中设置 PermitRootLogin No, 注意文章中的其它建议) 考虑禁用或删除 in.telnetd 通常, 使用 update-inetd --disable 禁用 /etc/inetd.conf 中无用的服务(或全部禁用 inetd, 或使用 xinetd 或 rlinetd 替换) 禁用其它无用网网络服务; mail, ftp, DNS, WWW 等, 如果您不需要或不监听就不应让其运行. 对于您需要的那些服务, 不要仅仅使用通用版本, 寻找引入 Debian(或从其它地方)的更加安全的版本.无论使用什么, 都应当了解其风险. 为外部用户和守护进程设置 chroot jail. 配置防火墙和 tcpwrappers(即 ); 注意文章中有关 /etc/hosts.deny 的技巧. 如果运行了ftp, 设置您的ftpd服务器总是运行在chroot 了的用户家目录内 如果运行了 X, 禁用 xhost 认证, 使用 ssh 替代; 最好禁用远程X 如果可以的话(为X命令行增加 -nolisten tcp 选项,通过在 /etc/X11/xdm/xdm-config中设置 requestPort 为 0, 关闭 XDMCP) 禁用打印机的外部访问 任何 IMAP 或 POP 会话都使用 SSL 或 ssh 隧道; 如果为远程邮件用户提供此项服务,安装 stunnel 配置日志主机, 并设置其它机器将日志发送到此主机(/etc/syslog.conf) 增强 BIND, Sendmail, 和其它复杂守护进程的安全性.(运行在 chroot 中; 以非root pseduo 用户运行) 安装 snort 或类似的日志工具. 如果可能不要使用 NIS 和 RPC(禁用 portmap). 策略问题 培训用户了解您的策略. 当您禁止某些在其它系统通常可以使用的事项时, 提供文档, 解释如何使用其它的以达到近似的效果, 或更安全的方法. 禁止使用明文密码的协议(telnet, rsh 和类似的; ftp, imap, http, ...). 禁止使用 SVGAlib 的程序. 启用磁盘配额. 谨记的安全问题 订阅安全邮件列表 配置可以安全更新的 `apt`-- 在 /etc/apt/sources.list 中增加一条(或多条)有关 /http://security.debian.org/debian-security 的源 并且谨记经常运行 apt-get update ; apt-get upgrade(或许可以设为一个 cron job?) 如 所述.

设定独立的 IDS

您可以很容易的使用 `snort` 配置用于 Debian 系统的入侵检测系统.

一些准则: 安装一个基本的Debian 系统, 不要选择多余的软件包. 下载, 并手工(用 dpkg)安装必要的软件包(参见后边的需要安装的软件包列表). 下载并安装 ACID(Analysis Console for Intrusion Databases).

当前用于 Debian 的软件包是 `acidlab`. 它为 snort 输出提供了一个图形化的 WWW 接口. 也可以从 , 或 处下载. 您还可以阅读 .

这个系统至少应当设置两个接口: 一个接口联接管理用的内网(用于查看结果和维护系统), 和不分配IP地址的一个接口, 用于获取分析用的网络数据段.

标准的 Debian /etc/network/interfaces 文件通常用于配置网卡,因而不能使用, 因为 ifup 和 ifdown 程序需要一个 IP 地址. 可以简单的改用 `ifconfig eth0 up`.

除了基本的安装外, `acidlab` 还基于 `php4` 和 `apache` 软件包. 下载下边的软件包(注意: 版本和您使用的 Debian 的版本有关,这是 Debian woody 2001年9月的列表):

ACID-0.9.5b9.tar.gz adduser_3.39_all.deb apache-common_1.3.20-1_i386.deb apache_1.3.20-1_i386.deb debconf_0.9.77_all.deb dialog_0.9a-20010527-1_i386.deb fileutils_4.1-2_i386.deb klogd_1.4.1-2_i386.deb libbz2-1.0_1.0.1-10_i386.deb libc6_2.2.3-6_i386.deb libdb2_2.7.7-8_i386.deb libdbd-mysql-perl_1.2216-2_i386.deb libdbi-perl_1.18-1_i386.deb libexpat1_1.95.1-5_i386.deb libgdbmg1_1.7.3-27_i386.deb libmm11_1.1.3-4_i386.deb libmysqlclient10_3.23.39-3_i386.deb libncurses5_5.2.20010318-2_i386.deb libpcap0_0.6.2-1_i386.deb libpcre3_3.4-1_i386.deb libreadline4_4.2-3_i386.deb libstdc++2.10-glibc2.2_2.95.4-0.010703_i386.deb logrotate_3.5.4-2_i386.deb mime-support_3.11-1_all.deb mysql-client_3.23.39-3_i386.deb mysql-common_3.23.39-3.1_all.deb mysql-server_3.23.39-3_i386.deb perl-base_5.6.1-5_i386.deb perl-modules_5.6.1-5_all.deb perl_5.6.1-5_i386.deb php4-mysql_4.0.6-4_i386.deb php4_4.0.6-1_i386.deb php4_4.0.6-4_i386.deb snort_1.7-9_i386.deb sysklogd_1.4.1-2_i386.deb zlib1g_1.1.3-15_i386.deb

安装的软件包 (dpkg -l):

ii adduser 3.39 ii ae 962-26 ii apache 1.3.20-1 ii apache-common 1.3.20-1 ii apt 0.3.19 ii base-config 0.33.2 ii base-files 2.2.0 ii base-passwd 3.1.10 ii bash 2.03-6 ii bsdutils 2.10f-5.1 ii console-data 1999.08.29-11. ii console-tools 0.2.3-10.3 ii console-tools- 0.2.3-10.3 ii cron 3.0pl1-57.2 ii debconf 0.9.77 ii debianutils 1.13.3 ii dialog 0.9a-20010527- ii diff 2.7-21 ii dpkg 1.6.15 ii e2fsprogs 1.18-3.0 ii elvis-tiny 1.4-11 ii fbset 2.1-6 ii fdflush 1.0.1-5 ii fdutils 5.3-3 ii fileutils 4.1-2 ii findutils 4.1-40 ii ftp 0.10-3.1 ii gettext-base 0.10.35-13 ii grep 2.4.2-1 ii gzip 1.2.4-33 ii hostname 2.07 ii isapnptools 1.21-2 ii joe 2.8-15.2 ii klogd 1.4.1-2 ii ldso 1.9.11-9 ii libbz2-1.0 1.0.1-10 ii libc6 2.2.3-6 ii libdb2 2.7.7-8 ii libdbd-mysql-p 1.2216-2 ii libdbi-perl 1.18-1 ii libexpat1 1.95.1-5 ii libgdbmg1 1.7.3-27 ii libmm11 1.1.3-4 ii libmysqlclient 3.23.39-3 ii libncurses5 5.2.20010318-2 ii libnewt0 0.50-7 ii libpam-modules 0.72-9 ii libpam-runtime 0.72-9 ii libpam0g 0.72-9 ii libpcap0 0.6.2-1 ii libpcre3 3.4-1 ii libpopt0 1.4-1.1 ii libreadline4 4.2-3 ii libssl09 0.9.4-5 ii libstdc++2.10 2.95.2-13 ii libstdc++2.10- 2.95.4-0.01070 ii libwrap0 7.6-4 ii lilo 21.4.3-2 ii locales 2.1.3-18 ii login 19990827-20 ii makedev 2.3.1-46.2 ii mawk 1.3.3-5 ii mbr 1.1.2-1 ii mime-support 3.11-1 ii modutils 2.3.11-13.1 ii mount 2.10f-5.1 ii mysql-client 3.23.39-3 ii mysql-common 3.23.39-3.1 ii mysql-server 3.23.39-3 ii ncurses-base 5.0-6.0potato1 ii ncurses-bin 5.0-6.0potato1 ii netbase 3.18-4 ii passwd 19990827-20 ii pciutils 2.1.2-2 ii perl 5.6.1-5 ii perl-base 5.6.1-5 ii perl-modules 5.6.1-5 ii php4 4.0.6-4 ii php4-mysql 4.0.6-4 ii ppp 2.3.11-1.4 ii pppconfig 2.0.5 ii procps 2.0.6-5 ii psmisc 19-2 ii pump 0.7.3-2 ii sed 3.02-5 ii setserial 2.17-16 ii shellutils 2.0-7 ii slang1 1.3.9-1 ii snort 1.7-9 ii ssh 1.2.3-9.3 ii sysklogd 1.4.1-2 ii syslinux 1.48-2 ii sysvinit 2.78-4 ii tar 1.13.17-2 ii tasksel 1.0-10 ii tcpd 7.6-4 ii telnet 0.16-4potato.1 ii textutils 2.0-2 ii update 2.11-1 ii util-linux 2.10f-5.1 ii zlib1g 1.1.3-15
设定网桥防火墙

这些内容由 Francois Bayart 提供,以帮助用户使用 2.4.x kernel 和 `iptables` 配置Linux 网桥/防火墙. 内核的补丁代码已经成为 Linux 内核的标准, 因此不再需要额外的内核补丁.

配置内核提供必要的支持, 运行 `make menuconfig` 或 `make menuconfig`. 在 Networking options 部分, 启用下边的选项:

[*] Network packet filtering (replaces ipchains) [ ] Network packet filtering debugging (NEW) <*> 802.1d Ethernet Bridging [*] netfilter (firewalling) support (NEW)

小心: 您如果要应用一些防火墙规则, 必须禁用此项, 否则 iptables 不会工作.

[ ] Network packet filtering debugging (NEW)

其次, 添加在 IP: Netfilter Configuration 部分添加正确的选项. 然后. 编译并安装内核. 如果您想以 Debian 的方式 完成这些工作, 安装 `kernel-package` 软件包, 并运行 make-kpkg 以构建一个通常的 Debian 内核软件包, 然后用 dpkg 安装. 一旦完成新内核的编译和安装, 安装 `bridge-utils` 软件包.

完成这些步骤后, 您就可以完成网桥的配置了. 下边的部分给出两种不通的配置网桥的可用方法, 都给出了假定的网络映射和必要的命令. 提供 NAT 和防火墙能力的网桥

这个配置使用桥梁作为带有网络地址转发(NAT)功能的防火墙, 用于保护服务器和内部局域网客户端. 下边给出的是网络布局图::

互联网 ---- 路由器 ( 62.3.3.25 ) ---- 网桥 (62.3.3.26 网关 62.3.3.25 / 192.168.0.1) | | |---- WWW 服务器 (62.3.3.27 网关 62.3.3.25) | | LAN --- Zipowz (192.168.0.2 网关 192.168.0.1)

下边给出配置这个网桥的命令.

# Create the interface br0 /usr/sbin/brctl addbr br0 # Add the Ethernet interface to use with the bridge /usr/sbin/brctl addif br0 eth0 /usr/sbin/brctl addif br0 eth1 # Start up the Ethernet interface /sbin/ifconfig eth0 0.0.0.0 /sbin/ifconfig eth1 0.0.0.0 # Configure the bridge ethernet # The bridge will be correct and invisible ( transparent firewall ). # It's hidden in a traceroute and you keep your real gateway on the # other computers. Now if you want you can config a gateway on your # bridge and choose it as your new gateway for the other computers. /sbin/ifconfig br0 62.3.3.26 netmask 255.255.255.248 broadcast 62.3.3.32 # I have added this internal IP to create my NAT ip addr add 192.168.0.1/24 dev br0 /sbin/route add default gw 62.3.3.25
提供防火墙能力的网桥

这种可能的配置用于系统用于为拥有公网IP地址的内外提供透明的防火墙.

互联网 ---- 路由器 (62.3.3.25) ---- 网桥 (62.3.3.26) | | |---- WWW 服务器 (62.3.3.28 网关 62.3.3.25) | | |---- 邮件服务器 (62.3.3.27 网关 62.3.3.25)

以下命令为配置网桥的过程.

# Create the interface br0 /usr/sbin/brctl addbr br0 # Add the Ethernet interface to use with the bridge /usr/sbin/brctl addif br0 eth0 /usr/sbin/brctl addif br0 eth1 # Start up the Ethernet interface /sbin/ifconfig eth0 0.0.0.0 /sbin/ifconfig eth1 0.0.0.0 # Configure the bridge Ethernet # The bridge will be correct and invisible ( transparent firewall ). # It's hidden in a traceroute and you keep your real gateway on the # other computers. Now if you want you can config a gateway on your # bridge and choose it as your new gateway for the other computers. /sbin/ifconfig br0 62.3.3.26 netmask 255.255.255.248 broadcast 62.3.3.32

如果 traceroute Linux 邮件服务器, 您不会看到网桥. 如果想使用 ssh 访问网桥, 则必须拥有一个网关,或者首先联接到其它服务器, 如"邮件服务器". 然后通过内部网卡联接到网桥.

基本的 IPtables 规则'

这是基本规则的范例, 可用于任何的设定.

iptables -F FORWARD iptables -P FORWARD DROP iptables -A FORWARD -s 0.0.0.0/0.0.0.0 -d 0.0.0.0/0.0.0.0 -m state --state INVALID -j DROP iptables -A FORWARD -m state --state ESTABLISHED,RELATED -j ACCEPT # Some funny rules but not in a classic Iptables sorry ... # Limit ICMP # iptables -A FORWARD -p icmp -m limit --limit 4/s -j ACCEPT # Match string, a good simple method to block some VIRUS very quickly # iptables -I FORWARD -j DROP -p tcp -s 0.0.0.0/0 -m string --string "cmd.exe" # Block all MySQL connection just to be sure iptables -A FORWARD -p tcp -s 0/0 -d 62.3.3.0/24 --dport 3306 -j DROP # Linux Mail Server Rules # Allow FTP-DATA ( 20 ) , FTP ( 21 ) , SSH ( 22 ) iptables -A FORWARD -p tcp -s 0.0.0.0/0 -d 62.3.3.27/32 --dport 20:22 -j ACCEPT # Allow the Mail Server to connect to the outside # Note: This is *not* needed for the previous connections # (remember: stateful filtering) and could be removed. iptables -A FORWARD -p tcp -s 62.3.3.27/32 -d 0/0 -j ACCEPT # WWW Server Rules # Allow HTTP ( 80 ) connections with the WWW server iptables -A FORWARD -p tcp -s 0.0.0.0/0 -d 62.3.3.28/32 --dport 80 -j ACCEPT # Allow HTTPS ( 443 ) connections with the WWW server iptables -A FORWARD -p tcp -s 0.0.0.0/0 -d 62.3.3.28/32 --dport 443 -j ACCEPT # Allow the WWW server to go out # Note: This is *not* needed for the previous connections # (remember: stateful filtering) and could be removed. iptables -A FORWARD -p tcp -s 62.3.3.28/32 -d 0/0 -j ACCEPT
修改Bind默认安装的示例脚本.

这个脚本自动修改 bind 名称服务器的默认安装, 使其不必以超级用户运行. 它将创建用于名称服务器的用户和组. 使用时应非常小心, 因为其未经过全面测试.

#!/bin/sh # Change the default Debian bind configuration to have it run # with a non-root user and group. # # WARN: This script has not been tested thoroughly, please # verify the changes made to the INITD script # (c) 2002 Javier Fernández-Sanguino Peña # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 1, or (at your option) # any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # Please see the file `COPYING' for the complete copyright notice. # restore() { # Just in case, restore the system if the changes fail echo "WARN: Restoring to the previous setup since I'm unable to properly change it." echo "WARN: Please check the $INITDERR script." mv $INITD $INITDERR cp $INITDBAK $INITD } USER=named GROUP=named INITD=/etc/init.d/bind INITDBAK=$INITD.preuserchange INITDERR=$INITD.changeerror START="start-stop-daemon --start --quiet --exec /usr/sbin/named -- -g $GROUP -u $USER" AWKS="awk ' /start-stop-daemon --start/ { print \"$START\"; noprint = 1; }; /\/usr\/sbin\/ndc reload/ { print \"stop; sleep 2; start;\"; noprint = 1; } /\\\\$/ { if ( noprint != 0 ) { noprint = noprint + 1;} } /^.*$/ { if ( noprint != 0 ) { noprint = noprint - 1; } else { print \$0; } } '" [ `id -u` -ne 0 ] && { echo "This program must be run by the root user" exit 1 } RUNUSER=`ps -eo user,fname |grep named |cut -f 1 -d " "` if [ "$RUNUSER" = "$USER" ] then echo "WARN: The name server running daemon is already running as $USER" echo "ERR: This script will not many any changes to your setup." exit 1 fi if [ ! -f $INITD ] then echo "ERR: This system does not have $INITD (which this script tries to change)" RUNNING=`ps -eo fname |grep named` [ -z "$RUNNING" ] && \ echo "ERR: In fact the name server daemon is not even running (is it installed?)" echo "ERR: No changes will be made to your system" exit 1 fi # Check if named group exists if [ -z "`grep $GROUP /etc/group`" ] then echo "Creating group $GROUP:" addgroup $GROUP else echo "WARN: Group $GROUP already exists. Will not create it" fi # Same for the user if [ -z "`grep $USER /etc/passwd`" ] then echo "Creating user $USER:" adduser --system --home /home/$USER \ --no-create-home --ingroup $GROUP \ --disabled-password --disabled-login $USER else echo "WARN: The user $USER already exists. Will not create it" fi # Change the init.d script # First make a backup (check that there is not already # one there first) if [ ! -f $INITDBAK ] then cp $INITD $INITDBAK fi # Then use it to change it cat $INITDBAK | eval $AWKS > $INITD echo "WARN: The script $INITD has been changed, trying to test the changes." echo "Restarting the named daemon (check for errors here)." $INITD restart if [ $? -ne 0 ] then echo "ERR: Failed to restart the daemon." restore exit 1 fi RUNNING=`ps -eo fname |grep named` if [ -z "$RUNNING" ] then echo "ERR: Named is not running, probably due to a problem with the changes." restore exit 1 fi # Check if it's running as expected RUNUSER=`ps -eo user,fname |grep named |cut -f 1 -d " "` if [ "$RUNUSER" = "$USER" ] then echo "All has gone well, named seems to be running now as $USER." else echo "ERR: The script failed to automatically change the system." echo "ERR: Named is currently running as $RUNUSER." restore exit 1 fi exit 0

前面的脚本, 运行在 Woody(Debian 3.0)的 bind 上, 创建 'named'用户和组后,将会处理下边的 initd 文件:

#!/bin/sh PATH=/sbin:/bin:/usr/sbin:/usr/bin test -x /usr/sbin/named || exit 0 start () { echo -n "Starting domain name service: named" start-stop-daemon --start --quiet \ --pidfile /var/run/named.pid --exec /usr/sbin/named echo "." } stop () { echo -n "Stopping domain name service: named" # --exec doesn't catch daemons running deleted instances of named, # as in an upgrade. Fortunately, --pidfile is only going to hit # things from the pidfile. start-stop-daemon --stop --quiet \ --pidfile /var/run/named.pid --name named echo "." } case "$1" in start) start ;; stop) stop ;; restart|force-reload) stop sleep 2 start ;; reload) /usr/sbin/ndc reload ;; *) echo "Usage: /etc/init.d/bind {start|stop|reload|restart|force-reload}" >&2 exit 1 ;; esac exit 0
防火墙保护下的安全更新

标准安装完成后, 系统也许仍然存在一些漏洞. 除非您下载用于其它系统的漏洞修补包(或您有 security.debian.org 的本地镜像)系统必须连入互联网进行下载.

但是, 当您入互联网时, 您的系统就完全暴露了. 如果您的本地服务中有一个存在漏洞, 那么就有可能在您完成更新前被攻陷! 这似乎有点偏执, 但事实上, 源自 的分析表明系统被攻陷的时间不超过三天, 即使系统还不为公共所知(即没有公布 DNS 记录).

当对没有外部系统如防火墙保护的系统进行升级时, 可以正确的设置本地防火墙, 以阻止除更新以外的其它连接. 下边的例子给出如何设置本地防火墙, 仅允许源自 security.debian.org 的更新连接.

FIXME: 在 /etc/hosts 中 security.debian.org 的 IP 地址(因为否则您就需要 DNS 服务).

FIXME: 测试设置是否有效

FIXME: 这只适用于 HTTP URL 因为 ftp 可能需要 ip_conntrack_ftp 模块,或者使用 passive 方式.

# iptables -F # iptables -L Chain INPUT (policy ACCEPT) target prot opt source destination Chain FORWARD (policy ACCEPT) target prot opt source destination Chain OUTPUT (policy ACCEPT) target prot opt source destination # iptables -P INPUT DROP # iptables -P FORWARD DROP # iptables -P OUTPUT DROP # iptables -A OUTPUT -d security.debian.org --dport 80 -j ACCEPT # iptables -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT # iptables -A INPUT -p icmp -j ACCEPT # iptables -A INPUT -j LOG # iptables -A OUTPUT -j LOG # iptables -L Chain INPUT (policy DROP) target prot opt source destination ACCEPT all -- 0.0.0.0/0 0.0.0.0/0 state RELATED,ESTABLISHED ACCEPT icmp -- 0.0.0.0/0 0.0.0.0/0 LOG all -- anywhere anywhere LOG level warning Chain FORWARD (policy DROP) target prot opt source destination Chain OUTPUT (policy DROP) target prot opt source destination ACCEPT 80 -- anywhere security.debian.org LOG all -- anywhere anywhere LOG level warning
SSH 的 chroot 环境

为 SSH 创建一个限制环境是一项坚苦的工作, 这由 SSH 为用户提供一个远程 shell 的事实可知, 其依赖关系和与其它服务不同. 因此, 您还必须考虑在此环境中那些程序用户可以使用. 如果您创建了这种文件结构, 如 /var/chroot/ssh, 您可以被 chroot 的 ssh 服务, 用下边的命令:

# chroot /var/chroot/ssh /sbin/sshd -f /etc/sshd_config
环境的自动构建(简单的方式)

您可以使用 `makejail` 软件包很容易的创建一个限制环境, 因为它自动跟踪处理服务器守护进程(使用 strace), 并使它运行在一个受限制的环境中.

自动构建 chroot 环境程序的优势在于它能为 chroot 环境复制任何软件包(甚至下边的依赖包, 并能保证其完整性). 因此, 用户使用起来更加容易.

使用 makejail 提供的例子配置环境, 运行下边的命令:

# makejail /usr/share/doc/makejail/examples/sshd.py

阅读示例文件, 查看还对环境做了哪些修改. 其中一些修改, 譬如用户主目录的复制, 不能自动完成. 还有, 限制显示的敏感信息只能由一些指定用户从 /etc/shadow 或 /etc/group 复制.

以下示例环境已经过(简单)测试, 使用软件包提供的配置文件构建, 包括 `fileutils` 软件包:

. |-- bin | |-- ash | |-- bash | |-- chgrp | |-- chmod | |-- chown | |-- cp | |-- csh -> /etc/alternatives/csh | |-- dd | |-- df | |-- dir | |-- fdflush | |-- ksh | |-- ln | |-- ls | |-- mkdir | |-- mknod | |-- mv | |-- rbash -> bash | |-- rm | |-- rmdir | |-- sh -> bash | |-- sync | |-- tcsh | |-- touch | |-- vdir | |-- zsh -> /etc/alternatives/zsh | `-- zsh4 |-- dev | |-- null | |-- ptmx | |-- pts | |-- ptya0 (...) | |-- tty | |-- tty0 (...) | `-- urandom |-- etc | |-- alternatives | | |-- csh -> /bin/tcsh | | `-- zsh -> /bin/zsh4 | |-- environment | |-- hosts | |-- hosts.allow | |-- hosts.deny | |-- ld.so.conf | |-- localtime -> /usr/share/zoneinfo/Europe/Madrid | |-- motd | |-- nsswitch.conf | |-- pam.conf | |-- pam.d | | |-- other | | `-- ssh | |-- passwd | |-- resolv.conf | |-- security | | |-- access.conf | | |-- chroot.conf | | |-- group.conf | | |-- limits.conf | | |-- pam_env.conf | | `-- time.conf | |-- shadow | |-- shells | `-- ssh | |-- moduli | |-- ssh_host_dsa_key | |-- ssh_host_dsa_key.pub | |-- ssh_host_rsa_key | |-- ssh_host_rsa_key.pub | `-- sshd_config |-- home | `-- userX |-- lib | |-- ld-2.2.5.so | |-- ld-linux.so.2 -> ld-2.2.5.so | |-- libc-2.2.5.so | |-- libc.so.6 -> libc-2.2.5.so | |-- libcap.so.1 -> libcap.so.1.10 | |-- libcap.so.1.10 | |-- libcrypt-2.2.5.so | |-- libcrypt.so.1 -> libcrypt-2.2.5.so | |-- libdl-2.2.5.so | |-- libdl.so.2 -> libdl-2.2.5.so | |-- libm-2.2.5.so | |-- libm.so.6 -> libm-2.2.5.so | |-- libncurses.so.5 -> libncurses.so.5.2 | |-- libncurses.so.5.2 | |-- libnsl-2.2.5.so | |-- libnsl.so.1 -> libnsl-2.2.5.so | |-- libnss_compat-2.2.5.so | |-- libnss_compat.so.2 -> libnss_compat-2.2.5.so | |-- libnss_db-2.2.so | |-- libnss_db.so.2 -> libnss_db-2.2.so | |-- libnss_dns-2.2.5.so | |-- libnss_dns.so.2 -> libnss_dns-2.2.5.so | |-- libnss_files-2.2.5.so | |-- libnss_files.so.2 -> libnss_files-2.2.5.so | |-- libnss_hesiod-2.2.5.so | |-- libnss_hesiod.so.2 -> libnss_hesiod-2.2.5.so | |-- libnss_nis-2.2.5.so | |-- libnss_nis.so.2 -> libnss_nis-2.2.5.so | |-- libnss_nisplus-2.2.5.so | |-- libnss_nisplus.so.2 -> libnss_nisplus-2.2.5.so | |-- libpam.so.0 -> libpam.so.0.72 | |-- libpam.so.0.72 | |-- libpthread-0.9.so | |-- libpthread.so.0 -> libpthread-0.9.so | |-- libresolv-2.2.5.so | |-- libresolv.so.2 -> libresolv-2.2.5.so | |-- librt-2.2.5.so | |-- librt.so.1 -> librt-2.2.5.so | |-- libutil-2.2.5.so | |-- libutil.so.1 -> libutil-2.2.5.so | |-- libwrap.so.0 -> libwrap.so.0.7.6 | |-- libwrap.so.0.7.6 | `-- security | |-- pam_access.so | |-- pam_chroot.so | |-- pam_deny.so | |-- pam_env.so | |-- pam_filter.so | |-- pam_ftp.so | |-- pam_group.so | |-- pam_issue.so | |-- pam_lastlog.so | |-- pam_limits.so | |-- pam_listfile.so | |-- pam_mail.so | |-- pam_mkhomedir.so | |-- pam_motd.so | |-- pam_nologin.so | |-- pam_permit.so | |-- pam_rhosts_auth.so | |-- pam_rootok.so | |-- pam_securetty.so | |-- pam_shells.so | |-- pam_stress.so | |-- pam_tally.so | |-- pam_time.so | |-- pam_unix.so | |-- pam_unix_acct.so -> pam_unix.so | |-- pam_unix_auth.so -> pam_unix.so | |-- pam_unix_passwd.so -> pam_unix.so | |-- pam_unix_session.so -> pam_unix.so | |-- pam_userdb.so | |-- pam_warn.so | `-- pam_wheel.so |-- sbin | `-- start-stop-daemon |-- usr | |-- bin | | |-- dircolors | | |-- du | | |-- install | | |-- link | | |-- mkfifo | | |-- shred | | |-- touch -> /bin/touch | | `-- unlink | |-- lib | | |-- libcrypto.so.0.9.6 | | |-- libdb3.so.3 -> libdb3.so.3.0.2 | | |-- libdb3.so.3.0.2 | | |-- libz.so.1 -> libz.so.1.1.4 | | `-- libz.so.1.1.4 | |-- sbin | | `-- sshd | `-- share | |-- locale | | `-- es | | |-- LC_MESSAGES | | | |-- fileutils.mo | | | |-- libc.mo | | | `-- sh-utils.mo | | `-- LC_TIME -> LC_MESSAGES | `-- zoneinfo | `-- Europe | `-- Madrid `-- var `-- run |-- sshd `-- sshd.pid 27 directories, 733 files
修补 SSH 启用 chroot 功能

Debian 的 sshd 不允许通过服务器限制用户的活动, 因为 sshd2 中(使用 'ChrootGroups' 或 'ChrootUsers', 参阅 )的商用程序缺乏 chroot 功能. 但是, 可以利用一个补丁来 增加此项功能. 这个补丁可能在 OpenSSH 的未来发行版中提供. 在 处 Emmanuel Lacour 提供了含有这种功能的 ssh deb 软件包. 虽然需要完成编译步骤.

在 处可以找到所有步骤的描述(虽然它是针对RedHat7.2 用户的, 几乎所有的内容都适用于 Debian). 打了补丁以后, 编辑 /etc/passwd 修改用户主目录为(注意 `/./`):

joeuser:x:1099:1099:Joe Random User:/home/joe/./:/bin/bash

这将限制通过 ssh 隧道的远程 shell 访问, 和通过 ssh 隧道进行的远程拷贝.

确保用户的 chroot 目录下包含了所有需要的程序和库文件. 这些文件的宿主应当是 root 以避免被用户篡改(在用户退出 chroot jail 时). 下边是一个范例:

./bin: total 660 drwxr-xr-x 2 root root 4096 Mar 18 13:36 . drwxr-xr-x 8 guest guest 4096 Mar 15 16:53 .. -r-xr-xr-x 1 root root 531160 Feb 6 22:36 bash -r-xr-xr-x 1 root root 43916 Nov 29 13:19 ls -r-xr-xr-x 1 root root 16684 Nov 29 13:19 mkdir -rwxr-xr-x 1 root root 23960 Mar 18 13:36 more -r-xr-xr-x 1 root root 9916 Jul 26 2001 pwd -r-xr-xr-x 1 root root 24780 Nov 29 13:19 rm lrwxrwxrwx 1 root root 4 Mar 30 16:29 sh -> bash ./etc: total 24 drwxr-xr-x 2 root root 4096 Mar 15 16:13 . drwxr-xr-x 8 guest guest 4096 Mar 15 16:53 .. -rw-r--r-- 1 root root 54 Mar 15 13:23 group -rw-r--r-- 1 root root 428 Mar 15 15:56 hosts -rw-r--r-- 1 root root 44 Mar 15 15:53 passwd -rw-r--r-- 1 root root 52 Mar 15 13:23 shells ./lib: total 1848 drwxr-xr-x 2 root root 4096 Mar 18 13:37 . drwxr-xr-x 8 guest guest 4096 Mar 15 16:53 .. -rwxr-xr-x 1 root root 92511 Mar 15 12:49 ld-linux.so.2 -rwxr-xr-x 1 root root 1170812 Mar 15 12:49 libc.so.6 -rw-r--r-- 1 root root 20900 Mar 15 13:01 libcrypt.so.1 -rw-r--r-- 1 root root 9436 Mar 15 12:49 libdl.so.2 -rw-r--r-- 1 root root 248132 Mar 15 12:48 libncurses.so.5 -rw-r--r-- 1 root root 71332 Mar 15 13:00 libnsl.so.1 -rw-r--r-- 1 root root 34144 Mar 15 16:10 libnss_files.so.2 -rw-r--r-- 1 root root 29420 Mar 15 12:57 libpam.so.0 -rw-r--r-- 1 root root 105498 Mar 15 12:51 libpthread.so.0 -rw-r--r-- 1 root root 25596 Mar 15 12:51 librt.so.1 -rw-r--r-- 1 root root 7760 Mar 15 12:59 libutil.so.1 -rw-r--r-- 1 root root 24328 Mar 15 12:57 libwrap.so.0 ./usr: total 16 drwxr-xr-x 4 root root 4096 Mar 15 13:00 . drwxr-xr-x 8 guest guest 4096 Mar 15 16:53 .. drwxr-xr-x 2 root root 4096 Mar 15 15:55 bin drwxr-xr-x 2 root root 4096 Mar 15 15:37 lib ./usr/bin: total 340 drwxr-xr-x 2 root root 4096 Mar 15 15:55 . drwxr-xr-x 4 root root 4096 Mar 15 13:00 .. -rwxr-xr-x 1 root root 10332 Mar 15 15:55 env -rwxr-xr-x 1 root root 13052 Mar 15 13:13 id -r-xr-xr-x 1 root root 25432 Mar 15 12:40 scp -rwxr-xr-x 1 root root 43768 Mar 15 15:15 sftp -r-sr-xr-x 1 root root 218456 Mar 15 12:40 ssh -rwxr-xr-x 1 root root 9692 Mar 15 13:17 tty ./usr/lib: total 852 drwxr-xr-x 2 root root 4096 Mar 15 15:37 . drwxr-xr-x 4 root root 4096 Mar 15 13:00 .. -rw-r--r-- 1 root root 771088 Mar 15 13:01 libcrypto.so.0.9.6 -rw-r--r-- 1 root root 54548 Mar 15 13:00 libz.so.1 -rwxr-xr-x 1 root root 23096 Mar 15 15:37 sftp-server
手工构建环境(复杂的方式)

使用尝试-错误的方式, 通过监视 sshd 服务器和日志文件以确定必要的文件, 构建一个环境是可能的. 下边的环境, 由 José Luis Ledesma 提供, 是一个 ssh 的 chroot 环境下的文件列表:

Notice that there are no SETUID files. This makes it more difficult for remote users to escape the chroot environment. However, it also prevents users from changing their passwords, since the passwd program cannot modify the files /etc/passwd or /etc/shadow.
.: total 36 drwxr-xr-x 9 root root 4096 Jun 5 10:05 ./ drwxr-xr-x 11 root root 4096 Jun 3 13:43 ../ drwxr-xr-x 2 root root 4096 Jun 4 12:13 bin/ drwxr-xr-x 2 root root 4096 Jun 4 12:16 dev/ drwxr-xr-x 4 root root 4096 Jun 4 12:35 etc/ drwxr-xr-x 3 root root 4096 Jun 4 12:13 lib/ drwxr-xr-x 2 root root 4096 Jun 4 12:35 sbin/ drwxr-xr-x 2 root root 4096 Jun 4 12:32 tmp/ drwxr-xr-x 2 root root 4096 Jun 4 12:16 usr/ ./bin: total 8368 drwxr-xr-x 2 root root 4096 Jun 4 12:13 ./ drwxr-xr-x 9 root root 4096 Jun 5 10:05 ../ -rwxr-xr-x 1 root root 109855 Jun 3 13:45 a2p* -rwxr-xr-x 1 root root 387764 Jun 3 13:45 bash* -rwxr-xr-x 1 root root 36365 Jun 3 13:45 c2ph* -rwxr-xr-x 1 root root 20629 Jun 3 13:45 dprofpp* -rwxr-xr-x 1 root root 6956 Jun 3 13:46 env* -rwxr-xr-x 1 root root 158116 Jun 3 13:45 fax2ps* -rwxr-xr-x 1 root root 104008 Jun 3 13:45 faxalter* -rwxr-xr-x 1 root root 89340 Jun 3 13:45 faxcover* -rwxr-xr-x 1 root root 441584 Jun 3 13:45 faxmail* -rwxr-xr-x 1 root root 96036 Jun 3 13:45 faxrm* -rwxr-xr-x 1 root root 107000 Jun 3 13:45 faxstat* -rwxr-xr-x 1 root root 77832 Jun 4 11:46 grep* -rwxr-xr-x 1 root root 19597 Jun 3 13:45 h2ph* -rwxr-xr-x 1 root root 46979 Jun 3 13:45 h2xs* -rwxr-xr-x 1 root root 10420 Jun 3 13:46 id* -rwxr-xr-x 1 root root 4528 Jun 3 13:46 ldd* -rwxr-xr-x 1 root root 111386 Jun 4 11:46 less* -r-xr-xr-x 1 root root 26168 Jun 3 13:45 login* -rwxr-xr-x 1 root root 49164 Jun 3 13:45 ls* -rwxr-xr-x 1 root root 11600 Jun 3 13:45 mkdir* -rwxr-xr-x 1 root root 24780 Jun 3 13:45 more* -rwxr-xr-x 1 root root 154980 Jun 3 13:45 pal2rgb* -rwxr-xr-x 1 root root 27920 Jun 3 13:46 passwd* -rwxr-xr-x 1 root root 4241 Jun 3 13:45 pl2pm* -rwxr-xr-x 1 root root 2350 Jun 3 13:45 pod2html* -rwxr-xr-x 1 root root 7875 Jun 3 13:45 pod2latex* -rwxr-xr-x 1 root root 17587 Jun 3 13:45 pod2man* -rwxr-xr-x 1 root root 6877 Jun 3 13:45 pod2text* -rwxr-xr-x 1 root root 3300 Jun 3 13:45 pod2usage* -rwxr-xr-x 1 root root 3341 Jun 3 13:45 podchecker* -rwxr-xr-x 1 root root 2483 Jun 3 13:45 podselect* -r-xr-xr-x 1 root root 82412 Jun 4 11:46 ps* -rwxr-xr-x 1 root root 36365 Jun 3 13:45 pstruct* -rwxr-xr-x 1 root root 7120 Jun 3 13:45 pwd* -rwxr-xr-x 1 root root 179884 Jun 3 13:45 rgb2ycbcr* -rwxr-xr-x 1 root root 20532 Jun 3 13:45 rm* -rwxr-xr-x 1 root root 6720 Jun 4 10:15 rmdir* -rwxr-xr-x 1 root root 14705 Jun 3 13:45 s2p* -rwxr-xr-x 1 root root 28764 Jun 3 13:46 scp* -rwxr-xr-x 1 root root 385000 Jun 3 13:45 sendfax* -rwxr-xr-x 1 root root 67548 Jun 3 13:45 sendpage* -rwxr-xr-x 1 root root 88632 Jun 3 13:46 sftp* -rwxr-xr-x 1 root root 387764 Jun 3 13:45 sh* -rws--x--x 1 root root 744500 Jun 3 13:46 slogin* -rwxr-xr-x 1 root root 14523 Jun 3 13:46 splain* -rws--x--x 1 root root 744500 Jun 3 13:46 ssh* -rwxr-xr-x 1 root root 570960 Jun 3 13:46 ssh-add* -rwxr-xr-x 1 root root 502952 Jun 3 13:46 ssh-agent* -rwxr-xr-x 1 root root 575740 Jun 3 13:46 ssh-keygen* -rwxr-xr-x 1 root root 383480 Jun 3 13:46 ssh-keyscan* -rwxr-xr-x 1 root root 39 Jun 3 13:46 ssh_europa* -rwxr-xr-x 1 root root 107252 Jun 4 10:14 strace* -rwxr-xr-x 1 root root 8323 Jun 4 10:14 strace-graph* -rwxr-xr-x 1 root root 158088 Jun 3 13:46 thumbnail* -rwxr-xr-x 1 root root 6312 Jun 3 13:46 tty* -rwxr-xr-x 1 root root 55904 Jun 4 11:46 useradd* -rwxr-xr-x 1 root root 585656 Jun 4 11:47 vi* -rwxr-xr-x 1 root root 6444 Jun 4 11:45 whoami* ./dev: total 8 drwxr-xr-x 2 root root 4096 Jun 4 12:16 ./ drwxr-xr-x 9 root root 4096 Jun 5 10:05 ../ crw-r--r-- 1 root root 1, 9 Jun 3 13:43 urandom ./etc: total 208 drwxr-xr-x 4 root root 4096 Jun 4 12:35 ./ drwxr-xr-x 9 root root 4096 Jun 5 10:05 ../ -rw------- 1 root root 0 Jun 4 11:46 .pwd.lock -rw-r--r-- 1 root root 653 Jun 3 13:46 group -rw-r--r-- 1 root root 242 Jun 4 11:33 host.conf -rw-r--r-- 1 root root 857 Jun 4 12:04 hosts -rw-r--r-- 1 root root 1050 Jun 4 11:29 ld.so.cache -rw-r--r-- 1 root root 304 Jun 4 11:28 ld.so.conf -rw-r--r-- 1 root root 235 Jun 4 11:27 ld.so.conf~ -rw-r--r-- 1 root root 88039 Jun 3 13:46 moduli -rw-r--r-- 1 root root 1342 Jun 4 11:34 nsswitch.conf drwxr-xr-x 2 root root 4096 Jun 4 12:02 pam.d/ -rw-r--r-- 1 root root 28 Jun 4 12:00 pam_smb.conf -rw-r--r-- 1 root root 2520 Jun 4 11:57 passwd -rw-r--r-- 1 root root 7228 Jun 3 13:48 profile -rw-r--r-- 1 root root 1339 Jun 4 11:33 protocols -rw-r--r-- 1 root root 274 Jun 4 11:44 resolv.conf drwxr-xr-x 2 root root 4096 Jun 3 13:43 security/ -rw-r----- 1 root root 1178 Jun 4 11:51 shadow -rw------- 1 root root 80 Jun 4 11:45 shadow- -rw-r----- 1 root root 1178 Jun 4 11:48 shadow.old -rw-r--r-- 1 root root 161 Jun 3 13:46 shells -rw-r--r-- 1 root root 1144 Jun 3 13:46 ssh_config -rw------- 1 root root 668 Jun 3 13:46 ssh_host_dsa_key -rw-r--r-- 1 root root 602 Jun 3 13:46 ssh_host_dsa_key.pub -rw------- 1 root root 527 Jun 3 13:46 ssh_host_key -rw-r--r-- 1 root root 331 Jun 3 13:46 ssh_host_key.pub -rw------- 1 root root 883 Jun 3 13:46 ssh_host_rsa_key -rw-r--r-- 1 root root 222 Jun 3 13:46 ssh_host_rsa_key.pub -rw-r--r-- 1 root root 2471 Jun 4 12:15 sshd_config ./etc/pam.d: total 24 drwxr-xr-x 2 root root 4096 Jun 4 12:02 ./ drwxr-xr-x 4 root root 4096 Jun 4 12:35 ../ lrwxrwxrwx 1 root root 4 Jun 4 12:02 other -> sshd -rw-r--r-- 1 root root 318 Jun 3 13:46 passwd -rw-r--r-- 1 root root 546 Jun 4 11:36 ssh -rw-r--r-- 1 root root 479 Jun 4 12:02 sshd -rw-r--r-- 1 root root 370 Jun 3 13:46 su ./etc/security: total 32 drwxr-xr-x 2 root root 4096 Jun 3 13:43 ./ drwxr-xr-x 4 root root 4096 Jun 4 12:35 ../ -rw-r--r-- 1 root root 1971 Jun 3 13:46 access.conf -rw-r--r-- 1 root root 184 Jun 3 13:46 chroot.conf -rw-r--r-- 1 root root 2145 Jun 3 13:46 group.conf -rw-r--r-- 1 root root 1356 Jun 3 13:46 limits.conf -rw-r--r-- 1 root root 2858 Jun 3 13:46 pam_env.conf -rw-r--r-- 1 root root 2154 Jun 3 13:46 time.conf ./lib: total 8316 drwxr-xr-x 3 root root 4096 Jun 4 12:13 ./ drwxr-xr-x 9 root root 4096 Jun 5 10:05 ../ -rw-r--r-- 1 root root 1024 Jun 4 11:51 cracklib_dict.hwm -rw-r--r-- 1 root root 214324 Jun 4 11:51 cracklib_dict.pwd -rw-r--r-- 1 root root 11360 Jun 4 11:51 cracklib_dict.pwi -rwxr-xr-x 1 root root 342427 Jun 3 13:46 ld-linux.so.2* -rwxr-xr-x 1 root root 4061504 Jun 3 13:46 libc.so.6* lrwxrwxrwx 1 root root 15 Jun 4 12:11 libcrack.so -> libcrack.so.2.7* lrwxrwxrwx 1 root root 15 Jun 4 12:11 libcrack.so.2 -> libcrack.so.2.7* -rwxr-xr-x 1 root root 33291 Jun 4 11:39 libcrack.so.2.7* -rwxr-xr-x 1 root root 60988 Jun 3 13:46 libcrypt.so.1* -rwxr-xr-x 1 root root 71846 Jun 3 13:46 libdl.so.2* -rwxr-xr-x 1 root root 27762 Jun 3 13:46 libhistory.so.4.0* lrwxrwxrwx 1 root root 17 Jun 4 12:12 libncurses.so.4 -> libncurses.so.4.2* -rwxr-xr-x 1 root root 503903 Jun 3 13:46 libncurses.so.4.2* lrwxrwxrwx 1 root root 17 Jun 4 12:12 libncurses.so.5 -> libncurses.so.5.0* -rwxr-xr-x 1 root root 549429 Jun 3 13:46 libncurses.so.5.0* -rwxr-xr-x 1 root root 369801 Jun 3 13:46 libnsl.so.1* -rwxr-xr-x 1 root root 142563 Jun 4 11:49 libnss_compat.so.1* -rwxr-xr-x 1 root root 215569 Jun 4 11:49 libnss_compat.so.2* -rwxr-xr-x 1 root root 61648 Jun 4 11:34 libnss_dns.so.1* -rwxr-xr-x 1 root root 63453 Jun 4 11:34 libnss_dns.so.2* -rwxr-xr-x 1 root root 63782 Jun 4 11:34 libnss_dns6.so.2* -rwxr-xr-x 1 root root 205715 Jun 3 13:46 libnss_files.so.1* -rwxr-xr-x 1 root root 235932 Jun 3 13:49 libnss_files.so.2* -rwxr-xr-x 1 root root 204383 Jun 4 11:33 libnss_nis.so.1* -rwxr-xr-x 1 root root 254023 Jun 4 11:33 libnss_nis.so.2* -rwxr-xr-x 1 root root 256465 Jun 4 11:33 libnss_nisplus.so.2* lrwxrwxrwx 1 root root 14 Jun 4 12:12 libpam.so.0 -> libpam.so.0.72* -rwxr-xr-x 1 root root 31449 Jun 3 13:46 libpam.so.0.72* lrwxrwxrwx 1 root root 19 Jun 4 12:12 libpam_misc.so.0 -> libpam_misc.so.0.72* -rwxr-xr-x 1 root root 8125 Jun 3 13:46 libpam_misc.so.0.72* lrwxrwxrwx 1 root root 15 Jun 4 12:12 libpamc.so.0 -> libpamc.so.0.72* -rwxr-xr-x 1 root root 10499 Jun 3 13:46 libpamc.so.0.72* -rwxr-xr-x 1 root root 176427 Jun 3 13:46 libreadline.so.4.0* -rwxr-xr-x 1 root root 44729 Jun 3 13:46 libutil.so.1* -rwxr-xr-x 1 root root 70254 Jun 3 13:46 libz.a* lrwxrwxrwx 1 root root 13 Jun 4 12:13 libz.so -> libz.so.1.1.3* lrwxrwxrwx 1 root root 13 Jun 4 12:13 libz.so.1 -> libz.so.1.1.3* -rwxr-xr-x 1 root root 63312 Jun 3 13:46 libz.so.1.1.3* drwxr-xr-x 2 root root 4096 Jun 4 12:00 security/ ./lib/security: total 668 drwxr-xr-x 2 root root 4096 Jun 4 12:00 ./ drwxr-xr-x 3 root root 4096 Jun 4 12:13 ../ -rwxr-xr-x 1 root root 10067 Jun 3 13:46 pam_access.so* -rwxr-xr-x 1 root root 8300 Jun 3 13:46 pam_chroot.so* -rwxr-xr-x 1 root root 14397 Jun 3 13:46 pam_cracklib.so* -rwxr-xr-x 1 root root 5082 Jun 3 13:46 pam_deny.so* -rwxr-xr-x 1 root root 13153 Jun 3 13:46 pam_env.so* -rwxr-xr-x 1 root root 13371 Jun 3 13:46 pam_filter.so* -rwxr-xr-x 1 root root 7957 Jun 3 13:46 pam_ftp.so* -rwxr-xr-x 1 root root 12771 Jun 3 13:46 pam_group.so* -rwxr-xr-x 1 root root 10174 Jun 3 13:46 pam_issue.so* -rwxr-xr-x 1 root root 9774 Jun 3 13:46 pam_lastlog.so* -rwxr-xr-x 1 root root 13591 Jun 3 13:46 pam_limits.so* -rwxr-xr-x 1 root root 11268 Jun 3 13:46 pam_listfile.so* -rwxr-xr-x 1 root root 11182 Jun 3 13:46 pam_mail.so* -rwxr-xr-x 1 root root 5923 Jun 3 13:46 pam_nologin.so* -rwxr-xr-x 1 root root 5460 Jun 3 13:46 pam_permit.so* -rwxr-xr-x 1 root root 18226 Jun 3 13:46 pam_pwcheck.so* -rwxr-xr-x 1 root root 12590 Jun 3 13:46 pam_rhosts_auth.so* -rwxr-xr-x 1 root root 5551 Jun 3 13:46 pam_rootok.so* -rwxr-xr-x 1 root root 7239 Jun 3 13:46 pam_securetty.so* -rwxr-xr-x 1 root root 6551 Jun 3 13:46 pam_shells.so* -rwxr-xr-x 1 root root 55925 Jun 4 12:00 pam_smb_auth.so* -rwxr-xr-x 1 root root 12678 Jun 3 13:46 pam_stress.so* -rwxr-xr-x 1 root root 11170 Jun 3 13:46 pam_tally.so* -rwxr-xr-x 1 root root 11124 Jun 3 13:46 pam_time.so* -rwxr-xr-x 1 root root 45703 Jun 3 13:46 pam_unix.so* -rwxr-xr-x 1 root root 45703 Jun 3 13:46 pam_unix2.so* -rwxr-xr-x 1 root root 45386 Jun 3 13:46 pam_unix_acct.so* -rwxr-xr-x 1 root root 45386 Jun 3 13:46 pam_unix_auth.so* -rwxr-xr-x 1 root root 45386 Jun 3 13:46 pam_unix_passwd.so* -rwxr-xr-x 1 root root 45386 Jun 3 13:46 pam_unix_session.so* -rwxr-xr-x 1 root root 9726 Jun 3 13:46 pam_userdb.so* -rwxr-xr-x 1 root root 6424 Jun 3 13:46 pam_warn.so* -rwxr-xr-x 1 root root 7460 Jun 3 13:46 pam_wheel.so* ./sbin: total 3132 drwxr-xr-x 2 root root 4096 Jun 4 12:35 ./ drwxr-xr-x 9 root root 4096 Jun 5 10:05 ../ -rwxr-xr-x 1 root root 178256 Jun 3 13:46 choptest* -rwxr-xr-x 1 root root 184032 Jun 3 13:46 cqtest* -rwxr-xr-x 1 root root 81096 Jun 3 13:46 dialtest* -rwxr-xr-x 1 root root 1142128 Jun 4 11:28 ldconfig* -rwxr-xr-x 1 root root 2868 Jun 3 13:46 lockname* -rwxr-xr-x 1 root root 3340 Jun 3 13:46 ondelay* -rwxr-xr-x 1 root root 376796 Jun 3 13:46 pagesend* -rwxr-xr-x 1 root root 13950 Jun 3 13:46 probemodem* -rwxr-xr-x 1 root root 9234 Jun 3 13:46 recvstats* -rwxr-xr-x 1 root root 64480 Jun 3 13:46 sftp-server* -rwxr-xr-x 1 root root 744412 Jun 3 13:46 sshd* -rwxr-xr-x 1 root root 30750 Jun 4 11:46 su* -rwxr-xr-x 1 root root 194632 Jun 3 13:46 tagtest* -rwxr-xr-x 1 root root 69892 Jun 3 13:46 tsitest* -rwxr-xr-x 1 root root 43792 Jun 3 13:46 typetest* ./tmp: total 8 drwxr-xr-x 2 root root 4096 Jun 4 12:32 ./ drwxr-xr-x 9 root root 4096 Jun 5 10:05 ../ ./usr: total 8 drwxr-xr-x 2 root root 4096 Jun 4 12:16 ./ drwxr-xr-x 9 root root 4096 Jun 5 10:05 ../ lrwxrwxrwx 1 root root 7 Jun 4 12:14 bin -> ../bin// lrwxrwxrwx 1 root root 7 Jun 4 11:33 lib -> ../lib// lrwxrwxrwx 1 root root 8 Jun 4 12:13 sbin -> ../sbin//
Apache 的 chroot 环境 介绍

chroot 工具常用来限制一个守护进程在一个限制的目录树中. 您可以使用它使各个服务之间相互隔离. 这样软件的安全问题就不会影响到整个服务器. 当使用 makejail 脚本时, 设置, 和更新 chroot 目录树是非常简单的.

FIXME: Apache 还可以使用 进行chroot, 其可以在 `libapache-mod-security` (for Apache 1.x) 和 `libapache2-mod-security` (for Apache 2.x) 中找到.

许可证

此文档2002版权为 Alexandre Ratti 所有. 其遵从双重许可证, 在 GPL version 2 (GNU Public License) the GNU-FDL 1.2 (GNU 自由文档许可证)和包含在此手册中其明确的许可下发布 (源自).

安装服务器

此过程在提供 makejail 0.0.4-1(在 Debian/testing 中)的 Debian GNU/Linux 3.0 (Woody)上经过测试.

以 root 登录, 创建 jail 目录:

$ mkdir -p /var/chroot/apache

创造一个用户和新组. 除了 chroot 了的 Apache 服务器用这个用户/组运行, 在此系统上不再做别的用途. 在这个例子中, 用户和组都叫 chrapach.

$ adduser --home /var/chroot/apache --shell /bin/false \ --no-create-home --system --group chrapach

FIXME: 需要新的用户吗? (Apache 已经作为 apache 用户运行了)

象通常一样在 Debian 上安装 Apache: `apt-get install apache` 配置 Apache(例如定义您的子域, 等). 在 /etc/apache/httpd.conf 配置文件中, 将 Group 和 User 选项设为 `chrapach`, 重新启动 Apache, 确保服务运行正常. 然后, 停掉 Apache 守护进程. 安装 makejail(现在 Debian/testing 中提供). 您还需要安装 makejail 会用到的 wget 和 lynx, 以测试 chroot 服务器: `apt-get install makejail wget lynx` 复制 Apache 示例配置文件到 /etc/makejail 目录:
# cp/usr/share/doc/makejail/examples/apache.py /etc/makejail/
编辑 /etc/makejail/apache.py. 您需要修改 chroot, users 和 groups 选项. 运行这个版本的 makejail, 您还可以添加一个 packages 选项. 详见 . 下边是一个示例:
chroot="/var/chroot/apache" testCommandsInsideJail=["/usr/sbin/apachectl start"] processNames=["apache"] testCommandsOutsideJail=["wget -r --spider http://localhost/", "lynx --source https://localhost/"] preserve=["/var/www", "/var/log/apache", "/dev/log"] users=["chrapach"] groups=["chrapach"] packages=["apache", "apache-common"] userFiles=["/etc/password", "/etc/shadow"] groupFiles=["/etc/group", "/etc/gshadow"] forceCopy=["/etc/hosts", "/etc/mime.types"]

FIXME: 一些选项似乎不能正确运行. 例如, /etc/shadow 和 /etc/gshadow 没有复制, 然而 /etc/password 和 /etc/group 是全部复制的, 而不是经过过滤.

创造 chroot 目录树: `makejail /etc/makejail/apache.py` 如果 /etc/password 和 /etc/group 被全部复制, 键入:
$ grep chrapach /etc/passwd > /var/chroot/apache/etc/passwd $ grep chrapach /etc/group > /var/chroot/apache/etc/group
用过滤出的拷贝覆盖它们. 复制网站的网页和日志文件到 jail 中. 这些文件都不是自动复制的.(参阅 makejail 配置文件中的 preserve 项).
# cp -Rp /var/www /var/chroot/apache/var # cp -Rp /var/log/apache/*.log /var/chroot/apache/var/log/apache
编辑启动脚本为系统日志守护进程, 使其同时也监听 /var/chroot/apache/dev/log socket. 在 /etc/init.d/sysklogd 文件中, 用 `SYSLOGD=" -a /var/chroot/apache/dev/log"` 替换 `SYSLOGD=""` 然后重启守护进程 (`/etc/init.d/sysklogd restart`). 编辑 Apache 的启动脚本(/etc/init.d/apache). 您可能需要适当地做对缺省的启动脚本做一些调整, 使其在 chroot 目录树中运行正常. 譬如: 在文件顶部设置一新 CHRDIR 变量; 编辑 start, stop, reload, 等部分; 增加一行用于在 jail 中加载和卸载 /proc 文件系统
#! /bin/bash # # apache Start the apache HTTP server. # CHRDIR=/var/chroot/apache NAME=apache PATH=/bin:/usr/bin:/sbin:/usr/sbin DAEMON=/usr/sbin/apache SUEXEC=/usr/lib/apache/suexec PIDFILE=/var/run/$NAME.pid CONF=/etc/apache/httpd.conf APACHECTL=/usr/sbin/apachectl trap "" 1 export LANG=C export PATH test -f $DAEMON || exit 0 test -f $APACHECTL || exit 0 # ensure we don't leak environment vars into apachectl APACHECTL="env -i LANG=${LANG} PATH=${PATH} chroot $CHRDIR $APACHECTL" if egrep -q -i "^[[:space:]]*ServerType[[:space:]]+inet" $CONF then exit 0 fi case "$1" in start) echo -n "Starting web server: $NAME" mount -t proc proc /var/chroot/apache/proc start-stop-daemon --start --pidfile $PIDFILE --exec $DAEMON \ --chroot $CHRDIR ;; stop) echo -n "Stopping web server: $NAME" start-stop-daemon --stop --pidfile "$CHRDIR/$PIDFILE" --oknodo umount /var/chroot/apache/proc ;; reload) echo -n "Reloading $NAME configuration" start-stop-daemon --stop --pidfile "$CHRDIR/$PIDFILE" \ --signal USR1 --startas $DAEMON --chroot $CHRDIR ;; reload-modules) echo -n "Reloading $NAME modules" start-stop-daemon --stop --pidfile "$CHRDIR/$PIDFILE" --oknodo \ --retry 30 start-stop-daemon --start --pidfile $PIDFILE \ --exec $DAEMON --chroot $CHRDIR ;; restart) $0 reload-modules exit $? ;; force-reload) $0 reload-modules exit $? ;; *) echo "Usage: /etc/init.d/$NAME {start|stop|reload|reload-modules|force-reload|restart}" exit 1 ;; esac if [ $? == 0 ]; then echo . exit 0 else echo failed exit 1 fi

FIXME: 第一个 Apache 进程应当以其它用户而不是 root 用户运行的(即, add --chuid chrapach:chrapach)? Cons: chrapache将需要对日志有写权限, 这非常不便.

在 /etc/logrotate.d/apache 中用 `/var/chroot/apache/var/log/apache/*.log` 替换 `/var/log/apache/*.log` 启动 Apache(/etc/init.d/apache start), 并检查 jail 日志文件中的相关报告(/var/chroot/apache/var/log/apache/error.log). 如果您的配置更加复杂, (例如, 您同时还使用 PHP 和 MySQL), 文件可能会找不到. 如果一些文件 makejail 没有自动复制, 您可以在 /etc/makejail/apache.py 配置文件的 forceCopy(直接拷贝的文件) 或 packages (直接拷贝的整个软件包和它们的依赖包) 选项中列出.

键入 `ps aux | grep apache` 以确保 Apache 正在运行. 您应当看到如下类似内容:

root 180 0.0 1.1 2936 1436 ? S 04:03 0:00 /usr/sbin/apache chrapach 189 0.0 1.1 2960 1456 ? S 04:03 0:00 /usr/sbin/apache chrapach 190 0.0 1.1 2960 1456 ? S 04:03 0:00 /usr/sbin/apache chrapach 191 0.0 1.1 2960 1456 ? S 04:03 0:00 /usr/sbin/apache chrapach 192 0.0 1.1 2960 1456 ? S 04:03 0:00 /usr/sbin/apache chrapach 193 0.0 1.1 2960 1456 ? S 04:03 0:00 /usr/sbin/apache
通过查看 /proc 文件系统来确认 Apache 在 chroot 环境下运行: `ls -la /proc/process_number/root/.`. 这里 process 是上边列出的 PID 号码(例如第二栏 189).应当列出限制目录树的内容:
drwxr-sr-x 10 root staff 240 Dec 2 16:06 . drwxrwsr-x 4 root staff 72 Dec 2 08:07 .. drwxr-xr-x 2 root root 144 Dec 2 16:05 bin drwxr-xr-x 2 root root 120 Dec 3 04:03 dev drwxr-xr-x 5 root root 408 Dec 3 04:03 etc drwxr-xr-x 2 root root 800 Dec 2 16:06 lib dr-xr-xr-x 43 root root 0 Dec 3 05:03 proc drwxr-xr-x 2 root root 48 Dec 2 16:06 sbin drwxr-xr-x 6 root root 144 Dec 2 16:04 usr drwxr-xr-x 7 root root 168 Dec 2 16:06 var

键入: `ls -la /proc/`cat /var/chroot/apache/var/run/apache.pid`/root/.` 自动完成整个测试

FIXME: 增加其它的测试, 以确保 jail 被关闭了?

我喜欢这样的原因是因为设定 jail 不是很困难, 并且服务器可以通过下边两行更新:

apt-get update && apt-get install apache makejail /etc/makejail/apache.py
其它

如果您要寻找更多资料, 不妨考虑这些信息来源的大本营: , 这个程序是由 Alain Tesio 完成的 by Jonathan, Network Dweebs, 21/10/2002