20.06.2017

Тестирование Kamailio и multidomain сертификата ssl

Как подключить к Камалио самоподписанный multidomain сертификат.

Как обычно источники: Статья 1, Статья 2

Смысл простой, я так понял это можно сделать добавив extensions в сертификат, а это в свою очередь определяется в файлике openssl.conf

Находим секцию REQ в openssl.conf проверяем, что x509_extensions не закомментирован:

[req]
...
x509_extensions = v3_ca

Затем добавляем секцию v3_ca и указываем в ней следующее:

[v3_ca]
...
subjectAltName = @alt_names
[alt_names]
DNS.1 = example.com
DNS.2 = www.example.com
DNS.3 = example.co.uk
DNS.4 = www.example.co.uk

У меня сработало и сертификат стал иметь несколько доменных зон, что крайне удобно когда использует DNS файловер.

Проверить, кстати, можно очень просто после создания запроса на сертификат, выполните

openssl req -text -noout -in <запрос_сертификата>.csr

И если увидите, что-то подобное, то можно генерировать сертификат.

Certificate Request:
    Data:
        Version: 0 (0x0)
        Subject: C=DE, ST=Germany, L=City, O=Company, OU=Organisation-Unit, CN=server1.example.com/emailAddress=alias@example.com
        Subject Public Key Info:
            Public Key Algorithm: rsaEncryption
            RSA Public Key: (4096 bit)
                Modulus (4096 bit):
[...]
                Exponent: 65537 (0x10001)
        Attributes:
        Requested Extensions:
            X509v3 Basic Constraints:
                CA:FALSE
            X509v3 Key Usage:
                Digital Signature, Non Repudiation, Key Encipherment
            X509v3 Subject Alternative Name:
                DNS:server1.example.com, DNS:mail.example.com, DNS:www.example.com
, DNS:www.sub.example.com, DNS:mx.example.com, DNS:support.example.com
    Signature Algorithm: sha1WithRSAEncryption
[...]

значит всё удалось.

16.06.2017

TLS. Kamailio. Asterisk. Настройка

Схема которую планировали реализовать:

Client1 —<TLS>— Kamailio —<UDP>— Asterisk —<UDP>— Kamailio —<TLS>— <Client2>

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

  1. Документация TLS модуля для Камалио 4.4 – прекрасно описывается как создать сертификат без получения и т.д.
  2. ssldump -Nn покажет обмен внутри протокола ssl кто кому какие сертификаты посылает
  3. howto kamailio and tls

Теперь непосредственно, то как работает TLS в двух словах.

  1. создать центра сертификации – CA
  2. подписать им сертификат для Камалио
  3. скопировать в подписанный сертификат приватный ключь, этот на всякий случай
  4. создать сертификат для sip-клиента
  5. скопировать приватный ключ в сертификат т.к. некоторые сип клиенты не имеют возможность для указания отдельно приватного ключа в настройках
  6. вынести конфигурацию tls в отдельный файл
  7. далее прописать в calist.pem сертификат CA. Это нужно чтобы камалио получив сертификат от клиента проверил его CA в своем списке и если СА в доверенных, то одобрить сертификат (при этом неважно откуда звонит клиент и какой домен (CN) указан в сертификате
  8. Повесить камалио на lts : listen:tls:ip_address:5061
  9. подключить к своему клиенту сертификат.
  10. клиент будет проверять сертификат поэтому, в виндоус нужно добавить в доверенные центры сертификации ваш сертификат CA, который вы создавали в самом начале.
  11. в сертификате Камалио обязательно должен быть указан CN соответствующий домену Камалио, либо его IP адресу если домена как такогово нет.
  12. В настройках камалио нужно оставить только verify_certificate = yes, require_certificate = no. Если поставить оба значения, то у меня ситуация выглядела так: Во время звонка при передаче ACK сообщения sip-клиент создавал новое соединение TLS и оно было отказывалось работать, потому, что не совпадали CN ожидаемые sip-клиентом и указанные в сертификате. Не стал разбираться дальше почему так происходит.

Настройка на данном этапе завершена, сертификат проверяется, т.е. использовать левый сертификат не получится.

15.06.2017

Восстановление базы MySQL из бинарных логов

Восстановление базы MySQL из бинарных логов
Простая статься на хабре, помогает быстренько восстановить утерянные insert в таблицы.

 

Восстановление базы данных из ib_logfile0

10.06.2017

SIPP Тестирование Asterisk

Решил провести тестирование Астериска на предмет максимального количества звонков.
Сразу скажу, у меня Астериск 1.4 и я просто посылаю на эхотест его, примеры эхотеста в астериска в sip.conf есть.

Чтобы провести тестирование нагрузки нам понадобится sipp

  1. yum install sipp
  2. копируем в локальный каталог сценарий с uac_pcap.xml из документации sipp
  3. копируем pcap файлы для астериск в каталог pcap текущей папки
  4. подбираем нужные параметры для sipp и должно работать

Здесь я опишу только 4 пункт:

в моем случае конфигурация рабочая выглядит так:

sipp -sf uac_pcap.xml -r 1 -mi 111.111.111.111 -i 111.111.111.111 -s 1005 222.222.222.222 -trace_msg -rtp_echo -d 5000

где
111.111.111.111 – внешний интерфейс вашей машины
222.222.222.222 – адрес астериска
1005 – номер для эхотеста
-d 5000 – пауза в 5 секунд (опционально)
и все погнали, в моей конфигурации сети, без особых проблем астериск успевает обслужить 50 вызовов в секунду и примерно 500 одновременных соединений, потом начинаются ретрансмиты сообщений.

9.06.2017

Memcached и ограничение соединений к нему

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

докопался до вот чего:

Огромное количество соединений к localhost остаются в состоянии time_wait в документации по memcached прекрасно сказано, что нужно проверить для увеличении производительности, а вот здесь был конкретный совет по поводу подвисших соединений:

Details of how to tune these variables are outside the scope of this document, but google for “Linux TCP network tuning TIME_WAIT” (or whatever OS you have) will usually give you good results. Look for the variables below and understand their meaning before tuning.

!THESE ARE EXAMPLES, NOT RECOMMENDED VALUES!
net.ipv4.ip_local_port_range = 16384 65534
net.ipv4.tcp_max_tw_buckets = 262144
net.ipv4.tcp_fin_timeout = 30
net.ipv4.tcp_tw_reuse = 1
net.ipv4.tcp_tw_recycle = 1

Я внес в систему только параметр net.ipv4.ip_local_port_range сделав его в два раза больше и дело пошло. Полезной оказалась статься про мониторинг memcached в частности утилита memcache-top и команда netstat которая показала кол-во еще ожидающих закрытия соединений.

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 вопросы
  • Безопасность
  • Городские номера
  • Готовые решения
  • Идеи
  • Проблемы в коде
  • Проблемы при настройке
  • Спорт
  • Гитара

 

3.02.2016

Ограничение вызовов для exten

Ограничение одновременных вызовов в Астериске . Смысл прост: Ищем каналы по выражению “116-” а потом считаем кол-во элементов в массиве.

same => n,GotoIf($[“${FIELDQTY(CHANNELS(${CALLERID(num)}-), )}” > “1”]?busy-custom,s,1)

3.02.2016

Asterisk. Annoucement. Dialplan. ChannelRedirect. Elastix. Part 2.

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

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

Итак, для начала скрипт АМИ, которым осуществляется вызов:

Action: Login
Username: admin
Secret: werkjnfgopw

 

Action: Originate
ActionID: 12345
Channel: Local/117@tapi
Context: agent-custom
Exten: 12122396200
Priority: 1

Ранее смысл решения основывался на том, чтобы сохранить внутренний номер телефона, привязать к нему имя правильного канала (то куда позвонили) и собственно воспроизвести в этот канал файлик с названием “extension_x”.

Для реализации у нас в  файле extension_custom.conf:

Этот контекст ловит определенный номер формата #*00x  и записывает приветствие в файлик “extension_x”. Тут все просто.

[custom-record] ; Context for recording voice messages
exten => _#*00X,1,Noop(${EXTEN})
same => n,Set(CHANNEL(language)=ru)
same => “”n,Set(MONITOR_FILENAME=${DIR}${CALLERID(num)}_${EXTEN:4})
same”” => n,Playback(beep)
same => n,Answer
same => n,Record(${MONITOR_FILENAME}:wav)
same => n,Playback(vm-msgsaved)
same => n,Playback(${MONITOR_FILENAME})
same => n,Playback(vm-goodbye)

этот макрос выполняется когда мы совершаем вызов вручную в функцию Dial встроен код ‘M^(testsub)’ делалось это прям через веб инфтерфейс Эластикса.

[macro-testsub]
exten => s,1,NoOp(${CHANNEL})
exten => s,n,NoOp(${MYVAR})
exten => s,n,Set(DB(br/${MYVAR})=${CHANNEL})
exten => s,n,NoOp(${DB(br/${MYVAR})})

Этот контекст должен вызываться когда с ext приходит команда ##X что означает, что ext хочет воспроизвести приветствие.

[transfer-context]
exten => “” _##X,1,NoOp(${DB(br/${CALLERID(num)})})
exten”” => “”_##X,2,Set(DB(from_ext/last_ext)=${CALLERID(num)})
exten”” => “”_##X,3,ChannelRedirect(${DB(br/${CALLERID(num)})},play-context,${EXTEN},1)
exten”” => _##X,4,Playback(${DIR}${CALLERID(num)}_${EXTEN:-1}) ;
exten => _##X,5,Hangup()

А Это вспомогательный контекст, в него мы перескакием, когда собственно случается событие приоритета 3 в transfer-context. До сих пор не понятно, почему нельзя передать переменную через channelredirect – приходит ее сохранять в DB затем извлекать…

[play-context]
exten => _##X,1,noop(${DB(from_ext/last_ext)})
exten => _##X,2,Playback(${DIR}${DB(from_ext/last_ext)}_${EXTEN:-1}) ;
exten => _##X,3,Set(DB(from_ext/last_ext)=”0″)
exten => _##X,4,Hangup()

 

Итак, при вызове функции AMI Originate как я описал выше, вызывается два пользователя: внутренний 116 например и внешний внутренний вызывается в контексте [tapi]

[tapi]

exten => 116,1,Answer
exten => 116,n,SIPAddHeader(Alert-Info: Ring Answer)
exten => 116,n,NoOp(Context: agent)
exten => 116,n,Dial(SIP/116)
exten => 116,n,hangup

а затем вызывается контекст [agent-custom]: Это все делает тот AMI скрипт. В подчеркнутых строчках сохранение переменной какой внутренний номер позвонил и вызов макроса dialer-dial, который…

exten => _1XXXXXXXXXX,1,Answer

exten => _1XXXXXXXXXX,n,NoOp(Context: agent)
exten => _1XXXXXXXXXX,n,noop(CALLERID: “””${CALLERID(all)})
exten””” => _1XXXXXXXXXX,n,NoOp(EXTEN: ${EXTEN})
exten => _1XXXXXXXXXX,n,noop(SIP_to: ${SIP_HEADER(TO)})
exten => _1XXXXXXXXXX,n,noop(SIP_from: ${SIP_HEADER(FROM)})
exten => _1XXXXXXXXXX,n,Set(__FROM_EXT=${CHANNEL(name)})
exten => _1XXXXXXXXXX,n,Dial(SIP/t1/991${EXTEN},60,r^M(dialer-dial))
exten => _1XXXXXXXXXX,n,noop(DIALSTATUS= ${DIALSTATUS})
exten => _1XXXXXXXXXX,n,gotoif($[“${DIALSTATUS}”= “BUSY”]?busy-custom,s,1)
exten => _1XXXXXXXXXX,n,gotoif($[“${DIALSTATUS}”= “CONGESTION”]?congestion-custom,s,1)
exten => _1XXXXXXXXXX,n,gotoif($[“${DIALSTATUS}”= “CHANUNAVAIL”]?congestion-custom,s,1)
exten => _1XXXXXXXXXX,n,gotoif($[“${DIALSTATUS}”= “NOANSWER”]?congestion-custom,s,1)
exten => _1XXXXXXXXXX,n,hangup

 

который… сохранит для нас связку внутреннего номера и канала который мы вызываем  в базу Астериска.

[macro-dialer-dial]

exten => s,1,NoOp(${FROM_EXT:6:3})
exten => s,n,Set(MYVAR_A=${FROM_EXT:6:3})
exten => s,n,Set(DB(br/${MYVAR_A})=${CHANNEL})