【问题标题】:Jenkins pipeline - ssh to different machine and where to store credentials (using ssh/SSHAgent plugin/etc...)Jenkins 管道 - ssh 到不同的机器以及存储凭据的位置(使用 ssh/SSHAgent 插件/等...)
【发布时间】:2016-10-14 19:48:23
【问题描述】:

TLDR:如何对不同的机器进行 ssh 以及在 Jenkins 管道上存储 ssh 凭据的位置(使用 ssh / SSHAgent 插件 /etc...)?

问题:在 Jenkins 管道中,我需要一个远程 ssh 到目标机器。 我的旧方法是使用“使用 ssh 在远程主机上执行 shell 脚本”。我想同时指定用户名和密码。

我已经读过,groovy 方法应该是这样的

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

RemoteCredentials:是带密码的私钥

有没有办法使用用户名/密码远程凭据制作 ssh? sshagent 不支持用户名/密码验证

里卡多

【问题讨论】:

标签: jenkins ssh jenkins-pipeline credentials ssh-agent


【解决方案1】:

很遗憾,你是对的。

看起来 ssh-agent-plugin 只支持通过 Jenkins 的凭据管理区域添加的存储用户、密码、公钥凭据。 See this unit test 根据公钥验证 ssh-agent 是否正常工作。插件中不太可能存在未经测试的功能来支持用户+密码身份验证。

如果可以,请切换到基于公钥的身份验证。如果由于某种原因您无法切换……您可以在您的 Jenkins 机器上安装 sshpass,但这通常被认为是不好的做法。

node {
    stage 'Does sshpass work?'
    sh 'sshpass -p \'password\' ssh user@host "ls; hostname; whois google.com;"'
}

【讨论】:

  • 即使您使用这种方法,请记住至少使用withCredentials,以免在 Jenkinsfile 中暴露密码。
【解决方案2】:

加强在 Jenkins 代理上运行 ssh 任务的游戏,将使您的服务器更加安全。当您运行像 Ansible 这样的 ssh 任务时,Jenkins 是一个攻击媒介,并且控制发布是可取的。

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

    密码验证否

    PubkeyAuthentication 是

    PermitRootLogin no

  • 从 DSA 或 RSA 密钥对转移到更安全的 ed25519 椭圆曲线 对私钥文件进行强力保护的密码学。

    ssh-keygen -t ed25519 -o -a 300 -C 詹金斯

    因为私钥需要上百轮,每次使用需要几十秒, 这对于开发人员可能窥探的构建代理来说是完美的。

我宁愿不将私钥作为凭证存储在 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"
                    }
                }
            }
        }
    }
}

【讨论】:

    【解决方案3】:

    解决方案:你想在你的管道中连接一些机器。我想提供一种不同的方法,这种方法更安全(我希望能够在机器本身上管理我的 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 ...'
     """
    

    复杂示例 - Bastion 使用堡垒云架构 (node -&gt; vpc-endpoint -&gt; destination-node) 将是:

    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 ...'
      """
    

    【讨论】:

      猜你喜欢
      • 2017-11-06
      • 2018-04-16
      • 1970-01-01
      • 2017-11-04
      • 1970-01-01
      • 2020-02-17
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多