PostgreSQL non scopre mai che un client è su una VPN. Riceve una connessione TCP da un indirizzo e un insieme di credenziali, e decide cosa farne. Rendere quindi l’accesso dipendente dal tunnel significa disporre tre decisioni separate in modo che concordino, e poi controllare l’unico indirizzo che il server vede davvero invece di quello che avete disegnato nello schema.

Tre decisioni che non devono fondersi

Dove il server ascolta è una decisione. Quale traffico può raggiungere quell’indirizzo è una seconda, presa dal firewall dell’host e da qualsiasi confine di rete davanti ad esso. Quale identità di database può autenticarsi da quale origine è una terza, presa in pg_hba.conf.

Ciascuna è applicata da un componente diverso, e ciascuna fallisce con un messaggio diverso. Fonderle in una discussione è il modo in cui le persone finiscono per modificare il file HBA per risolvere un problema di firewall. Tenetele in ordine: un listener non associato non può essere raggiunto, a una porta filtrata non ci si può connettere, e una regola HBA decide solo ciò che accade dopo che esiste una connessione. Quando una modifica non ha effetto, identificate quale dei tre livelli avete realmente cambiato.

Dove il server ascolta

Associate a un indirizzo realmente assegnato alla macchina, non a un nome di interfaccia:

listen_addresses = '10.20.0.30'

Il database può stare dietro il gateway VPN senza una propria interfaccia di tunnel, ed è esattamente per questo che un indirizzo è la cosa giusta da nominare. Modificare questa impostazione richiede un riavvio completo; un ricaricamento non basta.

Poi filtrate la porta, normalmente 5432, sull’host e su ogni confine davanti ad esso. Associarsi a un indirizzo privato non è prova di diniego pubblico, perché un inoltro di porta o una mappatura di indirizzo cloud può ancora consegnare pacchetti a quel listener privato.

L’indirizzo che l’HBA vede davvero

Con accesso instradato il server vede l’indirizzo interno del tunnel di ogni client. Con la traduzione dell’origine vede invece l’indirizzo tradotto del gateway, e ogni client collassa in quel singolo valore. Ispezionate l’origine attraverso le prove di connessione del server stesso prima di scegliere un prefisso da consentire.

Per una distribuzione che usa già TLS e SCRAM, un esempio di accesso remoto volutamente stretto appare così:

hostssl appdb app_login 10.8.0.0/24 scram-sha-256
host all all 0.0.0.0/0 reject
host all all ::/0 reject

Ciò consente un ruolo e un database su TLS dal pool indicato, poi rifiuta altri accessi TCP remoti. Non sostituisce un file HBA completo: mantenete l’amministrazione locale, la replica e qualsiasi altro servizio autorizzato, e collocate le regole strette prima delle autorizzazioni più ampie.

Quando la traduzione è in gioco, l’HBA non può distinguere i client dai loro indirizzi originali. Mantenete l’ammissione di rete rigorosa e richiedete credenziali reali del database, e non sostituite mai l’autenticazione trust con un account reale.

Vince la prima corrispondenza, senza riserva

PostgreSQL legge il file dall’alto verso il basso e usa il primo record che corrisponde alla connessione. Non c’è un secondo tentativo se l’autenticazione di quel record fallisce, quindi un’autorizzazione ampia precedente sconfigge silenziosamente un rifiuto successivo.

Questa regola d’ordine è il motivo più comune per cui un rifiuto scritto con cura non entra mai in vigore. Mettete le regole specifiche per prime e quelle ampie per ultime, poi leggete il file come una sequenza e non come un insieme. Una regola aggiunta in fondo non è una politica, è un commento. Spostatela in alto e ricaricate prima di concludere che il file viene ignorato.

Il riferimento HBA definisce sia l’ordine sia la differenza tra i record host e hostssl, il che conta quando il senso della regola è che la connessione deve essere cifrata.

Ricaricamento, riavvio e il caso negato

Le modifiche HBA vengono applicate con un ricaricamento, e la vista pg_hba_file_rules vi aiuta a trovare errori di analisi. Quella vista descrive il contenuto attuale del file, non se il server in esecuzione li ha caricati con successo, quindi un elenco pulito non è prova che le nuove regole siano attive.

Le modifiche al listener richiedono un riavvio proprio, e le due operazioni si confondono facilmente quando una modifica sembra non avere effetto.

Provate con sessioni nuove: un client approvato con l’account previsto si connette, lo stesso account da un percorso non approvato no, e un’identità di database non autorizzata fallisce ancora dall’interno della VPN. Questi tre risultati separano il confine di rete dall’autorizzazione del database, che è l’intero senso di tenere le decisioni separate.

Articoli correlati