modified | Thursday 1 May 2025 |
---|
Saturday, June 26, 2021 at 10:19
Linux 中 的 chroot 命 令
Jasonkay
张 小 凯 的 博 客
在 Linux 中 提 供 了 chroot 命 令 用 于 将 根 目 录 换 成 指 定 的 目 的 目 录 , 从 而
达 到 了 与 原 系 统 隔 离 的 目 的 ;
本 文 介 绍 了 Linux 中 的 chroot 命 令 ;
Linux 中 的 chroot 命 令
一
命 令 介 绍
chroot 命 令 用 来 在 指 定 的 根 目 录 下 运 行 指 令 , 即 : change root
directory “( 更 改 root 目 录 ) ;
chroot 最 早 是 作 为 系 统 调 用 引 入 1979 年 的 Unix V7 系 统 , 目 的 是 为
了 将 当 前 进 程 及 其 子 进 程 的 root 目 录 重 定 向 到 某 个 指 定 目 录 ;
1982 年 ,chroot 功 能 被 加 入 到 BSD 中 , 后 经 20 多 年 ,FreeBSD 团
沥 皎 i 在 原 本 的 chroot 机 制 上 , 开 发 了 新 的 jail
在 linux 系 统 中 , 系 统 默 认 的 目 录 结 构 都 是 以 /, 即 是 以 根 (root) 开 始
而 在 使 用 chroot 之 后 , 系 统 的 目 录 结 构 将 以 指 定 的 位 置 作 为 / 位 置 ;
ly
而 在 使 用 chroot 之 后 , 系 统 的 目 录 结 构 将 以 指 定 的 位 置 作 为 / 位 置 ;
在 经 过 chroot 命 令 之 后 , 系 统 读 取 到 的 目 录 和 文 件 将 不 在 是 旧 系 统 根
下 的 而 是 新 根 下 ( 即 被 指 定 的 新 的 位 置 ) 的 目 录 结 构 和 文 件 ;
简 单 来 说 :
二 个 正 在 运 行 的 进 程 经 过 chroot 操 作 后 , 其 根 目 录 将 被 显 式 映 射 为
E 它 将 不 能 够 对 该 指 定 目 录 之 外 的 文 件 进 行 访 问 动
这 是 一 种 非 常 简 单 的 资 源 隔 离 化 操 作 , 类 似 于 现 在 Linux 的 Mount
Namespace 功 能 ;
当 年 Docker 刚 开 源 的 时 候 , 有 个 人 就 利 用 Linux 下 chroot 命 令 , 用
100 多 行 的 Bash 代 码 实 现 了 一 个 模 拟 版 的 Docker;
因 此 它 带 来 的 好 处 大 致 有 以 下 3 个 :
。 增 加 系 统 的 安 全 性 , 限 制 用 户 的 权 力 ;
在 经 过 chroot 之 后 , 在 新 根 下 将 访 问 不 到 旧 系 统 的 根 目 录 结 构 和 文
件 , 这 样 就 增 强 了 系 统 的 安 全 性 ;
这 个 一 般 是 在 登 录 (login) 前 使 用 chroot, 以 此 达 到 用 户 不 能 访 问 一 些
特 定 的 文 件 ;
。 建 立 一 个 与 原 系 统 隔 离 的 系 统 目 录 结 构 , 方 便 用 户 的 开 发 ;
使 用 chroot 后 , 系 统 读 取 的 是 新 根 下 的 目 录 和 文 件 , 这 是 一 个 与 原 系
统 根 下 文 件 不 相 关 的 目 录 结 构 ;
坂 政 个 新 的 环 情 中 “ 可 I 田 来 测 评 妮 位 的 豁 太 绳 诶 I/ 乃 一 此 与 丞 统 不 相
使 用 chroot 后 , 系 统 读 取 的 是 新 根 下 的 目 录 和 文 件 , 这 是 一 个 与 原 系
统 根 下 文 件 不 柏 关 的 目 录 结 构 ;
在 这 个 新 的 环 境 中 , 可 以 用 来 测 试 软 件 的 静 态 编 译 以 及 一 些 与 系 统 不 相
关 的 独 立 开 发 ;
。 切 换 系 统 的 根 目 录 位 置 , 引 导 Linux 系 统 启 动 以 及 急 救 系 统 等 ;
chroot 的 作 用 就 是 切 换 系 统 的 根 位 置 , 而 这 个 作 用 最 为 明 显 的 是 在 系
统 初 始 引 导 磁 盘 的 处 理 过 程 中 使 用 , 从 初 始 RAM 磁 盘 (initrd) 切 换 系 统
的 根 位 置 并 执 行 真 正 的 init;
另 外 , 当 系 统 出 现 一 些 问 题 时 , 我 们 也 可 以 使 用 chroot 来 切 换 到 一 个
临 时 的 系 统 ;
使 用 场 景
如 果 一 个 进 程 / 命 令 运 行 在 一 个 不 能 访 问 外 部 根 目 录 文 件 的 已 修 改 环 境
中 , 这 种 修 改 环 境 通 常 被 称 为 监 禁 目 录 (jail1) 或 是 chroot 监 禁 , 只 有
特 权 进 程 和 根 用 户 才 能 使 用 chroot 命 令 :
这 通 常 是 很 有 用 的 :
. 将 特 权 分 配 给 无 特 权 的 进 程 , 例 如 Web 服 务 或 DNS 服 务 ;
建 立 测 试 环
不 使 程 序 或 系 统 崩 溃 下 , 运 行 旧 程 序 或 ABI 兼 容 的 程 序 ;
系 统 恢 复
, 重 新 安 装 引 导 装 载 程 座 , 例 如 Grub 或 Lilo;
密 码 找 回 , 重 置 一 个 已 姑 失 的 密 码 等 ;
网 纠 一 的 日 一
人 、 人 、 工 >
如 果 一 个 进 程 / 命 忧 运 行 在 一 个 不 能 访 问 外 部 根 目 录 文 件 的 已 修 改 环 境
中 , 这 种 修 改 环 境 通 常 被 称 为 监 禁 目 录 (jail1) 或 是 chroot 监 禁 , 只 有
特 权 进 程 和 根 用 户 才 能 使 用 chroot 命 令 ;
这 通 常 是 很 有 用 的 :
3; 不 使 程 序 或 系 统 崩 溃 下 , 运 行 旧 程 序 或 ABI 兼 容 的 程 序 ;
4「 系 统 恢 复
5, 里 新 安 装 引 导 装 载 程 座 , 例 如 Grub 或 Lilo;
6, 密 码 找 问 , 重 置 一 个 已 如 失 的 密 码 等 ;
命 令 语 法
在 现 今 的 Linux 上 ,chroot 既 是 一 个 CLI 工 具 (chroot(8)) , 又 是 一
个 系 统 调 用 (chroot(21 ) ;
命 令 语 法 如 下 :
chroot [O0PTION] NENROOT [COMMAND _[ARGS] . . . ] 汀 例 如 : chroot
/path/to/new/root command# 或 chroot /path/to/new/root
/path/to/server# 或 chroot [options] /path/to/new/root
/path/to/server# 选 项 –userspec=USER:GROUP “ 水 使 用 指 定 的 用 户 和
组 (ID 或 名 称 )–groups=G_LIST 汀 指 定 补 充 组 gl,g2, .. 「gN –
help 汀 显 示 帮 助 并 退 出 –version “ 永 显 示 版 本 信 息 并 退 出
。 目 录 (dir) : 指 定 新 的 根 目 录 ;
。 指 令 (command): 指 定 要 执 行 的 指 令 ;
COMMAND 指 的 是 切 换 root 目 录 后 需 要 执 行 的 命 令 , 如 果 没 有 指 定 ,
默 认 是 ${sHgLL} -i, 大 部 分 情 况 是 /bin/bash;
在 现 今 的 Linux 上 , chroot 既 是 一 个 CLI 工 具 (chroot(8)) , 又 是 一
个 系 统 调 用 (cthroot(2)) ;
命 令 语 法 如 下 :
chroot [O0PTION] NENROOT [COMMAND [ARGS] . . . ]# 例 如 : chroot
/path/to/new/root command# 或 chroot /path/to/new/root
/path/to/server# 或 chroot [options] /path/to/new/root
/path/to/server# 选 项 –userspec=USER:GROUP “ 水 使 用 指 定 的 用 户 和
组 (ID 或 名 称 ) - aronpa- =G_LIST 汀 指 定 补 充 组 gl,g2, .. 「gN –
he1Lp 江 显 示 帮 助 并 退 出 –version “ 水 显 示 版 本 信 息 并 退 出
。 相 录 (dir) : 指 定 新 的 根 目 录 ;
。 指 令 (command): 指 定 要 执 行 的 指 令 ;
COMMAND 指 的 是 切 换 root 目 录 后 需 要 执 行 的 命 令 , 如 果 没 有 指 定 ,
默 认 是 ${sSHELL} -i, 大 部 分 情 况 是 /bin/bash;
此 外 , 执 行 chroot(8 ) 需 要 使 用 root 权 限 ;
例 如 , 简 单 地 , 我 们 可 以 这 样 使 用 :
$ sudo chroot _/path/to/new/root /bin/bash
下 面 就 让 我 们 来 建 造 我 们 的 监 狱 (jai) ;
使 用 案 例 : Jail
创 建 对 应 的 新 的 根 目 录 :
\( J=\)
HOME/jail\( mkdir -p $J\)
mkdir -p $J/{bin, 1ib/x86_64-1inux-
gnu 1ib64,etc,Var}
创 建 对 应 的 新 的 根 目 录 :
\( J=\)
HOME/jail\( mkdir -p $J\)
mkdir -p $J/{bin, 1ib/x86_64-1inux-
gnu 1ib64,etc,Var}
将 几 个 必 要 的 命 令 工 具 copy 到 bin/ 下 :
\(sudo cp -vf /bin/{bash, 1s}\) J/bin
将 步 骤 2 中 可 执 行 命 令 依 赖 的 动 态 库 copy 到 jail/ 下 :
\( 1ist=“Ldd /bin/ls | egrep -o“/1ib.*v.[0-9]““\)
for i in
\(1ist; do sudo cp -vf \)
i \(J/\)
i; done\( 1ist=“1Ldd /bin/bash | egrep -o0“/1ib.*v.[0-9]““\)
for i in \(lList; do sudo cp \)
i -vf
\(J/\)
i; done
执 行 chroot 命 令 :
\(sudo chroot\)
J /bin/bashbash-4.3 汀 1sbin _etc 1Lib “1Lib64
varbash-4.3 水 cd /bash-4.3 汀 Lsbin _etc Lib Lib64 “varbash-4 . 3 汀
CQ ..bash-4.3 沥 LsSbin _etc Lib Lib64 Var
可 以 看 到 无 论 我 们 如 何 改 变 目 录 , 其 根 目 录 都 被 隔 离 在 $J 中 ;
执 行 exit 命 令 可 退 出 这 一 环 境 ;
使 用 chroot ( 心 ) 系 统 调 用
巳
chroot(2) 的 原 型 是 :
include <unistd.h>int chroot(const char *path) ;
hr»+ y 封 调 田 讽 程 乃 苑 子 讽 程 的 根 日 咤 拳 宋 为 nath *
chroot(2) 的 原 型 是 :
include <unistd.h>int chroot(const char *path) ;
chroot ( ) 将 调 用 进 程 及 其 子 进 程 的 根 目 录 指 定 为 path:;
同 样 的 , 执 行 该 调 用 需 要 使 用 root 权 限 ;
如 以 下 代 码 所 示 :
test_chroot.c
incLlude <stdio.h>incLlude <error .h>incLlude <unistd.h>incL1ude
<stdlib.h>char *const path =“/root/jail“; // 如 上 文 实 验 所 述 目 录
char x*const argv[] = {“/bin/bash“,NULL};int main(void) t E
(chroot(path) != 0) 《 perror (“chroot error“) ;
exit(1) ; } shaiz( 7 / 忽 略 返 回 值
execvp(“/bin/bash“ , argVv) ; / 忽 略 返 回 值 return 01 】
编 译 和 运 行 代 码 :
\( gcc test_chroot.c -o test_chroot\)
./test_chroot 汀 非 root 用 户
执 行 命 令 chroot error: 0peration not permitted$s sudo
./test_chrootbash-4 . 3 江
查 找 服 务 是 否 存 在 于 chrooted 监 禁
可 通 过 查 看 进 程 的 /proc/
如 上 文 , 其 chroot 下 bash 的 执 行 进 程 为 15768, 则 有 :
$ sudo L1s8 -1Q /BProc/15768/ZrootLrwxrwXrWx 1 root Foot 0 RAPF 17
17975073 3 F
可 通 过 查 看 进 程 的 /proc/
监 禁 中 :;
T 7T 》
如 上 文 , 其 chroot 下 bash 的 执 行 进 程 为 15768, 则 有 :
$ sudo L1s8 -1LQd /proc/15768/rootlrwxrwxrwx 1 root root 0 ARpr 17
22:47 /proc/15768/root -> /root/jail
可 见 其 根 目 录 已 经 被 修 改 为 /xoot/jail;
在 Linux 和 类 Unix 系 统 下 chroot 应 用 程 序 的 注 意 事 项
从 上 面 的 例 子 看 出 ,chroot 是 相 当 简 单 的 , 但 是 最 终 可 能 出 现 几 种 不
同 的 问 题 而 结 束 , 例 如 :
。 在 jail 中 缺 失 库 文 件 可 能 直 接 导 致 jail 崩 溃 ;
。 二 些 复 杂 的 程 序 不 好 被 chrooti _ _
。 正 在 运 行 某 一 程 序 的 jail 不 能 冒 运 行 其 他 程 序 , 不 能 更 改 任 何 文
件 , 也 不 能 “ 假 设 “ 另 一 个 用 户 的 身 份 ; 放 宽 这 些 限 制 , 会 降 低 你
的 安 全 性 , 请 根 据 具 体 情 况 使 用 Chroot;
因 此 要 么 尝 试 真 正 的 jail, 例 如 : FreeBSD 提 供 的 , 要 么 用 虚 拟 化 解
决 , 比 如 Linux 下 的 KVM;
还 要 注 意 :
. 当 你 升 级 本 地 程 序 时 , 不 要 忘 记 升 级 已 chroot 的 程 序 ;
. 并 非 所 有 程 序 能 够 或 者 应 该 被 chroot;
. 任 何 需 要 root 权 限 操 作 的 程 序 , 对 其 chroot 是 没 意 义 的 , 因 为
通 常 root 用 户 都 能 脱 离 chroot;
. Chropt 并 不 一 个 高 招 ; 更 多 的 可 以 学 习 如 何 保 护 和 加 强 系 统 的 各
一 〇 K 一
从 上 面 的 例 子 看 出 ,chroot 是 相 当 简 单 的 , 但 是 最 终 可 能 出 现 几 种 不
同 的 问 题 而 结 束 , 例 如 :
。 在 jail 中 缺 失 库 文 件 可 能 直 接 导 致 jail 崩 湟 ;
。 二 些 复 杂 的 程 序 不 好 被 chroot; “
。 正 在 运 行 某 一 程 序 的 jail 不 能 再 运 行 其 他 程 序 , 不 能 更 改 任 何 文
件 , 也 不 能 “ 假 设 “ 另 一 个 用 户 的 身 份 ; 放 宽 这 些 限 制 , 会 降 低 你
的 安 全 性 , 请 根 据 具 体 情 况 使 用 Chroot;
因 此 要 么 尝 试 真 正 的 jail, 例 如 : FreeBSD 提 供 的 , 要 么 用 虚 拟 化 解
决 , 比 如 Linux 下 的 KVM;
还 要 注 意 :
. 当 你 升 级 本 地 程 序 时 , 不 要 忘 记 升 级 已 chroot 的 程 序 ;
. 并 非 所 有 程 序 能 够 或 者 应 该 被 chroot;
. 任 何 需 要 root 权 限 操 作 的 程 序 , 对 其 chroot 是 没 意 义 的 , 因 为
通 常 root 用 户 都 能 脱 离 chroot;
. f 个 高 招 ; 更 多 的 可 以 学 习 如 何 保 护 和 加 强 系 统 的 各
工 口
一 〇 K 一
chroot 的 安 全 问 题 :
chroot 机 制 从 一 开 始 就 并 非 安 全 , 存 在 很 多 安 全 漏 洞 , 有 不 少 1 越
狱 」 (jailbreak) 的 手 段 ;
附 录
文 章 参 考 :
chroot
a 一 FF 仓 仁 | 口