View previous topic :: View next topic |
Author |
Message |
makoomba Bodhisattva
Joined: 03 Jun 2004 Posts: 1856
|
Posted: Fri Nov 04, 2005 5:09 pm Post subject: [TIP] Postfix tricks, Antispam on demand |
|
|
Innanzitutto una premessa: questo non è un howto.
Raccolgo in questo post una serie di tips, più o meno noti, inerenti la configurazione di un server mail basato su postfix.
Il setup utilizzato:
- Postfix e domini virtuali su database Mysql
- Maildrop per il delivery
- Dspam per l'antispam
- Courier per IMAP e POP3
Alcune soluzioni proposte sono prelevate dalle numerose guide presenti sulla rete, altre sono frutto di mie personali sperimentazioni per le quali vale il seguente disclaimer:
Quote: | a me funzionano, se il tuo sistema implodesse e/o i tuoi utenti dovessero rincorrerti forconi alla mano gridando "al rogo! al rogo!", non mi ritengo responsabile. |
Requisito fondamentale è che il lettore abbia una certa familiarità con postfix nel tipico setup domini virtuali + mysql. Ci sono già ottimi howto sull'argomento, per cui darò per scontato che si disponga di un sistema correttamente configurato.
Questo è il punto di non ritorno, se ritieni che quanto hai letto finora sia sufficiente per mandarmi a cagare, è arrivato il momento di passare a letture più interessanti.
Ci sei ancora ? ok, allora andiamo a cominciare.
nota:
nella definizione della mappe, saranno omessi i campi relativi a db, user, password, etc
Gli alias catch-all
Un alias catch-all ha la forma
Code: | @dominio nome@dominio |
il suo fine è quello di veicolare all'indirizzo nome@dominio tutte le email spedite a qualsiasicosa@dominio
Sebbene il suo utilizzo possa trasformare l'account catch-all in un ricettacolo di spam, alcuni clienti lo richiedono e tanto basta.
Veniamo al problema: che succede se ho altri account tipo acc1@dominio, acc2@dominio ?
Gli account in questione non riceveranno mai posta perchè, causa catch-all, saranno considerati alias di nome@dominio
Il problema si risolve inserendo un alias per ogni malibox
Code: | acc@dominio acc@dominio |
nella tabella contenente gli alias.
Come si può ottimizzare la cosa ?
Si crea una nuova mappa mysql_virtual_email2email.cf
Code: | table = mailbox
select_field = username
where_field = username
// mailbox: tabella che contiene le mailbox
// username: campo che contiene l'indirizzo
|
e la si aggiunge alle virtual_alias_maps.
La mappa trasforma ogni mailbox nell'alias di se stesso, problema risolto.
Allegati pericolosi
Gran parte dei virus/worm si diffonde grazie ad allegati che, eseguiti più o meno con il consenso dell'utente (ogni riferimento ad outlook è puramente intenzionale), provvedono ad infettare il sistema.
Come proteggere l'utente dall'allegato killer ?
Prima ancora dell'antivirus, è possibile configurare postfix per rifiutare le email contenenti allegati "eseguibili".
header_checks è tuo amico, nel main.cf
Code: | header_checks = regexp:/etc/postfix/mime_header_checks |
/etc/postfix/mime_header_checks
Code: | /^\s*Content-(Disposition|Type).*name\s*=\s*"?(.+\.(ad[ep]|asd|ba[st]|
c[ho]m|cmd|cpl|crt|dbx|dll|exe|hlp|hta|in[fs]|isp|js|jse|lnk|md[etw]|ms[cipt]|
nws|ocx|ops|pcd|pi|pif|prf|reg|scf|scr|sct|sh[bms]|swf|uue|vb|vb[esx]|vxd|wab|ws[cfh]))"?\s*$/
REJECT I files allegati alle email che contengono (o terminano) in "$3" sono rifiutati da questo
server perchè potrebbero contenere virus. Il file "$2" è stato rifiutato.
Per risolvere il problema basta includere tali files in un archivio zip. |
nota: ho spezzato il codice in più linee per motivi di leggibilità, ma va tutto in una linea.
Antispam on demand
Quasi tutte le soluzioni proposte negli howto, prevedono lo schema
Code: | Mail server esterno -> content filter -> Mail server interno (127.0.0.1) |
Alcuni setup utilizzano anche 3 istanze di postfix (smtpd) in esecuzione sulla stessa macchina, ma a me, sto fatto delle istanze multiple, non è mai piaciuto.
In più, ho la necessità di abilitare i controlli antispam solo per quei clienti che pag... che richiedono il servizio.
Nell'esempio che andrò a proporre ho utilizzato dspam, ma modificarlo per SA non dovrebbe essere difficile.
Prerequisito fondamentale è che si utilizzi maildrop per il virtual delivery, cioè che nel main.cf si abbia
Code: | virtual_transport = maildrop |
Per prima cosa, nella tabella che contiene i domini, si aggiunge un altro campo
Code: | option tinyint(3) unsigned |
e si setta option=3 per tutti i domini che necessitano di controlli antispam.
successivamente, si crea una nuova mappa mysql_virtual_antispam_maps.cf
Code: | table = domain
select_field = 'maildrop:spamcheck'
where_field = domain
additional_conditions = and domain.option = 3 |
e la si aggiunge alle transport_maps, mentre nel master.cf si definisce
Code: | maildrop unix - n n - 10 pipe
flags=DRhu user=vmail argv=/usr/bin/maildrop -d ${recipient} $nexthop |
come funziona l'accrocchio ?
quando viene processato un messaggio, postfix controlla se nelle trasport map sia definito un particolare trasporto per quel recipient o dominio.
Nel caso in cui, per il dominio in esame, si abbia option=3, la mappa appena creata restituisce il valore maildrop(trasporto):spamcheck(nexthop)
Nel master.cf abbiamo configurato maildrop per ricevere come parametro l'argomeno $nexthop
Modificando /etc/maildroprc, aggiungiamo il controllo
Code: | SPAMCHECK=(("$1" eq "spamcheck") && ($SIZE < 250000))
if ($SPAMCHECK)
{
xfilter "/usr/bin/dspamc --user $LOGNAME --mode=toe --stdout --feature=chained,noise --deliver=innocent,spam"
# Se è spam, ciao.
if (/^X-DSPAM-Result: Spam.*$/)
{
to "$HOME/$DEFAULT.Spam/"
}
}
|
Se maildrop è eseguito con il parametro "spamcheck" (e il messaggio è sotto i 250kb) viene invocato il controllo antispam.
Semplice no ? la vostra soddisfazione è il nostro miglior premio .... piripiripì! snack! snack! hihooo hihooo *
* chi capisce questa, possiede una solida cultura in fatto di B-Movies all'italiana (gugle non vale, cheater)
Bene, volevo aggiungere altre cosucce ma il post sta diventando troppo lungo, per cui mi fermo e ringrazio quei due o tre utenti (me compreso) che hanno avuto la pazienza di leggersi tutta la sbobba.
Sperando che quanto scritto possa essere d'aiuto a qualcuno, vi saluto e vado a cercare un'altra scusa per non lavorare.
Last edited by makoomba on Fri Nov 04, 2005 5:41 pm; edited 1 time in total |
|
Back to top |
|
|
xchris Advocate
Joined: 10 Jul 2003 Posts: 2824
|
Posted: Fri Nov 04, 2005 5:23 pm Post subject: |
|
|
interessante...
peccato che non usi questo tipo di setup.
(soprattutto l'antispam on demand)
ti consiglio di specificare un po' meglio il tipo di setup adottato all'inizio del post.
tempo fa ho provato dspam con postfix ma non mi era parso molto stabile.
(capitava di vedere la cpu al 99% con dspam inchiodato)
ora come va?
complimenti cmq per un post di TIPS inusuali
ciao _________________ while True:Gentoo() |
|
Back to top |
|
|
makoomba Bodhisattva
Joined: 03 Jun 2004 Posts: 1856
|
Posted: Fri Nov 04, 2005 5:35 pm Post subject: |
|
|
xchris wrote: | ti consiglio di specificare un po' meglio il tipo di setup adottato all'inizio del post. |
ok, ora edito
xchris wrote: | tempo fa ho provato dspam con postfix ma non mi era parso molto stabile. |
considera che sono passato a dspam perchè SA stava uccidendo un dual xeon.
va configurato attentamente, soprattutto la fase di training.
il load è sceso ad 1/4 e falcia lo spam con un'accuratezza micidiale.
xchris wrote: | complimenti cmq per un post di TIPS inusuali |
ci ho messo un pò a scriverlo, fa piacere constatare che qualcuno lo ha letto |
|
Back to top |
|
|
FonderiaDigitale Veteran
Joined: 06 Nov 2003 Posts: 1710 Location: Rome, Italy
|
Posted: Thu Dec 08, 2005 3:31 pm Post subject: |
|
|
L'ho letto anche io, in effetti e' raro vedere setup di postfix + dspam in giro.
Mi interesserebbe vedere come hai configurato e allenato dspam, l'output di dspam_stats, et al.
sopratutto per fare un confronto col mio.
ciao e grazie _________________ Come disse un amico, i sistemisti sono un po' come gli artigiani per l'informatica
|
|
Back to top |
|
|
makoomba Bodhisattva
Joined: 03 Jun 2004 Posts: 1856
|
Posted: Thu Dec 08, 2005 4:12 pm Post subject: |
|
|
TOE per tutti gli utenti.
ho fatto il train di un gruppo globale con qualche migliaio di messaggi già suddivisi in SPAM/HAM.
poi più passaggi con gli stessi msg + altri segnalando a dspam falsi positivi e missed spam.
ogni utente è in merged group con il gruppo globale ma resta indipendente per il training successivo.
per le stats, ti posso postare quelle del mio server che ha un traffico molto più moderato rispetto al dual xeon citato nel tip.
Code: | global TS: 4518 TI: 6471 SM: 318 IM: 0 SC: 3137 IC: 959
utente@dominio TS: 246 TI: 1622 SM: 7 IM: 5 SC: 0 IC: 0
|
appena l'assistenza restituisce il big server al cliente, ho intenzione di aggiornare dspam alla nuova versione e migrare da mysql a CSS.
per quanto riguarda il setup, buona parte è già riportata nel tip.
nel master.cf ho
Code: | dspam-retrain unix - n n - 10 pipe
flags=Ru user=vmail argv=/usr/bin/dspam-multiple.pl $nexthop $sender |
dspam-multiple.pl permette di inviare più msg come allegati e si occupa di richiamare dspam per il retrain.
in una transport maps è definito
Code: | spam@dominio dspam-retrain:spam
nospam@dominio dspam-retrain:innocent |
spam@dominio e nospam@dominio vengono utilizzate dagli utenti per segnalare rispettivamente missed spam e falsi positivi.
questo è quello che ricordo più o meno a memoria, se ti interessano alcuni dettagli in particolare, fammi sapere. _________________ When all else fails, read the instructions. |
|
Back to top |
|
|
FonderiaDigitale Veteran
Joined: 06 Nov 2003 Posts: 1710 Location: Rome, Italy
|
Posted: Thu Dec 08, 2005 10:55 pm Post subject: |
|
|
ok, grazie.
due domande:
a. da che versione a che versione migri?
b. che intendi con la sigla 'CSS'? _________________ Come disse un amico, i sistemisti sono un po' come gli artigiani per l'informatica
|
|
Back to top |
|
|
makoomba Bodhisattva
Joined: 03 Jun 2004 Posts: 1856
|
Posted: Fri Dec 09, 2005 11:39 am Post subject: |
|
|
3.4.9 -> 3.6.x
CSS = CRM Sparse Spectra algorithm
Quote: | In general, MySQL is one of the faster solutions with a smaller storage
footprint, and is well suited for both small and large-scale implementations.
The hash driver (inspired by Bill Yerazunis' CRM Sparse Spectra algorithm)
is the fastest solution by far and requires no dependencies, supports
an auto-extend feature to grow the file size as needed, and is very
fast and compact. It does, however, lack some features (such as merged
groups support) and uses a lot of memory to mmap() users. |
_________________ When all else fails, read the instructions. |
|
Back to top |
|
|
makoomba Bodhisattva
Joined: 03 Jun 2004 Posts: 1856
|
Posted: Fri Dec 09, 2005 12:01 pm Post subject: |
|
|
visto che ci sono, aggiungo alcuni script che ho creato gestire il sistema.
magari possono servire a qualcuno
dspam-multiple.pl gestisce il retrain
Code: | #! /usr/bin/perl -w
use strict;
my $class = $ARGV[0] || die; shift;
my $sender = $ARGV[0] || die; shift;
my $user = "";
my $subj = "";
my $from = "";
if ($sender =~ /^([\w|\@|\.|\-]+)$/) {
# username is in the sender
$user = $1;
} else {
print "Can't determine user\n";
exit 75; # EX_TEMPFAIL
}
# Pull out DSPAM signatures and send them to the dspam program
while (<>) {
if (/^Subject: /) {
$subj = $_;
} elsif (/^From: /) {
$from = $_;
} elsif ((/(!DSPAM:[a-f0-9]+!)/) || (/(X-DSPAM-Signature: [a-f0-9]+)/)) {
open(F, "|/usr/bin/dspamc --source=error --class=$class --user $user");
#open(F,">>/tmp/fabio.log");
#print F "user: $user\n";
print F "$from$subj$1";
close(F);
$subj = "";
$from = "";
}
} |
spamreport.pl crea un report in html dello spam e lo invia al cliente.
molti utenti usano esclusivamente pop3, in questo modo non sono costretti ad utilizzare il webmail per visionare lo spam.
Code: | #!/usr/bin/perl -w
use strict;
my $mailroot = "/data/mail";
my $mail = 'AntiSpam@Azienda.it';
my $head = <<HERE;
<p>
Report Servizio AntiSpam<br>
<br>
I seguenti messaggi sono stati identificati come spam e saranno eliminati entro i prossimi 7 giorni<br><br>
</p>
HERE
my $foot = <<HERE;
<p>
Utilizzando l'interfaccia <b><a href="http://webmail.Azienda.it">WebMail</a></b> potrai visualizzare i messaggi sopra riportati.
<br><br>
Servizio AntiSpam Azienda snc.<br>
Tel 434234334234<br>
email $mail<br>
</p>
HERE
my @maildirs;
if ($ARGV[0]) {
my $u;
my $d;
($u,$d)=split(/\@/,$ARGV[0]);
push @maildirs,"$mailroot/$d/$u";
} else {
# becco tutte le maildir che contengono spam recente
@maildirs = `find $mailroot/*/*/.Spam/{new,cur} -type f -mtime -1 | cut -d'/' -f1,2,3,4,5 | sort | uniq`;
}
my $date=`date -R`;
chomp($date);
foreach my $maildir (@maildirs) {
chomp($maildir);
my $user = "";
if ($maildir =~ /([^\/]+)\/([^\/]+)$/) { $user = "$2\@$1"}
# per ogni maildir, becco le prime 100 righe di ogni messaggio spam
open (SPAM,"find $maildir/.Spam/{cur,new} -type f -mtime -1 | sort -r | xargs -n 100 head -q -n 150 | grep -P '^From:|^Subject:|^X-DSPAM-Confidence:'|");
my @from;
my @subject;
my @prob;
my $count = 0;
my $msg = "";
while(<SPAM>) {
if (/^From:\s*(.+)/i) {
my $f = $1;
$f =~ s/</</i;
$f =~ s/>/>/i;
push @from,$f;
$count++;
} elsif (/^X-DSPAM-Confidence: 0\.(\d\d)/i) {
push @prob,$1;
} elsif (($count>0) && /^Subject:\s*(.+)/i) {
my $s = $1;
$s =~ s/</</i;
$s =~ s/>/>/i;
$subject[$count-1] = $s;
}
}
if ($count > 0) {
$msg = <<HERE;
Return-Path: <$mail>
From: "Servizio Antispam" <$mail>
To: $user
Subject: Report Spam su $user
Date: $date
MIME-Version: 1.0
Content-Type: text/html ; charset="ISO-8859-15"
Content-Transfer-Encoding: flowed
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
<HTML>
<HEAD>
<TITLE>Spam Report</TITLE>
<style>
body { font-family: Verdana; font-size: 11px; }
td { font-size: 11px; }
table.report tr.head { font-weight:bold; background-color: #00066F; color: white; }
table.report { background-color: #EAEAEA; }
table.report tr.gray { background-color: #CACACA; }
</style>
</HEAD>
<BODY>
$head
<table cellpadding=2 cellspacing=1 class="report">
<tr class="head"><td>n</td><td>Prob</td><td>Oggetto</td><td>Mittente</td></tr>
HERE
for (my $i=0; $i < $count; $i++) {
$subject[$i] = ($subject[$i] ? $subject[$i] : "-");
$msg .= ($i % 2) ? "<tr class=\"gray\">" : "<tr>";
$msg .= "<td>".($i+1)."</td><td>".$prob[$i]."%</td><td><b>".$subject[$i]."</b></td><td>".$from[$i]."</td></tr>\n";
}
$msg .= <<HERE;
</table>
$foot
</BODY>
</HTML>
HERE
open (MAIL,"|deliverquota $maildir");
print MAIL $msg;
close MAIL;
printf "%-30s %3d\n",$user,$count
}
close (SPAM);
undef @from;
undef @subject;
} |
clean.sh si occupa di ripulire le caselle di posta.
Code: | #!/bin/sh
mailroot=/data/mail
oldINBOX=30
oldSpam=7
oldTrash=3
oldSent=14
oldDrafts=14
cmd="rm -f &>/dev/null"
maxargs=500
name=`basename $0`
# Bail if already running (in case we are slammed with spam to train from):
processes=$(ps ax)
if [ `echo "${processes}" | grep $name | grep -v nano | wc -l` -gt 1 ]; then
echo "ERROR: $name is already running!"
exit 1
fi
function cleanOld() {
folder=$1
olderthen=$2
find $mailroot -type f -mtime +$olderthen -ipath "$mailroot/*/.$folder/*/*" | xargs -n $maxargs $cmd
}
function cleanUnusedINBOX() {
olderthen=$1
find $mailroot -type f -mtime +$olderthen -mindepth 4 -ipath "$mailroot/*/*/*" -name '*.mail,*' | xargs -n $maxargs $cmd
}
cleanOld Spam $oldSpam
cleanOld Trash $oldTrash
cleanOld Sent $oldSent
cleanOld Drafts $oldDrafts
cleanUnusedINBOX $oldINBOX |
updateMailboxes.sh sincronizza le maildir con il db mysql: crea le maildir per i nuovi utenti, cancella quelle degli utenti rimossi dal db.
Code: | #!/bin/sh
mailroot=/data/mail
dbhost="localhost"
dbname="mail"
dbuser="vmailuser"
dbpass="s30w:r4;x.a10f"
dbtable="mailbox"
uid="vmail"
gid=$uid
function existing() {
find $mailroot -type d -mindepth 2 -maxdepth 2 | sed -e "s|$mailroot/||" | sort
}
function getFromDB() {
mailbox="CONCAT(RIGHT(username, LENGTH(username) - LOCATE('@', username)), '/', LEFT(username, LOCATE('@', username)-1))"
mysql -u "$dbuser" --password="$dbpass" -h $dbhost $dbname --skip-column-names -se "SELECT $mailbox FROM $dbtable " | sort
}
function findDiffs() {
extFile=`tempfile 2>/dev/null`
existing > $extFile
dbFile=`tempfile 2>/dev/null`
getFromDB > $dbFile
diff $extFile $dbFile | grep -P '^<|^>' | sed -e 's|<\s\+|D:|' | sed -e 's|>\s\+|C:|'
rm -f $extFile $dbFile
}
function makeMailDir() {
local MKMDIR="/usr/bin/maildirmake"
MAILDIR=$mailroot/$1
#QUOTA=$2
/bin/mkdir -p $MAILDIR
/bin/rmdir $MAILDIR
$MKMDIR $MAILDIR
#$MKMDIR -q $QUOTA $MAILDIR
$MKMDIR -f Drafts $MAILDIR
$MKMDIR -f Sent $MAILDIR
$MKMDIR -f Spam $MAILDIR
$MKMDIR -f Trash $MAILDIR
echo -e "INBOX.Drafts\nINBOX.Sent\nINBOX.Trash\nINBOX.Spam" > ${MAILDIR}/courierimapsubscribed
chown -R $uid:$gid $MAILDIR
}
function update() {
for line in `findDiffs`
do
action=${line:0:1}
mbox=${line:2}
if [ "$action" = "C" ]
then
echo "Create: $mbox"
makeMailDir $mbox
else
echo "Delete: $mbox"
rm -rf $mailroot/$mbox
fi
done
}
update |
_________________ When all else fails, read the instructions. |
|
Back to top |
|
|
FonderiaDigitale Veteran
Joined: 06 Nov 2003 Posts: 1710 Location: Rome, Italy
|
Posted: Mon Dec 12, 2005 1:32 pm Post subject: |
|
|
molto utile, grazie.
Riguardo CSS, mi inquieta un po' l'idea di usare un file come database.. quantomeno per un discorso di stabilita' operativa.
che filesystem usi?
hai casistiche di utilizzo di questo CSS in produzione? _________________ Come disse un amico, i sistemisti sono un po' come gli artigiani per l'informatica
|
|
Back to top |
|
|
makoomba Bodhisattva
Joined: 03 Jun 2004 Posts: 1856
|
Posted: Mon Dec 12, 2005 2:55 pm Post subject: |
|
|
FonderiaDigitale wrote: | Riguardo CSS, mi inquieta un po' l'idea di usare un file come database.. quantomeno per un discorso di stabilita' operativa.
che filesystem usi?
hai casistiche di utilizzo di questo CSS in produzione? |
considera che è un formato di storage concepito appositamente per operare con in token e non necessita di server esterni.
ancora non l'ho provato ma, dai commenti sulle mailing lists, pare sia estremamente veloce. _________________ When all else fails, read the instructions. |
|
Back to top |
|
|
|
|
You cannot post new topics in this forum You cannot reply to topics in this forum You cannot edit your posts in this forum You cannot delete your posts in this forum You cannot vote in polls in this forum
|
|