Debian/Ubuntu Linux:通过设置chrooted jail将SSH用户会话限制到特定目录

时间:2020-01-09 10:38:04  来源:igfitidea点击:

问题描述:
我需要授权给用户ssh访问权限,但我不信任用户。如何将ssh用户会话限制为特定目录,例如/home/httpd/$USERNAME?

如何在Linux操作系统上设置ssh chroort监狱?

解决方法:您可以在Linux或类似Unix的系统上使用特殊的根目录进行交互式shell。您可以在身份验证后将目录的路径名(例如/home/httpd/foo)设置为chroot。 "路径名"的所有组件都必须是"根目录",而"其他任何用户或组"均不可写。在chroot之后,sshd将工作目录更改为用户的主目录。

ChrootDirectory指令

ChrootDirectory必须包含必要的文件和目录以支持用户会话。
对于交互式会话,这至少需要一个shell(通常为sh(1))和基本/dev节点,例如null(4),zero(4),stdin(4),stdout(4),stderr(4),随机(4)和tty(4)设备。
对于使用sftp的文件传输会话,如果使用进程内sftp服务器,则无需对环境进行其他配置,尽管使用日志记录的会话确实需要chroot目录中的/dev/log。

您可以授予您不完全信任的用户ssh访问权限。
您可以通过设置SSH chroot监狱来限制该用户只能看到或运行ls,date和内部bash命令。
让我们看看如何在Debain或Ubuntu Linux服务器上为OpenSSH服务器创建chroot监狱。
以下教程已在Debian Linux服务器v8.1上进行了测试:

# lsb_release -a

查找Linux发行版和名称命令

1.以root用户身份登录

执行以下任一命令:

$ su 

或者

$ sudo -s

2.创建chroot监狱

我将设置/home/jails /目录以将ssh用户会话限制为该目录:

# D=/home/jails
# mkdir -p $D

按照sshd手册页,您还需要以下文件:

# ls -l /dev/{null,zero,stdin,stdout,stderr,random,tty}

输出示例:

crw-rw-rw- 1 root root 1, 3 Jun 11 03:11 /dev/null
crw-rw-rw- 1 root root 1, 8 Jun 11 03:11 /dev/random
lrwxrwxrwx 1 root root   15 Jun 11 03:11 /dev/stderr -> /proc/self/fd/2
lrwxrwxrwx 1 root root   15 Jun 11 03:11 /dev/stdin -> /proc/self/fd/0
lrwxrwxrwx 1 root root   15 Jun 11 03:11 /dev/stdout -> /proc/self/fd/1
crw-rw-rw- 1 root tty  5, 0 Jun 11 04:43 /dev/tty
crw-rw-rw- 1 root root 1, 5 Jun 11 03:11 /dev/zero

要创建所需的/dev节点条目,请使用以下mknod命令:

# mkdir -p $D/dev/
# mknod -m 666 $D/dev/null c 1 3
# mknod -m 666 $D/dev/tty c 5 0
# mknod -m 666 $D/dev/zero c 1 5
# mknod -m 666 $D/dev/random c 1 8

3.设置权限

执行以下命令,以便chroot $D目录及其所有组件必须由root用户拥有,并且不能由任何非root用户或组写入:

# chown root:root $D
# chmod 0755 $D

验证一下:

# ls -ld $D

输出示例:

drwxr-xr-x 2 root root 4096 Jun 11 03:14 /home/jails

4.在$D中安装bash shell

执行以下命令以在$D路径中创建bin目录:

# mkdir -p $D/bin

将/bin/bash复制到$D/bin /目录:

# cp -v /bin/bash $D/bin

输出示例:

‘/bin/bash’ -> ‘/home/jails/bin/bash’

将所需的共享库复制到$D目录。
语法如下,以确定需要什么bash:

# ldd /bin/bash

输出示例:

linux-vdso.so.1 (0x00007ffdbb1bc000)
	libncurses.so.5 => /lib/x86_64-linux-gnu/libncurses.so.5 (0x00007f1349bc6000)
	libtinfo.so.5 => /lib/x86_64-linux-gnu/libtinfo.so.5 (0x00007f134999c000)
	libdl.so.2 => /lib/x86_64-linux-gnu/libdl.so.2 (0x00007f1349797000)
	libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007f13493ee000)
	/lib64/ld-linux-x86-64.so.2 (0x00007f1349e0d000)

使用cp命令按如下所示一对一复制突出显示的文件:

# mkdir -p $D/lib/
# mkdir -p $D/lib64/
# mkdir -p $D/lib/x86_64-linux-gnu/
# cp -v /lib/x86_64-linux-gnu/{libncurses.so.5,libtinfo.so.5,libdl.so.2,libc.so.6} $D/lib/

输出示例:

‘/lib/x86_64-linux-gnu/libncurses.so.5’ -> ‘/home/jails/lib/libncurses.so.5’
‘/lib/x86_64-linux-gnu/libtinfo.so.5’ -> ‘/home/jails/lib/libtinfo.so.5’
‘/lib/x86_64-linux-gnu/libdl.so.2’ -> ‘/home/jails/lib/libdl.so.2’
‘/lib/x86_64-linux-gnu/libc.so.6’ -> ‘/home/jails/lib/libc.so.6’

接下来,将/lib64/ld-linux-x86-64.so.2复制到/lib64 /目录:

# cp -v /lib64/ld-linux-x86-64.so.2 $D/lib64/

输出示例:

‘/lib64/ld-linux-x86-64.so.2’ -> ‘/home/jails/lib64/ld-linux-x86-64.so.2’

最后,复制/lib/x86_64-linux-gnu/libnss_files *,输入:

# cp -va /lib/x86_64-linux-gnu/libnss_files* $D/lib/x86_64-linux-gnu/

5.将用户添加到系统

您还需要将/etc/passwd和/etc/group文件复制到$D/etc /目录:mkdir -p $D/etc /添加一个名为tom和jerry的用户:

# adduser tom
# adduser jerry

输出示例:
在Debian Linux 8服务器上添加用户

最后,将更新的/etc/{passwd,group}文件复制到$D/etc /目录:

# cp -vf /etc/{passwd,group} $D/etc/

输出示例:

‘/etc/passwd’ -> ‘/home/jails/etc/passwd’
‘/etc/group’ -> ‘/home/jails/etc/group’

警告:如果您在/etc/passwd文件中添加,删除或更改了用户名或密码,请通过运行以下两个命令再次重新复制/etc/{passwd,group}文件:D =/home/jails cp -vf/etc/{passwd,group} $D/etc /

6.配置sshd

编辑/etc/ssh/sshd_config文件,输入:

# vi /etc/ssh/sshd_config

追加以下两个指令:

##  Apply the chrooted jail to the user called tom and jerry ##
Match User tom,jerry
ChrootDirectory /home/jails
## Allow sftp to chrooted jail ##
ForceCommand internal-sftp

7.重新启动sshd服务

对于Debian Linux版本8.x,输入:

# systemctl restart ssh.service

对于Debian 7.x及更早版本,请输入:

# /etc/init.d/ssh restart

8.测试

语法为:

ssh user@sever
ssh user@sever-ip-here
ssh tom@localhost

输出示例:

tom@localhost's password: 

Last login: Thu Jun 11 04:32:32 2015 from localhost
Could not chdir to home directory /home/tom: No such file or directory
-bash-4.3$ ls
-bash: ls: command not found
-bash-4.3$ date
-bash: date: command not found
-bash-4.3$ pwd
/
-bash-4.3$

9.安装其他命令

现在,该tom用户可以登录服务器,但不能运行其他命令,例如ls,date等。
该用户仅限于/bin/bash。
如果需要ls或任何其他命令,则需要像在/bin/bash中一样将它们安装在/home/jails /目录中。
最简单的方法如下:

# cd /root/
wget http://www.theitroad.local/files/lighttpd/l2chroot.txt
# mv l2chroot.txt l2chroot
# chmod +x l2chroot
# vi l2chroot

找到BASE行,并进行如下更改:

BASE="/home/jails"

保存并关闭文件。
在$D/bin /目录中安装/bin/ls:

# cp -v /bin/ls $D/bin/
# cp -v /bin/date $D/bin/
# /root/l2chroot /bin/ls
# /root/l2chroot /bin/date

创建$D/home/tom和$D/home/jerry目录:

# mkdir -p $D/home/{tom,jerry}
# chown -R tom:tom $D/home/tom/
# chown -R jerry:jerry $D/home/jerry/
# chmod -R 0700 $D/home/tom/
# chmod -R 0700 $D/home/jerry/

10.再次验证并测试

sftp命令的语法如下:

sftp user@server
sftp user@server-ip-here
sftp [email protected]

输出示例:

[email protected]'s password: 
Connected to server1.theitroad.local.

sftp> pwd
Remote working directory: /home/tom
sftp> ls
sftp> cd /home
sftp> ls
jerry  tom    
sftp> pwd
Remote working directory: /home
sftp> ls -l
drwx------    2 jerry    jerry        4096 Jun 11 08:55 jerry
drwx------    2 tom      tom          4096 Jun 11 08:53 tom
sftp> cd jerry
sftp> pwd
Remote working directory: /home/jerry
sftp> ls
remote readdir("/home/jerry"): Permission denied
sftp> ls
remote readdir("/home/jerry"): Permission denied
sftp> put /etc/resolv.conf .
Uploading /etc/resolv.conf to /home/jerry/.
remote open("/home/jerry/."): Permission denied
sftp> cd /home/tom
sftp> put /etc/resolv.conf .
Uploading /etc/resolv.conf to /home/tom/./resolv.conf
/etc/resolv.conf                                                 100%   70     0.1KB/s   00:00    
sftp> ls -l
-rw-r--r--    1 tom      tom            70 Jun 11 09:01 resolv.conf
sftp>  quit

如何将用户的Web服务器(DocumentRoot)映射到/home/jails /目录?

假设/home/httpd/tom_web是tom用户的DocumentRoot,然后:

# mkdir $D/home/tom/web
# mount --bind /home/httpd/tom_web $D/home/tom/web
## update fstab file so that it can mount after server reboot ##
# echo "/home/httpd/tom_web/ $D/home/tom/web none bind" >> /etc/fstab