Skip to content

SSH tunnels

When the database is only reachable from inside a private network, connect through an SSH server that is: a bastion host. Alcuin opens the tunnel itself; you do not need to run ssh -L first.

  1. Open the connection’s form and fill in Host, Port, Database and User as the bastion sees the database. Host is resolved by the SSH server, so a private name such as db.internal works.

  2. Beside Connect through SSH, click Set up.

  3. Fill in the SSH fields:

    Field What it takes
    SSH host The bastion’s name or address
    SSH port Its SSH port, 22 by default
    SSH user Your user on the bastion
    SSH authentication SSH agent, Private key file or Password
  4. Click Test connection. The steps start with SSH tunnel.

  5. The first time, Alcuin stops at the bastion’s host key. Check it and click Trust this key, as below.

  6. Click Save.

On success, Test connection says through the SSH tunnel. Turn the tunnel off again with Turn off.

The default. Alcuin uses the agent that SSH_AUTH_SOCK names in the environment Alcuin started with. If none is set, the test fails with no SSH agent is running (SSH_AUTH_SOCK is not set).

A variable set only in your shell’s startup files, such as ~/.zshrc, does not reach an app started from the Dock, Finder or a desktop launcher. That matters for agents such as 1Password’s: Alcuin uses one only when SSH_AUTH_SOCK in its own environment points at that agent’s socket.

Set Key path, or click Choose…. Alcuin reads OpenSSH, PEM and PuTTY private keys. If the key has a passphrase, enter it in Key passphrase. Alcuin keeps it encrypted with your system keychain.

~/ at the start of the path is your home folder. Alcuin refuses a file that is not a private key, with that file is not an SSH private key, and never shows its contents.

Enter SSH password. Alcuin keeps it in your keychain.

Before it sends the bastion any password, passphrase or agent signature, Alcuin checks that the bastion is the server you trusted.

It trusts a key when:

  • the connection’s settings hold it as Trusted server key, or
  • ~/.ssh/known_hosts lists it for the same host and port. Hashed entries count.

The first time, neither holds, and Test connection stops with the key’s fingerprint and a Trust this key button. Compare the fingerprint with the one the bastion’s owner gives you before you trust it. ALC-1003: Unknown SSH host key has the steps.

The failure box headed Couldn't open the SSH tunnel, with a cross on SSH tunnel, the message that bastion.example.com is not one this machine knows, Server key with the SHA256 fingerprint, and a Trust this key button.

The first time: compare the fingerprint, then Trust this key.

If the bastion presents a different key from the one trusted, Alcuin refuses to connect and offers Trust the new key. Find out why the key changed first. ALC-1004: SSH host key changed lists the harmless causes and the one that matters.

The failure box headed Couldn't open the SSH tunnel, with the message that bastion.example.com presented a different key from the one trusted for it, Server key with the new SHA256 fingerprint, and a red Trust the new key button.

A changed key: find out why before you choose Trust the new key.

To stop trusting a key, click Forget beside Trusted server key and save. To read keys from another file than ~/.ssh/known_hosts, start Alcuin with ALCUIN_SSH_KNOWN_HOSTS set to its path.

A saved password is kept with the key it was saved under. If the trusted key changes, Alcuin asks before it sends a saved password over the tunnel.

Alcuin doesn’t read ~/.ssh/config, so Host aliases, User, Port, IdentityFile and ProxyJump lines are not used: enter the real host name, user, port and key in the form. A tunnel goes through one SSH server. Not supported yet lists what else Alcuin doesn’t do.

For a chain of SSH servers, run the forward in a terminal and point Alcuin at it:

Terminal window
ssh -N -J jump.example.com -L 15432:db.internal:5432 bastion.example.com

Then set Host to localhost, Port to 15432, and leave Connect through SSH off. The certificate names the database host, not localhost, so use Required, verify certificate if the server has TLS.

The tunnel encrypts the hop to the bastion. The hop from the bastion to the database is only encrypted by Postgres’s own TLS, so keep Encryption on where the server offers it. Required, verify server works through Alcuin’s tunnel, because the host name is checked against Host as you typed it. See TLS and sslmode.

Alcuin sends the bastion a keepalive every 15 seconds and closes the tunnel after three go unanswered. It waits 15 seconds for the SSH handshake, and 15 seconds for the bastion to open a channel to the database.

When the tunnel drops, the connection drops with it: you see Connection lost. Reconnecting…, and Alcuin opens a new tunnel when it reconnects. Your tabs stay. See ALC-1002: Connection lost.

Test connection names the step Couldn't open the SSH tunnel. Try ssh -p <port> <user>@<host> from a terminal: if that fails too, fix SSH access first. Connection errors by message has each message and its fix: