Installation

How to install

Download the latest Modoboa’s tarball and extract it:

$ tar xzf modoboa-<version>.tar.gz
$ mv modoboa-<version> modoboa
$ cd modoboa

Then, enter the modoboa directory, create a settings.py file (you can use settings-sample.py as a model). Specify database relative informations. You must choose between MySQL, PostgreSQL or sqlite, other types are not supported by major email projects like postfix or dovecot.

Create a database with the name you specified in settings.py. Make sure your database is using UTF8 as a default charset. If not, you will surely have problems (with MySQL at least). You will probably need to install a python database backend (like MySQLdb).

Initialize the database by running the following command:

$ python manage.py syncdb --migrate

It will let you create the default super administrator.

Since version 0.8, Modoboa uses south to handle schema migrations, this is the reason why you must add the --migrate option.

Finally, create the scripts directory:

$ mkdir scripts

Time zone and language

Modoboa is available in english, french, german and spanish. You can choose which language to use by modifying the LANGUAGE_CODE variable inside settings.py:

LANGUAGE_CODE = 'en-US' # English
# or
LANGUAGE_CODE = 'fr-FR' # French
# or
LANGUAGE_CODE = 'de-DE' # German
# or
LANGUAGE_CODE = 'es-ES' # Spanish

You can also specify your time zone by modifying the TIME_ZONE variable. For example:

TIME_ZONE = 'Europe/Paris'

Default configuration

Throught the Admin > Configuration panel, you can customize the way Modoboa stores mailboxes on the filesystem. Here is the list of editable parameters with their default value:

Where Modoboa stores mailboxes
STORAGE_PATH = /var/vmail

Which user:group Modoboa uses to assign permissions on mailboxes
VIRTUAL_UID = vmail
VIRTUAL_GID = vmail

Which format is used to store messages in a mailbox
MAILBOX_TYPE = maildir

If maildir is in use, tells Modoboa that mailbox content is under a
potential sub-directory
MAILDIR_ROOT = .maildir

Which encryption method is used to store passwords
PASSWORD_SCHEME = crypt

Host configuration

Before using Modoboa, you must create a group and a user that will be used to store emails on the host filesystem. There is only one group/user needed because we are in a virtual hosting configuration (ie. users with non-UNIX accounts). Following examples are based on default values presented in Default configuration.

For example, create a vmail group:

$ groupadd vmail

Then create a vmail user:

$ useradd -g vmail -d /var/vmail -m vmail

At last, the system user used to run modoboa will need permissions to manipulate directories in vmail’s homedir. To do so, edit the /etc/sudoers file and add the following inside:

<user_that_runs_modoboa> ALL=(vmail) NOPASSWD: ALL

Secret key used to encrypt passwords in sessions

Since version 0.8.5, the SECRET_KEY parameter was moved from the webmail plugin to the auth application. The reason is simple : multiple plugins need to store the user password in the current session. This parameter needed to be centralised.

In the Admin > Configuration, click on the Auth section and modify the SECRET_KEY parameter. Choose a new value (exactly 16 characters). This key is really important, it is used to encrypt/decrypt user passwords stored inside sessions.

Note

Do not communicate this key to anyone!!

Testing installation

As a typical Django application, Modoboa can be tested using a simple web server. Just run this command to start it:

$ python manage.py runserver

You will be able to play with Modoboa by looking at http://<youraddress>:8000/modoboa/admin/.

External authentication backend

LDAP

Modoboa supports external LDAP authentication using the following extra components:

If you want to use this feature, you must first install those components:

$ easy_install python-ldap django-auth-ldap

Then, all you have to do is to modify the settings.py file:

  • Add a new authentication backend to the AUTHENTICATION_BACKENDS variable, like this:

    AUTHENTICATION_BACKENDS = (
      'django_auth_ldap.backend.LDAPBackend',
      'django.contrib.auth.backends.ModelBackend',
      'modoboa.lib.authbackends.SimpleBackend'
    )
    
  • Set the required parameters to establish the communication with your LDAP server, for example:

    import ldap
    from django_auth_ldap.config import LDAPSearch
    
    AUTH_LDAP_BIND_DN = ""
    AUTH_LDAP_BIND_PASSWORD = ""
    LDAP_USER_BASE = "ou=users,dc=example,dc=com"
    LDAP_USER_FILTER = "(mail=%(user)s)"
    AUTH_LDAP_USER_SEARCH = LDAPSearch(LDAP_USER_BASE,
        ldap.SCOPE_SUBTREE, LDAP_USER_FILTER)
    

You will find a detailled documentation here.

Once the authentication is properly configured, the users defined in your LDAP directory will be able to connect to Modoboa, the associated domain and mailboxes will be automatically created if needed.

Users will also be able to update their LDAP password directly from Modoboa.

Note

Modoboa doesn’t provide any synchronization mechanism once a user is registered into the database. Any modification done from the directory to a user account will not be reported to Modoboa (an email address change for example). Currently, the only solution is to manually delete the Modoboa record, it will be recreated on the next user login.

Available settings

  • LDAP_USER_BASE : the distinguish name of the search base
  • LDAP_USER_FILTER : the filter used to retrieve users distinguish name
  • LDAP_PASSWORD_ATTR : the attribute used to store the password (default: userPassword)
  • LDAP_ACTIVE_DIRECTORY : used to indicate if your directory is an Active Directory one (default: False)

How to upgrade

First, decompress the new tarball at the same location than your current installation. Then, check if the new version you’re installing requires a migration.

Note

Before executing a schema/data migration, I recommend that you make a copy of your existing database.

0.8.8: CSV import feature and minor fixes

  1. Edit the settings.py file and 'modoboa.lib.middleware.AjaxLoginRedirect' to the MIDDLEWARE_CLASSES variable like this:

    MIDDLEWARE_CLASSES = (
      'django.middleware.common.CommonMiddleware',
      'django.contrib.sessions.middleware.SessionMiddleware',
      'django.contrib.auth.middleware.AuthenticationMiddleware',
      'django.contrib.messages.middleware.MessageMiddleware',
      'django.middleware.locale.LocaleMiddleware',
      'modoboa.lib.middleware.AjaxLoginRedirect',
      'modoboa.lib.middleware.ExtControlMiddleware',
      'modoboa.extensions.webmail.middleware.WebmailErrorMiddleware',
    )
    
  2. Still inside settings.py, modify the DATABASE_ROUTERS variable like this:

    DATABASE_ROUTERS = ["modoboa.extensions.amavis_quarantine.dbrouter.AmavisRouter"]
    

0.8.7: per-user language selection

  1. Edit the settings.py file and add the 'django.middleware.locale.LocaleMiddleware' middleware to the MIDDLEWARE_CLASSES variable like this:

    MIDDLEWARE_CLASSES = (
      'django.middleware.common.CommonMiddleware',
      'django.contrib.sessions.middleware.SessionMiddleware',
      'django.contrib.auth.middleware.AuthenticationMiddleware',
      'django.contrib.messages.middleware.MessageMiddleware',
      'django.middleware.locale.LocaleMiddleware',
      'modoboa.lib.middleware.ExtControlMiddleware',
      'modoboa.extensions.webmail.middleware.WebmailErrorMiddleware',
    )
    
  2. To select a custom language, go to Options > Preferences and select the general section. Choose a value, save and disconnect from Modoboa. On the next login, the desired language will be used.

0.8.6.1: maintenance release

  1. If you have tried to create a new mailbox and if you have encountered the following issue, you must run the dbcleanup.py script in order to remove orphan records:

    $ cd <modoboa_dir>
    $ PYTHONPATH=$PWD/.. DJANGO_SETTINGS_MODULE=modoboa.settings ./admin/scripts/dbcleanup.py

0.8.6: Quarantine plugin refactoring (using Django’s ORM)

  1. Just update your configuration if you are using the quarantine plugin. Open settings.py, move the database configuration from the DB_CONNECTIONS variable to the DATABASES variable, like this:

    DATABASES = {
        "default" : {
            # The default database configuration
        },
        #    ...
        "amavis": {
            "ENGINE" : "<your value>",
            "HOST" : "<your value>",
            "NAME" : "<your value>",
            "USER" : "<your value>",
            "PASSWORD" : "<your value>"
        }
    }
    
  2. Add the new following variable somewhere in the file:

    DATABASE_ROUTERS = ["modoboa.extensions.amavis_quarantine.dbrouter.AmavisRouter"]
    
  3. Remove the deprecated DB_CONNECTIONS variable from settings.py.

0.8.5: new “Sieve filters” plugin, improved admin app

  1. Migrate the lib and admin applications:

    $ python manage.py migrate lib
    $ python manage.py migrate admin
  2. Add modoboa.auth and modoboa.extensions.sievefilters to the INSTALLED_APPS variable in settings.py.

  3. Go the Settings/Extensions panel, deactivate and activate your extensions, it will update all the symbolic links.

0.8.4: folders manipulation support (webmail) and bugfixes

  1. Update the MIDDLEWARE_CLASSES variable in settings.py:

    MIDDLEWARE_CLASSES = (
      'django.middleware.common.CommonMiddleware',
      'django.contrib.sessions.middleware.SessionMiddleware',
      'django.contrib.auth.middleware.AuthenticationMiddleware',
      'django.contrib.messages.middleware.MessageMiddleware',
      'modoboa.lib.middleware.ExtControlMiddleware',
      'modoboa.extensions.webmail.middleware.WebmailErrorMiddleware',
    )
    
  2. Go the Settings/Extensions panel, deactivate and activate your extensions, it will update all the symbolic links to the new format.

  3. Optional: update the DATABASES and TEMPLATE_LOADERS variables in settings.py to remove warning messages (appearing with Django 1.3):

    DATABASES = {
      "default" : {
        "ENGINE" : "<your engine>",
        "NAME" : "modoboa",
        "USER" : "<your user>",
        "PASSWORD" : "<your password>",
        "HOST" : "",
        "PORT" : ""
      }
    }
    
    TEMPLATE_LOADERS = (
      'django.template.loaders.filesystem.Loader',
      'django.template.loaders.app_directories.Loader',
    )
    

0.8.3: admin application refactoring and more

  1. Migrate the admin application:

    $ python manage.py migrate admin
  2. Update SQL queries used in your environnement (see Postfix or Dovecot).

  3. Update postfix configuration so that it can handle domain aliases (see Postfix).

0.8.2: ckeditor integration and more

  1. Migrate the admin applicaton:

    $ python manage.py migrate admin
  2. Update your config file and add all extensions to INSTALLED_APPS (even those you are not going to use).

  3. Inside the <modoboa_dir>/templates/ directory, remove all symbolic links.

  4. Download the latest release of ckeditor and extract it into <modoboa_dir>/static/js/. It should create a new directory named ckeditor.

  5. Update the following variables inside settings.py:

    MEDIA_ROOT = os.path.join(MODOBOA_DIR, 'static')
    MEDIA_URL = '/static/'
    
  6. Then, add the following variable: MODOBOA_WEBPATH = 'modoboa/'

  7. Delete the following variables: STATIC_ROOTDIR and TEMPLATE_CONTEXT_PROCESSORS.

  8. Finally, add modoboa.lib.middleware.ExtControlMiddleware to MIDDLEWARE_CLASSES.

0.8.1 : project renamed

  1. First, rename the mailng directory to modoboa and copy all the content from modoboa-0.8.1 to modoboa.

  2. Edit settings.py and replace all occurences of mailng by modoboa. Make sure you don’t modify the DATABASE section as you’re not going to rename your database.

  3. Rename the MAILNG_DIR variable to MODOBOA_DIR.

  4. Add 'django.contrib.messages.middleware.MessageMiddleware' to MIDDLEWARE_CLASSES and 'django.contrib.messages' to INSTALLED_APPS. Save your modifications.

  5. Run the following command:

    $ python manage.py syncdb
  6. For all activated extensions, run the following command:

    $ export PYTHONPATH=<modoboa_dir>/..=
    $ DJANGO_SETTINGS_MODULE=modoboa.settings <modoboa_dir>/scripts/extension.py <extension> on
  7. Update your webserver configuration and restart it.

0.8 : SQL migration needed

Before you start the migration, make sure you have updated your INSTALLED_APPS variable and that it contains at least:

INSTALLED_APPS = (
   # Django's stuff before

   'south',
   'mailng',
   'mailng.lib',
   'mailng.admin',
   'mailng.userprefs',
)

Starting with 0.8, mailng.main doesn’t exist anymore. You must remove it from your INSTALLED_APPS.

Finally, run the following commands:

$ python manage.py syncdb
$ python manage.py convert_to_south
$ python manage.py migrate --all 0001 --fake
$ python manage.py migrate --all 0002

0.7 : Nothing to do

0.6 : Nothing to do

Integrating Modoboa with other softwares

Postfix

For MySQL users, define the following map files on your server (it should work with postfix versions >= 2.2):

/etc/postfix/sql-domains.cf:

user = <user>
password = <password>
dbname = <database>
hosts = 127.0.0.1
query = SELECT name FROM admin_domain WHERE name='%s' AND enabled=1

/etc/postfix/sql-domain-aliases.cf:

user = <user>
password = <password>
dbname = <database>
hosts = 127.0.0.1
query = SELECT t2.name FROM admin_domainalias AS t1, admin_domain AS t2 WHERE t1.target_id=t2.id AND t1.enabled=1 AND t2.enabled=1 AND t1.name='%s'

/etc/postfix/sql-mailboxes.cf:

user = <user>
password = <password>
dbname = <database>
hosts = 127.0.0.1
query = SELECT concat(t2.name, '/', t1.path, (SELECT value FROM lib_parameter WHERE name='admin.MAILDIR_ROOT', '/') FROM admin_mailbox AS t1, admin_domain AS t2 WHERE t1.enabled=1 AND t1.domain_id=t2.id AND t1.address='%u' AND t2.enabled=1 AND t2.name='%d'

/etc/postfix/sql-aliases.cf:

user = <user>
password = <password>
dbname = <database>
hosts = 127.0.0.1
query = (SELECT concat(t1.address, '@', t2.name) FROM admin_mailbox t1, admin_domain t2 WHERE t1.id IN (SELECT t3.mailbox_id FROM admin_alias t1, admin_domain t2, admin_alias_mboxes t3 WHERE t1.enabled='1' AND t1.address='%u' AND t1.domain_id=t2.id AND t2.name='%d' AND t3.alias_id=t1.id) AND t1.domain_id=t2.id) UNION (SELECT t1.extmboxes FROM admin_alias AS t1, admin_domain AS t2 WHERE t1.enabled='1' AND t1.extmboxes<>'' AND t1.address='%u' AND t1.domain_id=t2.id AND t2.name="%d" AND t2.enabled='1')

/etc/postfix/sql-forwards.cf:

user = <user>
password = <password>
dbname = <database>
hosts = 127.0.0.1
query = SELECT t1.extmboxes FROM admin_alias AS t1, admin_domain AS t2 WHERE t1.enabled=1 AND t1.address='%u' AND t1.domain_id=t2.id AND t2.name="%d" AND t2.enabled=1

/etc/postfix/sql-domain-aliases-mailboxes.cf:

user = <user>
password = <password>
dbname = <database>
hosts = 127.0.0.1
query = SELECT concat(t2.address, '@', t3.name) FROM admin_domainalias AS t1, admin_mailbox AS t2, admin_domain AS t3 WHERE t1.target_id=t2.domain_id AND t2.domain_id=t3.id AND t1.name='%d' AND t2.address='%u'

Then, use the following configuration in the /etc/postfix/main.cf file (this is just one possible configuration):

# Stuff before
mailbox_transport = virtual
maildrop_destination_recipient_limit = 1
virtual_minimum_uid = <vmail user id>
virtual_gid_maps = static:<vmail group id>
virtual_uid_maps = static:<vmail user id>
virtual_mailbox_base = /var/vmail

relay_domains =
virtual_mailbox_domains = mysql:/etc/postfix/sql-domains.cf
virtual_alias_domains = mysql:/etc/postfix/sql-domain-aliases.cf
virtual_mailbox_maps = mysql:/etc/postfix/sql-mailboxes.cf
virtual_alias_maps = mysql:/etc/postfix/sql-aliases.cf,
      mysql:/etc/postfix/sql-domain-aliases-mailboxes.cf
# Stuff after

Note

Modoboa supports both maildir and mbox formats. You can specify which format to use by modifying the MAILBOX_TYPE parameter available in the admin panel.

Optional : ‘catchall’ aliases

Modoboa supports ‘catchall’ aliases creation. In the case you would like to use this feature, you’ll need to add specific queries to postfix configuration.

First, create the following new maps (MySQL users):

/etc/postfix/sql-email2email.cf:

user = <user>
password = <password>
dbname = <database>
hosts = 127.0.0.1
query = SELECT concat(t1.address, '@', t2.name) FROM admin_mailbox AS t1, admin_domain AS t2 WHERE t1.domain_id=t2.id AND t1.address='%u' AND t2.name='%d'

/etc/postfix/sql-catchall-aliases.cf:

user = <user>
password = <password>
dbname = <database>
hosts = 127.0.0.1
query = (SELECT concat(t1.address, '@', t2.name) FROM admin_mailbox t1, admin_domain t2 WHERE t1.id IN (SELECT t3.mailbox_id FROM admin_alias t1, admin_domain t2, admin_alias_mboxes t3 WHERE t1.enabled='1' AND t1.address='*' AND t1.domain_id=t2.id AND t2.name='%d' AND t3.alias_id=t1.id) AND t1.domain_id=t2.id) UNION (SELECT t1.extmboxes FROM admin_alias AS t1, admin_domain AS t2 WHERE t1.enabled='1' AND t1.extmboxes<>'' AND t1.address='*' AND t1.domain_id=t2.id AND t2.name="%d" AND t2.enabled='1')

Once done, edit the main.cf configuration file and add the new maps to the virtual_alias_maps parameter like this:

virtual_alias_maps = mysql:/etc/postfix/sql-aliases.cf,
     mysql:/etc/postfix/sql-forwards.cf,
     mysql:/etc/postfix/sql-domain-aliases-mailboxes.cf,
     mysql:/etc/postfix/sql-email2email.cf,                  # new
     mysql:/etc/postfix/sql-catchall-aliases.cf              # new

Reload postfix.

Optional: using Dovecot’s LDA

If you are using Dovecot in your environnement, I recommend to use its LDA. Doing so, you’ll will be able to use extra functionalities such as sieve filters and more.

First, edit the /etc/postfix/main.cf file and define (or modify if they already exist) the following parameters:

virtual_transport = dovecot
dovecot_destination_recipient_limit = 1

Then, edit the /etc/postfix/master.cf file and add the following definition at the end:

dovecot   unix  -       n       n       -       -       pipe
  flags=DRhu user=vmail:vmail argv=/usr/lib/dovecot/deliver -f ${sender} -d ${recipient}

If you have followed the Postfix section to install your environnement, you need to modify the SQL query corresponding to the virtual_mailbox_maps parameter. Edit the /etc/postfix/maps/sql-mailboxes.cf and modify the query parameter as follow:

query = SELECT concat(t2.name, '/', t1.path) FROM admin_mailbox AS t1, admin_domain AS t2 WHERE t1.enabled=1 AND t1.domain_id=t2.id AND t1.address='%u' AND t2.enabled=1 AND t2.name='%d'

Restart Postfix.

Dovecot

If you are using the maildir format to store mailboxes, add the following line into Dovecot’s main config file (/etc/dovecot/dovecot.conf):

mail_location = maildir:<path_to_mailboxes>/%h/.maildir

The .maildir part is the previous example must match the value of the MAILDIR_ROOT parameter. See Default configuration.

If you are using the mbox format, add the following:

mail_location = mbox:<path_to_mailboxes>/%h/:INBOX=<path_to_mailboxes>/%h/Inbox

To make the authentication work, edit dovecot.conf and add the following content inside:

auth default {
  # ... stuff before

  passdb sql {
    # Path for SQL configuration file, see /etc/dovecot/dovecot-sql.conf for
    #  example
    args = /etc/dovecot/dovecot-sql.conf
  }

  userdb sql {
    # Path for SQL configuration file
    args = /etc/dovecot/dovecot-sql.conf
  }

  # ... stuff after
}

Make sure to activate only one backend (per type) inside your configuration (just comment the other ones).

For MySQL users, edit your /etc/dovecot/dovecot-sql.conf and modify following lines:

driver = mysql
connect = host=<mysqld socket> dbname=<database> user=<user> password=<password>
default_pass_scheme = CRYPT
password_query = SELECT concat(t1.address, '@', t2.name) AS user, password FROM admin_mailbox AS t1, admin_domain AS t2 WHERE t1.domain_id=t2.id AND t1.address='%n' AND t2.name='%d'
user_query = SELECT concat(t2.name, '/', t1.path) AS home, uid, gid FROM admin_mailbox AS t1, admin_domain AS t2 WHERE t1.domain_id=t2.id AND t1.address='%n' AND t2.name='%d'

Enable quotas support

Put the following lines inside the dovecot.conf file:

protocol imap {
  mail_plugins = quota imap_quota
}

Before continuing, you need to know which quota backend must be used (function of mailboxes format):

  • mbox : backend=dirsize,
  • maildir : backend=maildir.

If you use version prior to 1.1, add also the following configuration:

plugin {
  # 10 MB default quota limit
  quota = <backend>:storage=10240
}

For MySQL users, modify the above query inside dovecot-sql.conf as follow to activate per-user quotas:

user_query = SELECT concat(t2.name, '/', t1.path) AS home, uid, gid, concat('<backend>:storage=', t1.quota / 1024) AS quota FROM admin_mailbox AS t1, admin_domain AS t2 WHERE t1.domain_id=t2.id AND t1.address='%n' AND t2.name='%d'

For version >= 1.1, put the following configuration inside the dovecot.conf file:

plugin {
  # Default 10M storage limit with an extra 5M limit when saving to Trash.
  quota = <backend>:User quota
  quota_rule = *:storage=10M
  quota_rule2 = Trash:storage=5M
}

For MySQL users, modify the above query inside dovecot-sql.conf to activate per-user quotas:

user_query = SELECT concat(t2.name, '/', t1.path) AS home, uid, gid, concat('*:storage=', t1.quota, 'M') AS quota_rule FROM admin_mailbox AS t1, admin_domain AS t2 WHERE t1.domain_id=t2.id AND t1.address='%n' AND t2.name='%d'

Enable ManageSieve/Sieve support

Note

The following configuration example should work with versions 1.X. For versions >= 2, please refer to Dovecot’s wiki.

Edit the /etc/dovecot/dovecot.conf file and make the following modifications:

  • Add managesieve to the protocols variable:

    protocols = imap imaps managesieve
  • Uncomment the managesieve section:

    protocol managesieve {
      # ...
    }
  • Configure the lda protocol as follow:

    protocol lda {
      postmaster_address = postmaster@<your domain>
      mail_plugins = sieve # + your other plugins
      # ...
    }
  • In the plugin section, uncomment the following content:

    plugin {
      # stuff before
    
      # Location of the active script. When ManageSieve is used this is actually
      # a symlink pointing to the active script in the sieve storage directory.
      sieve=~/.dovecot.sieve
    
      #
      # The path to the directory where the personal Sieve scripts are stored. For
      # ManageSieve this is where the uploaded scripts are stored.
      sieve_dir=~/sieve
    }

Restart Dovecot.

Note

If you’re using Postfix as MTA, you will have to use Dovecot‘s local delivery agent otherwise your emails won’t get filtered. See Optional: using Dovecot’s LDA to get information on how to activate this.

Migrating from other softwares

PostfixAdmin

Since version 0.8.5, Modoboa provides a simple script to migrate an existing PostfixAdmin (version 2.3.3+) database to a Modoboa one.

Note

This script is only suitable for a new installation.

First, you must follow the How to install step to create a fresh Modoboa database.

Once done, edit the setting.py file. First, add a new database connection named pfxadmin into the DATABASES variable corresponding to your PostfixAdmin setup:

DATABASES = {
  "default" : {
    # default connection definition
  },
  "pfxadmin" : {
    "ENGINE" : "<engine>",
    "NAME" : "<database name>",
    "USER" : "<database user>",
    "PASSWORD" : "<user password>",
  }
}

This connection should correspond to the one defined in PostfixAdmin’s configuration file.

You are now ready to start the migration. Enter Modoboa’s root directory and execute the following command:

$ PYTHONPATH=$PWD/.. DJANGO_SETTINGS_MODULE=modoboa.settings \
    ./tools/pfxadmin_migrate/migrate.py -r -p <directory that stores mailboxes>

Depending on how many domains/mailboxes your existing setup contains, the migration can be long. Just wait for the script’s ending.

Once the migration has succeed, go the Admin > Configuration panel, click on the admin row and modify the value of MAILDIR_ROOT as follow:

MAILDIR_ROOT =

The corresponding field must be empty. Don’t touch other fields except PASSWORD_SCHEME, if needed. (set it to the same method as the one used by PostfixAdmin, check its configuration file if you’re not sure)

Click on the Save button.

The procedure is over, edit the settings.py file and:

  • remove the pfxadmin database connection from the DATABASES variable
  • remove the 'modoboa.tools.pfxadmin_migrate', from the INSTALLED_APPS variable

You should be able to connect to Modoboa using the same credentials you were using to connect to PostfixAdmin.

How to serve Modoboa behind a webserver

Apache 2

First, make sure that both apache2 and mod_python are installed on your server.

Create a new virtualhost in your Apache configuration and put the following inside:

<VirtualHost *:80>
  <Location "/">
    SetHandler mod_python
    PythonHandler django.core.handlers.modpython
    PythonPath "['<path to directory that contains modoboa dir>'] + sys.path"
    SetEnv DJANGO_SETTINGS_MODULE modoboa.settings
  </Location>
  Alias "/static" "<path to modoboa dir>/static"
  <Location "/static/">
    SetHandler None
  </Location>
</VirtualHost>

This is one possible configuration. Note that you will certainly need more configuration in order to launch Apache.

Nginx

Nginx is a really fast HTTP server. Associated with Green Unicorn, it gives you one of the best setup to serve python/Django applications. Modoboa’s performances are really good with this configuration.

To use this setup, first download and install those softwares (Install gunicorn and install nginx).

Then, use the following sample gunicorn configuration (create a new file named gunicorn.conf.py inside Modoboa’s root dir):

backlog = 2048
bind = "unix:/var/run/gunicorn/modoboa.sock"
pidfile = "/var/run/gunicorn/modoboa.pid"
daemon = True
debug = False
workers = 2
logfile = "/var/log/gunicorn/modoboa.log"
loglevel = "info"

To start gunicorn, execute the following commands:

$ cd <modoboa dir>
$ gunicorn_django -c gunicorn.conf.py

Now the nginx part. Just create a new virtual host and use the following configuration:

upstream modoboa {
      server      unix:/var/run/gunicorn/modoboa.sock fail_timeout=0;
}

server {
      listen 443;
      server_name <host fqdn>;
      root <modoboa's root dir>;

      access_log  /var/log/nginx/<host fqdn>.access.log;
      error_log /var/log/nginx/<host fqdn>.error.log;

      location /static/ {
              autoindex on;
      }

      location / {
              proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
              proxy_set_header Host $http_host;
              proxy_redirect off;
              proxy_set_header X-Forwarded-Protocol ssl;

              if (!-f $request_filename) {
                      proxy_pass http://modoboa;
                      break;
              }
      }
}

Paste this content to your configuration (replace values between <> with yours), restart nginx and enjoy a really fast application!

Using default plugins

Enable or disable a plugin

Starting with 0.8.2, Modoboa provides an online panel to control plugins activation:

  • To activate a plugin, go to the admin -> settings -> extensions page, check the corresponding box and click on the Apply button.
  • To deactivate a plugin, go to the admin -> settings -> extensions page, uncheck the corresponding box and click on the Apply button.

Amavisd-new quarantine

This plugin allows you and your users to handle amavisd-new SQL quarantine. You can consult messages and/or release or delete them.

First, you need to specify where the database that contains the quarantine is. Inside settings.py, add a new connection to the DATABASES variable like this:

DATABASES = {
  # Stuff before
  #
  "amavis": {
    "ENGINE" : "<your value>",
    "HOST" : "<your value>",
    "NAME" : "<your value>",
    "USER" : "<your value>",
    "PASSWORD" : "<your value>"
  }
}

Replace values between <> with yours.

When viewing messages, you can choose to display links (addresses, images). In order to display images correctly, you need to create a tmp directory under static/ for storing them. For example:

$ mkdir <modoboa_dir>/static/tmp

To be able to release messages, first take a look at this page. It explains how to configure amavisd-new to listen somewhere for the AM.PDP protocol. This protocol is used to send release requests.

Below is an example of a working configuration:

$interface_policy{'SOCK'} = 'AM.PDP-SOCK';
$interface_policy{'9998'} = 'AM.PDP-INET';

$policy_bank{'AM.PDP-SOCK'} = {
  protocol => 'AM.PDP',
  auth_required_release => 0,
};
$policy_bank{'AM.PDP-INET'} = {
  protocol => 'AM.PDP',
  inet_acl => [qw( 127.0.0.1 [::1] )],
};

Don’t forget to update the inet_acl list if you plan to release from the network.

Once amavisd-new is configured, just tell Modoboa where it can find the “release server” by modifying the following parameters in the admin panel:

# "unix" or "inet"
AM_PDP_MODE = "inet"

# "unix" mode only
AM_PDP_SOCKET = "/var/amavis/amavisd.sock"

# "inet" mode only
AM_PDP_HOST = "127.0.0.1"
AM_PDP_PORT = 9998

Last point, Modoboa provides a simple script that periodically purges the quarantine database. If you want to use it, you can add the following line inside root’s crontab:

0 0 * * * PYTHONPATH=<modoboa_dir/..> \
  DJANGO_SETTINGS_MODULE=modoboa.settings \
  <modoboa_dir>/extensions/amavis_quarantine/cleanup.py

Replace modoboa_dir with the installation path of Modoboa.

By default, messages older than 14 days are automatically purged. You can modify this value by changing the MAX_MESSAGES_AGE parameter in the admin panel.

Graphical statistics

This plugin allows you to collect various statistics about emails traffic on your server. It parses log file to collect information and then generates graphics using the PNG format.

First, adapt the following parameters to your environnement:

# Path to mail log file
LOGFILE = "/var/log/mail.log"

# Path to directory where rrd files are stored
RRD_ROOTDIR = "/tmp/modoboa"

# Path to directory where png files are stored
IMG_ROOTDIR = "<modoboa_dir>/static/graphs"

Make sure the directories that will contain those files exist. If not, create them before going further. For example (according to the previous parameters):

$ mkdir /tmp/modoboa
$ mkdir <modoboa_dir>/static/graphs

To finish, you need to collect information periodically in order to feed the rrd files. To do so, just add the following line into root’s crontab:

*/5 * * * * PYTHONPATH=<modoboa_dir/..> DJANGO_SETTINGS_MODULE=modoboa.settings <modoboa_dir>/scripts/stats/logparser.py

Replace modoboa_dir with the installation path of Modoboa.

Graphics will be automatically created after each parsing.

Postifx auto-reply messages

Since version 0.6, mail users can define an auto-reply message with Modoboa.

Then run the following commands to update Modoboa SQL schema and content:

$ python manage.py syncdb
$ python manage.py migrate postfix-autoreply
$ export PYTHONPATH=$PWD/..
$ DJANGO_SETTINGS_MODULE=modoboa.settings ./scripts/postfix_autoreply/upgrade_autoreply.py

The user that executes the autoreply script needs to access settings.py. You must apply proper permissions on this file. For example, if settings.py belongs to www-data:www-data, you can add the vmail user to the www-data group and set the read permission for the group.

To make Postfix understand this feature, you need to update your configuration files as follow:

/etc/postfix/main.cf:

transport_maps = mysql:/etc/postfix/maps/sql-transport.cf
virtual_alias_maps = mysql:/etc/postfix/maps/sql-aliases.cf
        mysql:/etc/postfix/maps/sql-autoreplies.cf

/etc/postfix/master.cf:

autoreply unix        -       n       n       -       -       pipe
          flags= user=vmail:<group> argv=<path_to_modoboa>/scripts/postfix_autoreply/autoreply $sender $mailbox

For MySQL users, create new map files with the following content:

/etc/postfix/maps/sql-transport.cf:

user = <user>
password = <password>
dbname = <database>
hosts = 127.0.0.1
query = SELECT method FROM postfix_autoreply_transport WHERE domain='%s'

/etc/postfix/maps/sql-autoreplies.cf:

user = <user>
password = <password>
dbname = <database>
hosts = 127.0.0.1
query = SELECT full_address, autoreply_address FROM postfix_autoreply_alias WHERE full_address='%s'

Finally, edit the autoreply shell script located inside the scripts directory and change the value of BASEDIR. (just put absolute path of the directory where Modoboa is installed)

Note

Auto-reply messages are just sent one time per sender for a pre-defined time period. By default, this period is equal to 1 day (86400s), you can adjust this value by modifying the AUTOREPLY_TIMEOUT parameter available in the admin panel.

Note

Make sure that both autoreply and autoreply.py scripts (located inside the scripts/postfix_autoreply directory) have good permissions (ie. 0755).

Sieve filters

Since version 0.8.5, Modoboa provides a plugin to easily create server-side message filters, using the sievelib module (which provides Sieve and ManageSieve clients).

Two working modes are available to users:

  • A raw mode: you create filters using the Sieve language directly (advanced users)
  • An assisted mode: you create filters using an intuitive form

To be able to use this plugin, your server setup must include a ManageSieve server and your IMAP server must support the Sieve language. Don’t panic, Dovecot supports both :-)

Refer to Dovecot section if you want to active those features into Dovecot.

Note

The sieve filters plugin requires that the webmail plugin is activated and configured.

Go the admin panel and modify plugin’s parameters in order to communicate with the ManageSieve server (default values are displayed below):

SERVER = localhost
PORT = 2000
STARTTLS = no
AUTHENTICATION_MECH = plain

Webmail

Modoboa provides a simple webmail component (you can browse, read and compose messages). With this feature, it is possible to deploy an almost standalone emails platform just with Modoboa.

Sometimes, inline images are integrated inside emails. To display them, Modoboa stores images into a temporary directory. Make sure the following path exists. If not, create it:

$ mkdir <path_to_modoboa>/static/tmp

The user that is running Modoboa will need the write permission inside this directory.

Next, go to the admin panel and modify the following parameters in order to communicate with your IMAP and SMTP servers:

IMAP_SECURED = no
IMAP_SERVER = 127.0.0.1
IMAP_PORT = 143

SMTP_SECURED = no
SMTP_AUTHENTICATION = no
SMTP_SERVER = 127.0.0.1
SMTP_PORT = 25

Since version 0.8.7, the webmail supports the sending of attachments with messages. You can limit the size of each attachment by going to the Admin > Settings > Parameters page. Click on the webmail section and modify the value of the MAX_ATTACHMENT_SIZE parameter.