Aller au contenu principal

Hashi Vault

1. Présentation

## Générer un Root Token
Après l'installation, la commande permet d'obtenir un token

```bash
ansible operator init

À garder précieusement, sinon en cas de perte, il faut relancer tout un processus pour obtenir un nouveau:

Obtenir un nouveau root token:

vault operator generate-root -init -format=json
# Exemple
{
"nonce": "fewefwe-fewfew-8b3fwf-01fewfc-560637asdde7b",
"started": true,
"progress": 0,
"required": 3,
"complete": false,
"encoded_token": "",
"encoded_root_token": "",
"pgp_fingerprint": "",
"otp": "OTP",
"otp_length": 28
}

Puis:

# Ensuite
vault operator generate-root -nonce="NONE VALUE"
#
Operation nonce: "NONCE"
Unseal Key (will be hidden): "UNSEAL_KEYS_1..3"
# Résultat
Nonce "NONCE"
Started true
Progress 1/3
Complete false

À répéter 3 fois jusqu'à

Nonce            "NONCE"
Started true
Progress 3/3
Complete true
Encoded Token "TOKEN"
vault operator generate-root -decode="TOKEN" -otp="OTP"

Créer un nouvel utilisateur

# ACTIVATION
vault auth enable userpass
vault write auth/userpass/users/own_user password="own_passwd" policies="default"
vault login -method=userpass username=own_user password=own_passwd
WARNING! The VAULT_TOKEN environment variable is set! The value of this
variable will take precedence; if this is unwanted please unset VAULT_TOKEN or
update its value accordingly.

Success! You are now authenticated. The token information displayed below
is already stored in the token helper. You do NOT need to run "vault login"
again. Future Vault requests will automatically use this token.

Key Value
--- -----
token USER_TOKEN
token_accessor TOKEN_ACCESSOR
token_duration 768h
token_renewable true
token_policies ["default"]
identity_policies []
policies ["default"]
token_meta_username own_user

Automatisation de la création d'utilisateur

Le module ansible:

roles/vault/create-user
- name: Create User
hosts: ['host']
become: true
user: supervisor
vars:
secret: auth/userpass/users/username
data:
password: "password"
policies: ["default"]
roles:
- role: vault/create-user

Créer un secret (SSH Host Keys par exemple)

vault secrets enable -path=host-1 kv
# Success! Enabled the kv secrets engine at: host-1/
vault kv put host-1/private_key key=@.ssh/id_rsa
# Success! Data written to: host-1/private_key
vault kv get host-1/private_key

=== Data ===
Key Value
--- -----
key -----BEGIN OPENSSH PRIVATE KEY-----
b3BlbnNzaC1rZXktdjEAAAAABG5vbmUAAAAEbm9uZQAAAAAAAAABAAABlwAAAAdzc2gtcn
NhAAAAAwEAAQAAAYEA8PQOlAfNAtPHxlyEy+f+ZZoyk2477OyDii9suP/bMHaagm97psba
o955unZOqVApxYYiKT9p+wp2Uly9aP7YrQWUg0lZma7yrjUZP+6NMzCvNMNu2nt72mmxJ7
fJgwGilml0GTlsVSAe0zFjUIYypEzH2jjesk0riGL0RVRO9VEp8W4qpM/7gVIvKdQX6epi
lgergergerJOIjOJKPJSDPFKEWFFEWFEWGERHRTHEWjomPOJMpmijJMmjpPMhhomGOgGGG
qch5u34BhR0V1gUkwFdWVYyCyT+LGJPdERSDtpKUyvgF5Mm6nu2y33SbHxTHI+BcQ100fp
G97aSQuKVCN/H9Fw88CAyBxKhdcP7ht78w/1JPr28nkEVdpP/vUkFFtSPQ7So65ANeRHZ+
CxvsdvsdvsdgeiJmpgwemIJIPOHPugiuhhloif6giyffgivoivviviuvivudd8i123gWki
fJvSwb9bS4iLUhx9Bs2DHKSy2hMzwWlSv9CcM3aTAAAFkGSaEE1kmhBNAAAAB3NzaC1yc2
EAAAGBAPD0DpQHzQLTx8ZchMvn/mWaMpNuO+zsg4ovbLj/2zB2moJve6bG2qPeebp2TqlQ
KcWGIik/afsKdlJcvWj+2K0FlINJWZmu8q41GT/ujTMwrzTDbtp7e9ppsSe3yYMBopZpdB
k5bFUgHtMxY1CGMqRMx9o43rJNK4hi9EVUTvVRKfFuKqTP+4FSLynUF+nqYmyy5zH0YvHI
WM+fyXoy1NDnj1PpCl2dUL8IYb7bwJiKH67jH3Ii3AACAQiIn1f4x/VSfwo6nIebt+AYUd
FdYFJMBXVlWMgsk/ixiT3REUg7aSlMr4BeTJup7tst90mx8UxyPgXENdNH6Rve2kkLilQj
fx/RcPPAgMgcSoXXD+4be/MP9ST69vJ5BFXaT/71JBRbUj0O0qOuQDXkR2fgsUkTYJh2nC
tYNWU3jIJED8HNtXLd5UAi6WDvh4YvfR08mpqW6IqYsPS8N4f9qptdt4FpInyb0sG/W0uI
i1IcfQbNgxykstoTM8FpUr/QnDN2kwAAAAMBAAEAAAGBAMPf4qn73XDa8KAUPe/03B2ESH
EJP7XOXvBKtTt+4pR3FgvKzN468SodhR9LZY7GF+72p3aYknL9gkpaEa/02/drfdtsGWaR
jb6Ic8pBBpACl6tw5ADAOWLIYLdE9I+HGMDlYPfQcnyQ6/4LPA0NysU9lYmUiZSwnx70Ml
bZvoY2QL5/LDNmz7HFOYnrXLVPUEvE86TsYjLjBy9hWcv43oAkfaNc4oxPgoCJM8yPn/Vg
83icMcf7BpULDAP/7Gj7Vx4IYh+GHheQtWV83r3xWmSJ6QUFgj7fF4I9UQPHO80wwp9o6k
eHfE60YAzVu2IPUAvyMfylNzPyNJUNEv+OKiodqXwpNsSGqYPMzp0x1Wm5ndDAaE7XqtM4
4GrXkLV3ONo3q6dT3wef3w636pZWJuM6Cd0vRYcVoPGQKXvJHEfs15nZme5MUf9M1BMcfS
LKipLQL+9oE5OpL6/8RfCjKOoXzLWD4PJMctXMGDbgC9LvZBce6LfueVNq6KmwY5tqoQAA
AMEA2PvxzucBZeobFHseYtGX4M5nmKq1zWYePBKgW9jV9NmOA+tFDH1j5tra4qrFCTpHlN
KbipPRTwDsn9nJ5o30i9J9LDxQ77u+1n+6Xrl3EZyfA52KvjGOWx7oA4ekr2GZjEQRw7wx
m4fdwQU80JbuP45hiYtvPHOlq+sWiHaTMG3eA7TlF4ayRM2UQHAAAAwQD62SgBhRAjGT6l
LmfTsAAOgAQdPMGk0hl9+4wBI6dedededededededwefreg45h5jyj4xmV+/IEtn+wLGfR
R6xhcZrSWYr+arvmaiRc+kFPhFtS57IqJlXJlPlKDxIqxwSSSdT0aQUCerPC+I+QNvW1BS
DryHrAUUexaaihJ8RbJvWeZmV18XnQg1cAAADBAPXm4LZKMXiGLbObzNbBRI8LWVxk6Iko
qpAjUeYWTZ2fRCjMuuCV1dBu4f7N3+WOA/zIEfcmKzIMXTyiDfcw2pYuuiXIfiNe+q1BLv
XdeuSEngZ2NIzDv5hOSne0n4s5ZxejpVy57muW25gNHZkiBOIl0W/lmMjd72X7TYOHaKYV
quyiynpTF9l8qN0tOsgTbqlf3Uux6BDjzy/TWsk4sWCZ3ZvMhyRhonFwO01PLwPNV1Pl9D
+TTXwn3l7WGCl9JQAAABdzdXBlcnZpc29yQHN1cGVydmlzb3ItNAEC
-----END OPENSSH PRIVATE KEY-----

Générate PKI

1. Générate Root Certificate

Enable pki_gnr_ca path

vault secrets enable -path=pki_gnr_ca pki
# Success! Enabled the pki secrets engine at: pki_gnr_ca/

Modifier le TTL

vault secrets tune -max-lease-ttl=87600h pki_gnr_ca
# Success! Tuned the secrets engine at: pki_gnr_ca/
vault write -field=certificate pki_gnr_ca/root/generate/internal max_path_length=1 common_name="My Root CA" ttl=87600h key_bits=2048 > ca.crt

Pour vérifier les informations du certificat

openssl x509 -in ca.crt -text -noout
# cat CA_cert.crt
-----BEGIN CERTIFICATE-----
MIIDJjCCAg6gAwIBAgIUTMR1ILXw5KCUsB+fAzCIZIdos4UwDQYJKoZIhvcNAQEL
BQAwGTEXMBUGA1UEAxMOR2VuZ2FyIFJvb3QgQ0EwHhcNMjUwNDI4MTEyMjE5WhcN
MzUwNDI2MTEyMjMxWjAZMRcwFQYDVQQDEw5HZW5nYXIgUm9vdCBDQTCCASIwDQYJ
KoZIhvcNAQEBBQADggEPADCCAQoCggEBANHMdT3ekYlmYTiHJDit9LSYdGCsU5f0
hHZw2DgJ436Z5vtxnBUu1kkDY+AQutmrj6TLC37TqdPCRPgMo9Wz+IJNVWP1C8Jz
Ov+/x82VhcHDZeelSESY28tFZmta38sqX/wqUtK5ai7agL2PqZCEfwjZpS+fRahJ
TDo1xYWc2/Mi/BWMWIPboDk9+KmB1lKiA5NwmUSulUAwOXm815+bVNcoje79UeEX
YjuVzIMO9B7Y0PwG9mGTPl9Yfr2jabV892v+lfLFpDCikuFO+TsR1eZGCZb6ittc
aaNCZQsGI4Sgklm3LDFWN6A1ftGbjqL/6Uv8QbnHgpkBPINFV4LsT00CAwEAAaNm
MGQwDgYDVR0PAQH/BAQDAgEGMBIGA1UdEwEB/wQIMAYBAf8CAQEwHQYDVR0OBBYE
FESREPC3YKflZwARjMlAr4p24T2RMB8GA1UdIwQYMBaAFESREPC3YKflZwARjMlA
r4p24T2RMA0GCSqGSIb3DQEBCwUAA4IBAQAqYkT0pM9z3VrtCM4IxmVc1oUwTnSo
8GEd3uOr6Png6xWs91hCJp2W2IrV+nKY3mOnP4GrAs4teRJf+pXmAKKVWtcNSQ25
IVk3yw82biKa4jWbfMP05DX7kP/ujBXLu5f9Awg3lU1TtIMPi8czxNjGowLXhLSG
5D4dHwpNaCDj0KXKp66+uoyChfty2BcViu5o0dufHAh886szKGOifEjX2YxRo9+q
OaEQfm79w/NCP+9e5CTx2KsdGHumLwy49wFwJfZp3dmUmTtlfIRCt3ZML1KSeuyy
1VGbLv7MUebKIJYMWpkCnaaJnZrEbQvZZ9/5ztmxLEOODIY8RYciIK6u

Configurer l'accés http aux certificats

vault write pki_gnr_ca/config/urls issuing_certificates="https://vault.core.stack:8200/v1/pki_gnr_ca/ca" crl_distribution_points="https://vault.core.stack:8200/v1/pki_gnr_ca/crl"
vault write pki_gnr_ca/config/crl expiry="4380h"

Key Value
--- -----
auto_rebuild false
auto_rebuild_grace_period 12h
cross_cluster_revocation false
delta_rebuild_interval 15m
disable false
enable_delta false
expiry 4380h
max_crl_entries 100000
ocsp_disable false
ocsp_expiry 12h
unified_crl false
unified_crl_on_existing_paths false
vault read pki_gnr_ca/crl/rotate
Key Value
--- -----
success true

Créer un root certificat intermediaire

vault secrets enable -path=pki_int_gnr_ca pki
# Success! Enabled the pki secrets engine at: pki_int_gnr_ca/
vault secrets tune -max-lease-ttl=43800h pki_int_gnr_ca
# Success! Tuned the secrets engine at: pki_int_gnr_ca/
vault write -format=json pki_int_gnr_ca/intermediate/generate/internal common_name="Intermediate Authority" ttl=43800h | jq -r '.data.csr' > ca_int.csr

Générer le certificat signé

vault write -format=json pki_gnr_ca/root/sign-intermediate key_bits=2048 common_name="CA Int Root Issuing CA" csr=@ca_int.csr format=pem_bundle ttl="43800h" | jq -r '.data.certificate' > ca_int.cert.pem

Configurer les liens pour accéder aux certificats

vault write pki_int_gnr_ca/config/urls issuing_certificates="${VAULT_ADDR}/v1/pki_int_gnr_ca/ca" crl_distribution_points="${VAULT_ADDR}/v1/pki_int_gnr_ca/crl"

### Rsult

Key Value
--- -----
crl_distribution_points [https://address:port/v1/pki_int_gnr_ca/crl]
enable_templating false
issuing_certificates [https://address:port/v1/pki_int_gnr_ca/ca]
ocsp_servers []

Configurer le délai d'expiration

vault write pki_int_gnr_ca/config/crl expiry="4380h"

Vérification

vault read pki_int_gnr_ca/crl/rotate
# Result
Key Value
--- -----
success true
vault write pki_int_gnr_ca/roles/Issuer allow_any_name=True server_flag=False \ 
client_flag=False allow_subdomains=false ou="TO_DEFINE_FOR_NEED" \
organization="TO_DEFINE_FOR_NEED" country="GB" key_usage="DigitalSignature, \
KeyEncipherment" use_csr_common_name=true ext_key_usage="" ext_key_usage_oids="" \
ttl="4380h" max_ttl="4380h" enforce_hostnames=false allow_bare_domains=true
# Result
Key Value
--- -----
allow_any_name true
allow_bare_domains true
allow_glob_domains false
allow_ip_sans true
allow_localhost true
allow_subdomains false
allow_token_displayname false
allow_wildcard_certificates true
allowed_domains []
allowed_domains_template false
allowed_other_sans []
allowed_serial_numbers []
allowed_uri_sans []
allowed_uri_sans_template false
allowed_user_ids []
basic_constraints_valid_for_non_ca false
client_flag false
cn_validations [email hostname]
code_signing_flag false
country []
email_protection_flag false
enforce_hostnames false
ext_key_usage []
ext_key_usage_oids []
generate_lease false
issuer_ref default
key_bits 2048
key_type rsa
key_usage [DigitalSignature KeyEncipherment]
locality []
max_ttl 4380h
no_store false
not_after n/a
not_before_duration 30s
organization []
ou []
policy_identifiers []
postal_code []
province []
require_cn true
serial_number_source json-csr
server_flag false
signature_bits 256
street_address []
ttl 4380h
use_csr_common_name true
use_csr_sans true
use_pss false

Émettre un certificat de test

vault write -format=json pki_int_gnr_ca/issue/Issuer name="Test Certificate" common_name="Test Certificate"
vault write -format=json pki_int_gnr_ca/issue/Issuer name="Test Certificate" common_name="Test Certificate" | jq -r '.data.certificate' | openssl x509 -noout -text >> cert1
# Result
Certificate:
Data:
Version: 3 (0x2)
Serial Number:
2d:fe:20:ce:88:aa:8e:07:8c:45:86:19:55:5d:3a:30:01:82:f2:e8
Signature Algorithm: sha256WithRSAEncryption
Issuer: CN = CA Int Root Issuing CA
Validity
Not Before: Apr 28 15:38:56 2025 GMT
Not After : Oct 28 03:39:17 2025 GMT
Subject: CN = Test Certificate
Subject Public Key Info:
Public Key Algorithm: rsaEncryption
RSA Public-Key: (2048 bit)
Modulus:
00:d1:c6:3c:f1:45:09:10:ce:ed:33:d6:6b:a0:88:
ec:82:aa:2b:37:27:4c:8f:23:ea:77:7f:76:f0:25:
ac:8d:0e:df:56:4f:a4:9c:c0:05:d9:7e:57:2b:3a:
bf:1e:5b:f8:c5:c2:9d:79:6f:44:c6:56:67:31:af:
dc:93:00:95:9d:85:6e:9a:0f:52:b4:91:37:c4:ee:
b7:ed:68:d9:4a:8f:19:2b:f6:55:ea:92:29:ab:93:
71:a6:02:97:c9:db:4d:8d:69:97:4a:1d:cf:93:4c:
5a:6a:8b:7f:49:4e:e5:0a:9b:10:f1:27:20:38:20:
42:ad:31:d4:8d:3e:29:00:b3:b3:88:b4:86:35:67:
56:88:06:ae:07:b8:ae:ef:d3:32:7a:16:6f:e9:da:
0a:75:a2:ba:02:72:ad:e8:7b:2c:ba:61:22:04:03:
9d:36:69:f9:b3:fc:8b:0b:0e:d5:6e:2d:ae:d5:c6:
11:75:8b:a3:62:93:3f:0d:96:24:36:ec:97:0e:23:
3c:b9:63:c5:18:65:1b:01:d5:3e:51:d8:39:38:2c:
71:8e:3c:d7:75:2b:de:26:29:b6:dc:f7:7e:79:67:
a9:1f:e5:6a:13:fa:5b:1e:3c:5d:b7:35:d3:c9:26:
e1:88:bc:64:0f:d3:9b:cc:06:74:71:f9:7e:05:e8:
3a:9d
Exponent: 65537 (0x10001)
X509v3 extensions:
X509v3 Key Usage: critical
Digital Signature, Key Encipherment
X509v3 Subject Key Identifier:
AC:B5:17:C3:E0:F9:C9:7B:8D:83:14:FF:D2:C5:6A:95:2E:2C:42:03
X509v3 Authority Key Identifier:
keyid:1A:42:B8:C4:8A:DD:49:CC:D5:51:93:51:1F:11:A6:A9:18:BF:E7:DE

Authority Information Access:
CA Issuers - URI:https://address:port/v1/pki_int_gnr_ca/ca

X509v3 CRL Distribution Points:

Full Name:
URI:https://address:port/v1/pki_int_gnr_ca/crl

Signature Algorithm: sha256WithRSAEncryption
9e:98:56:b0:7d:0b:8c:85:fa:f7:33:9c:14:e9:cf:b2:fe:a8:
c5:de:88:49:f6:12:c9:0e:7a:4a:d3:ce:f3:2c:d2:29:b8:88:
f2:28:d1:c1:4f:d5:02:01:ce:53:83:ee:91:19:53:a0:53:9e:
33:53:49:53:2c:46:08:09:7a:27:dc:09:eb:56:c9:65:b9:00:
38:29:48:fd:f8:eb:16:fd:2b:bd:9c:7c:08:73:1a:70:13:08:
d8:ae:1f:4a:da:6e:b2:55:e5:35:a2:29:ea:64:d4:d0:ea:4e:
ee:42:46:c8:b1:f4:8a:0f:9e:0d:06:15:ec:c2:d9:b8:79:ca:
0d:2a:8f:3d:78:a3:ed:f6:7e:e9:f3:f2:81:8c:0d:7b:65:ed:
51:a7:f1:a5:76:76:70:ca:d8:e8:a6:5b:8e:e0:73:c4:09:f0:
cb:92:83:23:13:2b:d1:14:b0:c9:da:cc:e4:3b:12:40:8c:d1:
36:bb:85:5f:8b:cf:60:c5:6e:86:a4:d0:46:ac:a8:61:84:11:
b7:03:71:7d:a9:80:b1:eb:f0:f9:5f:13:43:0a:4d:54:18:41:
74:44:d8:7a:00:06:d2:61:65:ac:e7:f7:14:5b:2a:fe:e1:46:
93:9a:17:0e:97:cb:c6:45:68:ab:a3:a4:1d:b2:97:0f:f3:0f:
c6:77:9c:f8

et les 2 certificats parents sont téléchargeable sur

http://address:port/v1/pki_gnr_ca/ca 
http://address:port/v1/pki_int_gnr_ca/ca

IAC

# Root CA generate
- name: Generate Root CA
uri:
url: "{{ vault_addr }}/v1/{{ certificate.path }}/root/generate/internal"
method: POST
headers:
"X-Vault-Token": "{{ vault_token }}"
body_format: json
body:
common_name: "{{ certificate.common_name }}"
ttl: "{{ certificate.ttl }}"
format: "{{ certificate.format }}"
organization: "{{ certificate.organization }}"
ou: "{{ certificate.ou }}"
country: "{{ certificate.country }}"
validate_certs: false
when: certificate.type is defined and certificate.type == "root"
register: root_ca

- name: Debug Root CA
debug:
msg: "{{ root_ca }}"

- name: "Verify certificate information"
community.crypto.x509_certificate_info:
content: "{{ root_ca.json.data.certificate }}"
register: result_crt

- name: Check Root CA CRT
debug:
msg: "{{ result_crt }}"
# delegate_to: localhost