iKVM
Secure Login
Network Cards
Hard drives
SSHFS
Basic DNS
Website DNS
Certbot SSL
Apache and PHP
Maria DB
Mail Server Basics
Mail Server SSL
Mail Server Filters
Checklist
Backup
Mail Server Basics (Postfix and Dovecot)

Note: This article series covers configuring Debian 12 for hosting multiple domains and web sites on a single dedicated server. As such, some strategies may be inappropriate for your environment. Sockets for example are appropriate for communication between services hosted on the same machine but not suited to a set up with distributed services (where you'd use ports). Please consult the overview for more information.
Almost all internet web sites send and receive email. If you're from a Windows environment you'll most likely be used to your MTA (Mail Transfer Agent) and MDA (Mail Delivery Agent) being bundled in one application.
Mail Transfer Agents deal with sending and receiving the actual messages whilst Mail Delivery Agents are concerned with providing interfaces for your users to collect and interact with those emails (ie. IMAP and POP3).
In Linux, those 2 jobs are handled by 2 discrete services that work with each other (Postfix MTA and Dovecot MDA) and can be configured in a variety of ways which makes for a very flexible suite for possible solutions but can be a little confusing at times, especially as online tutorials from different time periods show you ways of achieving things in different ways. Older complicated methods are sometimes replaced by a simple switch in later versions.
I'm going to show you how to set up mail services on your Linux server which will serve multiple domains hosted on the same machine. I've spread it over 3 articles because I want to show you how to set up SSL certificates for multiple domains and I want to show you how to set up a Dovecot sieve filter that runs a script when mail arrives.
This first article covers setting up Postfix and Dovecot for multiple domains and basic SSL. If you're a casual and you just want a step-by-step guide to get yourself up and running in that environment then you've come to the right place.
Linux Mail Services can be a bit of a dark art so if you're a pro in a multi-server environment I recommend reading a book on this one, I also highly recommend you consult the Postfix and Dovecot manuals and pay careful attention to the words on the page, it's easy to overlook something that later becomes obvious. For example, I remember being a bit confused about the distinction between mail_home and mail_location for a while and that was leading to all kinds of errors and warnings!
Let's start by updating your package manager:
sudo apt update
Install Postfix (MTA):
sudo apt install postfix
Choose 'Internet Site', I use the FQDN of 'blnkserver.com'.
Install Dovecot (MDA):
sudo apt install dovecot-core dovecot-imapd dovecot-pop3d
If you run a firewall, you'll need to allow traffic on some ports for your Postfix and Dovecot services. You want to open ports 25 (SMTP), 587 (SMTP) and 465 (SMTP) and ports 110 (POP3), 995 (POP3s), 143 (IMAP) and 993 (IMAPs).
Obviously, if you don't plan to use both POP3 and IMAP then don't open those ports!
Configure Postfix for virtual mailbox domains
Linux mail can be sent and received for a system user (often how you set up an office environment) or you can set the server up to manage multiple virtual domains and users (for internet sites).With virtual domains you have a single system user (vmail in our case!) that you use for all mail boxes and you tell your services about the domains, mail boxes, SSL certificates and user logins.
I'm going to set up 2 domains - benosborne.com and blnk.co.uk
...and 2 users - ben@benosborne.com and ben@blnk.co.uk
At first, Postfix and Dovecot will access the mail boxes by knowing their location on the disk but later on we'll pass the mail from Postfix to Dovecot via LMTP (Local Mail Transport Protocol) which will enable us to filter it a bit when it arrives.
Add the user and group vmail. If the vmail user already exists on your system, your software will warn you and not re-create or overwrite it:
sudo adduser vmail
sudo addgroup vmail
Make a directory to store the virtual mail:
sudo mkdir /var/mail/vmail
Take ownership (chown) of that folder with vmail. Before the : is the user, after is the group:
sudo chown vmail:vmail /var/mail/vmail
get the user and group id's, we're going to tell Postfix about them.
sudo id vmail
Note the user (uid) and group (gid) id's. In my case uid=1001, gid=1001.
So you understand what we're doing here, virtual_mailbox_domains is just a list of domains that we want Postfix to be responsible for.
virtual_mailbox_maps (/etc/postfix/vmailbox) is going to be a list of mail boxes and their location on the disk whilst virtual_alias_maps (/etc/postfix/valiases) is going to be a list of aliases and which mail boxes to redirect them to (eg. sales@benosborne.com redirects to ben@benosborne.com).
The mailbox_base stuff just tells Postfix where mail boxes are stored and gives the user and group it needs to read / write to that location.
Edit the Postfix configuration (main.cf), obviously use your domain names and preferences:
sudo /etc/postfix/main.cf
virtual_mailbox_domains = benosborne.com, blnk.co.uk virtual_mailbox_maps = hash:/etc/postfix/vmailbox virtual_alias_maps = hash:/etc/postfix/valiases virtual_mailbox_base = /var/mail/vmail virtual_uid_maps = static:1001 virtual_gid_maps = static:1001Save changes then create your vmailbox and valiases files.
virtual_mailbox_maps defines vmailbox as the map file and tells postfix where to store mail on the disk for a certain email address. Mailbox name goes on the left side of the file, disk location on the right: eg. ben@blnk.co.uk blnk.co.uk/ben/
sudo nano /etc/postfix/vmailbox
ben@blnk.co.uk blnk.co.uk/ben/ ben@benosborne.com benosborne.com/ben/Note the trailing / indicates ben is a directory (maildir format) - this helps postfix decide whether to use mbox (a single file) or maildir format (multiple files). You want maildir for a number of reasons.
valiases tells postfix which inbox to redirect incoming mail to (eg. sales to ben@blnk.co.uk or a catch all @blnk.co.uk to ben@blnk.co.uk). Same deal as vmailbox, left of the file is the from mailbox and right side is the to mailbox:
sales@benosborne.com ben@benosborne.comor a catch all:
@benosborne.com ben@benosborne.comIt's worth remembering that if you do define a catch all the you must include aliases for all of your mailboxes or everything gets delivered to the catch all mailbox instead!
sudo nano /etc/postfix/valiases
After you've edited these files, they need to be in a format that postfix can read so you have to run postmap on them both, this creates vmailbox.db and valiases.db:
postmap /etc/postfix/vmailbox
postmap /etc/postfix/valiases
Configure Dovecot
Make sure dovecot knows which user and group owns the email, use the id's you noted earlier (vmail account):sudo nano /etc/dovecot/conf.d/10-mail.conf
mail_uid = 1001 mail_gid = 1001Set the mail_location and mail_home (used by LMTP and sieve later!). mail_home is where the mailbox lives whilst mail_location is where the messages are stored in that mailbox:
sudo nano /etc/dovecot/conf.d/10-mail.conf
mail_home = /var/mail/vmail/%d/%n mail_location = maildir:~/mail%d is the domain name and %n is the user name when defining mail_home.
Set the userdb and passdb to the file type and PLAIN for password. We'll be securing that file later to stop users reading it, don't worry the plain text password will only be transmitted over SSL.
Edit /etc/dovecot/conf.d/auth-passwdfile.conf.ext:
sudo nano /etc/dovecot/conf.d/auth-passwdfile.conf.ext
passdb { driver = passwd-file args = scheme=PLAIN username_format=%u /etc/dovecot/users } userdb { driver = passwd-file args = username_format=%u /etc/dovecot/users }Comment out the static file (for authenticating local users) in /etc/dovecot/conf.d/10-auth.conf and uncomment the auth-passwdfile.conf.ext (bottom of the file), also add login to the list of auth_mechanisms (for older clients).
The disable_plaintext_auth = yes option here prevents dovecot from sending the password unless over SSL (which is encrypted):
sudo nano /etc/dovecot/conf.d/10-auth.conf
disable_plaintext_auth = yes ... auth_mechanisms = plain login ... #!include auth-system.conf.ext #!include auth-sql.conf.ext #!include auth-ldap.conf.ext !include auth-passwdfile.conf.ext #!include auth-checkpassword.conf.ext #!include auth-static.conf.extCreate the users / passwords file and enter your users login info:
The format is username (ben@benosborne.com), a colon :{PLAIN}password followed by 6 colons :::::: (for the defaults!) eg. ben@benosborne.com:{PLAIN}some_password::::::
sudo nano /etc/dovecot/users
ben@benosborne.com:{PLAIN}some_password:::::: ben@blnk.co.uk:{PLAIN}some_password::::::
Basic SSL / TLS Encryption
We are going to enable basic SSL encryption for the domain specified in reverse DNS lookups (your primary domain, in my case blnkserver.com).Get a Certbot certificate for your mail server primary domain:
sudo certbot certonly --apache -d blnkserver.com
It generates the key files and gives you the paths :
eg.
/etc/letsencrypt/live/blnkserver.com/fullchain.pem /etc/letsencrypt/live/blnkserver.com/privkey.pemEnable SSL in dovecot:
sudo nano /etc/dovecot/conf.d/10-ssl.conf
ssl = required ssl_cert = </etc/letsencrypt/live/blnkserver.com/fullchain.pem ssl_key = </etc/letsencrypt/live/blnkserver.com/privkey.pemNote that the < character indicates that dovecot use the file contents.
SASL (check user is allowed to send)
We want Postfix to check the Dovecot users for authorisation before sending email so we're going to enable a socket for that purpose. The request for authorisation goes to Dovecot via a socket and it looks up the user to check they are authorised to send messages. This prevents our server from relaying messages from unauthorised users.In Dovecot, Edit 10-master.conf, service auth section and add a listener for Postfix:
sudo nano /etc/dovecot/conf.d/10-master.conf
service auth { ... unix_listener /var/spool/postfix/private/auth { mode = 0660 # Assuming the default Postfix user and group user = postfix group = postfix } ... }In 10-auth.conf ensure you support older mail clients (login method):
sudo nano /etc/dovecot/conf.d/10-auth.conf
auth_mechanisms = plain loginEdit Postfix main.cf and enable SASL (the authentication method for sending emails):
sudo nano /etc/postfix/main.cf
# SASL DOVECOT smtpd_sasl_type = dovecot smtpd_sasl_path = private/auth smtpd_sasl_auth_enable = yes # support older clients broken_sasl_auth_clients = yes smtpd_sasl_security_options = noanonymous, noplaintext smtpd_sasl_tls_security_options = noanonymous smtpd_tls_auth_only = yesBefore I could send to some clients eg. Gmail I needed to set up an spf record for the domain (it's just adding a TXT record to your DNS, I'll let you Google it!) and bind the Postfix server to one of my reverse IP's, for information about setting up reverse IP lookup see the article on Basic DNS:
sudo nano /etc/postfix/main.cf
# SETTING TO AN IP WITH REVERSE LOOKUP smtp_bind_address=74.201.177.83I also had to set my TLS settings to my Postfix server SSL certificates (because Postfix uses them to relay mail to enabled servers):
sudo nano /etc/postfix/main.cf
smtpd_tls_cert_file=/etc/letsencrypt/live/blnkserver.com/fullchain.pem smtpd_tls_key_file=/etc/letsencrypt/live/blnkserver.com/privkey.pem smtpd_tls_security_level=mayMake sure you restart Postfix to pick up your new settings:
sudo systemctl restart postfix.service
Secure it a bit!
Also, one thing I like to do is obfuscate / secure that Dovecot users file (/etc/dovecot/users):Firstly, change its name in auth-passwdfile.conf.ext to .users (prefixing a file with . in Linux makes it hidden in that dir):
sudo nano /etc/dovecot/conf.d/auth-passwdfile.conf.ext
passdb { driver = passwd-file args = scheme=PLAIN username_format=%u /etc/dovecot/.users } userdb { driver = passwd-file args = username_format=%u /etc/dovecot/.users }Rename the file:
sudo mv /etc/dovecot/users /etc/dovecot/.users
Change permissions on the file so that users cannot read it:
Take ownership for the dovecot user and group
sudo chown dovecot:dovecot /etc/dovecot/.users
Set rw for user, r for group and none for everyone else
sudo chmod 640 /etc/dovecot/.users
Restart dovecot:
sudo systemctl restart dovecot.service
Remember: From now on you'll want to sudo (become root) when you add a user and edit the /etc/dovecot/.users file:
sudo nano /etc/dovecot/.users
To view the logs for Postfix or Dovecot if you find yourself needing to diagnose a problem:
sudo journalctl -r -u dovecot.service
sudo journalctl -r -u postfix@-.service
Optional (for your web sites)
Set up PHP to send mail via Postfix.Now that you've got Postfix set up, you might like to allow your PHP scripts to send mail using it.
Edit php.ini - the location may vary depending on the version of php you're using:
sudo nano /etc/php/8.2/apache2/php.ini
In the [mail function] section:
[mail function] ... sendmail_path = /usr/sbin/sendmail -t ...I had to add -t to get the mail to send via Postfix using the standard 'mail' function (Allows you to specify the To email address). I was sending the To address in the headers as well and I was finding that some providers moan about a duplicate To address in the headers (because Postfix was adding one) so I had to modify my code and remove the To address from the header.
Check your Postfix logs after you send, it shows the mail transaction and gives you feedback about the outcome, it'll tell you if and why it failed. On Debian 12, logs are accessed using journalctl (I like reverse order and sent to a pager, so f (forward), b (back) and arrow keys), I use:
sudo journalctl -r -u postfix@-.service
You now have a basic mail server set up with basic SSL. You can access your inbox with IMAP (securely) but it's a bit clunky because you have to specify your primary domain in your account settings to use SSL. The next article covers adding SSL certificates for each domain which will make setting IMAP accounts up in clients like Thunderbird a cinch!
Some clients (like Gmail) insist on using the reverse lookup domain SSL certificate for IMAP (blnkserver.com in my case) whereas other GUIs allow you to enter an appropriate domain for mail authentication (like mail.benosborne.com).