为什么这个 ssh 密钥文件在 Windows/Filezilla 而不是 linux/command 行上工作?
Why is this ssh keyfile working on Windows/Filezilla and not on linux/command line?
我使用名为 mykey.ppk
的密钥成功连接到 Windows 上的 FileZilla
我正在尝试使用该密钥在 Linux 上的 Jenkins 管道中上传文件。
我根本无法使文件在 ubuntu 20:04
中工作
我使用 PuttyGen 将文件转换为名为 mykey_open.ppk
的 open-ssh 格式文件,如 https://serverfault.com/questions/1004774/load-key-privkey-ppk-invalid-format 中所示(加载 > 转换菜单 > 导出 OpenSSH 文件)
我将文件的权限设置为 600 与所有者 jenkins:jenkins
我在putty上输入了以下命令,
ssh -Tv myuser@myremote.site.io -i ./mykey_open.ppk
结果:
debug1: Trying private key: ./mykey_open.ppk
Load key "./mykey_open.ppk": Permission denied
debug2: we did not send a packet, disable method
debug1: No more authentication methods to try.
myuser@myremote.site.io : Permission denied (publickey).
并且也在 Jenkins 管道中:
sh 'ssh -Tv myuser@myremote.site.io -i ./mykey_open.ppk'
给出:
Transferred: sent 2520, received 2244 bytes, in 0.4 seconds
Bytes per second: sent 7154.6, received 6371.0
debug1: Exit status 1
[Pipeline] }
[Pipeline] // node
[Pipeline] End of Pipeline
ERROR: script returned exit code 1
Finished: FAILURE
我也试过使用管道命令
def remote = [:]
remote.name = "myremote"
remote.host = "myremote.site.io"
remote.allowAnyHosts = true
withCredentials([sshUserPrivateKey(keyFileVariable: 'identity', passphraseVariable: '', usernameVariable: 'myuser')]) {
remote.user = userName
remote.identityFile = "mykey_open.ppk"
stage("SSH Steps Rocks!") {
sshPut remote: remote, from: 'myfile.zip', into: '/myremote.site.io/path/to/folder'
}
这给出了
java.lang.NullPointerException
at java.base/java.util.Objects.requireNonNull(Objects.java:221)
at com.cloudbees.plugins.credentials.CredentialsProvider.findCredentialById(CredentialsProvider.java:877)
at com.cloudbees.plugins.credentials.CredentialsProvider.findCredentialById(CredentialsProvider.java:855)
at org.jenkinsci.plugins.credentialsbinding.MultiBinding.getCredentials(MultiBinding.java:195)
at org.jenkinsci.plugins.credentialsbinding.impl.SSHUserPrivateKeyBinding.bind(SSHUserPrivateKeyBinding.java:94)
at org.jenkinsci.plugins.credentialsbinding.impl.BindingStep$Execution2.doStart(BindingStep.java:134)
at org.jenkinsci.plugins.workflow.steps.GeneralNonBlockingStepExecution.lambda$run[=15=](GeneralNonBlockingStepExecution.java:77)
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)
Finished: FAILURE
找到解决方案:使用 sftp
命令代替 ssh
。
但 sftp 通常依赖于交互式命令:您键入 sftp
,然后您会得到 sftp>
提示以输入诸如 put
、get
等命令。
有一个在编程上下文中使用该命令的解决方法:
echo put localfile.txt path/to/local/remotefile.txt | sftp -i keyfile.ppk user@remote.site.address
在 Jenkins 管道的特定情况下,这变成:
sh 'echo put localfile.txt path/to/local/remotefile.txt | sftp -i keyfile.ppk user@remote.site.address'
我使用名为 mykey.ppk
我正在尝试使用该密钥在 Linux 上的 Jenkins 管道中上传文件。
我根本无法使文件在 ubuntu 20:04
中工作我使用 PuttyGen 将文件转换为名为 mykey_open.ppk
的 open-ssh 格式文件,如 https://serverfault.com/questions/1004774/load-key-privkey-ppk-invalid-format 中所示(加载 > 转换菜单 > 导出 OpenSSH 文件)
我将文件的权限设置为 600 与所有者 jenkins:jenkins
我在putty上输入了以下命令,
ssh -Tv myuser@myremote.site.io -i ./mykey_open.ppk
结果:
debug1: Trying private key: ./mykey_open.ppk
Load key "./mykey_open.ppk": Permission denied
debug2: we did not send a packet, disable method
debug1: No more authentication methods to try.
myuser@myremote.site.io : Permission denied (publickey).
并且也在 Jenkins 管道中:
sh 'ssh -Tv myuser@myremote.site.io -i ./mykey_open.ppk'
给出:
Transferred: sent 2520, received 2244 bytes, in 0.4 seconds
Bytes per second: sent 7154.6, received 6371.0
debug1: Exit status 1
[Pipeline] }
[Pipeline] // node
[Pipeline] End of Pipeline
ERROR: script returned exit code 1
Finished: FAILURE
我也试过使用管道命令
def remote = [:]
remote.name = "myremote"
remote.host = "myremote.site.io"
remote.allowAnyHosts = true
withCredentials([sshUserPrivateKey(keyFileVariable: 'identity', passphraseVariable: '', usernameVariable: 'myuser')]) {
remote.user = userName
remote.identityFile = "mykey_open.ppk"
stage("SSH Steps Rocks!") {
sshPut remote: remote, from: 'myfile.zip', into: '/myremote.site.io/path/to/folder'
}
这给出了
java.lang.NullPointerException
at java.base/java.util.Objects.requireNonNull(Objects.java:221)
at com.cloudbees.plugins.credentials.CredentialsProvider.findCredentialById(CredentialsProvider.java:877)
at com.cloudbees.plugins.credentials.CredentialsProvider.findCredentialById(CredentialsProvider.java:855)
at org.jenkinsci.plugins.credentialsbinding.MultiBinding.getCredentials(MultiBinding.java:195)
at org.jenkinsci.plugins.credentialsbinding.impl.SSHUserPrivateKeyBinding.bind(SSHUserPrivateKeyBinding.java:94)
at org.jenkinsci.plugins.credentialsbinding.impl.BindingStep$Execution2.doStart(BindingStep.java:134)
at org.jenkinsci.plugins.workflow.steps.GeneralNonBlockingStepExecution.lambda$run[=15=](GeneralNonBlockingStepExecution.java:77)
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)
Finished: FAILURE
找到解决方案:使用 sftp
命令代替 ssh
。
但 sftp 通常依赖于交互式命令:您键入 sftp
,然后您会得到 sftp>
提示以输入诸如 put
、get
等命令。
有一个在编程上下文中使用该命令的解决方法:
echo put localfile.txt path/to/local/remotefile.txt | sftp -i keyfile.ppk user@remote.site.address
在 Jenkins 管道的特定情况下,这变成:
sh 'echo put localfile.txt path/to/local/remotefile.txt | sftp -i keyfile.ppk user@remote.site.address'