On 12.02.2011 22:43, Victor Ustugov wrote:
t...@irk.ru wrote:
а есть что-нибудь некоммерческое к чему exim может ходить через
spamd_address?

http://bitbucket.org/vstakhov/rspamd/

разработчик из России, работает в Рамблере

Так как я также подписан на эту рассылку, то прокомментирую некоторые моменты.

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

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

что касается интеграции с exim, то есть как минимум три способа:
1. работа по протоколу SpamAssassin'а RSPAMC (не пробовал)

Протокол SpamAssassin'а - это все-таки spamc, а не rspamc.

2. работа по протоколу RSPAMC через одну из двух предлагаемых функций
local_scan (пробовал, работает, но local_scan для меня неприемлем)
3. на основе штатных local_scan функций легко можно написать свою dlfunc
(в том числе благодаря простоте протокола RSPAMC, см. выше)

Кроме этого, начиная с 0.3.5 можно использовать библиотеку librspamdclient. Или же приложенный патч.

уровень false positives и false negatives выше, чем у SpamAssassin,
правда ситуация немного выравнивается после дообучения местного Bayes
фильтра.

Думаю, что статистика SA, использующая униграммы (то есть, одиночные слова) намного хуже, чем статистика rspamd, которая использует алгоритм OSB на окне из 5-ти слов (то есть, анализируются не только слова, но и их сочетания). Похожие алгоритмы используются также, например, в dspam или в crm114.

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

На самом деле такой подход появился в результате следования логике разбиения правил в SA. Кроме того, была потребность повесить на некоторое правило функцию lua (например, правило EMPTY_IMAGE в примере конфигурации).

для правил нет строки описания, как в SpamAssassin, т. е. в ответе
демона фигурируют лишь названия правил, без весов и описания. как в этом
отношении ведет себя rspamd работая по протоколу SPAMC, я не проверял,
т. к. работа по протоколу SPAMC подразумевает, что контент сканер сам
получает информацию об адресе клиента, HELO, адресе отправителя и адресе
получателя из заголовков письма. а в случае использования протокола
RSPAMC эти данные передаются демону в явном виде.

Вообще, добавить описания к правилам - хорошая, годная, а главное - легко реализуемая идея, например, сделав в описании правил атрибут description:
<symbol weight="1.0" description="Some symbol">SYMBOL</symbol>

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

в регекспах не работают конструкции \1, \2 и т. д.
моих знаний программирования на C не хватило, чтобы понять, виноват
rspamd или pcre.

Просто для ускорения работы отключены capture group. Опять же можно добавить крыжик в конфигурацию, чтобы их можно было включать.

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

в плагине check_forged_headers есть ошибки, из-за чего правило
FORGED_RECIPIENTS ложно срабатывает время от времени.

Был бы признателен за подробности: в каких случаях оно ложно срабатывает?

я наткнулся уже на пару писем, при обработке которых возникаются
проблемы при описании более одной метрики в rspamd.xml.
демон пишет в сокет ответ с данными по первой метрике и начинает
потреблять около 90% процессорного времени.
тестирование проводилось в виртуалке, на физической машине может меньше
начнет отжирать, но от этого не легче. после этого приходилось демона
убивать по kill -9.
пока отложил проблему в сторону, т. к. вторая метрика была создана в
тестовых целях и для штатной работы пока вполне хватит одной метрики.

Спасибо за репорт, я попробую создать такую конфигурацию.

Ну и в целом, я всегда готов рассмотреть пожелания по улучшению rspamd или же по устранению багов, в нем обнаруженных :)
--- src/spam.c.orig     2011-01-20 19:29:51.179597017 +0300
+++ src/spam.c  2011-01-20 19:40:42.818516872 +0300
@@ -21,6 +21,9 @@
 int spam_ok = 0;
 int spam_rc = 0;
 
+/* push formatted line into vector */
+static int push_line(struct iovec *iov, int i, const char *fmt, ...);
+
 int spam(uschar **listptr) {
   int sep = 0;
   uschar *list = *listptr;
@@ -211,14 +214,26 @@
   }
 
   /* now we are connected to spamd on spamd_sock */
-  (void)string_format(spamd_buffer,
-           sizeof(spamd_buffer),
-           "REPORT SPAMC/1.2\r\nUser: %s\r\nContent-length: %ld\r\n\r\n",
-           user_name,
-           mbox_size);
+  int r, request_p = 0;
+  const char *helo;
+  struct iovec request_v[64];
+  
+  r = 0;
+  r += push_line(request_v, request_p++, "REPORT SPAMC/1.2\r\n");
+  r += push_line(request_v, request_p++, "Content-length: " OFF_T_FMT "\r\n", 
mbox_size);
+  r += push_line(request_v, request_p++, "Queue-Id: %s\r\n", message_id);
+  r += push_line(request_v, request_p++, "From: %s\r\n", sender_address);
+  r += push_line(request_v, request_p++, "Recipient-Number: %d\r\n", 
recipients_count);
+  for (i = 0; i < recipients_count; i ++)
+    r += push_line(request_v, request_p++, "Rcpt: %s\r\n", 
recipients_list[i].address);
+  if ((helo = expand_string(US"$sender_helo_name")) != NULL && *helo != '\0')
+    r += push_line(request_v, request_p++, "Helo: %s\r\n", helo);
+  if (sender_host_address != NULL)
+    r += push_line(request_v, request_p++, "IP: %s\r\n", sender_host_address);
+  r += push_line(request_v, request_p++, "\r\n");
 
   /* send our request */
-  if (send(spamd_sock, spamd_buffer, Ustrlen(spamd_buffer), 0) < 0) {
+  if (writev(spamd_sock, request_v, request_p) < 0) {
     (void)close(spamd_sock);
     log_write(0, LOG_MAIN|LOG_PANIC,
          "spam acl condition: spamd send failed: %s", strerror(errno));
@@ -420,4 +435,31 @@
   };
 }
 
+static int
+push_line(struct iovec *iov, const int i, const char *fmt, ...)
+{
+  va_list ap;
+  size_t len;
+  char buf[512];
+
+  if (i >= 64) {
+    log_write(0, LOG_MAIN, "rspam: %s: index out of bounds", __FUNCTION__);
+    return (-1);
+  }
+
+  va_start(ap, fmt);
+  len = vsnprintf(buf, sizeof(buf), fmt, ap);
+  va_end(ap);
+
+  iov[i].iov_base = string_copy(US buf);
+  iov[i].iov_len = len;
+
+  if (len >= sizeof(buf)) {
+    log_write(0, LOG_MAIN, "rspam: %s: error, string was longer than %d", 
__FUNCTION__, sizeof(buf));
+    return (-1);
+  }
+
+  return 0;
+}
+
 #endif
_______________________________________________
Exim-users mailing list
Exim-users@mailground.net
http://mailground.net/mailman/listinfo/exim-users

Ответить