Установка postfix dovecot postfixadmin в OS Debian
Задача:
Необходимо поднять почтовый сервер на котором будет крутиться связка Postfix + Dovecot. Виртуальные почтовые домены с индивидуальными (или на домен) квотами. С адекватной проверкой на вирусы и спам (остечение postgrey + на уровне SMTP-сессии + spamassassin). Так же организуем доступ пользователей через веб-интерефейс и управление пользователями так же через вебморду.
Решение:
Устанавливаем пакеты
Postifx, Dovecot, postgrey, amavis, spamassassin, roundcube, postfixadmin.
Установка
Поставим все необходимые пакеты:
apt-get install postfix postfix-mysql dovecot-mysql dovecot-sieve dovecot-pop3d dovecot-imapd amavisd-new \ libclass-dbi-mysql-perl spamassassin clamav clamav-daemon postgreyНастройка: В /etc/hostname должно быть имя сервера без доменной части. А в /etc/mailname наоборот - fqdn имя.
root@mx:~# cat /etc/hostname mx
root@mx:~# cat /etc/mailname mx.example.comЗамечание: опытным путем проверенно что hostname может быть любым, главное чтобы в mailname было прописан доменное имя, которое написано в MX-записи домена для которого делаем почту (Например: mail.example.com)
Файлик /etc/hosts
92.122.190.40 mx.example.com mx Создадим пользователя от имени которого будет работать postfix и dovecot.
groupadd -g 5000 vmail useradd -g vmail -u 5000 vmail -d /vmail -mНеобходимо сгенерировать сертификаты для работы почтового сервера. (для подключения пользователей с использованием SSL) Сгенерируем сертификаты
mkdir /etc/postfix/certs cd /etc/postfix/certs touch openssl.cnfВпишем
[req] default_bits = 4096 # Длинна ключа в битах. default_keyfile = key.pem # Имя файла, в который будет записан закрытый ключ. encrypt_key = no # Нам не нужно шифровать закрытый ключ паролем. default_md = sha512 # Алгоритм хеша. x509_extensions = v3_req # Включаем расширение V3. prompt = no # Не нужно запрашивать данные у пользователя, мы всё пропишем здесь. distinguished_name = req_distinguished_name # Имя секции с данными (может быть любым). [req_distinguished_name] C = Country # Двухбуквенный код страны L = Locality # Город O = Organization # Название организации CN = mail.example.com # Имя домена emailAddress = postmaster@example.com # Адрес электронной почты # Можно ещё указать следующие поля: # ST (State - штат, название провинции и т.п.) # OU (Organizational Unit - название подразделения) [v3_req] # Список альтернативных имён. Можно указать прямо здесь, но это не # удобно, особенно если их много, так что мы указываем название секции # с именами. subjectAltName = @alt_names [alt_names] # Имена. Можно указать хоть сколько, главное чтобы цифры после точки были разными. DNS.0 = example.com DNS.1 = www.example.comЕстественно, заменив значения на свои. Теперь сообственно сгенерируем сами сертификаты
openssl req -new -x509 -days 36500 -config openssl.cnf -out cert.pem -outform PEM -keyout key.pem -keyform PEMУдалим файл настроек
rm -f openssl.cnfПерейдем на настройкам postfix. Приведем main.cf к такому виду
# See /usr/share/postfix/main.cf.dist for a commented, more complete version # Debian specific: Specifying a file name will cause the first # line of that file to be used as the name. The Debian default # is /etc/mailname. #myorigin = /etc/mailname smtpd_banner = $myhostname ESMTP $mail_name (Debian/GNU) 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 = no # ================= # TLS parameters # ================= smtp_tls_security_level = may smtpd_tls_security_level = may smtpd_tls_received_header = yes smtpd_tls_session_cache_timeout = 3600s smtpd_tls_cert_file = /etc/postfix/certs/cert.pem smtpd_tls_key_file = /etc/postfix/certs/key.pem smtpd_use_tls = yes smtpd_tls_session_cache_database = btree:${data_directory}/smtpd_scache smtp_tls_session_cache_database = btree:${data_directory}/smtp_scache tls_random_source = dev:/dev/urandom # ================= # GENEREAL # ================= myhostname = mail.example.com #alias_maps = hash:/etc/aliases #alias_database = hash:/etc/aliases myorigin = /etc/mailname mydestination = $myhostname, localhost.$mydomain, localhost relayhost = mynetworks = 127.0.0.0/8 [::ffff:127.0.0.0]/104 [::1]/128 mailbox_command = procmail -a "$EXTENSION" mailbox_size_limit = 0 recipient_delimiter = + inet_interfaces = all max_use = 500 disable_vrfy_command = yes soft_bounce = no # ================ # SASL # ================ smtpd_sasl_auth_enable = yes broken_sasl_auth_clients = yes smtpd_sasl_authenticated_header = yes smtpd_sasl_tls_security_options = $smtpd_sasl_security_options smtpd_sasl_security_options = noanonymous smtpd_sasl_type = dovecot smtpd_sasl_path = private/auth smtpd_helo_required = yes smtpd_delay_reject = yes smtpd_discard_ehlo_keywords = etrn, silent-discard smtpd_recipient_limit = 10 smtpd_sender_login_maps = mysql:/etc/postfix/mysql-users.cf # ================= # VIRTUAL # ================= virtual_mailbox_domains = mysql:/etc/postfix/mysql-virtual-mailbox-domains.cf 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,mysql:/etc/postfix/mysql-virtual-alias-domain-maps.cf virtual_uid_maps = static:5000 virtual_gid_maps = static:5000 virtual_transport = dovecot dovecot_destination_recipient_limit = 1 # ================= # LIMITS # ================= message_size_limit = 51200000 smtpd_client_connection_count_limit = 20 smtpd_client_connection_rate_limit = 30 # ================= # QUEUE # ================= maximal_queue_lifetime = 1d bounce_queue_lifetime = 1d # ================= # RULES # ================= smtpd_client_restrictions = permit_mynetworks, check_client_access hash:/etc/postfix/sender_access, permit_sasl_authenticated, reject_unknown_reverse_client_hostname, warn_if_reject reject_unknown_client smtpd_helo_restrictions = permit_mynetworks, check_helo_access hash:/etc/postfix/sender_access, reject_invalid_helo_hostname, reject_unknown_helo_hostname, reject_non_fqdn_helo_hostname smtpd_sender_restrictions = permit_mynetworks, check_sender_access hash:/etc/postfix/sender_access, permit_sasl_authenticated, reject_non_fqdn_sender, reject_unverified_sender, reject_unauthenticated_sender_login_mismatch, reject_unknown_sender_domain smtpd_recipient_restrictions = permit_mynetworks, check_recipient_access hash:/etc/postfix/recipient_access, permit_sasl_authenticated, reject_non_fqdn_recipient, reject_unknown_recipient_domain, reject_multi_recipient_bounce, reject_unauth_destination, reject_unlisted_recipient, check_policy_service inet:127.0.0.1:10023 smtpd_data_restrictions = reject_unauth_pipelining # ================= # AMAVIS # ================= content_filter = smtp-amavis:[127.0.0.1]:10024 добавим в master.cf поддержку submission (это позволит работать postfix по 587 порту). Добавляем сразу после smtp. submission inet n - n - - smtpd -o syslog_name=postfix/submission -o smtpd_tls_wrappermode=no -o smtpd_tls_security_level=encrypt -o smtpd_sasl_auth_enable=yes -o smtpd_recipient_restrictions=permit_mynetworks,permit_sasl_authenticated,reject -o milter_macro_daemon_name=ORIGINATING так же добавим, что dovecot будет заниматься доставкой писем по ящикам. Добавим в конец файла. dovecot unix - n n - - pipe flags=DRhu user=vmail:vmail argv=/usr/lib/dovecot/deliver -d ${recipient} так же добавим поддержку amavis и postgrey smtp-amavis unix - - n - 2 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 - - - - smtpd -o content_filter= -o local_recipient_maps= -o relay_recipient_maps= -o smtpd_restriction_classes= -o smtpd_delay_reject=no -o mynetworks=127.0.0.0/8 -o smtpd_client_restrictions=permit_mynetworks,permit_sasl_authenticated,reject -o smtpd_helo_restrictions= -o smtpd_sender_restrictions= -o smtpd_recipient_restrictions=permit_mynetworks,permit_sasl_authenticated,reject -o smtpd_data_restrictions=reject_unauth_pipelining -o smtpd_end_of_data_restrictions= -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_address_mappings -o local_header_rewrite_clients=
Добавим файлы с запросами, для работы виртуальных доменов, пользователей, алиасов. Подставьте вместо
HOST = адрес MySQL сервера DB = имя базы данных USER = имя пользоватья для подключения в базе PASSWORD = его пароль Примечание: используйте в DB вместо localhost, 127.0.0.1. Иначе не взлетит!
mysql-email2email.cf user = USER password = PASSWORD hosts = HOST dbname = DB query = select username from mailbox where username = '%s' mysql-users.cf user = USER password = PASSWORD hosts = HOST dbname = DB query = select username from mailbox where username='%s' AND active = '1' mysql-virtual-alias-domain-maps.cf user = USER password = PASSWORD hosts = HOST dbname = DB query = select goto from alias,alias_domain where alias_domain.alias_domain = '%d' and alias.address = concat('%u', '@', alias_domain.target_domain) and alias.active = '1' mysql-virtual-alias-maps.cf user = USER password = PASSWORD hosts = HOST dbname = DB query = select goto from alias where address='%s' mysql-virtual-mailbox-domains.cf user = USER password = PASSWORD hosts = HOST dbname = DB query = select domain from domain where domain='%s' mysql-virtual-mailbox-maps.cf user = USER password = PASSWORD hosts = HOST dbname = DB query = select username from mailbox where username='%s' AND active = '1'Наведем порядок с правами на созданные файлы
chgrp postfix /etc/postfix/mysql-*.cf chmod u=rw,g=r,o= /etc/postfix/mysql-*.cfСоздадим файл белых списков для получателей и отправителей
touch /etc/postfix/sender_access touch /etc/postfix/recipient_access postmap /etc/postfix/sender_access postmap /etc/postfix/recipient_accessЗаписи в этих файлах должны выглядеть таким образом
example.com REJECT you are not in my local networks example.com OK Перейдем к настройке Dovecot. Приступим к редактированию его конфигов в /etc/dovecot/conf.d
10-auth.conf disable_plaintext_auth = no auth_realms = example.com auth_mechanisms = plain login #!include auth-system.conf.ext !include auth-sql.conf.ext example.com замените на свой домен, который Вы прописывали в /etc/mailname 10-logging.conf log_path = syslog syslog_facility = mail 10-mail.conf mail_location = maildir:/vmail/%d/%n/Maildir mail_uid = 5000 mail_gid = 5000 mail_plugins = quota namespace inbox { # Namespace type: private, shared or public type = private # Hierarchy separator to use. You should use the same separator for all # namespaces or some clients get confused. '/' is usually a good one. # The default however depends on the underlying mail storage format. separator = . # Prefix required to access this namespace. This needs to be different for # all namespaces. For example "Public/". prefix = # Physical location of the mailbox. This is in same format as # mail_location, which is also the default for it. #location = # There can be only one INBOX, and this setting defines which namespace # has it. inbox = yes # If namespace is hidden, it's not advertised to clients via NAMESPACE # extension. You'll most likely also want to set list=no. This is mostly # useful when converting from another server with different namespaces which # you want to deprecate but still keep working. For example you can create # hidden namespaces with prefixes "~/mail/", "~%u/mail/" and "mail/". #hidden = no # Show the mailboxes under this namespace with LIST command. This makes the # namespace visible for clients that don't support NAMESPACE extension. # "children" value lists child mailboxes, but hides the namespace prefix. #list = yes # Namespace handles its own subscriptions. If set to "no", the parent # namespace handles them (empty prefix should always have this as "yes") #subscriptions = yes } 10-master.conf service imap-login { inet_listener imap { port = 143 } inet_listener imaps { port = 993 ssl = yes } # Number of connections to handle before starting a new process. Typically # the only useful values are 0 (unlimited) or 1. 1 is more secure, but 0 # is faster. #service_count = 1 # Number of processes to always keep waiting for more connections. #process_min_avail = 0 # If you set service_count=0, you probably need to grow this. #vsz_limit = $default_vsz_limit } service pop3-login { inet_listener pop3 { port = 110 } inet_listener pop3s { port = 995 ssl = yes } } service auth { # auth_socket_path points to this userdb socket by default. It's typically # used by dovecot-lda, doveadm, possibly imap process, etc. Users that have # full permissions to this socket are able to get a list of all usernames and # get the results of everyone's userdb lookups. # # The default 0666 mode allows anyone to connect to the socket, but the # userdb lookups will succeed only if the userdb returns an "uid" field that # matches the caller process's UID. Also if caller's uid or gid matches the # socket's uid or gid the lookup succeeds. Anything else causes a failure. # # To give the caller full permissions to lookup all users, set the mode to # something else than 0666 and Dovecot lets the kernel enforce the # permissions (e.g. 0777 allows everyone full permissions). unix_listener auth-userdb { #mode = 0666 #user = #group = } # Postfix smtp-auth unix_listener /var/spool/postfix/private/auth { mode = 0666 user = vmail } # Auth process is run as this user. #user = $default_internal_user } service dict { # If dict proxy is used, mail processes should have access to its socket. # For example: mode=0660, group=vmail and global mail_access_groups=vmail unix_listener dict { mode = 0600 user = vmail #group = } } 10-ssl.conf ssl = yes ssl_cert = </etc/postfix/certs/cert.pem ssl_key = </etc/postfix/certs/key.pem 15-lda.conf postmaster_address = postmaster@example.com quota_full_tempfail = yes lda_mailbox_autocreate = yes lda_mailbox_autosubscribe = yes mail_plugins = $mail_plugins autocreate sieve 15-mailboxes.conf # These mailboxes are widely used and could perhaps be created automatically: mailbox Drafts { auto = subscribe special_use = \Drafts } mailbox Junk { auto = subscribe special_use = \Junk } mailbox Trash { auto = subscribe special_use = \Trash } # For \Sent mailboxes there are two widely used names. We'll mark both of # them as \Sent. User typically deletes one of them if duplicates are created. mailbox Sent { auto = subscribe special_use = \Sent } 20-imap.conf mail_plugins = $mail_plugins autocreate imap_quota 90-quota.conf quota_rule = *:storage=1G quota_warning = storage=95%% quota-warning 95 %u quota_warning2 = storage=80%% quota-warning 80 %u service quota-warning { executable = script /usr/local/bin/quota-warning.sh user = dovecot unix_listener quota-warning { user = vmail } } plugin { #quota = dirsize:User quota #quota = maildir:User quota quota = dict:User quota::proxy::quota #quota = fs:User quota } 90-sieve.conf sieve_default = /vmail/globalsieverc sieve_before = /vmail/globalsieverc Теперь вернемся в /etc/dovecot dovecot-sql.conf.ext driver = mysql connect = host=HOST dbname=DB user=USER password=PASSWORD default_pass_scheme = MD5-CRYPT password_query = SELECT username as user, password FROM mailbox WHERE username = '%u' user_query = SELECT '/vmail/%d/%n' AS home, 5000 AS uid, 5000 AS gid, CONCAT('*:bytes=', CAST(quota AS CHAR)) AS quota_rule FROM mailbox WHERE username = '%u' AND active = '1' dovecot-dict-sql.conf.ext connect = host=HOST dbname=DB user=USER password=PASSWORDв connect замените
HOST = адрес MySQL сервера DB = имя базы данных USER = имя пользоватья для подключения в базе PASSWORD = его пароль тут так же заменить в двух местах
table = quota на
table = quota2 так же закомментируем
#map { # pattern = shared/expire/$user/$mailbox # table = expires # value_field = expire_stamp # # fields { # username = $user # mailbox = $mailbox # } #} dovecot.conf quota = mysql:/etc/dovecot/dovecot-dict-sql.conf.extСоздадим скрипт оповещения пользователей о превышении квоты
/usr/local/bin/quota-warning.sh #!/bin/sh PERCENT=$1 FROM="postmaster@example.com" USER=$2 cat << EOF | /usr/sbin/sendmail -f $FROM $USER From: postmaster@nuft.edu.ua Subject: quota warning Your mailbox is now $PERCENT% full. EOF chmod +x /usr/local/bin/quota-warning.sh && chown dovecot: /usr/local/bin/quota-warning.sh
Настройка антиспам
Раскоментируем строчки в
/etc/amavis/conf.d/15-content_filter_mode @bypass_virus_checks_maps = ( \%bypass_virus_checks, \@bypass_virus_checks_acl, \$bypass_virus_checks_re); @bypass_spam_checks_maps = ( \%bypass_spam_checks, \@bypass_spam_checks_acl, \$bypass_spam_checks_re);Подправим пороговые значения для определения спама, а так же сделаем чтобы письма со спамом не отсекались, а пропускались. Потом настроим чтобы они складывались пользователю в папку спам.
/etc/amavis/conf.d/20-debian_defaults $sa_tag2_level_deflt = 4; # add 'spam detected' headers at that level $sa_kill_level_deflt = 4; # triggers spam evasive actions $final_spam_destiny = D_PASS;Желательно так же добавить виртуальные домены в whitelist, для того чтобы они точно не распознавались как спам
# This are some examples for whitelists, since envelope senders can be forged # they are not enabled by default. { # a hash-type lookup table (associative array) '.example.com' => -20.0, Так как у нас установлен только ClamAV, оставим только его как основной сканер на вирусы. Приведем конфиг к такому виду. 15-av_scanners use strict; ## ## AV Scanners (Debian version) ## @av_scanners = ( # ### http://www.clanfield.info/sophie/ (http://www.vanja.com/tools/sophie/) # ['Sophie', # \&ask_daemon, ["{}/\n", '/var/run/sophie'], # qr/(?x)^ 0+ ( : | [\000\r\n]* $)/m, qr/(?x)^ 1 ( : | [\000\r\n]* $)/m, # qr/(?x)^ [-+]? \d+ : (.*?) [\000\r\n]* $/m ], # ### http://www.csupomona.edu/~henson/www/projects/SAVI-Perl/ # ['Sophos SAVI', \&sophos_savi ], ### http://www.clamav.net/ ['ClamAV-clamd', \&ask_daemon, ["CONTSCAN {}\n", "/var/run/clamav/clamd.ctl"], qr/\bOK$/m, qr/\bFOUND$/m, qr/^.*?: (?!Infected Archive)(.*) FOUND$/m ], # NOTE: run clamd under the same user as amavisd, or run it under its own # uid such as clamav, add user clamav to the amavis group, and then add # AllowSupplementaryGroups to clamd.conf; # NOTE: match socket name (LocalSocket) in clamav.conf to the socket name in # this entry; when running chrooted one may prefer socket "$MYHOME/clamd". ); @av_scanners_backup = ( ### http://www.clamav.net/ - backs up clamd or Mail::ClamAV ['ClamAV-clamscan', 'clamscan', "--stdout --no-summary -r --tempdir=$TEMPBASE {}", [0], qr/:.*\sFOUND$/m, qr/^.*?: (?!Infected Archive)(.*) FOUND$/m ], ); 1; # ensure a defined return 50-userперед
#------------ Do not modify anything below this line ------------- 1; # ensure a defined return вставим @lookup_sql_dsn = ( ['DBI:mysql:database=DB;host=HOST;port=3306', 'USER', 'PASSWORD']); $sql_select_policy = 'SELECT domain FROM domain WHERE CONCAT("@",domain) IN (%k)';Для того чтобы не было проблем с правами доступа, в меняем в файле
/etc/clamav/clamd.conf User amavis LocalSocketGroup amavisа так же в
/etc/clamav/freshclam.confDatabaseOwner amavis добавляем пользователя amavis в группу clamav и наоборот, затем меняем владельца папки /var/log/clamav/
usermod -a -G amavis clamav usermod -a -G clamav amavis chown -R amavis:amavis /var/log/clamavв файл /etc/default/spamassassin
ENABLED=1 Для того чтобы письма класифицированные как спам откладывались в специальную папку и не получались почтовым клиентом, но оставалась возможность их просмотреть с помощью веб-интерфейса, создаем файл
/vmail/globalsieverc
require ["fileinto"]; # Move spam to spam folder if header :contains "X-Spam-Flag" ["YES"] { fileinto "Junk"; stop; }Файл должен пренадлежать полльзователю vmail.
chown vmail: /vmail/globalsievercпопдправим на последок настройки spamassassin и дело в шляпе
/etc/spamassassin/local.cf
rewrite_header Subject *****SPAM***** report_safe 0 required_score 4.0 use_bayes 1 bayes_auto_learn 0 bayes_ignore_header X-Bogosity bayes_ignore_header X-Spam-Flag bayes_ignore_header X-Spam-Status <code> Перед <code> endif # Mail::SpamAssassin::Plugin::Shortcircuitдобавим
score DEAR_SOMETHING 5 score T_DKIM_INVALID 1 score HTML_MESSAGE 0.5 score MISSING_MID 1 score FORGET_MUA_OUTLOOK 2.199 2.199 0.963 1.116 score FH_DATE_PAST_20XX 0.0 score DOS_OE_TO_MX_IMAGE 0.0 score DOS_OE_TO_MX 0.0 score DOT_OUTLOOK_TO_MX 0.0 score TO_NO_BRKTS_DIRECT 0.0 score HELO_LOCALHOST 0.0 score FSL_RU_URL 0.0 score FROM_MISSP_EH_MATCH 1.0 score TVD_RCVD_SINGLE 1.0 score TO_IN_SUBJ 1.0 # # TUNING # score SUBJ_FULL_OF_8BITS 0.00 score HTML_COMMENT_8BITS 0.01 score HEADER_8BITS 0.00 score TO_NO_USER 0.01 score FORGED_MUA_OUTLOOK 0.5 score X_AUTH_WARNING 0.01 score SUBJ_HAS_UNIQ_ID 9.99 score HTTP_USERNAME_USED 9.99 score FORGED_YAHOO_RCVD 9.99 score FORGED_JUNO_RCVD 16 score UNWANTED_LANGUAGE_BODY 1.02 score MLM 5.55 score RCVD_NUMERIC_HELO 4.95 # # WHITE/BLACK LISTS # whitelist_from root@localhost whitelist_from *@example.com blacklist_from *@outblaze.com auto_whitelist_path /etc/mail/spamassassin/auto-whitelist auto_whitelist_file_mode 0666В конфиге выше, whitelist_from *@example.com замените example.com на свой домен
Перезапускаем демоны, чтобы изменения вступили в силу
service clamav-daemon restart service clamav-freshclam restart service amavis restart service spamassassin startПервые две-три недели spamassassin надо будет пообучать, а потом вместе с postgrey они будут пропускать примерно один спам в день. Данного набора вполне достаточно для эффективной борьбы со спамом. Особенно хочу выразить свою гражданскую позицию относительно спамхауса: у системных администраторов, которые используют спамхаус, бабушки работали вахтерами на заводских проходных!
К слову
В виду базовости настроек postifx'a пришлось сильно его допилить на дополнительные проверки на отсекание спама. Чтобы снизить нагрузку на сервер (amavis жрет нормально так), мы будем проверять средствами postfix входящие письма на соответсвие RFC.
Варианты фильтров
Обратная DNS запись (PTR запись). Считается правилом хорошего тона, когда администратор назначает каждому хосту обратную (PTR) запись. Кроме того, считается таким же хорошим тоном, когда обратная запись запись совпадает с прямой (А) записью.
N.B. При настройке своего почтового сервера потрудитесь, чтобы обратная запись совпадала с прямой. Т.е. если Вы, сделав dig -x (команда для *nix среды), для хоста 256.155.148.244 получили ответ mx.example.com, то и прямая запись mx.example.com должна указывать на 256.155.148.244. В противном случае не удивляйтесь если половина почтовых серверов откажется принимать Ваши письма. PTR запись прописывается у владельца блока IP адресов, скорее всего это Ваш провайдер.
Отсутствие обратной записи у сервера отправителя косвенно указывает на то, что сообщение является спамом. Вы не найдете ни одного сервера gmail, yahoo, mail.ru, yandex.ru и т.д., которые бы не имели обратной записи. И, хотя, теоретически отсутствие обратной записи не может служить критерием для оценки спамности письма, но как показывает практика в 99% случаев обратная запись отсутствует именно у хостов рассылающих спам, поэтому по отсутствию обратной записи у отправителя вполне можно отсеивать спам, а сталкиваясь с оставшимся 1% – заносить их в список исключений. Соответствующие директивы в конфиге postfix: reject_unknown_client.
HELO/EHLO. RFC прямо не обязывает, но рекомендует отправителям начинать SMTP сессию с HELO, в котором указано полноценное доменное имя (fully qualified domain name или сокращенно FQDN, например “smtp.example.com”). И, хотя, нет прямого обязательства это делать, но как и в случае с обратной записью передача в HELO неполноценного доменного имени (например “example”) или передача несуществующего доменного имени де-факто стали косвенными указателями на то, что письмо является спамом. Соответствующие директивы в конфиге postfix: reject_invalid_hostname, reject_non_fqdn_hostname, reject_unknown_hostname.
N.B. При настройке своего почтового сервера потрудитесь, чтобы в HELO Ваш сервер отдавал то, что прописано в PTR записи… Ведь материал выше Вы читали внимательно и PTR запись и А запись у Вас уже совпадают, не так ли? ;)
MAIL FROM. Как мы выяснили, в команде mail from отправитель передаёт получателю имя почтового ящика того, кто отправил письмо. Если в mail from указан почтовый адрес, даже домен которого не существует (напримерuser@sn7y3t5iuhncuhg84dnh4875nf5.com), стоит ли нам принимать такое письмо? Однозначно нет. В ходе SMTP сессии мы можем проверить существование домена и, при его отсутствии, смело отвергнуть сообщение. Кроме того, если окажется что домен существует, мы можем проверить наличие указанного почтового ящика в домене отправителя (практически все MTA это умеют делать, называется “sender verify”). Для этого получатель создает обратную SMTP сессию в сторону отправителя, которая проходит три стадии: helo, mail from, rcpt to и не доходя до data завершается. Представим, что получатель в ходе SMTP сессии получил “mail from:snduser@examplesender.com”. В рамках проверки “sender verify” получатель инициирует SMTP сессию назад в сторону отправителя, где в rcpt to передает “rcpt to:snduser@examplesender.com”. Если он получает ответ 250 (продолжайте), то все ок – отправитель существует. Если же получает “550″ (user unknown), значит отправитель не существует и нам шлют письмо с поддельным адресом отправителя и это письмо можно отвергнуть. Но здесь палка о двух концах: с одной стороны поддельный адрес – это нехорошо, это скорее всего спам. С другой стороны существует немало честных рассылок, правда настроенных непонятно кем, когда рассылка идет с несуществующего адреса. И фильтровать такие рассылки только потому, что они криво настроены тоже не вариант. В общем стоит ли использовать sender verify или нет – мнения разделяются, но я бы рекомендовал все-таки включить sender verify, а сталкиваясь с криво настроенными рассылками – добавлять их в список исключений. Соответствующие директивы в конфиге postfix: reject_non_fqdn_sender, reject_unknown_sender_domain, reject_unverified_sender.
N.B. Если Вы настраиваете почтовую рассылку, которая не требует ответов, то потрудитесь создать почтовый ящик от имени которого идёт рассылка. Можете не читать его, можете планировщиком (например cron для *nix) удалять из него сообщения каждую ночь, можете что хотите делать с сообщениями в этом ящике, ноящик должен существовать.
RCPT TO. На стадии rcpt to мы получаем адрес того, кому предназначено письмо. Данные из rcpt to мы можем точно также подвергнуть проверке, как и helo, и mail from. Что же мы можем проверить? Мы можем проверить правильно ли указан адрес получателя, является ли он FQDN адресом. Обслуживаем ли мы домен, на ящик которого нам собираются передать письмо. Существует ли в обслуживаемом нами домене ящик, на который собираются передать письмо. Если почтовый ящик получателя не являет собой FQDN имя (например rcvuser@examplereceiver вместо rcvuser@examplereceiver.com), то такое письмо можно отклонить. Если нам передают письмо для пользователя из домена, который мы не обслуживаем (напримерsomeuser@somedomain.com), то его мы тоже отклоняем. Тоже самое с несуществующими пользователями в локальных доменах – отклоняем. Соответствующие директивы в конфиге postfix: reject_non_fqdn_recipient,reject_unauth_destination, reject_unlisted_recipient.
DNSBL. Суть работы фильтра DNSBL сводится к тому, принимающая сторона может проверить наличие/отсутствие IP адреса отправляющей стороны в черном списке и принять решения что делать с письмом. При этом, обычно, держателем черных списков выступает третья сторона. Соответствующие директивы в конфиге postfix:reject_rbl_client. Внимание! Никогда не используйте эту опцию!
Greylisting. Серый список. Работа грейлистинга основывается на том, что поведение клиентов рассылающих спам отличается от поведения честных почтовых серверов. В ходе SMTP сессии грейлист отдает клиенту ошибку с кодом (4xx), который означает “временная ошибка, попробуйте повторить позже”. Честный почтовый сервер через время обязательно предпримет попытку повторной доставки, поскольку умеет держать очередь почтовых сообщений. Спамеры же в свою очередь очередей не держат, это продиктовано огромными объемами рассылок, для них держать очередь сообщений просто нецелесообразно. В итоге получается так, что честное письмо немного задерживается (обычно 15-30 мин), затем отправитель заносится в белый список как честный отправитель и в последствии сообщения от него приходят без задержек. Спамеры же отсеиваются, не предпринимая попытки повторной доставки. Соответствующие директивы в конфиге postfix: check_policy_service.
Контент-фильтры. До этого мы рассматривали варианты фильтрации, когда фильтры оперируют данными из начальных стадий SMTP сессии. Контент фильтры же в свою очередь анализируют тело письма. Примеры контент-фильтров: ClamAV, Spamassassin, DSPAM.
Как фильтровать правильно?
Перед всеми фильтрами стоит добавить собственный белый список. В этот список Вы будете заносить честные сервера, которые неправильно настроены и из-за этого отфильтровываются. Их будет крайне мало, но они будут.
Проверка
Для того чтобы проверить работу антиспама и антивируса, просто отправте на виртуальный домен с другого ящика письмо с таким текстом:
антивирус
X5O!P%@AP[4\PZX54(P^)7CC)7}$EICAR-STANDARD-ANTIVIRUS-TEST-FILE!$H+H* антиспам
XJS*C4JDBQADN1.NSBN3*2IDNEN*GTUBE-STANDARD-ANTI-UBE-TEST-EMAIL*C.34X Postfixadmin
И на последок настроим управление виртуальными доменами и их почтовыми ящиками через вебморду.
Скачаем последнюю версию в сайта
http://sourceforge.net/projects/postfixadmin/
Копирование и настройка виртуального домена под postfixadmin оставляю за вами. Тут я только опишу настройку самого postfixadmin.
config.inc.php $CONF['configured'] = true; $CONF['setup_password'] = 'changeme'; $CONF['default_language'] = 'ru'; $CONF['database_type'] = 'mysqli'; $CONF['database_host'] = 'HOST'; $CONF['database_user'] = 'USER'; $CONF['database_password'] = 'PASSWORD'; $CONF['database_name'] = 'DB'; $CONF['admin_email'] = 'admin@example.com'; $CONF['smtp_server'] = 'mail.example.com'; $CONF['page_size'] = '20'; $CONF['default_aliases'] = array ( 'abuse' => 'abuse@nuft.edu.ua', 'hostmaster' => 'hostmaster@nuft.edu.ua', 'postmaster' => 'postmaster@nuft.edu.ua', 'webmaster' => 'webmaster@nuft.edu.ua' ); $CONF['quota'] = 'YES'; $CONF['used_quotas'] = 'YES'; $CONF['vacation_domain'] = 'autoreply.example.com'; $CONF['footer_text'] = 'Return to example.com'; $CONF['footer_link'] = 'http://example.com';Где подставим
HOST = адрес MySQL сервера DB = имя базы данных USER = имя пользоватья для подключения в базе PASSWORD = его пароль Еще момент
По умолчанию, postfixadmin не физически удаляет ящики после удаления из базы. В config.inc.php есть опции предусмотренные для исправления такой ситуации, но это будет работать только если postfixadmin установлен на том же сервере где и вся почтовая система. У меня разнесенная архитектура, потому для меня такой вариант не подходит, потому на просторах интернета был найден скрипт, который по cron'у запускается каждую ночь и ищет ящики которых нет в базе, но которые есть на сервере. После такой сверки он «подчищает» после postfixadmin'a следы. Сообщественно установить скрипт можно вот так:
wget http://thelinuxforce.org/upload/files/cleanupdirs.tar tar xvf cleanupdirs.tar cp -f cleanupdirs.pl /usr/local/sbin/ chmod +x /usr/local/sbin/cleanupdirs.pl touch /var/log/removed_maildirs.logВ самом скрипте нужно поправить подключение к базе данных postfixadmin по аналогии как мы делали раньше.
Далее установим задачу для cron
crontab -e добавим туда
30 0 * * * /usr/local/sbin/cleanupdirs.pl
Смотрите также:
http://thelinuxforce.org/article/32
Рекомендуем ознакомится с нашим продуктом-Виртуальная облачная инфраструктура IaaS
Актуальность: 2015/12/22 14:20