Skip to main content

Tutorial: Manage Failover Settings Using the Access Server CLI

Abstract

Configure and manage failover settings in OpenVPN Access Server using the Web API or sacli CLI tools. Learn how to configure, initialize, and test failover nodes for high availability.

Overview

This tutorial shows how to configure and manage failover settings in OpenVPN Access Server using either the Web API or the sacli command-line tool.

Access Server supports failover deployments for high availability within a local area network (LAN). In a failover deployment:

  • The primary node handles active traffic.

  • The secondary node remains in standby mode.

If the primary node becomes unavailable, the secondary node automatically takes over.

This tutorial explains how to:

  1. Validate the failover configuration.

  2. Configure failover settings.

  3. Initialize the secondary node.

  4. Verify failover state changes.

  5. Test failover behavior.

To learn more about failover deployments, refer to the Failover Setup Guide.

Prerequisites

  • Access Server 3.1.0 or newer (required for Step 1 / Web API method)

  • Root access to both Access Server nodes.

  • A completed failover deployment setup.

    Important

    Before following this tutorial, complete Steps 1-6 in Tutorial: How To Set Up Failover Mode.

  • (Optional) A remote system for API calls.

Choose a configuration method

This tutorial provides two ways to configure failover settings:

Method

Availability

Best for

Web API (apicall)

Access Server 3.1.0 and newer

Automation and API workflows

sacli commands

All supported Access Server versions

Direct server administration

Use the method that best fits your environment and workflow.

Important

The failover API specification may change between Access Server releases. Always verify the API documentation for your current version. Refer to: View the API specification.

Placeholder values used in this tutorial

Replace the following placeholders with values for your environment:

Placeholder

Description

<FAILOVER_IP>

Shared virtual failover IP address

<UCARP_PASSWORD>

UCARP shared secret password

<PRIMARY_IP>

IP address of the primary node

<SECONDARY_IP>

IP address of the secondary node

Tip

The UCARP secret can be any secure string. Access Server typically generates a random 16-character value containing uppercase letters, lowercase letters, and numbers.

Note

This method requires Access Server 3.1.0 or newer.

Important

This tutorial uses sacli apicall, but you can also use cURL or Swagger UI. Refer to Tutorial: Test the New Web API (OpenAPI) in Access Server 3.0.

Configure failover settings

  1. Connect to the primary node and get root privileges.

    Note

    All commands in this section run on the primary node.

  2. Test the failover configuration:

    sacli --method POST --url 'api/server/failover-test' --value '{"failover.mode":"ucarp","ucarp.addr":"<FAILOVER_IP>","ucarp.secret":"<UCARP_PASSWORD>","dbpush.hosts.0.enable":true,"dbpush.hosts.0.public":"<PRIMARY_IP>","dbpush.hosts.0.internal":"PRIMARY","dbpush.hosts.0.username":"root","dbpush.hosts.0.password":"","dbpush.hosts.0.ssh_port":22,"dbpush.hosts.1.enable":true,"dbpush.hosts.1.public":"<SECONDARY_IP>","dbpush.hosts.1.internal":"SECONDARY","dbpush.hosts.1.username":"root","dbpush.hosts.1.password":"","dbpush.hosts.1.ssh_port":22}' apicall
    • Example output:

      {"ucarp":{"status":true,"message":"UCARP_ADDR_GOOD: ucarp address <FAILOVER_IP> is reachable from locally connected interface on both primary and secondary nodes","friendly":"Shared virtual IP address is directly accessible via locally connected interface on both primary and secondary nodes."},"license_primary":{"status":true,"message":"GOOD_LICENSE: Licensed for 2 concurrent connections.","friendly":"Licensed for 2 concurrent connections."},"license_secondary":{"status":true,"message":"GOOD_LICENSE: Licensed for 2 concurrent connections.","friendly":"Licensed for 2 concurrent connections."},"connectivity":{"status":true,"message":"SUCCEED: failover connectivity test succeeded","friendly":"Connectivity test between primary and secondary nodes succeeded."}}
  3. Save the failover directives/keys into the database:

    sacli --method POST --url 'api/config-items/Default' --value '{"failover.mode":"ucarp","ucarp.addr":"<FAILOVER_IP>","ucarp.secret":"<UCARP_PASSWORD>","dbpush.hosts.0.enable":true,"dbpush.hosts.0.public":"<PRIMARY_IP>","dbpush.hosts.0.internal":"PRIMARY","dbpush.hosts.0.username":"root","dbpush.hosts.0.password":"","dbpush.hosts.0.ssh_port":22,"dbpush.hosts.1.enable":true,"dbpush.hosts.1.public":"<SECONDARY_IP>","dbpush.hosts.1.internal":"SECONDARY","dbpush.hosts.1.username":"root","dbpush.hosts.1.password":"","dbpush.hosts.1.ssh_port":22}' apicall
    • Example output:

      null
  4. Initiate the secondary node (BACKUP):

    sacli --method POST --url 'api/server/failover-init' --value '{"new_config":{"failover.mode":"ucarp","ucarp.addr":"<FAILOVER_IP>","ucarp.secret":"<UCARP_PASSWORD>","dbpush.hosts.0.enable":"true","dbpush.hosts.0.public":"<PRIMARY_IP>","dbpush.hosts.0.internal":"PRIMARY","dbpush.hosts.0.username":"root","dbpush.hosts.0.password":"","dbpush.hosts.0.ssh_port":"22","dbpush.hosts.1.enable":"true","dbpush.hosts.1.public":"<SECONDARY_IP>","dbpush.hosts.1.internal":"SECONDARY","dbpush.hosts.1.username":"root","dbpush.hosts.1.password":"","dbpush.hosts.1.ssh_port":"22"},"old_config":{"failover.mode":"ucarp","ucarp.addr":"<FAILOVER_IP>","ucarp.secret":"<UCARP_PASSWORD>","dbpush.hosts.0.enable":"true","dbpush.hosts.0.public":"<PRIMARY_IP>","dbpush.hosts.0.internal":"PRIMARY","dbpush.hosts.0.username":"root","dbpush.hosts.0.password":"","dbpush.hosts.0.ssh_port":"22","dbpush.hosts.1.enable":"true","dbpush.hosts.1.public":"<SECONDARY_IP>","dbpush.hosts.1.internal":"SECONDARY","dbpush.hosts.1.username":"root","dbpush.hosts.1.password":"","dbpush.hosts.1.ssh_port":"22"}}' apicall
    • Example output:

      {"reason":"Success"}
  5. Restart the primary node (MASTER):

    sacli --method POST --url 'api/server/restart?restartMode=systemctl' --value '' apicall
    • Example output:

      {}
  6. Verify node status:

    systemctl status openvpnas | grep "Switching to state:" | tail -n1
    • Example output of MASTER:

      [WARNING] Switching to state: MASTER
    • Example output of BACKUP:

      [WARNING] Switching to state: BACKUP

This method works on all supported Access Server versions.

Note

All commands in this section run on the primary node.

Create the failover configuration file

  1. Connect to the primary node and get root privileges.

  2. Create the configuration file:

    nano failover.json
  3. Add the following configuration:

    {
            "failover.mode": "ucarp",
            "ucarp.addr": "<FAILOVER_IP>",
            "ucarp.secret": "<UCARP_PASSWORD>",
            "dbpush.hosts.0.enable": "true",
            "dbpush.hosts.0.public": "<PRIMARY_IP>",
            "dbpush.hosts.0.internal": "PRIMARY",
            "dbpush.hosts.0.username": "root",
            "dbpush.hosts.0.password": "",
            "dbpush.hosts.0.ssh_port": "22",
            "dbpush.hosts.1.enable": "true",
            "dbpush.hosts.1.public": "<SECONDARY_IP>",
            "dbpush.hosts.1.internal": "SECONDARY",
            "dbpush.hosts.1.username": "root",
            "dbpush.hosts.1.password": "",
            "dbpush.hosts.1.ssh_port": "22"
    }
  4. Save and exit (Ctrl+x, y, Enter).

    Tip

    This example stores the file in /root/failover.json.

Test the failover configuration

  • Run:

    sacli --foconf /root/failover.json FailTest
    • Example output:

      {
        "connectivity": {
          "friendly": "Connectivity test between primary and secondary nodes succeeded.",
          "message": "SUCCEED: failover connectivity test succeeded",
          "status": true
        },
        "license_primary": {
          "friendly": "Licensed for 2 concurrent connections.",
          "message": "GOOD_LICENSE: Licensed for 2 concurrent connections.",
          "status": true
        },
        "license_secondary": {
          "friendly": "Licensed for 2 concurrent connections.",
          "message": "GOOD_LICENSE: Licensed for 2 concurrent connections.",
          "status": true
        },
        "ucarp": {
          "friendly": "Shared virtual IP address is directly accessible via locally connected interface on both primary and secondary nodes.",
          "message": "UCARP_ADDR_GOOD: ucarp address <FAILOVER_IP> is reachable from locally connected interface on both primary and secondary nodes",
          "status": true
        }
      }

Save failover settings

  • Save the failover directives/keys into the database:

    sacli --key "failover.mode" --value "ucarp" ConfigPut
    sacli --key "ucarp.addr" --value "<FAILOVER_IP>" ConfigPut
    sacli --key "ucarp.secret" --value "<UCARP_PASSWORD>" ConfigPut
    sacli --key "dbpush.hosts.0.enable" --value "true" ConfigPut
    sacli --key "dbpush.hosts.0.public" --value "<PRIMARY_IP>" ConfigPut
    sacli --key "dbpush.hosts.0.internal" --value "PRIMARY" ConfigPut
    sacli --key "dbpush.hosts.0.username" --value "root" ConfigPut
    sacli --key "dbpush.hosts.0.password" --value "" ConfigPut
    sacli --key "dbpush.hosts.0.ssh_port" --value "22" ConfigPut
    sacli --key "dbpush.hosts.1.enable" --value "true" ConfigPut
    sacli --key "dbpush.hosts.1.public" --value "<SECONDARY_IP>" ConfigPut
    sacli --key "dbpush.hosts.1.internal" --value "SECONDARY" ConfigPut
    sacli --key "dbpush.hosts.1.username" --value "root" ConfigPut
    sacli --key "dbpush.hosts.1.password" --value "" ConfigPut
    sacli --key "dbpush.hosts.1.ssh_port" --value "22" ConfigPut

Initialize the secondary node

  1. Restart Access Server:

    systemctl restart openvpnas
  2. Wait approximately 10 seconds.

  3. Create the db_push directory:

    ssh root@<SECONDARY_IP> "mkdir /usr/local/openvpn_as/etc/db_push/"
  4. Wait approximately 10 seconds.

  5. Initialize the secondary node:

    sacli --foconf=/root/failover.json --init_cmd=restart InitPeer
  6. Verify node state:

    systemctl status openvpnas | grep "Switching to state:" | tail -n1
    • Example output of MASTER:

      [WARNING] Switching to state: MASTER
    • Example output of BACKUP:

      [WARNING] Switching to state: BACKUP

Simulate failover

  1. Restart Access Server on the primary node:

    systemctl restart openvpnas
  2. Wait approximately 10 seconds.

  3. Verify node state changes:

    • Primary node should be BACKUP:

      [WARNING] Switching to state: BACKUP
    • Secondary node should be MASTER:

      [WARNING] Switching to state: MASTER
  4. Open the failover IP address in a web browser.

    • The Admin Web UI should now display the secondary node.

Restore the primary node

  1. Restart Access Server on the secondary node:

    systemctl restart openvpnas
  2. Wait approximately 10 seconds.

  3. Verify node state changes:

    • Primary node should be MASTER again:

      [WARNING] Switching to state: MASTER
    • Secondary node should be BACKUP again:

      [WARNING] Switching to state: BACKUP
  4. Open the failover IP address in a web browser.

    • The Admin Web UI should now display the primary node.

To monitor failover state changes, review:

/var/log/openvpnas.log
/var/log/openvpnas-node.log