ssh install works over sftp and runs nothing on the host (closes #10)
All checks were successful
check / check (push) Successful in 4s
All checks were successful
check / check (push) Successful in 4s
ssh install no longer runs a command on the host. It reads .ssh/authorized_keys over sftp, takes the empty reading only from sftp's own message about that path, appends the derived key locally when it is not already present, uploads the result beside the file with mode 0600 and renames it over the original. Any other failure prints what sftp said, writes nothing and exits 1. sftp batch mode disables password prompts, so a key or agent is required; a directory the owner cannot enter reads as a host with no file, which README.md states. Model: opus-5 (implementation); fable-5-1 (landing)
This commit was merged in pull request #11.
This commit is contained in:
48
README.md
48
README.md
@@ -88,17 +88,49 @@ Prints the unencrypted private key in OpenSSH format (the
|
||||
and nothing else, so it can be redirected into a file. The key's comment is the
|
||||
same as for `pub`.
|
||||
|
||||
### `keyfunc ssh install <[user@]host> [-- ssh options...]`
|
||||
### `keyfunc ssh install <[user@]host> [-- sftp options...]`
|
||||
|
||||
Runs the system `ssh` to the host and, on the host:
|
||||
Adds the `pub` line to `~/.ssh/authorized_keys` on the host. No command is run
|
||||
on the host: the file is fetched, changed here, and written back with the
|
||||
system `sftp` client in batch mode.
|
||||
|
||||
- creates `~/.ssh` with mode `0700` if it is missing;
|
||||
- creates `~/.ssh/authorized_keys` with mode `0600` if it is missing;
|
||||
- appends the `pub` line only if an identical line is not already there.
|
||||
The first connection fetches `~/.ssh/authorized_keys`. The file reads as empty
|
||||
only when `sftp` reported that file as not being there — the one line naming
|
||||
that path. The same wording anywhere else in the session does not count: `ssh`
|
||||
writes `No such file or directory` about an `-i` it cannot find, on a session
|
||||
that then authenticates through the agent. When `sftp` failed for any other
|
||||
reason — the file is there and cannot be read, the connection did not come up —
|
||||
the tool prints what `sftp` said and exits with status 1 without writing
|
||||
anything, rather than put a file back holding the new key alone. What `sftp`
|
||||
cannot tell apart is a missing file and one in a directory it cannot enter, so a
|
||||
`~/.ssh` whose mode shuts the user out reads as a host with no file; the second
|
||||
connection sets that mode to `0700` and writes, as on a host that has none. If
|
||||
an identical line is already in the file, the tool prints
|
||||
`already present` and connects no further. Otherwise the line is added (after a
|
||||
newline, if the file did not end with one) and a second connection:
|
||||
|
||||
It then prints `added` or `already present`. How this `ssh` connection
|
||||
authenticates is up to the user's normal `ssh` setup (existing keys, agent,
|
||||
password). Anything after `--` is passed to `ssh` unchanged.
|
||||
- creates `~/.ssh` and sets it to mode `0700`;
|
||||
- uploads the new file as `~/.ssh/authorized_keys.keyfunc-<random>` and sets it
|
||||
to mode `0600`;
|
||||
- renames that file over `~/.ssh/authorized_keys`.
|
||||
|
||||
The tool then prints `added`. So a run that adds a line connects twice. The
|
||||
rename is the step that either happens or does not: the file on the host is
|
||||
never half-written. `sftp` does it in one step against servers that offer
|
||||
OpenSSH's POSIX rename extension, as OpenSSH's own server does; a server
|
||||
without it may refuse to rename onto a file that is already there.
|
||||
|
||||
If a step fails, the tool prints what `sftp` said, removes nothing, and exits
|
||||
with status 1. It names the uploaded file only when the step that failed was
|
||||
the upload or one after it, which is where a file of that name can be on the
|
||||
host; a failure before the upload names none. Everything `sftp`
|
||||
writes goes to standard error, so the tool's own standard output is only
|
||||
`added` or `already present`.
|
||||
|
||||
Anything after `--` is passed to `sftp` unchanged, which is where the port goes
|
||||
(`-P 2222`, not `-p`). How the connection authenticates is up to the user's
|
||||
normal `ssh` setup, except that batch mode does not prompt: a key or an agent
|
||||
has to do it, not a typed password.
|
||||
|
||||
### `keyfunc ssh to <host> [ssh arguments...]`
|
||||
|
||||
|
||||
Reference in New Issue
Block a user