/etc/postfix/main.cf
.
mail.falcot.com
. Это единственный вопрос, задаваемый по-умолчанию, однако та конфигурация, которая с его помощью создаётся, не является достаточно полной для нужд Falcot, поэтому администраторы запускают команду dpkg-reconfigure postfix
для того, чтобы настроить больше параметров.
localhost
, но основной домен falcot.com
нужно добавить вручную. В общем, это все доменные имена, для который машина является MX сервером, другими словами — все доменные имена, для которых в DNS указано, что эта машина принимает электронную почту. Эта информация завершается переменной mydestination
в основном конфигурационном файле Postfix /etc/postfix/main.cf
.
192.168.0.0/16
для ответа по умолчанию. Если вопрос не задан, подходящая переменная в конфигурационном файле — mynetworks
. Смотрите пример внизу.
procmail
. Этот команда сортирует входящую почту в соответствии с правилами, хранящимися в файле ~/.procmailrc
. И Postfix, и Exim4 предлагают procmail по умолчанию, но есть альтернативы, такие как maildrop или Sieve фильтры.
Пример 11.1. Initial /etc/postfix/main.cf
file
# 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 # See http://www.postfix.org/COMPATIBILITY_README.html -- default to 2 on # fresh installs. compatibility_level = 2 # TLS parameters smtpd_tls_cert_file=/etc/ssl/certs/ssl-cert-snakeoil.pem smtpd_tls_key_file=/etc/ssl/private/ssl-cert-snakeoil.key smtpd_tls_security_level=may smtp_tls_CApath=/etc/ssl/certs smtp_tls_security_level=may smtp_tls_session_cache_database = btree:${data_directory}/smtp_scache smtpd_relay_restrictions = permit_mynetworks permit_sasl_authenticated defer_unauth_destination myhostname = mail.falcot.com alias_maps = hash:/etc/aliases alias_database = hash:/etc/aliases mydestination = mail.falcot.com, falcot.com, localhost.localdomain, localhost relayhost = mynetworks = 127.0.0.0/8 [::ffff:127.0.0.0]/104 [::1]/128 192.168.0.0/16 mailbox_size_limit = 0 recipient_delimiter = + inet_interfaces = all default_transport = smtp relay_transport = smtp inet_protocols = all myorigin = /etc/mailname
virtual_alias_domains
variable, and referencing an address mapping file in the virtual_alias_maps
variable.
virtual_alias_domains = falcotsbrand.com virtual_alias_maps = hash:/etc/postfix/virtual
/etc/postfix/virtual
file describes a mapping with a rather straightforward syntax: each line contains two fields separated by whitespace; the first field is the alias name, the second field is a list of email addresses where it redirects. The special @domain.com
syntax covers all remaining aliases in a domain.
webmaster@falcotsbrand.com jean@falcot.com contact@falcotsbrand.com laure@falcot.com, sophie@falcot.com # The alias below is generic and covers all addresses within # the falcotsbrand.com domain not otherwise covered by this file. # These addresses forward email to the same user name in the # falcot.com domain. @falcotsbrand.com @falcot.com
/etc/postfix/virtual
the postfix table /etc/postfix/virtual.db
needs to be updated using sudo postmap /etc/postfix/virtual
.
virtual_mailbox_domains
variable, and referencing a mailbox mapping file in virtual_mailbox_maps
. The virtual_mailbox_base
parameter contains the directory under which the mailboxes will be stored.
virtual_mailbox_domains = falcot.org virtual_mailbox_maps = hash:/etc/postfix/vmailbox virtual_mailbox_base = /var/mail/vhosts
virtual_uid_maps
parameter (respectively virtual_gid_maps
) references the file containing the mapping between the email address and the system user (respectively group) that “owns” the corresponding mailbox. To get all mailboxes owned by the same owner/group, the static:5000
syntax assigns a fixed UID/GID (of value 5000 here).
/etc/postfix/vmailbox
file is quite straightforward: two fields separated with whitespace. The first field is an email address within one of the virtual domains, and the second field is the location of the associated mailbox (relative to the directory specified in virtual_mailbox_base). If the mailbox name ends with a slash (/
), the emails will be stored in the maildir format; otherwise, the traditional mbox format will be used. The maildir format uses a whole directory to store a mailbox, each individual message being stored in a separate file. In the mbox format, on the other hand, the whole mailbox is stored in one file, and each line starting with “From
” (From
followed by a space) signals the start of a new message.
# Jean's email is stored as maildir, with # one file per email in a dedicated directory jean@falcot.org falcot.org/jean/ # Sophie's email is stored in a traditional "mbox" file, # with all mails concatenated into one single file sophie@falcot.org falcot.org/sophie
soft_bounce = yes
directive. By prepending a reject-type directive with warn_if_reject
only a log message will be recorded instead of rejecting the request.
smtpd_client_restrictions
directive controls which machines are allowed to communicate with the email server.
Пример 11.2. Restrictions Based on Client Address
smtpd_client_restrictions = permit_mynetworks, warn_if_reject reject_unknown_client_hostname, check_client_access hash:/etc/postfix/access_clientip, reject_rhsbl_reverse_client dbl.spamhaus.org, reject_rhsbl_reverse_client rhsbl.sorbs.net, reject_rbl_client zen.spamhaus.org, reject_rbl_client dnsbl.sorbs.net
permit_mynetworks
directive, used as the first rule, accepts all emails coming from a machine in the local network (as defined by the mynetworks
configuration variable).
warn_if_reject
modifier to the reject_unknown_client
directive: this modifier turns the rejection into a simple warning recorded in the logs. The administrators can then keep an eye on the number of messages that would be rejected if the rule were actually enforced, and make an informed decision later if they wish to enable such enforcement.
check_client_access
directive allows the administrator to set up a blacklist and a whitelist of email servers, stored in the /etc/postfix/access_clientip
file. Servers in the whitelist are considered as trusted, and the emails coming from there therefore do not go through the following filtering rules.
HELO
(or EHLO
) command, followed by the name of the sending email server. Checking the validity of this name can be interesting. To fully enforce the restrictions listed in smtpd_helo_restrictions
the smtpd_helo_required
option needs to be enabled. Otherwise clients could skip the restrictions by not sending any HELO
/EHLO
command.
Пример 11.3. Restrictions on the name announced in EHLO
smtpd_helo_required = yes smtpd_helo_restrictions = permit_mynetworks, reject_invalid_helo_hostname, reject_non_fqdn_helo_hostname, warn_if_reject reject_unknown_helo_hostname, check_helo_access hash:/etc/postfix/access_helo, reject_rhsbl_helo multi.surbl.org
permit_mynetworks
directive allows all machines on the local network to introduce themselves freely. This is important, because some email programs do not respect this part of the SMTP protocol adequately enough, and they can introduce themselves with nonsensical names.
reject_invalid_helo_hostname
rule rejects emails when the EHLO
announce lists a syntactically incorrect hostname. The reject_non_fqdn_helo_hostname
rule rejects messages when the announced hostname is not a fully-qualified domain name (including a domain name as well as a host name). The reject_unknown_helo_hostname
rule rejects messages if the announced name does not exist in the DNS. Since this last rule unfortunately leads to a lot of rejections, the administrators turned its effect to a simple warning with the warn_if_reject
modifier as a first step; they may decide to remove this modifier at a later stage, after auditing the results of this rule.
reject_rhsbl_helo
allows to specify a black list to check the hostname against an RHSBL.
permit_mynetworks
as the first rule has an interesting side effect: the following rules only apply to hosts outside the local network. This allows blacklisting all hosts that announce themselves as part of the falcot.com
network, for instance by adding a falcot.com REJECT You are not in our network!
line to the /etc/postfix/access_helo
file.
MAIL FROM
command of the SMTP protocol; again, this information can be validated in several different ways.
Пример 11.4. Sender checks
smtpd_sender_restrictions = check_sender_access hash:/etc/postfix/access_sender, reject_unknown_sender_domain, reject_unlisted_sender, reject_non_fqdn_sender, reject_rhsbl_sender rhsbl.sorbs.net
/etc/postfix/access_sender
table maps some special treatment to some senders. This usually means listing some senders into a white list or a black list.
reject_unknown_sender_domain
rule requires a valid sender domain, since it is needed for a valid address. The reject_unlisted_sender
rule rejects local senders if the address does not exist; this prevents emails being sent from an invalid address in the falcot.com
domain, and messages emanating from joe.bloggs@falcot.com
are only accepted if such an address really exists.
reject_non_fqdn_sender
rule rejects emails purporting to come from addresses without a fully-qualified domain name. In practice, this means rejecting emails coming from user@machine
: the address must be announced as either user@machine.example.com
or user@example.com
.
reject_rhsbl_sender
rule reject senders based on a (domain-based) RHSBL service.
RCPT TO
command in the SMTP protocol. These addresses also warrant validation, even if that may be less relevant than the checks made on the sender address.
Пример 11.5. Recipient checks
smtpd_recipient_restrictions = permit_mynetworks, reject_unauth_destination, reject_unlisted_recipient, reject_non_fqdn_recipient, permit
reject_unauth_destination
is the basic rule that requires outside messages to be addressed to us; messages sent to an address not served by this server are rejected. Without this rule, a server becomes an open relay that allows spammers to send unsolicited emails; this rule is therefore mandatory, and it will be best included near the beginning of the list, so that no other rules may authorize the message before its destination has been checked.
reject_unlisted_recipient
rule rejects messages sent to non-existing local users, which makes sense. Finally, the reject_non_fqdn_recipient
rule rejects non-fully-qualified addresses; this makes it impossible to send an email to jean
or jean@machine
, and requires using the full address instead, such as jean@machine.falcot.com
or jean@falcot.com
.
permit
directive at the end is not necessary. But it can be useful at the end of a restriction list to make the default policy explicit.
DATA
command of SMTP is emitted before the contents of the message. It doesn't provide any information per se, apart from announcing what comes next. It can still be subjected to checks.
reject_unauth_pipelining
directives causes the message to be rejected if the sending party sends a command before the reply to the previous command has been sent. This guards against a common optimization used by spammer robots, since they usually don't care a fig about replies and only focus on sending as many emails as possible in as short a time as possible.
RCPT TO
command by default.
EHLO
command, Postfix knows the sender and the recipient when announcing the rejection. It can then log a more explicit message than it could if the transaction had been interrupted from the start. In addition, a number of SMTP clients do not expect failures on the early SMTP commands, and these clients will be less disturbed by this late rejection.
smtpd_delay_reject
rule.
Пример 11.7. Enabling content-based filters
header_checks = regexp:/etc/postfix/header_checks body_checks = regexp:/etc/postfix/body_checks
Пример 11.8. Example /etc/postfix/header_checks
file
/^X-Mailer: GOTO Sarbacane/ REJECT I fight spam (GOTO Sarbacane) /^Subject: *Your email contains VIRUSES/ DISCARD virus notification
GOTO Sarbacane
(a bulk email software) is found, the message is rejected. The second expression controls the message subject; if it mentions a virus notification, we can decide not to reject the message but to discard it immediately instead.
check_policy_service
parameter as an extra restriction:
smtpd_recipient_restrictions = permit_mynetworks, [...] check_policy_service inet:127.0.0.1:10023
postgrey
daemon and send it information concerning the relevant message. On its side, Postgrey considers the IP address/sender/recipient triplet and checks in its database whether that same triplet has been seen recently. If so, Postgrey replies that the message should be accepted; if not, the reply indicates that the message should be temporarily rejected, and the triplet gets recorded in the database.
smtpd_restriction_classes
parameter, and defined the same way as smtpd_recipient_restrictions
. The check_recipient_access
directive then defines a table mapping a given recipient to the appropriate set of restrictions.
Пример 11.9. Defining restriction classes in main.cf
smtpd_restriction_classes = greylisting, aggressive, permissive greylisting = check_policy_service inet:127.0.0.1:10023 aggressive = reject_rbl_client sbl-xbl.spamhaus.org, check_policy_service inet:127.0.0.1:10023 permissive = permit smtpd_recipient_restrictions = permit_mynetworks, reject_unauth_destination, check_recipient_access hash:/etc/postfix/recipient_access
Пример 11.10. The /etc/postfix/recipient_access
file
# Unfiltered addresses postmaster@falcot.com permissive support@falcot.com permissive sales-asia@falcot.com permissive # Aggressive filtering for some privileged users joe@falcot.com aggressive # Special rule for the mailing-list manager sympa@falcot.com reject_unverified_sender # Greylisting by default falcot.com greylisting
clamav
from the homonymous package.
clamav-milter
. A milter (short for mail filter) is a filtering program specially designed to interface with email servers. A milter uses a standard application programming interface (API) that provides much better performance than filters external to the email servers. Milters were initially introduced by Sendmail, but Postfix soon followed suit.
dpkg-reconfigure clamav-milter
. When prompted for the “Communication interface with Sendmail”, answer “inet:10002@127.0.0.1
”.
dpkg-reconfigure clamav-base
.
/etc/postfix/main.cf
:
# Virus check with clamav-milter smtpd_milters = inet:[127.0.0.1]:10002
systemctl reload postfix
should be run so that this change is taken into account.
include
directive it must have one.
Name: example.org Type: TXT TTL: 3600 Data: v=spf1 a mx -all
falcot.org
.
#
host -t TXT falcot.org
falcot.org descriptive text "v=spf1 ip4:199.127.61.96 +a +mx +ip4:206.221.184.234 +ip4:209.222.96.251 ~all"
postfix
почтовый сервер может проверять запись SPF на наличие входящих писем с помощью пакета postfix-policyd-spf-python, это - агент политики, написанный на Python. Файл /usr/share/doc/postfix-policyd-spf-python/README.Debian
описывает необходимые шаги для интеграции агента в postfix, поэтому не будем здесь повторяться.
/etc/postfix-policyd-spf-python/policyd-spf.conf
, который полностью документирован в policyd-spf.conf(5) и /usr/share/doc/postfix-policyd-spf-python/policyd-spf.conf.commented.gz
. Основные параметры конфигурации: HELO_reject
и Mail_From_reject
, которые настраивают, следует ли отклонять электронные письма (Fail
) или принимать с добавлением заголовка (False
), если проверки не пройдут. Последнее часто бывает полезно, когда сообщение дополнительно обрабатывается спам-фильтром.
Header_Type
должен быть установлен на AR
.
postfix
добавляет цифровую подпись, связанную с именем домена, в заголовок исходящих писем. Получающая сторона может проверить текст сообщения и поля заголовка, проверив подпись по открытому ключу, который извлекается из DNS-записей отправителей.
opendkim-genkey -s SELECTOR -d DOMAIN
. SELECTOR должно быть уникальным именем ключа. Это может быть просто "mail" или дата создания, если вы планируете ротацию ключей.
Пример 11.11. Создать закрытый ключ для подписи электронных писем от falcot.com
#
opendkim-genkey -s mail -d falcot.com -D /etc/dkimkeys
#
chown opendkim.opendkim /etc/dkimkeys/mail.*
/etc/dkimkeys/mail.private
и /etc/dkimkeys/mail.txt
и установит для них соответствующие права владения. Первый файл содержит приватный (закрытый) ключ, а второй — публичный (открытый) ключ, который необходимо добавить в DNS:
Name: mail._domainkey Type: TXT TTL: 3600 Data: "v=DKIM1; h=sha256; k=rsa; s=email; p=[...]"
-b 1024
чтобы выбрать меньший размер ключа. Если opendkim-testkey
возвращает результат успешно, то запись успешно настроена. Синтаксис записи объясняется здесь:
SOCKET
и RUNDIR
должны быть выбраны в /etc/default/opendkim
. Заметьте что SOCKET
должен быть доступен из postfix
в его chroot среде. Дальнейшая настройка осуществляется в /etc/opendkim.conf
. Ниже приведен фрагмент конфигурации, который позволяет убедиться, что Domain
"falcot.com" и его субдомены (SubDomain
) подписаны Selector
"mail" и единственным приватным ключом (KeyFile
) /etc/dkimkeys/mail.private
. "relaxed" Canonicalization
как для заголовка, так и для тела письма допускает лёгкие модификации (например, с помощью программного обеспечения списка рассылки). Фильтр работает как при подписании ("s"), так и при проверке ("v") Mode
. Если подпись не проходит проверку (On-BadSignature
), почта должна быть помещена в карантин ("q").
[...] Domain falcot.com KeyFile /etc/dkimkeys/mail.private Selector mail [...] Canonicalization relaxed/relaxed Mode sv On-BadSignature q SubDomains yes [...] Socket inet:12345@localhost [...] UserID opendkim
KeyTable
), доменов (SigningTable
) и указать внутренние или доверенные хосты (InternalHosts
, ExternalIgnoreList
), которые могут отправлять почту через сервер как один из подписанных доменов без учётных данных.
/etc/postfix/main.cf
созданы postfix
используя это фильтр:
milter_default_action = accept non_smtpd_milters = inet:localhost:12345 smtpd_milters = inet:localhost:12345
/etc/postfix/master.cf
.
/usr/share/doc/opendkim/
и страницах руководства opendkim(8) и opendkim.conf(5).
_dmarc
и действия, которое следует предпринять, если электронные письма, содержащие ваш домен в качестве отправляющего хоста, не проходят проверку с использованием DKIM и SPF.
#
host -t TXT _dmarc.gmail.com
_dmarc.gmail.com descriptive text "v=DMARC1; p=none; sp=quarantine; rua=mailto:mailauth-reports@google.com"
#
host -t TXT _dmarc.yahoo.com
_dmarc.yahoo.com descriptive text "v=DMARC1; p=reject; pct=100; rua=mailto:d@rua.agari.com; ruf=mailto:d@ruf.agari.com;"
reject
все электронных писем, которые якобы отправлены с учётной записи Yahoo, но с отсутствующими или непройденными проверками DKIM и SPF. Google Mail (Gmail) пропагандирует очень мягкую политику, согласно которой такие сообщения из основного домена по-прежнему должны приниматься (p=none
). Для поддоменов они должны быть помечены как спам (sp=quarantine
). Адреса, указанные в ключе rua
могут использоваться для отправки агрегированных отчетов DMARC. Полный синтаксис описан здесь:
postfix
также может использовать эту информацию. Пакет opendmarc содержит необходимый milter. Подобно opendkim SOCKET
и RUNDIR
должен быть выбран в /etc/default/opendmarc
(для сокетов Unix вы должны убедиться, что они находятся внутри chroot postfix-а, чтобы их можно было найти). Конфигурационный файл /etc/opendmarc.conf
содержит подробные комментарии и также объясняется в opendmarc.conf(5). По умолчанию электронные письма, не прошедшие проверку DMARC, не отклоняются, а помечаются путем добавления соответствующего поля заголовка. Чтобы изменить это, используйте RejectFailures true
.
smtpd_milters
и non_smtpd_milters
. Если мы настроили milters opendkim и opendmarc для работы на портах 12345 и 54321, запись в /etc/postfix/main.cf
выглядит так:
non_smtpd_milters = inet:localhost:12345,inet:localhost:54321 smtpd_milters = inet:localhost:12345,inet:localhost:54321
/etc/postfix/master.cf
.
saslpasswd2
, которая принимает несколько параметров. Опция -u
определяет домен аутентификации, который должен соответствовать параметру smtpd_sasl_local_domain
в конфигурации Postfix. Опция -c
позволяет создать пользователя и -f
позволяет указать файл, который будет использоваться, если базу данных SASL необходимо хранить не в умолчальном расположении (/etc/sasldb2
).
#
saslpasswd2 -u `postconf -h myhostname` -f /var/spool/postfix/etc/sasldb2 -c jean
[... type jean's password twice ...]
/etc/sasldb2
в символическую ссылку, указывающую на базу данных, используемую Postfix, командой ln -sf /var/spool/postfix/etc/sasldb2 /etc/sasldb2
.
postfix
в группу sasl
, чтобы он мог получить доступ к базе данных учетных записей SASL. Для включения SASL также необходимо несколько новых параметров, а параметр smtpd_recipient_restrictions
необходимо настроить, чтобы клиенты, прошедшие проверку подлинности SASL, могли свободно отправлять электронные письма.
Пример 11.12. Включение SASL в /etc/postfix/main.cf
# Включить аутентификацию SASL smtpd_sasl_auth_enable = yes # Определить SASL домент аутентификации для использования smtpd_sasl_local_domain = $myhostname [...] # Добавить permit_sasl_authenticated перед reject_unauth_destination # разрешить ретранслировать почту, отправляемую SASL-аутентифицированными пользователями smtpd_recipient_restrictions = permit_sasl_authenticated, permit_mynetworks, reject_unauth_destination, [...]
/etc/postfix/master.cf
. Чтобы вообще отключить аутентификацию для порта 25 (smtpd
service), добавьте следующую директиву:
smtp inet n - y - - smtpd [..] -o smtpd_sasl_auth_enable=no [..]
AUTH
(так делают некоторые очень старые почтовые клиенты), совместимость с ними можно включить с помощью директивы broken_sasl_auth_clients
.