taoCMS是基于php+sqlite/mysql的国内最小(100Kb左右)的功能完善、开源免费的CMS管理系统

Creating a Chroot Jail for SSH Access

2015-05-11

Creating a Chroot Jail for SSH Access

I wanted to setup a way to allow SSH access to my machine but limit their abilities heavily. To do that I figured a chroot jail was the best way. In this example I'm using ArchLinux and OpenSSH 5.1p1. It should be a very similar process on any *nix operating system.

Setup your test user

The way I'm setting this up, is that all my chrooted users will be added to the sshusers group. So we must setup the group, then add the user.
$ groupadd sshusers
$ adduser -g sshusers user

Setup the jail directories

The next step is to setup all the directories needed. This needs to emulate the / directory to a bare minimum. That is we need a dev, etc, lib, usr, and bin directory as well as usr/bin/. The base directory has to be owned by root.
$ mkdir -p /var/jail/{dev,etc,lib,usr,bin}
$ mkdir -p /var/jail/usr/bin
$ chown root.root /var/jail
You also need the /dev/null file:
$ mknod -m 666 /var/jail/dev/null c 1 3
You need to fill up the etc directory with a few minimum files:
$ cd /var/jail/etc
$ cp /etc/ld.so.cache .
$ cp /etc/ld.so.conf .
$ cp /etc/nsswitch.conf .
$ cp /etc/hosts .
Once this is done you need to figure out what commands you want accessible by your limited users. In this example I only want the users to be able to get into bash and use the ls command. So you must copy the binaries to the jail.
$ cd /var/jail/usr/bin
$ cp /usr/bin/ls .
$ cp /usr/bin/bash .
Now that you've got all the binaries in place, you need to add the proper shared libraries. To find out what libraries are need you can run ldd /path/to/bin. The output looks similar to this:
$ ldd /bin/ls
         linux-gate.so.1 =>    (0xb7f2b000)
         librt.so.1 => /lib/librt.so.1 (0xb7f1d000)
         libacl.so.1 => /lib/libacl.so.1 (0xb7f16000)
         libc.so.6 => /lib/libc.so.6 (0xb7dcf000)
         libpthread.so.0 => /lib/libpthread.so.0 (0xb7db7000)
         /lib/ld-linux.so.2 (0xb7f2c000)
         libattr.so.1 => /lib/libattr.so.1 (0xb7db2000)
Then you have to manually copy each file to the lib directory in your jail. That is a pain. Especially if there is a lot of shared libraries for a binary you want. I came across a useful script called l2chroot which automatically finds the libraries and copies them to your chroot jail.
cd /sbin
wget -O l2chroot http://www.cyberciti.biz/files/lighttpd/l2chroot.txt
chmod +x l2chroot
Edit the l2chroot file and change BASE=”/webroot” to BASE=”/var/jail”. This tells l2chroot where your jail is located so it copies everything to the right place. Now go ahead and run the command on the binaries you want.
l2chroot ls
l2chroot bash

Configure SSHd to Chroot your users

All that is left is to set a few things in your sshd configuration file. You need to make sure you have at least OpenSSH 4.8p1, because before that they didn't have this nice ChrootDirectory() function. Previously there was a few extra steps you had to take to get it working, but really you should have a newer version anyway. To configure ChrootDirectory add the following to /etc/ssh/sshd_config:
Match group sshusers
          ChrootDirectory /var/jail/
          X11Forwarding no
          AllowTcpForwarding no
Note that this also disables X11Forwarding and does not allow port forwarding. If you want to setup a box to allow secure tunneling for your friends, you may want to change this.

Optional Steps

When you login to your test user, you'll notice a prompt as such:
bash-3-2$
That is not a very useful bash prompt. So if you want something a little better I recommend simply copying the contents of /etc/skel to /var/jail/home/user. This gives you a .bashrc file which sets the PS1 variable to a much nicer looking prompt. Here's what mine looks like:
phrygian:~> echo $PS1
h:w>
phrygian:~>


最近有这么一个需求,根据公司安全部的要求,需要在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/

类别:技术文章 | 阅读:193509 | 评论:37 | 标签:ssh jump server

想收藏或者和大家分享这篇好文章→

“Creating a Chroot Jail for SSH Access”共有0条留言

发表评论

姓名:

邮箱:

网址:

验证码:

公告

taoCMS发布taoCMS 3.0.2(最后更新21年03月15日),请大家速速升级,欢迎大家试用和提出您宝贵的意见建议。

捐助与联系

☟请使用新浪微博联系我☟

☟在github上follow我☟

标签云