Files
hq/04-ISSUES/172-the-ssh-client-block-matches-one-spelling-of-a-machine/00-report.md
T
jschoubben 69a002fce3 Issue 172: the ssh client block matches one spelling of a machine's name
Reported by the operator: ssh by the bare name logs in, by the mesh name
is refused. The predecessor's generator writes the bare name only; the
mesh's ssh-client roster already matches both and is not yet shipped.
2026-09-30 15:25:30 +02:00

3.2 KiB

status, opened, located-in, fixed-by, amended-design
status opened located-in fixed-by amended-design
located 2026-09-30
the predecessor's terminal module (still generating the operator's ssh client blocks on every workstation)
mesh-controller internal/catalogue (the ssh-client roster, tested and not yet a catalogue module)

172 — The ssh client block for a machine matches one spelling of its name, and the other gets the wrong user

What was observed

On a workstation, 2026-09-30, reported by the operator. ssh home-server logs in; ssh home-server.internal is refused with Permission denied (publickey). The operator expected the opposite, if either: the full mesh name is the one the resolver serves.

The name is not the fault. Both spellings resolve to the machine's private address — the mesh's roster region in the hosts file carries <node>.internal <node> on one line, and the resolver answers anything under the node's name. What differs is the login: the generated client configuration has a Host home-server block naming the account to log in as, and home-server.internal matches no block, so ssh falls back to the operator's local username, which has no account on that machine. Spelled account@home-server.internal it works.

The file is the predecessor's. ~/.ssh/config.d/mesh says in its own header that it is generated by the predecessor's terminal module, which only ever wrote the bare name. The mesh's own ssh-client roster — every other machine's Host block, written as a marked region of the operator's ~/.ssh/config with the account the mesh knows for that machine (to-be 29) — already matches both spellings, and a controller test holds Host marge marge.internal. It is composed and tested in the controller and is not a module in the catalogue, so no machine receives it; every workstation still runs the predecessor's generator.

Why it matters beyond this instance

A name the mesh serves and a name a person can use are not the same set, and the difference is silent. The resolver, the hosts file and the certificate authority all treat <node>.internal as the machine's name; the one file that decides who you log in as does not know it. A person who learns the mesh's name from status or from a certificate and types it is refused with an error that says nothing about a missing Host block.

It is the migration story for the operator's own tooling, arriving as a symptom. The mesh has the right file and does not ship it. Until the ssh-client roster is a module and is assigned to the workstations, the predecessor's generator keeps writing a file the mesh has already superseded, and every such file is one the mesh cannot correct.

Open questions

  • Should the ssh-client roster become a catalogue module now, assigned to every workstation, and take the predecessor's config.d/mesh out of the operator's Include? Its content is settled; what is not is the takeover of a file in a person's home that another generator still writes.
  • Should the block match a third spelling — the machine's public name, where it has one — or is that a different key and a different account?
  • What checks it? A controller test holds the two spellings; nothing checks that the file a workstation actually has is the mesh's rather than the predecessor's.