Emil CHERICHES

Emil CHERICHES

Dedicated Mail Server Hosting Multiple Domains – Step 3 – Postfix and Dovecot

September 6, 2014 Emil C
8 Comments

On a typical Linux mail server mail is stored on the disk either using one big file in /var/mai/%user either in one Maildir in users’s home folder. This Maildir usually contains one small file for each mail stored on your server and some indexing information etc.

In this setup, because users are stored on a virtual manner (in an SQL database) we need to create a user on the system, to which all the Maildirs will belong to.

adduser mails --shell=/usr/sbin/nologin

This will create a user that has “nologin” shell. There’s no need to set a password for it, as we will never use it for SSH login and by default ssh does not allow you to login remotely using empty passwords.

One of the most important sub-steps here is to get this user’s UID. For example I did not create any user on CentOS install, so my new user’s ID is 1000, it also gas GID 1000. This is important becautse your mail server will use this ID to store and access files.

We need to create a new SQL user to be used by Postfix MTA and Dovecot as the one used by Postfix Admin has write permissions and for this one there’s no need. After launching from the shell mysql -p and entering the password:

grant select on postfix.* to postfix@localhost identified by 'POSTFIX_PASSWORD';
flush privileges;

Then we start creating SQL config files for Postfix in /etc/postfix as follows:

mysql_virtual_alias_maps.cf

user = postfix
password = POSTFIX_PASSWORD
hosts = 127.0.0.1
dbname = postfix
query = SELECT goto FROM alias WHERE address='%s' AND active = 1

mysql_virtual_domains_maps.cf

user = postfix
password = POSTFIX_PASSWORD
hosts = 127.0.0.1
dbname = postfix
query = SELECT domain FROM domain WHERE domain='%s' and backupmx = '0' and active = '1'

mysql_virtual_mailbox_maps.cf

user = postfix
password = POSTFIX_PASSWORD
hosts = 127.0.0.1
dbname = postfix
query = SELECT maildir FROM mailbox WHERE username='%s' AND active = 1

mysql_relay_domains_maps.cf

user = postfix
password = POSTFIX_PASSWORD
hosts = 127.0.0.1
dbname = postfix
query = SELECT domain FROM domain WHERE domain='%s' and backupmx = '1'

Then in Postfix’s main.cf

virtual_alias_maps = proxy:mysql:/etc/postfix/mysql_virtual_alias_maps.cf
virtual_gid_maps = static:1000
virtual_mailbox_base = /home/mails
virtual_mailbox_domains = proxy:mysql:/etc/postfix/mysql_virtual_domains_maps.cf
virtual_mailbox_maps = proxy:mysql:/etc/postfix/mysql_virtual_mailbox_maps.cf
relay_domains = $mydestination, proxy:mysql:/etc/postfix/mysql_relay_domains_maps.cf
virtual_minimum_uid = 1000
virtual_transport = dovecot
virtual_uid_maps = static:1000

and in master.cf add the lines:

dovecot   unix  -       n       n       -       -       pipe
 flags=DRhu user=mails:mails argv=/usr/libexec/dovecot/dovecot-lda -f ${sender} -d ${recipient}

The next step is Dovecot. It is important to set it up as Postfix uses Dovecot LDA to deliver mail. After a simple yum install dovecot dovecot-mysql we need to change directory to /etc/dovecot/conf.d where we edit some files as follows:

10-auth.conf

disable_plaintext_auth = no # some people just don' bother
auth_mechanisms = plain login # Otherwise Windows 8/8.1's Mail app won't authenticate
#!include auth-system.conf.ext # comment this line
!include auth-sql.conf.ext #uncomment this one

15-lda.conf

lda_mailbox_autocreate = yes
lda_mailbox_autosubscribe = yes

10-mail.conf

mail_location = maildir:/home/mails/%u:INDEX=/home/mails/%u/index

/etc/dovecot/dovecot-sql.conf.ext

driver = mysql
connect = host=localhost dbname=postfix user=postfix password=$POSTFIX_PASSWORD

password_query = SELECT password FROM mailbox WHERE username = '%u'
user_query = SELECT username, 1000 AS uid, 1000 AS gid , '/home/mails/%u' as home FROM mailbox WHERE username = '%u'

Instead of 1000 you might put in the UID/GID from the user you created.

Have you added a new domain in your Postfix Admin interface? How about a new user? it is time to send him a test mail.

echo test |mail -s test USER@DOMAIN.COM

Now tail your mailllog. tail /var/log/maillog should show you something like:

Sep  6 12:31:46 mail postfix/qmgr[32482]: C44CD80BBFFE: from=<root@mail.cheriches.com>, size=438, nrcpt=1 (queue active)
Sep  6 12:31:46 mail dovecot: lda(emil@cheriches.com): msgid=<20140906085511.C44CD80BBFFE@mail.cheriches.com>: saved mail to INBOX
Sep  6 12:31:46 mail postfix/pipe[365]: C44CD80BBFFE: to=<emil@cheriches.com>, relay=dovecot, delay=5880, delays=5880/0.02/0/0.22, dsn=2.0.0, status=sent (delivered via dovecot service)

So, right now you have a functional email server, meaning that you are able to send and receive mail, but there’s still a lot of work to be done.

Mail Server Series CentOSDovecotMariaDBPostfixPostfix Admin
Previous Post

Dedicated Mail Server Hosting Multiple Domains - Step 2 - Database and Web Administration Interface Setup

Next Post

Dedicated Mail Server Hosting Multiple Domains - Step 4 - Further Configurations

  1. Rama October 25, 2014 at 4:09 am Reply

    And if mails user isnt my first user?
    I get this error in mailin file:
    Oct 25 00:42:23 my-vps dovecot: auth: Error: userdb(example@mail.com): client doesn’t have lookup permissions for this user: userdb uid (1000) doesn’t match peer uid (1002) (to bypass this check, set: service auth { unix_listener /var/run/dovecot/auth-userdb { mode=0777 } })
    Oct 25 00:42:23 my-vps dovecot: lda: Error: user example@mail.com: Auth USER lookup failed
    Oct 25 00:42:23 my-vps dovecot: lda: Fatal: Internal error occurred. Refer to server log for more information.
    Oct 25 00:42:23 my-vps postfix/pipe[27566]: BA9AE42461: to=, relay=dovecot, delay=0.14, delays=0.07/0.01/0/0.05, dsn=4.3.0, status=deferred (temporary failure)

    I read that i have to modify /var/run/dovecot/auth-userdb , its true?
    I’ am very newly with this, sory

    • Rama October 25, 2014 at 8:12 pm Reply

      I am a stupid haha, it was only I forget to modify the correct UID for the user mails in /etc/dovecot/dovecot-sql.conf.ext.
      To get the UID for user mails run in ssh: cat /etc/passwd | grep "^mails:" | cut -d":" -f3

  2. Andrew Schott March 20, 2016 at 5:19 am Reply

    Thanks for putting together this guide. But I am running into a roadblock on the test message. I followed the guide up until the end of this page, and then logged into the postfixadmin site and added the virtual domain and virtual user. And yes I do have the DNS setup already as well, its routeable to the host and there is an mx record thats appropriate. I get the following errors in /var/log/maillog:

    Mar 20 05:16:03 mx dovecot: auth-worker(3811): Error: mysql: Query timed out (no free connections for 60 secs): SELECT username, 1000 AS uid, 1000 AS gid , ‘/home/mails/andrew@andrewschott.com’ as home FROM mailbox WHERE username = ‘andrew@andrewschott.com’
    Mar 20 05:16:03 mx dovecot: auth-worker(3811): Error: sql(andrew@andrewschott.com): User query failed: Not connected to database
    Mar 20 05:16:03 mx dovecot: auth: Error: auth worker: Aborted request: Lookup timed out
    Mar 20 05:16:03 mx dovecot: lda: Error: user andrew@andrewschott.com: Auth USER lookup failed
    Mar 20 05:16:03 mx dovecot: lda: Fatal: Internal error occurred. Refer to server log for more information.
    Mar 20 05:16:03 mx dovecot: auth-worker(3821): Error: mysql(localhost): Connect failed to database (postfix): Access denied for user ‘postfix’@’localhost’ (using password: YES) – waiting for 1 seconds before retry
    Mar 20 05:16:03 mx postfix/pipe[3807]: 34CE33CE0: to=, relay=dovecot, delay=60, delays=0.05/0.01/0/60, dsn=4.3.0, status=deferred (temporary failure)
    Mar 20 05:16:04 mx dovecot: auth-worker(3821): Error: mysql(localhost): Connect failed to database (postfix): Access denied for user ‘postfix’@’localhost’ (using password: YES) – waiting for 5 seconds before retry
    Mar 20 05:16:09 mx dovecot: auth-worker(3821): Error: mysql(localhost): Connect failed to database (postfix): Access denied for user ‘postfix’@’localhost’ (using password: YES) – waiting for 25 seconds before retry

    • Emil C March 20, 2016 at 10:41 am Reply

      It looks as you have a problem connecting to the SQL server.

      Try connecting from the shell with “mysql -u postfix -p” then run something like “show processlist;” to see if you really have to many opened connections.

      Another thing to look for is SELinux, try setting it to permissive(“setenforce 0” as root) and see if it works this way.

  3. Andrew Schott March 20, 2016 at 2:24 pm Reply

    Thanks for the tips. Firstly, SELinux is off as this is a vps using some backend that prevents it.

    [root@mx ~]# sestatus
    SELinux status: disabled
    [root@mx ~]#

    As for the mysql stuff, not very familiar with that command, but here it goes. I booted the vps, did the test mail message command (the piped one from above) and then did the show processlist, It looks like this:

    MariaDB [(none)]> show processlist;
    +—-+———+—————–+———+———+——+——-+——————+———-+
    | Id | User | Host | db | Command | Time | State | Info | Progress |
    +—-+———+—————–+———+———+——+——-+——————+———-+
    | 2 | postfix | localhost | NULL | Query | 0 | NULL | show processlist | 0.000 |
    | 3 | postfix | localhost:48496 | postfix | Sleep | 22 | | NULL | 0.000 |
    | 4 | postfix | localhost:48498 | postfix | Sleep | 22 | | NULL | 0.000 |
    | 5 | postfix | localhost:48500 | postfix | Sleep | 22 | | NULL | 0.000 |
    +—-+———+—————–+———+———+——+——-+——————+———-+
    4 rows in set (0.00 sec)

    MariaDB [(none)]>

  4. Emil C March 20, 2016 at 2:27 pm Reply

    You should also run in MySQL:
    show variables like ‘max_connections’;

    • Andrew Schott March 20, 2016 at 2:35 pm Reply

      MariaDB [(none)]> show variables like “max_connections”;
      +—————–+——-+
      | Variable_name | Value |
      +—————–+——-+
      | max_connections | 151 |
      +—————–+——-+
      1 row in set (0.00 sec)

      MariaDB [(none)]>

  5. Frank June 16, 2016 at 1:57 pm Reply

    Hello good day Thank you for your tutorial excelnte mail and domain. But I was a problem with the alias domains : Recipient address rejected : User unknown in virtual mailbox table ; could you help me with this Thanks and Regards

Leave a Reply Cancel reply

This site uses Akismet to reduce spam. Learn how your comment data is processed.

Recent Posts
  • Flash Tasmota on the Sonoff Mini – Linux user experience
  • DokuWiki a simple solution to sorting documentation
  • I discovered Wireguard
  • Using Let’s Encrypt with CentOS (for now)
  • Let’s Encrypt is Trusted
Categories
  • from the web
  • just blog
  • linux
    • Mail Server Series
  • News
  • phones
  • Phones & Tablets
  • programing
  • security
  • Smart Home
  • Tips & Tricks
  • Uncategorized
  • Web development
  • Windows
Blogroll
  • cheriches.fr
Subscribe by Email
Recent Posts
  • Flash Tasmota on the Sonoff Mini – Linux user experience
  • DokuWiki a simple solution to sorting documentation
  • I discovered Wireguard
  • Using Let’s Encrypt with CentOS (for now)
  • Let’s Encrypt is Trusted
Categories
  • from the web (3)
  • just blog (1)
  • linux (23)
    • Mail Server Series (7)
  • News (1)
  • phones (1)
  • Phones & Tablets (2)
  • programing (1)
  • security (2)
  • Smart Home (1)
  • Tips & Tricks (15)
  • Uncategorized (3)
  • Web development (1)
  • Windows (1)
Blogroll
  • cheriches.fr
Tags cloud
adb ADS aircrack-ng Android Apache apt-get CentOS Chrome ClamAV Cluster CSS Debconf debian DKIM Dovecot EasyRSA EPEL Firefox Firewall GNOME High Availability iptables KVM linux MariaDB Milter MySQL Nginx php Postfix Postfix Admin Proxy_ARP Python release Roundcube Samba SELinux Sonoff SpamAssassin ssh Tasmota ubuntu VRRP windows Youtube
Recent Comments
  • Frank on Dedicated Mail Server Hosting Multiple Domains – Step 3 – Postfix and Dovecot
  • Andrew Schott on Dedicated Mail Server Hosting Multiple Domains – Step 3 – Postfix and Dovecot
  • Emil C on Dedicated Mail Server Hosting Multiple Domains – Step 3 – Postfix and Dovecot
  • Andrew Schott on Dedicated Mail Server Hosting Multiple Domains – Step 3 – Postfix and Dovecot
  • Emil C on Dedicated Mail Server Hosting Multiple Domains – Step 3 – Postfix and Dovecot
Proudly powered by WordPress | Theme: Fmi by Forrss.
Manage Cookie Consent
We use cookies to optimize our website and our service.
Functional cookies Always active
The technical storage or access is strictly necessary for the legitimate purpose of enabling the use of a specific service explicitly requested by the subscriber or user, or for the sole purpose of carrying out the transmission of a communication over an electronic communications network.
Preferences
The technical storage or access is necessary for the legitimate purpose of storing preferences that are not requested by the subscriber or user.
Statistics
The technical storage or access that is used exclusively for statistical purposes. The technical storage or access that is used exclusively for anonymous statistical purposes. Without a subpoena, voluntary compliance on the part of your Internet Service Provider, or additional records from a third party, information stored or retrieved for this purpose alone cannot usually be used to identify you.
Marketing
The technical storage or access is required to create user profiles to send advertising, or to track the user on a website or across several websites for similar marketing purposes.
Manage options Manage services Manage vendors Read more about these purposes
View preferences
{title} {title} {title}