From bba3424e2a7916bcb5f4f412244c9bfeab3834c8 Mon Sep 17 00:00:00 2001 From: "Toerd@archlinux" Date: Sun, 12 Apr 2020 16:44:32 +0200 Subject: [PATCH] feat: configure yubikey script added --- configure-yubikey.sh | 164 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 164 insertions(+) create mode 100755 configure-yubikey.sh diff --git a/configure-yubikey.sh b/configure-yubikey.sh new file mode 100755 index 0000000..f4a785f --- /dev/null +++ b/configure-yubikey.sh @@ -0,0 +1,164 @@ +#!/bin/bash +# author: phga +# date: 2020-04-04 +# desc: script to configure hmac/hotp on yubikeys + add required local configurations +me=$(basename "$0") +uname=$(logname) +# DEFINITIONS +# Add new types like |XY +G='\033[0;32m' +R='\033[0;31m' +N='\033[0m' # Normal + +y_or_n() { + read -p "(y/n): " answ +} + +generate_new_secret() { + secret_key=$(dd if=/dev/urandom bs=1 count=20 status=none | sha256sum | cut -b 1-40) +} + +ask_for_mode() { + while [[ ! "$mode" =~ ^(hmac|hotp)$ ]]; do + read -p "Which mode do you want to configure (hmac|hotp): " mode + done +} + +ask_for_secret() { + echo -e "Do you already have a secret? " && y_or_n + if [ ! "$answ" = "y" ]; then + generate_new_secret + else + read -p "Enter your secret key: " secret_key + fi +} + +check_secret() { + while [[ ! "$secret_key" =~ [a-f0-9]{40} ]]; do + echo -e "${R}Key must be 40 char HEX string${N}" + ask_for_secret + done +} + +ask_for_otp_slot() { + while [[ ! "$slot" =~ ^[12]$ ]]; do + read -p "Onto which slot should I configure htop (1|2): " slot + done +} + +delete_old_users() { + echo -e "${R}Deleted every hotp mapping in /etc/users.oath${N}" + sudo sed -i '/^HOTP.*/d' /etc/users.oath + echo "# Config automatically generated by $me <3" | sudo tee -a /etc/users.oath > /dev/null +} + +write_hotp_config() { + echo -e "Writing config to Yubikeys Slot $slot and creating initial mapping in /etc/users.oath" + sudo ykpersonalize -"$slot" -o oath-hotp -o oath-hotp8 -o append-cr -a "$secret_key" -y + [ ! -f "/etc/users.oath" ] && sudo touch "/etc/users.oath" + sudo sed -i "$ a HOTP ${uname} - ${secret_key}" /etc/users.oath + echo -e "Do you want to configure another Yubikey?" + echo -e "If so, unplug this Yubikey and insert the next one!" + echo -e "${G}NOTE: Using one Yubikey with multiple devices to authenticate doesn't make much sense" + echo -e "since the hex value on the Key increases per use => Key/Device(users.oath) out of sync${N}" + y_or_n +} + +write_pam_config() { + echo -e "Writing oath config lines into /etc/pam.d/login and /etc/pam.d/sudo" + echo -e "${R}Make sure to install oath-toolkit or similar package which provides pam_oath.so${N}" + sudo sed -i '/.*pam_oath\.so*/d' /etc/pam.d/login + sudo sed -i "2 i auth sufficient pam_oath.so usersfile=/etc/users.oath window=50 digits=8" /etc/pam.d/login + sudo sed -i '/.*pam_oath\.so*/d' /etc/pam.d/sudo + sudo sed -i "2 i auth sufficient pam_oath.so usersfile=/etc/users.oath window=50 digits=8" /etc/pam.d/sudo +} + +write_hmac_config() { + echo -e "Do you want to touch the key every time you need the chal-resp? " && y_or_n + to="-t" + [ ! "$answ" = "y" ] && to=" " + echo -e "Writing config to Yubikeys Slot $slot" + sudo ykman otp chalresp $to -f "$slot" "$secret_key" + echo -e "Do you want to configure another Yubikey?" + echo -e "If so, unplug this Yubikey and insert the next one!" + echo -e "${R}IMPORTANT: This secret has to be the same on all yubikeys, so that if we lose one, we are still able to decryt our password db.${N}" + y_or_n +} + +save_secret() { + echo "Let me save the secret as an encrypted file in ./secret.bak" + echo "$secret_key" | gpg -c -a -o ./secret.bak +} + +ask_to_save_secret() { + echo -e "Do you want me to save the secret for you?\n${R}It is REALLY IMPORTANT that you don't lose this secret!${N}\nYou will need GPG for the next step tho..." && y_or_n + [ "$answ" = "y" ] && save_secret +} + +check_requirements() { + if [ ! -f /lib/security/pam_oath.so ]; then + echo -e "${R}[WARNING]${N} It seems like /lib/security/pam_oath.so is missing" + else + echo -e "${G}[OK]${N} pam_oath.so found in /lib/security/" + fi + if ! hash ykman; then + echo -e "${R}[WARNING]${N} It seems like ykman is missing" + else + echo -e "${G}[OK]${N} ykman is installed" + fi + if ! hash ykpersonalize; then + echo -e "${R}[WARNING]${N} It seems like ykpersonalize is missing" + else + echo -e "${G}[OK]${N} ykpersonalize is installed" + fi +} + +while getopts "k:s:m:dh" opt; +do case $opt in + k) secret_key=${OPTARG} ;; + s) slot=${OPTARG} ;; + m) mode=${OPTARG} ;; + d) delete=1 ;; + h) echo -e "\nUsage: $me [OPTIONS]\n\nExamples:\n\n $ $me -m hmac -s 2 -k 583fa46c3d9bb0936ae36569dfacca2a304fa090 -d\n\nOptions:\n -m [hmac|hotp] mode to configure\n -s [1|2] slot to use\n -k SECRET 40 char secret key (hex)\n -d delete entries in /etc/users.oath\n" >&2 && exit ;; + \?) echo -e "-$OPTARG is not valid\nUsage: $me [OPTIONS]\n\nExamples:\n\n $ $me -m hmac -s 2 -k 583fa46c3d9bb0936ae36569dfacca2a304fa090 -d\n\nOptions:\n -m [hmac|hotp] mode to configure\n -s [1|2] slot to use\n -k SECRET 40 char secret key (hex)\n -d delete entries in /etc/users.oath\n" >&2 && exit ;; + esac +done + +echo -e "+------------------------------+" +echo -e "| Yubikey configuration script |" +echo -e "| Written by ${G}toerd${N} with ${R}<3${N} |" +echo -e "+------------------------------+" + +check_requirements +ask_for_mode +check_secret +ask_for_otp_slot +case $mode in + hmac) + write_hmac_config + while [ "$answ" = "y" ]; do + write_hmac_config + done + ask_to_save_secret + ;; + hotp) + [ "$delete" = 1 ] && delete_old_users + write_hotp_config + while [ "$answ" = "y" ]; do + write_hotp_config + done + write_pam_config + ;; + *) + echo -e "${R}No mode entered :(${N}" + ;; +esac + + +echo -e "${R}+------------------------------------------------------+" +echo -e "| WRITE THE SECRET KEY DOWN TO CONFIGURE OTHER DEVICES | " +echo -e "| SK: $secret_key |" +echo -e "| Used slot on Yubikey: $slot |" +echo -e "+------------------------------------------------------+${N}" + +exit \ No newline at end of file