Mail Server Setup

This is how I set up my mail server on

  • Ubuntu 12.04 Precise Pangolin
  • Dovecot 2.0.19
  • Postfix 2.9.6
  • Postfix Admin 2.3.6
  • Squirrel Mail 1.4.22
  • MySQL 5.5.34
  • PHP 5.3.10

Supporting Packages to Install

  • postfix-mysql
  • dovecot-core
  • dovecot-postfix
  • dovecot-mysql
  • dovecot-imapd
  • php5-mysql

Server configuration

vmail user configuration

uid=5000(vmail) gid=5000(vmail) groups=5000(vmail)

Postfix configuration

/etc/postfix/main.cf

main.cf
# See /usr/share/postfix/main.cf.dist for a commented, more complete version
 
 
# Debian specific:  Specifying a file name will cause the first
# line of that file to be used as the name.  The Debian default
# is /etc/mailname.
myorigin = /etc/mailname
 
smtpd_banner = $myhostname ESMTP $mail_name (Ubuntu)
biff = no
 
# appending .domain is the MUA's job.
append_dot_mydomain = no
 
# Uncomment the next line to generate "delayed mail" warnings
delay_warning_time = 4h
 
readme_directory = no
 
# TLS parameters
smtpd_tls_cert_file = /etc/ssl/certs/ssl-mail.pem
smtpd_tls_key_file = /etc/ssl/private/ssl-mail.key
smtpd_tls_loglevel = 1
smtpd_tls_security_level = may
smtpd_tls_session_cache_database = btree:${data_directory}/smtpd_scache
smtp_tls_session_cache_database = btree:${data_directory}/smtp_scache
tls_random_source = dev:/dev/urandom
tls_random_bytes = 32
tls_random_reseed_period = 3600s
#
home_mailbox = Maildir/
smtpd_sasl_auth_enable = yes
smtpd_sasl_type = dovecot
smtpd_sasl_path = private/dovecot-auth
smtpd_sasl_authenticated_header = yes
smtpd_sasl_security_options = noanonymous
smtpd_sasl_local_domain = $myhostname
broken_sasl_auth_clients = yes
smtpd_use_tls = yes
smtpd_tls_received_header = yes
smtpd_tls_mandatory_protocols = SSLv3, TLSv1
smtpd_tls_mandatory_ciphers = medium
#smtpd_tls_auth_only = yes
#
smtp_tls_cert_file=/etc/postfix/ssl/smtpd.pem
smtp_tls_key_file=$smtp_tls_cert_file
smtp_tls_loglevel = 1
smtp_tls_security_level = may
smtp_tls_note_starttls_offer = yes
smtp_use_tls = yes
#
 
# See /usr/share/doc/postfix/TLS_README.gz in the postfix-doc package for
# information on enabling SSL in the smtp client.
 
myhostname = example.org
alias_maps = hash:/etc/aliases
alias_database = hash:/etc/aliases
myorigin = /etc/mailname
#mydestination = example.org, www.example.org, example.cc, www.example.cc, myserverhostname, localhost.localdomain, localhost
mydestination =
relayhost = smtp-server.example.com
# This was commented out as it gives a "unused parameter" warning on Precise - works on Hardy
#relay_domain = $mydestination
mynetworks_style = subnet
#mynetworks = 127.0.0.0/8 [::ffff:127.0.0.0]/104 [::1]/128
mailbox_command = /usr/lib/dovecot/deliver -c /etc/dovecot/conf.d/01-mail-stack-delivery.conf -m "${EXTENSION}"
mailbox_size_limit = 0
recipient_delimiter = +
inet_interfaces = all
owner_request_special = no
message_size_limit = 32768000
#
# Virtual Mailbox Domain Settings
virtual_alias_maps = mysql:/etc/postfix/mysql/alias_maps.cf, mysql:/etc/postfix/mysql/alias_alias_maps.cf
virtual_mailbox_domains = mysql:/etc/postfix/mysql/domains_maps.cf
virtual_mailbox_maps = mysql:/etc/postfix/mysql/mailbox_maps.cf, mysql:/etc/postfix/mysql/mailbox_alias_maps.cf
virtual_mailbox_limit = 51200000
virtual_minimum_uid = 5000
virtual_uid_maps = static:5000
virtual_gid_maps = static:5000
virtual_mailbox_base = /home/vmail
virtual_transport = virtual
# Additional for quota support
# This was commented out as it gives a "unused parameter" warning on Precise - works on Hardy
#virtual_create_maildirsize = yes
#virtual_mailbox_extended = yes
#virtual_mailbox_limit_maps = mysql:/etc/postfix/mysql/mailbox_limit_maps.cf
#virtual_mailbox_limit_override = yes
#virtual_maildir_limit_message = Sorry, the your maildir has overdrawn your diskspace quota, please free up some of spaces of your mailbox try again.
#virtual_overquota_bounce = yes
#
# Spam reduction parameters. May be aggresive for some, but seems to work well.
access_map_reject_code = 554
invalid_hostname_reject_code = 554
maps_rbl_reject_code = 554
multi_recipient_bounce_reject_code = 554
non_fqdn_reject_code = 554
plaintext_reject_code = 554
reject_code = 554
relay_domains_reject_code = 554
unknown_local_recipient_reject_code = 550
unknown_address_reject_code = 550
unknown_client_reject_code = 550
unknown_hostname_reject_code = 550
unknown_relay_recipient_reject_code = 550
unknown_virtual_alias_reject_code = 550
unknown_virtual_mailbox_reject_code = 550
unverified_recipient_reject_code = 550
unverified_sender_reject_code = 550
#
default_process_limit = 20
smtpd_client_connection_count_limit = 10
# Value of 60 should translate to 1 per second limit
smtpd_client_connection_rate_limit = 60
smtpd_client_message_rate_limit = 60
smtpd_client_new_tls_session_rate_limit = 60
#
smtpd_helo_required = yes
smtpd_delay_reject = yes
address_verify_map = btree:${data_directory}/verify_cache
smtpd_reject_unlisted_sender=yes
#
smtpd_recipient_restrictions =
    check_client_access hash:/etc/postfix/white_lists,
    permit_sasl_authenticated,
    permit_mynetworks,
#   permit_tls_clientcerts,
    reject_invalid_hostname,
    reject_non_fqdn_hostname,
    reject_non_fqdn_sender,
    reject_non_fqdn_recipient,
    reject_unknown_sender_domain,
    reject_unknown_recipient_domain,
    reject_unverified_sender,
    reject_unauth_destination,
    reject_rbl_client zen.spamhaus.org,
    reject_rbl_client cbl.abuseat.org,
    permit
smtpd_data_restrictions =
    permit_sasl_authenticated,
    permit_mynetworks,
    reject_unauth_pipelining,
    permit
# Added for trying to send email from PDA
smtpd_client_restrictions =
    permit_sasl_authenticated
smtpd_helo_restrictions = permit_mynetworks,
    permit_sasl_authenticated,
    reject_non_fqdn_hostname,
    reject_invalid_hostname,
    permit
#

/etc/postfix/mailname

mailname
example.org

Client TLS Support

Follow this for Postfix Client TLS Support setup

Postfix MySql (maps) configuration

  • Create directory /etc/postfix/mysql
  • Please the following files under /etc/postfix/mysql
mysql_uid.cf
user=<mysql_db_user>
password=<mysql_db_password>
dbname=<mysql_db_name>
table=mailbox
select_field=username
where_field=username
hosts=127.0.0.1:<mysql_db_port>
mysql_gid.cf
user=<mysql_db_user>
password=<mysql_db_password>
dbname=<mysql_db_name>
table=mailbox
select_field=username
where_field=username
hosts=127.0.0.1:<mysql_db_port>
mailbox_maps.cf
user=<mysql_db_user>
password=<mysql_db_password>
dbname=<mysql_db_name>
table=mailbox
select_field=maildir
where_field=username
hosts=127.0.0.1:<mysql_db_port>
additional_conditions = and active = 1
mailbox_limit_maps.cf
user=<mysql_db_user>
password=<mysql_db_password>
dbname=<mysql_db_name>
table=mailbox
select_field=quota
where_field=username
hosts=127.0.0.1:<mysql_db_port>
additional_conditions = and active = 1
alias_maps.cf
user=<mysql_db_user>
password=<mysql_db_password>
dbname=<mysql_db_name>
table=alias
select_field=goto
where_field=address
hosts=127.0.0.1:<mysql_db_port>
additional_conditions = and active = 1
domains_maps.cf
user=<mysql_db_user>
password=<mysql_db_password>
dbname=<mysql_db_name>
table=domain
select_field=domain
where_field=domain
hosts=127.0.0.1:<mysql_db_port>
additional_conditions = and backupmx = 0 and active = 1
relay_domains.cf
user=<mysql_db_user>
password=<mysql_db_password>
dbname=<mysql_db_name>
table=domain
select_field=domain
where_field=domain
hosts=127.0.0.1:<mysql_db_port>
additional_conditions = and active = 1 and backupmx = 1

The below two settings (alias_alias_maps.cf & mailbox_alias_maps.cf) are for alias domains:

alias_alias_maps.cf
user=<mysql_db_user>
password=<mysql_db_password>
dbname=<mysql_db_name>
hosts=127.0.0.1:<mysql_db_port>
query = SELECT goto FROM alias,alias_domain
  WHERE alias_domain.alias_domain = '%d'
  AND alias.address=concat('%u', '@', alias_domain.target_domain)
  AND alias.active = 1 AND alias_domain.active = 1
mailbox_alias_maps.cf
user=<mysql_db_user>
password=<mysql_db_password>
dbname=<mysql_db_name>
hosts=127.0.0.1:<mysql_db_port>
query = SELECT maildir FROM mailbox, alias_domain
  WHERE alias_domain.alias_domain = '%d'
  AND mailbox.username=concat('%u', '@', alias_domain.target_domain )
  AND mailbox.active = 1 AND alias_domain.active = 1

Dovecot Configuration

Change the following files at /etc/dovecot & /etc/dovecot/conf.d

The files in /etc/dovecot need NO changes from default

  • dovecot.conf
  • dovecot-db.conf.ext
  • dovecot-dict-sql.conf.ext
  • dovecot-sql.conf.ext

File(s) requiring change

dovecot-sql.conf.ext
driver = mysql
connect = host=127.0.0.1 port=3306 user=root password=rootpassword dbname=postfixadmindbname
default_pass_scheme = CRAM-MD5
user_query = \
 SELECT \
        concat('/home/vmail/', maildir) as home, \
        5000 as uid, 5000 as gid \
        FROM mailbox \
        WHERE username = '%u' AND active = '1'
password_query = \
 SELECT username as user, password, \
        concat('/home/vmail/', maildir) as userdb_home, \
        concat('maildir:/home/vmail/', maildir) as userdb_mail, \
        5000 as userdb_uid, 5000 as userdb_gid \
        FROM mailbox \
        WHERE username = '%u' AND active = '1'

The following files in /etc/dovecot/conf.d do NOT require change as well

  • 01-mail-stack-delivery.conf
  • 10-director.conf
  • 10-master.conf
  • 10-ssl.conf
  • 15-lda.conf
  • 20-imap.conf
  • 20-managesieve.conf
  • 20-pop3.conf
  • 90-acl.conf
  • 90-plugin.conf
  • 90-quota.conf
  • 90-sieve.conf
  • auth-deny.conf.ext
  • auth-master.conf.ext
  • auth-passwdfile.conf.ext
  • auth-static.conf.ext
  • auth-vpopmail.conf.ext

File(s) requiring change

10-logging.conf
auth_verbose = yes
auth_debug = yes
plugin {
  # Events to log. Also available: flag_change append
  #mail_log_events = delete undelete expunge copy mailbox_delete mailbox_rename
  # Available fields: uid, box, msgid, from, subject, size, vsize, flags
  # size and vsize are available only for expunge and copy events.
  #mail_log_fields = uid box msgid size
}
10-auth.conf
auth_mechanisms = plain cram-md5
!include auth-system.conf.ext
auth-system.conf.ext
passdb {
  driver = sql
  args = /etc/dovecot/dovecot-sql.conf.ext
  # [session=yes] [setcred=yes] [failure_show_msg=yes] [max_requests=<n>]
  # [cache_key=<key>] [<service name>]
  #args = dovecot
}
userdb {
  # <doc/wiki/AuthDatabase.Passwd.txt>
  driver = sql
  args = /etc/dovecot/dovecot-sql.conf.ext
  # [blocking=no]
  #args =
}
10-mail.conf
mail_location = maildir:/home/vmail/%d/%u
mail_uid = vmail
mail_gid = vmail
maildir_copy_with_hardlinks = yes

Postfix Admin

All changes from the default go in config.local.php

config.local.php
$CONF['postfix_admin_url'] = 'http://pfa.example.org';
 
$CONF['domain_path'] = 'YES';
 
$CONF['database_type'] = 'mysql';
$CONF['database_host'] = 'localhost';
$CONF['database_user'] = 'upostfixadmin';
$CONF['database_password'] = 'somepassword';
$CONF['database_name'] = 'postfixadmin';
 
$CONF['admin_email'] = 'postmaster@example.com';
 
$CONF['smtp_server'] = 'smtp-server.example.com';
 
$CONF['encrypt'] = 'dovecot:CRAM-MD5';
 
$CONF['dovecotpw'] = "/usr/bin/doveadm pw";
 
$CONF['page_size'] = '100';
 
$CONF['default_aliases'] = array (
    'abuse' => 'abuse@example.com',
    'hostmaster' => 'hostmaster@example.com',
    'postmaster' => 'postmaster@example.com',
    'webmaster' => 'webmaster@example.com'
);
 
$CONF['aliases'] = '10000';
$CONF['mailboxes'] = '10000';
$CONF['maxquota'] = '10000';
 
$CONF['transport'] = 'YES';
 
$CONF['vacation_domain'] = 'autoreply.example.com';
 
$CONF['user_footer_link'] = "http://example.com/";
$CONF['footer_text'] = 'Return to example.com'; 
$CONF['footer_link'] = 'http://example.com';
 
$CONF['create_mailbox_subdirs_prefix']='';
$CONF['new_quota_table'] = 'YES';

Migration from Courier to Postfix

If you are moving to a new machine make sure that you tar and untar files to preserver permissions and most importantly timestamps. Or all your old mail will have the same date/time!

Resource

Command

/home/vmail/courier-dovecot-migrate.pl --to-dovecot --recursive --convert --overwrite /home/vmail/example.org/

Sample output:

Converting to Dovecot format
Finding maildirs under /home/vmail/example.org/

Total: 70 mailboxes / 38 users
       0 errors
46 dovecot-uidlist files written

WARNING: Badly done migration will cause your IMAP and/or POP3 clients to re-download all mails. Read http://wiki.dovecot.org/Migration carefully.

Folder between courier and dovecot

One way to get the courier subfolders to show up in dovecot is to add this to the configuration:

10-mail.conf
namespace private {
  prefix = INBOX.
  separator = .
  inbox = yes
}

Alternatively, I created the subfolders (from squirrel mail) and then delete the newly created folders from the Linux file folders and renamed the existing file folders to the name I just deleted. So here goes for example:

mv .INBOX.SomeSubFolder/ junk
mv .SomeSubFolder .INBOX.SomeSubFolder

Here I moved the newly created folder to a “junk” location (an alternative to just deleting it). Then renamed the original folder to the new folder name.

Squirrel Mail configuration

Follow this link.

Some dovecot commands

dovecot --build-options
find /usr/lib/dovecot/modules/
doveconf -a

Post Configuration Steps

white_lists file

To avoid error that there is no white list file

cd /etc/postfix
touch white_lists
postmap white_lists

Restart

service postfix restart
service dovecot restart

Related

Discussion

Daniel R, 2013/03/17 08:16

You have MySQL instructions, yet do not have a Postfix MySQL Maps Section, just wondering how you did it? So far your HowTo is the best out there as it describes where to put entries in each file.

Senthil Nathan, 2013/03/17 15:58

Thanks Daniel for pointing it out. I have included the MySQL configuration as well now. I am glad it is helping folks as it did take me a bit to get all this together.

Smithb907, 2014/04/23 06:54

Nice read, I just passed this onto a friend who was doing some research on that. And he just bought me lunch since I found it for him smile So let me rephrase that Thank you for lunch! Whenever you have an efficient government you have a dictatorship. by Harry S Truman. gcckeffeddgdffck

Enter your comment
IYUTH
 
 
tech/linux/mail_server_setup.txt · Last modified: 2013/12/03 07:54 (external edit)
 
Recent changes RSS feed Donate Powered by PHP Valid XHTML 1.0 Valid CSS Driven by DokuWiki Sitemap