Chroot Linux中所有的服务

/ns/wz/sys/data/20020731035229.htm


摘要:




对系统服务进行chroot以限制入侵者可能造成的破坏,从而提高系统的安全性。





--------------------------------------------------------------------------------



转帖
来源不明


介绍


什么是chroot?chroot基本上重定义了一个程序的运行环境。更确切地说,它重定义了一个程序(或登录会话)的“ROOT”目录或“/”。
也就是说,对于chroot了的程序或shell来说,chroot环境之外的目录是不存在的。

那这样又有什么用呢?如果入侵者入侵了你的电脑,他们就不能看见你系统里所有的文件了。
这样,就限制了入侵者可能执行的命令,从而禁止了他们溢出不安全文件的机会。但唯一的缺点是,
我认为这不能阻止他们察看网络连接和其他资料。因此,你应做一些本文未深入涉及的事情:




保护网络端口。

察看是否所有的服务都以非root权限运行。另外,是否所有的服务都进行了chroot?

把系统日志转移到其他电脑。

分析日志文件。

分析那些试图探测你的计算机的随机端口的人们。

限制服务所占用的cpu和内存资源。

激活用户配额。

我认为(把以非root权限运行的服务进行)chroot可以作为一道安全防线的原因是,
如果入侵者得到了一个非root账户,但没有使他们得到root权限的文件的话,那么他们只能对所入侵的区域造成破坏。
而且,如果root账户是入侵区域大部分文件的拥有者的话,入侵者是没有多少攻击的选择的。显然,如果你的账户被入侵,
那一定是某些地方出问题了,但最好能减少入侵者所能造成的破坏。

请记住 我所做的并不是100%正确的。这是我第一次尝试这样做,就算只是部分有效的话,
也应该是很容易完成基本的配置的。我想做一个chroot的HOWTO,现在所说的只是一些基本的东西。



怎样把所有的服务都chroot呢?

好的,让我们先创建一个目录“/chroot”,然后以下面的格式把我们的所有服务都放在它下面:



Syslogd 分别和每一个服务一起运行在hroot环境下。

Apache 运行在/chroot/httpd下.

Ssh 运行在/chroot/sshd下.

PostgreSQL 运行在/chroot/postmaster下.

Sendmail 运行在 chroot环境下,但不幸的是,它必须以root权限运行。

ntpd 运行在 /chroot/ntpd下。

named 运行在 /chroot/named 下。
每一个服务都是完全与外界隔离的。


我用来创建chroot环境的Perl脚本。

下载 href="http://main.linuxfocus.org/common/src/article225/Config_Chroot.pl.txt">Config_Chroot.pl.txt并更名为 Config_Chroot.pl. 这个Perl脚本让你列出所有已安装的服务,查看配置文件,配置服务,并启动和停止服务。通常,这就是你应该做的。



创建chroot目录
mkdir -p /chroot/Config/Backup

下载 href="http://main.linuxfocus.org/common/src/article225/Config_Chroot.pl.txt">Config_Chroot.pl.txt
并更名为 /chroot/Config_Chroot.pl

如果你的家目录(home directory)不是/chroot,请把Perl脚本里的$Home 变量作相应的改变。

下载我的 href="http://main.linuxfocus.org/common/src/article225/">配置文件。

现在,重要的是:我只在 RedHat
7.2 和 RedHat 6.2 上测试过。.

请在Perl脚本里作相应的改变以适应你的发行版。


关于chroot,我写了一遍很长的文章,但有了我的脚本,它变得短了很多。在chroot了很多服务之后,我注意到这些服务中需要被chroot的文件和配置都很相似。对一个特定的服务来说,判断哪些文件需要拷贝的最容易的方法是查看man,如果程序要用到库文件,就再键入“ldd /usr/bin/file“。你还可以把你正在安装的服务进行chroot并手动启动, 看看出了什么错或查一查它的日志文件。


通常,要安装一个服务,可以这样做:

cd /chroot
./Config_Chroot.pl config SERVICE
./Config_Chroot.pl install SERVICE
./Config_Chroot.pl start SERVICE




对 Ntpd 进行 Chroot


Ntpd 是一个时间服务,它使你的计算机以及其它计算机和实际时间同步。把它chroot是很简单的。

cd /chroot
# 如果你没有使用我的配置文件,请把下一行的注释去掉。
#./Config_Chroot.pl config ntpd
./Config_Chroot.pl install ntpd
./Config_Chroot.pl start ntpd




对 DNS 和 named 进行 Chroot

已经有了howto文件,请看
href="http://www.linuxdoc.org/HOWTO/Chroot-BIND8-HOWTO.html">http://www.linuxdoc.org/HOWTO/Chroot-BIND8-HOWTO.html


href="http://www.linuxdoc.org/HOWTO/Chroot-BIND-HOWTO.html">http://www.linuxdoc.org/HOWTO/Chroot-BIND-HOWTO.html


如果你想用我的脚本

cd /chroot
# 如果你没有使用我的配置文件,请把下一行的注释去掉。
#./Config_Chroot.pl config named
./Config_Chroot.pl install named
./Config_Chroot.pl start named




把 Syslog 和其他服务一起进行chroot以及我所遇到的困难。

我想把syslogd进行chroot。我遇到的困难是,syslogd默认使用/dev/log目录,而chroot了的服务是看不见这个目录的。因此,用syslogd做日志记录就不是很方便了。下面是可能的解决方案。



把syslogd分别和每一个服务进行chroot。我实际上就是这样测试的,而且记录了一些日志。我不喜欢这样做,因为我有一个以root权限运行的服务。

看看我们是否能连接到外部日志记录设备。

直接把日志记录到文件上而不是通过syslogd。这可能是最好的安全选择了,尽管如果被入侵,入侵者可以随意改动日志。

配置syslogd来查看几个地方,从而得到所有的服务,你可以用syslogd的-a选项来做到。

我的唯一的解决方案是确保syslogd分别和每一个服务进行chroot。我喜欢这样的解决方案,它以非root权限在自己的chroot环境(有些像网络端口)下记录日志。这也许是可行的,但我正在停止我所做的,然后寻求一个更好的解决方案。

如果你不想为每一个服务都配备一个独立的syslogd,那么当你的系统运行syslogd时,请在syslogd开始时运行下面命令:


syslogd -a /chroot/SERVICE/dev/log

如果有ssh和dns要运行,那么看上去应该像这样:
syslogd -a /chroot/ssh/dev/log -a /chroot/named/dev/log -a /dev/log



关于syslogd,我最后想说的是,我希望它能运行在非root账户下。我试了几个简单的东西,
但都没有成功,于是就放弃了。如果能让syslogd和每一个服务一起运行在非root账户下,
我就会对我的安全措施感到满意了。如果可能的话,最好将日志记录到外部设备上。



对 Apache 进行 Chroot

很简单。一旦我运行它,就可以执行Perl脚本。现在,我的配置文件是很长的,
因为我必须在chroot环境下包括Perl和PostgreSQL函数库。有一件事要注意,如果你要连接到数据库上,
请确保你的数据库服务运行在127.0.0.1 回环设备上,并在关于DBI的Perl脚本中指定主机为127.0.0.1.
下面是我怎样把apache永久连接到一个数据库上的例子:

$dbh ||= DBI->connect(dbi:Pg:dbname=DATABASE,"","", {PrintError=>0});

if ($dbh ) {$dbh->{PrintError} = 1;}
else
{$dbh ||= DBI->connect(dbi:Pg:dbname=DATABASE;host=127.0.0.1,"","",
{PrintError=>1});}



源地址: hrf="http://httpd.apache.org/dist/httpd/">http://httpd.apache.org/dist/httpd/



把apache编译并安装在你系统的/usr/local/apache目录下,然后运行Perl脚本。


cd /chroot
# 如果你没有使用我的配置文件,请把下一行的注释去掉。
# ./Config_Chroot.pl config httpd
./Config_Chroot.pl install httpd
./Config_Chroot.pl start httpd

在httpd.conf文件里包含以下几行:
ExtendedStatus On

<Location /server-status>
SetHandler server-status
Order deny,allow
Deny from all
Allow from 127.0.0.1
</Location>

<Location /server-info>
SetHandler server-info
Order deny,allow
Deny from all
Allow from 127.0.0.1
</Location>


然后,在你的浏览器里输入 http://127.0.0.1/server-status 或 http://127.0.0.1/server-info 并检查!


对 Ssh 进行 Chroot

首先,如果把ssh从端口22重定向到2222就理想了。然后,当你启动ssh时,
让它在一个非root账户下监听2222端口。在初始化ssh连接时,我们只想让有密码的安全账户连进来,但不做其他任何事情。
在他们登录之后,运行在端口127.0.0.1:2222 的第二个ssh程序让它们连接到真正的系统 -- 这第二个ssh程序应该只在回环设备上监听。
这才是你应该做的。现在我们不打算去做。我们要做的唯一的事情是以这个chroot的ssh做个例子。
上面提到的一个练习就请读者自己完成:让sshd运行在非root账户下,再安装第二个监听回环设备的sshd以使人们连进真正的系统。

此外,我们只要把ssh进行chroot并让你看一看那样做的结果(如果你只做了这些,你不必观察整个系统)。
当然,如果能把日志记录在外部设备上就更好了。我们应该用OpenSSH,但为了方便(这好像不是一个好的借口),我用的是一个商业的SSH。


源地址: href="http://www.ssh.com/products/ssh/download.cfm">http://www.ssh.com/products/ssh/download.cfm



在/usr/local/ssh_chroot下安装ssh并运行脚本。


cd /chroot
# 如果你没有使用我的配置文件,请把下一行的注释去掉。
# ./Config_Chroot.pl config sshd
./Config_Chroot.pl install sshd
./Config_Chroot.pl start sshd

我觉得把ssh放在chroot环境下的一个真正有益的事情是,如果你用它代替ftp服务器,人们在你的区域里就只有有限的权限。
Rsync 和 SCP 在人们上传文件时运行得非常好。我不是很喜欢建立ftp服务器让人们登录。很多ftp服务器都运行在chroot环境下,
但我不喜欢他们仍旧传送明文密码。


把 PostSQL 进行 Chroot

这几乎和perl一样简单,除了它需要一些额外的函数库。总的来说,这并不难做。
我必须做的一件事是把PostgreSQL放在网络上,但仅仅是放在回环设备上。因为它是被chroot了的,
所以其他已经chroot了的服务是不能和它接触的,就像web服务器 apache 一样。
我把Perl编译进PostgreSQL里去了,因此我必须在我的配置文件里加很多Perl的东西。

源代码: href="ftp://ftp.us.postgresql.org/source/v7.1.3/postgresql-7.1.3.tar.gz">ftp://ftp.us.postgresql.org/source/v7.1.3/postgresql-7.1.3.tar.gz



把apache编译并安装在你系统里的/usr/local/postgres目录下。然后运行Perl脚本。


cd /chroot
# 如果你没有使用我的配置文件,请把下一行的注释去掉。
# ./Config_Chroot.pl config postgres
./Config_Chroot.pl install postgres
./Config_Chroot.pl start postgres




把 Sendmail 进行 Chroot

请执行我的Perl脚本。
cd /chroot
# 如果你没有使用我的配置文件,请把下一行的注释去掉。
# ./Config_Chroot.pl config sendmail
./Config_Chroot.pl install sendmail
./Config_Chroot.pl start sendmail

现在你发现什么了?是的,他仍旧以root账户运行。而且,当sendmail启动的时候,程序/etc/rc.d/init.d/sendmail会重新建立一些文件。
我的脚本并没有解决这个问题。无论何时,如果你在/etc/mail下做了任何改动,请把改动过的文件拷贝到/chroot/sendmail/etc目录下。
你还必须把/var/spool/mail指向/chroot/sendmail/var/spool/mail,以使sendmail程序和用户(当他们登录进来的时候)看到的是相同的文件。

好在你随时可以发送邮件,当你收信的时候才会出问题。因此,我可以把sendmail和apache一起安装而不出问题。
我的一些Perl脚本会向外发送邮件,所以我要把sendmail程序拷贝到apache的chroot环境下。



关于 Chroot 的其他一些事情。

下面是我的观点:



你的机器上包括sendmail, ssh, apache,
postgresql, syslog在内的所有服务都必须运行在chroot环境下。

每一个服务都必须以非root账户运行(你也许需要把已受保护的端口重定向到未受保护得端口。这包括sendmail和syslog。

日志应该远离现场。

对每一个服务都实行磁盘配额,以限制入侵者所能占用的磁盘。当磁盘已写满时,你应该在回环设备上为某些服务安装文件系统。

所有不需改动的文件的拥有者应该是root账户。
现在,说到sendmail和syslogd,我仍然认为他们不应运行在root账户下。
对于sendmail,这也许是可能的,但我发现让它运行在非root账户下是极其困难的,至少我还没有成功过。
我想,sendmail不能运行在非root账户下应是一个很严重的错误。虽然我知道让它运行在非root账户下很困难,
但我认为所有的困难都是可以解决的。只要解决了文件的许可权问题,我觉得sendmail是不必以root权限运行的。
我肯定是忽略了什么东西,我不相信这些障碍是不可征服的。

至于syslog,我还没有试过,但我认为应该以非root账户去记录日志,我想这应该是可行的。
至少我可以为每一个服务在chroot的环境下记录日志。


所有的服务都要运行在非root账户下,甚至是NFS。请记住,是所有的服务。



建议





请运行两个sshd守护进程,并进行二次登录。

设法使sendmail或其他邮件程序运行在非root账户下。

删掉/lib下不需要的函数库。我只是拷了我需要的函数库在上面。其实你不需要其中的大部分。

请用syslogd进行远程日志记录,看看我们是否能让syslogd连接到网络端口上并得到运行在回环设备网络端口上的所有服务的日志。
看看能否使syslogd运行在非root账户下。




结论


我觉得对所有的服务来说chroot都是那么酷,我想,不能让所有的服务都运行在非root账户的chroot环境下应该是个很大的错误。
我希望主要的发行版应该做到这一点,当然,也希望其它发行版做到。Mandrake 以兼容 RedHat 起家并发展,因此,人们可以仿效 Mandrake ,
在其他人的基础上对chroot进行扩展。我认为这是可行的,因为在GNU/Linux里,没有什么会阻止你重做其他人的工作。
如果某个公司想chroot所有服务并为人们创建了一套容易管理chroot了的服务的环境,那么它就拥有了一个理想的发行版。
记住,Linux正趋向主流,人们不想再看见命令行,因此如果每件事都可以在gui的环境下去做,人们就不需要了解内部的构造,
并且不需要知道到底是什么在运行,他们只要能配置并知道这是行之有效的就行了。

我绝对支持让所有服务都运行在非root权限的chroot的环境下,任何不能做到这一点的发行版,我都不会考虑在生产环境中使用它。
我正使所有的服务都运行在chroot环境下,尽我的可能使越来越多的东西这样运行 -- 最终,我会达到我的理想。


我打算为chroot写一个HOWTO。我正发送请求,希望某个人能够把我这篇文章转换成LyX格式,以便它可以放到Linux得HOWTO上。



参考书目





如有变动,请见 href="http://www.gnujobs.com/Articles/23/chroot.html">http://www.gnujobs.com/Articles/23/chroot.html