chroot本质是通过切换进程根目录实现文件系统级隔离,需手动构建含bin/lib/etc/dev等的最小根环境,复制服务程序及全部依赖库,并以root权限调用chroot命令启动;它不隔离网络或进程,仅限文件路径视图限制。

chroot 本身不直接“限制服务进程”,而是通过构造一个隔离的文件系统视图,让服务在启动时运行于该受限根目录下。真正实现服务级 chroot 隔离,关键在于:服务必须由 root 启动、其二进制和全部依赖需完整复制到新根目录、且启动路径需显式指向 chroot 环境中的程序。它不是后台守护进程的动态挂起,而是一次性切换根路径后执行。
准备 chroot 监狱目录结构
目标目录(如 /var/chroot/nginx)必须模拟最小 Linux 根环境:
- 创建必要子目录:bin/、lib/、lib64/(x86_64)、etc/、usr/、dev/(可选,仅当服务需访问 /dev/null、/dev/random 等)
- 复制服务主程序及其依赖库:用 ldd /usr/sbin/nginx 查出所有 .so 路径,再逐个 cp -L 拷贝到对应 lib/ 目录
- 复制配置文件(如 nginx.conf)、证书、静态资源等所需文件到对应位置(如 /var/chroot/nginx/etc/nginx/)
- 确保 /var/chroot/nginx/dev/{null,zero,random,tty} 存在(可用 mknod 创建,权限设为 666)
以 chroot 方式启动服务
不能直接 systemctl start nginx;必须绕过原系统服务管理,手动在 jail 中拉起:
- 使用 sudo chroot /var/chroot/nginx /usr/sbin/nginx -c /etc/nginx/nginx.conf -g "daemon off;"
- 若需后台运行,可配合 nohup 或 systemd 的 ExecStart= 指向 chroot 命令(但注意 PID 文件、日志路径也需在 jail 内)
- 推荐搭配 --userspec=nobody:nogroup 降权运行,避免 root 权限逃逸风险
针对 SSH/SFTP 用户的自动 chroot(最常用场景)
这不是靠 chroot 命令临时执行,而是由 OpenSSH 内置机制实现:
- 编辑 /etc/ssh/sshd_config,确保只保留:Subsystem sftp internal-sftp
- 添加匹配块:
Match User sftpuser
ChrootDirectory /home/sftpuser
ForceCommand internal-sftp
AllowTcpForwarding no
X11Forwarding no - /home/sftpuser 必须属 root:root、权限 755;其内需有 ./bin/bash(或 shell)和 ./etc/passwd(仅含该用户条目)等基本组件
- 重启 sshd:sudo systemctl restart sshd
注意事项与常见失败点
chroot 失败往往不是命令报错,而是服务启动后立即退出或无法响应:
- 缺失动态库是最常见原因——务必用 ldd 检查并完整拷贝,注意软链接是否被正确解析(加 -L 参数)
- chroot 后当前工作目录不变,建议启动前先 chdir("/")(脚本中可加 cd /)
- 未挂载虚拟文件系统(proc、sys、devpts)会导致 ps、ls 等命令异常,调试时可临时执行:mount -t proc proc /var/chroot/nginx/proc
- chroot 不隔离网络、进程、用户命名空间,仅限文件系统层面;高安全需求应升级至 systemd-nspawn 或容器方案


















