From c4de5a088b8bdc7f3ad6cc6cc55a78d28b20425b Mon Sep 17 00:00:00 2001 From: Pratik Date: Fri, 18 Jan 2019 09:45:16 +0530 Subject: [PATCH] Updates --- init-linux-harden.sh | 382 ++++++++++++++++++++++++------------------- 1 file changed, 216 insertions(+), 166 deletions(-) diff --git a/init-linux-harden.sh b/init-linux-harden.sh index a5eb79b..c80a19b 100644 --- a/init-linux-harden.sh +++ b/init-linux-harden.sh @@ -28,7 +28,10 @@ SCRIPT_NAME=server_harden SCRIPT_VERSION=0.2 LOGFILE=/tmp/"$SCRIPT_NAME"_v"$SCRIPT_VERSION".log -BACKUP_EXTENSION='.'$(date '+%d%m%Y%H%M%S')"_bak" +# Reset previous log file +TS=$(date '+%d_%m_%Y-%H_%M_%S') +echo "Starting $0 - $TS" > "$LOGFILE" +BACKUP_EXTENSION='.'$TS"_bak" # Colors CSI='\033[' @@ -36,13 +39,40 @@ CEND="${CSI}0m" CRED="${CSI}1;31m" CGREEN="${CSI}1;32m" + +############################################################## +# Usage +############################################################## +# Script takes arguments as follows +# init-linux-harden -username=pratik --resetrootpwd +# init-linux-harden -u pratik --resetrootpwd + +function usage() { + if [ -n "$1" ]; then + echo "" + echo -e "${CRED}$1${CEND}\n" + fi + + echo "Usage: sudo bash $0 [-u|--username username] [-r|--resetrootpwd] [--defaultsourcelist]" + echo " -u, --username Username for your server (If omitted script will choose an username for you)" + echo " -r, --resetrootpwd Reset current root password" + echo " -d, --defaultsourcelist Updates /etc/apt/sources.list to download software from debian.org." + echo " NOTE - If you fail to update system after using it, you need to manually reset it. This script keeps a backup in the same folder." + + echo "" + echo "Example: $0 --username myuseraccount --resetrootpwd" + printf "\\nBelow restrictions apply to username this script accepts - \\n" + printf "%2s - [a-zA-Z0-9] [-] [_] are allowed\\n%2s - NO special characters.\\n%2s - NO spaces.\\n" " " " " " " +} + + ############################################################## # Basic checks before starting ############################################################## # No root - no good [ "$(id -u)" != "0" ] && { - printf "ERROR: You must be root to run this script.\\nPlease login as root and execute the script again." + usage "ERROR: You must be root to run this script.\\nPlease login as root and execute the script again." exit 1 } @@ -57,32 +87,11 @@ else exit 1 fi + ################################## # Parse script arguments ################################## -# Script takes arguments as follows -# init-linux-harden -username=pratik --resetroot -# init-linux-harden -u pratik --resetroot - -function usage() { - if [ -n "$1" ]; then - echo "" - echo -e "${CRED}$1${CEND}\n" - fi - - echo "Usage: $0 [-u|--username username] [-r|--resetrootpwd] [--defaultsourcelist]" - echo " -u, --username Username for your server (If omitted script will choose an username for you)" - echo " -r, --resetrootpwd Reset current root password" - echo " -d, --defaultsourcelist Updates /etc/apt/sources.list to download software from debian.org." - echo " NOTE - If you fail to update system after using it, you need to manually reset it. This script keeps a backup in the same folder." - - echo "" - echo "Example: $0 --username myuseraccount --resetrootpwd" - printf "\\nBelow restrictions apply to username this script accepts - \\n" - printf "%2s - [a-zA-Z0-9] [-] [_] are allowed\\n%2s - NO special characters.\\n%2s - NO spaces.\\n" " " " " " " -} - # defaults AUTO_GEN_USERNAME="y" RESET_ROOT_PWD="n" @@ -130,39 +139,112 @@ done ############################################################## -# Log +# Display what the script does ############################################################## -CVERTICAL="|" -CHORIZONTAL="_" +clear +cat <> "$LOGFILE" >&2 fi } @@ -257,29 +339,25 @@ function revert_root_pass_change(){ true } -function finally(){ - # Check if $what_failed is one of the catastrophic failures - # if - Catastrofic failure - Check if any .bkp file exist and revert them to original - # Let user know nothing was changed - # if - Non-catastrophic failure - Inform user of side effects - #local what_failed=$1 - line_fill "$CHORIZONTAL" 60 - recap "New root Password" "$PASS_ROOT" - recap "User Name" "$NORM_USER_NAME" - recap "User's Password" "$USER_PASS" - recap "User's SSH Private Key Location" "$KEY_PASS" - recap "User's SSH Public Key Location" "$KEY_PASS" - recap "User's SSH Key Passphrase" "$KEY_PASS" - line_fill "$CHORIZONTAL" 60 +############################################################## +# Log +############################################################## - # If something failed - try to revert things back - if [[ "$#" -gt 0 ]]; then - # show - something failed - trying to restore required changes - revert_changes "$1" +CVERTICAL="|" +CHORIZONTAL="_" - # If restoration failed - well you are f**ked - fi +function horizontal_fill() { + local char=$1 + declare -i rep=$2 + for ((x = 0; x < "$rep"; x++)); do + printf %s "$char" + done +} + +function line_fill() { + horizontal_fill "$1" "$2" + printf "\\n" } function file_log(){ @@ -292,69 +370,63 @@ function op_log() { if [ "$RESULT" = "SUCCESSFUL" ] then - printf "\r%30s %7s [${CGREEN}${RESULT}${CEND}]\\n" "$EVENT" " " + update_event_status "${EVENT}" 2 + printf "\r%33s %7s [${CGREEN}${RESULT}${CEND}]\\n" "$EVENT" " " file_log "${EVENT} - ${RESULT}" elif [ "$RESULT" = "FAILED" ] then - printf "\r%30s %7s [${CRED}${RESULT}${CEND}]\\n" "$EVENT" " " + update_event_status "${EVENT}" 3 + printf "\r%33s %7s [${CRED}${RESULT}${CEND}]\\n" "$EVENT" " " printf "\\n\\nPlease look at %s\\n\\n" "$LOGFILE" file_log "${EVENT} - ${RESULT}" finally "$EVENT" else - printf "%30s %7s [${CRED}..${CEND}]" "$EVENT" " " + update_event_status "${EVENT}" 1 + printf "%33s %7s [${CRED}..${CEND}]" "$EVENT" " " file_log "${EVENT} - begin..." fi } -# Reset previous log file -echo "Starting $0 - $(date '+%d-%b-%Y %H:%M:%S')" > "$LOGFILE" +function recap (){ + local purpose=$1 + local status=$2 + local value=$3 + if [[ $status -eq 0 ]]; then + value="[${CGREEN}--NO_OP--${CEND}]" + elif [[ $status -eq 2 ]]; then + value="[${CGREEN}${value}${CEND}]" + elif [[ $status -eq 1 ]] || [[ $status -eq 3 ]]; then + value="${CRED}--ERROR--${CEND}" + fi -############################################################## -# Display what the script does -############################################################## + horizontal_fill "$CVERTICAL" 1 + printf "%20s:%3s%-49s" "$purpose" " " "$(echo -e "$value")" + line_fill "$CVERTICAL" 1 +} -clear -cat <> "$LOGFILE" >&2 if [[ $? -eq 0 ]]; then op_log "Creating new user" "SUCCESSFUL" else op_log "Creating new user" "FAILED" - finally "CNU" exit 1; fi @@ -401,19 +472,22 @@ op_log "Creating SSH Key for new user" # If SSH files already exist - rename them to .timestamp_bkp if [[ ${#KEY_FILES[@]} -gt 0 ]]; then for key in "${KEY_FILES[@]}"; do - cp "$key" "$key""$BACKUP_EXTENSION" || exit 1 + cp "$key" "$key""$BACKUP_EXTENSION" || false + file_log "SSH Key File exists ($key) - Making backup ($key$BACKUP_EXTENSION) of the existing file" done fi SSH_DIR=/home/"$NORM_USER_NAME"/.ssh - mkdir "$SSH_DIR" || exit 1 + mkdir "$SSH_DIR" || false + file_log "Created SSH directory - $SSH_DIR" # Generate a 15 character random password for key - KEY_PASS="$(< /dev/urandom tr -cd "[:alnum:]" | head -c 15)" || exit 1 + KEY_PASS="$(< /dev/urandom tr -cd "[:alnum:]" | head -c 15)" file_log "Generated SSH Key Passphrase - ${KEY_PASS}" # Create a OpenSSH-compliant ed25519-type key - ssh-keygen -a 1000 -o -t ed25519 -N "$KEY_PASS" -C "$NORM_USER_NAME" -f "$SSH_DIR"/"$NORM_USER_NAME".pem -q || exit 1 + ssh-keygen -a 1000 -o -t ed25519 -N "$KEY_PASS" -C "$NORM_USER_NAME" -f "$SSH_DIR"/"$NORM_USER_NAME".pem -q || false + file_log "Generated SSH Key File - $SSH_DIR/$NORM_USER_NAME.pem" # TODO - Below would capture bak files as well - filter out the bak files # See if the files actually got created @@ -421,7 +495,7 @@ op_log "Creating SSH Key for new user" if [[ ${#KEY_FILES[@]} -eq 0 ]]; then file_log "Unknown error occured." file_log "Could not create SSH key files." - exit 1 + retun false fi } 2>> "$LOGFILE" >&2 @@ -429,35 +503,6 @@ if [[ $? -eq 0 ]]; then op_log "Creating SSH Key for new user" "SUCCESSFUL" else op_log "Creating SSH Key for new user" "FAILED" - finally "CSK" - exit 1; -fi - - -############################################################## -# Add generated key to authorized_keys file -############################################################## - -op_log "Adding SSH Key to 'authorized_keys' file" -{ - # If 'authorized_keys' exists create backup - # BACKUP_EXTENSION - if [[ -e "$SSH_DIR"/authorized_keys ]]; then - cp "$SSH_DIR"/authorized_keys "$SSH_DIR"/authorized_keys"$BACKUP_EXTENSION" || exit 1 - else - # Create authorized_keys if it does not exist yet - touch "$SSH_DIR"/authorized_keys || exit 1 - fi - - # Insert the public key into "authoried_keys" file - cat "$SSH_DIR"/"$NORM_USER_NAME".pem.pub >> "$SSH_DIR"/authorized_keys || exit 1 -} 2>> "$LOGFILE" >&2 - -if [[ $? -eq 0 ]]; then - op_log "Adding SSH Key to 'authorized_keys' file" "SUCCESSFUL" -else - op_log "Adding SSH Key to 'authorized_keys' file" "FAILED" - finally "ATAF" exit 1; fi @@ -473,13 +518,16 @@ op_log "Securing 'authorized_keys' file" chgrp -R "$NORM_USER_NAME" "$SSH_DIR" && \ chmod 700 "$SSH_DIR" && \ chmod 400 "$SSH_DIR"/authorized_keys && \ - chattr +i "$SSH_DIR"/authorized_keys + chattr +i "$SSH_DIR"/authorized_keys || false + file_log "Set appropriate permissions for $SSH_DIR dir and $SSH_DIR/authorized_keys file" # Restrict access to the generated SSH Key files as well for key in "${KEY_FILES[@]}"; do chmod 400 "$key" && \ chattr +i "$key" done + file_log "Restrict access to the generated SSH Key files" + } 2>> "$LOGFILE" >&2 if [[ $? -eq 0 ]]; then @@ -575,16 +623,20 @@ function set_config_key(){ op_log "Enabling SSH-only login" { # Backup the sshd_config file - cp /etc/ssh/sshd_config /etc/ssh/sshd_config"$BACKUP_EXTENSION" || exit 1 + cp /etc/ssh/sshd_config /etc/ssh/sshd_config"$BACKUP_EXTENSION" || false + file_log "Backed up /etc/ssh/sshd_config file to /etc/ssh/sshd_config$BACKUP_EXTENSION" # Remove root login - set_config_key "/etc/ssh/sshd_config" "PermitRootLogin" "no" + set_config_key "/etc/ssh/sshd_config" "PermitRootLogin" "no" || false + file_log "Remove root login -> PermitRootLogin no" # Disable password login - set_config_key "/etc/ssh/sshd_config" "PasswordAuthentication" "no" + set_config_key "/etc/ssh/sshd_config" "PasswordAuthentication" "no" || false + file_log "Disable password login -> PasswordAuthentication no" # Set SSH Authorization-Keys path - set_config_key "/etc/ssh/sshd_config" "AuthorizedKeysFile" '%h\/\.ssh\/authorized_keys' + set_config_key "/etc/ssh/sshd_config" "AuthorizedKeysFile" '%h\/\.ssh\/authorized_keys' || false + file_log "Set SSH Authorization-Keys path -> AuthorizedKeysFile '%h\/\.ssh\/authorized_keys'" systemctl restart sshd } 2>> "$LOGFILE" >&2 @@ -593,7 +645,6 @@ if [[ $? -eq 0 ]]; then op_log "Enabling SSH-only login" "SUCCESSFUL" else op_log "Enabling SSH-only login" "FAILED" - finally "ESOL" exit 1; fi @@ -654,7 +705,6 @@ TAG fi - ############################################################## # Install required softwares ############################################################## @@ -676,10 +726,10 @@ fi ############################################################## if [[ $RESET_ROOT_PWD == 'y' ]]; then - op_log " " + op_log "Changing root password" { # Generate a 15 character random password - PASS_ROOT="$(< /dev/urandom tr -cd "[:alnum:]" | head -c 15)" || exit 1 + PASS_ROOT="$(< /dev/urandom tr -cd "[:alnum:]" | head -c 15)" || false file_log "Generated Root Password - ${PASS_ROOT}"