镜缘浮影 小人本住在 苏州的城外 家里有屋又有田 生活乐无边

构建 chroot 监狱

2017-07-30
wilmosfang
原文地址 http://soft.dog/2017/07/30/chroot/

前言

在 linux 系统中,系统默认的目录结构都是以 / 根开始的

chroot 的作用就是可以以指定的位置作为 /

这样可以有效限制用户的权力范围,增加系统安全,也可以利用这个特性创建一个隔离环境屏蔽掉大环境的影响,进行隔离开发

系统在引导阶段是通过 chroot 将执行权限从 RAM 的 initrd 切换到真实的根系统,系统的 resume 模式中也是通过 chroot 来加载实际环境中的应用

Tip: chroot 命令其实调用的是 chroot() 函数


概要


系统环境

[root@56-201 home]# hostnamectl 
   Static hostname: 56-201
         Icon name: computer-vm
           Chassis: vm
        Machine ID: 33dc28f7e76c4903ad9b603b77e29a7c
           Boot ID: ad75de6f5afd4946915941f94ca644a5
    Virtualization: kvm
  Operating System: CentOS Linux 7 (Core)
       CPE OS Name: cpe:/o:centos:centos:7
            Kernel: Linux 3.10.0-514.21.1.el7.x86_64
      Architecture: x86-64
[root@56-201 home]# uname  -a 
Linux 56-201 3.10.0-514.21.1.el7.x86_64 #1 SMP Thu May 25 17:04:51 UTC 2017 x86_64 x86_64 x86_64 GNU/Linux
[root@56-201 home]# ip a 
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN qlen 1
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
    inet 127.0.0.1/8 scope host lo
       valid_lft forever preferred_lft forever
    inet6 ::1/128 scope host 
       valid_lft forever preferred_lft forever
2: enp0s3: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP qlen 1000
    link/ether 08:00:27:0e:38:94 brd ff:ff:ff:ff:ff:ff
    inet 10.0.2.15/24 brd 10.0.2.255 scope global dynamic enp0s3
       valid_lft 73640sec preferred_lft 73640sec
    inet6 fe80::2bb7:5b3:9584:d8eb/64 scope link 
       valid_lft forever preferred_lft forever
3: enp0s8: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP qlen 1000
    link/ether 08:00:27:bb:5d:54 brd ff:ff:ff:ff:ff:ff
    inet 192.168.56.201/24 brd 192.168.56.255 scope global enp0s8
       valid_lft forever preferred_lft forever
    inet6 fe80::a00:27ff:febb:5d54/64 scope link 
       valid_lft forever preferred_lft forever
4: virbr0: <NO-CARRIER,BROADCAST,MULTICAST,UP> mtu 1500 qdisc noqueue state DOWN qlen 1000
    link/ether 52:54:00:16:5e:11 brd ff:ff:ff:ff:ff:ff
    inet 192.168.122.1/24 brd 192.168.122.255 scope global virbr0
       valid_lft forever preferred_lft forever
5: virbr0-nic: <BROADCAST,MULTICAST> mtu 1500 qdisc pfifo_fast master virbr0 state DOWN qlen 1000
    link/ether 52:54:00:16:5e:11 brd ff:ff:ff:ff:ff:ff
[root@56-201 home]# 

目标

  • 创建一个监狱
  • 创建一个用户 jman
  • 只赋予 bash 和 tail 的执行能力给 jman

新建一个目录作为监狱

[root@56-201 home]# mkdir -p /home/jail
[root@56-201 home]# ll /home/jail/ -d 
drwxr-xr-x. 2 root root 6 7月  30 18:34 /home/jail/
[root@56-201 home]# 

新建一个用户 jman

[root@56-201 home]# useradd jman
[root@56-201 home]# passwd jman
Changing password for user jman.
New password: 
BAD PASSWORD: The password is shorter than 8 characters
Retype new password: 
passwd: all authentication tokens updated successfully.
[root@56-201 home]# ll /home/jman/ -d 
drwx------. 3 jman jman 78 7月  30 18:50 /home/jman/
[root@56-201 home]# ll /home/jman/ 
total 0
[root@56-201 home]# ll /home/jman/ -a
total 12
drwx------. 3 jman jman  78 7月  30 18:50 .
drwxr-xr-x. 6 root root  52 7月  30 18:50 ..
-rw-r--r--. 1 jman jman  18 12月  7 2016 .bash_logout
-rw-r--r--. 1 jman jman 193 12月  7 2016 .bash_profile
-rw-r--r--. 1 jman jman 231 12月  7 2016 .bashrc
drwxr-xr-x. 4 jman jman  39 6月  16 00:45 .mozilla
[root@56-201 home]#

jman 测试登录

[bolo@much ~]$ ssh jman@192.168.56.201
jman@192.168.56.201's password: 
[jman@56-201 ~]$

添加配置,将 jman 放入监狱

修改 sshd 配置

jman 将在通过认证后被投放到以 /home/jail 为根目录的监狱中

[root@56-201 home]# vim /etc/ssh/sshd_config 
[root@56-201 home]# tail -n 4 /etc/ssh/sshd_config

#move jman to jail dir /home/jail
Match User jman
ChrootDirectory /home/jail
[root@56-201 home]# systemctl restart sshd
[root@56-201 home]# echo $?
0
[root@56-201 home]# 

重启 sshd 服务后变更才生效


添加 bash 和 tail 命令到监狱中

命令底层依赖的库也一并要拷贝过去

[root@56-201 home]# ldd /bin/bash
	linux-vdso.so.1 =>  (0x00007ffca428a000)
	libtinfo.so.5 => /lib64/libtinfo.so.5 (0x00007f64c43fe000)
	libdl.so.2 => /lib64/libdl.so.2 (0x00007f64c41fa000)
	libc.so.6 => /lib64/libc.so.6 (0x00007f64c3e38000)
	/lib64/ld-linux-x86-64.so.2 (0x00007f64c463d000)
[root@56-201 home]# ldd /bin/tail
	linux-vdso.so.1 =>  (0x00007ffc58fb6000)
	libc.so.6 => /lib64/libc.so.6 (0x00007fb441cdf000)
	/lib64/ld-linux-x86-64.so.2 (0x00007fb4420b5000)
[root@56-201 home]# mkdir -p /home/jail/bin/
[root@56-201 home]# mkdir -p /home/jail/lib64/
[root@56-201 home]# cp /lib64/libtinfo.so.5  /lib64/libdl.so.2   /lib64/libc.so.6 /lib64/ld-linux-x86-64.so.2  /home/jail/lib64/
[root@56-201 home]# cp /bin/bash /bin/tail /home/jail/bin/
[root@56-201 home]# ll /home/jail/
total 0
drwxr-xr-x. 2 root root 30 7月  30 19:04 bin
drwxr-xr-x. 2 root root 90 7月  30 19:03 lib64
[root@56-201 home]# tree /home/jail/
/home/jail/
├── bin
│   ├── bash
│   └── tail
└── lib64
    ├── ld-linux-x86-64.so.2
    ├── libc.so.6
    ├── libdl.so.2
    └── libtinfo.so.5

2 directories, 6 files
[root@56-201 home]# 

Note: 必须加上 bash ,否则 jman 没法登录,这个是由 /etc/passwd 配置的

[root@56-201 jail]# tail -n2 /etc/passwd
cc:x:1001:1001::/home/cc:/bin/bash
jman:x:1002:1002::/home/jman:/bin/bash
[root@56-201 jail]# 

Note: 如果不加上 bash 会如何呢

[bolo@much ~]$ ssh jman@192.168.56.201
jman@192.168.56.201's password: 
Last login: Sun Jul 30 18:52:17 2017 from 192.168.56.202
Could not chdir to home directory /home/jman: No such file or directory
/bin/bash: No such file or directory
Connection to 192.168.56.201 closed.
[bolo@much ~]$

在认证通过后由于没有 /bin/bash,无法获得终端,于是被关闭了连接


登录测试 tail 命令

创建一个用于测试的文本

[root@56-201 home]# cd jail/
[root@56-201 jail]# ls
bin  lib64
[root@56-201 jail]# vim  abc
[root@56-201 jail]# cat abc 
1
2
3
4
5
[root@56-201 jail]# 

远程登录,测试 tail 命令

[bolo@much ~]$ ssh jman@192.168.56.201
jman@192.168.56.201's password: 
Last login: Sun Jul 30 18:59:33 2017 from 192.168.56.202
Could not chdir to home directory /home/jman: No such file or directory
-bash-4.2$ /bin/tail -n 2 abc 
4
5
-bash-4.2$

从结果来看,达到了预期

Tip: 为什么可以登录了,还是有 Could not chdir to home directory /home/jman: No such file or directory 的报错信息呢

那时因为,认证通过后就被 chroot 到了 /home/jail 之下,这时 /home/jail 在新的视野里就是 / ,而这里是没有 /home/jman 的,也就是 /home/jail/home/jman,所以会报错

Tip: 为什么要使用 /bin/tail ,可以直接使用 tail

不行,因为目前 jman 的处境是除了身在监狱的 / 中,没有任何环境变量给自己指引

-bash-4.2$ /bin/tail -n 2 abc 
4
5
-bash-4.2$ tail -n 2 abc      
-bash: tail: command not found
-bash-4.2$ 

不加上绝对路径,它是找不到北的,于是提示找不到命令

这时的 jman 被困在了 /home/jail/ 中,并且几乎没有任何权限,对系统也很难造成威胁

-bash-4.2$ pwd
/
-bash-4.2$ echo abc
abc
-bash-4.2$ ls
-bash: ls: command not found
-bash-4.2$ top
-bash: top: command not found
-bash-4.2$ ps
-bash: ps: command not found
-bash-4.2$ ip a 
-bash: ip: command not found
-bash-4.2$ echo def
def
-bash-4.2$

达到了预设的效果

这个能有什么用呢,tail 只是一个 demo 应用,其它应用也可以使用同样的逻辑来限制其潜在的风险

基于这个技术,后面来个好玩的,可以实现文本终端的同屏


命令汇总

  • mkdir -p /home/jail
  • useradd jman
  • passwd jman
  • ssh jman@192.168.56.201
  • vim /etc/ssh/sshd_config
  • tail -n 4 /etc/ssh/sshd_config
  • systemctl restart sshd
  • ldd /bin/bash
  • ldd /bin/tail
  • mkdir -p /home/jail/bin/
  • mkdir -p /home/jail/lib64/
  • cp /lib64/libtinfo.so.5 /lib64/libdl.so.2 /lib64/libc.so.6 /lib64/ld-linux-x86-64.so.2 /home/jail/lib64/
  • cp /bin/bash /bin/tail /home/jail/bin/
  • tree /home/jail/
  • tail -n2 /etc/passwd
  • vim abc
  • cat abc
  • ssh jman@192.168.56.201
原文地址 http://soft.dog/2017/07/30/chroot/

类似博客

评论