From 19b1e82504d8c5e617c1cc97c7cae720cf0f15ef Mon Sep 17 00:00:00 2001 From: Opeyemi <54288773+Eebru-gzy@users.noreply.github.com> Date: Tue, 18 Oct 2022 15:23:19 +0100 Subject: [PATCH] update image check script to latest version (#61) * update image check script to latest version * update image check script to latest version * update image check script to latest version * update the packer build file to remove dir * update DO image clean-up * add new way of using homebrew --- .github/workflows/release-digital-ocean.yml | 4 + .../marketplace-image.json | 3 +- .../scripts/99-img-check.sh | 109 ++++++++++-------- 3 files changed, 66 insertions(+), 50 deletions(-) diff --git a/.github/workflows/release-digital-ocean.yml b/.github/workflows/release-digital-ocean.yml index 4e1abd6..e862cab 100644 --- a/.github/workflows/release-digital-ocean.yml +++ b/.github/workflows/release-digital-ocean.yml @@ -54,6 +54,10 @@ jobs: working-directory: ./DigitalOceanMarketplace run: packer build marketplace-image.json + - name: Set up Homebrew + id: set-up-homebrew + uses: Homebrew/actions/setup-homebrew@master + - name: Digital Ocean Image Cleanup env: DIGITALOCEAN_TOKEN: ${{ steps.retrieve-secrets.outputs.digital-ocean-api-key }} diff --git a/DigitalOceanMarketplace/marketplace-image.json b/DigitalOceanMarketplace/marketplace-image.json index e3a20fc..c779784 100644 --- a/DigitalOceanMarketplace/marketplace-image.json +++ b/DigitalOceanMarketplace/marketplace-image.json @@ -61,7 +61,8 @@ "apt -qqy -o Dpkg::Options::='--force-confdef' -o Dpkg::Options::='--force-confold' install {{user `apt_packages_2`}}", "apt -qqy clean", "curl -L \"https://github.com/docker/compose/releases/download/1.29.2/docker-compose-$(uname -s)-$(uname -m)\" -o /usr/local/bin/docker-compose", - "chmod +x /usr/local/bin/docker-compose" + "chmod +x /usr/local/bin/docker-compose", + "rm -rf /opt/digitalocean" ] }, { diff --git a/DigitalOceanMarketplace/scripts/99-img-check.sh b/DigitalOceanMarketplace/scripts/99-img-check.sh index 32a9e77..a95d5cd 100755 --- a/DigitalOceanMarketplace/scripts/99-img-check.sh +++ b/DigitalOceanMarketplace/scripts/99-img-check.sh @@ -1,10 +1,10 @@ #!/bin/bash # DigitalOcean Marketplace Image Validation Tool -# © 2021 DigitalOcean LLC. +# © 2021-2022 DigitalOcean LLC. # This code is licensed under Apache 2.0 license (see LICENSE.md for details) -VERSION="v. 1.6" +VERSION="v. 1.8" RUNDATE=$( date ) # Script should be run with SUDO @@ -31,6 +31,7 @@ cmdExists() { function getDistro { if [ -f /etc/os-release ]; then # freedesktop.org and systemd + # shellcheck disable=SC1091 . /etc/os-release OS=$NAME VER=$VERSION_ID @@ -40,6 +41,7 @@ elif type lsb_release >/dev/null 2>&1; then VER=$(lsb_release -sr) elif [ -f /etc/lsb-release ]; then # For some versions of Debian/Ubuntu without lsb_release command + # shellcheck disable=SC1091 . /etc/lsb-release OS=$DISTRIB_ID VER=$DISTRIB_RELEASE @@ -52,8 +54,8 @@ elif [ -f /etc/SuSe-release ]; then : elif [ -f /etc/redhat-release ]; then # Older Red Hat, CentOS, etc. - VER=$( cat /etc/redhat-release | cut -d" " -f3 | cut -d "." -f1) - d=$( cat /etc/redhat-release | cut -d" " -f1 | cut -d "." -f1) + VER=$(cut -d" " -f3 < /etc/redhat-release | cut -d "." -f1) + d=$(cut -d" " -f1 < /etc/redhat-release | cut -d "." -f1) if [[ $d == "CentOS" ]]; then OS="CentOS Linux" fi @@ -68,15 +70,16 @@ SHADOW=$(cat /etc/shadow) } function checkAgent { - # Check for the presence of the do-agent in the filesystem - if [ -d /var/opt/digitalocean/do-agent ];then - echo -en "\e[41m[FAIL]\e[0m DigitalOcean Monitoring Agent detected.\n" + # Check for the presence of the DO directory in the filesystem + if [ -d /opt/digitalocean ];then + echo -en "\e[41m[FAIL]\e[0m DigitalOcean directory detected.\n" ((FAIL++)) STATUS=2 if [[ $OS == "CentOS Linux" ]] || [[ $OS == "CentOS Stream" ]] || [[ $OS == "Rocky Linux" ]]; then - echo "The agent can be removed with 'sudo yum remove do-agent' " - elif [[ $OS == "Ubuntu" ]]; then - echo "The agent can be removed with 'sudo apt-get purge do-agent' " + echo "To uninstall the agent: 'sudo yum remove droplet-agent'" + echo "To remove the DO directory: 'find /opt/digitalocean/ -type d -empty -delete'" + elif [[ $OS == "Ubuntu" ]] || [[ $OS == "Debian" ]]; then + echo "To uninstall the agent and remove the DO directory: 'sudo apt-get purge droplet-agent'" fi else echo -en "\e[32m[PASS]\e[0m DigitalOcean Monitoring agent was not found\n" @@ -90,8 +93,9 @@ function checkLogs { # Check if there are log archives or log files that have not been recently cleared. for f in /var/log/*-????????; do [[ -e $f ]] || break - if [ $f != $cp_ignore ]; then - echo -en "\e[93m[WARN]\e[0m Log archive ${f} found\n" + if [ "${f}" != "${cp_ignore}" ]; then + echo -en "\e[93m[WARN]\e[0m Log archive ${f} found; Contents:\n" + cat "${f}" ((WARN++)) if [[ $STATUS != 2 ]]; then STATUS=1 @@ -100,7 +104,8 @@ function checkLogs { done for f in /var/log/*.[0-9];do [[ -e $f ]] || break - echo -en "\e[93m[WARN]\e[0m Log archive ${f} found\n" + echo -en "\e[93m[WARN]\e[0m Log archive ${f} found; Contents:\n" + cat "${f}" ((WARN++)) if [[ $STATUS != 2 ]]; then STATUS=1 @@ -108,17 +113,19 @@ function checkLogs { done for f in /var/log/*.log; do [[ -e $f ]] || break - if [[ "${f}" = '/var/log/lfd.log' && "$( cat "${f}" | egrep -v '/var/log/messages has been reset| Watching /var/log/messages' | wc -c)" -gt 50 ]]; then - if [ $f != $cp_ignore ]; then - echo -en "\e[93m[WARN]\e[0m un-cleared log file, ${f} found\n" + if [[ "${f}" = '/var/log/lfd.log' && "$(grep -E -v '/var/log/messages has been reset| Watching /var/log/messages' "${f}" | wc -c)" -gt 50 ]]; then + if [ "${f}" != "${cp_ignore}" ]; then + echo -en "\e[93m[WARN]\e[0m un-cleared log file, ${f} found; Contents:\n" + cat "${f}" ((WARN++)) if [[ $STATUS != 2 ]]; then STATUS=1 fi fi - elif [[ "${f}" != '/var/log/lfd.log' && "$( cat "${f}" | wc -c)" -gt 50 ]]; then - if [ $f != $cp_ignore ]; then - echo -en "\e[93m[WARN]\e[0m un-cleared log file, ${f} found\n" + elif [[ "${f}" != '/var/log/lfd.log' && "$(wc -c < "${f}")" -gt 50 ]]; then + if [ "${f}" != "${cp_ignore}" ]; then + echo -en "\e[93m[WARN]\e[0m un-cleared log file, ${f} found; Contents:\n" + cat "${f}" ((WARN++)) if [[ $STATUS != 2 ]]; then STATUS=1 @@ -151,25 +158,25 @@ function checkRoot { if [ -d ${uhome}/ ]; then if [ -d ${uhome}/.ssh/ ]; then if ls ${uhome}/.ssh/*> /dev/null 2>&1; then - for key in ${uhome}/.ssh/* + for key in "${uhome}"/.ssh/* do if [ "${key}" == "${uhome}/.ssh/authorized_keys" ]; then - if [ "$( cat "${key}" | wc -c)" -gt 50 ]; then + if [ "$(wc -c < "${key}")" -gt 50 ]; then echo -en "\e[41m[FAIL]\e[0m User \e[1m${user}\e[0m has a populated authorized_keys file in \e[93m${key}\e[0m\n" - akey=$(cat ${key}) + akey=$(cat "${key}") echo "File Contents:" - echo $akey + echo "$akey" echo "--------------" ((FAIL++)) STATUS=2 fi elif [ "${key}" == "${uhome}/.ssh/id_rsa" ]; then - if [ "$( cat "${key}" | wc -c)" -gt 0 ]; then + if [ "$(wc -c < "${key}")" -gt 0 ]; then echo -en "\e[41m[FAIL]\e[0m User \e[1m${user}\e[0m has a private key file in \e[93m${key}\e[0m\n" - akey=$(cat ${key}) + akey=$(cat "${key}") echo "File Contents:" - echo $akey + echo "$akey" echo "--------------" ((FAIL++)) STATUS=2 @@ -187,7 +194,7 @@ function checkRoot { STATUS=1 fi else - if [ "$( cat "${key}" | wc -c)" -gt 50 ]; then + if [ "$(wc -c < "${key}")" -gt 50 ]; then echo -en "\e[93m[WARN]\e[0m User \e[1m${user}\e[0m has a populated known_hosts file in \e[93m${key}\e[0m\n" ((WARN++)) if [[ $STATUS != 2 ]]; then @@ -204,7 +211,7 @@ function checkRoot { fi if [ -f /root/.bash_history ];then - BH_S=$( cat /root/.bash_history | wc -c) + BH_S=$(wc -c < /root/.bash_history) if [[ $BH_S -lt 200 ]]; then echo -en "\e[32m[PASS]\e[0m ${user}'s Bash History appears to have been cleared\n" @@ -229,7 +236,7 @@ function checkRoot { function checkUsers { # Check each user-created account - for user in $(awk -F: '$3 >= 1000 && $1 != "nobody" {print $1}' /etc/passwd;) + awk -F: '$3 >= 1000 && $1 != "nobody" {print $1}' < /etc/passwd | while IFS= read -r user; do # Skip some other non-user system accounts if [[ $user == "centos" ]]; then @@ -244,9 +251,11 @@ function checkUsers { if [[ "${u[0]}" == "${user}" ]]; then if [[ ${u[1]} == "!" ]] || [[ ${u[1]} == "!!" ]] || [[ ${u[1]} == "*" ]]; then echo -en "\e[32m[PASS]\e[0m User ${user} has no password set.\n" + # shellcheck disable=SC2030 ((PASS++)) else echo -en "\e[41m[FAIL]\e[0m User ${user} has a password set on their account. Only system users are allowed on the image.\n" + # shellcheck disable=SC2030 ((FAIL++)) STATUS=2 fi @@ -257,29 +266,30 @@ function checkUsers { if [ -d "${uhome}/" ]; then if [ -d "${uhome}/.ssh/" ]; then if ls "${uhome}/.ssh/*"> /dev/null 2>&1; then - for key in ${uhome}/.ssh/* + for key in "${uhome}"/.ssh/* do if [ "${key}" == "${uhome}/.ssh/authorized_keys" ]; then - if [ "$( cat "${key}" | wc -c)" -gt 50 ]; then + if [ "$(wc -c < "${key}")" -gt 50 ]; then echo -en "\e[41m[FAIL]\e[0m User \e[1m${user}\e[0m has a populated authorized_keys file in \e[93m${key}\e[0m\n" - akey=$(cat ${key}) + akey=$(cat "${key}") echo "File Contents:" - echo $akey + echo "$akey" echo "--------------" ((FAIL++)) STATUS=2 fi elif [ "${key}" == "${uhome}/.ssh/id_rsa" ]; then - if [ "$( cat "${key}" | wc -c)" -gt 0 ]; then + if [ "$(wc -c < "${key}")" -gt 0 ]; then echo -en "\e[41m[FAIL]\e[0m User \e[1m${user}\e[0m has a private key file in \e[93m${key}\e[0m\n" - akey=$(cat ${key}) + akey=$(cat "${key}") echo "File Contents:" - echo $akey + echo "$akey" echo "--------------" ((FAIL++)) STATUS=2 else echo -en "\e[93m[WARN]\e[0m User \e[1m${user}\e[0m has empty private key file in \e[93m${key}\e[0m\n" + # shellcheck disable=SC2030 ((WARN++)) if [[ $STATUS != 2 ]]; then STATUS=1 @@ -294,7 +304,7 @@ function checkUsers { fi else - if [ "$( cat "${key}" | wc -c)" -gt 50 ]; then + if [ "$(wc -c < "${key}")" -gt 50 ]; then echo -en "\e[93m[WARN]\e[0m User \e[1m${user}\e[0m has a known_hosts file in \e[93m${key}\e[0m\n" ((WARN++)) if [[ $STATUS != 2 ]]; then @@ -317,7 +327,7 @@ function checkUsers { # Check for an uncleared .bash_history for this user if [ -f "${uhome}/.bash_history" ]; then - BH_S=$( cat "${uhome}/.bash_history" | wc -c ) + BH_S=$(wc -c < "${uhome}/.bash_history") if [[ $BH_S -lt 200 ]]; then echo -en "\e[32m[PASS]\e[0m ${user}'s Bash History appears to have been cleared\n" @@ -340,9 +350,11 @@ function checkFirewall { ufwa=$(ufw status |head -1| sed -e "s/^Status:\ //") if [[ $ufwa == "active" ]]; then FW_VER="\e[32m[PASS]\e[0m Firewall service (${fw}) is active\n" + # shellcheck disable=SC2031 ((PASS++)) else FW_VER="\e[93m[WARN]\e[0m No firewall is configured. Ensure ${fw} is installed and configured\n" + # shellcheck disable=SC2031 ((WARN++)) fi elif [[ $OS == "CentOS Linux" ]] || [[ $OS == "CentOS Stream" ]] || [[ $OS == "Rocky Linux" ]]; then @@ -399,7 +411,7 @@ function checkFirewall { else # user could be using vanilla iptables, check if kernel module is loaded fw="iptables" - if [[ $(lsmod | grep -q '^ip_tables' 2>/dev/null) ]]; then + if lsmod | grep -q '^ip_tables' 2>/dev/null; then FW_VER="\e[32m[PASS]\e[0m Firewall service (${fw}) is active\n" ((PASS++)) else @@ -423,9 +435,9 @@ function checkUpdates { echo -en "\nUpdating apt package database to check for security updates, this may take a minute...\n\n" apt-get -y update > /dev/null - uc=$(apt-get --just-print upgrade | grep -i "security" | wc -l) + uc=$(apt-get --just-print upgrade | grep -i "security" -c) if [[ $uc -gt 0 ]]; then - update_count=$(( ${uc} / 2 )) + update_count=$(( uc / 2 )) else update_count=0 fi @@ -437,10 +449,12 @@ function checkUpdates { sleep 2 apt-get --just-print upgrade | grep -i security | awk '{print $2}' | awk '!seen[$0]++' echo -en + # shellcheck disable=SC2031 ((FAIL++)) STATUS=2 else echo -en "\e[32m[PASS]\e[0m There are no pending security updates for this image.\n\n" + ((PASS++)) fi elif [[ $OS == "CentOS Linux" ]] || [[ $OS == "CentOS Stream" ]] || [[ $OS == "Rocky Linux" ]]; then echo -en "\nChecking for available security updates, this may take a minute...\n\n" @@ -492,14 +506,8 @@ osv=0 if [[ $OS == "Ubuntu" ]]; then ost=1 - if [[ $VER == "20.04" ]]; then - osv=1 - elif [[ $VER == "18.04" ]]; then - osv=1 - elif [[ $VER == "16.04" ]]; then + if [[ $VER == "22.04" ]] || [[ $VER == "20.04" ]] || [[ $VER == "18.04" ]] || [[ $VER == "16.04" ]]; then osv=1 - else - osv=0 fi elif [[ "$OS" =~ Debian.* ]]; then @@ -511,6 +519,9 @@ elif [[ "$OS" =~ Debian.* ]]; then 10) osv=1 ;; + 11) + osv=1 + ;; *) osv=2 ;; @@ -536,7 +547,7 @@ elif [[ $OS == "CentOS Stream" ]]; then fi elif [[ $OS == "Rocky Linux" ]]; then ost=1 - if [[ $VER =~ "8." ]]; then + if [[ $VER =~ 8\. ]]; then osv=1 else osv=2