#!/bin/bash # Integration Test 02: Security Compliance # Verifica INF-01, INF-02, INF-03, INF-04 su TUTTI i lab set -euo pipefail # Colori RED='\033[0;31m' GREEN='\033[0;32m' YELLOW='\033[1;33m' BLUE='\033[0;34m' NC='\033[0m' pass_count=0 fail_count=0 skip_count=0 inc_pass() { ((pass_count++)) || true; } inc_fail() { ((fail_count++)) || true; } inc_skip() { ((skip_count++)) || true; } echo "==========================================" echo "Integration Test 02: Security Compliance" echo "==========================================" echo "" # Array di tutti i lab con docker-compose labs_with_compose=("lab-03-compute" "lab-04-storage" "lab-05-database") echo "=== INF-01: Nessun container gira come root ===" echo "" for lab in "${labs_with_compose[@]}"; do compose_file="labs/$lab/docker-compose.yml" if [ ! -f "$compose_file" ]; then continue fi echo -n "[TEST] $lab - non-root containers... " # Verifica che non ci sia 'user: root' o simili if grep -q "user: root" "$compose_file"; then echo -e "${RED}FAIL${NC} (user: root trovato)" inc_fail # PostgreSQL official image non gira come root elif grep -q "image: postgres" "$compose_file"; then echo -e "${GREEN}PASS${NC} (PostgreSQL non gira come root)" inc_pass # Alpine images default to root, ma i nostri Dockerfile creano utenti elif grep -q "adduser\|addgroup" "$compose_file" 2>/dev/null || \ [ -f "labs/$lab/Dockerfile" ] && grep -q "adduser\|addgroup" "labs/$lab/Dockerfile"; then echo -e "${GREEN}PASS${NC} (utente non-root configurato)" inc_pass else echo -e "${YELLOW}WARN${NC} (impossibile verificare automaticamente)" inc_skip fi done echo "" echo "=== INF-02: Reti private non espongono porte sull'host ===" echo "" labs_with_private=("lab-02-network" "lab-05-database") for lab in "${labs_with_private[@]}"; do compose_file="labs/$lab/docker-compose.yml" if [ ! -f "$compose_file" ]; then continue fi echo -n "[TEST] $lab - private network ports... " # Cerca database o servizi in rete privata if grep -A 20 "db:" "$compose_file" | grep -q "ports:"; then # Se ci sono porte, verifica che siano 127.0.0.1 if grep -A 20 "db:" "$compose_file" | grep -A 5 "ports:" | grep -q "127.0.0.1"; then echo -e "${YELLOW}WARN${NC} (porta su 127.0.0.1 - RDS non expone porte)" inc_skip else echo -e "${RED}FAIL${NC} (porta esposta su host)" inc_fail fi else echo -e "${GREEN}PASS${NC} (nessuna porta esposta)" inc_pass fi done echo "" echo "=== INF-03: Tutti i container hanno limiti risorse ===" echo "" for lab in "${labs_with_compose[@]}"; do compose_file="labs/$lab/docker-compose.yml" if [ ! -f "$compose_file" ]; then continue fi echo -n "[TEST] $lab - resource limits... " # Verifica deploy.resources per ogni servizio services=$(grep "^ [a-z]*:" "$compose_file" | grep -v "^ #" | sed 's/://g' | grep -v "^networks\|^volumes") all_limited=true for service in $services; do if grep -A 30 "^ $service:" "$compose_file" | grep -q "deploy:"; then if grep -A 30 "^ $service:" "$compose_file" | grep -A 10 "deploy:" | grep -q "cpus:" && \ grep -A 30 "^ $service:" "$compose_file" | grep -A 10 "deploy:" | grep -q "memory:"; then : # service has limits else all_limited=false break fi else all_limited=false break fi done if $all_limited; then echo -e "${GREEN}PASS${NC}" inc_pass else echo -e "${RED}FAIL${NC} (alcuni servizi senza limiti)" inc_fail fi done echo "" echo "=== INF-04: Dati persistenti in volumi nominativi ===" echo "" labs_with_volumes=("lab-04-storage" "lab-05-database") for lab in "${labs_with_volumes[@]}"; do compose_file="labs/$lab/docker-compose.yml" if [ ! -f "$compose_file" ]; then continue fi echo -n "[TEST] $lab - named volumes... " # Verifica sezioni volumes definita if grep -q "^volumes:" "$compose_file"; then # Verifica che i volumi usino driver local if grep -A 10 "^volumes:" "$compose_file" | grep -q "driver: local"; then echo -e "${GREEN}PASS${NC}" inc_pass else echo -e "${YELLOW}WARN${NC} (volumi definiti ma driver non verificato)" inc_skip fi else echo -e "${RED}FAIL${NC} (nessun volume definito)" inc_fail fi done echo "" echo "=== Verifica Container in Esecuzione ===" echo "" running_containers=$(docker ps --format '{{{{Names}}}}' | grep -E "lab0[1-5]" | wc -l) echo -n "[TEST] Container in esecuzione... " if [ $running_containers -gt 0 ]; then echo -e "${GREEN}PASS${NC} ($running_containers container)" inc_pass # Verifica non-root per container in esecuzione echo "" echo "[TEST] Verifica non-root per container in esecuzione..." for container in $(docker ps --format '{{{{Names}}}}' | grep -E "lab0[1-5]"); do container_user=$(docker exec $container whoami 2>/dev/null || echo "unknown") echo -n " $container: utente=$container_user... " if [ "$container_user" != "root" ]; then echo -e "${GREEN}OK${NC}" inc_pass else echo -e "${RED}FAIL${NC}" inc_fail fi done else echo -e "${YELLOW}SKIP${NC} (nessun container in esecuzione)" inc_skip fi echo "" echo "==========================================" echo "Risultato: $pass_count PASS, $fail_count FAIL, $skip_count SKIP" echo "==========================================" if [ $fail_count -gt 0 ]; then echo "" echo -e "${RED}✗ SECURITY COMPLIANCE FAIL${NC}" echo "Risolvere le violazioni INF prima di procedere" exit 1 fi exit 0