В этой статье я бы хотел рассмотреть создание SIP<->Skype шлюза для проброса входящих skype-вызовов на корпоративную IP АТС (в данном случае это будет Asterisk). Так как Skype на данный момент является, пожалуй, самым популярным клиентом VoIP среди пользователей, возможность позвонить в Вашу компанию через Skype будет дополнительным плюсом для клиентов.
Для поставленной задачи был выбран следующий софт:
В принципе mod_skypiax может работать и с Asterisk, но мне было интересно пощупать именно FreeSwitch, да и писался этот модуль изначально для FreeSwitch.
Ключевым элементом всей схемы является mod_skypiax, который играет роль некой прослойки между FreeSwitch и сетью Skype. Этот модуль в терминологии FreeSwitch является канальным драйвером или конечной точкой (endpoint), такой же как, например, обычный IP-телефон.
Так как протокол Skype закрыт, то единственным способом подключения к сети Skype остается родной клиент, с которым mod_skypiax взаимодействует посредством Skype API. Каждый запущенный Skype приравнивается к одному голосовому каналу, т.е. если у Вас запущено 30 Skype'ов Вам могут одновременно звонить 30 человек. Стоит отметить, что в данной статье рассматривается использование всего одного skype-акаунта, который одновременно используется всеми запущенными Skype'ами.
Для минимизации нагрузки на сервер используется «fake» X-сервер Xvfb и snd_dummy драйвер. Использование dummy-драйвера также обосновано тем, что на серверах, как правило, отсутствует настоящая звуковая карта.
За SIP в FreeSwitch отвечает модуль mod_sofia, который, как видно на схеме, обеспечивает SIP-транк до Asterisk PBX.
Алгоритм входящего вызова выглядит примерно так:
Рассмотрим процесс установки и настройки ПО.
В debian нет готового пакета для FreeSwitch, поэтому у нас остается два варианта установки: собирать исходники из svn или собирать исходники релиза. Есть конечно вариант собрать из исходников deb-пакет, и поставить из него (что идеологически будет самым верным решением), но в таком случае, будет собрано и установлено еще куча ненужных для шлюза модулей. Поэтому, рассмотрим вариант с исходниками, а именно с svn.
Сначала поставим все, что понадобится для дальнейшей сборки:
Далее все команды и действия выполняются из под пользователя root, если не указано иное
Сразу оговорюсь, что Xvfb и все, что связано с X-сервером, нужно для запуска Skype-клиента и сборки mod_skypiax
Скачиваем дерево исходников из svn:
Редактируем
Собственно сборка и установка:
По умолчанию установка производится в директорию /usr/local/freeswitch. Копируем конфиг mod_skypiax и init-скрипт для запуска FreeSwitch:
Заводим пользователя, под которым будет работать FreeSwitch:
Готовый deb-пакет можно скачать с официального сайта Skype, так что качаем и пробуем ставить:
Оригинал статьи писался до выхода новой бета-версии Skype for Linux. Смею предположить, что в новой версии все тоже работает.
Скорее всего dpkg ругнется на недостающие зависимости, ставим их с помощью apt-get и пробуем установить Skype еще раз.
Заводим пользователя, под которым будет работать Skype:
Создаем директорию, из которой Skype будет читать свой конфиг:
Запускаем Skype на сервере, чтобы проверить его работоспособность и сконфигурировать:
где
skype_user — имя заранее зарегистрированного Skype-акаунта
skype_secret — пароль от этого акаунта
Проверить, что Skype запустился можно просто поискав его в списке процессов. Теперь нужно как-то добраться до графического интерфейса Skype, чтобы произвести необходимые настройки. Для этого воспользуемся VNC-сервером.
Подключившись по vnc к серверу, можно лицезреть запущенный в предыдущем шаге Skype, в настройках которого нужно убрать все лишнее (отключить события, автоматическое изменение статуса и т.д.) и выбрать dummy-драйвер в качестве всех звуковых устройств.
Теперь перейдем к самой важной настройке — Public API. Здесь нужно разрешить mod_skypiax обращаться к Skype. Сам Skype позволяет добавлять программы в список «Allowed programs» только по факту их обращения к Skype, но только для того, чтобы произвести такую настройку, нецелесообразно запускать FreeSwitch и mod_skypiax, поэтому создатели mod_skypiax написали небольшую утилитку, эмулирующую обращение mod_skypiax к Skype. Она находится в дереве исходников FreeSwitch и ее нужно скомпилировать отдельно:
Вернитесь в окно vnc-подключения — в появившемся диалоговом окне нужно нажать «Yes» и поставить галочку «Remember this selection».
На этом настройка Skype-клиента завершена. Осталось только клонировать полученный конфиг для нужного количества Skype-каналов.
где N — нужное количество Skype-каналов.
Для запуска Skype'ов можно воспользоваться таким скриптом:
На этом настройка Skype завершена. Осталось связать FreeSwitch со Skype'ами.
Редактируем конфиг mod_skypiax для нужного количества каналов:
Ниже привожу кусочек своего конфига как пример:
Здесь
7777 — экстеншн, на который будет маршрутизироваться входящий Skype-вызов;
:101 — дисплей X-сервера (для второго канала это будет :102 и так далее)
skype_user — имя Skype-акаунта
Запускаем FreeSwitch и пробуем загрузить mod_skypiax:
Если все хорошо, то выполнив команду sk list, можно увидеть список skypiax-интерфейсов.
Добавляем mod_skypiax в список модулей, загружающихся во время старта FreeSwitch. Для этого в файле /usr/local/freeswitch/conf/autoload_configs/modules.conf.xml нужно раскоментировать строчку
Важным моментом является то, что skype-клиенты должны запускаться до загрузки модуля mod_skypiax, т.е. перед стартом FreeSwitch. Также, остановка уже задействованных mod_skypiax копий Skype приведет к падению FreeSwitch.
Как Вы, вероятно, помните входящие Skype-вызовы будут маршрутизироваться на экстеншн 7777, который еще надо создать. Для этого в директории /usr/local/freeswitch/conf/dialplan/default создаем файл 02_skype.xml следующего содержания:
где
asterisk — название шлюза, на который будет уходить вызов (АТС на базе Asterisk)
5555 — экстеншн на этом шлюзе (для тестирования лучше всего просто поставить там Music On Hold)
Осталось настроить…
На сервере c FreeSwitch в директории /usr/local/freeswitch/conf/sip_profiles/external создаем файл asterisk.xml следующего содержания:
где
asterisk — имя шлюза (должно совпадать с указанным в предыдущем шаге);
asterisk.example.tld — имя хоста с Asterisk;
freeswitch — имя пользователя для доступа к шлюзу;
supersecret — пароль.
На сервере с Asterisk добавляем в sip.conf следующее:
где
1.1.1.1 — адрес сервера с FreeSwitch
freeswitch, supersecret — см. предыдущий шаг
Не забываем также указать контекст, для корректной маршрутизации вызова.
Осталось перечитать sip.conf:
Теперь при поступлении звонка на skype_user FreeSwitch будет соединять его с экстеншеном 5555 на хосте с Asterisk.
UPD: Как сообщает yitzhakv, сейчас в svn-транке Freeswitch модуль skypiax переработали и переименовали в skypopen, который работает менее стабильно. Поэтому, для стягивания исходников нужно воспользоваться командой
Для поставленной задачи был выбран следующий софт:
В принципе mod_skypiax может работать и с Asterisk, но мне было интересно пощупать именно FreeSwitch, да и писался этот модуль изначально для FreeSwitch.
Как это все работает
Ключевым элементом всей схемы является mod_skypiax, который играет роль некой прослойки между FreeSwitch и сетью Skype. Этот модуль в терминологии FreeSwitch является канальным драйвером или конечной точкой (endpoint), такой же как, например, обычный IP-телефон.
Так как протокол Skype закрыт, то единственным способом подключения к сети Skype остается родной клиент, с которым mod_skypiax взаимодействует посредством Skype API. Каждый запущенный Skype приравнивается к одному голосовому каналу, т.е. если у Вас запущено 30 Skype'ов Вам могут одновременно звонить 30 человек. Стоит отметить, что в данной статье рассматривается использование всего одного skype-акаунта, который одновременно используется всеми запущенными Skype'ами.
Для минимизации нагрузки на сервер используется «fake» X-сервер Xvfb и snd_dummy драйвер. Использование dummy-драйвера также обосновано тем, что на серверах, как правило, отсутствует настоящая звуковая карта.
За SIP в FreeSwitch отвечает модуль mod_sofia, который, как видно на схеме, обеспечивает SIP-транк до Asterisk PBX.
Алгоритм входящего вызова выглядит примерно так:
- Пользователь инициирует вызов на Ваш skype-акаунт;
- mod_skypiax принимает вызов используя первую свободную копию skype-клиента;
- mod_sofia инициирует SIP-соединение с Asterisk PBX, которое коммутируется с mod_skypiax.
Рассмотрим процесс установки и настройки ПО.
Установка FreeSwitch и mod_skypiax
В debian нет готового пакета для FreeSwitch, поэтому у нас остается два варианта установки: собирать исходники из svn или собирать исходники релиза. Есть конечно вариант собрать из исходников deb-пакет, и поставить из него (что идеологически будет самым верным решением), но в таком случае, будет собрано и установлено еще куча ненужных для шлюза модулей. Поэтому, рассмотрим вариант с исходниками, а именно с svn.
Сначала поставим все, что понадобится для дальнейшей сборки:
Далее все команды и действия выполняются из под пользователя root, если не указано иное
apt-get -y install build-essential subversion automake autoconf wget libtool \
libncurses5-dev xvfb libx11-dev libasound2-dev xfs xfonts-100dpi xfonts-75dpi xfonts-scalable
Сразу оговорюсь, что Xvfb и все, что связано с X-сервером, нужно для запуска Skype-клиента и сборки mod_skypiax
Скачиваем дерево исходников из svn:
cd /usr/src
svn co svn.freeswitch.org/svn/freeswitch/trunk freeswitch
cd freeswitch
Редактируем
/usr/src/freeswitch/modules.conf
под наши нужды. У меня он выглядел так:loggers/mod_console
loggers/mod_logfile
loggers/mod_syslog
applications/mod_commands
applications/mod_dptools
applications/mod_fifo
applications/mod_limit
applications/mod_expr
applications/mod_esf
codecs/mod_g723_1
codecs/mod_amr
codecs/mod_g729
codecs/mod_voipcodecs
codecs/mod_ilbc
codecs/mod_speex
dialplans/mod_dialplan_xml
endpoints/mod_sofia
endpoints/mod_skypiax
event_handlers/mod_event_socket
event_handlers/mod_cdr_csv
formats/mod_native_file
formats/mod_sndfile
formats/mod_local_stream
formats/mod_tone_stream
formats/mod_file_string
xml_int/mod_xml_cdr
Собственно сборка и установка:
cd /usr/src/freeswitch; ./bootstrap.sh ; ./configure
make && make install
По умолчанию установка производится в директорию /usr/local/freeswitch. Копируем конфиг mod_skypiax и init-скрипт для запуска FreeSwitch:
cp /usr/src/freeswitch/src/mod/endpoints/mod_skypiax/configs/skypiax.conf.xml \
/usr/local/freeswitch/conf/autoload_configs/
cp /usr/src/freeswitch/debian/freeswitch.init /etc/init.d/freeswitch
sed -i 's/opt/usr\/local/g' /etc/init.d/freeswitch
Заводим пользователя, под которым будет работать FreeSwitch:
adduser --disabled-password --quiet --system --home /usr/local/freeswitch \
--gecos "FreeSwitch Voice Platform" --ingroup daemon freeswitch
adduser freeswitch audio
chown -R freeswitch.daemon /usr/local/freeswitch
Установка и настройка Skype
Готовый deb-пакет можно скачать с официального сайта Skype, так что качаем и пробуем ставить:
wget www.skype.com/go/getskype-linux-deb
dpkg -i skype-debian_2.0.0.72-1_i386.deb
Оригинал статьи писался до выхода новой бета-версии Skype for Linux. Смею предположить, что в новой версии все тоже работает.
Скорее всего dpkg ругнется на недостающие зависимости, ставим их с помощью apt-get и пробуем установить Skype еще раз.
Заводим пользователя, под которым будет работать Skype:
adduser --home /home/skype --ingroup audio --disable-password skype
Создаем директорию, из которой Skype будет читать свой конфиг:
mkdir -p /home/skype/multi/interface01
chown -R skype.audio /home/skype/multi
Запускаем Skype на сервере, чтобы проверить его работоспособность и сконфигурировать:
/usr/bin/Xvfb :101 -ac &
su skype -c "/bin/echo 'skype_user skype_secret'| DISPLAY=:101 /usr/bin/skype \
--dbpath=/home/skype/multi/interface01 --pipelogin &"
где
skype_user — имя заранее зарегистрированного Skype-акаунта
skype_secret — пароль от этого акаунта
Проверить, что Skype запустился можно просто поискав его в списке процессов. Теперь нужно как-то добраться до графического интерфейса Skype, чтобы произвести необходимые настройки. Для этого воспользуемся VNC-сервером.
apt-get install x11vnc
x11vnc -display :101
Подключившись по vnc к серверу, можно лицезреть запущенный в предыдущем шаге Skype, в настройках которого нужно убрать все лишнее (отключить события, автоматическое изменение статуса и т.д.) и выбрать dummy-драйвер в качестве всех звуковых устройств.
Теперь перейдем к самой важной настройке — Public API. Здесь нужно разрешить mod_skypiax обращаться к Skype. Сам Skype позволяет добавлять программы в список «Allowed programs» только по факту их обращения к Skype, но только для того, чтобы произвести такую настройку, нецелесообразно запускать FreeSwitch и mod_skypiax, поэтому создатели mod_skypiax написали небольшую утилитку, эмулирующую обращение mod_skypiax к Skype. Она находится в дереве исходников FreeSwitch и ее нужно скомпилировать отдельно:
cd /usr/src/freeswitch/src/mod/endpoints/mod_skypiax/configs
gcc -Wall -ggdb skypiax_auth.c -o skypiax_auth -lX11
./skypiax_auth :101
Вернитесь в окно vnc-подключения — в появившемся диалоговом окне нужно нажать «Yes» и поставить галочку «Remember this selection».
На этом настройка Skype-клиента завершена. Осталось только клонировать полученный конфиг для нужного количества Skype-каналов.
cd /home/skype/multi
for i in $(seq 2 N); do i=$(printf "%02d" $i); cp -a interface01 interface$i; done
где N — нужное количество Skype-каналов.
Для запуска Skype'ов можно воспользоваться таким скриптом:
#!/bin/sh SKYPE_SYSTEM_USER=skype SKYPE_HOME=/home/skype/multi SKYPE_USER=skype_user SKYPE_PASSWORD=skype_secret SKYPE_INSTANCES=N XVFB=/usr/bin/Xvfb module_reload() { rmmod snd-dummy modprobe snd-dummy } skype_start() { for i in $(seq 1 $SKYPE_INSTANCES); do i=`printf "%02d" $i` $XVFB :1$i -ac >> /dev/null 2>&1 & sleep 3 su $SKYPE_SYSTEM_USER -c "/bin/echo '$SKYPE_USER $SKYPE_PASSWORD'| DISPLAY=:1$i /usr/bin/skype \ --dbpath=$SKYPE_HOME/interface$i --pipelogin >> /dev/null 2>&1 &" echo "Skype $i started" done } skype_stop() { kill -TERM `ps -u $SKYPE_SYSTEM_USER -o pid=` >> /dev/null 2>&1 sleep 3 kill -TERM `ps -C Xvfb -o pid=` >> /dev/null 2>&1 } case "$1" in start) module_reload sleep 3 skype_start ;; stop) skype_stop ;; restart) skype_stop sleep 3 skype_start ;; *) echo $"Usage: $0 {start|stop|restart}" exit 1 esac
На этом настройка Skype завершена. Осталось связать FreeSwitch со Skype'ами.
Настройка mod_skypiax
Редактируем конфиг mod_skypiax для нужного количества каналов:
vi /usr/local/freeswitch/conf/autoload_configs/skypiax.conf.xml
Ниже привожу кусочек своего конфига как пример:
<configuration name="skypiax.conf" description="Skypiax Configuration"> <global_settings> <param name="debug" value="8"/> <param name="codec-master" value="us"/> <param name="dialplan" value="XML"/> <param name="context" value="default"/> <param name="codec-prefs" value="gsm,ulaw"/> <param name="codec-rates" value="8000,16000"/> <param name="hold-music" value="$${moh_uri}"/> <param name="destination" value="7777"/> </global_settings> <!-- one entry here per skypiax interface --> <per_interface_settings> <interface id="1" name="skypiax1"> <param name="hold-music" value="$${moh_uri}"/> <param name="dialplan" value="XML"/> <param name="context" value="default"/> <param name="X11-display" value=":101"/> <param name="tcp_cli_port" value="15556"/> <param name="tcp_srv_port" value="15557"/> <param name="skype_user" value="skype_user"/> <param name="destination" value="7777"/> </interface> <!-- тут по аналогии добавляем нужное кол-во интерфейсов --> </per_interface_settings> </configuration>
Здесь
7777 — экстеншн, на который будет маршрутизироваться входящий Skype-вызов;
:101 — дисплей X-сервера (для второго канала это будет :102 и так далее)
skype_user — имя Skype-акаунта
Запускаем FreeSwitch и пробуем загрузить mod_skypiax:
/etc/init.d/freeswitch start
/usr/local/freeswitch/bin/fs_cli
freeswitch@internal> load mod_skypiax
Если все хорошо, то выполнив команду sk list, можно увидеть список skypiax-интерфейсов.
Добавляем mod_skypiax в список модулей, загружающихся во время старта FreeSwitch. Для этого в файле /usr/local/freeswitch/conf/autoload_configs/modules.conf.xml нужно раскоментировать строчку
<load module="mod_skypiax"/>
Важным моментом является то, что skype-клиенты должны запускаться до загрузки модуля mod_skypiax, т.е. перед стартом FreeSwitch. Также, остановка уже задействованных mod_skypiax копий Skype приведет к падению FreeSwitch.
Как Вы, вероятно, помните входящие Skype-вызовы будут маршрутизироваться на экстеншн 7777, который еще надо создать. Для этого в директории /usr/local/freeswitch/conf/dialplan/default создаем файл 02_skype.xml следующего содержания:
<include>
<extension name="skype_incoming">
<condition field="destination_number" expression="^7777$">
<action application="set" data="hangup_after_bridge=true"/>
<action application="set" data="effective_caller_id_name=Skype"/>
<action application="bridge" data="sofia/gateway/asterisk/5555"/>
<action application="hangup"/>
</condition>
</extension>
</include>
где
asterisk — название шлюза, на который будет уходить вызов (АТС на базе Asterisk)
5555 — экстеншн на этом шлюзе (для тестирования лучше всего просто поставить там Music On Hold)
Осталось настроить…
SIP-транк между FreeSwitch и Asterisk
На сервере c FreeSwitch в директории /usr/local/freeswitch/conf/sip_profiles/external создаем файл asterisk.xml следующего содержания:
<include>
<gateway name="asterisk">
<param name="username" value="freeswitch"/>
<param name="realm" value="asterisk.example.tld"/>
<param name="password" value="supersecret"/>
<param name="register" value="false"/>
</gateway>
</include>
где
asterisk — имя шлюза (должно совпадать с указанным в предыдущем шаге);
asterisk.example.tld — имя хоста с Asterisk;
freeswitch — имя пользователя для доступа к шлюзу;
supersecret — пароль.
На сервере с Asterisk добавляем в sip.conf следующее:
[freeswitch]
type=peer
host=1.1.1.1
username=freeswitch
port=5080
fromdomain=1.1.1.1
secret=supersecret
где
1.1.1.1 — адрес сервера с FreeSwitch
freeswitch, supersecret — см. предыдущий шаг
Не забываем также указать контекст, для корректной маршрутизации вызова.
Осталось перечитать sip.conf:
rasterisk -x 'sip reload'
Теперь при поступлении звонка на skype_user FreeSwitch будет соединять его с экстеншеном 5555 на хосте с Asterisk.
UPD: Как сообщает yitzhakv, сейчас в svn-транке Freeswitch модуль skypiax переработали и переименовали в skypopen, который работает менее стабильно. Поэтому, для стягивания исходников нужно воспользоваться командой
svn co svn.freeswitch.org/svn/freeswitch/tags/1.0.4 freeswitch