【问题标题】: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;"'
}
【解决方案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 -> vpc-endpoint -> 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 ...'
"""