Båda klienterna sitter på samma bärbara dator, går genom samma tunnel, och bara en av dem ansluter. Jämförelsen känns som bevis på att VPN:en är selektiv, medan den mycket vanligare förklaringen är att de två klienterna går till olika destinationer. En GUI behåller sin egen värd, port, roll och TLS-inställningar och bygger tyst en SSH-vidarebefordran när den behöver en, medan psql sätter ihop en anslutning från libpq-standardvärden som ditt skal kanske redan har satt. Att återskapa den fungerande anslutningen handlar om att läsa GUI:ns inställningar, inte om att installera om tunneln.

Myten: en fungerande klient bevisar vägen

Om GUI:n ansluter transporterar tunneln trafik, och det är det enda GUI:n bevisar. Den säger ingenting om vilken adress psql löser upp, vilken roll den autentiserar som, eller om socketen den öppnar någonsin lämnar maskinen. Vägen delas; parametrarna gör det inte.

En lokal vidarebefordran ökar skillnaden. GUI:n kan ansluta till 127.0.0.1 på en port som den vidarebefordrat över SSH, och den lyssnaren finns bara så länge GUI-sessionen varar. psql riktad mot localhost utan vidarebefordran får en avvisad anslutning som inte har något med VPN:en att göra.

Läs den ändpunkt GUI:n faktiskt använder

Öppna anslutningens egenskaper och kopiera fyra värden: värd, port, databas och roll. Leta sedan efter en tunnel-flik, eftersom en SSH-vidarebefordran gör en privat adress till en lokal port och ändrar vad psql måste få veta.

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

Varje rad misslyckas i ett olika lager, och meddelandet du får namnger det lagret. Att klistra in det vänliga namnet på den sparade profilen i psql bär ingen av värdena ovan, och ett tjänstenamn löses upp genom en fil som terminalen kanske aldrig läser.

Vad libpq ärver från ditt skal

psql är en tunn klient ovanpå libpq, och libpq läser miljön innan den läser något annat. Variabler som PGHOST, PGHOSTADDR, PGPORT, PGDATABASE, PGUSER, PGSERVICE och PGSSLMODE kan var och en omdirigera en del av anslutningen. De ärvs i stället för att skrivas, så ingenting i kommandot du körde visar dem. En exporterad PGSSLMODE kan också ändra vad klienten accepterar utan ett ord på kommandoraden.

Två av dessa variabler förtjänar misstanke först. PGHOSTADDR ger en numerisk destination som åsidosätter namnmatchning medan värdnamnet fortfarande styr certifikatets identitet, och PGSERVICE drar ut värd, databas och TLS-val från en tjänstefil. Att dumpa hela miljön för att felsöka detta är en dålig vana, eftersom den kan innehålla lösenord och orelaterade token; välj i stället de variabler du bryr dig om.

Att utelämna både host och hostaddr väljer en Unix-domänsocket i stället för en nätverksadress. Ett psql-anrop utan -h kan därför lyckas lokalt, eller misslyckas med ett socket-fel, utan att någonsin röra rutten GUI:n använder.

Skicka samma parametrar för hand

Med GUI:ns värden i handen, skicka dem explicit och hoppa över startfilen som kan lägga till åsidosättningar. Anslutningssträngen nedan är illustrativ: byt ut ändpunkten, porten, databasen och rollen mot de värden din administratör har godkänt, och behåll förtroendekonfigurationen som redan fungerar.

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

Tre detaljer i det kommandot är avsiktliga. -X undertrycker psql:s startfil, även om den inte undertrycker libpq:s miljö eller en tjänstdefinition. connect_timeout=5 hindrar en svart-hål-rutt från att hänga terminalen i minuter. sslmode=verify-full håller certifikat- och värdnamnskontroller påslagna, vilket är precis den del folk stänger av när ett TLS-fel dyker upp.

Om den godkända ändpunkten ligger bakom en pooler kan port 6432 och port 5432 nå samma data genom olika serveridentiteter, och verifieringen kan misslyckas på poolerns namn i stället för databasens. Rätta namnet i anslutningssträngen i stället för att försvaga läget.

Låt felmeddelandet välja nästa steg

Feltexten säger hur långt försöket kom, och det slår varje gissning om tunneln. Ett namn som inte löses upp misslyckas innan en socket finns, en tidsgräns betyder att rutten eller en brandvägg släppte paketen, en avvisning betyder att något svarade och nekade, och ett autentiseringsfel betyder att nätverket redan fungerade.

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

Jämför utdata från \conninfo med GUI:ns aktiva session: samma värd, samma port, samma roll, samma TLS-läge. När de fyra stämmer har VPN:en inget mer att förklara. Tills de stämmer är varje extra tunneländring en gissning om en anslutning som terminalen aldrig gjorde.

Relaterade artiklar