Архив автора: provoip

Об авторе provoip

Кролики - это не только ценный мех, но и полтора-два килограмма диетического, легкоусвояемого мяса (с)

FreeBSD: Работа с коллекцией портов

http://pro-voip.com.ua freebsd

Скачать и распаковать коллекцию портов (утилита portsnap):

portsnap fetch extract

-данная команда выполняется один раз после установки свежей ОС, если в процессе установки вы не отметили галочкой установку портов сразу; либо если вы потерли каким-то образом свою коллекцию портов. В последующем же, чтобы установить порт, достаточно выполнить три действия:

1. Обновить коллекцию портов:

portsnap fetch update

2. Найти нужный порт:

cd /usr/ports
make search name=rkhunter

3. Установить нужный порт:

cd /usr/ports/security/rkhunter
make install clean

 

Вся коллекция портов находится в /usr/ports. Все приложения, описаные в коллекции портов, сгруппированы в категории (databases, deskutils, net-mgmt и т.д.).

 

Поиск

Поиск необходимого порта по имени (ищет совпадения в названии порта). Команда выполняется в директории /usr/ports:

make search name=rkhunter

Поиск порта по описанию (ищет совпадения и в названии и в описании порта, полезно, если не помнишь, как приложение называется, но помнишь хоть примерно, что оно должно делать или с чем оно связано). Команда выполняется в директории /usr/ports:

make search key=hunter

 

Описание порта

Пример, порт /usr/ports/security/rkhunter

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

  • Makefile — содержит базовые команды и настройки для сборки порта. Здесь же и указывается (в переменной MASTER_SITES=), откуда скачивать исходники (src) приложения . Исходники приложения представляют собой сжатый архив с необходимыми src-файлами для сборки и установки.
  • distinfo — содержит контрольные суммы для файлов, которые скачиваются при сборке порта. Таким образом производится проверка на целосность.
  • files — директория содержит дополнительные патчи и исправления, которые в ходе сборки приложения накладываются на разархивированные исходники.
  • pkg-descr — описание приложения
  • pkg-message — содержит сообщения, адресованое от разработчиков администратору. В нем может указываться поздравление с установкой, необходмые дальнейшие шаги после установки, рекомендации и т.д. Файл pkg-message необязателен.
  • pkg-plist — перечень файлов, которые плодит устанавливает порт в системе.
  • В процессе сборки в директории порта создается рабочая директория work.

 

Описание процесса установки приложения с порта

  1. Конфигурирование опций порта
  2. Загрузка архива с исходными файлами приложения
  3. Проверка загруженых файлов на наличие ошибок
  4. Извлечение исходных файлов с архива в рабочую директорию
  5. Наложение патчей с директории files, если такое имеются и необходимы
  6. Проверка и установка зависимостей
  7. Запуск сценария configure, если такой есть в приложении
  8. Сборка приложения из исходных файлов
  9. Установка приложения (копирование скомпилированных бинарников, файлов конфигурации и т.п. в необходимые места в файловой системе — а что это за файлы и в какие необходимые места, описано в  pkg-plist)
  10. Регистрация приложения в /var/db/pkg — да, у нас получился обыкновенный пекедж.

 

Другие команды

Команды выполняются в директории порта. «make install clean» запускает поочередно цикл команд, которые проводят через все этапы установки приложения, описаные выше. При необходимости можете запускать эти команды вручную. Например, если вам нужно только собрать, но не устанавливать приложение, используем «make build«, который выполнит с 1 по 8-й пункты (см. описание процесса выше). Если нужно только скачать исходники, используем «make fetch«.

make config
— конфигурирование порта — если есть опциональные параметры, или дополнительные модули, здесь их можно включить/исключить.

make config-recursive
— конфигурирование порта и его зависимостей. Процесс сборки бывает длительным, и зависимостей бывает много. Для того чтобы перед установкой зависимостей каждый раз процесс не прерывался и не ждал от вас решения установить те или иные параметры для зависимостей, хорошо сразу все сконфигурить и оставить приложение собираться в одиночку.

make showconfig
— посмотреть, какие параметры выбраны.

make rmconfig
— удалить выставленные пользователем параметры, т.е. сбросить конфиг в дефолт — отмеченные изначально останутся отмечеными, отмеченные пользователем — удаляются.

make fetch
— загрузка архива с исходниками.

make fetch-recursive
— загрузка архивов с исходниками порта и зависимостей.

Откуда загрузка? — указано в Makefile в переменной MASTER_SITES=. Путей может быть несколько.
Куда загружаются исходники? — в /usr/ports/distfiles

make checksum
— проверка целосности скачаного архива с исходными файлами приложения

make extract
— извлечение скачаного архива — директории порта создается рабочий каталог work, куда и извлекаются исходники.

make patch
наложение или накладывание? Применение патчей с директории files.

make depends
— проверка зависимостей.

make configure
— если в приложении есть свой сценарий configure, он выполняется

make build
— компиляция кода.

make install
— установка приложения и регистрация его в /var/db/pkg.

make clean
— удаление рабочей директории work (архив с исходниками остается в /usr/ports/distfiles).

make distclean
— удалить архив с исходниками.

 

Источники информации

https://www.freebsd.org/doc/handbook/ports-using.html
http://freebsdguide.ru/_11/_6/

Freeswitch: Подключение к SIP-серверу провайдера

Подключение к оператору (провайдеру) связи производится через секцию <gateways> sip-профиля. Каждый gateway в секции <gateways> определяет одну регистрацию на сервере оператора. В дефолтном конфиге FS предлагает для таких вот внешних регистраций использовать sip-профиль external, описаный в файле external.xml. В дополнение к файлу external.xml подключается директория external, в котором в каждом xml-файле описан один gateway (вообще, такое деление на мелкие файлы мне лично кажется удобным для администрирования — удобно смотреть, редактировать, добавлять, удалять).

В этой статье я хочу описать несколько вариантов подключения FS к операторам/провайдерам связи. Это не все варианты — на страницах документации freeswitch.org можно найти больше примеров.

 

1. Регистрация Freeswitch по логину и паролю — один аккаунт у одного провайдера

В данном случае username, используемый для регистрации, является и нашим номером — 5555555, — на который мы будем принимать звонки, и номером, с которого мы будем звонить через этот gateway — поле From тоже будет 5555555. Регистрация будет происходить на сервере 192.168.100.100 — ip-адрес сервера прописан в gateway name.

 

2. Регистрация Freeswitch по логину и паролю — несколько аккаунтов у одного провайдера

Для того, чтобы зарегистрировать пару аккаунтов на одном и том же sip-сервере, нужно создать два отдельных gateway c разными названиями (name) —  при этом name не должен быть ip-адресом либо доменным именем, просто произвольное слово, например, gateway1 и gateway2, — а реальный ip-адрес сервера необходимо прописать в  параметре realm.

 

3. Регистрация Freeswitch по логину и паролю, один номер, username для регистрации отличается от номера

Параметр from-user используется для установки поля From при исходящих вызовах через данный gateway, параметр extension — для установки поля To при входящих вызовах с gateway. Если эти параметры явно не указать, по умолчанию применится значение username — user1 и, логично, вызовы с/на 5555555 проходить не будут.

 

4. Регистрация Freeswitch по логину и паролю, несколько номеров в одном аккаунте (построение транка с регистрацией)

Параметр caller-id-in-from позволяет каждому абоненту звонить со своим параметром From. Для этого в диалплане в extension, который описывает исходящий вызов через этот внешний gateway, нужно в переменную effective_caller_id_number подставить значение реального номера.

Например, есть абонент с внутренним номером 11, который при звонке «в город» должен звонить с номера 5555557. Прописываем в переменную абонента outbound_caller_id_number значение 5555557:

И прописываем в диалплане extension, в котором effective_caller_id_number подменяется значением переменной outbound_caller_id_number:

 

5. Подключение Freeswitch к провайдеру без регистрации

Просто ставим register=false и FS не будет отправлять запросы REGISTER к провайдеру. Обратите внимание, что username и password все равно должны присутствовать.

 

Зависимость значений некоторых параметров друг от друга в описании gateway

freeswitch gateway parameters

gateway name — обязательно нужно указывать. Параметр realm, если не указано другое, принимает значение gateway name. Параметр from-domain, если не указано другое, принимает значение realm и т.д.

Телефонный план нумерации Украины

Международный телефонный код Украины — 380.
Чтобы позвонить извне в Украину, набираем 380-yy-xxx-xx-xx

xxx-xx-xx — 7 цифр — звонки по фиксированной связи в пределах города
0-yy-xxx-xx-xx — 10 цифр — звонки в пределах Украины
00-код страны-код города-абонентский номер — звонки с Украины зарубеж

00 — выход на международные линии
0 — выход на междугородние линии или на мобильного оператора
yy — код мобильного оператора, или города, или области
xxx-xx-xx — 7-значный номер абонента

  • 010 — коды альтернативного выбора междугородней/международной фиксированной телефонной связи
  • 0100 — dial-up
  • 031, 032, 033, 034, 035, 036, 037, 038, 041, 043, 044, 045, 046, 047, 048, 051, 052, 053, 054, 055, 056, 057, 061, 062, 064, 065, 069 — список телефонных кодов областей Украины
  • 050, 063, 066, 067, 068, 073, 091, 092, 093, 094, 095, 096, 097, 098, 099 — список кодов мобильных операторов Украины
  • 0700 — код услуги персонального номера
  • 0800 — «бесплатные» горячие линии — платит получатель вызова
  • 089 — SIP-телефония Украины
  • 0900 — платные линии

 

Телефонные коды областей Украины
КодОбласть
31-xxx-xx-xxЗакарпатская область
32-xxx-xx-xxЛьвовская область
33-xxx-xx-xxВолынская область
34-xxx-xx-xxИвано-Франковская область
35-xxx-xx-xxТернопольская область
36-xxx-xx-xxРовенская область
37-xxx-xx-xxЧерновицкая область
38-xxx-xx-xxХмельницкая область
41-xxx-xx-xxЖитомирская область
43-xxx-xx-xxВинницкая область
44-xxx-xx-xxКиев город
45-xxx-xx-xxКиевская область
46-xxx-xx-xxЧерниговская область
47-xxx-xx-xxЧеркасская область
48-xxx-xx-xxОдесская область
51-xxx-xx-xxНиколаевская область
52-xxx-xx-xxКировоградская область
53-xxx-xx-xxПолтавская область
54-xxx-xx-xxСумская область
55-xxx-xx-xxХерсонская область
56-xxx-xx-xxДнепропетровская область
57-xxx-xx-xxХарьковская область
61-xxx-xx-xxЗапорожская область
62-xxx-xx-xxДонецкая область
64-xxx-xx-xxЛуганская область
65-xxx-xx-xxКрым АР - отключено 2015 г.
69-xxx-xx-xxСевастополь город - отключено 2015 г.

 

Телефонные коды мобильных операторов Украины
КодМобильный оператор
39-xxx-xx-xxGolden Telecom
50-xxx-xx-xxМТС Украина
63-xxx-xx-xxАстелит (он же Life:))
66-xxx-xx-xxМТС Украина
67-xxx-xx-xxКиевстар
68-xxx-xx-xxКиевстар (бывший Beeline)
73-xxx-xx-xxАстелит (он же Life:))
91-xxx-xx-xxТримоб (ТМ от Укртелеком)
92-xxx-xx-xxТЕЛЕСИСТЕМЫ УКРАИНЫ (они же PEOPLEnet)
93-xxx-xx-xxАстелит (он же Life:))
94-xxx-xx-xxИнтернациональные телекоммуникации (он же Интертелеком)
95-xxx-xx-xxМТС Украина
96-xxx-xx-xxКиевстар
97-xxx-xx-xxКиевстар
98-xxx-xx-xxКиевстар
99-xxx-xx-xxМТС Украина

 

SIP телефонные коды Украины
Код услугиНомерОператор
89SIP
89089-0xx-xx-xx--- не распределено
89189-1xx-xx-xxДатагруп
89289-2xx-xx-xxУкртелеком
89389-3xx-xx-xxТ.Р.Комьюникейшн
89489-4xx-xx-xxАтлантис Телеком
89589-5xx-xx-xxЛинком 3000
89689-6xx-xx-xx--- не распределено
89789-7xx-xx-xxКиевстар
89889-8xx-xx-xx--- не распределено
89989-9xx-xx-xxВелтон.Телеком

 

Другие телефонные коды Украины
Код услугиНомерОператор
10Коды альтернативного выбора сети междугородней фиксированной телефонной связи
10-23x-xx-xxДатагруп
10-93x-xx-xxАстелит (он же Life:))
10Коды альтернативного выбора сети международной фиксированной телефонной связи
10-23x-xx-xxДатагруп
10-33x-xx-xxФарлеп-Инвест
10-50x-xx-xxУкртелеком
10-93x-xx-xxАстелит (он же Life:))
100Код услуги выхода с сети ТФОП в сеть Интернет (dial-up)
100-50-xx-xxУкртелеком (dial-up)
700Код услуги персональных номеров
700-90-xx-xxИнтернациональные Телекоммуникации
800Бесплатные горячие линии.
Коды глобальной услуги "Вызов за счет абонента, который вызывают"
800-10-xx-xxВелтон.Телеком
800-20-xx-xxАстелит (он же Life:))
800-21-xx-xxДатагруп
800-30-xx-xxКиевстар
800-40-xx-xxМТС Украина
800-50-xx-xxУкртелеком
800-60-xx-xxФарлеп-Инвест
800-75-xx-xxИнтернациональные Телекоммуникации
800-80-xx-xxТ.Р.Комьюникейшн
900Платные линии. Коды глобальной услуги "С распределением прибыли"
900-23-xx-xxАудиотекс
900-25-xx-xxТ.Р. Комьюникейшн
900-26-xx-xxЕвроинформ
900-30-xx-xxУкртелеком
900-31-xx-xxДатагруп
900-32-xx-xxЕвро-Информ
900-33-xx-xxФарлеп-Инвест
900-90-xx-xxМикроком

 

Default settings

Чтобы долго не искать… Таблица дефолтных настроек для различного сетевого оборудования (будет заполняться постепенно)

Названиеdefault ip addressdefault login/passwordПримечания
Dlink DGS-1100-06/ME10.90.90.90/8admin/пустой пароль

 

Freeswitch: Dialplan. Conditions

http://pro-voip.com.ua freeswitch

Multiple Conditions (Logical AND)

Действие выполняется, когда все условия выполняются.

<condition field="destination_number" expression="^500$"/>
<condition wday="1">
    action(s)...
</condition>

— здесь action выполняется только если destination_number=500 и день недели — воскресенье. Если хоть одно из условий вернет false, Freeswitch перейдет к anti-action, а если anti-action не задан, то к следующему extension.

 

Nested Conditions — вложенные условия

require-nested  важный атрибут в nested conditions. Этот атрибут определяет, должно ли вложенное условие (sub-condition) вернуть значение true, чтобы выполнился action в родительском условии (top-level condition). Принимает значения: true или false;
Default: require-nested=true.

Если require-nested=true — sub-condition тоже должно вернуть true или иметь параметр break=never, чтобы выполнился action в родительском condition. При этом выполняются action, определенные и в sub-condition, и в top-level condition — и именно в таком порядке — сначала выполняются все action во всех sub-condition, а только потом все action в top-level condition (порядок записи не играет роли — даже если сначала записан action, а потом описан sub-condition).

! Обрабатываются сначала вложенные condition

Если require-nested=false — то неважно, что вернет sub-condition, action в родительком condition в любом случае выполнится.

 

break — флаг condition —  при каком результате проверки условия остановить обработку данного extension и перейти к следующему extension. Принимает значения: on-false, on-true, never;
Default: break=on-false;

break можно указывать в цепочке из условий, например, при создании логики Logical AND.

break применяется и в nested conditions (sub-condition). В обычной работе без указания данного флага (при require-nested=true и break=on-false — это дефолтные значения), если первый sub-condition возвращает false, то следующий (sub)-condition (если он есть) уже не проверяется, и в целом работа с данным extension прекращается и парсится уже следующий extension.

Так вот, если указать в первом sub-condition break=never, то даже если он вернет false, следующий за ним sub-condition проверяться будет!

 

Пример:

в top-level condition указан require-nested=false — результат проверки вложенных условий не повлияет на выполнение action в родительском condition); в sub-condition’ах указан флаг break=never — не прерывать выполнение всего extension, разрешить проверку следующих condition.

<extension name="nested_example">
  <condition field="destination_number" expression="^1234$" require-nested="false">
    <action application="log" data="INFO I'm before the nested conditions..."/>

    <condition field="${foo1}" expression="bar1" break="never">
      <action application="log" data="INFO foo1 is bar1" />
    </condition>

    <action application="log" data="INFO I'm in between the nested conditions..."/>

    <condition field="${foo2}" expression="bar2" break="never">
      <action application="log" data="INFO foo2 is bar2" />
    </condition>

    <action application="log" data="INFO I'm after the nested conditions..."/>

  </condition
</extension>

Для чего break=never для второго sub-condition? Ведь после него больше sub-condition нет. Да, но после второго sub-condition еще есть top-level condition, ведь проверка условий будет выполняться в следующем порядке: sub-condition 1, sub-condition 2, top-level condition — сначала по порядку все вложенные, и только потом родитель.

В итоге после выполнения данного extension у нас в логах будут записи в такой очередности:

<action application="log" data="INFO foo1 is bar1" />
<action application="log" data="INFO foo2 is bar2" />
<action application="log" data="INFO I'm before the nested conditions..."/>
<action application="log" data="INFO I'm in between the nested conditions..."/>
<action application="log" data="INFO I'm after the nested conditions..."/>

 

Multiple Conditions (Logical OR, XOR)

Логическое ИЛИ — action выполняется, если хоть одно из условий возвращет true.

Если ИЛИ нужно организовать для одного поля, т.е. смотрим только на одну переменную, то можно воспользоваться следующей конструкцией:

<condition field="destination_number" expression="^501|502$">
    action(s)...
</condition>

— action будет выполнен, если destination_number 501 ИЛИ 502.

Если ИЛИ для разных полей, используется regex.

<condition regex="all|any|xor">
  <regex field="some_field" expression="Some Value"/>
  <regex field="another_field" expression="^Another\s*Value$"/>
  <action(s) ...>
  <anti-action(s)...>
</condition>

regex может иметь следующие значения:

  • all — logical AND — все условия должны вернуть true, чтобы выполнилось action;
  • any — logical OR — хотя бы одно из условий должны возвратить true, чтобы выполнилось action;
  • xor — logical XOR — только одно условие должно возвратить true, чтобы выполнилось action;

 

Комплексный пример — маршрутизация по времени (time-based routing):

Пользователь звонит на extension 1100. Вызов перенаправляется на extension 1105 с понедельника по четверг с 8:00 до 21:59. В пятницу звонок перенаправляется на 1105 с 8:00 до 12:59. Во все остальное время вызовы перенаправляются в голосовую почту.

<extension name="Time-of-day-tod">
    <!--если это условие false, FreeSWITCH переходит к следующему *extension*.-->
    <condition field="destination_number" expression="^1100$" break="on-false"/>

    <!-- Если это условие возвращает true, следующее уже не проверяем-->
    <condition wday="6" hour="8-12" break="on-true">    <!--пятница с 8 до 12:59 -->
        <action application="transfer" data="1105 XML default"/>
    </condition>

    <condition wday="2-5" hour="8-21" break="on-true">   <!--понедельник-четверг с 8 до 21:59-->
        <action application="transfer" data="1105 XML default"/>
    </condition>

    <condition> <!-- перенаправление в голосовую почту в остальное время -->
        <action application="voicemail" data="default ${domain} 1105"/>
    </condition>
</extension>

— в первом condition в данном примере можно было и не указывать break=on-false, ведь это значение по умолчанию, если не задано другое.

Больше примеров в wiki.freeswitch.org

Freeswitch: Dialplan

http://pro-voip.com.ua freeswitch Для начала, что такое диалплан. Диалплан — это схема маршрутизации вызовов (звонков). В диалплане мы проверяем некоторые параметры вызова (например, номер вызывающего и вызываемого абонента) и на основании значения этих параметров указываем, куда перенаправить этот вызов дальше — на локальный номер, на шлюз оператора, в голосовую почту и т.д.

Для Freeswitch дефолтным диалпланом является XML dialplan. XML dialplan подключается к главному конфигурационному файлу freeswitch.xml с помощью include:

Диалплан может быть поделен на контексты (context) для разделения правил обработки и маршрутизации между разными группами пользователей. Пользователь с одним контекстом не может воспользоваться диалпланом другого контекста. Но существует возможность перенаправления вызовов между контекстами с помощью приложений диалплана (application).

Когда поступает входящий вызов, он поступает не из-неоткуда, он поступает от какого-либо зарегистрированного на Freeswitch абонента (будь то локальный абонент, или gateway оператора, или вызов может быть сгенерирован самим Freeswitch) и попадает сперва в обработку модуля mod_sofia. В Sofia вычисляются значения канальных переменных — channel variables — на основании значений в sip-заголовках входящего вызова, согласованных параметров вызова между вызывающим абонентом и Freeswitch, параметров, выставленных вручную в directory. Затем уже Freeswitch, используя вычисленные канальные переменные, парсит диалплан в поисках подходящего направления для данного вызова.

Диалплан работает по принципу «условие-действие»; «условие» задается в виде регулярного выражения — используется синтаксис Perl Regular Expression; «действие» — это одно или несколько приложений Freeswitch, также в качестве «действия» можно подключать свои внешние скрипты.

XML dialplan состоит из таких структурных единиц, как:

  • context (контекст),
  • extension («направление»),
  • condition (условие),
  • action (действие).

context состоит из множества extension, которые с помощью condition определяют action.

 

context

— логическое разделения групп правил маршрутизации вызовов.

Когда вы создаете пользователя в directory,  в переменной «user_context» вы указываете контекст, который пользователь может использовать для совершения вызовов — тем самым вы определяете набор доступных extension (направлений) для данного пользователя или группы пользователей, или всего домена. Если вы этого не сделаете, будет применяться контекст, указанный в переменной «context» sip-профиля.

Из выше сказанного и знаний про работу sip-профиля можно сделать следующие выводы: в sip-профиле может быть сколько угодно контекстов; в домене может быть сколько угодно контекстов; можно отдельного пользователя в домене завернуть в его отдельный контекст и чисто для этого пользователя написать диалплан; можно один контекст использовать для нескольких доменов.

context имеет обязательный параметр — это «name» — он должен быть уникальным. Для значения параметра name есть зарезервированное слово any — которое означает «любой контекст».

extension

— это отдельное направления для вызова — упрощенно — отдельная пара «условие-действие».

Также имеет обязательный параметр «name«, значение этого параметра может быть неуникальным; используется для описания extension — часто в name кратко описывают, что делает данный extension — это облегчает восприятие диалплана при просмотре его «глазками» без необходимости лезть внутрь самого екстеншена. При принятии решения о маршрутизации вызова Freeswitch парсит extension’ы и как только находит подходящий, на нем и останавливается, не досматривая остальные extension’ы до конца.

condition

— условие для выбора.

Здесь задаем, какую переменную проверяем, и под какое условие должно попасть значение этой переменной, чтобы применился данный extension. Можно сохранить значение всей переменной или непрерывную часть значения, для того, чтобы ее дальше можно было использовать в action. Для этого регулярное выражение или часть регулярного выражения заключаем в круглые скобки ( ). То, что окажется в пределах круглых скобок, сохранится в специальных переменных — $1, $2$9. Поскольку condition’ов может быт несколько, то и скобок в регулярных выражениях может быть несколько. Значение, попавшее в первые скобки, заносится в переменную $1, во вторые — $2 и т.д.

На примере:

здесь мы проверяем номер вызываемого абонента (destination_number) — он должен состоять из любых 4-х цифр. Если условие выполняется — то последние 2 цифры заносятся в переменную $1. Например, если destination_number=3589, то переменная $1=89.

Если после переменной $N нужно записать еще какую-то цифру, число, то используем фигурные скобки — ${N}

$1, $2$9 работают только в пределах того extension, где они были вычислены.

Переменных $10, $11, $12 и т.д. здесь не бывает. Если нужно переменных больше, чем 9, есть специальные приемы, но о них как-нибудь потом.

action

действие, которое мы выполняем, если мы попали под условие condition. Здесь мы указываем действие — это может быть направление вызова, установление каких-либо параметров, проигрывание музыки и т.д. Действие — это запуск определенного приложения (application).

В противовес action, есть еще anti-action — это действие, которое выполняется, когда результат проверки условий — false:

 

Написание тегов

Хочу обратить внимание на соблюдение порядка открывающих/закрывающих тегов.

<condition … > — открывающий тег
</condition> — закрывающий тег

<action … /> — не имеет отдельного закрывающего тега, поэтому в конце не забудьте про слеш

Если condition’ов несколько, то все, кроме последнего закрываем с помощью />, а последний condition закрываем  </condition>

<condition  … />
<condition … />
<condition … >
    <action … />
</condition>

SSH: Авторизация по ключам. Беспарольный доступ

http://pro-voip.com.ua freebsdгенерируем ключи на локальном хосте под тем пользователем, с которого хотим иметь доступ к удаленному хосту
ssh-keygen -b 2048 -t rsa

создаются два ключа
.ssh/id_rsa (закрытый)
.ssh/id_rsa.pub (открытый)

копируем открытый ключ — содержимое файла id_rsa.pub — на удаленный хост в файл .ssh/authorized_keys;
если файла authorized_keys нет, создаем его.

 

ssh-keygen

-t — тип ключа — dsa или rsa;
-b — длина ключа — для rsa можно и не указывать -b 2048 — потому как это дефолтное значение;
если нужен именно беспарольный доступ по ключам — поле passphrase оставляем пустым;

ssh-keygen -b 2048 -t rsa

Generating public/private rsa key pair.
Enter file in which to save the key (/home/user/.ssh/id_rsa):
Enter passphrase (empty for no passphrase):
Enter same passphrase again:
Your identification has been saved in /home/user/.ssh/id_rsa.
Your public key has been saved in /home/user/.ssh/id_rsa.pub.
The key fingerprint is:

 

Примечание

! При генерировании и размещении ключей имеют значения пары пользователь-локальный хост и пользователь-удаленный хост.

Вот следующая ситуация, имеем:

Локальный хост — host.example.com, пользователь на нем — user
Удаленный хост — server.example.com, пользователь на нем — admin

Вы — пользователь user на host.example.com и хотите иметь беспарольный доступ по ключам к server.example.com под пользователем admin.

Тогда вы на host.example.com, будучи залогиненым под своим пользователем user, генерируете ключи, которые сохраняются по умолчанию (если не задать другое) в вашем домашнем каталоге в директории .ssh

/home/user/.ssh/id_rsa
/home/user/.ssh/id_rsa.pub

На удаленном хосту в домашнем каталоге пользователя admin в директории .ssh создаете файл authorized_keys и копируете в этот файл одной строкой содержимое ранее сгенерированого на локальном хосту публичного ключа

/home/admin/.ssh/authorized_keys

Все работает:

[user@host ~]$ ssh admin@server.example.com

! При этом если измените пользователя на любой из сторон — без пароля уже не зайдете.

Например, все так же будучи залогиненым под пользователем user на host.example.com, вы ввели команду su и попали в окружение root-а на своем host.example.com, и теперь пытаетесь зайти на удаленный хост

root@host:/home/user# ssh admin@server.example.com
Password for admin@server.example.com:

— и у вас спрашивают пароль, а все потому что не тот пользователь.

! Опять-таки но — если вы root, то у вас есть доступ к любым файлам на вашей системе, в том числе и доступ к закрытому ключу /home/user/.ssh/id.rsa

поэтому с roota вы можете попасть на удаленный хост по ключам, просто указав путь к ключу с помощью опции -i

root@host:/home/user# ssh -i /home/user/.ssh/id_rsa admin@server.example.com

RSYNC: Резервное копирование. Простой backup-скрипт

http://pro-voip.com.ua freebsd

Режимы работы rsync

 

«listing«
аналог ls -l — команда rsync указывается с аргументом src, без dst:
# rsync /

«local«
локальный режим — копирование в пределах локального хоста — аналог cp:
# rsync /home/provoip/file1 /home/admin

«rsync via ssh«
копирование с/на удаленный хост используя транспорт ssh (или rsh, кто-то использует?):
# rsync /home/provoip/file1 admin@remoteserver.com:/home/admin

«rsync via daemon«
копирование с/на удаленный хост используя rsync демон (на сервере, где запущен rsync-демон, в пути ставим :: и указываем не путь к dst-директории, а модуль, модули настраиваются через конфигурационный файл rsync-демона):
# rsync /home/provoip/file1 jasmin@remoteserver.com::module1

 

Кусочек man rsync

 

Local: rsync [OPTION...] SRC... [DEST]

Access via remote shell:
Pull:  rsync [OPTION...] [USER@]HOST:SRC... [DEST]
Push:  rsync [OPTION...] SRC... [USER@]HOST:DEST

Access via rsync daemon:
Pull:  rsync [OPTION...] [USER@]HOST::SRC... [DEST]
       rsync [OPTION...] rsync://[USER@]HOST[:PORT]/SRC... [DEST]
Push:  rsync [OPTION...] SRC... [USER@]HOST::DEST
       rsync [OPTION...] SRC... rsync://[USER@]HOST[:PORT]/DEST

 

Опции rsync

 

-a, —archive — режим архивирования, набор опций -rlptgoD (без -H, -A, -X)

-r, —recursive,  рекурсивное копирование каталогов;
-l, —links,  копирование символических ссылок «как есть», то есть rsync не будет следовать по ним, обращаясь к файлам;
-p, —perms,  сохранение прав доступа к файлам;
-t, —times,  сохранение времени модификации файлов;
-o, —owner, -g, —group,  сохранение владельца и группы файла соответственно;
-D,  эквивалентно —devices —specials;
—devices,  сохранение файлов устройств (опция будет работать только для суперпользователя);
—specials, сохранение специальных файлов;

-H, —hard-links — сохранять жесткие ссылки;
-A, —acls — сохранять acl;
-X, —xattrs — сохранять расширеные атрибуты;

-R, —relative — использовать относительные пути — ну очень полезная опция

 

Вот с этим параметром была история. Нужно мне было сохранить на удаленном сервере две директории — /etc и /usr/local/etc. Соответственно, ввожу команду:

rsync -a /etc /usr/local/etc admin@remoteserver.com:/home/admin

и ожидаю увидеть на удаленном сервере в /home/admin две директории с конфигами… Фиг! Rsync сначала добросовестно скопировал директорию /etc, затем при копировании /usr/local/etc отбрасывает путь /usr/local, собирается копировать etc, видит, что на удаленном сервере etc уже какбы есть, поэтому просто добавляет недостающие, по его мнению, файлы c /usr/local/etc — т.е. слил все в одну директорию etc в указанном пути на удаленном сервере и с чувством выполненного долга завершил свою работу.

Для бекапа конфигов, как понимаете, такое положение вещей не подходит. Здесь мне на глаза попалась опция -R, которая была призвана решить мою проблему — на сервере теперь присутсвуют /home/admin/etc и /home/admin/usr/local/etc

 

-v, —verbose,  выводить имена копируемых файлов;
-q, —quiet,  не выводить не-error сообщения;
-z, —compress,  включает режим сжатия, полезно при передаче больших объемов информации;
-P, —partial, —progress,  отображать прогресс при копировании;
-c, —checksum,  заставляет rsync проверять файлы по контрольной сумме;
-n, —dry-run,  режим тестирования, нужен для проверки, что скопирует rsync, по факту не выполняя самого копирования. Используется с  -v и/или -i;
-i, —itemize-changes, показывать, какие изменения выполняются. Используется часто с -n

—delete,  удалять из бэкапа файлы, которых уже нет на стороне источника. —delete отличается от —delete-after тем, что удаление производится вначале, а не на завершающей стадии процесса бэкапа.
—delete-after,  работает быстрее, так как не требует лишней стадии обхода списка файлов, но требует использования опции —force для обработки таких ситуаций как удаление файла и появление диретории с тем же именем;
—delete-excluded,  удалять части которые уже есть на стороне бэкапа, но появились в списке исключения;

 

Примечания

 

копирование директорий

— указание пути директории с завершающим слешем приведет к копированию только файлов с этой директории
# rsync /etc/  admin@remoteserver.com:/home/admin   => результат — /home/admin/files_from_etc

— указание пути директории без завершающего слеша приведет к копированию целой директории с файлами
# rsync /etc  admin@remoteserver.com:/home/admin   => результат — /home/admin/etc

 

копирование нескольких директорий или файлов одновременно

— просто перечисляем через пробел:
# rsync /etc /home /usr  admin@remoteserver.com:/home/admin

 

Простой скрипт резервного копирования с использованием rsync

 

Скрипт не идеал, но работу свою выполняет. Как работает?

  • запускается по cron’у каждый день, при первом запуске делает полную копию указаных директорий, после — только вносит изменения;
  • каждое первое чило месяца сохраняет полную копию указаных директорий в каталоге, в имени которого указана дата — yyyymmdd;
  • все операции выполняет от имени root’а;
  • доступ к удаленному серверу по ключам;
  • после выполнения копирования шлет уведомление на почту;
  • список копируемых директорий/файлов указываем в переменной BKP_LIST

rsync_backup.sh

#!/bin/sh

################################################################################
# jasmin (c) 15.07.2015
# Scriprt rsync_backup.sh backups config files
# defined in list BKP_LIST to backup server
#
# - daily backup (incremental)
# - monthly backup (full backup in folder named with date) - every 1-st day of
# the month
#
# access to backup server with ssh-keys without passwords (user - root)
################################################################################

DATE=`date +%Y%m%d`
FIRST_DAY=`date +%d`

MAILADDR=admin@pro-voip.com.ua
HOSTNAME=www.pro-voip.com.ua
DBDIR=/dbbackup
REPORT=/tmp/rsync-report.$DATE

DST_SERVER=backup-srv.pro-voip.com.ua

(

    ################################################################################
    # if it is 1-st day of the month - make new folder and define new path
    ################################################################################
 
    if [ $FIRST_DAY == 01 ]
    then
        DST_DIR=/usr/home/RSYNK/provoip/$DATE
    else
        DST_DIR=/usr/home/RSYNK/provoip
    fi
  
    ################################################################################
    # DBDIR - local directory for dumps
    # Create database dump
    ################################################################################

    if [ ! -d $DBDIR ]
    then
        mkdir -p $DBDIR
    fi

    /usr/local/bin/mysqldump -u DBUSER -pDBPASSWORD --quick DATABASE > $DBDIR/DATABASE.sql

    ################################################################################
    # BKP_LIST - list of the directories to backup
    ################################################################################

    BKP_LIST="/etc /usr/local/etc /usr/local/www $DBDIR"


    ################################################################################
    # rsync options
    # -a - archive mode (save owners, permissions etc.)
    # -R - use relative path names - it is important!
    #
    # and make report in tmp-dir
    ################################################################################

    for BKP_ENTRY in `echo $BKP_LIST`
    do
        TIME=`date +%Y.%m.%d_%H:%M:%S`
        /usr/local/bin/rsync -aR --delete $BKP_ENTRY $DST_SERVER:$DST_DIR
        if [ $? == 0 ]
        then
            echo $TIME Rsync $BKP_ENTRY [done] >> $REPORT
        else
            echo $TIME Rsync $BKP_ENTRY [error] >> $REPORT
        fi
    done

) > $REPORT 2>&1

################################################################################
# send report to admin email
# if report have errors - Status in Subject is ERRROR, other case - OK
# then remove report from tmp-dir
################################################################################

grep error $REPORT
if [ $? = 0 ]
then
    /usr/bin/mail -s "[$HOSTNAME] rsync backup ERROR" $MAILADDR < $REPORT
else
    /usr/bin/mail -s "[$HOSTNAME] rsync backup OK" $MAILADDR < $REPORT
fi

rm $REPORT

exit 0

 

Mera MVTS: Коды разъединения

http://pro-voip.com.ua Справочная информация

Таблица локальных кодов разъединения Mera MVTS (Local Code). LOCAL CODE указывается в записи о вызове в CDR-файлах, дает дополнительную информацию о причине завершения вызова, наряду с Кодами разъединения Q931.

КодНазваниеОписание
1eCallerNormalЗвонок завершился нормально с посылкой “Release complete” от оригинирующей стороны.
2eCallerNormalЗвонок завершился нормально с посылкой “Release complete” от терминирующей стороны.
3eCallerDropTCPЗвонок завершился без получения “Release complete” в результате обрыва TCP соединения оригинирующей стороной.
4eCallerDropTCPЗвонок завершился без получения “Release complete” в результате обрыва TCP соединения терминирующей стороной.
10eRemoteGkDRQЗвонок завершился при получении disangageRequest от удаленного привратника.
100eForceTerminateCallЗвонок был завершен в принудительном порядке (останов MVTS, команда terminate call).
101eTimeoutTCPConnectH225Не было установлено H225 соединение с терминирующей стороной в течение 3 секунд.
102eTimeoutConnectMsgНе получено “Connect Message” в течении 120 секунд.
103eTimeoutRBTНе получено “Alerting Message” в течении 30 секунд.
104eInvalidH225SizeCallerПолучен H.225-пакет неверной длины от оригинатора звонка.
105eInvalidH225SizeCalledПолучен H.225-пакет неверной длины от терминатора звонка.
106eInvalidH225MsgCallerПолучен некорректный H.225-пакет от оригинатора звонка.
107eInvalidH225MsgCalledПолучен некорректный H.225-пакет от терминатора звонка.
108eInvalidH225ReadCallerMVTS не смог прочитать полученный от оригинатора звонка H.225-пакет.
109eInvalidH225ReadCalledMVTS не смог прочитать полученный от терминатора звонка H.225-пакет.
110eDestinationUnreachableНе найден соответствующий объект набора (dial peer) или ни один из требуемых шлюзов не был доступен.
112eFailedTCPConnectH225Сбой при установлении H225 сессии с терминирующей стороной.
113eInvalidCalledIpAddressНекорректный адрес терминатора звонка (согласно плану маршрутизации).
114eFailedDecodeUUCallerMVTS не смог декодировать поле UserUserField в пакете, полученном от оригинатора звонка.
115eInvalidTPKTCallerОшибка в заголовке пакета, полученного от оригинатора звонка. Встречалась в случае некорректной работы соответствующего шлюза.
116eFailedDecodeUUCalledMVTS не смог декодировать поле User Field в пакете, полученном от терминатора звонка.
118eDuplicateCallIdБыл получен звонок с Call ID, уже используемом в одном из активных соединений (защита от зацикливания звонков).
119eInvalidTPKTCalledОшибка в заголовке пакета, полученного от терминатора звонка. Встречалась в случае некорректной работы соответствующего шлюза.
120eTimeoutRouteAttemptНе было установлено соединение с терминирующим шлюзом в течении 10 секунд после начала роута на этот шлюз.
121eTimeoutSetupMsgНе был получен Setup Message в течении 15 секунд.
122eTimeoutRTPidleПри полном проксировании не было голосового трафика в течении 180 секунд. В этом случае звонок считается зависшим и завершается.
123eFailedTCPConnectH245CallerСбой при установлении H245 сессии
124eInvalidSetupMsgНеверный Setup Message (в пакете отсутствуют поле “User” или первым пришел не “Setup Message”).
125eMaxRerouteRetriesБыло совершено более 10 попыток рероута (защита от зацикливания при процедуре look ahead routing).
126eMaxCapacityExceedПревышено максимально допустимое значение параметра capacity для оригинатора звонка.
127eRouteBlockedМаршрут «оригинатор-объект набора-терминатор» заблокирован интеллектуальной маршрутизацией.
128eFailedTCPConnectH245CalledСбой при установлении H245 сессии на терминирующую вызов сторону.
129eNotAllowedPrefixПопытка совершения вызова на номер с запрещенным префиксом.
130eDuplicateCalledPartyNumberПревышено максимально разрешенное число вызовов с одинаковым номером вызываемого абонента
131eNoPacketTimeOutЗвонок завершен по причине отсутствия пакетов в течение заданного периода времени.
132eConsoleTerminatedCallЗвонок завершен в принудительном порядке командой terminate call.
133eDialpeerCapacityExceededПревышено максимально допустимое значение параметра сapacity= для объекта набора.
134eGatewayUnaccessibleНедоступность терминирующего шлюза.
135eGatewayIncompatibleНесовместимость оригинирующего и терминирующего шлюзов по полю compatibility.
136eDestinationGatewayCapacityExceededПревышено максимально допустимое количество звонков для данного терминирующего шлюза, заданное в поле capacity.
137eGatewayNullReachedМаршрутизация вызова завершена с причиной Q931 в результате обнаружения объекта набора с параметром gateway=NULL
138eHuntStoppedПоиск по объектам набора остановлен при значении параметра hunt_stop=1
139eNoAppropriateDialpeerНе найден подходящий диалпир при поиске маршрута для терминации.
141eMaxCallRateExceeded.Превышена максимальная скорость нарастания вызовов, указанная в поле max_callrate= (meraproxy.cfg [H.323]).
200eRadiusAdmissionCallerRejectRadius-сервером отклонена авторизация оригинатора звонка.
201eGkClientAdmissionTimeoutНа запрос Admission Request от удаленного привратника (gatekeeper) не получен ответ в течении 10 секунд.
202eSourceGatewayUnknownПолучен звонок с неизвестным адресом оригинатора (при прохождении звонка через конвертер SIP-HIT).
203eGkClientAdmissionRejectЗапрос Admission Request отклонен удаленным привратником (gatekeeper).
205eSourceGatewayAniRejectПараметр src_number оригинатора не совпадает с номерами, указанными в поле ani_allow описания шлюза или RAS-пользователя.
206eRadiusAdmissionTimeoutRadius-сервер не ответил на запрос в течении 10 секунд.
207eRadiusAdmissionCallerRejectRadius-сервером отклонена авторизация терминатора звонка.
208eRadiusAdmissionRouteRejectRadius-сервер отказал во внешней маршрутизации.
209eRouteProhibitedЗвонок с/на запрещенный адрес.
210eIncomingBandwidthOverloadПревышена входящая ширина полосы пропускания IP-адреса при использовании параметра «local_ip_manager=”.
211eOutcomingBandwidthOverloadПревышена исходящая ширина полосы пропускания IP-адреса при использовании параметра «local_ip_manager=”.
212eOutgoingDestNumberEmptyПредпринята попытка отправить Setup с пустым полем “CalledStationId«.
213ePacketOfDisconnectЗвонок завершен в принудительном порядке при получении от RADIUS-сервера пакета PacketOfDisconnect.
300eMaxSessionTimeПревышено максимальное время звонка (выдается Radius-сервером как CISCO_H323_CREDIT_TIME)
301eDanglingCallревышена максимальная длительность звонка (10000 секунд, около 3-х часов), предполагается, что это зависший звонок.
302eSystemOverflowПревышено количество одновременных звонков, указанных в лицензионном соглашении.
303eSourceGatewayExpiredИстекла дата, заданная в expire_date у шлюза-оригинатора звонка.
304eDestinationGatewayExpiredИстекла дата expire_date у терминатора звонка.
305eIncomingTrafficExceededПревышен лимит, определенный в max_incoming_time.
306eOutgoingTrafficExceededПревышен лимит времени, заданный в max_outgoing_time.
400eNoMediaServerОтсутствие Media MVTS серверов для терминации звонка с сигнального MVTS.
401eFailedTCPConnectMediaServerОшибка в установлении TCP-соединения с Media MVTS.

Mera MVTS: Регулярные выражения

Регулярные выражения применяются при конфигурировании следующих параметров:

dialpeer.cfg

  • dst_pattern=, src_pattern=
  • dst_translate=, src_translate=
  • dst_bill_translate=, src_bill_translate=
  • user_translate=

user.cfg, gateway.cfg

  • dst_pattern=, src_pattern=
  • dst_translate=, src_translate=
  • in_dst_translate=, in_src_translate=

Система проверяет регулярные выражения в сконфигурированных правилах трансляции на присутствие запрещенных символов и удаляет их. В правой части выражения трансляции можно использовать следующие символы: ^0123456789*#\&

Префиксы полей DST_PATTERN и SRC_PATTERN

Наиболее часто используемые конструкции:

dst_pattern=777[0-9]+
комментарий: номера, начинающиеся с 777 и состоящие далее из произвольных цифр
удачные примеры: 77711, 777922
неудачные примеры: 77811, 7771

dst_pattern=777[0-5].[0-9]+
комментарий: номера начинающиеся с 777, далее следует любая цифра в диапазоне от 0 до 5 и далее любые цифры
удачные примеры: 77711, 777422
неудачные примеры: 777, 77811, 77761, 7775,

dst_pattern=……
комментарий: любой шестизначный номер
удачные примеры: 123456, 976065 неудачные примеры: 1111111, 111

Трансляция номеров

При трансляции номеров наиболее часто используется добавление, отрезание и замена префикса.

Добавить префикс 78 к номеру 12345:
dst_translate = 12345/78&
результат: 12345 → 7812345

Добавить префикс 78312 к любому шестизначному номеру:
dst_pattern=……
dst_translate=.*/78312&
результат: 123456 → 78312 123456
результат: 654321 → 78312 654321

Добавить префикс 78312 к номеру, начинающемуся с 777:
dst_pattern=777……
dst_translate=[0-9]*/78312&
результат: 777123456 → 78312777123456
результат: 777121212 → 78312777121212

Отрезание префикса
dst_translate=095|.*/\2
комментарий: «отрезать» префикс 095, от последующей (второй) подстроки
результат: 09512345 → 095 | 123456 → 123456

dst_pattern=8182……
dst_translate=8182|[0-9]*/\2
комментарий: «отрезать» префикс 8182, т.е. подстроку 8182, предшествующую второй подстроке
результат: 8182123456 → 8182 | 123456 → 123456

Отрезать префикс и заменить его на другой:
dst_pattern=8182……
dst_translate=8182|[0-9]*/777\2
комментарий: «отрезать» префикс 8182 и вставить подстроку 777, перед второй подстрокой
результат: 8182123456 → 8182 | 123456 → 777 123456

bill_translate=1212|.*/1718\2
комментарий: «отрезать» префикс 1212 и заменить его на префикс 1718, перед второй подстрокой для целей биллинга
результат: 121212345 → 1212 | 12345 → 1718 | 12345 → 171812345

Убрать символ # из середины строки
src_translate=[0-9]*|#|[0-9]*/\1\3
комментарий:«вырезать» символ #, расположенный между 1-й и 3-й подстроками
результат: 123#45 → 123 | # | 45 → 12345

Отрезать символ #, завершающий строку:
dst_bill_translate=[0-9]*|#/\1
результат: 123456# → 123456 | # → 123456

Добавить символы в конец строки:
dst_translate=….|/\177
(комментарий: подставить 77 в конец первой подстроки)

Предварительная трансляция — выполняемая при поступлении звонка от этого шлюза,перед началом поиска обьекта набора
in_dst_translate=
in_src_translate=