0
28
Дек
2009

DSPAM для CGP v1.0.1

949d805d531e

Обновил dspam-cgp.c до версии 1.0.1.

Добавлен традиционный для CGP заголовок вида: X-Junk-Score: 90 [XXXX]. Его удобно использовать для применения различных действий  к письмам с разным уровнем «вероятности» спама. Этот заголовок автоматически используется в разделе «Упрощённые Правила по Обработке Спама». Так же это можно использовать и в своих правилах вида:

Header Field is   X-Junk-Score:*[XXXX*
Store in  Junk
Discard

Подробнее о том как использовать этот заголовок можно прочитать на сайте CGP в описании настроек для фильтра CGPSpamCatcher.

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

/* Defines the bar score ranges. By default the following ratios are used:
 * digital    Bar score
 * 0          []
 * 1-49       [X]
 * 50-70      [XX]
 * 71-89      [XXX]
 * 90-94      [XXXX]
 * 95-99      [XXXXX]
 * 100        [XXXXXX]
*/
int BARSCORERANGES[] = {0,49,70,89,94,99,100,      -1};

Вероятность может быть от 0 до 100. Количество диапазонов может быть любым. Вероятность вычисляется исходя из результатов, которые сообщает dspam.  Пока мне кажется оптимальным такое распределение вероятностей. Но вы можете сами изменить их, отредактировав BARSCORERANGES[]. Конечный «-1» всегда должен присутствовать последним элементом, он используется для определения конца массива.

О том как изменить dspam и использовать его для CGP читать в предыдущей статье: DSPAM для CGP в режиме добавления заголовков

0

dspam-logo-eyes DSPAM — это свободное программное обеспечение, представляющее собой статистический спам фильтр.

Проект DSPAM, который некоторое время оказался заброшенным, вот уже больше полугода активно развивается dspam-сообществом. В 2007 году его бывший автор Jonathan Zdziarski передал свои права компании Sensory Networks. А в январе 2009 года компания Sensory Networks объявила, что перестаёт заниматься этим проектом и полностью передала все права dspam-сообществу.

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

Читать полностью »

0

whitelistНаравне с технологией DNS blacklisting (DNSBL) существует технология DNS whitelisting (DNSWL). Это списки ip-адресов, хранимые с использованием системы архитектуры DNS. Но в отличии от «чёрных списков»(blacklist), которые хранят ip-адреса распространителей спама, «белые списки»(whitelist) хранят ip-адреса тех, кто в рассылках спама не замечен.

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

Мне показалось, что наиболее полную базу «белых адресов» имеет ресурс dnswl.org. Этот ресурс, помимо самого факта «чистоты» ip-адреса, хранит так же уровень этой чистоты(Trust Level).

Всего уровней четыре:

  1. High – никогда не рассылал спам;
  2. Medium – крайне редки случаи спама, быстро реагируют на проблемы;
  3. Low – иногда рассылают спам, активно реагируют на проблемы, но менее оперативно;
  4. None – легитимный почтовый сервер, но может рассылать спам.

Применение этого белого списка может быть таким:

  • не применять технологию «серых списков» для всех ip-адресов с уровнями None-High;
  • не применять технологию «черных списков» для всех ip-адресов с уровнями None-High;
  • не проверять письма на спам (или проверять в меньшей степени) для ip-адресов с уровнями Medium-High.

Вся остальная почта с адресов, которых нет в DNSWL, пройдёт полную проверку.

Для CGP я написал dnswl-cgp.c фильтр (cgp helper), который делает запрос в DNSWL и добавляет в сообщение заголовок: «X-DNSWL-Status: <Trust Level>».

Читать полностью »

0

mail_deliveryДля того, что бы доставлять сообщения в почтовый ящик пользователя, в ZMailer существует mailbox LDA. Но у него есть ряд ограничений:

  • он умеет работать только с mailbox ящиками (не умеет maildir или dbox)
  • он не имеет почтовых фильтров (и не умеет доставлять куда-либо, кроме INBOX)
  • квота может быть только на файловой системе (только fs_quota)
  • никак не учитывает того, кто дальше работает с этим ящиком (pop/imap)

Если же вы уже используете в качестве pop/imap сервера dovecot, то использование dovecot LDA выглядит хорошей идеей.

Тогда вы получаете:

  • индексирование ящика в момент доставки, что ускоряет доступ к нему через pop/imap
  • использование разных тип квот, которые умеет dovecot (fs, dirsize, dict, maildir)
  • язык фильтров sieve (переадресация, авто-ответ, доставка в любые папки)
  • ящик может быть не только mailbox типа (mbox, maildir, dbox)

Для установки в ZMailer'е dovecot LDA в качестве доставщика сообщений в ящик пользователя надо:

Читать полностью »

1

timeoutПонадобилось реализовать построчное чтение из сокета с timeout-ом. Написал для fgets () обёртку — ifgets (). Для обеспечения timeout-a используется select (). В процессе написания столкнулся с проблемой: select()  почему-то всегда выдавал timeout, хотя данные были прочтены еще не все.

Strace показал странное поведение: мною читалась первая строка, далее был выход из функции чтения, но далее кто-то(не я) читал всё остальное содержимое открытого сокета. Естественно, при моей попытке прочитать следующую строку из сокета, по мнению select () он был пуст и происходил timeout.

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

Пользоваться почти так же как fgets ():

int fd;
FILE *fds;

/* Делаем TCP сокет */
fd = socket(PF_INET, SOCK_STREAM, 0);

/* Параметры для соединения опущены */

/* Соединяемся */
connect(fd, (struct sockaddr *) &srv_i, sizeof(srv_i));

/* Переоткрываем сокет как поток */
fds =  fdopen(fd, "w+");

/* !!! ВНИМАНИЕ! Надо обязательно выключить буферизированное чтение.
Иначе всё сразу будет прочтено в буфер и
select будет возвращать только timeout
*/
setvbuf(fds, (char *) NULL, _IONBF, 0);

/* Ну а дальше вызываем ifges() и передаём timeout в сек.
и integer descriptor для select-а
*/
if (ifgets(buf, buflen, fds, timeout, fd))
      return strlen(buf);         
if (errno == ETIMEDOUT) {
     print("Socket timeout after %d seconds", timeout);
     return (-1);
}

Сама ifgets () реализована так:

char *
ifgets(char *s, int size, FILE *stream, int timeout, int fd)
{
  int res;

  if (timeout) {
      do {
          res = select_fd (fd, timeout, 0);
      } while (res == -1 && errno == EINTR);
      if (res < = 0) {
        if (res == 0) {
                errno = ETIMEDOUT;
                return NULL;
        }
      return NULL;
      }
  }
  if(fgets(s, size, stream)) {
        return s;
  }
  return NULL;
}
/* ----------------------------------------------------------------- */
static int
select_fd (int fd, int maxtime, int writep)
{
  fd_set fds, exceptfds;
  struct timeval timeout;
  FD_ZERO (&fds);
  FD_SET (fd, &fds);
  FD_ZERO (&exceptfds);
  FD_SET (fd, &exceptfds);
  timeout.tv_sec = maxtime;
  timeout.tv_usec = 0;
  /* HPUX reportedly warns here.  What is the correct incantation?  */
  return select (fd + 1, writep ? NULL : &fds, writep ? &fds : NULL,
                 &exceptfds, &timeout);
}
0

logo70-tran

У NFS клиента в 2.6.x ядре появилась неприятная особенность. Он никак не сигнализирует о невозможности записать данные по причине превышения файловой квоты. А наоборот всем своим поведением говорит о том, что всё хорошо. Все операции, включая fsync() и close() заканчиваются успешно. Более того, даже ls после этого показывает якобы всё записано (размер файла равен записанному, что превышает квоту). Но через несколько секунд размер файла «укорачивается» до того размера, что поместилось в квоту (что в общем-то и есть правда).

Вот небольшая тестовая программа test_nfswrite.c, которая пишет 1024 байтные блоки. Тестовый файл /mount/m7/tmp/test должен быть на NFS сервере (не важно с каким ядром). А клиент, который пишет с ядром 2.6.x.

Компилить надо так: gcc test_nfswrite.c -o test_nfswrite

Запускать так: ./test_nfswrite 500

где 500 — это количество блоков по 1024 байта. Если указать большое количество блоков, которое не влезает в квоту, то вы должны наблюдать ошибки. Читать полностью »

0

clam_av_logo

Как известно для прикручивания антивируса ClamAV к CGP есть два открытых helper’а: clamav-cgp и cgpav.

Есть еще один платный от  "Niversoft", но его мы рассматривать не будем.

Как выяснилось, работают они не одинаково. При рассылке большого потока одинаковых сообщений, заметили, что письма уходят медленно — в среднем 1 в секунду. Анализ SMTP диалога отправки сообщений показал, что тормозит проверка антивирусом. При отключенном антивирусе трафик вырос до 30 писем в секунду.

Исследования показали, что сам антивирус не потребляет особо много ресурсов. Тогда возникла мысль про тормоза «прокладки» между CGP и ClamAV. В это время у нас работал cgpav, решили попробовать  clamav-cgp. И о чудо, с новым helper`ом трафик вырос до 15 писем в секунду. Спасибо Andy Igoshin’у за замечательный продукт!

У себя я выложил слегка модифицированную «под себя» версию:

  1. Добавлено отрезание CGP-ных заголовков перед отправкой письма на проверку к ClamAV (рекомендации Николая Варинова из рассылки mx.ru: http://mx.ru/Lists/CGatePro/Message/17475-P.txt).
  2. Немного изменена логика работа helper’а. В случае каких-то внутренних проблем он всегда пропускает сообщение. В логи пишется диагностика ошибки.
  3. Если ClamAV сообщает, что письмо инфицировано, то вместо молчаливого удаления сообщения, генерируется ответ с причиной: в сообщении <YYYYY> найден <XXXXX> вирус.

Комментарии к изменениям: Читать полностью »