Jenkinsfile使用sshUserPrivateKey连接服务器遭遇认证失败错误
Jenkins SSH认证失败(Auth fail)排查与修复
问题分析
你遇到的com.jcraft.jsch.JSchException: Auth fail错误,大概率是sshCommand的配置存在冲突或遗漏,结合你的代码,主要有以下几个可能的问题点:
核心排查与修复步骤
用户名变量冲突:
你在sshUserPrivateKey中指定了usernameVariable: 'rocky',但后续又给remoteConfig.user赋值${REMOTE_USER_NAME},这会导致sshCommand使用的用户名和凭据中的用户名不匹配。建议统一使用凭据返回的用户名变量,或者移除usernameVariable配置,确保REMOTE_USER_NAME与凭据中的用户名一致。私钥文件权限问题:
JSch(sshCommand依赖的库)对私钥文件权限要求严格,必须设置为600(仅当前用户可读可写)。需要在withCredentials块中添加权限设置命令:chmod 600 ${privateKeyFilePath}sshCommand配置遗漏:
你的remoteConfig未显式指定端口(虽然默认是22,但显式配置更稳妥);如果私钥设有密码,passphraseVariable不能留空,需要指定变量并传递给remoteConfig。凭据有效性验证:
先通过直接的ssh命令验证凭据是否有效,如果该命令能成功执行,说明凭据本身没问题,问题集中在sshCommand的配置上。
修正后的Jenkinsfile示例
def remoteConfig = [:] remoteConfig.name = "my-remote-server" remoteConfig.host = "${REMOTE_HOST}" remoteConfig.port = 22 // 显式指定端口 remoteConfig.allowAnyHosts = true node { withCredentials([sshUserPrivateKey( credentialsId: "${REMOTE_CRED}", keyFileVariable: "privateKeyFilePath", passphraseVariable: 'SSH_PASSPHRASE', // 私钥有密码时必填,无密码可留空但建议明确赋值 usernameVariable: 'SSH_USER' // 使用凭据返回的用户名变量 )]) { // 修复私钥文件权限 sh "chmod 600 ${privateKeyFilePath}" remoteConfig.user = SSH_USER remoteConfig.identityFile = privateKeyFilePath // 如果私钥有密码,传递passphrase if (SSH_PASSPHRASE?.trim()) { remoteConfig.passphrase = SSH_PASSPHRASE } stage("ssh") { // 先验证凭据有效性 sh """ ssh \ -p 22 \ -i ${privateKeyFilePath} \ -o StrictHostKeyChecking=no \ ${SSH_USER}@${REMOTE_HOST} \ 'echo Hello World!' """ // 使用正确配置执行sshCommand sshCommand remote: remoteConfig, command: 'for i in {1..5}; do echo -n "Loop $i "; date ; sleep 1; done' } } }
内容的提问来源于stack exchange,提问作者程泽群
相关产品推荐
相关产品推荐

