Keep what ssh reads itself and linked key folders in ~/.ssh, and fail the sweep loudly (issue 1020, ADR 0417)
mesh/merge-gate head 05e6b583e2e3 merged into trunk ce56b491cffd — pass: builds ssh-client → ace, g14, novox, shanks; no bus step; every machine composes w…
mesh/repo-check head 05e6b583e2e3 merged into trunk ce56b491cffd — pass: THE CHANGE ALTERS ITS OWN CHECK (merge-check.sh): main's version judged it; the ch…
mesh/delivery delivered
mesh/merge-gate head 05e6b583e2e3 merged into trunk ce56b491cffd — pass: builds ssh-client → ace, g14, novox, shanks; no bus step; every machine composes w…
mesh/repo-check head 05e6b583e2e3 merged into trunk ce56b491cffd — pass: THE CHANGE ALTERS ITS OWN CHECK (merge-check.sh): main's version judged it; the ch…
mesh/delivery delivered
The sweep from issue 1017 moved known_hosts2, rc and environment, which ssh and sshd read by default, and moved a link to a folder of keys, breaking every login through it. It could move a file a tool was still writing. When ~/.local was on another file system, every sweep failed at its first move and left an empty folder each round, seen only in the journal. Its list was written after the moves with errors ignored. Now those files and linked key folders stay; a link whose target, or the folder it names, cannot be checked is left and named; a copy of authorized_keys is moved at any depth; a path changed in the last minute, at any depth, waits for the next sweep; a retired folder on another file system fails the sweep before anything is made; the list names each move before it is made; and each sweep's outcome is kept for ssh_client_check, which shows a failed sweep as a problem. A key's first line is read only so far. The catalogue's new checks/sshdir refuses any manifest but ssh-client naming a path under ~/.ssh (ADR 0415 §6). The README cites §7 for config.d.
This commit is contained in:
@@ -8,13 +8,14 @@ item 9). `sshd` is the machine's side.
|
||||
| path | class | how |
|
||||
|---|---|---|
|
||||
| `~/.ssh/` | owned | directory, the account's, mode 0700 |
|
||||
| `~/.ssh/config.d/` | owned | directory, the account's, mode 0700. It holds only the files this module declares (ADR 0415 §6). As every module's owned path, ssh-client is the only module that writes under `~/.ssh`: another module that needs a host there provides it through a provision, and this module writes it (ADR 0349 §1; the forge's host comes from `forge-account`). A host of the operator's own goes in `~/.ssh/config` below the mesh's region |
|
||||
| `~/.ssh/config.d/` | owned | directory, the account's, mode 0700. Apart from keys, it holds only the files this module declares (ADR 0415 §7). As every module's owned path, ssh-client is the only module that writes under `~/.ssh`: another module that needs a host there provides it through a provision, and this module writes it (ADR 0349 §1; the forge's host comes from `forge-account`). A host of the operator's own goes in `~/.ssh/config` below the mesh's region |
|
||||
| `~/.ssh/config.d/10-forge` | owned | the forge's host, with the machine's own key (ADR 0399) |
|
||||
| `~/.ssh/mesh_ed25519`, `.pub` | written by the module's own process | the machine's account's key for the forge, made once (keykeeper.go) |
|
||||
| `~/.ssh/config.d/00-mesh` | owned | a Host block per other machine of the mesh (a roster fact), regenerated whenever a machine joins, leaves or is renamed. It begins with the mesh's header |
|
||||
| `~/.ssh/config` | written into, **at the start** | the mesh's region, `# BEGIN mesh ssh-client.config` … `# END …`. It holds one `Include ~/.ssh/config.d/*`. Every line below the region is the operator's, kept byte for byte |
|
||||
| `~/.ssh/authorized_keys` | found | see *The gap* |
|
||||
| `~/.ssh/known_hosts` | found | see *The gap* |
|
||||
| `~/.ssh/authorized_keys2`, `known_hosts2`, `rc`, `environment` | kept | the files ssh and sshd read by themselves; this module writes none of them and never moves them (ADR 0415 §1, ADR 0417 §1) |
|
||||
| private keys, public keys, certificates | kept | never read, never written, never moved, at any depth and whatever their name. `ssh_client_keys` and `ssh_client_check` read a file's first line to recognise a key, and ask `ssh-keygen` about it |
|
||||
| anything else | swept | moved out of `~/.ssh` by the sweep (below) |
|
||||
|
||||
@@ -68,6 +69,23 @@ of what moved is written beside it as `<UTC time>.json`. Nothing is deleted. A f
|
||||
is gone into rather than moved whole, so the key stays where it is. A file or folder that cannot be read to
|
||||
tell whether it holds a key is left and named in the log.
|
||||
|
||||
ADR 0417 (issue 1020) adds:
|
||||
|
||||
- the files ssh and sshd read by themselves (`authorized_keys2`, `known_hosts2`, `rc`, `environment`) stay;
|
||||
- a symbolic link to a key, or to a folder holding one, stays; a link whose target cannot be checked is left
|
||||
and named; any other link is moved as the link;
|
||||
- a path changed less than a minute ago is being written (ssh-keygen's or `ssh_client_revoke`'s temporary
|
||||
file) and waits for the next sweep;
|
||||
- the retired folder must be on `~/.ssh`'s file system: otherwise the sweep moves nothing, makes no
|
||||
folder and fails. A sweep that moved nothing leaves no folder;
|
||||
- the list names each move before it is made, and a list that cannot be written stops the sweep;
|
||||
- each sweep writes what it did, or why it failed, to `~/.local/state/ssh-client/last-sweep.json`.
|
||||
`ssh_client_check` reports a failed last sweep, and a listed move with nothing at its destination, as a
|
||||
problem.
|
||||
|
||||
No other module declares a path under `~/.ssh` (ADR 0415 §6): the catalogue's `checks/sshdir` fails one
|
||||
that does.
|
||||
|
||||
So the predecessor's `config.d/mesh`, `config.bak-*`, `known_hosts.old`, `removed-*` and
|
||||
`authorized_keys.revoked-*` leave `~/.ssh` at the first sweep. Each move is logged by the process, and
|
||||
`ssh_client_check` lists every sweep that moved something, with where each path lies now.
|
||||
@@ -110,4 +128,7 @@ The tests use a temporary home and a fake runner, with public keys made for the
|
||||
- `known_host` matching, changed and refreshed, and an unreachable host never refreshed;
|
||||
- `test`: success, and failure with the agent named;
|
||||
- `check`'s findings;
|
||||
- the sweep: what it keeps (keys at any depth, links to keys and to key folders, sockets, what ssh reads
|
||||
itself), what it moves, what it leaves and names, a file being written, another file system, and the
|
||||
list written before each move;
|
||||
- that the tools served are the manifest's `tools`.
|
||||
|
||||
Reference in New Issue
Block a user