Как стать автором
Обновить
180.18

Расширенное руководство по разработке SIP-клиента для IP-телефонии

Уровень сложностиСложный
Время на прочтение10 мин
Количество просмотров1.5K

Всем привет! Меня зовут Илья Чубко, я технический архитектор К2Тех.

IP-телефония давно стала важной частью корпоративных коммуникаций. Она позволяет компаниям эффективно управлять голосовыми вызовами через интернет, а собственный SIP-клиент дает возможность глубже интегрировать телефонные функции в веб-приложения. Это улучшает взаимодействие с пользователями и повышает продуктивность. 

В этой статье я расскажу, как создается прототип SIP-клиента — минимально жизнеспособный продукт (MVP), который позволит совершать голосовые вызовы прямо из браузера через SIP-подключение. Такое решение поможет компаниям встроить голосовую связь в свои веб-приложения без установки дополнительного программного обеспечения. 

Ниже – пошаговая инструкция по созданию веб-SIP-клиента на Angular с использованием sip.js, его подключению к серверу Asterisk и настройке защищенного соединения через TLS с поддержкой WebRTC.

Для реализации проекта используются следующие технологии:

  • Angular — современный фреймворк для создания веб-приложений;

  • sip.js — популярная JavaScript-библиотека для работы с SIP-протоколом в браузере;

  • Asterisk — мощная IP-АТС с поддержкой VoIP;

  • CentOS 9 — серверная операционная система семейства RedHat для развертывания Asterisk;

  • TLS — защищенный протокол для шифрования SIP-соединений;

  • WebRTC — технология для передачи аудио и видео в реальном времени через браузер.

Установка и настройка Asterisk на CentOS 9

Для работы SIP-клиента необходимо настроить серверную часть на базе Asterisk — одной из самых популярных IP-АТС с открытым исходным кодом. Она позволяет управлять голосовыми вызовами, обрабатывать SIP-сообщения и поддерживает WebRTC.

В этом разделе разберем установку Asterisk на CentOS 9: подготовку системы, установку зависимостей, компиляцию и настройку конфигурационных файлов. После этого сервер будет готов принимать SIP-подключения и обрабатывать звонки.

Создадим пользователя, под которым будет работать Asterisk

sudo useradd -r -s /sbin/nologin asterisk
sudo mkdir -p /home/asterisk
sudo chown asterisk:asterisk /home/asterisk
sudo usermod -d /home/asterisk asterisk

Устанавливаем инструменты для сборки

sudo dnf groupinstall "Development Tools" -y
sudo dnf install epel-release wget git net-tools -y
sudo dnf config-manager --set-enabled crb
sudo dnf install libedit-devel libuuid-devel ncurses-devel libxml2-devel libsqlite3x-devel libicu-devel libsrtp libsrtp-devel openssl openssl-devel -y

Устанавливаем кодеки

sudo dnf install     https://mirrors.rpmfusion.org/free/el/rpmfusion-free-release-9.noarch.rpm     https://mirrors.rpmfusion.org/nonfree/el/rpmfusion-nonfree-release-9.noarch.rpm -y
sudo dnf install ffmpeg ffmpeg-devel -y

Установка и настройка базы данных (MariaDB)

sudo dnf install mariadb-server mariadb -y
sudo systemctl start mariadb && sudo systemctl enable mariadb
sudo mysql_secure_installation

Установка PHP

sudo dnf install -y dnf-utils
sudo dnf install -y https://rpms.remirepo.net/enterprise/remi-release-9.rpm
sudo dnf module list php
sudo dnf module enable php:8.2
sudo dnf install -y php php-cli php-common php-fpm php-pear php-mbstring php-xml php-json php-process php-mysqlnd

chown asterisk:asterisk /etc/php-fpm.d/ -R
chown asterisk:asterisk /var/run/php-fpm -R
chown asterisk:asterisk /var/log/php-fpm/ -R

sudo sed -i 's/^user = apache/user = asterisk/' /etc/php-fpm.d/www.conf
sudo sed -i 's/^group = apache/group = asterisk/' /etc/php-fpm.d/www.conf
sudo sed -i 's/^;listen.mode = 0660/listen.mode = 0660/' /etc/php-fpm.d/www.conf
sudo sed -i 's/^listen.acl_users = apache,nginx/listen.acl_users = asterisk/' /etc/php-fpm.d/www.conf

Вручную добавить пользователя в сервис /usr/lib/systemd/system/php-fpm.service:

[Service]
...
User=asterisk
Group=asterisk
...

Перезапускаем службу:

sudo vi /etc/systemd/system/php-fpm.service
systemctl daemon-reload
sudo systemctl restart php-fpm

Установка Httpd

sudo dnf install httpd -y
sudo sed -i 's/^User asterisk/User asterisk/' /etc/httpd/conf/httpd.conf
sed -i 's/AllowOverride None/AllowOverride All/' /etc/httpd/conf/httpd.conf
systemctl restart httpd && systemctl enable httpd

sudo sed -i 's/^User apache/User asterisk/' /etc/httpd/conf/httpd.conf
sudo sed -i 's/^Group apache/Group asterisk/' /etc/httpd/conf/httpd.conf

Установка NodeJs

curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.39.1/install.sh | bash
source ~/.bashrc
nvm install --lts
curl -sL https://rpm.nodesource.com/setup_18.x | sudo bash -
sudo dnf install -y nodejs-18.16.0

Установка Jansson

wget https://github.com/akheron/jansson/releases/download/v2.13.1/jansson-2.13.1.tar.gz
tar -xzvf jansson-2.13.1.tar.gz
cd jansson-2.13.1
sudo ./configure
sudo make
sudo make install

Установка Pjproject

cd /usr/src
wget https://github.com/pjsip/pjproject/archive/refs/tags/2.11.tar.gz
tar -xvf 2.11.tar.gz
cd pjproject-2.11
./configure
make
make install

Установка Asterisk

cd /usr/src/
sudo wget http://downloads.asterisk.org/pub/telephony/asterisk/asterisk-22-current.tar.gz
sudo tar xvf asterisk-22-current.tar.gz
cd asterisk-22.*/
sudo ./configure
sudo make menuselect
sudo make
sudo make install
sudo make samples
sudo make config

sudo chown -R asterisk:asterisk /var/run/asterisk && \
sudo chown -R asterisk:asterisk /var/lib/asterisk && \
sudo chown -R asterisk:asterisk /var/log/asterisk && \
sudo chown -R asterisk:asterisk /var/spool/asterisk

sudo -u asterisk /usr/sbin/asterisk
sudo chown -R asterisk:asterisk /etc/asterisk /var/{lib,log,spool}/asterisk /usr/lib/asterisk

sudo mkdir -p /var/run/asterisk
sudo chown -R asterisk:asterisk /var/run/asterisk
sudo chmod -R 775 /var/run/asterisk

Если отсутствуют файл modules.conf, то создаем его командой и следующим содержанием:

vi /etc/asterisk/modules.conf
[modules]
load => chan_sip.so
load => chan_pjsip.so
load => pbx_config.so

Регистрация службы:

sudo vi /etc/systemd/system/asterisk.service
[Unit]
Description=Asterisk PBX and telephony daemon
After=network.target

[Service]
Type=simple
User=asterisk
Group=asterisk
ExecStart=/usr/sbin/asterisk -f -C /etc/asterisk/asterisk.conf
ExecStop=/usr/sbin/asterisk -rx 'core stop now'
Restart=on-failure
RestartSec=5s

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

Установка FreePBX (опционально)

cd /usr/src/
sudo wget http://mirror.freepbx.org/modules/packages/freepbx/freepbx-17.0-latest.tgz
sudo tar xvf freepbx-17.0-latest.tgz
cd freepbx

sudo ./start_asterisk start
sudo ./install -n

fwconsole ma list
fwconsole ma install core
fwconsole ma installall
fwconsole ma upgradeall
fwconsole restart

sudo fwconsole chown
sudo fwconsole reload
sudo fwconsole ma refreshsignatures

sudo chown -R asterisk:asterisk /var/www/html/admin/libraries/BMO/
sudo chmod -R 755 /var/www/html/admin/libraries/BMO/

В итоге мы получили готовый сервер Asterisk, все службы работают под пользователем asterisk.

Обеспечение безопасности: настройка TLS для SIP-соединений

Для работы SIP-клиента в браузере необходимо использовать защищенное соединение, так как современные браузеры поддерживают WebRTC и SIP-соединения только при использовании TLS. Это позволяет зашифровать передаваемые данные и защитить их от перехвата.

В этом разделе мы настроим TLS в Asterisk, чтобы SIP-клиенты могли устанавливать безопасное соединение с сервером. Для этого потребуется:

  • сгенерировать самоподписанный сертификат или использовать сертификат от доверенного центра сертификации (например, Let's Encrypt);

  • настроить Asterisk для работы с TLS;

  • настроить Asterisk для работы с WSS.

После настройки клиенты могут подключаться к телефонии как с использованием TLS для софтфонов, например, microsip, так и с помощью веб-сокетов по защищенному протоколу WSS. Передача аудио данных после подключение будет происходить по WebRTC.

Генерация самоподписанного сертификата

Выполняем следующие команды для создания самоподписанного сертификата и настройки его в Asterisk:

# Создаём каталог для хранения сертификатов
mkdir -p /etc/asterisk/keys && cd /etc/asterisk/keys

# Генерируем закрытый ключ
openssl genrsa -out asterisk.key 2048

# Создаём запрос на сертификат (CSR)
openssl req -new -key asterisk.key -out asterisk.csr \
  -subj "/C=RU/ST=Moscow/L=Moscow/O=MyCompany/OU=IT/CN=$(hostname -f)"

# Подписываем сертификат (действителен 1 год)
openssl x509 -req -days 365 -in asterisk.csr -signkey asterisk.key -out asterisk.crt

# Создаём сертификат CA (Certification Authority)
openssl req -new -x509 -days 365 -key asterisk.key -out ca.crt \
  -subj "/C=RU/ST=Moscow/L=Moscow/O=MyCompany/OU=IT/CN=CA"

# Устанавливаем права доступа
chmod 600 asterisk.key
chmod 644 asterisk.crt ca.crt
chown asterisk:asterisk asterisk.key asterisk.crt ca.crt

Настроим Asterisk для работы с TLS

Добавить транспорт можно через файл /etc/asterisk/pjsip.transports.conf или pjsip.transports_custom.conf (если у вас FreePBX). Содержимое файла будет следующее:

[0.0.0.0-tls]
type=transport
protocol=tls
bind=0.0.0.0:5061
external_media_address=<ip сервера>
external_signaling_address=<ip сервера>
ca_list_file=/etc/pki/tls/certs/ca-bundle.crt
cert_file=/etc/asterisk/keys/asterisk.crt
priv_key_file=/etc/asterisk/keys/asterisk.key
method=tlsv1_2
verify_client=no
verify_server=no
allow_reload=yes
tos=cs3
cos=3
local_net=<локальные адреса>

Аналогичные настройки можно сделать через FreePBX в разделе Settings > Asterisk SIP Settings > SIP Settings [chan_pjsip].

Настроим Asterisk для работы с WSS

Для добавления транспорта wss также используем файлы pjsip.transports.conf или pjsip.transports_custom.conf.

[0.0.0.0-wss]
type=transport
protocol=wss
bind=0.0.0.0:8089
external_media_address=<ip сервера>
external_signaling_address=<ip сервера>
allow_reload=yes
tos=cs3
cos=3
local_net=<локальные адреса>
ca_list_file=/etc/pki/tls/certs/ca-bundle.crt
cert_file=/etc/asterisk/keys/asterisk.crt
priv_key_file=/etc/asterisk/keys/asterisk.key

Настройка расширений (extensions) в Asterisk

После настройки TLS и WSS необходимо создать SIP-учетные записи и диалпланы, чтобы клиенты могли регистрироваться на сервере и совершать звонки. В Asterisk это реализуется через файл pjsip.endpoint.conf или pjsip.endpoint_custom.conf, pjsip.endpoint_custom_post.conf (при наличии FreePBX). В качестве примера давайте настроим номер 100 для работы WSS, а 101 для TLS для софтфона. Файл pjsip.endpoint.conf будет выглядеть так:

[100]
type=endpoint
aors=100
auth=100-auth
tos_audio=ef
tos_video=af41
cos_audio=5
cos_video=4
allow=ulaw,alaw,gsm,g726,g722,opus,g729
context=from-internal
callerid=100 <100>
dtmf_mode=rfc4733
direct_media=yes
transport=0.0.0.0-tls
aggregate_mwi=yes
use_avpf=yes
rtcp_mux=yes
max_audio_streams=1
max_video_streams=1
bundle=yes
ice_support=yes
media_use_received_transport=no
trust_id_inbound=yes
user_eq_phone=no
send_connected_line=yes
media_encryption=dtls
timers=yes
timers_min_se=90
media_encryption_optimistic=no
refer_blind_progress=yes
rtp_timeout=30
rtp_timeout_hold=300
rtp_keepalive=0
send_pai=yes
rtp_symmetric=yes
rewrite_contact=yes
force_rport=yes
language=en
one_touch_recording=on
record_on_feature=apprecord
record_off_feature=apprecord
dtls_verify=fingerprint
dtls_setup=actpass
dtls_rekey=0
dtls_cert_file=/etc/asterisk/keys/asterisk.crt
dtls_private_key=/etc/asterisk/keys/asterisk.key

[101]
type=endpoint
aors=101
auth=101-auth
tos_audio=ef
tos_video=af41
cos_audio=5
cos_video=4
allow=ulaw,alaw,gsm,g726,g722,opus,g729
context=from-internal
callerid=101 <101>
dtmf_mode=rfc4733
direct_media=yes
transport=0.0.0.0-tls
aggregate_mwi=yes
use_avpf=yes
rtcp_mux=yes
max_audio_streams=1
max_video_streams=1
bundle=no
ice_support=yes
media_use_received_transport=no
trust_id_inbound=yes
user_eq_phone=no
send_connected_line=yes
media_encryption=dtls
timers=yes
timers_min_se=90
media_encryption_optimistic=no
refer_blind_progress=yes
rtp_timeout=30
rtp_timeout_hold=300
rtp_keepalive=0
send_pai=yes
rtp_symmetric=yes
rewrite_contact=yes
force_rport=yes
language=en
one_touch_recording=on
record_on_feature=apprecord
record_off_feature=apprecord
dtls_verify=fingerprint
dtls_setup=actpass
dtls_rekey=0
dtls_cert_file=/etc/asterisk/keys/asterisk.crt
dtls_private_key=/etc/asterisk/keys/asterisk.key

Также нужно скорректировать файлы pjsip.auth.conf и другие. Лучше создать пользователей в FreePBX либо обратиться к официальной документации по созданию extensions.
Хочу обратить внимание на то, что через FreeBPX нельзя указать транспорт wss для extension, и для решения этой проблемы можно использовать файл pjsip.transports_custom_post.conf, либо общий файл pjsip_custom_post.conf со следующим содержанием:

[100](+)
transport=0.0.0.0-wss

[101](+)
media_encryption=sdes

Причем у 101 нужно использовать более старый кодировщик, так как многие софтфоны могут не поддерживать новые.

Настройка обратного прокси

Если необходимо, можно настроить обратный прокси, чтобы разрешить websocket-соединение с сервером телефонии. Для примера приведу настройки nginx:

    location /ws {
        proxy_pass https://<ip-адрес>:8089/ws;
        proxy_http_version 1.1;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection "Upgrade";
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_read_timeout 86400;
        proxy_connect_timeout 60;
    }

Настройка SIP-клиента Angular с sip.js

Подробности о самом приложении рассказывать не буду. Приведу минимальную функциональность для установления соединения и совершения звонка на введённый номер.

Исходный код находится по адресу: https://github.com/chubkoiv/sip-client.git
Для подключение к серверу телефонии необходимо скорректировать переменные url, login, secret в sip.service.ts.

При запуске проекта с настройками произойдет поднятие websocket-соединения и регистрация номера в телефонии. Консоль браузера выглядит примерно так:

Состояние подключений endpoint можно посмотреть на сервере Asterisk, выполнив вход в CLI либо следующей командой:

asterisk -rx "pjsip show endpoints"

Настройка SIP-клиента с использованием софтфона microSip

Софтфон microsip вы можете скачать с официального сайта https://www.microsip.org.
Для регистрации номера выполним настройки для ранее созданного extension 101.

SIP-сервер: <ip>:5061
Имя пользователя: 101
Домен: <ip или dns-имя>
Логин: 101
Пароль: <secret из Asterisk>
Шифрование: необязательное
Транспорт: TKS

После этого в левом нижнем углу отобразится иконка зашифрованного соединения:

Теперь если мы введем в приложении 101 и нажмем "Вызвать", то получим входящий звонок в microsip.

Заключение

В процессе работы мы развернули Asterisk 22 на CentOS 9 Stream, настроили безопасное TLS-подключение, включили поддержку WebRTC и WSS (WebSocket Secure), а также создали SIP-клиент на Angular с использованием sip.js. В результате у нас получилось полноценное решение для VoIP-звонков прямо из браузера через защищенное соединение. Кроме того, можно подключать сторонние SIP-клиенты, например MicroSIP.

В дальнейшем проект можно развивать, добавляя поддержку видеозвонков, интеграцию с базой данных для хранения SIP-учетных данных и истории вызовов, настройку STUN/TURN-серверов для работы WebRTC за NAT, подключение к мобильным SIP-клиентам и интеграцию с FreePBX для удобного управления Asterisk. Это решение можно использовать как основу для построения VoIP-инфраструктуры в корпоративных веб-приложениях, колл-центрах и CRM-системах.

Теги:
Хабы:
+11
Комментарии0

Публикации

Информация

Сайт
k2.tech
Дата регистрации
Численность
101–200 человек
Местоположение
Россия