wiki:SoftswitchFailOver

Version 16 (modified by alx, 8 years ago) ( diff )

Доработано описание варианта ручного переключения серверов.

Вариант настройки отказоустойчивого сервера FreeSwitch

Исходные данные

Имеется ubuntu-16.04 c настроенным и работающим сервером FreeSwitch, установленным из нашего репозитория, и используемым для организации диспетчерской связи. Требуется сделать резервирование из двух идентичных серверов FreeSwitch.

Переносим базы данных FreeSwitch в MySQL

Устанавливаем драйвер MyODBC и настраиваем доступ к базе данных

Устанавливаем необходимые пакеты
$ sudo apt-get install libodbc1 odbcinst unixodbc
Установим драйвер myodbc
  • Скачиваем архив mysql-connector-odbc-5.3.7-linux-ubuntu16.04-x86-64bit.tar.gz отсюда;
  • Распаковываем архив:
    $ tar zxvf mysql-connector-odbc-5.3.7-linux-ubuntu16.04-x86-64bit.tar.gz
    
  • Переходим в распакованный каталог:
    $ cd mysql-connector-odbc-5.3.7-linux-ubuntu16.04-x86-64bit
    
  • Скопируем драйвер в каталог odbc:
    $ sudo cp lib/* /usr/lib/x86_64-linux-gnu/odbc/
    
  • Конфигурируем установленный драйвер с помощью инсталлятора:
    $ sudo bin/myodbc-installer -d -a -n MySQL -t "DRIVER=/usr/lib/x86_64-linux-gnu/odbc/libmyodbc5w.so;"
    
  • Конфигурирвем источник:
    $ sudo bin/myodbc-installer -s -a -n freeswitch -t "DRIVER=MySQL;SERVER=127.0.0.1;DATABASE=dispatcher;OPTION=67108864"
    
    где "dispatcher" - имя нашей базы данных на сервере MySQL.

В результате в каталоге /etc должны быть созданы файлы odbc.ini и odbcinst.ini с приблизительно таким содержанием:

odbc.ini:

[freeswitch]
Driver=MySQL
SERVER=127.0.0.1
DATABASE=dispatcher
PORT=3306
MULTI_STATEMENTS=1

odbcinst.ini:

[MySQL]
Driver=/usr/lib/x86_64-linux-gnu/odbc/libmyodbc5w.so
UsageCount=1
FileUsage=1
Проверим работу с базой данных MySQL серез ODBC
$ isql freeswitch <username> <password>
+---------------------------------------+
| Connected!                            |
|                                       |
| sql-statement                         |
| help [tablename]                      |
| quit                                  |
|                                       |
+---------------------------------------+
SQL> show tables;
+-----------------------------------------------------------------+
| Tables_in_dispatcher                                            |
+-----------------------------------------------------------------+
| cdr                                                             |
| options                                                         |
| recordings                                                      |
+-----------------------------------------------------------------+
SQLRowCount returns 10
10 rows fetched
SQL> quit

где <username> и <password> - имя и пароль, установленные для доступа FreeSwitch к базе данных при конфигурации FreeSwitch.

Теперь необходимо установить базе данных charset по умолчанию utf8, чтобы новые таблицы, которые создаст FreeSwitch, использовали именно его:

mysql> alter database <db-name> character set utf8;
Query OK, 1 row affected (0,00 sec)

где <db-name> - имя базы данных.

Конфигурируем FreeSwitch для хранения его данных в MySQL

Конфигурируем SIP профили FreeSwitch для хранения данных в MySQL

В файлах конфигурации SIP профилей в разделе <settings/> добавляем такой параметр:

<param name="odbc-dsn" value="odbc://freeswitch:<username>:<password>"/>

где <username> и <password> - имя и пароль, установленные для доступа FreeSwitch к базе данных при конфигурации FreeSwitch. Например:

<param name="odbc-dsn" value="odbc://freeswitch:freeswitch:lagjh46dh3"/>

Здесь же включаем track-calls:

<!-- Enable Track Calls -->
<param name="track-calls" value="true"/>

Теперь в консоли FreeSwitch перезапускаем профили командой:

> sofia profile <profile-name> restart

где <profile-name> - имя SIP профиля, например:

> sofia profile internal restart

Контролируем, что профили перезупустились с помощью команды в консоли FreeSwitch:

> sofia status

В нашей базе данных должны создаться новые таблицы. Проверим это:

$ mysql -u <username> -p <dbname> -e 'show tables'
Enter password: 
+-------------------------------------+
| Tables_in_dispatcher                |
+-------------------------------------+
| cdr                                 |
| options                             |
| recordings                          |
| sip_authentication                  |
| sip_dialogs                         |
| sip_presence                        |
| sip_registrations                   |
| sip_shared_appearance_dialogs       |
| sip_shared_appearance_subscriptions |
| sip_subscriptions                   |
+-------------------------------------+
Конфигурируем хранение core-db в MySQL

Одна из таблиц (а именно, channels) при попытке ее создания с использованием кодировки utf8 превосходила лимит на максимальный размер строки в таблице mysql. Поэтому создаем эту таблицу вручную, немного изменив тип некоторых особо "жирных" столбцов:

CREATE TABLE channels (
   uuid  VARCHAR(256),
   direction  VARCHAR(32),
   created  VARCHAR(128),
   created_epoch  INTEGER,
   name  VARCHAR(1024),
   state  VARCHAR(64),
   cid_name  VARCHAR(1024),
   cid_num  VARCHAR(256),
   ip_addr  VARCHAR(256),
   dest  VARCHAR(1024),
   application  VARCHAR(128),
   application_data  TEXT(4096),
   dialplan VARCHAR(128),
   context VARCHAR(128),
   read_codec  VARCHAR(128),
   read_rate  VARCHAR(32),
   read_bit_rate  VARCHAR(32),
   write_codec  VARCHAR(128),
   write_rate  VARCHAR(32),
   write_bit_rate  VARCHAR(32),
   secure VARCHAR(64),
   hostname VARCHAR(256),
   presence_id TEXT(4096),
   presence_data TEXT(4096),
   accountcode VARCHAR(256),
   callstate  VARCHAR(64),
   callee_name  VARCHAR(1024),
   callee_num  VARCHAR(256),
   callee_direction  VARCHAR(5),
   call_uuid  VARCHAR(256),
   sent_callee_name  VARCHAR(1024),
   sent_callee_num  VARCHAR(256),
   initial_cid_name  VARCHAR(1024),
   initial_cid_num  VARCHAR(256),
   initial_ip_addr  VARCHAR(256),
   initial_dest  VARCHAR(1024),
   initial_dialplan  VARCHAR(128),
   initial_context  VARCHAR(128)
);

В конфиг-файле switch.conf.xml добавляем параметр:

<param name="core-db-dsn" value="odbc://freeswitch:<username>:<password>"/>

где <username> и <password> - имя и пароль, установленные для доступа FreeSwitch к базе данных при конфигурации FreeSwitch.

Здесь же устанавливаем имя коммутатора:

<param name="switchname" value="freeswitch"/>

Теперь выполняем рестарт FreeSwitch:

$ sudo service freeswitch restart

Убедимся, что в базе данных появились новые таблицы:

$ mysql -u root -p dispatcher -e 'show tables'
Enter password: 
+-------------------------------------+
| Tables_in_dispatcher                |
+-------------------------------------+
| aliases                             |
| basic_calls                         |
| calls                               |
| cdr                                 |
| channels                            |
| complete                            |
| detailed_calls                      |
| interfaces                          |
| nat                                 |
| options                             |
| recordings                          |
| recovery                            |
| registrations                       |
| sip_authentication                  |
| sip_dialogs                         |
| sip_presence                        |
| sip_registrations                   |
| sip_shared_appearance_dialogs       |
| sip_shared_appearance_subscriptions |
| sip_subscriptions                   |
| tasks                               |
+-------------------------------------+

Конфигурируем второй сервер

Устанавливаем и конфигурируем второй сервер полностью аналогично первому. Проверим, что установлены все необходимые модули. Конфигурацию нового сервера (/etc/freeswitch) можно целиком скопировать с первого.

Настраиваем репликацию между двумя серверами mysql

Останавливаем FreeSwitch на обоих серверах:

$ sudo service freeswitch stop

В конфиг-файлы mysqld добавляем следующее:

server-id               = 1
log_bin                 = /var/log/mysql/mysql-bin.log
expire_logs_days        = 10
max_binlog_size         = 100M
binlog_do_db            = dispatcher

где server-id - идентификатор сервера, он должен быть разный у разных серверов.

Перезапускаем mysqld на обоих серверах:

$ sudo service mysql restart

Подключаемся к mysql серверу и создаем пользователя для репликации:

mysql> CREATE USER 'replicator'@'%' IDENTIFIED BY 'password';

заменив "password" каким-нибудь паролем.

Даем пользователю право на репликацию:

mysql> GRANT REPLICATION SLAVE ON *.* TO 'replicator'@'%';

На сервере 1 блокируем базу данных на запись:

mysql> FLUSH TABLES WITH READ LOCK;

Выводим состояние мастера:

mysql> SHOW MASTER STATUS;

Будет выведена примерно такая таблица:

+------------------+----------+--------------+------------------+-------------------+
| File             | Position | Binlog_Do_DB | Binlog_Ignore_DB | Executed_Gtid_Set |
+------------------+----------+--------------+------------------+-------------------+
| mysql-bin.000002 | 62249651 | dispatcher   |                  |                   |
+------------------+----------+--------------+------------------+-------------------+
1 row in set (0.00 sec)

Не выходя из консоли mysql (при выходе снимется блокировка), из другого терминала дампим базу данных:

$ mysqldump -u root -p dispatcher >dispatcher.dump

Когда дамп будет готов, снова выведем SHOW MASTER STATUS; и убедимся, что значение Position не изменилось. Теперь можно снять блокировку:

mysql> UNLOCK TABLES;

или просто выйти из консоли mysql.

Копируем сделанный дамп базы на второй сервер. Записываем дамп в базу данных:

$ mysql -u root -p dispatcher <dispatcher.dump

Теперь входим в консоль mysql сервера 2 и запускаем репликацию:

mysql> STOP SLAVE;
mysql> CHANGE MASTER TO MASTER_HOST = '<server 1 address>' , MASTER_USER = 'replicator', MASTER_PASSWORD = 'password', MASTER_LOG_FILE = 'mysql-bin.000002', MASTER_LOG_POS = 62249651;
mysql> START SLAVE;

заменив "password" на тот пароль, который установили пользователю replicator ранее.

Проверим, что репликация активирована:

mysql> SHOW SLAVE STATUS\G
*************************** 1. row ***************************
               Slave_IO_State: Waiting for master to send event
                  Master_Host: 192.168.0.64
                  Master_User: replicator
                  Master_Port: 3306
                Connect_Retry: 60
              Master_Log_File: mysql-bin.000003
          Read_Master_Log_Pos: 118750
               Relay_Log_File: r3-relay-bin.000002
                Relay_Log_Pos: 82017
        Relay_Master_Log_File: mysql-bin.000003
             Slave_IO_Running: Yes
            Slave_SQL_Running: Yes
              Replicate_Do_DB: 
          Replicate_Ignore_DB: 
           Replicate_Do_Table: 
       Replicate_Ignore_Table: 
      Replicate_Wild_Do_Table: 
  Replicate_Wild_Ignore_Table: 
                   Last_Errno: 0
                   Last_Error: 
                 Skip_Counter: 0
          Exec_Master_Log_Pos: 118750
              Relay_Log_Space: 82221
              Until_Condition: None
               Until_Log_File: 
                Until_Log_Pos: 0
           Master_SSL_Allowed: No
           Master_SSL_CA_File: 
           Master_SSL_CA_Path: 
              Master_SSL_Cert: 
            Master_SSL_Cipher: 
               Master_SSL_Key: 
        Seconds_Behind_Master: 0
Master_SSL_Verify_Server_Cert: No
                Last_IO_Errno: 0
                Last_IO_Error: 
               Last_SQL_Errno: 0
               Last_SQL_Error: 
  Replicate_Ignore_Server_Ids: 
             Master_Server_Id: 1
                  Master_UUID: 7603167a-1081-11e6-9637-902b3433882b
             Master_Info_File: /var/lib/mysql/master.info
                    SQL_Delay: 0
          SQL_Remaining_Delay: NULL
      Slave_SQL_Running_State: Slave has read all relay log; waiting for more updates
           Master_Retry_Count: 86400
                  Master_Bind: 
      Last_IO_Error_Timestamp: 
     Last_SQL_Error_Timestamp: 
               Master_SSL_Crl: 
           Master_SSL_Crlpath: 
           Retrieved_Gtid_Set: 
            Executed_Gtid_Set: 
                Auto_Position: 0
         Replicate_Rewrite_DB: 
                 Channel_Name: 
           Master_TLS_Version: 
1 row in set (0.00 sec)

Аналогично, только без выполнения/восстановления дампа настраиваем репликацию сервера 2 на сервер 1.

Синхронизация файлов конфигурации и записей переговоров

Синхронизацию файлов конфигурации и записей переговоров сделаем с помощью rsync. Чтобы схема была симметричной, каждый из серверов будет копировать свои обновившиеся файлы на другой сервер. Копирование будет производиться по SSH.

Для начала проверим, что в /etc/passwd пользователю freeswitch установлен реальный shell (а не /bin/false или что-то аналогичное). При необходимости установим шелл командой:

$ sudo usermod -s /bin/sh freeswitch

Генерируем пользователю freeswitch rsa ключ для ssh:

$ sudo su -l freeswitch
$ ssh-keygen -t rsa -b 4096

В результате в домашнем каталоге пользователя freeswitch будет создан файл .ssh/id_rsa.pub. Добавляем содержимое этого файла в файл .ssh/authorized_keys в домашнем каталоге пользователя freeswitch на другом сервере. Проверим, что пользователь freeswitch с одного сервера может войти по ssh на другой сервер без ввода пароля:

$ sudo su -l freeswitch
$ ssh <address>
Welcome to Ubuntu 16.04.2 LTS (GNU/Linux 4.4.0-62-generic x86_64)

 * Documentation:  https://help.ubuntu.com
 * Management:     https://landscape.canonical.com
 * Support:        https://ubuntu.com/advantage
Last login: Wed Feb 22 11:27:59 2017 from 192.168.0.61
$

Теперь, когда каждый из серверов может соединиться по SSH со своим собратом, настроим синхронизацию файлов конфигурации и записей переговоров. Для этого добавим в /etc/crontab каждого сервера такие записи:

*/5 * * * * freeswitch rsync -au -e ssh /etc/freeswitch/ <address>:/etc/freeswitch/
*/5 * * * * freeswitch rsync -au -e ssh /var/lib/freeswitch/recordings/ <address>:/var/lib/freeswitch/recordings/

В вышеприведенном примере файлы синхронизируются каждые 5 минут.

Для более равномерного распределения нагрузки на сеть можно настроить серверам разное время синхронизации, например:

0-59/5 * * * * freeswitch rsync -au -e ssh /etc/freeswitch/ .......
1-59/5 * * * * freeswitch rsync -au -e ssh /var/lib/freeswitch/recordings/ ........

на первом сервере и

2-59/5 * * * * freeswitch rsync -au -e ssh /etc/freeswitch/ .......
3-59/5 * * * * freeswitch rsync -au -e ssh /var/lib/freeswitch/recordings/ ........

на втором сервере.

Проверим работу синхронизации: на первом сервере создадим новый файл в /var/lib/freeswitch/recordings/ и изменим какой-нибудь файл в /etc/freeswitch/. Подождем 5 минут и убедимся, что на втором сервере появился новый файл в /var/lib/freeswitch/recordings/ и отразилось изменение файла в /etc/freeswitch/. Аналогично проверим копирование в обратном направлении.

Переключение на резерв

Далее будет описано два варианта настройки переключения на резервный сервер:

  • автоматическое переключение;
  • ручное переключение.

Автоматическое переключение

В этом варианте конфигурации мы будем использовать два общих IP адреса - один для базы данных MySQL, другой для FreeSwitch. Общий адрес - это IP адрес, используя который один из двух серверов (активный) будет предоставлять сервис. Пусть для определенности общий адрес FreeSwitch будет 192.168.0.63, а общий адрес MySQL - 192.168.0.66. Для автоматического переключения будем использовать протокол VRRP и демон keepalived. Этот демон будет обеспечивать поднятие на одном из серверов (активном, MASTER) общего адреса.

Устанавливаем пакет keepalived:

$ sudo apt-get install keepalived

Конфигурируем keepalived. Сначала создадим скрипт /etc/keepalived/ka-master.pl, который будет передавать FreeSwitch команду sofia recover при переходе сервера в состояние MASTER:

#!/usr/bin/perl

my $password = "secret";
 
open(STDOUT, "|/usr/bin/logger -t ka-master");
print "Instance went to master, issuing sofia recover.\n";
system("/usr/bin/fs_cli", "-p$password", "-x", "sofia recover");

где "secret" меняем на наш пароль доступа к event-socket FreeSwitch. Так как файл содержит пароль, не забываем установить ему права доступа, разрешающие чтение только для пользователя root:

$ sudo chown root:root /etc/keepalived/ka-master.pl
$ sudo chmod 700 /etc/keepalived/ka-master.pl

Создаем базовый файл конфигурации /etc/keepalived/keepalived.conf:

global_defs {
    router_id FREESW
}

vrrp_instance VI_FREESW {
    state BACKUP
    interface eth0
    virtual_router_id 51
    priority 100
    advert_int 1
    authentication {
        auth_type PASS
        auth_pass labuda25
    }
    notify_master "/etc/keepalived/ka-master.pl"
    virtual_ipaddress {
        192.168.0.63/24 dev eth0 label eth0:0
    }
}

vrrp_instance VI_MYSQL {
    state BACKUP
    interface eth0
    virtual_router_id 55
    priority 100
    advert_int 1
    authentication {
        auth_type PASS
        auth_pass labuda52
    }
    virtual_ipaddress {
        192.168.0.66/24 dev eth0 label eth0:1
    }
}

где "eth0" - имя сетевого интерфейса - меняем его в соответствии с именем интерфейса каждого сервера. В данной конфигурации описано два экземпляра объекта vrrp: VI_MYSQL для сервера MySQL и VI_FREESW для сервера FreeSwitch.

Запускаем keepalived на одном из серверов:

$ sudo service keepalived start

Контролируем в /var/log/syslog, что демон успешно запустился и, так как на втором сервере keepalived еще не запуцщен, сразу после запуска экземпляры VI_MYSQL и VI_FREESW должны перейти в состояние MASTER. Контролируем, что у сервера появились адреса 192.168.0.63 и 192.168.0.66.

Теперь запускаем keepalived на втором сервере. Контролируем, что демон запустился, но экземпляры VI_MYSQL и VI_FREESW находятся в состоянии BACKUP, так как в сети уже есть MASTER.

Контролируем переход сервера из состояния BACKUP в состояние MASTER. Для этого на несколько секунд отключаем активный в данный момент MASTER от сети (или просто останавливаем на нем демон keepalived). Контролируцем, что сервер, находившийся в состоянии BACKUP, перешел в состояние MASTER.

Теперь необходимо изменить настройки odbc таким образом, чтобы оба сервера FreeSwitch подключались к базе данных, используя общий адрес и, таким образом, подключались к одному и тому же серверу mysql. Для этого в ранее созданном файле /etc/odbc.ini указываем адрес сервера 192.168.0.66.

Устанавливаем параметр sysctl net.ipv4.ip_nonlocal_bind в значение 1 чтобы дать возможность неактивному серверу FreeSwitch слушать адрес, отсутствующий на его интерфейсах:

$ sudo sysctl net.ipv4.ip_nonlocal_bind=1

Для автоматической установки этого значения в файл /etc/sysctl.conf добавляем строку

net.ipv4.ip_nonlocal_bind=1

В конфигурации профилей FreeSwitch устанавливаем параметры sip-ip, rtp-ip, presence-hosts, ext-sip-ip и ext-rtp-ip в значение 192.168.0.63.

Теперь можно запустить сервера FreeSwitch:

$ sudo service freeswitch start

На данном этапе у нас настроен переход сервера из резерва в активное состояние по единственному критерию - недоступности мастера, определяемой по протоколу VRRP. Теперь добавим сюда контроль работоспособности FreeSwitch. Для этого создадим скрипт /etc/keepalived/fs-status.sh:

#!/bin/sh

password="secret";
profiles="internal internal6";

RESULT=`/usr/bin/fs_cli -p$password -x "sofia xmlstatus"`

for P in $profiles; do
    echo $RESULT | grep -q "<name>${P}</name>" || exit 1
done

exit 0;

где "secert" заменяем на пароль доступа к event-socket FreeSwitch-сервера, а переменной profiles присваиваем имена SIP-профилей, наличие которых необходимо контролировать. Не забываем установить скрипту права доступа, чтобы ничто не мог украсть пароль. Теперь, если все перечисленные в profiles профили запущены, скрипт вернет 0, иначе - 1.

Если требуется контролировать только один профиль, скрипт можно сделать более лаконичным:

#!/bin/sh

password="secret";
profile="internal";

/usr/bin/fs_cli -p$password -x "sofia xmlstatus" | grep -q "<name>${profile}</name>" || exit 1
exit 0;

Проверим функционирование скрипта, запустив его вручную. Если все хорошо, укажем keepalived проверять работоспособность FreeSwitch каждые 10 секунд. Для этого в /etc/keepalived/keepalived.conf добавляем секцию с описанием скрипта:

vrrp_script chk_fs {
    script "/etc/keepalived/fs-status.sh"
    interval 10
}

и в секцию vrrp_instance VI_FREESW добавляем указание использовать этот скрипт:

    track_script {
        chk_fs
    }

Перезапустим keepalived:

$ sudo service keepalived restart

Контролируем, что сервер в состоянии BACKUP. Теперь подключаемся к консоли FreeSwitch и останавливаем профиль internal:

> sofia profile internal stop

Ждем 10 секунд и контролируем, что экземпляр VI_FREESW перешел в состояние FAULT.

Ручное переключение

В этой схеме сервер, на котором поднят общий адрес, определяется командами администратора. Общий адрес - это IP адрес, используя который один из двух серверов (активный) будет предоставлять сервис. Пусть для определенности это будет адрес 192.168.0.63.

Для начала установим пакет arping:

$ sudo apt-get install arping

Теперь необходимо изменить настройки odbc таким образом, чтобы оба сервера FreeSwitch подключались к базе данных используя общий адрес и, таким образом, подключались к одному и тому же серверу mysql. Для этого в ранее созданном файле /etc/odbc.ini указываем адрес сервера 192.168.0.63.

Устанавливаем параметр sysctl net.ipv4.ip_nonlocal_bind в значение 1 чтобы дать возможность неактивному серверу FreeSwitch слушать адрес, отсутствующий на его интерфейсах:

$ sudo sysctl net.ipv4.ip_nonlocal_bind=1

Для автоматической установки этого значения в файл /etc/sysctl.conf добавляем строку

net.ipv4.ip_nonlocal_bind=1

В конфигурации профилей FreeSwitch устанавливаем параметры sip-ip, rtp-ip, presence-hosts, ext-sip-ip и ext-rtp-ip в значение 192.168.0.63.

Теперь можно запустить сервера FreeSwitch:

$ sudo service freeswitch start

Для управления переключением на каждом из серверов установим lighttpd:

$ sudo apt-get install lighttpd

На каждом из серверов добавим два cgi-скрипта - один для отображения текущего состояния сервера, другой - для активации/деактивации сервера. Скрипт страницы состояния /var/www/html/cgi-bin/status.sh:

#!/bin/sh

# Имя сетевого интерфейса с общим адресом
IFNAME="eth2:0"
# Название сервера в заголовке страницы
HEADER="Сервер 1"

# Генерируем веб-страницу с состоянием и кнопкой "Активировать"/"Деактивировать"
echo "Content-Type: text/html; charset=utf-8"
echo "Cache-Control: no-cache"
echo
echo '<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">'
echo "<html>"
echo "  <head>"
echo '    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />'
echo "    <title>${HEADER}</title>"
echo "  </head>"
echo "  <body>"
echo "    <h1>${HEADER}</h1>"
echo '    <form action="/cgi-bin/onoff.sh">'
if ifconfig -a | grep -q "^${IFNAME} "; then
echo '    <div style="text-align:center; font-size:24pt; color:green;">Активен</div>'
echo '    <div style="text-align:center"><button type="submit" name="action" value="off">Деактивировать</button></div>'
else
echo '    <div style="text-align:center; font-size:24pt; color:#909090;">В резерве</div>'
echo '    <div style="text-align:center"><button type="submit" name="action" value="on">Активировать</button></div>'
fi
echo '    </form>'
echo "  </body>"
echo "</html>"

где переменные IFNAME и HEADER устанавливаем в соответствии с именем именем сетевого интерфейса каждого сервера и желаемым заголовком соответственно.

Скрипт активации/деактивации /var/www/html/cgi-bin/onoff.sh:

#!/bin/sh

IFNAME="eth0:0"
IFADDR="192.168.0.63"
PASSWORD="secret"

echo "Content-Type: text/html; charset=utf-8"
echo "Cache-Control: no-cache"
echo "Refresh: 5; url=/cgi-bin/status.sh"
echo
echo '<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">'
echo "<html>"
echo "  <head>"
echo '    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />'
echo "    <title>${HEADER}</title>"
echo "  </head>"
echo "  <body>"

case ${QUERY_STRING} in
    action=on)
        echo "    <h1>Активируем сервер...</h1>"
        sudo /sbin/ifconfig ${IFNAME} ${IFADDR}
        sudo /usr/sbin/arping -c3 -W0.2 -PUq -S ${IFADDR} ${IFADDR}
        /usr/bin/fs_cli -p${PASSWORD} -x "sofia recover"
        ;;

    action=off)
        echo "    <h1>Деактивируем сервер...</h1>"
        sudo /sbin/ifconfig ${IFNAME} down
        ;;

    *)
        ;;
esac

echo "  </body>"
echo "</html>"

аналогично, переменным IFNAME и IFADDR в начале скрипта присваиваем имя сетевого интерфейса и общий адрес, переменной PASSWORD присваиваем пароль доступа к event-socket сервера FreeSwitch. Так как скрипт содержит пароль, не забудем ограничить права доступа:

$ sudo chown www-data:www-data /var/www/html/cgi-bin/onoff.sh
$ sudo chmod 700 /var/www/html/cgi-bin/onoff.sh

Теперь разрешим выполнение команд ifconfig и arping для пользователя www-data, от которого работает процесс lighttpd. Для этого добавляем в файл /etc/sudoers такие строчки:

www-data ALL=(ALL) NOPASSWD:/sbin/ifconfig eth0\:0 *
www-data ALL=(ALL) NOPASSWD:/usr/sbin/arping -c3 -W0.2 -PUq -S * *

Разрешим выполнение cgi-скриптов серверами lighttpd:

$ sudo ln -s ../conf-available/10-cgi.conf /etc/lighttpd/conf-enabled/

Теперь создадим HTML-страницу /var/www/html/index.html, на которой будет отображаться два фрейма с состоянием наших серверов:

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
    <head>
        <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
        <title>Управление серверами</title>
    </head>
    <body>
        <iframe src="http://192.168.0.61/cgi-bin/status.sh" style="width: 49%; height: 300px;"></iframe>
        <iframe src="http://192.168.0.62/cgi-bin/status.sh" style="width: 49%; height: 300px;"></iframe>
    </body>
</html>

где вместо 192.168.0.61 и 192.168.0.62 впишем адреса серверов.

Выполним рестарт lighttpd:

$ sudo service lighttpd restart

Проверим, что получилось, открыв браузером корневую страницу любого из серверов. Мы увидим что-то типа:

Проверим работу cgi-скриптов, нажимая кнопку "Деактивировать"/"Активировать". Нажатие должно приводить к появлению/пропаданию алиаса с общим адресом. Кроме этого, активация должна сопровождаться передачей трех ARP-пакетов для обновления ARP-таблиц сетевых устройств.

Attachments (1)

Download all attachments as: .zip

Note: See TracWiki for help on using the wiki.