FreeSWITCH High Availability Configuration Part 2 Keepalived - Omid-Mohajerani/freeswitch GitHub Wiki

OS: Debian 11 (bullseye)

FreeSWITCH installation method: debian packages

Node 1 IP : 10.10.10.151

Node 2 IP : 10.10.10.152

Virtual IP: 10.10.10.150

Keepalived installation

sudo apt-get update
sudo apt-get install linux-headers-$(uname -r)
sudo apt-get install keepalived

Keepalived Configuration

vim /etc/keepalived/keepalived.conf

Node1

global_defs {
   notification_email {
     [email protected]
     [email protected]
   }
   notification_email_from [email protected]
   smtp_server localhost
   smtp_connect_timeout 30
  # router_id 1
}

vrrp_script chk_fs {
    script "/usr/src/ka-status.pl"
    interval 10
}

vrrp_instance VI_1 {
    state MASTER
    interface ens18
    virtual_router_id 101
    priority 101
    advert_int 1
    authentication {
        auth_type PASS
        auth_pass 1111
    }

    notify "/usr/src/ka-notify.pl"
    virtual_ipaddress {
        10.10.10.150
    }
    track_script {
        chk_fs
    }
}
systemctl restart keepalived

Node 2

global_defs {
   notification_email {
     [email protected]
     [email protected]
   }

   notification_email_from [email protected]
   smtp_server localhost
   smtp_connect_timeout 30
#   router_id 1
}

vrrp_script chk_fs {
    script "/usr/src/ka-status.pl"
    interval 10
}


vrrp_instance VI_1 {
    state BACKUP
    interface ens18
    virtual_router_id 101
    priority 100
    advert_int 1
    authentication {
        auth_type PASS
        auth_pass 1111
    }

    notify "/usr/src/ka-notify.pl"
    virtual_ipaddress {
        10.10.10.150
    }
    track_script {
        chk_fs
    }

}
systemctl restart keepalived

Perl Scripts

vim /usr/src/freeswitch/ka-status.pl

#!/usr/bin/perl
 
use Sys::Syslog;
openlog "ka-status", "ndelay,pid", "local0";
 
my @required = ("internal");
 
my %saw = ();
open(my $in, "-|") || exec("/usr/bin/fs_cli", "-x", "sofia xmlstatus");
while ( defined(my $line = <$in>) )
{
    if ( $line =~ m|<name>(.*)</name>|o )
    {
        $saw{$1} = 1;
    }
}
close($in);
 
foreach my $profile ( @required )
{
    if ( ! $saw{$profile} )
    {
        syslog(LOG_INFO, "sip profile $profile not found, marking failure");
        exit(1);
    }
}
 
syslog(LOG_INFO, "all required sip profiles found, marking success");
exit(0);

vim /usr/src/freeswitch/ka-notify.pl

#!/usr/bin/perl
 
# INSTANCE|VI_FREESW|BACKUP|50
my ($what,$id,$state,$prio) = @ARGV;
open(STDOUT, "|/usr/bin/logger -t ka-notify");
 
print "what($what) id($id) state($state) prio($prio)\n";
 
if ( $state eq "MASTER" )
{
    print "Instance went to master, issuing sofia recover.\n";
    system("/usr/bin/fs_cli", "-x", "sofia recover");
 
    # Not ideal, but it seems to fail over too quickly for skinny devices
    # and since they don't actually handle the failover, need to poke them
    # Comment this out if you're not using mod_skinny/SCCP
    system("/usr/bin/fs_cli", "-x", "reload mod_skinny");
}

give run permission to scripts

chmod +x /usr/src/ka-*

Set the same hostname for both nodes

The hostname on both machines needs to be the same, as the sql query to recover calls, selects by hostname. To do this, simply set the following parameter in switch.conf.xml on both FS instances to the same value:

vim /etc/freeswitch/autoload_configs/switch.conf.xml
<param name="switchname" value="freeswitch"/>

Listen on floating IP Address (Run on both nodes)

Make sure that the SIP profiles are set to listen on your floating IP

vim /etc/freeswitch/sip_profiles/internal.xml

Edit the following parameters to your Virtual IP address

<param name="rtp-ip" value="10.10.10.150"/>
<param name="sip-ip" value="10.10.10.150"/>
<param name="presence-hosts" value="10.10.10.150"/>

Binding to Non-local IP addresses permanently

sudo vi /etc/sysctl.d/99-custom.conf
## allow Nginx to start and bind to non-local IP ##
net.ipv4.ip_nonlocal_bind=1
sudo sysctl -f /etc/sysctl.d/99-custom.conf
⚠️ **GitHub.com Fallback** ⚠️