126 lines
5.1 KiB
Markdown
126 lines
5.1 KiB
Markdown
|
|
# Hardening tier 2 — concrete plan
|
|||
|
|
|
|||
|
|
**Agent 4 of 9-agent wave, 2026-05-05.**
|
|||
|
|
|
|||
|
|
## Repo state already in tree
|
|||
|
|
|
|||
|
|
- `scripts/apparmor/` ships **3 profiles** (`thorium`, `veilor-power`,
|
|||
|
|
`lm-studio`) — complain-mode, **not auto-loaded**. No browser/mail
|
|||
|
|
/Element profile.
|
|||
|
|
- `scripts/selinux/` ships custom `.te` modules — primary MAC.
|
|||
|
|
- `overlay/etc/audit/plugins.d/veilor-remote.conf` +
|
|||
|
|
`audisp-remote.conf.disabled` — **scaffold present, opt-in switch
|
|||
|
|
missing**.
|
|||
|
|
- `kickstart/veilor-os.ks` — single live-ks. Real LUKS install lives
|
|||
|
|
in `overlay/usr/local/bin/veilor-installer` (generates ks at runtime).
|
|||
|
|
- No nftables overlay. No homed scaffold. No `veilor-audit-shipping` CLI.
|
|||
|
|
|
|||
|
|
## Item-by-item plan
|
|||
|
|
|
|||
|
|
### 1. AppArmor stack with SELinux — M
|
|||
|
|
|
|||
|
|
Fedora 43 ships `apparmor-parser`/`libapparmor`. Kernel has both LSMs.
|
|||
|
|
Stacking works since 5.1; SELinux stays primary, AppArmor confines
|
|||
|
|
specific binaries by path. **No conflict** — they layer. Risk: AA
|
|||
|
|
profiles based on Debian/Ubuntu paths fail on Fedora.
|
|||
|
|
|
|||
|
|
**Files:**
|
|||
|
|
- `kickstart/veilor-os.ks` `%packages` add `apparmor-parser apparmor-utils apparmor-profiles`
|
|||
|
|
- `overlay/etc/apparmor.d/veilor.d/` (new) — vendor profiles
|
|||
|
|
`firefox`, `thunderbird`, `element-desktop`, `signal-desktop`
|
|||
|
|
- `scripts/40-apparmor.sh` (new) — parses + sets all veilor profiles
|
|||
|
|
to **complain** on first install (logs only, no break)
|
|||
|
|
- `overlay/usr/local/bin/veilor-doctor` — adds AA status check
|
|||
|
|
|
|||
|
|
**Test:** `aa-status | grep complain` shows >=4 loaded; firefox writes
|
|||
|
|
outside policy → audit.log denial.
|
|||
|
|
|
|||
|
|
### 2. systemd-homed opt-in — L
|
|||
|
|
|
|||
|
|
Default LUKS storage `homectl` drops key on suspend; resume needs PAM
|
|||
|
|
unlock again — **breaks "lid open, keep working"**. Use
|
|||
|
|
`--storage=fscrypt` on top of existing btrfs `/home` subvol —
|
|||
|
|
suspend transparent, encrypts at rest with per-user key.
|
|||
|
|
|
|||
|
|
**Files:**
|
|||
|
|
- `overlay/usr/local/bin/veilor-homed-enable` (new) — confirms warning,
|
|||
|
|
runs `homectl create admin --storage=fscrypt --real-name="veilor admin"`
|
|||
|
|
after migrating files
|
|||
|
|
- `overlay/etc/pam.d/sddm` drop-in for `pam_systemd_home.so`
|
|||
|
|
- doc in `docs/HARDENING.md`. **Not auto-run** — only via post-install.
|
|||
|
|
|
|||
|
|
### 3. nftables alongside firewalld — S
|
|||
|
|
|
|||
|
|
firewalld speaks nftables backend on F43 — they don't conflict;
|
|||
|
|
firewalld owns `inet firewalld` table. veilor-os preset = separate
|
|||
|
|
`inet veilor` table loaded by its own service.
|
|||
|
|
|
|||
|
|
**Files:**
|
|||
|
|
- `overlay/etc/nftables/veilor.nft` (new) — table `inet veilor`:
|
|||
|
|
ssh per-IP rate limit (5/min), ICMP rate limit, optional
|
|||
|
|
`ip6 daddr ::/0 drop` toggled by sysctl-style `/etc/veilor/ipv6.disabled`,
|
|||
|
|
anti-port-scan via `meter` set
|
|||
|
|
- `overlay/etc/systemd/system/veilor-nftables.service` (new) —
|
|||
|
|
`After=firewalld.service`
|
|||
|
|
- `kickstart/veilor-os.ks` `%packages` add `nftables`, services-enabled
|
|||
|
|
add `veilor-nftables`
|
|||
|
|
|
|||
|
|
**Test:** `nft list ruleset` shows both `firewalld` AND `veilor`;
|
|||
|
|
`hping3 -S -p 22 --flood` from second VM gets rate-limited.
|
|||
|
|
|
|||
|
|
### 4. Audit log shipping — S
|
|||
|
|
|
|||
|
|
Plumbing **already in tree** (`audisp-remote.conf.disabled`,
|
|||
|
|
`veilor-remote.conf` with `active=no`). What's missing: CLI to flip
|
|||
|
|
the switch with cert pinning.
|
|||
|
|
|
|||
|
|
**Files:**
|
|||
|
|
- `overlay/usr/local/bin/veilor-audit-shipping` (new)
|
|||
|
|
- `enable HOST PORT FINGERPRINT` writes
|
|||
|
|
`/etc/veilor/audit-pin.sha256`, copies `audisp-remote.conf.disabled`
|
|||
|
|
→ `audisp-remote.conf` with substituted host/port, enables plugin
|
|||
|
|
(`active=yes`), restarts auditd
|
|||
|
|
- `disable` reverses
|
|||
|
|
- audisp-remote speaks TLS directly; cert pinning via `verify_peer=yes`
|
|||
|
|
+ `peer_cert_fingerprint`
|
|||
|
|
- Use **self-signed pinned**, not LE — collectors are LAN/VPN
|
|||
|
|
|
|||
|
|
**Test:** stand up `rsyslog` listener on nullstone with self-signed
|
|||
|
|
cert; run helper; trigger `sudo -i`; tail nullstone for AUTHPRIV
|
|||
|
|
event; revoke cert → events stop with logged TLS error.
|
|||
|
|
|
|||
|
|
### 5. Installer kickstart split — needs re-scope, S
|
|||
|
|
|
|||
|
|
Roadmap item is **stale**. As of v0.5.30 we already do real LUKS+btrfs
|
|||
|
|
in `veilor-installer` which generates ks at runtime. **Re-scope:**
|
|||
|
|
extract that generated ks template into static
|
|||
|
|
`kickstart/veilor-os-install.ks` (parameterised via `%include
|
|||
|
|
/tmp/answers.ks`), so reviewable in repo and reusable headlessly.
|
|||
|
|
|
|||
|
|
**Files:**
|
|||
|
|
- split `overlay/usr/local/bin/veilor-installer` heredoc into
|
|||
|
|
`kickstart/veilor-os-install.ks`
|
|||
|
|
- installer just writes answers + `cp` the ks
|
|||
|
|
- CI lints both with `ksvalidator`
|
|||
|
|
|
|||
|
|
### 6. Audit baseline re-run — S
|
|||
|
|
|
|||
|
|
Mechanical: `cp security/audit-template.md
|
|||
|
|
security/veilor-os-distro/2026-05-DD.md`, run on VM, target lower
|
|||
|
|
findings count than v0.2's baseline.
|
|||
|
|
|
|||
|
|
## Order, dependencies, ship plan
|
|||
|
|
|
|||
|
|
Dependencies: (5) blocks (6) — audit a stable installer, not a
|
|||
|
|
moving heredoc. Else parallel.
|
|||
|
|
|
|||
|
|
**Total effort:** 2S + 1S(rescope) + 1S + 1M + 1L ≈ **5–7 dev-days**.
|
|||
|
|
|
|||
|
|
- **v0.5.32 (small wins):** (4) audit shipping CLI + (3) nftables
|
|||
|
|
preset. Both S, scaffold completion, pure overlay (no kickstart risk).
|
|||
|
|
- **v0.5.33:** (5) ks split + (6) audit baseline re-run.
|
|||
|
|
- **v0.6 (medium):** (1) AppArmor stack — package install + 4 profiles
|
|||
|
|
+ doctor integration; complain-mode keeps blast radius zero.
|
|||
|
|
- **v0.7 (big lift):** (2) systemd-homed — UX-disruptive, needs
|
|||
|
|
migration helper + doc page + suspend/lock/swap testing.
|