System-level configuration files (/etc, /efi, /root) managed with
dotm using dest = "/".
- Atomic upgrades: via atomic-upgrade (per-host config override)
- Boot: systemd-boot with signed UKI (Secure Boot via sbctl)
- Filesystem: Btrfs on LUKS, automated snapshots via btrbk
- Network: systemd-networkd (wired + wifi)
- Firewall: firewalld with per-user network blocking and trusted zone templating
- Containers: Podman with btrfs storage driver
- Hardening: kernel sysctl, faillock, coredump off, USB lock, pam, hardened_malloc
- Nextcloud blocking: pacman hook prevents Nextcloud installation for user_c (controlled by
block_nextcloud_user_cprompt)
dotm's perms file sets mode, owner, and group on deployed files. Glob patterns, last match wins.
efi/**/ 0755 root root
efi/** 0755 root root
etc/**/ 0755 root root
etc/** 0644 root root
etc/polkit-1/rules.d/** 0750 root polkitd
root/**/ 0700 root root
root/** 0600 root root
Pattern ending with / matches directories only; without — files only. ** matches zero or more path segments. - means "don't change this attribute".
Installed as a separate package via gitpkg:
gitpkg install hardened_mallocSee hardened_malloc for details on variants, fake_rlimit shim, and compatibility notes.
The atomic-upgrade package is installed separately. This repo provides:
/etc/atomic.conf— per-host kernel parameters (TPM2 auto-unlock, etc.) via dotm template
firewalld configuration is templated with secrets from SOPS.
When block_network_user_c is enabled, firewalld direct rules drop all outbound IPv4/IPv6 traffic for the specified UID via iptables owner match:
<rule ipv="ipv4" table="filter" chain="OUTPUT" priority="0">-m owner --uid-owner <UID> -j DROP</rule>
<rule ipv="ipv6" table="filter" chain="OUTPUT" priority="0">-m owner --uid-owner <UID> -j DROP</rule>The UID is read from secrets.enc.yaml (users.user_c.uid).
The trusted zone template adds:
tun0interface (VPN)- Local subnet and Podman subnet as trusted sources
Subnet values are stored encrypted in secrets.enc.yaml (firewall.subnet1, firewall.podman_subnet).
.
├── dotm.toml # dotm config (dest, prompts)
├── perms # Permission rules (glob → mode/owner/group)
├── ignore.tmpl # Conditional ignore patterns
├── secrets.enc.yaml # SOPS-encrypted secrets (age)
├── .sops.yaml # SOPS recipients config
└── files/
├── efi/
│ └── loader/
│ └── loader.conf # systemd-boot config
├── etc/
│ ├── atomic.conf.tmpl # atomic-upgrade config override
│ ├── btrbk/
│ │ └── btrbk.conf.tmpl # Snapshot policy (per-host targets)
│ ├── containers/
│ │ └── storage.conf.tmpl # Podman (btrfs driver, per-host graphroot)
│ ├── firewalld/
│ │ ├── direct.xml.tmpl # Per-user outbound block (iptables owner match)
│ │ └── zones/
│ │ └── trusted.xml.tmpl # Trusted zone (VPN, subnets)
│ ├── mkinitcpio.conf # Initramfs base config
│ ├── mkinitcpio.conf.d/
│ │ └── 10-default.conf.tmpl # Drop-in (per-host nvidia modules)
│ ├── mkinitcpio.d/
│ │ └── linux.preset # Preset
│ ├── modprobe.d/
│ │ └── 10-nvidia.conf # NVIDIA kernel module options
│ ├── modules-load.d/
│ │ └── modules.conf # Kernel modules to load at boot
│ ├── pacman.conf # Pacman configuration
│ ├── pacman.d/
│ │ └── hooks/
│ │ └── block-nextcloud-user_c.hook
│ ├── pam.d/
│ │ └── login # PAM (gnome-keyring auto-unlock)
│ ├── polkit-1/
│ │ └── rules.d/
│ │ └── 99-sing-box.rules.tmpl
│ ├── security/
│ │ └── faillock.conf # Account lockout policy
│ ├── sysctl.d/
│ │ └── 10-default.conf # Kernel parameters
│ ├── systemd/
│ │ ├── coredump.conf # Coredump disabled
│ │ ├── journald.conf # Journal settings
│ │ ├── network/
│ │ │ ├── 10-wire.network # Wired network
│ │ │ └── 11-wifi.network # WiFi network
│ │ └── zram-generator.conf # Zram swap
│ └── tmpfiles.d/
│ ├── battery.conf # Battery charge thresholds
│ └── usb-lock.conf # USB authorization lock
└── root/
└── .zshrc # Root shell config
Feature flags are set via dotm init prompts and cached in ~/.local/state/dotm/:
| Variable | Description |
|---|---|
nvidia |
NVIDIA GPU (mkinitcpio modules, modprobe config) |
tpm2_unlock |
TPM2 LUKS auto-unlock (rd.luks.options=tpm2-device=auto) |
laptop |
Battery charge thresholds (tmpfiles) |
block_nextcloud_user_c |
Block Nextcloud access for user_c |
block_network_user_c |
Block all network access for user_c (firewalld direct rules) |
Per-host data (btrbk targets, podman graphroot, firewall subnets, user UIDs) is stored in secrets.enc.yaml, keyed by hostname or category.
Each machine has its own age key, stored separately from this repo.
# secrets.enc.yaml (decrypted view)
polkit:
username: "actual_username"
firewall:
subnet1: "192.168.x.x/24"
podman_subnet: "10.x.x.x/16"
users:
user_c:
uid: 1001Templates access secrets via:
{{ $s := output "sops" "-d" (joinPath .sourceDir "secrets.enc.yaml") | fromYaml -}}
{{ index $s "polkit" "username" }}
- Generate age key:
age-keygen -o /root/age.key
export SOPS_AGE_KEY_FILE=/root/age.key- Add public key to
.sops.yamland re-encrypt:
sops updatekeys secrets.enc.yaml- Clone and apply:
git clone <GIT_URL> /root/rootfiles
cd /root/rootfiles
dotm init
dotm apply# Install hardened_malloc
gitpkg install hardened_malloc
# Install atomic-upgrade
gitpkg install atomic-upgrade
# Enable zram
sudo systemctl start systemd-zram-setup@zram0.service
# Create snapshot directories for btrbk
sudo mkdir -p /snapshots/{root,home}
sudo systemctl enable --now btrbk.timer- dotm — dotfiles manager
sops+age— secret encryption
- hardened_malloc — hardened memory allocator (via gitpkg)
- atomic-upgrade — atomic system upgrades (via gitpkg or AUR)
btrbk— automated Btrfs snapshotspodman— containers (btrfs storage driver)firewalld— firewall with per-user blocking and trusted zones
AGPL-3.0-or-later