Создание динамического черного списка на EXIM

EXIM, sendmail, postfix, Dovecot и прочие. Решение проблем связанных с работой электронной почты

Модератор: xM

Правила форума
Убедительная просьба юзать теги [code] при оформлении листингов.
Сообщения не оформленные должным образом имеют все шансы быть незамеченными.
Podworko
рядовой
Сообщения: 11
Зарегистрирован: 2007-11-02 13:09:17

Создание динамического черного списка на EXIM

Непрочитанное сообщение Podworko » 2008-12-02 14:51:54

Доброе время суток!
Есть необходимость динамически блокировать ip адреса через файервол, если число реджектов для данного ip достигло какого-нить порогового значения.
Кто-нить занимался реализацией подобной схемы?

Хостинговая компания Host-Food.ru
Хостинг HostFood.ru
 

Услуги хостинговой компании Host-Food.ru

Хостинг HostFood.ru

Тарифы на хостинг в России, от 12 рублей: https://www.host-food.ru/tariffs/hosting/
Тарифы на виртуальные сервера (VPS/VDS/KVM) в РФ, от 189 руб.: https://www.host-food.ru/tariffs/virtualny-server-vps/
Выделенные сервера, Россия, Москва, от 2000 рублей (HP Proliant G5, Intel Xeon E5430 (2.66GHz, Quad-Core, 12Mb), 8Gb RAM, 2x300Gb SAS HDD, P400i, 512Mb, BBU):
https://www.host-food.ru/tariffs/vydelennyi-server-ds/
Недорогие домены в популярных зонах: https://www.host-food.ru/domains/

Аватара пользователя
dikens3
подполковник
Сообщения: 4856
Зарегистрирован: 2006-09-06 16:24:08
Откуда: Нижний Новгород
Контактная информация:

Re: Создание динамического черного списка на EXIM

Непрочитанное сообщение dikens3 » 2008-12-02 14:53:42

Админ по умолчанию ленив, если мне потом придётся кого-то из моей чёрной базы удалять, это так напрягает.
Лучше установить FreeBSD, чем потратить 30 лет на Linux'ы и выяснить какой из них хуже.

Podworko
рядовой
Сообщения: 11
Зарегистрирован: 2007-11-02 13:09:17

Re: Создание динамического черного списка на EXIM

Непрочитанное сообщение Podworko » 2008-12-02 14:57:51

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

У меня не хватает опыта работы в связке Mysql+Exim. Если б кто нить дал наводку, дальше бы сам дописал нюансы.

Аватара пользователя
dikens3
подполковник
Сообщения: 4856
Зарегистрирован: 2006-09-06 16:24:08
Откуда: Нижний Новгород
Контактная информация:

Re: Создание динамического черного списка на EXIM

Непрочитанное сообщение dikens3 » 2008-12-02 15:01:19

Podworko писал(а):Можно организовать время делистинга.
Просто по статистике первые позиции реджектов занимают Ip-адреса, которые сотнями раз в сутки долбят мой почтовик...
Ну много чего можно, загоняй их куда-нибудь в mysql, затем выбирай по своим параметрам и в таблицу ipfw.
Лучше установить FreeBSD, чем потратить 30 лет на Linux'ы и выяснить какой из них хуже.

Аватара пользователя
dikens3
подполковник
Сообщения: 4856
Зарегистрирован: 2006-09-06 16:24:08
Откуда: Нижний Новгород
Контактная информация:

Re: Создание динамического черного списка на EXIM

Непрочитанное сообщение dikens3 » 2008-12-02 15:08:18

Код: Выделить всё

# Удаляем/создаём базу.
DROP DATABASE IF EXISTS `exim`;
CREATE DATABASE IF NOT EXISTS `exim` DEFAULT CHARACTER SET koi8r;

USE mysql;
SET CHARACTER SET koi8r;

# Создаём пользователя/права доступа для eximuser.
GRANT SELECT,UPDATE,DELETE,INSERT ON `exim`.* TO `eximuser`@`localhost` IDENTIFIED BY 'eximpassword';
FLUSH PRIVILEGES;

# Создаём таблицу логов.
DROP TABLE IF EXISTS `log`;
CREATE TABLE `log` (
  `username` varchar(50) default NULL,
  `action` smallint(6) unsigned NOT NULL default '0',
  `src_email` varchar(50) default NULL,
  `dst_email` varchar(50) default NULL,
  `src_ip` varchar(15) default NULL,
  `hostname` varchar(255) default NULL,
  `helo` varchar(255) default NULL,
  `date` date default NULL,
  `size` int(11) default NULL,
  `time` timestamp NOT NULL default '',
  KEY `size-date` (`size`,`date`),
  KEY `action-date` (`action`,`date`),
  KEY `size` (`size`),
  KEY `date` (`date`)
) ENGINE=MyISAM DEFAULT CHARSET=koi8r COMMENT='Таблица логов';

# Создаём таблицу текста для логов.
DROP TABLE IF EXISTS `textlog`;
CREATE TABLE `textlog` (
  `id` smallint(6) unsigned NOT NULL auto_increment,
  `text` varchar(255) NOT NULL default '',
  `action` enum('deny','accept','send') NOT NULL default 'deny',
  `text_user` varchar(255) NOT NULL default '',
  PRIMARY KEY `text` (`text`),
  KEY `id` (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=koi8r COMMENT='Таблица текста для логов';


# Добавляем текст логов
LOCK TABLES `textlog` WRITE;
INSERT INTO `textlog` VALUES ('1','Пользователь не найден (root, mailer-daemon и т.п.)','deny','Пользователь не найден');
INSERT INTO `textlog` VALUES ('2','Превышен размер на исходящее сообщение','deny','Превышен размер на исходящее сообщение');
INSERT INTO `textlog` VALUES ('3','Превышен размер на входящее сообщение','deny','Превышен размер на входящее сообщение');
INSERT INTO `textlog` VALUES ('4','Некорректный адрес от (from)','deny','Некорректный адрес от (from)');
INSERT INTO `textlog` VALUES ('5','Запрещённые символы в адресе','deny','Запрещённые символы в адресе');
INSERT INTO `textlog` VALUES ('6','Необходима TLS аутентификация или пароль введён неверно','deny','Необходима TLS аутентификация или пароль введён неверно');
INSERT INTO `textlog` VALUES ('7','Relay у нас запрещён, а письмо не для нашего домена','deny','Relay у нас запрещён, а письмо не для нашего домена');
INSERT INTO `textlog` VALUES ('8','Приём/отправка сообщения разрешена','accept','Приём сообщения разрешён');
INSERT INTO `textlog` VALUES ('9','Рассылка для не аутентифицированных клиентов запрещена','deny','Рассылка для не аутентифицированных клиентов запрещена');
INSERT INTO `textlog` VALUES ('10','Отправитель не существует (подделан)','deny','Отправитель не существует (подделан)');
INSERT INTO `textlog` VALUES ('11','Отсутствует приветствие HELO/EHLO','deny','Сильно неправильно настроенный сервер');
INSERT INTO `textlog` VALUES ('12','IP-Адрес в HELO/EHLO','deny','Сильно неправильно настроенный сервер');
INSERT INTO `textlog` VALUES ('13','В HELO/EHLO нет точки (.)','deny','Сильно неправильно настроенный сервер');
INSERT INTO `textlog` VALUES ('14','Только цифры в HELO/EHLO','deny','Сильно неправильно настроенный сервер');
INSERT INTO `textlog` VALUES ('15','В HELO/EHLO находится localhost или birzhaplus','deny','Сильно неправильно настроенный сервер');
INSERT INTO `textlog` VALUES ('16','Заблокирован по нашему списку HELO/EHLO','deny','Сервер заблокирован нами');
INSERT INTO `textlog` VALUES ('17','Заблокированый нами хост (wanadoo и т.п.)','deny','Заблокированый компьютер отправителя');
INSERT INTO `textlog` VALUES ('18','SPF проверка отрицательна (fail)','deny','Отправитель подделан (spf-fail)');
INSERT INTO `textlog` VALUES ('19','Обнаружен вирус (clamav)','deny','В письме обнаружен вирус');
INSERT INTO `textlog` VALUES ('20','Заблокированный нами IP-Адрес','deny','Сервер заблокирован нами');
INSERT INTO `textlog` VALUES ('21','Такого домена получателя не существует','deny','Такого домена получателя не существует');
INSERT INTO `textlog` VALUES ('22','Хост находится в списках рассылающих спам. (RBL)','deny','Сервер находится в списках рассылающих спам.');
INSERT INTO `textlog` VALUES ('23','Китайские символы в письме','deny','Китайские символы в письме');
INSERT INTO `textlog` VALUES ('24','Ошибка в MIME кодировке письма','deny','Ошибка в кодировке письма');
INSERT INTO `textlog` VALUES ('25','Сообщение содержит недопустимый символ. (NUL)','deny','Сообщение содержит недопустимые символы.');
INSERT INTO `textlog` VALUES ('26','Некорректные заголовки в письме. (header_syntax)','deny','Некорректные данные в письме.');
INSERT INTO `textlog` VALUES ('27','Скрытые копии на этот E-Mail не принимаются.','deny','Скрытые копии на этот E-Mail не принимаются.');
INSERT INTO `textlog` VALUES ('28','Слишком много неправильных адресов получателей','deny','Слишком много неправильных адресов получателей');
INSERT INTO `textlog` VALUES ('29','Поле от содержит E-Mail:<>','deny','Вам пишут с адреса <>? Это наш клиент?');
INSERT INTO `textlog` VALUES ('30','SPF проверка отрицательна (softfail)','deny','Отправитель на 95% подделан (spf-softfail)');
INSERT INTO `textlog` VALUES ('31','Заблокированый нами E-Mail отправителя','deny','Заблокированый нами E-Mail отправителя');
INSERT INTO `textlog` VALUES ('32','Отправка сообщения разрешена','send','Отправка сообщения разрешена');
INSERT INTO `textlog` VALUES ('33','Приём сообщения разрешён','accept','Приём сообщения разрешён');
INSERT INTO `textlog` VALUES ('34','Слишком много адресов получателей','deny','Слишком много адресов получателей');
INSERT INTO `textlog` VALUES ('35','Письмо содержит рекламу. (acl_mime)','deny','Письмо содержит рекламу');
INSERT INTO `textlog` VALUES ('36','Обнаружен вирус (drweb)','deny','В письме обнаружен вирус');
UNLOCK TABLES;
exim.conf

Код: Выделить всё

# Как подключаться к серверу MYSQL (сокет, база, логин, пароль)
hide mysql_servers      = (/tmp/mysql.sock)/exim/eximuser/eximpassword

...
...
MYSQL_LOGBADVERIFY      = INSERT INTO `log`(`action`,src_ip,src_email,dst_email,helo,hostname,date,time) VALUES (10,'$sender_host_address',LCASE('$sender_address'),'$local_part@$domain','$sender_helo_name','$sender_host_name',CURDATE(),now())
MYSQL_LOGHELOEMPTY      = INSERT INTO `log`(`action`,src_ip,src_email,dst_email,helo,hostname,date,time) VALUES (11,'$sender_host_address',LCASE('$sender_address'),'$local_part@$domain','$sender_helo_name','$sender_host_name',CURDATE(),now())
MYSQL_LOGHELOIP         = INSERT INTO `log`(`action`,src_ip,src_email,dst_email,helo,hostname,date,time) VALUES (12,'$sender_host_address',LCASE('$sender_address'),'$local_part@$domain','$sender_helo_name','$sender_host_name',CURDATE(),now())
MYSQL_LOGHELONODOT      = INSERT INTO `log`(`action`,src_ip,src_email,dst_email,helo,hostname,date,time) VALUES (13,'$sender_host_address',LCASE('$sender_address'),'$local_part@$domain','$sender_helo_name','$sender_host_name',CURDATE(),now())
...
...

Код: Выделить всё

mail# cat 400.acl_rcpt_helo_deny.conf
# Прибиваем, если нет приветствия HELO/EHLO
  deny    message       = HELO/EHLO required by SMTP RFC
          !senders      = :
          condition     = ${if eq{$sender_helo_name}{}{yes}{no}}
          set acl_m19   = ${lookup mysql{MYSQL_LOGHELOEMPTY}}

# Прибиваем, если IP-Адрес в HELO (Может быть наш или клиента, что не есть гуд)
  deny    message       = IP in HELO/EHLO - access denied.
          !senders      = :
          condition     = ${if isip4{$sender_helo_name}{yes}{no}}
          set acl_m19   = ${lookup mysql{MYSQL_LOGHELOIP}}

# Прибиваем, если в HELO только цифры
  deny    message       = Numbers cannot be in HELO/EHLO - access denied.
          !senders      = :
          condition     = ${if match{$sender_helo_name}{\N^\d+$\N}{yes}{no}}
          set acl_m19   = ${lookup mysql{MYSQL_LOGHELONUMBERS}}

# Прибиваем, если в HELO моё имя хоста или localhost
  deny    message       = Incorrect HELO/EHLO - access denied.
          !senders      = :
          condition     = ${if match{$sender_helo_name}{localhost|mydomain1.ru|mydomain2.ru}{yes}{no}}
          set acl_m19   = ${lookup mysql{MYSQL_LOGHELOLOCALHOST}}

# Прибиваем, если в HELO нет . (точек)
  deny    message       = You need dot in HELO/EHLO - access denied.
          !senders      = :
          condition     = ${if !match{$sender_helo_name}{\N\w\.\w\N}{yes}{no}}
          set acl_m19   = ${lookup mysql{MYSQL_LOGHELONODOT}}

# Прибиваем, если HELO совпадает с нашими шаблонами блокировок
  deny    message       = Your are blocked in HELO/EHLO - access denied.
          !senders      = :
          condition     = ${if match{$sender_helo_name}{.orange.|.wanadoo.|dynamic|.vhonest.}{yes}{no}}
          set acl_m19   = ${lookup mysql{MYSQL_LOGHELOMYBLOCK}}

# Прибавляем 30 секунд, если HELO не совпадает с обратной записью DNS
  warn    condition     = ${if !eq{$sender_helo_name}{$sender_host_name}{yes}{no}}
          set acl_m17   = ${eval:$acl_m17+30}

# Прибавляем 30 секунд, если нет обратной записи
  warn    condition     = ${if eq{$host_lookup_failed}{1}{yes}{no}}
          set acl_m17   = ${eval:$acl_m17+30}

Код: Выделить всё

mail# cat mysc.sh
#!/bin/sh

mystartdate="2008-11-01"
myenddate="2008-11-31"

noreceive="SELECT log.src_ip,COUNT(*) FROM log JOIN textlog ON log.action = textlog.id WHERE ( \`date\` BETWEEN '$mystartdate' AND '$myenddate') AND log.size IS NULL GROUP BY log.src_ip HAVING count(*) > 150;"

password="passwordmysql"

# Отчёт по IP-Адресам, с количеством непринятых сообщений больше 150
echo
echo "Отчёт по IP-Адресам, с количеством непринятых сообщений больше 150"
echo "$noreceive" | mysql -t -u root -p$password exim
Я вот так спам от конкретных провайдеров смотрю.

Код: Выделить всё

mail# cat spam.sh
#!/bin/sh

password="passwordmysql"

# Спам от провайдера NIS
echo "use exim; SELECT log.size,log.src_ip,log.time,log.hostname,log.helo,log.src_email,log.dst_email,textlog.text FROM log JOIN textlog ON log.action = textlog.id WHERE (src_ip BETWEEN '212.67.0.0' AND '212.67.31.255') AND (size IS NULL) ORDER BY log.time;" | \
mysql -u root -p$password > spamnis

# Спам от провайдера Sandy
echo "use exim; SELECT log.size,log.src_ip,log.time,log.hostname,log.helo,log.src_email,log.dst_email,textlog.text FROM log JOIN textlog ON log.action = textlog.id WHERE (src_ip BETWEEN '195.122.224.0' AND '195.122.255.255' OR src_ip BETWEEN '194.190.176.0' AND '194.190.191.255' OR src_ip BETWEEN '193.125.70.0' AND '193.125.71.255' ) AND (size IS NULL) ORDER BY log.time;" | \
mysql -u root -p$password > spamsandy

# Спам от провайдера KIS
echo "use exim; SELECT log.size,log.src_ip,log.time,log.hostname,log.helo,log.src_email,log.dst_email,textlog.text FROM log JOIN textlog ON log.action = textlog.id WHERE (log.src_ip BETWEEN '195.98.32.0' AND '195.98.63.255' OR src_ip BETWEEN '212.92.128.0' AND '212.92.191.255' OR src_ip BETWEEN '217.118.93.0' AND '217.118.93.255' OR src_ip BETWEEN '89.189.0.0' AND '89.189.31.255') AND (log.size IS NULL) ORDER BY log.time;" | \
mysql -u root -p$password > spamkis
Лучше установить FreeBSD, чем потратить 30 лет на Linux'ы и выяснить какой из них хуже.