最近有这么一个需求,根据公司安全部的要求,需要在IDC放一台登录跳板,以后用户访问IDC内的服务器都必须先登录跳板服务器,然后再ssh到其他服务器。

安全部要求安全最大化,普通用户登陆到这台跳板以后只能执行ssh,ls等有限的基础命令。另外要求把用户锁定在特定目录下,这样即使被hack,也不会影响其他用户。

在openssh 4.8p1以前的版本,要支持chroot,必须使用第三方的修改。

而从openssh 4.8p1以后,chroot功能已经被内置了。

下面我说一下做一个满足上边所说的需求的openssh server的步骤。

系统平台: CentOS 4.8 x86_64
          Openssh 5.6p1
          zlib-1.2.5
          openssl-1.0.0c
          
CentOS中带的openssh是3.9版本的,必须升级到4.8p1以后,我选择升级到目前最高版本5.6p1。
具体升级到openssh 5.6p1的方法可以参考我这篇文章

根据sshd_config的man中所述,实现chroot功能需要配置"ChrootDirectory"这个参数。

ChrootDirectory 定义了用户通过认证以后的chroot目录

此目录及其所有子目录的属主必须是root
且这些目录只有root帐号可以进行写操作,其他任何组和帐号都不可写

chroot以后,sshd会将用户的工作目录转到chroot目录中用户自己的主目录。
如果ChrootDirectory定义的目录下没有相应的/home/username目录,则会直接转到chroot的/目录下。

下边是配置过程:

1.增加用户

# useradd -M foo
# passwd foo

2.建立基本的chroot环境

一个最基本的chroot环境最少一个shell(例如sh,bash)和一些必要的系统设备文件(例如/dev/null /dev/zero),如果要允许用户执行一些命令,那么还要准备相应的命令可执行文件和命令依赖的库文件。

# mkdir /var/chroot
# cd /var/chroot
# mkdir {bin,dev,lib,lib64,etc,home}
# mknod dev/null c 1 3
# mknod dev/zero c 1 5


# 可选,这两个文件ssh命令需要,如缺少会报告PRNG is not seeded

# mknod dev/random c 1 8
# mknod dev/urandom c 1 9


# 可选,ssh命令需要,如缺少会报告Host key verification failed.

# mknod dev/tty c 5 0


# 修改/var/chroot及其子目录的属主,并修改权限

# chown -R root.root /var/chroot
# chmod -R 755 /var/chroot

# 允许用户写这些设备文件,不可写会有些命令报错

# chmod 0666 dev/{null,zero,tty}


# 建立pts设备

# mkdir -p /var/chroot/dev/pts
# mount -t devpts devpts /var/chroot/dev/pts

然后我们将要允许用户执行的可执行文件和依赖的库文件复制到相应位置。

例如必须给用户一个可用的shell,我们一般用/bin/bash,所以执行ldd命令查看相关信息:

[root@sshgate ~]$ ldd /bin/bash
       libtermcap.so.2 => /lib64/libtermcap.so.2 (0x0000003665500000)
       libdl.so.2 => /lib64/libdl.so.2 (0x0000003665100000)
       libc.so.6 => /lib64/tls/libc.so.6 (0x0000003664e00000)
       /lib64/ld-linux-x86-64.so.2 (0x0000003664a00000)

我们可以看到/bin/bash要正确执行,依赖于如下几个文件
/lib64/libtermcap.so.2
/lib64/libdl.so.2
/lib64/tls/libc.so.6
/lib64/ld-linux-x86-64.so.2

那么我们必须把/bin/bash和相应的库文件复制到对应的位置。

cp -p /bin/bash /var/chroot/bin
cp -p /lib64/libtermcap.so.2 /var/chroot/lib64
cp -p /lib64/libdl.so.2 /var/chroot/lib64
cp -p /lib64/tls/libc.so.6 /var/chroot/lib64
cp -p /lib64/ld-linux-x86-64.so.2 /var/chroot/lib64


类似上边这样,对每个你想要允许用户执行的文件都如此操作即可。

当然我这只是为了说明具体过程,真正操作的时候肯定要用脚本来执行的。我从台湾一位先达网站抄来一个脚本,略加修改,内容如下:

# 要允许执行的文件列表
cmdlist="/bin/bash /bin/ls /bin/cp /bin/mkdir /bin/mv /bin/rm /bin/rmdir"
# chroot路径
chroot_path="/var/chroot"

# 依赖的库文件判断
lib_1=`ldd $cmdlist | awk '{ print $1 }' | grep "/lib" | sort | uniq`
lib_2=`ldd $cmdlist | awk '{ print $3 }' | grep "/lib" | sort | uniq`

# 复制命令文件
for i in $cmdlist
do
   cp -a $i $chroot_path/bin/ && echo "$i done"
done

# 复制依赖的库文件(因为是x86_64所以是lib64,i386的则是lib)
for j in $lib_1
do
cp -f $j $chroot_path/lib64/ && echo "$j done"
done

for k in $lib_2
do
cp -f $k $chroot_path/lib64/ && echo "$k done"
done


复制/etc/passwd和/etc/group 文件到/var/chroot/etc中,删掉除用户自己和root以外的所有帐号。
如果没有这两个文件,用户登录以后会报“I have no name!”
# grep didi /etc/passwd >> /var/chroot/etc/passwd
# grep didi /etc/group >> /home/chroot/etc/group
完成了基础 chroot 环境的设置后先使用 chroot 命令来检查配置是否正确 :
# chroot /var/chroot

3.建立chroot目录中的用户主目录

# mkdir /var/chroot/home/foo
# cp /etc/skel/* /var/chroot/home/foo
# chown -R foo /var/chroot/home/foo
# chmod 700 /var/chroot/home/foo

4.修改/etc/ssh/sshd_config文件,增加下边内容

Match User foo
ChrootDirectory /var/chroot

本例中,我们指定的chroot目录是/var/chroot。

也可以Match Group,举例如下:
Match Group sftponly
   PasswordAuthentication yes
   AllowAgentForwarding no
   AllowTcpForwarding no
   ChrootDirectory
/var/chroot/%u

如果还要允许用户执行sftp的话,修改sshd_config文件:
Subsystem sftp internal-sftp


# /etc/init.d/sshd restart

ok,经过以上的配置,现在就可以测试了。
用foo帐号ssh登录到系统中,看看是不是被限制在了一个虚假的根目录下了。
再试试执行一些命令,你会发现只有我们复制过来的命令可以执行,其他全都不可以。

常见故障排除:

1.SSH时提示Unkown Terminal type
解决方法:

复制/usr/share/terminfo 到chroot目录的usr/share

2.执行ssh命令时报"You don't exist, go away!"
解决方法:
报这个错意味着系统无法通过用户数据库(可能的类型有 /etcp/passwd, /etc/group, /etc/shadow,/etc/gshadow, LDAP, Kerberos, Windbind)校验用户名是否正确。
通常的解决方法是复制对应的文件到chroot目录中。
对于ssh来说,可以复制/lib64/libnss_* ,/etc/hosts, /etc/nsswitch.conf, /etc/resolv.conf 这些文件复制到chroot目录下的对应目录。
========================
2013-02-27 追加:

如何在chroot环境下安装软件

# mkdir -p /var/chroot/var/lib/rpm
# rpm --root /var/chroot --initdb
# yumdownloader --destdir=/var/tmp centos-release
# cd /var/tmp
# rpm --root /var/chroot -ivh --nodeps centos-release*rpm
# yum --installroot=/var/chroot install openssh-clients

这种安装方法会把所有依赖的程序包都装上,因此不能说是一个很安全的方法。
但确实是一种很快速和简单的方法,请酌情考虑使用。

此追加参考了http://prefetch.net/articles/yumchrootlinux.html

参考文档:
http://www.systemonix.com/2012/06/chroot-linux.html
http://blog.dougco.com/unix/svn-in-chroot-says-you-dont-exist/