From: E-Star on
In general what is the best method to save a backup of all emails that
pass through my server.

I'm setting up Postfix with virtual domains and users into a directory
like:

/var/vmail/domain1/user1
/var/vmail/domain1/user2

/var/vmail/domain2/user3
/var/vmail/domain2/user4

I know that the always_bcc parameter exists. Do people generally just
dump all emails into a backup user?

Or do people at least separate emails per domain, or even per
domain/user? If someone wants to investigate an email I think it'd be
easiest to have postfix separate them in a similar fashion as the
virtual domain/user directories are done.

Also, at some point I would want to possible delete old emails. Do
people do this usually based on time? or on disk-usage? If emails are
bcc'd into a mailbox can a script be automated to remove old emails from
the backup?
From: ivakras1 on
On 7 ���, 11:03, unix_c...(a)linuxmail.org (E-Star) wrote:
> In general what is the best method to save a backup of all emails that
> pass through my server.
>
> I'm setting up Postfix with virtual domains and users into a directory
> like:
>
> /var/vmail/domain1/user1
> /var/vmail/domain1/user2
>
> /var/vmail/domain2/user3
> /var/vmail/domain2/user4
>
> I know that the always_bcc parameter exists. Do people generally just
> dump all emails into a backup user?
>
> Or do people at least separate emails per domain, or even per
> domain/user? If someone wants to investigate an email I think it'd be
> easiest to have postfix separate them in a similar fashion as the
> virtual domain/user directories are done.
>
> Also, at some point I would want to possible delete old emails. Do
> people do this usually based on time? or on disk-usage? If emails are
> bcc'd into a mailbox can a script be automated to remove old emails from
> the backup?

Im using that way to backup:
%%postconf always_bcc
always_bcc = postbackup(a)domain.com
%%crontab -l
#min hour mday month wday command
# backup a mail archive once a week
0 23 * * 7 /usr/bin/perl /root/
mail_backup.pl -q
%%cat mail_backup.pl
#!/usr/bin/perl
#
# vars
use Log::LogLite;
$LOG_DIRECTORY = "/var/log";
$ERROR_LOG_LEVEL = 6;
$CALLER="mail_backup.pl";
$log = new Log::LogLite($LOG_DIRECTORY."/maillog", $ERROR_LOG_LEVEL);
use File::Copy;

$backup_path="/usr/mail_backup"; #to
$bcm_path="/usr/vmail/postbackup/new"; #from
$config_path="/etc/postfix/vusers"; #where the users

$banner="E-mail backup & sorting program by ONYX.\n";

print $banner;

#attempt to read postbackup maildir
opendir(MDIR,"$bcm_path") or die "Cant find postbackup maildir! Check
$bcm_path for existense.\n";
@files=readdir(MDIR);
closedir(MDIR);
if (scalar(@files)==2) #abort if no mail to backup
{
$log->write("No mails to backup! Aborted.",$CALLER);
die "No mails to backup! Aborted.\n";
}

#finded files
print "The following mails will be stored:\n\n";
for ($j=2;$j <= scalar(@files)-1;$j++)
{
print "$files[$j]\n";
}

printf("\nTotal: %d mails.\n",scalar(@files)-2);

#yes_no confirmation
if (!defined($ARGV[0]) or $ARGV[0] ne "-q")
{
print "\nConfirm? [y/n]: ";
$yes_no=<STDIN>;
chop($yes_no);
if ($yes_no ne 'y')
{
die "Not confirmed. Type 'y' to confirm! Aborted.\n";
}
}


#reading the config file
open(CONF,"$config_path") or die "Cant read postfix config! Check
$config_path for existense.\n";
$e=0;
while (<CONF>)
{
if ($_=~m|(\S+)|)
{
$config[$e]=$1;
$e++;
}
}
close(CONF);



#ok, here we go
chdir($bcm_path);
for ($i=2;$i <= scalar(@files)-1;$i++)
{
@content=0;
$lc=0;
open(MFILE,"$files[$i]") or die "Cant open $files[$i]! checkit.\n";
while ($line=<MFILE>)
{
$content[$lc]=$line;
if ($line=~m|X-Anti-Virus|i)
{
last;
}
$lc++;
}
close(MFILE);
$b=0;
for ($q=0;$q <= scalar(@content)-1;$q++)
{
if ($content[$q]=~m|^From:.*\s<(\S+@\S+)>|i or
$content[$q]=~m|^From:.*\s(\S+@\S+)|i)
{
if (is_local(@config,$1)!=0) #if sender is local...
{
$b++;
print "$i. Storing: outbox -> $1 ";
$ret=backup_mail($files[$i], $1,"out"); #store
the mail in his out dir
print("-> Done.");
}
}
if ($content[$q]=~m|^To:.*\s<(\S+\@\S+)>|i or $content[$q]=~m|
^To:.*\s(\S+\@\S+)|i)
{
if ($il=is_local(@config,$1)) #if recipient is local
{
$b++;
print "$i. Storing: inbox -> $1 ";
$ret=backup_mail($files[$i], $1,"in"); #store the
mail in his in dir
print("-> Done.");
}
}

}
if($b==0 or $b>2)
{
print "$i. Storing: inbox -> Unsorted ";
backup_mail($files[$i], "Unsorted","in");
print("-> Done.");
}
unlink($files[$i]) and print " -> Deleted.\n";
}

$log->write((scalar(@files)-2)." mails sorted OK.",$CALLER);

system("/usr/bin/tar zcf /usr/`/bin/date \"+%Y_%m_%d\"`.tar.gz
$backup_path/");
system("rm -r $backup_path/*");
$log->write((scalar(@files)-2)." mails compressed OK.",$CALLER);
exit 1;

sub backup_mail()
{
mkdir("$backup_path/$_[1]");
mkdir("$backup_path/$_[1]/out");
mkdir("$backup_path/$_[1]/in");
if ($_[2] eq "out")
{
copy("$_[0]","$backup_path/$_[1]/out/$_[0]") or return "Cant
copy to $backup_path/$_[1]/out/$_[0]! Check it.\n";
return "$backup_path/$_[1]/out/$_[0]\t\t";
}
else
{
copy("$_[0]","$backup_path/$_[1]/in/$_[0]") or return "Cant copy
to $backup_path/$_[1]/in/$_[0]! Check it.\n";
return "$backup_path/$_[1]/in/$_[0]\t\t";
}

}

sub is_local()
{
#print(@_[scalar(@_)-1]);
for ($r=0;$r <= scalar(@_)-2;$r++)
{
if ( $_[$r]=~m|$_[scalar(@_)-1]|i)
{
return 1;
}
}
return 0;
}
%%


Ones a week that script runs and sort\compress\delete mails in
postbackup maildir, where it was delivered with always_bcc :)

From: E-Star on
Seems simple enough. I will go through your script in more detail when
I'm at the point where I have my server running. Thanks.


<ivakras1(a)gmail.com> wrote:

> On 7 ???, 11:03, unix_c...(a)linuxmail.org (E-Star) wrote:
> > In general what is the best method to save a backup of all emails that
> > pass through my server.
> >
> > I'm setting up Postfix with virtual domains and users into a directory
> > like:
> >
> > /var/vmail/domain1/user1
> > /var/vmail/domain1/user2
> >
> > /var/vmail/domain2/user3
> > /var/vmail/domain2/user4
> >
> > I know that the always_bcc parameter exists. Do people generally just
> > dump all emails into a backup user?
> >
> > Or do people at least separate emails per domain, or even per
> > domain/user? If someone wants to investigate an email I think it'd be
> > easiest to have postfix separate them in a similar fashion as the
> > virtual domain/user directories are done.
> >
> > Also, at some point I would want to possible delete old emails. Do
> > people do this usually based on time? or on disk-usage? If emails are
> > bcc'd into a mailbox can a script be automated to remove old emails from
> > the backup?
>
> Im using that way to backup:
> %%postconf always_bcc
> always_bcc = postbackup(a)domain.com
> %%crontab -l
> #min hour mday month wday command
> # backup a mail archive once a week
> 0 23 * * 7 /usr/bin/perl /root/
> mail_backup.pl -q
> %%cat mail_backup.pl
> #!/usr/bin/perl
> #
> # vars
> use Log::LogLite;
> $LOG_DIRECTORY = "/var/log";
> $ERROR_LOG_LEVEL = 6;
> $CALLER="mail_backup.pl";
> $log = new Log::LogLite($LOG_DIRECTORY."/maillog", $ERROR_LOG_LEVEL);
> use File::Copy;
>
> $backup_path="/usr/mail_backup"; #to
> $bcm_path="/usr/vmail/postbackup/new"; #from
> $config_path="/etc/postfix/vusers"; #where the users
>
> $banner="E-mail backup & sorting program by ONYX.\n";
>
> print $banner;
>
> #attempt to read postbackup maildir
> opendir(MDIR,"$bcm_path") or die "Cant find postbackup maildir! Check
> $bcm_path for existense.\n";
> @files=readdir(MDIR);
> closedir(MDIR);
> if (scalar(@files)==2) #abort if no mail to backup
> {
> $log->write("No mails to backup! Aborted.",$CALLER);
> die "No mails to backup! Aborted.\n";
> }
>
> #finded files
> print "The following mails will be stored:\n\n";
> for ($j=2;$j <= scalar(@files)-1;$j++)
> {
> print "$files[$j]\n";
> }
>
> printf("\nTotal: %d mails.\n",scalar(@files)-2);
>
> #yes_no confirmation
> if (!defined($ARGV[0]) or $ARGV[0] ne "-q")
> {
> print "\nConfirm? [y/n]: ";
> $yes_no=<STDIN>;
> chop($yes_no);
> if ($yes_no ne 'y')
> {
> die "Not confirmed. Type 'y' to confirm! Aborted.\n";
> }
> }
>
>
> #reading the config file
> open(CONF,"$config_path") or die "Cant read postfix config! Check
> $config_path for existense.\n";
> $e=0;
> while (<CONF>)
> {
> if ($_=~m|(\S+)|)
> {
> $config[$e]=$1;
> $e++;
> }
> }
> close(CONF);
>
>
>
> #ok, here we go
> chdir($bcm_path);
> for ($i=2;$i <= scalar(@files)-1;$i++)
> {
> @content=0;
> $lc=0;
> open(MFILE,"$files[$i]") or die "Cant open $files[$i]! checkit.\n";
> while ($line=<MFILE>)
> {
> $content[$lc]=$line;
> if ($line=~m|X-Anti-Virus|i)
> {
> last;
> }
> $lc++;
> }
> close(MFILE);
> $b=0;
> for ($q=0;$q <= scalar(@content)-1;$q++)
> {
> if ($content[$q]=~m|^From:.*\s<(\S+@\S+)>|i or
> $content[$q]=~m|^From:.*\s(\S+@\S+)|i)
> {
> if (is_local(@config,$1)!=0) #if sender is local...
> {
> $b++;
> print "$i. Storing: outbox -> $1 ";
> $ret=backup_mail($files[$i], $1,"out"); #store
> the mail in his out dir
> print("-> Done.");
> }
> }
> if ($content[$q]=~m|^To:.*\s<(\S+\@\S+)>|i or $content[$q]=~m|
> ^To:.*\s(\S+\@\S+)|i)
> {
> if ($il=is_local(@config,$1)) #if recipient is local
> {
> $b++;
> print "$i. Storing: inbox -> $1 ";
> $ret=backup_mail($files[$i], $1,"in"); #store the
> mail in his in dir
> print("-> Done.");
> }
> }
>
> }
> if($b==0 or $b>2)
> {
> print "$i. Storing: inbox -> Unsorted ";
> backup_mail($files[$i], "Unsorted","in");
> print("-> Done.");
> }
> unlink($files[$i]) and print " -> Deleted.\n";
> }
>
> $log->write((scalar(@files)-2)." mails sorted OK.",$CALLER);
>
> system("/usr/bin/tar zcf /usr/`/bin/date \"+%Y_%m_%d\"`.tar.gz
> $backup_path/");
> system("rm -r $backup_path/*");
> $log->write((scalar(@files)-2)." mails compressed OK.",$CALLER);
> exit 1;
>
> sub backup_mail()
> {
> mkdir("$backup_path/$_[1]");
> mkdir("$backup_path/$_[1]/out");
> mkdir("$backup_path/$_[1]/in");
> if ($_[2] eq "out")
> {
> copy("$_[0]","$backup_path/$_[1]/out/$_[0]") or return "Cant
> copy to $backup_path/$_[1]/out/$_[0]! Check it.\n";
> return "$backup_path/$_[1]/out/$_[0]\t\t";
> }
> else
> {
> copy("$_[0]","$backup_path/$_[1]/in/$_[0]") or return "Cant copy
> to $backup_path/$_[1]/in/$_[0]! Check it.\n";
> return "$backup_path/$_[1]/in/$_[0]\t\t";
> }
>
> }
>
> sub is_local()
> {
> #print(@_[scalar(@_)-1]);
> for ($r=0;$r <= scalar(@_)-2;$r++)
> {
> if ( $_[$r]=~m|$_[scalar(@_)-1]|i)
> {
> return 1;
> }
> }
> return 0;
> }
> %%
>
>
> Ones a week that script runs and sort\compress\delete mails in
> postbackup maildir, where it was delivered with always_bcc :)