【问题标题】:Hiding password in Jenkins pipeline script在 Jenkins 管道脚本中隐藏密码
【发布时间】:2017-02-21 15:49:03
【问题描述】:

我正在尝试在我的 Jenkins 构建中隐藏密码。

我一直在尝试the mask-passwords plugin

但是,这似乎不适用于我的 Jenkins 流水线脚本,因为如果我定义密码 PASSWD1,然后在脚本中使用它,例如 ${PASSWD1},我会得到:

No such DSL method '$' found among steps [addToClasspath, ansiColor, ansiblePlaybook, ....]

如果我使用env.PASSWD1,那么它的值将被解析为null

那么我应该如何在 Jenkins 流水线脚本中屏蔽密码?

【问题讨论】:

  • 你能展示更多你的管道脚本吗? ${PASSWD1} 语法仅适用于双引号字符串。或者你应该使用PASSWD1env.PASSWD1。虽然这与 Mask Passwords 插件无关。虽然这个问题听起来很相关:issues.jenkins-ci.org/browse/JENKINS-41955
  • 我也尝试过使用env.PASSWD1。我更新了我的问题。

标签: jenkins jenkins-pipeline


【解决方案1】:

最简单的方法是使用Credentials Plugin

您可以在此处定义不同类型的凭据,无论是单个密码(“秘密文本”)、文件还是用户名/密码组合。此外,其他插件可以提供其他类型的凭据。

当您创建凭证时(通过 Jenkins 主页上的凭证链接),请确保您设置了“ID”。在下面的示例中,我将其命名为my-pass。如果你不设置它,它仍然可以工作,Jenkins 会为你分配一个不透明的 UUID。

无论如何,您都可以使用snippet generator 轻松生成所需的语法。

withCredentials([string(credentialsId: 'my-pass', variable: 'PW1')]) {
    echo "My password is '${PW1}'!"
}

这将使密码仅在此块内的给定变量中可用。如果您尝试打印密码,就像我在这里所做的那样,它将被屏蔽。

【讨论】:

  • 谢谢!如果我只是尝试打印密码,这将有效。但是,我也进行了 API 调用:httpRequest myUrl。这将打印HttpMode: GET URL: myUrl,而这一次,在myUrl 中,密码是纯文本的。知道如何防止这种情况发生吗?
  • @octavian 你在用HTTP Request Plugin?。您可以在“授权”标头(在日志中被屏蔽)而不是 URL 中传递凭据。
  • 那么如果你想将多个变量传递到同一个阶段呢?
【解决方案2】:

看到这个问题,https://issues.jenkins-ci.org/browse/JENKINS-27392,你应该可以做到以下几点:

node {
    wrap([$class: 'MaskPasswordsBuildWrapper', varPasswordPairs: [[password: '123ADS', var: 'SECRET']]]) {
        echo env['SECRET'];
    }
}

但是,如果您查看该问题中的最后一个 cmets,它不起作用,似乎是一个错误。但是,如果您知道秘密并在日志中意外打印了 int ,则它会被隐藏,如下所示:

node {
        wrap([$class: 'MaskPasswordsBuildWrapper', varPasswordPairs: [[password: '123ADS', var: 'SECRET']]]) {
        echo "123ADS";
    }
}

这会产生:

[Pipeline] node
Running on master in workspace/pl
[Pipeline] {
[Pipeline] wrap
[Pipeline] {
[Pipeline] echo
********
[Pipeline] }
[Pipeline] // wrap
[Pipeline] }
[Pipeline] // node
[Pipeline] End of Pipeline
Finished: SUCCESS

关于你得到的错误,No such DSL method '$' found among steps ...,我只是猜测,但你可能直接在管道脚本中使用${VAR}${...} 仅与 groovy 中的字符串内部相关。

编辑: 或者您可以使用Credentails Plugin 和管道步骤withCredentials

// Credential d389273c-03a0-45af-a847-166092b77bda is set to a string secret in Jenkins config.
node {
    withCredentials([string(credentialsId: 'd389273c-03a0-45af-a847-166092b77bda', variable: 'SECRET')]) {
        bat """
if ["${SECRET}"] == ["123ASD"] echo "Equal!"
""";
    }
}

这会导致:

[Pipeline] node
Running on master in workspace/pl
[Pipeline] {
[Pipeline] withCredentials
[Pipeline] {
[Pipeline] bat
[pl] Running batch script

workspace/pl>if ["****"] == ["****"] echo "Equal!" 
"Equal!"
[Pipeline] }
[Pipeline] // withCredentials
[Pipeline] }
[Pipeline] // node
[Pipeline] End of Pipeline
Finished: SUCCESS

请注意,此插件将变量直接绑定到闭包,而不是其他环境,例如我可以直接使用变量SECRET

【讨论】:

  • 您也在纯文本的脚本中显示密码:password: '123ADS',对吧?我也不希望它出现在脚本中。它应该存储在 Jenkins 的某个地方,在某个 Credentials 字段中,加密。
  • 我认为您可以使用Mask Passwords Plugin 设置系统范围的密码,我只是在本地使用它作为一个完整的示例
  • 既然env.PASSWD1 被解析为null,用wrap([$class: 'MaskPasswordsBuildWrapper', varPasswordPairs: [[password: '123ADS', var: 'SECRET']]]) { 包装我的代码是行不通的,对吧?我的意思是它仍然无法解决,不是吗?
  • Doh,对,我的错,你,也许可以使用withCredentials 步骤。我会看看我是否可以修复一个例子。
  • 考虑您有密码并需要通过 curl 作为 base64 发送密码的情况。然后 Jenkins 不会将 base64 视为密码,也不会隐藏其值。或者构建代理通过环境变量注入密码的情况。也许它在轮换,每 30 分钟更换一次。您不希望那个出现在日志中。需要有一种方法告诉 Jenkins 一些随机字符串是需要隐藏在日志中的密码。
猜你喜欢
  • 1970-01-01
  • 2013-04-16
  • 2010-10-10
  • 1970-01-01
  • 1970-01-01
  • 2016-03-24
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多