Can't connect to containerized localhost Postgres on a domain joined Mac

Aperta
#323 2 commenti 0 reazioni 0 assegnatari Vedi su GitHub

Nessuno ha ancora preso questa issue.

Valutazione

Difficoltà
4/5
Tempo stimato
3-5 giorni
Idoneità per principianti
48/100
Tipo di issue
Bug
Chiarezza
Specificata chiaramente
Stato di attività
Attiva
Stack tecnologico
macos, postgresql
Ambito
database

Direzione di ricerca

Start by reading the connection profile schema and Advanced Connection Settings implementation, which the issue identifies as places to expose gssencmode; compare how the existing SSL options are handled. Reproduce with the bundled libpq and the described PGGSSENCMODE=disable workaround. Done means the connection avoids timing out on the stalled GSS exchange, with the setting available to users and covered by an appropriate test.

Scritto dal modello di indicizzazione a partire dal testo della issue.

Descrizione

Local connections time out on domain-joined macOS machines (gssencmode=prefer + GSS-capable server)

Describe the bug

The extension cannot connect to PostgreSQL on localhost (or any GSS-capable server) from a domain-joined corporate Mac with active Kerberos tickets. The connection fails after connect_timeout seconds with:

Connection error for host=localhost port=5432 dbname=postgres user=postgres password=*****
connect_timeout=15 client_encoding=utf8 sslmode=prefer: connection timeout expired

Extension host log:

Error connecting to server "localhost". Details: Could not connect to 'localhost' within 15 seconds.
Failed to initialize object explorer session: couldn't get a connection after 15.00 sec

Every other client (DBeaver, node-postgres, the ckolkman.vscode-postgres extension, raw sockets) connects to the same server in milliseconds. Azure DB connections from the same extension and same tools-service process also work.

Root cause: the tools service's bundled libpq runs with the default gssencmode=prefer. The extension's conninfo never sets gssencmode. When the server advertises GSS encryption support (responds G to a GSSENCRequest), libpq starts a Kerberos GSSAPI exchange against the machine's AD domain. On corporate machines the KDC is often unreachable or black-holed over the VPN path, the exchange stalls, and the connect timeout expires. libpq only falls back to SSL/plaintext if the GSS attempt errors out quickly — a stalled KDC exchange consumes the entire timeout.

This is likely the real cause of #78, currently attributed to macOS Sequoia Local Network privacy restrictions. Every report there matches this profile: corporate-managed, domain-joined Macs, local/LAN targets, 127.0.0.1/::1/localhost all failing identically, other tools working — including from VS Code's own integrated terminal. The GSS attempt happens regardless of loopback form, and granting VS Code Local Network permission changes nothing.

To Reproduce

  1. Join a Mac to an AD domain with valid Kerberos tickets (klist shows a TGT) and a network path where the KDC is unreachable or drops packets (corporate VPN).

  2. Run PostgreSQL locally in a container using an official image with GSSAPI support (verified with postgres:18-alpine). These images answer G to a GSSENCRequest even with no keytab, so a GSS attempt can never complete:

    printf '\x00\x00\x00\x08\x04\xd2\x16\x30' | nc -w 5 127.0.0.1 5432 | xxd
    00000000: 47    G
    
  3. In VS Code with this extension, create a connection profile for host=localhost port=5432 with default settings.

  4. Connect. It hangs for exactly connect_timeout (15 s) and fails with connection timeout expired.

Verified with the extension's own bundled libpq.5.dylib (pgsqltoolsservice/v3.7.4/OSX/.../psycopg_binary/.dylibs/libpq.5.dylib): a raw PQconnectdb() with the extension's exact conninfo blocks in the GSS/Kerberos exchange and does not return within 60 seconds. No password is needed to reproduce — with the GSS path removed it fails fast (in ~0.01 s) at fe_sendauth: no password supplied, which is the expected auth-stage failure.

Expected behavior

The connection succeeds, or at minimum libpq falls back to SSL/plaintext instead of burning the whole timeout on a stalled GSS exchange. Ideally:

  • Expose gssencmode (disable/prefer/require) in the connection profile schema and Advanced Connection Settings drawer, alongside the SSL options.
  • Consider defaulting to gssencmode=disable for local servers (loopback / private addresses from the local-install and Docker/Podman flows). A local or containerized Postgres on a dev machine won't authenticate via Kerberos; attempting GSS against it can only produce a fallback or a timeout. This would fix connections for all domain-joined corporate users with zero configuration.
  • At minimum, document the PGGSSENCMODE=disable workaround in the troubleshooting guide, since the connection dialog offers no way to set it.

Workaround

launchctl setenv PGGSSENCMODE disable   # fully quit and restart VS Code

Resets on reboot. Alternatively export PGGSSENCMODE=disable in the shell profile and launch VS Code via the code CLI so the tools service inherits it. This only works because the extension never sets gssencmode in its conninfo — if a future version starts setting it, the env var is silently ignored (libpq precedence: conninfo value > env var > compiled default).

Screenshots

N/A.

VS Code version

VS Code 1.145.0
macOS (Apple Silicon), AD-bound to corporate domain (valid TGT), Cisco AnyConnect, Jamf, CrowdStrike

(Paste full Code -> About Visual Studio Code output when filing.)

Extension: ms-ossdata.vscode-pgsql 1.32.1 (stable)
Tools service: ossdbtoolsservice v3.7.4 (bundled psycopg 3.2.4, psycopg_pool 3.2.6, bundled libpq.5.dylib)
Server: postgres:18-alpine in a Podman container, published on 0.0.0.0:5432

Extension Logs

Log showing the failure and conninfo (no gssencmode present):

Connection error for host=localhost port=5432 dbname=postgres user=postgres password=*****
connect_timeout=15 client_encoding=utf8 sslmode=prefer: connection timeout expired
Error connecting to server "localhost". Details: Could not connect to 'localhost' within 15 seconds.
Failed to initialize object explorer session: couldn't get a connection after 15.00 sec

Additional context

  • Verified with the extension's bundled libpq: adding gssencmode=disable to the same conninfo reaches the auth stage in ~0.01 s. Identical result with host=127.0.0.1, so it is not IPv4/IPv6/localhost-resolution related.
  • Non-GSS protocol path verified against the live server via raw sockets (sequential and 5 concurrent, IPv4 and IPv6, through the container runtime's port forwarder): SSLRequest → N, StartupMessage → SCRAM challenge, single-digit milliseconds every time.
  • Azure DB connections from the same tools-service process succeed because GSS realm discovery for the Azure hostname fails fast and libpq falls back to SSL (~550 ms, per pgsql-tools.log). A stalled KDC exchange does not fail fast — that's the difference.
  • libpq docs on GSSENCMODE / PGGSSENCMODE: default is prefer; env var PGGSSENCMODE is honored only when the conninfo doesn't set the parameter.
  • Related: #78; psycopg/psycopg#888, psycopg/psycopg#1089.
Lingua principale
Nessun dato sulla lingua
Stelle
406
Fork
35
Merge medio
2h 47m
PR unite (30g)
5

Preparare l'ambiente

Questo progetto non fornisce container di sviluppo, Dockerfile né guida per i contributori, quindi l'ambiente è a tuo carico: parti dal suo README e consulta la nostra guida al primo contributo per i passaggi generali.

Come iniziare

  1. Leggi tutta la issue e poi la guida ai contributi del progetto.
  2. Commenta sulla issue per dire che te ne occupi tu — evita che due persone facciano lo stesso lavoro.
  3. Fai un fork del repository e lavora su un branch.
  4. Apri una pull request che faccia riferimento al numero della issue.

Altre issue di microsoft/vscode-pgsql

Tutte le issue di microsoft/vscode-pgsql

Issue simili

Altre issue su Databases

Ricevi le nuove issue nella tua casella

Un breve riepilogo di issue GitHub adatte ai principianti.