This commit is a lie
This commit is contained in:
117
harden
117
harden
@@ -74,7 +74,7 @@ function install_packages {
|
|||||||
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
|
||||||
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 DEBIAN_FRONTEND=noninteractive
|
||||||
export NEEDRESTART_MODE=a
|
export NEEDRESTART_MODE=a
|
||||||
export DEBIAN_PRIORITY=critical
|
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.
|
# 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
|
||||||
# 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 <#
|
#> 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
|
||||||
@@ -165,7 +163,6 @@ function getCorrectFirewall {
|
|||||||
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
|
||||||
# echo '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
|
||||||
@@ -201,7 +198,6 @@ function getCorrectKernelSecurityModule {
|
|||||||
;;
|
;;
|
||||||
"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
|
||||||
# echo '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
|
||||||
@@ -237,8 +233,7 @@ function firewallInit {
|
|||||||
sudo ufw allow 22100/tcp # Allow ssh connections on port 22100
|
sudo ufw allow 22100/tcp # Allow ssh connections on port 22100
|
||||||
;;
|
;;
|
||||||
firewalld)
|
firewalld)
|
||||||
sudo systemctl enable firewalld # Enable the firewall on boot and start it
|
sudo systemctl enable firewalld # Enable the firewall on boot
|
||||||
# sudo systemctl enable --now firewalld # Enable the firewall on boot and start it
|
|
||||||
sudo firewall-cmd --permanent --add-port=22100/tcp # Allow ssh connections on port 22100
|
sudo firewall-cmd --permanent --add-port=22100/tcp # Allow ssh connections on port 22100
|
||||||
;;
|
;;
|
||||||
*)
|
*)
|
||||||
@@ -273,18 +268,6 @@ function kernelSecurityModuleInit {
|
|||||||
esac
|
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 {
|
function dockerInit {
|
||||||
# Set up rootless docker
|
# Set up rootless docker
|
||||||
# Enable linger for the secdep user
|
# 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 PATH=/home/$USER/bin:$PATH" >> "$HOME/.bashrc"
|
||||||
printf "%s\n" "export DOCKER_HOST=unix:///run/user/$UID/docker.sock" >> "$HOME/.bashrc"
|
printf "%s\n" "export DOCKER_HOST=unix:///run/user/$UID/docker.sock" >> "$HOME/.bashrc"
|
||||||
EOF
|
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
|
# Enable the user to bind to ports below 1024
|
||||||
sudo setcap cap_net_bind_service=ep /home/secdep/bin/rootlesskit
|
sudo setcap cap_net_bind_service=ep /home/secdep/bin/rootlesskit
|
||||||
# Restart docker
|
# Restart docker
|
||||||
@@ -327,8 +309,6 @@ EOF
|
|||||||
sudo chmod -x /home/secdep/docker-compose.yml > /dev/null 2>&1
|
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 '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'
|
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'
|
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
|
# 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' ' '"
|
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 --network dockerNetworkNoICC option will connect the docker image to the dockerNetworkNoICC network
|
||||||
# The -v /:/host option will enable the docker rootless mode
|
# 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
|
# # 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 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 --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"
|
# 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
|
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.
|
# The selinuxConfig function will set up and configure selinux with sane defaults.
|
||||||
# function selinuxConfig {
|
# function selinuxConfig {
|
||||||
# # Set the selinux boolean to allow docker to use the network
|
# # Set the selinux boolean to allow docker to use the network
|
||||||
# sudo setsebool -P docker_connect_any 1
|
# 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
|
# Fix banaction ufw with iptables
|
||||||
# Does not persist after reboot
|
# Does not always persist after reboot
|
||||||
function configureFail2ban {
|
function configureFail2ban {
|
||||||
FAIL2BAN_LOCAL=$(cat <<'EOF'
|
FAIL2BAN_LOCAL=$(cat <<'EOF'
|
||||||
[Definition]
|
[Definition]
|
||||||
@@ -473,48 +428,31 @@ EOF
|
|||||||
sudo mkdir -p /etc/systemd/system/fail2ban.service.d
|
sudo mkdir -p /etc/systemd/system/fail2ban.service.d
|
||||||
printf "%s" "$HARDEN_FAIL2BAN_SERVICE" | sudo tee /etc/systemd/system/fail2ban.service.d/override.conf
|
printf "%s" "$HARDEN_FAIL2BAN_SERVICE" | sudo tee /etc/systemd/system/fail2ban.service.d/override.conf
|
||||||
sudo systemctl daemon-reload
|
sudo systemctl daemon-reload
|
||||||
# sudo systemctl enable fail2ban
|
|
||||||
# services+=("fail2ban") # Add fail2ban to the services array
|
|
||||||
sudo systemctl enable --now fail2ban
|
sudo systemctl enable --now fail2ban
|
||||||
printf "%s" "LogLevel VERBOSE" | sudo tee -a /etc/ssh/sshd_config
|
printf "%s" "LogLevel VERBOSE" | sudo tee -a /etc/ssh/sshd_config
|
||||||
#sudo systemctl restart sshd
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function enableServices {
|
function enableServices {
|
||||||
for service in "${services[@]}"; do
|
for service in "${services[@]}"; do
|
||||||
sudo systemctl restart "$service"
|
sudo systemctl restart "$service"
|
||||||
done
|
done
|
||||||
# command -v ufw >/dev/null 2>&1 && currentFirewall="ufw" || currentFirewall="firewalld"
|
|
||||||
whereis ufw | grep -q /ufw && 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
|
if [[ "$currentFirewall" == "ufw" ]]; then
|
||||||
# echo "You should enable ufw"
|
# Enable the firewall
|
||||||
sudo ufw --force enable
|
sudo ufw --force enable
|
||||||
|
# Enable and start the firewall on boot
|
||||||
sudo systemctl enable --now ufw
|
sudo systemctl enable --now ufw
|
||||||
|
# For firewalld
|
||||||
elif [[ "$currentFirewall" == "firewalld" ]]; then
|
elif [[ "$currentFirewall" == "firewalld" ]]; then
|
||||||
|
# Reload the firewall
|
||||||
sudo firewall-cmd --reload
|
sudo firewall-cmd --reload
|
||||||
else
|
else
|
||||||
printf "%s" "Unsupported firewall"
|
printf "%s" "Somehow there is no firewall installed"
|
||||||
exit 1
|
exit 1
|
||||||
fi
|
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
|
# 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.
|
# 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.
|
# It will also output a message to the user to let them know that the script has finished.
|
||||||
function main {
|
function main {
|
||||||
printf "%s" "$SCRIPT_NAME 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"
|
||||||
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"
|
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"
|
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"
|
printf "%s" "Fail2ban configured"
|
||||||
# apparmorConfig # Configure apparmor
|
|
||||||
# apparmorProfiles # Create apparmor profiles for all docker images
|
|
||||||
# selinuxConfig # Configure selinux
|
# selinuxConfig # Configure selinux
|
||||||
# If number of arguments is greater than 0
|
|
||||||
# Call the dockerInit function with the arguments passed to the script
|
# Call the dockerInit function with the arguments passed to the script
|
||||||
# Else exit with error code 1
|
dockerInit "$@" || exit 1 # Initialize docker and exit if it fails
|
||||||
## [[ $# -gt 0 ]] && dockerInit "$@" || exit 1
|
|
||||||
dockerInit "$@" || exit 1 # Initialize docker and exit if it fails
|
|
||||||
enableServices || exit 1
|
enableServices || exit 1
|
||||||
deleteRemainingUsers || exit 1
|
deleteRemainingUsers || exit 1
|
||||||
printf "%s" "$SCRIPT_NAME finished" # Output message to the user
|
printf "%s" "$SCRIPT_NAME script finished" # Output message to the user
|
||||||
printf "%s" "You should reboot" # Output message to the user
|
printf "%s" "System will reboot momentarily" # Output message to the user
|
||||||
# sudo reboot
|
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
|
# Call the main function
|
||||||
main "$@"
|
main "$@"
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user