From 389712283ec8852fce6f54c1955f8810ae7dec60 Mon Sep 17 00:00:00 2001 From: Pratik Tripathy <> Date: Thu, 4 Sep 2025 22:42:03 +0530 Subject: [PATCH] Option to quit, log-level in file logs, fixes, refactors - feat: Add log-level to file logs - refactor: Calculate duration inside `formatted_execution_duration` - refactor: Console log display `OK` -> `DONE` - fix: Debian/Ubuntu: Set default TZ -> UTC to let the installation continue without getting stuck - fix: Use local variable to store `JAIL_LOCAL_FILE` in `update_fail2ban_jail_local_file` - feat: Give user option to quit before starting the script --- init-linux-harden.sh | 269 ++++++++++++++++++++++--------------------- 1 file changed, 138 insertions(+), 131 deletions(-) diff --git a/init-linux-harden.sh b/init-linux-harden.sh index f2c9e40..d65af33 100755 --- a/init-linux-harden.sh +++ b/init-linux-harden.sh @@ -4,10 +4,9 @@ SCRIPT_NAME=server-init-harden SCRIPT_VERSION=2.0 TIMESTAMP=$(date '+%Y-%m-%d_%H-%M-%S') LOGFILE_NAME="${SCRIPT_NAME}_${TIMESTAMP}.log" -SHOW_CREDENTIALS=false START_TIME=$(date +%s) -# username and root-reset flag +SHOW_CREDENTIALS=false USERNAME="" RESET_ROOT=false @@ -63,7 +62,6 @@ EOF exit 1 } -# Parse command line arguments parse_args() { while [ "$#" -gt 0 ]; do case "$1" in @@ -73,7 +71,8 @@ parse_args() { USERNAME="$2" shift 2 else - console_log "Error" "Invalid username format. Must start with a letter and contain only alphanumeric characters, hyphens, or underscores." + console_log "ERROR" "Invalid username format. Must start with a letter and contain only alphanumeric characters, hyphens, or underscores." + file_log "ERROR" "Invalid username format. Must start with a letter and contain only alphanumeric characters, hyphens, or underscores." exit 1 fi ;; @@ -89,7 +88,8 @@ parse_args() { usage ;; *) - console_log "Error" "Unknown option: $1" + console_log "ERROR" "Unknown option: $1" + file_log "ERROR" "Unknown option: $1" exit 1 ;; esac @@ -104,43 +104,46 @@ create_logfile() { } file_log() { - # $1: Log message + # $1: Log level + # $2: Log message # Write to logfile with timestamps and log level timestamp=$(date '+%Y-%m-%d %H:%M:%S') - printf "%s: %s\n" "$timestamp" "$1" >>"$LOGFILE_NAME" + printf "[%s] %s: %s\n" "$timestamp" "$1" "$2" >>"$LOGFILE_NAME" } console_log() { # $1: Log level # $2: Log message + case "$1" in - Success | SUCCESS) printf "[\033[0;32m OK \033[0m] %s\n" "$2" ;; - Error | ERROR) printf "[\033[0;31m FAIL \033[0m] %s\n" "$2" ;; - Warning | WARNING) printf "[\033[0;33m WARN \033[0m] %s\n" "$2" ;; - Info | INFO) printf "[\033[0;34m INFO \033[0m] %s\n" "$2" ;; - CREDENTIALS) printf "[\033[0;30m CREDS \033[0m] %s\n" "$2" ;; + Success | SUCCESS) printf "[\033[0;32m DONE \033[0m] %s\n" "$2" ;; + Error | ERROR) printf "[\033[0;31m FAIL \033[0m] %s\n" "$2" ;; + Warning | WARNING) printf "[\033[0;33m WARN \033[0m] %s\n" "$2" ;; + Info | INFO) printf "[\033[0;34m INFO \033[0m] %s\n" "$2" ;; + CREDENTIALS) printf "[\033[0;30m CREDS \033[0m] %s\n" "$2" ;; *) printf "[ ] %s\n" "$2" ;; esac } log_credentials() { message="$1" - file_log "$message" + file_log "CREDENTIALS" "$message" if [ "$SHOW_CREDENTIALS" = true ]; then console_log "CREDENTIALS" "$message" fi } +# TODO: Print the options chosen by user print_logfile_details() { printf "\nLog file location: %s\n" "$LOGFILE_NAME" - printf "To view the log file, use one of these commands:\n" printf " cat %s # View log file\n" "$LOGFILE_NAME" printf " tail -f %s # Follow log in real-time\n\n" "$LOGFILE_NAME" } formatted_execution_duration() { - duration=$1 + end_time=$(date +%s) + duration=$((end_time - START_TIME)) days=$((duration / 86400)) hours=$(((duration % 86400) / 3600)) minutes=$(((duration % 3600) / 60)) @@ -164,7 +167,7 @@ manage_service() { command_status=0 # Try service command if command -v service >/dev/null 2>&1; then - file_log "Using service command for $service_name $action" + file_log "INFO" "Using service command for $service_name $action" case "$action" in enable) # Service command doesn't support enable @@ -174,7 +177,7 @@ manage_service() { output=$(service "$service_name" "$action" 2>&1) command_status=$? if [ -n "$output" ]; then - file_log "service $action output: $output" + file_log "INFO" "service $action output: $output" fi return $command_status ;; @@ -183,18 +186,18 @@ manage_service() { # Try systemctl first (systemd) if command -v systemctl >/dev/null 2>&1; then - file_log "Using systemctl for $service_name $action" + file_log "INFO" "Using systemctl for $service_name $action" output=$(systemctl "$action" "$service_name" 2>&1) command_status=$? if [ -n "$output" ]; then - file_log "systemctl $action output: $output" + file_log "INFO" "systemctl $action output: $output" fi return $command_status fi # Try init.d script if [ -x "/etc/init.d/$service_name" ]; then - file_log "Using init.d script for $service_name $action" + file_log "INFO" "Using init.d script for $service_name $action" case "$action" in enable) # Try to enable using chkconfig if available @@ -202,14 +205,14 @@ manage_service() { output=$(chkconfig "$service_name" on 2>&1) command_status=$? if [ -n "$output" ]; then - file_log "chkconfig output: $output" + file_log "INFO" "chkconfig output: $output" fi return $command_status elif command -v update-rc.d >/dev/null 2>&1; then output=$(update-rc.d "$service_name" defaults 2>&1) command_status=$? if [ -n "$output" ]; then - file_log "update-rc.d output: $output" + file_log "INFO" "update-rc.d output: $output" fi return $command_status fi @@ -218,14 +221,14 @@ manage_service() { output=$("/etc/init.d/$service_name" "$action" 2>&1) command_status=$? if [ -n "$output" ]; then - file_log "init.d $action output: $output" + file_log "INFO" "init.d $action output: $output" fi return $command_status ;; esac fi - file_log "No suitable service manager found for $service_name" + file_log "ERROR" "No suitable service manager found for $service_name" return 1 } @@ -233,7 +236,7 @@ manage_service() { ###################################### OPERATIONS ######################################### reset_root_password() { - file_log "Attempting to reset root password" + file_log "INFO" "Attempting to reset root password" ROOT_PASSWORD=$(head -c 12 /dev/urandom | base64 | tr -dc "[:alnum:]" | head -c 15) # Change root password @@ -241,16 +244,16 @@ reset_root_password() { # shellcheck disable=SC2181 if [ $? -ne 0 ]; then - console_log "Error" "Failed to reset root password" - file_log "Failed to reset root password" + console_log "ERROR" "Failed to reset root password" + file_log "ERROR" "Failed to reset root password" if [ -n "$output" ]; then - file_log "passwd command output: $output" + file_log "ERROR" "passwd command output: $output" fi return 1 fi if [ -n "$output" ]; then - file_log "passwd command output: $output" + file_log "INFO" "passwd command output: $output" fi log_credentials "New root password: $ROOT_PASSWORD" @@ -259,26 +262,26 @@ reset_root_password() { } revert_create_user() { - file_log "Attempting to remove user $USERNAME" + file_log "INFO" "Attempting to remove user $USERNAME" # Check if the user exists before attempting to remove if id "$USERNAME" >/dev/null 2>&1; then # Remove user and its home directory output=$(userdel -r "$USERNAME" 2>&1) if [ -n "$output" ]; then - file_log "userdel command output: $output" + file_log "INFO" "userdel command output: $output" fi # shellcheck disable=SC2181 if [ $? -eq 0 ]; then - file_log "User $USERNAME and home directory removed successfully" + file_log "SUCCESS" "User $USERNAME and home directory removed successfully" return 0 else - file_log "Failed to remove user $USERNAME" + file_log "ERROR" "Failed to remove user $USERNAME" return 1 fi else - file_log "No user $USERNAME found to remove" + file_log "WARNING" "No user $USERNAME found to remove" return 0 fi } @@ -286,40 +289,40 @@ revert_create_user() { create_user() { # Check if username already exists if id "$USERNAME" >/dev/null 2>&1; then - file_log "User $USERNAME already exists" + file_log "WARNING" "User $USERNAME already exists" return 1 fi # Generate a 15-character random password USER_PASSWORD=$(head -c 12 /dev/urandom | base64 | tr -dc "[:alnum:]" | head -c 15) - file_log "Creating user $USERNAME" + file_log "INFO" "Creating user $USERNAME" output=$(printf '%s\n%s\n' "${USER_PASSWORD}" "${USER_PASSWORD}" | adduser "$USERNAME" -q --gecos "First Last,RoomNumber,WorkPhone,HomePhone" 2>&1) # shellcheck disable=SC2181 if [ $? -ne 0 ]; then - file_log "Failed to create user $USERNAME" + file_log "ERROR" "Failed to create user $USERNAME" return 1 fi if [ -n "$output" ]; then - file_log "adduser command output: $output" + file_log "INFO" "adduser command output: $output" fi output=$(usermod -aG sudo "$USERNAME" 2>&1) # shellcheck disable=SC2181 if [ $? -ne 0 ]; then - console_log "Warning" "Failed to add user $USERNAME to sudo group" - file_log "Failed to add user $USERNAME to sudo group" + console_log "WARNING" "Failed to add user $USERNAME to sudo group" + file_log "WARNING" "Failed to add user $USERNAME to sudo group" fi if [ -n "$output" ]; then - file_log "usermod command output: $output" + file_log "INFO" "usermod command output: $output" fi # Log user creation details - file_log "User created: $USERNAME" - console_log "Success" "User created: $USERNAME" + file_log "SUCCESS" "User created: $USERNAME" + console_log "SUCCESS" "User created: $USERNAME" log_credentials "$USERNAME's - Password: $USER_PASSWORD" return 0 @@ -329,12 +332,12 @@ generate_ssh_key() { target_user="$1" console_log "INFO" "Generating SSH key for user: $target_user..." - file_log "Generating SSH key for user: $target_user" + file_log "INFO" "Generating SSH key for user: $target_user" home_dir=$(eval echo "~$target_user") if [ ! -d "$home_dir" ]; then console_log "ERROR" "Home directory not found for user: $target_user" - file_log "Home directory not found for user: $target_user" + file_log "ERROR" "Home directory not found for user: $target_user" return 1 fi @@ -344,7 +347,7 @@ generate_ssh_key() { mkdir -p "$ssh_dir" chown "$target_user:$target_user" "$ssh_dir" chmod 700 "$ssh_dir" - file_log "Created .ssh directory: $ssh_dir" + file_log "INFO" "Created .ssh directory: $ssh_dir" fi # Generate a strong passphrase @@ -354,14 +357,14 @@ generate_ssh_key() { key_path="$ssh_dir/$key_name" # Generate the SSH key - file_log "Generating SSH key for $target_user" + file_log "INFO" "Generating SSH key for $target_user" if ! output=$(su -c "ssh-keygen -o -a 1000 -t ed25519 -f '$key_path' -N '$key_passphrase'" - "$target_user" 2>&1); then console_log "ERROR" "Failed to generate SSH key for user: $target_user" - file_log "Failed to generate SSH key for user: $target_user" - file_log "ssh-keygen output: $output" + file_log "ERROR" "Failed to generate SSH key for user: $target_user" + file_log "ERROR" "ssh-keygen output: $output" return 1 fi - file_log "SSH key generated successfully for user: $target_user" + file_log "INFO" "SSH key generated successfully for user: $target_user" # Set proper permissions for the key chmod 600 "$key_path" @@ -371,22 +374,22 @@ generate_ssh_key() { authorized_keys="$ssh_dir/authorized_keys" if ! cat "$key_path.pub" >>"$authorized_keys"; then console_log "ERROR" "Failed to append public key to authorized_keys" - file_log "Failed to append public key to authorized_keys" + file_log "ERROR" "Failed to append public key to authorized_keys" return 1 fi # Set proper permissions on authorized_keys chmod 400 "$authorized_keys" chown "$target_user:$target_user" "$authorized_keys" - file_log "Added public key to: $authorized_keys" + file_log "INFO" "Added public key to: $authorized_keys" # Log the key details - file_log "SSH key generated successfully for user: $target_user" - console_log "Success" "SSH key generated successfully for user: $target_user" - file_log "Key path: $key_path" + file_log "INFO" "SSH key generated successfully for user: $target_user" + console_log "SUCCESS" "SSH key generated successfully for user: $target_user" + file_log "SUCCESS" "Key path: $key_path" - console_log "Info" "Key path: $key_path" - console_log "Info" "Authorized keys path: $authorized_keys" + console_log "INFO" "Key path: $key_path" + console_log "INFO" "Authorized keys path: $authorized_keys" log_credentials "SSH key details for $target_user:" log_credentials "SSH Key passphrase: $key_passphrase" @@ -405,23 +408,23 @@ update_ssh_setting() { # Comment out existing setting if found output=$(sed -i "s/^${setting}/#${setting}/" "$SSHD_CONFIG" 2>&1) if [ -n "$output" ]; then - file_log "sed command output: $output" + file_log "INFO" "sed command output: $output" fi # Add new setting at the end of file echo "${setting} ${value}" >>"$SSHD_CONFIG" - file_log "Updated SSH setting: ${setting} ${value}" + file_log "INFO" "Updated SSH setting: ${setting} ${value}" } harden_ssh_config() { console_log "INFO" "Configuring SSH hardening settings..." - file_log "Starting SSH configuration hardening" + file_log "INFO" "Starting SSH configuration hardening..." SSHD_CONFIG="/etc/ssh/sshd_config" if [ ! -f "$SSHD_CONFIG" ]; then console_log "ERROR" "SSH config file not found at $SSHD_CONFIG" - file_log "SSH config file not found at $SSHD_CONFIG" + file_log "ERROR" "SSH config file not found at $SSHD_CONFIG" return 1 fi @@ -429,9 +432,9 @@ harden_ssh_config() { BACKUP_FILE="${SSHD_CONFIG}.bak.${TIMESTAMP}" output=$(cp "$SSHD_CONFIG" "$BACKUP_FILE" 2>&1) if [ -n "$output" ]; then - file_log "cp command output: $output" + file_log "INFO" "cp command output: $output" fi - file_log "Created backup of sshd_config at: $BACKUP_FILE" + file_log "INFO" "Created backup of sshd_config at: $BACKUP_FILE" # Update SSH settings update_ssh_setting "PermitRootLogin" "no" @@ -440,43 +443,43 @@ harden_ssh_config() { update_ssh_setting "AuthorizedKeysFile" ".ssh/authorized_keys" console_log "SUCCESS" "SSH configuration hardening completed" - file_log "SSH configuration hardening completed" + file_log "SUCCESS" "SSH configuration hardening completed" # Restart SSH service if manage_service sshd restart || manage_service ssh restart; then console_log "SUCCESS" "SSH service restarted successfully" - file_log "SSH service restarted successfully" + file_log "SUCCESS" "SSH service restarted successfully" return 0 fi console_log "ERROR" "Failed to restart SSH service" - file_log "Failed to restart SSH service" + file_log "ERROR" "Failed to restart SSH service" # Revert to backup and try restarting again console_log "INFO" "Reverting to backup configuration..." - file_log "Reverting to backup configuration from: $BACKUP_FILE" + file_log "INFO" "Reverting to backup configuration from: $BACKUP_FILE" if ! cp "$BACKUP_FILE" "$SSHD_CONFIG"; then console_log "ERROR" "Failed to restore SSH config backup" - file_log "Failed to restore SSH config backup" + file_log "ERROR" "Failed to restore SSH config backup" exit 1 fi # Try restarting SSH with original config if manage_service sshd restart || manage_service ssh restart; then console_log "SUCCESS" "SSH service restarted successfully with original configuration" - file_log "SSH service restarted successfully with original configuration" + file_log "SUCCESS" "SSH service restarted successfully with original configuration" exit 1 fi console_log "ERROR" "Failed to restart SSH service even with original configuration" - file_log "Failed to restart SSH service even with original configuration" + file_log "ERROR" "Failed to restart SSH service even with original configuration" exit 1 } install_package() { if [ $# -eq 0 ]; then - file_log "No package specified for installation" + file_log "ERROR" "No package specified for installation" return 1 fi @@ -485,87 +488,90 @@ install_package() { # Detect the package manager and OS if [ -f /etc/debian_version ] || [ -f /etc/ubuntu_version ]; then # Debian/Ubuntu - file_log "Installing $PACKAGE_NAME using apt..." + file_log "INFO" "Installing $PACKAGE_NAME using apt..." + # Don't let timezone setting stop the installation: make UTC the system timezone + ln -fs /usr/share/zoneinfo/UTC /etc/localtime + file_log "WARNING" "Set UTC as system timezone. Change this after the script completes." # shellcheck disable=SC2086 - output=$(DEBIAN_FRONTEND=noninteractive apt-get update && apt-get install -y --no-install-recommends $PACKAGE_NAME 2>&1) + output=$(DEBIAN_FRONTEND=noninteractive apt-get update -y && apt-get install -y --no-install-recommends $PACKAGE_NAME 2>&1) ret=$? elif [ -f /etc/fedora-release ]; then # Fedora - file_log "Installing $PACKAGE_NAME using dnf..." + file_log "INFO" "Installing $PACKAGE_NAME using dnf..." # shellcheck disable=SC2086 output=$(dnf makecache && dnf install -y $PACKAGE_NAME 2>&1) ret=$? elif [ -f /etc/freebsd-update.conf ]; then # FreeBSD - file_log "Installing $PACKAGE_NAME using pkg..." + file_log "INFO" "Installing $PACKAGE_NAME using pkg..." # shellcheck disable=SC2086 output=$(pkg update && pkg install -y $PACKAGE_NAME 2>&1) ret=$? else - file_log "Unsupported operating system" + file_log "ERROR" "Unsupported operating system" return 1 fi # Log the output if any if [ -n "$output" ]; then - file_log "Package installation output: $output" + file_log "INFO" "Package installation output: $output" fi # Handle the return status if [ $ret -ne 0 ]; then - file_log "Failed to install package: $PACKAGE_NAME" + file_log "ERROR" "Failed to install package: $PACKAGE_NAME" return 1 fi - file_log "Successfully installed package: $PACKAGE_NAME" + file_log "SUCCESS" "Successfully installed package: $PACKAGE_NAME" return 0 } configure_ufw() { console_log "INFO" "Starting UFW configuration..." - file_log "Starting UFW configuration" + file_log "INFO" "Starting UFW configuration" # Check if UFW is installed if ! command -v ufw >/dev/null 2>&1; then - file_log "UFW is not installed" + file_log "ERROR" "UFW is not installed" return 1 fi output=$(ufw allow ssh 2>&1) if [ -n "$output" ]; then - file_log "ufw allow ssh output: $output" + file_log "INFO" "ufw allow ssh output: $output" fi output=$(ufw allow http 2>&1) if [ -n "$output" ]; then - file_log "ufw allow http output: $output" + file_log "INFO" "ufw allow http output: $output" fi output=$(ufw allow https 2>&1) if [ -n "$output" ]; then - file_log "ufw allow https output: $output" + file_log "INFO" "ufw allow https output: $output" fi # Enable UFW output=$(echo "y" | ufw enable 2>&1) if [ -n "$output" ]; then - file_log "ufw enable output: $output" + file_log "INFO" "ufw enable output: $output" fi # Verify UFW is active output=$(ufw status 2>&1) if [ -n "$output" ]; then - file_log "ufw status output: $output" + file_log "INFO" "ufw status output: $output" fi if ! echo "$output" | grep -q "Status: active"; then console_log "ERROR" "UFW is not active after enabling" - file_log "UFW is not active after enabling" + file_log "ERROR" "UFW is not active after enabling" return 1 fi - console_log "Success" "UFW configuration completed successfully" - file_log "UFW configuration completed successfully" + console_log "SUCCESS" "UFW configuration completed successfully" + file_log "SUCCESS" "UFW configuration completed successfully" return 0 } @@ -577,22 +583,23 @@ update_fail2ban_jail_local_file() { # [DEFAULT] section ends right before "# JAILS" range_start="^\[DEFAULT\]$" range_end="^# JAILS$" + file=$JAIL_LOCAL_FILE # When the setting exists & it's NOT commented out -> comment it and add the new setting on next line - if sed -n "/${range_start}/,/${range_end}/p" "$JAIL_LOCAL" | grep -q "^${search_term}[[:blank:]]*="; then - sed -ri "/${range_start}/,/${range_end}/ s/^(${search_term}[[:blank:]]*=.*)/#\1/" "$JAIL_LOCAL" - sed -ri "/${range_start}/,/${range_end}/ s/^#${search_term}[[:blank:]]*=.*/&\n${search_term} = ${new_value}/" "$JAIL_LOCAL" + if sed -n "/${range_start}/,/${range_end}/p" "$file" | grep -q "^${search_term}[[:blank:]]*="; then + sed -ri "/${range_start}/,/${range_end}/ s/^(${search_term}[[:blank:]]*=.*)/#\1/" "$file" + sed -ri "/${range_start}/,/${range_end}/ s/^#${search_term}[[:blank:]]*=.*/&\n${search_term} = ${new_value}/" "$file" else # If the setting is commented out or it doesn't exist -> add it after the commented line or at the end of the section - sed -ri "/${range_start}/,/${range_end}/ s/^#${search_term}[[:blank:]]*=.*/&\n${search_term} = ${new_value}/" "$JAIL_LOCAL" + sed -ri "/${range_start}/,/${range_end}/ s/^#${search_term}[[:blank:]]*=.*/&\n${search_term} = ${new_value}/" "$file" fi } configure_fail2ban() { console_log "INFO" "Starting Fail2ban configuration..." - file_log "Starting Fail2ban configuration" + file_log "INFO" "Starting Fail2ban configuration" if ! command -v fail2ban-client >/dev/null 2>&1; then - file_log "Fail2ban is not installed" + file_log "ERROR" "Fail2ban is not installed" return 1 fi @@ -604,28 +611,28 @@ configure_fail2ban() { if [ -f "$JAIL_LOCAL_FILE" ]; then JAIL_LOCAL_BACKUP_FILE="${JAIL_LOCAL_FILE}.bak.${TIMESTAMP}" cp "$JAIL_LOCAL_FILE" "$JAIL_LOCAL_BACKUP_FILE" - file_log "Created backup of existing jail.local at $JAIL_LOCAL_BACKUP_FILE" + file_log "INFO" "Created backup of existing jail.local at $JAIL_LOCAL_BACKUP_FILE" else # Copy jail.conf to jail.local if jail.local doesn't exist if [ -f "$DEFAULT_JAIL_CONF_FILE" ]; then cp "$DEFAULT_JAIL_CONF_FILE" "$JAIL_LOCAL_FILE" - file_log "Created jail.local from jail.conf" + file_log "INFO" "Created jail.local from jail.conf" else console_log "ERROR" "Neither jail.conf nor jail.local exists" - file_log "Neither jail.conf nor jail.local exists" + file_log "ERROR" "Neither jail.conf nor jail.local exists" return 1 fi fi # Fetch public IP using ipinfo.io/ip - file_log "Attempting to get server's public IP" + file_log "INFO" "Attempting to get server's public IP" output=$(curl -s -4 ifconfig.me 2>&1 || curl -s -4 icanhazip.com 2>&1 || curl -s -4 ipinfo.io/ip 2>&1) if [ -z "$output" ]; then console_log "ERROR" "Could not determine server's public IP" - file_log "Could not determine server's public IP" + file_log "ERROR" "Could not determine server's public IP" PUBLIC_IP="" else PUBLIC_IP="$output" - file_log "Server public IP: $PUBLIC_IP" + file_log "INFO" "Server public IP: $PUBLIC_IP" fi # Update default settings in jail.local @@ -634,7 +641,7 @@ configure_fail2ban() { update_fail2ban_jail_local_file "ignoreip" "127.0.0.1\/8 ::1 $PUBLIC_IP" # Enable jails and more settings for them in /etc/fail2ban/jail.d/custom-enabled.conf - file_log "Enabling jails in $CUSTOM_JAILS_FILE" + file_log "INFO" "Enabling jails in $CUSTOM_JAILS_FILE" cat <$CUSTOM_JAILS_FILE [sshd] enabled = true @@ -657,48 +664,47 @@ maxretry = 50 FAIL2BAN if ! manage_service fail2ban restart; then - # If restarting service fails, try reverting all configurations & restart again console_log "ERROR" "Failed to restart fail2ban service" - file_log "Failed to restart fail2ban service" + file_log "ERROR" "Failed to restart fail2ban service" # Revert jail.local to backup if it exists if [ -f "$JAIL_LOCAL_BACKUP_FILE" ]; then console_log "INFO" "Reverting jail.local to backup..." - file_log "Reverting jail.local to backup from: $JAIL_LOCAL_BACKUP_FILE" + file_log "INFO" "Reverting jail.local to backup from: $JAIL_LOCAL_BACKUP_FILE" if ! cp "$JAIL_LOCAL_BACKUP_FILE" "$JAIL_LOCAL_FILE"; then console_log "ERROR" "Failed to restore jail.local backup" - file_log "Failed to restore jail.local backup" + file_log "ERROR" "Failed to restore jail.local backup" exit 1 fi else # If no backup exists (i.e, jail.local was created from jail.conf) -> remove jail.local console_log "INFO" "Removing newly created jail.local..." - file_log "Removing newly created jail.local" + file_log "INFO" "Removing newly created jail.local" rm -f "$JAIL_LOCAL_FILE" fi # Remove the custom enabled configuration if [ -f "$CUSTOM_JAILS_FILE" ]; then console_log "INFO" "Removing custom jail configuration..." - file_log "Removing custom jail configuration: $CUSTOM_JAILS_FILE" + file_log "INFO" "Removing custom jail configuration: $CUSTOM_JAILS_FILE" rm -f "$CUSTOM_JAILS_FILE" fi # Try restarting fail2ban with original configuration if ! manage_service fail2ban restart; then console_log "ERROR" "Failed to restart fail2ban service even with original configuration" - file_log "Failed to restart fail2ban service even with original configuration" + file_log "ERROR" "Failed to restart fail2ban service even with original configuration" exit 1 fi console_log "INFO" "Fail2ban restarted with original configuration" - file_log "Fail2ban restarted with original configuration" + file_log "INFO" "Fail2ban restarted with original configuration" exit 1 fi - console_log "Success" "Fail2ban configuration completed successfully" - file_log "Fail2ban configuration completed successfully" + console_log "SUCCESS" "Fail2ban configuration completed successfully" + file_log "SUCCESS" "Fail2ban configuration completed successfully" return 0 } @@ -706,11 +712,15 @@ main() { parse_args "$@" create_logfile + clear print_logfile_details + echo "Press Enter to continue..." + # shellcheck disable=SC2162,SC2034 + read dummy # Log script start - console_log "INFO" "Starting $SCRIPT_NAME v$SCRIPT_VERSION" - file_log "Starting $SCRIPT_NAME v$SCRIPT_VERSION" + console_log "INFO" "Starting $SCRIPT_NAME v$SCRIPT_VERSION..." + file_log "INFO" "Starting $SCRIPT_NAME v$SCRIPT_VERSION..." # Step 1: Reset root password if requested if [ "$RESET_ROOT" = true ]; then @@ -749,47 +759,44 @@ main() { fi # Step 5: Install required packages - console_log "INFO" "Installing required packages" - file_log "Installing required packages" + console_log "INFO" "Installing required packages..." + file_log "INFO" "Installing required packages..." if ! install_package "curl ufw fail2ban"; then console_log "ERROR" "Failed to install required packages" print_logfile_details return 1 # Abort on error fi - console_log "Success" "Successfully installed all required packages" - file_log "Successfully installed all required packages" + console_log "SUCCESS" "Successfully installed all required packages" # Step 6: Configure UFW - console_log "INFO" "Configuring UFW" - file_log "Configuring UFW" + console_log "INFO" "Configuring UFW..." + file_log "INFO" "Configuring UFW..." if ! configure_ufw; then console_log "ERROR" "Failed to configure UFW" print_logfile_details return 1 # Abort on error fi - console_log "Success" "Successfully configured UFW" - file_log "Successfully configured UFW" + console_log "SUCCESS" "Successfully configured UFW" + file_log "SUCCESS" "Successfully configured UFW" # Step 7: Configure Fail2ban - console_log "INFO" "Configuring Fail2ban" - file_log "Configuring Fail2ban" + console_log "INFO" "Configuring Fail2ban..." + file_log "INFO" "Configuring Fail2ban..." if ! configure_fail2ban; then console_log "ERROR" "Failed to configure Fail2ban" print_logfile_details return 1 # Abort on error fi - console_log "Success" "Successfully configured Fail2ban" - file_log "Successfully configured Fail2ban" + console_log "SUCCESS" "Successfully configured Fail2ban" + file_log "SUCCESS" "Successfully configured Fail2ban" console_log "SUCCESS" "Script completed successfully" - file_log "Script completed successfully" + file_log "SUCCESS" "Script completed successfully" # Calculate and show execution time - END_TIME=$(date +%s) - DURATION=$((END_TIME - START_TIME)) - FORMATTED_DURATION=$(formatted_execution_duration $DURATION) + FORMATTED_DURATION=$(formatted_execution_duration) console_log "INFO" "Total execution time: $FORMATTED_DURATION" - file_log "Total execution time: $FORMATTED_DURATION" + file_log "INFO" "Total execution time: $FORMATTED_DURATION" print_logfile_details return 0