The ssh install command works over sftp (closes #10)
All checks were successful
check / check (push) Successful in 20s
All checks were successful
check / check (push) Successful in 20s
The command no longer sends a shell script to the host. It fetches ~/.ssh/authorized_keys with the system sftp in batch mode, adds the key line here, and writes the file back in a second session: mkdir and chmod on ~/.ssh, put to authorized_keys.keyfunc-<random>, chmod 600, rename over authorized_keys. Adding the line connects twice. The file reads as empty only when sftp reported it as not there, in the line naming that path; the same wording elsewhere -- ssh writes it about an identity file it cannot find -- does not count, so a file that cannot be read is never written over. A failed step removes nothing and names the uploaded file once sftp's echo shows the put was reached. Model: opus-5
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