Tutoriel N° 282
Gestion des Bounces - Mailer-Daemon avec postfix sur release 3 OVH
Nous allons traiter dans ce tutoriel l'installation d'un filtre pour gérer les mails retours MAILER-DAEMON via une base MYSQL.
# Création d'une table MYSQL qui recevra les mails des expéditeurs MAILER-DAEMON
# Mise en place d'un filtre POSTFIX pour filtrer les mails sans expéditeur valable.
# Script PHP qui gère les BOUNCES
# Mise en place et éxécution sur POSTFIX
# Création d'une table MYSQL qui recevra les mails des expéditeurs MAILER-DAEMON
Exécuter ce script dans une base de votre PHPMyAdmin
# Création d'une table npai
CREATE TABLE IF NOT EXISTS `npai` (
`id_stats` int(11) NOT NULL AUTO_INCREMENT,
`ip` text,
`referer` text,
`date` date DEFAULT NULL,
`base` varchar(4000) DEFAULT NULL,
PRIMARY KEY (`id_stats`)
) ENGINE=MyISAM DEFAULT CHARSET=latin1 AUTO_INCREMENT=24 ;
CREATE TABLE IF NOT EXISTS `npai` (
`id_stats` int(11) NOT NULL AUTO_INCREMENT,
`ip` text,
`referer` text,
`date` date DEFAULT NULL,
`base` varchar(4000) DEFAULT NULL,
PRIMARY KEY (`id_stats`)
) ENGINE=MyISAM DEFAULT CHARSET=latin1 AUTO_INCREMENT=24 ;
# Mise en place d'un filtre POSTFIX pour filtrer les mails sans expéditeur valable.
Commencer par créer une boîte mail qui recevra l'ensemble des mails retour noreply@domaine.com par exemple via https://vpsxxxxxx.ovh.net/postfixadmin/login.php
On ajoute le filtre postfix pour le domaine de la boîte mail expéditrice.
On remplace domain par le nom de répertoire de votre domaine dans /home
nano /etc/postfix/master.cf
# on y ajoute
bounce-pipe-filtre1 unix - n n - - pipe flags=FDRhu user=domain argv=/usr/bin/php /home/domain/www/forwardm.php ${sender}
bounce-pipe-filtre1 unix - n n - - pipe flags=FDRhu user=domain argv=/usr/bin/php /home/domain/www/forwardm.php ${sender}
nano /etc/postfix/transport
on y ajoute
noreply@domaine.com bounce-pipe-filtre1:
noreply@domaine.com bounce-pipe-filtre1:
On exécute les commandes suivantes:
postmap /etc/postfix/transport
/etc/init.d/postfix reload
postmap /etc/postfix/transport
/etc/init.d/postfix reload
Le filtre est maintenant fonctionnel. A chaque réception d'un mail retour d'erreur une ligne sera ajouté dans la table mysql npai avec l'email retour.
# Script PHP qui gère les BOUNCES
On crée le script PHP forwardm.php appelé par le filtre POSTFIX
nano /home/domain/www/forwardm.php
<?
$base='BASE_MYSQL';
$login='LOGIN_MYSQL';
$pwd='MOT_DE_PASSE_MYSQL';
$host='localhost';
$db=mysql_connect($host, $login, $pwd);
if(!mysql_select_db($base,$db))
{
echo "erreur ".mysql_error()."<br>";
mysql_close($db);
exit;
}
//*** this function will write to log.log some error details ***
/*
function write_log($mesaj)
{
$handle = fopen("log.log","w");
fwrite($handle,date("Y-m-d h:i:s").": ".$mesaj."n");
fclose($handle);
}*/
//**********************************
/* read the mail that is forwarded to the script *** */
$fd = fopen("php://stdin", "r");
$email = "";
while (!feof($fd)) {
$email .= fread($fd, 1024);
}
fclose($fd);
//*** handle email ***
$lines = explode("n", $email);
// empty vars
$from = "";
$to = "";
$date = "";
$subject = "";
$Final = "";
$message = "";
$splittingheaders = true;
for ($i=0; $i<count($lines); $i++) {
if ($splittingheaders) {
// look out for special headers
if ( (preg_match("/^Subject: (.*)/", $lines[$i], $matches)) and ($subject=="") ){
$subject = $matches[1];
}
if ( (preg_match("/^Final-Recipient: (.*)/", $lines[$i], $matches)) and ($Final=="") ){
$Final = $matches[1];
}
$bounce=explode(" ",$Final);
if ( (preg_match("/^From: (.*)/", $lines[$i], $matches)) and ($from=="") ){
if(strpos($lines[$i],"<"))
{
//the name exist too in from header
$data = explode('<',$lines[$i]);
$from = substr(trim($data[1]),0,-1);
}
else{
//only the mail
$from = $matches[1];
}
}
if (preg_match("/^To: (.*)/", $lines[$i], $matches)) {
$to = $matches[1];
}
if (preg_match("/^Date: (.*)/", $lines[$i], $matches)) {
$date = $matches[1];
}
} else {
// not a header, but message
$message .= $lines[$i]."n";
}
if ($i==45) {
// empty line, header section has ended
$splittingheaders = false;
}
}
$date=date("Y-m-d");
$sql="INSERT INTO npai ( id_stats , ip , referer , date , base ) VALUES ('', '$to', '$from', '$date' , '$bounce[1]');";
mysql_query($sql);
mysql_close();
?>
$base='BASE_MYSQL';
$login='LOGIN_MYSQL';
$pwd='MOT_DE_PASSE_MYSQL';
$host='localhost';
$db=mysql_connect($host, $login, $pwd);
if(!mysql_select_db($base,$db))
{
echo "erreur ".mysql_error()."<br>";
mysql_close($db);
exit;
}
//*** this function will write to log.log some error details ***
/*
function write_log($mesaj)
{
$handle = fopen("log.log","w");
fwrite($handle,date("Y-m-d h:i:s").": ".$mesaj."n");
fclose($handle);
}*/
//**********************************
/* read the mail that is forwarded to the script *** */
$fd = fopen("php://stdin", "r");
$email = "";
while (!feof($fd)) {
$email .= fread($fd, 1024);
}
fclose($fd);
//*** handle email ***
$lines = explode("n", $email);
// empty vars
$from = "";
$to = "";
$date = "";
$subject = "";
$Final = "";
$message = "";
$splittingheaders = true;
for ($i=0; $i<count($lines); $i++) {
if ($splittingheaders) {
// look out for special headers
if ( (preg_match("/^Subject: (.*)/", $lines[$i], $matches)) and ($subject=="") ){
$subject = $matches[1];
}
if ( (preg_match("/^Final-Recipient: (.*)/", $lines[$i], $matches)) and ($Final=="") ){
$Final = $matches[1];
}
$bounce=explode(" ",$Final);
if ( (preg_match("/^From: (.*)/", $lines[$i], $matches)) and ($from=="") ){
if(strpos($lines[$i],"<"))
{
//the name exist too in from header
$data = explode('<',$lines[$i]);
$from = substr(trim($data[1]),0,-1);
}
else{
//only the mail
$from = $matches[1];
}
}
if (preg_match("/^To: (.*)/", $lines[$i], $matches)) {
$to = $matches[1];
}
if (preg_match("/^Date: (.*)/", $lines[$i], $matches)) {
$date = $matches[1];
}
} else {
// not a header, but message
$message .= $lines[$i]."n";
}
if ($i==45) {
// empty line, header section has ended
$splittingheaders = false;
}
}
$date=date("Y-m-d");
$sql="INSERT INTO npai ( id_stats , ip , referer , date , base ) VALUES ('', '$to', '$from', '$date' , '$bounce[1]');";
mysql_query($sql);
mysql_close();
?>
# Mise en place et éxécution sur POSTFIX
Pour supprimer ce filtre il suffit de mettre un # devant le filtre
nano /etc/postfix/master.cf
#bounce-pipe-filtre1 unix - n n - - pipe flags=FDRhu user=domain argv=/usr/bin/php /home/domain/www/forwardm.php ${sender}
nano /etc/postfix/transport
#noreply@domaine.com bounce-pipe-filtre1:
On exécute les commandes suivantes:
postmap /etc/postfix/transport
/etc/init.d/postfix reload
postmap /etc/postfix/transport
/etc/init.d/postfix reload