Jenkins升级服务器后,SSH私钥验证失败

4

我有一个运行在Ubuntu服务器上的Jenkins实例通过Docker运行。该Jenkins实例使用ssh脚本(“使用ssh在远程主机上执行shell脚本”)连接到同一台Ubuntu服务器运行作业。身份验证是通过私钥完成的,已经安全运行了一年多。

最近,我升级了我的Ubuntu版本(do-release-upgrade),之后涉及该服务器的所有脚本都无法进行身份验证。

错误信息:

[SSH] executing...
[SSH] Exception:Auth fail
com.jcraft.jsch.JSchException: Auth fail

我不确定为什么,但我一直在进行故障排除:

  1. 还有一些 SSH 脚本连接到其他机器,这些仍然运行良好。这个问题并不涉及 SSH 插件或 Jenkins 本身,而是连接的服务器。

  2. 我有两个用户为此服务器配置了私钥(假设为 <user>root),但都无法工作。因此,它似乎与特定用户无关,而是与服务器有关。

  3. 我尝试使用一个简单的 echo "hello",结果是相同的。这证实了脚本不是问题所在——也应该如此,因为它们没有被更改。

  4. 如果我将身份验证方法从私钥更改为用户名和密码,则系统可以正常连接。因此,它并不像是任何机器或代理阻止它。再次强调,除了升级 Ubuntu 外,任何设置都没有更改。这应该排除许多基本问题,如确保 IP/端口正确等。

  5. 我尝试重新创建密钥,结果是一样的。我使用了一些变体来创建它们(有关更多详细信息,请参见下面的“Key variants”)。在这样做时,我将私钥的内容复制到了 Jenkins 中;我尝试生成带有和不带有口令的密钥。请注意,我遵循了上次创建密钥时的相同过程,并且这一直有效(我记录下来以防忘记)。

  6. 为了安全起见,我尝试彻底删除 ~/.ssh/ 文件夹并重新创建它,以防有些问题。

  7. 如果我尝试使用 MacBook 上的私钥登录到服务器,连接就可以正常工作(ssh -i key.pem <user>@<ip> -p <port>),其中 key.pem 是我正在粘贴到 Jenkins 凭据中的相同内容。这让我想到密钥已经正确生成。

  8. 在升级后,我在 MacBook 上不得不删除 known_hosts 中对服务器的旧引用。但是,我无法在 Jenkins 配置中找到相同的内容——事实上,它可以使用用户名和密码进行连接,这使我认为没有任何东西阻止连接,而是 Jenkins 无法正确使用私钥。

  9. 我知道服务器上的某些文件在升级后发生了更改,包括 /etc/ssh/sshd_config。我必须恢复一些设置,包括将 PasswordAuthentication no 更改为 PasswordAuthentication yes——我相信这是我之前的设置。(查看下面的 sshd_config 内容,一些部分被遮盖了)。

  10. 我还尝试更新 Jenkins 及其插件,永远不知道会发生什么。

虽然使用用户名和密码是可行的,但我希望确认一下是否使用了私钥,因为这种方式感觉更加安全,而且易于管理不同用户的访问和权限级别。对于如何解决或尝试下一步操作有什么想法吗? :)

提前感谢!



附录


密钥变体

通用

# Generate keys
mkdir ~/.ssh; cd ~/.ssh/ && ssh-keygen -t rsa -m PEM -C "Jenkins agent key" -f "jenkinsAgent_rsa"

# Authorize keys
cat jenkinsAgent_rsa.pub >> ~/.ssh/authorized_keys
chmod 700 ~/.ssh
chmod 600 ~/.ssh/authorized_keys ~/.ssh/jenkinsAgent_rsa

# Get private key for Jenkins
cat ~/.ssh/jenkinsAgent_rsa

拥有root权限

# Run before the other commands
sudo su $AGENT_USER

或者
# Run before the other commands
sudo su

不同的密钥生成器

ssh-keygen -t rsa -b 4096 -m PEM -C "Jenkins agent key" -f "jenkinsAgent_rsa"

ssh-keygen -t rsa -C "Jenkins agent key" -f "jenkinsAgent_rsa"

生成的密钥(格式化后,内容已剥离)

这是我要复制到Jenkins的内容。

-----BEGIN RSA PRIVATE KEY-----
Proc-Type: 4,ENCRYPTED
DEK-Info: AES-128-CBC,518C612F99A868<somecharsremoved>09C9A6047E20

sDqB0yOas0sf4dJRLvb8IxyOvoIwr8Ls3uMbugwTOJ/
(...)
MuZyUzWXnhUaWgnXJlTLhnmXiJ9XgUClYftQpP4RZw9Ult/dje5XD81RmwwhuxUV
-----END RSA PRIVATE KEY-----

sshd_config(删除所有注释)

PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games
Include /etc/ssh/sshd_config.d/*.conf
Port <port>
# This used to be `ChallengeResponseAuthentication no` but I assume no issues.
KbdInteractiveAuthentication no
UsePAM yes
X11Forwarding yes
PrintMotd no
AcceptEnv LANG LC_*
Subsystem       sftp    /usr/lib/openssh/sftp-server
PasswordAuthentication yes
1个回答

3
我猜测你的系统现在正在运行OpenSSH 8.8或更新版本,因为此版本默认禁用使用SHA-1哈希算法的RSA签名。这意味着使用此算法生成的任何SSH密钥将不再被接受。
当连接到未升级或未严密跟踪SSH协议改进的较旧SSH实现时,不兼容性更有可能发生。对于这些情况,可能需要通过HostkeyAlgorithms和PubkeyAcceptedAlgorithms选项选择性重新启用RSA/SHA1以允许连接和/或用户身份验证。例如,在~/.ssh/config中加入以下内容将为单个目标主机启用RSA / SHA1主机和用户身份验证:
Host old-host
    HostkeyAlgorithms +ssh-rsa
    PubkeyAcceptedAlgorithms +ssh-rsa

虽然这样也许可以工作,但这只是一个权宜之计,而不是解决方案。OpenSSH禁用ssh-rsa有一个非常好的安全原因。解决方案是使用ed25519密钥(ssh-keygen -t ed25519 ... )并确保在您的服务器上始终更新OpenSSH。


很有洞察力!我会假设如果这是根本原因,我就不能利用密钥登录我的 MacBook。这将对所有人禁用。虽然可能有不同的解释。我稍后会尝试并回复!谢谢! - nitobuendia
这仍然失败了,但是出现了 [SSH] executing... /n ERROR: Failed to authenticate with public key /n com.jcraft.jsch.JSchException: invalid privatekey: [B@42f2a9bc。我使用以下命令生成了密钥 ssh-keygen -t ed25519 -m PEM -C "Jenkins (nito)" -f "jenkins_nito_key"。该密钥以 -----BEGIN OPENSSH PRIVATE KEY-----\nb3BlbnNzaC1rZXktdjEAAA (...) 开头。看起来 Jenkins 还不支持它 - https://issues.jenkins.io/browse/JENKINS-64654。 - nitobuendia
我还尝试在服务器的/etc/sshd_config中添加HostkeyAlgorithms +ssh-rsaPubkeyAcceptedAlgorithms +ssh-rsa,并重新启动ssh服务,但原始错误仍然存在。这是否产生了与您在~/.ssh/config中提出的Host old-host和配置建议相同的结果? - nitobuendia
~/.ssh/config 是 ssh 客户端的配置文件。/etc/sshd_config 是 sshd 守护进程(ssh 服务器)的配置文件。您可以尝试在您连接到的服务器上添加这些选项。另一个选项是尝试使用 ECDSA 密钥。希望从 Jenkins 中看到更详细的日志,Auth fail 并不是很有信息量(类似于 ssh -vvv)。 - Alexander Volkovsky
除非我漏掉了什么,否则这里对ssh客户端的控制是有限的,因为它是Jenkins插件。我没有直接运行ssh命令,而是由插件编排。我能够更多地控制主机/服务器,而且那也是已经发生了变化并且正在失败的机器。这也是我尝试将rsa支持添加回服务器的原因。根据上面的链接,Jenkins似乎还不支持ed25519。 - nitobuendia

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接