Commit Graph

950 Commits (a84e6ac41cb357ef5fc0da964916af7cd9b20f0b)

Author SHA1 Message Date
Amir Alexander Abdelbaki a84e6ac41c feat(archiso): add system reset mode to installer
Adds a post-keymap action selection to launch.sh (Install vs Reset).
The reset routine (reset-arch.sh) unlocks LUKS via FIDO2 token and/or
passphrase, snapshots /etc credentials and config, wipes and recreates
the @ btrfs subvolume, reinstalls base packages via pacstrap, restores
auth files (passwd/shadow/pam.d/sudoers) and system config, then
regenerates the initramfs and GRUB menu from chroot. User home data is
preserved; ~/.config is cleared except Yubico/ auth keys so FIDO2 PAM
login continues to work. libfido2 added to packages.extra for live-env
token unlock support.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-20 15:09:00 +02:00
Amir Alexander Abdelbaki c56c86d57b fix(freeipa): harden container SMB setup and fetch-alerts script
ansipa-smb.service: WantedBy=multi-user.target (was smb.service) so the
  setup service always runs at boot, not only when smb.service pulls it in

docker-compose.yml: add NetBIOS UDP ports 137/138 to match Dockerfile EXPOSE
  and nmb.service being enabled

ansipa-smb-setup.sh:
  - use printf '%q' when writing SMB_SCAN_PASSWORD to ansipa-smb.env so
    passwords with spaces or shell-special chars are correctly quoted
  - always write /etc/cron.d/ansipa-check-scans (remove the [[ ! -f ]] guard)
    since /etc/cron.d is on the ephemeral container layer and is lost on
    container recreation; the service runs on every start anyway

Dockerfile: add -e SMB_SCAN_PASSWORD and -p 445:445 to the quick-test comment

ansipa-fetch-alerts.sh: replace $NEW && log with [[ "$NEW" == true ]] && log
  to avoid set -e ambiguity with the 'false' builtin

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-20 13:13:53 +02:00
Amir Alexander Abdelbaki 11e66dbddd feat(freeipa): scan result reporting, alert notifications, and SMB share
Container (ansipa image):
- Add samba + cronie to Dockerfile; expose ports 445/139
- ansipa-smb-setup.sh: idempotent setup of smbd + scanupload user +
  /data/scan-results/{archive,alerts}/ on every container start
- ansipa-smb.service: runs setup before smb.service on each boot
- ansipa-check-scans.sh: hourly cron on server; analyses archive logs for
  ClamAV/rkhunter/chkrootkit findings and writes <host>/<date>.alert files
- docker-compose.yml: add SMB_SCAN_PASSWORD env var + port mappings
- .env.example: document SMB_SCAN_PASSWORD

Client (policy-security-scan):
- Scan script now uploads log to //ipa-server/ansipa-scans/archive/<host>/
  via smbclient after each run

Client (policy-scan-notify — new policy group):
- ansipa-fetch-alerts.sh: root timer (10 min) downloads alerts from SMB into
  ~/administration/<hostname>/ for each active login session; deletes server
  alert when user removes local file (acknowledgment)
- ansipa-scan-notify.sh: user daemon started via /etc/profile.d/ansipa-notify.sh;
  sends notify-send every 10 min while *.alert files remain in ~/administration/
- deploy-ansipa-policies.yml: installs samba-client, deploys SMB creds file
  (/etc/ansipa-smb.creds, 0600), and deploys both notification scripts

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-20 12:32:21 +02:00
Amir Alexander Abdelbaki fb8ca498ef feat(freeipa): add AppArmor deny profiles to binary blocking policy
Binary blocking now applies two layers:
  1. PATH-priority wrapper in /usr/local/bin/ (existing)
  2. Empty AppArmor profile in /etc/apparmor.d/ loaded in enforce mode

An empty AppArmor profile denies all access — the blocked binary cannot
load shared libraries and exits immediately with a permission error,
covering callers that use absolute paths and bypassed the wrapper.

AppArmor layer is skipped silently when apparmor_parser is not present,
and deferred with a warning if the real binary is not yet installed.
Profiles are unloaded and deleted when the host leaves the policy group.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-20 12:00:55 +02:00
Amir Alexander Abdelbaki 45fd7e5d36 feat(freeipa): add policy enforcement for binary blocking, backups, scans, and sudo
Introduces a FreeIPA host-group-driven policy system alongside a sudo
rules management playbook:

- ansipa-enforce-policies.sh: client-side enforcer (systemd timer, 30 min)
  - policy-block-binary-<name>: PATH-priority wrapper blocks the binary
  - policy-timeshift-backup: daily Timeshift snapshot cron (03:00)
  - policy-security-scan: daily ClamAV/rkhunter/chkrootkit cron (02:00)
  Policies are reversible — leaving a group removes enforcement on next run.

- deploy-ansipa-policies.yml: deploys enforcer + systemd service/timer to clients

- manage-sudo-rules.yml: creates FreeIPA sudo rules (allow_sudoers,
  allow_sudo_nopasswd) that SSSD clients already pick up via --sudo enrollment.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-20 11:34:09 +02:00
Amir Alexander Abdelbaki da0a9e7a32 fix(archiso): move user input before partitioning, fall back to bash on exit
Keymap selection was unreachable because user input ran after pacman/partition
steps that could fail under set -e. Move the entire user input block (kernel,
hostname, username, encryption, keymap) to before lsblk and drive selection.
Also remove the redundant live-env keymap section (launch.sh handles that).

Drop exec from .zlogin so quitting the installer returns to a bash shell
instead of ending the session.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-20 07:20:14 +02:00
Amir Alexander Abdelbaki f08aa29c7a feat(archiso): add keymap selection to launch.sh, default de-latin1-nodeadkeys
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-20 00:18:54 +02:00
Amir Alexander Abdelbaki 6ccc91303f fix(setup): port KEYMAPS+vconsole support to auto-installer and answerfile generator
arch-autoinstall.sh was missing the keymap handling added to the guided
installer in the previous two commits, so booting the ISO in auto mode
(answerfile embedded) never called loadkeys and left the installed system
with no /etc/vconsole.conf.

- Add the same KEYMAPS array + selection logic to arch-autoinstall.sh
  (AF mode reads .keymap, interactive mode prompts)
- Call loadkeys and export KEYMAP into the chroot
- Write /etc/vconsole.conf inside the chroot
- Add keymap dialog to generate-answerfile.sh so the field is populated
- Document .keymap in the arch-autoinstall.sh answerfile field list

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-20 00:01:19 +02:00
Amir Alexander Abdelbaki 77c3e1def8 feat(setup): replace hardcoded loadkeys with a KEYMAPS-array menu
Both the live-environment prompt and the installed-system prompt now
loop over a single KEYMAPS array, so adding a new layout is a
one-line change.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-19 23:37:01 +02:00
Amir Alexander Abdelbaki 58de8fac1b chmod setup/archiso/build.sh 2026-05-19 23:19:53 +02:00
Amir Alexander Abdelbaki ef599a111e feat(setup): add keymap selection dialog to guided installer
Prompts for us/de keymap interactively; reads .keymap from answerfile in unattended mode. Writes /etc/vconsole.conf in chroot.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-19 23:18:50 +02:00
Amir Alexander Abdelbaki 9e541eb21b fix(archiso): chown work and output dirs back to user after mkarchiso
sudo mkarchiso leaves files owned by root, causing rm -rf to fail on re-runs.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-19 22:24:25 +02:00
Amir Alexander Abdelbaki 278ffb4a5a feat(archiso): auto-start guided installer on boot, use answerfile for unattended mode
.zlogin execs .automated_script.sh on login, which checks for /answerfile.json;
if present it runs the auto installer (passing the path), otherwise launches the
guided installer directly — no manual invocation needed.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-19 22:20:30 +02:00
Amir Alexander Abdelbaki 33934f633d feat(setup): add anti-malware module with freshclam cron job
Adds clamav, clamtk, rkhunter, chkrootkit and installs a twice-daily
/etc/cron.d/freshclam entry for automatic virus definition updates.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-19 19:58:35 +02:00
Amir Alexander Abdelbaki c7511b750a adjusted size of eww bar - i found the sweet spot 2026-05-19 18:31:18 +02:00
Amir Alexander Abdelbaki 9f480eb1b1 adjusted size of eww bar 2026-05-19 18:30:02 +02:00
Amir Alexander Abdelbaki 6a9d286e55 fixed workspace navigation 2026-05-19 18:26:28 +02:00
Amir Alexander Abdelbaki a8e9a4b49b fix(nvim): use coc#pum API for Enter confirmation
pumvisible() checks the native Vim pum, which coc.nvim bypasses in
favour of its own popup — so the confirm never fired. Switch to
coc#pum#visible() / coc#pum#confirm() to match the Tab/S-Tab bindings.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-19 18:25:30 +02:00
Amir Alexander Abdelbaki 7fe95c8b72 fix(eww): port hyprctl dispatch calls to Lua API
Replace hyprctl dispatch with hyprctl eval using hl.dsp.* in all
three eww variants. Workspace switching uses hl.dsp.focus with r+/r-
relative prefixes; killactive becomes hl.dsp.window.close(); exec
uses hl.dsp.exec_cmd.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-19 16:57:10 +02:00
Amir Alexander Abdelbaki ef4a0a483d fix(scripts): port screen rotation to Lua config
Replace hyprctl keyword with hyprctl eval + hl.monitor/hl.device Lua API,
and switch monitor/device parsing from fragile grep to hyprctl -j + jq.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-19 16:41:52 +02:00
Amir Alexander Abdelbaki f880191764 fix(scripts): update caffeine and toggle-touchpad to Lua config syntax
Replace hyprctl dispatch exec with direct daemon invocation in caffeine.sh,
and replace defunct \$LAPTOP_KB_ENABLED .conf variable with the actual
device key path in hyprland-toggle-touchpad.sh.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-19 16:29:53 +02:00
Amir Alexander Abdelbaki 7b9379b1c1 feat(binds): convert gestures to new Hyprland Lua syntax
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-19 15:00:26 +02:00
Amir Alexander Abdelbaki b5b21ce4cd fixed issue with resizing windows with keyboard shortcuts 2026-05-19 14:54:13 +02:00
Amir Alexander Abdelbaki 820a12616c fixed theming issues 2026-05-19 14:39:29 +02:00
Amir Alexander Abdelbaki 1c278b3830 fix(qt): drop custom style plugin, use Fusion + qt6ct custom palette
The cyberqueer style plugin only overrode polish(QPalette&) with colors
identical to those already in cyberqueer.conf. Qt failed to load the
plugin for apps after the first, falling back to Fusion Light entirely.
Switching to the built-in Fusion style with qt6ct's custom_palette
mechanism gives the same result reliably for every app.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-19 14:05:49 +02:00
Amir Alexander Abdelbaki 3a49ab44d9 feat(qt,gtk): overhaul theming — qt6ct style plugin, dark palette, GTK color-scheme
Qt: replace QT_STYLE_OVERRIDE/QT_STYLE_SHEET env vars with QT_QPA_PLATFORMTHEME=qt6ct +
QT_QUICK_CONTROLS_STYLE=Fusion; add cyberqueer Qt6 style plugin (QProxyStyle wrapping
Fusion with hardcoded dark palette); enable custom_palette in qt6ct.conf so qt6ct applies
the dark QPalette directly for both Qt Widgets and Qt Quick apps.

GTK: fix dark mode not applying — set gtk-application-prefer-dark-theme=1 in GTK3
settings.ini; add gsettings color-scheme=prefer-dark to install script (required by
libadwaita apps which ignore gtk-theme-name); add index.theme so the theme is recognized
by GTK theme discovery.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-19 13:43:13 +02:00
Amir Alexander Abdelbaki cfb949dff3 timeshift installer module 2026-05-19 11:49:25 +02:00
Amir Alexander Abdelbaki 3cd4cb5df7 fix(hyprlua): theme and position vicinae correctly
Move settings.json out of the wrong vicinae/vicinae/ subdir so it deploys
to ~/.config/vicinae/settings.json where vicinae actually reads it, enabling
the cyberqueer theme. Add GTK_THEME=cyberqueer on launch for correct font
rendering. Add float=true to the launcher window rule so the cursor-position
move formula is applied.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-19 11:48:14 +02:00
Amir Alexander Abdelbaki bf4821c48e fix(hyprlua): correct Lua dispatcher API calls in binds.lua
- window.tag: pass table { tag = "..." } instead of bare string
- window.cycle_next: remove invalid false argument
- window.resize: use { x, y } fields instead of { delta = "x y" }
- group.change_active: replaced with hyprctl dispatch fallback (not in Lua API)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-19 11:13:18 +02:00
Amir Alexander Abdelbaki f453b1d3d3 feat(desktopenvs): add hyprland → hyprlua migration script
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-19 10:22:56 +02:00
Amir Alexander Abdelbaki 851a64d7f3 chore(nvim): untrack lazy-lock.json and add it to gitignore
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-19 09:07:17 +02:00
Amir Alexander Abdelbaki 51c93db7b5 feat(nvim): add claude-code.nvim plugin
Adds greggh/claude-code.nvim with plenary.nvim as a required dependency.
Provides :ClaudeCode toggle, continue/resume/verbose commands, and
<C-,> / <leader>cC keybinds out of the box.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-19 09:03:22 +02:00
Amir Alexander Abdelbaki a79be2fcbf chore(nvim): add lazy-lock.json for reproducible plugin installs
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-19 09:01:07 +02:00
Amir Alexander Abdelbaki 690b8ec217 fix(nvim): place airline cyberqueer theme inside rtp so it is auto-discovered
airline#themes#cyberqueer#palette was undefined because the theme file was
being copied under the wrong name (cyberqueer-airline.vim instead of
cyberqueer.vim). Fixed by adding the file at the proper rtp-relative path
nvim/autoload/airline/themes/cyberqueer.vim — picked up automatically via
the ~/.config/nvim symlink, no extra copy step needed. Removed the now-
redundant manual cp from shell-setup.sh.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-19 08:59:50 +02:00
Amir Alexander Abdelbaki 20cf670adb feat(nvim): convert config to Lua with lazy.nvim
Renames nvim/ → nvim.old/ (preserving init.vim + incomplete prior attempts)
and creates a fresh nvim/ with init.lua. All settings, keymaps, and plugin
declarations are converted from VimScript to Lua idioms. Plugin manager
migrated from vim-plug to lazy.nvim, which self-bootstraps on first launch.

shell-setup.sh updated to drop the vim-plug curl install; the symlink and
airline theme copy are retained (path updated for lazy's data directory).

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-19 08:56:43 +02:00
Amir Alexander Abdelbaki b629697ddd feat: add hyprlua config set and migrate hyprland envvars to dedicated file
Duplicates desktopenvs/hyprland/ as desktopenvs/hyprlua/ and converts all
Hyprland-specific configs (.conf) to Lua (.lua) using the 0.55+ hl.* API:
hyprland.lua, envvars.lua, monitors.lua, input.lua, autostart.lua,
windowrules.lua, binds.lua. Non-Hyprland tool configs (hyprpaper, hyprlock,
hypridle, hyprtoolkit) remain as .conf. Adds hyprlua.sh installer (user-side
.lua files install to ~/.config/hypr/ for require() resolution) and registers
HyprLua as the recommended DE option in tui-install.sh, marking the old
hyprlang-based Hyprland install as legacy.

Also consolidates hyprland (legacy) env vars into hypr-usr/envvars.conf,
removing duplicates from hyprland.conf and monitors.conf.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-19 08:50:23 +02:00
Amir Alexander Abdelbaki 2b282a1565 docs: replace readme with cliff notes and links to full docs
Old readme archived as readme.md.old.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-18 16:00:30 +02:00
Amir Alexander Abdelbaki be3352897c renamed old doc -> notes 2026-05-18 15:49:38 +02:00
Amir Alexander Abdelbaki 6c5c1f8589 gitignore: exclude generated docs/html/ build artifacts
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-18 15:48:47 +02:00
Amir Alexander Abdelbaki 8128ae84e4 docs: add full documentation site with CyberQueer HTML theme
9 Markdown pages covering installation, theming, Hyprland, editors,
modules, archiso, FreeIPA/Ansible, and utilities. md-to-html.sh
converts them to self-contained styled HTML using the live palette
from colors.conf with inline CyberQueer CSS.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-18 15:47:09 +02:00
Amir Alexander Abdelbaki f1ea6dcb54 ansible: add collect-luks-keys playbook for LUKS backup key archival
New playbook collect-luks-keys.yml connects to all enrolled FreeIPA
clients, checks for /_LUKS_BACKUP_KEY (placed there by the installer
when encryption is enabled), and fetches each key to the Ansible
controller as luks-keys/<HOSTNAME>_LUKS_BACKUP_KEY (mode 0400).

Hosts without the file are reported but not treated as errors.
The luks-keys/ store directory is created with mode 0700.

Usage:
  ansible-playbook -i inventory collect-luks-keys.yml

Can be scheduled via cron on the controller for automatic collection.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-18 15:25:05 +02:00
Amir Alexander Abdelbaki b5a3b46c79 setup: add answerfile system for fully automated installs
tui-install.sh:
  - Reads /answerfile.json if present (ANSWERFILE_MODE)
  - All dialog selections (components, DE, apps) sourced from file
  - Hostname from answerfile gets MAC address suffix appended to
    prevent conflicts when deploying one image to multiple machines
  - Interactive hostname inputbox added to the normal TUI flow
  - Colorway dialog added as final step; skipped if no colors differ
    from defaults and no answerfile colors are set
  - Answerfile mode: runs non-interactively, logs warnings on failure

generate-answerfile.sh (new):
  - Dry-runs the full installer dialog flow (OS + dotfiles)
  - Writes selections to ~/answerfile.json (or a given path)
  - No software is installed; passwords are never written to the file

build.sh:
  - New --preconf [FILE] flag embeds an answerfile into the ISO at
    /answerfile.json; omitting the flag leaves the ISO clean
  - Validates JSON with jq if available before embedding
  - Reworked arg parsing to handle the new flag alongside OUT_DIR

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-18 15:24:47 +02:00
Amir Alexander Abdelbaki e25dd231cb installer: add no-encryption option and auto LUKS backup key
Both arch-autoinstall.sh and archbaseos-guided-install.sh now ask
whether to enable disk encryption. If skipped, btrfs is formatted
directly on the root partition with an appropriate plain GRUB cmdline
(root=UUID=... rootflags=subvol=@).

When encryption is chosen, a 64-byte random key is generated, enrolled
as a second LUKS keyslot, and written to /_LUKS_BACKUP_KEY inside the
new system (mode 400, root-owned, inside the encrypted container).

Also fixes: duplicate 'encrypt' hook in original mkinitcpio HOOKS
strings, missing KERNEL export into arch-autoinstall chroot heredoc.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-18 15:24:29 +02:00
Amir Alexander Abdelbaki 19b31859f6 archiso: use HOME instead of /tmp for build and output dirs
/tmp in WSL is a RAM-backed tmpfs that fills up during the build,
leaving xorriso with no room to write the ISO.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-18 14:33:01 +02:00
Amir Alexander Abdelbaki d05eb3ad89 setup: add browser/IDE modules and lynx to core packages
New optional modules (browsers): chromium, firefox, zen-browser,
nyxt, librewolf, min-browser.
New optional modules (editors/IDEs): vscodium, zed, geany,
codeblocks, kate.
Add lynx to default core packages.

All 11 modules wired into both install-modules.sh and tui-install.sh
(the archiso-embedded installer) with consistent count_steps,
checklist, summary, and dispatch entries. Every module path verified
to exist; all scripts pass bash -n syntax check.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-18 14:23:43 +02:00
Amir Alexander Abdelbaki ecd272cdce archiso: make WORK_DIR and OUT_DIR overridable via env vars
/tmp fills up during large builds; allow redirecting both dirs without
editing the script (WORK_DIR=~/iso-work ./build.sh ~/iso-out).

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-18 14:11:50 +02:00
Amir Alexander Abdelbaki 39f31f9d46 setup: check network connectivity before installer and launch nmtui if offline
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-18 13:35:24 +02:00
Amir Alexander Abdelbaki 089841f5d3 archiso: fix deprecated boot modes and grub/systemd-boot conflict
Replace five deprecated boot mode names with the canonical 'bios.syslinux'
and 'uefi.systemd-boot', removing the ia32 grub mode that required grub
installed and conflicted with systemd-boot.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-18 13:29:58 +02:00
Amir Alexander Abdelbaki 94fea62255 gitignore: ignore build and image output artifacts
Add patterns for disk images, archives, and packages generated by setup scripts.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-18 12:58:45 +02:00
Amir Alexander Abdelbaki 86cf9b954f setup: add dust to core packages and POV-Ray to blender module
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-18 12:17:56 +02:00