From a3fbdebc46e7c783eb24469f98459cfa874fa398 Mon Sep 17 00:00:00 2001 From: konsthol Date: Sat, 2 Sep 2023 02:38:41 +0300 Subject: [PATCH] This commit is a lie --- harden | 117 +++++++++++---------------------------------------------- 1 file changed, 21 insertions(+), 96 deletions(-) diff --git a/harden b/harden index e0c49f4..94ccf81 100755 --- a/harden +++ b/harden @@ -74,7 +74,7 @@ function install_packages { package_manager="$(get_package_manager)" # Get the package manager case "$package_manager" in # Use case to check for the package manager "apt") # If the package manager is apt - echo '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 NEEDRESTART_MODE=a export DEBIAN_PRIORITY=critical @@ -104,8 +104,6 @@ function install_packages { # Then it will install the packages that are missing by invoking the install_packages function. 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 docker-compose systemd-container htop curl git sudo vim ssh wget fail2ban) # Declare dependencies as a local array - # local dependencies=(fuse-overlayfs dbus-user-session uidmap slirp4netns docker-compose dnsutils 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 <# local missing_dependencies=() # Declare missing_dependencies as a local array for dependency in "${dependencies[@]}"; do # Loop through the dependencies array @@ -165,7 +163,6 @@ function getCorrectFirewall { case "$distro" in # Use case to check for the distribution name "Ubuntu" | "Debian GNU/Linux") # If the distribution is Ubuntu or Debian printf "%s" 'debconf debconf/frontend select Noninteractive' | sudo debconf-set-selections - # echo 'debconf debconf/frontend select Noninteractive' | sudo debconf-set-selections export DEBIAN_FRONTEND=noninteractive export NEEDRESTART_MODE=a export DEBIAN_PRIORITY=critical @@ -201,7 +198,6 @@ function getCorrectKernelSecurityModule { ;; "Debian GNU/Linux") # If the distribution is Debian printf "%s" 'debconf debconf/frontend select Noninteractive' | sudo debconf-set-selections - # echo 'debconf debconf/frontend select Noninteractive' | sudo debconf-set-selections export DEBIAN_FRONTEND=noninteractive export NEEDRESTART_MODE=a export DEBIAN_PRIORITY=critical @@ -237,8 +233,7 @@ function firewallInit { sudo ufw allow 22100/tcp # Allow ssh connections on port 22100 ;; firewalld) - sudo systemctl enable firewalld # Enable the firewall on boot and start it - # sudo systemctl enable --now firewalld # Enable the firewall on boot and start it + sudo systemctl enable firewalld # Enable the firewall on boot sudo firewall-cmd --permanent --add-port=22100/tcp # Allow ssh connections on port 22100 ;; *) @@ -273,18 +268,6 @@ function kernelSecurityModuleInit { esac } -# function getIP { -# RESOLVERS='@resolver4.opendns.com @resolver3.opendns.com @resolver2.opendns.com @resolver1.opendns.com' -# for resolver in $RESOLVERS ; do -# result="$(dig +short myip.opendns.com "$resolver")" -# rc="$?" -# if [ -n "$result" ] ; then -# printf "%s\n" "$result" -# exit "$rc" -# fi -# done -# } - function dockerInit { # Set up rootless docker # Enable linger for the secdep user @@ -298,7 +281,6 @@ function dockerInit { printf "%s\n" "export PATH=/home/$USER/bin:$PATH" >> "$HOME/.bashrc" printf "%s\n" "export DOCKER_HOST=unix:///run/user/$UID/docker.sock" >> "$HOME/.bashrc" EOF - # printf "%s\n" "alias docker=\"docker --restart always --security-opt=no-new-privileges --cap-drop all --cap-add NET_BIND_SERVICE --read-only --tmpfs /home/$USER/opt -v /:/host\"" >> "$HOME/.bashrc" # Enable the user to bind to ports below 1024 sudo setcap cap_net_bind_service=ep /home/secdep/bin/rootlesskit # Restart docker @@ -327,8 +309,6 @@ EOF sudo chmod -x /home/secdep/docker-compose.yml > /dev/null 2>&1 sudo machinectl shell secdep@ /bin/bash -c 'curl -SL https://github.com/docker/compose/releases/download/v2.20.3/docker-compose-linux-x86_64 -o /home/secdep/bin/docker-compose' sudo machinectl shell secdep@ /bin/bash -c 'chmod +x /home/secdep/bin/docker-compose' - ## No immediate way to check if the docker-compose.yml file exists and is readable - ## so we'll just try to run it and if it doesn't exist or is not readable it will error out sudo machinectl shell secdep@ "$(which bash)" -c '[[ -f "$HOME/docker-compose.yml" ]] && DOCKER_HOST=unix:///run/user/$UID/docker.sock /home/secdep/bin/docker-compose -f /home/secdep/docker-compose.yml up -d' # Read the docker-compose.yml file for port mappings to add to the firewall CMD_PORTS="cat /home/secdep/docker-compose.yml | sed '/^[[:space:]]*$/d' | grep -A1 ports | grep '[0-9]:[0-9]' | rev | cut -d':' -f1 | rev | grep -Eow '[[:digit:]]+' | tr '\n' ' '" @@ -380,7 +360,7 @@ EOF # The --network dockerNetworkNoICC option will connect the docker image to the dockerNetworkNoICC network # The -v /:/host option will enable the docker rootless mode # # The --user secdep option will run the docker image as the secdep user to prevent privilege escalation - sudo -u secdep bash -c 'mkdir -p /home/secdep/opt' + # sudo -u secdep bash -c 'mkdir -p /home/secdep/opt' CMD="docker pull $dockerImage" # CMD="docker run -d --restart always --name $dockerImageName --security-opt=no-new-privileges --cap-drop all --cap-add NET_BIND_SERVICE --tmpfs /home/secdep/opt -v /:/host $dockerImage" # CMD="docker run -d --restart always --name $dockerImageName --security-opt=no-new-privileges --cap-drop all --cap-add NET_BIND_SERVICE --read-only --tmpfs /home/secdep/opt -v /:/host $dockerImage" @@ -388,39 +368,14 @@ EOF done } -# The apparmorConfig function will set up and configure apparmor with sane defaults. -# function apparmorConfig { -# # Create a new apparmor profile for the docker daemon -# sudo aa-genprof docker -# # Enable the apparmor profile for the docker daemon -# sudo aa-enforce docker -# # Reload the apparmor profiles -# sudo systemctl reload apparmor -# } - # The selinuxConfig function will set up and configure selinux with sane defaults. # function selinuxConfig { # # Set the selinux boolean to allow docker to use the network # sudo setsebool -P docker_connect_any 1 # } -# This function will create a new apparmor profile for every docker image installed on the system. -# function apparmorProfiles { -# # Get all the docker images installed on the system and store them in the dockerImages array -# local dockerImages=("$(docker images --format "{{.Repository}}")") -# # Loop through the dockerImages array -# for dockerImage in "${dockerImages[@]}"; do -# # Create a new apparmor profile for the docker image -# sudo aa-genprof "$dockerImage" -# # Enable the apparmor profile for the docker image -# sudo aa-enforce "$dockerImage" -# done -# # Reload the apparmor profiles -# sudo systemctl reload apparmor -# } - # Fix banaction ufw with iptables -# Does not persist after reboot +# Does not always persist after reboot function configureFail2ban { FAIL2BAN_LOCAL=$(cat <<'EOF' [Definition] @@ -473,48 +428,31 @@ EOF sudo mkdir -p /etc/systemd/system/fail2ban.service.d printf "%s" "$HARDEN_FAIL2BAN_SERVICE" | sudo tee /etc/systemd/system/fail2ban.service.d/override.conf sudo systemctl daemon-reload -# sudo systemctl enable fail2ban -# services+=("fail2ban") # Add fail2ban to the services array sudo systemctl enable --now fail2ban printf "%s" "LogLevel VERBOSE" | sudo tee -a /etc/ssh/sshd_config -#sudo systemctl restart sshd } function enableServices { for service in "${services[@]}"; do sudo systemctl restart "$service" done - # command -v ufw >/dev/null 2>&1 && currentFirewall="ufw" || currentFirewall="firewalld" whereis ufw | grep -q /ufw && currentFirewall="ufw" || currentFirewall="firewalld" + # With the if block it doesn't error out at firewalld check so we do it this way + # For ufw if [[ "$currentFirewall" == "ufw" ]]; then - # echo "You should enable ufw" + # Enable the firewall sudo ufw --force enable + # Enable and start the firewall on boot sudo systemctl enable --now ufw + # For firewalld elif [[ "$currentFirewall" == "firewalld" ]]; then + # Reload the firewall sudo firewall-cmd --reload else - printf "%s" "Unsupported firewall" + printf "%s" "Somehow there is no firewall installed" exit 1 fi - # sudo fail2ban-client start - # With the if block it doesn't error out at firewalld check - # For ufw - # Enable the firewall - # Enable and start the firewall on boot - # [[ "$currentFirewall" == "ufw" ]] && sudo ufw enable && sudo systemctl enable --now ufw - # [[ "$currentFirewall" == "ufw" ]] && sudo ufw enable && sudo systemctl enable ufw - # Getting stuck at sudo ufw enable? - # [[ "$currentFirewall" == "ufw" ]] && sudo systemctl enable ufw - # [[ "$currentFirewall" == "ufw" ]] && echo "You should enable ufw" - # For firewalld - # Reload the firewall - # [[ "$currentFirewall" == "firewalld" ]] && sudo firewall-cmd --reload - # sudo systemctl disable --now docker.service docker.socket - # sudo systemctl disable --now docker - # Make sure docker is disabled after - # installing docker-compose, to make sure - # only rootless docker is used } # Sometimes the user is not deleted after the script is run @@ -536,40 +474,27 @@ EOF # The main function will call the check_dependencies function and exit if it fails. # It will also output a message to the user to let them know that the script has finished. function main { - printf "%s" "$SCRIPT_NAME started" - check_dependencies || exit 1 # Check dependencies and exit if it fails + printf "%s" "$SCRIPT_NAME script started" + check_dependencies || exit 1 # Check dependencies and exit if it fails 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" - firewallInit || exit 1 # Initialize the firewall and exit if it fails + firewallInit || exit 1 # Initialize the firewall and exit if it fails printf "%s" "Firewall initialized" - kernelSecurityModuleInit || exit 1 # Initialize the kernel security module and exit if it fails + kernelSecurityModuleInit || exit 1 # Initialize the kernel security module and exit if it fails printf "%s" "Kernel security module initialized" - configureFail2ban || exit 1 # Initialize fail2ban and exit if it fails + configureFail2ban || exit 1 # Initialize fail2ban and exit if it fails printf "%s" "Fail2ban configured" -# apparmorConfig # Configure apparmor -# apparmorProfiles # Create apparmor profiles for all docker images # selinuxConfig # Configure selinux - # If number of arguments is greater than 0 # Call the dockerInit function with the arguments passed to the script - # Else exit with error code 1 -## [[ $# -gt 0 ]] && dockerInit "$@" || exit 1 - dockerInit "$@" || exit 1 # Initialize docker and exit if it fails + dockerInit "$@" || exit 1 # Initialize docker and exit if it fails enableServices || exit 1 deleteRemainingUsers || exit 1 - printf "%s" "$SCRIPT_NAME finished" # Output message to the user - printf "%s" "You should reboot" # Output message to the user - # sudo reboot + printf "%s" "$SCRIPT_NAME script finished" # Output message to the user + printf "%s" "System will reboot momentarily" # Output message to the user + sudo at now + 2 minute <<< "reboot" } -# # The am_i_root function will check if the user is root and exit if they are not. -# function am_i_root { -# if [[ $EUID -ne 0 ]]; then # Check if the user is root -# printf "%s" "Please run as root" # Output message to the user -# exit 1 # Exit with error code 1 -# fi -# } - # Call the main function main "$@"