refactor(setup): consolidate build/deploy tooling under setup/tools; docs
Move the build and deployment scripts into setup/tools alongside the existing
generators (proxmox-lxc-gen.sh, freeipa-image.sh, generate-modules.sh):
- setup/generate-answerfile.sh -> setup/tools/generate-answerfile.sh
- setup/archiso/build.sh -> setup/tools/build.sh
- setup/archiso/wds-deploy.sh -> setup/tools/wds-deploy.sh
- setup/archiso/write-usb.sh -> setup/tools/write-usb.sh
The archiso overlay/ (profile data: airootfs, profiledef.sh, packages.extra)
stays in setup/archiso/; build.sh now resolves it via an OVERLAY_DIR anchored
at the repo root, and DOTFILES_DIR is corrected for the new two-levels-deep
location. Updated every reference (generate-modules.sh, readme.md,
docs/md/{archiso,installation,index}.md).
generate-answerfile.sh: add linux-hardened to the kernel menu; verified its
emitted answerfile schema still matches every field the installers consume
(drive/kernel/keymap/hostname/username/password/luks_password/encrypt/
fido2_*/run_tui/components/desktop_environment/apps/shell_rc/colors).
Docs: add a dedicated ansipa Setup Guide (docs/md/ansipa-setup.md) covering
architecture, the full port list, the nginx portal + reverse-proxy paths, the
exact upstream reverse-proxy snippets (nginx/Caddy), NAT/push-mode behaviour,
and the Arch autofs/AUR caveat; link it from the index and cross-reference the
CheckMK/nginx ports from freeipa-ansible.md.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01MUhrcFU8J1Hnf7vNqNxZNi
feat/astal-menu
parent
d63e0e554c
commit
a73bc7cb93
|
|
@ -0,0 +1,230 @@
|
||||||
|
# ansipa Setup Guide
|
||||||
|
|
||||||
|
**ansipa** = **Ans**ible + Free**IPA**: a GPO-like management plane for Linux
|
||||||
|
fleets. FreeIPA provides identity, Kerberos, sudo/HBAC and host/user groups;
|
||||||
|
a lightweight client-side enforcer turns group membership into enforced policy;
|
||||||
|
CheckMK monitors the fleet; Keycloak adds SSO; and an nginx gateway fronts all
|
||||||
|
the web UIs behind one hostname.
|
||||||
|
|
||||||
|
This guide covers a full deployment: architecture, every port, the reverse-proxy
|
||||||
|
gateway, the exact snippet to expose it behind your own reverse proxy, the
|
||||||
|
NAT / behind-firewall behaviour, and known distro caveats. For the policy
|
||||||
|
catalogue and playbook reference see [FreeIPA & Ansible](freeipa-ansible.md).
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Architecture
|
||||||
|
|
||||||
|
```
|
||||||
|
┌─────────────────────────── docker host ───────────────────────────┐
|
||||||
|
│ docker network ipa-net (172.30.0.0/24) │
|
||||||
|
your reverse │ │
|
||||||
|
proxy (TLS) │ ┌── ansipa-nginx (gateway) ──┐ │
|
||||||
|
│ │ │ / portal start page │ │
|
||||||
|
https://ansipa ──┼──►│ /ipa/ ─► freeipa :443 ───┼──► 172.30.0.10 FreeIPA │
|
||||||
|
.example.com │ │ /cmk/ ─► checkmk :5000 ──┼──► 172.30.0.12 CheckMK │
|
||||||
|
(:443) │ │ /auth/ ─► keycloak :8080 ──┼──► keycloak Keycloak │
|
||||||
|
│ └────────────────────────────┘ │ │
|
||||||
|
│ :8088 (http) └─ postgres (KC backend) │
|
||||||
|
└────────────────────────────────────────────────────────────────────┘
|
||||||
|
▲ ▲
|
||||||
|
client-initiated only │ (enroll, kinit, policy pull, │
|
||||||
|
— works across NAT │ CheckMK push :8000) │
|
||||||
|
┌────────────────┴───────────┐ ┌──────────────┴─────────────┐
|
||||||
|
│ enrolled client (Arch) │ │ enrolled client (Fedora…) │
|
||||||
|
│ ansipa-enforce-policies │ │ SSSD + Kerberos + enforcer │
|
||||||
|
│ .timer (every 30 min) │ │ │
|
||||||
|
└─────────────────────────────┘ └────────────────────────────┘
|
||||||
|
```
|
||||||
|
|
||||||
|
The design is **pull-based**: the server never initiates connections to clients.
|
||||||
|
Every enrolled host runs `ansipa-enforce-policies.sh` on a 30-minute timer, does
|
||||||
|
`kinit -k host/$FQDN`, reads its own group memberships from FreeIPA, and applies
|
||||||
|
the matching policies locally. This is what makes the whole system work when
|
||||||
|
clients are behind NAT (see [Clients behind NAT](#clients-behind-nat)).
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Bringing up the server stack
|
||||||
|
|
||||||
|
```bash
|
||||||
|
cd setup/modules/FreeipaAnsible/image
|
||||||
|
cp .env.example .env && $EDITOR .env # set domain, realm, passwords, ports
|
||||||
|
|
||||||
|
# cgroup v2 hosts (WSL2, modern Fedora/Ubuntu/Arch): use the run.sh wrapper —
|
||||||
|
# the FreeIPA container needs --cgroupns host, which compose cannot express.
|
||||||
|
./run.sh all # freeipa + postgres + keycloak + checkmk + nginx gateway
|
||||||
|
# ./run.sh # freeipa only
|
||||||
|
# ./run.sh down # stop everything
|
||||||
|
|
||||||
|
# plain cgroup v1 hosts can use compose directly:
|
||||||
|
docker compose up -d
|
||||||
|
|
||||||
|
docker compose logs -f freeipa # watch first-boot (~10 min)
|
||||||
|
./keycloak-configure.sh # wire Keycloak → FreeIPA LDAP (once healthy)
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Ports
|
||||||
|
|
||||||
|
### Server (published on the docker host)
|
||||||
|
|
||||||
|
| Port | Proto | Service | Notes |
|
||||||
|
|------|-------|---------|-------|
|
||||||
|
| 389 | TCP | LDAP | FreeIPA directory |
|
||||||
|
| 636 | TCP | LDAPS | FreeIPA directory (TLS) |
|
||||||
|
| 88 | TCP+UDP | Kerberos | KDC |
|
||||||
|
| 464 | TCP+UDP | kpasswd | password changes |
|
||||||
|
| 443 | TCP | HTTPS | FreeIPA web UI (also proxied at `/ipa/`) |
|
||||||
|
| 445 | TCP | SMB | Samba shares (scans, LUKS keys, policy store) |
|
||||||
|
| 137 | UDP | NetBIOS name | Samba |
|
||||||
|
| 138 | UDP | NetBIOS datagram | Samba |
|
||||||
|
| 139 | TCP | NetBIOS session | Samba |
|
||||||
|
| 8090 | TCP | CheckMK web UI | container :5000 → host 8090 (also proxied at `/cmk/`) |
|
||||||
|
| 8000 | TCP | CheckMK agent receiver | **push-mode** target for NAT clients |
|
||||||
|
| 6557 | TCP | CheckMK livestatus | optional, external tooling |
|
||||||
|
| 8080 | TCP | Keycloak HTTP | dev mode (also proxied at `/auth/`) |
|
||||||
|
| 8443 | TCP | Keycloak HTTPS | needs a cert for the `start` command |
|
||||||
|
| **8088** | TCP | **nginx gateway** | single entry for the portal + all UIs (`ANSIPA_HTTP_PORT`) |
|
||||||
|
|
||||||
|
### Client (only needed for CheckMK **pull** mode)
|
||||||
|
|
||||||
|
| Port | Proto | Service | Notes |
|
||||||
|
|------|-------|---------|-------|
|
||||||
|
| 6556 | TCP | check_mk agent socket | server → client; **unreachable across NAT**, use push mode instead |
|
||||||
|
| 22 | TCP | sshd | if the client is in `dev_daemon-enable-sshd` and you manage over SSH |
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## The nginx gateway (portal + reverse proxy)
|
||||||
|
|
||||||
|
The `ansipa-nginx` service fronts all three web UIs on **one hostname/port** and
|
||||||
|
serves a portal landing page. Each backend is proxied at the path it already
|
||||||
|
uses natively, so there is no path rewriting to fight:
|
||||||
|
|
||||||
|
| Path | Backend | Notes |
|
||||||
|
|------|---------|-------|
|
||||||
|
| `/` | portal start page | static, links to the three UIs |
|
||||||
|
| `/ipa/` | FreeIPA `:443` | Host + Referer pinned to the IPA hostname (IPA anti-CSRF) |
|
||||||
|
| `/cmk/` | CheckMK `:5000` | CheckMK already serves under `/cmk` |
|
||||||
|
| `/auth/` | Keycloak `:8080` | Keycloak runs with `KC_HTTP_RELATIVE_PATH=/auth` |
|
||||||
|
|
||||||
|
The gateway speaks plain HTTP on `ANSIPA_HTTP_PORT` (default **8088**) and trusts
|
||||||
|
`X-Forwarded-*`, so it is designed to sit **behind your own TLS-terminating
|
||||||
|
reverse proxy**.
|
||||||
|
|
||||||
|
### Exposing ansipa behind your main reverse proxy
|
||||||
|
|
||||||
|
Point one hostname at the gateway. TLS is terminated by your proxy; ansipa
|
||||||
|
receives plain HTTP and reads `X-Forwarded-Proto` to build correct URLs.
|
||||||
|
|
||||||
|
**nginx** (add to your main reverse proxy):
|
||||||
|
|
||||||
|
```nginx
|
||||||
|
server {
|
||||||
|
listen 443 ssl;
|
||||||
|
server_name ansipa.example.com;
|
||||||
|
# ssl_certificate / ssl_certificate_key ...
|
||||||
|
|
||||||
|
location / {
|
||||||
|
proxy_pass http://DOCKER_HOST_IP:8088;
|
||||||
|
proxy_set_header Host $host;
|
||||||
|
proxy_set_header X-Forwarded-Proto $scheme;
|
||||||
|
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
||||||
|
proxy_set_header X-Forwarded-Host $host;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
**Caddy** (one line):
|
||||||
|
|
||||||
|
```caddy
|
||||||
|
ansipa.example.com {
|
||||||
|
reverse_proxy DOCKER_HOST_IP:8088
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
**Traefik** (docker labels on the nginx service): route the host rule to the
|
||||||
|
`ansipa-nginx` service on port 80.
|
||||||
|
|
||||||
|
### Per-app hostname settings (recommended for production)
|
||||||
|
|
||||||
|
Both CheckMK and Keycloak generate some absolute URLs from their own configured
|
||||||
|
hostname rather than the forwarded one. For a clean deployment behind a public
|
||||||
|
name, set:
|
||||||
|
|
||||||
|
- **Keycloak**: `KC_HOSTNAME=https://ansipa.example.com/auth` in `.env`.
|
||||||
|
- **CheckMK**: set the site's URL prefix / base URL to your public `https://ansipa.example.com/cmk/` (OMD → *Global settings → User interface → Base URL*), so login redirects use `https` and the public host.
|
||||||
|
|
||||||
|
Without these the UIs are still reachable through the proxy; only some redirects
|
||||||
|
fall back to the container-internal scheme/host.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Clients behind NAT
|
||||||
|
|
||||||
|
The controller can live on the public internet while clients sit behind NAT — the
|
||||||
|
architecture is client-initiated end to end:
|
||||||
|
|
||||||
|
| Function | Direction | Works behind NAT? |
|
||||||
|
|----------|-----------|-------------------|
|
||||||
|
| Enrollment (`ipa-client-install`) | client → server | ✅ |
|
||||||
|
| Policy enforcement (30-min timer) | client → server (kinit + `ipa` reads) | ✅ |
|
||||||
|
| Policy store sync | client → server SMB | ✅ |
|
||||||
|
| CheckMK **pull** (`:6556`) | **server → client** | ❌ — blocked by NAT |
|
||||||
|
| CheckMK **push** (`cmk-agent-ctl` → `:8000`) | client → server | ✅ |
|
||||||
|
|
||||||
|
So policies and identity Just Work across NAT. For monitoring, NAT clients must
|
||||||
|
use **push mode**: the server records a push request for each host in
|
||||||
|
`dev_mon_base` (`ansipa-checkmk-setup.sh` writes `/cmk-creds/push-mode-<host>.req`,
|
||||||
|
the CheckMK container consumes it and flips the host to `cmk_agent_connection:
|
||||||
|
push-agent`), and the client registers with `cmk-agent-ctl register --server
|
||||||
|
<host>:8000`. Advertise a **client-routable** CheckMK URL so agents can reach the
|
||||||
|
server — set `CMK_ADVERTISED_URL` in `.env` (e.g. `http://mon.example.com:8090`);
|
||||||
|
it is stored in the `dev_mon_base` group description and must NOT be the
|
||||||
|
container-internal `172.30.0.12`.
|
||||||
|
|
||||||
|
> **Note:** push mode needs the full CheckMK agent’s `cmk-agent-ctl` binary.
|
||||||
|
> RPM/DEB distros ship it in the agent package; on Arch the portable
|
||||||
|
> `check_mk_agent` fallback lacks it, so an Arch NAT client enrolls and gets
|
||||||
|
> policies but needs `cmk-agent-ctl` installed manually for push monitoring.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Client enrollment
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# on the client, as root:
|
||||||
|
sudo ./freeipa-enroll.sh --domain ansipa.example.com --realm ANSIPA.EXAMPLE.COM \
|
||||||
|
--server ipa.ansipa.example.com --hostname client01.ansipa.example.com
|
||||||
|
# (IPA_PASSWORD env var or --password; --no-dns-update if IPA does not run DNS)
|
||||||
|
```
|
||||||
|
|
||||||
|
Supported distros: **Arch**, **Fedora**, **RHEL/Rocky/AlmaLinux**, **Debian/Ubuntu**.
|
||||||
|
The script picks the right package manager and package names automatically.
|
||||||
|
|
||||||
|
### Arch caveat — autofs / freeipa-client from the AUR
|
||||||
|
|
||||||
|
On Arch, `ipa-client-install` comes from the AUR `freeipa-client` package, which
|
||||||
|
pulls the entire FreeIPA suite plus `autofs` from source — a long build
|
||||||
|
(tens of minutes on a small VM). ansipa bundles its own `autofs-pkgbuild/` that
|
||||||
|
builds autofs from upstream git, because the stock AUR `autofs` currently fails
|
||||||
|
(its pinned `autofs-5.1.9.tar.xz` was pruned from kernel.org). `freeipa-enroll.sh`
|
||||||
|
builds and installs it automatically before the AUR `freeipa-client` step, so no
|
||||||
|
manual intervention is needed — just expect the first enrollment to take a while.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Verifying a deployment
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# server
|
||||||
|
docker compose ps # all healthy
|
||||||
|
curl -fsS http://DOCKER_HOST_IP:8088/ | grep ansipa # portal
|
||||||
|
# client (after enrollment + one enforcer run)
|
||||||
|
id admin # SSSD resolves IPA users
|
||||||
|
kinit admin && klist # Kerberos works
|
||||||
|
sudo /usr/local/bin/ansipa-enforce-policies.sh # apply policies now
|
||||||
|
sudo systemctl list-timers ansipa-enforce-policies.timer
|
||||||
|
```
|
||||||
|
|
@ -16,19 +16,19 @@ sudo pacman -S archiso jq
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
# Basic build — interactive installer, no answerfile
|
# Basic build — interactive installer, no answerfile
|
||||||
bash setup/archiso/build.sh
|
bash setup/tools/build.sh
|
||||||
|
|
||||||
# Specify output directory
|
# Specify output directory
|
||||||
bash setup/archiso/build.sh /path/to/output
|
bash setup/tools/build.sh /path/to/output
|
||||||
|
|
||||||
# Embed an answerfile for automated deployment
|
# Embed an answerfile for automated deployment
|
||||||
bash setup/archiso/build.sh --preconf
|
bash setup/tools/build.sh --preconf
|
||||||
|
|
||||||
# Embed a specific answerfile
|
# Embed a specific answerfile
|
||||||
bash setup/archiso/build.sh --preconf ~/my-server.json
|
bash setup/tools/build.sh --preconf ~/my-server.json
|
||||||
|
|
||||||
# Both flags together
|
# Both flags together
|
||||||
bash setup/archiso/build.sh --preconf ~/my-server.json /media/usb/output
|
bash setup/tools/build.sh --preconf ~/my-server.json /media/usb/output
|
||||||
```
|
```
|
||||||
|
|
||||||
| Flag | Effect |
|
| Flag | Effect |
|
||||||
|
|
@ -226,9 +226,9 @@ Every build also produces a `*-netboot-*.tar.gz` artifact alongside the ISO. Thi
|
||||||
### 1. Build with a netboot URL
|
### 1. Build with a netboot URL
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
bash setup/archiso/build.sh --netboot-url http://your-server/m-archy
|
bash setup/tools/build.sh --netboot-url http://your-server/m-archy
|
||||||
# or combined with an answerfile:
|
# or combined with an answerfile:
|
||||||
bash setup/archiso/build.sh --preconf --netboot-url http://your-server/m-archy
|
bash setup/tools/build.sh --preconf --netboot-url http://your-server/m-archy
|
||||||
```
|
```
|
||||||
|
|
||||||
This generates `~/m-archy-out/m-archy-netboot.ipxe` alongside the netboot tarball.
|
This generates `~/m-archy-out/m-archy-netboot.ipxe` alongside the netboot tarball.
|
||||||
|
|
|
||||||
|
|
@ -99,6 +99,14 @@ docker compose up -d freeipa
|
||||||
| 138 | UDP | NetBIOS datagram |
|
| 138 | UDP | NetBIOS datagram |
|
||||||
| 8080 | TCP | Keycloak HTTP |
|
| 8080 | TCP | Keycloak HTTP |
|
||||||
| 8443 | TCP | Keycloak HTTPS |
|
| 8443 | TCP | Keycloak HTTPS |
|
||||||
|
| 8090 | TCP | CheckMK web UI (container :5000) |
|
||||||
|
| 8000 | TCP | CheckMK agent receiver (push mode) |
|
||||||
|
| 6557 | TCP | CheckMK livestatus (optional) |
|
||||||
|
| 8088 | TCP | nginx gateway — portal + reverse proxy for all UIs |
|
||||||
|
|
||||||
|
> For a full deployment walkthrough — the nginx portal, exposing ansipa behind
|
||||||
|
> your own reverse proxy, and NAT/push-mode behaviour — see the
|
||||||
|
> [ansipa Setup Guide](ansipa-setup.md).
|
||||||
|
|
||||||
### Container Internals
|
### Container Internals
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -16,6 +16,7 @@ A production-grade Arch Linux configuration for network administration, developm
|
||||||
| [Niri](niri.md) | Niri scrollable-tiling compositor — config, keybindings, tools |
|
| [Niri](niri.md) | Niri scrollable-tiling compositor — config, keybindings, tools |
|
||||||
| [Modules](modules.md) | Core modules and full optional-app catalogue |
|
| [Modules](modules.md) | Core modules and full optional-app catalogue |
|
||||||
| [Archiso](archiso.md) | Building the custom live installer ISO |
|
| [Archiso](archiso.md) | Building the custom live installer ISO |
|
||||||
|
| [ansipa Setup Guide](ansipa-setup.md) | Full deployment: ports, nginx portal + reverse proxy, NAT, enrollment |
|
||||||
| [FreeIPA & Ansible](freeipa-ansible.md) | Identity management and automated config deployment |
|
| [FreeIPA & Ansible](freeipa-ansible.md) | Identity management and automated config deployment |
|
||||||
| [Editors](editors.md) | Neovim, Micro, Yazi |
|
| [Editors](editors.md) | Neovim, Micro, Yazi |
|
||||||
| [Utilities](utilities.md) | Encryption helpers, ClamAV, credentials, update scripts |
|
| [Utilities](utilities.md) | Encryption helpers, ClamAV, credentials, update scripts |
|
||||||
|
|
@ -61,11 +62,17 @@ Dotfiles/
|
||||||
├── update.sh # pacman + yay full system update
|
├── update.sh # pacman + yay full system update
|
||||||
├── setup/
|
├── setup/
|
||||||
│ ├── tui-install.sh # Main interactive / answerfile installer
|
│ ├── tui-install.sh # Main interactive / answerfile installer
|
||||||
│ ├── generate-answerfile.sh # Dry-run to produce answerfile.json
|
|
||||||
│ ├── arch-autoinstall.sh # Automated base OS installer
|
│ ├── arch-autoinstall.sh # Automated base OS installer
|
||||||
│ ├── archbaseos-guided-install.sh # Guided base OS installer
|
│ ├── archbaseos-guided-install.sh # Guided base OS installer
|
||||||
│ ├── install-modules.sh # Add optional modules to existing system
|
│ ├── install-modules.sh # Add optional modules to existing system
|
||||||
│ ├── archiso/ # Custom Arch live ISO builder
|
│ ├── archiso/overlay/ # Custom Arch live ISO profile overlay
|
||||||
|
│ ├── tools/ # Build & deploy tooling:
|
||||||
|
│ │ ├── build.sh # build the live installer ISO + netboot
|
||||||
|
│ │ ├── wds-deploy.sh # package netboot artifacts for WDS/PXE
|
||||||
|
│ │ ├── write-usb.sh # write the ISO to a USB stick
|
||||||
|
│ │ ├── generate-answerfile.sh # dry-run to produce answerfile.json
|
||||||
|
│ │ ├── proxmox-lxc-gen.sh # Proxmox LXC container generator (TUI)
|
||||||
|
│ │ └── freeipa-image.sh # build the ansipa FreeIPA container image
|
||||||
│ └── modules/ # Modular install scripts
|
│ └── modules/ # Modular install scripts
|
||||||
├── desktopenvs/hyprlua/ # HyprLua (Lua-based Hyprland) configs
|
├── desktopenvs/hyprlua/ # HyprLua (Lua-based Hyprland) configs
|
||||||
├── desktopenvs/niri/ # Niri scrollable-tiling compositor configs
|
├── desktopenvs/niri/ # Niri scrollable-tiling compositor configs
|
||||||
|
|
|
||||||
|
|
@ -61,7 +61,7 @@ An **answerfile** lets the entire install — base OS _and_ dotfiles — run wit
|
||||||
### Generating an Answerfile
|
### Generating an Answerfile
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
bash ~/Dotfiles/setup/generate-answerfile.sh [OUTPUT_PATH]
|
bash ~/Dotfiles/setup/tools/generate-answerfile.sh [OUTPUT_PATH]
|
||||||
# Default output: ~/answerfile.json
|
# Default output: ~/answerfile.json
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -21,7 +21,7 @@ To add modules to an existing system: `bash ~/Dotfiles/setup/install-modules.sh`
|
||||||
## Cliff Notes
|
## Cliff Notes
|
||||||
|
|
||||||
- **Single source of truth for colours** — edit `colors.conf`, run `apply-theme.sh` to propagate everywhere.
|
- **Single source of truth for colours** — edit `colors.conf`, run `apply-theme.sh` to propagate everywhere.
|
||||||
- **Answerfile** — generate with `setup/generate-answerfile.sh`, place at `/answerfile.json` for a fully automated install. Passwords are never stored in it.
|
- **Answerfile** — generate with `setup/tools/generate-answerfile.sh`, place at `/answerfile.json` for a fully automated install. Passwords are never stored in it.
|
||||||
- **Hostname uniqueness** — the MAC address of the primary NIC is appended automatically when an answerfile hostname is set (`myhost` → `myhost-aabbccddee11`).
|
- **Hostname uniqueness** — the MAC address of the primary NIC is appended automatically when an answerfile hostname is set (`myhost` → `myhost-aabbccddee11`).
|
||||||
- **LUKS encryption** — backup key is auto-generated from `/dev/urandom`, enrolled in a second LUKS slot, written to `/_LUKS_BACKUP_KEY` (root-only, inside the encrypted container). Collected by Ansible and stored on the SMB `ansipa-luks-keys` share (KeyAdmin-only read access).
|
- **LUKS encryption** — backup key is auto-generated from `/dev/urandom`, enrolled in a second LUKS slot, written to `/_LUKS_BACKUP_KEY` (root-only, inside the encrypted container). Collected by Ansible and stored on the SMB `ansipa-luks-keys` share (KeyAdmin-only read access).
|
||||||
- **Custom ISO** — `setup/archiso/` builds a live USB that can embed a pre-baked answerfile for zero-touch deployment. The live environment also includes a **System Reset** mode that reinstalls the root subvolume while preserving home data and FIDO2 auth keys.
|
- **Custom ISO** — `setup/archiso/` builds a live USB that can embed a pre-baked answerfile for zero-touch deployment. The live environment also includes a **System Reset** mode that reinstalls the root subvolume while preserving home data and FIDO2 auth keys.
|
||||||
|
|
|
||||||
|
|
@ -41,6 +41,9 @@ set -euo pipefail
|
||||||
# safer when the script is sourced or called with a relative path.
|
# safer when the script is sourced or called with a relative path.
|
||||||
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
||||||
DOTFILES_DIR="$(cd "$SCRIPT_DIR/../.." && pwd)"
|
DOTFILES_DIR="$(cd "$SCRIPT_DIR/../.." && pwd)"
|
||||||
|
# The archiso overlay (airootfs, profiledef.sh, packages.extra) is profile data
|
||||||
|
# that lives in setup/archiso/overlay/, not alongside this script in setup/tools/.
|
||||||
|
OVERLAY_DIR="$DOTFILES_DIR/setup/archiso/overlay"
|
||||||
|
|
||||||
# ── Argument parsing ───────────────────────────────────────────────────────────
|
# ── Argument parsing ───────────────────────────────────────────────────────────
|
||||||
# We support both --flag value and --flag=value syntax.
|
# We support both --flag value and --flag=value syntax.
|
||||||
|
|
@ -149,13 +152,13 @@ echo "Applying M-Archy overlay..."
|
||||||
# Merge our custom airootfs overlay ON TOP of the releng copy.
|
# Merge our custom airootfs overlay ON TOP of the releng copy.
|
||||||
# Files in our overlay replace or extend the releng defaults.
|
# Files in our overlay replace or extend the releng defaults.
|
||||||
# The trailing /. ensures we copy the directory contents, not the directory itself.
|
# The trailing /. ensures we copy the directory contents, not the directory itself.
|
||||||
cp -r "$SCRIPT_DIR/overlay/airootfs/." "$PROFILE/airootfs/"
|
cp -r "$OVERLAY_DIR/airootfs/." "$PROFILE/airootfs/"
|
||||||
|
|
||||||
echo "Replacing profiledef..."
|
echo "Replacing profiledef..."
|
||||||
# profiledef.sh controls ISO metadata (name, label, build modes, boot modes,
|
# profiledef.sh controls ISO metadata (name, label, build modes, boot modes,
|
||||||
# compression settings, and file permissions in the final image).
|
# compression settings, and file permissions in the final image).
|
||||||
# We replace the releng default entirely with our customized version.
|
# We replace the releng default entirely with our customized version.
|
||||||
cp "$SCRIPT_DIR/overlay/profiledef.sh" "$PROFILE/profiledef.sh"
|
cp "$OVERLAY_DIR/profiledef.sh" "$PROFILE/profiledef.sh"
|
||||||
|
|
||||||
echo "Adding extra packages..."
|
echo "Adding extra packages..."
|
||||||
# packages.extra lists additional packages beyond releng's defaults.
|
# packages.extra lists additional packages beyond releng's defaults.
|
||||||
|
|
@ -165,7 +168,7 @@ echo "Adding extra packages..."
|
||||||
while IFS= read -r pkg || [[ -n "$pkg" ]]; do
|
while IFS= read -r pkg || [[ -n "$pkg" ]]; do
|
||||||
[[ -z "$pkg" || "$pkg" == \#* ]] && continue
|
[[ -z "$pkg" || "$pkg" == \#* ]] && continue
|
||||||
grep -qxF "$pkg" "$PROFILE/packages.x86_64" || echo "$pkg" >> "$PROFILE/packages.x86_64"
|
grep -qxF "$pkg" "$PROFILE/packages.x86_64" || echo "$pkg" >> "$PROFILE/packages.x86_64"
|
||||||
done < "$SCRIPT_DIR/overlay/packages.extra"
|
done < "$OVERLAY_DIR/packages.extra"
|
||||||
|
|
||||||
# ── Embed installer scripts ────────────────────────────────────────────────────
|
# ── Embed installer scripts ────────────────────────────────────────────────────
|
||||||
# These three scripts live in the main setup/ directory of the dotfiles repo
|
# These three scripts live in the main setup/ directory of the dotfiles repo
|
||||||
|
|
@ -13,7 +13,8 @@
|
||||||
set -uo pipefail
|
set -uo pipefail
|
||||||
|
|
||||||
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
||||||
DOTFILES_DIR="$(cd "$SCRIPT_DIR/.." && pwd)"
|
# This script lives in setup/tools/, so the repo root is two levels up.
|
||||||
|
DOTFILES_DIR="$(cd "$SCRIPT_DIR/../.." && pwd)"
|
||||||
OUTPUT="${1:-$HOME/answerfile.json}"
|
OUTPUT="${1:-$HOME/answerfile.json}"
|
||||||
TMP_D="$(mktemp -d)"
|
TMP_D="$(mktemp -d)"
|
||||||
trap 'rm -rf "$TMP_D"' EXIT
|
trap 'rm -rf "$TMP_D"' EXIT
|
||||||
|
|
@ -112,10 +113,11 @@ AF_DRIVE=$(dialog --backtitle "$BACKTITLE" \
|
||||||
# ── Kernel ────────────────────────────────────────────────────────────────────
|
# ── Kernel ────────────────────────────────────────────────────────────────────
|
||||||
AF_KERNEL=$(dialog --backtitle "$BACKTITLE" \
|
AF_KERNEL=$(dialog --backtitle "$BACKTITLE" \
|
||||||
--title " Kernel " \
|
--title " Kernel " \
|
||||||
--menu "Select kernel package:" 12 54 3 \
|
--menu "Select kernel package:" 13 54 4 \
|
||||||
"linux" "Stable kernel" \
|
"linux" "Stable kernel" \
|
||||||
"linux-lts" "Long-term support kernel" \
|
"linux-lts" "Long-term support kernel" \
|
||||||
"linux-zen" "Zen performance kernel" \
|
"linux-zen" "Zen performance kernel" \
|
||||||
|
"linux-hardened" "Security-hardened kernel" \
|
||||||
3>&1 1>&2 2>&3) || AF_KERNEL="linux"
|
3>&1 1>&2 2>&3) || AF_KERNEL="linux"
|
||||||
|
|
||||||
# ── Keymap ────────────────────────────────────────────────────────────────────
|
# ── Keymap ────────────────────────────────────────────────────────────────────
|
||||||
|
|
@ -451,4 +453,4 @@ mkdir -p "$(dirname "$OUTPUT")"
|
||||||
|
|
||||||
clear
|
clear
|
||||||
printf "\n Answerfile saved to: %s\n\n" "$OUTPUT"
|
printf "\n Answerfile saved to: %s\n\n" "$OUTPUT"
|
||||||
printf " To embed in ISO: bash setup/archiso/build.sh --preconf %s\n\n" "$OUTPUT"
|
printf " To embed in ISO: bash setup/tools/build.sh --preconf %s\n\n" "$OUTPUT"
|
||||||
|
|
@ -14,7 +14,7 @@ SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
||||||
SETUP_DIR="$(cd "$SCRIPT_DIR/.." && pwd)"
|
SETUP_DIR="$(cd "$SCRIPT_DIR/.." && pwd)"
|
||||||
CONF="$SETUP_DIR/modules.conf"
|
CONF="$SETUP_DIR/modules.conf"
|
||||||
TUI="$SETUP_DIR/tui-install.sh"
|
TUI="$SETUP_DIR/tui-install.sh"
|
||||||
AF="$SETUP_DIR/generate-answerfile.sh"
|
AF="$SCRIPT_DIR/generate-answerfile.sh" # sibling in setup/tools/
|
||||||
DOCS="$SETUP_DIR/../docs/md/modules.md"
|
DOCS="$SETUP_DIR/../docs/md/modules.md"
|
||||||
|
|
||||||
DRY_RUN=false
|
DRY_RUN=false
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue