If you run (or want to run) an OPNsense HA pair with CARP but your WAN is DHCP-assigned rather than static, you've probably hit this wall: the docs assume 3 static WAN IPs, and stock CARP can't work on DHCP or single IP. This plugin closes that gap.
Why stock CARP can't do it: a CARP virtual IP is static, and a DHCP WAN only routes an address while a live DHCP lease is bound to its MAC - so the VIP never gets a lease and never receives traffic. dhclient can't help either: it can't decouple the DHCP chaddr from the interface's hardware MAC.
What it does: a small daemon keeps a DHCP lease alive for the CARP VIP's virtual MAC. The ISP then routes the VIP to that MAC, native CARP answers ARP and fails over as usual - so the shared IP works and fails over on a dynamic WAN. Runs on both nodes redundantly, follows a changing address, and keeps the upstream ARP fresh (some gateways silently blackhole otherwise).
Tested on two independent real ISP lines (one CGNAT, one a plain public-DHCP WAN). On a two-node bench the whole path is verified end-to-end: the VIP holds its lease on the virtual MAC, CARP fails over cleanly (master link down -> backup takes over, VIP held), the ARP nudge is answered by the real ISP gateway, and follow works (the VIP tracks a changed address without ever dropping the lease).
When it applies: an HA pair + a DHCP (not static/PPPoE) WAN. Works whether the line hands out several concurrent leases (one per node's WAN + one for the VIP - the straightforward case) or only a single address.
Only a single IP? Supported too - a single floating VIP holds the one lease while each node uses a private WAN IP for CARP, and the backup reaches the internet through the master. Every mechanism is lab-validated on the bench, but I haven't yet run the whole single-IP topology on a live one-IP line — so I'd love a field report if you run it on a real single-IP WAN.
Also worth knowing for HA: for outbound traffic to survive a failover, point Outbound NAT at the CARP VIP (not a node's own WAN address). If the address is dynamic, the plugin can keep a firewall alias in sync so NAT/rules follow it automatically.
Personal third-party plugin for now. If there's interest I'd like to propose it for the official OPNsense community plugins - so say so if it'd be useful, and a star on the repo helps make that case.
Repo + one-line installer: https://github.com/toreamun/opnsense-plugins