TableCore

SSH tunnels

Most production MongoDB servers are not reachable from a laptop. TableCore can open an SSH connection to a host that is reachable and forward a local port through it.

What it does

When a profile has Connect through an SSH tunnel enabled, TableCore:

  1. connects to the SSH host with the credentials you gave it,
  2. picks a free port on 127.0.0.1,
  3. forwards that port to the MongoDB host and port from your connection string,
  4. rewrites the connection string to point at the local port, and connects the driver to that.

The tunnel belongs to the connection profile and stays open while the profile is in use. Opening the same profile again closes the previous tunnel first, so you never accumulate forwards.

Setting it up

FieldNotes
SSH hostThe bastion, not the database host
SSH port22 unless you changed it
SSH usernameThe account on the bastion
SSH authenticationPassword or Private key
SSH passwordStored in the OS credential store
Private key pathA path on your machine — the key file is read, never copied
Private key passphraseOptional, stored in the OS credential store

The Connection String stays the address of MongoDB as seen from the SSH host. If the database is on the bastion itself that is mongodb://localhost:27017; if it is on another machine in that network, use that machine's name.

What is supported, and what is not

One server, and mongodb:// only

Tunnelling requires a standard mongodb:// URI naming exactly one MongoDB server. A mongodb+srv:// seed list, or a mongodb:// URI listing several replica set members, is refused with "SSH tunneling requires a standard mongodb:// URI with exactly one MongoDB server."

This is a real limitation, not a validation quirk. One local port can only forward to one remote address, and a replica set discovered through a tunnel advertises its members' own hostnames — which your machine still cannot reach. Connecting to a single member directly is the shape that works.

Host key verification

TableCore checks that the machine answering on the SSH address is the machine your profile means, the same way your own SSH client does. Without that check a tunnel protects nothing: anything that can answer on that address gets your SSH session and the MongoDB credentials you send through it.

Three things are consulted, in this order:

  1. @revoked lines in your ~/.ssh/known_hosts. A key marked revoked is refused, and nothing in the profile can override it.
  2. Keys this profile has already accepted. Stored per profile, with the host and port they were accepted for.
  3. The rest of your ~/.ssh/known_hosts. A bastion you already reach from a terminal connects on the first try, with no prompt.

TableCore only ever reads known_hosts. It never writes to it, so accepting a key here cannot quietly widen what your ssh, scp and git will connect to.

The first time you connect

If nothing knows the key, the connection is refused and the connection profile shows you what was presented:

SHA256:47DEQpj8HBSa+/TImW+5JCeuQeRkm5NMpJWZG3hSuFU

Check it somewhere you trust before accepting — the dialog prints the command:

ssh-keyscan -p 22 bastion.example.com | ssh-keygen -lf -

Accept this key records it against that profile and tries again. The acceptance is saved when you save the profile, so cancelling the dialog cancels the acceptance too.

A profile you already had will ask once

Profiles created before this check existed have accepted nothing yet, so the first connection after upgrading shows the fingerprint. That is the check working, not a fault. If the host is in your known_hosts already, you will not be asked at all.

When the key has changed

If the profile or your known_hosts holds a different key of the same type for that host, the connection is refused and there is no button that accepts it. That is deliberate: a substituted host key is what a machine-in-the-middle looks like, and a prompt whose easiest answer is yes turns the one warning that matters into a click.

Both fingerprints are shown so you can compare them. If the server really was rebuilt, confirm the new key out of band, use Forget them to clear what the profile remembers, and connect again.

A host that is known by a key of a different type — your known_hosts has its RSA key and it answered with Ed25519 — is treated as a first sight of that key, not as a change. The dialog says so.

Turning the check off

Do not verify the SSH host key is a per-profile checkbox. It exists so that the insecure case is something you choose rather than something you get by accident, and it is never a fallback: if the fingerprint cannot be shown, the connection is refused rather than allowed. A @revoked key is still refused with this on.

Reading a failure

Tunnel failures are reported before MongoDB is ever contacted, so the message is about the tunnel rather than about the database.

MessageWhat to fix
The SSH host is requiredThe tunnel is enabled with an empty host
The SSH port must be between 1 and 65535As it says
The SSH username is requiredAs it says
The SSH private key path is requiredPrivate-key authentication with no path given
The SSH private key was not found: …The path is wrong, or the file is not readable by you
An SSH password has not been saved for this connectionPassword authentication with nothing in the credential store — re-enter it in the profile
The MongoDB connection string is invalidThe URI does not parse at all
SSH tunneling requires a standard mongodb:// URI with exactly one MongoDB serverSee above
The SSH local forward did not startThe SSH server refused the forward. AllowTcpForwarding is often off on hardened bastions
The host key of host:port is not trusted yetOpen the connection profile, read the fingerprint and accept it there
The host key of host:port has changedSee When the key has changed. Do not work around this without checking
The host key of host:port is marked @revokedYour own known_hosts says this key must never be used again
The SSH server did not present a host key to verifyThe server completed a handshake without offering a key TableCore could check. Refused rather than trusted
Could not establish the SSH tunnel to host:portEverything else — authentication rejected, host unreachable, key format not supported. The underlying error is attached

If the tunnel opens but MongoDB then fails, the problem has moved: the forward works and the database is refusing you. Read those errors as ordinary connection failures against 127.0.0.1.

An alternative that always works

Nothing stops you from running the forward yourself:

ssh -N -L 27018:db.internal.example:27017 deploy@bastion.example.com

and giving TableCore mongodb://localhost:27018 with the tunnel switched off. You get your agent, your jump hosts, certificate host keys and the rest of your SSH config for free — none of which the built-in tunnel reads. It exists so that the simple case does not require a second terminal, not to replace your SSH client.