Postfix-MySQL configuration

<!-- NOTES - Beter dekkende term voor de essentie van deze procedure (postfix configuratie gebeurd overal / is niet de essentie) --> <!-- GOAL ONE-LINER --> <p>Create a subset of configuration files required for SMTP server (Postfix).</p> <!-- RATIONALE --> <p>These configuration files enable Postfix to connect to MySQL to retrieve information about valid domains, users and aliases.</p> <!-- NUANCE --> <h2>Procedure</h2> <!-- NARRATIVE FORM --> <!-- STEP BY STEP --> <ol> <li> <p>Create the domain configuration file <code>/etc/postfix/mysql-virtual-mailbox-domains.cf</code> to enable domain existence checks using the database:</p> <pre><code class="language-diff">+ hosts = 127.0.0.1 + dbname = mailserver + user = mailadmin + password = &lt;MYSQL PASSWORD&gt; + query = SELECT 1 FROM `domains` WHERE `name` = '%s' LIMIT 1;</code></pre> <p><code>&lt;MYSQL PASSWORD&gt;</code> being the password of choice defined during <a href="/mailserver/postfix-mysql-config/Mail-server_Database-preparation">database preparation</a>.</p> </li> <li> <p>Create the user configuration file <code>/etc/postfix/mysql-virtual-mailbox-maps.cf</code> to enable an e-mail address (user@domain) existence checks using the database:</p> <pre><code class="language-diff">+ hosts = 127.0.0.1 + dbname = mailserver + user = mailadmin + password = &lt;MYSQL PASSWORD&gt; + query = SELECT 1 FROM `users` WHERE `username` = '%u' AND `domain` = '%d' LIMIT 1;</code></pre> <p><code>&lt;MYSQL PASSWORD&gt;</code> being the password of choice defined during <a href="/mailserver/postfix-mysql-config/Mail-server_Database-preparation">database preparation</a>.</p> </li> <li> <p>Create the aliases configuration file <code>/etc/postfix/mysql-virtual-alias-maps.cf</code> to enable alias destination retrieval from the database:</p> <pre><code class="language-diff">+ hosts = 127.0.0.1 + dbname = mailserver + user = mailadmin + password = &lt;MYSQL PASSWORD&gt; + query = SELECT `destination` FROM `aliases` WHERE `source` = '%s';</code></pre> <p><code>&lt;MYSQL PASSWORD&gt;</code> being the password of choice defined during <a href="/mailserver/postfix-mysql-config/Mail-server_Database-preparation">database preparation</a>.</p> </li> <li> <p>Create the email to email configuration file <code>/etc/postfix/mysql-email2email.cf</code> to enable specific target e-mail address retrieval from the database:</p> <pre><code class="language-diff">+ hosts = 127.0.0.1 + dbname = mailserver + user = mailadmin + password = &lt;MYSQL PASSWORD&gt; + query = SELECT '%s' FROM `users` WHERE `username` = '%u' AND `domain` = '%d' LIMIT 1;</code></pre> <p><code>&lt;MYSQL PASSWORD&gt;</code> being the password of choice defined during <a href="/mailserver/postfix-mysql-config/Mail-server_Database-preparation">database preparation</a>.</p> </li> <li> <p>Turn the created, human readable, configuration files into mapping-matrices of a format that postfix "understands". The last step is a trick; it combines the alias definition table and the user definition table to be dealt with as if it were <em>one</em> big operational alias table for Postfix*:</p> <pre><code class="language-shell">postconf -e "virtual_mailbox_domains=mysql:/etc/postfix/mysql-virtual-mailbox-domains.cf" postconf -e "virtual_alias_maps=mysql:/etc/postfix/mysql-virtual-alias-maps.cf,mysql:/etc/postfix/mysql-email2email.cf" postconf -e "virtual_mailbox_maps=mysql:/etc/postfix/mysql-virtual-mailbox-maps.cf"</code></pre> <blockquote> <p>:information_source: *Postfix prefers aliases (explicit redirection) over the actual existing user accounts. It does so by always checking the alias table before the user table when determining an e-mails destination (i.e. if it finds an <em>alias source</em> that corresponds with the "to-address" of the received e-mail, it will send it to its corresponding <em>alias destination</em>, rather than send it to a user that may have the same address). In other words: Alias rules overrule user (endpoint) definitions should they exist.</p> <p>This is perfectly fine as long as only explicit user definitions are used in the alias table. However respecting the aforementioned preference model would make a 'catch all alias' definition indeed (always!) catch <em>all</em> e-mail, making no exceptions for specific e-mail addresses that may be present in the user table. Of course this <em>could</em> be countered by additionally including all specific user e-mail address definitions as a source and target in the alias table next to also being present in the user table to begin with. However, that would result in tedious user-management.</p> <p>Instead this guide combines the alias and user definition (database) tables (in the last line of the final 'effectuation' step) as such that Postfix will effectively be presented with that combination as if it is <em>one alias</em> table. Using this "trickery"; specific users do not have to be added <em>manually</em> to the alias <em>definition</em> table any longer but <em>are</em> nevertheless encountered when postfix searches within the (combined) table that it is offered as its operational alias table.</p> </blockquote> </li> <li> <p>Reload the configuration files into postfix to effectuate the changes:</p> <pre><code class="language-shell">service postfix reload</code></pre> </li> </ol> <!-- REFERENCES -->