Bash脚本SSH连远程服务器执行git pull报公钥权限错误如何解决
问题根因
报错核心原因是通过SSH传递执行远程命令时启动的是非交互式Shell,不会加载日常登录服务器时的SSH密钥、ssh-agent相关环境配置。
日常手动SSH登录远程服务器B时启动的是交互式登录Shell,会自动读取~/.bashrc、~/.profile等用户配置文件,其中配置的ssh-agent启动、私钥加载逻辑会正常生效,因此手动执行git pull可以正常认证。而使用ssh $SSH_ENDPOINT /bin/bash << EOF的heredoc方式传递远程命令时,启动的bash属于非交互模式,默认不会加载上述用户配置,git调用SSH连接GitHub时找不到可用的有效私钥,就会抛出公钥认证失败的错误。
快速排查方法
- 在原脚本的
git pull命令前添加ssh -T git@github.com,执行后可以看到远程非交互会话下完全没有GitHub的有效认证信息,和手动登录B服务器执行同一条命令的输出有明显差异 - 在
git pull前添加echo $SSH_AUTH_SOCK,会发现非交互式会话下该环境变量为空,说明当前会话没有关联到存储了有效私钥的ssh-agent进程
可行解决方法
- 方法1:强制远程Bash以登录交互模式启动,加载完整用户配置
把原SSH命令的bash启动参数调整为登录交互模式,强制加载所有用户环境配置:
参数说明:ssh $SSH_ENDPOINT /bin/bash -il << EOF cd ~/$PROJECT git pull EOF-i指定启动交互模式加载shell配置,-l指定按登录shell流程初始化所有环境变量。 - 方法2:开启SSH Agent转发,复用本地机器A的GitHub密钥
不需要依赖B服务器本地存储的密钥,SSH连接时加-A参数开启代理转发,让远程会话直接使用本地A上已经加载到ssh-agent的GitHub私钥完成认证:
使用前提:本地A机器的ssh-agent已经提前加载了GitHub对应私钥,执行ssh -A $SSH_ENDPOINT /bin/bash << EOF cd ~/$PROJECT git pull EOFssh-add -l可以看到对应密钥的指纹即可正常使用 - 方法3:执行git操作时手动指定B机器上的GitHub私钥路径
如果不想调整Shell启动参数,也可以在执行git pull前临时指定GIT_SSH_COMMAND参数,明确告诉git调用SSH时要使用的私钥路径:ssh $SSH_ENDPOINT /bin/bash << EOF cd ~/$PROJECT GIT_SSH_COMMAND="ssh -i ~/.ssh/你存储在B上的GitHub私钥文件名 -o IdentitiesOnly=yes" git pull EOF
内容的提问来源于stack exchange,提问作者Ajay Pillay
相关产品推荐
相关产品推荐

