среда, 31 декабря 2008 г.

FreeSWITCH, кодеки, g729

А вы в курсе, что FreeSWITCH практически единственное решение в мире открытых исходников, которое поддерживает HD кодеки?

Так недавно была добавлена поддержка кодеков Siren от компании Polycom. Была добавлена поддержка кодека celt! А кодек celt это 48 кГц - больше чем у CD записей. И это в полосе меньшей, чем у G.711 с 8 кГц. В общем жду когда эти кодеки можно будет попробовать в каком-нибудь IP-телефоне.

Хотя чего ждать? FreeSWITCH может работать как программный IP-телефон. Фактически, linux+FS это готовая программная начинка для IP-телефона с огромными возможностями. 3-way конференция? Легко, причем в HD качестве. Правда пытался присмотреться к железу, на котором можно было бы подобное собрать, и понял что ничего в этом не понимаю - большинство попадавшихся плат были для разработчиков, то есть не для использования для сборки в каких либо продуктах, и откуда берут платы производители телефонов не понимаю. Видимо они их могут сами спроектировать.

А пока я пытаюсь собрать/дописать кодек G.729. Программист на C из меня вообще никакой, так что утечки памяти гарантирую :) Исходники моего творчества лежат тут, если кто то захочет помочь - милости прощу, с радостью свалю задачу человеку, который хорошо понимает значение всех этих звездочек. Если кому то просто интересно получить рабочий кодек (не гарантирую, что стабильный) заглядывайте, смотрите на прогресс.

воскресенье, 21 декабря 2008 г.

Путешествие группы формант по голосовому тракту

Трое монтажников связи. Страдания Джорджа и Гарриса. Жертва ста семи помех. Полезные рецепты. Средство против болезней голосового тракта у монтажников. Монтажники сходятся на том, что переутомились и что им нужен отдых. Неделя в море, вдали от лапши? Джордж предлагает путешествие по реке. Монморенси выдвигает возражение, лапша недостаточно удаляется. Первоначальное предложение принято большинством трех против одного.


Аналоговая телефония



Все что нужно, чтобы связаться посредством двух телефонов - двухжильный провод и питание постоянным током (батарейка "Крона", например). Эту нехитрую истину знают монтажники связи - десятилетия у каждого из представителей доблестной профессии в сумке болтается переделанная трубка от советского дискового телефона.

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

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

В дисковых телефонах номер набирался серией импульсов, что в трубке слышалось как серия щелчков. Импульсный набор зародился во времена декадно-шаговых АТС. Импульсы с телефонного аппарата напрямую управляли процессом набора номера на станции. Декадно-шаговые АТС были первыми автоматическими телефонными станциями.

На сегодняшний день используются цифровые АТС и IP-АТС. То есть, конечно, в глухих лесах необъятной Родины можно найти и АТС декадно-шаговой системы, координатные АТС и прочие системы, но на новых объектах их не ставят, а в городах стараются заменять.

АТС в телефонном тракте на начальном этапе играла роль источника питания и коммутатора - между абонентами одной АТС соединение устанавливало одну электрическую цепь. Конечно же на качестве связи отражалось всё - скрутки, станционные приборы, наводки, тепловые токи и т.д.

Цифра


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

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

Человеческое ухо способно воспринимать звук с частотами от 20 герц до 24-25 килогерц. В соответствии с теоремой Котельникова (Найквиста) для оцифровки сигнала требуется частота выборки в два раза большая частоты сигнала. В действительности, для передачи голоса, достаточно гораздо более узкой полосы - в телефонии принята полоса от 300 Гц до 3 кГц. То есть в этой полосе располагаются основные форманты, которые наиболее значимы для различимости речи. В телефонии используется частота дискретизации (выборки) 8 кГц. При использовании 8-ми бит на один шаг получаем 64 кбит/c. В IP-телефонии кодек с такими характеристиками называется G.711.

Таким образом 64 кбит/c является стандартной скоростью передачи одного голосового канала в цифровой технике связи. С какой бы технологией вы не столкнулись - многоканальная связь, цифровая телефония, ISDN, ИКМ - везде под один голосовой канал отводится именно такая пропускная способность. Все скорости передачи в цифровой телефонии кратны 64 кбит/с и теперь вы знаете почему. Так же вам теперь понятно, почему сигнал ADSL, использующий частоты за голосовым спектром, не может быть пропущен через цифровые тракты, и обычно оканчивается на ближайшей городской АТС - телефония предполагает передачу сигнала с частотой не более 3 кГц.

Модемы и факсы также спроектированы с учетом этих фактов. Поэтому, когда в IP-телефонии используется этот же кодек (G711,64 кбит/с), факсы путешествуют через такие каналы без проблем.

Цифровые АТС работают именно с такими потоками. Если к цифровой АТС есть возможность подключить традиционные аналоговые телефоны - на входе их сигнал будет кодирован в цифровой и внутри АТС будет обрабатываться точно так же, как сигналы от цифровых телефонов.

В данной серии были изложены основы и упомянута теорема Котельникова, а Монморенси совершил подвиг, зажав зубами кабель, и спас селекторное. В следующих сериях страшные истории про кодеки, SIP и SDP, а также продолжение серии о монтажнике Джордже.

Принимаются критические замечания, в том числе и в гугл-группе freeswitch-ru.

пятница, 12 декабря 2008 г.

FreeSWITCH, факсы

Итак, кое-что о факсах. Какими бы бурными темпами ни двигался интернет в каждый дом, факс остается весьма важным средством передачи документов. В протоколах VoIP этому моменту уделено внимание, специально для факсов создан протокол T.38.

Временное отсутствие T.38 в FreeSWITCH я не считаю большой проблемой - на сегодняшний день лучше всего передаются факсы при использовании кодека G.711. T.38 будет реализован в обозримом будущем, а пока я опишу то, что уже есть.
В FreeSWITCH был добавлен модуль mod_fax. Он предоставляет две функции - txfax и rxfax. На текущий момент поддерживается протокол T.30. Пример из wiki:

<extension name="fax">
<condition field="destination_number" expression="^fax$">
<action application="answer" />
<action application="playback" data="silence_stream://2000"/>
<action application="rxfax" data="/usr/local/freeswitch/fax/${caller_id_number}-${strftime(%Y-%m-%d-%H-%M-%S)}.tiff"/>
<action application="hangup"/>
</condition>
</extension>



Обнаружение передачи факса.

FreeSWITCH предоставляет специальную функцию для обнаружения тоновых сигналов в голосовом потоке - tone_detect.

<extension name="5555555">
<condition field="destination_number" expression="^(5555555)$"/>
<action application="tone_detect" data="fax 1100 r +5000 transfer fax XML default"/>
<action application="answer"/>
<action application="sleep" data="1000"/>
<action application="ivr" data="main"/>
<action application="hangup"/>
</condition>
</extension>
<extension name="fax">
<condition field="destination_number" expression="^fax$">
<action application="answer" />
<action application="playback" data="silence_stream://2000"/>
<action application="rxfax" data="/usr/local/freeswitch/fax/${caller_id_number}-${strftime(%Y-%m-%d-%H-%M-%S)}.tiff"/>
<action application="hangup"/>
</condition>
</extension>



А можно поставить обнаружение на всю сессию:

<!-- continue="true" - означает, что надо продолжить выполнение номерного плана после этого пункта -->
<extension name="fax_tone_detect_permanent" continue="true">
<!-- ловим любые звонки, так как .* означает любое кол-во любых символов -->
<condition field="destination_number" expression="^.*$"/>
<!-- ставим обнаружение тона 1100 со стороны звонящего(r) бесконечное время(0)
В случае обнаружения тона передаем (transfer) на обработку в "default" номерной план
с номером "fax"-->
<action application="tone_detect" data="fax 1100 r 0 transfer fax XML default"/>
</condition>
</extension>


Таким образом прием факсов в FreeSWITCH организовать достаточно легко. Надеюсь реализация T.38 не заставит себя долго ждать.

Слабым местом пока остается поддержка кодеков. Все заинтересованные уже знакомы с патентной системой США - практически все дистрибутивы в нашей стране имеют "поддержку кодеков из коробки".
G.729, G.723, AMR сейчас поддерживаются только в режиме без перекодирования. То есть использовать с этими кодеками голосовую почту, голосовые меню, запись разговоров затруднительно.

Заколдованый круг - пока FreeSWITCH не поддерживает кодеки он не очень интересен у нас. А пока он не очень интересен - кодеки реализовывать некому.

воскресенье, 23 ноября 2008 г.

Google-группы по kerberos и Freeswitch

Я создал две новых google-группы для обсуждения вопросов, связанных с kerberos и freeswitch. Просьба все свои вопросы задавать там - формат комментариев к блогу не очень хорошо подходит для подобных обсуждений.


1. ru-kerberos
2. freswitch-ru

четверг, 13 ноября 2008 г.

plasma-mediacontroller

Почему то Am4rok, из Ubuntu 8.10, у меня не работает. Не разбирался, ведь те, кто следят за блогом, знают - теперь есть биндинги под python! Сделал себе свой велосипед - plasma-mediacontroller. Он конечно не так здорово смотрится, но главное он у меня работает.

Если кому то будет интересен, можно продолжить разработку. Сейчас он работает только с Amarok, но нет ничего сложного в добавлении поддержки практически любого медиаплеера. Ведь большинство из них реализует стандартный интерфейс DBus для медиаплееров.

Кому интересно - берите тут. В первой записи о plasma-python есть инструкции по установке плазмоида.

понедельник, 10 ноября 2008 г.

8.10, dkms, nvidia, btrfs

Итак, раз уж в рубунтнете поднялась мода описывать свой опыт по общению с разного вида "козлами" (у кого насколько переводческой фантазии хватит), присоединюсь к этому движению. Да, я тоже обновился до 8.10, чему очень рад. Собственно рад я в основном новой фишке - DKMS.

Некоторое время у меня задурил драйвер Nvidia - я особо не разбирался конечно, и с налету решить не удалось - вместо модуля nvidia_new, который новой версии, грузился старый nvidia. В 8.10 эту часть работы с модулями заменили на DKMS.

Итак, а что это? А это такая система автоматической сборки модуля под ваше ядро. Предположим поставили вы себе 2.6.28, а DKMS тут как тут - тут же соберет модуль и установит его под новое ядро. То есть думать о том, что вы там такого стороннего в ядро напихали, каждый раз совершенно не надо.

И тут у нашего повествования этакий плавный переход. Связующее звено у двух повествований все тот же DKMS. Я экспериментировал с Btrfs, а так как это новая файловая система, планируемая (авторами, когда нибудь : )) ) к включению в ядро, и вообще чтобы корень на нее помещать, то представляет собой она собственно модуль ядра. А модулями ядра у нас теперь ведает - DKMS.

Итак, чтобы вы тоже приобщились к 21 веку, и познали прелесть COW (copy-on-write) систем, дам вам указание верного пути, то есть dkms.conf.
Стягиваем исходники модуля ядра и кладем их в /usr/src/btrfs-0.16 (ну вот такая вот у нас текущая версия). В том же каталоге создаем dkms.conf следующего содержания:

MAKE[0]=make
BUILT_MODULE_NAME[0]=btrfs
DEST_MODULE_LOCATION[0]="/kernel/fs/btrfs"
PACKAGE_NAME="btrfs"
PACKAGE_VERSION="0.16"
CLEAN="make clean"
AUTOINSTALL="yes"


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

root:host~# dkms add -m btrfs -v 0.16
root@rni-15:~# dkms add -m btrfs -v 0.16

Creating symlink /var/lib/dkms/btrfs/0.16/source ->
/usr/src/btrfs-0.16

DKMS: add Completed.
root:host~#
root:host~# dkms build -m btrfs -v 0.16

Kernel preparation unnecessary for this kernel. Skipping...

Building module:
cleaning build area....
make KERNELRELEASE=2.6.27-7-generic............
cleaning build area....

DKMS: build Completed.

root:host~# dkms install -m btrfs -v 0.16
Running module version sanity check.

btrfs.ko:
- Original module
- No original module exists within this kernel
- Installation
- Installing to /lib/modules/2.6.27-7-generic/updates/dkms/

depmod........

DKMS: install Completed.

root:host~# modprobe btrfs

Отлично, теперь скачайте утилиты для работы с btrfs и посмотрите, что вам может дать эта система. А может она вам дать снимки, тома, контрольную сумму всех блоков, raid различных уровней и многое другое. Работает гораздо живее zfs которая на fuse. Но не стоит пока размещать на ней /home or /.

Кстати о снимках, если вы пересилите себя, и доберетесь до самого первого поста этого блога, то увидите там бесподобную идею поставить /etc/ под контроль версий. Идея умерла с того момента, как я познакомился с концепциями zfs и btrfs - это наше файловое будущее.

Подробности, одни из, тут.

четверг, 30 октября 2008 г.

Мой первый плазмоид

Я поклонник KDE и python. С удивлением я, как и многие другие, смотрел на KDE 4.0. После вылизанного 3.5 это было конечно страшно. Особенно мне не хватало kicker и его "кикоидов". Но время идет, проект продолжает развиваться невзирая на возню анонимов на веб просторах, и теперь наконец то есть привязки plasma для python, а значит теперь я сам себе автор плазмоидов.

Мой первый плазмоид страшно кособок, но тем не менее показателен. Итак, по устоявшейся традиции среди Qt-шников, будем делать свой браузер. Правда этот, удивительный своей неординарностью, экземпляр, мы встроим прямо в рабочий стол.

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


mkdir -p wwwv/contents/code
cd wwwv
cat > metadata.desktop << EOF
[Desktop Entry]
Encoding=UTF-8
Name=WWW viewer
Type=Service
ServiceTypes=Plasma/Applet
X-Plasma-API=python
Icon=chronometer

X-KDE-PluginInfo-Author=Mikhail Krivushin
X-KDE-PluginInfo-Email=mkrivushin@yandex.ru
X-KDE-PluginInfo-Name=plasma-wwwv
X-KDE-PluginInfo-Version=1.0
X-KDE-PluginInfo-Website=http://deepwalker.blogspot.com
X-KDE-PluginInfo-Category=Tests
X-KDE-PluginInfo-Depends=
X-KDE-PluginInfo-License=GPL
X-KDE-PluginInfo-EnabledByDefault=true
EOF

cat > contents/code/main.py << EOF
#! /usr/bin/python

from PyQt4.QtCore import *
from PyQt4.QtGui import *
from PyQt4 import QtWebKit
from PyKDE4.kdecore import *
from PyKDE4.kdeui import *
from PyKDE4.plasma import Plasma
import plasma

class PyWWWvApplet(plasma.Applet):
def __init__(self,parent,args=None):
plasma.Applet.__init__(self,parent)

self.url = None
self.clicked = QPoint()

def init(self):
KGlobal.locale().insertCatalog("www")

self.setHasConfigurationInterface(False)
self.setAspectRatioMode(Plasma.IgnoreAspectRatio)

self.dialog = None

self.theme = Plasma.Svg(self)
self.theme.setImagePath("widgets/background")
self.theme.setContainsMultipleImages(False)
self.theme.resize(self.size())

self.webview = Plasma.WebContent()
self.mlayout = QGraphicsLinearLayout(Qt.Vertical)
self.eline = Plasma.LineEdit()
self.mlayout.addItem(self.eline)
self.mlayout.addItem(self.webview)
self.setLayout(self.mlayout)

self.connect(self.eline,SIGNAL('returnPressed()'),self.open_page)

self.webview.setUrl(KUrl('http://127.0.0.1/'))
self.webview.update()

def open_page(self):
page = self.eline.text()
#print "Go to %s"%page
self.webview.setUrl(KUrl(page))
self.webview.update()

def shape(self):
if self.theme.hasElement("hint-square-clock"):
return plasma.Applet.shape(self)
path = QPainterPath()
path.addEllipse(self.boundingRect().adjusted(-2, -2, 2, 2))
return path


def constraintsEvent(self, constraints):
if constraints & Plasma.SizeConstraint:
self.resize(self.size())

def CreateApplet(parent):
return PyWWWvApplet(parent)
EOF

zip -r ../wwwv.zip .

plasmapkg -i wwwv.zip


Конечно же надо поставить соответствующие привязки. Так как я уже на 8.10, то просто сделал aptitude install python-plasma.

Далее располагайте плазмоид на рабочем столе и удивляйтесь мощи моего гения. Теперь же я, пожалуй, отправлюсь спать. А вы, дорогие мои, утомляйте неутомимый google бесчисленными запросами - "plasma python qt webkit" в поисках ответа на вопрос - а как же сделать, чтобы оно использовало прокси?

среда, 1 октября 2008 г.

FreeSWITCH, кластеризация

Вопрос был задан в одном из комментариев - поддерживает ли FS кластеризацию? Этот краткий пост будет ответом.

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

Всю информацию FS хранит в БД, к которой осуществляется доступ через ODBC. Конфигурацию FS может забирать через xml_curl. Таким образом все данные и настройки легко распределяются на несколько серверов.

среда, 17 сентября 2008 г.

FreeSWITCH+Django

FreeSWITCH предоставляет замечательный механизм - xml_curl. Этот модуль может забирать номерной план, пользователей и даже конфигурацию через http запросы.
Работает весьма просто, например так:

# cat /opt/freeswitch/conf/autoload_configs/xml_curl.conf.xml
<configuration name="xml_curl.conf" description="cURL XML Gateway">
<bindings>
<binding name="fs2web_user_fetcher">
<param name="gateway-url" value="http://localhost:8000/get/user/" bindings="directory">
</binding>
</bindings>
</configuration>


# cat /opt/freeswitch/conf/autoload_configs/modules.conf.xml
...
<load module="mod_xml_curl"/>
...



Теперь FS будет слать тонну информации методом POST на web сервер по указаному адресу и ждать в ответ описание пользователя в стандартном xml:


~$ wget http://127.0.0.1:8000/get/user/?sip_auth_username=3000 -O -
--23:36:28-- http://127.0.0.1:8000/get/user/?sip_auth_username=3000
=> `-'
Устанавливается соединение с 127.0.0.1:8000... соединились.
Запрос HTTP послан, ожидание ответа... 200 OK
Длина: нет информации [text/html]

[<=> ] 0 --.--K/s
<document type="freeswitch/xml">
<section name="directory">
<domain name="">
<user id="3000" mailbox="3000">
<params>
<param name="password" value="1234"/>
<param name="vm-password" value="3000"/>
</params>
<variables>
<variable name="accountcode" value="3000"/>
<variable name="user_context" value="public"/>
<variable name="effective_caller_id_name" value="Mihail Krivushin"/>
<variable name="effective_caller_id_number" value="3000"/>
</variables>
</user>
</domain>
</section>
</document>
[ <=> ] 608 --.--K/s

23:36:29 (1.91 MB/s) - `-' сохранён [608]



Ну и напоследок, мне кажется не совсем бесполезная ссылка на пример готового сервера на Django. Клонируйте, и затем поправьте settings.py. Пользователей можно заводить через стандартный административный интерфейс Django. Администратор - "admin", пароль - "kuku".

четверг, 17 июля 2008 г.

Разработчик, возлюби RFC

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

Глюки обнаружились при переходе на FreeSWITCH.
1. Телефоны Linksys SPA901 и SPA921 неправильно называют кодек g729 в SDP (Session Description Protocol). Для того чтобы поправить это, вам нужно зайти на web интерфейс телефона, переключить в режим Admin+Advanced. Далее на вкладке "SIP" в разделе "SDP Payload Types" ищем пункт "G729a Codec Name:" и приводим к виду "g729", то есть убираем "a" на конце.

2. Вообще в интернете не встречал упоминания, но шлюзы Addpac AP1005 (4xFXO) также страдают забавным глюком - они отдают странный SDP при связи друг с другом: a=rtpmap:18 G729/8000/3

Так как FreeSWITCH свято чтит RFC и документ, который будет указан ниже (а быть может эта любовь от SIP стека Sofia, производства компании Nokia), то он прекрасно знает, что rtpmap с номером 18 может означать только G729/8000/1 Никаких "a" или трех звуковых каналов, что вообще забавно смотрится - 3 канала на моно голос это явный перебор.

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

В остальном телефоны и шлюзы впечатление оставляют самое приятное - телефоны работают как от них ожидается, шлюзы Addpac чудесно гибкие в настройке. Но все же - чем им так не угодили RFC?

Как я подозреваю, большинство реализаций смотрит только на номер rtpmap, и ничуть не заботится разбором последующих конструкций. А вот это зря - например кодеки g726-xx статического номера не имеют, а шлюзы Addpac для g726-16 другой номер, кроме как 116, не воспринимают. Это противоречит RFC и этому документу.

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

На этом внеочередное заседание любителей RFC объявляю закрытым.

вторник, 15 июля 2008 г.

FreeSWITCH

Тема VoIP стала на данный момент ближе моему сердцу, чем Kerberos, а виной тому, наверное, инструмент. Мне кажется странным, что мало кто слышал о FreeSWITCH (далее FS), ведь этот наследок Asterisk несет в себе куда более продуманную архитектуру. Нет, что вы, это не очередной форк от Asterisk как вы уже было подумали, вовсе нет. Это вынужденный ход одного из бывших разработчиков Asterisk, он просто решил, что из за кривизны изначальной архитектуры Asterisk проще будет переписать все с нуля.

И знаете, я уже давно не смотрю новые версии Asterisk, так как желание отбито давно и крепко (кто скажет что не ловил ни разу segmentation fault, или глюки с памятью, или же третье пусть считает себя везунчиком, FS vs Asterisk на ЛОРе). В общем с той поры как я решил, что Asterisk не стоит моих нервов, я пересмотрел много альтернатив. Был в списке и CallWeaver, но так как это просто форк Asterisk, то ничего нового в мой опыт он не привнес. Работал я с SipXpbx (с названиями и их сменой у данного продукта мне разбираться лень), тут главной сложностью было его собрать, так как SipXConfig тянет за собой тонны зависимостей и все из мира Java, в котором я полный ноль. Но гибкости в нем нет, это красивое решение, хороший конфигуратор, соответствие стандартам, но нельзя крутить его настройку теми адскими способами, что в FS.

FreeSWITCH мне порекомендовали в самарской news конференции (nntp еще кто то помнит? В Самаре отлично помнят : )) ). Я сразу ожидал что соберу его через неделю, как SipX, но я был невероятно удивлен, когда в директории слитой с svn я увидел столь любимую мной папку debian! А самой главное чудо, что debian/rules binary сработали, лишь пару библиотечек вроде бы доставить пришлось.

Итак, я получил deb пакеты, и поставил их используя dpkg -i. Еще я немного покрутил директорию debian для сборки mod_python (ну любимый инструмент, что поделаешь), если кому то будет интересно могу описать.

В итоге получается практически готовый сервер - в поставку входит демонстрационный Dialplan (план нумерации наверное буду его называть), настроены учетные записи пользователей. То есть можно сразу начинать работать с FS. Если вы ставили из пакетов, то установится FS в папку /opt/freeswitch, конфигурация хранится в директории conf.

Для начала можно настроить любой IP телефон на учетку 1000 с паролем 1234 и попробовать поиграться с голосовыми меню, с голосовой почтой, с конференциями (никаких модулей ядра не нужно) - все прекрасно работает, правда, как это водится, без намека на русский язык. Впрочем, если кому то будет интересно, можем попробовать сделать русскую локализацию сообща.

Впечатления - все что заявлено работает, в плане нумерации используются регулярные выражения (наверное сразу представили себе что можно с этим вытворить?), набор команд покрывает практически любые хотелки.

Теперь немного по первичной настройке SIP. Для работы с SIP используется mod_sofia (а он используется open source библиотеку от Nokia), загружен по умолчанию. Для работы нужны профили (conf/sip_profiles). Например если вам нужно чтобы на ваш SIP сервер могли звонить все кому придется без регистрации, то вы создаете профиль, настраиваете его, проставляете ему контекст(context), и перезапускаете FS. Профили должны использовать разные порты.

Контексты это отдельные планы нумерации - у профиля прописан контекст по умолчанию, у пользователей могут быть указаны свои (то есть отличающиеся от профиля по умолчанию). План нумерации хранится в conf/dialplan, очень сильно рекомендуется к изучению - там очень много интересного.

Итак, вы стартовали и вам понравилось? Я на это надеюсь, и поэтому дам совет как изучать FreeSWITCH - идете в wiki проекта. Можно просто походить по разделам, но гораздо лучше взяться за файл conf/dialplan/default.xml и вставлять из него непонятные конструкции в поиск по wiki - так вы можете сразу узнать для чего та или иная команда.

Надеюсь вам понравится FreeSWITCH, приятного изучения.

суббота, 5 июля 2008 г.

NFSv4 vs Samba

Выбор это сложная и важная часть в построении офисно-торговых сетей. Вы выбираете роутеры, свитчи, эникейщиков, и, конечно же, технологии, протоколы, программы. Выбор между Kerberos и чистой LDAP аутентификациями для вас я думаю уже ясен, хотя, к сожаления, не обязательно совпадает с моим.

Теперь я задумался - а нужен ли NFSv4? Он весь такой обновленный, очищенный от лишнего, ускоренный и поддерживает Kerberos. Включен в ядро, в дистрибутивы, и даже местами описана его настройка. А также никоим образом не позволяет побороть umask и различия в кодировках, и совершенно не поддерживается windows.

Samba весьма гибкий инструмент, с огромным количеством документации, не лезет в ядро (только клиент, но ядерный клиент пока не сильно интересен - Samba 3.2 конечно вышла, но когда новый mount.cifs упадет в дистрибутивы не известно), есть кластерные примочки, кодировки поддерживаются, в описаниях шары можно указать маску для новых файлов и не только.

Так зачем мне тогда NFSv4, судьба которого еще года два проходить в бетах, так и оставить неразрешенной проблему cross realm, и вообще существовать в отрыве от реальности. У меня постоянно вылезает с ней проблема umask - ну нельзя же делать umask 000! Это в конце концов не только к шарам относится, но и к домашней папке, а системы у нас, как известно, многопользовательские.

Насколько все таки мудро в AFS раздавались права на папки, жаль вот только с кодировками там также полный облом.

В общем Samba на сегодняшний день лучшая сетевая FS для бизнеса/офиса и не только.

вторник, 24 июня 2008 г.

Subversion 1.5 и SASL

Если кто-то пропустил, то обращаю внимание, что теперь Subversion поддерживает GSSAPI, так как они перешли на стороннюю библиотеку для реализации SASL.

Поддержка есть как в svnserve, так и в клиенте. Настройки абсолютно стандартные - принципиал svn/`hostname -f` в keytab, и указать имя keytab в переменной окружения KRB5_KTNAME для svnserve. Ну и надо прописать в списке методов gssapi (документация рулит).

понедельник, 23 июня 2008 г.

Как мне установить программу, распространяемую в исходных кодах?

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


Вступление


Существует несколько способов. Практически у всех есть общая часть - распаковать исходники:
tar xvfj mega_app.tar.bz2
or
tar xvfz mega_app.tar.gz
Выполнить комманду ./configure, затем make. Эти комманды служат для сборки из исходных кодов исполняемых файлов, библиотек и тп.

Отдельно стоит отметить первую комманду - ./configure
Если выполнить ./configure --help, то вы получите список параметров, которые можно передать ./configure
Например часто возможна такая комманда:
./configure --prefix=/opt/mega_app

Или указать путь к библиотеке, которая по каким либо причинам не нашлась сама:
./configure --kerberos-lib=/opt/kerberos/lib

Классический.


Итак делаем последовательность:
./configure
make
и команда которая собственно установит все составляющие программы в систему:
make install
WARNING!!! Используя этот способ легко получить очень серьезные проблемы в дальнейшем. Во первых, скорее всего,
вы не сможете удалить программу (make uninstall).

Checkinstall.


Правильный путь. После выполнения общей части запускаете:
checkinstall
Программа сама спросит вас обо всем, а можете просто везде нажать ENTER.
man checkinstall тоже очень хороший путь : ))

Сборка пакета для Debian.


Это отдельный и сложный путь - вам нужно разобраться со многими аспектами создания deb-пакетов (или любых других).
Здесь этот путь не будет описан в полной мере, только пример как собрать пакет из уже подготовленных материалов. Я,
например, пользовался им чтобы сделать бекпортинг пакетов из Feisty в Dapper.
Итак, пример. Идем на packages.ubuntu.com, находим нужный пакет (diff например) и качаем два файла - исходник (http://archive.ubuntu.com/ubuntu/pool/main/d/diffutils/diffutils_2.8.1.orig.tar.gz) и патч к нему, который поправит исходники и создаст папку debian с магическим файлом rules внутри (http://archive.ubuntu.com/ubuntu/pool/main/d/diffutils/diffutils_2.8.1-11ubuntu4.diff.gz).
Я скопировал их в папку ~/test и для начала распаковал исходник:
tar xvfz diffutils_2.8.1.orig.tar.gz
А затем наложил патч:
cd diffutils-2.8.1/
gzip -cd ../diffutils_2.8.1-11ubuntu4.diff.gz | patch -p1
Теперь надо сделать debian/rules исполняемым:
chmod 750 debian/rules
И собрать пакет:
fakeroot debian/rules binary
Fakeroot нужна для сборки пакета обычным пользователем (обычно многие операции требуемые не позволили бы вам сделать пакет).
ls ../
diff_2.8.1-11ubuntu4_i386.deb diffutils-2.8.1 diffutils_2.8.1-11ubuntu4.diff.gz diffutils_2.8.1.orig.tar.gz
Как видите, пакет готов.

Заключение


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

Ну и конечно автор ответственности не несет ни за что и никогда : ))

среда, 18 июня 2008 г.

Инфраструктура Kerberos, Windows

Включение Windows машины в сферу Kerberos


В этой статье прекрасно описана процедура включения машины под управлением Windows в сферу Kerberos и настройки Samba. Если нет сервера с AD, то это прекрасный метод, только пользователей вручную создавать придется (возможно еще при помощи cfengine или сделать скрипт для синхронизации с LDAP).

Доверительные отношения сферы Kerberos и домена Active Directory



Первым делом ссылка на документацию от Heimdal.

Для настройки доверия нам потребуется утилита ksetup (вы же прочитали статью по ссылке?), с ее помощью мы настроим в Windows адреса KDC сферы на каждом контроллере AD:

$ ksetup.exe /addkdc REALM.TLD kdc1.realm.tld
$ ksetup.exe /addkdc REALM.TLD kdc2.realm.tld

Возможно потребуется перегрузить контроллер. Настройка доверия на контроллере AD:

$ netdom trust AD-REALM.TLD /Domain:SOUZT.TLD /add /realm /passwordt:пароль_доверия

Теперь надо добавить доверительную запись в базу нашего KDC:

# kadmin -l
> add krbtgt/AD-REALM.TLD@REALM.TLD <<< ввести пароль_доверия
> add krbtgt/REALM.TLD@AD-REALM.TLD <<< ввести пароль_доверия


Важно - надо удалить типы кодирования ключей, которые не поддерживаются AD, то есть все кроме des-cbc-md5(pw-salt), des-cbc-md4(pw-salt), des-cbc-crc(pw-salt), arcfour-hmac-md5(pw-salt). Точный список сейчас не скажу, например в W2003R2 была какая то проблема, связанная со сменой типа ключа используемого по умолчанию. Если кто то имеет более актуальную информацию - поделитесь.

Я использую это доверие в работе для доступа к ресурсам AD - к сетевым папкам и каталогу LDAP. Для этого надо настроить отображение - mapping. Отличная ссылка из первых рук, но попробую описать на родном.

Нам понадобится оснастка MMC для управления учетками, меню <Вид>, галочку на <Дополнительные функции>. Теперь находим пользователя deepwalker, в контекстном меню выбираем <Отображение имен>. Выбираем вкладку Kerberos и добавляем в список deepwalker@REALM.TLD. На этом все, попробуйте сделать нечто вроде:

ldapsearch -H ldap://pdc.ad-realm.tld/ -Y gssapi -b dc=ad-realm,dc=tld
klist

Весь домен должен промелькнуть у вас перед глазами, а в выводе klist должна появится строка:

Jun 18 11:19:24 Jun 18 19:08:22 ldap/pdc.ad-realm.tld@AD-REALM.TLD

Это будет означать, что билет вы получили и доверие работает. Далее можете попробовать зайти в сетевые папки через konqueror или через подобную программу.

Fusesmb поддерживает gssapi, но ее часть, составляющую список сетевых папок, надо прибивать. В противном случае, по истечении билета, ваша учетка в AD очень быстро будет заблокирована.

На сегодня все, а про гневные комментарии вы и так помните : ) Надеюсь, что если я что то здесь не доосветил, то приведенные ссылки и google.ru вам помогут.

вторник, 17 июня 2008 г.

Инфраструктура Kerberos, Squid

LDAP мы уже настраивали, перейдем к одной из самых популярных серверных компонент - прокси серверу, в нашем случае это Squid.
Достаточное время существует механизм аутентификации для HTTP протокола - Negotiate. В среде windows используется SSPI, в linux GSSAPI. Поддерживается механизм в Firefox, WebKit (Safari), Konqueror, IE7, Squid, ISA server. Про Opera не подскажу, не использую.

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

Собрать Squid надо с ключами --enable-auth="negotiate" --enable-negotiate-auth-helpers="squid_kerb_auth" (это не означает, что других ключей не надо). Надо сказать, что из коробки такой метод сборки хелпера аутентификации squid_kerb_auth работает только для MIT библиотек и для Heimdal надо лезть в helpers/negotiate_auth/squid_kerb_auth/Makefile и править руками (сами найдете где).

Ну и если squid у вас в дистрибутиве уже собраный, то скорее всего хелпера там нет. Сильно рекомендую собирать не из исходников с сайта, а взять исходник из своего дистрибутива и поправить сборочные скрипты. Для debian based надо зайти на packages.*.*, найти squid, скачать исходник и diff к нему, распаковать исходники и пропатчить. Затем vim debian/rules, chmod 755 debian/rules, fakeroot debian/rules binary. Примерно так : ) Заодно разберетесь как пакеты собирать, кто не в курсе.

Еще есть возможность скачать squid_kerb_auth из cvs с sourceforge, но я не думаю, что в дистрибутивном squid вообще включен механизм negotiate, так что пересобирать все равно придется (к слову у меня он как раз из cvs).

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

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

/etc/krb5.conf настраиваете по аналогии с предыдущими статьями (копируете просто).

В squid.conf:

auth_param negotiate program /usr/local/squid/libexec/squid_kerb_auth -d -s HTTP/squid_host.realm.tld@REALM.TLD
auth_param negotiate children 10
auth_param negotiate keep_alive on


Выгружаем ключи:

kinit admin/admin
ktutil -k /etc/squid/HTTP.keytab HTTP/`hostname -f` >>> DNS конечно же уже настроен в обе стороны?
chown squid-user /etc/squid/HTTP.keytab >>> пользователя смотрим в своем конфиге
kdestroy


В стартовый скрипт squid (/etc/rc.d/rc.squid, /etc/init.d/squid):

export KRB5_KTNAME=/etc/squid/HTTP.keytab <<< перед стартом демона


Перезапускаем, радуемся жизни пишем баг репорты (можно поднять тему на opennet.ru и дать мне ссылку в комментарии) - всем помогу : )

четверг, 12 июня 2008 г.

Инфраструктура Kerberos, рабочая станция

Рабочая станция, при включении в инфраструктуру должна осуществлять аутентификацию, через PAM, брать авторизационную информацию из источников, настроенных в /etc/nsswitch.conf, и, заодно, быть включенной в какую либо систему управления.

Самое первое, это на каждой машине установить поддержку kerberos:
aptitude install heimdal-clients
и настроить /etc/krb5.conf также, как и на KDC в первой заметке из серии (проверяем пытаясь получить билет и тп).

Для начала аутентификация. В нашем случае это, конечно же, kerberos, что как мы помним, дает нам множество неоспоримых преимуществ. Для этого ставим модули pam:
aptitude install libpam-heimdal libpam-ccreds
Модуль ccreds нам понадобится для локального кеширования пароля, на случай отсутствия связи с сервером (особенно актуально для ноутбучников). Пароль конечно не хранится в чистом виде - это хеш, что исключает его подбор в обозримом будущем, в случае кражи файла с парольным кешем.

Настройки PAM.
/etc/pam.d/common-auth

auth [success=done default=ignore] pam_unix.so nullok_secure try_first_pass
auth [authinfo_unavail=ignore success=1 default=2] pam_krb5.so use_first_pass minimum_uid=1000 forwardable debug
auth [default=done] pam_ccreds.so action=validate use_first_pass
auth [default=done] pam_ccreds.so action=store
auth [default=bad] pam_ccreds.so action=update

/etc/pam.d/common-account

account sufficient pam_krb5.so forwardable minimum_uid=1000
account required pam_unix.so use_first_pass

/etc/pam.d/common-session

session required pam_unix.so
session optional pam_foreground.so
session optional pam_krb5.so
session required pam_mkhomedir.so umask=0022 skel=/etc/skel


Теперь при входе получается билет, пароль кешируется, все замечательно. Вот только не будет работать. Вся информация о наших пользователях хранится в ldap, надо ее доставить на рабочие станции:
aptitude install libnss-ldapd libnss-db nss-updatedb
Здесь у нас опять таки помимо необходимой библиотеки идет кеширующий комплект - nss-updatedb забирает информацию из ldap и дублирует ее в локальные базы - на случай отсутствия связи с сервером. Запускать через cron или через cfengine (советую почитать - интересная вещь).

Редактируем /etc/nss-ldapd.conf:

uri ldap://kdc.realm.tld
base dc=realm,dc=tld
ldap_version 3
scope sub
use_sasl on
krb5_ccname FILE:/tmp/krb5cc_0


В /etc/nsswitch.conf, правим только эти две строки:

passwd: files ldap [NOTFOUND=return] db
group: files ldap [NOTFOUND=return] db


А так как для libnss-ldapd демона мы указали, что ему нужно получать доступ к каталогу с помощью ключа Kerberos, то надо ему этот ключ предоставить. Здесь мы возращаемся к настройке сервера.
В /etc/inetd.conf должна присутствовать строка:
kerberos-adm stream tcp nowait root /usr/lib/heimdal-servers/kadmind kadmind

В /etc/heimdal-kdc/kadmind.acl:

deepwalker/admin all

Это немного другой пользователь, добавьте его в базу kerberos. Также, я думаю, вы уже сами настроили bind и прямую и обратную зоны и время у вас на машинах сильно не различается, потому что описываться это будет несколько позже. Вернемся к рабочей станции, получаем билет:

sudo su >>> root
kinit deepwalker >>> получаем билет
ktutil get host/`hostname -f` >>> загружаем с сервера ключи для машины
kdestroy >>> теперь ключ администратора не нужен - убираем его
kinit -k host/`hostname -f` >>> получаем билет для машины
/etc/init.d/nslcd restart >>> Рестартуем демона ldapd
/etc/init.d/nscd restart >>> рестартуем nscd
exit >>> больше нам root не нужен

Теперь должно быть возможным заходить под пользователем из каталога LDAP с паролем Kerberos. Здесь я не описывал, но вообще то в каталоге надо создать предварительно контейнер, где KDC будет хранить ключи рабочей станции, что то вроде:

dn: dc=kdc.realm.tld,ou=hosts,dc=realm,dc=tld
uid: host/kdc.realm.tld
krb5PrincipalName: host/kdc.realm.tld@REALM.TLD
objectClass: top
objectClass: krb5KDCEntry
objectClass: krb5Principal
objectClass: domainRelatedObject
objectClass: dcObject
objectClass: dNSDomain
objectClass: posixAccount
associatedDomain: kdc.realm.tld
uidNumber: 5002
krb5KDCFlags: 126
dc: kdc.realm.tld
gidNumber: 5000
homeDirectory: /home/cfengine
cn: kdc.realm.tld
krb5KeyVersionNumber: 0

dn: uid=nfs,dc=kdc.realm.tld,ou=hosts,dc=realm,dc=tld
objectClass: krb5KDCEntry
objectClass: krb5Principal
objectClass: account
uid: nfs
krb5KDCFlags: 126
krb5PrincipalName: nfs/kdc.realm.tld@REALM.TLD
krb5KeyVersionNumber: 0

>>> Ну следующая запись требуется только для сервера, если конечно вы не хотите поднять LDAP для каких либо иных нужд
dn: uid=ldap,dc=kdc.realm.tld,ou=hosts,dc=realm,dc=tld
objectClass: krb5KDCEntry
objectClass: krb5Principal
objectClass: account
uid: ldap
krb5KDCFlags: 126
krb5PrincipalName: ldap/kdc.realm.tld@REALM.TLD
krb5KeyVersionNumber: 0


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

четверг, 29 мая 2008 г.

Инфраструктура Kerberos, сервисы

Теперь, когда у нас есть KDC, можно настраивать доступ к службам с использованием Kerberos.
Первым делом пример доступа к LDAP, так как этот сервис уже настроен. OpenLDAP поддерживает SASL(Simple Authentication and Security Layer). Почитать: http://bog.pp.ru/work/SASL.html или в Википедии.

Одним из механизмов SASL выступает GSSAPI - как раз наш случай, Kerberos (на самом деле не только). Остается настроить этот механизм (фрагмент /etc/ldap/slapd.conf):

sasl-realm REALM.TLD
sasl-host kdc.realm.tld

Далее надо чтобы был настроен /etc/krb5.conf, установлен пакет libsasl2-modules-gssapi-heimdal (или mit, но если вы читали статью про heimdal-kcm, то выбрать вам будет проще).

Если это все готово, то переходим к следующему этапу - надо сделать keytab файл для slapd. Тут стоит остановиться подробнее - keytab файл хранит ключи для сервисов (вы же не будете настукивать пароль при каждом обращении пользователя :) ). Чтение этого файла, всем кроме root, противопоказано, а slapd у нас работает от пользователя openldap. Значит делаем финт ушами:
в /etc/default/slapd добавим строчку - export KRB5_KTNAME="FILE:/etc/ldap/slapd.keytab". Это укажет slapd где искать ключи. Далее надо собствено выгрузить ключи:

kadmin -l ext --keytab=/etc/ldap/slapd.keytab ldap/kdc.realm.tld
chown openldap.openldap /etc/ldap/slapd.keytab


Надеюсь вы помните, что мы пока находимся все на том же сервере, а поэтому мы используем kadmin с ключом "-l", что позволяет пользователю root делать что угодно с базой kerberos. Для доступа с другой машины надо будет настроить kadmind

Ключи выгружены, slapd настроен, рестартуем демон: /etc/init.d/slapd restart
Проверка:

root@kdc:~# kinit deepwalker <<< надо будет ввести пароль
root@kdc:~# ldapsearch -H ldap://127.0.0.1 -Y GSSAPI
>>> тут должно быть выведено все дерево каталога <<<


Примерно таким же образом настраивается все остальное. Например для apache надо будет подгрузить модуль с поддержкой kerberos, выгрузить ключи вида HTTP/wwwhost.realm.tld. Для NFSv4 ключи надо выгружать в стандартный /etc/krb5.keytab для каждой машины. Впрочем по отдельным сервисам статьи можно написать будет отдельно. Главную мысль вы, я надеюсь, уловили.

Проблемы:
главная проблема это DNS (расхождения времени мы пока получить не можем, так как машина одна). В /etc/hosts вбейте нечто вроде:

127.0.0.1 localhost
192.168.0.1 kdc.realm.tld kdc


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

понедельник, 26 мая 2008 г.

mount.cifs & kerberos

Недавно прошла конференция в Томске, на которой я был докладчиком. В качестве одной из проблем взаимодействия linux и windows сред, я указал проблему с поддержкой kerberos в cifs подсистеме ядра - долгое время ее там просто не было.

Так вот http://abbra.livejournal.com/ подсказал, что ребята из Samba team озаботились этой проблемой - kerberos в mount.cifs быть!

После этого замечания, я стал искать - а как же я могу уже это использовать, и пришел к выводу, что пока никак - для работы, как я выяснил, требуется cifs.spnego - хелпер для mount.cifs. Также, как я понял, этот хелпер будет в Samba 3.2. Вообще толковой информации накопать так и не удалось, ясно, что smbfs из ядра уберут (или уже), а cifs доделали. Неясно в какой версии ядра это все есть, неясно как использовать.

Если есть кто то, кто в курсе, как это будет, напишите пожалуйста.

На самом деле Samba выглядит гораздо более готовой для использования, чем NFSv4. Также Abbra говорил, что большую часть работы в ветке Samba4 доделают к концу года, а мне казалось, что проект стоит ожидать в следующем веке. В этом свете, мне кажется, что можно будет строить домены на Samba, не изобретая свой велосипед на Kerberos + LDAP, ведь у этой связки есть достаточно серьезные проблемы о которых будет следующая запись.

Инфраструктура Kerberos, начало

Как и обещал, попробую написать, как это делается. Приветствуются замечания, предложения, улучшения. Если есть что добавить к документу - я всеми руками за. Указывайте на ошибки, ругайте и тп : )

Вообще автор ждет Samba4, а пока спасается как может.

Итак, мы строим следующую структуру:
1. Heimdal KDC - центр распределения ключей;
2. OpenLDAP 2.4 - каталог, здесь будет храниться вся сетевая конфигурация. Такая как ключи kerberos, DNS, конфигурация (в предыдущих постах я описывал SCFL, только вот пока не выложил).

Я использую ubuntu 8.04, поэтому, как обычно, правит каждый сам под себя. Да и вообще - не надо всему, что вы прочли в интернете, слепо верить - стоит почитать документацию.

Ставим минимальный набор:

aptitude install heimdal-kdc slapd heimdal-clients pdns-server pdns-backend-ldap


Правим /etc/heimdal-kdc/kdc.conf:

[kdc]
logging = FILE:/var/log/heimdal-kdc.log
database = {
realm = REALM.TLD
dbname = ldap:dc=realm,dc=tld
mkey_file = /var/lib/heimdal-kdc/m-key
acl_file = /etc/heimdal-kdc/kadmind.acl
}


Правим /etc/ldap/slapd.conf:

include /etc/ldap/schema/core.schema
include /etc/ldap/schema/cosine.schema
include /etc/ldap/schema/nis.schema
include /etc/ldap/schema/inetorgperson.schema
include /etc/ldap/schema/hdb.schema
include /etc/ldap/schema/dnsdomain2.schema #PowerDNS схема расширяющая стандартную

pidfile /var/run/slapd/slapd.pid
argsfile /var/run/slapd/slapd.args
loglevel 0

modulepath /usr/lib/ldap
moduleload back_bdb
moduleload syncprov #Для синхронизации

sizelimit 500
tool-threads 1
backend bdb
sasl-realm REALM.TLD
sasl-host kdc.realm.tld

# Следующая строчка преобразует пользователя, подключающегося через sasl механизм
# GSSAPI(kerberos) к его реальному DN в дереве.
# В данном случае поиском, так как у меня они не лежат в одной папке.
authz-regexp uid=([^,]*),cn=realm.tld,cn=gssapi,cn=auth
ldap:///dc=realm,dc=tld??sub?(uid=$1)


database bdb #Мне тут сказали, что лучше использовать hdb. Попробую, почитаю.
suffix "dc=realm,dc=tld"
checkpoint 512 30
directory "/var/lib/ldap"

# Далее настройки хранилища bdb какие были по умолчанию. Надо бы разобраться и докрутить.
dbconfig set_cachesize 0 2097152 0
dbconfig set_lk_max_objects 1500
dbconfig set_lk_max_locks 1500
dbconfig set_lk_max_lockers 1500

# Настройки индекса. В общем то надо расширить их значительно.
index objectClass,uid eq
lastmod on

access to attrs=userPassword,shadowLastChange
# Везде рекомендуют вначале привести к нормальному имени.
# Пометим как TODO
by dn="gidnumber=0+uidnumber=0,cn=peercred,cn=external,cn=auth" write
by * none

access to attrs=krb5Key
by dn="gidnumber=0+uidnumber=0,cn=peercred,cn=external,cn=auth" write
by * none

access to dn.base="" by * read
access to dn.subtree="ou=config,dc=realm,dc=tld"
# Мне можно править : )
by dn.base="uid=deepwalker,ou=users,dc=realm,dc=tld" manage
# Остальным читать
by users read
by anonymous auth
by * none

access to *
by dn="gidnumber=0+uidnumber=0,cn=peercred,cn=external,cn=auth" write
by users read
by anonymous auth
by * none
# Последняя строчка для синхронизации
overlay syncprov

Теперь надо инициализировать LDAP, но для начала в /etc/default/slapd вставляем строчку:

SLAPD_SERVICES="ldap:/// ldapi:///"

Это заставит демон слушать на локальном сокете. Перезапускаем, и создаем файлик base.ldif с содержимым:

# realm.tld
dn: dc=realm,dc=tld
objectClass: dcObject
objectClass: organization
o: realm
dc: realm

# users, realm.tld
dn: ou=users,dc=realm,dc=tld
ou: users
objectClass: top
objectClass: organizationalUnit

# hosts, realm.tld
dn: ou=hosts,dc=realm,dc=tld
ou: hosts
objectClass: top
objectClass: organizationalUnit

# groups, realm.tld
dn: ou=groups,dc=realm,dc=tld
ou: groups
objectClass: top
objectClass: organizationalUnit

Теперь загрузим его в базу:

cat base.ldif | ldapadd -H ldapi:/// -Y EXTERNAL

Здесь это делается от root, мы подключаемся к локальному сокету и аутентифицируемся по специальному sasl механизму external - просто локальные пользователи.

Ну и инициализация KDC:

# /etc/init.d/heimdal-kdc restart
# kadmin -l
> init REALM.TLD

Далее надо по идее создать пользователя. Если вы в kadmin сделаете "add deepwalker", то создаст он вам пользователя немного не так, как хотелось бы, а по сему делаем tmpuser.ldif:

dn: uid=TMPUSER,ou=users,dc=realm,dc=tld
uid: TMPUSER
krb5PrincipalName: TMPUSER@REALM.TLD
objectClass: top
objectClass: posixAccount
objectClass: shadowAccount
objectClass: inetOrgPerson
objectClass: organizationalPerson
objectClass: person
objectClass: userSecurityInformation
objectClass: krb5KDCEntry
objectClass: krb5Principal
loginShell: /bin/bash
uidNumber: TMPUIDNUM
krb5KDCFlags: 126
gidNumber: 2000
sn: TMPUSER
homeDirectory: /home/TMPUSER
krb5KeyVersionNumber: 1

И используем:

root@kdc:~# a=`ldapsearch -H ldapi:/// -Y external uidNumber | grep ^uidNumber | cut -c 12- | sort |tail -n 1`; let last_uid=$a+1
root@kdc:~# cat tmpuser.ldif | sed s/TMPUSER/deepwalker/g | sed s/TMPUIDNUM/$last_uid/g | ldapadd -H ldapi:/// -Y external
root@kdc:~# kadmin -l cpw deepwalker

Можно посмотреть содержимое каталога LDAP:

slapcat
# или
ldapsearch -Y external -H ldapi:///

Теперь надо настроить /etc/krb5.conf:

[libdefaults]
default_realm = REALM.TLD
default_tgs_enctypes = des-cbc-crc
default_tkt_enctypes = des-cbc-crc
default_etypes = des-cbc-crc
default_etypes_des = des-cbc-crc

fcc-mit-ticketflags = true


[realms]
REALM.TLD = {
kdc = kdc.realm.tld
admin_server = kdc.realm.tld
}

[domain_realm]
realm.tld = REALM.TLD
.realm.tld = REALM.TLD

Пробуем получить билет:

kinit deepwalker

Далее пишем гневные комментарии и ждем следующей части.

среда, 7 мая 2008 г.

py-configurator, scfl - добавки к Cfengine

Для нужд рабочих я написал несколько скриптов:
1. py-configurator - уже описывал и выкладывал;
2. scfl - Sync Config From LDAP - скоро выложу;
3. apt-control - ставит или удаляет пакеты руководствуясь списком из файла.

Это все добавки к Cfengine, хотя если будет время создать py-facter (для выуживания данных из окружения) и py-controller (контроль поцессов, запуск команд шелла и тп), то это будет полностью самостоятельной группой программ. По идее py-configurator и scfl уже связаны в тандем - один выгружает, второй рендерит шаблоны и кладет на место, - но они достаточно легко могут быть использованы по отдельности (достаточно конфигурацию поменять, так как py-configurator по умолчанию лезет в папку, в которую scfl по умолчанию выгружает).

Собственно сайт проекта на Google Code - py-configurator. Со временем туда выложу SCFL и apt-control (надо очистить их от рабочих данных).

Ключевая фишка всего набора - ориентирован он по умолчанию на Kerberos+LDAP окружение, чего, к сожалению, нет ни в одной альтернативе. Иначе я бы не стал изобретать велосипед.

вторник, 6 мая 2008 г.

LDAP vs Kerberos

Часто, когда люди узнают, что я использую Kerberos они говорят, что у них чистый LDAP (pam_ldap) и все прекрасно работает, папки монтируются, сервер проверяется на истинность сертификатами. Но главное, что у них не работает это SSO - Single Sign On. То есть пароль придется вводить на доступ к каждой службе отдельно, отдельно на прокси, отдельно на почту. И это мой главный аргумент за использование Kerberos. О том, что в случае использования Kerberos, пароли по сети не передаются в любом виде, я и вовсе молчу. К хорошей сети сложно подключить машину, которой там быть не должно - EAP существует достаточно давно, а потому украсть передаваемый трафик это очень сложная задача.

Тут можно привести еще один аргумент - в среде Kerberos сервер также не получает ваш пароль, и подстановка фальшивого сервера практически невозможна. Ну а если некто и взломает сервер, то пароль он все равно получить не сможет и все что ему достанется это информация на этом самом сервере.

Для меня выбор Kerberos очевиден еще и потому, что установив дружеские отношения с доменом Active Directory, я фактически решил проблему взаимодействия Linux и Windows сред.

пятница, 2 мая 2008 г.

Скрипт для конфигурации по шаблонам

Кратенький код для конфигурирования машины по шаблонам файлов. Действует так - натравливаете его на каталог с шаблонами, он строит в указаной вами папке то самое дерево, только с отрендеренными шаблонами. По первому же импорту знающие люди поймут какой должен быть синтаксис : ) Ну а для людей не от мира Django будут примеры. Код:


#! /usr/bin/python

from jinja import Environment, FileSystemLoader
from ConfigParser import SafeConfigParser
import os


# pc_cfg = py-configurator
pc_cfg = SafeConfigParser()
pc_cfg.read('/etc/py-configurator/py-configurator.cfg')
pc_config = dict(pc_cfg.items('main'))

base_path = pc_cfg.get('main','templates').rstrip('/')
target_path = pc_cfg.get('main','target').rstrip('/')
if not target_path:
target_path='/'
machine_cfg = pc_cfg.get('main','machine_cfg')
print 'Configuration:',pc_config.items()

ws_cfg = SafeConfigParser()
ws_cfg.read(machine_cfg)
ws_config = dict(ws_cfg.items('main'))

base_len = len(base_path)+1
env = Environment(loader=FileSystemLoader(base_path))

for root, dirs, files in os.walk(base_path, topdown=False):
for name in files:
na_root = root[base_len:]+'/' if root!=base_path else ''
print "Work on file:",name,"Root:",root,"Short root",na_root
tmpl_file=na_root+name
try:
os.lstat(os.path.join(target_path,na_root))
except:
os.mkdir(os.path.join(target_path,na_root))
tmpl = env.get_template(tmpl_file)

tmpl_vars={'name':tmpl_file}
tmpl_vars.update(os.environ)
tmpl_vars.update(ws_config)

open(os.path.join(target_path,tmpl_file),'w').write(tmpl.render(**tmpl_vars))



Пример конфига:

[main]
templates = /etc/py-configurator/templates/
target = /etc
machine_cfg = /etc/machine.cfg

Переменные берет из /etc/machine.cfg, например из такого:

[main]
ws_name = ws3
ws_num = 3
domain = msk5
region_addr = 24
dep_addr = 55

По сути сварганить бы что то вроде facter из puppet, но еще один велосипед, даже не знаю стоит ли.
Обещаный пример (/etc/hosts):

127.0.0.1 localhost
10.{{ region_addr }}.{{ dep_addr }}.{{ ws_num }} {{ ws_name }}.{{ domain }}.realm.tld {{ ws_name }}
10.{{ region_addr }}.{{ dep_addr }}.1 kdc.{{ domain }}.realm.tld

# The following lines are desirable for IPv6 capable hosts
::1 ip6-localhost ip6-loopback
fe00::0 ip6-localnet
ff00::0 ip6-mcastprefix
ff02::1 ip6-allnodes
ff02::2 ip6-allrouters
ff02::3 ip6-allhosts

Подробнее о синтаксисе шаблонов (а он богат возможностями) тут.
Собственно вся затея с etc-шаблонятором родилась от любви к шаблонам Django, ну и слегка требовалась утилита шаблонной настройки.

четверг, 24 апреля 2008 г.

Addpac, детекция сигнала отбоя

Довольно распространенная проблема - АТС генерирует короткие гудки, дабы человек понял, что разговор окончен, но вот техника это не воспринимает. У шлюзов addpac есть специальная настройка для детекции сигнала отбоя - Clear-down-tone cadence.
Итак, заходим на шлюз:

AP1005# conf
Enter configuration commands, one per line. End with CNTL/Z
AP1005(config)# deb
AP1005(config)# end
AP1005# debug rta voice

Далее звоним через шлюз и кладем трубку со стороны АТС. В момент коротких гудков снимаем нечто вроде:

AP1005# 60 60 60 60 60 60 60 60 60 60 60 60 60 23 16 16 16 16 16 16 16 16 16 16 16 16 16 16 16 16 16 16 16 16 16 16 16 16 16 16 16 16 16 16 16 16 16 16 17 50 60 60 60 60 60 60 60 60 60 60 60 60 60 60 60 60 60 60 60 60 60 60 60 60 60 60 60 60 60 60 60 60 60 22 16 16 16 16 16 16 16 16 16 16 16 16 16 16 16 16 16 16 16 16 16 16 16 16 16 16 16 16 16 16 16 16 16 16 17 50 60 60 60 60 60 60 60 60 60 60 60 60 60 60 60 60 60 60 60 60 60 60 60 60 60 60 60 60 60 60 60 60 60 22 16 16 16 16 16 16 16 16 16 16 16 16 16 16 16 16 16 16 16 16 16 16 16 16 16 16 16 16 16 1616 16 16 16 17 50 60 60 60 60 60 60 60 60 60 60 60 60

Считаем:
сигналов ~=-16 * 35. Умножаем на 35, если кодек g711 или g729 - на 10. У меня последний вариант, так что получаем 350. Это у нас active power, а число зовется Active Time Duration.
сигналов ~=-60 * 34. Здесь тоже самое - получаем 340. Это idle power, число - Idle Time Duration.
Получаем:

voice class clear-down-cadence 1 -16 350 340 3 11

Здесь
1 - число необходимого повторения данно последовательности, у меня (1);
2 - уровень тона, те active power (-16);
3 - ActiveTimeDuration (350);
4 - Idle Time Duration (340);
5 - Active Power Variance - отклонения уровня, у нас не отклоняется, но все равно ставим 3 - на всякий;
6 - Idle Power Variance - отклонения уровня паузы, ставим 11.
Применяем:

AP1005# conf
Enter configuration commands, one per line. End with CNTL/Z
AP1005(config)# voice class clear-down-cadence 1 -16 350 340 3 11

Это собственно все описано в мануале от Addpac, ссылку не припомню, но на английском. Работает метод замечательно.

вторник, 22 апреля 2008 г.

upstart, x11vnc

В последних сборках Ubuntu и Debian включен Xorg 7.3, и любимый мной vnc.so там не работает. Ну а няньчить пользователей тем не менее людям надо. Для решения проблемы в Hardy использовал upstart:

# x11vnc
#
# X11VNC start event
#

description "x11vnc starter"
author "Mihail Krivushin "

start on kdm-started
stop on kdm-stopped

stop on runlevel 0
stop on runlevel 1
stop on runlevel 6


console output

pre-start script
DAEMON="x11vnc"
a=`ps -ef | grep $DAEMON | wc -l`
if [a gt 1]; then
killall $DAEMON 2> /dev/null
fi
exit 0
end script

script
DAEMON="x11vnc -rfbauth /путь к файлу/vncpasswd -display :0 -auth `find /var/run/xauth/ -type f` -noxfixes -o /var/log/vnc.log"
$DAEMON
exit 0
end script

post-stop script
DAEMON="x11vnc"
a=`ps -ef | grep $DAEMON | wc -l`
if [a gt 1]; then
killall $DAEMON 2> /dev/null
fi
exit 0
end script

respawn

В /etc/init.d/kdm пришлось вставить initctl emit kdm-started и initctl emit kdm-stopped. Код конечно не причесаный, зато работает, да и вообще я python знаю намного лучше чем bash. Upstart полезная вещь!

вторник, 15 апреля 2008 г.

Heimdal KCM

В коплекте поставки Heimdal Kerberos есть удобный демон KCM. В общем случае он служит для хранения билетов в памяти. Недостаток его в том, что только библиотеки Heimdal его поддерживают. В тоже время, во многих современных дистрибутивах, по умолчанию все пакеты собраны с MIT Kerberos. И nfs4 тоже. Тут можно было бы и забыть о KCM, но не будем этого делать. Для пользователя билет, к которому программы не имеют доступа, конечно бесполезен, но для служб, использующих бибилиотеку Cyrus SASL вполне подойдет.

Долгое время в debian/ubuntu пакет libsasl2-modules-gssapi-heimdal был просто заглушкой, и библиотек, собранных с поддержкой Heimdal, не содержал. В грядущем Hardy Heron ситуацию откатили и теперь это полноценный Heimdal GSSAPI. А значит библиотеки OpenLDAP теперь вполне могут пользоваться очень важной фишкой KCM - этот демон умеет держать билет системы в актуальном состоянии, своевременно его обновляя и переполучая заново.

Итак, правим стартовый скрипт, так, чтобы вышло примерно следующее:

HOSTNAME=`hostname -f`
KCM_PARAMS="--detach --cache-name=0 -k host/$HOSTNAME"


Правим конфиг libnss-ldapd:

uri ldap://kdc.realm.tld
base dc=realm,dc=tld
ldap_version 3
scope sub
use_sasl on
krb5_ccname KCM:0


И для нашей реплики LDAP добавляем (например в /etc/default/slapd):

export KRB5CCNAME="KCM:0"


Все, перезапускаем heimdal-kcm, пользуемся.

четверг, 10 апреля 2008 г.

OpenLDAP, syncrepl

В жестко централизованной структуре, как у меня, есть одна неприятность - связь иногда все таки пропадает между центром и филиалом. Ну и если билет вначале рабочего дня получен, и если в филиале есть реплика ldap, то ничего страшного - по крайней мере обмениваться файлами пользователи смогут.

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

Что требуется:
1. На нашем центральном сервере/серверах добавляем:

database bdb
...
overlay syncprov

2. Реплика в филиале:

database bdb
...
syncrepl rid=1
provider=ldap://kdc.realm.tld
bindmethod=sasl
saslmech=GSSAPI
searchbase="dc=realm,dc=tld"
filter="(objectClass=*)"
attrs="*"
schemachecking=off
scope=sub
type=refreshOnly
retry="5 5 300 5"

updateref ldap://kdc.realm.tld

Преимущество в таком методе рпликации - не требуется предварительная синхронизация каталога. У меня это все заводится вообще с пустой репликой. Также пользователь openldap должен иметь доступ к активному билету. Сейчас как раз собираюсь постараться решить эту проблему кардинально, о результатах напишу позже.

воскресенье, 6 апреля 2008 г.

pk-init

Из документации heimdal:

4.18 Setting up PK-INIT

PK-INIT is levering the existing PKI infrastructure to use certificates to get the initial ticket, that is usually the krbtgt.

To use PK-INIT you must first have a PKI, so if you don't have one, it is time to create it. Note that you should read the whole chapter of the document to see the requirements on the CA software.

Таким образом есть путь для использования сертификатов (pki) и множества сервисов поддерживающих kerberos. Надо будет обдумать, где это применить этак хитро, в голову сразу приходит pam-usb. О результатах общения с google еще напишу (надо почитать перед изобретением велотранспорта). Просто часть всяких служб поддерживает только сертификаты или только kerberos, а так можно использовать и то и другое.

Upd: да, видимо с pam-usb я поторопился. Думал что там сертификаты используются.

пятница, 4 апреля 2008 г.

nss-ldapd, реинкарнация детища padl

У оригинального libnss-ldap есть серьезный недостаток при работе с gssapi - любому пользователю, желающему ознакомиться со списком пользователей, требуется предоставить билет kerberos. Второй вариант - дать всем читать билет, которым будет пользоваться libnss-ldap. Первое это нереально - ну откуда у dbus свой билет? Второе просто уже тупо как то - зачем вообще тогда весь этот лес?

nss-ldapd решает эту проблему. Возможно, ее автор хотел решить какие то другие проблемы, но меня волновала эта. Эта версия состоит из двух частей - демона, который собственно имеет билет и общается с ldap, и клиента, который просто обащается с демоном в пределах одной машины. Разом снимает головную боль с билетами.

Приведу элементарную настройку на работу с kerberos:

uri ldap://kdc.realm.tld
base dc=realm,dc=tld
ldap_version 3
scope sub
use_sasl on
krb5_ccname FILE:/tmp/krb5cc_0


Кстати в kinit (Heimdal последних версий) есть возможность обновлять билет, до тех пор пока работает программа, переданная в качестве параметра.
То есть можно поправить стартовый скрипт nslcd, и билет будет обновляться автоматически.

четверг, 3 апреля 2008 г.

ldapvi

Предыдущий пост описывает прием работы, который подходит для скриптования. Но есть в репозиториях совершенно дикая вещь - ldapvi.
Что это? Это метод скрестить крокодила с бегемотом - ldap и текстовый редактор. Описывать смысла особого нет - дает возможность быстренько что либо поправить в свойствах записи, удалить записи и тп. Данный пост просто повод обратить внимание.

среда, 2 апреля 2008 г.

ldif

Для редактирования LDAP каталогов многие используют разные программы, например luma, ldap administrator и тп. Для новичков кажется ldif кажется сложноватым, а работа с утилитами командной строки тем более.
На самом деле работа с ldif может сэкономить много времени.

deep@host:~$ ldapsearch -h kdc -b uid=anyuser,ou=users,dc=city,dc=realm,dc=tld
SASL/GSSAPI authentication started
SASL username: deep@REALM.TLD
SASL SSF: 56
SASL data security layer installed.
# extended LDIF
#
# LDAPv3
# base with scope subtree
# filter: (objectclass=*)
# requesting: ALL
#

dn: uid=anyuser,ou=users,dc=city,dc=realm,dc=tld
cn: Any User
displayName:: skipped
gecos: Any User
givenName:: skipped
homeDirectory: /home/anyuser
loginShell: /bin/bash
o:: skipped
objectClass: top
objectClass: posixAccount
objectClass: shadowAccount
objectClass: inetOrgPerson
objectClass: organizationalPerson
objectClass: person
objectClass: userSecurityInformation
sn: anyuser
title: anyworker
uid: anyuser
uidNumber: 2118
userPassword: secret
gidNumber: 2030

# search result
search: 5
result: 0 Success

# numResponses: 2
# numEntries: 1

Практически этот вывод можно перенаправить сразу в файл. Затем редактируем, заменяя anyuser на anyuser_new и таким образом можно легко создать нового пользовталя:

deep@host:~$ ldapsearch -h kdc -b uid=anyuser,ou=users,dc=city,dc=realm,dc=tld > user.ldif
deep@host:~$ vim user.ldif
deep@host:~$ cat user.ldif > ldapadd -h kdc

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

nfs4 и samba - дружим доменами

При мигрировании, грамотно не ломать что либо сразу, а произвести плавный переход. Сначало плавно учимся привыкать к толстому OOo, а потом некоторую часть пользователей переводим на linux. Но перевод на linux не должен прерывать обмен данными с оставшимися пользователями. А у нас большое количество данных проходит через сетевые папки (некую файлопомойку с элементами упорядоченной структуры). Как знают грамотные люди, электронный документооборот требует не только покупки софта, а потому наша фирма пока еще пользуется таким способом работы.
Но вернемся к теме - linux, с некоторых пор, имеет поддержку nfs4, поддержку cifs он имеет с времен незапамятных. В свою очередь, nfs4 имеет поддержку протокола kerberos, ну а современные windows сети без kerberos не живут. Протокол kerberos пятой версии характеризуется хорошим механизмом отношений, или иначе "дружбой" сфер kerberos.
Я решил сделать как раз по этой схеме - у linux машин своя сфера kerberos, у windows - AD.
В общем я придумал три варианта:
1. Файловый сервер на машине с windows. Тут как раз нужно настроить дружбу доменов (сфер), а потом создавать пользователей два раза. Почему? Потому что это самый простой путь для подобной схемы - вы просто настраиваете отображение пользователей сферы linux в пользователей домена windows.
2. Файловый сервер на Samba и nfs4. В этом случае вы вводите машину с samba в домен windows, что, однако никак не отражается на самой системе сервера, просто теперь машины из AD смогут получить доступ к вашему серверу аутентифицируясь в AD. В то же время пользователи из сферы linux смогут получить доступ к файлам по протоколу nfs4, аутентифицируясь в linux сфере kerberos. Ключевым моментом схемы является отображение пользователей windows при помощи winbind - uid'ы пользователей AD не должны пересекаться с linux пользователями.
3. А можно не делать отдельную сферу kerberos для linux пользователей, можно аутентификацию и получение kerberos билетов организовать через домен AD. Тогда и проблем нет - делайте хоть на samba, хоть на windows сервере. Но мне не нравится это тем, что тогда отказаться от AD в дальнейшем не выйдет, и ничего то мы не сэкономим на подобном переходе. В общем я этот вариант не реализовывал.

При использовании второго варианта, доступ через nfs4 для linux машин более удобен и прост, так как монтирование по протоколу cifs(так называется протокол, используемый в windows среде) сетевой папки имеет некоторые недостатки:
1. ядро не имеет поддержки монтирования cifs шар с kerberos;
2. основанный на smbclient, smbfs имеет наприятные особенности;
3. если пользоваться, например, kde, то программы из этой среды смогут работать с сетевой папкой через kio-slaves, а вот OOo нет;
Таким образом, просматривать и скачивать файлы можно при помощи различных slaves (kde, да и гном что то такое имел в своем составе), а вот нормально работать только при использовании smbfs.

А вот конкретные настройки будут в следущей серии...

вторник, 1 апреля 2008 г.

OpenLDAP+GSSAPI начало

Буду описывать краткими кусочками : )
Если хочется полного описания, хотя, на мой взгляд, довольно таки дурацкого, то вам сюда -> http://www.bayour.com/LDAPv3-HOWTO.html
У меня же тут будет все попроще для понимания, я надеюсь. В любом случае на родном оно сподручнее читать.

Нам надо сделать аутентификацию, при обращении к каталогу ldap, по GSSAPI. Можно конечно и по сертификатам, но мне нравится kerberos. Ключевое при получении авторизационной информации машинами клиентами, это аутентификация сервера. Это важно - если вашим машинам подставят другой сервер, и на нем скажут, что вот Вася Пупкин админ, то, согласитесь, радости это нам доставит мало.

На примере ubuntu (мне думается, что debian в этом плане сильно не отличается), мы просто делаем любимое aptitude install slapd.

Далее изменения в конфиг:

backend bdb

#######################################################################
# Specific Backend Directives for 'other':
# Backend specific directives apply to this backend until another
# 'backend' directive occurs
#backend
+sasl-realm REALM.TLD # Ваша сфера kerberos
+sasl-host ldap.realm.tld # Имя машины, на которой это все присходит
+authz-regexp uid=([^,]*),cn=realm.tld,cn=gssapi,cn=auth # А вот тут нужно почитать
+ ldap:///dc=realm,dc=tld??sub?(uid=$1) # справку, что бы понять

Суть такова - вы указываете сферу, имя, и настраиваете отображение имен. Это довольно важный момент - когда пользователь аутентифицируется, его имя выглядит как uid=anyuser,cn=realm.tld,cn=gssapi,cn=auth, но системе надо знать его dn, те uid=anyuser,ou=users,dc=town,dc=realm,dc=tld. По идее, конечно, и в таком виде сойдет, но тогда в ваших списках доступа не будут иметь смысла записи self, и пользователь не сможет сменить себе /bin/bash на любимый zsh, ну и пароль.

По идее далее идут настройки acl, которые довольно хорошо выполнены по ссылке выше. Но о чем стоит вспомнить, так это о том, что slapd запускается под пользователем openldap и доступа к /etc/krb5.keytab не имеет. Ну это не большая проблема, просто ключ надо сохранить в, например, /etc/ldap/slapd.keytab, поправить права, а демону перед стартом пояснить где его искать. Это можно сделать например редактированием стартового скрипта /etc/init.d/slapd. Вносим вначале файла export KRB5_KTNAME="FILE:/etc/ldap/slapd.keytab" и всех делов.

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

Баше-нико-генератор

Иногда проглядывая баш, замечаю там ники с заменой букв на всякие символы вроде @$%. Ради разминки написал генератор ников, вот только словарь ему пополнить надо, не силен я в этом : )


#! /usr/bin/python
# -*- coding:utf-8 -*-

import sys

a=[(u'aAаА',u'@'),(u'bBбБ',u'$'),
(u'фФ',u'%')]

fraze = u'голубые киты плакали в глубине, фыркали.'

chars_conv = {}
for i in a:
for ch in i[0]:
chars_conv[ch]=i[1]

if len(sys.argv) > 1:
fraze = sys.argv[1].decode('utf8')

res=u''
for char in fraze:
if char in chars_conv:
res=res+chars_conv[char]
else:
res=res+char
print res

Результат:

голу$ые киты пл@к@ли в глу$ине, %ырк@ли.

понедельник, 31 марта 2008 г.

Подписаный репозитарий Ubuntu

Сделал репозитарий своих пакетов. Вдохновило описание работы Яндекса с deb пакетами. Ну и самое главное - подписал. Ниже результат изысканий:


dpkg-scanpackages . > Packages

cat Packages | gzip -c > Packages.gz
cat Packages | bzip2 -c > Packages.bz2

rm Release Release.gpg

apt-ftparchive release . \
-o APT::FTPArchive::Release::Origin="JSC SOUZ T"\
-o APT::FTPArchive::Release::Codename="hardy" > /root/Release

# Важно - Release нужно класть именно в другую папку, иначе потом будет ошибка
# неверной подписи

mv /root/Release Release

# Перед подписью неплохо бы gpg ключ сгенерировать - gpg --gen-key
# на сервере, стоящем далеко, подергать мышью не удастся, и энтропию фиг получите : )
# я сделал что то типа find / | xargs -I'{}' dd if='{}' of=/dev/null
# а потом эскпортировать - gpg --export --armor > repo-key.asc
# ну и на клиенте импортировать - apt-key add repo-key.asc

gpg -abs -o Release.gpg Release

четверг, 27 марта 2008 г.

Thinstation, протираем фару

За что я все таки больше люблю linux, чем известный аналог, так это за благодарность системы пытливому уму. То есть, если вы не жалеете времени изучая принципы, стандартные решения, идеологию в конце концов, то повернется она к вам таки не то что лицом, а всей своей душой своей механической, такими же пытливыми умами созданой.
Я это все к чему, случается иногда, что править душу эту приходится, так как иные умы и мыслят не по вашему, и железо у них другое, и ваши тяготы не всем доступны.
К делу - у thinstation есть четыря уровня для пытливости:
1. скачать готовый вариант, подходящий для большинства;
2. натыкать галки и получить несколько заточеный под себя (позволяет выбрать включаемые компоненты);
3. скачать вариант для ручной сборки уже собранных бинарников, ядра и тп (позволяет поправить конфиги, стартовые скрипты, сделать то, для чего вообще не думалось применять thinstation);
4. самый глубокий уровень - скачать среду разработчика и руками собрать все, что иные умы сочли излишним, или же вообще не слышали о таком;

Моя ситуация была довольно банальна, несмотря на выспренность слога в первом абзаце - драйвера от сетевой карты не работали, ибо оборудование было уж слишком свежим. На сайте intel (а именно они отцы этой карты), драйвера под линукс были.
Чтобы получить модуль нужны исходники ядра, но не только. Еще требуется собрать модуль той же версией компилятора, что и ядро. В общем проще скачать среду разработчика Thinstation, там все для счастья положено.
1. Качаем;
2. tar xvfz thinstation_src-2.3.tgz
3. cd thinstation_src-2.3
4. ./RUNME
Вот мы и "дома". То есть можно делать теперь все, ради чего тянули 300 мегабайт. Драйвера с сайта intel тихо и не заметно уже легли в директорию между пунктами 3 и 4, и в 4 пункте sudo я забыл.


sh-3.1# cd intel
sh-3.1# ls
e1000-7.6.5.tar.gz
sh-3.1# tar xvfz e1000-7.6.5.tar.gz
sh-3.1# cd e1000-7.6.5/src/
sh-3.1# make
Makefile:197: ***
Makefile:202: *** Warning: kernel source configuration (UP)
Makefile:203: *** does not match running kernel (SMP)
Makefile:205: *** Continuing with build,
Makefile:206: *** resulting driver may not be what you want
Makefile:207: ***
make -C /usr/src/linux SUBDIRS=/intel/e1000-7.6.5/src modules
...
CC /intel/e1000-7.6.5/src/e1000.mod.o
LD [M] /intel/e1000-7.6.5/src/e1000.ko
make[1]: Leaving directory `/source/kernel-2.6.21.1/linux-2.6.21.1'


На этом все, полученным e1000.ko заменяем уже имеющийся в каталогах 3го варианта сборки. На самом деле Thinstation я перетряс куда основательнее, да разве все упомнишь. А это так - пример образа мыслей, что собственно намного вернее всяческих howto.

понедельник, 24 марта 2008 г.

Черный Баламут

Прочел недавно книгу "Черный Баламут" - поразила настолько сильно, что уже вторую неделю разговариваю в стиле Индры и Карны Секача, и постоянно думаю о нелегкой ошибке Кришны Бхагавана. Настоятельно рекомендую к прочтению.

Читать в википедии

linux в торговле

Уже много лет активно обсуждается применение linux на корпоративном десктопе. Ну что же, это вполне возможно и ни капли не смертельно. Уж я то точно могу об этом сказать, так как проэкспериментировал на собственной фирме.

Не так давно наша фирма решила немного расширить свое розничное направление (а торгует наша компания мебелью), и запустила новый бренд розничной сети. Ну и под этим брендом открываются у нас несколько магазинов. Вообще магазины у нас были довольно таки обкатаной единицей к тому времени - контроллер домена + файлосвалка, офисная АТС, около 4 рабочих станций, около 5 тонких клиентов (Thinstation linux).

Как у любых администраторов, linux был конечно же у всех на слуху (а у кого то и на рабочем месте). Я вообще довольно давно разбирался в вопросах как сделать интегрированую сеть на linux, и наработки были. И решили все таки попробовать.

Стандартную схему переработали, контроллер домена сменили на linux сервер, АТС на него же. Так же linux установили на все рабочие места. Единственной рабочее место с windows, это место "Моделирование кухонь". Многие производители кухонь делают что то на коленке для этих целей, а коленка у них это access, ms jet и иже с ними. В общем wine я под это заточить не сумел, да и с возможными косяками возится не очень то и хотелось - я же все таки ленивый админ или как?

Традиционную телефонию убрали, sipx нам в этом хорошо помог. При ценах на офисные АТС, даже дешевле получилось, ну а плюсы вы можете прочесть в любой из сотен рекламных брошюр по теме. Если еще сюда прибавить, что собственно телефон как отдельный аппарат это опция, то получается совсем уж замечательно.

Ну а самое важное для корпоратива, это конечно же логины, пароли, сетевые папки. Ну это просто достаточно - ldap как хранилище авторизационной информации, kerberos как служба аутентификации, nfs4 как сетевая фс, samba для общения с офисом, который еще не так продвинут (тяжело его продвинуть все таки, магазин он маленький, а офис...).

Вот это то наверное и буду описывать в дальнейшем, для этого и завел себе блог. Но сразу стоит оговориться, что коробочного толкового решения я еще не видел, чтоб хоп, как в windows, пару раз мышкой щелкнули, и машина в домене. Сейчас активно разрабатываются FreeIPA, Mandriva DS, но первый минус этой кухни - работает в одном каком то конкретном дистрибутиве (fedora и mandriva, конечно же), а второе - еще не допилено до конца. Можно сказать , что у меня есть предвзятое отношение, но mandriva у меня всегда вызывала опасения. Возможно я не прав, и руки у них за столько лет стали прямее, но ранний опыт использования не впечатлил. Fedora же довольно последовательно строит свой каталог, и уважение корпоративщиков к ее старшему брату, существует видимо неспроста.

А пока я строю свой каталог на коленке из openldap и heimdal kerberos, но об этом в следующих сериях.

SipX, стоит обратить внимание

Не многие знают об этом продукте, а между тем, работает он, на мой взгляд, лучше asterisk.
Ниша его - корпоративная VoIP связь. В отличие от ser, который может применятся для создания публичных VoIP сервисов, SipX имеет в своем составе голосовую почту, группы дозвона, хороший web интерфейс для управления. Также есть возможность настройки телефонов через тот же интерфейс (телефоны будут забирать все настройки через dhcp + tftp). Есть и еще пара полезных фич, о которых вы можете прочесть сами. Главные отличия от asterisk - поддерживает только sip (но уж ближе к rfc его не поддерживает практически никто), нет никаких reinvite (те сервер просто не пропускает поток rtp через себя, и именно поэтому не имеет проблем с джиттерами и кодеками).

Самым сложным для меня в отоношениях с sipx была его установка. Но есть уже готовые пакеты для rpm дистрибутивов. Мне же, как любителю debian, пришлось порядком повозиться с доустановкой дополнительных пакетов и настройкой odbc и java. Впрочем, в wiki есть основные моменты.

Данная запись это не подробное описание продукта. Это скорее повод посмотреть на него, для тех, кому VoIP интересен.

Мои личные впечатления от SipX крайне положительны. Его эксплуатация в тестовом режиме за несколько месяцев не выявила никаких паталогий. Могу только вспомнить неприятность с телефоном Addpac IP100, который не сохранял CSeq, и из за этого не мог зарегистрироваться на сервере после перезагрузки. Перезагружать SipX из за глюков не приходилось.

Из переписки

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

Я его на данный момент расставляю в филиалах, где обычной телефонии нет в принципе. А так связь на данный момент через шлюзы, прицепленные к атскам в старых филиалах (у нас сейчас куча новых открывается, в них вот как раз АТСки офисной нет, есть шлюз на городские номера и ip фоны на рабочих местах).

Почему не астериск - был плохой опыт его использования. Много глюков от его привычки пускать вначале соединение через себя. Те он проксирует rtp поток. Из этого получается, что он должен понимать все кодеки, а это не так. Потом он rtp пытается перевести с помощью функции reinvite, и это самый большой источник глюков. Победить это все можно, если желание есть. У меня нет : )

SipX настраивается через web морду, удобно, просто (астериск тоже умеет). Потоки через себя не пропускает, что избавляет от части проблем - меньше нагрузка на сервер, нет возни с jitter буферами и тп (пусть этим производители железок озабачиваются). А оно ему и не надо. Всякие штуки типа звонка сразу на 5 телефонов держит легко. Есть что то для ivr и тп, пока не требовалось, полный переход на ип телефонию планируется после обкатки решения на филиалах. Намного более asterisk'a соответствует rfc. В общем именно как офисная АТС прекрасен. Можно делать кластер и тп.

По части сервера, смотрящего в мир (ну там по типу skype, sipnet) я бы наверное не рекомендовал. Тут больше ser подходит, особенно по сравнению с астериском, ибо в нем уже вообще нечему глючить. Вот только ser не совсем тривиален в настройке - это вообще конструктор еще тот. Конфиг - программа на си подобном языке. Но уж наконфигурить можно все что угодно. Но тут подводный камень - это sip router именно, а потому делать специфичные вещи типа звонков на несколько номеров ему тупо не под силу. В общем для публичного сервиса хорош, для офиса не очень.

суббота, 8 марта 2008 г.

Откат изменений при загрузке

Пришла мне в голову идея - помню вот народ Hg использовал для сохранения всех изменений в дереве /etc, я и сам пользуюсь этим на серверах. Кто не в курсе - Hg это система контроля версий, Mercurial. Системы контроля версий сохраняют все ваши изменения и используются в основном программистами для совместной работы и, собственно, контроля версий : )
Итак, в качестве полигона используем папку у себя в домашней директории :

aptitude install mercurial # у кого еще нет : )
mkdir temp
cd temp
hg init
# создадим тестовый набор файлов
for i in `echo "0 1 2 3 4" | xargs`; do touch test$i; done

Добавим их под контроль:


hg add test*

смотрим hg status:



A test0
A test1
A test2
A test3
A test4

Далее фиксируем текущий шаг изменений:


»mkrivushin@dot:~/temp$ hg commit -m "`date` автоматический фикс"
No username found, using 'mkrivushin@dot.souzt.tld' instead

еще разок:



»mkrivushin@dot:~/temp$ hg commit -m "`date` автоматический фикс"
nothing changed

Как видите, по второму разу неизмененное не фиксируется.

поправим test0:



echo "wqerqwrqwer" > test0
»mkrivushin@dot:~/temp$ hg commit -m “`date` автоматический фикс”
No username found, using ‘mkrivushin@dot.souzt.tld’ instead

Изменения зафиксировались, посмотрим:



»mkrivushin@dot:~/temp$ hg log
changeset: 1:e2aab7338581
tag: tip
user: mkrivushin@dot.souzt.tld
date: Fri Mar 07 11:44:18 2008 +0600
summary: Птн Мар 7 11:44:18 NOVT 2008 автоматический фикс

changeset: 0:88a5a7a6c86a
user: mkrivushin@dot.souzt.tld
date: Fri Mar 07 11:41:39 2008 +0600
summary: Птн Мар 7 11:41:39 NOVT 2008 автоматический фикс

Пробуем теперь с откатами к предыдущей редакции:



»mkrivushin@dot:~/temp$ echo "осмысленный текст" > test0
»mkrivushin@dot:~/temp$ hg commit -m "`date` автоматический фикс"
No username found, using 'mkrivushin@dot.souzt.tld' instead
»mkrivushin@dot:~/temp$ hg log
changeset: 2:0b341c5a3f32
tag: tip
user: mkrivushin@dot.souzt.tld
date: Fri Mar 07 11:47:00 2008 +0600
summary: Птн Мар 7 11:47:00 NOVT 2008 автоматический фикс

changeset: 1:e2aab7338581
user: mkrivushin@dot.souzt.tld
date: Fri Mar 07 11:44:18 2008 +0600
summary: Птн Мар 7 11:44:18 NOVT 2008 автоматический фикс

changeset: 0:88a5a7a6c86a
user: mkrivushin@dot.souzt.tld
date: Fri Mar 07 11:41:39 2008 +0600
summary: Птн Мар 7 11:41:39 NOVT 2008 автоматический фикс
»mkrivushin@dot:~/temp$ hg revert -a -r 1
reverting test0
»mkrivushin@dot:~/temp$ cat test0
wqerqwrqwer

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




»mkrivushin@dot:~/temp$ for i in `echo "0 1 2 3 4" | xargs`; do touch new$i; done
»mkrivushin@dot:~/temp$ ls
new0 new1 new2 new3 new4 test0 test1 test2 test3 test4
»mkrivushin@dot:~/temp$ hg st
? new0
? new1
? new2
? new3
? new4

Смотрим - новые файлы выводятся вопросами. Ну значит применим : )



»mkrivushin@dot:~/temp$ hg st | grep ^? | sed s/^?\ /\"/g | sed s/$/\"/g | xargs -n 1 hg add
»mkrivushin@dot:~/temp$ hg st
A kuku kuku
A new0
A new1
A new2
A new3
A new4

Добавились! : )


В общем вы догадались уже, что это можно применить к одному очень интересному каталогу - /etc
Но это еще не все! А как же нам при загрузке вернуться к рабочей системе, которую мы грохнули изучая pam, hesiod и kerberos? : ) Вот тут приходит такой очень хороший каталог - /proc



»mkrivushin@dot:~/temp$ cat /proc/cmdline
root=UUID=hehe-hehe-hehe-hehe ro quiet splash

А вот и параметры переданные ядру : ) Продолжать? Я думаю, вы конечно догадались, но так и быть допишем опус. Итак, напишем скрипт, который будет смотреть в параметры переданые ядру при загрузке, вылавливать оттуда номер ревизии и откатывать /etc к ней.



#! /usr/bin/python
import re
import os
cmd = open(’/proc/cmdline’,'r’).read().strip()
try:
revert = re.search(r’revert=(?P\d+)’,cmd).groupdict()[’revert’]
except:
revert=None
if revert:
os.system(”cd /etc && hg revert -a -r %s”%revert)
print “System config catalog /etc was reverted!!!”


Ставим этот скрипт в загрузку первым (/etc/event.d или используем дебиановский update-rc.d) и ломаем систему спокойно : ) Можно еще сделать возврат к какой либо версии по дате/времени.


А теперь самоe страшное - не тестировал, только собираюсь, но времени пока нет. Если кому-то интересно, я могу помочь советами, а также могу помочь сделать пакет из этого хозяйства. Кстати, если это велосипед, скажите автору в комментариях, чтоб больше не занимался фигней на рабочем месте : )