There are many postfix tutorials out there. I’ve always wondered what the hell I was copy/pasting onto my system and decided to start (nearly) from scratch. I took one of those tutorials (don’t remember which one) as inspiration, but based the final result on the official docs. I kept what I liked, changed some settings I did not like so much, and threw out a few other things which I deemed useless.
The main problem with those tutorials is that they show you a final result without telling you how they ended up with the result, sometimes it looks like an amalgam of other tutorials ending up in a huge “frankenconfig”. I don’t like deploying something where I don’t know what it’s doing…
The final result is a config which is stripped down to my most basic needs.
The first iteration will be an extremely simple config:
- No database will be used to store mail config. This however is something I will certainly implement.
- Only simple spam handling using blocklists.
- No antivirus.
- No webmail access.
- No POP access.
- No IMAP access.
- Not relay mails for other hosts (only local delivery)j.
For now, I only require e-mail aliasing. That is, I only want to handle e-mails destined for my domains, but I only want to “forward” them to other destinations. Local delivery (and access to those mails) may or may not be implemented later. It will be set up on an Ubuntu Precise Pangolin Server and should get you started for a basic mail server.
Here’s the main config:
The template contains 3 “variables”. Those variables need to be replaced by your values before deploying this!
- {{fqdn}}
- The fully qualified hostname of your server
- {{vgid}}
- The group-id of the local system group for files stored on the local disk.
- {{vuid}}
- The user-id of the local system user for files stored on the local disk.
The most interesting part of the config is at the end of the config after the “Virtual Mail” header. This part defines which e-mail addresses the MTA is handling and how. Will the mails be stored locally? Will they be “aliased” to another e-mail?
The config should be documented well-enough.
# 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
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
# 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_use_tls=yes
smtpd_tls_session_cache_database = btree:${data_directory}/smtpd_scache
smtp_tls_session_cache_database = btree:${data_directory}/smtp_scache
# See /usr/share/doc/postfix/TLS_README.gz in the postfix-doc package for
# information on enabling SSL in the smtp client.
myhostname = {{fqdn}}
alias_maps = hash:/etc/aliases
alias_database = hash:/etc/aliases
mydestination = {{fqdn}}, $myorigin
relayhost =
mynetworks = 127.0.0.0/8 [::ffff:127.0.0.0]/104 [::1]/128
mailbox_size_limit = 51200000
recipient_delimiter = +
inet_interfaces = all
inet_protocols = all
# how long to keep message on queue before return as failed.
maximal_queue_lifetime = 7d
# how many address can be used in one message.
# effective stopper to mass spammers, accidental copy in whole address list
# but may restrict intentional mail shots.
smtpd_recipient_limit = 16
# how many error before back off.
smtpd_soft_error_limit = 3
# how many max errors before blocking it.
smtpd_hard_error_limit = 12
# Requirements for the HELO statement
smtpd_helo_restrictions = permit_mynetworks, warn_if_reject
reject_non_fqdn_hostname, reject_invalid_hostname, permit
# Requirements for the sender details
smtpd_sender_restrictions = permit_mynetworks, warn_if_reject
reject_non_fqdn_sender, reject_unknown_sender_domain, reject_unauth_pipelining,
permit
# Requirements for the connecting server
smtpd_client_restrictions = reject_rbl_client sbl.spamhaus.org,
reject_rbl_client blackholes.easynet.nl
# Requirement for the recipient address
smtpd_recipient_restrictions = reject_unauth_pipelining, permit_mynetworks,
reject_non_fqdn_recipient, reject_unknown_recipient_domain,
reject_unauth_destination, permit
smtpd_data_restrictions = reject_unauth_pipelining
# require proper helo at connections
smtpd_helo_required = yes
# waste spammers time before rejecting them
smtpd_delay_reject = yes
disable_vrfy_command = yes
# ----------------------------------------------------------------------------
# Virtual Mail
# ----------------------------------------------------------------------------
# basic security (user ID mapping)
virtual_minimum_uid = 100
virtual_gid_maps = static:{{vgid}}
virtual_uid_maps = static:{{vuid}}
# base folder
virtual_mailbox_base = /var/spool/mail/virtual
# Domains for which we only ALIAS (mail will not be stored on the local disk).
virtual_alias_domains = hash:/etc/postfix/valias_domains
# Domains for which we deliver mail LOCALLY (mail will be stored on local
# disk).
virtual_mailbox_domains = hash:/etc/postfix/vdomains
# Aliases. Maps one e-mail to another.
# delivered (i.e. stored on the local disk), the end-point of the alias (the
# "right-hand side") must be on a domain which is delivered LOCALLY (see
# below).
virtual_alias_maps = hash:/etc/postfix/valiases
# Mappings for locally delivered mail (maps to files/folders which are stored
# below the base folder `virtual_mailbox_base`)
virtual_mailbox_maps = hash:/etc/postfix/vmailbox
Examples for the hash files (for an explanation what they do, see above):
---- is usually the same as the right-hand-side.
domain1.tld domain1.tld
domain2.tld domain2.tld
---- vdomains -- This is another list.
domain3.tld domain3.tld
---- valiases -- This is a "map". Think "key/value". So,
---- forcibly the LHS differs from the RHS
user@domain1.tld john.doe@external.domain.tld
user2@domain2.tld user@domain1.tld
---- vmailbox -- This is another "map"
# the trailing slash defines a Maildir format.
user3@domain3.tld folder/subfolder/user3/
# Not having a trailing slash makes it an Mbox file.
user4@domain3.tld folder/subfolder/user4