KOSHI0.4.0
Remote sessions
v0.4remotefield manual

Saved servers

Keep the machines this koshi dials — names, addresses, secrets, and pinned certificates — and reconnect when a remote link drops.

A saved server is one record on the machine you sit at: a name, an address, a secret, and the fingerprint of the certificate that machine presented. The store is readable only by its owner, and koshi remote list never prints a secret.

CommandResult
koshi remote newSave a server, asking for its name, address and secret
koshi remote edit <SERVER>Change one saved server's name, address or secret
koshi remote list [--format table|json]List the servers this machine has saved
koshi remote forget <SERVER>Drop one saved server
koshi remote set-secret <SERVER>Replace the secret of one saved server

Naming a server

--remote takes either the host:port a machine listens on or the name it was saved under. The first connection names the address, and --save-as gives it a short name:

koshi attach --remote laptop.local:7654 --save-as work web

After that the name stands in, and nothing is retyped:

koshi attach --remote work web

koshi remote new saves a server without attaching to one of its sessions. It asks the three questions in turn, then dials once to check the secret. See the setup walkthrough.

Pinned certificates

On the first connection koshi records the fingerprint of the certificate the server presented — the sha256 of it, as 64 lowercase hex characters — and pins it.

A later connection presenting a different certificate is always refused, and the refusal names the address and both fingerprints.

koshi remote forget work   # only when the server really was reinstalled

Connect again to pin the new certificate.

A changed fingerprint means the machine answering that address is not the one you pinned. Forget the record only when you know why the certificate changed.

A server saved past a failed check holds no fingerprint, and its first connection pins the certificate it meets.

Editing a saved server

koshi remote edit work

It asks the same three questions with the saved values in brackets. An empty answer keeps the value in brackets, and an empty secret keeps the saved secret, so only what changes is typed:

$ koshi remote edit work
press Enter to keep the value in brackets. An empty secret keeps the saved one. Ctrl-C stops without saving.
name [work]:
address [laptop.local:7654]: laptop.local:7655
secret:
checking laptop.local:7655 …
updated work at laptop.local:7655.

An edit that keeps the address requires the pinned fingerprint on the check, so a certificate that changed under that address does not pass. An edit that changes the address requires none: a pinned fingerprint stands for the address the record held when that certificate was met.

A check that passes pins the certificate the server presented, either way. A check that does not pass keeps the pinned fingerprint while the address is unchanged, and keeps none once the address changed. When the check does not pass, the last question names it:

save the change anyway? The certificate at that address is pinned on the first connection to it. [y/N]

Nothing is written until every answer has settled. Ctrl-C at any question, and input that ends before an answer arrives, leave the saved server unchanged.

Rotating a secret

Once the serving machine grants a fresh secret:

koshi remote set-secret work

It reads the new secret the way a connection does — from KOSHI_REMOTE_SECRET, or asked for at the terminal.

Two koshi processes at once

The store is read again at the moment the record is written, and the read and the write are held against every other koshi by a lock on remote/servers.lock beside the store.

  • A server another koshi saved while the questions were open is still saved, and a name or address that another record took meanwhile is refused with nothing written.
  • Every command that changes a saved server takes that lock, koshi attach included, which stamps the record it dialled.
  • A lock another koshi still holds after five seconds reads koshi: IPC unavailable: another koshi is changing the saved servers; try again. The operating system releases the lock if the koshi holding it dies.
  • The lock is never held while a question waits for an answer.

An edit re-reads its record at that same moment. A record whose name, address, secret, or fingerprint another koshi changed while the questions were open is refused, and the older values are not written:

koshi: invalid arguments: work changed while the questions were open, so nothing was saved; run `koshi remote edit work` again

The added time and the last-used time are not compared, so another koshi that only dialled this server does not stop the edit.

The sweep

A bare koshi list-sessions and a bare koshi attach sweep every saved server and append what answered. The sweep waits two seconds in total, not two seconds per server, so one unreachable machine cannot slow the list. A server not heard from inside that wait is left out.

A server that answers and refuses the saved secret is not hidden — it prints the command that replaces that secret:

work: the saved secret was refused; run `koshi remote set-secret work`

A saved server that pins no certificate is left out of the sweep, and one stderr line names it. Naming it connects, pins the certificate that server presents, and the sweep includes it from then on:

koshi list-sessions --remote work

Reconnecting

remote-reconnect is on by default and belongs to the terminal you sit at. It applies only to a terminal viewing a session on another machine.

A dropped link dials that machine again — after 1 second, then 2, 4, 8, and 8 before every dial after that — for up to 120 seconds. While it waits, the tab strip reads a tag shaped like:

RECONNECTING (attempt 4, retry in 8s)

The first number is the dial it is about to make; the second is the seconds left before that dial, counting down by one each second. The attempt number rises by one on every dial, so the fourth dial and every dial after it waits the full 8 seconds.

Joining again puts back the tab you were on, the focused pane of each tab, the fullscreened pane of each tab, and the scroll offset of each pane. Keys typed while the link is down are dropped; a resize is kept.

A refusal no dial can change stops the dialing at once, without waiting the 120 seconds out. When the dialing stops, koshi puts your terminal back the way it found it, then prints the cause, then the session continues without you, then the command that lists the session on that server and the command that joins it again. It exits with a non-zero status.

Off, a dropped link ends the terminal, printing how to attach again by hand. A link to a session on this machine ends the terminal either way.

koshi.kdl
version 1
remote-reconnect #true

On this page