VPN:en blockerar inte psql: din klient går någon annanstans
psql och en GUI-klient kan gå till olika ändpunkter från samma maskin. Jämför värd, socket, roll och TLS innan du skyller på VPN:en.
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.
| 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 |
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 --versionJä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.