Postfixadmin – setup/install guide for virtual mail users on Postfix

This is a re-hash of the various guides I’ve made over the years detailing how to setup a virtual mail server (i.e. one that can handle multiple domains/users).

This guide is based on release 2.3 of Postfixadmin. It’s about the only open source project I contribute to regularly – so I ought to at least make an effort and document it 🙂

Requirements:

  • Linux Server (Debian, Ubuntu, CentOS, SuSE) or FreeBSD etc
  • PostgreSQL or MySQL database
  • PHP 5.2.x or greater
  • Postfix
  • Courier / Cyrus / Dovecot (as appropriate) (I only use Courier, so am of little help with the others).

Postfixadmin Installation

This assumes version 2.3 or above.

dpkg -i postfixadmin-xxxxx.deb

There are also rpm’s around somewhere for SuSE/RH, a port in FreeBSD or you can install from source.

Using the .deb, the database should be created for you, along with some configuration options being filled in within config.inc.php.

  1. Visit setup.php – it will prompt you to create a setup_password, which needs putting into the config.inc.php file
  2. After editing config.inc.php, re-visit setup.php and follow it through – this will create the admin user and setup the initial DB structure
  3. Your database should now be installed
  4. You may wish to edit other config.inc.php settings (e.g. to turn vacation support on/off or to turn xmlrpc support on/off).

If you perform an upgrade of Postfixadmin in the future, all upgrades to the database should be handled automatically through use of ‘upgrade.php’.

Postfix configuration

There are a few changes that need making to Postfix, firstly – it’s necessary to tell it to use a relational database for various lookups (e.g. aliases and mailboxes); it’s also necessary to configure it to support vacation/auto-reply emails – if you require this functionality.

In my case, I run Postfix on Debian Lenny – other platforms may vary slightly. To attempt at being ‘tidy’ the configuration files for PostgreSQL live in /etc/postfix/pgsql.

(If you’re security concious, especially when you own Daisy slots or any online betting site, then you might want to ensure the database ‘postfix’ user only has read permissions)

Note: I’ve not used the proper alias domains stuff yet – if you wish to use it, check the supplied documentation with Postfixadmin (POSTFIX_CONF.txt)

File: relay_domains.cf

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

File: virtual_alias_maps.cf

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

File: virtual_domains_maps.cf

user = postfix
password = something
hosts = localhost
dbname = postfix
#query = SELECT domain FROM domain WHERE domain='%s'
#optional query to use when relaying for backup MX
query = SELECT domain FROM domain WHERE domain='%s' and backupmx = false and active = true

File: virtual_mailbox_limits.cf

# Used for QUOTA!
user = postfix
password = something
hosts = localhost
dbname = postfix
query = SELECT quota FROM mailbox WHERE username='%s'

(Note: I’ve never used quota support, so I can’t guarantee the above is correct)

File: virtual_mailbox_maps.cf

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

To /etc/postfix/main.cf add the following :

relay_domains = <whatever may have been here before> proxy:pgsql:/etc/postfix/pgsql/relay_domains.cf
virtual_alias_maps = proxy:pgsql:/etc/postfix/pgsql/virtual_alias_maps.cf
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_mailbox_base = /var/mail/vmail
virtual_mailbox_limit = 512000000
virtual_minimum_uid = 8
virtual_transport = virtual
virtual_uid_maps = static:8
virtual_gid_maps = static:8
local_transport = virtual
local_recipient_maps = $virtual_mailbox_maps
# this is only needed if you want vacation support -
transport_maps = hash:/etc/postfix/transport

Adding the 'proxy:' to the various lookup lines should improve performance/scalability.

Courier configuration

Courier needs configuring to know how to authorise clients and where to find mailboxes on disk.

/etc/courier/authdaemonrc :

– Enable the appropriate module – e.g.

authmodulelist=”authpgsql”

And then in ‘authpgsqlrc’ contains :

PGSQL_HOST        localhost
PGSQL_PORT        5432
PGSQL_USERNAME        postfix
PGSQL_PASSWORD        something
PGSQL_DATABASE         postfix
PGSQL_USER_TABLE    mailbox
PGSQL_CRYPT_PWFIELD    password
PGSQL_UID_FIELD        ‘8’
PGSQL_GID_FIELD        ‘8’
PGSQL_LOGIN_FIELD    username
PGSQL_HOME_FIELD    ‘/var/mail/vmail’
PGSQL_NAME_FIELD    name
PGSQL_MAILDIR_FIELD    maildir
PGSQL_QUOTA_FIELD    quota

(As you can see, I’ve elected to store the mail under /var/mail/vmail with file ownerships set to 8:8. Your installation may differ – but obviously ensure this is kept in sync with Postfix’s main.cf).

This would probably be a good time to test the system to ensure authentication works correctly – create a virtual mailbox through Postfixadmin and tail -f /var/log/mail.log and see if you can login via pop3/imap etc.

SMTP Authentication

This is often useful to allow remote clients to relay through the server – assuming they can prove who they are!

Postfix can use SASL for authentication  – this requires SASL to be told to use imap to perform the authentication checks.

File: /etc/sasl/smtpd.conf
pwcheck_method: saslauthd
saslauthd_path: /var/run/saslauthd/mux
log_level: 3
mech_list: PLAIN LOGIN
auxprop_plugin: rimap

On Debian, I have sasl2-bin, libsasl2-modules and libsasl7 packages installed.

You’ll need to edit /etc/default/saslauthd and ensure it has :

OPTIONS=”-c -r  -O localhost -m /var/spool/postfix/var/run/saslauthd”

You may also need to explicitly create the above path.

Create /etc/postfix/sasl/smtpd.conf with :

pwcheck_method: saslauthd
saslauthd_path: /var/run/saslauthd/mux
log_level: 3
mech_list: PLAIN LOGIN
auxprop_plugin: rimap

And ensure /etc/postfix/main.cf has :

smtpd_sasl_authenticated_header = yes
smtpd_sasl_auth_enable = yes
smtpd_sasl_security_options = noanonymous
broken_sasl_auth_clients = yes

And smtpd_sender_restrictions contains ‘permit_sasl_authenticated’

Squirrelmail-postfixadmin

If you wish to allow your users to change their passwords/forwarding settings or vacation/auto-reply settings, a postfixadmin plugin is available for squirrelmail (squirrelmail-postfixadmin). You can download it from https://github.com/postfixadmin/postfixadmin/tree/master/ADDITIONS/squirrelmail-plugin

The latest version of the plugin works over XMLRPC and requires very minimal configuration – you’ll need to edit the config file within the plugin to specify the XMLRPC interface URL (http://server/postfixadmin/xmlrpc.php). It’s also necessary to edit the Postfixadmin config.inc.php file to explicitly enable the xmlrpc interface.

Note, when your users go to use the postfixadmin-squirrelmail plugin they will be prompted to enter their mailbox password.

37 Replies to “Postfixadmin – setup/install guide for virtual mail users on Postfix”

  1. Wonderful guide, after searching the web for a few hours I finally found a simply, easy-to-read guide which even I could follow 😀

  2. The .deb package seems to install the site to /usr/share/postfixadmin when your install procedure never mentions anything about either modifying this location, or creating symlinks to accomodate your web server configuration, or changing your web server configuration to fit. I think it deserves some kind of mention at least.

  3. Good documentation, thanks.
    Could you provide some pointers on setting up xmlrpc? I don’t think we have it currently active on our Debian system. If we don’t use xmlrpc, can we continue to use the old config.php syntax, adding the mysql login and password, etc?

  4. Here is my maildroprc with that the courier quota work out of the box with postfixadmin and you dont need to patch anything:

    hope someone can use it.

    # —– BEGIN CONFIGURATION —–
    #
    # All values *must* be inside quotes.
    # Quotes are required!!!
    ##

    SHELL=”/bin/bash”
    SENDMAIL=”/usr/sbin/sendmail”
    MAILDROP=”/usr/bin/maildrop”
    FORMAIL=”/usr/bin/reformail”
    ## SPAMC=”/usr/bin/spamc”
    SPAMC=”/usr/bin/spamc -x”
    SA_LEARN=”/usr/bin/sa-learn”
    TEST=”/usr/bin/test”
    VHOME=”/home/virtual”
    LOGDIR=”/var/log/maildrop”
    MAILDIRMAKE=”/usr/bin/maildirmake”
    MKDIR=”/bin/mkdir”
    CHOWN=”/bin/chown”
    CHMOD=”/bin/chmod”

    # —– END CONFIGURATION —–
    # —– DO NOT MAKE CHANGES PAST THIS LINE —–

    logfile “$LOGDIR/maildrop.log”

    RECIPIENT=tolower(“$1”)
    USER=tolower(“$2”)
    HOST=tolower(“$3”)
    SENDER=tolower(“$4”)
    HOME=tolower(“$5″)
    QUOTA=”$MAILDIRQUOTA””S”

    #
    # Set date/time
    #
    TICKS=`date +%s`
    DATE=`date +%T`
    TIME=`date +%x`

    DEFAULT=”$HOME”
    if ( !$HOME )
    {
    HOME=”$VHOME”
    DEFAULT=”$HOME/$HOST/$USER@$HOST”
    }

    MAILDIR=”$DEFAULT/”

    ##
    ## maildir erstellen
    ##
    # Let’s check if /home/vmail/domain.tld/username exists
    `$TEST -d “$VHOME/$HOST/$USER@$HOST/” && exit 0 || exit 1`
    if( $RETURNCODE == 1 )
    {
    log “domain und user”
    ## Now check if the domain directory /home/vmail/dominio.tld exists.
    `$TEST -d “$VHOME/$HOST/” && exit 0 || exit 1`
    if( $RETURNCODE == 1 )
    {
    log “domain”
    `$MKDIR -p “$VHOME/$HOST”`
    log “Domain neu erstellt”
    }
    log “user”
    `$MAILDIRMAKE “$VHOME/$HOST/$USER@$HOST”`
    ## Quotas fuer maildir erstellen

    ## checken ob quotas auf 0 oder -1 gestellt sind
    if( $QUOTA > “0” )
    {
    log “quotas 0 maildirmake”
    `$MAILDIRMAKE -q $QUOTA “$VHOME/$HOST/$USER@$HOST/”`
    log “User Dir neu erstellt”
    }
    }
    ## quotas checken und bei aenderung in der DB updaten
    if( $RETURNCODE == 0 )
    {
    log “quota update”
    ## checken ob quotas auf 0 oder -1 gestellt sind
    if( $QUOTA > “0” )
    {
    log “quotas updates quotas nicht 0”
    `$MAILDIRMAKE -q $QUOTA “$VHOME/$HOST/$USER@$HOST/”`
    }
    else
    {
    log “quotas update quotas 0”
    ## Falls quotas auf 0 oder -1 dann wird das quota file geloescht
    `$TEST -d “$VHOME/$HOST/$USER@$HOST/maildirsize” && exit 0 || exit 1`
    if( $RETURNCODE == 1 )
    {
    log “quotas 0 sizefile loeschen”
    `rm “$VHOME/$HOST/$USER@$HOST/maildirsize”`
    }
    }
    }
    ##

    ## log file
    logfile “$LOGDIR/maildrop.log”

    #
    # Check for admin user .adminfilter file
    #
    ADMIN_FILTER=”$DEFAULT/.adminfilter”
    `$TEST -e $ADMIN_FILTER && exit 0 || exit 1`
    if ( $RETURNCODE == 0 )
    {
    exception {
    log “$TICKS : >>> Including $ADMIN_FILTER”
    include “$ADMIN_FILTER”
    }
    }

    to “$MAILDIR”

    exit

  5. Hi,
    thx for this nice tutorial, i installed postfixadmin a while back and have to upgrade now after a disk crash.

    although i’m using mysql, i’ve mapped my sql config and postfix/courrier pop works fine, as well as virtual mail delivery.
    Mail accounts can be retrieved thru pop without error but i have the following problem :

    sasl authentication fails for smtp and i have noticed a few things that differs on my debian from yours.

    first saslauthd seems to work and postfix queries it for smtpd action but salsauthd fails to authenticate account information, for an unknown reason.

    i have the following saslauthd sequence :
    saslauthd[24963] :rel_accept_lock : released accept lock
    saslauthd[24964] :get_accept_lock : acquired accept lock
    saslauthd[24963] :cache_get_rlock : attempting a read lock on slot: 1412
    saslauthd[24963] :cache_lookup : [login=mail@domain.com] [service=domain.com] [realm=smtp]: not found, update pending
    saslauthd[24963] :cache_un_lock : attempting to release lock on slot: 1412
    saslauthd[24963] :do_auth : auth failure: [user=mail@domain.com] [service=smtp] [realm=domain.com] [mech=pam] [reason=PAM auth error]

    but i’ve seen you mention imap for sasl authentication and i was wondering if any imap package were required for proper use of sasl authentication ? what about PAm what kind of config does that require if any ?

    the other thing is that with my sasl packages installed (libsasl2-2, libsasl2-modules, libsasl7, sasl2-bin) i don’t have any /etc/sasl/ path
    i did create /etc/postfix/sasl/smtpd.conf as it was already present in my previous conf
    and those two files look identical so i was wondering what’s really required..

    but my main problem concerns that sasl imap thing as i don’t seem to have anything imap installed on my system, i’m wondering how sasl can access the database account info..

    i also remember fighting with cyrus sasl on my previous install, and sasl in general there was some password encryption problem at the time, is it required or can it be discarded ?

    thx for any input

  6. looks like i had to change the sasl setup and setup the pam smtp, as follows :
    (the sql matches a postfixadmin setup)

    /etc/postfix/sasl/smtpd.conf :
    pwcheck_method: saslauthd
    saslauthd_path: /var/run/saslauthd/mux
    log_level: 3
    mech_list: PLAIN LOGIN
    auxprop_plugin: mysql
    ## optional ##
    allow_plaintext: true
    sql_hostnames: 127.0.0.1
    sql_user: postfix
    sql_passwd: yourdbpass
    sql_database: postfix
    sql_select: select password from mailbox where username = ‘%u’
    ## end optional ##

    i’m not sure the #optional# statements are required as there are some others in the pam setup, but i found that conf as is. I don’t seem to need those optional statements on my setup.

    then create /etc/pam.d/smtp :
    auth required pam_mysql.so user=postfix passwd=yourdbpass host=127.0.0.1 db=postfix table=mailbox usercolumn=username passwdcolumn=password crypt=1 md5=1

    account sufficient pam_mysql.so user=postfix passwd=yourdbpass host=127.0.0.1 db=postfix table=mailbox usercolumn=username passwdcolumn=password crypt=1 md5=1

    you may have to install libpam-mysql to get mysql support in pam.
    And as i thought, it seems that /etc/sasl/smtpd.conf is not required on my debian setup.

    thx for the tutorial.

  7. Lovely! You are the first person that actually mentions how to use Postfixadmin after setup 😀

    thanks!

  8. Why do you setup these two lines?

    local_transport = virtual
    local_recipient_maps = $virtual_mailbox_maps

    They will completely skip local delivery and for example Mailman integration won’t work. What’s the advantage of these two lines?

  9. I’m bit confused of this part:

    “Create /etc/postfix/sasl/smtpd.conf with …”

    when and how then this file is readed?
    there is no definition of this in postfix config….

  10. Aiva – afaik, /etc/postfix/sasl/smtpd.conf is the default file postfix uses if you want to do smtpd authentication (i.e. allowing people to relay through your server using their mailbox username/password to identify themselves)

  11. Thanks for this input.

    I am currently looking for a way to integrate mailman into a configuration like this (on the Postfix side at least, I have dovecot for IMAP). But all I find searching for mailman and postfixadmin is people trying to figure out the same thing.

    Does anyone know a solution?


  12. This guide is based on release 2.3 of Postfixadmin. It’s about the only open source project I contribute to regularly – so I ought to at least make an effort and document it

    I have translated some part of it into french, but i don’t know where to send it. Can you email me the reference, please ?

  13. OS : debian etch
    database : mysql
    dovecot

    I always got the message
    “Setup password not specified correctly
    If you want to use the password you entered as setup password, edit config.inc.php and set
    $CONF[‘setup_password’] = ‘607cff0fb23fec6012109f2c34ec9738:f73e57a9973b40cedc1eb1fc7178198a313930ec’;”

    please help me…..

  14. Flo – do you have APC or similar op-code cache turned on, and it’s been told to not re-check the source code of files? Hence, I’d suggest restarting Apache/the web server.

    Failing that, check if config.local.php has an override for $CONF[‘setup_password’] – perhaps it contains a different one that’s overwriting the above?

    Failing that, check out #postfixadmin on irc.freenode.net

  15. hi i asked you questions.
    i have freebsd 8.1 server with apache 2, mysql, php5. this server is mail server. (postfix+squirrel mail) i want to add mailuser (over than 10000 user) automatically. how i do it? i think user in mysql table. i want to script for you if possible. Best regards

  16. Hm I set
    $CONF[‘encrypt’] = ‘cleartext’;
    Dunno why it worked, Mailbox Passwords are stored now Plain too. Sux kinda, maybe ill check myself a hardcoded md5 in SQL queries. However, later, i must go on with everything.

    Later in furtheron Setup i couldnt btw connect to DB.
    It was a “!” (exclamation mark) in the MySql Password.

    So: Users passwords in plain text, mine pass no special chars. Born to be root.

    After this setup, i took the mailbox create script and stripped/included it in order to allow users of mine System setting up Mailboxes themselfes (finally).
    That way i can use all Languages etc from Postfixadmin.
    Its working kewl.

    Now im going on with Postfix Database Setup, thats the less trivial step i would say.
    I mean: Oki Postfix Admin. When i have a Table where i can simply add rows: Im saved from creating mailboxes every day.
    Funny what can happen when u try to run a PHP script with Mysql support yey!
    Thx for the help!

  17. Thank you so much for this post! I’ve tried to set up Postfix+Postfixadmin+Courier+SASL+PostgreSQL on Ubuntu 10.10 for hours now and your solution to use the rimap method (which is way more elegant than PAM) solved all of my problems in an instant!

    Thanks again! You saved my day!

  18. how to create superadmin? keep getting “Setup password not specified correctly” encrypt=cleartext, setup password used same as the config.ini.php, what was wrong?

  19. The installer will prompt you for a setup password; after entering this it will show you a hashed string which needs to go into the config.*.php file. Once this is done, you can use the installer (/setup) to create superadmins.

  20. Let me quote a sniplet from PostfixAdmin’s INSTALL.TXT:

    There are also lots of HOWTOs around the web. Be warned that many of them may be outdated or incomplete.
    Please stick to the PostfixAdmin documentation, and use those HOWTOs only if you need some additional information that is missing in the PostfixAdmin DOCUMENTS/ folder.

    This is also true for this HowTo – the queries for alias domains are missing. David, can you please update the text? 😉

  21. Yeah – I know – I did start to write an updated version for CentOS or something similar… but then never got as far as publishing it. Taking/embedding screenshots and being explicit with instructions seemed to take forever.

  22. I was trying to use vacations with my msql domains… “transport_maps” was all that I needed thanks

Leave a Reply

Your email address will not be published. Required fields are marked *