Skip to content

feat(connections): Unix socket support — dialed locally or through the SSH tunnel#492

Open
debba wants to merge 5 commits into
mainfrom
feat/ssh-unix-socket-forward
Open

feat(connections): Unix socket support — dialed locally or through the SSH tunnel#492
debba wants to merge 5 commits into
mainfrom
feat/ssh-unix-socket-forward

Conversation

@debba

@debba debba commented Jul 18, 2026

Copy link
Copy Markdown
Collaborator

What

A single optional Socket Path field on the connection: the Unix socket the database listens on at the connection's destination. Like Host and Port, its perspective follows the tunnel state:

  • No tunnel — the drivers dial the socket on this machine directly instead of host:port (MySQL, PostgreSQL).
  • SSH tunnel — the SSH server connects to the socket instead of Host and Port, via a direct-streamlocal@openssh.com channel (russh backend) or ssh -L <port>:/path/to/socket (system ssh backend). Reaches databases that only listen on a socket, e.g. MySQL with skip_networking or PostgreSQL with listen_addresses = ''.
  • Kubernetes tunnel — ignored (kubectl port-forward is TCP-only).

How

  • One unix_socket_path param on ConnectionParams drives both modes. resolve_connection_params turns it into the SshForwardDestination::UnixSocket when SSH is enabled (enum threaded through SshTunnel::new, both backends, and the tunnel cache key); tunnel resolution then clears the field so it can never bypass the tunnel's forwarded local port at the driver level.
  • Local dialing: MySQL via sqlx's .socket(); PostgreSQL via Config::host_path — the socket file (/var/run/postgresql/.s.PGSQL.5432) is split into the directory + port tokio_postgres expects, and a plain directory also works, paired with the Port field. The ad-hoc pool cache key uses the socket as the endpoint in place of host:port.
  • Database TLS is forced off in both modes: a socket peer cannot negotiate it, and the path is local or already SSH-encrypted. The MySQL cleartext-plugin TLS requirement is waived over a local socket only.
  • Local dialing is gated by a new unix_socket driver capability (default false; true for built-in mysql/postgres; plugins opt in via manifest, unixSocket alias accepted). The field shows in the General tab when the driver has the capability or SSH is enabled; Host/Port grey out while a socket is in effect, and advisory hints (never blocking) follow the tunnel state and flag relative or directory-looking paths.
  • The field lives on the DB connection, not on the reusable SSH profile, so one bastion profile serves both TCP and socket-only databases. New i18n keys in all 9 locales.

Plugin drivers are untouched: with SSH they receive already-resolved params (127.0.0.1 + local tunnel port); the field is skip-serialized when unset, so JSON-RPC payloads only change when the feature is used.

Tests

  • cargo test: 962 passed (forward-spec/tunnel-key destination tests, resolve-side destination + ssl override tests, local-socket option builders, postgres socket-path splitting, pool-key endpoint tests, tunnel-clears-socket test)
  • pnpm test: 2929 passed (unixSocketPathIssue, effectiveLocalSocketPath, socket-aware format/validate/subtitle)
  • tsc --noEmit and eslint clean

debba added 2 commits July 18, 2026 15:13
Add unix_socket_path to ConnectionParams: when set and no SSH/K8s tunnel
is enabled, MySQL connects via sqlx's socket option and PostgreSQL via
host_path (the .s.PGSQL.<port> file path is split into directory + port).
Database TLS is forced off — a local socket peer cannot negotiate it and
the traffic never leaves the machine. Tunnel resolution clears the field
so a leftover path cannot bypass the tunnel's forwarded port.

The field is gated by a new unix_socket driver capability (default false,
true for the built-in mysql/postgres drivers); plugins can opt in via
their manifest. The connection modal shows a Local Socket Path field that
greys out Host/Port when active, reusing the SSH-forward advisory checks
(helper renamed to unixSocketPathIssue).
@debba debba changed the title feat(ssh): forward the tunnel to a Unix socket instead of host:port feat(connections): Unix socket support — local connections and SSH tunnel forwarding Jul 18, 2026
debba added a commit to TabularisDB/website that referenced this pull request Jul 18, 2026
Companion to TabularisDB/tabularis#492: the PR now also lets the MySQL
and PostgreSQL drivers dial a Unix socket on the local machine directly,
gated by the new unix_socket driver capability. Adds the field to the
connection-profile table, a Local Unix socket section in connections.md,
the capability row in plugins.md, and a cross-link from the SSH
forwarding section.
@kilo-code-bot

kilo-code-bot Bot commented Jul 18, 2026

Copy link
Copy Markdown
Contributor

Code Review Summary

Status: No Issues Found | Recommendation: Merge

Files Reviewed (25 files)
  • src-tauri/src/commands.rs
  • src-tauri/src/drivers/driver_trait.rs
  • src-tauri/src/drivers/mysql/mod.rs
  • src-tauri/src/drivers/postgres/mod.rs
  • src-tauri/src/drivers/sqlite/mod.rs
  • src-tauri/src/models.rs
  • src-tauri/src/plugins/driver.rs
  • src-tauri/src/pool_manager.rs
  • src-tauri/src/pool_manager_tests.rs
  • src-tauri/src/ssh_tunnel.rs
  • src/components/modals/NewConnectionModal.tsx
  • src/contexts/DatabaseContext.ts
  • src/i18n/locales/de.json
  • src/i18n/locales/en.json
  • src/i18n/locales/es.json
  • src/i18n/locales/fr.json
  • src/i18n/locales/it.json
  • src/i18n/locales/ja.json
  • src/i18n/locales/ko.json
  • src/i18n/locales/ru.json
  • src/i18n/locales/tl.json
  • src/types/plugins.ts
  • src/utils/connections.ts
  • src/utils/credentials.ts
  • tests/utils/connections.test.ts
Previous Review Summary (commit 4b2f54f)

Current summary above is authoritative. Previous snapshots are kept for context only.

Previous review (commit 4b2f54f)

Status: No Issues Found | Recommendation: Merge

Files Reviewed (25 files)
  • src-tauri/src/commands.rs
  • src-tauri/src/drivers/driver_trait.rs
  • src-tauri/src/drivers/mysql/mod.rs
  • src-tauri/src/drivers/postgres/mod.rs
  • src-tauri/src/drivers/sqlite/mod.rs
  • src-tauri/src/models.rs
  • src-tauri/src/plugins/driver.rs
  • src-tauri/src/pool_manager.rs
  • src-tauri/src/pool_manager_tests.rs
  • src-tauri/src/ssh_tunnel.rs
  • src/components/modals/NewConnectionModal.tsx
  • src/contexts/DatabaseContext.ts
  • src/i18n/locales/de.json
  • src/i18n/locales/en.json
  • src/i18n/locales/es.json
  • src/i18n/locales/fr.json
  • src/i18n/locales/it.json
  • src/i18n/locales/ja.json
  • src/i18n/locales/ko.json
  • src/i18n/locales/ru.json
  • src/i18n/locales/tl.json
  • src/types/plugins.ts
  • src/utils/connections.ts
  • src/utils/credentials.ts
  • tests/utils/connections.test.ts

Reviewed by kimi-k2.6 · Input: 58.2K · Output: 3.8K · Cached: 34.4K

The SSH-forward socket path and the local socket path were the same
concept — the Unix socket the database listens on at the connection's
destination — distinguished only by who dials it. Host/port already have
exactly that tunnel-relative semantics, so fold both into the single
unix_socket_path field: without a tunnel the drivers dial it locally
(capability-gated), with SSH it becomes the forward destination, and a
K8s tunnel ignores it. ssh_forward_unix_socket_path is gone (never
shipped, so nothing saved references it).

One Socket Path field now lives in the General tab, shown when the
driver has the unix_socket capability or SSH is enabled, with hints that
follow the tunnel state; the SSH-tab field is removed and the i18n keys
collapse from 11 to 8 per locale.
@debba debba changed the title feat(connections): Unix socket support — local connections and SSH tunnel forwarding feat(connections): Unix socket support — dialed locally or through the SSH tunnel Jul 18, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant