OpenSSH SFTP可通过internal-sftp内置子系统结合ChrootDirectory实现安全隔离;需修改sshd_config启用internal-sftp、禁用shell、设置严格权限(root所有且无组/其他写权),并确保chroot路径下有用户可写子目录。

OpenSSH 的 SFTP 子系统默认以内嵌方式运行(sftp-server 作为 sshd 的子进程),但也可配置为独立守护进程(internal-sftp 模式下通过 ForceCommand 启用),并结合 ChrootDirectory 实现用户目录禁锢(chroot jail)。这种组合能提升安全性,避免 shell 访问,限制用户仅能操作指定目录。
启用 internal-sftp 并禁用 shell 登录
修改 /etc/ssh/sshd_config,将 SFTP 切换为 OpenSSH 内置的 internal-sftp,不调用外部二进制文件:
- 注释或删除原有
Subsystem sftp /usr/lib/openssh/sftp-server行 - 添加:
Subsystem sftp internal-sftp - 对目标用户或用户组,禁用 shell 并强制进入 SFTP 模式,例如:
ChrootDirectory /srv/sftp/%u
ForceCommand internal-sftp
AllowTcpForwarding no
X11Forwarding no
PermitTTY no
配置 Chroot 目录权限与结构
chroot 要求严格权限控制,否则 sshd 会拒绝启动 SFTP 会话:
-
ChrootDirectory路径(如/srv/sftp/sftpuser)必须由 root 拥有,且不可被组/其他用户写入 - 该路径本身不能是用户主目录;通常需在其下创建
home或upload子目录供用户实际使用 - 示例结构与权限:
sudo chown root:root /srv/sftp/sftpuser
sudo chmod 755 /srv/sftp/sftpuser
sudo chown sftpuser:sftpuser /srv/sftp/sftpuser/home
sudo chmod 755 /srv/sftp/sftpuser/home
支持多用户统一 chroot 根目录
使用 %u(用户名)、%h(用户家目录)等通配符可批量管理:
-
ChrootDirectory /srv/sftp/%u:每个用户隔离在独立子目录 -
ChrootDirectory /srv/sftp+Match Group sftponly:所有成员共用同一 chroot 根,需额外控制子目录访问(如 ACL 或 umask) - 注意:
%u路径必须存在且满足权限要求,建议用脚本批量创建
验证与排错要点
重启 sshd 后测试前,务必检查以下常见问题:
- 运行
sudo sshd -t验证配置语法正确 - 确保
/srv/sftp/xxx所有上级目录(如/srv、/srv/sftp)均为 root:root 且无写权限给组/其他 - SFTP 登录失败时查看
journalctl -u ssh或/var/log/auth.log,典型错误包括 “bad ownership or modes” 或 “fatal: bad ownership or modes on chroot directory” - 用户 UID/GID 必须真实存在,且
ChrootDirectory下至少包含一个用户可写的子目录(如home),否则登录后无法列目录










