This repository has been archived on 2026-08-17. You can view files and clone it. You cannot open issues or pull requests or push a commit.
Files
debian-configuration/freeipa/docs/install.md
T
beatzaplentyandClaude Sonnet 4.6 761fe9e194
Secret Scan / Scan for secrets and sensitive config (push) Failing after 4s
Secret Scan / Scan for secrets and sensitive config (pull_request) Failing after 3s
docs(freeipa): update IPs and remove Pi-hole references
- IPA now runs at 192.168.2.253 (previously shown as .138 in install docs)
- cloud-init nameserver and nmcli DNS during install use .254 (gateway)
  since IPA isn't running yet at that point
- --forwarder updated to 192.168.2.254 (LAN gateway, Pi-hole is gone)
- Remove Step 7 (Pi-hole DNS forwarding config) from install.md
- Delete obsolete freeipa/docs/pihole-dns.md and configure-pihole-dns.sh
- Update CLAUDE.md section count and freeipa/ guidance entry
- Update freeipa/README.md IP and DNS forwarding description

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-07-28 15:25:22 +10:00

6.6 KiB
Raw Blame History

FreeIPA Install Procedure

Full reproduction guide for domain-controller.sweet.home. Tested on Rocky Linux 9.8 (GenericCloud), VMID 108, pve1.sweet.home.

Prerequisites

  • Proxmox node with local-zfs storage and internet access from guests
  • Rocky Linux 9 GenericCloud image downloaded (see step 1)
  • SSH access to Proxmox node as a user with sudo for qm/pvesm
  • The operator's SSH public key available to inject via cloud-init

Step 1 — Download Rocky Linux 9 GenericCloud image

On the Proxmox node, download to your ISO/image store:

wget -O /mnt/pve/server-iso/Rocky-9-GenericCloud.latest.x86_64.qcow2 \
  https://download.rockylinux.org/pub/rocky/9/images/x86_64/Rocky-9-GenericCloud.latest.x86_64.qcow2

The image is ~617 MB. The Proxmox storage must be configured to accept both ISO images and disk images (set "Content" to include "Disk image" in the Proxmox UI for that storage).


Step 2 — Prepare the VM in Proxmox

Use an existing VM or create a new one. The config used for VMID 108:

  • CPU: 2 cores, x86-64-v2-AES
  • RAM: 2048 MB
  • Disk: 32 GB on local-zfs
  • BIOS: SeaBIOS (GenericCloud uses MBR — not UEFI)
  • Network: virtio on vmbr0, firewall enabled
  • QEMU guest agent: enabled

If rebuilding an existing VM (e.g. replacing a prior OS):

# On pve1 — stop the VM
sudo qm stop <VMID>

# Remove existing disks from config
sudo qm set <VMID> --delete scsi0,efidisk0

# Switch to SeaBIOS if the VM was UEFI
sudo qm set <VMID> --bios seabios

# Free old disk volumes from storage
sudo pvesm free local-zfs:vm-<VMID>-disk-0
sudo pvesm free local-zfs:vm-<VMID>-disk-1

Import the Rocky image and configure cloud-init

# Import image as a new disk
sudo qm importdisk <VMID> /mnt/pve/server-iso/Rocky-9-GenericCloud.latest.x86_64.qcow2 local-zfs

# Check what disk name was assigned
sudo qm config <VMID>   # look for unused0: local-zfs:vm-<VMID>-disk-N

# Attach as scsi0 (adjust disk name from above)
sudo qm set <VMID> --scsi0 local-zfs:vm-<VMID>-disk-0,iothread=1

# Resize to 32 GB
sudo qm disk resize <VMID> scsi0 32G

# Add cloud-init drive
sudo qm set <VMID> --ide2 local-zfs:cloudinit

# Write SSH public key to a temp file
echo 'ssh-rsa AAAA... wayne@stream' > /tmp/admin-key.pub
# (use the key from variables.nix adminSshKey)

# Configure cloud-init
# Use the LAN gateway as temporary DNS — IPA itself will be the DNS at
# 192.168.2.253, but it's not running yet at this point in the install.
sudo qm set <VMID> \
  --ciuser wayne \
  --sshkeys /tmp/admin-key.pub \
  --ipconfig0 ip=dhcp \
  --nameserver 192.168.2.254 \
  --searchdomain sweet.home

# Set boot order
sudo qm set <VMID> --boot order=scsi0

# Start VM
sudo qm start <VMID>

Note on SSH key mismatch

The GenericCloud image injects the cloud-init SSH key on first boot. If you need to add an additional key (e.g. from a different machine) after first boot, mount the disk via nbd while the VM is stopped:

sudo qm stop <VMID>
sudo qemu-nbd --connect=/dev/nbd1 --format=raw /dev/zvol/rpool/data/vm-<VMID>-disk-0
# wait 2s, then:
sudo mount /dev/nbd1p4 /mnt/vm   # p4 is the root partition on Rocky 9 GenericCloud
sudo tee -a /mnt/vm/home/wayne/.ssh/authorized_keys <<< 'ssh-ed25519 AAAA... extra-key'
sudo umount /mnt/vm
sudo qemu-nbd --disconnect /dev/nbd1
sudo qm start <VMID>

Rocky 9 GenericCloud partition layout: p1=BIOS boot (2M), p2=EFI (100M), p3=/boot (1G), p4=/ (rest).


Step 3 — First-boot system preparation

SSH in as wayne once cloud-init has completed (usually 6090 s):

ssh wayne@<VM-IP>

Add swap (required — FreeIPA needs headroom beyond 1.7 GB RAM)

sudo dd if=/dev/zero of=/swapfile bs=1M count=2048 status=progress
sudo chmod 600 /swapfile
sudo mkswap /swapfile
sudo swapon /swapfile
echo '/swapfile none swap defaults 0 0' | sudo tee -a /etc/fstab

Set static IP via NetworkManager

CON=$(nmcli -t -f NAME con show --active | head -1)
sudo nmcli con mod "$CON" \
  ipv4.method manual \
  ipv4.addresses 192.168.2.253/24 \
  ipv4.gateway 192.168.2.254 \
  ipv4.dns 192.168.2.254 \
  ipv4.dns-search sweet.home
# Note: using the gateway as DNS here — after IPA installs it becomes the
# authoritative resolver at 192.168.2.253. Clients should then point to
# 192.168.2.253 for sweet.home resolution.
sudo nmcli con up "$CON"

Fix /etc/hosts (cloud-init maps FQDN to 127.0.0.1 — IPA requires real IP)

sudo sed -i '/domain-controller/d' /etc/hosts
echo '192.168.2.253 domain-controller.sweet.home domain-controller' \
  | sudo tee -a /etc/hosts

# Prevent cloud-init from resetting this on reboot
sudo sed -i 's/manage_etc_hosts: true/manage_etc_hosts: false/' \
  /etc/cloud/cloud.cfg

Step 4 — Install FreeIPA packages

sudo dnf install -y ipa-server ipa-server-dns

This pulls ~200 packages including 389-ds, Dogtag PKI, BIND, and MIT Kerberos. Takes 510 minutes depending on mirror speed.


Step 5 — Run the unattended install

Generate strong passwords (min 8 chars; store them in your password manager):

DM_PASS=$(openssl rand -base64 24 | tr -dc 'A-Za-z0-9' | head -c 24)
ADMIN_PASS=$(openssl rand -base64 24 | tr -dc 'A-Za-z0-9' | head -c 24)
echo "Directory Manager: $DM_PASS"
echo "IPA Admin:         $ADMIN_PASS"
# Save both in your password manager NOW before proceeding

Run the installer (takes 1520 minutes):

sudo ipa-server-install \
  --realm=SWEET.HOME \
  --domain=sweet.home \
  --hostname=domain-controller.sweet.home \
  --ds-password="$DM_PASS" \
  --admin-password="$ADMIN_PASS" \
  --setup-dns \
  --forwarder=192.168.2.254 \
  --no-dnssec-validation \
  --no-ntp \
  --unattended

Key flags:

  • --setup-dns — install BIND as IPA's authoritative DNS for sweet.home
  • --forwarder=192.168.2.254 — forward non-sweet.home queries to the LAN gateway
  • --no-dnssec-validation — skip DNSSEC (home lab has no DNSSEC chain)
  • --no-ntp — Proxmox handles time sync for guests; don't install chrony

Step 6 — Verify

# All services should show RUNNING
ipactl status

# Get a Kerberos ticket and confirm
echo "$ADMIN_PASS" | kinit admin
klist

# Check DNS SRV records are in place
dig +short _kerberos._udp.sweet.home SRV @127.0.0.1
# Expected: 0 100 88 domain-controller.sweet.home.

Step 7 — Back up the CA certificate

# On domain-controller (encrypted with Directory Manager password)
ls -lh /root/cacert.p12

# Copy to a safe location
scp root@domain-controller:/root/cacert.p12 ~/backups/ipa-cacert.p12

This file is required if you ever set up a replica or need to re-issue service certificates.