Выбрать главу

Example 11.7. Restrictions on the name announced in EHLO

smtpd_helo_restrictions = permit_mynetworks, reject_invalid_hostname,

    check_helo_access hash:/etc/postfix/access_helo,

    reject_non_fqdn_hostname, warn_if_reject reject_unknown_hostname

The first permit_mynetworks directive allows all machines on the local network to introduce themselves freely. This is important, be cause some email programs do not respect this part of the SMTP protocol adequately enough, and they can introduce themselves with nonsensical names.

The reject_invalid_hostname rule rejects emails when the EHLO announce lists a syntactically incorrect hostname. The reject_non_fqdn_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_hostname rule rejects messages if the announced name does not exist in the DNS. Since this last rule unfortunately leads to too many 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.

Using 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, for instance by adding a falcot.com REJECT You're not in our network! line to the /etc/postfix/access_helo file.

11.1.3.3. Accepting or Refusing Based on the Announced Sender

Every message has a sender, announced by the MAIL FROM command of the SMTP protocol; again, this information can be validated in several different ways.

Example 11.8. Sender checks

smtpd_sender_restrictions =

    check_sender_access hash:/etc/postfix/access_sender,

    reject_unknown_sender_domain, reject_unlisted_sender,

    reject_non_fqdn_sender

The /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.

The 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 from 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.

Finally, the 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.

11.1.3.4. Accepting or Refusing Based on the Recipient

Each email has at least one recipient, announced with the 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.

Example 11.9. Recipient checks

smtpd_recipient_restrictions = permit_mynetworks,

    reject_unauth_destination, reject_unlisted_recipient,

    reject_non_fqdn_recipient

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 sent unsolicited emails; this rule is therefore strongly recommended, and it will be located near the beginning of the list for preference, so as to avoid other rules to authorize the message to pass through before its destination has been checked.

The 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.

11.1.3.5. Restrictions Associated with the DATA Command

The 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.

Example 11.10. DATA checks

smtpd_data_restrictions = reject_unauth_pipelining

The 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.

11.1.3.6. Applying Restrictions

Although the above commands validate informations at various stages of the SMTP exchange, Postfix only sends the actual rejection as a reply to the RCPT TO command.

This means that even if the message is rejected due to an invalid 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.

A final advantage to this choice is that the rules can accumulate information during the various stages of SMTP; this allows defining more fine-grained permissions, such as rejecting a non-local connection if it announces itself with a local sender.

11.1.3.7. Filtering Based on the Message Contents

QUICK LOOK Regexp tables

The /usr/share/doc/postfix-doc/examples/header_checks.gz file contains many explanatory comments and can be used as a starting point for creating the /etc/postfix/header_checks and /etc/postfix/body_checks files.

The validation and restriction system would not be complete without a way to apply checks to the message contents. Postfix differenciates the checks applying on the email headers from those applying to the email body.

Example 11.11. Enabling content-based filters

header_checks = regexp:/etc/postfix/header_checks

body_checks = regexp:/etc/postfix/body_checks

Both files contain a list of regular expressions (commonly known as regexps or regexes) and associated actions to be triggered when the email headers (or body) match the expression.

Example 11.12. Example /etc/postfix/header_checks file

/^X-Mailer: GOTO Sarbacane/ REJECT I fight spam (GOTO Sarbacane)

/^Subject: *Your email contains VIRUSES/ DISCARD virus notification

BACK TO BASICS Regular expression

The regular expression term (shortened to regexp or regex) references a generic notation for expressing a descrition of the contents and/or structure of a string of characters. Certain special characters allow defining alternatives (for instance, foo|bar matches either “foo” or “bar”), sets of allowed characters (for instance, [0-9] means any digit, and . — a dot — means any character), quantifications (s? matches either s or the empty string, in other words 0 or 1 occurrence of s; s+ matches one or more consecutive s characters; and so on). Parentheses allow grouping search results.