Jenkins流水线 - SSH连接到不同的机器以及存储凭据的位置(使用ssh/SSHAgent插件等)

8

简要概述:如何使用ssh连接到不同的计算机以及在Jenkins流水线中存储ssh凭据(使用ssh/SSHAgent插件等)?

问题:在Jenkins流水线中,我需要对目标计算机进行远程ssh。我的旧方法是使用“使用ssh在远程主机上执行shell脚本”选项。我想指定用户名和密码。

我了解到Groovy的做法可能是这样的:

sshagent(['RemoteCredentials']) {
    sh 'ssh -o StrictHostKeyChecking=no -l remoteusername remotetarget uname -a'
  }

远程凭证:它是带有密语的私钥。

是否有一种使用用户名/密码的远程凭据进行ssh连接的方法?ssh代理不支持用户名/密码验证。

Riccardo


1
请查看此链接:https://dev59.com/konda4cB1Zd3GeqPFeZI - izzekil
你可以参考这篇文章中的SSH步骤,使用用户名和密码进行连接:https://jenkins.io/blog/2019/02/06/ssh-steps-for-jenkins-pipeline/sshCommand remote: remote, command: 'for i in {1..5}; do echo -n "Loop $i "; date ; sleep 1; done' - user11506835
3个回答

9
很不幸,你是正确的。
看起来ssh-agent插件只支持通过Jenkins的凭证管理区添加的存储用户、密码、公钥凭据。可以参考这个单元测试来验证基于公钥的ssh-agent是否正常工作。该插件不太可能有未经测试的功能来支持用户+密码身份验证。 如果可能,请切换到基于公钥的身份验证。如果出于某些原因无法切换...你可以在Jenkins服务器上安装sshpass,但这通常被认为是一种不好的做法。
node {
    stage 'Does sshpass work?'
    sh 'sshpass -p \'password\' ssh user@host "ls; hostname; whois google.com;"'
}

2
即使您使用此方法,请记得至少使用withCredentials来在Jenkinsfile中不暴露密码。 - dag

0
解决方案: 您想要在管道中ssh到某台机器。我想提供一种不同的方法,更加安全(我希望能够在机器本身上管理我的ssh凭据)。确保您的ssh密钥预先构建在~/.ssh/id_rsa下的基础设施中(可以通过ansible/chef/puppet进行预配置,或者只需使用带有aws/gcp/azure云环境的图像快照)。您的管道应该在机器上加载ssh私钥凭据并连接到节点(其中包含公钥)。
_node(with private key) ---> testing/staging/production_node(with public key)

你什么时候使用它? 例如使用情况 - 您想在另一个节点上运行/停止某些进程,或在您的管道中部署应用程序在实例x和y上

简单示例 - 点对点node -> destination_node)将是:

def ip-address=<some-ip-address> 

sh """#!/bin/bash
        eval "\$(ssh-agent -s)"
        ssh-add ~/.ssh/id_rsa
        ssh -o StrictHostKeyChecking=no ${ip-address} << 'EOF'
        echo 'im in ...'
 """

复杂示例 - 堡垒使用堡垒云架构(节点 -> VPC 端点 -> 目标节点)将是:

def vpc-endpoint-gw-ip=<some-ip-address>
def subnet-ip=<some-subnet-address>

sh """#!/bin/bash 
        eval "\$(ssh-agent -s)"
        ssh-add ~/.ssh/id_rsa
        ssh -At -o StrictHostKeyChecking=no ${vpc-endpoint-gw-ip} << 'EOF'
        ssh -o StrictHostKeyChecking=no ${subnet-ip} << 'EOF2'
        echo 'im in ...'
  """

0

提升在Jenkins代理上运行ssh任务的能力,将使您的服务器更加安全。当您运行像Ansible这样的ssh任务时,Jenkins是一个攻击向量,控制发布非常有必要。

  • 改进/etc/sshd_config将阻止黑客进行大量探测。

    PasswordAuthentication no

    PubkeyAuthentication yes

    PermitRootLogin no

  • 从DSA或RSA密钥对转换到更安全的ed25519椭圆曲线密码学,并在私钥文件上使用暴力保护。

    ssh-keygen -t ed25519 -o -a 300 -C Jenkins

    由于私钥需要数百轮,每次使用需要几十秒钟,这非常适合构建代理,因为开发人员可能会窥探周围。

我不想将私钥作为凭据存储在Jenkins中,因为Jenkins是可插拔的代码执行引擎,而是仅将口令作为秘密文本凭据(在示例中命名为mySecretText)存储。我为环境专门设置了代理,每个代理都有自己的~/.ssh/id_ed25519密钥文件,具有有限的爆炸半径。口令用于启动ssh-agent,更具体地说,用于每个会话加载密钥。

下面的Jenkinsfile允许使用密钥对将标签推送到git,但磁盘上没有明文。选择了这种实现方式是因为ssh-agent插件不允许ssh-add。
node {
    println("Checkout repository...")
    checkout scm
}

pipeline {
    agent {
        label "linux"
    }

    options {
        disableConcurrentBuilds()
    }

    stages {
        stage('PushTheTag') {
            steps {
                script {
                    withCredentials([string(credentialsId: 'mySecretText', variable: 'SSH_PASSPHRASE')]) {
                        sh "echo 'echo \$SSH_PASSPHRASE' > ~/.ssh/tmp && chmod 700 ~/.ssh/tmp"
                        sh "eval `ssh-agent -s` && cat ~/.ssh/id_ed25519|DISPLAY=None SSH_ASKPASS=~/.ssh/tmp ssh-add - && git tag ${env.BUILD_NUMBER} && git push --tags; kill -9 \$SSH_AGENT_PID"
                    }
                }
            }
        }
    }
}

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