Thursday, December 3, 2009

blocking read

посовещавшись с людьми в отделе, мы тут поняли, что несмотря на то, что почитать из файла в objective-c в блокирующем режиме очень сложно, программисты кварка, адоба и майкрософта таки смогли это сделать под mac os x

вот уже минут 40 напротив меня возятся чуваки, пытающиеся настроить авторизацию по ключам и получить данные из git репозитория на машине под управлением windows. втроем.

Sunday, September 13, 2009

zfs

вот уже почти год я использую zfs в качестве отказоустойчивого хранилища; на трех терабайтных дисках собран raid 5 (господа из sun называют его raidz1). в целом меня устраивает как это все работает, но хочется заострить внимание на некоторых моментах.

кэширование

начиная с mac os x 10.5 для открываемых файлов было введено кэширование. причем, работает оно по умолчанию. для того, чтобы его отключить, нужно после открытия файла принудительно выставить флаг F_GLOBAL_NOCACHE или F_NOCACHE. гугл дает достаточно информации для того, чтобы составить представление о значении этих флагов. в целом, это не проблема, до тех пор, пока пользователь не начинает пользоваться терминалом и transmission.app. в силу того, что с помощью transmission.app выкачиваются большие объемы данных, то и места в памяти под кэш отдается изрядно. в результате объем неактивной памяти растет, приложения тормозят. то же самое происходит и в терминале при копировании файлов (как минимум).

zfs относится к этому тем местом, что кэширование содержимого файлов на zfs не работает. для системя это в целом плохо, но для transmission — хорошо.

snapshots

zfs поддерживает технологию copy-on-write. суть ее состоит в том, что в случае перезаписи содержимого файла, реальная запись производится в свободное место. поэтому старые данные остаются доступными даже после изменения файла. на этом основан механизм snapshot'ов. при создании снимка состояния диска просто указывается время, когда считать данные измененными. и такой снимок совсем не занимает места, потому как место на диске занимают только измененные по сравнению с неким состоянием snapshot данные. в целом, это такой аналог тайм машины, только без резервного копирования.

raidz

это аналог raid5. то есть когда данные равномерным слоем размазаны по дискам, при этом данных — 2/3, а контрольных сумм — 1/3 от объема. поэтому емкость raidz в 2 терабайта достигается тремя дисками по терабайту. не так давно один из диско вышел из строя, для его замены оказалось достаточным поставить диск для замены, разметить его аналогично и запустить процедуру миграции данных с помощью команды zpool replace. аналогичных бесплатных решений для mac os x не существует.

с raidz связана одна не самая приятная особенность. в силу того, что building blocks для zfs являются файлы, то и перестройка raidz оказалась очень длительной — около 20–ти часов.




zpool status
pool: ultra
state: DEGRADED
status: One or more devices is currently being resilvered. The pool will
continue to function, possibly in a degraded state.
action: Wait for the resilver to complete.
scrub: resilver in progress, 0.00% done, 1665h13m to go
config:

NAME STATE READ WRITE CKSUM
ultra DEGRADED 0 0 0
raidz1 DEGRADED 0 0 0
replacing DEGRADED 0 0 0
disk2s3/old UNAVAIL 0 0 0 cannot open
disk2s3 ONLINE 0 0 0
disk1s3 ONLINE 0 0 0
disk3s3 ONLINE 0 0 0





частичная поддержка

в настоящее время zfs имеется для 10.5 и при этом часть функциональности просто не работает: очистка корзины, поддержка из disk utility и некотрые другие мелочи.

Friday, August 14, 2009

cafeteria refactoring

1. выручка


в РИА «Новости» есть столовая. не буду придираться к качеству питания, меня устраивает, но не фонтан, конечно же. сотрудники питаются со скидкой 15%; чеки у сотрудников и людей со стороны разные.

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

проанализировав чеки, оказалось, что у них есть два счетчика — сквозной для всех касс номер чека и уникальная для кассы сумма, на которую отобедали люди со скидкой. получилось, что в среднем за сутки столовая выдает 1300 чеков. если учесть, что не все люди ходят обедать (хотя, большинство все–таки ходит), некоторые ходят завтракать и вечером пить кофе, то, наверное, можно получить около тысячи чеков, которые входят в «обеденную» выборку. с учетом средней суммы чека в 100 рублей, выходит оборот в сто тысяч рублей в день.

вечернюю выборку чеков по всем кассам мы не делали.

2. рефакторинг


рефакторинг кухни я не рассматриваю, так как знаю про кухню понаслышке. например, возьмем очереди в столовой. они возникают на раздаче, где люди заказывают еду. заказ — положить на тарелку — отдать тарелку. вполне можно организовать на каждое блюдо одного человека, который просто следит за тем чтобы каждого блюда было достаточно для того, чтобы люди подошли и просто взяли тарелку (спасибо, tinsdale). очередь уменьшается, но при этом растет очередь на кассе. дажен разгрузив кассу, придется найти дополнительное место в столовой и так далее. то есть оказывается, что текущий подход оказывается выигрышным из–за того, что ожидая везде понемногу, человеку не приходится стоять перед занятыми столами.

3. маржа


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

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

4. все просто


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

Sunday, August 9, 2009

HTTPOnly

это будет добрый пост.

почти без мата.

волшебный параметр для кук (cookies), который управляет отдачей их клиенту. например, скрипту.

документация: http://www.owasp.org/index.php/HTTPOnly

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

вообще, исходя из поддержки всякого стаффа, нужно оставить только два движка — вебкит и gecko (и то, последний — только до тех пор, пока все не перетянутся на хром/сафари). потому что IE любой версии все хуево рендерит и вообще, для них приходится часто другие страницы писать, а опера — просто говно браузер.

Wednesday, August 5, 2009

colocation support

хостинг на три буквы, первая — m




я: нужно перезагрузить сервер
они: готово
я: что–то нет ответа. а не могли бы вы подключить kvm?
они: готово, логин, пароль
я: спасибо, kvm работает, но, к сожалению, сервер не мой



первый их сбой, кстати. все остальное — просто замечательно; лучший хостер из всех на моей памяти



хостинг на 6 букв, первая — m


сначала подвисала сетевуха с сообщением TX is hung и они не могли разобраться в проблеме


после перетыкания кабеля стало работать


обнаружив, что соединение half duplex вместо full duplex, предположил, что проблема у них в кабельной системе. ответа жду уже третью неделю



хостинг на 10 букв, первая — m



перевозили без предупреждения ночью сервер в другой датацентр


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



хостинг на 9 букв, первая буква — p


пиздец, никому не пожелаю.


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


при установке сервера выдали мне чужие ip адреса.


забыли оформить пропуск на внос сервера.


при расставании выдали не мои салазки.


на площадке сервер перед выносом всегда выключается по питанию.

Friday, July 24, 2009

svn

svn мне напоминает анекдот:

«
– я ж тебе говорил, что это говно, а ты — засахарилось, засахарилось.
»

возьмем, например связывание директории с другим репозиторием через svn:externals

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

памятка:
$ cat >svn_ext_val.txt
dir_of_repo_one http://svn.my.com/path/to/repo_one
dir/of/repo/two http://svn.my.com/path/to/dir1/dir2/repo_two
svn propset svn:externals . -F svn_ext_val.txt

ЕЩЕ: все оказалось еще интереснее. оказывается, эти проперти нужно закоммитить, а у меня была куча файлов, которые коммитить не хотелось. определенно, разработчики svn какие–то хуеголовые

ЕЩЕЩЕ: они не умеют показать файлы, которые будут обновлены без реального update. это уже даже не пиздец

Monday, July 13, 2009

SD vs BluRay

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


типSD/microSDDVDBluRayHDD
размер32 × 24 mm
11 x 15 mm
120 x 120 mm101.6 х 26.1 х 147 mm
емкость*8GB4.38 GB25GB1000GB
скорость доступа20 MB/s at 150x10 MB/s18 MB/s at 4x30 MB/s (USB 2.0)
стоимость оборудования, руб.100100090001000
цена носителя за гигабайт717213
цена за 1000 гигабайт**125 / 72500220 / 785040 / 302001 / 4200


* за номинальную емкость SD взята емкость, которая оправдана экономически, то есть лучше по соотношению емкость/стоимость

** включая стоимость оборудования, коим является кардридер, дисковод и коробка для hdd; цифра в числителе дроби — количество накопителей.

мораль всего этого такова:
  1. для домашнего консервирования дешевле и удобнее купить внешний жесткий диск;

  2. для переноса небольшого количества данных стоит использовать SD/microSD; для большого количества данных — внешний hdd

  3. диски BluRay по большому счету нафиг никому не нужны в дальней перспективе — SD очень активно дешевеют, чего за BluRay дисками не наблюдается. и применения им не видно, потому что для переноски данных они не годятся из–за высокой стоимости оборудования, для консервирования — из–за высокой стоимости;

  4. DVD — достояние истории. на них по прежнему можно хранить данные, но ощутимо проще (но не дешевле) купить SD на 8–16 GB и забыть про стопки DVD как про страшный сон;

  5. не стоит рассматривать SD как панацею — стоимость за гигабайт все еще слишком высока.

Monday, June 22, 2009

opensource

вообще, opensource забавная штука. вот я выкладываю свой код и получаю на него вполне себе feedback. opensource — это как социальные сети для разработчиков.

в большинстве своем opensource, конечно, на редкость уебищно — нет ни нормального интерфейса, ни нормального кода, но некоторые проекты, в которых есть некий заказчик и организатор или упёртый эниузиаст, выходят отличными. например, ничего лучше, чем evolution, для почты еще не придумали. или другой пример, я использую eclipse colorer plugin для подсветки синтаксиса многих файлов. оба — и eclipse и colorer — примеры качественного opensource.

и мне самому было бы тяжело без открытого кода. как бы я тогда поправил баги в DBD::Oracle, если бы не было исходников?

вообще все это я хотел написать после того, как пересоберу colorer под snow leopard. но не тут то было — colorer пересобрался, но при попытке открытия файла падает.


ХАХАХА: мы с создателем colorer нашли проблему и я таки собрал новую версию.

Thursday, June 4, 2009

miraculous oracle

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

допустим, в таблице есть поле VARCHAR2. максимальный размер поля такого типа — 4000 байт. теперь начинается fun. допустим, мы создаем поле типа VARCHAR2(100 CHAR). в реальности же будет создано поле размером x00 байт (где x — максимальное количество байт, которое потребуется для представления любого символа из UCS2 в UTF8). так, чтобы 100 любых символов из unicode поместились. хотя, возможно, внутри оно хранится в UCS2 и поэтому выделяется всего 400 байт.

отойдем от технических деталей и попробуем вставить 100 символов. у нас все получится, несмотря на кодировку. то есть вставится и 100 ASCII и 100 Kana.

теперь же попробуем выделить 4000 CHAR для этого поля. и что вы думаете? в такое поле может быть вставлено будет только то количество символов, которое в utf8 помещается в это количество байт. на другие значения будет выдано сообщение об ошибке.

совсем забыл: но это еще не все. для обхождения ограничения в 4000 байт нужно использовать CLOB. но просто так нельзя записать в CLOB более 4000 байт (меньше — можно). для записи нужно отказаться от


prepare ($$sql)
execute (@params)


и начать использовать


prepare ($sql)
foreach my $params (@params) {
if (sql_type_of ($param) eq 'CLOB') {
bind_param ($i, $param, {ora_type => 112})
} else {
bind_param ($i, $param)
}
}
execute


там, конечно, условия посложнее, но общее представление показывают

DBD::Oracle bugs

второй критический баг в DBD::Oracle:

https://rt.cpan.org/Ticket/Display.html?id=46661

p.s: первый:

https://rt.cpan.org/Ticket/Display.html?id=44788

Tuesday, May 19, 2009

еще немного в копилку о базах

как обычно, сегодня одна какашка в сторону oracle и луч поноса в сторону mysql.

oracle, как сурьезный движок баз данных, конечно же не имеет неявных секвенсоров (хотя, может и имеет, но я не знаю способа привязать секвенсор к полю кроме как через триггер). поэтому функция $dbh->last_insert_id вообще не имеет смысла. чтобы достать это самое значение для primary key, сгенерированное из некоего секвенсора, я должен детектить секвенсор и брать из него currval. жутковато, но работает.

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

вообще, oracle постепенно у меня в голове превращается в долбанутую, но вполне работоспособную систему.

теперь к mysql

BEWARE 5.1!

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

короче, я не знаю, как там будет дальше с mysql, но если он исчезнет, то я не расстроюсь. ну его нахуй в таком–то виде.

Wednesday, May 13, 2009

mymyки

все–таки, mysql — это даже не пиздец.

это пиздец–пиздец–пиздец.

команда mysqlcheck (5.1.31a) с опцией оптимизации таблиц убивает несколько полей из системных таблиц mysql. что порождает веcелые ошибки типа:


090514 3:21:50 [ERROR] Column count of mysql.db is wrong. Expected 22, found 20. The table is probably corrupted
090514 3:21:50 [ERROR] mysql.user has no `Event_priv` column at position 29
090514 3:21:50 [ERROR] Event Scheduler: An error occurred when initializing system tables. Disabling the Event Scheduler.


что перерастает в черепашьи скорости работы с базой.

вот мне на память:


alter table db add `Event_priv` enum('N','Y') CHARACTER SET utf8 NOT NULL DEFAULT 'N';
alter table db add `Trigger_priv` enum('N','Y') CHARACTER SET utf8 NOT NULL DEFAULT 'N';
alter table user add `Event_priv` enum('N','Y') CHARACTER SET utf8 NOT NULL DEFAULT 'N' after Create_user_priv;
alter table user add `Trigger_priv` enum('N','Y') CHARACTER SET utf8 NOT NULL DEFAULT 'N' after Event_priv;

oramac

вообще, история оракла на mac os x напоминает желанного, но нелюбимого ребенка. видимо когда–то, когда вышел mac os x, кто–то из менеджеров оракла сказал:

— а чё ваще! это же юникс, вон на нем уже кластера собирают, jre есть, давайте забацаем оракл под мак!

и программисты бацают оракл под мак PPC.

причем, сама база выпускается не в production, а так, для игр:

«This document accompanies Oracle9i Developer release 2 (9.2.0.1.0) for Mac
OS X. Its contents supplement or supersede information in the Oracle9i
documentation library.

This is a developer release. It is not intended to be used in a production
environment. You should try this software only in a test environment.»

выпустив oracle 10g под мак, про саму базу надолго забыли. только один раз обновили клиента. и вот, совсем недавно, появилось обновление самой базы: ее наконец умудрились собрать под x86_64.

естественно, люди из оракла живут в своей собственной вселенной. они ничего не знают ни про universal binary, ни про launchd, ни про пользовательский интерфейс mac os x.

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

естественно, DBD::Oracle не смог поставиться сам. после небольшого шаманства с патчами таки его удалось собрать, но работать он от этого не стал — в rian.ru используются named sql placeholders, а они–то как раз и не завелись. несколько утренних упражнений с драйвером рассказали мне о том, что на линуксе bool это нифига не bool а char и, даже, возможно, int. а на маке совсем не так. ну ладно, патч отправил, у меня локально все заработало и даже в DBD::Oracle 1.23 включили мои изменения.

но вот какой вопрос не дает мне покоя: неужели никто до меня не использовал named placeholders в oracle через perl на mac os x? вообще, хоть кто–то работал с ораклом через perl?

Tuesday, May 12, 2009

nginx + rpaf

используя nginx в качестве frontend и apache2 в качестве backend, обнаружил, что у кучи говноскриптов на php отвалился определитель клиентского ip. mod_rpaf меня выручил, но собрать universal binary оказало не так просто.

вот solution — скачать, распаковать, запустить:

sudo apxs -Wl,-arch -Wl,i386 -Wl,-arch -Wl,ppc -Wc,-arch -Wc,ppc -Wc,-arch -Wc,i386 -Wl,-arch -Wl,x86_64 -Wl,-arch -Wl,ppc64 -Wc,-arch -Wc,ppc64 -Wc,-arch -Wc,x86_64 -i -c -n mod_rpaf-2.0.so mod_rpaf-2.0.c

oracle environment variables

вот никак не мог правильно подобрать выражение, чтобы правильно описать мою возню с oracle. накатило и я все понял; вот оно:

«чтобы спереди погладить, нужно сзади полизать»

пример:

установка переменной:

alter session set nls_date_format = 'dd/mm/yyyy hh24:mi:ss';

получение значения переменной:

select parameter, value from v$nls_parameters where parameter = 'NLS_DATE_FORMAT';

касательно установки oracle server на mac os x:

вообще, оракл сервер весь из себя прикольный–прикольный. проще даже сказать, ебанутый на всю голову. вот, например, после установки, обнаруживается, что там внутри свой собственный jre и собственный perl 5.8.3 и еще много всего. зато старт–стоп скриптов отродясь не водится. «читайте пару лет документацию и вам откроется тайное знание написания старт–стоп скриптов». до кучи нужно сказать, что оракл сервер смог поставиться, но не смог запуститься.

Thursday, April 9, 2009

mac os x limits

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

оказывается, что в mac os x 10.5 по умолчанию одним пользователем можно открыть не более 266 приложений. при этом часть из них — системные сервисы, поэтому реально запущеных приложений будет меньше. если такого количества не хватает, то можно увеличить лимит и об этом пойдет речь ниже.

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

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

как показывает команда «sysctl -a | grep maxproc», операционная система ограничила себя до 532 процессов в целом и не более 266 на одного пользователя. не очень–то пожируешь. ну что ж, на то нам дадены руки.

sysctl -w kern.maxproc=4096
sysctl: kern.maxproc: Invalid argument

опа, а это что такое?

это оказалось, что в ядре операционной системы записан жесткий лимит в 2500 соединений. превысить его можно только после пересборки ядра. то есть запустить под mac os x client более 2500 процессов невозможно.

в server 10.4.11 тоже есть подобный лимит, только он чуть ниже — 2068

для увеличения лимита можно добавить информацию в два файла:

/etc/sysctl.conf и /etc/launchd.conf

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

/etc/sysctl.conf
kern.maxprocperuid=1024
kern.maxproc=2048

/etc/launchd.conf
limit maxproc 512 1024

Wednesday, March 25, 2009

postfix: no spam without antispam

борьба со спамом без антиспама.

примерно с месяц назад на своей работе я начал переносить почту со старого и неуправляемого CommunigatePro на более стандартный (в рамках почтового сервера под управлением Mac OS X) postfix. и после переноса аккаунтов обнаружил, что /var/log/mail.log растет не по дням, а по часам, причем на пару сотен мегабайт в час. к концу суток у меня был шестигигабайтный лог файл и около гигабайта новых писем. я довольно сильно испугался, что так будет и дальше.

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

это вынудило меня начать разбираться со встроенными механизмами фильтрации спама в postfix и возможности применить особенности протокола smtp для отсеивания всей этой корреспонденции. можно было бы попробовать поставить spamassassin или другие решения с открытыми исходниками и натюнинговать их, но гигабайт принятой почты меня совсем не радовал. платные варианты сразу же были исключены, так как спам в основном приходит на русском языке, а kaspersky antispam и спамоборона не имеют сборок под Mac OS X.

немного теории

любая машина, подключенная к интернет, может получить mx dns запись для любого из доменов и отправить туда почту. при этом, можно отправить почту не напрямую, а через специальный relay сервер, который уже сам займется доставкой почты до получателя. обычно relay сервера требуют авторизации отправителя для дальнейшей пересылки почты. те, которые не требуют авторизации, называются open relay. проблема, которая связана с ними — это то, что любая машина сможет послать письмо, которое будет выглядеть, как письмо, полученное от этого relay.

в итоге доставка почты выглядит примерно так:

машина пользователя => relay => … => relay => сервер назначения

отсылка почты напрямую используется сейчас не очень часто и, в основном, всякими сервисами и гиками, которые сподобились настроить local delivery. в том случае, когда пользователь отправляет почту через почтовую программу с указанием mail сервера и данных аутентификации или через web–интерфейс, то почта уходит напрямую с сервера почтового сервиса. при этом отсылка почты напрямую в большинстве случаев сразу же дает знать о себе: скорее всего у такого хоста не будет reverse dns записи или будет что–то выделяющееся, например ppp85-140-10-222.pppoe.mtu-net.ru; в случае серьезного сервиса его владельцы обычно заботятся о reverse dns записи.

reverse dns — это когда по ip адресу можно получить имя связанного с ним домена.

тут есть одна тонкость: спамер может зарегистрировать кучу доменов, купить кучу ip адресов, но ему придется все время покупать новые домены и ip адреса (потому что его будут блокировать — адрес–то известен), что не слишком выгодно. поэтому зачастую спамеры используют зараженные вирусами машины, чтобы ответственность легла на пользователя такой машины. большинство таких зараженных машин находится дома у пользователей, а самый распространненый тип домашнего подключения — это доступ с динамическим ip адресом.

поэтому, отказывая в получении почты с динамических адресов, мы ограничиваем неправильно настроенные интернет–сервисы, гиков с local delivery и сети машин домашних пользователей, зараженные вирусами и рассылающие спам.

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

после отсеивания всех неугодных нам машин, мы беремся за то, как спамеры общаются с нашим почтовым сервером по SMTP протоколу. большинство доковылявших спам–ботов отваливается на простой проверке — в команде HELO должно быть полное доменное имя отправителя. дальше вставляем несколько простых проверок — на наличие указанного адресата, на количество адресатов в минуту, почту для которых мы готовы принять. дальше просто принимаем почту и надеемся, что тупых бот сетей больше, чем разумных.

практика

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

различные «строгие» опции:


strict_rfc821_envelopes = yes
disable_vrfy_command = yes
smtpd_delay_reject = yes
smtpd_helo_required = yes



лимитирование слишком быстрых:


anvil_rate_time_unit = 60s

smtpd_client_connection_count_limit = 5
smtpd_client_connection_rate_limit = 6
smtpd_client_message_rate_limit = 6
smtpd_client_recipient_rate_limit = 10


вторая проблема, которая стала сразу же видна — это соединения с динамических адресов различных интернет провайдеров (через dialup, adsl или подобные соединения) или тех адресов, которые вообще не имеют reverse dns записи. копания в поисках способа определения этих самых динамических пользователей привели меня к статье http://www.yekt.info/postfix_antyspam.html. там я и почерпнул необходимую информацию, но, к сожалению, действия, приводимые там мне не очень понравились, поэтому я расскажу, что сделал я, а те, кому интересно, смогут сравнить и сделать свои собственные выводы.

отклоняем желание клиента прогнать команды «по–быстрому»; разрешаем тех, кто ввел логин/пароль; разрешаем соединения из доверенных сетей; отклоняем тех у кого не совпадают сочетания ip адрес 1=>домен, домен=>ip адрес 2 и ip адрес 1 == ip адрес 2; проверяем клиента на отсутствие в известных dialup и dsl сетях.


smtpd_client_restrictions =
reject_unauth_pipelining,
permit_sasl_authenticated,
permit_mynetworks,
reject_unknown_client_hostname,
check_client_access regexp:/etc/postfix/dul_checks,
permit


ниже добавились:
проверка на известные проблемные helo, отказ от обслуживания клиентам, доменное имя которых вызывает подозрения


smtpd_helo_restrictions =
permit_mynetworks,
permit_sasl_authenticated,
check_helo_access regexp:/etc/postfix/helo_regexp,
check_helo_access regexp:/etc/postfix/dul_checks,
reject_invalid_helo_hostname,
reject_non_fqdn_helo_hostname,
reject_unknown_helo_hostname,
permit


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


smtpd_sender_restrictions =
permit_sasl_authenticated,
permit_mynetworks,
reject_non_fqdn_sender,
reject_unknown_sender_domain,
permit


smtpd_recipient_restrictions =
reject_unauth_pipelining,
permit_mynetworks,
permit_sasl_authenticated,
reject_unauth_destination,
reject_invalid_hostname,
reject_non_fqdn_recipient,
reject_unknown_recipient_domain,
permit


результат

оказался хорош. например, за 24 марта было 433 158 попыток соединения с почтовым сервером, чтобы отправить почту и почта была доставлена лишь в 1 068 случаях.

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

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

Friday, March 20, 2009

Thursday, March 5, 2009

mysql grants dump

меня тут на собеседовании спросили: «а почему вы не любите mysql»?

я вам отвечу.

когда делается «grant privileges on … to 'user'@'hostname' … », то при наличии двух записей, указывающих на один и тот же ip адрес (например 'user'@'host.example.com' и 'user'@'10.0.2.1'), то выбирается всегда запись с ip адресом, а вот сообщение в логе выводится по reverse dns имени хоста. разработчики mysql, вот вам от меня гнилой помидор!

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


mysql -u super -p <mysql_dump


и вуаля — не работают указанные вами гранты. хотите узнать почему? потому что разработчики mysql не умеют без костыликов и вам придется запустить этот костылик самому:


flush privileges


получите–ка, дорогие мои, в лицо собачьей какашкой.

Friday, January 9, 2009

beware perl

как ни странно, скрипт ниже по тексту письма работает без ошибок.


#!/usr/bin/perl

use strict;

print asdfagertghswdfgasdfgsdfgasdf;

# то же самое, когда перл не может определить контекст bareword, он рассматривает его как FILEHANDLE

{
no strict 'refs';
*{a} = sub {return "hello!!!";};
}

print a; # does nothing
print a (); # nothing
print "-=-=-=-=-=-=-=-";
print a(); # ok
print &a; # ok

#beware!