Table of Contents
Previous Section Next Section

Postfix

Postfix is another widely used MTA written by Wietse Venema. More information on Postfix is available online at http://www.postfix.org/. Unless otherwise noted, all configuration information in this section pertains to Postfix version 2.x.

Updating the Configuration

In a "standard" Postfix installation, the /etc/postfix directory is the home of all Postfix configuration files. main.cf contains the parameters that control the operation of Postfix. These settings include the SMTP clients and sender domains from which Postfix will accept mail. The clients and domains can be listed directly in the main.cf configuration file.

Whenever you modify any Postfix configuration file, including main.cf, you must reload the Postfix server by issuing the postfix reload command, typically located in /usr/sbin or /usr/local/sbin. postfix reload will force Postfix to re-read all of its configuration files and make active any changes you have made.

Static Filter Setup

Similar to Sendmail, Postfix implements blocking/allowing messages by IP addresses or sending domain by using an access database. You can specify the database to use for enforcing sender IP address restrictions in the Postfix configuration file, /etc/postfix/main.cf.

The main.cf parameter smtpd_client_restrictions lists the IP address restrictions of SMTP clients. By default, this parameter is empty, which causes Postfix to accept mail from any mail server. Restrictions are specified in a comma- or space-separated list. For example, consider the following entry:

smtpd_client_restrictions = check_client_access hash:/etc/postfix/client_access

This line specifies that connecting SMTP clients will be checked against the access database stored in the hash file /etc/postfix/client_access.

The parameter smtpd_sender_restrictions lists the restrictions for sender addresses and domains. By default, this parameter is empty, and Postfix will accept mail from any sender. Restrictions are specified in a comma- or space-separated list.

For example, look at this configuration file entry:

smtpd_sender_restrictions = check_sender_access hash:/etc/postfix/sender_access

This entry specifies that the sender addresses and domains will be checked against the access database stored in the hash file /etc/postfix/access. Note that the same file can contain both sender and recipient restrictions. See the example at the end of the next section for more information.

The Postfix Access Database

The Postfix access database, /etc/postfix/access.db, is a BerkeleyDB format file created from a plain-text file, /etc/postfix/access, using the postmap command that comes with Postfix:

# postmap hash /etc/postfix/access

This command converts the /etc/postfix/access text file into a hash database file that Postfix can read efficiently. The format of the access file consists of two fields similar to Sendmail. The left hand side (LHS) specifies the address to block or allow and is specified as:

  • Email address user@example.com

  • Domain name example.com

  • Single IP address 192.168.64.78

  • /24 or Class C IP address block 10.5.3

The right hand side (RHS) indicates the action to take for the specified address:

  • REJECT Bounce the message back with a generic error message.

  • 4## custom message Temporarily defer delivery of the message with the specified custom message.

  • 5## custom message Bounce the message back with the custom specified message.

  • OK Accept the message that would otherwise be rejected by a more general rule.

Consider the following example Postfix access file:

#
# postfix access database#
# reject specific from address
spammer@spamalot.com REJECT
# reject entire from domain with custom error message
spammer.net      550 We don't accept mail from spammers
# accept exception to rejected domain
okay.spammer.net OK
# a spammer.net user that we want to get mail from
cooldude@spammer.net OK
# reject specific ip address
192.0.34.166       REJECT
# reject ip address block
192.168.16        REJECT
# allow specfic ip address from rejected block
192.168.16.11        OK

Using this access database, mail from spammer@spamalot.com would be rejected with the following message:

554 <spammer@spamalot.com>: Sender address rejected: Access denied

Mail from any user at spammer.net would be rejected with this message:

550 <anyuser@spammer.net>: Sender address rejected: We don't accept mail from spammers

If the SMTP client attempting to send mail has the IP address 192.0.34.166, it will be rejected with this message:

554 <www.example.com[192.0.34.166]>: Client host rejected: Access denied

It is important to note the different treatment an access database entry receives, depending on whether the check is being made on the client or sender. For example, using the previously described access database, a message would be rejected using the client restrictions if the connecting client's IP address mapped to the spammer.net domain unless it originated from the address associated with okay.spammer.net.

Using the sender restrictions, Postfix would reject the message if it were from spammer@spamalot.com or any user from spammer.net (except domainokay.spammer.net and cooldude@spammer.net), regardless of the address of the connecting client. In a similar fashion, in this example, the entire block of 192.168.16 addresses are not allowed, except for 192.168.16.11, which is specifically allowed.

In the preceding example, the access databases for client and sender restrictions are combined for convenience. They can also be kept separate. For example, the following parameter settings in main.cf would use separate access databases for each:

smtpd_client_restrictions = check_client_access hash:/etc/postfix/access_sender
smtpd_sender_restrictions = check_sender_access hash:/etc/postfix/access_client

Complete documentation for the access file is at http://www.postfix.org/access.5.html.

Blocking via Blackhole Listing

Postfix uses the reject_rbl_client restriction in the smtpd_client_restictions list. This restriction takes an argument specifying the blackhole-listed domain to use:

smtpd_client_restrictions = reject_rbl_client rbl.example.com

These restrictions can be combined with others on the same main.cf parameter line:

smtpd_client_restrictions = check_client_access
hash:/etc/postfix/access_sender,
reject_rbl_client rbl.example.com

The message returned for rejected messages can be customized using the default_rbl_reply parameter, which is set in main.cf. There are many built-in macros that can be used, such as

  • $rbl_class The class of the blacklisted entity, such as client host, sender address.

  • $rbl_domain The domain serving the blacklist that the entity was on.

  • $rbl_code The numerical reply code. The default is 554, but it can be changed by setting $maps_rbl_reject_code.

  • $rbl_what The blacklisted entity, such as IP address, domain, sender address.

  • $rbl_reason The reason the domain is blacklisted.

Complete documentation is at http://www.postfix.org/uce.html#additional.

Consider the following entry:


default_rbl_reply = $rbl_code Service unavailable; $rbl_class [$rbl_what] blocked see http
://$rbl_domain

A message sent by a client listed in rbl.example.com's map would then be rejected with this message:

554 Service unavailable; Client host [192.168.16.7] blocked see http://rbl.example.com

Overriding Entries on BLS

In order to allow servers that might be listed on blackhole listing services such as MAPS to send you email, simply list the name or IP address of the server in the Postfix access database as OK. This will allow you to override any BLS list entries with which you or your email users need to communicate.

Qmail Tcpserver and Rblsmtpd

True to its minimalist design, qmail has no built-in mechanism for blocking connecting SMTP clients by address. As a result, tcpserver must be used in combination with rblsmtpd for this purpose. tcpserver is part of Dan Bernstein's ucspi-tcp package. It allows programs to easily control access to arbitrary TCP/IP connections. It is similar to inetd/xinetd in nature.

Qmail's SMTP server doesn't run as a daemon listening on the SMTP port waiting for incoming connections as Sendmail and Postfix do. Another daemon, tcpserver, is used to listen for incoming connections. When an SMTP connection is received, tcpserver invokes qmail, connecting stdin and stdout to the socket, much as inetd does for the services it manages. tcpserver is started with qmail as an argument. Here is a simple example for starting qmail under tcpserver control:

tcpserver -v -u <qmail-uid> -g <qmail-gid> 0 smtp /var/qmail/bin/qmail-smtpd 2>&1 &

ucspi-tcp (a package required by qmail, which includes tcpserver) is distributed with a program called rblsmtpd. rblsmtpd blocks or allows messages depending upon the value of an environment variable $RBLSMTPD. If the variable $RBLSMTPD is set and nonempty, the email message is rejected with the text value of $RBLSMTPD used as the bounce message. If the variable is set and empty, the message is accepted. If the variable is not set, then the blackhole-listed databases are consulted to determine whether the message should be accepted or rejected. $RBLSMTPD is set by /usr/local/bin/rblsmtpd.

rblsmtpd is invoked by a call from tcpserver. tcpserver takes an -x argument, which specifies the name of a file containing rules to be used for blocking or allowing connecting clients by IP address. Furthermore, environment variables can be set depending upon the IP address of the connecting client. For example, the following command configures qmail to use rblsmtpd and the IP address connection rules located in /etc/tcp.smtp.cdb:

tcpserver -v -x /etc/tcp.smtp.cdb -u <qmail-uid> -g <qmail-gid> 0 smtp \
/usr/local/bin/rblsmtpd /var/qmail/bin/qmail-smtpd 2>&1 &

Tcpserver Rules

The tcpserver rules file is actually a database created from a plain-text file using the tcprules program. For example, if the rules database was /etc/tcp.smtp.cdb and the text file source for it was /etc/tcp.smtp, the following command would update it after a change was made:

# tcprules /etc/tcp.smtp.cdb /etc/tcp.smtp.cdb.tmp < /etc/tcp.smtp

(Note: tcprules's second argument is the name of a temporary file to hold the new database before it is renamed to that of the old.)

Blocking and Allowing Messages by IP Address

CDB is a database format used by tcpserver to manage the IP addresses that are allowed to connect to the qmail server. A CDB rule consists of two fields separated by the colon (:) character. The LHS of the colon is an address, and the RHS is an instruction beginning with allow or deny. The instruction can also have environment variable assignments. The first rule that matches is applied.

For the purposes of using rblsmtpd to reject specific addresses, the addresses to be blocked are listed with the allow instruction followed by the RBLSMTPD environment variable assignment that will cause rblsmtpd to reject the incoming mail with the specified message. Simply setting the instruction to deny drops the connection before rblsmtpd can return an error message, causing the sender to re-queue and retry the mail as if a network failure had occurred.

The message is sent back as error 451, which indicates a temporary failure, and the sender re-queues the message. If the message text is prepended with a hyphen (-), the message is sent back as a permanent failure, 553.

For example:

# defer messages from a specific IP address
192.0.34.166:allow,RBLSMTPD="We don't accept mail from spammers"
# allow specfic IP address from rejected block
192.168.16.11:allow,RBLSMTPD=""
# reject messages from an IP address block
192.168.16.:allow,RBLSMTPD="-We don't accept mail from spammers"

Using this tcp.smtp.cdb database, a message relayed from 192.0.34.166 would be rejected with the message

451 We don't accept mail from spammers

A message relayed from 192.168.16.11 would be accepted, though a message from all other addresses in 192.168.16.xx would be rejected with the message

553 We don't accept mail from spammers

Further tcprules documentation can be found at http://cr.yp.to/ucspi-tcp/tcprules.html.

Blocking and Allowing Messages by Email Address

In order to block non-IP addresses via qmail, we must move our focus back to qmail. Messages may be blocked based on the envelope From: address by listing the addresses in the file badmailfrom typically located in the /var/qmail/control directory. Addresses are listed in badmailfrom as user@domain.com or @domain.com. For example, consider the following entries:

spammer@spamalot.com
spammer.net

Using this badmailfrom entry, spammer@spamalot.com or any user from spammer.net would be rejected with the following message:

553 sorry, your envelope sender is in my badmailfrom list (#5.7.1)

Blocking via Blackhole Listing

As mentioned previously, the rblsmtpd program will look up connecting clients IP addresses in blackhole lists to determine whether to block or allow the connection. Unlike Sendmail and Postfix, qmail looks up a DNS TXT record associated with the address rather than a DNS A record. A DNS TXT record is essentially a text comment string, and an A record is an address record, indicating the IP address associated with a name.

For this reason, some commonly used blackhole listing services won't work with rblsmtpd. Blackhole listing sources to use for the lookup are specified with the -r option to rblsmtpd. Additionally "anti-rbl" sources may also be specified using the -a option. An anti-blackhole listing queries for an A record. Each specified source is used in order until a lookup is successful. If the successful lookup is from a blackhole listing source, the mail is blocked, and the text returned by the lookup is used as the error message. If the successful lookup is from an anti-blackhole listing source, the message is accepted.

A 451 error code deferring delivery temporarily is returned by default for mail rejected as a result of a blackhole listing lookup. The -b flag causes a 533 error code, indicating permanent failure to be returned. You probably should use the -b flag so that messages aren't continually queued by the sender, causing resources to be consumed on your email system for no benefit to you.

By default, if the lookup fails temporarily, the mail is accepted. The -c flag causes delivery to be deferred with a 451 error message.

For example, to use rbl.example.com as an rbl source, add -r rbl.example.com to the tcpserver command line. The -b causes a 553 error code to be returned:

tcpserver -v -x /etc/tcp.smtp.cdb -u <qmail-uid> -g <qmail-gid> 0 smtp \
/usr/local/bin/rblsmtpd -b -r rbl.example.com /var/qmail/bin/qmail-smtpd 2>&1 &

If the TXT record for 7.16.168.192.rbl.example.com is

7.16.168.192.rbl.example.com. IN TXT     "listed in rbl, see http://rbl.example.com"

then messages relayed from a host listed on rbl.example.com will be rejected with the following message:

553 listed in rbl, see http://rbl.example.com

Overriding Entries on BLS

In order to override BLS entries that block messages from mail servers you need to receive messages from, set the RBLSMTPD variable in the tcp.smtp line to be blank. So, if you wanted to allow mail from the server 1.2.3.4, which was listed in a BLS you were using, you would enter the following line:

1.2.3.4:allow,RBLSMTPD=""

This would allow 1.2.3.4 to send email to your qmail server, even though it was listed in a BLS you were using.

    Table of Contents
    Previous Section Next Section