VyOS Migration: Decisions & Risks

Architecture Decisions

Why VyOS over OPNsense or pfSense Rebuild

Factor Rationale

CLI-first

VyOS is built around a CLI configuration model (Junos-like set/commit). This aligns with infrastructure-as-code principles and makes config diffable, scriptable, and versionable.

No GUI dependency

pfSense and OPNsense are GUI-first. When the GUI breaks (as it did), troubleshooting requires understanding the underlying FreeBSD config — effectively two systems to know.

VRRP native

VyOS has first-class VRRP support. pfSense uses CARP (FreeBSD-native) which has known issues with asymmetric routing and connection tracking sync.

Linux kernel

VyOS runs on Debian/Linux. Easier to integrate with the existing Linux-based infrastructure (Wazuh, Prometheus, Vault agents) than FreeBSD.

Zone-based firewall

nftables backend with zone policies. More intuitive than pfSense’s per-interface rules for a multi-VLAN environment.

Why VRRP over CARP

  • VRRP is an IETF standard (RFC 5798) — vendor-neutral, well-documented

  • CARP is BSD-specific — no Linux implementation without custom patching

  • VRRP integrates with conntrack-sync for stateful failover

  • VyOS VRRP supports health-check scripts for application-aware failover

Why Dual-BIND Instead of VyOS Built-in DNS

VyOS includes a DNS forwarder (PowerDNS recursor), but the infrastructure required authoritative DNS for internal zones. Running BIND on dedicated VMs provides:

  • Zone file management with serial tracking

  • AXFR zone transfers for DNS HA (bind-01 → bind-02)

  • Dynamic DNS update support for future DHCP integration

  • Separation of concerns — router doesn’t hold DNS state

Parallel Deployment Risk Model

The migration used a parallel deployment strategy:

  1. Deploy VyOS alongside pfSense (both running simultaneously)

  2. Test VyOS with select VLANs while pfSense handles the rest

  3. Cutover one VLAN at a time

  4. pfSense remains available for instant rollback

This eliminated the "big bang" risk. At any point during phases A-D, reverting to pfSense took <30 seconds.