228 lines
6.5 KiB
Bash
228 lines
6.5 KiB
Bash
|
function zssh_boot()
|
||
|
{
|
||
|
typeset -g zssh_ssh_dotdir="${HOME}/.ssh"
|
||
|
typeset -g zssh_private_keys="${zssh_ssh_dotdir}/keystore"
|
||
|
typeset -g zssh_private_configs="${zssh_ssh_dotdir}/config.d"
|
||
|
typeset -g zssh_global_configs=${globaldots_path}/config/ssh
|
||
|
typeset -g zssh_global_pubkeys=${globaldots_path}/keys/ssh
|
||
|
zssh_configure
|
||
|
zssh_process
|
||
|
}
|
||
|
|
||
|
function zssh_configure ()
|
||
|
{
|
||
|
if [[ -n "$zssh_host" ]]
|
||
|
then
|
||
|
zbootstrap_message zssh "zssh_host is set"
|
||
|
ztools_ensure -d $zssh_private_keys
|
||
|
ztools_ensure -d $zssh_private_configs
|
||
|
ztools_ensure -d ${zssh_global_configs}
|
||
|
ztools_ensure -d ${zssh_global_pubkeys}
|
||
|
zssh_enumeratenodes
|
||
|
if [[ ${#zssh_host_config_accesses} -gt 0 ]]
|
||
|
then
|
||
|
zbootstrap_message zssh "zssh_host_config_accesses is set"
|
||
|
typeset -g zssh_global_config_hostdir="${zssh_global_configs}/${zssh_host}"
|
||
|
typeset -g zssh_global_pubkey_hostdir="${zssh_global_pubkeys}/${zssh_host}"
|
||
|
ztools_ensure -d "${zssh_global_pubkey_hostdir}"
|
||
|
ztools_ensure -d "${zssh_global_config_hostdir}"
|
||
|
else
|
||
|
zbootstrap_message zssh "zssh_host_config_accesses is NOT set, not going to bother accepting keys"
|
||
|
fi
|
||
|
else
|
||
|
zbootstrap_message zssh "zssh_host is NOT set, which means we cannot neither publish keys nor accept them"
|
||
|
fi
|
||
|
}
|
||
|
|
||
|
function zssh_process()
|
||
|
{
|
||
|
if [[ -n "$zssh_host" ]]
|
||
|
then
|
||
|
if [[ ${#zssh_host_config_accesses} -gt 0 ]]
|
||
|
then
|
||
|
zbootstrap_message zssh "processing ssh server setup"
|
||
|
if [[ "${HOME}/.config/zsh/local.config.zsh" -nt "${zssh_global_config_hostdir}" ]]
|
||
|
then
|
||
|
zbootstrap_message zssh "publishing our configs …"
|
||
|
zssh_publish_configs
|
||
|
else
|
||
|
zbootstrap_message zssh "not publishing our configs …"
|
||
|
fi
|
||
|
fi
|
||
|
zbootstrap_message zssh "processing ssh client setup"
|
||
|
zssh_install_peers
|
||
|
zssh_publish_pubkeys
|
||
|
fi
|
||
|
}
|
||
|
|
||
|
function zssh_install_peers()
|
||
|
{
|
||
|
[[ -n $zssh_host ]] || return 63
|
||
|
zbootstrap_message zssh "installing peers"
|
||
|
for ssh_node in $zssh_nodes
|
||
|
do
|
||
|
zbootstrap_message zssh "installing peer $ssh_node …"
|
||
|
zssh_generate_privkey4 $ssh_node
|
||
|
zssh_generate_config4 $ssh_node
|
||
|
done
|
||
|
}
|
||
|
|
||
|
function zssh_publish_pubkeys()
|
||
|
{
|
||
|
for ssh_node in $zssh_nodes
|
||
|
do
|
||
|
zssh_mail_pubkey2 $ssh_node
|
||
|
done
|
||
|
}
|
||
|
|
||
|
function zssh_mail_pubkey2()
|
||
|
{
|
||
|
[[ -n $zssh_host ]] || return 63
|
||
|
ssh_node="$1"
|
||
|
local targetspool="$zssh_global_pubkeys/$ssh_node"
|
||
|
local srcpk="$zssh_private_keys/$ssh_node.key.pub"
|
||
|
ztools_ensure -d "${targetspool}"
|
||
|
cp -t "$targetspool" "$srcpk"
|
||
|
}
|
||
|
|
||
|
function zssh_publish_configs()
|
||
|
{
|
||
|
[[ -n "$zssh_host_config_accesses" ]] || return 62
|
||
|
for sshmatch in ${(k)zssh_host_config_accesses}
|
||
|
do
|
||
|
hostaccessconfig_file="${zssh_global_config_hostdir}/${sshmatch}.sshconf"
|
||
|
zbootstrap_message zssh "generating our server access config '${hostaccessconfig_file}'"
|
||
|
zssh_generate_hostaccessconfig $sshmatch > "$hostaccessconfig_file"
|
||
|
done
|
||
|
zbootstrap_message zssh "updating mtime for ${zssh_global_config_hostdir}"
|
||
|
touch "${zssh_global_config_hostdir}"
|
||
|
}
|
||
|
|
||
|
function zssh_generate_hostaccessconfig()
|
||
|
{
|
||
|
sshmatch="${1}"
|
||
|
sshcontents=${zssh_host_config_accesses[$sshmatch]}
|
||
|
sshmatch_user=${sshmatch%%@*}
|
||
|
sshmatch_host=${sshmatch##*@}
|
||
|
if [[ "$sshmatch_host" == "$sshmatch_user" ]]
|
||
|
then
|
||
|
sshmatch_user=''
|
||
|
fi
|
||
|
<< HERE
|
||
|
Match ${sshmatch_host:+host $sshmatch_host,} ${sshmatch_user:+user $sshmatch_user,}
|
||
|
${sshcontents}
|
||
|
${zssh_host_config}
|
||
|
HERE
|
||
|
}
|
||
|
|
||
|
function zssh_generate_config4
|
||
|
{
|
||
|
ssh_node="$1"
|
||
|
dst="$zssh_private_configs/$ssh_node.sshconf"
|
||
|
srcs="$zssh_global_configs/$ssh_node"
|
||
|
zbootstrap_message zssh "checking configs for $ssh_node …"
|
||
|
if [[ -d "$srcs" ]] && ! [[ $dst -nt $srcs ]]
|
||
|
then
|
||
|
sshkey="$zssh_private_keys/$ssh_node.key"
|
||
|
zbootstrap_message zssh "found fresh configs directory for $ssh_node"
|
||
|
zbootstrap_message zssh "config destination is '$dst'"
|
||
|
zbootstrap_message zssh "tied ssh key is '$sshkey'"
|
||
|
rm "$dst" 2> /dev/null
|
||
|
for src in "$srcs"/*.sshconf(N)
|
||
|
do
|
||
|
zbootstrap_message zssh "sourcing $src"
|
||
|
cat "$src" >> "$dst"
|
||
|
printf "\n IdentityFile %s\n\n" "$sshkey" >> "$dst"
|
||
|
done
|
||
|
fi
|
||
|
zbootstrap_message zssh "done with $ssh_node"
|
||
|
}
|
||
|
|
||
|
function zssh_generate_privkey4
|
||
|
{
|
||
|
ssh_node="$1"
|
||
|
zbootstrap_message zssh "checking keys for peer $ssh_node …"
|
||
|
local newkey=$zssh_private_keys/$ssh_node.key
|
||
|
if ! [[ -s $newkey ]]
|
||
|
then
|
||
|
zbootstrap_message zssh "generate key for $ssh_node"
|
||
|
ssh-keygen -t ed25519 -N '' -C "$ssh_host($USER@$HOST) for $ssh_node" -f $newkey >> "${HOME}/.log/ssh-keygen.log"
|
||
|
if [[ "$ssh_node" == "$zssh_host" ]]
|
||
|
then
|
||
|
zbootstrap_message zssh "Self accepting key: $ssh_node"
|
||
|
cat "$newkey.pub" >> ${HOME}/.ssh/authorized_keys
|
||
|
fi
|
||
|
fi
|
||
|
}
|
||
|
|
||
|
function zssh_offer_all()
|
||
|
{
|
||
|
# offers keys for every node
|
||
|
if ! [[ -d $zssh_private_keys ]]
|
||
|
then
|
||
|
zbootstrap_message zssh "$zssh_private_keys not found"
|
||
|
return
|
||
|
fi
|
||
|
if [[ -n $zssh_thishost ]]
|
||
|
then
|
||
|
for ssh_node in $zssh_nodes
|
||
|
do
|
||
|
local node_directory=$zssh_global_configs/$ssh_node
|
||
|
local keytooffer=$node_directory/keyoffers/$zssh_thishost.pub
|
||
|
local keysource=$zssh_private_keys/$ssh_node.key
|
||
|
if ! [[ -s $keysource ]]
|
||
|
then
|
||
|
zbootstrap_message zssh "$ssh_node misses $keysource private key in keystore"
|
||
|
continue
|
||
|
fi
|
||
|
if ! [[ -d $node_directory ]]
|
||
|
then
|
||
|
zbootstrap_message zssh "$ssh_node misses its config directory '$node_directory'"
|
||
|
continue
|
||
|
fi
|
||
|
if ! [[ -d $node_directory/keyoffers ]]
|
||
|
then
|
||
|
zbootstrap_message zssh "creating keyoffer directory for $ssh_node"
|
||
|
mkdir $node_directory/keyoffers
|
||
|
fi
|
||
|
# offering ...
|
||
|
if ! [[ -s $keytooffer ]]
|
||
|
then
|
||
|
zbootstrap_message zssh "Offering public key for $ssh_node"
|
||
|
ssh-keygen -y -f $keysource -C "$zssh_thishost offered to ${ssh_node}" > $keytooffer
|
||
|
fi
|
||
|
done
|
||
|
else
|
||
|
zbootstrap_message zssh "no zssh_thishost defined, offering skipped"
|
||
|
fi
|
||
|
}
|
||
|
|
||
|
function zssh_accept_key()
|
||
|
{
|
||
|
local offered=$zssh_global_configs/$zssh_thishost/keyoffer/$1.pub
|
||
|
cat $offered
|
||
|
echo "do you accept key '$1'? :"
|
||
|
read
|
||
|
if [[ $REPLY == 'Y' ]]
|
||
|
then
|
||
|
echo "key $1 accepted"
|
||
|
cat $offered >> ${HOME}/.ssh/authorized_keys
|
||
|
else
|
||
|
echo "key $1 NOT accepted"
|
||
|
fi
|
||
|
}
|
||
|
|
||
|
function zssh_enumeratenodes()
|
||
|
{
|
||
|
typeset -g -a zssh_nodes;
|
||
|
zbootstrap_message zssh "enumerating nodes"
|
||
|
if [[ -d $zssh_global_configs ]]
|
||
|
then
|
||
|
for __ssh_node in ${zssh_global_configs}/*(/)
|
||
|
do
|
||
|
zssh_nodes+=($(basename $__ssh_node))
|
||
|
done
|
||
|
fi
|
||
|
zbootstrap_message zssh "got ${#zssh_nodes} nodes"
|
||
|
}
|