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.

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

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 --version

Compare 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.

Artigos relacionados