diff --git a/kickstart/veilor-os.ks b/kickstart/veilor-os.ks index b5be79d..85caef6 100644 --- a/kickstart/veilor-os.ks +++ b/kickstart/veilor-os.ks @@ -119,6 +119,12 @@ chrony firewalld plymouth +# AppArmor stack — Fedora 43 ships parser/utils/profiles. v0.6 ships +# loaded-but-complain only (see scripts/40-apparmor.sh + tier-2 plan). +apparmor-parser +apparmor-utils +apparmor-profiles + # admin essentials git vim-enhanced diff --git a/overlay/etc/apparmor.d/veilor.d/firefox b/overlay/etc/apparmor.d/veilor.d/firefox new file mode 100644 index 0000000..29675bf --- /dev/null +++ b/overlay/etc/apparmor.d/veilor.d/firefox @@ -0,0 +1,11 @@ +# veilor-os AppArmor profile stub — firefox +# +# v0.6 scope: marker only. Loads in complain mode via scripts/40-apparmor.sh +# so AppArmor can log the syscall surface for v0.7 policy authoring. No +# actual confinement rules yet — full policy is post-v0.6. + +#include + +profile veilor-firefox /usr/lib*/firefox/firefox flags=(complain) { + #include +} diff --git a/overlay/etc/apparmor.d/veilor.d/thunderbird b/overlay/etc/apparmor.d/veilor.d/thunderbird new file mode 100644 index 0000000..46fe2ee --- /dev/null +++ b/overlay/etc/apparmor.d/veilor.d/thunderbird @@ -0,0 +1,11 @@ +# veilor-os AppArmor profile stub — thunderbird +# +# v0.6 scope: marker only. Loads in complain mode via scripts/40-apparmor.sh +# so AppArmor can log the syscall surface for v0.7 policy authoring. No +# actual confinement rules yet — full policy is post-v0.6. + +#include + +profile veilor-thunderbird /usr/lib*/thunderbird/thunderbird flags=(complain) { + #include +} diff --git a/overlay/usr/local/bin/veilor-installer b/overlay/usr/local/bin/veilor-installer index 999766a..4e660b8 100644 --- a/overlay/usr/local/bin/veilor-installer +++ b/overlay/usr/local/bin/veilor-installer @@ -488,6 +488,12 @@ chrony firewalld plymouth +# AppArmor stack — Fedora 43 ships parser/utils/profiles. v0.6 ships +# loaded-but-complain only (see scripts/40-apparmor.sh + tier-2 plan). +apparmor-parser +apparmor-utils +apparmor-profiles + # admin essentials git vim-enhanced diff --git a/scripts/40-apparmor.sh b/scripts/40-apparmor.sh new file mode 100644 index 0000000..898db05 --- /dev/null +++ b/scripts/40-apparmor.sh @@ -0,0 +1,77 @@ +#!/usr/bin/env bash +# veilor-os — 40-apparmor: load veilor-shipped AppArmor profiles in +# COMPLAIN mode. v0.6 scope: "loaded, present, nothing breaks". +# +# Per docs/research/2026-05-05-agent-wave/04-hardening-tier-2.md, v0.6 +# ships AppArmor stacked alongside SELinux, but every veilor-shipped +# profile stays in complain mode (logs only, no enforce). Real policy +# authoring is post-v0.6. +# +# Idempotent: profiles already in complain mode are skipped. Run as +# root during kickstart %post or post-install. + +set -uo pipefail + +GREEN='\033[0;32m'; YELLOW='\033[1;33m'; RED='\033[0;31m'; NC='\033[0m' +ok() { echo -e "${GREEN}[OK]${NC} $*"; } +info() { echo -e "${YELLOW}[INFO]${NC} $*"; } +warn() { echo -e "${YELLOW}[WARN]${NC} $*"; } +err() { echo -e "${RED}[ERR]${NC} $*"; } + +[[ $EUID -eq 0 ]] || { err "Must run as root"; exit 1; } + +echo "════════════════════════════════════════════════════════" +echo " veilor-os :: 40-apparmor (complain mode only)" +echo "════════════════════════════════════════════════════════" + +PROFILE_DIR=/etc/apparmor.d/veilor.d + +# ── Sanity: tools present? ── +if ! command -v apparmor_parser >/dev/null 2>&1; then + warn "apparmor_parser not installed — skipping (package step missed?)" + exit 0 +fi +if ! command -v aa-complain >/dev/null 2>&1; then + warn "aa-complain not installed (apparmor-utils missing) — skipping" + exit 0 +fi + +if [[ ! -d $PROFILE_DIR ]]; then + info "$PROFILE_DIR not present — no veilor profiles to load" + exit 0 +fi + +# ── Walk every profile we ship and force complain mode ── +shopt -s nullglob +loaded=0 +skipped=0 +failed=0 + +for profile in "$PROFILE_DIR"/*; do + [[ -f $profile ]] || continue + name=$(basename "$profile") + + # Already in complain mode? aa-status reports loaded profiles by + # internal profile name, not file path — best-effort match against + # the file basename to avoid re-parsing on repeat runs. + if command -v aa-status >/dev/null 2>&1 \ + && aa-status --complaining 2>/dev/null | grep -qE "(^|/)veilor-${name}([[:space:]]|$)"; then + info "$name already in complain mode — skipping" + skipped=$((skipped + 1)) + continue + fi + + info "loading $name (complain mode)" + if aa-complain "$profile" >/dev/null 2>&1; then + ok "$name → complain" + loaded=$((loaded + 1)) + else + warn "$name failed to load (parser may reject stub on this kernel)" + failed=$((failed + 1)) + fi +done + +echo "────────────────────────────────────────────────────────" +info "summary: loaded=$loaded skipped=$skipped failed=$failed" +ok "v0.6 AppArmor stub: complain-mode only — no enforcement, log-only" +exit 0