【问题标题】:How to test a git-crypt encrypted repo with Jenkins如何使用 Jenkins 测试 git-crypt 加密仓库
【发布时间】:2020-05-25 06:23:43
【问题描述】:

我在我的仓库中使用 Jenkins(多分支管道)运行的测试通过 git-crypt 使用其中的加密文件 (keys.py)。为了在本地使用该文件,我通常使用git-crypt unlock,但由于该命令的工作方式,我无法直接将此步骤添加到 Jenkinsfile:

  1. gpg 用于解密用于加密我的文件的对称密钥(即.git-crypt/keys/default/0/xxxx.gpg)。此密钥使用我的私钥通过 RSA 加密,并且此密钥有一个密码,您在尝试使用它时会提示输入该密码。
  2. 使用解密的密钥解密keys.py

【问题讨论】:

    标签: jenkins encryption jenkins-pipeline


    【解决方案1】:

    要解决提示问题,请运行git-crypt 步骤手动插入 您的密码作为gpg 的命令行参数和解密的对称 git-crypt unlock 的密钥。在这里,我们使用了更多的技巧,将 像使用 Jenkins environment variables 一样轻松生活。

    gpg --no-tty --passphrase YOUR_PASSPHRASE_GOES_HERE --output $WORKSPACE/.git-crypt/keys/default/0/decrypted.gpg --decrypt $WORKSPACE/.git-crypt/keys/default/0/YOUR_KEY_FILE_GOES_HERE.gpg && git-crypt unlock $WORKSPACE/.git-crypt/keys/default/0/decrypted.gpg

    这里我们提出了第二个问题,就是执行两次会引发一个 错误也是如此。我们希望 repo 仅在加密时才被解密。在 为了解决这个问题,首先检查包含对称密钥的文件 存在,仅在上一步中生成。最后,我们得到一个 看起来像这样的阶段:

    stage('Unlock repo') { steps { script { sh("[ -f $WORKSPACE/.git-crypt/keys/default/0/decrypted.gpg ] || gpg --no-tty --passphrase YOUR_PASSPHRASE_GOES_HERE --output $WORKSPACE/.git-crypt/keys/default/0/decrypted.gpg --decrypt $WORKSPACE/.git-crypt/keys/default/0/YOUR_KEY_FILE_GOES_HERE.gpg && git-crypt unlock $WORKSPACE/.git-crypt/keys/default/0/decrypted.gpg") } } }

    【讨论】:

    • 我觉得这个解决方案有点难看,因为它可以工作,但在 Jenkinsfile 中包含了我的私钥的密码,它作为明文上传到 git 存储库,以及它检查是否执行的方式unlock 看起来很冗长,有点不可读。如果有人有比这更好的想法,请贡献!
    • 使用 jenkins 秘密文本凭据,您可以混淆密码和密钥文件名,因为除非您更改它们,否则它们不应更改。
    【解决方案2】:

    我已经为 git-crypt 构建了另一个解决方案,方法是使用 git-crypt 创建一个单独的容器,并在主要构建步骤之前和之后分阶段调用它们:

    pipeline {
        environment {
           // $HOME is not set in build-agent
           JAVA_TOOL_OPTIONS = '-Duser.home=/home/jenkins/'
        }
        agent {
            label 'docker'
        }
    
        stages {
            stage('Decrypt') {
                agent {
                    docker {
                        image 'wjung/jenkins-git-crypt:latest'
                        registryUrl 'https://index.docker.io/v1/'
                        registryCredentialsId 'docker-hub'
                    }
                }
                steps {
                    withCredentials([file(credentialsId: 'git-crypt-key', variable: 'FILE')]) {
                        sh 'cd $WORKSPACE; git-crypt unlock $FILE'
                    }
                }
            }
            stage('Build docker image') {
                agent {
                    docker {
                        image 'maven:3-jdk-11'
                        args '-v /services/maven/m2:/home/jenkins/.m2 -v /services/maven/m2/cache:/home/jenkins/.cache'
                    }
                }
                steps {
                    configFileProvider([configFile(fileId: 'mvn-setting-xml', variable: 'MAVEN_SETTINGS')]) {
                        sh 'mvn -s $MAVEN_SETTINGS -B -Dmaven.test.skip clean deploy'
                    }
                }
            }
            stage('Lock dir') {
                agent {
                    docker {
                        image 'wjung/jenkins-git-crypt:latest'
                        registryUrl 'https://index.docker.io/v1/'
                        registryCredentialsId 'docker-hub'
                    }
                }
                steps {
                    sh 'cd $WORKSPACE; git-crypt lock'
                }
            }
        }
    }
    

    加密密钥由 git-crypt export-key TMPFILE 从存储库中导出,后来添加为秘密文件,ID 为:git-crypt-key

    【讨论】: