必须将用户shell设为/sbin/nologin并配合forcecommand internal-sftp和chrootdirectory,因permittty no仅禁tty分配而不禁登录,真正禁shell需账户层(无效shell)、协议层(internal-sftp)与会话层(forcecommand等)协同。

PermitTTY no 本身不能“强行剥离”用户的 shell 权限,它只是禁止分配伪终端(TTY),属于会话层面的限制,而非账户权限层面的禁用。真正禁用交互式 Shell 登录,必须配合用户 shell 设置(如 /sbin/nologin)和 ForceCommand 等机制。PermitTTY no 的作用是补位——在用户已具备合法登录能力的前提下,防止其获得交互式命令行环境。
PermitTTY no 的真实定位和生效前提
该指令仅在 SSH 认证成功、会话已建立后才起作用。它不阻止登录,也不影响 SFTP、SCP 或端口转发等非交互式功能。若用户 shell 是 /bin/bash 且未做其他限制,设置 PermitTTY no 后仍可通过 ssh user@host 打开连接(只是看不到 $ 提示符),并可能执行单行命令(如 ssh user@host ls),甚至某些绕过方式仍可触发 TTY 分配。
- PermitTTY no 必须写在 Match User 块内,否则全局生效,影响所有用户
- 它对 SFTP 用户无效——SFTP 本就不依赖 TTY,ForceCommand internal-sftp 才是关键
- 单独使用 PermitTTY no + PasswordAuthentication no 无法阻止密钥登录后的命令执行
针对自动化同步账号的完整防护链
以专用同步账号 sync-backup 为例,仅靠 PermitTTY no 远不够。需构建三层控制:
-
账户层:设 shell 为 /sbin/nologin,确保无合法登录入口
→ sudo usermod -s /sbin/nologin sync-backup -
协议层:在 sshd_config 中启用 internal-sftp 并强制接管
→ Subsystem sftp internal-sftp(注释掉旧的 sftp-server 行) -
会话层:Match User 段中组合使用
→ Match User sync-backup
→ ForceCommand internal-sftp
→ PermitTTY no
→ AllowTcpForwarding no
→ X11Forwarding no
为什么 ChrootDirectory 和目录权限是硬性门槛
OpenSSH 对 internal-sftp + ChrootDirectory 的校验极其严格:/sftp/sync-backup 目录本身必须由 root 拥有、权限为 755,且所有上级路径(如 /sftp)也必须满足同样条件。一旦 /sftp/sync-backup 属主是 sync-backup 或权限含 w(如 775),sshd 将直接拒绝该用户连接,并在 /var/log/auth.log 中记录 “bad ownership or modes for chroot directory”。
- 正确设置:
sudo mkdir -p /sftp/sync-backup
sudo chown root:root /sftp/sync-backup
sudo chmod 755 /sftp/sync-backup - 可写子目录(如 upload)可归 sync-backup 所有,但父级 chroot 路径绝不可以
验证是否真正生效
测试不是看能不能连上,而是看连上后能做什么:
- ssh sync-backup@localhost → 应立即退出或进入 sftp> 提示符(非 $),且无法执行任何 bash 命令
- sftp sync-backup@localhost → 应正常进入 sftp 会话,可 ls、put、get
- scp file sync-backup@localhost:/upload/ → 应成功传输(SCP 复用 SFTP 子系统)
- 查看日志:sudo grep sync-backup /var/log/auth.log,确认无 “session opened” 类型记录,只有 “subsystem request for sftp”











