1.1 为什么要使用凭据?

在我们配置持续交付流水线的过程中会与第三方的系统交互。例如:Jira、GitLab、SonarQube等等工具。平时我们在设置第三方系统的认证信息的时候是明文配置的,这样非常不安全,建议使用Jenkins凭据来存储使用。Jenkins的凭据管理是通过Credentials Binding插件实现的,所以在使用前请确保插件已经安装了。

接下来我们演示凭据的使用:进入系统管理> 凭据管理

新Jenkins实践-第5章 Pipeline数据脱敏-Jenkins系统凭据管理_第1张图片

在这里,你将看到系统中的所有的可用的凭据,默认是空的。现实生活中我们每个人都有一个唯一的身份证号码,凭据也具有一个唯一的ID,我们后续在流水线中通过凭据的ID来读取对应的凭据。凭据ID很重要,可以自己定义。

新Jenkins实践-第5章 Pipeline数据脱敏-Jenkins系统凭据管理_第2张图片

1.2 凭据的类型

凭据其实也是可以划分多个作用域的,默认是全局作用域。 我们进入全局作用域,然后可以添加凭据。 添加凭据的时候我们可以选择凭据类型、凭据内容、凭据ID、凭据描述。

Jenkins中凭据支持的类型偏多,用法都比较类似所以这里列举常用的凭据类型:

  • Secret text: 存放一些API Token,类似于GitLab Personal Token等等。
  • Username and password:存放用户名和密码类型的凭据,例如:GitLab管理员的账号密码。
  • SSH Username with private key: 存放一个SSH认证秘钥信息。

我们来创建一个Secret text 类型的凭据。这里的凭据主要用来存放第三方系统交互的API Token。 我在这里就随便写一个token 了。注意大家在写的时候要以实际为准。

新Jenkins实践-第5章 Pipeline数据脱敏-Jenkins系统凭据管理_第3张图片

变量的作用域: System只能由Jenkins系统中访问,例如:插件。 Global是全局的在System的基础上也可以供Job访问。 是保存后就能看到我们的凭据了。

新Jenkins实践-第5章 Pipeline数据脱敏-Jenkins系统凭据管理_第4张图片


1.3 jenkins 如何存储凭据?

Jenkins的凭据加密存储用到了三个文件:credentials.xml文件里面存储的是加密后的凭据。 master.key纯文本格式存储的key。 hudson.util.Secret二进制文件加密文件。(这里暂时不研究凭据的加密过程)

$JENKINS_HOME/credentials.xml 
$JENKINS_HOME/secrets/master.key
$JENKINS_HOME/secrets/hudson.util.Secret

获取所有的凭据ID。

# cat credentials.xml | grep ""
192.168.1.200-ssh-users
jenkins-ssh-user
gitlab-api-token


  
    
      
        
      
      
        .........

        
          GLOBAL
          gitlab-api-token
          gitlab-api-token
          {AQAAABAAAAAQkZVQA/LNTRYnWBibiMI4hFjO2HcNNME8jkDLA/kGVEc=}
        

        ...........

      
    
  

凭据内容是加密的,如果忘记了怎么办呢?我们具有管理员权限是可以根据secret解密的。这里简单演示一下,我通常如果忘记了凭据的内容,我会这样做的。 在Script Console,输入一下语句。

println hudson.util.Secret.decrypt("{AQAAABAAAAAQkZVQA/LNTRYnWBibiMI4hFjO2HcNNME8jkDLA/kGVEc=}")

新Jenkins实践-第5章 Pipeline数据脱敏-Jenkins系统凭据管理_第5张图片

如果你想把所有的凭据内容解密,推荐可以使用工具jenkins-credentials-decryptor解密。此工具的项目地址:https://github.com/hoto/jenkins-credentials-decryptor/releases/download/0.0.8/jenkins-credentials-decryptor_0.0.8_Linux_x86_64

cd ${JENKINS_HOME}
mv jenkins-credentials-decryptor_0.0.8_Linux_x86_64 jenkins-credentials-decryptor

chmod +x jenkins-credentials-decryptor

./jenkins-credentials-decryptor \
-m ./secrets/master.key \
-s ./secrets/hudson.util.Secret \
-c ./credentials.xml 

##### 输入#######3
0
    scope=GLOBAL
    id=192.168.1.200-ssh-users
    description=192.168.1.200-ssh-users
    username=root
    password=123456
1
    privateKeySource=
    scope=GLOBAL
    id=jenkins-ssh-user
    description=jenkins-ssh-user
    username=root
2
    scope=GLOBAL
    id=gitlab-api-token
    description=gitlab-api-token
    secret=aaaaaabbbbbbb

1.4 项目中使用凭据

为了最大程度地提高安全性,在Jenkins中配置的凭据以加密形式存储在主Jenkins实例上(由Jenkins实例ID加密),并且仅在Pipeline项目中通过其凭据ID进行使用。这最大程度地减少了将实际凭证本身暴露给Jenkins用户的机会。

在涉及到代码下载的时候需要用到凭据

新Jenkins实践-第5章 Pipeline数据脱敏-Jenkins系统凭据管理_第6张图片

在参数化构建项目中添加凭据参数

新Jenkins实践-第5章 Pipeline数据脱敏-Jenkins系统凭据管理_第7张图片

Credentials As Code

由于我们目前还没有学习到Jenkins pipeline项目,所以这里先做为了解,后续对你一定有用的。我们先随便创建一个流水线类型的项目。然后选择流水线语法, 进入片段生成器

新Jenkins实践-第5章 Pipeline数据脱敏-Jenkins系统凭据管理_第8张图片

点击新增,选择要使用的凭据。这种情况我们是把凭据作为值赋给了变量,所以在这里定义一个变量名称,然后后续在流水线中使用此变量引用凭据的内容。

新Jenkins实践-第5章 Pipeline数据脱敏-Jenkins系统凭据管理_第9张图片

选择好凭据之后,我们开始点击生成流水线脚本。 最后生成了如下的代码块。some block是一些语句块。

withCredentials([string(credentialsId: 'gitlab-api-token', variable: 'gitUsers')]) {
    // some block
}

好了,现在基本上你已经掌握了如何生成凭据代码块。接下来我们写个简单的demo来测试一下。这个模板是通用的,可以复制哦。

pipeline {
    agent any

    stages {
        stage('Hello') {
            steps {
                echo 'Hello World'
                withCredentials([string(credentialsId: 'gitlab-api-token', variable: 'gitUsers')]) {
    // some block

    println(gitUsers)
}
            }
        }
    }
}

运行作业,检查日志会发现Jenkins试图通过查找密钥值并将其替换为星号来从构建日志中显示。

新Jenkins实践-第5章 Pipeline数据脱敏-Jenkins系统凭据管理_第10张图片

这里注意下,我们以使用变量的方式打印它们,便可以看到实际的秘密值。这样,每个字符将单独打印。所以这里要严格把控流水线的编辑权限,否则还是会造成秘钥泄露。

print 'gitUsers.collect { it }=' + gitUsers.collect { it }

新Jenkins实践-第5章 Pipeline数据脱敏-Jenkins系统凭据管理_第11张图片

这里我们来展示一个操作GitLab系统的参考实例,这个实例就是后续我们在共享库中定义的内容。

//封装HTTP请求
def HttpReq(reqType,reqUrl,reqBody){
    def gitServer = "http://192.168.1.200:30088/api/v4"
    withCredentials([string(credentialsId: 'gitlab-token', variable: 'gitlabToken')]) {
      result = httpRequest customHeaders: [[maskValue: true, name: 'PRIVATE-TOKEN', value: "${gitlabToken}"]], 
                httpMode: reqType, 
                contentType: "APPLICATION_JSON",
                consoleLogResponseBody: true,
                ignoreSslErrors: true, 
                requestBody: reqBody,
                url: "${gitServer}/${reqUrl}"
                //quiet: true
    }
    return result
}

今天我们分享了Jenkins的凭据管理,通过凭据管理可以对流水线中与第三方系统交互需要配置的认证信息加密存储。便于对流水线中数据脱敏。但是jenkins的凭据管理还是存在一些安全漏洞问题,如果允许最好将秘钥信息存储在外围系统中。我们不创建秘密,它们就不会泄漏。后续我们继续分享Jenkins系统中的权限管理。

Jenkins基础部分最后一篇公开的博文了,后续系列博文仅对Jenkins课程学员提供,如果有需要请大家可以支持下今天刚刚推出的DevOps教程,感谢支持!

DevOps流水线实践教程已上线,需要的同学可以点击链接获取哦。

https://edu.51cto.com/sd/36f6e