Kamailio SIP proxy: приклад установки і мінімальної налаштування


В роботі системного адміністратора, що займається впровадженням систем телефонії на базі Asterisk, рано чи пізно може виникнути ситуація, коли апаратних можливостей одного сервера для обробки всіх викликів вже недостатньо. Відповідно, виникає необхідність розділити навантаження на декілька серверів. Одним із способів вирішення такого завдання є використання SIP proxy, але варто визнати, що на відміну від Asterisk, інформації по SIP proxy, форумів, прикладів і описів, менше як мінімум на порядок. Мета цієї статті — показати на простому прикладі можливість використання SIP proxy Kamailio в зв'язці з Asterisk так, щоб максимально полегшити освоєння SIP proxy для новачків.

Всі налаштування в рамках даного прикладу ми будемо виробляти на віртуальних машинах, розміщених в локальній мережі, хоча якщо б вони мали публічні адреси і перебували б у хмарі, принципової різниці не було.

Припустимо, що в організації вже встановлено Asterisk, і співробітники обробляють велику кількість вхідних дзвінків, з яким сервер вже не справляється. Ми додамо ще один сервер Asterisk (точніше, клонируем існуючий), а SIP proxy візьме на себе роль «розподільника» вхідних дзвінків.

Почнемо з вибору SIP proxy. На хабре є хороша стаття на цю тему, в якій розглянута історія розвитку основних проектів. На відміну від автора цієї статті, мій вибір припав на Kamailio і web-інтерфейс для нього під назвою Siremis.

Встановимо Kamailio. У якості ОС будемо використовувати CentOs 6.8.

В першу чергу, необхідно відключити SELinux, оновити пакети і встановити необхідні залежності:

yum -y update && yum -y groupinstall core && yum -y groupinstall base && yum -y install epel-release
yum -y install httpd mysql-server, php php-mysql php-php gd-curl

Нам потрібен доступ до 80 порту для роботи з web-інтерфейсом і до 5060 udp для роботи з sip, тому додамо правила IPTables:

iptables -A INPUT -m state --state NEW -m tcp -p tcp --dport 80 -j ACCEPT
iptables -A INPUT -m state --state NEW -m udp -p udp --dport 5060 -j ACCEPT

Створюємо файл /etc/yum.repos.d/kamailio.repo з вмістом:

[kamailio]
name=RPMs for Kamailio on CentOS 6
type=rpm-md
baseurl=http://rpm.kamailio.org/stable/CentOS_6/
gpgcheck=1
gpgkey=http://rpm.kamailio.org/stable/CentOS_6/repodata/repomd.xml.key
enabled=1

І встановлюємо kamailio:

yum install kamailio kamailio-presence kamailio-mysql

Не забудемо додати демони в автозавантаження:

chkconfig mysqld on
chkconfig httpd on
chkconfig kamailio on

Відредагуємо файл /etc/kamailio/kamctlrc: потрібно розкоментувати рядок

DBENGINE=MYSQL

і вказати SIP_DOMAIN. В силу того, що ми налаштовуємо систему в локальній мережі, досить буде вказати ip-адресу, у моєму випадку

SIP_DOMAIN=192.168.0.237

Нижче можна редагувати параметри підключення до бази даних, але в разі навчального стенду міняти їх не обов'язково.

Запустимо MySQL і згенеруємо необхідні таблиці:

service mysqld start
kamdbctl create

На всі питання майстри відповідаємо ствердно.

Тепер відредагуємо основний конфігураційний файл /etc/kamailio/kamailio.cfg. Логічно він розбитий на кілька секцій: глобальні параметри завантаження модулів, встановлення параметрів модулів і маршрути. Кожен модуль Kamailio виконує певну функцію, тому можна завантажувати необхідні для конкретної задачі бібліотеки. Початок файлу приведемо до вигляду:

#!KAMAILIO
#!define WITH_MYSQL
#!define WITH_AUTH
#!define WITH_USRLOCDB
#!define WITH_PRESENCE
#!define WITH_ACCDB

Як зрозуміло з коментарів нижче, ці директиви включають необхідні модулі, наприклад WITH_MYSQL, визначений на початку файлу, нижче призводить до завантаження модуля mysql.so:

#!ifdef WITH_MYSQL
loadmodule "db_mysql.so"
#!endif

Безумовно, можна завантажити всі модулі вручну, але використання директиви набагато зручніше. WITH_AUTH, наприклад, дає можливість користувачам реєструватися на Kamailio з використанням імені та пароля, а всі варіанти вибору ви можете подивитися в коментарях нижче.

Для подальшої коректної роботи web-інтерфейсу і статистики внесемо ще кілька змін:

Після всіх рядків loadmodule додамо завантаження ще двох:

again "rtimer.so" 
loadmodule "sqlops.so" 

Перед секцією маршрутів, яка відокремлюється рядком ####### Routing Logic ######## додамо параметри завантажених модулів:

modparam("rtimer", "timer", "name=cdr;interval=300;mode=1;")
modparam("rtimer", "exec", "timer=cdr;route=CDRS")
modparam("sqlops", "sqlcon", "cb=>mysql://kamailio:kamailiorw@localhost/kamailio")

І додамо додатковий маршрут після останньої секції route в районі 910 рядка файлу:

route[CDRS] {
sql_query("cb","call kamailio_cdrs()","rb");
sql_query("cb","call kamailio_rating('default')","rb");
}

Запускаємо Kamailio і перевіряємо, що він запустився:

service kamailio start
ps aux | grep kamailio

Якщо Kamailio не запускається, потрібно подивитися лог /var/log/messages — саме туди будуть потрапляти помилки Kamailio, якщо додатково не налаштувати rsyslog, що не представляє великої складності.

За замовчуванням використовується база MySQL kamailio c користувачем kamailio c паролем kamailiorw, якщо звичайно не змінити установки за замовчуванням у файлі /etc/kamailio/kamctlrc перед створенням бази даних. У тому випадку, якщо ви змінили ці установки, буде незайвим пройтися автозаміну за основним конфігураційного файлу kamailio.cfg і внести коректні дані підключення до бази.

В принципі, Kamailio може працювати і без бази даних — всі необхідні значення для модулів можна задавати в конфігураційному файлі або зберігати у файлах, але використання БД, особливо на великих проектах, набагато зручніше, плюс саме з базою працюватиме web-інтерфейс Siremis, який ми зараз встановимо.

Потрібно завантажити, розпакувати файли, копіювати їх у директорію, з якою буде працювати apache і дати вірні права:

cd /usr/src
wget http://siremis.asipto.com/pub/downloads/siremis/siremis-4.3.0.tgz
tar zxvf siremis*
cp -a siremis*/. /var/www/html
cd /var/www/html
make prepare
rm -rf /var/www/html/Makefile
rm -rf /var/www/html/Changelog
rm -rf /var/www/html/README
chown -R apache. /var/www/html

У секцію VirtualHost в конфігурації apache для Siremis додамо

<Fs "/var/www/html/siremis">
Options Indexes FollowSymLinks MultiViews
AllowOverride All
Order allow,deny
Allow from all
<FilesMatch "\.xml$">
Order deny,allow
Deny from all
</FilesMatch>
<FilesMatch "\.inc$">
Order deny,allow
Deny from all
</FilesMatch>
</Directory>

<Fs "/var/www/html/openbiz">
AllowOverride All
Order deny,allow
Deny from all
</Directory>

<Fs "/var/www/html/misc">
AllowOverride All
Order deny,allow
Deny from all
</Directory>

При подальшій установці останньої на момент написання статті версії Siremis 4.3.0 можуть виникнути проблеми у випадку, якщо у вас не заданий date.timezone, тому рекомендується відразу внести зміни в php.ini:

date.timezone = Europe/Moskow

Для Siremis потрібна окрема база даних. Додамо користувача:

mysql -e "GRANT ALL PRIVILEGES ON siremis.* TO siremis@localhost IDENTIFIED BY 'siremisrw';"

Ви можете змінити параметри підключення до бази, але не забудьте тоді задати правильні значення в подальшому.

Тепер можна перезапустити apache і перейти до завершального етапу установки Siremis — вже через браузер. Перейдіть за адресою ваш ip/siremis



Якщо перевірка системи пройдено, можна починати установку.



Зверніть увагу: за замовчуванням під зірочками ховаються дефолтні паролі від користувачів Kamailio і Siremis, так що якщо ви не вносили змін раніше, то і на цьому кроці можна не забивати паролі вручну.

Обов'язково поставте галочки на всіх пунктах — Create Siremus DB, Import Dafault Data, Update SIP DB, Replace DB config.



Перевірте, що вказані коректні дані.



І на цьому встановлення завершено.



Давайте спробуємо здійснити перший дзвінок через Kamailio. Для цього перейдемо на вкладку SIP Admin menu і додамо новий домен в Domain List. Kamailio буде обслуговувати тільки перераховані тут домени (або ip-адреси).



У разі, якщо до адресою прив'язаний домен, і користувачі можуть реєструватися як вказавши ip-адресу, так і вказавши домен, слід додати і доменне ім'я в список. У нашому випадку додаємо тільки ip-адресу сервера, до якого будуть звертатися клієнти.



Для створення внутрішнього абонента або підписувача перейдемо до Subscriber Services -> Subscribers і додамо два номери — 101 і 102, вказавши для них паролі і сірий адресу в якості домену (в нашому випадку 192.168.0.237).



Тепер, використовуючи софтфон, наприклад Zoiper, ми можемо зареєструватися на сервері і здійснити дзвінок з 101 на номер 102 або навпаки і переконатися в тому, що всі попередні дії були виконані вірно.

Перейдемо до налаштування розподілу вхідних викликів. У локальній мережі, у нас є 2 віртуальні машини з Asterisk адреси 192.168.0.234 і 192.168.0.235, і нам потрібно порівну розподілити вхідні дзвінки між ними. В даній ситуації ми будемо використовувати модуль dispatcher, який надає необхідний функціонал.

Повернемося в консоль, і додамо в kamailio.cfg в секцію завантаження модулів

again "dispatcher.so"

а також два параметри підключення до бази даних, в якій буде зберігатися список серверів Asterisk, і частоту перевірки цих серверів, щоб дзвінок ні в якому разі не пішов на вимкнений сервер:

modparam("dispatcher", "db_url", "mysql://kamailio:kamailiorw@localhost/kamailio")
modparam("dispatcher", "ds_ping_interval", 30)

Взагалі, повний список модулів, їх параметрів та функцій завжди можна подивитися на офіційному сайті. Після підключення модуля перезапустим Kamailio і переконаємося в тому, що він запустився. У разі виникнення проблем (модулі можуть залежати від інших, вимагати встановлення певних параметрів як для самого модуля, так і для тих, від яких він залежить) ми побачимо помилку в балці.

Тепер перейдемо до секції маршрутів. Створені за замовчуванням маршрути в принципі забезпечують необхідний мінімум, наприклад, при спробі зареєструватися з невірним паролем, Kamailio віддасть помилку 401, а при спробі подзвонити на неіснуюче напрямок — 404. Складність у розумінні маршрутизації Kamailio представляють використовувані змінні і функції, які надаються різними використовуються модулями, і не завжди відразу можна зрозуміти, яка змінна або функція до якого модулю відноситься. Для наших навчальних цілей маршрут буде потрібно зовсім простий — в самий початок головного маршруту ми додамо умова:

if ( method=="INVITE" ) {
ds_select_dst("1","4");
sl_send_reply("100","Trying");
forward();
exit();
}

Якщо приходить запит типу INVITE, тобто запрошення до початку розмови, то ми вибираємо один з серверів, які пізніше занесемо в таблицю, з групи 1 по стратегії вибору 4 — round-robin. Потім надсилаємо відповідь викликає і здійснюємо переклад дзвінка на обраний призначення. Зверніть увагу, що тепер абсолютно будь-INVITE буде оброблятися таким чином, так що можливість зателефонувати з 101 номери на 102, які ми створювали раніше, буде втрачена, дзвінки з них теж будуть відлітати на один з серверів Asterisk, і надходять ззовні запити INVITE також будуть безпосередньо йти на Asterisk без усякої перевірки джерела запиту.

Для того, щоб Asterisk міг обробити такі виклики, потрібно додати peer наступного виду на кожен із серверів:

[kamailio]
host=192.168.0.237
port=5060
insecure=invite
type=friend
context=from-pstn

Тепер можна додати сервера Asterisk в базу даних Kamailio через web-інтерфейс:



Setid задасть до якої групи серверів відноситься новий сервер, Priority не використовується в стратегії вибору round-robin, але може використовуватися в інших стратегіях, а Flags в даному випадку встановлює, що за замовчуванням ми вважаємо сервер неактивним і перевіряємо його стан.

Після додавання серверів можна перезапустити Kamailio, що неприпустимо на продакшне, або виконати команду
kamcmd dispatcher.reload
. Список команд для кожного модуля також можна подивитися на офіційному сайті.

Можна переходити до тестування. Використовуючи софтфон, наприклад, Zoiper, можна здійснити виклик безпосередньо на Kamailio, без всяких акаунтів і реєстрацій. Достатньо ввести у поле набору sip:1@192.168.0.237. Відразу після цього виклик буде переадресовано на один з Asterisk і оброблений у відповідності з диалпланом. Наступний виклик піде на другий сервер.

В принципі, стояла перед нами навчальну задачу — розподіляти вхідні дзвінки порівну між серверами, — ми вирішили. Однак, далеко не кожен оператор зв'язку готовий віддавати дзвінки на ваш ip-адресу безпосередньо, без реєстрації, і треба буде посилати запити типу REGISTER. Цей функціонал реалізує модуль uac. Додамо в нашу схему ще один Asterisk — він буде виконувати роль провайдера. На ньому створимо якийсь внутрішній номер, наприклад, 200200, який буде вимагати реєстрацію.

Завантажимо модуль в конфігураційному файлі:

again "uac.so"

І задамо кілька обов'язкових у нашому випадку параметрів:

modparam("uac", "reg_db_url", "mysql://kamailio:kamailiorw@localhost/kamailio")
modparam("uac", "reg_contact_addr", "192.168.0.237")

Крім того, потрібно внести зміну в параметр іншого модуля. Знайдіть у файлі рядок

modparam("rr", "append_fromtag", 0) 

і замініть на:

modparam("rr", "append_fromtag", 1)

Тепер можна налаштувати реєстрацію перезавантаження попередньо Kamailio, щоб модуль завантажився:



Зверніть увагу на полі Realm. За замовчуванням, ви можете ввести в нього що завгодно, але тоді реєстрація проходити не буде, а в балці ви побачите щось на зразок:

kamailio /usr/sbin/kamailio[26277]: ERROR: uac [uac_reg.c:799]: uac_reg_tm_callback(): realms do not match. requested realm: [asterisk]

Саме тому при виникненні якихось проблем не варто відразу перечитувати мануал, шукати інші інструкції і сумніватися в своїх здібностях найчастіше пояснення можна знайти у протоколі.

Залишається тільки переконатися в тому, що абонент 200200 зареєстрований на Asterisk, який грає роль провайдера, і здійснити дзвінок з будь-якого іншого номера на 200200.

На цьому приклад налаштування Kamailio ми закінчуємо, але зверніть увагу, що в статті не розглянута робота за NAT, безпека, маршрутизація вихідних дзвінків і багато іншого, що може знадобитися в реальній ситуації. Однак сподіваюся, що ця стаття полегшить для вас освоєння Kamailio.
Джерело: Хабрахабр

0 коментарів

Тільки зареєстровані та авторизовані користувачі можуть залишати коментарі.