Safeguard
Supply Chain Security•

VRRP Explained: First Hop Redundancy, Virtual Routers and Security

VRRP lets two or more routers share one gateway address so hosts survive a router failure. How election, failover and VRRPv3 work, and how to secure it.

Safeguard Security Team
43 min read

VRRP, the Virtual Router Redundancy Protocol, lets two or more routers on one LAN share a gateway IP address and virtual MAC address, so hosts keep one static default gateway while a backup takes over in about three seconds if the active router fails. It has no authentication, so its security depends on who can send packets on that LAN.

This post continues our one protocol per post series, next to Ethernet switching, ARP and IPv6 Neighbor Discovery, DHCP, OSPF and VXLAN and EVPN. Here we stay on the gateway: election and failover with the timer arithmetic, version changes, why authentication was removed, how the attacks work, and how to run and lock down VRRP on Linux.

Key takeaways

  • The current standard is VRRP version 3 in RFC 9568 (April 2024), which obsoletes RFC 5798 (March 2010). RFC 5798 obsoleted RFC 3768 (April 2004), which obsoleted the original RFC 2338 (April 1998).
  • VRRP runs directly over IP as protocol number 112, sends advertisements to 224.0.0.18 (IPv4) or ff02::12 (IPv6), and uses virtual MAC addresses 00-00-5E-00-01-XX for IPv4 and 00-00-5E-00-02-XX for IPv6, where XX is the virtual router ID in hex.
  • Highest priority wins: 255 is the address owner, 1 to 254 are backups (default 100), and 0 means "I am leaving, take over now".
  • A backup declares the active router dead after three advertisement intervals plus a skew that shrinks as priority rises: about 3.6 seconds at defaults.
  • VRRPv3 added IPv6 and centisecond timers for sub second failover; RFC 9568 renamed "Master" to "Active Router".
  • Authentication was removed in 2004 by RFC 3768, not in version 3: any LAN node can disrupt forwarding through ARP or Neighbor Discovery anyway, and mismatched secrets created multiple active routers.
  • VRRP is protected by the TTL 255 rule, filtering VRRP on host facing switch ports, and first hop security. Unicast VRRP across routers loses the TTL protection, which is why keepalived added an HMAC extension in 2026.

What problem does first hop redundancy solve?

Every host that talks outside its own subnet needs a first hop router, the default gateway, usually set statically, by DHCPv4 or by IPv6 Router Advertisements. RFC 9568 notes that hosts could instead run or snoop a routing protocol, but that costs administration and processing and may not exist on a given platform. So most networks use one static gateway per subnet, which the RFC says "creates a single point of failure". A host configured with gateway 192.0.2.1 keeps sending to that address and its cached MAC; a second router at 192.0.2.254 does nothing for it.

First hop redundancy protocols fix this without touching the hosts. The routers agree which one answers for the gateway address now, and move that address (and, in VRRP, its MAC address) to a survivor when it fails.

IPv6 has its own router discovery, but RFC 9568 explains that Router Advertisements are too infrequent to detect a dead router and Neighbor Unreachability Detection only probes routers in active use after a quiet period, so a host can take more than 10 seconds to notice. RFC 4861's defaults show why: REACHABLE_TIME is 30,000 milliseconds, DELAY_FIRST_PROBE_TIME is 5 seconds, then MAX_UNICAST_SOLICIT (3) probes one RETRANS_TIMER (1,000 milliseconds) apart. VRRP for IPv6 replaces that with a takeover in "around three seconds" at default timers.

How VRRP presents one virtual gateway address

VRRP introduces a virtual router, identified by a Virtual Router ID (VRID) from 1 to 255 that is unique per LAN segment and address family. A virtual router has:

  • One or more virtual IP addresses. These are what hosts use as their default gateway. For IPv6, RFC 9568 requires that the first address is a link local address associated with the virtual router.
  • A virtual MAC address derived from the VRID. RFC 9568 section 7.3 defines 00-00-5E-00-01-XX for IPv4 and 00-00-5E-00-02-XX for IPv6, where the last octet is the VRID. The IANA "ethernet numbers" registry lists the 00-01-00 to 00-01-FF and 00-02-00 to 00-02-FF blocks under the IANA OUI against RFC 9568.
  • A set of physical routers, each configured with a priority for that VRID.

One router at a time is the Active Router (the Master in RFC 3768 and RFC 5798). It answers ARP or IPv6 Neighbor Solicitations for the virtual address with the virtual MAC, forwards traffic sent to that MAC, and multicasts an advertisement every interval. The others stay in Backup and listen.

Because the MAC moves with the role, a host's cached gateway entry stays correct after failover. The new active router sends gratuitous ARP or unsolicited Neighbor Advertisements, and advertisements use the virtual MAC as source, so switches keep learning the virtual MAC on the current active router's port.

If one router has the virtual IP configured as its own interface address, it is the "IPvX address owner", must use priority 255, and preempts everyone as soon as it starts. Many deployments use an unowned virtual address so all routers are peers at priorities 1 to 254.

Where VRRP sits on the wire

ItemIPv4IPv6
IP protocol / Next Header112112
Destination address224.0.0.18ff02::12 (link local scope)
TTL / Hop Limitmust be 255, checked on receiptmust be 255, checked on receipt
Virtual MAC00-00-5E-00-01-XX00-00-5E-00-02-XX
Source addressthe sender's primary IPv4 address on the interfacethe sender's link local address
Packet types1 (ADVERTISEMENT) only1 (ADVERTISEMENT) only
Confidentialitynonenone

All values come from RFC 9568 and the IANA protocol number, multicast and ethernet number registries.

There is one message type and no hello, request, acknowledgement or state sync. Each router decides locally from the advertisements it hears, which also defines the security model: whoever sends the most convincing advertisement wins.

How does VRRP elect an active router and fail over?

Priority

Each router has a priority per virtual router, an 8 bit value:

PriorityMeaning
255The router owns the virtual address. It always becomes active and always preempts. Only one router per VRID should use it.
1 to 254Backup routers. Higher wins. Default is 100.
0Sent by the active router when it stops participating (for example on a clean shutdown) so backups take over without waiting for a timeout.

When two routers advertise the same priority, the tie breaks on the primary IP address: the router whose primary address is greater, compared as an unsigned integer in network byte order, wins. RFC 9568 section 8.3.2 recommends giving every router a different priority, with enough of a gap that a lower priority backup does not claim the active role before it hears from a higher priority one.

Advertisement interval

In VRRPv2 the advertisement interval was an 8 bit field in whole seconds, default 1. In VRRPv3 it is a 12 bit "Max Advertise Interval" in centiseconds, default 100, so it runs up to 4,095 centiseconds (40.95 seconds). FRRouting exposes this as 10 to 40,950 milliseconds in multiples of 10.

Backups compute their timeout from the interval in the active router's advertisements (Active_Adver_Interval), not their own setting. RFC 9568 recommends logging a mismatch, because mixed intervals cause instability.

Skew time and Active_Down_Interval

A backup declares the active router dead when it has not heard an advertisement for Active_Down_Interval:

Skew_Time            = ((256 - Priority) * Active_Adver_Interval) / 256
Active_Down_Interval = (3 * Active_Adver_Interval) + Skew_Time

Both are in centiseconds in VRRPv3. Higher priority means smaller skew, so the best backup's timer fires first, it starts advertising, and the others reset their timers before they fire.

Worked example 1: default timers, two backups. The active router advertises every 100 centiseconds (1 second). Backup B has priority 200 and backup C has the default 100.

  • B: Skew_Time = (256 minus 200) times 100 divided by 256 = 5,600 / 256 = 21.875 centiseconds, about 219 ms. Active_Down_Interval = 300 + 21.875 = 321.875 centiseconds, about 3.22 seconds.
  • C: Skew_Time = (256 minus 100) times 100 divided by 256 = 15,600 / 256 = 60.9375 centiseconds, about 609 ms. Active_Down_Interval = 300 + 60.94 = 360.94 centiseconds, about 3.61 seconds.

If the active router dies silently, B takes over about 3.2 seconds after the last advertisement, while C still has about 390 ms to go. FRRouting's example output shows a 210 ms skew for priority 200 at 1,000 ms, the same formula in integer centiseconds.

Worked example 2: narrow priority gaps. Same interval, B at 110 and C at 100. B's skew is 146 times 100 divided by 256, about 57.0 centiseconds, against C's 60.9, a gap of about 39 ms. A scheduler delay or lost advertisement can let both become active briefly. At 150 versus 100 the skews are about 41.4 and 60.9 centiseconds, a gap of about 195 ms. Hence RFC 9568's call for "sufficient differences" and the keepalived manual's advice to set the intended active router 50 points higher.

Worked example 3: sub second timers. At a 10 centisecond (100 ms) interval, a priority 254 backup has a skew of about 0.08 centiseconds and an Active_Down_Interval of about 30.1 centiseconds, roughly 301 ms; a priority 1 backup waits about 400 ms. The cost is ten advertisements per second per virtual router and sensitivity to CPU stalls, which the keepalived manual links to "thread timer expired" messages.

Graceful shutdown. A cleanly stopping active router sends priority 0, and backups set their timer to Skew_Time only. For B in example 1, failover drops from about 3.2 seconds to about 219 ms, so do maintenance with a clean stop, not a power cut.

VRRPv2 (RFC 3768) used whole seconds and a skew of (256 minus Priority) / 256 seconds that did not scale with the interval, so it could not fail over much faster than three seconds.

Preemption

With preemption on (the RFC default), a higher priority backup ignores a lower priority active router's advertisements, lets its timer expire and takes over. With it off, the running active router keeps the role until it fails.

On returns traffic to the preferred router; off stops a flapping router pulling traffic back on every reboot. The address owner always preempts. keepalived offers a preempt delay so a rebooted router waits for its routes to converge.

Accept_Mode

With Accept_Mode False (the default), an active router that is not the address owner forwards through the virtual router but does not accept packets addressed to the virtual IP, so you cannot SSH or, usually, ping it. RFC 9568 suggests enabling it where deployments rely on pinging the gateway; IPv6 NS and NA are never dropped.

So a ping check against the virtual gateway fails on a correctly configured router. FRRouting does not implement Accept_Mode, and keepalived's strict mode turns it off for non owners using firewall rules.

The state machine in one table

StateWhat the router doesLeaves the state when
InitializeWaits for a startup eventStarts as Active if priority is 255 (sends an advertisement and gratuitous ARP or unsolicited NA at once); otherwise goes to Backup and starts the Active_Down_Timer
BackupListens; does not answer ARP or ND for the virtual address; drops traffic sent to the virtual MACIts Active_Down_Timer fires (becomes Active), or it receives a priority 0 advertisement (timer set to Skew_Time), or it receives a lower priority advertisement while preempting (ignores it and lets the timer run)
ActiveAnswers ARP or ND with the virtual MAC, forwards traffic, advertises every intervalIt hears a higher priority advertisement, or an equal priority one from a higher primary address (goes to Backup), or it shuts down (sends priority 0, goes to Initialize)

RFC 9568 added one behaviour in the Active state: when the active router hears an advertisement from a lower priority router, it sends an advertisement immediately, so learning bridges point at the correct router again. Earlier versions simply discarded the lower priority advertisement.

What changed from VRRPv2 to VRRPv3?

A short history in dates

DateDocument or eventWhat it didSource
April 1998RFC 2338First VRRP standard, IPv4 only. Three authentication types: none, simple clear text password, IP Authentication Header with HMAC-MD5-96rfc-editor.org
April 2004RFC 3768 (VRRPv2)Obsoleted RFC 2338. Removed the authentication types (types 1 and 2 kept only as reserved values) because they "did not provide any real security"rfc-editor.org
October 2007RFC 5082The Generalized TTL Security Mechanism, the TTL 255 technique VRRP cites for rejecting off link packetsrfc-editor.org
March 2010RFC 5798 (VRRPv3)Obsoleted RFC 3768. One protocol for IPv4 and IPv6, centisecond timers, no authentication fieldrfc-editor.org
March 2012RFC 6527VRRPv3 MIB for SNMP managementrfc-editor.org
March 2018RFC 8347YANG data model covering VRRPv2 and VRRPv3rfc-editor.org
October 2021RFC 9135EVPN integrated routing and bridging, which reuses the VRRP MAC ranges for auto derived anycast gateway MACsrfc-editor.org
April 2024RFC 9568Obsoleted RFC 5798. Inclusive terminology (Active Router), state machine errata fixed, checksum clarified, immediate re advertisement on hearing a lower priority routerrfc-editor.org
22 June 2026keepalived 2.4.0Added the auth_hmac extension: an HMAC-SHA256 trailer on each advertisement, aimed at unicast deploymentskeepalived.org release notes
27 July 2026draft-cassen-vrrp-auth-hmac-01Individual Internet-Draft describing that HMAC extension. Not an IETF standardIETF Datatracker

VRRPv2 versus VRRPv3, field by field

PropertyVRRPv2 (RFC 3768)VRRPv3 (RFC 5798, RFC 9568)
Address familiesIPv4 onlyIPv4 and IPv6, as separate virtual router instances
Version field23
Timer field8 bit Advertisement Interval in seconds12 bit Max Advertise Interval in centiseconds
Fastest standard failovera little over 3 secondsroughly 30 centiseconds at a 10 centisecond interval
AuthenticationAuth Type field present; only type 0 (none) defined, 1 and 2 reservedNo authentication field at all
Checksumover the VRRP messageover the VRRP message; for IPv6 also over the RFC 8200 pseudo header; RFC 9568 clarified that the IPv4 checksum does not include a pseudo header
TerminologyMaster and BackupMaster and Backup in RFC 5798; Active and Backup in RFC 9568
Behaviour on hearing a lower priority router while activediscardRFC 9568: discard and send an advertisement at once
Interoperationnot applicableoptional mode to send and listen to both versions, for migration only

IPv6 support

An IPv6 virtual router advertises from its link local address to ff02::12 with Hop Limit 255, its first virtual address must be link local, and it answers Neighbor Solicitations with the IPv6 virtual MAC. RFC 9568 makes the active router responsible for sending Router Advertisements for the virtual router, and backups must be configured with the same Router Advertisement options as the address owner.

IPv4 and IPv6 instances are independent even with the same VRID, so one can be active on router A and the other on router B. That is useful, and confusing when monitoring checks only one family.

Interoperation and migration

RFC 9568 section 8.4 allows an optional mode that sends and listens to both v2 and v3, "NOT RECOMMENDED for permanent deployments". Do not give a slow v2 router a higher priority than sub second v3 peers, and run at 100 centiseconds during migration so v3 does not overwhelm v2 backups; go sub second only after v2 is gone.

Implementations also read RFC 5798 differently on whether the IPv4 checksum includes a pseudo header. RFC 9568 says it does not, while FRRouting's checksum-with-ipv4-pseudoheader option is documented as enabled by default. If mixed implementations reject IPv4 advertisements with checksum errors, compare this first.

Why was authentication removed, and what replaces it?

VRRPv3 did not drop authentication; RFC 3768 removed it in April 2004, keeping the Auth Type field only for parsing old packets, and VRRPv3 then removed the field.

RFC 2338 offered three choices: none, a clear text password, and IPsec Authentication Header with HMAC-MD5-96. The RFC itself said the password only guarded against accidental misconfiguration, not a node "snooping VRRP packets on the LAN". AH gave real integrity and replay protection.

RFC 3768, RFC 5798 and RFC 9568 give the same three reasons for dropping even the strong option:

  1. Misconfigured secrets caused outages. Routers that disagree on the key discard each other's advertisements and both become active, "causing multiple Active Routers to be elected" in RFC 9568's words.
  2. Authentication cannot stop the attack that matters. A hostile node can behave as an active router, answering ARP or ND for the gateway, without sending any VRRP. Multiple active routers disrupt as much as none.
  3. The LAN was never trusted. Any node can already receive frames for the router's MAC, spoof the router's MAC to redirect switch learning, send ICMP redirects, and send or answer ND messages. VRRP "does not add to these vulnerabilities".

What the RFC relies on instead:

  • The TTL 255 rule. Advertisements leave with TTL or Hop Limit 255 and receivers drop anything else, so packets that crossed a router are rejected. This is the RFC 5082 Generalized TTL Security Mechanism, which "limits most vulnerabilities to attacks on the local network".
  • Switch port filtering. RFC 9568 suggests filtering VRRP from ports facing end hosts where hosts are untrusted.
  • IPv6 first hop security. It recommends section 2.3 of RFC 9099 (August 2021), which covers Router Advertisement Guard (RFC 6105, February 2011) and source address validation, and notes VRRP works with SEcure Neighbor Discovery (RFC 3971, March 2005) trust anchor modes if active and backup routers share prefix delegation but have their own key pairs.
  • No confidentiality. Nothing in an advertisement is secret.

Where the RFC reasoning runs out: unicast VRRP

The TTL argument assumes multicast on one link. Where multicast is unavailable, daemons send unicast advertisements to configured peers, often across routers, so the receiver must relax the TTL check and any host that can route a spoofed packet to it can inject an advertisement.

keepalived 2.4.0 (22 June 2026) added auth_hmac for this case. Per the project's documentation, it appends an HMAC-SHA256 tag truncated to 128 bits plus a time based sequence number, binds address family, version, VRID and source address, works for v2 and v3 over IPv4 and IPv6, and adds 28 bytes per advertisement. Keys are 32 to 64 bytes with rotation, and receive only and permissive modes allow a hitless rollout. Release 2.4.3 (20 July 2026) fixed a clock step case that could cause a lasting dual active state. The project says it complements the TTL check rather than replacing it. Its format is in an individual Internet-Draft, draft-cassen-vrrp-auth-hmac-01, not an IETF standard, and non keepalived peers will not understand it.

The 1998 lesson still applies: a shared key brings back "mismatched key means two active routers", which is why keepalived ships staged rollout modes and verification counters.

How do other first hop redundancy approaches compare?

Described by category, not by product:

Proprietary active and standby protocols. Several equipment makers ship their own protocols with the same idea (priorities, hello timers, a virtual IP and MAC, one active router) but different packet formats, multicast groups and MAC ranges, sometimes with optional authentication. They do not interoperate with VRRP or each other.

Proprietary load balancing protocols. These give each router its own virtual MAC and have a coordinator answer ARP for the single virtual IP with different MACs for different hosts. Load splits per host at ARP time, which is coarse, and failover moves a virtual MAC.

Load sharing with plain VRRP. RFC 9568's sample network 2 runs VRID 1 active on router A and VRID 2 active on router B, each backing the other, with half the hosts using each gateway address.

Active and active gateways with multi chassis link aggregation. Switch pairs presenting one link aggregation group to servers can both route for the same gateway address, whichever receives the frame.

Distributed anycast gateway in EVPN fabrics. Every leaf hosts the same gateway IP and, in the recommended option, the same gateway MAC. RFC 9135 (October 2021) requires an auto derived anycast MAC to come from the VRRP ranges. There is no election, so the security question moves to who can inject BGP EVPN routes.

Routing to the host. Following the RFC 7938 (August 2016) data centre pattern, server subnets are announced into BGP and some designs run a routing daemon on each server with equal cost next hops, so no virtual gateway is needed, at the cost of complexity on every host.

Comparison table

ApproachStandardElectionActive forwarders per subnetTypical failoverHost changesMain security exposure
VRRPv3IETF RFC 9568Priority and timersOne per virtual routerAbout 3.6 s at defaults, sub second possibleNoneAny LAN node can send advertisements; ARP and ND spoofing
Proprietary active and standby FHRPVendor specificPriority and hello timersOne per groupSeconds, sub second with tuningNoneSame as VRRP; some offer optional authentication with the same key mismatch risk
Proprietary load balancing FHRPVendor specificCoordinator plus per router virtual MACsSeveral, split per host at ARP timeSecondsNoneSame as above, plus a more complex ARP responder to protect
VRRP with multiple VRIDsIETFPer virtual routerOne per VRID, so several in totalAs VRRPHosts split across gateway addressesAs VRRP
EVPN distributed anycast gatewayIETF RFC 7432, RFC 9135None; every leaf is activeEvery leafBounded by fabric and host reachability convergenceNoneBGP EVPN control plane, route injection, leaf compromise
Routing to the hostIETF routing protocols, RFC 7938 patternRouting protocol best path and ECMPAll next hopsRouting protocol convergence, set by failure detection timersA routing daemon on every hostRouting protocol authentication, route filters on host sessions

Which one to use

SituationReasonable choice
Two routers or firewalls at a branch, campus or small siteVRRPv3 with distinct priorities and host port filtering
Two Linux load balancers or gateways in a VM or bare metal pairkeepalived or FRRouting VRRP; multicast if the network allows, otherwise unicast with auth_hmac
Cloud network without multicast and with provider managed routingPrefer the provider's own routing or load balancing primitives; unicast VRRP only with authentication and tight security groups
Leaf and spine data centre with VXLAN and EVPNDistributed anycast gateway
Large fleet already running BGP to the top of rackRouting to the host, or anycast gateway at the leaf
Mixed equipment from different makersVRRP, because it is the only interoperable option

How has VRRP been attacked, and what was the fix each time?

Every attack follows from one fact: any node on the segment can send an advertisement. Mechanisms are described conceptually only.

Rogue advertisement with a higher priority, then interception

Mechanism. A host on the LAN advertises an existing VRID with a priority above the current active router, up to 255. Following the protocol correctly, the real router drops to Backup and the rogue host starts answering ARP or ND for the gateway. All off subnet traffic now reaches the attacker, who can forward it onward so nothing visibly breaks while copying or altering unencrypted traffic.

Fix. Drop IP protocol 112 on every switch port facing end hosts, so only router ports can advertise. Alert on any new source advertising a known VRID and on unexpected priority 255 advertisements (RFC 9568 says routers should log multiple priority 255 advertisers). Encrypt and authenticate application traffic end to end (TLS with certificate validation, SSH with known host keys) so a node in the path gains little.

Lesson. On a shared segment, VRRP's security boundary is the switch port. If a host can send to 224.0.0.18 with TTL 255, it can take the gateway.

Denial of service

Mechanism. A rogue active router can drop traffic, repeatedly take over and then send priority 0 to force constant elections, or flood advertisements to burn router CPU. Sub second timers make this easier, since a delayed advertisement already causes a failover.

Fix. Port filtering, control plane policing of protocol 112 on routers, default timers unless you need faster, and alerts on state transition counts, which both keepalived and FRRouting expose.

Lesson. When every packet can change forwarding state, you need rate limits and change alerts as well as filters.

Harvesting the clear text password

Mechanism. RFC 2338's simple text password travelled in every advertisement, once a second by default. One captured packet gave an attacker the password.

Fix. RFC 3768 removed it in 2004. The keepalived manual still offers a PASS option for compatibility, notes only the first eight characters are used, calls it non compliant, and its strict mode refuses it.

Lesson. A secret broadcast in clear on the segment it protects is not a control. Treat any surviving auth_type PASS as no authentication, and never reuse that string elsewhere.

Off link injection, and unicast mode bringing it back

Mechanism. Without a TTL check, anyone who can route to 224.0.0.18 or a router's address could inject advertisements from another network. The TTL 255 rule, present since RFC 2338 and formalised as GTSM in RFC 5082, closes that for multicast. Unicast mode reopens it: advertisements cross routers, the check is relaxed, and a host that can spoof a peer's source address can demote the active router, force an election with priority 0, or replay captured advertisements. The keepalived documentation describes exactly this threat.

Fix. Keep the TTL check in multicast mode. Keep unicast peers on a shared link where possible, with unicast_ttl 255 and min_ttl 255. Across hops, restrict reachable sources, enable check_unicast_src, and use keepalived's auth_hmac if every peer supports it.

Lesson. Moving a link local protocol onto routed transport removes the property its security model rests on. Put a replacement control in place first.

Bypassing VRRP with ARP or ND spoofing

Mechanism. An attacker answers ARP requests for the gateway address, or sends unsolicited ARP or Neighbor Advertisements, claiming the gateway IP with its own MAC. The VRRP routers never notice.

Fix. DHCP snooping with dynamic ARP inspection on IPv4, Router Advertisement Guard and source address validation on IPv6 (RFC 6105, RFC 9099 section 2.3), and port security. Our ARP and Neighbor Discovery post covers these.

Lesson. This is why the RFC authors judged VRRP authentication pointless on its own: protecting VRRP without protecting ARP and ND moves the attacker one protocol sideways.

Bugs in the daemons themselves

Mechanism. VRRP daemons parse network input and configuration and carry ordinary bugs. NVD lists CVE-2024-41184 (published 18 July 2024), an integer overflow in keepalived's vrrp_ipsets configuration handler through 2.3.1. NVD shows a 9.8 CVSS 3.1 score from a secondary source, but the CVE text itself says the record "might not be worthwhile" because it needs an empty ipset name in the configuration, so treat that score with care. The keepalived 2.4.0 release notes separately list buffer overflow fixes in the checker and parser.

Fix. Track the daemon version on every router, appliance image and container, patch through your normal pipeline, and run track and notify scripts as an unprivileged user (keepalived's enable_script_security and script_user).

Lesson. The protocol is stable, but the daemon on your gateway is a dependency like any other, often inside images nobody rebuilds.

Attack and defence summary

Attack (conceptual)NeedsPrimary fixDetect with
Rogue higher priority advertisement and interceptionAny host on the segmentDrop protocol 112 on host facing ports; TLS and SSH everywhereNew advertiser alerts; gateway MAC on an unexpected port
Election storms and black holesAny host on the segmentPort filtering, control plane policing, sane timersState transition counters
Clear text password captureLegacy RFC 2338 style configurationRemove PASS authenticationConfiguration review
Off link injectionRouted reachabilityTTL or Hop Limit 255 checkDiscard counters, logs
Unicast spoofing and replayRouted reachability to a peerSource filtering, check_unicast_src, auth_hmacVerification failure counters
ARP or ND spoofing of the gatewayAny host on the segmentDynamic ARP inspection, RA Guard, SAVIDuplicate MAC for gateway IP
Daemon vulnerabilitiesDepends on the bugVersion tracking and patchingInventory of daemon versions

Step by step: run and secure VRRP on Linux

This builds a two node IPv4 and IPv6 gateway pair with keepalived using documentation ranges: LAN 192.0.2.0/24 and 2001:db8:10::/64, router A 192.0.2.2, router B 192.0.2.3, gateway 192.0.2.1 and 2001:db8:10::1. Nothing here destroys data, but changing a live gateway interrupts traffic, so use a lab or a maintenance window.

Step 1: install keepalived and confirm the version

# Debian or Ubuntu
sudo apt update && sudo apt install keepalived

# Fedora, RHEL and derivatives
sudo dnf install keepalived

# Confirm what you actually got; distribution packages often trail upstream
keepalived -v

The auth_hmac extension in step 7 needs keepalived 2.4.0 or newer (2.4.3 fixed its clock step handling). If your distribution ships older, use multicast with port filtering or package a newer release through your normal process.

Step 2: enable forwarding and check reverse path filtering

# Routers must forward packets
sudo sysctl -w net.ipv4.ip_forward=1
sudo sysctl -w net.ipv6.conf.all.forwarding=1

# Check reverse path filtering; keepalived adjusts it when use_vmac is enabled
sysctl net.ipv4.conf.all.rp_filter net.ipv4.conf.eth0.rp_filter

Persist these under /etc/sysctl.d/. Set ip_forward first: the kernel's ip-sysctl documentation warns that changing it resets IPv4 configuration parameters to their host or router defaults. The keepalived manual notes that use_vmac on an IPv4 instance with rp_filter set raises the per interface values and sets all.rp_filter to 0 while it runs.

Step 3: write the configuration on router A

# /etc/keepalived/keepalived.conf on router A
global_defs {
    router_id gw-a
    vrrp_version 3
    # Enforce RFC behaviour: no authentication, no unicast,
    # no preempt delay, accept mode off unless priority is 255
    vrrp_strict
    # Run track and notify scripts as an unprivileged user
    enable_script_security
    script_user keepalived_script
}

vrrp_script chk_uplink {
    # Exits 0 when the upstream path is healthy
    script "/usr/local/sbin/check-uplink"
    interval 2
    fall 2
    rise 2
    # Drop priority by 60 when the uplink is down, so router B (100) wins
    weight -60
}

vrrp_instance LAN_V4 {
    # vrrp_strict only allows state MASTER with priority 255
    state BACKUP
    interface eth0
    virtual_router_id 10
    priority 150
    advert_int 1
    virtual_ipaddress {
        192.0.2.1/24
    }
    track_script {
        chk_uplink
    }
}

vrrp_instance LAN_V6 {
    state BACKUP
    interface eth0
    virtual_router_id 10
    priority 150
    advert_int 1
    virtual_ipaddress {
        # VRRPv3 requires the first IPv6 virtual address to be link local
        fe80::1/64
        2001:db8:10::1/64
    }
    track_script {
        chk_uplink
    }
}

Router B gets the same file with router_id gw-b and priority 100. Notes:

  • One VRID (10) serves both families because VRRPv3 treats them as separate virtual routers with different virtual MACs (00:00:5e:00:01:0a and 00:00:5e:00:02:0a).
  • The 50 point gap follows the keepalived manual, and weight minus 60 drops A to 90, below B, when its uplink fails.
  • vrrp_strict enforces RFC rules listed in the manual, including no authentication, no unicast peers, no preempt delay and accept mode off for non owners, so A will not answer pings to 192.0.2.1. Monitor the routers' own addresses and forwarding instead.
  • For preemption off, add nopreempt to both instances; it only works when the initial state is not MASTER.
  • Without use_vmac, keepalived puts virtual addresses on the physical interface and relies on gratuitous ARP, so the gateway's MAC changes on failover. use_vmac creates a macvlan with the RFC virtual MAC.

Create the script user and keep the script root owned:

sudo useradd --system --no-create-home --shell /usr/sbin/nologin keepalived_script
sudo install -o root -g root -m 0755 check-uplink /usr/local/sbin/check-uplink

Step 4: test the configuration, then start

# Syntax and semantic check; non-zero exit status on errors
sudo keepalived -t -f /etc/keepalived/keepalived.conf; echo "exit: $?"

sudo systemctl enable --now keepalived
sudo journalctl -u keepalived -n 50 --no-pager

The man page documents distinct exit codes for the test, including one for scripts configured without script security. Run the test in whatever pushes configuration.

Step 5: check state

# Which node holds the virtual addresses right now
ip -br addr show dev eth0

# Watch advertisements on the wire (protocol 112)
sudo tcpdump -ni eth0 'ip proto 112 or ip6 proto 112' -c 10 -vv

# Dump keepalived's internal state to a file (path shown in the man page,
# usually /tmp/keepalived.data unless state_dump_file is set)
sudo kill -s $(keepalived --signum=DATA) $(cat /run/keepalived.pid)
sudo grep -E 'VRRP Instance|State|Priority|Last transition' /tmp/keepalived.data

In tcpdump, check the source is router A, TTL or hop limit is 255, version is 3 and priority is 150. Router B should not hold the virtual addresses and should log BACKUP.

Step 6: test failover the right way and the hard way

# Clean stop on router A: sends priority 0, B should take over in well under a second
sudo systemctl stop keepalived
# On router B, confirm it now holds 192.0.2.1 and 2001:db8:10::1
ip -br addr show dev eth0
# Bring A back; with preemption on it reclaims the role after hearing B
sudo systemctl start keepalived

Then, in a lab, pull router A's cable and time how long a continuous ping from a host loses replies. Expect roughly three to four seconds at default timers, matching the arithmetic above.

Step 7: if multicast is unavailable, use unicast with authentication

Where multicast is unavailable, keepalived can unicast advertisements. Strict mode forbids this, so drop vrrp_strict for these instances and add the controls by hand:

vrrp_instance LAN_V4 {
    state BACKUP
    interface eth0
    virtual_router_id 10
    priority 150
    advert_int 1
    unicast_src_ip 192.0.2.2
    unicast_peer {
        # Keep the TTL proof when both peers share a link
        192.0.2.3 min_ttl 255 max_ttl 255
    }
    check_unicast_src
    auth_hmac {
        # 32 byte key read from a root only file, never inline in shared config
        key 1 file:/etc/keepalived/keys/vrid10
        active_key 1
        anti_replay time
    }
    virtual_ipaddress {
        192.0.2.1/24
    }
}

Per the keepalived documentation, roll auth_hmac out receive only, then permissive, then enforce; keep clocks synced with NTP for time based anti replay; and rotate keys by adding a second key and moving active_key. Every peer must run 2.4.0 or newer.

Step 8: the FRRouting alternative

FRRouting's vrrpd implements VRRPv2 and VRRPv3 on Linux 5.1 or newer. You create a macvlan per address family with the virtual MAC, in bridge mode, with a random IPv6 link local address so two routers never share one and both claim the active role:

ip link add vrrp4-2-1 link eth0 addrgenmode random type macvlan mode bridge
ip link set dev vrrp4-2-1 address 00:00:5e:00:01:0a
ip addr add 192.0.2.1/24 dev vrrp4-2-1
ip link set dev vrrp4-2-1 up
interface eth0
 vrrp 10 version 3
 vrrp 10 priority 150
 vrrp 10 advertisement-interval 1000
 vrrp 10 ip 192.0.2.1

show vrrp prints per family status, effective priority, skew time, down interval and counters for advertisements and state transitions. FRRouting puts the macvlan into protodown in Backup rather than removing addresses, hence bridge mode and kernel 5.1. It supports no VRRP authentication.

Step 9: filter VRRP where it should never appear

On switches, apply an access list on every host facing port that drops IPv4 protocol 112, IPv6 next header 112 and traffic to 224.0.0.18 and ff02::12. Syntax varies by platform, so confirm with your switching team that only router ports can send VRRP.

On Linux hosts that are not gateways, drop VRRP with nftables:

sudo nft add table inet vrrp_guard
sudo nft add chain inet vrrp_guard in '{ type filter hook input priority 0 ; policy accept ; }'
sudo nft add chain inet vrrp_guard out '{ type filter hook output priority 0 ; policy accept ; }'
sudo nft add rule inet vrrp_guard in meta l4proto 112 counter drop
sudo nft add rule inet vrrp_guard out meta l4proto 112 counter drop
sudo nft list table inet vrrp_guard

On gateways, accept VRRP only from known peers with TTL or hop limit 255 and count the rest:

sudo nft add table inet vrrp_peers
sudo nft add chain inet vrrp_peers in '{ type filter hook input priority -10 ; policy accept ; }'
sudo nft add rule inet vrrp_peers in iifname "eth0" ip protocol 112 ip saddr '{ 192.0.2.2, 192.0.2.3 }' ip ttl 255 accept
sudo nft add rule inet vrrp_peers in iifname "eth0" ip6 nexthdr 112 ip6 hoplimit 255 ip6 saddr fe80::/10 accept
sudo nft add rule inet vrrp_peers in meta l4proto 112 counter log prefix '"vrrp-unexpected: "' drop

The nftables manual documents meta l4proto for either IP version and the ip and ip6 header fields used here. Tighten the IPv6 rule to the routers' link local addresses, and watch the final counter: on a healthy segment it stays at zero.

How to monitor VRRP

  • State transitions. Every Backup to Active change should raise an event. keepalived can run notify scripts or write to a FIFO; FRRouting counts transitions. More than a few a day means flapping or interference.
  • Advertiser set. Any source outside the expected routers for a VRID is a misconfiguration or a rogue node.
  • Duplicate active routers. Two sources active for one VRID is always wrong, typically from a broken inter switch link, a firewall dropping 224.0.0.18, or a key mismatch.
  • Management models. RFC 6527 defines the VRRPv3 MIB and RFC 8347 (March 2018) a YANG model for v2 and v3 telemetry.
  • Gateway MAC location. The gateway MAC should only be learned on router ports; a host port means takeover or ARP spoofing.

Common mistakes

  • Reusing a VRID on one segment. Two pairs on VRID 1 in the same VLAN fight. Keep a VRID register per VLAN.
  • Equal or close priorities. Ties fall back to the highest IP, and close priorities leave skew gaps of tens of milliseconds.
  • Blocking 224.0.0.18 between the routers. Each thinks the other is dead and both go active.
  • Relaxing the TTL check for unicast and adding nothing back.
  • Keeping legacy password authentication. It sends the secret in clear and breaks failover when one side changes.
  • Pinging the virtual IP for monitoring. With Accept_Mode off a healthy router does not answer, and the "fix" of enabling it everywhere is worse.
  • Sub second timers on busy or virtualised hosts. A stalled process or descheduled VM triggers needless failovers.
  • Mixing VRRPv2 and VRRPv3 permanently. RFC 9568 allows it only during migration.
  • Ignoring the IPv6 instance. The families fail over independently.
  • Forgetting first hop security. Open ARP and Router Advertisements leave the same interception path.
  • Treating the daemon as furniture. It has its own release notes and CVEs.

FAQ

What is VRRP in simple terms?

A group of routers acting as one. Hosts use one gateway address, the routers decide which one answers, and if it fails another takes over the same IP and MAC within seconds.

What port does VRRP use?

None. VRRP runs directly over IP as protocol number 112, sending to 224.0.0.18 or ff02::12, so firewall rules must match protocol 112, not a port.

What is the difference between VRRPv2 and VRRPv3?

VRRPv2 (RFC 3768) is IPv4 only with whole second timers. VRRPv3 (RFC 5798, now RFC 9568) adds IPv6, centisecond timers for sub second failover, and drops the authentication field. RFC 9568 renamed Master to Active Router.

Is RFC 5798 obsolete?

Yes. RFC 9568 (April 2024) obsoletes it. The protocol is still version 3, with errata fixes, a clarified checksum, new terminology and an immediate advertisement when the active router hears a lower priority router.

How long does VRRP failover take?

At defaults (1 second interval), a priority 100 backup waits three intervals plus about 0.61 seconds of skew, about 3.6 seconds. After a clean shutdown (priority 0) it waits only the skew. At a 100 ms interval, roughly 300 to 400 ms.

Does VRRP support authentication?

The standard does not; RFC 3768 removed it in 2004. Some daemons keep legacy VRRPv2 modes, and keepalived 2.4.0 (June 2026) added a non standard HMAC-SHA256 extension, mainly for unicast, that only works between keepalived peers.

Can VRRP load balance traffic?

Not within one virtual router. Run two virtual routers with opposite priorities and give half the hosts each gateway. Some proprietary protocols balance per host via ARP replies.

What is the VRRP virtual MAC address?

00-00-5E-00-01-XX for IPv4 and 00-00-5E-00-02-XX for IPv6, where XX is the VRID in hex. VRID 10 gives 00-00-5E-00-01-0A.

Can someone on my network hijack the VRRP gateway?

Yes, if host ports can send VRRP: a higher priority advertisement makes the host active. Filter VRRP on host facing ports, as RFC 9568 suggests, and protect ARP and Neighbor Discovery, since a host can spoof the gateway without VRRP.

Should I use VRRP or an anycast gateway?

In a VXLAN and EVPN fabric, the RFC 9135 distributed anycast gateway is usual: every leaf forwards and there is no election. VRRP fits router or firewall pairs on a conventional LAN, especially across equipment makers.

Where Safeguard fits

Safeguard does not monitor VRRP, filter switch ports or inspect network traffic, so the fit is indirect and sits with the software that implements the gateway. keepalived and FRRouting are open source packages that ship inside firewall images, load balancer containers and router appliance builds, along with OpenSSL for auth_hmac. Safeguard scans repositories, container images and SBOM files with safeguard scan, matches components against vulnerability databases, and shows which projects contain a given component and version, so "which gateway images still ship keepalived older than 2.4.0" has an answer from your own data. Port ACLs, first hop security and timer tuning stay with your network team.

Fix it without waiting for upstream

Gateway pairs are rarely rebuilt, so the keepalived or FRRouting build inside a firewall image or load balancer container can sit unchanged for years while its own dependencies collect advisories. The steps below cover the open source packages and images you build and ship around your gateways; for a vendor appliance's own VRRP code, the fix still comes from that vendor, and fork and patch is early access.

Whatever the vulnerability, most of the risk sits in two gaps. The first is the time between a fix being published and that fix actually running in your production builds. The second, and worse, is the time before any fix exists at all, while a maintainer works out a patch and a release schedule. Waiting through both gaps is a habit, not a requirement. Safeguard gives teams three ways to close them.

1. Autonomous remediation: pull requests, not tickets

When a fixed version exists, Safeguard's Griffin models open a tested, policy gated pull request that moves the affected dependency to the safe version. You can run it on one repository or in bulk across every project that carries the vulnerable version. Remediation covers eight categories, including dependencies, licenses, security posture and findings. Reachability analysis ranks the vulnerable code paths your application actually calls first, so the first pull requests you merge are the ones that matter most. Autonomous remediation ships switched off, with every category set to Manual, so your team decides how much runs on its own and what still needs a human approval.

2. Gold Open Source: the safe version in seconds, free

gold.safeguard.sh is free and needs no login. Search any CVE or package to see affected and fixed versions, CVSS, EPSS, CISA KEV status and a recommended safe version, or use the "Am I affected?" checker. The same data is available through a free read API, README status badges and RSS threat feeds. The safeguard-sh/gold-scan-action GitHub Action can fail a build on a known exploited vulnerability, on any known vulnerability, or never, so a version you have just removed cannot quietly come back in next week's merge.

3. Gold Registry: start from components that are already fixed

registry.safeguard.sh provides hardened, drop in replacements for upstream packages and container images. Every Gold artifact is held continuously to zero exploitable critical or high CVEs, zero malware and a completed license check, with SLSA L3 or higher provenance, a Sigstore signature and a public evidence page you can hand to an auditor. An artifact loses its Gold badge if it regresses. Teams can point their own package directory at the registry so hardened equivalents resolve without changing how developers install anything.

When upstream has no fix yet, or will not ship one, Safeguard first works to get the fix accepted upstream. If the issue is severe or upstream will not move, Safeguard builds a fork, fixes the vulnerability there and publishes a hardened Gold build, so you are not stuck on a maintainer's release schedule. You can also request a hardened, compatibility tested build of a specific package. This fork and patch flow is in early access today, so ask which packages it covers before you plan around it.

Your situationWhat to use
A fixed version existsAutonomous remediation opens the upgrade pull request; Gold Open Source confirms the safe version
You need to know today whether you are affectedGold Open Source lookup and "Am I affected?" checker, free and without login
You want vulnerable versions to stop shippingThe Gold scan GitHub Action in CI, plus Safeguard policies and gates
Upstream has no fix yet, or will not ship oneA custom Gold request; fork and patch (early access)
You want to start clean on new projectsPull hardened components and images from Gold Registry

One honest limit: when the vulnerable code lives in a vendor appliance, a hosted service or an operating system runtime you do not build yourself, the fix still has to come from that vendor or distribution. The steps above apply to the open source dependencies and container images you build and ship, which is where most teams carry the largest and least tracked share of their exposure.

See how Safeguard would help

These demos show dependency, SBOM and remediation workflows, not VRRP monitoring. You can download Safeguard and follow the CLI docs to try them on your own projects.

This demo sets up the Safeguard runner on your own machine, approves it with its device code and scans from the terminal. Pointed at the container image for a gateway or load balancer your team builds, the same scan lists the packages inside it, including the keepalived or FRRouting version, and their known vulnerabilities.

Click through it at your own pace, or open it full screen.

This demo is a real CLI session: ask it to fix the lodash CVE in a repository and watch it read the finding and the advisory, ask before each command, move lodash to 4.17.21, run npm install and npm test with your approval, and push nothing. The same approve each step flow applies when you bump a pinned package version in the Dockerfile or build recipe that produces your gateway image.

Click through it at your own pace, or open it full screen.

This demo connects Claude to the Safeguard MCP server with OAuth and lets you choose which tools Claude can use. You can then ask which of your projects ship a given keepalived version and get the answer from your own scan data rather than from memory.

Click through it at your own pace, or open it full screen.

Quick check

With a 1 second advertisement interval, how long does a priority 200 backup wait before taking over from a silent active router?

Skew_Time is (256 minus 200) times 100 divided by 256, about 21.9 centiseconds, so Active_Down_Interval is 300 plus 21.9, about 322 centiseconds or roughly 3.2 seconds after the last advertisement it heard.

Which RFC removed VRRP authentication, and what does RFC 9568 suggest instead?

RFC 3768 removed it in April 2004. RFC 9568 relies on the TTL or Hop Limit 255 check against off link packets, suggests filtering VRRP on switch ports facing end hosts, and recommends the link layer security guidance in RFC 9099 section 2.3 for IPv6.

Sources

Last reviewed: 23 October 2026. VRRP implementations change their defaults and options between releases, and the keepalived HMAC extension is described in an individual Internet-Draft that may change; check RFC 9568 and your daemon's documentation for the version you run.

Never miss an update

Weekly insights on software supply chain security, delivered to your inbox.

Self-healing security runs on Safeguard.

Your first fix PR is minutes away.

No sales call required, even your agent can complete the purchase over MCP.