Configuração do ambiente
Antes de prosseguirmos, certifique-se que o seu
Policyd está devidamente configurado e o seu
Postfix está em funcionamento.
Caso esteja, edite seu
policyd.conf e defina como ativo a utilização do recurso de SpamTrap, como mostrado no trecho abaixo:
######################################################
# SPAMTRAP (functional) #
######################################################
#
# enable spamtrap default: off
#
# the idea of this module is to allow you to capture
# hosts that mail to your spamtraps without having to
# resort to parsing the mails to identify senders. you
# now have the ability to blacklist the host/netblock
# for a period of time (definable in SPAMTRAP_AUTO_EXPIRE).
#
# 1=on 0=off
SPAMTRAPPING=1#
# spamtrap rejection: default: "Abuse. Go Away."
#
# what error message the connecting host will recieve
# when a message is directly sent to your spamtraps
#
SPAMTRAP_REJECTION="Abuse. Go away."#
# spamtrap auto expire: default: 7 days
#
# this allows you to specify for what period of time any
# host will be blacklisted for when it has been caught
# mailing to your spamtrap addresses. (a setting of 0
# sets a permanent blacklist)
#
SPAMTRAP_AUTO_EXPIRE=1d
O objetivo
O script abaixo procura na tabela triplet - que registra ações da greylist - e tenta rankear e-mails "inexistentes" comumente mais alvejados por SPAM de brute-force. Ou seja, na tabela triplet fica registrado a intenção de envio de um e-mail com os campos FROM e TO (Remente/Destinatário) capturados. A partir disso é possível saber se o e-mail foi entregue ou não ao destinatário - o que torna possível o processo de ranking.
Dessa forma, quando um MTA passa pela greylist e entrega um e-mail, essa entrega fica registrada na tabela em questão.
Como o script funciona?
Levando em consideração que a maioria das tentativas de SPAM nunca ou quase nunca passam pela greylist, utilizando o script que segue abaixo você poderá fazer o ranking dos e-mails que mais são alvo de SPAM, como dito anteriormente. Com o ranking feito, uma nova consulta é gerada para remover os e-mails reais, ou seja, que existem realmente no seu servidor de correio. Dessa forma a lista será o equivalente a:
"Alvos de SPAM" - "E-mails e Aliases reais" = "Lista da SpamTrap"
Pra que isso serve?
Se seu servidor de correio é alvo de abusos de SPAM baseado em brute force/alvos aleatórios, existe uma grande chance de um spammer (principalmente zombies que comutam wordlists) cair num e-mail registrado na SpamTrap e ir para sua blacklist. Dessa forma, estando na sua lista negra, as posteriores requisições do spammer serão automaticamente descartadas do seu MTA, economizando link e processamento do seu servidor.
Segue abaixo o script PHP, note que suas configurações do Postfix pode utilizar tabelas distintas, por isso fique a vontade para modificar o script:
#!/usr/bin/php
<?php
/**
Software License Agreement (BSD License)Copyright (c) 2006, Yahoo! Inc.All rights reserved.Redistribution and use of this software in source and binary forms, with or without modification, arepermitted provided that the following conditions are met:* Redistributions of source code must retain the abovecopyright notice, this list of conditions and the
following disclaimer.
* Redistributions in binary form must reproduce the above
copyright notice, this list of conditions and thefollowing disclaimer in the documentation and/or other
materials provided with the distribution.
* Neither the name of Yahoo! Inc. nor the names of itscontributors may be used to endorse or promote products
derived from this software without specific priorwritten permission of Yahoo! Inc.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED
WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR APARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOTLIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, ORTORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
/**
* Autor: Allyson de Paula
* e-mail: ragen ponto dazs arroba gmail ponto com
*/
/*
* CONFIGURATION
*/// MIN TRIPLETS REQUIRED TO ANALIZE IF ADDRESS WILL BE AN SPAMTRAP
define("MIN_TRIPLET", 25); // UNTRIPLET EMAILS TOLERANCE IN PERCENTE
define("UNTRIPLET_TOLERANCE", 80); // DATABASE CONF
define("MYSQL_HOST", 'localhost');
define("MYSQL_USER", 'postfix');
define("MYSQL_PASS", 'password');
define("MYSQL_DBNAME", 'policyd');// USE FOR DEBUG
define("VERBOSE_MODE", 1);/**
* DO NOT MODIFY BELLOW IF YOU DON'T KNOW WHAT YOU ARE DOING
*/$link = mysql_connect(MYSQL_HOST, MYSQL_USER, MYSQL_PASS);
if (!$link) {
die('Not connected : ' . mysql_error());
}$db_selected = mysql_select_db(MYSQL_DBNAME, $link);
if (!$db_selected) {
die ('Can\'t use '.MYSQL_DBNAME.' : ' . mysql_error());
}$query = "
select username as email from postfix.mailbox
UNION
select address as email from postfix.alias
";$stmt = mysql_query($query) or die (mysql_error());
while ($row = mysql_fetch_assoc($stmt)) {
$email[$row['email']] = 1;
}
$query = "
select
_rcpt,
count(*) as total,
sum(_count) as passed
from
triplet
group by
_rcpt
order by
3 asc,2 desc
";
$stmt = mysql_query($query) or die (mysql_error());
if (mysql_num_rows($stmt)) {
#passthru('/etc/init.d/rc.firewall restart');
mysql_query('truncate table spamtrap');
for($i = 1; $row = mysql_fetch_assoc($stmt); $i++) {
if ((($row['passed']*100)/$row['total'] <= (100 - UNTRIPLET_TOLERANCE)) && ($row['total'] >= MIN_TRIPLET)) {
if ($email[$row['_rcpt']]) {
if (VERBOSE_MODE) {
$out[] = "[Policyd] ABORTING AUTO TRAPING: {$row['_rcpt']} - SPAM TARGET, BUT EMAILS EXISTS #".(count($out)+1)."\n";
}
} else {
if (VERBOSE_MODE) {
echo "[Policyd] AUTO TRAPING: {$row['_rcpt']} - SPAM TARGET #$i WHIT ".round(($row['passed']*100)/$row['total'],2)."% OF SUCCESS TRIPLET RATE \n";
}
mysql_query("insert into spamtrap(_rcpt,_active) values('".mysql_escape_string($row['_rcpt'])."', 1)");
if (mysql_error()) {
echo "Error inserting last entry: ".mysql_error()."\n";
}
}
}
}
if (VERBOSE_MODE) {
if (count($out)) {
echo "========== WARNING =============\n";
for ($i = 0; $i < count($out); $i++) {
echo $out[$i];
}
}
}
}
?>
Testando
Após ter salvo o arquivo, digite na shell:
$ chmod +x spamtrap.php
$ ./spamtrap