如何向登录shell为git-shell的服务器用户上传文件至~/www目录
报错核心原因
你为gituser配置的/usr/bin/git-shell是专门为Git服务设计的高度受限Shell,设计目标仅放行git upload-pack、git receive-pack、git upload-archive三类Git操作相关命令,会直接拦截所有非Git类的SSH请求。你执行scp时,SSH通道传给服务端的执行命令scp -t ~/www/不在内置白名单内,因此被git-shell拦截抛出未识别命令错误,连接中断。
可落地的解决方案
方案1:配置git-shell白名单放行scp,适配原有上传命令
这个方案不需要改动git用户的原有登录配置,调整成本最低:
- 登录服务器,使用拥有gituser家目录操作权限的账号执行操作
- 在gituser家目录下创建git-shell的自定义命令白名单目录:
mkdir -p ~gituser/git-shell-commands - 校验目录权限,保证该目录对其他用户不可写:
chmod 755 ~gituser/git-shell-commands。若目录权限过松,git-shell会出于安全机制直接拒绝执行自定义命令 - 在白名单目录下创建scp的可执行包装脚本:
nano ~gituser/git-shell-commands/scp,脚本内容为:#!/bin/sh exec /usr/bin/scp "$@" - 给脚本添加执行权限:
chmod +x ~gituser/git-shell-commands/scp
配置完成后,你原来的scp上传命令scp index.html gituser@example.de:~/www/即可正常执行。git-shell收到scp开头的请求时,会匹配到白名单内的包装脚本,实际调用系统scp程序完成文件传输。
方案2:依托现有Git服务能力传文件,不放开额外权限
如果你不想调整git-shell的受限规则,可以利用Git本身的能力完成文件上传,安全性更高:
- 在服务器的
~/www路径初始化Git裸仓库,配置post-receive钩子自动将仓库内容检出到www目录 - 本地将存放index.html的目录关联为该远程Git仓库的工作区,提交修改后直接通过
git push推送文件,由服务端钩子自动完成文件落盘
该方式不需要给git-shell增加任何额外权限,完全符合git-shell的安全设计初衷。
方案3:单独配置普通权限传输账号
可以新建一个拥有普通bash权限的系统用户,将~/www目录的所属组和该新账号绑定,配置对应读写权限。后续上传文件时使用这个新账号执行scp操作,既不会破坏原gituser的git-shell安全配置,也不会扩大原有Git服务的权限范围。
内容的提问来源于stack exchange,提问作者rubo77
相关产品推荐
相关产品推荐

