I'm having difficulty figuring out how to create a particular Postfix configuration for a Postfix instance that will be running inside a container.

Here are my requirements:

  1. Disallow relaying unless sender is from one of a small set of IP addresses or the sender is a local program (though how to allow a program outside the container to queue up mail for the Postfix running in the container is an interesting conundrum).
  2. Run every piece of incoming mail from non-relay IP addresses through a small set of checks and refuse delivery if it doesn't pass them all:
    1. If sender IP is in a specified RBL, reject it.
    2. Greylist incoming IPs I haven't accepted mail from before.
    3. If the user portion of the destination address doesn't match any of a small set of regexps, reject it.
    4. If the mail doesn't pass a few simple and fast spamassassin checks, reject it.
  3. For all local delivery, use a program to determine final disposition. This program will have one of four results.
    1. Deliver to a different local address (Delivered-To will be updated to provide looping protection and the local delivery program will be run again).
    2. Forward to a remote address (like a gmail account or something).
    3. Deliver to a local Maildir directory owned by a particular user (always the same user for now).

I only need to handle mail addressed to one domain. At some point I would like to add a new domain in which all mail is handled by Mailman, though it would again be nice to reject any mail for a non-existent list address before delivery.

Are there any pointers to documents that specify how to achieve one or more of these goals? The Postfix manual for local and transport are too obtuse to really be helpful. It would be nice to have a document specifying the flow of mail through the system and how it can be altered at various points.

Also, while I can write my own program to deliver to a Maildir mailbox, doing so perfectly correctly is rather tricky, and I'd like to avoid it if at all possible and have the part of Postfix that already knows how to do this handle it.

Postfix will be running in a container. The queue directory and the Maildir directories will be persistent filesystems that are mounted inside the container. I presume that all the programs needed to implement the stuff I talked about before (postgrey, spamassassin, the thing that determines how local mail will be disposed of) will also run in the same container. I may have to arrange for the state that postgrey and spamassassin keep to also be persistent across container invocations.

I will be using mutt to read the mail. Currently, I will be the only person for whom mail will be delivered locally, though I will have several different Maildir directories that things will be delivered to. I will likely be running Dovecot on the same system (perhaps containerized in a different container) to do this.

Also, I have a few hundred local recipient addresses, most of which I wish to treat in an identical way. They all fit a pattern, but some that fit this pattern need to be treated differently from others. I know which beforehand without reference to the contents of the email, so I can create more specific patterns for those.


Many of the items can be covered in the smtpd_client_restrictions section of Postfix Configuration Parameters

Here are my client restrictions:

smtpd_client_restrictions = permit_mynetworks 
                            check_policy_service unix:private/policy-spf
                            reject_rbl_client cbl.abuseat.org
                            reject_rbl_client pbl.spamhaus.org
                            reject_rbl_client sbl.spamhaus.org
                            reject_rbl_client bl.blocklist.de

This configuration removes about 99% of incoming spam mail. The list is an ordered list. Each check falls through to the next. Once a failure occurs, then the mail is rejected. I found I needed to create a few exceptions to my rules and those are contained in the client_checks db file.

This exception file looks like this:

cat /etc/postfix/client_checks

ip.address.123.456     OK
ip.address.789.123     REJECT

Once you make the plain text columnar file, you need to issue the postmap command so that the file is output as a db file.

postmap /etc/postfix/client_checks

Forwarding rules for a system that has one or two recipients should be fairly easy to setup through aliases.

man aliases
man postaliases

The file format and procedure is pretty much the same. Enter aliases line by line and then issue the postaliases command to create the db.

For more complicated aliases, regular expressions can be included in your alias table:

man regexp_table
   # Disallow sender-specified routing. This is a must if you relay mail
   # for other domains.
   /[%!@].*[%!@]/       550 Sender-specified routing rejected

   # Postmaster is OK, that way they can talk to us about how to fix
   # their problem.
   /^postmaster@/       OK

   # Protect your outgoing majordomo exploders
   if !/^owner-/
   /^(.*)-outgoing@(.*)$/  550 Use ${1}@${2} instead
  • I have more than one or two recipients. I create a new email address for every website I visit. I need to set up a rule that allows any mail sent to an address that fits a pattern, but will reject mail that's been sent to a particular address that's not in a 'permitted' set to send only 2-3 emails. This is so I can easily do the email verification two-step for companies that I don't believe deserve to send me much email, but whitelist those I have a continuing email relationship with. – Omnifarious Dec 28 '17 at 1:02
  • 1
    @Omnifarious: postfix aliases can be regular expressions ... You'll need to read through man regexp_table – RubberStamp Dec 28 '17 at 3:06
  • Wouldn't I get more mileage out of using Maildrop for local delivery instead? – Omnifarious Dec 28 '17 at 19:41
  • I agree that the smtpd_client_restrictions thing is perfect for rejecting mail before it's delivered. I think there's even a way I can have it run my own program for checking things. – Omnifarious Dec 28 '17 at 19:43

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.