Если Вам есть что добавить по данным тематикам, то шлите Ваши предложения, замечания на почту.
Как ejabberd подружить с LDAP
Не будем рассказывать как устанавливать ejabberd, это достаточно прозаично.
Рассмотрим сразу часть конфигурационного файла который отвечает за связь джаббер сервера с LDAP. В конкретном примере с Active Directory.
%% %% Говорим что авторизоваться будем по протоколу LDAP %% {auth_method, ldap}. %% %% IP адрес LDAP сервера ( PDC в Active Directory) {ldap_servers, ["ip_address_server"]}. %% %% Порт сервера LDAP: {ldap_port, 389}. %% DN запись пользователя который является администратором/менеджером сервера {ldap_rootdn, "CN=manager,DC=domain,DC=com"}. %% %% Пароль вышеуказанной учетной записи {ldap_password, "password"}. %% %% База поиска. Откуда мы будем начинать поиск пользователей: {ldap_base, "dc=domain,dc=com"}. %% %% LDAP аттрибут по которому будет определяться уникальность пользователя и подключение его: {ldap_uids, [{"sAMAccountName", "%u"}]}. %% Фильтр говорящий о том что мы ищем среди всех объектов только тех кто имеет класс person {ldap_filter, "(objectCategory=person)"}.
Это первая часть
и вторая часть это настройка связанная с тем что мы хотим получать дополнительную информацию из LDAP ( домашний телефон, адрес и т.д.)
{mod_vcard_ldap, [ {matches, 1000}, {ldap_vcard_map, [{"NICKNAME", "%u", []}, {"GIVEN", "%s", ["givenName"]}, {"MIDDLE", "%s", ["initials"]}, {"FAMILY", "%s", ["sn"]}, {"FN", "%s", ["displayName"]}, {"EMAIL", "%s", ["mail"]}, {"ORGNAME", "%s", ["company"]}, {"ORGUNIT", "%s", ["department"]}, {"CTRY", "%s", ["c"]}, {"LOCALITY", "%s", ["l"]}, {"STREET", "%s", ["streetAddress"]}, {"REGION", "%s", ["st"]}, {"PCODE", "%s", ["postalCode"]}, {"TITLE", "%s", ["title"]}, {"URL", "%s", ["wWWHomePage"]}, {"DESC", "%s", ["description"]}, {"TEL", "%s %s", ["telephoneNumber","telephoneNumbe$ ]}, %% Задаём поля для поиска по карточкам и их соответствие атрибутам акк$ {ldap_search_fields, [ {"User", "%u"}, {"Name", "givenName"}, {"Family Name", "sn"}, {"Email", "mail"} ]} %% Задаём какие поля vCard надо показывать в результатах поиска %% {ldap_search_reported, [ %% {"Full Name", "FN"}, %% {"Nickname", "NICKNAME"} %% ]} ]},
Что здесь есть интересного
{matches, 1000}, - при поиске будет отображать максимально 1000 найденных совпадений. По умолчанию будет выдаваться первые 30 записей.
Все остальные поля - это соответствие между аттрибутами LDAP и клиентской реализацией RFC-2426
Так как реализация этого RFC у каждого разработчика своя.. то некоторые поля в информации о пользователе в разных клиентах могут быть не видны.
Например в QIP не показывает при вышеупомянутых настройках почтовый индекс ({"PCODE", "%s", ["postalCode"]},), а PSI показывает.
Как написать простого ботаВ данной статье расмотрим несколько jabber ботов для различных целей написанных на языке Ruby
1. Это самый простейший бот, даже можно сказать недобот :) Присылает нужному пользователю какое либо сообщение
#!/usr/bin/env ruby # это мы пишем учетную запись и парольна jabber сервере от лица которого будет действовать скрипт # /Miranda говорит о называемом ресурсе ( необязательный параметр) ARGV[0]=' Этот e-mail адрес защищен от спам-ботов, для его просмотра у Вас должен быть включен Javascript /Miranda' ARGV[1]='password # подключаем необходимые бибилиотеки require 'rubygems' require 'xmpp4r' # включаем отладку, что бы видеть ошибки.. когда ошибок не будет можно нижнюю строку убрать Jabber::debug = true # подключаем пользователя cl = Jabber::Client.new(Jabber::JID.new(ARGV[0])) puts "Connecting Jabber client..." cl.connect puts "Authenticating..." cl.auth ARGV[1] # теперь пишем кому и что мы будем сообщать. Получатель как вы видите может быть на любом jabber сервере. to = ' Этот e-mail адрес защищен от спам-ботов, для его просмотра у Вас должен быть включен Javascript ' # это пишем тему и сам текст сообщения subject = 'Срочное сообщение' body = 'Вы забыли выключить утюг!' m = Jabber::Message::new( to, body ).set_type(:chat).set_id('1').set_subject(subject) cl.send m
Итак у нас получилось отправлять сообщения любым пользователям. В принципе неплохо: администраторы и IT специалисты смогут узнавать о каких то неполадках, пользователи о чрезвычайных событиях (например трудоголикам о том, что пора на обед)
Почему я называю этот скрипт недоботом? К сожалению на робота он не похож по функционалу: - во первых его надо запускать каждый раз как хотим что то отправить - во вторых его не видно в roster ( списке пользователей у клиента) - в третих ему нельзя сказать что либо в ответ. Поэтому представим другой скрипт
2. Давайте для начала расширим типы недоботов и напишем скрипт что проверяет наличие почты в почтовом ящике. Например на mail.ru #!/usr/bin/env ruby require 'net/pop' pop = Net::POP3.new 'pop3.mail.ru' pop.start ' Этот e-mail адрес защищен от спам-ботов, для его просмотра у Вас должен быть включен Javascript ', 'password' if pop.mails.empty? puts "No mail." else puts "You have #{pop.mails.length} new messages." end Если мы запустим этот скрипт то получим в результате подобный ответ
"You have 144 new messages."
Отлично, только если мы посмотрим на наш почтовый ящик то увидим, что скрипт посчитал абсолютно все письма и прочитанные и не прочитанные. К сожалению, протокол pop3 не дает различия между прочитанными и не прочитанными сообщениями. Необходимо использовать протокол IMAP. Но мы отвлеклись от создания ботов.
3. Простой бот. Отвечающий на Ваши сообщения. #!/usr/bin/env ruby # это мы пишем учетную запись и парольна jabber сервере от лица которого будет действовать скрипт # /Miranda говорит о называемом ресурсе ( необязательный параметр) ARGV[0]=' Этот e-mail адрес защищен от спам-ботов, для его просмотра у Вас должен быть включен Javascript /Miranda' ARGV[1]='password # подключаем необходимые бибилиотеки require 'rubygems' require 'xmpp4r' # включаем отладку, что бы видеть ошибки.. когда ошибок не будет можно нижнюю строку убрать Jabber::debug = true # подключаем пользователя cl = Jabber::Client.new(Jabber::JID.new(ARGV[0])) puts "Connecting Jabber client..." cl.connect puts "Authenticating..." cl.auth ARGV[1] # добавляем возможность видеть бота в своем roster (списке) roster = Jabber::Roster::Helper.new(cl) roster.add_subscription_request_callback do |item, pres| puts "Added by #{pres.from}" roster.accept_subscription(pres.from) # Разрешить видеть свой статус new_pres = Presence.new.set_type(:subscribe).set_to(pres.from) cl.send(new_pres) # Запросить разрешение видеть статус end # делаем так что бы на наш запрос jabber выполнял команду whois cl.add_message_callback do |m| body=`whois #{m.body}` message = Jabber::Message::new(m.from,body).set_type(:normal).set_id('1') cl.send(message) end puts cl.send(Jabber::Presence.new(:chat, 'Готов ответить на вопросы!')) Thread.stop
Скрипт готов к использованию. Роботу пишем название домена, например ya.ru и он нам отвечает.
% By submitting a query to RIPN's Whois Service % you agree to abide by the following terms of use: % http://www.ripn.net/about/servpol.html#3.2 (in Russian) % http://www.ripn.net/about/en/servpol.html#3.2 (in English). domain: YA.RU nserver: ns1.yandex.ru. nserver: ns5.yandex.ru. state: REGISTERED, DELEGATED, VERIFIED org: YANDEX, LLC. phone: +7 495 7397000 fax-no: +7 495 7397070 e-mail: Этот e-mail адрес защищен от спам-ботов, для его просмотра у Вас должен быть включен Javascript registrar: RU-CENTER-REG-RIPN created: 1999.07.12 paid-till: 2011.08.01 source: TCI Last updated on 2011.05.05 14:33:42 MSK/MSD Так мы можем беседовать с роботом бесконечно, расширяя функционал ответов/действий которые должен выполнять наш простой бот.
вместо `whois #{m.body}` можем писать как и внутренние команды системы ls, ps, find так и внешние скрипты написанные на любом языке программирования. С последним ботом возможно еще один удобный способ получения/управления информацией. Первый идеи которые приходят в голову, для реализации в корпоративных/офисных сетях. - отправка смс через бот - информирование о наступлении какого либо события. - поиск пользователей в адресной книге. - отправка файлов ( это вообще отдельная тема что можно сделать с этим функционалом) - выполнение команд на удаленном компьютере/сервере - сообщать через бота о пропущенных звонках (когда и кто звонил) пока вы отсутствовали на рабочем месте. - вести напоминания, дневники и т.д. И все это можно делать через бота, который неприметно находится среди Ваших обычных собеседников в jabber. Нет необходимости, открывать другие программы что бы получить такую же информацию через бота... Работать становится быстрее, удобнее, проще!
Дополнение: Робот отвечающий словом "ПРИВЕТ" на Ваши запросы, но написанный на языке PHP
<?php include('/usr/share/php/XMPPHP/XMPP.php'); $conn = new XMPPHP_XMPP('IP сервера', его порт, 'учётная запись, часть JID до @', 'его пароль', 'xmpphp', 'часть JID после @', $printlog=True, $loglevel=XMPPHP_Log::LEVEL_DEBUG); $conn->useEncryption(false); $conn->connect(); while(!@$conn->disconnect) { $payloads = $conn->processUntil(array('message','code','presence', 'end_stream', 'session_start')); foreach($payloads as $event) { $pl = $event[1]; switch($event[0]) { case 'message': $body="ПРИВЕТ"; $conn->presence($status="ТЕСТ"); $conn->message($pl['from'], $body, $type=$pl['type']); break; }}}
php?>
Добавлено 24 июня
бот на языке PHP
<?php
Как установить ejabberdНе будем рассказывать как устанавливать ejabberd, это достаточно прозаично. Рассмотрим сразу часть конфигурационного файла который отвечает за связь джаббер сервера с LDAP. В конкретном примере с Active Directory. %% %% Фильтр говорящий о том что мы ищем среди всех объектов только тех кто имеет класс person {ldap_filter, "(objectCategory=person)"}.
Это первая часть и вторая часть это настройка связанная с тем что мы хотим получать дополнительную информацию из LDAP ( домашний телефон, адрес и т.д.)
{mod_vcard_ldap, [ {ldap_vcard_map, [ {"NICKNAME", "%u", []}, {"GIVEN", "%s", ["givenName"]}, {"FAMILY", "%s", ["sn"]}, {"FN", "%s %s", ["givenName", "sn"]}, {"PHONE", "%s", ["homePhone"]}, {"EMAIL", "%s", ["mail"]} ]}, %% Задаём поля для поиска по карточкам и их соответствие атрибутам аккаунтов LDAP {ldap_search_fields, [ {"User", "%u"}, {"Name", "givenName"}, {"Family Name", "sn"}, {"Email", "mail"} ]}
Прием файлов2 OpenDS установка
1. C сайта скачиваем последнюю версию дистрибуьтива. http://www.opends.org/ 2. Распаковываем в любую папку где будет находится Ваш сервер. Запускаем setup. 3. Если работаем через терминал то отвечаем на поставленные вопросы
The graphical Setup launch failed. Check file /tmp/opends-setup-808473160811020821.log for more details. Launching command line setup... OpenDS Directory Server 2.2.1 Please wait while the setup program initializes... What would you like to use as the initial root user DN for the Directory Server? [cn=Directory Manager]: cn=admin Please provide the password to use for the initial root user: вводим пароль Please re-enter the password for confirmation: повторяем ввод пароля On which port would you like the Directory Server to accept connections from LDAP clients? [389]: подверждаем что сервер будет работать на 389 порту. Можете поменять на любой другой
On which port would you like the Administration Connector to accept
connections? [4444]: Порт для администрирования
What do you wish to use as the base DN for the directory data?
[dc=example,dc=com]: dc=place,dc=org
Options for populating the database:
1) Only create the base entry
2) Leave the database empty
3) Import data from an LDIF file
4) Load automatically-generated sample data
Enter choice [1]: соглашаемся только базовые настройки
Do you want to enable SSL? (yes / no) [no]: отказываемся от настройки SSL
Do you want to enable Start TLS? (yes / no) [no]: отказываемся от поддержки TLS
Do you want to start the server when the configuration is completed? (yes /
no) [yes]: Подтверждаем что мы все настроили верно
Start Server when the configuration is completed
What would you like to do?
1) Setup the server with the parameters above
2) Provide the setup parameters again
3) Cancel the setup
Enter choice [1]: соглашаемся запустить сервер с указанными выше парамерами
Configuring Directory Server ..... Done.
Creating Base Entry dc=spii,dc=rzdp,dc=ru ..... Done.
Starting Directory Server ................... Done.
Все. Наш LDAP сервер установлен. Установка заняла 3 минуты. Описание этой инструкции заняло в три раза больше времени.
OpenDS vs OpenLDAPИтак на мой взгляд попробую объяснить чем лучше OpenDS по сравнению OpenLDAP.
1. OpenDS устанавливается достаточно быстро, с последующей начальной конфигурацией. OpenLDAP после установки надо править slapd.conf, а в новых версиях каталог конфигурации.
2. Расширение схемы OpenLDAP делается проще. Известен синтаксис написания схемы и схему можно разместить в папке схем, которая будет активирована после перезапуска LDAP сервера. В этом отношении расширение схемы в OpenDS чуть сложнее, но это компенсируется отличной помощью на сайте OpenDS.
3. Индексирование аттрибутов опять же проще в OpenLDAP. В старых версиях.
4. Что касается скорости записи, то по опыту OpenDS несравнимо лучше чем OpenLDAP. 340 тысяч записей( каждая запись из 8 полей) в OpenDS записалось примерно часа за 4-ре. OpenLDAP не справился с этой задачей и за сутки. Наверняка есть методы оптимизации в OpenLDAP которые позволят увеличить скорость, но если мы обладаем минимальными/базовыми настройкам при разворачивании LDAP сервера, то использование OpenDS более предпочтительнее.
Ну и последнее, одним из наиболее удачных LDAP редакторов, из бесплатных, является Apache Directory Studio. У этого же разработчика есть и свой LDAP сервер ApacheDS, но я его не тестировал и не разворачивал в своих сетях. Индексирование аттрибутов1 Расширение схемы OpenDSРасширение схемы для OpenDS практически одинаково как и для OpenLDAP Отличие только в способе расширения схемы и изменении структуры файла. Итак для того что бы расирить схему необходимо воспользоватся следующей командой: ldapmodify -h hostname -p 389 -D "cn=Directory Manager" -w password -f /usr/local/modify.ldif
где "cn=Directory Manager" - учетная запись администратора password - пароль администратора /usr/local/modify.ldif - файл расширения схемы
Структура файла при добавлении схемы будет такой.
dn: cn=schema changetype: modify add: attributeTypes attributeTypes: ( 1.3.6.1.4.1.777.0.0.1.1 NAME ( 'point' ) DESC 'Название' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 SINGLE-VALUE X-ORIGIN 'OpenDS Directory Server') dn: cn=schema
changetype: modify
add: attributeTypes
attributeTypes: ( 1.3.6.1.4.1.777.0.0.1.2 NAME ( 'altname' ) DESC 'Альтернативные названия' EQUALITY caseExactMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 X-ORIGIN 'OpenDS Directory Server')
dn: cn=schema
changetype: modify
add: objectClasses
objectClasses: ( 1.3.6.1.4.1.777.0.0.1.0 NAME ( 'Geo' ) DESC 'Класс объекта' STRUCTURAL MUST point MAY (altname) X-ORIGIN 'OpenDS Directory Server' )
Запускаем:
root@server:/home# ldapmodify -h localhost -p 389 -D "cn=admin" -w password -f modify.ldif modifying entry "cn=schema" modifying entry "cn=schema" modifying entry "cn=schema" root@server:/home#
Наша схема принята LDAP сервером и готова к работе. Расширение схемы OpenLdapРассмотрим расширение схемы LDAP на сервере OpenLdap Есть файл с географическими координатами, содержащие такие строки:
123 Samara Samara,Самара, Куйбышев,kyjbyshev 50.13 51.44 где 123 - уникальный код (kod) Samara - название в английской транскрипции (name) Samara,Самара, Куйбышев,kyjbyshev - альтернативные названия населенного пункта (altname) 50.13 - географическая широта (lantitude) 51.44 - географическая долгота. (longitude)
Теперь, что бы мы могли добавить все данные об объектах в каталог, мы создадим LDAP класс. Общий вид который в формате OpenLdap будет следующим:
attributetype ( 1.3.6.1.4.1.777.0.0.1.1 NAME 'gname' EQUALITY caseIgnoreMatch SUBSTR caseIgnoreSubstringsMatch DESC 'Название географической точки' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 SINGLE-VALUE ) attributetype ( 1.3.6.1.4.1.777.0.0.1.2 NAME 'altname' EQUALITY caseIgnoreMatch SUBSTR caseIgnoreSubstringsMatch DESC 'Альтернативные названия географической точки' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 ) attributetype ( 1.3.6.1.4.1.777.0.0.1.3 NAME 'latitude' DESC 'Географическая широта' SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 SINGLE-VALUE ) attributetype ( 1.3.6.1.4.1.777.0.0.1.4 NAME 'longitude' DESC 'Географическая долгота' SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 SINGLE-VALUE ) attributetype ( 1.3.6.1.4.1.777.0.0.1.5 NAME 'kod' DESC 'Цифровое обозначение географической точки' SYNTAX 1.3.6.1.4.1.1466.115.121.1.36 SINGLE-VALUE ) objectclass ( 1.3.6.1.4.1.777.0.0.1.0 NAME 'Geo' DESC 'Класс описывающий географические объекты' STRUCTURAL MUST gname MAY (altname $ latitude $ longitude $ kod))
Давайте разберем чуть поподробнее что же мы сделали: Первым делом мы придумали OID ( для локальных целей он может быть любым главное что бы не пересекался с существующими) взяли за основу существующий/зарезервированный 1.3.6.1.4.1. и к ней добавили 777.0.0.1.0 (цифры взяты с потолка). то есть 1.3.6.1.4.1.777.0.0.1.0 , 1.3.6.1.4.1.777.0.0.2.0 и т.п это будут описания классов, а если последняя цифра не ноль, то это аттрибут к уже существующему классу как видно у аттрибутов, последняя цифра меняется от 1 до 5. Итак мы создали класс с именем Geo и сказали что у него есть обязательные (MUST) аттрибут gname и необязательные ( altname $ latitude $ longitude $ kod), которые ими могут быть пустими или вообще отсутствовать. Теперь к описанию аттрибутов
attributetype ( 1.3.6.1.4.1.777.0.0.1.5 NAME 'kod' DESC 'Цифровое обозначение географической точки' SYNTAX 1.3.6.1.4.1.1466.115.121.1.36 SINGLE-VALUE )
SINGLE-VALUE - говорит о том что значение может быть только одно ( ну и логично что оно уникально, иначе при добавлении копии такого объекта, нам говорили что он уже существует) SYNTAX 1.3.6.1.4.1.1466.115.121.1.36 - если мы откроем RFC-4517, то увидим что kod может принимает цифровые значения с пробелами.
Теперь другой аттрибут
attributetype ( 1.3.6.1.4.1.777.0.0.1.2 NAME 'altname' EQUALITY caseIgnoreMatch SUBSTR caseIgnoreSubstringsMatch DESC 'Альтернативные названия географической точки' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )
SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 - говорится о том что altname может быть строкой в том числе и в национальной кодировке. SINGLE-VALUE - отсутствует, а значит в это поле можно записывать много различных значений EQUALITY caseIgnoreMatch - говорит о том что при добавлении данных, будет игнорироваться регистр. То есть Самара и самара - для каталога будут равоценны SUBSTR caseIgnoreSubstringsMatch - необходим только в случае поиска и индексации по этому аттрибуту. Не различать регистр при поиске.
Например если мы будем искать по *АрА то нам все равно выдаст Самара. Если этот аттрибут убрать, то по запросу *АрА мы не найдем ничего.
В принципе все.
Схема создана, осталось её включить в работающий LDAP сервер. Открываем файл /etc/ldap/slapd.conf Добавляем "include /etc/ldap/schema/geo.schema" если мы собираемся индексировать какие то аттрибуты, дабы поиск был быстрым то добавлем
"index altname sub index gname sub" где говорим что индексируем два аттрибута altname и gname по любой части фразы.
Останавливаем сервер LDAP запускаем slapdindex -v После пере индексации запускаем сервер. Наша схема работает!
P.S. Если Ваша конфигурация LDAP храниться не в slapd.conf а в каталоге, то исправить это легко. Достаточно в файле /etc/default/slapd изменить параметр SLAPD_CONF. По умолчанию он пустой. Если напишем SLAPD_CONF=/etc/ldap/slapd.conf то при запуске LDAP сервера конфигурация будет считываться с файла /etc/ldap/slapd.conf.
Узнать количество заблокированных клиентов AD при помощи LDAP
В данной статье мы рассмотрим некоторые запросы LDAP с помощью которых можно получать ту или иную информацию из Windows ActiveDirectory.
Считаем что Вы подключились к LDAP серверу как администратор.
Ваш домен именуется domain.com
1. Получить все записи DNS сервера. Первичная зона именуется domain.com Запрос: DC=domain.com,CN=MicrosoftDNS,CN=System,DC=domain,DC=com фильтр: (&(objectClass=dnsNode)) Доступные аттрибуты: dnsRecord - (вторая позиция) в 16-тиричном виде записан IP адрес. Например ac 19 28 c8 => 172.25.40.200 name - имя компьютера в ДНС зоне whenChanged - время когда запись была последний раз изменена whenCreated - время когда запись была создана. Пример: 25.01.2010 10:14:00 MSK (20100125071400.0Z)
2. Получить список компьютеров в домене. Запрос: CN=Computers,DC=domain,DC=com Фильтр: ((objectClass=computer) Доступные аттрибуты: name - имя компьютера operatingSystem - название операционной системы. Пример: Windows XP Professional operatingSystemServicePack - номер сервис пака. Пример: Service Pack 3 operatingSystemVersion - версия операционной системы. Пример: 5.1 (2600) whenChanged - время когда запись была последний раз изменена whenCreated - время когда запись была создана. Пример: 25.01.2010 10:14:00 MSK (20100125071400.0Z)
3. Получить пользователей. Считаем что пользователи у Вас находятся в Users, хотя это не критично можете указать любой путь в поиске. Запрос: CN=Users,DC=domain,DC=com Фильтр: (objectClass=person) adminCount - если эта позиция не пустая и равна 1 то пользователь является администратором домена. company - имя организации. Заполняется администратором. Практически применяется когда надо будет строить адресные книги. department - имя отдела/сектора. displayName - отображаемое имя. Пример: Иванов Петр Сергеевич ipPhone - номер телефона mail - адрес электронной почты mobile - номер мобильного телефона sAMAccountName - логин пользователя memberOf - список групп в какие входит пользователь
4. Изменить аттрибуты учетной записи у пользователей домена. Запрос: CN=Users,DC=domain,DC=com Фильтр: (&(objectclass=user)(objectcategory=person)) userAccountControl - аттрибут отвечающий за настройки пользователя которые размещены на вкладе Account (Account option) 512 - все галочки сняты в окне Account option 66048 - все галочки сняты в окне Account option и поставлена только галочка напротив Password never expires аттрибут pwdLastSet равен 0 когда в окне Account option стоит галочка User must change password at next logon если аттрибут userAccountControl равен 514 то данный пользователь заблокирован. Поэтому, если мы хотим получить список всех заблокированных пользователей в домене, наш запрос должен выглядеть так: (&(objectclass=user)(objectcategory=person)(userAccountControl=514))
Yate. Начало работы
Начинаем рассказывать о возможностях и функционале Yate(Yet Another Telephony Engine) программной VoIP АТС. Данную АТС можно настроить в режиме: 1. Сервера VoIP 2. Клиента VoIP 3. Сервера конференции - до 200 каналов на единственную конференцию 4. Шлюза VoIP - PSTN 5. Привратника (Gateway) H.323 6. Прокси сервера H.323 <-> SIP 7. Маршрутизатора SIP 8. Регистрационного сервера SIP 9. Сервера MGCP (Агент Звонка) 10. Переключателя SS7 11. Сервера центра обработки вызовов. 12. Механизма IVR ( голосовое меню)
Итак устанавливаем Yate на наш сервер. Последняя версия 3.3 скачиваем файлы
http://yate.null.ro/pmwiki/index.php?n=Main.Download
SVN Checkout http://voip.null.ro/svn/yate/trunk Yate Заходим в папку yate, читаем файл Readme
./configure make make install
Все, наш Yate сервер установлен.
Запускается сервер командой yate. Конфигурационные файлы лежат в папке /usr/local/etc/yate
root@server:/usr/local/etc/yate# yate Yate (24390) is starting Wed May 4 16:09:37 2011 Loaded module CdrFile Loaded module MOH Loaded module File Transfer Loaded module WaveFile Loaded module OpenSSL - based on OpenSSL 0.9.8o 01 Jun 2010 Loaded module Call Generator Loaded module RegexRoute Loaded module YSOCKS Loaded module YSTUN Loaded module Call Forker Loaded module ExtModule Loaded module iLBC - based on iLBC library Loaded module Conference Loaded module Analyzer Loaded module ZLib - using zlib library version 1.2.3.4 Loaded module DumbChannel Loaded module RManager Loaded module YRTP Loaded module YJingle Loaded module SIP Channel Loaded module MUX Loaded module ToneGen Loaded module YIAX Loaded module ToneDetector Loaded module MsgSniffer Loaded module PBX Loaded module CdrBuild Loaded module Late Router Loaded module Register for database Loaded module CallCounters Loaded module Queues Notify Loaded module MGCP-GW Loaded module Cpu Loaded module Analog Detector Loaded module Registration from file Loaded module Users Management Loaded module MRCP Loaded module Queues Loaded module CCongestion Loaded module Subscriptions Loaded module Cisco SM Loaded module DbWave Loaded module PostgreSQL Loaded module MGCP-CA Loaded module Monitoring Loaded module Radius client Loaded module Clustering Loaded module SIP Features Loaded module Signalling Channel Loaded module Heartbeat Loaded module ISUP Mangler Loaded module Analog Channel Loaded module PBX for database Loaded module SigTransport Loaded module Call Parking Loaded module Accounts from file Loaded module SNMP Agent Loaded module MySQL based on 5.0.67 Loaded module Presence Loaded module Jabber Server Features Loaded module Jabber Server Initializing plugins Initializing module Jabber Server Initializing module Jabber Server Features Initializing module MySQL Initializing module SigTransport Initializing module Clustering Initializing module MGCP Call Agent Initializing module PostgreSQL Initializing module DbWave Initializing module Cisco SM Initializing module Subscriptions Initializing module Analog Detector Initializing module Cpu Initializing module MUX Initializing module ZLib Initializing module YSOCKS Initializing module OpenSSL Initializing module CdrFile Initializing module MOH Initializing module File Transfer Initializing module WaveFile Initializing module Call Generator Initializing module RegexRoute Initializing module YSTUN Initializing module Call Forker Initializing module ExtModule Initializing module Conference Initializing module Analyzer Initializing module DumbChannel DumbChannel initialized Initializing module RManager Initializing module YRTP Initializing module YJingle Initializing module SIP Channel Initializing module ToneGen Initializing module YIAX Initializing module ToneDetector Initializing module MsgSniffer Initializing module PBX Initializing module CdrBuild Initializing module Late Router Initializing module Register for database Initializing module Queues Notify Initializing module MGCP Gateway Initializing module Register from file Initializing module Users Management Initializing module MrcpSpeech Initializing module Queues for database Initializing module CCongestion Initializing module Monitoring Initializing module Radius client Initializing module SIP Features Initializing module Signalling Channel Initializing module ISUP Mangler Initializing module Analog Channel Initializing module PBX for database Initializing module Call Parking Initializing module Accounts from file Initializing module Presence Initialization complete Yate engine is initialized and starting up on server
Если мы хотим запустить сервер в режиме демона то пишем yate -d
Если мы хотим запустить yate в режиме отладки то пишем yate -v или yate -vvvv где количество букв v означает детализацию отладки
Давайте сделаем самый просто пример и попробуем подключиться к нашему SIP серверу через программный телефон. для начала отредактируем файл regfile.conf впишем строки
[707] password=12345
где 707 имя пользователя все, на стороне сервера мы настройки сделали.
Теперь на стороне клиента указываем IP адрес сервера, порт (по умолчанию 5060) имя (707) и пароль (12345) пытаемся зарегистрироваться. если мы на сервере запустили yate с отладкой (yate -ммм) то увидим следующее <sip:NOTE> Registered user '707' expires in 3600 s Наш клиент зарегистрирован.
Выход на городские линии1 Маршрутизация
Итак, у нас есть работающий сервер АТС.
Более того, мы можем осуществлять звонки между зарегистрированными пользователями. Но мы хотим расширить наш функционал. В этой статье мы рассматриваем файл regexroute.conf, который отвечает за маршрутизацию звонков.
200- номер секретаря 222 - номер директора 127.0.0.1 - имя сервера нашей АТС 127.0.0.2 - адрес VoIP шлюза (Planet, Dlink, AddPack и т.д.)
^777$=fork sip/sip:200@127.0.0.1 |next=20000 sip/sip:222@127.0.0.1 |stoperror=busy при звонке на номер 777, сначала звонит телефон секретаря. потом по истечении 20000 милисекунд, звонок пере направится на директора, если там трубку не берут, то идет отбой.
^123$=wave/play//usr/local/share/yate/sounds/fon.slin при звонке на номер 123 - начинает проигрываться мелодия. Как создавать мелодии или заготовку голосового меню в yate мы рассмотрим позже.
^9\(.*\)$=sip/sip:\1@127.0.0.2;caller;callername если мы набираем номер 9-972-39-62 то перенаправить их на VoIP шлюз убрав первую девятку. то есть к шлюзу ушел номер 972-39-62
^9\(.*\)$=sip/sip:\1;line=sipnet;caller;callername если мы набираем номер 9-972-39-62 то пере направить этот звонок через sipnet.ru. Как настраивается расскажем чуть позже.
^777$ =fork sip/sip:200@127.0.0.1 sip/sip:222@127.0.0.1 |exec=20000 queue/desk wave/play/queue_full.au звонок секретарю и директору будет осуществятся одновременно, кто первый возьмет. После 20000 милисекунд будет проигрываться мелодия или Ваша голосовая запись.
Настраиваем Yate с SIPNETНастройка /простая интеграция Yate с Sipnet, заключается в редактировании файла accfile.conf Вписываем туда
[sipnet] enabled=yes protocol=sip username=Ваше учетная имя в Sipnet.ru Например 00008678768 description=sipnet.ru ;interval=600 formats=alaw,mulaw authname=совпадает с username password=пароль для учетной записи на Sipnet ;number=1234 domain=sipnet.ru registrar=sipnet.ru
Далее в файле маршуртизации regexroute.conf мы добавлем строку ^9\(.*\)$=sip/sip:\1;line=sipnet;caller;callername которая говорит что при наборе номера с префиксом 9, звонок переадресовывать через sipnet, естественно предварительно префикс убрать.
Все, таким нехитрым способом мы можем подключать на любые префиксы любых SIP операторов, да и не только их. Например, такая схема пригодиться для соединения двух и более Yate серверов.
Парковка и перенаправление1 Создаем голосовое менюYate позволяет создавать многоуровневые голосовые меню, приглашения, подсказки. Количество вложенных меню не ограниченно. Для начала мы создадим простейшее звуковое приглашение. Запишем с помощью любой программы наш текст "Здраствуйте, Вы позвонили в компанию. Если Вы хотите что бы вас соединили с директором нажмите 1, с тех.поддержкой нажмите 2... или дожитесь ответа секретаря" Получили файл к примеру logo.wav в Ubuntu запускаем программу sox с следущими параметрами
sox logo.wav -t raw -r 8000 -c 1 -w -s logo.slin
Все, наш файл готов. Теперь в файле модуля маршрутизации мы можем проверить как это работает ^555$=wave/play//path/to/file/logo.slin набираем в телефонном аппарате номер 555 и наслаждаемся записанным приглашением Более подробно о конвертации, в другие форматы, Вы можете увидеть в http://yate.null.ro/pmwiki/index.php?n=Main.ConvertingAudio Кстати, если мы запишем
Для начала в файле extmodule.conf укажем где будут находится наши скрипты
[general] scripts_dir=/usr/local/lib/yate/
и файле маршрутизации мы добавляем
^555$=external/nodata/voicemail.php
при наборе 555 - будет выполняться внешний скрипт voicemail.php
Как второй вариант, можно обратиться к нам.
Статистика звонковЗа статистику звонков, за хранение этой статистики в файле, отвечает файл cdrfile.conf. Вот пример этого файла
[general] ; file: string: Name of the file to write the CDR to ;file= file=/tmp/cdr.log ; tabs: bool: Use tab-separated instead of comma-separated if format is missing ;tabs=false ;;tabs=true ; format: string: Custom format to use, overrides default. Each ${parameter} ; is replaced with the value of that parameter in the call.cdr message ; tab-separated (.tsv) ;format=${time} ${billid} ${chan} ${address} ${caller} ${called} ${billtime} ${ringtime} ${duration} ${direction} ${status} ${reason} ; comma-separated (.csv) format=${time},"${billid}","${chan}","${address}","${caller}","${called}",${billtime},${ringtime},${duration},"${direction}","${status}","${reason}" все очень просто
говорим что все логи хранить в папке /tmp/cdr.log
и показываем в каком формате информацию записывать
Вид файла будет следующий
1305285957.430,"1305285941-1","sip/2","172.25.40.200:5060","201","201",1.479,2.560,4.141,"outgoing","answered",""
1305285957.428,"1305285941-1","sip/1","172.25.40.200:5060","201","201",1.480,2.560,4.144,"incoming","answered",""
1305286986.429,"1305286985-1","sip/1","172.25.40.200:5060","201","200",0.000,0.001,0.001,"incoming","rejected","No route to call target"
1305286989.583,"1305286985-2","sip/2","172.25.40.200:5060","201","200",0.000,0.001,0.001,"incoming","rejected","No route to call target"
1305286992.401,"1305286985-3","sip/3","172.25.40.200:5060","201","201",0.000,0.001,0.001,"incoming","rejected","No route to call target"
1305287007.641,"1305286985-5","sip/6","172.25.40.8:5060","","708",0.000,0.001,0.001,"incoming","rejected","No route to call target"
1305287007.619,"1305286985-4","sip/5","172.25.40.8:5060","","",0.000,0.042,0.042,"outgoing","outgoing","No route to call target"
1305287004.082,"1305286985-4","sip/4","172.25.40.200:5060","201","777",3.664,0.000,3.582,"incoming","answered","Not Found"
1305287013.378,"1305286985-6","sip/7","172.25.40.200:5060","201","777",12.801,0.000,12.423,"incoming","answered",""
1305287029.171,"1305286985-7","sip/8","172.25.40.200:5060","201","781",0.000,0.001,0.001,"incoming","rejected","No route to call target"
И такую статистику можно обрабатывать периодически и предоставлять сводную информацию, кто куда звонил и сколько время потратил.
Достаточно написать парсер/скрипт что эту информацию приведет в удобочитаемый для руководства вид.
Для организаций это самое просто и удобное решение контроля звонков для своих сотрудников.
DVI и HDMI. Распайка и соединениеDigital Visual Interface, сокр. DVI (англ. цифровой видеоинтерфейс) — стандарт на интерфейс и соответствующий разъём, предназначенный для передачи видеоизображения на цифровые устройства отображения, такие как жидкокристаллические мониторы и проекторы
High-Definition Multimedia Interface (HDMI) — интерфейс для мультимедиа высокой чёткости, позволяющий передавать цифровые видеоданные высокого разрешения и многоканальные цифровые аудиосигналы с защитой от копирования (англ. High Bandwidth DigitalCopy Protection, HDCP). Разъём HDMI обеспечивает цифровое DVI-соединение нескольких устройств с помощью соответствующих кабелей. Основное различие между HDMI и DVI состоит в том, что разъём HDMI меньше по размеру, а также поддерживает передачу многоканальных цифровых аудиосигналов
Jabber бот (Операции с датами)Предоставляет информацию по операциям с датами, на основе григорианского календаря.
- Рассчитывает день недели на любое число. от Рождества Христова до 999999 года - Рассчитывает количество суток прошедшее между двумя датами - Рассчитывает дату, которая наступит( или была) несколько дней (недель, часов) назад.
Внимание! Если Вы пользуетесь сервисом через jabber, то впереди всегда добавляйте ключевое слово dat Здесь могут учитываться ключевые слова, такие как неделя, час. Слова месяц, год, квартал не учитываются в данной программе так как нельзя с точностью сказать какое количество будет в квартале, месяце, годе. Примеры: (dat) 01.01.1997 Ответ: День недели среда Дата 01.01.1997 Хотелось бы заметить что бы дату писали полную 01.01.97 - Вам даст день недели 1 января 97 года от Рождества Христова.. да к тому же и не правильную, так как григорианский календарь был придуман в 16 веке, а в России он стал применяться с 1918 года.
Пример (dat) 01.01.1997 23.06.2011 Ответ: Первая дата среда 01.01.1997 Вторая дата четверг 23.06.2011 Разница между двумя датами составляет 5286 суток Учтите, что даты работают только в нашей эре.... Если будете считать сколько прошло дней с момента постройки пирамид, результаты будут далеки от истинных. Также следует учесть что при при выполнении dat 01.01.1997 31.12.1997 мы получим разницу в 364 суток, а не 365 как это хотелось бы некоторым.
Пример (dat) 23.06.2011 33 - Ответ: Дата 21.5.2011 что получается при вычитании 33 суток относительно даты 23.06.2011 День недели суббота (dat) 23.06.2011 33
Дата 26.7.2011 что получается при сложении 33 суток относительно даты 23.06.2011 День недели вторник
Пример (dat) 22.08.2007 40 нед - Ответ: Дата 15.11.2006 что получается при вычитании 40 недель относительно даты 22.08.2007 День недели среда Зная рождение ребенка, как видите достаточно просто узнать когда примерно Вы забеременели.
Пример (dat) 30.12.1976 100 часов Ответ: Дата 3.1.1977 что получается при сложении 100 часов относительно даты 30.12.1976 День недели понедельник
MAC адрес производителя
Данный сервис предлагает Вам получить информацию о производителе того или иного сетевого оборудования. MAC-адрес (от англ. Media Access Control — управление доступом к среде, также Hardware Address) — это уникальный идентификатор, присваиваемый каждой единице оборудования компьютерных сетей. Первые три числа MAC-адрес представляют собой или указывают код производителя конкретного сетевого устройства, остальные цифры – партию и номер выпуска.
Введите часть мак адреса через тире или сплошным текстом, или введите наименование производителя. Например Cisco.
Данный сервис доступен через наш Jabber сервер. Правило использования. пишите: mac поисковая строка. Например mac 0011 или mac Planet и Jabber сервер ответит Вам результатом поиска.
Здесь же,в поле ввода, пишите просто Planet или 00117 и Вам сервер даст ответ.
Ubuntu. ИнтересностиВопрос: Как узнать версию ядра ? Ответ: uname -a Linux animal-server 2.6.31-23-server #74-Ubuntu SMP Mon Feb 28 22:32:34 UTC 2011 x86_64 GNU/Linux
Вопрос: Как узнать версию Ubuntu ? Ответ: lsb_release -a
Distributor ID: Ubuntu
Description: Ubuntu 9.10
Release: 9.10
Codename: karmic
Вопрос: Как найти файлы txt в определенной папке folder и в её подпапках? Ответ: find /folder -name *.txt /folder/yate/libs/ysig/usage.txt /folder/yate/tools/gdb-bt-all.txt /folder/yate/share/scripts/yaypm/README.txt
USB и RS232. Распайка и соединение
![]()
Ошибка BH NT_STATUS_ACCESS_DENIED
Иногда при работе SQUID возникают следующие ошибки в файле /var/log/squid3/cache.log 2011/05/24 08:48:58| authenticateNTLMHandleReply: Error validating user via NTLM. Error returned 'BH NT_STATUS_ACCESS_DENIED' [2011/05/24 08:49:05, 0] utils/ntlm_auth.c:winbind_pw_check(545) Login for user [SPII]\[v.menshikov]@[SPII-MENSHIKOV] failed due to [winbind client not authorized to use winbindd_pam_auth_crap. Ensure permissions on /var/run/samba/winbindd_privileged are set correctly.] [2011/05/24 08:49:05, 0] utils/ntlm_auth.c:manage_squid_ntlmssp_request(817) NTLMSSP BH: NT_STATUS_ACCESS_DENIED 2011/05/24 08:49:05| authenticateNTLMHandleReply: Error validating user via NTLM. Error returned 'BH NT_STATUS_ACCESS_DENIED'
Как следствие у пользователей которые работают через прокси, постоянно запрашивает имя и пароль. И в Интернет не дает доступа. Причина таких ошибок проста - неправильно поставлены права.
Самое простое решение это изменить права chown proxy:proxy -R /var/run/samba/winbindd_privileged /etc/init.d/squid3 restart
|
Авторизация
Счетчик посещений






![]() | Сегодня | 39 |
![]() | Вчера | 81 |
![]() | Эта неделя | 462 |
![]() | Та неделя | 508 |
![]() | Этот месяц | 1978 |
![]() | Тот месяц | 2387 |
![]() | Все дни | 22821 |
Online (20 minutes ago): 3
Ваш адрес: 38.107.179.233
,
Today: Янв 28, 2012
Ваш адрес: 38.107.179.233
,
Today: Янв 28, 2012









