Permalink
Switch branches/tags
Nothing to show
Find file Copy path
Fetching contributors…
Cannot retrieve contributors at this time
executable file 224 lines (193 sloc) 5.86 KB
#!/bin/bash
# The Keymaker v2
# o——m
#
# Generates and pushes ssh keys for remote machines.
#
# Setup: make executable via `chmod u+x the_keymaker.sh`
# Optional: OS-dependant. These have been tested on Ubuntu.
# 1) Place in /usr/local/bin/ and rename so it is available in your path; or
# 2) Create an alias to reference this file.
# Run: `./the_keymaker.sh` and enter information based on prompts.
#
# This tool was created to help developers maintain a
# succinct and relatively safe ssh config file.
################
# Variables #
################
#Generic variables
ssh_folder="$HOME/.ssh"
ssh_config_path="$ssh_folder/config"
quiet=false
verbose=false
first_key=false
#config file variables
hostname=""
shortname=""
remoteuser=""
email=""
################
# Function #
################
#Exits the program if an error status code is returned. Otherwise prints OK
catch() {
if [[ "$@" =~ ^-?[0-9]+$ ]]; then
local STATUS="$@";
else
"$@"
local STATUS=$?;
fi
if [ $STATUS -ne 0 ]; then
echo -e "[\e[31mFAILED\e[39m]";
exit $STATUS;
else
echo -e "[\e[32mOK\e[39m]";
fi
return $STATUS;
}
################
# Setup #
################
#Grab command line arguments
while [[ $# > 0 ]]; do
key="$1"
case $key in
-q|--quiet)
quiet=true
shift # past argument
;;
-v|--verbose)
verbose=true
shift
;;
*)
# unknown option
echo "Error: Unknown flag: '$key'"
exit 1;
;;
esac
done
#Mutually exclusive flags, make sure they're all good
if [[ $verbose == true && $quiet == true ]]; then
echo "Cannot be both verbose and quiet. Please choose one option or the other.";
exit 1;
fi
# Create missing folder if necessary
if [ ! -d "$ssh_folder" ]; then
if [[ $quiet == false ]]; then
echo -n "Missing folder $ssh_folder creating..."
fi
catch mkdir -p "$ssh_folder"
fi
# Create config file if necessary
if [ -f $ssh_config_path ]; then
#Check if keymaker has made on before, if not make a backup and inform user
# What's going on.
if grep -q "^#Generated by the_keymaker o——m" "$ssh_config_path"; then
if [[ $verbose == true ]]; then
echo "Config file previously created by the keymaker. Will append key."
fi
else
backup_path="$ssh_config_path.BACKUP"
echo "========================================================"
echo " WARNING"
echo " You appear to already have a config file located at:"
echo " $ssh_config_path"
echo " Therefore the keymaker will backup your config file at:"
echo " $backup_path"
echo "========================================================="
echo -n "Creating backup... "
catch mv $ssh_config_path $backup_path
echo -n "Creating new config file..."
catch touch $ssh_config_path
first_key=true
fi
else
echo -n "Missing config file, creating..."
catch touch "$ssh_config_path"
first_key=true
fi
#If this is the first key keymaker has made we want to throw some safe defaults into the config file.
if [[ $first_key == true ]]; then
echo "First SSH Key generated by keymaker, creating safe default values."
echo "#Generated by the_keymaker o——m" > $ssh_config_path
echo "Host *" >> $ssh_config_path
echo " VisualHostKey yes" >> $ssh_config_path
echo " ServerAliveInterval 30" >> $ssh_config_path
echo " ServerAliveCountMax 120" >> $ssh_config_path
echo " IdentitiesOnly yes" >> $ssh_config_path
echo " ForwardAgent no" >> $ssh_config_path
echo " ForwardX11 no" >> $ssh_config_path
echo " UseRoaming no" >> $ssh_config_path
fi
################
# User Input #
################
#Get hostname to use in ssh user@hostname
while [ "$hostname" == "" ]; do
read -r -p "Enter host name you wish to generate keys for: " hostname
if [ "$hostname" == "" ]; then
echo -e "[\e[31mError\e[39m] Missing hostname!";
fi
done
#This is optional and thus does not have a while loop
read -r -p "Enter a shortname for the host. eg 'sn' Allows for ssh sn. Leave blank for none: " shortname
if [ "$shortname" == "" ]; then
shortname="$hostname"
fi
#Get remote user to use in ssh user@hostname
while [ "$remoteuser" == "" ]; do
read -r -p "Enter username for remote host: " remoteuser
if [ "$remoteuser" == "" ]; then
echo -e "[\e[31mError\e[39m] Missing remote user name!";
fi
done
#Get email to use in the ssh key
while [ "$email" == "" ]; do
read -r -p "Enter your email to be associated with this key: " email
if [ "$email" == "" ]; then
echo -e "[\e[31mError\e[39m] Missing remail!";
fi
done
#Create variables based on information passed
key_filename="$hostname""_id"
key_filepath="$HOME/.ssh/$key_filename"
#Create ssh key (with or without a passphrase)
key_pass="n"
read -r -p "Do you want to use a passphrase with this key? y/n (default: n): " key_pass
echo ""
if [[ "$key_pass" == "y" || "$key_pass" == "Y" ]]; then
ssh-keygen -t rsa -b 4096 -C "$email" -f "$key_filepath"
else
ssh-keygen -t rsa -b 4096 -C "$email" -N "" -f "$key_filepath"
fi
keygen_status=$?
#If the key was created successfully echo the host info to the config file
#Give the user some info and copy to the remote machine.
if [ $keygen_status -eq 0 ]; then
echo "
Host $shortname
User $remoteuser
HostName $hostname
IdentityFile $key_filepath
VisualHostKey yes" >> $ssh_config_path
echo -e "\e[32mKey generation complete! o——m\e[39m";
echo ""
echo "Going to attempt to copy ssh public key to remote server for passwordless login..."
read -r -s -p "Press any key to continue" -n 1 dummyvar
echo ""
echo "Now attempting to copy key over..."
ssh-copy-id -i "$key_filepath.pub" $remoteuser@$hostname
copy_result=$?
if [ $copy_result -eq 0 ]; then
echo "SSH key setup complete!";
exit 0;
else
echo "ERROR: An error occurred copying the key to the remote server."
echo "Try again manually."
exit $copy_result
fi
else
echo "Error with key generation, exiting with status code.";
exit $keygen_status;
fi