Автоматическое внесение адресов почты получателей в белый лист policyd на Postfix-е

И так, проблема стара как мир, мне очень часто звонят пользователи и администраторы других объектов с проблемой, что к ним почту отправили, но вот уже ждут не первый час и она все еще не дошла. В 99.9% случаев она не прошла GreyListing и наш сервер до сих пор ждет повторного запроса. Через какое-то время мне все это надоело, и я решил добавить несколько скриптов что бы добавлять в белый лист policyd на 3 месяца адреса на которые пишут мои пользователи. Скажу сразу, что проблема была решена, и теперь, проблемные звонки исчезли как страшный сон.

И так, первое что нам необходимо, это в /etc/policyd.conf добавить:

WHITELISTSENDER=1

Этой опцией мы включаем возможность вносить в белый лист электронные адреса.

Далее мы немного изменим /etc/postfix/master.cf . Добавим контент фильтр gsql

:smtp inet n — — — — smtpd
-o content_filter=gsql:dummy

И опишем сам контент фильтр, в том же файле master.cf

gsql unix — n n — — pipe
flags=Rq user=edd null_sender=
argv=/etc/postfix/polycid/main.sh -f ${sender} — ${recipient}

Тоесть, теперь весь трафик будет проходить через фильтр gsql, исполняемая часть которого будет находиться в /etc/postfix/polycid/ и называться он будет main.sh. Очень важно создать пользователя, от имени которого будет исполняться скрипт, в моем случаи это edd. Далее создаем каталог /etc/postfix/polycid/ и файл main.sh с таким содержанием:

#!/bin/bash
  #Policyd Content Filter for Postfix v1.03
  #1.02 Added BADMAIL
  #1.03 Multi outgoing emails
 
  SENDMAIL="/usr/sbin/sendmail"

#Директория в которой мы временно будем сохранять письма   
  WORK_DIR="/tmp/sqlg"
#Домены, адреса которых не надо добавлять в белый лист(регистро зависемо)
  DOMAIN1="eddnet.org"
  DOMAIN2="EDDNET.ORG"
#Адресса, письма от которых мы пропускаем и не будем добавлять их получателей в белый лист
  BADMAIL1="-bounces@eddnet.org"
  BADMAIL2="info@eddnet.org
 
TEMPFAIL=75
UNAVAILABLE=69

# Проверяем, если каталог /tmp/sqlg и даем там права пользователю edd
if [ ! -d $WORK_DIR ]; then
  mkdir $WORK_DIR
  chown edd $WORK_DIR
  chmod 777 $WORK_DIR
  fi


cd $WORK_DIR || { echo $WORK_DIR does not exist; exit $TEMPFAIL; }
trap "rm -f in.$$" 0 1 2 3 15
cat >in.$$ || { echo Cannot write to $WORK_DIR; exit $TEMPFAIL; }
  
SENDER=$2
# Значение X необходимо для подсчета адресатов, так как письма могут быть направлены множеству людей одновременно.
X=0

for ARG in $*
	do
	if [ "$X" -ge "3" ]
	then
		MAIL=$ARG
		while true; do
			case $SENDER in
			'')
				while true; do
					case $MAIL in
					'')
#Если все нормально, то передаем данные в php скрипт для добавления их в MySQL
					php "/etc/postfix/polycid/sql.php" $ARG $2
					break;;
						${DOMAIN1}*)
					break;;
						${DOMAIN2}*)
					break;;
 					esac
  					MAIL=${MAIL#?}
  				done
			break;;
 				${BADMAIL1}*)
 			break;;
 				${BADMAIL2}*)
 			break;;
			esac
		SENDER=${SENDER#?}
		done

	else
		X=$[$X+1]
	fi
done

$SENDMAIL "$@" <in.$$
  exit $?

Внимательно просмотрите весь скрипт и измените параметры на необходимые вам!

Теперь перейдем к файлу sql.php. Обязательно измените параметры для входа в MySQL базу

#!/usr/bin/php
  #Part of Policyd Content filter
  #Script adding mails to SQL table v1.01
  #1.01 Added loging
<?php
  // hostname or ip of server
$servername='localhost';
  // username and password to log onto db server
$dbusername='login';
  $dbpassword='password';
// name of database
  $dbname='policyd';
////////////// Соединяемся с базой/////////
 connecttodb($servername,$dbname,$dbusername,$dbpassword);
function connecttodb($servername,$dbname,$dbuser,$dbpassword)
  {
  global $link;
  $link=mysql_connect ("$servername","$dbuser","$dbpassword");
  if(!$link){die("Could not connect to MySQL");}
  mysql_select_db("$dbname",$link) or die ("could not open db".mysql_error());
  }
//Текущее время
$today = date("Y-m-d H:i:s");
//Время через 3 месяца
  $nextyear = date("Y-m-d H:i:s",strtotime("+3 months"));
  $unix_stamp = strtotime($nextyear);
//Проверяем если уже адрес в базе
$select = "SELECT _whitelist FROM whitelist_sender WHERE _whitelist = '{$argv[1]}'";
  $mail = mysql_query($select) or die ("Error updating: ".mysql_error());

if (mysql_num_rows($mail) == 0)
//Если адреса нет, то добавляем его
  {
  $query = "INSERT INTO whitelist_sender (_whitelist,_description,_expire) VALUES ('".$argv[1]."','\'".$argv[2]."\'','".$unix_stamp."')";
  mysql_query($query) or die ('Error updating');
  $entry = "$today: Our sender $argv[2] sended to $argv[1]\n\r";
  $fp = fopen("/var/log/policyd/policyd.log","a");
  fputs($fp,$entry);
  fclose($fp);
  }
//Если адрес уже есть, то обновляем его счетчик времени снова на три месяца
  else
  {
  $query = "UPDATE whitelist_sender SET _expire = '".$unix_stamp."' where _whitelist = '".$argv[1]."'";
  //    $query = "INSERT INTO whitelist_sender (_whitelist,_description,_expire) VALUES ('".$argv[1]."','\'".$argv[2]."\'','".$unix_stamp."')";
  mysql_query($query) or die ('Error updating');
  $query = "UPDATE whitelist_sender SET _count = _count + 1 where _whitelist = '".$argv[1]."'";
  mysql_query($query) or die ('Error updating');
  $entry = "$today: Our sender $argv[2] REsended to $argv[1]\n\r";
  $fp = fopen("/var/log/policyd/policyd.log","a");
  fputs($fp,$entry);
  fclose($fp);
  }
  mysql_close($link);
?>

Лог добавлений будет в /var/log/policyd/policyd.log

Данные скрипты могут быть легко адаптированы например к SQLGrey

Случайные Статьи

Loading…


Количество просмотров :3849

2 Comments

  1. Vasily:

    Спасибо за скрипт!
    Заработало, НО у писем отрезаются аттачи!!!
    что я мог не так сделать?

    по команде $SENDMAIL «$@» <in.$$
    файл in.$$ передается полностью с аттачами. (проверял копированием in.$$ в др. файл, перед передачей в сендмайл)

    да, в качестве почтовой системы стоит сборка IREDMAIL

  2. i-mak:

    Доброго времени суток!
    Благодарю за статью.
    Но есть вопросы. При подключении пользователй по IMAP+SMTP все работает, аттачи как в предыдущем посте не режутся (тоже установлен iRedMail v 0.8.3)
    Однако при подключении по SIMAP + SSMTP фильтр не отрабатывает.
    Пробовал вносить изенения в сервис smtps
    smtps inet n — — — — smtpd
    -o content_filter=gsql:dummy

    Результата не дало. Не подскажете, что еще нужно прописать в master.cf для работы автодополнения белых списков?

Оставьте коментарий