Router Configuration Consolidation Design
Date: 2026-02-12 Status: Approved Context: Replacing Firewalla router, need to ensure all custom config is in Ansible
Problem Statement
Section titled “Problem Statement”The router has accumulated custom configurations that are either:
- Not represented in Ansible playbooks
- Diverged from Ansible templates (router has newer changes)
- Partially deployed (Kopia installed but timer missing)
Current State Analysis
Section titled “Current State Analysis”Scripts in post_main.d
Section titled “Scripts in post_main.d”| Script | Ansible Managed | Divergence |
|---|---|---|
0000-a-remount-root-for-more-space.sh | No | N/A - needs addition |
0000-ensure-dhcpcd6-duid.sh | Partial | Has hardcoded DUID, not using Vault |
0000-mount-extdata.sh | Yes | Router has sudo prefixes |
0001-ipv6-ula.sh | Yes | Hooks to Python script |
0002-ipv6-cron-fix-vzw.sh | No | N/A - needs addition |
0050-start-docker.sh | Yes | Router has sudo, usermod |
0100-install-docker-compose-v2.sh | Yes | Completely different implementation |
0125-start-alloy.sh | Yes | Router has sudo, dual start |
0150-start-tailscale.sh | Yes | Router has sudo, dual start |
0151-start-router-hosts.sh | Yes | Router has sudo, dual start |
0200-start-vault-unseal.sh | Yes | Missing set -euo pipefail |
Kopia Backup Status
Section titled “Kopia Backup Status”- Binary installed at
/extdata/tools/kopia - Repository connected to R2
- No systemd timer/service - backups not running
- Security issue: Credentials embedded in
/extdata/kopia/config/init-repo.sh
Execution Context
Section titled “Execution Context”Scripts in post_main.d run as user pi, requiring sudo for root operations.
Design
Section titled “Design”Phase 1: Update Ansible Templates
Section titled “Phase 1: Update Ansible Templates”Update templates to match router reality (add sudo where needed):
1.1 router-extdata-mount
Section titled “1.1 router-extdata-mount”File: templates/mount-extdata.sh.j2
Changes:
- Add
sudoprefix tomountcommand - Add
sudoprefix totouchcommand - Add
sudoprefix toteecommand in log function
1.2 router-docker
Section titled “1.2 router-docker”File: templates/start-docker.sh.j2
Changes:
- Add
sudoprefix to all ipset commands - Add
sudoprefix tosystemctlcommands - Add
sudoprefix toteecommand in log function - Add
sudo usermod -a -G docker piat end
1.3 router-tailscale
Section titled “1.3 router-tailscale”File: templates/boot-script.sh.j2
Changes:
- Add
sudoprefix todocker composecommand - Add
sudo systemctl enable --now docker-compose@tailscale
1.4 router-hosts
Section titled “1.4 router-hosts”File: templates/z0100-start-router-hosts.sh.j2
Changes:
- Add
cdto docker compose directory - Add
sudo docker compose up -dbefore systemctl - Add
sudoprefix to systemctl command
1.5 router-ipv6-ula
Section titled “1.5 router-ipv6-ula”File: templates/configure-ipv6-ula.py.j2
Changes:
- Add
sudotoip -6 addr addcommand - Add
sudotokill -HUPcommand
1.6 router-docker-compose
Section titled “1.6 router-docker-compose”File: templates/docker-compose@.service.j2
Changes:
- Update
TMPDIRpath from/data/tmp/%ito/extdata/tmp/%i
1.7 router-vault-unseal
Section titled “1.7 router-vault-unseal”File: templates/boot-script.sh.j2
Changes:
- Add
set -euo pipefailat start (already in template, verify router version)
1.8 alloy
Section titled “1.8 alloy”File: templates/boot-script.yml
Changes:
- Add
sudoprefix todocker composecommand - Add
sudo systemctl enable --now docker-compose@alloy
Phase 2: Add Missing Scripts
Section titled “Phase 2: Add Missing Scripts”2.1 router-common - Root remount
Section titled “2.1 router-common - Root remount”Add new file: templates/remount-root.sh.j2
#!/bin/bash# {{ ansible_managed }}# Remount root-rw with larger size for Firewalla operationssudo mount -o remount,size=384M /media/root-rwAdd task to deploy with priority 0000-a.
2.2 router-dhcpcd6-duid - Boot script
Section titled “2.2 router-dhcpcd6-duid - Boot script”Add new file: templates/ensure-dhcpcd6-duid.sh.j2
- Read DUID from Vault (already fetched in playbook)
- Compare with current file
- Update if different, restart dhcpcd6 service
2.3 router-dhcp6-vzw-fix - Cron installer
Section titled “2.3 router-dhcp6-vzw-fix - Cron installer”Add new file: templates/install-cron.sh.j2
#!/bin/bash# {{ ansible_managed }}# Install dhcp6-lease-fix cron jobecho "* * * * * root {{ router_dhcp6_vzw_fix_script_path }}" | sudo tee /etc/cron.d/dhcp6-lease-fixPhase 3: Fix Kopia
Section titled “Phase 3: Fix Kopia”3.1 Deploy systemd timer/service
Section titled “3.1 Deploy systemd timer/service”The role already has templates for:
kopia-backup.service.j2kopia-backup.timer.j2
Issue: These were never deployed. Run the role to deploy them.
3.2 Remove embedded credentials
Section titled “3.2 Remove embedded credentials”Delete /extdata/kopia/config/init-repo.sh from the router.
The repository is already connected; credentials come from Vault at deploy time.
Phase 4: Cleanup
Section titled “Phase 4: Cleanup”Remove from router:
/home/pi/.firewalla/config/post_main.d/z_0050-start-docker.sh/home/pi/.firewalla/config/post_main.d/z_0100-start-haproxy.sh
Implementation Order
Section titled “Implementation Order”- Phase 1: Update templates (preserves router changes)
- Phase 4: Cleanup old files
- Phase 2: Add missing scripts
- Phase 3: Fix Kopia
- Verify all services running
Verification
Section titled “Verification”After implementation:
ssh router "ls -la /home/pi/.firewalla/config/post_main.d/"- no z_* filesssh router "systemctl status kopia-backup.timer"- timer activessh router "docker ps"- all containers runningssh router "cat /etc/cron.d/dhcp6-lease-fix"- cron installed- Run full playbook with
--check --diff- no changes
Security Improvements
Section titled “Security Improvements”- Remove hardcoded DUID from
0000-ensure-dhcpcd6-duid.sh(use Vault) - Remove embedded credentials from
init-repo.sh(already in Vault)