I'm just a grunt. Don't blame me for this awful PoS.

This commit is contained in:
2023-09-05 05:12:24 +03:00
parent 8e40ee36a9
commit 8edb5737bc

255
harden
View File

@@ -33,85 +33,84 @@ SCRIPT_NAME="${0##*/}"
# The get_distro function will use short if statements to check for the os-release file existence and readability. # The get_distro function will use short if statements to check for the os-release file existence and readability.
# Then it will source it and output the distribution's name or exit in case of failure of either case. # Then it will source it and output the distribution's name or exit in case of failure of either case.
function get_distro { function get_distro {
if [[ -e /etc/os-release ]] && [[ -r /etc/os-release ]]; then # Check if file exists and is readable if [[ -e /etc/os-release ]] && [[ -r /etc/os-release ]]; then # Check if file exists and is readable
. /etc/os-release # Source the file . /etc/os-release # Source the file
printf "%s" "$NAME" # Output the distribution's name printf "%s" "$NAME" # Output the distribution's name
else # If the file does not exist or is not readable else # If the file does not exist or is not readable
printf "%s" "File os-release not found or not readable" # Output error message printf "%s" "File os-release not found or not readable" # Output error message
exit 1 # Exit with error code 1 exit 1 # Exit with error code 1
fi fi
} }
# The get_package_manager function will take the output of the get_distro function and determine # The get_package_manager function will take the output of the get_distro function and determine
# which is the package manager used for the most popular server distros and exit if it is not found. # which is the package manager used for the most popular server distros and exit if it is not found.
function get_package_manager { function get_package_manager {
local distro # Declare distro as a local variable local distro # Declare distro as a local variable
distro="$(get_distro)" # Get the distribution name distro="$(get_distro)" # Get the distribution name
case "$distro" in # Use case to check for the distribution name case "$distro" in # Use case to check for the distribution name
"Ubuntu" | "Debian GNU/Linux") # If the distribution is Ubuntu or Debian "Ubuntu" | "Debian GNU/Linux") # If the distribution is Ubuntu or Debian
printf "%s" "apt" # Output apt printf "%s" "apt" # Output apt
;; ;;
"CentOS Linux" | "Fedora" | "Red Hat Enterprise Linux Server") # If the distribution is CentOS, Fedora or RHEL "CentOS Linux" | "Fedora" | "Red Hat Enterprise Linux Server") # If the distribution is CentOS, Fedora or RHEL
printf "%s" "dnf" # Output dnf printf "%s" "dnf" # Output dnf
;; ;;
"openSUSE Leap") # If the distribution is OpenSUSE
"openSUSE Leap") # If the distribution is OpenSUSE printf "%s" "zypper" # Output zypper
printf "%s" "zypper" # Output zypper ;;
;; *)
*) # If the distribution is none of the above, output unsupported distribution
# If the distribution is none of the above, output unsupported distribution # and exit with error code 1
# and exit with error code 1 printf "%s" "Unsupported distribution"
printf "%s" "Unsupported distribution" exit 1 # Exit with error code 1
exit 1 # Exit with error code 1 ;;
;; esac
esac
} }
# The install_packages function will take the output of the get_package_manager function and install any # The install_packages function will take the output of the get_package_manager function and install any
# package passed as an argument to it. It will also check if the package manager is known and exit if it is not. # package passed as an argument to it. It will also check if the package manager is known and exit if it is not.
function install_packages { function install_packages {
local package_manager # Declare package_manager as a local variable local package_manager # Declare package_manager as a local variable
package_manager="$(get_package_manager)" # Get the package manager package_manager="$(get_package_manager)" # Get the package manager
case "$package_manager" in # Use case to check for the package manager case "$package_manager" in # Use case to check for the package manager
"apt") # If the package manager is apt "apt") # If the package manager is apt
printf "%s" 'debconf debconf/frontend select Noninteractive' | sudo debconf-set-selections printf "%s" 'debconf debconf/frontend select Noninteractive' | sudo debconf-set-selections
export DEBIAN_FRONTEND=noninteractive export DEBIAN_FRONTEND=noninteractive
export NEEDRESTART_MODE=a export NEEDRESTART_MODE=a
export DEBIAN_PRIORITY=critical export DEBIAN_PRIORITY=critical
# Running sudo with -E will preserve the environment variables set in the script # Running sudo with -E will preserve the environment variables set in the script
sudo -E apt update -y && sudo apt upgrade -y # Update the package list and upgrade the packages sudo -E apt update -y && sudo apt upgrade -y # Update the package list and upgrade the packages
sudo -E apt install -y "$@" # Install the packages passed as arguments sudo -E apt install -y "$@" # Install the packages passed as arguments
;; ;;
"dnf") # If the package manager is dnf "dnf") # If the package manager is dnf
sudo dnf upgrade -y # Update the package list sudo dnf upgrade -y # Update the package list
sudo dnf install -y "$@" # Install the packages passed as arguments sudo dnf install -y "$@" # Install the packages passed as arguments
;; ;;
"zypper") # If the package manager is zypper "zypper") # If the package manager is zypper
sudo zypper update -y # Update the package list sudo zypper update -y # Update the package list
sudo zypper install -y "$@" # Install the packages passed as arguments sudo zypper install -y "$@" # Install the packages passed as arguments
;; ;;
*) *)
# If the package manager is not one of the above, output unsupported package manager # If the package manager is not one of the above, output unsupported package manager
# and exit with error code 1 # and exit with error code 1
printf "%s" "Unsupported package manager" printf "%s" "Unsupported package manager"
exit 1 # Exit with error code 1 exit 1 # Exit with error code 1
;; ;;
esac esac
} }
# The check_dependencies function will check if the dependencies defined in a local array are not installed # The check_dependencies function will check if the dependencies defined in a local array are not installed
# and store the ones that are indeed absent in another local array. # and store the ones that are indeed absent in another local array.
# Then it will install the packages that are missing by invoking the install_packages function. # Then it will install the packages that are missing by invoking the install_packages function.
function check_dependencies { # systemd-container is for machinectl function check_dependencies { # systemd-container is for machinectl
local dependencies=(fuse-overlayfs dbus-user-session uidmap slirp4netns systemd-container at htop curl git sudo vim ssh wget fail2ban) # Declare dependencies as a local array local dependencies=(fuse-overlayfs dbus-user-session uidmap slirp4netns systemd-container at htop curl git sudo vim ssh wget fail2ban) # Declare dependencies as a local array
#> see what to do with name differences between distros if any <# #> see what to do with name differences between distros if any <#
local missing_dependencies=() # Declare missing_dependencies as a local array local missing_dependencies=() # Declare missing_dependencies as a local array
for dependency in "${dependencies[@]}"; do # Loop through the dependencies array for dependency in "${dependencies[@]}"; do # Loop through the dependencies array
# If the dependency is not installed, add it to the missing_dependencies array # If the dependency is not installed, add it to the missing_dependencies array
! command -v "$dependency" &> /dev/null && missing_dependencies+=("$dependency") ! command -v "$dependency" &> /dev/null && missing_dependencies+=("$dependency")
done done
# If the missing_dependencies array is not empty, install the packages # If the missing_dependencies array is not empty, install the packages
[[ ${#missing_dependencies[@]} -ne 0 ]] && install_packages "${missing_dependencies[@]}" [[ ${#missing_dependencies[@]} -ne 0 ]] && install_packages "${missing_dependencies[@]}"
} }
# Global array of the service names to be restarted # Global array of the service names to be restarted
@@ -130,95 +129,93 @@ services=()
# - Disable agent forwarding to prevent ssh-agent hijacking # - Disable agent forwarding to prevent ssh-agent hijacking
# Then it will store the sshd service name in the services array. # Then it will store the sshd service name in the services array.
function hardenSSH { function hardenSSH {
# Check if the sshd_config file exists and is readable # Check if the sshd_config file exists and is readable
# If it is, then modify it using sed and restart the sshd service # If it is, then modify it using sed and restart the sshd service
# If it is not, then output an error message and exit with error code 1 # If it is not, then output an error message and exit with error code 1
# The -i flag is used to modify the file in place # The -i flag is used to modify the file in place
# We split the sed command into multiple lines for readability purposes # We split the sed command into multiple lines for readability purposes
# and to avoid calling it multiple times # and to avoid calling it multiple times
if [[ -e /etc/ssh/sshd_config ]] && [[ -r /etc/ssh/sshd_config ]]; then if [[ -e /etc/ssh/sshd_config ]] && [[ -r /etc/ssh/sshd_config ]]; then
sudo sed -i \ sudo sed -i \
-e 's/^#AllowGroups.*/AllowGroups sudo/' \ -e 's/^#AllowGroups.*/AllowGroups sudo/' \
-e 's/^#Port.*/Port 22100/' \ -e 's/^#Port.*/Port 22100/' \
-e 's/^#ClientAliveInterval.*/ClientAliveInterval 300/' \ -e 's/^#ClientAliveInterval.*/ClientAliveInterval 300/' \
-e 's/^#ClientAliveCountMax.*/ClientAliveCountMax 3/' \ -e 's/^#ClientAliveCountMax.*/ClientAliveCountMax 3/' \
-e 's/^#PermitRootLogin.*/PermitRootLogin no/' \ -e 's/^#PermitRootLogin.*/PermitRootLogin no/' \
-e 's/^#PermitEmptyPasswords.*/PermitEmptyPasswords no/' \ -e 's/^#PermitEmptyPasswords.*/PermitEmptyPasswords no/' \
-e 's/^#Protocol.*/Protocol 2/' \ -e 's/^#Protocol.*/Protocol 2/' \
-e 's/^#PasswordAuthentication.*/PasswordAuthentication no/' \ -e 's/^#PasswordAuthentication.*/PasswordAuthentication no/' \
-e 's/^#X11Forwarding.*/X11Forwarding no/' \ -e 's/^#X11Forwarding.*/X11Forwarding no/' \
-e 's/^X11Forwarding.*/X11Forwarding no/' \ -e 's/^X11Forwarding.*/X11Forwarding no/' \
-e 's/^#AllowAgentForwarding.*/AllowAgentForwarding no/' \ -e 's/^#AllowAgentForwarding.*/AllowAgentForwarding no/' \
/etc/ssh/sshd_config /etc/ssh/sshd_config
services+=("sshd") # Add sshd to the services array services+=("sshd") # Add sshd to the services array
else else
printf "%s" "File sshd_config not found or not readable" printf "%s" "File sshd_config not found or not readable"
exit 1 exit 1
fi fi
} }
function getCorrectFirewall { function getCorrectFirewall {
local distro # Declare distro as a local variable local distro # Declare distro as a local variable
distro="$(get_distro)" # Get the distribution name distro="$(get_distro)" # Get the distribution name
case "$distro" in # Use case to check for the distribution name case "$distro" in # Use case to check for the distribution name
"Ubuntu" | "Debian GNU/Linux") # If the distribution is Ubuntu or Debian "Ubuntu" | "Debian GNU/Linux") # If the distribution is Ubuntu or Debian
printf "%s" 'debconf debconf/frontend select Noninteractive' | sudo debconf-set-selections printf "%s" 'debconf debconf/frontend select Noninteractive' | sudo debconf-set-selections
export DEBIAN_FRONTEND=noninteractive export DEBIAN_FRONTEND=noninteractive
export NEEDRESTART_MODE=a export NEEDRESTART_MODE=a
export DEBIAN_PRIORITY=critical export DEBIAN_PRIORITY=critical
sudo -E apt install ufw -y # Install ufw sudo -E apt install ufw -y # Install ufw
printf "%s" "ufw" # Output ufw printf "%s" "ufw" # Output ufw
;; ;;
"CentOS Linux" | "Fedora" | "Red Hat Enterprise Linux Server") # If the distribution is CentOS, Fedora or RHEL "CentOS Linux" | "Fedora" | "Red Hat Enterprise Linux Server") # If the distribution is CentOS, Fedora or RHEL
sudo dnf install firewalld -y # Install firewalld sudo dnf install firewalld -y # Install firewalld
printf "%s" "firewalld" # Output firewalld printf "%s" "firewalld" # Output firewalld
;; ;;
"openSUSE Leap") # If the distribution is OpenSUSE "openSUSE Leap") # If the distribution is OpenSUSE
sudo zypper install firewalld -y # Install firewalld sudo zypper install firewalld -y # Install firewalld
printf "%s" "firewalld" # Output firewalld printf "%s" "firewalld" # Output firewalld
;; ;;
*) *)
# If the distribution is none of the above, output unsupported distribution # If the distribution is none of the above, output unsupported distribution
# and exit with error code 1 # and exit with error code 1
printf "%s" "Unsupported distribution" printf "%s" "Unsupported distribution"
exit 1 # Exit with error code 1 exit 1 # Exit with error code 1
;; ;;
esac esac
} }
function getCorrectKernelSecurityModule { function getCorrectKernelSecurityModule {
local distro # Declare distro as a local variable local distro # Declare distro as a local variable
distro="$(get_distro)" # Get the distribution name distro="$(get_distro)" # Get the distribution name
case "$distro" in # Use case to check for the distribution name case "$distro" in # Use case to check for the distribution name
"Ubuntu") # If the distribution is Ubuntu "Ubuntu") # If the distribution is Ubuntu
sudo apt install apparmor-profiles apparmor-utils apparmor-profiles-extra -y # Install apparmor sudo apt install apparmor-profiles apparmor-utils apparmor-profiles-extra -y # Install apparmor
printf "%s" "apparmor" # Output apparmor printf "%s" "apparmor" # Output apparmor
;; ;;
"Debian GNU/Linux") # If the distribution is Debian "Debian GNU/Linux") # If the distribution is Debian
printf "%s" 'debconf debconf/frontend select Noninteractive' | sudo debconf-set-selections printf "%s" 'debconf debconf/frontend select Noninteractive' | sudo debconf-set-selections
export DEBIAN_FRONTEND=noninteractive export DEBIAN_FRONTEND=noninteractive
export NEEDRESTART_MODE=a export NEEDRESTART_MODE=a
export DEBIAN_PRIORITY=critical export DEBIAN_PRIORITY=critical
sudo -E apt install apparmor apparmor-profiles apparmor-profiles-extra apparmor-utils auditd python3-apparmor -y # Install apparmor sudo -E apt install apparmor apparmor-profiles apparmor-profiles-extra apparmor-utils auditd python3-apparmor -y # Install apparmor
printf "%s" "apparmor" # Output apparmor printf "%s" "apparmor" # Output apparmor
;; ;;
"CentOS Linux" | "Fedora" | "Red Hat Enterprise Linux Server") # If the distribution is CentOS, Fedora or RHEL "CentOS Linux" | "Fedora" | "Red Hat Enterprise Linux Server") # If the distribution is CentOS, Fedora or RHEL
sudo dnf install selinux container-selinux -y # Install selinux sudo dnf install selinux container-selinux -y # Install selinux
printf "%s" "selinux" # Output selinux printf "%s" "selinux" # Output selinux
;; ;;
"openSUSE Leap") # If the distribution is OpenSUSE
"openSUSE Leap") # If the distribution is OpenSUSE sudo zypper install -t pattern apparmor -y # Install apparmor
sudo zypper install -t pattern apparmor -y # Install apparmor
printf "%s" "apparmor" # Output apparmor printf "%s" "apparmor" # Output apparmor
;; ;;
*) *)
# If the distribution is none of the above, output unsupported distribution # If the distribution is none of the above, output unsupported distribution
# and exit with error code 1 # and exit with error code 1
printf "%s" "Unsupported distribution" printf "%s" "Unsupported distribution"
exit 1 # Exit with error code 1 exit 1 # Exit with error code 1
;; ;;
esac esac
} }
@@ -320,11 +317,13 @@ EOF
rm -f -- *.sha512 rm -f -- *.sha512
chmod a+rx runsc containerd-shim-runsc-v1 chmod a+rx runsc containerd-shim-runsc-v1
sudo mv runsc containerd-shim-runsc-v1 /home/secdep/bin sudo mv runsc containerd-shim-runsc-v1 /home/secdep/bin
sudo chown secdep:secdep /home/secdep/bin/runsc
sudo chown secdep:secdep /home/secdep/bin/containerd-shim-runsc-v1
) )
# Enable gVisor for docker by default while hardening the docker daemon.json file # Enable gVisor for docker by default while hardening the docker daemon.json file
# The no-new-privileges option will prevent the docker daemon from gaining new privileges # The no-new-privileges option will prevent the docker daemon from gaining new privileges
# The runsc option --network=host and --ignore-cgroup will help with running runsc # The runsc option --network=host and --ignore-cgroups=true will help with running runsc
# with rootless docker # with rootless docker without much hassle
sudo runuser - secdep -c 'mkdir -p /home/secdep/.config/docker' sudo runuser - secdep -c 'mkdir -p /home/secdep/.config/docker'
# "icc": false to disable inter-container communication, does not work without br_netfilter module loaded # "icc": false to disable inter-container communication, does not work without br_netfilter module loaded
# and it is sometimes prohibited by the hosting provider # and it is sometimes prohibited by the hosting provider
@@ -339,7 +338,9 @@ EOF
"path": "/home/secdep/bin/runsc", "path": "/home/secdep/bin/runsc",
"runtimeArgs": [ "runtimeArgs": [
"--network=host", "--network=host",
"--ignore-cgroups" "--ignore-cgroups=true",
"--overlay2 all:memory",
"--rootless"
] ]
} }
} }
@@ -489,7 +490,7 @@ EOF
# Then it will output a message to the user and reboot the system in 2 minutes. # Then it will output a message to the user and reboot the system in 2 minutes.
function main { function main {
printf "%s" "$SCRIPT_NAME script started" printf "%s" "$SCRIPT_NAME script started"
check_dependencies || exit 1 # Check dependencies and exit if it fails check_dependencies || exit 1 # Check dependencies and exit if it fails
printf "%s" "Dependencies installed" printf "%s" "Dependencies installed"
hardenSSH || exit 1 # Harden ssh and exit if it fails hardenSSH || exit 1 # Harden ssh and exit if it fails
printf "%s" "SSH hardened" printf "%s" "SSH hardened"
@@ -507,8 +508,8 @@ function main {
printf "%s" "Services restarted and firewall enabled" printf "%s" "Services restarted and firewall enabled"
deleteRemainingUsers || exit 1 # Delete possible remaining users deleteRemainingUsers || exit 1 # Delete possible remaining users
printf "%s" "Any unnecessary users deleted" printf "%s" "Any unnecessary users deleted"
printf "%s" "$SCRIPT_NAME script finished" # Output message to the user printf "%s" "$SCRIPT_NAME script finished" # Output message to the user
printf "%s" "System will reboot momentarily" # Output message to the user printf "%s" "System will reboot momentarily" # Output message to the user
# Reboot the system in 2 minutes with the shutdown command so that login before the reboot is not possible # Reboot the system in 2 minutes with the shutdown command so that login before the reboot is not possible
sudo shutdown -r +2 sudo shutdown -r +2
} }