Skip to content

Instantly share code, notes, and snippets.

@JSouthGB
Last active July 14, 2024 17:06
Show Gist options
  • Save JSouthGB/84d0d9725b4cd19b638dd746d84914ab to your computer and use it in GitHub Desktop.
Save JSouthGB/84d0d9725b4cd19b638dd746d84914ab to your computer and use it in GitHub Desktop.
Generate SSH key file pair, copy to remote server, and add entry to .ssh/config
#!/usr/bin/env bash
# TODO: Allow specifying the key type and size as optional arguments
# TODO: Validate the IP address, port number, and hostname
# TODO: Add a check for the existence of the .ssh directory/config file
# TODO: Better handling of existing SSH config entries, offer to update/append
# TODO: Check that external commands are available before using them
# This script generates SSH key file pairs, copies the key file to a remote server, and adds an entry in the local .ssh/config
# Check for terminal color support
if [ -t 1 ]; then
RED='\033[0;31m'
NO_COLOR='\033[0m'
else
RED=''
NO_COLOR=''
fi
display_help() {
echo "Usage: $0 -k <key_name> -u <remote_username> -i <remote_ip> -p <remote_port> -n <host_name>"
echo "Arguments:"
echo " -k key_name - The name of the SSH key file."
echo " -u remote_username - The username for the remote system."
echo " -i remote_ip - The IP address of the remote system."
echo " -p remote_port - The port number of the remote system."
echo " -n host_name - The host name to use in the .ssh/config file."
exit 0
}
check_preconditions() {
local key_name=$1
local host_name=$2
local found_issues=0
# Check if the SSH key file pairs already exist
if [ -f "$HOME/.ssh/${key_name}" ] || [ -f "$HOME/.ssh/${key_name}.pub" ]; then
echo -e "${RED}Key file name ${key_name} already exists.${NO_COLOR}"
found_issues=1
fi
# Check for duplication in .ssh/config
if grep -q "^Host ${host_name}$" "$HOME/.ssh/config"; then
echo -e "${RED}An entry for ${host_name} already exists in .ssh/config.${NO_COLOR}"
found_issues=1
fi
# Exit if any issues were found
if [ "$found_issues" -ne 0 ]; then
echo "Resolve the issues and try again."
exit 1
fi
}
generate_ssh_key() {
local key_name=$1
ssh-keygen -f "$HOME/.ssh/${key_name}" -t ecdsa -b 521
chmod 600 "$HOME/.ssh/${key_name}"
chmod 644 "$HOME/.ssh/${key_name}.pub"
}
copy_ssh_key() {
local username=$1
local ip_address=$2
local key_name=$3
local remote_port=$4
ssh-copy-id -i "$HOME/.ssh/${key_name}.pub" -p "${remote_port}" "${username}@${ip_address}"
}
add_ssh_config() {
local host_name=$1
local ip_address=$2
local user_name=$3
local remote_port=$4
local key_name=$5
echo -e "\nHost ${host_name}
HostName ${ip_address}
User ${user_name}
Port ${remote_port}
IdentityFile $HOME/.ssh/${key_name}" >> "$HOME/.ssh/config"
chmod 644 "$HOME/.ssh/config"
}
# main()
while getopts ":hk:u:i:p:n:" opt; do
case ${opt} in
h )
display_help
;;
k )
key_name=$OPTARG
;;
u )
remote_username=$OPTARG
;;
i )
remote_ip=$OPTARG
;;
p )
remote_port=$OPTARG
;;
n )
host_name=$OPTARG
;;
\? )
echo -e "${RED}Invalid Option: -$OPTARG${NO_COLOR}" 1>&2
display_help
;;
: )
echo -e "${RED}Option -$OPTARG requires an argument.${NO_COLOR}" 1>&2
exit 1
;;
esac
done
shift $((OPTIND -1))
# Check for unexpected arguments
if [ $# -gt 0 ]; then
echo -e "${RED}Unexpected arguments provided.${NO_COLOR}"
display_help
exit 1
fi
# Ensure all required arguments were provided
if [ -z "${key_name}" ] || [ -z "${remote_username}" ] || [ -z "${remote_ip}" ] || [ -z "${remote_port}" ] || [ -z "${host_name}" ]; then
echo -e "${RED}All arguments are required.${NO_COLOR}"
display_help
exit 1
fi
check_preconditions "${key_name}" "${host_name}"
generate_ssh_key "${key_name}"
copy_ssh_key "${remote_username}" "${remote_ip}" "${key_name}" "${remote_port}"
add_ssh_config "${host_name}" "${remote_ip}" "${remote_username}" "${remote_port}" "${key_name}"
echo "SSH setup completed."
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment