diff --git a/harden b/harden index c7dd8b2..032a6ac 100755 --- a/harden +++ b/harden @@ -103,7 +103,7 @@ function install_packages { # 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. function check_dependencies { - local dependencies=(fuse-overlayfs dbus-user-session uidmap slirp4netns docker-compose 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 @@ -282,162 +282,39 @@ function kernelSecurityModuleInit { # } function dockerInit { - # Add user to docker group to avoid using sudo when running docker commands - ##sudo usermod -aG docker "$USER" # Set up rootless docker - # sudo runuser - secdep -c 'curl -fsSL https://get.docker.com/rootless | sh' - # IP="$(getIP)" - -# sudo su secdep << 'EOF' -# -# export XDG_RUNTIME_DIR=/run/user/$(id -u secdep) -# export DBUS_SESSION_BUS_ADDRESS=/run/user/$(id -u secdep)/bus -# curl -fsSL https://get.docker.com/rootless | sh -# export DOCKER_HOST=unix:///run/user/$UID/docker.sock -# export PATH=/home/$USER/bin:$PATH -# 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" -# source "$HOME/.bashrc" && systemctl --machine=secdep@.host --user enable now docker.service -# -# EOF - - # export XDG_RUNTIME_DIR=/run/user/$(id -u secdep) - # export DBUS_SESSION_BUS_ADDRESS=/run/user/$(id -u secdep)/bus - + # Enable linger for the secdep user + sudo loginctl enable-linger secdep + # Enable dbus for the secdep user + sudo machinectl shell secdep@ /bin/bash -c "systemctl --user enable --now dbus" + # Install rootless docker + sudo machinectl shell secdep@ /bin/bash -c "curl -fsSL https://get.docker.com/rootless | sh" + # Add important environment variables to the secdep user's .bashrc sudo su secdep << 'EOF' - - curl -fsSL https://get.docker.com/rootless | sh - export DOCKER_HOST=unix:///run/user/$UID/docker.sock - export PATH=/home/$USER/bin:$PATH 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 + # Enable the user to bind to ports below 1024 + sudo setcap cap_net_bind_service=ep /home/secdep/bin/rootlesskit + # Restart docker + sudo machinectl shell secdep@ /bin/bash -c "systemctl --user restart docker" - # sudo -u secdep bash -c 'curl -fsSL https://get.docker.com/rootless | sh' - # sudo touch /etc/profile.d/docker.sh - # sudo echo '[[ -S /run/user/${UID}/docker.sock ]] && { export XDG_RUNTIME_DIR=/run/user/${UID} export PATH=/usr/bin:$PATH export DOCKER_HOST=unix:///run/user/${UID}/docker.sock; }' | sudo tee -a /etc/profile.d/docker.sh - sudo runuser - secdep -c 'mkdir -p "/home/secdep/.config/systemd/user"' - sudo runuser - secdep -c 'mkdir -p "/home/secdep/.config/systemd/default.target.wants"' - sudo runuser - secdep -c 'touch "/home/secdep/.config/systemd/user/docker.service"' - - # sudo runuser - secdep -c 'cat <<- EOT > "/home/secdep/.config/systemd/user/docker.service" - sudo runuser - secdep -c 'cat << EOF > "/home/secdep/.config/systemd/user/docker.service" -[Unit] -Description=Docker Application Container Engine (Rootless) -Documentation=https://docs.docker.com/go/rootless/ -[Service] -Environment=PATH=/home/secdep/bin:/sbin:/usr/sbin:/home/secdep/bin:/home/secdep/bin:/home/secdep/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin -ExecStart=/home/secdep/bin/dockerd-rootless.sh -ExecReload=/bin/kill -s HUP $MAINPID -TimeoutSec=0 -RestartSec=2 -Restart=always -StartLimitBurst=3 -StartLimitInterval=60s -LimitNOFILE=infinity -LimitNPROC=infinity -LimitCORE=infinity -TasksMax=infinity -Delegate=yes -Type=notify -NotifyAccess=all -KillMode=mixed -[Install] -WantedBy=default.target -EOF' - - sudo runuser - secdep -c 'ln -s "/home/secdep/.config/systemd/user/docker.service" "/home/secdep/.config/systemd/default.target.wants/docker.service"' - -# sudo su secdep << 'EOF' -# export XDG_RUNTIME_DIR=/run/user/$(id -u secdep) -# export DBUS_SESSION_BUS_ADDRESS=/run/user/$(id -u secdep)/bus -# systemctl --machine=secdep@.host --user daemon-reload -# systemctl --machine=secdep@.host --user enable --now docker.service -# EOF - -id=$(id -u secdep) -sudo mkdir -p /run/user/"$id" -sudo chown secdep /run/user/"$id" -sudo systemctl start user@"$id" -sudo loginctl enable-linger secdep -sudo setcap cap_net_bind_service=ep /home/secdep/bin/rootlesskit -export DBUS_SESSION_BUS_ADDRESS=unix:path=/run/user/"$id"/bus -export XDG_RUNTIME_DIR=/run/user/"id" -sudo -E su secdep << 'EOF' - systemctl --user daemon-reload - systemctl --user enable --now docker.service -EOF -# sudo su secdep << EOF -# export XDG_RUNTIME_DIR=/run/user/$(id -u secdep) -# export DBUS_SESSION_BUS_ADDRESS=/run/user/$(id -u secdep)/bus -# systemctl --host secdep@$IP daemon-reload -# systemctl --host secdep@$IP enable --now docker.service -# EOF - - # sudo runuser - secdep -c 'mkdir -p "/home/secdep/.docker/run"' - - # sudo runuser - secdep -c 'bash /home/secdep/bin/dockerd-rootless-setuptool.sh install' - # sudo runuser - secdep -c 'mkdir -p "/home/secdep/.config/systemd/user"' - # sudo runuser - secdep -c 'cat <<- EOT > "/home/secdep/.config/systemd/user/docker.service" - # [Unit] - # Description=Docker Application Container Engine (Rootless) - # Documentation=https://docs.docker.com/go/rootless/ - # [Service] - # Environment=PATH=$BIN:/sbin:/usr/sbin:$PATH - # ExecStart=$BIN/dockerd-rootless.sh $DOCKERD_ROOTLESS_SH_FLAGS - # ExecReload=/bin/kill -s HUP \$MAINPID - # TimeoutSec=0 - # RestartSec=2 - # Restart=always - # StartLimitBurst=3 - # StartLimitInterval=60s - # LimitNOFILE=infinity - # LimitNPROC=infinity - # LimitCORE=infinity - # TasksMax=infinity - # Delegate=yes - # Type=notify - # NotifyAccess=all - # KillMode=mixed - # [Install] - # WantedBy=default.target - # EOT - # ' - - # sudo runuser - secdep -c 'systemctl --user -M secdep@ daemon-reload' - - #sudo runuser - secdep -c 'export XDG_RUNTIME_DIR=/run/user/$UID' - - - # sudo -u secdep bash -c 'export DOCKER_HOST=unix:///run/user/$UID/docker.sock' - # sudo -u secdep bash -c 'export PATH=/home/$USER/bin:$PATH' - # sudo -u secdep bash -c 'printf "%s\n" "export DOCKER_HOST=unix:///run/user/$UID/docker.sock" >> "$HOME/.bashrc"' - # sudo -u secdep bash -c 'printf "%s\n" "export PATH=/home/$USER/bin:$PATH" >> "$HOME/.bashrc"' - # sudo -u secdep bash -c 'source "$HOME/.bashrc" && systemctl --user start docker.service' - # sudo runuser - secdep -c 'systemctl --user -M secdep@ enable --now docker.service' - - # sudo loginctl enable-linger secdep - # sudo setcap cap_net_bind_service=ep /home/secdep/bin/rootlesskit - - # sudo runuser - secdep -c "systemctl --host secdep@$IP --user restart docker.service" - # sudo runuser - secdep -c "systemctl --machine=secdep@.host --user restart docker.service" - - # sudo runuser - secdep -c 'sudo setcap cap_net_bind_service=ep "$(which rootlesskit)"' - # sudo -u secdep bash -c 'systemctl --user restart docker.service' - # Create a new docker network to dissalow communication between containers - ##sudo docker network create --driver bridge -o "com.docker.network.bridge.enable_icc"="false" dockerNetworkNoICC +# # Create a new docker network to dissalow communication between containers +# ##sudo docker network create --driver bridge -o "com.docker.network.bridge.enable_icc"="false" dockerNetworkNoICC # Get all arguments passed to the function and store them in the dockerImages array local dockerImages=("$@") - # Check if there is a docker-compose.yml file in the user's home directory - sudo -u secdep bash -c '[[ -f "$HOME/docker-compose.yml" ]] && docker-compose -f "$HOME/docker-compose.yml" up -d' # If there is, run it - # sudo runuser - secdep -c '[[ -f "$HOME/docker-compose.yml" ]] && docker-compose -f "$HOME/docker-compose.yml" up -d' || return 0 # If there is, run it + # Check if there is a docker-compose.yml file in the user's home directory and run it if there is + sudo -u secdep bash -c '[[ -f "$HOME/docker-compose.yml" ]] && docker-compose -f "$HOME/docker-compose.yml" up -d' # Check if the dockerImages array is empty and return 0 if it is [[ "${#dockerImages[@]}" -eq 0 ]] && return 0 - ID=$(id -u secdep) # Loop through the dockerImages array # The dockerImages array contains all the docker images to install and run for dockerImage in "${dockerImages[@]}"; do + # If dockerImage contains a ":" character (if it is a docker image with a tag) + # then store the docker image name in the dockerImageName variable + [[ "$dockerImage" == *":"* ]] && dockerImageName="${dockerImage%:*}" || dockerImageName="$dockerImage" + # Same goes for "/" + [[ "$dockerImageName" == *"/"* ]] && dockerImageName="${dockerImageName%/*}" # No need to pull the docker image as the run command will do it automatically # Run the docker image in the background, # with the restart always option and the name of the docker image @@ -450,13 +327,9 @@ EOF # 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' - CMD="docker run -d --restart always --name $dockerImage --security-opt=no-new-privileges --cap-drop all --cap-add NET_BIND_SERVICE --read-only --tmpfs /home/secdep/opt -v /run/user/$ID/docker.sock:/home/secdep/.docker/run/docker.sock $dockerImage" - # CMD="docker run -d --restart always --name \"$dockerImage\" --security-opt=no-new-privileges --cap-drop all --cap-add NET_BIND_SERVICE --read-only --tmpfs /home/secdep/opt -v /:/host \"$dockerImage\"" - # sudo -u secdep bash -c "$CMD" - sudo runuser - secdep -c "$CMD" - # /home/secdep/bin/docker run -d --restart always --name "$dockerImage" --security-opt=no-new-privileges --cap-drop all --cap-add NET_BIND_SERVICE --read-only --tmpfs /opt -v /:/host "$dockerImage" - ##docker run -d --restart always --name "$dockerImage" --security-opt=no-new-privileges --cap-drop all --cap-add NET_BIND_SERVICE --read-only --tmpfs /opt -v /:/host --network dockerNetworkNoICC "$dockerImage" - #docker run -d --restart always --name "$dockerImage" --security-opt=no-new-privileges --cap-drop all --cap-add NET_ADMIN --user secdep "$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" + sudo -E runuser - secdep -c "$CMD" done } @@ -491,8 +364,6 @@ EOF # sudo systemctl reload apparmor # } - - function configureFail2ban { FAIL2BAN_LOCAL=$(cat <<'EOF' [Definition] @@ -543,9 +414,9 @@ printf "%s" "LogLevel VERBOSE" | sudo tee -a /etc/ssh/sshd_config } function restartServices { - for service in "${services[@]}"; do - sudo systemctl restart "$service" - done + # 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" # For ufw @@ -581,6 +452,8 @@ function main { dockerInit "$@" || exit 1 restartServices || exit 1 printf "%s" "Script finished" # Output message to the user + printf "%s" "Now rebooting" # Output message to the user + sudo reboot } # # The am_i_root function will check if the user is root and exit if they are not.