Аутентификация Hashicorp Vault TLS Cert не читает сертификат
Я пытаюсь настроить аутентификацию на основе сертификатов в 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"
}
Я запустил и распечатал 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
Теперь я сгенерировал пару ключ / сертификат 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
Из того, что я смог найти в источниках, это сообщение об ошибке возвращается только тогда, когда в Vault вообще не предоставляется сертификат. Просто чтобы убедиться, что это не проблема в клиенте Vault, я попытался сделать то же самое с 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
Сервер хранилища, работающий в режиме трассировки, не предоставляет журналы во время этого взаимодействия. Хотя, если я буду использовать ключ из другого сертификата, пытаясь преднамеренно нарушить TLS, я вижу сообщение об ошибке в Vault, указывающее на это.
Есть идеи, что может быть не так с этой настройкой?
2 ответа
После просмотра коммитов, касающихся проверки клиента TLS для Vault, у меня наконец-то появился рабочий экземпляр Vault.
Для настройки проверки сертификата клиента для любого запроса к прослушивателю Vault TCP необходимо настроить два значения:
tls_client_ca_file = "/my/intermediate/ca/intermediate.cert.pem
tls_require_and_verify_client_cert = true
Когда эти два параметра настроены, все запросы к бэкэнду без действительного сертификата клиента блокируются, все действительные клиентские запросы затем перенаправляются в экземпляр Vault.
В моем понимании это просто "фильтр" для несанкционированного доступа.
Итак, начнем с настройки аутентификации TLS-сертификата:
Прежде всего, нам нужно настроить CLI Vault для предоставления клиентского сертификата для каждого выполняемого запроса:
export VAULT_CLIENT_CERT="/my/cert/path/vault-client.cert.pem"
export VAULT_CLIENT_KEY="/my/cert/path/vault-client.key.pem"
export VAULT_ADDR="https://my.vault.app.com:8200"
С помощью этой команды мы можем пройти через "фильтр" слушателя TCP.
И, наконец, выполните команду, которая включает аутентификацию сертификата клиента
vault auth enable cert
Для предоставления доступа определенным клиентам сертификат должен быть связан с политикой, которая сама описывает доступ к определенному механизму секретов:
Давайте создадим простой движок секретов KV для myorganization/dev
:
vault secrets enable -path=myorganization/dev kv
Затем мы должны создать файл политики (синтаксис HCL) для Secrets Engine:
path "myorganization/dev/myapp" {
capabilities = ["read"]
}
После создания файла политики мы можем загрузить его в хранилище политик хранилища:
vault policy write myapp-read-access myapp-read-access.hcl
И, наконец, мы должны назначить сертификат приложения или клиента * этой политике, загрузив файл.cert.pem в хранилище сертификатов и сопоставив его с этой политикой:
vault write auth/cert/certs/myapp display_name="My Vault Test App" policies=myapp-read-access certificate=myapp.cert.pem ttl=3600
* Это может быть так же, как в export
директивы или какой-то другой сертификат (тот же CA конечно)
После того, как это настроено, вы можете использовать клиент CLI:
vault login -method=cert
Кроме того, вы можете указать другой сертификат для входа в систему, используя:
vault login -method=cert -client-cert=myapp.cert.pem -client-key=myapp.key.pem
В моем случае я использовал клиент Java со следующим POM Maven для зависимостей:
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-vault-dependencies</artifactId>
<version>2.0.2.BUILD-SNAPSHOT</version>
<scope>import</scope>
<type>pom</type>
</dependency>
И следующая конфигурация клиента Vault (bootstrap.yml):
spring.application.name: myapp
spring.cloud.vault:
host: my.vault.app.com
port: 8200
scheme: https
generic.backend: myorganization/dev
authentication: CERT
ssl:
key-store: classpath:myapp.jks
key-store-password: <MYKEYSTOREPW>
cert-auth-path: cert
И вуаля:
2018-09-19 14: 02: 18.114 INFO 51832 --- [main] bcPropertySourceBootstrapConfiguration: источник расположенного свойства: CompositePropertySource {name='vault', propertySources=[LeaseAwareVaultPropertySource {name= "myorganization/dev/myapp'}, LeaseAwareVaultPropertyS Name='myorganization/ Dev / приложение'}]}
Или в случае предоставления недействительного сертификата:
org.springframework.web.client.ResourceAccessException: ошибка ввода-вывода при запросе POST для " https://my.vault.app.com:8200/v1/auth/cert/login": получено фатальное предупреждение: bad_certificate; вложенным исключением является javax.net.ssl.SSLHandshakeException: получено фатальное предупреждение: bad_certificate
У меня была та же самая проблема сегодня.. провел полдня, пытаясь выяснить, что не так... оказалось, что в конфигурации хранилища "tls_disable_client_certs = false" в разделе слушателя, фактически отключает аутентификацию сертификата..
так что надеюсь, что кто-то еще может наткнуться на эту проблему, получите некоторую подсказку... удалите эту строку и сертификат будет работать.
вот ссылка на документ, не знаю, как я это интерпретировал, так как включение этого означает, что браузер и другие клиенты будут игнорировать сертификат самоподписи, что не так..
https://www.vaultproject.io/docs/configuration/listener/tcp.html
tls_disable_client_certs (string: "false") - отключает аутентификацию клиента для этого слушателя. Поведение по умолчанию (когда это ложно) для Vault запрашивать сертификаты клиентов, когда они доступны.
Хотя отвечаю поздно. Но мне удалось настроить сервер конфигурации Spring Cloud для использования Vault в качестве бэкэнда с аутентификацией CERT через сертификаты.
И репозиторий GitHub: https://github.com/java-developer-raman/config-server-vault-backend