摘自:https://blog.csdn.net/yanggd1987/article/details/54310686
需求
普通用户通过ssh登陆到跳板机后,再通过ssh跳转到内网其他服务器。跳板机只提供ssh、ls等基本命令,禁止scp、sftp、管道等以防数据传输到本地;另外用户登陆后需要将其锁定在特定的目录下,防止用户浏览服务器数据。
通常情况下我们使用磁盘限额来限制用户传输数据,但是磁盘限额必须是针对独立的磁盘分区,而不能够是文件目录,因此用户家目录必须是独立挂载的,若是放在根目录下,配置磁盘限额效果不大。
ssh的chroot功能就可以很好的解决此类问题。根据sshd_config的man中所述,实现chroot功能需要配置”ChrootDirectory”这个参数。
ChrootDirectory:定义了用户通过认证以后的chroot目录,此目录及其所有子目录的属主必须是root,且这些目录只有root帐号可以进行写操作,其他任何组和帐号都不可写。chroot以后,sshd会将用户的工作目录转到chroot目录中用户自己的主目录。如果ChrootDirectory定义的目录下没有相应的/home/username目录,则会直接转到chroot的/目录下
配置
本次实验将test用户锁定在/var/chroot下,test登陆后只能使用ssh、ls等基本命令。
一、创建用户
1.创建test用户(不创建其缺省家目录)
useradd -M test passwd test
2.建立chroot目录中用户主目录
mkdir -p /var/chroot/home/test chown -R test.test /var/chroot/home/test chmod 700 /var/chroot/home/test
二、搭建基本的chroot环境
注意:一个最基本的chroot环境至少有一个shell(例如sh,bash)和一些必要的系统设备文件(例如/dev/null,/dev/zero),如果要允许用户执行一些命令,那么还要准备相应的命令可执行文件和命令依赖的库文件
mkdir -p /var/chroot cd /var/chroot mkdir {bin,dev,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} #复制/etc/passwd和/etc/group文件到/var/chroot/etc中,并删除用户自己和root以外的所有帐号。如果没有这两个文件,用登录以后会报“I have no name!” cp -p /etc/passwd /var/chroot/etc/ cp -p /etc/group /var/chroot/etc/
cat /var/chroot/etc/group
root:x:0:
test:x:516:
cat /var/chroot/etc/passwd
root:x:0:0:root:/root:/bin/bash
test:x:516:516::/home/test:/bin/bash
三、配置ssh
vim /etc/ssh/sshd_config
#在最后添加如下行,否则会报错
Match User test
ChrootDirectory /var/chroot
#重启ssh
service sshd restart
四、拷贝基础命令
例如用户登陆后必须有一个可用的shell,因此用到/bin/bash,还有其他命令如ls、mkdir等。
注意:/bin/ls命令和/usr/bin/ssh命令使用的类库文件目录不一样,因此我们需要在执行脚本前先建好相应的路径(此问题已经通过脚本解决)
ldd /bin/ls | awk '{ print $3 }' | grep "/lib" | sort | uniq /lib64/libacl.so.1 /lib64/libattr.so.1 /lib64/libcap.so.2 /lib64/libc.so.6 /lib64/libdl.so.2 /lib64/libpthread.so.0 /lib64/librt.so.1 /lib64/libselinux.so.1 ldd /usr/bin/ssh | awk '{ print $3 }' | grep "/lib" | sort | uniq /lib64/libcom_err.so.2 /lib64/libcrypt.so.1 /lib64/libc.so.6 /lib64/libdl.so.2 /lib64/libfipscheck.so.1 /lib64/libfreebl3.so /lib64/libgssapi_krb5.so.2 /lib64/libk5crypto.so.3 /lib64/libkeyutils.so.1 /lib64/libkrb5.so.3 /lib64/libkrb5support.so.0 /lib64/libnsl.so.1 /lib64/libnspr4.so /lib64/libplc4.so /lib64/libplds4.so /lib64/libpthread.so.0 /lib64/libresolv.so.2 /lib64/librt.so.1 /lib64/libselinux.so.1 /lib64/libutil.so.1 /lib64/libz.so.1 /usr/lib64/libcrypto.so.10 /usr/lib64/libnss3.so /usr/lib64/libnssutil3.so
在此我们使用脚本:
#!/bin/bash #comment:用于ssh登陆chroot后,给用户添加命令 # 要允许执行的文件列表 cmdlist="/bin/bash /bin/ls /bin/cp /bin/mkdir /bin/mv /bin/rm /bin/rmdir /usr/bin/ssh /usr/bin/id" # 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 if [ ! -d `dirname ${chroot_path}$i` ];then mkdir -p `dirname ${chroot_path}$i` fi cp -a $i ${chroot_path}$i && echo "$i done" done # 复制依赖的库文件(因为是i386,所以是lib,如果是x86_64,则是lib64,) for j in $lib_1 do if [ ! -d `dirname ${chroot_path}$j` ];then mkdir -p `dirname ${chroot_path}$j` fi cp -f $j ${chroot_path}$j && echo "$j done" done for k in $lib_2 do if [ ! -d `dirname ${chroot_path}$k` ];then mkdir -p `dirname ${chroot_path}$k` fi cp -f $k ${chroot_path}$k && echo "$k done" done
至此,我们已经能够用test用户登陆了,并且用户被锁定在/var/chroot/home/test目录下,还可以使用ls mkdir等命令,但是此时ssh命令却无法使用。
ssh test@10.60.80.100 bash-4.1$ mkdir test bash-4.1$ ls a test bash-4.1$ ssh root@10.60.80.101 You don't exist, go away!
报这个错意味着系统无法通过用户数据库(可能的类型有 /etcp/passwd, /etc/group, /etc/shadow,/etc/gshadow)校验用户名是否正确。
通常的解决方法是复制对应的文件到chroot目录中。
对于ssh来说,可以复制/lib64/libnss_* ,这些文件复制到chroot目录下的对应目录.
解决方法:
cp /lib64/libnss_* lib64/.
另外通过以上我们可以看到test用户登陆后默认为”bash-4.1$”,这是由于环境配置文件导致,我们可以通过以下更改:
cp /etc/bashrc /var/chroot/etc/ cp /home/xxx/.bashrc /var/chroot/home/test/ cp /home/xxx/.bash_profile /var/chroot/home/test/
测试
1.通过scp传输数据
scp login_union.py test@10.60.80.100:/home/test test@10.10.65.100's password: /etc/bashrc: line 65: id: command not found /etc/bashrc: line 65: id: command not found bash: scp: command not found lost connection
由于我们没有安装id命令,因此显示”/etc/bashrc: line 65: id: command not found”,在脚本中添加/usr/bin/id即可
由于跳板机没有安装scp命令,因此从远程主机传输数据时提示”bash: scp: command not found”,若要解决此问题只需在脚本中添加”/usr/bin/scp”命令即可
2.通过sftp传输数据
若需要允许使用sftp,只需修改以下即可
vim /etc/ssh/sshd_config Subsystem sftp internal-sftp