问题

在 Bitbucket 使用 Linux 机器上 ssh-keygen 工具生成的公钥作为 API KEY,然后在 Jenkins 里面存储对应的 SSH 私钥,最后执行 Job 的时候,Windows Agent 提示 SSH 密钥不正确。

 > git fetch --tags --force --progress -- ssh://git@bitbucket.xxxxx.com:7999/xxxx.git +refs/heads/*:refs/remotes/origin/* # timeout=10
ERROR: Error fetching remote repo 'origin'
hudson.plugins.git.GitException: Failed to fetch from git@bitbucket.xxxxx.com:7999/xxxx.git
at hudson.plugins.git.GitSCM.fetchFrom(GitSCM.java:1001)
at hudson.plugins.git.GitSCM.retrieveChanges(GitSCM.java:1242)
at hudson.plugins.git.GitSCM.checkout(GitSCM.java:1302)
at org.jenkinsci.plugins.workflow.steps.scm.SCMStep.checkout(SCMStep.java:129)
at org.jenkinsci.plugins.workflow.steps.scm.SCMStep$StepExecutionImpl.run(SCMStep.java:97)
at org.jenkinsci.plugins.workflow.steps.scm.SCMStep$StepExecutionImpl.run(SCMStep.java:84)
at org.jenkinsci.plugins.workflow.steps.SynchronousNonBlockingStepExecution.lambda$start$0(SynchronousNonBlockingStepExecution.java:47)
at java.base/java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:515)
at java.base/java.util.concurrent.FutureTask.run(FutureTask.java:264)
at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1128)
at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:628)
at java.base/java.lang.Thread.run(Thread.java:829)
Caused by: hudson.plugins.git.GitException: Command "git fetch --tags --force --progress -- ssh://git@bitbucket.xxxxx.com:7999/xxxx.git +refs/heads/*:refs/remotes/origin/*" returned status code 128:
stdout:
stderr: git@bitbucket.xxxxx.com: Permission denied (publickey).
fatal: Could not read from remote repository. Please make sure you have the correct access rights
and the repository exists. at org.jenkinsci.plugins.gitclient.CliGitAPIImpl.launchCommandIn(CliGitAPIImpl.java:2671)
at org.jenkinsci.plugins.gitclient.CliGitAPIImpl.launchCommandWithCredentials(CliGitAPIImpl.java:2096)
at org.jenkinsci.plugins.gitclient.CliGitAPIImpl.access$500(CliGitAPIImpl.java:84)
at org.jenkinsci.plugins.gitclient.CliGitAPIImpl$1.execute(CliGitAPIImpl.java:618)
at org.jenkinsci.plugins.gitclient.RemoteGitImpl$CommandInvocationHandler$GitCommandMasterToSlaveCallable.call(RemoteGitImpl.java:158)
at org.jenkinsci.plugins.gitclient.RemoteGitImpl$CommandInvocationHandler$GitCommandMasterToSlaveCallable.call(RemoteGitImpl.java:151)
at hudson.remoting.UserRequest.perform(UserRequest.java:211)
at hudson.remoting.UserRequest.perform(UserRequest.java:54)
at hudson.remoting.Request$2.run(Request.java:376)
at hudson.remoting.InterceptingExecutorService.lambda$wrap$0(InterceptingExecutorService.java:78)
at java.util.concurrent.FutureTask.run(Unknown Source)
at java.util.concurrent.ThreadPoolExecutor.runWorker(Unknown Source)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source)
at hudson.remoting.Engine$1.lambda$newThread$0(Engine.java:122)
at java.lang.Thread.run(Unknown Source)
Suppressed: hudson.remoting.Channel$CallSiteStackTrace: Remote call to dev-eu01-njen03.solera.farm
at hudson.remoting.Channel.attachCallSiteStackTrace(Channel.java:1797)
at hudson.remoting.UserRequest$ExceptionResponse.retrieve(UserRequest.java:356)
at hudson.remoting.Channel.call(Channel.java:1001)
at org.jenkinsci.plugins.gitclient.RemoteGitImpl$CommandInvocationHandler.execute(RemoteGitImpl.java:143)
at jdk.internal.reflect.GeneratedMethodAccessor8221.invoke(Unknown Source)
at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.base/java.lang.reflect.Method.invoke(Method.java:566)
at org.jenkinsci.plugins.gitclient.RemoteGitImpl$CommandInvocationHandler.invoke(RemoteGitImpl.java:129)
at com.sun.proxy.$Proxy126.execute(Unknown Source)
at hudson.plugins.git.GitSCM.fetchFrom(GitSCM.java:999)
at hudson.plugins.git.GitSCM.retrieveChanges(GitSCM.java:1242)
at hudson.plugins.git.GitSCM.checkout(GitSCM.java:1302)
at org.jenkinsci.plugins.workflow.steps.scm.SCMStep.checkout(SCMStep.java:129)
at org.jenkinsci.plugins.workflow.steps.scm.SCMStep$StepExecutionImpl.run(SCMStep.java:97)
at org.jenkinsci.plugins.workflow.steps.scm.SCMStep$StepExecutionImpl.run(SCMStep.java:84)
at org.jenkinsci.plugins.workflow.steps.SynchronousNonBlockingStepExecution.lambda$start$0(SynchronousNonBlockingStepExecution.java:47)
at java.base/java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:515)
at java.base/java.util.concurrent.FutureTask.run(FutureTask.java:264)
at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1128)
at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:628)
at java.base/java.lang.Thread.run(Thread.java:829)

最后登录到对应的 Windows 节点,直接使用 git clone 命令也是这样,说明不是 Jenkins 的权限问题。

查询资料得知,出现这种情况需要将对应公钥(id_rsa)与私钥文件(id_rsa.pub) 复制到 Jenkins Agent 执行用户的 HOME 目录下的 .ssh 文件夹。

普通用户的 HOME 目录就是 echo $HOME,一般也就是 C:\User\UserName 的路径。但是 Jenkins Agent 一旦作为服务执行,那么他的执行用户就是 SYSTEM ACCOUNT,它的 HOME 目录路径是 C:\WINDOWS\system32\config\systemprofile\.ssh

根据上述情况试了,还是没有解决,不管是 ssh-add xxx,还是更改 Git 的 SSH CONFIG 文件都无法解决。

原因

我一直以为是自己的问题,结果用 GitHub 试了,是正常的。最后将目光转向了 BitBucket,根据官方的文章,设置了 GIT_SSH_COMMAND 环境变量,并指定 ssh -vvvv 命令,这样能够让我们看到详细的错误信息。

最后得到了以下输出:

查询资料得知,根本原因是 BitBucket 现在不支持 RSA SHA-1 生成的密钥。

解决

官方的解决方案有两种,第一种是使用不安全的 RSA SHA-1 密钥,只需要更改客户端的配置文件,将 ssh-rsa 添加进去即可。不过这种做法并不安全,最好的做法还是使用 ssh-keygen 命令生成更加安全,基于 ED25519 算法的密钥。

ssh-keygen -t ed25519 -C "your_email@example.com"

将这个公钥重新设置在 Bitbucket,然后将私钥替换掉 Jenkins 里面的 Credential,执行 Jenkins Job 成功。

参考资料

Bitbucket 使用 SSH 拉取仓库失败的问题的更多相关文章

  1. 【Git】4、创建代码仓库,HTTP、SSH拉取远端代码

    拉取远端代码:使用Git命令下载远程仓库到本地 文章目录 拉取远端代码:使用Git命令下载远程仓库到本地 1.创建远程代码仓库 2.创建仓库 3.进入仓库 4.HTTP(S)获取远程仓库 首次拉取 更 ...

  2. 小程序切换账户拉取仓库文件的appid提示

    小程序切换账户拉取仓库文件,拉取后appid会提示项目不是当前appid的项目,因为切换了账户,而每个小程序账户只有一个appid,所以会冲突 去project.config.json里吧appid改 ...

  3. docker学习笔记(1)——ubuntu16.04安装docker(含如何彻底卸载docker,docker拉取镜像失败解决)

    参考博客: 1.官网教程:https://docs.docker.com/engine/install/   根据本机不同的信息选择不同的安装方式:  https://docs.docker.com/ ...

  4. Kubernetes之解决从k8s.gcr.io拉取镜像失败问题

    前言 因谷歌网络限制问题,国内的K8ser大多数在学习Kubernetes过程中因为镜像下载失败问题间接地产生些许失落感,笔者也因此脑壳疼,故翻阅资料得到以下解决方式: 在应用yaml文件创建资源时, ...

  5. maven私服拉取jar失败(内网)

    解决方案: 1.私服没jar,找私服负责人添加 2.私服有拉不下来,重启nexus服务端(负责人做) 3.本地有jar但是idea中没找到,先执行一下reimport,不行的话,随意修改下pom文件, ...

  6. 配置 Containerd 在 harbor 私有仓库拉取镜像

    官方文档地址:https://github.com/containerd/cri/blob/master/docs/registry.md 严格来说,这个具体可分为两部分 1.在k8s中使用Conta ...

  7. git拉取分支

    拉取仓库代码很简单,直接建立连接在pull下来就可以,如果想要拉取仓库中的某一个分支的话,则可能比较麻烦一点,下面简单介绍了一种拉取仓库分支的方法 1.先新建一个项目文件夹 2.git初始化git i ...

  8. 使用Docker之镜像的拉取、查询、删除

    1:查看镜像列表 2:拉取镜像    通过命令可以从镜像仓库中拉取镜像,默认从Docker Hub 获取. 命令格式: docker image pull <repository>:< ...

  9. 【mq】从零开始实现 mq-09-消费者拉取消息 pull message

    前景回顾 [mq]从零开始实现 mq-01-生产者.消费者启动 [mq]从零开始实现 mq-02-如何实现生产者调用消费者? [mq]从零开始实现 mq-03-引入 broker 中间人 [mq]从零 ...

随机推荐

  1. SpringMVC踩的第一个坑——Servlet.init()引发异常

    正确的设置了第一个SpringMVC相关的配置,初始启动服务器时,报404,经过排查,是项目生成构建的时候没有导入好依赖,手动在项目结构里面新建lib目录添加依赖解决了404的问题,重新部署以后开始报 ...

  2. form表单请求

    form 表单的acton属性指向url:端口号/(服务器get,post的参数), meyhod='get'/'post'  请求方式,必须要加上name属性. <form action=&q ...

  3. Casdoor + OAuth 实现单点登录 SSO

    简介 Casdoor 是一个基于 OAuth 2.0 / OIDC 的中心化的单点登录(SSO)身份验证平台,简单来说,就是 Casdoor 可以帮你解决用户管理的难题,你无需开发用户登录.注册等与用 ...

  4. 洛谷 P2392 kkksc03考前临时抱佛脚, dp / 深搜

    题目链接 P2392 kkksc03考前临时抱佛脚 - 洛谷 | 计算机科学教育新生态 (luogu.com.cn) 题目 dp代码 #include <iostream> #includ ...

  5. 面试官:RabbitMQ过期时间设置、死信队列、延时队列怎么设计?

    哈喽!大家好,我是小奇,一位不靠谱的程序员 小奇打算以轻松幽默的对话方式来分享一些技术,如果你觉得通过小奇的文章学到了东西,那就给小奇一个赞吧 文章持续更新 一.前言 RabbitMQ我们经常的使用, ...

  6. React + TypeScript + Taro前端开发小结

    前言 项目到一段落,先来记录一下,本文以前端新手的角度记录React.TypeScript.Taro相关技术的开发体验以及遇到的问题和解决方法. 之前总说要学React(这篇博客:代码使我头疼之Rea ...

  7. Java语言学习day14--7月19日

    ###10数组逆序功能实现 * A:案例代码 /* 数组的逆序: 数组中的元素,进行位置上的交换 逆序 不等于 反向遍历 就是数组中最远的两个索引,进行位置交换,实现数组的逆序 使用的是数组的指针思想 ...

  8. Mysql、Oracle锁表处理

    MySql解锁方式 1 # 1. 查看当前数据库锁表的情况 2 SELECT * FROM information_schema.INNODB_TRX; 3 # 2. 杀掉查询结果中锁表的trx_my ...

  9. go语言编译过程概述

    go语言编译过程概述 总结自<go语言设计与实现> 名词解释: 中间代码 中间代码是编译器或者虚拟机使用的语言,它可以来帮助我们分析计算机程序.在编译过程中,编译器会在将源代码转换到机器码 ...

  10. 数据结构 - AVL 树

    简介 基本概念 AVL 树是最早被发明的自平衡的二叉查找树,在 AVL 树中,任意结点的两个子树的高度最大差别为 1,所以它也被称为高度平衡树,其本质仍然是一颗二叉查找树. 结合二叉查找树,AVL 树 ...