A VPN não bloqueia o psql: o seu cliente marca outro destino
psql e um cliente GUI podem marcar extremos diferentes a partir da mesma máquina. Compare anfitrião, socket, função e TLS antes de culpar a VPN.
Ambos os clientes estão no mesmo portátil, atravessam o mesmo túnel e só um deles liga. Essa comparação parece prova de que a VPN é seletiva, quando a explicação muito mais comum é que os dois clientes marcam destinos diferentes. Uma GUI guarda o seu próprio anfitrião, porta, função e definições TLS e constrói silenciosamente um encaminhamento SSH quando precisa de um, enquanto o psql monta uma ligação a partir dos valores predefinidos do libpq que a sua shell talvez já tenha definido. Reproduzir a ligação que funciona é uma questão de ler as definições da GUI, não de reinstalar o túnel.
O mito: um cliente que funciona prova o caminho
Se a GUI liga, o túnel transporta tráfego, e é só isso que a GUI prova. Não diz nada sobre que endereço o psql resolve, com que função se autentica ou se o socket que abre chega a sair da máquina. O caminho é partilhado; os parâmetros não.
Um encaminhamento local alarga a diferença. A GUI pode ligar-se a 127.0.0.1 numa porta que encaminhou por SSH, e esse ouvinte só existe enquanto durar a sessão da GUI. O psql apontado a localhost sem o encaminhamento recebe uma ligação recusada que não tem nada a ver com a VPN.
Leia o extremo que a GUI usa realmente
Abra as propriedades da ligação e copie quatro valores: anfitrião, porta, base de dados e função. Depois procure um separador de túnel, porque um encaminhamento SSH transforma um endereço privado numa porta local e muda o que é preciso dizer ao psql.
| Setting | What the GUI holds | What psql uses when the value is absent |
|---|---|---|
| Destination | A saved hostname, sometimes behind a forward | A local Unix socket, not the remote endpoint |
| Port | The direct port or a forwarded local port | 5432, or the port from a service file |
| Role and database | Stored per connection profile | Your operating-system user name |
| TLS identity | Its own CA bundle and verification mode | Whatever PGSSLMODE or the service file says |
| Startup files | Not read at all | Read unless -X is passed |
Cada linha falha numa camada diferente, e a mensagem que recebe nomeia essa camada. Colar o nome amigável do perfil guardado no psql não transporta nenhum dos valores acima, e um nome de serviço é resolvido através de um ficheiro que o terminal talvez nunca leia.
O que o libpq herda da sua shell
O psql é um cliente fino sobre o libpq, e o libpq lê o ambiente antes de ler qualquer outra coisa. Variáveis como PGHOST, PGHOSTADDR, PGPORT, PGDATABASE, PGUSER, PGSERVICE e PGSSLMODE podem redirecionar cada uma parte da ligação. São herdadas em vez de escritas, por isso nada no comando que executou as mostra. Uma PGSSLMODE exportada também pode mudar o que o cliente aceita sem uma palavra na linha de comandos.
Duas dessas variáveis merecem suspeita primeiro. PGHOSTADDR fornece um destino numérico que anula a resolução de nomes enquanto o nome do anfitrião continua a reger a identidade do certificado, e PGSERVICE retira anfitrião, base de dados e escolhas TLS de um ficheiro de serviço. Despejar todo o ambiente para depurar isto é um mau hábito, pois pode conter palavras-passe e tokens não relacionados; selecione antes as variáveis que lhe importam.
Omitir tanto host como hostaddr seleciona um socket de domínio Unix em vez de um endereço de rede. Uma chamada psql sem -h pode, por isso, ter êxito localmente ou falhar com um erro de socket, sem nunca tocar na rota que a GUI usa.
Envie os mesmos parâmetros à mão
Com os valores da GUI na mão, passe-os explicitamente e salte o ficheiro de arranque que poderia acrescentar substituições. A cadeia de ligação abaixo é ilustrativa: substitua o extremo, a porta, a base de dados e a função pelos valores aprovados pelo seu administrador, e mantenha a configuração de confiança que já funciona.
psql -X "host=db.internal.example port=6432 dbname=orders user=report_ro sslmode=verify-full connect_timeout=5"Três detalhes desse comando são deliberados. -X suprime o ficheiro de arranque do psql, embora não suprima o ambiente do libpq nem uma definição de serviço. connect_timeout=5 impede que uma rota bloqueada pendure o terminal durante minutos. sslmode=verify-full mantém ativas as verificações de certificado e de nome de anfitrião, que é exatamente a parte que as pessoas desativam quando aparece um erro TLS.
Se o extremo aprovado estiver atrás de um pooler, a porta 6432 e a porta 5432 podem chegar aos mesmos dados através de identidades de servidor diferentes, e a verificação pode falhar no nome do pooler em vez do da base de dados. Corrija o nome na cadeia de ligação em vez de enfraquecer o modo.
Deixe a mensagem de erro escolher o passo seguinte
O texto da falha diz até onde chegou a tentativa, e isso supera qualquer suposição sobre o túnel. Um nome que não resolve falha antes de existir um socket, um tempo esgotado significa que a rota ou uma firewall descartou pacotes, uma recusa significa que algo respondeu e recusou, e um erro de autenticação significa que a rede já funcionava.
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 --versionCompare a saída de \conninfo com a sessão ao vivo da GUI: mesmo anfitrião, mesma porta, mesma função, mesmo estado TLS. Quando esses quatro coincidem, a VPN não tem mais nada a explicar. Até coincidirem, cada alteração adicional no túnel é uma suposição sobre uma ligação que o terminal nunca fez.