0887 371 498 support@itservice-bg.net
07.10.2017 · Самуил Арсов · Bash script, Debian, Hosting, Linux commands, Mail, Ubuntu

Postfix mail tools in bash

Инструменти за анализ и статистика на Postfix мейл сървъра в bash среда

Postfix е вероятно най-използваният пощенски сървър в интернет. Създаден като алтернатива на Sendmail, той отдавна надмина опонента си. За Postfix съществува изобилна документация — как да се инсталира, как да се конфигурира. Но диагностиката на проблеми и наблюдението на сървъра на по-ниско ниво са слабо документирани. С времето събрах набор от команди, трикове и скриптове, улесняващи процеса по диагностика и наблюдение на пощенския сървър — по-специално в ISPConfig среда.

Send message

Изпращане на мейл директно от терминала:

echo "Message Body" | mail -s "Message Subject" support@itservice-bg.net

Mail log

Следене на лога в реално време:

tail -f /var/log/mail.log

Mail log с оцветяване

При преглеждане на mail лога в реално време редовете вървят бързо и са еднообразни. Скриптът по-долу оцветява ключовите параметри, което прави проследяването на информацията интуитивно:

#!/bin/bash

shopt -s expand_aliases
alias grey-grep="GREP_COLOR='1;30' grep -E --color=always --line-buffered"
alias red-grep="GREP_COLOR='1;31' grep -E --color=always --line-buffered"
alias green-grep="GREP_COLOR='1;32' grep -E --color=always --line-buffered"
alias yellow-grep="GREP_COLOR='1;33' grep -E --color=always --line-buffered"
alias cyan-grep="GREP_COLOR='1;36' grep -E --color=always --line-buffered"

tail -f -n 100 /var/log/mail.log | \
grey-grep -w "postfix|dovecot|$" | \
red-grep -w "unknown|lost|Aborted|disconnect|Disconnected|reject|denied|rejected|timeout|NOQUEUE|discarded|spam|failed|error|RCPT|$" | \
green-grep -w "done|Ok|sent|relay|delay|queued|queue|active|delays|dsn|$" | \
yellow-grep -w "Login:|connect|user|from|to|$" | \
cyan-grep -w "imap-login|pop3-login|smtpd|smtp|qmgr|cleanup$"

Оцветяване само на грешките:

grep -E '(reject|warning|error|fatal|panic):' /var/log/mail.log

Mail queue

Преглед на опашката с неизпратени писма:

mailq
# или еквивалентно:
postqueue -p

Queue ID (подчертан в примера) е уникален идентификатор на писмото. С postcat може да се прегледа съдържанието му — заглавната част (header) съдържа информация за изпращача, получателя и маршрута:

postcat -vq 336B22E045C6

Изпразване на цялата опашка:

postsuper -d ALL

Изтриване на конкретно писмо по Queue ID:

postsuper -d 336B22E045C6

Принудително изпращане на опашката (flush):

postqueue -f

Mail statistic

Брой изпратени писма по изпращач:

grep 'from=<' /var/log/mail.log | grep 'qmgr' | awk '{print $7}' | sed -r 's/^.*=<(.*?)>.*$/\1/' | sort | uniq -c | sort -n

Всички успешно изпратени писма по изпращач:

grep "status=sent" /var/log/mail.log | cut -d "=" -f 2 | cut -d ">" -f 1 | cut -d "<" -f 2 | sort | uniq -c | sort -n

Кои дни са налични в лога:

awk '{print $1,$2}' /var/log/mail.log | uniq

Изпращал ли е писма даден адрес:

grep 'from=' /var/log/mail.log

Изпращал ли е адрес писмо до конкретен получател:

grep 'from=' /var/log/mail.log | grep 'to='

pflogsumm

pflogsumm предоставя подробна статистика на Postfix и дава пълна картина на мейл трафика — включително ранни индикации за потенциални проблеми.

Инсталиране:

apt-get install pflogsumm

Обща статистика:

pflogsumm /var/log/mail.log

Подробна статистика за изпращачи и получатели:

pflogsumm -e /var/log/mail.log

Автоматичен дневен отчет по имейл чрез cron — добавяме в /etc/crontab:

59 23 * * * root pflogsumm -d today /var/log/mail.log | mail -s "pflogsumm itservice" robot@telehost.bg

Рестартиране на cron:

systemctl restart cron.service

Изтриване на Trash, Junk, Spam, Low Priority

Скрипт за принудително изтриване на писма по-стари от 30 дни в директориите Trash, Junk, Spam и Low Priority на всички потребители:

#!/bin/bash

MAILDIRS=$(find /var/vmail/*/*/Maildir/ -maxdepth 0 -type d)
for basedir in $MAILDIRS; do
  for dir in .Trash .Junk .Spam ".Low Priority"; do
    for dir2 in cur new; do
      [ -e "$basedir/$dir/$dir2" ] && (
        echo "Processing $basedir/$dir/$dir2..."
        find "$basedir/$dir/$dir2/" -type f -mtime +30 -delete
      )
    done
  done
done

pflogrep — Postfix log grep complete activity

За подробен анализ на конкретна пощенска кутия използвам Perl скрипта pflogrep:

#!/usr/bin/perl

use Getopt::Long;

($me = $0) =~ s%.*/%%;

$Usage = "
$me [-i] [-s] [-v] PATTERN [FILE]....
  -i  -- ignore case distinctions when matching
  -s  -- add separator between messages
  -v  -- selected lines are those not matching
Examples:
  $me info\@example.com mail.log | pflogsumm
  $me example.com mail.log | grep -e from= -e to= | grep --color -P \\<.*\\>\\|status
";

die $Usage unless &GetOptions( 'i', 's', 'v' ) && (@ARGV >= 1 );

my $ptn = shift;
my $regex = ( $opt_i ) ?  qr/$ptn/io : qr/$ptn/o;
my %P;
my $found = 0;

$exstat = 1;
$|++;

sub checkMatch() {
    my $q = shift;
    my $matches = $P{$q} =~ $regex;
    if ( ($matches && !$opt_v) || (!$matches && $opt_v)) {
        print $P{$q};
        print '-' x 50, "\n" if $opt_s;
        $found++;
    }
    undef $P{$q};
}

sub handleStream() {
    my $fh = shift;

    while (<$fh>) {
        next unless /: (([0-9A-Zb-z]{10,15})|NOQUEUE)/;
        $q = $1;
        $P{$q} .= $_;
        if (/: (removed$|milter-reject:)/ || $q eq 'NOQUEUE') {
            &checkMatch($q);
        }
    }
    foreach my $q (keys %P) {
        &checkMatch($q);
    }
    return $found;
}

if (@ARGV==0) {
    $exstat = 0 if &handleStream(\*STDIN);
    exit( $exstat );
}

for $f ( @ARGV ) {
    unless ( open( INP, '<', $f )) {
        warn "Unable to open input file $f: $!\n";
        next;
    }
    $exstat = 0 if &handleStream(\*INP);
    close INP;
}
exit( $exstat );

Анализ само за конкретна пощенска кутия чрез pflogsumm:

./pflogrep.pl support@itservice-bg.net /var/log/mail.log | pflogsumm

Оцветяване на from=, to= и status:

./pflogrep.pl support@itservice-bg.net /var/log/mail.log | grep -e from= -e to= | grep --color -P '\<.*\>\|status'

Maillog Perl скрипт

Друг полезен Perl скрипт: https://github.com/SokoloffA/maillog/blob/master/maillog.pl

chmod 755 maillog.pl

Получени писма за конкретен ден към пощенска кутия:

./maillog.pl -d 08/10/2017 -t support@itservice-bg.net

Изпратени писма за конкретен ден от пощенска кутия:

./maillog.pl -d 09/10/2017 -f support@itservice-bg.net

Четене на пощенска кутия с Mutt

apt-get install mutt

Създаване на конфигурационен файл ~/.muttrc:

set mbox_type=Maildir
set folder="/var/vmail/itservice-bg.net/support/Maildir"
set mask="!^\\.[^.]"
set mbox="/var/vmail/itservice-bg.net/support/Maildir"
set record="+.Sent"
set postponed="+.Drafts"
set spoolfile="/var/vmail/itservice-bg.net/support/Maildir"

Стартиране:

mutt

Roundcube

Неуспешни опити за логване:

cat /var/log/roundcube/errors | grep failed | awk '{print $1,$2,$6,$7,$9,$11}'

Изпратени писма през Roundcube:

cat /var/log/roundcube/sendmail | awk '{print $1,$2,$5,$6,$7,$8,$9}'

Посещения регистрирани в Apache лога:

grep roundcube /var/log/apache2/other_vhosts_access.log

Спам чрез crontab от web

Полезна практика е периодично да се преглежда auth.log за необичайни cron заявки:

tail -f /var/log/auth.log
# Mar 11 14:30:01 host CRON[10977]: pam_unix(cron:session): session opened for user web119

Проверка на crontab на потребителя:

crontab -u web119 -l

Ако е открит злонамерен запис — компилиран Perl файл в /var/tmp/, стартиращ се на всеки 10 минути — изтриваме реда от crontab и файла, след което рестартираме cron:

systemctl restart cron.service

Спам чрез mail() от PHP

Неподдържани или некачествено разработени сайтове понякога генерират масово количество спам чрез функцията mail() на PHP. Забраната се поставя в php.ini:

За PHP 7.x:

vim /etc/php/7.0/apache2/php.ini

За PHP 8.x:

vim /etc/php/8.1/apache2/php.ini

Намерете disable_functions и добавете mail:

disable_functions = mail

Рестартирайте уеб сървъра след промяната. В ISPConfig забраната може да се приложи само за конкретен сайт от менюто на домейна: