diff --git a/AzureMarketplace/marketplace-image.pkr.hcl b/AzureMarketplace/marketplace-image.pkr.hcl index 16d0067..5ab93bd 100644 --- a/AzureMarketplace/marketplace-image.pkr.hcl +++ b/AzureMarketplace/marketplace-image.pkr.hcl @@ -174,16 +174,12 @@ build { ] } - # Upgrade Azure Linux Agent from Microsoft's package repository to meet minimum version requirement provisioner "shell" { - environment_vars = [ - "DEBIAN_FRONTEND=noninteractive", - ] + environment_vars = ["DEBIAN_FRONTEND=noninteractive"] inline = [ - "curl -fsSL https://packages.microsoft.com/keys/microsoft.asc | sudo gpg --dearmor -o /etc/apt/keyrings/microsoft.gpg", - "echo \"deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/microsoft.gpg] https://packages.microsoft.com/ubuntu/24.04/prod noble main\" | sudo tee /etc/apt/sources.list.d/microsoft-prod.list > /dev/null", - "sudo apt-get -qqy update", - "sudo apt-get -qqy -o Dpkg::Options::='--force-confdef' -o Dpkg::Options::='--force-confold' install walinuxagent" + "sudo apt-get -qqy -o Dpkg::Options::='--force-confdef' -o Dpkg::Options::='--force-confold' install walinuxagent", + "sudo systemctl enable walinuxagent", + "waagent --version", ] } @@ -207,9 +203,14 @@ build { # Azure-specific cleanup provisioner "shell" { - execute_command = "chmod +x {{ .Path }}; {{ .Vars }} sudo -E bash '{{ .Path }}'" + execute_command = "chmod +x {{ .Path }}; {{ .Vars }} sudo -E bash '{{ .Path }}'" + environment_vars = [ + "HISTFILE=/dev/null", + "HISTSIZE=0", + ] inline = [ - "truncate -s 0 /var/log/waagent.log 2>/dev/null || true" + "truncate -s 0 /var/log/waagent.log 2>/dev/null || true", + "find / -xdev -name '.bash_history' -type f -delete 2>/dev/null || true", ] } diff --git a/AzureMarketplace/scripts/99-img-check.sh b/AzureMarketplace/scripts/99-img-check.sh index 05deb5d..0f4bb18 100644 --- a/AzureMarketplace/scripts/99-img-check.sh +++ b/AzureMarketplace/scripts/99-img-check.sh @@ -2,6 +2,10 @@ # Azure Marketplace Image Validation Tool +# Prevent this script from writing to bash history +unset HISTFILE +export HISTSIZE=0 + VERSION="v. 1.0.0" RUNDATE=$( date ) @@ -73,6 +77,16 @@ else STATUS=2 fi +# Check Azure Linux Agent service is enabled (will start on the deployed VM) +if systemctl is-enabled walinuxagent >/dev/null 2>&1; then + echo -en "\e[32m[PASS]\e[0m Azure Linux Agent service is enabled.\n" + ((PASS++)) +else + echo -en "\e[41m[FAIL]\e[0m Azure Linux Agent service is not enabled.\n" + ((FAIL++)) + STATUS=2 +fi + # Check Docker if hash docker 2>/dev/null; then echo -en "\e[32m[PASS]\e[0m Docker is installed.\n" @@ -142,7 +156,7 @@ else fi # Check SSH ClientAliveInterval (Azure requirement: 30-235 seconds) -ALIVE_INTERVAL=$(grep -i "^ClientAliveInterval" /etc/ssh/sshd_config | awk '{print $2}' | tail -1) +ALIVE_INTERVAL=$(sshd -T 2>/dev/null | awk '/^clientaliveinterval/{print $2}') if [[ -n "${ALIVE_INTERVAL}" ]] && [[ "${ALIVE_INTERVAL}" -ge 30 ]] && [[ "${ALIVE_INTERVAL}" -le 235 ]]; then echo -en "\e[32m[PASS]\e[0m SSH ClientAliveInterval is ${ALIVE_INTERVAL} seconds (30-235 required).\n" ((PASS++)) @@ -163,20 +177,24 @@ else STATUS=2 fi -# Check bash history -if [ -f /root/.bash_history ]; then - BH_S=$(wc -c < /root/.bash_history) - if [[ $BH_S -lt 200 ]]; then - echo -en "\e[32m[PASS]\e[0m Root bash history appears cleared.\n" - ((PASS++)) - else - echo -en "\e[41m[FAIL]\e[0m Root bash history should be cleared.\n" - ((FAIL++)) - STATUS=2 - fi -else - echo -en "\e[32m[PASS]\e[0m Root bash history is not present.\n" +# Check waagent will not recreate swap on first boot of the deployed VM. +if [ -f /etc/waagent.conf ] && grep -q "^ResourceDisk.EnableSwap=n" /etc/waagent.conf; then + echo -en "\e[32m[PASS]\e[0m waagent ResourceDisk.EnableSwap is disabled.\n" ((PASS++)) +else + echo -en "\e[41m[FAIL]\e[0m waagent will recreate swap on first boot (ResourceDisk.EnableSwap is not 'n').\n" + ((FAIL++)) + STATUS=2 +fi + +# Check bash history — Azure tests for file existence, not size. +if [ ! -f /root/.bash_history ] && [ ! -f /home/ubuntu/.bash_history ]; then + echo -en "\e[32m[PASS]\e[0m No bash history files present.\n" + ((PASS++)) +else + echo -en "\e[41m[FAIL]\e[0m bash history file present (must be deleted, not truncated).\n" + ((FAIL++)) + STATUS=2 fi # Check cloud-init first-boot script is present and executable diff --git a/CommonMarketplace/scripts/90-cleanup.sh b/CommonMarketplace/scripts/90-cleanup.sh index c1dea46..81641ec 100644 --- a/CommonMarketplace/scripts/90-cleanup.sh +++ b/CommonMarketplace/scripts/90-cleanup.sh @@ -4,6 +4,10 @@ set -o errexit +# Prevent this script from writing to bash history +unset HISTFILE +export HISTSIZE=0 + # Ensure /tmp exists and has the proper permissions if [ ! -d /tmp ]; then mkdir /tmp @@ -18,19 +22,35 @@ if [ -n "$(command -v apt-get)" ]; then apt-get -y autoclean fi -# Disable swap (marketplace requirement: no swap on OS disk) +# Disable swap (marketplace requirement: no swap on OS disk). +# Build-time: clear current swap and fstab. swapoff -a 2>/dev/null || true sed -i '/\bswap\b/d' /etc/fstab if [ -f /swapfile ]; then rm -f /swapfile fi - -# Configure SSH client alive interval (Azure requirement: 30-235 seconds) -if grep -q "^#*\s*ClientAliveInterval" /etc/ssh/sshd_config; then - sed -i 's/^#*\s*ClientAliveInterval.*/ClientAliveInterval 120/' /etc/ssh/sshd_config -else - echo "ClientAliveInterval 120" >> /etc/ssh/sshd_config +# Boot-time: tell waagent not to create resource-disk swap on first boot. +if [ -f /etc/waagent.conf ]; then + sed -i 's/^ResourceDisk\.EnableSwap=.*/ResourceDisk.EnableSwap=n/' /etc/waagent.conf + sed -i 's/^ResourceDisk\.SwapSizeMB=.*/ResourceDisk.SwapSizeMB=0/' /etc/waagent.conf fi +# Boot-time: tell cloud-init not to create /swap.img. +cat > /etc/cloud/cloud.cfg.d/99-disable-swap.cfg <<'EOF' +swap: + filename: /swap.img + size: 0 + maxsize: 0 +EOF +chmod 644 /etc/cloud/cloud.cfg.d/99-disable-swap.cfg + +# Configure SSH client alive interval (Azure requirement: 30-235 seconds). +# Use a drop-in that sorts before /etc/ssh/sshd_config.d/50-cloud-init.conf so +# this setting wins — sshd uses the first occurrence of each directive. +cat > /etc/ssh/sshd_config.d/10-azure-marketplace.conf <<'EOF' +ClientAliveInterval 120 +ClientAliveCountMax 3 +EOF +chmod 644 /etc/ssh/sshd_config.d/10-azure-marketplace.conf rm -rf /tmp/* /var/tmp/*