9.06.2017

Автозапуск Debian 6 и Centos 6.8

Запуск программ при старте Debian:

Добавление скрипта в автозагрузку:

Удаление скрипта из автозагрузки:

27.05.2017

О себе и реквизиты

Я рос хорошим мальчиком. Давным давно, работая в службе технической поддержки в небольшом интернет-провайдере, случилось так, что у моего коллеги не получилось настроить voip телефонию в компании и за дело взялся я. Это самая моя любимая работа разбираться в том, в чем я не разбираюсь. Если у меня появляется азарт в этом, то всё – ныряю с головой.

Так я начал работать с интернет-телефонией.

Нет нужды описывать мой жизненный путь, оно как правило ни к чему, только повздыхать да покритиковать стороннему наблюдателю – от чего я вас, дорогие друзья, избавлю.

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

И вот я уже не хочу тратить много времени на статью про себя, просто скажу работаю на компанию ООО “ЮКСИ”.

Реквизиты:

ООО «ЮКСИ»

sip: 74952284411@did.yooxy.ru

fb: facebook.com/erewin

Юр. Адрес: 454021, ул Молодогвардейцев д.58 оф.1

Почтовый адрес: 454902, ул. Гостевая 3, оф. 002

ОГРН 1127447003386

ИНН/КПП 7447206406/744701001

Директор Еремин Павел Сергеевич, действует на основании Устава.

Расчетный счет № 40702810590000016075

в ОАО «ЧЕЛЯБИНВЕСТБАНК»

БИК 047501779 ИНН 7421000200 КПП 745301001

Кор/счет 30101810400000000779

27.05.2017

Куда я попал?

Добро пожаловать в обновленную версию записной книжки voip-инженера.

Давно начал вести записи по поводу решений разных задач области ip-телефонии. И несмотря на то, что задача это достаточно занудна, лично для меня конечно, часто ей пользовался. Моя работа связана как правила с разными задачами, от программирования до развертывания нескольких серверов для телефонии.

Что можно здесь найти, в первую очередь конечно меня, как консультанта, но и заметки по решениям разных задач. Вот список рубрик в которых приходилось решать те или иные задачи и решения которых, находятся на старом адресе http://opensips-blog.yooxy.ru

  • Asterisk
  • SQL запросы
  • Unix вопросы
  • Безопасность
  • Городские номера
  • Готовые решения
  • Идеи
  • Проблемы в коде
  • Проблемы при настройке
  • Спорт
  • Гитара

 

16.08.2015

SOX. WAV. ASTERISK. BATCH. Конвертнуть файлы для астериска.

Привет!

Дали wavки для заливки на астериск, если честно понятия не имею что там и как устроено в астере, но Астериск сам предлоагает сервис для конвертации WAV файлов во все нужные ему форматы. при помощи CLI “file convert”.

1. WAV нужно преобразовать в 8000 Khz и 1 канал, делается это командой: “sox input.wav -c 1 -b 8000 outout.wav”

лично я не смог потратить время с делать одной командой конвертацию файлов в каталоге поэтому поступил тупейшим образом: ls -a *.wav

скопировал результат в файлик, там произвел замену при помощи регулярных выражений например из строчки: 1.wav я получил

sox  1.wav -r 8000 -c 1 new/1.wav

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

2.далее я создаю файлик с командами типа ” asterisk -x “file convert    transfering.wav           res/transfering.g729”

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

Кодеки должны присутствовать и быть активными конечно.

Бай.

4.06.2015

Opensips Ростелеком chel.media.usi.ru

Чтобы подключить услугу НЕОФОН от Ростелекома на Опенсипсе – необхоидмо выполнить несколько условий.

 

1. Ростелеком трЕбует:

FROM: sip: 7337788@chel.media.usi.ru

2. Исходящий звонок должен происходить обязательно с железки с которой была регистрация, вот рабочая версия для модуля registrant:

modparam(“uac_registrant”,”uac”, “sip:chel.media.usi.ru,,sip:7298171@chel.media.usi.ru,,7337788,PASSWORD,sip:7298171@123.123.123.123:5060,,,”)

3. при получении пакета 407 необходимо отсылать логин и пароль:

route[AUTHCHECK] {
if (t_check_status(“(401)|(407)”)) {

xlog(“got auth request from”);

if ( uri=~”sip:.+@chel.media.usi.ru” ) {
$avp(authrealm) = “Realm”;
$avp(authuser) = “7337788”;
$avp(authpass) = “PASSWORD”;
}

}

failure_route[2] {
xlog(“second failure route”);
uac_auth();
route(AUTHCHECK);

}

10.04.2015

Тестирование максимальной пропускной способности A2Billing.

1. Абонента А – Opensips – Media2 – Абонент B (600)

Тестирование проводится командой sipp. Необходимо поправит скрипт, для того, чтобы sipp работал c opensips. Заставить работать ту версию, что поставке – никак не смог.

/sipp   -default_behaviors abortunexp -s 600 -sf uac_pcap.xml sip.fiberpipe.in -r 10 -trace_err

 

Первая Проблема была традиционной: ограничение на кол-во открытых файлов в системе.

Вторая проблема касалась того, что Mysql для таких систем должен стоять либо в памяти либо на SSD.

Третья проблема касалась ограничения кол-ва поключений к Mysql.

Вытекающие проблемы: надо делать для Mysql репликацию из памяти на HDD.

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

 

Сценарий для sipp:

<?xml version=”1.0″ encoding=”ISO-8859-1″ ?>
<!DOCTYPE scenario SYSTEM “sipp.dtd”>

<!– This program is free software; you can redistribute it and/or –>
<!– modify it under the terms of the GNU General Public License as –>
<!– published by the Free Software Foundation; either version 2 of the –>
<!– License, or (at your option) any later version. –>
<!– –>
<!– This program is distributed in the hope that it will be useful, –>
<!– but WITHOUT ANY WARRANTY; without even the implied warranty of –>
<!– MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the –>
<!– GNU General Public License for more details. –>
<!– –>
<!– You should have received a copy of the GNU General Public License –>
<!– along with this program; if not, write to the –>
<!– Free Software Foundation, Inc., –>
<!– 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA –>
<!– –>
<!– Sipp ‘uac’ scenario with pcap (rtp) play –>
<!– –>

<scenario name=”UAC with media”>
<!– In client mode (sipp placing calls), the Call-ID MUST be –>
<!– generated by sipp. To do so, use [call_id] keyword. –>
<send retrans=”500″ >
<![CDATA[

INVITE sip:[service]@[remote_ip]:[remote_port] SIP/2.0
Via: SIP/2.0/[transport] [local_ip]:[local_port];branch=[branch]
From: 9415601662 <sip:9415601662@[local_ip]:[local_port]>;tag=[call_number]
To: sut <sip:[service]@[remote_ip]:[remote_port]>
Call-ID: [call_id]
CSeq: 1 INVITE
Contact: sip:sipp@[local_ip]:[local_port]
Max-Forwards: 70
Subject: Performance Test
Content-Type: application/sdp
Content-Length: [len]

v=0
o=user1 53655765 2353687637 IN IP[local_ip_type] [local_ip]
s=-
c=IN IP[local_ip_type] [local_ip]
t=0 0
m=audio [auto_media_port] RTP/AVP 8
a=rtpmap:8 PCMA/8000
a=rtpmap:101 telephone-event/8000
a=fmtp:101 0-11,16

]]>
</send>

<recv response=”100″ optional=”true”>
</recv>

<recv response=”180″ optional=”true”>
</recv>

<!– By adding rrs=”true” (Record Route Sets), the route sets –>
<!– are saved and used for following messages sent. Useful to test –>
<!– against stateful SIP proxies/B2BUAs. –>
<recv response=”200″ rrs=”true” rtd=”true” crlf=”true”>
</recv>

<!– Packet lost can be simulated in any send/recv message by –>
<!– by adding the ‘lost = “10”‘. Value can be [1-100] percent. –>
<send>
<![CDATA[

ACK [next_url] SIP/2.0
Via: SIP/2.0/[transport] [local_ip]:[local_port];branch=[branch]
From: 9415601662 <sip:9415601662@[local_ip]:[local_port]>;tag=[call_number]
To: sut <sip:[service]@[remote_ip]:[remote_port]>[peer_tag_param]
Call-ID: [call_id]
CSeq: 1 ACK
Contact: sip:sipp@[local_ip]:[local_port]
Max-Forwards: 70
Subject: Performance Test
Content-Length: 0

]]>
</send>

<!– Play a pre-recorded PCAP file (RTP stream) –>
<nop>
<action>
<exec play_pcap_audio=”pcap/g711a.pcap”/>
</action>
</nop>

<!– Pause 8 seconds, which is approximately the duration of the –>
<!– PCAP file –>
<pause milliseconds=”12000″/>

<!– The ‘crlf’ option inserts a blank line in the statistics report. –>
<send retrans=”500″>
<![CDATA[

BYE [next_url] SIP/2.0
Via: SIP/2.0/[transport] [local_ip]:[local_port];branch=[branch]
[routes]
From: 9415601662 <sip:9415601662@[local_ip]:[local_port]>;tag=[call_number]
To: sut <sip:[service]@[remote_ip]:[remote_port]>[peer_tag_param]
Call-ID: [call_id]
CSeq: 2 BYE
Contact: sip:sipp@[local_ip]:[local_port]
Max-Forwards: 70
Subject: Performance Test
Content-Length: 0

]]>
</send>

<recv response=”200″ crlf=”true”>
</recv>

<!– definition of the response time repartition table (unit is ms) –>
<ResponseTimeRepartition value=”10, 20, 30, 40, 50, 100, 150, 200″/>

<!– definition of the call length repartition table (unit is ms) –>
<CallLengthRepartition value=”10, 50, 100, 500, 1000, 5000, 10000″/>

</scenario>

10.09.2014

uac_auth cseq increase Решение solve

Авторизация при помощи uac_auth имеет недостаток.
Она не генерирует новый CSEQ. в результате чего некоторые девайсы орут мол закольцовка . Loop Detected.

Решение было найдено из документации и выглядит оно мягко говоря не очень, особенно если нарисовать схему:

А -> Proxy1 -> b2b -> Proxy1 -> sbc.megafon.ru.

Почему нужно посылать звонок обратно в прокси, а не сразу в мегафон?
Да можно сразу в Мегафон, вот только инфу о таком звонке вы потеряете. Более того, вы не сможете сделать фейловер для Мегафона.

После того как я посмотрел на это решение, меня охватило уныние ибо не красиво. Взялся за третий способ и вот он-то и привел к желаемому результату. Хотя для этого используется стороннее ПО: SEMS все же этот SEMS очень хороший инструмент для opensips.

1. Способ описанный в письме Богданом: http://opensips.org/pipermail/users/2010-January/010215.html

> I’m trying to authenticate a UAC phone with a third party SIP to
> PSTN gateway, while having OpenSIPS in between. The gateway rejects
> repeated INVITEs with the same cseq number. The situation is quite
> typical, so I’m sure that OpenSIPS provides a way to solve this
> problem, no?
>
OpenSIPS itself no (as said, it cannot change elements that are defining
the dialog). But you may try a trick – when you receive the auth request
from the GW, ask the caller again for auth (from opensips), so that the
caller will generate a new proper INVITE you can use for auth. Shortly,
instead of the generating the second INVITE on opensips, force the
client (in whatever way) to generate it (to have proper cseq) and you
simply attach the credentials to the new INVITE when sending it to
GW…..just an idea, never tried it 🙂

В этом способе говорится о том, точбы заставить UAC отправить новый invite и пофиг каким способом это вы сделаете. Я этого способа не нашел, наверняка он очень простой.

2. Способ использовать b2b_uac. Но здесь возникает вопрос, а сможет ли вообще b2b Это сделать. Будем проверять….
способ оказался рабочий, но остается проблема с медиа_прокси.

Пока разбирался как работают сценарии, оказалось, что необходимый нам сценарий крайне прост. Прям вот вообще, выглядит так:

<scenario id=”b2b_test” name=”MS start and end” param=”1″ type=”script”>
<init>
<bridge>
<server>
<id>server1</id>
</server>

<client>
<id>client1</id>
<type>message</type>
<destination>
<value type=”param”>1</value>
</destination>
</client>

</bridge>
<state>1</state>
</init>

</scenario>

приведу выедржку из конфига:

loadmodule “b2b_entities.so”
loadmodule “b2b_logic.so”

modparam(“b2b_entities”, “db_mode”, 0)
modparam(“b2b_entities”, “script_req_route”, “b2b_request”) #request recieved
modparam(“b2b_entities”, “script_reply_route”, “b2b_reply”) #reply recieved
modparam(“b2b_logic”, “db_mode”, 0)
modparam(“b2b_logic”, “script_scenario”, “/usr/sipcolor/etc/opensips/b2b_test.xml”)

3. Работа с SEMS я решил скачать исходники 1.5 и скомпилировать только то что мне нужно, а именно CORE и SBC приложение.

Работа по компиляции уперлась в недостающие библиотеки, которые в принципе были легко установленны. На одной из систем возникла ошибка при компиляции исполняемого файла: pthread_cancel.

лечится добавлением ключа -pthread к компилятору. в Makefile.defs.

Всегда устанавливаю приложения в свои папки типа /usr/isp через префикс “make prefix=/usr/isp”. Так очень удобно искать файлы самого приложения.

 

UDP: в коде SEMS плагине uac_auth есть проверка на метод шифрования проверяется на MD5 и если вам прровайдер пришлет в нижнем регистре буквы md5 то хрен вам а не авторизация. патчится легко в файлике модуля.

Итак установили. Ниже приведу выдержки из трех файлов sems.conf, sbc.conf, auth_b2b.sbcprofiles.conf

 

sems.conf: Здесь главное указать какое приложение запускать я указал sbc.


# example for announcement with only g711 and ilbc codecs
# load_plugins=wav;ilbc;announcement
load_plugins=wav;isac;l16;gsm;ilbc;uac_auth;sbc

# examples:
# application = conference
# application = $(mapping)
# application = $(ruri.user)
# application = $(ruri.param)
# application = $(apphdr)
application = sbc

sbc.conf: необходимо указать профайлы для приложения sbc.

# profiles – comma-separated list of call profiles to load
#
# .sbcprofile.conf is loaded from module config
# path (the path where this file resides)
profiles=auth_b2b

# active call profile – comma separated list, first non-empty is used
#
# o active_profile=<profile_name> always use <profile_name> #
# o active_profile=$(ruri.user) use user part of INVITE Request URI
#
# o active_profile=$(paramhdr) use “profile” option in P-App-Param header
#
# o any replacement pattern
#
active_profile=auth_b2b

auth_b2b.sbcprofiles.conf: настройка самого модуля авторизации, кстати этот модуль на данный момент имеет ограничение: в него нельзя передать прокси сервер, если вам нужно иметь разные домен и прокси куда посылать запрос. next_hop можно указать только один. в связи с этим для авторизации на двух провайдеров придется пока запустить две копии SEMS.

UDP: посылается звонок на разных провайдеров очень просто, active_profile указывается $M($rU=>ruri_map),refuse , где ruri_map файлик соответствий номера с диалпланом, также можно сделать файлик соответствий IP входящего звонка и т.д. очень, очень гибко усе.


RURI=sip:$rU@todomain.ru
#From=””$P(u)” <sip:$P(u)@$P(d)>”
#To=””$rU” <sip:$rU@$P(d)>”

From=”<sip:name@fromdomain.ru>”
To=”<sip:$rU@todomain.ru>”

## routing
# outbound proxy:
#outbound_proxy=sip:79.170.27.75:5067
# force outbound proxy (in-dialog requests)?
#force_outbound_proxy=yes
# destination IP[:port] for outgoing requests
next_hop=proxy.forauth.ru

enable_auth=yes
auth_user=”02345234524″
auth_pwd=”1PвапрвапрвапрlX”

Запуск SEMS командой: /usr/isp/sbin/sems -f /usr/isp/etc/sems/sems.conf

и смотрим syslog для анализа того что происходит во время вызова, кстати, лог у SEMS просто отличный!

25.07.2014

Load Balancing SIP

UAC – > LB -> (PROXY1 | PROXY2 | … ) -> UAS

Задача: раскидать звонки между sip proxy, сначала на PROXY1, в случае его недоступности на PROXY2.

В идеале если хочется распределять нагрузку между несколькими прокси серверами, то нужно делать LB  в режиме stateless (использовать функцию forward() совместо с модулем dispatcher) однако в таком случае нет возможности сделать failover в случае падения одного из проксей, т.к. response нельзя поймать в отдельный блок. (хотя возможно разместив код в разделе onreply_route… надо будет проверить).

Сначала учтем ситуацию что в сообщении уже содержится route и вызовем функцию loose_route. без нее вы рискуете на некоторых звонках, это зависит от вашего окружения, получить зацикливание сообщений ACK. Нужно обязательно проверить, чтобы loose вызывался для ACK сообщений и участвующих в диалоге, а не для первых сообщений в диалоге, т.к. это может привести к пробеганию через ваш прокси трафика на чужие сервера, либо на поставщиков услуг, что страшнее, т.к. это сразу минус бабки.

Ниже представлен конфиг:

request_route {
if (loose_route()) {                                                #Если сообщение содержит Route: то функция выдаст 1. Если его там нет, то 0. Здесь мы проверяем, есть ли в сообщении Route и если да, то…
xlog(“L_INFO”,”ACK TRansported…”);   #Выводим в лог любую хрень полезную для понимания
t_relay();                                                                 #Оправляем сообщение согласно этому заголовку Route. 
exit;                                                                            #Завершаем выполнение скрипта, т.к. больше LB делать ничего не надо. 
}

if (!ds_select_domain(“1”, “8”))                   # Здест мы пользуемся функцией которая выберет для нас адрес прокси (proxy1) и подставит его в URI (первая строчка в SIP сообщении)
{
xlog(“L_ALERT”,”404 No route $ru”); # ВЫводим в лог сообщение елси ни один из проксей не доступен.
send_reply(“404″,”No route”);                  #Посылаем “клиенту” 404 сообщение, мол, нет возможности отправить вызов.
exit;                                                                          # Завершаем скрипт
} else {
t_on_failure(“RTF_DISPATCH”);            # Если таки прокси для сообщения определен, то привязываем ответ к разделу “RTF_DISPATH”, там мы поймаем ответ, и если он говорит о проблеме с прокси, то                                                                                             отправим сообщение на другой прокси.
 xlog(“L_ALERT”,”Passed dispatcher $ru via $du $rm”);   # Запишем в лог информацию о том, что сообщение будет отправленно на $ru.(при вызове функции ds_select_domain $ru меняется на новый
route(RELAY);                                                      # собственно отправляем сообщение в раздел где оно отправится к $ru.
}
}

 

 

2.04.2013

Userblacklist / GlobalBlack list

Реализация Чернго и белого списка на opensips.

Достаточно триавиальная задача, но есть несколько ньюансов,прежде всего нужно понять по какой схеме мыбудемблокировать польователя, они могут быть разными. Мне нужно было реализовывать черные и белые списки относительно входящих звонков на номера,поэтому логика такая:

1) проверка набранного номера на наличие в глобальном блэклисте, Если есть то смерть, если нет,то далее….

2) проверим пользовательский черный список, если набранный номер есть, то проведем сверку с колонкой prefix поля from, и в зависимости от значения whitelist либо дадим звонку идти дальше либо выставим запрет.

сам код:

### Глобальный Черный список
if (!check_blacklist(“globalblacklist”)) {
xlog(“For $ru globalblack list Active…”);
$avp(is_in_blacklist) = “1”;
sl_send_reply(“403”, “Forbidden BlackListed”);
exit;
}

if (!check_user_blacklist(“$rU”, “$fd”, “$fU”)) {
sl_send_reply(“403”, “Forbidden BlackListed”);
xlog(“User Black listed $fu -> $ru”);
exit;
} else {
xlog(“User white list active for $fu to $rU”);
}

Обратите внимание на параметры к функции check_user_blacklist . Изменен порядок, так чтобы пользователем являлся набранный номер, а префикс применялся к АОНу т.е. номеру звонящего или проще говоря полю FROM.

Для понимания ссылка на то как выгядит сам список.