【问题标题】:Travis CI: How do I escape my password for `travis encrypt` to work?Travis CI:如何转义密码以使“travis encrypt”正常工作?
【发布时间】:2019-02-05 15:52:43
【问题描述】:

travis encryption docs 提到我必须在加密之前对密码进行 bash 转义:

转义某些符号的注意事项

当您使用 travis encrypt 加密敏感数据时,需要注意的是,它将作为 bash 语句处理。这意味着当 bash 解析它时,您正在加密的秘密不应导致错误。数据不完整会导致 bash 将错误语句转储到日志中,其中包含部分敏感数据。

因此,您需要转义特殊字符,例如大括号、圆括号、反斜杠和管道符号。例如,当你要将字符串6&a(5!1Ab\赋值给FOO时,需要执行:

travis encrypt "FOO=6\\&a\\(5\\!1Ab\\\\"

bash 的答案似乎围绕printf "%q" 展开,但要弄清楚如何将printftravis cli 连接起来仍然太复杂了。

travis encrypt 做它应该做的事情是什么?

我的意思是,我想粘贴我的变量名和它的值,并确保它会被正确加密,而不必担心 bash 转义。我们可以继续使用上面的示例,假设我想将字符串 6&a(5!1Ab\ 分配给变量 FOO

当我们讨论这个问题时,travis env set 对应的单行代码是什么?这将有助于那些与data too large 错误作斗争的人。

【问题讨论】:

  • 我认为您需要的只是printf -v esc_foo '%q' "$foo",现在esc_foo 包含正确转义的字符串
  • "Processed as a bash statement" 让我觉得它只是在参数上调用eval,这意味着我会考虑很长时间才能使用它根本.
  • 另外,为什么他们会建议反斜杠出没的噩梦而不是travis encrypt "FOO='6&a(5!1Ab\'"
  • 非常感谢@Inian。

标签: bash escaping travis-ci


【解决方案1】:

基于Armali's answer

read -r && travis encrypt "$(printf %q "$REPLY")"

然后粘贴您的变量及其值:

FOO=6&a(5!1Ab\

【讨论】:

    【解决方案2】:

    travis encrypt 做它应该做的事情是什么?

    我的意思是,我想粘贴我的变量名及其值,并确保它会被正确加密,而不必担心 bash 转义。

    这一般是不可能的,因为如果要在命令行中插入值,某种引用是必不可少的,因此至少有一个引用字符(如果允许出现在值中)必须特殊处理,不能简单粘贴进去;这就是为什么如果 ' 出现在值中(当然' 应该允许在密码中),将值包含在 ' ' 中不起作用的原因。因此,只有当 one-liner 的要求被删除并且值作为输入提供时,才能满足能够粘贴值的要求。
    然后,由于travis encrypt 命令需要额外引用参数(也许是因为,正如 chepner 所认为的,eval 被调用),我们可以使用printf %q 提供此引用,例如。 G。

    read -r
    6&a(5!1Ab\
    travis encrypt "$(printf %q "FOO=$REPLY")"
    
    (要粘贴的粗线)。

    VAR=VALUE 放在read 语句中以将所有内容放在一起怎么样? read -r,粘贴FOO=6&a(5!1Ab\ ,最后粘贴travis encrypt "$(printf %q "$REPLY")"

    当然也可以。

    此外,真的没有办法将read -r 的结果传递给travis encrypt吗?

    如果你的意思是字面上的管道,那么不,没有办法将某些东西通过管道传递给只需要参数的命令。但是如果你只是想知道我们是否可以连接命令,那么是的,我们也可以写 e。 G。

    read -r; travis encrypt "$(printf %q "$REPLY")"
    FOO=6&a(5!1Ab\
    

    【讨论】:

    • 非常感谢!将VAR=VALUE 放在read 语句中以将所有内容放在一起怎么样? read -r,粘贴FOO=6&a(5!1Ab\ ,最后粘贴travis encrypt "$(printf %q "$REPLY")"。此外,真的没有办法将read -r 的结果传递给travis encrypt
    • &&链接语句怎么样?那将是:read -r && travis encrypt "$(printf %q "$REPLY")",然后粘贴FOO=6&a(5!1Ab\ 。这将满足我的单线要求。我有什么遗漏吗?
    • @Pierre F - 我刚刚将您第一条评论中的问题纳入我的回答中。你使用&& 的想法比我的; 还要好。
    • 感谢@Armali 的更新。关于您关于特别处理引用字符的论点:即使该行包含字符",此解决方案是否总是有效,还是我们需要再次转义该字符以确保安全?
    • @Pierre F - 这也适用于",因为包含的引号在$REPLY 的扩展过程中不会被解释,然后像其他特殊字符一样被printf %q 转义。
    【解决方案3】:

    在构建中仅对字符串进行 base64 解码并对其进行解码要容易得多。通过 travis 中的转义,省去了所有的麻烦。

    Travis 和任何其他 CI/CD 服务允许秘密存储环境变量以供每次构建使用。在为您的项目构建设置时,添加环境变量选项。要在 cli 中回显用于 base64 的密码,您仍然需要转义字符串,因为它需要由 bash 评估。使用您的密码创建一个临时文件。那么:

    cat /tmp/secret | base64 -w 0

    复制字符串并将其粘贴到 travis ci env var 设置的值字段中

    .travis.yaml 文件中简单地检索秘密:

    echo $SECRET | base64 -d

    虽然可能存在边缘情况,但这应该可以解决大多数用例。

    【讨论】:

    • 这也是个不错的主意,谢谢。我猜这个答案对于其他使用相应命令的堆栈溢出用户会更有用:How to base64-encode & encrypt in the command-line, and how to decrypt & base64-decode the environment variable in .travis.yml跨度>
    • 感谢您使用base64 命令更新答案。我不确定如何使用它,例如加密一个像部署密码一样直接使用的变量。有了 Armali 的回答,你可以直接travis encrypt --add deploy.password
    猜你喜欢
    • 1970-01-01
    • 2018-06-16
    • 2013-01-11
    • 2016-11-08
    • 1970-01-01
    • 1970-01-01
    • 2018-11-22
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多