Postfix

Installation

Now that we have postfixadmin and the database set up we can install postfix.

#apt-get install postfix-pgsql

NOTE: At this point there is a chance that Debian has pre-empted you and automatically installed a number of packages that you do not want and that conflict with the packages that you intend to use (I love Debian but its “nanny knows best” approach really pisses me off sometimes). If it does then you will need to run

#apt-get install postfix postfix-pgsql

This will probably bring up a window for configuration of exim4 even though it is going to remove it rather than install it; just humour it by excepting the defaults and let it do its thang!

After this you can run autoremove if you want to get rid of the mysql stuff that debian thinks that you are going to need

#apt-get autoremove

We are going to store the mail in a custom location or /home/mailstore so we need to create that directory and set the permissions on it.

First though we are going to add a user and a group called mailer

#groupadd mailer
#useradd mailer –g mailer

now we can create the directory and set the permissions

#mkdir /home/mailstore
#chown mailer:mailer /home/mailstore

The other thing that we need to do is obtain the userid and groupid for the mailer user and group so that we can use them in the configuration file

#id mailer

should return something like

uid=1001(mailer) gid=1001(mailer) groups=1001(mailer)

so we now know that the user and group id’s are 1001

Postfix Configuration

master.cf

Postfix has two main config files: main.cf, which specifies what you would think of as config options, and master.cf, which specifies the services postfix should run.

First, configure the master.cf file (in /etc/postfix/). Add an extra “smtpd” instance called “submission” that will take mail from trusted clients for delivery to the world at large, which we don’t allow for anyone else.  To do that, open master.cf (take a look at man 5 master if you want to understand what’s going on) and uncomment the submission config and add options to enable SASL:

submission inet n       -       -       -       -       smtpd
-o syslog_name=postfix/submission
-o smtpd_tls_wrappermode=no
-o smtpd_tls_security_level=encrypt
-o smtpd_sasl_auth_enable=yes
-o smtpd_recipient_restrictions=permit_mynetworks,permit_sasl_authenticated,reject_unauth_destination
-o milter_macro_daemon_name=ORIGINATING  
-o smtpd_sasl_type=dovecot  
-o smtpd_sasl_path=private/auth

Note there are 2 spaces prepending the “-o”, these are necessary for the configuration to load

taken from https://kuther.net/howtos/soho-mailserver-postfix-postgresql-dovecot-spamassassin-roundcube

This warrants a bit of explanation. The -o … options override the settings that are taken from defaults or define in the config, which we’ll set later.
In a nutshell what happens here is that this enables the “submission” daemon with TLS to secure the outer connection, and dovecot-mediated SASL to check the username and password of connecting clients. (We will set that up in dovecot later).

The important detail is smtpd_recipient_restrictions which is missing reject_unauth_destination, this is what restricts relaying.

 

main.cf

That is it for master.cf, now we want to configure main.cf. Let’s first set the network information: (information about the domains postfix is handling mail for, and a bit of extra info)

myhostname = fqdn.suffix
myorigin = /etc/mailname
mydestination = fqdn.suffix, domain.com, localhost,
localhost.localdomain
relayhost =
mynetworks = 127.0.0.0/8
[::ffff:127.0.0.0]/104 [::1]/128
mailbox_size_limit = 0
recipient_delimiter = +
inet_interfaces = all

We set the hostname and the default origin, which is sourced from /etc/mailname by debian convention. You can set it explicitly if you don’t have /etc/mailname. The default origin is used to construct the ‘From’ address for local users. mydestination sets the domains that postfix accepts emails for as final destination, and we set “relayhost” empty to disable relaying mail (relaying means accepting mail and then forwarding to a mail server that is not the final destination for the mail and we have no need for that; that is useful e.g. in a corporate intranet where a central mail server should check mail before it leaves the network.)

Now we need to set up the virtual mail for postgresql and dovecot transport. Depending on how your server is setup you might want to keep mail in a non default location. If possible I like to make a separate partition to store mail on, but if that is not possible then I will use the /home directory. Whatever directory is used, it needs to be set in the virtual_mailbox_base directive

virtual_mailbox_base = /home/mailstore

virtual_mailbox_limit sets the maximum size of the mailbox, here we have it set to 5gig because space is not really a concern

virtual_mailbox_limit = 512000000

In a moment we are going to create some files that we will use to drag information from the postfix database. The following directives tell postfix what type of database we are connecting to, what the files are called, and their locations.

virtual_mailbox_domains = proxy:pgsql:/etc/postfix/pgsql/virtual_domains_maps.cf
virtual_mailbox_maps = proxy:pgsql:/etc/postfix/pgsql/virtual_mailbox_maps.cf
virtual_alias_maps = proxy:pgsql:/etc/postfix/pgsql/virtual_alias_maps.cf

virtual_uid_maps and virtual_gid_maps are what we use to set the user and group ids of the user that has read write access to the mailstore. Earlier we used “id mailer” to obtain the gid and uid and discovered that in this particular instance they were both 1001 so we can set them her

virtual_uid_maps = static:1001
virtual_gid_maps = static:1001

The only other settings are

virtual_minimum_uid = 8
inet_protocols = ipv4

 

pgsql config files

As mentioned earlier in the postfixadmin configuration section, postfix uses the postgresql database tables that are managed with postfixadmin to gather the information it needs to operate correctly. The way that it does this is by running a series of SELECT statements depending on its needs. Unfortunately these statements need to be configured manually.

The first thing we need to do is create a folder to store these files in called pgsql

#mkdir /etc/postfix/pgsql

Once we have done that, we can create each of these files in the directory.

Create /etc/postfix/pgsql/relay_domains.cf and add the following to it

user = postfixro
password = changeme
hosts = localhost
dbname = postfix
query = SELECT domain FROM domain WHERE domain='%s' and backupmx = true

Note that this is where we use the postfixro user as we only need read only access, if we are connecting to a remote host then its fqdn will need to be put in the hosts directive. The rest of these files should not require any further explanation as it is only the SQL statement that differs.

Create /etc/postfix/pgsql/virtual_alias_maps.cf

user = postfixro
password = secret
hosts = localhost
dbname = postfix
query = SELECT goto FROM alias WHERE address='%s' AND active = true

Create /etc/postfix/pgsql/virtual_domains_maps.cf

user = postfixro
password = secret
hosts = localhost
dbname = postfix
query = SELECT domain FROM domain WHERE domain='%s' and backupmx = false and active = true

Create /etc/postfix/pgsql/virtual_mailbox_limits.cf

user = postfixro
password = secret
hosts = localhost
dbname = postfix
query = SELECT quota FROM mailbox WHERE username='%s'

Create /etc/postfix/pgsql/virtual_mailbox_maps.cf

user = postfixro
password = secret
hosts = localhost
dbname = postfix
query = SELECT maildir FROM mailbox WHERE username='%s' AND active = true

There is no need to alter the permissions on any of the files. Once this is done you should have fully configured postfix.

 

Troubleshooting

#service postfix status

Use this to check the status of postfix

#postconf

This checks that the configuration is valid, note that it does not check that the configuration is correct, only that it could be valid, but it is still useful to check for syntax errors. Note that postconf can be used to alter settings, but this is beyond the scope of this manual.

From the man page: By default, the postconf(1) command displays the values of main.cf configuration parameters, and warns about possible mis-typed parameter names (Postfix 2.9 and later). It can also change main.cf configuration parameter values, or display other configuration information about the Postfix mail system.

#tail –f /var/log/mail.log

Use this command to monitor the log file to check for errors

#psql -U postfixro -d postfix

postfix# SELECT * FROM mailbox

This can be used to check that your user can query the database. I had to edit pg_hba.conf to allow local access and when I tested it I could not select so had to run the following command on the database:

GRANT SELECT ON ALL TABLES IN SCHEMA public TO postfixro

Reverse PTR record

If your ISP is useless then getting them to assign a reverse PTR record for your given domain is slim to 0.  The only way around this is to find the hostname that they have assigned to your ip and use that in your postfix configuration.  First thing to do is

dig -x XXX.XXX.XXX.XXX

where xxx.xxx.xxx.xxx is your service provider’s assigned static ip address

The reverse lookup should return a domain name in the answer section

static-xxx-xxx-xxx-xxx.vodafonexdsl.co.uk

You will need to then edit your /etc/postfix/main.cf file so that it uses this domain name for both the banner and the HELO name. To do that go ahead and open main.cf with your favourite editor and add the line:

smtp_helo_name = static-xxx-xxx-xxx-xxx.vodafonexdsl.co.uk

You will also need to change the banner to match:

#smtpd_banner = $myhostname ESMTP $mail_name (Debian/GNU)
smtpd_banner = static-xxx-xxx-xxx-xxx.vodafonexdsl.co.uk

Comment out the existing line and add a new one for your isp assigned hostname.  This does not affect how you connect to your mail server, you can carry on using whatever you used previously, it is simply a workaround for poor service from your internet service provider.