# Linux chroot 环境：原理与应用详解
Date: 2024-12-08


### **深入理解 Linux `chroot`：从原理到实战**

在 Linux 系统管理中，`chroot` 可以通过改变程序的根目录来实现文件系统的隔离。在本文中，我们将详细介绍 `chroot` 的原理，并通过一个模拟 Postfix 调用 SASL 的实战演示，帮助你掌握如何正确配置和验证 `chroot` 环境。

在一次smtp相关测试任务中， ubuntu虚拟机中搭建postfix服务器使用 sasl 中的密码验证方式使用 sasldb 报如下错误：

```
Sep 12 08:36:20 server postfix/smtpd[2384]: warning: SASL authentication failure: cannot connect to saslauthd server: No such file or directory
```

搜索到下面帖子：https://serverfault.com/questions/721925/postfix-smtpsaslauthd-autentication-failure，发现与chroot有关。

* * *

### **什么是 `chroot`？**

`chroot` 是 Linux 提供的一种文件系统隔离机制，全称为 **"change root"**，它允许我们将某个进程及其子进程的根目录 `/` 改变为指定的目录。在这个受限环境中，进程只能访问新的根目录中的资源，而无法接触到系统其他部分。

* * *

### **`chroot` 的应用场景**

1. **安全隔离：**
    
    - 限制进程访问系统文件，提高安全性。例如，运行 Postfix 等服务时，将其置于 `chroot` 环境中，防止潜在的漏洞被利用。
2. **测试和调试：**
    
    - 模拟不同的系统环境，调试服务或运行实验，而不会影响主系统。
3. **系统修复：**
    
    - 使用 `chroot` 进入受损系统进行修复操作。
4. **简化依赖：**
    
    - 将服务依赖的文件与主系统隔离，便于管理和迁移。

* * *

### **`chroot` 实战：搭建模拟环境**

以下是一个以 `Postfix` 调用 `SASL` 为例的 `chroot` 配置实战，帮助我们验证服务在隔离环境中的运行。

* * *

#### **1\. 创建 `chroot` 环境目录**

在 `/tmp` 下创建一个 `chroot` 目录，模拟服务运行环境：

```bash
sudo mkdir -p /tmp/chroot-demo/{bin,etc,lib,lib64,var/run}
sudo mkdir -p /tmp/chroot-demo/var/run/saslauthd
```

`/var/run/saslauthd` 模拟了 Postfix 中 `saslauthd` 的套接字路径。

* * *

#### **2\. 准备必要的程序和资源**

为了运行一个简单的程序（如 `bash`），我们需要复制二进制文件及其依赖库到 `chroot` 环境。

- **查找 `bash` 的依赖库**：

```bash
ldd /bin/bash
```

输出：

```
linux-vdso.so.1 (0x00007ffc5f7d1000)
libtinfo.so.6 => /lib64/libtinfo.so.6 (0x00007fe3865d5000)
libdl.so.2 => /lib64/libdl.so.2 (0x00007fe3865ce000)
libc.so.6 => /lib64/libc.so.6 (0x00007fe3863f2000)
/lib64/ld-linux-x86-64.so.2 (0x00007fe38673a000)
```

```bash
ldd /bin/ls
```

```
linux-vdso.so.1 (0x00007ffd75518000)
*libselinux.so.1 => /lib64/libselinux.so.1 (0x00007f5b6d00e000)
*libcap.so.2 => /lib64/libcap.so.2 (0x00007f5b6d004000)
libc.so.6 => /lib64/libc.so.6 (0x00007f5b6ce28000)
*libpcre2-8.so.0 => /lib64/libpcre2-8.so.0 (0x00007f5b6cd9c000)
libdl.so.2 => /lib64/libdl.so.2 (0x00007f5b6cd95000)
/lib64/ld-linux-x86-64.so.2 (0x00007f5b6d070000)
*libpthread.so.0 => /lib64/libpthread.so.0 (0x00007f5b6cd73000)
```

```bash
ldd /bin/realpath
```

```
linux-vdso.so.1 (0x00007ffd2017e000)
libc.so.6 => /lib64/libc.so.6 (0x00007f1a4debe000)
/lib64/ld-linux-x86-64.so.2 (0x00007f1a4e0b7000)
```

```bash
ldd /bin/touch
```

```
linux-vdso.so.1 (0x00007ffc7370b000)
libc.so.6 => /lib64/libc.so.6 (0x00007f505a21e000)
/lib64/ld-linux-x86-64.so.2 (0x00007f505a422000)
```

- **根据输出结果复制程序和依赖库到 `chroot` 环境**：

```bash
sudo cp /bin/touch /tmp/chroot-demo/bin
sudo cp /bin/realpath /tmp/chroot-demo/bin
sudo cp /bin/ls /tmp/chroot-demo/bin
sudo cp /bin/bash /tmp/chroot-demo/bin/
sudo cp /lib64/libtinfo.so.6 /tmp/chroot-demo/lib64/
sudo cp /lib64/libdl.so.2 /tmp/chroot-demo/lib64/
sudo cp /lib64/libc.so.6 /tmp/chroot-demo/lib64/
sudo cp /lib64/ld-linux-x86-64.so.2 /tmp/chroot-demo/lib64/
sudo cp /lib64/libselinux.so.1 /tmp/chroot-demo/lib64/
sudo cp /lib64/libcap.so.2 /tmp/chroot-demo/lib64/
sudo cp /lib64/libpcre2-8.so.0 /tmp/chroot-demo/lib64/
sudo cp /lib64/libpthread.so.0 /tmp/chroot-demo/lib64/
```

- **创建基本配置文件**：

```bash
sudo sh -c 'echo "root:x:0:0:root:/root:/bin/bash" > /tmp/chroot-demo/etc/passwd'
sudo sh -c 'echo "root:x:0:" > /tmp/chroot-demo/etc/group'
```

* * *

#### **3\. 模拟 `saslauthd` 的套接字**

创建一个模拟的套接字文件 `/var/run/saslauthd/mux`：

```bash
sudo touch /tmp/chroot-demo/var/run/saslauthd/mux
sudo chown root:root /tmp/chroot-demo/var/run/saslauthd/mux
sudo chmod 777 /tmp/chroot-demo/var/run/saslauthd/mux
```

套接字文件的权限确保任何进程都可以访问它。

* * *

#### **4\. 进入 `chroot` 环境**

使用 `chroot` 命令切换到新环境：

```bash
sudo chroot /tmp/chroot-demo /bin/bash
```

在 `chroot` 环境中，运行以下命令验证文件结构：

```bash
ls /
ls /var/run/saslauthd
exit
```

输出应类似：

```
bin etc lib lib64 var
mux
```

* * *

#### **5\. 验证服务调用**

创建一个简单的脚本，模拟服务对 `saslauthd` 套接字的访问： exit退出chroot

```bash
sudo sh -c 'echo -e "#!/bin/bash\necho Authentication successful via \$(realpath /var/run/saslauthd/mux)" > /tmp/chroot-demo/bin/auth_service.sh'
sudo chmod +x /tmp/chroot-demo/bin/auth_service.sh
```

在 `chroot` 环境中执行：

```bash
sudo chroot /tmp/chroot-demo /bin/bash
bin/auth_service.sh
```

输出：

```
Authentication successful via /var/run/saslauthd/mux
```

* * *

#### **6\. 文件系统隔离验证**

在 `chroot` 环境中创建一个文件：

```bash
sudo chroot /tmp/chroot-demo /bin/bash
touch /etc/testfile
ls /etc/
```

退出 `chroot` 后检查：

```bash
ls /etc/testfile
```

* * *

### **总结**

通过这次实战，我们完成了以下操作： 1. 创建了一个隔离的 `chroot` 环境。 2. 模拟了 `Postfix` 中 `saslauthd` 套接字的场景。 3. 验证了文件系统隔离的效果。

`chroot` 是一个轻量级的隔离工具，虽然不如容器技术（如 Docker）功能全面，但在许多场景中依然是高效且实用的选择。对于需要安全隔离或调试特定服务的情况，`chroot` 是一项不可忽视的技能。

 

图片from[**陳丁光**](https://www.facebook.com/groups/474930279315210/user/100010173011046/?__cft__[0]=AZU1BsxxcnSjavZU3on5dzOkxzi7ZSg8NqN40xLOiTMPHw2O6iG_aRqQLoGTc2lMLToXqf3-2dIvGQl7-HFYmFFi7S8iBI0zB1ZM-9ns0_6M19C5Gh63gt7BWarcOBJ85NDT99ND2cCcYtjnZwYf9f05RrBdLW81ZSXBK8NvCr9fVLFRqxZidwMoXwi_g9iiLwB3TiiD8UXC6k7IfwPbIqkv&__tn__=-UC%2CP-R)

