Hashicorp Vault tls cert 身份验证不读取证书

ale*_*exK 3 ssl hashicorp-vault

我正在尝试在 Vault 中设置基于证书的身份验证。为了进行测试,我刚刚创建了一个干净的 Vault 设置。保险库配置如下:

listener "tcp" {
  address                  = "192.168.33.10:8200"
  tls_cert_file            = "/etc/vault/vault_cert.pem"
  tls_key_file             = "/etc/vault/vault_key.pem"
  tls_disable_client_certs = false
  tls_disable              = false
}

listener "tcp" {
  address                  = "127.0.0.1:8200"
  tls_disable              = true
}

storage "file" {
  path = "/etc/vault/data"
}
Run Code Online (Sandbox Code Playgroud)

我已经启动并解封了 Vault 并启用了证书身份验证:

[vagrant@localhost ~]$ ./vault status
Key             Value
---             -----
Seal Type       shamir
Sealed          false
Total Shares    5
Threshold       3
Version         0.9.3
Cluster Name    vault-cluster-37dffb3b
Cluster ID      1ddd4712-99f6-3691-a066-d476fbc6d7c6
HA Enabled      false
[vagrant@localhost ~]$ ./vault auth list
Path      Type     Description
----      ----     -----------
cert/     cert     n/a
token/    token    token based credentials
Run Code Online (Sandbox Code Playgroud)

现在我已经生成了 ssl 密钥/证书对,尚未添加到 Vault 中,因此我希望 Vault 告诉我证书无效(至少这是我从此处阅读源代码中得到的理解。虽然我得到的答案是根本没有提供证书:

[vagrant@localhost ~]$ VAULT_ADDR='https://192.168.33.10:8200' ./vault login -method cert -tls-skip-verify -client-cert=./client_cert.pem -client-key=./client_key.pem
Error authenticating: Error making API request.

URL: PUT https://192.168.33.10:8200/v1/auth/cert/login
Code: 400. Errors:

* client certificate must be supplied
Run Code Online (Sandbox Code Playgroud)

根据我在来源中找到的信息,只有当根本没有向 Vault 提供证书时才会返回此错误消息。为了确保这在 Vault cli 客户端中不是问题,我尝试对curl 执行相同的操作,但得到了相同的结果:

[vagrant@localhost ~]$ curl -iv -k -X POST --cert ./client_cert.pem --key ./client_key.pem https://192.168.33.10:8200/v1/auth/cert/login
* About to connect() to 192.168.33.10 port 8200 (#0)
*   Trying 192.168.33.10...
* Connected to 192.168.33.10 (192.168.33.10) port 8200 (#0)
* Initializing NSS with certpath: sql:/etc/pki/nssdb
* skipping SSL peer certificate verification
* SSL connection using TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384
* Server certificate:
*   subject: CN=Vault,E=vault@example.com,O=Exmaple,L=Berlin,ST=BERLIN,C=DE
*   start date: Feb 14 15:59:37 2018 GMT
*   expire date: Feb 12 15:59:37 2028 GMT
*   common name: Vault
*   issuer: CN=Vault,E=vault@example.com,O=Exmaple,L=Berlin,ST=BERLIN,C=DE
> POST /v1/auth/cert/login HTTP/1.1
> User-Agent: curl/7.29.0
> Host: 192.168.33.10:8200
> Accept: */*
>
< HTTP/1.1 400 Bad Request
HTTP/1.1 400 Bad Request
< Cache-Control: no-store
Cache-Control: no-store
< Content-Type: application/json
Content-Type: application/json
< Date: Wed, 14 Feb 2018 16:20:57 GMT
Date: Wed, 14 Feb 2018 16:20:57 GMT
< Content-Length: 51
Content-Length: 51

<
{"errors":["client certificate must be supplied"]}
* Connection #0 to host 192.168.33.10 left intact
Run Code Online (Sandbox Code Playgroud)

在跟踪模式下运行的 Vault 服务器在此交互期间不提供任何日志。不过,如果我使用不同证书中的密钥尝试故意破坏 TLS,我会在 Vault 中看到一条错误消息,表明这一点。

知道这个设置可能有什么问题吗?

jAC*_*jAC 5

在深入研究有关 Vault 的 TLS 客户端验证的提交后,我终于有了一个可用的 Vault 实例。

\n\n

要为 Vault TCP 侦听器的任何请求设置客户端证书验证,您必须配置两个值:

\n\n
    \n
  • tls_client_ca_file = "/my/intermediate/ca/intermediate.cert.pem
  • \n
  • tls_require_and_verify_client_cert = true
  • \n
\n\n

配置这两个设置后,所有没有有效客户端证书的后端请求都会被阻止,所有有效的客户端请求都会转发到 Vault 实例。

\n\n

根据我的理解,这只是一个针对未经授权的访问的“过滤器”。

\n\n

那么让我们从 TLS 证书身份验证设置开始:

\n\n

首先,我们必须设置 Vault CLI 为其执行的每个请求提供客户端证书:

\n\n
export VAULT_CLIENT_CERT="/my/cert/path/vault-client.cert.pem"\nexport VAULT_CLIENT_KEY="/my/cert/path/vault-client.key.pem"\n\nexport VAULT_ADDR="https://my.vault.app.com:8200"\n
Run Code Online (Sandbox Code Playgroud)\n\n

通过这个命令,我们就可以通过TCP监听器的“过滤器”了。

\n\n

最后执行启用客户端证书身份验证的命令

\n\n
vault auth enable cert\n
Run Code Online (Sandbox Code Playgroud)\n\n

为了授予对特定客户端的访问权限,证书必须链接到一个策略,该策略本身描述对特定秘密引擎的访问权限:

\n\n

让我们创建一个简单的 KV 秘密引擎myorganization/dev

\n\n
vault secrets enable -path=myorganization/dev kv\n
Run Code Online (Sandbox Code Playgroud)\n\n

然后我们必须为 Secrets Engine创建一个策略文件( HCL语法):

\n\n
path "myorganization/dev/myapp" {\n     capabilities = ["read"]\n}\n
Run Code Online (Sandbox Code Playgroud)\n\n

创建策略文件后,我们可以将其上传到保管库的策略存储:

\n\n
vault policy write myapp-read-access myapp-read-access.hcl\n
Run Code Online (Sandbox Code Playgroud)\n\n

最后,我们必须通过将 .cert.pem 文件上传到证书存储并将其映射到此策略来将应用程序或客户端证书*分配给此策略:

\n\n
vault write auth/cert/certs/myapp display_name="My Vault Test App" policies=myapp-read-access certificate=myapp.cert.pem ttl=3600\n
Run Code Online (Sandbox Code Playgroud)\n\n

* 这可以与指令或其他一些证书中的相同export(当然是相同的 CA)

\n\n

配置完成后,您就可以使用 CLI 客户端:

\n\n
vault login -method=cert\n
Run Code Online (Sandbox Code Playgroud)\n\n

或者,您可以使用以下命令指定另一个用于登录的证书:

\n\n
vault login -method=cert -client-cert=myapp.cert.pem -client-key=myapp.key.pem\n
Run Code Online (Sandbox Code Playgroud)\n\n

在我的例子中,我使用了 Java 客户端,并使用以下 Maven POM 作为依赖项:

\n\n
<dependency>\n    <groupId>org.springframework.cloud</groupId>\n    <artifactId>spring-cloud-vault-dependencies</artifactId>\n    <version>2.0.2.BUILD-SNAPSHOT</version>\n    <scope>import</scope>\n    <type>pom</type>\n</dependency>\n
Run Code Online (Sandbox Code Playgroud)\n\n

以及以下 Vault 客户端配置 (bootstrap.yml):

\n\n
spring.application.name: myapp\nspring.cloud.vault:\n  host: my.vault.app.com\n  port: 8200\n  scheme: https\n  generic.backend: myorganization/dev\n  authentication: CERT\n  ssl:\n    key-store: classpath:myapp.jks\n    key-store-password: <MYKEYSTOREPW>\n    cert-auth-path: cert\n
Run Code Online (Sandbox Code Playgroud)\n\n

等等\xc3\xa0:

\n\n
\n

2018-09-19 14:02:18.114 INFO 51832 --- [ main] bcPropertySourceBootstrapConfiguration :定位属性源:CompositePropertySource {name=\'vault\', propertySources=[LeaseAwareVaultPropertySource {name=\'myorganization/dev/myapp\' }, LeaseAwareVaultPropertySource {name=\'myorganization/dev/application\'}]}

\n
\n\n

或者如果提供了无效的证书:

\n\n
\n

org.springframework.web.client.ResourceAccessException:“ https://my.vault.app.com:8200/v1/auth/cert/login的 POST 请求上出现 I/O 错误:\n 收到致命警报:坏证书;嵌套异常为\n javax.net.ssl.SSLHandshakeException: 收到致命警报:\n bad_certificate

\n
\n