Skip to content

Instantly share code, notes, and snippets.

@Slyke
Last active September 12, 2022 09:12
Show Gist options
  • Save Slyke/d8f2e50052657d35bfc90a40823d9653 to your computer and use it in GitHub Desktop.
Save Slyke/d8f2e50052657d35bfc90a40823d9653 to your computer and use it in GitHub Desktop.
Automatic Install SSH Keys
#!/bin/bash
# Created by: Slyke
# Email: [email protected]
# Version: 3
# Date: 2022-09-10
# This script allows you to automatically install SSH keys from your github account, and optionally disable password authentication for sshd.
# Best to clone this script to your own github gist and curl it from there, instead of using mine.
# It is also better to dump this to a file locally and run it from there if placed in a cronjob.
# License: MIT
# Save this script to a file:
# curl -fsSL https://gist.githubusercontent.com/Slyke/d8f2e50052657d35bfc90a40823d9653/raw -o update_ssh_key.sh
# Usage:
# Help:
# curl -fsSL https://gist.githubusercontent.com/Slyke/d8f2e50052657d35bfc90a40823d9653/raw | bash -s -- --help
# Basic:
# curl -fsSL https://gist.githubusercontent.com/Slyke/d8f2e50052657d35bfc90a40823d9653/raw | bash
# or
# curl -fsSL https://gist.githubusercontent.com/Slyke/d8f2e50052657d35bfc90a40823d9653/raw?$(date +%s) | sudo bash -s -- --skip-ssh-warning --disable-password-authentication --username githubUsername --localuser ubuntu
# Do not remove current keys from authorized_keys file:
# curl -fsSL https://gist.githubusercontent.com/Slyke/d8f2e50052657d35bfc90a40823d9653/raw?$(date +%s) | bash -s -- --skip-ssh-warning --username githubUsername --skip-remove-keys
# *************************
VERBOSE_MODE=0
DISABLE_PASSWORD_AUTH=0
SKIP_SSH_WARNING=0
SKIP_REMOVE_KEYS="false"
AUTH_KEYS_FILE_PARAM=""
SSH_CONFIG_FILE=/etc/ssh/sshd_config
function printHelp() {
echo "Usage:"
echo " --quiet"
echo " No output, unless displaying errors or input is required."
echo ""
echo " --clear"
echo " Clears all entries in the used authorization_keys file"
echo ""
echo " --username {USERNAME}"
echo " Set your github username so that you are not prompted for it"
echo ""
echo " --localuser {USERNAME}"
echo " Set your local username in case you use sudo for this command. Chmod for this authorized_keys file will be udpated to 600 and chowned will be set to this username."
echo ""
echo " --auth-keys-file {PATH}"
echo " Set your authorized_keys file path."
echo ""
echo " --disable-password-authentication"
echo " Updates $SSH_CONFIG_FILE to disable password authentication and then restarts ssh service. Requires sudo access. Warning: You may lock yourself out."
echo ""
echo " --skip-ssh-warning"
echo " Skips the warning and the wait when --disable-password-authentication is set."
echo ""
echo " --skip-remove-keys"
echo " Do not remove keys from the authorized_keys file that are not in the github account. Placing '# KEEP-KEY' after the key in the authorized_keys file will also prevent it from being removed."
echo ""
echo " --help"
echo " Displays this message"
echo ""
echo "Example:"
echo " $0 --clear --username slyke --quiet"
echo ""
exit 0
}
function setUsername() {
GH_USERNAME=$1
}
function setAuthKeysFile() {
AUTH_KEYS_FILE_PARAM=$1
}
function setLocalUser() {
LOCAL_USERNAME=$1
}
function clearAuthKeys() {
if [ -f $AUTH_KEYS_FILE ]; then
echo "" > $AUTH_KEYS_FILE
fi
}
function disablePasswordAuthentication () {
sudo -E grep -q "ChallengeResponseAuthentication" $SSH_CONFIG_FILE && sed -i "/^[^#]*ChallengeResponseAuthentication[[:space:]]yes.*/c\ChallengeResponseAuthentication no" $SSH_CONFIG_FILE || echo "ChallengeResponseAuthentication no" >> $SSH_CONFIG_FILE
sudo -E grep -q "^[^#]*PasswordAuthentication" $SSH_CONFIG_FILE && sed -i "/^[^#]*PasswordAuthentication[[:space:]]yes/c\PasswordAuthentication no" $SSH_CONFIG_FILE || echo "PasswordAuthentication no" >> $SSH_CONFIG_FILE
sudo -E service ssh restart
}
while test $# -gt 0
do
case "$1" in
--quiet) VERBOSE_MODE=1
;;
--username) setUsername $2
;;
--localuser) setLocalUser $2
;;
--auth-keys-file) setAuthKeysFile $2
;;
--clear) clearAuthKeys
;;
--disable-password-authentication) DISABLE_PASSWORD_AUTH=1
;;
--disable-password-auth) DISABLE_PASSWORD_AUTH=1
;;
--disable-passwd-auth) DISABLE_PASSWORD_AUTH=1
;;
--skip-ssh-warning) SKIP_SSH_WARNING=1
;;
--skip-remove-keys) SKIP_REMOVE_KEYS="true"
;;
--help) printHelp
;;
-h) printHelp
;;
--*) echo "Bad option $1"; echo "For help use: $0 --help "; exit 3
;;
esac
shift
done
if [ -z ${GH_USERNAME} ]; then
echo ""
echo "Enter your github username"
read GH_USERNAME < /dev/tty;
fi
if [ -z ${LOCAL_USERNAME} ]; then
AUTH_KEYS_FILE=~/.ssh/authorized_keys
else
AUTH_KEYS_FILE=/home/$LOCAL_USERNAME/.ssh/authorized_keys
fi
exec 3>&1
# exec 4>&2
if [[ "$VERBOSE_MODE" -eq 1 ]]; then
exec 1>/dev/null
# exec 2>/dev/null
fi
if [[ -n ${AUTH_KEYS_FILE_PARAM} ]]; then
AUTH_KEYS_FILE="$AUTH_KEYS_FILE_PARAM"
echo "Using '$AUTH_KEYS_FILE' as authorized_keys file"
if [[ -z $AUTH_KEYS_FILE ]]; then
echo "No authorized_keys file set. Exiting."
exit 3
fi
fi
if [ ! -f $AUTH_KEYS_FILE ]; then
touch $AUTH_KEYS_FILE
if [[ $? -eq 0 ]]; then
echo "Created: '$AUTH_KEYS_FILE'"
else
echo "Something went wrong creating: '$AUTH_KEYS_FILE'"
exit 2
fi
fi
if [[ "$DISABLE_PASSWORD_AUTH" -eq 1 ]]; then
if [[ ! "$SKIP_SSH_WARNING" -eq 1 ]]; then
echo "Will disable password authentication and restart sshd service after installing ssh keys."
echo "Press ctrl+c now to cancel."
sleep 5
fi
fi
KEYS_ADDED=0
KEYS_SKIPPED=0
KEYS_INVALID=0
KEYS_REMOVED=0
SSH_KEYS=$(curl -s "https://github.com/$GH_USERNAME.keys?$(date +%s)")
if [[ "$SSH_KEYS" == "Not Found" ]]; then
>&2 echo "Username '$GH_USERNAME' not found"
>&2 echo "URL: 'https://github.com/$GH_USERNAME.keys'"
exit 1
fi
if [[ ${#SSH_KEYS} -le 16 ]]; then
>&2 echo "Something went wrong retrieving SSH keys for '$GH_USERNAME'"
>&2 echo "URL: 'https://github.com/$GH_USERNAME.keys'"
>&2 echo "Result: "
>&2 echo "$SSH_KEYS"
exit 2
fi
while read -r AUTH_KEY; do AUTHKEYS+=("$AUTH_KEY"); done <<<"$SSH_KEYS"
for i in "${!AUTHKEYS[@]}"; do
if grep -Fq "${AUTHKEYS[$i]}" $AUTH_KEYS_FILE ; then
KEYS_SKIPPED=$(( $KEYS_SKIPPED + 1 ))
# echo "Key $i already exists in '$AUTH_KEYS_FILE' Skipping..."
else
if [[ "${AUTHKEYS[$i]}" =~ ^ssh.*|^ssh-rsa.* ]]; then
echo "${AUTHKEYS[$i]} # Added at: $(date '+%Y-%m-%d %H:%M:%S')" >> $AUTH_KEYS_FILE
echo "Key [$i] added."
KEYS_ADDED=$(( $KEYS_ADDED + 1 ))
else
echo "Invalid key from Github. Key should start with 'ssh'"
KEYS_INVALID=$(( $KEYS_INVALID + 1 ))
fi
fi
done
REMOVER_INDEX=0
if [[ "$SKIP_REMOVE_KEYS" == "false" ]]; then
while read AUTHLINE; do
REMOVER_INDEX=$((REMOVER_INDEX + 1))
if grep -Fq "${SSH_KEYS}" <<< "$AUTHLINE" ; then
# echo "Key $REMOVER_INDEX exists in returned ssh keys. Will not remove..."
echo "${AUTHLINE}" >> $AUTH_KEYS_FILE.tmp
else
if [[ "${AUTHLINE}" =~ .*"# KEEP-KEY".*|.*"# KEEP_KEY".*|.*"# KEEP_ME".*|.*"# KEEP-ME".* ]]; then
# echo "Key $REMOVER_INDEX contains skip token. Skipping..."
echo "${AUTHLINE}" >> $AUTH_KEYS_FILE.tmp
else
if [ ${#AUTHLINE} -ge 1 ]; then # Skip empty lines
echo "Key $REMOVER_INDEX removed"
KEYS_REMOVED=$(( $KEYS_REMOVED + 1 ))
fi
fi
fi
done <<< "$(cat $AUTH_KEYS_FILE)"
command cp -rf $AUTH_KEYS_FILE $AUTH_KEYS_FILE.bak
mv -f $AUTH_KEYS_FILE.tmp $AUTH_KEYS_FILE
fi
echo "Keys Added: $KEYS_ADDED"
echo "Keys Skipped: $KEYS_SKIPPED"
if [[ "$SKIP_REMOVE_KEYS" == "false" ]]; then
echo "Keys Removed: $KEYS_REMOVED"
fi
echo "Keys Invalid (also skipped): $KEYS_INVALID"
if [ -n ${LOCAL_USERNAME} ]; then
echo "User: $(whoami) (Local Username: $LOCAL_USERNAME)"
chmod 600 $AUTH_KEYS_FILE
echo "File '$AUTH_KEYS_FILE' chmod updated to '600'"
chown $LOCAL_USERNAME:$LOCAL_USERNAME $AUTH_KEYS_FILE
echo "File '$AUTH_KEYS_FILE' owner updated to '$LOCAL_USERNAME:$LOCAL_USERNAME'"
else
echo "User: $(whoami)"
fi
if [[ "$DISABLE_PASSWORD_AUTH" -eq 1 ]]; then
if [[ -f $AUTH_KEYS_FILE ]]; then
echo "Disabling password authentication and restarting sshd:"
disablePasswordAuthentication
else
echo "Couldn't find auth keys file $AUTH_KEYS_FILE. Will not disable password authentication."
fi
fi
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment