Задача Одним из наиболее популярных приложений для голосового общения в сети является Skype. Для этого есть и объективные предпосылки - достаточно развитые возможности клиента и протокола, неплохая работа в условиях NAT (и даже возможность работы через прокси), интеграция (коммерческая) с телефонными сетями, мультиплатформенный клиент. Основной недостаток - закрытость протокола и клиента, сложность интеграции с другими chat/voice сервисами, замкнутость технологии на одной компании. Тем не менее - реалии таковы что на сегодняшний день это наиболее популярное средство для общения и, на мой взгляд, альтернатив, особенно открытых, немного. В этой заметке я решил описать создание гейта skype <-> SIP с использованием IP АТС Asterisk. Данное решение позволит преобразовать skype трафик в стандартный и открытый SIP, с которым потом уже средствами Asterisk (и не только) можно делать все что угодно. Выбор ПО Редкий тролль не любит рассказов об ужасах, скрывающихся в BLOB`ах закрытых продуктов (особенно забавна история когда обнаружили чтение skype`ом /etc/passwd и стали трубить о том что скайп "ворует пароли"), которые чаще всего не подкреплены какими либо доказательствами. Тем не менее - в данной задаче, на мой взгляд, и в самом деле удобнее создать изолированное окружения, как по соображениям безопасности так и с точки зрения удобства поддержки. В качестве виртуальной машины я выбрал linux-kvm (также успешно протестирована работа в VirtualBox), в качестве гостевой среды - debian 5 (который как раз только что вышел). Выбор основан исключительно на личных предпочтениях, думаю что должно работать на любом другом дистрибутиве, и скорее всего, даже на BSD (в линуксяторе). В дальнейшем я планирую перенести гейт на XEN, так что в данном случае нормальная поддержка в debian работы в domU тоже плюс. Единственным найденным мной открытым решением для *nix стал Skypiax, так что тут и выбирать не пришлось. Принцип работы Как уже упоминалось - скайп закрытое приложение, и его протокол достаточно неплохо защищен от сторонних разработчиков. Так что единственным доступным клиентом протокола в настоящий момент является сам skype. Но для интеграции своего ПО со сторонними разработчиками (как железа, так и ПО) skype клиент позволяет работать с ним используя документированное API. В linux версии для транспорта используется DBUS и X11. API достаточно обширно, но тем не менее о полноценном embed клиенте говорить не приходится, так что нам все равно потребуется X11 и запущенный клиент. Skypiax позволяет Asterisk общаться с запущенными skype клиентами и совершать или принимать skype звонки. Установка ПО Для начала установим ОС. Для нашей задачи будет вполне достаточно диска на 2Gb (думаю, что хватило бы и сильно меньшего но это потребовало бы пересборки пакетов без ненужных зависимостей). Ставить дистрибутив x86_64 лишено смысла, так как клиент все равно i386, да и памяти меньше израсходуем. qemu-img create ~/images/skype 2G kvm -hda ~/images/skype -cdrom ~/dists/debian-500-i386-CD-1.iso Выбираем вариант установки без десктоп окружения и прочего непотребства, все что нужно мы позже установим из пакетов. После того как установка завершена - перезагружаем гостя и устанавливаем нужные пакеты: Asterisk, заголовки и куча преимущественно ненужных нам зависимостей skype:~# apt-get install asterisk-dev Skype client skype:~# wget http://skype.com/go/getskype-linux-deb skype:~# dpkg -i skype-debian_2.0.0.71-1_i386.deb skype:~# apt-get -f install skype:~# dpkg -i skype-debian_2.0.0.71-1_i386.deb Subversion (потребуется для скачивания исходников skypiax) skype:~# apt-get install subversion OpenSSH server (для управления в будущем и первоначальной настройки Skype) skype:~# apt-get install openssh-server Заголовки Xlib потребуются нам позже skype:~# apt-get install libx11-dev Теперь загрузим и скомпилируем skypiax: skype:~# svn co http://www.celliax.org:8081/svn/celliax/trunk celliax skype:~# cd celliax/skypiax_stuff/build/ skype:~/celliax/skypiax_stuff/build# vi Makefile Заменяем путь AST_INCLUDE_DIR=/home/user/devel/asterisk-1.4.23.1/include на AST_INCLUDE_DIR=/usr/include, компилируем и копируем результат в нужную нам папку. skype:~/celliax/skypiax_stuff/build# make skype:~/celliax/skypiax_stuff/build# cp chan_skypiax.so /usr/lib/asterisk/modules/ && cp skypiax.conf /etc/asterisk/ На этом установка завершена, можно переходить к более увлекательному этапу настройки. Настраиваем skype клиента Для запуска skype я использован возможность X11 forwarding openssh сервера и клиента, присоединившись с десктоп машины на skype сервер с параметром -X: ssh -X [email protected] Для своей работы скайп захочет звуковую карту, для подобных целей в alsa предусмотрен драйвер snd-dummy, загрузим его: modprobe snd-dummy После этого запускаем в терминале скайп, и если все работает правильно - он должен показать лицензионное соглашение и свой интерфейс на рабочем столе. Скайп позволяет использовать одно и тоже подключение из нескольких мест (чем, кстати, выгодно отличается от SIP), но тем не менее я рекомендую завести отдельную запись, как минимум для удобства тестирования. Запустив скайп соглашаемся с лицензией и вводим данные учетной записи. Если все настроено правильно - skype должен зарегистрироваться в сети. Перейдя в настройки отключаем уведомления (Notifications -> Enable Event). Теперь самое важное - в пункте Sound Devices указываем устройство Dummy (hw:Dummy,0). В меню Advanced стоит отключить проверку обновлений, а в меню Video Devices - поддержку видео. После этого skype клиент должен без проблем совершать или принимать звонки, правда слышно ничего не будет, так как карта виртуальная. Не закрываем клиент (он нам скоро потребуется) и переходим к настройке Asterisk. Настраиваем Asterisk 1. Подключаемся к серверу с включенным X11 forwarding Desktop:~$ ssh -X [email protected] 2. Для того, чтобы астериск смог взаимодействовать с запущенным skype клиентом нам потребуется значение переменной DISPLAY skype:~# echo $DISPLAY В моем случае это localhost:11.0 3. Параметры skype транков (их может много) задаются в /etc/asterisk/skypiax.conf. По умолчанию там уже заданы 2 транка, закомментируем их. Параметры для моего транка выглядят так: [skypeclient] language=en ; default context=default ; incoming context extension=600 ; forward calls to default asterisk echo test skype=yes ; legacy setting X11_display=localhost:11.0 ; value from $DISPLAY tcp_cli_port=11234 ; 2 random pots tcp_srv_port=11235 ; skype_user=skypet123 ; skype nickname playback_boost=0 ; volume boost for playback capture_boost=0 ; ... and recording В данной конфигурации я указал X11_display из пункта 2, для того, чтобы asterisk смог соединиться с запущенным клиентом. Extension=600 обозночает что входящие звонки в будут перенаправлены в extension 600, который по умолчанию (см. extensions.conf) перенаправляется на эхо тест задержки. Это позволит нам убедиться что все работает правильно и заодно определить на слух задержу сигнала. 4. Запускаем астериск в режиме консоли skype:~# /etc/init.d/asterisk stop; asterisk -c -vvv -ddd Если все настроено верно - скайп должен показать уведомление о том, что другая программа пытается к нему подключиться. Обязательно отмечаем галку "Remember this selection" и разрешаем подключение. После этого пробуем позвонить на эту скайп запись. Если все настроено верно - вы должны слышать эхо-тест астериска. Кстати, распознавание DTMF прекрасно работает, что позволяет создавать IVR на базе данного решения. Запуск скайп в виртуальном X сервере Для того, чтобы skype работал в виртуальном X11 окружении установим xvfb - Virtual Framebuffer 'fake' X server. skype:~# apt-get install xvfb Данный сервер позволяет работать X11 приложением локально, не требуя видео карты и потребляя сравнительно немного ресурсов. Для запуска скайпа создадим скрипт skypestart.sh: #!/bin/sh # loading sound driver /sbin/modprobe snd_dummy # setting DISPLAY export DISPLAY=:1 # starting virtual framebuffer X-Server nohup /usr/bin/Xvfb ${DISPLAY} -screen scrn 300x600x8 >/dev/null & echo <skypenick> <password>|/usr/bin/skype --pipelogin & # restarting asterisk sleep 5 /etc/init.d/asterisk restart заменив <skypenick> <password> на данные skype записи. Этот скрипт загружает snd_dummy, запускает X-server и загружает скайп. Перезагрузка астериска требуется для того, чтобы он установил связь с клиентом. Скрипт можно добавить в крон, например так: @reboot /root/skypestart.sh Или сделать на его основе полноценный init.d сценарий. Также возможна запуска более чем одной копии Skype. Для этого надо скопировать $HOME/.Skype/ в соответствующие поддиректории, и переопределив HOME и DISPLAY запустить для каждой из копий свой xvfb сервер и клиента, добавив соответствующие записи в конфигурацию asterisk. Redirect звонков skype на SIP phone Для тестирования работы skype c SIP телефоном я использовал ATA adapter Linksys (подойдет и любой sofpthone, например - Ekiga), подключив его к Asterisk. Для этого создадим запись в файле /etc/asterisk/sip.conf ; linksys ata adapter, skype testing [sipphone] context=default type=friend ; ATA login secret=f.ck ; ATA password host=dynamic ; allow to register Перезапустим Asterisk и настроем АТА адаптер используя Asterisk в качестве сервера. Для проверки наберем на SIP телефоне 600#, вы должны услышать эхо тест. Если все работаем - настроим перенаправление. Для этого в /etc/asterisk/skypiax.conf заменим строчку extension=600 на, например extensions=555. В файле /etc/asterisk/extensions.conf (секция [default]) добавим exten => 555,1,Dial(SIP/sipphone); Перезапустим Asterisk и попробуем вызвать наш тествовый SkypeID - звонок должен быть перенаправлен на sipphone. Единственный неприятный момент - скайп берет трубку сразу после поступления вызова, так что корректную сигнализацию, вероятно, обеспечить не удастся. Вызов skype абонентов Для того, чтобы с sipphone вызывать skype пользователей - добавим соответствующие записи в /etc/asterisk/extensions.conf (секция default), например [default] exten => 555,1,Dial(SIP/sipphone); exten => 556,1,Dial(Skypiax/skypeclient/echo123); exten => 557,1,Dial(Skypiax/skypeclient/drugdiler); exten => 558,1,Dial(Skypiax/skypeclient/advokat); и в консоли Asterisk наберем dialplan reload. Теперь набрав на sipphone 556 asterisk соединет нас с Skype call testing service. Что и требовалось ) Заключение Для использования решения в production желательно сделать некоторые доработки, так я планирую сделать скрипты для пуска/остановки клиентов, создать rootless окружение для всего этого, интегрировать все это хозяйство с monit и перенести все в Xen domU. Тем не менее уже сейчас понятно что решение работоспособно и работает достаточно неплохо. Я буду рад дельным замечаниям и комментариям на эту тему.
Источник: OpenNet