用户只能用sftp、不能ssh登录,核心在于禁用shell(设为/sbin/nologin)、启用internal-sftp子系统、配好chrootdirectory;三者缺一不可,且chroot路径须root属主、755权限,上级目录不可有组/其他写权限。

直接结论:用户只能用 SFTP、不能 SSH 登录,核心在于三件事——禁用 Shell、启用 internal-sftp、配好 ChrootDirectory。缺一不可,任一环节权限或路径不对,连接会直接被拒绝或报 Write failed: Broken pipe。
为什么 /sbin/nologin 不能只靠改 Shell?
仅把用户 Shell 设为 /sbin/nologin 或 /bin/false,只能阻止 SSH 登录,但默认仍允许该用户走完整 SSH 协议栈(包括执行命令、端口转发等),SFTP 客户端可能连上后立刻断开,或出现 Connection closed by foreign host。
- 必须配合
ForceCommand internal-sftp,强制所有会话只运行 SFTP 子系统 -
AllowTcpForwarding no和X11Forwarding no要显式关闭,否则部分旧版 OpenSSH 仍可能绕过限制 - 如果用了
Match Group xxx,确保用户确实属于该组(id sftpuser可验证)
ChrootDirectory 权限为什么总报错?
OpenSSH 对 chroot 路径有硬性要求:从 ChrootDirectory 往上直到 / 的每一级目录,属主必须是 root,且**不能有 group 或 other 写权限**。哪怕 /sftp/sftpuser 权限是 775,也会失败并记日志:fatal: bad ownership or modes for chroot directory component。
- 正确做法:
sudo chown root:root /sftp /sftp/sftpuser;sudo chmod 755 /sftp /sftp/sftpuser - 上传目录必须在 chroot 内部(如
/sftp/sftpuser/upload),且由用户自己拥有:sudo chown sftpuser:sftpusers /sftp/sftpuser/upload;sudo chmod 775 /sftp/sftpuser/upload - 路径中不能含符号链接,否则 SSH 直接拒绝启动 chroot
为什么重启 sshd 后还是连不上?
常见原因不是配置没生效,而是 OpenSSH 拒绝加载错误配置——它不会报错,只会静默回退到旧配置。最典型的是:
-
Subsystem sftp internal-sftp行被重复定义(比如既有旧的sftp-server,又加了internal-sftp),OpenSSH 只认第一个,后续 Match 规则失效 -
ChrootDirectory路径不存在,或属主/权限不满足要求,sshd -t测试时不会提示,但journalctl -u sshd里能看到 fatal 日志 - SELinux 启用时(CentOS/RHEL 默认开启),
/var/log/audit/audit.log里会有 avc denied 记录,需运行sudo setsebool -P ssh_chroot_rw_on 1或临时设为 permissive
真正卡住的地方往往不是“怎么配”,而是 chroot 路径的 owner 和权限链、以及 sshd_config 里 Subsystem 和 Match 的顺序冲突。改完务必跑一次 sudo sshd -t 验证语法,再看 sudo journalctl -u sshd -n 20 --no-pager 确认有没有 fatal 级报错。











