feat: add hardened base and per-edition image overlays

Add the files that land in the image, organised as layered rootfs trees
(base first, then the edition layer wins on conflict).

- base: hardened kernel cmdline + sysctl, default-deny nftables,
  key-only ssh, persistent journald, module blacklist, no core dumps,
  snapshot timer units, motd.
- server: Prometheus + auto-provisioned Grafana + Loki + promtail.
- workstation: dev profile and desktop sysctl relaxations (perf,
  rootless containers).
- cloud: cloud-init provisioning config.
This commit is contained in:
Blake Ridgway
2026-08-21 13:15:43 -05:00
parent 729f191950
commit 94ab6043e7
19 changed files with 516 additions and 0 deletions

View File

@@ -0,0 +1,43 @@
# Arcline OS — pre-built alerting rules (Prometheus)
groups:
- name: arcline-node
rules:
- alert: NodeDown
expr: up == 0
for: 2m
labels:
severity: critical
annotations:
summary: "{{ $labels.instance }} is unreachable"
- alert: HighCpuLoad
expr: node_load1 / count(node_cpu_seconds_total{mode="idle"}) > 2
for: 10m
labels:
severity: warning
annotations:
summary: "sustained load average > 2 on {{ $labels.instance }}"
- alert: DiskAlmostFull
expr: (1 - node_filesystem_avail_bytes{fstype!~"tmpfs|overlay|squashfs"} / node_filesystem_size_bytes) * 100 > 85
for: 10m
labels:
severity: warning
annotations:
summary: "filesystem {{ $labels.mountpoint }} on {{ $labels.instance }} > 85%"
- alert: RootDiskCritical
expr: (1 - node_filesystem_avail_bytes{mountpoint="/"} / node_filesystem_size_bytes{mountpoint="/"}) * 100 > 95
for: 5m
labels:
severity: critical
annotations:
summary: "root filesystem on {{ $labels.instance }} > 95%"
- alert: ServiceRestarts
expr: increase(node_systemd_unit_restart_total[15m]) > 2
for: 0m
labels:
severity: warning
annotations:
summary: "unit {{ $labels.name }} restarting repeatedly on {{ $labels.instance }}"

View File

@@ -0,0 +1,25 @@
# Arcline OS — Prometheus configuration (server edition)
# Scrapes itself and node_exporter on the local host. Extension points for
# the Arcline toolchain (arcline-uptime exposes :8081/metrics) are commented.
global:
scrape_interval: 15s
evaluation_interval: 15s
external_labels:
cluster: arcline
rule_files:
- /etc/prometheus/arcline.rules.yml
scrape_configs:
- job_name: prometheus
static_configs:
- targets: ["localhost:9090"]
- job_name: node
static_configs:
- targets: ["localhost:9100"]
# - job_name: arcline-uptime
# static_configs:
# - targets: ["localhost:8081"]