在不使用 WithCredentials 的情况下隐藏 Jenkins Pipeline 日志输出中的密码
Hiding passwords in Jenkins Pipeline log output without using WithCredentials
我有一个基于 Jenkinsfile
的参数化 Jenkins 管道。一些参数包含我不想出现在作业的构建日志中的敏感密码。
所以我的问题是:我能否以某种方式在 Jenkinsfile
中注册一个字符串,然后在它出现在日志输出中时替换为 **********
?
我知道 withCredentials
步骤,但我无法使用它,因为凭证未存储在 Jenkins 凭证存储中(但在运行时作为参数提供)。
我在这里 找到了这个答案并尝试了这个:
def secrets = [
[password: firstPassword, var: 'SECRET'],
[password: secondPassword, var: 'SECRET'],
[password: thirdPassword, var: 'SECRET']
]
node() {
wrap([$class: 'MaskPasswordsBuildWrapper', varPasswordPairs: secrets]) {
// my stages containing steps...
}
}
其中 firstPassword
、secondPassword
、thirdPassword
是包含我的密码的变量。但我仍然得到 firstPassword
的内容...在日志输出中显示纯文本。
我在我的 Jenkins 2.12.0 版本中安装了 Mask Password plugin。
基本上我正在搜索这样的东西:https://issues.jenkins-ci.org/browse/JENKINS-27486 - 票已解决,但没有给出最终实施的示例片段。
我想你在找 JENKINS-36007?
你可以看看https://github.com/jenkinsci/log-file-filter-plugin
此插件允许通过正则表达式过滤 Jenkins 的控制台输出。如果某些模式匹配,则匹配的字符串将替换为可以为配置中的每个模式指定的字符串。
目前该插件不支持从 jenkinsfile 添加过滤模式,只能从 Jenkins 全局设置添加。
实际上我不知道为什么这首先不起作用,但这是问题的解决方案。
定义一个包含要隐藏的秘密的数组:
def splunkPassword = 'verySecretPa55w0rd'
def basicAuthPassword = 'my8asicAuthPa55w0rd'
def getSecrets() {
[
[password: splunkPassword, var: 'SECRET'],
[password: basicAuthPassword, var: 'SECRET']
]
}
免责声明:我不知道 SECRET
值是否有重要作用,从一些片段中复制并粘贴它,它按预期工作:)
之后,您可以像这样在脚本管道中包装任何调用:
node {
wrap([$class: 'MaskPasswordsBuildWrapper', varPasswordPairs: getSecrets()]) {
stage 'First Stage' { ... }
stage 'Second Stage' { ... }
}
}
getSecrets()
数组中提供的所有密码将在您的构建输出中像这样被屏蔽:
SPLUNK_PASSWORD: ********
BASIC_AUTH_ADMIN_PASSWORD: ********
非常残酷的解决方法。
编写一个简单的脚本,例如bash,并将参数凭据回显到某个任意格式的文件中,直至您的回显方法。
例如基本 shell 脚本:
$ cat executor/obfuscate.sh
#!/bin/bash
echo "PASSWORD: ${AWX_PW}" > ./executor/credential.yml
然后在您的管道中:
stages {
stage('Placing') {
steps {
**sh './executor/obfuscate.sh'** }
[...]
< something reading credential.yml>
}
}
结果,控制台中没有显示任何内容:
2020 年 5 月 26 日更新
下面的解决方法最近对我不起作用。我的猜测是最近的 Jenkins 更新发生了一些变化。我试图避免安装另一个插件,但我最终放弃并安装了 Mask Passwords plugin.
我使用以下语法与参数一起使用:
parameters {
string(name: 'USERNAME', defaultValue: '', description: 'Username')
password(name: 'PASSWORD', defaultValue: '', description: 'Password')
}
然后在构建阶段:
steps {
script {
wrap([$class: 'MaskPasswordsBuildWrapper',
varPasswordPairs: [
[password: "${USERNAME}", var: 'USR'],
[password: "${PASSWORD}", var: 'PSW']
]
]) {
sh '''
echo "Username: ${USERNAME}"
echo "Password: ${PASSWORD}"
'''
}
}
}
下面是最初的解决方法,以防其他人尝试走同样的路。
我发现了一个变通方法,它有点麻烦,但似乎运行良好。诀窍是使用 withCredentials
,但用参数覆盖变量。
这是一个示例,它使用 environment 指令的 credentials()
辅助方法来填充环境变量,然后覆盖自动定义(并在日志中屏蔽)的两个附加环境变量。
首先,创建一个虚拟 Username with password
凭据。 Username
和 Password
值无关紧要,我们只需要一个 Credential 用作占位符。输入一个 ID,例如 dummy-credentials
.
然后使用虚拟凭据定义环境变量,并使用参数覆盖自动定义的变量(本例中为 MYUSERNAME
和 MYPASSWORD
):
environment {
MY_CREDS = credentials('dummy-credentials')
MY_CREDS_USR = "${params.MYUSERNAME}"
MY_CREDS_PSW = "${params.MYPASSWORD}"
}
在需要引用机密的任何地方使用 MY_CREDS_USR
和 MY_CREDS_PSW
环境变量。它们的内容将在控制台日志中被屏蔽。
sh '''
echo "Username: ${MY_CREDS_USR}"
echo "Password: ${MY_CREDS_PSW}"
'''
我有一个基于 Jenkinsfile
的参数化 Jenkins 管道。一些参数包含我不想出现在作业的构建日志中的敏感密码。
所以我的问题是:我能否以某种方式在 Jenkinsfile
中注册一个字符串,然后在它出现在日志输出中时替换为 **********
?
我知道 withCredentials
步骤,但我无法使用它,因为凭证未存储在 Jenkins 凭证存储中(但在运行时作为参数提供)。
我在这里
def secrets = [
[password: firstPassword, var: 'SECRET'],
[password: secondPassword, var: 'SECRET'],
[password: thirdPassword, var: 'SECRET']
]
node() {
wrap([$class: 'MaskPasswordsBuildWrapper', varPasswordPairs: secrets]) {
// my stages containing steps...
}
}
其中 firstPassword
、secondPassword
、thirdPassword
是包含我的密码的变量。但我仍然得到 firstPassword
的内容...在日志输出中显示纯文本。
我在我的 Jenkins 2.12.0 版本中安装了 Mask Password plugin。
基本上我正在搜索这样的东西:https://issues.jenkins-ci.org/browse/JENKINS-27486 - 票已解决,但没有给出最终实施的示例片段。
我想你在找 JENKINS-36007?
你可以看看https://github.com/jenkinsci/log-file-filter-plugin
此插件允许通过正则表达式过滤 Jenkins 的控制台输出。如果某些模式匹配,则匹配的字符串将替换为可以为配置中的每个模式指定的字符串。
目前该插件不支持从 jenkinsfile 添加过滤模式,只能从 Jenkins 全局设置添加。
实际上我不知道为什么这首先不起作用,但这是问题的解决方案。
定义一个包含要隐藏的秘密的数组:
def splunkPassword = 'verySecretPa55w0rd'
def basicAuthPassword = 'my8asicAuthPa55w0rd'
def getSecrets() {
[
[password: splunkPassword, var: 'SECRET'],
[password: basicAuthPassword, var: 'SECRET']
]
}
免责声明:我不知道 SECRET
值是否有重要作用,从一些片段中复制并粘贴它,它按预期工作:)
之后,您可以像这样在脚本管道中包装任何调用:
node {
wrap([$class: 'MaskPasswordsBuildWrapper', varPasswordPairs: getSecrets()]) {
stage 'First Stage' { ... }
stage 'Second Stage' { ... }
}
}
getSecrets()
数组中提供的所有密码将在您的构建输出中像这样被屏蔽:
SPLUNK_PASSWORD: ********
BASIC_AUTH_ADMIN_PASSWORD: ********
非常残酷的解决方法。
编写一个简单的脚本,例如bash,并将参数凭据回显到某个任意格式的文件中,直至您的回显方法。
例如基本 shell 脚本:
$ cat executor/obfuscate.sh
#!/bin/bash
echo "PASSWORD: ${AWX_PW}" > ./executor/credential.yml
然后在您的管道中:
stages {
stage('Placing') {
steps {
**sh './executor/obfuscate.sh'** }
[...]
< something reading credential.yml>
}
}
结果,控制台中没有显示任何内容:
2020 年 5 月 26 日更新
下面的解决方法最近对我不起作用。我的猜测是最近的 Jenkins 更新发生了一些变化。我试图避免安装另一个插件,但我最终放弃并安装了 Mask Passwords plugin.
我使用以下语法与参数一起使用:
parameters {
string(name: 'USERNAME', defaultValue: '', description: 'Username')
password(name: 'PASSWORD', defaultValue: '', description: 'Password')
}
然后在构建阶段:
steps {
script {
wrap([$class: 'MaskPasswordsBuildWrapper',
varPasswordPairs: [
[password: "${USERNAME}", var: 'USR'],
[password: "${PASSWORD}", var: 'PSW']
]
]) {
sh '''
echo "Username: ${USERNAME}"
echo "Password: ${PASSWORD}"
'''
}
}
}
下面是最初的解决方法,以防其他人尝试走同样的路。
我发现了一个变通方法,它有点麻烦,但似乎运行良好。诀窍是使用 withCredentials
,但用参数覆盖变量。
这是一个示例,它使用 environment 指令的 credentials()
辅助方法来填充环境变量,然后覆盖自动定义(并在日志中屏蔽)的两个附加环境变量。
首先,创建一个虚拟 Username with password
凭据。 Username
和 Password
值无关紧要,我们只需要一个 Credential 用作占位符。输入一个 ID,例如 dummy-credentials
.
然后使用虚拟凭据定义环境变量,并使用参数覆盖自动定义的变量(本例中为 MYUSERNAME
和 MYPASSWORD
):
environment {
MY_CREDS = credentials('dummy-credentials')
MY_CREDS_USR = "${params.MYUSERNAME}"
MY_CREDS_PSW = "${params.MYPASSWORD}"
}
在需要引用机密的任何地方使用 MY_CREDS_USR
和 MY_CREDS_PSW
环境变量。它们的内容将在控制台日志中被屏蔽。
sh '''
echo "Username: ${MY_CREDS_USR}"
echo "Password: ${MY_CREDS_PSW}"
'''