How to install a complete mailserver on Debian 8/9, featuring Postfix, Dovecot, MySQL, Spamassassin, ClamAV, Roundcube and Fail2ban.
~ the howto that actually works ~
Part 1: Introduction
Part 2: Preparations: Apache, Let’s Encrypt, MySQL and phpMyAdmin
Part 3: MTA: Postfix
Part 4: IMAP server: Dovecot
Part 5: Web interface: Roundcube
Part 6: Spam filtering: SpamAsasssin
Part 7: Antivirus: ClamAV and ClamSMTP
Part 8: Quota and other Roundcube settings
Part 9: Using mail with a remote IMAP client (i.e. Thunderbird)
Part 10: Counter brute-force attacks with Fail2ban
Part 11: Sources, config files, colouring and comments
On this page
Sources
Config files
Colouring Picture
Comments
I hope you’ve enjoyed my howto on installing a mailserver on Debian. If this article has been of use to you feel free to click the ads to generate a few cents of revenue or even consider a small donation using the PayPal button in the upper right corner of this page.
Please post comments or questions the comment section on this page. Note that I can’t answer every individual question and more technical questions should generally be asked in the mailing lists of the software in question.
~~~
If you’ve made it this far I salute you. To reward you for your perseverance you may print out the colouring picture below for an hour of colouring fun \o/ If you scan it and mail to dekapitein [at] this site’s domain I will post it here :)
Sources
Official documentation:
Debian
Postfix
Dovecot
Fail2ban
ClamAV
ClamSMTP
SpamAssassin
Thunderbird
Let’s Encrypt
Inspiring sources:
PostfixBasicSetupHowto
PostfixVirtualMailBoxClamSmtpHowto
EasyEngine: Sieve Mail Filtering Setup
Debian Mail Server with Postfix and Dovecot
Server world: Install Dovecot
BinaryTides: Setup a mail server with Postfix and Dovecot on Ubuntu / Debian
DigitalOcean: How To Configure a Mail Server Using Postfix, Dovecot, MySQL, and SpamAssassin
RoseHosting: How to set-up server-side email filtering with Dovecot Sieve and Roundcube on a CentOS 6 VPS
Linuxconfig.org Generate SSL Certificates With LetsEncrypt on Debian Linux
Config files
This file contains all settings of the files we’ve worked with in this howto. You may use it for reference in case you get stuck. It is not intended for production.
Colouring Picture
Picture courtesy of krewinkelkrijst.nl. Click for a larger version!
Wannabe SysAdmin
2016-07-13
Hi,
great guide and thanks for sharing!
The only problem I encountered was with the configuration of ‘Automatically delete spam after 30 days’.
My logs give me ‘dovecot: auth: Error: Trying to iterate users, but userdbs don’t support it’.
In my ‘/etc/dovecot/dovecot-sql.conf.ext’ I added ‘iterate_query = SELECT email AS user FROM addresses’ but the problem persists.
The only thing I did different from your tutorial was the settings of ‘/etc/dovecot/conf.d/auth-sql.conf.ext’.
I have:
userdb {
driver = static
args = uid=vmail gid=vmail home=/var/vmail/%d/%n
}
and I also commented out the following because it gives me an error about ‘my_db_name.users don’t exit’
#userdb {
# driver = sql
# args = /etc/dovecot/dovecot-sql.conf.ext
#}
Of course I tried all kinds of configuration in ‘/etc/dovecot/conf.d/auth-sql.conf.ext’ but nothing seems to work.
Any help would be grealty appreciated!
Thanks in advance!
= = = = = = = = =
Some suggestions/fixes to improve your tutorial:
– CREATE DATABASE postfix; => CREATE DATABASE postfix CHARACTER SET utf8 COLLATE utf8_general_ci;
– BBCode typo [em]may[/em] => may in /installing-a-mailserver-on-debian-8-part-2-preparations-apache-lets-encrypt-mysql-and-phpmyadmin/
– Alias /roundcube /var/log/roundcube => Alias /roundcube /var/lib/roundcube => Alias /webmail /var/lib/roundcube (the last one is personal choice)
– After creating the spamfilter.sieve file the user should => sievec /etc/dovecot/sieve/spamfilter.sieve (otherwise they might end up with a ‘sieve not compiled’ kind of error)
Kapitein Vorkbaard
2016-07-14
Because you are using static lookups instead of dynamics your iterate query doesn’t work. Therefor you need “driver = mysql” and not “driver = static”. Of course ONLY changing that is not enough; you need to design your database to reflect that. Check Part 4 of this series, just under “Have Dovecot look up accounts in MySQL rather than PAM”.
The iteration (=looping through all accounts) uses sql, therefor it must be able to look everything up. Either that or you need to write a query that fakes it (e.g. “SELECT 5000 AS uid”, which always returns uid=5000).
I struggled with this issue myself and it is really confusing and poorly documented throughout the web, *unless* you already know how it works, *then* the documentation makes sense.
The typos I already found yesterday, coincidentally ;) But thanks anyway.
As for the Sieve compilation: Sieve rules are compiled on the fly. You only need to precompile them if the user will never run them, which is the case for default rules. But those are deleted for that user when he/she creates his/her own rules which can be very confusing! So I chose not to use that kind of rule. Hence nothing to precompile :)
I’ll look into the BBCode. I’m not sure how to go about that because for some reason I find it easier to set up a complete mailserver than to configure this WordPress site…
Thanks for your suggestions!
Wannabe SysAdmin
2016-07-14
Unfortunately I can’t change my driver from static to mysql because then I get another error about ‘my_db_name.users don’t exist’.
Therefore, I went with solution number 2 by just adapting my iteration but nothing seems to work.
In my nano /etc/dovecot/dovecot-sql.conf.ext I tried:
As the (…) indicate I tried a lot of variations but nothing seems to work. What do I miss?
Kapitein Vorkbaard
2016-07-14
Like I said: you also need to change your database design. You need to have a table with users to select your users from. No table, no select. Merely saying “select from a table” without actually having that table will not work.
Wannabe SysAdmin
2016-07-14
Yeah I get that but I do have a table… I just adapted my code above to match your tutorial…
I have a database with the following:
and for creating a system user to handle the mails i did:
~$ groupadd -g 5000 vmail
~$ useradd -g vmail -u 5000 vmail -d /var/vmail -m
To be honest is confusing but as far as I understand I should create an extra table in my db lets say vmail_user_table and select that user in my iteration_query?
Some thing like:
Wannabe SysAdmin
2016-07-13
Also it might be a good idea to allow users post comments with BBCode or some limited HTML so the spacing preserved. My first comment had spaces between the topics I mentioned with the intention of being easier to read but now it seems pretty messed up…
Stephane
2016-12-04
Very good and educational tutorial! And it works right away!
Did you try to setup a backup MX server? I would love a Part 9 : “Backup mail server”.
Kapitein Vorkbaard
2016-12-05
Thank you :) I did not try that, perhaps I should. But I have no plans for it on the short term.
Stephane
2016-12-04
(I meant a “Part 12”)
Snapp R
2017-04-03
hey there,
Thanks for the awesome tutorial.. this is really helpful~ :)
need some help, i got problem with SpamAssassin.. already follow all the step of configurations, but SpamAssassin isn’t detecting TheGTUBE test Spam.
checking the Source Config Files, there is spamass-milter there but not on the tutorial(Part 6), so i tried installing spamass-milter and set the config same as yours.. but still not detecting TheGTUBE test spam.
what did i do wrong here?
Thanks!
Kapitein Vorkbaard
2017-04-03
Hi Snapp, on which line did you find a milter in my config file? https://vorkbaard.nl/wp-content/uploads/2016/03/configfiles.txt What does your /var/log/maillog say when you send in a GTUBE test mail? Are you 100% sure you copied the GTUBE code correctly?
Snapp R
2017-04-03
opss, sorry.. i looked at other source config when trying to fix it (did clean everything except code in this tutorial) >.\)
i’m sure copy paste the GTUBE code correctly..
i’m new on linux & a bit confused about reading the log.. but i think the problem is this, that “failed” word >.<)v :
Apr 3 14:56:58 mail spamc[30521]: connect(AF_UNIX) to spamd using –socket='/var/spool/postfix/spamass/spamass.sock' failed: No such file or directory
Apr 3 14:56:58 mail postfix/pickup[30177]: 777CC281BC9: uid=1001 from=
Apr 3 14:56:58 mail postfix/cleanup[30519]: 777CC281BC9: message-id=
Apr 3 14:56:58 mail postfix/qmgr[30176]: 777CC281BC9: from=, size=4828, nrcpt=1 (queue active)
Apr 3 14:56:58 mail postfix/pipe[30520]: 994BB281BC7: to=, relay=spamassassin, delay=0.87, delays=0.86/0/0/0.01, dsn=2.0.0, status=sent (delivered via spamassassin service)
Apr 3 14:56:58 mail postfix/qmgr[30176]: 994BB281BC7: removed
Kapitein Vorkbaard
2017-04-03
Also: did you start the spamassassin service?
Snapp R
2017-04-03
the service is running~ the other config is working correctly.. only the spamassassin still not detecting spam test~
Snapp R
2017-04-03
ok.. found out the problem, i think i got error cause of different config before i found this tutorial here.. there is this file named spamc.conf (/etc/spamassassin/spamc.conf) with some command.. did purge all of installation from previous tutorial before starting urs, but forget to delete manually created config.. >.<)v
tried to delete it, and the spamassassin is working right away.. sorry for asking about the error caused by myself.. ur tutorial is totally GOOD!!!! THANKS!! :')
Kapitein Vorkbaard
2017-04-03
Good job, Snapp :) And thanks for sharing your solution.
Jeff
2017-05-06
Amazing tutorial! I haven’t finished yet, but wanted to comment. This entire tutorial is a breath of fresh air. Thanks for creating and sharing it!
Paulo Gobbato
2017-05-27
GREAT guide! I looked to closely to make sure I did not lose any { or } that I forgot one # and broke everything in step 4. For the life of me I couldn’t find it. I had to get my wife to check the files for me. (She is absolutely not an IT person)
Kapitein Vorkbaard
2017-06-26
Thanks :) A trick I sometimes use is to read the config backwards. That way you’re not distracted by the meaning of words.
Hannah Sophia Arada
2017-06-25
Your tutorial is the best so far I found on the internet. Thanks!
Just a small question, is it relatively easy to implement DKIM on your config?
Kapitein Vorkbaard
2017-06-26
I didn’t try that but it is supported so it shouldn’t be too difficult.
leila
2017-07-06
hey good tuto
However i did not fid the postfix database?
why wasn’t it created and what command is suppose to do so?
Thank you
Kapitein Vorkbaard
2017-07-06
Your question is corrupt: the database was created in part 2: ‘Creating the database’ ;)
leila
2017-07-06
thank you i didn’t finish all part since i’ve already used another tuto but faced some issues so here i am
again good tuto
Erik
2017-07-06
Followed the entire manual using MariaDB from start and altered the user database using an extra field to set user_quota settings per user.
Works like a charm!
Next step: Upgrade the entire environment to Debian 9. Curious if it will keep running ;-)
Erik
2017-07-06
And together with the E.F.A. 3 gateway I’ve got a complete mailsystem to kick out the hMailserver on Windows.
Kapitein Vorkbaard
2017-07-06
Sounds like a project :D Thanks for your feedback.
Erik
2017-07-06
A year ago I would have pointed my finger to my forehead (ben niet gek!) if I told myself (as a Windows guy) I would migrate all Windows 2012R2 servers on my homeserver to Linux…
This is the last one step hehe!
Kapitein Vorkbaard
2017-07-06
Heh :P I used to run hMailserver years ago. It’s ok but the things a Linux server allows you to do..! Documentation is the key :)
Erik
2017-07-06
Well, upgraded it to Debian 9, needed to uninstall php7 and reinstall to get Roundcube and PHPMyadmin running again.
Needed to alter the postfix config to delete the entry !SSLv2 as it is obsolete. (did an update leaving all configs untouched)
I can mail again, but I think Spamassasin is not working as the GTUBE fails. Along with the other services a nice task for next Monday. I have the feeling it will work again next week :D
Kapitein Vorkbaard
2017-07-06
I need to figure out the WordPress reactions part some day. This is a reaction to your next reaction.
I’ll be looking into Debian 9 and whatever Ubuntu version is current soon and document accordingly. It’s a dirty job but someone’s gotta do it :P
Erik
2017-07-06
Well, in reaction to that, cause I wish to see where it goes
l
i
k
e
t
h
i
s
.
I’m going to copy all these pages into one giant PDF and add my own changes, so when the site goes down… I happen to have a backup ;-)
Kapitein Vorkbaard
2017-07-07
Yeah… This site isn’t going to go down :P
Erik
2017-07-10
Good! And btw,.. did a GTUBE and EICAR test on Debian 9, it works!
Now need to figure out why I don’t see any mail message from clamav that a virus was found (only the log showed me it did)
Probably a setting, but meanwhile, it survived the upgrade without any big surprises!
Kapitein Vorkbaard
2017-07-10
Good job! And thanks for sharing :)
leila
2017-07-08
hello
i followed the tuto but arriving at Dovecot the emails stoped been sent or received?
leila
2017-07-08
when i delete the connection between
i mean delete these lines
“virtual_transport = lmtp:unix:private/dovecot-lmtp
smtpd_sasl_auth_enable = yes
smtpd_sasl_type = dovecot
smtpd_sasl_path = private/auth”
i can receive emails
besides this i can not login to roundcube
leila
2017-07-08
when i do the dovecot -n at the end i get “userdb {
args = uid=vmail gid=vmail home=/var/vmail/%d/%n
driver = static
}
”
i did not use vmail as a user but i changed it to myuser
i went through the tuto several times to check whether i did something wrong but i can’t figure it out
Kapitein Vorkbaard
2017-07-08
You can compare your config files agains mine, perhaps you’ll find a discrepancy: https://vorkbaard.nl/wp-content/uploads/2016/03/configfiles.txt
Kapitein Vorkbaard
2017-07-08
That’s normal. Roundcube comes later; don’t worrry.
Jack
2017-07-14
Incredible tutorial.
Great resource, thanks very much.
Antonio Trujillo Carmona
2017-08-25
God tutorial.
But. I have problem with @gmail.com.
Where can I got help with that?
Kapitein Vorkbaard
2017-08-25
Hi Antonio (and THANKS :)) Are any relevant errors logged in /var/log/mail.log?
C. Hvilsted
2017-08-30
Great tutorial. You have really invested a lot of time in this. Thank you so much.
I does not appear to me that Covedot supports UT8 chars? With the Danish layout I get errors if I don’t set smtputf8_enable = no in /etc/postfix/main.cf.
If I set smtputf8_enable = no the mail vil get delivered – but the Danish chars in the mail will be gibberish.
C. Hvilsted
2017-08-30
What a mess, lots of typos in my comment – I cannot edit – I hope you get the point anyway.
Kapitein Vorkbaard
2017-08-30
I think you should look at supported charsets on your OS itself. I’m not sure Dovecot really cares. Anyway, I’m not an expert but I can use diacritic characters without a problem. Using Dutch, so some diacritic chars. Anyway I never looked at that in much detail, sorry. It always just worked :P
C. Hvilsted
2017-08-31
Thank you so much for your answer. That’s a great idea! I will check up on that!
Rogier
2017-08-31
Hello,
After a lot of troubleshooting I fixed most of my erros but unfortunately I can’t solve this one.
When i’m trying to send e-mails i receive the following error message: ‘SMTP-fout (250): Authenticatie mislukt./SMTP-error (250): Authentication failure.’
Can you please help me in this case?
Thanks in advance!
Kapitein Vorkbaard
2017-09-01
* Can you log on to your account in Roundcube? If so the database connection with your password is alright.
* Turn up logging verbosity in /etc/dovecot/conf.d/10-logging.conf
* Turn up logging verbosity in Postfix: http://www.postfix.org/DEBUG_README.html#debug_peer
* Check /var/log/auth.log
* You can check your configuration files against mine: https://vorkbaard.nl/wp-content/uploads/2016/03/configfiles.txt
Hope that helps!
Rogier
2017-09-01
Thanks. Had some mistakes in config.inc.php file from roundcube..
Rogier
2017-09-01
Ok.. everything is working now, so first of all thanks for the manual and the support!
Actually, when i send e-mails to, for example a Gmail account, it goes to the spam folder.. The same thing is for Outlook.
Can you please advise me?
Thanks a lot!
Kapitein Vorkbaard
2017-09-01
Please read https://vorkbaard.nl/installing-a-mailserver-on-debian-8-part-3-mta-postfix/#setting_myhostname
Also check https://mxtoolbox.com – I suppose your reverse dns is not set (correctly). This is tricky stuff; you need to contact your hosting provider to set your reverse dns. This is probably not the same entity as your internet service provider.
If you need more help feel free to mail me at ‘dekapitein’ at this domain.
Kapitein Vorkbaard
2017-09-01
Also check http://isnotspam.com/
Dario
2017-09-05
Hi, very great tutorial!
Unfortunately i’m stuck on a boring problem.
I’ve followed each part of the tutorial, but in the end i got a Password mismatch from dovecot.
Can you please help me to deal with it?
Thank you in advance for your effort!
Kapitein Vorkbaard
2017-09-05
Carefully read https://vorkbaard.nl/installing-a-mailserver-on-debian-8-part-5-web-interface-roundcube/#set_a_user_passwords and turn up logging in /etc/dovecot/conf.d/10-logging.conf.
Are you seeing any sql errors? Did you copy the $6 part of the password into the password field? Any other errors in your logfile?
Patrik Lantz
2017-09-23
Hi,
This is one of the best tutorials I’ve found on the net.
Great work on this.
I do have some quick questions you might could answer or point me in the right direction.
* How do I add virtual-users / mailbox without using phpmyadmin.
– Could I use Webmin, ISP-Config or is there something similar ?
I’m trying to setup a server LAMP + Mailserver and it would be great if I could you your setup + one of the above Panels to have better control.
/Patrik
Patrik Lantz
2017-09-23
I forgot to say that I would like to use Roundcube and usage with Thunderbird IMAP/POP3.
Kapitein Vorkbaard
2017-09-24
Hi Patrik, there’s a command-line version on the same page as the PhpMyAdmin stuff, but I think you’re not looking for that. You could write a short Bash script to add virtual users and use Webmin’s command option to run it. I’m not very familiar with ISP-Config but I suggest you Google for something like ‘run custom script from ISP-Config’.
If you find anything please let me know and I’ll happily add it to the tutorial :)
Patrik Lantz
2017-09-24
Thanks, will look into “Run custom script”
But I hoped that Webmin or ISP-Config automaticly could config it self…
I wonder if you have any good pointers to solve the, not able to send to xx@gmail.com
Kapitein Vorkbaard
2017-09-25
Either your log files or the recipient will help you ;) ‘Not able’ is not enough information to go on.
KTdesignstudio
2017-11-30
Thank You very much Mr Vorkbaard. The mail server of mine works like a pro.Clicked google ads on top, hope it helps a bit.
Kapitein Vorkbaard
2017-12-01
It did a bit! Thanks for the feedback :)
Marouan
2017-12-20
Hi Mr Vorkbaard, did you get my previous comment ?
Thanks.
Marouan
2017-12-20
I am sorry i did send a previous message but it didn’t work ?!
I followed your tutorial wich is great by the way i just have a problem.
postfix/postdrop[18913]: warning: mail_queue_enter: create file maildrop/924506.18913: Permission denied
and i can send mails from the command as root but from wordpress for example i get this error.
Kapitein Vorkbaard
2017-12-20
Hi Marouan, I’m not sure what’s going on but it does seem to be a common problem according to Google. For example: https://bbs.archlinux.org/viewtopic.php?id=164583 and https://jeffkarney.com/2013/01/15/fixing-postfix-permission-issues-linux/ Anyway it sounds like a permissions problem so I’d walk through the tutorial again and make very sure you pass all the tests in there.
Marouan
2017-12-21
Hi Vorkbaard and thanks for your reply i changed the files permissions and user to postfix postdrop but the problem remains i will uninstall everything and start from scratch and see if the problem goes away.
Hannah Sophia Arada
2018-01-30
Thanks for this great guide :D