142 lines
4.2 KiB
Bash
142 lines
4.2 KiB
Bash
#!/bin/sh
|
|
# ssh_passwordless_manager.sh
|
|
# Manage passwordless SSH hosts: list, add, delete, edit, query.
|
|
|
|
CONFIG_FILE="$HOME/.ssh_playground_hosts"
|
|
|
|
# Ensure config file exists
|
|
touch "$CONFIG_FILE"
|
|
|
|
# Print usage information
|
|
usage() {
|
|
cat <<EOF
|
|
Usage: $(basename "$0") <command> [options]
|
|
|
|
Commands:
|
|
list List all hosts configured for SSH connection
|
|
add <alias> <user@host> <priv_key> [pub_key]
|
|
Add a new host; installs public key and saves config
|
|
delete <alias> Remove a host; deletes key from remote and config
|
|
edit <alias> <new_priv_key> [new_pub_key]
|
|
Replace the key for a given host
|
|
query <alias> Show the configuration for a given host
|
|
help Show this help message
|
|
EOF
|
|
exit 1
|
|
}
|
|
|
|
# Load entry by alias
|
|
load_entry() {
|
|
grep "^$1|" "$CONFIG_FILE"
|
|
}
|
|
|
|
# List hosts
|
|
list_hosts() {
|
|
if [ ! -s "$CONFIG_FILE" ]; then
|
|
echo "No hosts configured."
|
|
exit 0
|
|
fi
|
|
printf "%-15s %-25s %s\n" "ALIAS" "USER@HOST" "PRIVATE_KEY"
|
|
echo "---------------------------------------------------------------"
|
|
while IFS='|' read -r alias userhost privkey pubkey; do
|
|
printf "%-15s %-25s %s\n" "$alias" "$userhost" "$privkey"
|
|
done < "$CONFIG_FILE"
|
|
}
|
|
|
|
# Add host
|
|
add_host() {
|
|
[ $# -lt 3 ] && echo "add requires alias, user@host, private key" && usage
|
|
alias="$1"; userhost="$2"; privkey="$3"; pubkey="$4"
|
|
[ -z "$pubkey" ] && pubkey="${privkey}.pub"
|
|
|
|
if load_entry "$alias" >/dev/null; then
|
|
echo "Alias '$alias' already exists." && exit 1
|
|
fi
|
|
|
|
# Copy public key to remote
|
|
echo "Installing public key to $userhost..."
|
|
ssh-copy-id -i "$pubkey" "$userhost" || { echo "Failed to install key."; exit 1; }
|
|
|
|
# Save to config
|
|
echo "$alias|$userhost|$privkey|$pubkey" >> "$CONFIG_FILE"
|
|
echo "Host '$alias' added."
|
|
}
|
|
|
|
# Delete host
|
|
delete_host() {
|
|
[ $# -lt 1 ] && echo "delete requires alias" && usage
|
|
alias="$1"
|
|
entry=$(load_entry "$alias")
|
|
[ -z "$entry" ] && echo "Alias '$alias' not found." && exit 1
|
|
|
|
IFS='|' read -r _ userhost privkey pubkey <<EOF
|
|
$entry
|
|
EOF
|
|
|
|
# Read public key content
|
|
pubcontent=$(sed -n '1p' "$pubkey")
|
|
|
|
# Remove key from remote authorized_keys
|
|
echo "Removing public key from $userhost..."
|
|
ssh "$userhost" "mkdir -p ~/.ssh && chmod 700 ~/.ssh && \
|
|
grep -v '$pubcontent' ~/.ssh/authorized_keys > ~/.ssh/authorized_keys.tmp && \
|
|
mv ~/.ssh/authorized_keys.tmp ~/.ssh/authorized_keys" || echo "Warning: could not remove key on remote."
|
|
|
|
# Remove from config
|
|
grep -v "^$alias|" "$CONFIG_FILE" > "$CONFIG_FILE.tmp" && mv "$CONFIG_FILE.tmp" "$CONFIG_FILE"
|
|
echo "Host '$alias' deleted."
|
|
}
|
|
|
|
# Edit host key
|
|
edit_host() {
|
|
[ $# -lt 2 ] && echo "edit requires alias and new private key" && usage
|
|
alias="$1"; newpriv="$2"; newpub="$3"
|
|
[ -z "$newpub" ] && newpub="${newpriv}.pub"
|
|
entry=$(load_entry "$alias")
|
|
[ -z "$entry" ] && echo "Alias '$alias' not found." && exit 1
|
|
|
|
IFS='|' read -r _ userhost oldpriv oldpub <<EOF
|
|
$entry
|
|
EOF
|
|
|
|
# Remove old key
|
|
oldcontent=$(sed -n '1p' "$oldpub")
|
|
echo "Removing old key from $userhost..."
|
|
ssh "$userhost" "grep -v '$oldcontent' ~/.ssh/authorized_keys > ~/.ssh/authorized_keys.tmp && mv ~/.ssh/authorized_keys.tmp ~/.ssh/authorized_keys" || echo "Warning: could not remove old key."
|
|
|
|
# Install new key
|
|
echo "Installing new public key to $userhost..."
|
|
ssh-copy-id -i "$newpub" "$userhost" || { echo "Failed to install new key."; exit 1; }
|
|
|
|
# Update config
|
|
grep -v "^$alias|" "$CONFIG_FILE" > "$CONFIG_FILE.tmp"
|
|
echo "$alias|$userhost|$newpriv|$newpub" >> "$CONFIG_FILE.tmp"
|
|
mv "$CONFIG_FILE.tmp" "$CONFIG_FILE"
|
|
echo "Host '$alias' updated."
|
|
}
|
|
|
|
# Query host
|
|
query_host() {
|
|
[ $# -lt 1 ] && echo "query requires alias" && usage
|
|
alias="$1"
|
|
entry=$(load_entry "$alias")
|
|
[ -z "$entry" ] && echo "Alias '$alias' not found." && exit 1
|
|
IFS='|' read -r _ userhost privkey pubkey <<EOF
|
|
$entry
|
|
EOF
|
|
echo "Alias : $alias"
|
|
echo "Host : $userhost"
|
|
echo "Priv key : $privkey"
|
|
echo "Pub key : $pubkey"
|
|
}
|
|
|
|
# Main dispatch
|
|
case "$1" in
|
|
list) list_hosts ;;
|
|
add) shift; add_host "$@" ;;
|
|
delete) shift; delete_host "$@" ;;
|
|
edit) shift; edit_host "$@" ;;
|
|
query) shift; query_host "$@" ;;
|
|
help|*) usage ;;
|
|
esac
|