HowTo: Skype-шлюз на базе FreeSwitch

    В этой статье я бы хотел рассмотреть создание 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.

    Алгоритм входящего вызова выглядит примерно так:
    1. Пользователь инициирует вызов на Ваш skype-акаунт;
    2. mod_skypiax принимает вызов используя первую свободную копию skype-клиента;
    3. 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».

    another program wants to use skype

    На этом настройка 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
    Метки:
    Поделиться публикацией
    Комментарии 38
    • 0
      Попробую вечером дома. Выглядит очень привлекательно с точки зрения пробрасывания звонков с скайпа на мобильный. Черт! Я однозначно сделаю это!
      • 0
        Проброс звонков с скайпа на мобильный вроде есть и в самом скайпе. Попровьте если не прав.
        • +2
          за деньги.
          • 0
            А как можно звонить на мобильные бесплатно?!
            • 0
              тариф Эксклюзив видимо
              • 0
                совсем уж бесплатно конечно никак, но дешево можно поставив FXS шлюз и звоня по городской линии.

                Раньше у сипнета, кстати, была бесплатная Москва и Питер.
                • 0
                  А как связаны FXS и городская линия?
                  • 0
                    Сорри, FXO. Очепятался.
                • +2
                  В телефонии, как и в связи в целом всё «бесплатное» на самом деле не такое уж и бесплатное, просто за это платит кто-то другой…
                  • 0
                    Корпоративные тарифы некоторые подразумевают бесплатные звонки внутри корпорации. По крайней мере, у нас, с Беларуси, такие есть. Остаётся только поставить gsm-гейт и skype-гейт.
                    • 0
                      Только перед установкой gsm-шлюза внимательно почитайте договор с ОПСОСом. Не в их правилах терять деньги.
                      • 0
                        На прошлой своей работе консультировался с представителем ОПСОСа по поводу установки gsm-гейта. Мне сказали, что не вопрос, конечно же можно. Договор не читал, но никаких претензий не было. И мне кажется, что при гейтовании звонков из интернета через скайп на мобильник(несколько мобильников) корпорации проблем не возникнет.
                    • 0
                      Ну бывают же тарифы для стационарных телефонов с бесплатными звонками на мобильные.
                      И у мобильных бывают городские номера.

              • 0
                Спасибо. Полезная информация… И главное вовремя для меня IMHO.
                • 0
                  Как карма подрастет, перенесите в какой-нибудь коллективный блог, сюда habrahabr.ru/blogs/voip/, к примеру.
                  • 0
                    в исследовательском плане работы интересная и полезная, но в принципе для этого есть chan_skype.
                    • 0
                      насколько я понял, chan_skype — коммерческое решение
                      • 0
                        и стоит 66 уе
                        • 0
                          И принципиально ни чем не отличается от изложенного в теме. Тот же fake X11, dummy_snd драйвер и пачка запущеных Skype-ов управляемых через Skype API.

                          Хочу дожить до того момента, когда настоящие герои смогу таки разобрать Skype протокол по косточкам и написать простой, компактный и масштабируемый шлюз (a-la наш GTalk2VoIP), который не будет тащить за собой весь Skype целиком.

                          А еще (в мечтах конечно) хочу дожить до того момента, когда подобные Skype-у проприетарные решения изживут себя и каждому первокласснику будет понятно в чем состоит их вселенское зло.

                          • 0
                            Кстати Digium на днях зарелизили свой Skype For Asterisk, который, по всей видимости, работает без «пачки запущенных Skype-ов», но опять таки коммерческий.
                            • 0
                              chan_skype это и есть продукт Digium за $66. Принципиально отличается тем, что можно на 1 сервере держать N каналов Skype. X11 и пачки запущенных клиентов там близко нет.
                  • 0
                    вначале вы пишите что все звонки со skype будут переадресованы на ext 7777, а в конце вдруг на ext 5555
                    или это на freeswitch ext 7777 а на asterisk ext 5555?
                    • 0
                      7777 — это FreeSwitch, а 5555 — Asterisk
                    • 0
                      перенес в блог «IP-телефония», всем спасибо за карму
                      • 0
                        SIPNET тоже ввели эту функцию для своих пользователей:

                        www.sipnet.ru/call/skype.html
                        SIPNET начинает тестирование новой услуги «Вызов из SIPNET в Skype и обратно».
                        Все соединения между абонентами сетей SIPNET и Skype не тарифицируются.
                        • 0
                          Это очень странный шлюз, то временами не могут прозвониться из Скайпа, то я временами не могу из Сипнета вызвонить абонентов Skype. Не стабильно работает --> как только найду нормальное алтернативное решение, сразу же заменю Sipnet…
                          • 0
                            Может дело в вашей АТС? В нашей компании уже более полугода используется это решение — и клиенты довольны.
                            • 0
                              Я использую это решения — с первого дня «тестирования». Временами работает, временами глючит. У меня — не АТС.
                              Я — конечный пользователь. SIP железка — Zyxel…
                              • 0
                                В 50% случаев проблема настройки оконечного железа, или промежуточного NAT. Делайте дамп SIP при плохой связи.
                                • 0
                                  Оконечное железо — работает без проблем. Никаких проблем с SIP на других 4 провайдерах НЕТ. Да и собственно при связи через Sipnet тоже…
                                  «Промежуточный» NAT — это что за зверь?
                                  У меня железка имеет выделенный IP.
                                  Все сервера у sipneta — тоже имеют выделенный IP. ОТКУДА здесь возникнет NAT ??

                                  Проблема именно в стыке Sipnet<->Skype… но повлиять я на это практически никак не могу. Воспринимаю, «as is»…
                                  • 0
                                    Ну вдруг у вас NAT, кто же знает.

                                    Если не нравится чужое решение — купите лицензию себе. Порядка 60$.

                                    У telphin тоже есть свой шлюз — попробуйте.
                                    • 0
                                      60$ ???
                                      Что за лицензия такая?
                                      Вы имеете ввиду лицензию на SIP канал для Астериска??
                                      (Там мне помнится было 66$)
                                      Проблема в том, что сам Астериск нужно куда-то поставить.
                                      В ближайшие пару месяцев — это будет только «теоретическим изысканием»…

                                      А где вы на telphin.com нашли skype шлюз?

                                      Думаю в ближайшее время подключить www.e1tele.com -> они вроде тоже со Skype шлюз имеют…
                        • 0
                          Спасибо! Могли бы Вы написать как настроить звонки с астериски в скайп.
                          • 0
                            собирал на днях такую связку на skypopen + asterisk 1.6/1.8 все работает стабильно.
                            • 0
                              Спустя 4 года после вашей публикации поднял skype в freeswitch на Debian 7 Wheezy.
                              С незначительными изменениями в конфигах взлетело.
                              Спасибо! :)

                            Только полноправные пользователи могут оставлять комментарии. Войдите, пожалуйста.