#!/usr/bin/env bash
# audit-baseline.sh — kumpulkan baseline keamanan server ke satu laporan.
#
# Pemakaian:
#   audit-baseline.sh <dir-data> > laporan-audit.txt
#
# <dir-data> adalah miniatur filesystem server yang berisi snapshot:
#   services.txt      systemctl list-units --type=service
#                     --state=running --no-pager --no-legend
#   port-terbuka.txt  ss -tlnH
#   passwd            cuplikan /etc/passwd
#   upgradable.txt    apt list --upgradable
#   home/<user>/...   home directory tiap user (untuk authorized_keys)
#
# Kode keluar:
#   0  laporan berhasil dihasilkan (temuan dibaca isinya, bukan kodenya)
#   1  pemakaian salah: argumen hilang atau snapshot tidak lengkap

set -u

if [ "$#" -ne 1 ]; then
    printf 'pemakaian: audit-baseline.sh <dir-data>\n' >&2
    exit 1
fi
DATA=$1
if [ ! -d "$DATA" ]; then
    printf 'audit-baseline.sh: folder data tidak ditemukan: %s\n' "$DATA" >&2
    exit 1
fi
for berkas in services.txt port-terbuka.txt passwd upgradable.txt; do
    if [ ! -f "$DATA/$berkas" ]; then
        printf 'audit-baseline.sh: berkas snapshot hilang: %s/%s\n' \
            "$DATA" "$berkas" >&2
        exit 1
    fi
done

printf '===== AUDIT BASELINE KEAMANAN =====\n'
printf 'sumber data: %s\n\n' "$DATA"

# --- [1] service yang sedang berjalan ---------------------------------
jumlah_service=$(awk '$4 == "running" { c++ } END { print c + 0 }' \
    "$DATA/services.txt")
printf '[1] SERVICE BERJALAN: %d\n' "$jumlah_service"
awk '$4 == "running" { print $1 }' "$DATA/services.txt" | sort |
    sed 's/^/    /'
printf '\n'

# --- [2] port TCP yang terbuka ----------------------------------------
jumlah_port=$(grep -c . "$DATA/port-terbuka.txt")
printf '[2] PORT TCP TERBUKA: %d\n' "$jumlah_port"
awk '{
    ket = "semua interface"
    if (substr($4, 1, 4) == "127.")
        ket = "loopback saja"
    printf "    %-15s %s\n", $4, ket
}' "$DATA/port-terbuka.txt"
printf '\n'

# --- [3] user yang punya shell login ----------------------------------
jumlah_user=$(awk -F: '$7 !~ /(nologin|false)$/ { c++ } END { print c + 0 }' \
    "$DATA/passwd")
printf '[3] USER DENGAN SHELL LOGIN: %d\n' "$jumlah_user"
awk -F: '$7 !~ /(nologin|false)$/ { printf "    %-8s %s\n", $1, $7 }' \
    "$DATA/passwd"
printf '\n'

# --- [4] kunci SSH per user --------------------------------------------
printf '[4] KUNCI SSH PER USER:\n'
awk -F: '$7 !~ /(nologin|false)$/ { print $1, $6 }' "$DATA/passwd" |
while read -r user home; do
    kunci="$DATA$home/.ssh/authorized_keys"
    if [ -f "$kunci" ]; then
        printf '    %-8s %d kunci\n' "$user" "$(grep -c . "$kunci")"
    else
        printf '    %-8s tanpa authorized_keys\n' "$user"
    fi
done
printf '\n'

# --- [5] paket yang tertinggal pembaruan --------------------------------
jumlah_paket=$(grep -c 'upgradable from' "$DATA/upgradable.txt")
printf '[5] PAKET SIAP DIPERBARUI: %d\n' "$jumlah_paket"
grep 'upgradable from' "$DATA/upgradable.txt" | awk '{ print "    " $1 }'
printf '\n'

# --- ringkasan temuan ----------------------------------------------------
jumlah_luar=$(awk '{ if (substr($4, 1, 4) != "127.") c++ }
    END { print c + 0 }' "$DATA/port-terbuka.txt")
tanpa_kunci=$(awk -F: '$7 !~ /(nologin|false)$/ { print $1, $6 }' \
    "$DATA/passwd" |
while read -r user home; do
    [ -f "$DATA$home/.ssh/authorized_keys" ] || printf '%s\n' "$user"
done | paste -sd' ' -)
jumlah_tanpa=$(printf '%s' "$tanpa_kunci" | wc -w)
printf 'RINGKASAN TEMUAN:\n'
printf '    - %d port mendengarkan di semua interface (terjangkau dari luar)\n' \
    "$jumlah_luar"
printf '    - %d akun shell tanpa authorized_keys: %s\n' \
    "$jumlah_tanpa" "$tanpa_kunci"
printf '    - %d paket tertinggal pembaruan\n' "$jumlah_paket"
exit 0
