1 июля 2013

Лето, отпуск, asterisk или сам себе VoIP оператор

Asterisk
Из песочницы
Лето, отпуск, asterisk


Собрался я вместе со своим товарищем в период летнего отпуска поколесить на авто по Европе. А серой осенью есть мысли отправиться поближе к экватору. И вполне резонно встал вопрос связи. Skype, ICQ и прочие сервисы это конечно хорошо, но только не для старшего поколения. Жена и друзья без вопросов, а родители? Супруга сразу же сказала что передастом (человек который передает что-либо) быть не желает. Еще неплохо было бы свой номер рабочим оставить, чтоб у людей не было ощущения, что я канул в небытие. Опять же учитывая непростую роуминговую тарификацию наших операторов сотовой связи, в которой разбираться у меня нет никакого желания, сформировалось представление того, что я хочу получить в итоге.

  1. Звонки из любой точки мира по местным тарифам
  2. Прием звонков на свой личный номер
  3. Голосовые сообщения если я не доступен
  4. Голосовая почта
  5. Прием и передача смс
  6. Безопасность соединения


Выбор программного обеспечения



Для реализации бюджетного VoIP как нельзя лучше подходит Asterisk, с которым мне периодически приходится сталкиваться по работе. Дешево, сердито и надежно.

GSM шлюз это конечно хорошо, но даже goip это 12 тыс.руб. и более. Поэтому единственный вариант который мне показался приемлемым это chan_dongle и парочка huawei.

Прием и передача смс это либо jabber, либо электронная почта.

Безопасность отдельная тема. Все таки считаю что не замечательно будет, если астериск голой попой на всеобщее обозрение выставить. Если к астериску подключатся с ноутбука, то в общем то без разницы какой будет VPN. Но это же не правильно и не удобно каждый раз доставать ноут. А учитывая что у меня неистовая любовь к андроиду, я изучил маркет на предмет vpn клиентов и на своего старичка galaxy s поставил OpenVPN.

Итак, приступим


Порылся в дальнем углу кладовки и достал старый комп. Система ubuntu, т.к. дебиан подобные мне близки. Ставил исключительно с болванки, так как ubuntu с флешки ставится только после магических па.

Так как на хабре предпочитают jedi way и не любят стандартные маны по установке, будем ставить астериск 11 ручками и спрячем подробности под спойлеры. OpenVPN будем ставить как смертные. Выбор 11 астериска обусловлен новым модулем xmpp, в котором появилась возможность обрабатывать входящие сообщения.

Openvpn

Так как решено использовать соединение через OpenVPN а комп с астериском будет стоять на работе за натом, то будем использовать внешний VPN сервер. Для личных нужд у меня имеется сервачек у немцев. Но в принципе не будет хуже, если использовать что ни будь наше. Селектел мне понравился (ни разу не реклама), все интуитивно понятно, разворачивается только в путь. И по затратам вполне гуманно, надо включил, не надо выключил.

В общем, накатываем openVPN на что ни будь торчащее в сеть, в моем случае дебиан.

Для сервера
Ставим OpenVPN
sudo su
aptitude update
aptitude upgrade
aptitude install openvpn


Создадим директорию и скопируем комплект скриптов из примеров:
mkdir /etc/openvpn/easy-rsa/
cp -r /usr/share/doc/openvpn/examples/easy-rsa/2.0/* /etc/openvpn/easy-rsa/


Редактируем vars
nano /etc/openvpn/easy-rsa/vars

Я правил:
export KEY_COUNTRY="RU"
export KEY_PROVINCE="REGION"
export KEY_CITY="GLUBINKA"
export KEY_ORG="KROILOVO CORP"
export KEY_EMAIL=”KC@example.ru”


Дальше генерируем сертификаты и переносим в каталог с настройками:
cd /etc/openvpn/easy-rsa/
source vars
./clean-all
./build-dh
./pkitool --initca
./pkitool --server server
cd keys
openvpn --genkey --secret ta.key
cp server.crt server.key ca.crt dh1024.pem ta.key /etc/openvpn/


Теперь необходимо сгенерировать сертификаты для клиентов
cd /etc/openvpn/easy-rsa/
source vars
./build-key client_name ,где clien_name имя клиента


На клиентские устройства необходимо передать:
/etc/openvpn/ca.crt
/etc/openvpn/easy-rsa/keys/clien_name.crt
/etc/openvpn/easy-rsa/keys/ clien_name.key
/etc/openvpn/ta.key


Мой server.conf
port 1110
proto tcp
dev tun
ca ca.crt
cert server.crt
key server.key
dh dh1024.pem
server 192.168.100.0 255.255.255.0
ifconfig-pool-persist ipp.txt
client-to-client  #чтоб клиенты видели друг  друга
tls-auth ta.key 0
keepalive 10 120
comp-lzo
max-clients 10
persist-key
persist-tun
status openvpn-status.log
verb 3


Для клиентов linux
Ставим OpenVPN
sudo su
aptitude update
aptitude upgrade
aptitude install openvpn

в /etc/openvpn должны лежать
ca.crt
clien_name.crt
сlien_name.key
ta.key
client_name.conf

Мой client_name.conf
Client
dev tun
proto tcp
remote serverIP 1110
resolv-retry infinite
nobind
persist-key
persist-tun
ca ca.crt
cert client_name.crt
key client_name.key
tls-auth ta.key 1
comp-lzo
verb 3


Для клиентов Android
Из google play ставим OpenVPN for Android
Копируем на флешку устройства сертификаты, сгенерированные на сервере
Задаем адрес и порт сервера, добавляем сертификаты и соединяемся.


В итоге получаем все устройства в одной VPN.
У меня получилось 5 устройств:
  1. Сервер OpenVPN
  2. Asterisk
  3. Ноутбук
  4. Телефон
  5. Телефон компаньона


Asterisk

Идем на asterisk.org и в downloads качаем. В тот момент когда я ставил asterisk.org лежал. Поэтому ставил 11.2.1 так как оно на компе валялось. На данный момент доступен 11.4.0. Не думаю что сильно отличается, но changelog не читал.
Установка Asterisk
sudo su
mkdir /usr/src/asterisk
cd /usr/src/asterisk
wget http://downloads.asterisk.org/pub/telephony/asterisk/asterisk-11-current.tar.gz
aptitude update
aptitude upgrade

Ставим зависимости
aptitude install build-essential linux-headers-`uname -r` g++ libmysqlclient-dev libxml2-dev libncurses5-dev libsqlite3-dev libssl-dev libsrtp0-dev unixodbc-dev

Так как в планируется использовать jabber, то нужно поставить iksemel и openssl. Без них модуль xmpp не соберется
aptitude install libssl-dev libssl1.0.0 libiksemel-dev libiksemel3

Начинаем ставить
tar xvf asterisk-11-current.tar.gz
cd asterisk-11-current
./configure
make menuselect

Добавил xmpp и ael остальное по дефолту
make
make install

делаем
make samples

чтобы получить дефолтовые конфиги.
делаем
make config 

чтобы астериск запускался демоном.


Chan dongle

Дальше нам нужно собрать chan_dongle. Чудесный проект, который поддерживал товарищ BG2, но толи запал пропал, толи в силу непреодолимых обстоятельств обновлений у проекта не было достаточно давно (что прискорбно) и под 11 астериском оно собираться отказывается напрочь. Но гитхаб нам поможет.
Установка chan_dongle
aptitude install git
cd /usr/src/asterisk
wget https://github.com/jstasiak/asterisk-chan-dongle/archive/asterisk11.zip
unzip asterisk11.zip

ну а дальше по мануалу
aclocal
autoconf
automake –a
./configure
Make
Make install



Дальше читаем вики проекта wiki.e1550.mobi и находим модемы из списка поддерживаемых. В моем случае это оказались E1550 и E173. С самими модемами все просто, гуглим на предмет usbmodeswitch ну или под windows переводим в режим только модем через терминал. На моем Е1550 еще потребовалось активировать голосовые функции. В Dongle.conf особых изменений не делал, только добавил IMSI своих симок, по которым модуль будет выбирать ту самую симку, и контекст для входящих.
изменения dongle.conf
context=dongle-incoming
[mts]
imsi=25001xxxxxxxxxx;
exten=911 
[megafon]
imsi=25002xxxxxxxxxx;
exten=921 


теперь в CLI астериска перегружаем модуль и проверяем зацепились ли модемы
dongle reload now
dongle show devices

Если все увиделось и все хорошо то можно приступать к настройке всего этого добра.

Настройка Asterisk

В sip.conf прописываем пользователей
sip.conf
[general]
language = ru;
tcpenable = yes ;
transport = tcp,udp;

[LOCAL-USERS](!)
type = friend ; 
host = dynamic ;
context = from-office ;
disallow = all ; 
allow = ulaw ; 
allow = alaw ; 
allow = gsm ;
monitor = yes ;
callcounter = yes ;
callwaiting = no ;
rtptimeout = 10;
rtpholdtimeout = 20;
dtmfmode = rfc2833 ;
[10](LOCAL-USERS) ;
username = 10 ;
secret = passfor10 ;
[11](LOCAL-USERS) ;
username = 11 ;
secret = passfor11 ;
[12](LOCAL-USERS);
username = 12 ;
secret = passfor12;
[13](LOCAL-USERS);
username = 13 ;
secret = passfor13;
[14](LOCAL-USERS);
username = 14 ;
secret = passfor14;


Cоздаем очередь в queues.conf
queues.conf
[general]
persistentmembers = yes ;
autofill = yes ;
monitor-type = MixMonitor

[WORKGROUP]
strategy = ringall;
ringinuse = yes ;
timeout = 20 ;
retry = 1 ;
maxlen = 0 ; 
member => SIP/10
member => SIP/11
member => SIP/12
member => SIP/13
member => SIP/14


Так как для восприятия более удобным считаю AEL, то диалплан писал исключительно на нем.
Extensions.ael
Globals {
     __TRANSFER_CONTEXT=transfer; //Дефолтовый контекст для перевода звонков
};
context transfer{
        _1X => Dial(SIP/${EXTEN},60,t);   //перевод звонков
}
context from-office {    
        includes {			; //инклудим контексты чтоб кашу не устраивать
                mobile-numbers;
                city-numbers;
                local-users;
        };
};
context mobile-numbers {  ;//все мобильные
        _89XXXXXXXXX =>  Dial(Dongle/s:25002/${EXTEN},,T);  //Кроить дак кроить, звонить будем с рабочего номера :)
};
context city-numbers {   ; //городские
        _XXXXXX => Dial(Dongle/s:25002/${EXTEN},,T);
};
context dongle-incoming {   ;// входящие c chan_dongle
        921 =>  Queue(WORKGROUP,t,,,60); //все входящие с рабочего отправляем в очередь workgroup
        911 =>{  ;// все входящие на личный
            Answer;
            Dial(SIP/10,60,tT); //набираем на андроид
            Dial(SIP/11,60,tT); //набираем на ноут
            Playback(/tmp/ya_v_otpuske); //говорим что я в отпуске 
            Jabbersend(asterisk@jabber_example.ru,grasp@jabber_example.ru,Тебе звонили с номера {CALLERID(num)});   // шлем в jabber номер звонящего
            Hangup;
};
        sms => {
            Jabbersend(asterisk@jabber_example.ru,grasp@jabber_example.ru,${CALLERID(num)} ${SMS});   //в jabber шлем входящие смс
            Hangup();
        };
        ussd => {
            Jabbersend(asterisk@ jabber_example.ru,grasp@jabber_example.ru,${USSD});  // //в jabber шлем входящие ussd
            Hangup();
        };
};
context local-users {
        _500 => { ;  // для записи голосовых файлов
            Wait(2);
            Record(/tmp/ast:wav);
            Wait(2);
            Playback(/tmp/ast);
            Wait(2);
            Hangup;
        };
        _600 => { ; // запрос баланса, ответ придет в jabber
            System(/usr/sbin/asterisk -x 'dongle ussd mts *100#');
            System(/usr/sbin/asterisk -x 'dongle ussd megafon *100#');
        };
        _1X => {
            Dial(SIP/${EXTEN},60,tT);  // Для внутренних звонков
        };
};


Логика следующая: При звонке на рабочий номер, звонки заворачиваются в очередь. В этой очереди все мои устройства и вторая линия на VoIP телефоне напарника, который находится в офисе. При звонке на мой личный номер сначала asterisk будет пытаться соединить с андроидом, потом с ноутбуком и если я не доступен, то будет играться голосовое сообщение про то, что я в отпуске и смогу связаться со всеми жаждущими при первой же возможности. Ну и в конце сообщение в jabber.

На андроиде поставил 2х клиентов 3сх и CSipSimple. Были проблемы со звуком в одну сторону, но разбираться было особенно некогда, поэтому в openVPN поставил галочку “перенаправлять весь трафик через VPN” и все заработало. Проверял через 3G и wifi, работает не заикается.

Для jabber поднял openfire. Думаю описывать не стоит да и можно что то стороннее использовать. В xmpp.conf прописал настройки и все с пол пинка запустилось. OpenFire ставил исключительно из любопытства, так как под него есть плагин для астериска, но это отдельная история. Остается еще прикрутить отправку смс через jabber, но пока еще окончательно не решил действительно ли оно мне надо. Еще надо бы настроить голосовую почту, но вроде тоже пока не сильно актуально, вернусь из отпуска и будет ясно.

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

Прошу строго не судить. Если что то забыл указать пишите поправлю, так как последовательность действий описывал по памяти, мог чего ни будь и упустить. Так же, если старшие товарищи поделятся своими идеями или реализациями чего ни будь подобного то буду только рад.
Теги:diy или сделай самasterisklinuxvoipandroid
Хабы: Asterisk
+32
62,8k 453
Комментарии 51
Похожие публикации
Профессия Android-разработчик
14 декабря 202071 000 ₽SkillFactory
Android Developer. Basic
24 декабря 202070 000 ₽OTUS
Android Developer. Professional
24 декабря 202060 000 ₽OTUS
Administrator Linux. Professional
18 января 202180 000 ₽OTUS
Профессия Android-разработчик
25 января 202130 000 ₽Loftschool
Лучшие публикации за сутки