diff --git a/docs/md/ansipa-administration.md b/docs/md/ansipa-administration.md new file mode 100644 index 0000000..da34a88 --- /dev/null +++ b/docs/md/ansipa-administration.md @@ -0,0 +1,294 @@ +# ansipa Administration Guide + +Day-to-day operation of the ansipa management plane: the full policy catalogue +and how to apply, target, and revert each policy. For the deployment/ports/ +reverse-proxy story see the [ansipa Setup Guide](ansipa-setup.md); for the +architecture and container internals see [FreeIPA & Ansible](freeipa-ansible.md). + +--- + +## How administration works + +Everything is driven by **FreeIPA group membership**. You never log into a +client to change its policy — you add or remove a host or user from a group on +the FreeIPA server, and the fleet converges on the next timer tick. + +Two independent client-side mechanisms consume that membership, both installed +by the Ansible playbooks and both idempotent and reversible (leaving a group +undoes the change on the next run): + +| Mechanism | Timer | Reads | Applies | +|-----------|-------|-------|---------| +| **Policy enforcer** (`ansipa-enforce-policies.sh`) | `ansipa-enforce-policies.timer`, every 30 min | host + user groups | daemon/sudo/ssh/monitoring/scan/SMB/block policies | +| **Installer timers** (`ansipa-install-*.sh`) | `ansipa-install*.timer`, every 30 min | `dev_pkg_*`, `dev_mod_*`, `dev_fp_*` host groups | packages, setup modules, Flatpaks | + +Because it is all client-**pull**, everything works across NAT (the server never +initiates a connection to a client). To apply a change immediately instead of +waiting for the timer, run the relevant script on the client as root: + +```bash +sudo /usr/local/bin/ansipa-enforce-policies.sh # policies +sudo /usr/local/bin/ansipa-install-packages.sh # dev_pkg_* +sudo /usr/local/bin/ansipa-install-modules.sh # dev_mod_* +sudo /usr/local/bin/ansipa-install-flatpaks.sh # dev_fp_* +``` + +### The two group scopes + +- **Host groups** (`dev_*`) — a *device* policy. Applies to the machine(s) you + add to the group. Managed with `ipa hostgroup-*`. +- **User groups** (`usr_*`) — a *user* policy that **follows the user** to every + enrolled machine they log into. Applies while the group exists; managed with + `ipa group-*`. Several user policies key off the group merely *existing* (not + the specific host), because the enforcer runs on every host. + +### The two ways to bind a target + +Most policies encode their target in the **group name suffix** +(`dev_local-sudo-alice`, `dev_pkg_htop`, `usr_block-binary-nano`). A few need +extra data (a printer URI, an SMB credential) which lives in the **group +description**, set with `ipa group-mod --desc='…'` — noted per-policy below. + +### Everyday commands + +```bash +# Create + populate a host group (device policy) +ipa hostgroup-add dev_mon_base --desc "CheckMK monitored hosts" +ipa hostgroup-add-member dev_mon_base --hosts=client01.corp.example.com +ipa hostgroup-remove-member dev_mon_base --hosts=client01.corp.example.com + +# Create + populate a user group (user policy) +ipa group-add usr_admin --desc "Fleet-wide sudoers" +ipa group-add-member usr_admin --users=alice +ipa group-remove-member usr_admin --users=alice + +# Inspect +ipa host-show client01.corp.example.com | grep -A3 'Member of host-groups' +ipa hostgroup-show dev_pkg_htop +``` + +Everything below can equally be done from the FreeIPA web UI +(**Identity → Host Groups / User Groups**). + +--- + +## Device policies (`dev_*` host groups) + +### `dev_daemon-enable-` / `dev_daemon-disable-` +Force a systemd unit on or off fleet-wide. + +- **Apply:** enable → `systemctl enable --now `; disable → `disable --now`. +- **Revert (leave group):** the opposite action. +- The `.service` suffix is optional (appended automatically for a bare name); any + unit type works. A unit in **both** enable and disable groups is skipped with a + warning. +- **Example:** `ipa hostgroup-add dev_daemon-disable-bluetooth` then add hosts → + `bluetooth.service` is stopped and masked-off on them. + +> ⚠️ Enabling `sshd` this way and later reverting will **stop sshd** — don't lock +> yourself out of a headless box you only reach over SSH. + +### `dev_timeshift-backup` +Enforce a daily Timeshift snapshot at 03:00 (requires `timeshift`; add the host +to `dev_mod_timeshift` to install it). Leaving the group removes the cron. + +### `dev_no-local-users` +Lock the password of **every** local account — root (UID 0) and all regular +users (UID ≥ 1000) — with `passwd -l`, so only FreeIPA accounts can authenticate. +Accounts already locked are left untouched and not tracked; revert unlocks only +what this policy locked. State: `/var/lib/ansipa-policies/no-local-users`. + +### `dev_local-sudo-` +Grant `` full sudo on **this specific device** via a sudoers drop-in. +Device-scoped (unlike `usr_admin`). Leaving the group removes the drop-in. + +- **Example:** `ipa hostgroup-add dev_local-sudo-alice` + add `lab-pc-3` → alice + gets sudo on `lab-pc-3` only. + +### `dev_ssh_` +Distribute ``'s SSH public keys from their IPA profile to +`/home//.ssh/authorized_keys` on hosts in the group (in an +ansipa-managed section; hand-added keys are preserved). Store the keys in IPA: + +```bash +ipa user-mod alice --sshpubkey='ssh-ed25519 AAAA...' +ipa hostgroup-add dev_ssh_alice && ipa hostgroup-add-member dev_ssh_alice --hosts=… +``` + +Leaving the group removes only the ansipa-managed section. + +--- + +## Monitoring policies (`dev_mon_*`, `usr_mon_*`) + +All CheckMK monitoring requires the CheckMK stack to be up and +`ansipa-checkmk-setup.sh` to have run on the FreeIPA container (seeds the +`dev_mon_base` credentials + the monitoring groups in IPA). All checks are +collected by the agent, so **every monitored host must also be in +`dev_mon_base`**. + +### `dev_mon_base` (required for all monitoring) +Installs the CheckMK agent, registers the host in CheckMK (under `/ansipa`), and +opens the agent for collection: pull mode on `check_mk.socket` (port 6556) where +the server can reach the client, or **push mode** (`cmk-agent-ctl` → server +`:8000`) for NAT clients. Built-in CPU/RAM/disk/uptime plus an installed-package +count check (`Ansipa_Packages`). Leaving the group deregisters the host and +disables the agent. + +> Credentials are auto-discovered from the `dev_mon_base` group description +> (`cmk://:/:automation:`), which the server populates. +> Set `CMK_ADVERTISED_URL` in `.env` to a **client-routable** address. + +### `dev_mon_clamscan` +Run a daily ClamAV + rkhunter + chkrootkit scan at 02:00 and report the result +to CheckMK as the **`Ansipa_ClamScan`** service (OK = clean, WARN = stale DB or +rkhunter warnings, CRIT = infected). Self-contained — it runs the scan *and* +writes the local check; results no longer go over SMB. + +- **Prerequisites:** `dev_mod_anti-malware` (tools) + `dev_mon_base` (agent). +- **Revert:** removes the cron, scan script, log, and local check. + +### `dev_mon_timeshift` +`Ansipa_Timeshift` check on the newest Timeshift snapshot age: WARN > 5 days, +CRIT > 10 days or none found. Pair with `dev_timeshift-backup` (which creates +them) and `dev_mon_base`. + +### `dev_mon_power` +`Ansipa_Power` check on CPU-package power via Intel RAPL (preferred) or +lm-sensors: WARN ≥ 65 W, CRIT ≥ 95 W. Add the host to `dev_mod_*` that installs +`lm_sensors` if RAPL is unavailable. + +### `usr_mon_logins` (user group) +`Ansipa_Logins` check reporting SSH login attempts in the last 24 h (successful + +failed + invalid-user), with thresholds. Installed fleet-wide when the group +exists; needs `dev_mon_base` on the hosts. + +--- + +## Software-installer policies (`dev_pkg_*`, `dev_mod_*`, `dev_fp_*`) + +These are the GPO-like software-deployment groups, applied by the +`ansipa-install-*` timers (not the policy enforcer). Join → installed; leave → +removed. Install state is tracked so revert only touches what ansipa installed. + +### `dev_pkg_` +Install a single distro package (via pacman/dnf/apt — auto-detected). + +```bash +ipa hostgroup-add dev_pkg_htop && ipa hostgroup-add-member dev_pkg_htop --hosts=… +``` + +### `dev_mod_` +Apply a whole **setup module** from `setup/modules/optional-Modules/apps/` — +e.g. `dev_mod_docker`, `dev_mod_anti-malware`, `dev_mod_timeshift`, +`dev_mod_ollama`. This is how you install the tools other policies need +(`dev_mod_anti-malware` before `dev_mon_clamscan`, `dev_mod_timeshift` before +`dev_timeshift-backup`). + +### `dev_fp_` +Install a Flathub Flatpak. Encode the app ID with `__` in place of `.`: + +```bash +# org.gimp.Gimp +ipa hostgroup-add dev_fp_org__gimp__Gimp +ipa hostgroup-add-member dev_fp_org__gimp__Gimp --hosts=… +``` + +--- + +## User policies (`usr_*` user groups) + +### `usr_admin` +Full sudo on **every** enrolled host for members, via a `%usr_admin` sudoers +drop-in resolved through SSSD. Active while the group exists; the drop-in is +removed when the **group is deleted** (not merely when a member leaves — removing +a member just drops that user's sudo, since it is group-based). + +### `usr_block-binary-` +Prevent members from running `` on any enrolled host via a PATH-priority +wrapper that checks group membership at runtime. Use `__` for `.` to block a +Flatpak (`usr_block-binary-org__gimp__Gimp`). Non-members are unaffected +(the wrapper transparently execs the real binary). Deleting the IPA group removes +the wrapper. + +### `usr_prt_` +Auto-add `` to CUPS on any host where a member is logged in. **Store the +printer URI in the group description:** + +```bash +ipa group-add usr_prt_frontdesk --desc='ipps://printserver/printers/frontdesk' +ipa group-add-member usr_prt_frontdesk --users=alice +``` + +Requires `cups` (installed by the policy deploy). Leaving/deleting removes the +printer. + +### `usr_smb_r_` / `usr_smb_rw_` +Auto-mount a Samba share at `~/` for logged-in members (`rw` wins if a user +is in both). **Store the credential in the group description** (written by +`ansipa-smb-setup.sh` for the built-in shares): + +``` +cifs://:: +``` + +Requires `cifs-utils` (installed by the policy deploy). Leaving unmounts on the +next run. + +### `usr_smb_adm_policystore` +Mount the policy store at `~/policystore` (rw) for admin members, so you can edit +the live `policies.d/*.sh` files directly on the share — changes take effect +fleet-wide on the next 30-min enforcer tick, no redeploy needed. Credential in +the group description (auto-set by `ansipa-smb-setup.sh`). + +--- + +## BaseUser sync (`BaseUser` group) +Not a policy script — a `systemd.path` unit (deployed by +`deploy-baseuser-sync.yml`) that, on login, adds any member of the FreeIPA +`BaseUser` group to the local `baseusers` group. Use it to grant a baseline local +group to all standard users. + +--- + +## Common recipes + +**Onboard a new workstation** (identity + monitoring + a couple of apps): +```bash +H=ws-42.corp.example.com +ipa hostgroup-add-member dev_mon_base --hosts=$H +ipa hostgroup-add-member dev_mon_clamscan --hosts=$H +ipa hostgroup-add-member dev_mod_anti-malware --hosts=$H # installs clamav/rkhunter +ipa hostgroup-add-member dev_mod_docker --hosts=$H +ipa hostgroup-add-member dev_pkg_htop --hosts=$H +# then, on the box (or wait 30 min): +sudo /usr/local/bin/ansipa-enforce-policies.sh +sudo /usr/local/bin/ansipa-install-modules.sh +``` + +**Give a helpdesk user sudo everywhere, block a risky tool:** +```bash +ipa group-add-member usr_admin --users=bob +ipa group-add usr_block-binary-tcpdump && ipa group-add-member usr_block-binary-tcpdump --users=intern +``` + +**Edit policy logic live** (as an admin in `usr_smb_adm_policystore`): +```bash +$EDITOR ~/policystore/dev_mon_clamscan.sh # applied fleet-wide next enforcer tick +``` + +--- + +## Troubleshooting + +| Symptom | Check | +|---------|-------| +| Policy not applying | `sudo /usr/local/bin/ansipa-enforce-policies.sh` on the client; read the `[ansipa-policies]` discovery line — is the group listed? | +| Host not in CheckMK | Is it in `dev_mon_base`? Is `CMK_ADVERTISED_URL` client-routable? `ipa hostgroup-show dev_mon_base` description present? | +| ClamAV shows "no scan yet" | Scans run 02:00; trigger once with `sudo /usr/local/bin/ansipa-clamscan.sh`. Tools installed via `dev_mod_anti-malware`? | +| Package group ignored | `dev_pkg_*` uses the *installer* timer, not the enforcer — run `sudo /usr/local/bin/ansipa-install-packages.sh`. | +| Enforcer error `ipa: command not found` | The host is not enrolled — run `freeipa-enroll.sh` first. | +| Changes take up to 30 min | That's the timer cadence; run the script manually to apply now. | + +State for all policies lives under `/var/lib/ansipa-policies/`; logs go to the +journal under the `ansipa-policies` tag (`journalctl -t ansipa-policies`). diff --git a/docs/md/index.md b/docs/md/index.md index e6ddf89..589910d 100644 --- a/docs/md/index.md +++ b/docs/md/index.md @@ -17,6 +17,7 @@ A production-grade Arch Linux configuration for network administration, developm | [Modules](modules.md) | Core modules and full optional-app catalogue | | [Archiso](archiso.md) | Building the custom live installer ISO | | [ansipa Setup Guide](ansipa-setup.md) | Full deployment: ports, nginx portal + reverse proxy, NAT, enrollment | +| [ansipa Administration](ansipa-administration.md) | Day-to-day operation: the full policy catalogue + recipes | | [FreeIPA & Ansible](freeipa-ansible.md) | Identity management and automated config deployment | | [Editors](editors.md) | Neovim, Micro, Yazi | | [Utilities](utilities.md) | Encryption helpers, ClamAV, credentials, update scripts |