From 2b3aaf08cb94145e78ebc9cecaeec0ca29b4944d Mon Sep 17 00:00:00 2001 From: "Hunter T." Date: Thu, 15 Aug 2024 13:41:34 -0700 Subject: [PATCH 01/12] Refer to CHANGELOG.md --- auditing/Lynis Installer/lynis-installer | 63 +++++++++++------------- 1 file changed, 29 insertions(+), 34 deletions(-) diff --git a/auditing/Lynis Installer/lynis-installer b/auditing/Lynis Installer/lynis-installer index f599ff3..83b7dc7 100755 --- a/auditing/Lynis Installer/lynis-installer +++ b/auditing/Lynis Installer/lynis-installer @@ -1,55 +1,50 @@ #!/bin/bash # -# This script downloads a security auditing tool called Lynis, designed to scan a system -# and identify security issues, and provides recommendations on how to better secure it. -# Lynis, unless an error is encountered, will always be downloaded to the user's root -# directory (/home/USERNAME/). +# Name: lynis-installer.bash # -# Version: v1.0.6 +# Description: +# This script downloads a security auditing tool called Lynis, designed to scan a +# system and identify security issues, and provides recommendations on how to better +# secure it. Lynis, unless an error is encountered, will always be downloaded to the +# user's root directory (/home/USERNAME/). +# +# Version: v1.0.7 # License: MIT License # Copyright (c) 2020-2024 Hunter T. (StrangeRanger) # ######################################################################################## -####[ Script Wide Variables ]########################################################### - - -green="$(printf '\033[0;32m')" -cyan="$(printf '\033[0;36m')" -red="$(printf '\033[1;31m')" -nc="$(printf '\033[0m')" +C_YELLOW="$(printf '\033[1;33m')" +C_GREEN="$(printf '\033[0;32m')" +C_CYAN="$(printf '\033[0;36m')" +C_RED="$(printf '\033[1;31m')" +C_NC="$(printf '\033[0m')" +C_ERROR="${C_RED}ERROR:${C_NC} " +C_WARNING="${C_YELLOW}WARNING:${C_NC} " -####[ Prepping ]######################################################################## +read -rp "We will now download lynis. Press [Enter] to continue." -## Check if the script was executed with root privilege. -if [[ $EUID != 0 ]]; then - echo "${red}Please run this script as or with root privilege${nc}" >&2 +[[ -d "$HOME/lynis" ]] && { + echo "${C_WARNING}Lynis is already downloaded to your system" >&2 + echo "Current location: '$HOME/lynis'" echo -e "\nExiting..." - exit 1 -fi - - -####[ Main ]############################################################################ - - -read -rp "We will now download lynis. Press [Enter] to continue." + exit 0 +} -echo "Changing working directory to '/home/$SUDO_USER'..." -cd /home/"$SUDO_USER" || { - echo "${red}Failed to change working directory to '/home/$SUDO_USER'" - echo "${cyan}Lynis will download to '$PWD'${nc}" +echo "Changing working directory to '$HOME'..." +cd "$HOME" || { + echo "${C_ERROR}Failed to change working directory to '$HOME'" >&2 + echo "${C_CYAN}Lynis will download to '$PWD'${C_NC}" } echo "Downloading lynis..." git clone https://github.com/CISOfy/lynis || { - echo "${red}Failed to download lynis${nc}" >&2 + echo "${C_ERROR}Failed to download lynis" >&2 echo -e "\nExiting..." exit 1 } -echo "Changing ownership of lynis to root:root..." -chown -R root:root lynis -echo -e "\n${green}Lynis has been downloaded to your system" -echo -e "${cyan}To perform a system scan with lynis, execute the following command in" \ - "the lynis root directory: sudo ./lynis audit system${nc}" +echo -e "\n${C_GREEN}Lynis has been downloaded to your system" +echo -e "${C_CYAN}To perform a system scan with lynis, execute the following command" \ + "in the lynis root directory: sudo ./lynis audit system${C_NC}" From 820f42fe99195c778b7327b87267cf22824468b2 Mon Sep 17 00:00:00 2001 From: "Hunter T." Date: Thu, 15 Aug 2024 13:41:58 -0700 Subject: [PATCH 02/12] Update CHANGELOG.md --- auditing/Lynis Installer/CHANGELOG.md | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/auditing/Lynis Installer/CHANGELOG.md b/auditing/Lynis Installer/CHANGELOG.md index 31356c4..4c40955 100644 --- a/auditing/Lynis Installer/CHANGELOG.md +++ b/auditing/Lynis Installer/CHANGELOG.md @@ -4,6 +4,14 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). +## v1.0.7 - 2024-08-15 + +### Changed + +- No longer requires root permission to run the script. +- Won't download lynis if is already present on the system. +- Improved syntax of the script. + ## v1.0.6 - 2024-04-13 ### Changed From ed72c81ab84cb865ee538becf829bc7bb1b59c5f Mon Sep 17 00:00:00 2001 From: "Hunter T." Date: Thu, 15 Aug 2024 13:43:37 -0700 Subject: [PATCH 03/12] Rename script --- .../Lynis Installer/{lynis-installer => lynis-installer.bash} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename auditing/Lynis Installer/{lynis-installer => lynis-installer.bash} (100%) diff --git a/auditing/Lynis Installer/lynis-installer b/auditing/Lynis Installer/lynis-installer.bash similarity index 100% rename from auditing/Lynis Installer/lynis-installer rename to auditing/Lynis Installer/lynis-installer.bash From 6831e666a49bad31949a92164171e0b6fcdee122 Mon Sep 17 00:00:00 2001 From: "Hunter T." Date: Thu, 15 Aug 2024 13:54:28 -0700 Subject: [PATCH 04/12] Refer to CHANGELOG.md --- hardening/Root Locker/root-locker | 35 ++++++++++++++----------------- 1 file changed, 16 insertions(+), 19 deletions(-) diff --git a/hardening/Root Locker/root-locker b/hardening/Root Locker/root-locker index 6c431ca..31d1850 100755 --- a/hardening/Root Locker/root-locker +++ b/hardening/Root Locker/root-locker @@ -1,43 +1,40 @@ #!/bin/bash # -# This script locks and removes the root account's password (if one is set). This -# prevents users from successfully logging into the root account via su. Note that it -# doesn't prevent users from becoming root via methods such as sudo su. +# Name: root-locker.bash # -# Version: v1.0.6 +# Description: +# This script locks the root account, preventing users from direct logins as root. +# +# Note: +# Locking the root account doesn't prevent users from using something like `sudo su` +# to gain root access. +# +# Version: v1.0.7 # License: MIT License # Copyright (c) 2020-2024 Hunter T. (StrangeRanger) # ######################################################################################## -####[ Script Wide Variables ]########################################################### - - -green="$(printf '\033[0;32m')" -red="$(printf '\033[1;31m')" -nc="$(printf '\033[0m')" - -####[ Prepping ]######################################################################## +C_GREEN="$(printf '\033[0;32m')" +C_RED="$(printf '\033[1;31m')" +C_NC="$(printf '\033[0m')" ## Check if this script was executed with root privilege. if [[ $EUID != 0 ]]; then - echo "${red}Please run this script as or with root privilege${nc}" >&2 + echo "${C_RED}Please run this script as or with root privilege${C_NC}" >&2 echo -e "\nExiting..." exit 1 fi -####[ Main ]############################################################################ - - read -rp "We will now disable the root account. Press [Enter] to continue." echo "Disabling root account..." -passwd -dl root || { - echo -e "\n${red}Failed to lock the root account${nc}" +usermod -L root || { + echo -e "\n${C_RED}Failed to lock the root account${C_NC}" >&2 echo -e "\nExiting..." exit 1 } -echo -e "\n${green}The root account has been locked${nc}" +echo -e "\n${C_GREEN}The root account has been locked${C_NC}" From f055c9ca2ee98f6b49a569713b4924b8369e1e30 Mon Sep 17 00:00:00 2001 From: "Hunter T." Date: Thu, 15 Aug 2024 13:54:49 -0700 Subject: [PATCH 05/12] Rename script --- hardening/Root Locker/{root-locker => root-locker.bash} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename hardening/Root Locker/{root-locker => root-locker.bash} (100%) diff --git a/hardening/Root Locker/root-locker b/hardening/Root Locker/root-locker.bash similarity index 100% rename from hardening/Root Locker/root-locker rename to hardening/Root Locker/root-locker.bash From 67d750acdca3c973e02405055ccaa08953f7235d Mon Sep 17 00:00:00 2001 From: "Hunter T." Date: Thu, 15 Aug 2024 13:55:46 -0700 Subject: [PATCH 06/12] Update CHANGELOG.md --- hardening/Root Locker/CHANGELOG.md | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/hardening/Root Locker/CHANGELOG.md b/hardening/Root Locker/CHANGELOG.md index e149588..0f2ab58 100644 --- a/hardening/Root Locker/CHANGELOG.md +++ b/hardening/Root Locker/CHANGELOG.md @@ -4,6 +4,15 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). +## v1.0.7 - 2024-08-15 + +### Changed + +- Improved error handling. +- Modify syntax and documentation. +- Utilizes `usermod -L` to lock the root account. +- Rename script to `root-locker.bash`. + ## v1.0.6 - 2024-04-13 ### Changed From 74ebd337b466b82bdf061c2c36213b2458058af0 Mon Sep 17 00:00:00 2001 From: "Hunter T." Date: Thu, 15 Aug 2024 13:56:29 -0700 Subject: [PATCH 07/12] Update CHANGELOG.md --- auditing/Lynis Installer/CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/auditing/Lynis Installer/CHANGELOG.md b/auditing/Lynis Installer/CHANGELOG.md index 4c40955..22aaed8 100644 --- a/auditing/Lynis Installer/CHANGELOG.md +++ b/auditing/Lynis Installer/CHANGELOG.md @@ -11,6 +11,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), - No longer requires root permission to run the script. - Won't download lynis if is already present on the system. - Improved syntax of the script. +- Rename script to `lynis-installer.bash`. ## v1.0.6 - 2024-04-13 From 9c0ab4c745f8750d7f44be499314eca75209e343 Mon Sep 17 00:00:00 2001 From: "Hunter T." Date: Thu, 15 Aug 2024 13:59:33 -0700 Subject: [PATCH 08/12] Modify wording of error message --- hardening/Root Locker/root-locker.bash | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/hardening/Root Locker/root-locker.bash b/hardening/Root Locker/root-locker.bash index 31d1850..bb68914 100755 --- a/hardening/Root Locker/root-locker.bash +++ b/hardening/Root Locker/root-locker.bash @@ -32,7 +32,7 @@ read -rp "We will now disable the root account. Press [Enter] to continue." echo "Disabling root account..." usermod -L root || { - echo -e "\n${C_RED}Failed to lock the root account${C_NC}" >&2 + echo -e "${C_RED}ERROR:${C_NC} Failed to lock the root account" >&2 echo -e "\nExiting..." exit 1 } From 8ba653c9fe3104ed3fab65a1c96df245618d4eb6 Mon Sep 17 00:00:00 2001 From: "Hunter T." Date: Thu, 15 Aug 2024 18:00:41 -0700 Subject: [PATCH 09/12] Refer to CHANGELOG.md --- hardening/SSHD Hardening/sshd | 357 ++++++++++++++++------------------ 1 file changed, 164 insertions(+), 193 deletions(-) diff --git a/hardening/SSHD Hardening/sshd b/hardening/SSHD Hardening/sshd index f39e723..6d557e9 100755 --- a/hardening/SSHD Hardening/sshd +++ b/hardening/SSHD Hardening/sshd @@ -1,243 +1,214 @@ #!/bin/bash # -# This script hardens the sshd-server, by modifying it's configuration file -# (sshd_config). +# Name: harden-sshd.bash # -# Note: This configures sshd_config to the recommendations of the security auditing tool -# knonw as Lynis (https://github.com/CISOfy/lynis). +# Description: +# This script hardens the sshd-server, by modifying it's configuration file +# (sshd_config). # -# Version: v1.1.2 +# Note: +# This configures sshd_config to the recommendations of the security auditing tool +# knonw as Lynis (https://github.com/CISOfy/lynis). +# +# Version: v2.0.0 # License: MIT License # Copyright (c) 2020-2024 Hunter T. (StrangeRanger) # ######################################################################################## -####[ Script Wide Variables ]########################################################### - - -config_file_bak="/etc/ssh/sshd_config.bak" -config_file="/etc/ssh/sshd_config" -green="$(printf '\033[0;32m')" -cyan="$(printf '\033[0;36m')" -red="$(printf '\033[1;31m')" -nc="$(printf '\033[0m')" +####[ Global Variables ]################################################################ + + +readonly C_CONFIG_FILE_BAK="/etc/ssh/sshd_config.bak" +readonly C_CONFIG_FILE="/etc/ssh/sshd_config" + +## Used to colorize output. +C_YELLOW="$(printf '\033[1;33m')" +C_GREEN="$(printf '\033[0;32m')" +C_BLUE="$(printf '\033[0;34m')" +C_CYAN="$(printf '\033[0;36m')" +C_RED="$(printf '\033[1;31m')" +C_NC="$(printf '\033[0m')" +readonly C_GREEN C_CYAN C_RED C_NC + +## Short-hand colorized messages. +C_SUCCESS="${C_GREEN}==>${C_NC} " +C_WARNING="${C_YELLOW}==>${C_NC} " +C_ERROR="${C_RED}ERROR:${C_NC} " +C_INFO="${C_BLUE}==>${C_NC} " +C_NOTE="${C_CYAN}==>${C_NC} " + +# Associative array containing the configuration settings for sshd_config. +declare -A C_SSHD_CONFIG=( + ["LogLevel"]="VERBOSE" + ["LogLevelRegex"]='^#?LogLevel\s+.*$' + ["LoginGraceTime"]="30" + ["LoginGraceTimeRegex"]='^#?LoginGraceTime\s+.*$' + ["PermitRootLogin"]="no" + ["PermitRootLoginRegex"]='^#?PermitRootLogin\s+.*$' + ["MaxAuthTries"]="3" + ["MaxAuthTriesRegex"]='^#?MaxAuthTries\s+.*$' + ["MaxSessions"]="2" + ["MaxSessionsRegex"]='^#?MaxSessions\s+.*$' + ["PubkeyAuthentication"]="yes" + ["PubkeyAuthenticationRegex"]='^#?PubkeyAuthentication\s+.*$' + ["PermitEmptyPasswords"]="no" + ["PermitEmptyPasswordsRegex"]='^#?PermitEmptyPasswords\s+.*$' + ["ChallengeResponseAuthentication"]="no" + ["ChallengeResponseAuthenticationRegex"]='^#?ChallengeResponseAuthentication\s+.*$' + ["KbdInteractiveAuthentication"]="no" + ["KbdInteractiveAuthenticationRegex"]='^#?KbdInteractiveAuthentication\s+.*$' + ["UsePAM"]="yes" + ["UsePAMRegex"]='^#?UsePAM\s+.*$' + ["AllowAgentForwarding"]="no" + ["AllowAgentForwardingRegex"]='^#?AllowAgentForwarding\s+.*$' + ["AllowTcpForwarding"]="no" + ["AllowTcpForwardingRegex"]='^#?AllowTcpForwarding\s+.*$' + ["X11Forwarding"]="no" + ["X11ForwardingRegex"]='^#?X11Forwarding\s+.*$' + ["PrintMotd"]="no" + ["PrintMotdRegex"]='^#?PrintMotd\s+.*$' + ["TCPKeepAlive"]="no" + ["TCPKeepAliveRegex"]='^#?TCPKeepAlive\s+.*$' + ["Compression"]="no" + ["CompressionRegex"]='^#?Compression\s+.*$' + ["ClientAliveInterval"]="300" + ["ClientAliveIntervalRegex"]='^#?ClientAliveInterval\s+.*$' + ["ClientAliveCountMax"]="2" + ["ClientAliveCountMaxRegex"]='^#?ClientAliveCountMax\s+.*$' +) +readonly C_SSHD_CONFIG ####[ Functions ]####################################################################### #### -# Cleanly exit the script. +# Description: +# Cleanly exit the script. # # Arguments: # - $1: exit_code (Required) -# - Description: The exit code to exit the script with. -#### -clean_up() { +# - The exit code to exit the script with. +clean_exit() { local exit_code="$1" - echo -e "\nExiting..." + case "$exit_code" in + 0) exit 0 ;; + 1) echo "" ;; + 130) echo -e "\n${C_WARNING}User interrupt detected" ;; + *) echo -e "\n${C_RED}==>${C_NC} Exiting with code: $exit_code" ;; + esac + + echo -e "${C_INFO}Exiting..." exit "$exit_code" } +####[ Trapping Logic ]################################################################## + + +# Catch some of the most common signals. +trap 'clean_exit $?' EXIT INT TERM HUP QUIT ERR + + ####[ Prepping ]######################################################################## ## Check if the script was executed with root privilege. if [[ $EUID != 0 ]]; then - echo "${red}Please run this script as or with root privilege${nc}" >&2 - clean_up 1 + echo "${C_ERROR}This script requires root privilege" >&2 + exit 1 fi ## Confirm that 'sshd_config' exists. -if [[ ! -f $config_file ]]; then - echo "${red}'sshd_config' doesn't exist" >&2 - echo "${cyan}openssh-server may not be installed${nc}" - clean_up 1 +if [[ ! -f $C_CONFIG_FILE ]]; then + echo "${C_WARNING}'sshd_config' doesn't exist" >&2 + echo "${C_NOTE}openssh-server may not be installed" + exit 1 fi ####[ Main ]############################################################################ -read -rp "We will now harden sshd. Press [Enter] to continue." +read -rp "${C_NOTE}We will now harden sshd. Press [Enter] to continue." -if [[ -f $config_file_bak ]]; then - printf "A backup of 'sshd_config' already exists. " +### +### [ Backup 'sshd_config' ] +### + +if [[ -f $C_CONFIG_FILE_BAK ]]; then + printf "%sA backup of 'sshd_config' already exists. " "$C_NOTE" read -rp "Do you want to overwrite it? [y/N] " choice + choice="${choice,,}" - choice=$(echo "$choice" | tr '[:upper:]' '[:lower:]') case "$choice" in - y|yes) - echo "Overwriting backup of 'sshd_config'..." - # shellcheck disable=SC2015 - rm $config_file_bak && cp $config_file $config_file_bak || { - echo "${red}Failed to back up sshd_config" >&2 - echo "${cyan}Please create a backup of the original 'sshd_config'" \ - "before continuing${nc}" - clean_up 1 + y*) + echo "${C_INFO}Overwriting backup of 'sshd_config'..." + { + rm $C_CONFIG_FILE_BAK && cp $C_CONFIG_FILE $C_CONFIG_FILE_BAK + } || { + echo "${C_ERROR}Failed to overwrite backup of 'sshd_config'" >&2 + exit 1 } ;; + *) + echo "${C_INFO}Skipping backup of 'sshd_config'..." + ;; esac + + unset choice else - echo "Backing up 'sshd_config'..." - cp $config_file $config_file_bak || { - echo "${red}Failed to back up sshd_config" >&2 - echo "${cyan}Please create a backup of the original 'sshd_config' before" \ - "continuing${nc}" - clean_up 1 + echo "${C_INFO}Backing up 'sshd_config'..." + cp $C_CONFIG_FILE $C_CONFIG_FILE_BAK || { + echo "${C_ERROR}Failed to back up sshd_config" >&2 + echo "${C_NOTE}Please create a backup of the original 'sshd_config' before" \ + "continuing" + exit 1 } fi -if grep -Eq '^LogLevel VERBOSE$' "$config_file"; then - echo "LogLevel already set to 'VERBOSE'" -elif grep -Eq '^#?LogLevel(.*)?$' "$config_file"; then - echo "Setting 'LogLevel VERBOSE'..." - sed -Ei 's/^#?LogLevel(.*)?$/LogLevel VERBOSE/gm' "$config_file" \ - || echo "${red}Failed to set 'LogLevel VERBOSE'${nc}" -fi - -if grep -Eq '^LoginGraceTime 30$' "$config_file"; then - echo "LoginGraceTime already set to '30'" -elif grep -Eq '^#?LoginGraceTime(.*)?$' "$config_file"; then - echo "Setting 'LoginGraceTime 30'..." - sed -Ei 's/^#?LoginGraceTime(.*)?$/LoginGraceTime 30/gm' "$config_file" \ - || echo "${red}Failed to set 'LoginGraceTime 30'${nc}" -fi - -if grep -Eq '^PermitRootLogin no$' "$config_file"; then - echo "PermitRootLogin already set to 'no'" -elif grep -Eq '^#?PermitRootLogin(.*)?$' "$config_file"; then - echo "Setting 'PermitRootLogin no'..." - sed -Ei 's/^#?PermitRootLogin(.*)?$/PermitRootLogin no/gm' "$config_file" \ - || echo "${red}Failed to set 'PermitRootLogin no'${nc}" -fi - -if grep -Eq '^MaxAuthTries 3$' "$config_file"; then - echo "MaxAuthTries already set to '3'" -elif grep -Eq '^#?MaxAuthTries(.*)?$' "$config_file"; then - echo "Setting 'MaxAuthTries 3'..." - sed -Ei 's/^#?MaxAuthTries(.*)?$/MaxAuthTries 3/gm' "$config_file" \ - || echo "${red}Failed to set 'MaxAuthTries 3'${nc}" -fi - -if grep -Eq '^MaxSessions 2$' "$config_file"; then - echo "MaxSessions already set to '2'" -elif grep -Eq '^#?MaxSessions(.*)?$' "$config_file"; then - echo "Setting 'MaxSessions 2'..." - sed -Ei 's/^#?MaxSessions(.*)?$/MaxSessions 2/gm' "$config_file" \ - || echo "${red}Failed to set 'MaxSessions 2'${nc}" -fi - -if grep -Eq '^PubkeyAuthentication yes$' "$config_file"; then - echo "PubkeyAuthentication already set to 'yes'" -elif grep -Eq '^#?PubkeyAuthentication(.*)?$' "$config_file"; then - echo "Setting 'PubkeyAuthentication yes'..." - sed -Ei 's/^#?PubkeyAuthentication(.*)?$/PubkeyAuthentication yes/gm' "$config_file" \ - || echo "${red}Failed to set 'PubkeyAuthentication yes'${nc}" -fi - -if grep -Eq '^PermitEmptyPasswords no$' "$config_file"; then - echo "PermitEmptyPasswords already set to 'no'" -elif grep -Eq '^#?PermitEmptyPasswords(.*)?$' "$config_file"; then - echo "Setting 'PermitEmptyPasswords no'..." - sed -Ei 's/^#?PermitEmptyPasswords(.*)?$/PermitEmptyPasswords no/gm' "$config_file" \ - || echo "${red}Failed to set 'PermitEmptyPasswords no'${nc}" -fi - -if grep -Eq '^ChallengeResponseAuthentication no$' "$config_file"; then - echo "ChallengeResponseAuthentication already set to 'no'" -elif grep -Eq '^#?ChallengeResponseAuthentication(.*)?$' "$config_file"; then - echo "Setting 'ChallengeResponseAuthentication no'..." - sed -Ei 's/^#?ChallengeResponseAuthentication(.*)?$/ChallengeResponseAuthentication no/gm' "$config_file" \ - || echo "${red}Failed to set 'ChallengeResponseAuthentication no'${nc}" -fi - -if grep -Eq '^KbdInteractiveAuthentication no$' "$config_file"; then - echo "KbdInteractiveAuthentication already set to 'no'" -elif grep -Eq '^#?KbdInteractiveAuthentication(.*)?$' "$config_file"; then - echo "Setting 'KbdInteractiveAuthentication no'..." - sed -Ei 's/^#?KbdInteractiveAuthentication(.*)?$/KbdInteractiveAuthentication no/gm' "$config_file" \ - || echo "${red}Failed to set 'KbdInteractiveAuthentication no'${nc}" -fi - -if grep -Eq '^UsePAM yes$' "$config_file"; then - echo "UsePAM already set to 'yes'" -elif grep -Eq '^#?UsePAM(.*)?$' "$config_file"; then - echo "Setting 'UsePAM yes'..." - sed -Ei 's/^#?UsePAM(.*)?$/UsePAM yes/gm' "$config_file" \ - || echo "${red}Failed to set 'UsePAM yes'${nc}" -fi - -if grep -Eq '^AllowAgentForwarding no$' "$config_file"; then - echo "AllowAgentForwarding already set to 'no'" -elif grep -Eq '^#?AllowAgentForwarding(.*)?$' "$config_file"; then - echo "Setting 'AllowAgentForwarding no'..." - sed -Ei 's/^#?AllowAgentForwarding(.*)?$/AllowAgentForwarding no/gm' "$config_file" \ - || echo "${red}Failed to set 'AllowAgentForwarding no'${nc}" -fi - -if grep -Eq '^AllowTcpForwarding no$' "$config_file"; then - echo "AllowTcpForwarding already set to 'no'" -elif grep -Eq '^#?AllowTcpForwarding(.*)?$' "$config_file"; then - echo "Setting 'AllowTcpForwarding no'..." - sed -Ei 's/^#?AllowTcpForwarding(.*)?$/AllowTcpForwarding no/gm' "$config_file" \ - || echo "${red}Failed to set 'AllowTcpForwarding no'${nc}" -fi - -if grep -Eq '^X11Forwarding no$' "$config_file"; then - echo "X11Forwarding already set to 'no'" -elif grep -Eq '^#?X11Forwarding(.*)?$' "$config_file"; then - echo "Setting 'X11Forwarding no'..." - sed -Ei 's/^#?X11Forwarding(.*)?$/X11Forwarding no/gm' "$config_file" \ - || echo "${red}Failed to set 'X11Forwarding no'${nc}" -fi - -if grep -Eq '^PrintMotd no$' "$config_file"; then - echo "PrintMotd already set to 'no'" -elif grep -Eq '^#?PrintMotd(.*)?$' "$config_file"; then - echo "Setting 'PrintMotd no'..." - sed -Ei 's/^#?PrintMotd(.*)?$/PrintMotd no/gm' "$config_file" \ - || echo "${red}Failed to set 'PrintMotd no'${nc}" -fi - -if grep -Eq '^TCPKeepAlive no$' "$config_file"; then - echo "TCPKeepAlive already set to 'no'" -elif grep -Eq '^#?TCPKeepAlive(.*)?$' "$config_file"; then - echo "Setting 'TCPKeepAlive no'..." - sed -Ei 's/^#?TCPKeepAlive(.*)?$/TCPKeepAlive no/gm' "$config_file" \ - || echo "${red}Failed to set 'TCPKeepAlive no'${nc}" -fi - -if grep -Eq '^Compression no$' "$config_file"; then - echo "Compression already set to 'no'" -elif grep -Eq '^#?Compression(.*)?$' "$config_file"; then - echo "Setting 'Compression no'..." - sed -Ei 's/^#?Compression(.*)?$/Compression no/gm' "$config_file" \ - || echo "${red}Failed to set 'Compression no'${nc}" -fi - -if grep -Eq '^ClientAliveInterval 300$' "$config_file"; then - echo "ClientAliveInterval already set to '300'" -elif grep -Eq '^#?ClientAliveInterval(.*)?$' "$config_file"; then - echo "Setting 'ClientAliveInterval 300'..." - sed -Ei 's/^#?ClientAliveInterval(.*)?$/ClientAliveInterval 300/gm' "$config_file" \ - || echo "${red}Failed to set 'ClientAliveInterval 300'${nc}" -fi - -if grep -Eq '^ClientAliveCountMax 2$' "$config_file"; then - echo "UseClientAliveCountMaxPAM already set to '2'" -elif grep -Eq '^#?ClientAliveCountMax(.*)?$' "$config_file"; then - echo "Setting 'ClientAliveCountMax 2'..." - sed -Ei 's/^#?ClientAliveCountMax(.*)?$/ClientAliveCountMax 2/gm' "$config_file" \ - || echo "${red}Failed to set 'ClientAliveCountMax 2'${nc}" -fi +### +### [ Harden 'sshd_config' ] +### + +for key in "${!C_SSHD_CONFIG[@]}"; do + # Skip processing Regex keys directly. + if [[ "$key" =~ Regex$ ]]; then + continue + fi + + regex_key="${key}Regex" + sed_regex="0,/${C_SSHD_CONFIG[$regex_key]}/s/${C_SSHD_CONFIG[$regex_key]}/${key} ${C_SSHD_CONFIG[$key]}/" + echo "${C_INFO}Checking '${key}'..." + + ## Check if the key is already set to the desired value. + if grep -Eq "^${key} ${C_SSHD_CONFIG[$key]}$" "$C_CONFIG_FILE"; then + echo "${C_SUCCESS}${key} already set to '${C_SSHD_CONFIG[$key]}'" + ## Check if the configurations are present in the file. + elif grep -Eq "${C_SSHD_CONFIG[$regex_key]}" "$C_CONFIG_FILE"; then + echo "${C_INFO}Setting '${key} ${C_SSHD_CONFIG[$key]}'..." + sed -Ei "$sed_regex" "$C_CONFIG_FILE" \ + || echo "${C_ERROR}Failed to set '${key} ${C_SSHD_CONFIG[$key]}'" >&2 + ## If the configuration is not present in the file. + else + echo "${C_WARNING}'${key}' not found in configuration file" >&2 + fi +done + +### +### [ Finalizing ] +### + +echo -e "\n${C_INFO}Restarting sshd..." +systemctl restart sshd || { + echo "${C_ERROR}Failed to restart sshd" >&2 + exit 1 +} -echo -e "\nRestarting sshd..." -systemctl restart sshd +echo -e "\n${C_SUCCESS}Finished hardening sshd" +echo -e "${C_NOTE}It is highly recommended to manually:" +echo -e "${C_NOTE} 1) Change the default sshd port (22)" +echo -e "${C_NOTE} 2) Disable PasswordAuthentication in favor of PubkeyAuthentication" +echo -e "${C_NOTE} 3) Add 'AllowUsers [your username]' to the bottom of 'sshd_config'" -echo -e "\n${green}Finished hardening sshd" -echo -e "${cyan}It is highly recommended to manually: -1) Change the default sshd port (22) -2) Disable PasswordAuthentication in favor of PubkeyAuthentication -3) Add 'AllowUsers [your username]' to the bottom of 'sshd_config'${nc}" From 4afc2a79f4b063fcad304c25d069cb9d8cfe3e11 Mon Sep 17 00:00:00 2001 From: "Hunter T." Date: Thu, 15 Aug 2024 18:00:50 -0700 Subject: [PATCH 10/12] Update CHANGELOG.md --- hardening/SSHD Hardening/CHANGELOG.md | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/hardening/SSHD Hardening/CHANGELOG.md b/hardening/SSHD Hardening/CHANGELOG.md index e287867..d3f6dfa 100644 --- a/hardening/SSHD Hardening/CHANGELOG.md +++ b/hardening/SSHD Hardening/CHANGELOG.md @@ -4,6 +4,22 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). +## v2.0.0 - 2024-08-15 + +Complete rewrite of the script. Below are just some of the differences in the new version. + +### Added + +- Can catch common error signals. +- Output is now colored to better differentiate between different types of messages. + +### Changes + +- Improved the script's structure. +- Improved regex and replacement of sshd configurations. +- Improved error handling. +- The script has been renamed to `harden-sshd.bash`. + ## v1.1.3 - 2024-04-13 ### Changed From fb37698db56b5219f8cd19b534795a903193fe95 Mon Sep 17 00:00:00 2001 From: "Hunter T." Date: Thu, 15 Aug 2024 18:01:42 -0700 Subject: [PATCH 11/12] Rename script --- hardening/SSHD Hardening/{sshd => harden-sshd.bash} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename hardening/SSHD Hardening/{sshd => harden-sshd.bash} (100%) diff --git a/hardening/SSHD Hardening/sshd b/hardening/SSHD Hardening/harden-sshd.bash similarity index 100% rename from hardening/SSHD Hardening/sshd rename to hardening/SSHD Hardening/harden-sshd.bash From 5a28b65866266bd062efd5488ea3b83012a586ec Mon Sep 17 00:00:00 2001 From: "Hunter T." Date: Thu, 15 Aug 2024 18:04:27 -0700 Subject: [PATCH 12/12] Initial commit for new security script --- hardening/UFW Cloudflare/CHANGELOG.md | 0 hardening/UFW Cloudflare/ufw-cloudflare.bash | 0 2 files changed, 0 insertions(+), 0 deletions(-) create mode 100644 hardening/UFW Cloudflare/CHANGELOG.md create mode 100644 hardening/UFW Cloudflare/ufw-cloudflare.bash diff --git a/hardening/UFW Cloudflare/CHANGELOG.md b/hardening/UFW Cloudflare/CHANGELOG.md new file mode 100644 index 0000000..e69de29 diff --git a/hardening/UFW Cloudflare/ufw-cloudflare.bash b/hardening/UFW Cloudflare/ufw-cloudflare.bash new file mode 100644 index 0000000..e69de29