03.25.08

dovecot 1.1: xexec

Posted in linux, mail at 1:46 am by viliar

В процессе обсуждения в списках рассылки dovecot@dovecot.org
поднятого мною вопроса о невозможности компиляции xexec с версией 1.1 Stephan Bosch сделал патч, который я, соответственно, протестировал у себя.  Пропатченный модуль нормально работает с новой веткой dovecot 1.1, которая, правда, пока находится на стадии rc, но этой весной должен выйти стабильный релиз.

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

dovecot-xexec-1.1.v2.patch.

xexec.dovecot.v1.1.tar.gz.

Из-за пертрубаций в dovecot вики выложил файлы и у себя:

xexec.tar.gz

dovecot-xexec-1.1.v2.patch

xexec.1.1.v2.tar.gz

03.20.08

Hans Reiser Trial

Posted in opensource at 7:54 pm by viliar

Наиболее подробное описание процесса на Рейзером. Обновляется после каждого заседания суда.
На ‘американском’ английском.

http://blog.wired.com/27bstroke6/hans_reiser_trial/

Производит, правда, довольно тягостное впечатление, как оно все там тянется :-(

03.19.08

intellectual property vs. integrity of the voting process

Posted in wonderland at 12:31 am by viliar

http://www.opennet.ru/opennews/art.shtml?num=14813

03.18.08

dovecot: max connections per host /ip p2.

Posted in linux, mail at 4:51 pm by viliar

Согласно рекомендациям Timo я сделал такой простейший патч:

— src/master/mail-process.c.orig 2008-03-18 19:55:04.000000000 -0400
+++ src/master/mail-process.c 2008-03-18 19:55:35.000000000 -0400
@@ -75,7 +75,8 @@ mail_process_group_lookup(enum process_t
struct mail_process_group lookup_group;
lookup_group.process.type = type;
- lookup_group.user = t_strdup_noconst(user);
+ /*lookup_group.user = t_strdup_noconst(user);*/
+ lookup_group.user = “”;
lookup_group.remote_ip = *ip;
return hash_lookup(mail_process_groups, &lookup_group);
@@ -89,7 +90,8 @@ mail_process_group_create(enum process_t
group = i_new(struct mail_process_group, 1);
group->process.type = type;
- group->user = i_strdup(user);
+ /*group->user = i_strdup(user);*/
+ group->user = “”;
group->remote_ip = *ip;
i_array_init(&group->processes, 10);
— src/login-common/sasl-server.c.orig 2008-03-19 09:36:56.000000000 -0400
+++ src/login-common/sasl-server.c 2008-03-19 09:37:21.000000000 -0400
@@ -51,7 +51,7 @@ master_callback(struct client *client, e
case MASTER_LOGIN_STATUS_INTERNAL_ERROR:
break;
case MASTER_LOGIN_STATUS_MAX_CONNECTIONS:
- data = “Maximum number of connections from user+IP exceeded”;
+ data = “Maximum number of connections from ip exceeded”;
break;
}
call_client_callback(client, reply, data, NULL);

patch

Вcе работает, но имхо, это может быть только временным воркэраундом, так как работает не так, хотелось бы. Оное ограничивает только кол-во _логинов_ с одного ip. Может кому-то это покажется тем же самым или совсем несущественной разницей, но при этом не ограничиваются коннекты, их можно
сделать сколько угодно, переполнив пул соединений сервера. Так
что будем ждать более правильного решения. Правда в мейллист
все-таки отпишусь, чтобы как-то повлиять на предполагаемую реализацию сего. Кстати, хотелось бы иметь возможность
ограничивать как общее кол-во соединений с ip, так и кол-во соединений к конкретному аккаунту.

dovecot: max connections per host / ip.

Posted in linux, mail at 2:42 am by viliar

Вчера  в мейллист dovecot’а написал вопрос об возможных путях решения вопроса об ограничении одновременного кол-ва коннектов с одного хоста, как это можно сделать, опять же, в том же CGP. На что уже сегодня получил ответ от Timo (автора dovecot’а) и еще один.

> Hi everyone!
> >
> > I want to manage mail server resource part (like it can CGP) and with it
> > I have one question. Is any way to limit overall max simultaneous
> > connections to imap/pop3 server from one(each) host, except use
> > iptables/ipfw and so on? Like a patch to dovecot or, maybe, it can be
> > released in future versions?

Probably in future versions.

> > I know about
> > mail_max_userip_connections in dovecot 1.1

It should be pretty easy to patch this code to ignore the user and just
limit IPs. You could basically just remove “user” from struct
mail_process_group and fix the code to compile. Or even easier:

static struct mail_process_group *
mail_process_group_lookup(enum process_type type, const char *user,
const struct ip_addr *ip)
{
user = “”; // use the same empty user for everyone

// …

static struct mail_process_group *
mail_process_group_create(enum process_type type, const char *user,
const struct ip_addr *ip)
{
struct mail_process_group *group;

user = “”; // use the same empty user for everyone

и

Sounds like

> > Probably in future versions.

could be trivially implemented with a “mail_process_group_lookup_key”
setting that defaults to %u :)

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

//Странно, что этот вопрос никто не задавал до меня. Хорошо, что я его задал. :-) Если это еще и реализуют, это будет совсем прекрасно.
Всем приятной ночи :-)

03.12.08

dovecot: xexec.

Posted in linux, mail at 8:38 pm by viliar

Немного в продолжение предыдущего поста. Я обещал написать про
xexec. В процессе все тех же поисков рулеза нашел в документации
dovecot’а информацию про этот модуль. Помечен, как
экспериментальный, но мне думается не в силу качества кода,
а в силу того, как они сами написали, что его действия не попадают в стандарты rfc по imap протоколу и, соответственно, не поддерживаются никакими клиентами.

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

“Execute any server side application and communicate with it through plugins over IMAP”

Для начала немного примеров:

# telnet 127.0.0.1 143
Trying 127.0.0.1…
Connected to 127.0.0.1.
Escape character is ‘^]’.
* OK Dovecot ready.
001 login viliar@dungeon.local xxxXx
001 OK Logged in.
002 xexec user
* OK User: viliar@dungeon.local, effective uid: 2003
002 OK command exited successfully

Теперь чуть подробнее
003 xexec more
* OK Dovecot gave next info about you:
* OK your account viliar in domain dungeon.local
* OK home at /home/mail/dungeon.local/viliar/ and your uid 2003
* OK connected by IMAP service
* OK local ip 127.0.0.1, your ip 127.0.0.1
003 OK command exited successfully

То есть плагин используется в контексте пользовательского процесса, с
его привелегиями! Теперь давайте вспомним, что я писал про passwd-like файлы. Можно на стороне нарисовать очень простой интерфейс, который будет проверять полученные данные от довекота о пользователе, проверять входные данные и менять файлы конфигурации, которые созданы под его юидом. Никакого доступа к чувствительной информации. Кайф? Не то слово.

Ну и так, до кучи поменяем пароль:

004 xexec chpass  XdaRT34
* OK password successefully updated
004 OK command exited successfully
005 logout
* BYE Logging out
005 OK Logout completed.
Connection closed by foreign host

На стороне сервера это будет выглядеть примерно таким образом:
/etc/dovecot/dovecot.conf
plugin {
quota = maildir:ignore=Trash
xexec = date:/usr/local/bin/date
xexec2 = user:/usr/local/bin/user %u
xexec3 = chpass:/usr/local/bin/chpass %u
xexec4 = more:/usr/local/bin/more.sh %n %d %s %p %l %r %h %i
}

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

Плюсы очевидны. Гибкость и безопасность. Если, условно, сравнить с postfixadmin, хотя это сравнение, я понимаю, не очень корректно, так как сравнивается протокол и интерфейс администрирования. Скорее я сравниваю и то и другое как возможность администрирования почтового сервера и это касается скорее не самого postfixadmin’а, а методов работы таких “вебморд”.

У них, как правило, конкретная привязка к определенному типу хранилища. Ну может быть к нескольким однотипным, на основе sql. Postfixadmin работает только с mysql. Это ограничивает нас существенно. И этому, возможно, очень замечательному интерфейсу я должен дать _полный_  доступ до базы. Это самое ужасное. При возникновении дыр в нем самом, или специфических дыр в php в этом случае можно, простите за выражение, огрести по полной. При совокупности дыр, через mysql, если кому-то придет нелепая идея использовать его еще для чего-то, можно тоже
получить и утечку данных и все-такое. Но это уже из области допущений и можно в расчет не принимать. Но все равно несекурно
совсем как получается. Можно ограничить доступ до административного интерфеса при помощи basic auth и вобще заставлять пользователей ходить только через https. Таким образом мы уменьшаем число потениальных взломщиков только до числа зарегистрированных пользователей. Но это из разряда вспомогательных решений и не хотелось бы надеяться только на дополнительные меры. Хочется секурного “из коробки”, чтобы в основании были более безопасные методы работы с информацией.

При использовании xexec мы получаем возможность использовать любой интерфейс на стороне сервера и на стороне клиента, то есть веб-приложения. Написать, например, модуль для squirrelmail. И это будет
значительно более безопасное решение, потому что веб-интерфейсу мы не даем ключ от квартиры пароль от базы, где лежат
все данные. Ну а если доводить идею об безопасности до абсурда, то сквирмейл, во избежания модификации скриптов, если будут дыры - держать на read-only разделе с единым профилем для всех. Шучу. :-)

Это так, немного информации к размышлению и очередной бонус
активно развивающемуся проекту dovecot. Модульность рулит :-)

postfix,dovecot.

Posted in linux, mail at 3:42 pm by viliar

Чуть раньше, чем я стал выяснять вопрос с sqlite хранилищем я пытался нарисовать немного другую схему с, так сказать, распределенным хранилищем всей информации, как то домены, аккаунты и алиасы. Для тех, кто работал с CommuniGate (я пишу о ветке 4.1.x, с обновленным монстром, включающим себя сильно позднее даже ip телефонию я не работал) сервером, полагаю, понятно, что я имею в виду. Но, все-таки поясню для остальных. В CGP информация обо всем этом лежит не в каком-то отдельном месте, отдельной базе, но в каталогах самих доменов, аккаунтов следующим образом:
о домене
/var/CommuniGate/Domains/domain.ru/Settings/access.settings
/var/CommuniGate/Domains/domain.ru/Settings/domain.settings
/var/CommuniGate/Domains/domain.ru/Settings/domainAliases.data
об аккаунте:
/var/CommuniGate/Domains/domain.ru/mail.macnt/account.info
/var/CommuniGate/Domains/domain.ru/mail.macnt/account.settings
/var/CommuniGate/Domains/domain.ru/mail.macnt/INBOX.mdir

При запуске Коммунигейта вся информация считывается в память. Что может быть весьма долго, до 2-3 минут на моей памяти при большом кол-ве доменов/аккаунтов. (сотни  доменов и тысячи аккаунтов), зато это компенсируется дальнейшим очень быстрым доступом до этих данных. При этом, правда, следует учесть,
что изменения данных на уровне файловой системы, не через
Коммунигейтовские интерфейсы будут замечены только после перезапуска сервера.

Соответсвенно, я стал выяснять, нельзя ли что-то похожее реализовать в связке postfix/dovecot. В процессе изысканий выяснилось, что умничка dovecot умеет работать со можеством passwd-ike файлов. По шаблону. В версии 1.0.x это будет выглядеть
так (из минусов - файлы будут перечитываться каждый раз заново, а может, только если mtime менялся - нужно смотреть сам код):

passdb passwd-file {
args = /mail/%d/%n/settings
}

где :%d, как вы догадались, домен, а %n - имя аккаунта.
Красота? Красота. Уже довольно похоже на файловую структуру CGP.
Но этого, конечно, маловато. Нам недостаточно только логина и пароля. А что делать с квотой и пр? Это тоже пока не из области фантастики, благодаря гибкости довекота:

userdb passwd-file {
args = /mail/%d/%n/settings
}

userdb prefetch {
}

Последний пункт, according documentation, попытка выйграть
некоторое кол-во тактов процессора, возвращая вместе с паролем
дополнительную информацию об аккаунте. Один запрос вместо двух. Все это вобщем-то есть в вики.
Вот, например, что мы еще можем хранить в passwd-like файле:

# cat /mail/skymail.local/hensen/settings
hensen:{plain}test:2000:2000::::userdb_nice=10 userdb_quota=maildir:storage=2048 quota=maildir:storage=2048

Пояснять отдельные моменты не буду, отмечу лишь, что home задается mail_loction, но можно и здесь. Плюс, что нам дает еще эта схема? Возвращять один uid на пользователя, если нужно, а можно один для домена. Что хорошо для виртуального хостинга, для использования общей файловой квоты на аккаунты. В общем, наметки выглядят довольно вкусно, если еще учитывать возможности плагина xexec, о котором я напишу отдельным постом. Получается, на этой базе можно выстроить хорошую конфигурацию pop3/imap сервера, дополнительно используя namespaces и managesieve. Да,
к довекоту есть интерфейс managesieve, правда на данный момент отдельным патчем. К версии 2.0, которая пока неизвестно, когда
будет, Timo Sirainen предполагает переработать патч и включить в основную ветку.

А что, собственно, делать с postfix? Каким он боком будет в этой схеме? На часть вопросов ответ у меня есть. Из-за других, я собственно и стал рассматривать другие варианты хранилища.
Первая - хорошая новость. Postfix c версии 2.3 может использовать
процесс dovecot-auth для авторизации (через sasl) пользователей.
Одним зайцем меньше. Что существенно. Но остаются самые большие зайцы. Как вписывать в эту схему алиасы и домены я пока не придумал. Использовать для них отдельное хранилище? Дублируются данные и встает вопрос о необходимости постоянной синхронизации. Мне этот вариант не нравится. Пришлось гнать от себя прочь всякие
извращенные мысли,типа inotify демона, который будет отслеживать
изменения файлов settings,aliases  в этих каталогах и обновлять базу
postfix’а. Или демона, который будет считывать информацию из каталогов домена и по tcp будет отвечать postfix’у.
Т.к. Postfix поддерживает такой тип таблиц в девел версии:  tcp:
Но это ни разу не production решения.

Все должно быть проще. Чем больше компонентов в системе, тем больше шансов, что что-то отвалится. Может быть в будущих версиях postfix’а что-то изменится к лучшему, а может найдется решение, которое вроде бы перед глазами, но я его пока не вижу.

opensource’ц

Posted in linux, mail, programming at 1:35 am by viliar

Когда много работаешь с опенсурсным софтом, зачастую поневоле, а где-то из интереса, (не*)много узнаешь из смежных нужной тебе области. В том числе, часто и из программирования. На перле я уже сравнительно давно делаю разные скрипты для административной работы, когда возможности шелла не то чтобы исчерпаны, но когда нужен более высокий уровень абстракций. И на перле это реализовать гораздо проще. С C/C++ все гораздо сложнее, особенно в случае если и склад ума не пограммерский (в хорошем смысле этого слова) и база знаний безмерно мала - это про меня. Все-таки для того, чтобы писать на перле, как и на баше, зачастую достаточно где-то подглядеть примеры и, так сказать, начиная с малого, втягиваешься в процесс, по мере необходимого заглядывая в маны. А для Си нужно все-таки довольно плотное изучение.
Сейчас обдумываю и местами воплощаю различные улучшения своей почтовой системы. В том числе мысли занимает и то, какое хранилище
использовать с postfix/dovecot для виртуальных аккаунтов/доменов/алиасов.
Список поддерживаемых баз довольно внушительный у обоих. Есть и места пересечения. Pgsql/Mysql/Ldap например.
C самого mysql все-таки надо слезать, так как показала моя небольшая практика, дополнительный демон здесь лишнее уязвимое звено.
Пару раз он падал по сторонним причинам и почта вставала. Да и хотелось бы что-нибудь полегче. Pgsql и Ldap вобщем-то не подходят по тем же причинам, плюс, несмотря на предпологаемую
легковестность решения на основе Ldap, сам он, имхо, требует немало телодвижений для освоения,  а демон в итоге остается. В процессе поисков нашел, что dovecot обладает встроенной поддержкой sqlite, а к
postfix ее можно прикрутить при помощи стороннего патча (postfix_sqlite.patch), который, судя по одному из тредов в мейллистах postfix-users, имеет и шансы попасть в мейнстрим. Если у автора будет достаточно времени, чтобы привести документацию в некий порядок, а вернее ее написать, а также устранить некоторые недочеты. Отсутствие необходимости держать
в этом случае еще одного демона, а также скорость на более простых
выборках, нежели у mysql остановили мой выбор на нем. Хотя бы для
начала “на посмотреть”.
Стал пересобирать postfix по спек файлу с необходимыми изменениями и… обломс. Не выходит у Данилы каменный цеток. В процессе компиляции
отваливается с ошибкой
../../lib/libglobal.a(dict_sqlite.o): In function `dict_sqlite_lookup’:
/usr/src/redhat/BUILD/postfix-2.5.0/src/global/dict_sqlite.c:171:
undefined reference to `sqlite3_prepare_v2′
Взгляд девелопера/программиста, возможно, в общих чертах или даже
сразу понял в чем дело. Это был не мой взгляд :-)
еще раз перепроверил, что устновленно в системе:
# rpm -qa | grep sqlite
sqlite-devel-3.3.6-2
sqlite-3.3.6-2
python-sqlite-1.1.7-1.2.1
На месте. Опции сборки:
%if %{SQLITE}
CCARGS=”${CCARGS} -DHAS_SQLITE -I/usr/include ”
AUXLIBS=”${AUXLIBS} -L/usr/lib -lsqlite3 ”
%endif
Тоже все на месте. Гугл по вопросу не то, чтобы молчит, но и не говорит ничего определенного. Только в одном месте “глаза споткнулись” об
“checking for SQLITE… yes
checking for sqlite3_table_column_metadata in -lsqlite3… no
Installed SQLite was not compiled with the SQLITE_ENABLE_COLUMN_METADATA,
using embedded SQLite”.

Вероятно где-то это дало внутренний ход работы мозгу. Но решение, да и суть проблемы пока ускользали.
Что делать, когда нужно, а не выходит? Если без виагры, то писать автору патча. После некоторых телодвижений, грепа, просмотра списка rpm пакетов, пары хождений в процессе рабочего дня на сайт sqlite.org я так и сделал. В процессе написания подбил инфу, что установлено, какая система и т.д.
И после отправки письма мысль зашевилилась дальше:

# strings /usr/lib/libsqlite3.so | grep prepare
sqlite3_prepare
sqlite3_prepare16
# grep prepare /usr/include/sqlite3.h | grep int
int sqlite3_prepare(
int sqlite3_prepare16(

После этого и еще одного похода на сайт sqlite.org в раздел документации
все стало ясно. В данной версии просто нет необходимой функции, используемой автором. Справедливости ради должен сказать, что здесь http://www.sqlite.org/capi3ref.html#sqlite3_prepare
я не нашел описания, в каких версиях какие функции были добавлены. Совсем не http://dev.mysql.com, где это есть для функций пользовательских, может и что-такое тоже расписано.
Наверное это нужно искать в чейнжлогах. Плюс, отсутствие какой-либо документации к патчу. Это же опенсурс :-) Есть нужно - сам найдешь/сделаешь/поправишь. Дальше было еще одно письмо автору
(не дожидаясь ответа на первое) с вопросом “can function be safely replaced with sqlite3_prepare or sqlite3_prepare16?”
и опять же, просмотр документации вкупе с самим патчем.
Аргументы, согласно документации у обоих функций одинаковый
и у sqlite3_prepare и у sqlite3_prepare_v2, а сама функция используется один раз. Как же тут не попробовать. Процесс компиляции прошел успешно.
Остальное - посмотрим. Opensource, однако.

14 queries. 0.390 seconds