#!/bin/bash # ansipa-smb-setup.sh — configure the Samba scan-results and LUKS-key shares on the IPA container. # # Runs on every container start via ansipa-smb.service so that smb.conf and # Samba users are always in place after container restarts (ephemeral rootfs). # # Password sources (first match wins per variable): # 1. Environment variable (first boot / explicit override) # 2. /data/samba/ansipa-smb.env (persisted from first boot) # # Shares: # ansipa-scans — write-only for 'scanupload'; clients push scan results here. # ansipa-luks-keys — write-only for 'luks-upload' (Ansible controller); # read for members of the 'KeyAdmin' Linux group. # Add a Samba user to KeyAdmin to grant key-read access: # useradd -r -G KeyAdmin # smbpasswd -a set -euo pipefail LOG_TAG="ansipa-smb-setup" SCAN_BASE="/data/scan-results" LUKS_BASE="/data/luks-keys" SMB_CONF="/etc/samba/smb.conf" SMB_USER="scanupload" LUKS_UPLOAD_USER="luks-upload" KEYADMIN_GROUP="KeyAdmin" ENV_FILE="/data/samba/ansipa-smb.env" log() { echo "[$LOG_TAG] $*"; } die() { echo "[$LOG_TAG][ERROR] $*" >&2; exit 1; } # ── Resolve passwords ───────────────────────────────────────────────────────── SMB_PASS="${SMB_SCAN_PASSWORD:-}" LUKS_PASS="${LUKS_KEY_UPLOAD_PASSWORD:-}" if [[ -f "$ENV_FILE" ]]; then # shellcheck source=/dev/null source "$ENV_FILE" SMB_PASS="${SMB_SCAN_PASSWORD:-$SMB_PASS}" LUKS_PASS="${LUKS_KEY_UPLOAD_PASSWORD:-$LUKS_PASS}" fi [[ -z "$SMB_PASS" ]] && die "SMB_SCAN_PASSWORD not set and $ENV_FILE not present. Set it in .env." [[ -z "$LUKS_PASS" ]] && die "LUKS_KEY_UPLOAD_PASSWORD not set and $ENV_FILE not present. Set it in .env." # ── Persist for subsequent restarts ────────────────────────────────────────── mkdir -p "$(dirname "$ENV_FILE")" { printf 'SMB_SCAN_PASSWORD=%q\n' "$SMB_PASS" printf 'LUKS_KEY_UPLOAD_PASSWORD=%q\n' "$LUKS_PASS" } > "$ENV_FILE" chmod 600 "$ENV_FILE" # ── Directory structure (idempotent) ────────────────────────────────────────── mkdir -p "$SCAN_BASE/archive" "$SCAN_BASE/alerts" mkdir -p "$LUKS_BASE" # ── KeyAdmin group ──────────────────────────────────────────────────────────── if ! getent group "$KEYADMIN_GROUP" &>/dev/null; then groupadd -r "$KEYADMIN_GROUP" log "Created group: $KEYADMIN_GROUP" fi # ── System users ────────────────────────────────────────────────────────────── if ! id "$SMB_USER" &>/dev/null; then useradd -r -s /sbin/nologin -d "$SCAN_BASE" -M "$SMB_USER" log "Created system user: $SMB_USER" fi if ! id "$LUKS_UPLOAD_USER" &>/dev/null; then useradd -r -s /sbin/nologin -d "$LUKS_BASE" -M -G "$KEYADMIN_GROUP" "$LUKS_UPLOAD_USER" log "Created system user: $LUKS_UPLOAD_USER (member of $KEYADMIN_GROUP)" else # Ensure group membership is correct after container recreations usermod -aG "$KEYADMIN_GROUP" "$LUKS_UPLOAD_USER" fi chown -R "$SMB_USER:$SMB_USER" "$SCAN_BASE" chown -R "root:$KEYADMIN_GROUP" "$LUKS_BASE" chmod 2750 "$LUKS_BASE" # setgid so new files inherit KeyAdmin group # ── smb.conf ────────────────────────────────────────────────────────────────── log "Writing $SMB_CONF" cat > "$SMB_CONF" </dev/null || \ printf '%s\n%s\n' "$pass" "$pass" | smbpasswd -s "$user" 2>/dev/null || \ log "WARN: smbpasswd returned non-zero for $user (may already be set correctly)" } _smb_set_pass "$SMB_USER" "$SMB_PASS" _smb_set_pass "$LUKS_UPLOAD_USER" "$LUKS_PASS" # ── Server-side scan checker cron (hourly, analysed on the IPA server itself) ─ # Always (re-)write: /etc/cron.d is on the ephemeral container layer and is # lost on container recreation, so we must restore it on every start. cat > /etc/cron.d/ansipa-check-scans <<'CRON' # ansipa: analyze client scan logs and write alerts — managed, do not edit. 0 * * * * root /usr/local/sbin/ansipa-check-scans.sh 2>&1 | logger -t ansipa-check-scans CRON chmod 644 /etc/cron.d/ansipa-check-scans log "Installed hourly scan-checker cron" log "Samba setup complete. Share: //localhost/ansipa-scans user: $SMB_USER"