Configurazione SSL/TLS per Connessioni PostgreSQL Sicure: Guida Completa
Impara come proteggere le connessioni PostgreSQL con la crittografia SSL/TLS. Questa guida completa copre la configurazione lato server e client, inclusa la generazione di certificati, la modifica di `postgresql.conf` e `pg_hba.conf`, e la configurazione dei client per una comunicazione sicura e crittografata. Proteggi i tuoi dati sensibili in transito e garantisci la conformità con gli standard di sicurezza moderni.
Configurazione SSL/TLS per Connessioni PostgreSQL Sicure: Guida Completa
La configurazione SSL/TLS di PostgreSQL ha due compiti distinti. Il primo è la crittografia, in modo che nessuno sulla rete possa leggere le credenziali o i risultati delle query in transito. Il secondo è l'identità, in modo che il client sappia di parlare con il vero server di database e non con una macchina che si finge tale. Molte configurazioni eseguono la prima parte e accidentalmente saltano la seconda.
Questa distinzione è importante nelle distribuzioni reali. sslmode=require crittografa la connessione, ma da solo non verifica completamente il nome host del server. sslmode=verify-full lo fa. Se la tua applicazione si connette attraverso una rete pubblica, una rete aziendale condivisa, un overlay Kubernetes che non controlli completamente, o qualsiasi ambiente in cui il traffico potrebbe essere intercettato, verify-full dovrebbe essere l'obiettivo.
Comprensione di SSL/TLS in PostgreSQL
SSL/TLS (Secure Sockets Layer/Transport Layer Security) è un protocollo crittografico progettato per fornire sicurezza della comunicazione su una rete informatica. Quando applicato a PostgreSQL, crittografa i dati scambiati tra il server di database e i suoi client. Ciò impedisce a parti non autorizzate di intercettare e leggere informazioni sensibili come credenziali, dati finanziari o dettagli personali.
I client PostgreSQL supportano diverse modalità SSL:
sslmode=disable: Usa solo una connessione semplice e non crittografata.sslmode=prefer: Prova prima TLS, poi torna a TCP semplice se TLS non è disponibile. Questo è comodo, ma può nascondere una configurazione errata.sslmode=require: Richiede la crittografia TLS, ma non verifica necessariamente il nome host del server.sslmode=verify-ca: Richiede TLS e verifica che il certificato sia collegato a una CA attendibile.sslmode=verify-full: Richiede TLS, verifica la CA e verifica che il nome host corrisponda al certificato.
Lato server, ssl = on significa solo che PostgreSQL è in grado di accettare connessioni TLS. Non forza ogni client a usare TLS. L'applicazione avviene in pg_hba.conf con regole hostssl ed evitando regole host più ampie che consentono agli stessi utenti e reti di connettersi senza TLS.
Prerequisiti per la Configurazione SSL/TLS
Prima di iniziare a configurare PostgreSQL per SSL/TLS, assicurati di avere quanto segue:
- OpenSSL Installato: Il toolkit OpenSSL è essenziale per generare e gestire i certificati SSL. Di solito è preinstallato sui sistemi Linux e macOS. Per Windows, potresti doverlo scaricare e installare separatamente.
- Accesso ai File di Configurazione di PostgreSQL: Avrai bisogno di privilegi amministrativi per modificare i file
postgresql.confepg_hba.conf. - Comprensione delle Autorità di Certificazione (CA): Mentre puoi creare certificati autofirmati per i test, gli ambienti di produzione dovrebbero idealmente utilizzare certificati firmati da un'Autorità di Certificazione (CA) attendibile o da una CA aziendale interna.
Configurazione SSL/TLS Lato Server
La configurazione lato server comporta l'abilitazione di SSL, la specifica della posizione dei certificati e delle chiavi SSL e la configurazione dell'autenticazione del client.
1. Generazione o Ottenimento di Certificati e Chiavi SSL
Ci sono due modi principali per ottenere certificati SSL per il tuo server PostgreSQL:
- Certificati Autofirmati (per test/sviluppo): Questi vengono creati usando OpenSSL e non sono attendibili per impostazione predefinita dai client esterni. Sono utili per la configurazione iniziale e i test interni.
- Certificati da un'Autorità di Certificazione (CA) (per produzione): Ottieni certificati da una CA pubblica attendibile (es. Let's Encrypt, DigiCert) o da una CA aziendale interna. Questo garantisce che i client possano verificare l'identità del server.
Creazione di Certificati Autofirmati usando OpenSSL:
Questo è un approccio comune per ambienti di sviluppo e interni. Esegui i seguenti comandi sul tuo server PostgreSQL o su una macchina con OpenSSL:
Crea una directory per i certificati: È buona pratica tenere i certificati organizzati.
sudo mkdir -p /etc/postgresql/ssl sudo chown postgres:postgres /etc/postgresql/ssl cd /etc/postgresql/sslGenera la Chiave Privata del Server: Questa chiave deve essere tenuta segreta.
sudo openssl genrsa -out server.key 2048Crea una Richiesta di Firma del Certificato (CSR) del Server: Contiene informazioni sul tuo server.
sudo openssl req -new -key server.key -out server.csrUsa il nome host a cui i client si connetteranno, come
db01.internal.example.com. I client moderni normalmente controllano il Subject Alternative Name (SAN), quindi includi i nomi DNS nella richiesta del certificato quando il tuo processo CA lo supporta.Firma il Certificato con la Tua CA (per uso interno) :
- Crea una chiave privata e un certificato CA root (se non ne hai uno):
# Genera la chiave privata CA sudo openssl genrsa -des3 -out root.key 2048 # Crea il certificato CA (valido per 3650 giorni) sudo openssl req -new -x509 -days 3650 -key root.key -out root.crt - Firma la CSR del server con la CA: Questo crea il certificato del server attendibile.
sudo openssl x509 -req -days 365 -in server.csr -CA root.crt -CAkey root.key -set_serial 01 -out server.crt
- Crea una chiave privata e un certificato CA root (se non ne hai uno):
Imposta i Permessi: Assicurati che l'utente PostgreSQL possa leggere questi file.
sudo chown postgres:postgres server.key server.crt root.crt sudo chmod 600 server.key sudo chmod 644 server.crt root.crt
Utilizzo di Certificati da una CA Pubblica/Aziendale:
Se ottieni certificati da una CA, di solito riceverai:
server.crt: Il certificato pubblico del tuo server.server.key: La chiave privata del tuo server.root.crt(o simile): Il certificato root della CA (e potenzialmente certificati intermedi).
Posiziona questi file in una directory sicura (es. /etc/postgresql/ssl/) e assicurati che l'utente PostgreSQL abbia i permessi di lettura.
2. Configurazione di postgresql.conf
Modifica il tuo file postgresql.conf (di solito situato nella directory dei dati di PostgreSQL) per abilitare SSL e specificare i file del certificato.
#------------------------------------------------------------------------------
# SSL
#------------------------------------------------------------------------------
ssl = on
# Questi sono tutti in formato PEM e vengono ignorati se la chiave/certificato del server
# non sono configurati. Per impostazione predefinita, i file dovrebbero trovarsi nella directory
# dei dati del server. In alternativa, possono essere specificati come percorsi completi.
ssl_cert_file = '/etc/postgresql/ssl/server.crt' # (cambia il nome file se necessario)
ssl_key_file = '/etc/postgresql/ssl/server.key' # (cambia il nome file se necessario)
ssl_ca_file = '/etc/postgresql/ssl/root.crt' # (opzionale, per la verifica del certificato client)
# Opzionale: specifica l'elenco di cifrari se necessario
#ssl_ciphers = 'HIGH:MEDIUM:+3DES:!aNULL'
# Opzionale: abilita la verifica del certificato client
#ssl_ca_file deve essere impostato su un file contenente i certificati CA da considerare attendibili
#ssl_crl_file = ''
#ssl_crl_dir = ''
ssl = on: Abilita il supporto SSL sul server.ssl_cert_file: Percorso del certificato pubblico del server.ssl_key_file: Percorso della chiave privata del server.ssl_ca_file: Percorso dei certificati CA che PostgreSQL deve considerare attendibili quando verifica i certificati client. I client usano il proprio file CA, comesslrootcert, per verificare il server.
3. Configurazione di pg_hba.conf per l'Applicazione SSL
Il file pg_hba.conf controlla l'autenticazione del client. Devi modificare le voci per applicare le connessioni SSL.
Per impostazione predefinita, le voci in pg_hba.conf appaiono così:
# TYPE DATABASE USER ADDRESS METHOD
local all all peer
# Connessioni locali IPv4:
host all all 127.0.0.1/32 scram-sha-256
# Connessioni locali IPv6:
host all all ::1/128 scram-sha-256
Per applicare SSL, cambia le voci host in hostssl:
# TYPE DATABASE USER ADDRESS METHOD
local all all peer
# Connessioni locali IPv4:
hostssl all all 127.0.0.1/32 scram-sha-256
# Connessioni locali IPv6:
hostssl all all ::1/128 scram-sha-256
# Esempio per accesso a rete esterna - richiede SSL
hostssl all app_user 10.20.0.0/16 scram-sha-256
hostssl all app_user 2001:db8:20::/48 scram-sha-256
hostssl: Questo tipo di record richiede connessioni SSL. Qualsiasi tentativo di connessione senza SSL verrà rifiutato.hostnossl: Questo tipo di record vieta esplicitamente le connessioni SSL.host: Consente sia connessioni SSL che non SSL. Se esiste una regolahostcorrispondente prima o al posto della tua regolahostssl, i client potrebbero ancora connettersi senza TLS.
Evita di pubblicare l'accesso 0.0.0.0/0 a meno che non ci sia una forte ragione e altri controlli siano in atto. La maggior parte dei database di produzione dovrebbe accettare connessioni solo da sottoreti di applicazioni, host bastion, pooler di connessioni o intervalli di rete privati.
4. Riavvio del Server PostgreSQL
Dopo aver modificato postgresql.conf e pg_hba.conf, devi riavviare il servizio PostgreSQL affinché le modifiche abbiano effetto.
# Per sistemi che usano systemd (la maggior parte delle distribuzioni Linux moderne)
sudo systemctl restart postgresql
# Per sistemi che usano init.d
sudo service postgresql restart
Configurazione SSL/TLS Lato Client
Anche i client devono essere configurati per connettersi in modo sicuro. Ciò comporta la specifica dei parametri di connessione, la potenziale fornitura di certificati client e la verifica del certificato del server.
1. Parametri della Stringa di Connessione
Quando ti connetti tramite psql o qualsiasi libreria client PostgreSQL, puoi specificare i parametri SSL nella stringa di connessione o come opzioni individuali.
Connessione SSL di Base (Solo Autenticazione del Server):
psql "sslmode=require host=nome_host_server dbname=nome_db user=nome_utente"
sslmode: Controlla il comportamento SSL del client.disable: Consenti solo connessioni non SSL.allow: Consenti non SSL, ma preferisci SSL se il server lo supporta.prefer(predefinito): Preferisci SSL, ma consenti non SSL se SSL fallisce.require: Consenti solo connessioni SSL. Se il server non supporta SSL, la connessione fallisce.verify-ca: Consenti solo connessioni SSL e verifica che il certificato del server sia firmato da una CA attendibile. Il parametrosslrootcertdeve essere impostato.verify-full: Consenti solo connessioni SSL, verifica il certificato del server rispetto a una CA attendibile e verifica che il nome host del server corrisponda al nome comune (CN) o al subject alternative name (SAN) del certificato.
Verifica del Certificato del Server (verify-ca o verify-full):
Per una sicurezza migliorata, i client dovrebbero verificare l'identità del server. Ciò richiede che il client si fidi della CA che ha firmato il certificato del server.
- Ottieni il Certificato CA: Ottieni il file
root.crt(o il certificato CA appropriato) che è stato usato per firmare il certificato del server. - Specifica
sslrootcert: Dì al client dove trovare questo certificato CA.
psql "sslmode=verify-full host=nome_host_server dbname=nome_db user=nome_utente sslrootcert=/percorso/del/tuo/root.crt"
Questa è la stringa di connessione che dovresti testare dallo stesso host o contenitore che esegue l'applicazione. Un errore comune è che psql funzioni da un laptop amministratore perché il file CA esiste lì, mentre il contenitore dell'applicazione fallisce perché il bundle CA non è mai stato montato.
2. Certificati Client (Autenticazione Reciproca)
Per un livello di sicurezza ancora più elevato, puoi implementare l'autenticazione reciproca, in cui il server verifica anche l'identità del client utilizzando i certificati client.
Generazione di Certificati Client:
Simile ai certificati del server, avrai bisogno di una chiave privata client e di un certificato client firmato da una CA attendibile dal server (spesso la stessa CA del certificato del server).
Genera la Chiave Privata Client:
openssl genrsa -des3 -out client.key 2048Crea la CSR del Client:
openssl req -new -key client.key -out client.csrFornisci i dettagli, assicurandoti che il Common Name sia univoco per il client.
Firma la CSR del Client con la CA:
sudo openssl x509 -req -days 365 -in client.csr -CA root.crt -CAkey root.key -set_serial <serial_univoco> -out client.crtImposta i Permessi:
chmod 600 client.key chmod 644 client.crt
Configurazione di pg_hba.conf per l'Autenticazione con Certificato Client:
Sul server, devi configurare pg_hba.conf per accettare l'autenticazione con certificato client. Questo spesso usa il metodo di autenticazione cert.
# TYPE DATABASE USER ADDRESS METHOD
# Richiede SSL e autenticazione con certificato client per utente/db specifico
hostssl all tuo_utente ip_client/32 cert map=tua_mappa_cert
Potresti anche dover definire un file di mappa dei certificati (opzione cert_map) se vuoi mappare dettagli specifici del certificato client (come Subject o SubjectAltName) agli utenti PostgreSQL. Consulta la documentazione ufficiale di PostgreSQL per la configurazione dettagliata dell'autenticazione cert e della mappatura dei certificati.
Configurazione del Client per Usare i Certificati:
Aggiorna la stringa di connessione del client per includere i percorsi del suo certificato e della sua chiave:
psql "sslmode=verify-full host=nome_host_server dbname=nome_db user=nome_utente \
sslrootcert=/percorso/del/tuo/root.crt sslcert=/percorso/del/tuo/client.crt sslkey=/percorso/del/tuo/client.key"
Best Practice e Suggerimenti
- Usa
sslmode=verify-full: Punta a usareverify-fulllato client per ridurre il rischio di attacchi man-in-the-middle. - Proteggi le Chiavi Private: Assicurati che le chiavi private (file
.key) abbiano permessi di file rigorosi (es.chmod 600) e siano leggibili solo dall'utente PostgreSQL sul server e dall'utente che si connette sul client. - Rinnova Regolarmente i Certificati: I certificati hanno date di scadenza. Implementa un processo per rinnovarli prima che scadano per evitare interruzioni della connessione.
- Gestione Centralizzata dei Certificati: Per distribuzioni più grandi, considera l'uso di un sistema di gestione dei certificati o l'automazione dell'emissione e del rinnovo dei certificati.
- Monitora i Log: Controlla i log di PostgreSQL per eventuali errori relativi a SSL durante l'avvio o i tentativi di connessione.
- Documentazione: Fai riferimento alla documentazione ufficiale di PostgreSQL per i parametri più aggiornati e le opzioni di configurazione avanzate specifiche per la tua versione di PostgreSQL.
Lista di Controllo Rapida per la Verifica
Dopo aver riavviato PostgreSQL, controlla che il server stia ascoltando con TLS abilitato:
SHOW ssl;
SHOW ssl_cert_file;
SHOW ssl_key_file;
Poi testa da un host client:
psql "host=nome_host_server dbname=nome_db user=nome_utente sslmode=verify-full sslrootcert=/percorso/di/root.crt"
All'interno della sessione, conferma che la connessione sia crittografata:
SELECT ssl, version, cipher
FROM pg_stat_ssl
WHERE pid = pg_backend_pid();
Se ssl è falso, le tue regole pg_hba.conf non stanno applicando ciò che pensi. Se verify-full fallisce ma require funziona, probabilmente il certificato manca del nome host corretto, il client non si fida della CA, o l'applicazione si connette tramite indirizzo IP mentre il certificato è emesso per un nome DNS.
Una buona configurazione TLS di PostgreSQL non è solo ssl = on. È una catena: un certificato con i nomi giusti, chiavi private con permessi rigorosi, regole hostssl che applicano effettivamente TLS e client che verificano il server invece di crittografare semplicemente il socket.