Дата: 2015-04-05 21:57:21
Комментариев: 0
Ещё одна попытка настройки идеального почтового сервера. Начнем с установки необходимых пакетов:
sudo apt-get install postfix postfix-mysql dovecot dovecot-mysql dovecot-managesieved dovecot-sieve mysql-server mysql-client amavisd-new spamassassin clamav-daemon postgrey fail2ban opendkim opendkim-tools openssl ssl-cert arj cabextract cpio lha nomarch pax rar unrar unzip zip p7zip unrar-free


Создаем пользователя:
groupadd -g 5000 vmail
useradd -d /var/vmail/ -g 5000 -u 5000 vmail
chown vmail:vmail /srv/vmail

Через StartSSL получаем SSL сертификат для этого у себя на сервере создаем приватный ключ:
sudo openssl genrsa -des3 -out enlr.ru_secure.key 4096

Создаем CSR сертификат, который скармливаем StartSSL (при генерации сертификата нужно скипнуть создание приватного ключа):
sudo openssl req -new -key site.ru_secure.key -out site.ru.csr

После того как скормим StartSSL CSR ключ он выдаст CRT и далее создаем PEM файл:
cat site.ru.crt sub.class1.server.ca.pem > site.ru.pem

Убираем кодовую фразу из ключа:
sudo openssl rsa -in site.ru_secure.key -out site.ru.key

Структура базы данных:

mailserver.sql открыть закрыть

SET SQL_MODE = "NO_AUTO_VALUE_ON_ZERO";
SET time_zone = "+00:00";
 
 
/*!40101 SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT */;
/*!40101 SET @OLD_CHARACTER_SET_RESULTS=@@CHARACTER_SET_RESULTS */;
/*!40101 SET @OLD_COLLATION_CONNECTION=@@COLLATION_CONNECTION */;
/*!40101 SET NAMES utf8 */;
 
--
-- База данных: `mailserver`
--
 
-- --------------------------------------------------------
 
--
-- Структура таблицы `quota`
--
 
CREATE TABLE IF NOT EXISTS `quota` (
  `username` varchar(100) NOT NULL,
  `bytes` bigint(20) NOT NULL DEFAULT '0',
  `messages` int(11) NOT NULL DEFAULT '0',
  PRIMARY KEY (`username`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
 
-- --------------------------------------------------------
 
--
-- Дублирующая структура для представления `view_aliases`
--
CREATE TABLE IF NOT EXISTS `view_aliases` (
`email` varchar(91)
,`destination` varchar(80)
);
-- --------------------------------------------------------
 
--
-- Дублирующая структура для представления `view_users`
--
CREATE TABLE IF NOT EXISTS `view_users` (
`email` varchar(91)
,`password` varchar(32)
,`quota` int(10)
);
-- --------------------------------------------------------
 
--
-- Структура таблицы `virtual_aliases`
--
 
CREATE TABLE IF NOT EXISTS `virtual_aliases` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `domain_id` int(11) NOT NULL,
  `source` varchar(40) NOT NULL,
  `destination` varchar(80) NOT NULL,
  PRIMARY KEY (`id`),
  KEY `domain_id` (`domain_id`)
) ENGINE=MyISAM  DEFAULT CHARSET=latin1 AUTO_INCREMENT=0 ;
 
-- --------------------------------------------------------
 
--
-- Структура таблицы `virtual_domains`
--
 
CREATE TABLE IF NOT EXISTS `virtual_domains` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `name` varchar(50) NOT NULL,
  PRIMARY KEY (`id`)
) ENGINE=MyISAM  DEFAULT CHARSET=latin1 AUTO_INCREMENT=0 ;
 
-- --------------------------------------------------------
 
--
-- Структура таблицы `virtual_users`
--
 
CREATE TABLE IF NOT EXISTS `virtual_users` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `domain_id` int(11) NOT NULL,
  `user` varchar(40) NOT NULL,
  `password` varchar(32) NOT NULL,
  `quota` int(10) NOT NULL DEFAULT '50485760',
  PRIMARY KEY (`id`),
  UNIQUE KEY `UNIQUE_EMAIL` (`domain_id`,`user`)
) ENGINE=MyISAM  DEFAULT CHARSET=latin1 AUTO_INCREMENT=0 ;
 
-- --------------------------------------------------------
 
--
-- Структура для представления `view_aliases`
--
DROP TABLE IF EXISTS `view_aliases`;
 
CREATE ALGORITHM=UNDEFINED DEFINER=`root`@`localhost` SQL SECURITY DEFINER VIEW `view_aliases` AS select concat(`virtual_aliases`.`source`,'@',`virtual_domains`.`name`) AS `email`,`virtual_aliases`.`destination` AS `destination` from (`virtual_aliases` left join `virtual_domains` on((`virtual_aliases`.`domain_id` = `virtual_domains`.`id`)));
 
-- --------------------------------------------------------
 
--
-- Структура для представления `view_users`
--
DROP TABLE IF EXISTS `view_users`;
 
CREATE ALGORITHM=UNDEFINED DEFINER=`root`@`localhost` SQL SECURITY DEFINER VIEW `view_users` AS select concat(`virtual_users`.`user`,'@',`virtual_domains`.`name`) AS `email`,`virtual_users`.`password` AS `password`,`virtual_users`.`quota` AS `quota` from (`virtual_users` left join `virtual_domains` on((`virtual_users`.`domain_id` = `virtual_domains`.`id`)));
 
/*!40101 SET CHARACTER_SET_CLIENT=@OLD_CHARACTER_SET_CLIENT */;
/*!40101 SET CHARACTER_SET_RESULTS=@OLD_CHARACTER_SET_RESULTS */;
/*!40101 SET COLLATION_CONNECTION=@OLD_COLLATION_CONNECTION */;
 

Конфиги Postfix:

1. /etc/postfix/main.cf открыть закрыть

smtpd_banner = $myhostname ESMTP $mail_name
biff = no
 
# appending .domain is the MUA's job.
append_dot_mydomain = no
 
# Uncomment the next line to generate "delayed mail" warnings
#delay_warning_time = 4h
 
readme_directory = /usr/share/doc/postfix
 
# TLS parameters
smtp_tls_security_level = may
smtpd_tls_security_level = may
smtpd_tls_loglevel = 1
smtpd_tls_received_header = yes
smtpd_tls_session_cache_timeout = 3600s
smtpd_tls_mandatory_protocols=!SSLv2, !SSLv3
tls_random_source = dev:/dev/urandom
smtpd_tls_auth_only = no
smtpd_tls_cert_file = /etc/postfix/ssl/site.ru.postfix.pem
smtpd_tls_key_file = /etc/postfix/ssl/site.ru.postfix.key
smtpd_use_tls = yes
smtpd_tls_session_cache_database = btree:${data_directory}/smtpd_scache
smtp_tls_session_cache_database = btree:${data_directory}/smtp_scache
 
 
#MISC
smtpd_helo_required = yes
smtpd_discard_ehlo_keywords = etrn, silent-discard
smtpd_forbidden_commands = CONNECT GET POST
broken_sasl_auth_clients = yes
smtpd_delay_reject = yes
disable_vrfy_command = yes
 
smtpd_helo_restrictions = permit_mynetworks,
                          permit_sasl_authenticated,
                          reject_non_fqdn_helo_hostname,
                          reject_invalid_helo_hostname
 
smtpd_data_restrictions = permit_mynetworks,
                          permit_sasl_authenticated,
                          reject_unauth_pipelining,
                          reject_multi_recipient_bounce,
 
smtpd_sender_restrictions = permit_mynetworks,
                            permit_sasl_authenticated,
                            reject_non_fqdn_sender,
                            reject_unknown_sender_domain
 
#
myhostname = mail.site.ru
alias_maps = hash:/etc/aliases
alias_database = hash:/etc/aliases
myorigin = /etc/mailname
mydestination = 
relayhost = 
mynetworks = 127.0.0.0/8, 192.168.0.0/24
mailbox_size_limit = 1024000
recipient_delimiter = +
inet_interfaces = all
inet_protocols = all
virtual_mailbox_domains = mysql:/etc/postfix/mysql-virtual-mailbox-domains.cf
virtual_uid_maps = static:5000
virtual_gid_maps = static:5000
virtual_mailbox_maps = mysql:/etc/postfix/mysql-virtual-mailbox-maps.cf
virtual_alias_maps = mysql:/etc/postfix/mysql-virtual-alias-maps.cf,mysql:/etc/postfix/mysql-email2email.cf,hash:/etc/postfix/virtual
virtual_transport = dovecot
dovecot_destination_recipient_limit = 1
smtpd_sasl_type = dovecot
smtpd_sasl_path = private/auth
smtpd_sasl_auth_enable = yes
smtpd_recipient_restrictions = permit_mynetworks,permit_sasl_authenticated,reject_unauth_destination,check_policy_service inet:127.0.0.1:10023,reject_invalid_hostname,reject_non_fqdn_hostname,reject_non_fqdn_sender,reject_non_fqdn_recipient,reject_unknown_sender_domain,reject_unknown_recipient_domain,permit_mynetworks,reject_unauth_pipelining,reject_rbl_client zombie.dnsbl.sorbs.net,reject_rbl_client cbl.abuseat.org,reject_rbl_client zen.spamhaus.org,reject_rbl_client bl.spamcop.net,reject_rbl_client work.rsbs.express.ru,reject_rbl_client dnsbl.sorbs.net
#
smtpd_sasl_security_options = noanonymous
html_directory = /usr/share/doc/postfix/html
content_filter = smtp-amavis:[127.0.0.1]:10024
 
#####
# ============================================================
# LIMITS
# ============================================================
message_size_limit = 51200000
smtpd_soft_error_limit = 10
smtpd_hard_error_limit = 15
smtpd_error_sleep_time = 20
anvil_rate_time_unit = 60s
smtpd_client_connection_count_limit = 20
smtpd_client_connection_rate_limit = 30
smtpd_client_message_rate_limit = 30
smtpd_client_event_limit_exceptions = 127.0.0.0/8
smtpd_client_connection_limit_exceptions = 127.0.0.0/8
 
# ============================================================
# QUEUE
# ============================================================
maximal_queue_lifetime = 1d
bounce_queue_lifetime = 1d
 
# ============================================================
# DKIM
# ============================================================   
milter_default_action = accept
milter_protocol = 2
smtpd_milters = inet:localhost:8891
non_smtpd_milters = inet:localhost:8891

2. /etc/postfix/master.cf открыть закрыть

# ==========================================================================
smtp      inet  n       -       -       -       -       smtpd
#
submission inet n       -       n       -       -       smtpd
  -o syslog_name=postfix/submission
  -o smtpd_tls_wrappermode=yes
  -o smtpd_tls_security_level=encrypt
  -o smtpd_sasl_auth_enable=yes
  -o smtpd_recipient_restrictions=permit_mynetworks,permit_sasl_authenticated,reject
  -o smtpd_relay_restrictions=permit_mynetworks,permit_sasl_authenticated,defer_unauth_destination
  -o milter_macro_daemon_name=ORIGINATING
#
pickup    fifo  n       -       -       60      1       pickup
cleanup   unix  n       -       -       -       0       cleanup
qmgr      fifo  n       -       n       300     1       qmgr
tlsmgr    unix  -       -       -       1000?   1       tlsmgr
rewrite   unix  -       -       -       -       -       trivial-rewrite
bounce    unix  -       -       -       -       0       bounce
defer     unix  -       -       -       -       0       bounce
trace     unix  -       -       -       -       0       bounce
verify    unix  -       -       -       -       1       verify
flush     unix  n       -       -       1000?   0       flush
proxymap  unix  -       -       n       -       -       proxymap
proxywrite unix -       -       n       -       1       proxymap
smtp      unix  -       -       -       -       -       smtp
# When relaying mail as backup MX, disable fallback_relay to avoid MX loops
relay     unix  -       -       -       -       -       smtp
        -o smtp_fallback_relay=
#       -o smtp_helo_timeout=5 -o smtp_connect_timeout=5
showq     unix  n       -       -       -       -       showq
error     unix  -       -       -       -       -       error
retry     unix  -       -       -       -       -       error
discard   unix  -       -       -       -       -       discard
local     unix  -       n       n       -       -       local
virtual   unix  -       n       n       -       -       virtual
lmtp      unix  -       -       -       -       -       lmtp
anvil     unix  -       -       -       -       1       anvil
scache    unix  -       -       -       -       1       scache
 
#
maildrop  unix  -       n       n       -       -       pipe
  flags=DRhu user=vmail argv=/usr/bin/maildrop -d ${recipient}
#
uucp      unix  -       n       n       -       -       pipe
  flags=Fqhu user=uucp argv=uux -r -n -z -a$sender - $nexthop!rmail ($recipient)
#
# Other external delivery methods.
#
ifmail    unix  -       n       n       -       -       pipe
  flags=F user=ftn argv=/usr/lib/ifmail/ifmail -r $nexthop ($recipient)
bsmtp     unix  -       n       n       -       -       pipe
  flags=Fq. user=bsmtp argv=/usr/lib/bsmtp/bsmtp -t$nexthop -f$sender $recipient
scalemail-backend unix  -       n       n       -       2       pipe
  flags=R user=scalemail argv=/usr/lib/scalemail/bin/scalemail-store ${nexthop} ${user} ${extension}
mailman   unix  -       n       n       -       -       pipe
  flags=FR user=list argv=/usr/lib/mailman/bin/postfix-to-mailman.py
  ${nexthop} ${user}
dovecot  unix - n n - - pipe
   flags=DRhu user=vmail:vmail argv=/usr/lib/dovecot/deliver -f ${sender} -d ${recipient}
smtp-amavis unix -      -       n     -       4  smtp
     -o smtp_data_done_timeout=1200
     -o smtp_send_xforward_command=yes
     -o disable_dns_lookups=yes
     -o max_use=20
 
127.0.0.1:10025 inet n    -       n       -       -     smtpd
     -o content_filter=
     -o smtpd_delay_reject=no
     -o smtpd_client_restrictions=permit_mynetworks,reject
     -o smtpd_helo_restrictions=
     -o smtpd_sender_restrictions=
     -o smtpd_recipient_restrictions=permit_mynetworks,reject
     -o smtpd_data_restrictions=reject_unauth_pipelining
     -o smtpd_end_of_data_restrictions=
     -o smtpd_restriction_classes=
     -o mynetworks=127.0.0.0/8,192.168.0.0/16
     -o smtpd_error_sleep_time=0
     -o smtpd_soft_error_limit=1001
     -o smtpd_hard_error_limit=1000
     -o smtpd_client_connection_count_limit=0
     -o smtpd_client_connection_rate_limit=0
     -o receive_override_options=no_header_body_checks,no_unknown_recipient_checks,no_milters,no_address_mappings
     -o local_header_rewrite_clients=
     -o smtpd_milters=
     -o local_recipient_maps=
     -o relay_recipient_maps=

3. /etc/postfix/mysql-email2email.cf открыть закрыть

user = mailuser
password = password-for-mailuser
hosts = 127.0.0.1
dbname = mailserver
query = SELECT email FROM view_users WHERE email='%s'

4. /etc/postfix/mysql-virtual-alias-maps.cf открыть закрыть

user = mailuser
password = password-for-mailuser
hosts = 127.0.0.1
dbname = mailserver
query = SELECT destination FROM view_aliases WHERE email='%s'

5. /etc/postfix/mysql-virtual-mailbox-domains.cf открыть закрыть

user = mailuser
password = password-for-mailuser
hosts = 127.0.0.1
dbname = mailserver
query = SELECT 1 FROM virtual_domains WHERE name='%s'

6. /etc/postfix/mysql-virtual_mailbox_limit_maps.cf открыть закрыть

user = mailuser
password = password-for-mailuser
hosts = 127.0.0.1
dbname = mailserver
query = SELECT quota FROM view_users WHERE email='%s'

7. /etc/postfix/mysql-virtual-mailbox-maps.cf открыть закрыть

user = mailuser
password = password-for-mailuser
hosts = 127.0.0.1
dbname = mailserver
query = SELECT 1 FROM view_users WHERE email='%s'

Настройка OpenDKIM:
mkdir /etc/postfix/opendkim
opendkim-genkey -t -s site.ru -d site.ru

При выполнении второй команды будут созданы файлы /etc/postfix/opendkim/site.ru.private и /etc/postfix/opendkim/site.ru.txt, с секретным и публичными ключами соответственно. Публичный ключ нужно добавить в соответствующую TXT запись вашего домена. Также дадим доступ на чтение для группы, в которой работает OpenDKIM, а сам postfix добавим в ту же группу, чтобы тот мог подписывать письма подключаясь к демону OpenDKIM через его сокет:
chgrp opendkim /etc/postfix/opendkim/*
chmod g+r /etc/postfix/opendkim/*
gpasswd -a postfix opendkim

Конфиг OpenDKIM

/etc/opendkim.conf открыть закрыть

Syslog                  yes
UMask                   002
OversignHeaders         From
 
Canonicalization relaxed/relaxed
SyslogSuccess yes
KeyTable file:/etc/postfix/opendkim/keytable
SigningTable file:/etc/postfix/opendkim/signingtable
SoftwareHeader yes
# на время отладки включим расширенное логгирование:
LogWhy yes
RequireSafeKeys false

И укажим какую почту следует подписывать:
echo dkim._domainkey.site.ru:dkim:/etc/postfix/opendkim/site.ru.private | tee -a /etc/postfix/opendkim/keytable
echo site.ru dkim._domainkey.site.ru | tee -a /etc/postfix/opendkim/signingtable

Если проверка проходит успешно, то стоит формально запретить другим серверам принимать письма с вашим доменом, но без подписи, добавив ADSP запись:
_adsp._domainkey.site.ru IN TXT "dkim=all"

Теперь переходим к конфигам Dovecot:

1. /etc/dovecot/dovecot.conf открыть закрыть

mail_uid = 5000
mail_gid = 5000
first_valid_uid = 5000 
last_valid_uid = 5000
 
disable_plaintext_auth = no
dotlock_use_excl = no
log_timestamp = "%Y-%m-%d %H:%M:%S "
mail_fsync = always
mail_location = maildir:/srv/vmail/%d/%n/:INDEX=/srv/vmail/%d/%n/
mail_nfs_index = yes
mail_nfs_storage = yes
mail_privileged_group = mail
mmap_disable = yes
mail_plugins = quota
namespace {
  inbox = yes
  location = 
  prefix =
  separator = /
  type = private
  subscriptions = yes
}
 
passdb {
  driver = pam
}
 
userdb {
    args = /etc/dovecot/dovecot-sql.conf
    driver = sql
}
passdb {
  args = /etc/dovecot/dovecot-sql.conf
  driver = sql
}
 
plugin {
    autocreate = INBOX
    autocreate2 = Sent
    autocreate3 = Trash
    autocreate4 = Drafts
    autocreate5 = Junk
    autocreate6 = HAM
    autosubscribe = INBOX
    autosubscribe2 = Sent
    autosubscribe3 = Trash
    autosubscribe4 = Drafts
    autosubscribe5 = Junk
    autosubscribe6 = HAM
    sieve_dir = /srv/vmail/%d/%n/sieve
    sieve = /srv/vmail/%d/%n/sieve/dovecot.sieve
 
# Quota
    quota = dict:User quota::proxy::quotadict
    quota_rule = *:storage=1G
    quota_warning = storage=85%% quota-warning 85 %u
    quota_warning2 = storage=90%% quota-warning 90 %u
    quota_warning3 = storage=95%% quota-warning 95 %u
 
}
 
# Quota
service quota-warning {
    executable = script /etc/dovecot/dovecot-quota-warning.sh
    unix_listener quota-warning {
        user = vmail
        group = vmail
        mode = 0660
    }
}
 
service dict {
    unix_listener dict {
        mode = 0660
        user = vmail
        group = vmail
    }
}
 
dict {
    quotadict = mysql:/etc/dovecot/dovecot-used-quota.conf
}
 
protocols = imap imaps sieve
 
service auth {
  unix_listener /var/spool/postfix/private/auth {
    group = postfix
    mode = 0660
    user = postfix
  }
  unix_listener auth-master {
    mode = 0600
    user = vmail
  }
  user = root
}
 
service imap-login {
  client_limit = 20
  process_min_avail = 1
}
 
service pop3-login {
  client_limit = 20
  process_min_avail = 1
 
}
 
 
ssl_cert = </etc/dovecot/site.ru.pem
ssl_key = </etc/dovecot/site.ru.key
ssl_listen = *
ssl = yes
ssl_protocols = !SSLv3 !SSLv2
 
userdb {
  driver = passwd
}
 
userdb {
  args = uid=5000 gid=5000 home=/srv/vmail/%d/%n allow_all_users=yes
  driver = static
}
 
protocol pop3 {
  pop3_uidl_format = %08Xu%08Xv
}
 
protocol lda {
  auth_socket_path = /var/run/dovecot/auth-master
  log_path = /var/log/sieve.log
  mail_plugins = $mail_plugins autocreate sieve 
  quota_full_tempfail = no
  lda_mailbox_autocreate = yes
  lda_mailbox_autosubscribe = yes
  postmaster_address = admin@site.ru
}
 
protocol imap {
  mail_plugins = $mail_plugins autocreate imap_quota
}

2. /etc/dovecot/dovecot-sql.conf открыть закрыть

driver = mysql connect = host=127.0.0.1 dbname=mailserver user=mailuser password=password-for-mailuser default_pass_scheme = PLAIN-MD5 password_query = SELECT email as user, password FROM view_users WHERE email='%u'; user_query = SELECT CONCAT('*:bytes=', quota) AS quota_rule FROM view_users WHERE email = '%u'

3. /etc/dovecot/conf.d/15-mailboxes.conf открыть закрыть

##
## Mailbox definitions
##
 
namespace inbox {
 
  # These mailboxes are widely used and could perhaps be created automatically:
  mailbox Drafts {
    auto = subscribe
    special_use = \Drafts
  }
  mailbox HAM {
    auto = subscribe
    special_use = \HAM
  }
  mailbox Junk {
    auto = subscribe
    special_use = \Junk
  }
  mailbox Trash {
    auto = subscribe
    special_use = \Trash
  }
 
  mailbox Sent {
    auto = subscribe
    special_use = \Sent
  }
  mailbox "Sent Messages" {
    auto = subscribe
    special_use = \Sent
  }
 
}

4. /etc/dovecot/dovecot-quota-warning.sh открыть закрыть

#!/usr/bin/env bash
 
PERCENT=${1}
USER=${2}
 
if [ ${PERCENT} -ge 95 ]; then
    DOMAIN="$(echo ${USER} | awk -F'@' '{print $2}')"
    cat << EOF | /usr/lib/dovecot/deliver -d ${USER} -o "plugin/quota=dict:User quota::noenforcing:proxy::quota"
From: no-reply@site.ru
Content-Type: text/plain; charset="utf-8"
Subject: ВНИМАНИЕ ! Прием Вашей почты временно приостановлен.
 
Mailbox Quota Warning: ${PERCENT}% full, ${USER}
 
На данный момент, выделенное вам дисковое пространство полностью израсходовано Вашей входящей почтой.
Прием на Ваш адрес временно прекращен и будет автоматически возобновлен, после того как Вы заберете накопившуюся почту.
 
EOF
else
cat << EOF | /usr/lib/dovecot/deliver -d ${USER} -o "plugin/quota=dict:User quota::noenforcing:proxy::quota"
From: <b>no-reply@enlr.ru</b>
Content-Type: text/plain; charset="utf-8"
Subject: ВНИМАНИЕ: Ваша почта заполнена на ${PERCENT}%
 
Ваш почтовый ящик заполнен на ${PERCENT}% , пожалуйста, удалите не нужные письма для последующих входящих писем.
 
EOF
 
fi

Конфиг Spamassassin:

/etc/spamassassin/local.cf открыть закрыть

required_score      5.0
rewrite_header      Subject ***SPAM***
 
report_safe         0
lock_method         flock
 
use_bayes          1
bayes_auto_learn   0
bayes_auto_expire  0
 
score ALL_TRUSTED -10.000
 
score URIBL_AB_SURBL 0 0.3306 0 0.3812
score URIBL_JP_SURBL 0 0.3360 0 0.4087
score URIBL_OB_SURBL 0 0.2617 0 0.3008
score URIBL_PH_SURBL 0 0.2240 0 0.2800
score URIBL_SBL 0 0.1094 0 0.1639
score URIBL_SC_SURBL 0 0.3600 0 0.4498
score URIBL_WS_SURBL 0 0.1533 0 0.2140
score DNS_FROM_AHBL_RHSBL 0
 
spf_timeout         5
 
whitelist_from_spf      *@gmail.com
whitelist_from_spf      *@126.com *@163.com
whitelist_from_spf      *@sina.com *@sohu.com *@tom.com
whitelist_from_spf      *@live.com *@hotmail.com
 
whitelist_from_dkim       *@gmail.com *@paypal.com
ok_locales          all
 

Для обучения спам фильтров Spamassassin просто перекладывайте спам письма в папку "Junk", а хорошие письма в папку "HAM" и далее раз в день или неделю запускайте скрипт c именем ящика:
./sa-learn.sh name@site.ru

nano sa-learn.sh открыть закрыть

#!/bin/bash
# путь к домашнему каталогу пользователя, который будет заниматься обучением spamassassin
DOMAIN=` echo "$1" | sed 's/\@/ /g' | awk {' print $2'}`
USER=` echo "$1" | sed 's/\@/ /g' | awk {' print $1'}`
ADMIN="/srv/vmail/$DOMAIN/$USER"
# Путь к домашнему каталогу учётной записи для spamassasin
SPAM="/var/lib/spamassassin"
 
if [ -z "$1" ] ; then
echo "Введите ящик"
exit
fi
 
# Путь к домашнему каталогу учётной записи для spamassasin
SPAM="/var/lib/spamassassin"
 
cd $SPAM/.spamassassin
 
if [ `ls $ADMIN/.HAM/cur/ | grep -v "^\.$" | grep -v "^\.\.$" | wc -l` = "0" ]; then
        echo "not found"
else
        mv $ADMIN/.HAM/cur/* $SPAM/.spamassassin/ham/
fi
 
if [ `ls $ADMIN/.HAM/new/ | grep -v "^\.$" | grep -v "^\.\.$" | wc -l` = "0" ]; then
        echo "not found"
else
        mv $ADMIN/.HAM/new/* $SPAM/.spamassassin/ham/
fi
 
if [ `ls $ADMIN/.Junk/cur/ | grep -v "^\.$" | grep -v "^\.\.$" | wc -l` = "0" ]; then
        echo "not found"
else
        mv $ADMIN/.Junk/cur/* $SPAM/.spamassassin/spam/
fi
 
if [ `ls $ADMIN/.Junk/new/ | grep -v "^\.$" | grep -v "^\.\.$" | wc -l` = "0" ]; then
        echo "not found"
else
        mv $ADMIN/.Junk/new/* $SPAM/.spamassassin/spam/
fi
 
PATHSPAM="$SPAM/.spamassassin"
 
if [ `ls $PATHSPAM/spam/  | grep -v "^\.$" | grep -v "^\.\.$" | wc -l` = "0" ]; then
        echo "SPAM: not found"
else
        sa-learn -u spam --spam --dbpath = $PATHSPAM/ $PATHSPAM/spam/*
        rm $PATHSPAM/spam/*
fi
 
if [ `ls $PATHSPAM/ham/  | grep -v "^\.$" | grep -v "^\.\.$" | wc -l` = "0" ]; then
        echo "HAM: not found"
else
        sa-learn -u spam --ham --dbpath = $PATHSPAM/ $PATHSPAM/ham/*
        rm $PATHSPAM/ham/*
fi

Конфиг Amavis:

1. /etc/amavis/conf.d/20-debian_defaults открыть закрыть

use strict;
 
$QUARANTINEDIR = "/srv/virusmail";
$quarantine_subdir_levels = 0; # enable quarantine dir hashing
 
$log_recip_templ = undef;    # disable by-recipient level-0 log entries
$DO_SYSLOG = 1;              # log via syslogd (preferred)
$syslog_ident = 'amavis';    # syslog ident tag, prepended to all messages
$syslog_facility = 'mail';
$syslog_priority = 'debug';  # switch to info to drop debug output, etc
 
$enable_db = 1;              # enable use of BerkeleyDB/libdb (SNMP and nanny)
$enable_global_cache = 1;    # enable use of libdb-based cache if $enable_db=1
 
$inet_socket_port = 10024;   # default listening socket
 
$sa_spam_subject_tag = '***SPAM*** ';
$sa_spam_modifies_subj = 1;
$sa_tag_level_deflt  = 2.0;  # add spam info headers if at, or above that level
$sa_tag2_level_deflt = 5.0; # add 'spam detected' headers at that level
$sa_kill_level_deflt = 6.31; # triggers spam evasive actions
$sa_dsn_cutoff_level = 10;   # spam level beyond which a DSN is not sent
 
$sa_mail_body_size_limit = 200*1024; # don't waste time on SA if mail is larger
$sa_local_tests_only = 0;    # only tests which do not require internet access?
 
$MAXLEVELS = 14;
$MAXFILES = 1500;
$MIN_EXPANSION_QUOTA =      100*1024;  # bytes
$MAX_EXPANSION_QUOTA = 300*1024*1024;  # bytes
 
$final_virus_destiny      = D_DISCARD;  # (data not lost, see virus quarantine)
$final_banned_destiny     = D_PASS;
$final_spam_destiny       = D_PASS;
$final_bad_header_destiny = D_PASS;     # False-positive prone (for spam)
 
$enable_dkim_verification = 0; #disabled to prevent warning
 
$virus_admin = "admin\@$mydomain"; # due to D_DISCARD default
 
$X_HEADER_LINE = "";
 
@viruses_that_fake_sender_maps = (new_RE(
  [qr'\bEICAR\b'i => 0],            # av test pattern name
  [qr/.*/ => 1],  # true for everything else
));
 
@keep_decoded_original_maps = (new_RE(
  qr'^MAIL-UNDECIPHERABLE$', # recheck full mail if it contains undecipherables
  qr'^(ASCII(?! cpio)|text|uuencoded|xxencoded|binhex)'i,
));
 
$banned_filename_re = new_RE(
  qr'\.[^./]*\.(exe|vbs|pif|scr|bat|cmd|com|cpl|dll)\.?$'i,
 
  qr'\{[0-9a-f]{8}(-[0-9a-f]{4}){3}-[0-9a-f]{12}\}?$'i, # Windows Class ID CLSID, strict
 
  qr'^application/x-msdownload$'i,                  # block these MIME types
  qr'^application/x-msdos-program$'i,
  qr'^application/hta$'i,
 
 
  qr'.\.(exe|vbs|pif|scr|bat|cmd|com|cpl)$'i, # banned extension - basic
 
  qr'^\.(exe-ms)$',                       # banned file(1) types
);
 
@score_sender_maps = ({ # a by-recipient hash lookup table,
                        # results from all matching recipient tables are summed
 
  '.' => [  # the _first_ matching sender determines the score boost
 
   new_RE(  # regexp-type lookup table, just happens to be all soft-blacklist
    [qr'^(bulkmail|offers|cheapbenefits|earnmoney|foryou)@'i         => 5.0],
    [qr'^(greatcasino|investments|lose_weight_today|market\.alert)@'i=> 5.0],
    [qr'^(money2you|MyGreenCard|new\.tld\.registry|opt-out|opt-in)@'i=> 5.0],
    [qr'^(optin|saveonlsmoking2002k|specialoffer|specialoffers)@'i   => 5.0],
    [qr'^(stockalert|stopsnoring|wantsome|workathome|yesitsfree)@'i  => 5.0],
    [qr'^(your_friend|greatoffers)@'i                                => 5.0],
    [qr'^(inkjetplanet|marketopt|MakeMoney)\d*@'i                    => 5.0],
   ),
 
   { # a hash-type lookup table (associative array)
   },
  ],  # end of site-wide tables
});
 
1;  # ensure a defined return

2. /etc/amavis/conf.d/50-user открыть закрыть

use strict;
 
@lookup_sql_dsn = ( ['DBI:mysql:database=mailserver;host=127.0.0.1;port =3306', 'mailuser', 'password-for-mailuser']);
$sql_select_policy = 'SELECT name FROM virtual_domains WHERE CONCAT("@",name) IN (%k)';
 
$max_servers = 4;
 
$mailfrom_to_quarantine = ''; # null return path; uses original sender if undef
 
$bad_header_quarantine_method = undef;
 
$spam_quarantine_method = undef;
 
$banned_files_quarantine_method = undef;
 
#------------ Do not modify anything below this line -------------
1;  # ensure a defined return

Настройка Postgrey. Указываем слушать порт 10023:

nano /etc/default/postgrey
POSTGREY_OPTS="--inet=10023"

Настройка правил для Fail2ban:

/etc/fail2ban/jail.conf открыть закрыть

##
## Убедитесь, что путь к логам соответствует действительности
##
 
[ssh-iptables]
enabled  = true
filter   = sshd
action   = iptables[name=SSH, port=ssh, protocol=tcp]
logpath  = /var/log/secure
maxretry = 5
 
[postfix-banhammer]
enabled  = true
filter   = postfix
action   = iptables-multiport-tcp[name=PFIX, port="smtp,smtps", protocol=tcp]
logpath  = /var/log/maillog
maxretry = 3
bantime  = 7200
 
[dovecot-banhammer]
enabled  = true
filter   = dovecot
action   = iptables-multiport-tcp[name=DCOT, port="pop3,pop3s,imap,imaps", protocol=tcp]
logpath  = /var/log/maillog
findtime = 300
maxretry = 10
bantime  = 1800
 
[sasl-banhammer]
enabled  = true
filter   = sasl
action   = iptables-multiport-tcp[name=SASL, port="smtp,smtps", protocol=tcp]
logpath  = /var/log/maillog
findtime = 300
maxretry = 10
bantime  = 1800

На этом пока все.

0 комментариев

Оставить комментарий: