Entrambi i client stanno sullo stesso portatile, attraversano lo stesso tunnel e solo uno dei due si connette. Il confronto sembra la prova che la VPN sia selettiva, mentre la spiegazione molto più comune è che i due client puntino a destinazioni diverse. Una GUI conserva il proprio host, porta, ruolo e impostazioni TLS e costruisce in silenzio un inoltro SSH quando le serve, mentre psql assembla una connessione dai valori predefiniti di libpq che la tua shell potrebbe aver già impostato. Riprodurre la connessione funzionante significa leggere le impostazioni della GUI, non reinstallare il tunnel.

Il mito: un client che funziona dimostra il percorso

Se la GUI si connette, il tunnel trasporta traffico, e questa è l’unica cosa che la GUI dimostra. Non dice nulla su quale indirizzo risolva psql, con quale ruolo si autentichi o se il socket che apre lasci mai la macchina. Il percorso è condiviso; i parametri no.

Un inoltro locale allarga il divario. La GUI può connettersi a 127.0.0.1 su una porta che ha inoltrato via SSH, e quell’ascoltatore esiste solo per la durata della sessione della GUI. psql puntato a localhost senza l’inoltro riceve una connessione rifiutata che non ha nulla a che fare con la VPN.

Leggi l’estremità che la GUI usa davvero

Apri le proprietà della connessione e copia quattro valori: host, porta, database e ruolo. Poi cerca una scheda tunnel, perché un inoltro SSH trasforma un indirizzo privato in una porta locale e cambia ciò che va detto a psql.

SettingWhat the GUI holdsWhat psql uses when the value is absent
DestinationA saved hostname, sometimes behind a forwardA local Unix socket, not the remote endpoint
PortThe direct port or a forwarded local port5432, or the port from a service file
Role and databaseStored per connection profileYour operating-system user name
TLS identityIts own CA bundle and verification modeWhatever PGSSLMODE or the service file says
Startup filesNot read at allRead unless -X is passed

Ogni riga fallisce a uno strato diverso, e il messaggio che ricevi nomina quello strato. Incollare il nome amichevole del profilo salvato in psql non porta nessuno dei valori qui sopra, e un nome di servizio viene risolto tramite un file che il terminale forse non leggerà mai.

Che cosa eredita libpq dalla tua shell

psql è un client sottile sopra libpq, e libpq legge l’ambiente prima di leggere qualsiasi altra cosa. Variabili come PGHOST, PGHOSTADDR, PGPORT, PGDATABASE, PGUSER, PGSERVICE e PGSSLMODE possono reindirizzare ciascuna una parte della connessione. Vengono ereditate anziché digitate, quindi nulla nel comando che hai eseguito le mostra. Una PGSSLMODE esportata può anche cambiare ciò che il client accetta senza una parola sulla riga di comando.

Due di queste variabili meritano il sospetto per prime. PGHOSTADDR fornisce una destinazione numerica che scavalca la risoluzione dei nomi mentre il nome host continua a governare l’identità del certificato, e PGSERVICE tira fuori host, database e scelte TLS da un file di servizio. Scaricare tutto l’ambiente per fare debug è una cattiva abitudine, perché può contenere password e token non correlati; seleziona invece le variabili che ti interessano.

Omettere sia host sia hostaddr seleziona un socket di dominio Unix anziché un indirizzo di rete. Una chiamata psql senza -h può quindi riuscire localmente, o fallire con un errore di socket, senza mai toccare la rotta usata dalla GUI.

Invia gli stessi parametri a mano

Con i valori della GUI in mano, passali esplicitamente e salta il file di avvio che potrebbe aggiungere sovrascritture. La stringa di connessione qui sotto è illustrativa: sostituisci l’estremità, la porta, il database e il ruolo con i valori approvati dal tuo amministratore, e conserva la configurazione di fiducia che già funziona.

psql -X "host=db.internal.example port=6432 dbname=orders user=report_ro sslmode=verify-full connect_timeout=5"

Tre dettagli di quel comando sono deliberati. -X sopprime il file di avvio di psql, anche se non sopprime l’ambiente di libpq né una definizione di servizio. connect_timeout=5 evita che una rotta bloccata blocchi il terminale per minuti. sslmode=verify-full mantiene attivi i controlli di certificato e nome host, che è esattamente la parte che la gente disattiva quando compare un errore TLS.

Se l’estremità approvata sta dietro un pooler, la porta 6432 e la porta 5432 possono raggiungere gli stessi dati tramite identità server diverse, e la verifica può fallire sul nome del pooler invece che su quello del database. Correggi il nome nella stringa di connessione invece di indebolire la modalità.

Lascia che il messaggio di errore scelga il passo successivo

Il testo dell’errore dice fin dove è arrivato il tentativo, e questo batte qualsiasi supposizione sul tunnel. Un nome che non si risolve fallisce prima che esista un socket, un timeout significa che la rotta o un firewall ha scartato pacchetti, un rifiuto significa che qualcosa ha risposto e ha rifiutato, e un errore di autenticazione significa che la rete funzionava già.

psql -X -w "host=db.internal.example port=6432 dbname=orders user=report_ro sslmode=verify-full connect_timeout=5" -c '\conninfo'
env | grep -E '^PG'
psql --version

Confronta l’output di \conninfo con la sessione live della GUI: stesso host, stessa porta, stesso ruolo, stesso stato TLS. Quando questi quattro concordano, alla VPN non resta nulla da spiegare. Finché non concordano, ogni ulteriore modifica al tunnel è una supposizione su una connessione che il terminale non ha mai fatto.

Articoli correlati