必须为root:root且权限严格755,因openssh的internal-sftp在chroot时逐级校验路径所有权与权限,任一父目录非root所有或权限>755(如775)均触发“bad ownership or modes”错误并拒绝连接。

ChrootDirectory 权限必须严格为 root:root + 755
OpenSSH 的 internal-sftp 在启动 chroot 时会从根目录(/)开始逐级检查路径所有权和权限。只要 ChrootDirectory 或其任意父目录(比如 /home、/home/sftpuser)不是 root:root 所有,或权限 >755(如 775、750 带 sticky bit),sshd 就拒绝加载该配置,并在 journalctl -u sshd 中报错:fatal: bad ownership or modes for chroot directory component。
常见错误包括:
- 直接设
ChrootDirectory /home/sftpuser,但该目录属主是sftpuser—— 必须执行chown root:root /home/sftpuser -
/home/sftpuser权限是 775 或含 setgid —— 必须chmod 755 /home/sftpuser - 误把
/data/ftp当作 chroot 根,却忘了/data目录属主不是 root —— 运行ls -ld / /data /data/ftp确认每级都是root:root
用户 shell 必须设为 /sbin/nologin,不能用 /bin/false
仅靠 ForceCommand internal-sftp 无法阻止用户通过普通 SSH 登录并执行命令。如果用户 shell 是 /bin/bash 或 /bin/sh,ta 仍可 ssh user@host 进入交互式 shell,完全绕过 SFTP 限制。
正确做法是创建或修改用户时显式指定无登录 shell:
- 新建用户:
useradd -s /sbin/nologin sftpuser(CentOS/RHEL)或useradd -s /usr/sbin/nologin sftpuser(Debian/Ubuntu) - 已有用户:
usermod -s /sbin/nologin sftpuser - 绝对不要用
/bin/false或/bin/true—— 某些 OpenSSH 版本(尤其是 8.2 之前)会因此拒绝sftp登录,报错Connection closed
用户实际可写目录必须是 chroot 根下的子目录,且属主为该用户
ChrootDirectory 根目录本身(如 /home/sftpuser)必须由 root 拥有、不可写;否则 chroot 失败。但用户要上传文件,就得在它下面建一个可写子目录,并把属主交给用户本人。
例如:
Zynq‑7000 / Zynq UltraScale+ 硬件调试技能。适用于 Xilinx Zynq(Cortex‑A9/A53 + FPGA)Linux 环境,调试 I2C、I2S、UART、GPIO 等外设。包括设备树配置、内核驱动、用户空间调试工具、交叉编译和常见问题排查,支持 PetaLinux 开发。
mkdir -p /home/sftpuser/uploadschown sftpuser:sftpgroup /home/sftpuser/uploads-
chmod 755 /home/sftpuser/uploads(或更严的 750)
注意:不能对 /home/sftpuser 执行 chown sftpuser:sftpgroup,否则 chroot 立即失效;也不能让 uploads 的父目录(即 /home/sftpuser)对用户可写。
sshd_config 配置必须禁用旧版 sftp-server,启用 internal-sftp
默认的 Subsystem sftp /usr/lib/openssh/sftp-server 不支持 chroot,必须替换为 internal-sftp,且 Match 块内必须包含 ForceCommand internal-sftp。
典型配置段(放在 /etc/ssh/sshd_config 末尾):
Subsystem sftp internal-sftp
Match Group sftpgroup
ChrootDirectory /home/%u
ForceCommand internal-sftp
AllowTcpForwarding no
X11Forwarding no
关键点:
- 注释掉原有
Subsystem行,只保留一条internal-sftp -
Match必须精确匹配用户或组,%u是用户名变量,%g是组名变量 - 改完务必运行
sshd -t验证语法,再systemctl restart sshd
chroot 路径里任何一环权限或属主出错,都会导致连接瞬间断开(Write failed: Broken pipe 或直接拒绝认证),而日志里往往只有一行 fatal 提示——排查时优先看 journalctl -u sshd -n 50,别只盯着客户端报错。










