Linux配置Chroot监狱限制用户访问
配置SFTP的ChrootDirectory时,权限和所有权是绕不开的核心。很多人配置后连接断开,报“Couldn't read packet: Connection reset by peer”,或者看似登录成功却能执行cd ..逃出限制,问题往往就出在几个硬性条件没满足。 ChrootDirec
配置SFTP的ChrootDirectory时,权限和所有权是绕不开的核心。很多人配置后连接断开,报“Couldn't read packet: Connection reset by peer”,或者看似登录成功却能执行cd ..逃出限制,问题往往就出在几个硬性条件没满足。

ChrootDirectory 配置必须满足的三个硬性条件
简单来说,不满足这三点,ChrootDirectory 就等于没配。核心要求都卡在权限和所有权上:
ChrootDirectory必须满足三个硬性条件:目录及其所有父路径须root所有且非root不可写,目录权限为755,且仅能配合internal-sftp子系统使用。
具体拆解一下:
首先,ChrootDirectory 指定的目录(例如 /home/sftpuser)必须由 root 用户所有,并且组和其他用户不可写。这通常意味着执行 chown root:root /home/sftpuser 加上 chmod 755 /home/sftpuser。
其次,该目录的所有父路径(一直追溯到根目录 /)也必须对非 root 用户不可写。一个常见的坑是,有人把 /home 目录权限设成了 777,这会导致整个 chroot 机制失效。
最后,如果用户需要在 chroot 环境内写入文件,不能在 ChrootDirectory 指定的根目录下直接操作。正确做法是在其内部创建子目录(比如 /home/sftpuser/upload),然后将这个子目录的所有权交给对应用户,例如 chown sftpuser:sftpuser /home/sftpuser/upload。
为什么 root 用户不能直接用 ChrootDirectory?
OpenSSH 的设计明确禁止对 root 用户启用 ChrootDirectory。即使你在配置里强行加上,sshd 服务在启动时也会静默忽略这条规则,或者直接启动失败,报错“Bad configuration option: ChrootDirectory”。
这并非程序缺陷,而是出于安全考虑的设计——因为 chroot 环境对拥有 root 权限的用户来说形同虚设,内核允许 root 用户从这种“监狱”中逃逸。在实际操作中,应该遵循以下原则:
绝对不要使用 root 账户进行 SFTP 操作。正确的做法是创建专用的低权限用户,例如执行 useradd -m -s /usr/bin/false sftp-deploy。
如果某些业务操作确实需要更高权限,应该通过配置 sudo 命令的白名单来精确控制,而不是开放整个文件系统的访问视图。
务必检查 /etc/ssh/sshd_config 配置文件,看是否存在 Match User root 这样的配置块。如果存在,必须删除或注释掉其中与 ChrootDirectory 相关的行。
internal-sftp 和传统 sftp-server 的关键区别
选错了 SFTP 子系统,chroot 同样不会生效。这里必须使用 internal-sftp,而不能使用传统的外部二进制文件(例如 /usr/libexec/openssh/sftp-server)。
原因在于:internal-sftp 是 SSH 守护进程(sshd)内置的功能模块,它能够与 ChrootDirectory 指令协同工作,完成路径的重绑定。而外部的 sftp-server 进程在启动时已经脱离了 sshd 的上下文环境,因此无法感知到 chroot 的设置。
配置时需要注意这几个要点:
在配置文件中,全局范围通常只保留一行 Subsystem sftp internal-sftp,并删除或注释掉所有其他定义 SFTP 子系统的行。
在针对特定用户的 Match User xxx 配置块里,必须显式地写上 ForceCommand internal-sftp。否则,用户仍然有可能通过获取一个普通的 SSH shell 来绕过文件访问限制。
避免在该 Match 块中添加 AllowTcpForwarding yes 或 X11Forwarding yes 这类选项,它们会削弱隔离的效果。
调试时最该看的三处日志和现象
配置完成后重启 sshd 服务却连接不上?先别急着反复修改配置,按照顺序排查以下三个地方,能更快定位问题:
如果客户端直接报“Connection closed”或没有任何提示就退出,应该立刻查看系统日志。使用命令 journalctl -u sshd -n 50 -f 追踪最新日志,其中大约90%的情况是 ChrootDirectory 目录权限设置错误,日志里通常会明确记录“fatal: bad ownership or modes for chroot directory component”。
如果能登录,但执行文件操作时提示“Couldn't stat remote file: Permission denied”,这说明 chroot 目录内部的子目录权限没设对。检查命令 ls -ld /home/sftpuser/upload 的输出,确认该目录是否属于目标用户并且可读写。
使用 sftp -v user@host 命令进行详细模式连接,观察连接协商阶段是否出现了“subsystem: sftp”和“chroot to /home/sftpuser”这样的字样。如果没有这两条关键信息,说明你的配置根本没有被成功匹配和应用。
说到底,chroot 环境的脆弱性往往不在于配置语法本身,而在于从根目录到目标目录这条路径上所有权链的完整性。少执行一个 chown root,就等于在监狱的围墙上留下了一扇没上锁的窗。
