【问题标题】:Vault: enabling unauthenticated "public" resourcesVault:启用未经身份验证的“公共”资源
【发布时间】:2020-09-30 18:39:28
【问题描述】:

我正在创建一个用于签署 JWT 的传输 RSA 密钥,并希望将此策略提供给任何可以连接到保管库实例的调用者,无需身份验证(假设 TLS 已经在所有客户端上运行)。

path "transit/keys/jwt-signing" {
  capabilities = ["read"]
}

需要什么样的策略和身份验证后端组合来模拟保险库中标准 pki 机密引擎管理的某些端点中的行为?

取自https://www.vaultproject.io/api-docs/secret/pki#read-ca-certificate


»读取 CA 证书

此端点以 PEM 格式检索 CA 证书 [...]。

这是一个未经身份验证的端点。 [强调我的]

»样品请求

$ curl \
   http://127.0.0.1:8200/v1/pki/ca/pem

我想以类似的方式公开我的签名令牌的公共部分,以在 API 中构造一个典型的 .well-known/jkws 端点。

【问题讨论】:

    标签: hashicorp-vault hcl


    【解决方案1】:

    保管库不支持完全未经身份验证的访问。令牌从根本上与保险库向最终用户(包括运营商)公开的方式相关联。

    没有办法绕过它,最终结果中将涉及令牌,因此令牌到期,撤销和更新。使用a periodic token 是最简单的方法。


    »定期令牌

    在某些情况下,撤销令牌会在很长一段时间内出现问题 [...]。在这种情况下,可以使用周期性令牌。可以通过以下几种方式创建周期性令牌:

    1. 由 [...] 带有auth/token/create 端点的根令牌

    [...] 只要令牌在这些时间段内成功更新,它就永远不会过期。除了根令牌之外,这是目前 Vault 中令牌拥有无限生命周期的唯一方式


    鉴于将为此使用根令牌,创建令牌包括“公共”访问的最后一个生活质量功能,即set the token id of a created token 的能力。


    »创建令牌

    创建一个新的令牌。某些选项只有在被根令牌调用时才可用

    »参数

    • id (string: "") – 客户端令牌的 ID。 只能由根令牌指定。提供的 ID 可能不包含 . 字符。否则,令牌 ID 是随机生成的值。

    创建令牌时,它需要附加一个策略,否则它会继承创建它的令牌的范围。对于根令牌,这是不可取的。创建策略并将其绑定到令牌包括 a special built-in policy to simplify token lifecycle tasks, the default token policy


    »默认策略

    默认策略是无法删除的内置 Vault 策略。默认情况下,它附加到所有令牌,但可以通过支持身份验证方法在令牌创建时明确排除

    [...]

    要查看您的 Vault 安装的默认策略授予的所有权限,请运行:

    $ vault read sys/policy/default
    

    禁用附加默认策略:

    $ vault token create -no-default-policy
    

    需要禁用此默认策略,因为它允许令牌所有者访问auth/token/revoke-self,并破坏令牌被所有人使用的能力。

    $ vault read sys/policy/default -format=table
    Key      Value                                                                                            
    ---      -----                                                                                            
    name     default                                                                                          
    rules    # Allow tokens to look up their own properties
    path "auth/token/lookup-self" {
        capabilities = ["read"]                                                                                                                                                                                         
    }                       
                                                         
    # Allow tokens to renew themselves
    path "auth/token/renew-self" {                
        capabilities = ["update"]     
    }                                            
                                                         
    # Allow tokens to revoke themselves
    path "auth/token/revoke-self" {
        capabilities = ["update"]
    }
    

    使用这些事实,设置对保管库端点的访问以读取 jwt 签名密钥的公共部分归结为使用根令牌:

    • 创建一个保管库令牌
      • 具有公开共享的id 值“jwk”
      • 作为周期性令牌,没有父代
      • 周期的 TTL 可能值最高
      • 没有附加默认策略
    • 绑定到自定义策略
      • 可以读取公共 jwt 签名密钥
      • 可以在其令牌上查找自我
      • 可以在其令牌上更新自我

    这是一个演示如何将所有这些组合在一起的脚本:

    #!/bin/bash
    
    mkdir -p /vault/config/
    
    cat <<EOT > /vault/config/init.hcl
    storage "inmem" {}
    disable_mlock = "true"
    
    listener "tcp" {
      tls_disable = "true"
      address = "0.0.0.0:8200"
    }
    
    api_addr = "http://127.0.0.1:8200"
    EOT
    
    nohup vault server --config /vault/config/init.hcl > /vault/nohup.log 2>&1 &
    echo $! > /vault/nohup_pid.txt
    sleep 1
    
    VAULT_INIT=$(vault operator init -key-shares=1 -key-threshold=1 2>&1)
    VAULT_ROOT=$(echo "$VAULT_INIT" 2>&1 | jq -r ".root_token")
    VAULT_UNSEAL=$(echo "$VAULT_INIT" 2>&1 | jq -r ".unseal_keys_hex[0]")
    UNSEAL_OPERATION=$(vault operator unseal "$VAULT_UNSEAL" 2>&1)
    LOGIN_OPERATION=$(printf "$VAULT_ROOT" | vault login - 2>&1)
    
    vault secrets enable transit 2>&1 >/dev/null
    vault write "transit/keys/jwt-signing" type=rsa-4096 exportable=false 2>&1 >/dev/null
    
    cat <<EOT > /vault/config/jwk.policy.hcl
    path "transit/keys/jwt-signing" {
      capabilities = ["read"]
    }
    
    path "/auth/token/lookup-self" {
      capabilities = ["read"]
    }
    
    path "/auth/token/renew-self" {
      capabilities = ["update"]
    }
    EOT
    vault policy write "jwk" /vault/config/jwk.policy.hcl 2>&1 >/dev/null
    vault write auth/token/create-orphan id="jwk" no_default_policy="true" policies="jwk" ttl="0" explicit_max_ttl="0" num_uses="0" period="2764800" 2>&1 >/dev/null
    
    curl -s -H "X-Vault-Token: jwk" "http://localhost:8200/v1/transit/keys/jwt-signing" | jq -r '.data.keys["1"].public_key'
    

    哪些打印:

    -----BEGIN PUBLIC KEY-----
    MIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEAxoZ3HfPOTtcKGXpPSg15
    l/ElL4NzNr4YjQrMlRCxw3LPfum1VIyAXupvFb6+dIsmyF9kEE8kXCePpioaEZwo
    hlqrqTOrrJRzbsA5znnJPW/S8BuMm1o44x4EXQuc8cWTFc3aP2IgNnMSP31urIpy
    /gFoHlYkNCydHSMzCB/oQ33IwpB6KCy7c8ChB2ZqTSlfiXHYkCA4QVLxY/Aoitqz
    pAN988QwFDtXwzFxaayT/awS6pSgH75Twrs5K7JnC/97uEl2IQDYrB+DXugGvoHa
    ZFi1KqdA2sCRW70ephox0+byLjAYsYI55eWdMtOdCcLfDoIHt/V5YaolzqJgNMSv
    t6VfIL139xnnX2L66P/BJ2MOr/BtDlb7bUhVoGFojBoZd2UvNBSK+b1Jgydy+ZNy
    5XIDtEnW+TzEHhgMyjLnBl4r54ncDsF++2qqRoyxjFQNBLxTNgxLj6joxfu3OvOP
    MQOpBlYwHIYpsvImY5tV2XVioT8VTVeHmZfL52H7K+CkIoP5rebX6R+JdrIuvFht
    Gn9GpMsJBJe+g0zCwM1tEfWct/vkIMNcOp4gwhUI129tLOeEep0sbAQCj5Ee+U9U
    1M4yh4U1yvRIK2Y5jjZnr7JeW+jf2jHbpKmunFq3s5HMTjxOTmfM84cvdt5bqbzB
    ly1rdyPowulT/l7qQtUJCi8CAwEAAQ==
    -----END PUBLIC KEY-----
    

    这是我可以达到的“未经身份验证”访问权限。

    不要忘记每月至少定期更新此令牌一次!

    curl -s -X POST -H "X-Vault-Token: jwk" http://localhost:8200/v1/auth/token/renew-self
    

    【讨论】:

    • 多么完整和有用的答案。谢谢!
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2015-07-01
    • 2019-09-25
    • 2021-01-21
    • 1970-01-01
    • 2017-03-06
    • 1970-01-01
    • 2017-03-28
    相关资源
    最近更新 更多