要实现SFTP chroot,需用OpenSSH internal-sftp子系统配合ChrootDirectory指令:chroot目录须root所有、权限755且不可被组/其他写入;用户真实家目录置于chroot内(如/sftp/user/home/user),并配置sshd_config中Match规则与ForceCommand。

要实现 SFTP 子系统权限限制和用户家目录禁锢(即 chroot),核心是使用 OpenSSH 内置的 internal-sftp 子系统配合 ChrootDirectory 指令,而非传统的 shell 登录方式。关键点在于:chroot 目录必须由 root 所有且不可被组/其他用户写入,同时需正确设置用户家目录结构与权限。
配置 SSH 使用 internal-sftp 并启用 chroot
编辑 /etc/ssh/sshd_config,禁用 shell 登录、指定 SFTP 子系统,并为特定用户或用户组设置 chroot:
- 确保全局启用 SFTP 子系统:
Subsystem sftp internal-sftp - 注释或删除旧的
Subsystem sftp /usr/lib/openssh/sftp-server行(避免冲突) - 在文件末尾添加匹配规则,例如限制
sftpuser用户:
Match User sftpuser
X11Forwarding no
AllowTcpForwarding no
PermitTTY no
ForceCommand internal-sftp
ChrootDirectory /sftp/%u
其中 %u 表示用户名,/sftp/sftpuser 将成为该用户的根目录。
准备 chroot 环境的目录结构与权限
chroot 目录(如 /sftp/sftpuser)必须满足严格权限要求,否则 SSH 会拒绝启动 SFTP 会话并报错 “bad ownership or modes”:
- chroot 目录本身必须由
root所有,且权限为755(即drwxr-xr-x) - 目录不能被组或其他用户写入(否则 SSH 拒绝进入)
- 用户真实家目录需放在 chroot 内部,例如:
/sftp/sftpuser/home/sftpuser,并设为该用户的 home - 执行
usermod -d /home/sftpuser sftpuser是无效的——实际生效的是 chroot 内的路径,所以应在 chroot 内创建/home/sftpuser,再通过ChrootDirectory隐式映射
创建受限用户并验证配置
创建无登录 shell 的 SFTP 专用用户:
- 添加用户:
sudo useradd -m -s /bin/false sftpuser - 设置密码:
sudo passwd sftpuser - 创建 chroot 根目录及内部家目录:
sudo mkdir -p /sftp/sftpuser/home/sftpusersudo chown root:root /sftp/sftpusersudo chmod 755 /sftp/sftpusersudo chown sftpuser:sftpuser /sftp/sftpuser/home/sftpuser - 重启服务:
sudo systemctl restart sshd - 测试连接:
sftp sftpuser@localhost,成功后应只能看到/home/sftpuser,无法跳出
进阶:按组统一管理多个 SFTP 用户
若需批量管控,可用 Group 匹配替代 User:
- 新建组:
sudo groupadd sftpusers - 将用户加入组:
sudo usermod -aG sftpusers sftpuser - 在
sshd_config中添加:
Match Group sftpusers
X11Forwarding no
AllowTcpForwarding no
PermitTTY no
ForceCommand internal-sftp
ChrootDirectory /sftp/%u
注意:仍需为每个用户单独创建符合权限要求的 /sftp/用户名 目录结构。也可用脚本批量初始化,但切勿放松 root:root 755 这一硬性约束。

















