Notification

Cookies de sécurité

Nous utilisons uniquement des cookies essentiels pour sécuriser notre formulaire de contact. En savoir plus

Google Analytics

Analyse l'utilisation du site

Protection reCAPTCHA

Empêche les soumissions automatisées

Premier audit gratuit

En savoir +
Infrastructure Zero Trust avec HashiCorp Vault, Boundary et Terraform
Dev-sec-ops
+2

Infrastructure Zero Trust avec HashiCorp Vault, Boundary et Terraform

Equipe Novicore

Auteur

21 Oct 2025

Date de publication

45 mins

Temps de lecture

Guide pas à pas

Suivez ce tutoriel étape par étape pour maîtriser le sujet

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.

126d418c.png


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é.

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

bash
#!/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 :

bash
# 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.

3ef71cc3.png

Déploiement de Vault en mode développement

bash
#!/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

bash
#!/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

bash
#!/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

bash
#!/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.

f60213cd.png

Déploiement de Boundary

bash
#!/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

bash
#!/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

hcl
# 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

hcl
# 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

bash
# 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 -}}
EOF

Déploiement et tests

Script de déploiement complet

bash
#!/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

bash
#!/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é

bash
# 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

Tutoriels récents

Aucun tutoriel

Le contenu sera bientôt disponible. Revenez plus tard !

Newsletter

Soyez les premiers informés de nos derniers tutoriels, analyses de sécurité et conseils d'experts en cybersécurité.

Bientôt disponible