Skip to main content

Command Palette

Search for a command to run...

Freepbx 17 (Debian) отказоустойчивый кластер, бесплатно

Published
4 min read

Для реалезации отказоустойчевого кластера на Freepbx 17 будем использовать CARP протокол. Устанавливаем два сервера Freepbx на которых будет настроен отказоустойчивый кластер.

Freepbx01(Master) - 192.168.121.214

Freepbx02(Slave) - 192.168.121.215

HA(общий адрес) - 192.168.121.14

  1. Редактируем файлы конфигурации:

Freepbx01(Master) - 192.168.121.214

cat /etc/network/interfaces

auto lo
iface lo inet loopback

auto ens192
iface ens192 inet static
    address 192.168.121.214
    netmask 255.255.255.0
    gateway 192.168.121.1

    ucarp-vid 3
    ucarp-vip 192.168.121.14
    ucarp-password 12qwae21sS
    ucarp-advbase 1
    ucarp-advskew 0
    ucarp-master yes
iface ens192:ucarp inet static
        address 192.168.121.14
        netmask 255.255.255.0

Carp интерфейс появился 192.168.121.14. Также добавляю скрипт который будет мониторить состояние сервиса asterisk, и если по какой то причине он не работает, то интерфейс CARP будет отключен, соответственно все устройства переподключатся на резервный сервер, так как он станем Мастером.

sudo mkdir -p /var/log/ucarp-watchdog
sudo touch /var/log/ucarp-watchdog/watchdog.log
sudo chmod 664 /var/log/ucarp-watchdog/watchdog.log

sudo mcedit /usr/local/bin/ucarp-watchdog.sh

#!/bin/bash

LOG="/var/log/ucarp-watchdog/watchdog.log"
NIC="ens192"
TARGET_IP="192.168.121.14/24"    # IP з префіксом, який має бути на інтерфейсі
ASTERISK_BINARY="/usr/sbin/asterisk"

mkdir -p /var/log/ucarp-watchdog

echo "\((date '+%F %T') UCARP Watchdog started" >> "\)LOG"

ASTERISK_WAS_DOWN=0       # 0 = раніше був UP (або стартовий стан), 1 = виявлено DOWN
NETWORK_RESTARTED=0      # 0 = ще не рестартували після останнього підняття Asterisk, 1 = рестарт вже зроблено

while true; do
    # Лог часу перевірки
    TS="$(date '+%F %T')"
    echo "\(TS CHECK: start" >> "\)LOG"

    # Перевіряємо чи процес Asterisk існує (повний шлях)
    if pgrep -f "$ASTERISK_BINARY" > /dev/null ; then
        echo "\(TS CHECK: Asterisk process FOUND" >> "\)LOG"

        # Якщо раніше був DOWN (тобто тепер відновився) — помітимо відновлення
        if [ $ASTERISK_WAS_DOWN -eq 1 ]; then
            echo "\(TS INFO: Asterisk recovered" >> "\)LOG"
            # скидаємо прапорець NETWORK_RESTARTED, щоб дозволити рестарт мережі при потребі
            NETWORK_RESTARTED=0
            ASTERISK_WAS_DOWN=0
        fi

        # Перевіряємо наявність CARP-IP на інтерфейсі
        if ip a show dev "\(NIC" | grep -qF "\)TARGET_IP"; then
            echo "\(TS INFO: \)TARGET_IP is present on \(NIC" >> "\)LOG"
            # якщо IP є — нічого не робимо
            NETWORK_RESTARTED=1
        else
            echo "\(TS WARN: \)TARGET_IP NOT found on \(NIC" >> "\)LOG"
            # Якщо Asterisk працює і ми ще не рестартували мережу під час цієї сесії → рестарт
            if [ $NETWORK_RESTARTED -eq 0 ]; then
                echo "\(TS ACTION: restarting networking.service because Asterisk is running but \)TARGET_IP is missing" >> "$LOG"
                systemctl restart networking.service >> "$LOG" 2>&1
                if [ $? -eq 0 ]; then
                    echo "\(TS OK: networking.service restarted" >> "\)LOG"
                else
                    echo "\(TS ERROR: networking.service restart failed" >> "\)LOG"
                fi
                NETWORK_RESTARTED=1
            else
                echo "\(TS INFO: networking already restarted once while Asterisk is up; skipping" >> "\)LOG"
            fi
        fi

    else
        # Asterisk не працює
        echo "\(TS CHECK: Asterisk process NOT FOUND" >> "\)LOG"

        # Якщо тільки-но впав — вбити ucarp і поставити прапорець DOWN
        if [ $ASTERISK_WAS_DOWN -eq 0 ]; then
            echo "\(TS ACTION: Asterisk DOWN detected → killing UCARP" >> "\)LOG"
            pkill ucarp >> "$LOG" 2>&1 || true
            ASTERISK_WAS_DOWN=1
        else
            echo "\(TS INFO: Asterisk still down" >> "\)LOG"
        fi

        # Скидаємо прапорець NETWORK_RESTARTED, щоб при наступному піднятті Asterisk була нова спроба рестарту мережі
        NETWORK_RESTARTED=0
    fi

    echo "\(TS CHECK: end" >> "\)LOG"
    sleep 60
done

sudo chmod +x /usr/local/bin/ucarp-watchdog.sh

sudo nano /etc/systemd/system/ucarp-watchdog.service

[Unit]
Description=UCARP Asterisk Watchdog
After=network-online.target
Wants=network-online.target

[Service]
Type=simple
ExecStart=/usr/local/bin/ucarp-watchdog.sh
Restart=always
RestartSec=5
User=root
StandardOutput=append:/var/log/ucarp-watchdog/watchdog.log
StandardError=append:/var/log/ucarp-watchdog/watchdog.log

[Install]
WantedBy=multi-user.target
sudo systemctl daemon-reload
sudo systemctl enable ucarp-watchdog
sudo systemctl start ucarp-watchdog

Проверка

systemctl status ucarp-watchdog

tail -f /var/log/ucarp-watchdog/watchdog.log

  1. Freepbx01(Master) - 192.168.121.215
auto lo
iface lo inet loopback

auto ens192
iface ens192 inet static
    address 192.168.121.215
    netmask 255.255.255.0
    gateway 192.168.121.1

    ucarp-vid 3
    ucarp-vip 192.168.121.14
    ucarp-password 12qwae21sS
    ucarp-advbase 1
    ucarp-advskew 100
    ucarp-master no

iface ens192:ucarp inet static
        address 192.168.121.14
        netmask 255.255.255.0

Install zabbix

apt install zabbix-agent2

mcedit /etc/sudoers

zabbix ><------>ALL=(ALL) NOPASSWD: /usr/sbin/asterisk

usermod -aG asterisk zabbix systemctl restart zabbix-agent2

Время

ln -sf /usr/share/zoneinfo/Europe/Kiev /etc/localtime

Настройка file2ban уведомлений через Graylog

mcedit /etc/rsyslog.d/30-fail2ban.conf

module(load="imfile")

input(
  type="imfile"
  File="/var/log/fail2ban.log"
  Tag="fail2ban:"
  Severity="info"
  Facility="local0"
)

local0.* action(
  type="omfwd"
  target="192.168.96.20"
  port="514"
  protocol="udp"
)

sudo systemctl restart rsyslog

Вариант 2 отправка всех системных логов. mcedit /etc/rsyslog.conf

*.* @Ip_your_server:12223

Отправка логов Asterisk mcedit /etc/rsyslog.conf добавляю

#Asterisk full log                        
module(load="imfile")                     
input(type="imfile"                       
      File="/var/log/asterisk/full"       
      Tag="asterisk"                      
      Severity="info"                     
      Facility="local6")                  

#File2ban log
input(type="imfile"
      File="/var/log/fail2ban.log"
      Tag="fail2ban"
      Severity="info"
      Facility="local6")

Перезапуск

systemctl restart rsyslog
systemctl status rsyslog

More from this blog

IT Notes

21 posts