New version based on Debian 7.2 and with the latest Modoboa… watch this space. If you wan’t to help out testing the new guide, leave a comment below.
First off, this guide like 90% complete. If you follow it, please report back if something is wrong etc.
When I first started writing, I ran through the steps a couple of times installing everything from scratch, but after a while, I got tired of re installing just to try stuff out, so some things may gone wrong along the way.
These are mostly my own notes setting up modoboa. When completed, you’ll have postfix, dovecot and modoboa running with nginx.
I won’t go into detail how to configure the various modoboa extensions, this is covered in modoboas documentation.
I’m using a minimal install of Debian Squeeze for this. So, some packages may already be installed if you don’t us the same dist. The steps described here also should work on Ubuntu, but I haven’t verified that.
Replace <fqdn> with your fully qualified domain name. For example: mail.domain.com. <domain> with your domain. For example: example.com.
This guide assumes you’ll run mailserver, mysql and modoboa on the same host. If you plan to grow, it might be a good idea to separate these.
Content
- Install packages
- amavisd-new setup
- Configure clamav
- Make /tmp a bit more secure
- Make /tmp a bit more secure
- Create users
- Install modoboa with pip
- Create databases and user
- Create amavis tables
- Configure postfix
- configure nginx
- Change MAILDIR_ROOT
- Create a SECRET_KEY
- Change NOTIFICATIONS_SENDER
- Configure dovecot
- Troubleshooting
- Deploy modoboa
Install packages
I’d start with installing netselect-apt to find your fastest mirror. This is optional (works only in Debian).
apt-get install netselect-apt cd /etc/apt/ netselect-apt apt-get update
then we’ll install the needed packages. We won’t use the Debian packaged version of amavisd-new but the latest from source. That’s why we install all the perl modules and archive packages
apt-get install sudo gcc libxslt-dev python-pip postfix-mysql nginx \ python-dev python-rrdtool python-mysqldb mysql-server dovecot-imapd \ dovecot-pop3d pwgen spamassassin vim ca-certificates dkim-filter \ libarchive-zip-perl libconvert-tnef-perl libconvert-uulib-perl \ libmime-tools-perl libcrypt-openssl-rsa-perl libnet-cidr-perl \ libevent-1.4-2 libnet-server-perl pax libnfsidmap2 libmail-dkim-perl \ libberkeleydb-perl librpcsecgss3 libio-multiplex-perl libgssglue1 portmap \ libunix-syslog-perl libcrypt-openssl-bignum-perl ncompress nomarch \ arc arj zoo tnef cabextract clamav clamav-daemon bzip2 unrar-free xdms \ p7zip p7zip-full unzip orange ripole lzop rpm2cpio lrzip
If you’re using Ubuntu, replace package dkim-filter with opendkim. I won’t go into detail how to enable dkim in this guide anyway.
amavisd-new setup
These instructions pretty much come from the INSTALL file from amavisd-new.
Create user group amavis:amavis and set to home dir /var/amavis
useradd amavis -d /var/amavis mkdir -p /var/amavis/tmp /var/amavis/var /var/amavis/db /var/amavis/home chown -R amavis:amavis /var/amavis chmod -R 750 /var/amavis
Download and unpack amavisd-new.
cd /usr/local/src wget http://www.amavis.org/amavisd-new-2.8.0.tar.gz -O - | tar zxf - cd amavisd-new-2.8.0
install amavis
cp amavisd /usr/local/sbin/ chown root /usr/local/sbin/amavisd chmod 755 /usr/local/sbin/amavisd
copy configfile
cp amavisd.conf /etc/ chown root:amavis /etc/amavisd.conf chmod 640 /etc/amavisd.conf
create a directory to be used by amavisd-new as a quarantine area
mkdir /var/virusmails chown amavis:amavis /var/virusmails chmod 750 /var/virusmails
edit /etc/amavisd.conf and change, enable or uncomment, the following settings:
$daemon_user = 'amavis'; $daemon_group = 'amavis'; $mydomain = 'example.com'; $MYHOME = '/var/amavis'; $TEMPBASE = "$MYHOME/tmp"; $db_home = "$MYHOME/db"; $helpers_home = "$MYHOME/home"; $pid_file = "/var/run/amavis/amavisd.pid"; $lock_file = "/var/run/amavis/amavisd.lock"; $unix_socketname = "/var/run/amavis/amavisd.sock"; $myhostname = '<fdqn>';
since we’re doing the ”uncluttered” setup, for some extra security, also change ownerships:
chown root /var/amavis chown -R amavis:amavis /var/amavis/home chmod 750 /var/amavis /var/amavis/home
Create init script for amavisd
Create a new file, /etc/init.d/amavisd, containing:
#!/bin/sh # /etc/init.d/amavisd ### BEGIN INIT INFO # Provides: amavis # Required-Start: $local_fs $remote_fs $network $syslog $time # Required-Stop: $local_fs $remote_fs $network $syslog # Default-Start: 2 3 4 5 # Default-Stop: 0 1 6 # Short-Description: Start amavis at boot time # Description: Enable amavis service ### END INIT INFO PATH=/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin PIDFILE=/var/run/amavis/amavisd.pid SOCKET=/var/run/amavis/amavisd.sock case "$1" in start) if [ -f "$PIDFILE" ]; then echo "Already running" else echo "Starting amavisd" /usr/local/sbin/amavisd -u amavis fi ;; stop) if [ -f "$PIDFILE" ]; then echo "Stopping amavisd" kill `cat $PIDFILE` else echo "Not running" fi ;; restart) echo "Restarting amavisd" $0 stop sleep 1 $0 start ;; reload) echo "Reloading amavisd" kill -HUP `cat /var/amavis/amavisd.pid` ;; *) echo "Usage: /etc/init.d/amavisd {start|stop}" exit 1 ;; esac exit 0
also create the directory /var/run/amavis.
mkdir /var/run/amavis chown amavis:amavis /var/run/amavis chmod 700 /var/run/amavis
and finally set executable bit and enable the service:
chmod +x /etc/init.d/amavisd update-rc.d amavisd defaults
and start the service:
service amavisd start
Configure clamav
Add the clamav user to the amavis group
make sure the following lines are enabled in /etc/amavisd.conf (note the change from .sock to .ctl).
['ClamAV-clamd', \&ask_daemon, ["CONTSCAN {}\n", "/var/run/clamav/clamd.ctl"], qr/\bOK$/m, qr/\bFOUND$/m, qr/^.*?: (?!Infected Archive)(.*) FOUND$/m ],
and make sure
AllowSupplementaryGroups true
is set in /etc/clamav/clamd.conf. This is the default setting (at least in Debian squeeze).
gpasswd -a clamav
and finally start clamd-daemon
service clamav-daemon start
Make /tmp a bit more secure
Add the following line to /etc/fstab. As per recommendation in amavisd-new install instructions.
tmpfs /tmp tmpfs noexec,nosuid,nodev 0 0
After that, create a new file /etc/apt/apt.conf.d/50extracttemplates. Apt uses /tmp per default running installation scripts and if we add noexec to /tmp, this will make sure this doesn’t happen.
APT { ExtractTemplates { TempDir "/var/tmp"; }; };
Create users
groupadd -g 5000 vmail useradd -g vmail -u 5000 vmail -d /var/vmail -m chown -R vmail:vmail /var/vmail chmod u+w /var/vmail
Install modoboa with pip
pip install modoboa
This will download, compile and install modoboa and what’s needed to run the whole shebang.
Create databases and user
mysql -u root -p
create database modoboa; create database amavis; grant all privileges on modoboa.* to 'modoboa'@'localhost' identified by 'somepassword'; grant all privileges on amavis.* to 'amavis'@'localhost' identified by 'someotherpassword'; flush privileges;
Create amavis tables
I’ve removed (some) comments to save pixels. Please refer to the amavis documentation for the whole thing. It’s pure SQL so you can cut and paste. If you get errors. Take one query at the time.
use amavis; CREATE TABLE users ( id int unsigned NOT NULL AUTO_INCREMENT PRIMARY KEY, -- unique id priority integer NOT NULL DEFAULT '7', -- sort field, 0 is low prior. policy_id integer unsigned NOT NULL DEFAULT '1', -- JOINs with policy.id email varbinary(255) NOT NULL UNIQUE, fullname varchar(255) DEFAULT NULL -- not used by amavisd-new -- local char(1) -- Y/N (optional field, see note further down) ); CREATE TABLE mailaddr ( id int unsigned NOT NULL AUTO_INCREMENT PRIMARY KEY, priority integer NOT NULL DEFAULT '7', -- 0 is low priority email varbinary(255) NOT NULL UNIQUE ); CREATE TABLE wblist ( rid integer unsigned NOT NULL, -- recipient: users.id sid integer unsigned NOT NULL, -- sender: mailaddr.id wb varchar(10) NOT NULL, -- W or Y / B or N / space=neutral / score PRIMARY KEY (rid,sid) ); CREATE TABLE policy ( id int unsigned NOT NULL AUTO_INCREMENT PRIMARY KEY, -- 'id' this is the _only_ required field policy_name varchar(32), -- not used by amavisd-new, a comment virus_lover char(1) default NULL, -- Y/N spam_lover char(1) default NULL, -- Y/N unchecked_lover char(1) default NULL, -- Y/N banned_files_lover char(1) default NULL, -- Y/N bad_header_lover char(1) default NULL, -- Y/N bypass_virus_checks char(1) default NULL, -- Y/N bypass_spam_checks char(1) default NULL, -- Y/N bypass_banned_checks char(1) default NULL, -- Y/N bypass_header_checks char(1) default NULL, -- Y/N spam_modifies_subj char(1) default NULL, -- Y/N virus_quarantine_to varchar(64) default NULL, spam_quarantine_to varchar(64) default NULL, banned_quarantine_to varchar(64) default NULL, unchecked_quarantine_to varchar(64) default NULL, bad_header_quarantine_to varchar(64) default NULL, clean_quarantine_to varchar(64) default NULL, archive_quarantine_to varchar(64) default NULL, spam_tag_level float default NULL, -- higher score inserts spam info headers spam_tag2_level float default NULL, -- inserts 'declared spam' header fields spam_tag3_level float default NULL, -- inserts 'blatant spam' header fields spam_kill_level float default NULL, -- higher score triggers evasive actions -- e.g. reject/drop, quarantine, ... -- (subject to final_spam_destiny setting) spam_dsn_cutoff_level float default NULL, spam_quarantine_cutoff_level float default NULL, addr_extension_virus varchar(64) default NULL, addr_extension_spam varchar(64) default NULL, addr_extension_banned varchar(64) default NULL, addr_extension_bad_header varchar(64) default NULL, warnvirusrecip char(1) default NULL, -- Y/N warnbannedrecip char(1) default NULL, -- Y/N warnbadhrecip char(1) default NULL, -- Y/N newvirus_admin varchar(64) default NULL, virus_admin varchar(64) default NULL, banned_admin varchar(64) default NULL, bad_header_admin varchar(64) default NULL, spam_admin varchar(64) default NULL, spam_subject_tag varchar(64) default NULL, spam_subject_tag2 varchar(64) default NULL, spam_subject_tag3 varchar(64) default NULL, message_size_limit integer default NULL, -- max size in bytes, 0 disable banned_rulenames varchar(64) default NULL, -- comma-separated list of ... -- names mapped through %banned_rules to actual banned_filename tables disclaimer_options varchar(64) default NULL, forward_method varchar(64) default NULL, sa_userconf varchar(64) default NULL, sa_username varchar(64) default NULL ); CREATE TABLE maddr ( partition_tag integer DEFAULT 0, -- see $partition_tag id bigint unsigned NOT NULL AUTO_INCREMENT PRIMARY KEY, email varbinary(255) NOT NULL, -- full mail address domain varchar(255) NOT NULL, -- only domain part of the email address -- with subdomain fields in reverse CONSTRAINT part_email UNIQUE (partition_tag,email) ) ENGINE=InnoDB; CREATE TABLE msgs ( partition_tag integer DEFAULT 0, -- see $partition_tag mail_id varbinary(16) NOT NULL, -- long-term unique mail id, dflt 12 ch secret_id varbinary(16) DEFAULT '', -- authorizes release of mail_id, 12 ch am_id varchar(20) NOT NULL, -- id used in the log time_num integer unsigned NOT NULL, -- rx_time: seconds since Unix epoch time_iso char(16) NOT NULL, -- rx_time: ISO8601 UTC ascii time sid bigint unsigned NOT NULL, -- sender: maddr.id policy varchar(255) DEFAULT '', -- policy bank path (like macro %p) client_addr varchar(255) DEFAULT '', -- SMTP client IP address (IPv4 or v6) size integer unsigned NOT NULL, -- message size in bytes originating char(1) DEFAULT ' ' NOT NULL, -- sender from inside or auth'd content char(1), -- content type: V/B/U/S/Y/M/H/O/T/C -- virus/banned/unchecked/spam(kill)/spammy(tag2)/ -- /bad-mime/bad-header/oversized/mta-err/clean -- is NULL on partially processed mail -- (prior to 2.7.0 the CC_SPAMMY was logged as 's', now 'Y' is used; -- to avoid a need for case-insenstivity in queries) quar_type char(1), -- quarantined as: ' '/F/Z/B/Q/M/L -- none/file/zipfile/bsmtp/sql/ -- /mailbox(smtp)/mailbox(lmtp) quar_loc varbinary(255) DEFAULT '', -- quarantine location (e.g. file) dsn_sent char(1), -- was DSN sent? Y/N/q (q=quenched) spam_level float, -- SA spam level (no boosts) message_id varchar(255) DEFAULT '', -- mail Message-ID header field from_addr varchar(255) CHARACTER SET utf8 COLLATE utf8_bin DEFAULT '', -- mail From header field, UTF8 subject varchar(255) CHARACTER SET utf8 COLLATE utf8_bin DEFAULT '', -- mail Subject header field, UTF8 host varchar(255) NOT NULL, -- hostname where amavisd is running PRIMARY KEY (partition_tag,mail_id) -- FOREIGN KEY (sid) REFERENCES maddr(id) ON DELETE RESTRICT ) ENGINE=InnoDB; CREATE INDEX msgs_idx_sid ON msgs (sid); CREATE INDEX msgs_idx_mess_id ON msgs (message_id); -- useful with pen pals CREATE INDEX msgs_idx_time_num ON msgs (time_num); -- alternatively when purging based on time_iso (instead of msgs_idx_time_num): -- CREATE INDEX msgs_idx_time_iso ON msgs (time_iso); CREATE TABLE msgrcpt ( partition_tag integer DEFAULT 0, -- see $partition_tag mail_id varbinary(16) NOT NULL, -- (must allow duplicates) rseqnum integer DEFAULT 0 NOT NULL, -- recip's enumeration within msg rid bigint unsigned NOT NULL, -- recipient: maddr.id (dupl. allowed) is_local char(1) DEFAULT ' ' NOT NULL, -- recip is: Y=local, N=foreign content char(1) DEFAULT ' ' NOT NULL, -- content type V/B/U/S/Y/M/H/O/T/C ds char(1) NOT NULL, -- delivery status: P/R/B/D/T -- pass/reject/bounce/discard/tempfail rs char(1) NOT NULL, -- release status: initialized to ' ' bl char(1) DEFAULT ' ', -- sender blacklisted by this recip wl char(1) DEFAULT ' ', -- sender whitelisted by this recip bspam_level float, -- per-recipient (total) spam level smtp_resp varchar(255) DEFAULT '', -- SMTP response given to MTA PRIMARY KEY (partition_tag,mail_id,rseqnum) -- FOREIGN KEY (rid) REFERENCES maddr(id) ON DELETE RESTRICT, -- FOREIGN KEY (mail_id) REFERENCES msgs(mail_id) ON DELETE CASCADE ) ENGINE=InnoDB; CREATE INDEX msgrcpt_idx_mail_id ON msgrcpt (mail_id); CREATE INDEX msgrcpt_idx_rid ON msgrcpt (rid); CREATE TABLE quarantine ( partition_tag integer DEFAULT 0, -- see $partition_tag mail_id varbinary(16) NOT NULL, -- long-term unique mail id chunk_ind integer unsigned NOT NULL, -- chunk number, starting with 1 mail_text blob NOT NULL, -- store mail as chunks of octets PRIMARY KEY (partition_tag,mail_id,chunk_ind) -- FOREIGN KEY (mail_id) REFERENCES msgs(mail_id) ON DELETE CASCADE ) ENGINE=InnoDB;
Deploy modoboa
mkdir /var/www && cd /var/www modoboa-admin.py deploy --syncdb --collectstatic --with-amavis mailadmin cd mailadmin python manage.py collectstatic python manage.py syncdb --migrate --noinput python manage.py loaddata initial_users.json
Configure postfix
Use the modoboa-admin.py script to create these files automatically.
modoboa-admin.py postfix_maps --dbtype mysql /etc/postfix/maps
Answer the questions with the values you used earlier. The database is the modoboa database.
Fix permissions. Since these files contain your database passwords and it’s only postfix that need to read them.
chown root:postfix /etc/postfix/maps/sql-* chmod 640 /etc/postfix/maps/sql-*
configure postfix
postconf -e mailbox_transport=virtual postconf -e maildrop_destination_recipient_limit=1 postconf -e virtual_minimum_uid=5000 postconf -e virtual_gid_maps=static:5000 postconf -e virtual_uid_maps=static:5000 postconf -e virtual_mailbox_base=/var/vmail postconf -e relay_domains= postconf -e virtual_mailbox_domains=mysql:/etc/postfix/maps/sql-domains.cf postconf -e virtual_alias_domains=mysql:/etc/postfix/maps/sql-domain-aliases.cf postconf -e virtual_mailbox_maps=mysql:/etc/postfix/maps/sql-mailboxes.cf postconf -e virtual_alias_maps=mysql:/etc/postfix/maps/sql-aliases.cf,mysql:/etc/postfix/maps/sql-domain-aliases-mailboxes.cf,mysql:/etc/postfix/maps/sql-email2email.cf,mysql:/etc/postfix/maps/sql-catchall-aliases.cf postconf -e virtual_transport=dovecot postconf -e dovecot_destination_recipient_limit=1
add definition to /etc/postfix/master.cf
dovecot unix - n n - - pipe flags=DRhu user=vmail:vmail argv=/usr/lib/dovecot/deliver -f ${sender} -d ${recipient}
and then restart postfix
service postfix restart
configure nginx
Now we’ll install Green Unicorn and configure nginx. I know, there is a package included with Debian, don’t use that, use easy_install as described here to get the latest version instead.
Green Unicorn
easy_install -U gunicorn
create a gunicorn config file /var/www/mailadmin/gunicorn.conf.py
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"
Now, gunicorn won’t run without /var/run/gunicorn, let’s create it.
mkdir /var/run/gunicorn
then create a init script, /etc/init.d/modoboa:
#!/bin/sh # /etc/init.d/modoboa ### BEGIN INIT INFO # Provides: modoboa # Required-Start: $local_fs $remote_fs $network $syslog $time # Required-Stop: $local_fs $remote_fs $network $syslog # Default-Start: 2 3 4 5 # Default-Stop: 0 1 6 # Short-Description: Start modoboa at boot time # Description: Enable modoboa service ### END INIT INFO PATH=/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin MODOBOA_ROOT=/var/www/mailadmin LOGFILE=/var/log/modoboa.log PIDFILE=/var/run/gunicorn/modoboa.pid SOCKET=/var/run/gunicorn/modoboa.sock case "$1" in start) if [ -f "$PIDFILE" ]; then echo "Already running" else echo "Starting modoboa" cd $MODOBOA_ROOT gunicorn_django --error-log $LOGFILE -c gunicorn.conf.py fi ;; stop) if [ -f "$PIDFILE" ]; then echo "Stopping modoboa" kill -QUIT `cat /var/run/gunicorn/modoboa.pid` else echo "Not running" fi ;; restart) echo "Restarting modoboa" $0 stop sleep 1 $0 start ;; reload) echo "Reloading modoboa" kill -HUP `cat /var/run/gunicorn/modoboa.pid` ;; *) echo "Usage: /etc/init.d/modoboa {start|stop}" exit 1 ;; esac exit 0
set executable bit and enable the service:
chmod +x /etc/init.d/modoboa update-rc.d modoboa defaults
and finally start it
service modoboa start
nginx
now create a config file for nginx
vi /etc/nginx/sites-available/modoboa
change as it suits you:
upstream modoboa { server unix:/var/run/gunicorn/modoboa.sock fail_timeout=0; } server { listen 443; server_name <fqdn>; root /var/www/mailadmin/mailadmin/; ssl on; ssl_certificate /etc/ssl/<fqdn>.pem; ssl_certificate_key /etc/ssl/<fqdn>.key; # if you're serve other stuff; it might be good to use separate logfile access_log /var/log/nginx/access.log; error_log /var/log/nginx/error.log; location /sitestatic/ { autoindex on; } location /media/ { 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; proxy_pass http://modoboa; } }
change path to your cert and key accordingly. you can read here how to enable ssl and generate a self signed cert/key pair. You can use the same cert/key for dovecot below if you have the same fdqn on web- and mailserver.
Now enable the site and restart nginx. Make sure the certificates excist, otherwise nginx won’t start.
ln -s /etc/nginx/sites-available/modoboa /etc/nginx/sites-enabled/modoboa service nginx restart
You shold now be able to login using the default username: admin and password: password at https://<fqdn>. First thing you do is to change the password! First time you save modoboa settings, some tables are creted. Do that and then run the following snippets.
Change MAILDIR_ROOT
Change default maildir root from .maildir/ to just /. I think it’s prettier, and I already used this on a server I migrated from. This is optional.
echo "update modoboa.lib_parameter set value = '/' where name = 'admin.MAILDIR_ROOT';" | mysql -u root -p
Create a SECRET_KEY
echo "update modoboa.lib_parameter set value = '`pwgen -N 1 -s 32`' where name = 'auth.SECRET_KEY';" | mysql -u root -p
Change NOTIFICATIONS_SENDER
echo "update modoboa.lib_parameter set value = 'admin@domain.com' where name = 'amavis.NOTIFICATIONS_SENDER';" | mysql -u root -p
Configure dovecot
I won’t go into detail here. I’ll just paste an example config file. NOT COMPLETE YET!
# if you, like me, have mail stored on nfs use these settings so index files doesn't get corrupted (according to dovecot manual) mmap_disable = yes dotlock_use_excl = no mail_nfs_storage = yes mail_nfs_index = yes login_processes_count=16 login_max_processes_count=256 mail_max_userip_connections=20 protocols = imap imaps pop3 pop3s managesieve disable_plaintext_auth=no log_timestamp = "%Y-%m-%d %H:%M:%S" # certificates ssl_ca_file = /etc/ssl/certs/ca-certificates.crt ssl_cert_file = /etc/ssl/mail.crt ssl_key_file = /etc/ssl/mail.key # needed for fail2ban to work auth_verbose=yes log_path = /var/log/dovecot.log info_log_path = /var/log/dovecot-info.log mail_location = maildir:/var/vmail/%d/%n namespace private { separator=. inbox = yes } mail_privileged_group = mail protocol pop3 { pop3_uidl_format = %08Xu%08Xv } protocol imap { mail_plugins = quota imap_quota } plugin { sieve_global_path = /var/vmail/globalsieverc sieve_dir=/var/vmail/%d/%n/sieve sieve=/var/vmail/%d/%n/.dovecot.sieve quota = maildir:User quota quota_rule = *:storage=100M quota_rule2 = Trash:storage=50M } protocol managesieve { login_executable = /usr/lib/dovecot/managesieve-login mail_executable = /usr/lib/dovecot/managesieve managesieve_max_line_length = 65536 managesieve_logout_format = bytes=%i/%o #managesieve_implementation_string = Cyrus timsieved v2.2.13 } protocol lda { postmaster_address = admin@dalnix.se auth_socket_path = /var/run/dovecot/auth-master mail_plugins = sieve log_path = /var/log/dovecot-deliver-errors.log info_log_path = /var/log/dovecot-deliver.log } auth default { mechanisms = plain login passdb sql { args = /etc/dovecot/dovecot-sql.conf } userdb sql { args = /etc/dovecot/dovecot-sql.conf } user = root socket listen { master { path = /var/run/dovecot/auth-master mode = 0600 user = vmail } client { path = /var/spool/postfix/private/auth mode = 0660 user = postfix } } }
now create /etc/dovecot/dovecot-sql.conf.
driver = mysql connect = host=localhost dbname=modoboa user=modoboa password=somepassword default_pass_scheme = CRYPT password_query = SELECT email AS user, password FROM auth_user WHERE email='%u' and is_active=1 user_query = SELECT concat('/', dom.name, '/', mb.path) AS home, uid, gid, concat('*:storage=', mb.quota, 'M') AS quota_rule FROM admin_mailbox mb INNER JOIN admin_domain dom ON mb.domain_id=dom.id WHERE mb.address='%n' AND dom.name='%d'
and then restart dovecot
service dovecot restart
Troubleshooting
Relay access denied
If you get lines like these in your /etc/mail.log.
Mar 15 18:59:19 mail postfix/smtpd[4012]: NOQUEUE: reject: RCPT from mail-qe0-f48.google.com[209.85.128.48]: 454 4.7.1 <joe@example.com>: Relay access denied; from=<mrbad@gmail.com> to=<joe@example.com> proto=ESMTP helo=<mail-qe0-f48.google.com>
Make sure the domain/account is actually enabled in modoboa. I had some trouble figuring this out after doing an import of alot of domains and all apparantly got imported without beeing enabled (my bad).
Hi,
Am unable to launch the gunucorn server. Any help will be much appreciated.
Bellow is the /var/log/modoboa.log output.
http://pastebin.com/NJ0M1VyG
ValueError: Unable to configure handler ’modoboa’: Cannot resolve ’modoboa.lib.logutils.SQLHandler’: cannot import name connection
Hi, I’m sorry but I can’t help you. I’m not really a pyhon guru. Plus this guide is quite old and probably won’t work for Modoboa 1.0.
You’ll get better help asking in the #modoboa irc channel on Freenode etc.
Hi
You should mention that you need to specify ALLOWED_HOSTS in settings.py for the django app to get it up and running with nginx.
Regards
Paul
I would like to help you out testing Debian 7.2 setup.
Hi, I never got around to finishing mine. But I can recommend you check out this guide instead.