Guide pas à pas
Introduction : L'évolution nécessaire de la sécurité d'accès
La gestion traditionnelle des accès aux infrastructures repose encore trop souvent sur des modèles périmètriques obsolètes : VPN larges, mots de passe partagés, certificats statiques à longue durée de vie. Ces approches, héritées d'une époque où le réseau d'entreprise était clairement délimité, montrent aujourd'hui leurs limites face aux enjeux du cloud hybride, du télétravail généralisé et des exigences réglementaires comme NIS2 ou ISO 27001.
Ce tutoriel vous guide dans la mise en œuvre d'une alternative moderne : une infrastructure Zero Trust combinant HashiCorp Vault pour la gestion centralisée des secrets et de la PKI, HashiCorp Boundary pour le contrôle d'accès granulaire sans exposition réseau, et Terraform pour orchestrer l'ensemble de manière reproductible. Cette approche garantit que chaque accès est authentifié, autorisé et audité individuellement, sans jamais exposer les ressources internes.
Objectifs de ce tutoriel :
- Déployer un PKI complet avec renouvellement automatique des certificats
- Configurer un accès SSH sécurisé sans VPN ni exposition des serveurs
- Automatiser l'infrastructure complète avec Terraform
- Intégrer audit et traçabilité pour la conformité
Durée estimée : 45 minutes
Niveau : Intermédiaire à avancé
Architecture globale de la solution
Cette architecture s'articule autour de trois composants principaux qui interagissent de manière sécurisée et orchestrée. HashiCorp Vault (port 8200) centralise la gestion des secrets et opère comme autorité de certification via son moteur PKI intégré. Il génère des certificats temporaires à la demande, éliminant le besoin de stocker des clés privées à long terme sur les postes utilisateurs ou les serveurs.
HashiCorp Boundary (port 9200) contrôle les accès selon le principe Zero Trust. Son architecture découplée entre Controller (authentification, autorisation, audit) et Worker (proxy de session) permet de sécuriser l'accès aux ressources sans jamais les exposer directement. Les utilisateurs n'obtiennent jamais d'adresses IP internes : ils accèdent aux ressources via des sessions proxy temporaires et auditées.
Terraform orchestre le déploiement et la configuration de l'ensemble. Il provisionne les montages PKI dans Vault, configure les rôles de certificats, déploie les scopes et targets dans Boundary, et établit les intégrations entre les composants. Cette approche Infrastructure as Code garantit la reproductibilité et facilite la maintenance.
Flux d'authentification et d'accès sécurisé
Le processus d'accès sécurisé suit un workflow précis qui garantit la validation de chaque étape. L'utilisateur s'authentifie d'abord auprès de Boundary via CLI ou interface web, fournissant ses credentials (password, OIDC, ou autre méthode configurée). Boundary vérifie immédiatement les permissions RBAC associées au compte utilisateur et détermine les ressources accessibles.
Si l'accès est autorisé, Boundary contacte Vault pour demander un certificat temporaire correspondant au rôle utilisateur et à la ressource cible. Vault génère instantanément un certificat PKI avec une durée de vie courte (typiquement 24 heures), signé par l'autorité de certification intermédiaire. Ce certificat est automatiquement injecté dans la session Boundary, sans manipulation manuelle de la part de l'utilisateur.
Boundary établit ensuite une session proxy sécurisée vers la ressource cible, en utilisant le certificat comme moyen d'authentification. L'utilisateur accède à la ressource via cette session proxy, qui reste transparente mais entièrement auditée. Chaque action, commande et transfert de données est enregistré dans les logs Boundary pour la conformité et l'analyse sécurité.
Image non trouvée: e11b4dd4.png
Prérequis et environnement de déploiement
Configuration système recommandée
| Composant | Minimum | Recommandé | Production |
|---|---|---|---|
| RAM | 8 Go | 16 Go | 32 Go+ |
| CPU | 4 cœurs | 8 cœurs | 16 cœurs+ |
| Stockage | 20 Go SSD | 50 Go SSD | 200 Go+ SSD |
| OS | Ubuntu 22.04 | Ubuntu 22.04 LTS | RHEL 9+ |
Installation des outils HashiCorp
#!/bin/bash
# Installation des outils HashiCorp sur Ubuntu/Debian
echo "=== Installation des prérequis ==="
sudo apt update && sudo apt install -y wget curl gpg lsb-release unzip git jq
echo "=== Ajout du repository HashiCorp ==="
wget -O- https://apt.releases.hashicorp.com/gpg | \
sudo gpg --dearmor -o /usr/share/keyrings/hashicorp-archive-keyring.gpg
echo "deb [signed-by=/usr/share/keyrings/hashicorp-archive-keyring.gpg] \
https://apt.releases.hashicorp.com $(lsb_release -cs) main" | \
sudo tee /etc/apt/sources.list.d/hashicorp.list
echo "=== Installation Terraform, Vault, Boundary ==="
sudo apt update
sudo apt install -y terraform vault boundary
echo "=== Vérification des versions ==="
terraform version
vault version
boundary version
echo "=== Création de la structure projet ==="
mkdir -p ~/vault-boundary-tutorial/{terraform,configs,scripts,outputs,logs}
cd ~/vault-boundary-tutorial
echo "Installation terminée avec succès"Validation de l'installation :
# Vérifier que tous les outils sont fonctionnels terraform version # >= v1.6.0 vault version # >= v1.15.0 boundary version # >= v0.14.0
Configuration de HashiCorp Vault avec moteur PKI
Hiérarchie de l'autorité de certification
La structure PKI repose sur une hiérarchie à deux niveaux, respectant les bonnes pratiques de sécurité. La Root CA constitue le point de confiance ultime avec un certificat auto-signé valide 10 ans, protégé par une clé RSA 4096 bits. Cette CA racine ne sert qu'à signer l'autorité intermédiaire et reste généralement hors ligne en production.
L'Intermediate CA opère comme autorité de certification opérationnelle. Son certificat, signé par la Root CA, dispose d'une validité de 5 ans et utilise également RSA 4096 pour les signatures. Cette CA intermédiaire émet tous les certificats de production via des rôles configurés, permettant une gestion granulaire des politiques d'émission.
Deux rôles de certificats sont configurés au niveau de l'autorité intermédiaire : le rôle serveur autorise l'émission de certificats pour *.novicore.local et *.example.com avec une durée maximale de 24 heures, tandis que le rôle client génère des certificats d'authentification pour les utilisateurs et services internes.
Déploiement de Vault en mode développement
#!/bin/bash # Script : 01-deploy-vault.sh echo "=== Démarrage de HashiCorp Vault ===" # Démarrer Vault en mode dev avec token prévisible nohup vault server -dev \ -dev-root-token-id="root" \ -dev-listen-address="0.0.0.0:8200" \ -log-level="INFO" \ > ~/vault-boundary-tutorial/logs/vault.log 2>&1 & # Sauvegarder le PID du processus echo $! > ~/vault-boundary-tutorial/vault.pid # Attendre le démarrage complet sleep 5 # Configuration des variables d'environnement export VAULT_ADDR='http://127.0.0.1:8200' export VAULT_TOKEN='root' # Sauvegarder la configuration pour réutilisation cat > ~/vault-boundary-tutorial/configs/vault-env.sh << 'EOF' export VAULT_ADDR='http://127.0.0.1:8200' export VAULT_TOKEN='root' EOF # Vérification du statut de Vault vault status echo "Vault démarré et accessible sur http://127.0.0.1:8200" echo "Token d'accès : root"
Configuration du moteur PKI principal
#!/bin/bash
# Configuration de la Root CA et PKI principal
source ~/vault-boundary-tutorial/configs/vault-env.sh
echo "=== Configuration du moteur PKI principal ==="
# Activer le moteur PKI
vault secrets enable pki
# Configurer le TTL maximal (10 ans)
vault secrets tune -max-lease-ttl=87600h pki
# Générer la Root CA auto-signée
vault write -field=certificate pki/root/generate/internal \
common_name="Novicore Root CA" \
issuer_name="root-2025" \
ttl=87600h \
key_type="rsa" \
key_bits=4096 \
country="FR" \
province="Île-de-France" \
locality="Paris" \
organization="Novicore" \
ou="Security Department" \
> ~/vault-boundary-tutorial/outputs/root_ca.crt
# Configurer les URLs de distribution
vault write pki/config/urls \
issuing_certificates="$VAULT_ADDR/v1/pki/ca" \
crl_distribution_points="$VAULT_ADDR/v1/pki/crl"
echo "Root CA générée et configurée"
echo "Certificat sauvé : ~/vault-boundary-tutorial/outputs/root_ca.crt"Configuration de la PKI intermédiaire
#!/bin/bash
# Configuration de l'Intermediate CA
source ~/vault-boundary-tutorial/configs/vault-env.sh
echo "=== Configuration du PKI intermédiaire ==="
# Monter un second moteur PKI pour l'autorité intermédiaire
vault secrets enable -path=pki_int pki
# Configurer le TTL maximal (5 ans)
vault secrets tune -max-lease-ttl=43800h pki_int
# Générer la demande de certificat (CSR) pour l'intermédiaire
vault write -format=json pki_int/intermediate/generate/internal \
common_name="Novicore Intermediate CA" \
issuer_name="novicore-intermediate" \
key_type="rsa" \
key_bits=4096 \
country="FR" \
province="Île-de-France" \
locality="Paris" \
organization="Novicore" \
ou="PKI Operations" \
| jq -r '.data.csr' \
> ~/vault-boundary-tutorial/outputs/pki_intermediate.csr
# Faire signer la CSR par la Root CA
vault write -format=json pki/root/sign-intermediate \
issuer_ref="root-2025" \
csr=@~/vault-boundary-tutorial/outputs/pki_intermediate.csr \
format=pem_bundle \
ttl="43800h" \
| jq -r '.data.certificate' \
> ~/vault-boundary-tutorial/outputs/intermediate.cert.pem
# Importer le certificat signé dans le PKI intermédiaire
vault write pki_int/intermediate/set-signed \
certificate=@~/vault-boundary-tutorial/outputs/intermediate.cert.pem
# Configurer les URLs pour l'autorité intermédiaire
vault write pki_int/config/urls \
issuing_certificates="$VAULT_ADDR/v1/pki_int/ca" \
crl_distribution_points="$VAULT_ADDR/v1/pki_int/crl"
echo "Intermediate CA configurée et opérationnelle"Création des rôles des certificats
#!/bin/bash
# Création des rôles pour l'émission de certificats
source ~/vault-boundary-tutorial/configs/vault-env.sh
echo "=== Création des rôles de certificats ==="
# Rôle pour les certificats serveur
vault write pki_int/roles/server-role \
allowed_domains="novicore.local,example.com,localhost" \
allow_subdomains=true \
allow_localhost=true \
allow_ip_sans=true \
max_ttl="8760h" \
key_type="rsa" \
key_bits=2048 \
server_flag=true \
client_flag=false \
enforce_hostnames=true \
key_usage="DigitalSignature,KeyEncipherment" \
ext_key_usage="ServerAuth"
# Rôle pour les certificats client (authentification utilisateur)
vault write pki_int/roles/client-role \
allowed_domains="novicore.local" \
allow_subdomains=true \
max_ttl="720h" \
key_type="rsa" \
key_bits=2048 \
server_flag=false \
client_flag=true \
key_usage="DigitalSignature" \
ext_key_usage="ClientAuth"
# Rôle spécialisé pour SSH (authentification par certificat)
vault write pki_int/roles/ssh-role \
allowed_domains="novicore.local,internal.local" \
allow_subdomains=true \
max_ttl="24h" \
key_type="rsa" \
key_bits=2048 \
server_flag=false \
client_flag=true
echo "Rôles de certificats créés avec succès"
# Test d'émission d'un certificat serveur
echo "=== Test d'émission de certificat ==="
vault write -format=json pki_int/issue/server-role \
common_name="test.novicore.local" \
alt_names="api.test.novicore.local,web.test.novicore.local" \
ip_sans="127.0.0.1" \
ttl="24h" \
> ~/vault-boundary-tutorial/outputs/test_server_cert.json
# Extraire et vérifier le certificat
jq -r '.data.certificate' ~/vault-boundary-tutorial/outputs/test_server_cert.json \
> ~/vault-boundary-tutorial/outputs/test_server.crt
jq -r '.data.private_key' ~/vault-boundary-tutorial/outputs/test_server_cert.json \
> ~/vault-boundary-tutorial/outputs/test_server.key
# Vérification du certificat généré
echo "Détails du certificat de test :"
openssl x509 -in ~/vault-boundary-tutorial/outputs/test_server.crt \
-text -noout | head -30
echo "PKI complètement opérationnel"Configuration de HashiCorp Boundary
Structure des scopes et organisation
Boundary organise les ressources selon une hiérarchie de scopes qui permet l'isolation et la délégation granulaire des permissions. Le Global Scope contient la configuration système et les méthodes d'authentification globales. Le scope Organisation (Novicore-Org) regroupe les utilisateurs, groupes et rôles de l'entreprise. Enfin, le scope Projet (Infrastructure-Project) contient les ressources accessibles : targets, host catalogs et credential stores.
Cette structure hiérarchique permet d'appliquer le principe de moindre privilège : un utilisateur dispose uniquement des permissions explicitement accordées à son niveau et hérite des permissions des scopes parents. Les administrateurs peuvent déléguer la gestion d'un projet à une équipe sans lui donner accès aux autres projets de l'organisation.
Déploiement de Boundary
#!/bin/bash
# Script : 02-deploy-boundary.sh
echo "=== Déploiement de HashiCorp Boundary ==="
# Créer la configuration Boundary
mkdir -p ~/vault-boundary-tutorial/configs/boundary
# Configuration du controller Boundary
cat > ~/vault-boundary-tutorial/configs/boundary/controller.hcl << 'EOF'
# Configuration Boundary Controller (mode dev)
disable_mlock = true
controller {
name = "boundary-controller"
description = "Boundary controller for tutorial"
database {
url = "env://BOUNDARY_PG_URL"
}
}
listener "tcp" {
address = "0.0.0.0:9200"
purpose = "api"
tls_disable = true
}
listener "tcp" {
address = "0.0.0.0:9201"
purpose = "cluster"
tls_disable = true
}
listener "tcp" {
address = "0.0.0.0:9202"
purpose = "proxy"
tls_disable = true
}
kms "aead" {
purpose = "root"
aead_type = "aes-gcm"
key = "sP1fnF5Xz85RrXyELHFeZg9Ad2qt4Z4bgNHVGtD6ung="
key_id = "global_root"
}
kms "aead" {
purpose = "worker-auth"
aead_type = "aes-gcm"
key = "8fZBjCUfN0TzjEGLQldGY4+iE9AkOvCfjh7+p0GtRBQ="
key_id = "global_worker-auth"
}
kms "aead" {
purpose = "recovery"
aead_type = "aes-gcm"
key = "8fZBjCUfN0TzjEGLQldGY4+iE9AkOvCfjh7+p0GtRBQ="
key_id = "global_recovery"
}
EOF
# Démarrer PostgreSQL pour Boundary (via Docker)
echo "=== Démarrage de PostgreSQL pour Boundary ==="
docker run -d --name boundary-postgres \
-e POSTGRES_DB=boundary \
-e POSTGRES_USER=boundary \
-e POSTGRES_PASSWORD=boundary_pass \
-p 5432:5432 \
postgres:15
sleep 10
# Configuration de l'URL de base de données
export BOUNDARY_PG_URL="postgresql://boundary:boundary_pass@localhost:5432/boundary?sslmode=disable"
# Initialiser la base de données Boundary
boundary database init -config ~/vault-boundary-tutorial/configs/boundary/controller.hcl
# Démarrer le controller Boundary
nohup boundary server -config ~/vault-boundary-tutorial/configs/boundary/controller.hcl \
> ~/vault-boundary-tutorial/logs/boundary-controller.log 2>&1 &
echo $! > ~/vault-boundary-tutorial/boundary-controller.pid
sleep 5
echo "Boundary Controller démarré sur port 9200"Configuration initiale via Terraform
#!/bin/bash
# Création de la structure Terraform pour Boundary
cd ~/vault-boundary-tutorial/terraform
# Provider Boundary
cat > boundary.tf << 'EOF'
terraform {
required_providers {
boundary = {
source = "hashicorp/boundary"
version = "~> 1.1"
}
}
}
provider "boundary" {
addr = "http://127.0.0.1:9200"
auth_method_id = var.auth_method_id
auth_method_login_name = var.auth_login_name
auth_method_password = var.auth_password
}
variable "auth_method_id" {
description = "Auth method ID from Boundary initialization"
type = string
}
variable "auth_login_name" {
description = "Initial admin login name"
type = string
}
variable "auth_password" {
description = "Initial admin password"
type = string
sensitive = true
}
# Récupérer le scope global
data "boundary_scope" "global" {
scope_id = "global"
}
# Créer le scope organisation
resource "boundary_scope" "org" {
scope_id = data.boundary_scope.global.id
name = "novicore-org"
description = "Organisation Novicore"
auto_create_admin_role = true
auto_create_default_role = true
}
# Créer le scope projet
resource "boundary_scope" "project" {
scope_id = boundary_scope.org.id
name = "infrastructure-project"
description = "Projet Infrastructure"
auto_create_admin_role = true
}
# Créer des utilisateurs
resource "boundary_user" "infrastructure_admin" {
name = "infra-admin"
description = "Administrateur infrastructure"
scope_id = boundary_scope.org.id
}
resource "boundary_user" "developer" {
name = "developer"
description = "Développeur"
scope_id = boundary_scope.org.id
}
# Créer un groupe
resource "boundary_group" "infrastructure_team" {
name = "infrastructure-team"
description = "Équipe Infrastructure"
scope_id = boundary_scope.org.id
member_ids = [
boundary_user.infrastructure_admin.id,
boundary_user.developer.id
]
}
# Host catalog statique
resource "boundary_host_catalog_static" "servers" {
name = "servers-catalog"
description = "Catalogue des serveurs"
scope_id = boundary_scope.project.id
}
# Hosts (serveurs cibles)
resource "boundary_host_static" "ssh_server" {
name = "ssh-server-1"
description = "Serveur SSH test"
address = "127.0.0.1"
host_catalog_id = boundary_host_catalog_static.servers.id
}
# Host set
resource "boundary_host_set_static" "ssh_servers" {
name = "ssh-servers-set"
description = "Ensemble serveurs SSH"
host_catalog_id = boundary_host_catalog_static.servers.id
host_ids = [
boundary_host_static.ssh_server.id
]
}
# Target SSH
resource "boundary_target" "ssh_target" {
name = "ssh-server-target"
description = "Accès SSH sécurisé"
type = "tcp"
default_port = 22
scope_id = boundary_scope.project.id
host_source_ids = [
boundary_host_set_static.ssh_servers.id
]
}
# Rôle d'accès aux targets
resource "boundary_role" "infrastructure_access" {
name = "infrastructure-access"
description = "Accès aux ressources d'infrastructure"
scope_id = boundary_scope.project.id
grant_strings = [
"id=${boundary_target.ssh_target.id};actions=authorize-session",
"type=session;actions=read,list,cancel:self"
]
principal_ids = [boundary_group.infrastructure_team.id]
}
# Outputs
output "org_scope_id" {
value = boundary_scope.org.id
}
output "project_scope_id" {
value = boundary_scope.project.id
}
output "ssh_target_id" {
value = boundary_target.ssh_target.id
}
EOF
echo "Configuration Terraform Boundary créée"Intégration Vault et Boundary avec Terraform
Configuration complète du provider Vault
# terraform/vault-config.tf
terraform {
required_version = ">= 1.0"
required_providers {
vault = {
source = "hashicorp/vault"
version = "~> 3.21"
}
boundary = {
source = "hashicorp/boundary"
version = "~> 1.1"
}
}
}
provider "vault" {
address = var.vault_address
token = var.vault_token
}
variable "vault_address" {
description = "Adresse du serveur Vault"
type = string
default = "http://127.0.0.1:8200"
}
variable "vault_token" {
description = "Token d'authentification Vault"
type = string
default = "root"
sensitive = true
}
# Configuration du credential store Vault dans Boundary
resource "boundary_credential_store_vault" "vault_creds" {
name = "vault-credential-store"
description = "Store de credentials Vault pour certificats"
address = var.vault_address
token = var.vault_token
scope_id = boundary_scope.project.id
namespace = "admin"
}
# Credential library pour les certificats SSH
resource "boundary_credential_library_vault_ssh_certificate" "ssh_certs" {
name = "ssh-certificates"
description = "Certificats SSH depuis Vault PKI"
credential_store_id = boundary_credential_store_vault.vault_creds.id
path = "pki_int/sign/ssh-role"
username = "ubuntu"
# Extensions SSH personnalisées
extensions = {
permit-pty = ""
permit-user-rc = ""
}
# Principals (utilisateurs autorisés)
key_type = "ecdsa"
key_bits = 256
}
# Associer les credentials à la target SSH
resource "boundary_target" "ssh_target_with_creds" {
name = "ssh-server-with-vault-creds"
description = "SSH avec certificats Vault automatiques"
type = "ssh"
default_port = 22
scope_id = boundary_scope.project.id
host_source_ids = [
boundary_host_set_static.ssh_servers.id
]
# Injection automatique des credentials
injected_application_credential_source_ids = [
boundary_credential_library_vault_ssh_certificate.ssh_creds.id
]
}Configuration du renouvellement automatique avec Vault Agent
# Configuration Vault Agent pour le renouvellement automatique
# Fichier : configs/vault-agent.hcl
pid_file = "./vault-agent.pid"
exit_after_auth = false
vault {
address = "http://127.0.0.1:8200"
retry {
num_retries = 5
}
}
auto_auth {
method {
type = "token_file"
config {
token_file_path = "/tmp/vault-token"
}
}
sink {
type = "file"
config {
path = "/tmp/vault-agent-token"
mode = 0640
}
}
}
# Template pour certificat serveur auto-renouvelé
template {
source = "/home/$USER/vault-boundary-tutorial/configs/server-cert.tpl"
destination = "/home/$USER/vault-boundary-tutorial/outputs/auto-server.crt"
perms = 0600
command = "echo 'Server certificate renewed at $(date)' >> /home/$USER/vault-boundary-tutorial/logs/renewal.log"
}
# Template pour clé privée serveur
template {
source = "/home/$USER/vault-boundary-tutorial/configs/server-key.tpl"
destination = "/home/$USER/vault-boundary-tutorial/outputs/auto-server.key"
perms = 0600
}
# Template pour certificats clients
template {
source = "/home/$USER/vault-boundary-tutorial/configs/client-cert.tpl"
destination = "/home/$USER/vault-boundary-tutorial/outputs/auto-client.crt"
perms = 0600
}Templates de certificats pour Vault Agent
# Créer les templates de certificats
mkdir -p ~/vault-boundary-tutorial/configs/templates
# Template certificat serveur
cat > ~/vault-boundary-tutorial/configs/server-cert.tpl << 'EOF'
{{- with secret "pki_int/issue/server-role" "common_name=auto-server.novicore.local" "alt_names=api.novicore.local,web.novicore.local" "ttl=24h" -}}
{{ .Data.certificate }}
{{- end -}}
EOF
# Template clé privée serveur
cat > ~/vault-boundary-tutorial/configs/server-key.tpl << 'EOF'
{{- with secret "pki_int/issue/server-role" "common_name=auto-server.novicore.local" "alt_names=api.novicore.local,web.novicore.local" "ttl=24h" -}}
{{ .Data.private_key }}
{{- end -}}
EOF
# Template certificat client
cat > ~/vault-boundary-tutorial/configs/client-cert.tpl << 'EOF'
{{- with secret "pki_int/issue/client-role" "common_name=auto-client.novicore.local" "ttl=24h" -}}
{{ .Data.certificate }}
{{- end -}}
EOFDéploiement et tests
Script de déploiement complet
#!/bin/bash
# Script maître : deploy-complete-infrastructure.sh
set -e
echo "Déploiement de l'infrastructure Vault + Boundary + Terraform"
echo "=============================================================="
START_TIME=$(date +%s)
# Phase 1 : Préparation
echo "Phase 1 : Préparation de l'environnement"
bash ~/vault-boundary-tutorial/scripts/00-setup-environment.sh
# Phase 2 : Vault
echo "Phase 2 : Déploiement HashiCorp Vault"
bash ~/vault-boundary-tutorial/scripts/01-deploy-vault.sh
# Phase 3 : Configuration PKI
echo "Phase 3 : Configuration PKI et rôles"
bash ~/vault-boundary-tutorial/scripts/01-configure-pki.sh
# Phase 4 : Boundary
echo "Phase 4 : Déploiement HashiCorp Boundary"
bash ~/vault-boundary-tutorial/scripts/02-deploy-boundary.sh
# Phase 5 : Terraform
echo "Phase 5 : Application configuration Terraform"
cd ~/vault-boundary-tutorial/terraform
terraform init
terraform validate
terraform plan -out=tfplan
terraform apply tfplan
# Phase 6 : Vault Agent
echo "Phase 6 : Configuration Vault Agent"
echo "root" > /tmp/vault-token
nohup vault agent -config=~/vault-boundary-tutorial/configs/vault-agent.hcl \
> ~/vault-boundary-tutorial/logs/vault-agent.log 2>&1 &
echo $! > ~/vault-boundary-tutorial/vault-agent.pid
# Phase 7 : Tests
echo "Phase 7 : Tests de validation"
sleep 10
# Test 1 : Vault PKI
echo "Test 1 : Émission certificat via Vault"
vault write -format=json pki_int/issue/server-role \
common_name="final-test.novicore.local" \
ttl="24h" > ~/vault-boundary-tutorial/outputs/final-test.json
if [ $? -eq 0 ]; then
echo "Test Vault PKI : SUCCÈS"
else
echo "Test Vault PKI : ÉCHEC"
fi
# Test 2 : Boundary targets
echo "Test 2 : Liste des targets Boundary"
export BOUNDARY_ADDR='http://127.0.0.1:9200'
PROJECT_SCOPE=$(terraform output -raw project_scope_id)
boundary targets list -scope-id=$PROJECT_SCOPE > ~/vault-boundary-tutorial/outputs/boundary-targets.txt
if [ $? -eq 0 ]; then
echo "Test Boundary targets : SUCCÈS"
else
echo "Test Boundary targets : ÉCHEC"
fi
# Test 3 : Vault Agent renewal
echo "Test 3 : Vérification Vault Agent"
if [ -f ~/vault-boundary-tutorial/outputs/auto-server.crt ]; then
echo "Test Vault Agent : SUCCÈS"
openssl x509 -in ~/vault-boundary-tutorial/outputs/auto-server.crt -noout -dates
else
echo "Test Vault Agent : ÉCHEC"
fi
END_TIME=$(date +%s)
DURATION=$((END_TIME - START_TIME))
echo ""
echo "Déploiement terminé avec succès !"
echo "Durée totale : ${DURATION} secondes"
echo ""
echo "Informations d'accès :"
echo "- Vault UI : http://127.0.0.1:8200 (token: root)"
echo "- Boundary UI : http://127.0.0.1:9201"
echo "- Logs : ~/vault-boundary-tutorial/logs/"
echo "- Certificats : ~/vault-boundary-tutorial/outputs/"
echo ""Tests de validation et troubleshooting
#!/bin/bash
# Script de validation complète
echo "=== Tests de validation infrastructure ==="
# Source des environnements
source ~/vault-boundary-tutorial/configs/vault-env.sh
export BOUNDARY_ADDR='http://127.0.0.1:9200'
echo "1. Test de connectivité Vault"
vault status
if [ $? -eq 0 ]; then
echo "Vault accessible"
else
echo "Vault inaccessible - vérifiez les logs"
exit 1
fi
echo "2. Test PKI - Émission certificat"
vault write -format=json pki_int/issue/server-role \
common_name="validation.novicore.local" \
ttl="1h" > /tmp/validation_cert.json
if [ $? -eq 0 ]; then
echo "PKI fonctionnel"
# Vérifier le certificat
jq -r '.data.certificate' /tmp/validation_cert.json > /tmp/validation.crt
openssl x509 -in /tmp/validation.crt -text -noout | grep "Subject:"
else
echo "Problème PKI"
exit 1
fi
echo "3. Test Boundary - Liste des scopes"
boundary scopes list
echo "4. Test intégration - Certificats auto-renouvelés"
if [ -f ~/vault-boundary-tutorial/outputs/auto-server.crt ]; then
echo "Vault Agent fonctionnel"
echo "Détails du certificat auto-renouvelé :"
openssl x509 -in ~/vault-boundary-tutorial/outputs/auto-server.crt -text -noout | grep -A 2 "Validity"
else
echo "Vault Agent pas encore démarré ou problème"
fi
echo "5. Test complet - Connexion SSH via Boundary"
PROJECT_SCOPE=$(cd ~/vault-boundary-tutorial/terraform && terraform output -raw project_scope_id)
TARGET_ID=$(cd ~/vault-boundary-tutorial/terraform && terraform output -raw ssh_target_id)
echo "Scope projet : $PROJECT_SCOPE"
echo "Target SSH : $TARGET_ID"
# Test d'autorisation session (sans connexion réelle)
boundary targets authorize-session -id=$TARGET_ID
echo "Tous les tests de validation réussis"Bonnes pratiques et sécurisation pour la production
Checklist de sécurisation
Configuration Vault pour production :
- ✅ Utiliser un backend de stockage HA (Consul, Raft intégré)
- ✅ Activer le TLS pour tous les endpoints
- ✅ Configurer l'auto-unseal avec un KMS cloud
- ✅ Implémenter la sauvegarde automatique des snapshots
- ✅ Utiliser des tokens à durée limitée (pas de root permanent)
Configuration Boundary pour production :
- ✅ Déployer en mode cluster avec plusieurs controllers
- ✅ Utiliser une base de données managée (RDS, Azure SQL)
- ✅ Configurer l'authentification OIDC/LDAP
- ✅ Implémenter des workers dans chaque zone réseau
- ✅ Activer l'audit logging complet
Infrastructure Terraform :
- ✅ Utiliser un backend distant pour le state (S3, Azure Storage)
- ✅ Chiffrer le state avec une clé KMS
- ✅ Implémenter la validation de politique (OPA, Sentinel)
- ✅ Utiliser des modules réutilisables et versionnés
Monitoring et observabilité
# Configuration de monitoring pour l'infrastructure # Métriques Vault (Prometheus/Grafana) vault audit enable file file_path=/var/log/vault_audit.log # Métriques Boundary boundary config update-listener \ -scope-id=global \ -prometheus-addr=127.0.0.1:9203 # Logs centralisés (ELK Stack) # Configuration rsyslog pour centralisation echo "*.* @@logserver:514" >> /etc/rsyslog.conf
Conclusion et perspectives
Cette infrastructure Vault + Boundary + Terraform offre une base solide pour implémenter le Zero Trust dans votre organisation. Les certificats sont générés et renouvelés automatiquement, les accès sont contrôlés granulairementf et auditées, et l'ensemble reste reproductible via Infrastructure as Code.
Bénéfices immédiats :
- Élimination des mots de passe statiques et clés SSH permanentes
- Traçabilité complète des accès et sessions
- Isolation réseau des ressources critiques
- Conformité renforcée (ISO 27001, NIS2)
Prochaines étapes recommandées :
- Intégrer avec votre authentification d'entreprise (OIDC/SAML)
- Déployer des workers Boundary dans vos environnements cloud
- Automatiser la rotation des secrets applicatifs
- Implémenter des politiques de conformité automatisées
Cette approche s'inscrit parfaitement dans la stratégie de modernisation sécuritaire que nous prônons chez Novicore : transformer les contraintes de sécurité en avantages opérationnels grâce à l'automatisation intelligente.
Ce tutoriel vous a-t-il été utile ?
Votre retour nous aide à améliorer nos contenus
