Postfix MTA setup guide ----------------------- Because setting up a mta _properly_ isn't a quite so easy task, I'm going to document the process here. At least for Postfix 2.3/2.4. I'll discuss main.cf, master.cf and maps/ in a short. Also I only show few important settings. Also please note that this isn't an exhaustive guide. I don't guarantee that it'll work at all or in the desired way. I expect you to EXACTLY KNOW what you are doing if you use this guide. Do not complain to me if it doesn't work the way you had imagined! This guide is directed at experts as a checkup list. Also I think it's note-worthy that this setup does not rely on external entities (e.g. blacklists). Yours, satmd 2011-05-31 15:34 CEST ------------------------------------------------------------------------------- ############################ ### /etc/postfix/main.cf ### ############################ # We want to turn away people sending to inexistant users (5xx) unknown_local_recipient_reject_code = 550 # Only our own machine is "automatically authorized" to relay mail to the # outside mynetworks_style = host mynetworks = 127.0.0.1 # we prefer maildir home_mailbox = .maildir/ # Spammers can verify the existant of addresses if not disabled # This is of limited use, as they still can test by just sending a mail :p disable_vrfy_command = yes # We require senders to use EHLO/HELO smtpd_helo_required = yes # This will add a hint on encryption to Received: headers smtpd_tls_received_header = yes # Enable authentication # for my machine I use dovecot sasl smtpd_sasl_auth_enable = yes smtpd_sasl_application_name = smtpd smtpd_sasl_local_domain = $myhostname smtpd_sasl_security_options = noanonymous # next line is required for some (all?) versions of Microsoft Outlook # it is unable to parse the AUTH line elseway (MS, fix your code!) # I doubt it would be a great loss if *I* turned off. broken_sasl_auth_clients = yes # We want postfix to add a header so others can verify the sender smtpd_sasl_authenticated_header = yes # Those lines are specifically for use with dovecot sasl smtpd_sasl_type = dovecot smtpd_sasl_path = private/auth # *_restrictions are the heart of postfix, those decide what mail to # accept/route/deliver/forward. Those default to "OK" if no other rules decide # otherwise. # permit_sasl_authenticated ..... Allows authenticated clients to proceed # permit_mynetworks ............. Allow "mynetwork" (127.0.0.1) to proceed # reject_unknown_client_hostname. Reject clients that don't have a reverse # DNS hostname entry # check_client_access ........... Delegate lookups to a table # reject_unknown_sender_domain .. Reject mail from senders with no valid domain # reject_non_fqdn_sender ........ We are on the internet, so we expect # "fully-qualified domain names" # check_policy_services ......... This one is commented out, but allows you to # use policy demons via master.cf # reject_unauth_destination ..... This will reject relayed mails for # unauthenticated clients # reject_unauth_pipelining ...... Rejects the submission of SEVERAL mails # without authentication # check_helo_access ............. Reject clients with a EHLO/HELO lookup from # a table. # reject_invalid_helo_hostname .. Reject mails with a EHLO/HELO containing # invalid characters # reject_non_fqdn_helo_hostname . Reject non-fqdn EHLO/HELO # reject_unknown_helo_hostname .. Require a DNS hostname (depends on wether an # IP would be suggested to be fqdn # reject_unverified_recipient ... Do not queue up mails for accounts that do # not exist or cannot be verified. Use this # when you do NOT relay mail for other servers # in a backup MX configuration. This will stop # backscatter mail when the spam sender drops # the connection before you can tell him that # his mail will be rejected. Postfix will try # to send a mail back otherwise. I'm not sure # this will play nice with backup MX'es when # the primary MX is down, but one can # eventually work around that. # Checking the client hostname/ip smtpd_client_restrictions = permit_sasl_authenticated permit_mynetworks reject_unknown_client_hostname check_client_access cidr:/etc/postfix/maps/access_cidr_map check_client_access hash:/etc/postfix/maps/access_map check_client_access regexp:/etc/postfix/maps/access_regexp_map # Checking the ENVELOPE sender smtpd_sender_restrictions = reject_authenticated_sender_login_mismatch permit_mynetworks permit_sasl_authenticated #reject_unknown_sender_domain reject_non_fqdn_sender # Checking the recipients smtpd_recipient_restrictions = permit_sasl_authenticated permit_mynetworks # check_policy_service unix:private/policy-spf reject_unauth_destination reject_unauth_pipelining # reject_unverified_recipient # Checking the EHLO/HELO smtpd_helo_restrictions = permit_sasl_authenticated permit_mynetworks check_helo_access hash:/etc/postfix/maps/helo_map reject_invalid_helo_hostname reject_non_fqdn_helo_hostname reject_unknown_helo_hostname # You can run checks on the headers header_checks = regexp:/etc/postfix/maps/header_checks # I forgot why I put this here, but probably because my postfix kept on # replying with a 4xx for inexistant users. unknown_local_recipient_reject_code = 550 # We can have virtual user tables. I use those for associating mail addresses # with recipient accounts/forwardings virtual_alias_maps = hash:/etc/postfix/maps/virtuals virtual_mailbox_maps = $virtual_alias_maps # The syntax for aliases in virtuals is # You also need an entry for EACH domain you want to use # with virtuals # List domains you need to relay here, e.g. for mailman's lists.example.com # style vhosting #relay_domains = # I put mailman's lists.example.com there and associated it with a transport # from master.cf transport_maps = hash:/etc/postfix/maps/transport # We verify the senders against the virtuals table so that authenticated users # only can use THEIR OWN mail addresses smtpd_sender_login_maps = hash:/etc/postfix/maps/virtuals # The following line effectively blocks broken web apps from sending mail # through "apache" itself. Instead users are required to log in to a mail # account authorized_submit_users = !apache, static:all # This defines the MDA (see procmail notes file) # mailbox_command = /usr/bin/procmail -a "$EXTENSION" ############################## ### /etc/postfix/master.cf ### ############################## # I was unable to get postfix running unless I *disabled* chrooting for smtpd smtp inet n - n - - smtpd # Next line shows how to add the mailman transport. Currently, gentoo lacks # this useful script. I had to fetch it from the net and ADJUST it, too mailman unix - n n - - pipe flags=FR user=mailman argv=/usr/lib/mailman/bin/postfix-to-mailman-2.1.py ${nexthop} ${user} # This is an example how to use a policy daemon policy-spf unix - n n - - spawn user=nobody argv=/usr/bin/perl /usr/libexec/postfix/postfix-policyd-spf.pl ################################## ### /etc/postfix/maps/Makefile ### ################################## # whenever I change a file in maps/, I run "make" to update the hashtables and # to tell postfix of the changes. Pretty self-explanatory. .PHONE: FORCE .SILENT: all: access_map.db access_regexp_map.db header_checks.db helo_map.db transport.db virtuals.db access_cidr_map.db postfix reload %.db: % FORCE echo -n "Compiling $< ... " -postmap $< echo "done" FORCE: ################################## ### /etc/postfix/maps/* (maps) ### ################################## # Generally, I'd suggest you to check out the manuals on "access", # "transport", "virtual", ... They also explain the ACTIONs. # but I give you some useful examples, too: # e.g. header_checks can be used to block our widespread vulnerable mail # clients like old versions of SquirrelMail. Use \s instead of spaces # since my header_checks used a regexp: table! /^User-Agent:\s\s*SquirrelMail\/1\.4\.[34]/ HOLD /^X-Mailer:\s\s*SquirrelMail\/1\.4\.[34]/ HOLD # or in helo_map you should put all hostnames your machine ITSELF owns. localhost REJECT You are not me. # transports work like this: lists.example.com mailman: # For the other tables, read the manuals. It's worth the time.