Авторизация



Счетчик посещений

mod_vvisit_countermod_vvisit_countermod_vvisit_countermod_vvisit_countermod_vvisit_countermod_vvisit_counter
mod_vvisit_counterСегодня39
mod_vvisit_counterВчера81
mod_vvisit_counterЭта неделя462
mod_vvisit_counterТа неделя508
mod_vvisit_counterЭтот месяц1978
mod_vvisit_counterТот месяц2387
mod_vvisit_counterВсе дни22821

Online (20 minutes ago): 3
Ваш адрес: 38.107.179.233
,
Today: Янв 28, 2012

Поиск

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

Как 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
include
("xmpp.php");
$conn
= new XMPP('talk.google.com', 5222, 'user', 'password', 'xmpphp', 'gmail.com', $printlog=True, $loglevel=LOGGING_INFO);
$conn
->connect();
while(!$conn->disconnected) {
    $payloads
= $conn->processUntil(array('message', 'presence', 'end_stream', 'session_start'));
   
foreach($payloads as $event) {
        $pl
= $event[1];
       
switch($event[0]) {
           
case 'message':
               
print "---------------------------------------------------------------------------------\n";
               
print "Message from: {$pl['from']}\n";
               
if($pl['subject']) print "Subject: {$pl['subject']}\n";
               
print $pl['body'] . "\n";
               
print "---------------------------------------------------------------------------------\n";
                $conn
->message($pl['from'], $body="Thanks for sending me \"{$pl['body']}\".", $type=$pl['type']);
               
if($pl['body'] == 'quit') $conn->disconnect();
               
if($pl['body'] == 'break') $conn->send("</end>");
           
break;
           
case 'presence':
               
print "Presence: {$pl['from']} [{$pl['show']}] {$pl['status']}\n";
           
break;
           
case 'session_start':
                $conn
->presence($status="Cheese!");
           
break;
       
}
   
}
}
?>

 

Как установить ejabberd

Не будем рассказывать как устанавливать 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, [

{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

Кстати, если  мы  запишем


^555$=wave/record//path/to/file/rec.slin


то при звонке на номер 555 мы сможем записывать наш разговор, в файл rec.slin


Yate позволяет использовать в своей работе внешние скрипты, в частности на языке PHP и Python. Это открывает перед нами огромные возможности по созданию шедевров навигации, обработки сигналов, записи звука через голосовое меню.

Для начала в файле extmodule.conf укажем где будут находится наши скрипты

[general]
scripts_dir=/usr/local/lib/yate/

 

и файле маршрутизации мы добавляем

^555$=external/nodata/voicemail.php

 

при наборе 555 - будет выполняться внешний скрипт voicemail.php


Для примера всегда можно взять за основу файл ivrsample.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 меньше по размеру, а также поддерживает передачу многоканальных цифровых аудиосигналов

Ножка Сигнал
1 T.M.D.S DATA 2-
2 T.M.D.S DATA 2+
3 T.M.D.S DATA 2/4 SHIELD
4 T.M.D.S DATA 4-
5 T.M.D.S DATA 4+
6 DDC CLOCK
7 DDC DATA
8 ANALOG VERT. SYNC
9 T.M.D.S DATA 1-
10 T.M.D.S DATA 1+
11 T.M.D.S DATA 1/3 SHIELD
12 T.M.D.S DATA 3-
13 T.M.D.S DATA 3+
14 +5V POWER
15 GND
16 HOT PLUG DETECT
17 T.M.D.S DATA 0-
18 T.M.D.S DATA 0+
19 T.M.D.S DATA 0/5 SHIELD
20 T.M.D.S DATA 5-
21 T.M.D.S DATA 5+
22 T.M.D.S CLOCK SHIELD
23 T.M.D.S CLOCK+
24 T.M.D.S CLOCK-
С1 ANALOG RED
С2 ANALOG GREEN
С3 ANALOG BLUE
С4 ANALOG HORZ SYNC
С5 ANALOG GROUND

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. Распайка и соединение

Контакт DB9
Обозначение
Описание
IN/OUT
1
DCD
Data Carrier Detected - обнаружение несущей
IN
2
RD
Receive Data - принимаемые данные
IN
3
TD
Transmit Data - передаваемые данные
OUT
4
DTR
Data Terminal Ready - готовность терминала
OUT
5
SG
Signal Ground - сигнальная земля
-
6
DSR
Data Set Ready - готовность данных
IN
7
RTS
Request To Send - запрос на передачу
OUT
8
CTS
Clear To Send - готовность к приему
IN
9
RI
Ring Indicator - индикатор вызова
IN

 




Вывод Название Цвет провода Описание
1 VCC Красный +5В
2 D- Белый Данные -
3 D+ Зеленый Данные +
4 GND Черный Земля

 

Ошибка 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


 

 
© 2007-2011 Позитивные решения - удобные решения для бизнеса.