High availability

Configure two HAProxy Enterprise servers for active/standby clustering

This page applies to:

  • HAProxy Enterprise - all versions

Using HAProxy Fusion?

If you’re using HAProxy Fusion, then see the HAProxy Fusion - High availability topic instead.

In an active-standby cluster, one HAProxy Enterprise node receives traffic while a second node is put on standby. In case the active node fails, the standby takes over. With HAProxy Enterprise, you configure an active-standby cluster by installing the Virtual Router Redundancy Protocol (VRRP) module.

The HAProxy Enterprise VRRP module assigns a virtual, static IP address to your load balancer node. If the node fails, the IP address will instantly transfer to a backup node, avoiding any break in service. Your router can continue to send traffic to the same IP address for the load balancer, never knowing that there was a failover. The module utilizes a stable version of Keepalived, which implements VRRP.

In this guide, we will set up two load balancers: one active and the other on standby.

Active/Standby with VRRP

Prerequisites Jump to heading

Multicast capability required VRRP requires multicast capability. However, some environments, such as AWS, may not allow multicasting. In these environments, you may have to configure a unicast implementation instead or use some other solution besides VRRP.

If you have a firewall running on the server, such as firewalld (the default on Red Hat Enterprise Linux) or iptables, then be sure to add an exception for VRRP traffic.

Add an exception to firewalld

To add an exception for VRRP to firewalld:

  1. Check if firewalld is running:

    nix
    sudo firewall-cmd --state
    nix
    sudo firewall-cmd --state
    output
    running
    output
    running
  2. Check which firewalld zones are active for your network interfaces. Below, our active zone is named public:

    nix
    sudo firewall-cmd --get-active-zones
    nix
    sudo firewall-cmd --get-active-zones
    output
    public interfaces: eth0 eth1
    output
    public interfaces: eth0 eth1
  3. To ensure that existing runtime rules (those that are in effect) are persisted, save them as permanent before going further:

    nix
    sudo firewall-cmd --runtime-to-permanent
    nix
    sudo firewall-cmd --runtime-to-permanent
    output
    success
    output
    success
  4. Add the VRRP protocol to the list of rules. Below, we use the zone named public:

    nix
    sudo firewall-cmd --zone=public --add-protocol=vrrp --permanent
    sudo firewall-cmd --reload
    nix
    sudo firewall-cmd --zone=public --add-protocol=vrrp --permanent
    sudo firewall-cmd --reload
    output
    success
    output
    success
  5. Verify that the protocol has been added. Below, we use the zone named public:

    nix
    sudo firewall-cmd --zone=public --list-all | grep vrrp
    nix
    sudo firewall-cmd --zone=public --list-all | grep vrrp
    protocols: vrrp
    protocols: vrrp
  6. Make these changes persist:

    nix
    sudo firewall-cmd --runtime-to-permanent
    nix
    sudo firewall-cmd --runtime-to-permanent
    output
    success
    output
    success
  7. If you need to revert this change, run these commands:

    nix
    sudo firewall-cmd --zone=public --remove-protocol=vrrp --permanent
    sudo firewall-cmd --reload
    nix
    sudo firewall-cmd --zone=public --remove-protocol=vrrp --permanent
    sudo firewall-cmd --reload
Add an exception to iptables

To add an exception for VRRP to iptables:

  1. Save a backup of your current iptables configuration:

    nix
    sudo apt install iptables-persistent
    sudo su -c 'iptables-save > /etc/iptables.backup.rules'
    nix
    sudo apt install iptables-persistent
    sudo su -c 'iptables-save > /etc/iptables.backup.rules'
  2. Add the VRRP protocol to the list of rules. Below, we specify the interface eth0:

    nix
    sudo iptables -A INPUT -p vrrp -i eth0 -j ACCEPT && sudo iptables -A OUTPUT -p vrrp -j ACCEPT
    nix
    sudo iptables -A INPUT -p vrrp -i eth0 -j ACCEPT && sudo iptables -A OUTPUT -p vrrp -j ACCEPT
  3. Verify that the protocol number 112 (VRRP) has been added:

    nix
    sudo iptables -nvL | grep 112
    nix
    sudo iptables -nvL | grep 112
    output
    0 0 ACCEPT 112 -- eth0 * 0.0.0.0/0 0.0.0.0/0 0 0 ACCEPT 112 -- * * 0.0.0.0/0 0.0.0.0/0
    output
    0 0 ACCEPT 112 -- eth0 * 0.0.0.0/0 0.0.0.0/0 0 0 ACCEPT 112 -- * * 0.0.0.0/0 0.0.0.0/0
  4. Save the configuration:

    nix
    sudo su -c 'iptables-save > /etc/iptables/rules.v4'
    nix
    sudo su -c 'iptables-save > /etc/iptables/rules.v4'
  5. To revert this change, run this command:

    nix
    sudo iptables-restore < /etc/iptables.backup.rules
    nix
    sudo iptables-restore < /etc/iptables.backup.rules

    Then save the configuration as in the previous step.

Are you using Cisco ACI (Application Centric Infrastructure) in your setup?

A known issue with Cisco ACI occurs after a failover in which traffic continues to go to the load balancer that was formerly the primary. This can happen when the former primary briefly sends out traffic over old connections, causing Cisco ACI to relearn the VIP back to the former primary. Avoid this issue by disabling the IP Data-plane Learning option under the VRF and enabling GARP-based detection. See the Cisco ACI White Paper for more details.

Installation Jump to heading

Follow the steps on your active and backup load balancers.

Active load balancer Jump to heading

On the active load balancer, follow these steps:

  1. Install the VRRP module using your system’s package manager:

    Remove the hapee-extras-vrrp package if you installed it previously:

    nix
    sudo apt remove hapee-extras-vrrp
    nix
    sudo apt remove hapee-extras-vrrp

    Install the 2.2 version of VRRP:

    nix
    sudo apt-get install hapee-extras-vrrp22
    nix
    sudo apt-get install hapee-extras-vrrp22

    Remove the hapee-extras-vrrp package if you installed it previously:

    nix
    sudo yum remove hapee-extras-vrrp
    nix
    sudo yum remove hapee-extras-vrrp

    Install the 2.2 version of VRRP:

    nix
    sudo yum install hapee-extras-vrrp22
    nix
    sudo yum install hapee-extras-vrrp22

    Remove the hapee-extras-vrrp package if you installed it previously:

    nix
    sudo zypper remove hapee-extras-vrrp
    nix
    sudo zypper remove hapee-extras-vrrp

    Install the 2.2 version of VRRP:

    nix
    sudo zypper install hapee-extras-vrrp22
    nix
    sudo zypper install hapee-extras-vrrp22

    Remove the hapee-extras-vrrp package if you installed it previously:

    nix
    sudo pkg delete hapee-extras-vrrp
    nix
    sudo pkg delete hapee-extras-vrrp

    Install the 2.2 version of VRRP:

    nix
    sudo pkg install hapee-extras-vrrp22
    nix
    sudo pkg install hapee-extras-vrrp22
  2. Decide on a unique Virtual Router Identifier (VRID) for the cluster. A VRID can be any number between 1 and 255. It allows the instances in a cluster to share a virtual router and virtual IP address. The VRID must be the same on all instances in a cluster. If there are multiple VRRP clusters in the environment, the VRID must be unique for each cluster.

    Don’t use a VRID already in use for another cluster. If the vrrp service has been started and enabled, you can list VRIDs already in use by executing the following command (substitute your interface for eth0):

    nix
    sudo tcpdump -vvvenns0 -c 50 -i eth0 vrrp | grep -o "vrid [0-9]*" | sort -nr | uniq
    nix
    sudo tcpdump -vvvenns0 -c 50 -i eth0 vrrp | grep -o "vrid [0-9]*" | sort -nr | uniq
    output
    text
    [...]
    5 packets captured
    6 packets received by filter
    0 packets dropped by kernel
    vrid 161
    vrid 155
    output
    text
    [...]
    5 packets captured
    6 packets received by filter
    0 packets dropped by kernel
    vrid 161
    vrid 155

    In our example configuration, we will use VRID 51.

  3. Decide on a password for the cluster. The password is a clear-text string for use by all instances in this VRRP cluster. It doesn’t provide security, but it ensures that VRRP instances from other clusters can’t accidentally join this cluster.

  4. Edit the file /etc/hapee-extras/hapee-vrrp.cfg.

    • In the vrrp_instance section, change the interface value from eth0 to the name of a network interface that receives traffic on the server. This is the same interface that you the bind HAProxy Enterprise’s frontend to. For example, if traffic reaches the load balancer using interface enp0s8. Set this line to interface enp0s8.

    • For the virtual_router_id value, specify the VRID determined previously.

    • Change the authentication password in auth_pass to the password determined previously. If the vrrp_instance section does not already contain an authentication section, add one:

      hapee-vrrp.cfg
      text
      vrrp_instance vrrp_1 {
      authentication {
      auth_type PASS
      auth_pass 1234 # Text string unique to this cluster
      }
      hapee-vrrp.cfg
      text
      vrrp_instance vrrp_1 {
      authentication {
      auth_type PASS
      auth_pass 1234 # Text string unique to this cluster
      }
    • Change the IP address listed in the virtual_ipaddress_excluded block to the virtual IP address you’d like to assign to this interface. HAProxy Enterprise will bind to this address to receive traffic. If needed, add more IP addresses here, each on its own line. The new address(es) should fall within the interface’s IP subnet but shouldn’t already be assigned to any server.

    • In the track_interface block, specify the same interface name that is specified in the interface field.

    The full vrrp_instance section:

    hapee-vrrp.cfg
    text
    vrrp_instance vrrp_1 {
    interface enp0s8 # Change network interface name
    state MASTER
    virtual_router_id 51 # VRID unique to this cluster
    authentication {
    auth_type PASS
    auth_pass 1234 # Text string unique to this cluster
    }
    priority 101
    virtual_ipaddress_excluded {
    192.168.50.10 # New IP address
    }
    track_interface {
    enp0s8 weight -2 # Change network interface name
    }
    track_script {
    chk_sshd
    chk_lb
    }
    }
    hapee-vrrp.cfg
    text
    vrrp_instance vrrp_1 {
    interface enp0s8 # Change network interface name
    state MASTER
    virtual_router_id 51 # VRID unique to this cluster
    authentication {
    auth_type PASS
    auth_pass 1234 # Text string unique to this cluster
    }
    priority 101
    virtual_ipaddress_excluded {
    192.168.50.10 # New IP address
    }
    track_interface {
    enp0s8 weight -2 # Change network interface name
    }
    track_script {
    chk_sshd
    chk_lb
    }
    }
  5. Enable and start the hapee-extras-vrrp service:

    nix
    sudo systemctl unmask hapee-extras-vrrp
    sudo systemctl enable hapee-extras-vrrp
    sudo systemctl start hapee-extras-vrrp
    nix
    sudo systemctl unmask hapee-extras-vrrp
    sudo systemctl enable hapee-extras-vrrp
    sudo systemctl start hapee-extras-vrrp
  6. Allow the server to bind to the virtual IP address.

    Edit the file /etc/sysctl.conf and add the net.ipv4.ip_nonlocal_bind=1 directive. This directive allows the server to accept connections for IP addresses that aren’t bound to any of its interfaces, enabling the use of a floating, virtual IP.

    sysctl.conf
    ini
    net.ipv4.ip_nonlocal_bind=1
    sysctl.conf
    ini
    net.ipv4.ip_nonlocal_bind=1
  7. Configure your bind line in the HAProxy Enterprise configuration to use the virtual IP address.

    haproxy
    frontend myfrontend
    mode http
    bind 192.168.50.10:80
    default_backend web_servers
    haproxy
    frontend myfrontend
    mode http
    bind 192.168.50.10:80
    default_backend web_servers
  8. Reboot the server.

Standby load balancer Jump to heading

On the standby load balancer, follow these steps:

  1. Install the VRRP module using your system’s package manager:

    Remove the hapee-extras-vrrp package if you installed it previously:

    nix
    sudo apt remove hapee-extras-vrrp
    nix
    sudo apt remove hapee-extras-vrrp

    Install the 2.2 version of VRRP:

    nix
    sudo apt-get install hapee-extras-vrrp22
    nix
    sudo apt-get install hapee-extras-vrrp22

    Remove the hapee-extras-vrrp package if you installed it previously:

    nix
    sudo yum remove hapee-extras-vrrp
    nix
    sudo yum remove hapee-extras-vrrp

    Install the 2.2 version of VRRP:

    nix
    sudo yum install hapee-extras-vrrp22
    nix
    sudo yum install hapee-extras-vrrp22

    Remove the hapee-extras-vrrp package if you installed it previously:

    nix
    sudo zypper remove hapee-extras-vrrp
    nix
    sudo zypper remove hapee-extras-vrrp

    Install the 2.2 version of VRRP:

    nix
    sudo zypper install hapee-extras-vrrp22
    nix
    sudo zypper install hapee-extras-vrrp22

    Remove the hapee-extras-vrrp package if you installed it previously:

    nix
    sudo pkg delete hapee-extras-vrrp
    nix
    sudo pkg delete hapee-extras-vrrp

    Install the 2.2 version of VRRP:

    nix
    sudo pkg install hapee-extras-vrrp22
    nix
    sudo pkg install hapee-extras-vrrp22
  2. Edit the VRRP configuration /etc/hapee-extras/hapee-vrrp.cfg. It must be exactly the same as the file on the active load balancer, except for these differences:

    • In the vrrp_instance block, change the interface value to the name of the network interface that receives traffic on the server.

    • Change the state value to BACKUP.

    • For the virtual_router_id value, specify the VRID determined previously.

    • Change the authentication password in auth_pass to the password determined previously. If the vrrp_instance section does not already contain an authentication section, add one:

      hapee-vrrp.cfg
      text
      vrrp_instance vrrp_1 {
      authentication {
      auth_type PASS
      auth_pass 1234 # Text string unique to this cluster
      }
      hapee-vrrp.cfg
      text
      vrrp_instance vrrp_1 {
      authentication {
      auth_type PASS
      auth_pass 1234 # Text string unique to this cluster
      }
    • Change the priority field to have a lower number than the active node. The load balancer with the highest priority is promoted to be the active node. For example, if the priority on the active node is 101, then set the backup node’s priority to 100.

    • In the track_interface block, specify the same interface name that is specified in the interface field.

    hapee-vrrp.cfg
    text
    vrrp_instance vrrp_1 {
    interface enp0s8 # Change network interface name
    state BACKUP # Change to BACKUP
    virtual_router_id 51
    authentication {
    auth_type PASS
    auth_pass 1234
    }
    priority 100 # A lower priority value than the primary
    virtual_ipaddress_excluded {
    192.168.50.10 # Same IP address as on primary
    }
    track_interface {
    enp0s8 weight -2 # Change network interface name
    }
    track_script {
    chk_sshd
    chk_lb
    }
    }
    hapee-vrrp.cfg
    text
    vrrp_instance vrrp_1 {
    interface enp0s8 # Change network interface name
    state BACKUP # Change to BACKUP
    virtual_router_id 51
    authentication {
    auth_type PASS
    auth_pass 1234
    }
    priority 100 # A lower priority value than the primary
    virtual_ipaddress_excluded {
    192.168.50.10 # Same IP address as on primary
    }
    track_interface {
    enp0s8 weight -2 # Change network interface name
    }
    track_script {
    chk_sshd
    chk_lb
    }
    }
  3. Enable and start the hapee-extras-vrrp service:

    nix
    sudo systemctl unmask hapee-extras-vrrp
    sudo systemctl enable hapee-extras-vrrp
    sudo systemctl start hapee-extras-vrrp
    nix
    sudo systemctl unmask hapee-extras-vrrp
    sudo systemctl enable hapee-extras-vrrp
    sudo systemctl start hapee-extras-vrrp
  4. Allow the server to bind to the virtual IP address.

    Edit the file /etc/sysctl.conf and add the net.ipv4.ip_nonlocal_bind=1 directive. This directive allows the server to accept connections for IP addresses that aren’t bound to any of its interfaces, enabling the use of a floating, virtual IP.

    sysctl.conf
    ini
    net.ipv4.ip_nonlocal_bind=1
    sysctl.conf
    ini
    net.ipv4.ip_nonlocal_bind=1
  5. Configure your bind line in the HAProxy Enterprise configuration to use the virtual IP address.

    haproxy
    frontend myfrontend
    mode http
    bind 192.168.50.10:80
    default_backend web_servers
    haproxy
    frontend myfrontend
    mode http
    bind 192.168.50.10:80
    default_backend web_servers
  6. Reboot the server.

Verify the setup Jump to heading

To check that the VRRP service is running, use systemctl status:

nix
sudo systemctl status hapee-extras-vrrp --no-pager
nix
sudo systemctl status hapee-extras-vrrp --no-pager
output
text
● hapee-extras-vrrp.service - HAPEE VRRP : VRRP daemon (Keepalived)
Loaded: loaded (/usr/lib/systemd/system/hapee-extras-vrrp.service; enabled; preset: enabled)
Active: active (running) since Thu 2026-09-24 18:08:18 UTC; 19h ago
Main PID: 559 (hapee-vrrp)
Tasks: 2 (limit: 3736)
Memory: 2.1M (peak: 4.3M)
CPU: 12min 23.921s
CGroup: /system.slice/hapee-extras-vrrp.service
├─559 /opt/hapee-extras/sbin/hapee-vrrp --dont-fork -D -f /etc/hapee-extras/hapee-vrrp.cfg -p /var/run/hapee-extras/hapee-vrrp.pid
└─567 /opt/hapee-extras/sbin/hapee-vrrp --dont-fork -D -f /etc/hapee-extras/hapee-vrrp.cfg -p /var/run/hapee-extras/hapee-vrrp.pid
Sep 24 18:08:27 ip-10-80-10-37 Keepalived_vrrp[567]: (vrrp_1) forcing a new MASTER election
Sep 24 18:08:28 ip-10-80-10-37 Keepalived_vrrp[567]: (vrrp_1) Transition to MASTER STATE
Sep 24 18:08:29 ip-10-80-10-37 Keepalived_vrrp[567]: (vrrp_1) Entering MASTER STATE
Sep 24 18:08:30 ip-10-80-10-37 Keepalived_vrrp[567]: (vrrp_1) setting protocol E-VIPs.
Sep 24 18:08:31 ip-10-80-10-37 Keepalived_vrrp[567]: (vrrp_1) Sending gratuitous ARPs on ens5 for 10.80.10.51
output
text
● hapee-extras-vrrp.service - HAPEE VRRP : VRRP daemon (Keepalived)
Loaded: loaded (/usr/lib/systemd/system/hapee-extras-vrrp.service; enabled; preset: enabled)
Active: active (running) since Thu 2026-09-24 18:08:18 UTC; 19h ago
Main PID: 559 (hapee-vrrp)
Tasks: 2 (limit: 3736)
Memory: 2.1M (peak: 4.3M)
CPU: 12min 23.921s
CGroup: /system.slice/hapee-extras-vrrp.service
├─559 /opt/hapee-extras/sbin/hapee-vrrp --dont-fork -D -f /etc/hapee-extras/hapee-vrrp.cfg -p /var/run/hapee-extras/hapee-vrrp.pid
└─567 /opt/hapee-extras/sbin/hapee-vrrp --dont-fork -D -f /etc/hapee-extras/hapee-vrrp.cfg -p /var/run/hapee-extras/hapee-vrrp.pid
Sep 24 18:08:27 ip-10-80-10-37 Keepalived_vrrp[567]: (vrrp_1) forcing a new MASTER election
Sep 24 18:08:28 ip-10-80-10-37 Keepalived_vrrp[567]: (vrrp_1) Transition to MASTER STATE
Sep 24 18:08:29 ip-10-80-10-37 Keepalived_vrrp[567]: (vrrp_1) Entering MASTER STATE
Sep 24 18:08:30 ip-10-80-10-37 Keepalived_vrrp[567]: (vrrp_1) setting protocol E-VIPs.
Sep 24 18:08:31 ip-10-80-10-37 Keepalived_vrrp[567]: (vrrp_1) Sending gratuitous ARPs on ens5 for 10.80.10.51

Manual failover Jump to heading

To activate the standby load balancer while simultaneously putting the active load balancer into standby mode:

  1. Edit the VRRP configuration /etc/hapee-extras/hapee-vrrp.cfg on the active (current master) load balancer.

  2. Lower the priority value to less than the standby load balancer’s priority. This will put the active load balancer into the standby state and simultaneously activate the standby load balancer. For example, change it from 101 to 90.

  3. Restart the hapee-extras-vrrp service.

    nix
    sudo systemctl restart hapee-extras-vrrp
    nix
    sudo systemctl restart hapee-extras-vrrp

Reverse these actions to restore the original state.

Failover triggers Jump to heading

The following events can trigger a failover:

  • The active node lowers its weight below one of the backup nodes due to a failed health check.
  • A backup node is reconfigured with a weight larger than the current active node.
  • The active node stops emitting its heartbeat packet to the cluster.

VRRP health check scripts Jump to heading

In the VRRP configuration, the vrrp_script blocks define health checks that can trigger a failover. By default, our configuration checks whether the SSH daemon is running and whether HAProxy Enterprise is running. You may want to add more checks.

Consider this block, which checks the status of the SSH daemon every five seconds. If the service isn’t available, the VRRP instance’s weight (its priority) is reduced by 4 points:

hapee-vrrp.cfg
text
vrrp_script chk_sshd {
script "pkill -0 sshd" # pkill -0 is cheaper than pidof
interval 5 # check every 5 seconds
weight -4 # remove 4 points of prio if missing
fall 2 # check twice before setting down
rise 1 # check once before setting up
}
hapee-vrrp.cfg
text
vrrp_script chk_sshd {
script "pkill -0 sshd" # pkill -0 is cheaper than pidof
interval 5 # check every 5 seconds
weight -4 # remove 4 points of prio if missing
fall 2 # check twice before setting down
rise 1 # check once before setting up
}

The HAProxy Enterprise health check is similar, except if the hapee-lb process is running, it adds 6 points. The reason is, in case one load balancer has SSH working but not hapee-lb, while the other has hapee-lb but not SSH, the one with hapee-lb will become the active node, even though it isn’t manageable remotely.

hapee-vrrp.cfg
text
vrrp_script chk_lb {
script "pkill -0 hapee-lb" # pkill -0 is cheaper than pidof
interval 1 # check every second
weight 6 # add 6 points of prio if present
fall 2 # check twice before setting down
rise 1 # check once before setting up
}
hapee-vrrp.cfg
text
vrrp_script chk_lb {
script "pkill -0 hapee-lb" # pkill -0 is cheaper than pidof
interval 1 # check every second
weight 6 # add 6 points of prio if present
fall 2 # check twice before setting down
rise 1 # check once before setting up
}

The following fields define a vrrp_script block:

Name Argument type Description
script string Command to run. Running pkill -0 checks if any process with the given name is running. If it returns 0, the check passes; if it returns 1, the check fails.
interval integer Interval (in seconds) between two checks.
weight integer Points to add or remove to instance weight.
fall integer Number of consecutive negative checks before considered as down.
rise integer Number of consecutive positive checks before considered as up.

Monitor with SNMP Jump to heading

This section applies to

  • HAProxy Enterprise 3.4r1 and newer

The HAProxy Enterprise VRRP module exposes metrics that your network monitoring software can poll for at an interval, via Simple Network Management Protocol (SNMP). It also supports SNMP traps, which are alerts the module sends to the monitoring software without waiting for the next round of polling. SNMP traps apply to critical events.

Enable SNMP in the module Jump to heading

Perform these steps on all HAProxy Enterprise servers in the cluster to enable the VRRP module’s SNMP metrics:

  1. On the HAProxy Enterprise server, install the SNMP agent software, which returns metrics when queried by the network monitoring software. We’ll also install the SNMP client utilities, which provides tools like snmpusm for creating SNMPv3 user accounts, and snmpwalk for making ad hoc queries.

    nix
    sudo apt update
    sudo apt install snmpd snmp
    nix
    sudo apt update
    sudo apt install snmpd snmp
    nix
    sudo yum install net-snmp net-snmp-utils
    nix
    sudo yum install net-snmp net-snmp-utils
  2. Create the snmp group.

    nix
    sudo groupadd -r snmp
    nix
    sudo groupadd -r snmp
  3. Edit the SNMP agent’s configuration file, /etc/snmp/snmpd.conf.

    • Enable the AgentX protocol, which allows the agent to be extended with new management objects, in this case for VRRP. Add these lines if they’re missing:

      snmpd.conf
      text
      master agentx
      agentXSocket /var/agentx/master
      agentXPerms 0660 0550 nobody snmp
      snmpd.conf
      text
      master agentx
      agentXSocket /var/agentx/master
      agentXPerms 0660 0550 nobody snmp
    • If there’s an agentaddress line that’s set to 127.0.0.1,[::1], comment it out by prefixing it with a hash sign. This changes the agent to listen for traffic on all IP addresses, not just the loopback address.

      snmpd.conf
      text
      # agentaddress 127.0.0.1,[::1]
      snmpd.conf
      text
      # agentaddress 127.0.0.1,[::1]
    • Configure SNMPv3 access. Add the following createUser and rwuser lines to the end of the file to create an initial user account with read-write access. Note that this applies to SNMPv3 only, since older versions of the protocol don’t require user accounts and instead use a community string for authentication. This initial user account will become the template from which we will create other user accounts.

      snmpd.conf
      text
      createUser initial SHA setup_passphrase AES setup_passphrase
      rwuser initial
      snmpd.conf
      text
      createUser initial SHA setup_passphrase AES setup_passphrase
      rwuser initial
    • Add another rwuser line to prepare a second user account with read-write access. Below, we define permissions for a user named myuser:

      snmpd.conf
      text
      rwuser myuser
      snmpd.conf
      text
      rwuser myuser

    Save and exit the file.

  4. Start the SNMP agent service:

    nix
    sudo systemctl start snmpd
    nix
    sudo systemctl start snmpd
  5. Using the initial user’s username and passphrase, create a new user account that you’ll use to make SNMP requests. This user will inherit settings from the initial user account. Below, we create a user named myuser:

    nix
    snmpusm -v3 -n "" -u initial -a SHA -A setup_passphrase -x AES -X setup_passphrase -l authPriv 127.0.0.1 create myuser initial
    nix
    snmpusm -v3 -n "" -u initial -a SHA -A setup_passphrase -x AES -X setup_passphrase -l authPriv 127.0.0.1 create myuser initial
    output
    text
    User successfully created.
    output
    text
    User successfully created.
  6. The new user account inherited the passphrase from the initial user account. Use the snmpusm command again to change the user’s passphrase. Below, we change the myuser user account’s passphrase to mypassword. In a production environment, be sure to use a strong password.

    nix
    snmpusm -v3 -n "" -u myuser -a SHA -A setup_passphrase -x AES -X setup_passphrase -l authPriv 127.0.0.1 passwd setup_passphrase mypassword
    nix
    snmpusm -v3 -n "" -u myuser -a SHA -A setup_passphrase -x AES -X setup_passphrase -l authPriv 127.0.0.1 passwd setup_passphrase mypassword
    output
    text
    SNMPv3 Key(s) successfully changed.
    output
    text
    SNMPv3 Key(s) successfully changed.
  7. Edit the VRRP module’s configuration file, /etc/hapee-extras/hapee-vrrp.cfg. Add this global_defs section to the top of the file to enable SNMP metrics.

    hapee-vrrp.cfg
    text
    global_defs {
    enable_snmp_rfcv3 # enable SNMP handling of RFC6527 VRRP MIB
    enable_snmp_vrrp # enable SNMP handling of vrrp element of KEEPALIVED MIB
    enable_traps # enable SNMP traps
    }
    hapee-vrrp.cfg
    text
    global_defs {
    enable_snmp_rfcv3 # enable SNMP handling of RFC6527 VRRP MIB
    enable_snmp_vrrp # enable SNMP handling of vrrp element of KEEPALIVED MIB
    enable_traps # enable SNMP traps
    }
  8. Restart the hapee-extras-vrrp service:

    nix
    sudo systemctl restart hapee-extras-vrrp
    nix
    sudo systemctl restart hapee-extras-vrrp
  9. Check the status of the service. It should show Sending SNMP notification.

    nix
    sudo systemctl status hapee-extras-vrrp
    nix
    sudo systemctl status hapee-extras-vrrp
    output
    text
    Sep 29 18:44:29 lb1 Keepalived_vrrp[15927]: (vrrp_1) Sending SNMP notification
    output
    text
    Sep 29 18:44:29 lb1 Keepalived_vrrp[15927]: (vrrp_1) Sending SNMP notification

Get metrics Jump to heading

To verify that you’ve set up the VRRP module for SNMP, we’ll install SNMP tools on a remote host and fetch metrics.

On the remote host:

  1. Install the SNMP client utilities, which provides tools like snmpwalk for making ad hoc queries.

    nix
    sudo apt update
    sudo apt install snmp
    nix
    sudo apt update
    sudo apt install snmp
    nix
    sudo yum install net-snmp-utils
    nix
    sudo yum install net-snmp-utils
  2. On Debian and Ubuntu only, perform these steps:

    • Configure the management software to load Management Information Bases (MIBs) by editing the file /etc/snmp/snmp.conf and commenting out the mibs line so that it looks like this:

      snmp.conf
      text
      # mibs :
      snmp.conf
      text
      # mibs :
    • Locate the mibdirs line. If it is commented out, uncomment it.

      snmp.conf
      text
      mibdirs /usr/share/snmp/mibs:/usr/share/snmp/mibs/iana:/usr/share/snmp/mibs/ietf
      snmp.conf
      text
      mibdirs /usr/share/snmp/mibs:/usr/share/snmp/mibs/iana:/usr/share/snmp/mibs/ietf
    • To install snmp-mibs-downloader, you need the non-free repository. Open /etc/apt/sources.list. If all content has been commented out and it says sources have been moved to /etc/apt/sources.list.d/ubuntu.sources, you don’t need to change apt source declarations. On the other hand, if the sources.list file contains an uncommented source declaration, append the non-free repository to the declaration:

      sources.list
      text
      deb https://deb.debian.org/debian bookworm main non-free
      sources.list
      text
      deb https://deb.debian.org/debian bookworm main non-free
    • Add the MIB files by installing the snmp-mibs-downloader package:

      nix
      sudo apt update
      sudo apt install snmp-mibs-downloader
      nix
      sudo apt update
      sudo apt install snmp-mibs-downloader
  3. To verify that the user you created can make requests to the agent software, you can use the management software’s snmpget command to fetch some metrics. Try the following, but replace <LB-IP-ADDRESS> with your load balancer’s IP address.

    nix
    snmpget -v3 -n "" -u myuser -a SHA -A mypassword -x AES -X mypassword -l authPriv <LB-IP-ADDRESS> sysUpTime.0
    nix
    snmpget -v3 -n "" -u myuser -a SHA -A mypassword -x AES -X mypassword -l authPriv <LB-IP-ADDRESS> sysUpTime.0
    output
    text
    DISMAN-EVENT-MIB::sysUpTimeInstance = Timeticks: (34926) 0:05:49.26
    output
    text
    DISMAN-EVENT-MIB::sysUpTimeInstance = Timeticks: (34926) 0:05:49.26
  4. Install the Keepalived MIB file by downloading it to the mibs directory. A MIB (management information base) allows SNMP to return readable names instead of long strings of numbers (OIDs).

    nix
    sudo curl https://raw.githubusercontent.com/acassen/keepalived/refs/heads/master/doc/KEEPALIVED-MIB.txt -o /usr/share/snmp/mibs/KEEPALIVED-MIB.txt
    nix
    sudo curl https://raw.githubusercontent.com/acassen/keepalived/refs/heads/master/doc/KEEPALIVED-MIB.txt -o /usr/share/snmp/mibs/KEEPALIVED-MIB.txt
  5. Use the snmpwalk command to fetch metrics for the vrrp object.

    In these examples, replace <LB-IP-ADDRESS> with your load balancer’s IP address.

    nix
    snmpwalk -v3 -u myuser -a SHA -A mypassword -x AES -X mypassword -l authPriv <LB-IP-ADDRESS> KEEPALIVED-MIB::vrrp
    nix
    snmpwalk -v3 -u myuser -a SHA -A mypassword -x AES -X mypassword -l authPriv <LB-IP-ADDRESS> KEEPALIVED-MIB::vrrp
    output
    text
    KEEPALIVED-MIB::vrrpInstanceName.1 = STRING: vrrp_1
    KEEPALIVED-MIB::vrrpInstanceVirtualRouterId.1 = Gauge32: 51
    KEEPALIVED-MIB::vrrpInstanceState.1 = INTEGER: master(2)
    KEEPALIVED-MIB::vrrpInstanceInitialState.1 = INTEGER: master(2)
    KEEPALIVED-MIB::vrrpInstanceWantedState.1 = INTEGER: master(2)
    KEEPALIVED-MIB::vrrpInstanceBasePriority.1 = INTEGER: 101
    KEEPALIVED-MIB::vrrpInstanceEffectivePriority.1 = INTEGER: 107
    KEEPALIVED-MIB::vrrpInstanceVipsStatus.1 = INTEGER: allSet(1)
    KEEPALIVED-MIB::vrrpInstancePrimaryInterface.1 = STRING: eth1
    KEEPALIVED-MIB::vrrpInstanceTrackPrimaryIf.1 = INTEGER: notTracked(2)
    KEEPALIVED-MIB::vrrpInstanceAdvertisementsInt.1 = Gauge32: 1 seconds(VRRPv2) / centiseconds(VRRPv3)
    KEEPALIVED-MIB::vrrpInstancePreempt.1 = INTEGER: preempt(1)
    KEEPALIVED-MIB::vrrpInstancePreemptDelay.1 = Gauge32: 0 seconds
    KEEPALIVED-MIB::vrrpInstanceAuthType.1 = INTEGER: password(1)
    KEEPALIVED-MIB::vrrpInstanceGarpDelay.1 = Gauge32: 5 seconds
    KEEPALIVED-MIB::vrrpInstanceSmtpAlert.1 = INTEGER: disabled(2)
    KEEPALIVED-MIB::vrrpInstanceNotifyExec.1 = INTEGER: disabled(2)
    KEEPALIVED-MIB::vrrpInstanceAccept.1 = INTEGER: 0
    KEEPALIVED-MIB::vrrpInstancePromoteSecondaries.1 = INTEGER: false(2)
    KEEPALIVED-MIB::vrrpInstanceUseLinkbeat.1 = INTEGER: false(2)
    KEEPALIVED-MIB::vrrpInstanceVrrpVersion.1 = INTEGER: vrrpv2(2)
    KEEPALIVED-MIB::vrrpInstanceNotifyDeleted.1 = INTEGER: false(2)
    KEEPALIVED-MIB::vrrpInstanceMulticastAddressType.1 = INTEGER: ipv4(1)
    KEEPALIVED-MIB::vrrpInstanceMulticastAddress.1 = Hex-STRING: E0 00 00 12
    KEEPALIVED-MIB::vrrpTrackedScriptName.1.1 = STRING: chk_sshd
    KEEPALIVED-MIB::vrrpTrackedScriptName.1.2 = STRING: chk_lb
    KEEPALIVED-MIB::vrrpTrackedScriptWeight.1.1 = INTEGER: -4
    KEEPALIVED-MIB::vrrpTrackedScriptWeight.1.2 = INTEGER: 6
    KEEPALIVED-MIB::vrrpTrackedScriptWgtRev.1.1 = INTEGER: false(2)
    KEEPALIVED-MIB::vrrpTrackedScriptWgtRev.1.2 = INTEGER: false(2)
    KEEPALIVED-MIB::vrrpAddressType.1.1 = INTEGER: ipv4(1)
    KEEPALIVED-MIB::vrrpAddressValue.1.1 = Hex-STRING: C0 A8 38 1E
    KEEPALIVED-MIB::vrrpAddressBroadcast.1.1 = Hex-STRING: 00 00 00 00
    KEEPALIVED-MIB::vrrpAddressMask.1.1 = Gauge32: 32
    KEEPALIVED-MIB::vrrpAddressScope.1.1 = INTEGER: global(14)
    KEEPALIVED-MIB::vrrpAddressIfIndex.1.1 = INTEGER: 3
    KEEPALIVED-MIB::vrrpAddressIfName.1.1 = STRING: eth1
    KEEPALIVED-MIB::vrrpAddressStatus.1.1 = INTEGER: set(1)
    KEEPALIVED-MIB::vrrpAddressAdvertising.1.1 = INTEGER: notAdvertised(2)
    KEEPALIVED-MIB::vrrpScriptName.1 = STRING: chk_sshd
    KEEPALIVED-MIB::vrrpScriptName.2 = STRING: chk_lb
    KEEPALIVED-MIB::vrrpScriptCommand.1 = STRING: '/usr/bin/pkill' '-0' 'sshd'
    KEEPALIVED-MIB::vrrpScriptCommand.2 = STRING: '/usr/bin/pkill' '-0' 'hapee-lb'
    KEEPALIVED-MIB::vrrpScriptInterval.1 = INTEGER: 5 seconds
    KEEPALIVED-MIB::vrrpScriptInterval.2 = INTEGER: 1 seconds
    KEEPALIVED-MIB::vrrpScriptWeight.1 = INTEGER: -4
    KEEPALIVED-MIB::vrrpScriptWeight.2 = INTEGER: 6
    KEEPALIVED-MIB::vrrpScriptResult.1 = INTEGER: good(3)
    KEEPALIVED-MIB::vrrpScriptResult.2 = INTEGER: good(3)
    KEEPALIVED-MIB::vrrpScriptRise.1 = Gauge32: 1
    KEEPALIVED-MIB::vrrpScriptRise.2 = Gauge32: 1
    KEEPALIVED-MIB::vrrpScriptFall.1 = Gauge32: 2
    KEEPALIVED-MIB::vrrpScriptFall.2 = Gauge32: 2
    KEEPALIVED-MIB::vrrpScriptWgtRev.1 = INTEGER: false(2)
    KEEPALIVED-MIB::vrrpScriptWgtRev.2 = INTEGER: false(2)
    output
    text
    KEEPALIVED-MIB::vrrpInstanceName.1 = STRING: vrrp_1
    KEEPALIVED-MIB::vrrpInstanceVirtualRouterId.1 = Gauge32: 51
    KEEPALIVED-MIB::vrrpInstanceState.1 = INTEGER: master(2)
    KEEPALIVED-MIB::vrrpInstanceInitialState.1 = INTEGER: master(2)
    KEEPALIVED-MIB::vrrpInstanceWantedState.1 = INTEGER: master(2)
    KEEPALIVED-MIB::vrrpInstanceBasePriority.1 = INTEGER: 101
    KEEPALIVED-MIB::vrrpInstanceEffectivePriority.1 = INTEGER: 107
    KEEPALIVED-MIB::vrrpInstanceVipsStatus.1 = INTEGER: allSet(1)
    KEEPALIVED-MIB::vrrpInstancePrimaryInterface.1 = STRING: eth1
    KEEPALIVED-MIB::vrrpInstanceTrackPrimaryIf.1 = INTEGER: notTracked(2)
    KEEPALIVED-MIB::vrrpInstanceAdvertisementsInt.1 = Gauge32: 1 seconds(VRRPv2) / centiseconds(VRRPv3)
    KEEPALIVED-MIB::vrrpInstancePreempt.1 = INTEGER: preempt(1)
    KEEPALIVED-MIB::vrrpInstancePreemptDelay.1 = Gauge32: 0 seconds
    KEEPALIVED-MIB::vrrpInstanceAuthType.1 = INTEGER: password(1)
    KEEPALIVED-MIB::vrrpInstanceGarpDelay.1 = Gauge32: 5 seconds
    KEEPALIVED-MIB::vrrpInstanceSmtpAlert.1 = INTEGER: disabled(2)
    KEEPALIVED-MIB::vrrpInstanceNotifyExec.1 = INTEGER: disabled(2)
    KEEPALIVED-MIB::vrrpInstanceAccept.1 = INTEGER: 0
    KEEPALIVED-MIB::vrrpInstancePromoteSecondaries.1 = INTEGER: false(2)
    KEEPALIVED-MIB::vrrpInstanceUseLinkbeat.1 = INTEGER: false(2)
    KEEPALIVED-MIB::vrrpInstanceVrrpVersion.1 = INTEGER: vrrpv2(2)
    KEEPALIVED-MIB::vrrpInstanceNotifyDeleted.1 = INTEGER: false(2)
    KEEPALIVED-MIB::vrrpInstanceMulticastAddressType.1 = INTEGER: ipv4(1)
    KEEPALIVED-MIB::vrrpInstanceMulticastAddress.1 = Hex-STRING: E0 00 00 12
    KEEPALIVED-MIB::vrrpTrackedScriptName.1.1 = STRING: chk_sshd
    KEEPALIVED-MIB::vrrpTrackedScriptName.1.2 = STRING: chk_lb
    KEEPALIVED-MIB::vrrpTrackedScriptWeight.1.1 = INTEGER: -4
    KEEPALIVED-MIB::vrrpTrackedScriptWeight.1.2 = INTEGER: 6
    KEEPALIVED-MIB::vrrpTrackedScriptWgtRev.1.1 = INTEGER: false(2)
    KEEPALIVED-MIB::vrrpTrackedScriptWgtRev.1.2 = INTEGER: false(2)
    KEEPALIVED-MIB::vrrpAddressType.1.1 = INTEGER: ipv4(1)
    KEEPALIVED-MIB::vrrpAddressValue.1.1 = Hex-STRING: C0 A8 38 1E
    KEEPALIVED-MIB::vrrpAddressBroadcast.1.1 = Hex-STRING: 00 00 00 00
    KEEPALIVED-MIB::vrrpAddressMask.1.1 = Gauge32: 32
    KEEPALIVED-MIB::vrrpAddressScope.1.1 = INTEGER: global(14)
    KEEPALIVED-MIB::vrrpAddressIfIndex.1.1 = INTEGER: 3
    KEEPALIVED-MIB::vrrpAddressIfName.1.1 = STRING: eth1
    KEEPALIVED-MIB::vrrpAddressStatus.1.1 = INTEGER: set(1)
    KEEPALIVED-MIB::vrrpAddressAdvertising.1.1 = INTEGER: notAdvertised(2)
    KEEPALIVED-MIB::vrrpScriptName.1 = STRING: chk_sshd
    KEEPALIVED-MIB::vrrpScriptName.2 = STRING: chk_lb
    KEEPALIVED-MIB::vrrpScriptCommand.1 = STRING: '/usr/bin/pkill' '-0' 'sshd'
    KEEPALIVED-MIB::vrrpScriptCommand.2 = STRING: '/usr/bin/pkill' '-0' 'hapee-lb'
    KEEPALIVED-MIB::vrrpScriptInterval.1 = INTEGER: 5 seconds
    KEEPALIVED-MIB::vrrpScriptInterval.2 = INTEGER: 1 seconds
    KEEPALIVED-MIB::vrrpScriptWeight.1 = INTEGER: -4
    KEEPALIVED-MIB::vrrpScriptWeight.2 = INTEGER: 6
    KEEPALIVED-MIB::vrrpScriptResult.1 = INTEGER: good(3)
    KEEPALIVED-MIB::vrrpScriptResult.2 = INTEGER: good(3)
    KEEPALIVED-MIB::vrrpScriptRise.1 = Gauge32: 1
    KEEPALIVED-MIB::vrrpScriptRise.2 = Gauge32: 1
    KEEPALIVED-MIB::vrrpScriptFall.1 = Gauge32: 2
    KEEPALIVED-MIB::vrrpScriptFall.2 = Gauge32: 2
    KEEPALIVED-MIB::vrrpScriptWgtRev.1 = INTEGER: false(2)
    KEEPALIVED-MIB::vrrpScriptWgtRev.2 = INTEGER: false(2)
  6. Configure your SNMP monitoring software to collect metrics from the HAProxy Enterprise server by using the SNMPv3 protocol with the username and passphrase you set.

Receive trap messages Jump to heading

After you’ve configured the remote server to get metrics, you can prepare it to receive SNMP trap messages:

  1. On the HAProxy Enterprise server, edit the SNMP agent’s configuration file, /etc/snmp/snmpd.conf, and add a trapsess directive that sets the IP address of the remote server where you’ll send trap messages. Replace <REMOTE-IP> with the IP address of the server that receives trap messages.

    snmpd.conf
    text
    trapsess -v3 -l authPriv -u myuser -a SHA -A mypassword -x AES -X mypassword <REMOTE-IP>
    snmpd.conf
    text
    trapsess -v3 -l authPriv -u myuser -a SHA -A mypassword -x AES -X mypassword <REMOTE-IP>
  2. Restart the SNMP agent service:

    nix
    sudo systemctl restart snmpd
    nix
    sudo systemctl restart snmpd
  3. On the remote host, install the snmptrapd package to get the snmptrapd application, which receives and logs SNMP trap messages.

    nix
    sudo apt update
    sudo apt install snmptrapd
    nix
    sudo apt update
    sudo apt install snmptrapd
    nix
    sudo yum install net-snmp net-snmp-utils
    nix
    sudo yum install net-snmp net-snmp-utils
  4. Edit the snmptrapd systemd unit file.

    nix
    sudo systemctl edit snmptrapd
    nix
    sudo systemctl edit snmptrapd

    Add -m ALL to the ExecStart line to load all MIB files.

    snmptrapd.service
    ini
    [Unit]
    Description=Simple Network Management Protocol (SNMP) Trap Daemon.
    [Service]
    Type=notify
    User=Debian-snmp
    ExecStart=/usr/sbin/snmptrapd -LOw -f udp:162 udp6:162 -m ALL
    ExecReload=/bin/kill -HUP $MAINPID
    snmptrapd.service
    ini
    [Unit]
    Description=Simple Network Management Protocol (SNMP) Trap Daemon.
    [Service]
    Type=notify
    User=Debian-snmp
    ExecStart=/usr/sbin/snmptrapd -LOw -f udp:162 udp6:162 -m ALL
    ExecReload=/bin/kill -HUP $MAINPID

    Save and exit.

  5. Reload the systemd daemon.

    nix
    sudo systemctl daemon-reload
    nix
    sudo systemctl daemon-reload
  6. Create a custom script to handle notifications when they arrive. For example, the script below writes the notification messages to a file:

    logtrap.sh
    #!/bin/bash STDIN=$(cat) FILE=/tmp/trap-messages.txt TIMESTAMP=$(date +"%Y-%m-%d %T") echo "Time: $TIMESTAMP" >> $FILE echo $STDIN >> $FILE
    logtrap.sh
    #!/bin/bash STDIN=$(cat) FILE=/tmp/trap-messages.txt TIMESTAMP=$(date +"%Y-%m-%d %T") echo "Time: $TIMESTAMP" >> $FILE echo $STDIN >> $FILE
  7. Save this as /usr/local/bin/logtrap.sh and make it executable:

    nix
    sudo cp logtrap.sh /usr/local/bin/
    sudo chmod +x /usr/local/bin/logtrap.sh
    nix
    sudo cp logtrap.sh /usr/local/bin/
    sudo chmod +x /usr/local/bin/logtrap.sh
  8. For each HAProxy Enterprise server, use the snmpget command to get the SNMP EngineID, which returns a hex string that’s unique to that server. Replace <REMOTE-IP>.

    nix
    snmpget -v3 -n "" -u myuser -a SHA -A mypassword -x AES -X mypassword -l authPriv <REMOTE-IP> SNMP-FRAMEWORK-MIB::snmpEngineID.0
    nix
    snmpget -v3 -n "" -u myuser -a SHA -A mypassword -x AES -X mypassword -l authPriv <REMOTE-IP> SNMP-FRAMEWORK-MIB::snmpEngineID.0

    The EngineID is 0x80001F88802790C035B925BC6A00000000. Note that the output can wrap onto a new line, as in this example.

    output
    text
    SNMP-FRAMEWORK-MIB::snmpEngineID.0 = Hex-STRING: 80 00 1F 88 80 27 90 C0 35 B9 25 BC 6A 00 00 00
    00
    output
    text
    SNMP-FRAMEWORK-MIB::snmpEngineID.0 = Hex-STRING: 80 00 1F 88 80 27 90 C0 35 B9 25 BC 6A 00 00 00
    00

    Do this for both HAProxy Enterprise servers, since each has a unique EngineID.

  9. Edit /etc/snmp/snmptrapd.conf.

    • Add createUser and authuser directives to set SNMPv3 user credentials for authenticating to the HAProxy Enterprise’s VRRP module.

      snmptrapd.conf
      text
      # SNMPv3 User Configuration
      # Load balancer 1
      createUser -e 0x80001F88802790C035B925BC6A00000000 myuser SHA mypassword AES mypassword
      # Load balancer 2
      createUser -e 0x80001F8880EA93A91E0E5EBC6A00000000 myuser SHA mypassword AES mypassword
      authuser log,execute myuser
      snmptrapd.conf
      text
      # SNMPv3 User Configuration
      # Load balancer 1
      createUser -e 0x80001F88802790C035B925BC6A00000000 myuser SHA mypassword AES mypassword
      # Load balancer 2
      createUser -e 0x80001F8880EA93A91E0E5EBC6A00000000 myuser SHA mypassword AES mypassword
      authuser log,execute myuser
    • Add a traphandle directive to use the example script. The default argument treats this handler as the default to execute when no other traphandle has precedence.

      snmptrapd.conf
      text
      traphandle default /usr/local/bin/logtrap.sh
      snmptrapd.conf
      text
      traphandle default /usr/local/bin/logtrap.sh

    Save and exit the file.

  10. Enable and start the service:

    nix
    sudo systemctl enable snmptrapd
    sudo systemctl start snmptrapd
    nix
    sudo systemctl enable snmptrapd
    sudo systemctl start snmptrapd

    Check the /tmp/trap-messages.txt log file for new messages. You can trigger messages by triggering a manual failover on the master VRRP instance and then restarting the hapee-extras-vrrp service.

    In this example, a failover caused the vrrpInstanceState value on each load balancer to change. One became master and the other became backup.

    trap-messages.txt
    text
    Time: 2026-09-30 15:06:23
    <UNKNOWN> UDP: [192.168.56.25]:60157->[192.168.56.26]:162 DISMAN-EXPRESSION-MIB::sysUpTimeInstance 0:1:58:31.52 SNMPv2-MIB::snmpTrapOID.0 KEEPALIVED-MIB::vrrpInstanceStateChange KEEPALIVED-MIB::vrrpInstanceName vrrp_1 KEEPALIVED-MIB::vrrpInstanceState shutdown KEEPALIVED-MIB::vrrpInstanceInitialState master KEEPALIVED-MIB::routerId.0 lb1
    Time: 2026-09-30 15:06:24
    <UNKNOWN> UDP: [192.168.56.27]:43088->[192.168.56.26]:162 DISMAN-EXPRESSION-MIB::sysUpTimeInstance 0:1:58:12.59 SNMPv2-MIB::snmpTrapOID.0 KEEPALIVED-MIB::vrrpInstanceStateChange KEEPALIVED-MIB::vrrpInstanceName vrrp_1 KEEPALIVED-MIB::vrrpInstanceState master KEEPALIVED-MIB::vrrpInstanceInitialState backup KEEPALIVED-MIB::routerId.0 lb2
    Time: 2026-09-30 15:06:25
    <UNKNOWN> UDP: [192.168.56.25]:60157->[192.168.56.26]:162 DISMAN-EXPRESSION-MIB::sysUpTimeInstance 0:1:58:32.68 SNMPv2-MIB::snmpTrapOID.0 KEEPALIVED-MIB::vrrpInstanceStateChange KEEPALIVED-MIB::vrrpInstanceName vrrp_1 KEEPALIVED-MIB::vrrpInstanceState backup KEEPALIVED-MIB::vrrpInstanceInitialState master KEEPALIVED-MIB::routerId.0 lb1
    trap-messages.txt
    text
    Time: 2026-09-30 15:06:23
    <UNKNOWN> UDP: [192.168.56.25]:60157->[192.168.56.26]:162 DISMAN-EXPRESSION-MIB::sysUpTimeInstance 0:1:58:31.52 SNMPv2-MIB::snmpTrapOID.0 KEEPALIVED-MIB::vrrpInstanceStateChange KEEPALIVED-MIB::vrrpInstanceName vrrp_1 KEEPALIVED-MIB::vrrpInstanceState shutdown KEEPALIVED-MIB::vrrpInstanceInitialState master KEEPALIVED-MIB::routerId.0 lb1
    Time: 2026-09-30 15:06:24
    <UNKNOWN> UDP: [192.168.56.27]:43088->[192.168.56.26]:162 DISMAN-EXPRESSION-MIB::sysUpTimeInstance 0:1:58:12.59 SNMPv2-MIB::snmpTrapOID.0 KEEPALIVED-MIB::vrrpInstanceStateChange KEEPALIVED-MIB::vrrpInstanceName vrrp_1 KEEPALIVED-MIB::vrrpInstanceState master KEEPALIVED-MIB::vrrpInstanceInitialState backup KEEPALIVED-MIB::routerId.0 lb2
    Time: 2026-09-30 15:06:25
    <UNKNOWN> UDP: [192.168.56.25]:60157->[192.168.56.26]:162 DISMAN-EXPRESSION-MIB::sysUpTimeInstance 0:1:58:32.68 SNMPv2-MIB::snmpTrapOID.0 KEEPALIVED-MIB::vrrpInstanceStateChange KEEPALIVED-MIB::vrrpInstanceName vrrp_1 KEEPALIVED-MIB::vrrpInstanceState backup KEEPALIVED-MIB::vrrpInstanceInitialState master KEEPALIVED-MIB::routerId.0 lb1

VRRP instance reference Jump to heading

The following fields define a vrrp_instance block:

Name Argument type Description
vrrp_instance string Describes a new VRRP instance.
interface string Interface managed by the VRRP module.
state string State at startup until VRRP priority negotiation completes. Can be either MASTER or BACKUP.
virtual_router_id integer VRRP instance identifier, which must be common to all nodes of the same cluster. Each cluster must have a unique ID. The value can range from 1 to 255.
priority integer Weight of local node in this VRRP instance. NOTE This won’t work on cloud provider networks that disable IP multicast.
virtual_ipaddress string List of virtual IP addresses to add when the state changes to MASTER or remove when it changes to BACKUP. All VRRP nodes in a cluster must own the same IP. NOTE This won’t work on cloud provider networks that disable IP multicast.
virtual_ipaddress_excluded string The same as virtual_ipaddress, but IPs aren’t announced in the VRRP heartbeat packet, which reduces bandwidth usage when sending packets.
track_interface string Tracks interface status and updates priority accordingly.
track_script string Runs the health check scripts and updates priority accordingly.

VRRP Troubleshooting Jump to heading

Does a packet capture reveal that packets are reaching the server, but the VRRP service doesn’t receive them?

  • Check if there is a firewall running that may be blocking the packets. See Prerequisites.

Are you using Cisco ACI and experiencing traffic routing back to the failed node after a failover?

  • Disable the IP Data-plane Learning option under the VRF and enable GARP-based IP move detection mode. See Prerequisites.

You aren’t receiving trap messages

  • Stop the snmptrapd.service and snmptrapd.socket services and run snmptrapd interactively to debug.

    nix
    sudo systemctl stop snmptrapd
    sudo systemctl stop snmptrapd.socket
    sudo snmptrapd -f -Le -c /etc/snmp/snmptrapd.conf -Dread_config,usm
    nix
    sudo systemctl stop snmptrapd
    sudo systemctl stop snmptrapd.socket
    sudo snmptrapd -f -Le -c /etc/snmp/snmptrapd.conf -Dread_config,usm

See also Jump to heading

The VRRP module is a wrapper around the Keepalived software. The syntax we use is different, but you may still find the Keepalived documentation useful.

Do you have any suggestions on how we can improve the content of this page? Please leave feedback!