Postfix HOWTO
This guide will help you install a complete mail server for the home, office and even an ISP. The guide follows a freshly installed Debian Sarge (currently testing) system, and uses Postfix, Courier IMAP, SASL, MySQL, Postfix admin, Squirrelmail and other nice software packages.
This HOWTO has probably been slightly outdated lately, since I have not had time to update it.
New HOWTO available: Mail server HOWTO – Postfix and Dovecot with MySQL and TLS/SSL, Postgrey and DSPAM
Prerequisites
Before getting started with the Postfix installation, the mysql server should be installed. We also need the mysql-client to populate the tables in the Postfix database:
# apt-get install mysql-server mysql-client
Note that the default MySQL installation in Debian does not have a password for the root user. Before continuing with this guide, set a root password! This is a far too easy thing to forget later on and it can have tremendous security implications.
Now it is time to download the Postfix admin software. It is a virtual user administraton system written in PHP for the Postfix SMTP server. Head over to a temporary directory and download the archive from their site. When wget is done, unpack the file and enter the directory. Now we want to populate our MySQL database with the schema provided by Postfix admin:
# wget “http://high5.net/postfixadmin/download.php?file=postfixadmin-2.1.0.tgz”
# tar xvfz postfixadmin-2.1.0.tgz
# cd postfixadmin-2.1.0
# mysql -uroot -p < DATABASE_MYSQL.TXT
Now over to the next section.
Postfix
The database part is finished for now, and the time has now come for the Postfix SMTP daemon to be installed. When debconf asks you which configuration to install, just choose “no configuration”, since we will do everything by hand:
# apt-get install postfix postfix-tls postfix-mysql
The first thing to do is figuring out where you want the virtual home directory located. Good places for this could be /home/virtual, /var/mail/virtual, /var/spool/postfix/virtual and so on. In this guide I will use /home/virtual as a base for virtual users. We need to let Postfix be the owner of this directory, so do the following:
# cd /home
# mkdir virtual
# chown -R postfix:postfix virtual
# chmod -R 771 virtual
Let’s get cracking on the Postfix configuration now shall we. We need to add lots of configuration options to several files in the /etc/postfix directory.
/etc/postfix/main.cf:
# Set your hostname
myhostname = mail.example.com
mynetworks = 127.0.0.0/8
smtpd_banner = $myhostname ESMTP ready
# If you need to relay outgoing mail via your ISP, set it here
#relayhost = smtprelay.example.com
virtual_alias_maps = mysql:/etc/postfix/mysql_virtual_alias_maps.cf
# Make sure that the following number is the GID for the postfix user
virtual_gid_maps = static:102
virtual_mailbox_base = /home/virtual
virtual_mailbox_domains = mysql:/etc/postfix/mysql_virtual_domains_maps.cf
virtual_mailbox_limit = 512000000
virtual_mailbox_maps = mysql:/etc/postfix/mysql_virtual_mailbox_maps.cf
virtual_minimum_uid = 100
virtual_transport = virtual
# Make sure that the following number is the UID for the postfix user
virtual_uid_maps = static:102
virtual_create_maildirsize = yes
virtual_mailbox_extended = yes
virtual_mailbox_limit_maps =
mysql:/etc/postfix/mysql_virtual_mailbox_limit_maps.cf
virtual_mailbox_limit_override = yes
virtual_maildir_limit_message = Sorry, the user’s maildir has overdrawn his
diskspace quota, please try again later.
virtual_overquota_bounce = yes
relay_domains = proxy:mysql:/etc/postfix/mysql_relay_domains_maps.cf
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,
reject_rbl_client opm.blitzed.org,
reject_rbl_client list.dsbl.org,
reject_rbl_client bl.spamcop.net,
reject_rbl_client sbl-xbl.spamhaus.org,
permit
smtpd_sasl_auth_enable = yes
smtpd_sasl_local_domain = $myhostname
smtpd_sasl_security_options = noanonymous
smtpd_tls_cert_file = /etc/postfix/sasl/smtpd.cert
smtpd_tls_key_file = /etc/postfix/sasl/smtpd.key
tls_random_source = dev:/dev/urandom
tls_daemon_random_source = dev:/dev/urandom
smtpd_use_tls = yes
broken_sasl_auth_clients = yes
#content_filter=smtp-amavis:[127.0.0.1]:10024
max_use = 10
/etc/postfix/mysql_virtual_alias_maps.cf:
user = postfix
password = postfix
hosts = localhost
dbname = postfix
table = alias
select_field = goto
where_field = address
/etc/postfix/mysql_virtual_domains_maps.cf:
user = postfix
password = postfix
hosts = localhost
dbname = postfix
table = domain
select_field = description
where_field = domain
#additional_conditions = and backupmx = ’0′ and active = ’1′
/etc/postfix/mysql_virtual_mailbox_maps.cf:
user = postfix
password = postfix
hosts = localhost
dbname = postfix
table = mailbox
select_field = maildir
where_field = username
#additional_conditions = and active = ’1′
/etc/postfix/mysql_virtual_mailbox_limit_maps.cf:
user = postfix
password = postfix
hosts = localhost
dbname = postfix
table = mailbox
select_field = quota
where_field = username
#additional_conditions = and active = ’1′
/etc/postfix/mysql_relay_domains_maps.cf:
user = postfix
password = postfix
hosts = localhost
dbname = postfix
table = domain
select_field = domain
where_field = domain
additional_conditions = and backupmx = ’1′
Now over to the next section.
SASL2
For the SMTP authentication to work, the configuration file for SASL2 must be added. Here you can change everything about how the Postfix server behave in the authentication procedure. First you need to install the Sasl2 application:
# apt-get install sasl2-bin libsasl2 libsasl2-modules libsasl2-modules-sql
/etc/postfix/sasl/smtpd.conf:
pwcheck_method: auxprop
auxprop_plugin: sql
sql_engine: mysql
mech_list: LOGIN
sql_hostnames: localhost
sql_user: postfix
sql_passwd: postfix
sql_database: postfix
sql_select: SELECT password FROM mailbox WHERE username = ‘%u@%r’
Create the certificates for the Postfix server. Just make sure that the Common Name equals the mail server hostname:
# openssl genrsa -out server.key 1024
# openssl req -new -key server.key -x509 -out server.cert
Now over to the next section.
Courier IMAP
The Courier IMAP daemon needs to be told that it should use the postfix database for authentication. Note that there must not be ANY spaces in authmysqlrc, only tabs! Also, make sure that the UID and GID fields are according to the postfix user.
Begin by installing the IMAP server:
# apt-get install courier-imap-ssl
/etc/courier/authmysqlrc:
#DEFAULT_DOMAIN example.net
MYSQL_CRYPT_PWFIELD password
MYSQL_DATABASE postfix
MYSQL_GID_FIELD 102
MYSQL_HOME_FIELD ‘/home/virtual’
MYSQL_LOGIN_FIELD username
MYSQL_MAILDIR_FIELD maildir
MYSQL_NAME_FIELD name
MYSQL_OPT 0
MYSQL_PASSWORD postfix
#MYSQL_PORT 0
MYSQL_QUOTA_FIELD quota
MYSQL_SERVER localhost
MYSQL_SOCKET /var/run/mysqld/mysqld.sock
MYSQL_UID_FIELD 102
MYSQL_USERNAME postfix
MYSQL_USER_TABLE mailbox
#MYSQL_WHERE_CLAUSE server=’mailhost.example.com’
Now over to the next section.
Postfix admin
Copy the Postfix admin directory to a web directory and read the installation instructions. Now your server should be working, but for simple webmail access Squirrelmail is the way to go.
Squirrelmail
Download the latest version of Squirrelmail and unpack it to an SSL enabled webspace. Configure it to use localhost as SMTP and IMAP, and set the IMAP server to courier. Good plugins are the following. (TODO: Add links to plugins)
- address_add
- compatibility
- notes
- quicksave
- sent_confirmation
- check_quota
- gpg (development version)
- retrieveuserdata
- BayesSpam
Quota support
Note that this step is optional, but if you have lots of users, quota is necessary. Postfix in Debian doesn’t support virtual quouta out of the box. This isn’t a big deal. Just make sure that you have corresponding deb-src entries in your /etc/apt/sources.list file. Don’t forget to run apt-get update after to download the latest package information. To patch the Postfix source, do the following:
# apt-get source postfix
# apt-get build-dep postfix
# wget http://web.onda.com.br/nadal/postfix/VDA/postfix-2.1.5-trash.patch.gz
# zcat postfix-2.1.5-trash.patch.gz | patch -p0
# cd postfix-2.1.5
# dpkg-buildpackage -rfakeroot -uc -b
# cd ..
# dpkg –install postfix*.deb
The new Postfix packages should now be installed and the quota should now be working!
IMAP Proxy Daemon
Since Squirrelmail is stateless, it makes a new connection to the IMAP server every time it need some data. If you have lots of users accessing the IMAP server simultaneous, this can have a tremendous impact on performance. To remedy this proxy servers can be used. To install an IMAP proxy in Debian, do the following:
# apt-get install imapproxy
You will need to change the configuration somewhat, and file to edit is /etc/imapproxy.conf so open it up with your favourite editor and make it look like the following.
/etc/imapproxy.conf:
server_hostname localhost
cache_size 3072
listen_port 144
server_port 143
cache_expiration_time 900
proc_username nobody
proc_groupname nogroup
stat_filename /var/run/pimpstats
protocol_log_filename /var/log/imapproxy_protocol.log
syslog_facility LOG_MAIL
send_tcp_keepalives no
enable_select_cache no
foreground_mode no
Now start the daemon and change the IMAP server port in Squirrelmail to 144, and now your IMAP connections will be cached and will speed up Squirrelmail.
References
Virtual Users and Domains with Courier-IMAP and MySQL


sasl2-bin paketet behövs inte om man inte har planerat att köra saslauthd.
— Svenska
Jag fick inte SASL auth att fungera med Debians standardpaket eftersom SASL förväntar sig att lösenorden i databasen inte är krypterade. Jag var tvungen att patcha libsasl2 med “den här patchen”:http://www.viperstrike.com/~lopaka/sysadmin/cyrus-sasl-mysql-encrypt/software-sources/patch-linux.
Jag har kompilerat “färdiga Debian paket”:http://pelme.se/~andreas/sasl2-encrypted-passwords/ med patchen inkluderad .
— English
The sasl2-bin package is not required if you do not run saslauthd.
My SASL auth does not work with the default Debian package, because it does not expect the password to be encrypted in the database. I had to patch libsasl2 “with this patch”:http://www.viperstrike.com/~lopaka/sysadmin/cyrus-sasl-mysql-encrypt/software-sources/patch-linux.
I have “compiled Debian packages”:http://pelme.se/~andreas/sasl2-encrypted-passwords/ with this patch included.
I got SASL AUTH working with no patches and keeping chroot, by using saslauthd’s rimap mechanism, since the IMAP server has no problem with authentication. It’s a bit convoluted, especially if you insert imapproxy into things, but it works.
Hi,
I have followed your installation instructions, but I ran into some problems.
My Postfix installation with virtual users works fine and I can see that received mails are placed in the respective folders in my virtual folder.
Afterwards I installed courier-imap-ssl according to your instructions, but I keep on getting login errors (Unknown user or password incorrect), when I try to login either through squirrelmail or outlook.
When I try to login with my normal linux account name(just for a test), I get another error saying “connection dropped by imap-srver”.
Does anyone have an idea of what I did wrong?
Hi
I have solved the problem.
By comparing the installation instructions at http://workaround.org/articles/ispmail-sarge/ with yours, I found that I was missing the courier-authmysql debian package.
After the installation of this package, everything works perfect.
hi
dns2:~# openssl genrsa -out smtpd.key 1024
Generating RSA private key, 1024 bit long modulus
………++++++
……………………..++++++
e is 65537 (0×10001)
dns2:~# openssl req -new -key server.key -x509 -out server.cert
Error opening Private Key server.key
720:error:02001002:system library:fopen:No such file or directory:bss_file.c:278:fopen(‘server.key’,'r’)
720:error:20074002:BIO routines:FILE_CTRL:system lib:bss_file.c:280:
unable to load Private Key
why?
The keyfile specified in the second command is not accurate. (I will update the howto when I have time, thanks for noticing.)
Try this instead:
# openssl genrsa -out server.key 1024
# openssl req -new -key server.key -x509 -out server.cert
Hope it helps.
Hi, I have used this guide, and did excactly as it said.
Still I get these errors in my log,
and I can’t connect to the imap server, (using MS outlook) i get prompted for my username password which is my email address+passwd, what did i do wrong =?
output:
Mar 22 05:24:05 localhost postfix/smtpd[14502]: warning: dict_nis_init: NIS domain name not set – NIS lookups disabled
Mar 22 05:24:05 localhost postfix/smtpd[14502]: unable to get certificate from ‘/etc/postfix/sasl/smtpd.cert’
Mar 22 05:24:05 localhost postfix/smtpd[14502]: 14502:error:02001002:system library:fopen:No such file or directory:bss_file.c:278:fopen(‘/etc/postfix/sasl/smtpd.cert’,'r’):
Mar 22 05:24:05 localhost postfix/smtpd[14502]: 14502:error:20074002:BIO routines:FILE_CTRL:system lib:bss_file.c:280:
Mar 22 05:24:05 localhost postfix/smtpd[14502]: 14502:error:140DC002:SSL routines:SSL_CTX_use_certificate_chain_file:system lib:ssl_rsa.c:760:
Mar 22 05:24:05 localhost postfix/smtpd[14502]: TLS engine: cannot load RSA cert/key data
Mar 22 05:24:05 localhost postfix/smtpd[14502]: connect from fitch5.uni2.net[130.227.212.5]
Mar 22 05:24:05 localhost postfix/trivial-rewrite[14504]: warning: connect to mysql server localhost: Can’t connect to local MySQL server through socket ‘/var/run/mysqld/mysqld.sock’ (2)
Mar 22 05:24:05 localhost postfix/trivial-rewrite[14504]: fatal: mysql:/etc/postfix/mysql_virtual_alias_maps.cf(0,100): table lookup problem
Mar 22 05:24:06 localhost postfix/smtpd[14502]: warning: premature end-of-input on private/rewrite socket while reading input attribute name
Mar 22 05:24:06 localhost postfix/smtpd[14502]: warning: problem talking to service rewrite: Success
Mar 22 05:24:06 localhost postfix/master[14418]: warning: process /usr/lib/postfix/trivial-rewrite pid 14504 exit status 1
Mar 22 05:24:08 localhost postfix/trivial-rewrite[14505]: warning: connect to mysql server localhost: Can’t connect to local MySQL server through socket ‘/var/run/mysqld/mysqld.sock’ (2)
Mar 22 05:24:08 localhost postfix/trivial-rewrite[14505]: fatal: mysql:/etc/postfix/mysql_virtual_alias_maps.cf(0,100): table lookup problem
Mar 22 05:24:09 localhost postfix/smtpd[14502]: warning: premature end-of-input on private/rewrite socket while reading input attribute name
Mar 22 05:24:09 localhost postfix/smtpd[14502]: warning: problem talking to service rewrite: Success
Mar 22 05:24:09 localhost postfix/master[14418]: warning: process /usr/lib/postfix/trivial-rewrite pid 14505 exit status 1
Mar 22 05:24:09 localhost postfix/master[14418]: warning: /usr/lib/postfix/trivial-rewrite: bad command startup — throttling
Two things, first the log file states that it can’t find the private key. Check pathnames and filenames. It can have something to do with the the chroot thing described next too.
Second, it can’t connect to your SQL-server. The easiest way to fix this is to run the smtpd without chroot, and that is done in the master.cf file, so have a look there. Otherwise you can enable inet mode, and connect using a tcp port instead of a unix socket.
Please note that this document is not finished, so there are probably some things that are vauge. I know several people who have followed this guide and succeded, so you might have to do some out-of-the-box thinking. I will have a new revision of this guide up soon.
I have created an APT repository for my patched sasl2 packages (described in my prior post). The repository contains Postfix with quota support and the sasl2 packages with encrypted passwords support.
Add this line to your /etc/apt/sources.list if you like to use it (before the official Debian repositories):
deb http://pelme.se/~andreas/postfix-virtual sarge unofficial
So, this looks easy but effectively is not. I have followed all the steps (including adding the courier-authmysql package).
So, I can connect to squirrelmail (which is good
)
However, I do not see the mailboxes being created in /home/virtual. Also I cannot log in using squirrelmail as it keeps telling me that there’s something wrong with the user/password. Looking in the mysql database I see the user so now I’m really confused.
Any ideas?
Have a look at the mail logs for any strange lines (/var/log/mail.log). Paste them here so I can have a look, if you don’t know what they mean.
Johnny,
Here’s the last entry in the log file:
Feb 24 14:22:55 oldcourse postfix/trivial-rewrite[5959]: warning: connect to mys
ql server localhost: Can’t connect to local MySQL server through socket ‘/var/ru
n/mysqld/mysqld.sock’ (2)
Feb 24 14:22:55 oldcourse postfix/trivial-rewrite[5959]: fatal: mysql:/etc/postf
ix/mysql_virtual_alias_maps.cf(0,100): table lookup problem
Feb 24 14:22:56 oldcourse postfix/smtpd[5880]: warning: premature end-of-input o
n private/rewrite socket while reading input attribute name
Feb 24 14:22:56 oldcourse postfix/smtpd[5880]: warning: problem talking to service rewrite: Success
Feb 24 14:22:56 oldcourse postfix/master[5698]: warning: process /usr/lib/postfi
x/trivial-rewrite pid 5959 exit status 1
Feb 24 14:22:56 oldcourse postfix/master[5698]: warning: /usr/lib/postfix/trivia
l-rewrite: bad command startup — throttling
The thing that bugs me is that:
a. I cannot see new mailfolders being created
b. I cannot log in using Squirrelmail (which should be real easy)
I guess I made a typo somewhere but for the life of it I cannot figure out where I made the mistake. So your help is much appreciated!
It seems that the mail server can’t connect to your MySQL server (It’s trying to connect to /var/ru
n/mysqld/mysqld.sock) which is not available in the chroot environment).
You could either remove the chroot for the Postfix services in master.cf which is easiest, or start the MySQL server in TCP mode and connect to an internet socket instead of a UNIX socket.
Ok, I must admit that I’m lost now…
I have no idea how to do either, could you help me understand what I need to do?
By the way, although I’m having some trouble with it but this is BY FAR the easiest Howto helping you set up a mailserver!
To disable the chroot environment in Postfix, open the /etc/postfix/master.cf file and look for the chroot(yes) column.
Change all occurrences below to ‘n’ without the quotes. This will disable the chroot environments for all Postfix components. Now, it should be able to connect to the MySQL server.
Thank you for that. It’s great that it is appreciated.
Ok, done that. Restarted postfix and tried again. Figured that it might not hurt so deleted the mailbox that I had set up and added it again.
Now what happened is that the tool tells me that the user@mydomain.dom mailbox (user@mydomain.dom) has been added BUT then I get the error (in red) that creation of the mailbox has failed.
Again, /home/virtual is empty so it seems that the expected maildir for my new user was not created?
The virtual mail directory should be created when a mail is sent to that address. Postfixadmin should do this automatically.
Are the permissions on /home/virtual ok? postfix should be the owner and have full permissions (cd /home; chmod -R 700 virtual; chown -R postfix virtual). That should be typed as root.
If that does not solve the problem, try to create the maildir manually by going to /home/virtual and running “maildirmake user@domain.tld” and changing the permissions like above.
I added the maildir manually and tried to log in again. Same error about unknown user/password incorrect so I had a look at the log file.
Feb 24 16:01:31 oldcourse imaplogin: Connection, ip=[::ffff:127.0.0.1]
Feb 24 16:01:36 oldcourse imaplogin: LOGIN FAILED, ip=[::ffff:127.0.0.1]
Feb 24 16:01:36 oldcourse imaplogin: LOGOUT, ip=[::ffff:127.0.0.1]
I do assume that I’m expected to log in with my mail address right?
Yes, you are supposed to log in using your email address.
The table “mailbox” in MySQL contains a column called “password”, which should contain an entry similar to “$1$345b40f8$gleMfk58flN2LaOE/xwZ”. If it is in clear text, your Postfixadmin is misconfigured.
Change the encryption settings in “config.inc.php” to “$CONF['encrypt'] = ‘md5crypt’;” in your Postfixadmin configuration.
Also, make sure that “/etc/courier/authmysqlrc” has “MYSQL_CRYPT_PWFIELD” and NOT “MYSQL_CLEAR_PWFIELD”.
It’s strange that you don’t get any other log entries other than that. Have you looked in all mail and system log files?
All the things you mention are correct. I have the
MYSQL_CRYPT_PWFIELD password and the md5crypt settings.
The log file I look at is /var/log/mail.log What others are you suggesting I review?
Have a look in /var/log/syslog as well.
/etc/courier/authdaemonrc should contain “authmysql” as authentication module:
authmodulelist=”authmysql”
Your might also want to check to see that /etc/courier/authmodulelist only contains “authdaemon”.
It’s kind of hard to suggest a solution without knowing what’s wrong.
Is the maildir created when you create a user with Postfixadmin? It should. If it does not, look in the log files to see what Postfix spits out.
Well, I used another (albeit longer) HOWTO to set up my mail server as well. And it works, but not with PostfixAdmin. Which is a shame because I like PostfixAdmin.
So I tried to merge this howto with the other one to get best of both worlds. And again it fails with PostfixAdmin.
So I guess I’m too stupid to set this up
Thanks for all your help and pointers, but I’m going to go with what I know works….
Please forgive how simple a question this is. I have taken over supporting a Postfix server with Postfix Admin (it says that it’s Postfix Admin ver 2.1.0) installed. I can get into the admin panel, where I can edit domains, create users, etc. When I click on virtual list and view all the users, I see all the users on the system, but when I choose to edit a user, all I can do is edit their alias. I need to change the password for a certain user. The old network admin is MIA, and the user forgot the password. How do I do that? I went in the CLI and hit passwd jstevens (user name is jstevens) and it let me assign a password. But that password does not work. It does not let me do “passwd jstevens@domain.com” – so what should I do? I appreciate any help you can provide. Thank you.
@ Dave Martin
The first thing you need to get sorted out is if the mail system is using local users or virtual users. When you set “passwd jstevens” you are changing the password for the local user. In Postfixadmin, the users are usually stored in a MySQL database, and they are separate from the system users.
I don’t have a Postfix admin installation nearby, so I can not check the specifics regarding that. You said that you went to the Virtual list, which is only for adding aliases, if I remember correctly. You need to look at the mailbox tab (or something similar).
Hi all,
What is virtual_minimum_uid = 100 means?
Hello Kirby,
From the Postfix documentation: “[virtual_minimum_uid] specifies a minimum UID that will be accepted as a return from a virtual_uid_maps lookup. Returned values less than this will be rejected, and the message will be deferred.”
Good luck.
Hi Johnny,
Do i have to follow any uid in the /etc/passwd or just 100 will do, or the uid of Postfix?
regards,
KC
Kirby,
Set it lower than or equal to virtual_uid_maps and you should be fine.
Hello,
i got the same problem, even with chroot n
and this only occurs some times, after i reboot the sever, it works for a few hours.
:postfix/trivial-rewrite[21451]: fatal: … process /usr/lib/postfix/trivial-rewrite
Hello
I have a little problem…When I create the domain and the mailbox it only creates the mailbox directory…the domain directory is not created…
Anybody has any idea why?
Thank you
[quote comment="73577"]Hello
I have a little problem…When I create the domain and the mailbox it only creates the mailbox directory…the domain directory is not created…
Anybody has any idea why?
Thank you[/quote]
Sounds like a permissions problem on the directory above the domain directories.
Thanx for your great article….
i have little problem… i follow your tutorial and its work well, but my smtp authentication not work.. my postfix not read identity user, so i can send mail with abuse user… how i configure smtp authentication?
thanx alot