Setting Postfix isn’t especially hard, but for sure is tedious. To make this process less inconvinient, I created a simple shell script for Debian 7
that takes care of basic system configuration. After some minor changes it should be usable for other Linux distributions.
That configuration supports most secure solutions: SMTPS
with STARTTLS
on port 587
and SSL
secured IMAP
on port 993
. I also decided to use PostgreSQL
instead of MySQL which is used in most configurations you can find on the Internet. So this is virtual mail system
based on Dovecot
, managed by Postfix Admin
, with web frontend Roundcube
.
Complete script is available here: gitsts.github.com.
To start it, follow these steps:
wget https://gist.githubusercontent.com/solusipse/7ed8e1da104baaee3f05/raw/dd11da572636fb239a4f786c3182d614880f605e/02_postfix.sh
chmod a+x 02_postfix.sh
./02_postfix.sh
It was tested on fresh install of Debian 7 on Digital Ocean. Here, I’ll explain what it does.
Adding user (and its group) for handling mails.
For security reasons, emails will be stored in vmail
user’s home directory:
groupadd -g 5000 vmail
useradd -u 5000 -g vmail -s /usr/bin/nologin -d /home/vmail -m vmail
Installing software
These are all you’ll need during whole process:
apt-get install postfix dovecot-core dovecot-imapd postgresql postfix-pgsql dovecot-lmtpd dovecot-pgsql php5-fpm php5-imap php5-pgsql
Preparing database
This part of the script is used for creating user for virtual mail system:
:::bash
DBPASS=$(date | md5sum | head -c 32)
CREATEUSER="CREATE USER postfix_user WITH PASSWORD '${DBPASS}';"
CREATEDB="CREATE DATABASE postfix_db;"
PERMISSDB="GRANT ALL PRIVILEGES ON DATABASE postfix_db TO postfix_user;"
sudo -u postgres psql -c "${CREATEUSER}"
sudo -u postgres psql -c "${CREATEDB}"
sudo -u postgres psql -c "${PERMISSDB}"
Note that ${DBPASS}
will be used later in some configuration files.
Creating config files
Many of these contains ${DBPASS}
variable. If you set your password manually, remember to replace ${DBPASS}
with it.
/etc/postfix/main.cf
relay_domains =
virtual_alias_maps = proxy:pgsql:/etc/postfix/virtual_alias_maps.cf
virtual_mailbox_domains = proxy:pgsql:/etc/postfix/virtual_mailbox_domains.cf
virtual_mailbox_maps = proxy:pgsql:/etc/postfix/virtual_mailbox_maps.cf
virtual_mailbox_base = /home/vmail
virtual_mailbox_limit = 512000000
virtual_minimum_uid = 5000
virtual_transport = virtual
virtual_uid_maps = static:5000
virtual_gid_maps = static:5000
local_transport = virtual
local_recipient_maps = $virtual_mailbox_maps
transport_maps = hash:/etc/postfix/transport
smtpd_sasl_auth_enable = yes
smtpd_sasl_type = dovecot
smtpd_sasl_path = private/auth
smtpd_recipient_restrictions = permit_mynetworks, permit_sasl_authenticated, reject_unauth_destination
smtpd_sasl_security_options = noanonymous
smtpd_sasl_tls_security_options = $smtpd_sasl_security_options
smtpd_tls_auth_only = yes
smtpd_tls_cert_file = /etc/ssl/private/server.crt
smtpd_tls_key_file = /etc/ssl/private/server.key
smtpd_sasl_local_domain = $mydomain
broken_sasl_auth_clients = yes
smtpd_tls_loglevel = 1
html_directory = /usr/share/doc/postfix/html
queue_directory = /var/spool/postfix
mydestination = localhost
/etc/postfix/master.cf
smtp inet n - - - - smtpd
submission inet n - - - - smtpd
-o smtpd_tls_security_level=encrypt
-o smtpd_sasl_auth_enable=yes
smtps inet n - - - - smtpd
-o smtpd_tls_wrappermode=yes
-o smtpd_sasl_auth_enable=yes
pickup fifo n - - 60 1 pickup
cleanup unix n - - - 0 cleanup
qmgr fifo n - n 300 1 qmgr
#qmgr fifo n - n 300 1 oqmgr
tlsmgr unix - - - 1000? 1 tlsmgr
rewrite unix - - - - - trivial-rewrite
bounce unix - - - - 0 bounce
defer unix - - - - 0 bounce
trace unix - - - - 0 bounce
verify unix - - - - 1 verify
flush unix n - - 1000? 0 flush
proxymap unix - - n - - proxymap
proxywrite unix - - n - 1 proxymap
smtp unix - - - - - smtp
relay unix - - - - - smtp
showq unix n - - - - showq
error unix - - - - - error
retry unix - - - - - error
discard unix - - - - - discard
local unix - n n - - local
virtual unix - n n - - virtual
lmtp unix - - - - - lmtp
anvil unix - - - - 1 anvil
scache unix - - - - 1 scache
maildrop unix - n n - - pipe
flags=DRhu user=vmail argv=/usr/bin/maildrop -d ${recipient}
uucp unix - n n - - pipe
flags=Fqhu user=uucp argv=uux -r -n -z -a$sender - $nexthop!rmail ($recipient)
ifmail unix - n n - - pipe
flags=F user=ftn argv=/usr/lib/ifmail/ifmail -r $nexthop ($recipient)
bsmtp unix - n n - - pipe
flags=Fq. user=bsmtp argv=/usr/lib/bsmtp/bsmtp -t$nexthop -f$sender $recipient
scalemail-backend unix - n n - 2 pipe
flags=R user=scalemail argv=/usr/lib/scalemail/bin/scalemail-store ${nexthop} ${user} ${extension}
mailman unix - n n - - pipe
flags=FR user=list argv=/usr/lib/mailman/bin/postfix-to-mailman.py
${nexthop} ${user}
cleanup unix n - - - 0 cleanup
subcleanup unix n - - - 0 cleanup
-o header_checks=regexp:/etc/postfix/submission_header_checks
/etc/postfix/submission_header_checks
/^Received:/ IGNORE
/^User-Agent:/ IGNORE" > /etc/postfix/submission_header_checks
/etc/postfix/virtual_alias_maps.cf
user = postfix_user
password = ${DBPASS}
hosts = localhost
dbname = postfix_db
query = SELECT goto FROM alias WHERE address='%s' AND active = true
/etc/postfix/virtual_mailbox_domains.cf
user = postfix_user
password = ${DBPASS}
hosts = localhost
dbname = postfix_db
query = SELECT domain FROM domain WHERE domain='%s' AND backupmx = false AND active = true
/etc/postfix/virtual_mailbox_maps.cf
user = postfix_user
password = ${DBPASS}
hosts = localhost
dbname = postfix_db
query = SELECT maildir FROM mailbox WHERE username='%s' AND active = true
/etc/dovecot/dovecot.conf
protocols = imap
auth_mechanisms = plain
passdb {
driver = sql
args = /etc/dovecot/dovecot-sql.conf
}
userdb {
driver = sql
args = /etc/dovecot/dovecot-sql.conf
}
service auth {
unix_listener /var/spool/postfix/private/auth {
group = postfix
mode = 0660
user = postfix
}
user = root
}
mail_home = /home/vmail/%d/%u
mail_location = maildir:~
ssl_cert = </etc/ssl/private/server.crt
ssl_key = </etc/ssl/private/server.key
/etc/dovecot/dovecot-sql.conf
driver = pgsql
connect = host=localhost dbname=postfix_db user=postfix_user password=${DBPASS}
default_pass_scheme = MD5-CRYPT
user_query = SELECT '/home/vmail/%d/%u' as home, 'maildir:/home/vmail/%d/%u' as mail, 5000 AS uid, 5000 AS gid, concat('dirsize:storage=', quota) AS quota FROM mailbox WHERE username = '%u' AND active = '1'
password_query = SELECT username as user, password, '/home/vmail/%d/%u' as userdb_home, 'maildir:/home/vmail/%d/%u' as userdb_mail, 5000 as userdb_uid, 5000 as userdb_gid FROM mailbox WHERE username = '%u' AND active = '1'
Create certificate
cd /etc/ssl/private/
openssl genpkey -algorithm RSA -pkeyopt rsa_keygen_bits:2048 -out server.key
chmod 400 server.key
openssl req -new -key server.key -out server.csr
openssl x509 -req -days 365 -in server.csr -signkey server.key -out server.crt
chmod 444 server.crt
Creating postmap, starting services
Let’s create postmap:
touch /etc/postfix/transport
postmap /etc/postfix/transport
Make sure that all services we’ll need are running:
/etc/init.d/postfix restart
/etc/init.d/dovecot restart
/etc/init.d/php5-fpm restart
Postfix Admin
To complete this setup, you need working webserver with php support. I used nginx
. After you’ll configure it, download Postfix Admin
:
wget -O postfixadmin.tar.gz http://sourceforge.net/projects/postfixadmin/files/latest/download
Unpack it to location that is served by webserver. Now you need to modify config.inc.php
to match your settings. Change tese values:
:::php
$CONF['configured'] = true;
$CONF['domain_path'] = 'YES';
$CONF['domain_in_mailbox'] = 'YES';
$CONF['database_type'] = 'pgsql';
$CONF['database_host'] = 'localhost';
$CONF['database_user'] = 'postfix_user';
$CONF['database_password'] = 'PASSWORD FROM INSTALLER SCRIPT';
$CONF['database_name'] = 'postfix_db';
Then, follow installer’s instructions. After creating admin account, you’ll need to create at least one domain and one user.
Roundcube
Now you’re ready to download and install Roundcube
. It’s quite easy, so i won’t describe the whole process. Just remember to create an user and database for it:
:::sql
su postgres
psql
postgres=# CREATE USER roundcube WITH PASSWORD 'PASSWORD FROM INSTALLER SCRIPT';
postgres=# CREATE DATABASE roundcubemail;
postgres=# GRANT ALL PRIVILEGES ON DATABASE roundcubemail TO roundcube;
Now follow the installer’s instructions.
Your email server is now fully configured. Don’t forget to set things like iptables
.