Template OPNsense 26 — build Packer
Étape mi-parcours reconstruction. Suppose Proxmox up sur coruscant + NAS jedha monté + secrets SOPS déchiffrables. Produit le template VM 9200 cloné ensuite par Terraform pour créer la VM OPNsense de prod (VM 200 → 10.0.1.1 LAN / 192.168.1.2 WAN / 10.0.2.1 DMZ).
Contexte
Pourquoi un template ? OPNsense = firewall/routeur central de minfra-v2 (gateway LAN, NAT WAN, VLANs, WireGuard, DHCP Kea, Unbound). Avoir un template Packer permet :
- Reproductibilité bit-perfect entre rebuilds DR
- Clé SSH minfra pré-injectée → Ansible bootstrap immédiat post-clone
- Config bootstrap (hostname, SSH, interfaces stub) baked dans
/conf/config.xml→ 1er boot already-configured - Aucune intervention console au clone Terraform
Stratégie INLINE (vs HTTP fetch) : toutes les commandes
d’installation sont tapées via VNC par Packer (boot_command), pas
de serveur HTTP temporaire à provisionner sur coruscant. Plus simple,
plus robuste (pas de routage HTTP entre VM build et hôte).
Flux build:
1. Packer crée VM 9200 vide sur coruscant (proxmox-iso plugin)
2. Boot OPNsense live ISO (jedha-data:iso/OPNsense-26.1.6-dvd-amd64.iso)
3. boot_command VNC : login root → menu OPNsense → option 8 Shell
4. gpart destroy/create GPT sur da0 (20 GB scsi)
5. gpart add freebsd-boot 512k + swap 4G + ufs (reste)
6. newfs -j /dev/da0p3 + mount /mnt
7. tar -cpf - / | tar -xpf - -C /mnt (copie live → disque ~30s)
8. fstab + rc.conf + sshd_config + root password
9. Injecte clé SSH minfra dans /root/.ssh/authorized_keys du LIVE
10. ifconfig vtnet1 10.0.1.250 → Packer SSH se connecte via bastion coruscant
11. provisioner shell : post_install.sh écrit config.xml prod dans /mnt
12. Shutdown VM + conversion en template Proxmox (template-opnsense26)
Durée totale ≈ 15 min.
Hypothèses:
- Proxmox coruscant up sur 10.0.1.30 (port 22 + 8006 ouverts)
- Storage
local-lvm(disque template) +jedha-data(NFS ISO) montés - Token API Proxmox
root@pam!packercréé (cf.proxmox:setup) - ISO
OPNsense-26.1.6-dvd-amd64.isouploadée dansjedha-data:iso/ - SOPS age key présente + secrets
infra/packer/secrets/proxmox.yamlchiffrés - Clé SSH
~/.ssh/id_ed25519_minfraprésente (auth bastion + injection live) - WSL Ubuntu installé (le wrapper
_runutilisewsl bash)
Précheck — vérifier tous les prérequis
Script bash valide 8 points : SOPS key, SSH key, secrets Packer/Ansible, SSH coruscant joignable, ISO présente, état VM 9200/200.
# === Windows (PowerShell) ===
cd D:\git\minfra-v2
wsl bash dev/bash/opnsense_precheck.sh
Verify: bash dev/bash/opnsense_precheck.sh ; echo $? Verify: ls infra/packer/secrets/proxmox.yaml
Si échec sur ISO → fix:
task -- packer:iso:upload ISO_BZ2="\\jedha\data\iso\OPNsense-26.1.6-dvd-amd64.iso.bz2"
Si échec sur secrets Packer → init:
task -- packer:secrets:init TOKEN_SECRET=<token-pam-packer>
Init plugin Packer (1×)
Télécharge le plugin proxmox-iso (github.com/hashicorp/proxmox >= 1.2.0)
dans ~/.packer.d/plugins/. Idempotent.
cd D:\git\minfra-v2
task -- packer:init
Verify: wsl bash -c “ls ~/.packer.d/plugins/github.com/hashicorp/proxmox/“
Valider la syntaxe HCL (sans build)
Sanity check avant le build de 15 min. Décrypte secrets temporairement
puis lance packer validate.
task -- packer:build:opnsense:check
Verify: echo $LASTEXITCODE # doit être 0
Lancer le build
Auto-clean VM 9200 si présente (sinon Packer échoue), décrypte secrets
SOPS, lance packer build. Durée ~15 min.
task opnsense:template:deploy
Suivre les logs pour identifier les étapes :
qemu: création VM 9200 videqemu: boot ISO + boot_command VNC tape (~3 min de wait + tap)ssh: Packer SSH se connecte (= install live OK, IP 10.0.1.250 up)shell: exécution post_install.shConverting VM to template: conversion finale
Verify: ssh -i ~/.ssh/id_ed25519_minfra root@10.0.1.30 ‘qm list | grep 9200’
À la fin, VM 9200 doit apparaître avec colonne Status=stopped et
marker template dans Proxmox UI.
Si le build plante en cours
Le script build.sh clean détruit la VM 9200 partielle pour permettre
un retry propre.
task opnsense:template:destroy
Puis relancer task opnsense:template:deploy.
Verify: ssh root@10.0.1.30 ‘qm status 9200 2>&1’ # doit retourner “Configuration file does not exist”
Vérifier le template post-build
# SSH coruscant + qm list filtrer template
wsl bash -c "ssh -i ~/.ssh/id_ed25519_minfra root@10.0.1.30 'qm config 9200 | grep -E \"^(name|template|memory|cores|net0|net1):\"'"
Doit afficher :
name: template-opnsense26
template: 1
memory: 4096
cores: 2
net0: virtio,bridge=vmbr0,tag=999
net1: virtio,bridge=vmbr0
Verify: ssh root@10.0.1.30 ‘qm config 9200 | grep -q template:.1’
Cloner pour créer la VM OPNsense prod
Une fois le template prêt, Terraform clone → VM 200 (IPs prod) :
task opnsense:vm:deploy
Enchaîne : terraform init → terraform apply → bootstrap SSH key →
clean known_hosts entry 10.0.1.1. ~2 min.
Verify: ssh -i ~/.ssh/id_ed25519_minfra root@10.0.1.1 ‘uname -a’
Configurer OPNsense via Ansible
Roles idempotents : user, aliases, firewall, NAT, port_forward, DHCP Kea, Unbound, WireGuard.
task opnsense:config
Verify: task opnsense:postcheck
Hors périmètre (Phase 2+)
- HA OPNsense (CARP) — secondaire sur kalevala plus tard
- Multi-WAN — un seul lien SFR actuellement
- VLAN 40 (IoT) + VLAN 50 (Invités) — différés
- DPI / IDS Suricata — RAM 4GB juste pour FW basique, upgrade RAM avant activation Suricata
- Sauvegarde config.xml — TODO via cron
scp /conf/config.xml jedha:
Suite logique
08-vm-debian-tatooine— clone template Debian12 pour tatooine (host docker)09-platform-pki-traefik-authentik— déploiement stack platform- …