Merge pull request 'feat(seed): outbound SSH client material for hands-free node→mother' (#115) from seed-ssh-client-material into main
Reviewed-on: #115
This commit is contained in:
commit
af83717524
2 changed files with 91 additions and 1 deletions
|
|
@ -112,6 +112,65 @@ _seed_install_authorized_keys() {
|
|||
_seed_log "installed authorized_keys from ${_src} -> ${_dst}"
|
||||
}
|
||||
|
||||
# Install OUTBOUND ssh client material from an agent's ssh/ dir into the agent
|
||||
# home so a seeded node can SSH out (e.g. node -> mother) hands-free, with the
|
||||
# private key delivered on the offline seed instead of baked into the image:
|
||||
# config -> ~/.ssh/config (0600; e.g. a "Host mother" alias)
|
||||
# known_hosts* -> ~/.ssh/known_hosts* (0644; merged, so mother's host key
|
||||
# is trusted and the first connect
|
||||
# does not prompt)
|
||||
# <name>.pub -> ~/.ssh/<name>.pub (0644)
|
||||
# <name> -> ~/.ssh/<name> (0600; any other file = private key)
|
||||
# authorized_keys is INBOUND and handled by _seed_install_authorized_keys.
|
||||
_seed_install_ssh_material() {
|
||||
_srcdir="$1"
|
||||
_user="${2:-${SEED_USER}}"
|
||||
_home="${3:-${SEED_USER_HOME}}"
|
||||
|
||||
[ -d "${_srcdir}" ] || return 0
|
||||
|
||||
_ssh_dir="${_home}/.ssh"
|
||||
mkdir -p "${_ssh_dir}"
|
||||
chown "${_user}:${_user}" "${_ssh_dir}" 2>/dev/null || true
|
||||
chmod 0700 "${_ssh_dir}"
|
||||
|
||||
for _f in "${_srcdir}"/*; do
|
||||
[ -f "${_f}" ] || continue
|
||||
_base="$(basename "${_f}")"
|
||||
_dst="${_ssh_dir}/${_base}"
|
||||
case "${_base}" in
|
||||
authorized_keys)
|
||||
continue ;; # inbound, installed separately
|
||||
known_hosts|known_hosts2)
|
||||
touch "${_dst}"
|
||||
tr -d '\r' <"${_f}" >>"${_dst}"
|
||||
# De-dup so re-imports stay idempotent (order is irrelevant here).
|
||||
sort -u "${_dst}" -o "${_dst}" 2>/dev/null || true
|
||||
chmod 0644 "${_dst}"
|
||||
chown "${_user}:${_user}" "${_dst}" 2>/dev/null || true
|
||||
_seed_log "merged ${_base} -> ${_dst}" ;;
|
||||
config)
|
||||
tr -d '\r' <"${_f}" >"${_dst}.new"
|
||||
mv -f "${_dst}.new" "${_dst}"
|
||||
chmod 0600 "${_dst}"
|
||||
chown "${_user}:${_user}" "${_dst}" 2>/dev/null || true
|
||||
_seed_log "installed ssh config -> ${_dst}" ;;
|
||||
*.pub)
|
||||
tr -d '\r' <"${_f}" >"${_dst}.new"
|
||||
mv -f "${_dst}.new" "${_dst}"
|
||||
chmod 0644 "${_dst}"
|
||||
chown "${_user}:${_user}" "${_dst}" 2>/dev/null || true
|
||||
_seed_log "installed public key -> ${_dst}" ;;
|
||||
*)
|
||||
tr -d '\r' <"${_f}" >"${_dst}.new"
|
||||
mv -f "${_dst}.new" "${_dst}"
|
||||
chmod 0600 "${_dst}"
|
||||
chown "${_user}:${_user}" "${_dst}" 2>/dev/null || true
|
||||
_seed_log "installed private key -> ${_dst}" ;;
|
||||
esac
|
||||
done
|
||||
}
|
||||
|
||||
# Valid POSIX-ish shell env var name. Guards against garbled seed lines
|
||||
# injecting odd content into .env.
|
||||
_seed_key_ok() {
|
||||
|
|
@ -285,6 +344,11 @@ _seed_activate_agent() {
|
|||
if [ -f "${_dir}/ssh/authorized_keys" ]; then
|
||||
_seed_install_authorized_keys "${_dir}/ssh/authorized_keys" "${_user}" "${_home}"
|
||||
fi
|
||||
# Outbound client material (config, known_hosts, client keys) for node->mother
|
||||
# connectivity, delivered via the offline seed rather than baked in the image.
|
||||
if [ -d "${_dir}/ssh" ]; then
|
||||
_seed_install_ssh_material "${_dir}/ssh" "${_user}" "${_home}"
|
||||
fi
|
||||
|
||||
_seed_log "activated agent '${_agent}' for user ${_user} (home ${_home})"
|
||||
}
|
||||
|
|
|
|||
|
|
@ -79,7 +79,33 @@ Inside it, any of these are honored:
|
|||
under /var/db/clawdie/seed/<agent>/soul for
|
||||
the agent workspace to load.
|
||||
|
||||
/<agent>/ssh/authorized_keys Public SSH keys for this agent.
|
||||
/<agent>/ssh/authorized_keys INBOUND: public keys allowed to SSH INTO this
|
||||
node. Installed to ~/.ssh/authorized_keys (0600).
|
||||
|
||||
/<agent>/ssh/<name> OUTBOUND: a private client key so this node can
|
||||
SSH OUT hands-free (e.g. node -> mother).
|
||||
Installed to ~/.ssh/<name> (0600). The private
|
||||
key rides on this offline seed instead of being
|
||||
baked into the image, so the image stays
|
||||
secret-free. Any file here that is not
|
||||
authorized_keys/config/known_hosts and does not
|
||||
end in .pub is treated as a private key.
|
||||
|
||||
/<agent>/ssh/<name>.pub OUTBOUND: installed to ~/.ssh/<name>.pub (0644).
|
||||
|
||||
/<agent>/ssh/config OUTBOUND: installed to ~/.ssh/config (0600).
|
||||
Typical use — a host alias for the mother server:
|
||||
|
||||
Host mother
|
||||
HostName osa.smilepowered.org
|
||||
User clawdie
|
||||
IdentityFile ~/.ssh/osa-mother-2026
|
||||
|
||||
/<agent>/ssh/known_hosts OUTBOUND: merged into ~/.ssh/known_hosts (0644),
|
||||
de-duplicated. Pin the mother server's host key
|
||||
here so the first node -> mother connection does
|
||||
not stop on an unknown-host prompt. Get the line
|
||||
with: ssh-keyscan osa.smilepowered.org
|
||||
|
||||
Agent directory names may contain only A-Z a-z 0-9 . _ - (no spaces or
|
||||
slashes). The name `ssh` is reserved for Layer 1.
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue