docs: update readme and docs for recent changes
- freeipa-ansible.md: expand into full container installation guide covering SMB shares (ansipa-scans, ansipa-luks-keys), KeyAdmin access control, LUKS_KEY_UPLOAD_PASSWORD env var, updated collect-luks-keys flow via SMB, daemon enable/disable policy, security scan + alert pipeline, and Keycloak section - modules.md: add Virtualisation & Remote Desktop section (qemu, rdp-client, lamco-rdp-server) - archiso.md: document system reset mode (reset-arch.sh), launch.sh action selection, libfido2 in packages.extra - readme.md: update Cliff Notes and docs table to reflect all changes Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>main
parent
5d56984e38
commit
6f2b24c51a
|
|
@ -71,8 +71,11 @@ pam-u2f
|
|||
btop
|
||||
fastfetch
|
||||
openssh
|
||||
libfido2
|
||||
```
|
||||
|
||||
`libfido2` is included to support FIDO2 / token-based LUKS unlock in the system reset mode (see below).
|
||||
|
||||
These are added on top of the standard Arch `releng` package set.
|
||||
|
||||
---
|
||||
|
|
@ -93,7 +96,10 @@ install-arch auto # automated mode (reads /answerfile.json)
|
|||
|
||||
### `/root/launch.sh`
|
||||
|
||||
Internal dispatcher used by `install-arch`.
|
||||
Internal dispatcher used by `install-arch`. After keymap selection, it prompts for one of two actions:
|
||||
|
||||
- **Install** — runs the normal guided or automated installer.
|
||||
- **Reset** — runs `setup/reset-arch.sh` (see [System Reset Mode](#system-reset-mode)).
|
||||
|
||||
### `/answerfile.json`
|
||||
|
||||
|
|
@ -101,6 +107,48 @@ Only present when built with `--preconf`. Both installer scripts check for this
|
|||
|
||||
---
|
||||
|
||||
## System Reset Mode
|
||||
|
||||
`setup/reset-arch.sh` performs a non-destructive system reinstall from the live environment, keeping user home data and authentication keys intact.
|
||||
|
||||
### What it does
|
||||
|
||||
1. Detects LUKS2 encryption on the selected partition and unlocks it:
|
||||
- **Option 1** (recommended): tries the enrolled FIDO2/TPM2 token first, falls back to passphrase.
|
||||
- **Option 2**: passphrase only.
|
||||
- **Option 3**: enrolled token only.
|
||||
2. Snapshots `/etc` credentials and config from the existing `@` subvolume.
|
||||
3. Wipes `~/.config` from `@home` for all users, **preserving** `~/.config/Yubico/` so FIDO2 PAM login continues to work after reset.
|
||||
4. Deletes and recreates the `@` (root) Btrfs subvolume.
|
||||
5. Reinstalls base system packages via `pacstrap`.
|
||||
6. Restores `passwd`, `shadow`, `pam.d`, `sudoers`, `fstab`, `mkinitcpio.conf`, and GRUB config from the snapshot.
|
||||
7. Regenerates initramfs and GRUB menu from chroot.
|
||||
|
||||
### How to run it
|
||||
|
||||
Boot from the ISO. At the action prompt, select **Reset**.
|
||||
|
||||
The reset mode is also available standalone on any live Arch environment:
|
||||
|
||||
```bash
|
||||
bash /path/to/setup/reset-arch.sh
|
||||
```
|
||||
|
||||
### What is preserved
|
||||
|
||||
| Data | Preserved |
|
||||
|------|-----------|
|
||||
| User home directories (`/home/*`) | Yes |
|
||||
| User passwords (`/etc/shadow`) | Yes |
|
||||
| FIDO2 keys (`~/.config/Yubico/`) | Yes |
|
||||
| PAM configuration | Yes |
|
||||
| sudoers rules | Yes |
|
||||
| fstab, mkinitcpio config | Yes |
|
||||
| App configs (`~/.config/*`) | **No** (wiped except Yubico) |
|
||||
| Installed packages | **No** (reinstalled from base) |
|
||||
|
||||
---
|
||||
|
||||
## Automated Deployment Workflow
|
||||
|
||||
```
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
# FreeIPA & Ansible
|
||||
|
||||
The FreeIPA/Ansible system provides centralised identity management for a fleet of Arch Linux machines: single sign-on, host-group-driven package and module deployment, LUKS backup key collection, and automatic Keycloak configuration.
|
||||
The FreeIPA/Ansible system provides centralised identity management for a fleet of Arch Linux machines: single sign-on, host-group-driven package and module deployment, policy enforcement, LUKS backup key collection, scan-result aggregation, and automatic Keycloak configuration.
|
||||
|
||||
All relevant files live under `setup/modules/FreeipaAnsible/`.
|
||||
|
||||
|
|
@ -9,54 +9,140 @@ All relevant files live under `setup/modules/FreeipaAnsible/`.
|
|||
## Architecture
|
||||
|
||||
```
|
||||
┌────────────────────────────────────┐
|
||||
│ FreeIPA Server │
|
||||
│ (can run in Docker / LXC) │
|
||||
┌──────────────────────────────────────────────────────────────────────┐
|
||||
│ FreeIPA + Keycloak + Samba container (docker-compose) │
|
||||
│ │
|
||||
│ • User/host directory │
|
||||
│ • Kerberos KDC │
|
||||
│ • DNS (optional) │
|
||||
│ • Host group management │
|
||||
└──────────┬─────────────────────────┘
|
||||
│ SSSD / Kerberos
|
||||
▼
|
||||
┌────────────────────────────────────┐
|
||||
│ Enrolled client machine │
|
||||
│ │
|
||||
│ • sssd — authentication │
|
||||
│ • ipa CLI — host group queries │
|
||||
│ • Ansible-deployed timers │
|
||||
│ ├── package installer │
|
||||
│ ├── module installer │
|
||||
│ ├── Flatpak installer │
|
||||
│ └── baseuser group sync │
|
||||
└────────────────────────────────────┘
|
||||
│ • FreeIPA — user/host directory, Kerberos KDC, DNS (optional) │
|
||||
│ • Keycloak — OIDC provider federating FreeIPA via LDAP │
|
||||
│ • Samba — two SMB shares for scan results and LUKS backup keys │
|
||||
│ • cronie — hourly scan-result analyser (ansipa-check-scans) │
|
||||
└───────────┬─────────────────────────┬────────────────────────────────┘
|
||||
│ SSSD / Kerberos │ SMB (445)
|
||||
▼ ▼
|
||||
┌──────────────────────┐ ┌─────────────────────────────────────────┐
|
||||
│ Enrolled client │ │ Ansible controller │
|
||||
│ │ │ │
|
||||
│ • sssd │ │ • deploy-ansipa-*.yml playbooks │
|
||||
│ • ipa CLI │ │ • collect-luks-keys.yml │
|
||||
│ • Ansible-deployed │ │ (uploads keys to ansipa-luks-keys │
|
||||
│ timers: │ │ share as luks-upload service acct) │
|
||||
│ ├── pkg installer │ └─────────────────────────────────────────┘
|
||||
│ ├── module install│
|
||||
│ ├── Flatpak install
|
||||
│ ├── baseuser sync │
|
||||
│ └── policy enforcer (every 30 min)
|
||||
│ ├── binary blocking
|
||||
│ ├── daemon enable/disable
|
||||
│ ├── Timeshift backups
|
||||
│ ├── security scans + SMB upload
|
||||
│ └── alert fetch + desktop notify
|
||||
└──────────────────────┘
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## FreeIPA Server
|
||||
## FreeIPA Server Container
|
||||
|
||||
### Docker / OCI Image
|
||||
|
||||
A pre-built Docker image is available via `setup/modules/FreeipaAnsible/image/`:
|
||||
### Quick Start
|
||||
|
||||
```bash
|
||||
cd setup/modules/FreeipaAnsible/image
|
||||
cp .env.example .env
|
||||
# Edit .env with your domain, admin password, realm, etc.
|
||||
$EDITOR .env # set all required variables
|
||||
docker compose up -d
|
||||
docker compose logs -f freeipa # watch first-boot (~10 min)
|
||||
# Once freeipa is healthy:
|
||||
./keycloak-configure.sh # wire Keycloak → FreeIPA LDAP
|
||||
```
|
||||
|
||||
The container runs `ipa-first-boot.sh` on first start to initialise the IPA instance, then optionally `keycloak-configure.sh` to wire up Keycloak as an OIDC provider.
|
||||
|
||||
### Interactive Server Setup
|
||||
To run FreeIPA without Keycloak:
|
||||
|
||||
```bash
|
||||
bash setup/modules/optional-Modules/apps/freeipa-server.sh
|
||||
docker compose up -d freeipa
|
||||
```
|
||||
|
||||
Prompts for realm, domain, admin password, and whether to generate client-install scripts.
|
||||
### Environment Variables (`.env`)
|
||||
|
||||
| Variable | Required | Description |
|
||||
|----------|----------|-------------|
|
||||
| `IPA_HOSTNAME` | yes | FQDN of the IPA server (e.g. `ipa.corp.example.com`) |
|
||||
| `IPA_DOMAIN` | yes | DNS domain (e.g. `corp.example.com`) |
|
||||
| `IPA_REALM` | — | Kerberos realm; defaults to `IPA_DOMAIN` uppercased |
|
||||
| `IPA_ADMIN_PASSWORD` | yes | `admin` account password |
|
||||
| `IPA_DM_PASSWORD` | yes | Directory Manager password |
|
||||
| `IPA_SETUP_DNS` | — | `true` to enable integrated DNS (default `false`) |
|
||||
| `IPA_DNS_FORWARDER` | — | Upstream DNS when `IPA_SETUP_DNS=true` |
|
||||
| `IPA_SETUP_KRA` | — | `true` to enable the Key Recovery Authority |
|
||||
| `SMB_SCAN_PASSWORD` | yes | Password for the `scanupload` Samba service account |
|
||||
| `LUKS_KEY_UPLOAD_PASSWORD` | yes | Password for the `luks-upload` Samba service account |
|
||||
| `KC_HOSTNAME` | yes | Public hostname of Keycloak |
|
||||
| `KC_REALM` | — | Keycloak realm name (default `corp`) |
|
||||
| `KC_ADMIN` | — | Keycloak admin username (default `admin`) |
|
||||
| `KC_ADMIN_PASSWORD` | yes | Keycloak admin password |
|
||||
| `KC_DB_PASSWORD` | yes | PostgreSQL password for Keycloak |
|
||||
| `IPA_BIND_DN` | — | LDAP bind DN for Keycloak federation (default: Directory Manager) |
|
||||
| `IPA_BIND_PASSWORD` | — | LDAP bind password; leave blank to reuse `IPA_DM_PASSWORD` |
|
||||
| `IPA_USE_LDAPS` | — | `true` to use LDAPS for Keycloak federation |
|
||||
|
||||
### Exposed Ports
|
||||
|
||||
| Port | Protocol | Service |
|
||||
|------|----------|---------|
|
||||
| 389 | TCP | LDAP |
|
||||
| 636 | TCP | LDAPS |
|
||||
| 88 | TCP + UDP | Kerberos |
|
||||
| 464 | TCP + UDP | kpasswd |
|
||||
| 443 | TCP | HTTPS (IPA web UI) |
|
||||
| 445 | TCP | SMB (Samba shares) |
|
||||
| 139 | TCP | NetBIOS session (Samba) |
|
||||
| 137 | UDP | NetBIOS name service |
|
||||
| 138 | UDP | NetBIOS datagram |
|
||||
| 8080 | TCP | Keycloak HTTP |
|
||||
| 8443 | TCP | Keycloak HTTPS |
|
||||
|
||||
### Container Internals
|
||||
|
||||
On first start, `ipa-first-boot.service` runs `ipa-first-boot.sh` to initialise the FreeIPA instance. On every start, `ansipa-smb.service` runs `ansipa-smb-setup.sh` to configure Samba (the container rootfs is ephemeral — Samba config and users must be re-applied after restarts).
|
||||
|
||||
Data persisted to the `/data` volume:
|
||||
|
||||
```
|
||||
/data/
|
||||
├── samba/
|
||||
│ ├── passdb.tdb # Samba password database (survives restarts)
|
||||
│ └── ansipa-smb.env # Persisted SMB passwords (auto-written on first start)
|
||||
├── scan-results/
|
||||
│ ├── archive/<host>/ # Client scan logs (written by clients via SMB)
|
||||
│ └── alerts/<host>/ # Alert files generated by ansipa-check-scans (hourly)
|
||||
└── luks-keys/ # LUKS backup keys (written by Ansible controller via SMB)
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## SMB Shares
|
||||
|
||||
The container exposes two Samba shares, both configured by `ansipa-smb-setup.sh`.
|
||||
|
||||
### `ansipa-scans` — Scan Result Archive
|
||||
|
||||
- **Path:** `/data/scan-results`
|
||||
- **Authenticated user:** `scanupload` (write-only; no browse)
|
||||
- **Purpose:** Clients enrolled in `policy-security-scan` upload their daily ClamAV / rkhunter / chkrootkit logs here after each scan run.
|
||||
- **Analysis:** `ansipa-check-scans.sh` runs hourly via cronie; it reads each host's archive logs and writes `*.alert` files to the `alerts/` subdirectory when concerning patterns are found.
|
||||
- **Credentials file on clients:** `/etc/ansipa-smb.creds` (deployed by `deploy-ansipa-policies.yml`)
|
||||
|
||||
### `ansipa-luks-keys` — LUKS Backup Key Store
|
||||
|
||||
- **Path:** `/data/luks-keys`
|
||||
- **Permissions:** write-only for `luks-upload`; read-only for members of the `KeyAdmin` Linux group
|
||||
- **Purpose:** The Ansible controller writes each host's LUKS backup key here after collecting it via `collect-luks-keys.yml`.
|
||||
- **Access control:** Add an admin Samba user to the `KeyAdmin` group on the container:
|
||||
```bash
|
||||
# On the freeipa container
|
||||
useradd -r -G KeyAdmin <username>
|
||||
smbpasswd -a <username>
|
||||
```
|
||||
The `KeyAdmin` group and the `luks-upload` / `scanupload` service accounts are created by `ansipa-smb-setup.sh` on every container start.
|
||||
|
||||
---
|
||||
|
||||
|
|
@ -118,9 +204,9 @@ All playbooks live in `setup/modules/FreeipaAnsible/ansible/` and require an inv
|
|||
ansible-playbook -i inventory deploy-ansipa-install.yml
|
||||
```
|
||||
|
||||
Deploys `ansipa-install-packages.sh` + a systemd timer that runs every 30 minutes. The script queries IPA for host groups named `ansipa-install-<package>` and installs/removes packages to match.
|
||||
Deploys `ansipa-install-packages.sh` + a systemd timer (every 30 min). The script queries IPA for host groups named `ansipa-install-<package>` and installs or removes packages to match.
|
||||
|
||||
**Group naming convention:** `ansipa-install-firefox` → installs the `firefox` package.
|
||||
**Group naming convention:** `ansipa-install-firefox` → installs `firefox`.
|
||||
|
||||
### Deploy Module Auto-Installer
|
||||
|
||||
|
|
@ -129,13 +215,9 @@ ansible-playbook -i inventory deploy-ansipa-modules.yml \
|
|||
[-e ansipa_user=amir]
|
||||
```
|
||||
|
||||
Deploys `ansipa-install-modules.sh` + timer. Queries for groups named `ansipa-module-<name>` and runs the matching script from `/usr/local/lib/ansipa-modules/<name>.sh`.
|
||||
Deploys `ansipa-install-modules.sh` + timer. Queries for groups named `ansipa-module-<name>` and runs the matching script from `/usr/local/lib/ansipa-modules/<name>.sh`. Module scripts are copied from `setup/modules/optional-Modules/apps/*.sh`.
|
||||
|
||||
Module scripts are the same ones used by `install-modules.sh` — copied from `setup/modules/optional-Modules/apps/*.sh`.
|
||||
|
||||
**Group naming convention:** `ansipa-module-docker` → runs `docker.sh` on the host.
|
||||
|
||||
Each module is applied once and stamped in `/var/lib/ansipa-modules/<name>.done`. Re-running the timer skips already-applied modules.
|
||||
Each module is applied once and stamped in `/var/lib/ansipa-modules/<name>.done`.
|
||||
|
||||
### Deploy BaseUser Sync
|
||||
|
||||
|
|
@ -143,27 +225,40 @@ Each module is applied once and stamped in `/var/lib/ansipa-modules/<name>.done`
|
|||
ansible-playbook -i inventory deploy-baseuser-sync.yml
|
||||
```
|
||||
|
||||
Deploys a `systemd.path` unit that triggers whenever a user logs in. If the user is a member of the IPA `BaseUser` group, they are automatically added to the local `baseusers` group — useful for desktop permission grants.
|
||||
Deploys a `systemd.path` unit that triggers on login. Users who are members of the IPA `BaseUser` group are automatically added to the local `baseusers` group.
|
||||
|
||||
### Deploy Policy Enforcer
|
||||
|
||||
```bash
|
||||
ansible-playbook -i inventory deploy-ansipa-policies.yml \
|
||||
-e smb_scan_password=<SMB_SCAN_PASSWORD>
|
||||
```
|
||||
|
||||
Deploys `ansipa-enforce-policies.sh`, `ansipa-fetch-alerts.sh`, `ansipa-scan-notify.sh`, a systemd timer (every 30 min), and `/etc/ansipa-smb.creds`. Use `ansible-vault` for the password in production.
|
||||
|
||||
### Collect LUKS Backup Keys
|
||||
|
||||
```bash
|
||||
ansible-playbook -i inventory collect-luks-keys.yml \
|
||||
[-e luks_keys_store=/secure/location]
|
||||
-e luks_smb_server=ipa.corp.example.com \
|
||||
-e luks_upload_password=<LUKS_KEY_UPLOAD_PASSWORD>
|
||||
```
|
||||
|
||||
For each enrolled host, checks for `/_LUKS_BACKUP_KEY` (placed there by the M-Archy installer when disk encryption is enabled) and fetches it to the controller as:
|
||||
For each enrolled host:
|
||||
1. Fetches `/_LUKS_BACKUP_KEY` from the client to a local staging directory.
|
||||
2. Uploads the staged key to `//ipa-server/ansipa-luks-keys/<hostname>_LUKS_BACKUP_KEY` via `smbclient` using a temporary credentials file (`no_log`, deleted in `post_tasks`).
|
||||
3. Removes the local staging copy after a successful upload.
|
||||
|
||||
```
|
||||
<luks_keys_store>/<HOSTNAME>_LUKS_BACKUP_KEY
|
||||
```
|
||||
Keys on the SMB share are accessible only to `KeyAdmin` group members (see [SMB Shares](#smb-shares)).
|
||||
|
||||
Keys are stored with mode `0400`. The store directory is created with mode `0700`.
|
||||
**Schedule automatic collection:**
|
||||
|
||||
**Schedule for automatic collection:**
|
||||
```bash
|
||||
# Add to crontab on the Ansible controller
|
||||
0 3 * * * cd /path/to/playbooks && ansible-playbook -i inventory collect-luks-keys.yml
|
||||
0 3 * * * cd /path/to/FreeipaAnsible/ansible && \
|
||||
ansible-playbook -i inventory collect-luks-keys.yml \
|
||||
-e luks_smb_server=ipa.corp.example.com \
|
||||
-e luks_upload_password=<LUKS_KEY_UPLOAD_PASSWORD>
|
||||
```
|
||||
|
||||
---
|
||||
|
|
@ -176,6 +271,63 @@ Keys are stored with mode `0400`. The store directory is created with mode `0700
|
|||
| `ansipa-module-<name>` | `ansipa-install-modules.sh` | Run module script once |
|
||||
| `fp_install-<app>` | `ansipa-install-flatpaks.sh` | Install Flatpak app |
|
||||
| `BaseUser` | `auto-add-baseuser.sh` | Add user to local `baseusers` group |
|
||||
| `policy-block-binary-<name>` | `ansipa-enforce-policies.sh` | Block binary via PATH wrapper + AppArmor |
|
||||
| `policy-daemon-enable-<unit>` | `ansipa-enforce-policies.sh` | `systemctl enable --now <unit>`; reverted on leave |
|
||||
| `policy-daemon-disable-<unit>` | `ansipa-enforce-policies.sh` | `systemctl disable --now <unit>`; reverted on leave |
|
||||
| `policy-timeshift-backup` | `ansipa-enforce-policies.sh` | Daily Timeshift snapshot at 03:00 |
|
||||
| `policy-security-scan` | `ansipa-enforce-policies.sh` | Daily ClamAV + rkhunter + chkrootkit scan + SMB upload |
|
||||
| `policy-scan-notify` | `ansipa-enforce-policies.sh` | Fetch server alerts, notify user every 10 min until acknowledged |
|
||||
|
||||
---
|
||||
|
||||
## Policy Enforcement
|
||||
|
||||
`ansipa-enforce-policies.sh` runs every 30 minutes on each enrolled client (deployed by `deploy-ansipa-policies.yml`). All policies are idempotent and reversible — leaving a host group undoes the policy on the next run.
|
||||
|
||||
### Binary Blocking
|
||||
|
||||
Adding a host to `policy-block-binary-<name>` applies two layers:
|
||||
|
||||
1. **PATH wrapper** — a script in `/usr/local/bin/<name>` that prints a policy message and exits 1. Takes priority over the real binary for `$PATH`-based calls.
|
||||
2. **AppArmor deny profile** — `/etc/apparmor.d/ansipa-block-<name>` with an empty profile, denying all file access. Blocks absolute-path calls and direct `exec()`. Skipped silently if `apparmor_parser` is not present.
|
||||
|
||||
Leaving the group removes both layers on the next enforcer run.
|
||||
|
||||
### Daemon Enable / Disable
|
||||
|
||||
| Group | Effect on join | Effect on leave |
|
||||
|-------|---------------|-----------------|
|
||||
| `policy-daemon-enable-<unit>` | `systemctl enable --now <unit>` | `systemctl disable --now <unit>` |
|
||||
| `policy-daemon-disable-<unit>` | `systemctl disable --now <unit>` | `systemctl enable --now <unit>` |
|
||||
|
||||
The `.service` suffix is optional — it is appended automatically when the unit name contains no dot, so any systemd unit type works. If a unit appears in both enable and disable groups simultaneously, it is skipped with a warning.
|
||||
|
||||
State is tracked in `/var/lib/ansipa-policies/daemon-enabled` and `daemon-disabled` so revert actions are applied correctly when a host leaves a group.
|
||||
|
||||
### Security Scans & Alert Pipeline
|
||||
|
||||
```
|
||||
Client (policy-security-scan)
|
||||
└── daily 02:00: clamscan + rkhunter + chkrootkit
|
||||
└── smbclient → //ipa-server/ansipa-scans/archive/<host>/<date>.log
|
||||
|
||||
IPA container (hourly cron)
|
||||
└── ansipa-check-scans.sh
|
||||
└── grep for FOUND / Warning / Possible rootkit / etc.
|
||||
└── writes /data/scan-results/alerts/<host>/<date>.alert
|
||||
|
||||
Client (policy-scan-notify, every 10 min via systemd timer)
|
||||
└── ansipa-fetch-alerts.sh (root)
|
||||
└── downloads *.alert files → ~/administration/<host>/ per active user
|
||||
└── ansipa-scan-notify.sh (user daemon, started on login via profile.d)
|
||||
└── notify-send every 10 min while *.alert files remain
|
||||
└── delete file to acknowledge → removed from server on next fetch
|
||||
```
|
||||
|
||||
**Prerequisites for scan policies:**
|
||||
- Add host to `ansipa-module-anti-malware` before `policy-security-scan` (installs ClamAV, rkhunter, chkrootkit).
|
||||
- `samba-client` is installed automatically by `deploy-ansipa-policies.yml`.
|
||||
- SMB credentials are written to `/etc/ansipa-smb.creds` (root-only, `0600`).
|
||||
|
||||
---
|
||||
|
||||
|
|
@ -190,15 +342,40 @@ Keys are stored with mode `0400`. The store directory is created with mode `0700
|
|||
4. Key written to /_LUKS_BACKUP_KEY (mode 0400, root-only)
|
||||
inside the encrypted Btrfs volume
|
||||
|
||||
Post-install (Ansible)
|
||||
──────────────────────
|
||||
5. collect-luks-keys.yml runs from the controller
|
||||
6. Fetches /_LUKS_BACKUP_KEY from each client
|
||||
7. Stores as luks-keys/<HOSTNAME>_LUKS_BACKUP_KEY (mode 0400)
|
||||
on the controller
|
||||
Post-install (Ansible controller)
|
||||
──────────────────────────────────
|
||||
5. collect-luks-keys.yml runs
|
||||
6. Fetches /_LUKS_BACKUP_KEY from each client (become: yes)
|
||||
7. Uploads to //ipa-server/ansipa-luks-keys/<host>_LUKS_BACKUP_KEY
|
||||
as 'luks-upload' service account (write-only, no_log)
|
||||
8. Local staging copy deleted after successful upload
|
||||
|
||||
Recovery (KeyAdmin member)
|
||||
───────────────────────────
|
||||
9. Connect to //ipa-server/ansipa-luks-keys with a KeyAdmin Samba account
|
||||
10. Retrieve <host>_LUKS_BACKUP_KEY and use with cryptsetup
|
||||
```
|
||||
|
||||
The backup key lives inside the encrypted partition, so it is only accessible when the disk is already unlocked. Its purpose is to allow an admin to unlock the disk for recovery without knowing the user's passphrase.
|
||||
The backup key lives inside the encrypted partition and is only accessible when the disk is already unlocked. Its purpose is to allow an admin to unlock the disk for recovery without knowing the user's passphrase.
|
||||
|
||||
---
|
||||
|
||||
## Keycloak
|
||||
|
||||
`keycloak-configure.sh` performs the initial wiring after both FreeIPA and Keycloak containers are healthy:
|
||||
|
||||
1. Creates the configured realm in Keycloak.
|
||||
2. Sets up an LDAP federation pointing at the FreeIPA LDAP/LDAPS endpoint.
|
||||
3. Configures user and group mappers.
|
||||
|
||||
Run it once after the first `docker compose up`:
|
||||
|
||||
```bash
|
||||
cd setup/modules/FreeipaAnsible/image
|
||||
./keycloak-configure.sh
|
||||
```
|
||||
|
||||
The Keycloak admin console is available at `http://<KC_HOSTNAME>:8080` (dev mode) or `https://<KC_HOSTNAME>:8443` (requires TLS cert for production `start` command).
|
||||
|
||||
---
|
||||
|
||||
|
|
|
|||
|
|
@ -89,6 +89,20 @@ bash ~/Dotfiles/setup/install-modules.sh
|
|||
| `ssh-server` | openssh | SSH daemon with key-auth enforcement |
|
||||
| `wireshark` | wireshark-qt | Packet capture and analysis GUI |
|
||||
|
||||
### Virtualisation & Remote Desktop
|
||||
|
||||
| ID | Packages | Description |
|
||||
|----|---------|-------------|
|
||||
| `qemu` | qemu-full · libvirt · virt-manager · virt-viewer · dnsmasq · bridge-utils · edk2-ovmf · swtpm · vde2 | Full QEMU/KVM stack with virt-manager GUI; enables libvirtd, auto-starts default NAT network, adds user to `libvirt` and `kvm` groups |
|
||||
| `rdp-client` | remmina · freerdp · libvncserver | Remmina remote desktop client with RDP (FreeRDP) and VNC support |
|
||||
| `lamco-rdp-server` | lamco-rdp-server (AUR) | Native Wayland RDP server written in Rust with H.264/VA-API encoding; runs as a systemd user service |
|
||||
|
||||
**lamco-rdp-server notes:**
|
||||
- Enabled as a user service: `systemctl --user enable lamco-rdp-server.service`
|
||||
- Start manually: `systemctl --user start lamco-rdp-server`
|
||||
- Optional GUI tray: `lamco-rdp-server-gui`
|
||||
- Requires an `xdg-desktop-portal` matching your compositor (`-hyprland`, `-wlr`, `-gnome`, `-kde`)
|
||||
|
||||
### Development
|
||||
|
||||
| ID | Packages | Description |
|
||||
|
|
|
|||
|
|
@ -23,8 +23,9 @@ To add modules to an existing system: `bash ~/Dotfiles/setup/install-modules.sh`
|
|||
- **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.
|
||||
- **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). Collectable via Ansible.
|
||||
- **Custom ISO** — `setup/archiso/` builds a live USB that can embed a pre-baked answerfile for zero-touch deployment.
|
||||
- **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.
|
||||
- **FreeIPA + Keycloak + Samba container** — `setup/modules/FreeipaAnsible/image/` ships a single `docker compose up` stack: FreeIPA for identity, Keycloak for OIDC, and Samba for scan-result and LUKS-key SMB shares. Host-group-driven policies (binary blocking, daemon enable/disable, daily scans, alert delivery) are enforced on enrolled clients every 30 minutes via Ansible-deployed timers.
|
||||
- **Modular** — core, shell, services, and desktop are independent components; pick only what you need.
|
||||
|
||||
---
|
||||
|
|
@ -41,7 +42,7 @@ Full docs live in [`docs/md/`](docs/md/) (Markdown) and [`docs/html/`](docs/html
|
|||
| Theming & CyberQueer palette | [theming.md](docs/md/theming.md) | [theming.html](docs/html/theming.html) |
|
||||
| Optional modules & app catalogue | [modules.md](docs/md/modules.md) | [modules.html](docs/html/modules.html) |
|
||||
| Custom Archiso builder | [archiso.md](docs/md/archiso.md) | [archiso.html](docs/html/archiso.html) |
|
||||
| FreeIPA & Ansible | [freeipa-ansible.md](docs/md/freeipa-ansible.md) | [freeipa-ansible.html](docs/html/freeipa-ansible.html) |
|
||||
| FreeIPA, Ansible, Keycloak & SMB | [freeipa-ansible.md](docs/md/freeipa-ansible.md) | [freeipa-ansible.html](docs/html/freeipa-ansible.html) |
|
||||
| Editors (Neovim, Micro, Yazi) | [editors.md](docs/md/editors.md) | [editors.html](docs/html/editors.html) |
|
||||
| Utilities (encrypt, ClamAV, updates) | [utilities.md](docs/md/utilities.md) | [utilities.html](docs/html/utilities.html) |
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue