Debian Wheezy Mail Server – Postfix Dovecot Sasl MySQL PostfixAdmin RoundCube SpamAssassin Clamav Greylist Nginx PHP5

This is a tutorial on how to install an email server on Debian Wheezy 7.

We are going to install the following components:

E-mail server:

  • Postfix
  • Dovecot
  • Sasl library
  • MySQL

Milters:

  • SpamAssassin
  • Clamav
  • Greylist

Webserver:

  • Nginx
  • PHP5
  • phpMyAdmin
  • PostfixAdmin
  • RoundCube

Please replace any text in red with your info.

Here is a scheme about the internals, click on image to get a clear view:

Install E-mail Server - Postfix Dovecot Sasl MySQL PostfixAdmin RoundCube SpamAssassin Clamav Greylist Nginx PHP5 on Debian Wheezy 7 2014

1. Install Debian Wheezy 7

When installing Debian 7 itself, only select ‘SSH server’ when prompted to select software.
If Debian is ready, install the following packages:

apt-get install sudo mc vim

2. Install MySQL server and client

apt-get install mysql-server mysql-client

Enter a MySQL root password when prompted.

Check that mysqld is running:

ps aux

3. Install PHP5 and Nginx

At this point I use the Dotdeb repo to install PHP version 5.5.x

Add Dotdeb repositories to /etc/apt/sources.list file:

deb http://packages.dotdeb.org wheezy-php55 all
deb-src http://packages.dotdeb.org wheezy-php55 all

Add Dotdeb key:

wget http://www.dotdeb.org/dotdeb.gpg
sudo apt-key add dotdeb.gpg

Update apt cache:

apt-get update

Install PHP5 and Nginx:

apt-get install php5-fpm php5-imap php5-mysql php5-mcrypt php5-intl nginx openssl ssl-cert

Make sure php5-fpm and nginx are running:

service php5-fpm start
service nginx start

Create a folders to store web files:

mkdir /home/clients_ssl
mkdir /home/clients_ssl/<subdomain.domain.tld>
mkdir /home/clients_ssl/<subdomain.domain.tld>/logs
mkdir /home/clients_ssl/<subdomain.domain.tld>/tmp
mkdir /home/clients_ssl/<subdomain.domain.tld>/www

Create nginx config for this site:

vi /etc/nginx/sites-available/<subdomain.domain.tld>_ssl

Press ‘i’ and paste the following in vim, replace <yourip> and <subdomain.domain.tld> with your info:

server {

    listen <yourip>:443;
    server_name <subdomain.domain.tld>;

    ssl on;
    ssl_certificate        /etc/nginx/certs/<subdomain.domain.tld>.combined.crt;
    ssl_certificate_key    /etc/nginx/certs/<subdomain.domain.tld>.key;

    root /home/clients_ssl/<subdomain.domain.tld>/www;
    index index.php index.html index.htm;

    location ~ \.php$ {

        fastcgi_pass unix:/etc/php5/fpm/socks/ssl_<subdomain.domain.tld>.sock;
        include fastcgi_params;
        fastcgi_param HTTPS on;

    }

    location ~ /\. {
        deny all;
    }

    access_log /home/clients_ssl/<subdomain.domain.tld>/logs/access.log;
    error_log /home/clients_ssl/<subdomain.domain.tld>/logs/error.log;
    error_page 404 /404.html;

}

Remove the default site and put your site online:

rm /etc/nginx/sites-available/default
ln -s /etc/nginx/sites-available/<subdomain.domain.tld>_ssl /etc/nginx/sites-enabled/<subdomain.domain.tld>_ssl

Create the certs folder.

mkdir /etc/nginx/certs

Put your cerificates in there. Get a valid certificate from a certificate authority or create a self signed certificate.
You can google on how to make one. Make sure to edit your Nginx config file to match the certificate filenames.

Restart Nginx

service nginx restart

Create a php5-fpm config file:

vi /etc/php5/fpm/pool.d/ssl_<subdomain.domain.tld>.conf

Press ‘i’ and paste the following in vim, replace <subdomain.domain.tld> with your info:

[ssl_<subdomain.domain.tld>]

    listen = /etc/php5/fpm/socks/ssl_<subdomain.domain.tld>.sock
    user = u1001
    group = g1001
    listen.owner = www-data
    listen.group = www-data
    listen.mode = 0666
    pm = dynamic
    pm.max_children = 50
    pm.start_servers = 1
    pm.min_spare_servers = 1
    pm.max_spare_servers = 5
    pm.max_requests = 0
    php_admin_value[open_basedir]=/
    php_admin_value[session.save_path]=/home/clients_ssl/<subdomain.domain.tld>/tmp
    php_admin_value[upload_tmp_dir]=/home/clients_ssl/<subdomain.domain.tld>/tmp
    php_admin_value[disable_functions]=dl

Create a user for this virtualhost:

groupadd -g 1001 g1001
useradd --no-create-home -g 1001 -u 1001 u1001

Create socks folder:

mkdir /etc/php5/fpm/socks

Remove the default php pool:

rm /etc/php5/fpm/pool.d/www.conf

Add timezone info to php ini file /etc/php5/fpm/php.ini:

date.timezone = Europe/Tallinn

Restart php5-fpm

service php5-fpm restart

4. Install phpMyAdmin

cd /home/clients_ssl/<subdomain.domain.tld>/www
wget 'http://downloads.sourceforge.net/project/phpmyadmin/phpMyAdmin/4.0.8/phpMyAdmin-4.0.8-english.tar.gz?use_mirror=netcologne'
mv phpMyAdmin-4.0.8-english.tar.gz\?use_mirror=netcologne pma.tar.gz
tar -zxvf pma.tar.gz

Hide pma or bots will try to hack into it:

mv phpMyAdmin-4.0.8-english pma_763773
cd pma_763773
cp config.sample.inc.php config.inc.php

Set the right owner for www and tmp folder:

cd /home/clients_ssl/<subdomain.domain.tld>
chown -R 1001.1001 www tmp

Now you should be able to access pma at: https://<subdomain.domain.tld>/pma_763773/

Now open phpMyAdmin and click on ‘SQL’ on the top menubar. Paste the following SQL queries to create a database and user, replace <password> as you see fit:

CREATE DATABASE postfix;
GRANT ALL PRIVILEGES ON postfix.* TO 'postfix_admin'@'%' IDENTIFIED BY '<dbpassword1>';
GRANT SELECT ON postfix.* TO 'postfix'@'%' IDENTIFIED BY '<dbpassword2>';
FLUSH PRIVILEGES;

5. Install PostfixAdmin

Although you can install it from a standard Debian package I am going to download it directly instead so I can put it under my custom path immediately.

cd /home/clients_ssl/<subdomain.domain.tld>/www
wget 'http://downloads.sourceforge.net/project/postfixadmin/postfixadmin/postfixadmin-2.3.6/postfixadmin-2.3.6.tar.gz?use_mirror=garr'
mv postfixadmin-2.3.6.tar.gz\?use_mirror=garr pfa.tar.gz
tar -zxvf pfa.tar.gz
mv postfixadmin-2.3.6 pfa_746338
chown -R 1001.1001 pfa_746338
cd pfa_746338
sed -i 's/change-this-to-your.domain.tld/<subdomain.domain.tld>/g' config.inc.php

Now edit configuration file config.inc.php and change these values:

$CONF['configured'] = true;
$CONF['postfix_admin_url'] = 'https://<subdomain.domain.tld>/pfa_746338';
$CONF['database_type'] = 'mysqli';
$CONF['database_host'] = 'localhost';
$CONF['database_user'] = 'postfix_admin';
$CONF['database_password'] = '<dbpassword1>';
$CONF['database_name'] = 'postfix';
$CONF['domain_path'] = 'YES';
$CONF['domain_in_mailbox'] = 'NO';
$CONF['fetchmail'] = 'NO';

Go to https://<subdomain.domain.tld>/pfa_746338/setup.php

This setup script should create the nesessary tables to postfix database.

At the bottom of setup.php enter your admin password and click ‘Gererate password hash’.

Edit config.inc.php and add the hash:

$CONF['setup_password'] = '<hash>';

Now enter superadmin account info. You can use this to access PostfixAdmin and configure domains, e-mail accounts, aliases etc.

Try to log in with the admin account here: https://<subdomain.domain.tld>/pfa_746338

6. Install Postfix and Sasl library

apt-get install postfix postfix-mysql libsasl2-modules libsasl2-modules-sql

When prompted, choose ‘Internet Site’.

Use yor domain name as ‘System mail name’: <subdomain.domain.tld>
For example use ‘mail.yourdomain.tld’. Do not use ‘yourdomain.tld’ here if it is going to be one of your virtual mailbox domains.

Create virtual mail user and group:

groupadd -g 3000 vmail
useradd -d /home/vmail -m -u 3000 -g 3000 vmail

Edit /etc/postfix/main.cf:

mydestination = <subdomain.domain.tld>, localhost

and add the following lines:

virtual_uid_maps = static:3000
virtual_gid_maps = static:3000
virtual_mailbox_base = /home/vmail
virtual_mailbox_domains = mysql:/etc/postfix/mysql_virtual_mailbox_domains.cf
virtual_mailbox_maps = mysql:/etc/postfix/mysql_virtual_mailbox_maps.cf
virtual_alias_maps = mysql:/etc/postfix/mysql_virtual_alias_maps.cf
relay_domains = mysql:/etc/postfix/mysql_relay_domains.cf
virtual_transport = lmtp:unix:private/dovecot-lmtp
smtpd_recipient_restrictions =
 permit_mynetworks,
 permit_sasl_authenticated,
 reject_non_fqdn_hostname,
 reject_non_fqdn_sender,
 reject_non_fqdn_recipient,
 reject_unauth_destination,
 reject_unauth_pipelining,
 reject_invalid_hostname
smtpd_sasl_auth_enable = yes
smtpd_sasl_security_options = noanonymous
smtpd_sasl_type = dovecot
smtpd_sasl_path = private/auth
milter_default_action = accept

Create the following files:

/etc/postfix/mysql_virtual_mailbox_domains.cf

hosts = 127.0.0.1
user = postfix
password = <dbpassword2>
dbname = postfix
query = SELECT domain FROM domain WHERE domain='%s' and backupmx = 0 and active = 1

/etc/postfix/mysql_virtual_mailbox_maps.cf

hosts = 127.0.0.1
user = postfix
password = <dbpassword2>
dbname = postfix
query = SELECT maildir FROM mailbox WHERE username='%s' AND active = 1

/etc/postfix/mysql_virtual_alias_maps.cf

hosts = 127.0.0.1
user = postfix
password = <dbpassword2>
dbname = postfix
query = SELECT goto FROM alias WHERE address='%s' AND active = 1

/etc/postfix/mysql_relay_domains.cf

hosts = 127.0.0.1
user = postfix
password = <dbpassword2>
dbname = postfix
query = SELECT domain FROM domain WHERE domain='%s' and backupmx = 1

/etc/postfix/sasl/smtpd.conf

pwcheck_method: auxprop
mech_list: plain login
auxprop_plugin: sql
sql_engine: mysql
sql_hostnames: 127.0.0.1
sql_user: postfix
sql_passwd: <dbpassword2>
sql_database: postfix
sql_select: SELECT password FROM mailbox WHERE username = '%u@%r' AND active = 1

Add postfix user to sasl group:

adduser postfix sasl

Enable secure smtp ports, edit /etc/postfix/master.cf and uncomment:

submission inet n - - - - smtpd 
 -o syslog_name=postfix/submission 
 -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
smtps inet n - - - - smtpd
 -o syslog_name=postfix/smtps
 -o smtpd_tls_wrappermode=yes
 -o smtpd_sasl_auth_enable=yes
 -o smtpd_client_restrictions=permit_sasl_authenticated,reject
 -o milter_macro_daemon_name=ORIGINATING

7. Install Dovecot

apt-get install dovecot-imapd dovecot-pop3d dovecot-mysql dovecot-lmtpd

Create file /etc/dovecot/dovecot-mysql.conf.ext:

driver = mysql
connect = host=127.0.0.1 dbname=postfix user=postfix password=<dbpassword2>
default_pass_scheme = MD5-CRYPT
user_query = SELECT '/home/vmail/%d/%n' as home, 3000 AS uid, 3000 AS gid FROM mailbox WHERE username = '%u'
password_query = SELECT password FROM mailbox WHERE username = '%u'

Edit /etc/dovecot/conf.d/10-auth.conf

disable_plaintext_auth = no
auth_mechanisms = plain login
#!include auth-system.conf.ext
!include auth-sql.conf.ext

Edit /etc/dovecot/conf.d/10-mail.conf

mail_location = maildir:/home/vmail/%d/%n:INDEX=/home/vmail/%d/%n/indexes

Edit /etc/dovecot/conf.d/10-ssl.conf

ssl = yes

Edit /etc/dovecot/conf.d/20-imap.conf

mail_max_userip_connections = 10

Edit /etc/dovecot/conf.d/auth-sql.conf.ext

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

Edit /etc/dovecot/conf.d/10-master.conf

service lmtp {
  unix_listener /var/spool/postfix/private/dovecot-lmtp {
    mode = 0600
    user = postfix
    group = postfix
  }
}
service auth {
  # Postfix smtp-auth
  unix_listener /var/spool/postfix/private/auth {
    mode = 0666
  }
}

Restart services:

service dovecot restart
service postfix restart

You can now add a domain with PostfixAdmin and test your e-mail server.

Any errors are found in logfiles:

/var/log/auth.log
/var/log/mail.log
/var/log/syslog

8. Install Milters

apt-get install clamav-milter clamav-unofficial-sigs milter-greylist spamass-milter

 

clamav-milter:

Update ClamAv database and start the daemon:

freshclam
/etc/init.d/clamav-daemon start

Edit /etc/default/clamav-milter and uncomment the last line:

SOCKET_RWGROUP=postfix

Create a socket folder inside Postfix chroot environment:

mkdir /var/spool/postfix/clamav
chown clamav /var/spool/postfix/clamav

Configure ClamAv milter:

dpkg-reconfigure clamav-milter

Answer questions as follows:

Handle configuration automatically --> yes
User for daemon --> clamav
Additional groups --> none (empty field)
path to socket --> /var/spool/postfix/clamav/clamav-milter.ctl
group owner for the socket --> clamav
permissions (mode) for socket --> 660
remove stale socket --> yes
wait timeout for clamd --> 120
foreground --> no
chroot --> none (empty field)
pid file --> /var/run/clamav/clamav-milter.pid
temporary path --> /tmp
clamd socket --> unix:/var/run/clamav/clamd.ctl
hosts excluded for scanning --> none (empty field)
mail whitelist --> none (empty field)
action for "infected" mail --> reject
action on error --> defer
reason for rejection --> Rejecting harmful e-mail: %v found.
headers -> replace
log file --> /var/log/clamav/clamav-milter.log
disable log file locking --> no
maximum log file size --> 0
log time --> yes
use syslog --> no
log facility (type of syslog message) --> LOG_LOCAL6
verbose logging --> no
log level when infected --> off
log level when no threat --> off
size limit for scanned messages  --> 25

Tell Postfix to use this new milter:

postconf -e 'smtpd_milters = unix:/clamav/clamav-milter.ctl'
postfix reload

 

spamass-milter:

Edit /etc/default/spamass-milter:

Add ‘-m’ so it won’t change the subject header.

Add ‘-r -1’ so Postfix rejects what SpamAssassin flags as spam.

Add ‘-l’ to avoid scanning e-mails sent by logged in users.

OPTIONS="-u spamass-milter -i 127.0.0.1 -m -r -1 -I"

Restart milter:

service spamass-milter restart

Add a dedicated user for SpamAssassin daemon:

adduser --shell /bin/false --home /var/lib/spamassassin --disabled-password --disabled-login --gecos "" spamd

Edit /etc/default/spamassassin:

ENABLED=1
OPTIONS="--create-prefs --max-children 5 --helper-home-dir=/var/lib/spamassassin -u spamd -g spamd"
CRON=1

Update rules and restart the daemon:

sa-update
service spamassassin restart

Tell Postfix to use new milter:

postconf -e 'smtpd_milters = unix:/clamav/clamav-milter.ctl, unix:/spamass/spamass.sock'
postfix reload

 

milter-greylist:

Edit /etc/milter-greylist/greylist.conf:

# For sendmail use the following two lines
#socket "/var/run/milter-greylist/milter-greylist.sock"
#user "smmsp"
# For Postfix uncomment the following two lines and comment out the
# sendmail ones above.
socket "/var/spool/postfix/milter-greylist/milter-greylist.sock" 660
user "greylist"

Edit /etc/default/milter-greylist:

ENABLED=1
SOCKET="/var/spool/postfix/milter-greylist/milter-greylist.sock"

Make a folder for the socket and restart milter:

mkdir /var/spool/postfix/milter-greylist
chmod 2755 /var/spool/postfix/milter-greylist
chown greylist:postfix /var/spool/postfix/milter-greylist
service milter-greylist restart

Tell Postfix to use the new milter:

postconf -e 'milter_connect_macros = i b j _ {daemon_name} {if_name} {client_addr}'
postconf -e 'smtpd_milters = unix:/milter-greylist/milter-greylist.sock, unix:/clamav/clamav-milter.ctl, unix:/spamass/spamass.sock'
postfix reload

9. Install RoundCube

wget 'http://downloads.sourceforge.net/project/roundcubemail/roundcubemail/0.9.4/roundcubemail-0.9.4.tar.gz?use_mirror=heanet'
mv roundcubemail-0.9.4.tar.gz\?use_mirror=heanet roundcubemail-0.9.4.tar.gz
tar -zxvf roundcubemail-0.9.4.tar.gz
mv roundcubemail-0.9.4 rcb_733621
chown -R 1001.1001 rcb_733621

Open phpMyAdmin SQL window and paste:

CREATE DATABASE roundcube;
GRANT ALL PRIVILEGES ON roundcube.* TO roundcube@localhost IDENTIFIED BY '<rcpassword>';
FLUSH PRIVILEGES;

Add initial tables and data:

cd /home/clients_ssl/<subdomain.domain.tld>/www/rcb_733621
mysql -u roundcube -p roundcube < SQL/mysql.initial.sql

Go to https://<subdomain.domain.tld>/rcb_733621/installer/

See that your environment is ok and click Next.

On the ‘Create config’ page, you may want to change the following values:

product_name: <yourproductname>
support_url: <yoururl>
database name: roundcube
database password: <rcpassword>
default_host: localhost
smtp_server: localhost
language: en_US

Click Continue

Change the value in textarea to:

$rcmail_config['use_https'] = true;

Then copy all from textarea and paste the contents to main.inc.php and db.inc.php under /home/clients_ssl/<subdomain.domain.tld>/www/rcb_733621/config

Remove installer folder:

mv installer ../../

Open RoundCube at https://<subdomain.domain.tld>/rcb_733621/

This is it 🙂
If this was of any use please link back to this tutorial.
Thank you.

Sources used to build this tutorial:

https://library.linode.com/email/postfix/postfix2.9.6-dovecot2.0.19-mysql
http://www.bytetouch.com/blog/linux/how-to-linux-mail-server-with-postfix-and-dovecot-on-debian-lenny/
https://lelutin.ca/posts/installing_postfix_-_clamav_-_spamassassin_-_dovecot_-_postfixadmin_on_debian_squeeze/

92 thoughts on “Debian Wheezy Mail Server – Postfix Dovecot Sasl MySQL PostfixAdmin RoundCube SpamAssassin Clamav Greylist Nginx PHP5

  1. aris says:

    Hi. nice tutorial. I am afraid i am having an issue in step 3. After doing the steps in step 3, i cannot have access anywhere to http/https. Any ideas?

  2. Yllar says:

    Check if nginx and php5-fpm are running and see what the /home/clients/…/logs say. Also check /var/log/php5-fpm.log and /var/log/nginx/error.log

  3. Yllar says:

    I was also missing _ssl in this line:
    vi /etc/nginx/sites-available/<subdomain.domain.tld>_ssl
    That is now fixed in the tutorial above.

  4. aris says:

    the problem is actually in php5-fpm. i am getting error:
    [08-Nov-2013 04:22:10] ERROR: [/etc/php5/fpm/pool.d/ssl_aris.eu.conf:1] value is NULL for a ZEND_INI_PARSER_ENTRY
    [08-Nov-2013 04:22:10] ERROR: Unable to include /etc/php5/fpm/pool.d/ssl_aris.eu.conf from /etc/php5/fpm/php-fpm.conf at line 1
    [08-Nov-2013 04:22:10] ERROR: failed to load configuration file ‘/etc/php5/fpm/php-fpm.conf’
    [08-Nov-2013 04:22:10] ERROR: FPM initialization failed
    [FAIL] Restarting PHP5 FastCGI Process Manager: php5-fpm failed!

  5. aris says:

    i am installing in a wheezy. i did a fresh install and now the error is gone. i have 2 final questions:
    -roundcube installer fails to write to database main.inc.php: NOT OK and db.inc.php: NOT OK
    -all the spam messages will get discarded or will it be send to recepients spam folder?

  6. vidal says:

    Hello, in the final step where it says “Then copy and paste the contens to main.inc.php and db.inc.php”. These files must be created or adder configuration information to them? What is the path where it should be located? Thank you.

  7. Yllar says:

    aris, just check your roundcube mysql user permissions with phpmyadmin. by default spamassassin adds a header if mail gets more than 5 points and sends it to users inbox.

  8. vidal says:

    Thanks, I’ve corrected the above problem. Now the problem is that roundcube not access mailboxes and displays the message “Error 504 Gateway Time out”

  9. Thanks for the tutorial. Just a little heads up for others that the PHP process must be able to write to ‘/home/clients_ssl//tmp’ otherwise when you try to login into PostfixAdmin you will be constantly redirected back to the login page.

  10. Mauro says:

    Hi, Thanks for the tutorial.
    After a few problems I managed to complete it.
    Everything seems ok, including logs, but incoming messages do not show up anywhere. What should I check?

    • Sander says:

      The problem lies in here with the fact that postfix mails are stuck in queue :

      Dec 8 14:56:45 excelsior milter-greylist: (unknown id): Sender IP 209.85.128.46 and address are SPF-compliant, bypassing greylist
      Dec 8 14:56:45 excelsior postfix/smtpd[4139]: 9E3FC40AE1: client=mail-qe0-f46.google.com[209.85.128.46]
      Dec 8 14:56:45 excelsior postfix/cleanup[4146]: 9E3FC40AE1: message-id=
      Dec 8 14:56:45 excelsior milter-greylist: smfi_getsymval failed for {if_addr}
      Dec 8 14:56:45 excelsior spamd[3228]: spamd: connection from localhost [127.0.0.1] at port 42791
      Dec 8 14:56:45 excelsior spamd[3228]: spamd: handle_user unable to find user: ‘info’
      Dec 8 14:56:45 excelsior spamd[3228]: spamd: processing message for info:1001
      Dec 8 14:56:46 excelsior spamd[3228]: plugin: eval failed: bayes: (in learn) locker: safe_lock: cannot create tmp lockfile /var/lib/spamassassin/.spamassassin/bayes.lock.excelsior.sandervankasteel.nl.3228 for /var/lib/spamassassin/.spamassassin/bayes.lock: No such file or directory
      Dec 8 14:56:46 excelsior spamd[3228]: spamd: clean message (-0.7/5.0) for info:1001 in 0.5 seconds, 7635 bytes.
      Dec 8 14:56:46 excelsior spamd[3228]: spamd: result: . 0 – FREEMAIL_FROM,HTML_MESSAGE,RCVD_IN_DNSWL_LOW,SPF_PASS,T_DKIM_INVALID,URIBL_BLOCKED scantime=0.5,size=7635,user=info,uid=1001,required_score=5.0,rhost=localhost,raddr=127.0.0.1,rport=42791,mid=,autolearn=unavailable
      Dec 8 14:56:46 excelsior postfix/qmgr[4092]: 9E3FC40AE1: from=, size=7360, nrcpt=1 (queue active)
      Dec 8 14:56:46 excelsior postfix/smtpd[4139]: disconnect from mail-qe0-f46.google.com[209.85.128.46]

      Apparently it spamd cant the user info. But it shouldn’t be info. It should be info@mydomain.org

  11. Sander says:

    To fix the mail stuck in postfix queue error ..

    Change the following settings

    /etc/dovecot/conf.d/10-master.conf

    from :

    unix_listener lmtp {
    mode = 0600
    user = postfix
    group = postfix
    }

    to :
    unix_listener /var/spool/postfix/private/dovecot-lmtp {
    mode = 0600
    user = postfix
    group = postfix
    }

    /etc/postfix/main.cf

    from :

    virtual_transport = lmtp:unix:private/lmtp

    to :

    virtual_transport = lmtp:unix:private/dovecot-lmtp

    • Dr4K4n says:

      Thank you very much Sander, with your little modification it finally worked!
      Of course also a very big Thank You! to Yllar for creating such a great tutorial.

    • TooMeeK says:

      Thank You soo much, of course it WORKED.
      I’ve also made mistake in:
      /etc/init.d/dovecot restart
      doveconf: Fatal: Error in configuration file /etc/dovecot/conf.d/10-master.conf line 62: Unexpected ‘}’
      [….] Restarting IMAP/POP3 mail server: dovecotdoveconf: Fatal: Error in configuration file /etc/dovecot/conf.d/10-master.conf line 62: Unexpected ‘}’
      failed!

      I recommend reading logs during e-mail testing with following:
      colortail -f /var/log/mail.log
      It’s simpler to read.. 🙂

  12. Brett says:

    Awesome tutorial Yllar! Thanks for taking the (surely very long) time to put it together. Now I have a sheevaplug email sever for 2014 🙂

    At the last step of the roundcube webmail installer (Test Config) I had to solve a problem (maybe just sheevaplug repositories??).
    The database connection failed so I looked in db.inc.php and saw it was looking for “roundcubemail” database instead of “roundcube”.

    I changed this line –> $rcmail_config[‘db_dsnw’] = ‘mysql://roundcube:@localhost/roundcubemail’;
    to this –> $rcmail_config[‘db_dsnw’] = ‘mysql://roundcube:@localhost/roundcube’;
    and it worked fine.

  13. GATEN says:

    I’m just turning crazy with the folowing error :

    ***
    I’m sorry to have to inform you that your message could not
    be delivered to one or more recipients. It’s attached below.

    For further assistance, please send mail to postmaster.

    If you do so, please include this problem report. You can
    delete your own text from the attached returned message.

    The mail system

    Action: failed
    Status: 5.1.1
    Diagnostic-Code: X-Postfix; unknown user:
    ***
    It’s the content of the email who is send back to every people who want to send a message to my server.

    Everything else works as espected

  14. GATEN says:

    So finally I did :

    /etc/postfix/main.cf
    mydestination = ”
    virtual_transport = dovecot
    dovecot_destination_recipient_limit = 1
    virtual_mailbox_domains = put-your-domain.com

    At the end of /etc/postfix/master.cf
    dovecot unix – n n – – pipe
    flags=DRhu user=vmail:vmail argv=/usr/lib/dovecot/dovecot-lda -f ${sender} -d ${user}@${nexthop} -m ${extension}

    And now it works.
    I didn’t install the section “milters” of this topic.

    I try it in a fresh install of Debian Wheezy 7.3

  15. Heh, in the middle of instalation (step 5) I’ve figured out that I missed something – it’s the HOSTNAME, so mail server name.
    Confusing entries are:
    subdomain.domain.tld
    it should be like this:
    mailserver.domain.com
    for better understanding. Everything can be corrected but before Step 5 is finished.
    Also in my case DB server is external machine (for security reasons), so MyPHPadmin isn’t needed.
    Grat how-to by the way.. 🙂

    • Aha, so U missed SSL certs 🙂
      cd /etc/nginx/certs/
      openssl genrsa -out subdomain.domain.tld.key 1024
      openssl req -new -x509 -days 365 -key subdomain.domain.tld.key -out subdomain.domain.tld.combined.crt

  16. The postfix and dovecot are working ok. However clamav-milter worked once then failed and the spamassassin fails with the same socket / no such file error:

    postfix/smtpd[15872]: warning: connect to Milter service unix:/clamav/clamav-milter.ctl: No such file or directory
    postfix/smtpd[15872]: warning: connect to Milter service unix:/spamass/spamass.sock: No such file or directory

    multiusers and sites, with mysql.

    mydestination = localhost

    #Handing off local delivery to Dovecot’s LMTP, and telling it where to store mail
    virtual_transport = lmtp:unix:private/dovecot-lmtp

    #Virtual domains, users, and aliases
    virtual_mailbox_domains = mysql:/etc/postfix/mysql-virtual-mailbox-domains.cf
    virtual_mailbox_maps = mysql:/etc/postfix/mysql-virtual-mailbox-maps.cf
    virtual_alias_maps = mysql:/etc/postfix/mysql-virtual-alias-maps.cf

    smtpd_milters = unix:/clamav/clamav-milter.ctl, unix:/spamass/spamass.sock

    //dovecot
    service lmtp {
    unix_listener /var/spool/postfix/private/dovecot-lmtp {
    mode = 0600
    user = postfix
    group = postfix
    }

    srw-rw—- 1 postfix postfix 0 Jan 12 21:59 /var/spool/postfix/spamass/spamass.sock
    srw-rw—- 1 clamav postfix 0 Jan 12 21:29 /var/spool/postfix/clamav/clamav-milter.ctl

    any ideas on debugging the above would be appreciated.
    BR
    Mike.

  17. Constin says:

    you dont need psteps 3 and 4.
    apt-get install apache2 is 3 and 4 step

    step 5
    apt-get install postfixadmin
    http://localhost/postfixadmin/setup.php

    then replace user = postfix to user = postfixadmin
    password = to password from /etc/postfixadmin/dbconfig.inc.php $dbpass
    dbname = postfix to dbname = postfixadmin\

    very nice manual, but to overloaded with trash in 3-5 steps.

  18. Nice tutorial, very clear and pleasant to read.
    Thank you _very much_ for this. It was very helpful. I just had to tweak some settings to make it work in ‘few’ hours.
    I don’t understand why you decided to install phpMyAdmin (I did not myself) but it’s a matter of choice.
    Good job !

  19. Frank says:

    Thanks for the guide, really helped get all the pieces together.
    Just wondering, there is an error in my logs from minter-greylist:

    minter-greylist: smfi_getsymval failed for {if_addr}

    I tried changing the setting in main.cf to {client_addr}
    as suggested in http://www.postfix.org/MILTER_README.html#Workarounds
    but then it gives the error:

    minter-greylist: smfi_getsymval failed for {client_addr}

    mail is getting through, not sure if this is something that needs fixing or just a minor warning?

  20. Bridgit says:

    Very good tutorial!
    Thank you very much!
    My mail.log show this:

    Jan 27 01:58:25 mailhub spamass-milter[2984]: Could not retrieve sendmail macro “i”!. Please add it to conf MILTER_MACROS_ENVFROM for better spamassassin results
    Jan 27 01:58:25 mailhub milter-greylist: smfi_getsymval failed for {i}
    Jan 27 01:58:25 mailhub milter-greylist: smfi_getsymval failed for {if_addr}

    Will these errors that affect system security?

    /B

    • Sascha says:

      Jan 27 01:58:25 mailhub milter-greylist: smfi_getsymval failed for {if_addr}:

      use: milter_connect_macros = i b j _ {daemon_name} {client_name} {client_addr}

  21. Hello,
    thanks for your Tutorial. The Server work now, but I get 3 error Messages one I could solve, the other both I don’t find anything by google.

    The first is

    /etc/cron.daily/spamassassin:
    channel: attempt to rm channel cf file failed, attempting to continue anyway at /usr/bin/sa-update line 825.
    error: can't remove file /var/lib/spamassassin/3.003002/updates_spamassassin_org/MIRRORED.BY: Keine Berechtigung
    channel: attempt to rm channel directory failed, attempting to continue anyway at /usr/bin/sa-update line 828.
    error: failed to open /var/lib/spamassassin/3.003002/updates_spamassassin_org/10_default_prefs.cf for write: Keine Berechtigung at /usr/bin/sa-update line 1118.
    channel: archive extraction failed, channel failed
    error: can't remove file /var/lib/spamassassin/3.003002/updates_spamassassin_org/MIRRORED.BY: Keine Berechtigung
    channel: attempt to clean up failed extraction also failed!
    sa-update failed for unknown reasons

    To Solve:
    I change the spamd User to debain-spamd in /etc/default/spamassassin

    Now the other both Error Messages:


    spamd[5562]: spamd: unauthorized connection from Der Name oder der Dienst ist nicht bekannt [192.168.178.200] at port 56564 at /usr/sbin/spamd line 1274.
    spamass-milter[5540]: Could not extract score from
    (The Name oder service is not known. 192.168.178.200 Is the internal IP from the Server)

    spamass-milter[5540]: Could not retrieve sendmail macro "i"!. Please add it to confMILTER_MACROS_ENVFROM for better spamassassin results
    milter-greylist: smfi_getsymval failed for {i}
    milter-greylist: smfi_getsymval failed for {if_addr}

    Can You help me to solve the both errors? The Spamassassin is’n running 🙁

    Thank You

  22. First I would like to thank you for the time you took, to create this tutorial. Very nice. But I´m gettin this sticky error, and I couldn´t find out, where the error is.
    In my log I found this entry:

    dovecot: imap(mogli@power.org): Error: file_dotlock_create(/var/vmail/power.org/mogli/dovecot-uidlist) failed: Permission denied (euid=999() egid=122() missing +w perm: /var/vmail/power.org/mogli, dir owned by 1001:113 mode=0755)

    Do I have a permission problem here? I tried to change the permissions on the folder, but won´t change the situation.

    I only installed step1 to step7…

    any ideas, where I went wrong?

    • Gabriel says:

      Thanks for this too, MrGalloway! But I don’t understand why one would install PhpMyAdmin, only to run a couple of simple queries. It adds a security concern to this setup, totally needlessly. I think it is much better to run the SQL commands directly in the mysql interactive (or not!) client.

  23. Hey 😉
    Big thanks for this tutorial!
    I am using debian 7, but without nginx and apache2 instead.
    Now, i dont understand postfixadmin very well and i cant create a user/mail for my roundcube installation.
    What steps do i have to do with postfixadmin?
    Do you have a configuration for apache too? 😉

    Thanks a lot,
    David

  24. Long says:

    Hi,

    Thank you for your tutorial ! I would like to know if it is possible to add quotas for each domain name and quotas for each account?

    Kind regards,
    Long

  25. Mike says:

    Thanks for the tutorial – been meaning to try it for ages. Mostly working, but having some issues…

    From Roundcube, I *can*:
    * send mail to external addresses,
    * send email to local users on the mailserver (e.g. root),

    but I *can’t* seem to get an email delivered to any of my virtual users. Even the “Broadcast message” option in PostfixAdmin” doesn’t deliver them.

    Using “postqueue -q”, I see all my mails backed up having timed out with the following message:
    (lost connection with myprivatedomain.com[private/dovecot-lmtp] while receiving the initial server greeting)

    Not really sure where to start looking. Any suggestions would be very much appreciated.

    Best regards,
    Mike

    • Mike says:

      Nevermind… left it overnight and when I came back in the morning, all was good. Think it was a reboot that fixed it after I’d made some settings changes related to hosts and domains.

      Great article.
      Mike

      • Mike says:

        Forgot to mention – I followed this article on a Raspberry Pi model B using the Raspbian Wheezy image. I will only have a few users (family), but multiple domains/mail boxes albeit low-volume. So far, the Pi seems to be holding up nicely. Enabling some of the milters seemed to swamp the CPU but, once running, they all settled down nicely. Now I have a great low-cost mail server!

  26. Michael says:

    Thank you for the Tutorial!

    But there ist a Problem: If i deactivate a user in postfixadmin, the user can still log in and he still gets mails.
    I modified the sql-statements in the file /etc/dovecot/dovecot-mysql.conf.ext to:
    user_query = SELECT CONCAT(‘/home/vmail/’,maildir) as home, 3000 AS uid, 3000 AS gid FROM mailbox WHERE username = ‘%u’ AND active = 1
    password_query = SELECT password FROM mailbox WHERE username = ‘%u’ AND active = 1

    Now it works for me.

  27. xcls says:

    With debian wheezy postfix seems not to deliver the mails into /home/vmail/domain/user but into /var/mail/user, with the file containing ALL mails for the user.

    How can I fix this?

    • I found one of two possible causes. Firstly I hadn’t done /etc/postfix/mysql_virtual_mailbox_maps.cf configuration.

      Secondly I noticed a warning in mail.log to not have mydomain.co.uk in both mail map and mydestination. I took it out of the “mydestination” parametre and now everything gets sent to the correct mailbox

  28. sianios says:

    I followed you tutorial without any problem until the end, I have installed roundcube, created the user accounts but when I try to send this message i get the following error
    SMTP Error (451): Failed to add recipient “user@gmail.com” (4.3.0 : Temporary lookup failure).

  29. Gabriel says:

    Hi, thanks and congrats.
    I have successfully reached paragraph 7 (incl.) but then I see that it is sendmail which is listening on port 25.
    Is this normal? I would expect postfix, no?
    Thanks!

  30. In step 4, install phpMyAdmin, i encountered the error “nginx 502 bad gateway error” when accessing https:///phpmyadmin/, and when I check the error log in /home/clients_ssl//logs/error.log, it says “permisson denied on /etc/php5/fpm/socks/ssl_.sock”, so I finally solved it by:

    chmod 666 /etc/php5/fpm/socks/ssl_.sock

    • Kulinski says:

      Put these two rows in your /etc/php5/fpm/pool.d/ssl_.conf

      listen.owner = www-data
      listen.group = www-data

      Else the socks permissions will change back after restarting php5-fpm and you will get the same error again.

      Regards

      Peter

    • maxime says:

      Same problem here.
      If I apply your solution it works but as soon as I restart the server, I need to do this command again.

      Would there be a way to have this issue fixed all the time ? (without a need of action from me ?)

  31. maxime says:

    Hi,

    I followed this tutorial and it seems to work well……apart that I cannot receive emails.

    I can send emails from this newly created server, but I cannot receive them.

    The error message I get is :


    This is the mail system at host vpsXXXXX.ovh.net.

    I’m sorry to have to inform you that your message could not
    be delivered to one or more recipients. It’s attached below.

    For further assistance, please send mail to postmaster.

    If you do so, please include this problem report. You can
    delete your own text from the attached returned message.

    The mail system

    : unknown user: “maxime”

    Final-Recipient: rfc822; maxime@mydomainname.org
    Original-Recipient: rfc822;maxime@mydomainname.org
    Action: failed
    Status: 5.1.1
    Diagnostic-Code: X-Postfix; unknown user: “maxime”

    Any idea what could have gone wrong ?

    All I did is :
    – Go to postfixadmin
    – Create a domain “mydomainname.org”
    – Create an email address
    – I can then connect to roundcube using this email address
    – I can send emails to my gmail account (and it works)
    – It fails when I reply from my gmail account to the new address

    I would love some help, please ! 🙂

    • maxime says:

      Hi again,

      So, I solved my issue by removing from the mydestination of /etc/postfix/main.cf :

      mydestination = localhost

  32. Marek says:

    Hello
    How i can add whitelist to IP?
    I try add to /etc/spamassassin/local.cf
    trusted_networks 222.222.222.222
    but after send fake spam i get in log:
    Jun 27 14:41:27 MAILDIR1 postfix/cleanup[6687]: A12B8200656: milter-reject: END-OF-MESSAGE from unknown[222.222.222.222]: 5.7.1 Blocked by SpamAssassin;

    Thanks

  33. I note you have marked as deleted all the lines in /etc/postfix/sasl/smtpd.conf. If this is the case,
    where should one tell saslauthd to use, in my case, mysql for authentication. I just upgraded my server to
    wheezy, and sasl authentication is no longer working.
    thanks!

    • john says:

      Have you soled the vacation (out of office) in your configuration ? I m facing the same issue .. My idea was set up postfixadmin’s vacation perl script.

  34. sayad says:

    hello

    i get this error on mail.log file?

    Jul 31 14:00:02 mail postfix/qmgr[3140]: 0196B1208F4: removed
    Jul 31 14:00:27 mail postfix/smtpd[3333]: connect from localhost[127.0.0.1]
    Jul 31 14:00:27 mail postfix/smtpd[3333]: 133A51208DD: client=localhost[127.0.0.1]
    Jul 31 14:00:27 mail postfix/cleanup[3341]: 133A51208DD: message-id=
    Jul 31 14:00:27 mail postfix/qmgr[3140]: 133A51208DD: from=, size=629, nrcpt=1 (queue active)
    Jul 31 14:00:27 mail postfix/local[3344]: 133A51208DD: to=, relay=local, delay=0.08, delays=0.06/0/0/0.03, dsn=5.1.1, status=bounced (unknown user: “user1”)
    Jul 31 14:00:27 mail postfix/cleanup[3341]: 27E2E1208F4: message-id=
    Jul 31 14:00:27 mail postfix/bounce[3345]: 133A51208DD: sender non-delivery notification: 27E2E1208F4
    Jul 31 14:00:27 mail postfix/qmgr[3140]: 27E2E1208F4: from=, size=2545, nrcpt=1 (queue active)
    Jul 31 14:00:27 mail postfix/qmgr[3140]: 133A51208DD: removed
    Jul 31 14:00:27 mail postfix/local[3344]: 27E2E1208F4: to=, relay=local, delay=0.08, delays=0.05/0/0/0.03, dsn=5.1.1, status=bounced (unknown user: “user1”)
    Jul 31 14:00:27 mail postfix/qmgr[3140]: 27E2E1208F4: removed
    Jul 31 14:00:27 mail postfix/smtpd[3333]: disconnect from localhost[127.0.0.1

    why?

  35. First of all many thanks for such a nice writeup. This must be the most concise and easiest postfix installation I ever came across.

    Irrespective of excellent hand-holding I managed to get stuck:

    1. First of all each time it generates different hash for the same setup password. Is that normal?

    2. I created a setup password and updated config. Afterwards I used that password to create “Super Admins”. I continued with the steps and finished almost completely. But now when I try to login into the postfix-admin, it does not accept the password. I checked the database and I can see all admin logins in the admin table with a password hash. It almost looks like the mechanism that is used to create the password hash while creating the admin user is different from that being used while authenticating. Where should I look to get some solution? Any help would be much appreciated.

  36. I figured out the error. PHP was unable to maintain the session. I made all files writeable (for everybody) and that fixed the issue. On a real installation I would use appropriate user and minimal rights.

  37. Alex says:

    Thanks for nice write up !

    One suggestion:

    You really want to change in /etc/dovecot/conf.d/10-mail.conf:

    mail_location = maildir:/home/vmail/%d/%n:INDEX=/home/vmail/%d/%n/indexes
    to
    mail_location = maildir:/home/vmail/%Ld/%Ln:INDEX=/home/vmail/%Ld/%Ln/indexes

    otherwise if someone will send you email with mixed case such as AbCdE@ExAmPle.com then dovecot will create a NEW directories for the same user.

  38. Omur says:

    Really nice guide, thank you. After failing to configure a fully working email server so many times, with this guide finally I have a mail server… There are few problems but nothing important (probably some software versions changed since this guide is written, clamav is giving permission denied but I’ve found a workaround)

    • Jake Turner says:

      Hey Omur,
      What was your workaround for the permission denied error? I’m currently getting:
      “Jun 7 22:06:51 mail postfix/smtpd[16043]: warning: connect to Milter service unix:/clamav/clamav-milter.ctl: Permission denied”
      Jake

  39. Kurt says:

    Thanks to Teast and Alex for the two tips. They were helpful.

    I don’t know what changed, but in Debian 7.8 I was not able to get incoming mail to work at all. It would fail with “access denied” error every time. I finally upgaded to Postfix 2.11 from Debian backports and was able to successfully get things working.

    The sort of “diff” style tutorial saves a lot of space by not showing complete configuration files, but it does make things more difficult at times. Especially when trying to determine if problems are due to configurations changing in Debian between the time this was posted and the time people implement it. It would be helpful to have links to full config files to refer to in such cases.

    I would also recommend never, ever, ever, EVER exposing postfixadmin, phpmyadmin, or anything of the sort to the outside world, even in obfuscated folders. If you make the mistake of trying the url on an unencrypted connection even once (type http instead of https) and thus expose the folder name unencrypted, you will then be the object of password attacks forever. Much safer is to configure your web server to forbid access to the directories to all except localhost, and tunnel your connection through ssh. Security through obscurity is never a good idea.

  40. Ivan Trofimov says:

    When i try to restart php5-fpm on Step 3, I get this problem:
    [FAIL] Restarting PHP5 FastCGI Process Manager: php5-fpm failed!

    /var/log/php5-fpm.log:
    [10-May-2015 01:08:27] ERROR: [pool ssl_mail.trofimov.me] cannot get gid for group ‘g1001’
    [10-May-2015 01:08:27] ERROR: FPM initialization failed

    But user and group for this virtualhost was created correctly. What is the problem?

    • pooria says:

      is it necessary in /etc/dovecot/dovecot.conf to uncomment the porotocols to tel the dovecot what protocol is in use ?


      #protocols = imap pop3 lmtp

  41. shukaze says:

    I cannot login into roundcube, I thought creating mailboxes in postfixadmin would create accounts for roundcube? Am I missing something?

  42. Krokosh Nikita says:

    Hello, I get Http 200 blank pages visiting /pma and /pfa, nginx access log says:

    192.168.0.160 – – [22/Jan/2016:11:56:51 +1000] “GET /pma/ HTTP/1.1” 200 31 “-” “Mozilla/5.0 (Windows NT 5.1; rv:43.0) Gecko/20100101 Firefox/43.0”
    192.168.0.160 – – [22/Jan/2016:11:56:58 +1000] “GET /pfa HTTP/1.1” 301 184 “-” “Mozilla/5.0 (Windows NT 5.1; rv:43.0) Gecko/20100101 Firefox/43.0”
    192.168.0.160 – – [22/Jan/2016:11:56:58 +1000] “GET /pfa/ HTTP/1.1” 200 31 “-” “Mozilla/5.0 (Windows NT 5.1; rv:43.0) Gecko/20100101 Firefox/43.0”

    Here’s the list of www directory:

    drwxr-xr-x 17 u1001 g1001 4096 Jan 22 11:00 pfa
    -rw-r–r– 1 u1001 g1001 1269907 Sep 27 01:26 pfa.tar.gz
    drwxr-xr-x 10 u1001 g1001 4096 Dec 26 06:08 pma
    -rw-r–r– 1 u1001 g1001 5583242 Dec 26 06:13 pma.tar.gz

    Can you tell me what am I doing wrong?

      • BENJA says:

        I have somme error:

        Jun 9 16:48:31 test dovecot: pop3-login: Fatal: Couldn’t parse private ssl_key: error:0906D06C:PEM routines:PEM_read_bio:no start line: Expecting: ANY PRIVATE KEY
        Jun 9 16:48:31 test dovecot: master: Error: service(pop3-login): command startup failed, throttling for 2 secs
        Jun 9 16:48:31 test postfix/smtpd[1496]: connect from unknown[192.168.1.3]
        Jun 9 16:48:31 test postfix/smtpd[1496]: warning: connect to Milter service unix:/milter-greylist/milter-greylist.sock: No such file or directory
        Jun 9 16:48:31 test spamass-milter[598]: Could not retrieve sendmail macro “i”!. Please add it to confMILTER_MACROS_ENVFROM for better spamassassin results
        Jun 9 16:48:31 test postfix/smtpd[1496]: NOQUEUE: reject: RCPT from unknown[192.168.1.3]: 504 5.5.2 : Helo command rejected: need fully-qualified hostname; from= to= proto=ESMTP helo=
        Jun 9 16:48:31 test postfix/smtpd[1496]: lost connection after RCPT from unknown[192.168.1.3]
        Jun 9 16:48:31 test postfix/smtpd[1496]: disconnect from unknown[192.168.1.3]

  43. Thanks alot man.
    it was great.

    I installed this mail service on debian 7 and its working fine.
    Notice: I had to disable + remove the “sendmail” from debian 7, and reboot it once.
    after that the postfix started, and working well.

Leave a Reply to Mike Cancel reply

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

You must enable javascript to see captcha here!