Installing Postfix on Fedora using MySQL

From MattWiki
Jump to: navigation, search

This article is written with the goal of building an email server, that will receive mail for users with virtual email accounts stored in a MySQL database, for multiple domains. Allow you to filter your mail with SpamAssassin and other filtering tools. Also relay all outbound email threw your ISP's SMTP server using your ISP username and password. And allow your users to use both IMAP or POP3 or webmail to read there email.

Besides setting up postfix you also need to make sure your firewall is open for port 25 in order to receive emails.

This How-To was build with these specs.

Fedora 14 Postfix 2.8.5
Dovecot 2.0.15 MySQL 5.1.58
Apache 2.2.17 PostfixAdmin 2.3.4
Spamassassin 3.2.5 ClamAV 0.97.2
Squirrelmail 1.4.13-1 RoundCube 0.6
Intel Pentium III 1.0 Ghz 512 MB Ram

This is my notes on installing and setting up my mail server. Any usernames or passwords are not valid on my network.

Installing Postfix with MySQL Support

MySQL support is NOT built into Fedora's Postfix RPM's, because of this, we ether need to build them ourselves (mine are on my yum repo) or grab them from atrpms.com.

Installing from Source

See: Installing Postfix from Source

Configuring Postfix

mkdir /var/spool/virtualmailboxes/
echo "virtualmail:x:1000:1000::/var/spool/virtualmailboxes:/sbin/nologin" >> /etc/passwd
echo "virtualmail:x:1000:" >> /etc/group
chmod 700 /var/spool/virtualmailboxes/
chown -R virtualmail:virtualmail /var/spool/virtualmailboxes/

Postfix main.cf file

/etc/postfix/main.cf

These first options are mostly the defaults, but you should confirm they are correct.

queue_directory = /var/spool/postfix
command_directory = /usr/sbin
daemon_directory = /usr/libexec/postfix

The alias_maps refers to local accounts only. forward the root account to one of your virtual address and postmap the file postmap /etc/postfix/aliases

alias_maps = hash:${config_directory}/aliases

postfix is the default and the best answer.

mail_owner = postfix

This is the HELO/EHLO answer, make this your hosts full qualified domain name.

myhostname = mail.example.com

Your hosts domain name.

mydomain = example.com

The origin of this servers locally outbound domain name.

myorigin = $mydomain

What ethernet interfaces will be allowed to except email.

inet_interfaces = all

mydestination is for excepting email for the local agent. the following will not allow receiving of email for this domain, that will be covered by the virtual domain setup.

mydestination = $myhostname, localhost.$mydomain, localhost

local_recipient_map is the lookup tables with all addresses of local recipients (not virtual users).

local_recipient_maps = $alias_maps

message_size_limit (default: 10240000) in bytes, remember to give space for the messages headers also.

# Max Message Size 32505856 = 31 Mbytes
message_size_limit = 32505856

Set the mynetworks_style to subnet so the mynetworks parameter will allow local "trusted" network users to uses the outbound smtpd function without logging in.

mynetworks_style = subnet

The list of "trusted" SMTP clients that have more privileges than "strangers".

mynetworks = 192.168.1.0/24, 127.0.0.0/8

Reject messages that are not from vailed local/virtual senders (Not in alias/virtual_alias table)

smtpd_reject_unlisted_sender = yes

This is the section that allows you to block emails based on there connection info, the following options are safe.

smtpd_recipient_restrictions = 
   permit_mynetworks,  
   reject_unauth_destination,
   reject_rbl_client zen.spamhaus.org

Now we need to setup the MySQL access files, the following files do not yet exist so once were done with this file we will need to create and populate them (see below).

relay_domains = mysql:${config_directory}/mysql_relay_domains_maps.cf
virtual_alias_maps = mysql:${config_directory}/mysql_virtual_alias_maps.cf
virtual_mailbox_domains = mysql:${config_directory}/mysql_virtual_domains_maps.cf
virtual_mailbox_maps = mysql:${config_directory}/mysql_virtual_mailbox_maps.cf
virtual_mailbox_limit = mysql:${config_directory}/mysql_virtual_mailbox_limit_maps.cf
smtpd_sender_login_maps = mysql:${config_directory}/mysql_virtual_sender_maps.cf

This is the location of your virtual mailboxes, this directory needs to be owned by virtual_uid below.

virtual_mailbox_base = /var/spool/virtualmailboxes

The virtual uid and virtual gid is the user and group that will deliver the mail to the virtual_mailbox_base directory.

virtual_minimum_uid= 1000
virtual_uid_maps = static:1000
virtual_gid_maps = static:1000

And that finishes the /etc/postfix/main.cf config file.

Postfix Add On Config files

Now you need to create the following files, these file allow postfix to read from the MySQL table. /etc/postfix/mysql_relay_domains_maps.cf

user = postfix
password = postfix
hosts = localhost
dbname = postfix
query = SELECT domain FROM domain WHERE domain='%s' and backupmx = '1' and active = '1'

/etc/postfix/mysql_virtual_alias_maps.cf

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

/etc/postfix/mysql_virtual_domains_maps.cf

user = postfix
password = postfix
hosts = localhost
dbname = postfix
query = SELECT domain FROM domain WHERE domain='%s' and backupmx = '0' and active = '1'

/etc/postfix/mysql_virtual_mailbox_maps.cf

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

/etc/postfix/mysql_virtual_sender_maps.cf

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

Building the BerkeleyDB Database files

Now we need to build some of the database files required from our setup above.

/usr/bin/newaliases
/usr/sbin/postmap /etc/postfix/sasl_passwd

Creating MySQL Databases and Permissions for Postfix

First we need to create the databases for Postfix.

As root run the following

mysqladmin create postfix

Now we need to create a user to use with Postfix.

mysql
grant all on postfix.* to postfix@"localhost" identified by "postfix";

Assuming both those commands finished successfully you can exit mysql.

exit

You have now added the needed databases and user and gave then the correct permissions. We will not add the Postfix tables now, since PostfixAdmin will add them during the set-up process.

TLS Support

Note Note: This section assumes that you have a working CA and PEM files, please see the TLS section for more information

For TLS Support add the following to /etc/postfix/main.cf.

smtpd_tls_CAfile = /etc/postfix/cacert.pem
smtpd_tls_cert_file = /etc/postfix/smtpd.pem
smtpd_tls_key_file = /etc/postfix/postfix-key.pem
smtpd_tls_loglevel = 1
smtpd_tls_security_level = may

If you have a pre-setup pem key this should work with you only needing to change the smtpd_tls_cert_file parameter. If you don't have a pre-setup key then look at the TLS page for setup information.

SASL Authentication for outbound email

(notice it's smtp) The next-hop destination of non-local (to this server) mail. If your ISP requires you to use one of there relay servers, place it here.

relayhost = [smtp.comcast.net]:587
smtp_sasl_auth = yes
smtp_sasl_password_maps = hash:/etc/postfix/sasl_passwd

And your ISP's username and password in /etc/postfix/sasl_passwd

<Offsite-SMTP-Server> <Offsite-Username>:<Offsite-Password>

PostfixAdmin

PostfixAdmin will allow you to add, delete and edit mailboxes and full domains. This web based app access you MySQL config for postfix and edits it directly.

Installing PostfixAdmin's Prerequisites

Using Apache

yum install httpd mysql mysql-server php php-mysql php-mbstring subversion

Now setup the programs to start up when the system start then start them.

/sbin/chkconfig httpd on
/sbin/chkconfig mysqld on
/sbin/service httpd start
/sbin/service mysqld start

Using Lighttpd

yum install lighttpd lighttpd-fastcgi mysql mysql-server php-cli php-imap php-mysql php-mbstring subversion

To use Lighttpd you need to configure your lighttpd.conf file, uncomment the following lines.

  • /etc/lighttpd/lighttpd.conf
fastcgi.server             = ( ".php" =>
                               ( "localhost" =>
                                 (
                                   "socket" => "/var/run/lighttpd/php-fastcgi.socket",
                                   "bin-path" => "/usr/bin/php-cgi"
                                 )
                               )
                            )

Now setup the programs to run properly

/sbin/chkconfig lighttpd on
/sbin/chkconfig mysqld on
/sbin/service lighttpd start
/sbin/service mysqld start

PostfixAdmin Download and Install

We will be using the Subversion version of Postfix Admin. First you need to deside where you would like your Postfix Admin install to live, mine will live under apache's root dirctory

With Apache

cd /var/www/html/
svn co https://postfixadmin.svn.sourceforge.net/svnroot/postfixadmin/trunk postfixadmin
cd postfixadmin

With Lighttpd

cd /var/www/lighttpd/
svn co https://postfixadmin.svn.sourceforge.net/svnroot/postfixadmin/trunk postfixadmin
cd postfixadmin

Now you have the current version of Postfix Admin.

PostfixAdmin Config File

  • see: PostfixAdmin
  • /var/www/html/postfixadmin/config.inc.php or /var/www/lighttpd/postfixadmin/config.inc.php

General Options

TFirst thing to do is to tell postfix that you have configure the app.

$CONF['configured'] = true;

The full url of your postfix admin build

$CONF['postfix_admin_url'] = 'https://mail.example.com/postfixadmin';

Database Setup

Next you need to setup your database connection. Since I'm using MySQL this is my setup. I think the setup is pretty self explanatory.

$CONF['database_type'] = 'mysql';
$CONF['database_host'] = 'localhost';
$CONF['database_user'] = 'postfix';
$CONF['database_password'] = 'postfix';
$CONF['database_name'] = 'postfix';
$CONF['database_prefix'] = ;

The email address that all problems will be reported to and the sender of site wide messages.

$CONF['admin_email'] = 'postmaster@example.com';

The location and port of the SMTP server for site messages.

$CONF['smtp_server'] = 'localhost';
$CONF['smtp_port'] = '25';

In what way do you want the passwords to be crypted?

$CONF['encrypt'] = 'md5';

Minimum length required for passwords. (Admins can set shorter passwords but users can't)

$CONF['min_password_length'] = 7;

The default aliases that need to be created for all domains.

$CONF['default_aliases'] = array (
    'postmaster' => 'postmaster@example.com',
);

Mailbox Setup

If you want to store the mailboxes per domain set this to 'YES'. (Example: /usr/local/virtual/example.com/username@example.com

$CONF['domain_path'] = 'YES';

If you don't want to have the domain in your mailbox set this to 'NO'. (Example: /usr/local/virtual/example.com/username)

$CONF['domain_in_mailbox'] = 'YES';

Default Domain Values. Specify your default values below. Quota in MB.

$CONF['aliases'] = '0';
$CONF['mailboxes'] = '0';
$CONF['maxquota'] = '512';

Quota Setup

If you wish to enforce quota for your mailbox users set this to 'YES'.

$CONF['quota'] = 'YES';
// You can either use '1024000' or '1048576'
$CONF['quota_multiplier'] = '1024000';

Transport Setup

If you want to define additional transport options for a domain set this to 'YES'.

$CONF['transport'] = 'YES';

If you want to define additional transport options put them in array below.

$CONF['transport_options'] = array (
    'virtual',  // for virtual accounts
    'local',    // for system accounts
    'relay'     // for backup mx
);

Transport default

$CONF['transport_default'] = 'virtual';

Alias Control

Postfix Admin inserts an alias in the alias table for every mailbox it creates. The reason for this is that when you want catch-all and normal mailboxes to work you need to have the mailbox replicated in the alias table. If you want to take control of these aliases as well set this to 'YES'.

$CONF['alias_control'] = 'YES';

Alias Control for admins.

$CONF['alias_control_admin'] = 'YES';

Welcome Message

This message is send to every newly created mailbox.

$CONF['welcome_text'] = <<<EOM
Hi,

Welcome to your new account.
EOM;

Misc Options

When creating mailboxes, check that the domain-part of the address is legal by performing a name server look-up.

$CONF['emailcheck_resolve_domain']='YES';

PostfixAdmin Webbased Setup

Next go to the URL that you have set in PostfixAdmin, and go to the setup page.

http://mail.example.com/postfixadmin/setup.php

This page will setup the database for you and also test your system to confirm its all running correctly.

Dovecot

Installing Dovecot

First you need to download the lastest dovecot release from http://dovecot.org/download.html and untar it.

wget http://dovecot.org/releases/1.1/dovecot-1.1.1.tar.gz
tar -xzf dovecot-1.1.1.tar.gz
cd dovecot-1.1.1

To setup the environment (the "--enable-header-install" option is for Dovecot-SASL).

./configure --with-mysql --enable-header-install
echo $?

Now to compile the program

make
echo $?

And to install it

make install
echo $?

Were going to leave the dovecot daemon down for now until we setup the full program.

Configuring Dovecot

  • /etc/dovecot.conf
## Dovecot configuration file
protocols = imap
login_user = postfix
listen =
ssl_listen =
ssl_disable = no
ssl_cert_file = /etc/postfix/smtpd.pem
ssl_key_file = /etc/postfix/smtpd.pem
auth_cache_size = 128
auth_cache_ttl = 600
mail_debug = no

#The below needs to be put on a single line, not two like is shown here.
mail_location = maildir:/var/spool/virtualmailboxes/%d/%u/imap/:INBOX=/var/spool/virtualmailboxes/%d/%u/:
INDEX=/var/spool/virtualmailboxes/%d/%u/imap/index/

protocol imap {
 listen = *:143
 mail_plugins = quota imap_quota
}

protocol lda {
  postmaster_address = postmaster@mattrude.com
  hostname = samantha.mattrude.com
  mail_plugins = cmusieve
  mail_plugins = quota
  sieve_global_path = /var/spool/sieve/dovecot.sieve
  mail_plugin_dir = /usr/local/lib/dovecot/lda
  auth_socket_path = /usr/local/var/run/dovecot/auth-master
}

namespace private {
  separator = /
  prefix =
  inbox = yes
}

auth default {
  mechanisms = plain login
  userdb sql {
    args = /etc/dovecot-mysql.conf
  }
  passdb sql {
    args = /etc/dovecot-mysql.conf
  }
  socket listen {
    master {
      path = /var/run/dovecot/auth-master
      user = virtualmail
      group = virtualmail
    }
    client {
      path = /var/spool/postfix/private/auth
      mode = 0660
      user = postfix
      group = postfix
    }
  }
}

dict {
}

plugin sql {
# 10 MB Default Mailbox Size Limit
  quota = maildir:storage=10240
#  quota = maildir:ignore=Trash
#  quota = maildir:ignore=Junk
}
  • /etc/dovecot-mysql.conf
driver = mysql
connect = dbname=postfix user=postfix host=localhost password=postfix
default_pass_scheme = PLAIN-MD5
password_query = SELECT password, username AS user FROM mailbox WHERE username = '%u'

#The below needs to be put on a single line, not two like is shown here.
user_query = SELECT maildir, 1000 AS uid, 1000 AS gid, CONCAT('maildir:storage=', ROUND( mailbox.quota / 1024 ) ) 
AS quota FROM mailbox WHERE username = '%u' AND active = '1'

Now since we compiled from source, you need to link the config files you just created to /usr/local/etc/ directory.

ln -s /usr/local/etc/dovecot.conf /etc/dovecot.conf
ln -s /usr/local/etc/dovecot-mysql.conf /etc/dovecot-mysql.conf

Setting up Dovecot's SASL Authentication

When we use Dovecot SASL authentication we are only going to use it on the submission port (587). To do this add the following to your /etc/postfix/main.cf

  • /etc/postfix/main.cf
# SASL Support
smtpd_sasl_type = dovecot
smtpd_sasl_path = /var/spool/postfix/private/auth
smtpd_sasl_security_options = noanonymous

Note that we didn't add smtpd_sasl_auth_enable to the main.cf file, this is so we can only enable SASL authentication on the submission port (587). Are you going to allow Outlook on your network?

broken_sasl_auth_clients = yes
Note Note: The below assumes you have enabled TLS support in Postfix, if you have not, remove smtpd_tls_security_level.

So now in the /etc/postfix/master.cf add or uncomment the following.

submission inet n       -       n       -       -       smtpd
        -o smtpd_tls_security_level=encrypt
        -o smtpd_sasl_auth_enable=yes
        -o smtpd_client_restrictions=permit_sasl_authenticated,reject
        -o milter_macro_daemon_name=ORIGINATING

Setting up Spamassassin to Postfix's Mail Processing

Note Note: This section assumes you have a running Spamassassin installation.


In /etc/postfix/master.cf, add -o content_filter=spamassassin

# ==========================================================================
# service type  private unpriv  chroot  wakeup  maxproc command + args
#               (yes)   (yes)   (yes)   (never) (50)
# ==========================================================================
smtp      inet  n       -       -       -       -       smtpd                
         -o content_filter=spamassassin
  • Then, at the end of the file, you must tell postfix what the content filter "spamassassin" should do. Add the following lines:
spamassassin unix -     n       n       -       -       pipe
       flags=Rq user=nobody argv=/usr/bin/spamc -u ${recipient} -e /usr/sbin/sendmail \
 -oi -f ${sender} ${recipient}

Setting up the Clam Anti-Virus system with ClamSMTP

Note Note: This section assumes you have a running ClamAV installation and a running ClamSMTP daemon.


First in /etc/postfix/main.cf, add:

content_filter = scan:127.0.0.1:10025
receive_override_options = no_address_mappings

Then in /etc/postfix/master.cf, near the bottom, add:

# AV scan filter (used by content_filter)
scan      unix  -       -       n       -       16      smtp
        -o smtp_send_xforward_command=yes
# For injecting mail back into postfix from the filter
127.0.0.1:10026 inet  n -       n       -       16      smtpd
        -o content_filter=
        -o receive_override_options=no_unknown_recipient_checks,no_header_body_checks
        -o smtpd_helo_restrictions=
        -o smtpd_client_restrictions=
        -o smtpd_sender_restrictions=
        -o smtpd_recipient_restrictions=permit_mynetworks,reject
        -o mynetworks_style=host
        -o smtpd_authorized_xforward_hosts=127.0.0.0/8

Setting up SPF filter for inbound mail

Were going to use python-postfix-policyd-spf 0.7.1 from openspf.org.

wget http://www.openspf.org/blobs/pypolicyd-spf-0.7.1.tar.gz
tar -xzf pypolicyd-spf-0.7.1.tar.gz
cd pypolicyd-spf-0.7.1
./setup.py build
cd build/scripts-2.5/
cp -f policyd-spf /usr/local/bin/policyd-spf
cd ../lib
cp -f policydspfsupp.py /usr/lib/python2.5/policydspfsupp.py
cd ../../
mkdir /etc/python-policyd-spf/
cp -f policyd-spf.conf /etc/python-policyd-spf/policyd-spf.conf
cp -f policyd-spf.1 /usr/share/man/man1/policyd-spf.1
cp -f policyd-spf.conf.5 /usr/share/man/man5/policyd-spf.conf.5

Next we need to update the main.cf file /etc/postfix/main.cf

As close to the bottom of your smtpd_recipient_restrictions as you can but above any DNSBL add the following.

smtpd_recipient_restrictions =
  check_policy_service unix:private/policy
policy_time_limit = 3600

Now we need to setup the master.cf file /etc/postfix/master.cf

Add the following to your master.cf file, somewhere near the bottom.

policy     unix  -       n       n       -       -       spawn
       user=nobody argv=/usr/local/bin/policyd-spf

Next lets reload postfix

postfix reload

Monit Inclusion

Note Note: This section asumes that you have a running Monit daemon.

If you are running Monit then you can add the following to your /etc/monitrc file then reload Monit (monit reload). The following dose asumme a lot, mostly that you followed the above example nearly to the tee. Be careful with Monit so you don't crash a running program.

  • /etc/monitrc
check device root with path /
 if space > 80 % THEN ALERT

check process clamav with pidfile /var/run/clamav/clamd.pid
 group email
 start program = "/etc/init.d/clamav start"
 stop  program = "/etc/init.d/clamav stop"
 if 50 restarts within 52 cycles then timeout
 if cpu usage > 80% for 5 cycles then alert
 if mem usage > 80% for 5 cycles then alert

check process clamsmtp with pidfile /var/run/clamav/clamsmtpd.pid
 group email
 depends on clamav
 start program = "/etc/init.d/clamsmtpd start"
 stop  program = "/etc/init.d/clamsmtpd stop"
 if 50 restarts within 52 cycles then timeout
 if cpu usage > 80% for 5 cycles then alert
 if mem usage > 80% for 5 cycles then alert

check process dovecot with pidfile /usr/local/var/run/dovecot/master.pid
 group email
 depends on mysql
 start program = "/etc/init.d/dovecot start"
 stop  program = "/etc/init.d/dovecot stop"
 if 50 restarts within 52 cycles then timeout
 if cpu usage > 80% for 5 cycles then alert
 if mem usage > 80% for 5 cycles then alert

check process freshclam with pidfile /var/run/clamav/freshclam.pid
 group email
 depends on clamav
 start program = "/etc/init.d/freshclam start"
 stop  program = "/etc/init.d/freshclam stop"
 if 50 restarts within 52 cycles then timeout
 if cpu usage > 80% for 5 cycles then alert
 if mem usage > 80% for 5 cycles then alert

check process postfix with pidfile /var/spool/postfix/pid/master.pid
 group email
 depends on mysql
 start program = "/etc/init.d/postfix start"
 stop  program = "/etc/init.d/postfix stop"
 if 50 restarts within 52 cycles then timeout
 if cpu usage > 80% for 5 cycles then alert
 if mem usage > 80% for 5 cycles then alert

check process saslauthd with pidfile /var/run/saslauthd/saslauthd.pid
 group email
 depends on postfix
 start program = "/etc/init.d/saslauthd start"
 stop program = "/etc/init.d/saslauthd stop"
 if 50 restarts within 52 cycles then timeout
 if cpu usage > 80% for 5 cycles then alert
 if mem usage > 80% for 5 cycles then alert

check process spamd with pidfile /var/run/spamd.pid
 group email
 depends on mysql
 start program = "/etc/init.d/spamassassin start"
 stop  program = "/etc/init.d/spamassassin stop"
 if 50 restarts within 52 cycles then timeout
 if cpu usage > 80% for 5 cycles then alert
 if mem usage > 80% for 5 cycles then alert

check process mysql with pidfile /var/run/mysqld/mysqld.pid
 group email
 start program = "/etc/init.d/mysqld start"
 stop program = "/etc/init.d/mysqld stop"
 if failed port 3306 then restart
 if 50 restarts within 52 cycles then timeout
 if cpu usage > 80% for 5 cycles then alert
 if mem usage > 80% for 5 cycles then alert

check file aliases path /etc/postfix/aliases
 group email
 if changed sha1 checksum
   then exec "/usr/bin/newaliases"
 if failed permission 0644
   then exec "/bin/chmod 0644 /etc/postfix/aliases"
 if failed uid 0
   then exec "/bin/chown 0 /etc/postfix/aliases"
 if failed gid 0
   then exec "/bin/chown 0:0 /etc/postfix/aliases"

check file main.cf path /etc/postfix/main.cf
 group email
 if failed permission 0644
   then exec "/bin/chmod 0644 /etc/postfix/main.cf"
 if failed uid 0
   then exec "/bin/chown 0 /etc/postfix/main.cf"
 if failed gid 0
   then exec "/bin/chown 0:0 /etc/postfix/main.cf"

check file master.cf path /etc/postfix/master.cf
 group email
 if failed permission 0644
   then exec "/bin/chmod 0644 /etc/postfix/master.cf"
 if failed uid 0
   then exec "/bin/chown 0 /etc/postfix/master.cf"
 if failed gid 0
   then exec "/bin/chown 0:0 /etc/postfix/master.cf"

check file sasl_passwd path /etc/postfix/sasl_passwd
 group email
 if changed sha1 checksum
   then exec "/usr/sbin/postmap /etc/postfix/sasl_passwd && /usr/sbin/postfix reload"
 if failed permission 0644
   then exec "/bin/chmod 0644 /etc/postfix/sasl_passwd"
 if failed uid 0
   then exec "/bin/chown 0 /etc/postfix/sasl_passwd"
 if failed gid 0
   then exec "/bin/chown 0:0 /etc/postfix/sasl_passwd"

check file transport path /etc/postfix/transport
 group email
 if changed sha1 checksum
   then exec "/usr/sbin/postmap /etc/postfix/transport && /usr/sbin/postfix reload"
 if failed permission 0644
   then exec "/bin/chmod 0644 /etc/postfix/transport"
 if failed uid 0
   then exec "/bin/chown 0 /etc/postfix/transport"
 if failed gid 0
   then exec "/bin/chown 0:0 /etc/postfix/transport"

check directory clamav_virus_dir path "/tmp/clamav"
 group email
 start program = "/bin/mkdir /tmp/clamav"
 if failed permission 0700 then exec "/bin/chmod 0700 /tmp/clamav"
 if failed uid 509 then exec "/bin/chown 509 /tmp/clamav"
 if failed gid 509 then exec "/bin/chown 509:509 /tmp/clamav"

check directory postfix_config_dir path "/etc/postfix"
 group email
 if failed permission 0755 then exec "/bin/chmod 0755 /etc/postfix"
 if failed uid 0 then exec "/bin/chown 0 /etc/postfix"
 if failed gid 0 then exec "/bin/chown 0:0 /etc/postfix"

check directory virtualmailboxes_dir path "/var/spool/virtualmailboxes"
 group email
 start program = "/bin/mkdir /var/spool/virtualmailboxes"
 if failed permission 0700
   then exec "/bin/chmod 777 /var/spool/virtualmailboxes && /bin/chmod -R u=rwX,go-rwx /var/spool/virtualmailboxes/"
 if failed uid 1000
   then exec "/bin/chown -R 1000 /var/spool/virtualmailboxes/"
 if failed gid 1000
   then exec "/bin/chown -R 1000:1000 /var/spool/virtualmailboxes/"

Testing Postfix