Guida completa all'utilizzo di HashiCorp Vault in un ambiente Spring Boot
Indice
- Cos'è HashiCorp Vault?
- Il Ruolo di Vault in Produzione con Spring Boot
- Panoramica dell'Architettura di Sistema
- Autenticazione e Rischi di Sicurezza
- Vault Agent e Integrazione Sicura
- Configurazione di Vault per la Memorizzazione dei Segreti e l'Impostazione di HTTPS
- Configurazione di Vault per il Motore di Transito (Crittografia e Decrittografia)
- Gestione del Token di Vault in Spring Boot
- Conclusione
Cos'è HashiCorp Vault?
HashiCorp Vault è uno strumento open-source progettato per gestire i segreti e proteggere i dati sensibili. Fornisce uno storage centralizzato per i segreti, controllo degli accessi e registrazione degli audit. Vault si integra facilmente con varie piattaforme cloud, consentendo di proteggere i dati sensibili sia in ambienti cloud-native che on-premise.
Il Ruolo di Vault in Produzione con Spring Boot
In produzione, Vault assicura che i segreti, come le credenziali del database, siano gestiti dinamicamente, eliminando la necessità di informazioni sensibili hardcoded nell'applicazione.
Vantaggi di HashiCorp Vault per la Gestione dei Segreti
- Storage Centralizzato per i Segreti: Previene la presenza di segreti hardcoded nel codice, riducendo la superficie di attacco.
- Credenziali Dinamiche: Genera credenziali temporanee, minimizzando i rischi di sicurezza.
- Audit e Conformità: I log di audit integrati aiutano a monitorare gli accessi e a soddisfare i requisiti normativi.
Panoramica dell'Architettura di Sistema
Componenti dell'Architettura Un tipico setup di Vault in produzione con Spring Boot comprende:
- Applicazione Spring Boot: Il framework microservizi principale basato su Java.
- Vault Agent: Intermediario sul server di produzione dove gira Spring Boot, che recupera i segreti dal server Vault.
- Server Vault: Gestisce e memorizza i segreti in modo sicuro.
- Database SQL: Backend che contiene i dati dell'applicazione e richiede accesso sicuro tramite credenziali dinamiche.
Diagramma del Flusso dei Segreti I seguenti passaggi illustrano come i segreti vengono recuperati e utilizzati:
- Spring Boot richiede credenziali dal Vault Agent.
- Il Vault Agent si autentica al server Vault e recupera i segreti necessari.
- Le credenziali vengono iniettate in modo sicuro nell'applicazione, che poi si connette al database SQL.
Autenticazione e Rischi di Sicurezza
Rischi nella Memorizzazione delle Credenziali Memorizzare nomi utente e password in chiaro o in file di configurazione può esporli agli attacchi, creando un rischio significativo per la sicurezza.
Strategie di Mitigazione
- Evitare Credenziali Statiche: Utilizzare credenziali dinamiche anziché nomi utente e password hardcoded.
- Autenticazione AppRole: Il metodo AppRole di Vault consente l'autenticazione non interattiva con token dinamici, migliorando la sicurezza.
- Secret Wrapping: Vault può incapsulare i segreti in un token a tempo limitato per passare in modo sicuro le credenziali tra i sistemi.
Vault Agent e Integrazione Sicura
Configurare il Vault Agent in un Ambiente di Produzione In un ambiente di produzione, il Vault Agent è distribuito sullo stesso server dell'applicazione Spring Boot, mentre il server Vault si trova su una macchina separata. Tutte le comunicazioni tra il Vault Agent, il server Vault e il database SQL sono sicure tramite crittografia TLS.

Environment overview

Panoramica del Setup dell'Ambiente:
- Server Vault (IP: 192.168.101.1): Gestisce i segreti e li fornisce in modo sicuro alle applicazioni autorizzate.
- Vault Agent (IP: 192.168.101.2): Intermediario sul server di produzione dove gira Spring Boot, che recupera i segreti dal server Vault.
- Database SQL (IP: 192.168.101.3): Memorizza i dati dell'applicazione, accessibili tramite credenziali gestite da Vault.
- Crittografia TLS: Garantisce la privacy e l'integrità dei dati nelle comunicazioni tra i componenti di Vault.
Esempio di Configurazione del Vault Agent: Ecco come configurare il Vault Agent sul server di produzione (192.168.101.2) per recuperare in modo sicuro i segreti dal server Vault (192.168.101.1) tramite TLS.
auto_auth {
method "approle" {
mount_path = "auth/approle"
config = {
role_id_file_path = "/etc/vault/role_id"
secret_id_file_path = "/etc/vault/secret_id"
}
}
}
cache {
use_auto_auth_token = true
}
listener "tcp" {
address = "0.0.0.0:8200"
tls_cert_file = "/etc/vault-agent/certs/vault-agent.crt"
tls_key_file = "/etc/vault-agent/certs/vault-agent.key"
tls_client_ca_file = "/etc/vault-agent/certs/ca.crt"
}
vault {
address = "https://192.168.101.1:8200"
}
Integrazione di Spring Boot in Produzione
L'applicazione Spring Boot in esecuzione su 192.168.101.2 comunica con il Vault Agent per recuperare in modo sicuro le credenziali dinamiche.
Esempio: Proprietà dell'Applicazione per l'Integrazione con Vault:
spring:
cloud:
vault:
uri: https://127.0.0.1:8200 # Vault Agent local communication
authentication: APPROLE
token: ${VAULT_TOKEN}
Configurazione di Vault per la Memorizzazione dei Segreti e l’Impostazione di HTTPS
Memorizzazione dei Segreti per Spring Boot
Per memorizzare segreti, come le credenziali del database, in Vault e recuperarli in modo sicuro in un'applicazione Spring Boot, segui questi passaggi:
Step 1: Abilitare il Motore dei Segreti KV
Step 2: Memorizzare i Segreti
Step 3: Configurare Spring Boot per Recuperare i Segreti
spring:
cloud:
vault:
kv:
enabled: true
uri: https://192.168.101.1:8200
authentication: APPROLE
token: ${VAULT_TOKEN}
kv:
backend: secret
Abilitare HTTPS su Vault
Per abilitare HTTPS e garantire comunicazioni sicure tra Vault, Vault Agent e Spring Boot, è necessario configurare Vault con certificati SSL.
Step 1: Generare Certificati SSL
Step 2: Configurare Vault per HTTPS
listener "tcp" {
address = "0.0.0.0:8200"
tls_cert_file = "/etc/vault/vault.crt"
tls_key_file = "/etc/vault/vault.key"
}
storage "file" {
path = "/vault/data"
}
Step 3: Avviare Vault con HTTPS
Configurazione di Vault per il Motore di Transito (Crittografia e Decrittografia)
Il motore Transit di Vault è progettato per operazioni crittografiche come la crittografia e la decrittografia dei dati. Di seguito sono riportati i passaggi per configurare Vault per gestire la crittografia e la decrittografia utilizzando la chiave di crittografia my-encryption-key.
Step 1: Abilitare il Motore dei Segreti Transit
Per abilitare il motore dei segreti Transit, usa il CLI di Vault. Questo motore è responsabile della gestione delle chiavi di crittografia e dell’esecuzione delle operazioni crittografiche come la crittografia e la decrittografia dei dati.
This command enables the Transit
Secrets Engine at the default path, transit/. If you
want to enable it at a custom path, you can specify that with the -path
flag, but for simplicity, we’ll stick with the default.
Step 2: Creare una Chiave di Crittografia
This command creates a
named encryption key (my-encryption-key) under the Transit
engine. By default, the key is generated with 256-bit
AES-GCM encryption. You can customize the key type by specifying
additional parameters if needed.
Step 3: Configurare le Autorizzazioni della Chiave
Abilitare la Decrittografia: Per impostazione predefinita, Vault abilita sia la crittografia che la decrittografia.
Puoi verificare lo stato e la configurazione della chiave con:
Step 4: Utilizzare la Chiave per Crittografia e Decrittografia
Crittografare i Dati
To encrypt data using the my-encryption-key:
curl --header "X-Vault-Token: $VAULT_TOKEN" \
--request POST \
--data '{"plaintext": "VGhpcyBpcyBhIHNlY3JldCBtZXNzYWdl"}' \
https://192.168.101.1:8200/v1/transit/encrypt/my-encryption-key
Nella richiesta precedente:
Il campo
plaintextcontiene i dati codificati in base64 da crittografare (VGhpcyBpcyBhIHNlY3JldCBtZXNzYWdl è "This is a secret message" in Base64).Il server Vault risponde con una stringa di
ciphertext.
Decrittografare i Dati
To decrypt the data using the same key:
curl --header "X-Vault-Token: $VAULT_TOKEN" \
--request POST \
--data '{"ciphertext": "vault:v1:i8NjUu..."}' \
https://192.168.101.1:8200/v1/transit/decrypt/my-encryption-key
Nella richiesta precedente:
- Il campo
ciphertextcontiene la stringa criptata restituita da Vault durante il processo di crittografia.
Implementare Crittografia e Decrittografia in Spring Boot
Una volta configurato il server Vault, puoi integrare la crittografia e la decrittografia nella tua applicazione Spring Boot. Ecco il codice Java per crittografare e decrittografare i dati:
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.web.client.RestTemplate;
import org.springframework.http.ResponseEntity;
import org.springframework.web.client.HttpClientErrorException;
import java.util.Base64;
import java.util.HashMap;
import java.util.Map;
public class VaultEncryptionService {
private RestTemplate restTemplate;
private static final String VAULT_TRANSIT_ENCRYPT_URL =
"https://192.168.101.1:8200/v1/transit/encrypt/my-encryption-key";
private static final String VAULT_TRANSIT_DECRYPT_URL =
"https://192.168.101.1:8200/v1/transit/decrypt/my-encryption-key";
// Encrypt Data
public String encryptData(String plaintext) {
Map<String, String> requestBody = new HashMap<>();
requestBody.put("plaintext", Base64.getEncoder().encodeToString(plaintext.getBytes()));
try {
ResponseEntity<Map<String, Object>> response = restTemplate.postForEntity(
VAULT_TRANSIT_ENCRYPT_URL, requestBody, Map.class);
if (response.getBody() != null && response.getBody().containsKey("ciphertext")) {
return (String) response.getBody().get("ciphertext");
} else {
throw new RuntimeException("Encryption failed: no ciphertext returned");
}
} catch (HttpClientErrorException e) {
throw new RuntimeException("Error during encryption request: " + e.getResponseBodyAsString(), e);
}
}
// Decrypt Data
public String decryptData(String ciphertext) {
Map<String, String> requestBody = new HashMap<>();
requestBody.put("ciphertext", ciphertext);
try {
ResponseEntity<Map<String, Object>> response = restTemplate.postForEntity(
VAULT_TRANSIT_DECRYPT_URL, requestBody, Map.class);
if (response.getBody() != null && response.getBody().containsKey("plaintext")) {
String base64Decrypted = (String) response.getBody().get("plaintext");
return new String(Base64.getDecoder().decode(base64Decrypted));
} else {
throw new RuntimeException("Decryption failed: no plaintext returned");
}
} catch (HttpClientErrorException e) {
throw new RuntimeException("Error during decryption request: " + e.getResponseBodyAsString(), e);
}
}
}
Gestione del Token di Vault in Spring Boot
Il VAULT_TOKEN è una parte fondamentale del processo di autenticazione tra la tua applicazione Spring Boot e HashiCorp Vault. I token di Vault possono essere iniettati nella tua applicazione Spring Boot tramite variabili d'ambiente, rendendo il token disponibile a runtime senza hardcodificarlo nei file di configurazione, migliorando così la sicurezza.
Step 1: Configurare la Gestione del Token di Vault
Esistono due metodi principali per gestire il VAULT_TOKEN in modo sicuro:
Usare Vault Agent con Auto-Auth: Il Vault Agent si autentica con Vault e inietta automaticamente il token nell'ambiente.
Impostare Manualmente la Variabile d'Ambiente: Il token può essere esportato come variabile d'ambiente durante il deployment.
Utilizzare Vault Agent per la Gestione del Token
In questa configurazione:
- Il Vault Agent si autentica utilizzando AppRole con i file
role_idesecret_id. - Il parametro
token_fileindica dove verrà memorizzato il token dopo un’autenticazione riuscita (/etc/vault/token). - Il token viene memorizzato nella cache e rinnovato automaticamente, garantendo che sia sempre disponibile senza intervento manuale.
Iniettare il Token in Spring Boot
Una volta che il Vault Agent ha recuperato il token e lo ha scritto nel file token_file, puoi configurare Spring Boot per leggere il token da questo file o direttamente dall'ambiente:
Questo rende il
VAULT_TOKEN disponibile come variabile d'ambiente.2. Manually Setting the Vault Token as an Environment Variable
You can also export the Vault token directly as an environment variable when deploying your application. For example, in your CI/CD pipeline or server deployment script:
Step 2: Iniettare il VAULT_TOKEN nelle Proprietà di Spring Boot
Nella tua applicazione Spring Boot, puoi fare riferimento alla variabile d'ambiente VAULT_TOKEN all'interno del file application.yml o application.properties:
spring:
cloud:
vault:
uri: https://192.168.101.1:8200
authentication: APPROLE
token: ${VAULT_TOKEN}
Spring Boot risolverà automaticamente il segnaposto ${VAULT_TOKEN} leggendo il valore dalla variabile d'ambiente esportata durante il deployment o gestita dal Vault Agent.
Step 3: Testare la Configurazione
Per verificare che il VAULT_TOKEN sia correttamente iniettato nell'applicazione, puoi eseguire il seguente comando:
Se il token è impostato correttamente, verrà stampato il token, e Spring Boot lo utilizzerà per autenticarsi con Vault.
Gestione del Rinnovo e della Scadenza del Token
Se utilizzi il Vault Agent, il token viene automaticamente rinnovato prima della scadenza, grazie ai meccanismi di auto-autenticazione e cache. Se gestisci manualmente il token, assicurati che venga rinnovato regolarmente tramite il tuo processo di CI/CD o deployment, poiché i token di Vault hanno una durata limitata (TTL).
Sfide e Considerazioni in Produzione:
- Latenza: Potrebbe esserci un leggero aumento della latenza se l'applicazione recupera frequentemente segreti da Vault. Per mitigare questo problema, puoi memorizzare i segreti in cache localmente nell'applicazione o utilizzare i meccanismi di cache integrati di Vault.
- Disponibilità di Vault: In ambienti di produzione, è fondamentale garantire un'elevata disponibilità di Vault. Puoi distribuire Vault in modalità altamente disponibile con Consul o utilizzare l'archiviazione Raft di Vault per garantire la disponibilità continua.
- Configurazioni di Sicurezza: TLS deve essere configurato per la comunicazione tra l'applicazione Spring Boot e Vault, soprattutto in produzione. Inoltre, l'utilizzo di metodi di autenticazione come AppRole o Kubernetes può fornire modi più sicuri per autenticare le applicazioni senza incorporare token statici nell'applicazione.
Conclusione
L'integrazione di HashiCorp Vault con Spring Boot garantisce una gestione sicura e centralizzata dei segreti in ambienti di produzione. Utilizzando le capacità di generazione dinamica delle credenziali e crittografia di Vault, gli sviluppatori possono ridurre il rischio di esposizione di dati sensibili, migliorando la sicurezza delle loro applicazioni.
Riferimenti:
- HashiCorp Vault Documentation
- Spring Cloud Vault Documentation
- Database Secrets Engine in Vault
- Introduction to HashiCorp Vault: A Comprehensive Guide and Essential Commands
- Essential HashiCorp Vault Guide and Commands
- Illustrazioni generate con l'aiuto dell'intelligenza artificiale di OpenAI.
Su di me
Sono appassionato di tecnologie IT. Se sei interessato a saperne di più o a rimanere aggiornato sui miei ultimi articoli, sentiti libero di connetterti con me su:
LinkedIn
Instagram
Personal Website
Non esitare a contattarmi attraverso queste piattaforme se hai domande!
Non vedo l'ora di conoscere i tuoi pensieri! 👇


Commenti
Posta un commento