凭据管理
Jenkins 凭据概述
Jenkins 凭据是 Jenkins 中用于安全存储和管理敏感信息的机制。这些凭据可以用来提供给 Jenkins 作业、管道(pipeline)或插件,避免在脚本中硬编码敏感信息,如密码、SSH 密钥、API 令牌等。Jenkins 凭据的设计使得用户可以安全地处理这些信息,且通过访问控制保证只有经过授权的任务和人员能够使用它们。
凭据的主要类型
Jenkins 支持多种类型的凭据,常见的有:
-
用户名和密码(Username with password)
- 这是最基本的凭据类型,存储用户名和密码,通常用于 HTTP 基本认证、API 访问等。
-
SSH 私钥(SSH Username with private key)
- 用于 SSH 连接时的认证,通常在 Jenkins 中执行 SSH 操作(如通过 SSH 连接到远程主机)时使用。
-
Secret Text
- 单个的密文字符串,可以是密码、API 令牌或其他类型的密钥。常用于与第三方服务集成时提供 API Token。
-
Secret File
- 敏感的文件凭据,比如私钥文件、配置文件等,可以在作业中下载并使用。
-
证书(Certificate)
- 用于存储包含私钥的证书文件,通常用于需要双向 SSL 的场景,如与某些服务的加密通信。
-
GitHub 凭据
- 专用于 GitHub 操作的 OAuth 令牌、用户名/密码或 SSH 私钥,用于与 GitHub 仓库交互。
Jenkins 中的凭据存储
Jenkins 凭据默认存储在主控节点的加密数据库中。Jenkins 通过 Credentials 插件来管理凭据,并通过 Web 界面或 Jenkinsfile 进行使用和引用。对于安全性,Jenkins 采用两种机制来保护凭据:
-
凭据域(Credential Domains)
- 可以将不同的凭据分配到不同的域中,限制它们在哪些 Jenkins 作业或项目中可用。例如,你可以创建一个用于生产环境的凭据域,确保这些凭据只能用于生产相关的作业,而无法被其他作业访问。
-
凭据作用范围(Scope)
- 凭据可以设置为 全局 或 系统范围,全局凭据可在 Jenkins 实例中的所有项目使用,而系统范围的凭据仅限于特定的 Jenkins 系统组件。
凭据使用示例
-
在 Jenkins 界面中使用:
- 在配置 Jenkins 任务时,可以在 “构建环境” 或 “源码管理” 中引用存储的凭据。例如,配置 Git SCM 时,可以选择一个存储的凭据来访问 Git 仓库。
-
在 Jenkinsfile 中使用:
-
在 pipeline 脚本中,使用
credentials函数来引用凭据,例如:pipeline { agent any stages { stage('Build') { steps { withCredentials([usernamePassword(credentialsId: 'my-credentials-id', usernameVariable: 'USER', passwordVariable: 'PASS')]) { sh 'echo "Using username $USER and password $PASS"' } } } } }
-
在这个例子中,凭据 ID 为 my-credentials-id 的用户名和密码被赋值给环境变量 USER 和 PASS,可以在 Shell 脚本中引用。
安全注意事项
- 最小化凭据访问权限:使用凭据域和作用范围,确保凭据只对需要的作业和用户可见。
- 审计和监控:定期检查哪些凭据被访问,并通过 Jenkins 的审计插件跟踪谁使用了哪些凭据。
- 密钥轮换:定期更新凭据,避免长期使用相同的密钥或密码。
通过合理配置 Jenkins 凭据系统,能够提高敏感信息的安全性并减少泄露的风险。
Jenkins 添加凭据
GitLab
在 Jenkins 中添加并使用 GitLab 个人访问令牌(Personal Access Token, PAT)作为凭据,可以让 Jenkins 自动访问 GitLab 仓库,执行构建、触发 CI/CD 管道等操作。以下是详细步骤:
一、在 GitLab 中生成个人访问令牌(PAT)
- 登录到 GitLab:
- 使用你的 GitLab 账号登录到 GitLab 实例。
- 进入个人设置:
- 点击右上角的头像,选择 Settings(设置)。
- 访问 Token 配置:
- 在左侧菜单中,找到 Access Tokens 或 Personal Access Tokens 选项。
- 生成新的 Token:
- 在创建页面中,输入令牌的名称(如
Jenkins Token)。 - 设置有效期(可选,如果你希望令牌有过期时间)。
- 选择适当的 权限范围(Scopes),一般需要勾选:
api:允许 Jenkins 访问 GitLab API。read_user:读取用户信息。read_repository或write_repository:访问 Git 仓库(write_repository允许推送代码)。
- 在创建页面中,输入令牌的名称(如
- 创建并保存:
- 点击 Create personal access token,GitLab 会生成一个新的 Token。
- 注意:生成的 Token 只会显示一次,请记得保存到安全的地方。
- glpat-FPsLWNSZxss-xGxX5WXh
- 测试 Token:
git clone https://<ACCESS_TOKEN_NAME>:<YOUR_ACCESS_TOKEN>@gitlab.com/<USERNAME>/<REPOSITORY>.gitgit clone http://cicd:glpat-FPsLWNSZxss-xGxX5WXh@172.16.20.24/four_honey/front.git
二、在 Jenkins 中添加 GitLab 个人令牌作为凭据
-
进入 Jenkins 管理界面:
- 打开 Jenkins 的 Web 界面,点击左侧菜单的 Manage Jenkins。
-
打开凭据管理:
- 在 Manage Jenkins 页面,选择 Manage Credentials。
-
选择存储域:
- 选择要存储凭据的域(通常为
Global domain,表示全局可用)。 - 点击 (global) 右侧的 Add Credentials 按钮。
- 选择要存储凭据的域(通常为
-
添加新凭据: 在添加凭据的页面中,完成以下配置:
- Kind:选择 Secret text(因为 GitLab 的 PAT 是一个纯文本的密钥)。
- Secret:将你从 GitLab 获取的个人访问令牌粘贴到这里。
- ID(可选):为该凭据设置一个唯一的 ID(如
gitlab-pat),方便在 Jenkinsfile 或作业中引用。 - Description:为凭据添加描述(如
GitLab Personal Access Token for Jenkins)。
-
保存凭据:
- 点击 OK,保存此凭据。
三、在 Jenkins 中使用 GitLab 个人令牌
凭据添加完成后,你可以在 Jenkins 中的作业或管道中使用它。
1. 在传统 Jenkins Freestyle 作业中使用:
- 在配置 Freestyle 项目时,设置 Git 或 GitLab SCM(Source Code Management)插件。
- 在 Credentials 下拉框中,选择之前添加的 GitLab 个人访问令牌(PAT)凭据。
- 这样,Jenkins 就可以使用该 Token 拉取 GitLab 仓库代码了。
2. 在 Pipeline 脚本中使用:
在 Jenkinsfile 中,通过 withCredentials 函数引用这个凭据,例如:
pipeline {
agent any
stages {
stage('Clone GitLab Repo') {
steps {
withCredentials([string(credentialsId: 'gitlab-pat', variable: 'GITLAB_TOKEN')]) {
sh 'git clone https://gitlab-ci-token:$GITLAB_TOKEN@gitlab.com/username/repo.git'
}
}
}
}
}在此例中:
- 使用
withCredentials将凭据 ID 为gitlab-pat的令牌赋值给环境变量GITLAB_TOKEN。 - 在
sh步骤中使用git clone命令,从 GitLab 上克隆仓库。
3. 使用 Jenkins GitLab Plugin:
- 如果你使用的是 Jenkins 的 GitLab 插件,可以直接在插件配置中选择凭据。大多数 GitLab 插件,如 GitLab Branch Source Plugin 或 GitLab Authentication Plugin,支持选择 Jenkins 的凭据进行身份验证。
总结
- 生成 GitLab 个人访问令牌(PAT),确保拥有正确的访问权限范围(如
api、read_repository等)。 - 在 Jenkins 中添加该令牌为 Secret text 类型的凭据。
- 在 Freestyle 作业或 Pipeline 中使用凭据,通过
withCredentials引用 Token,安全地进行 GitLab 操作。
这样配置完成后,Jenkins 就可以通过安全的方式访问 GitLab 仓库进行各种自动化操作了。
SSH 私钥
在 Jenkins 中添加和使用 SSH 私钥作为凭据,可以让 Jenkins 安全地通过 SSH 访问远程服务器或 Git 仓库。以下是详细步骤,包括如何添加 SSH 私钥凭据以及如何在 Jenkins 作业和管道(Pipeline)中使用它。
一、生成 SSH 私钥(如果还没有)
如果你还没有 SSH 私钥,可以在你的机器上生成一个新的私钥。
-
在本地生成 SSH 密钥对:
在被连接的主机中,使用以下命令生成 SSH 密钥对:
ssh-keygen -t rsa -b 4096 -C "your_email@example.com"-t rsa:指定使用 RSA 算法生成密钥。-b 4096:密钥长度为 4096 位。-C:注释,可填入你的邮箱或描述信息。
生成后,密钥文件通常位于
~/.ssh/目录下,其中id_rsa是私钥,id_rsa.pub是公钥。 -
将公钥添加到远程服务器或 Git 仓库:
- 如果要通过 SSH 访问 Git 仓库(如 GitHub、GitLab),需要将
id_rsa.pub添加到你的 Git 仓库的 SSH keys 配置页面。 - 如果要通过 SSH 访问服务器,需要将
id_rsa.pub添加到远程服务器的~/.ssh/authorized_keys文件中。
- 如果要通过 SSH 访问 Git 仓库(如 GitHub、GitLab),需要将
二、在 Jenkins 中添加 SSH 私钥凭据
-
进入 Jenkins 管理界面:
- 打开 Jenkins 的 Web 界面,点击左侧的 Manage Jenkins。
-
打开凭据管理:
- 在 Manage Jenkins 页面,选择 Manage Credentials。
-
选择存储域:
- 选择要存储凭据的域,通常为
Global,表示全局可用。 - 点击 (global) 右侧的 Add Credentials 按钮。
- 选择要存储凭据的域,通常为
-
添加 SSH 凭据:
在添加凭据的页面中,完成以下配置:
- Kind:选择 SSH Username with private key。
- Scope:选择凭据的作用范围,可以选择全局(
Global)或系统范围(System)。 - Username:输入与你的 SSH 私钥相关联的用户名(通常是远程服务器的用户名,或 Git 仓库的用户名)。
- Private Key:选择 Enter directly,然后粘贴你本地
id_rsa文件中的内容(不要包含.pub公钥,只粘贴私钥部分)。- 如果你的私钥有密码,可以勾选 Passphrase,并输入密码。
- ID(可选):为该凭据设置一个唯一的 ID(如
my-ssh-key),方便在 Jenkinsfile 或作业中引用。 - Description:为凭据添加描述(如
SSH Key for GitHub)。
-
保存凭据:
- 点击 OK,保存此 SSH 凭据。
三、在 Jenkins 中使用 SSH 私钥
1. 在 Freestyle 作业中使用:
-
在配置 Freestyle 作业时,可以通过 Git 或 SSH 相关插件,使用 SSH 凭据。
- 如果使用 Git SCM,选择 Git 作为源代码管理工具。
- 在 Credentials 下拉列表中,选择你刚才添加的 SSH 私钥凭据。
这样 Jenkins 就可以使用 SSH 私钥从 Git 仓库克隆代码了。
2. 在 Pipeline(Jenkinsfile)中使用:
在 Jenkinsfile 中,使用 withCredentials 函数来引用 SSH 私钥。例如:
pipeline {
agent any
stages {
stage('Clone with SSH') {
steps {
withCredentials([sshUserPrivateKey(credentialsId: 'my-ssh-key', keyFileVariable: 'SSH_KEY', usernameVariable: 'USER')]) {
sh '''
echo "Cloning repository using SSH"
GIT_SSH_COMMAND="ssh -i $SSH_KEY" git clone git@github.com:your-repo/your-project.git
'''
}
}
}
}
}在这个例子中:
credentialsId: 'my-ssh-key'指的是你在 Jenkins 中添加的 SSH 私钥凭据的 ID。keyFileVariable: 'SSH_KEY'是 Jenkins 在运行时将 SSH 私钥内容保存到的环境变量。usernameVariable: 'USER'是将用户名保存到的环境变量。GIT_SSH_COMMAND="ssh -i $SSH_KEY"使用了 SSH 私钥来执行git clone操作。
四、使用 SSH 凭据
通过 SSH Agent 插件
https://www.jenkins.io/doc/pipeline/steps/ssh-agent/
https://plugins.jenkins.io/ssh-agent/
pipeline {
agent any
stages {
stage('Test') {
steps {
echo 'Deploying to Nginx server...'
sshagent (credentials: ['ssh_key-172.16.0.123']) {
sh 'scp -r -o StrictHostKeyChecking=no * root@172.16.0.123:'
sh 'ssh -o StrictHostKeyChecking=no root@172.16.0.123 uname -a'
}
}
}
}
}通过 Git 插件
-
Jenkins Git Plugin:
如果你使用 Git 插件来从 Git 仓库拉取代码,Git 插件会自动检测并支持使用 SSH 凭据。只需在配置源码管理时,选择对应的凭据即可。
-
Jenkins SSH Agent Plugin:
在需要通过 SSH 连接远程服务器时,可以使用 SSH Agent Plugin,该插件允许你在构建期间使用 SSH 凭据。以下是一个 Pipeline 使用
ssh-agent插件的例子:pipeline { agent any stages { stage('SSH to Remote Server') { steps { sshagent(['my-ssh-key']) { sh 'ssh -o StrictHostKeyChecking=no user@remote-host "ls -la"' } } } } }在这个例子中:
sshagent(['my-ssh-key']):启动 SSH Agent,并加载 Jenkins 中 ID 为my-ssh-key的 SSH 凭据。sh 'ssh ...':通过 SSH 连接到远程服务器,并执行命令。
总结
- 生成 SSH 私钥:如果没有 SSH 私钥,首先在本地生成一个。
- 添加 SSH 私钥到 Jenkins:在 Jenkins 中通过 SSH Username with private key 类型添加 SSH 凭据,粘贴私钥,并配置相关参数。
- 在作业或 Pipeline 中使用 SSH 凭据:通过 Jenkins 的 Git 插件、
withCredentials函数,或使用ssh-agent插件来安全地使用 SSH 凭据进行 Git 操作或连接远程服务器。
通过这些步骤,你可以安全地使用 SSH 凭据来进行自动化的操作。
—
Credential 概述
https://www.jenkins.io/zh/doc/book/using/using-credentials/
https://www.jenkins.io/doc/book/using/using-credentials/
- 有时候,我们需要在Pipeline中为steps提供凭证,以完成steps中必要的操作步骤,从而避免将敏感信息直接写入pipeline中;
- 例如:当gitlab需要基于ssh协议拉取代码时,就可以配置一个ssh的凭据,最后在pipeline中引用
Credential 类型
Jenkins 支持的凭据包括但不限于以下类型,取决于安装的插件
- 例如:二进制数据,或者更复杂形式的项目,例如OAuth凭据等;
Username with password:用户名和密码,
Github App:
SSH Username with private key:SSH用户名和私钥
Secret file:需要保密的文本文件,保存有Token等信息
Secret text:Token,一串需要保密的文本,例如Github的API Token等;
Certificate:证书
Gitlab API Token:安装 Gitlab 插件后生成的凭据类型
Credential 作用域
凭据的作用域决定了它可用的目标范围;
- 系统:作用于Jenkins系统自身,仅可用于系统和后台任务,且一般用于连接到agent节点之上;
- 全局:作用于Jenkins上的所有任务,以确保任务的正常执行;
- 用户:作用于用户级别,仅生效于Jenkins中的线程代表该用户进行身份验证之时;
Credential 提供者
凭据Provider是指能够存储和获取凭据的地方,它可以Jenkins内部的凭据存储,也可以是外部的凭据库例如:vault
Jenkins共支持如下几个凭据Provider
- 系统凭据Provider:支持系统和全局两个作用域的凭据;
- 用户凭据Provider:用户凭据的存储机制,且每个用户仅能看到自己的凭据;
- 文件夹凭据Provider:文件夹凭据存储,可作用于该文件夹及其子文件夹;
- 默认存放在
$Jenkins_HOME/secrets目录下,默认该目录的权限为700,为了安全起见,目录的权限一定要保持正确
- 默认存放在
- Blue Ocean凭据插件:作用于Blue Ocean接口,以及通过该接口创建或访问的项目;
Credential 配置
系统管理 –> 凭据配置,Jenkins的凭据配置用于定义凭据的提供者和类型
- 提供者:
- 包括选择:明确选定要使用的凭证提供者
- 所有可见
- 排除选择:明确排除不支持使用的凭证提供者
- 类型:
- 包括选择:明确选定要使用的凭证类型
- 所有可见
- 排除选择:明确排除不支持使用的凭证类型
Credential 创建
- ID:如未指定则会生成一个随机ID,通常明确指定ID名称 以便于在pipeline中引用。
Credential Plugin
Credential Binding
https://plugins.jenkins.io/credentials-binding/
https://docs.cloudbees.com/docs/cloudbees-ci/latest/cloud-secure-guide/injecting-secrets
https://docs.cloudbees.com/docs/cloudbees-ci/latest/cloud-secure-guide/injecting-secrets
-
凭据绑定插件,可以实现将凭据绑定到环境变量中,而后可以在steps中引用,该插件默认已经安装;
-
相关语法可以参考片断生成器中的 withCredentials: Bind credentials to variables
-
以Username and password举例:
-
Username and password (separated)
-
用户名变量,例如:USERNAME
-
密码变量,例如:PASSWORD
-
凭据,选择先决条件中创建的凭据
-
-
Username with password
- 需要先创建一个 Username with password 类型的 Credential
// 用户名和密码使用变量名可自行指定,而后,Jenkins都会通过credentialsID从指定的凭证填充用户名和密码
// 最后在控制台的输出结果为USERNAME会正常打印,PASSWORD由于默认加密所以输出结果为*****
pipeline {
agent any
stages {
stage('Test Credentials') {
steps {
withCredentials([usernamePassword(credentialsId: 'azheng-user', passwordVariable: 'PASSWORD', usernameVariable: 'USERNAME')]) { // 需要进行的操作定义在{}中
echo "$USERNAME" // 使用pipeline内置echo时建议使用双引号
sh 'echo $PASSWORD' // 调用shell插件时建议使用单引号
}
}
}
}
}SSH Agent
https://plugins.jenkins.io/ssh-agent/
- 该插件可以实现在pipeline中添加ssh私钥凭据
- 请注意,只能使用基于私钥的凭据。
先决条件
- 创建ssh私钥的凭据
pipeline example
- 相关语法可以参考片断生成器中的 SSHAGENT: SSH Agent
1
- 有待验证
pipeline {
agent any
stages {
stage('Update Source') {
steps {
sshagent(['ssh-private-key-gitlab-user-magedu']) {
sh 'git config user.name iKubernetes'
sh 'git config user.email mage@magedu.com'
sh "git tag –a ${env.BUILD_TAG} –m 'iKubernetes push of tags'"
sh "git push ${sshRepodef} –tags"
}
}
}
}
}2
- ?
steps {
sshagent(credentials: ['ssh-credentials-id']) {
sh '''
[ -d ~/.ssh ] || mkdir ~/.ssh && chmod 0700 ~/.ssh
ssh-keyscan -t rsa,dsa example.com >> ~/.ssh/known_hosts
ssh user@example.com ...
'''
}
}优雅地使用凭证
- 显然,每次调用凭证时都使用withCredentials( )有点过于麻烦;
- 为此,声明式pipeline提供了 credentials helper方法,它允许在environment{}代码段中通过credentials(‘credentialsId’)直接取出凭证并保存于指定的变量中;
pipeline {
agent any
environment {
ding_robot_token = credentials('dingtalk-robot-token')
}
stages {
stage('debug') {
steps {
sh "printenv"
}
}
}
post {
success {
script {
echo "${env.ding_robot_token}"
}
dingTalk accessToken: "${env.ding_robot_token}", imageUrl: '', jenkinsUrl: '', message: 'Build Successfully.', notifyPeople: ''
}
}
}