ssh密钥的command选项限制用户仅执行指定备份脚本,本质是认证即执行、不可绕过。具体为在authorized_keys中为公钥添加command="..."前缀,强制覆盖默认shell,配合no-port-forwarding等限制项实现细粒度权限控制。

用 SSH 密钥的 command 选项限制用户只能执行指定备份脚本,本质是把权限控制前移到认证环节——不是靠登录后限制命令,而是让密钥“自带指令”,一认证就直接跑脚本,且无法绕过。
核心原理:密钥绑定命令,覆盖默认 Shell
OpenSSH 允许在 ~/.ssh/authorized_keys 文件中,为某一行公钥添加 command="..." 前缀。只要该密钥用于登录,SSH 服务端就会忽略用户想启动的 shell 或传入的命令,强制执行这个预设字符串(支持简单变量和路径)。
这种方式不依赖 ForceCommand(那是服务端全局配置),也不需要改用户默认 shell,粒度更细、更轻量,特别适合专用账号(如 backup-bot)。
具体操作步骤
- 创建专用系统用户(不给交互权限):
sudo useradd -r -s /bin/false backup-bot - 生成专用密钥对(建议带注释便于识别):
ssh-keygen -t ed25519 -C "backup-job@prod" -f ~/.ssh/backup_key - 将公钥内容复制到目标用户的
authorized_keys,并在开头加上command=...:command="/opt/scripts/run-backup.sh",no-port-forwarding,no-X11-forwarding,no-agent-forwarding ssh-ed25519 AAAA... backup-job@prod - 确保脚本存在、可执行、权限合理:
sudo chown root:backup-bot /opt/scripts/run-backup.shsudo chmod 750 /opt/scripts/run-backup.sh - 验证:用私钥连接,应直接执行脚本并退出,不能进入 shell:
ssh -i ~/.ssh/backup_key backup-bot@server
关键细节与安全建议
command 字符串里不要写 exec 或 bash -c——它本身就会被当作命令执行;如果脚本需要环境变量,可在脚本开头显式加载(如 . /etc/profile),或用 command="PATH=/usr/local/bin:/usr/bin:/bin /opt/scripts/run-backup.sh" 显式声明。
务必加上 no-* 限制项(如 no-port-forwarding),防止攻击者利用隧道逃逸;no-pty 可选,但加上后能彻底禁用伪终端分配,进一步缩小攻击面。
脚本内部应做最小权限设计:避免 sudo,尽量用 rsync --rsync-path="rsync --fake-super" 等机制替代 root 操作;输出日志建议写入 /var/log/backup/ 并由 backup-bot 用户组可写。
常见问题排查
如果连接后立即断开且无输出,先检查:
— 脚本第一行是否为正确 shebang(如 #!/bin/bash);
— 脚本中调用的命令(如 mysqldump、rsync)是否在 PATH 中,或是否用了绝对路径;
— authorized_keys 文件权限是否为 600,目录 ~/.ssh 是否为 700;
— 查看服务端日志:sudo journalctl -u sshd -n 50 -f,搜索 “skipped” 或 “failed command” 类提示。










