<?xml version="1.0"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="en">
	<id>https://wiki.alpinelinux.org/w/api.php?action=feedcontributions&amp;feedformat=atom&amp;user=Djhughes</id>
	<title>Alpine Linux - User contributions [en]</title>
	<link rel="self" type="application/atom+xml" href="https://wiki.alpinelinux.org/w/api.php?action=feedcontributions&amp;feedformat=atom&amp;user=Djhughes"/>
	<link rel="alternate" type="text/html" href="https://wiki.alpinelinux.org/wiki/Special:Contributions/Djhughes"/>
	<updated>2026-04-30T18:41:10Z</updated>
	<subtitle>User contributions</subtitle>
	<generator>MediaWiki 1.40.0</generator>
	<entry>
		<id>https://wiki.alpinelinux.org/w/index.php?title=Talk:Redmine&amp;diff=8018</id>
		<title>Talk:Redmine</title>
		<link rel="alternate" type="text/html" href="https://wiki.alpinelinux.org/w/index.php?title=Talk:Redmine&amp;diff=8018"/>
		<updated>2012-05-09T11:50:03Z</updated>

		<summary type="html">&lt;p&gt;Djhughes: /* command lacks proper path */ new section&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Why redmine and mysql?&lt;br /&gt;
Everything else in Alpine prefers sqlite3 or postgresql&lt;br /&gt;
&lt;br /&gt;
 I followed http://www.redmine.org/wiki/redmine/RedmineInstall when setting up Redmine on my test system and am more familiar with MySQL,&lt;br /&gt;
 so used it.  I&#039;m sure it&#039;d work just as well with postgres of sqlite. [[User:Jbilyk|Jbilyk]] 16:33, 20 December 2010 (UTC)&lt;br /&gt;
&lt;br /&gt;
== command lacks proper path ==&lt;br /&gt;
&lt;br /&gt;
Hi&lt;br /&gt;
&lt;br /&gt;
Running command {{Cmd|su -pc &amp;quot;/usr/lib/ruby/gems/1.8/bin/rake generate_session_store&amp;quot; lighttpd}} yields:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
rake aborted!&lt;br /&gt;
No Rakefile found (looking for: rakefile, Rakefile, rakefile.rb, Rakefile.rb)&lt;br /&gt;
&lt;br /&gt;
(See full trace by running task with --trace)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Even though this command is run from the /usr/share/webapps/redmine directory, the su command runs it from the lighttpd user home directory, so it yields the above. I got around it by running: {{Cmd|su -p lighttpd}} and then running the rake generate_session_store command.&lt;br /&gt;
&lt;br /&gt;
Same goes for the following command in the documentation for creating the redmine DB structure.&lt;br /&gt;
&lt;br /&gt;
What might be a better way of documenting this command?&lt;br /&gt;
&lt;br /&gt;
--[[User:Djhughes|Djhughes]] 11:50, 9 May 2012 (UTC)&lt;/div&gt;</summary>
		<author><name>Djhughes</name></author>
	</entry>
	<entry>
		<id>https://wiki.alpinelinux.org/w/index.php?title=Zabbix_-_cgi_and_mysql&amp;diff=5815</id>
		<title>Zabbix - cgi and mysql</title>
		<link rel="alternate" type="text/html" href="https://wiki.alpinelinux.org/w/index.php?title=Zabbix_-_cgi_and_mysql&amp;diff=5815"/>
		<updated>2011-11-04T07:17:17Z</updated>

		<summary type="html">&lt;p&gt;Djhughes: /* Zabbix Monitoring Solution */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Category:monitoring]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Zabbix Monitoring Solution ==&lt;br /&gt;
&lt;br /&gt;
The purpose of this document is to assist in installing the Zabbix server software and Zabbix agent on the Alpine Linux operating system. Instructions on how to configure and use Zabbix - as well as many useful tutorials - can be found at http://www.zabbix.com.&lt;br /&gt;
&lt;br /&gt;
{{Note|The minimum required version of Alpine Linux required to install Zabbix is Alpine 2.2.}}&lt;br /&gt;
&lt;br /&gt;
== Install Lighttpd, and PHP ==&lt;br /&gt;
&lt;br /&gt;
{{:Setting Up Lighttpd With FastCGI}}&lt;br /&gt;
&lt;br /&gt;
== Configure PostgreSQL ==&lt;br /&gt;
&lt;br /&gt;
Setup and configure PostgreSQL:&lt;br /&gt;
&lt;br /&gt;
{{Cmd|apk add postgresql postgresql-client &lt;br /&gt;
/etc/init.d/postgresql setup&lt;br /&gt;
/etc/init.d/postgresql start&lt;br /&gt;
rc-update add postgresql}}&lt;br /&gt;
&lt;br /&gt;
== Install Zabbix ==&lt;br /&gt;
&lt;br /&gt;
{{Cmd|apk add zabbix zabbix-pgsql zabbix-webif zabbix-setup}}&lt;br /&gt;
&lt;br /&gt;
Now we need to set up the zabbix database. Substitute &#039;*********&#039; in the example below for a real password:&lt;br /&gt;
&lt;br /&gt;
{{Cmd|&amp;lt;nowiki&amp;gt;psql –U postgres&lt;br /&gt;
postgres=# create user zabbix with password &#039;*********&#039;;&lt;br /&gt;
postgres=# create database zabbix owner zabbix;&lt;br /&gt;
postgres=# \q&lt;br /&gt;
cd /usr/share/zabbix/create/schema/&lt;br /&gt;
cat postgresql.sql | psql -U zabbix zabbix&lt;br /&gt;
cd ..&lt;br /&gt;
cd data/&lt;br /&gt;
cat data.sql | psql -U zabbix zabbix&lt;br /&gt;
cat images_pgsql.sql | psql -U zabbix zabbix&amp;lt;/nowiki&amp;gt;}}&lt;br /&gt;
&lt;br /&gt;
Create a softlink for the Zabbix web-frontend files:&lt;br /&gt;
&lt;br /&gt;
{{Cmd|rm /var/www/localhost/htdocs -R&lt;br /&gt;
ln -s /usr/share/webapps/zabbix /var/www/localhost/htdocs}}&lt;br /&gt;
&lt;br /&gt;
Edit PHP configuration to satisfy some zabbix requirements. Edit /etc/php/php.ini and configure the following values at least:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Max_execution_time = 600&lt;br /&gt;
Expose_php = off&lt;br /&gt;
Date.timezone = &amp;lt;insert your timezone here&amp;gt;&lt;br /&gt;
post_max_size = 32M&lt;br /&gt;
upload_max_filesize = 16M&lt;br /&gt;
max_input_time = 600&lt;br /&gt;
memory_limit = 256M&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Configure the following entries in /etc/zabbix/zabbix_server.conf, where DBPassword is the password chosen for the database above:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
DBName=zabbix&lt;br /&gt;
&lt;br /&gt;
# Database user&lt;br /&gt;
&lt;br /&gt;
DBUser=zabbix&lt;br /&gt;
&lt;br /&gt;
# Database password&lt;br /&gt;
# Comment this line if no password used&lt;br /&gt;
&lt;br /&gt;
DBPassword=*********&lt;br /&gt;
&lt;br /&gt;
FpingLocation=/usr/sbin/fping&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Start Zabbix server:&lt;br /&gt;
&lt;br /&gt;
{{Cmd|rc-update add zabbix-server&lt;br /&gt;
/etc/init.d/zabbix-server start}}&lt;br /&gt;
&lt;br /&gt;
Fix permissions on conf directory.&lt;br /&gt;
&lt;br /&gt;
{{Cmd|chown -R lighttpd /usr/share/webapps/zabbix/conf}}&lt;br /&gt;
&lt;br /&gt;
You should now be able to browse to the Zabbix frontend: http://yourservername/.&lt;br /&gt;
&lt;br /&gt;
or&lt;br /&gt;
&lt;br /&gt;
You should now be able to browse to the Zabbix setup frontend: http://yourserverip/instal.php.&lt;br /&gt;
&lt;br /&gt;
Follow the setup instructions to configure Zabbix, supplying the database information used above.&lt;br /&gt;
&lt;br /&gt;
After setup, login using: Login name: &#039;&#039;&#039;Admin&#039;&#039;&#039; Password:&#039;&#039;&#039;zabbix&#039;&#039;&#039;. (as described at http://www.zabbix.com/documentation/1.8/manual/installation)&lt;br /&gt;
&lt;br /&gt;
Finally, Zabbix requires special permissions to use the fping binary.&lt;br /&gt;
&lt;br /&gt;
{{Cmd|chmod u+s /usr/sbin/fping}}&lt;br /&gt;
&lt;br /&gt;
== Install Zabbix Agent on Monitored Servers ==&lt;br /&gt;
&lt;br /&gt;
Zabbix can monitor almost any operating system, including Alpine Linux hosts. Complete the following steps to install the Zabbix agent on Alpine Linux.&lt;br /&gt;
&lt;br /&gt;
{{Note|Support to allow zabbix-agentd to view running processes on Alpine Linux has been added since linux-grsec-2.6.35.9-r2. Please ensure you have that kernel installed prior to attempting to run zabbix-agentd.}}&lt;br /&gt;
&lt;br /&gt;
Ensure that the readproc group exists (support added since alpine-baselayout-2.0_rc1-r1), by adding the following line to /etc/group:&lt;br /&gt;
&lt;br /&gt;
{{Cmd|readproc:x:30:zabbix}}&lt;br /&gt;
&lt;br /&gt;
Install the agent package:&lt;br /&gt;
&lt;br /&gt;
{{Cmd|apk add zabbix-agent}}&lt;br /&gt;
&lt;br /&gt;
Edit the /etc/zabbix/zabbix_agentd.conf file and configure at least the following option:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Server=&amp;lt;ip or hostname of zabbix server&amp;gt;&lt;br /&gt;
Hostname=&amp;lt;ip or hostname of zabbix agent&amp;gt;&lt;br /&gt;
ListenPort=10050&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Start the zabbix-agent:&lt;br /&gt;
&lt;br /&gt;
{{Cmd|rc-update add zabbix-agentd&lt;br /&gt;
/etc/init.d/zabbix-agentd start}}&lt;br /&gt;
&lt;br /&gt;
In case you want to monitor using SNMP agent on remote machines you have to add these packages on zabbix server:&lt;br /&gt;
&lt;br /&gt;
{{Cmd|apk add net-snmp net-snmp-tools}}&lt;br /&gt;
&lt;br /&gt;
And add these packages on remote machines:&lt;br /&gt;
&lt;br /&gt;
{{Cmd|apk add net-snmp }}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Optional: Crash course in adding hosts, checks and notifications ==&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;Note:&#039;&#039; This is optional since it&#039;s not specific to Alpine Linux, but I wanted a couple notes for how to perform a simple check on a server that doesn&#039;t have the agent installed on it, and be notified on state changes.&lt;br /&gt;
&lt;br /&gt;
Administration -&amp;gt; Media Types -&amp;gt; Email&lt;br /&gt;
* Setup server, helo, email from address&lt;br /&gt;
&lt;br /&gt;
Administration -&amp;gt; Users&lt;br /&gt;
* Setup each user who&#039;ll get notified, make sure they have media type &amp;quot;Email&amp;quot; added with their address&lt;br /&gt;
&lt;br /&gt;
Configuration -&amp;gt; Hosts -&amp;gt; Create host&lt;br /&gt;
* In Linux Servers hostgroup&lt;br /&gt;
* Define dns name, ip, connect by IP&lt;br /&gt;
* If the machine is a simple networking device that will only be monitored using SNMP, add it to Template_SNMPv2_Device, and you&#039;re done.&lt;br /&gt;
&lt;br /&gt;
Configuration -&amp;gt; Templates -&amp;gt; Create template&lt;br /&gt;
* Give it a name (Template_Alpine_Linux_Infra_HTTP)&lt;br /&gt;
* In Templates group&lt;br /&gt;
&lt;br /&gt;
Configuration -&amp;gt; Templates -&amp;gt; Template_Alpine_Linux_Infra_HTTP -&amp;gt; Items&lt;br /&gt;
* Create Item&lt;br /&gt;
* Host: Template_Alpine_Linux_Infra_HTTP&lt;br /&gt;
* Description: HTTP Basic Check&lt;br /&gt;
* Type: Simple_check&lt;br /&gt;
* Key: http,80&lt;br /&gt;
&lt;br /&gt;
Configuration -&amp;gt; Templates -&amp;gt; Template_Alpine_Linux_Infra_HTTP -&amp;gt; Triggers&lt;br /&gt;
* Create Trigger&lt;br /&gt;
* Name: &amp;quot;HTTP Trigger&amp;quot;&lt;br /&gt;
* Expression: {Template_Alpine_Linux_Infra_HTTP:http,80.last(0)}#1&lt;br /&gt;
* Severity: High&lt;br /&gt;
&lt;br /&gt;
Configuration -&amp;gt; Actions -&amp;gt; &lt;br /&gt;
* Create Action&lt;br /&gt;
* name: Email notifications&lt;br /&gt;
* Event source: triggers&lt;br /&gt;
* Default Subject: add &amp;quot;{HOST.DNS}:&amp;quot; to the beginning&lt;br /&gt;
* Default message: add &amp;quot;{HOST.DNS}:&amp;quot; to the beginning&lt;br /&gt;
* Conditions: make host have to be from &amp;quot;Linux Servers&amp;quot; hostgroup, and Template_Alpine_Linux_Infra_HTTP:HTTP trigger&amp;quot; is not 1&lt;br /&gt;
* Email affected users&lt;/div&gt;</summary>
		<author><name>Djhughes</name></author>
	</entry>
	<entry>
		<id>https://wiki.alpinelinux.org/w/index.php?title=Zabbix_-_cgi_and_mysql&amp;diff=4944</id>
		<title>Zabbix - cgi and mysql</title>
		<link rel="alternate" type="text/html" href="https://wiki.alpinelinux.org/w/index.php?title=Zabbix_-_cgi_and_mysql&amp;diff=4944"/>
		<updated>2011-02-08T02:40:36Z</updated>

		<summary type="html">&lt;p&gt;Djhughes: added zabbix split packages&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Category:monitoring]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Zabbix Monitoring Solution ==&lt;br /&gt;
&lt;br /&gt;
The purpose of this document is to assist in installing the Zabbix server software and Zabbix agent on the Alpine Linux operating system. Instructions on how to configure and use Zabbix - as well as many useful tutorials - can be found at http://www.zabbix.com.&lt;br /&gt;
&lt;br /&gt;
{{Note|Currently, Zabbix will only work as expected when running on an Alpine Linux system updated from the latest snapshots of the Edge repository. It will be properly supported with the next major version stable release (Alpine 2.2).}}&lt;br /&gt;
&lt;br /&gt;
== Install Lighttpd, and PHP ==&lt;br /&gt;
&lt;br /&gt;
{{:Setting Up Lighttpd With FastCGI}}&lt;br /&gt;
&lt;br /&gt;
== Configure PostgreSQL ==&lt;br /&gt;
&lt;br /&gt;
Setup and configure PostgreSQL:&lt;br /&gt;
&lt;br /&gt;
 apk add postgresql postgresql-client &lt;br /&gt;
 /etc/init.d/postgresql setup&lt;br /&gt;
 /etc/init.d/postgresql start&lt;br /&gt;
 rc-update add postgresql&lt;br /&gt;
&lt;br /&gt;
== Install Zabbix ==&lt;br /&gt;
&lt;br /&gt;
 apk add zabbix zabbix-pgsql zabbix-webif zabbix-setup&lt;br /&gt;
&lt;br /&gt;
Now we need to set up the zabbix database. Substitute &#039;*********&#039; in the example below for a real password:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
psql –U postgres&lt;br /&gt;
postgres=# create user zabbix with password &#039;*********&#039;;&lt;br /&gt;
postgres=# create database zabbix owner zabbix;&lt;br /&gt;
postgres=# \q&lt;br /&gt;
cd /usr/share/zabbix/dbms/create/&lt;br /&gt;
cat postgresql.sql | psql -U zabbix zabbix&lt;br /&gt;
cd data/&lt;br /&gt;
cat data.sql | psql -U zabbix zabbix&lt;br /&gt;
cat images_pgsql.sql | psql -U zabbix zabbix&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Create a softlink for the Zabbix web-frontend files:&lt;br /&gt;
&lt;br /&gt;
 ln -s /usr/share/webapps/zabbix /var/www/localhost/htdocs/zabbix&lt;br /&gt;
&lt;br /&gt;
Edit PHP configuration to satisfy some zabbix requirements. Edit /etc/php/php.ini and configure the following values at least:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Max_execution_time = 600&lt;br /&gt;
Expose_php = off&lt;br /&gt;
Date.timezone = &amp;lt;insert your timezone here&amp;gt;&lt;br /&gt;
post_max_size = 32M&lt;br /&gt;
upload_max_filesize = 16M&lt;br /&gt;
max_input_time = 600&lt;br /&gt;
memory_limit = 256M&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Configure the following entries in /etc/zabbix/zabbix_server.conf, where DBPassword is the password chosen for the database above:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
DBName=zabbix&lt;br /&gt;
&lt;br /&gt;
# Database user&lt;br /&gt;
&lt;br /&gt;
DBUser=zabbix&lt;br /&gt;
&lt;br /&gt;
# Database password&lt;br /&gt;
# Comment this line if no password used&lt;br /&gt;
&lt;br /&gt;
DBPassword=*********&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Start Zabbix server:&lt;br /&gt;
&lt;br /&gt;
 rc-update add zabbix-server&lt;br /&gt;
 /etc/init.d/zabbix-server start&lt;br /&gt;
&lt;br /&gt;
You should now be able to browse to the Zabbix frontend: http://yourservername/zabbix.&lt;br /&gt;
&lt;br /&gt;
Follow the setup instructions to configure Zabbix, supplying the database information used above.&lt;br /&gt;
&lt;br /&gt;
Finally, Zabbix requires special permissions to use the fping binary.&lt;br /&gt;
&lt;br /&gt;
 chmod u+s /usr/sbin/fping&lt;br /&gt;
&lt;br /&gt;
== Install Zabbix Agent on Monitored Servers ==&lt;br /&gt;
&lt;br /&gt;
Zabbix can monitor almost any operating system, including Alpine Linux hosts. Complete the following steps to install the Zabbix agent on Alpine Linux.&lt;br /&gt;
&lt;br /&gt;
{{Note|Support to allow zabbix-agentd to view running processes on Alpine Linux has been added since linux-grsec-2.6.35.9-r2. Please ensure you have that kernel installed prior to attempting to run zabbix-agentd.}}&lt;br /&gt;
&lt;br /&gt;
Ensure that the readproc group exists (support added since alpine-baselayout-2.0_rc1-r1), by adding the following line to /etc/group:&lt;br /&gt;
&lt;br /&gt;
 readproc:x:30:zabbix&lt;br /&gt;
&lt;br /&gt;
Install the agent package:&lt;br /&gt;
&lt;br /&gt;
 apk add zabbix-agent&lt;br /&gt;
&lt;br /&gt;
Edit the /etc/zabbix/zabbix_agentd.conf file and configure at least the following option:&lt;br /&gt;
&lt;br /&gt;
 Server=&amp;lt;ip or hostname of zabbix server&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Start the zabbix-agent:&lt;br /&gt;
&lt;br /&gt;
 rc-update add zabbix-agentd&lt;br /&gt;
 /etc/init.d/zabbix-agentd start&lt;/div&gt;</summary>
		<author><name>Djhughes</name></author>
	</entry>
	<entry>
		<id>https://wiki.alpinelinux.org/w/index.php?title=Zabbix_-_cgi_and_mysql&amp;diff=4882</id>
		<title>Zabbix - cgi and mysql</title>
		<link rel="alternate" type="text/html" href="https://wiki.alpinelinux.org/w/index.php?title=Zabbix_-_cgi_and_mysql&amp;diff=4882"/>
		<updated>2011-01-26T09:29:40Z</updated>

		<summary type="html">&lt;p&gt;Djhughes: zabbix user needs to be in readproc group&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Category:monitoring]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Zabbix Monitoring Solution ==&lt;br /&gt;
&lt;br /&gt;
The purpose of this document is to assist in installing the Zabbix server software and Zabbix agent on the Alpine Linux operating system. Instructions on how to configure and use Zabbix - as well as many useful tutorials - can be found at http://www.zabbix.com.&lt;br /&gt;
&lt;br /&gt;
{{Note|Currently, Zabbix will only work as expected when running on an Alpine Linux system updated from the latest snapshots of the Edge repository. It will be properly supported with the next major version stable release (Alpine 2.2).}}&lt;br /&gt;
&lt;br /&gt;
== Install Lighttpd, and PHP ==&lt;br /&gt;
&lt;br /&gt;
{{:Setting Up Lighttpd With FastCGI}}&lt;br /&gt;
&lt;br /&gt;
== Configure PostgreSQL ==&lt;br /&gt;
&lt;br /&gt;
Setup and configure PostgreSQL:&lt;br /&gt;
&lt;br /&gt;
 apk add postgresql postgresql-client &lt;br /&gt;
 /etc/init.d/postgresql setup&lt;br /&gt;
 /etc/init.d/postgresql start&lt;br /&gt;
 rc-update add postgresql&lt;br /&gt;
&lt;br /&gt;
== Install Zabbix ==&lt;br /&gt;
&lt;br /&gt;
 apk add zabbix&lt;br /&gt;
&lt;br /&gt;
Now we need to set up the zabbix database. Substitute &#039;*********&#039; in the example below for a real password:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
psql –U postgres&lt;br /&gt;
postgres=# create user zabbix with password &#039;*********&#039;;&lt;br /&gt;
postgres=# create database zabbix owner zabbix;&lt;br /&gt;
postgres=# \q&lt;br /&gt;
cd /usr/share/zabbix/dbms/create/&lt;br /&gt;
cat postgresql.sql | psql -U zabbix zabbix&lt;br /&gt;
cd data/&lt;br /&gt;
cat data.sql | psql -U zabbix zabbix&lt;br /&gt;
cat images_pgsql.sql | psql -U zabbix zabbix&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Create a softlink for the Zabbix web-frontend files:&lt;br /&gt;
&lt;br /&gt;
 ln -s /usr/share/webapps/zabbix /var/www/localhost/htdocs/zabbix&lt;br /&gt;
&lt;br /&gt;
Edit PHP configuration to satisfy some zabbix requirements. Edit /etc/php/php.ini and configure the following values at least:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Max_execution_time = 600&lt;br /&gt;
Expose_php = off&lt;br /&gt;
Date.timezone = &amp;lt;insert your timezone here&amp;gt;&lt;br /&gt;
post_max_size = 32M&lt;br /&gt;
upload_max_filesize = 16M&lt;br /&gt;
max_input_time = 600&lt;br /&gt;
memory_limit = 256M&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Configure the following entries in /etc/zabbix/zabbix_server.conf, where DBPassword is the password chosen for the database above:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
DBName=zabbix&lt;br /&gt;
&lt;br /&gt;
# Database user&lt;br /&gt;
&lt;br /&gt;
DBUser=zabbix&lt;br /&gt;
&lt;br /&gt;
# Database password&lt;br /&gt;
# Comment this line if no password used&lt;br /&gt;
&lt;br /&gt;
DBPassword=*********&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Start Zabbix server:&lt;br /&gt;
&lt;br /&gt;
 rc-update add zabbix-server&lt;br /&gt;
 /etc/init.d/zabbix-server start&lt;br /&gt;
&lt;br /&gt;
You should now be able to browse to the Zabbix frontend: http://yourservername/zabbix.&lt;br /&gt;
&lt;br /&gt;
Follow the setup instructions to configure Zabbix, supplying the database information used above.&lt;br /&gt;
&lt;br /&gt;
Finally, Zabbix requires special permissions to use the fping binary.&lt;br /&gt;
&lt;br /&gt;
 chmod u+s /usr/sbin/fping&lt;br /&gt;
&lt;br /&gt;
== Install Zabbix Agent on Monitored Servers ==&lt;br /&gt;
&lt;br /&gt;
Zabbix can monitor almost any operating system, including Alpine Linux hosts. Complete the following steps to install the Zabbix agent on Alpine Linux.&lt;br /&gt;
&lt;br /&gt;
{{Note|Support to allow zabbix-agentd to view running processes on Alpine Linux has been added since linux-grsec-2.6.35.9-r2. Please ensure you have that kernel installed prior to attempting to run zabbix-agentd.}}&lt;br /&gt;
&lt;br /&gt;
Ensure that the readproc group exists (support added since alpine-baselayout-2.0_rc1-r1), by adding the following line to /etc/group:&lt;br /&gt;
&lt;br /&gt;
 readproc:x:30:zabbix&lt;br /&gt;
&lt;br /&gt;
Install the agent package:&lt;br /&gt;
&lt;br /&gt;
 apk add zabbix-agent&lt;br /&gt;
&lt;br /&gt;
Edit the /etc/zabbix/zabbix_agentd.conf file and configure at least the following option:&lt;br /&gt;
&lt;br /&gt;
 Server=&amp;lt;ip or hostname of zabbix server&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Start the zabbix-agent:&lt;br /&gt;
&lt;br /&gt;
 rc-update add zabbix-agentd&lt;br /&gt;
 /etc/init.d/zabbix-agentd start&lt;/div&gt;</summary>
		<author><name>Djhughes</name></author>
	</entry>
	<entry>
		<id>https://wiki.alpinelinux.org/w/index.php?title=Creating_an_Alpine_package&amp;diff=4860</id>
		<title>Creating an Alpine package</title>
		<link rel="alternate" type="text/html" href="https://wiki.alpinelinux.org/w/index.php?title=Creating_an_Alpine_package&amp;diff=4860"/>
		<updated>2011-01-21T09:37:41Z</updated>

		<summary type="html">&lt;p&gt;Djhughes: updated some broken links&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== General ==&lt;br /&gt;
&lt;br /&gt;
This document assumes that you have a working [[Setting up the build environment|build environment]], or use a diskbased alpine installation. &lt;br /&gt;
&lt;br /&gt;
=== The APKBUILDs  ===&lt;br /&gt;
&lt;br /&gt;
The &#039;&#039;[http://git.alpinelinux.org/cgit/abuild/ abuild]&#039;&#039; script reads the &#039;&#039;[http://git.alpinelinux.org/cgit/abuild/tree/sample.APKBUILD APKBUILD]&#039;&#039; and executes the steps needed to create a package. &lt;br /&gt;
&lt;br /&gt;
=== The aports tree  ===&lt;br /&gt;
&lt;br /&gt;
The [http://git.alpinelinux.org/cgit/aports aports] tree is a [http://git.alpinelinux.org/cgit/aports/tree directory tree] with many APKBUILDs. Those files are used when building alpine from source. &lt;br /&gt;
&lt;br /&gt;
== Installing and configuring the alpine-sdk  ==&lt;br /&gt;
&lt;br /&gt;
The alpine-sdk is a metapackage that pulls in the most essential packages used to build new packages.&amp;lt;BR&amp;gt;&lt;br /&gt;
Install those packages now: &lt;br /&gt;
&lt;br /&gt;
  apk add alpine-sdk&lt;br /&gt;
&lt;br /&gt;
This would be a good time to create a normal user account for you to work in. (You weren&#039;t going to develop as root now, were you!) To create the user:&lt;br /&gt;
&lt;br /&gt;
  adduser &amp;lt;yourusername&amp;gt;&lt;br /&gt;
&lt;br /&gt;
To make life easier later, it&#039;s a good idea to add this user to /etc/sudoers. Append the line&lt;br /&gt;
&lt;br /&gt;
&amp;lt;yourusername&amp;gt;    ALL=(ALL) ALL&lt;br /&gt;
&lt;br /&gt;
using the command:&lt;br /&gt;
&lt;br /&gt;
  visudo&lt;br /&gt;
&lt;br /&gt;
Now logout of the root account, and login as &amp;lt;yourusername&amp;gt;. From here on everything can be done in a normal user account, and operations that require superuser privileges can be done with sudo.&lt;br /&gt;
&lt;br /&gt;
The aports tree is in git so before we clone the aports tree we should configure git.&lt;br /&gt;
&lt;br /&gt;
  git config --global user.name &amp;quot;Your Full Name&amp;quot;&lt;br /&gt;
  git config --global user.email &amp;quot;your@email.address&amp;quot;&lt;br /&gt;
&lt;br /&gt;
Now we can clone the aports tree. &lt;br /&gt;
&lt;br /&gt;
  git clone git://dev.alpinelinux.org/aports&lt;br /&gt;
&lt;br /&gt;
Before we start creating or modifying APKBUILD files we need to setup abuild to our system/user. Edit the file abuild.conf to your requirements. Most of the defaults can be left alone, unless you are developing for a custom platform, in which case the comments in the file should guide you. The one field to edit is PACKAGER, so that you can get credit (or blame) for packages you create.&lt;br /&gt;
&lt;br /&gt;
  sudo vi /etc/abuild.conf&lt;br /&gt;
&lt;br /&gt;
We also need to prepare the location that the build process caches files when they are downloaded. By default this is /var/cache/distfiles. To create this directory and ensure that it is writeable, enter the following commands:&lt;br /&gt;
&lt;br /&gt;
  sudo mkdir -p /var/cache/distfiles&lt;br /&gt;
  sudo chmod a+w /var/cache/distfiles&lt;br /&gt;
&lt;br /&gt;
The last step in preparation is to configure the security keys for abuild with the command:&lt;br /&gt;
&lt;br /&gt;
  abuild-keygen -a -i&lt;br /&gt;
&lt;br /&gt;
== Getting some help ==&lt;br /&gt;
&lt;br /&gt;
It might be wise to start by checking what the abuild program can/cannot do.&lt;br /&gt;
&lt;br /&gt;
 abuild -h&lt;br /&gt;
&lt;br /&gt;
== Creating an APKBUILD file  ==&lt;br /&gt;
&lt;br /&gt;
=== Use a template APKBUILD ===&lt;br /&gt;
&lt;br /&gt;
To create the actual APKBUILD file abuild has the option -n (new). It will simply copy an example/template APKBUILD file to the given directory and fill some variables.&amp;lt;BR&amp;gt;&lt;br /&gt;
If you are create a daemon package which needs initd scripts you can add the -c making it: &lt;br /&gt;
&lt;br /&gt;
 abuild -c -n &#039;&#039;packagename&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
{{Note|The &#039;packagename&#039; is a parameter to the -n option so order of -c and -n matters.  Further, on newer Alpine systems, &#039;newapkbuild&#039; has replaced abuild with the -n switch.}}&lt;br /&gt;
&lt;br /&gt;
This will copy the sample initd and confd files to the build directory.&amp;lt;BR&amp;gt;&lt;br /&gt;
A third file sample.install file will be copied as well (we will discuss this later on).&lt;br /&gt;
&lt;br /&gt;
=== Modify your APKBUILD ===&lt;br /&gt;
Edit APKBUILD and fill in the needed info (especially pkgname, pkgver, pkgdesc, url, license, depends and source). &lt;br /&gt;
&lt;br /&gt;
If you are going to use any of the variables for directories like $pkgdir, always make sure they are double quoted like: &lt;br /&gt;
&lt;br /&gt;
 &amp;quot;$pkgdir&amp;quot;/somedir&lt;br /&gt;
&lt;br /&gt;
This will prevent issues with spaces/special characters in the future. &lt;br /&gt;
&lt;br /&gt;
{{Note|If you like syntax highlighting we suggest you to install vim. We have setup vim to recognize the APKBUILD file as a bash scripts so its easier to read them.}}&lt;br /&gt;
&lt;br /&gt;
=== APKBUILD variables/functions  ===&lt;br /&gt;
&lt;br /&gt;
==== source  ====&lt;br /&gt;
&lt;br /&gt;
The source variable is not only used to list the remote source files to fetch, it is also used to list the local files that abuild will need in order to build the apk. Examples of such local files include: init.d files, conf.d files, install files (see [[Creating an Alpine package#install|install variable]]), patches, and all other necessary files.&lt;br /&gt;
&lt;br /&gt;
Here are few things to note:&lt;br /&gt;
&lt;br /&gt;
* When you are finished adding local and/or remote files to &#039;&#039;source&#039;&#039;, you can execute the following command to add their checksums to the APKBUILD file:&lt;br /&gt;
: &amp;lt;pre&amp;gt;abuild checksum&amp;lt;/pre&amp;gt;&lt;br /&gt;
: {{Note|When later updating the content of &#039;&#039;source&#039;&#039;, or updating a file that is listed in &#039;&#039;source&#039;&#039;, you must also update their checksums again with the same command.}}&lt;br /&gt;
&lt;br /&gt;
* When the remote file is hosted at SourceForge, it&#039;s best to specify the special mirrors link used by SourceForge:&lt;br /&gt;
: &amp;lt;pre&amp;gt;http://downloads.sourceforge.net/$pkgname/$pkgname-$pkgver.tar.gz&amp;lt;/pre&amp;gt;&lt;br /&gt;
: (or similar depending on the package).&lt;br /&gt;
&lt;br /&gt;
* When the remote filename is not specified in the URI (ie, does not end in &#039;/software-1.0.tar.gz&#039;), such as:&lt;br /&gt;
: &amp;lt;pre&amp;gt;http://oss.example.org/?get=software&amp;amp;ver=1.0&amp;lt;/pre&amp;gt;&lt;br /&gt;
: You must prepend &#039;saveas-&#039; to the protocol and append &#039;/software-1.0.tar.gz&#039; (for instance) to the end of the URI, like so:&lt;br /&gt;
: &amp;lt;pre&amp;gt;saveas-http://oss.example.org/?get=software&amp;amp;ver=1.0/software-1.0.tar.gz&amp;lt;/pre&amp;gt;&lt;br /&gt;
: This causes the file to be saved as &#039;&#039;software-1.0.tar.gz&#039;&#039; where abuild can use it, instead of &#039;&#039;?get=software&amp;amp;ver=1.0&#039;&#039;, where abuild cannot use it.&lt;br /&gt;
&lt;br /&gt;
* abuild currently supports the following protocols for remote file retrieval:&lt;br /&gt;
** http&lt;br /&gt;
** https&lt;br /&gt;
** ftp&lt;br /&gt;
&lt;br /&gt;
* abuild currently supports the following archive types/archive file extensions:&lt;br /&gt;
** .tar.gz / .tgz&lt;br /&gt;
** .tar.bz2&lt;br /&gt;
** .tar.lzma&lt;br /&gt;
** .tar.xz&lt;br /&gt;
** .zip&lt;br /&gt;
&lt;br /&gt;
==== depends &amp;amp;amp; makedepends  ====&lt;br /&gt;
&lt;br /&gt;
Depends are the actual running dependencies that a package would need when it is running. Makedepends are only needed when you are building a package. If you set a package, in depends you do not need to add it to makedepends as well. The best way to find out what the depends and makedepends of a package are is to [http://en.wikipedia.org/wiki/Rtfm RTFM]. &lt;br /&gt;
&lt;br /&gt;
No kidding, lots of important information can be found it the package INSTALL and README file (or the likes). Another good way is the run ./configure --help from the source directory to see which options are needed for configure to finish without errors. If you do not yet have a src directory you can create one with the command: &lt;br /&gt;
&lt;br /&gt;
 abuild unpack&lt;br /&gt;
&lt;br /&gt;
Running configure will also show you how you can disable a specific option for this package. A good example is for instance &amp;quot;--disable-nls&amp;quot; which will disable native language support and thus does not depend on gettext(libiconv,glib..). &lt;br /&gt;
&lt;br /&gt;
Alpine likes to keep things small, so we try to disable as much as possible without losing too many features. The exact disable/enable options are decided the package builder but please try to follow Alpine&#039;s design concept as much as possible. &lt;br /&gt;
&lt;br /&gt;
An easy way of quickly finding out the build info for a package is to check Arch Linux (Alpine package management and build scripts are similar) or Gentoo linux ebuilds (previous versions of Alpine were based on Gentoo). &lt;br /&gt;
&lt;br /&gt;
* [http://www.gentoo-portage.com Search ebuilds] &lt;br /&gt;
* [http://sources.gentoo.org/viewcvs.py/gentoo-x86/ Gentoo CVS] &lt;br /&gt;
* [http://www.archlinux.org/packages/search/ Arch Linux packages] &lt;br /&gt;
&lt;br /&gt;
After the package is successfully compiled and created we should make sure it didn&#039;t link to any package that is not present in the $depends variable. We do this by using scanelf. If scanelf is not yet installed on your system you can do that by installing pax-utils. &lt;br /&gt;
&lt;br /&gt;
 scanelf -nR pkg&lt;br /&gt;
&lt;br /&gt;
An example output of libcurl would be: &lt;br /&gt;
&lt;br /&gt;
 ET_DYN libssl.so.0.9.8,libcrypto.so.0.9.8,libz.so.1,libc.so.0,ld-uClibc.so.0 pkg/usr/lib/libcurl.so.4.1.1&lt;br /&gt;
&lt;br /&gt;
You can see the needed files and should be able to find out which file belongs to which package.&lt;br /&gt;
&lt;br /&gt;
==== license  ====&lt;br /&gt;
&lt;br /&gt;
If a package has a special/custom license we need to provide it with the release. Because we want to save space and don&#039;t like to have licenses all over our system we have decided to include the license in the doc subpackage. Please follow the following guidelines to add a proper license. Locate the license file inside the source package. Add the doc subpackage to the $subpackages variable as follows: &lt;br /&gt;
&lt;br /&gt;
 subpackages=&amp;quot;$pkgname-doc&amp;quot;&lt;br /&gt;
&lt;br /&gt;
Add a similar line to the following to your build() function, depending on the license description file: &lt;br /&gt;
&lt;br /&gt;
 install -Dm644 COPYING &amp;quot;$pkgdir&amp;quot;/usr/share/licenses/$pkgname/COPYING&lt;br /&gt;
&lt;br /&gt;
If you follow these steps then abuild will automatically add the license to the package-doc apk for you.&lt;br /&gt;
&lt;br /&gt;
==== arch ====&lt;br /&gt;
&lt;br /&gt;
The package architecture(s) to build for.  This can be one of: &#039;&#039;x86, x86_64, all,&#039;&#039; or &#039;&#039;noarch&#039;&#039;, where &#039;&#039;all&#039;&#039; means all architectures, and &#039;&#039;noarch&#039;&#039; means it&#039;s architecture-independent (ie, a pure-python package).&lt;br /&gt;
{{Tip|To determine if your APKBUILD can use &#039;&#039;noarch&#039;&#039;, build the package for your architecture and then run &amp;quot;scanelf -R pkg&amp;quot; from the directory that the APKBUILD resides in, in order to scan for ELF files in the &#039;&#039;./pkg&#039;&#039; directory.  If you do NOT get output from this, then &#039;&#039;noarch&#039;&#039; can be used.}}&lt;br /&gt;
&lt;br /&gt;
==== url  ====&lt;br /&gt;
&lt;br /&gt;
Website address for the program. This is usefully later on when either finding documentation or other information about the package.&lt;br /&gt;
&lt;br /&gt;
==== pkgdesc  ====&lt;br /&gt;
&lt;br /&gt;
A brief, one line, description of what the package does. Useful for the package management system.&lt;br /&gt;
&lt;br /&gt;
Here is an example from apk_info for the OpenSSH client package&lt;br /&gt;
&lt;br /&gt;
 pkgdesc=&amp;quot;Port of OpenBSD&#039;s free SSH release - client&amp;quot;&lt;br /&gt;
&lt;br /&gt;
==== pkgver  ====&lt;br /&gt;
&lt;br /&gt;
Provide the release number of the package you are building.&lt;br /&gt;
&lt;br /&gt;
==== pkgrel  ====&lt;br /&gt;
&lt;br /&gt;
The $pkgrel versioning is made so if you change something to your APKBUILD file without changing the actual $pkgver you can higer pkgrel so apk tools will detect it as an update. For instance if you forget to add a dependency you can add it afterward and you can +1 pkgver so apk finds this update and add the missing dependency. &lt;br /&gt;
&lt;br /&gt;
==== pkgname  ====&lt;br /&gt;
&lt;br /&gt;
The base name of the package you are creating.  For Freeswitch 1.0.6, you would use &amp;quot;freeswitch&amp;quot;&lt;br /&gt;
&lt;br /&gt;
==== install  ====&lt;br /&gt;
&lt;br /&gt;
There are 6 different kinds of install scripts. Each script is called with the $pkgname.&#039;&#039;&amp;lt;action&amp;gt;&#039;&#039; where &#039;&#039;&amp;lt;action&amp;gt;&#039;&#039; is one of the following:&lt;br /&gt;
&lt;br /&gt;
===== $pkgname.pre-install =====&lt;br /&gt;
This script is executed before package is installed. Typical use is when package needs a user/group to be created. For example:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#!/bin/sh&lt;br /&gt;
adduser -H -s /bin/false -D clamav 2&amp;gt;/dev/null&lt;br /&gt;
exit 0&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Note the &#039;&#039;exit 0&#039;&#039; at the end. If the script exits with failure (if the user already exist), the package will not be installed and apk add will exit with failure.&lt;br /&gt;
&lt;br /&gt;
===== $pkgname.post-install =====&lt;br /&gt;
This script is executed after package is installed. Can be used to generate font cache and similar.&lt;br /&gt;
&lt;br /&gt;
===== $pkgname.pre-upgrade =====&lt;br /&gt;
Same as pre-install but is executed before upgrading an already installed package.&lt;br /&gt;
&lt;br /&gt;
===== $pkgname.post-upgrade =====&lt;br /&gt;
Same as post-install but is executed after upgrading an already installed package. &lt;br /&gt;
&lt;br /&gt;
===== $pkgname.pre-deinstall =====&lt;br /&gt;
This script is executed before uninstalling a package. If script exits with failure apk will not uninstall the package.&lt;br /&gt;
&lt;br /&gt;
===== $pkgname.post-deinstall =====&lt;br /&gt;
This script is executed after a package have been uninstalled. Can be used to update font caches and restore busybox links. For example:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#!/bin/sh&lt;br /&gt;
busybox --install -s&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
If the package have an pre-install and post-install script the APKBUILD should have the &#039;&#039;install&#039;&#039; variable defined and the scripts should also be added to the source variable:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
...&lt;br /&gt;
install=&amp;quot;$pkgname.pre-install $pkgname.post-install&amp;quot;&lt;br /&gt;
source=&amp;quot;http://....&lt;br /&gt;
       $install&amp;quot;&lt;br /&gt;
...&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== subpackages  ====&lt;br /&gt;
&lt;br /&gt;
$subpackages are made to split up the normal &amp;quot;make install&amp;quot; into separate packages. The most common subpackages we use are doc and dev. Because we like to keep our target system small we move documentation and development files (only needed when building packages) into separate packages. To use the specific program a user only need to install the base apk without package-doc or package-dev, but if he wants to read the manual he will need to install package-doc. &lt;br /&gt;
&lt;br /&gt;
The easiest way to find out if you need to use -dev and -doc is to first build the package without these options set and wait until the build finishes. When its finished you should have a pkg directory which is the fake root directory. Inside this directory you will see the structure as how it would be installed in / on the target system. &lt;br /&gt;
&lt;br /&gt;
To see if you need the -dev package you can run the following cmd: &lt;br /&gt;
&lt;br /&gt;
 find pkg/usr/ -name &#039;*.[acho]&#039; -o -name &#039;*.la&#039;&lt;br /&gt;
&lt;br /&gt;
If this returns any files you need to include the -dev package. &lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt; To see if you need the -doc package you can run the following cmd: &lt;br /&gt;
&lt;br /&gt;
 find pkg/usr/share -name doc -o -name man -o -name info -o -name html -o -name sgml -o -name licenses&lt;br /&gt;
&lt;br /&gt;
If this returns any directories you need to include the -doc package. &lt;br /&gt;
&lt;br /&gt;
===== Custom subpackages  =====&lt;br /&gt;
&lt;br /&gt;
Some applications will have except doc and dev files other non needed at run time files which we want to separate away from the base package. Some packages include large test suites which are only needed in specific circumstances or binaries which have depends which we prefer not to install. To handle those we create our own package/function. In the APKBUILD below the build() function we create another function: &lt;br /&gt;
&lt;br /&gt;
 test() {&lt;br /&gt;
        mkdir -p &amp;quot;$subpkgdir&amp;quot;/usr&lt;br /&gt;
        mv &amp;quot;$pkgdir&amp;quot;/usr/package-test &amp;quot;$subpkgdir&amp;quot;/usr/&lt;br /&gt;
 }&lt;br /&gt;
 &lt;br /&gt;
&lt;br /&gt;
We also need to add the package info to $subpackages variable: &lt;br /&gt;
&lt;br /&gt;
 subpackages=&amp;quot;$pkgname-doc $pkgname-dev $pkgname-test&amp;quot;&lt;br /&gt;
&lt;br /&gt;
After we finish building the package you should see another apk called packagename-test.apk which includes the files which we moved to the $subpkgdir dir. &lt;br /&gt;
&lt;br /&gt;
The above mentioned variables can also be used in our custom function. If we want for instance to build the test() function with perl support we would add: &lt;br /&gt;
&lt;br /&gt;
 depends=&amp;quot;perl&amp;quot;&lt;br /&gt;
 makedepends=&amp;quot;perl-dev&amp;quot;&lt;br /&gt;
&lt;br /&gt;
If we would install the base package it would not install perl, but if we install the package-test package it would.&lt;br /&gt;
&lt;br /&gt;
==== Patches  ====&lt;br /&gt;
&lt;br /&gt;
Please make sure you always submit human readable patches. Way&#039;s to create them are: &lt;br /&gt;
&lt;br /&gt;
directory compare: &lt;br /&gt;
&lt;br /&gt;
 diff -urp original_directory new_directory &amp;amp;gt; filename.patch&lt;br /&gt;
&lt;br /&gt;
file compare: &lt;br /&gt;
&lt;br /&gt;
 diff -up original.file new.file &amp;amp;gt; filename.patch&lt;br /&gt;
&lt;br /&gt;
If you are going to use multiple patches for a single package, the preferred way to handle those is a loop and numbering the patches. &lt;br /&gt;
&lt;br /&gt;
 for i in &amp;quot;$srcdir&amp;quot;/*.patch; do&lt;br /&gt;
        msg &amp;quot;Applying ${i}&amp;quot;&lt;br /&gt;
        patch -p0 -i $i || return 1&lt;br /&gt;
 done&lt;br /&gt;
&lt;br /&gt;
Because multiple patches can patch the same file, we could create offset for the next patch. To make sure we always patch in a specified way we should number the patches as followed: &lt;br /&gt;
&lt;br /&gt;
 10-patch1.patch 20-patch2.patch 30-patch3.patch&lt;br /&gt;
&lt;br /&gt;
This way we are always sure patch 1 is first and if we want to add additional patches between them we can use 11,12,21,22... &lt;br /&gt;
&lt;br /&gt;
==== Configure options  ====&lt;br /&gt;
&lt;br /&gt;
Alpine has some default configure options we set by default. We use /usr for prefix to make sure everyting is installed with /usr in front of it. If you notice that anything is installed in the wrong directory please run ./configure --help and see if you can set the correct location. &lt;br /&gt;
&lt;br /&gt;
We are not covering the depend switches here we have discussed this already in the depend section. &lt;br /&gt;
&lt;br /&gt;
==== Make options  ====&lt;br /&gt;
&lt;br /&gt;
If you notice weird problems when compiling or installing the package with make/make install you could try to disable [http://www.gnu.org/software/make/manual/make.html#Parallel parallel] building/installing. A normal make line would be: &lt;br /&gt;
&lt;br /&gt;
 make || return 1&lt;br /&gt;
&lt;br /&gt;
To disable parallel we use: &lt;br /&gt;
&lt;br /&gt;
 make -j1 || return 1&lt;br /&gt;
&lt;br /&gt;
We can use the same for make install. &lt;br /&gt;
&lt;br /&gt;
Because we do not want to install the package in our build environment but we want to install it in a fake root directory we need to tell &#039;make install&#039; to use another destination directory instead of &#039;/&#039;. We do this by setting a variable when we execute make install as followed: &lt;br /&gt;
&lt;br /&gt;
 make DESTDIR=&amp;quot;$pkgdir&amp;quot; install&lt;br /&gt;
&lt;br /&gt;
Please note that some Makefiles do not support this variable and will always install software in &#039;/&#039;. To make sure you do not mess up your build system NEVER run your build system as root but always use a custom user and sudo when needed. If by accident the Makefile does not support DESTDIR variable it will fail to install in our build system system directories.&lt;br /&gt;
&lt;br /&gt;
==== Additional files  ====&lt;br /&gt;
&lt;br /&gt;
If you want/need to install additional files not mentioned above you can use the following cmd (this is an example of a conf file): &lt;br /&gt;
&lt;br /&gt;
 install -Dm644 doc/$pkgname.conf &amp;quot;$pkgdir&amp;quot;/etc/$pkgname.conf&lt;br /&gt;
&lt;br /&gt;
== Build the package  ==&lt;br /&gt;
&lt;br /&gt;
If you did not already create the checksums as mentioned above you can do so now: &lt;br /&gt;
&lt;br /&gt;
 cd $pkgname&lt;br /&gt;
 abuild checksum&lt;br /&gt;
&lt;br /&gt;
Its about time we build our package. Because a build system should never have all the package installed to prevent linking to packages we dont want it to link we use a abuild recursively with the -r switch. It will install all dependency&#039;s from your repository and builds it, afterwards it will uninstall all those depending packages again. You could also use the -R switch which would build your package including the dependency packages. &lt;br /&gt;
&lt;br /&gt;
 abuild -r&lt;br /&gt;
&lt;br /&gt;
== Commit your work  ==&lt;br /&gt;
&lt;br /&gt;
After you successfully build your package you can submit your APKBUILD to alpine git repository. &lt;br /&gt;
&lt;br /&gt;
Update you git repo, before adding new files: &lt;br /&gt;
&lt;br /&gt;
 cd $aportsdir&lt;br /&gt;
 git pull&lt;br /&gt;
&lt;br /&gt;
This should pull all the changes made by others into you local git repo. When you think you are ready you can add your files to git: &lt;br /&gt;
&lt;br /&gt;
 cd $apkbuilddir&lt;br /&gt;
 git add APKBUILD (include any other files needed for the build; $pkgname.install...)&lt;br /&gt;
 git commit&lt;br /&gt;
&lt;br /&gt;
Now your changes are only available locally in your repo. Because you do not have push rights to the alpine repo you need to create diff (patch) of the changes you made: &lt;br /&gt;
&lt;br /&gt;
 git format-patch -1&lt;br /&gt;
&lt;br /&gt;
Where -1 sets how many commits you want to go back (mostly this is 1). This should create a patch called 0001......patch. &lt;br /&gt;
&lt;br /&gt;
An easy way to send this patch to the list is with an program called &#039;email&#039;. &lt;br /&gt;
&lt;br /&gt;
 apk_add email&lt;br /&gt;
&lt;br /&gt;
to send to the mailing list you would do: &lt;br /&gt;
&lt;br /&gt;
 email -a 0001...patch alpine-devel@lists.alpinelinux.org&lt;br /&gt;
&lt;br /&gt;
And provide a subject and body after you execute the above cmd. &lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt; If you doubt to which repo your package belongs to you can safely use testing.&lt;br /&gt;
&lt;br /&gt;
== See Also ==&lt;br /&gt;
* [[APKBUILD Reference]]&lt;br /&gt;
* [[Development using git]]&lt;/div&gt;</summary>
		<author><name>Djhughes</name></author>
	</entry>
	<entry>
		<id>https://wiki.alpinelinux.org/w/index.php?title=Upgrading_Alpine_Linux_to_a_new_release_branch&amp;diff=4841</id>
		<title>Upgrading Alpine Linux to a new release branch</title>
		<link rel="alternate" type="text/html" href="https://wiki.alpinelinux.org/w/index.php?title=Upgrading_Alpine_Linux_to_a_new_release_branch&amp;diff=4841"/>
		<updated>2011-01-13T09:55:29Z</updated>

		<summary type="html">&lt;p&gt;Djhughes: minor update&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== General notes ==&lt;br /&gt;
Alpine can be booted from various media.&amp;lt;BR&amp;gt;&lt;br /&gt;
It has also made some adjustments through time and this could also have impact on how a upgrade could be done.&amp;lt;BR&amp;gt;&lt;br /&gt;
These factors makes it hard to make a &#039;general&#039; upgrade instruction that fits all scenarios.&amp;lt;BR&amp;gt;&lt;br /&gt;
The principle is still the same.&lt;br /&gt;
&lt;br /&gt;
To make your upgrade easy, we now present various documents that will help you in your situation.&lt;br /&gt;
&lt;br /&gt;
== What is your *present* setup ==&lt;br /&gt;
You need to know... &lt;br /&gt;
* what alpine version the box (that you are upgrading) is running at this moment.&lt;br /&gt;
* what media you are planning to upgrade (on what media is your alpine distro at this moment).&amp;lt;BR&amp;gt;&#039;&#039;Choose &#039;&#039;&#039;CD&#039;&#039;&#039;, &#039;&#039;&#039;USB&#039;&#039;&#039;, &#039;&#039;&#039;HD/CF&#039;&#039;&#039; or whatever fits your setup.&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Choose your current setup in the below list&lt;br /&gt;
{|&lt;br /&gt;
|&#039;&#039;&#039;alpine-1.9.x or later&#039;&#039;&#039;&lt;br /&gt;
|[[Upgrading_Alpine_-_v1.9.x|All Installation Types]]&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;alpine-1.8.x&#039;&#039;&#039;&lt;br /&gt;
|[[Upgrading_Alpine_-_CD_v1.8.x|CD]]&lt;br /&gt;
|[[Upgrading_Alpine_-_HD_v1.8.x|HD/CF/USB]]&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;alpine-1.7.x&#039;&#039;&#039;&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;alpine-1.6.x&#039;&#039;&#039;&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
! &amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&lt;br /&gt;
! &amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&lt;br /&gt;
! &amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&lt;br /&gt;
! &amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&lt;br /&gt;
|}&lt;/div&gt;</summary>
		<author><name>Djhughes</name></author>
	</entry>
	<entry>
		<id>https://wiki.alpinelinux.org/w/index.php?title=Template:Using_Internet_Repositories_for_apk-tools&amp;diff=4840</id>
		<title>Template:Using Internet Repositories for apk-tools</title>
		<link rel="alternate" type="text/html" href="https://wiki.alpinelinux.org/w/index.php?title=Template:Using_Internet_Repositories_for_apk-tools&amp;diff=4840"/>
		<updated>2011-01-13T09:51:19Z</updated>

		<summary type="html">&lt;p&gt;Djhughes: updated for version 2.1&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Edit the &#039;&#039;&#039;/etc/apk/repositories&#039;&#039;&#039; file and if necessary, add references to the Alpine package repositories. In the example below, the reference to the Alpine CD is maintained, so that if the requested package is available on the local media, it will be obtained from there instead of being downloaded from the remote repository:&lt;br /&gt;
&lt;br /&gt;
 /media/cdrom/apks&lt;br /&gt;
 http://dl-3.alpinelinux.org/alpine/v2.1/packages/main&lt;br /&gt;
&lt;br /&gt;
Only one repository is shown above, however, you may also use these (if you wish to use another version, substitute v2.1 for the desired version (i.e: v1.9, v1.10)):&lt;br /&gt;
 http://dl-4.alpinelinux.org/alpine/v2.1/packages/main&lt;br /&gt;
 http://distrib-coffee.ipsl.jussieu.fr/pub/linux/alpine/alpine/v2.1/packages/main&lt;br /&gt;
 http://dl-2.alpinelinux.org/alpine/v2.1/packages/main&lt;br /&gt;
 http://nl.alpinelinux.org/alpine/v2.1/packages/main&lt;br /&gt;
&lt;br /&gt;
After updating the repositories file, obtain the latest index of available packages:&lt;br /&gt;
{{Cmd|apk update}}&lt;/div&gt;</summary>
		<author><name>Djhughes</name></author>
	</entry>
	<entry>
		<id>https://wiki.alpinelinux.org/w/index.php?title=Upgrading_Alpine_-_v1.9.x&amp;diff=4839</id>
		<title>Upgrading Alpine - v1.9.x</title>
		<link rel="alternate" type="text/html" href="https://wiki.alpinelinux.org/w/index.php?title=Upgrading_Alpine_-_v1.9.x&amp;diff=4839"/>
		<updated>2011-01-13T09:48:35Z</updated>

		<summary type="html">&lt;p&gt;Djhughes: added steps for v2.x&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This document covers upgrading from a previous version of Alpine Linux 1.9 (or 1.10) to newer versions of 1.9 / 1.10 / 2.x. Thanks to many improvements in Alpine Linux 1.9 and later, it is possible to easily upgrade in most scenarios.&lt;br /&gt;
&lt;br /&gt;
All examples/instructions/actions mentioned in this document should be executed on the box that you are planning to upgrade (unless you are instructed otherwise).&lt;br /&gt;
&lt;br /&gt;
== Upgrading an Alpine Linux Hard-disk installation ==&lt;br /&gt;
&lt;br /&gt;
When Alpine Linux is installed to hard drive, upgrading the installation is simple.&lt;br /&gt;
&lt;br /&gt;
{{Using_Internet_Repositories_for_apk-tools}}&lt;br /&gt;
&lt;br /&gt;
{{Note|For upgrading to Alpine 1.9 / 1.10, the following steps apply. Alpine 2.x is treated slightly differently (See below).}}&lt;br /&gt;
&lt;br /&gt;
Ensure you have the latest available version of the Alpine Linux Package Manager first before upgrading anything else:&lt;br /&gt;
{{Cmd|apk add -u apk-tools}}&lt;br /&gt;
&lt;br /&gt;
Finally, upgrade all remaining packages, including the kernel if applicable:&lt;br /&gt;
{{Cmd|apk upgrade&lt;br /&gt;
sync}}&lt;br /&gt;
&lt;br /&gt;
{{Note|For upgrading to Alpine 2.x, the following steps apply.}}&lt;br /&gt;
&lt;br /&gt;
Ensure you have the latest available version of the Alpine Linux Package Manager first before upgrading anything else:&lt;br /&gt;
{{Cmd|apk add -u apk-tools}}&lt;br /&gt;
&lt;br /&gt;
Remove GNU Wget before attempting an upgrade:&lt;br /&gt;
{{Cmd|apk del wget}}&lt;br /&gt;
&lt;br /&gt;
Finally, upgrade all remaining packages, including the kernel. The --available switch is used to force all packages to be upgraded, even if they have the same version number, due to changes in uClibc:&lt;br /&gt;
{{Cmd|apk upgrade --update-cache --available&lt;br /&gt;
sync}}&lt;br /&gt;
&lt;br /&gt;
{{Note|You will need to restart any services that have been upgraded to begin using the upgraded versions. If the kernel is upgraded, you will need to reboot to begin using the upgraded version.}}&lt;br /&gt;
&lt;br /&gt;
== Upgrading Separate Boot Media ==&lt;br /&gt;
&lt;br /&gt;
You may have an installation where the boot media being used (such as a CD, for example) is separate from the media used to store the configuration information. In this case, simply download the latest ISO, and replace the boot media contents with the contents of the latest ISO. If you are booting from a CD, this would simply mean replacing the CD with a CD made from the new image and rebooting the Alpine Linux box. &lt;br /&gt;
&lt;br /&gt;
== Upgrading Alpine Linux on CF/USB ==&lt;br /&gt;
&lt;br /&gt;
Your installation may consist of Alpine Linux running on Compact Flash or USB media. In most cases, it should be sufficient to upgrade most packages using the &#039;&#039;&#039;Alpine Linux Hard-disk Installation&#039;&#039;&#039; upgrade procedures described above. However, for new packages to survive after a reboot, you should enable [[How_to_enable_APK_caching|APK caching]].&lt;br /&gt;
&lt;br /&gt;
{{Warning|As the newer version of alpine may include kernel upgrades, simply pointing the Alpine Linux Package Manager to an Internet-based repository and running &#039;&#039;apk upgrade&#039;&#039; will not be enough, as kernel components are not upgraded when Alpine Linux is run from memory.}}&lt;br /&gt;
&lt;br /&gt;
{{Upgrading_Alpine_environmentvars}}&lt;br /&gt;
&lt;br /&gt;
=== Upgrade Step-by-Step ===&lt;br /&gt;
&lt;br /&gt;
Start by checking that you have enough space on your media.&amp;lt;BR&amp;gt;&lt;br /&gt;
You need at least 400MB available space.&lt;br /&gt;
{{Cmd|df -h | grep &amp;quot;Filesystem\|$LBU_MEDIA&amp;quot;}}&lt;br /&gt;
&lt;br /&gt;
==== Download and verify new release ====&lt;br /&gt;
&lt;br /&gt;
Start downloading a new &#039;.iso&#039; and a &#039;.sha1&#039; file &lt;br /&gt;
{{Cmd|cd /media/$LBU_MEDIA&lt;br /&gt;
wget -c {{#latestalp:alpine|url}}&lt;br /&gt;
wget {{#latestalp:alpine|url}}.sha1}}&lt;br /&gt;
&lt;br /&gt;
Check integrity of the downloaded files &#039;&#039;(it might take some time)&#039;&#039;&lt;br /&gt;
{{Cmd|sha1sum -c {{#latestalp:alpine|file}}.sha1}}&lt;br /&gt;
&#039;&#039;The output of the above command should say &#039;OK&#039;.&amp;lt;BR&amp;gt;&#039;&#039;&lt;br /&gt;
&#039;&#039;If says &#039;FAILED&#039;, delete the iso file and download it again.&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
==== Copy the new release  ====&lt;br /&gt;
{{Note|There is a tool, &#039;&#039;setup-bootable&#039;&#039;, in alpine-1.10.4 and newer, that does the mounting and copying for you. With this tool simply do: {{Cmd|setup-bootable -u {{#latestalp:alpine|file}} /media/$LBU_MEDIA}}&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
Mount the ISO.&lt;br /&gt;
 &lt;br /&gt;
{{Cmd|mount -t iso9660 {{#latestalp:alpine|file}} /mnt}}&lt;br /&gt;
 &lt;br /&gt;
Back up files that you have modified. For example, you might have modified &#039;&#039;syslinux.cfg&#039;&#039; to show console output on a serial port.&amp;lt;BR&amp;gt;&lt;br /&gt;
&lt;br /&gt;
{{Cmd|cp /media/$LBU_MEDIA/syslinux.cfg /media/$LBU_MEDIA/syslinux.cfg.my}}&lt;br /&gt;
&lt;br /&gt;
Install the &#039;&#039;&#039;rsync&#039;&#039;&#039; package if necessary, and copy the files:&lt;br /&gt;
&lt;br /&gt;
{{Cmd|cd /mnt&lt;br /&gt;
apk add rsync&lt;br /&gt;
rsync --delete -rltv .alpine-release * /media/$LBU_MEDIA/}}&lt;br /&gt;
&lt;br /&gt;
Restore your backed up files &#039;&#039;(in case you had any)&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
{{Cmd|mv -f /media/$LBU_MEDIA/syslinux.cfg.my /media/$LBU_MEDIA/syslinux.cfg}}&lt;br /&gt;
&lt;br /&gt;
Make sure that all files are permanently saved in right place &lt;br /&gt;
&lt;br /&gt;
{{Cmd|sync}}&lt;br /&gt;
&lt;br /&gt;
==== Clean up ====&lt;br /&gt;
Clean up the downloaded/unpacked files&lt;br /&gt;
{{Cmd|cd ..&lt;br /&gt;
umount /mnt&lt;br /&gt;
rm /media/$LBU_MEDIA/{{#latestalp:alpine|file}}&lt;br /&gt;
rm /media/$LBU_MEDIA/{{#latestalp:alpine|file}}.sha1}}&lt;br /&gt;
&lt;br /&gt;
=== Save changes ===&lt;br /&gt;
Now that all upgrades are done, we should save our settings to our media (which you hopefully have backed up prior to doing this upgrade).&lt;br /&gt;
{{Cmd|lbu ci}}&lt;br /&gt;
&lt;br /&gt;
=== Load new kernel ===&lt;br /&gt;
In most cases you will need to reboot Alpine Linux (especially if there are changes in the kernel):&lt;br /&gt;
{{Cmd|reboot}}&lt;br /&gt;
{{Note|If you know what you are doing, you might not need to reboot. But make sure that all services affected by the upgrade are restarted.}}&lt;br /&gt;
&lt;br /&gt;
=== Update remaining packages from Web repository ===&lt;br /&gt;
&lt;br /&gt;
* Check that /etc/apk/repositories reflects the current version, for example, for 2.1 it could say:&lt;br /&gt;
 http://dl-3.alpinelinux.org/alpine/v2.1/packages/main&lt;br /&gt;
* Upgrade packages from Web.&lt;br /&gt;
{{Cmd|apk update&lt;br /&gt;
apk add -u apk-tools&lt;br /&gt;
apk upgrade -U}}&lt;/div&gt;</summary>
		<author><name>Djhughes</name></author>
	</entry>
	<entry>
		<id>https://wiki.alpinelinux.org/w/index.php?title=Zabbix_-_cgi_and_mysql&amp;diff=4772</id>
		<title>Zabbix - cgi and mysql</title>
		<link rel="alternate" type="text/html" href="https://wiki.alpinelinux.org/w/index.php?title=Zabbix_-_cgi_and_mysql&amp;diff=4772"/>
		<updated>2011-01-07T07:39:04Z</updated>

		<summary type="html">&lt;p&gt;Djhughes: permissions for fping&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Category:monitoring]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Zabbix Monitoring Solution ==&lt;br /&gt;
&lt;br /&gt;
The purpose of this document is to assist in installing the Zabbix server software and Zabbix agent on the Alpine Linux operating system. Instructions on how to configure and use Zabbix - as well as many useful tutorials - can be found at http://www.zabbix.com.&lt;br /&gt;
&lt;br /&gt;
{{Note|Currently, Zabbix will only work as expected when running on an Alpine Linux system updated from the latest snapshots of the Edge repository. It will be properly supported with the next major version stable release (Alpine 2.2).}}&lt;br /&gt;
&lt;br /&gt;
== Install Lighttpd, and PHP ==&lt;br /&gt;
&lt;br /&gt;
{{:Setting Up Lighttpd With FastCGI}}&lt;br /&gt;
&lt;br /&gt;
== Configure PostgreSQL ==&lt;br /&gt;
&lt;br /&gt;
Setup and configure PostgreSQL:&lt;br /&gt;
&lt;br /&gt;
 apk add postgresql postgresql-client &lt;br /&gt;
 /etc/init.d/postgresql setup&lt;br /&gt;
 /etc/init.d/postgresql start&lt;br /&gt;
 rc-update add postgresql&lt;br /&gt;
&lt;br /&gt;
== Install Zabbix ==&lt;br /&gt;
&lt;br /&gt;
 apk add zabbix&lt;br /&gt;
&lt;br /&gt;
Now we need to set up the zabbix database. Substitute &#039;*********&#039; in the example below for a real password:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
psql –U postgres&lt;br /&gt;
postgres=# create user zabbix with password &#039;*********&#039;;&lt;br /&gt;
postgres=# create database zabbix owner zabbix;&lt;br /&gt;
postgres=# \q&lt;br /&gt;
cd /usr/share/zabbix/dbms/create/&lt;br /&gt;
cat postgresql.sql | psql -U zabbix zabbix&lt;br /&gt;
cd data/&lt;br /&gt;
cat data.sql | psql -U zabbix zabbix&lt;br /&gt;
cat images_pgsql.sql | psql -U zabbix zabbix&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Create a softlink for the Zabbix web-frontend files:&lt;br /&gt;
&lt;br /&gt;
 ln -s /usr/share/webapps/zabbix /var/www/localhost/htdocs/zabbix&lt;br /&gt;
&lt;br /&gt;
Edit PHP configuration to satisfy some zabbix requirements. Edit /etc/php/php.ini and configure the following values at least:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Max_execution_time = 600&lt;br /&gt;
Expose_php = off&lt;br /&gt;
Date.timezone = &amp;lt;insert your timezone here&amp;gt;&lt;br /&gt;
post_max_size = 32M&lt;br /&gt;
upload_max_filesize = 16M&lt;br /&gt;
max_input_time = 600&lt;br /&gt;
memory_limit = 256M&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Configure the following entries in /etc/zabbix/zabbix_server.conf, where DBPassword is the password chosen for the database above:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
DBName=zabbix&lt;br /&gt;
&lt;br /&gt;
# Database user&lt;br /&gt;
&lt;br /&gt;
DBUser=zabbix&lt;br /&gt;
&lt;br /&gt;
# Database password&lt;br /&gt;
# Comment this line if no password used&lt;br /&gt;
&lt;br /&gt;
DBPassword=*********&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Start Zabbix server:&lt;br /&gt;
&lt;br /&gt;
 rc-update add zabbix-server&lt;br /&gt;
 /etc/init.d/zabbix-server start&lt;br /&gt;
&lt;br /&gt;
You should now be able to browse to the Zabbix frontend: http://yourservername/zabbix.&lt;br /&gt;
&lt;br /&gt;
Follow the setup instructions to configure Zabbix, supplying the database information used above.&lt;br /&gt;
&lt;br /&gt;
Finally, Zabbix requires special permissions to use the fping binary.&lt;br /&gt;
&lt;br /&gt;
 chmod u+s /usr/sbin/fping&lt;br /&gt;
&lt;br /&gt;
== Install Zabbix Agent on Monitored Servers ==&lt;br /&gt;
&lt;br /&gt;
Zabbix can monitor almost any operating system, including Alpine Linux hosts. Complete the following steps to install the Zabbix agent on Alpine Linux.&lt;br /&gt;
&lt;br /&gt;
{{Note|Support to allow zabbix-agentd to view running processes on Alpine Linux has been added since linux-grsec-2.6.35.9-r2. Please ensure you have that kernel installed prior to attempting to run zabbix-agentd.}}&lt;br /&gt;
&lt;br /&gt;
Ensure that the readproc group exists (support added since alpine-baselayout-2.0_rc1-r1), by adding the following line to /etc/group:&lt;br /&gt;
&lt;br /&gt;
 readproc:x:30:&lt;br /&gt;
&lt;br /&gt;
Install the agent package:&lt;br /&gt;
&lt;br /&gt;
 apk add zabbix-agent&lt;br /&gt;
&lt;br /&gt;
Edit the /etc/zabbix/zabbix_agentd.conf file and configure at least the following option:&lt;br /&gt;
&lt;br /&gt;
 Server=&amp;lt;ip or hostname of zabbix server&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Start the zabbix-agent:&lt;br /&gt;
&lt;br /&gt;
 rc-update add zabbix-agentd&lt;br /&gt;
 /etc/init.d/zabbix-agentd start&lt;/div&gt;</summary>
		<author><name>Djhughes</name></author>
	</entry>
	<entry>
		<id>https://wiki.alpinelinux.org/w/index.php?title=Zabbix_-_cgi_and_mysql&amp;diff=4693</id>
		<title>Zabbix - cgi and mysql</title>
		<link rel="alternate" type="text/html" href="https://wiki.alpinelinux.org/w/index.php?title=Zabbix_-_cgi_and_mysql&amp;diff=4693"/>
		<updated>2010-12-16T02:46:46Z</updated>

		<summary type="html">&lt;p&gt;Djhughes: use readproc group for zabbix-agentd&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Category:monitoring]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Zabbix Monitoring Solution ==&lt;br /&gt;
&lt;br /&gt;
The purpose of this document is to assist in installing the Zabbix server software and Zabbix agent on the Alpine Linux operating system. Instructions on how to configure and use Zabbix - as well as many useful tutorials - can be found at http://www.zabbix.com.&lt;br /&gt;
&lt;br /&gt;
{{Note|Currently, Zabbix will only work as expected when running on an Alpine Linux system updated from the latest snapshots of the Edge repository. It will be properly supported with the next major version stable release (Alpine 2.2).}}&lt;br /&gt;
&lt;br /&gt;
== Install Lighttpd, and PHP ==&lt;br /&gt;
&lt;br /&gt;
{{:Setting Up Lighttpd With FastCGI}}&lt;br /&gt;
&lt;br /&gt;
== Configure PostgreSQL ==&lt;br /&gt;
&lt;br /&gt;
Setup and configure PostgreSQL:&lt;br /&gt;
&lt;br /&gt;
 apk add postgresql postgresql-client &lt;br /&gt;
 /etc/init.d/postgresql setup&lt;br /&gt;
 /etc/init.d/postgresql start&lt;br /&gt;
 rc-update add postgresql&lt;br /&gt;
&lt;br /&gt;
== Install Zabbix ==&lt;br /&gt;
&lt;br /&gt;
 apk add zabbix&lt;br /&gt;
&lt;br /&gt;
Now we need to set up the zabbix database. Substitute &#039;*********&#039; in the example below for a real password:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
psql –U postgres&lt;br /&gt;
postgres=# create user zabbix with password &#039;*********&#039;;&lt;br /&gt;
postgres=# create database zabbix owner zabbix;&lt;br /&gt;
postgres=# \q&lt;br /&gt;
cd /usr/share/zabbix/dbms/create/&lt;br /&gt;
cat postgresql.sql | psql -U zabbix zabbix&lt;br /&gt;
cd data/&lt;br /&gt;
cat data.sql | psql -U zabbix zabbix&lt;br /&gt;
cat images_pgsql.sql | psql -U zabbix zabbix&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Create a softlink for the Zabbix web-frontend files:&lt;br /&gt;
&lt;br /&gt;
 ln -s /usr/share/webapps/zabbix /var/www/localhost/htdocs/zabbix&lt;br /&gt;
&lt;br /&gt;
Edit PHP configuration to satisfy some zabbix requirements. Edit /etc/php/php.ini and configure the following values at least:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Max_execution_time = 600&lt;br /&gt;
Expose_php = off&lt;br /&gt;
Date.timezone = &amp;lt;insert your timezone here&amp;gt;&lt;br /&gt;
post_max_size = 32M&lt;br /&gt;
upload_max_filesize = 16M&lt;br /&gt;
max_input_time = 600&lt;br /&gt;
memory_limit = 256M&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Configure the following entries in /etc/zabbix/zabbix_server.conf, where DBPassword is the password chosen for the database above:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
DBName=zabbix&lt;br /&gt;
&lt;br /&gt;
# Database user&lt;br /&gt;
&lt;br /&gt;
DBUser=zabbix&lt;br /&gt;
&lt;br /&gt;
# Database password&lt;br /&gt;
# Comment this line if no password used&lt;br /&gt;
&lt;br /&gt;
DBPassword=*********&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Start Zabbix server:&lt;br /&gt;
&lt;br /&gt;
 rc-update add zabbix-server&lt;br /&gt;
 /etc/init.d/zabbix-server start&lt;br /&gt;
&lt;br /&gt;
You should now be able to browse to the Zabbix frontend: http://yourservername/zabbix.&lt;br /&gt;
&lt;br /&gt;
Follow the setup instructions to configure Zabbix, supplying the database information used above.&lt;br /&gt;
&lt;br /&gt;
== Install Zabbix Agent on Monitored Servers ==&lt;br /&gt;
&lt;br /&gt;
Zabbix can monitor almost any operating system, including Alpine Linux hosts. Complete the following steps to install the Zabbix agent on Alpine Linux.&lt;br /&gt;
&lt;br /&gt;
{{Note|Support to allow zabbix-agentd to view running processes on Alpine Linux has been added since linux-grsec-2.6.35.9-r2. Please ensure you have that kernel installed prior to attempting to run zabbix-agentd.}}&lt;br /&gt;
&lt;br /&gt;
Ensure that the readproc group exists (support added since alpine-baselayout-2.0_rc1-r1), by adding the following line to /etc/group:&lt;br /&gt;
&lt;br /&gt;
 readproc:x:30:&lt;br /&gt;
&lt;br /&gt;
Install the agent package:&lt;br /&gt;
&lt;br /&gt;
 apk add zabbix-agent&lt;br /&gt;
&lt;br /&gt;
Edit the /etc/zabbix/zabbix_agentd.conf file and configure at least the following option:&lt;br /&gt;
&lt;br /&gt;
 Server=&amp;lt;ip or hostname of zabbix server&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Start the zabbix-agent:&lt;br /&gt;
&lt;br /&gt;
 rc-update add zabbix-agentd&lt;br /&gt;
 /etc/init.d/zabbix-agentd start&lt;/div&gt;</summary>
		<author><name>Djhughes</name></author>
	</entry>
	<entry>
		<id>https://wiki.alpinelinux.org/w/index.php?title=Zabbix_-_cgi_and_mysql&amp;diff=4685</id>
		<title>Zabbix - cgi and mysql</title>
		<link rel="alternate" type="text/html" href="https://wiki.alpinelinux.org/w/index.php?title=Zabbix_-_cgi_and_mysql&amp;diff=4685"/>
		<updated>2010-12-09T03:35:54Z</updated>

		<summary type="html">&lt;p&gt;Djhughes: Updated documentation&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Category:monitoring]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Zabbix Monitoring Solution ==&lt;br /&gt;
&lt;br /&gt;
The purpose of this document is to assist in installing the Zabbix server software and Zabbix agent on the Alpine Linux operating system. Instructions on how to configure and use Zabbix - as well as many useful tutorials - can be found at http://www.zabbix.com.&lt;br /&gt;
&lt;br /&gt;
{{Note|Currently, Zabbix will only work as expected when running on an Alpine Linux system updated from the latest snapshots of the Edge repository. It will be properly supported with the next major version stable release (Alpine 2.2).}}&lt;br /&gt;
&lt;br /&gt;
== Install Lighttpd, and PHP ==&lt;br /&gt;
&lt;br /&gt;
{{:Setting Up Lighttpd With FastCGI}}&lt;br /&gt;
&lt;br /&gt;
== Configure PostgreSQL ==&lt;br /&gt;
&lt;br /&gt;
Setup and configure PostgreSQL:&lt;br /&gt;
&lt;br /&gt;
 apk add postgresql postgresql-client &lt;br /&gt;
 /etc/init.d/postgresql setup&lt;br /&gt;
 /etc/init.d/postgresql start&lt;br /&gt;
 rc-update add postgresql&lt;br /&gt;
&lt;br /&gt;
== Install Zabbix ==&lt;br /&gt;
&lt;br /&gt;
 apk add zabbix&lt;br /&gt;
&lt;br /&gt;
Now we need to set up the zabbix database. Substitute &#039;*********&#039; in the example below for a real password:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
psql –U postgres&lt;br /&gt;
postgres=# create user zabbix with password &#039;*********&#039;;&lt;br /&gt;
postgres=# create database zabbix owner zabbix;&lt;br /&gt;
postgres=# \q&lt;br /&gt;
cd /usr/share/zabbix/dbms/create/&lt;br /&gt;
cat postgresql.sql | psql -U zabbix zabbix&lt;br /&gt;
cd data/&lt;br /&gt;
cat data.sql | psql -U zabbix zabbix&lt;br /&gt;
cat images_pgsql.sql | psql -U zabbix zabbix&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Create a softlink for the Zabbix web-frontend files:&lt;br /&gt;
&lt;br /&gt;
 ln -s /usr/share/webapps/zabbix /var/www/localhost/htdocs/zabbix&lt;br /&gt;
&lt;br /&gt;
Edit PHP configuration to satisfy some zabbix requirements. Edit /etc/php/php.ini and configure the following values at least:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Max_execution_time = 600&lt;br /&gt;
Expose_php = off&lt;br /&gt;
Date.timezone = &amp;lt;insert your timezone here&amp;gt;&lt;br /&gt;
post_max_size = 32M&lt;br /&gt;
upload_max_filesize = 16M&lt;br /&gt;
max input time = 600&lt;br /&gt;
memory limit = 256M&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Configure the following entries in /etc/zabbix/zabbix_server.conf, where DBPassword is the password chosen for the database above:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
DBName=zabbix&lt;br /&gt;
&lt;br /&gt;
# Database user&lt;br /&gt;
&lt;br /&gt;
DBUser=zabbix&lt;br /&gt;
&lt;br /&gt;
# Database password&lt;br /&gt;
# Comment this line if no password used&lt;br /&gt;
&lt;br /&gt;
DBPassword=*********&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Start Zabbix server:&lt;br /&gt;
&lt;br /&gt;
 rc-update add zabbix-server&lt;br /&gt;
 /etc/init.d/zabbix-server start&lt;br /&gt;
&lt;br /&gt;
You should now be able to browse to the Zabbix frontend: http://yourservername/zabbix.&lt;br /&gt;
&lt;br /&gt;
Follow the setup instructions to configure Zabbix, supplying the database information used above.&lt;br /&gt;
&lt;br /&gt;
== Install Zabbix Agent on Monitored Servers ==&lt;br /&gt;
&lt;br /&gt;
Zabbix can monitor almost any operating system, including Alpine Linux hosts. Complete the following steps to install the Zabbix agent on Alpine Linux.&lt;br /&gt;
&lt;br /&gt;
Install the agent package:&lt;br /&gt;
&lt;br /&gt;
 apk add zabbix-agent&lt;br /&gt;
&lt;br /&gt;
Edit the /etc/zabbix/zabbix_agentd.conf file and configure at least the following option:&lt;br /&gt;
&lt;br /&gt;
 Server=&amp;lt;ip or hostname of zabbix server&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Start the zabbix-agent:&lt;br /&gt;
&lt;br /&gt;
 rc-update add zabbix-agentd&lt;br /&gt;
 /etc/init.d/zabbix-agentd start&lt;/div&gt;</summary>
		<author><name>Djhughes</name></author>
	</entry>
	<entry>
		<id>https://wiki.alpinelinux.org/w/index.php?title=ISP_Mail_Server_HowTo&amp;diff=4349</id>
		<title>ISP Mail Server HowTo</title>
		<link rel="alternate" type="text/html" href="https://wiki.alpinelinux.org/w/index.php?title=ISP_Mail_Server_HowTo&amp;diff=4349"/>
		<updated>2010-08-27T14:49:48Z</updated>

		<summary type="html">&lt;p&gt;Djhughes: restart services&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Category:mail]]&lt;br /&gt;
== A Full Service Mail Server ==&lt;br /&gt;
&lt;br /&gt;
The goal of this document is to describe how to set up postfix, dovecot, clamav, dspam, roundecube, and postfixadmin for a full-featured &amp;quot;ISP&amp;quot; level mail server.&lt;br /&gt;
&lt;br /&gt;
The server must provide:&lt;br /&gt;
&lt;br /&gt;
* multiple virtual domains&lt;br /&gt;
* admins for each domain (to add/remove virtual accounts)&lt;br /&gt;
* Quota support per domain / account&lt;br /&gt;
* downloading email via IMAP / IMAPS / POP3 / POP3S&lt;br /&gt;
* relaying email for authenticated users with TLS or SSL (Submission / SMTPS protocol)&lt;br /&gt;
* Standard filters (virus/spam/rbl/etc)&lt;br /&gt;
* Web mail client&lt;br /&gt;
* Value Add services&lt;br /&gt;
&lt;br /&gt;
== Set up Lighttpd + PHP ==&lt;br /&gt;
&lt;br /&gt;
PostfixAdmin needs php pgpsql and imap modules, so we do it in this step.&lt;br /&gt;
&lt;br /&gt;
  apk add lighttpd php php-pgsql php-imap&lt;br /&gt;
&lt;br /&gt;
Stop and remove mini_httpd, and move ACF to lighttpd;  We are setting this up to be a multi-domain virtual web server (replace host.example.com with the actual domain):&lt;br /&gt;
&lt;br /&gt;
  /etc/init.d/mini_httpd stop&lt;br /&gt;
  apk del mini_httpd&lt;br /&gt;
  mkdir -p /var/www/domains/host.example.com/www&lt;br /&gt;
  ln -s /usr/share/acf/www /var/www/domains/host.example.com/www/acf&lt;br /&gt;
&lt;br /&gt;
Edit /var/www/domains/host.example.com/index.html to put a simple redirection page:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;lt;!DOCTYPE HTML PUBLIC &amp;quot;-//W3C//DTD HTML 4.01//EN&amp;quot; &amp;quot;http://www.w3.org/TR/html4/strict.dtd&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;html lang=&amp;quot;en&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;head&amp;gt;&lt;br /&gt;
&amp;lt;meta http-equiv=&amp;quot;Content-Type&amp;quot; content=&amp;quot;text/html; charset=ISO-8859-1&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;title&amp;gt;host.example.com Redirector&amp;lt;/title&amp;gt;&lt;br /&gt;
&amp;lt;/head&amp;gt;&lt;br /&gt;
&amp;lt;body&amp;gt;&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;&amp;lt;a href=&amp;quot;/acf&amp;quot;&amp;gt;ACF&amp;lt;/a&amp;gt;&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;&amp;lt;a href=&amp;quot;/postfixadmin&amp;quot;&amp;gt;PostfixAdmin&amp;lt;/a&amp;gt;&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;&amp;lt;a href=&amp;quot;/roundcube&amp;quot;&amp;gt;Roundcube&amp;lt;/a&amp;gt;&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
&amp;lt;/body&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Edit /etc/lighttpd/mod_cgi.conf to serve haserl files by adding a &amp;quot;&amp;quot; =&amp;gt; &amp;quot;&amp;quot; cgi handler and to treat /acf/cgi-bin as a CGI directory (remove the &#039;^&#039;)&lt;br /&gt;
&lt;br /&gt;
 $HTTP[&amp;quot;url&amp;quot;] =~ &amp;quot;/cgi-bin/&amp;quot; {&lt;br /&gt;
     # disable directory listings&lt;br /&gt;
     dir-listing.activate = &amp;quot;disable&amp;quot;&lt;br /&gt;
     # only allow cgi&#039;s in this directory&lt;br /&gt;
     cgi.assign = (&lt;br /&gt;
 		&amp;quot;.pl&amp;quot;	=&amp;gt;	&amp;quot;/usr/bin/perl&amp;quot;,&lt;br /&gt;
 		&amp;quot;.cgi&amp;quot;	=&amp;gt;	&amp;quot;/usr/bin/perl&amp;quot;,&lt;br /&gt;
 		&amp;quot;&amp;quot; =&amp;gt; &amp;quot;&amp;quot;&lt;br /&gt;
 	)&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
Get a web certificate, and install it.  You have two options: 1. If you want to use a self-signed cert, you can use the instructions found at [[Generating SSL certs with ACF]] or [[Generating SSL certs with ACF 1.9]] to generate it. 2. Use the certificate created with the &#039;&#039;&#039;setup-acf&#039;&#039;&#039; command. &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Option 1:&#039;&#039;&#039;&lt;br /&gt;
If you create your own self-signed certificate, you can create the &amp;quot;server-bundle.pem&amp;quot; and the &amp;quot;ca-crt.pem&amp;quot; file with these commands:&lt;br /&gt;
&lt;br /&gt;
  openssl pkcs12 -nokeys -cacerts -in certificate.pfx  -out /etc/lighttpd/ca-crt.pem&lt;br /&gt;
  openssl pkcs12 -nodes -in certificate.pfx -out /etc/lighttpd/server-bundle.pem&lt;br /&gt;
  chown root:root /etc/lighttpd/server-bundle.pem&lt;br /&gt;
  chmod 400 /etc/lighttpd/server-bundle.pem&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Note:&#039;&#039;&#039; The server certificate &#039;&#039;and&#039;&#039; key are in the server-bundle.pem file, so it is critical that the file be read-only by user &amp;quot;root&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Option 2:&#039;&#039;&#039;&lt;br /&gt;
If you prefer to just use the default certificate created with the &#039;&#039;&#039;setup-acf&#039;&#039;&#039; command, then you will need to do the following:&lt;br /&gt;
&lt;br /&gt;
  setup-acf&lt;br /&gt;
&lt;br /&gt;
During the above process, mini_httpd will be started, if it isn&#039;t already, and a certificate will be created. Once you have completed the setup-acf steps, do the following to move the certificate files to the correct location for lighttpd to use.&lt;br /&gt;
&lt;br /&gt;
  mv /etc/ssl/mini_httpd/server.pem /etc/lighttpd/server-bundle.pem&lt;br /&gt;
  chown root:root /etc/lighttpd/server-bundle.pem&lt;br /&gt;
  chmod 400 /etc/lighttpd/server-bundle.pem&lt;br /&gt;
&lt;br /&gt;
Add these lines to /etc/lighttpd/lighttpd.conf to point to the new document root, and set it up to listen on port 443 (replace &#039;&#039;host.example.com&#039;&#039; with the actual domain and &#039;&#039;ip_address_of_server&#039;&#039; with the actual IP address):&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
simple-vhost.server-root   = &amp;quot;/var/www/domains/&amp;quot;&lt;br /&gt;
simple-vhost.default-host  = &amp;quot;/host.example.com/&amp;quot;&lt;br /&gt;
simple-vhost.document-root = &amp;quot;www/&amp;quot;&lt;br /&gt;
&lt;br /&gt;
$SERVER[&amp;quot;socket&amp;quot;] == &amp;quot;ip_address_of_server:443&amp;quot; {&lt;br /&gt;
ssl.engine    = &amp;quot;enable&amp;quot;&lt;br /&gt;
ssl.pemfile   = &amp;quot;/etc/lighttpd/server-bundle.pem&amp;quot;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
If you went with Option 1 above, then add an additional line underneath the ssl.pemfile line, so that the section appears as follows:&lt;br /&gt;
&lt;br /&gt;
  $SERVER[&amp;quot;socket&amp;quot;] == &amp;quot;ip_address_of_server:443&amp;quot; {&lt;br /&gt;
  ssl.engine    = &amp;quot;enable&amp;quot;&lt;br /&gt;
  ssl.pemfile   = &amp;quot;/etc/lighttpd/server-bundle.pem&amp;quot;&lt;br /&gt;
  ssl.ca-file   = &amp;quot;/etc/lighttpd/ca-crt.pem&amp;quot;&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
Ensure that the simple_vhosts module is loaded, as well as the cgi config scripts by uncommenting the following lines in /etc/lighttpd/lighttpd.conf&lt;br /&gt;
&lt;br /&gt;
 server.modules = (&lt;br /&gt;
     #  other modules may be listed&lt;br /&gt;
     &amp;quot;mod_simple_vhost&amp;quot;, &lt;br /&gt;
     #  other modules may be listed&lt;br /&gt;
  .&lt;br /&gt;
  .&lt;br /&gt;
  .&lt;br /&gt;
     include &amp;quot;mod_cgi.conf&amp;quot;&lt;br /&gt;
 &lt;br /&gt;
     include &amp;quot;mod_fastcgi.conf&amp;quot;&lt;br /&gt;
&lt;br /&gt;
Stop and remove mini_httpd; start lighttpd, test&lt;br /&gt;
&lt;br /&gt;
  /etc/init.d/mini_httpd stop&lt;br /&gt;
  rc-update del mini_httpd&lt;br /&gt;
  apk del mini_httpd&lt;br /&gt;
  rc-update add lighttpd&lt;br /&gt;
  /etc/init.d/lighttpd start&lt;br /&gt;
&lt;br /&gt;
At this point you should be able to see ACF being served with lighttpd (Note: this will work well with alpine 1.10. With earlier versions there will be problems.)  https://host.example.com/acf/&lt;br /&gt;
&lt;br /&gt;
== Install Postgresql ==&lt;br /&gt;
&lt;br /&gt;
Add and configure postgresql&lt;br /&gt;
&lt;br /&gt;
  apk add acf-postgresql postgresql-client&lt;br /&gt;
  /etc/init.d/postgresql setup&lt;br /&gt;
  /etc/init.d/postgresql start&lt;br /&gt;
  rc-update add postgresql&lt;br /&gt;
&lt;br /&gt;
At this point any user can connect to the sql server with &amp;quot;trust&amp;quot; mechanism.  If you want to enforce password authentication (you probably do) edit /var/lib/postgresql/8.4/data/pg_hba.conf&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
  Editme: What should we recommend?&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Create the postfix database:&lt;br /&gt;
&lt;br /&gt;
  psql -U postgres&lt;br /&gt;
   create user postfix with password &#039;******&#039;;&lt;br /&gt;
   create database postfix owner postfix;&lt;br /&gt;
   \c postfix&lt;br /&gt;
   create language plpgsql;&lt;br /&gt;
   \q&lt;br /&gt;
&lt;br /&gt;
(Of course, use your selected password where ******* is shown above.)&lt;br /&gt;
&lt;br /&gt;
== Install PostfixAdmin ==&lt;br /&gt;
&lt;br /&gt;
We are going to install the postfix admin web front-end before we install the mail server.  This just creates an interface to populate the SQL tables that postfix and dovecot will use.&lt;br /&gt;
&lt;br /&gt;
Download PostfixAdmin from Sourceforge.  When these instructions were written, 2.3 was the current release, so (replace host.example.com with the actual domain):&lt;br /&gt;
&lt;br /&gt;
 wget http://downloads.sourceforge.net/project/postfixadmin/postfixadmin/postfixadmin-2.3.2/postfixadmin-2.3.2.tar.gz&lt;br /&gt;
 tar zxvf postfixadmin-2.3.2.tar.gz&lt;br /&gt;
 mkdir -p /var/www/domains/host.example.com/www/postfixadmin&lt;br /&gt;
 mv  postfixadmin-2.3.2/* /var/www/domains/host.example.com/www/postfixadmin&lt;br /&gt;
 rm -rf postfixadmin*&lt;br /&gt;
&lt;br /&gt;
Edit /var/www/domains/host.example.com/www/postfixadmin/config.inc.php and modify at least these lines (replace host.example.com with the actual domain):&lt;br /&gt;
&lt;br /&gt;
 $CONF[&#039;configured&#039;] = true;&lt;br /&gt;
 $CONF[&#039;setup_password&#039;] = &amp;quot;&amp;quot;;  &amp;lt;&amp;lt; Don&#039;t change this yet&lt;br /&gt;
 $CONF[&#039;database_type&#039;] = &#039;pgsql&#039;;&lt;br /&gt;
 $CONF[&#039;database_host&#039;] = &#039;localhost&#039;;&lt;br /&gt;
 $CONF[&#039;database_user&#039;] = &#039;postfix&#039;;&lt;br /&gt;
 $CONF[&#039;database_password&#039;] = &#039;*****&#039;;   &amp;lt;&amp;lt; The password you chose above&lt;br /&gt;
 $CONF[&#039;database_name&#039;] = &#039;postfix&#039;;&lt;br /&gt;
 $CONF[&#039;database_prefix&#039;] = &amp;quot;&amp;quot;;&lt;br /&gt;
 $CONF[&#039;admin_email&#039;] = &#039;you@some.email.com&#039;;  &amp;lt;&amp;lt; Your email address &lt;br /&gt;
 $CONF[&#039;encrypt&#039;] = &#039;md5crypt&#039;;&lt;br /&gt;
 $CONF[&#039;authlib_default_flavor&#039;] = &#039;md5raw&#039;;&lt;br /&gt;
 $CONF[&#039;dovecotpw&#039;] = &amp;quot;/usr/sbin/dovecotpw&amp;quot;;&lt;br /&gt;
 $CONF[&#039;domain_path&#039;] = &#039;YES&#039;;&lt;br /&gt;
 $CONF[&#039;domain_in_mailbox&#039;] = &#039;NO&#039;;&lt;br /&gt;
 $CONF[&#039;aliases&#039;] = &#039;10&#039;;                       &lt;br /&gt;
 $CONF[&#039;mailboxes&#039;] = &#039;10&#039;;&lt;br /&gt;
 $CONF[&#039;maxquota&#039;] = &#039;10&#039;;&lt;br /&gt;
 $CONF[&#039;quota&#039;] = &#039;YES&#039;;&lt;br /&gt;
 $CONF[&#039;quota_multiplier&#039;] = &#039;1024000&#039;;&lt;br /&gt;
 $CONF[&#039;vacation&#039;] = &#039;NO&#039;; &lt;br /&gt;
 $CONF[&#039;vacation_control&#039;] =&#039;NO&#039;;&lt;br /&gt;
 $CONF[&#039;vacation_control_admin&#039;] = &#039;NO&#039;;&lt;br /&gt;
 $CONF[&#039;alias_control&#039;] = &#039;YES&#039;;&lt;br /&gt;
 $CONF[&#039;alias_control_admin&#039;] = &#039;YES&#039;;&lt;br /&gt;
 $CONF[&#039;special_alias_control&#039;] = &#039;YES&#039;;&lt;br /&gt;
 $CONF[&#039;fetchmail&#039;] = &#039;NO&#039;;&lt;br /&gt;
 $CONF[&#039;user_footer_link&#039;] = &amp;quot;http://host.example.com/postfixadmin&amp;quot;;&lt;br /&gt;
 $CONF[&#039;footer_link&#039;] = &#039;http://host.example.com/postfixadmin/main.php&#039;;&lt;br /&gt;
 $CONF[&#039;create_mailbox_subdirs_prefix&#039;]=&amp;quot;&amp;quot;;  &lt;br /&gt;
 $CONF[&#039;used_quotas&#039;] = &#039;YES&#039;;   &lt;br /&gt;
 $CONF[&#039;new_quota_table&#039;] = &#039;YES&#039;;  &lt;br /&gt;
&lt;br /&gt;
You should further edit /var/www/domains/host.example.com/www/postfixadmin/config.inc.php and replace all instances of &amp;quot;change-this-to-your.domain.tld&amp;quot; with your actual mail domain. This can be done with busybox sed (replace example.com with your domain name):&lt;br /&gt;
&lt;br /&gt;
 sed -i -e &#039;s/change-this-to-your.domain.tld/example.com/g&#039; /var/www/domains/host.example.com/www/postfixadmin/config.inc.php&lt;br /&gt;
&lt;br /&gt;
Go to https://host.example.com/postfixadmin/setup.php&lt;br /&gt;
&lt;br /&gt;
Create the password hash, add it to the config.inc.php file&lt;br /&gt;
&lt;br /&gt;
Go back to https://host.example.com/postfixadmin/setup.php&lt;br /&gt;
&lt;br /&gt;
Create superadmin account.&lt;br /&gt;
&lt;br /&gt;
== Install Postfix ==&lt;br /&gt;
&lt;br /&gt;
Create a user for the virtual mail delivery, and get its uid/gid (you&#039;ll need the numeric uid/gid for postfix)&lt;br /&gt;
&lt;br /&gt;
 adduser vmail -H -D -s /bin/false&lt;br /&gt;
 grep vmail /etc/passwd&lt;br /&gt;
&lt;br /&gt;
(In examples below, we use 1006/1006 for the uid/gid)&lt;br /&gt;
&lt;br /&gt;
Create the mail directory, and assign vmail as the owner&lt;br /&gt;
 mkdir -p /var/mail/domains&lt;br /&gt;
 chown -R vmail:vmail /var/mail/domains&lt;br /&gt;
 &lt;br /&gt;
&lt;br /&gt;
Install postfix&lt;br /&gt;
&lt;br /&gt;
 apk add acf-postfix postfix-pgsql&lt;br /&gt;
&lt;br /&gt;
Edit the /etc/postfix/main.cf file. Here&#039;s an example (don&#039;t forget to replace the uid/gid):&lt;br /&gt;
&lt;br /&gt;
 myhostname=host.example.com&lt;br /&gt;
 mydomain=example.com&lt;br /&gt;
 &lt;br /&gt;
 mydestination = localhost.$mydomain, localhost&lt;br /&gt;
 mynetworks_style = subnet&lt;br /&gt;
 mynetworks = 127.0.0.0/8&lt;br /&gt;
 &lt;br /&gt;
 virtual_mailbox_domains = proxy:pgsql:/etc/postfix/sql/pgsql_virtual_domains_maps.cf&lt;br /&gt;
 virtual_alias_maps = proxy:pgsql:/etc/postfix/sql/pgsql_virtual_alias_maps.cf,&lt;br /&gt;
        proxy:pgsql:/etc/postfix/sql/pgsql_virtual_alias_domain_maps.cf,&lt;br /&gt;
        proxy:pgsql:/etc/postfix/sql/pgsql_virtual_alias_domain_catchall_maps.cf&lt;br /&gt;
 &lt;br /&gt;
 virtual_mailbox_maps = proxy:pgsql:/etc/postfix/sql/pgsql_virtual_mailbox_maps.cf,&lt;br /&gt;
        proxy:pgsql:/etc/postfix/sql/pgsql_virtual_alias_domain_mailbox_maps.cf&lt;br /&gt;
 &lt;br /&gt;
 virtual_mailbox_base = /var/mail/domains/&lt;br /&gt;
 virtual_gid_maps = static:1006&lt;br /&gt;
 virtual_uid_maps = static:1006&lt;br /&gt;
 virtual_minimum_uid = 100&lt;br /&gt;
 virtual_transport = virtual&lt;br /&gt;
 &lt;br /&gt;
 &lt;br /&gt;
 # This next command means you must create a virtual&lt;br /&gt;
 # domain for the host itself - ALL mail goes through&lt;br /&gt;
 # The virtual transport&lt;br /&gt;
 &lt;br /&gt;
 mailbox_transport = virtual&lt;br /&gt;
 local_transport = virtual&lt;br /&gt;
 local_transport_maps = $virtual_mailbox_maps&lt;br /&gt;
 &lt;br /&gt;
 smtpd_helo_required = yes&lt;br /&gt;
 disable_vrfy_command = yes&lt;br /&gt;
 message_size_limit = 10240000&lt;br /&gt;
 queue_minfree = 51200000&lt;br /&gt;
 &lt;br /&gt;
 smtpd_sender_restrictions =&lt;br /&gt;
        permit_mynetworks,&lt;br /&gt;
        reject_non_fqdn_sender,&lt;br /&gt;
        reject_unknown_sender_domain&lt;br /&gt;
 &lt;br /&gt;
 smtpd_recipient_restrictions =&lt;br /&gt;
        reject_non_fqdn_recipient,&lt;br /&gt;
        reject_unknown_recipient_domain,&lt;br /&gt;
        permit_mynetworks,&lt;br /&gt;
        permit_sasl_authenticated,&lt;br /&gt;
        reject_unauth_destination,&lt;br /&gt;
        reject_rbl_client dnsbl.sorbs.net,&lt;br /&gt;
        reject_rbl_client zen.spamhaus.org,&lt;br /&gt;
        reject_rbl_client bl.spamcop.net&lt;br /&gt;
 &lt;br /&gt;
 smtpd_data_restrictions = reject_unauth_pipelining&lt;br /&gt;
 &lt;br /&gt;
 # we will use this later - This prevents cleartext authentication&lt;br /&gt;
 # for relaying&lt;br /&gt;
 smtpd_tls_auth_only = yes&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Now we need to create a *bunch* of files so that postfix can get the delivery information out of sql. Here&#039;s a shell script to create the scripts.  Change PGPW to the password for the postfix user of the postfix SQL database.&lt;br /&gt;
&lt;br /&gt;
 cd /etc/postfix&lt;br /&gt;
 mkdir sql&lt;br /&gt;
 PGPW=&amp;quot;ChangeMe&amp;quot;&lt;br /&gt;
 &lt;br /&gt;
 cat - &amp;lt;&amp;lt;EOF &amp;gt;sql/pgsql_virtual_alias_domain_catchall_maps.cf&lt;br /&gt;
 user=postfix&lt;br /&gt;
 password = $PGPW&lt;br /&gt;
 hosts = localhost&lt;br /&gt;
 dbname = postfix&lt;br /&gt;
 query = Select goto From alias,alias_domain where alias_domain.alias_domain = &#039;%d&#039; and alias.address = &#039;@&#039; ||  alias_domain.target_domain and alias.active = true and alias_domain.active= true &lt;br /&gt;
 EOF&lt;br /&gt;
 &lt;br /&gt;
 cat - &amp;lt;&amp;lt;EOF &amp;gt;sql/pgsql_virtual_alias_domain_mailbox_maps.cf&lt;br /&gt;
 user=postfix&lt;br /&gt;
 password = $PGPW&lt;br /&gt;
 hosts = localhost&lt;br /&gt;
 dbname = postfix&lt;br /&gt;
 query = Select maildir from mailbox,alias_domain where alias_domain.alias_domain = &#039;%d&#039; and mailbox.username = &#039;%u&#039; || &#039;@&#039; || alias_domain.target_domain and mailbox.active = true and alias_domain.active&lt;br /&gt;
 EOF&lt;br /&gt;
 &lt;br /&gt;
 cat - &amp;lt;&amp;lt;EOF &amp;gt;sql/pgsql_virtual_alias_domain_maps.cf&lt;br /&gt;
 user=postfix&lt;br /&gt;
 password = $PGPW&lt;br /&gt;
 hosts = localhost&lt;br /&gt;
 dbname = postfix&lt;br /&gt;
 query = select goto from alias,alias_domain where alias_domain.alias_domain=&#039;%d&#039; and alias.address = &#039;%u&#039; || &#039;@&#039; || alias_domain.target_domain and alias.active= true and alias_domain.active= true&lt;br /&gt;
 EOF&lt;br /&gt;
 &lt;br /&gt;
 cat - &amp;lt;&amp;lt;EOF &amp;gt;sql/pgsql_virtual_alias_maps.cf&lt;br /&gt;
 user=postfix&lt;br /&gt;
 password = $PGPW&lt;br /&gt;
 hosts = localhost&lt;br /&gt;
 dbname = postfix&lt;br /&gt;
 query = Select goto From alias Where address=&#039;%s&#039; and active =&#039;1&#039;&lt;br /&gt;
 EOF&lt;br /&gt;
 &lt;br /&gt;
 cat - &amp;lt;&amp;lt;EOF &amp;gt;sql/pgsql_virtual_domains_maps.cf&lt;br /&gt;
 user=postfix&lt;br /&gt;
 password = $PGPW&lt;br /&gt;
 hosts = localhost&lt;br /&gt;
 dbname = postfix&lt;br /&gt;
 query = Select domain from domain where domain=&#039;%s&#039; and active=&#039;1&#039;&lt;br /&gt;
 EOF&lt;br /&gt;
 &lt;br /&gt;
 cat - &amp;lt;&amp;lt;EOF &amp;gt;sql/pgsql_virtual_mailbox_maps.cf&lt;br /&gt;
 user=postfix&lt;br /&gt;
 password = $PGPW&lt;br /&gt;
 hosts = localhost&lt;br /&gt;
 dbname = postfix&lt;br /&gt;
 query = Select maildir from mailbox where username=&#039;%s&#039; and active=true&lt;br /&gt;
 EOF&lt;br /&gt;
 &lt;br /&gt;
 chown -R postfix:postfix sql&lt;br /&gt;
 chmod 640 sql/*&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
At this point you should be able to start up postfix&lt;br /&gt;
 &lt;br /&gt;
 newaliases  # so postfix is happy...&lt;br /&gt;
 /etc/init.d/postfix start&lt;br /&gt;
 rc-update add postfix&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Create a domain in PostfixAdmin and test ===&lt;br /&gt;
&lt;br /&gt;
Go to http://host.example.com/postfixadmin/&lt;br /&gt;
&lt;br /&gt;
Log in using the superadmin account, create a domain for the local box (e.g. example.com), and create a user mailbox (e.g. root).&lt;br /&gt;
&lt;br /&gt;
From the machine, send a test message:&lt;br /&gt;
&lt;br /&gt;
 sendmail -t root@example.com&lt;br /&gt;
 subject: test&lt;br /&gt;
 .&lt;br /&gt;
 ^d&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
In /var/log/mail.log (or /var/log/messages, if you still have busybox syslogd running) you should see the message queued.  The message should be in /var/mail/domains/example.com/root/new&lt;br /&gt;
&lt;br /&gt;
== Install Dovecot ==&lt;br /&gt;
&lt;br /&gt;
Dovecot is the POP3/IMAP server to retrieve mail.&lt;br /&gt;
&lt;br /&gt;
As before, we install dovecot: &lt;br /&gt;
&lt;br /&gt;
 apk add acf-dovecot dovecot-pgsql&lt;br /&gt;
&lt;br /&gt;
edit /etc/dovecot/dovecot.conf&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
# Select only the protocols you wish to support - all are listed in the next line&lt;br /&gt;
protocols               =       imap imaps pop3 pop3s&lt;br /&gt;
log_path                =       /var/log/dovecot.log&lt;br /&gt;
info_log_path           =       /var/log/dovecot-info.log&lt;br /&gt;
disable_plaintext_auth  =       no&lt;br /&gt;
auth_username_format    =       %Lu&lt;br /&gt;
&lt;br /&gt;
# Authenticated IMAP&lt;br /&gt;
ssl                     =       yes&lt;br /&gt;
ssl_cert_file           =       /etc/lighttpd/server-bundle.pem&lt;br /&gt;
ssl_key_file            =       /etc/lighttpd/server-bundle.pem&lt;br /&gt;
auth_verbose            =       yes&lt;br /&gt;
auth_debug              =       no&lt;br /&gt;
mail_location           =       maildir:/var/mail/domains/%d/%n&lt;br /&gt;
auth default    {&lt;br /&gt;
       mechanisms = plain&lt;br /&gt;
       passdb sql {&lt;br /&gt;
               args = /etc/dovecot/dovecot-sql.conf&lt;br /&gt;
               }&lt;br /&gt;
       userdb static {&lt;br /&gt;
               args =  uid=1006 gid=1006 home=/var/mail/domains/%d/%n&lt;br /&gt;
               }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
protocol imap {&lt;br /&gt;
        mail_plugins = autocreate&lt;br /&gt;
}&lt;br /&gt;
plugin {&lt;br /&gt;
        autocreate = Trash&lt;br /&gt;
        autocreate2 = Spam&lt;br /&gt;
        autocreate3 = Sent&lt;br /&gt;
        autosubscribe = Trash&lt;br /&gt;
        autosubscribe2 = Spam&lt;br /&gt;
        autosubscribe3 = Sent&lt;br /&gt;
&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Be sure to replace the uid and gid with the appropriate values for the vmail user.&lt;br /&gt;
&lt;br /&gt;
We need a certificate for SSL/TLS authentication, so in the example above, we use the lighttpd cert. That way when the cert is renewed/replaced, Dovecot will have access to the new cert as well.  &lt;br /&gt;
&lt;br /&gt;
Create the /etc/dovecot/dovecot-sql.conf file:&lt;br /&gt;
&lt;br /&gt;
 driver = pgsql&lt;br /&gt;
 connect = host=localhost dbname=postfix user=postfix password=********&lt;br /&gt;
 password_query = select username,password from mailbox where local_part = &#039;%n&#039; and domain = &#039;%d&#039;&lt;br /&gt;
 default_pass_scheme =  MD5-CRYPT&lt;br /&gt;
&lt;br /&gt;
Again, change the password above to your postfix user password, and protect the file from prying eyes:&lt;br /&gt;
&lt;br /&gt;
 chown root:root /etc/dovecot/dovecot-sql.conf&lt;br /&gt;
 chmod 600 /etc/dovecot/dovecot-sql.conf&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Start dovecot&lt;br /&gt;
 /etc/init.d/dovecot start&lt;br /&gt;
 rc-update add dovecot&lt;br /&gt;
&lt;br /&gt;
== Testing ==&lt;br /&gt;
&lt;br /&gt;
Make sure your firewall allows in ports 25(SMTP) 110 (POP3), 995 (POP3S), 143(IMAP), 993(IMAPS), or whatever subset you support.  &lt;br /&gt;
 &lt;br /&gt;
At this point, you should be able to:&lt;br /&gt;
 * Create a new domain and add users with PostfixAdmin&lt;br /&gt;
 * Send mail to those users via SMTP to port 25&lt;br /&gt;
 * Retrieve mail using the user&#039;s full email and password (e.g. username: user@example.com  password: ChangeMe)&lt;br /&gt;
&lt;br /&gt;
== Value Add Features ==&lt;br /&gt;
&lt;br /&gt;
If you followed the guide above, you now have a functional mail server with many interconnected parts.  The features below assume that the server is already running as described above.  You should be able to add any or all of these features below to further enhance the mail service.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Virus Scanning ===&lt;br /&gt;
&lt;br /&gt;
This procedure uses clamav and the postfix content_filter mechanism to scan inbound and outbound email for viruses.  Infected emails are dropped.  Clean emails are tagged with a &amp;quot;scanned by clamav&amp;quot; header.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* Install clamav and clamsmtp:&lt;br /&gt;
 apk add acf-clamav clamsmtp&lt;br /&gt;
* Edit the /etc/clamav/clamd.conf file if desired (not necessary in most cases)&lt;br /&gt;
* Edit /etc/clamsmtpd.conf and verify the following lines&lt;br /&gt;
 OutAddress: 10026&lt;br /&gt;
 Listen: 127.0.0.1:10025                                               &lt;br /&gt;
 Header: X-Virus-Scanned: ClamAV using ClamSMTP&lt;br /&gt;
 Action: drop&lt;br /&gt;
 User: clamav                                                      &lt;br /&gt;
* Start the daemons&lt;br /&gt;
 rc-update add clamd&lt;br /&gt;
 rc-update add clamsmtpd&lt;br /&gt;
 /etc/init.d/clamd start&lt;br /&gt;
 /etc/init.d/clamsmtpd start&lt;br /&gt;
* Verify clamsmtp is listening on port 10025:&lt;br /&gt;
 netstat -anp | grep clamsmtp&lt;br /&gt;
* [http://memberwebs.com/stef/software/clamsmtp/postfix.html Following the clamsmtp instructions]&lt;br /&gt;
** edit /etc/postfix/main.cf and add:&lt;br /&gt;
 content_filter = scan:[127.0.0.1]:10025                                                      &lt;br /&gt;
** edit /etc/postfix/master.cf and add&lt;br /&gt;
 # AV scan filter (used by content_filter)&lt;br /&gt;
 scan      unix  -       -       n       -       16      smtp&lt;br /&gt;
         -o smtp_send_xforward_command=yes&lt;br /&gt;
         -o smtp_enforce_tls=no&lt;br /&gt;
 # For injecting mail back into postfix from the filter&lt;br /&gt;
 127.0.0.1:10026 inet  n -       n       -       16      smtpd&lt;br /&gt;
         -o content_filter=&lt;br /&gt;
         -o receive_override_options=no_unknown_recipient_checks,no_header_body_checks&lt;br /&gt;
         -o smtpd_helo_restrictions=&lt;br /&gt;
         -o smtpd_client_restrictions=&lt;br /&gt;
         -o smtpd_sender_restrictions=&lt;br /&gt;
         -o smtpd_recipient_restrictions=permit_mynetworks,reject&lt;br /&gt;
         -o mynetworks_style=host&lt;br /&gt;
         -o smtpd_authorized_xforward_hosts=127.0.0.0/8&lt;br /&gt;
* postfix reload&lt;br /&gt;
* Send and email into a local virtual domain - it should have the &#039;&#039;X-Virus-Scanned: ClamAV using ClamSMTP&#039;&#039; header.&lt;br /&gt;
&lt;br /&gt;
=== Relay for Authenticated Users ===&lt;br /&gt;
&lt;br /&gt;
As configured above, the mail server accepts email from the Internet, but it does not relay email.  If it is a perimeter exchanger for a protected network, then you can add the protected networks to the &#039;&#039;mynetworks&#039;&#039; configuration line in /etc/postfix/main.cf&lt;br /&gt;
&lt;br /&gt;
This configuration change allows &#039;&#039;remote&#039;&#039; users to authenticate against the mail server and relay through it.  The rules for relaying are:&lt;br /&gt;
* Only authenticated users can relay&lt;br /&gt;
* Authentication Credentials must be encrypted with TLS or SSL&lt;br /&gt;
* Allow Submission and SMTPS ports for relaying (many consumer networks block port 25 - SMTP by default)&lt;br /&gt;
The process uses the dovecot authentication mechanism (used with IMAPS) to authenticate users before they are allowed to relay through postfix.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* Edit /etc/dovecot/dovecot.conf and add teh following inside the &#039;&#039;auth default&#039;&#039; stanza:&lt;br /&gt;
 # this is for postfix SASL (authenticated users can relay through us)&lt;br /&gt;
 socket listen {&lt;br /&gt;
                client {&lt;br /&gt;
                        path    = /var/spool/postfix/private/dovecot-auth.sock&lt;br /&gt;
                        mode    = 0660&lt;br /&gt;
                        user    = postfix&lt;br /&gt;
                        group   = postfix&lt;br /&gt;
                        }&lt;br /&gt;
                }&lt;br /&gt;
        }&lt;br /&gt;
* Restart dovecot&lt;br /&gt;
 /etc/init.d/dovecot restart&lt;br /&gt;
* Edit /etc/postfix/main.cf and add:&lt;br /&gt;
 # TLS Stuff -- since we allow SASL with tls *only*, we have to set up TLS first                    &lt;br /&gt;
 &lt;br /&gt;
 smtpd_tls_cert_file = /etc/lighttpd/server-bundle.pem&lt;br /&gt;
 smtpd_tls_key_file = /etc/lighttpd/server-bundle.pem&lt;br /&gt;
 smtpd_tls_CAfile = /etc/lighttpd/ca-crt.pem&lt;br /&gt;
 # If tls_security_level is set to &amp;quot;encrypt&amp;quot;, then SMTP rejects &lt;br /&gt;
 # unencrypted email (e.g. normal mail) which is bad.&lt;br /&gt;
 # By setting it to &amp;quot;may&amp;quot; you get TLS encrypted mail from google, slashdot, and other &lt;br /&gt;
 # interesting places.  Check your logs to see who&lt;br /&gt;
 smtpd_tls_security_level = may&lt;br /&gt;
 # Log info about the negotiated encryption levels&lt;br /&gt;
 smtpd_tls_received_header = yes&lt;br /&gt;
 smtpd_tls_loglevel = 1&lt;br /&gt;
 &lt;br /&gt;
 # SASL - this allows senders to authenticiate themselves&lt;br /&gt;
 # This along with &amp;quot;permit_sasl_authenticated&amp;quot; in smtpd_recipient_restrictions allows relaying&lt;br /&gt;
 smtpd_sasl_type = dovecot&lt;br /&gt;
 smtpd_sasl_path = private/dovecot-auth.sock&lt;br /&gt;
 smtpd_sasl_auth_enable = yes&lt;br /&gt;
 smtpd_sasl_authenticated_header = yes&lt;br /&gt;
 smtpd_tls_auth_only = yes&lt;br /&gt;
* Edit /etc/postfix/master.cf and enable the submission and smtps transports.  They are probably already at the top of your  master.cf file, just commented out:&lt;br /&gt;
 submission inet n       -       n       -       -       smtpd&lt;br /&gt;
   -o smtpd_tls_security_level=encrypt&lt;br /&gt;
   -o smtpd_sasl_auth_enable=yes&lt;br /&gt;
   -o smtpd_client_restrictions=permit_sasl_authenticated,reject&lt;br /&gt;
   -o milter_macro_daemon_name=ORIGINATING&lt;br /&gt;
 smtps     inet  n       -       n       -       -       smtpd&lt;br /&gt;
   -o smtpd_tls_security_level=encrypt&lt;br /&gt;
   -o smtpd_tls_wrappermode=yes&lt;br /&gt;
   -o smtpd_sasl_auth_enable=yes&lt;br /&gt;
   -o smtpd_client_restrictions=permit_sasl_authenticated,reject&lt;br /&gt;
   -o milter_macro_daemon_name=ORIGINATING&lt;br /&gt;
*Verfiy submission and smtps are defined in /etc/services&lt;br /&gt;
 grep &amp;quot;submission\|ssmtp&amp;quot; /etc/services&lt;br /&gt;
 submission	587/tcp				# mail message submission&lt;br /&gt;
 submission	587/udp&lt;br /&gt;
 smtps		465/tcp		ssmtp		# smtp protocol over TLS/SSL&lt;br /&gt;
 smtps		465/udp		ssmtp&lt;br /&gt;
* Restart postfix&lt;br /&gt;
 postfix reload&lt;br /&gt;
&lt;br /&gt;
At this point, you should be able to set up a mail client to relay through the server with TLS (port 587) or SSL (port 465)  Note that &amp;quot;plain&amp;quot; authentication is used because the underlying link is encrypted.  For example, in Thunderbird leave &amp;quot;secure authentication&amp;quot; unchecked, and choose STARTTLS (or TLS) for the connection security.&lt;br /&gt;
&lt;br /&gt;
=== Mailbox Quotas ===&lt;br /&gt;
&lt;br /&gt;
In the default configuration, PostfixAdmin knows about quotas, but they are not enforced.   Documentation on the web mentions the [http://vda.sourceforge.net vda patch to postfix] to enforce quotas.  The only bad thing... its a &#039;&#039;patch&#039;&#039;.   Postfix and Dovecot are both conservative systems, so if the patch isn&#039;t in the upstream source, we&#039;ll assume there&#039;s a good reason.   There is a way of using quotas without patches - and it involves using dovecot&#039;s [http://wiki.dovecot.org/LDA deliver] lda for local delivery.&lt;br /&gt;
&lt;br /&gt;
Note: As of Jan 2010, the documention is confusing, with multiple versions of dovecot, PostfixAdmin, and Mysql referenced.  These instructions apply to:&lt;br /&gt;
* Postgresql 8.4.2 &lt;br /&gt;
* PostfixAdmin 2.3 &lt;br /&gt;
* Dovecot 1.2.11&lt;br /&gt;
* Postfix 2.6.5&lt;br /&gt;
&lt;br /&gt;
Presumably later versions will work the same, but if not, please update the documentation and versions above.&lt;br /&gt;
&lt;br /&gt;
* Update /etc/dovecot/dovecot.conf (old lines shown commented out):&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
# old postfix &lt;br /&gt;
#       userdb static {&lt;br /&gt;
#               args =  uid=1006 gid=1006 home=/var/mail/domains/%d/%n&lt;br /&gt;
#               }&lt;br /&gt;
&lt;br /&gt;
# new quota support:&lt;br /&gt;
        userdb prefetch {&lt;br /&gt;
                }&lt;br /&gt;
&lt;br /&gt;
        userdb sql {&lt;br /&gt;
                args = /etc/dovecot/dovecot-sql.conf&lt;br /&gt;
                }&lt;br /&gt;
&lt;br /&gt;
        socket listen {&lt;br /&gt;
                client {&lt;br /&gt;
                        path    = /var/spool/postfix/private/dovecot-auth.sock&lt;br /&gt;
                        mode    = 0660&lt;br /&gt;
                        user    = postfix&lt;br /&gt;
                        group   = postfix&lt;br /&gt;
                        }&lt;br /&gt;
                # These lines below are for the deliver lda&lt;br /&gt;
                master {&lt;br /&gt;
                        path =  /var/run/dovecot/auth-master&lt;br /&gt;
                        mode    = 0660&lt;br /&gt;
                        user    = vmail&lt;br /&gt;
                        group   = vmail&lt;br /&gt;
                        }&lt;br /&gt;
                }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
protocol imap {                                                               &lt;br /&gt;
         mail_plugins = quota imap_quota                                       &lt;br /&gt;
         }                                                                     &lt;br /&gt;
                                                                              &lt;br /&gt;
protocol pop3 {                                                               &lt;br /&gt;
         mail_plugins = quota                                                  &lt;br /&gt;
         }                                                                     &lt;br /&gt;
                                                                              &lt;br /&gt;
dict {                                                                        &lt;br /&gt;
        quotadict = pgsql:/etc/dovecot/dovecot-dict-quota.conf                &lt;br /&gt;
        }                                                                     &lt;br /&gt;
                                                                              &lt;br /&gt;
plugin {                                                                      &lt;br /&gt;
         quota = dict:user::proxy::quotadict                                   &lt;br /&gt;
         }                                                     &lt;br /&gt;
                                                              &lt;br /&gt;
protocol lda {                                                &lt;br /&gt;
   postmaster_address = postmaster@host.example.com&lt;br /&gt;
   mail_plugins = quota                                        &lt;br /&gt;
   auth_socket_path =  /var/run/dovecot/auth-master&lt;br /&gt;
   sendmail_path = /usr/sbin/sendmail&lt;br /&gt;
}                                                                            &lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
 &lt;br /&gt;
You should already have a &amp;lt;tt&amp;gt;socket-&amp;gt; listen-&amp;gt; client&amp;lt;/tt&amp;gt; section, but it is listed above to show where it goes in relationship to the &amp;lt;tt&amp;gt;socket -&amp;gt; listen -&amp;gt; master&amp;lt;/tt&amp;gt; section&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* edit &amp;lt;tt&amp;gt;/etc/dovecot/dovecot-sql.conf&amp;lt;/tt&amp;gt; and replace the user and password queries with the following (you may not have a user_query yet - add it):&lt;br /&gt;
&lt;br /&gt;
 password_query = select username as user, password, 1006 as userdb_uid, 1006 as userdb_gid, &#039;*:bytes=&#039; || quota as userdb_quota_rule from mailbox  where local_part = &#039;%n&#039; and domain = &#039;%d&#039;&lt;br /&gt;
 user_query = select &#039;/var/mail/domains/&#039; || maildir as home, 1006 as uid, 1006 as gid, &#039;*:bytes=&#039; || quota  as quota_rule from mailbox where local_part = &#039;%n&#039; and domain =&#039;%d&#039;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* create &amp;lt;tt&amp;gt;/etc/dovecot/dovecot-dict-quota.conf&amp;lt;/tt&amp;gt;&lt;br /&gt;
 connect = host=localhost dbname=postfix user=postfix password=********&lt;br /&gt;
 &lt;br /&gt;
 map {&lt;br /&gt;
         pattern = priv/quota/storage&lt;br /&gt;
         table = quota2&lt;br /&gt;
         username_field =username&lt;br /&gt;
         value_field = bytes&lt;br /&gt;
 }&lt;br /&gt;
 &lt;br /&gt;
 map {&lt;br /&gt;
        pattern= priv/quota/messages&lt;br /&gt;
        table = quota2&lt;br /&gt;
        username_field = username&lt;br /&gt;
        value_field = messages&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
Again, change the password above to your postfix user password, and protect the file from prying eyes:&lt;br /&gt;
  chown root:root /etc/dovecot/dovecot-dict-quota.conf&lt;br /&gt;
  chmod 600 /etc/dovecot/dovecot-dict-quota.conf&lt;br /&gt;
&lt;br /&gt;
Side note: [http://wiki.dovecot.org/Quota/Dict The Dovecot Quota Documentation] mentions the need for a trigger with pgsql.  This was created in the PostfixAdmin install, which is why you instantiated the pgsql language when creating the database.  If not, you will need to create the trigger, to reference the quota2 table, not the quota table mentioned in the dovecot docs.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* create a new transport for the dovecot lda.   Add the following to  /etc/postfix/master.cf:&lt;br /&gt;
 # The dovecot deliver lda&lt;br /&gt;
 dovecot   unix  -       n       n       -       -       pipe&lt;br /&gt;
   flags=DRhu user=vmail:vmail argv=/usr/libexec/dovecot/deliver -f ${sender} -d ${user}@${nexthop}&lt;br /&gt;
&lt;br /&gt;
* Edit the /etc/postfix/main.cf.  Replace &lt;br /&gt;
 virtual_transport = virtual &lt;br /&gt;
with&lt;br /&gt;
 virtual_transport = dovecot&lt;br /&gt;
 dovecot_destination_recipient_limit = 1&lt;br /&gt;
&lt;br /&gt;
Change permissions on the /var/log/dovecot* log files, so that the vmail user can write to them:&lt;br /&gt;
&lt;br /&gt;
 chown vmail:vmail /var/log/dovecot*&lt;br /&gt;
&lt;br /&gt;
Restart Postfix and Dovecot:&lt;br /&gt;
&lt;br /&gt;
 /etc/init.d/postfix restart&lt;br /&gt;
 /etc/init.d/dovecot restart&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;TODO&#039;&#039;&#039;  This will cause over-quota emails to bounce.   Which could be a source of backscatter.   We need a way of checking quota limits after RBL checking but before the message is accepted in the queue.&lt;br /&gt;
&lt;br /&gt;
=== WebMail (RoundCube) ===&lt;br /&gt;
&lt;br /&gt;
[http://roundcube.net/ RoundCube] is an &amp;quot;ajax /Web2.0&amp;quot; web-mail client.  These instructions are for the Alpine Linux 1.10 repository &lt;br /&gt;
&lt;br /&gt;
* Verify that you have at least the following in /etc/postfix/main.cf. Unless you have followed the Relay for Authenticated Users section above, set &#039;&#039;&#039;smtpd_tls_auth_only = no&#039;&#039;&#039;, otherwise leave it set to &#039;&#039;&#039;yes&#039;&#039;&#039;:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
# SASL - this allows senders to authenticiate themselves&lt;br /&gt;
# This along with &amp;quot;permit_sasl_authenticated&amp;quot; in smtpd_recipient_restrictions allows relaying&lt;br /&gt;
smtpd_sasl_type = dovecot&lt;br /&gt;
smtpd_sasl_path = private/dovecot-auth.sock&lt;br /&gt;
smtpd_sasl_auth_enable = yes&lt;br /&gt;
smtpd_sasl_authenticated_header = yes&lt;br /&gt;
# Set the next line to no if TLS auth is not configured &lt;br /&gt;
smtpd_tls_auth_only = no&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* Ensure you have this section in /etc/dovecot/dovecot.conf, inside the &#039;&#039;auth default&#039;&#039; stanza:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
# this is for postfix SASL (authenticated users can relay through us)&lt;br /&gt;
socket listen {&lt;br /&gt;
               client {&lt;br /&gt;
                       path    = /var/spool/postfix/private/dovecot-auth.sock&lt;br /&gt;
                       mode    = 0660&lt;br /&gt;
                       user    = postfix&lt;br /&gt;
                       group   = postfix&lt;br /&gt;
                       }&lt;br /&gt;
               }&lt;br /&gt;
       }&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* Restart the relevant services:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
/etc/init.d/postfix restart&lt;br /&gt;
/etc/init.d/dovecot restart&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* Add the package and related php modules:&lt;br /&gt;
 apk add roundcubemail php-xml php-openssl php-mcrypt php-gd php-iconv&lt;br /&gt;
&lt;br /&gt;
* link the roundcube application back into the docroot&lt;br /&gt;
 ln -s /usr/share/webapps/roundcube /var/www/domains/host.example.com/www/roundcube&lt;br /&gt;
&lt;br /&gt;
* follow the instructions in /usr/share/webapps/roundcube/INSTALL:&lt;br /&gt;
 cd /usr/share/webapps/roundcube&lt;br /&gt;
 chown -R lighttpd:lighttpd temp logs&lt;br /&gt;
 &lt;br /&gt;
 su postgres&lt;br /&gt;
 createuser roundcube&lt;br /&gt;
   Shall the new role be a superuser? (y/n) n&lt;br /&gt;
   Shall the new role be allowed to create databases? (y/n) n&lt;br /&gt;
   Shall the new role be allowed to create more new roles? (y/n) y&lt;br /&gt;
 createdb -O roundcube -E UNICODE -T template0 roundcubemail&lt;br /&gt;
 psql roundcubemail&lt;br /&gt;
   roundcubemail=# ALTER USER roundcube WITH PASSWORD &#039;the_new_password&#039;;&lt;br /&gt;
   roundcubemail=# \c - roundcube&lt;br /&gt;
   roundcubemail=&amp;gt; \i /usr/share/webapps/roundcube/SQL/postgres.initial.sql&lt;br /&gt;
   roundcubemail=&amp;gt; \q&lt;br /&gt;
 exit&lt;br /&gt;
&lt;br /&gt;
* edit /etc/php/php.ini and set date.timezone to your local timezone, or to UTC&lt;br /&gt;
&lt;br /&gt;
* restart lighttpd to verify the new php libraries are used&lt;br /&gt;
 /etc/init.d/lighttpd restart&lt;br /&gt;
&lt;br /&gt;
* Point your browser to http://host.example.com/roundcube/installer&lt;br /&gt;
* Start installation&lt;br /&gt;
&lt;br /&gt;
For the specific configuration parameters in the install step:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!Property&lt;br /&gt;
!Setting&lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;enable_spellcheck&#039;&#039; ||   disabled &lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;identities_level&#039;&#039; ||  one identity with possibility to edit all params but not email address &lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;log driver&#039;&#039; || syslog &lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;sylog_id&#039;&#039; || roundcube &lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;syslog_facility&#039;&#039; || mailsubsystem &lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;db_dnsw&#039;&#039; || pgsql properties, as described above &lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;imap_host&#039;&#039; || 127.0.0.1 &lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;auto_create_user&#039;&#039; || enabled &lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;smtp_server&#039;&#039; ||  127.0.0.1&lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;smtp_port&#039;&#039; ||  25&lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;smtp_user/smtp_pass&#039;&#039; ||  enable &#039;&#039;Use Current IMAP username and password for SMTP authentication&#039;&#039;&lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;smtp_log&#039;&#039; ||  enable (optional, but gives additional log record)&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
The other items can be left at default settings, or adjusted if desired.&lt;br /&gt;
&lt;br /&gt;
* Follow the instructions in step 3 of the install to copy the files to the server&lt;br /&gt;
* You should now be able to get to roundcube at http://host.example.com/roundcube&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
After its working, the INSTALL file recommends removing the install directory.   If you want to keep the installer around later, you can simply change the ownership and permissions.  So do &#039;&#039;&#039;one&#039;&#039;&#039; of the following:&lt;br /&gt;
 cd /usr/share/webapps/roundcube&lt;br /&gt;
 rm -rf LICENSE UPGRADING INSTALL README CHANGELOG  SQL installer&lt;br /&gt;
or&lt;br /&gt;
 cd /usr/share/webapps/roundcube&lt;br /&gt;
 chown -R root:root LICENSE UPGRADING INSTALL README CHANGELOG  SQL installer&lt;br /&gt;
 chmod -R 600 LICENSE UPGRADING INSTALL README CHANGELOG SQL &lt;br /&gt;
 chmod 700 SQL installer&lt;br /&gt;
&lt;br /&gt;
==== Enable Plug-ins ====&lt;br /&gt;
&lt;br /&gt;
RoundCube has various useful plug-ins, which could be found in &#039;&#039;/usr/share/webapps/roundcube/plugins&#039;&#039; directory. For example you may want to enable &#039;&#039;password&#039;&#039; plug-in to let users change their passwords directly from RoundCube using an extra Password Tab added to User Settings.&lt;br /&gt;
&lt;br /&gt;
* Grant limited permissions for &#039;&#039;roundcube&#039;&#039; database role &lt;br /&gt;
 psql -U postgres postfix&lt;br /&gt;
   postfix=# GRANT UPDATE (password,modified) ON mailbox TO roundcube;&lt;br /&gt;
   postfix=# GRANT SELECT (username) ON mailbox TO roundcube;&lt;br /&gt;
   postfix=# GRANT INSERT ON log TO roundcube;&lt;br /&gt;
   postfix=# \q&lt;br /&gt;
&lt;br /&gt;
* Setup &#039;&#039;password&#039;&#039; plug-in parameters in &#039;&#039;/usr/share/webapps/roundcube/plugins/password/config.inc.php&#039;&#039;&lt;br /&gt;
 mv /usr/share/webapps/roundcube/plugins/password/config.inc.php.dist /usr/share/webapps/roundcube/plugins/password/config.inc.php&lt;br /&gt;
 vi /usr/share/webapps/roundcube/plugins/password/config.inc.php&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
$rcmail_config[&#039;password_minimum_length&#039;] = 7;&lt;br /&gt;
$rcmail_config[&#039;password_require_nonalpha&#039;] = true;&lt;br /&gt;
...&lt;br /&gt;
$rcmail_config[&#039;password_db_dsn&#039;] = &#039;pgsql://roundcube:&amp;lt;roundcube_password&amp;gt;@localhost/postfix&#039;;&lt;br /&gt;
...&lt;br /&gt;
$rcmail_config[&#039;password_query&#039;] = &amp;quot;UPDATE mailbox set password = %c, modified = NOW() where username = %u; INSERT INTO log (timestamp,username,domain,action,data) VALUES (NOW(),%u || &#039; (&#039; || %h || &#039;)&#039;,%d,&#039;edit_password&#039;,%u)&amp;quot;;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* Enable &#039;&#039;password&#039;&#039; plug-in&lt;br /&gt;
 vi /usr/share/webapps/roundcube/config/main.inc.php&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
...&lt;br /&gt;
$rcmail_config[&#039;plugins&#039;] = array(&#039;password&#039;);&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== OpenLDAP based Address Book ===&lt;br /&gt;
&lt;br /&gt;
This OpenLDAP configuration uses the SQL backend, which represents information stored in PostgreSQL as an LDAP subtree for Address Book functionality for email lookups, user authentication or even &lt;br /&gt;
replication account information between sites. This procedure uses some metainformation to translate LDAP queries to SQL queries, leaving relational schema untouched, which allows SQL and LDAP &lt;br /&gt;
applications to inter-operate without replication, and exchange data as needed. The SQL backend uses UnixODBC to connect to PostgresSQL. &lt;br /&gt;
&lt;br /&gt;
* Install OpenLDAP and ODBC&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
apk add openldap libldap openldap-back-sql php-ldap unixodbc psqlodbc ca-certificates&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Note&#039;&#039;&#039;: The psqlodbc package is currently unavailable&lt;br /&gt;
&lt;br /&gt;
* Update &amp;quot;postfix&amp;quot; database (it will add &#039;id&#039; columns to mailbox and domain tables, also will create tables and views to represent LDAP metainformation)&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Note&#039;&#039;&#039;: These instructions are for example domain example.com. So make sure you replaced all entries of &#039;example&#039; and &#039;com&#039; according to your domain name parts.&lt;br /&gt;
&lt;br /&gt;
Put the following into a new file called &#039;&#039;&#039;script&#039;&#039;&#039;:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
ALTER TABLE domain ADD COLUMN id SERIAL; &lt;br /&gt;
ALTER TABLE mailbox ADD COLUMN id SERIAL; &lt;br /&gt;
&lt;br /&gt;
CREATE TABLE ldap_entry_objclasses (&lt;br /&gt;
    entry_id integer NOT NULL,&lt;br /&gt;
    oc_name character varying(64)&lt;br /&gt;
);&lt;br /&gt;
&lt;br /&gt;
CREATE TABLE ldap_oc_mappings (&lt;br /&gt;
    name character varying(64) NOT NULL,&lt;br /&gt;
    keytbl character varying(64) NOT NULL,&lt;br /&gt;
    keycol character varying(64) NOT NULL,&lt;br /&gt;
    create_proc character varying(255),&lt;br /&gt;
    delete_proc character varying(255),&lt;br /&gt;
    expect_return integer NOT NULL&lt;br /&gt;
);&lt;br /&gt;
&lt;br /&gt;
ALTER TABLE ldap_oc_mappings ADD COLUMN id SERIAL;&lt;br /&gt;
ALTER TABLE ldap_oc_mappings ADD PRIMARY KEY (id);&lt;br /&gt;
&lt;br /&gt;
CREATE TABLE ldap_attr_mappings (&lt;br /&gt;
    oc_map_id integer NOT NULL REFERENCES ldap_oc_mappings(id),&lt;br /&gt;
    name character varying(255) NOT NULL,&lt;br /&gt;
    sel_expr character varying(255) NOT NULL,&lt;br /&gt;
    sel_expr_u character varying(255),&lt;br /&gt;
    from_tbls character varying(255) NOT NULL,&lt;br /&gt;
    join_where character varying(255),&lt;br /&gt;
    add_proc character varying(255),&lt;br /&gt;
    delete_proc character varying(255),&lt;br /&gt;
    param_order integer NOT NULL,&lt;br /&gt;
    expect_return integer NOT NULL&lt;br /&gt;
);&lt;br /&gt;
&lt;br /&gt;
ALTER TABLE ldap_attr_mappings ADD COLUMN id SERIAL;&lt;br /&gt;
ALTER TABLE ldap_attr_mappings ADD PRIMARY KEY (id);&lt;br /&gt;
&lt;br /&gt;
CREATE VIEW ldap_dcs AS&lt;br /&gt;
    ((SELECT (domain.id + 100000) AS id,&lt;br /&gt;
            (&#039;dc=&#039;::text || replace((domain.domain)::text, &#039;.&#039;::text, &#039;,dc=&#039;::text)) AS dn,&lt;br /&gt;
            1 AS oc_map_id,&lt;br /&gt;
            100000 AS parent,&lt;br /&gt;
            0 AS keyval,&lt;br /&gt;
            domain.domain&lt;br /&gt;
     FROM domain&lt;br /&gt;
     WHERE domain.domain &amp;lt;&amp;gt; &#039;ALL&#039;)&lt;br /&gt;
      UNION&lt;br /&gt;
     (SELECT 100000 AS id,&lt;br /&gt;
           (&#039;dc=&#039; || regexp_replace((domain.domain)::text, &#039;.*\\.&#039;, &#039;&#039;::text)) AS dn,&lt;br /&gt;
           1 AS oc_map_id,&lt;br /&gt;
           0 AS parent,&lt;br /&gt;
           0 AS keyval,&lt;br /&gt;
           (regexp_replace((domain.domain)::text, &#039;.*\\.&#039;, &#039;&#039;::text)) AS domain&lt;br /&gt;
      FROM domain&lt;br /&gt;
      WHERE domain.domain &amp;lt;&amp;gt; &#039;ALL&#039;&lt;br /&gt;
      LIMIT 1));&lt;br /&gt;
&lt;br /&gt;
CREATE VIEW ldap_entries AS&lt;br /&gt;
    SELECT mailbox.id,&lt;br /&gt;
    (((&#039;cn=&#039;::text || initcap(replace(split_part((mailbox.username)::text, &#039;@&#039;::text, 1), &#039;.&#039;::text, &#039; &#039;::text))) || &#039;,dc=&#039;::text) ||&lt;br /&gt;
             replace(regexp_replace((mailbox.username)::text, &#039;.*@&#039;, &#039;&#039;::text), &#039;.&#039;::text, &#039;,dc=&#039;::text)) AS dn,&lt;br /&gt;
          1 AS oc_map_id,&lt;br /&gt;
          (SELECT ldap_dcs.id&lt;br /&gt;
           FROM ldap_dcs&lt;br /&gt;
           WHERE ((ldap_dcs.domain)::text = (mailbox.domain)::text)) AS parent,&lt;br /&gt;
           mailbox.id AS keyval&lt;br /&gt;
           FROM mailbox&lt;br /&gt;
           UNION&lt;br /&gt;
           SELECT ldap_dcs.id,&lt;br /&gt;
                  ldap_dcs.dn,&lt;br /&gt;
                  ldap_dcs.oc_map_id,&lt;br /&gt;
                  ldap_dcs.parent,&lt;br /&gt;
                  ldap_dcs.keyval&lt;br /&gt;
           FROM ldap_dcs;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Finally, execute the commands in the file with:&lt;br /&gt;
 cat script | psql -U postfix postfix&lt;br /&gt;
 rm script&lt;br /&gt;
&lt;br /&gt;
* Fill out LDAP tables according to following example (make sure to separate values with TABs):&lt;br /&gt;
&lt;br /&gt;
Put the following into a new file called &#039;&#039;&#039;script&#039;&#039;&#039;:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
COPY ldap_oc_mappings (id, name, keytbl, keycol, create_proc, delete_proc, expect_return) FROM stdin;&lt;br /&gt;
1	exampleBox	mailbox	id	\N	\N	1&lt;br /&gt;
\.&lt;br /&gt;
COPY ldap_attr_mappings (id, oc_map_id, name, sel_expr, sel_expr_u, from_tbls, join_where, add_proc, delete_proc, param_order, expect_return) FROM stdin;&lt;br /&gt;
1	1	displayName	mailbox.name	\N	mailbox	\N	\N	\N	3	0&lt;br /&gt;
2	1	mail	mailbox.username	\N	mailbox	\N	\N	\N	3	0&lt;br /&gt;
3	1	cn	mailbox.name	\N	mailbox	\N	\N	\N	3	0&lt;br /&gt;
4	1	userPassword	&#039;{CRYPT}&#039;||mailbox.password	\N	mailbox	\N	\N	\N	3	0&lt;br /&gt;
\.&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Finally, execute the commands in the file with:&lt;br /&gt;
 cat script | psql -U postfix postfix&lt;br /&gt;
 rm script&lt;br /&gt;
&lt;br /&gt;
* Check that &amp;quot;ldap_dcs&amp;quot; view looks something like this:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
echo &#039;select * from ldap_dcs&#039; | psql -U postgres postfix&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
   id   |             dn              | oc_map_id | parent | keyval |       domain       &lt;br /&gt;
--------+-----------------------------+-----------+--------+--------+--------------------&lt;br /&gt;
 100000 | dc=com                      |         1 |      0 |      0 | com&lt;br /&gt;
 100001 | dc=example,dc=com           |         1 | 100000 |      0 | example.com&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* Check that &amp;quot;ldap_entries&amp;quot; view looks something like this:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
echo &#039;select * from ldap_entries&#039; | psql -U postgres postfix&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
   id   |                          dn                           | oc_map_id | parent | keyval &lt;br /&gt;
--------+-------------------------------------------------------+-----------+--------+--------&lt;br /&gt;
    1   | cn=address1,dc=example,dc=com                         |         1 | 100001 |    1&lt;br /&gt;
...&lt;br /&gt;
   123  | cn=address123,dc=example,dc=com                       |         1 | 100001 |    1&lt;br /&gt;
 100000 | dc=com                                                |         1 |      0 |    0&lt;br /&gt;
 100001 | dc=example,dc=com                                     |         1 | 100000 |    0&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* Configure ODBC parameters&lt;br /&gt;
&lt;br /&gt;
Edit /etc/odbc.ini:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
[PostgreSQL]&lt;br /&gt;
Description             = Connection to Postgres&lt;br /&gt;
Driver                  = PostgreSQL&lt;br /&gt;
Trace                   = Yes&lt;br /&gt;
TraceFile               = sql.log&lt;br /&gt;
Database                = postfix&lt;br /&gt;
Servername              = 127.0.0.1&lt;br /&gt;
UserName                =&lt;br /&gt;
Password                =&lt;br /&gt;
Port                    = 5432&lt;br /&gt;
Protocol                = 6.4&lt;br /&gt;
ReadOnly                = No&lt;br /&gt;
RowVersining            = No&lt;br /&gt;
ShowSystemTables        = No&lt;br /&gt;
ShowOidColumn           = No&lt;br /&gt;
FakeOidIndex            = No&lt;br /&gt;
ConnSettings            =&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Edit /etc/odbcinst.ini:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
[PostgreSQL]&lt;br /&gt;
Description     = PostgreSQL driver for Linux&lt;br /&gt;
Driver          = /usr/lib/psqlodbcw.so&lt;br /&gt;
Setup           = /usr/lib/libodbcpsqlS.so&lt;br /&gt;
FileUsage       = 1&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* Test ODBC connection&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
echo &amp;quot;select * from domain;&amp;quot; | isql PostgreSQL postgres&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* Provide permission to certificate for LDAP server&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
chown ldap /etc/lighttpd/server-bundle.pem&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* Edit LDAP schema&lt;br /&gt;
&lt;br /&gt;
Edit /etc/openldap/schema/example.com.schema:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
attributetype ( 0.9.2342.19200300.100.1.3&lt;br /&gt;
	NAME ( &#039;mail&#039; &#039;rfc822Mailbox&#039; )&lt;br /&gt;
	DESC &#039;RFC1274: RFC822 Mailbox&#039;&lt;br /&gt;
        EQUALITY caseIgnoreIA5Match&lt;br /&gt;
        SUBSTR caseIgnoreIA5SubstringsMatch&lt;br /&gt;
        SYNTAX 1.3.6.1.4.1.1466.115.121.1.26{256} )&lt;br /&gt;
&lt;br /&gt;
attributetype ( 2.16.840.1.113730.3.1.241&lt;br /&gt;
	NAME &#039;displayName&#039;&lt;br /&gt;
	DESC &#039;RFC2798: preferred name to be used when displaying entries&#039;&lt;br /&gt;
	EQUALITY caseIgnoreMatch&lt;br /&gt;
	SUBSTR caseIgnoreSubstringsMatch&lt;br /&gt;
	SYNTAX 1.3.6.1.4.1.1466.115.121.1.15&lt;br /&gt;
	SINGLE-VALUE )&lt;br /&gt;
&lt;br /&gt;
objectclass   ( 2.16.840.1.113730.3.2.2&lt;br /&gt;
        NAME &#039;exampleBox&#039;&lt;br /&gt;
	DESC &#039;example.com mailbox&#039;&lt;br /&gt;
	MUST ( displayName $ mail $ userPassword )&lt;br /&gt;
	)&lt;br /&gt;
&lt;br /&gt;
# RFC 1274 + RFC 2247&lt;br /&gt;
attributetype ( 0.9.2342.19200300.100.1.25&lt;br /&gt;
        NAME ( &#039;dc&#039; &#039;domainComponent&#039; )&lt;br /&gt;
        DESC &#039;RFC1274/2247: domain component&#039;&lt;br /&gt;
        EQUALITY caseIgnoreIA5Match&lt;br /&gt;
        SUBSTR caseIgnoreIA5SubstringsMatch&lt;br /&gt;
        SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 SINGLE-VALUE )&lt;br /&gt;
&lt;br /&gt;
attributetype ( 2.5.4.46 NAME &#039;dnQualifier&#039;&lt;br /&gt;
        DESC &#039;RFC2256: DN qualifier&#039;&lt;br /&gt;
        EQUALITY caseIgnoreMatch&lt;br /&gt;
        ORDERING caseIgnoreOrderingMatch&lt;br /&gt;
        SUBSTR caseIgnoreSubstringsMatch&lt;br /&gt;
        SYNTAX 1.3.6.1.4.1.1466.115.121.1.44 )&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* Configure LDAP server&lt;br /&gt;
&lt;br /&gt;
Edit /etc/openldap/slapd.conf:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
include         /etc/openldap/schema/example.com.schema&lt;br /&gt;
pidfile         /var/run/openldap/slapd.pid&lt;br /&gt;
argsfile        /var/run/openldap/slapd.args&lt;br /&gt;
&lt;br /&gt;
TLSCipherSuite HIGH&lt;br /&gt;
TLSCACertificateFile /etc/lighttpd/ca-crt.pem&lt;br /&gt;
TLSCertificateFile /etc/lighttpd/server-bundle.pem&lt;br /&gt;
TLSCertificateKeyFile /etc/lighttpd/server-bundle.pem&lt;br /&gt;
TLSVerifyClient never &lt;br /&gt;
&lt;br /&gt;
# This is needed for proper representation of MD5-CRYPT format stored in database&lt;br /&gt;
#  see more details in http://strugglers.net/~andy/blog/2010/01/23/openldap-and-md5crypt/&lt;br /&gt;
password-hash  {CRYPT}&lt;br /&gt;
password-crypt-salt-format &amp;quot;$1$%.8s&amp;quot;&lt;br /&gt;
&lt;br /&gt;
loglevel        stats&lt;br /&gt;
moduleload	/usr/lib/openldap/back_sql.so&lt;br /&gt;
sizelimit 3000&lt;br /&gt;
&lt;br /&gt;
database        sql&lt;br /&gt;
&lt;br /&gt;
dbname		PostgreSQL&lt;br /&gt;
dbuser		postfix&lt;br /&gt;
dbpasswd	*****&lt;br /&gt;
&lt;br /&gt;
suffix          &amp;quot;dc=example,dc=com&amp;quot;&lt;br /&gt;
&lt;br /&gt;
upper_func      &amp;quot;upper&amp;quot;&lt;br /&gt;
strcast_func    &amp;quot;text&amp;quot;&lt;br /&gt;
concat_pattern  &amp;quot;?||?&amp;quot;&lt;br /&gt;
has_ldapinfo_dn_ru      no&lt;br /&gt;
lastmod         off&lt;br /&gt;
&lt;br /&gt;
access to attrs=userPassword by * auth&lt;br /&gt;
&lt;br /&gt;
access to * by peername.ip=127.0.0.1 read&lt;br /&gt;
#           by peername.ip=&amp;lt;IP&amp;gt;%&amp;lt;netmask&amp;gt; read&lt;br /&gt;
#           by peername.ip=&amp;lt;IP&amp;gt; read&lt;br /&gt;
	    by users read&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* Set permissions for slapd.conf&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
chown ldap:ldap /etc/openldap/slapd.conf&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* Configure startup parameters to make sure that LDAP server start AFTER PostgreSQL and listens on localhost with clear text and public IP with SSL&lt;br /&gt;
&lt;br /&gt;
Edit /etc/conf.d/slapd:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
rc_need=&amp;quot;postgresql&amp;quot; &lt;br /&gt;
OPTS=&amp;quot;-h &#039;ldaps:// ldap://127.0.0.1&#039;&amp;quot;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* Start LDAP server&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
rc-update add slapd default&lt;br /&gt;
/etc/init.d/slapd start&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* Configure LDAP client utilities&lt;br /&gt;
&lt;br /&gt;
Edit /etc/openldap/ldap.conf&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
BASE	dc=example,dc=com&lt;br /&gt;
URI	ldaps://host.example.com&lt;br /&gt;
&lt;br /&gt;
TLS_CACERT /etc/lighttpd/ca-crt.pem&lt;br /&gt;
TLS_CERT /etc/lighttpd/server-bundle.pem&lt;br /&gt;
TLS_KEY /etc/lighttpd/server-bundle.pem&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* Test LDAP server&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
ldapsearch -z 3&lt;br /&gt;
ldapsearch -z 3 -x -W -D cn=admin,dc=example,dc=com&lt;br /&gt;
ldapsearch -z 3 -x -W -D cn=address1,dc=example,dc=com&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* Configure RoundCube webmail for email lookups&lt;br /&gt;
&lt;br /&gt;
In order to enable php-ldap support you need to restart lighttpd server&lt;br /&gt;
&lt;br /&gt;
 /etc/init.d/lighttpd restart&lt;br /&gt;
&lt;br /&gt;
Edit /usr/share/webapps/roundcube/config/main.inc.php:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
$rcmail_config[&#039;ldap_debug&#039;] = false;&lt;br /&gt;
...&lt;br /&gt;
$rcmail_config[&#039;address_book_type&#039;] = &#039;sql&#039;;&lt;br /&gt;
&lt;br /&gt;
$rcmail_config[&#039;ldap_public&#039;][&#039;example.com&#039;] = array(&lt;br /&gt;
  &#039;name&#039;          =&amp;gt; &#039;example.com&#039;,&lt;br /&gt;
  &#039;hosts&#039;         =&amp;gt; array(&#039;127.0.0.1&#039;),&lt;br /&gt;
  &#039;port&#039;          =&amp;gt; 389,&lt;br /&gt;
  &#039;use_tls&#039;         =&amp;gt; false,&lt;br /&gt;
  &#039;user_specific&#039; =&amp;gt; false,&lt;br /&gt;
  &#039;base_dn&#039;       =&amp;gt; &#039;dc=example,dc=com&#039;,&lt;br /&gt;
  &#039;bind_dn&#039;       =&amp;gt; &#039;&#039;,&lt;br /&gt;
  &#039;bind_pass&#039;     =&amp;gt; &#039;&#039;,&lt;br /&gt;
  &#039;writable&#039;      =&amp;gt; false,&lt;br /&gt;
  &#039;LDAP_Object_Classes&#039; =&amp;gt; array(&amp;quot;top&amp;quot;, &amp;quot;exampleBox&amp;quot;),&lt;br /&gt;
  &#039;required_fields&#039;     =&amp;gt; array(&amp;quot;cn&amp;quot;, &amp;quot;sn&amp;quot;, &amp;quot;mail&amp;quot;),&lt;br /&gt;
  &#039;LDAP_rdn&#039;      =&amp;gt; &#039;mail&#039;,&lt;br /&gt;
  &#039;ldap_version&#039;  =&amp;gt; 3,&lt;br /&gt;
  &#039;search_fields&#039; =&amp;gt; array(&#039;mail&#039;, &#039;cn&#039;, &#039;sn&#039;, &#039;givenName&#039;),&lt;br /&gt;
  &#039;name_field&#039;    =&amp;gt; &#039;cn&#039;,&lt;br /&gt;
  &#039;email_field&#039;   =&amp;gt; &#039;mail&#039;,&lt;br /&gt;
  &#039;surname_field&#039; =&amp;gt; &#039;sn&#039;,&lt;br /&gt;
  &#039;firstname_field&#039; =&amp;gt; &#039;gn&#039;,&lt;br /&gt;
  &#039;sort&#039;          =&amp;gt; &#039;cn&#039;,&lt;br /&gt;
  &#039;scope&#039;         =&amp;gt; &#039;sub&#039;,&lt;br /&gt;
  &#039;filter&#039;        =&amp;gt; &#039;(objectClass=*)&#039;, // Construct here any filter you need&lt;br /&gt;
  &#039;fuzzy_search&#039;  =&amp;gt; true);&lt;br /&gt;
&lt;br /&gt;
$rcmail_config[&#039;autocomplete_addressbooks&#039;] = array(&#039;sql&#039;,&#039;example.com&#039;);&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* Fix PostfixAdmin to work with the new table definition&lt;br /&gt;
&lt;br /&gt;
Edit /var/www/domains/example.com/www/postfixadmin/list-domain.php. Replace the line:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
   SELECT domain.* , COUNT( DISTINCT mailbox.username ) AS mailbox_count&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
With the lines:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
   SELECT domain.domain, domain.description, domain.aliases, domain.mailboxes,&lt;br /&gt;
   domain.maxquota, domain.quota, domain.transport, domain.backupmx, domain.created,&lt;br /&gt;
   domain.modified, domain.active, COUNT( DISTINCT mailbox.username ) AS mailbox_count&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== log rotation ==&lt;br /&gt;
&lt;br /&gt;
Ensure the busybox cron service is started and is configured to auto-start:&lt;br /&gt;
&lt;br /&gt;
 /etc/init.d/cron start&lt;br /&gt;
 rc-update add cron default&lt;br /&gt;
&lt;br /&gt;
Add log rotate:&lt;br /&gt;
&lt;br /&gt;
 apk add logrotate&lt;br /&gt;
&lt;br /&gt;
Edit &#039;&#039;/etc/logrotate.conf&#039;&#039; as desired, but the defaults should be sufficient for most people.&lt;br /&gt;
&lt;br /&gt;
== Optional: Configure Web Server Virtual Domains ==&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Note:&#039;&#039;&#039; These steps can be done &#039;&#039;in addition to&#039;&#039; the default lighttpd configuration above, which allows you to access the ACF, PostfixAdmin and Roundcube interfaces as subfolders of one web service.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Note:&#039;&#039;&#039; If you provide SSL access for multiple domain site you may need to follow http://redmine.lighttpd.net/projects/lighttpd/wiki/Docs:SSL#SSL-on-multiple-domains in order to provide multi-domain certificates. If you would like to redirect hosts to their secure equivalents use the following instructions http://redmine.lighttpd.net/projects/lighttpd/wiki/HowToRedirectHttpToHttps.&lt;br /&gt;
&lt;br /&gt;
This server hosts three separate web applications, and these can be handled as three &#039;&#039;different&#039;&#039; virtual domains on the same web server. They will be distinguished by their DNS names, so you can choose domains for the three separate services (or at least the ones you want to publish):&lt;br /&gt;
&lt;br /&gt;
* ACF - Alpine Configuration Framework for managing the server&lt;br /&gt;
* PostfixAdmin - for managing the postfix installation&lt;br /&gt;
* RoundCube - for accessing individual mailboxes&lt;br /&gt;
&lt;br /&gt;
Choose three different domains (from here on known as ACF_DOMAIN, POSTFIXADMIN_DOMAIN, and ROUNDCUBE_DOMAIN) and configure DNS for all three to point to the IP address of your host. These should be DNS &#039;&#039;&#039;A&#039;&#039;&#039; records.&lt;br /&gt;
&lt;br /&gt;
Then, configure lighttpd to handle the three separate domains by editing /etc/lighttpd/lighttpd.conf:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 $HTTP[&amp;quot;host&amp;quot;] == &amp;quot;ACF_DOMAIN&amp;quot; {&lt;br /&gt;
	simple-vhost.server-root   = &amp;quot;/var/www/domains/&amp;quot;&lt;br /&gt;
	simple-vhost.default-host  = &amp;quot;/ACF_DOMAIN/&amp;quot;&lt;br /&gt;
	simple-vhost.document-root = &amp;quot;www/&amp;quot;&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
 $HTTP[&amp;quot;host&amp;quot;] == &amp;quot;POSTFIXADMIN_DOMAIN&amp;quot; {&lt;br /&gt;
	simple-vhost.server-root   = &amp;quot;/var/www/domains/&amp;quot;&lt;br /&gt;
	simple-vhost.default-host  = &amp;quot;/POSTFIXADMIN_DOMAIN/&amp;quot;&lt;br /&gt;
	simple-vhost.document-root = &amp;quot;www/&amp;quot;&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
 $HTTP[&amp;quot;host&amp;quot;] == &amp;quot;ROUNDCUBE_DOMAIN&amp;quot; {&lt;br /&gt;
	simple-vhost.server-root   = &amp;quot;/var/www/domains/&amp;quot;&lt;br /&gt;
	simple-vhost.default-host  = &amp;quot;/ROUNDCUBE_DOMAIN/&amp;quot;&lt;br /&gt;
	simple-vhost.document-root = &amp;quot;www/&amp;quot;&lt;br /&gt;
 }&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
And, then link the appropriate www directories.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  mkdir -p /var/www/domains/ACF_DOMAIN&lt;br /&gt;
  ln -s /usr/share/acf/www /var/www/domains/ACF_DOMAIN/www&lt;br /&gt;
&lt;br /&gt;
  mkdir -p /var/www/domains/POSTFIXADMIN_DOMAIN&lt;br /&gt;
  ln -s /var/www/domains/host.example.com/www/postfixadmin /var/www/domains/POSTFIXADMIN_DOMAIN/www&lt;br /&gt;
&lt;br /&gt;
  mkdir -p /var/www/domains/ROUNDCUBE_DOMAIN&lt;br /&gt;
  ln -s /usr/share/webapps/roundcube /var/www/domains/ROUNDCUBE_DOMAIN/www&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;/div&gt;</summary>
		<author><name>Djhughes</name></author>
	</entry>
	<entry>
		<id>https://wiki.alpinelinux.org/w/index.php?title=ISP_Mail_Server_HowTo&amp;diff=4348</id>
		<title>ISP Mail Server HowTo</title>
		<link rel="alternate" type="text/html" href="https://wiki.alpinelinux.org/w/index.php?title=ISP_Mail_Server_HowTo&amp;diff=4348"/>
		<updated>2010-08-27T14:44:24Z</updated>

		<summary type="html">&lt;p&gt;Djhughes: check to make sure sasl is enabled for dovecot/postfix&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Category:mail]]&lt;br /&gt;
== A Full Service Mail Server ==&lt;br /&gt;
&lt;br /&gt;
The goal of this document is to describe how to set up postfix, dovecot, clamav, dspam, roundecube, and postfixadmin for a full-featured &amp;quot;ISP&amp;quot; level mail server.&lt;br /&gt;
&lt;br /&gt;
The server must provide:&lt;br /&gt;
&lt;br /&gt;
* multiple virtual domains&lt;br /&gt;
* admins for each domain (to add/remove virtual accounts)&lt;br /&gt;
* Quota support per domain / account&lt;br /&gt;
* downloading email via IMAP / IMAPS / POP3 / POP3S&lt;br /&gt;
* relaying email for authenticated users with TLS or SSL (Submission / SMTPS protocol)&lt;br /&gt;
* Standard filters (virus/spam/rbl/etc)&lt;br /&gt;
* Web mail client&lt;br /&gt;
* Value Add services&lt;br /&gt;
&lt;br /&gt;
== Set up Lighttpd + PHP ==&lt;br /&gt;
&lt;br /&gt;
PostfixAdmin needs php pgpsql and imap modules, so we do it in this step.&lt;br /&gt;
&lt;br /&gt;
  apk add lighttpd php php-pgsql php-imap&lt;br /&gt;
&lt;br /&gt;
Stop and remove mini_httpd, and move ACF to lighttpd;  We are setting this up to be a multi-domain virtual web server (replace host.example.com with the actual domain):&lt;br /&gt;
&lt;br /&gt;
  /etc/init.d/mini_httpd stop&lt;br /&gt;
  apk del mini_httpd&lt;br /&gt;
  mkdir -p /var/www/domains/host.example.com/www&lt;br /&gt;
  ln -s /usr/share/acf/www /var/www/domains/host.example.com/www/acf&lt;br /&gt;
&lt;br /&gt;
Edit /var/www/domains/host.example.com/index.html to put a simple redirection page:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;lt;!DOCTYPE HTML PUBLIC &amp;quot;-//W3C//DTD HTML 4.01//EN&amp;quot; &amp;quot;http://www.w3.org/TR/html4/strict.dtd&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;html lang=&amp;quot;en&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;head&amp;gt;&lt;br /&gt;
&amp;lt;meta http-equiv=&amp;quot;Content-Type&amp;quot; content=&amp;quot;text/html; charset=ISO-8859-1&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;title&amp;gt;host.example.com Redirector&amp;lt;/title&amp;gt;&lt;br /&gt;
&amp;lt;/head&amp;gt;&lt;br /&gt;
&amp;lt;body&amp;gt;&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;&amp;lt;a href=&amp;quot;/acf&amp;quot;&amp;gt;ACF&amp;lt;/a&amp;gt;&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;&amp;lt;a href=&amp;quot;/postfixadmin&amp;quot;&amp;gt;PostfixAdmin&amp;lt;/a&amp;gt;&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;&amp;lt;a href=&amp;quot;/roundcube&amp;quot;&amp;gt;Roundcube&amp;lt;/a&amp;gt;&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
&amp;lt;/body&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Edit /etc/lighttpd/mod_cgi.conf to serve haserl files by adding a &amp;quot;&amp;quot; =&amp;gt; &amp;quot;&amp;quot; cgi handler and to treat /acf/cgi-bin as a CGI directory (remove the &#039;^&#039;)&lt;br /&gt;
&lt;br /&gt;
 $HTTP[&amp;quot;url&amp;quot;] =~ &amp;quot;/cgi-bin/&amp;quot; {&lt;br /&gt;
     # disable directory listings&lt;br /&gt;
     dir-listing.activate = &amp;quot;disable&amp;quot;&lt;br /&gt;
     # only allow cgi&#039;s in this directory&lt;br /&gt;
     cgi.assign = (&lt;br /&gt;
 		&amp;quot;.pl&amp;quot;	=&amp;gt;	&amp;quot;/usr/bin/perl&amp;quot;,&lt;br /&gt;
 		&amp;quot;.cgi&amp;quot;	=&amp;gt;	&amp;quot;/usr/bin/perl&amp;quot;,&lt;br /&gt;
 		&amp;quot;&amp;quot; =&amp;gt; &amp;quot;&amp;quot;&lt;br /&gt;
 	)&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
Get a web certificate, and install it.  You have two options: 1. If you want to use a self-signed cert, you can use the instructions found at [[Generating SSL certs with ACF]] or [[Generating SSL certs with ACF 1.9]] to generate it. 2. Use the certificate created with the &#039;&#039;&#039;setup-acf&#039;&#039;&#039; command. &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Option 1:&#039;&#039;&#039;&lt;br /&gt;
If you create your own self-signed certificate, you can create the &amp;quot;server-bundle.pem&amp;quot; and the &amp;quot;ca-crt.pem&amp;quot; file with these commands:&lt;br /&gt;
&lt;br /&gt;
  openssl pkcs12 -nokeys -cacerts -in certificate.pfx  -out /etc/lighttpd/ca-crt.pem&lt;br /&gt;
  openssl pkcs12 -nodes -in certificate.pfx -out /etc/lighttpd/server-bundle.pem&lt;br /&gt;
  chown root:root /etc/lighttpd/server-bundle.pem&lt;br /&gt;
  chmod 400 /etc/lighttpd/server-bundle.pem&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Note:&#039;&#039;&#039; The server certificate &#039;&#039;and&#039;&#039; key are in the server-bundle.pem file, so it is critical that the file be read-only by user &amp;quot;root&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Option 2:&#039;&#039;&#039;&lt;br /&gt;
If you prefer to just use the default certificate created with the &#039;&#039;&#039;setup-acf&#039;&#039;&#039; command, then you will need to do the following:&lt;br /&gt;
&lt;br /&gt;
  setup-acf&lt;br /&gt;
&lt;br /&gt;
During the above process, mini_httpd will be started, if it isn&#039;t already, and a certificate will be created. Once you have completed the setup-acf steps, do the following to move the certificate files to the correct location for lighttpd to use.&lt;br /&gt;
&lt;br /&gt;
  mv /etc/ssl/mini_httpd/server.pem /etc/lighttpd/server-bundle.pem&lt;br /&gt;
  chown root:root /etc/lighttpd/server-bundle.pem&lt;br /&gt;
  chmod 400 /etc/lighttpd/server-bundle.pem&lt;br /&gt;
&lt;br /&gt;
Add these lines to /etc/lighttpd/lighttpd.conf to point to the new document root, and set it up to listen on port 443 (replace &#039;&#039;host.example.com&#039;&#039; with the actual domain and &#039;&#039;ip_address_of_server&#039;&#039; with the actual IP address):&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
simple-vhost.server-root   = &amp;quot;/var/www/domains/&amp;quot;&lt;br /&gt;
simple-vhost.default-host  = &amp;quot;/host.example.com/&amp;quot;&lt;br /&gt;
simple-vhost.document-root = &amp;quot;www/&amp;quot;&lt;br /&gt;
&lt;br /&gt;
$SERVER[&amp;quot;socket&amp;quot;] == &amp;quot;ip_address_of_server:443&amp;quot; {&lt;br /&gt;
ssl.engine    = &amp;quot;enable&amp;quot;&lt;br /&gt;
ssl.pemfile   = &amp;quot;/etc/lighttpd/server-bundle.pem&amp;quot;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
If you went with Option 1 above, then add an additional line underneath the ssl.pemfile line, so that the section appears as follows:&lt;br /&gt;
&lt;br /&gt;
  $SERVER[&amp;quot;socket&amp;quot;] == &amp;quot;ip_address_of_server:443&amp;quot; {&lt;br /&gt;
  ssl.engine    = &amp;quot;enable&amp;quot;&lt;br /&gt;
  ssl.pemfile   = &amp;quot;/etc/lighttpd/server-bundle.pem&amp;quot;&lt;br /&gt;
  ssl.ca-file   = &amp;quot;/etc/lighttpd/ca-crt.pem&amp;quot;&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
Ensure that the simple_vhosts module is loaded, as well as the cgi config scripts by uncommenting the following lines in /etc/lighttpd/lighttpd.conf&lt;br /&gt;
&lt;br /&gt;
 server.modules = (&lt;br /&gt;
     #  other modules may be listed&lt;br /&gt;
     &amp;quot;mod_simple_vhost&amp;quot;, &lt;br /&gt;
     #  other modules may be listed&lt;br /&gt;
  .&lt;br /&gt;
  .&lt;br /&gt;
  .&lt;br /&gt;
     include &amp;quot;mod_cgi.conf&amp;quot;&lt;br /&gt;
 &lt;br /&gt;
     include &amp;quot;mod_fastcgi.conf&amp;quot;&lt;br /&gt;
&lt;br /&gt;
Stop and remove mini_httpd; start lighttpd, test&lt;br /&gt;
&lt;br /&gt;
  /etc/init.d/mini_httpd stop&lt;br /&gt;
  rc-update del mini_httpd&lt;br /&gt;
  apk del mini_httpd&lt;br /&gt;
  rc-update add lighttpd&lt;br /&gt;
  /etc/init.d/lighttpd start&lt;br /&gt;
&lt;br /&gt;
At this point you should be able to see ACF being served with lighttpd (Note: this will work well with alpine 1.10. With earlier versions there will be problems.)  https://host.example.com/acf/&lt;br /&gt;
&lt;br /&gt;
== Install Postgresql ==&lt;br /&gt;
&lt;br /&gt;
Add and configure postgresql&lt;br /&gt;
&lt;br /&gt;
  apk add acf-postgresql postgresql-client&lt;br /&gt;
  /etc/init.d/postgresql setup&lt;br /&gt;
  /etc/init.d/postgresql start&lt;br /&gt;
  rc-update add postgresql&lt;br /&gt;
&lt;br /&gt;
At this point any user can connect to the sql server with &amp;quot;trust&amp;quot; mechanism.  If you want to enforce password authentication (you probably do) edit /var/lib/postgresql/8.4/data/pg_hba.conf&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
  Editme: What should we recommend?&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Create the postfix database:&lt;br /&gt;
&lt;br /&gt;
  psql -U postgres&lt;br /&gt;
   create user postfix with password &#039;******&#039;;&lt;br /&gt;
   create database postfix owner postfix;&lt;br /&gt;
   \c postfix&lt;br /&gt;
   create language plpgsql;&lt;br /&gt;
   \q&lt;br /&gt;
&lt;br /&gt;
(Of course, use your selected password where ******* is shown above.)&lt;br /&gt;
&lt;br /&gt;
== Install PostfixAdmin ==&lt;br /&gt;
&lt;br /&gt;
We are going to install the postfix admin web front-end before we install the mail server.  This just creates an interface to populate the SQL tables that postfix and dovecot will use.&lt;br /&gt;
&lt;br /&gt;
Download PostfixAdmin from Sourceforge.  When these instructions were written, 2.3 was the current release, so (replace host.example.com with the actual domain):&lt;br /&gt;
&lt;br /&gt;
 wget http://downloads.sourceforge.net/project/postfixadmin/postfixadmin/postfixadmin-2.3.2/postfixadmin-2.3.2.tar.gz&lt;br /&gt;
 tar zxvf postfixadmin-2.3.2.tar.gz&lt;br /&gt;
 mkdir -p /var/www/domains/host.example.com/www/postfixadmin&lt;br /&gt;
 mv  postfixadmin-2.3.2/* /var/www/domains/host.example.com/www/postfixadmin&lt;br /&gt;
 rm -rf postfixadmin*&lt;br /&gt;
&lt;br /&gt;
Edit /var/www/domains/host.example.com/www/postfixadmin/config.inc.php and modify at least these lines (replace host.example.com with the actual domain):&lt;br /&gt;
&lt;br /&gt;
 $CONF[&#039;configured&#039;] = true;&lt;br /&gt;
 $CONF[&#039;setup_password&#039;] = &amp;quot;&amp;quot;;  &amp;lt;&amp;lt; Don&#039;t change this yet&lt;br /&gt;
 $CONF[&#039;database_type&#039;] = &#039;pgsql&#039;;&lt;br /&gt;
 $CONF[&#039;database_host&#039;] = &#039;localhost&#039;;&lt;br /&gt;
 $CONF[&#039;database_user&#039;] = &#039;postfix&#039;;&lt;br /&gt;
 $CONF[&#039;database_password&#039;] = &#039;*****&#039;;   &amp;lt;&amp;lt; The password you chose above&lt;br /&gt;
 $CONF[&#039;database_name&#039;] = &#039;postfix&#039;;&lt;br /&gt;
 $CONF[&#039;database_prefix&#039;] = &amp;quot;&amp;quot;;&lt;br /&gt;
 $CONF[&#039;admin_email&#039;] = &#039;you@some.email.com&#039;;  &amp;lt;&amp;lt; Your email address &lt;br /&gt;
 $CONF[&#039;encrypt&#039;] = &#039;md5crypt&#039;;&lt;br /&gt;
 $CONF[&#039;authlib_default_flavor&#039;] = &#039;md5raw&#039;;&lt;br /&gt;
 $CONF[&#039;dovecotpw&#039;] = &amp;quot;/usr/sbin/dovecotpw&amp;quot;;&lt;br /&gt;
 $CONF[&#039;domain_path&#039;] = &#039;YES&#039;;&lt;br /&gt;
 $CONF[&#039;domain_in_mailbox&#039;] = &#039;NO&#039;;&lt;br /&gt;
 $CONF[&#039;aliases&#039;] = &#039;10&#039;;                       &lt;br /&gt;
 $CONF[&#039;mailboxes&#039;] = &#039;10&#039;;&lt;br /&gt;
 $CONF[&#039;maxquota&#039;] = &#039;10&#039;;&lt;br /&gt;
 $CONF[&#039;quota&#039;] = &#039;YES&#039;;&lt;br /&gt;
 $CONF[&#039;quota_multiplier&#039;] = &#039;1024000&#039;;&lt;br /&gt;
 $CONF[&#039;vacation&#039;] = &#039;NO&#039;; &lt;br /&gt;
 $CONF[&#039;vacation_control&#039;] =&#039;NO&#039;;&lt;br /&gt;
 $CONF[&#039;vacation_control_admin&#039;] = &#039;NO&#039;;&lt;br /&gt;
 $CONF[&#039;alias_control&#039;] = &#039;YES&#039;;&lt;br /&gt;
 $CONF[&#039;alias_control_admin&#039;] = &#039;YES&#039;;&lt;br /&gt;
 $CONF[&#039;special_alias_control&#039;] = &#039;YES&#039;;&lt;br /&gt;
 $CONF[&#039;fetchmail&#039;] = &#039;NO&#039;;&lt;br /&gt;
 $CONF[&#039;user_footer_link&#039;] = &amp;quot;http://host.example.com/postfixadmin&amp;quot;;&lt;br /&gt;
 $CONF[&#039;footer_link&#039;] = &#039;http://host.example.com/postfixadmin/main.php&#039;;&lt;br /&gt;
 $CONF[&#039;create_mailbox_subdirs_prefix&#039;]=&amp;quot;&amp;quot;;  &lt;br /&gt;
 $CONF[&#039;used_quotas&#039;] = &#039;YES&#039;;   &lt;br /&gt;
 $CONF[&#039;new_quota_table&#039;] = &#039;YES&#039;;  &lt;br /&gt;
&lt;br /&gt;
You should further edit /var/www/domains/host.example.com/www/postfixadmin/config.inc.php and replace all instances of &amp;quot;change-this-to-your.domain.tld&amp;quot; with your actual mail domain. This can be done with busybox sed (replace example.com with your domain name):&lt;br /&gt;
&lt;br /&gt;
 sed -i -e &#039;s/change-this-to-your.domain.tld/example.com/g&#039; /var/www/domains/host.example.com/www/postfixadmin/config.inc.php&lt;br /&gt;
&lt;br /&gt;
Go to https://host.example.com/postfixadmin/setup.php&lt;br /&gt;
&lt;br /&gt;
Create the password hash, add it to the config.inc.php file&lt;br /&gt;
&lt;br /&gt;
Go back to https://host.example.com/postfixadmin/setup.php&lt;br /&gt;
&lt;br /&gt;
Create superadmin account.&lt;br /&gt;
&lt;br /&gt;
== Install Postfix ==&lt;br /&gt;
&lt;br /&gt;
Create a user for the virtual mail delivery, and get its uid/gid (you&#039;ll need the numeric uid/gid for postfix)&lt;br /&gt;
&lt;br /&gt;
 adduser vmail -H -D -s /bin/false&lt;br /&gt;
 grep vmail /etc/passwd&lt;br /&gt;
&lt;br /&gt;
(In examples below, we use 1006/1006 for the uid/gid)&lt;br /&gt;
&lt;br /&gt;
Create the mail directory, and assign vmail as the owner&lt;br /&gt;
 mkdir -p /var/mail/domains&lt;br /&gt;
 chown -R vmail:vmail /var/mail/domains&lt;br /&gt;
 &lt;br /&gt;
&lt;br /&gt;
Install postfix&lt;br /&gt;
&lt;br /&gt;
 apk add acf-postfix postfix-pgsql&lt;br /&gt;
&lt;br /&gt;
Edit the /etc/postfix/main.cf file. Here&#039;s an example (don&#039;t forget to replace the uid/gid):&lt;br /&gt;
&lt;br /&gt;
 myhostname=host.example.com&lt;br /&gt;
 mydomain=example.com&lt;br /&gt;
 &lt;br /&gt;
 mydestination = localhost.$mydomain, localhost&lt;br /&gt;
 mynetworks_style = subnet&lt;br /&gt;
 mynetworks = 127.0.0.0/8&lt;br /&gt;
 &lt;br /&gt;
 virtual_mailbox_domains = proxy:pgsql:/etc/postfix/sql/pgsql_virtual_domains_maps.cf&lt;br /&gt;
 virtual_alias_maps = proxy:pgsql:/etc/postfix/sql/pgsql_virtual_alias_maps.cf,&lt;br /&gt;
        proxy:pgsql:/etc/postfix/sql/pgsql_virtual_alias_domain_maps.cf,&lt;br /&gt;
        proxy:pgsql:/etc/postfix/sql/pgsql_virtual_alias_domain_catchall_maps.cf&lt;br /&gt;
 &lt;br /&gt;
 virtual_mailbox_maps = proxy:pgsql:/etc/postfix/sql/pgsql_virtual_mailbox_maps.cf,&lt;br /&gt;
        proxy:pgsql:/etc/postfix/sql/pgsql_virtual_alias_domain_mailbox_maps.cf&lt;br /&gt;
 &lt;br /&gt;
 virtual_mailbox_base = /var/mail/domains/&lt;br /&gt;
 virtual_gid_maps = static:1006&lt;br /&gt;
 virtual_uid_maps = static:1006&lt;br /&gt;
 virtual_minimum_uid = 100&lt;br /&gt;
 virtual_transport = virtual&lt;br /&gt;
 &lt;br /&gt;
 &lt;br /&gt;
 # This next command means you must create a virtual&lt;br /&gt;
 # domain for the host itself - ALL mail goes through&lt;br /&gt;
 # The virtual transport&lt;br /&gt;
 &lt;br /&gt;
 mailbox_transport = virtual&lt;br /&gt;
 local_transport = virtual&lt;br /&gt;
 local_transport_maps = $virtual_mailbox_maps&lt;br /&gt;
 &lt;br /&gt;
 smtpd_helo_required = yes&lt;br /&gt;
 disable_vrfy_command = yes&lt;br /&gt;
 message_size_limit = 10240000&lt;br /&gt;
 queue_minfree = 51200000&lt;br /&gt;
 &lt;br /&gt;
 smtpd_sender_restrictions =&lt;br /&gt;
        permit_mynetworks,&lt;br /&gt;
        reject_non_fqdn_sender,&lt;br /&gt;
        reject_unknown_sender_domain&lt;br /&gt;
 &lt;br /&gt;
 smtpd_recipient_restrictions =&lt;br /&gt;
        reject_non_fqdn_recipient,&lt;br /&gt;
        reject_unknown_recipient_domain,&lt;br /&gt;
        permit_mynetworks,&lt;br /&gt;
        permit_sasl_authenticated,&lt;br /&gt;
        reject_unauth_destination,&lt;br /&gt;
        reject_rbl_client dnsbl.sorbs.net,&lt;br /&gt;
        reject_rbl_client zen.spamhaus.org,&lt;br /&gt;
        reject_rbl_client bl.spamcop.net&lt;br /&gt;
 &lt;br /&gt;
 smtpd_data_restrictions = reject_unauth_pipelining&lt;br /&gt;
 &lt;br /&gt;
 # we will use this later - This prevents cleartext authentication&lt;br /&gt;
 # for relaying&lt;br /&gt;
 smtpd_tls_auth_only = yes&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Now we need to create a *bunch* of files so that postfix can get the delivery information out of sql. Here&#039;s a shell script to create the scripts.  Change PGPW to the password for the postfix user of the postfix SQL database.&lt;br /&gt;
&lt;br /&gt;
 cd /etc/postfix&lt;br /&gt;
 mkdir sql&lt;br /&gt;
 PGPW=&amp;quot;ChangeMe&amp;quot;&lt;br /&gt;
 &lt;br /&gt;
 cat - &amp;lt;&amp;lt;EOF &amp;gt;sql/pgsql_virtual_alias_domain_catchall_maps.cf&lt;br /&gt;
 user=postfix&lt;br /&gt;
 password = $PGPW&lt;br /&gt;
 hosts = localhost&lt;br /&gt;
 dbname = postfix&lt;br /&gt;
 query = Select goto From alias,alias_domain where alias_domain.alias_domain = &#039;%d&#039; and alias.address = &#039;@&#039; ||  alias_domain.target_domain and alias.active = true and alias_domain.active= true &lt;br /&gt;
 EOF&lt;br /&gt;
 &lt;br /&gt;
 cat - &amp;lt;&amp;lt;EOF &amp;gt;sql/pgsql_virtual_alias_domain_mailbox_maps.cf&lt;br /&gt;
 user=postfix&lt;br /&gt;
 password = $PGPW&lt;br /&gt;
 hosts = localhost&lt;br /&gt;
 dbname = postfix&lt;br /&gt;
 query = Select maildir from mailbox,alias_domain where alias_domain.alias_domain = &#039;%d&#039; and mailbox.username = &#039;%u&#039; || &#039;@&#039; || alias_domain.target_domain and mailbox.active = true and alias_domain.active&lt;br /&gt;
 EOF&lt;br /&gt;
 &lt;br /&gt;
 cat - &amp;lt;&amp;lt;EOF &amp;gt;sql/pgsql_virtual_alias_domain_maps.cf&lt;br /&gt;
 user=postfix&lt;br /&gt;
 password = $PGPW&lt;br /&gt;
 hosts = localhost&lt;br /&gt;
 dbname = postfix&lt;br /&gt;
 query = select goto from alias,alias_domain where alias_domain.alias_domain=&#039;%d&#039; and alias.address = &#039;%u&#039; || &#039;@&#039; || alias_domain.target_domain and alias.active= true and alias_domain.active= true&lt;br /&gt;
 EOF&lt;br /&gt;
 &lt;br /&gt;
 cat - &amp;lt;&amp;lt;EOF &amp;gt;sql/pgsql_virtual_alias_maps.cf&lt;br /&gt;
 user=postfix&lt;br /&gt;
 password = $PGPW&lt;br /&gt;
 hosts = localhost&lt;br /&gt;
 dbname = postfix&lt;br /&gt;
 query = Select goto From alias Where address=&#039;%s&#039; and active =&#039;1&#039;&lt;br /&gt;
 EOF&lt;br /&gt;
 &lt;br /&gt;
 cat - &amp;lt;&amp;lt;EOF &amp;gt;sql/pgsql_virtual_domains_maps.cf&lt;br /&gt;
 user=postfix&lt;br /&gt;
 password = $PGPW&lt;br /&gt;
 hosts = localhost&lt;br /&gt;
 dbname = postfix&lt;br /&gt;
 query = Select domain from domain where domain=&#039;%s&#039; and active=&#039;1&#039;&lt;br /&gt;
 EOF&lt;br /&gt;
 &lt;br /&gt;
 cat - &amp;lt;&amp;lt;EOF &amp;gt;sql/pgsql_virtual_mailbox_maps.cf&lt;br /&gt;
 user=postfix&lt;br /&gt;
 password = $PGPW&lt;br /&gt;
 hosts = localhost&lt;br /&gt;
 dbname = postfix&lt;br /&gt;
 query = Select maildir from mailbox where username=&#039;%s&#039; and active=true&lt;br /&gt;
 EOF&lt;br /&gt;
 &lt;br /&gt;
 chown -R postfix:postfix sql&lt;br /&gt;
 chmod 640 sql/*&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
At this point you should be able to start up postfix&lt;br /&gt;
 &lt;br /&gt;
 newaliases  # so postfix is happy...&lt;br /&gt;
 /etc/init.d/postfix start&lt;br /&gt;
 rc-update add postfix&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Create a domain in PostfixAdmin and test ===&lt;br /&gt;
&lt;br /&gt;
Go to http://host.example.com/postfixadmin/&lt;br /&gt;
&lt;br /&gt;
Log in using the superadmin account, create a domain for the local box (e.g. example.com), and create a user mailbox (e.g. root).&lt;br /&gt;
&lt;br /&gt;
From the machine, send a test message:&lt;br /&gt;
&lt;br /&gt;
 sendmail -t root@example.com&lt;br /&gt;
 subject: test&lt;br /&gt;
 .&lt;br /&gt;
 ^d&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
In /var/log/mail.log (or /var/log/messages, if you still have busybox syslogd running) you should see the message queued.  The message should be in /var/mail/domains/example.com/root/new&lt;br /&gt;
&lt;br /&gt;
== Install Dovecot ==&lt;br /&gt;
&lt;br /&gt;
Dovecot is the POP3/IMAP server to retrieve mail.&lt;br /&gt;
&lt;br /&gt;
As before, we install dovecot: &lt;br /&gt;
&lt;br /&gt;
 apk add acf-dovecot dovecot-pgsql&lt;br /&gt;
&lt;br /&gt;
edit /etc/dovecot/dovecot.conf&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
# Select only the protocols you wish to support - all are listed in the next line&lt;br /&gt;
protocols               =       imap imaps pop3 pop3s&lt;br /&gt;
log_path                =       /var/log/dovecot.log&lt;br /&gt;
info_log_path           =       /var/log/dovecot-info.log&lt;br /&gt;
disable_plaintext_auth  =       no&lt;br /&gt;
auth_username_format    =       %Lu&lt;br /&gt;
&lt;br /&gt;
# Authenticated IMAP&lt;br /&gt;
ssl                     =       yes&lt;br /&gt;
ssl_cert_file           =       /etc/lighttpd/server-bundle.pem&lt;br /&gt;
ssl_key_file            =       /etc/lighttpd/server-bundle.pem&lt;br /&gt;
auth_verbose            =       yes&lt;br /&gt;
auth_debug              =       no&lt;br /&gt;
mail_location           =       maildir:/var/mail/domains/%d/%n&lt;br /&gt;
auth default    {&lt;br /&gt;
       mechanisms = plain&lt;br /&gt;
       passdb sql {&lt;br /&gt;
               args = /etc/dovecot/dovecot-sql.conf&lt;br /&gt;
               }&lt;br /&gt;
       userdb static {&lt;br /&gt;
               args =  uid=1006 gid=1006 home=/var/mail/domains/%d/%n&lt;br /&gt;
               }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
protocol imap {&lt;br /&gt;
        mail_plugins = autocreate&lt;br /&gt;
}&lt;br /&gt;
plugin {&lt;br /&gt;
        autocreate = Trash&lt;br /&gt;
        autocreate2 = Spam&lt;br /&gt;
        autocreate3 = Sent&lt;br /&gt;
        autosubscribe = Trash&lt;br /&gt;
        autosubscribe2 = Spam&lt;br /&gt;
        autosubscribe3 = Sent&lt;br /&gt;
&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Be sure to replace the uid and gid with the appropriate values for the vmail user.&lt;br /&gt;
&lt;br /&gt;
We need a certificate for SSL/TLS authentication, so in the example above, we use the lighttpd cert. That way when the cert is renewed/replaced, Dovecot will have access to the new cert as well.  &lt;br /&gt;
&lt;br /&gt;
Create the /etc/dovecot/dovecot-sql.conf file:&lt;br /&gt;
&lt;br /&gt;
 driver = pgsql&lt;br /&gt;
 connect = host=localhost dbname=postfix user=postfix password=********&lt;br /&gt;
 password_query = select username,password from mailbox where local_part = &#039;%n&#039; and domain = &#039;%d&#039;&lt;br /&gt;
 default_pass_scheme =  MD5-CRYPT&lt;br /&gt;
&lt;br /&gt;
Again, change the password above to your postfix user password, and protect the file from prying eyes:&lt;br /&gt;
&lt;br /&gt;
 chown root:root /etc/dovecot/dovecot-sql.conf&lt;br /&gt;
 chmod 600 /etc/dovecot/dovecot-sql.conf&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Start dovecot&lt;br /&gt;
 /etc/init.d/dovecot start&lt;br /&gt;
 rc-update add dovecot&lt;br /&gt;
&lt;br /&gt;
== Testing ==&lt;br /&gt;
&lt;br /&gt;
Make sure your firewall allows in ports 25(SMTP) 110 (POP3), 995 (POP3S), 143(IMAP), 993(IMAPS), or whatever subset you support.  &lt;br /&gt;
 &lt;br /&gt;
At this point, you should be able to:&lt;br /&gt;
 * Create a new domain and add users with PostfixAdmin&lt;br /&gt;
 * Send mail to those users via SMTP to port 25&lt;br /&gt;
 * Retrieve mail using the user&#039;s full email and password (e.g. username: user@example.com  password: ChangeMe)&lt;br /&gt;
&lt;br /&gt;
== Value Add Features ==&lt;br /&gt;
&lt;br /&gt;
If you followed the guide above, you now have a functional mail server with many interconnected parts.  The features below assume that the server is already running as described above.  You should be able to add any or all of these features below to further enhance the mail service.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Virus Scanning ===&lt;br /&gt;
&lt;br /&gt;
This procedure uses clamav and the postfix content_filter mechanism to scan inbound and outbound email for viruses.  Infected emails are dropped.  Clean emails are tagged with a &amp;quot;scanned by clamav&amp;quot; header.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* Install clamav and clamsmtp:&lt;br /&gt;
 apk add acf-clamav clamsmtp&lt;br /&gt;
* Edit the /etc/clamav/clamd.conf file if desired (not necessary in most cases)&lt;br /&gt;
* Edit /etc/clamsmtpd.conf and verify the following lines&lt;br /&gt;
 OutAddress: 10026&lt;br /&gt;
 Listen: 127.0.0.1:10025                                               &lt;br /&gt;
 Header: X-Virus-Scanned: ClamAV using ClamSMTP&lt;br /&gt;
 Action: drop&lt;br /&gt;
 User: clamav                                                      &lt;br /&gt;
* Start the daemons&lt;br /&gt;
 rc-update add clamd&lt;br /&gt;
 rc-update add clamsmtpd&lt;br /&gt;
 /etc/init.d/clamd start&lt;br /&gt;
 /etc/init.d/clamsmtpd start&lt;br /&gt;
* Verify clamsmtp is listening on port 10025:&lt;br /&gt;
 netstat -anp | grep clamsmtp&lt;br /&gt;
* [http://memberwebs.com/stef/software/clamsmtp/postfix.html Following the clamsmtp instructions]&lt;br /&gt;
** edit /etc/postfix/main.cf and add:&lt;br /&gt;
 content_filter = scan:[127.0.0.1]:10025                                                      &lt;br /&gt;
** edit /etc/postfix/master.cf and add&lt;br /&gt;
 # AV scan filter (used by content_filter)&lt;br /&gt;
 scan      unix  -       -       n       -       16      smtp&lt;br /&gt;
         -o smtp_send_xforward_command=yes&lt;br /&gt;
         -o smtp_enforce_tls=no&lt;br /&gt;
 # For injecting mail back into postfix from the filter&lt;br /&gt;
 127.0.0.1:10026 inet  n -       n       -       16      smtpd&lt;br /&gt;
         -o content_filter=&lt;br /&gt;
         -o receive_override_options=no_unknown_recipient_checks,no_header_body_checks&lt;br /&gt;
         -o smtpd_helo_restrictions=&lt;br /&gt;
         -o smtpd_client_restrictions=&lt;br /&gt;
         -o smtpd_sender_restrictions=&lt;br /&gt;
         -o smtpd_recipient_restrictions=permit_mynetworks,reject&lt;br /&gt;
         -o mynetworks_style=host&lt;br /&gt;
         -o smtpd_authorized_xforward_hosts=127.0.0.0/8&lt;br /&gt;
* postfix reload&lt;br /&gt;
* Send and email into a local virtual domain - it should have the &#039;&#039;X-Virus-Scanned: ClamAV using ClamSMTP&#039;&#039; header.&lt;br /&gt;
&lt;br /&gt;
=== Relay for Authenticated Users ===&lt;br /&gt;
&lt;br /&gt;
As configured above, the mail server accepts email from the Internet, but it does not relay email.  If it is a perimeter exchanger for a protected network, then you can add the protected networks to the &#039;&#039;mynetworks&#039;&#039; configuration line in /etc/postfix/main.cf&lt;br /&gt;
&lt;br /&gt;
This configuration change allows &#039;&#039;remote&#039;&#039; users to authenticate against the mail server and relay through it.  The rules for relaying are:&lt;br /&gt;
* Only authenticated users can relay&lt;br /&gt;
* Authentication Credentials must be encrypted with TLS or SSL&lt;br /&gt;
* Allow Submission and SMTPS ports for relaying (many consumer networks block port 25 - SMTP by default)&lt;br /&gt;
The process uses the dovecot authentication mechanism (used with IMAPS) to authenticate users before they are allowed to relay through postfix.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* Edit /etc/dovecot/dovecot.conf and add teh following inside the &#039;&#039;auth default&#039;&#039; stanza:&lt;br /&gt;
 # this is for postfix SASL (authenticated users can relay through us)&lt;br /&gt;
 socket listen {&lt;br /&gt;
                client {&lt;br /&gt;
                        path    = /var/spool/postfix/private/dovecot-auth.sock&lt;br /&gt;
                        mode    = 0660&lt;br /&gt;
                        user    = postfix&lt;br /&gt;
                        group   = postfix&lt;br /&gt;
                        }&lt;br /&gt;
                }&lt;br /&gt;
        }&lt;br /&gt;
* Restart dovecot&lt;br /&gt;
 /etc/init.d/dovecot restart&lt;br /&gt;
* Edit /etc/postfix/main.cf and add:&lt;br /&gt;
 # TLS Stuff -- since we allow SASL with tls *only*, we have to set up TLS first                    &lt;br /&gt;
 &lt;br /&gt;
 smtpd_tls_cert_file = /etc/lighttpd/server-bundle.pem&lt;br /&gt;
 smtpd_tls_key_file = /etc/lighttpd/server-bundle.pem&lt;br /&gt;
 smtpd_tls_CAfile = /etc/lighttpd/ca-crt.pem&lt;br /&gt;
 # If tls_security_level is set to &amp;quot;encrypt&amp;quot;, then SMTP rejects &lt;br /&gt;
 # unencrypted email (e.g. normal mail) which is bad.&lt;br /&gt;
 # By setting it to &amp;quot;may&amp;quot; you get TLS encrypted mail from google, slashdot, and other &lt;br /&gt;
 # interesting places.  Check your logs to see who&lt;br /&gt;
 smtpd_tls_security_level = may&lt;br /&gt;
 # Log info about the negotiated encryption levels&lt;br /&gt;
 smtpd_tls_received_header = yes&lt;br /&gt;
 smtpd_tls_loglevel = 1&lt;br /&gt;
 &lt;br /&gt;
 # SASL - this allows senders to authenticiate themselves&lt;br /&gt;
 # This along with &amp;quot;permit_sasl_authenticated&amp;quot; in smtpd_recipient_restrictions allows relaying&lt;br /&gt;
 smtpd_sasl_type = dovecot&lt;br /&gt;
 smtpd_sasl_path = private/dovecot-auth.sock&lt;br /&gt;
 smtpd_sasl_auth_enable = yes&lt;br /&gt;
 smtpd_sasl_authenticated_header = yes&lt;br /&gt;
 smtpd_tls_auth_only = yes&lt;br /&gt;
* Edit /etc/postfix/master.cf and enable the submission and smtps transports.  They are probably already at the top of your  master.cf file, just commented out:&lt;br /&gt;
 submission inet n       -       n       -       -       smtpd&lt;br /&gt;
   -o smtpd_tls_security_level=encrypt&lt;br /&gt;
   -o smtpd_sasl_auth_enable=yes&lt;br /&gt;
   -o smtpd_client_restrictions=permit_sasl_authenticated,reject&lt;br /&gt;
   -o milter_macro_daemon_name=ORIGINATING&lt;br /&gt;
 smtps     inet  n       -       n       -       -       smtpd&lt;br /&gt;
   -o smtpd_tls_security_level=encrypt&lt;br /&gt;
   -o smtpd_tls_wrappermode=yes&lt;br /&gt;
   -o smtpd_sasl_auth_enable=yes&lt;br /&gt;
   -o smtpd_client_restrictions=permit_sasl_authenticated,reject&lt;br /&gt;
   -o milter_macro_daemon_name=ORIGINATING&lt;br /&gt;
*Verfiy submission and smtps are defined in /etc/services&lt;br /&gt;
 grep &amp;quot;submission\|ssmtp&amp;quot; /etc/services&lt;br /&gt;
 submission	587/tcp				# mail message submission&lt;br /&gt;
 submission	587/udp&lt;br /&gt;
 smtps		465/tcp		ssmtp		# smtp protocol over TLS/SSL&lt;br /&gt;
 smtps		465/udp		ssmtp&lt;br /&gt;
* Restart postfix&lt;br /&gt;
 postfix reload&lt;br /&gt;
&lt;br /&gt;
At this point, you should be able to set up a mail client to relay through the server with TLS (port 587) or SSL (port 465)  Note that &amp;quot;plain&amp;quot; authentication is used because the underlying link is encrypted.  For example, in Thunderbird leave &amp;quot;secure authentication&amp;quot; unchecked, and choose STARTTLS (or TLS) for the connection security.&lt;br /&gt;
&lt;br /&gt;
=== Mailbox Quotas ===&lt;br /&gt;
&lt;br /&gt;
In the default configuration, PostfixAdmin knows about quotas, but they are not enforced.   Documentation on the web mentions the [http://vda.sourceforge.net vda patch to postfix] to enforce quotas.  The only bad thing... its a &#039;&#039;patch&#039;&#039;.   Postfix and Dovecot are both conservative systems, so if the patch isn&#039;t in the upstream source, we&#039;ll assume there&#039;s a good reason.   There is a way of using quotas without patches - and it involves using dovecot&#039;s [http://wiki.dovecot.org/LDA deliver] lda for local delivery.&lt;br /&gt;
&lt;br /&gt;
Note: As of Jan 2010, the documention is confusing, with multiple versions of dovecot, PostfixAdmin, and Mysql referenced.  These instructions apply to:&lt;br /&gt;
* Postgresql 8.4.2 &lt;br /&gt;
* PostfixAdmin 2.3 &lt;br /&gt;
* Dovecot 1.2.11&lt;br /&gt;
* Postfix 2.6.5&lt;br /&gt;
&lt;br /&gt;
Presumably later versions will work the same, but if not, please update the documentation and versions above.&lt;br /&gt;
&lt;br /&gt;
* Update /etc/dovecot/dovecot.conf (old lines shown commented out):&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
# old postfix &lt;br /&gt;
#       userdb static {&lt;br /&gt;
#               args =  uid=1006 gid=1006 home=/var/mail/domains/%d/%n&lt;br /&gt;
#               }&lt;br /&gt;
&lt;br /&gt;
# new quota support:&lt;br /&gt;
        userdb prefetch {&lt;br /&gt;
                }&lt;br /&gt;
&lt;br /&gt;
        userdb sql {&lt;br /&gt;
                args = /etc/dovecot/dovecot-sql.conf&lt;br /&gt;
                }&lt;br /&gt;
&lt;br /&gt;
        socket listen {&lt;br /&gt;
                client {&lt;br /&gt;
                        path    = /var/spool/postfix/private/dovecot-auth.sock&lt;br /&gt;
                        mode    = 0660&lt;br /&gt;
                        user    = postfix&lt;br /&gt;
                        group   = postfix&lt;br /&gt;
                        }&lt;br /&gt;
                # These lines below are for the deliver lda&lt;br /&gt;
                master {&lt;br /&gt;
                        path =  /var/run/dovecot/auth-master&lt;br /&gt;
                        mode    = 0660&lt;br /&gt;
                        user    = vmail&lt;br /&gt;
                        group   = vmail&lt;br /&gt;
                        }&lt;br /&gt;
                }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
protocol imap {                                                               &lt;br /&gt;
         mail_plugins = quota imap_quota                                       &lt;br /&gt;
         }                                                                     &lt;br /&gt;
                                                                              &lt;br /&gt;
protocol pop3 {                                                               &lt;br /&gt;
         mail_plugins = quota                                                  &lt;br /&gt;
         }                                                                     &lt;br /&gt;
                                                                              &lt;br /&gt;
dict {                                                                        &lt;br /&gt;
        quotadict = pgsql:/etc/dovecot/dovecot-dict-quota.conf                &lt;br /&gt;
        }                                                                     &lt;br /&gt;
                                                                              &lt;br /&gt;
plugin {                                                                      &lt;br /&gt;
         quota = dict:user::proxy::quotadict                                   &lt;br /&gt;
         }                                                     &lt;br /&gt;
                                                              &lt;br /&gt;
protocol lda {                                                &lt;br /&gt;
   postmaster_address = postmaster@host.example.com&lt;br /&gt;
   mail_plugins = quota                                        &lt;br /&gt;
   auth_socket_path =  /var/run/dovecot/auth-master&lt;br /&gt;
   sendmail_path = /usr/sbin/sendmail&lt;br /&gt;
}                                                                            &lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
 &lt;br /&gt;
You should already have a &amp;lt;tt&amp;gt;socket-&amp;gt; listen-&amp;gt; client&amp;lt;/tt&amp;gt; section, but it is listed above to show where it goes in relationship to the &amp;lt;tt&amp;gt;socket -&amp;gt; listen -&amp;gt; master&amp;lt;/tt&amp;gt; section&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* edit &amp;lt;tt&amp;gt;/etc/dovecot/dovecot-sql.conf&amp;lt;/tt&amp;gt; and replace the user and password queries with the following (you may not have a user_query yet - add it):&lt;br /&gt;
&lt;br /&gt;
 password_query = select username as user, password, 1006 as userdb_uid, 1006 as userdb_gid, &#039;*:bytes=&#039; || quota as userdb_quota_rule from mailbox  where local_part = &#039;%n&#039; and domain = &#039;%d&#039;&lt;br /&gt;
 user_query = select &#039;/var/mail/domains/&#039; || maildir as home, 1006 as uid, 1006 as gid, &#039;*:bytes=&#039; || quota  as quota_rule from mailbox where local_part = &#039;%n&#039; and domain =&#039;%d&#039;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* create &amp;lt;tt&amp;gt;/etc/dovecot/dovecot-dict-quota.conf&amp;lt;/tt&amp;gt;&lt;br /&gt;
 connect = host=localhost dbname=postfix user=postfix password=********&lt;br /&gt;
 &lt;br /&gt;
 map {&lt;br /&gt;
         pattern = priv/quota/storage&lt;br /&gt;
         table = quota2&lt;br /&gt;
         username_field =username&lt;br /&gt;
         value_field = bytes&lt;br /&gt;
 }&lt;br /&gt;
 &lt;br /&gt;
 map {&lt;br /&gt;
        pattern= priv/quota/messages&lt;br /&gt;
        table = quota2&lt;br /&gt;
        username_field = username&lt;br /&gt;
        value_field = messages&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
Again, change the password above to your postfix user password, and protect the file from prying eyes:&lt;br /&gt;
  chown root:root /etc/dovecot/dovecot-dict-quota.conf&lt;br /&gt;
  chmod 600 /etc/dovecot/dovecot-dict-quota.conf&lt;br /&gt;
&lt;br /&gt;
Side note: [http://wiki.dovecot.org/Quota/Dict The Dovecot Quota Documentation] mentions the need for a trigger with pgsql.  This was created in the PostfixAdmin install, which is why you instantiated the pgsql language when creating the database.  If not, you will need to create the trigger, to reference the quota2 table, not the quota table mentioned in the dovecot docs.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* create a new transport for the dovecot lda.   Add the following to  /etc/postfix/master.cf:&lt;br /&gt;
 # The dovecot deliver lda&lt;br /&gt;
 dovecot   unix  -       n       n       -       -       pipe&lt;br /&gt;
   flags=DRhu user=vmail:vmail argv=/usr/libexec/dovecot/deliver -f ${sender} -d ${user}@${nexthop}&lt;br /&gt;
&lt;br /&gt;
* Edit the /etc/postfix/main.cf.  Replace &lt;br /&gt;
 virtual_transport = virtual &lt;br /&gt;
with&lt;br /&gt;
 virtual_transport = dovecot&lt;br /&gt;
 dovecot_destination_recipient_limit = 1&lt;br /&gt;
&lt;br /&gt;
Change permissions on the /var/log/dovecot* log files, so that the vmail user can write to them:&lt;br /&gt;
&lt;br /&gt;
 chown vmail:vmail /var/log/dovecot*&lt;br /&gt;
&lt;br /&gt;
Restart Postfix and Dovecot:&lt;br /&gt;
&lt;br /&gt;
 /etc/init.d/postfix restart&lt;br /&gt;
 /etc/init.d/dovecot restart&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;TODO&#039;&#039;&#039;  This will cause over-quota emails to bounce.   Which could be a source of backscatter.   We need a way of checking quota limits after RBL checking but before the message is accepted in the queue.&lt;br /&gt;
&lt;br /&gt;
=== WebMail (RoundCube) ===&lt;br /&gt;
&lt;br /&gt;
[http://roundcube.net/ RoundCube] is an &amp;quot;ajax /Web2.0&amp;quot; web-mail client.  These instructions are for the Alpine Linux 1.10 repository &lt;br /&gt;
&lt;br /&gt;
Verify that you have at least the following in /etc/postfix/main.cf. Unless you have followed the Relay for Authenticated Users section above, set &#039;&#039;&#039;smtpd_tls_auth_only = no&#039;&#039;&#039;, otherwise leave it set to &#039;&#039;&#039;yes&#039;&#039;&#039;:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
# SASL - this allows senders to authenticiate themselves&lt;br /&gt;
# This along with &amp;quot;permit_sasl_authenticated&amp;quot; in smtpd_recipient_restrictions allows relaying&lt;br /&gt;
smtpd_sasl_type = dovecot&lt;br /&gt;
smtpd_sasl_path = private/dovecot-auth.sock&lt;br /&gt;
smtpd_sasl_auth_enable = yes&lt;br /&gt;
smtpd_sasl_authenticated_header = yes&lt;br /&gt;
# Set the next line to no if TLS auth is not configured &lt;br /&gt;
smtpd_tls_auth_only = no&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Ensure you have this section in /etc/dovecot/dovecot.conf, inside the &#039;&#039;auth default&#039;&#039; stanza:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
# this is for postfix SASL (authenticated users can relay through us)&lt;br /&gt;
socket listen {&lt;br /&gt;
               client {&lt;br /&gt;
                       path    = /var/spool/postfix/private/dovecot-auth.sock&lt;br /&gt;
                       mode    = 0660&lt;br /&gt;
                       user    = postfix&lt;br /&gt;
                       group   = postfix&lt;br /&gt;
                       }&lt;br /&gt;
               }&lt;br /&gt;
       }&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* Add the package and related php modules:&lt;br /&gt;
 apk add roundcubemail php-xml php-openssl php-mcrypt php-gd php-iconv&lt;br /&gt;
&lt;br /&gt;
* link the roundcube application back into the docroot&lt;br /&gt;
 ln -s /usr/share/webapps/roundcube /var/www/domains/host.example.com/www/roundcube&lt;br /&gt;
&lt;br /&gt;
* follow the instructions in /usr/share/webapps/roundcube/INSTALL:&lt;br /&gt;
 cd /usr/share/webapps/roundcube&lt;br /&gt;
 chown -R lighttpd:lighttpd temp logs&lt;br /&gt;
 &lt;br /&gt;
 su postgres&lt;br /&gt;
 createuser roundcube&lt;br /&gt;
   Shall the new role be a superuser? (y/n) n&lt;br /&gt;
   Shall the new role be allowed to create databases? (y/n) n&lt;br /&gt;
   Shall the new role be allowed to create more new roles? (y/n) y&lt;br /&gt;
 createdb -O roundcube -E UNICODE -T template0 roundcubemail&lt;br /&gt;
 psql roundcubemail&lt;br /&gt;
   roundcubemail=# ALTER USER roundcube WITH PASSWORD &#039;the_new_password&#039;;&lt;br /&gt;
   roundcubemail=# \c - roundcube&lt;br /&gt;
   roundcubemail=&amp;gt; \i /usr/share/webapps/roundcube/SQL/postgres.initial.sql&lt;br /&gt;
   roundcubemail=&amp;gt; \q&lt;br /&gt;
 exit&lt;br /&gt;
&lt;br /&gt;
* edit /etc/php/php.ini and set date.timezone to your local timezone, or to UTC&lt;br /&gt;
&lt;br /&gt;
* restart lighttpd to verify the new php libraries are used&lt;br /&gt;
 /etc/init.d/lighttpd restart&lt;br /&gt;
&lt;br /&gt;
* Point your browser to http://host.example.com/roundcube/installer&lt;br /&gt;
* Start installation&lt;br /&gt;
&lt;br /&gt;
For the specific configuration parameters in the install step:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!Property&lt;br /&gt;
!Setting&lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;enable_spellcheck&#039;&#039; ||   disabled &lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;identities_level&#039;&#039; ||  one identity with possibility to edit all params but not email address &lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;log driver&#039;&#039; || syslog &lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;sylog_id&#039;&#039; || roundcube &lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;syslog_facility&#039;&#039; || mailsubsystem &lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;db_dnsw&#039;&#039; || pgsql properties, as described above &lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;imap_host&#039;&#039; || 127.0.0.1 &lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;auto_create_user&#039;&#039; || enabled &lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;smtp_server&#039;&#039; ||  127.0.0.1&lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;smtp_port&#039;&#039; ||  25&lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;smtp_user/smtp_pass&#039;&#039; ||  enable &#039;&#039;Use Current IMAP username and password for SMTP authentication&#039;&#039;&lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;smtp_log&#039;&#039; ||  enable (optional, but gives additional log record)&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
The other items can be left at default settings, or adjusted if desired.&lt;br /&gt;
&lt;br /&gt;
* Follow the instructions in step 3 of the install to copy the files to the server&lt;br /&gt;
* You should now be able to get to roundcube at http://host.example.com/roundcube&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
After its working, the INSTALL file recommends removing the install directory.   If you want to keep the installer around later, you can simply change the ownership and permissions.  So do &#039;&#039;&#039;one&#039;&#039;&#039; of the following:&lt;br /&gt;
 cd /usr/share/webapps/roundcube&lt;br /&gt;
 rm -rf LICENSE UPGRADING INSTALL README CHANGELOG  SQL installer&lt;br /&gt;
or&lt;br /&gt;
 cd /usr/share/webapps/roundcube&lt;br /&gt;
 chown -R root:root LICENSE UPGRADING INSTALL README CHANGELOG  SQL installer&lt;br /&gt;
 chmod -R 600 LICENSE UPGRADING INSTALL README CHANGELOG SQL &lt;br /&gt;
 chmod 700 SQL installer&lt;br /&gt;
&lt;br /&gt;
==== Enable Plug-ins ====&lt;br /&gt;
&lt;br /&gt;
RoundCube has various useful plug-ins, which could be found in &#039;&#039;/usr/share/webapps/roundcube/plugins&#039;&#039; directory. For example you may want to enable &#039;&#039;password&#039;&#039; plug-in to let users change their passwords directly from RoundCube using an extra Password Tab added to User Settings.&lt;br /&gt;
&lt;br /&gt;
* Grant limited permissions for &#039;&#039;roundcube&#039;&#039; database role &lt;br /&gt;
 psql -U postgres postfix&lt;br /&gt;
   postfix=# GRANT UPDATE (password,modified) ON mailbox TO roundcube;&lt;br /&gt;
   postfix=# GRANT SELECT (username) ON mailbox TO roundcube;&lt;br /&gt;
   postfix=# GRANT INSERT ON log TO roundcube;&lt;br /&gt;
   postfix=# \q&lt;br /&gt;
&lt;br /&gt;
* Setup &#039;&#039;password&#039;&#039; plug-in parameters in &#039;&#039;/usr/share/webapps/roundcube/plugins/password/config.inc.php&#039;&#039;&lt;br /&gt;
 mv /usr/share/webapps/roundcube/plugins/password/config.inc.php.dist /usr/share/webapps/roundcube/plugins/password/config.inc.php&lt;br /&gt;
 vi /usr/share/webapps/roundcube/plugins/password/config.inc.php&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
$rcmail_config[&#039;password_minimum_length&#039;] = 7;&lt;br /&gt;
$rcmail_config[&#039;password_require_nonalpha&#039;] = true;&lt;br /&gt;
...&lt;br /&gt;
$rcmail_config[&#039;password_db_dsn&#039;] = &#039;pgsql://roundcube:&amp;lt;roundcube_password&amp;gt;@localhost/postfix&#039;;&lt;br /&gt;
...&lt;br /&gt;
$rcmail_config[&#039;password_query&#039;] = &amp;quot;UPDATE mailbox set password = %c, modified = NOW() where username = %u; INSERT INTO log (timestamp,username,domain,action,data) VALUES (NOW(),%u || &#039; (&#039; || %h || &#039;)&#039;,%d,&#039;edit_password&#039;,%u)&amp;quot;;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* Enable &#039;&#039;password&#039;&#039; plug-in&lt;br /&gt;
 vi /usr/share/webapps/roundcube/config/main.inc.php&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
...&lt;br /&gt;
$rcmail_config[&#039;plugins&#039;] = array(&#039;password&#039;);&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== OpenLDAP based Address Book ===&lt;br /&gt;
&lt;br /&gt;
This OpenLDAP configuration uses the SQL backend, which represents information stored in PostgreSQL as an LDAP subtree for Address Book functionality for email lookups, user authentication or even &lt;br /&gt;
replication account information between sites. This procedure uses some metainformation to translate LDAP queries to SQL queries, leaving relational schema untouched, which allows SQL and LDAP &lt;br /&gt;
applications to inter-operate without replication, and exchange data as needed. The SQL backend uses UnixODBC to connect to PostgresSQL. &lt;br /&gt;
&lt;br /&gt;
* Install OpenLDAP and ODBC&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
apk add openldap libldap openldap-back-sql php-ldap unixodbc psqlodbc ca-certificates&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Note&#039;&#039;&#039;: The psqlodbc package is currently unavailable&lt;br /&gt;
&lt;br /&gt;
* Update &amp;quot;postfix&amp;quot; database (it will add &#039;id&#039; columns to mailbox and domain tables, also will create tables and views to represent LDAP metainformation)&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Note&#039;&#039;&#039;: These instructions are for example domain example.com. So make sure you replaced all entries of &#039;example&#039; and &#039;com&#039; according to your domain name parts.&lt;br /&gt;
&lt;br /&gt;
Put the following into a new file called &#039;&#039;&#039;script&#039;&#039;&#039;:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
ALTER TABLE domain ADD COLUMN id SERIAL; &lt;br /&gt;
ALTER TABLE mailbox ADD COLUMN id SERIAL; &lt;br /&gt;
&lt;br /&gt;
CREATE TABLE ldap_entry_objclasses (&lt;br /&gt;
    entry_id integer NOT NULL,&lt;br /&gt;
    oc_name character varying(64)&lt;br /&gt;
);&lt;br /&gt;
&lt;br /&gt;
CREATE TABLE ldap_oc_mappings (&lt;br /&gt;
    name character varying(64) NOT NULL,&lt;br /&gt;
    keytbl character varying(64) NOT NULL,&lt;br /&gt;
    keycol character varying(64) NOT NULL,&lt;br /&gt;
    create_proc character varying(255),&lt;br /&gt;
    delete_proc character varying(255),&lt;br /&gt;
    expect_return integer NOT NULL&lt;br /&gt;
);&lt;br /&gt;
&lt;br /&gt;
ALTER TABLE ldap_oc_mappings ADD COLUMN id SERIAL;&lt;br /&gt;
ALTER TABLE ldap_oc_mappings ADD PRIMARY KEY (id);&lt;br /&gt;
&lt;br /&gt;
CREATE TABLE ldap_attr_mappings (&lt;br /&gt;
    oc_map_id integer NOT NULL REFERENCES ldap_oc_mappings(id),&lt;br /&gt;
    name character varying(255) NOT NULL,&lt;br /&gt;
    sel_expr character varying(255) NOT NULL,&lt;br /&gt;
    sel_expr_u character varying(255),&lt;br /&gt;
    from_tbls character varying(255) NOT NULL,&lt;br /&gt;
    join_where character varying(255),&lt;br /&gt;
    add_proc character varying(255),&lt;br /&gt;
    delete_proc character varying(255),&lt;br /&gt;
    param_order integer NOT NULL,&lt;br /&gt;
    expect_return integer NOT NULL&lt;br /&gt;
);&lt;br /&gt;
&lt;br /&gt;
ALTER TABLE ldap_attr_mappings ADD COLUMN id SERIAL;&lt;br /&gt;
ALTER TABLE ldap_attr_mappings ADD PRIMARY KEY (id);&lt;br /&gt;
&lt;br /&gt;
CREATE VIEW ldap_dcs AS&lt;br /&gt;
    ((SELECT (domain.id + 100000) AS id,&lt;br /&gt;
            (&#039;dc=&#039;::text || replace((domain.domain)::text, &#039;.&#039;::text, &#039;,dc=&#039;::text)) AS dn,&lt;br /&gt;
            1 AS oc_map_id,&lt;br /&gt;
            100000 AS parent,&lt;br /&gt;
            0 AS keyval,&lt;br /&gt;
            domain.domain&lt;br /&gt;
     FROM domain&lt;br /&gt;
     WHERE domain.domain &amp;lt;&amp;gt; &#039;ALL&#039;)&lt;br /&gt;
      UNION&lt;br /&gt;
     (SELECT 100000 AS id,&lt;br /&gt;
           (&#039;dc=&#039; || regexp_replace((domain.domain)::text, &#039;.*\\.&#039;, &#039;&#039;::text)) AS dn,&lt;br /&gt;
           1 AS oc_map_id,&lt;br /&gt;
           0 AS parent,&lt;br /&gt;
           0 AS keyval,&lt;br /&gt;
           (regexp_replace((domain.domain)::text, &#039;.*\\.&#039;, &#039;&#039;::text)) AS domain&lt;br /&gt;
      FROM domain&lt;br /&gt;
      WHERE domain.domain &amp;lt;&amp;gt; &#039;ALL&#039;&lt;br /&gt;
      LIMIT 1));&lt;br /&gt;
&lt;br /&gt;
CREATE VIEW ldap_entries AS&lt;br /&gt;
    SELECT mailbox.id,&lt;br /&gt;
    (((&#039;cn=&#039;::text || initcap(replace(split_part((mailbox.username)::text, &#039;@&#039;::text, 1), &#039;.&#039;::text, &#039; &#039;::text))) || &#039;,dc=&#039;::text) ||&lt;br /&gt;
             replace(regexp_replace((mailbox.username)::text, &#039;.*@&#039;, &#039;&#039;::text), &#039;.&#039;::text, &#039;,dc=&#039;::text)) AS dn,&lt;br /&gt;
          1 AS oc_map_id,&lt;br /&gt;
          (SELECT ldap_dcs.id&lt;br /&gt;
           FROM ldap_dcs&lt;br /&gt;
           WHERE ((ldap_dcs.domain)::text = (mailbox.domain)::text)) AS parent,&lt;br /&gt;
           mailbox.id AS keyval&lt;br /&gt;
           FROM mailbox&lt;br /&gt;
           UNION&lt;br /&gt;
           SELECT ldap_dcs.id,&lt;br /&gt;
                  ldap_dcs.dn,&lt;br /&gt;
                  ldap_dcs.oc_map_id,&lt;br /&gt;
                  ldap_dcs.parent,&lt;br /&gt;
                  ldap_dcs.keyval&lt;br /&gt;
           FROM ldap_dcs;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Finally, execute the commands in the file with:&lt;br /&gt;
 cat script | psql -U postfix postfix&lt;br /&gt;
 rm script&lt;br /&gt;
&lt;br /&gt;
* Fill out LDAP tables according to following example (make sure to separate values with TABs):&lt;br /&gt;
&lt;br /&gt;
Put the following into a new file called &#039;&#039;&#039;script&#039;&#039;&#039;:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
COPY ldap_oc_mappings (id, name, keytbl, keycol, create_proc, delete_proc, expect_return) FROM stdin;&lt;br /&gt;
1	exampleBox	mailbox	id	\N	\N	1&lt;br /&gt;
\.&lt;br /&gt;
COPY ldap_attr_mappings (id, oc_map_id, name, sel_expr, sel_expr_u, from_tbls, join_where, add_proc, delete_proc, param_order, expect_return) FROM stdin;&lt;br /&gt;
1	1	displayName	mailbox.name	\N	mailbox	\N	\N	\N	3	0&lt;br /&gt;
2	1	mail	mailbox.username	\N	mailbox	\N	\N	\N	3	0&lt;br /&gt;
3	1	cn	mailbox.name	\N	mailbox	\N	\N	\N	3	0&lt;br /&gt;
4	1	userPassword	&#039;{CRYPT}&#039;||mailbox.password	\N	mailbox	\N	\N	\N	3	0&lt;br /&gt;
\.&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Finally, execute the commands in the file with:&lt;br /&gt;
 cat script | psql -U postfix postfix&lt;br /&gt;
 rm script&lt;br /&gt;
&lt;br /&gt;
* Check that &amp;quot;ldap_dcs&amp;quot; view looks something like this:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
echo &#039;select * from ldap_dcs&#039; | psql -U postgres postfix&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
   id   |             dn              | oc_map_id | parent | keyval |       domain       &lt;br /&gt;
--------+-----------------------------+-----------+--------+--------+--------------------&lt;br /&gt;
 100000 | dc=com                      |         1 |      0 |      0 | com&lt;br /&gt;
 100001 | dc=example,dc=com           |         1 | 100000 |      0 | example.com&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* Check that &amp;quot;ldap_entries&amp;quot; view looks something like this:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
echo &#039;select * from ldap_entries&#039; | psql -U postgres postfix&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
   id   |                          dn                           | oc_map_id | parent | keyval &lt;br /&gt;
--------+-------------------------------------------------------+-----------+--------+--------&lt;br /&gt;
    1   | cn=address1,dc=example,dc=com                         |         1 | 100001 |    1&lt;br /&gt;
...&lt;br /&gt;
   123  | cn=address123,dc=example,dc=com                       |         1 | 100001 |    1&lt;br /&gt;
 100000 | dc=com                                                |         1 |      0 |    0&lt;br /&gt;
 100001 | dc=example,dc=com                                     |         1 | 100000 |    0&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* Configure ODBC parameters&lt;br /&gt;
&lt;br /&gt;
Edit /etc/odbc.ini:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
[PostgreSQL]&lt;br /&gt;
Description             = Connection to Postgres&lt;br /&gt;
Driver                  = PostgreSQL&lt;br /&gt;
Trace                   = Yes&lt;br /&gt;
TraceFile               = sql.log&lt;br /&gt;
Database                = postfix&lt;br /&gt;
Servername              = 127.0.0.1&lt;br /&gt;
UserName                =&lt;br /&gt;
Password                =&lt;br /&gt;
Port                    = 5432&lt;br /&gt;
Protocol                = 6.4&lt;br /&gt;
ReadOnly                = No&lt;br /&gt;
RowVersining            = No&lt;br /&gt;
ShowSystemTables        = No&lt;br /&gt;
ShowOidColumn           = No&lt;br /&gt;
FakeOidIndex            = No&lt;br /&gt;
ConnSettings            =&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Edit /etc/odbcinst.ini:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
[PostgreSQL]&lt;br /&gt;
Description     = PostgreSQL driver for Linux&lt;br /&gt;
Driver          = /usr/lib/psqlodbcw.so&lt;br /&gt;
Setup           = /usr/lib/libodbcpsqlS.so&lt;br /&gt;
FileUsage       = 1&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* Test ODBC connection&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
echo &amp;quot;select * from domain;&amp;quot; | isql PostgreSQL postgres&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* Provide permission to certificate for LDAP server&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
chown ldap /etc/lighttpd/server-bundle.pem&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* Edit LDAP schema&lt;br /&gt;
&lt;br /&gt;
Edit /etc/openldap/schema/example.com.schema:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
attributetype ( 0.9.2342.19200300.100.1.3&lt;br /&gt;
	NAME ( &#039;mail&#039; &#039;rfc822Mailbox&#039; )&lt;br /&gt;
	DESC &#039;RFC1274: RFC822 Mailbox&#039;&lt;br /&gt;
        EQUALITY caseIgnoreIA5Match&lt;br /&gt;
        SUBSTR caseIgnoreIA5SubstringsMatch&lt;br /&gt;
        SYNTAX 1.3.6.1.4.1.1466.115.121.1.26{256} )&lt;br /&gt;
&lt;br /&gt;
attributetype ( 2.16.840.1.113730.3.1.241&lt;br /&gt;
	NAME &#039;displayName&#039;&lt;br /&gt;
	DESC &#039;RFC2798: preferred name to be used when displaying entries&#039;&lt;br /&gt;
	EQUALITY caseIgnoreMatch&lt;br /&gt;
	SUBSTR caseIgnoreSubstringsMatch&lt;br /&gt;
	SYNTAX 1.3.6.1.4.1.1466.115.121.1.15&lt;br /&gt;
	SINGLE-VALUE )&lt;br /&gt;
&lt;br /&gt;
objectclass   ( 2.16.840.1.113730.3.2.2&lt;br /&gt;
        NAME &#039;exampleBox&#039;&lt;br /&gt;
	DESC &#039;example.com mailbox&#039;&lt;br /&gt;
	MUST ( displayName $ mail $ userPassword )&lt;br /&gt;
	)&lt;br /&gt;
&lt;br /&gt;
# RFC 1274 + RFC 2247&lt;br /&gt;
attributetype ( 0.9.2342.19200300.100.1.25&lt;br /&gt;
        NAME ( &#039;dc&#039; &#039;domainComponent&#039; )&lt;br /&gt;
        DESC &#039;RFC1274/2247: domain component&#039;&lt;br /&gt;
        EQUALITY caseIgnoreIA5Match&lt;br /&gt;
        SUBSTR caseIgnoreIA5SubstringsMatch&lt;br /&gt;
        SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 SINGLE-VALUE )&lt;br /&gt;
&lt;br /&gt;
attributetype ( 2.5.4.46 NAME &#039;dnQualifier&#039;&lt;br /&gt;
        DESC &#039;RFC2256: DN qualifier&#039;&lt;br /&gt;
        EQUALITY caseIgnoreMatch&lt;br /&gt;
        ORDERING caseIgnoreOrderingMatch&lt;br /&gt;
        SUBSTR caseIgnoreSubstringsMatch&lt;br /&gt;
        SYNTAX 1.3.6.1.4.1.1466.115.121.1.44 )&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* Configure LDAP server&lt;br /&gt;
&lt;br /&gt;
Edit /etc/openldap/slapd.conf:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
include         /etc/openldap/schema/example.com.schema&lt;br /&gt;
pidfile         /var/run/openldap/slapd.pid&lt;br /&gt;
argsfile        /var/run/openldap/slapd.args&lt;br /&gt;
&lt;br /&gt;
TLSCipherSuite HIGH&lt;br /&gt;
TLSCACertificateFile /etc/lighttpd/ca-crt.pem&lt;br /&gt;
TLSCertificateFile /etc/lighttpd/server-bundle.pem&lt;br /&gt;
TLSCertificateKeyFile /etc/lighttpd/server-bundle.pem&lt;br /&gt;
TLSVerifyClient never &lt;br /&gt;
&lt;br /&gt;
# This is needed for proper representation of MD5-CRYPT format stored in database&lt;br /&gt;
#  see more details in http://strugglers.net/~andy/blog/2010/01/23/openldap-and-md5crypt/&lt;br /&gt;
password-hash  {CRYPT}&lt;br /&gt;
password-crypt-salt-format &amp;quot;$1$%.8s&amp;quot;&lt;br /&gt;
&lt;br /&gt;
loglevel        stats&lt;br /&gt;
moduleload	/usr/lib/openldap/back_sql.so&lt;br /&gt;
sizelimit 3000&lt;br /&gt;
&lt;br /&gt;
database        sql&lt;br /&gt;
&lt;br /&gt;
dbname		PostgreSQL&lt;br /&gt;
dbuser		postfix&lt;br /&gt;
dbpasswd	*****&lt;br /&gt;
&lt;br /&gt;
suffix          &amp;quot;dc=example,dc=com&amp;quot;&lt;br /&gt;
&lt;br /&gt;
upper_func      &amp;quot;upper&amp;quot;&lt;br /&gt;
strcast_func    &amp;quot;text&amp;quot;&lt;br /&gt;
concat_pattern  &amp;quot;?||?&amp;quot;&lt;br /&gt;
has_ldapinfo_dn_ru      no&lt;br /&gt;
lastmod         off&lt;br /&gt;
&lt;br /&gt;
access to attrs=userPassword by * auth&lt;br /&gt;
&lt;br /&gt;
access to * by peername.ip=127.0.0.1 read&lt;br /&gt;
#           by peername.ip=&amp;lt;IP&amp;gt;%&amp;lt;netmask&amp;gt; read&lt;br /&gt;
#           by peername.ip=&amp;lt;IP&amp;gt; read&lt;br /&gt;
	    by users read&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* Set permissions for slapd.conf&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
chown ldap:ldap /etc/openldap/slapd.conf&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* Configure startup parameters to make sure that LDAP server start AFTER PostgreSQL and listens on localhost with clear text and public IP with SSL&lt;br /&gt;
&lt;br /&gt;
Edit /etc/conf.d/slapd:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
rc_need=&amp;quot;postgresql&amp;quot; &lt;br /&gt;
OPTS=&amp;quot;-h &#039;ldaps:// ldap://127.0.0.1&#039;&amp;quot;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* Start LDAP server&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
rc-update add slapd default&lt;br /&gt;
/etc/init.d/slapd start&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* Configure LDAP client utilities&lt;br /&gt;
&lt;br /&gt;
Edit /etc/openldap/ldap.conf&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
BASE	dc=example,dc=com&lt;br /&gt;
URI	ldaps://host.example.com&lt;br /&gt;
&lt;br /&gt;
TLS_CACERT /etc/lighttpd/ca-crt.pem&lt;br /&gt;
TLS_CERT /etc/lighttpd/server-bundle.pem&lt;br /&gt;
TLS_KEY /etc/lighttpd/server-bundle.pem&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* Test LDAP server&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
ldapsearch -z 3&lt;br /&gt;
ldapsearch -z 3 -x -W -D cn=admin,dc=example,dc=com&lt;br /&gt;
ldapsearch -z 3 -x -W -D cn=address1,dc=example,dc=com&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* Configure RoundCube webmail for email lookups&lt;br /&gt;
&lt;br /&gt;
In order to enable php-ldap support you need to restart lighttpd server&lt;br /&gt;
&lt;br /&gt;
 /etc/init.d/lighttpd restart&lt;br /&gt;
&lt;br /&gt;
Edit /usr/share/webapps/roundcube/config/main.inc.php:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
$rcmail_config[&#039;ldap_debug&#039;] = false;&lt;br /&gt;
...&lt;br /&gt;
$rcmail_config[&#039;address_book_type&#039;] = &#039;sql&#039;;&lt;br /&gt;
&lt;br /&gt;
$rcmail_config[&#039;ldap_public&#039;][&#039;example.com&#039;] = array(&lt;br /&gt;
  &#039;name&#039;          =&amp;gt; &#039;example.com&#039;,&lt;br /&gt;
  &#039;hosts&#039;         =&amp;gt; array(&#039;127.0.0.1&#039;),&lt;br /&gt;
  &#039;port&#039;          =&amp;gt; 389,&lt;br /&gt;
  &#039;use_tls&#039;         =&amp;gt; false,&lt;br /&gt;
  &#039;user_specific&#039; =&amp;gt; false,&lt;br /&gt;
  &#039;base_dn&#039;       =&amp;gt; &#039;dc=example,dc=com&#039;,&lt;br /&gt;
  &#039;bind_dn&#039;       =&amp;gt; &#039;&#039;,&lt;br /&gt;
  &#039;bind_pass&#039;     =&amp;gt; &#039;&#039;,&lt;br /&gt;
  &#039;writable&#039;      =&amp;gt; false,&lt;br /&gt;
  &#039;LDAP_Object_Classes&#039; =&amp;gt; array(&amp;quot;top&amp;quot;, &amp;quot;exampleBox&amp;quot;),&lt;br /&gt;
  &#039;required_fields&#039;     =&amp;gt; array(&amp;quot;cn&amp;quot;, &amp;quot;sn&amp;quot;, &amp;quot;mail&amp;quot;),&lt;br /&gt;
  &#039;LDAP_rdn&#039;      =&amp;gt; &#039;mail&#039;,&lt;br /&gt;
  &#039;ldap_version&#039;  =&amp;gt; 3,&lt;br /&gt;
  &#039;search_fields&#039; =&amp;gt; array(&#039;mail&#039;, &#039;cn&#039;, &#039;sn&#039;, &#039;givenName&#039;),&lt;br /&gt;
  &#039;name_field&#039;    =&amp;gt; &#039;cn&#039;,&lt;br /&gt;
  &#039;email_field&#039;   =&amp;gt; &#039;mail&#039;,&lt;br /&gt;
  &#039;surname_field&#039; =&amp;gt; &#039;sn&#039;,&lt;br /&gt;
  &#039;firstname_field&#039; =&amp;gt; &#039;gn&#039;,&lt;br /&gt;
  &#039;sort&#039;          =&amp;gt; &#039;cn&#039;,&lt;br /&gt;
  &#039;scope&#039;         =&amp;gt; &#039;sub&#039;,&lt;br /&gt;
  &#039;filter&#039;        =&amp;gt; &#039;(objectClass=*)&#039;, // Construct here any filter you need&lt;br /&gt;
  &#039;fuzzy_search&#039;  =&amp;gt; true);&lt;br /&gt;
&lt;br /&gt;
$rcmail_config[&#039;autocomplete_addressbooks&#039;] = array(&#039;sql&#039;,&#039;example.com&#039;);&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* Fix PostfixAdmin to work with the new table definition&lt;br /&gt;
&lt;br /&gt;
Edit /var/www/domains/example.com/www/postfixadmin/list-domain.php. Replace the line:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
   SELECT domain.* , COUNT( DISTINCT mailbox.username ) AS mailbox_count&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
With the lines:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
   SELECT domain.domain, domain.description, domain.aliases, domain.mailboxes,&lt;br /&gt;
   domain.maxquota, domain.quota, domain.transport, domain.backupmx, domain.created,&lt;br /&gt;
   domain.modified, domain.active, COUNT( DISTINCT mailbox.username ) AS mailbox_count&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== log rotation ==&lt;br /&gt;
&lt;br /&gt;
Ensure the busybox cron service is started and is configured to auto-start:&lt;br /&gt;
&lt;br /&gt;
 /etc/init.d/cron start&lt;br /&gt;
 rc-update add cron default&lt;br /&gt;
&lt;br /&gt;
Add log rotate:&lt;br /&gt;
&lt;br /&gt;
 apk add logrotate&lt;br /&gt;
&lt;br /&gt;
Edit &#039;&#039;/etc/logrotate.conf&#039;&#039; as desired, but the defaults should be sufficient for most people.&lt;br /&gt;
&lt;br /&gt;
== Optional: Configure Web Server Virtual Domains ==&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Note:&#039;&#039;&#039; These steps can be done &#039;&#039;in addition to&#039;&#039; the default lighttpd configuration above, which allows you to access the ACF, PostfixAdmin and Roundcube interfaces as subfolders of one web service.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Note:&#039;&#039;&#039; If you provide SSL access for multiple domain site you may need to follow http://redmine.lighttpd.net/projects/lighttpd/wiki/Docs:SSL#SSL-on-multiple-domains in order to provide multi-domain certificates. If you would like to redirect hosts to their secure equivalents use the following instructions http://redmine.lighttpd.net/projects/lighttpd/wiki/HowToRedirectHttpToHttps.&lt;br /&gt;
&lt;br /&gt;
This server hosts three separate web applications, and these can be handled as three &#039;&#039;different&#039;&#039; virtual domains on the same web server. They will be distinguished by their DNS names, so you can choose domains for the three separate services (or at least the ones you want to publish):&lt;br /&gt;
&lt;br /&gt;
* ACF - Alpine Configuration Framework for managing the server&lt;br /&gt;
* PostfixAdmin - for managing the postfix installation&lt;br /&gt;
* RoundCube - for accessing individual mailboxes&lt;br /&gt;
&lt;br /&gt;
Choose three different domains (from here on known as ACF_DOMAIN, POSTFIXADMIN_DOMAIN, and ROUNDCUBE_DOMAIN) and configure DNS for all three to point to the IP address of your host. These should be DNS &#039;&#039;&#039;A&#039;&#039;&#039; records.&lt;br /&gt;
&lt;br /&gt;
Then, configure lighttpd to handle the three separate domains by editing /etc/lighttpd/lighttpd.conf:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 $HTTP[&amp;quot;host&amp;quot;] == &amp;quot;ACF_DOMAIN&amp;quot; {&lt;br /&gt;
	simple-vhost.server-root   = &amp;quot;/var/www/domains/&amp;quot;&lt;br /&gt;
	simple-vhost.default-host  = &amp;quot;/ACF_DOMAIN/&amp;quot;&lt;br /&gt;
	simple-vhost.document-root = &amp;quot;www/&amp;quot;&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
 $HTTP[&amp;quot;host&amp;quot;] == &amp;quot;POSTFIXADMIN_DOMAIN&amp;quot; {&lt;br /&gt;
	simple-vhost.server-root   = &amp;quot;/var/www/domains/&amp;quot;&lt;br /&gt;
	simple-vhost.default-host  = &amp;quot;/POSTFIXADMIN_DOMAIN/&amp;quot;&lt;br /&gt;
	simple-vhost.document-root = &amp;quot;www/&amp;quot;&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
 $HTTP[&amp;quot;host&amp;quot;] == &amp;quot;ROUNDCUBE_DOMAIN&amp;quot; {&lt;br /&gt;
	simple-vhost.server-root   = &amp;quot;/var/www/domains/&amp;quot;&lt;br /&gt;
	simple-vhost.default-host  = &amp;quot;/ROUNDCUBE_DOMAIN/&amp;quot;&lt;br /&gt;
	simple-vhost.document-root = &amp;quot;www/&amp;quot;&lt;br /&gt;
 }&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
And, then link the appropriate www directories.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  mkdir -p /var/www/domains/ACF_DOMAIN&lt;br /&gt;
  ln -s /usr/share/acf/www /var/www/domains/ACF_DOMAIN/www&lt;br /&gt;
&lt;br /&gt;
  mkdir -p /var/www/domains/POSTFIXADMIN_DOMAIN&lt;br /&gt;
  ln -s /var/www/domains/host.example.com/www/postfixadmin /var/www/domains/POSTFIXADMIN_DOMAIN/www&lt;br /&gt;
&lt;br /&gt;
  mkdir -p /var/www/domains/ROUNDCUBE_DOMAIN&lt;br /&gt;
  ln -s /usr/share/webapps/roundcube /var/www/domains/ROUNDCUBE_DOMAIN/www&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;/div&gt;</summary>
		<author><name>Djhughes</name></author>
	</entry>
	<entry>
		<id>https://wiki.alpinelinux.org/w/index.php?title=Obtaining_user_information_via_SNMP&amp;diff=4119</id>
		<title>Obtaining user information via SNMP</title>
		<link rel="alternate" type="text/html" href="https://wiki.alpinelinux.org/w/index.php?title=Obtaining_user_information_via_SNMP&amp;diff=4119"/>
		<updated>2010-07-30T03:29:52Z</updated>

		<summary type="html">&lt;p&gt;Djhughes: added some configuration.&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Draft}}&lt;br /&gt;
&lt;br /&gt;
This documents how to use the squark-auth squid authentication helper to obtain a user-name or other information from via SNMP from a switch. The example uses an HP Procurve 5400zl switch.&lt;br /&gt;
&lt;br /&gt;
It is possible to configure HP Procurve switches to do port-based web authentication. A network device initiates traffic on a port, and is assigned to a &amp;quot;guest&amp;quot; vlan with limited or no network access. A browser needs to be opened, and the user is given a user-name and password prompt. For more information on configuring web-based authentication on an HP switch, see [http://h40060.www4.hp.com/procurve/uk/en/pdfs/application-notes/AN-S1_Web-Authentication-final-080608.pdf this link].&lt;br /&gt;
&lt;br /&gt;
The squark-auth squid authentication helper queries the HP switch via SNMP using standard MIBs to obtain the user-name associated with the IP address, which it injects into the squid access logs, which can help web-log auditors analyse . For more information see the squark-auth documentation [http://insert.reallink.com here].&lt;br /&gt;
&lt;br /&gt;
=== Enable SNMP Lookups on HP Procurve Device ===&lt;br /&gt;
&lt;br /&gt;
Create an SNMP read-only community on your HP Procurve Switch, or use one that already exists (the following example uses &amp;quot;public&amp;quot; as a community name - adjust as you like):&lt;br /&gt;
&lt;br /&gt;
{{cmd|configure&lt;br /&gt;
snmp-server community &amp;quot;public&amp;quot; restricted&lt;br /&gt;
snmp-server response-source dst-ip-of-request&lt;br /&gt;
exit }}&lt;br /&gt;
&lt;br /&gt;
The 2nd last command ensures that the SNMP replies are always returned from the switch&#039;s primary management interface. Run the above commands on all switches that the squark-auth plugin will run snmp queries against. Run them exactly as they appear.&lt;br /&gt;
&lt;br /&gt;
=== Install Squark and Configure Squid ===&lt;br /&gt;
&lt;br /&gt;
{{cmd|apk add squark}}&lt;br /&gt;
&lt;br /&gt;
The squark-auth binary used by squid is copied into the /usr/local/bin directory. All further configuration is done in /etc/squid/squid.conf:&lt;br /&gt;
&lt;br /&gt;
{{Note| The following configuration assumes that you are using SNMPv2c}}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#external ACL squid auth helper&lt;br /&gt;
# Squark authentication external acl&lt;br /&gt;
external_acl_type squark_auth children=1 ttl=1800 negative_ttl=60 concurrency=128 grace=10 %SRC /usr/local/bin/squark-auth -c &amp;lt;communityname&amp;gt; -r &amp;lt;ip.of.switch&amp;gt; -i VLAN&amp;lt;id&amp;gt; -v &amp;lt;id&amp;gt;&lt;br /&gt;
acl Zone_D_SquarkAuth external squark_auth&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Replace &amp;lt;communityname&amp;gt; with the SNMPv2 community name you have configured on your switch. Replace &amp;lt;ip.of.switch&amp;gt; with the IP of your switch, and replace &amp;lt;id&amp;gt; with the VLAN Id number of the VLAN that the clients will be connected to.&lt;br /&gt;
&lt;br /&gt;
Here is an example to illustrate how the above configuration could look:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#external ACL squid auth helper&lt;br /&gt;
# Squark authentication external acl&lt;br /&gt;
external_acl_type squark_auth children=1 ttl=1800 negative_ttl=60 concurrency=128 grace=10 %SRC /usr/local/bin/squark-auth -c public -r 192.168.0.1 -i VLAN5 -v 5&lt;br /&gt;
acl Zone_D_SquarkAuth external squark_auth&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
{{Note| If you have multiple switches in your environment, Link Layer Discovery Protocol (LLDP) should be enabled in order for squark-auth to work properly. If the IP of the switch that you have specified is a core switch (such as in a star topology network, and the all the switches in your network have LLDP enabled (usually enabled by default), then your network topology should be automatically discoverable.}}&lt;br /&gt;
&lt;br /&gt;
{{Note| For more information on the squark_auth options available, run the command &#039;&#039;&#039;man squark-auth&#039;&#039;&#039;.}}&lt;br /&gt;
&lt;br /&gt;
=== Optional: SNMP v3 Configuration ===&lt;br /&gt;
&lt;br /&gt;
Squark will use the configuration specified in &#039;&#039;&#039;/etc/snmp/snmp.conf&#039;&#039;&#039; when snmpv3 is specified as the preferred version of SNMP to use.&lt;br /&gt;
&lt;br /&gt;
Ensure that you have at least the following in &#039;&#039;&#039;/etc/snmp/snmp.conf&#039;&#039;&#039;:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
defContext none&lt;br /&gt;
defSecurityName &amp;lt;username&amp;gt;&lt;br /&gt;
defAuthPassphrase &amp;lt;password&amp;gt;&lt;br /&gt;
defVersion 3&lt;br /&gt;
defAuthType MD5&lt;br /&gt;
defSecurityLevel authNoPriv&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Adjust the above as dictated by the SNMP v3 configuration on your switch.&lt;/div&gt;</summary>
		<author><name>Djhughes</name></author>
	</entry>
	<entry>
		<id>https://wiki.alpinelinux.org/w/index.php?title=Tutorials_and_Howtos&amp;diff=4114</id>
		<title>Tutorials and Howtos</title>
		<link rel="alternate" type="text/html" href="https://wiki.alpinelinux.org/w/index.php?title=Tutorials_and_Howtos&amp;diff=4114"/>
		<updated>2010-07-26T14:31:38Z</updated>

		<summary type="html">&lt;p&gt;Djhughes: Reverted edits by MyrtaZiobro (Talk); changed back to last version by Djhughes&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Image:package_edutainment.svg|left|link=]]&lt;br /&gt;
{{TOC right}}&#039;&#039;&#039;Welcome to Tutorials and Howtos, a place of basic and advanced configuration tasks for your Alpine Linux.&#039;&#039;&#039;&lt;br /&gt;
The tutorials are hands-on and the reader is expected to try and achieve the goals described in each step, possibly with the help of a good examples. The output in one step is the starting point for the following step.&amp;lt;br/&amp;gt;&lt;br /&gt;
Howtos are smaller articles explaining how to perform a particular task with Alpine Linux. We encourage people to send in both complete articles as well as requesting topics to be covered. If you think you have the skills and knowledge to write an Alpine Linux related article please do so on this Wiki. If you want to request a topic, please add your request in this page [[Talk:Tutorials_and_Howtos|Discussion]]. 	&lt;br /&gt;
&lt;br /&gt;
== Installation ==&lt;br /&gt;
* [[Bootstrapping Alpine on Soekris net4xxx]]&lt;br /&gt;
* [[Bootstrapping Alpine on PC Engines ALIX.3]]&lt;br /&gt;
* [[Setting up a software raid1 array]]&lt;br /&gt;
* [[Setting up Logical Volumes with LVM]]&lt;br /&gt;
* [[Setting up a /var partition on software IDE raid1]]&lt;br /&gt;
* [[Replacing non-Alpine Linux with Alpine remotely]]&lt;br /&gt;
* [[Booting Alpine on an HP ML350 G6]]&lt;br /&gt;
* [[Installing XFCE as a VirtualBox guest]]&lt;br /&gt;
* [[Enable Serial Console on Boot]]&lt;br /&gt;
* [[How to enable APK caching]]&lt;br /&gt;
* [[Install Alpine on VirtualBox]]&lt;br /&gt;
* [[Upgrading to Edge]]&lt;br /&gt;
&lt;br /&gt;
== Networking ==&lt;br /&gt;
* [[Howto Configure a Network Bridge]]&lt;br /&gt;
* [[Setting up a OpenVPN-server with Alpine]]&lt;br /&gt;
* [[Setting up traffic monitoring using rrdtool (and snmp)]]&lt;br /&gt;
* [[Setting up Zaptel/Asterisk on Alpine]]&lt;br /&gt;
* [[Using HSDPA modem]]&lt;br /&gt;
* [[Using Alpine on Windows domain with IPSEC isolation]]&lt;br /&gt;
* [[Using Racoon for Remote Sites]]&lt;br /&gt;
* [[High Performance and Fault Tolerant Routing with Alpine Linux]]&lt;br /&gt;
&lt;br /&gt;
== Misc ==&lt;br /&gt;
* [[Setting up lm_sensors]]&lt;br /&gt;
* [[Setting up Satellite Internet Connection]]&lt;br /&gt;
* [[Setting up Streaming an Asterisk Channel]]&lt;br /&gt;
* [[Formatting HD/Floppy/Other]]&lt;br /&gt;
* [[Setting up Transmission (bittorrent) with Clutch WebUI]]&lt;br /&gt;
* [[Hosting services on Alpine]] &#039;&#039;(This applies to hosting mail, webservices and other services)&#039;&#039;&lt;br /&gt;
** [[Setting up postfix with virtual domains]]&lt;br /&gt;
** [[Protecting your email server with Alpine]]&lt;br /&gt;
** [[Hosting Web/Email services on Alpine]]&lt;br /&gt;
* [[Running Alpine Linux As a QEMU networked Guest ]]&lt;br /&gt;
* [[Screen on console]]&lt;br /&gt;
* [[Using espeak on Alpine Linux]]&lt;br /&gt;
* [[Generating SSL certs with ACF]]&lt;br /&gt;
* [[Setting up a ssh-server]]&lt;br /&gt;
* [[Changing passwords]]&lt;br /&gt;
* [[Multiple Instances of Services]]&lt;br /&gt;
* [[Setting up NRPE daemon]]&lt;br /&gt;
* [[IPTV How To]]&lt;br /&gt;
* [[ISP Mail Server HowTo]] &#039;&#039;(Postfix+PostfixAdmin+DoveCot+Roundcube+ClamAV+Spamd - A full-serivce ISP mail server)&#039;&#039;&lt;br /&gt;
* [[XFCE Setup]]&lt;br /&gt;
* [[Freepbx on Alpine Linux]]&lt;br /&gt;
* [[Setting up Transparent Squid Proxy]] &#039;&#039;(Covers Squid proxy and URL Filtering system)&#039;&#039;&lt;br /&gt;
** [[Obtaining user information via SNMP]] &#039;&#039;(Using the Squark Squid authentication helper)&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
== iSCSI ==&lt;br /&gt;
* [[iSCSI Target and Initiator Configuration]]&lt;br /&gt;
* [[iSCSI Raid and Clustered File Systems]]&lt;br /&gt;
&lt;br /&gt;
== Vserver ==&lt;br /&gt;
* [[Setting up a basic vserver]]&lt;br /&gt;
&lt;br /&gt;
== Obsolete Docs ==&lt;br /&gt;
Those are candidates for rewriting/removal.&lt;br /&gt;
* [[Native Harddisk Install]]&lt;br /&gt;
* [[Installing XUbuntu using Alpine boot floppy]]&lt;br /&gt;
* [[Setting up trac wiki]]&lt;/div&gt;</summary>
		<author><name>Djhughes</name></author>
	</entry>
	<entry>
		<id>https://wiki.alpinelinux.org/w/index.php?title=Setting_up_Transparent_Squid_Proxy&amp;diff=4104</id>
		<title>Setting up Transparent Squid Proxy</title>
		<link rel="alternate" type="text/html" href="https://wiki.alpinelinux.org/w/index.php?title=Setting_up_Transparent_Squid_Proxy&amp;diff=4104"/>
		<updated>2010-07-23T15:40:33Z</updated>

		<summary type="html">&lt;p&gt;Djhughes: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Draft}}&lt;br /&gt;
&lt;br /&gt;
This document covers how to set up squid as a transparent proxy server.&lt;br /&gt;
&lt;br /&gt;
The following is assumed:&lt;br /&gt;
* You have already install a server running Alpine Linux as a base, with Alpine 1.10.6 or later.&lt;br /&gt;
* Your proxy server will reside in a DMZ zone, separated from the network segment your clients are in. Other implementations are covered [http://wiki.squid-cache.org/SquidFaq/InterceptionProxy here].&lt;br /&gt;
** In order to transparently redirect web traffic from your clients to the proxy server in the DMZ, you will need to configure your intercepting router to DNAT traffic.&lt;br /&gt;
&lt;br /&gt;
=== Install Squid ===&lt;br /&gt;
&lt;br /&gt;
{{Cmd|apk add acf-squid}}&lt;br /&gt;
&lt;br /&gt;
Configure squid with at least the following configuration:&lt;br /&gt;
&lt;br /&gt;
{{Note|substitute &#039;&#039;&#039;proxy.example.com&#039;&#039;&#039; and the &#039;&#039;&#039;mynet&#039;&#039;&#039; acl for your own desired hostname and network subnet respectively}}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
# This makes squid transparent&lt;br /&gt;
http_port 8080 transparent&lt;br /&gt;
&lt;br /&gt;
visible_hostname proxy.example.com&lt;br /&gt;
cache_mem 8 MB&lt;br /&gt;
cache_dir aufs /var/cache/squid 900 16 256&lt;br /&gt;
&lt;br /&gt;
# Even though we only use one proxy, this line is recommended&lt;br /&gt;
# More info: http://www.squid-cache.org/Versions/v2/2.7/cfgman/hierarchy_stoplist.html&lt;br /&gt;
hierarchy_stoplist cgi-bin ?&lt;br /&gt;
&lt;br /&gt;
# Keep 7 days of logs&lt;br /&gt;
logfile_rotate 7&lt;br /&gt;
&lt;br /&gt;
access_log /var/log/squid/access.log squid&lt;br /&gt;
cache_store_log none&lt;br /&gt;
pid_filename /var/run/squid.pid&lt;br /&gt;
&lt;br /&gt;
# Web auditors want to see the full uri, even with the query terms&lt;br /&gt;
strip_query_terms off&lt;br /&gt;
&lt;br /&gt;
refresh_pattern ^ftp:		1440	20%	10080&lt;br /&gt;
refresh_pattern ^gopher:	1440	0%	1440&lt;br /&gt;
refresh_pattern -i (/cgi-bin/|\?) 0	0%	0&lt;br /&gt;
refresh_pattern .		0	20%	4320&lt;br /&gt;
&lt;br /&gt;
coredump_dir /var/cache/squid&lt;br /&gt;
&lt;br /&gt;
# &lt;br /&gt;
# Authentication&lt;br /&gt;
#&lt;br /&gt;
&lt;br /&gt;
# Optional authentication methods (NTLM, etc) can go here&lt;br /&gt;
&lt;br /&gt;
#&lt;br /&gt;
# Access Control Lists (ACL&#039;s)&lt;br /&gt;
#&lt;br /&gt;
&lt;br /&gt;
# These settings are recommended by squid&lt;br /&gt;
acl shoutcast rep_header X-HTTP09-First-Line ^ICY.[0-9]&lt;br /&gt;
upgrade_http0.9 deny shoutcast&lt;br /&gt;
acl apache rep_header Server ^Apache&lt;br /&gt;
broken_vary_encoding allow apache&lt;br /&gt;
&lt;br /&gt;
# Standard ACL settings&lt;br /&gt;
acl QUERY urlpath_regex cgi-bin \? asp aspx jsp&lt;br /&gt;
acl all src all&lt;br /&gt;
acl manager proto cache_object&lt;br /&gt;
acl localhost src 127.0.0.1/32&lt;br /&gt;
acl to_localhost dst 127.0.0.0/8&lt;br /&gt;
acl SSL_ports port 443 563 8004 9000&lt;br /&gt;
acl Safe_ports port 21 70 80 81 210 280 443 563 499 591 777 1024 1022 1025-65535&lt;br /&gt;
acl purge method PURGE&lt;br /&gt;
acl CONNECT method CONNECT&lt;br /&gt;
&lt;br /&gt;
# Require authentication&lt;br /&gt;
#acl userlist  proxy_auth REQUIRED&lt;br /&gt;
acl userlist  src 0.0.0.0/0.0.0.0&lt;br /&gt;
&lt;br /&gt;
# Definition of network subnets&lt;br /&gt;
acl mynet src 192.168.0.0/24&lt;br /&gt;
&lt;br /&gt;
#&lt;br /&gt;
# Access restrictions&lt;br /&gt;
#&lt;br /&gt;
&lt;br /&gt;
cache deny QUERY&lt;br /&gt;
&lt;br /&gt;
# Only allow cachemgr access from localhost&lt;br /&gt;
http_access allow manager localhost&lt;br /&gt;
http_access deny manager&lt;br /&gt;
&lt;br /&gt;
# Only allow purge requests from localhost&lt;br /&gt;
http_access allow purge localhost&lt;br /&gt;
http_access deny purge&lt;br /&gt;
&lt;br /&gt;
# Deny requests to unknown ports&lt;br /&gt;
http_access deny !Safe_ports&lt;br /&gt;
&lt;br /&gt;
# Deny CONNECT to other than SSL ports&lt;br /&gt;
http_access deny CONNECT !SSL_ports&lt;br /&gt;
&lt;br /&gt;
# Allow hosts in mynet subnet to access the entire Internet without being&lt;br /&gt;
# authenticated&lt;br /&gt;
http_access allow mynet&lt;br /&gt;
&lt;br /&gt;
# Denying all access not explicitly allowed&lt;br /&gt;
http_access deny all&lt;br /&gt;
&lt;br /&gt;
http_reply_access allow all&lt;br /&gt;
icp_access allow all&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Check squid with:&lt;br /&gt;
{{Cmd|squid -k reconfigure}}&lt;br /&gt;
&lt;br /&gt;
Start squid:&lt;br /&gt;
{{Cmd|/etc/init.d/squid start}}&lt;br /&gt;
&lt;br /&gt;
Add squid to boot-up sequence:&lt;br /&gt;
{{Cmd|rc-update add squid default}}&lt;br /&gt;
&lt;br /&gt;
Remember to add port 8080 to the permitted ports clients can connect on to any firewalls on your proxy server or inbetween the proxy and the clients.&lt;br /&gt;
&lt;br /&gt;
If you are running an Alpine Linux firewall on the firewall separating the Proxy from the clients, you will need to redirect all traffic from your client subnet on port 80 to the proxy server on port 8080 to allow web traffic to be proxied.&lt;br /&gt;
&lt;br /&gt;
If you are running shorewall, add this to your /etc/shorewall/rules file:&lt;br /&gt;
&lt;br /&gt;
{{Note|Substitute &#039;&#039;&#039;loc&#039;&#039;&#039; and &#039;&#039;&#039;dmz:172.16.1.2:8080&#039;&#039;&#039; for your client subnet zone and proxy server zone and IP as defined in /etc/shorewall/zones.}}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
## This forces all web traffic to be redirected to the proxy on port 8080&lt;br /&gt;
DNAT    loc      dmz:172.16.1.2:8080     tcp    80&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
And restart shorewall with:&lt;br /&gt;
 &lt;br /&gt;
{{Cmd|shorewall check}}&lt;br /&gt;
{{Cmd|shorewall restart}}&lt;/div&gt;</summary>
		<author><name>Djhughes</name></author>
	</entry>
	<entry>
		<id>https://wiki.alpinelinux.org/w/index.php?title=Template:Draft&amp;diff=4103</id>
		<title>Template:Draft</title>
		<link rel="alternate" type="text/html" href="https://wiki.alpinelinux.org/w/index.php?title=Template:Draft&amp;diff=4103"/>
		<updated>2010-07-23T15:39:33Z</updated>

		<summary type="html">&lt;p&gt;Djhughes: created using K0gen&amp;#039;s idea&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&amp;lt;noinclude&amp;gt;{{Template}}&lt;br /&gt;
&lt;br /&gt;
== Template Documentation ==&lt;br /&gt;
This template should be used for work-in-progress pages.&lt;br /&gt;
Example:&lt;br /&gt;
&amp;lt;nowiki&amp;gt;{{Draft}}&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Will produce:&lt;br /&gt;
{{Draft}}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/noinclude&amp;gt;&amp;lt;onlyinclude&amp;gt;[[Category:Draft]]&amp;lt;center&amp;gt;&lt;br /&gt;
{|style=&amp;quot;width: 33em; padding:2px; margin:0; margin-bottom:10px; background-color:#f6f6f6; border:1px solid #aaa; -moz-border-radius-bottomright: 0.5em; -moz-border-radius-bottomleft: 1em; border-radius-bottomright: 0.5em; border-radius-bottomleft: 1em; -webkit-border-bottom-right-radius: 0.5em; -webkit-border-bottom-left-radius: 1em;&amp;quot;&lt;br /&gt;
|&amp;lt;div style=&amp;quot;font-size: 1.5em; font-weight:bold;&amp;quot;&amp;gt; [[Image:Underconstruction_clock_icon_gray.svg‎|64px|left|link=]] This page is work in progress ... &amp;lt;/div&amp;gt;&amp;lt;p style=&amp;quot;text-align: center; font-size: 87%;&amp;quot;&amp;gt;This page is under construction. Do not follow this document until this notice is removed.&amp;lt;/p&amp;gt;&lt;br /&gt;
|}&amp;lt;/center&amp;gt;&amp;lt;/onlyinclude&amp;gt;&lt;/div&gt;</summary>
		<author><name>Djhughes</name></author>
	</entry>
	<entry>
		<id>https://wiki.alpinelinux.org/w/index.php?title=Template:Sandbox&amp;diff=4102</id>
		<title>Template:Sandbox</title>
		<link rel="alternate" type="text/html" href="https://wiki.alpinelinux.org/w/index.php?title=Template:Sandbox&amp;diff=4102"/>
		<updated>2010-07-23T15:33:52Z</updated>

		<summary type="html">&lt;p&gt;Djhughes: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&amp;lt;noinclude&amp;gt;{{Template}}&lt;br /&gt;
== Template Documentation ==&lt;br /&gt;
This template should be used for commands&lt;br /&gt;
Example:&lt;br /&gt;
&amp;lt;nowiki&amp;gt;{{Draft}}&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Will produce:&lt;br /&gt;
&amp;lt;center&amp;gt;&lt;br /&gt;
{|style=&amp;quot;width: 33em; padding:2px; margin:0; margin-bottom:10px; background-color:#f6f6f6; border:1px solid #aaa; -moz-border-radius-bottomright: 0.5em; -moz-border-radius-bottomleft: 1em; border-radius-bottomright: 0.5em; border-radius-bottomleft: 1em; -webkit-border-bottom-right-radius: 0.5em; -webkit-border-bottom-left-radius: 1em;&amp;quot;&lt;br /&gt;
|&amp;lt;div style=&amp;quot;font-size: 1.5em; font-weight:bold;&amp;quot;&amp;gt; [[Image:Underconstruction_clock_icon_gray.svg‎|64px|left|link=]] This page is work in progress ... &amp;lt;/div&amp;gt;&amp;lt;p style=&amp;quot;text-align: center; font-size: 87%;&amp;quot;&amp;gt;This page is under construction. Do not follow this document until this notice is removed.&amp;lt;/p&amp;gt;&lt;br /&gt;
|}&amp;lt;/center&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== [[Image:Newspaper_Cover.svg‎|32px|link=]] Recent News ==&lt;br /&gt;
{{Sandbox|2010-07-16 Alpine 2.0.0 Beta3 released|&lt;br /&gt;
This is the first announced beta release for v2.0 series. See [[Release Notes for Alpine 2.0.0_beta3]] for more details of the release.&lt;br /&gt;
|[[User:ncopa|ncopa]] 20:58, 16 July 2010 (GMT)&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
{{Sandbox|2010-07-16 Alpine 2.0.0 Beta3 released|&lt;br /&gt;
This is the first announced beta release for v2.0 series. See [[Release Notes for Alpine 2.0.0_beta3]] for more details of the release.&lt;br /&gt;
|[[User:ncopa|ncopa]] 20:58, 16 July 2010 (GMT)&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/noinclude&amp;gt;&amp;lt;onlyinclude&amp;gt;&lt;br /&gt;
&amp;lt;span class=&amp;quot;editsection plainlinks&amp;quot; id=&amp;quot;doc_editlinks&amp;quot;&amp;gt;[[{{fullurl:News_talk:{{{1}}}|}} Discuss]]&amp;lt;/span&amp;gt;&lt;br /&gt;
&amp;lt;h5&amp;gt;{{{1}}}&amp;lt;/h5&amp;gt;&lt;br /&gt;
{{{2}}}&lt;br /&gt;
&amp;lt;div style=&amp;quot;text-align: right;&amp;quot;&amp;gt;{{{3}}}&amp;lt;/div&amp;gt;&lt;br /&gt;
----&lt;br /&gt;
&amp;lt;/onlyinclude&amp;gt;&lt;/div&gt;</summary>
		<author><name>Djhughes</name></author>
	</entry>
	<entry>
		<id>https://wiki.alpinelinux.org/w/index.php?title=Setting_up_Transparent_Squid_Proxy&amp;diff=4101</id>
		<title>Setting up Transparent Squid Proxy</title>
		<link rel="alternate" type="text/html" href="https://wiki.alpinelinux.org/w/index.php?title=Setting_up_Transparent_Squid_Proxy&amp;diff=4101"/>
		<updated>2010-07-23T15:24:57Z</updated>

		<summary type="html">&lt;p&gt;Djhughes: added some templates&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This document covers how to set up squid as a transparent proxy server.&lt;br /&gt;
&lt;br /&gt;
The following is assumed:&lt;br /&gt;
* You have already install a server running Alpine Linux as a base, with Alpine 1.10.6 or later.&lt;br /&gt;
* Your proxy server will reside in a DMZ zone, separated from the network segment your clients are in. Other implementations are covered [http://wiki.squid-cache.org/SquidFaq/InterceptionProxy here].&lt;br /&gt;
** In order to transparently redirect web traffic from your clients to the proxy server in the DMZ, you will need to configure your intercepting router to DNAT traffic.&lt;br /&gt;
&lt;br /&gt;
=== Install Squid ===&lt;br /&gt;
&lt;br /&gt;
{{Cmd|apk add acf-squid}}&lt;br /&gt;
&lt;br /&gt;
Configure squid with at least the following configuration:&lt;br /&gt;
&lt;br /&gt;
{{Note|substitute &#039;&#039;&#039;proxy.example.com&#039;&#039;&#039; and the &#039;&#039;&#039;mynet&#039;&#039;&#039; acl for your own desired hostname and network subnet respectively}}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
# This makes squid transparent&lt;br /&gt;
http_port 8080 transparent&lt;br /&gt;
&lt;br /&gt;
visible_hostname proxy.example.com&lt;br /&gt;
cache_mem 8 MB&lt;br /&gt;
cache_dir aufs /var/cache/squid 900 16 256&lt;br /&gt;
&lt;br /&gt;
# Even though we only use one proxy, this line is recommended&lt;br /&gt;
# More info: http://www.squid-cache.org/Versions/v2/2.7/cfgman/hierarchy_stoplist.html&lt;br /&gt;
hierarchy_stoplist cgi-bin ?&lt;br /&gt;
&lt;br /&gt;
# Keep 7 days of logs&lt;br /&gt;
logfile_rotate 7&lt;br /&gt;
&lt;br /&gt;
access_log /var/log/squid/access.log squid&lt;br /&gt;
cache_store_log none&lt;br /&gt;
pid_filename /var/run/squid.pid&lt;br /&gt;
&lt;br /&gt;
# Web auditors want to see the full uri, even with the query terms&lt;br /&gt;
strip_query_terms off&lt;br /&gt;
&lt;br /&gt;
refresh_pattern ^ftp:		1440	20%	10080&lt;br /&gt;
refresh_pattern ^gopher:	1440	0%	1440&lt;br /&gt;
refresh_pattern -i (/cgi-bin/|\?) 0	0%	0&lt;br /&gt;
refresh_pattern .		0	20%	4320&lt;br /&gt;
&lt;br /&gt;
coredump_dir /var/cache/squid&lt;br /&gt;
&lt;br /&gt;
# &lt;br /&gt;
# Authentication&lt;br /&gt;
#&lt;br /&gt;
&lt;br /&gt;
# Optional authentication methods (NTLM, etc) can go here&lt;br /&gt;
&lt;br /&gt;
#&lt;br /&gt;
# Access Control Lists (ACL&#039;s)&lt;br /&gt;
#&lt;br /&gt;
&lt;br /&gt;
# These settings are recommended by squid&lt;br /&gt;
acl shoutcast rep_header X-HTTP09-First-Line ^ICY.[0-9]&lt;br /&gt;
upgrade_http0.9 deny shoutcast&lt;br /&gt;
acl apache rep_header Server ^Apache&lt;br /&gt;
broken_vary_encoding allow apache&lt;br /&gt;
&lt;br /&gt;
# Standard ACL settings&lt;br /&gt;
acl QUERY urlpath_regex cgi-bin \? asp aspx jsp&lt;br /&gt;
acl all src all&lt;br /&gt;
acl manager proto cache_object&lt;br /&gt;
acl localhost src 127.0.0.1/32&lt;br /&gt;
acl to_localhost dst 127.0.0.0/8&lt;br /&gt;
acl SSL_ports port 443 563 8004 9000&lt;br /&gt;
acl Safe_ports port 21 70 80 81 210 280 443 563 499 591 777 1024 1022 1025-65535&lt;br /&gt;
acl purge method PURGE&lt;br /&gt;
acl CONNECT method CONNECT&lt;br /&gt;
&lt;br /&gt;
# Require authentication&lt;br /&gt;
#acl userlist  proxy_auth REQUIRED&lt;br /&gt;
acl userlist  src 0.0.0.0/0.0.0.0&lt;br /&gt;
&lt;br /&gt;
# Definition of network subnets&lt;br /&gt;
acl mynet src 192.168.0.0/24&lt;br /&gt;
&lt;br /&gt;
#&lt;br /&gt;
# Access restrictions&lt;br /&gt;
#&lt;br /&gt;
&lt;br /&gt;
cache deny QUERY&lt;br /&gt;
&lt;br /&gt;
# Only allow cachemgr access from localhost&lt;br /&gt;
http_access allow manager localhost&lt;br /&gt;
http_access deny manager&lt;br /&gt;
&lt;br /&gt;
# Only allow purge requests from localhost&lt;br /&gt;
http_access allow purge localhost&lt;br /&gt;
http_access deny purge&lt;br /&gt;
&lt;br /&gt;
# Deny requests to unknown ports&lt;br /&gt;
http_access deny !Safe_ports&lt;br /&gt;
&lt;br /&gt;
# Deny CONNECT to other than SSL ports&lt;br /&gt;
http_access deny CONNECT !SSL_ports&lt;br /&gt;
&lt;br /&gt;
# Allow hosts in mynet subnet to access the entire Internet without being&lt;br /&gt;
# authenticated&lt;br /&gt;
http_access allow mynet&lt;br /&gt;
&lt;br /&gt;
# Denying all access not explicitly allowed&lt;br /&gt;
http_access deny all&lt;br /&gt;
&lt;br /&gt;
http_reply_access allow all&lt;br /&gt;
icp_access allow all&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Check squid with:&lt;br /&gt;
{{Cmd|squid -k reconfigure}}&lt;br /&gt;
&lt;br /&gt;
Start squid:&lt;br /&gt;
{{Cmd|/etc/init.d/squid start}}&lt;br /&gt;
&lt;br /&gt;
Add squid to boot-up sequence:&lt;br /&gt;
{{Cmd|rc-update add squid default}}&lt;br /&gt;
&lt;br /&gt;
Remember to add port 8080 to the permitted ports clients can connect on to any firewalls on your proxy server or inbetween the proxy and the clients.&lt;br /&gt;
&lt;br /&gt;
If you are running an Alpine Linux firewall on the firewall separating the Proxy from the clients, you will need to redirect all traffic from your client subnet on port 80 to the proxy server on port 8080 to allow web traffic to be proxied.&lt;br /&gt;
&lt;br /&gt;
If you are running shorewall, add this to your /etc/shorewall/rules file:&lt;br /&gt;
&lt;br /&gt;
{{Note|Substitute &#039;&#039;&#039;loc&#039;&#039;&#039; and &#039;&#039;&#039;dmz:172.16.1.2:8080&#039;&#039;&#039; for your client subnet zone and proxy server zone and IP as defined in /etc/shorewall/zones.}}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
## This forces all web traffic to be redirected to the proxy on port 8080&lt;br /&gt;
DNAT    loc      dmz:172.16.1.2:8080     tcp    80&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
And restart shorewall with:&lt;br /&gt;
 &lt;br /&gt;
{{Cmd|shorewall check}}&lt;br /&gt;
{{Cmd|shorewall restart}}&lt;/div&gt;</summary>
		<author><name>Djhughes</name></author>
	</entry>
	<entry>
		<id>https://wiki.alpinelinux.org/w/index.php?title=Template:Cmd&amp;diff=4100</id>
		<title>Template:Cmd</title>
		<link rel="alternate" type="text/html" href="https://wiki.alpinelinux.org/w/index.php?title=Template:Cmd&amp;diff=4100"/>
		<updated>2010-07-23T15:23:35Z</updated>

		<summary type="html">&lt;p&gt;Djhughes: increased font size&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&amp;lt;noinclude&amp;gt;{{Template}}&lt;br /&gt;
== Template Documentation ==&lt;br /&gt;
This template should be used for commands&amp;lt;br /&amp;gt;&lt;br /&gt;
Example:&lt;br /&gt;
&amp;lt;nowiki&amp;gt;{{Cmd|apk add -U}}&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Will produce:&lt;br /&gt;
{{Cmd|apk add -U}}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/noinclude&amp;gt;&amp;lt;onlyinclude&amp;gt;&amp;lt;div style=&amp;quot;background-color:#eeeeee; color:#111111; padding:.05em .5em; margin:.5em; border:1px solid #dddddd; border-left:2px solid #dddddd; white-space:pre; font-family:monospace; font-size:10pt;&amp;quot;&amp;gt;{{{1}}}&amp;lt;/div&amp;gt;&amp;lt;/onlyinclude&amp;gt;&lt;/div&gt;</summary>
		<author><name>Djhughes</name></author>
	</entry>
	<entry>
		<id>https://wiki.alpinelinux.org/w/index.php?title=Obtaining_user_information_via_SNMP&amp;diff=4099</id>
		<title>Obtaining user information via SNMP</title>
		<link rel="alternate" type="text/html" href="https://wiki.alpinelinux.org/w/index.php?title=Obtaining_user_information_via_SNMP&amp;diff=4099"/>
		<updated>2010-07-23T12:35:26Z</updated>

		<summary type="html">&lt;p&gt;Djhughes: began work on squark-auth squid helper documentation&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&#039;&#039;&#039;Draft&#039;&#039;&#039; - Work in progress&lt;br /&gt;
&lt;br /&gt;
This documents how to use the squark-auth squid authentication helper to obtain a user-name or other information from via SNMP from a switch. The example uses an HP Procurve 5400zl switch.&lt;br /&gt;
&lt;br /&gt;
It is possible to configure HP Procurve switches to do port-based web authentication. A network device initiates traffic on a port, and is assigned to a &amp;quot;guest&amp;quot; vlan with limited or no network access. A browser needs to be opened, and the user is given a user-name and password prompt. For more information on configuring web-based authentication on an HP switch, see [http://h40060.www4.hp.com/procurve/uk/en/pdfs/application-notes/AN-S1_Web-Authentication-final-080608.pdf this link].&lt;br /&gt;
&lt;br /&gt;
The squark-auth squid authentication helper queries the HP switch via SNMP using standard MIBs to obtain the user-name associated with the IP address, which it injects into the squid access logs, which can help web-log auditors analyse . For more information see the squark-auth documentation [http://insert.reallink.com here].&lt;br /&gt;
&lt;br /&gt;
=== Enable SNMP Lookups on HP Procurve Device ===&lt;br /&gt;
&lt;br /&gt;
Create an SNMP read-only community on your HP Procurve Switch, or use one that already exists (the following example uses &amp;quot;public&amp;quot; as a community name - adjust as you like):&lt;br /&gt;
&lt;br /&gt;
 configure&lt;br /&gt;
 snmp-server community &amp;quot;public&amp;quot; restricted&lt;br /&gt;
 snmp-server response-source dst-ip-of-request&lt;br /&gt;
 exit&lt;br /&gt;
&lt;br /&gt;
The 2nd last command ensures that the SNMP replies are always returned from the switch&#039;s primary management interface. Run the above commands on all switches that the squark-auth plugin will run snmp queries against. Run them exactly as they appear.&lt;br /&gt;
&lt;br /&gt;
=== Install Squark and Configure Squid ===&lt;br /&gt;
&lt;br /&gt;
 apk add squark&lt;br /&gt;
&lt;br /&gt;
The squark-auth binary used by squid is copied into the /usr/local/bin directory. All further configuration is done in /etc/squid/squid.conf:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#external ACL squid auth helper&lt;br /&gt;
insert code here&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;/div&gt;</summary>
		<author><name>Djhughes</name></author>
	</entry>
	<entry>
		<id>https://wiki.alpinelinux.org/w/index.php?title=Setting_up_Transparent_Squid_Proxy&amp;diff=4098</id>
		<title>Setting up Transparent Squid Proxy</title>
		<link rel="alternate" type="text/html" href="https://wiki.alpinelinux.org/w/index.php?title=Setting_up_Transparent_Squid_Proxy&amp;diff=4098"/>
		<updated>2010-07-23T09:55:02Z</updated>

		<summary type="html">&lt;p&gt;Djhughes: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;br /&gt;
This document covers how to set up squid as a transparent proxy server.&lt;br /&gt;
&lt;br /&gt;
The following is assumed:&lt;br /&gt;
* You have already install a server running Alpine Linux as a base, with Alpine 1.10.6 or later.&lt;br /&gt;
* Your proxy server will reside in a DMZ zone, separated from the network segment your clients are in. Other implementations are covered here&lt;br /&gt;
** In order to transparently redirect web traffic from your clients to the proxy server in the DMZ, you will need to configure &lt;br /&gt;
&lt;br /&gt;
=== Install Squid ===&lt;br /&gt;
&lt;br /&gt;
 apk add acf-squid&lt;br /&gt;
&lt;br /&gt;
Configure squid with at least the following configuration:&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Note:&#039;&#039;&#039; substitute &#039;&#039;&#039;proxy.example.com&#039;&#039;&#039; and the &#039;&#039;&#039;mynet&#039;&#039;&#039; acl for your own desired hostname and network subnet respectively):&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
# This makes squid transparent&lt;br /&gt;
http_port 8080 transparent&lt;br /&gt;
&lt;br /&gt;
visible_hostname proxy.example.com&lt;br /&gt;
cache_mem 8 MB&lt;br /&gt;
cache_dir aufs /var/cache/squid 900 16 256&lt;br /&gt;
&lt;br /&gt;
# Even though we only use one proxy, this line is recommended&lt;br /&gt;
# More info: http://www.squid-cache.org/Versions/v2/2.7/cfgman/hierarchy_stoplist.html&lt;br /&gt;
hierarchy_stoplist cgi-bin ?&lt;br /&gt;
&lt;br /&gt;
# Keep 7 days of logs&lt;br /&gt;
logfile_rotate 7&lt;br /&gt;
&lt;br /&gt;
access_log /var/log/squid/access.log squid&lt;br /&gt;
cache_store_log none&lt;br /&gt;
pid_filename /var/run/squid.pid&lt;br /&gt;
&lt;br /&gt;
# Web auditors want to see the full uri, even with the query terms&lt;br /&gt;
strip_query_terms off&lt;br /&gt;
&lt;br /&gt;
refresh_pattern ^ftp:		1440	20%	10080&lt;br /&gt;
refresh_pattern ^gopher:	1440	0%	1440&lt;br /&gt;
refresh_pattern -i (/cgi-bin/|\?) 0	0%	0&lt;br /&gt;
refresh_pattern .		0	20%	4320&lt;br /&gt;
&lt;br /&gt;
coredump_dir /var/cache/squid&lt;br /&gt;
&lt;br /&gt;
# &lt;br /&gt;
# Authentication&lt;br /&gt;
#&lt;br /&gt;
&lt;br /&gt;
# Optional authentication methods (NTLM, etc) can go here&lt;br /&gt;
&lt;br /&gt;
#&lt;br /&gt;
# Access Control Lists (ACL&#039;s)&lt;br /&gt;
#&lt;br /&gt;
&lt;br /&gt;
# These settings are recommended by squid&lt;br /&gt;
acl shoutcast rep_header X-HTTP09-First-Line ^ICY.[0-9]&lt;br /&gt;
upgrade_http0.9 deny shoutcast&lt;br /&gt;
acl apache rep_header Server ^Apache&lt;br /&gt;
broken_vary_encoding allow apache&lt;br /&gt;
&lt;br /&gt;
# Standard ACL settings&lt;br /&gt;
acl QUERY urlpath_regex cgi-bin \? asp aspx jsp&lt;br /&gt;
acl all src all&lt;br /&gt;
acl manager proto cache_object&lt;br /&gt;
acl localhost src 127.0.0.1/32&lt;br /&gt;
acl to_localhost dst 127.0.0.0/8&lt;br /&gt;
acl SSL_ports port 443 563 8004 9000&lt;br /&gt;
acl Safe_ports port 21 70 80 81 210 280 443 563 499 591 777 1024 1022 1025-65535&lt;br /&gt;
acl purge method PURGE&lt;br /&gt;
acl CONNECT method CONNECT&lt;br /&gt;
&lt;br /&gt;
# Require authentication&lt;br /&gt;
#acl userlist  proxy_auth REQUIRED&lt;br /&gt;
acl userlist  src 0.0.0.0/0.0.0.0&lt;br /&gt;
&lt;br /&gt;
# Definition of network subnets&lt;br /&gt;
acl mynet src 192.168.0.0/24&lt;br /&gt;
&lt;br /&gt;
#&lt;br /&gt;
# Access restrictions&lt;br /&gt;
#&lt;br /&gt;
&lt;br /&gt;
cache deny QUERY&lt;br /&gt;
&lt;br /&gt;
# Only allow cachemgr access from localhost&lt;br /&gt;
http_access allow manager localhost&lt;br /&gt;
http_access deny manager&lt;br /&gt;
&lt;br /&gt;
# Only allow purge requests from localhost&lt;br /&gt;
http_access allow purge localhost&lt;br /&gt;
http_access deny purge&lt;br /&gt;
&lt;br /&gt;
# Deny requests to unknown ports&lt;br /&gt;
http_access deny !Safe_ports&lt;br /&gt;
&lt;br /&gt;
# Deny CONNECT to other than SSL ports&lt;br /&gt;
http_access deny CONNECT !SSL_ports&lt;br /&gt;
&lt;br /&gt;
# Allow hosts in mynet subnet to access the entire Internet without being&lt;br /&gt;
# authenticated&lt;br /&gt;
http_access allow mynet&lt;br /&gt;
&lt;br /&gt;
# Denying all access not explicitly allowed&lt;br /&gt;
http_access deny all&lt;br /&gt;
&lt;br /&gt;
http_reply_access allow all&lt;br /&gt;
icp_access allow all&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Check squid with:&lt;br /&gt;
 squid -k reconfigure&lt;br /&gt;
&lt;br /&gt;
Start squid:&lt;br /&gt;
 /etc/init.d/squid start&lt;br /&gt;
&lt;br /&gt;
Add squid to boot-up sequence:&lt;br /&gt;
rc-update add squid default&lt;br /&gt;
&lt;br /&gt;
Remember to add port 8080 to the permitted ports clients can connect on to any firewalls on your proxy server or inbetween the proxy and the clients.&lt;br /&gt;
&lt;br /&gt;
If you are running an Alpine Linux firewall on the firewall separating the Proxy from the clients, you will need to redirect all traffic from your client subnet on port 80 to the proxy server on port 8080 to allow web traffic to be proxied.&lt;br /&gt;
&lt;br /&gt;
If you are running shorewall, add this to your /etc/shorewall/rules file:&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Note:&#039;&#039;&#039; substitute &#039;&#039;&#039;loc&#039;&#039;&#039; and &#039;&#039;&#039;dmz:172.16.1.2:8080&#039;&#039;&#039; for your client subnet zone and proxy server zone and IP as defined in /etc/shorewall/zones.&lt;br /&gt;
&lt;br /&gt;
 ## This forces all web traffic to be redirected to the proxy on port 8080&lt;br /&gt;
 DNAT    loc      dmz:172.16.1.2:8080     tcp    80&lt;br /&gt;
&lt;br /&gt;
And restart shorewall with:&lt;br /&gt;
 &lt;br /&gt;
 shorewall check&lt;br /&gt;
 shorewall restart&lt;/div&gt;</summary>
		<author><name>Djhughes</name></author>
	</entry>
	<entry>
		<id>https://wiki.alpinelinux.org/w/index.php?title=Setting_up_Transparent_Squid_Proxy&amp;diff=4097</id>
		<title>Setting up Transparent Squid Proxy</title>
		<link rel="alternate" type="text/html" href="https://wiki.alpinelinux.org/w/index.php?title=Setting_up_Transparent_Squid_Proxy&amp;diff=4097"/>
		<updated>2010-07-23T09:54:21Z</updated>

		<summary type="html">&lt;p&gt;Djhughes: created page&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Squid Transparent Proxy Server ==&lt;br /&gt;
&lt;br /&gt;
This document covers how to set up squid as a transparent proxy server.&lt;br /&gt;
&lt;br /&gt;
The following is assumed:&lt;br /&gt;
* You have already install a server running Alpine Linux as a base, with Alpine 1.10.6 or later.&lt;br /&gt;
* Your proxy server will reside in a DMZ zone, separated from the network segment your clients are in. Other implementations are covered here&lt;br /&gt;
** In order to transparently redirect web traffic from your clients to the proxy server in the DMZ, you will need to configure &lt;br /&gt;
&lt;br /&gt;
=== Install Squid ===&lt;br /&gt;
&lt;br /&gt;
 apk add acf-squid&lt;br /&gt;
&lt;br /&gt;
Configure squid with at least the following configuration:&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Note:&#039;&#039;&#039; substitute &#039;&#039;&#039;proxy.example.com&#039;&#039;&#039; and the &#039;&#039;&#039;mynet&#039;&#039;&#039; acl for your own desired hostname and network subnet respectively):&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
# This makes squid transparent&lt;br /&gt;
http_port 8080 transparent&lt;br /&gt;
&lt;br /&gt;
visible_hostname proxy.example.com&lt;br /&gt;
cache_mem 8 MB&lt;br /&gt;
cache_dir aufs /var/cache/squid 900 16 256&lt;br /&gt;
&lt;br /&gt;
# Even though we only use one proxy, this line is recommended&lt;br /&gt;
# More info: http://www.squid-cache.org/Versions/v2/2.7/cfgman/hierarchy_stoplist.html&lt;br /&gt;
hierarchy_stoplist cgi-bin ?&lt;br /&gt;
&lt;br /&gt;
# Keep 7 days of logs&lt;br /&gt;
logfile_rotate 7&lt;br /&gt;
&lt;br /&gt;
access_log /var/log/squid/access.log squid&lt;br /&gt;
cache_store_log none&lt;br /&gt;
pid_filename /var/run/squid.pid&lt;br /&gt;
&lt;br /&gt;
# Web auditors want to see the full uri, even with the query terms&lt;br /&gt;
strip_query_terms off&lt;br /&gt;
&lt;br /&gt;
refresh_pattern ^ftp:		1440	20%	10080&lt;br /&gt;
refresh_pattern ^gopher:	1440	0%	1440&lt;br /&gt;
refresh_pattern -i (/cgi-bin/|\?) 0	0%	0&lt;br /&gt;
refresh_pattern .		0	20%	4320&lt;br /&gt;
&lt;br /&gt;
coredump_dir /var/cache/squid&lt;br /&gt;
&lt;br /&gt;
# &lt;br /&gt;
# Authentication&lt;br /&gt;
#&lt;br /&gt;
&lt;br /&gt;
# Optional authentication methods (NTLM, etc) can go here&lt;br /&gt;
&lt;br /&gt;
#&lt;br /&gt;
# Access Control Lists (ACL&#039;s)&lt;br /&gt;
#&lt;br /&gt;
&lt;br /&gt;
# These settings are recommended by squid&lt;br /&gt;
acl shoutcast rep_header X-HTTP09-First-Line ^ICY.[0-9]&lt;br /&gt;
upgrade_http0.9 deny shoutcast&lt;br /&gt;
acl apache rep_header Server ^Apache&lt;br /&gt;
broken_vary_encoding allow apache&lt;br /&gt;
&lt;br /&gt;
# Standard ACL settings&lt;br /&gt;
acl QUERY urlpath_regex cgi-bin \? asp aspx jsp&lt;br /&gt;
acl all src all&lt;br /&gt;
acl manager proto cache_object&lt;br /&gt;
acl localhost src 127.0.0.1/32&lt;br /&gt;
acl to_localhost dst 127.0.0.0/8&lt;br /&gt;
acl SSL_ports port 443 563 8004 9000&lt;br /&gt;
acl Safe_ports port 21 70 80 81 210 280 443 563 499 591 777 1024 1022 1025-65535&lt;br /&gt;
acl purge method PURGE&lt;br /&gt;
acl CONNECT method CONNECT&lt;br /&gt;
&lt;br /&gt;
# Require authentication&lt;br /&gt;
#acl userlist  proxy_auth REQUIRED&lt;br /&gt;
acl userlist  src 0.0.0.0/0.0.0.0&lt;br /&gt;
&lt;br /&gt;
# Definition of network subnets&lt;br /&gt;
acl mynet src 192.168.0.0/24&lt;br /&gt;
&lt;br /&gt;
#&lt;br /&gt;
# Access restrictions&lt;br /&gt;
#&lt;br /&gt;
&lt;br /&gt;
cache deny QUERY&lt;br /&gt;
&lt;br /&gt;
# Only allow cachemgr access from localhost&lt;br /&gt;
http_access allow manager localhost&lt;br /&gt;
http_access deny manager&lt;br /&gt;
&lt;br /&gt;
# Only allow purge requests from localhost&lt;br /&gt;
http_access allow purge localhost&lt;br /&gt;
http_access deny purge&lt;br /&gt;
&lt;br /&gt;
# Deny requests to unknown ports&lt;br /&gt;
http_access deny !Safe_ports&lt;br /&gt;
&lt;br /&gt;
# Deny CONNECT to other than SSL ports&lt;br /&gt;
http_access deny CONNECT !SSL_ports&lt;br /&gt;
&lt;br /&gt;
# Allow hosts in mynet subnet to access the entire Internet without being&lt;br /&gt;
# authenticated&lt;br /&gt;
http_access allow mynet&lt;br /&gt;
&lt;br /&gt;
# Denying all access not explicitly allowed&lt;br /&gt;
http_access deny all&lt;br /&gt;
&lt;br /&gt;
http_reply_access allow all&lt;br /&gt;
icp_access allow all&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Check squid with:&lt;br /&gt;
 squid -k reconfigure&lt;br /&gt;
&lt;br /&gt;
Start squid:&lt;br /&gt;
 /etc/init.d/squid start&lt;br /&gt;
&lt;br /&gt;
Add squid to boot-up sequence:&lt;br /&gt;
rc-update add squid default&lt;br /&gt;
&lt;br /&gt;
Remember to add port 8080 to the permitted ports clients can connect on to any firewalls on your proxy server or inbetween the proxy and the clients.&lt;br /&gt;
&lt;br /&gt;
If you are running an Alpine Linux firewall on the firewall separating the Proxy from the clients, you will need to redirect all traffic from your client subnet on port 80 to the proxy server on port 8080 to allow web traffic to be proxied.&lt;br /&gt;
&lt;br /&gt;
If you are running shorewall, add this to your /etc/shorewall/rules file:&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Note:&#039;&#039;&#039; substitute &#039;&#039;&#039;loc&#039;&#039;&#039; and &#039;&#039;&#039;dmz:172.16.1.2:8080&#039;&#039;&#039; for your client subnet zone and proxy server zone and IP as defined in /etc/shorewall/zones.&lt;br /&gt;
&lt;br /&gt;
 ## This forces all web traffic to be redirected to the proxy on port 8080&lt;br /&gt;
 DNAT    loc      dmz:172.16.1.2:8080     tcp    80&lt;br /&gt;
&lt;br /&gt;
And restart shorewall with:&lt;br /&gt;
 &lt;br /&gt;
 shorewall check&lt;br /&gt;
 shorewall restart&lt;/div&gt;</summary>
		<author><name>Djhughes</name></author>
	</entry>
	<entry>
		<id>https://wiki.alpinelinux.org/w/index.php?title=Tutorials_and_Howtos&amp;diff=4096</id>
		<title>Tutorials and Howtos</title>
		<link rel="alternate" type="text/html" href="https://wiki.alpinelinux.org/w/index.php?title=Tutorials_and_Howtos&amp;diff=4096"/>
		<updated>2010-07-23T09:29:00Z</updated>

		<summary type="html">&lt;p&gt;Djhughes: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Image:package_edutainment.svg|left|link=]]&lt;br /&gt;
{{TOC right}}&#039;&#039;&#039;Welcome to Tutorials and Howtos, a place of basic and advanced configuration tasks for your Alpine Linux.&#039;&#039;&#039;&lt;br /&gt;
The tutorials are hands-on and the reader is expected to try and achieve the goals described in each step, possibly with the help of a good examples. The output in one step is the starting point for the following step.&amp;lt;br/&amp;gt;&lt;br /&gt;
Howtos are smaller articles explaining how to perform a particular task with Alpine Linux. We encourage people to send in both complete articles as well as requesting topics to be covered. If you think you have the skills and knowledge to write an Alpine Linux related article please do so on this Wiki. If you want to request a topic, please add your request in this page [[Talk:Tutorials_and_Howtos|Discussion]]. 	&lt;br /&gt;
&lt;br /&gt;
== Installation ==&lt;br /&gt;
* [[Bootstrapping Alpine on Soekris net4xxx]]&lt;br /&gt;
* [[Bootstrapping Alpine on PC Engines ALIX.3]]&lt;br /&gt;
* [[Setting up a software raid1 array]]&lt;br /&gt;
* [[Setting up Logical Volumes with LVM]]&lt;br /&gt;
* [[Setting up a /var partition on software IDE raid1]]&lt;br /&gt;
* [[Replacing non-Alpine Linux with Alpine remotely]]&lt;br /&gt;
* [[Booting Alpine on an HP ML350 G6]]&lt;br /&gt;
* [[Installing XFCE as a VirtualBox guest]]&lt;br /&gt;
* [[Enable Serial Console on Boot]]&lt;br /&gt;
* [[How to enable APK caching]]&lt;br /&gt;
* [[Install Alpine on VirtualBox]]&lt;br /&gt;
* [[Upgrading to Edge]]&lt;br /&gt;
&lt;br /&gt;
== Networking ==&lt;br /&gt;
* [[Howto Configure a Network Bridge]]&lt;br /&gt;
* [[Setting up a OpenVPN-server with Alpine]]&lt;br /&gt;
* [[Setting up traffic monitoring using rrdtool (and snmp)]]&lt;br /&gt;
* [[Setting up Zaptel/Asterisk on Alpine]]&lt;br /&gt;
* [[Using HSDPA modem]]&lt;br /&gt;
* [[Using Alpine on Windows domain with IPSEC isolation]]&lt;br /&gt;
* [[Using Racoon for Remote Sites]]&lt;br /&gt;
* [[High Performance and Fault Tolerant Routing with Alpine Linux]]&lt;br /&gt;
&lt;br /&gt;
== Misc ==&lt;br /&gt;
* [[Setting up lm_sensors]]&lt;br /&gt;
* [[Setting up Satellite Internet Connection]]&lt;br /&gt;
* [[Setting up Streaming an Asterisk Channel]]&lt;br /&gt;
* [[Formatting HD/Floppy/Other]]&lt;br /&gt;
* [[Setting up Transmission (bittorrent) with Clutch WebUI]]&lt;br /&gt;
* [[Hosting services on Alpine]] &#039;&#039;(This applies to hosting mail, webservices and other services)&#039;&#039;&lt;br /&gt;
** [[Setting up postfix with virtual domains]]&lt;br /&gt;
** [[Protecting your email server with Alpine]]&lt;br /&gt;
** [[Hosting Web/Email services on Alpine]]&lt;br /&gt;
* [[Running Alpine Linux As a QEMU networked Guest ]]&lt;br /&gt;
* [[Screen on console]]&lt;br /&gt;
* [[Using espeak on Alpine Linux]]&lt;br /&gt;
* [[Generating SSL certs with ACF]]&lt;br /&gt;
* [[Setting up a ssh-server]]&lt;br /&gt;
* [[Changing passwords]]&lt;br /&gt;
* [[Multiple Instances of Services]]&lt;br /&gt;
* [[Setting up NRPE daemon]]&lt;br /&gt;
* [[IPTV How To]]&lt;br /&gt;
* [[ISP Mail Server HowTo]] &#039;&#039;(Postfix+PostfixAdmin+DoveCot+Roundcube+ClamAV+Spamd - A full-serivce ISP mail server)&#039;&#039;&lt;br /&gt;
* [[XFCE Setup]]&lt;br /&gt;
* [[Freepbx on Alpine Linux]]&lt;br /&gt;
* [[Setting up Transparent Squid Proxy]] &#039;&#039;(Covers Squid proxy and URL Filtering system)&#039;&#039;&lt;br /&gt;
** [[Obtaining user information via SNMP]] &#039;&#039;(Using the Squark Squid authentication helper)&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
== iSCSI ==&lt;br /&gt;
* [[iSCSI Target and Initiator Configuration]]&lt;br /&gt;
* [[iSCSI Raid and Clustered File Systems]]&lt;br /&gt;
&lt;br /&gt;
== Vserver ==&lt;br /&gt;
* [[Setting up a basic vserver]]&lt;br /&gt;
&lt;br /&gt;
== Obsolete Docs ==&lt;br /&gt;
Those are candidates for rewriting/removal.&lt;br /&gt;
* [[Native Harddisk Install]]&lt;br /&gt;
* [[Installing XUbuntu using Alpine boot floppy]]&lt;br /&gt;
* [[Setting up trac wiki]]&lt;/div&gt;</summary>
		<author><name>Djhughes</name></author>
	</entry>
	<entry>
		<id>https://wiki.alpinelinux.org/w/index.php?title=Tutorials_and_Howtos&amp;diff=4095</id>
		<title>Tutorials and Howtos</title>
		<link rel="alternate" type="text/html" href="https://wiki.alpinelinux.org/w/index.php?title=Tutorials_and_Howtos&amp;diff=4095"/>
		<updated>2010-07-23T09:25:11Z</updated>

		<summary type="html">&lt;p&gt;Djhughes: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Image:package_edutainment.svg|left|link=]]&lt;br /&gt;
{{TOC right}}&#039;&#039;&#039;Welcome to Tutorials and Howtos, a place of basic and advanced configuration tasks for your Alpine Linux.&#039;&#039;&#039;&lt;br /&gt;
The tutorials are hands-on and the reader is expected to try and achieve the goals described in each step, possibly with the help of a good examples. The output in one step is the starting point for the following step.&amp;lt;br/&amp;gt;&lt;br /&gt;
Howtos are smaller articles explaining how to perform a particular task with Alpine Linux. We encourage people to send in both complete articles as well as requesting topics to be covered. If you think you have the skills and knowledge to write an Alpine Linux related article please do so on this Wiki. If you want to request a topic, please add your request in this page [[Talk:Tutorials_and_Howtos|Discussion]]. 	&lt;br /&gt;
&lt;br /&gt;
== Installation ==&lt;br /&gt;
* [[Bootstrapping Alpine on Soekris net4xxx]]&lt;br /&gt;
* [[Bootstrapping Alpine on PC Engines ALIX.3]]&lt;br /&gt;
* [[Setting up a software raid1 array]]&lt;br /&gt;
* [[Setting up Logical Volumes with LVM]]&lt;br /&gt;
* [[Setting up a /var partition on software IDE raid1]]&lt;br /&gt;
* [[Replacing non-Alpine Linux with Alpine remotely]]&lt;br /&gt;
* [[Booting Alpine on an HP ML350 G6]]&lt;br /&gt;
* [[Installing XFCE as a VirtualBox guest]]&lt;br /&gt;
* [[Enable Serial Console on Boot]]&lt;br /&gt;
* [[How to enable APK caching]]&lt;br /&gt;
* [[Install Alpine on VirtualBox]]&lt;br /&gt;
* [[Upgrading to Edge]]&lt;br /&gt;
&lt;br /&gt;
== Networking ==&lt;br /&gt;
* [[Howto Configure a Network Bridge]]&lt;br /&gt;
* [[Setting up a OpenVPN-server with Alpine]]&lt;br /&gt;
* [[Setting up traffic monitoring using rrdtool (and snmp)]]&lt;br /&gt;
* [[Setting up Zaptel/Asterisk on Alpine]]&lt;br /&gt;
* [[Using HSDPA modem]]&lt;br /&gt;
* [[Using Alpine on Windows domain with IPSEC isolation]]&lt;br /&gt;
* [[Using Racoon for Remote Sites]]&lt;br /&gt;
* [[High Performance and Fault Tolerant Routing with Alpine Linux]]&lt;br /&gt;
&lt;br /&gt;
== Misc ==&lt;br /&gt;
* [[Setting up lm_sensors]]&lt;br /&gt;
* [[Setting up Satellite Internet Connection]]&lt;br /&gt;
* [[Setting up Streaming an Asterisk Channel]]&lt;br /&gt;
* [[Formatting HD/Floppy/Other]]&lt;br /&gt;
* [[Setting up Transmission (bittorrent) with Clutch WebUI]]&lt;br /&gt;
* [[Hosting services on Alpine]] &#039;&#039;(This applies to hosting mail, webservices and other services)&#039;&#039;&lt;br /&gt;
** [[Setting up postfix with virtual domains]]&lt;br /&gt;
** [[Protecting your email server with Alpine]]&lt;br /&gt;
** [[Hosting Web/Email services on Alpine]]&lt;br /&gt;
* [[Running Alpine Linux As a QEMU networked Guest ]]&lt;br /&gt;
* [[Screen on console]]&lt;br /&gt;
* [[Using espeak on Alpine Linux]]&lt;br /&gt;
* [[Generating SSL certs with ACF]]&lt;br /&gt;
* [[Setting up a ssh-server]]&lt;br /&gt;
* [[Changing passwords]]&lt;br /&gt;
* [[Multiple Instances of Services]]&lt;br /&gt;
* [[Setting up NRPE daemon]]&lt;br /&gt;
* [[IPTV How To]]&lt;br /&gt;
* [[ISP Mail Server HowTo]] &#039;&#039;(Postfix+PostfixAdmin+DoveCot+Roundcube+ClamAV+Spamd - A full-serivce ISP mail server)&#039;&#039;&lt;br /&gt;
* [[XFCE Setup]]&lt;br /&gt;
* [[Freepbx on Alpine Linux]]&lt;br /&gt;
* [[Setting up Transparent Squid Proxy]] &#039;&#039;(Covers Squid proxy and URL Filtering system)&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
== iSCSI ==&lt;br /&gt;
* [[iSCSI Target and Initiator Configuration]]&lt;br /&gt;
* [[iSCSI Raid and Clustered File Systems]]&lt;br /&gt;
&lt;br /&gt;
== Vserver ==&lt;br /&gt;
* [[Setting up a basic vserver]]&lt;br /&gt;
&lt;br /&gt;
== Obsolete Docs ==&lt;br /&gt;
Those are candidates for rewriting/removal.&lt;br /&gt;
* [[Native Harddisk Install]]&lt;br /&gt;
* [[Installing XUbuntu using Alpine boot floppy]]&lt;br /&gt;
* [[Setting up trac wiki]]&lt;/div&gt;</summary>
		<author><name>Djhughes</name></author>
	</entry>
	<entry>
		<id>https://wiki.alpinelinux.org/w/index.php?title=How_to_use_xdelta_and_download_only_differential_update_files&amp;diff=3982</id>
		<title>How to use xdelta and download only differential update files</title>
		<link rel="alternate" type="text/html" href="https://wiki.alpinelinux.org/w/index.php?title=How_to_use_xdelta_and_download_only_differential_update_files&amp;diff=3982"/>
		<updated>2010-06-10T05:06:54Z</updated>

		<summary type="html">&lt;p&gt;Djhughes: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;For those having a slow connection, it is possible to download a smaller differential file that contains only the new Alpine Linux version changes. If you have an ISO file of the version immediately prior to the latest version, you can then use the downloaded xdelta file to update to the latest ISO. You will still need to download the new ISO checksum file and test the integrity of the newly built ISO file. For xdelta to work you should have the three files on the same directory level, i.e.: alpine-1.10.3-1.10.4.xdelta, alpine-1.10.3-x86.iso (previous release) and the alpine-1.10.4-x86.iso.sha1&lt;br /&gt;
    &lt;br /&gt;
 wget -c http://www.alpinelinux.org/cgi-bin/dl.cgi/v1.10/releases/alpine-1.10.3-1.10.4.xdelta&lt;br /&gt;
 wget http://www.alpinelinux.org/cgi-bin/dl.cgi/v1.10/releases/alpine-1.10.4-x86.iso.sha1&lt;br /&gt;
&lt;br /&gt;
Make sure you have xdelta3 installed and build the new ISO:&lt;br /&gt;
&lt;br /&gt;
 apk add xdelta3&lt;br /&gt;
 xdelta3 -d alpine-1.10.3-1.10.4.xdelta&lt;br /&gt;
&lt;br /&gt;
Check the integrity of the file:&lt;br /&gt;
&lt;br /&gt;
 sha1sum -c alpine-1.10.4-x86.iso.sha1&lt;br /&gt;
&lt;br /&gt;
If checking the integrity of the file shows: alpine-1.10.4-x86.iso: OK then you are ready to continue.&lt;/div&gt;</summary>
		<author><name>Djhughes</name></author>
	</entry>
	<entry>
		<id>https://wiki.alpinelinux.org/w/index.php?title=How_to_use_xdelta_and_download_only_differential_update_files&amp;diff=3981</id>
		<title>How to use xdelta and download only differential update files</title>
		<link rel="alternate" type="text/html" href="https://wiki.alpinelinux.org/w/index.php?title=How_to_use_xdelta_and_download_only_differential_update_files&amp;diff=3981"/>
		<updated>2010-06-10T05:06:05Z</updated>

		<summary type="html">&lt;p&gt;Djhughes: check integrity and minor clarification&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;For those having a slow connection, it is possible to download a smaller differential file that contains only the new Alpine Linux version changes. If you have an ISO file of the version immediately prior to the latest version, you can then use the downloaded xdelta file to update to the latest ISO. You will still need to download the new ISO checksum file and test the integrity of the newly built ISO file. For xdelta to work you should have the three files on the same directory level, i.e.: alpine-1.10.3-1.10.4.xdelta, alpine-1.10.3-x86.iso (previous release) and the alpine-1.10.4-x86.iso.sha1&lt;br /&gt;
    &lt;br /&gt;
 wget –c http://www.alpinelinux.org/cgi-bin/dl.cgi/v1.10/releases/alpine-1.10.3-1.10.4.xdelta&lt;br /&gt;
 wget http://www.alpinelinux.org/cgi-bin/dl.cgi/v1.10/releases/alpine-1.10.4-x86.iso.sha1&lt;br /&gt;
&lt;br /&gt;
Make sure you have xdelta3 installed and build the new ISO:&lt;br /&gt;
&lt;br /&gt;
 apk add xdelta3&lt;br /&gt;
 xdelta3 -d alpine-1.10.3-1.10.4.xdelta&lt;br /&gt;
&lt;br /&gt;
Check the integrity of the file:&lt;br /&gt;
&lt;br /&gt;
 sha1sum -c alpine-1.10.4-x86.iso.sha1&lt;br /&gt;
&lt;br /&gt;
If checking the integrity of the file shows: alpine-1.10.4-x86.iso: OK then you are ready to continue.&lt;/div&gt;</summary>
		<author><name>Djhughes</name></author>
	</entry>
	<entry>
		<id>https://wiki.alpinelinux.org/w/index.php?title=ISP_Mail_Server_HowTo&amp;diff=3862</id>
		<title>ISP Mail Server HowTo</title>
		<link rel="alternate" type="text/html" href="https://wiki.alpinelinux.org/w/index.php?title=ISP_Mail_Server_HowTo&amp;diff=3862"/>
		<updated>2010-05-21T04:45:07Z</updated>

		<summary type="html">&lt;p&gt;Djhughes: corrected directory&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== A Full Service Mail Server ==&lt;br /&gt;
&lt;br /&gt;
The goal of this document is to describe how to set up postfix, dovecot, clamav, dspam, roundecube, and postfixadmin for a full-featured &amp;quot;ISP&amp;quot; level mail server.&lt;br /&gt;
&lt;br /&gt;
The server must provide:&lt;br /&gt;
&lt;br /&gt;
* multiple virtual domains&lt;br /&gt;
* admins for each domain (to add/remove virtual accounts)&lt;br /&gt;
* Quota support per domain / account&lt;br /&gt;
* downloading email via IMAP / IMAPS / POP3 / POP3S&lt;br /&gt;
* relaying email for authenticated users with TLS or SSL (Submission / SMTPS protocol)&lt;br /&gt;
* Standard filters (virus/spam/rbl/etc)&lt;br /&gt;
* Web mail client&lt;br /&gt;
* Value Add services&lt;br /&gt;
&lt;br /&gt;
== Set up Lighttpd + PHP ==&lt;br /&gt;
&lt;br /&gt;
PostfixAdmin needs php pgpsql and imap modules, so we do it in this step.&lt;br /&gt;
&lt;br /&gt;
  apk add lighttpd php php-pgsql php-imap&lt;br /&gt;
&lt;br /&gt;
Stop and remove mini_httpd, and move ACF to lighttpd;  We are setting this up to be a multi-domain virtual web server (replace host.example.com with the actual domain):&lt;br /&gt;
&lt;br /&gt;
  mkdir -p /var/www/domains/host.example.com/www&lt;br /&gt;
  ln -s /usr/share/acf/www /var/www/domains/host.example.com/www/acf&lt;br /&gt;
&lt;br /&gt;
Edit /var/www/domains/host.example.com/index.html to put a simple redirection page:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;lt;!DOCTYPE HTML PUBLIC &amp;quot;-//W3C//DTD HTML 4.01//EN&amp;quot; &amp;quot;http://www.w3.org/TR/html4/strict.dtd&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;html lang=&amp;quot;en&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;head&amp;gt;&lt;br /&gt;
&amp;lt;meta http-equiv=&amp;quot;Content-Type&amp;quot; content=&amp;quot;text/html; charset=ISO-8859-1&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;title&amp;gt;host.example.com Redirector&amp;lt;/title&amp;gt;&lt;br /&gt;
&amp;lt;/head&amp;gt;&lt;br /&gt;
&amp;lt;body&amp;gt;&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;&amp;lt;a href=&amp;quot;/acf&amp;quot;&amp;gt;ACF&amp;lt;/a&amp;gt;&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;&amp;lt;a href=&amp;quot;/postfixadmin&amp;quot;&amp;gt;PostfixAdmin&amp;lt;/a&amp;gt;&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;&amp;lt;a href=&amp;quot;/roundcube&amp;quot;&amp;gt;Roundcube&amp;lt;/a&amp;gt;&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
&amp;lt;/body&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Edit /etc/lighttpd/mod_cgi.conf to serve haserl files by adding a &amp;quot;&amp;quot; =&amp;gt; &amp;quot;&amp;quot; cgi handler and to treat /acf/cgi-bin as a CGI directory (remove the &#039;^&#039;)&lt;br /&gt;
&lt;br /&gt;
 $HTTP[&amp;quot;url&amp;quot;] =~ &amp;quot;/cgi-bin/&amp;quot; {&lt;br /&gt;
     # disable directory listings&lt;br /&gt;
     dir-listing.activate = &amp;quot;disable&amp;quot;&lt;br /&gt;
     # only allow cgi&#039;s in this directory&lt;br /&gt;
     cgi.assign = (&lt;br /&gt;
 		&amp;quot;.pl&amp;quot;	=&amp;gt;	&amp;quot;/usr/bin/perl&amp;quot;,&lt;br /&gt;
 		&amp;quot;.cgi&amp;quot;	=&amp;gt;	&amp;quot;/usr/bin/perl&amp;quot;,&lt;br /&gt;
 		&amp;quot;&amp;quot; =&amp;gt; &amp;quot;&amp;quot;&lt;br /&gt;
 	)&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
Get a web certificate, and install it.  You have two options: 1. If you want to use a self-signed cert, you can use the instructions found at [[Generating SSL certs with ACF]] or [[Generating SSL certs with ACF 1.9]] to generate it. 2. Use the certificate created with the &#039;&#039;&#039;setup-acf&#039;&#039;&#039; command. &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Option 1:&#039;&#039;&#039;&lt;br /&gt;
If you create your own self-signed certificate, you can create the &amp;quot;server-bundle.pem&amp;quot; and the &amp;quot;ca-crt.pem&amp;quot; file with these commands:&lt;br /&gt;
&lt;br /&gt;
  openssl pkcs12 -nokeys -cacerts -in certificate.pfx  -out /etc/lighttpd/ca-crt.pem&lt;br /&gt;
  openssl pkcs12 -nodes -in certificate.pfx -out /etc/lighttpd/server-bundle.pem&lt;br /&gt;
  chown root:root /etc/lighttpd/server-bundle.pem&lt;br /&gt;
  chmod 400 /etc/lighttpd/server-bundle.pem&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Note:&#039;&#039;&#039; The server certificate &#039;&#039;and&#039;&#039; key are in the server-bundle.pem file, so it is critical that the file be read-only by user &amp;quot;root&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Option 2:&#039;&#039;&#039;&lt;br /&gt;
If you prefer to just use the default certificate created with the &#039;&#039;&#039;setup-acf&#039;&#039;&#039; command, then you will need to do the following:&lt;br /&gt;
&lt;br /&gt;
  setup-acf&lt;br /&gt;
&lt;br /&gt;
During the above process, mini_httpd will be started, if it isn&#039;t already, and a certificate will be created. Once you have completed the setup-acf steps, do the following to move the certificate files to the correct location for lighttpd to use.&lt;br /&gt;
&lt;br /&gt;
  mv /etc/ssl/mini_httpd/server.pem /etc/lighttpd/server-bundle.pem&lt;br /&gt;
  chown root:root /etc/lighttpd/server-bundle.pem&lt;br /&gt;
  chmod 400 /etc/lighttpd/server-bundle.pem&lt;br /&gt;
&lt;br /&gt;
Add these lines to /etc/lighttpd/lighttpd.conf to point to the new document root, and set it up to listen on port 443 (replace &#039;&#039;host.example.com&#039;&#039; with the actual domain and &#039;&#039;ip_address_of_server&#039;&#039; with the actual IP address):&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
simple-vhost.server-root   = &amp;quot;/var/www/domains/&amp;quot;&lt;br /&gt;
simple-vhost.default-host  = &amp;quot;/host.example.com/&amp;quot;&lt;br /&gt;
simple-vhost.document-root = &amp;quot;www/&amp;quot;&lt;br /&gt;
&lt;br /&gt;
$SERVER[&amp;quot;socket&amp;quot;] == &amp;quot;ip_address_of_server:443&amp;quot; {&lt;br /&gt;
ssl.engine    = &amp;quot;enable&amp;quot;&lt;br /&gt;
ssl.pemfile   = &amp;quot;/etc/lighttpd/server-bundle.pem&amp;quot;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
If you went with Option 1 above, then add an additional line underneath the ssl.pemfile line, so that the section appears as follows:&lt;br /&gt;
&lt;br /&gt;
  $SERVER[&amp;quot;socket&amp;quot;] == &amp;quot;ip_address_of_server:443&amp;quot; {&lt;br /&gt;
  ssl.engine    = &amp;quot;enable&amp;quot;&lt;br /&gt;
  ssl.pemfile   = &amp;quot;/etc/lighttpd/server-bundle.pem&amp;quot;&lt;br /&gt;
  ssl.ca-file   = &amp;quot;/etc/lighttpd/ca-crt.pem&amp;quot;&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
Ensure that the simple_vhosts module is loaded, as well as the cgi config scripts by uncommenting the following lines in /etc/lighttpd/lighttpd.conf&lt;br /&gt;
&lt;br /&gt;
 server.modules = (&lt;br /&gt;
     #  other modules may be listed&lt;br /&gt;
     &amp;quot;mod_simple_vhost&amp;quot;, &lt;br /&gt;
     #  other modules may be listed&lt;br /&gt;
  .&lt;br /&gt;
  .&lt;br /&gt;
  .&lt;br /&gt;
     include &amp;quot;mod_cgi.conf&amp;quot;&lt;br /&gt;
 &lt;br /&gt;
     include &amp;quot;mod_fastcgi.conf&amp;quot;&lt;br /&gt;
&lt;br /&gt;
Stop and remove mini_httpd; start lighttpd, test&lt;br /&gt;
&lt;br /&gt;
  /etc/init.d/mini_httpd stop&lt;br /&gt;
  rc-update del mini_httpd&lt;br /&gt;
  apk del mini_httpd&lt;br /&gt;
  rc-update add lighttpd&lt;br /&gt;
  /etc/init.d/lighttpd start&lt;br /&gt;
&lt;br /&gt;
At this point you should be able to see ACF being served with lighttpd (Note: this will work well with alpine 1.10. With earlier versions there will be problems.)  https://host.example.com/acf/&lt;br /&gt;
&lt;br /&gt;
== Install Postgresql ==&lt;br /&gt;
&lt;br /&gt;
Add and configure postgresql&lt;br /&gt;
&lt;br /&gt;
  apk add acf-postgresql postgresql-client&lt;br /&gt;
  /etc/init.d/postgresql setup&lt;br /&gt;
  /etc/init.d/postgresql start&lt;br /&gt;
  rc-update add postgresql&lt;br /&gt;
&lt;br /&gt;
At this point any user can connect to the sql server with &amp;quot;trust&amp;quot; mechanism.  If you want to enforce password authentication (you probably do) edit /var/lib/postgresql/8.4/data/pg_hba.conf&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
  Editme: What should we recommend?&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Create the postfix database:&lt;br /&gt;
&lt;br /&gt;
  psql -U postgres&lt;br /&gt;
   create user postfix with password &#039;******&#039;;&lt;br /&gt;
   create database postfix owner postfix;&lt;br /&gt;
   \c postfix&lt;br /&gt;
   create language plpgsql;&lt;br /&gt;
   \q&lt;br /&gt;
&lt;br /&gt;
(Of course, use your selected password where ******* is shown above.)&lt;br /&gt;
&lt;br /&gt;
== Install PostfixAdmin ==&lt;br /&gt;
&lt;br /&gt;
We are going to install the postfix admin web front-end before we install the mail server.  This just creates an interface to populate the SQL tables that postfix and dovecot will use.&lt;br /&gt;
&lt;br /&gt;
Download PostfixAdmin from Sourceforge.  When these instructions were written, 2.3 was the current release, so (replace host.example.com with the actual domain):&lt;br /&gt;
 wget http://downloads.sourceforge.net/project/postfixadmin/postfixadmin/postfixadmin_2.3.tar.gz&lt;br /&gt;
 tar zxvf postfixadmin_2.3.tar.gz&lt;br /&gt;
 mkdir -p /var/www/domains/host.example.com/www/postfixadmin&lt;br /&gt;
 mv postfixadmin-2.3/* /var/www/domains/host.example.com/www/postfixadmin&lt;br /&gt;
 rm -rf postfixadmin*&lt;br /&gt;
&lt;br /&gt;
Edit /var/www/domains/host.example.com/www/postfixadmin/config.inc.php and modify at least these lines (replace host.example.com with the actual domain):&lt;br /&gt;
&lt;br /&gt;
 $CONF[&#039;configured&#039;] = true;&lt;br /&gt;
 $CONF[&#039;setup_password&#039;] = &amp;quot;&amp;quot;;  &amp;lt;&amp;lt; Don&#039;t change this yet&lt;br /&gt;
 $CONF[&#039;database_type&#039;] = &#039;pgsql&#039;;&lt;br /&gt;
 $CONF[&#039;database_host&#039;] = &#039;localhost&#039;;&lt;br /&gt;
 $CONF[&#039;database_user&#039;] = &#039;postfix&#039;;&lt;br /&gt;
 $CONF[&#039;database_password&#039;] = &#039;*****&#039;;   &amp;lt;&amp;lt; The password you chose above&lt;br /&gt;
 $CONF[&#039;database_name&#039;] = &#039;postfix&#039;;&lt;br /&gt;
 $CONF[&#039;database_prefix&#039;] = &amp;quot;&amp;quot;;&lt;br /&gt;
 $CONF[&#039;admin_email&#039;] = &#039;you@some.email.com&#039;;  &amp;lt;&amp;lt; Your email address &lt;br /&gt;
 $CONF[&#039;encrypt&#039;] = &#039;md5crypt&#039;;&lt;br /&gt;
 $CONF[&#039;authlib_default_flavor&#039;] = &#039;md5raw&#039;;&lt;br /&gt;
 $CONF[&#039;dovecotpw&#039;] = &amp;quot;/usr/sbin/dovecotpw&amp;quot;;&lt;br /&gt;
 $CONF[&#039;domain_path&#039;] = &#039;YES&#039;;&lt;br /&gt;
 $CONF[&#039;domain_in_mailbox&#039;] = &#039;NO&#039;;&lt;br /&gt;
 $CONF[&#039;aliases&#039;] = &#039;10&#039;;                       &lt;br /&gt;
 $CONF[&#039;mailboxes&#039;] = &#039;10&#039;;&lt;br /&gt;
 $CONF[&#039;maxquota&#039;] = &#039;10&#039;;&lt;br /&gt;
 $CONF[&#039;quota&#039;] = &#039;YES&#039;;&lt;br /&gt;
 $CONF[&#039;quota_multiplier&#039;] = &#039;1024000&#039;;&lt;br /&gt;
 $CONF[&#039;vacation&#039;] = &#039;NO&#039;; &lt;br /&gt;
 $CONF[&#039;vacation_control&#039;] =&#039;NO&#039;;&lt;br /&gt;
 $CONF[&#039;vacation_control_admin&#039;] = &#039;NO&#039;;&lt;br /&gt;
 $CONF[&#039;alias_control&#039;] = &#039;YES&#039;;&lt;br /&gt;
 $CONF[&#039;alias_control_admin&#039;] = &#039;YES&#039;;&lt;br /&gt;
 $CONF[&#039;special_alias_control&#039;] = &#039;YES&#039;;&lt;br /&gt;
 $CONF[&#039;fetchmail&#039;] = &#039;NO&#039;;&lt;br /&gt;
 $CONF[&#039;user_footer_link&#039;] = &amp;quot;http://host.example.com/postfixadmin&amp;quot;;&lt;br /&gt;
 $CONF[&#039;footer_link&#039;] = &#039;http://host.example.com/postfixadmin/main.php&#039;;&lt;br /&gt;
 $CONF[&#039;create_mailbox_subdirs_prefix&#039;]=&amp;quot;&amp;quot;;  &lt;br /&gt;
 $CONF[&#039;used_quotas&#039;] = &#039;YES&#039;;   &lt;br /&gt;
 $CONF[&#039;new_quota_table&#039;] = &#039;YES&#039;;  &lt;br /&gt;
&lt;br /&gt;
You should further edit /var/www/domains/host.example.com/www/postfixadmin/config.inc.php and replace all instances of &amp;quot;change-this-to-your.domain.tld&amp;quot; with your actual mail domain. This can be done with busybox sed (replace example.com with your domain name):&lt;br /&gt;
&lt;br /&gt;
 sed -i -e &#039;s/change-this-to-your.domain.tld/example.com/g&#039; /var/www/domains/host.example.com/www/postfixadmin/config.inc.php&lt;br /&gt;
&lt;br /&gt;
Go to http://host.example.com/postfixadmin/setup.php&lt;br /&gt;
&lt;br /&gt;
Create the password hash, add it to the config.inc.php file&lt;br /&gt;
&lt;br /&gt;
Go back to http://host.example.com/postfixadmin/setup.php&lt;br /&gt;
&lt;br /&gt;
Create superadmin account.&lt;br /&gt;
&lt;br /&gt;
== Install Postfix ==&lt;br /&gt;
&lt;br /&gt;
Create a user for the virtual mail delivery, and get its uid/gid (you&#039;ll need the numeric uid/gid for postfix)&lt;br /&gt;
&lt;br /&gt;
 adduser vmail -H -D -s /bin/false&lt;br /&gt;
 grep vmail /etc/passwd&lt;br /&gt;
&lt;br /&gt;
(In examples below, we use 1006/1006 for the uid/gid)&lt;br /&gt;
&lt;br /&gt;
Create the mail directory, and assign vmail as the owner&lt;br /&gt;
 mkdir -p /var/mail/domains&lt;br /&gt;
 chown -R vmail:vmail /var/mail/domains&lt;br /&gt;
 &lt;br /&gt;
&lt;br /&gt;
Install postfix&lt;br /&gt;
&lt;br /&gt;
 apk add acf-postfix postfix-pgsql&lt;br /&gt;
&lt;br /&gt;
Edit the /etc/postfix/main.cf file. Here&#039;s an example (don&#039;t forget to replace the uid/gid):&lt;br /&gt;
&lt;br /&gt;
 myhostname=host.example.com&lt;br /&gt;
 mydomain=example.com&lt;br /&gt;
 &lt;br /&gt;
 mydestination = localhost.$mydomain, localhost&lt;br /&gt;
 mynetworks_style = subnet&lt;br /&gt;
 mynetworks = 127.0.0.0/8&lt;br /&gt;
 &lt;br /&gt;
 virtual_mailbox_domains = proxy:pgsql:/etc/postfix/sql/pgsql_virtual_domains_maps.cf&lt;br /&gt;
 virtual_alias_maps = proxy:pgsql:/etc/postfix/sql/pgsql_virtual_alias_maps.cf,&lt;br /&gt;
        proxy:pgsql:/etc/postfix/sql/pgsql_virtual_alias_domain_maps.cf,&lt;br /&gt;
        proxy:pgsql:/etc/postfix/sql/pgsql_virtual_alias_domain_catchall_maps.cf&lt;br /&gt;
 &lt;br /&gt;
 virtual_mailbox_maps = proxy:pgsql:/etc/postfix/sql/pgsql_virtual_mailbox_maps.cf,&lt;br /&gt;
        proxy:pgsql:/etc/postfix/sql/pgsql_virtual_alias_domain_mailbox_maps.cf&lt;br /&gt;
 &lt;br /&gt;
 virtual_mailbox_base = /var/mail/domains/&lt;br /&gt;
 virtual_gid_maps = static:1006&lt;br /&gt;
 virtual_uid_maps = static:1006&lt;br /&gt;
 virtual_minimum_uid = 100&lt;br /&gt;
 virtual_transport = virtual&lt;br /&gt;
 &lt;br /&gt;
 &lt;br /&gt;
 # This next command means you must create a virtual&lt;br /&gt;
 # domain for the host itself - ALL mail goes through&lt;br /&gt;
 # The virtual transport&lt;br /&gt;
 &lt;br /&gt;
 mailbox_transport = virtual&lt;br /&gt;
 local_transport = virtual&lt;br /&gt;
 local_transport_maps = $virtual_mailbox_maps&lt;br /&gt;
 &lt;br /&gt;
 smtpd_helo_required = yes&lt;br /&gt;
 disable_vrfy_command = yes&lt;br /&gt;
 message_size_limit = 10240000&lt;br /&gt;
 queue_minfree = 51200000&lt;br /&gt;
 &lt;br /&gt;
 smtpd_sender_restrictions =&lt;br /&gt;
        permit_mynetworks,&lt;br /&gt;
        reject_non_fqdn_sender,&lt;br /&gt;
        reject_unknown_sender_domain&lt;br /&gt;
 &lt;br /&gt;
 smtpd_recipient_restrictions =&lt;br /&gt;
        reject_non_fqdn_recipient,&lt;br /&gt;
        reject_unknown_recipient_domain,&lt;br /&gt;
        permit_mynetworks,&lt;br /&gt;
        permit_sasl_authenticated,&lt;br /&gt;
        reject_unauth_destination,&lt;br /&gt;
        reject_rbl_client dnsbl.sorbs.net,&lt;br /&gt;
        reject_rbl_client zen.spamhaus.org,&lt;br /&gt;
        reject_rbl_client bl.spamcop.net&lt;br /&gt;
 &lt;br /&gt;
 smtpd_data_restrictions = reject_unauth_pipelining&lt;br /&gt;
 &lt;br /&gt;
 # we will use this later - This prevents cleartext authentication&lt;br /&gt;
 # for relaying&lt;br /&gt;
 smtpd_tls_auth_only = yes&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Now we need to create a *bunch* of files so that postfix can get the delivery information out of sql. Here&#039;s a shell script to create the scripts.  Change PGPW to the password for the postfix user of the postfix SQL database.&lt;br /&gt;
&lt;br /&gt;
 cd /etc/postfix&lt;br /&gt;
 mkdir sql&lt;br /&gt;
 PGPW=&amp;quot;ChangeMe&amp;quot;&lt;br /&gt;
 &lt;br /&gt;
 cat - &amp;lt;&amp;lt;EOF &amp;gt;sql/pgsql_virtual_alias_domain_catchall_maps.cf&lt;br /&gt;
 user=postfix&lt;br /&gt;
 password = $PGPW&lt;br /&gt;
 hosts = localhost&lt;br /&gt;
 dbname = postfix&lt;br /&gt;
 query = Select goto From alias,alias_domain where alias_domain.alias_domain = &#039;%d&#039; and alias.address = &#039;@&#039; ||  alias_domain.target_domain and alias.active = true and alias_domain.active= true &lt;br /&gt;
 EOF&lt;br /&gt;
 &lt;br /&gt;
 cat - &amp;lt;&amp;lt;EOF &amp;gt;sql/pgsql_virtual_alias_domain_mailbox_maps.cf&lt;br /&gt;
 user=postfix&lt;br /&gt;
 password = $PGPW&lt;br /&gt;
 hosts = localhost&lt;br /&gt;
 dbname = postfix&lt;br /&gt;
 query = Select maildir from mailbox,alias_domain where alias_domain.alias_domain = &#039;%d&#039; and mailbox.username = &#039;%u&#039; || &#039;@&#039; || alias_domain.target_domain and mailbox.active = true and alias_domain.active&lt;br /&gt;
 EOF&lt;br /&gt;
 &lt;br /&gt;
 cat - &amp;lt;&amp;lt;EOF &amp;gt;sql/pgsql_virtual_alias_domain_maps.cf&lt;br /&gt;
 user=postfix&lt;br /&gt;
 password = $PGPW&lt;br /&gt;
 hosts = localhost&lt;br /&gt;
 dbname = postfix&lt;br /&gt;
 query = select goto from alias,alias_domain where alias_domain.alias_domain=&#039;%d&#039; and alias.address = &#039;%u&#039; || &#039;@&#039; || alias_domain.target_domain and alias.active= true and alias_domain.active= true&lt;br /&gt;
 EOF&lt;br /&gt;
 &lt;br /&gt;
 cat - &amp;lt;&amp;lt;EOF &amp;gt;sql/pgsql_virtual_alias_maps.cf&lt;br /&gt;
 user=postfix&lt;br /&gt;
 password = $PGPW&lt;br /&gt;
 hosts = localhost&lt;br /&gt;
 dbname = postfix&lt;br /&gt;
 query = Select goto From alias Where address=&#039;%s&#039; and active =&#039;1&#039;&lt;br /&gt;
 EOF&lt;br /&gt;
 &lt;br /&gt;
 cat - &amp;lt;&amp;lt;EOF &amp;gt;sql/pgsql_virtual_domains_maps.cf&lt;br /&gt;
 user=postfix&lt;br /&gt;
 password = $PGPW&lt;br /&gt;
 hosts = localhost&lt;br /&gt;
 dbname = postfix&lt;br /&gt;
 query = Select domain from domain where domain=&#039;%s&#039; and active=&#039;1&#039;&lt;br /&gt;
 EOF&lt;br /&gt;
 &lt;br /&gt;
 cat - &amp;lt;&amp;lt;EOF &amp;gt;sql/pgsql_virtual_mailbox_maps.cf&lt;br /&gt;
 user=postfix&lt;br /&gt;
 password = $PGPW&lt;br /&gt;
 hosts = localhost&lt;br /&gt;
 dbname = postfix&lt;br /&gt;
 query = Select maildir from mailbox where username=&#039;%s&#039; and active=true&lt;br /&gt;
 EOF&lt;br /&gt;
 &lt;br /&gt;
 chown -R postfix:postfix sql&lt;br /&gt;
 chmod 640 sql/*&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
At this point you should be able to start up postfix&lt;br /&gt;
 &lt;br /&gt;
 newaliases  # so postfix is happy...&lt;br /&gt;
 /etc/init.d/postfix start&lt;br /&gt;
 rc-update add postfix&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Create a domain in PostfixAdmin and test ===&lt;br /&gt;
&lt;br /&gt;
Go to http://host.example.com/postfixadmin/&lt;br /&gt;
&lt;br /&gt;
Log in using the superadmin account, create a domain for the local box (e.g. example.com), and create a user mailbox (e.g. root).&lt;br /&gt;
&lt;br /&gt;
From the machine, send a test message:&lt;br /&gt;
&lt;br /&gt;
 sendmail -t root@example.com&lt;br /&gt;
 subject: test&lt;br /&gt;
 .&lt;br /&gt;
 ^d&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
In /var/log/mail.log (or /var/log/messages, if you still have busybox syslogd running) you should see the message queued.  The message should be in /var/mail/domains/example.com/root/new&lt;br /&gt;
&lt;br /&gt;
== Install Dovecot ==&lt;br /&gt;
&lt;br /&gt;
Dovecot is the POP3/IMAP server to retrieve mail.&lt;br /&gt;
&lt;br /&gt;
As before, we install dovecot: &lt;br /&gt;
&lt;br /&gt;
 apk add acf-dovecot dovecot-pgsql&lt;br /&gt;
&lt;br /&gt;
edit /etc/dovecot/dovecot.conf&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
# Select only the protocols you wish to support - all are listed in the next line&lt;br /&gt;
protocols               =       imap imaps pop pop3s&lt;br /&gt;
log_path                =       /var/log/dovecot.log&lt;br /&gt;
info_log_path           =       /var/log/dovecot-info.log&lt;br /&gt;
disable_plaintext_auth  =       no&lt;br /&gt;
&lt;br /&gt;
# Authenticated IMAP&lt;br /&gt;
ssl                     =       yes&lt;br /&gt;
ssl_cert_file           =       /etc/lighttpd/server-bundle.pem&lt;br /&gt;
ssl_key_file            =       /etc/lighttpd/server-bundle.pem&lt;br /&gt;
auth_verbose            =       yes&lt;br /&gt;
auth_debug              =       no&lt;br /&gt;
mail_location           =       maildir:/var/mail/domains/%d/%n&lt;br /&gt;
auth default    {&lt;br /&gt;
       mechanisms = plain&lt;br /&gt;
       passdb sql {&lt;br /&gt;
               args = /etc/dovecot/dovecot-sql.conf&lt;br /&gt;
               }&lt;br /&gt;
       userdb static {&lt;br /&gt;
               args =  uid=1006 gid=1006 home=/var/mail/domains/%d/%n&lt;br /&gt;
               }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Be sure to replace the uid and gid with the appropriate values for the vmail user.&lt;br /&gt;
&lt;br /&gt;
We need a certificate for SSL/TLS authentication, so in the example above, we use the lighttpd cert. That way when the cert is renewed/replaced, Dovecot will have access to the new cert as well.  &lt;br /&gt;
&lt;br /&gt;
Create the /etc/dovecot/dovecot-sql.conf file:&lt;br /&gt;
&lt;br /&gt;
 driver = pgsql&lt;br /&gt;
 connect = host=localhost dbname=postfix user=postfix password=********&lt;br /&gt;
 password_query = select username,password from mailbox where local_part = &#039;%n&#039; and domain = &#039;%d&#039;&lt;br /&gt;
 default_pass_scheme =  MD5-CRYPT&lt;br /&gt;
&lt;br /&gt;
Again, change the password above to your postfix user password, and protect the file from prying eyes:&lt;br /&gt;
&lt;br /&gt;
 chown root:root /etc/dovecot/dovecot-sql.conf&lt;br /&gt;
 chmod 600 /etc/dovecot/dovecot-sql.conf&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Start dovecot&lt;br /&gt;
 /etc/init.d/dovecot start&lt;br /&gt;
 rc-update add dovecot&lt;br /&gt;
&lt;br /&gt;
== Testing ==&lt;br /&gt;
&lt;br /&gt;
Make sure your firewall allows in ports 25(SMTP) 110 (POP3), 995 (POP3S), 143(IMAP), 993(IMAPS), or whatever subset you support.  &lt;br /&gt;
 &lt;br /&gt;
At this point, you should be able to:&lt;br /&gt;
 * Create a new domain and add users with PostfixAdmin&lt;br /&gt;
 * Send mail to those users via SMTP to port 25&lt;br /&gt;
 * Retrieve mail using the user&#039;s full email and password (e.g. username: user@example.com  password: ChangeMe)&lt;br /&gt;
&lt;br /&gt;
== Value Add Features ==&lt;br /&gt;
&lt;br /&gt;
If you followed the guide above, you now have a functional mail server with many interconnected parts.  The features below assume that the server is already running as described above.  You should be able to add any or all of these features below to further enhance the mail service.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Virus Scanning ===&lt;br /&gt;
&lt;br /&gt;
This procedure uses clamav and the postfix content_filter mechanism to scan inbound and outbound email for viruses.  Infected emails are dropped.  Clean emails are tagged with a &amp;quot;scanned by clamav&amp;quot; header.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* Install clamav and clamsmtp:&lt;br /&gt;
 apk add acf-clamav clamsmtp&lt;br /&gt;
* Edit the /etc/clamav/clamd.conf file if desired (not necessary in most cases)&lt;br /&gt;
* Edit /etc/clamsmtpd.conf and verify the following lines&lt;br /&gt;
 OutAddress: 10026&lt;br /&gt;
 Listen: 127.0.0.1:10025                                               &lt;br /&gt;
 Header: X-Virus-Scanned: ClamAV using ClamSMTP&lt;br /&gt;
 Action: drop&lt;br /&gt;
 User: clamav                                                      &lt;br /&gt;
* Start the daemons&lt;br /&gt;
 rc-update add clamd&lt;br /&gt;
 rc-update add clamsmtpd&lt;br /&gt;
 /etc/init.d/clamd start&lt;br /&gt;
 /etc/init.d/clamsmtpd start&lt;br /&gt;
* Verify clamsmtp is listening on port 10025:&lt;br /&gt;
 netstat -anp | grep clamsmtp&lt;br /&gt;
* [http://memberwebs.com/stef/software/clamsmtp/postfix.html Following the clamsmtp instructions]&lt;br /&gt;
** edit /etc/postfix/main.cf and add:&lt;br /&gt;
 content_filter = scan:[127.0.0.1]:10025                                                      &lt;br /&gt;
** edit /etc/postfix/master.cf and add&lt;br /&gt;
 # AV scan filter (used by content_filter)&lt;br /&gt;
 scan      unix  -       -       n       -       16      smtp&lt;br /&gt;
         -o smtp_send_xforward_command=yes&lt;br /&gt;
         -o smtp_enforce_tls=no&lt;br /&gt;
 # For injecting mail back into postfix from the filter&lt;br /&gt;
 127.0.0.1:10026 inet  n -       n       -       16      smtpd&lt;br /&gt;
         -o content_filter=&lt;br /&gt;
         -o receive_override_options=no_unknown_recipient_checks,no_header_body_checks&lt;br /&gt;
         -o smtpd_helo_restrictions=&lt;br /&gt;
         -o smtpd_client_restrictions=&lt;br /&gt;
         -o smtpd_sender_restrictions=&lt;br /&gt;
         -o smtpd_recipient_restrictions=permit_mynetworks,reject&lt;br /&gt;
         -o mynetworks_style=host&lt;br /&gt;
         -o smtpd_authorized_xforward_hosts=127.0.0.0/8&lt;br /&gt;
* postfix reload&lt;br /&gt;
* Send and email into a local virtual domain - it should have the &#039;&#039;X-Virus-Scanned: ClamAV using ClamSMTP&#039;&#039; header.&lt;br /&gt;
&lt;br /&gt;
=== Relay for Authenticated Users ===&lt;br /&gt;
&lt;br /&gt;
As configured above, the mail server accepts email from the Internet, but it does not relay email.  If it is a perimeter exchanger for a protected network, then you can add the protected networks to the &#039;&#039;mynetworks&#039;&#039; configuration line in /etc/postfix/main.cf&lt;br /&gt;
&lt;br /&gt;
This configuration change allows &#039;&#039;remote&#039;&#039; users to authenticate against the mail server and relay through it.  The rules for relaying are:&lt;br /&gt;
* Only authenticated users can relay&lt;br /&gt;
* Authentication Credentials must be encrypted with TLS or SSL&lt;br /&gt;
* Allow Submission and SMTPS ports for relaying (many consumer networks block port 25 - SMTP by default)&lt;br /&gt;
The process uses the dovecot authentication mechanism (used with IMAPS) to authenticate users before they are allowed to relay through postfix.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* Edit /etc/dovecot/dovecot.conf and add teh following inside the &#039;&#039;auth default&#039;&#039; stanza:&lt;br /&gt;
 # this is for postfix SASL (authenticated users can relay through us)&lt;br /&gt;
 socket listen {&lt;br /&gt;
                client {&lt;br /&gt;
                        path    = /var/spool/postfix/private/dovecot-auth.sock&lt;br /&gt;
                        mode    = 0660&lt;br /&gt;
                        user    = postfix&lt;br /&gt;
                        group   = postfix&lt;br /&gt;
                        }&lt;br /&gt;
                }&lt;br /&gt;
        }&lt;br /&gt;
* Restart dovecot&lt;br /&gt;
 /etc/init.d/dovecot restart&lt;br /&gt;
* Edit /etc/postfix/main.cf and add:&lt;br /&gt;
 # TLS Stuff -- since we allow SASL with tls *only*, we have to set up TLS first                    &lt;br /&gt;
 &lt;br /&gt;
 smtpd_tls_cert_file = /etc/lighttpd/server-bundle.pem&lt;br /&gt;
 smtpd_tls_key_file = /etc/lighttpd/server-bundle.pem&lt;br /&gt;
 smtpd_tls_CAfile = /etc/lighttpd/ca-crt.pem&lt;br /&gt;
 # If tls_security_level is set to &amp;quot;encrypt&amp;quot;, then SMTP rejects &lt;br /&gt;
 # unencrypted email (e.g. normal mail) which is bad.&lt;br /&gt;
 # By setting it to &amp;quot;may&amp;quot; you get TLS encrypted mail from google, slashdot, and other &lt;br /&gt;
 # interesting places.  Check your logs to see who&lt;br /&gt;
 smtpd_tls_security_level = may&lt;br /&gt;
 # Log info about the negotiated encryption levels&lt;br /&gt;
 smtpd_tls_received_header = yes&lt;br /&gt;
 smtpd_tls_loglevel = 1&lt;br /&gt;
 &lt;br /&gt;
 # SASL - this allows senders to authenticiate themselves&lt;br /&gt;
 # This along with &amp;quot;permit_sasl_authenticated&amp;quot; in smtpd_recipient_restrictions allows relaying&lt;br /&gt;
 smtpd_sasl_type = dovecot&lt;br /&gt;
 smtpd_sasl_path = private/dovecot-auth.sock&lt;br /&gt;
 smtpd_sasl_auth_enable = yes&lt;br /&gt;
 smtpd_sasl_authenticated_header = yes&lt;br /&gt;
 smtpd_tls_auth_only = yes&lt;br /&gt;
* Edit /etc/postfix/master.cf and enable the submission and smtps transports.  They are probably already at the top of your  master.cf file, just commented out:&lt;br /&gt;
 submission inet n       -       n       -       -       smtpd&lt;br /&gt;
   -o smtpd_tls_security_level=encrypt&lt;br /&gt;
   -o smtpd_sasl_auth_enable=yes&lt;br /&gt;
   -o smtpd_client_restrictions=permit_sasl_authenticated,reject&lt;br /&gt;
   -o milter_macro_daemon_name=ORIGINATING&lt;br /&gt;
 smtps     inet  n       -       n       -       -       smtpd&lt;br /&gt;
   -o smtpd_tls_security_level=encrypt&lt;br /&gt;
   -o smtpd_tls_wrappermode=yes&lt;br /&gt;
   -o smtpd_sasl_auth_enable=yes&lt;br /&gt;
   -o smtpd_client_restrictions=permit_sasl_authenticated,reject&lt;br /&gt;
   -o milter_macro_daemon_name=ORIGINATING&lt;br /&gt;
*Verfiy submission and smtps are defined in /etc/services&lt;br /&gt;
 grep &amp;quot;submission\|ssmtp&amp;quot; /etc/services&lt;br /&gt;
 submission	587/tcp				# mail message submission&lt;br /&gt;
 submission	587/udp&lt;br /&gt;
 smtps		465/tcp		ssmtp		# smtp protocol over TLS/SSL&lt;br /&gt;
 smtps		465/udp		ssmtp&lt;br /&gt;
* Restart postfix&lt;br /&gt;
 postfix reload&lt;br /&gt;
&lt;br /&gt;
At this point, you should be able to set up a mail client to relay through the server with TLS (port 587) or SSL (port 465)  Note that &amp;quot;plain&amp;quot; authentication is used because the underlying link is encrypted.  For example, in Thunderbird leave &amp;quot;secure authentication&amp;quot; unchecked, and choose STARTTLS (or TLS) for the connection security.&lt;br /&gt;
&lt;br /&gt;
=== Mailbox Quotas ===&lt;br /&gt;
&lt;br /&gt;
In the default configuration, PostfixAdmin knows about quotas, but they are not enforced.   Documentation on the web mentions the [http://vda.sourceforge.net vda patch to postfix] to enforce quotas.  The only bad thing... its a &#039;&#039;patch&#039;&#039;.   Postfix and Dovecot are both conservative systems, so if the patch isn&#039;t in the upstream source, we&#039;ll assume there&#039;s a good reason.   There is a way of using quotas without patches - and it involves using dovecot&#039;s [http://wiki.dovecot.org/LDA deliver] lda for local delivery.&lt;br /&gt;
&lt;br /&gt;
Note: As of Jan 2010, the documention is confusing, with multiple versions of dovecot, PostfixAdmin, and Mysql referenced.  These instructions apply to:&lt;br /&gt;
* Postgresql 8.4.2 &lt;br /&gt;
* PostfixAdmin 2.3 &lt;br /&gt;
* Dovecot 1.2.11&lt;br /&gt;
* Postfix 2.6.5&lt;br /&gt;
&lt;br /&gt;
Presumably later versions will work the same, but if not, please update the documentation and versions above.&lt;br /&gt;
&lt;br /&gt;
* Update /etc/dovecot/dovecot.conf (old lines shown commented out):&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
# old postfix &lt;br /&gt;
#       userdb static {&lt;br /&gt;
#               args =  uid=1006 gid=1006 home=/var/mail/domains/%d/%n&lt;br /&gt;
#               }&lt;br /&gt;
&lt;br /&gt;
# new quota support:&lt;br /&gt;
        userdb prefetch {&lt;br /&gt;
                }&lt;br /&gt;
&lt;br /&gt;
        userdb sql {&lt;br /&gt;
                args = /etc/dovecot/dovecot-sql.conf&lt;br /&gt;
                }&lt;br /&gt;
&lt;br /&gt;
        socket listen {&lt;br /&gt;
                client {&lt;br /&gt;
                        path    = /var/spool/postfix/private/dovecot-auth.sock&lt;br /&gt;
                        mode    = 0660&lt;br /&gt;
                        user    = postfix&lt;br /&gt;
                        group   = postfix&lt;br /&gt;
                        }&lt;br /&gt;
                # These lines below are for the deliver lda&lt;br /&gt;
                master {&lt;br /&gt;
                        path =  /var/run/dovecot/auth-master&lt;br /&gt;
                        mode    = 0660&lt;br /&gt;
                        user    = vmail&lt;br /&gt;
                        group   = vmail&lt;br /&gt;
                        }&lt;br /&gt;
                }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
protocol imap {                                                               &lt;br /&gt;
         mail_plugins = quota imap_quota                                       &lt;br /&gt;
         }                                                                     &lt;br /&gt;
                                                                              &lt;br /&gt;
protocol pop3 {                                                               &lt;br /&gt;
         mail_plugins = quota                                                  &lt;br /&gt;
         }                                                                     &lt;br /&gt;
                                                                              &lt;br /&gt;
dict {                                                                        &lt;br /&gt;
        quotadict = pgsql:/etc/dovecot/dovecot-dict-quota.conf                &lt;br /&gt;
        }                                                                     &lt;br /&gt;
                                                                              &lt;br /&gt;
plugin {                                                                      &lt;br /&gt;
         quota = dict:user::proxy::quotadict                                   &lt;br /&gt;
         }                                                     &lt;br /&gt;
                                                              &lt;br /&gt;
protocol lda {                                                &lt;br /&gt;
   postmaster_address = postmaster@host.example.com&lt;br /&gt;
   mail_plugins = quota                                        &lt;br /&gt;
   auth_socket_path =  /var/run/dovecot/auth-master&lt;br /&gt;
   sendmail_path = /usr/sbin/sendmail&lt;br /&gt;
}                                                                            &lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
 &lt;br /&gt;
You should already have a &amp;lt;tt&amp;gt;socket-&amp;gt; listen-&amp;gt; client&amp;lt;/tt&amp;gt; section, but it is listed above to show where it goes in relationship to the &amp;lt;tt&amp;gt;socket -&amp;gt; listen -&amp;gt; master&amp;lt;/tt&amp;gt; section&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* edit &amp;lt;tt&amp;gt;/etc/dovecot/dovecot-sql.conf&amp;lt;/tt&amp;gt; and replace the user and password queries with the following (you may not have a user_query yet - add it):&lt;br /&gt;
&lt;br /&gt;
 password_query = select username as user, password, 1006 as userdb_uid, 1006 as userdb_gid, &#039;*:bytes=&#039; || quota as userdb_quota_rule from mailbox  where local_part = &#039;%n&#039; and domain = &#039;%d&#039;&lt;br /&gt;
 user_query = select &#039;/var/mail/domains/&#039; || maildir as home, 1006 as uid, 1006 as gid, &#039;*:bytes=&#039; || quota  as quota_rule from mailbox where local_part = &#039;%n&#039; and domain =&#039;%d&#039;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* create &amp;lt;tt&amp;gt;/etc/dovecot/dovecot-dict-quota.conf&amp;lt;/tt&amp;gt;&lt;br /&gt;
 connect = host=localhost dbname=postfix user=postfix password=********&lt;br /&gt;
 &lt;br /&gt;
 map {&lt;br /&gt;
         pattern = priv/quota/storage&lt;br /&gt;
         table = quota2&lt;br /&gt;
         username_field =username&lt;br /&gt;
         value_field = bytes&lt;br /&gt;
 }&lt;br /&gt;
 &lt;br /&gt;
 map {&lt;br /&gt;
        pattern= priv/quota/messages&lt;br /&gt;
        table = quota2&lt;br /&gt;
        username_field = username&lt;br /&gt;
        value_field = messages&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
Again, change the password above to your postfix user password, and protect the file from prying eyes:&lt;br /&gt;
  chown root:root /etc/dovecot/dovecot-dict-quota.conf&lt;br /&gt;
  chmod 600 /etc/dovecot/dovecot-dict-quota.conf&lt;br /&gt;
&lt;br /&gt;
Side note: [http://wiki.dovecot.org/Quota/Dict The Dovecot Quota Documentation] mentions the need for a trigger with pgsql.  This was created in the PostfixAdmin install, which is why you instantiated the pgsql language when creating the database.  If not, you will need to create the trigger, to reference the quota2 table, not the quota table mentioned in the dovecot docs.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* create a new transport for the dovecot lda.   Add the following to  /etc/postfix/master.cf:&lt;br /&gt;
 # The dovecot deliver lda&lt;br /&gt;
 dovecot   unix  -       n       n       -       -       pipe&lt;br /&gt;
   flags=DRhu user=vmail:vmail argv=/usr/libexec/dovecot/deliver -f ${sender} -d ${user}@${nexthop}&lt;br /&gt;
&lt;br /&gt;
* Edit the /etc/postfix/main.cf.  Replace &lt;br /&gt;
 virtual_transport = virtual &lt;br /&gt;
with&lt;br /&gt;
 virtual_transport = dovecot&lt;br /&gt;
 dovecot_destination_recipient_limit = 1&lt;br /&gt;
&lt;br /&gt;
Change permissions on the /var/log/dovecot* log files, so that the vmail user can write to them:&lt;br /&gt;
&lt;br /&gt;
 chown vmail:vmail /var/log/dovecot*&lt;br /&gt;
&lt;br /&gt;
Restart Postfix and Dovecot:&lt;br /&gt;
&lt;br /&gt;
 /etc/init.d/postfix restart&lt;br /&gt;
 /etc/init.d/dovecot restart&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;TODO&#039;&#039;&#039;  This will cause over-quota emails to bounce.   Which could be a source of backscatter.   We need a way of checking quota limits after RBL checking but before the message is accepted in the queue.&lt;br /&gt;
&lt;br /&gt;
=== WebMail (RoundCube) ===&lt;br /&gt;
&lt;br /&gt;
[http://roundcube.net/ RoundCube] is an &amp;quot;ajax /Web2.0&amp;quot; web-mail client.  These instructions are for the Alpine Linux 1.10 repository &lt;br /&gt;
&lt;br /&gt;
* Add the package and related php modules:&lt;br /&gt;
 apk add roundcubemail php-xml php-openssl php-mcrypt php-gd php-iconv&lt;br /&gt;
&lt;br /&gt;
* link the roundcube application back into the docroot&lt;br /&gt;
 ln -s /usr/share/webapps/roundcube /var/www/domains/host.example.com/www/roundcube&lt;br /&gt;
&lt;br /&gt;
* follow the instructions in /usr/share/webapps/roundcube/INSTALL:&lt;br /&gt;
 cd /usr/share/webapps/roundcube&lt;br /&gt;
 chown -R lighttpd:lighttpd temp logs&lt;br /&gt;
 &lt;br /&gt;
 su postgres&lt;br /&gt;
 createuser roundcube&lt;br /&gt;
   Shall the new role be a superuser? (y/n) n&lt;br /&gt;
   Shall the new role be allowed to create databases? (y/n) n&lt;br /&gt;
   Shall the new role be allowed to create more new roles? (y/n) y&lt;br /&gt;
 createdb -O roundcube -E UNICODE -T template0 roundcubemail&lt;br /&gt;
 psql roundcubemail&lt;br /&gt;
   roundcubemail=# ALTER USER roundcube WITH PASSWORD &#039;the_new_password&#039;;&lt;br /&gt;
   roundcubemail=# \c - roundcube&lt;br /&gt;
   roundcubemail=&amp;gt; \i /usr/share/webapps/roundcube/SQL/postgres.initial.sql&lt;br /&gt;
   roundcubemail=&amp;gt; \q&lt;br /&gt;
 exit&lt;br /&gt;
&lt;br /&gt;
* edit /etc/php/php.ini and set date.timezone to your local timezone, or to UTC&lt;br /&gt;
&lt;br /&gt;
* restart lighttpd to verify the new php libraries are used&lt;br /&gt;
 /etc/init.d/lighttpd restart&lt;br /&gt;
&lt;br /&gt;
* Point your browser to http://host.example.com/roundcube/installer&lt;br /&gt;
* Start installation&lt;br /&gt;
&lt;br /&gt;
For the specific configuration parameters in the install step:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!Property&lt;br /&gt;
!Setting&lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;enable_spellcheck&#039;&#039; ||   disabled &lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;identities_level&#039;&#039; ||  one identity with possibility to edit all params but not email address &lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;log driver&#039;&#039; || syslog &lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;sylog_id&#039;&#039; || roundcube &lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;syslog_facility&#039;&#039; || mailsubsystem &lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;db_dnsw&#039;&#039; || pgsql properties, as described above &lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;imap_host&#039;&#039; || 127.0.0.1 &lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;auto_create_user&#039;&#039; || enabled &lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;smtp_server&#039;&#039; ||  127.0.0.1&lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;smtp_port&#039;&#039; ||  25&lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;smtp_user/smtp_pass&#039;&#039; ||  enable &#039;&#039;Use Current IMAP username and password for SMTP authentication&#039;&#039;&lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;smtp_log&#039;&#039; ||  enable (optional, but gives additional log record)&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
The other items can be left at default settings, or adjusted if desired.&lt;br /&gt;
&lt;br /&gt;
* Follow the instructions in step 3 of the install to copy the files to the server&lt;br /&gt;
* You should now be able to get to roundcube at http://host.example.com/roundcube&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
After its working, the INSTALL file recommends removing the install directory.   If you want to keep the installer around later, you can simply change the ownership and permissions.  So do &#039;&#039;&#039;one&#039;&#039;&#039; of the following:&lt;br /&gt;
 cd /usr/share/webapps/roundcube&lt;br /&gt;
 rm -rf LICENSE UPGRADING INSTALL README CHANGELOG  SQL installer&lt;br /&gt;
or&lt;br /&gt;
 cd /usr/share/webapps/roundcube&lt;br /&gt;
 chown -R root:root LICENSE UPGRADING INSTALL README CHANGELOG  SQL installer&lt;br /&gt;
 chmod -R 600 LICENSE UPGRADING INSTALL README CHANGELOG SQL &lt;br /&gt;
 chmod 700 SQL installer&lt;br /&gt;
&lt;br /&gt;
==== Enable Plug-ins ====&lt;br /&gt;
&lt;br /&gt;
RoundCube has various useful plug-ins, which could be found in &#039;&#039;/usr/share/webapps/roundcube/plugins&#039;&#039; directory. For example you may want to enable &#039;&#039;password&#039;&#039; plug-in to let users change their passwords directly from RoundCube using an extra Password Tab added to User Settings.&lt;br /&gt;
&lt;br /&gt;
* Grant limited permissions for &#039;&#039;roundcube&#039;&#039; database role &lt;br /&gt;
 psql -U postgres postfix&lt;br /&gt;
   postfix=# GRANT UPDATE (password,modified) ON mailbox TO roundcube;&lt;br /&gt;
   postfix=# GRANT SELECT (username) ON mailbox TO roundcube;&lt;br /&gt;
   postfix=# GRANT INSERT ON log TO roundcube;&lt;br /&gt;
   postfix=# \q&lt;br /&gt;
&lt;br /&gt;
* Setup &#039;&#039;password&#039;&#039; plug-in parameters in &#039;&#039;/usr/share/webapps/roundcube/plugins/password/config.inc.php&#039;&#039;&lt;br /&gt;
 mv /usr/share/webapps/roundcube/plugins/password/config.inc.php.dist /usr/share/webapps/roundcube/plugins/password/config.inc.php&lt;br /&gt;
 vi /usr/share/webapps/roundcube/plugins/password/config.inc.php&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
$rcmail_config[&#039;password_minimum_length&#039;] = 7;&lt;br /&gt;
$rcmail_config[&#039;password_require_nonalpha&#039;] = true;&lt;br /&gt;
...&lt;br /&gt;
$rcmail_config[&#039;password_db_dsn&#039;] = &#039;pgsql://roundcube:&amp;lt;roundcube_password&amp;gt;@localhost/postfix&#039;;&lt;br /&gt;
...&lt;br /&gt;
$rcmail_config[&#039;password_query&#039;] = &amp;quot;UPDATE mailbox set password = %c, modified = NOW() where username = %u; INSERT INTO log (timestamp,username,domain,action,data) VALUES (NOW(),%u || &#039; (&#039; || %h || &#039;)&#039;,%d,&#039;edit_password&#039;,%u)&amp;quot;;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* Enable &#039;&#039;password&#039;&#039; plug-in&lt;br /&gt;
 vi /usr/share/webapps/roundcube/config/main.inc.php&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
...&lt;br /&gt;
$rcmail_config[&#039;plugins&#039;] = array(&#039;password&#039;);&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== OpenLDAP based Address Book ===&lt;br /&gt;
&lt;br /&gt;
This OpenLDAP configuration uses the SQL backend, which represents information stored in PostgreSQL as an LDAP subtree for Address Book functionality for email lookups, user authentication or even &lt;br /&gt;
replication account information between sites. This procedure uses some metainformation to translate LDAP queries to SQL queries, leaving relational schema untouched, which allows SQL and LDAP &lt;br /&gt;
applications to inter-operate without replication, and exchange data as needed. The SQL backend uses UnixODBC to connect to PostgresSQL. &lt;br /&gt;
&lt;br /&gt;
* Install OpenLDAP and ODBC&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
apk add openldap libldap openldap-back-sql php-ldap unixodbc psqlodbc ca-certificates&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Note&#039;&#039;&#039;: The psqlodbc package is currently unavailable&lt;br /&gt;
&lt;br /&gt;
* Update &amp;quot;postfix&amp;quot; database (it will add &#039;id&#039; columns to mailbox and domain tables, also will create tables and views to represent LDAP metainformation)&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Note&#039;&#039;&#039;: These instructions are for example domain example.com. So make sure you replaced all entries of &#039;example&#039; and &#039;com&#039; according to your domain name parts.&lt;br /&gt;
&lt;br /&gt;
Put the following into a new file called &#039;&#039;&#039;script&#039;&#039;&#039;:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
ALTER TABLE domain ADD COLUMN id SERIAL; &lt;br /&gt;
ALTER TABLE mailbox ADD COLUMN id SERIAL; &lt;br /&gt;
&lt;br /&gt;
CREATE TABLE ldap_entry_objclasses (&lt;br /&gt;
    entry_id integer NOT NULL,&lt;br /&gt;
    oc_name character varying(64)&lt;br /&gt;
);&lt;br /&gt;
&lt;br /&gt;
CREATE TABLE ldap_oc_mappings (&lt;br /&gt;
    name character varying(64) NOT NULL,&lt;br /&gt;
    keytbl character varying(64) NOT NULL,&lt;br /&gt;
    keycol character varying(64) NOT NULL,&lt;br /&gt;
    create_proc character varying(255),&lt;br /&gt;
    delete_proc character varying(255),&lt;br /&gt;
    expect_return integer NOT NULL&lt;br /&gt;
);&lt;br /&gt;
&lt;br /&gt;
ALTER TABLE ldap_oc_mappings ADD COLUMN id SERIAL;&lt;br /&gt;
ALTER TABLE ldap_oc_mappings ADD PRIMARY KEY (id);&lt;br /&gt;
&lt;br /&gt;
CREATE TABLE ldap_attr_mappings (&lt;br /&gt;
    oc_map_id integer NOT NULL REFERENCES ldap_oc_mappings(id),&lt;br /&gt;
    name character varying(255) NOT NULL,&lt;br /&gt;
    sel_expr character varying(255) NOT NULL,&lt;br /&gt;
    sel_expr_u character varying(255),&lt;br /&gt;
    from_tbls character varying(255) NOT NULL,&lt;br /&gt;
    join_where character varying(255),&lt;br /&gt;
    add_proc character varying(255),&lt;br /&gt;
    delete_proc character varying(255),&lt;br /&gt;
    param_order integer NOT NULL,&lt;br /&gt;
    expect_return integer NOT NULL&lt;br /&gt;
);&lt;br /&gt;
&lt;br /&gt;
ALTER TABLE ldap_attr_mappings ADD COLUMN id SERIAL;&lt;br /&gt;
ALTER TABLE ldap_attr_mappings ADD PRIMARY KEY (id);&lt;br /&gt;
&lt;br /&gt;
CREATE VIEW ldap_dcs AS&lt;br /&gt;
    ((SELECT (domain.id + 100000) AS id,&lt;br /&gt;
            (&#039;dc=&#039;::text || replace((domain.domain)::text, &#039;.&#039;::text, &#039;,dc=&#039;::text)) AS dn,&lt;br /&gt;
            1 AS oc_map_id,&lt;br /&gt;
            100000 AS parent,&lt;br /&gt;
            0 AS keyval,&lt;br /&gt;
            domain.domain&lt;br /&gt;
     FROM domain&lt;br /&gt;
     WHERE domain.domain &amp;lt;&amp;gt; &#039;ALL&#039;)&lt;br /&gt;
      UNION&lt;br /&gt;
     (SELECT 100000 AS id,&lt;br /&gt;
           (&#039;dc=&#039; || regexp_replace((domain.domain)::text, &#039;.*\\.&#039;, &#039;&#039;::text)) AS dn,&lt;br /&gt;
           1 AS oc_map_id,&lt;br /&gt;
           0 AS parent,&lt;br /&gt;
           0 AS keyval,&lt;br /&gt;
           (regexp_replace((domain.domain)::text, &#039;.*\\.&#039;, &#039;&#039;::text)) AS domain&lt;br /&gt;
      FROM domain&lt;br /&gt;
      WHERE domain.domain &amp;lt;&amp;gt; &#039;ALL&#039;&lt;br /&gt;
      LIMIT 1));&lt;br /&gt;
&lt;br /&gt;
CREATE VIEW ldap_entries AS&lt;br /&gt;
    SELECT mailbox.id,&lt;br /&gt;
    (((&#039;cn=&#039;::text || initcap(replace(split_part((mailbox.username)::text, &#039;@&#039;::text, 1), &#039;.&#039;::text, &#039; &#039;::text))) || &#039;,dc=&#039;::text) ||&lt;br /&gt;
             replace(regexp_replace((mailbox.username)::text, &#039;.*@&#039;, &#039;&#039;::text), &#039;.&#039;::text, &#039;,dc=&#039;::text)) AS dn,&lt;br /&gt;
          1 AS oc_map_id,&lt;br /&gt;
          (SELECT ldap_dcs.id&lt;br /&gt;
           FROM ldap_dcs&lt;br /&gt;
           WHERE ((ldap_dcs.domain)::text = (mailbox.domain)::text)) AS parent,&lt;br /&gt;
           mailbox.id AS keyval&lt;br /&gt;
           FROM mailbox&lt;br /&gt;
           UNION&lt;br /&gt;
           SELECT ldap_dcs.id,&lt;br /&gt;
                  ldap_dcs.dn,&lt;br /&gt;
                  ldap_dcs.oc_map_id,&lt;br /&gt;
                  ldap_dcs.parent,&lt;br /&gt;
                  ldap_dcs.keyval&lt;br /&gt;
           FROM ldap_dcs;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Finally, execute the commands in the file with:&lt;br /&gt;
 cat script | psql -U postfix postfix&lt;br /&gt;
 rm script&lt;br /&gt;
&lt;br /&gt;
* Fill out LDAP tables according to following example (make sure to separate values with TABs):&lt;br /&gt;
&lt;br /&gt;
Put the following into a new file called &#039;&#039;&#039;script&#039;&#039;&#039;:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
COPY ldap_oc_mappings (id, name, keytbl, keycol, create_proc, delete_proc, expect_return) FROM stdin;&lt;br /&gt;
1	exampleBox	mailbox	id	\N	\N	1&lt;br /&gt;
\.&lt;br /&gt;
COPY ldap_attr_mappings (id, oc_map_id, name, sel_expr, sel_expr_u, from_tbls, join_where, add_proc, delete_proc, param_order, expect_return) FROM stdin;&lt;br /&gt;
1	1	displayName	mailbox.name	\N	mailbox	\N	\N	\N	3	0&lt;br /&gt;
2	1	mail	mailbox.username	\N	mailbox	\N	\N	\N	3	0&lt;br /&gt;
3	1	cn	mailbox.name	\N	mailbox	\N	\N	\N	3	0&lt;br /&gt;
4	1	userPassword	&#039;{CRYPT}&#039;||mailbox.password	\N	mailbox	\N	\N	\N	3	0&lt;br /&gt;
\.&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Finally, execute the commands in the file with:&lt;br /&gt;
 cat script | psql -U postfix postfix&lt;br /&gt;
 rm script&lt;br /&gt;
&lt;br /&gt;
* Check that &amp;quot;ldap_dcs&amp;quot; view looks something like this:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
echo &#039;select * from ldap_dcs&#039; | psql -U postgres postfix&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
   id   |             dn              | oc_map_id | parent | keyval |       domain       &lt;br /&gt;
--------+-----------------------------+-----------+--------+--------+--------------------&lt;br /&gt;
 100000 | dc=com                      |         1 |      0 |      0 | com&lt;br /&gt;
 100001 | dc=example,dc=com           |         1 | 100000 |      0 | example.com&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* Check that &amp;quot;ldap_entries&amp;quot; view looks something like this:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
echo &#039;select * from ldap_entries&#039; | psql -U postgres postfix&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
   id   |                          dn                           | oc_map_id | parent | keyval &lt;br /&gt;
--------+-------------------------------------------------------+-----------+--------+--------&lt;br /&gt;
    1   | cn=address1,dc=example,dc=com                         |         1 | 100001 |    1&lt;br /&gt;
...&lt;br /&gt;
   123  | cn=address123,dc=example,dc=com                       |         1 | 100001 |    1&lt;br /&gt;
 100000 | dc=com                                                |         1 |      0 |    0&lt;br /&gt;
 100001 | dc=example,dc=com                                     |         1 | 100000 |    0&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* Configure ODBC parameters&lt;br /&gt;
&lt;br /&gt;
Edit /etc/odbc.ini:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
[PostgreSQL]&lt;br /&gt;
Description             = Connection to Postgres&lt;br /&gt;
Driver                  = PostgreSQL&lt;br /&gt;
Trace                   = Yes&lt;br /&gt;
TraceFile               = sql.log&lt;br /&gt;
Database                = postfix&lt;br /&gt;
Servername              = 127.0.0.1&lt;br /&gt;
UserName                =&lt;br /&gt;
Password                =&lt;br /&gt;
Port                    = 5432&lt;br /&gt;
Protocol                = 6.4&lt;br /&gt;
ReadOnly                = No&lt;br /&gt;
RowVersining            = No&lt;br /&gt;
ShowSystemTables        = No&lt;br /&gt;
ShowOidColumn           = No&lt;br /&gt;
FakeOidIndex            = No&lt;br /&gt;
ConnSettings            =&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Edit /etc/odbcinst.ini:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
[PostgreSQL]&lt;br /&gt;
Description     = PostgreSQL driver for Linux&lt;br /&gt;
Driver          = /usr/lib/psqlodbcw.so&lt;br /&gt;
Setup           = /usr/lib/libodbcpsqlS.so&lt;br /&gt;
FileUsage       = 1&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* Test ODBC connection&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
echo &amp;quot;select * from domain;&amp;quot; | isql PostgreSQL postgres&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* Provide permission to certificate for LDAP server&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
chown ldap /etc/lighttpd/server-bundle.pem&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* Edit LDAP schema&lt;br /&gt;
&lt;br /&gt;
Edit /etc/openldap/schema/example.com.schema:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
attributetype ( 0.9.2342.19200300.100.1.3&lt;br /&gt;
	NAME ( &#039;mail&#039; &#039;rfc822Mailbox&#039; )&lt;br /&gt;
	DESC &#039;RFC1274: RFC822 Mailbox&#039;&lt;br /&gt;
        EQUALITY caseIgnoreIA5Match&lt;br /&gt;
        SUBSTR caseIgnoreIA5SubstringsMatch&lt;br /&gt;
        SYNTAX 1.3.6.1.4.1.1466.115.121.1.26{256} )&lt;br /&gt;
&lt;br /&gt;
attributetype ( 2.16.840.1.113730.3.1.241&lt;br /&gt;
	NAME &#039;displayName&#039;&lt;br /&gt;
	DESC &#039;RFC2798: preferred name to be used when displaying entries&#039;&lt;br /&gt;
	EQUALITY caseIgnoreMatch&lt;br /&gt;
	SUBSTR caseIgnoreSubstringsMatch&lt;br /&gt;
	SYNTAX 1.3.6.1.4.1.1466.115.121.1.15&lt;br /&gt;
	SINGLE-VALUE )&lt;br /&gt;
&lt;br /&gt;
objectclass   ( 2.16.840.1.113730.3.2.2&lt;br /&gt;
        NAME &#039;exampleBox&#039;&lt;br /&gt;
	DESC &#039;example.com mailbox&#039;&lt;br /&gt;
	MUST ( displayName $ mail $ userPassword )&lt;br /&gt;
	)&lt;br /&gt;
&lt;br /&gt;
# RFC 1274 + RFC 2247&lt;br /&gt;
attributetype ( 0.9.2342.19200300.100.1.25&lt;br /&gt;
        NAME ( &#039;dc&#039; &#039;domainComponent&#039; )&lt;br /&gt;
        DESC &#039;RFC1274/2247: domain component&#039;&lt;br /&gt;
        EQUALITY caseIgnoreIA5Match&lt;br /&gt;
        SUBSTR caseIgnoreIA5SubstringsMatch&lt;br /&gt;
        SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 SINGLE-VALUE )&lt;br /&gt;
&lt;br /&gt;
attributetype ( 2.5.4.46 NAME &#039;dnQualifier&#039;&lt;br /&gt;
        DESC &#039;RFC2256: DN qualifier&#039;&lt;br /&gt;
        EQUALITY caseIgnoreMatch&lt;br /&gt;
        ORDERING caseIgnoreOrderingMatch&lt;br /&gt;
        SUBSTR caseIgnoreSubstringsMatch&lt;br /&gt;
        SYNTAX 1.3.6.1.4.1.1466.115.121.1.44 )&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* Configure LDAP server&lt;br /&gt;
&lt;br /&gt;
Edit /etc/openldap/slapd.conf:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
include         /etc/openldap/schema/example.com.schema&lt;br /&gt;
pidfile         /var/run/openldap/slapd.pid&lt;br /&gt;
argsfile        /var/run/openldap/slapd.args&lt;br /&gt;
&lt;br /&gt;
TLSCipherSuite HIGH&lt;br /&gt;
TLSCACertificateFile /etc/lighttpd/ca-crt.pem&lt;br /&gt;
TLSCertificateFile /etc/lighttpd/server-bundle.pem&lt;br /&gt;
TLSCertificateKeyFile /etc/lighttpd/server-bundle.pem&lt;br /&gt;
TLSVerifyClient never &lt;br /&gt;
&lt;br /&gt;
# This is needed for proper representation of MD5-CRYPT format stored in database&lt;br /&gt;
#  see more details in http://strugglers.net/~andy/blog/2010/01/23/openldap-and-md5crypt/&lt;br /&gt;
password-hash  {CRYPT}&lt;br /&gt;
password-crypt-salt-format &amp;quot;$1$%.8s&amp;quot;&lt;br /&gt;
&lt;br /&gt;
loglevel        stats&lt;br /&gt;
moduleload	/usr/lib/openldap/back_sql.so&lt;br /&gt;
sizelimit 3000&lt;br /&gt;
&lt;br /&gt;
database        sql&lt;br /&gt;
&lt;br /&gt;
dbname		PostgreSQL&lt;br /&gt;
dbuser		postfix&lt;br /&gt;
dbpasswd	*****&lt;br /&gt;
&lt;br /&gt;
suffix          &amp;quot;dc=example,dc=com&amp;quot;&lt;br /&gt;
&lt;br /&gt;
upper_func      &amp;quot;upper&amp;quot;&lt;br /&gt;
strcast_func    &amp;quot;text&amp;quot;&lt;br /&gt;
concat_pattern  &amp;quot;?||?&amp;quot;&lt;br /&gt;
has_ldapinfo_dn_ru      no&lt;br /&gt;
lastmod         off&lt;br /&gt;
&lt;br /&gt;
access to attrs=userPassword by * auth&lt;br /&gt;
&lt;br /&gt;
access to * by peername.ip=127.0.0.1 read&lt;br /&gt;
#           by peername.ip=&amp;lt;IP&amp;gt;%&amp;lt;netmask&amp;gt; read&lt;br /&gt;
#           by peername.ip=&amp;lt;IP&amp;gt; read&lt;br /&gt;
	    by users read&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* Set permissions for slapd.conf&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
chown ldap:ldap /etc/openldap/slapd.conf&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* Configure startup parameters to make sure that LDAP server start AFTER PostgreSQL and listens on localhost with clear text and public IP with SSL&lt;br /&gt;
&lt;br /&gt;
Edit /etc/conf.d/slapd:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
rc_need=&amp;quot;postgresql&amp;quot; &lt;br /&gt;
OPTS=&amp;quot;-h &#039;ldaps:// ldap://127.0.0.1&#039;&amp;quot;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* Start LDAP server&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
rc-update add slapd default&lt;br /&gt;
/etc/init.d/slapd start&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* Configure LDAP client utilities&lt;br /&gt;
&lt;br /&gt;
Edit /etc/openldap/ldap.conf&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
BASE	dc=example,dc=com&lt;br /&gt;
URI	ldaps://host.example.com&lt;br /&gt;
&lt;br /&gt;
TLS_CACERT /etc/lighttpd/ca-crt.pem&lt;br /&gt;
TLS_CERT /etc/lighttpd/server-bundle.pem&lt;br /&gt;
TLS_KEY /etc/lighttpd/server-bundle.pem&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* Test LDAP server&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
ldapsearch -z 3&lt;br /&gt;
ldapsearch -z 3 -x -W -D cn=admin,dc=example,dc=com&lt;br /&gt;
ldapsearch -z 3 -x -W -D cn=address1,dc=example,dc=com&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* Configure RoundCube webmail for email lookups&lt;br /&gt;
&lt;br /&gt;
In order to enable php-ldap support you need to restart lighttpd server&lt;br /&gt;
&lt;br /&gt;
 /etc/init.d/lighttpd restart&lt;br /&gt;
&lt;br /&gt;
Edit /usr/share/webapps/roundcube/config/main.inc.php:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
$rcmail_config[&#039;ldap_debug&#039;] = false;&lt;br /&gt;
...&lt;br /&gt;
$rcmail_config[&#039;address_book_type&#039;] = &#039;sql&#039;;&lt;br /&gt;
&lt;br /&gt;
$rcmail_config[&#039;ldap_public&#039;][&#039;example.com&#039;] = array(&lt;br /&gt;
  &#039;name&#039;          =&amp;gt; &#039;example.com&#039;,&lt;br /&gt;
  &#039;hosts&#039;         =&amp;gt; array(&#039;127.0.0.1&#039;),&lt;br /&gt;
  &#039;port&#039;          =&amp;gt; 389,&lt;br /&gt;
  &#039;use_tls&#039;         =&amp;gt; false,&lt;br /&gt;
  &#039;user_specific&#039; =&amp;gt; false,&lt;br /&gt;
  &#039;base_dn&#039;       =&amp;gt; &#039;dc=example,dc=com&#039;,&lt;br /&gt;
  &#039;bind_dn&#039;       =&amp;gt; &#039;&#039;,&lt;br /&gt;
  &#039;bind_pass&#039;     =&amp;gt; &#039;&#039;,&lt;br /&gt;
  &#039;writable&#039;      =&amp;gt; false,&lt;br /&gt;
  &#039;LDAP_Object_Classes&#039; =&amp;gt; array(&amp;quot;top&amp;quot;, &amp;quot;exampleBox&amp;quot;),&lt;br /&gt;
  &#039;required_fields&#039;     =&amp;gt; array(&amp;quot;cn&amp;quot;, &amp;quot;sn&amp;quot;, &amp;quot;mail&amp;quot;),&lt;br /&gt;
  &#039;LDAP_rdn&#039;      =&amp;gt; &#039;mail&#039;,&lt;br /&gt;
  &#039;ldap_version&#039;  =&amp;gt; 3,&lt;br /&gt;
  &#039;search_fields&#039; =&amp;gt; array(&#039;mail&#039;, &#039;cn&#039;, &#039;sn&#039;, &#039;givenName&#039;),&lt;br /&gt;
  &#039;name_field&#039;    =&amp;gt; &#039;cn&#039;,&lt;br /&gt;
  &#039;email_field&#039;   =&amp;gt; &#039;mail&#039;,&lt;br /&gt;
  &#039;surname_field&#039; =&amp;gt; &#039;sn&#039;,&lt;br /&gt;
  &#039;firstname_field&#039; =&amp;gt; &#039;gn&#039;,&lt;br /&gt;
  &#039;sort&#039;          =&amp;gt; &#039;cn&#039;,&lt;br /&gt;
  &#039;scope&#039;         =&amp;gt; &#039;sub&#039;,&lt;br /&gt;
  &#039;filter&#039;        =&amp;gt; &#039;(objectClass=*)&#039;, // Construct here any filter you need&lt;br /&gt;
  &#039;fuzzy_search&#039;  =&amp;gt; true);&lt;br /&gt;
&lt;br /&gt;
$rcmail_config[&#039;autocomplete_addressbooks&#039;] = array(&#039;sql&#039;,&#039;example.com&#039;);&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* Fix PostfixAdmin to work with the new table definition&lt;br /&gt;
&lt;br /&gt;
Edit /var/www/domains/example.com/www/postfixadmin/list-domain.php. Replace the line:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
   SELECT domain.* , COUNT( DISTINCT mailbox.username ) AS mailbox_count&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
With the lines:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
   SELECT domain.domain, domain.description, domain.aliases, domain.mailboxes,&lt;br /&gt;
   domain.maxquota, domain.quota, domain.transport, domain.backupmx, domain.created,&lt;br /&gt;
   domain.modified, domain.active, COUNT( DISTINCT mailbox.username ) AS mailbox_count&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== log rotation ==&lt;br /&gt;
&lt;br /&gt;
Ensure the busybox cron service is started and is configured to auto-start:&lt;br /&gt;
&lt;br /&gt;
 /etc/init.d/cron start&lt;br /&gt;
 rc-update add cron default&lt;br /&gt;
&lt;br /&gt;
Add log rotate:&lt;br /&gt;
&lt;br /&gt;
 apk add logrotate&lt;br /&gt;
&lt;br /&gt;
Edit &#039;&#039;/etc/logrotate.conf&#039;&#039; as desired, but the defaults should be sufficient for most people.&lt;br /&gt;
&lt;br /&gt;
== Optional: Configure Web Server Virtual Domains ==&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Note:&#039;&#039;&#039; These steps can be done &#039;&#039;in addition to&#039;&#039; the default lighttpd configuration above, which allows you to access the ACF, PostfixAdmin and Roundcube interfaces as subfolders of one web service.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Note:&#039;&#039;&#039; If you provide SSL access for multiple domain site you may need to follow http://redmine.lighttpd.net/projects/lighttpd/wiki/Docs:SSL#SSL-on-multiple-domains in order to provide multi-domain certificates. If you would like to redirect hosts to their secure equivalents use the following instructions http://redmine.lighttpd.net/projects/lighttpd/wiki/HowToRedirectHttpToHttps.&lt;br /&gt;
&lt;br /&gt;
This server hosts three separate web applications, and these can be handled as three &#039;&#039;different&#039;&#039; virtual domains on the same web server. They will be distinguished by their DNS names, so you can choose domains for the three separate services (or at least the ones you want to publish):&lt;br /&gt;
&lt;br /&gt;
* ACF - Alpine Configuration Framework for managing the server&lt;br /&gt;
* PostfixAdmin - for managing the postfix installation&lt;br /&gt;
* RoundCube - for accessing individual mailboxes&lt;br /&gt;
&lt;br /&gt;
Choose three different domains (from here on known as ACF_DOMAIN, POSTFIXADMIN_DOMAIN, and ROUNDCUBE_DOMAIN) and configure DNS for all three to point to the IP address of your host. These should be DNS &#039;&#039;&#039;A&#039;&#039;&#039; records.&lt;br /&gt;
&lt;br /&gt;
Then, configure lighttpd to handle the three separate domains by editing /etc/lighttpd/lighttpd.conf:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 $HTTP[&amp;quot;host&amp;quot;] == &amp;quot;ACF_DOMAIN&amp;quot; {&lt;br /&gt;
	simple-vhost.server-root   = &amp;quot;/var/www/domains/&amp;quot;&lt;br /&gt;
	simple-vhost.default-host  = &amp;quot;/ACF_DOMAIN/&amp;quot;&lt;br /&gt;
	simple-vhost.document-root = &amp;quot;www/&amp;quot;&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
 $HTTP[&amp;quot;host&amp;quot;] == &amp;quot;POSTFIXADMIN_DOMAIN&amp;quot; {&lt;br /&gt;
	simple-vhost.server-root   = &amp;quot;/var/www/domains/&amp;quot;&lt;br /&gt;
	simple-vhost.default-host  = &amp;quot;/POSTFIXADMIN_DOMAIN/&amp;quot;&lt;br /&gt;
	simple-vhost.document-root = &amp;quot;www/&amp;quot;&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
 $HTTP[&amp;quot;host&amp;quot;] == &amp;quot;ROUNDCUBE_DOMAIN&amp;quot; {&lt;br /&gt;
	simple-vhost.server-root   = &amp;quot;/var/www/domains/&amp;quot;&lt;br /&gt;
	simple-vhost.default-host  = &amp;quot;/ROUNDCUBE_DOMAIN/&amp;quot;&lt;br /&gt;
	simple-vhost.document-root = &amp;quot;www/&amp;quot;&lt;br /&gt;
 }&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
And, then link the appropriate www directories.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  mkdir -p /var/www/domains/ACF_DOMAIN&lt;br /&gt;
  ln -s /usr/share/acf/www /var/www/domains/ACF_DOMAIN/www&lt;br /&gt;
&lt;br /&gt;
  mkdir -p /var/www/domains/POSTFIXADMIN_DOMAIN&lt;br /&gt;
  ln -s /var/www/domains/host.example.com/www/postfixadmin /var/www/domains/POSTFIXADMIN_DOMAIN/www&lt;br /&gt;
&lt;br /&gt;
  mkdir -p /var/www/domains/ROUNDCUBE_DOMAIN&lt;br /&gt;
  ln -s /usr/share/webapps/roundcube /var/www/domains/ROUNDCUBE_DOMAIN/www&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;/div&gt;</summary>
		<author><name>Djhughes</name></author>
	</entry>
	<entry>
		<id>https://wiki.alpinelinux.org/w/index.php?title=ISP_Mail_Server_HowTo&amp;diff=3835</id>
		<title>ISP Mail Server HowTo</title>
		<link rel="alternate" type="text/html" href="https://wiki.alpinelinux.org/w/index.php?title=ISP_Mail_Server_HowTo&amp;diff=3835"/>
		<updated>2010-05-20T07:29:19Z</updated>

		<summary type="html">&lt;p&gt;Djhughes: perms on log files, and restart services&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== A Full Service Mail Server ==&lt;br /&gt;
&lt;br /&gt;
The goal of this document is to describe how to set up postfix, dovecot, clamav, dspam, roundecube, and postfixadmin for a full-featured &amp;quot;ISP&amp;quot; level mail server.&lt;br /&gt;
&lt;br /&gt;
The server must provide:&lt;br /&gt;
&lt;br /&gt;
* multiple virtual domains&lt;br /&gt;
* admins for each domain (to add/remove virtual accounts)&lt;br /&gt;
* Quota support per domain / account&lt;br /&gt;
* downloading email via IMAP / IMAPS / POP3 / POP3S&lt;br /&gt;
* relaying email for authenticated users with TLS or SSL (Submission / SMTPS protocol)&lt;br /&gt;
* Standard filters (virus/spam/rbl/etc)&lt;br /&gt;
* Web mail client&lt;br /&gt;
* Value Add services&lt;br /&gt;
&lt;br /&gt;
== Set up Lighttpd + PHP ==&lt;br /&gt;
&lt;br /&gt;
PostfixAdmin needs php pgpsql and imap modules, so we do it in this step.&lt;br /&gt;
&lt;br /&gt;
  apk add lighttpd php php-pgsql php-imap&lt;br /&gt;
&lt;br /&gt;
Stop and remove mini_httpd, and move ACF to lighttpd;  We are setting this up to be a multi-domain virtual web server (replace host.example.com with the actual domain):&lt;br /&gt;
&lt;br /&gt;
  mkdir -p /var/www/domains/host.example.com/www&lt;br /&gt;
  ln -s /usr/share/acf/www /var/www/domains/host.example.com/www/acf&lt;br /&gt;
&lt;br /&gt;
Edit /var/www/domains/host.example.com/index.html to put a simple redirection page:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;lt;!DOCTYPE HTML PUBLIC &amp;quot;-//W3C//DTD HTML 4.01//EN&amp;quot; &amp;quot;http://www.w3.org/TR/html4/strict.dtd&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;html lang=&amp;quot;en&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;head&amp;gt;&lt;br /&gt;
&amp;lt;meta http-equiv=&amp;quot;Content-Type&amp;quot; content=&amp;quot;text/html; charset=ISO-8859-1&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;title&amp;gt;host.example.com Redirector&amp;lt;/title&amp;gt;&lt;br /&gt;
&amp;lt;/head&amp;gt;&lt;br /&gt;
&amp;lt;body&amp;gt;&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;&amp;lt;a href=&amp;quot;/acf&amp;quot;&amp;gt;ACF&amp;lt;/a&amp;gt;&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;&amp;lt;a href=&amp;quot;/postfixadmin&amp;quot;&amp;gt;PostfixAdmin&amp;lt;/a&amp;gt;&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;&amp;lt;a href=&amp;quot;/roundcube&amp;quot;&amp;gt;Roundcube&amp;lt;/a&amp;gt;&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
&amp;lt;/body&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Edit /etc/lighttpd/mod_cgi.conf to serve haserl files by adding a &amp;quot;&amp;quot; =&amp;gt; &amp;quot;&amp;quot; cgi handler and to treat /acf/cgi-bin as a CGI directory (remove the &#039;^&#039;)&lt;br /&gt;
&lt;br /&gt;
 $HTTP[&amp;quot;url&amp;quot;] =~ &amp;quot;/cgi-bin/&amp;quot; {&lt;br /&gt;
     # disable directory listings&lt;br /&gt;
     dir-listing.activate = &amp;quot;disable&amp;quot;&lt;br /&gt;
     # only allow cgi&#039;s in this directory&lt;br /&gt;
     cgi.assign = (&lt;br /&gt;
 		&amp;quot;.pl&amp;quot;	=&amp;gt;	&amp;quot;/usr/bin/perl&amp;quot;,&lt;br /&gt;
 		&amp;quot;.cgi&amp;quot;	=&amp;gt;	&amp;quot;/usr/bin/perl&amp;quot;,&lt;br /&gt;
 		&amp;quot;&amp;quot; =&amp;gt; &amp;quot;&amp;quot;&lt;br /&gt;
 	)&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
Get a web certificate, and install it.  You have two options: 1. If you want to use a self-signed cert, you can use the instructions found at [[Generating SSL certs with ACF]] or [[Generating SSL certs with ACF 1.9]] to generate it. 2. Use the certificate created with the &#039;&#039;&#039;setup-acf&#039;&#039;&#039; command. &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Option 1:&#039;&#039;&#039;&lt;br /&gt;
If you create your own self-signed certificate, you can create the &amp;quot;server-bundle.pem&amp;quot; and the &amp;quot;ca-crt.pem&amp;quot; file with these commands:&lt;br /&gt;
&lt;br /&gt;
  openssl pkcs12 -nokeys -cacerts -in certificate.pfx  -out /etc/lighttpd/ca-crt.pem&lt;br /&gt;
  openssl pkcs12 -nodes -in certificate.pfx -out /etc/lighttpd/server-bundle.pem&lt;br /&gt;
  chown root:root /etc/lighttpd/server-bundle.pem&lt;br /&gt;
  chmod 400 /etc/lighttpd/server-bundle.pem&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Note:&#039;&#039;&#039; The server certificate &#039;&#039;and&#039;&#039; key are in the server-bundle.pem file, so it is critical that the file be read-only by user &amp;quot;root&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Option 2:&#039;&#039;&#039;&lt;br /&gt;
If you prefer to just use the default certificate created with the &#039;&#039;&#039;setup-acf&#039;&#039;&#039; command, then you will need to do the following:&lt;br /&gt;
&lt;br /&gt;
  setup-acf&lt;br /&gt;
&lt;br /&gt;
During the above process, mini_httpd will be started, if it isn&#039;t already, and a certificate will be created. Once you have completed the setup-acf steps, do the following to move the certificate files to the correct location for lighttpd to use.&lt;br /&gt;
&lt;br /&gt;
  mv /etc/ssl/mini_httpd/server.pem /etc/lighttpd/server-bundle.pem&lt;br /&gt;
  chown root:root /etc/lighttpd/server-bundle.pem&lt;br /&gt;
  chmod 400 /etc/lighttpd/server-bundle.pem&lt;br /&gt;
&lt;br /&gt;
Add these lines to /etc/lighttpd/lighttpd.conf to point to the new document root, and set it up to listen on port 443 (replace &#039;&#039;host.example.com&#039;&#039; with the actual domain and &#039;&#039;ip_address_of_server&#039;&#039; with the actual IP address):&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
simple-vhost.server-root   = &amp;quot;/var/www/domains/&amp;quot;&lt;br /&gt;
simple-vhost.default-host  = &amp;quot;/host.example.com/&amp;quot;&lt;br /&gt;
simple-vhost.document-root = &amp;quot;www/&amp;quot;&lt;br /&gt;
&lt;br /&gt;
$SERVER[&amp;quot;socket&amp;quot;] == &amp;quot;ip_address_of_server:443&amp;quot; {&lt;br /&gt;
ssl.engine    = &amp;quot;enable&amp;quot;&lt;br /&gt;
ssl.pemfile   = &amp;quot;/etc/lighttpd/server-bundle.pem&amp;quot;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
If you went with Option 1 above, then add an additional line underneath the ssl.pemfile line, so that the section appears as follows:&lt;br /&gt;
&lt;br /&gt;
  $SERVER[&amp;quot;socket&amp;quot;] == &amp;quot;ip_address_of_server:443&amp;quot; {&lt;br /&gt;
  ssl.engine    = &amp;quot;enable&amp;quot;&lt;br /&gt;
  ssl.pemfile   = &amp;quot;/etc/lighttpd/server-bundle.pem&amp;quot;&lt;br /&gt;
  ssl.ca-file   = &amp;quot;/etc/lighttpd/ca-crt.pem&amp;quot;&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
Ensure that the simple_vhosts module is loaded, as well as the cgi config scripts by uncommenting the following lines in /etc/lighttpd/lighttpd.conf&lt;br /&gt;
&lt;br /&gt;
 server.modules = (&lt;br /&gt;
     #  other modules may be listed&lt;br /&gt;
     &amp;quot;mod_simple_vhost&amp;quot;, &lt;br /&gt;
     #  other modules may be listed&lt;br /&gt;
  .&lt;br /&gt;
  .&lt;br /&gt;
  .&lt;br /&gt;
     include &amp;quot;mod_cgi.conf&amp;quot;&lt;br /&gt;
 &lt;br /&gt;
     include &amp;quot;mod_fastcgi.conf&amp;quot;&lt;br /&gt;
&lt;br /&gt;
Stop and remove mini_httpd; start lighttpd, test&lt;br /&gt;
&lt;br /&gt;
  /etc/init.d/mini_httpd stop&lt;br /&gt;
  rc-update del mini_httpd&lt;br /&gt;
  apk del mini_httpd&lt;br /&gt;
  rc-update add lighttpd&lt;br /&gt;
  /etc/init.d/lighttpd start&lt;br /&gt;
&lt;br /&gt;
At this point you should be able to see ACF being served with lighttpd (Note: this will work well with alpine 1.10. With earlier versions there will be problems.)  https://host.example.com/acf/&lt;br /&gt;
&lt;br /&gt;
== Install Postgresql ==&lt;br /&gt;
&lt;br /&gt;
Add and configure postgresql&lt;br /&gt;
&lt;br /&gt;
  apk add acf-postgresql postgresql-client&lt;br /&gt;
  /etc/init.d/postgresql setup&lt;br /&gt;
  /etc/init.d/postgresql start&lt;br /&gt;
  rc-update add postgresql&lt;br /&gt;
&lt;br /&gt;
At this point any user can connect to the sql server with &amp;quot;trust&amp;quot; mechanism.  If you want to enforce password authentication (you probably do) edit /var/lib/postgresql/8.4/data/pg_hba.conf&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
  Editme: What should we recommend?&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Create the postfix database:&lt;br /&gt;
&lt;br /&gt;
  psql -U postgres&lt;br /&gt;
   create user postfix with password &#039;******&#039;;&lt;br /&gt;
   create database postfix owner postfix;&lt;br /&gt;
   \c postfix&lt;br /&gt;
   create language plpgsql;&lt;br /&gt;
   \q&lt;br /&gt;
&lt;br /&gt;
(Of course, use your selected password where ******* is shown above.)&lt;br /&gt;
&lt;br /&gt;
== Install PostfixAdmin ==&lt;br /&gt;
&lt;br /&gt;
We are going to install the postfix admin web front-end before we install the mail server.  This just creates an interface to populate the SQL tables that postfix and dovecot will use.&lt;br /&gt;
&lt;br /&gt;
Download PostfixAdmin from Sourceforge.  When these instructions were written, 2.3 was the current release, so (replace host.example.com with the actual domain):&lt;br /&gt;
 wget http://downloads.sourceforge.net/project/postfixadmin/postfixadmin/postfixadmin_2.3.tar.gz&lt;br /&gt;
 tar zxvf postfixadmin_2.3.tar.gz&lt;br /&gt;
 mkdir -p /var/www/domains/host.example.com/www/postfixadmin&lt;br /&gt;
 mv postfixadmin-2.3/* /var/www/domains/host.example.com/www/postfixadmin&lt;br /&gt;
 rm -rf postfixadmin*&lt;br /&gt;
&lt;br /&gt;
Edit /var/www/domains/host.example.com/www/postfixadmin/config.inc.php and modify at least these lines (replace host.example.com with the actual domain):&lt;br /&gt;
&lt;br /&gt;
 $CONF[&#039;configured&#039;] = true;&lt;br /&gt;
 $CONF[&#039;setup_password&#039;] = &amp;quot;&amp;quot;;  &amp;lt;&amp;lt; Don&#039;t change this yet&lt;br /&gt;
 $CONF[&#039;database_type&#039;] = &#039;pgsql&#039;;&lt;br /&gt;
 $CONF[&#039;database_host&#039;] = &#039;localhost&#039;;&lt;br /&gt;
 $CONF[&#039;database_user&#039;] = &#039;postfix&#039;;&lt;br /&gt;
 $CONF[&#039;database_password&#039;] = &#039;*****&#039;;   &amp;lt;&amp;lt; The password you chose above&lt;br /&gt;
 $CONF[&#039;database_name&#039;] = &#039;postfix&#039;;&lt;br /&gt;
 $CONF[&#039;database_prefix&#039;] = &amp;quot;&amp;quot;;&lt;br /&gt;
 $CONF[&#039;admin_email&#039;] = &#039;you@some.email.com&#039;;  &amp;lt;&amp;lt; Your email address &lt;br /&gt;
 $CONF[&#039;encrypt&#039;] = &#039;md5crypt&#039;;&lt;br /&gt;
 $CONF[&#039;authlib_default_flavor&#039;] = &#039;md5raw&#039;;&lt;br /&gt;
 $CONF[&#039;dovecotpw&#039;] = &amp;quot;/usr/sbin/dovecotpw&amp;quot;;&lt;br /&gt;
 $CONF[&#039;domain_path&#039;] = &#039;YES&#039;;&lt;br /&gt;
 $CONF[&#039;domain_in_mailbox&#039;] = &#039;NO&#039;;&lt;br /&gt;
 $CONF[&#039;aliases&#039;] = &#039;10&#039;;                       &lt;br /&gt;
 $CONF[&#039;mailboxes&#039;] = &#039;10&#039;;&lt;br /&gt;
 $CONF[&#039;maxquota&#039;] = &#039;10&#039;;&lt;br /&gt;
 $CONF[&#039;quota&#039;] = &#039;YES&#039;;&lt;br /&gt;
 $CONF[&#039;quota_multiplier&#039;] = &#039;1024000&#039;;&lt;br /&gt;
 $CONF[&#039;vacation&#039;] = &#039;NO&#039;; &lt;br /&gt;
 $CONF[&#039;vacation_control&#039;] =&#039;NO&#039;;&lt;br /&gt;
 $CONF[&#039;vacation_control_admin&#039;] = &#039;NO&#039;;&lt;br /&gt;
 $CONF[&#039;alias_control&#039;] = &#039;YES&#039;;&lt;br /&gt;
 $CONF[&#039;alias_control_admin&#039;] = &#039;YES&#039;;&lt;br /&gt;
 $CONF[&#039;special_alias_control&#039;] = &#039;YES&#039;;&lt;br /&gt;
 $CONF[&#039;fetchmail&#039;] = &#039;NO&#039;;&lt;br /&gt;
 $CONF[&#039;user_footer_link&#039;] = &amp;quot;http://host.example.com/postfixadmin&amp;quot;;&lt;br /&gt;
 $CONF[&#039;footer_link&#039;] = &#039;http://host.example.com/postfixadmin/main.php&#039;;&lt;br /&gt;
 $CONF[&#039;create_mailbox_subdirs_prefix&#039;]=&amp;quot;&amp;quot;;  &lt;br /&gt;
 $CONF[&#039;used_quotas&#039;] = &#039;YES&#039;;   &lt;br /&gt;
 $CONF[&#039;new_quota_table&#039;] = &#039;YES&#039;;  &lt;br /&gt;
&lt;br /&gt;
You should further edit /var/www/domains/host.example.com/www/postfixadmin/config.inc.php and replace all instances of &amp;quot;change-this-to-your.domain.tld&amp;quot; with your actual mail domain. This can be done with busybox sed (replace example.com with your domain name):&lt;br /&gt;
&lt;br /&gt;
 sed -i -e &#039;s/change-this-to-your.domain.tld/example.com/g&#039; /var/www/domains/host.example.com/www/postfixadmin/config.inc.php&lt;br /&gt;
&lt;br /&gt;
Go to http://host.example.com/postfixadmin/setup.php&lt;br /&gt;
&lt;br /&gt;
Create the password hash, add it to the config.inc.php file&lt;br /&gt;
&lt;br /&gt;
Go back to http://host.example.com/postfixadmin/setup.php&lt;br /&gt;
&lt;br /&gt;
Create superadmin account.&lt;br /&gt;
&lt;br /&gt;
== Install Postfix ==&lt;br /&gt;
&lt;br /&gt;
Create a user for the virtual mail delivery, and get its uid/gid (you&#039;ll need the numeric uid/gid for postfix)&lt;br /&gt;
&lt;br /&gt;
 adduser vmail -H -D -s /bin/false&lt;br /&gt;
 grep vmail /etc/passwd&lt;br /&gt;
&lt;br /&gt;
(In examples below, we use 1006/1006 for the uid/gid)&lt;br /&gt;
&lt;br /&gt;
Create the mail directory, and assign vmail as the owner&lt;br /&gt;
 mkdir -p /var/mail/domains&lt;br /&gt;
 chown -R vmail:vmail /var/mail/domains&lt;br /&gt;
 &lt;br /&gt;
&lt;br /&gt;
Install postfix&lt;br /&gt;
&lt;br /&gt;
 apk add acf-postfix postfix-pgsql&lt;br /&gt;
&lt;br /&gt;
Edit the /etc/postfix/main.cf file. Here&#039;s an example (don&#039;t forget to replace the uid/gid):&lt;br /&gt;
&lt;br /&gt;
 myhostname=host.example.com&lt;br /&gt;
 mydomain=example.com&lt;br /&gt;
 &lt;br /&gt;
 mydestination = localhost.$mydomain, localhost&lt;br /&gt;
 mynetworks_style = subnet&lt;br /&gt;
 mynetworks = 127.0.0.0/8&lt;br /&gt;
 &lt;br /&gt;
 virtual_mailbox_domains = proxy:pgsql:/etc/postfix/sql/pgsql_virtual_domains_maps.cf&lt;br /&gt;
 virtual_alias_maps = proxy:pgsql:/etc/postfix/sql/pgsql_virtual_alias_maps.cf,&lt;br /&gt;
        proxy:pgsql:/etc/postfix/sql/pgsql_virtual_alias_domain_maps.cf,&lt;br /&gt;
        proxy:pgsql:/etc/postfix/sql/pgsql_virtual_alias_domain_catchall_maps.cf&lt;br /&gt;
 &lt;br /&gt;
 virtual_mailbox_maps = proxy:pgsql:/etc/postfix/sql/pgsql_virtual_mailbox_maps.cf,&lt;br /&gt;
        proxy:pgsql:/etc/postfix/sql/pgsql_virtual_alias_domain_mailbox_maps.cf&lt;br /&gt;
 &lt;br /&gt;
 virtual_mailbox_base = /var/mail/domains/&lt;br /&gt;
 virtual_gid_maps = static:1006&lt;br /&gt;
 virtual_uid_maps = static:1006&lt;br /&gt;
 virtual_minimum_uid = 100&lt;br /&gt;
 virtual_transport = virtual&lt;br /&gt;
 &lt;br /&gt;
 &lt;br /&gt;
 # This next command means you must create a virtual&lt;br /&gt;
 # domain for the host itself - ALL mail goes through&lt;br /&gt;
 # The virtual transport&lt;br /&gt;
 &lt;br /&gt;
 mailbox_transport = virtual&lt;br /&gt;
 local_transport = virtual&lt;br /&gt;
 local_transport_maps = $virtual_mailbox_maps&lt;br /&gt;
 &lt;br /&gt;
 smtpd_helo_required = yes&lt;br /&gt;
 disable_vrfy_command = yes&lt;br /&gt;
 message_size_limit = 10240000&lt;br /&gt;
 queue_minfree = 51200000&lt;br /&gt;
 &lt;br /&gt;
 smtpd_sender_restrictions =&lt;br /&gt;
        permit_mynetworks,&lt;br /&gt;
        reject_non_fqdn_sender,&lt;br /&gt;
        reject_unknown_sender_domain&lt;br /&gt;
 &lt;br /&gt;
 smtpd_recipient_restrictions =&lt;br /&gt;
        reject_non_fqdn_recipient,&lt;br /&gt;
        reject_unknown_recipient_domain,&lt;br /&gt;
        permit_mynetworks,&lt;br /&gt;
        permit_sasl_authenticated,&lt;br /&gt;
        reject_unauth_destination,&lt;br /&gt;
        reject_rbl_client dnsbl.sorbs.net,&lt;br /&gt;
        reject_rbl_client zen.spamhaus.org,&lt;br /&gt;
        reject_rbl_client bl.spamcop.net&lt;br /&gt;
 &lt;br /&gt;
 smtpd_data_restrictions = reject_unauth_pipelining&lt;br /&gt;
 &lt;br /&gt;
 # we will use this later - This prevents cleartext authentication&lt;br /&gt;
 # for relaying&lt;br /&gt;
 smtpd_tls_auth_only = yes&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Now we need to create a *bunch* of files so that postfix can get the delivery information out of sql. Here&#039;s a shell script to create the scripts.  Change PGPW to the password for the postfix user of the postfix SQL database.&lt;br /&gt;
&lt;br /&gt;
 cd /etc/postfix&lt;br /&gt;
 mkdir sql&lt;br /&gt;
 PGPW=&amp;quot;ChangeMe&amp;quot;&lt;br /&gt;
 &lt;br /&gt;
 cat - &amp;lt;&amp;lt;EOF &amp;gt;sql/pgsql_virtual_alias_domain_catchall_maps.cf&lt;br /&gt;
 user=postfix&lt;br /&gt;
 password = $PGPW&lt;br /&gt;
 hosts = localhost&lt;br /&gt;
 dbname = postfix&lt;br /&gt;
 query = Select goto From alias,alias_domain where alias_domain.alias_domain = &#039;%d&#039; and alias.address = &#039;@&#039; ||  alias_domain.target_domain and alias.active = true and alias_domain.active= true &lt;br /&gt;
 EOF&lt;br /&gt;
 &lt;br /&gt;
 cat - &amp;lt;&amp;lt;EOF &amp;gt;sql/pgsql_virtual_alias_domain_mailbox_maps.cf&lt;br /&gt;
 user=postfix&lt;br /&gt;
 password = $PGPW&lt;br /&gt;
 hosts = localhost&lt;br /&gt;
 dbname = postfix&lt;br /&gt;
 query = Select maildir from mailbox,alias_domain where alias_domain.alias_domain = &#039;%d&#039; and mailbox.username = &#039;%u&#039; || &#039;@&#039; || alias_domain.target_domain and mailbox.active = true and alias_domain.active&lt;br /&gt;
 EOF&lt;br /&gt;
 &lt;br /&gt;
 cat - &amp;lt;&amp;lt;EOF &amp;gt;sql/pgsql_virtual_alias_domain_maps.cf&lt;br /&gt;
 user=postfix&lt;br /&gt;
 password = $PGPW&lt;br /&gt;
 hosts = localhost&lt;br /&gt;
 dbname = postfix&lt;br /&gt;
 query = select goto from alias,alias_domain where alias_domain.alias_domain=&#039;%d&#039; and alias.address = &#039;%u&#039; || &#039;@&#039; || alias_domain.target_domain and alias.active= true and alias_domain.active= true&lt;br /&gt;
 EOF&lt;br /&gt;
 &lt;br /&gt;
 cat - &amp;lt;&amp;lt;EOF &amp;gt;sql/pgsql_virtual_alias_maps.cf&lt;br /&gt;
 user=postfix&lt;br /&gt;
 password = $PGPW&lt;br /&gt;
 hosts = localhost&lt;br /&gt;
 dbname = postfix&lt;br /&gt;
 query = Select goto From alias Where address=&#039;%s&#039; and active =&#039;1&#039;&lt;br /&gt;
 EOF&lt;br /&gt;
 &lt;br /&gt;
 cat - &amp;lt;&amp;lt;EOF &amp;gt;sql/pgsql_virtual_domains_maps.cf&lt;br /&gt;
 user=postfix&lt;br /&gt;
 password = $PGPW&lt;br /&gt;
 hosts = localhost&lt;br /&gt;
 dbname = postfix&lt;br /&gt;
 query = Select domain from domain where domain=&#039;%s&#039; and active=&#039;1&#039;&lt;br /&gt;
 EOF&lt;br /&gt;
 &lt;br /&gt;
 cat - &amp;lt;&amp;lt;EOF &amp;gt;sql/pgsql_virtual_mailbox_maps.cf&lt;br /&gt;
 user=postfix&lt;br /&gt;
 password = $PGPW&lt;br /&gt;
 hosts = localhost&lt;br /&gt;
 dbname = postfix&lt;br /&gt;
 query = Select maildir from mailbox where username=&#039;%s&#039; and active=true&lt;br /&gt;
 EOF&lt;br /&gt;
 &lt;br /&gt;
 chown -R postfix:postfix sql&lt;br /&gt;
 chmod 640 sql/*&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
At this point you should be able to start up postfix&lt;br /&gt;
 &lt;br /&gt;
 newaliases  # so postfix is happy...&lt;br /&gt;
 /etc/init.d/postfix start&lt;br /&gt;
 rc-update add postfix&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Create a domain in PostfixAdmin and test ===&lt;br /&gt;
&lt;br /&gt;
Go to http://host.example.com/postfixadmin/&lt;br /&gt;
&lt;br /&gt;
Log in using the superadmin account, create a domain for the local box (e.g. example.com), and create a user mailbox (e.g. root).&lt;br /&gt;
&lt;br /&gt;
From the machine, send a test message:&lt;br /&gt;
&lt;br /&gt;
 sendmail -t root@example.com&lt;br /&gt;
 subject: test&lt;br /&gt;
 .&lt;br /&gt;
 ^d&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
In /var/log/mail.log (or /var/log/messages, if you still have busybox syslogd running) you should see the message queued.  The message should be in /var/mail/domains/example.com/root/new&lt;br /&gt;
&lt;br /&gt;
== Install Dovecot ==&lt;br /&gt;
&lt;br /&gt;
Dovecot is the POP3/IMAP server to retrieve mail.&lt;br /&gt;
&lt;br /&gt;
As before, we install dovecot: &lt;br /&gt;
&lt;br /&gt;
 apk add acf-dovecot dovecot-pgsql&lt;br /&gt;
&lt;br /&gt;
edit /etc/dovecot/dovecot.conf&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
# Select only the protocols you wish to support - all are listed in the next line&lt;br /&gt;
protocols               =       imap imaps pop pop3s&lt;br /&gt;
log_path                =       /var/log/dovecot.log&lt;br /&gt;
info_log_path           =       /var/log/dovecot-info.log&lt;br /&gt;
disable_plaintext_auth  =       no&lt;br /&gt;
&lt;br /&gt;
# Authenticated IMAP&lt;br /&gt;
ssl                     =       yes&lt;br /&gt;
ssl_cert_file           =       /etc/lighttpd/server-bundle.pem&lt;br /&gt;
ssl_key_file            =       /etc/lighttpd/server-bundle.pem&lt;br /&gt;
auth_verbose            =       yes&lt;br /&gt;
auth_debug              =       no&lt;br /&gt;
mail_location           =       maildir:/var/mail/domains/%d/%n&lt;br /&gt;
auth default    {&lt;br /&gt;
       mechanisms = plain&lt;br /&gt;
       passdb sql {&lt;br /&gt;
               args = /etc/dovecot/dovecot-sql.conf&lt;br /&gt;
               }&lt;br /&gt;
       userdb static {&lt;br /&gt;
               args =  uid=1006 gid=1006 home=/var/mail/domains/%d/%n&lt;br /&gt;
               }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Be sure to replace the uid and gid with the appropriate values for the vmail user.&lt;br /&gt;
&lt;br /&gt;
We need a certificate for SSL/TLS authentication, so in the example above, we use the lighttpd cert. That way when the cert is renewed/replaced, Dovecot will have access to the new cert as well.  &lt;br /&gt;
&lt;br /&gt;
Create the /etc/dovecot/dovecot-sql.conf file:&lt;br /&gt;
&lt;br /&gt;
 driver = pgsql&lt;br /&gt;
 connect = host=localhost dbname=postfix user=postfix password=********&lt;br /&gt;
 password_query = select username,password from mailbox where local_part = &#039;%n&#039; and domain = &#039;%d&#039;&lt;br /&gt;
 default_pass_scheme =  MD5-CRYPT&lt;br /&gt;
&lt;br /&gt;
Again, change the password above to your postfix user password, and protect the file from prying eyes:&lt;br /&gt;
&lt;br /&gt;
 chown root:root /etc/dovecot/dovecot-sql.conf&lt;br /&gt;
 chmod 600 /etc/dovecot/dovecot-sql.conf&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Start dovecot&lt;br /&gt;
 /etc/init.d/dovecot start&lt;br /&gt;
 rc-update add dovecot&lt;br /&gt;
&lt;br /&gt;
== Testing ==&lt;br /&gt;
&lt;br /&gt;
Make sure your firewall allows in ports 25(SMTP) 110 (POP3), 995 (POP3S), 143(IMAP), 993(IMAPS), or whatever subset you support.  &lt;br /&gt;
 &lt;br /&gt;
At this point, you should be able to:&lt;br /&gt;
 * Create a new domain and add users with PostfixAdmin&lt;br /&gt;
 * Send mail to those users via SMTP to port 25&lt;br /&gt;
 * Retrieve mail using the user&#039;s full email and password (e.g. username: user@example.com  password: ChangeMe)&lt;br /&gt;
&lt;br /&gt;
== Value Add Features ==&lt;br /&gt;
&lt;br /&gt;
If you followed the guide above, you now have a functional mail server with many interconnected parts.  The features below assume that the server is already running as described above.  You should be able to add any or all of these features below to further enhance the mail service.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Virus Scanning ===&lt;br /&gt;
&lt;br /&gt;
This procedure uses clamav and the postfix content_filter mechanism to scan inbound and outbound email for viruses.  Infected emails are dropped.  Clean emails are tagged with a &amp;quot;scanned by clamav&amp;quot; header.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* Install clamav and clamsmtp:&lt;br /&gt;
 apk add acf-clamav clamsmtp&lt;br /&gt;
* Edit the /etc/clamav/clamd.conf file if desired (not necessary in most cases)&lt;br /&gt;
* Edit /etc/clamsmtpd.conf and verify the following lines&lt;br /&gt;
 OutAddress: 10026&lt;br /&gt;
 Listen: 127.0.0.1:10025                                               &lt;br /&gt;
 Header: X-Virus-Scanned: ClamAV using ClamSMTP&lt;br /&gt;
 Action: drop&lt;br /&gt;
 User: clamav                                                      &lt;br /&gt;
* Start the daemons&lt;br /&gt;
 rc-update add clamd&lt;br /&gt;
 rc-update add clamsmtpd&lt;br /&gt;
 /etc/init.d/clamd start&lt;br /&gt;
 /etc/init.d/clamsmtpd start&lt;br /&gt;
* Verify clamsmtp is listening on port 10025:&lt;br /&gt;
 netstat -anp | grep clamsmtp&lt;br /&gt;
* [http://memberwebs.com/stef/software/clamsmtp/postfix.html Following the clamsmtp instructions]&lt;br /&gt;
** edit /etc/postfix/main.cf and add:&lt;br /&gt;
 content_filter = scan:[127.0.0.1]:10025                                                      &lt;br /&gt;
** edit /etc/postfix/master.cf and add&lt;br /&gt;
 # AV scan filter (used by content_filter)&lt;br /&gt;
 scan      unix  -       -       n       -       16      smtp&lt;br /&gt;
         -o smtp_send_xforward_command=yes&lt;br /&gt;
         -o smtp_enforce_tls=no&lt;br /&gt;
 # For injecting mail back into postfix from the filter&lt;br /&gt;
 127.0.0.1:10026 inet  n -       n       -       16      smtpd&lt;br /&gt;
         -o content_filter=&lt;br /&gt;
         -o receive_override_options=no_unknown_recipient_checks,no_header_body_checks&lt;br /&gt;
         -o smtpd_helo_restrictions=&lt;br /&gt;
         -o smtpd_client_restrictions=&lt;br /&gt;
         -o smtpd_sender_restrictions=&lt;br /&gt;
         -o smtpd_recipient_restrictions=permit_mynetworks,reject&lt;br /&gt;
         -o mynetworks_style=host&lt;br /&gt;
         -o smtpd_authorized_xforward_hosts=127.0.0.0/8&lt;br /&gt;
* postfix reload&lt;br /&gt;
* Send and email into a local virtual domain - it should have the &#039;&#039;X-Virus-Scanned: ClamAV using ClamSMTP&#039;&#039; header.&lt;br /&gt;
&lt;br /&gt;
=== Relay for Authenticated Users ===&lt;br /&gt;
&lt;br /&gt;
As configured above, the mail server accepts email from the Internet, but it does not relay email.  If it is a perimeter exchanger for a protected network, then you can add the protected networks to the &#039;&#039;mynetworks&#039;&#039; configuration line in /etc/postfix/main.cf&lt;br /&gt;
&lt;br /&gt;
This configuration change allows &#039;&#039;remote&#039;&#039; users to authenticate against the mail server and relay through it.  The rules for relaying are:&lt;br /&gt;
* Only authenticated users can relay&lt;br /&gt;
* Authentication Credentials must be encrypted with TLS or SSL&lt;br /&gt;
* Allow Submission and SMTPS ports for relaying (many consumer networks block port 25 - SMTP by default)&lt;br /&gt;
The process uses the dovecot authentication mechanism (used with IMAPS) to authenticate users before they are allowed to relay through postfix.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* Edit /etc/dovecot/dovecot.conf and add teh following inside the &#039;&#039;auth default&#039;&#039; stanza:&lt;br /&gt;
 # this is for postfix SASL (authenticated users can relay through us)&lt;br /&gt;
 socket listen {&lt;br /&gt;
                client {&lt;br /&gt;
                        path    = /var/spool/postfix/private/dovecot-auth.sock&lt;br /&gt;
                        mode    = 0660&lt;br /&gt;
                        user    = postfix&lt;br /&gt;
                        group   = postfix&lt;br /&gt;
                        }&lt;br /&gt;
                }&lt;br /&gt;
        }&lt;br /&gt;
* Restart dovecot&lt;br /&gt;
 /etc/init.d/dovecot restart&lt;br /&gt;
* Edit /etc/postfix/main.cf and add:&lt;br /&gt;
 # TLS Stuff -- since we allow SASL with tls *only*, we have to set up TLS first                    &lt;br /&gt;
 &lt;br /&gt;
 smtpd_tls_cert_file = /etc/lighttpd/server-bundle.pem&lt;br /&gt;
 smtpd_tls_key_file = /etc/lighttpd/server-bundle.pem&lt;br /&gt;
 smtpd_tls_CAfile = /etc/lighttpd/ca-crt.pem&lt;br /&gt;
 # If tls_security_level is set to &amp;quot;encrypt&amp;quot;, then SMTP rejects &lt;br /&gt;
 # unencrypted email (e.g. normal mail) which is bad.&lt;br /&gt;
 # By setting it to &amp;quot;may&amp;quot; you get TLS encrypted mail from google, slashdot, and other &lt;br /&gt;
 # interesting places.  Check your logs to see who&lt;br /&gt;
 smtpd_tls_security_level = may&lt;br /&gt;
 # Log info about the negotiated encryption levels&lt;br /&gt;
 smtpd_tls_received_header = yes&lt;br /&gt;
 smtpd_tls_loglevel = 1&lt;br /&gt;
 &lt;br /&gt;
 # SASL - this allows senders to authenticiate themselves&lt;br /&gt;
 # This along with &amp;quot;permit_sasl_authenticated&amp;quot; in smtpd_recipient_restrictions allows relaying&lt;br /&gt;
 smtpd_sasl_type = dovecot&lt;br /&gt;
 smtpd_sasl_path = private/dovecot-auth.sock&lt;br /&gt;
 smtpd_sasl_auth_enable = yes&lt;br /&gt;
 smtpd_sasl_authenticated_header = yes&lt;br /&gt;
 smtpd_tls_auth_only = yes&lt;br /&gt;
* Edit /etc/postfix/master.cf and enable the submission and smtps transports.  They are probably already at the top of your  master.cf file, just commented out:&lt;br /&gt;
 submission inet n       -       n       -       -       smtpd&lt;br /&gt;
   -o smtpd_tls_security_level=encrypt&lt;br /&gt;
   -o smtpd_sasl_auth_enable=yes&lt;br /&gt;
   -o smtpd_client_restrictions=permit_sasl_authenticated,reject&lt;br /&gt;
   -o milter_macro_daemon_name=ORIGINATING&lt;br /&gt;
 smtps     inet  n       -       n       -       -       smtpd&lt;br /&gt;
   -o smtpd_tls_security_level=encrypt&lt;br /&gt;
   -o smtpd_tls_wrappermode=yes&lt;br /&gt;
   -o smtpd_sasl_auth_enable=yes&lt;br /&gt;
   -o smtpd_client_restrictions=permit_sasl_authenticated,reject&lt;br /&gt;
   -o milter_macro_daemon_name=ORIGINATING&lt;br /&gt;
*Verfiy submission and smtps are defined in /etc/services&lt;br /&gt;
 grep &amp;quot;submission\|ssmtp&amp;quot; /etc/services&lt;br /&gt;
 submission	587/tcp				# mail message submission&lt;br /&gt;
 submission	587/udp&lt;br /&gt;
 smtps		465/tcp		ssmtp		# smtp protocol over TLS/SSL&lt;br /&gt;
 smtps		465/udp		ssmtp&lt;br /&gt;
* Restart postfix&lt;br /&gt;
 postfix reload&lt;br /&gt;
&lt;br /&gt;
At this point, you should be able to set up a mail client to relay through the server with TLS (port 587) or SSL (port 465)  Note that &amp;quot;plain&amp;quot; authentication is used because the underlying link is encrypted.  For example, in Thunderbird leave &amp;quot;secure authentication&amp;quot; unchecked, and choose STARTTLS (or TLS) for the connection security.&lt;br /&gt;
&lt;br /&gt;
=== Mailbox Quotas ===&lt;br /&gt;
&lt;br /&gt;
In the default configuration, PostfixAdmin knows about quotas, but they are not enforced.   Documentation on the web mentions the [http://vda.sourceforge.net vda patch to postfix] to enforce quotas.  The only bad thing... its a &#039;&#039;patch&#039;&#039;.   Postfix and Dovecot are both conservative systems, so if the patch isn&#039;t in the upstream source, we&#039;ll assume there&#039;s a good reason.   There is a way of using quotas without patches - and it involves using dovecot&#039;s [http://wiki.dovecot.org/LDA deliver] lda for local delivery.&lt;br /&gt;
&lt;br /&gt;
Note: As of Jan 2010, the documention is confusing, with multiple versions of dovecot, PostfixAdmin, and Mysql referenced.  These instructions apply to:&lt;br /&gt;
* Postgresql 8.4.2 &lt;br /&gt;
* PostfixAdmin 2.3 &lt;br /&gt;
* Dovecot 1.2.11&lt;br /&gt;
* Postfix 2.6.5&lt;br /&gt;
&lt;br /&gt;
Presumably later versions will work the same, but if not, please update the documentation and versions above.&lt;br /&gt;
&lt;br /&gt;
* Update /etc/dovecot/dovecot.conf (old lines shown commented out):&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
# old postfix &lt;br /&gt;
#       userdb static {&lt;br /&gt;
#               args =  uid=1006 gid=1006 home=/var/mail/domains/%d/%n&lt;br /&gt;
#               }&lt;br /&gt;
&lt;br /&gt;
# new quota support:&lt;br /&gt;
        userdb prefetch {&lt;br /&gt;
                }&lt;br /&gt;
&lt;br /&gt;
        userdb sql {&lt;br /&gt;
                args = /etc/dovecot/dovecot-sql.conf&lt;br /&gt;
                }&lt;br /&gt;
&lt;br /&gt;
        socket listen {&lt;br /&gt;
                client {&lt;br /&gt;
                        path    = /var/spool/postfix/private/dovecot-auth.sock&lt;br /&gt;
                        mode    = 0660&lt;br /&gt;
                        user    = postfix&lt;br /&gt;
                        group   = postfix&lt;br /&gt;
                        }&lt;br /&gt;
                # These lines below are for the deliver lda&lt;br /&gt;
                master {&lt;br /&gt;
                        path =  /var/run/dovecot/auth-master&lt;br /&gt;
                        mode    = 0660&lt;br /&gt;
                        user    = vmail&lt;br /&gt;
                        group   = vmail&lt;br /&gt;
                        }&lt;br /&gt;
                }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
protocol imap {                                                               &lt;br /&gt;
         mail_plugins = quota imap_quota                                       &lt;br /&gt;
         }                                                                     &lt;br /&gt;
                                                                              &lt;br /&gt;
protocol pop3 {                                                               &lt;br /&gt;
         mail_plugins = quota                                                  &lt;br /&gt;
         }                                                                     &lt;br /&gt;
                                                                              &lt;br /&gt;
dict {                                                                        &lt;br /&gt;
        quotadict = pgsql:/etc/dovecot/dovecot-dict-quota.conf                &lt;br /&gt;
        }                                                                     &lt;br /&gt;
                                                                              &lt;br /&gt;
plugin {                                                                      &lt;br /&gt;
         quota = dict:user::proxy::quotadict                                   &lt;br /&gt;
         }                                                     &lt;br /&gt;
                                                              &lt;br /&gt;
protocol lda {                                                &lt;br /&gt;
   postmaster_address = postmaster@host.example.com&lt;br /&gt;
   mail_plugins = quota                                        &lt;br /&gt;
   auth_socket_path =  /var/run/dovecot/auth-master&lt;br /&gt;
   sendmail_path = /usr/sbin/sendmail&lt;br /&gt;
}                                                                            &lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
 &lt;br /&gt;
You should already have a &amp;lt;tt&amp;gt;socket-&amp;gt; listen-&amp;gt; client&amp;lt;/tt&amp;gt; section, but it is listed above to show where it goes in relationship to the &amp;lt;tt&amp;gt;socket -&amp;gt; listen -&amp;gt; master&amp;lt;/tt&amp;gt; section&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* edit &amp;lt;tt&amp;gt;/etc/dovecot/dovecot-sql.conf&amp;lt;/tt&amp;gt; and replace the user and password queries with the following (you may not have a user_query yet - add it):&lt;br /&gt;
&lt;br /&gt;
 password_query = select username as user, password, 1006 as userdb_uid, 1006 as userdb_gid, &#039;*:bytes=&#039; || quota as userdb_quota_rule from mailbox  where local_part = &#039;%n&#039; and domain = &#039;%d&#039;&lt;br /&gt;
 user_query = select &#039;/var/mail/domains/&#039; || maildir as home, 1006 as uid, 1006 as gid, &#039;*:bytes=&#039; || quota  as quota_rule from mailbox where local_part = &#039;%n&#039; and domain =&#039;%d&#039;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* create &amp;lt;tt&amp;gt;/etc/dovecot/dovecot-dict-quota.conf&amp;lt;/tt&amp;gt;&lt;br /&gt;
 connect = host=localhost dbname=postfix user=postfix password=********&lt;br /&gt;
 &lt;br /&gt;
 map {&lt;br /&gt;
         pattern = priv/quota/storage&lt;br /&gt;
         table = quota2&lt;br /&gt;
         username_field =username&lt;br /&gt;
         value_field = bytes&lt;br /&gt;
 }&lt;br /&gt;
 &lt;br /&gt;
 map {&lt;br /&gt;
        pattern= priv/quota/messages&lt;br /&gt;
        table = quota2&lt;br /&gt;
        username_field = username&lt;br /&gt;
        value_field = messages&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
Again, change the password above to your postfix user password, and protect the file from prying eyes:&lt;br /&gt;
  chown root:root /etc/dovecot/dovecot-dict-quota.conf&lt;br /&gt;
  chmod 600 /etc/dovecot/dovecot-dict-quota.conf&lt;br /&gt;
&lt;br /&gt;
Side note: [http://wiki.dovecot.org/Quota/Dict The Dovecot Quota Documentation] mentions the need for a trigger with pgsql.  This was created in the PostfixAdmin install, which is why you instantiated the pgsql language when creating the database.  If not, you will need to create the trigger, to reference the quota2 table, not the quota table mentioned in the dovecot docs.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* create a new transport for the dovecot lda.   Add the following to  /etc/postfix/master.cf:&lt;br /&gt;
 # The dovecot deliver lda&lt;br /&gt;
 dovecot   unix  -       n       n       -       -       pipe&lt;br /&gt;
   flags=DRhu user=vmail:vmail argv=/usr/libexec/dovecot/deliver -f ${sender} -d ${user}@${nexthop}&lt;br /&gt;
&lt;br /&gt;
* Edit the /etc/postfix/main.cf.  Replace &lt;br /&gt;
 virtual_transport = virtual &lt;br /&gt;
with&lt;br /&gt;
 virtual_transport = dovecot&lt;br /&gt;
 dovecot_destination_recipient_limit = 1&lt;br /&gt;
&lt;br /&gt;
Change permissions on the /var/log/dovecot* log files, so that the vmail user can write to them:&lt;br /&gt;
&lt;br /&gt;
 chown vmail:vmail /var/log/dovecot*&lt;br /&gt;
&lt;br /&gt;
Restart Postfix and Dovecot:&lt;br /&gt;
&lt;br /&gt;
 /etc/init.d/postfix restart&lt;br /&gt;
 /etc/init.d/dovecot restart&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;TODO&#039;&#039;&#039;  This will cause over-quota emails to bounce.   Which could be a source of backscatter.   We need a way of checking quota limits after RBL checking but before the message is accepted in the queue.&lt;br /&gt;
&lt;br /&gt;
=== WebMail (RoundCube) ===&lt;br /&gt;
&lt;br /&gt;
[http://roundcube.net/ RoundCube] is an &amp;quot;ajax /Web2.0&amp;quot; web-mail client.  These instructions are for the Alpine Linux 1.10 repository &lt;br /&gt;
&lt;br /&gt;
* Add the package and related php modules:&lt;br /&gt;
 apk add roundcubemail php-xml php-openssl php-mcrypt php-gd php-iconv&lt;br /&gt;
&lt;br /&gt;
* link the roundcube application back into the docroot&lt;br /&gt;
 ln -s /usr/share/webapps/roundcube /var/www/domains/host.example.com/www/roundcube&lt;br /&gt;
&lt;br /&gt;
* follow the instructions in /usr/share/webapps/roundcube/INSTALL:&lt;br /&gt;
 cd /usr/share/webapps/roundcube&lt;br /&gt;
 chown -R lighttpd:lighttpd temp logs&lt;br /&gt;
 &lt;br /&gt;
 su postgres&lt;br /&gt;
 createuser roundcube&lt;br /&gt;
   Shall the new role be a superuser? (y/n) n&lt;br /&gt;
   Shall the new role be allowed to create databases? (y/n) n&lt;br /&gt;
   Shall the new role be allowed to create more new roles? (y/n) y&lt;br /&gt;
 createdb -O roundcube -E UNICODE -T template0 roundcubemail&lt;br /&gt;
 psql roundcubemail&lt;br /&gt;
   roundcubemail=# ALTER USER roundcube WITH PASSWORD &#039;the_new_password&#039;;&lt;br /&gt;
   roundcubemail=# \c - roundcube&lt;br /&gt;
   roundcubemail=&amp;gt; \i /usr/share/webapps/roundcube/SQL/postgres.initial.sql&lt;br /&gt;
   roundcubemail=&amp;gt; \q&lt;br /&gt;
 exit&lt;br /&gt;
&lt;br /&gt;
* edit /etc/php/php.ini and set date.timezone to your local timezone, or to UTC&lt;br /&gt;
&lt;br /&gt;
* restart lighttpd to verify the new php libraries are used&lt;br /&gt;
 /etc/init.d/lighttpd restart&lt;br /&gt;
&lt;br /&gt;
* Point your browser to http://host.example.com/roundcube/installer&lt;br /&gt;
* Start installation&lt;br /&gt;
&lt;br /&gt;
For the specific configuration parameters in the install step:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!Property&lt;br /&gt;
!Setting&lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;enable_spellcheck&#039;&#039; ||   disabled &lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;identities_level&#039;&#039; ||  one identity with possibility to edit all params but not email address &lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;log driver&#039;&#039; || syslog &lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;sylog_id&#039;&#039; || roundcube &lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;syslog_facility&#039;&#039; || mailsubsystem &lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;db_dnsw&#039;&#039; || pgsql properties, as described above &lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;imap_host&#039;&#039; || 127.0.0.1 &lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;auto_create_user&#039;&#039; || enabled &lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;smtp_server&#039;&#039; ||  127.0.0.1&lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;smtp_port&#039;&#039; ||  25&lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;smtp_user/smtp_pass&#039;&#039; ||  enable &#039;&#039;Use Current IMAP username and password for SMTP authentication&#039;&#039;&lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;smtp_log&#039;&#039; ||  enable (optional, but gives additional log record)&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
The other items can be left at default settings, or adjusted if desired.&lt;br /&gt;
&lt;br /&gt;
* Follow the instructions in step 3 of the install to copy the files to the server&lt;br /&gt;
* You should now be able to get to roundcube at http://host.example.com/roundcube&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
After its working, the INSTALL file recommends removing the install directory.   If you want to keep the installer around later, you can simply change the ownership and permissions.  So do &#039;&#039;&#039;one&#039;&#039;&#039; of the following:&lt;br /&gt;
 cd /usr/share/webapps/roundcube&lt;br /&gt;
 rm -rf LICENSE UPGRADING INSTALL README CHANGELOG  SQL installer&lt;br /&gt;
or&lt;br /&gt;
 cd /usr/share/webapps/roundcube&lt;br /&gt;
 chown -R root:root LICENSE UPGRADING INSTALL README CHANGELOG  SQL installer&lt;br /&gt;
 chmod -R 600 LICENSE UPGRADING INSTALL README CHANGELOG SQL &lt;br /&gt;
 chmod 700 SQL installer&lt;br /&gt;
&lt;br /&gt;
==== Enable Plug-ins ====&lt;br /&gt;
&lt;br /&gt;
RoundCube has various useful plug-ins, which could be found in &#039;&#039;/usr/share/webapps/roundcube/plugins&#039;&#039; directory. For example you may want to enable &#039;&#039;password&#039;&#039; plug-in to let users change their passwords directly from RoundCube using an extra Password Tab added to User Settings.&lt;br /&gt;
&lt;br /&gt;
* Grant limited permissions for &#039;&#039;roundcube&#039;&#039; database role &lt;br /&gt;
 psql -U postgres postfix&lt;br /&gt;
   postfix=# GRANT UPDATE (password,modified) ON mailbox TO roundcube;&lt;br /&gt;
   postfix=# GRANT SELECT (username) ON mailbox TO roundcube;&lt;br /&gt;
   postfix=# GRANT INSERT ON log TO roundcube;&lt;br /&gt;
   postfix=# \q&lt;br /&gt;
&lt;br /&gt;
* Setup &#039;&#039;password&#039;&#039; plug-in parameters in &#039;&#039;/usr/share/webapps/roundcube/plugins/password/config.inc.php&#039;&#039;&lt;br /&gt;
 mv /usr/share/webapps/roundcube/plugins/password/config.inc.php.dist /usr/share/webapps/roundcube/plugins/password/config.inc.php&lt;br /&gt;
 vi /usr/share/webapps/roundcube/plugins/password/config.inc.php&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
$rcmail_config[&#039;password_minimum_length&#039;] = 7;&lt;br /&gt;
$rcmail_config[&#039;password_require_nonalpha&#039;] = true;&lt;br /&gt;
...&lt;br /&gt;
$rcmail_config[&#039;password_db_dsn&#039;] = &#039;pgsql://roundcube:&amp;lt;roundcube_password&amp;gt;@localhost/postfix&#039;;&lt;br /&gt;
...&lt;br /&gt;
$rcmail_config[&#039;password_query&#039;] = &amp;quot;UPDATE mailbox set password = %c, modified = NOW() where username = %u; INSERT INTO log (timestamp,username,domain,action,data) VALUES (NOW(),%u || &#039; (&#039; || %h || &#039;)&#039;,%d,&#039;edit_password&#039;,%u)&amp;quot;;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* Enable &#039;&#039;password&#039;&#039; plug-in&lt;br /&gt;
 vi /usr/share/webapps/roundcube/config/main.inc.php&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
...&lt;br /&gt;
$rcmail_config[&#039;plugins&#039;] = array(&#039;password&#039;);&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== OpenLDAP based Address Book ===&lt;br /&gt;
&lt;br /&gt;
This OpenLDAP configuration uses the SQL backend, which represents information stored in PostgreSQL as an LDAP subtree for Address Book functionality for email lookups, user authentication or even &lt;br /&gt;
replication account information between sites. This procedure uses some metainformation to translate LDAP queries to SQL queries, leaving relational schema untouched, which allows SQL and LDAP &lt;br /&gt;
applications to inter-operate without replication, and exchange data as needed. The SQL backend uses UnixODBC to connect to PostgresSQL. &lt;br /&gt;
&lt;br /&gt;
* Install OpenLDAP and ODBC&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
apk add openldap libldap openldap-back-sql php-ldap unixodbc psqlodbc ca-certificates&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Note&#039;&#039;&#039;: The psqlodbc package is currently unavailable&lt;br /&gt;
&lt;br /&gt;
* Update &amp;quot;postfix&amp;quot; database (it will add &#039;id&#039; columns to mailbox and domain tables, also will create tables and views to represent LDAP metainformation)&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Note&#039;&#039;&#039;: These instructions are for example domain example.com. So make sure you replaced all entries of &#039;example&#039; and &#039;com&#039; according to your domain name parts.&lt;br /&gt;
&lt;br /&gt;
Put the following into a new file called &#039;&#039;&#039;script&#039;&#039;&#039;:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
ALTER TABLE domain ADD COLUMN id SERIAL; &lt;br /&gt;
ALTER TABLE mailbox ADD COLUMN id SERIAL; &lt;br /&gt;
&lt;br /&gt;
CREATE TABLE ldap_entry_objclasses (&lt;br /&gt;
    entry_id integer NOT NULL,&lt;br /&gt;
    oc_name character varying(64)&lt;br /&gt;
);&lt;br /&gt;
&lt;br /&gt;
CREATE TABLE ldap_oc_mappings (&lt;br /&gt;
    name character varying(64) NOT NULL,&lt;br /&gt;
    keytbl character varying(64) NOT NULL,&lt;br /&gt;
    keycol character varying(64) NOT NULL,&lt;br /&gt;
    create_proc character varying(255),&lt;br /&gt;
    delete_proc character varying(255),&lt;br /&gt;
    expect_return integer NOT NULL&lt;br /&gt;
);&lt;br /&gt;
&lt;br /&gt;
ALTER TABLE ldap_oc_mappings ADD COLUMN id SERIAL;&lt;br /&gt;
ALTER TABLE ldap_oc_mappings ADD PRIMARY KEY (id);&lt;br /&gt;
&lt;br /&gt;
CREATE TABLE ldap_attr_mappings (&lt;br /&gt;
    oc_map_id integer NOT NULL REFERENCES ldap_oc_mappings(id),&lt;br /&gt;
    name character varying(255) NOT NULL,&lt;br /&gt;
    sel_expr character varying(255) NOT NULL,&lt;br /&gt;
    sel_expr_u character varying(255),&lt;br /&gt;
    from_tbls character varying(255) NOT NULL,&lt;br /&gt;
    join_where character varying(255),&lt;br /&gt;
    add_proc character varying(255),&lt;br /&gt;
    delete_proc character varying(255),&lt;br /&gt;
    param_order integer NOT NULL,&lt;br /&gt;
    expect_return integer NOT NULL&lt;br /&gt;
);&lt;br /&gt;
&lt;br /&gt;
ALTER TABLE ldap_attr_mappings ADD COLUMN id SERIAL;&lt;br /&gt;
ALTER TABLE ldap_attr_mappings ADD PRIMARY KEY (id);&lt;br /&gt;
&lt;br /&gt;
CREATE VIEW ldap_dcs AS&lt;br /&gt;
    ((SELECT (domain.id + 100000) AS id,&lt;br /&gt;
            (&#039;dc=&#039;::text || replace((domain.domain)::text, &#039;.&#039;::text, &#039;,dc=&#039;::text)) AS dn,&lt;br /&gt;
            1 AS oc_map_id,&lt;br /&gt;
            100000 AS parent,&lt;br /&gt;
            0 AS keyval,&lt;br /&gt;
            domain.domain&lt;br /&gt;
     FROM domain&lt;br /&gt;
     WHERE domain.domain &amp;lt;&amp;gt; &#039;ALL&#039;)&lt;br /&gt;
      UNION&lt;br /&gt;
     (SELECT 100000 AS id,&lt;br /&gt;
           (&#039;dc=&#039; || regexp_replace((domain.domain)::text, &#039;.*\\.&#039;, &#039;&#039;::text)) AS dn,&lt;br /&gt;
           1 AS oc_map_id,&lt;br /&gt;
           0 AS parent,&lt;br /&gt;
           0 AS keyval,&lt;br /&gt;
           (regexp_replace((domain.domain)::text, &#039;.*\\.&#039;, &#039;&#039;::text)) AS domain&lt;br /&gt;
      FROM domain&lt;br /&gt;
      WHERE domain.domain &amp;lt;&amp;gt; &#039;ALL&#039;&lt;br /&gt;
      LIMIT 1));&lt;br /&gt;
&lt;br /&gt;
CREATE VIEW ldap_entries AS&lt;br /&gt;
    SELECT mailbox.id,&lt;br /&gt;
    (((&#039;cn=&#039;::text || initcap(replace(split_part((mailbox.username)::text, &#039;@&#039;::text, 1), &#039;.&#039;::text, &#039; &#039;::text))) || &#039;,dc=&#039;::text) ||&lt;br /&gt;
             replace(regexp_replace((mailbox.username)::text, &#039;.*@&#039;, &#039;&#039;::text), &#039;.&#039;::text, &#039;,dc=&#039;::text)) AS dn,&lt;br /&gt;
          1 AS oc_map_id,&lt;br /&gt;
          (SELECT ldap_dcs.id&lt;br /&gt;
           FROM ldap_dcs&lt;br /&gt;
           WHERE ((ldap_dcs.domain)::text = (mailbox.domain)::text)) AS parent,&lt;br /&gt;
           mailbox.id AS keyval&lt;br /&gt;
           FROM mailbox&lt;br /&gt;
           UNION&lt;br /&gt;
           SELECT ldap_dcs.id,&lt;br /&gt;
                  ldap_dcs.dn,&lt;br /&gt;
                  ldap_dcs.oc_map_id,&lt;br /&gt;
                  ldap_dcs.parent,&lt;br /&gt;
                  ldap_dcs.keyval&lt;br /&gt;
           FROM ldap_dcs;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Finally, execute the commands in the file with:&lt;br /&gt;
 cat script | psql -U postfix postfix&lt;br /&gt;
 rm script&lt;br /&gt;
&lt;br /&gt;
* Fill out LDAP tables according to following example (make sure to separate values with TABs):&lt;br /&gt;
&lt;br /&gt;
Put the following into a new file called &#039;&#039;&#039;script&#039;&#039;&#039;:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
COPY ldap_oc_mappings (id, name, keytbl, keycol, create_proc, delete_proc, expect_return) FROM stdin;&lt;br /&gt;
1	exampleBox	mailbox	id	\N	\N	1&lt;br /&gt;
\.&lt;br /&gt;
COPY ldap_attr_mappings (id, oc_map_id, name, sel_expr, sel_expr_u, from_tbls, join_where, add_proc, delete_proc, param_order, expect_return) FROM stdin;&lt;br /&gt;
1	1	displayName	mailbox.name	\N	mailbox	\N	\N	\N	3	0&lt;br /&gt;
2	1	mail	mailbox.username	\N	mailbox	\N	\N	\N	3	0&lt;br /&gt;
3	1	cn	mailbox.name	\N	mailbox	\N	\N	\N	3	0&lt;br /&gt;
4	1	userPassword	&#039;{CRYPT}&#039;||mailbox.password	\N	mailbox	\N	\N	\N	3	0&lt;br /&gt;
\.&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Finally, execute the commands in the file with:&lt;br /&gt;
 cat script | psql -U postfix postfix&lt;br /&gt;
 rm script&lt;br /&gt;
&lt;br /&gt;
* Check that &amp;quot;ldap_dcs&amp;quot; view looks something like this:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
echo &#039;select * from ldap_dcs&#039; | psql -U postgres postfix&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
   id   |             dn              | oc_map_id | parent | keyval |       domain       &lt;br /&gt;
--------+-----------------------------+-----------+--------+--------+--------------------&lt;br /&gt;
 100000 | dc=com                      |         1 |      0 |      0 | com&lt;br /&gt;
 100001 | dc=example,dc=com           |         1 | 100000 |      0 | example.com&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* Check that &amp;quot;ldap_entries&amp;quot; view looks something like this:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
echo &#039;select * from ldap_entries&#039; | psql -U postgres postfix&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
   id   |                          dn                           | oc_map_id | parent | keyval &lt;br /&gt;
--------+-------------------------------------------------------+-----------+--------+--------&lt;br /&gt;
    1   | cn=address1,dc=example,dc=com                         |         1 | 100001 |    1&lt;br /&gt;
...&lt;br /&gt;
   123  | cn=address123,dc=example,dc=com                       |         1 | 100001 |    1&lt;br /&gt;
 100000 | dc=com                                                |         1 |      0 |    0&lt;br /&gt;
 100001 | dc=example,dc=com                                     |         1 | 100000 |    0&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* Configure ODBC parameters&lt;br /&gt;
&lt;br /&gt;
Edit /etc/odbc.ini:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
[PostgreSQL]&lt;br /&gt;
Description             = Connection to Postgres&lt;br /&gt;
Driver                  = PostgreSQL&lt;br /&gt;
Trace                   = Yes&lt;br /&gt;
TraceFile               = sql.log&lt;br /&gt;
Database                = postfix&lt;br /&gt;
Servername              = 127.0.0.1&lt;br /&gt;
UserName                =&lt;br /&gt;
Password                =&lt;br /&gt;
Port                    = 5432&lt;br /&gt;
Protocol                = 6.4&lt;br /&gt;
ReadOnly                = No&lt;br /&gt;
RowVersining            = No&lt;br /&gt;
ShowSystemTables        = No&lt;br /&gt;
ShowOidColumn           = No&lt;br /&gt;
FakeOidIndex            = No&lt;br /&gt;
ConnSettings            =&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Edit /etc/odbcinst.ini:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
[PostgreSQL]&lt;br /&gt;
Description     = PostgreSQL driver for Linux&lt;br /&gt;
Driver          = /usr/lib/psqlodbcw.so&lt;br /&gt;
Setup           = /usr/lib/libodbcpsqlS.so&lt;br /&gt;
FileUsage       = 1&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* Test ODBC connection&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
echo &amp;quot;select * from domain;&amp;quot; | isql PostgreSQL postgres&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* Provide permission to certificate for LDAP server&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
chown ldap /etc/lighttpd/server-bundle.pem&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* Edit LDAP schema&lt;br /&gt;
&lt;br /&gt;
Edit /etc/openldap/schema/example.com.schema:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
attributetype ( 0.9.2342.19200300.100.1.3&lt;br /&gt;
	NAME ( &#039;mail&#039; &#039;rfc822Mailbox&#039; )&lt;br /&gt;
	DESC &#039;RFC1274: RFC822 Mailbox&#039;&lt;br /&gt;
        EQUALITY caseIgnoreIA5Match&lt;br /&gt;
        SUBSTR caseIgnoreIA5SubstringsMatch&lt;br /&gt;
        SYNTAX 1.3.6.1.4.1.1466.115.121.1.26{256} )&lt;br /&gt;
&lt;br /&gt;
attributetype ( 2.16.840.1.113730.3.1.241&lt;br /&gt;
	NAME &#039;displayName&#039;&lt;br /&gt;
	DESC &#039;RFC2798: preferred name to be used when displaying entries&#039;&lt;br /&gt;
	EQUALITY caseIgnoreMatch&lt;br /&gt;
	SUBSTR caseIgnoreSubstringsMatch&lt;br /&gt;
	SYNTAX 1.3.6.1.4.1.1466.115.121.1.15&lt;br /&gt;
	SINGLE-VALUE )&lt;br /&gt;
&lt;br /&gt;
objectclass   ( 2.16.840.1.113730.3.2.2&lt;br /&gt;
        NAME &#039;exampleBox&#039;&lt;br /&gt;
	DESC &#039;example.com mailbox&#039;&lt;br /&gt;
	MUST ( displayName $ mail $ userPassword )&lt;br /&gt;
	)&lt;br /&gt;
&lt;br /&gt;
# RFC 1274 + RFC 2247&lt;br /&gt;
attributetype ( 0.9.2342.19200300.100.1.25&lt;br /&gt;
        NAME ( &#039;dc&#039; &#039;domainComponent&#039; )&lt;br /&gt;
        DESC &#039;RFC1274/2247: domain component&#039;&lt;br /&gt;
        EQUALITY caseIgnoreIA5Match&lt;br /&gt;
        SUBSTR caseIgnoreIA5SubstringsMatch&lt;br /&gt;
        SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 SINGLE-VALUE )&lt;br /&gt;
&lt;br /&gt;
attributetype ( 2.5.4.46 NAME &#039;dnQualifier&#039;&lt;br /&gt;
        DESC &#039;RFC2256: DN qualifier&#039;&lt;br /&gt;
        EQUALITY caseIgnoreMatch&lt;br /&gt;
        ORDERING caseIgnoreOrderingMatch&lt;br /&gt;
        SUBSTR caseIgnoreSubstringsMatch&lt;br /&gt;
        SYNTAX 1.3.6.1.4.1.1466.115.121.1.44 )&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* Configure LDAP server&lt;br /&gt;
&lt;br /&gt;
Edit /etc/openldap/slapd.conf:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
include         /etc/openldap/schema/example.com.schema&lt;br /&gt;
pidfile         /var/run/openldap/slapd.pid&lt;br /&gt;
argsfile        /var/run/openldap/slapd.args&lt;br /&gt;
&lt;br /&gt;
TLSCipherSuite HIGH&lt;br /&gt;
TLSCACertificateFile /etc/lighttpd/ca-crt.pem&lt;br /&gt;
TLSCertificateFile /etc/lighttpd/server-bundle.pem&lt;br /&gt;
TLSCertificateKeyFile /etc/lighttpd/server-bundle.pem&lt;br /&gt;
TLSVerifyClient never &lt;br /&gt;
&lt;br /&gt;
# This is needed for proper representation of MD5-CRYPT format stored in database&lt;br /&gt;
#  see more details in http://strugglers.net/~andy/blog/2010/01/23/openldap-and-md5crypt/&lt;br /&gt;
password-hash  {CRYPT}&lt;br /&gt;
password-crypt-salt-format &amp;quot;$1$%.8s&amp;quot;&lt;br /&gt;
&lt;br /&gt;
loglevel        stats&lt;br /&gt;
moduleload	/usr/lib/openldap/back_sql.so&lt;br /&gt;
sizelimit 3000&lt;br /&gt;
&lt;br /&gt;
database        sql&lt;br /&gt;
&lt;br /&gt;
dbname		PostgreSQL&lt;br /&gt;
dbuser		postfix&lt;br /&gt;
dbpasswd	*****&lt;br /&gt;
&lt;br /&gt;
suffix          &amp;quot;dc=example,dc=com&amp;quot;&lt;br /&gt;
&lt;br /&gt;
upper_func      &amp;quot;upper&amp;quot;&lt;br /&gt;
strcast_func    &amp;quot;text&amp;quot;&lt;br /&gt;
concat_pattern  &amp;quot;?||?&amp;quot;&lt;br /&gt;
has_ldapinfo_dn_ru      no&lt;br /&gt;
lastmod         off&lt;br /&gt;
&lt;br /&gt;
access to attrs=userPassword by * auth&lt;br /&gt;
&lt;br /&gt;
access to * by peername.ip=127.0.0.1 read&lt;br /&gt;
#           by peername.ip=&amp;lt;IP&amp;gt;%&amp;lt;netmask&amp;gt; read&lt;br /&gt;
#           by peername.ip=&amp;lt;IP&amp;gt; read&lt;br /&gt;
	    by users read&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* Set permissions for slapd.conf&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
chown ldap:ldap /etc/openldap/slapd.conf&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* Configure startup parameters to make sure that LDAP server start AFTER PostgreSQL and listens on localhost with clear text and public IP with SSL&lt;br /&gt;
&lt;br /&gt;
Edit /etc/conf.d/slapd:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
rc_need=&amp;quot;postgresql&amp;quot; &lt;br /&gt;
OPTS=&amp;quot;-h &#039;ldaps:// ldap://127.0.0.1&#039;&amp;quot;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* Start LDAP server&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
rc-update add slapd default&lt;br /&gt;
/etc/init.d/slapd start&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* Configure LDAP client utilities&lt;br /&gt;
&lt;br /&gt;
Edit /etc/openldap/ldap.conf&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
BASE	dc=example,dc=com&lt;br /&gt;
URI	ldaps://host.example.com&lt;br /&gt;
&lt;br /&gt;
TLS_CACERT /etc/lighttpd/ca-crt.pem&lt;br /&gt;
TLS_CERT /etc/lighttpd/server-bundle.pem&lt;br /&gt;
TLS_KEY /etc/lighttpd/server-bundle.pem&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* Test LDAP server&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
ldapsearch -z 3&lt;br /&gt;
ldapsearch -z 3 -x -W -D cn=admin,dc=example,dc=com&lt;br /&gt;
ldapsearch -z 3 -x -W -D cn=address1,dc=example,dc=com&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* Configure RoundCube webmail for email lookups&lt;br /&gt;
&lt;br /&gt;
In order to enable php-ldap support you need to restart lighttpd server&lt;br /&gt;
&lt;br /&gt;
 /etc/init.d/lighttpd restart&lt;br /&gt;
&lt;br /&gt;
Edit /usr/share/webapps/roundcube/config/main.inc.php:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
$rcmail_config[&#039;ldap_debug&#039;] = false;&lt;br /&gt;
...&lt;br /&gt;
$rcmail_config[&#039;address_book_type&#039;] = &#039;sql&#039;;&lt;br /&gt;
&lt;br /&gt;
$rcmail_config[&#039;ldap_public&#039;][&#039;example.com&#039;] = array(&lt;br /&gt;
  &#039;name&#039;          =&amp;gt; &#039;example.com&#039;,&lt;br /&gt;
  &#039;hosts&#039;         =&amp;gt; array(&#039;127.0.0.1&#039;),&lt;br /&gt;
  &#039;port&#039;          =&amp;gt; 389,&lt;br /&gt;
  &#039;use_tls&#039;         =&amp;gt; false,&lt;br /&gt;
  &#039;user_specific&#039; =&amp;gt; false,&lt;br /&gt;
  &#039;base_dn&#039;       =&amp;gt; &#039;dc=example,dc=com&#039;,&lt;br /&gt;
  &#039;bind_dn&#039;       =&amp;gt; &#039;&#039;,&lt;br /&gt;
  &#039;bind_pass&#039;     =&amp;gt; &#039;&#039;,&lt;br /&gt;
  &#039;writable&#039;      =&amp;gt; false,&lt;br /&gt;
  &#039;LDAP_Object_Classes&#039; =&amp;gt; array(&amp;quot;top&amp;quot;, &amp;quot;exampleBox&amp;quot;),&lt;br /&gt;
  &#039;required_fields&#039;     =&amp;gt; array(&amp;quot;cn&amp;quot;, &amp;quot;sn&amp;quot;, &amp;quot;mail&amp;quot;),&lt;br /&gt;
  &#039;LDAP_rdn&#039;      =&amp;gt; &#039;mail&#039;,&lt;br /&gt;
  &#039;ldap_version&#039;  =&amp;gt; 3,&lt;br /&gt;
  &#039;search_fields&#039; =&amp;gt; array(&#039;mail&#039;, &#039;cn&#039;, &#039;sn&#039;, &#039;givenName&#039;),&lt;br /&gt;
  &#039;name_field&#039;    =&amp;gt; &#039;cn&#039;,&lt;br /&gt;
  &#039;email_field&#039;   =&amp;gt; &#039;mail&#039;,&lt;br /&gt;
  &#039;surname_field&#039; =&amp;gt; &#039;sn&#039;,&lt;br /&gt;
  &#039;firstname_field&#039; =&amp;gt; &#039;gn&#039;,&lt;br /&gt;
  &#039;sort&#039;          =&amp;gt; &#039;cn&#039;,&lt;br /&gt;
  &#039;scope&#039;         =&amp;gt; &#039;sub&#039;,&lt;br /&gt;
  &#039;filter&#039;        =&amp;gt; &#039;(objectClass=*)&#039;, // Construct here any filter you need&lt;br /&gt;
  &#039;fuzzy_search&#039;  =&amp;gt; true);&lt;br /&gt;
&lt;br /&gt;
$rcmail_config[&#039;autocomplete_addressbooks&#039;] = array(&#039;sql&#039;,&#039;example.com&#039;);&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* Fix PostfixAdmin to work with the new table definition&lt;br /&gt;
&lt;br /&gt;
Edit /var/www/domains/example.com/www/list-domain.php. Replace the line:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
   SELECT domain.* , COUNT( DISTINCT mailbox.username ) AS mailbox_count&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
With the lines:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
   SELECT domain.domain, domain.description, domain.aliases, domain.mailboxes,&lt;br /&gt;
   domain.maxquota, domain.quota, domain.transport, domain.backupmx, domain.created,&lt;br /&gt;
   domain.modified, domain.active, COUNT( DISTINCT mailbox.username ) AS mailbox_count&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== log rotation ==&lt;br /&gt;
&lt;br /&gt;
Ensure the busybox cron service is started and is configured to auto-start:&lt;br /&gt;
&lt;br /&gt;
 /etc/init.d/cron start&lt;br /&gt;
 rc-update add cron default&lt;br /&gt;
&lt;br /&gt;
Add log rotate:&lt;br /&gt;
&lt;br /&gt;
 apk add logrotate&lt;br /&gt;
&lt;br /&gt;
Edit &#039;&#039;/etc/logrotate.conf&#039;&#039; as desired, but the defaults should be sufficient for most people.&lt;br /&gt;
&lt;br /&gt;
== Optional: Configure Web Server Virtual Domains ==&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Note:&#039;&#039;&#039; These steps can be done &#039;&#039;in addition to&#039;&#039; the default lighttpd configuration above, which allows you to access the ACF, PostfixAdmin and Roundcube interfaces as subfolders of one web service.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Note:&#039;&#039;&#039; If you provide SSL access for multiple domain site you may need to follow http://redmine.lighttpd.net/projects/lighttpd/wiki/Docs:SSL#SSL-on-multiple-domains in order to provide multi-domain certificates. If you would like to redirect hosts to their secure equivalents use the following instructions http://redmine.lighttpd.net/projects/lighttpd/wiki/HowToRedirectHttpToHttps.&lt;br /&gt;
&lt;br /&gt;
This server hosts three separate web applications, and these can be handled as three &#039;&#039;different&#039;&#039; virtual domains on the same web server. They will be distinguished by their DNS names, so you can choose domains for the three separate services (or at least the ones you want to publish):&lt;br /&gt;
&lt;br /&gt;
* ACF - Alpine Configuration Framework for managing the server&lt;br /&gt;
* PostfixAdmin - for managing the postfix installation&lt;br /&gt;
* RoundCube - for accessing individual mailboxes&lt;br /&gt;
&lt;br /&gt;
Choose three different domains (from here on known as ACF_DOMAIN, POSTFIXADMIN_DOMAIN, and ROUNDCUBE_DOMAIN) and configure DNS for all three to point to the IP address of your host. These should be DNS &#039;&#039;&#039;A&#039;&#039;&#039; records.&lt;br /&gt;
&lt;br /&gt;
Then, configure lighttpd to handle the three separate domains by editing /etc/lighttpd/lighttpd.conf:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 $HTTP[&amp;quot;host&amp;quot;] == &amp;quot;ACF_DOMAIN&amp;quot; {&lt;br /&gt;
	simple-vhost.server-root   = &amp;quot;/var/www/domains/&amp;quot;&lt;br /&gt;
	simple-vhost.default-host  = &amp;quot;/ACF_DOMAIN/&amp;quot;&lt;br /&gt;
	simple-vhost.document-root = &amp;quot;www/&amp;quot;&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
 $HTTP[&amp;quot;host&amp;quot;] == &amp;quot;POSTFIXADMIN_DOMAIN&amp;quot; {&lt;br /&gt;
	simple-vhost.server-root   = &amp;quot;/var/www/domains/&amp;quot;&lt;br /&gt;
	simple-vhost.default-host  = &amp;quot;/POSTFIXADMIN_DOMAIN/&amp;quot;&lt;br /&gt;
	simple-vhost.document-root = &amp;quot;www/&amp;quot;&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
 $HTTP[&amp;quot;host&amp;quot;] == &amp;quot;ROUNDCUBE_DOMAIN&amp;quot; {&lt;br /&gt;
	simple-vhost.server-root   = &amp;quot;/var/www/domains/&amp;quot;&lt;br /&gt;
	simple-vhost.default-host  = &amp;quot;/ROUNDCUBE_DOMAIN/&amp;quot;&lt;br /&gt;
	simple-vhost.document-root = &amp;quot;www/&amp;quot;&lt;br /&gt;
 }&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
And, then link the appropriate www directories.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  mkdir -p /var/www/domains/ACF_DOMAIN&lt;br /&gt;
  ln -s /usr/share/acf/www /var/www/domains/ACF_DOMAIN/www&lt;br /&gt;
&lt;br /&gt;
  mkdir -p /var/www/domains/POSTFIXADMIN_DOMAIN&lt;br /&gt;
  ln -s /var/www/domains/host.example.com/www/postfixadmin /var/www/domains/POSTFIXADMIN_DOMAIN/www&lt;br /&gt;
&lt;br /&gt;
  mkdir -p /var/www/domains/ROUNDCUBE_DOMAIN&lt;br /&gt;
  ln -s /usr/share/webapps/roundcube /var/www/domains/ROUNDCUBE_DOMAIN/www&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;/div&gt;</summary>
		<author><name>Djhughes</name></author>
	</entry>
	<entry>
		<id>https://wiki.alpinelinux.org/w/index.php?title=ISP_Mail_Server_HowTo&amp;diff=3784</id>
		<title>ISP Mail Server HowTo</title>
		<link rel="alternate" type="text/html" href="https://wiki.alpinelinux.org/w/index.php?title=ISP_Mail_Server_HowTo&amp;diff=3784"/>
		<updated>2010-05-13T08:10:11Z</updated>

		<summary type="html">&lt;p&gt;Djhughes: minor&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== A Full Service Mail Server ==&lt;br /&gt;
&lt;br /&gt;
The goal of this document is to describe how to set up postfix, dovecot, clamav, dspam, roundecube, and postfixadmin for a full-featured &amp;quot;ISP&amp;quot; level mail server.&lt;br /&gt;
&lt;br /&gt;
The server must provide:&lt;br /&gt;
&lt;br /&gt;
* multiple virtual domains&lt;br /&gt;
* admins for each domain (to add/remove virtual accounts)&lt;br /&gt;
* Quota support per domain / account&lt;br /&gt;
* downloading email via IMAP / IMAPS / POP3 / POP3S&lt;br /&gt;
* relaying email for authenticated users with TLS or SSL (Submission / SMTPS protocol)&lt;br /&gt;
* Standard filters (virus/spam/rbl/etc)&lt;br /&gt;
* Web mail client&lt;br /&gt;
* Value Add services&lt;br /&gt;
&lt;br /&gt;
== Set up Lighttpd + PHP ==&lt;br /&gt;
&lt;br /&gt;
PostfixAdmin needs php pgpsql and imap modules, so we do it in this step.&lt;br /&gt;
&lt;br /&gt;
  apk add lighttpd php php-pgsql php-imap&lt;br /&gt;
&lt;br /&gt;
Stop and remove mini_httpd, and move ACF to lighttpd;  We are setting this up to be a multi-domain virtual web server (replace host.example.com with the actual domain):&lt;br /&gt;
&lt;br /&gt;
  mkdir -p /var/www/domains/host.example.com/www&lt;br /&gt;
  ln -s /usr/share/acf/www /var/www/domains/host.example.com/www/acf&lt;br /&gt;
&lt;br /&gt;
Edit /var/www/domains/host.example.com/index.html to put a simple redirection page:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;lt;!DOCTYPE HTML PUBLIC &amp;quot;-//W3C//DTD HTML 4.01//EN&amp;quot; &amp;quot;http://www.w3.org/TR/html4/strict.dtd&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;html lang=&amp;quot;en&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;head&amp;gt;&lt;br /&gt;
&amp;lt;meta http-equiv=&amp;quot;Content-Type&amp;quot; content=&amp;quot;text/html; charset=ISO-8859-1&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;title&amp;gt;host.example.com Redirector&amp;lt;/title&amp;gt;&lt;br /&gt;
&amp;lt;/head&amp;gt;&lt;br /&gt;
&amp;lt;body&amp;gt;&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;&amp;lt;a href=&amp;quot;/acf&amp;quot;&amp;gt;ACF&amp;lt;/a&amp;gt;&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;&amp;lt;a href=&amp;quot;/postfixadmin&amp;quot;&amp;gt;PostfixAdmin&amp;lt;/a&amp;gt;&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;&amp;lt;a href=&amp;quot;/roundcube&amp;quot;&amp;gt;Roundcube&amp;lt;/a&amp;gt;&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
&amp;lt;/body&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Edit /etc/lighttpd/mod_cgi.conf to serve haserl files by adding a &amp;quot;&amp;quot; =&amp;gt; &amp;quot;&amp;quot; cgi handler and to treat /acf/cgi-bin as a CGI directory (remove the &#039;^&#039;)&lt;br /&gt;
&lt;br /&gt;
 $HTTP[&amp;quot;url&amp;quot;] =~ &amp;quot;/cgi-bin/&amp;quot; {&lt;br /&gt;
     # disable directory listings&lt;br /&gt;
     dir-listing.activate = &amp;quot;disable&amp;quot;&lt;br /&gt;
     # only allow cgi&#039;s in this directory&lt;br /&gt;
     cgi.assign = (&lt;br /&gt;
 		&amp;quot;.pl&amp;quot;	=&amp;gt;	&amp;quot;/usr/bin/perl&amp;quot;,&lt;br /&gt;
 		&amp;quot;.cgi&amp;quot;	=&amp;gt;	&amp;quot;/usr/bin/perl&amp;quot;,&lt;br /&gt;
 		&amp;quot;&amp;quot; =&amp;gt; &amp;quot;&amp;quot;&lt;br /&gt;
 	)&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
Get a web certificate, and install it.  You have two options: 1. If you want to use a self-signed cert, you can use the instructions found at [[Generating SSL certs with ACF]] or [[Generating SSL certs with ACF 1.9]] to generate it. 2. Use the certificate created with the &#039;&#039;&#039;setup-acf&#039;&#039;&#039; command. &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Option 1:&#039;&#039;&#039;&lt;br /&gt;
If you create your own self-signed certificate, you can create the &amp;quot;server-bundle.pem&amp;quot; and the &amp;quot;ca-crt.pem&amp;quot; file with these commands:&lt;br /&gt;
&lt;br /&gt;
  openssl pkcs12 -nokeys -cacerts -in certificate.pfx  -out /etc/lighttpd/ca-crt.pem&lt;br /&gt;
  openssl pkcs12 -nodes -in certificate.pfx -out /etc/lighttpd/server-bundle.pem&lt;br /&gt;
  chown root:root /etc/lighttpd/server-bundle.pem&lt;br /&gt;
  chmod 400 /etc/lighttpd/server-bundle.pem&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Note:&#039;&#039;&#039; The server certificate &#039;&#039;and&#039;&#039; key are in the server-bundle.pem file, so it is critical that the file be read-only by user &amp;quot;root&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Option 2:&#039;&#039;&#039;&lt;br /&gt;
If you prefer to just use the default certificate created with the &#039;&#039;&#039;setup-acf&#039;&#039;&#039; command, then you will need to do the following:&lt;br /&gt;
&lt;br /&gt;
  setup-acf&lt;br /&gt;
&lt;br /&gt;
During the above process, mini_httpd will be started, if it isn&#039;t already, and a certificate will be created. Once you have completed the setup-acf steps, do the following to move the certificate files to the correct location for lighttpd to use.&lt;br /&gt;
&lt;br /&gt;
  mv /etc/ssl/mini_httpd/server.pem /etc/lighttpd/server-bundle.pem&lt;br /&gt;
  chown root:root /etc/lighttpd/server-bundle.pem&lt;br /&gt;
  chmod 400 /etc/lighttpd/server-bundle.pem&lt;br /&gt;
&lt;br /&gt;
Add these lines to /etc/lighttpd/lighttpd.conf to point to the new document root, and set it up to listen on port 443 (replace &#039;&#039;host.example.com&#039;&#039; with the actual domain and &#039;&#039;ip_address_of_server&#039;&#039; with the actual IP address):&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
simple-vhost.server-root   = &amp;quot;/var/www/domains/&amp;quot;&lt;br /&gt;
simple-vhost.default-host  = &amp;quot;/host.example.com/&amp;quot;&lt;br /&gt;
simple-vhost.document-root = &amp;quot;www/&amp;quot;&lt;br /&gt;
&lt;br /&gt;
$SERVER[&amp;quot;socket&amp;quot;] == &amp;quot;ip_address_of_server:443&amp;quot; {&lt;br /&gt;
ssl.engine    = &amp;quot;enable&amp;quot;&lt;br /&gt;
ssl.pemfile   = &amp;quot;/etc/lighttpd/server-bundle.pem&amp;quot;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
If you went with Option 1 above, then add an additional line underneath the ssl.pemfile line, so that the section appears as follows:&lt;br /&gt;
&lt;br /&gt;
  $SERVER[&amp;quot;socket&amp;quot;] == &amp;quot;ip_address_of_server:443&amp;quot; {&lt;br /&gt;
  ssl.engine    = &amp;quot;enable&amp;quot;&lt;br /&gt;
  ssl.pemfile   = &amp;quot;/etc/lighttpd/server-bundle.pem&amp;quot;&lt;br /&gt;
  ssl.ca-file   = &amp;quot;/etc/lighttpd/ca-crt.pem&amp;quot;&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
Ensure that the simple_vhosts module is loaded, as well as the cgi config scripts by uncommenting the following lines in /etc/lighttpd/lighttpd.conf&lt;br /&gt;
&lt;br /&gt;
 server.modules = (&lt;br /&gt;
     #  other modules may be listed&lt;br /&gt;
     &amp;quot;mod_simple_vhost&amp;quot;, &lt;br /&gt;
     #  other modules may be listed&lt;br /&gt;
  .&lt;br /&gt;
  .&lt;br /&gt;
  .&lt;br /&gt;
     include &amp;quot;mod_cgi.conf&amp;quot;&lt;br /&gt;
 &lt;br /&gt;
     include &amp;quot;mod_fastcgi.conf&amp;quot;&lt;br /&gt;
&lt;br /&gt;
Stop and remove mini_httpd; start lighttpd, test&lt;br /&gt;
&lt;br /&gt;
  /etc/init.d/mini_httpd stop&lt;br /&gt;
  rc-update del mini_httpd&lt;br /&gt;
  apk del mini_httpd&lt;br /&gt;
  rc-update add lighttpd&lt;br /&gt;
  /etc/init.d/lighttpd start&lt;br /&gt;
&lt;br /&gt;
At this point you should be able to see ACF being served with lighttpd (Note: this will work well with alpine 1.10. With earlier versions there will be problems.)  https://host.example.com/acf/&lt;br /&gt;
&lt;br /&gt;
== Install Postgresql ==&lt;br /&gt;
&lt;br /&gt;
Add and configure postgresql&lt;br /&gt;
&lt;br /&gt;
  apk add acf-postgresql postgresql-client&lt;br /&gt;
  /etc/init.d/postgresql setup&lt;br /&gt;
  /etc/init.d/postgresql start&lt;br /&gt;
  rc-update add postgresql&lt;br /&gt;
&lt;br /&gt;
At this point any user can connect to the sql server with &amp;quot;trust&amp;quot; mechanism.  If you want to enforce password authentication (you probably do) edit /var/lib/postgresql/8.4/data/pg_hba.conf&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
  Editme: What should we recommend?&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Create the postfix database:&lt;br /&gt;
&lt;br /&gt;
  psql -U postgres&lt;br /&gt;
   create user postfix with password &#039;******&#039;;&lt;br /&gt;
   create database postfix owner postfix;&lt;br /&gt;
   \c postfix&lt;br /&gt;
   create language plpgsql;&lt;br /&gt;
   \q&lt;br /&gt;
&lt;br /&gt;
(Of course, use your selected password where ******* is shown above.)&lt;br /&gt;
&lt;br /&gt;
== Install PostfixAdmin ==&lt;br /&gt;
&lt;br /&gt;
We are going to install the postfix admin web front-end before we install the mail server.  This just creates an interface to populate the SQL tables that postfix and dovecot will use.&lt;br /&gt;
&lt;br /&gt;
Download PostfixAdmin from Sourceforge.  When these instructions were written, 2.3 was the current release, so (replace host.example.com with the actual domain):&lt;br /&gt;
 wget http://downloads.sourceforge.net/project/postfixadmin/postfixadmin/postfixadmin_2.3.tar.gz&lt;br /&gt;
 tar zxvf postfixadmin_2.3.tar.gz&lt;br /&gt;
 mkdir -p /var/www/domains/host.example.com/www/postfixadmin&lt;br /&gt;
 mv postfixadmin-2.3/* /var/www/domains/host.example.com/www/postfixadmin&lt;br /&gt;
 rm -rf postfixadmin*&lt;br /&gt;
&lt;br /&gt;
Edit /var/www/domains/host.example.com/www/postfixadmin/config.inc.php and modify at least these lines (replace host.example.com with the actual domain):&lt;br /&gt;
&lt;br /&gt;
 $CONF[&#039;configured&#039;] = true;&lt;br /&gt;
 $CONF[&#039;setup_password&#039;] = &amp;quot;&amp;quot;;  &amp;lt;&amp;lt; Don&#039;t change this yet&lt;br /&gt;
 $CONF[&#039;database_type&#039;] = &#039;pgsql&#039;;&lt;br /&gt;
 $CONF[&#039;database_host&#039;] = &#039;localhost&#039;;&lt;br /&gt;
 $CONF[&#039;database_user&#039;] = &#039;postfix&#039;;&lt;br /&gt;
 $CONF[&#039;database_password&#039;] = &#039;*****&#039;;   &amp;lt;&amp;lt; The password you chose above&lt;br /&gt;
 $CONF[&#039;database_name&#039;] = &#039;postfix&#039;;&lt;br /&gt;
 $CONF[&#039;database_prefix&#039;] = &amp;quot;&amp;quot;;&lt;br /&gt;
 $CONF[&#039;admin_email&#039;] = &#039;you@some.email.com&#039;;  &amp;lt;&amp;lt; Your email address &lt;br /&gt;
 $CONF[&#039;encrypt&#039;] = &#039;md5crypt&#039;;&lt;br /&gt;
 $CONF[&#039;authlib_default_flavor&#039;] = &#039;md5raw&#039;;&lt;br /&gt;
 $CONF[&#039;dovecotpw&#039;] = &amp;quot;/usr/sbin/dovecotpw&amp;quot;;&lt;br /&gt;
 $CONF[&#039;domain_path&#039;] = &#039;YES&#039;;&lt;br /&gt;
 $CONF[&#039;domain_in_mailbox&#039;] = &#039;NO&#039;;&lt;br /&gt;
 $CONF[&#039;aliases&#039;] = &#039;10&#039;;                       &lt;br /&gt;
 $CONF[&#039;mailboxes&#039;] = &#039;10&#039;;&lt;br /&gt;
 $CONF[&#039;maxquota&#039;] = &#039;10&#039;;&lt;br /&gt;
 $CONF[&#039;quota&#039;] = &#039;YES&#039;;&lt;br /&gt;
 $CONF[&#039;quota_multiplier&#039;] = &#039;1024000&#039;;&lt;br /&gt;
 $CONF[&#039;vacation&#039;] = &#039;NO&#039;; &lt;br /&gt;
 $CONF[&#039;vacation_control&#039;] =&#039;NO&#039;;&lt;br /&gt;
 $CONF[&#039;vacation_control_admin&#039;] = &#039;NO&#039;;&lt;br /&gt;
 $CONF[&#039;alias_control&#039;] = &#039;YES&#039;;&lt;br /&gt;
 $CONF[&#039;alias_control_admin&#039;] = &#039;YES&#039;;&lt;br /&gt;
 $CONF[&#039;special_alias_control&#039;] = &#039;YES&#039;;&lt;br /&gt;
 $CONF[&#039;fetchmail&#039;] = &#039;NO&#039;;&lt;br /&gt;
 $CONF[&#039;user_footer_link&#039;] = &amp;quot;http://host.example.com/postfixadmin&amp;quot;;&lt;br /&gt;
 $CONF[&#039;footer_link&#039;] = &#039;http://host.example.com/postfixadmin/main.php&#039;;&lt;br /&gt;
 $CONF[&#039;create_mailbox_subdirs_prefix&#039;]=&amp;quot;&amp;quot;;  &lt;br /&gt;
 $CONF[&#039;used_quotas&#039;] = &#039;YES&#039;;   &lt;br /&gt;
 $CONF[&#039;new_quota_table&#039;] = &#039;YES&#039;;  &lt;br /&gt;
&lt;br /&gt;
You should further edit /var/www/domains/host.example.com/www/postfixadmin/config.inc.php and replace all instances of &amp;quot;change-this-to-your.domain.tld&amp;quot; with your actual mail domain. This can be done with busybox sed (replace example.com with your domain name):&lt;br /&gt;
&lt;br /&gt;
 sed -i -e &#039;s/change-this-to-your.domain.tld/example.com/g&#039; /var/www/domains/host.example.com/www/postfixadmin/config.inc.php&lt;br /&gt;
&lt;br /&gt;
Go to http://host.example.com/postfixadmin/setup.php&lt;br /&gt;
&lt;br /&gt;
Create the password hash, add it to the config.inc.php file&lt;br /&gt;
&lt;br /&gt;
Go back to http://host.example.com/postfixadmin/setup.php&lt;br /&gt;
&lt;br /&gt;
Create superadmin account.&lt;br /&gt;
&lt;br /&gt;
== Install Postfix ==&lt;br /&gt;
&lt;br /&gt;
Create a user for the virtual mail delivery, and get its uid/gid (you&#039;ll need the numeric uid/gid for postfix)&lt;br /&gt;
&lt;br /&gt;
 adduser vmail -H -D -s /bin/false&lt;br /&gt;
 grep vmail /etc/passwd&lt;br /&gt;
&lt;br /&gt;
(In examples below, we use 1006/1006 for the uid/gid)&lt;br /&gt;
&lt;br /&gt;
Create the mail directory, and assign vmail as the owner&lt;br /&gt;
 mkdir -p /var/mail/domains&lt;br /&gt;
 chown -R vmail:vmail /var/mail/domains&lt;br /&gt;
 &lt;br /&gt;
&lt;br /&gt;
Install postfix&lt;br /&gt;
&lt;br /&gt;
 apk add acf-postfix postfix-pgsql&lt;br /&gt;
&lt;br /&gt;
Edit the /etc/postfix/main.cf file. Here&#039;s an example (don&#039;t forget to replace the uid/gid):&lt;br /&gt;
&lt;br /&gt;
 myhostname=host.example.com&lt;br /&gt;
 mydomain=example.com&lt;br /&gt;
 &lt;br /&gt;
 mydestination = localhost.$mydomain, localhost&lt;br /&gt;
 mynetworks_style = subnet&lt;br /&gt;
 mynetworks = 127.0.0.0/8&lt;br /&gt;
 &lt;br /&gt;
 virtual_mailbox_domains = proxy:pgsql:/etc/postfix/sql/pgsql_virtual_domains_maps.cf&lt;br /&gt;
 virtual_alias_maps = proxy:pgsql:/etc/postfix/sql/pgsql_virtual_alias_maps.cf,&lt;br /&gt;
        proxy:pgsql:/etc/postfix/sql/pgsql_virtual_alias_domain_maps.cf,&lt;br /&gt;
        proxy:pgsql:/etc/postfix/sql/pgsql_virtual_alias_domain_catchall_maps.cf&lt;br /&gt;
 &lt;br /&gt;
 virtual_mailbox_maps = proxy:pgsql:/etc/postfix/sql/pgsql_virtual_mailbox_maps.cf,&lt;br /&gt;
        proxy:pgsql:/etc/postfix/sql/pgsql_virtual_alias_domain_mailbox_maps.cf&lt;br /&gt;
 &lt;br /&gt;
 virtual_mailbox_base = /var/mail/domains/&lt;br /&gt;
 virtual_gid_maps = static:1006&lt;br /&gt;
 virtual_uid_maps = static:1006&lt;br /&gt;
 virtual_minimum_uid = 100&lt;br /&gt;
 virtual_transport = virtual&lt;br /&gt;
 &lt;br /&gt;
 &lt;br /&gt;
 # This next command means you must create a virtual&lt;br /&gt;
 # domain for the host itself - ALL mail goes through&lt;br /&gt;
 # The virtual transport&lt;br /&gt;
 &lt;br /&gt;
 mailbox_transport = virtual&lt;br /&gt;
 local_transport = virtual&lt;br /&gt;
 local_transport_maps = $virtual_mailbox_maps&lt;br /&gt;
 &lt;br /&gt;
 smtpd_helo_required = yes&lt;br /&gt;
 disable_vrfy_command = yes&lt;br /&gt;
 message_size_limit = 10240000&lt;br /&gt;
 queue_minfree = 51200000&lt;br /&gt;
 &lt;br /&gt;
 smtpd_sender_restrictions =&lt;br /&gt;
        permit_mynetworks,&lt;br /&gt;
        reject_non_fqdn_sender,&lt;br /&gt;
        reject_unknown_sender_domain&lt;br /&gt;
 &lt;br /&gt;
 smtpd_recipient_restrictions =&lt;br /&gt;
        reject_non_fqdn_recipient,&lt;br /&gt;
        reject_unknown_recipient_domain,&lt;br /&gt;
        permit_mynetworks,&lt;br /&gt;
        permit_sasl_authenticated,&lt;br /&gt;
        reject_unauth_destination,&lt;br /&gt;
        reject_rbl_client dnsbl.sorbs.net,&lt;br /&gt;
        reject_rbl_client zen.spamhaus.org,&lt;br /&gt;
        reject_rbl_client bl.spamcop.net&lt;br /&gt;
 &lt;br /&gt;
 smtpd_data_restrictions = reject_unauth_pipelining&lt;br /&gt;
 &lt;br /&gt;
 # we will use this later - This prevents cleartext authentication&lt;br /&gt;
 # for relaying&lt;br /&gt;
 smtpd_tls_auth_only = yes&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Now we need to create a *bunch* of files so that postfix can get the delivery information out of sql. Here&#039;s a shell script to create the scripts.  Change PGPW to the password for the postfix user of the postfix SQL database.&lt;br /&gt;
&lt;br /&gt;
 cd /etc/postfix&lt;br /&gt;
 mkdir sql&lt;br /&gt;
 PGPW=&amp;quot;ChangeMe&amp;quot;&lt;br /&gt;
 &lt;br /&gt;
 cat - &amp;lt;&amp;lt;EOF &amp;gt;sql/pgsql_virtual_alias_domain_catchall_maps.cf&lt;br /&gt;
 user=postfix&lt;br /&gt;
 password = $PGPW&lt;br /&gt;
 hosts = localhost&lt;br /&gt;
 dbname = postfix&lt;br /&gt;
 query = Select goto From alias,alias_domain where alias_domain.alias_domain = &#039;%d&#039; and alias.address = &#039;@&#039; ||  alias_domain.target_domain and alias.active = true and alias_domain.active= true &lt;br /&gt;
 EOF&lt;br /&gt;
 &lt;br /&gt;
 cat - &amp;lt;&amp;lt;EOF &amp;gt;sql/pgsql_virtual_alias_domain_mailbox_maps.cf&lt;br /&gt;
 user=postfix&lt;br /&gt;
 password = $PGPW&lt;br /&gt;
 hosts = localhost&lt;br /&gt;
 dbname = postfix&lt;br /&gt;
 query = Select maildir from mailbox,alias_domain where alias_domain.alias_domain = &#039;%d&#039; and mailbox.username = &#039;%u&#039; || &#039;@&#039; || alias_domain.target_domain and mailbox.active = true and alias_domain.active&lt;br /&gt;
 EOF&lt;br /&gt;
 &lt;br /&gt;
 cat - &amp;lt;&amp;lt;EOF &amp;gt;sql/pgsql_virtual_alias_domain_maps.cf&lt;br /&gt;
 user=postfix&lt;br /&gt;
 password = $PGPW&lt;br /&gt;
 hosts = localhost&lt;br /&gt;
 dbname = postfix&lt;br /&gt;
 query = select goto from alias,alias_domain where alias_domain.alias_domain=&#039;%d&#039; and alias.address = &#039;%u&#039; || &#039;@&#039; || alias_domain.target_domain and alias.active= true and alias_domain.active= true&lt;br /&gt;
 EOF&lt;br /&gt;
 &lt;br /&gt;
 cat - &amp;lt;&amp;lt;EOF &amp;gt;sql/pgsql_virtual_alias_maps.cf&lt;br /&gt;
 user=postfix&lt;br /&gt;
 password = $PGPW&lt;br /&gt;
 hosts = localhost&lt;br /&gt;
 dbname = postfix&lt;br /&gt;
 query = Select goto From alias Where address=&#039;%s&#039; and active =&#039;1&#039;&lt;br /&gt;
 EOF&lt;br /&gt;
 &lt;br /&gt;
 cat - &amp;lt;&amp;lt;EOF &amp;gt;sql/pgsql_virtual_domains_maps.cf&lt;br /&gt;
 user=postfix&lt;br /&gt;
 password = $PGPW&lt;br /&gt;
 hosts = localhost&lt;br /&gt;
 dbname = postfix&lt;br /&gt;
 query = Select domain from domain where domain=&#039;%s&#039; and active=&#039;1&#039;&lt;br /&gt;
 EOF&lt;br /&gt;
 &lt;br /&gt;
 cat - &amp;lt;&amp;lt;EOF &amp;gt;sql/pgsql_virtual_mailbox_maps.cf&lt;br /&gt;
 user=postfix&lt;br /&gt;
 password = $PGPW&lt;br /&gt;
 hosts = localhost&lt;br /&gt;
 dbname = postfix&lt;br /&gt;
 query = Select maildir from mailbox where username=&#039;%s&#039; and active=true&lt;br /&gt;
 EOF&lt;br /&gt;
 &lt;br /&gt;
 chown -R postfix:postfix sql&lt;br /&gt;
 chmod 640 sql/*&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
At this point you should be able to start up postfix&lt;br /&gt;
 &lt;br /&gt;
 newaliases  # so postfix is happy...&lt;br /&gt;
 /etc/init.d/postfix start&lt;br /&gt;
 rc-update add postfix&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Create a domain in PostfixAdmin and test ===&lt;br /&gt;
&lt;br /&gt;
Go to http://host.example.com/postfixadmin/&lt;br /&gt;
&lt;br /&gt;
Log in using the superadmin account, create a domain for the local box (e.g. example.com), and create a user mailbox (e.g. root).&lt;br /&gt;
&lt;br /&gt;
From the machine, send a test message:&lt;br /&gt;
&lt;br /&gt;
 sendmail -t root@example.com&lt;br /&gt;
 subject: test&lt;br /&gt;
 .&lt;br /&gt;
 ^d&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
In /var/log/mail.log (or /var/log/messages, if you still have busybox syslogd running) you should see the message queued.  The message should be in /var/mail/domains/example.com/root/new&lt;br /&gt;
&lt;br /&gt;
== Install Dovecot ==&lt;br /&gt;
&lt;br /&gt;
Dovecot is the POP3/IMAP server to retrieve mail.&lt;br /&gt;
&lt;br /&gt;
As before, we install dovecot: &lt;br /&gt;
&lt;br /&gt;
 apk add acf-dovecot dovecot-pgsql&lt;br /&gt;
&lt;br /&gt;
edit /etc/dovecot/dovecot.conf&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
# Select only the protocols you wish to support - all are listed in the next line&lt;br /&gt;
protocols               =       imap imaps pop pop3s&lt;br /&gt;
log_path                =       /var/log/dovecot.log&lt;br /&gt;
info_log_path           =       /var/log/dovecot-info.log&lt;br /&gt;
disable_plaintext_auth  =       no&lt;br /&gt;
&lt;br /&gt;
# Authenticated IMAP&lt;br /&gt;
ssl                     =       yes&lt;br /&gt;
ssl_cert_file           =       /etc/lighttpd/server-bundle.pem&lt;br /&gt;
ssl_key_file            =       /etc/lighttpd/server-bundle.pem&lt;br /&gt;
auth_verbose            =       yes&lt;br /&gt;
auth_debug              =       no&lt;br /&gt;
mail_location           =       maildir:/var/mail/domains/%d/%n&lt;br /&gt;
auth default    {&lt;br /&gt;
       mechanisms = plain&lt;br /&gt;
       passdb sql {&lt;br /&gt;
               args = /etc/dovecot/dovecot-sql.conf&lt;br /&gt;
               }&lt;br /&gt;
       userdb static {&lt;br /&gt;
               args =  uid=1006 gid=1006 home=/var/mail/domains/%d/%n&lt;br /&gt;
               }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Be sure to replace the uid and gid with the appropriate values for the vmail user.&lt;br /&gt;
&lt;br /&gt;
We need a certificate for SSL/TLS authentication, so in the example above, we use the lighttpd cert. That way when the cert is renewed/replaced, Dovecot will have access to the new cert as well.  &lt;br /&gt;
&lt;br /&gt;
Create the /etc/dovecot/dovecot-sql.conf file:&lt;br /&gt;
&lt;br /&gt;
 driver = pgsql&lt;br /&gt;
 connect = host=localhost dbname=postfix user=postfix password=********&lt;br /&gt;
 password_query = select username,password from mailbox where local_part = &#039;%n&#039; and domain = &#039;%d&#039;&lt;br /&gt;
 default_pass_scheme =  MD5-CRYPT&lt;br /&gt;
&lt;br /&gt;
Again, change the password above to your postfix user password, and protect the file from prying eyes:&lt;br /&gt;
&lt;br /&gt;
 chown root:root /etc/dovecot/dovecot-sql.conf&lt;br /&gt;
 chmod 600 /etc/dovecot/dovecot-sql.conf&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Start dovecot&lt;br /&gt;
 /etc/init.d/dovecot start&lt;br /&gt;
 rc-update add dovecot&lt;br /&gt;
&lt;br /&gt;
== Testing ==&lt;br /&gt;
&lt;br /&gt;
Make sure your firewall allows in ports 25(SMTP) 110 (POP3), 995 (POP3S), 143(IMAP), 993(IMAPS), or whatever subset you support.  &lt;br /&gt;
 &lt;br /&gt;
At this point, you should be able to:&lt;br /&gt;
 * Create a new domain and add users with PostfixAdmin&lt;br /&gt;
 * Send mail to those users via SMTP to port 25&lt;br /&gt;
 * Retrieve mail using the user&#039;s full email and password (e.g. username: user@example.com  password: ChangeMe)&lt;br /&gt;
&lt;br /&gt;
== Value Add Features ==&lt;br /&gt;
&lt;br /&gt;
If you followed the guide above, you now have a functional mail server with many interconnected parts.  The features below assume that the server is already running as described above.  You should be able to add any or all of these features below to further enhance the mail service.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Virus Scanning ===&lt;br /&gt;
&lt;br /&gt;
This procedure uses clamav and the postfix content_filter mechanism to scan inbound and outbound email for viruses.  Infected emails are dropped.  Clean emails are tagged with a &amp;quot;scanned by clamav&amp;quot; header.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* Install clamav and clamsmtp:&lt;br /&gt;
 apk add acf-clamav clamsmtp&lt;br /&gt;
* Edit the /etc/clamav/clamd.conf file if desired (not necessary in most cases)&lt;br /&gt;
* Edit /etc/clamsmtpd.conf and verify the following lines&lt;br /&gt;
 OutAddress: 10026&lt;br /&gt;
 Listen: 127.0.0.1:10025                                               &lt;br /&gt;
 Header: X-Virus-Scanned: ClamAV using ClamSMTP&lt;br /&gt;
 Action: drop&lt;br /&gt;
 User: clamav                                                      &lt;br /&gt;
* Start the daemons&lt;br /&gt;
 rc-update add clamd&lt;br /&gt;
 rc-update add clamsmtpd&lt;br /&gt;
 /etc/init.d/clamd start&lt;br /&gt;
 /etc/init.d/clamsmtpd start&lt;br /&gt;
* Verify clamsmtp is listening on port 10025:&lt;br /&gt;
 netstat -anp | grep clamsmtp&lt;br /&gt;
* [http://memberwebs.com/stef/software/clamsmtp/postfix.html Following the clamsmtp instructions]&lt;br /&gt;
** edit /etc/postfix/main.cf and add:&lt;br /&gt;
 content_filter = scan:[127.0.0.1]:10025                                                      &lt;br /&gt;
** edit /etc/postfix/master.cf and add&lt;br /&gt;
 # AV scan filter (used by content_filter)&lt;br /&gt;
 scan      unix  -       -       n       -       16      smtp&lt;br /&gt;
         -o smtp_send_xforward_command=yes&lt;br /&gt;
         -o smtp_enforce_tls=no&lt;br /&gt;
 # For injecting mail back into postfix from the filter&lt;br /&gt;
 127.0.0.1:10026 inet  n -       n       -       16      smtpd&lt;br /&gt;
         -o content_filter=&lt;br /&gt;
         -o receive_override_options=no_unknown_recipient_checks,no_header_body_checks&lt;br /&gt;
         -o smtpd_helo_restrictions=&lt;br /&gt;
         -o smtpd_client_restrictions=&lt;br /&gt;
         -o smtpd_sender_restrictions=&lt;br /&gt;
         -o smtpd_recipient_restrictions=permit_mynetworks,reject&lt;br /&gt;
         -o mynetworks_style=host&lt;br /&gt;
         -o smtpd_authorized_xforward_hosts=127.0.0.0/8&lt;br /&gt;
* postfix reload&lt;br /&gt;
* Send and email into a local virtual domain - it should have the &#039;&#039;X-Virus-Scanned: ClamAV using ClamSMTP&#039;&#039; header.&lt;br /&gt;
&lt;br /&gt;
=== Relay for Authenticated Users ===&lt;br /&gt;
&lt;br /&gt;
As configured above, the mail server accepts email from the Internet, but it does not relay email.  If it is a perimeter exchanger for a protected network, then you can add the protected networks to the &#039;&#039;mynetworks&#039;&#039; configuration line in /etc/postfix/main.cf&lt;br /&gt;
&lt;br /&gt;
This configuration change allows &#039;&#039;remote&#039;&#039; users to authenticate against the mail server and relay through it.  The rules for relaying are:&lt;br /&gt;
* Only authenticated users can relay&lt;br /&gt;
* Authentication Credentials must be encrypted with TLS or SSL&lt;br /&gt;
* Allow Submission and SMTPS ports for relaying (many consumer networks block port 25 - SMTP by default)&lt;br /&gt;
The process uses the dovecot authentication mechanism (used with IMAPS) to authenticate users before they are allowed to relay through postfix.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* Edit /etc/dovecot/dovecot.conf and add teh following inside the &#039;&#039;auth default&#039;&#039; stanza:&lt;br /&gt;
 # this is for postfix SASL (authenticated users can relay through us)&lt;br /&gt;
 socket listen {&lt;br /&gt;
                client {&lt;br /&gt;
                        path    = /var/spool/postfix/private/dovecot-auth.sock&lt;br /&gt;
                        mode    = 0660&lt;br /&gt;
                        user    = postfix&lt;br /&gt;
                        group   = postfix&lt;br /&gt;
                        }&lt;br /&gt;
                }&lt;br /&gt;
        }&lt;br /&gt;
* Restart dovecot&lt;br /&gt;
 /etc/init.d/dovecot restart&lt;br /&gt;
* Edit /etc/postfix/main.cf and add:&lt;br /&gt;
 # TLS Stuff -- since we allow SASL with tls *only*, we have to set up TLS first                    &lt;br /&gt;
 &lt;br /&gt;
 smtpd_tls_cert_file = /etc/lighttpd/server-bundle.pem&lt;br /&gt;
 smtpd_tls_key_file = /etc/lighttpd/server-bundle.pem&lt;br /&gt;
 smtpd_tls_CAfile = /etc/lighttpd/ca-crt.pem&lt;br /&gt;
 # If tls_security_level is set to &amp;quot;encrypt&amp;quot;, then SMTP rejects &lt;br /&gt;
 # unencrypted email (e.g. normal mail) which is bad.&lt;br /&gt;
 # By setting it to &amp;quot;may&amp;quot; you get TLS encrypted mail from google, slashdot, and other &lt;br /&gt;
 # interesting places.  Check your logs to see who&lt;br /&gt;
 smtpd_tls_security_level = may&lt;br /&gt;
 # Log info about the negotiated encryption levels&lt;br /&gt;
 smtpd_tls_received_header = yes&lt;br /&gt;
 smtpd_tls_loglevel = 1&lt;br /&gt;
 &lt;br /&gt;
 # SASL - this allows senders to authenticiate themselves&lt;br /&gt;
 # This along with &amp;quot;permit_sasl_authenticated&amp;quot; in smtpd_recipient_restrictions allows relaying&lt;br /&gt;
 smtpd_sasl_type = dovecot&lt;br /&gt;
 smtpd_sasl_path = private/dovecot-auth.sock&lt;br /&gt;
 smtpd_sasl_auth_enable = yes&lt;br /&gt;
 smtpd_sasl_authenticated_header = yes&lt;br /&gt;
 smtpd_tls_auth_only = yes&lt;br /&gt;
* Edit /etc/postfix/master.cf and enable the submission and smtps transports.  They are probably already at the top of your  master.cf file, just commented out:&lt;br /&gt;
 submission inet n       -       n       -       -       smtpd&lt;br /&gt;
   -o smtpd_tls_security_level=encrypt&lt;br /&gt;
   -o smtpd_sasl_auth_enable=yes&lt;br /&gt;
   -o smtpd_client_restrictions=permit_sasl_authenticated,reject&lt;br /&gt;
   -o milter_macro_daemon_name=ORIGINATING&lt;br /&gt;
 smtps     inet  n       -       n       -       -       smtpd&lt;br /&gt;
   -o smtpd_tls_security_level=encrypt&lt;br /&gt;
   -o smtpd_tls_wrappermode=yes&lt;br /&gt;
   -o smtpd_sasl_auth_enable=yes&lt;br /&gt;
   -o smtpd_client_restrictions=permit_sasl_authenticated,reject&lt;br /&gt;
   -o milter_macro_daemon_name=ORIGINATING&lt;br /&gt;
*Verfiy submission and smtps are defined in /etc/services&lt;br /&gt;
 grep &amp;quot;submission\|ssmtp&amp;quot; /etc/services&lt;br /&gt;
 submission	587/tcp				# mail message submission&lt;br /&gt;
 submission	587/udp&lt;br /&gt;
 smtps		465/tcp		ssmtp		# smtp protocol over TLS/SSL&lt;br /&gt;
 smtps		465/udp		ssmtp&lt;br /&gt;
* Restart postfix&lt;br /&gt;
 postfix reload&lt;br /&gt;
&lt;br /&gt;
At this point, you should be able to set up a mail client to relay through the server with TLS (port 587) or SSL (port 465)  Note that &amp;quot;plain&amp;quot; authentication is used because the underlying link is encrypted.  For example, in Thunderbird leave &amp;quot;secure authentication&amp;quot; unchecked, and choose STARTTLS (or TLS) for the connection security.&lt;br /&gt;
&lt;br /&gt;
=== Mailbox Quotas ===&lt;br /&gt;
&lt;br /&gt;
In the default configuration, PostfixAdmin knows about quotas, but they are not enforced.   Documentation on the web mentions the [http://vda.sourceforge.net vda patch to postfix] to enforce quotas.  The only bad thing... its a &#039;&#039;patch&#039;&#039;.   Postfix and Dovecot are both conservative systems, so if the patch isn&#039;t in the upstream source, we&#039;ll assume there&#039;s a good reason.   There is a way of using quotas without patches - and it involves using dovecot&#039;s [http://wiki.dovecot.org/LDA deliver] lda for local delivery.&lt;br /&gt;
&lt;br /&gt;
Note: As of Jan 2010, the documention is confusing, with multiple versions of dovecot, PostfixAdmin, and Mysql referenced.  These instructions apply to:&lt;br /&gt;
* Postgresql 8.4.2 &lt;br /&gt;
* PostfixAdmin 2.3 &lt;br /&gt;
* Dovecot 1.2.11&lt;br /&gt;
* Postfix 2.6.5&lt;br /&gt;
&lt;br /&gt;
Presumably later versions will work the same, but if not, please update the documentation and versions above.&lt;br /&gt;
&lt;br /&gt;
* Update /etc/dovecot/dovecot.conf (old lines shown commented out):&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
# old postfix &lt;br /&gt;
#       userdb static {&lt;br /&gt;
#               args =  uid=1006 gid=1006 home=/var/mail/domains/%d/%n&lt;br /&gt;
#               }&lt;br /&gt;
&lt;br /&gt;
# new quota support:&lt;br /&gt;
        userdb prefetch {&lt;br /&gt;
                }&lt;br /&gt;
&lt;br /&gt;
        userdb sql {&lt;br /&gt;
                args = /etc/dovecot/dovecot-sql.conf&lt;br /&gt;
                }&lt;br /&gt;
&lt;br /&gt;
        socket listen {&lt;br /&gt;
                client {&lt;br /&gt;
                        path    = /var/spool/postfix/private/dovecot-auth.sock&lt;br /&gt;
                        mode    = 0660&lt;br /&gt;
                        user    = postfix&lt;br /&gt;
                        group   = postfix&lt;br /&gt;
                        }&lt;br /&gt;
                # These lines below are for the deliver lda&lt;br /&gt;
                master {&lt;br /&gt;
                        path =  /var/run/dovecot/auth-master&lt;br /&gt;
                        mode    = 0660&lt;br /&gt;
                        user    = vmail&lt;br /&gt;
                        group   = vmail&lt;br /&gt;
                        }&lt;br /&gt;
                }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
protocol imap {                                                               &lt;br /&gt;
         mail_plugins = quota imap_quota                                       &lt;br /&gt;
         }                                                                     &lt;br /&gt;
                                                                              &lt;br /&gt;
protocol pop3 {                                                               &lt;br /&gt;
         mail_plugins = quota                                                  &lt;br /&gt;
         }                                                                     &lt;br /&gt;
                                                                              &lt;br /&gt;
dict {                                                                        &lt;br /&gt;
        quotadict = pgsql:/etc/dovecot/dovecot-dict-quota.conf                &lt;br /&gt;
        }                                                                     &lt;br /&gt;
                                                                              &lt;br /&gt;
plugin {                                                                      &lt;br /&gt;
         quota = dict:user::proxy::quotadict                                   &lt;br /&gt;
         }                                                     &lt;br /&gt;
                                                              &lt;br /&gt;
protocol lda {                                                &lt;br /&gt;
   postmaster_address = postmaster@host.example.com&lt;br /&gt;
   mail_plugins = quota                                        &lt;br /&gt;
   auth_socket_path =  /var/run/dovecot/auth-master&lt;br /&gt;
   sendmail_path = /usr/sbin/sendmail&lt;br /&gt;
}                                                                            &lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
 &lt;br /&gt;
You should already have a &amp;lt;tt&amp;gt;socket-&amp;gt; listen-&amp;gt; client&amp;lt;/tt&amp;gt; section, but it is listed above to show where it goes in relationship to the &amp;lt;tt&amp;gt;socket -&amp;gt; listen -&amp;gt; master&amp;lt;/tt&amp;gt; section&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* edit &amp;lt;tt&amp;gt;/etc/dovecot/dovecot-sql.conf&amp;lt;/tt&amp;gt; and replace the user and password queries with the following (you may not have a user_query yet - add it):&lt;br /&gt;
&lt;br /&gt;
 password_query = select username as user, password, 1006 as userdb_uid, 1006 as userdb_gid, &#039;*:bytes=&#039; || quota as userdb_quota_rule from mailbox  where local_part = &#039;%n&#039; and domain = &#039;%d&#039;&lt;br /&gt;
 user_query = select &#039;/var/mail/domains/&#039; || maildir as home, 1006 as uid, 1006 as gid, &#039;*:bytes=&#039; || quota  as quota_rule from mailbox where local_part = &#039;%n&#039; and domain =&#039;%d&#039;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* create &amp;lt;tt&amp;gt;/etc/dovecot/dovecot-dict-quota.conf&amp;lt;/tt&amp;gt;&lt;br /&gt;
 connect = host=localhost dbname=postfix user=postfix password=********&lt;br /&gt;
 &lt;br /&gt;
 map {&lt;br /&gt;
         pattern = priv/quota/storage&lt;br /&gt;
         table = quota2&lt;br /&gt;
         username_field =username&lt;br /&gt;
         value_field = bytes&lt;br /&gt;
 }&lt;br /&gt;
 &lt;br /&gt;
 map {&lt;br /&gt;
        pattern= priv/quota/messages&lt;br /&gt;
        table = quota2&lt;br /&gt;
        username_field = username&lt;br /&gt;
        value_field = messages&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
Again, change the password above to your postfix user password, and protect the file from prying eyes:&lt;br /&gt;
  chown root:root /etc/dovecot/dovecot-dict-quota.conf&lt;br /&gt;
  chmod 600 /etc/dovecot/dovecot-dict-quota.conf&lt;br /&gt;
&lt;br /&gt;
Side note: [http://wiki.dovecot.org/Quota/Dict The Dovecot Quota Documentation] mentions the need for a trigger with pgsql.  This was created in the PostfixAdmin install, which is why you instantiated the pgsql language when creating the database.  If not, you will need to create the trigger, to reference the quota2 table, not the quota table mentioned in the dovecot docs.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* create a new transport for the dovecot lda.   Add the following to  /etc/postfix/master.cf:&lt;br /&gt;
 # The dovecot deliver lda&lt;br /&gt;
 dovecot   unix  -       n       n       -       -       pipe&lt;br /&gt;
   flags=DRhu user=vmail:vmail argv=/usr/libexec/dovecot/deliver -f ${sender} -d ${user}@${nexthop}&lt;br /&gt;
&lt;br /&gt;
* Edit the /etc/postfix/main.cf.  Replace &lt;br /&gt;
 virtual_transport = virtual &lt;br /&gt;
with&lt;br /&gt;
 virtual_transport = dovecot&lt;br /&gt;
 dovecot_destination_recipient_limit = 1&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;TODO&#039;&#039;&#039;  This will cause over-quota emails to bounce.   Which could be a source of backscatter.   We need a way of checking quota limits after RBL checking but before the message is accepted in the queue.&lt;br /&gt;
&lt;br /&gt;
=== WebMail (RoundCube) ===&lt;br /&gt;
&lt;br /&gt;
[http://roundcube.net/ RoundCube] is an &amp;quot;ajax /Web2.0&amp;quot; web-mail client.  These instructions are for the Alpine Linux 1.10 repository &lt;br /&gt;
&lt;br /&gt;
* Add the package and related php modules:&lt;br /&gt;
 apk add roundcubemail php-xml php-openssl php-mcrypt php-gd php-iconv&lt;br /&gt;
&lt;br /&gt;
* link the roundcube application back into the docroot&lt;br /&gt;
 ln -s /usr/share/webapps/roundcube /var/www/domains/host.example.com/www/roundcube&lt;br /&gt;
&lt;br /&gt;
* follow the instructions in /usr/share/webapps/roundcube/INSTALL:&lt;br /&gt;
 cd /usr/share/webapps/roundcube&lt;br /&gt;
 chown -R lighttpd:lighttpd temp logs&lt;br /&gt;
 &lt;br /&gt;
 su postgres&lt;br /&gt;
 createuser roundcube&lt;br /&gt;
   Shall the new role be a superuser? (y/n) n&lt;br /&gt;
   Shall the new role be allowed to create databases? (y/n) n&lt;br /&gt;
   Shall the new role be allowed to create more new roles? (y/n) y&lt;br /&gt;
 createdb -O roundcube -E UNICODE -T template0 roundcubemail&lt;br /&gt;
 psql roundcubemail&lt;br /&gt;
   roundcubemail=# ALTER USER roundcube WITH PASSWORD &#039;the_new_password&#039;;&lt;br /&gt;
   roundcubemail=# \c - roundcube&lt;br /&gt;
   roundcubemail=&amp;gt; \i /usr/share/webapps/roundcube/SQL/postgres.initial.sql&lt;br /&gt;
   roundcubemail=&amp;gt; \q&lt;br /&gt;
 exit&lt;br /&gt;
&lt;br /&gt;
* edit /etc/php/php.ini and set date.timezone to your local timezone, or to UTC&lt;br /&gt;
&lt;br /&gt;
* restart lighttpd to verify the new php libraries are used&lt;br /&gt;
 /etc/init.d/lighttpd restart&lt;br /&gt;
&lt;br /&gt;
* Point your browser to http://host.example.com/roundcube/installer&lt;br /&gt;
* Start installation&lt;br /&gt;
&lt;br /&gt;
For the specific configuration parameters in the install step:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!Property&lt;br /&gt;
!Setting&lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;enable_spellcheck&#039;&#039; ||   disabled &lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;identities_level&#039;&#039; ||  one identity with possibility to edit all params but not email address &lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;log driver&#039;&#039; || syslog &lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;sylog_id&#039;&#039; || roundcube &lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;syslog_facility&#039;&#039; || mailsubsystem &lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;db_dnsw&#039;&#039; || pgsql properties, as described above &lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;imap_host&#039;&#039; || 127.0.0.1 &lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;auto_create_user&#039;&#039; || enabled &lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;smtp_server&#039;&#039; ||  127.0.0.1&lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;smtp_port&#039;&#039; ||  25&lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;smtp_user/smtp_pass&#039;&#039; ||  enable &#039;&#039;Use Current IMAP username and password for SMTP authentication&#039;&#039;&lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;smtp_log&#039;&#039; ||  enable (optional, but gives additional log record)&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
The other items can be left at default settings, or adjusted if desired.&lt;br /&gt;
&lt;br /&gt;
* Follow the instructions in step 3 of the install to copy the files to the server&lt;br /&gt;
* You should now be able to get to roundcube at http://host.example.com/roundcube&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
After its working, the INSTALL file recommends removing the install directory.   If you want to keep the installer around later, you can simply change the ownership and permissions.  So do &#039;&#039;&#039;one&#039;&#039;&#039; of the following:&lt;br /&gt;
 cd /usr/share/webapps/roundcube&lt;br /&gt;
 rm -rf LICENSE UPGRADING INSTALL README CHANGELOG  SQL installer&lt;br /&gt;
or&lt;br /&gt;
 cd /usr/share/webapps/roundcube&lt;br /&gt;
 chown -R root:root LICENSE UPGRADING INSTALL README CHANGELOG  SQL installer&lt;br /&gt;
 chmod -R 600 LICENSE UPGRADING INSTALL README CHANGELOG SQL &lt;br /&gt;
 chmod 700 SQL installer&lt;br /&gt;
&lt;br /&gt;
==== Enable Plug-ins ====&lt;br /&gt;
&lt;br /&gt;
RoundCube has various useful plug-ins, which could be found in &#039;&#039;/usr/share/webapps/roundcube/plugins&#039;&#039; directory. For example you may want to enable &#039;&#039;password&#039;&#039; plug-in to let users change their passwords directly from RoundCube using an extra Password Tab added to User Settings.&lt;br /&gt;
&lt;br /&gt;
* Grant limited permissions for &#039;&#039;roundcube&#039;&#039; database role &lt;br /&gt;
 psql -U postgres postfix&lt;br /&gt;
   postfix=# GRANT UPDATE (password,modified) ON mailbox TO roundcube;&lt;br /&gt;
   postfix=# GRANT SELECT (username) ON mailbox TO roundcube;&lt;br /&gt;
   postfix=# GRANT INSERT ON log TO roundcube;&lt;br /&gt;
   postfix=# \q&lt;br /&gt;
&lt;br /&gt;
* Setup &#039;&#039;password&#039;&#039; plug-in parameters in &#039;&#039;/usr/share/webapps/roundcube/plugins/password/config.inc.php&#039;&#039;&lt;br /&gt;
 mv /usr/share/webapps/roundcube/plugins/password/config.inc.php.dist /usr/share/webapps/roundcube/plugins/password/config.inc.php&lt;br /&gt;
 vi /usr/share/webapps/roundcube/plugins/password/config.inc.php&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
$rcmail_config[&#039;password_minimum_length&#039;] = 7;&lt;br /&gt;
$rcmail_config[&#039;password_require_nonalpha&#039;] = true;&lt;br /&gt;
...&lt;br /&gt;
$rcmail_config[&#039;password_db_dsn&#039;] = &#039;pgsql://roundcube:&amp;lt;roundcube_password&amp;gt;@localhost/postfix&#039;;&lt;br /&gt;
...&lt;br /&gt;
$rcmail_config[&#039;password_query&#039;] = &amp;quot;UPDATE mailbox set password = %c, modified = NOW() where username = %u; INSERT INTO log (timestamp,username,domain,action,data) VALUES (NOW(),%u || &#039; (&#039; || %h || &#039;)&#039;,%d,&#039;edit_password&#039;,%u)&amp;quot;;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* Enable &#039;&#039;password&#039;&#039; plug-in&lt;br /&gt;
 vi /usr/share/webapps/roundcube/config/main.inc.php&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
...&lt;br /&gt;
$rcmail_config[&#039;plugins&#039;] = array(&#039;password&#039;);&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== OpenLDAP based Address Book ===&lt;br /&gt;
&lt;br /&gt;
This OpenLDAP configuration uses the SQL backend, which represents information stored in PostgreSQL as an LDAP subtree for Address Book functionality for email lookups, user authentication or even &lt;br /&gt;
replication account information between sites. This procedure uses some metainformation to translate LDAP queries to SQL queries, leaving relational schema untouched, which allows SQL and LDAP &lt;br /&gt;
applications to inter-operate without replication, and exchange data as needed. The SQL backend uses UnixODBC to connect to PostgresSQL. &lt;br /&gt;
&lt;br /&gt;
* Install OpenLDAP and ODBC&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
apk add openldap libldap openldap-back-sql php-ldap unixodbc psqlodbc ca-certificates&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Note&#039;&#039;&#039;: The psqlodbc package is currently unavailable&lt;br /&gt;
&lt;br /&gt;
* Update &amp;quot;postfix&amp;quot; database (it will add &#039;id&#039; columns to mailbox and domain tables, also will create tables and views to represent LDAP metainformation)&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Note&#039;&#039;&#039;: These instructions are for example domain example.com. So make sure you replaced all entries of &#039;example&#039; and &#039;com&#039; according to your domain name parts.&lt;br /&gt;
&lt;br /&gt;
Put the following into a new file called &#039;&#039;&#039;script&#039;&#039;&#039;:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
ALTER TABLE domain ADD COLUMN id SERIAL; &lt;br /&gt;
ALTER TABLE mailbox ADD COLUMN id SERIAL; &lt;br /&gt;
&lt;br /&gt;
CREATE TABLE ldap_entry_objclasses (&lt;br /&gt;
    entry_id integer NOT NULL,&lt;br /&gt;
    oc_name character varying(64)&lt;br /&gt;
);&lt;br /&gt;
&lt;br /&gt;
CREATE TABLE ldap_oc_mappings (&lt;br /&gt;
    name character varying(64) NOT NULL,&lt;br /&gt;
    keytbl character varying(64) NOT NULL,&lt;br /&gt;
    keycol character varying(64) NOT NULL,&lt;br /&gt;
    create_proc character varying(255),&lt;br /&gt;
    delete_proc character varying(255),&lt;br /&gt;
    expect_return integer NOT NULL&lt;br /&gt;
);&lt;br /&gt;
&lt;br /&gt;
ALTER TABLE ldap_oc_mappings ADD COLUMN id SERIAL;&lt;br /&gt;
ALTER TABLE ldap_oc_mappings ADD PRIMARY KEY (id);&lt;br /&gt;
&lt;br /&gt;
CREATE TABLE ldap_attr_mappings (&lt;br /&gt;
    oc_map_id integer NOT NULL REFERENCES ldap_oc_mappings(id),&lt;br /&gt;
    name character varying(255) NOT NULL,&lt;br /&gt;
    sel_expr character varying(255) NOT NULL,&lt;br /&gt;
    sel_expr_u character varying(255),&lt;br /&gt;
    from_tbls character varying(255) NOT NULL,&lt;br /&gt;
    join_where character varying(255),&lt;br /&gt;
    add_proc character varying(255),&lt;br /&gt;
    delete_proc character varying(255),&lt;br /&gt;
    param_order integer NOT NULL,&lt;br /&gt;
    expect_return integer NOT NULL&lt;br /&gt;
);&lt;br /&gt;
&lt;br /&gt;
ALTER TABLE ldap_attr_mappings ADD COLUMN id SERIAL;&lt;br /&gt;
ALTER TABLE ldap_attr_mappings ADD PRIMARY KEY (id);&lt;br /&gt;
&lt;br /&gt;
CREATE VIEW ldap_dcs AS&lt;br /&gt;
    ((SELECT (domain.id + 100000) AS id,&lt;br /&gt;
            (&#039;dc=&#039;::text || replace((domain.domain)::text, &#039;.&#039;::text, &#039;,dc=&#039;::text)) AS dn,&lt;br /&gt;
            1 AS oc_map_id,&lt;br /&gt;
            100000 AS parent,&lt;br /&gt;
            0 AS keyval,&lt;br /&gt;
            domain.domain&lt;br /&gt;
     FROM domain&lt;br /&gt;
     WHERE domain.domain &amp;lt;&amp;gt; &#039;ALL&#039;)&lt;br /&gt;
      UNION&lt;br /&gt;
     (SELECT 100000 AS id,&lt;br /&gt;
           (&#039;dc=&#039; || regexp_replace((domain.domain)::text, &#039;.*\\.&#039;, &#039;&#039;::text)) AS dn,&lt;br /&gt;
           1 AS oc_map_id,&lt;br /&gt;
           0 AS parent,&lt;br /&gt;
           0 AS keyval,&lt;br /&gt;
           (regexp_replace((domain.domain)::text, &#039;.*\\.&#039;, &#039;&#039;::text)) AS domain&lt;br /&gt;
      FROM domain&lt;br /&gt;
      WHERE domain.domain &amp;lt;&amp;gt; &#039;ALL&#039;&lt;br /&gt;
      LIMIT 1));&lt;br /&gt;
&lt;br /&gt;
CREATE VIEW ldap_entries AS&lt;br /&gt;
    SELECT mailbox.id,&lt;br /&gt;
    (((&#039;cn=&#039;::text || initcap(replace(split_part((mailbox.username)::text, &#039;@&#039;::text, 1), &#039;.&#039;::text, &#039; &#039;::text))) || &#039;,dc=&#039;::text) ||&lt;br /&gt;
             replace(regexp_replace((mailbox.username)::text, &#039;.*@&#039;, &#039;&#039;::text), &#039;.&#039;::text, &#039;,dc=&#039;::text)) AS dn,&lt;br /&gt;
          1 AS oc_map_id,&lt;br /&gt;
          (SELECT ldap_dcs.id&lt;br /&gt;
           FROM ldap_dcs&lt;br /&gt;
           WHERE ((ldap_dcs.domain)::text = (mailbox.domain)::text)) AS parent,&lt;br /&gt;
           mailbox.id AS keyval&lt;br /&gt;
           FROM mailbox&lt;br /&gt;
           UNION&lt;br /&gt;
           SELECT ldap_dcs.id,&lt;br /&gt;
                  ldap_dcs.dn,&lt;br /&gt;
                  ldap_dcs.oc_map_id,&lt;br /&gt;
                  ldap_dcs.parent,&lt;br /&gt;
                  ldap_dcs.keyval&lt;br /&gt;
           FROM ldap_dcs;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Finally, execute the commands in the file with:&lt;br /&gt;
 cat script | psql -U postfix postfix&lt;br /&gt;
 rm script&lt;br /&gt;
&lt;br /&gt;
* Fill out LDAP tables according to following example (make sure to separate values with TABs):&lt;br /&gt;
&lt;br /&gt;
Put the following into a new file called &#039;&#039;&#039;script&#039;&#039;&#039;:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
COPY ldap_oc_mappings (id, name, keytbl, keycol, create_proc, delete_proc, expect_return) FROM stdin;&lt;br /&gt;
1	exampleBox	mailbox	id	\N	\N	1&lt;br /&gt;
\.&lt;br /&gt;
COPY ldap_attr_mappings (id, oc_map_id, name, sel_expr, sel_expr_u, from_tbls, join_where, add_proc, delete_proc, param_order, expect_return) FROM stdin;&lt;br /&gt;
1	1	displayName	mailbox.name	\N	mailbox	\N	\N	\N	3	0&lt;br /&gt;
2	1	mail	mailbox.username	\N	mailbox	\N	\N	\N	3	0&lt;br /&gt;
3	1	cn	mailbox.name	\N	mailbox	\N	\N	\N	3	0&lt;br /&gt;
4	1	userPassword	&#039;{CRYPT}&#039;||mailbox.password	\N	mailbox	\N	\N	\N	3	0&lt;br /&gt;
\.&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Finally, execute the commands in the file with:&lt;br /&gt;
 cat script | psql -U postfix postfix&lt;br /&gt;
 rm script&lt;br /&gt;
&lt;br /&gt;
* Check that &amp;quot;ldap_dcs&amp;quot; view looks something like this:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
echo &#039;select * from ldap_dcs&#039; | psql -U postgres postfix&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
   id   |             dn              | oc_map_id | parent | keyval |       domain       &lt;br /&gt;
--------+-----------------------------+-----------+--------+--------+--------------------&lt;br /&gt;
 100000 | dc=com                      |         1 |      0 |      0 | com&lt;br /&gt;
 100001 | dc=example,dc=com           |         1 | 100000 |      0 | example.com&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* Check that &amp;quot;ldap_entries&amp;quot; view looks something like this:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
echo &#039;select * from ldap_entries&#039; | psql -U postgres postfix&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
   id   |                          dn                           | oc_map_id | parent | keyval &lt;br /&gt;
--------+-------------------------------------------------------+-----------+--------+--------&lt;br /&gt;
    1   | cn=address1,dc=example,dc=com                         |         1 | 100001 |    1&lt;br /&gt;
...&lt;br /&gt;
   123  | cn=address123,dc=example,dc=com                       |         1 | 100001 |    1&lt;br /&gt;
 100000 | dc=com                                                |         1 |      0 |    0&lt;br /&gt;
 100001 | dc=example,dc=com                                     |         1 | 100000 |    0&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* Configure ODBC parameters&lt;br /&gt;
&lt;br /&gt;
Edit /etc/odbc.ini:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
[PostgreSQL]&lt;br /&gt;
Description             = Connection to Postgres&lt;br /&gt;
Driver                  = PostgreSQL&lt;br /&gt;
Trace                   = Yes&lt;br /&gt;
TraceFile               = sql.log&lt;br /&gt;
Database                = postfix&lt;br /&gt;
Servername              = 127.0.0.1&lt;br /&gt;
UserName                =&lt;br /&gt;
Password                =&lt;br /&gt;
Port                    = 5432&lt;br /&gt;
Protocol                = 6.4&lt;br /&gt;
ReadOnly                = No&lt;br /&gt;
RowVersining            = No&lt;br /&gt;
ShowSystemTables        = No&lt;br /&gt;
ShowOidColumn           = No&lt;br /&gt;
FakeOidIndex            = No&lt;br /&gt;
ConnSettings            =&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Edit /etc/odbcinst.ini:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
[PostgreSQL]&lt;br /&gt;
Description     = PostgreSQL driver for Linux&lt;br /&gt;
Driver          = /usr/lib/psqlodbcw.so&lt;br /&gt;
Setup           = /usr/lib/libodbcpsqlS.so&lt;br /&gt;
FileUsage       = 1&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* Test ODBC connection&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
echo &amp;quot;select * from domain;&amp;quot; | isql PostgreSQL postgres&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* Provide permission to certificate for LDAP server&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
chown ldap /etc/lighttpd/server-bundle.pem&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* Edit LDAP schema&lt;br /&gt;
&lt;br /&gt;
Edit /etc/openldap/schema/example.com.schema:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
attributetype ( 0.9.2342.19200300.100.1.3&lt;br /&gt;
	NAME ( &#039;mail&#039; &#039;rfc822Mailbox&#039; )&lt;br /&gt;
	DESC &#039;RFC1274: RFC822 Mailbox&#039;&lt;br /&gt;
        EQUALITY caseIgnoreIA5Match&lt;br /&gt;
        SUBSTR caseIgnoreIA5SubstringsMatch&lt;br /&gt;
        SYNTAX 1.3.6.1.4.1.1466.115.121.1.26{256} )&lt;br /&gt;
&lt;br /&gt;
attributetype ( 2.16.840.1.113730.3.1.241&lt;br /&gt;
	NAME &#039;displayName&#039;&lt;br /&gt;
	DESC &#039;RFC2798: preferred name to be used when displaying entries&#039;&lt;br /&gt;
	EQUALITY caseIgnoreMatch&lt;br /&gt;
	SUBSTR caseIgnoreSubstringsMatch&lt;br /&gt;
	SYNTAX 1.3.6.1.4.1.1466.115.121.1.15&lt;br /&gt;
	SINGLE-VALUE )&lt;br /&gt;
&lt;br /&gt;
objectclass   ( 2.16.840.1.113730.3.2.2&lt;br /&gt;
        NAME &#039;exampleBox&#039;&lt;br /&gt;
	DESC &#039;example.com mailbox&#039;&lt;br /&gt;
	MUST ( displayName $ mail $ userPassword )&lt;br /&gt;
	)&lt;br /&gt;
&lt;br /&gt;
# RFC 1274 + RFC 2247&lt;br /&gt;
attributetype ( 0.9.2342.19200300.100.1.25&lt;br /&gt;
        NAME ( &#039;dc&#039; &#039;domainComponent&#039; )&lt;br /&gt;
        DESC &#039;RFC1274/2247: domain component&#039;&lt;br /&gt;
        EQUALITY caseIgnoreIA5Match&lt;br /&gt;
        SUBSTR caseIgnoreIA5SubstringsMatch&lt;br /&gt;
        SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 SINGLE-VALUE )&lt;br /&gt;
&lt;br /&gt;
attributetype ( 2.5.4.46 NAME &#039;dnQualifier&#039;&lt;br /&gt;
        DESC &#039;RFC2256: DN qualifier&#039;&lt;br /&gt;
        EQUALITY caseIgnoreMatch&lt;br /&gt;
        ORDERING caseIgnoreOrderingMatch&lt;br /&gt;
        SUBSTR caseIgnoreSubstringsMatch&lt;br /&gt;
        SYNTAX 1.3.6.1.4.1.1466.115.121.1.44 )&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* Configure LDAP server&lt;br /&gt;
&lt;br /&gt;
Edit /etc/openldap/slapd.conf:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
include         /etc/openldap/schema/example.com.schema&lt;br /&gt;
pidfile         /var/run/openldap/slapd.pid&lt;br /&gt;
argsfile        /var/run/openldap/slapd.args&lt;br /&gt;
&lt;br /&gt;
TLSCipherSuite HIGH&lt;br /&gt;
TLSCACertificateFile /etc/lighttpd/ca-crt.pem&lt;br /&gt;
TLSCertificateFile /etc/lighttpd/server-bundle.pem&lt;br /&gt;
TLSCertificateKeyFile /etc/lighttpd/server-bundle.pem&lt;br /&gt;
TLSVerifyClient never &lt;br /&gt;
&lt;br /&gt;
# This is needed for proper representation of MD5-CRYPT format stored in database&lt;br /&gt;
#  see more details in http://strugglers.net/~andy/blog/2010/01/23/openldap-and-md5crypt/&lt;br /&gt;
password-hash  {CRYPT}&lt;br /&gt;
password-crypt-salt-format &amp;quot;$1$%.8s&amp;quot;&lt;br /&gt;
&lt;br /&gt;
loglevel        stats&lt;br /&gt;
moduleload	/usr/lib/openldap/back_sql.so&lt;br /&gt;
sizelimit 3000&lt;br /&gt;
&lt;br /&gt;
database        sql&lt;br /&gt;
&lt;br /&gt;
dbname		PostgreSQL&lt;br /&gt;
dbuser		postfix&lt;br /&gt;
dbpasswd	*****&lt;br /&gt;
&lt;br /&gt;
suffix          &amp;quot;dc=example,dc=com&amp;quot;&lt;br /&gt;
&lt;br /&gt;
upper_func      &amp;quot;upper&amp;quot;&lt;br /&gt;
strcast_func    &amp;quot;text&amp;quot;&lt;br /&gt;
concat_pattern  &amp;quot;?||?&amp;quot;&lt;br /&gt;
has_ldapinfo_dn_ru      no&lt;br /&gt;
lastmod         off&lt;br /&gt;
&lt;br /&gt;
access to attrs=userPassword by * auth&lt;br /&gt;
&lt;br /&gt;
access to * by peername.ip=127.0.0.1 read&lt;br /&gt;
#           by peername.ip=&amp;lt;IP&amp;gt;%&amp;lt;netmask&amp;gt; read&lt;br /&gt;
#           by peername.ip=&amp;lt;IP&amp;gt; read&lt;br /&gt;
	    by users read&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* Set permissions for slapd.conf&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
chown ldap:ldap /etc/openldap/slapd.conf&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* Configure startup parameters to make sure that LDAP server start AFTER PostgreSQL and listens on localhost with clear text and public IP with SSL&lt;br /&gt;
&lt;br /&gt;
Edit /etc/conf.d/slapd:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
rc_need=&amp;quot;postgresql&amp;quot; &lt;br /&gt;
OPTS=&amp;quot;-h &#039;ldaps:// ldap://127.0.0.1&#039;&amp;quot;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* Start LDAP server&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
rc-update add slapd default&lt;br /&gt;
/etc/init.d/slapd start&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* Configure LDAP client utilities&lt;br /&gt;
&lt;br /&gt;
Edit /etc/openldap/ldap.conf&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
BASE	dc=example,dc=com&lt;br /&gt;
URI	ldaps://host.example.com&lt;br /&gt;
&lt;br /&gt;
TLS_CACERT /etc/lighttpd/ca-crt.pem&lt;br /&gt;
TLS_CERT /etc/lighttpd/server-bundle.pem&lt;br /&gt;
TLS_KEY /etc/lighttpd/server-bundle.pem&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* Test LDAP server&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
ldapsearch -z 3&lt;br /&gt;
ldapsearch -z 3 -x -W -D cn=admin,dc=example,dc=com&lt;br /&gt;
ldapsearch -z 3 -x -W -D cn=address1,dc=example,dc=com&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* Configure RoundCube webmail for email lookups&lt;br /&gt;
&lt;br /&gt;
In order to enable php-ldap support you need to restart lighttpd server&lt;br /&gt;
&lt;br /&gt;
 /etc/init.d/lighttpd restart&lt;br /&gt;
&lt;br /&gt;
Edit /usr/share/webapps/roundcube/config/main.inc.php:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
$rcmail_config[&#039;ldap_debug&#039;] = false;&lt;br /&gt;
...&lt;br /&gt;
$rcmail_config[&#039;address_book_type&#039;] = &#039;sql&#039;;&lt;br /&gt;
&lt;br /&gt;
$rcmail_config[&#039;ldap_public&#039;][&#039;example.com&#039;] = array(&lt;br /&gt;
  &#039;name&#039;          =&amp;gt; &#039;example.com&#039;,&lt;br /&gt;
  &#039;hosts&#039;         =&amp;gt; array(&#039;127.0.0.1&#039;),&lt;br /&gt;
  &#039;port&#039;          =&amp;gt; 389,&lt;br /&gt;
  &#039;use_tls&#039;         =&amp;gt; false,&lt;br /&gt;
  &#039;user_specific&#039; =&amp;gt; false,&lt;br /&gt;
  &#039;base_dn&#039;       =&amp;gt; &#039;dc=example,dc=com&#039;,&lt;br /&gt;
  &#039;bind_dn&#039;       =&amp;gt; &#039;&#039;,&lt;br /&gt;
  &#039;bind_pass&#039;     =&amp;gt; &#039;&#039;,&lt;br /&gt;
  &#039;writable&#039;      =&amp;gt; false,&lt;br /&gt;
  &#039;LDAP_Object_Classes&#039; =&amp;gt; array(&amp;quot;top&amp;quot;, &amp;quot;exampleBox&amp;quot;),&lt;br /&gt;
  &#039;required_fields&#039;     =&amp;gt; array(&amp;quot;cn&amp;quot;, &amp;quot;sn&amp;quot;, &amp;quot;mail&amp;quot;),&lt;br /&gt;
  &#039;LDAP_rdn&#039;      =&amp;gt; &#039;mail&#039;,&lt;br /&gt;
  &#039;ldap_version&#039;  =&amp;gt; 3,&lt;br /&gt;
  &#039;search_fields&#039; =&amp;gt; array(&#039;mail&#039;, &#039;cn&#039;, &#039;sn&#039;, &#039;givenName&#039;),&lt;br /&gt;
  &#039;name_field&#039;    =&amp;gt; &#039;cn&#039;,&lt;br /&gt;
  &#039;email_field&#039;   =&amp;gt; &#039;mail&#039;,&lt;br /&gt;
  &#039;surname_field&#039; =&amp;gt; &#039;sn&#039;,&lt;br /&gt;
  &#039;firstname_field&#039; =&amp;gt; &#039;gn&#039;,&lt;br /&gt;
  &#039;sort&#039;          =&amp;gt; &#039;cn&#039;,&lt;br /&gt;
  &#039;scope&#039;         =&amp;gt; &#039;sub&#039;,&lt;br /&gt;
  &#039;filter&#039;        =&amp;gt; &#039;(objectClass=*)&#039;, // Construct here any filter you need&lt;br /&gt;
  &#039;fuzzy_search&#039;  =&amp;gt; true);&lt;br /&gt;
&lt;br /&gt;
$rcmail_config[&#039;autocomplete_addressbooks&#039;] = array(&#039;sql&#039;,&#039;example.com&#039;);&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* Fix PostfixAdmin to work with the new table definition&lt;br /&gt;
&lt;br /&gt;
Edit /var/www/domains/example.com/www/list-domain.php. Replace the line:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
   SELECT domain.* , COUNT( DISTINCT mailbox.username ) AS mailbox_count&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
With the lines:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
   SELECT domain.domain, domain.description, domain.aliases, domain.mailboxes,&lt;br /&gt;
   domain.maxquota, domain.quota, domain.transport, domain.backupmx, domain.created,&lt;br /&gt;
   domain.modified, domain.active, COUNT( DISTINCT mailbox.username ) AS mailbox_count&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== log rotation ==&lt;br /&gt;
&lt;br /&gt;
Ensure the busybox cron service is started and is configured to auto-start:&lt;br /&gt;
&lt;br /&gt;
 /etc/init.d/cron start&lt;br /&gt;
 rc-update add cron default&lt;br /&gt;
&lt;br /&gt;
Add log rotate:&lt;br /&gt;
&lt;br /&gt;
 apk add logrotate&lt;br /&gt;
&lt;br /&gt;
Edit &#039;&#039;/etc/logrotate.conf&#039;&#039; as desired, but the defaults should be sufficient for most people.&lt;br /&gt;
&lt;br /&gt;
== Optional: Configure Web Server Virtual Domains ==&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Note:&#039;&#039;&#039; These steps can be done &#039;&#039;in addition to&#039;&#039; the default lighttpd configuration above, which allows you to access the ACF, PostfixAdmin and Roundcube interfaces as subfolders of one web service.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Note:&#039;&#039;&#039; If you provide SSL access for multiple domain site you may need to follow http://redmine.lighttpd.net/projects/lighttpd/wiki/Docs:SSL#SSL-on-multiple-domains in order to provide multi-domain certificates. If you would like to redirect hosts to their secure equivalents use the following instructions http://redmine.lighttpd.net/projects/lighttpd/wiki/HowToRedirectHttpToHttps.&lt;br /&gt;
&lt;br /&gt;
This server hosts three separate web applications, and these can be handled as three &#039;&#039;different&#039;&#039; virtual domains on the same web server. They will be distinguished by their DNS names, so you can choose domains for the three separate services (or at least the ones you want to publish):&lt;br /&gt;
&lt;br /&gt;
* ACF - Alpine Configuration Framework for managing the server&lt;br /&gt;
* PostfixAdmin - for managing the postfix installation&lt;br /&gt;
* RoundCube - for accessing individual mailboxes&lt;br /&gt;
&lt;br /&gt;
Choose three different domains (from here on known as ACF_DOMAIN, POSTFIXADMIN_DOMAIN, and ROUNDCUBE_DOMAIN) and configure DNS for all three to point to the IP address of your host. These should be DNS &#039;&#039;&#039;A&#039;&#039;&#039; records.&lt;br /&gt;
&lt;br /&gt;
Then, configure lighttpd to handle the three separate domains by editing /etc/lighttpd/lighttpd.conf:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 $HTTP[&amp;quot;host&amp;quot;] == &amp;quot;ACF_DOMAIN&amp;quot; {&lt;br /&gt;
	simple-vhost.server-root   = &amp;quot;/var/www/domains/&amp;quot;&lt;br /&gt;
	simple-vhost.default-host  = &amp;quot;/ACF_DOMAIN/&amp;quot;&lt;br /&gt;
	simple-vhost.document-root = &amp;quot;www/&amp;quot;&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
 $HTTP[&amp;quot;host&amp;quot;] == &amp;quot;POSTFIXADMIN_DOMAIN&amp;quot; {&lt;br /&gt;
	simple-vhost.server-root   = &amp;quot;/var/www/domains/&amp;quot;&lt;br /&gt;
	simple-vhost.default-host  = &amp;quot;/POSTFIXADMIN_DOMAIN/&amp;quot;&lt;br /&gt;
	simple-vhost.document-root = &amp;quot;www/&amp;quot;&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
 $HTTP[&amp;quot;host&amp;quot;] == &amp;quot;ROUNDCUBE_DOMAIN&amp;quot; {&lt;br /&gt;
	simple-vhost.server-root   = &amp;quot;/var/www/domains/&amp;quot;&lt;br /&gt;
	simple-vhost.default-host  = &amp;quot;/ROUNDCUBE_DOMAIN/&amp;quot;&lt;br /&gt;
	simple-vhost.document-root = &amp;quot;www/&amp;quot;&lt;br /&gt;
 }&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
And, then link the appropriate www directories.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  mkdir -p /var/www/domains/ACF_DOMAIN&lt;br /&gt;
  ln -s /usr/share/acf/www /var/www/domains/ACF_DOMAIN/www&lt;br /&gt;
&lt;br /&gt;
  mkdir -p /var/www/domains/POSTFIXADMIN_DOMAIN&lt;br /&gt;
  ln -s /var/www/domains/host.example.com/www/postfixadmin /var/www/domains/POSTFIXADMIN_DOMAIN/www&lt;br /&gt;
&lt;br /&gt;
  mkdir -p /var/www/domains/ROUNDCUBE_DOMAIN&lt;br /&gt;
  ln -s /usr/share/webapps/roundcube /var/www/domains/ROUNDCUBE_DOMAIN/www&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;/div&gt;</summary>
		<author><name>Djhughes</name></author>
	</entry>
	<entry>
		<id>https://wiki.alpinelinux.org/w/index.php?title=ISP_Mail_Server_HowTo&amp;diff=3783</id>
		<title>ISP Mail Server HowTo</title>
		<link rel="alternate" type="text/html" href="https://wiki.alpinelinux.org/w/index.php?title=ISP_Mail_Server_HowTo&amp;diff=3783"/>
		<updated>2010-05-13T03:23:25Z</updated>

		<summary type="html">&lt;p&gt;Djhughes: reorganized a bit&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== A Full Service Mail Server ==&lt;br /&gt;
&lt;br /&gt;
The goal of this document is to describe how to set up postfix, dovecot, clamav, dspam, roundecube, and postfixadmin for a full-featured &amp;quot;ISP&amp;quot; level mail server.&lt;br /&gt;
&lt;br /&gt;
The server must provide:&lt;br /&gt;
&lt;br /&gt;
* multiple virtual domains&lt;br /&gt;
* admins for each domain (to add/remove virtual accounts)&lt;br /&gt;
* Quota support per domain / account&lt;br /&gt;
* downloading email via IMAP / IMAPS / POP3 / POP3S&lt;br /&gt;
* relaying email for authenticated users with TLS or SSL (Submission / SMTPS protocol)&lt;br /&gt;
* Standard filters (virus/spam/rbl/etc)&lt;br /&gt;
* Web mail client&lt;br /&gt;
* Value Add services&lt;br /&gt;
&lt;br /&gt;
== Set up Lighttpd + PHP ==&lt;br /&gt;
&lt;br /&gt;
PostfixAdmin needs php pgpsql and imap modules, so we do it in this step.&lt;br /&gt;
&lt;br /&gt;
  apk add lighttpd php php-pgsql php-imap&lt;br /&gt;
&lt;br /&gt;
Stop and remove mini_httpd, and move ACF to lighttpd;  We are setting this up to be a multi-domain virtual web server (replace host.example.com with the actual domain):&lt;br /&gt;
&lt;br /&gt;
  mkdir -p /var/www/domains/host.example.com/www&lt;br /&gt;
  ln -s /usr/share/acf/www /var/www/domains/host.example.com/www/acf&lt;br /&gt;
&lt;br /&gt;
Edit /var/www/domains/host.example.com/index.html to put a simple redirection page:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;lt;!DOCTYPE HTML PUBLIC &amp;quot;-//W3C//DTD HTML 4.01//EN&amp;quot; &amp;quot;http://www.w3.org/TR/html4/strict.dtd&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;html lang=&amp;quot;en&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;head&amp;gt;&lt;br /&gt;
&amp;lt;meta http-equiv=&amp;quot;Content-Type&amp;quot; content=&amp;quot;text/html; charset=ISO-8859-1&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;title&amp;gt;host.example.com Redirector&amp;lt;/title&amp;gt;&lt;br /&gt;
&amp;lt;/head&amp;gt;&lt;br /&gt;
&amp;lt;body&amp;gt;&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;&amp;lt;a href=&amp;quot;/acf&amp;quot;&amp;gt;ACF&amp;lt;/a&amp;gt;&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;&amp;lt;a href=&amp;quot;/postfixadmin&amp;quot;&amp;gt;PostfixAdmin&amp;lt;/a&amp;gt;&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;&amp;lt;a href=&amp;quot;/roundcube&amp;quot;&amp;gt;Roundcube&amp;lt;/a&amp;gt;&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
&amp;lt;/body&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Edit /etc/lighttpd/mod_cgi.conf to serve haserl files by adding a &amp;quot;&amp;quot; =&amp;gt; &amp;quot;&amp;quot; cgi handler and to treat /acf/cgi-bin as a CGI directory (remove the &#039;^&#039;)&lt;br /&gt;
&lt;br /&gt;
 $HTTP[&amp;quot;url&amp;quot;] =~ &amp;quot;/cgi-bin/&amp;quot; {&lt;br /&gt;
     # disable directory listings&lt;br /&gt;
     dir-listing.activate = &amp;quot;disable&amp;quot;&lt;br /&gt;
     # only allow cgi&#039;s in this directory&lt;br /&gt;
     cgi.assign = (&lt;br /&gt;
 		&amp;quot;.pl&amp;quot;	=&amp;gt;	&amp;quot;/usr/bin/perl&amp;quot;,&lt;br /&gt;
 		&amp;quot;.cgi&amp;quot;	=&amp;gt;	&amp;quot;/usr/bin/perl&amp;quot;,&lt;br /&gt;
 		&amp;quot;&amp;quot; =&amp;gt; &amp;quot;&amp;quot;&lt;br /&gt;
 	)&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
Get a web certificate, and install it.  You have two options: 1. If you want to use a self-signed cert, you can use the instructions found at [[Generating SSL certs with ACF]] or [[Generating SSL certs with ACF 1.9]] to generate it. 2. Use the certificate created with the &#039;&#039;&#039;setup-acf&#039;&#039;&#039; command. &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Option 1:&#039;&#039;&#039;&lt;br /&gt;
If you create your own self-signed certificate, you can create the &amp;quot;server-bundle.pem&amp;quot; and the &amp;quot;ca-crt.pem&amp;quot; file with these commands:&lt;br /&gt;
&lt;br /&gt;
  openssl pkcs12 -nokeys -cacerts -in certificate.pfx  -out /etc/lighttpd/ca-crt.pem&lt;br /&gt;
  openssl pkcs12 -nodes -in certificate.pfx -out /etc/lighttpd/server-bundle.pem&lt;br /&gt;
  chown root:root /etc/lighttpd/server-bundle.pem&lt;br /&gt;
  chmod 400 /etc/lighttpd/server-bundle.pem&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Note:&#039;&#039;&#039; The server certificate &#039;&#039;and&#039;&#039; key are in the server-bundle.pem file, so it is critical that the file be read-only by user &amp;quot;root&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Option 2:&#039;&#039;&#039;&lt;br /&gt;
If you prefer to just use the default certificate created with the &#039;&#039;&#039;setup-acf&#039;&#039;&#039; command, then you will need to do the following:&lt;br /&gt;
&lt;br /&gt;
  setup-acf&lt;br /&gt;
&lt;br /&gt;
During the above process, mini_httpd will be started, if it isn&#039;t already, and a certificate will be created. Once you have completed the setup-acf steps, do the following to move the certificate files to the correct location for lighttpd to use.&lt;br /&gt;
&lt;br /&gt;
  mv /etc/ssl/mini_httpd/server.pem /etc/lighttpd/server-bundle.pem&lt;br /&gt;
  chown root:root /etc/lighttpd/server-bundle.pem&lt;br /&gt;
  chmod 400 /etc/lighttpd/server-bundle.pem&lt;br /&gt;
&lt;br /&gt;
Add these lines to /etc/lighttpd/lighttpd.conf to point to the new document root, and set it up to listen on port 443 (replace &#039;&#039;host.example.com&#039;&#039; with the actual domain and &#039;&#039;ip_address_of_server&#039;&#039; with the actual IP address):&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
simple-vhost.server-root   = &amp;quot;/var/www/domains/&amp;quot;&lt;br /&gt;
simple-vhost.default-host  = &amp;quot;/host.example.com/&amp;quot;&lt;br /&gt;
simple-vhost.document-root = &amp;quot;www/&amp;quot;&lt;br /&gt;
&lt;br /&gt;
$SERVER[&amp;quot;socket&amp;quot;] == &amp;quot;ip_address_of_server:443&amp;quot; {&lt;br /&gt;
ssl.engine    = &amp;quot;enable&amp;quot;&lt;br /&gt;
ssl.pemfile   = &amp;quot;/etc/lighttpd/server-bundle.pem&amp;quot;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
If you went with Option 1 above, then add an additional line underneath the ssl.pemfile line, so that the section appears as follows:&lt;br /&gt;
&lt;br /&gt;
  $SERVER[&amp;quot;socket&amp;quot;] == &amp;quot;ip_address_of_server:443&amp;quot; {&lt;br /&gt;
  ssl.engine    = &amp;quot;enable&amp;quot;&lt;br /&gt;
  ssl.pemfile   = &amp;quot;/etc/lighttpd/server-bundle.pem&amp;quot;&lt;br /&gt;
  ssl.ca-file   = &amp;quot;/etc/lighttpd/ca-crt.pem&amp;quot;&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
Ensure that the simple_vhosts module is loaded, as well as the cgi config scripts by uncommenting the following lines in /etc/lighttpd/lighttpd.conf&lt;br /&gt;
&lt;br /&gt;
 server.modules = (&lt;br /&gt;
     #  other modules may be listed&lt;br /&gt;
     &amp;quot;mod_simple_vhost&amp;quot;, &lt;br /&gt;
     #  other modules may be listed&lt;br /&gt;
  .&lt;br /&gt;
  .&lt;br /&gt;
  .&lt;br /&gt;
     include &amp;quot;mod_cgi.conf&amp;quot;&lt;br /&gt;
 &lt;br /&gt;
     include &amp;quot;mod_fastcgi.conf&amp;quot;&lt;br /&gt;
&lt;br /&gt;
Stop and remove mini_httpd; start lighttpd, test&lt;br /&gt;
&lt;br /&gt;
  /etc/init.d/mini_httpd stop&lt;br /&gt;
  rc-update del mini_httpd&lt;br /&gt;
  apk del mini_httpd&lt;br /&gt;
  rc-update add lighttpd&lt;br /&gt;
  /etc/init.d/lighttpd start&lt;br /&gt;
&lt;br /&gt;
At this point you should be able to see ACF being served with lighttpd (Note: this will work well with alpine 1.10. With earlier versions there will be problems.)  https://host.example.com/acf/&lt;br /&gt;
&lt;br /&gt;
== Install Postgresql ==&lt;br /&gt;
&lt;br /&gt;
Add and configure postgresql&lt;br /&gt;
&lt;br /&gt;
  apk add acf-postgresql postgresql-client&lt;br /&gt;
  /etc/init.d/postgresql setup&lt;br /&gt;
  /etc/init.d/postgresql start&lt;br /&gt;
  rc-update add postgresql&lt;br /&gt;
&lt;br /&gt;
At this point any user can connect to the sql server with &amp;quot;trust&amp;quot; mechanism.  If you want to enforce password authentication (you probably do) edit /var/lib/postgresql/8.4/data/pg_hba.conf&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
  Editme: What should we recommend?&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Create the postfix database:&lt;br /&gt;
&lt;br /&gt;
  psql -U postgres&lt;br /&gt;
   create user postfix with password &#039;******&#039;;&lt;br /&gt;
   create database postfix owner postfix;&lt;br /&gt;
   \c postfix&lt;br /&gt;
   create language plpgsql;&lt;br /&gt;
   \q&lt;br /&gt;
&lt;br /&gt;
(Of course, use your selected password where ******* is shown above.)&lt;br /&gt;
&lt;br /&gt;
== Install PostfixAdmin ==&lt;br /&gt;
&lt;br /&gt;
We are going to install the postfix admin web front-end before we install the mail server.  This just creates an interface to populate the SQL tables that postfix and dovecot will use.&lt;br /&gt;
&lt;br /&gt;
Download PostfixAdmin from Sourceforge.  When these instructions were written, 2.3 was the current release, so (replace host.example.com with the actual domain):&lt;br /&gt;
 wget http://downloads.sourceforge.net/project/postfixadmin/postfixadmin/postfixadmin_2.3.tar.gz&lt;br /&gt;
 tar zxvf postfixadmin_2.3.tar.gz&lt;br /&gt;
 mkdir -p /var/www/domains/host.example.com/www/postfixadmin&lt;br /&gt;
 mv postfixadmin-2.3/* /var/www/domains/host.example.com/www/postfixadmin&lt;br /&gt;
 rm -rf postfixadmin*&lt;br /&gt;
&lt;br /&gt;
Edit /var/www/domains/host.example.com/www/postfixadmin/config.inc.php and modify at least these lines (replace host.example.com with the actual domain):&lt;br /&gt;
&lt;br /&gt;
 $CONF[&#039;configured&#039;] = true;&lt;br /&gt;
 $CONF[&#039;setup_password&#039;] = &amp;quot;&amp;quot;;  &amp;lt;&amp;lt; Don&#039;t change this yet&lt;br /&gt;
 $CONF[&#039;database_type&#039;] = &#039;pgsql&#039;;&lt;br /&gt;
 $CONF[&#039;database_host&#039;] = &#039;localhost&#039;;&lt;br /&gt;
 $CONF[&#039;database_user&#039;] = &#039;postfix&#039;;&lt;br /&gt;
 $CONF[&#039;database_password&#039;] = &#039;*****&#039;;   &amp;lt;&amp;lt; The password you chose above&lt;br /&gt;
 $CONF[&#039;database_name&#039;] = &#039;postfix&#039;;&lt;br /&gt;
 $CONF[&#039;database_prefix&#039;] = &amp;quot;&amp;quot;;&lt;br /&gt;
 $CONF[&#039;admin_email&#039;] = &#039;you@some.email.com&#039;;  &amp;lt;&amp;lt; Your email address &lt;br /&gt;
 $CONF[&#039;encrypt&#039;] = &#039;md5crypt&#039;;&lt;br /&gt;
 $CONF[&#039;authlib_default_flavor&#039;] = &#039;md5raw&#039;;&lt;br /&gt;
 $CONF[&#039;dovecotpw&#039;] = &amp;quot;/usr/sbin/dovecotpw&amp;quot;;&lt;br /&gt;
 $CONF[&#039;domain_path&#039;] = &#039;YES&#039;;&lt;br /&gt;
 $CONF[&#039;domain_in_mailbox&#039;] = &#039;NO&#039;;&lt;br /&gt;
 $CONF[&#039;aliases&#039;] = &#039;10&#039;;                       &lt;br /&gt;
 $CONF[&#039;mailboxes&#039;] = &#039;10&#039;;&lt;br /&gt;
 $CONF[&#039;maxquota&#039;] = &#039;10&#039;;&lt;br /&gt;
 $CONF[&#039;quota&#039;] = &#039;YES&#039;;&lt;br /&gt;
 $CONF[&#039;quota_multiplier&#039;] = &#039;1024000&#039;;&lt;br /&gt;
 $CONF[&#039;vacation&#039;] = &#039;NO&#039;; &lt;br /&gt;
 $CONF[&#039;vacation_control&#039;] =&#039;NO&#039;;&lt;br /&gt;
 $CONF[&#039;vacation_control_admin&#039;] = &#039;NO&#039;;&lt;br /&gt;
 $CONF[&#039;alias_control&#039;] = &#039;YES&#039;;&lt;br /&gt;
 $CONF[&#039;alias_control_admin&#039;] = &#039;YES&#039;;&lt;br /&gt;
 $CONF[&#039;special_alias_control&#039;] = &#039;YES&#039;;&lt;br /&gt;
 $CONF[&#039;fetchmail&#039;] = &#039;NO&#039;;&lt;br /&gt;
 $CONF[&#039;user_footer_link&#039;] = &amp;quot;http://host.example.com/postfixadmin&amp;quot;;&lt;br /&gt;
 $CONF[&#039;footer_link&#039;] = &#039;http://host.example.com/postfixadmin/main.php&#039;;&lt;br /&gt;
 $CONF[&#039;create_mailbox_subdirs_prefix&#039;]=&amp;quot;&amp;quot;;  &lt;br /&gt;
 $CONF[&#039;used_quotas&#039;] = &#039;YES&#039;;   &lt;br /&gt;
 $CONF[&#039;new_quota_table&#039;] = &#039;YES&#039;;  &lt;br /&gt;
&lt;br /&gt;
You should further edit /var/www/domains/host.example.com/www/postfixadmin/config.inc.php and replace all instances of &amp;quot;change-this-to-your.domain.tld&amp;quot; with your actual mail domain. This can be done with busybox sed (replace example.com with your domain name):&lt;br /&gt;
&lt;br /&gt;
 sed -i -e &#039;s/change-this-to-your.domain.tld/example.com/g&#039; /var/www/domains/host.example.com/www/postfixadmin/config.inc.php&lt;br /&gt;
&lt;br /&gt;
Go to http://host.example.com/postfixadmin/setup.php&lt;br /&gt;
&lt;br /&gt;
Create the password hash, add it to the config.inc.php file&lt;br /&gt;
&lt;br /&gt;
Go back to http://host.example.com/postfixadmin/setup.php&lt;br /&gt;
&lt;br /&gt;
Create superadmin account.&lt;br /&gt;
&lt;br /&gt;
== Install Postfix ==&lt;br /&gt;
&lt;br /&gt;
Create a user for the virtual mail delivery, and get its uid/gid (you&#039;ll need the numeric uid/gid for postfix)&lt;br /&gt;
&lt;br /&gt;
 adduser vmail -H -D -s /bin/false&lt;br /&gt;
 grep vmail /etc/passwd&lt;br /&gt;
&lt;br /&gt;
(In examples below, we use 1006/1006 for the uid/gid)&lt;br /&gt;
&lt;br /&gt;
Create the mail directory, and assign vmail as the owner&lt;br /&gt;
 mkdir -p /var/mail/domains&lt;br /&gt;
 chown -R vmail:vmail /var/mail/domains&lt;br /&gt;
 &lt;br /&gt;
&lt;br /&gt;
Install postfix&lt;br /&gt;
&lt;br /&gt;
 apk add acf-postfix postfix-pgsql&lt;br /&gt;
&lt;br /&gt;
Edit the /etc/postfix/main.cf file. Here&#039;s an example (don&#039;t forget to replace the uid/gid):&lt;br /&gt;
&lt;br /&gt;
 myhostname=host.example.com&lt;br /&gt;
 mydomain=example.com&lt;br /&gt;
 &lt;br /&gt;
 mydestination = localhost.$mydomain, localhost&lt;br /&gt;
 mynetworks_style = subnet&lt;br /&gt;
 mynetworks = 127.0.0.0/8&lt;br /&gt;
 &lt;br /&gt;
 virtual_mailbox_domains = proxy:pgsql:/etc/postfix/sql/pgsql_virtual_domains_maps.cf&lt;br /&gt;
 virtual_alias_maps = proxy:pgsql:/etc/postfix/sql/pgsql_virtual_alias_maps.cf,&lt;br /&gt;
        proxy:pgsql:/etc/postfix/sql/pgsql_virtual_alias_domain_maps.cf,&lt;br /&gt;
        proxy:pgsql:/etc/postfix/sql/pgsql_virtual_alias_domain_catchall_maps.cf&lt;br /&gt;
 &lt;br /&gt;
 virtual_mailbox_maps = proxy:pgsql:/etc/postfix/sql/pgsql_virtual_mailbox_maps.cf,&lt;br /&gt;
        proxy:pgsql:/etc/postfix/sql/pgsql_virtual_alias_domain_mailbox_maps.cf&lt;br /&gt;
 &lt;br /&gt;
 virtual_mailbox_base = /var/mail/domains/&lt;br /&gt;
 virtual_gid_maps = static:1006&lt;br /&gt;
 virtual_uid_maps = static:1006&lt;br /&gt;
 virtual_minimum_uid = 100&lt;br /&gt;
 virtual_transport = virtual&lt;br /&gt;
 &lt;br /&gt;
 &lt;br /&gt;
 # This next command means you must create a virtual&lt;br /&gt;
 # domain for the host itself - ALL mail goes through&lt;br /&gt;
 # The virtual transport&lt;br /&gt;
 &lt;br /&gt;
 mailbox_transport = virtual&lt;br /&gt;
 local_transport = virtual&lt;br /&gt;
 local_transport_maps = $virtual_mailbox_maps&lt;br /&gt;
 &lt;br /&gt;
 smtpd_helo_required = yes&lt;br /&gt;
 disable_vrfy_command = yes&lt;br /&gt;
 message_size_limit = 10240000&lt;br /&gt;
 queue_minfree = 51200000&lt;br /&gt;
 &lt;br /&gt;
 smtpd_sender_restrictions =&lt;br /&gt;
        permit_mynetworks,&lt;br /&gt;
        reject_non_fqdn_sender,&lt;br /&gt;
        reject_unknown_sender_domain&lt;br /&gt;
 &lt;br /&gt;
 smtpd_recipient_restrictions =&lt;br /&gt;
        reject_non_fqdn_recipient,&lt;br /&gt;
        reject_unknown_recipient_domain,&lt;br /&gt;
        permit_mynetworks,&lt;br /&gt;
        permit_sasl_authenticated,&lt;br /&gt;
        reject_unauth_destination,&lt;br /&gt;
        reject_rbl_client dnsbl.sorbs.net,&lt;br /&gt;
        reject_rbl_client zen.spamhaus.org,&lt;br /&gt;
        reject_rbl_client bl.spamcop.net&lt;br /&gt;
 &lt;br /&gt;
 smtpd_data_restrictions = reject_unauth_pipelining&lt;br /&gt;
 &lt;br /&gt;
 # we will use this later - This prevents cleartext authentication&lt;br /&gt;
 # for relaying&lt;br /&gt;
 smtpd_tls_auth_only = yes&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Now we need to create a *bunch* of files so that postfix can get the delivery information out of sql. Here&#039;s a shell script to create the scripts.  Change PGPW to the password for the postfix user of the postfix SQL database.&lt;br /&gt;
&lt;br /&gt;
 cd /etc/postfix&lt;br /&gt;
 mkdir sql&lt;br /&gt;
 PGPW=&amp;quot;ChangeMe&amp;quot;&lt;br /&gt;
 &lt;br /&gt;
 cat - &amp;lt;&amp;lt;EOF &amp;gt;sql/pgsql_virtual_alias_domain_catchall_maps.cf&lt;br /&gt;
 user=postfix&lt;br /&gt;
 password = $PGPW&lt;br /&gt;
 hosts = localhost&lt;br /&gt;
 dbname = postfix&lt;br /&gt;
 query = Select goto From alias,alias_domain where alias_domain.alias_domain = &#039;%d&#039; and alias.address = &#039;@&#039; ||  alias_domain.target_domain and alias.active = true and alias_domain.active= true &lt;br /&gt;
 EOF&lt;br /&gt;
 &lt;br /&gt;
 cat - &amp;lt;&amp;lt;EOF &amp;gt;sql/pgsql_virtual_alias_domain_mailbox_maps.cf&lt;br /&gt;
 user=postfix&lt;br /&gt;
 password = $PGPW&lt;br /&gt;
 hosts = localhost&lt;br /&gt;
 dbname = postfix&lt;br /&gt;
 query = Select maildir from mailbox,alias_domain where alias_domain.alias_domain = &#039;%d&#039; and mailbox.username = &#039;%u&#039; || &#039;@&#039; || alias_domain.target_domain and mailbox.active = true and alias_domain.active&lt;br /&gt;
 EOF&lt;br /&gt;
 &lt;br /&gt;
 cat - &amp;lt;&amp;lt;EOF &amp;gt;sql/pgsql_virtual_alias_domain_maps.cf&lt;br /&gt;
 user=postfix&lt;br /&gt;
 password = $PGPW&lt;br /&gt;
 hosts = localhost&lt;br /&gt;
 dbname = postfix&lt;br /&gt;
 query = select goto from alias,alias_domain where alias_domain.alias_domain=&#039;%d&#039; and alias.address = &#039;%u&#039; || &#039;@&#039; || alias_domain.target_domain and alias.active= true and alias_domain.active= true&lt;br /&gt;
 EOF&lt;br /&gt;
 &lt;br /&gt;
 cat - &amp;lt;&amp;lt;EOF &amp;gt;sql/pgsql_virtual_alias_maps.cf&lt;br /&gt;
 user=postfix&lt;br /&gt;
 password = $PGPW&lt;br /&gt;
 hosts = localhost&lt;br /&gt;
 dbname = postfix&lt;br /&gt;
 query = Select goto From alias Where address=&#039;%s&#039; and active =&#039;1&#039;&lt;br /&gt;
 EOF&lt;br /&gt;
 &lt;br /&gt;
 cat - &amp;lt;&amp;lt;EOF &amp;gt;sql/pgsql_virtual_domains_maps.cf&lt;br /&gt;
 user=postfix&lt;br /&gt;
 password = $PGPW&lt;br /&gt;
 hosts = localhost&lt;br /&gt;
 dbname = postfix&lt;br /&gt;
 query = Select domain from domain where domain=&#039;%s&#039; and active=&#039;1&#039;&lt;br /&gt;
 EOF&lt;br /&gt;
 &lt;br /&gt;
 cat - &amp;lt;&amp;lt;EOF &amp;gt;sql/pgsql_virtual_mailbox_maps.cf&lt;br /&gt;
 user=postfix&lt;br /&gt;
 password = $PGPW&lt;br /&gt;
 hosts = localhost&lt;br /&gt;
 dbname = postfix&lt;br /&gt;
 query = Select maildir from mailbox where username=&#039;%s&#039; and active=true&lt;br /&gt;
 EOF&lt;br /&gt;
 &lt;br /&gt;
 chown -R postfix:postfix sql&lt;br /&gt;
 chmod 640 sql/*&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
At this point you should be able to start up postfix&lt;br /&gt;
 &lt;br /&gt;
 newaliases  # so postfix is happy...&lt;br /&gt;
 /etc/init.d/postfix start&lt;br /&gt;
 rc-update add postfix&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Create a domain in PostfixAdmin and test ===&lt;br /&gt;
&lt;br /&gt;
Go to http://host.example.com/postfixadmin/&lt;br /&gt;
&lt;br /&gt;
Log in using the superadmin account, create a domain for the local box (e.g. example.com), and create a user mailbox (e.g. root).&lt;br /&gt;
&lt;br /&gt;
From the machine, send a test message:&lt;br /&gt;
&lt;br /&gt;
 sendmail -t root@example.com&lt;br /&gt;
 subject: test&lt;br /&gt;
 .&lt;br /&gt;
 ^d&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
In /var/log/mail.log (or /var/log/messages, if you still have busybox syslogd running) you should see the message queued.  The message should be in /var/mail/domains/example.com/root/new&lt;br /&gt;
&lt;br /&gt;
== Install Dovecot ==&lt;br /&gt;
&lt;br /&gt;
Dovecot is the POP3/IMAP server to retrieve mail.&lt;br /&gt;
&lt;br /&gt;
As before, we install dovecot: &lt;br /&gt;
&lt;br /&gt;
 apk add acf-dovecot dovecot-pgsql&lt;br /&gt;
&lt;br /&gt;
edit /etc/dovecot/dovecot.conf&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 # Select only the protocols you wish to support - all are listed in the next line&lt;br /&gt;
 protocols               =       imap imaps pop pop3s&lt;br /&gt;
 log_path                =       /var/log/dovecot.log&lt;br /&gt;
 info_log_path           =       /var/log/dovecot-info.log&lt;br /&gt;
 disable_plaintext_auth  =       no&lt;br /&gt;
&lt;br /&gt;
 # Authenticated IMAP&lt;br /&gt;
 ssl                     =       yes&lt;br /&gt;
 ssl_cert_file           =       /etc/lighttpd/server-bundle.pem&lt;br /&gt;
 ssl_key_file            =       /etc/lighttpd/server-bundle.pem&lt;br /&gt;
 auth_verbose            =       yes&lt;br /&gt;
 auth_debug              =       no&lt;br /&gt;
 mail_location           =       maildir:/var/mail/domains/%d/%n&lt;br /&gt;
 auth default    {&lt;br /&gt;
        mechanisms = plain&lt;br /&gt;
        passdb sql {&lt;br /&gt;
                args = /etc/dovecot/dovecot-sql.conf&lt;br /&gt;
                }&lt;br /&gt;
        userdb static {&lt;br /&gt;
                args =  uid=1006 gid=1006 home=/var/mail/domains/%d/%n&lt;br /&gt;
                }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Be sure to replace the uid and gid with the appropriate values for the vmail user.&lt;br /&gt;
&lt;br /&gt;
We need a certificate for SSL/TLS authentication, so in the example above, we use the lighttpd cert. That way when the cert is renewed/replaced, Dovecot will have access to the new cert as well.  &lt;br /&gt;
&lt;br /&gt;
Create the /etc/dovecot/dovecot-sql.conf file:&lt;br /&gt;
&lt;br /&gt;
 driver = pgsql&lt;br /&gt;
 connect = host=localhost dbname=postfix user=postfix password=********&lt;br /&gt;
 password_query = select username,password from mailbox where local_part = &#039;%n&#039; and domain = &#039;%d&#039;&lt;br /&gt;
 default_pass_scheme =  MD5-CRYPT&lt;br /&gt;
&lt;br /&gt;
Again, change the password above to your postfix user password, and protect the file from prying eyes:&lt;br /&gt;
&lt;br /&gt;
 chown root:root /etc/dovecot/dovecot-sql.conf&lt;br /&gt;
 chmod 600 /etc/dovecot/dovecot-sql.conf&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Start dovecot&lt;br /&gt;
 /etc/init.d/dovecot start&lt;br /&gt;
 rc-update add dovecot&lt;br /&gt;
&lt;br /&gt;
== Testing ==&lt;br /&gt;
&lt;br /&gt;
Make sure your firewall allows in ports 25(SMTP) 110 (POP3), 995 (POP3S), 143(IMAP), 993(IMAPS), or whatever subset you support.  &lt;br /&gt;
 &lt;br /&gt;
At this point, you should be able to:&lt;br /&gt;
 * Create a new domain and add users with PostfixAdmin&lt;br /&gt;
 * Send mail to those users via SMTP to port 25&lt;br /&gt;
 * Retrieve mail using the user&#039;s full email and password (e.g. username: user@example.com  password: ChangeMe)&lt;br /&gt;
&lt;br /&gt;
== Value Add Features ==&lt;br /&gt;
&lt;br /&gt;
If you followed the guide above, you now have a functional mail server with many interconnected parts.  The features below assume that the server is already running as described above.  You should be able to add any or all of these features below to further enhance the mail service.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Virus Scanning ===&lt;br /&gt;
&lt;br /&gt;
This procedure uses clamav and the postfix content_filter mechanism to scan inbound and outbound email for viruses.  Infected emails are dropped.  Clean emails are tagged with a &amp;quot;scanned by clamav&amp;quot; header.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* Install clamav and clamsmtp:&lt;br /&gt;
 apk add acf-clamav clamsmtp&lt;br /&gt;
* Edit the /etc/clamav/clamd.conf file if desired (not necessary in most cases)&lt;br /&gt;
* Edit /etc/clamsmtpd.conf and verify the following lines&lt;br /&gt;
 OutAddress: 10026&lt;br /&gt;
 Listen: 127.0.0.1:10025                                               &lt;br /&gt;
 Header: X-Virus-Scanned: ClamAV using ClamSMTP&lt;br /&gt;
 Action: drop&lt;br /&gt;
 User: clamav                                                      &lt;br /&gt;
* Start the daemons&lt;br /&gt;
 rc-update add clamd&lt;br /&gt;
 rc-update add clamsmtpd&lt;br /&gt;
 /etc/init.d/clamd start&lt;br /&gt;
 /etc/init.d/clamsmtpd start&lt;br /&gt;
* Verify clamsmtp is listening on port 10025:&lt;br /&gt;
 netstat -anp | grep clamsmtp&lt;br /&gt;
* [http://memberwebs.com/stef/software/clamsmtp/postfix.html Following the clamsmtp instructions]&lt;br /&gt;
** edit /etc/postfix/main.cf and add:&lt;br /&gt;
 content_filter = scan:[127.0.0.1]:10025                                                      &lt;br /&gt;
** edit /etc/postfix/master.cf and add&lt;br /&gt;
 # AV scan filter (used by content_filter)&lt;br /&gt;
 scan      unix  -       -       n       -       16      smtp&lt;br /&gt;
         -o smtp_send_xforward_command=yes&lt;br /&gt;
         -o smtp_enforce_tls=no&lt;br /&gt;
 # For injecting mail back into postfix from the filter&lt;br /&gt;
 127.0.0.1:10026 inet  n -       n       -       16      smtpd&lt;br /&gt;
         -o content_filter=&lt;br /&gt;
         -o receive_override_options=no_unknown_recipient_checks,no_header_body_checks&lt;br /&gt;
         -o smtpd_helo_restrictions=&lt;br /&gt;
         -o smtpd_client_restrictions=&lt;br /&gt;
         -o smtpd_sender_restrictions=&lt;br /&gt;
         -o smtpd_recipient_restrictions=permit_mynetworks,reject&lt;br /&gt;
         -o mynetworks_style=host&lt;br /&gt;
         -o smtpd_authorized_xforward_hosts=127.0.0.0/8&lt;br /&gt;
* postfix reload&lt;br /&gt;
* Send and email into a local virtual domain - it should have the &#039;&#039;X-Virus-Scanned: ClamAV using ClamSMTP&#039;&#039; header.&lt;br /&gt;
&lt;br /&gt;
=== Relay for Authenticated Users ===&lt;br /&gt;
&lt;br /&gt;
As configured above, the mail server accepts email from the Internet, but it does not relay email.  If it is a perimeter exchanger for a protected network, then you can add the protected networks to the &#039;&#039;mynetworks&#039;&#039; configuration line in /etc/postfix/main.cf&lt;br /&gt;
&lt;br /&gt;
This configuration change allows &#039;&#039;remote&#039;&#039; users to authenticate against the mail server and relay through it.  The rules for relaying are:&lt;br /&gt;
* Only authenticated users can relay&lt;br /&gt;
* Authentication Credentials must be encrypted with TLS or SSL&lt;br /&gt;
* Allow Submission and SMTPS ports for relaying (many consumer networks block port 25 - SMTP by default)&lt;br /&gt;
The process uses the dovecot authentication mechanism (used with IMAPS) to authenticate users before they are allowed to relay through postfix.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* Edit /etc/dovecot/dovecot.conf and add teh following inside the &#039;&#039;auth default&#039;&#039; stanza:&lt;br /&gt;
 # this is for postfix SASL (authenticated users can relay through us)&lt;br /&gt;
 socket listen {&lt;br /&gt;
                client {&lt;br /&gt;
                        path    = /var/spool/postfix/private/dovecot-auth.sock&lt;br /&gt;
                        mode    = 0660&lt;br /&gt;
                        user    = postfix&lt;br /&gt;
                        group   = postfix&lt;br /&gt;
                        }&lt;br /&gt;
                }&lt;br /&gt;
        }&lt;br /&gt;
* Restart dovecot&lt;br /&gt;
 /etc/init.d/dovecot restart&lt;br /&gt;
* Edit /etc/postfix/main.cf and add:&lt;br /&gt;
 # TLS Stuff -- since we allow SASL with tls *only*, we have to set up TLS first                    &lt;br /&gt;
 &lt;br /&gt;
 smtpd_tls_cert_file = /etc/lighttpd/server-bundle.pem&lt;br /&gt;
 smtpd_tls_key_file = /etc/lighttpd/server-bundle.pem&lt;br /&gt;
 smtpd_tls_CAfile = /etc/lighttpd/ca-crt.pem&lt;br /&gt;
 # If tls_security_level is set to &amp;quot;encrypt&amp;quot;, then SMTP rejects &lt;br /&gt;
 # unencrypted email (e.g. normal mail) which is bad.&lt;br /&gt;
 # By setting it to &amp;quot;may&amp;quot; you get TLS encrypted mail from google, slashdot, and other &lt;br /&gt;
 # interesting places.  Check your logs to see who&lt;br /&gt;
 smtpd_tls_security_level = may&lt;br /&gt;
 # Log info about the negotiated encryption levels&lt;br /&gt;
 smtpd_tls_received_header = yes&lt;br /&gt;
 smtpd_tls_loglevel = 1&lt;br /&gt;
 &lt;br /&gt;
 # SASL - this allows senders to authenticiate themselves&lt;br /&gt;
 # This along with &amp;quot;permit_sasl_authenticated&amp;quot; in smtpd_recipient_restrictions allows relaying&lt;br /&gt;
 smtpd_sasl_type = dovecot&lt;br /&gt;
 smtpd_sasl_path = private/dovecot-auth.sock&lt;br /&gt;
 smtpd_sasl_auth_enable = yes&lt;br /&gt;
 smtpd_sasl_authenticated_header = yes&lt;br /&gt;
 smtpd_tls_auth_only = yes&lt;br /&gt;
* Edit /etc/postfix/master.cf and enable the submission and smtps transports.  They are probably already at the top of your  master.cf file, just commented out:&lt;br /&gt;
 submission inet n       -       n       -       -       smtpd&lt;br /&gt;
   -o smtpd_tls_security_level=encrypt&lt;br /&gt;
   -o smtpd_sasl_auth_enable=yes&lt;br /&gt;
   -o smtpd_client_restrictions=permit_sasl_authenticated,reject&lt;br /&gt;
   -o milter_macro_daemon_name=ORIGINATING&lt;br /&gt;
 smtps     inet  n       -       n       -       -       smtpd&lt;br /&gt;
   -o smtpd_tls_security_level=encrypt&lt;br /&gt;
   -o smtpd_tls_wrappermode=yes&lt;br /&gt;
   -o smtpd_sasl_auth_enable=yes&lt;br /&gt;
   -o smtpd_client_restrictions=permit_sasl_authenticated,reject&lt;br /&gt;
   -o milter_macro_daemon_name=ORIGINATING&lt;br /&gt;
*Verfiy submission and smtps are defined in /etc/services&lt;br /&gt;
 grep &amp;quot;submission\|ssmtp&amp;quot; /etc/services&lt;br /&gt;
 submission	587/tcp				# mail message submission&lt;br /&gt;
 submission	587/udp&lt;br /&gt;
 smtps		465/tcp		ssmtp		# smtp protocol over TLS/SSL&lt;br /&gt;
 smtps		465/udp		ssmtp&lt;br /&gt;
* Restart postfix&lt;br /&gt;
 postfix reload&lt;br /&gt;
&lt;br /&gt;
At this point, you should be able to set up a mail client to relay through the server with TLS (port 587) or SSL (port 465)  Note that &amp;quot;plain&amp;quot; authentication is used because the underlying link is encrypted.  For example, in Thunderbird leave &amp;quot;secure authentication&amp;quot; unchecked, and choose STARTTLS (or TLS) for the connection security.&lt;br /&gt;
&lt;br /&gt;
=== Mailbox Quotas ===&lt;br /&gt;
&lt;br /&gt;
In the default configuration, PostfixAdmin knows about quotas, but they are not enforced.   Documentation on the web mentions the [http://vda.sourceforge.net vda patch to postfix] to enforce quotas.  The only bad thing... its a &#039;&#039;patch&#039;&#039;.   Postfix and Dovecot are both conservative systems, so if the patch isn&#039;t in the upstream source, we&#039;ll assume there&#039;s a good reason.   There is a way of using quotas without patches - and it involves using dovecot&#039;s [http://wiki.dovecot.org/LDA deliver] lda for local delivery.&lt;br /&gt;
&lt;br /&gt;
Note: As of Jan 2010, the documention is confusing, with multiple versions of dovecot, PostfixAdmin, and Mysql referenced.  These instructions apply to:&lt;br /&gt;
* Postgresql 8.4.2 &lt;br /&gt;
* PostfixAdmin 2.3 &lt;br /&gt;
* Dovecot 1.2.11&lt;br /&gt;
* Postfix 2.6.5&lt;br /&gt;
&lt;br /&gt;
Presumably later versions will work the same, but if not, please update the documentation and versions above.&lt;br /&gt;
&lt;br /&gt;
* Update /etc/dovecot/dovecot.conf (old lines shown commented out):&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
# old postfix &lt;br /&gt;
#       userdb static {&lt;br /&gt;
#               args =  uid=1006 gid=1006 home=/var/mail/domains/%d/%n&lt;br /&gt;
#               }&lt;br /&gt;
&lt;br /&gt;
# new quota support:&lt;br /&gt;
        userdb prefetch {&lt;br /&gt;
                }&lt;br /&gt;
&lt;br /&gt;
        userdb sql {&lt;br /&gt;
                args = /etc/dovecot/dovecot-sql.conf&lt;br /&gt;
                }&lt;br /&gt;
&lt;br /&gt;
        socket listen {&lt;br /&gt;
                client {&lt;br /&gt;
                        path    = /var/spool/postfix/private/dovecot-auth.sock&lt;br /&gt;
                        mode    = 0660&lt;br /&gt;
                        user    = postfix&lt;br /&gt;
                        group   = postfix&lt;br /&gt;
                        }&lt;br /&gt;
                # These lines below are for the deliver lda&lt;br /&gt;
                master {&lt;br /&gt;
                        path =  /var/run/dovecot/auth-master&lt;br /&gt;
                        mode    = 0660&lt;br /&gt;
                        user    = vmail&lt;br /&gt;
                        group   = vmail&lt;br /&gt;
                        }&lt;br /&gt;
                }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
protocol imap {                                                               &lt;br /&gt;
         mail_plugins = quota imap_quota                                       &lt;br /&gt;
         }                                                                     &lt;br /&gt;
                                                                              &lt;br /&gt;
protocol pop3 {                                                               &lt;br /&gt;
         mail_plugins = quota                                                  &lt;br /&gt;
         }                                                                     &lt;br /&gt;
                                                                              &lt;br /&gt;
dict {                                                                        &lt;br /&gt;
        quotadict = pgsql:/etc/dovecot/dovecot-dict-quota.conf                &lt;br /&gt;
        }                                                                     &lt;br /&gt;
                                                                              &lt;br /&gt;
plugin {                                                                      &lt;br /&gt;
         quota = dict:user::proxy::quotadict                                   &lt;br /&gt;
         }                                                     &lt;br /&gt;
                                                              &lt;br /&gt;
protocol lda {                                                &lt;br /&gt;
   postmaster_address = postmaster@host.example.com&lt;br /&gt;
   mail_plugins = quota                                        &lt;br /&gt;
   auth_socket_path =  /var/run/dovecot/auth-master&lt;br /&gt;
   sendmail_path = /usr/sbin/sendmail&lt;br /&gt;
}                                                                            &lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
 &lt;br /&gt;
You should already have a &amp;lt;tt&amp;gt;socket-&amp;gt; listen-&amp;gt; client&amp;lt;/tt&amp;gt; section, but it is listed above to show where it goes in relationship to the &amp;lt;tt&amp;gt;socket -&amp;gt; listen -&amp;gt; master&amp;lt;/tt&amp;gt; section&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* edit &amp;lt;tt&amp;gt;/etc/dovecot/dovecot-sql.conf&amp;lt;/tt&amp;gt; and replace the user and password queries with the following (you may not have a user_query yet - add it):&lt;br /&gt;
&lt;br /&gt;
 password_query = select username as user, password, 1006 as userdb_uid, 1006 as userdb_gid, &#039;*:bytes=&#039; || quota as userdb_quota_rule from mailbox  where local_part = &#039;%n&#039; and domain = &#039;%d&#039;&lt;br /&gt;
 user_query = select &#039;/var/mail/domains/&#039; || maildir as home, 1006 as uid, 1006 as gid, &#039;*:bytes=&#039; || quota  as quota_rule from mailbox where local_part = &#039;%n&#039; and domain =&#039;%d&#039;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* create &amp;lt;tt&amp;gt;/etc/dovecot/dovecot-dict-quota.conf&amp;lt;/tt&amp;gt;&lt;br /&gt;
 connect = host=localhost dbname=postfix user=postfix password=********&lt;br /&gt;
 &lt;br /&gt;
 map {&lt;br /&gt;
         pattern = priv/quota/storage&lt;br /&gt;
         table = quota2&lt;br /&gt;
         username_field =username&lt;br /&gt;
         value_field = bytes&lt;br /&gt;
 }&lt;br /&gt;
 &lt;br /&gt;
 map {&lt;br /&gt;
        pattern= priv/quota/messages&lt;br /&gt;
        table = quota2&lt;br /&gt;
        username_field = username&lt;br /&gt;
        value_field = messages&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
Again, change the password above to your postfix user password, and protect the file from prying eyes:&lt;br /&gt;
  chown root:root /etc/dovecot/dovecot-dict-quota.conf&lt;br /&gt;
  chmod 600 /etc/dovecot/dovecot-dict-quota.conf&lt;br /&gt;
&lt;br /&gt;
Side note: [http://wiki.dovecot.org/Quota/Dict The Dovecot Quota Documentation] mentions the need for a trigger with pgsql.  This was created in the PostfixAdmin install, which is why you instantiated the pgsql language when creating the database.  If not, you will need to create the trigger, to reference the quota2 table, not the quota table mentioned in the dovecot docs.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* create a new transport for the dovecot lda.   Add the following to  /etc/postfix/master.cf:&lt;br /&gt;
 # The dovecot deliver lda&lt;br /&gt;
 dovecot   unix  -       n       n       -       -       pipe&lt;br /&gt;
   flags=DRhu user=vmail:vmail argv=/usr/libexec/dovecot/deliver -f ${sender} -d ${user}@${nexthop}&lt;br /&gt;
&lt;br /&gt;
* Edit the /etc/postfix/main.cf.  Replace &lt;br /&gt;
 virtual_transport = virtual &lt;br /&gt;
with&lt;br /&gt;
 virtual_transport = dovecot&lt;br /&gt;
 dovecot_destination_recipient_limit = 1&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;TODO&#039;&#039;&#039;  This will cause over-quota emails to bounce.   Which could be a source of backscatter.   We need a way of checking quota limits after RBL checking but before the message is accepted in the queue.&lt;br /&gt;
&lt;br /&gt;
=== WebMail (RoundCube) ===&lt;br /&gt;
&lt;br /&gt;
[http://roundcube.net/ RoundCube] is an &amp;quot;ajax /Web2.0&amp;quot; web-mail client.  These instructions are for the Alpine Linux 1.10 repository &lt;br /&gt;
&lt;br /&gt;
* Add the package and related php modules:&lt;br /&gt;
 apk add roundcubemail php-xml php-openssl php-mcrypt php-gd php-iconv&lt;br /&gt;
&lt;br /&gt;
* link the roundcube application back into the docroot&lt;br /&gt;
 ln -s /usr/share/webapps/roundcube /var/www/domains/host.example.com/www/roundcube&lt;br /&gt;
&lt;br /&gt;
* follow the instructions in /usr/share/webapps/roundcube/INSTALL:&lt;br /&gt;
 cd /usr/share/webapps/roundcube&lt;br /&gt;
 chown -R lighttpd:lighttpd temp logs&lt;br /&gt;
 &lt;br /&gt;
 su postgres&lt;br /&gt;
 createuser roundcube&lt;br /&gt;
   Shall the new role be a superuser? (y/n) n&lt;br /&gt;
   Shall the new role be allowed to create databases? (y/n) n&lt;br /&gt;
   Shall the new role be allowed to create more new roles? (y/n) y&lt;br /&gt;
 createdb -O roundcube -E UNICODE -T template0 roundcubemail&lt;br /&gt;
 psql roundcubemail&lt;br /&gt;
   roundcubemail=# ALTER USER roundcube WITH PASSWORD &#039;the_new_password&#039;;&lt;br /&gt;
   roundcubemail=# \c - roundcube&lt;br /&gt;
   roundcubemail=&amp;gt; \i /usr/share/webapps/roundcube/SQL/postgres.initial.sql&lt;br /&gt;
   roundcubemail=&amp;gt; \q&lt;br /&gt;
 exit&lt;br /&gt;
&lt;br /&gt;
* edit /etc/php/php.ini and set date.timezone to your local timezone, or to UTC&lt;br /&gt;
&lt;br /&gt;
* restart lighttpd to verify the new php libraries are used&lt;br /&gt;
 /etc/init.d/lighttpd restart&lt;br /&gt;
&lt;br /&gt;
* Point your browser to http://host.example.com/roundcube/installer&lt;br /&gt;
* Start installation&lt;br /&gt;
&lt;br /&gt;
For the specific configuration parameters in the install step:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!Property&lt;br /&gt;
!Setting&lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;enable_spellcheck&#039;&#039; ||   disabled &lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;identities_level&#039;&#039; ||  one identity with possibility to edit all params but not email address &lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;log driver&#039;&#039; || syslog &lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;sylog_id&#039;&#039; || roundcube &lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;syslog_facility&#039;&#039; || mailsubsystem &lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;db_dnsw&#039;&#039; || pgsql properties, as described above &lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;imap_host&#039;&#039; || 127.0.0.1 &lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;auto_create_user&#039;&#039; || enabled &lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;smtp_server&#039;&#039; ||  127.0.0.1&lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;smtp_port&#039;&#039; ||  25&lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;smtp_user/smtp_pass&#039;&#039; ||  enable &#039;&#039;Use Current IMAP username and password for SMTP authentication&#039;&#039;&lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;smtp_log&#039;&#039; ||  enable (optional, but gives additional log record)&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
The other items can be left at default settings, or adjusted if desired.&lt;br /&gt;
&lt;br /&gt;
* Follow the instructions in step 3 of the install to copy the files to the server&lt;br /&gt;
* You should now be able to get to roundcube at http://host.example.com/roundcube&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
After its working, the INSTALL file recommends removing the install directory.   If you want to keep the installer around later, you can simply change the ownership and permissions.  So do &#039;&#039;&#039;one&#039;&#039;&#039; of the following:&lt;br /&gt;
 cd /usr/share/webapps/roundcube&lt;br /&gt;
 rm -rf LICENSE UPGRADING INSTALL README CHANGELOG  SQL installer&lt;br /&gt;
or&lt;br /&gt;
 cd /usr/share/webapps/roundcube&lt;br /&gt;
 chown -R root:root LICENSE UPGRADING INSTALL README CHANGELOG  SQL installer&lt;br /&gt;
 chmod -R 600 LICENSE UPGRADING INSTALL README CHANGELOG SQL &lt;br /&gt;
 chmod 700 SQL installer&lt;br /&gt;
&lt;br /&gt;
==== Enable Plug-ins ====&lt;br /&gt;
&lt;br /&gt;
RoundCube has various useful plug-ins, which could be found in &#039;&#039;/usr/share/webapps/roundcube/plugins&#039;&#039; directory. For example you may want to enable &#039;&#039;password&#039;&#039; plug-in to let users change their passwords directly from RoundCube using an extra Password Tab added to User Settings.&lt;br /&gt;
&lt;br /&gt;
* Grant limited permissions for &#039;&#039;roundcube&#039;&#039; database role &lt;br /&gt;
 psql -U postgres postfix&lt;br /&gt;
   postfix=# GRANT UPDATE (password,modified) ON mailbox TO roundcube;&lt;br /&gt;
   postfix=# GRANT SELECT (username) ON mailbox TO roundcube;&lt;br /&gt;
   postfix=# GRANT INSERT ON log TO roundcube;&lt;br /&gt;
   postfix=# \q&lt;br /&gt;
&lt;br /&gt;
* Setup &#039;&#039;password&#039;&#039; plug-in parameters in &#039;&#039;/usr/share/webapps/roundcube/plugins/password/config.inc.php&#039;&#039;&lt;br /&gt;
 mv /usr/share/webapps/roundcube/plugins/password/config.inc.php.dist /usr/share/webapps/roundcube/plugins/password/config.inc.php&lt;br /&gt;
 vi /usr/share/webapps/roundcube/plugins/password/config.inc.php&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
$rcmail_config[&#039;password_minimum_length&#039;] = 7;&lt;br /&gt;
$rcmail_config[&#039;password_require_nonalpha&#039;] = true;&lt;br /&gt;
...&lt;br /&gt;
$rcmail_config[&#039;password_db_dsn&#039;] = &#039;pgsql://roundcube:&amp;lt;roundcube_password&amp;gt;@localhost/postfix&#039;;&lt;br /&gt;
...&lt;br /&gt;
$rcmail_config[&#039;password_query&#039;] = &amp;quot;UPDATE mailbox set password = %c, modified = NOW() where username = %u; INSERT INTO log (timestamp,username,domain,action,data) VALUES (NOW(),%u || &#039; (&#039; || %h || &#039;)&#039;,%d,&#039;edit_password&#039;,%u)&amp;quot;;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* Enable &#039;&#039;password&#039;&#039; plug-in&lt;br /&gt;
 vi /usr/share/webapps/roundcube/config/main.inc.php&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
...&lt;br /&gt;
$rcmail_config[&#039;plugins&#039;] = array(&#039;password&#039;);&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== OpenLDAP based Address Book ===&lt;br /&gt;
&lt;br /&gt;
This OpenLDAP configuration uses the SQL backend, which represents information stored in PostgreSQL as an LDAP subtree for Address Book functionality for email lookups, user authentication or even &lt;br /&gt;
replication account information between sites. This procedure uses some metainformation to translate LDAP queries to SQL queries, leaving relational schema untouched, which allows SQL and LDAP &lt;br /&gt;
applications to inter-operate without replication, and exchange data as needed. The SQL backend uses UnixODBC to connect to PostgresSQL. &lt;br /&gt;
&lt;br /&gt;
* Install OpenLDAP and ODBC&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
apk add openldap libldap openldap-back-sql php-ldap unixodbc psqlodbc ca-certificates&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Note&#039;&#039;&#039;: The psqlodbc package is currently unavailable&lt;br /&gt;
&lt;br /&gt;
* Update &amp;quot;postfix&amp;quot; database (it will add &#039;id&#039; columns to mailbox and domain tables, also will create tables and views to represent LDAP metainformation)&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Note&#039;&#039;&#039;: These instructions are for example domain example.com. So make sure you replaced all entries of &#039;example&#039; and &#039;com&#039; according to your domain name parts.&lt;br /&gt;
&lt;br /&gt;
Put the following into a new file called &#039;&#039;&#039;script&#039;&#039;&#039;:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
ALTER TABLE domain ADD COLUMN id SERIAL; &lt;br /&gt;
ALTER TABLE mailbox ADD COLUMN id SERIAL; &lt;br /&gt;
&lt;br /&gt;
CREATE TABLE ldap_entry_objclasses (&lt;br /&gt;
    entry_id integer NOT NULL,&lt;br /&gt;
    oc_name character varying(64)&lt;br /&gt;
);&lt;br /&gt;
&lt;br /&gt;
CREATE TABLE ldap_oc_mappings (&lt;br /&gt;
    name character varying(64) NOT NULL,&lt;br /&gt;
    keytbl character varying(64) NOT NULL,&lt;br /&gt;
    keycol character varying(64) NOT NULL,&lt;br /&gt;
    create_proc character varying(255),&lt;br /&gt;
    delete_proc character varying(255),&lt;br /&gt;
    expect_return integer NOT NULL&lt;br /&gt;
);&lt;br /&gt;
&lt;br /&gt;
ALTER TABLE ldap_oc_mappings ADD COLUMN id SERIAL;&lt;br /&gt;
ALTER TABLE ldap_oc_mappings ADD PRIMARY KEY (id);&lt;br /&gt;
&lt;br /&gt;
CREATE TABLE ldap_attr_mappings (&lt;br /&gt;
    oc_map_id integer NOT NULL REFERENCES ldap_oc_mappings(id),&lt;br /&gt;
    name character varying(255) NOT NULL,&lt;br /&gt;
    sel_expr character varying(255) NOT NULL,&lt;br /&gt;
    sel_expr_u character varying(255),&lt;br /&gt;
    from_tbls character varying(255) NOT NULL,&lt;br /&gt;
    join_where character varying(255),&lt;br /&gt;
    add_proc character varying(255),&lt;br /&gt;
    delete_proc character varying(255),&lt;br /&gt;
    param_order integer NOT NULL,&lt;br /&gt;
    expect_return integer NOT NULL&lt;br /&gt;
);&lt;br /&gt;
&lt;br /&gt;
ALTER TABLE ldap_attr_mappings ADD COLUMN id SERIAL;&lt;br /&gt;
ALTER TABLE ldap_attr_mappings ADD PRIMARY KEY (id);&lt;br /&gt;
&lt;br /&gt;
CREATE VIEW ldap_dcs AS&lt;br /&gt;
    ((SELECT (domain.id + 100000) AS id,&lt;br /&gt;
            (&#039;dc=&#039;::text || replace((domain.domain)::text, &#039;.&#039;::text, &#039;,dc=&#039;::text)) AS dn,&lt;br /&gt;
            1 AS oc_map_id,&lt;br /&gt;
            100000 AS parent,&lt;br /&gt;
            0 AS keyval,&lt;br /&gt;
            domain.domain&lt;br /&gt;
     FROM domain&lt;br /&gt;
     WHERE domain.domain &amp;lt;&amp;gt; &#039;ALL&#039;)&lt;br /&gt;
      UNION&lt;br /&gt;
     (SELECT 100000 AS id,&lt;br /&gt;
           (&#039;dc=&#039; || regexp_replace((domain.domain)::text, &#039;.*\\.&#039;, &#039;&#039;::text)) AS dn,&lt;br /&gt;
           1 AS oc_map_id,&lt;br /&gt;
           0 AS parent,&lt;br /&gt;
           0 AS keyval,&lt;br /&gt;
           (regexp_replace((domain.domain)::text, &#039;.*\\.&#039;, &#039;&#039;::text)) AS domain&lt;br /&gt;
      FROM domain&lt;br /&gt;
      WHERE domain.domain &amp;lt;&amp;gt; &#039;ALL&#039;&lt;br /&gt;
      LIMIT 1));&lt;br /&gt;
&lt;br /&gt;
CREATE VIEW ldap_entries AS&lt;br /&gt;
    SELECT mailbox.id,&lt;br /&gt;
    (((&#039;cn=&#039;::text || initcap(replace(split_part((mailbox.username)::text, &#039;@&#039;::text, 1), &#039;.&#039;::text, &#039; &#039;::text))) || &#039;,dc=&#039;::text) ||&lt;br /&gt;
             replace(regexp_replace((mailbox.username)::text, &#039;.*@&#039;, &#039;&#039;::text), &#039;.&#039;::text, &#039;,dc=&#039;::text)) AS dn,&lt;br /&gt;
          1 AS oc_map_id,&lt;br /&gt;
          (SELECT ldap_dcs.id&lt;br /&gt;
           FROM ldap_dcs&lt;br /&gt;
           WHERE ((ldap_dcs.domain)::text = (mailbox.domain)::text)) AS parent,&lt;br /&gt;
           mailbox.id AS keyval&lt;br /&gt;
           FROM mailbox&lt;br /&gt;
           UNION&lt;br /&gt;
           SELECT ldap_dcs.id,&lt;br /&gt;
                  ldap_dcs.dn,&lt;br /&gt;
                  ldap_dcs.oc_map_id,&lt;br /&gt;
                  ldap_dcs.parent,&lt;br /&gt;
                  ldap_dcs.keyval&lt;br /&gt;
           FROM ldap_dcs;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Finally, execute the commands in the file with:&lt;br /&gt;
 cat script | psql -U postfix postfix&lt;br /&gt;
 rm script&lt;br /&gt;
&lt;br /&gt;
* Fill out LDAP tables according to following example (make sure to separate values with TABs):&lt;br /&gt;
&lt;br /&gt;
Put the following into a new file called &#039;&#039;&#039;script&#039;&#039;&#039;:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
COPY ldap_oc_mappings (id, name, keytbl, keycol, create_proc, delete_proc, expect_return) FROM stdin;&lt;br /&gt;
1	exampleBox	mailbox	id	\N	\N	1&lt;br /&gt;
\.&lt;br /&gt;
COPY ldap_attr_mappings (id, oc_map_id, name, sel_expr, sel_expr_u, from_tbls, join_where, add_proc, delete_proc, param_order, expect_return) FROM stdin;&lt;br /&gt;
1	1	displayName	mailbox.name	\N	mailbox	\N	\N	\N	3	0&lt;br /&gt;
2	1	mail	mailbox.username	\N	mailbox	\N	\N	\N	3	0&lt;br /&gt;
3	1	cn	mailbox.name	\N	mailbox	\N	\N	\N	3	0&lt;br /&gt;
4	1	userPassword	&#039;{CRYPT}&#039;||mailbox.password	\N	mailbox	\N	\N	\N	3	0&lt;br /&gt;
\.&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Finally, execute the commands in the file with:&lt;br /&gt;
 cat script | psql -U postfix postfix&lt;br /&gt;
 rm script&lt;br /&gt;
&lt;br /&gt;
* Check that &amp;quot;ldap_dcs&amp;quot; view looks something like this:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
echo &#039;select * from ldap_dcs&#039; | psql -U postgres postfix&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
   id   |             dn              | oc_map_id | parent | keyval |       domain       &lt;br /&gt;
--------+-----------------------------+-----------+--------+--------+--------------------&lt;br /&gt;
 100000 | dc=com                      |         1 |      0 |      0 | com&lt;br /&gt;
 100001 | dc=example,dc=com           |         1 | 100000 |      0 | example.com&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* Check that &amp;quot;ldap_entries&amp;quot; view looks something like this:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
echo &#039;select * from ldap_entries&#039; | psql -U postgres postfix&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
   id   |                          dn                           | oc_map_id | parent | keyval &lt;br /&gt;
--------+-------------------------------------------------------+-----------+--------+--------&lt;br /&gt;
    1   | cn=address1,dc=example,dc=com                         |         1 | 100001 |    1&lt;br /&gt;
...&lt;br /&gt;
   123  | cn=address123,dc=example,dc=com                       |         1 | 100001 |    1&lt;br /&gt;
 100000 | dc=com                                                |         1 |      0 |    0&lt;br /&gt;
 100001 | dc=example,dc=com                                     |         1 | 100000 |    0&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* Configure ODBC parameters&lt;br /&gt;
&lt;br /&gt;
Edit /etc/odbc.ini:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
[PostgreSQL]&lt;br /&gt;
Description             = Connection to Postgres&lt;br /&gt;
Driver                  = PostgreSQL&lt;br /&gt;
Trace                   = Yes&lt;br /&gt;
TraceFile               = sql.log&lt;br /&gt;
Database                = postfix&lt;br /&gt;
Servername              = 127.0.0.1&lt;br /&gt;
UserName                =&lt;br /&gt;
Password                =&lt;br /&gt;
Port                    = 5432&lt;br /&gt;
Protocol                = 6.4&lt;br /&gt;
ReadOnly                = No&lt;br /&gt;
RowVersining            = No&lt;br /&gt;
ShowSystemTables        = No&lt;br /&gt;
ShowOidColumn           = No&lt;br /&gt;
FakeOidIndex            = No&lt;br /&gt;
ConnSettings            =&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Edit /etc/odbcinst.ini:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
[PostgreSQL]&lt;br /&gt;
Description     = PostgreSQL driver for Linux&lt;br /&gt;
Driver          = /usr/lib/psqlodbcw.so&lt;br /&gt;
Setup           = /usr/lib/libodbcpsqlS.so&lt;br /&gt;
FileUsage       = 1&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* Test ODBC connection&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
echo &amp;quot;select * from domain;&amp;quot; | isql PostgreSQL postgres&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* Provide permission to certificate for LDAP server&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
chown ldap /etc/lighttpd/server-bundle.pem&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* Edit LDAP schema&lt;br /&gt;
&lt;br /&gt;
Edit /etc/openldap/schema/example.com.schema:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
attributetype ( 0.9.2342.19200300.100.1.3&lt;br /&gt;
	NAME ( &#039;mail&#039; &#039;rfc822Mailbox&#039; )&lt;br /&gt;
	DESC &#039;RFC1274: RFC822 Mailbox&#039;&lt;br /&gt;
        EQUALITY caseIgnoreIA5Match&lt;br /&gt;
        SUBSTR caseIgnoreIA5SubstringsMatch&lt;br /&gt;
        SYNTAX 1.3.6.1.4.1.1466.115.121.1.26{256} )&lt;br /&gt;
&lt;br /&gt;
attributetype ( 2.16.840.1.113730.3.1.241&lt;br /&gt;
	NAME &#039;displayName&#039;&lt;br /&gt;
	DESC &#039;RFC2798: preferred name to be used when displaying entries&#039;&lt;br /&gt;
	EQUALITY caseIgnoreMatch&lt;br /&gt;
	SUBSTR caseIgnoreSubstringsMatch&lt;br /&gt;
	SYNTAX 1.3.6.1.4.1.1466.115.121.1.15&lt;br /&gt;
	SINGLE-VALUE )&lt;br /&gt;
&lt;br /&gt;
objectclass   ( 2.16.840.1.113730.3.2.2&lt;br /&gt;
        NAME &#039;exampleBox&#039;&lt;br /&gt;
	DESC &#039;example.com mailbox&#039;&lt;br /&gt;
	MUST ( displayName $ mail $ userPassword )&lt;br /&gt;
	)&lt;br /&gt;
&lt;br /&gt;
# RFC 1274 + RFC 2247&lt;br /&gt;
attributetype ( 0.9.2342.19200300.100.1.25&lt;br /&gt;
        NAME ( &#039;dc&#039; &#039;domainComponent&#039; )&lt;br /&gt;
        DESC &#039;RFC1274/2247: domain component&#039;&lt;br /&gt;
        EQUALITY caseIgnoreIA5Match&lt;br /&gt;
        SUBSTR caseIgnoreIA5SubstringsMatch&lt;br /&gt;
        SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 SINGLE-VALUE )&lt;br /&gt;
&lt;br /&gt;
attributetype ( 2.5.4.46 NAME &#039;dnQualifier&#039;&lt;br /&gt;
        DESC &#039;RFC2256: DN qualifier&#039;&lt;br /&gt;
        EQUALITY caseIgnoreMatch&lt;br /&gt;
        ORDERING caseIgnoreOrderingMatch&lt;br /&gt;
        SUBSTR caseIgnoreSubstringsMatch&lt;br /&gt;
        SYNTAX 1.3.6.1.4.1.1466.115.121.1.44 )&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* Configure LDAP server&lt;br /&gt;
&lt;br /&gt;
Edit /etc/openldap/slapd.conf:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
include         /etc/openldap/schema/example.com.schema&lt;br /&gt;
pidfile         /var/run/openldap/slapd.pid&lt;br /&gt;
argsfile        /var/run/openldap/slapd.args&lt;br /&gt;
&lt;br /&gt;
TLSCipherSuite HIGH&lt;br /&gt;
TLSCACertificateFile /etc/lighttpd/ca-crt.pem&lt;br /&gt;
TLSCertificateFile /etc/lighttpd/server-bundle.pem&lt;br /&gt;
TLSCertificateKeyFile /etc/lighttpd/server-bundle.pem&lt;br /&gt;
TLSVerifyClient never &lt;br /&gt;
&lt;br /&gt;
# This is needed for proper representation of MD5-CRYPT format stored in database&lt;br /&gt;
#  see more details in http://strugglers.net/~andy/blog/2010/01/23/openldap-and-md5crypt/&lt;br /&gt;
password-hash  {CRYPT}&lt;br /&gt;
password-crypt-salt-format &amp;quot;$1$%.8s&amp;quot;&lt;br /&gt;
&lt;br /&gt;
loglevel        stats&lt;br /&gt;
moduleload	/usr/lib/openldap/back_sql.so&lt;br /&gt;
sizelimit 3000&lt;br /&gt;
&lt;br /&gt;
database        sql&lt;br /&gt;
&lt;br /&gt;
dbname		PostgreSQL&lt;br /&gt;
dbuser		postfix&lt;br /&gt;
dbpasswd	*****&lt;br /&gt;
&lt;br /&gt;
suffix          &amp;quot;dc=example,dc=com&amp;quot;&lt;br /&gt;
&lt;br /&gt;
upper_func      &amp;quot;upper&amp;quot;&lt;br /&gt;
strcast_func    &amp;quot;text&amp;quot;&lt;br /&gt;
concat_pattern  &amp;quot;?||?&amp;quot;&lt;br /&gt;
has_ldapinfo_dn_ru      no&lt;br /&gt;
lastmod         off&lt;br /&gt;
&lt;br /&gt;
access to attrs=userPassword by * auth&lt;br /&gt;
&lt;br /&gt;
access to * by peername.ip=127.0.0.1 read&lt;br /&gt;
#           by peername.ip=&amp;lt;IP&amp;gt;%&amp;lt;netmask&amp;gt; read&lt;br /&gt;
#           by peername.ip=&amp;lt;IP&amp;gt; read&lt;br /&gt;
	    by users read&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* Set permissions for slapd.conf&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
chown ldap:ldap /etc/openldap/slapd.conf&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* Configure startup parameters to make sure that LDAP server start AFTER PostgreSQL and listens on localhost with clear text and public IP with SSL&lt;br /&gt;
&lt;br /&gt;
Edit /etc/conf.d/slapd:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
rc_need=&amp;quot;postgresql&amp;quot; &lt;br /&gt;
OPTS=&amp;quot;-h &#039;ldaps:// ldap://127.0.0.1&#039;&amp;quot;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* Start LDAP server&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
rc-update add slapd default&lt;br /&gt;
/etc/init.d/slapd start&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* Configure LDAP client utilities&lt;br /&gt;
&lt;br /&gt;
Edit /etc/openldap/ldap.conf&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
BASE	dc=example,dc=com&lt;br /&gt;
URI	ldaps://host.example.com&lt;br /&gt;
&lt;br /&gt;
TLS_CACERT /etc/lighttpd/ca-crt.pem&lt;br /&gt;
TLS_CERT /etc/lighttpd/server-bundle.pem&lt;br /&gt;
TLS_KEY /etc/lighttpd/server-bundle.pem&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* Test LDAP server&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
ldapsearch -z 3&lt;br /&gt;
ldapsearch -z 3 -x -W -D cn=admin,dc=example,dc=com&lt;br /&gt;
ldapsearch -z 3 -x -W -D cn=address1,dc=example,dc=com&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* Configure RoundCube webmail for email lookups&lt;br /&gt;
&lt;br /&gt;
In order to enable php-ldap support you need to restart lighttpd server&lt;br /&gt;
&lt;br /&gt;
 /etc/init.d/lighttpd restart&lt;br /&gt;
&lt;br /&gt;
Edit /usr/share/webapps/roundcube/config/main.inc.php:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
$rcmail_config[&#039;ldap_debug&#039;] = false;&lt;br /&gt;
...&lt;br /&gt;
$rcmail_config[&#039;address_book_type&#039;] = &#039;sql&#039;;&lt;br /&gt;
&lt;br /&gt;
$rcmail_config[&#039;ldap_public&#039;][&#039;example.com&#039;] = array(&lt;br /&gt;
  &#039;name&#039;          =&amp;gt; &#039;example.com&#039;,&lt;br /&gt;
  &#039;hosts&#039;         =&amp;gt; array(&#039;127.0.0.1&#039;),&lt;br /&gt;
  &#039;port&#039;          =&amp;gt; 389,&lt;br /&gt;
  &#039;use_tls&#039;         =&amp;gt; false,&lt;br /&gt;
  &#039;user_specific&#039; =&amp;gt; false,&lt;br /&gt;
  &#039;base_dn&#039;       =&amp;gt; &#039;dc=example,dc=com&#039;,&lt;br /&gt;
  &#039;bind_dn&#039;       =&amp;gt; &#039;&#039;,&lt;br /&gt;
  &#039;bind_pass&#039;     =&amp;gt; &#039;&#039;,&lt;br /&gt;
  &#039;writable&#039;      =&amp;gt; false,&lt;br /&gt;
  &#039;LDAP_Object_Classes&#039; =&amp;gt; array(&amp;quot;top&amp;quot;, &amp;quot;exampleBox&amp;quot;),&lt;br /&gt;
  &#039;required_fields&#039;     =&amp;gt; array(&amp;quot;cn&amp;quot;, &amp;quot;sn&amp;quot;, &amp;quot;mail&amp;quot;),&lt;br /&gt;
  &#039;LDAP_rdn&#039;      =&amp;gt; &#039;mail&#039;,&lt;br /&gt;
  &#039;ldap_version&#039;  =&amp;gt; 3,&lt;br /&gt;
  &#039;search_fields&#039; =&amp;gt; array(&#039;mail&#039;, &#039;cn&#039;, &#039;sn&#039;, &#039;givenName&#039;),&lt;br /&gt;
  &#039;name_field&#039;    =&amp;gt; &#039;cn&#039;,&lt;br /&gt;
  &#039;email_field&#039;   =&amp;gt; &#039;mail&#039;,&lt;br /&gt;
  &#039;surname_field&#039; =&amp;gt; &#039;sn&#039;,&lt;br /&gt;
  &#039;firstname_field&#039; =&amp;gt; &#039;gn&#039;,&lt;br /&gt;
  &#039;sort&#039;          =&amp;gt; &#039;cn&#039;,&lt;br /&gt;
  &#039;scope&#039;         =&amp;gt; &#039;sub&#039;,&lt;br /&gt;
  &#039;filter&#039;        =&amp;gt; &#039;(objectClass=*)&#039;, // Construct here any filter you need&lt;br /&gt;
  &#039;fuzzy_search&#039;  =&amp;gt; true);&lt;br /&gt;
&lt;br /&gt;
$rcmail_config[&#039;autocomplete_addressbooks&#039;] = array(&#039;sql&#039;,&#039;example.com&#039;);&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* Fix PostfixAdmin to work with the new table definition&lt;br /&gt;
&lt;br /&gt;
Edit /var/www/domains/example.com/www/list-domain.php. Replace the line:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
   SELECT domain.* , COUNT( DISTINCT mailbox.username ) AS mailbox_count&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
With the lines:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
   SELECT domain.domain, domain.description, domain.aliases, domain.mailboxes,&lt;br /&gt;
   domain.maxquota, domain.quota, domain.transport, domain.backupmx, domain.created,&lt;br /&gt;
   domain.modified, domain.active, COUNT( DISTINCT mailbox.username ) AS mailbox_count&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== log rotation ==&lt;br /&gt;
&lt;br /&gt;
Ensure the busybox cron service is started and is configured to auto-start:&lt;br /&gt;
&lt;br /&gt;
 /etc/init.d/cron start&lt;br /&gt;
 rc-update add cron default&lt;br /&gt;
&lt;br /&gt;
Add log rotate:&lt;br /&gt;
&lt;br /&gt;
 apk add logrotate&lt;br /&gt;
&lt;br /&gt;
Edit &#039;&#039;/etc/logrotate.conf&#039;&#039; as desired, but the defaults should be sufficient for most people.&lt;br /&gt;
&lt;br /&gt;
== Optional: Configure Web Server Virtual Domains ==&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Note:&#039;&#039;&#039; These steps can be done &#039;&#039;in addition to&#039;&#039; the default lighttpd configuration above, which allows you to access the ACF, PostfixAdmin and Roundcube interfaces as subfolders of one web service.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Note:&#039;&#039;&#039; If you provide SSL access for multiple domain site you may need to follow http://redmine.lighttpd.net/projects/lighttpd/wiki/Docs:SSL#SSL-on-multiple-domains in order to provide multi-domain certificates. If you would like to redirect hosts to their secure equivalents use the following instructions http://redmine.lighttpd.net/projects/lighttpd/wiki/HowToRedirectHttpToHttps.&lt;br /&gt;
&lt;br /&gt;
This server hosts three separate web applications, and these can be handled as three &#039;&#039;different&#039;&#039; virtual domains on the same web server. They will be distinguished by their DNS names, so you can choose domains for the three separate services (or at least the ones you want to publish):&lt;br /&gt;
&lt;br /&gt;
* ACF - Alpine Configuration Framework for managing the server&lt;br /&gt;
* PostfixAdmin - for managing the postfix installation&lt;br /&gt;
* RoundCube - for accessing individual mailboxes&lt;br /&gt;
&lt;br /&gt;
Choose three different domains (from here on known as ACF_DOMAIN, POSTFIXADMIN_DOMAIN, and ROUNDCUBE_DOMAIN) and configure DNS for all three to point to the IP address of your host. These should be DNS &#039;&#039;&#039;A&#039;&#039;&#039; records.&lt;br /&gt;
&lt;br /&gt;
Then, configure lighttpd to handle the three separate domains by editing /etc/lighttpd/lighttpd.conf:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 $HTTP[&amp;quot;host&amp;quot;] == &amp;quot;ACF_DOMAIN&amp;quot; {&lt;br /&gt;
	simple-vhost.server-root   = &amp;quot;/var/www/domains/&amp;quot;&lt;br /&gt;
	simple-vhost.default-host  = &amp;quot;/ACF_DOMAIN/&amp;quot;&lt;br /&gt;
	simple-vhost.document-root = &amp;quot;www/&amp;quot;&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
 $HTTP[&amp;quot;host&amp;quot;] == &amp;quot;POSTFIXADMIN_DOMAIN&amp;quot; {&lt;br /&gt;
	simple-vhost.server-root   = &amp;quot;/var/www/domains/&amp;quot;&lt;br /&gt;
	simple-vhost.default-host  = &amp;quot;/POSTFIXADMIN_DOMAIN/&amp;quot;&lt;br /&gt;
	simple-vhost.document-root = &amp;quot;www/&amp;quot;&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
 $HTTP[&amp;quot;host&amp;quot;] == &amp;quot;ROUNDCUBE_DOMAIN&amp;quot; {&lt;br /&gt;
	simple-vhost.server-root   = &amp;quot;/var/www/domains/&amp;quot;&lt;br /&gt;
	simple-vhost.default-host  = &amp;quot;/ROUNDCUBE_DOMAIN/&amp;quot;&lt;br /&gt;
	simple-vhost.document-root = &amp;quot;www/&amp;quot;&lt;br /&gt;
 }&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
And, then link the appropriate www directories.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  mkdir -p /var/www/domains/ACF_DOMAIN&lt;br /&gt;
  ln -s /usr/share/acf/www /var/www/domains/ACF_DOMAIN/www&lt;br /&gt;
&lt;br /&gt;
  mkdir -p /var/www/domains/POSTFIXADMIN_DOMAIN&lt;br /&gt;
  ln -s /var/www/domains/host.example.com/www/postfixadmin /var/www/domains/POSTFIXADMIN_DOMAIN/www&lt;br /&gt;
&lt;br /&gt;
  mkdir -p /var/www/domains/ROUNDCUBE_DOMAIN&lt;br /&gt;
  ln -s /usr/share/webapps/roundcube /var/www/domains/ROUNDCUBE_DOMAIN/www&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;/div&gt;</summary>
		<author><name>Djhughes</name></author>
	</entry>
	<entry>
		<id>https://wiki.alpinelinux.org/w/index.php?title=ISP_Mail_Server_HowTo&amp;diff=3782</id>
		<title>ISP Mail Server HowTo</title>
		<link rel="alternate" type="text/html" href="https://wiki.alpinelinux.org/w/index.php?title=ISP_Mail_Server_HowTo&amp;diff=3782"/>
		<updated>2010-05-13T03:00:54Z</updated>

		<summary type="html">&lt;p&gt;Djhughes: no ca cert with setup-acf&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== A Full Service Mail Server ==&lt;br /&gt;
&lt;br /&gt;
The goal of this document is to describe how to set up postfix, dovecot, clamav, dspam, roundecube, and postfixadmin for a full-featured &amp;quot;ISP&amp;quot; level mail server.&lt;br /&gt;
&lt;br /&gt;
The server must provide:&lt;br /&gt;
&lt;br /&gt;
* multiple virtual domains&lt;br /&gt;
* admins for each domain (to add/remove virtual accounts)&lt;br /&gt;
* Quota support per domain / account&lt;br /&gt;
* downloading email via IMAP / IMAPS / POP3 / POP3S&lt;br /&gt;
* relaying email for authenticated users with TLS or SSL (Submission / SMTPS protocol)&lt;br /&gt;
* Standard filters (virus/spam/rbl/etc)&lt;br /&gt;
* Web mail client&lt;br /&gt;
* Value Add services&lt;br /&gt;
&lt;br /&gt;
== Set up Lighttpd + PHP ==&lt;br /&gt;
&lt;br /&gt;
PostfixAdmin needs php pgpsql and imap modules, so we do it in this step.&lt;br /&gt;
&lt;br /&gt;
  apk add lighttpd php php-pgsql php-imap&lt;br /&gt;
&lt;br /&gt;
Stop and remove mini_httpd, and move ACF to lighttpd;  We are setting this up to be a multi-domain virtual web server (replace host.example.com with the actual domain):&lt;br /&gt;
&lt;br /&gt;
  mkdir -p /var/www/domains/host.example.com/www&lt;br /&gt;
  ln -s /usr/share/acf/www /var/www/domains/host.example.com/www/acf&lt;br /&gt;
&lt;br /&gt;
Edit /var/www/domains/host.example.com/index.html to put a simple redirection page:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;lt;!DOCTYPE HTML PUBLIC &amp;quot;-//W3C//DTD HTML 4.01//EN&amp;quot; &amp;quot;http://www.w3.org/TR/html4/strict.dtd&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;html lang=&amp;quot;en&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;head&amp;gt;&lt;br /&gt;
&amp;lt;meta http-equiv=&amp;quot;Content-Type&amp;quot; content=&amp;quot;text/html; charset=ISO-8859-1&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;title&amp;gt;host.example.com Redirector&amp;lt;/title&amp;gt;&lt;br /&gt;
&amp;lt;/head&amp;gt;&lt;br /&gt;
&amp;lt;body&amp;gt;&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;&amp;lt;a href=&amp;quot;/acf&amp;quot;&amp;gt;ACF&amp;lt;/a&amp;gt;&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;&amp;lt;a href=&amp;quot;/postfixadmin&amp;quot;&amp;gt;PostfixAdmin&amp;lt;/a&amp;gt;&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;&amp;lt;a href=&amp;quot;/roundcube&amp;quot;&amp;gt;Roundcube&amp;lt;/a&amp;gt;&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
&amp;lt;/body&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Edit /etc/lighttpd/mod_cgi.conf to serve haserl files by adding a &amp;quot;&amp;quot; =&amp;gt; &amp;quot;&amp;quot; cgi handler and to treat /acf/cgi-bin as a CGI directory (remove the &#039;^&#039;)&lt;br /&gt;
&lt;br /&gt;
 $HTTP[&amp;quot;url&amp;quot;] =~ &amp;quot;/cgi-bin/&amp;quot; {&lt;br /&gt;
     # disable directory listings&lt;br /&gt;
     dir-listing.activate = &amp;quot;disable&amp;quot;&lt;br /&gt;
     # only allow cgi&#039;s in this directory&lt;br /&gt;
     cgi.assign = (&lt;br /&gt;
 		&amp;quot;.pl&amp;quot;	=&amp;gt;	&amp;quot;/usr/bin/perl&amp;quot;,&lt;br /&gt;
 		&amp;quot;.cgi&amp;quot;	=&amp;gt;	&amp;quot;/usr/bin/perl&amp;quot;,&lt;br /&gt;
 		&amp;quot;&amp;quot; =&amp;gt; &amp;quot;&amp;quot;&lt;br /&gt;
 	)&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
Add these lines to /etc/lighttpd/lighttpd.conf to point to the new document root, and set it up to listen on port 443 (replace &#039;&#039;host.example.com&#039;&#039; with the actual domain and &#039;&#039;ip_address_of_server&#039;&#039; with the actual IP address):&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
simple-vhost.server-root   = &amp;quot;/var/www/domains/&amp;quot;&lt;br /&gt;
simple-vhost.default-host  = &amp;quot;/host.example.com/&amp;quot;&lt;br /&gt;
simple-vhost.document-root = &amp;quot;www/&amp;quot;&lt;br /&gt;
&lt;br /&gt;
$SERVER[&amp;quot;socket&amp;quot;] == &amp;quot;ip_address_of_server:443&amp;quot; {&lt;br /&gt;
ssl.engine    = &amp;quot;enable&amp;quot;&lt;br /&gt;
ssl.pemfile   = &amp;quot;/etc/lighttpd/server-bundle.pem&amp;quot;&lt;br /&gt;
ssl.ca-file   = &amp;quot;/etc/lighttpd/ca-crt.pem&amp;quot;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Ensure that the simple_vhosts module is loaded, as well as the cgi config scripts by uncommenting the following lines in /etc/lighttpd/lighttpd.conf&lt;br /&gt;
&lt;br /&gt;
 server.modules = (&lt;br /&gt;
     #  other modules may be listed&lt;br /&gt;
     &amp;quot;mod_simple_vhost&amp;quot;, &lt;br /&gt;
     #  other modules may be listed&lt;br /&gt;
  .&lt;br /&gt;
  .&lt;br /&gt;
  .&lt;br /&gt;
     include &amp;quot;mod_cgi.conf&amp;quot;&lt;br /&gt;
 &lt;br /&gt;
     include &amp;quot;mod_fastcgi.conf&amp;quot;&lt;br /&gt;
 &lt;br /&gt;
Get a web certificate, and install it.  You have two options: 1. If you want to use a self-signed cert, you can use the instructions found at [[Generating SSL certs with ACF]] or [[Generating SSL certs with ACF 1.9]] to generate it. 2. Use the certificate created with the &#039;&#039;&#039;setup-acf&#039;&#039;&#039; command. &lt;br /&gt;
&lt;br /&gt;
If you create your own self-signed certificate, you can create the &amp;quot;server-bundle.pem&amp;quot; and the &amp;quot;ca-crt.pem&amp;quot; file with these commands:&lt;br /&gt;
&lt;br /&gt;
  openssl pkcs12 -nokeys -cacerts -in certificate.pfx  -out /etc/lighttpd/ca-crt.pem&lt;br /&gt;
  openssl pkcs12 -nodes -in certificate.pfx -out /etc/lighttpd/server-bundle.pem&lt;br /&gt;
  chown root:root /etc/lighttpd/server-bundle.pem&lt;br /&gt;
  chmod 400 /etc/lighttpd/server-bundle.pem&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Note:&#039;&#039;&#039; The server certificate &#039;&#039;and&#039;&#039; key are in the server-bundle.pem file, so it is critical that the file be read-only by user &amp;quot;root&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
If you prefer to just use the default certificate created with the &#039;&#039;&#039;setup-acf&#039;&#039;&#039; command, then you will need to do the following:&lt;br /&gt;
&lt;br /&gt;
  setup-acf&lt;br /&gt;
&lt;br /&gt;
During the above process, mini_httpd will be started, if it isn&#039;t already, and a certificate will be created. Once you have completed the setup-acf steps, do the following to move the certificate files to the correct location for lighttpd to use.&lt;br /&gt;
&lt;br /&gt;
  mv /etc/ssl/mini_httpd/server.pem /etc/lighttpd/server-bundle.pem&lt;br /&gt;
  chown root:root /etc/lighttpd/server-bundle.pem&lt;br /&gt;
  chmod 400 /etc/lighttpd/server-bundle.pem&lt;br /&gt;
&lt;br /&gt;
Stop and remove mini_httpd; start lighttpd, test&lt;br /&gt;
&lt;br /&gt;
  /etc/init.d/mini_httpd stop&lt;br /&gt;
  rc-update del mini_httpd&lt;br /&gt;
  apk del mini_httpd&lt;br /&gt;
  rc-update add lighttpd&lt;br /&gt;
  /etc/init.d/lighttpd start&lt;br /&gt;
&lt;br /&gt;
At this point you should be able to see ACF being served with lighttpd (Note: this will work well with alpine 1.10. With earlier versions there will be problems.)  https://host.example.com/acf/&lt;br /&gt;
&lt;br /&gt;
== Install Postgresql ==&lt;br /&gt;
&lt;br /&gt;
Add and configure postgresql&lt;br /&gt;
&lt;br /&gt;
  apk add acf-postgresql postgresql-client&lt;br /&gt;
  /etc/init.d/postgresql setup&lt;br /&gt;
  /etc/init.d/postgresql start&lt;br /&gt;
  rc-update add postgresql&lt;br /&gt;
&lt;br /&gt;
At this point any user can connect to the sql server with &amp;quot;trust&amp;quot; mechanism.  If you want to enforce password authentication (you probably do) edit /var/lib/postgresql/8.4/data/pg_hba.conf&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
  Editme: What should we recommend?&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Create the postfix database:&lt;br /&gt;
&lt;br /&gt;
  psql -U postgres&lt;br /&gt;
   create user postfix with password &#039;******&#039;;&lt;br /&gt;
   create database postfix owner postfix;&lt;br /&gt;
   \c postfix&lt;br /&gt;
   create language plpgsql;&lt;br /&gt;
   \q&lt;br /&gt;
&lt;br /&gt;
(Of course, use your selected password where ******* is shown above.)&lt;br /&gt;
&lt;br /&gt;
== Install PostfixAdmin ==&lt;br /&gt;
&lt;br /&gt;
We are going to install the postfix admin web front-end before we install the mail server.  This just creates an interface to populate the SQL tables that postfix and dovecot will use.&lt;br /&gt;
&lt;br /&gt;
Download PostfixAdmin from Sourceforge.  When these instructions were written, 2.3 was the current release, so (replace host.example.com with the actual domain):&lt;br /&gt;
 wget http://downloads.sourceforge.net/project/postfixadmin/postfixadmin/postfixadmin_2.3.tar.gz&lt;br /&gt;
 tar zxvf postfixadmin_2.3.tar.gz&lt;br /&gt;
 mkdir -p /var/www/domains/host.example.com/www/postfixadmin&lt;br /&gt;
 mv postfixadmin-2.3/* /var/www/domains/host.example.com/www/postfixadmin&lt;br /&gt;
 rm -rf postfixadmin*&lt;br /&gt;
&lt;br /&gt;
Edit /var/www/domains/host.example.com/www/postfixadmin/config.inc.php and modify at least these lines (replace host.example.com with the actual domain):&lt;br /&gt;
&lt;br /&gt;
 $CONF[&#039;configured&#039;] = true;&lt;br /&gt;
 $CONF[&#039;setup_password&#039;] = &amp;quot;&amp;quot;;  &amp;lt;&amp;lt; Don&#039;t change this yet&lt;br /&gt;
 $CONF[&#039;database_type&#039;] = &#039;pgsql&#039;;&lt;br /&gt;
 $CONF[&#039;database_host&#039;] = &#039;localhost&#039;;&lt;br /&gt;
 $CONF[&#039;database_user&#039;] = &#039;postfix&#039;;&lt;br /&gt;
 $CONF[&#039;database_password&#039;] = &#039;*****&#039;;   &amp;lt;&amp;lt; The password you chose above&lt;br /&gt;
 $CONF[&#039;database_name&#039;] = &#039;postfix&#039;;&lt;br /&gt;
 $CONF[&#039;database_prefix&#039;] = &amp;quot;&amp;quot;;&lt;br /&gt;
 $CONF[&#039;admin_email&#039;] = &#039;you@some.email.com&#039;;  &amp;lt;&amp;lt; Your email address &lt;br /&gt;
 $CONF[&#039;encrypt&#039;] = &#039;md5crypt&#039;;&lt;br /&gt;
 $CONF[&#039;authlib_default_flavor&#039;] = &#039;md5raw&#039;;&lt;br /&gt;
 $CONF[&#039;dovecotpw&#039;] = &amp;quot;/usr/sbin/dovecotpw&amp;quot;;&lt;br /&gt;
 $CONF[&#039;domain_path&#039;] = &#039;YES&#039;;&lt;br /&gt;
 $CONF[&#039;domain_in_mailbox&#039;] = &#039;NO&#039;;&lt;br /&gt;
 $CONF[&#039;aliases&#039;] = &#039;10&#039;;                       &lt;br /&gt;
 $CONF[&#039;mailboxes&#039;] = &#039;10&#039;;&lt;br /&gt;
 $CONF[&#039;maxquota&#039;] = &#039;10&#039;;&lt;br /&gt;
 $CONF[&#039;quota&#039;] = &#039;YES&#039;;&lt;br /&gt;
 $CONF[&#039;quota_multiplier&#039;] = &#039;1024000&#039;;&lt;br /&gt;
 $CONF[&#039;vacation&#039;] = &#039;NO&#039;; &lt;br /&gt;
 $CONF[&#039;vacation_control&#039;] =&#039;NO&#039;;&lt;br /&gt;
 $CONF[&#039;vacation_control_admin&#039;] = &#039;NO&#039;;&lt;br /&gt;
 $CONF[&#039;alias_control&#039;] = &#039;YES&#039;;&lt;br /&gt;
 $CONF[&#039;alias_control_admin&#039;] = &#039;YES&#039;;&lt;br /&gt;
 $CONF[&#039;special_alias_control&#039;] = &#039;YES&#039;;&lt;br /&gt;
 $CONF[&#039;fetchmail&#039;] = &#039;NO&#039;;&lt;br /&gt;
 $CONF[&#039;user_footer_link&#039;] = &amp;quot;http://host.example.com/postfixadmin&amp;quot;;&lt;br /&gt;
 $CONF[&#039;footer_link&#039;] = &#039;http://host.example.com/postfixadmin/main.php&#039;;&lt;br /&gt;
 $CONF[&#039;create_mailbox_subdirs_prefix&#039;]=&amp;quot;&amp;quot;;  &lt;br /&gt;
 $CONF[&#039;used_quotas&#039;] = &#039;YES&#039;;   &lt;br /&gt;
 $CONF[&#039;new_quota_table&#039;] = &#039;YES&#039;;  &lt;br /&gt;
&lt;br /&gt;
You should further edit /var/www/domains/host.example.com/www/postfixadmin/config.inc.php and replace all instances of &amp;quot;change-this-to-your.domain.tld&amp;quot; with your actual mail domain. This can be done with busybox sed (replace example.com with your domain name):&lt;br /&gt;
&lt;br /&gt;
 sed -i -e &#039;s/change-this-to-your.domain.tld/example.com/g&#039; /var/www/domains/host.example.com/www/postfixadmin/config.inc.php&lt;br /&gt;
&lt;br /&gt;
Go to http://host.example.com/postfixadmin/setup.php&lt;br /&gt;
&lt;br /&gt;
Create the password hash, add it to the config.inc.php file&lt;br /&gt;
&lt;br /&gt;
Go back to http://host.example.com/postfixadmin/setup.php&lt;br /&gt;
&lt;br /&gt;
Create superadmin account.&lt;br /&gt;
&lt;br /&gt;
== Install Postfix ==&lt;br /&gt;
&lt;br /&gt;
Create a user for the virtual mail delivery, and get its uid/gid (you&#039;ll need the numeric uid/gid for postfix)&lt;br /&gt;
&lt;br /&gt;
 adduser vmail -H -D -s /bin/false&lt;br /&gt;
 grep vmail /etc/passwd&lt;br /&gt;
&lt;br /&gt;
(In examples below, we use 1006/1006 for the uid/gid)&lt;br /&gt;
&lt;br /&gt;
Create the mail directory, and assign vmail as the owner&lt;br /&gt;
 mkdir -p /var/mail/domains&lt;br /&gt;
 chown -R vmail:vmail /var/mail/domains&lt;br /&gt;
 &lt;br /&gt;
&lt;br /&gt;
Install postfix&lt;br /&gt;
&lt;br /&gt;
 apk add acf-postfix postfix-pgsql&lt;br /&gt;
&lt;br /&gt;
Edit the /etc/postfix/main.cf file. Here&#039;s an example (don&#039;t forget to replace the uid/gid):&lt;br /&gt;
&lt;br /&gt;
 myhostname=host.example.com&lt;br /&gt;
 mydomain=example.com&lt;br /&gt;
 &lt;br /&gt;
 mydestination = localhost.$mydomain, localhost&lt;br /&gt;
 mynetworks_style = subnet&lt;br /&gt;
 mynetworks = 127.0.0.0/8&lt;br /&gt;
 &lt;br /&gt;
 virtual_mailbox_domains = proxy:pgsql:/etc/postfix/sql/pgsql_virtual_domains_maps.cf&lt;br /&gt;
 virtual_alias_maps = proxy:pgsql:/etc/postfix/sql/pgsql_virtual_alias_maps.cf,&lt;br /&gt;
        proxy:pgsql:/etc/postfix/sql/pgsql_virtual_alias_domain_maps.cf,&lt;br /&gt;
        proxy:pgsql:/etc/postfix/sql/pgsql_virtual_alias_domain_catchall_maps.cf&lt;br /&gt;
 &lt;br /&gt;
 virtual_mailbox_maps = proxy:pgsql:/etc/postfix/sql/pgsql_virtual_mailbox_maps.cf,&lt;br /&gt;
        proxy:pgsql:/etc/postfix/sql/pgsql_virtual_alias_domain_mailbox_maps.cf&lt;br /&gt;
 &lt;br /&gt;
 virtual_mailbox_base = /var/mail/domains/&lt;br /&gt;
 virtual_gid_maps = static:1006&lt;br /&gt;
 virtual_uid_maps = static:1006&lt;br /&gt;
 virtual_minimum_uid = 100&lt;br /&gt;
 virtual_transport = virtual&lt;br /&gt;
 &lt;br /&gt;
 &lt;br /&gt;
 # This next command means you must create a virtual&lt;br /&gt;
 # domain for the host itself - ALL mail goes through&lt;br /&gt;
 # The virtual transport&lt;br /&gt;
 &lt;br /&gt;
 mailbox_transport = virtual&lt;br /&gt;
 local_transport = virtual&lt;br /&gt;
 local_transport_maps = $virtual_mailbox_maps&lt;br /&gt;
 &lt;br /&gt;
 smtpd_helo_required = yes&lt;br /&gt;
 disable_vrfy_command = yes&lt;br /&gt;
 message_size_limit = 10240000&lt;br /&gt;
 queue_minfree = 51200000&lt;br /&gt;
 &lt;br /&gt;
 smtpd_sender_restrictions =&lt;br /&gt;
        permit_mynetworks,&lt;br /&gt;
        reject_non_fqdn_sender,&lt;br /&gt;
        reject_unknown_sender_domain&lt;br /&gt;
 &lt;br /&gt;
 smtpd_recipient_restrictions =&lt;br /&gt;
        reject_non_fqdn_recipient,&lt;br /&gt;
        reject_unknown_recipient_domain,&lt;br /&gt;
        permit_mynetworks,&lt;br /&gt;
        permit_sasl_authenticated,&lt;br /&gt;
        reject_unauth_destination,&lt;br /&gt;
        reject_rbl_client dnsbl.sorbs.net,&lt;br /&gt;
        reject_rbl_client zen.spamhaus.org,&lt;br /&gt;
        reject_rbl_client bl.spamcop.net&lt;br /&gt;
 &lt;br /&gt;
 smtpd_data_restrictions = reject_unauth_pipelining&lt;br /&gt;
 &lt;br /&gt;
 # we will use this later - This prevents cleartext authentication&lt;br /&gt;
 # for relaying&lt;br /&gt;
 smtpd_tls_auth_only = yes&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Now we need to create a *bunch* of files so that postfix can get the delivery information out of sql. Here&#039;s a shell script to create the scripts.  Change PGPW to the password for the postfix user of the postfix SQL database.&lt;br /&gt;
&lt;br /&gt;
 cd /etc/postfix&lt;br /&gt;
 mkdir sql&lt;br /&gt;
 PGPW=&amp;quot;ChangeMe&amp;quot;&lt;br /&gt;
 &lt;br /&gt;
 cat - &amp;lt;&amp;lt;EOF &amp;gt;sql/pgsql_virtual_alias_domain_catchall_maps.cf&lt;br /&gt;
 user=postfix&lt;br /&gt;
 password = $PGPW&lt;br /&gt;
 hosts = localhost&lt;br /&gt;
 dbname = postfix&lt;br /&gt;
 query = Select goto From alias,alias_domain where alias_domain.alias_domain = &#039;%d&#039; and alias.address = &#039;@&#039; ||  alias_domain.target_domain and alias.active = true and alias_domain.active= true &lt;br /&gt;
 EOF&lt;br /&gt;
 &lt;br /&gt;
 cat - &amp;lt;&amp;lt;EOF &amp;gt;sql/pgsql_virtual_alias_domain_mailbox_maps.cf&lt;br /&gt;
 user=postfix&lt;br /&gt;
 password = $PGPW&lt;br /&gt;
 hosts = localhost&lt;br /&gt;
 dbname = postfix&lt;br /&gt;
 query = Select maildir from mailbox,alias_domain where alias_domain.alias_domain = &#039;%d&#039; and mailbox.username = &#039;%u&#039; || &#039;@&#039; || alias_domain.target_domain and mailbox.active = true and alias_domain.active&lt;br /&gt;
 EOF&lt;br /&gt;
 &lt;br /&gt;
 cat - &amp;lt;&amp;lt;EOF &amp;gt;sql/pgsql_virtual_alias_domain_maps.cf&lt;br /&gt;
 user=postfix&lt;br /&gt;
 password = $PGPW&lt;br /&gt;
 hosts = localhost&lt;br /&gt;
 dbname = postfix&lt;br /&gt;
 query = select goto from alias,alias_domain where alias_domain.alias_domain=&#039;%d&#039; and alias.address = &#039;%u&#039; || &#039;@&#039; || alias_domain.target_domain and alias.active= true and alias_domain.active= true&lt;br /&gt;
 EOF&lt;br /&gt;
 &lt;br /&gt;
 cat - &amp;lt;&amp;lt;EOF &amp;gt;sql/pgsql_virtual_alias_maps.cf&lt;br /&gt;
 user=postfix&lt;br /&gt;
 password = $PGPW&lt;br /&gt;
 hosts = localhost&lt;br /&gt;
 dbname = postfix&lt;br /&gt;
 query = Select goto From alias Where address=&#039;%s&#039; and active =&#039;1&#039;&lt;br /&gt;
 EOF&lt;br /&gt;
 &lt;br /&gt;
 cat - &amp;lt;&amp;lt;EOF &amp;gt;sql/pgsql_virtual_domains_maps.cf&lt;br /&gt;
 user=postfix&lt;br /&gt;
 password = $PGPW&lt;br /&gt;
 hosts = localhost&lt;br /&gt;
 dbname = postfix&lt;br /&gt;
 query = Select domain from domain where domain=&#039;%s&#039; and active=&#039;1&#039;&lt;br /&gt;
 EOF&lt;br /&gt;
 &lt;br /&gt;
 cat - &amp;lt;&amp;lt;EOF &amp;gt;sql/pgsql_virtual_mailbox_maps.cf&lt;br /&gt;
 user=postfix&lt;br /&gt;
 password = $PGPW&lt;br /&gt;
 hosts = localhost&lt;br /&gt;
 dbname = postfix&lt;br /&gt;
 query = Select maildir from mailbox where username=&#039;%s&#039; and active=true&lt;br /&gt;
 EOF&lt;br /&gt;
 &lt;br /&gt;
 chown -R postfix:postfix sql&lt;br /&gt;
 chmod 640 sql/*&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
At this point you should be able to start up postfix&lt;br /&gt;
 &lt;br /&gt;
 newaliases  # so postfix is happy...&lt;br /&gt;
 /etc/init.d/postfix start&lt;br /&gt;
 rc-update add postfix&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Create a domain in PostfixAdmin and test ===&lt;br /&gt;
&lt;br /&gt;
Go to http://host.example.com/postfixadmin/&lt;br /&gt;
&lt;br /&gt;
Log in using the superadmin account, create a domain for the local box (e.g. example.com), and create a user mailbox (e.g. root).&lt;br /&gt;
&lt;br /&gt;
From the machine, send a test message:&lt;br /&gt;
&lt;br /&gt;
 sendmail -t root@example.com&lt;br /&gt;
 subject: test&lt;br /&gt;
 .&lt;br /&gt;
 ^d&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
In /var/log/mail.log (or /var/log/messages, if you still have busybox syslogd running) you should see the message queued.  The message should be in /var/mail/domains/example.com/root/new&lt;br /&gt;
&lt;br /&gt;
== Install Dovecot ==&lt;br /&gt;
&lt;br /&gt;
Dovecot is the POP3/IMAP server to retrieve mail.&lt;br /&gt;
&lt;br /&gt;
As before, we install dovecot: &lt;br /&gt;
&lt;br /&gt;
 apk add acf-dovecot dovecot-pgsql&lt;br /&gt;
&lt;br /&gt;
edit /etc/dovecot/dovecot.conf&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 # Select only the protocols you wish to support - all are listed in the next line&lt;br /&gt;
 protocols               =       imap imaps pop pop3s&lt;br /&gt;
 log_path                =       /var/log/dovecot.log&lt;br /&gt;
 info_log_path           =       /var/log/dovecot-info.log&lt;br /&gt;
 disable_plaintext_auth  =       no&lt;br /&gt;
&lt;br /&gt;
 # Authenticated IMAP&lt;br /&gt;
 ssl                     =       yes&lt;br /&gt;
 ssl_cert_file           =       /etc/lighttpd/server-bundle.pem&lt;br /&gt;
 ssl_key_file            =       /etc/lighttpd/server-bundle.pem&lt;br /&gt;
 auth_verbose            =       yes&lt;br /&gt;
 auth_debug              =       no&lt;br /&gt;
 mail_location           =       maildir:/var/mail/domains/%d/%n&lt;br /&gt;
 auth default    {&lt;br /&gt;
        mechanisms = plain&lt;br /&gt;
        passdb sql {&lt;br /&gt;
                args = /etc/dovecot/dovecot-sql.conf&lt;br /&gt;
                }&lt;br /&gt;
        userdb static {&lt;br /&gt;
                args =  uid=1006 gid=1006 home=/var/mail/domains/%d/%n&lt;br /&gt;
                }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Be sure to replace the uid and gid with the appropriate values for the vmail user.&lt;br /&gt;
&lt;br /&gt;
We need a certificate for SSL/TLS authentication, so in the example above, we use the lighttpd cert. That way when the cert is renewed/replaced, Dovecot will have access to the new cert as well.  &lt;br /&gt;
&lt;br /&gt;
Create the /etc/dovecot/dovecot-sql.conf file:&lt;br /&gt;
&lt;br /&gt;
 driver = pgsql&lt;br /&gt;
 connect = host=localhost dbname=postfix user=postfix password=********&lt;br /&gt;
 password_query = select username,password from mailbox where local_part = &#039;%n&#039; and domain = &#039;%d&#039;&lt;br /&gt;
 default_pass_scheme =  MD5-CRYPT&lt;br /&gt;
&lt;br /&gt;
Again, change the password above to your postfix user password, and protect the file from prying eyes:&lt;br /&gt;
&lt;br /&gt;
 chown root:root /etc/dovecot/dovecot-sql.conf&lt;br /&gt;
 chmod 600 /etc/dovecot/dovecot-sql.conf&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Start dovecot&lt;br /&gt;
 /etc/init.d/dovecot start&lt;br /&gt;
 rc-update add dovecot&lt;br /&gt;
&lt;br /&gt;
== Testing ==&lt;br /&gt;
&lt;br /&gt;
Make sure your firewall allows in ports 25(SMTP) 110 (POP3), 995 (POP3S), 143(IMAP), 993(IMAPS), or whatever subset you support.  &lt;br /&gt;
 &lt;br /&gt;
At this point, you should be able to:&lt;br /&gt;
 * Create a new domain and add users with PostfixAdmin&lt;br /&gt;
 * Send mail to those users via SMTP to port 25&lt;br /&gt;
 * Retrieve mail using the user&#039;s full email and password (e.g. username: user@example.com  password: ChangeMe)&lt;br /&gt;
&lt;br /&gt;
== Value Add Features ==&lt;br /&gt;
&lt;br /&gt;
If you followed the guide above, you now have a functional mail server with many interconnected parts.  The features below assume that the server is already running as described above.  You should be able to add any or all of these features below to further enhance the mail service.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Virus Scanning ===&lt;br /&gt;
&lt;br /&gt;
This procedure uses clamav and the postfix content_filter mechanism to scan inbound and outbound email for viruses.  Infected emails are dropped.  Clean emails are tagged with a &amp;quot;scanned by clamav&amp;quot; header.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* Install clamav and clamsmtp:&lt;br /&gt;
 apk add acf-clamav clamsmtp&lt;br /&gt;
* Edit the /etc/clamav/clamd.conf file if desired (not necessary in most cases)&lt;br /&gt;
* Edit /etc/clamsmtpd.conf and verify the following lines&lt;br /&gt;
 OutAddress: 10026&lt;br /&gt;
 Listen: 127.0.0.1:10025                                               &lt;br /&gt;
 Header: X-Virus-Scanned: ClamAV using ClamSMTP&lt;br /&gt;
 Action: drop&lt;br /&gt;
 User: clamav                                                      &lt;br /&gt;
* Start the daemons&lt;br /&gt;
 rc-update add clamd&lt;br /&gt;
 rc-update add clamsmtpd&lt;br /&gt;
 /etc/init.d/clamd start&lt;br /&gt;
 /etc/init.d/clamsmtpd start&lt;br /&gt;
* Verify clamsmtp is listening on port 10025:&lt;br /&gt;
 netstat -anp | grep clamsmtp&lt;br /&gt;
* [http://memberwebs.com/stef/software/clamsmtp/postfix.html Following the clamsmtp instructions]&lt;br /&gt;
** edit /etc/postfix/main.cf and add:&lt;br /&gt;
 content_filter = scan:[127.0.0.1]:10025                                                      &lt;br /&gt;
** edit /etc/postfix/master.cf and add&lt;br /&gt;
 # AV scan filter (used by content_filter)&lt;br /&gt;
 scan      unix  -       -       n       -       16      smtp&lt;br /&gt;
         -o smtp_send_xforward_command=yes&lt;br /&gt;
         -o smtp_enforce_tls=no&lt;br /&gt;
 # For injecting mail back into postfix from the filter&lt;br /&gt;
 127.0.0.1:10026 inet  n -       n       -       16      smtpd&lt;br /&gt;
         -o content_filter=&lt;br /&gt;
         -o receive_override_options=no_unknown_recipient_checks,no_header_body_checks&lt;br /&gt;
         -o smtpd_helo_restrictions=&lt;br /&gt;
         -o smtpd_client_restrictions=&lt;br /&gt;
         -o smtpd_sender_restrictions=&lt;br /&gt;
         -o smtpd_recipient_restrictions=permit_mynetworks,reject&lt;br /&gt;
         -o mynetworks_style=host&lt;br /&gt;
         -o smtpd_authorized_xforward_hosts=127.0.0.0/8&lt;br /&gt;
* postfix reload&lt;br /&gt;
* Send and email into a local virtual domain - it should have the &#039;&#039;X-Virus-Scanned: ClamAV using ClamSMTP&#039;&#039; header.&lt;br /&gt;
&lt;br /&gt;
=== Relay for Authenticated Users ===&lt;br /&gt;
&lt;br /&gt;
As configured above, the mail server accepts email from the Internet, but it does not relay email.  If it is a perimeter exchanger for a protected network, then you can add the protected networks to the &#039;&#039;mynetworks&#039;&#039; configuration line in /etc/postfix/main.cf&lt;br /&gt;
&lt;br /&gt;
This configuration change allows &#039;&#039;remote&#039;&#039; users to authenticate against the mail server and relay through it.  The rules for relaying are:&lt;br /&gt;
* Only authenticated users can relay&lt;br /&gt;
* Authentication Credentials must be encrypted with TLS or SSL&lt;br /&gt;
* Allow Submission and SMTPS ports for relaying (many consumer networks block port 25 - SMTP by default)&lt;br /&gt;
The process uses the dovecot authentication mechanism (used with IMAPS) to authenticate users before they are allowed to relay through postfix.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* Edit /etc/dovecot/dovecot.conf and add teh following inside the &#039;&#039;auth default&#039;&#039; stanza:&lt;br /&gt;
 # this is for postfix SASL (authenticated users can relay through us)&lt;br /&gt;
 socket listen {&lt;br /&gt;
                client {&lt;br /&gt;
                        path    = /var/spool/postfix/private/dovecot-auth.sock&lt;br /&gt;
                        mode    = 0660&lt;br /&gt;
                        user    = postfix&lt;br /&gt;
                        group   = postfix&lt;br /&gt;
                        }&lt;br /&gt;
                }&lt;br /&gt;
        }&lt;br /&gt;
* Restart dovecot&lt;br /&gt;
 /etc/init.d/dovecot restart&lt;br /&gt;
* Edit /etc/postfix/main.cf and add:&lt;br /&gt;
 # TLS Stuff -- since we allow SASL with tls *only*, we have to set up TLS first                    &lt;br /&gt;
 &lt;br /&gt;
 smtpd_tls_cert_file = /etc/lighttpd/server-bundle.pem&lt;br /&gt;
 smtpd_tls_key_file = /etc/lighttpd/server-bundle.pem&lt;br /&gt;
 smtpd_tls_CAfile = /etc/lighttpd/ca-crt.pem&lt;br /&gt;
 # If tls_security_level is set to &amp;quot;encrypt&amp;quot;, then SMTP rejects &lt;br /&gt;
 # unencrypted email (e.g. normal mail) which is bad.&lt;br /&gt;
 # By setting it to &amp;quot;may&amp;quot; you get TLS encrypted mail from google, slashdot, and other &lt;br /&gt;
 # interesting places.  Check your logs to see who&lt;br /&gt;
 smtpd_tls_security_level = may&lt;br /&gt;
 # Log info about the negotiated encryption levels&lt;br /&gt;
 smtpd_tls_received_header = yes&lt;br /&gt;
 smtpd_tls_loglevel = 1&lt;br /&gt;
 &lt;br /&gt;
 # SASL - this allows senders to authenticiate themselves&lt;br /&gt;
 # This along with &amp;quot;permit_sasl_authenticated&amp;quot; in smtpd_recipient_restrictions allows relaying&lt;br /&gt;
 smtpd_sasl_type = dovecot&lt;br /&gt;
 smtpd_sasl_path = private/dovecot-auth.sock&lt;br /&gt;
 smtpd_sasl_auth_enable = yes&lt;br /&gt;
 smtpd_sasl_authenticated_header = yes&lt;br /&gt;
 smtpd_tls_auth_only = yes&lt;br /&gt;
* Edit /etc/postfix/master.cf and enable the submission and smtps transports.  They are probably already at the top of your  master.cf file, just commented out:&lt;br /&gt;
 submission inet n       -       n       -       -       smtpd&lt;br /&gt;
   -o smtpd_tls_security_level=encrypt&lt;br /&gt;
   -o smtpd_sasl_auth_enable=yes&lt;br /&gt;
   -o smtpd_client_restrictions=permit_sasl_authenticated,reject&lt;br /&gt;
   -o milter_macro_daemon_name=ORIGINATING&lt;br /&gt;
 smtps     inet  n       -       n       -       -       smtpd&lt;br /&gt;
   -o smtpd_tls_security_level=encrypt&lt;br /&gt;
   -o smtpd_tls_wrappermode=yes&lt;br /&gt;
   -o smtpd_sasl_auth_enable=yes&lt;br /&gt;
   -o smtpd_client_restrictions=permit_sasl_authenticated,reject&lt;br /&gt;
   -o milter_macro_daemon_name=ORIGINATING&lt;br /&gt;
*Verfiy submission and smtps are defined in /etc/services&lt;br /&gt;
 grep &amp;quot;submission\|ssmtp&amp;quot; /etc/services&lt;br /&gt;
 submission	587/tcp				# mail message submission&lt;br /&gt;
 submission	587/udp&lt;br /&gt;
 smtps		465/tcp		ssmtp		# smtp protocol over TLS/SSL&lt;br /&gt;
 smtps		465/udp		ssmtp&lt;br /&gt;
* Restart postfix&lt;br /&gt;
 postfix reload&lt;br /&gt;
&lt;br /&gt;
At this point, you should be able to set up a mail client to relay through the server with TLS (port 587) or SSL (port 465)  Note that &amp;quot;plain&amp;quot; authentication is used because the underlying link is encrypted.  For example, in Thunderbird leave &amp;quot;secure authentication&amp;quot; unchecked, and choose STARTTLS (or TLS) for the connection security.&lt;br /&gt;
&lt;br /&gt;
=== Mailbox Quotas ===&lt;br /&gt;
&lt;br /&gt;
In the default configuration, PostfixAdmin knows about quotas, but they are not enforced.   Documentation on the web mentions the [http://vda.sourceforge.net vda patch to postfix] to enforce quotas.  The only bad thing... its a &#039;&#039;patch&#039;&#039;.   Postfix and Dovecot are both conservative systems, so if the patch isn&#039;t in the upstream source, we&#039;ll assume there&#039;s a good reason.   There is a way of using quotas without patches - and it involves using dovecot&#039;s [http://wiki.dovecot.org/LDA deliver] lda for local delivery.&lt;br /&gt;
&lt;br /&gt;
Note: As of Jan 2010, the documention is confusing, with multiple versions of dovecot, PostfixAdmin, and Mysql referenced.  These instructions apply to:&lt;br /&gt;
* Postgresql 8.4.2 &lt;br /&gt;
* PostfixAdmin 2.3 &lt;br /&gt;
* Dovecot 1.2.11&lt;br /&gt;
* Postfix 2.6.5&lt;br /&gt;
&lt;br /&gt;
Presumably later versions will work the same, but if not, please update the documentation and versions above.&lt;br /&gt;
&lt;br /&gt;
* Update /etc/dovecot/dovecot.conf (old lines shown commented out):&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
# old postfix &lt;br /&gt;
#       userdb static {&lt;br /&gt;
#               args =  uid=1006 gid=1006 home=/var/mail/domains/%d/%n&lt;br /&gt;
#               }&lt;br /&gt;
&lt;br /&gt;
# new quota support:&lt;br /&gt;
        userdb prefetch {&lt;br /&gt;
                }&lt;br /&gt;
&lt;br /&gt;
        userdb sql {&lt;br /&gt;
                args = /etc/dovecot/dovecot-sql.conf&lt;br /&gt;
                }&lt;br /&gt;
&lt;br /&gt;
        socket listen {&lt;br /&gt;
                client {&lt;br /&gt;
                        path    = /var/spool/postfix/private/dovecot-auth.sock&lt;br /&gt;
                        mode    = 0660&lt;br /&gt;
                        user    = postfix&lt;br /&gt;
                        group   = postfix&lt;br /&gt;
                        }&lt;br /&gt;
                # These lines below are for the deliver lda&lt;br /&gt;
                master {&lt;br /&gt;
                        path =  /var/run/dovecot/auth-master&lt;br /&gt;
                        mode    = 0660&lt;br /&gt;
                        user    = vmail&lt;br /&gt;
                        group   = vmail&lt;br /&gt;
                        }&lt;br /&gt;
                }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
protocol imap {                                                               &lt;br /&gt;
         mail_plugins = quota imap_quota                                       &lt;br /&gt;
         }                                                                     &lt;br /&gt;
                                                                              &lt;br /&gt;
protocol pop3 {                                                               &lt;br /&gt;
         mail_plugins = quota                                                  &lt;br /&gt;
         }                                                                     &lt;br /&gt;
                                                                              &lt;br /&gt;
dict {                                                                        &lt;br /&gt;
        quotadict = pgsql:/etc/dovecot/dovecot-dict-quota.conf                &lt;br /&gt;
        }                                                                     &lt;br /&gt;
                                                                              &lt;br /&gt;
plugin {                                                                      &lt;br /&gt;
         quota = dict:user::proxy::quotadict                                   &lt;br /&gt;
         }                                                     &lt;br /&gt;
                                                              &lt;br /&gt;
protocol lda {                                                &lt;br /&gt;
   postmaster_address = postmaster@host.example.com&lt;br /&gt;
   mail_plugins = quota                                        &lt;br /&gt;
   auth_socket_path =  /var/run/dovecot/auth-master&lt;br /&gt;
   sendmail_path = /usr/sbin/sendmail&lt;br /&gt;
}                                                                            &lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
 &lt;br /&gt;
You should already have a &amp;lt;tt&amp;gt;socket-&amp;gt; listen-&amp;gt; client&amp;lt;/tt&amp;gt; section, but it is listed above to show where it goes in relationship to the &amp;lt;tt&amp;gt;socket -&amp;gt; listen -&amp;gt; master&amp;lt;/tt&amp;gt; section&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* edit &amp;lt;tt&amp;gt;/etc/dovecot/dovecot-sql.conf&amp;lt;/tt&amp;gt; and replace the user and password queries with the following (you may not have a user_query yet - add it):&lt;br /&gt;
&lt;br /&gt;
 password_query = select username as user, password, 1006 as userdb_uid, 1006 as userdb_gid, &#039;*:bytes=&#039; || quota as userdb_quota_rule from mailbox  where local_part = &#039;%n&#039; and domain = &#039;%d&#039;&lt;br /&gt;
 user_query = select &#039;/var/mail/domains/&#039; || maildir as home, 1006 as uid, 1006 as gid, &#039;*:bytes=&#039; || quota  as quota_rule from mailbox where local_part = &#039;%n&#039; and domain =&#039;%d&#039;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* create &amp;lt;tt&amp;gt;/etc/dovecot/dovecot-dict-quota.conf&amp;lt;/tt&amp;gt;&lt;br /&gt;
 connect = host=localhost dbname=postfix user=postfix password=********&lt;br /&gt;
 &lt;br /&gt;
 map {&lt;br /&gt;
         pattern = priv/quota/storage&lt;br /&gt;
         table = quota2&lt;br /&gt;
         username_field =username&lt;br /&gt;
         value_field = bytes&lt;br /&gt;
 }&lt;br /&gt;
 &lt;br /&gt;
 map {&lt;br /&gt;
        pattern= priv/quota/messages&lt;br /&gt;
        table = quota2&lt;br /&gt;
        username_field = username&lt;br /&gt;
        value_field = messages&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
Again, change the password above to your postfix user password, and protect the file from prying eyes:&lt;br /&gt;
  chown root:root /etc/dovecot/dovecot-dict-quota.conf&lt;br /&gt;
  chmod 600 /etc/dovecot/dovecot-dict-quota.conf&lt;br /&gt;
&lt;br /&gt;
Side note: [http://wiki.dovecot.org/Quota/Dict The Dovecot Quota Documentation] mentions the need for a trigger with pgsql.  This was created in the PostfixAdmin install, which is why you instantiated the pgsql language when creating the database.  If not, you will need to create the trigger, to reference the quota2 table, not the quota table mentioned in the dovecot docs.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* create a new transport for the dovecot lda.   Add the following to  /etc/postfix/master.cf:&lt;br /&gt;
 # The dovecot deliver lda&lt;br /&gt;
 dovecot   unix  -       n       n       -       -       pipe&lt;br /&gt;
   flags=DRhu user=vmail:vmail argv=/usr/libexec/dovecot/deliver -f ${sender} -d ${user}@${nexthop}&lt;br /&gt;
&lt;br /&gt;
* Edit the /etc/postfix/main.cf.  Replace &lt;br /&gt;
 virtual_transport = virtual &lt;br /&gt;
with&lt;br /&gt;
 virtual_transport = dovecot&lt;br /&gt;
 dovecot_destination_recipient_limit = 1&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;TODO&#039;&#039;&#039;  This will cause over-quota emails to bounce.   Which could be a source of backscatter.   We need a way of checking quota limits after RBL checking but before the message is accepted in the queue.&lt;br /&gt;
&lt;br /&gt;
=== WebMail (RoundCube) ===&lt;br /&gt;
&lt;br /&gt;
[http://roundcube.net/ RoundCube] is an &amp;quot;ajax /Web2.0&amp;quot; web-mail client.  These instructions are for the Alpine Linux 1.10 repository &lt;br /&gt;
&lt;br /&gt;
* Add the package and related php modules:&lt;br /&gt;
 apk add roundcubemail php-xml php-openssl php-mcrypt php-gd php-iconv&lt;br /&gt;
&lt;br /&gt;
* link the roundcube application back into the docroot&lt;br /&gt;
 ln -s /usr/share/webapps/roundcube /var/www/domains/host.example.com/www/roundcube&lt;br /&gt;
&lt;br /&gt;
* follow the instructions in /usr/share/webapps/roundcube/INSTALL:&lt;br /&gt;
 cd /usr/share/webapps/roundcube&lt;br /&gt;
 chown -R lighttpd:lighttpd temp logs&lt;br /&gt;
 &lt;br /&gt;
 su postgres&lt;br /&gt;
 createuser roundcube&lt;br /&gt;
   Shall the new role be a superuser? (y/n) n&lt;br /&gt;
   Shall the new role be allowed to create databases? (y/n) n&lt;br /&gt;
   Shall the new role be allowed to create more new roles? (y/n) y&lt;br /&gt;
 createdb -O roundcube -E UNICODE -T template0 roundcubemail&lt;br /&gt;
 psql roundcubemail&lt;br /&gt;
   roundcubemail=# ALTER USER roundcube WITH PASSWORD &#039;the_new_password&#039;;&lt;br /&gt;
   roundcubemail=# \c - roundcube&lt;br /&gt;
   roundcubemail=&amp;gt; \i /usr/share/webapps/roundcube/SQL/postgres.initial.sql&lt;br /&gt;
   roundcubemail=&amp;gt; \q&lt;br /&gt;
 exit&lt;br /&gt;
&lt;br /&gt;
* edit /etc/php/php.ini and set date.timezone to your local timezone, or to UTC&lt;br /&gt;
&lt;br /&gt;
* restart lighttpd to verify the new php libraries are used&lt;br /&gt;
 /etc/init.d/lighttpd restart&lt;br /&gt;
&lt;br /&gt;
* Point your browser to http://host.example.com/roundcube/installer&lt;br /&gt;
* Start installation&lt;br /&gt;
&lt;br /&gt;
For the specific configuration parameters in the install step:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!Property&lt;br /&gt;
!Setting&lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;enable_spellcheck&#039;&#039; ||   disabled &lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;identities_level&#039;&#039; ||  one identity with possibility to edit all params but not email address &lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;log driver&#039;&#039; || syslog &lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;sylog_id&#039;&#039; || roundcube &lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;syslog_facility&#039;&#039; || mailsubsystem &lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;db_dnsw&#039;&#039; || pgsql properties, as described above &lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;imap_host&#039;&#039; || 127.0.0.1 &lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;auto_create_user&#039;&#039; || enabled &lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;smtp_server&#039;&#039; ||  127.0.0.1&lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;smtp_port&#039;&#039; ||  25&lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;smtp_user/smtp_pass&#039;&#039; ||  enable &#039;&#039;Use Current IMAP username and password for SMTP authentication&#039;&#039;&lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;smtp_log&#039;&#039; ||  enable (optional, but gives additional log record)&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
The other items can be left at default settings, or adjusted if desired.&lt;br /&gt;
&lt;br /&gt;
* Follow the instructions in step 3 of the install to copy the files to the server&lt;br /&gt;
* You should now be able to get to roundcube at http://host.example.com/roundcube&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
After its working, the INSTALL file recommends removing the install directory.   If you want to keep the installer around later, you can simply change the ownership and permissions.  So do &#039;&#039;&#039;one&#039;&#039;&#039; of the following:&lt;br /&gt;
 cd /usr/share/webapps/roundcube&lt;br /&gt;
 rm -rf LICENSE UPGRADING INSTALL README CHANGELOG  SQL installer&lt;br /&gt;
or&lt;br /&gt;
 cd /usr/share/webapps/roundcube&lt;br /&gt;
 chown -R root:root LICENSE UPGRADING INSTALL README CHANGELOG  SQL installer&lt;br /&gt;
 chmod -R 600 LICENSE UPGRADING INSTALL README CHANGELOG SQL &lt;br /&gt;
 chmod 700 SQL installer&lt;br /&gt;
&lt;br /&gt;
==== Enable Plug-ins ====&lt;br /&gt;
&lt;br /&gt;
RoundCube has various useful plug-ins, which could be found in &#039;&#039;/usr/share/webapps/roundcube/plugins&#039;&#039; directory. For example you may want to enable &#039;&#039;password&#039;&#039; plug-in to let users change their passwords directly from RoundCube using an extra Password Tab added to User Settings.&lt;br /&gt;
&lt;br /&gt;
* Grant limited permissions for &#039;&#039;roundcube&#039;&#039; database role &lt;br /&gt;
 psql -U postgres postfix&lt;br /&gt;
   postfix=# GRANT UPDATE (password,modified) ON mailbox TO roundcube;&lt;br /&gt;
   postfix=# GRANT SELECT (username) ON mailbox TO roundcube;&lt;br /&gt;
   postfix=# GRANT INSERT ON log TO roundcube;&lt;br /&gt;
   postfix=# \q&lt;br /&gt;
&lt;br /&gt;
* Setup &#039;&#039;password&#039;&#039; plug-in parameters in &#039;&#039;/usr/share/webapps/roundcube/plugins/password/config.inc.php&#039;&#039;&lt;br /&gt;
 mv /usr/share/webapps/roundcube/plugins/password/config.inc.php.dist /usr/share/webapps/roundcube/plugins/password/config.inc.php&lt;br /&gt;
 vi /usr/share/webapps/roundcube/plugins/password/config.inc.php&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
$rcmail_config[&#039;password_minimum_length&#039;] = 7;&lt;br /&gt;
$rcmail_config[&#039;password_require_nonalpha&#039;] = true;&lt;br /&gt;
...&lt;br /&gt;
$rcmail_config[&#039;password_db_dsn&#039;] = &#039;pgsql://roundcube:&amp;lt;roundcube_password&amp;gt;@localhost/postfix&#039;;&lt;br /&gt;
...&lt;br /&gt;
$rcmail_config[&#039;password_query&#039;] = &amp;quot;UPDATE mailbox set password = %c, modified = NOW() where username = %u; INSERT INTO log (timestamp,username,domain,action,data) VALUES (NOW(),%u || &#039; (&#039; || %h || &#039;)&#039;,%d,&#039;edit_password&#039;,%u)&amp;quot;;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* Enable &#039;&#039;password&#039;&#039; plug-in&lt;br /&gt;
 vi /usr/share/webapps/roundcube/config/main.inc.php&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
...&lt;br /&gt;
$rcmail_config[&#039;plugins&#039;] = array(&#039;password&#039;);&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== OpenLDAP based Address Book ===&lt;br /&gt;
&lt;br /&gt;
This OpenLDAP configuration uses the SQL backend, which represents information stored in PostgreSQL as an LDAP subtree for Address Book functionality for email lookups, user authentication or even &lt;br /&gt;
replication account information between sites. This procedure uses some metainformation to translate LDAP queries to SQL queries, leaving relational schema untouched, which allows SQL and LDAP &lt;br /&gt;
applications to inter-operate without replication, and exchange data as needed. The SQL backend uses UnixODBC to connect to PostgresSQL. &lt;br /&gt;
&lt;br /&gt;
* Install OpenLDAP and ODBC&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
apk add openldap libldap openldap-back-sql php-ldap unixodbc psqlodbc ca-certificates&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Note&#039;&#039;&#039;: The psqlodbc package is currently unavailable&lt;br /&gt;
&lt;br /&gt;
* Update &amp;quot;postfix&amp;quot; database (it will add &#039;id&#039; columns to mailbox and domain tables, also will create tables and views to represent LDAP metainformation)&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Note&#039;&#039;&#039;: These instructions are for example domain example.com. So make sure you replaced all entries of &#039;example&#039; and &#039;com&#039; according to your domain name parts.&lt;br /&gt;
&lt;br /&gt;
Put the following into a new file called &#039;&#039;&#039;script&#039;&#039;&#039;:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
ALTER TABLE domain ADD COLUMN id SERIAL; &lt;br /&gt;
ALTER TABLE mailbox ADD COLUMN id SERIAL; &lt;br /&gt;
&lt;br /&gt;
CREATE TABLE ldap_entry_objclasses (&lt;br /&gt;
    entry_id integer NOT NULL,&lt;br /&gt;
    oc_name character varying(64)&lt;br /&gt;
);&lt;br /&gt;
&lt;br /&gt;
CREATE TABLE ldap_oc_mappings (&lt;br /&gt;
    name character varying(64) NOT NULL,&lt;br /&gt;
    keytbl character varying(64) NOT NULL,&lt;br /&gt;
    keycol character varying(64) NOT NULL,&lt;br /&gt;
    create_proc character varying(255),&lt;br /&gt;
    delete_proc character varying(255),&lt;br /&gt;
    expect_return integer NOT NULL&lt;br /&gt;
);&lt;br /&gt;
&lt;br /&gt;
ALTER TABLE ldap_oc_mappings ADD COLUMN id SERIAL;&lt;br /&gt;
ALTER TABLE ldap_oc_mappings ADD PRIMARY KEY (id);&lt;br /&gt;
&lt;br /&gt;
CREATE TABLE ldap_attr_mappings (&lt;br /&gt;
    oc_map_id integer NOT NULL REFERENCES ldap_oc_mappings(id),&lt;br /&gt;
    name character varying(255) NOT NULL,&lt;br /&gt;
    sel_expr character varying(255) NOT NULL,&lt;br /&gt;
    sel_expr_u character varying(255),&lt;br /&gt;
    from_tbls character varying(255) NOT NULL,&lt;br /&gt;
    join_where character varying(255),&lt;br /&gt;
    add_proc character varying(255),&lt;br /&gt;
    delete_proc character varying(255),&lt;br /&gt;
    param_order integer NOT NULL,&lt;br /&gt;
    expect_return integer NOT NULL&lt;br /&gt;
);&lt;br /&gt;
&lt;br /&gt;
ALTER TABLE ldap_attr_mappings ADD COLUMN id SERIAL;&lt;br /&gt;
ALTER TABLE ldap_attr_mappings ADD PRIMARY KEY (id);&lt;br /&gt;
&lt;br /&gt;
CREATE VIEW ldap_dcs AS&lt;br /&gt;
    ((SELECT (domain.id + 100000) AS id,&lt;br /&gt;
            (&#039;dc=&#039;::text || replace((domain.domain)::text, &#039;.&#039;::text, &#039;,dc=&#039;::text)) AS dn,&lt;br /&gt;
            1 AS oc_map_id,&lt;br /&gt;
            100000 AS parent,&lt;br /&gt;
            0 AS keyval,&lt;br /&gt;
            domain.domain&lt;br /&gt;
     FROM domain&lt;br /&gt;
     WHERE domain.domain &amp;lt;&amp;gt; &#039;ALL&#039;)&lt;br /&gt;
      UNION&lt;br /&gt;
     (SELECT 100000 AS id,&lt;br /&gt;
           (&#039;dc=&#039; || regexp_replace((domain.domain)::text, &#039;.*\\.&#039;, &#039;&#039;::text)) AS dn,&lt;br /&gt;
           1 AS oc_map_id,&lt;br /&gt;
           0 AS parent,&lt;br /&gt;
           0 AS keyval,&lt;br /&gt;
           (regexp_replace((domain.domain)::text, &#039;.*\\.&#039;, &#039;&#039;::text)) AS domain&lt;br /&gt;
      FROM domain&lt;br /&gt;
      WHERE domain.domain &amp;lt;&amp;gt; &#039;ALL&#039;&lt;br /&gt;
      LIMIT 1));&lt;br /&gt;
&lt;br /&gt;
CREATE VIEW ldap_entries AS&lt;br /&gt;
    SELECT mailbox.id,&lt;br /&gt;
    (((&#039;cn=&#039;::text || initcap(replace(split_part((mailbox.username)::text, &#039;@&#039;::text, 1), &#039;.&#039;::text, &#039; &#039;::text))) || &#039;,dc=&#039;::text) ||&lt;br /&gt;
             replace(regexp_replace((mailbox.username)::text, &#039;.*@&#039;, &#039;&#039;::text), &#039;.&#039;::text, &#039;,dc=&#039;::text)) AS dn,&lt;br /&gt;
          1 AS oc_map_id,&lt;br /&gt;
          (SELECT ldap_dcs.id&lt;br /&gt;
           FROM ldap_dcs&lt;br /&gt;
           WHERE ((ldap_dcs.domain)::text = (mailbox.domain)::text)) AS parent,&lt;br /&gt;
           mailbox.id AS keyval&lt;br /&gt;
           FROM mailbox&lt;br /&gt;
           UNION&lt;br /&gt;
           SELECT ldap_dcs.id,&lt;br /&gt;
                  ldap_dcs.dn,&lt;br /&gt;
                  ldap_dcs.oc_map_id,&lt;br /&gt;
                  ldap_dcs.parent,&lt;br /&gt;
                  ldap_dcs.keyval&lt;br /&gt;
           FROM ldap_dcs;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Finally, execute the commands in the file with:&lt;br /&gt;
 cat script | psql -U postfix postfix&lt;br /&gt;
 rm script&lt;br /&gt;
&lt;br /&gt;
* Fill out LDAP tables according to following example (make sure to separate values with TABs):&lt;br /&gt;
&lt;br /&gt;
Put the following into a new file called &#039;&#039;&#039;script&#039;&#039;&#039;:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
COPY ldap_oc_mappings (id, name, keytbl, keycol, create_proc, delete_proc, expect_return) FROM stdin;&lt;br /&gt;
1	exampleBox	mailbox	id	\N	\N	1&lt;br /&gt;
\.&lt;br /&gt;
COPY ldap_attr_mappings (id, oc_map_id, name, sel_expr, sel_expr_u, from_tbls, join_where, add_proc, delete_proc, param_order, expect_return) FROM stdin;&lt;br /&gt;
1	1	displayName	mailbox.name	\N	mailbox	\N	\N	\N	3	0&lt;br /&gt;
2	1	mail	mailbox.username	\N	mailbox	\N	\N	\N	3	0&lt;br /&gt;
3	1	cn	mailbox.name	\N	mailbox	\N	\N	\N	3	0&lt;br /&gt;
4	1	userPassword	&#039;{CRYPT}&#039;||mailbox.password	\N	mailbox	\N	\N	\N	3	0&lt;br /&gt;
\.&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Finally, execute the commands in the file with:&lt;br /&gt;
 cat script | psql -U postfix postfix&lt;br /&gt;
 rm script&lt;br /&gt;
&lt;br /&gt;
* Check that &amp;quot;ldap_dcs&amp;quot; view looks something like this:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
echo &#039;select * from ldap_dcs&#039; | psql -U postgres postfix&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
   id   |             dn              | oc_map_id | parent | keyval |       domain       &lt;br /&gt;
--------+-----------------------------+-----------+--------+--------+--------------------&lt;br /&gt;
 100000 | dc=com                      |         1 |      0 |      0 | com&lt;br /&gt;
 100001 | dc=example,dc=com           |         1 | 100000 |      0 | example.com&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* Check that &amp;quot;ldap_entries&amp;quot; view looks something like this:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
echo &#039;select * from ldap_entries&#039; | psql -U postgres postfix&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
   id   |                          dn                           | oc_map_id | parent | keyval &lt;br /&gt;
--------+-------------------------------------------------------+-----------+--------+--------&lt;br /&gt;
    1   | cn=address1,dc=example,dc=com                         |         1 | 100001 |    1&lt;br /&gt;
...&lt;br /&gt;
   123  | cn=address123,dc=example,dc=com                       |         1 | 100001 |    1&lt;br /&gt;
 100000 | dc=com                                                |         1 |      0 |    0&lt;br /&gt;
 100001 | dc=example,dc=com                                     |         1 | 100000 |    0&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* Configure ODBC parameters&lt;br /&gt;
&lt;br /&gt;
Edit /etc/odbc.ini:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
[PostgreSQL]&lt;br /&gt;
Description             = Connection to Postgres&lt;br /&gt;
Driver                  = PostgreSQL&lt;br /&gt;
Trace                   = Yes&lt;br /&gt;
TraceFile               = sql.log&lt;br /&gt;
Database                = postfix&lt;br /&gt;
Servername              = 127.0.0.1&lt;br /&gt;
UserName                =&lt;br /&gt;
Password                =&lt;br /&gt;
Port                    = 5432&lt;br /&gt;
Protocol                = 6.4&lt;br /&gt;
ReadOnly                = No&lt;br /&gt;
RowVersining            = No&lt;br /&gt;
ShowSystemTables        = No&lt;br /&gt;
ShowOidColumn           = No&lt;br /&gt;
FakeOidIndex            = No&lt;br /&gt;
ConnSettings            =&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Edit /etc/odbcinst.ini:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
[PostgreSQL]&lt;br /&gt;
Description     = PostgreSQL driver for Linux&lt;br /&gt;
Driver          = /usr/lib/psqlodbcw.so&lt;br /&gt;
Setup           = /usr/lib/libodbcpsqlS.so&lt;br /&gt;
FileUsage       = 1&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* Test ODBC connection&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
echo &amp;quot;select * from domain;&amp;quot; | isql PostgreSQL postgres&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* Provide permission to certificate for LDAP server&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
chown ldap /etc/lighttpd/server-bundle.pem&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* Edit LDAP schema&lt;br /&gt;
&lt;br /&gt;
Edit /etc/openldap/schema/example.com.schema:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
attributetype ( 0.9.2342.19200300.100.1.3&lt;br /&gt;
	NAME ( &#039;mail&#039; &#039;rfc822Mailbox&#039; )&lt;br /&gt;
	DESC &#039;RFC1274: RFC822 Mailbox&#039;&lt;br /&gt;
        EQUALITY caseIgnoreIA5Match&lt;br /&gt;
        SUBSTR caseIgnoreIA5SubstringsMatch&lt;br /&gt;
        SYNTAX 1.3.6.1.4.1.1466.115.121.1.26{256} )&lt;br /&gt;
&lt;br /&gt;
attributetype ( 2.16.840.1.113730.3.1.241&lt;br /&gt;
	NAME &#039;displayName&#039;&lt;br /&gt;
	DESC &#039;RFC2798: preferred name to be used when displaying entries&#039;&lt;br /&gt;
	EQUALITY caseIgnoreMatch&lt;br /&gt;
	SUBSTR caseIgnoreSubstringsMatch&lt;br /&gt;
	SYNTAX 1.3.6.1.4.1.1466.115.121.1.15&lt;br /&gt;
	SINGLE-VALUE )&lt;br /&gt;
&lt;br /&gt;
objectclass   ( 2.16.840.1.113730.3.2.2&lt;br /&gt;
        NAME &#039;exampleBox&#039;&lt;br /&gt;
	DESC &#039;example.com mailbox&#039;&lt;br /&gt;
	MUST ( displayName $ mail $ userPassword )&lt;br /&gt;
	)&lt;br /&gt;
&lt;br /&gt;
# RFC 1274 + RFC 2247&lt;br /&gt;
attributetype ( 0.9.2342.19200300.100.1.25&lt;br /&gt;
        NAME ( &#039;dc&#039; &#039;domainComponent&#039; )&lt;br /&gt;
        DESC &#039;RFC1274/2247: domain component&#039;&lt;br /&gt;
        EQUALITY caseIgnoreIA5Match&lt;br /&gt;
        SUBSTR caseIgnoreIA5SubstringsMatch&lt;br /&gt;
        SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 SINGLE-VALUE )&lt;br /&gt;
&lt;br /&gt;
attributetype ( 2.5.4.46 NAME &#039;dnQualifier&#039;&lt;br /&gt;
        DESC &#039;RFC2256: DN qualifier&#039;&lt;br /&gt;
        EQUALITY caseIgnoreMatch&lt;br /&gt;
        ORDERING caseIgnoreOrderingMatch&lt;br /&gt;
        SUBSTR caseIgnoreSubstringsMatch&lt;br /&gt;
        SYNTAX 1.3.6.1.4.1.1466.115.121.1.44 )&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* Configure LDAP server&lt;br /&gt;
&lt;br /&gt;
Edit /etc/openldap/slapd.conf:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
include         /etc/openldap/schema/example.com.schema&lt;br /&gt;
pidfile         /var/run/openldap/slapd.pid&lt;br /&gt;
argsfile        /var/run/openldap/slapd.args&lt;br /&gt;
&lt;br /&gt;
TLSCipherSuite HIGH&lt;br /&gt;
TLSCACertificateFile /etc/lighttpd/ca-crt.pem&lt;br /&gt;
TLSCertificateFile /etc/lighttpd/server-bundle.pem&lt;br /&gt;
TLSCertificateKeyFile /etc/lighttpd/server-bundle.pem&lt;br /&gt;
TLSVerifyClient never &lt;br /&gt;
&lt;br /&gt;
# This is needed for proper representation of MD5-CRYPT format stored in database&lt;br /&gt;
#  see more details in http://strugglers.net/~andy/blog/2010/01/23/openldap-and-md5crypt/&lt;br /&gt;
password-hash  {CRYPT}&lt;br /&gt;
password-crypt-salt-format &amp;quot;$1$%.8s&amp;quot;&lt;br /&gt;
&lt;br /&gt;
loglevel        stats&lt;br /&gt;
moduleload	/usr/lib/openldap/back_sql.so&lt;br /&gt;
sizelimit 3000&lt;br /&gt;
&lt;br /&gt;
database        sql&lt;br /&gt;
&lt;br /&gt;
dbname		PostgreSQL&lt;br /&gt;
dbuser		postfix&lt;br /&gt;
dbpasswd	*****&lt;br /&gt;
&lt;br /&gt;
suffix          &amp;quot;dc=example,dc=com&amp;quot;&lt;br /&gt;
&lt;br /&gt;
upper_func      &amp;quot;upper&amp;quot;&lt;br /&gt;
strcast_func    &amp;quot;text&amp;quot;&lt;br /&gt;
concat_pattern  &amp;quot;?||?&amp;quot;&lt;br /&gt;
has_ldapinfo_dn_ru      no&lt;br /&gt;
lastmod         off&lt;br /&gt;
&lt;br /&gt;
access to attrs=userPassword by * auth&lt;br /&gt;
&lt;br /&gt;
access to * by peername.ip=127.0.0.1 read&lt;br /&gt;
#           by peername.ip=&amp;lt;IP&amp;gt;%&amp;lt;netmask&amp;gt; read&lt;br /&gt;
#           by peername.ip=&amp;lt;IP&amp;gt; read&lt;br /&gt;
	    by users read&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* Set permissions for slapd.conf&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
chown ldap:ldap /etc/openldap/slapd.conf&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* Configure startup parameters to make sure that LDAP server start AFTER PostgreSQL and listens on localhost with clear text and public IP with SSL&lt;br /&gt;
&lt;br /&gt;
Edit /etc/conf.d/slapd:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
rc_need=&amp;quot;postgresql&amp;quot; &lt;br /&gt;
OPTS=&amp;quot;-h &#039;ldaps:// ldap://127.0.0.1&#039;&amp;quot;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* Start LDAP server&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
rc-update add slapd default&lt;br /&gt;
/etc/init.d/slapd start&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* Configure LDAP client utilities&lt;br /&gt;
&lt;br /&gt;
Edit /etc/openldap/ldap.conf&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
BASE	dc=example,dc=com&lt;br /&gt;
URI	ldaps://host.example.com&lt;br /&gt;
&lt;br /&gt;
TLS_CACERT /etc/lighttpd/ca-crt.pem&lt;br /&gt;
TLS_CERT /etc/lighttpd/server-bundle.pem&lt;br /&gt;
TLS_KEY /etc/lighttpd/server-bundle.pem&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* Test LDAP server&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
ldapsearch -z 3&lt;br /&gt;
ldapsearch -z 3 -x -W -D cn=admin,dc=example,dc=com&lt;br /&gt;
ldapsearch -z 3 -x -W -D cn=address1,dc=example,dc=com&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* Configure RoundCube webmail for email lookups&lt;br /&gt;
&lt;br /&gt;
In order to enable php-ldap support you need to restart lighttpd server&lt;br /&gt;
&lt;br /&gt;
 /etc/init.d/lighttpd restart&lt;br /&gt;
&lt;br /&gt;
Edit /usr/share/webapps/roundcube/config/main.inc.php:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
$rcmail_config[&#039;ldap_debug&#039;] = false;&lt;br /&gt;
...&lt;br /&gt;
$rcmail_config[&#039;address_book_type&#039;] = &#039;sql&#039;;&lt;br /&gt;
&lt;br /&gt;
$rcmail_config[&#039;ldap_public&#039;][&#039;example.com&#039;] = array(&lt;br /&gt;
  &#039;name&#039;          =&amp;gt; &#039;example.com&#039;,&lt;br /&gt;
  &#039;hosts&#039;         =&amp;gt; array(&#039;127.0.0.1&#039;),&lt;br /&gt;
  &#039;port&#039;          =&amp;gt; 389,&lt;br /&gt;
  &#039;use_tls&#039;         =&amp;gt; false,&lt;br /&gt;
  &#039;user_specific&#039; =&amp;gt; false,&lt;br /&gt;
  &#039;base_dn&#039;       =&amp;gt; &#039;dc=example,dc=com&#039;,&lt;br /&gt;
  &#039;bind_dn&#039;       =&amp;gt; &#039;&#039;,&lt;br /&gt;
  &#039;bind_pass&#039;     =&amp;gt; &#039;&#039;,&lt;br /&gt;
  &#039;writable&#039;      =&amp;gt; false,&lt;br /&gt;
  &#039;LDAP_Object_Classes&#039; =&amp;gt; array(&amp;quot;top&amp;quot;, &amp;quot;exampleBox&amp;quot;),&lt;br /&gt;
  &#039;required_fields&#039;     =&amp;gt; array(&amp;quot;cn&amp;quot;, &amp;quot;sn&amp;quot;, &amp;quot;mail&amp;quot;),&lt;br /&gt;
  &#039;LDAP_rdn&#039;      =&amp;gt; &#039;mail&#039;,&lt;br /&gt;
  &#039;ldap_version&#039;  =&amp;gt; 3,&lt;br /&gt;
  &#039;search_fields&#039; =&amp;gt; array(&#039;mail&#039;, &#039;cn&#039;, &#039;sn&#039;, &#039;givenName&#039;),&lt;br /&gt;
  &#039;name_field&#039;    =&amp;gt; &#039;cn&#039;,&lt;br /&gt;
  &#039;email_field&#039;   =&amp;gt; &#039;mail&#039;,&lt;br /&gt;
  &#039;surname_field&#039; =&amp;gt; &#039;sn&#039;,&lt;br /&gt;
  &#039;firstname_field&#039; =&amp;gt; &#039;gn&#039;,&lt;br /&gt;
  &#039;sort&#039;          =&amp;gt; &#039;cn&#039;,&lt;br /&gt;
  &#039;scope&#039;         =&amp;gt; &#039;sub&#039;,&lt;br /&gt;
  &#039;filter&#039;        =&amp;gt; &#039;(objectClass=*)&#039;, // Construct here any filter you need&lt;br /&gt;
  &#039;fuzzy_search&#039;  =&amp;gt; true);&lt;br /&gt;
&lt;br /&gt;
$rcmail_config[&#039;autocomplete_addressbooks&#039;] = array(&#039;sql&#039;,&#039;example.com&#039;);&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* Fix PostfixAdmin to work with the new table definition&lt;br /&gt;
&lt;br /&gt;
Edit /var/www/domains/example.com/www/list-domain.php. Replace the line:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
   SELECT domain.* , COUNT( DISTINCT mailbox.username ) AS mailbox_count&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
With the lines:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
   SELECT domain.domain, domain.description, domain.aliases, domain.mailboxes,&lt;br /&gt;
   domain.maxquota, domain.quota, domain.transport, domain.backupmx, domain.created,&lt;br /&gt;
   domain.modified, domain.active, COUNT( DISTINCT mailbox.username ) AS mailbox_count&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== log rotation ==&lt;br /&gt;
&lt;br /&gt;
Ensure the busybox cron service is started and is configured to auto-start:&lt;br /&gt;
&lt;br /&gt;
 /etc/init.d/cron start&lt;br /&gt;
 rc-update add cron default&lt;br /&gt;
&lt;br /&gt;
Add log rotate:&lt;br /&gt;
&lt;br /&gt;
 apk add logrotate&lt;br /&gt;
&lt;br /&gt;
Edit &#039;&#039;/etc/logrotate.conf&#039;&#039; as desired, but the defaults should be sufficient for most people.&lt;br /&gt;
&lt;br /&gt;
== Optional: Configure Web Server Virtual Domains ==&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Note:&#039;&#039;&#039; These steps can be done &#039;&#039;in addition to&#039;&#039; the default lighttpd configuration above, which allows you to access the ACF, PostfixAdmin and Roundcube interfaces as subfolders of one web service.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Note:&#039;&#039;&#039; If you provide SSL access for multiple domain site you may need to follow http://redmine.lighttpd.net/projects/lighttpd/wiki/Docs:SSL#SSL-on-multiple-domains in order to provide multi-domain certificates. If you would like to redirect hosts to their secure equivalents use the following instructions http://redmine.lighttpd.net/projects/lighttpd/wiki/HowToRedirectHttpToHttps.&lt;br /&gt;
&lt;br /&gt;
This server hosts three separate web applications, and these can be handled as three &#039;&#039;different&#039;&#039; virtual domains on the same web server. They will be distinguished by their DNS names, so you can choose domains for the three separate services (or at least the ones you want to publish):&lt;br /&gt;
&lt;br /&gt;
* ACF - Alpine Configuration Framework for managing the server&lt;br /&gt;
* PostfixAdmin - for managing the postfix installation&lt;br /&gt;
* RoundCube - for accessing individual mailboxes&lt;br /&gt;
&lt;br /&gt;
Choose three different domains (from here on known as ACF_DOMAIN, POSTFIXADMIN_DOMAIN, and ROUNDCUBE_DOMAIN) and configure DNS for all three to point to the IP address of your host. These should be DNS &#039;&#039;&#039;A&#039;&#039;&#039; records.&lt;br /&gt;
&lt;br /&gt;
Then, configure lighttpd to handle the three separate domains by editing /etc/lighttpd/lighttpd.conf:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 $HTTP[&amp;quot;host&amp;quot;] == &amp;quot;ACF_DOMAIN&amp;quot; {&lt;br /&gt;
	simple-vhost.server-root   = &amp;quot;/var/www/domains/&amp;quot;&lt;br /&gt;
	simple-vhost.default-host  = &amp;quot;/ACF_DOMAIN/&amp;quot;&lt;br /&gt;
	simple-vhost.document-root = &amp;quot;www/&amp;quot;&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
 $HTTP[&amp;quot;host&amp;quot;] == &amp;quot;POSTFIXADMIN_DOMAIN&amp;quot; {&lt;br /&gt;
	simple-vhost.server-root   = &amp;quot;/var/www/domains/&amp;quot;&lt;br /&gt;
	simple-vhost.default-host  = &amp;quot;/POSTFIXADMIN_DOMAIN/&amp;quot;&lt;br /&gt;
	simple-vhost.document-root = &amp;quot;www/&amp;quot;&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
 $HTTP[&amp;quot;host&amp;quot;] == &amp;quot;ROUNDCUBE_DOMAIN&amp;quot; {&lt;br /&gt;
	simple-vhost.server-root   = &amp;quot;/var/www/domains/&amp;quot;&lt;br /&gt;
	simple-vhost.default-host  = &amp;quot;/ROUNDCUBE_DOMAIN/&amp;quot;&lt;br /&gt;
	simple-vhost.document-root = &amp;quot;www/&amp;quot;&lt;br /&gt;
 }&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
And, then link the appropriate www directories.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  mkdir -p /var/www/domains/ACF_DOMAIN&lt;br /&gt;
  ln -s /usr/share/acf/www /var/www/domains/ACF_DOMAIN/www&lt;br /&gt;
&lt;br /&gt;
  mkdir -p /var/www/domains/POSTFIXADMIN_DOMAIN&lt;br /&gt;
  ln -s /var/www/domains/host.example.com/www/postfixadmin /var/www/domains/POSTFIXADMIN_DOMAIN/www&lt;br /&gt;
&lt;br /&gt;
  mkdir -p /var/www/domains/ROUNDCUBE_DOMAIN&lt;br /&gt;
  ln -s /usr/share/webapps/roundcube /var/www/domains/ROUNDCUBE_DOMAIN/www&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;/div&gt;</summary>
		<author><name>Djhughes</name></author>
	</entry>
	<entry>
		<id>https://wiki.alpinelinux.org/w/index.php?title=ISP_Mail_Server_HowTo&amp;diff=3742</id>
		<title>ISP Mail Server HowTo</title>
		<link rel="alternate" type="text/html" href="https://wiki.alpinelinux.org/w/index.php?title=ISP_Mail_Server_HowTo&amp;diff=3742"/>
		<updated>2010-05-10T08:28:59Z</updated>

		<summary type="html">&lt;p&gt;Djhughes: added steps for optionally using the setup-acf generated cert&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== A Full Service Mail Server ==&lt;br /&gt;
&lt;br /&gt;
The goal of this document is to describe how to set up postfix, dovecot, clamav, dspam, roundecube, and postfixadmin for a full-featured &amp;quot;ISP&amp;quot; level mail server.&lt;br /&gt;
&lt;br /&gt;
The server must provide:&lt;br /&gt;
&lt;br /&gt;
* multiple virtual domains&lt;br /&gt;
* admins for each domain (to add/remove virtual accounts)&lt;br /&gt;
* Quota support per domain / account&lt;br /&gt;
* downloading email via IMAP / IMAPS / POP3 / POP3S&lt;br /&gt;
* relaying email for authenticated users with TLS or SSL (Submission / SMTPS protocol)&lt;br /&gt;
* Standard filters (virus/spam/rbl/etc)&lt;br /&gt;
* Web mail client&lt;br /&gt;
* Value Add services&lt;br /&gt;
&lt;br /&gt;
== Set up Lighttpd + PHP ==&lt;br /&gt;
&lt;br /&gt;
PostfixAdmin needs php pgpsql and imap modules, so we do it in this step.&lt;br /&gt;
&lt;br /&gt;
  apk add lighttpd php php-pgsql php-imap&lt;br /&gt;
&lt;br /&gt;
Stop and remove mini_httpd, and move ACF to lighttpd;  We are setting this up to be a multi-domain virtual web server (replace host.example.com with the actual domain):&lt;br /&gt;
&lt;br /&gt;
  mkdir -p /var/www/domains/host.example.com/www&lt;br /&gt;
  ln -s /usr/share/acf/www /var/www/domains/host.example.com/www/acf&lt;br /&gt;
&lt;br /&gt;
Edit /var/www/domains/host.example.com/index.html to put a simple redirection page:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;lt;!DOCTYPE HTML PUBLIC &amp;quot;-//W3C//DTD HTML 4.01//EN&amp;quot; &amp;quot;http://www.w3.org/TR/html4/strict.dtd&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;html lang=&amp;quot;en&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;head&amp;gt;&lt;br /&gt;
&amp;lt;meta http-equiv=&amp;quot;Content-Type&amp;quot; content=&amp;quot;text/html; charset=ISO-8859-1&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;title&amp;gt;host.example.com Redirector&amp;lt;/title&amp;gt;&lt;br /&gt;
&amp;lt;/head&amp;gt;&lt;br /&gt;
&amp;lt;body&amp;gt;&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;&amp;lt;a href=&amp;quot;/acf&amp;quot;&amp;gt;ACF&amp;lt;/a&amp;gt;&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;&amp;lt;a href=&amp;quot;/postfixadmin&amp;quot;&amp;gt;PostfixAdmin&amp;lt;/a&amp;gt;&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;&amp;lt;a href=&amp;quot;/roundcube&amp;quot;&amp;gt;Roundcube&amp;lt;/a&amp;gt;&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
&amp;lt;/body&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Edit /etc/lighttpd/mod_cgi.conf to serve haserl files by adding a &amp;quot;&amp;quot; =&amp;gt; &amp;quot;&amp;quot; cgi handler and to treat /acf/cgi-bin as a CGI directory (remove the &#039;^&#039;)&lt;br /&gt;
&lt;br /&gt;
 $HTTP[&amp;quot;url&amp;quot;] =~ &amp;quot;/cgi-bin/&amp;quot; {&lt;br /&gt;
     # disable directory listings&lt;br /&gt;
     dir-listing.activate = &amp;quot;disable&amp;quot;&lt;br /&gt;
     # only allow cgi&#039;s in this directory&lt;br /&gt;
     cgi.assign = (&lt;br /&gt;
 		&amp;quot;.pl&amp;quot;	=&amp;gt;	&amp;quot;/usr/bin/perl&amp;quot;,&lt;br /&gt;
 		&amp;quot;.cgi&amp;quot;	=&amp;gt;	&amp;quot;/usr/bin/perl&amp;quot;,&lt;br /&gt;
 		&amp;quot;&amp;quot; =&amp;gt; &amp;quot;&amp;quot;&lt;br /&gt;
 	)&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
Add these lines to /etc/lighttpd/lighttpd.conf to point to the new document root, and set it up to listen on port 443 (replace &#039;&#039;host.example.com&#039;&#039; with the actual domain and &#039;&#039;ip_address_of_server&#039;&#039; with the actual IP address):&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
simple-vhost.server-root   = &amp;quot;/var/www/domains/&amp;quot;&lt;br /&gt;
simple-vhost.default-host  = &amp;quot;/host.example.com/&amp;quot;&lt;br /&gt;
simple-vhost.document-root = &amp;quot;www/&amp;quot;&lt;br /&gt;
&lt;br /&gt;
$SERVER[&amp;quot;socket&amp;quot;] == &amp;quot;ip_address_of_server:443&amp;quot; {&lt;br /&gt;
ssl.engine    = &amp;quot;enable&amp;quot;&lt;br /&gt;
ssl.pemfile   = &amp;quot;/etc/lighttpd/server-bundle.pem&amp;quot;&lt;br /&gt;
ssl.ca-file   = &amp;quot;/etc/lighttpd/ca-crt.pem&amp;quot;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Ensure that the simple_vhosts module is loaded, as well as the cgi config scripts by uncommenting the following lines in /etc/lighttpd/lighttpd.conf&lt;br /&gt;
&lt;br /&gt;
 server.modules = (&lt;br /&gt;
     #  other modules may be listed&lt;br /&gt;
     &amp;quot;mod_simple_vhost&amp;quot;, &lt;br /&gt;
     #  other modules may be listed&lt;br /&gt;
  .&lt;br /&gt;
  .&lt;br /&gt;
  .&lt;br /&gt;
     include &amp;quot;mod_cgi.conf&amp;quot;&lt;br /&gt;
 &lt;br /&gt;
     include &amp;quot;mod_fastcgi.conf&amp;quot;&lt;br /&gt;
 &lt;br /&gt;
Get a web certificate, and install it.  You have two options: 1. If you want to use a self-signed cert, you can use the instructions found at [[Generating SSL certs with ACF]] or [[Generating SSL certs with ACF 1.9]] to generate it. 2. Use the certificate created with the &#039;&#039;&#039;setup-acf&#039;&#039;&#039; command. &lt;br /&gt;
&lt;br /&gt;
If you create your own self-signed certificate, you can create the &amp;quot;server-bundle.pem&amp;quot; and the &amp;quot;ca-crt.pem&amp;quot; file with these commands:&lt;br /&gt;
&lt;br /&gt;
  openssl pkcs12 -nokeys -cacerts -in certificate.pfx  -out /etc/lighttpd/ca-crt.pem&lt;br /&gt;
  openssl pkcs12 -nodes -in certificate.pfx -out /etc/lighttpd/server-bundle.pem&lt;br /&gt;
  chown root:root /etc/lighttpd/server-bundle.pem&lt;br /&gt;
  chmod 400 /etc/lighttpd/server-bundle.pem&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Note:&#039;&#039;&#039; The server certificate &#039;&#039;and&#039;&#039; key are in the server-bundle.pem file, so it is critical that the file be read-only by user &amp;quot;root&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
If you prefer to just use the default certificate created with the &#039;&#039;&#039;setup-acf&#039;&#039;&#039; command, then you will need to do the following:&lt;br /&gt;
&lt;br /&gt;
  setup-acf&lt;br /&gt;
&lt;br /&gt;
During the above process, mini_httpd will be started, if it isn&#039;t already, and a certificate will be created. Once you have completed the setup-acf steps, do the following to move the certificate files to the correct location for lighttpd to use.&lt;br /&gt;
&lt;br /&gt;
  mv /etc/ssl/mini_httpd/server.pem /etc/lighttpd/server-bundle.pem&lt;br /&gt;
  cp /etc/ssl/cacert.pem /etc/lighttpd/ca-crt.pem&lt;br /&gt;
  chown root:root /etc/lighttpd/server-bundle.pem&lt;br /&gt;
  chmod 400 /etc/lighttpd/server-bundle.pem&lt;br /&gt;
&lt;br /&gt;
Stop and remove mini_httpd; start lighttpd, test&lt;br /&gt;
&lt;br /&gt;
  /etc/init.d/mini_httpd stop&lt;br /&gt;
  rc-update del mini_httpd&lt;br /&gt;
  apk del mini_httpd&lt;br /&gt;
  rc-update add lighttpd&lt;br /&gt;
  /etc/init.d/lighttpd start&lt;br /&gt;
&lt;br /&gt;
At this point you should be able to see ACF being served with lighttpd (Note: this will work well with alpine 1.10. With earlier versions there will be problems.)  https://host.example.com/acf/&lt;br /&gt;
&lt;br /&gt;
== Install Postgresql ==&lt;br /&gt;
&lt;br /&gt;
Add and configure postgresql&lt;br /&gt;
&lt;br /&gt;
  apk add acf-postgresql postgresql-client&lt;br /&gt;
  /etc/init.d/postgresql setup&lt;br /&gt;
  /etc/init.d/postgresql start&lt;br /&gt;
  rc-update add postgresql&lt;br /&gt;
&lt;br /&gt;
At this point any user can connect to the sql server with &amp;quot;trust&amp;quot; mechanism.  If you want to enforce password authentication (you probably do) edit /var/lib/postgresql/8.4/data/pg_hba.conf&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
  Editme: What should we recommend?&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Create the postfix database:&lt;br /&gt;
&lt;br /&gt;
  psql -U postgres&lt;br /&gt;
   create user postfix with password &#039;******&#039;;&lt;br /&gt;
   create database postfix owner postfix;&lt;br /&gt;
   \c postfix&lt;br /&gt;
   create language plpgsql;&lt;br /&gt;
   \q&lt;br /&gt;
&lt;br /&gt;
(Of course, use your selected password where ******* is shown above.)&lt;br /&gt;
&lt;br /&gt;
== Install PostfixAdmin ==&lt;br /&gt;
&lt;br /&gt;
We are going to install the postfix admin web front-end before we install the mail server.  This just creates an interface to populate the SQL tables that postfix and dovecot will use.&lt;br /&gt;
&lt;br /&gt;
Download PostfixAdmin from Sourceforge.  When these instructions were written, 2.3 was the current release, so (replace host.example.com with the actual domain):&lt;br /&gt;
 wget http://downloads.sourceforge.net/project/postfixadmin/postfixadmin/postfixadmin_2.3.tar.gz&lt;br /&gt;
 tar zxvf postfixadmin_2.3.tar.gz&lt;br /&gt;
 mkdir -p /var/www/domains/host.example.com/www/postfixadmin&lt;br /&gt;
 mv postfixadmin-2.3/* /var/www/domains/host.example.com/www/postfixadmin&lt;br /&gt;
 rm -rf postfixadmin*&lt;br /&gt;
&lt;br /&gt;
Edit /var/www/domains/host.example.com/www/postfixadmin/config.inc.php and modify at least these lines (replace host.example.com with the actual domain):&lt;br /&gt;
&lt;br /&gt;
 $CONF[&#039;configured&#039;] = true;&lt;br /&gt;
 $CONF[&#039;setup_password&#039;] = &amp;quot;&amp;quot;;  &amp;lt;&amp;lt; Don&#039;t change this yet&lt;br /&gt;
 $CONF[&#039;database_type&#039;] = &#039;pgsql&#039;;&lt;br /&gt;
 $CONF[&#039;database_host&#039;] = &#039;localhost&#039;;&lt;br /&gt;
 $CONF[&#039;database_user&#039;] = &#039;postfix&#039;;&lt;br /&gt;
 $CONF[&#039;database_password&#039;] = &#039;*****&#039;;   &amp;lt;&amp;lt; The password you chose above&lt;br /&gt;
 $CONF[&#039;database_name&#039;] = &#039;postfix&#039;;&lt;br /&gt;
 $CONF[&#039;database_prefix&#039;] = &amp;quot;&amp;quot;;&lt;br /&gt;
 $CONF[&#039;admin_email&#039;] = &#039;you@some.email.com&#039;;  &amp;lt;&amp;lt; Your email address &lt;br /&gt;
 $CONF[&#039;encrypt&#039;] = &#039;md5crypt&#039;;&lt;br /&gt;
 $CONF[&#039;authlib_default_flavor&#039;] = &#039;md5raw&#039;;&lt;br /&gt;
 $CONF[&#039;dovecotpw&#039;] = &amp;quot;/usr/sbin/dovecotpw&amp;quot;;&lt;br /&gt;
 $CONF[&#039;domain_path&#039;] = &#039;YES&#039;;&lt;br /&gt;
 $CONF[&#039;domain_in_mailbox&#039;] = &#039;NO&#039;;&lt;br /&gt;
 $CONF[&#039;aliases&#039;] = &#039;10&#039;;                       &lt;br /&gt;
 $CONF[&#039;mailboxes&#039;] = &#039;10&#039;;&lt;br /&gt;
 $CONF[&#039;maxquota&#039;] = &#039;10&#039;;&lt;br /&gt;
 $CONF[&#039;quota&#039;] = &#039;YES&#039;;&lt;br /&gt;
 $CONF[&#039;quota_multiplier&#039;] = &#039;1024000&#039;;&lt;br /&gt;
 $CONF[&#039;vacation&#039;] = &#039;NO&#039;; &lt;br /&gt;
 $CONF[&#039;vacation_control&#039;] =&#039;NO&#039;;&lt;br /&gt;
 $CONF[&#039;vacation_control_admin&#039;] = &#039;NO&#039;;&lt;br /&gt;
 $CONF[&#039;alias_control&#039;] = &#039;YES&#039;;&lt;br /&gt;
 $CONF[&#039;alias_control_admin&#039;] = &#039;YES&#039;;&lt;br /&gt;
 $CONF[&#039;special_alias_control&#039;] = &#039;YES&#039;;&lt;br /&gt;
 $CONF[&#039;fetchmail&#039;] = &#039;NO&#039;;&lt;br /&gt;
 $CONF[&#039;user_footer_link&#039;] = &amp;quot;http://host.example.com/postfixadmin&amp;quot;;&lt;br /&gt;
 $CONF[&#039;footer_link&#039;] = &#039;http://host.example.com/postfixadmin/main.php&#039;;&lt;br /&gt;
 $CONF[&#039;create_mailbox_subdirs_prefix&#039;]=&amp;quot;&amp;quot;;  &lt;br /&gt;
 $CONF[&#039;used_quotas&#039;] = &#039;YES&#039;;   &lt;br /&gt;
 $CONF[&#039;new_quota_table&#039;] = &#039;YES&#039;;  &lt;br /&gt;
&lt;br /&gt;
You should further edit /var/www/domains/host.example.com/www/postfixadmin/config.inc.php and replace all instances of &amp;quot;change-this-to-your.domain.tld&amp;quot; with your actual mail domain. This can be done with busybox sed (replace example.com with your domain name):&lt;br /&gt;
&lt;br /&gt;
 sed -i -e &#039;s/change-this-to-your.domain.tld/example.com/g&#039; /var/www/domains/host.example.com/www/postfixadmin/config.inc.php&lt;br /&gt;
&lt;br /&gt;
Go to http://host.example.com/postfixadmin/setup.php&lt;br /&gt;
&lt;br /&gt;
Create the password hash, add it to the config.inc.php file&lt;br /&gt;
&lt;br /&gt;
Go back to http://host.example.com/postfixadmin/setup.php&lt;br /&gt;
&lt;br /&gt;
Create superadmin account.&lt;br /&gt;
&lt;br /&gt;
== Install Postfix ==&lt;br /&gt;
&lt;br /&gt;
Create a user for the virtual mail delivery, and get its uid/gid (you&#039;ll need the numeric uid/gid for postfix)&lt;br /&gt;
&lt;br /&gt;
 adduser vmail -H -D -s /bin/false&lt;br /&gt;
 grep vmail /etc/passwd&lt;br /&gt;
&lt;br /&gt;
(In examples below, we use 1006/1006 for the uid/gid)&lt;br /&gt;
&lt;br /&gt;
Create the mail directory, and assign vmail as the owner&lt;br /&gt;
 mkdir -p /var/mail/domains&lt;br /&gt;
 chown -R vmail:vmail /var/mail/domains&lt;br /&gt;
 &lt;br /&gt;
&lt;br /&gt;
Install postfix&lt;br /&gt;
&lt;br /&gt;
 apk add acf-postfix postfix-pgsql&lt;br /&gt;
&lt;br /&gt;
Edit the /etc/postfix/main.cf file. Here&#039;s an example (don&#039;t forget to replace the uid/gid):&lt;br /&gt;
&lt;br /&gt;
 myhostname=host.example.com&lt;br /&gt;
 mydomain=example.com&lt;br /&gt;
 &lt;br /&gt;
 mydestination = localhost.$mydomain, localhost&lt;br /&gt;
 mynetworks_style = subnet&lt;br /&gt;
 mynetworks = 127.0.0.0/8&lt;br /&gt;
 &lt;br /&gt;
 virtual_mailbox_domains = proxy:pgsql:/etc/postfix/sql/pgsql_virtual_domains_maps.cf&lt;br /&gt;
 virtual_alias_maps = proxy:pgsql:/etc/postfix/sql/pgsql_virtual_alias_maps.cf,&lt;br /&gt;
        proxy:pgsql:/etc/postfix/sql/pgsql_virtual_alias_domain_maps.cf,&lt;br /&gt;
        proxy:pgsql:/etc/postfix/sql/pgsql_virtual_alias_domain_catchall_maps.cf&lt;br /&gt;
 &lt;br /&gt;
 virtual_mailbox_maps = proxy:pgsql:/etc/postfix/sql/pgsql_virtual_mailbox_maps.cf,&lt;br /&gt;
        proxy:pgsql:/etc/postfix/sql/pgsql_virtual_alias_domain_mailbox_maps.cf&lt;br /&gt;
 &lt;br /&gt;
 virtual_mailbox_base = /var/mail/domains/&lt;br /&gt;
 virtual_gid_maps = static:1006&lt;br /&gt;
 virtual_uid_maps = static:1006&lt;br /&gt;
 virtual_minimum_uid = 100&lt;br /&gt;
 virtual_transport = virtual&lt;br /&gt;
 &lt;br /&gt;
 &lt;br /&gt;
 # This next command means you must create a virtual&lt;br /&gt;
 # domain for the host itself - ALL mail goes through&lt;br /&gt;
 # The virtual transport&lt;br /&gt;
 &lt;br /&gt;
 mailbox_transport = virtual&lt;br /&gt;
 local_transport = virtual&lt;br /&gt;
 local_transport_maps = $virtual_mailbox_maps&lt;br /&gt;
 &lt;br /&gt;
 smtpd_helo_required = yes&lt;br /&gt;
 disable_vrfy_command = yes&lt;br /&gt;
 message_size_limit = 10240000&lt;br /&gt;
 queue_minfree = 51200000&lt;br /&gt;
 &lt;br /&gt;
 smtpd_sender_restrictions =&lt;br /&gt;
        permit_mynetworks,&lt;br /&gt;
        reject_non_fqdn_sender,&lt;br /&gt;
        reject_unknown_sender_domain&lt;br /&gt;
 &lt;br /&gt;
 smtpd_recipient_restrictions =&lt;br /&gt;
        reject_non_fqdn_recipient,&lt;br /&gt;
        reject_unknown_recipient_domain,&lt;br /&gt;
        permit_mynetworks,&lt;br /&gt;
        permit_sasl_authenticated,&lt;br /&gt;
        reject_unauth_destination,&lt;br /&gt;
        reject_rbl_client dnsbl.sorbs.net,&lt;br /&gt;
        reject_rbl_client zen.spamhaus.org,&lt;br /&gt;
        reject_rbl_client bl.spamcop.net&lt;br /&gt;
 &lt;br /&gt;
 smtpd_data_restrictions = reject_unauth_pipelining&lt;br /&gt;
 &lt;br /&gt;
 # we will use this later - This prevents cleartext authentication&lt;br /&gt;
 # for relaying&lt;br /&gt;
 smtpd_tls_auth_only = yes&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Now we need to create a *bunch* of files so that postfix can get the delivery information out of sql. Here&#039;s a shell script to create the scripts.  Change PGPW to the password for the postfix user of the postfix SQL database.&lt;br /&gt;
&lt;br /&gt;
 cd /etc/postfix&lt;br /&gt;
 mkdir sql&lt;br /&gt;
 PGPW=&amp;quot;ChangeMe&amp;quot;&lt;br /&gt;
 &lt;br /&gt;
 cat - &amp;lt;&amp;lt;EOF &amp;gt;sql/pgsql_virtual_alias_domain_catchall_maps.cf&lt;br /&gt;
 user=postfix&lt;br /&gt;
 password = $PGPW&lt;br /&gt;
 hosts = localhost&lt;br /&gt;
 dbname = postfix&lt;br /&gt;
 query = Select goto From alias,alias_domain where alias_domain.alias_domain = &#039;%d&#039; and alias.address = &#039;@&#039; ||  alias_domain.target_domain and alias.active = true and alias_domain.active= true &lt;br /&gt;
 EOF&lt;br /&gt;
 &lt;br /&gt;
 cat - &amp;lt;&amp;lt;EOF &amp;gt;sql/pgsql_virtual_alias_domain_mailbox_maps.cf&lt;br /&gt;
 user=postfix&lt;br /&gt;
 password = $PGPW&lt;br /&gt;
 hosts = localhost&lt;br /&gt;
 dbname = postfix&lt;br /&gt;
 query = Select maildir from mailbox,alias_domain where alias_domain.alias_domain = &#039;%d&#039; and mailbox.username = &#039;%u&#039; || &#039;@&#039; || alias_domain.target_domain and mailbox.active = true and alias_domain.active&lt;br /&gt;
 EOF&lt;br /&gt;
 &lt;br /&gt;
 cat - &amp;lt;&amp;lt;EOF &amp;gt;sql/pgsql_virtual_alias_domain_maps.cf&lt;br /&gt;
 user=postfix&lt;br /&gt;
 password = $PGPW&lt;br /&gt;
 hosts = localhost&lt;br /&gt;
 dbname = postfix&lt;br /&gt;
 query = select goto from alias,alias_domain where alias_domain.alias_domain=&#039;%d&#039; and alias.address = &#039;%u&#039; || &#039;@&#039; || alias_domain.target_domain and alias.active= true and alias_domain.active= true&lt;br /&gt;
 EOF&lt;br /&gt;
 &lt;br /&gt;
 cat - &amp;lt;&amp;lt;EOF &amp;gt;sql/pgsql_virtual_alias_maps.cf&lt;br /&gt;
 user=postfix&lt;br /&gt;
 password = $PGPW&lt;br /&gt;
 hosts = localhost&lt;br /&gt;
 dbname = postfix&lt;br /&gt;
 query = Select goto From alias Where address=&#039;%s&#039; and active =&#039;1&#039;&lt;br /&gt;
 EOF&lt;br /&gt;
 &lt;br /&gt;
 cat - &amp;lt;&amp;lt;EOF &amp;gt;sql/pgsql_virtual_domains_maps.cf&lt;br /&gt;
 user=postfix&lt;br /&gt;
 password = $PGPW&lt;br /&gt;
 hosts = localhost&lt;br /&gt;
 dbname = postfix&lt;br /&gt;
 query = Select domain from domain where domain=&#039;%s&#039; and active=&#039;1&#039;&lt;br /&gt;
 EOF&lt;br /&gt;
 &lt;br /&gt;
 cat - &amp;lt;&amp;lt;EOF &amp;gt;sql/pgsql_virtual_mailbox_maps.cf&lt;br /&gt;
 user=postfix&lt;br /&gt;
 password = $PGPW&lt;br /&gt;
 hosts = localhost&lt;br /&gt;
 dbname = postfix&lt;br /&gt;
 query = Select maildir from mailbox where username=&#039;%s&#039; and active=true&lt;br /&gt;
 EOF&lt;br /&gt;
 &lt;br /&gt;
 chown -R postfix:postfix sql&lt;br /&gt;
 chmod 640 sql/*&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
At this point you should be able to start up postfix&lt;br /&gt;
 &lt;br /&gt;
 newaliases  # so postfix is happy...&lt;br /&gt;
 /etc/init.d/postfix start&lt;br /&gt;
 rc-update add postfix&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Create a domain in PostfixAdmin and test ===&lt;br /&gt;
&lt;br /&gt;
Go to http://host.example.com/postfixadmin/&lt;br /&gt;
&lt;br /&gt;
Log in using the superadmin account, create a domain for the local box (e.g. example.com), and create a user mailbox (e.g. root).&lt;br /&gt;
&lt;br /&gt;
From the machine, send a test message:&lt;br /&gt;
&lt;br /&gt;
 sendmail -t root@example.com&lt;br /&gt;
 subject: test&lt;br /&gt;
 .&lt;br /&gt;
 ^d&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
In /var/log/mail.log (or /var/log/messages, if you still have busybox syslogd running) you should see the message queued.  The message should be in /var/mail/domains/example.com/root/new&lt;br /&gt;
&lt;br /&gt;
== Install Dovecot ==&lt;br /&gt;
&lt;br /&gt;
Dovecot is the POP3/IMAP server to retrieve mail.&lt;br /&gt;
&lt;br /&gt;
As before, we install dovecot: &lt;br /&gt;
&lt;br /&gt;
 apk add acf-dovecot dovecot-pgsql&lt;br /&gt;
&lt;br /&gt;
edit /etc/dovecot/dovecot.conf&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 # Select only the protocols you wish to support - all are listed in the next line&lt;br /&gt;
 protocols               =       imap imaps pop pop3s&lt;br /&gt;
 log_path                =       /var/log/dovecot.log&lt;br /&gt;
 info_log_path           =       /var/log/dovecot-info.log&lt;br /&gt;
 disable_plaintext_auth  =       no&lt;br /&gt;
&lt;br /&gt;
 # Authenticated IMAP&lt;br /&gt;
 ssl                     =       yes&lt;br /&gt;
 ssl_cert_file           =       /etc/lighttpd/server-bundle.pem&lt;br /&gt;
 ssl_key_file            =       /etc/lighttpd/server-bundle.pem&lt;br /&gt;
 auth_verbose            =       yes&lt;br /&gt;
 auth_debug              =       no&lt;br /&gt;
 mail_location           =       maildir:/var/mail/domains/%d/%n&lt;br /&gt;
 auth default    {&lt;br /&gt;
        mechanisms = plain&lt;br /&gt;
        passdb sql {&lt;br /&gt;
                args = /etc/dovecot/dovecot-sql.conf&lt;br /&gt;
                }&lt;br /&gt;
        userdb static {&lt;br /&gt;
                args =  uid=1006 gid=1006 home=/var/mail/domains/%d/%n&lt;br /&gt;
                }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Be sure to replace the uid and gid with the appropriate values for the vmail user.&lt;br /&gt;
&lt;br /&gt;
We need a certificate for SSL/TLS authentication, so in the example above, we use the lighttpd cert. That way when the cert is renewed/replaced, Dovecot will have access to the new cert as well.  &lt;br /&gt;
&lt;br /&gt;
Create the /etc/dovecot/dovecot-sql.conf file:&lt;br /&gt;
&lt;br /&gt;
 driver = pgsql&lt;br /&gt;
 connect = host=localhost dbname=postfix user=postfix password=********&lt;br /&gt;
 password_query = select username,password from mailbox where local_part = &#039;%n&#039; and domain = &#039;%d&#039;&lt;br /&gt;
 default_pass_scheme =  MD5-CRYPT&lt;br /&gt;
&lt;br /&gt;
Again, change the password above to your postfix user password, and protect the file from prying eyes:&lt;br /&gt;
&lt;br /&gt;
 chown root:root /etc/dovecot/dovecot-sql.conf&lt;br /&gt;
 chmod 600 /etc/dovecot/dovecot-sql.conf&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Start dovecot&lt;br /&gt;
 /etc/init.d/dovecot start&lt;br /&gt;
 rc-update add dovecot&lt;br /&gt;
&lt;br /&gt;
== Testing ==&lt;br /&gt;
&lt;br /&gt;
Make sure your firewall allows in ports 25(SMTP) 110 (POP3), 995 (POP3S), 143(IMAP), 993(IMAPS), or whatever subset you support.  &lt;br /&gt;
 &lt;br /&gt;
At this point, you should be able to:&lt;br /&gt;
 * Create a new domain and add users with PostfixAdmin&lt;br /&gt;
 * Send mail to those users via SMTP to port 25&lt;br /&gt;
 * Retrieve mail using the user&#039;s full email and password (e.g. username: user@example.com  password: ChangeMe)&lt;br /&gt;
&lt;br /&gt;
== Value Add Features ==&lt;br /&gt;
&lt;br /&gt;
If you followed the guide above, you now have a functional mail server with many interconnected parts.  The features below assume that the server is already running as described above.  You should be able to add any or all of these features below to further enhance the mail service.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Virus Scanning ===&lt;br /&gt;
&lt;br /&gt;
This procedure uses clamav and the postfix content_filter mechanism to scan inbound and outbound email for viruses.  Infected emails are dropped.  Clean emails are tagged with a &amp;quot;scanned by clamav&amp;quot; header.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* Install clamav and clamsmtp:&lt;br /&gt;
 apk add acf-clamav clamsmtp&lt;br /&gt;
* Edit the /etc/clamav/clamd.conf file if desired (not necessary in most cases)&lt;br /&gt;
* Edit /etc/clamsmtpd.conf and verify the following lines&lt;br /&gt;
 OutAddress: 10026&lt;br /&gt;
 Listen: 127.0.0.1:10025                                               &lt;br /&gt;
 Header: X-Virus-Scanned: ClamAV using ClamSMTP&lt;br /&gt;
 Action: drop&lt;br /&gt;
 User: clamav                                                      &lt;br /&gt;
* Start the daemons&lt;br /&gt;
 rc-update add clamd&lt;br /&gt;
 rc-update add clamsmtpd&lt;br /&gt;
 /etc/init.d/clamd start&lt;br /&gt;
 /etc/init.d/clamsmtpd start&lt;br /&gt;
* Verify clamsmtp is listening on port 10025:&lt;br /&gt;
 netstat -anp | grep clamsmtp&lt;br /&gt;
* [http://memberwebs.com/stef/software/clamsmtp/postfix.html Following the clamsmtp instructions]&lt;br /&gt;
** edit /etc/postfix/main.cf and add:&lt;br /&gt;
 content_filter = scan:[127.0.0.1]:10025                                                      &lt;br /&gt;
** edit /etc/postfix/master.cf and add&lt;br /&gt;
 # AV scan filter (used by content_filter)&lt;br /&gt;
 scan      unix  -       -       n       -       16      smtp&lt;br /&gt;
         -o smtp_send_xforward_command=yes&lt;br /&gt;
         -o smtp_enforce_tls=no&lt;br /&gt;
 # For injecting mail back into postfix from the filter&lt;br /&gt;
 127.0.0.1:10026 inet  n -       n       -       16      smtpd&lt;br /&gt;
         -o content_filter=&lt;br /&gt;
         -o receive_override_options=no_unknown_recipient_checks,no_header_body_checks&lt;br /&gt;
         -o smtpd_helo_restrictions=&lt;br /&gt;
         -o smtpd_client_restrictions=&lt;br /&gt;
         -o smtpd_sender_restrictions=&lt;br /&gt;
         -o smtpd_recipient_restrictions=permit_mynetworks,reject&lt;br /&gt;
         -o mynetworks_style=host&lt;br /&gt;
         -o smtpd_authorized_xforward_hosts=127.0.0.0/8&lt;br /&gt;
* postfix reload&lt;br /&gt;
* Send and email into a local virtual domain - it should have the &#039;&#039;X-Virus-Scanned: ClamAV using ClamSMTP&#039;&#039; header.&lt;br /&gt;
&lt;br /&gt;
=== Relay for Authenticated Users ===&lt;br /&gt;
&lt;br /&gt;
As configured above, the mail server accepts email from the Internet, but it does not relay email.  If it is a perimeter exchanger for a protected network, then you can add the protected networks to the &#039;&#039;mynetworks&#039;&#039; configuration line in /etc/postfix/main.cf&lt;br /&gt;
&lt;br /&gt;
This configuration change allows &#039;&#039;remote&#039;&#039; users to authenticate against the mail server and relay through it.  The rules for relaying are:&lt;br /&gt;
* Only authenticated users can relay&lt;br /&gt;
* Authentication Credentials must be encrypted with TLS or SSL&lt;br /&gt;
* Allow Submission and SMTPS ports for relaying (many consumer networks block port 25 - SMTP by default)&lt;br /&gt;
The process uses the dovecot authentication mechanism (used with IMAPS) to authenticate users before they are allowed to relay through postfix.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* Edit /etc/dovecot/dovecot.conf and add teh following inside the &#039;&#039;auth default&#039;&#039; stanza:&lt;br /&gt;
 # this is for postfix SASL (authenticated users can relay through us)&lt;br /&gt;
 socket listen {&lt;br /&gt;
                client {&lt;br /&gt;
                        path    = /var/spool/postfix/private/dovecot-auth.sock&lt;br /&gt;
                        mode    = 0660&lt;br /&gt;
                        user    = postfix&lt;br /&gt;
                        group   = postfix&lt;br /&gt;
                        }&lt;br /&gt;
                }&lt;br /&gt;
        }&lt;br /&gt;
* Restart dovecot&lt;br /&gt;
 /etc/init.d/dovecot restart&lt;br /&gt;
* Edit /etc/postfix/main.cf and add:&lt;br /&gt;
 # TLS Stuff -- since we allow SASL with tls *only*, we have to set up TLS first                    &lt;br /&gt;
 &lt;br /&gt;
 smtpd_tls_cert_file = /etc/lighttpd/server-bundle.pem&lt;br /&gt;
 smtpd_tls_key_file = /etc/lighttpd/server-bundle.pem&lt;br /&gt;
 smtpd_tls_CAfile = /etc/lighttpd/ca-crt.pem&lt;br /&gt;
 # If tls_security_level is set to &amp;quot;encrypt&amp;quot;, then SMTP rejects &lt;br /&gt;
 # unencrypted email (e.g. normal mail) which is bad.&lt;br /&gt;
 # By setting it to &amp;quot;may&amp;quot; you get TLS encrypted mail from google, slashdot, and other &lt;br /&gt;
 # interesting places.  Check your logs to see who&lt;br /&gt;
 smtpd_tls_security_level = may&lt;br /&gt;
 # Log info about the negotiated encryption levels&lt;br /&gt;
 smtpd_tls_received_header = yes&lt;br /&gt;
 smtpd_tls_loglevel = 1&lt;br /&gt;
 &lt;br /&gt;
 # SASL - this allows senders to authenticiate themselves&lt;br /&gt;
 # This along with &amp;quot;permit_sasl_authenticated&amp;quot; in smtpd_recipient_restrictions allows relaying&lt;br /&gt;
 smtpd_sasl_type = dovecot&lt;br /&gt;
 smtpd_sasl_path = private/dovecot-auth.sock&lt;br /&gt;
 smtpd_sasl_auth_enable = yes&lt;br /&gt;
 smtpd_sasl_authenticated_header = yes&lt;br /&gt;
 smtpd_tls_auth_only = yes&lt;br /&gt;
* Edit /etc/postfix/master.cf and enable the submission and smtps transports.  They are probably already at the top of your  master.cf file, just commented out:&lt;br /&gt;
 submission inet n       -       n       -       -       smtpd&lt;br /&gt;
   -o smtpd_tls_security_level=encrypt&lt;br /&gt;
   -o smtpd_sasl_auth_enable=yes&lt;br /&gt;
   -o smtpd_client_restrictions=permit_sasl_authenticated,reject&lt;br /&gt;
   -o milter_macro_daemon_name=ORIGINATING&lt;br /&gt;
 smtps     inet  n       -       n       -       -       smtpd&lt;br /&gt;
   -o smtpd_tls_security_level=encrypt&lt;br /&gt;
   -o smtpd_tls_wrappermode=yes&lt;br /&gt;
   -o smtpd_sasl_auth_enable=yes&lt;br /&gt;
   -o smtpd_client_restrictions=permit_sasl_authenticated,reject&lt;br /&gt;
   -o milter_macro_daemon_name=ORIGINATING&lt;br /&gt;
*Verfiy submission and smtps are defined in /etc/services&lt;br /&gt;
 grep &amp;quot;submission\|ssmtp&amp;quot; /etc/services&lt;br /&gt;
 submission	587/tcp				# mail message submission&lt;br /&gt;
 submission	587/udp&lt;br /&gt;
 smtps		465/tcp		ssmtp		# smtp protocol over TLS/SSL&lt;br /&gt;
 smtps		465/udp		ssmtp&lt;br /&gt;
* Restart postfix&lt;br /&gt;
 postfix reload&lt;br /&gt;
&lt;br /&gt;
At this point, you should be able to set up a mail client to relay through the server with TLS (port 587) or SSL (port 465)  Note that &amp;quot;plain&amp;quot; authentication is used because the underlying link is encrypted.  For example, in Thunderbird leave &amp;quot;secure authentication&amp;quot; unchecked, and choose STARTTLS (or TLS) for the connection security.&lt;br /&gt;
&lt;br /&gt;
=== Mailbox Quotas ===&lt;br /&gt;
&lt;br /&gt;
In the default configuration, PostfixAdmin knows about quotas, but they are not enforced.   Documentation on the web mentions the [http://vda.sourceforge.net vda patch to postfix] to enforce quotas.  The only bad thing... its a &#039;&#039;patch&#039;&#039;.   Postfix and Dovecot are both conservative systems, so if the patch isn&#039;t in the upstream source, we&#039;ll assume there&#039;s a good reason.   There is a way of using quotas without patches - and it involves using dovecot&#039;s [http://wiki.dovecot.org/LDA deliver] lda for local delivery.&lt;br /&gt;
&lt;br /&gt;
Note: As of Jan 2010, the documention is confusing, with multiple versions of dovecot, PostfixAdmin, and Mysql referenced.  These instructions apply to:&lt;br /&gt;
* Postgresql 8.4.2 &lt;br /&gt;
* PostfixAdmin 2.3 &lt;br /&gt;
* Dovecot 1.2.11&lt;br /&gt;
* Postfix 2.6.5&lt;br /&gt;
&lt;br /&gt;
Presumably later versions will work the same, but if not, please update the documentation and versions above.&lt;br /&gt;
&lt;br /&gt;
* Update /etc/dovecot/dovecot.conf (old lines shown commented out):&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
# old postfix &lt;br /&gt;
#       userdb static {&lt;br /&gt;
#               args =  uid=1006 gid=1006 home=/var/mail/domains/%d/%n&lt;br /&gt;
#               }&lt;br /&gt;
&lt;br /&gt;
# new quota support:&lt;br /&gt;
        userdb prefetch {&lt;br /&gt;
                }&lt;br /&gt;
&lt;br /&gt;
        userdb sql {&lt;br /&gt;
                args = /etc/dovecot/dovecot-sql.conf&lt;br /&gt;
                }&lt;br /&gt;
&lt;br /&gt;
        socket listen {&lt;br /&gt;
                client {&lt;br /&gt;
                        path    = /var/spool/postfix/private/dovecot-auth.sock&lt;br /&gt;
                        mode    = 0660&lt;br /&gt;
                        user    = postfix&lt;br /&gt;
                        group   = postfix&lt;br /&gt;
                        }&lt;br /&gt;
                # These lines below are for the deliver lda&lt;br /&gt;
                master {&lt;br /&gt;
                        path =  /var/run/dovecot/auth-master&lt;br /&gt;
                        mode    = 0660&lt;br /&gt;
                        user    = vmail&lt;br /&gt;
                        group   = vmail&lt;br /&gt;
                        }&lt;br /&gt;
                }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
protocol imap {                                                               &lt;br /&gt;
         mail_plugins = quota imap_quota                                       &lt;br /&gt;
         }                                                                     &lt;br /&gt;
                                                                              &lt;br /&gt;
protocol pop3 {                                                               &lt;br /&gt;
         mail_plugins = quota                                                  &lt;br /&gt;
         }                                                                     &lt;br /&gt;
                                                                              &lt;br /&gt;
dict {                                                                        &lt;br /&gt;
        quotadict = pgsql:/etc/dovecot/dovecot-dict-quota.conf                &lt;br /&gt;
        }                                                                     &lt;br /&gt;
                                                                              &lt;br /&gt;
plugin {                                                                      &lt;br /&gt;
         quota = dict:user::proxy::quotadict                                   &lt;br /&gt;
         }                                                     &lt;br /&gt;
                                                              &lt;br /&gt;
protocol lda {                                                &lt;br /&gt;
   postmaster_address = postmaster@host.example.com&lt;br /&gt;
   mail_plugins = quota                                        &lt;br /&gt;
   auth_socket_path =  /var/run/dovecot/auth-master&lt;br /&gt;
   sendmail_path = /usr/sbin/sendmail&lt;br /&gt;
}                                                                            &lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
 &lt;br /&gt;
You should already have a &amp;lt;tt&amp;gt;socket-&amp;gt; listen-&amp;gt; client&amp;lt;/tt&amp;gt; section, but it is listed above to show where it goes in relationship to the &amp;lt;tt&amp;gt;socket -&amp;gt; listen -&amp;gt; master&amp;lt;/tt&amp;gt; section&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* edit &amp;lt;tt&amp;gt;/etc/dovecot/dovecot-sql.conf&amp;lt;/tt&amp;gt; and replace the user and password queries with the following (you may not have a user_query yet - add it):&lt;br /&gt;
&lt;br /&gt;
 password_query = select username as user, password, 1006 as userdb_uid, 1006 as userdb_gid, &#039;*:bytes=&#039; || quota as userdb_quota_rule from mailbox  where local_part = &#039;%n&#039; and domain = &#039;%d&#039;&lt;br /&gt;
 user_query = select &#039;/var/mail/domains/&#039; || maildir as home, 1006 as uid, 1006 as gid, &#039;*:bytes=&#039; || quota  as quota_rule from mailbox where local_part = &#039;%n&#039; and domain =&#039;%d&#039;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* create &amp;lt;tt&amp;gt;/etc/dovecot/dovecot-dict-quota.conf&amp;lt;/tt&amp;gt;&lt;br /&gt;
 connect = host=localhost dbname=postfix user=postfix password=********&lt;br /&gt;
 &lt;br /&gt;
 map {&lt;br /&gt;
         pattern = priv/quota/storage&lt;br /&gt;
         table = quota2&lt;br /&gt;
         username_field =username&lt;br /&gt;
         value_field = bytes&lt;br /&gt;
 }&lt;br /&gt;
 &lt;br /&gt;
 map {&lt;br /&gt;
        pattern= priv/quota/messages&lt;br /&gt;
        table = quota2&lt;br /&gt;
        username_field = username&lt;br /&gt;
        value_field = messages&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
Again, change the password above to your postfix user password, and protect the file from prying eyes:&lt;br /&gt;
  chown root:root /etc/dovecot/dovecot-dict-quota.conf&lt;br /&gt;
  chmod 600 /etc/dovecot/dovecot-dict-quota.conf&lt;br /&gt;
&lt;br /&gt;
Side note: [http://wiki.dovecot.org/Quota/Dict The Dovecot Quota Documentation] mentions the need for a trigger with pgsql.  This was created in the PostfixAdmin install, which is why you instantiated the pgsql language when creating the database.  If not, you will need to create the trigger, to reference the quota2 table, not the quota table mentioned in the dovecot docs.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* create a new transport for the dovecot lda.   Add the following to  /etc/postfix/master.cf:&lt;br /&gt;
 # The dovecot deliver lda&lt;br /&gt;
 dovecot   unix  -       n       n       -       -       pipe&lt;br /&gt;
   flags=DRhu user=vmail:vmail argv=/usr/libexec/dovecot/deliver -f ${sender} -d ${user}@${nexthop}&lt;br /&gt;
&lt;br /&gt;
* Edit the /etc/postfix/main.cf.  Replace &lt;br /&gt;
 virtual_transport = virtual &lt;br /&gt;
with&lt;br /&gt;
 virtual_transport = dovecot&lt;br /&gt;
 dovecot_destination_recipient_limit = 1&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;TODO&#039;&#039;&#039;  This will cause over-quota emails to bounce.   Which could be a source of backscatter.   We need a way of checking quota limits after RBL checking but before the message is accepted in the queue.&lt;br /&gt;
&lt;br /&gt;
=== WebMail (RoundCube) ===&lt;br /&gt;
&lt;br /&gt;
[http://roundcube.net/ RoundCube] is an &amp;quot;ajax /Web2.0&amp;quot; web-mail client.  These instructions are for the Alpine Linux 1.10 repository &lt;br /&gt;
&lt;br /&gt;
* Add the package and related php modules:&lt;br /&gt;
 apk add roundcubemail php-xml php-openssl php-mcrypt php-gd php-iconv&lt;br /&gt;
&lt;br /&gt;
* link the roundcube application back into the docroot&lt;br /&gt;
 ln -s /usr/share/webapps/roundcube /var/www/domains/host.example.com/www/roundcube&lt;br /&gt;
&lt;br /&gt;
* follow the instructions in /usr/share/webapps/roundcube/INSTALL:&lt;br /&gt;
 cd /usr/share/webapps/roundcube&lt;br /&gt;
 chown -R lighttpd:lighttpd temp logs&lt;br /&gt;
 &lt;br /&gt;
 su postgres&lt;br /&gt;
 createuser roundcube&lt;br /&gt;
   Shall the new role be a superuser? (y/n) n&lt;br /&gt;
   Shall the new role be allowed to create databases? (y/n) n&lt;br /&gt;
   Shall the new role be allowed to create more new roles? (y/n) y&lt;br /&gt;
 createdb -O roundcube -E UNICODE -T template0 roundcubemail&lt;br /&gt;
 psql roundcubemail&lt;br /&gt;
   roundcubemail=# ALTER USER roundcube WITH PASSWORD &#039;the_new_password&#039;;&lt;br /&gt;
   roundcubemail=# \c - roundcube&lt;br /&gt;
   roundcubemail=&amp;gt; \i /usr/share/webapps/roundcube/SQL/postgres.initial.sql&lt;br /&gt;
   roundcubemail=&amp;gt; \q&lt;br /&gt;
 exit&lt;br /&gt;
&lt;br /&gt;
* edit /etc/php/php.ini and set date.timezone to your local timezone, or to UTC&lt;br /&gt;
&lt;br /&gt;
* restart lighttpd to verify the new php libraries are used&lt;br /&gt;
 /etc/init.d/lighttpd restart&lt;br /&gt;
&lt;br /&gt;
* Point your browser to http://host.example.com/roundcube/installer&lt;br /&gt;
* Start installation&lt;br /&gt;
&lt;br /&gt;
For the specific configuration parameters in the install step:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!Property&lt;br /&gt;
!Setting&lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;enable_spellcheck&#039;&#039; ||   disabled &lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;identities_level&#039;&#039; ||  one identity with possibility to edit all params but not email address &lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;log driver&#039;&#039; || syslog &lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;sylog_id&#039;&#039; || roundcube &lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;syslog_facility&#039;&#039; || mailsubsystem &lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;db_dnsw&#039;&#039; || pgsql properties, as described above &lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;imap_host&#039;&#039; || 127.0.0.1 &lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;auto_create_user&#039;&#039; || enabled &lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;smtp_server&#039;&#039; ||  127.0.0.1&lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;smtp_port&#039;&#039; ||  25&lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;smtp_user/smtp_pass&#039;&#039; ||  enable &#039;&#039;Use Current IMAP username and password for SMTP authentication&#039;&#039;&lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;smtp_log&#039;&#039; ||  enable (optional, but gives additional log record)&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
The other items can be left at default settings, or adjusted if desired.&lt;br /&gt;
&lt;br /&gt;
* Follow the instructions in step 3 of the install to copy the files to the server&lt;br /&gt;
* You should now be able to get to roundcube at http://host.example.com/roundcube&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
After its working, the INSTALL file recommends removing the install directory.   If you want to keep the installer around later, you can simply change the ownership and permissions.  So do &#039;&#039;&#039;one&#039;&#039;&#039; of the following:&lt;br /&gt;
 cd /usr/share/webapps/roundcube&lt;br /&gt;
 rm -rf LICENSE UPGRADING INSTALL README CHANGELOG  SQL installer&lt;br /&gt;
or&lt;br /&gt;
 cd /usr/share/webapps/roundcube&lt;br /&gt;
 chown -R root:root LICENSE UPGRADING INSTALL README CHANGELOG  SQL installer&lt;br /&gt;
 chmod -R 600 LICENSE UPGRADING INSTALL README CHANGELOG SQL &lt;br /&gt;
 chmod 700 SQL installer&lt;br /&gt;
&lt;br /&gt;
==== Enable Plug-ins ====&lt;br /&gt;
&lt;br /&gt;
RoundCube has various useful plug-ins, which could be found in &#039;&#039;/usr/share/webapps/roundcube/plugins&#039;&#039; directory. For example you may want to enable &#039;&#039;password&#039;&#039; plug-in to let users change their passwords directly from RoundCube using an extra Password Tab added to User Settings.&lt;br /&gt;
&lt;br /&gt;
* Grant limited permissions for &#039;&#039;roundcube&#039;&#039; database role &lt;br /&gt;
 psql -U postgres postfix&lt;br /&gt;
   postfix=# GRANT UPDATE (password,modified) ON mailbox TO roundcube;&lt;br /&gt;
   postfix=# GRANT SELECT (username) ON mailbox TO roundcube;&lt;br /&gt;
   postfix=# GRANT INSERT ON log TO roundcube;&lt;br /&gt;
   postfix=# \q&lt;br /&gt;
&lt;br /&gt;
* Setup &#039;&#039;password&#039;&#039; plug-in parameters in &#039;&#039;/usr/share/webapps/roundcube/plugins/password/config.inc.php&#039;&#039;&lt;br /&gt;
 mv /usr/share/webapps/roundcube/plugins/password/config.inc.php.dist /usr/share/webapps/roundcube/plugins/password/config.inc.php&lt;br /&gt;
 vi /usr/share/webapps/roundcube/plugins/password/config.inc.php&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
$rcmail_config[&#039;password_minimum_length&#039;] = 7;&lt;br /&gt;
$rcmail_config[&#039;password_require_nonalpha&#039;] = true;&lt;br /&gt;
...&lt;br /&gt;
$rcmail_config[&#039;password_db_dsn&#039;] = &#039;pgsql://roundcube:&amp;lt;roundcube_password&amp;gt;@localhost/postfix&#039;;&lt;br /&gt;
...&lt;br /&gt;
$rcmail_config[&#039;password_query&#039;] = &amp;quot;UPDATE mailbox set password = %c, modified = NOW() where username = %u; INSERT INTO log (timestamp,username,domain,action,data) VALUES (NOW(),%u || &#039; (&#039; || %h || &#039;)&#039;,%d,&#039;edit_password&#039;,%u)&amp;quot;;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* Enable &#039;&#039;password&#039;&#039; plug-in&lt;br /&gt;
 vi /usr/share/webapps/roundcube/config/main.inc.php&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
...&lt;br /&gt;
$rcmail_config[&#039;plugins&#039;] = array(&#039;password&#039;);&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== OpenLDAP based Address Book ===&lt;br /&gt;
&lt;br /&gt;
This OpenLDAP configuration uses the SQL backend, which represents information stored in PostgreSQL as an LDAP subtree for Address Book functionality for email lookups, user authentication or even &lt;br /&gt;
replication account information between sites. This procedure uses some metainformation to translate LDAP queries to SQL queries, leaving relational schema untouched, which allows SQL and LDAP &lt;br /&gt;
applications to inter-operate without replication, and exchange data as needed. The SQL backend uses UnixODBC to connect to PostgresSQL. &lt;br /&gt;
&lt;br /&gt;
* Install OpenLDAP and ODBC&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
apk add openldap libldap openldap-back-sql php-ldap unixodbc psqlodbc ca-certificates&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Note&#039;&#039;&#039;: The psqlodbc package is currently unavailable&lt;br /&gt;
&lt;br /&gt;
* Update &amp;quot;postfix&amp;quot; database (it will add &#039;id&#039; columns to mailbox and domain tables, also will create tables and views to represent LDAP metainformation)&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Note&#039;&#039;&#039;: These instructions are for example domain example.com. So make sure you replaced all entries of &#039;example&#039; and &#039;com&#039; according to your domain name parts.&lt;br /&gt;
&lt;br /&gt;
Put the following into a new file called &#039;&#039;&#039;script&#039;&#039;&#039;:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
ALTER TABLE domain ADD COLUMN id SERIAL; &lt;br /&gt;
ALTER TABLE mailbox ADD COLUMN id SERIAL; &lt;br /&gt;
&lt;br /&gt;
CREATE TABLE ldap_entry_objclasses (&lt;br /&gt;
    entry_id integer NOT NULL,&lt;br /&gt;
    oc_name character varying(64)&lt;br /&gt;
);&lt;br /&gt;
&lt;br /&gt;
CREATE TABLE ldap_oc_mappings (&lt;br /&gt;
    name character varying(64) NOT NULL,&lt;br /&gt;
    keytbl character varying(64) NOT NULL,&lt;br /&gt;
    keycol character varying(64) NOT NULL,&lt;br /&gt;
    create_proc character varying(255),&lt;br /&gt;
    delete_proc character varying(255),&lt;br /&gt;
    expect_return integer NOT NULL&lt;br /&gt;
);&lt;br /&gt;
&lt;br /&gt;
ALTER TABLE ldap_oc_mappings ADD COLUMN id SERIAL;&lt;br /&gt;
ALTER TABLE ldap_oc_mappings ADD PRIMARY KEY (id);&lt;br /&gt;
&lt;br /&gt;
CREATE TABLE ldap_attr_mappings (&lt;br /&gt;
    oc_map_id integer NOT NULL REFERENCES ldap_oc_mappings(id),&lt;br /&gt;
    name character varying(255) NOT NULL,&lt;br /&gt;
    sel_expr character varying(255) NOT NULL,&lt;br /&gt;
    sel_expr_u character varying(255),&lt;br /&gt;
    from_tbls character varying(255) NOT NULL,&lt;br /&gt;
    join_where character varying(255),&lt;br /&gt;
    add_proc character varying(255),&lt;br /&gt;
    delete_proc character varying(255),&lt;br /&gt;
    param_order integer NOT NULL,&lt;br /&gt;
    expect_return integer NOT NULL&lt;br /&gt;
);&lt;br /&gt;
&lt;br /&gt;
ALTER TABLE ldap_attr_mappings ADD COLUMN id SERIAL;&lt;br /&gt;
ALTER TABLE ldap_attr_mappings ADD PRIMARY KEY (id);&lt;br /&gt;
&lt;br /&gt;
CREATE VIEW ldap_dcs AS&lt;br /&gt;
    ((SELECT (domain.id + 100000) AS id,&lt;br /&gt;
            (&#039;dc=&#039;::text || replace((domain.domain)::text, &#039;.&#039;::text, &#039;,dc=&#039;::text)) AS dn,&lt;br /&gt;
            1 AS oc_map_id,&lt;br /&gt;
            100000 AS parent,&lt;br /&gt;
            0 AS keyval,&lt;br /&gt;
            domain.domain&lt;br /&gt;
     FROM domain&lt;br /&gt;
     WHERE domain.domain &amp;lt;&amp;gt; &#039;ALL&#039;)&lt;br /&gt;
      UNION&lt;br /&gt;
     (SELECT 100000 AS id,&lt;br /&gt;
           (&#039;dc=&#039; || regexp_replace((domain.domain)::text, &#039;.*\\.&#039;, &#039;&#039;::text)) AS dn,&lt;br /&gt;
           1 AS oc_map_id,&lt;br /&gt;
           0 AS parent,&lt;br /&gt;
           0 AS keyval,&lt;br /&gt;
           (regexp_replace((domain.domain)::text, &#039;.*\\.&#039;, &#039;&#039;::text)) AS domain&lt;br /&gt;
      FROM domain&lt;br /&gt;
      WHERE domain.domain &amp;lt;&amp;gt; &#039;ALL&#039;&lt;br /&gt;
      LIMIT 1));&lt;br /&gt;
&lt;br /&gt;
CREATE VIEW ldap_entries AS&lt;br /&gt;
    SELECT mailbox.id,&lt;br /&gt;
    (((&#039;cn=&#039;::text || initcap(replace(split_part((mailbox.username)::text, &#039;@&#039;::text, 1), &#039;.&#039;::text, &#039; &#039;::text))) || &#039;,dc=&#039;::text) ||&lt;br /&gt;
             replace(regexp_replace((mailbox.username)::text, &#039;.*@&#039;, &#039;&#039;::text), &#039;.&#039;::text, &#039;,dc=&#039;::text)) AS dn,&lt;br /&gt;
          1 AS oc_map_id,&lt;br /&gt;
          (SELECT ldap_dcs.id&lt;br /&gt;
           FROM ldap_dcs&lt;br /&gt;
           WHERE ((ldap_dcs.domain)::text = (mailbox.domain)::text)) AS parent,&lt;br /&gt;
           mailbox.id AS keyval&lt;br /&gt;
           FROM mailbox&lt;br /&gt;
           UNION&lt;br /&gt;
           SELECT ldap_dcs.id,&lt;br /&gt;
                  ldap_dcs.dn,&lt;br /&gt;
                  ldap_dcs.oc_map_id,&lt;br /&gt;
                  ldap_dcs.parent,&lt;br /&gt;
                  ldap_dcs.keyval&lt;br /&gt;
           FROM ldap_dcs;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Finally, execute the commands in the file with:&lt;br /&gt;
 cat script | psql -U postfix postfix&lt;br /&gt;
 rm script&lt;br /&gt;
&lt;br /&gt;
* Fill out LDAP tables according to following example (make sure to separate values with TABs):&lt;br /&gt;
&lt;br /&gt;
Put the following into a new file called &#039;&#039;&#039;script&#039;&#039;&#039;:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
COPY ldap_oc_mappings (id, name, keytbl, keycol, create_proc, delete_proc, expect_return) FROM stdin;&lt;br /&gt;
1	exampleBox	mailbox	id	\N	\N	1&lt;br /&gt;
\.&lt;br /&gt;
COPY ldap_attr_mappings (id, oc_map_id, name, sel_expr, sel_expr_u, from_tbls, join_where, add_proc, delete_proc, param_order, expect_return) FROM stdin;&lt;br /&gt;
1	1	displayName	mailbox.name	\N	mailbox	\N	\N	\N	3	0&lt;br /&gt;
2	1	mail	mailbox.username	\N	mailbox	\N	\N	\N	3	0&lt;br /&gt;
3	1	cn	mailbox.name	\N	mailbox	\N	\N	\N	3	0&lt;br /&gt;
4	1	userPassword	&#039;{CRYPT}&#039;||mailbox.password	\N	mailbox	\N	\N	\N	3	0&lt;br /&gt;
\.&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Finally, execute the commands in the file with:&lt;br /&gt;
 cat script | psql -U postfix postfix&lt;br /&gt;
 rm script&lt;br /&gt;
&lt;br /&gt;
* Check that &amp;quot;ldap_dcs&amp;quot; view looks something like this:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
echo &#039;select * from ldap_dcs&#039; | psql -U postgres postfix&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
   id   |             dn              | oc_map_id | parent | keyval |       domain       &lt;br /&gt;
--------+-----------------------------+-----------+--------+--------+--------------------&lt;br /&gt;
 100000 | dc=com                      |         1 |      0 |      0 | com&lt;br /&gt;
 100001 | dc=example,dc=com           |         1 | 100000 |      0 | example.com&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* Check that &amp;quot;ldap_entries&amp;quot; view looks something like this:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
echo &#039;select * from ldap_entries&#039; | psql -U postgres postfix&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
   id   |                          dn                           | oc_map_id | parent | keyval &lt;br /&gt;
--------+-------------------------------------------------------+-----------+--------+--------&lt;br /&gt;
    1   | cn=address1,dc=example,dc=com                         |         1 | 100001 |    1&lt;br /&gt;
...&lt;br /&gt;
   123  | cn=address123,dc=example,dc=com                       |         1 | 100001 |    1&lt;br /&gt;
 100000 | dc=com                                                |         1 |      0 |    0&lt;br /&gt;
 100001 | dc=example,dc=com                                     |         1 | 100000 |    0&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* Configure ODBC parameters&lt;br /&gt;
&lt;br /&gt;
Edit /etc/odbc.ini:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
[PostgreSQL]&lt;br /&gt;
Description             = Connection to Postgres&lt;br /&gt;
Driver                  = PostgreSQL&lt;br /&gt;
Trace                   = Yes&lt;br /&gt;
TraceFile               = sql.log&lt;br /&gt;
Database                = postfix&lt;br /&gt;
Servername              = 127.0.0.1&lt;br /&gt;
UserName                =&lt;br /&gt;
Password                =&lt;br /&gt;
Port                    = 5432&lt;br /&gt;
Protocol                = 6.4&lt;br /&gt;
ReadOnly                = No&lt;br /&gt;
RowVersining            = No&lt;br /&gt;
ShowSystemTables        = No&lt;br /&gt;
ShowOidColumn           = No&lt;br /&gt;
FakeOidIndex            = No&lt;br /&gt;
ConnSettings            =&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Edit /etc/odbcinst.ini:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
[PostgreSQL]&lt;br /&gt;
Description     = PostgreSQL driver for Linux&lt;br /&gt;
Driver          = /usr/lib/psqlodbcw.so&lt;br /&gt;
Setup           = /usr/lib/libodbcpsqlS.so&lt;br /&gt;
FileUsage       = 1&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* Test ODBC connection&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
echo &amp;quot;select * from domain;&amp;quot; | isql PostgreSQL postgres&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* Provide permission to certificate for LDAP server&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
chown ldap /etc/lighttpd/server-bundle.pem&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* Edit LDAP schema&lt;br /&gt;
&lt;br /&gt;
Edit /etc/openldap/schema/example.com.schema:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
attributetype ( 0.9.2342.19200300.100.1.3&lt;br /&gt;
	NAME ( &#039;mail&#039; &#039;rfc822Mailbox&#039; )&lt;br /&gt;
	DESC &#039;RFC1274: RFC822 Mailbox&#039;&lt;br /&gt;
        EQUALITY caseIgnoreIA5Match&lt;br /&gt;
        SUBSTR caseIgnoreIA5SubstringsMatch&lt;br /&gt;
        SYNTAX 1.3.6.1.4.1.1466.115.121.1.26{256} )&lt;br /&gt;
&lt;br /&gt;
attributetype ( 2.16.840.1.113730.3.1.241&lt;br /&gt;
	NAME &#039;displayName&#039;&lt;br /&gt;
	DESC &#039;RFC2798: preferred name to be used when displaying entries&#039;&lt;br /&gt;
	EQUALITY caseIgnoreMatch&lt;br /&gt;
	SUBSTR caseIgnoreSubstringsMatch&lt;br /&gt;
	SYNTAX 1.3.6.1.4.1.1466.115.121.1.15&lt;br /&gt;
	SINGLE-VALUE )&lt;br /&gt;
&lt;br /&gt;
objectclass   ( 2.16.840.1.113730.3.2.2&lt;br /&gt;
        NAME &#039;exampleBox&#039;&lt;br /&gt;
	DESC &#039;example.com mailbox&#039;&lt;br /&gt;
	MUST ( displayName $ mail $ userPassword )&lt;br /&gt;
	)&lt;br /&gt;
&lt;br /&gt;
# RFC 1274 + RFC 2247&lt;br /&gt;
attributetype ( 0.9.2342.19200300.100.1.25&lt;br /&gt;
        NAME ( &#039;dc&#039; &#039;domainComponent&#039; )&lt;br /&gt;
        DESC &#039;RFC1274/2247: domain component&#039;&lt;br /&gt;
        EQUALITY caseIgnoreIA5Match&lt;br /&gt;
        SUBSTR caseIgnoreIA5SubstringsMatch&lt;br /&gt;
        SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 SINGLE-VALUE )&lt;br /&gt;
&lt;br /&gt;
attributetype ( 2.5.4.46 NAME &#039;dnQualifier&#039;&lt;br /&gt;
        DESC &#039;RFC2256: DN qualifier&#039;&lt;br /&gt;
        EQUALITY caseIgnoreMatch&lt;br /&gt;
        ORDERING caseIgnoreOrderingMatch&lt;br /&gt;
        SUBSTR caseIgnoreSubstringsMatch&lt;br /&gt;
        SYNTAX 1.3.6.1.4.1.1466.115.121.1.44 )&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* Configure LDAP server&lt;br /&gt;
&lt;br /&gt;
Edit /etc/openldap/slapd.conf:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
include         /etc/openldap/schema/example.com.schema&lt;br /&gt;
pidfile         /var/run/openldap/slapd.pid&lt;br /&gt;
argsfile        /var/run/openldap/slapd.args&lt;br /&gt;
&lt;br /&gt;
TLSCipherSuite HIGH&lt;br /&gt;
TLSCACertificateFile /etc/lighttpd/ca-crt.pem&lt;br /&gt;
TLSCertificateFile /etc/lighttpd/server-bundle.pem&lt;br /&gt;
TLSCertificateKeyFile /etc/lighttpd/server-bundle.pem&lt;br /&gt;
TLSVerifyClient never &lt;br /&gt;
&lt;br /&gt;
# This is needed for proper representation of MD5-CRYPT format stored in database&lt;br /&gt;
#  see more details in http://strugglers.net/~andy/blog/2010/01/23/openldap-and-md5crypt/&lt;br /&gt;
password-hash  {CRYPT}&lt;br /&gt;
password-crypt-salt-format &amp;quot;$1$%.8s&amp;quot;&lt;br /&gt;
&lt;br /&gt;
loglevel        stats&lt;br /&gt;
moduleload	/usr/lib/openldap/back_sql.so&lt;br /&gt;
sizelimit 3000&lt;br /&gt;
&lt;br /&gt;
database        sql&lt;br /&gt;
&lt;br /&gt;
dbname		PostgreSQL&lt;br /&gt;
dbuser		postfix&lt;br /&gt;
dbpasswd	*****&lt;br /&gt;
&lt;br /&gt;
suffix          &amp;quot;dc=example,dc=com&amp;quot;&lt;br /&gt;
&lt;br /&gt;
upper_func      &amp;quot;upper&amp;quot;&lt;br /&gt;
strcast_func    &amp;quot;text&amp;quot;&lt;br /&gt;
concat_pattern  &amp;quot;?||?&amp;quot;&lt;br /&gt;
has_ldapinfo_dn_ru      no&lt;br /&gt;
lastmod         off&lt;br /&gt;
&lt;br /&gt;
access to attrs=userPassword by * auth&lt;br /&gt;
&lt;br /&gt;
access to * by peername.ip=127.0.0.1 read&lt;br /&gt;
#           by peername.ip=&amp;lt;IP&amp;gt;%&amp;lt;netmask&amp;gt; read&lt;br /&gt;
#           by peername.ip=&amp;lt;IP&amp;gt; read&lt;br /&gt;
	    by users read&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* Set permissions for slapd.conf&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
chown ldap:ldap /etc/openldap/slapd.conf&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* Configure startup parameters to make sure that LDAP server start AFTER PostgreSQL and listens on localhost with clear text and public IP with SSL&lt;br /&gt;
&lt;br /&gt;
Edit /etc/conf.d/slapd:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
rc_need=&amp;quot;postgresql&amp;quot; &lt;br /&gt;
OPTS=&amp;quot;-h &#039;ldaps:// ldap://127.0.0.1&#039;&amp;quot;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* Start LDAP server&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
rc-update add slapd default&lt;br /&gt;
/etc/init.d/slapd start&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* Configure LDAP client utilities&lt;br /&gt;
&lt;br /&gt;
Edit /etc/openldap/ldap.conf&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
BASE	dc=example,dc=com&lt;br /&gt;
URI	ldaps://host.example.com&lt;br /&gt;
&lt;br /&gt;
TLS_CACERT /etc/lighttpd/ca-crt.pem&lt;br /&gt;
TLS_CERT /etc/lighttpd/server-bundle.pem&lt;br /&gt;
TLS_KEY /etc/lighttpd/server-bundle.pem&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* Test LDAP server&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
ldapsearch -z 3&lt;br /&gt;
ldapsearch -z 3 -x -W -D cn=admin,dc=example,dc=com&lt;br /&gt;
ldapsearch -z 3 -x -W -D cn=address1,dc=example,dc=com&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* Configure RoundCube webmail for email lookups&lt;br /&gt;
&lt;br /&gt;
In order to enable php-ldap support you need to restart lighttpd server&lt;br /&gt;
&lt;br /&gt;
 /etc/init.d/lighttpd restart&lt;br /&gt;
&lt;br /&gt;
Edit /usr/share/webapps/roundcube/config/main.inc.php:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
$rcmail_config[&#039;ldap_debug&#039;] = false;&lt;br /&gt;
...&lt;br /&gt;
$rcmail_config[&#039;address_book_type&#039;] = &#039;sql&#039;;&lt;br /&gt;
&lt;br /&gt;
$rcmail_config[&#039;ldap_public&#039;][&#039;example.com&#039;] = array(&lt;br /&gt;
  &#039;name&#039;          =&amp;gt; &#039;example.com&#039;,&lt;br /&gt;
  &#039;hosts&#039;         =&amp;gt; array(&#039;127.0.0.1&#039;),&lt;br /&gt;
  &#039;port&#039;          =&amp;gt; 389,&lt;br /&gt;
  &#039;use_tls&#039;         =&amp;gt; false,&lt;br /&gt;
  &#039;user_specific&#039; =&amp;gt; false,&lt;br /&gt;
  &#039;base_dn&#039;       =&amp;gt; &#039;dc=example,dc=com&#039;,&lt;br /&gt;
  &#039;bind_dn&#039;       =&amp;gt; &#039;&#039;,&lt;br /&gt;
  &#039;bind_pass&#039;     =&amp;gt; &#039;&#039;,&lt;br /&gt;
  &#039;writable&#039;      =&amp;gt; false,&lt;br /&gt;
  &#039;LDAP_Object_Classes&#039; =&amp;gt; array(&amp;quot;top&amp;quot;, &amp;quot;exampleBox&amp;quot;),&lt;br /&gt;
  &#039;required_fields&#039;     =&amp;gt; array(&amp;quot;cn&amp;quot;, &amp;quot;sn&amp;quot;, &amp;quot;mail&amp;quot;),&lt;br /&gt;
  &#039;LDAP_rdn&#039;      =&amp;gt; &#039;mail&#039;,&lt;br /&gt;
  &#039;ldap_version&#039;  =&amp;gt; 3,&lt;br /&gt;
  &#039;search_fields&#039; =&amp;gt; array(&#039;mail&#039;, &#039;cn&#039;, &#039;sn&#039;, &#039;givenName&#039;),&lt;br /&gt;
  &#039;name_field&#039;    =&amp;gt; &#039;cn&#039;,&lt;br /&gt;
  &#039;email_field&#039;   =&amp;gt; &#039;mail&#039;,&lt;br /&gt;
  &#039;surname_field&#039; =&amp;gt; &#039;sn&#039;,&lt;br /&gt;
  &#039;firstname_field&#039; =&amp;gt; &#039;gn&#039;,&lt;br /&gt;
  &#039;sort&#039;          =&amp;gt; &#039;cn&#039;,&lt;br /&gt;
  &#039;scope&#039;         =&amp;gt; &#039;sub&#039;,&lt;br /&gt;
  &#039;filter&#039;        =&amp;gt; &#039;(objectClass=*)&#039;, // Construct here any filter you need&lt;br /&gt;
  &#039;fuzzy_search&#039;  =&amp;gt; true);&lt;br /&gt;
&lt;br /&gt;
$rcmail_config[&#039;autocomplete_addressbooks&#039;] = array(&#039;sql&#039;,&#039;example.com&#039;);&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* Fix PostfixAdmin to work with the new table definition&lt;br /&gt;
&lt;br /&gt;
Edit /var/www/domains/example.com/www/list-domain.php. Replace the line:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
   SELECT domain.* , COUNT( DISTINCT mailbox.username ) AS mailbox_count&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
With the lines:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
   SELECT domain.domain, domain.description, domain.aliases, domain.mailboxes,&lt;br /&gt;
   domain.maxquota, domain.quota, domain.transport, domain.backupmx, domain.created,&lt;br /&gt;
   domain.modified, domain.active, COUNT( DISTINCT mailbox.username ) AS mailbox_count&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== log rotation ==&lt;br /&gt;
&lt;br /&gt;
Ensure the busybox cron service is started and is configured to auto-start:&lt;br /&gt;
&lt;br /&gt;
 /etc/init.d/cron start&lt;br /&gt;
 rc-update add cron default&lt;br /&gt;
&lt;br /&gt;
Add log rotate:&lt;br /&gt;
&lt;br /&gt;
 apk add logrotate&lt;br /&gt;
&lt;br /&gt;
Edit &#039;&#039;/etc/logrotate.conf&#039;&#039; as desired, but the defaults should be sufficient for most people.&lt;br /&gt;
&lt;br /&gt;
== Optional: Configure Web Server Virtual Domains ==&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Note:&#039;&#039;&#039; These steps can be done &#039;&#039;in addition to&#039;&#039; the default lighttpd configuration above, which allows you to access the ACF, PostfixAdmin and Roundcube interfaces as subfolders of one web service.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Note:&#039;&#039;&#039; If you provide SSL access for multiple domain site you may need to follow http://redmine.lighttpd.net/projects/lighttpd/wiki/Docs:SSL#SSL-on-multiple-domains in order to provide multi-domain certificates. If you would like to redirect hosts to their secure equivalents use the following instructions http://redmine.lighttpd.net/projects/lighttpd/wiki/HowToRedirectHttpToHttps.&lt;br /&gt;
&lt;br /&gt;
This server hosts three separate web applications, and these can be handled as three &#039;&#039;different&#039;&#039; virtual domains on the same web server. They will be distinguished by their DNS names, so you can choose domains for the three separate services (or at least the ones you want to publish):&lt;br /&gt;
&lt;br /&gt;
* ACF - Alpine Configuration Framework for managing the server&lt;br /&gt;
* PostfixAdmin - for managing the postfix installation&lt;br /&gt;
* RoundCube - for accessing individual mailboxes&lt;br /&gt;
&lt;br /&gt;
Choose three different domains (from here on known as ACF_DOMAIN, POSTFIXADMIN_DOMAIN, and ROUNDCUBE_DOMAIN) and configure DNS for all three to point to the IP address of your host. These should be DNS &#039;&#039;&#039;A&#039;&#039;&#039; records.&lt;br /&gt;
&lt;br /&gt;
Then, configure lighttpd to handle the three separate domains by editing /etc/lighttpd/lighttpd.conf:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 $HTTP[&amp;quot;host&amp;quot;] == &amp;quot;ACF_DOMAIN&amp;quot; {&lt;br /&gt;
	simple-vhost.server-root   = &amp;quot;/var/www/domains/&amp;quot;&lt;br /&gt;
	simple-vhost.default-host  = &amp;quot;/ACF_DOMAIN/&amp;quot;&lt;br /&gt;
	simple-vhost.document-root = &amp;quot;www/&amp;quot;&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
 $HTTP[&amp;quot;host&amp;quot;] == &amp;quot;POSTFIXADMIN_DOMAIN&amp;quot; {&lt;br /&gt;
	simple-vhost.server-root   = &amp;quot;/var/www/domains/&amp;quot;&lt;br /&gt;
	simple-vhost.default-host  = &amp;quot;/POSTFIXADMIN_DOMAIN/&amp;quot;&lt;br /&gt;
	simple-vhost.document-root = &amp;quot;www/&amp;quot;&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
 $HTTP[&amp;quot;host&amp;quot;] == &amp;quot;ROUNDCUBE_DOMAIN&amp;quot; {&lt;br /&gt;
	simple-vhost.server-root   = &amp;quot;/var/www/domains/&amp;quot;&lt;br /&gt;
	simple-vhost.default-host  = &amp;quot;/ROUNDCUBE_DOMAIN/&amp;quot;&lt;br /&gt;
	simple-vhost.document-root = &amp;quot;www/&amp;quot;&lt;br /&gt;
 }&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
And, then link the appropriate www directories.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  mkdir -p /var/www/domains/ACF_DOMAIN&lt;br /&gt;
  ln -s /usr/share/acf/www /var/www/domains/ACF_DOMAIN/www&lt;br /&gt;
&lt;br /&gt;
  mkdir -p /var/www/domains/POSTFIXADMIN_DOMAIN&lt;br /&gt;
  ln -s /var/www/domains/host.example.com/www/postfixadmin /var/www/domains/POSTFIXADMIN_DOMAIN/www&lt;br /&gt;
&lt;br /&gt;
  mkdir -p /var/www/domains/ROUNDCUBE_DOMAIN&lt;br /&gt;
  ln -s /usr/share/webapps/roundcube /var/www/domains/ROUNDCUBE_DOMAIN/www&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;/div&gt;</summary>
		<author><name>Djhughes</name></author>
	</entry>
	<entry>
		<id>https://wiki.alpinelinux.org/w/index.php?title=ISP_Mail_Server_HowTo&amp;diff=3509</id>
		<title>ISP Mail Server HowTo</title>
		<link rel="alternate" type="text/html" href="https://wiki.alpinelinux.org/w/index.php?title=ISP_Mail_Server_HowTo&amp;diff=3509"/>
		<updated>2010-03-30T09:16:10Z</updated>

		<summary type="html">&lt;p&gt;Djhughes: minor&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== A Full Service Mail Server ==&lt;br /&gt;
&lt;br /&gt;
The goal of this document is to describe how to set up postfix, dovecot, clamav, dspam, roundecube, and postfixadmin for a full-featured &amp;quot;ISP&amp;quot; level mail server.&lt;br /&gt;
&lt;br /&gt;
The server must provide:&lt;br /&gt;
&lt;br /&gt;
* multiple virtual domains&lt;br /&gt;
* admins for each domain (to add/remove virtual accounts)&lt;br /&gt;
* Quota support per domain / account&lt;br /&gt;
* downloading email via IMAP / IMAPS / POP3 / POP3S&lt;br /&gt;
* relaying email for authenticated users with TLS or SSL (Submission / SMTPS protocol)&lt;br /&gt;
* Standard filters (virus/spam/rbl/etc)&lt;br /&gt;
* Web mail client&lt;br /&gt;
* Value Add services&lt;br /&gt;
&lt;br /&gt;
== Set up Lighttpd + PHP ==&lt;br /&gt;
&lt;br /&gt;
PostfixAdmin needs php pgpsql and imap modules, so we do it in this step.&lt;br /&gt;
&lt;br /&gt;
  apk add lighttpd php php-pgsql php-imap&lt;br /&gt;
&lt;br /&gt;
Stop and remove mini_httpd, and move ACF to lighttpd;  We are setting this up to be a multi-domain virtual web server (replace host.example.com with the actual domain):&lt;br /&gt;
&lt;br /&gt;
  mkdir -p /var/www/domains/host.example.com/www&lt;br /&gt;
  ln -s /usr/share/acf/www /var/www/domains/host.example.com/www/acf&lt;br /&gt;
&lt;br /&gt;
Edit /var/www/domains/host.example.com/index.html to put a simple redirection page:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;lt;!DOCTYPE HTML PUBLIC &amp;quot;-//W3C//DTD HTML 4.01//EN&amp;quot; &amp;quot;http://www.w3.org/TR/html4/strict.dtd&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;html lang=&amp;quot;en&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;head&amp;gt;&lt;br /&gt;
&amp;lt;meta http-equiv=&amp;quot;Content-Type&amp;quot; content=&amp;quot;text/html; charset=ISO-8859-1&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;title&amp;gt;host.example.com Redirector&amp;lt;/title&amp;gt;&lt;br /&gt;
&amp;lt;/head&amp;gt;&lt;br /&gt;
&amp;lt;body&amp;gt;&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;&amp;lt;a href=&amp;quot;/acf&amp;quot;&amp;gt;ACF&amp;lt;/a&amp;gt;&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;&amp;lt;a href=&amp;quot;/postfixadmin&amp;quot;&amp;gt;PostfixAdmin&amp;lt;/a&amp;gt;&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;&amp;lt;a href=&amp;quot;/roundcube&amp;quot;&amp;gt;Roundcube&amp;lt;/a&amp;gt;&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
&amp;lt;/body&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Edit /etc/lighttpd/mod_cgi.conf to serve haserl files by adding a &amp;quot;&amp;quot; =&amp;gt; &amp;quot;&amp;quot; cgi handler and to treat /acf/cgi-bin as a CGI directory (remove the &#039;^&#039;)&lt;br /&gt;
&lt;br /&gt;
 $HTTP[&amp;quot;url&amp;quot;] =~ &amp;quot;/cgi-bin/&amp;quot; {&lt;br /&gt;
     # disable directory listings&lt;br /&gt;
     dir-listing.activate = &amp;quot;disable&amp;quot;&lt;br /&gt;
     # only allow cgi&#039;s in this directory&lt;br /&gt;
     cgi.assign = (&lt;br /&gt;
 		&amp;quot;.pl&amp;quot;	=&amp;gt;	&amp;quot;/usr/bin/perl&amp;quot;,&lt;br /&gt;
 		&amp;quot;.cgi&amp;quot;	=&amp;gt;	&amp;quot;/usr/bin/perl&amp;quot;,&lt;br /&gt;
 		&amp;quot;&amp;quot; =&amp;gt; &amp;quot;&amp;quot;&lt;br /&gt;
 	)&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
Add these lines to /etc/lighttpd/lighttpd.conf to point to the new document root, and set it up to listen on port 443 (replace &#039;&#039;host.example.com&#039;&#039; with the actual domain and &#039;&#039;ip_address_of_server&#039;&#039; with the actual IP address):&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
simple-vhost.server-root   = &amp;quot;/var/www/domains/&amp;quot;&lt;br /&gt;
simple-vhost.default-host  = &amp;quot;/host.example.com/&amp;quot;&lt;br /&gt;
simple-vhost.document-root = &amp;quot;www/&amp;quot;&lt;br /&gt;
&lt;br /&gt;
$SERVER[&amp;quot;socket&amp;quot;] == &amp;quot;ip_address_of_server:443&amp;quot; {&lt;br /&gt;
ssl.engine    = &amp;quot;enable&amp;quot;&lt;br /&gt;
ssl.pemfile   = &amp;quot;/etc/lighttpd/server-bundle.pem&amp;quot;&lt;br /&gt;
ssl.ca-file   = &amp;quot;/etc/lighttpd/ca-crt.pem&amp;quot;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Ensure that the simple_vhosts module is loaded, as well as the cgi config scripts by uncommenting the following lines in /etc/lighttpd/lighttpd.conf&lt;br /&gt;
&lt;br /&gt;
 server.modules = (&lt;br /&gt;
     #  other modules may be listed&lt;br /&gt;
     &amp;quot;mod_simple_vhost&amp;quot;, &lt;br /&gt;
     #  other modules may be listed&lt;br /&gt;
  .&lt;br /&gt;
  .&lt;br /&gt;
  .&lt;br /&gt;
     include &amp;quot;mod_cgi.conf&amp;quot;&lt;br /&gt;
 &lt;br /&gt;
     include &amp;quot;mod_fastcgi.conf&amp;quot;&lt;br /&gt;
 &lt;br /&gt;
&lt;br /&gt;
Get a web certificate, and install it.  If you want to use a self-signed cert, you can use [[Generating SSL certs with ACF]] or [[Generating SSL certs with ACF 1.9]].  If you create a certificate with ACF, you can create the &amp;quot;server-bundle.pem&amp;quot; and the &amp;quot;ca-crt.pem&amp;quot; file with these commands:&lt;br /&gt;
&lt;br /&gt;
  openssl pkcs12 -nokeys -cacerts -in certificate.pfx  -out /etc/lighttpd/ca-crt.pem&lt;br /&gt;
  openssl pkcs12 -nodes -in certifcate.pfx -out /etc/lighttpd/server-bundle.pem&lt;br /&gt;
  chown root:root /etc/lighttpd/server-bundle.pem&lt;br /&gt;
  chmod 400 /etc/lighttpd/server-bundle.pem&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Note:&#039;&#039;&#039; The server certificate &#039;&#039;and&#039;&#039; key are in the server-bundle.pem file, so it is critical that the file be read-only by user &amp;quot;root&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
 Editme: We should probably only serve ACF to restricted hosts&lt;br /&gt;
&lt;br /&gt;
Stop and remove mini_httpd; start lighttpd, test&lt;br /&gt;
&lt;br /&gt;
  /etc/init.d/mini_httpd stop&lt;br /&gt;
  rc-update del mini_httpd&lt;br /&gt;
  apk del mini_httpd&lt;br /&gt;
  rc-update add lighttpd&lt;br /&gt;
  /etc/init.d/lighttpd start&lt;br /&gt;
&lt;br /&gt;
At this point you should be able to see ACF being served with lighttpd (Note: this will work well with alpine 1.10. With earlier versions there will be problems.)  https://host.example.com/acf/&lt;br /&gt;
&lt;br /&gt;
== Install Postgresql ==&lt;br /&gt;
&lt;br /&gt;
Add and configure postgresql&lt;br /&gt;
&lt;br /&gt;
  apk add acf-postgresql postgresql-client&lt;br /&gt;
  /etc/init.d/postgresql setup&lt;br /&gt;
  /etc/init.d/postgresql start&lt;br /&gt;
  rc-update add postgresql&lt;br /&gt;
&lt;br /&gt;
At this point any user can connect to the sql server with &amp;quot;trust&amp;quot; mechanism.  If you want to enforce password authentication (you probably do) edit /var/lib/postgresql/8.4/data/pg_hba.conf&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
  Editme: What should we recommend?&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Create the postfix database:&lt;br /&gt;
&lt;br /&gt;
  psql -U postgres&lt;br /&gt;
   create user postfix with password &#039;******&#039;;&lt;br /&gt;
   create database postfix owner postfix;&lt;br /&gt;
   \c postfix&lt;br /&gt;
   create language plpgsql;&lt;br /&gt;
   \q&lt;br /&gt;
&lt;br /&gt;
(Of course, use your selected password where ******* is shown above.)&lt;br /&gt;
&lt;br /&gt;
== Install PostfixAdmin ==&lt;br /&gt;
&lt;br /&gt;
We are going to install the postfix admin web front-end before we install the mail server.  This just creates an interface to populate the SQL tables that postfix and dovecot will use.&lt;br /&gt;
&lt;br /&gt;
Download PostfixAdmin from Sourceforge.  When these instructions were written, 2.3 was the current release, so (replace host.example.com with the actual domain):&lt;br /&gt;
 wget http://downloads.sourceforge.net/project/postfixadmin/postfixadmin/postfixadmin_2.3.tar.gz&lt;br /&gt;
 tar zxvf postfixadmin_2.3.tar.gz&lt;br /&gt;
 mkdir -p /var/www/domains/host.example.com/www/postfixadmin&lt;br /&gt;
 mv postfixadmin-2.3/* /var/www/domains/host.example.com/www/postfixadmin&lt;br /&gt;
 rm -rf postfixadmin*&lt;br /&gt;
&lt;br /&gt;
Edit /var/www/domains/host.example.com/www/postfixadmin/config.inc.php and modify at least these lines (replace host.example.com with the actual domain):&lt;br /&gt;
&lt;br /&gt;
 $CONF[&#039;configured&#039;] = true;&lt;br /&gt;
 $CONF[&#039;setup_password&#039;] = &amp;quot;&amp;quot;;  &amp;lt;&amp;lt; Don&#039;t change this yet&lt;br /&gt;
 $CONF[&#039;database_type&#039;] = &#039;pgsql&#039;;&lt;br /&gt;
 $CONF[&#039;database_host&#039;] = &#039;localhost&#039;;&lt;br /&gt;
 $CONF[&#039;database_user&#039;] = &#039;postfix&#039;;&lt;br /&gt;
 $CONF[&#039;database_password&#039;] = &#039;*****&#039;;   &amp;lt;&amp;lt; The password you chose above&lt;br /&gt;
 $CONF[&#039;database_name&#039;] = &#039;postfix&#039;;&lt;br /&gt;
 $CONF[&#039;database_prefix&#039;] = &amp;quot;&amp;quot;;&lt;br /&gt;
 $CONF[&#039;admin_email&#039;] = &#039;you@some.email.com&#039;;  &amp;lt;&amp;lt; Your email address &lt;br /&gt;
 $CONF[&#039;encrypt&#039;] = &#039;md5crypt&#039;;&lt;br /&gt;
 $CONF[&#039;authlib_default_flavor&#039;] = &#039;md5raw&#039;;&lt;br /&gt;
 $CONF[&#039;dovecotpw&#039;] = &amp;quot;/usr/sbin/dovecotpw&amp;quot;;&lt;br /&gt;
 $CONF[&#039;domain_path&#039;] = &#039;YES&#039;;&lt;br /&gt;
 $CONF[&#039;domain_in_mailbox&#039;] = &#039;NO&#039;;&lt;br /&gt;
 $CONF[&#039;aliases&#039;] = &#039;10&#039;;                       &lt;br /&gt;
 $CONF[&#039;mailboxes&#039;] = &#039;10&#039;;&lt;br /&gt;
 $CONF[&#039;maxquota&#039;] = &#039;10&#039;;&lt;br /&gt;
 $CONF[&#039;quota&#039;] = &#039;YES&#039;;&lt;br /&gt;
 $CONF[&#039;quota_multiplier&#039;] = &#039;1024000&#039;;&lt;br /&gt;
 $CONF[&#039;vacation&#039;] = &#039;NO&#039;; &lt;br /&gt;
 $CONF[&#039;vacation_control&#039;] =&#039;NO&#039;;&lt;br /&gt;
 $CONF[&#039;vacation_control_admin&#039;] = &#039;NO&#039;;&lt;br /&gt;
 $CONF[&#039;alias_control&#039;] = &#039;YES&#039;;&lt;br /&gt;
 $CONF[&#039;alias_control_admin&#039;] = &#039;YES&#039;;&lt;br /&gt;
 $CONF[&#039;special_alias_control&#039;] = &#039;YES&#039;;&lt;br /&gt;
 $CONF[&#039;fetchmail&#039;] = &#039;NO&#039;;&lt;br /&gt;
 $CONF[&#039;user_footer_link&#039;] = &amp;quot;http://host.example.com/postfixadmin&amp;quot;;&lt;br /&gt;
 $CONF[&#039;footer_link&#039;] = &#039;http://host.example.com/postfixadmin/main.php&#039;;&lt;br /&gt;
 $CONF[&#039;create_mailbox_subdirs_prefix&#039;]=&amp;quot;&amp;quot;;  &lt;br /&gt;
 $CONF[&#039;used_quotas&#039;] = &#039;YES&#039;;   &lt;br /&gt;
 $CONF[&#039;new_quota_table&#039;] = &#039;YES&#039;;  &lt;br /&gt;
&lt;br /&gt;
You should further edit /var/www/domains/host.example.com/www/postfixadmin/config.inc.php and replace all instances of &amp;quot;change-this-to-your.domain.tld&amp;quot; with your actual mail domain. This can be done with busybox sed (replace example.com with your domain name):&lt;br /&gt;
&lt;br /&gt;
 sed -i -e &#039;s/change-this-to-your.domain.tld/example.com/g&#039; /var/www/domains/host.example.com/www/postfixadmin/config.inc.php&lt;br /&gt;
&lt;br /&gt;
Go to http://host.example.com/postfixadmin/setup.php&lt;br /&gt;
&lt;br /&gt;
Create the password hash, add it to the config.inc.php file&lt;br /&gt;
&lt;br /&gt;
Go back to http://host.example.com/postfixadmin/setup.php&lt;br /&gt;
&lt;br /&gt;
Create superadmin account.&lt;br /&gt;
&lt;br /&gt;
== Install Postfix ==&lt;br /&gt;
&lt;br /&gt;
Create a user for the virtual mail delivery, and get its uid/gid (you&#039;ll need the numeric uid/gid for postfix)&lt;br /&gt;
&lt;br /&gt;
 adduser vmail -H -D -s /bin/false&lt;br /&gt;
 grep vmail /etc/passwd&lt;br /&gt;
&lt;br /&gt;
(In examples below, we use 1006/1006 for the uid/gid)&lt;br /&gt;
&lt;br /&gt;
Create the mail directory, and assign vmail as the owner&lt;br /&gt;
 mkdir -p /var/mail/domains&lt;br /&gt;
 chown -R vmail:vmail /var/mail/domains&lt;br /&gt;
 &lt;br /&gt;
&lt;br /&gt;
Install postfix&lt;br /&gt;
&lt;br /&gt;
 apk add acf-postfix postfix-pgsql&lt;br /&gt;
&lt;br /&gt;
Edit the /etc/postfix/main.cf file. Here&#039;s an example (don&#039;t forget to replace the uid/gid):&lt;br /&gt;
&lt;br /&gt;
 myhostname=host.example.com&lt;br /&gt;
 mydomain=example.com&lt;br /&gt;
 &lt;br /&gt;
 mydestination = localhost.$mydomain, localhost&lt;br /&gt;
 mynetworks_style = subnet&lt;br /&gt;
 mynetworks = 127.0.0.0/8&lt;br /&gt;
 &lt;br /&gt;
 virtual_mailbox_domains = proxy:pgsql:/etc/postfix/sql/pgsql_virtual_domains_maps.cf&lt;br /&gt;
 virtual_alias_maps = proxy:pgsql:/etc/postfix/sql/pgsql_virtual_alias_maps.cf,&lt;br /&gt;
        proxy:pgsql:/etc/postfix/sql/pgsql_virtual_alias_domain_maps.cf,&lt;br /&gt;
        proxy:pgsql:/etc/postfix/sql/pgsql_virtual_alias_domain_catchall_maps.cf&lt;br /&gt;
 &lt;br /&gt;
 virtual_mailbox_maps = proxy:pgsql:/etc/postfix/sql/pgsql_virtual_mailbox_maps.cf,&lt;br /&gt;
        proxy:pgsql:/etc/postfix/sql/pgsql_virtual_alias_domain_mailbox_maps.cf&lt;br /&gt;
 &lt;br /&gt;
 virtual_mailbox_base = /var/mail/domains/&lt;br /&gt;
 virtual_gid_maps = static:1006&lt;br /&gt;
 virtual_uid_maps = static:1006&lt;br /&gt;
 virtual_minimum_uid = 100&lt;br /&gt;
 virtual_transport = virtual&lt;br /&gt;
 &lt;br /&gt;
 &lt;br /&gt;
 # This next command means you must create a virtual&lt;br /&gt;
 # domain for the host itself - ALL mail goes through&lt;br /&gt;
 # The virtual transport&lt;br /&gt;
 &lt;br /&gt;
 mailbox_transport = virtual&lt;br /&gt;
 local_transport = virtual&lt;br /&gt;
 local_transport_maps = $virtual_mailbox_maps&lt;br /&gt;
 &lt;br /&gt;
 smtpd_helo_required = yes&lt;br /&gt;
 disable_vrfy_command = yes&lt;br /&gt;
 message_size_limit = 10240000&lt;br /&gt;
 queue_minfree = 51200000&lt;br /&gt;
 &lt;br /&gt;
 smtpd_sender_restrictions =&lt;br /&gt;
        permit_mynetworks,&lt;br /&gt;
        reject_non_fqdn_sender,&lt;br /&gt;
        reject_unknown_sender_domain&lt;br /&gt;
 &lt;br /&gt;
 smtpd_recipient_restrictions =&lt;br /&gt;
        reject_non_fqdn_recipient,&lt;br /&gt;
        reject_unknown_recipient_domain,&lt;br /&gt;
        permit_mynetworks,&lt;br /&gt;
        permit_sasl_authenticated,&lt;br /&gt;
        reject_unauth_destination,&lt;br /&gt;
        reject_rbl_client dnsbl.sorbs.net,&lt;br /&gt;
        reject_rbl_client zen.spamhaus.org,&lt;br /&gt;
        reject_rbl_client bl.spamcop.net&lt;br /&gt;
 &lt;br /&gt;
 smtpd_data_restrictions = reject_unauth_pipelining&lt;br /&gt;
 &lt;br /&gt;
 # we will use this later - This prevents cleartext authentication&lt;br /&gt;
 # for relaying&lt;br /&gt;
 smtpd_tls_auth_only = yes&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Now we need to create a *bunch* of files so that postfix can get the delivery information out of sql. Here&#039;s a shell script to create the scripts.  Change PGPW to the password for the postfix user of the postfix SQL database.&lt;br /&gt;
&lt;br /&gt;
 cd /etc/postfix&lt;br /&gt;
 mkdir sql&lt;br /&gt;
 PGPW=&amp;quot;ChangeMe&amp;quot;&lt;br /&gt;
 &lt;br /&gt;
 cat - &amp;lt;&amp;lt;EOF &amp;gt;sql/pgsql_virtual_alias_domain_catchall_maps.cf&lt;br /&gt;
 user=postfix&lt;br /&gt;
 password = $PGPW&lt;br /&gt;
 hosts = localhost&lt;br /&gt;
 dbname = postfix&lt;br /&gt;
 query = Select goto From alias,alias_domain where alias_domain.alias_domain = &#039;%d&#039; and alias.address = &#039;@&#039; ||  alias_domain.target_domain and alias.active = true and alias_domain.active= true &lt;br /&gt;
 EOF&lt;br /&gt;
 &lt;br /&gt;
 cat - &amp;lt;&amp;lt;EOF &amp;gt;sql/pgsql_virtual_alias_domain_mailbox_maps.cf&lt;br /&gt;
 user=postfix&lt;br /&gt;
 password = $PGPW&lt;br /&gt;
 hosts = localhost&lt;br /&gt;
 dbname = postfix&lt;br /&gt;
 query = Select maildir from mailbox,alias_domain where alias_domain.alias_domain = &#039;%d&#039; and mailbox.username = &#039;%u&#039; || &#039;@&#039; || alias_domain.target_domain and mailbox.active = true and alias_domain.active&lt;br /&gt;
 EOF&lt;br /&gt;
 &lt;br /&gt;
 cat - &amp;lt;&amp;lt;EOF &amp;gt;sql/pgsql_virtual_alias_domain_maps.cf&lt;br /&gt;
 user=postfix&lt;br /&gt;
 password = $PGPW&lt;br /&gt;
 hosts = localhost&lt;br /&gt;
 dbname = postfix&lt;br /&gt;
 query = select goto from alias,alias_domain where alias_domain.alias_domain=&#039;%d&#039; and alias.address = &#039;%u&#039; || &#039;@&#039; || alias_domain.target_domain and alias.active= true and alias_domain.active= true&lt;br /&gt;
 EOF&lt;br /&gt;
 &lt;br /&gt;
 cat - &amp;lt;&amp;lt;EOF &amp;gt;sql/pgsql_virtual_alias_maps.cf&lt;br /&gt;
 user=postfix&lt;br /&gt;
 password = $PGPW&lt;br /&gt;
 hosts = localhost&lt;br /&gt;
 dbname = postfix&lt;br /&gt;
 query = Select goto From alias Where address=&#039;%s&#039; and active =&#039;1&#039;&lt;br /&gt;
 EOF&lt;br /&gt;
 &lt;br /&gt;
 cat - &amp;lt;&amp;lt;EOF &amp;gt;sql/pgsql_virtual_domains_maps.cf&lt;br /&gt;
 user=postfix&lt;br /&gt;
 password = $PGPW&lt;br /&gt;
 hosts = localhost&lt;br /&gt;
 dbname = postfix&lt;br /&gt;
 query = Select domain from domain where domain=&#039;%s&#039; and active=&#039;1&#039;&lt;br /&gt;
 EOF&lt;br /&gt;
 &lt;br /&gt;
 cat - &amp;lt;&amp;lt;EOF &amp;gt;sql/pgsql_virtual_mailbox_maps.cf&lt;br /&gt;
 user=postfix&lt;br /&gt;
 password = $PGPW&lt;br /&gt;
 hosts = localhost&lt;br /&gt;
 dbname = postfix&lt;br /&gt;
 query = Select maildir from mailbox where username=&#039;%s&#039; and active=true&lt;br /&gt;
 EOF&lt;br /&gt;
 &lt;br /&gt;
 chown -R postfix:postfix sql&lt;br /&gt;
 chmod 640 sql/*&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
At this point you should be able to start up postfix&lt;br /&gt;
 &lt;br /&gt;
 newaliases  # so postfix is happy...&lt;br /&gt;
 /etc/init.d/postfix start&lt;br /&gt;
 rc-update add postfix&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Create a domain in PostfixAdmin and test ===&lt;br /&gt;
&lt;br /&gt;
Go to http://host.example.com/postfixadmin/&lt;br /&gt;
&lt;br /&gt;
Log in using the superadmin account, create a domain for the local box (e.g. example.com), and create a user mailbox (e.g. root).&lt;br /&gt;
&lt;br /&gt;
From the machine, send a test message:&lt;br /&gt;
&lt;br /&gt;
 sendmail -t root@example.com&lt;br /&gt;
 subject: test&lt;br /&gt;
 .&lt;br /&gt;
 ^d&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
In /var/log/mail.log (or /var/log/messages, if you still have busybox syslogd running) you should see the message queued.  The message should be in /var/mail/domains/example.com/root/new&lt;br /&gt;
&lt;br /&gt;
== Install Dovecot ==&lt;br /&gt;
&lt;br /&gt;
Dovecot is the POP3/IMAP server to retrieve mail.&lt;br /&gt;
&lt;br /&gt;
As before, we install dovecot: &lt;br /&gt;
&lt;br /&gt;
 apk add acf-dovecot dovecot-pgsql&lt;br /&gt;
&lt;br /&gt;
edit /etc/dovecot/dovecot.conf&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 # Select only the protocols you wish to support - all are listed in the next line&lt;br /&gt;
 protocols               =       imap imaps pop pop3s&lt;br /&gt;
 log_path                =       /var/log/dovecot.log&lt;br /&gt;
 info_log_path           =       /var/log/dovecot-info.log&lt;br /&gt;
 disable_plaintext_auth  =       no&lt;br /&gt;
&lt;br /&gt;
 # Authenticated IMAP&lt;br /&gt;
 ssl                     =       yes&lt;br /&gt;
 ssl_cert_file           =       /etc/lighttpd/server-bundle.pem&lt;br /&gt;
 ssl_key_file            =       /etc/lighttpd/server-bundle.pem&lt;br /&gt;
 auth_verbose            =       yes&lt;br /&gt;
 auth_debug              =       no&lt;br /&gt;
 mail_location           =       maildir:/var/mail/domains/%d/%n&lt;br /&gt;
 auth default    {&lt;br /&gt;
        mechanisms = plain&lt;br /&gt;
        passdb sql {&lt;br /&gt;
                args = /etc/dovecot/dovecot-sql.conf&lt;br /&gt;
                }&lt;br /&gt;
        userdb static {&lt;br /&gt;
                args =  uid=1006 gid=1006 home=/var/mail/domains/%d/%n&lt;br /&gt;
                }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Be sure to replace the uid and gid with the appropriate values for the vmail user.&lt;br /&gt;
&lt;br /&gt;
We need a certificate for SSL/TLS authentication, so in the example above, we use the lighttpd cert. That way when the cert is renewed/replaced, Dovecot will have access to the new cert as well.  &lt;br /&gt;
&lt;br /&gt;
Create the /etc/dovecot/dovecot-sql.conf file:&lt;br /&gt;
&lt;br /&gt;
 driver = pgsql&lt;br /&gt;
 connect = host=localhost dbname=postfix user=postfix password=********&lt;br /&gt;
 password_query = select username,password from mailbox where local_part = &#039;%n&#039; and domain = &#039;%d&#039;&lt;br /&gt;
 default_pass_scheme =  MD5-CRYPT&lt;br /&gt;
&lt;br /&gt;
Again, change the password above to your postfix user password, and protect the file from prying eyes:&lt;br /&gt;
&lt;br /&gt;
 chown root:root /etc/dovecot/dovecot-sql.conf&lt;br /&gt;
 chmod 600 /etc/dovecot/dovecot-sql.conf&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Start dovecot&lt;br /&gt;
 /etc/init.d/dovecot start&lt;br /&gt;
 rc-update add dovecot&lt;br /&gt;
&lt;br /&gt;
== Testing ==&lt;br /&gt;
&lt;br /&gt;
Make sure your firewall allows in ports 25(SMTP) 110 (POP3), 995 (POP3S), 143(IMAP), 993(IMAPS), or whatever subset you support.  &lt;br /&gt;
 &lt;br /&gt;
At this point, you should be able to:&lt;br /&gt;
 * Create a new domain and add users with PostfixAdmin&lt;br /&gt;
 * Send mail to those users via SMTP to port 25&lt;br /&gt;
 * Retrieve mail using the user&#039;s full email and password (e.g. username: user@example.com  password: ChangeMe)&lt;br /&gt;
&lt;br /&gt;
== Value Add Features ==&lt;br /&gt;
&lt;br /&gt;
If you followed the guide above, you now have a functional mail server with many interconnected parts.  The features below assume that the server is already running as described above.  You should be able to add any or all of these features below to further enhance the mail service.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Virus Scanning ===&lt;br /&gt;
&lt;br /&gt;
This procedure uses clamav and the postfix content_filter mechanism to scan inbound and outbound email for viruses.  Infected emails are dropped.  Clean emails are tagged with a &amp;quot;scanned by clamav&amp;quot; header.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* Install clamav and clamsmtp:&lt;br /&gt;
 apk add acf-clamav clamsmtp&lt;br /&gt;
* Edit the /etc/clamav/clamd.conf file if desired (not necessary in most cases)&lt;br /&gt;
* Edit /etc/clamsmtpd.conf and verify the following lines&lt;br /&gt;
 OutAddress: 10026&lt;br /&gt;
 Listen: 127.0.0.1:10025                                               &lt;br /&gt;
 Header: X-Virus-Scanned: ClamAV using ClamSMTP&lt;br /&gt;
 Action: drop&lt;br /&gt;
 User: clamav                                                      &lt;br /&gt;
* Start the daemons&lt;br /&gt;
 rc-update add clamd&lt;br /&gt;
 rc-update add clamsmtpd&lt;br /&gt;
 /etc/init.d/clamd start&lt;br /&gt;
 /etc/init.d/clamsmtpd start&lt;br /&gt;
* Verify clamsmtp is listening on port 10025:&lt;br /&gt;
 netstat -anp | grep clamsmtp&lt;br /&gt;
* [http://memberwebs.com/stef/software/clamsmtp/postfix.html Following the clamsmtp instructions]&lt;br /&gt;
** edit /etc/postfix/main.cf and add:&lt;br /&gt;
 content_filter = scan:[127.0.0.1]:10025                                                      &lt;br /&gt;
** edit /etc/postfix/master.cf and add&lt;br /&gt;
 # AV scan filter (used by content_filter)&lt;br /&gt;
 scan      unix  -       -       n       -       16      smtp&lt;br /&gt;
         -o smtp_send_xforward_command=yes&lt;br /&gt;
         -o smtp_enforce_tls=no&lt;br /&gt;
 # For injecting mail back into postfix from the filter&lt;br /&gt;
 127.0.0.1:10026 inet  n -       n       -       16      smtpd&lt;br /&gt;
         -o content_filter=&lt;br /&gt;
         -o receive_override_options=no_unknown_recipient_checks,no_header_body_checks&lt;br /&gt;
         -o smtpd_helo_restrictions=&lt;br /&gt;
         -o smtpd_client_restrictions=&lt;br /&gt;
         -o smtpd_sender_restrictions=&lt;br /&gt;
         -o smtpd_recipient_restrictions=permit_mynetworks,reject&lt;br /&gt;
         -o mynetworks_style=host&lt;br /&gt;
         -o smtpd_authorized_xforward_hosts=127.0.0.0/8&lt;br /&gt;
* postfix reload&lt;br /&gt;
* Send and email into a local virtual domain - it should have the &#039;&#039;X-Virus-Scanned: ClamAV using ClamSMTP&#039;&#039; header.&lt;br /&gt;
&lt;br /&gt;
=== Relay for Authenticated Users ===&lt;br /&gt;
&lt;br /&gt;
As configured above, the mail server accepts email from the Internet, but it does not relay email.  If it is a perimeter exchanger for a protected network, then you can add the protected networks to the &#039;&#039;mynetworks&#039;&#039; configuration line in /etc/postfix/main.cf&lt;br /&gt;
&lt;br /&gt;
This configuration change allows &#039;&#039;remote&#039;&#039; users to authenticate against the mail server and relay through it.  The rules for relaying are:&lt;br /&gt;
* Only authenticated users can relay&lt;br /&gt;
* Authentication Credentials must be encrypted with TLS or SSL&lt;br /&gt;
* Allow Submission and SMTPS ports for relaying (many consumer networks block port 25 - SMTP by default)&lt;br /&gt;
The process uses the dovecot authentication mechanism (used with IMAPS) to authenticate users before they are allowed to relay through postfix.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* Edit /etc/dovecot/dovecot.conf and add teh following inside the &#039;&#039;auth default&#039;&#039; stanza:&lt;br /&gt;
 # this is for postfix SASL (authenticated users can relay through us)&lt;br /&gt;
 socket listen {&lt;br /&gt;
                client {&lt;br /&gt;
                        path    = /var/spool/postfix/private/dovecot-auth.sock&lt;br /&gt;
                        mode    = 0660&lt;br /&gt;
                        user    = postfix&lt;br /&gt;
                        group   = postfix&lt;br /&gt;
                        }&lt;br /&gt;
                }&lt;br /&gt;
        }&lt;br /&gt;
* Restart dovecot&lt;br /&gt;
 /etc/init.d/dovecot restart&lt;br /&gt;
* Edit /etc/postfix/main.cf and add:&lt;br /&gt;
 # TLS Stuff -- since we allow SASL with tls *only*, we have to set up TLS first                    &lt;br /&gt;
 &lt;br /&gt;
 smtpd_tls_cert_file = /etc/lighttpd/server-bundle.pem&lt;br /&gt;
 smtpd_tls_key_file = /etc/lighttpd/server-bundle.pem&lt;br /&gt;
 smtpd_tls_CAfile = /etc/lighttpd/ca-crt.pem&lt;br /&gt;
 # If tls_security_level is set to &amp;quot;encrypt&amp;quot;, then SMTP rejects &lt;br /&gt;
 # unencrypted email (e.g. normal mail) which is bad.&lt;br /&gt;
 # By setting it to &amp;quot;may&amp;quot; you get TLS encrypted mail from google, slashdot, and other &lt;br /&gt;
 # interesting places.  Check your logs to see who&lt;br /&gt;
 smtpd_tls_security_level = may&lt;br /&gt;
 # Log info about the negotiated encryption levels&lt;br /&gt;
 smtpd_tls_received_header = yes&lt;br /&gt;
 smtpd_tls_loglevel = 1&lt;br /&gt;
 &lt;br /&gt;
 # SASL - this allows senders to authenticiate themselves&lt;br /&gt;
 # This along with &amp;quot;permit_sasl_authenticated&amp;quot; in smtpd_recipient_restrictions allows relaying&lt;br /&gt;
 smtpd_sasl_type = dovecot&lt;br /&gt;
 smtpd_sasl_path = private/dovecot-auth.sock&lt;br /&gt;
 smtpd_sasl_auth_enable = yes&lt;br /&gt;
 smtpd_sasl_authenticated_header = yes&lt;br /&gt;
 smtpd_tls_auth_only = yes&lt;br /&gt;
* Edit /etc/postfix/master.cf and enable the submission and smtps transports.  They are probably already at the top of your  master.cf file, just commented out:&lt;br /&gt;
 submission inet n       -       n       -       -       smtpd&lt;br /&gt;
   -o smtpd_tls_security_level=encrypt&lt;br /&gt;
   -o smtpd_sasl_auth_enable=yes&lt;br /&gt;
   -o smtpd_client_restrictions=permit_sasl_authenticated,reject&lt;br /&gt;
   -o milter_macro_daemon_name=ORIGINATING&lt;br /&gt;
 smtps     inet  n       -       n       -       -       smtpd&lt;br /&gt;
   -o smtpd_tls_security_level=encrypt&lt;br /&gt;
   -o smtpd_tls_wrappermode=yes&lt;br /&gt;
   -o smtpd_sasl_auth_enable=yes&lt;br /&gt;
   -o smtpd_client_restrictions=permit_sasl_authenticated,reject&lt;br /&gt;
   -o milter_macro_daemon_name=ORIGINATING&lt;br /&gt;
*Verfiy submission and smtps are defined in /etc/services&lt;br /&gt;
 grep &amp;quot;submission\|ssmtp&amp;quot; /etc/services&lt;br /&gt;
 submission	587/tcp				# mail message submission&lt;br /&gt;
 submission	587/udp&lt;br /&gt;
 smtps		465/tcp		ssmtp		# smtp protocol over TLS/SSL&lt;br /&gt;
 smtps		465/udp		ssmtp&lt;br /&gt;
* Restart postfix&lt;br /&gt;
 postfix reload&lt;br /&gt;
&lt;br /&gt;
At this point, you should be able to set up a mail client to relay through the server with TLS (port 587) or SSL (port 465)  Note that &amp;quot;plain&amp;quot; authentication is used because the underlying link is encrypted.  For example, in Thunderbird leave &amp;quot;secure authentication&amp;quot; unchecked, and choose STARTTLS (or TLS) for the connection security.&lt;br /&gt;
&lt;br /&gt;
=== Mailbox Quotas ===&lt;br /&gt;
&lt;br /&gt;
In the default configuration, PostfixAdmin knows about quotas, but they are not enforced.   Documentation on the web mentions the [http://vda.sourceforge.net vda patch to postfix] to enforce quotas.  The only bad thing... its a &#039;&#039;patch&#039;&#039;.   Postfix and Dovecot are both conservative systems, so if the patch isn&#039;t in the upstream source, we&#039;ll assume there&#039;s a good reason.   There is a way of using quotas without patches - and it involves using dovecot&#039;s [http://wiki.dovecot.org/LDA deliver] lda for local delivery.&lt;br /&gt;
&lt;br /&gt;
Note: As of Jan 2010, the documention is confusing, with multiple versions of dovecot, PostfixAdmin, and Mysql referenced.  These instructions apply to:&lt;br /&gt;
* Postgresql 8.4.2 &lt;br /&gt;
* PostfixAdmin 2.3 &lt;br /&gt;
* Dovecot 1.2.11&lt;br /&gt;
* Postfix 2.6.5&lt;br /&gt;
&lt;br /&gt;
Presumably later versions will work the same, but if not, please update the documentation and versions above.&lt;br /&gt;
&lt;br /&gt;
* Update /etc/dovecot/dovecot.conf (old lines shown commented out):&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
# old postfix &lt;br /&gt;
#       userdb static {&lt;br /&gt;
#               args =  uid=1006 gid=1006 home=/var/mail/domains/%d/%n&lt;br /&gt;
#               }&lt;br /&gt;
&lt;br /&gt;
# new quota support:&lt;br /&gt;
        userdb prefetch {&lt;br /&gt;
                }&lt;br /&gt;
&lt;br /&gt;
        userdb sql {&lt;br /&gt;
                args = /etc/dovecot/dovecot-sql.conf&lt;br /&gt;
                }&lt;br /&gt;
&lt;br /&gt;
        socket listen {&lt;br /&gt;
                client {&lt;br /&gt;
                        path    = /var/spool/postfix/private/dovecot-auth.sock&lt;br /&gt;
                        mode    = 0660&lt;br /&gt;
                        user    = postfix&lt;br /&gt;
                        group   = postfix&lt;br /&gt;
                        }&lt;br /&gt;
                # These lines below are for the deliver lda&lt;br /&gt;
                master {&lt;br /&gt;
                        path =  /var/run/dovecot/auth-master&lt;br /&gt;
                        mode    = 0660&lt;br /&gt;
                        user    = vmail&lt;br /&gt;
                        group   = vmail&lt;br /&gt;
                        }&lt;br /&gt;
                }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
protocol imap {                                                               &lt;br /&gt;
         mail_plugins = quota imap_quota                                       &lt;br /&gt;
         }                                                                     &lt;br /&gt;
                                                                              &lt;br /&gt;
protocol pop3 {                                                               &lt;br /&gt;
         mail_plugins = quota                                                  &lt;br /&gt;
         }                                                                     &lt;br /&gt;
                                                                              &lt;br /&gt;
dict {                                                                        &lt;br /&gt;
        quotadict = pgsql:/etc/dovecot/dovecot-dict-quota.conf                &lt;br /&gt;
        }                                                                     &lt;br /&gt;
                                                                              &lt;br /&gt;
plugin {                                                                      &lt;br /&gt;
         quota = dict:user::proxy::quotadict                                   &lt;br /&gt;
         }                                                     &lt;br /&gt;
                                                              &lt;br /&gt;
protocol lda {                                                &lt;br /&gt;
   postmaster_address = postmaster@host.example.com&lt;br /&gt;
   mail_plugins = quota                                        &lt;br /&gt;
   auth_socket_path =  /var/run/dovecot/auth-master&lt;br /&gt;
   sendmail_path = /usr/sbin/sendmail&lt;br /&gt;
}                                                                            &lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
 &lt;br /&gt;
You should already have a &amp;lt;tt&amp;gt;socket-&amp;gt; listen-&amp;gt; client&amp;lt;/tt&amp;gt; section, but it is listed above to show where it goes in relationship to the &amp;lt;tt&amp;gt;socket -&amp;gt; listen -&amp;gt; master&amp;lt;/tt&amp;gt; section&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* edit &amp;lt;tt&amp;gt;/etc/dovecot/dovecot-sql.conf&amp;lt;/tt&amp;gt; and replace the user and password queries with the following (you may not have a user_query yet - add it):&lt;br /&gt;
&lt;br /&gt;
 password_query = select username as user, password, 1006 as userdb_uid, 1006 as userdb_gid, &#039;*:bytes=&#039; || quota as userdb_quota_rule from mailbox  where local_part = &#039;%n&#039; and domain = &#039;%d&#039;&lt;br /&gt;
 user_query = select &#039;/var/mail/domains/&#039; as home, 1006 as uid, 1006 as gid, &#039;*:bytes=&#039; || quota  as quota_rule from mailbox where local_part = &#039;%n&#039; and domain =&#039;%d&#039;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* create &amp;lt;tt&amp;gt;/etc/dovecot/dovecot-dict-quota.conf&amp;lt;/tt&amp;gt;&lt;br /&gt;
 connect = host=localhost dbname=postfix user=postfix password=********&lt;br /&gt;
 &lt;br /&gt;
 map {&lt;br /&gt;
         pattern = priv/quota/storage&lt;br /&gt;
         table = quota2&lt;br /&gt;
         username_field =username&lt;br /&gt;
         value_field = bytes&lt;br /&gt;
 }&lt;br /&gt;
 &lt;br /&gt;
 map {&lt;br /&gt;
        pattern= priv/quota/messages&lt;br /&gt;
        table = quota2&lt;br /&gt;
        username_field = username&lt;br /&gt;
        value_field = messages&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
Side note: [http://wiki.dovecot.org/Quota/Dict The Dovecot Quota Documentation] mentions the need for a trigger with pgsql.  This was created in the PostfixAdmin install, which is why you instantiated the pgsql language when creating the database.  If not, you will need to create the trigger, to reference the quota2 table, not the quota table mentioned in the dovecot docs.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* create a new transport for the dovecot lda.   Add the following to  /etc/postfix/master.cf:&lt;br /&gt;
 # The dovecot deliver lda&lt;br /&gt;
 dovecot   unix  -       n       n       -       -       pipe&lt;br /&gt;
   flags=DRhu user=vmail:vmail argv=/usr/libexec/dovecot/deliver -f ${sender} -d ${user}@${nexthop}&lt;br /&gt;
&lt;br /&gt;
* Edit the /etc/postfix/main.cf.  Replace &lt;br /&gt;
 virtual_transport = virtual &lt;br /&gt;
with&lt;br /&gt;
 virtual_transport = dovecot&lt;br /&gt;
 dovecot_destination_recipient_limit = 1&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;TODO&#039;&#039;&#039;  This will cause over-quota emails to bounce.   Which could be a source of backscatter.   We need a way of checking quota limits after RBL checking but before the message is accepted in the queue.&lt;br /&gt;
&lt;br /&gt;
=== WebMail (RoundCube) ===&lt;br /&gt;
&lt;br /&gt;
[http://roundcube.net/ RoundCube] is an &amp;quot;ajax /Web2.0&amp;quot; web-mail client.  These instructions are for the Alpine Linux 1.10 repository &lt;br /&gt;
&lt;br /&gt;
* Add the package and related php modules:&lt;br /&gt;
 apk add roundcubemail php-xml php-openssl php-mcrypt php-gd php-iconv&lt;br /&gt;
&lt;br /&gt;
* link the roundcube application back into the docroot&lt;br /&gt;
 ln -s /usr/share/webapps/roundcube /var/www/domains/host.example.com/www/roundcube&lt;br /&gt;
&lt;br /&gt;
* follow the instructions in /usr/share/webapps/roundcube/INSTALL:&lt;br /&gt;
 cd /usr/share/webapps/roundcube&lt;br /&gt;
 chown -R lighttpd:lighttpd temp logs&lt;br /&gt;
 &lt;br /&gt;
 su postgres&lt;br /&gt;
 createuser roundcube&lt;br /&gt;
   Shall the new role be a superuser? (y/n) n&lt;br /&gt;
   Shall the new role be allowed to create databases? (y/n) n&lt;br /&gt;
   Shall the new role be allowed to create more new roles? (y/n) y&lt;br /&gt;
 createdb -O roundcube -E UNICODE -T template0 roundcubemail&lt;br /&gt;
 psql roundcubemail&lt;br /&gt;
   roundcubemail=# ALTER USER roundcube WITH PASSWORD &#039;the_new_password&#039;;&lt;br /&gt;
   roundcubemail=# \c - roundcube&lt;br /&gt;
   roundcubemail=&amp;gt; \i /usr/share/webapps/roundcube/SQL/postgres.initial.sql&lt;br /&gt;
   roundcubemail=&amp;gt; \q&lt;br /&gt;
 exit&lt;br /&gt;
&lt;br /&gt;
* edit /etc/php/php.ini and set date.timezone to your local timezone, or to UTC&lt;br /&gt;
&lt;br /&gt;
* restart lighttpd to verify the new php libraries are used&lt;br /&gt;
 /etc/init.d/lighttpd restart&lt;br /&gt;
&lt;br /&gt;
* Point your browser to http://host.example.com/roundcube/installer&lt;br /&gt;
* Start installation&lt;br /&gt;
&lt;br /&gt;
For the specific configuration parameters in the install step:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!Property&lt;br /&gt;
!Setting&lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;enable_spellcheck&#039;&#039; ||   disabled &lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;identities_level&#039;&#039; ||  one identity with possibility to edit all params but not email address &lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;log driver&#039;&#039; || syslog &lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;sylog_id&#039;&#039; || roundcube &lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;syslog_facility&#039;&#039; || mailsubsystem &lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;db_dnsw&#039;&#039; || pgsql properties, as described above &lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;imap_host&#039;&#039; || 127.0.0.1 &lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;auto_create_user&#039;&#039; || enabled &lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;smtp_server&#039;&#039; ||  127.0.0.1&lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;smtp_port&#039;&#039; ||  25&lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;smtp_user/smtp_pass&#039;&#039; ||  enable &#039;&#039;Use Current IMAP username and password for SMTP authentication&#039;&#039;&lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;smtp_log&#039;&#039; ||  enable (optional, but gives additional log record)&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
The other items can be left at default settings, or adjusted if desired.&lt;br /&gt;
&lt;br /&gt;
* Follow the instructions in step 3 of the install to copy the files to the server&lt;br /&gt;
* You should now be able to get to roundcube at http://host.example.com/roundcube&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
After its working, the INSTALL file recommends removing the install directory.   If you want to keep the installer around later, you can simply change the ownership and permissions.  So do &#039;&#039;&#039;one&#039;&#039;&#039; of the following:&lt;br /&gt;
 cd /usr/share/webapps/roundcube&lt;br /&gt;
 rm -rf LICENSE UPGRADING INSTALL README CHANGELOG  SQL installer&lt;br /&gt;
or&lt;br /&gt;
 cd /usr/share/webapps/roundcube&lt;br /&gt;
 chown -R root:root LICENSE UPGRADING INSTALL README CHANGELOG  SQL installer&lt;br /&gt;
 chmod -R 600 LICENSE UPGRADING INSTALL README CHANGELOG SQL &lt;br /&gt;
 chmod 700 SQL installer&lt;br /&gt;
&lt;br /&gt;
==== Enable Plug-ins ====&lt;br /&gt;
&lt;br /&gt;
RoundCube has various useful plug-ins, which could be found in &#039;&#039;/usr/share/webapps/roundcube/plugins&#039;&#039; directory. For example you may want to enable &#039;&#039;password&#039;&#039; plug-in to let users change their passwords directly from RoundCube using an extra Password Tab added to User Settings.&lt;br /&gt;
&lt;br /&gt;
* Grant limited permissions for &#039;&#039;roundcube&#039;&#039; database role &lt;br /&gt;
 psql -U postgres postfix&lt;br /&gt;
   postfix=# GRANT UPDATE (password) ON mailbox TO roundcube;&lt;br /&gt;
   postfix=# GRANT SELECT (username) ON mailbox TO roundcube;&lt;br /&gt;
   postfix=# \q&lt;br /&gt;
&lt;br /&gt;
* Setup &#039;&#039;password&#039;&#039; plug-in parameters in &#039;&#039;/usr/share/webapps/roundcube/plugins/password/config.inc.php&#039;&#039;&lt;br /&gt;
 mv /usr/share/webapps/roundcube/plugins/password/config.inc.php.dist /usr/share/webapps/roundcube/plugins/password/config.inc.php&lt;br /&gt;
 vi /usr/share/webapps/roundcube/plugins/password/config.inc.php&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
$rcmail_config[&#039;password_db_dsn&#039;] = &#039;pgsql://roundcube:&amp;lt;roundcube_password&amp;gt;@localhost/postfix&#039;;&lt;br /&gt;
...&lt;br /&gt;
$rcmail_config[&#039;password_query&#039;] = &amp;quot;UPDATE mailbox set password = %c where username = %u&amp;quot;;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* Enable &#039;&#039;password&#039;&#039; plug-in&lt;br /&gt;
 vi /usr/share/webapps/roundcube/config/main.inc.php&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
...&lt;br /&gt;
$rcmail_config[&#039;plugins&#039;] = array(&#039;password&#039;);&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== OpenLDAP based Address Book ===&lt;br /&gt;
&lt;br /&gt;
This OpenLDAP configuration uses the SQL backend, which represents information stored in PostgreSQL as an LDAP subtree for Address Book functionality for email lookups, user authentication or even &lt;br /&gt;
replication account information between sites. This procedure uses some metainformation to translate LDAP queries to SQL queries, leaving relational schema untouched, which allows SQL and LDAP &lt;br /&gt;
applications to inter-operate without replication, and exchange data as needed. The SQL backend uses UnixODBC to connect to PostgresSQL. &lt;br /&gt;
&lt;br /&gt;
* Install OpenLDAP and ODBC&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
apk add openldap libldap openldap-back-sql php-ldap unixodbc psqlodbc ca-certificates&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Note&#039;&#039;&#039;: Perhaps some packages should be installed from &amp;quot;edge&amp;quot; repository&lt;br /&gt;
&lt;br /&gt;
* Update &amp;quot;postfix&amp;quot; database (it will add &#039;id&#039; columns to mailbox and domain tables, also will create tables and views to represent LDAP metainformation)&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Note&#039;&#039;&#039;: These instructions are for example domain example.com. So make sure you replaced all entries of &#039;example&#039; and &#039;com&#039; according to your domain name parts.&lt;br /&gt;
&lt;br /&gt;
Put the following into a new file called &#039;&#039;&#039;script&#039;&#039;&#039;:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
ALTER TABLE domain ADD COLUMN id SERIAL; &lt;br /&gt;
ALTER TABLE mailbox ADD COLUMN id SERIAL; &lt;br /&gt;
&lt;br /&gt;
CREATE TABLE ldap_entry_objclasses (&lt;br /&gt;
    entry_id integer NOT NULL,&lt;br /&gt;
    oc_name character varying(64)&lt;br /&gt;
);&lt;br /&gt;
&lt;br /&gt;
CREATE TABLE ldap_oc_mappings (&lt;br /&gt;
    name character varying(64) NOT NULL,&lt;br /&gt;
    keytbl character varying(64) NOT NULL,&lt;br /&gt;
    keycol character varying(64) NOT NULL,&lt;br /&gt;
    create_proc character varying(255),&lt;br /&gt;
    delete_proc character varying(255),&lt;br /&gt;
    expect_return integer NOT NULL,&lt;br /&gt;
);&lt;br /&gt;
&lt;br /&gt;
ALTER TABLE ldap_oc_mappings ADD COLUMN id SERIAL;&lt;br /&gt;
ALTER TABLE ldap_oc_mappings ADD PRIMARY KEY (id);&lt;br /&gt;
&lt;br /&gt;
CREATE TABLE ldap_attr_mappings_test (&lt;br /&gt;
    oc_map_id integer NOT NULL REFERENCES ldap_oc_mappings(id),&lt;br /&gt;
    name character varying(255) NOT NULL,&lt;br /&gt;
    sel_expr character varying(255) NOT NULL,&lt;br /&gt;
    sel_expr_u character varying(255),&lt;br /&gt;
    from_tbls character varying(255) NOT NULL,&lt;br /&gt;
    join_where character varying(255),&lt;br /&gt;
    add_proc character varying(255),&lt;br /&gt;
    delete_proc character varying(255),&lt;br /&gt;
    param_order integer NOT NULL,&lt;br /&gt;
    expect_return integer NOT NULL,&lt;br /&gt;
);&lt;br /&gt;
&lt;br /&gt;
ALTER TABLE ldap_attr_mappings_test ADD COLUMN id SERIAL;&lt;br /&gt;
ALTER TABLE ldap_attr_mappings_test ADD PRIMARY KEY (id);&lt;br /&gt;
&lt;br /&gt;
CREATE VIEW ldap_dcs AS&lt;br /&gt;
    (SELECT (domain.id + 100000) AS id, &lt;br /&gt;
            (((&#039;dc=&#039;::text || split_part((domain.domain)::text, &#039;.&#039;::text, 1)) || &#039;,dc=&#039;::text) || &lt;br /&gt;
            CASE WHEN (split_part((domain.domain)::text, &#039;.&#039;::text, 2) = &#039;com&#039;::text) THEN split_part((domain.domain)::text, &#039;.&#039;::text, 2) &lt;br /&gt;
                 ELSE ((split_part((domain.domain)::text, &#039;.&#039;::text, 2) || &#039;,dc=&#039;::text) || split_part((domain.domain)::text, &#039;.&#039;::text, 3)) &lt;br /&gt;
            END) AS dn, &lt;br /&gt;
            1 AS oc_map_id, &lt;br /&gt;
            100000 AS parent, &lt;br /&gt;
            0 AS keyval, &lt;br /&gt;
            domain.domain&lt;br /&gt;
     FROM domain &lt;br /&gt;
     WHERE domain.domain &amp;lt;&amp;gt; &#039;ALL&#039; &lt;br /&gt;
      UNION &lt;br /&gt;
     SELECT 100000 AS id, &lt;br /&gt;
           &#039;dc=com&#039; AS dn, &lt;br /&gt;
           1 AS oc_map_id, &lt;br /&gt;
           0 AS parent, &lt;br /&gt;
           0 AS keyval, &lt;br /&gt;
           &#039;com&#039; AS domain);&lt;br /&gt;
&lt;br /&gt;
CREATE VIEW ldap_entries AS&lt;br /&gt;
    SELECT mailbox.id, &lt;br /&gt;
    (((((&#039;cn=&#039;::text || initcap(replace(split_part((mailbox.username)::text, &#039;@&#039;::text, 1), &#039;.&#039;::text, &#039; &#039;::text))) || &#039;,dc=&#039;::text) || &lt;br /&gt;
          split_part(split_part((mailbox.username)::text, &#039;@&#039;::text, 2), &#039;.&#039;::text, 1)) || &#039;,dc=&#039;::text) || &lt;br /&gt;
             CASE WHEN (split_part(split_part((mailbox.username)::text, &#039;@&#039;::text, 2), &#039;.&#039;::text, 2) = &#039;com&#039;::text) &lt;br /&gt;
                  THEN split_part(split_part((mailbox.username)::text, &#039;@&#039;::text, 2), &#039;.&#039;::text, 2) &lt;br /&gt;
                  ELSE ((split_part(split_part((mailbox.username)::text, &#039;@&#039;::text, 2), &#039;.&#039;::text, 2) || &#039;,dc=&#039;::text) || &lt;br /&gt;
                         split_part(split_part((mailbox.username)::text, &#039;@&#039;::text, 2), &#039;.&#039;::text, 3)) &lt;br /&gt;
             END) AS dn, &lt;br /&gt;
          1 AS oc_map_id, &lt;br /&gt;
          (SELECT ldap_dcs.id &lt;br /&gt;
           FROM ldap_dcs &lt;br /&gt;
           WHERE ((ldap_dcs.domain)::text = (mailbox.domain)::text)) AS parent, &lt;br /&gt;
           mailbox.id AS keyval &lt;br /&gt;
           FROM mailbox &lt;br /&gt;
           UNION &lt;br /&gt;
           SELECT ldap_dcs.id,  &lt;br /&gt;
                  ldap_dcs.dn, &lt;br /&gt;
                  ldap_dcs.oc_map_id, &lt;br /&gt;
                  ldap_dcs.parent, &lt;br /&gt;
                  ldap_dcs.keyval &lt;br /&gt;
           FROM ldap_dcs;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Finally, execute the commands in the file with:&lt;br /&gt;
 cat script | psql -U postfix postfix&lt;br /&gt;
&lt;br /&gt;
* Fill out LDAP tables according to following example (make sure to separate values with TABs):&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
cat - &amp;lt;&amp;lt;EOF | psql -U postgres postfix&lt;br /&gt;
COPY ldap_attr_mappings (id, oc_map_id, name, sel_expr, sel_expr_u, from_tbls, join_where, add_proc, delete_proc, param_order, expect_return) FROM stdin;&lt;br /&gt;
1	1	displayName	mailbox.name	\N	mailbox	\N	\N	\N	3	0&lt;br /&gt;
2	1	mail	mailbox.username	\N	mailbox	\N	\N	\N	3	0&lt;br /&gt;
3	1	cn	mailbox.name	\N	mailbox	\N	\N	\N	3	0&lt;br /&gt;
4	1	userPassword	&#039;{CRYPT}&#039;||mailbox.password	\N	mailbox	\N	\N	\N	3	0&lt;br /&gt;
\.&lt;br /&gt;
&lt;br /&gt;
COPY ldap_oc_mappings (id, name, keytbl, keycol, create_proc, delete_proc, expect_return) FROM stdin;&lt;br /&gt;
1	exampleBox	mailbox	id	\N	\N	1&lt;br /&gt;
\.&lt;br /&gt;
EOF&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* Check that &amp;quot;ldap_dcs&amp;quot; view presens something like this:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
echo &#039;select * from ldap_dcs&#039; | psql -U postgres postfix&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
   id   |             dn              | oc_map_id | parent | keyval |       domain       &lt;br /&gt;
--------+-----------------------------+-----------+--------+--------+--------------------&lt;br /&gt;
 100000 | dc=com                      |         1 |      0 |      0 | com&lt;br /&gt;
 100001 | dc=example,dc=com           |         1 | 100000 |      0 | example.com&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* Check that &amp;quot;ldap_entries&amp;quot; view presens something like this:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
echo &#039;select * from ldap_entries&#039; | psql -U postgres postfix&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
   id   |                          dn                           | oc_map_id | parent | keyval &lt;br /&gt;
--------+-------------------------------------------------------+-----------+--------+--------&lt;br /&gt;
    1   | cn=address1,dc=example,dc=com                         |         1 | 100001 |    1&lt;br /&gt;
...&lt;br /&gt;
   123  | cn=address123,dc=example,dc=com                       |         1 | 100001 |    1&lt;br /&gt;
 100000 | dc=com                                                |         1 |      0 |    0&lt;br /&gt;
 100001 | dc=example,dc=com                                     |         1 | 100000 |    0&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* Configure ODBC parameters&lt;br /&gt;
&lt;br /&gt;
Edit /etc/odbc.ini:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
[PostgreSQL]&lt;br /&gt;
Description             = Connection to Postgres&lt;br /&gt;
Driver                  = PostgreSQL&lt;br /&gt;
Trace                   = Yes&lt;br /&gt;
TraceFile               = sql.log&lt;br /&gt;
Database                = postfix&lt;br /&gt;
Servername              = 127.0.0.1&lt;br /&gt;
UserName                =&lt;br /&gt;
Password                =&lt;br /&gt;
Port                    = 5432&lt;br /&gt;
Protocol                = 6.4&lt;br /&gt;
ReadOnly                = No&lt;br /&gt;
RowVersining            = No&lt;br /&gt;
ShowSystemTables        = No&lt;br /&gt;
ShowOidColumn           = No&lt;br /&gt;
FakeOidIndex            = No&lt;br /&gt;
ConnSettings            =&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Edit /etc/odbcinst.ini:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
[PostgreSQL]&lt;br /&gt;
Description     = PostgreSQL driver for Linux&lt;br /&gt;
Driver          = /usr/lib/psqlodbcw.so&lt;br /&gt;
Setup           = /usr/lib/libodbcpsqlS.so&lt;br /&gt;
FileUsage       = 1&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* Test ODBC connection&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
echo &amp;quot;select * from domain;&amp;quot; | isql PostgreSQL postgres&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* Provide permission to certificate for LDAP server&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
chown ldap /etc/lighttpd/server-bundle.pem&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* Edit LDAP schema&lt;br /&gt;
&lt;br /&gt;
Edit /etc/openldap/schema/example.com.schema:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
attributetype ( 0.9.2342.19200300.100.1.3&lt;br /&gt;
	NAME ( &#039;mail&#039; &#039;rfc822Mailbox&#039; )&lt;br /&gt;
	DESC &#039;RFC1274: RFC822 Mailbox&#039;&lt;br /&gt;
        EQUALITY caseIgnoreIA5Match&lt;br /&gt;
        SUBSTR caseIgnoreIA5SubstringsMatch&lt;br /&gt;
        SYNTAX 1.3.6.1.4.1.1466.115.121.1.26{256} )&lt;br /&gt;
&lt;br /&gt;
attributetype ( 2.16.840.1.113730.3.1.241&lt;br /&gt;
	NAME &#039;displayName&#039;&lt;br /&gt;
	DESC &#039;RFC2798: preferred name to be used when displaying entries&#039;&lt;br /&gt;
	EQUALITY caseIgnoreMatch&lt;br /&gt;
	SUBSTR caseIgnoreSubstringsMatch&lt;br /&gt;
	SYNTAX 1.3.6.1.4.1.1466.115.121.1.15&lt;br /&gt;
	SINGLE-VALUE )&lt;br /&gt;
&lt;br /&gt;
objectclass   ( 2.16.840.1.113730.3.2.2&lt;br /&gt;
        NAME &#039;exampleBox&#039;&lt;br /&gt;
	DESC &#039;example.com mailbox&#039;&lt;br /&gt;
	MUST ( displayName $ mail $ userPassword )&lt;br /&gt;
	)&lt;br /&gt;
&lt;br /&gt;
# RFC 1274 + RFC 2247&lt;br /&gt;
attributetype ( 0.9.2342.19200300.100.1.25&lt;br /&gt;
        NAME ( &#039;dc&#039; &#039;domainComponent&#039; )&lt;br /&gt;
        DESC &#039;RFC1274/2247: domain component&#039;&lt;br /&gt;
        EQUALITY caseIgnoreIA5Match&lt;br /&gt;
        SUBSTR caseIgnoreIA5SubstringsMatch&lt;br /&gt;
        SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 SINGLE-VALUE )&lt;br /&gt;
&lt;br /&gt;
attributetype ( 2.5.4.46 NAME &#039;dnQualifier&#039;&lt;br /&gt;
        DESC &#039;RFC2256: DN qualifier&#039;&lt;br /&gt;
        EQUALITY caseIgnoreMatch&lt;br /&gt;
        ORDERING caseIgnoreOrderingMatch&lt;br /&gt;
        SUBSTR caseIgnoreSubstringsMatch&lt;br /&gt;
        SYNTAX 1.3.6.1.4.1.1466.115.121.1.44 )&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* Configure LDAP server&lt;br /&gt;
&lt;br /&gt;
Edit /etc/openldap/slapd.conf:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
include         /etc/openldap/schema/example.com.schema&lt;br /&gt;
pidfile         /var/run/openldap/slapd.pid&lt;br /&gt;
argsfile        /var/run/openldap/slapd.args&lt;br /&gt;
&lt;br /&gt;
TLSCipherSuite HIGH&lt;br /&gt;
TLSCACertificateFile /etc/lighttpd/ca-crt.pem&lt;br /&gt;
TLSCertificateFile /etc/lighttpd/server-bundle.pem&lt;br /&gt;
TLSCertificateKeyFile /etc/lighttpd/server-bundle.pem&lt;br /&gt;
TLSVerifyClient never &lt;br /&gt;
&lt;br /&gt;
# This is needed for proper representation of MD5-CRYPT format stored in database&lt;br /&gt;
#  see more details in http://strugglers.net/~andy/blog/2010/01/23/openldap-and-md5crypt/&lt;br /&gt;
password-hash  {CRYPT}&lt;br /&gt;
password-crypt-salt-format &amp;quot;$1$%.8s&amp;quot;&lt;br /&gt;
&lt;br /&gt;
loglevel        stats&lt;br /&gt;
moduleload	/usr/lib/openldap/back_sql.so&lt;br /&gt;
sizelimit 3000&lt;br /&gt;
&lt;br /&gt;
database        sql&lt;br /&gt;
&lt;br /&gt;
dbname		PostgreSQL&lt;br /&gt;
dbuser		postfix&lt;br /&gt;
dbpasswd	*****&lt;br /&gt;
&lt;br /&gt;
suffix          &amp;quot;dc=example,dc=com&amp;quot;&lt;br /&gt;
rootdn          &amp;quot;cn=admin,dc=example,dc=com&amp;quot;&lt;br /&gt;
rootpw		{MD5}&amp;lt;Hashed password for root dn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
upper_func      &amp;quot;upper&amp;quot;&lt;br /&gt;
strcast_func    &amp;quot;text&amp;quot;&lt;br /&gt;
concat_pattern  &amp;quot;?||?&amp;quot;&lt;br /&gt;
has_ldapinfo_dn_ru      no&lt;br /&gt;
lastmod         off&lt;br /&gt;
&lt;br /&gt;
access to attrs=userPassword by * auth&lt;br /&gt;
&lt;br /&gt;
access to * by peername.ip=127.0.0.1 read&lt;br /&gt;
            ### by peername.ip=&amp;lt;IP&amp;gt;%&amp;lt;netmask&amp;gt; read&lt;br /&gt;
            ### by peername.ip=&amp;lt;IP&amp;gt; read&lt;br /&gt;
	    by users read&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* Set permissions for slapd.conf&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
chown ldap:ldap /etc/openldap/slapd.conf&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* Configure startup parameters to make sure that LDAP server start AFTER PostgreSQL and listens on localhost with clear text and public IP with SSL&lt;br /&gt;
&lt;br /&gt;
Edit /etc/conf.d/slapd:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
echo rc_need=&amp;quot;postgresql&amp;quot; &lt;br /&gt;
OPTS=&amp;quot;-h &#039;ldaps:// ldap://127.0.0.1&#039;&amp;quot;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* Start LDAP server&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
rc-update add slapd default&lt;br /&gt;
/etc/init.d/slapd start&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* Configure LDAP client utilities&lt;br /&gt;
&lt;br /&gt;
Edit /etc/openldap/ldap.conf&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
BASE	dc=example,dc=com&lt;br /&gt;
URI	ldaps://host.example.com&lt;br /&gt;
&lt;br /&gt;
TLS_CACERT /etc/lighttpd/ca-crt.pem&lt;br /&gt;
TLS_CERT /etc/lighttpd/server-bundle.pem&lt;br /&gt;
TLS_KEY /etc/lighttpd/server-bundle.pem&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* Test LDAP server&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
ldapsearch -z 3&lt;br /&gt;
ldapsearch -z 3 -x -W -D cn=admin,dc=example,dc=com&lt;br /&gt;
ldapsearch -z 3 -x -W -D cn=address1,dc=example,dc=com&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* Configure RoundCube webmail for email lookups&lt;br /&gt;
&lt;br /&gt;
Edit /usr/share/webapps/roundcube/config/main.inc.php:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
$rcmail_config[&#039;ldap_debug&#039;] = false;&lt;br /&gt;
...&lt;br /&gt;
$rcmail_config[&#039;address_book_type&#039;] = &#039;ldap&#039;;&lt;br /&gt;
&lt;br /&gt;
$rcmail_config[&#039;ldap_public&#039;][&#039;example.com&#039;] = array(&lt;br /&gt;
  &#039;name&#039;          =&amp;gt; &#039;example.com&#039;,&lt;br /&gt;
  &#039;hosts&#039;         =&amp;gt; array(&#039;127.0.0.1&#039;),&lt;br /&gt;
  &#039;port&#039;          =&amp;gt; 389,&lt;br /&gt;
  &#039;use_tls&#039;         =&amp;gt; false,&lt;br /&gt;
  &#039;user_specific&#039; =&amp;gt; false,&lt;br /&gt;
  &#039;base_dn&#039;       =&amp;gt; &#039;dc=example,dc=com&#039;,&lt;br /&gt;
  &#039;bind_dn&#039;       =&amp;gt; &#039;&#039;,&lt;br /&gt;
  &#039;bind_pass&#039;     =&amp;gt; &#039;&#039;,&lt;br /&gt;
  &#039;writable&#039;      =&amp;gt; false,&lt;br /&gt;
  &#039;LDAP_Object_Classes&#039; =&amp;gt; array(&amp;quot;top&amp;quot;, &amp;quot;exampleBox&amp;quot;),&lt;br /&gt;
  &#039;required_fields&#039;     =&amp;gt; array(&amp;quot;cn&amp;quot;, &amp;quot;sn&amp;quot;, &amp;quot;mail&amp;quot;),&lt;br /&gt;
  &#039;LDAP_rdn&#039;      =&amp;gt; &#039;mail&#039;,&lt;br /&gt;
  &#039;ldap_version&#039;  =&amp;gt; 3,&lt;br /&gt;
  &#039;search_fields&#039; =&amp;gt; array(&#039;mail&#039;, &#039;cn&#039;, &#039;sn&#039;, &#039;givenName&#039;),&lt;br /&gt;
  &#039;name_field&#039;    =&amp;gt; &#039;cn&#039;,&lt;br /&gt;
  &#039;email_field&#039;   =&amp;gt; &#039;mail&#039;,&lt;br /&gt;
  &#039;surname_field&#039; =&amp;gt; &#039;sn&#039;,&lt;br /&gt;
  &#039;firstname_field&#039; =&amp;gt; &#039;gn&#039;,&lt;br /&gt;
  &#039;sort&#039;          =&amp;gt; &#039;cn&#039;,&lt;br /&gt;
  &#039;scope&#039;         =&amp;gt; &#039;sub&#039;,&lt;br /&gt;
  &#039;filter&#039;        =&amp;gt; &#039;(objectClass=*)&#039;, // Construct here any filter you need&lt;br /&gt;
  &#039;fuzzy_search&#039;  =&amp;gt; true);&lt;br /&gt;
&lt;br /&gt;
$rcmail_config[&#039;autocomplete_addressbooks&#039;] = array(&#039;example.com&#039;);&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== log rotation ==&lt;br /&gt;
&lt;br /&gt;
Ensure the busybox cron service is started and is configured to auto-start:&lt;br /&gt;
&lt;br /&gt;
 /etc/init.d/cron start&lt;br /&gt;
 rc-update add cron default&lt;br /&gt;
&lt;br /&gt;
Add log rotate:&lt;br /&gt;
&lt;br /&gt;
 apk add logrotate&lt;br /&gt;
&lt;br /&gt;
Edit &#039;&#039;/etc/logrotate.conf&#039;&#039; as desired, but the defaults should be sufficient for most people.&lt;br /&gt;
&lt;br /&gt;
== Optional: Configure Web Server Virtual Domains ==&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Note:&#039;&#039;&#039; These steps can be done &#039;&#039;in addition to&#039;&#039; the default lighttpd configuration above, which allows you to access the ACF, PostfixAdmin and Roundcube interfaces as subfolders of one web service.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Note:&#039;&#039;&#039; If you provide SSL access for multiple domain site you may need to follow http://redmine.lighttpd.net/projects/lighttpd/wiki/Docs:SSL#SSL-on-multiple-domains in order to provide multi-domain certificates. If you would like to redirect hosts to their secure equivalents use the following instructions http://redmine.lighttpd.net/projects/lighttpd/wiki/HowToRedirectHttpToHttps.&lt;br /&gt;
&lt;br /&gt;
This server hosts three separate web applications, and these can be handled as three &#039;&#039;different&#039;&#039; virtual domains on the same web server. They will be distinguished by their DNS names, so you can choose domains for the three separate services (or at least the ones you want to publish):&lt;br /&gt;
&lt;br /&gt;
* ACF - Alpine Configuration Framework for managing the server&lt;br /&gt;
* PostfixAdmin - for managing the postfix installation&lt;br /&gt;
* RoundCube - for accessing individual mailboxes&lt;br /&gt;
&lt;br /&gt;
Choose three different domains (from here on known as ACF_DOMAIN, POSTFIXADMIN_DOMAIN, and ROUNDCUBE_DOMAIN) and configure DNS for all three to point to the IP address of your host. These should be DNS &#039;&#039;&#039;A&#039;&#039;&#039; records.&lt;br /&gt;
&lt;br /&gt;
Then, configure lighttpd to handle the three separate domains by editing /etc/lighttpd/lighttpd.conf:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 $HTTP[&amp;quot;host&amp;quot;] == &amp;quot;ACF_DOMAIN&amp;quot; {&lt;br /&gt;
	simple-vhost.server-root   = &amp;quot;/var/www/domains/&amp;quot;&lt;br /&gt;
	simple-vhost.default-host  = &amp;quot;/ACF_DOMAIN/&amp;quot;&lt;br /&gt;
	simple-vhost.document-root = &amp;quot;www/&amp;quot;&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
 $HTTP[&amp;quot;host&amp;quot;] == &amp;quot;POSTFIXADMIN_DOMAIN&amp;quot; {&lt;br /&gt;
	simple-vhost.server-root   = &amp;quot;/var/www/domains/&amp;quot;&lt;br /&gt;
	simple-vhost.default-host  = &amp;quot;/POSTFIXADMIN_DOMAIN/&amp;quot;&lt;br /&gt;
	simple-vhost.document-root = &amp;quot;www/&amp;quot;&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
 $HTTP[&amp;quot;host&amp;quot;] == &amp;quot;ROUNDCUBE_DOMAIN&amp;quot; {&lt;br /&gt;
	simple-vhost.server-root   = &amp;quot;/var/www/domains/&amp;quot;&lt;br /&gt;
	simple-vhost.default-host  = &amp;quot;/ROUNDCUBE_DOMAIN/&amp;quot;&lt;br /&gt;
	simple-vhost.document-root = &amp;quot;www/&amp;quot;&lt;br /&gt;
 }&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
And, then link the appropriate www directories.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  mkdir -p /var/www/domains/ACF_DOMAIN&lt;br /&gt;
  ln -s /usr/share/acf/www /var/www/domains/ACF_DOMAIN/www&lt;br /&gt;
&lt;br /&gt;
  mkdir -p /var/www/domains/POSTFIXADMIN_DOMAIN&lt;br /&gt;
  ln -s /var/www/domains/host.example.com/www/postfixadmin /var/www/domains/POSTFIXADMIN_DOMAIN/www&lt;br /&gt;
&lt;br /&gt;
  mkdir -p /var/www/domains/ROUNDCUBE_DOMAIN&lt;br /&gt;
  ln -s /usr/share/webapps/roundcube /var/www/domains/ROUNDCUBE_DOMAIN/www&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;/div&gt;</summary>
		<author><name>Djhughes</name></author>
	</entry>
	<entry>
		<id>https://wiki.alpinelinux.org/w/index.php?title=ISP_Mail_Server_HowTo&amp;diff=3508</id>
		<title>ISP Mail Server HowTo</title>
		<link rel="alternate" type="text/html" href="https://wiki.alpinelinux.org/w/index.php?title=ISP_Mail_Server_HowTo&amp;diff=3508"/>
		<updated>2010-03-30T09:15:08Z</updated>

		<summary type="html">&lt;p&gt;Djhughes: some fixes for database script&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== A Full Service Mail Server ==&lt;br /&gt;
&lt;br /&gt;
The goal of this document is to describe how to set up postfix, dovecot, clamav, dspam, roundecube, and postfixadmin for a full-featured &amp;quot;ISP&amp;quot; level mail server.&lt;br /&gt;
&lt;br /&gt;
The server must provide:&lt;br /&gt;
&lt;br /&gt;
* multiple virtual domains&lt;br /&gt;
* admins for each domain (to add/remove virtual accounts)&lt;br /&gt;
* Quota support per domain / account&lt;br /&gt;
* downloading email via IMAP / IMAPS / POP3 / POP3S&lt;br /&gt;
* relaying email for authenticated users with TLS or SSL (Submission / SMTPS protocol)&lt;br /&gt;
* Standard filters (virus/spam/rbl/etc)&lt;br /&gt;
* Web mail client&lt;br /&gt;
* Value Add services&lt;br /&gt;
&lt;br /&gt;
== Set up Lighttpd + PHP ==&lt;br /&gt;
&lt;br /&gt;
PostfixAdmin needs php pgpsql and imap modules, so we do it in this step.&lt;br /&gt;
&lt;br /&gt;
  apk add lighttpd php php-pgsql php-imap&lt;br /&gt;
&lt;br /&gt;
Stop and remove mini_httpd, and move ACF to lighttpd;  We are setting this up to be a multi-domain virtual web server (replace host.example.com with the actual domain):&lt;br /&gt;
&lt;br /&gt;
  mkdir -p /var/www/domains/host.example.com/www&lt;br /&gt;
  ln -s /usr/share/acf/www /var/www/domains/host.example.com/www/acf&lt;br /&gt;
&lt;br /&gt;
Edit /var/www/domains/host.example.com/index.html to put a simple redirection page:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;lt;!DOCTYPE HTML PUBLIC &amp;quot;-//W3C//DTD HTML 4.01//EN&amp;quot; &amp;quot;http://www.w3.org/TR/html4/strict.dtd&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;html lang=&amp;quot;en&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;head&amp;gt;&lt;br /&gt;
&amp;lt;meta http-equiv=&amp;quot;Content-Type&amp;quot; content=&amp;quot;text/html; charset=ISO-8859-1&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;title&amp;gt;host.example.com Redirector&amp;lt;/title&amp;gt;&lt;br /&gt;
&amp;lt;/head&amp;gt;&lt;br /&gt;
&amp;lt;body&amp;gt;&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;&amp;lt;a href=&amp;quot;/acf&amp;quot;&amp;gt;ACF&amp;lt;/a&amp;gt;&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;&amp;lt;a href=&amp;quot;/postfixadmin&amp;quot;&amp;gt;PostfixAdmin&amp;lt;/a&amp;gt;&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;&amp;lt;a href=&amp;quot;/roundcube&amp;quot;&amp;gt;Roundcube&amp;lt;/a&amp;gt;&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
&amp;lt;/body&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Edit /etc/lighttpd/mod_cgi.conf to serve haserl files by adding a &amp;quot;&amp;quot; =&amp;gt; &amp;quot;&amp;quot; cgi handler and to treat /acf/cgi-bin as a CGI directory (remove the &#039;^&#039;)&lt;br /&gt;
&lt;br /&gt;
 $HTTP[&amp;quot;url&amp;quot;] =~ &amp;quot;/cgi-bin/&amp;quot; {&lt;br /&gt;
     # disable directory listings&lt;br /&gt;
     dir-listing.activate = &amp;quot;disable&amp;quot;&lt;br /&gt;
     # only allow cgi&#039;s in this directory&lt;br /&gt;
     cgi.assign = (&lt;br /&gt;
 		&amp;quot;.pl&amp;quot;	=&amp;gt;	&amp;quot;/usr/bin/perl&amp;quot;,&lt;br /&gt;
 		&amp;quot;.cgi&amp;quot;	=&amp;gt;	&amp;quot;/usr/bin/perl&amp;quot;,&lt;br /&gt;
 		&amp;quot;&amp;quot; =&amp;gt; &amp;quot;&amp;quot;&lt;br /&gt;
 	)&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
Add these lines to /etc/lighttpd/lighttpd.conf to point to the new document root, and set it up to listen on port 443 (replace &#039;&#039;host.example.com&#039;&#039; with the actual domain and &#039;&#039;ip_address_of_server&#039;&#039; with the actual IP address):&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
simple-vhost.server-root   = &amp;quot;/var/www/domains/&amp;quot;&lt;br /&gt;
simple-vhost.default-host  = &amp;quot;/host.example.com/&amp;quot;&lt;br /&gt;
simple-vhost.document-root = &amp;quot;www/&amp;quot;&lt;br /&gt;
&lt;br /&gt;
$SERVER[&amp;quot;socket&amp;quot;] == &amp;quot;ip_address_of_server:443&amp;quot; {&lt;br /&gt;
ssl.engine    = &amp;quot;enable&amp;quot;&lt;br /&gt;
ssl.pemfile   = &amp;quot;/etc/lighttpd/server-bundle.pem&amp;quot;&lt;br /&gt;
ssl.ca-file   = &amp;quot;/etc/lighttpd/ca-crt.pem&amp;quot;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Ensure that the simple_vhosts module is loaded, as well as the cgi config scripts by uncommenting the following lines in /etc/lighttpd/lighttpd.conf&lt;br /&gt;
&lt;br /&gt;
 server.modules = (&lt;br /&gt;
     #  other modules may be listed&lt;br /&gt;
     &amp;quot;mod_simple_vhost&amp;quot;, &lt;br /&gt;
     #  other modules may be listed&lt;br /&gt;
  .&lt;br /&gt;
  .&lt;br /&gt;
  .&lt;br /&gt;
     include &amp;quot;mod_cgi.conf&amp;quot;&lt;br /&gt;
 &lt;br /&gt;
     include &amp;quot;mod_fastcgi.conf&amp;quot;&lt;br /&gt;
 &lt;br /&gt;
&lt;br /&gt;
Get a web certificate, and install it.  If you want to use a self-signed cert, you can use [[Generating SSL certs with ACF]] or [[Generating SSL certs with ACF 1.9]].  If you create a certificate with ACF, you can create the &amp;quot;server-bundle.pem&amp;quot; and the &amp;quot;ca-crt.pem&amp;quot; file with these commands:&lt;br /&gt;
&lt;br /&gt;
  openssl pkcs12 -nokeys -cacerts -in certificate.pfx  -out /etc/lighttpd/ca-crt.pem&lt;br /&gt;
  openssl pkcs12 -nodes -in certifcate.pfx -out /etc/lighttpd/server-bundle.pem&lt;br /&gt;
  chown root:root /etc/lighttpd/server-bundle.pem&lt;br /&gt;
  chmod 400 /etc/lighttpd/server-bundle.pem&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Note:&#039;&#039;&#039; The server certificate &#039;&#039;and&#039;&#039; key are in the server-bundle.pem file, so it is critical that the file be read-only by user &amp;quot;root&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
 Editme: We should probably only serve ACF to restricted hosts&lt;br /&gt;
&lt;br /&gt;
Stop and remove mini_httpd; start lighttpd, test&lt;br /&gt;
&lt;br /&gt;
  /etc/init.d/mini_httpd stop&lt;br /&gt;
  rc-update del mini_httpd&lt;br /&gt;
  apk del mini_httpd&lt;br /&gt;
  rc-update add lighttpd&lt;br /&gt;
  /etc/init.d/lighttpd start&lt;br /&gt;
&lt;br /&gt;
At this point you should be able to see ACF being served with lighttpd (Note: this will work well with alpine 1.10. With earlier versions there will be problems.)  https://host.example.com/acf/&lt;br /&gt;
&lt;br /&gt;
== Install Postgresql ==&lt;br /&gt;
&lt;br /&gt;
Add and configure postgresql&lt;br /&gt;
&lt;br /&gt;
  apk add acf-postgresql postgresql-client&lt;br /&gt;
  /etc/init.d/postgresql setup&lt;br /&gt;
  /etc/init.d/postgresql start&lt;br /&gt;
  rc-update add postgresql&lt;br /&gt;
&lt;br /&gt;
At this point any user can connect to the sql server with &amp;quot;trust&amp;quot; mechanism.  If you want to enforce password authentication (you probably do) edit /var/lib/postgresql/8.4/data/pg_hba.conf&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
  Editme: What should we recommend?&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Create the postfix database:&lt;br /&gt;
&lt;br /&gt;
  psql -U postgres&lt;br /&gt;
   create user postfix with password &#039;******&#039;;&lt;br /&gt;
   create database postfix owner postfix;&lt;br /&gt;
   \c postfix&lt;br /&gt;
   create language plpgsql;&lt;br /&gt;
   \q&lt;br /&gt;
&lt;br /&gt;
(Of course, use your selected password where ******* is shown above.)&lt;br /&gt;
&lt;br /&gt;
== Install PostfixAdmin ==&lt;br /&gt;
&lt;br /&gt;
We are going to install the postfix admin web front-end before we install the mail server.  This just creates an interface to populate the SQL tables that postfix and dovecot will use.&lt;br /&gt;
&lt;br /&gt;
Download PostfixAdmin from Sourceforge.  When these instructions were written, 2.3 was the current release, so (replace host.example.com with the actual domain):&lt;br /&gt;
 wget http://downloads.sourceforge.net/project/postfixadmin/postfixadmin/postfixadmin_2.3.tar.gz&lt;br /&gt;
 tar zxvf postfixadmin_2.3.tar.gz&lt;br /&gt;
 mkdir -p /var/www/domains/host.example.com/www/postfixadmin&lt;br /&gt;
 mv postfixadmin-2.3/* /var/www/domains/host.example.com/www/postfixadmin&lt;br /&gt;
 rm -rf postfixadmin*&lt;br /&gt;
&lt;br /&gt;
Edit /var/www/domains/host.example.com/www/postfixadmin/config.inc.php and modify at least these lines (replace host.example.com with the actual domain):&lt;br /&gt;
&lt;br /&gt;
 $CONF[&#039;configured&#039;] = true;&lt;br /&gt;
 $CONF[&#039;setup_password&#039;] = &amp;quot;&amp;quot;;  &amp;lt;&amp;lt; Don&#039;t change this yet&lt;br /&gt;
 $CONF[&#039;database_type&#039;] = &#039;pgsql&#039;;&lt;br /&gt;
 $CONF[&#039;database_host&#039;] = &#039;localhost&#039;;&lt;br /&gt;
 $CONF[&#039;database_user&#039;] = &#039;postfix&#039;;&lt;br /&gt;
 $CONF[&#039;database_password&#039;] = &#039;*****&#039;;   &amp;lt;&amp;lt; The password you chose above&lt;br /&gt;
 $CONF[&#039;database_name&#039;] = &#039;postfix&#039;;&lt;br /&gt;
 $CONF[&#039;database_prefix&#039;] = &amp;quot;&amp;quot;;&lt;br /&gt;
 $CONF[&#039;admin_email&#039;] = &#039;you@some.email.com&#039;;  &amp;lt;&amp;lt; Your email address &lt;br /&gt;
 $CONF[&#039;encrypt&#039;] = &#039;md5crypt&#039;;&lt;br /&gt;
 $CONF[&#039;authlib_default_flavor&#039;] = &#039;md5raw&#039;;&lt;br /&gt;
 $CONF[&#039;dovecotpw&#039;] = &amp;quot;/usr/sbin/dovecotpw&amp;quot;;&lt;br /&gt;
 $CONF[&#039;domain_path&#039;] = &#039;YES&#039;;&lt;br /&gt;
 $CONF[&#039;domain_in_mailbox&#039;] = &#039;NO&#039;;&lt;br /&gt;
 $CONF[&#039;aliases&#039;] = &#039;10&#039;;                       &lt;br /&gt;
 $CONF[&#039;mailboxes&#039;] = &#039;10&#039;;&lt;br /&gt;
 $CONF[&#039;maxquota&#039;] = &#039;10&#039;;&lt;br /&gt;
 $CONF[&#039;quota&#039;] = &#039;YES&#039;;&lt;br /&gt;
 $CONF[&#039;quota_multiplier&#039;] = &#039;1024000&#039;;&lt;br /&gt;
 $CONF[&#039;vacation&#039;] = &#039;NO&#039;; &lt;br /&gt;
 $CONF[&#039;vacation_control&#039;] =&#039;NO&#039;;&lt;br /&gt;
 $CONF[&#039;vacation_control_admin&#039;] = &#039;NO&#039;;&lt;br /&gt;
 $CONF[&#039;alias_control&#039;] = &#039;YES&#039;;&lt;br /&gt;
 $CONF[&#039;alias_control_admin&#039;] = &#039;YES&#039;;&lt;br /&gt;
 $CONF[&#039;special_alias_control&#039;] = &#039;YES&#039;;&lt;br /&gt;
 $CONF[&#039;fetchmail&#039;] = &#039;NO&#039;;&lt;br /&gt;
 $CONF[&#039;user_footer_link&#039;] = &amp;quot;http://host.example.com/postfixadmin&amp;quot;;&lt;br /&gt;
 $CONF[&#039;footer_link&#039;] = &#039;http://host.example.com/postfixadmin/main.php&#039;;&lt;br /&gt;
 $CONF[&#039;create_mailbox_subdirs_prefix&#039;]=&amp;quot;&amp;quot;;  &lt;br /&gt;
 $CONF[&#039;used_quotas&#039;] = &#039;YES&#039;;   &lt;br /&gt;
 $CONF[&#039;new_quota_table&#039;] = &#039;YES&#039;;  &lt;br /&gt;
&lt;br /&gt;
You should further edit /var/www/domains/host.example.com/www/postfixadmin/config.inc.php and replace all instances of &amp;quot;change-this-to-your.domain.tld&amp;quot; with your actual mail domain. This can be done with busybox sed (replace example.com with your domain name):&lt;br /&gt;
&lt;br /&gt;
 sed -i -e &#039;s/change-this-to-your.domain.tld/example.com/g&#039; /var/www/domains/host.example.com/www/postfixadmin/config.inc.php&lt;br /&gt;
&lt;br /&gt;
Go to http://host.example.com/postfixadmin/setup.php&lt;br /&gt;
&lt;br /&gt;
Create the password hash, add it to the config.inc.php file&lt;br /&gt;
&lt;br /&gt;
Go back to http://host.example.com/postfixadmin/setup.php&lt;br /&gt;
&lt;br /&gt;
Create superadmin account.&lt;br /&gt;
&lt;br /&gt;
== Install Postfix ==&lt;br /&gt;
&lt;br /&gt;
Create a user for the virtual mail delivery, and get its uid/gid (you&#039;ll need the numeric uid/gid for postfix)&lt;br /&gt;
&lt;br /&gt;
 adduser vmail -H -D -s /bin/false&lt;br /&gt;
 grep vmail /etc/passwd&lt;br /&gt;
&lt;br /&gt;
(In examples below, we use 1006/1006 for the uid/gid)&lt;br /&gt;
&lt;br /&gt;
Create the mail directory, and assign vmail as the owner&lt;br /&gt;
 mkdir -p /var/mail/domains&lt;br /&gt;
 chown -R vmail:vmail /var/mail/domains&lt;br /&gt;
 &lt;br /&gt;
&lt;br /&gt;
Install postfix&lt;br /&gt;
&lt;br /&gt;
 apk add acf-postfix postfix-pgsql&lt;br /&gt;
&lt;br /&gt;
Edit the /etc/postfix/main.cf file. Here&#039;s an example (don&#039;t forget to replace the uid/gid):&lt;br /&gt;
&lt;br /&gt;
 myhostname=host.example.com&lt;br /&gt;
 mydomain=example.com&lt;br /&gt;
 &lt;br /&gt;
 mydestination = localhost.$mydomain, localhost&lt;br /&gt;
 mynetworks_style = subnet&lt;br /&gt;
 mynetworks = 127.0.0.0/8&lt;br /&gt;
 &lt;br /&gt;
 virtual_mailbox_domains = proxy:pgsql:/etc/postfix/sql/pgsql_virtual_domains_maps.cf&lt;br /&gt;
 virtual_alias_maps = proxy:pgsql:/etc/postfix/sql/pgsql_virtual_alias_maps.cf,&lt;br /&gt;
        proxy:pgsql:/etc/postfix/sql/pgsql_virtual_alias_domain_maps.cf,&lt;br /&gt;
        proxy:pgsql:/etc/postfix/sql/pgsql_virtual_alias_domain_catchall_maps.cf&lt;br /&gt;
 &lt;br /&gt;
 virtual_mailbox_maps = proxy:pgsql:/etc/postfix/sql/pgsql_virtual_mailbox_maps.cf,&lt;br /&gt;
        proxy:pgsql:/etc/postfix/sql/pgsql_virtual_alias_domain_mailbox_maps.cf&lt;br /&gt;
 &lt;br /&gt;
 virtual_mailbox_base = /var/mail/domains/&lt;br /&gt;
 virtual_gid_maps = static:1006&lt;br /&gt;
 virtual_uid_maps = static:1006&lt;br /&gt;
 virtual_minimum_uid = 100&lt;br /&gt;
 virtual_transport = virtual&lt;br /&gt;
 &lt;br /&gt;
 &lt;br /&gt;
 # This next command means you must create a virtual&lt;br /&gt;
 # domain for the host itself - ALL mail goes through&lt;br /&gt;
 # The virtual transport&lt;br /&gt;
 &lt;br /&gt;
 mailbox_transport = virtual&lt;br /&gt;
 local_transport = virtual&lt;br /&gt;
 local_transport_maps = $virtual_mailbox_maps&lt;br /&gt;
 &lt;br /&gt;
 smtpd_helo_required = yes&lt;br /&gt;
 disable_vrfy_command = yes&lt;br /&gt;
 message_size_limit = 10240000&lt;br /&gt;
 queue_minfree = 51200000&lt;br /&gt;
 &lt;br /&gt;
 smtpd_sender_restrictions =&lt;br /&gt;
        permit_mynetworks,&lt;br /&gt;
        reject_non_fqdn_sender,&lt;br /&gt;
        reject_unknown_sender_domain&lt;br /&gt;
 &lt;br /&gt;
 smtpd_recipient_restrictions =&lt;br /&gt;
        reject_non_fqdn_recipient,&lt;br /&gt;
        reject_unknown_recipient_domain,&lt;br /&gt;
        permit_mynetworks,&lt;br /&gt;
        permit_sasl_authenticated,&lt;br /&gt;
        reject_unauth_destination,&lt;br /&gt;
        reject_rbl_client dnsbl.sorbs.net,&lt;br /&gt;
        reject_rbl_client zen.spamhaus.org,&lt;br /&gt;
        reject_rbl_client bl.spamcop.net&lt;br /&gt;
 &lt;br /&gt;
 smtpd_data_restrictions = reject_unauth_pipelining&lt;br /&gt;
 &lt;br /&gt;
 # we will use this later - This prevents cleartext authentication&lt;br /&gt;
 # for relaying&lt;br /&gt;
 smtpd_tls_auth_only = yes&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Now we need to create a *bunch* of files so that postfix can get the delivery information out of sql. Here&#039;s a shell script to create the scripts.  Change PGPW to the password for the postfix user of the postfix SQL database.&lt;br /&gt;
&lt;br /&gt;
 cd /etc/postfix&lt;br /&gt;
 mkdir sql&lt;br /&gt;
 PGPW=&amp;quot;ChangeMe&amp;quot;&lt;br /&gt;
 &lt;br /&gt;
 cat - &amp;lt;&amp;lt;EOF &amp;gt;sql/pgsql_virtual_alias_domain_catchall_maps.cf&lt;br /&gt;
 user=postfix&lt;br /&gt;
 password = $PGPW&lt;br /&gt;
 hosts = localhost&lt;br /&gt;
 dbname = postfix&lt;br /&gt;
 query = Select goto From alias,alias_domain where alias_domain.alias_domain = &#039;%d&#039; and alias.address = &#039;@&#039; ||  alias_domain.target_domain and alias.active = true and alias_domain.active= true &lt;br /&gt;
 EOF&lt;br /&gt;
 &lt;br /&gt;
 cat - &amp;lt;&amp;lt;EOF &amp;gt;sql/pgsql_virtual_alias_domain_mailbox_maps.cf&lt;br /&gt;
 user=postfix&lt;br /&gt;
 password = $PGPW&lt;br /&gt;
 hosts = localhost&lt;br /&gt;
 dbname = postfix&lt;br /&gt;
 query = Select maildir from mailbox,alias_domain where alias_domain.alias_domain = &#039;%d&#039; and mailbox.username = &#039;%u&#039; || &#039;@&#039; || alias_domain.target_domain and mailbox.active = true and alias_domain.active&lt;br /&gt;
 EOF&lt;br /&gt;
 &lt;br /&gt;
 cat - &amp;lt;&amp;lt;EOF &amp;gt;sql/pgsql_virtual_alias_domain_maps.cf&lt;br /&gt;
 user=postfix&lt;br /&gt;
 password = $PGPW&lt;br /&gt;
 hosts = localhost&lt;br /&gt;
 dbname = postfix&lt;br /&gt;
 query = select goto from alias,alias_domain where alias_domain.alias_domain=&#039;%d&#039; and alias.address = &#039;%u&#039; || &#039;@&#039; || alias_domain.target_domain and alias.active= true and alias_domain.active= true&lt;br /&gt;
 EOF&lt;br /&gt;
 &lt;br /&gt;
 cat - &amp;lt;&amp;lt;EOF &amp;gt;sql/pgsql_virtual_alias_maps.cf&lt;br /&gt;
 user=postfix&lt;br /&gt;
 password = $PGPW&lt;br /&gt;
 hosts = localhost&lt;br /&gt;
 dbname = postfix&lt;br /&gt;
 query = Select goto From alias Where address=&#039;%s&#039; and active =&#039;1&#039;&lt;br /&gt;
 EOF&lt;br /&gt;
 &lt;br /&gt;
 cat - &amp;lt;&amp;lt;EOF &amp;gt;sql/pgsql_virtual_domains_maps.cf&lt;br /&gt;
 user=postfix&lt;br /&gt;
 password = $PGPW&lt;br /&gt;
 hosts = localhost&lt;br /&gt;
 dbname = postfix&lt;br /&gt;
 query = Select domain from domain where domain=&#039;%s&#039; and active=&#039;1&#039;&lt;br /&gt;
 EOF&lt;br /&gt;
 &lt;br /&gt;
 cat - &amp;lt;&amp;lt;EOF &amp;gt;sql/pgsql_virtual_mailbox_maps.cf&lt;br /&gt;
 user=postfix&lt;br /&gt;
 password = $PGPW&lt;br /&gt;
 hosts = localhost&lt;br /&gt;
 dbname = postfix&lt;br /&gt;
 query = Select maildir from mailbox where username=&#039;%s&#039; and active=true&lt;br /&gt;
 EOF&lt;br /&gt;
 &lt;br /&gt;
 chown -R postfix:postfix sql&lt;br /&gt;
 chmod 640 sql/*&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
At this point you should be able to start up postfix&lt;br /&gt;
 &lt;br /&gt;
 newaliases  # so postfix is happy...&lt;br /&gt;
 /etc/init.d/postfix start&lt;br /&gt;
 rc-update add postfix&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Create a domain in PostfixAdmin and test ===&lt;br /&gt;
&lt;br /&gt;
Go to http://host.example.com/postfixadmin/&lt;br /&gt;
&lt;br /&gt;
Log in using the superadmin account, create a domain for the local box (e.g. example.com), and create a user mailbox (e.g. root).&lt;br /&gt;
&lt;br /&gt;
From the machine, send a test message:&lt;br /&gt;
&lt;br /&gt;
 sendmail -t root@example.com&lt;br /&gt;
 subject: test&lt;br /&gt;
 .&lt;br /&gt;
 ^d&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
In /var/log/mail.log (or /var/log/messages, if you still have busybox syslogd running) you should see the message queued.  The message should be in /var/mail/domains/example.com/root/new&lt;br /&gt;
&lt;br /&gt;
== Install Dovecot ==&lt;br /&gt;
&lt;br /&gt;
Dovecot is the POP3/IMAP server to retrieve mail.&lt;br /&gt;
&lt;br /&gt;
As before, we install dovecot: &lt;br /&gt;
&lt;br /&gt;
 apk add acf-dovecot dovecot-pgsql&lt;br /&gt;
&lt;br /&gt;
edit /etc/dovecot/dovecot.conf&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 # Select only the protocols you wish to support - all are listed in the next line&lt;br /&gt;
 protocols               =       imap imaps pop pop3s&lt;br /&gt;
 log_path                =       /var/log/dovecot.log&lt;br /&gt;
 info_log_path           =       /var/log/dovecot-info.log&lt;br /&gt;
 disable_plaintext_auth  =       no&lt;br /&gt;
&lt;br /&gt;
 # Authenticated IMAP&lt;br /&gt;
 ssl                     =       yes&lt;br /&gt;
 ssl_cert_file           =       /etc/lighttpd/server-bundle.pem&lt;br /&gt;
 ssl_key_file            =       /etc/lighttpd/server-bundle.pem&lt;br /&gt;
 auth_verbose            =       yes&lt;br /&gt;
 auth_debug              =       no&lt;br /&gt;
 mail_location           =       maildir:/var/mail/domains/%d/%n&lt;br /&gt;
 auth default    {&lt;br /&gt;
        mechanisms = plain&lt;br /&gt;
        passdb sql {&lt;br /&gt;
                args = /etc/dovecot/dovecot-sql.conf&lt;br /&gt;
                }&lt;br /&gt;
        userdb static {&lt;br /&gt;
                args =  uid=1006 gid=1006 home=/var/mail/domains/%d/%n&lt;br /&gt;
                }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Be sure to replace the uid and gid with the appropriate values for the vmail user.&lt;br /&gt;
&lt;br /&gt;
We need a certificate for SSL/TLS authentication, so in the example above, we use the lighttpd cert. That way when the cert is renewed/replaced, Dovecot will have access to the new cert as well.  &lt;br /&gt;
&lt;br /&gt;
Create the /etc/dovecot/dovecot-sql.conf file:&lt;br /&gt;
&lt;br /&gt;
 driver = pgsql&lt;br /&gt;
 connect = host=localhost dbname=postfix user=postfix password=********&lt;br /&gt;
 password_query = select username,password from mailbox where local_part = &#039;%n&#039; and domain = &#039;%d&#039;&lt;br /&gt;
 default_pass_scheme =  MD5-CRYPT&lt;br /&gt;
&lt;br /&gt;
Again, change the password above to your postfix user password, and protect the file from prying eyes:&lt;br /&gt;
&lt;br /&gt;
 chown root:root /etc/dovecot/dovecot-sql.conf&lt;br /&gt;
 chmod 600 /etc/dovecot/dovecot-sql.conf&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Start dovecot&lt;br /&gt;
 /etc/init.d/dovecot start&lt;br /&gt;
 rc-update add dovecot&lt;br /&gt;
&lt;br /&gt;
== Testing ==&lt;br /&gt;
&lt;br /&gt;
Make sure your firewall allows in ports 25(SMTP) 110 (POP3), 995 (POP3S), 143(IMAP), 993(IMAPS), or whatever subset you support.  &lt;br /&gt;
 &lt;br /&gt;
At this point, you should be able to:&lt;br /&gt;
 * Create a new domain and add users with PostfixAdmin&lt;br /&gt;
 * Send mail to those users via SMTP to port 25&lt;br /&gt;
 * Retrieve mail using the user&#039;s full email and password (e.g. username: user@example.com  password: ChangeMe)&lt;br /&gt;
&lt;br /&gt;
== Value Add Features ==&lt;br /&gt;
&lt;br /&gt;
If you followed the guide above, you now have a functional mail server with many interconnected parts.  The features below assume that the server is already running as described above.  You should be able to add any or all of these features below to further enhance the mail service.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Virus Scanning ===&lt;br /&gt;
&lt;br /&gt;
This procedure uses clamav and the postfix content_filter mechanism to scan inbound and outbound email for viruses.  Infected emails are dropped.  Clean emails are tagged with a &amp;quot;scanned by clamav&amp;quot; header.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* Install clamav and clamsmtp:&lt;br /&gt;
 apk add acf-clamav clamsmtp&lt;br /&gt;
* Edit the /etc/clamav/clamd.conf file if desired (not necessary in most cases)&lt;br /&gt;
* Edit /etc/clamsmtpd.conf and verify the following lines&lt;br /&gt;
 OutAddress: 10026&lt;br /&gt;
 Listen: 127.0.0.1:10025                                               &lt;br /&gt;
 Header: X-Virus-Scanned: ClamAV using ClamSMTP&lt;br /&gt;
 Action: drop&lt;br /&gt;
 User: clamav                                                      &lt;br /&gt;
* Start the daemons&lt;br /&gt;
 rc-update add clamd&lt;br /&gt;
 rc-update add clamsmtpd&lt;br /&gt;
 /etc/init.d/clamd start&lt;br /&gt;
 /etc/init.d/clamsmtpd start&lt;br /&gt;
* Verify clamsmtp is listening on port 10025:&lt;br /&gt;
 netstat -anp | grep clamsmtp&lt;br /&gt;
* [http://memberwebs.com/stef/software/clamsmtp/postfix.html Following the clamsmtp instructions]&lt;br /&gt;
** edit /etc/postfix/main.cf and add:&lt;br /&gt;
 content_filter = scan:[127.0.0.1]:10025                                                      &lt;br /&gt;
** edit /etc/postfix/master.cf and add&lt;br /&gt;
 # AV scan filter (used by content_filter)&lt;br /&gt;
 scan      unix  -       -       n       -       16      smtp&lt;br /&gt;
         -o smtp_send_xforward_command=yes&lt;br /&gt;
         -o smtp_enforce_tls=no&lt;br /&gt;
 # For injecting mail back into postfix from the filter&lt;br /&gt;
 127.0.0.1:10026 inet  n -       n       -       16      smtpd&lt;br /&gt;
         -o content_filter=&lt;br /&gt;
         -o receive_override_options=no_unknown_recipient_checks,no_header_body_checks&lt;br /&gt;
         -o smtpd_helo_restrictions=&lt;br /&gt;
         -o smtpd_client_restrictions=&lt;br /&gt;
         -o smtpd_sender_restrictions=&lt;br /&gt;
         -o smtpd_recipient_restrictions=permit_mynetworks,reject&lt;br /&gt;
         -o mynetworks_style=host&lt;br /&gt;
         -o smtpd_authorized_xforward_hosts=127.0.0.0/8&lt;br /&gt;
* postfix reload&lt;br /&gt;
* Send and email into a local virtual domain - it should have the &#039;&#039;X-Virus-Scanned: ClamAV using ClamSMTP&#039;&#039; header.&lt;br /&gt;
&lt;br /&gt;
=== Relay for Authenticated Users ===&lt;br /&gt;
&lt;br /&gt;
As configured above, the mail server accepts email from the Internet, but it does not relay email.  If it is a perimeter exchanger for a protected network, then you can add the protected networks to the &#039;&#039;mynetworks&#039;&#039; configuration line in /etc/postfix/main.cf&lt;br /&gt;
&lt;br /&gt;
This configuration change allows &#039;&#039;remote&#039;&#039; users to authenticate against the mail server and relay through it.  The rules for relaying are:&lt;br /&gt;
* Only authenticated users can relay&lt;br /&gt;
* Authentication Credentials must be encrypted with TLS or SSL&lt;br /&gt;
* Allow Submission and SMTPS ports for relaying (many consumer networks block port 25 - SMTP by default)&lt;br /&gt;
The process uses the dovecot authentication mechanism (used with IMAPS) to authenticate users before they are allowed to relay through postfix.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* Edit /etc/dovecot/dovecot.conf and add teh following inside the &#039;&#039;auth default&#039;&#039; stanza:&lt;br /&gt;
 # this is for postfix SASL (authenticated users can relay through us)&lt;br /&gt;
 socket listen {&lt;br /&gt;
                client {&lt;br /&gt;
                        path    = /var/spool/postfix/private/dovecot-auth.sock&lt;br /&gt;
                        mode    = 0660&lt;br /&gt;
                        user    = postfix&lt;br /&gt;
                        group   = postfix&lt;br /&gt;
                        }&lt;br /&gt;
                }&lt;br /&gt;
        }&lt;br /&gt;
* Restart dovecot&lt;br /&gt;
 /etc/init.d/dovecot restart&lt;br /&gt;
* Edit /etc/postfix/main.cf and add:&lt;br /&gt;
 # TLS Stuff -- since we allow SASL with tls *only*, we have to set up TLS first                    &lt;br /&gt;
 &lt;br /&gt;
 smtpd_tls_cert_file = /etc/lighttpd/server-bundle.pem&lt;br /&gt;
 smtpd_tls_key_file = /etc/lighttpd/server-bundle.pem&lt;br /&gt;
 smtpd_tls_CAfile = /etc/lighttpd/ca-crt.pem&lt;br /&gt;
 # If tls_security_level is set to &amp;quot;encrypt&amp;quot;, then SMTP rejects &lt;br /&gt;
 # unencrypted email (e.g. normal mail) which is bad.&lt;br /&gt;
 # By setting it to &amp;quot;may&amp;quot; you get TLS encrypted mail from google, slashdot, and other &lt;br /&gt;
 # interesting places.  Check your logs to see who&lt;br /&gt;
 smtpd_tls_security_level = may&lt;br /&gt;
 # Log info about the negotiated encryption levels&lt;br /&gt;
 smtpd_tls_received_header = yes&lt;br /&gt;
 smtpd_tls_loglevel = 1&lt;br /&gt;
 &lt;br /&gt;
 # SASL - this allows senders to authenticiate themselves&lt;br /&gt;
 # This along with &amp;quot;permit_sasl_authenticated&amp;quot; in smtpd_recipient_restrictions allows relaying&lt;br /&gt;
 smtpd_sasl_type = dovecot&lt;br /&gt;
 smtpd_sasl_path = private/dovecot-auth.sock&lt;br /&gt;
 smtpd_sasl_auth_enable = yes&lt;br /&gt;
 smtpd_sasl_authenticated_header = yes&lt;br /&gt;
 smtpd_tls_auth_only = yes&lt;br /&gt;
* Edit /etc/postfix/master.cf and enable the submission and smtps transports.  They are probably already at the top of your  master.cf file, just commented out:&lt;br /&gt;
 submission inet n       -       n       -       -       smtpd&lt;br /&gt;
   -o smtpd_tls_security_level=encrypt&lt;br /&gt;
   -o smtpd_sasl_auth_enable=yes&lt;br /&gt;
   -o smtpd_client_restrictions=permit_sasl_authenticated,reject&lt;br /&gt;
   -o milter_macro_daemon_name=ORIGINATING&lt;br /&gt;
 smtps     inet  n       -       n       -       -       smtpd&lt;br /&gt;
   -o smtpd_tls_security_level=encrypt&lt;br /&gt;
   -o smtpd_tls_wrappermode=yes&lt;br /&gt;
   -o smtpd_sasl_auth_enable=yes&lt;br /&gt;
   -o smtpd_client_restrictions=permit_sasl_authenticated,reject&lt;br /&gt;
   -o milter_macro_daemon_name=ORIGINATING&lt;br /&gt;
*Verfiy submission and smtps are defined in /etc/services&lt;br /&gt;
 grep &amp;quot;submission\|ssmtp&amp;quot; /etc/services&lt;br /&gt;
 submission	587/tcp				# mail message submission&lt;br /&gt;
 submission	587/udp&lt;br /&gt;
 smtps		465/tcp		ssmtp		# smtp protocol over TLS/SSL&lt;br /&gt;
 smtps		465/udp		ssmtp&lt;br /&gt;
* Restart postfix&lt;br /&gt;
 postfix reload&lt;br /&gt;
&lt;br /&gt;
At this point, you should be able to set up a mail client to relay through the server with TLS (port 587) or SSL (port 465)  Note that &amp;quot;plain&amp;quot; authentication is used because the underlying link is encrypted.  For example, in Thunderbird leave &amp;quot;secure authentication&amp;quot; unchecked, and choose STARTTLS (or TLS) for the connection security.&lt;br /&gt;
&lt;br /&gt;
=== Mailbox Quotas ===&lt;br /&gt;
&lt;br /&gt;
In the default configuration, PostfixAdmin knows about quotas, but they are not enforced.   Documentation on the web mentions the [http://vda.sourceforge.net vda patch to postfix] to enforce quotas.  The only bad thing... its a &#039;&#039;patch&#039;&#039;.   Postfix and Dovecot are both conservative systems, so if the patch isn&#039;t in the upstream source, we&#039;ll assume there&#039;s a good reason.   There is a way of using quotas without patches - and it involves using dovecot&#039;s [http://wiki.dovecot.org/LDA deliver] lda for local delivery.&lt;br /&gt;
&lt;br /&gt;
Note: As of Jan 2010, the documention is confusing, with multiple versions of dovecot, PostfixAdmin, and Mysql referenced.  These instructions apply to:&lt;br /&gt;
* Postgresql 8.4.2 &lt;br /&gt;
* PostfixAdmin 2.3 &lt;br /&gt;
* Dovecot 1.2.11&lt;br /&gt;
* Postfix 2.6.5&lt;br /&gt;
&lt;br /&gt;
Presumably later versions will work the same, but if not, please update the documentation and versions above.&lt;br /&gt;
&lt;br /&gt;
* Update /etc/dovecot/dovecot.conf (old lines shown commented out):&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
# old postfix &lt;br /&gt;
#       userdb static {&lt;br /&gt;
#               args =  uid=1006 gid=1006 home=/var/mail/domains/%d/%n&lt;br /&gt;
#               }&lt;br /&gt;
&lt;br /&gt;
# new quota support:&lt;br /&gt;
        userdb prefetch {&lt;br /&gt;
                }&lt;br /&gt;
&lt;br /&gt;
        userdb sql {&lt;br /&gt;
                args = /etc/dovecot/dovecot-sql.conf&lt;br /&gt;
                }&lt;br /&gt;
&lt;br /&gt;
        socket listen {&lt;br /&gt;
                client {&lt;br /&gt;
                        path    = /var/spool/postfix/private/dovecot-auth.sock&lt;br /&gt;
                        mode    = 0660&lt;br /&gt;
                        user    = postfix&lt;br /&gt;
                        group   = postfix&lt;br /&gt;
                        }&lt;br /&gt;
                # These lines below are for the deliver lda&lt;br /&gt;
                master {&lt;br /&gt;
                        path =  /var/run/dovecot/auth-master&lt;br /&gt;
                        mode    = 0660&lt;br /&gt;
                        user    = vmail&lt;br /&gt;
                        group   = vmail&lt;br /&gt;
                        }&lt;br /&gt;
                }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
protocol imap {                                                               &lt;br /&gt;
         mail_plugins = quota imap_quota                                       &lt;br /&gt;
         }                                                                     &lt;br /&gt;
                                                                              &lt;br /&gt;
protocol pop3 {                                                               &lt;br /&gt;
         mail_plugins = quota                                                  &lt;br /&gt;
         }                                                                     &lt;br /&gt;
                                                                              &lt;br /&gt;
dict {                                                                        &lt;br /&gt;
        quotadict = pgsql:/etc/dovecot/dovecot-dict-quota.conf                &lt;br /&gt;
        }                                                                     &lt;br /&gt;
                                                                              &lt;br /&gt;
plugin {                                                                      &lt;br /&gt;
         quota = dict:user::proxy::quotadict                                   &lt;br /&gt;
         }                                                     &lt;br /&gt;
                                                              &lt;br /&gt;
protocol lda {                                                &lt;br /&gt;
   postmaster_address = postmaster@host.example.com&lt;br /&gt;
   mail_plugins = quota                                        &lt;br /&gt;
   auth_socket_path =  /var/run/dovecot/auth-master&lt;br /&gt;
   sendmail_path = /usr/sbin/sendmail&lt;br /&gt;
}                                                                            &lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
 &lt;br /&gt;
You should already have a &amp;lt;tt&amp;gt;socket-&amp;gt; listen-&amp;gt; client&amp;lt;/tt&amp;gt; section, but it is listed above to show where it goes in relationship to the &amp;lt;tt&amp;gt;socket -&amp;gt; listen -&amp;gt; master&amp;lt;/tt&amp;gt; section&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* edit &amp;lt;tt&amp;gt;/etc/dovecot/dovecot-sql.conf&amp;lt;/tt&amp;gt; and replace the user and password queries with the following (you may not have a user_query yet - add it):&lt;br /&gt;
&lt;br /&gt;
 password_query = select username as user, password, 1006 as userdb_uid, 1006 as userdb_gid, &#039;*:bytes=&#039; || quota as userdb_quota_rule from mailbox  where local_part = &#039;%n&#039; and domain = &#039;%d&#039;&lt;br /&gt;
 user_query = select &#039;/var/mail/domains/&#039; as home, 1006 as uid, 1006 as gid, &#039;*:bytes=&#039; || quota  as quota_rule from mailbox where local_part = &#039;%n&#039; and domain =&#039;%d&#039;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* create &amp;lt;tt&amp;gt;/etc/dovecot/dovecot-dict-quota.conf&amp;lt;/tt&amp;gt;&lt;br /&gt;
 connect = host=localhost dbname=postfix user=postfix password=********&lt;br /&gt;
 &lt;br /&gt;
 map {&lt;br /&gt;
         pattern = priv/quota/storage&lt;br /&gt;
         table = quota2&lt;br /&gt;
         username_field =username&lt;br /&gt;
         value_field = bytes&lt;br /&gt;
 }&lt;br /&gt;
 &lt;br /&gt;
 map {&lt;br /&gt;
        pattern= priv/quota/messages&lt;br /&gt;
        table = quota2&lt;br /&gt;
        username_field = username&lt;br /&gt;
        value_field = messages&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
Side note: [http://wiki.dovecot.org/Quota/Dict The Dovecot Quota Documentation] mentions the need for a trigger with pgsql.  This was created in the PostfixAdmin install, which is why you instantiated the pgsql language when creating the database.  If not, you will need to create the trigger, to reference the quota2 table, not the quota table mentioned in the dovecot docs.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* create a new transport for the dovecot lda.   Add the following to  /etc/postfix/master.cf:&lt;br /&gt;
 # The dovecot deliver lda&lt;br /&gt;
 dovecot   unix  -       n       n       -       -       pipe&lt;br /&gt;
   flags=DRhu user=vmail:vmail argv=/usr/libexec/dovecot/deliver -f ${sender} -d ${user}@${nexthop}&lt;br /&gt;
&lt;br /&gt;
* Edit the /etc/postfix/main.cf.  Replace &lt;br /&gt;
 virtual_transport = virtual &lt;br /&gt;
with&lt;br /&gt;
 virtual_transport = dovecot&lt;br /&gt;
 dovecot_destination_recipient_limit = 1&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;TODO&#039;&#039;&#039;  This will cause over-quota emails to bounce.   Which could be a source of backscatter.   We need a way of checking quota limits after RBL checking but before the message is accepted in the queue.&lt;br /&gt;
&lt;br /&gt;
=== WebMail (RoundCube) ===&lt;br /&gt;
&lt;br /&gt;
[http://roundcube.net/ RoundCube] is an &amp;quot;ajax /Web2.0&amp;quot; web-mail client.  These instructions are for the Alpine Linux 1.10 repository &lt;br /&gt;
&lt;br /&gt;
* Add the package and related php modules:&lt;br /&gt;
 apk add roundcubemail php-xml php-openssl php-mcrypt php-gd php-iconv&lt;br /&gt;
&lt;br /&gt;
* link the roundcube application back into the docroot&lt;br /&gt;
 ln -s /usr/share/webapps/roundcube /var/www/domains/host.example.com/www/roundcube&lt;br /&gt;
&lt;br /&gt;
* follow the instructions in /usr/share/webapps/roundcube/INSTALL:&lt;br /&gt;
 cd /usr/share/webapps/roundcube&lt;br /&gt;
 chown -R lighttpd:lighttpd temp logs&lt;br /&gt;
 &lt;br /&gt;
 su postgres&lt;br /&gt;
 createuser roundcube&lt;br /&gt;
   Shall the new role be a superuser? (y/n) n&lt;br /&gt;
   Shall the new role be allowed to create databases? (y/n) n&lt;br /&gt;
   Shall the new role be allowed to create more new roles? (y/n) y&lt;br /&gt;
 createdb -O roundcube -E UNICODE -T template0 roundcubemail&lt;br /&gt;
 psql roundcubemail&lt;br /&gt;
   roundcubemail=# ALTER USER roundcube WITH PASSWORD &#039;the_new_password&#039;;&lt;br /&gt;
   roundcubemail=# \c - roundcube&lt;br /&gt;
   roundcubemail=&amp;gt; \i /usr/share/webapps/roundcube/SQL/postgres.initial.sql&lt;br /&gt;
   roundcubemail=&amp;gt; \q&lt;br /&gt;
 exit&lt;br /&gt;
&lt;br /&gt;
* edit /etc/php/php.ini and set date.timezone to your local timezone, or to UTC&lt;br /&gt;
&lt;br /&gt;
* restart lighttpd to verify the new php libraries are used&lt;br /&gt;
 /etc/init.d/lighttpd restart&lt;br /&gt;
&lt;br /&gt;
* Point your browser to http://host.example.com/roundcube/installer&lt;br /&gt;
* Start installation&lt;br /&gt;
&lt;br /&gt;
For the specific configuration parameters in the install step:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!Property&lt;br /&gt;
!Setting&lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;enable_spellcheck&#039;&#039; ||   disabled &lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;identities_level&#039;&#039; ||  one identity with possibility to edit all params but not email address &lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;log driver&#039;&#039; || syslog &lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;sylog_id&#039;&#039; || roundcube &lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;syslog_facility&#039;&#039; || mailsubsystem &lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;db_dnsw&#039;&#039; || pgsql properties, as described above &lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;imap_host&#039;&#039; || 127.0.0.1 &lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;auto_create_user&#039;&#039; || enabled &lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;smtp_server&#039;&#039; ||  127.0.0.1&lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;smtp_port&#039;&#039; ||  25&lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;smtp_user/smtp_pass&#039;&#039; ||  enable &#039;&#039;Use Current IMAP username and password for SMTP authentication&#039;&#039;&lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;smtp_log&#039;&#039; ||  enable (optional, but gives additional log record)&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
The other items can be left at default settings, or adjusted if desired.&lt;br /&gt;
&lt;br /&gt;
* Follow the instructions in step 3 of the install to copy the files to the server&lt;br /&gt;
* You should now be able to get to roundcube at http://host.example.com/roundcube&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
After its working, the INSTALL file recommends removing the install directory.   If you want to keep the installer around later, you can simply change the ownership and permissions.  So do &#039;&#039;&#039;one&#039;&#039;&#039; of the following:&lt;br /&gt;
 cd /usr/share/webapps/roundcube&lt;br /&gt;
 rm -rf LICENSE UPGRADING INSTALL README CHANGELOG  SQL installer&lt;br /&gt;
or&lt;br /&gt;
 cd /usr/share/webapps/roundcube&lt;br /&gt;
 chown -R root:root LICENSE UPGRADING INSTALL README CHANGELOG  SQL installer&lt;br /&gt;
 chmod -R 600 LICENSE UPGRADING INSTALL README CHANGELOG SQL &lt;br /&gt;
 chmod 700 SQL installer&lt;br /&gt;
&lt;br /&gt;
==== Enable Plug-ins ====&lt;br /&gt;
&lt;br /&gt;
RoundCube has various useful plug-ins, which could be found in &#039;&#039;/usr/share/webapps/roundcube/plugins&#039;&#039; directory. For example you may want to enable &#039;&#039;password&#039;&#039; plug-in to let users change their passwords directly from RoundCube using an extra Password Tab added to User Settings.&lt;br /&gt;
&lt;br /&gt;
* Grant limited permissions for &#039;&#039;roundcube&#039;&#039; database role &lt;br /&gt;
 psql -U postgres postfix&lt;br /&gt;
   postfix=# GRANT UPDATE (password) ON mailbox TO roundcube;&lt;br /&gt;
   postfix=# GRANT SELECT (username) ON mailbox TO roundcube;&lt;br /&gt;
   postfix=# \q&lt;br /&gt;
&lt;br /&gt;
* Setup &#039;&#039;password&#039;&#039; plug-in parameters in &#039;&#039;/usr/share/webapps/roundcube/plugins/password/config.inc.php&#039;&#039;&lt;br /&gt;
 mv /usr/share/webapps/roundcube/plugins/password/config.inc.php.dist /usr/share/webapps/roundcube/plugins/password/config.inc.php&lt;br /&gt;
 vi /usr/share/webapps/roundcube/plugins/password/config.inc.php&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
$rcmail_config[&#039;password_db_dsn&#039;] = &#039;pgsql://roundcube:&amp;lt;roundcube_password&amp;gt;@localhost/postfix&#039;;&lt;br /&gt;
...&lt;br /&gt;
$rcmail_config[&#039;password_query&#039;] = &amp;quot;UPDATE mailbox set password = %c where username = %u&amp;quot;;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* Enable &#039;&#039;password&#039;&#039; plug-in&lt;br /&gt;
 vi /usr/share/webapps/roundcube/config/main.inc.php&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
...&lt;br /&gt;
$rcmail_config[&#039;plugins&#039;] = array(&#039;password&#039;);&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== OpenLDAP based Address Book ===&lt;br /&gt;
&lt;br /&gt;
This OpenLDAP configuration uses the SQL backend, which represents information stored in PostgreSQL as an LDAP subtree for Address Book functionality for email lookups, user authentication or even &lt;br /&gt;
replication account information between sites. This procedure uses some metainformation to translate LDAP queries to SQL queries, leaving relational schema untouched, which allows SQL and LDAP &lt;br /&gt;
applications to inter-operate without replication, and exchange data as needed. The SQL backend uses UnixODBC to connect to PostgresSQL. &lt;br /&gt;
&lt;br /&gt;
* Install OpenLDAP and ODBC&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
apk add openldap libldap openldap-back-sql php-ldap unixodbc psqlodbc ca-certificates&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Note&#039;&#039;&#039;: Perhaps some packages should be installed from &amp;quot;edge&amp;quot; repository&lt;br /&gt;
&lt;br /&gt;
* Update &amp;quot;postfix&amp;quot; database (it will add &#039;id&#039; columns to mailbox and domain tables, also will create tables and views to represent LDAP metainformation)&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Note&#039;&#039;&#039;: These instructions are for example domain example.com. So make sure you replaced all entries of &#039;example&#039; and &#039;com&#039; according to your domain name parts.&lt;br /&gt;
&lt;br /&gt;
Put the following into a new file:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
ALTER TABLE domain ADD COLUMN id SERIAL; &lt;br /&gt;
ALTER TABLE mailbox ADD COLUMN id SERIAL; &lt;br /&gt;
&lt;br /&gt;
CREATE TABLE ldap_entry_objclasses (&lt;br /&gt;
    entry_id integer NOT NULL,&lt;br /&gt;
    oc_name character varying(64)&lt;br /&gt;
);&lt;br /&gt;
&lt;br /&gt;
CREATE TABLE ldap_oc_mappings (&lt;br /&gt;
    name character varying(64) NOT NULL,&lt;br /&gt;
    keytbl character varying(64) NOT NULL,&lt;br /&gt;
    keycol character varying(64) NOT NULL,&lt;br /&gt;
    create_proc character varying(255),&lt;br /&gt;
    delete_proc character varying(255),&lt;br /&gt;
    expect_return integer NOT NULL,&lt;br /&gt;
);&lt;br /&gt;
&lt;br /&gt;
ALTER TABLE ldap_oc_mappings ADD COLUMN id SERIAL;&lt;br /&gt;
ALTER TABLE ldap_oc_mappings ADD PRIMARY KEY (id);&lt;br /&gt;
&lt;br /&gt;
CREATE TABLE ldap_attr_mappings_test (&lt;br /&gt;
    oc_map_id integer NOT NULL REFERENCES ldap_oc_mappings(id),&lt;br /&gt;
    name character varying(255) NOT NULL,&lt;br /&gt;
    sel_expr character varying(255) NOT NULL,&lt;br /&gt;
    sel_expr_u character varying(255),&lt;br /&gt;
    from_tbls character varying(255) NOT NULL,&lt;br /&gt;
    join_where character varying(255),&lt;br /&gt;
    add_proc character varying(255),&lt;br /&gt;
    delete_proc character varying(255),&lt;br /&gt;
    param_order integer NOT NULL,&lt;br /&gt;
    expect_return integer NOT NULL,&lt;br /&gt;
);&lt;br /&gt;
&lt;br /&gt;
ALTER TABLE ldap_attr_mappings_test ADD COLUMN id SERIAL;&lt;br /&gt;
ALTER TABLE ldap_attr_mappings_test ADD PRIMARY KEY (id);&lt;br /&gt;
&lt;br /&gt;
CREATE VIEW ldap_dcs AS&lt;br /&gt;
    (SELECT (domain.id + 100000) AS id, &lt;br /&gt;
            (((&#039;dc=&#039;::text || split_part((domain.domain)::text, &#039;.&#039;::text, 1)) || &#039;,dc=&#039;::text) || &lt;br /&gt;
            CASE WHEN (split_part((domain.domain)::text, &#039;.&#039;::text, 2) = &#039;com&#039;::text) THEN split_part((domain.domain)::text, &#039;.&#039;::text, 2) &lt;br /&gt;
                 ELSE ((split_part((domain.domain)::text, &#039;.&#039;::text, 2) || &#039;,dc=&#039;::text) || split_part((domain.domain)::text, &#039;.&#039;::text, 3)) &lt;br /&gt;
            END) AS dn, &lt;br /&gt;
            1 AS oc_map_id, &lt;br /&gt;
            100000 AS parent, &lt;br /&gt;
            0 AS keyval, &lt;br /&gt;
            domain.domain&lt;br /&gt;
     FROM domain &lt;br /&gt;
     WHERE domain.domain &amp;lt;&amp;gt; &#039;ALL&#039; &lt;br /&gt;
      UNION &lt;br /&gt;
     SELECT 100000 AS id, &lt;br /&gt;
           &#039;dc=com&#039; AS dn, &lt;br /&gt;
           1 AS oc_map_id, &lt;br /&gt;
           0 AS parent, &lt;br /&gt;
           0 AS keyval, &lt;br /&gt;
           &#039;com&#039; AS domain);&lt;br /&gt;
&lt;br /&gt;
CREATE VIEW ldap_entries AS&lt;br /&gt;
    SELECT mailbox.id, &lt;br /&gt;
    (((((&#039;cn=&#039;::text || initcap(replace(split_part((mailbox.username)::text, &#039;@&#039;::text, 1), &#039;.&#039;::text, &#039; &#039;::text))) || &#039;,dc=&#039;::text) || &lt;br /&gt;
          split_part(split_part((mailbox.username)::text, &#039;@&#039;::text, 2), &#039;.&#039;::text, 1)) || &#039;,dc=&#039;::text) || &lt;br /&gt;
             CASE WHEN (split_part(split_part((mailbox.username)::text, &#039;@&#039;::text, 2), &#039;.&#039;::text, 2) = &#039;com&#039;::text) &lt;br /&gt;
                  THEN split_part(split_part((mailbox.username)::text, &#039;@&#039;::text, 2), &#039;.&#039;::text, 2) &lt;br /&gt;
                  ELSE ((split_part(split_part((mailbox.username)::text, &#039;@&#039;::text, 2), &#039;.&#039;::text, 2) || &#039;,dc=&#039;::text) || &lt;br /&gt;
                         split_part(split_part((mailbox.username)::text, &#039;@&#039;::text, 2), &#039;.&#039;::text, 3)) &lt;br /&gt;
             END) AS dn, &lt;br /&gt;
          1 AS oc_map_id, &lt;br /&gt;
          (SELECT ldap_dcs.id &lt;br /&gt;
           FROM ldap_dcs &lt;br /&gt;
           WHERE ((ldap_dcs.domain)::text = (mailbox.domain)::text)) AS parent, &lt;br /&gt;
           mailbox.id AS keyval &lt;br /&gt;
           FROM mailbox &lt;br /&gt;
           UNION &lt;br /&gt;
           SELECT ldap_dcs.id,  &lt;br /&gt;
                  ldap_dcs.dn, &lt;br /&gt;
                  ldap_dcs.oc_map_id, &lt;br /&gt;
                  ldap_dcs.parent, &lt;br /&gt;
                  ldap_dcs.keyval &lt;br /&gt;
           FROM ldap_dcs;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Finally, execute the commands in the file with:&lt;br /&gt;
 cat script | psql -U postfix postfix&lt;br /&gt;
&lt;br /&gt;
* Fill out LDAP tables according to following example (make sure to separate values with TABs):&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
cat - &amp;lt;&amp;lt;EOF | psql -U postgres postfix&lt;br /&gt;
COPY ldap_attr_mappings (id, oc_map_id, name, sel_expr, sel_expr_u, from_tbls, join_where, add_proc, delete_proc, param_order, expect_return) FROM stdin;&lt;br /&gt;
1	1	displayName	mailbox.name	\N	mailbox	\N	\N	\N	3	0&lt;br /&gt;
2	1	mail	mailbox.username	\N	mailbox	\N	\N	\N	3	0&lt;br /&gt;
3	1	cn	mailbox.name	\N	mailbox	\N	\N	\N	3	0&lt;br /&gt;
4	1	userPassword	&#039;{CRYPT}&#039;||mailbox.password	\N	mailbox	\N	\N	\N	3	0&lt;br /&gt;
\.&lt;br /&gt;
&lt;br /&gt;
COPY ldap_oc_mappings (id, name, keytbl, keycol, create_proc, delete_proc, expect_return) FROM stdin;&lt;br /&gt;
1	exampleBox	mailbox	id	\N	\N	1&lt;br /&gt;
\.&lt;br /&gt;
EOF&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* Check that &amp;quot;ldap_dcs&amp;quot; view presens something like this:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
echo &#039;select * from ldap_dcs&#039; | psql -U postgres postfix&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
   id   |             dn              | oc_map_id | parent | keyval |       domain       &lt;br /&gt;
--------+-----------------------------+-----------+--------+--------+--------------------&lt;br /&gt;
 100000 | dc=com                      |         1 |      0 |      0 | com&lt;br /&gt;
 100001 | dc=example,dc=com           |         1 | 100000 |      0 | example.com&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* Check that &amp;quot;ldap_entries&amp;quot; view presens something like this:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
echo &#039;select * from ldap_entries&#039; | psql -U postgres postfix&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
   id   |                          dn                           | oc_map_id | parent | keyval &lt;br /&gt;
--------+-------------------------------------------------------+-----------+--------+--------&lt;br /&gt;
    1   | cn=address1,dc=example,dc=com                         |         1 | 100001 |    1&lt;br /&gt;
...&lt;br /&gt;
   123  | cn=address123,dc=example,dc=com                       |         1 | 100001 |    1&lt;br /&gt;
 100000 | dc=com                                                |         1 |      0 |    0&lt;br /&gt;
 100001 | dc=example,dc=com                                     |         1 | 100000 |    0&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* Configure ODBC parameters&lt;br /&gt;
&lt;br /&gt;
Edit /etc/odbc.ini:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
[PostgreSQL]&lt;br /&gt;
Description             = Connection to Postgres&lt;br /&gt;
Driver                  = PostgreSQL&lt;br /&gt;
Trace                   = Yes&lt;br /&gt;
TraceFile               = sql.log&lt;br /&gt;
Database                = postfix&lt;br /&gt;
Servername              = 127.0.0.1&lt;br /&gt;
UserName                =&lt;br /&gt;
Password                =&lt;br /&gt;
Port                    = 5432&lt;br /&gt;
Protocol                = 6.4&lt;br /&gt;
ReadOnly                = No&lt;br /&gt;
RowVersining            = No&lt;br /&gt;
ShowSystemTables        = No&lt;br /&gt;
ShowOidColumn           = No&lt;br /&gt;
FakeOidIndex            = No&lt;br /&gt;
ConnSettings            =&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Edit /etc/odbcinst.ini:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
[PostgreSQL]&lt;br /&gt;
Description     = PostgreSQL driver for Linux&lt;br /&gt;
Driver          = /usr/lib/psqlodbcw.so&lt;br /&gt;
Setup           = /usr/lib/libodbcpsqlS.so&lt;br /&gt;
FileUsage       = 1&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* Test ODBC connection&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
echo &amp;quot;select * from domain;&amp;quot; | isql PostgreSQL postgres&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* Provide permission to certificate for LDAP server&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
chown ldap /etc/lighttpd/server-bundle.pem&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* Edit LDAP schema&lt;br /&gt;
&lt;br /&gt;
Edit /etc/openldap/schema/example.com.schema:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
attributetype ( 0.9.2342.19200300.100.1.3&lt;br /&gt;
	NAME ( &#039;mail&#039; &#039;rfc822Mailbox&#039; )&lt;br /&gt;
	DESC &#039;RFC1274: RFC822 Mailbox&#039;&lt;br /&gt;
        EQUALITY caseIgnoreIA5Match&lt;br /&gt;
        SUBSTR caseIgnoreIA5SubstringsMatch&lt;br /&gt;
        SYNTAX 1.3.6.1.4.1.1466.115.121.1.26{256} )&lt;br /&gt;
&lt;br /&gt;
attributetype ( 2.16.840.1.113730.3.1.241&lt;br /&gt;
	NAME &#039;displayName&#039;&lt;br /&gt;
	DESC &#039;RFC2798: preferred name to be used when displaying entries&#039;&lt;br /&gt;
	EQUALITY caseIgnoreMatch&lt;br /&gt;
	SUBSTR caseIgnoreSubstringsMatch&lt;br /&gt;
	SYNTAX 1.3.6.1.4.1.1466.115.121.1.15&lt;br /&gt;
	SINGLE-VALUE )&lt;br /&gt;
&lt;br /&gt;
objectclass   ( 2.16.840.1.113730.3.2.2&lt;br /&gt;
        NAME &#039;exampleBox&#039;&lt;br /&gt;
	DESC &#039;example.com mailbox&#039;&lt;br /&gt;
	MUST ( displayName $ mail $ userPassword )&lt;br /&gt;
	)&lt;br /&gt;
&lt;br /&gt;
# RFC 1274 + RFC 2247&lt;br /&gt;
attributetype ( 0.9.2342.19200300.100.1.25&lt;br /&gt;
        NAME ( &#039;dc&#039; &#039;domainComponent&#039; )&lt;br /&gt;
        DESC &#039;RFC1274/2247: domain component&#039;&lt;br /&gt;
        EQUALITY caseIgnoreIA5Match&lt;br /&gt;
        SUBSTR caseIgnoreIA5SubstringsMatch&lt;br /&gt;
        SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 SINGLE-VALUE )&lt;br /&gt;
&lt;br /&gt;
attributetype ( 2.5.4.46 NAME &#039;dnQualifier&#039;&lt;br /&gt;
        DESC &#039;RFC2256: DN qualifier&#039;&lt;br /&gt;
        EQUALITY caseIgnoreMatch&lt;br /&gt;
        ORDERING caseIgnoreOrderingMatch&lt;br /&gt;
        SUBSTR caseIgnoreSubstringsMatch&lt;br /&gt;
        SYNTAX 1.3.6.1.4.1.1466.115.121.1.44 )&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* Configure LDAP server&lt;br /&gt;
&lt;br /&gt;
Edit /etc/openldap/slapd.conf:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
include         /etc/openldap/schema/example.com.schema&lt;br /&gt;
pidfile         /var/run/openldap/slapd.pid&lt;br /&gt;
argsfile        /var/run/openldap/slapd.args&lt;br /&gt;
&lt;br /&gt;
TLSCipherSuite HIGH&lt;br /&gt;
TLSCACertificateFile /etc/lighttpd/ca-crt.pem&lt;br /&gt;
TLSCertificateFile /etc/lighttpd/server-bundle.pem&lt;br /&gt;
TLSCertificateKeyFile /etc/lighttpd/server-bundle.pem&lt;br /&gt;
TLSVerifyClient never &lt;br /&gt;
&lt;br /&gt;
# This is needed for proper representation of MD5-CRYPT format stored in database&lt;br /&gt;
#  see more details in http://strugglers.net/~andy/blog/2010/01/23/openldap-and-md5crypt/&lt;br /&gt;
password-hash  {CRYPT}&lt;br /&gt;
password-crypt-salt-format &amp;quot;$1$%.8s&amp;quot;&lt;br /&gt;
&lt;br /&gt;
loglevel        stats&lt;br /&gt;
moduleload	/usr/lib/openldap/back_sql.so&lt;br /&gt;
sizelimit 3000&lt;br /&gt;
&lt;br /&gt;
database        sql&lt;br /&gt;
&lt;br /&gt;
dbname		PostgreSQL&lt;br /&gt;
dbuser		postfix&lt;br /&gt;
dbpasswd	*****&lt;br /&gt;
&lt;br /&gt;
suffix          &amp;quot;dc=example,dc=com&amp;quot;&lt;br /&gt;
rootdn          &amp;quot;cn=admin,dc=example,dc=com&amp;quot;&lt;br /&gt;
rootpw		{MD5}&amp;lt;Hashed password for root dn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
upper_func      &amp;quot;upper&amp;quot;&lt;br /&gt;
strcast_func    &amp;quot;text&amp;quot;&lt;br /&gt;
concat_pattern  &amp;quot;?||?&amp;quot;&lt;br /&gt;
has_ldapinfo_dn_ru      no&lt;br /&gt;
lastmod         off&lt;br /&gt;
&lt;br /&gt;
access to attrs=userPassword by * auth&lt;br /&gt;
&lt;br /&gt;
access to * by peername.ip=127.0.0.1 read&lt;br /&gt;
            ### by peername.ip=&amp;lt;IP&amp;gt;%&amp;lt;netmask&amp;gt; read&lt;br /&gt;
            ### by peername.ip=&amp;lt;IP&amp;gt; read&lt;br /&gt;
	    by users read&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* Set permissions for slapd.conf&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
chown ldap:ldap /etc/openldap/slapd.conf&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* Configure startup parameters to make sure that LDAP server start AFTER PostgreSQL and listens on localhost with clear text and public IP with SSL&lt;br /&gt;
&lt;br /&gt;
Edit /etc/conf.d/slapd:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
echo rc_need=&amp;quot;postgresql&amp;quot; &lt;br /&gt;
OPTS=&amp;quot;-h &#039;ldaps:// ldap://127.0.0.1&#039;&amp;quot;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* Start LDAP server&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
rc-update add slapd default&lt;br /&gt;
/etc/init.d/slapd start&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* Configure LDAP client utilities&lt;br /&gt;
&lt;br /&gt;
Edit /etc/openldap/ldap.conf&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
BASE	dc=example,dc=com&lt;br /&gt;
URI	ldaps://host.example.com&lt;br /&gt;
&lt;br /&gt;
TLS_CACERT /etc/lighttpd/ca-crt.pem&lt;br /&gt;
TLS_CERT /etc/lighttpd/server-bundle.pem&lt;br /&gt;
TLS_KEY /etc/lighttpd/server-bundle.pem&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* Test LDAP server&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
ldapsearch -z 3&lt;br /&gt;
ldapsearch -z 3 -x -W -D cn=admin,dc=example,dc=com&lt;br /&gt;
ldapsearch -z 3 -x -W -D cn=address1,dc=example,dc=com&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* Configure RoundCube webmail for email lookups&lt;br /&gt;
&lt;br /&gt;
Edit /usr/share/webapps/roundcube/config/main.inc.php:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
$rcmail_config[&#039;ldap_debug&#039;] = false;&lt;br /&gt;
...&lt;br /&gt;
$rcmail_config[&#039;address_book_type&#039;] = &#039;ldap&#039;;&lt;br /&gt;
&lt;br /&gt;
$rcmail_config[&#039;ldap_public&#039;][&#039;example.com&#039;] = array(&lt;br /&gt;
  &#039;name&#039;          =&amp;gt; &#039;example.com&#039;,&lt;br /&gt;
  &#039;hosts&#039;         =&amp;gt; array(&#039;127.0.0.1&#039;),&lt;br /&gt;
  &#039;port&#039;          =&amp;gt; 389,&lt;br /&gt;
  &#039;use_tls&#039;         =&amp;gt; false,&lt;br /&gt;
  &#039;user_specific&#039; =&amp;gt; false,&lt;br /&gt;
  &#039;base_dn&#039;       =&amp;gt; &#039;dc=example,dc=com&#039;,&lt;br /&gt;
  &#039;bind_dn&#039;       =&amp;gt; &#039;&#039;,&lt;br /&gt;
  &#039;bind_pass&#039;     =&amp;gt; &#039;&#039;,&lt;br /&gt;
  &#039;writable&#039;      =&amp;gt; false,&lt;br /&gt;
  &#039;LDAP_Object_Classes&#039; =&amp;gt; array(&amp;quot;top&amp;quot;, &amp;quot;exampleBox&amp;quot;),&lt;br /&gt;
  &#039;required_fields&#039;     =&amp;gt; array(&amp;quot;cn&amp;quot;, &amp;quot;sn&amp;quot;, &amp;quot;mail&amp;quot;),&lt;br /&gt;
  &#039;LDAP_rdn&#039;      =&amp;gt; &#039;mail&#039;,&lt;br /&gt;
  &#039;ldap_version&#039;  =&amp;gt; 3,&lt;br /&gt;
  &#039;search_fields&#039; =&amp;gt; array(&#039;mail&#039;, &#039;cn&#039;, &#039;sn&#039;, &#039;givenName&#039;),&lt;br /&gt;
  &#039;name_field&#039;    =&amp;gt; &#039;cn&#039;,&lt;br /&gt;
  &#039;email_field&#039;   =&amp;gt; &#039;mail&#039;,&lt;br /&gt;
  &#039;surname_field&#039; =&amp;gt; &#039;sn&#039;,&lt;br /&gt;
  &#039;firstname_field&#039; =&amp;gt; &#039;gn&#039;,&lt;br /&gt;
  &#039;sort&#039;          =&amp;gt; &#039;cn&#039;,&lt;br /&gt;
  &#039;scope&#039;         =&amp;gt; &#039;sub&#039;,&lt;br /&gt;
  &#039;filter&#039;        =&amp;gt; &#039;(objectClass=*)&#039;, // Construct here any filter you need&lt;br /&gt;
  &#039;fuzzy_search&#039;  =&amp;gt; true);&lt;br /&gt;
&lt;br /&gt;
$rcmail_config[&#039;autocomplete_addressbooks&#039;] = array(&#039;example.com&#039;);&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== log rotation ==&lt;br /&gt;
&lt;br /&gt;
Ensure the busybox cron service is started and is configured to auto-start:&lt;br /&gt;
&lt;br /&gt;
 /etc/init.d/cron start&lt;br /&gt;
 rc-update add cron default&lt;br /&gt;
&lt;br /&gt;
Add log rotate:&lt;br /&gt;
&lt;br /&gt;
 apk add logrotate&lt;br /&gt;
&lt;br /&gt;
Edit &#039;&#039;/etc/logrotate.conf&#039;&#039; as desired, but the defaults should be sufficient for most people.&lt;br /&gt;
&lt;br /&gt;
== Optional: Configure Web Server Virtual Domains ==&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Note:&#039;&#039;&#039; These steps can be done &#039;&#039;in addition to&#039;&#039; the default lighttpd configuration above, which allows you to access the ACF, PostfixAdmin and Roundcube interfaces as subfolders of one web service.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Note:&#039;&#039;&#039; If you provide SSL access for multiple domain site you may need to follow http://redmine.lighttpd.net/projects/lighttpd/wiki/Docs:SSL#SSL-on-multiple-domains in order to provide multi-domain certificates. If you would like to redirect hosts to their secure equivalents use the following instructions http://redmine.lighttpd.net/projects/lighttpd/wiki/HowToRedirectHttpToHttps.&lt;br /&gt;
&lt;br /&gt;
This server hosts three separate web applications, and these can be handled as three &#039;&#039;different&#039;&#039; virtual domains on the same web server. They will be distinguished by their DNS names, so you can choose domains for the three separate services (or at least the ones you want to publish):&lt;br /&gt;
&lt;br /&gt;
* ACF - Alpine Configuration Framework for managing the server&lt;br /&gt;
* PostfixAdmin - for managing the postfix installation&lt;br /&gt;
* RoundCube - for accessing individual mailboxes&lt;br /&gt;
&lt;br /&gt;
Choose three different domains (from here on known as ACF_DOMAIN, POSTFIXADMIN_DOMAIN, and ROUNDCUBE_DOMAIN) and configure DNS for all three to point to the IP address of your host. These should be DNS &#039;&#039;&#039;A&#039;&#039;&#039; records.&lt;br /&gt;
&lt;br /&gt;
Then, configure lighttpd to handle the three separate domains by editing /etc/lighttpd/lighttpd.conf:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 $HTTP[&amp;quot;host&amp;quot;] == &amp;quot;ACF_DOMAIN&amp;quot; {&lt;br /&gt;
	simple-vhost.server-root   = &amp;quot;/var/www/domains/&amp;quot;&lt;br /&gt;
	simple-vhost.default-host  = &amp;quot;/ACF_DOMAIN/&amp;quot;&lt;br /&gt;
	simple-vhost.document-root = &amp;quot;www/&amp;quot;&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
 $HTTP[&amp;quot;host&amp;quot;] == &amp;quot;POSTFIXADMIN_DOMAIN&amp;quot; {&lt;br /&gt;
	simple-vhost.server-root   = &amp;quot;/var/www/domains/&amp;quot;&lt;br /&gt;
	simple-vhost.default-host  = &amp;quot;/POSTFIXADMIN_DOMAIN/&amp;quot;&lt;br /&gt;
	simple-vhost.document-root = &amp;quot;www/&amp;quot;&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
 $HTTP[&amp;quot;host&amp;quot;] == &amp;quot;ROUNDCUBE_DOMAIN&amp;quot; {&lt;br /&gt;
	simple-vhost.server-root   = &amp;quot;/var/www/domains/&amp;quot;&lt;br /&gt;
	simple-vhost.default-host  = &amp;quot;/ROUNDCUBE_DOMAIN/&amp;quot;&lt;br /&gt;
	simple-vhost.document-root = &amp;quot;www/&amp;quot;&lt;br /&gt;
 }&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
And, then link the appropriate www directories.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  mkdir -p /var/www/domains/ACF_DOMAIN&lt;br /&gt;
  ln -s /usr/share/acf/www /var/www/domains/ACF_DOMAIN/www&lt;br /&gt;
&lt;br /&gt;
  mkdir -p /var/www/domains/POSTFIXADMIN_DOMAIN&lt;br /&gt;
  ln -s /var/www/domains/host.example.com/www/postfixadmin /var/www/domains/POSTFIXADMIN_DOMAIN/www&lt;br /&gt;
&lt;br /&gt;
  mkdir -p /var/www/domains/ROUNDCUBE_DOMAIN&lt;br /&gt;
  ln -s /usr/share/webapps/roundcube /var/www/domains/ROUNDCUBE_DOMAIN/www&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;/div&gt;</summary>
		<author><name>Djhughes</name></author>
	</entry>
	<entry>
		<id>https://wiki.alpinelinux.org/w/index.php?title=ISP_Mail_Server_HowTo&amp;diff=3499</id>
		<title>ISP Mail Server HowTo</title>
		<link rel="alternate" type="text/html" href="https://wiki.alpinelinux.org/w/index.php?title=ISP_Mail_Server_HowTo&amp;diff=3499"/>
		<updated>2010-03-19T09:22:25Z</updated>

		<summary type="html">&lt;p&gt;Djhughes: update for dovecot 1.2.11&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== A Full Service Mail Server ==&lt;br /&gt;
&lt;br /&gt;
The goal of this document is to describe how to set up postfix, dovecot, clamav, dspam, roundecube, and postfixadmin for a full-featured &amp;quot;ISP&amp;quot; level mail server.&lt;br /&gt;
&lt;br /&gt;
The server must provide:&lt;br /&gt;
&lt;br /&gt;
* multiple virtual domains&lt;br /&gt;
* admins for each domain (to add/remove virtual accounts)&lt;br /&gt;
* Quota support per domain / account&lt;br /&gt;
* downloading email via IMAP / IMAPS / POP3 / POP3S&lt;br /&gt;
* relaying email for authenticated users with TLS or SSL (Submission / SMTPS protocol)&lt;br /&gt;
* Standard filters (virus/spam/rbl/etc)&lt;br /&gt;
* Web mail client&lt;br /&gt;
* Value Add services&lt;br /&gt;
&lt;br /&gt;
== Set up Lighttpd + PHP ==&lt;br /&gt;
&lt;br /&gt;
PostfixAdmin needs php pgpsql and imap modules, so we do it in this step.&lt;br /&gt;
&lt;br /&gt;
  apk add lighttpd php php-pgsql php-imap&lt;br /&gt;
&lt;br /&gt;
Stop and remove mini_httpd, and move ACF to lighttpd;  We are setting this up to be a multi-domain virtual web server (replace host.example.com with the actual domain):&lt;br /&gt;
&lt;br /&gt;
  mkdir -p /var/www/domains/host.example.com/www&lt;br /&gt;
  ln -s /usr/share/acf/www /var/www/domains/host.example.com/www/acf&lt;br /&gt;
&lt;br /&gt;
Edit /var/www/domains/host.example.com/index.html to put a simple redirection page:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;lt;!DOCTYPE HTML PUBLIC &amp;quot;-//W3C//DTD HTML 4.01//EN&amp;quot; &amp;quot;http://www.w3.org/TR/html4/strict.dtd&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;html lang=&amp;quot;en&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;head&amp;gt;&lt;br /&gt;
&amp;lt;meta http-equiv=&amp;quot;Content-Type&amp;quot; content=&amp;quot;text/html; charset=ISO-8859-1&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;title&amp;gt;host.example.com Redirector&amp;lt;/title&amp;gt;&lt;br /&gt;
&amp;lt;/head&amp;gt;&lt;br /&gt;
&amp;lt;body&amp;gt;&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;&amp;lt;a href=&amp;quot;/acf&amp;quot;&amp;gt;ACF&amp;lt;/a&amp;gt;&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;&amp;lt;a href=&amp;quot;/postfixadmin&amp;quot;&amp;gt;PostfixAdmin&amp;lt;/a&amp;gt;&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;&amp;lt;a href=&amp;quot;/roundcube&amp;quot;&amp;gt;Roundcube&amp;lt;/a&amp;gt;&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
&amp;lt;/body&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Edit /etc/lighttpd/mod_cgi.conf to serve haserl files by adding a &amp;quot;&amp;quot; =&amp;gt; &amp;quot;&amp;quot; cgi handler and to treat /acf/cgi-bin as a CGI directory (remove the &#039;^&#039;)&lt;br /&gt;
&lt;br /&gt;
 $HTTP[&amp;quot;url&amp;quot;] =~ &amp;quot;/cgi-bin/&amp;quot; {&lt;br /&gt;
     # disable directory listings&lt;br /&gt;
     dir-listing.activate = &amp;quot;disable&amp;quot;&lt;br /&gt;
     # only allow cgi&#039;s in this directory&lt;br /&gt;
     cgi.assign = (&lt;br /&gt;
 		&amp;quot;.pl&amp;quot;	=&amp;gt;	&amp;quot;/usr/bin/perl&amp;quot;,&lt;br /&gt;
 		&amp;quot;.cgi&amp;quot;	=&amp;gt;	&amp;quot;/usr/bin/perl&amp;quot;,&lt;br /&gt;
 		&amp;quot;&amp;quot; =&amp;gt; &amp;quot;&amp;quot;&lt;br /&gt;
 	)&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
Add these lines to /etc/lighttpd/lighttpd.conf to point to the new document root, and set it up to listen on port 443 (replace &#039;&#039;host.example.com&#039;&#039; with the actual domain and &#039;&#039;ip_address_of_server&#039;&#039; with the actual IP address):&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
simple-vhost.server-root   = &amp;quot;/var/www/domains/&amp;quot;&lt;br /&gt;
simple-vhost.default-host  = &amp;quot;/host.example.com/&amp;quot;&lt;br /&gt;
simple-vhost.document-root = &amp;quot;www/&amp;quot;&lt;br /&gt;
&lt;br /&gt;
$SERVER[&amp;quot;socket&amp;quot;] == &amp;quot;ip_address_of_server:443&amp;quot; {&lt;br /&gt;
ssl.engine    = &amp;quot;enable&amp;quot;&lt;br /&gt;
ssl.pemfile   = &amp;quot;/etc/lighttpd/server-bundle.pem&amp;quot;&lt;br /&gt;
ssl.ca-file   = &amp;quot;/etc/lighttpd/ca-crt.pem&amp;quot;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Ensure that the simple_vhosts module is loaded, as well as the cgi config scripts by uncommenting the following lines in /etc/lighttpd/lighttpd.conf&lt;br /&gt;
&lt;br /&gt;
 server.modules = (&lt;br /&gt;
     #  other modules may be listed&lt;br /&gt;
     &amp;quot;mod_simple_vhost&amp;quot;, &lt;br /&gt;
     #  other modules may be listed&lt;br /&gt;
  .&lt;br /&gt;
  .&lt;br /&gt;
  .&lt;br /&gt;
     include &amp;quot;mod_cgi.conf&amp;quot;&lt;br /&gt;
 &lt;br /&gt;
     include &amp;quot;mod_fastcgi.conf&amp;quot;&lt;br /&gt;
 &lt;br /&gt;
&lt;br /&gt;
Get a web certificate, and install it.  If you want to use a self-signed cert, you can use [[Generating SSL certs with ACF]] or [[Generating SSL certs with ACF 1.9]].  If you create a certificate with ACF, you can create the &amp;quot;server-bundle.pem&amp;quot; and the &amp;quot;ca-crt.pem&amp;quot; file with these commands:&lt;br /&gt;
&lt;br /&gt;
  openssl pkcs12 -nokeys -cacerts -in certificate.pfx  -out /etc/lighttpd/ca-crt.pem&lt;br /&gt;
  openssl pkcs12 -nodes -in certifcate.pfx -out /etc/lighttpd/server-bundle.pem&lt;br /&gt;
  chown root:root /etc/lighttpd/server-bundle.pem&lt;br /&gt;
  chmod 400 /etc/lighttpd/server-bundle.pem&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Note:&#039;&#039;&#039; The server certificate &#039;&#039;and&#039;&#039; key are in the server-bundle.pem file, so it is critical that the file be read-only by user &amp;quot;root&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
 Editme: We should probably only serve ACF to restricted hosts&lt;br /&gt;
&lt;br /&gt;
Stop and remove mini_httpd; start lighttpd, test&lt;br /&gt;
&lt;br /&gt;
  /etc/init.d/mini_httpd stop&lt;br /&gt;
  rc-update del mini_httpd&lt;br /&gt;
  apk del mini_httpd&lt;br /&gt;
  rc-update add lighttpd&lt;br /&gt;
  /etc/init.d/lighttpd start&lt;br /&gt;
&lt;br /&gt;
At this point you should be able to see ACF being served with lighttpd (Note: this will work well with alpine 1.10. With earlier versions there will be problems.)  https://host.example.com/acf/&lt;br /&gt;
&lt;br /&gt;
== Install Postgresql ==&lt;br /&gt;
&lt;br /&gt;
Add and configure postgresql&lt;br /&gt;
&lt;br /&gt;
  apk add acf-postgresql postgresql-client&lt;br /&gt;
  /etc/init.d/postgresql setup&lt;br /&gt;
  /etc/init.d/postgresql start&lt;br /&gt;
  rc-update add postgresql&lt;br /&gt;
&lt;br /&gt;
At this point any user can connect to the sql server with &amp;quot;trust&amp;quot; mechanism.  If you want to enforce password authentication (you probably do) edit /var/lib/postgresql/8.4/data/pg_hba.conf&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
  Editme: What should we recommend?&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Create the postfix database:&lt;br /&gt;
&lt;br /&gt;
  psql -U postgres&lt;br /&gt;
   create user postfix with password &#039;******&#039;;&lt;br /&gt;
   create database postfix owner postfix;&lt;br /&gt;
   \c postfix&lt;br /&gt;
   create language plpgsql;&lt;br /&gt;
   \q&lt;br /&gt;
&lt;br /&gt;
(Of course, use your selected password where ******* is shown above.)&lt;br /&gt;
&lt;br /&gt;
== Install PostfixAdmin ==&lt;br /&gt;
&lt;br /&gt;
We are going to install the postfix admin web front-end before we install the mail server.  This just creates an interface to populate the SQL tables that postfix and dovecot will use.&lt;br /&gt;
&lt;br /&gt;
Download PostfixAdmin from Sourceforge.  When these instructions were written, 2.3 was the current release, so (replace host.example.com with the actual domain):&lt;br /&gt;
 wget http://downloads.sourceforge.net/project/postfixadmin/postfixadmin/postfixadmin_2.3.tar.gz&lt;br /&gt;
 tar zxvf postfixadmin_2.3.tar.gz&lt;br /&gt;
 mkdir -p /var/www/domains/host.example.com/www/postfixadmin&lt;br /&gt;
 mv postfixadmin-2.3/* /var/www/domains/host.example.com/www/postfixadmin&lt;br /&gt;
 rm -rf postfixadmin*&lt;br /&gt;
&lt;br /&gt;
Edit /var/www/domains/host.example.com/www/postfixadmin/config.inc.php and modify at least these lines (replace host.example.com with the actual domain):&lt;br /&gt;
&lt;br /&gt;
 $CONF[&#039;configured&#039;] = true;&lt;br /&gt;
 $CONF[&#039;setup_password&#039;] = &amp;quot;&amp;quot;;  &amp;lt;&amp;lt; Don&#039;t change this yet&lt;br /&gt;
 $CONF[&#039;database_type&#039;] = &#039;pgsql&#039;;&lt;br /&gt;
 $CONF[&#039;database_host&#039;] = &#039;localhost&#039;;&lt;br /&gt;
 $CONF[&#039;database_user&#039;] = &#039;postfix&#039;;&lt;br /&gt;
 $CONF[&#039;database_password&#039;] = &#039;*****&#039;;   &amp;lt;&amp;lt; The password you chose above&lt;br /&gt;
 $CONF[&#039;database_name&#039;] = &#039;postfix&#039;;&lt;br /&gt;
 $CONF[&#039;database_prefix&#039;] = &amp;quot;&amp;quot;;&lt;br /&gt;
 $CONF[&#039;admin_email&#039;] = &#039;you@some.email.com&#039;;  &amp;lt;&amp;lt; Your email address &lt;br /&gt;
 $CONF[&#039;encrypt&#039;] = &#039;md5crypt&#039;;&lt;br /&gt;
 $CONF[&#039;authlib_default_flavor&#039;] = &#039;md5raw&#039;;&lt;br /&gt;
 $CONF[&#039;dovecotpw&#039;] = &amp;quot;/usr/sbin/dovecotpw&amp;quot;;&lt;br /&gt;
 $CONF[&#039;domain_path&#039;] = &#039;YES&#039;;&lt;br /&gt;
 $CONF[&#039;domain_in_mailbox&#039;] = &#039;NO&#039;;&lt;br /&gt;
 $CONF[&#039;aliases&#039;] = &#039;10&#039;;                       &lt;br /&gt;
 $CONF[&#039;mailboxes&#039;] = &#039;10&#039;;&lt;br /&gt;
 $CONF[&#039;maxquota&#039;] = &#039;10&#039;;&lt;br /&gt;
 $CONF[&#039;quota&#039;] = &#039;YES&#039;;&lt;br /&gt;
 $CONF[&#039;quota_multiplier&#039;] = &#039;1024000&#039;;&lt;br /&gt;
 $CONF[&#039;vacation&#039;] = &#039;NO&#039;; &lt;br /&gt;
 $CONF[&#039;vacation_control&#039;] =&#039;NO&#039;;&lt;br /&gt;
 $CONF[&#039;vacation_control_admin&#039;] = &#039;NO&#039;;&lt;br /&gt;
 $CONF[&#039;alias_control&#039;] = &#039;YES&#039;;&lt;br /&gt;
 $CONF[&#039;alias_control_admin&#039;] = &#039;YES&#039;;&lt;br /&gt;
 $CONF[&#039;special_alias_control&#039;] = &#039;YES&#039;;&lt;br /&gt;
 $CONF[&#039;fetchmail&#039;] = &#039;NO&#039;;&lt;br /&gt;
 $CONF[&#039;user_footer_link&#039;] = &amp;quot;http://host.example.com/postfixadmin&amp;quot;;&lt;br /&gt;
 $CONF[&#039;footer_link&#039;] = &#039;http://host.example.com/postfixadmin/main.php&#039;;&lt;br /&gt;
 $CONF[&#039;create_mailbox_subdirs_prefix&#039;]=&amp;quot;&amp;quot;;  &lt;br /&gt;
 $CONF[&#039;used_quotas&#039;] = &#039;YES&#039;;   &lt;br /&gt;
 $CONF[&#039;new_quota_table&#039;] = &#039;YES&#039;;  &lt;br /&gt;
&lt;br /&gt;
You should further edit /var/www/domains/host.example.com/www/postfixadmin/config.inc.php and replace all instances of &amp;quot;change-this-to-your.domain.tld&amp;quot; with your actual mail domain. This can be done with busybox sed (replace example.com with your domain name):&lt;br /&gt;
&lt;br /&gt;
 sed -i -e &#039;s/change-this-to-your.domain.tld/example.com/g&#039; /var/www/domains/host.example.com/www/postfixadmin/config.inc.php&lt;br /&gt;
&lt;br /&gt;
Go to http://host.example.com/postfixadmin/setup.php&lt;br /&gt;
&lt;br /&gt;
Create the password hash, add it to the config.inc.php file&lt;br /&gt;
&lt;br /&gt;
Go back to http://host.example.com/postfixadmin/setup.php&lt;br /&gt;
&lt;br /&gt;
Create superadmin account.&lt;br /&gt;
&lt;br /&gt;
== Install Postfix ==&lt;br /&gt;
&lt;br /&gt;
Create a user for the virtual mail delivery, and get its uid/gid (you&#039;ll need the numeric uid/gid for postfix)&lt;br /&gt;
&lt;br /&gt;
 adduser vmail -H -D -s /bin/false&lt;br /&gt;
 grep vmail /etc/passwd&lt;br /&gt;
&lt;br /&gt;
(In examples below, we use 1006/1006 for the uid/gid)&lt;br /&gt;
&lt;br /&gt;
Create the mail directory, and assign vmail as the owner&lt;br /&gt;
 mkdir -p /var/mail/domains&lt;br /&gt;
 chown -R vmail:vmail /var/mail/domains&lt;br /&gt;
 &lt;br /&gt;
&lt;br /&gt;
Install postfix&lt;br /&gt;
&lt;br /&gt;
 apk add acf-postfix postfix-pgsql&lt;br /&gt;
&lt;br /&gt;
Edit the /etc/postfix/main.cf file. Here&#039;s an example (don&#039;t forget to replace the uid/gid):&lt;br /&gt;
&lt;br /&gt;
 myhostname=host.example.com&lt;br /&gt;
 mydomain=example.com&lt;br /&gt;
 &lt;br /&gt;
 mydestination = localhost.$mydomain, localhost&lt;br /&gt;
 mynetworks_style = subnet&lt;br /&gt;
 mynetworks = 127.0.0.0/8&lt;br /&gt;
 &lt;br /&gt;
 virtual_mailbox_domains = proxy:pgsql:/etc/postfix/sql/pgsql_virtual_domains_maps.cf&lt;br /&gt;
 virtual_alias_maps = proxy:pgsql:/etc/postfix/sql/pgsql_virtual_alias_maps.cf,&lt;br /&gt;
        proxy:pgsql:/etc/postfix/sql/pgsql_virtual_alias_domain_maps.cf,&lt;br /&gt;
        proxy:pgsql:/etc/postfix/sql/pgsql_virtual_alias_domain_catchall_maps.cf&lt;br /&gt;
 &lt;br /&gt;
 virtual_mailbox_maps = proxy:pgsql:/etc/postfix/sql/pgsql_virtual_mailbox_maps.cf,&lt;br /&gt;
        proxy:pgsql:/etc/postfix/sql/pgsql_virtual_alias_domain_mailbox_maps.cf&lt;br /&gt;
 &lt;br /&gt;
 virtual_mailbox_base = /var/mail/domains/&lt;br /&gt;
 virtual_gid_maps = static:1006&lt;br /&gt;
 virtual_uid_maps = static:1006&lt;br /&gt;
 virtual_minimum_uid = 100&lt;br /&gt;
 virtual_transport = virtual&lt;br /&gt;
 &lt;br /&gt;
 &lt;br /&gt;
 # This next command means you must create a virtual&lt;br /&gt;
 # domain for the host itself - ALL mail goes through&lt;br /&gt;
 # The virtual transport&lt;br /&gt;
 &lt;br /&gt;
 mailbox_transport = virtual&lt;br /&gt;
 local_transport = virtual&lt;br /&gt;
 local_transport_maps = $virtual_mailbox_maps&lt;br /&gt;
 &lt;br /&gt;
 smtpd_helo_required = yes&lt;br /&gt;
 disable_vrfy_command = yes&lt;br /&gt;
 message_size_limit = 10240000&lt;br /&gt;
 queue_minfree = 51200000&lt;br /&gt;
 &lt;br /&gt;
 smtpd_sender_restrictions =&lt;br /&gt;
        permit_mynetworks,&lt;br /&gt;
        reject_non_fqdn_sender,&lt;br /&gt;
        reject_unknown_sender_domain&lt;br /&gt;
 &lt;br /&gt;
 smtpd_recipient_restrictions =&lt;br /&gt;
        reject_non_fqdn_recipient,&lt;br /&gt;
        reject_unknown_recipient_domain,&lt;br /&gt;
        permit_mynetworks,&lt;br /&gt;
        permit_sasl_authenticated,&lt;br /&gt;
        reject_unauth_destination,&lt;br /&gt;
        reject_rbl_client dnsbl.sorbs.net,&lt;br /&gt;
        reject_rbl_client zen.spamhaus.org,&lt;br /&gt;
        reject_rbl_client bl.spamcop.net&lt;br /&gt;
 &lt;br /&gt;
 smtpd_data_restrictions = reject_unauth_pipelining&lt;br /&gt;
 &lt;br /&gt;
 # we will use this later - This prevents cleartext authentication&lt;br /&gt;
 # for relaying&lt;br /&gt;
 smtpd_tls_auth_only = yes&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Now we need to create a *bunch* of files so that postfix can get the delivery information out of sql. Here&#039;s a shell script to create the scripts.  Change PGPW to the password for the postfix user of the postfix SQL database.&lt;br /&gt;
&lt;br /&gt;
 cd /etc/postfix&lt;br /&gt;
 mkdir sql&lt;br /&gt;
 PGPW=&amp;quot;ChangeMe&amp;quot;&lt;br /&gt;
 &lt;br /&gt;
 cat - &amp;lt;&amp;lt;EOF &amp;gt;sql/pgsql_virtual_alias_domain_catchall_maps.cf&lt;br /&gt;
 user=postfix&lt;br /&gt;
 password = $PGPW&lt;br /&gt;
 hosts = localhost&lt;br /&gt;
 dbname = postfix&lt;br /&gt;
 query = Select goto From alias,alias_domain where alias_domain.alias_domain = &#039;%d&#039; and alias.address = &#039;@&#039; ||  alias_domain.target_domain and alias.active = true and alias_domain.active= true &lt;br /&gt;
 EOF&lt;br /&gt;
 &lt;br /&gt;
 cat - &amp;lt;&amp;lt;EOF &amp;gt;sql/pgsql_virtual_alias_domain_mailbox_maps.cf&lt;br /&gt;
 user=postfix&lt;br /&gt;
 password = $PGPW&lt;br /&gt;
 hosts = localhost&lt;br /&gt;
 dbname = postfix&lt;br /&gt;
 query = Select maildir from mailbox,alias_domain where alias_domain.alias_domain = &#039;%d&#039; and mailbox.username = &#039;%u&#039; || &#039;@&#039; || alias_domain.target_domain and mailbox.active = true and alias_domain.active&lt;br /&gt;
 EOF&lt;br /&gt;
 &lt;br /&gt;
 cat - &amp;lt;&amp;lt;EOF &amp;gt;sql/pgsql_virtual_alias_domain_maps.cf&lt;br /&gt;
 user=postfix&lt;br /&gt;
 password = $PGPW&lt;br /&gt;
 hosts = localhost&lt;br /&gt;
 dbname = postfix&lt;br /&gt;
 query = select goto from alias,alias_domain where alias_domain.alias_domain=&#039;%d&#039; and alias.address = &#039;%u&#039; || &#039;@&#039; || alias_domain.target_domain and alias.active= true and alias_domain.active= true&lt;br /&gt;
 EOF&lt;br /&gt;
 &lt;br /&gt;
 cat - &amp;lt;&amp;lt;EOF &amp;gt;sql/pgsql_virtual_alias_maps.cf&lt;br /&gt;
 user=postfix&lt;br /&gt;
 password = $PGPW&lt;br /&gt;
 hosts = localhost&lt;br /&gt;
 dbname = postfix&lt;br /&gt;
 query = Select goto From alias Where address=&#039;%s&#039; and active =&#039;1&#039;&lt;br /&gt;
 EOF&lt;br /&gt;
 &lt;br /&gt;
 cat - &amp;lt;&amp;lt;EOF &amp;gt;sql/pgsql_virtual_domains_maps.cf&lt;br /&gt;
 user=postfix&lt;br /&gt;
 password = $PGPW&lt;br /&gt;
 hosts = localhost&lt;br /&gt;
 dbname = postfix&lt;br /&gt;
 query = Select domain from domain where domain=&#039;%s&#039; and active=&#039;1&#039;&lt;br /&gt;
 EOF&lt;br /&gt;
 &lt;br /&gt;
 cat - &amp;lt;&amp;lt;EOF &amp;gt;sql/pgsql_virtual_mailbox_maps.cf&lt;br /&gt;
 user=postfix&lt;br /&gt;
 password = $PGPW&lt;br /&gt;
 hosts = localhost&lt;br /&gt;
 dbname = postfix&lt;br /&gt;
 query = Select maildir from mailbox where username=&#039;%s&#039; and active=true&lt;br /&gt;
 EOF&lt;br /&gt;
 &lt;br /&gt;
 chown -R postfix:postfix sql&lt;br /&gt;
 chmod 640 sql/*&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
At this point you should be able to start up postfix&lt;br /&gt;
 &lt;br /&gt;
 newaliases  # so postfix is happy...&lt;br /&gt;
 /etc/init.d/postfix start&lt;br /&gt;
 rc-update add postfix&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Create a domain in PostfixAdmin and test ===&lt;br /&gt;
&lt;br /&gt;
Go to http://host.example.com/postfixadmin/&lt;br /&gt;
&lt;br /&gt;
Log in using the superadmin account, create a domain for the local box (e.g. example.com), and create a user mailbox (e.g. root).&lt;br /&gt;
&lt;br /&gt;
From the machine, send a test message:&lt;br /&gt;
&lt;br /&gt;
 sendmail -t root@example.com&lt;br /&gt;
 subject: test&lt;br /&gt;
 .&lt;br /&gt;
 ^d&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
In /var/log/mail.log (or /var/log/messages, if you still have busybox syslogd running) you should see the message queued.  The message should be in /var/mail/domains/example.com/root/new&lt;br /&gt;
&lt;br /&gt;
== Install Dovecot ==&lt;br /&gt;
&lt;br /&gt;
Dovecot is the POP3/IMAP server to retrieve mail.&lt;br /&gt;
&lt;br /&gt;
As before, we install dovecot: &lt;br /&gt;
&lt;br /&gt;
 apk add acf-dovecot dovecot-pgsql&lt;br /&gt;
&lt;br /&gt;
edit /etc/dovecot/dovecot.conf&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 # Select only the protocols you wish to support - all are listed in the next line&lt;br /&gt;
 protocols               =       imap imaps pop pop3s&lt;br /&gt;
 log_path                =       /var/log/dovecot.log&lt;br /&gt;
 info_log_path           =       /var/log/dovecot-info.log&lt;br /&gt;
 disable_plaintext_auth  =       no&lt;br /&gt;
&lt;br /&gt;
 # Authenticated IMAP&lt;br /&gt;
 ssl                     =       yes&lt;br /&gt;
 ssl_cert_file           =       /etc/lighttpd/server-bundle.pem&lt;br /&gt;
 ssl_key_file            =       /etc/lighttpd/server-bundle.pem&lt;br /&gt;
 auth_verbose            =       yes&lt;br /&gt;
 auth_debug              =       no&lt;br /&gt;
 mail_location           =       maildir:/var/mail/domains/%d/%n&lt;br /&gt;
 auth default    {&lt;br /&gt;
        mechanisms = plain&lt;br /&gt;
        passdb sql {&lt;br /&gt;
                args = /etc/dovecot/dovecot-sql.conf&lt;br /&gt;
                }&lt;br /&gt;
        userdb static {&lt;br /&gt;
                args =  uid=1006 gid=1006 home=/var/mail/domains/%d/%n&lt;br /&gt;
                }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Be sure to replace the uid and gid with the appropriate values for the vmail user.&lt;br /&gt;
&lt;br /&gt;
We need a certificate for SSL/TLS authentication, so in the example above, we use the lighttpd cert. That way when the cert is renewed/replaced, Dovecot will have access to the new cert as well.  &lt;br /&gt;
&lt;br /&gt;
Create the /etc/dovecot/dovecot-sql.conf file:&lt;br /&gt;
&lt;br /&gt;
 driver = pgsql&lt;br /&gt;
 connect = host=localhost dbname=postfix user=postfix password=********&lt;br /&gt;
 password_query = select username,password from mailbox where local_part = &#039;%n&#039; and domain = &#039;%d&#039;&lt;br /&gt;
 default_pass_scheme =  MD5-CRYPT&lt;br /&gt;
&lt;br /&gt;
Again, change the password above to your postfix user password, and protect the file from prying eyes:&lt;br /&gt;
&lt;br /&gt;
 chown root:root /etc/dovecot/dovecot-sql.conf&lt;br /&gt;
 chmod 600 /etc/dovecot/dovecot-sql.conf&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Start dovecot&lt;br /&gt;
 /etc/init.d/dovecot start&lt;br /&gt;
 rc-update add dovecot&lt;br /&gt;
&lt;br /&gt;
== Testing ==&lt;br /&gt;
&lt;br /&gt;
Make sure your firewall allows in ports 25(SMTP) 110 (POP3), 995 (POP3S), 143(IMAP), 993(IMAPS), or whatever subset you support.  &lt;br /&gt;
 &lt;br /&gt;
At this point, you should be able to:&lt;br /&gt;
 * Create a new domain and add users with PostfixAdmin&lt;br /&gt;
 * Send mail to those users via SMTP to port 25&lt;br /&gt;
 * Retrieve mail using the user&#039;s full email and password (e.g. username: user@example.com  password: ChangeMe)&lt;br /&gt;
&lt;br /&gt;
== Value Add Features ==&lt;br /&gt;
&lt;br /&gt;
If you followed the guide above, you now have a functional mail server with many interconnected parts.  The features below assume that the server is already running as described above.  You should be able to add any or all of these features below to further enhance the mail service.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Virus Scanning ===&lt;br /&gt;
&lt;br /&gt;
This procedure uses clamav and the postfix content_filter mechanism to scan inbound and outbound email for viruses.  Infected emails are dropped.  Clean emails are tagged with a &amp;quot;scanned by clamav&amp;quot; header.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* Install clamav and clamsmtp:&lt;br /&gt;
 apk add acf-clamav clamsmtp&lt;br /&gt;
* Edit the /etc/clamav/clamd.conf file if desired (not necessary in most cases)&lt;br /&gt;
* Edit /etc/clamsmtpd.conf and verify the following lines&lt;br /&gt;
 OutAddress: 10026&lt;br /&gt;
 Listen: 127.0.0.1:10025                                               &lt;br /&gt;
 Header: X-Virus-Scanned: ClamAV using ClamSMTP&lt;br /&gt;
 Action: drop&lt;br /&gt;
 User: clamav                                                      &lt;br /&gt;
* Start the daemons&lt;br /&gt;
 rc-update add clamd&lt;br /&gt;
 rc-update add clamsmtpd&lt;br /&gt;
 /etc/init.d/clamd start&lt;br /&gt;
 /etc/init.d/clamsmtpd start&lt;br /&gt;
* Verify clamsmtp is listening on port 10025:&lt;br /&gt;
 netstat -anp | grep clamsmtp&lt;br /&gt;
* [http://memberwebs.com/stef/software/clamsmtp/postfix.html Following the clamsmtp instructions]&lt;br /&gt;
** edit /etc/postfix/main.cf and add:&lt;br /&gt;
 content_filter = scan:[127.0.0.1]:10025                                                      &lt;br /&gt;
** edit /etc/postfix/master.cf and add&lt;br /&gt;
 # AV scan filter (used by content_filter)&lt;br /&gt;
 scan      unix  -       -       n       -       16      smtp&lt;br /&gt;
         -o smtp_send_xforward_command=yes&lt;br /&gt;
         -o smtp_enforce_tls=no&lt;br /&gt;
 # For injecting mail back into postfix from the filter&lt;br /&gt;
 127.0.0.1:10026 inet  n -       n       -       16      smtpd&lt;br /&gt;
         -o content_filter=&lt;br /&gt;
         -o receive_override_options=no_unknown_recipient_checks,no_header_body_checks&lt;br /&gt;
         -o smtpd_helo_restrictions=&lt;br /&gt;
         -o smtpd_client_restrictions=&lt;br /&gt;
         -o smtpd_sender_restrictions=&lt;br /&gt;
         -o smtpd_recipient_restrictions=permit_mynetworks,reject&lt;br /&gt;
         -o mynetworks_style=host&lt;br /&gt;
         -o smtpd_authorized_xforward_hosts=127.0.0.0/8&lt;br /&gt;
* postfix reload&lt;br /&gt;
* Send and email into a local virtual domain - it should have the &#039;&#039;X-Virus-Scanned: ClamAV using ClamSMTP&#039;&#039; header.&lt;br /&gt;
&lt;br /&gt;
=== Relay for Authenticated Users ===&lt;br /&gt;
&lt;br /&gt;
As configured above, the mail server accepts email from the Internet, but it does not relay email.  If it is a perimeter exchanger for a protected network, then you can add the protected networks to the &#039;&#039;mynetworks&#039;&#039; configuration line in /etc/postfix/main.cf&lt;br /&gt;
&lt;br /&gt;
This configuration change allows &#039;&#039;remote&#039;&#039; users to authenticate against the mail server and relay through it.  The rules for relaying are:&lt;br /&gt;
* Only authenticated users can relay&lt;br /&gt;
* Authentication Credentials must be encrypted with TLS or SSL&lt;br /&gt;
* Allow Submission and SMTPS ports for relaying (many consumer networks block port 25 - SMTP by default)&lt;br /&gt;
The process uses the dovecot authentication mechanism (used with IMAPS) to authenticate users before they are allowed to relay through postfix.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* Edit /etc/dovecot/dovecot.conf and add:&lt;br /&gt;
 # this is for postfix SASL (authenticated users can relay through us)&lt;br /&gt;
 socket listen {&lt;br /&gt;
                client {&lt;br /&gt;
                        path    = /var/spool/postfix/private/dovecot-auth.sock&lt;br /&gt;
                        mode    = 0660&lt;br /&gt;
                        user    = postfix&lt;br /&gt;
                        group   = postfix&lt;br /&gt;
                        }&lt;br /&gt;
                }&lt;br /&gt;
        }&lt;br /&gt;
* Restart dovecot&lt;br /&gt;
 /etc/init.d/dovecot restart&lt;br /&gt;
* Edit /etc/postfix/main.cf and add:&lt;br /&gt;
 # TLS Stuff -- since we allow SASL with tls *only*, we have to set up TLS first                    &lt;br /&gt;
 &lt;br /&gt;
 smtpd_tls_cert_file = /etc/lighttpd/server-bundle.pem&lt;br /&gt;
 smtpd_tls_key_file = /etc/lighttpd/server-bundle.pem&lt;br /&gt;
 smtpd_tls_CAfile = /etc/lighttpd/ca-crt.pem&lt;br /&gt;
 # If tls_security_level is set to &amp;quot;encrypt&amp;quot;, then SMTP rejects &lt;br /&gt;
 # unencrypted email (e.g. normal mail) which is bad.&lt;br /&gt;
 # By setting it to &amp;quot;may&amp;quot; you get TLS encrypted mail from google, slashdot, and other &lt;br /&gt;
 # interesting places.  Check your logs to see who&lt;br /&gt;
 smtpd_tls_security_level = may&lt;br /&gt;
 # Log info about the negotiated encryption levels&lt;br /&gt;
 smtpd_tls_received_header = yes&lt;br /&gt;
 smtpd_tls_loglevel = 1&lt;br /&gt;
 &lt;br /&gt;
 # SASL - this allows senders to authenticiate themselves&lt;br /&gt;
 # This along with &amp;quot;permit_sasl_authenticated&amp;quot; in smtpd_recipient_restrictions allows relaying&lt;br /&gt;
 smtpd_sasl_type = dovecot&lt;br /&gt;
 smtpd_sasl_path = private/dovecot-auth.sock&lt;br /&gt;
 smtpd_sasl_auth_enable = yes&lt;br /&gt;
 smtpd_sasl_authenticated_header = yes&lt;br /&gt;
 smtpd_tls_auth_only = yes&lt;br /&gt;
* Edit /etc/postfix/master.cf and enable the submission and smtps transports.  They are probably already at the top of your  master.cf file, just commented out:&lt;br /&gt;
 submission inet n       -       n       -       -       smtpd&lt;br /&gt;
   -o smtpd_tls_security_level=encrypt&lt;br /&gt;
   -o smtpd_sasl_auth_enable=yes&lt;br /&gt;
   -o smtpd_client_restrictions=permit_sasl_authenticated,reject&lt;br /&gt;
   -o milter_macro_daemon_name=ORIGINATING&lt;br /&gt;
 smtps     inet  n       -       n       -       -       smtpd&lt;br /&gt;
   -o smtpd_tls_security_level=encrypt&lt;br /&gt;
   -o smtpd_tls_wrappermode=yes&lt;br /&gt;
   -o smtpd_sasl_auth_enable=yes&lt;br /&gt;
   -o smtpd_client_restrictions=permit_sasl_authenticated,reject&lt;br /&gt;
   -o milter_macro_daemon_name=ORIGINATING&lt;br /&gt;
*Verfiy submission and smtps are defined in /etc/services&lt;br /&gt;
 grep &amp;quot;submission\|ssmtp&amp;quot; /etc/services&lt;br /&gt;
 submission	587/tcp				# mail message submission&lt;br /&gt;
 submission	587/udp&lt;br /&gt;
 smtps		465/tcp		ssmtp		# smtp protocol over TLS/SSL&lt;br /&gt;
 smtps		465/udp		ssmtp&lt;br /&gt;
* Restart postfix&lt;br /&gt;
 postfix reload&lt;br /&gt;
&lt;br /&gt;
At this point, you should be able to set up a mail client to relay through the server with TLS (port 587) or SSL (port 465)  Note that &amp;quot;plain&amp;quot; authentication is used because the underlying link is encrypted.  For example, in Thunderbird leave &amp;quot;secure authentication&amp;quot; unchecked, and choose STARTTLS (or TLS) for the connection security.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Mailbox Quotas ===&lt;br /&gt;
&lt;br /&gt;
In the default configuration, PostfixAdmin knows about quotas, but they are not enforced.   Documentation on the web mentions the [http://vda.sourceforge.net vda patch to postfix] to enforce quotas.  The only bad thing... its a &#039;&#039;patch&#039;&#039;.   Postfix and Dovecot are both conservative systems, so if the patch isn&#039;t in the upstream source, we&#039;ll assume there&#039;s a good reason.   There is a way of using quotas without patches - and it involves using dovecot&#039;s [http://wiki.dovecot.org/LDA deliver] lda for local delivery.&lt;br /&gt;
&lt;br /&gt;
Note: As of Jan 2010, the documention is confusing, with multiple versions of dovecot, PostfixAdmin, and Mysql referenced.  These instructions apply to:&lt;br /&gt;
* Postgresql 8.4.2 &lt;br /&gt;
* PostfixAdmin 2.3 &lt;br /&gt;
* Dovecot 1.2.11&lt;br /&gt;
* Postfix 2.6.5&lt;br /&gt;
&lt;br /&gt;
Presumably later versions will work the same, but if not, please update the documentation and versions above.&lt;br /&gt;
&lt;br /&gt;
* Update /etc/dovecot/dovecot.conf (old lines shown commented out):&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
# old postfix &lt;br /&gt;
#       userdb static {&lt;br /&gt;
#               args =  uid=1006 gid=1006 home=/var/mail/domains/%d/%n&lt;br /&gt;
#               }&lt;br /&gt;
&lt;br /&gt;
# new quota support:&lt;br /&gt;
        userdb prefetch {&lt;br /&gt;
                }&lt;br /&gt;
&lt;br /&gt;
        userdb sql {&lt;br /&gt;
                args = /etc/dovecot/dovecot-sql.conf&lt;br /&gt;
                }&lt;br /&gt;
&lt;br /&gt;
        socket listen {&lt;br /&gt;
                client {&lt;br /&gt;
                        path    = /var/spool/postfix/private/dovecot-auth.sock&lt;br /&gt;
                        mode    = 0660&lt;br /&gt;
                        user    = postfix&lt;br /&gt;
                        group   = postfix&lt;br /&gt;
                        }&lt;br /&gt;
                # These lines below are for the deliver lda&lt;br /&gt;
                master {&lt;br /&gt;
                        path =  /var/run/dovecot/auth-master&lt;br /&gt;
                        mode    = 0660&lt;br /&gt;
                        user    = vmail&lt;br /&gt;
                        group   = vmail&lt;br /&gt;
                        }&lt;br /&gt;
                }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
protocol imap {                                                               &lt;br /&gt;
         mail_plugins = quota imap_quota                                       &lt;br /&gt;
         }                                                                     &lt;br /&gt;
                                                                              &lt;br /&gt;
protocol pop3 {                                                               &lt;br /&gt;
         mail_plugins = quota                                                  &lt;br /&gt;
         }                                                                     &lt;br /&gt;
                                                                              &lt;br /&gt;
dict {                                                                        &lt;br /&gt;
        quotadict = pgsql:/etc/dovecot/dovecot-dict-quota.conf                &lt;br /&gt;
        }                                                                     &lt;br /&gt;
                                                                              &lt;br /&gt;
plugin {                                                                      &lt;br /&gt;
         quota = dict:user::proxy::quotadict                                   &lt;br /&gt;
         }                                                     &lt;br /&gt;
                                                              &lt;br /&gt;
protocol lda {                                                &lt;br /&gt;
   postmaster_address = postmaster@host.example.com&lt;br /&gt;
   mail_plugins = quota                                        &lt;br /&gt;
   auth_socket_path =  /var/run/dovecot/auth-master&lt;br /&gt;
   sendmail_path = /usr/sbin/sendmail&lt;br /&gt;
}                                                                            &lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
 &lt;br /&gt;
You should already have a &amp;lt;tt&amp;gt;socket-&amp;gt; listen-&amp;gt; client&amp;lt;/tt&amp;gt; section, but it is listed above to show where it goes in relationship to the &amp;lt;tt&amp;gt;socket -&amp;gt; listen -&amp;gt; master&amp;lt;/tt&amp;gt; section&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* edit &amp;lt;tt&amp;gt;/etc/dovecot/dovecot-sql.conf&amp;lt;/tt&amp;gt; and replace the user and password queries with the following (you may not have a user_query yet - add it):&lt;br /&gt;
&lt;br /&gt;
 password_query = select username as user, password, 1006 as userdb_uid, 1006 as userdb_gid, &#039;*:bytes=&#039; || quota as userdb_quota_rule from mailbox  where local_part = &#039;%n&#039; and domain = &#039;%d&#039;&lt;br /&gt;
 user_query = select &#039;/var/mail/domains/&#039; as home, 1006 as uid, 1006 as gid, &#039;*:bytes=&#039; || quota  as quota_rule from mailbox where local_part = &#039;%n&#039; and domain =&#039;%d&#039;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* create &amp;lt;tt&amp;gt;/etc/dovecot/dovecot-dict-quota.conf&amp;lt;/tt&amp;gt;&lt;br /&gt;
 connect = host=localhost dbname=postfix user=postfix password=********&lt;br /&gt;
 &lt;br /&gt;
 map {&lt;br /&gt;
         pattern = priv/quota/storage&lt;br /&gt;
         table = quota2&lt;br /&gt;
         username_field =username&lt;br /&gt;
         value_field = bytes&lt;br /&gt;
 }&lt;br /&gt;
 &lt;br /&gt;
 map {&lt;br /&gt;
        pattern= priv/quota/messages&lt;br /&gt;
        table = quota2&lt;br /&gt;
        username_field = username&lt;br /&gt;
        value_field = messages&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
Side note: [http://wiki.dovecot.org/Quota/Dict The Dovecot Quota Documentation] mentions the need for a trigger with pgsql.  This was created in the PostfixAdmin install, which is why you instantiated the pgsql language when creating the database.  If not, you will need to create the trigger, to reference the quota2 table, not the quota table mentioned in the dovecot docs.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* create a new transport for the dovecot lda.   Add the following to  /etc/postfix/master.cf:&lt;br /&gt;
 # The dovecot deliver lda&lt;br /&gt;
 dovecot   unix  -       n       n       -       -       pipe&lt;br /&gt;
   flags=DRhu user=vmail:vmail argv=/usr/libexec/dovecot/deliver -f ${sender} -d ${user}@${nexthop}&lt;br /&gt;
&lt;br /&gt;
* Edit the /etc/postfix/main.cf.  Replace &lt;br /&gt;
 virtual_transport = virtual &lt;br /&gt;
with&lt;br /&gt;
 virtual_transport = dovecot&lt;br /&gt;
 dovecot_destination_recipient_limit = 1&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;TODO&#039;&#039;&#039;  This will cause over-quota emails to bounce.   Which could be a source of backscatter.   We need a way of checking quota limits after RBL checking but before the message is accepted in the queue.&lt;br /&gt;
&lt;br /&gt;
=== WebMail (RoundCube) ===&lt;br /&gt;
&lt;br /&gt;
[http://roundcube.net/ RoundCube] is an &amp;quot;ajax /Web2.0&amp;quot; web-mail client.  These instructions are for the Alpine Linux 1.10 repository &lt;br /&gt;
&lt;br /&gt;
* Add the package and related php modules:&lt;br /&gt;
 apk add roundcubemail php-xml php-openssl php-mcrypt php-gd php-iconv&lt;br /&gt;
&lt;br /&gt;
* link the roundcube application back into the docroot&lt;br /&gt;
 ln -s /usr/share/webapps/roundcube /var/www/domains/host.example.com/www/roundcube&lt;br /&gt;
&lt;br /&gt;
* follow the instructions in /usr/share/webapps/roundcube/INSTALL:&lt;br /&gt;
 cd /usr/share/webapps/roundcube&lt;br /&gt;
 chown -R lighttpd:lighttpd temp logs&lt;br /&gt;
 &lt;br /&gt;
 su postgres&lt;br /&gt;
 createuser roundcube&lt;br /&gt;
   Shall the new role be a superuser? (y/n) n&lt;br /&gt;
   Shall the new role be allowed to create databases? (y/n) n&lt;br /&gt;
   Shall the new role be allowed to create more new roles? (y/n) y&lt;br /&gt;
 createdb -O roundcube -E UNICODE -T template0 roundcubemail&lt;br /&gt;
 psql roundcubemail&lt;br /&gt;
   roundcubemail=# ALTER USER roundcube WITH PASSWORD &#039;the_new_password&#039;;&lt;br /&gt;
   roundcubemail=# \c - roundcube&lt;br /&gt;
   roundcubemail=&amp;gt; \i /usr/share/webapps/roundcube/SQL/postgres.initial.sql&lt;br /&gt;
   roundcubemail=&amp;gt; \q&lt;br /&gt;
 exit&lt;br /&gt;
&lt;br /&gt;
* edit /etc/php/php.ini and set date.timezone to your local timezone, or to UTC&lt;br /&gt;
&lt;br /&gt;
* restart lighttpd to verify the new php libraries are used&lt;br /&gt;
 /etc/init.d/lighttpd restart&lt;br /&gt;
&lt;br /&gt;
* Point your browser to http://host.example.com/roundcube/installer&lt;br /&gt;
* Start installation&lt;br /&gt;
&lt;br /&gt;
For the specific configuration parameters in the install step:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!Property&lt;br /&gt;
!Setting&lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;enable_spellcheck&#039;&#039; ||   disabled &lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;identities_level&#039;&#039; ||  one identity with possibility to edit all params but not email address &lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;log driver&#039;&#039; || syslog &lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;sylog_id&#039;&#039; || roundcube &lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;syslog_facility&#039;&#039; || mailsubsystem &lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;db_dnsw&#039;&#039; || pgsql properties, as described above &lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;imap_host&#039;&#039; || 127.0.0.1 &lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;auto_create_user&#039;&#039; || enabled &lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;smtp_server&#039;&#039; ||  127.0.0.1&lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;smtp_port&#039;&#039; ||  25&lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;smtp_user/smtp_pass&#039;&#039; ||  enable &#039;&#039;Use Current IMAP username and password for SMTP authentication&#039;&#039;&lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;smtp_log&#039;&#039; ||  enable (optional, but gives additional log record)&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
The other items can be left at default settings, or adjusted if desired.&lt;br /&gt;
&lt;br /&gt;
* Follow the instructions in step 3 of the install to copy the files to the server&lt;br /&gt;
* You should now be able to get to roundcube at http://host.example.com/roundcube&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
After its working, the INSTALL file recommends removing the install directory.   If you want to keep the installer around later, you can simply change the ownership and permissions.  So do &#039;&#039;&#039;one&#039;&#039;&#039; of the following:&lt;br /&gt;
 cd /usr/share/webapps/roundcube&lt;br /&gt;
 rm -rf LICENSE UPGRADING INSTALL README CHANGELOG  SQL installer&lt;br /&gt;
or&lt;br /&gt;
 cd /usr/share/webapps/roundcube&lt;br /&gt;
 chown -R root:root LICENSE UPGRADING INSTALL README CHANGELOG  SQL installer&lt;br /&gt;
 chmod -R 600 LICENSE UPGRADING INSTALL README CHANGELOG SQL &lt;br /&gt;
 chmod 700 SQL installer&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== OpenLDAP based Address Book ===&lt;br /&gt;
&lt;br /&gt;
This OpenLDAP configuration uses the SQL backend, which represents information stored in PostgreSQL as an LDAP subtree for Address Book functionality for email lookups, user authentication or even &lt;br /&gt;
replication account information between sites. This procedure uses some metainformation to translate LDAP queries to SQL queries, leaving relational schema untouched, which allows SQL and LDAP &lt;br /&gt;
applications to inter-operate without replication, and exchange data as needed. The SQL backend uses UnixODBC to connect to PostgresSQL. &lt;br /&gt;
&lt;br /&gt;
* Install OpenLDAP and ODBC&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
apk add openldap libldap openldap-back-sql php-ldap unixodbc psqlodbc ca-certificates&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Note&#039;&#039;&#039;: Perhaps some packages should be installed from &amp;quot;edge&amp;quot; repository&lt;br /&gt;
&lt;br /&gt;
* Update &amp;quot;postfix&amp;quot; database (it will add &#039;id&#039; columns to mailbox and domain tables, also will create tables and views to represent LDAP metainformation)&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Note&#039;&#039;&#039;: These instructions are for example domain example.com. So make sure you replaced all entries of &#039;example&#039; and &#039;com&#039; according to your domain name parts.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
cat - &amp;lt;&amp;lt;EOF | psql -U postgres postfix&lt;br /&gt;
ALTER TABLE domain ADD COLUMN id SERIAL; &lt;br /&gt;
ALTER TABLE mailbox ADD COLUMN id SERIAL; &lt;br /&gt;
&lt;br /&gt;
CREATE TABLE ldap_entry_objclasses (&lt;br /&gt;
    entry_id integer NOT NULL,&lt;br /&gt;
    oc_name character varying(64)&lt;br /&gt;
);&lt;br /&gt;
&lt;br /&gt;
CREATE TABLE ldap_oc_mappings (&lt;br /&gt;
    id integer SERIAL,&lt;br /&gt;
    name character varying(64) NOT NULL,&lt;br /&gt;
    keytbl character varying(64) NOT NULL,&lt;br /&gt;
    keycol character varying(64) NOT NULL,&lt;br /&gt;
    create_proc character varying(255),&lt;br /&gt;
    delete_proc character varying(255),&lt;br /&gt;
    expect_return integer NOT NULL,&lt;br /&gt;
    PRIMARY KEY(id)&lt;br /&gt;
);&lt;br /&gt;
&lt;br /&gt;
CREATE TABLE ldap_attr_mappings_test (&lt;br /&gt;
    id integer SERIAL,&lt;br /&gt;
    oc_map_id integer NOT NULL REFERENCES ldap_oc_mappings(id),&lt;br /&gt;
    name character varying(255) NOT NULL,&lt;br /&gt;
    sel_expr character varying(255) NOT NULL,&lt;br /&gt;
    sel_expr_u character varying(255),&lt;br /&gt;
    from_tbls character varying(255) NOT NULL,&lt;br /&gt;
    join_where character varying(255),&lt;br /&gt;
    add_proc character varying(255),&lt;br /&gt;
    delete_proc character varying(255),&lt;br /&gt;
    param_order integer NOT NULL,&lt;br /&gt;
    expect_return integer NOT NULL,&lt;br /&gt;
    PRIMARY KEY(id)&lt;br /&gt;
);&lt;br /&gt;
&lt;br /&gt;
CREATE VIEW ldap_dcs AS&lt;br /&gt;
    (SELECT (domain.id + 100000) AS id, &lt;br /&gt;
            (((&#039;dc=&#039;::text || split_part((domain.domain)::text, &#039;.&#039;::text, 1)) || &#039;,dc=&#039;::text) || &lt;br /&gt;
            CASE WHEN (split_part((domain.domain)::text, &#039;.&#039;::text, 2) = &#039;com&#039;::text) THEN split_part((domain.domain)::text, &#039;.&#039;::text, 2) &lt;br /&gt;
                 ELSE ((split_part((domain.domain)::text, &#039;.&#039;::text, 2) || &#039;,dc=&#039;::text) || split_part((domain.domain)::text, &#039;.&#039;::text, 3)) &lt;br /&gt;
            END) AS dn, &lt;br /&gt;
            1 AS oc_map_id, &lt;br /&gt;
            100000 AS parent, &lt;br /&gt;
            0 AS keyval, &lt;br /&gt;
            domain.domain&lt;br /&gt;
     FROM domain &lt;br /&gt;
     WHERE domain.domain &amp;lt;&amp;gt; &#039;ALL&#039; &lt;br /&gt;
      UNION &lt;br /&gt;
     SELECT 100000 AS id, &lt;br /&gt;
           &#039;dc=com&#039; AS dn, &lt;br /&gt;
           1 AS oc_map_id, &lt;br /&gt;
           0 AS parent, &lt;br /&gt;
           0 AS keyval, &lt;br /&gt;
           &#039;com&#039; AS domain);&lt;br /&gt;
&lt;br /&gt;
CREATE VIEW ldap_entries AS&lt;br /&gt;
    SELECT mailbox.id, &lt;br /&gt;
    (((((&#039;cn=&#039;::text || initcap(replace(split_part((mailbox.username)::text, &#039;@&#039;::text, 1), &#039;.&#039;::text, &#039; &#039;::text))) || &#039;,dc=&#039;::text) || &lt;br /&gt;
          split_part(split_part((mailbox.username)::text, &#039;@&#039;::text, 2), &#039;.&#039;::text, 1)) || &#039;,dc=&#039;::text) || &lt;br /&gt;
             CASE WHEN (split_part(split_part((mailbox.username)::text, &#039;@&#039;::text, 2), &#039;.&#039;::text, 2) = &#039;com&#039;::text) &lt;br /&gt;
                  THEN split_part(split_part((mailbox.username)::text, &#039;@&#039;::text, 2), &#039;.&#039;::text, 2) &lt;br /&gt;
                  ELSE ((split_part(split_part((mailbox.username)::text, &#039;@&#039;::text, 2), &#039;.&#039;::text, 2) || &#039;,dc=&#039;::text) || &lt;br /&gt;
                         split_part(split_part((mailbox.username)::text, &#039;@&#039;::text, 2), &#039;.&#039;::text, 3)) &lt;br /&gt;
             END) AS dn, &lt;br /&gt;
          1 AS oc_map_id, &lt;br /&gt;
          (SELECT ldap_dcs.id &lt;br /&gt;
           FROM ldap_dcs &lt;br /&gt;
           WHERE ((ldap_dcs.domain)::text = (mailbox.domain)::text)) AS parent, &lt;br /&gt;
           mailbox.id AS keyval &lt;br /&gt;
           FROM mailbox &lt;br /&gt;
           UNION &lt;br /&gt;
           SELECT ldap_dcs.id,  &lt;br /&gt;
                  ldap_dcs.dn, &lt;br /&gt;
                  ldap_dcs.oc_map_id, &lt;br /&gt;
                  ldap_dcs.parent, &lt;br /&gt;
                  ldap_dcs.keyval &lt;br /&gt;
           FROM ldap_dcs;&lt;br /&gt;
EOF&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* Fill out LDAP tables according to following example (make sure to separate values with TABs):&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
cat - &amp;lt;&amp;lt;EOF | psql -U postgres postfix&lt;br /&gt;
COPY ldap_attr_mappings (id, oc_map_id, name, sel_expr, sel_expr_u, from_tbls, join_where, add_proc, delete_proc, param_order, expect_return) FROM stdin;&lt;br /&gt;
1	1	displayName	mailbox.name	\N	mailbox	\N	\N	\N	3	0&lt;br /&gt;
2	1	mail	mailbox.username	\N	mailbox	\N	\N	\N	3	0&lt;br /&gt;
3	1	cn	mailbox.name	\N	mailbox	\N	\N	\N	3	0&lt;br /&gt;
4	1	userPassword	&#039;{CRYPT}&#039;||mailbox.password	\N	mailbox	\N	\N	\N	3	0&lt;br /&gt;
\.&lt;br /&gt;
&lt;br /&gt;
COPY ldap_oc_mappings (id, name, keytbl, keycol, create_proc, delete_proc, expect_return) FROM stdin;&lt;br /&gt;
1	exampleBox	mailbox	id	\N	\N	1&lt;br /&gt;
\.&lt;br /&gt;
EOF&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* Check that &amp;quot;ldap_dcs&amp;quot; view presens something like this:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
echo &#039;select * from ldap_dcs&#039; | psql -U postgres postfix&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
   id   |             dn              | oc_map_id | parent | keyval |       domain       &lt;br /&gt;
--------+-----------------------------+-----------+--------+--------+--------------------&lt;br /&gt;
 100000 | dc=com                      |         1 |      0 |      0 | com&lt;br /&gt;
 100001 | dc=example,dc=com           |         1 | 100000 |      0 | example.com&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* Check that &amp;quot;ldap_entries&amp;quot; view presens something like this:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
echo &#039;select * from ldap_entries&#039; | psql -U postgres postfix&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
   id   |                          dn                           | oc_map_id | parent | keyval &lt;br /&gt;
--------+-------------------------------------------------------+-----------+--------+--------&lt;br /&gt;
    1   | cn=address1,dc=example,dc=com                         |         1 | 100001 |    1&lt;br /&gt;
...&lt;br /&gt;
   123  | cn=address123,dc=example,dc=com                       |         1 | 100001 |    1&lt;br /&gt;
 100000 | dc=com                                                |         1 |      0 |    0&lt;br /&gt;
 100001 | dc=example,dc=com                                     |         1 | 100000 |    0&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* Configure ODBC parameters&lt;br /&gt;
&lt;br /&gt;
Edit /etc/odbc.ini:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
[PostgreSQL]&lt;br /&gt;
Description             = Connection to Postgres&lt;br /&gt;
Driver                  = PostgreSQL&lt;br /&gt;
Trace                   = Yes&lt;br /&gt;
TraceFile               = sql.log&lt;br /&gt;
Database                = postfix&lt;br /&gt;
Servername              = 127.0.0.1&lt;br /&gt;
UserName                =&lt;br /&gt;
Password                =&lt;br /&gt;
Port                    = 5432&lt;br /&gt;
Protocol                = 6.4&lt;br /&gt;
ReadOnly                = No&lt;br /&gt;
RowVersining            = No&lt;br /&gt;
ShowSystemTables        = No&lt;br /&gt;
ShowOidColumn           = No&lt;br /&gt;
FakeOidIndex            = No&lt;br /&gt;
ConnSettings            =&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Edit /etc/odbcinst.ini:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
[PostgreSQL]&lt;br /&gt;
Description     = PostgreSQL driver for Linux&lt;br /&gt;
Driver          = /usr/lib/psqlodbcw.so&lt;br /&gt;
Setup           = /usr/lib/libodbcpsqlS.so&lt;br /&gt;
FileUsage       = 1&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* Test ODBC connection&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
echo &amp;quot;select * from domain;&amp;quot; | isql PostgreSQL postgres&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* Provide permission to certificate for LDAP server&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
chown ldap /etc/lighttpd/server-bundle.pem&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* Edit LDAP schema&lt;br /&gt;
&lt;br /&gt;
Edit /etc/openldap/schema/example.com.schema:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
attributetype ( 0.9.2342.19200300.100.1.3&lt;br /&gt;
	NAME ( &#039;mail&#039; &#039;rfc822Mailbox&#039; )&lt;br /&gt;
	DESC &#039;RFC1274: RFC822 Mailbox&#039;&lt;br /&gt;
        EQUALITY caseIgnoreIA5Match&lt;br /&gt;
        SUBSTR caseIgnoreIA5SubstringsMatch&lt;br /&gt;
        SYNTAX 1.3.6.1.4.1.1466.115.121.1.26{256} )&lt;br /&gt;
&lt;br /&gt;
attributetype ( 2.16.840.1.113730.3.1.241&lt;br /&gt;
	NAME &#039;displayName&#039;&lt;br /&gt;
	DESC &#039;RFC2798: preferred name to be used when displaying entries&#039;&lt;br /&gt;
	EQUALITY caseIgnoreMatch&lt;br /&gt;
	SUBSTR caseIgnoreSubstringsMatch&lt;br /&gt;
	SYNTAX 1.3.6.1.4.1.1466.115.121.1.15&lt;br /&gt;
	SINGLE-VALUE )&lt;br /&gt;
&lt;br /&gt;
objectclass   ( 2.16.840.1.113730.3.2.2&lt;br /&gt;
        NAME &#039;exampleBox&#039;&lt;br /&gt;
	DESC &#039;example.com mailbox&#039;&lt;br /&gt;
	MUST ( displayName $ mail $ userPassword )&lt;br /&gt;
	)&lt;br /&gt;
&lt;br /&gt;
# RFC 1274 + RFC 2247&lt;br /&gt;
attributetype ( 0.9.2342.19200300.100.1.25&lt;br /&gt;
        NAME ( &#039;dc&#039; &#039;domainComponent&#039; )&lt;br /&gt;
        DESC &#039;RFC1274/2247: domain component&#039;&lt;br /&gt;
        EQUALITY caseIgnoreIA5Match&lt;br /&gt;
        SUBSTR caseIgnoreIA5SubstringsMatch&lt;br /&gt;
        SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 SINGLE-VALUE )&lt;br /&gt;
&lt;br /&gt;
attributetype ( 2.5.4.46 NAME &#039;dnQualifier&#039;&lt;br /&gt;
        DESC &#039;RFC2256: DN qualifier&#039;&lt;br /&gt;
        EQUALITY caseIgnoreMatch&lt;br /&gt;
        ORDERING caseIgnoreOrderingMatch&lt;br /&gt;
        SUBSTR caseIgnoreSubstringsMatch&lt;br /&gt;
        SYNTAX 1.3.6.1.4.1.1466.115.121.1.44 )&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* Configure LDAP server&lt;br /&gt;
&lt;br /&gt;
Edit /etc/openldap/slapd.conf:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
include         /etc/openldap/schema/example.com.schema&lt;br /&gt;
pidfile         /var/run/openldap/slapd.pid&lt;br /&gt;
argsfile        /var/run/openldap/slapd.args&lt;br /&gt;
&lt;br /&gt;
TLSCipherSuite HIGH&lt;br /&gt;
TLSCACertificateFile /etc/lighttpd/ca-crt.pem&lt;br /&gt;
TLSCertificateFile /etc/lighttpd/server-bundle.pem&lt;br /&gt;
TLSCertificateKeyFile /etc/lighttpd/server-bundle.pem&lt;br /&gt;
TLSVerifyClient never &lt;br /&gt;
&lt;br /&gt;
# This is needed for proper representation of MD5-CRYPT format stored in database&lt;br /&gt;
#  see more details in http://strugglers.net/~andy/blog/2010/01/23/openldap-and-md5crypt/&lt;br /&gt;
password-hash  {CRYPT}&lt;br /&gt;
password-crypt-salt-format &amp;quot;$1$%.8s&amp;quot;&lt;br /&gt;
&lt;br /&gt;
loglevel        stats&lt;br /&gt;
moduleload	/usr/lib/openldap/back_sql.so&lt;br /&gt;
sizelimit 3000&lt;br /&gt;
&lt;br /&gt;
database        sql&lt;br /&gt;
&lt;br /&gt;
dbname		PostgreSQL&lt;br /&gt;
dbuser		postfix&lt;br /&gt;
dbpasswd	*****&lt;br /&gt;
&lt;br /&gt;
suffix          &amp;quot;dc=example,dc=com&amp;quot;&lt;br /&gt;
rootdn          &amp;quot;cn=admin,dc=example,dc=com&amp;quot;&lt;br /&gt;
rootpw		{MD5}&amp;lt;Hashed password for root dn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
upper_func      &amp;quot;upper&amp;quot;&lt;br /&gt;
strcast_func    &amp;quot;text&amp;quot;&lt;br /&gt;
concat_pattern  &amp;quot;?||?&amp;quot;&lt;br /&gt;
has_ldapinfo_dn_ru      no&lt;br /&gt;
lastmod         off&lt;br /&gt;
&lt;br /&gt;
access to attrs=userPassword by * auth&lt;br /&gt;
&lt;br /&gt;
access to * by peername.ip=127.0.0.1 read&lt;br /&gt;
            ### by peername.ip=&amp;lt;IP&amp;gt;%&amp;lt;netmask&amp;gt; read&lt;br /&gt;
            ### by peername.ip=&amp;lt;IP&amp;gt; read&lt;br /&gt;
	    by users read&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* Set permissions for slapd.conf&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
chown ldap:ldap /etc/openldap/slapd.conf&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* Configure startup parameters to make sure that LDAP server start AFTER PostgreSQL and listens on localhost with clear text and public IP with SSL&lt;br /&gt;
&lt;br /&gt;
Edit /etc/conf.d/slapd:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
echo rc_need=&amp;quot;postgresql&amp;quot; &lt;br /&gt;
OPTS=&amp;quot;-h &#039;ldaps:// ldap://127.0.0.1&#039;&amp;quot;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* Start LDAP server&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
rc-update add slapd default&lt;br /&gt;
/etc/init.d/slapd start&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* Configure LDAP client utilities&lt;br /&gt;
&lt;br /&gt;
Edit /etc/openldap/ldap.conf&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
BASE	dc=example,dc=com&lt;br /&gt;
URI	ldaps://host.example.com&lt;br /&gt;
&lt;br /&gt;
TLS_CACERT /etc/lighttpd/ca-crt.pem&lt;br /&gt;
TLS_CERT /etc/lighttpd/server-bundle.pem&lt;br /&gt;
TLS_KEY /etc/lighttpd/server-bundle.pem&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* Test LDAP server&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
ldapsearch -z 3&lt;br /&gt;
ldapsearch -z 3 -x -W -D cn=admin,dc=example,dc=com&lt;br /&gt;
ldapsearch -z 3 -x -W -D cn=address1,dc=example,dc=com&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* Configure RoundCube webmail for email lookups&lt;br /&gt;
&lt;br /&gt;
Edit /usr/share/webapps/roundcube/config/main.inc.php:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
$rcmail_config[&#039;ldap_debug&#039;] = false;&lt;br /&gt;
...&lt;br /&gt;
$rcmail_config[&#039;address_book_type&#039;] = &#039;ldap&#039;;&lt;br /&gt;
&lt;br /&gt;
$rcmail_config[&#039;ldap_public&#039;][&#039;example.com&#039;] = array(&lt;br /&gt;
  &#039;name&#039;          =&amp;gt; &#039;example.com&#039;,&lt;br /&gt;
  &#039;hosts&#039;         =&amp;gt; array(&#039;127.0.0.1&#039;),&lt;br /&gt;
  &#039;port&#039;          =&amp;gt; 389,&lt;br /&gt;
  &#039;use_tls&#039;         =&amp;gt; false,&lt;br /&gt;
  &#039;user_specific&#039; =&amp;gt; false,&lt;br /&gt;
  &#039;base_dn&#039;       =&amp;gt; &#039;dc=example,dc=com&#039;,&lt;br /&gt;
  &#039;bind_dn&#039;       =&amp;gt; &#039;&#039;,&lt;br /&gt;
  &#039;bind_pass&#039;     =&amp;gt; &#039;&#039;,&lt;br /&gt;
  &#039;writable&#039;      =&amp;gt; false,&lt;br /&gt;
  &#039;LDAP_Object_Classes&#039; =&amp;gt; array(&amp;quot;top&amp;quot;, &amp;quot;exampleBox&amp;quot;),&lt;br /&gt;
  &#039;required_fields&#039;     =&amp;gt; array(&amp;quot;cn&amp;quot;, &amp;quot;sn&amp;quot;, &amp;quot;mail&amp;quot;),&lt;br /&gt;
  &#039;LDAP_rdn&#039;      =&amp;gt; &#039;mail&#039;,&lt;br /&gt;
  &#039;ldap_version&#039;  =&amp;gt; 3,&lt;br /&gt;
  &#039;search_fields&#039; =&amp;gt; array(&#039;mail&#039;, &#039;cn&#039;, &#039;sn&#039;, &#039;givenName&#039;),&lt;br /&gt;
  &#039;name_field&#039;    =&amp;gt; &#039;cn&#039;,&lt;br /&gt;
  &#039;email_field&#039;   =&amp;gt; &#039;mail&#039;,&lt;br /&gt;
  &#039;surname_field&#039; =&amp;gt; &#039;sn&#039;,&lt;br /&gt;
  &#039;firstname_field&#039; =&amp;gt; &#039;gn&#039;,&lt;br /&gt;
  &#039;sort&#039;          =&amp;gt; &#039;cn&#039;,&lt;br /&gt;
  &#039;scope&#039;         =&amp;gt; &#039;sub&#039;,&lt;br /&gt;
  &#039;filter&#039;        =&amp;gt; &#039;(objectClass=*)&#039;, // Construct here any filter you need&lt;br /&gt;
  &#039;fuzzy_search&#039;  =&amp;gt; true);&lt;br /&gt;
&lt;br /&gt;
$rcmail_config[&#039;autocomplete_addressbooks&#039;] = array(&#039;example.com&#039;);&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== log rotation ==&lt;br /&gt;
&lt;br /&gt;
Ensure the busybox cron service is started and is configured to auto-start:&lt;br /&gt;
&lt;br /&gt;
 /etc/init.d/cron start&lt;br /&gt;
 rc-update add cron default&lt;br /&gt;
&lt;br /&gt;
Add log rotate:&lt;br /&gt;
&lt;br /&gt;
 apk add logrotate&lt;br /&gt;
&lt;br /&gt;
Edit &#039;&#039;/etc/logrotate.conf&#039;&#039; as desired, but the defaults should be sufficient for most people.&lt;br /&gt;
&lt;br /&gt;
== Optional: Configure Web Server Virtual Domains ==&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Note:&#039;&#039;&#039; These steps can be done &#039;&#039;instead of&#039;&#039; the default lighttpd configuration above, which allows you to access the ACF, PostfixAdmin and Roundcube interfaces as subfolders of one web service.&lt;br /&gt;
&lt;br /&gt;
This server hosts three separate web applications, and these can be handled as three &#039;&#039;different&#039;&#039; virtual domains on the same web server. They will be distinguished by their DNS names, so you can choose domains for the three separate services (or at least the ones you want to publish):&lt;br /&gt;
&lt;br /&gt;
* ACF - Alpine Configuration Framework for managing the server&lt;br /&gt;
* PostfixAdmin - for managing the postfix installation&lt;br /&gt;
* RoundCube - for accessing individual mailboxes&lt;br /&gt;
&lt;br /&gt;
Choose three different domains (from here on known as ACF_DOMAIN, POSTFIXADMIN_DOMAIN, and ROUNDCUBE_DOMAIN) and configure DNS for all three to point to the IP address of your host. These should be DNS &#039;&#039;&#039;A&#039;&#039;&#039; records.&lt;br /&gt;
&lt;br /&gt;
Then, configure lighttpd to handle the three separate domains by editing /etc/lighttpd/lighttpd.conf:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 $HTTP[&amp;quot;host&amp;quot;] == &amp;quot;ACF_DOMAIN&amp;quot; {&lt;br /&gt;
	simple-vhost.server-root   = &amp;quot;/var/www/domains/&amp;quot;&lt;br /&gt;
	simple-vhost.default-host  = &amp;quot;/ACF_DOMAIN/&amp;quot;&lt;br /&gt;
	simple-vhost.document-root = &amp;quot;www/&amp;quot;&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
 $HTTP[&amp;quot;host&amp;quot;] == &amp;quot;POSTFIXADMIN_DOMAIN&amp;quot; {&lt;br /&gt;
	simple-vhost.server-root   = &amp;quot;/var/www/domains/&amp;quot;&lt;br /&gt;
	simple-vhost.default-host  = &amp;quot;/POSTFIXADMIN_DOMAIN/&amp;quot;&lt;br /&gt;
	simple-vhost.document-root = &amp;quot;www/&amp;quot;&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
 $HTTP[&amp;quot;host&amp;quot;] == &amp;quot;ROUNDCUBE_DOMAIN&amp;quot; {&lt;br /&gt;
	simple-vhost.server-root   = &amp;quot;/var/www/domains/&amp;quot;&lt;br /&gt;
	simple-vhost.default-host  = &amp;quot;/ROUNDCUBE_DOMAIN/&amp;quot;&lt;br /&gt;
	simple-vhost.document-root = &amp;quot;www/&amp;quot;&lt;br /&gt;
 }&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
And, then link the appropriate www directories.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  mkdir -p /var/www/domains/ACF_DOMAIN&lt;br /&gt;
  ln -s /usr/share/acf/www /var/www/domains/ACF_DOMAIN/www&lt;br /&gt;
&lt;br /&gt;
  mkdir -p /var/www/domains/POSTFIXADMIN_DOMAIN&lt;br /&gt;
  ln -s /var/www/domains/host.example.com/www/postfixadmin /var/www/domains/POSTFIXADMIN_DOMAIN/www&lt;br /&gt;
&lt;br /&gt;
  mkdir -p /var/www/domains/ROUNDCUBE_DOMAIN&lt;br /&gt;
  ln -s /usr/share/webapps/roundcube /var/www/domains/ROUNDCUBE_DOMAIN/www&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;/div&gt;</summary>
		<author><name>Djhughes</name></author>
	</entry>
	<entry>
		<id>https://wiki.alpinelinux.org/w/index.php?title=ISP_Mail_Server_HowTo&amp;diff=3498</id>
		<title>ISP Mail Server HowTo</title>
		<link rel="alternate" type="text/html" href="https://wiki.alpinelinux.org/w/index.php?title=ISP_Mail_Server_HowTo&amp;diff=3498"/>
		<updated>2010-03-18T13:59:26Z</updated>

		<summary type="html">&lt;p&gt;Djhughes: clarified optional DNS configuration&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== A Full Service Mail Server ==&lt;br /&gt;
&lt;br /&gt;
The goal of this document is to describe how to set up postfix, dovecot, clamav, dspam, roundecube, and postfixadmin for a full-featured &amp;quot;ISP&amp;quot; level mail server.&lt;br /&gt;
&lt;br /&gt;
The server must provide:&lt;br /&gt;
&lt;br /&gt;
* multiple virtual domains&lt;br /&gt;
* admins for each domain (to add/remove virtual accounts)&lt;br /&gt;
* Quota support per domain / account&lt;br /&gt;
* downloading email via IMAP / IMAPS / POP3 / POP3S&lt;br /&gt;
* relaying email for authenticated users with TLS or SSL (Submission / SMTPS protocol)&lt;br /&gt;
* Standard filters (virus/spam/rbl/etc)&lt;br /&gt;
* Web mail client&lt;br /&gt;
* Value Add services&lt;br /&gt;
&lt;br /&gt;
== Set up Lighttpd + PHP ==&lt;br /&gt;
&lt;br /&gt;
PostfixAdmin needs php pgpsql and imap modules, so we do it in this step.&lt;br /&gt;
&lt;br /&gt;
  apk add lighttpd php php-pgsql php-imap&lt;br /&gt;
&lt;br /&gt;
Stop and remove mini_httpd, and move ACF to lighttpd;  We are setting this up to be a multi-domain virtual web server (replace host.example.com with the actual domain):&lt;br /&gt;
&lt;br /&gt;
  mkdir -p /var/www/domains/host.example.com/www&lt;br /&gt;
  ln -s /usr/share/acf/www /var/www/domains/host.example.com/www/acf&lt;br /&gt;
&lt;br /&gt;
Edit /var/www/domains/host.example.com/index.html to put a simple redirection page:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;lt;!DOCTYPE HTML PUBLIC &amp;quot;-//W3C//DTD HTML 4.01//EN&amp;quot; &amp;quot;http://www.w3.org/TR/html4/strict.dtd&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;html lang=&amp;quot;en&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;head&amp;gt;&lt;br /&gt;
&amp;lt;meta http-equiv=&amp;quot;Content-Type&amp;quot; content=&amp;quot;text/html; charset=ISO-8859-1&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;title&amp;gt;host.example.com Redirector&amp;lt;/title&amp;gt;&lt;br /&gt;
&amp;lt;/head&amp;gt;&lt;br /&gt;
&amp;lt;body&amp;gt;&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;&amp;lt;a href=&amp;quot;/acf&amp;quot;&amp;gt;ACF&amp;lt;/a&amp;gt;&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;&amp;lt;a href=&amp;quot;/postfixadmin&amp;quot;&amp;gt;PostfixAdmin&amp;lt;/a&amp;gt;&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;&amp;lt;a href=&amp;quot;/roundcube&amp;quot;&amp;gt;Roundcube&amp;lt;/a&amp;gt;&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
&amp;lt;/body&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Edit /etc/lighttpd/mod_cgi.conf to serve haserl files by adding a &amp;quot;&amp;quot; =&amp;gt; &amp;quot;&amp;quot; cgi handler and to treat /acf/cgi-bin as a CGI directory (remove the &#039;^&#039;)&lt;br /&gt;
&lt;br /&gt;
 $HTTP[&amp;quot;url&amp;quot;] =~ &amp;quot;/cgi-bin/&amp;quot; {&lt;br /&gt;
     # disable directory listings&lt;br /&gt;
     dir-listing.activate = &amp;quot;disable&amp;quot;&lt;br /&gt;
     # only allow cgi&#039;s in this directory&lt;br /&gt;
     cgi.assign = (&lt;br /&gt;
 		&amp;quot;.pl&amp;quot;	=&amp;gt;	&amp;quot;/usr/bin/perl&amp;quot;,&lt;br /&gt;
 		&amp;quot;.cgi&amp;quot;	=&amp;gt;	&amp;quot;/usr/bin/perl&amp;quot;,&lt;br /&gt;
 		&amp;quot;&amp;quot; =&amp;gt; &amp;quot;&amp;quot;&lt;br /&gt;
 	)&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
Add these lines to /etc/lighttpd/lighttpd.conf to point to the new document root, and set it up to listen on port 443 (replace &#039;&#039;host.example.com&#039;&#039; with the actual domain and &#039;&#039;ip_address_of_server&#039;&#039; with the actual IP address):&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
simple-vhost.server-root   = &amp;quot;/var/www/domains/&amp;quot;&lt;br /&gt;
simple-vhost.default-host  = &amp;quot;/host.example.com/&amp;quot;&lt;br /&gt;
simple-vhost.document-root = &amp;quot;www/&amp;quot;&lt;br /&gt;
&lt;br /&gt;
$SERVER[&amp;quot;socket&amp;quot;] == &amp;quot;ip_address_of_server:443&amp;quot; {&lt;br /&gt;
ssl.engine    = &amp;quot;enable&amp;quot;&lt;br /&gt;
ssl.pemfile   = &amp;quot;/etc/lighttpd/server-bundle.pem&amp;quot;&lt;br /&gt;
ssl.ca-file   = &amp;quot;/etc/lighttpd/ca-crt.pem&amp;quot;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Ensure that the simple_vhosts module is loaded, as well as the cgi config scripts by uncommenting the following lines in /etc/lighttpd/lighttpd.conf&lt;br /&gt;
&lt;br /&gt;
 server.modules = (&lt;br /&gt;
     #  other modules may be listed&lt;br /&gt;
     &amp;quot;mod_simple_vhost&amp;quot;, &lt;br /&gt;
     #  other modules may be listed&lt;br /&gt;
  .&lt;br /&gt;
  .&lt;br /&gt;
  .&lt;br /&gt;
     include &amp;quot;mod_cgi.conf&amp;quot;&lt;br /&gt;
 &lt;br /&gt;
     include &amp;quot;mod_fastcgi.conf&amp;quot;&lt;br /&gt;
 &lt;br /&gt;
&lt;br /&gt;
Get a web certificate, and install it.  If you want to use a self-signed cert, you can use [[Generating SSL certs with ACF]] or [[Generating SSL certs with ACF 1.9]].  If you create a certificate with ACF, you can create the &amp;quot;server-bundle.pem&amp;quot; and the &amp;quot;ca-crt.pem&amp;quot; file with these commands:&lt;br /&gt;
&lt;br /&gt;
  openssl pkcs12 -nokeys -cacerts -in certificate.pfx  -out /etc/lighttpd/ca-crt.pem&lt;br /&gt;
  openssl pkcs12 -nodes -in certifcate.pfx -out /etc/lighttpd/server-bundle.pem&lt;br /&gt;
  chown root:root /etc/lighttpd/server-bundle.pem&lt;br /&gt;
  chmod 400 /etc/lighttpd/server-bundle.pem&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Note:&#039;&#039;&#039; The server certificate &#039;&#039;and&#039;&#039; key are in the server-bundle.pem file, so it is critical that the file be read-only by user &amp;quot;root&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
 Editme: We should probably only serve ACF to restricted hosts&lt;br /&gt;
&lt;br /&gt;
Stop and remove mini_httpd; start lighttpd, test&lt;br /&gt;
&lt;br /&gt;
  /etc/init.d/mini_httpd stop&lt;br /&gt;
  rc-update del mini_httpd&lt;br /&gt;
  apk del mini_httpd&lt;br /&gt;
  rc-update add lighttpd&lt;br /&gt;
  /etc/init.d/lighttpd start&lt;br /&gt;
&lt;br /&gt;
At this point you should be able to see ACF being served with lighttpd (Note: this will work well with alpine 1.10. With earlier versions there will be problems.)  https://host.example.com/acf/&lt;br /&gt;
&lt;br /&gt;
== Install Postgresql ==&lt;br /&gt;
&lt;br /&gt;
Add and configure postgresql&lt;br /&gt;
&lt;br /&gt;
  apk add acf-postgresql postgresql-client&lt;br /&gt;
  /etc/init.d/postgresql setup&lt;br /&gt;
  /etc/init.d/postgresql start&lt;br /&gt;
  rc-update add postgresql&lt;br /&gt;
&lt;br /&gt;
At this point any user can connect to the sql server with &amp;quot;trust&amp;quot; mechanism.  If you want to enforce password authentication (you probably do) edit /var/lib/postgresql/8.4/data/pg_hba.conf&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
  Editme: What should we recommend?&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Create the postfix database:&lt;br /&gt;
&lt;br /&gt;
  psql -U postgres&lt;br /&gt;
   create user postfix with password &#039;******&#039;;&lt;br /&gt;
   create database postfix owner postfix;&lt;br /&gt;
   \c postfix&lt;br /&gt;
   create language plpgsql;&lt;br /&gt;
   \q&lt;br /&gt;
&lt;br /&gt;
(Of course, use your selected password where ******* is shown above.)&lt;br /&gt;
&lt;br /&gt;
== Install PostfixAdmin ==&lt;br /&gt;
&lt;br /&gt;
We are going to install the postfix admin web front-end before we install the mail server.  This just creates an interface to populate the SQL tables that postfix and dovecot will use.&lt;br /&gt;
&lt;br /&gt;
Download PostfixAdmin from Sourceforge.  When these instructions were written, 2.3 was the current release, so (replace host.example.com with the actual domain):&lt;br /&gt;
 wget http://downloads.sourceforge.net/project/postfixadmin/postfixadmin/postfixadmin_2.3.tar.gz&lt;br /&gt;
 tar zxvf postfixadmin_2.3.tar.gz&lt;br /&gt;
 mkdir -p /var/www/domains/host.example.com/www/postfixadmin&lt;br /&gt;
 mv postfixadmin-2.3/* /var/www/domains/host.example.com/www/postfixadmin&lt;br /&gt;
 rm -rf postfixadmin*&lt;br /&gt;
&lt;br /&gt;
Edit /var/www/domains/host.example.com/www/postfixadmin/config.inc.php and modify at least these lines (replace host.example.com with the actual domain):&lt;br /&gt;
&lt;br /&gt;
 $CONF[&#039;configured&#039;] = true;&lt;br /&gt;
 $CONF[&#039;setup_password&#039;] = &amp;quot;&amp;quot;;  &amp;lt;&amp;lt; Don&#039;t change this yet&lt;br /&gt;
 $CONF[&#039;database_type&#039;] = &#039;pgsql&#039;;&lt;br /&gt;
 $CONF[&#039;database_host&#039;] = &#039;localhost&#039;;&lt;br /&gt;
 $CONF[&#039;database_user&#039;] = &#039;postfix&#039;;&lt;br /&gt;
 $CONF[&#039;database_password&#039;] = &#039;*****&#039;;   &amp;lt;&amp;lt; The password you chose above&lt;br /&gt;
 $CONF[&#039;database_name&#039;] = &#039;postfix&#039;;&lt;br /&gt;
 $CONF[&#039;database_prefix&#039;] = &amp;quot;&amp;quot;;&lt;br /&gt;
 $CONF[&#039;admin_email&#039;] = &#039;you@some.email.com&#039;;  &amp;lt;&amp;lt; Your email address &lt;br /&gt;
 $CONF[&#039;encrypt&#039;] = &#039;md5crypt&#039;;&lt;br /&gt;
 $CONF[&#039;authlib_default_flavor&#039;] = &#039;md5raw&#039;;&lt;br /&gt;
 $CONF[&#039;dovecotpw&#039;] = &amp;quot;/usr/sbin/dovecotpw&amp;quot;;&lt;br /&gt;
 $CONF[&#039;domain_path&#039;] = &#039;YES&#039;;&lt;br /&gt;
 $CONF[&#039;domain_in_mailbox&#039;] = &#039;NO&#039;;&lt;br /&gt;
 $CONF[&#039;aliases&#039;] = &#039;10&#039;;                       &lt;br /&gt;
 $CONF[&#039;mailboxes&#039;] = &#039;10&#039;;&lt;br /&gt;
 $CONF[&#039;maxquota&#039;] = &#039;10&#039;;&lt;br /&gt;
 $CONF[&#039;quota&#039;] = &#039;YES&#039;;&lt;br /&gt;
 $CONF[&#039;quota_multiplier&#039;] = &#039;1024000&#039;;&lt;br /&gt;
 $CONF[&#039;vacation&#039;] = &#039;NO&#039;; &lt;br /&gt;
 $CONF[&#039;vacation_control&#039;] =&#039;NO&#039;;&lt;br /&gt;
 $CONF[&#039;vacation_control_admin&#039;] = &#039;NO&#039;;&lt;br /&gt;
 $CONF[&#039;alias_control&#039;] = &#039;YES&#039;;&lt;br /&gt;
 $CONF[&#039;alias_control_admin&#039;] = &#039;YES&#039;;&lt;br /&gt;
 $CONF[&#039;special_alias_control&#039;] = &#039;YES&#039;;&lt;br /&gt;
 $CONF[&#039;fetchmail&#039;] = &#039;NO&#039;;&lt;br /&gt;
 $CONF[&#039;user_footer_link&#039;] = &amp;quot;http://host.example.com/postfixadmin&amp;quot;;&lt;br /&gt;
 $CONF[&#039;footer_link&#039;] = &#039;http://host.example.com/postfixadmin/main.php&#039;;&lt;br /&gt;
 $CONF[&#039;create_mailbox_subdirs_prefix&#039;]=&amp;quot;&amp;quot;;  &lt;br /&gt;
 $CONF[&#039;used_quotas&#039;] = &#039;YES&#039;;   &lt;br /&gt;
 $CONF[&#039;new_quota_table&#039;] = &#039;YES&#039;;  &lt;br /&gt;
&lt;br /&gt;
You should further edit /var/www/domains/host.example.com/www/postfixadmin/config.inc.php and replace all instances of &amp;quot;change-this-to-your.domain.tld&amp;quot; with your actual mail domain. This can be done with busybox sed (replace example.com with your domain name):&lt;br /&gt;
&lt;br /&gt;
 sed -i -e &#039;s/change-this-to-your.domain.tld/example.com/g&#039; /var/www/domains/host.example.com/www/postfixadmin/config.inc.php&lt;br /&gt;
&lt;br /&gt;
Go to http://host.example.com/postfixadmin/setup.php&lt;br /&gt;
&lt;br /&gt;
Create the password hash, add it to the config.inc.php file&lt;br /&gt;
&lt;br /&gt;
Go back to http://host.example.com/postfixadmin/setup.php&lt;br /&gt;
&lt;br /&gt;
Create superadmin account.&lt;br /&gt;
&lt;br /&gt;
== Install Postfix ==&lt;br /&gt;
&lt;br /&gt;
Create a user for the virtual mail delivery, and get its uid/gid (you&#039;ll need the numeric uid/gid for postfix)&lt;br /&gt;
&lt;br /&gt;
 adduser vmail -H -D -s /bin/false&lt;br /&gt;
 grep vmail /etc/passwd&lt;br /&gt;
&lt;br /&gt;
(In examples below, we use 1006/1006 for the uid/gid)&lt;br /&gt;
&lt;br /&gt;
Create the mail directory, and assign vmail as the owner&lt;br /&gt;
 mkdir -p /var/mail/domains&lt;br /&gt;
 chown -R vmail:vmail /var/mail/domains&lt;br /&gt;
 &lt;br /&gt;
&lt;br /&gt;
Install postfix&lt;br /&gt;
&lt;br /&gt;
 apk add acf-postfix postfix-pgsql&lt;br /&gt;
&lt;br /&gt;
Edit the /etc/postfix/main.cf file. Here&#039;s an example (don&#039;t forget to replace the uid/gid):&lt;br /&gt;
&lt;br /&gt;
 myhostname=host.example.com&lt;br /&gt;
 mydomain=example.com&lt;br /&gt;
 &lt;br /&gt;
 mydestination = localhost.$mydomain, localhost&lt;br /&gt;
 mynetworks_style = subnet&lt;br /&gt;
 mynetworks = 127.0.0.0/8&lt;br /&gt;
 &lt;br /&gt;
 virtual_mailbox_domains = proxy:pgsql:/etc/postfix/sql/pgsql_virtual_domains_maps.cf&lt;br /&gt;
 virtual_alias_maps = proxy:pgsql:/etc/postfix/sql/pgsql_virtual_alias_maps.cf,&lt;br /&gt;
        proxy:pgsql:/etc/postfix/sql/pgsql_virtual_alias_domain_maps.cf,&lt;br /&gt;
        proxy:pgsql:/etc/postfix/sql/pgsql_virtual_alias_domain_catchall_maps.cf&lt;br /&gt;
 &lt;br /&gt;
 virtual_mailbox_maps = proxy:pgsql:/etc/postfix/sql/pgsql_virtual_mailbox_maps.cf,&lt;br /&gt;
        proxy:pgsql:/etc/postfix/sql/pgsql_virtual_alias_domain_mailbox_maps.cf&lt;br /&gt;
 &lt;br /&gt;
 virtual_mailbox_base = /var/mail/domains/&lt;br /&gt;
 virtual_gid_maps = static:1006&lt;br /&gt;
 virtual_uid_maps = static:1006&lt;br /&gt;
 virtual_minimum_uid = 100&lt;br /&gt;
 virtual_transport = virtual&lt;br /&gt;
 &lt;br /&gt;
 &lt;br /&gt;
 # This next command means you must create a virtual&lt;br /&gt;
 # domain for the host itself - ALL mail goes through&lt;br /&gt;
 # The virtual transport&lt;br /&gt;
 &lt;br /&gt;
 mailbox_transport = virtual&lt;br /&gt;
 local_transport = virtual&lt;br /&gt;
 local_transport_maps = $virtual_mailbox_maps&lt;br /&gt;
 &lt;br /&gt;
 smtpd_helo_required = yes&lt;br /&gt;
 disable_vrfy_command = yes&lt;br /&gt;
 message_size_limit = 10240000&lt;br /&gt;
 queue_minfree = 51200000&lt;br /&gt;
 &lt;br /&gt;
 smtpd_sender_restrictions =&lt;br /&gt;
        permit_mynetworks,&lt;br /&gt;
        reject_non_fqdn_sender,&lt;br /&gt;
        reject_unknown_sender_domain&lt;br /&gt;
 &lt;br /&gt;
 smtpd_recipient_restrictions =&lt;br /&gt;
        reject_non_fqdn_recipient,&lt;br /&gt;
        reject_unknown_recipient_domain,&lt;br /&gt;
        permit_mynetworks,&lt;br /&gt;
        permit_sasl_authenticated,&lt;br /&gt;
        reject_unauth_destination,&lt;br /&gt;
        reject_rbl_client dnsbl.sorbs.net,&lt;br /&gt;
        reject_rbl_client zen.spamhaus.org,&lt;br /&gt;
        reject_rbl_client bl.spamcop.net&lt;br /&gt;
 &lt;br /&gt;
 smtpd_data_restrictions = reject_unauth_pipelining&lt;br /&gt;
 &lt;br /&gt;
 # we will use this later - This prevents cleartext authentication&lt;br /&gt;
 # for relaying&lt;br /&gt;
 smtpd_tls_auth_only = yes&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Now we need to create a *bunch* of files so that postfix can get the delivery information out of sql. Here&#039;s a shell script to create the scripts.  Change PGPW to the password for the postfix user of the postfix SQL database.&lt;br /&gt;
&lt;br /&gt;
 cd /etc/postfix&lt;br /&gt;
 mkdir sql&lt;br /&gt;
 PGPW=&amp;quot;ChangeMe&amp;quot;&lt;br /&gt;
 &lt;br /&gt;
 cat - &amp;lt;&amp;lt;EOF &amp;gt;sql/pgsql_virtual_alias_domain_catchall_maps.cf&lt;br /&gt;
 user=postfix&lt;br /&gt;
 password = $PGPW&lt;br /&gt;
 hosts = localhost&lt;br /&gt;
 dbname = postfix&lt;br /&gt;
 query = Select goto From alias,alias_domain where alias_domain.alias_domain = &#039;%d&#039; and alias.address = &#039;@&#039; ||  alias_domain.target_domain and alias.active = true and alias_domain.active= true &lt;br /&gt;
 EOF&lt;br /&gt;
 &lt;br /&gt;
 cat - &amp;lt;&amp;lt;EOF &amp;gt;sql/pgsql_virtual_alias_domain_mailbox_maps.cf&lt;br /&gt;
 user=postfix&lt;br /&gt;
 password = $PGPW&lt;br /&gt;
 hosts = localhost&lt;br /&gt;
 dbname = postfix&lt;br /&gt;
 query = Select maildir from mailbox,alias_domain where alias_domain.alias_domain = &#039;%d&#039; and mailbox.username = &#039;%u&#039; || &#039;@&#039; || alias_domain.target_domain and mailbox.active = true and alias_domain.active&lt;br /&gt;
 EOF&lt;br /&gt;
 &lt;br /&gt;
 cat - &amp;lt;&amp;lt;EOF &amp;gt;sql/pgsql_virtual_alias_domain_maps.cf&lt;br /&gt;
 user=postfix&lt;br /&gt;
 password = $PGPW&lt;br /&gt;
 hosts = localhost&lt;br /&gt;
 dbname = postfix&lt;br /&gt;
 query = select goto from alias,alias_domain where alias_domain.alias_domain=&#039;%d&#039; and alias.address = &#039;%u&#039; || &#039;@&#039; || alias_domain.target_domain and alias.active= true and alias_domain.active= true&lt;br /&gt;
 EOF&lt;br /&gt;
 &lt;br /&gt;
 cat - &amp;lt;&amp;lt;EOF &amp;gt;sql/pgsql_virtual_alias_maps.cf&lt;br /&gt;
 user=postfix&lt;br /&gt;
 password = $PGPW&lt;br /&gt;
 hosts = localhost&lt;br /&gt;
 dbname = postfix&lt;br /&gt;
 query = Select goto From alias Where address=&#039;%s&#039; and active =&#039;1&#039;&lt;br /&gt;
 EOF&lt;br /&gt;
 &lt;br /&gt;
 cat - &amp;lt;&amp;lt;EOF &amp;gt;sql/pgsql_virtual_domains_maps.cf&lt;br /&gt;
 user=postfix&lt;br /&gt;
 password = $PGPW&lt;br /&gt;
 hosts = localhost&lt;br /&gt;
 dbname = postfix&lt;br /&gt;
 query = Select domain from domain where domain=&#039;%s&#039; and active=&#039;1&#039;&lt;br /&gt;
 EOF&lt;br /&gt;
 &lt;br /&gt;
 cat - &amp;lt;&amp;lt;EOF &amp;gt;sql/pgsql_virtual_mailbox_maps.cf&lt;br /&gt;
 user=postfix&lt;br /&gt;
 password = $PGPW&lt;br /&gt;
 hosts = localhost&lt;br /&gt;
 dbname = postfix&lt;br /&gt;
 query = Select maildir from mailbox where username=&#039;%s&#039; and active=true&lt;br /&gt;
 EOF&lt;br /&gt;
 &lt;br /&gt;
 chown -R postfix:postfix sql&lt;br /&gt;
 chmod 640 sql/*&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
At this point you should be able to start up postfix&lt;br /&gt;
 &lt;br /&gt;
 newaliases  # so postfix is happy...&lt;br /&gt;
 /etc/init.d/postfix start&lt;br /&gt;
 rc-update add postfix&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Create a domain in PostfixAdmin and test ===&lt;br /&gt;
&lt;br /&gt;
Go to http://host.example.com/postfixadmin/&lt;br /&gt;
&lt;br /&gt;
Log in using the superadmin account, create a domain for the local box (e.g. example.com), and create a user mailbox (e.g. root).&lt;br /&gt;
&lt;br /&gt;
From the machine, send a test message:&lt;br /&gt;
&lt;br /&gt;
 sendmail -t root@example.com&lt;br /&gt;
 subject: test&lt;br /&gt;
 .&lt;br /&gt;
 ^d&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
In /var/log/mail.log (or /var/log/messages, if you still have busybox syslogd running) you should see the message queued.  The message should be in /var/mail/domains/example.com/root/new&lt;br /&gt;
&lt;br /&gt;
== Install Dovecot ==&lt;br /&gt;
&lt;br /&gt;
Dovecot is the POP3/IMAP server to retrieve mail.&lt;br /&gt;
&lt;br /&gt;
As before, we install dovecot: &lt;br /&gt;
&lt;br /&gt;
 apk add acf-dovecot dovecot-pgsql&lt;br /&gt;
&lt;br /&gt;
edit /etc/dovecot/dovecot.conf&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 # Select only the protocols you wish to support - all are listed in the next line&lt;br /&gt;
 protocols               =       imap imaps pop pop3s&lt;br /&gt;
 log_path                =       /var/log/dovecot.log&lt;br /&gt;
 info_log_path           =       /var/log/dovecot-info.log&lt;br /&gt;
 disable_plaintext_auth  =       no&lt;br /&gt;
&lt;br /&gt;
 # Authenticated IMAP&lt;br /&gt;
 ssl                     =       yes&lt;br /&gt;
 ssl_cert_file           =       /etc/lighttpd/server-bundle.pem&lt;br /&gt;
 ssl_key_file            =       /etc/lighttpd/server-bundle.pem&lt;br /&gt;
 auth_verbose            =       yes&lt;br /&gt;
 auth_debug              =       no&lt;br /&gt;
 mail_location           =       maildir:/var/mail/domains/%d/%n&lt;br /&gt;
 auth default    {&lt;br /&gt;
        mechanisms = plain&lt;br /&gt;
        passdb sql {&lt;br /&gt;
                args = /etc/dovecot/dovecot-sql.conf&lt;br /&gt;
                }&lt;br /&gt;
        userdb static {&lt;br /&gt;
                args =  uid=1006 gid=1006 home=/var/mail/domains/%d/%n&lt;br /&gt;
                }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Be sure to replace the uid and gid with the appropriate values for the vmail user.&lt;br /&gt;
&lt;br /&gt;
We need a certificate for SSL/TLS authentication, so in the example above, we use the lighttpd cert. That way when the cert is renewed/replaced, Dovecot will have access to the new cert as well.  &lt;br /&gt;
&lt;br /&gt;
Create the /etc/dovecot/dovecot-sql.conf file:&lt;br /&gt;
&lt;br /&gt;
 driver = pgsql&lt;br /&gt;
 connect = host=localhost dbname=postfix user=postfix password=********&lt;br /&gt;
 password_query = select username,password from mailbox where local_part = &#039;%n&#039; and domain = &#039;%d&#039;&lt;br /&gt;
 default_pass_scheme =  MD5-CRYPT&lt;br /&gt;
&lt;br /&gt;
Again, change the password above to your postfix user password, and protect the file from prying eyes:&lt;br /&gt;
&lt;br /&gt;
 chown root:root /etc/dovecot/dovecot-sql.conf&lt;br /&gt;
 chmod 600 /etc/dovecot/dovecot-sql.conf&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Start dovecot&lt;br /&gt;
 /etc/init.d/dovecot start&lt;br /&gt;
 rc-update add dovecot&lt;br /&gt;
&lt;br /&gt;
== Testing ==&lt;br /&gt;
&lt;br /&gt;
Make sure your firewall allows in ports 25(SMTP) 110 (POP3), 995 (POP3S), 143(IMAP), 993(IMAPS), or whatever subset you support.  &lt;br /&gt;
 &lt;br /&gt;
At this point, you should be able to:&lt;br /&gt;
 * Create a new domain and add users with PostfixAdmin&lt;br /&gt;
 * Send mail to those users via SMTP to port 25&lt;br /&gt;
 * Retrieve mail using the user&#039;s full email and password (e.g. username: user@example.com  password: ChangeMe)&lt;br /&gt;
&lt;br /&gt;
== Value Add Features ==&lt;br /&gt;
&lt;br /&gt;
If you followed the guide above, you now have a functional mail server with many interconnected parts.  The features below assume that the server is already running as described above.  You should be able to add any or all of these features below to further enhance the mail service.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Virus Scanning ===&lt;br /&gt;
&lt;br /&gt;
This procedure uses clamav and the postfix content_filter mechanism to scan inbound and outbound email for viruses.  Infected emails are dropped.  Clean emails are tagged with a &amp;quot;scanned by clamav&amp;quot; header.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* Install clamav and clamsmtp:&lt;br /&gt;
 apk add acf-clamav clamsmtp&lt;br /&gt;
* Edit the /etc/clamav/clamd.conf file if desired (not necessary in most cases)&lt;br /&gt;
* Edit /etc/clamsmtpd.conf and verify the following lines&lt;br /&gt;
 OutAddress: 10026&lt;br /&gt;
 Listen: 127.0.0.1:10025                                               &lt;br /&gt;
 Header: X-Virus-Scanned: ClamAV using ClamSMTP&lt;br /&gt;
 Action: drop&lt;br /&gt;
 User: clamav                                                      &lt;br /&gt;
* Start the daemons&lt;br /&gt;
 rc-update add clamd&lt;br /&gt;
 rc-update add clamsmtpd&lt;br /&gt;
 /etc/init.d/clamd start&lt;br /&gt;
 /etc/init.d/clamsmtpd start&lt;br /&gt;
* Verify clamsmtp is listening on port 10025:&lt;br /&gt;
 netstat -anp | grep clamsmtp&lt;br /&gt;
* [http://memberwebs.com/stef/software/clamsmtp/postfix.html Following the clamsmtp instructions]&lt;br /&gt;
** edit /etc/postfix/main.cf and add:&lt;br /&gt;
 content_filter = scan:[127.0.0.1]:10025                                                      &lt;br /&gt;
** edit /etc/postfix/master.cf and add&lt;br /&gt;
 # AV scan filter (used by content_filter)&lt;br /&gt;
 scan      unix  -       -       n       -       16      smtp&lt;br /&gt;
         -o smtp_send_xforward_command=yes&lt;br /&gt;
         -o smtp_enforce_tls=no&lt;br /&gt;
 # For injecting mail back into postfix from the filter&lt;br /&gt;
 127.0.0.1:10026 inet  n -       n       -       16      smtpd&lt;br /&gt;
         -o content_filter=&lt;br /&gt;
         -o receive_override_options=no_unknown_recipient_checks,no_header_body_checks&lt;br /&gt;
         -o smtpd_helo_restrictions=&lt;br /&gt;
         -o smtpd_client_restrictions=&lt;br /&gt;
         -o smtpd_sender_restrictions=&lt;br /&gt;
         -o smtpd_recipient_restrictions=permit_mynetworks,reject&lt;br /&gt;
         -o mynetworks_style=host&lt;br /&gt;
         -o smtpd_authorized_xforward_hosts=127.0.0.0/8&lt;br /&gt;
* postfix reload&lt;br /&gt;
* Send and email into a local virtual domain - it should have the &#039;&#039;X-Virus-Scanned: ClamAV using ClamSMTP&#039;&#039; header.&lt;br /&gt;
&lt;br /&gt;
=== Relay for Authenticated Users ===&lt;br /&gt;
&lt;br /&gt;
As configured above, the mail server accepts email from the Internet, but it does not relay email.  If it is a perimeter exchanger for a protected network, then you can add the protected networks to the &#039;&#039;mynetworks&#039;&#039; configuration line in /etc/postfix/main.cf&lt;br /&gt;
&lt;br /&gt;
This configuration change allows &#039;&#039;remote&#039;&#039; users to authenticate against the mail server and relay through it.  The rules for relaying are:&lt;br /&gt;
* Only authenticated users can relay&lt;br /&gt;
* Authentication Credentials must be encrypted with TLS or SSL&lt;br /&gt;
* Allow Submission and SMTPS ports for relaying (many consumer networks block port 25 - SMTP by default)&lt;br /&gt;
The process uses the dovecot authentication mechanism (used with IMAPS) to authenticate users before they are allowed to relay through postfix.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* Edit /etc/dovecot/dovecot.conf and add:&lt;br /&gt;
 # this is for postfix SASL (authenticated users can relay through us)&lt;br /&gt;
 socket listen {&lt;br /&gt;
                client {&lt;br /&gt;
                        path    = /var/spool/postfix/private/dovecot-auth.sock&lt;br /&gt;
                        mode    = 0660&lt;br /&gt;
                        user    = postfix&lt;br /&gt;
                        group   = postfix&lt;br /&gt;
                        }&lt;br /&gt;
                }&lt;br /&gt;
        }&lt;br /&gt;
* Restart dovecot&lt;br /&gt;
 /etc/init.d/dovecot restart&lt;br /&gt;
* Edit /etc/postfix/main.cf and add:&lt;br /&gt;
 # TLS Stuff -- since we allow SASL with tls *only*, we have to set up TLS first                    &lt;br /&gt;
 &lt;br /&gt;
 smtpd_tls_cert_file = /etc/lighttpd/server-bundle.pem&lt;br /&gt;
 smtpd_tls_key_file = /etc/lighttpd/server-bundle.pem&lt;br /&gt;
 smtpd_tls_CAfile = /etc/lighttpd/ca-crt.pem&lt;br /&gt;
 # If tls_security_level is set to &amp;quot;encrypt&amp;quot;, then SMTP rejects &lt;br /&gt;
 # unencrypted email (e.g. normal mail) which is bad.&lt;br /&gt;
 # By setting it to &amp;quot;may&amp;quot; you get TLS encrypted mail from google, slashdot, and other &lt;br /&gt;
 # interesting places.  Check your logs to see who&lt;br /&gt;
 smtpd_tls_security_level = may&lt;br /&gt;
 # Log info about the negotiated encryption levels&lt;br /&gt;
 smtpd_tls_received_header = yes&lt;br /&gt;
 smtpd_tls_loglevel = 1&lt;br /&gt;
 &lt;br /&gt;
 # SASL - this allows senders to authenticiate themselves&lt;br /&gt;
 # This along with &amp;quot;permit_sasl_authenticated&amp;quot; in smtpd_recipient_restrictions allows relaying&lt;br /&gt;
 smtpd_sasl_type = dovecot&lt;br /&gt;
 smtpd_sasl_path = private/dovecot-auth.sock&lt;br /&gt;
 smtpd_sasl_auth_enable = yes&lt;br /&gt;
 smtpd_sasl_authenticated_header = yes&lt;br /&gt;
 smtpd_tls_auth_only = yes&lt;br /&gt;
* Edit /etc/postfix/master.cf and enable the submission and smtps transports.  They are probably already at the top of your  master.cf file, just commented out:&lt;br /&gt;
 submission inet n       -       n       -       -       smtpd&lt;br /&gt;
   -o smtpd_tls_security_level=encrypt&lt;br /&gt;
   -o smtpd_sasl_auth_enable=yes&lt;br /&gt;
   -o smtpd_client_restrictions=permit_sasl_authenticated,reject&lt;br /&gt;
   -o milter_macro_daemon_name=ORIGINATING&lt;br /&gt;
 smtps     inet  n       -       n       -       -       smtpd&lt;br /&gt;
   -o smtpd_tls_security_level=encrypt&lt;br /&gt;
   -o smtpd_tls_wrappermode=yes&lt;br /&gt;
   -o smtpd_sasl_auth_enable=yes&lt;br /&gt;
   -o smtpd_client_restrictions=permit_sasl_authenticated,reject&lt;br /&gt;
   -o milter_macro_daemon_name=ORIGINATING&lt;br /&gt;
*Verfiy submission and smtps are defined in /etc/services&lt;br /&gt;
 grep &amp;quot;submission\|ssmtp&amp;quot; /etc/services&lt;br /&gt;
 submission	587/tcp				# mail message submission&lt;br /&gt;
 submission	587/udp&lt;br /&gt;
 smtps		465/tcp		ssmtp		# smtp protocol over TLS/SSL&lt;br /&gt;
 smtps		465/udp		ssmtp&lt;br /&gt;
* Restart postfix&lt;br /&gt;
 postfix reload&lt;br /&gt;
&lt;br /&gt;
At this point, you should be able to set up a mail client to relay through the server with TLS (port 587) or SSL (port 465)  Note that &amp;quot;plain&amp;quot; authentication is used because the underlying link is encrypted.  For example, in Thunderbird leave &amp;quot;secure authentication&amp;quot; unchecked, and choose STARTTLS (or TLS) for the connection security.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Mailbox Quotas ===&lt;br /&gt;
&lt;br /&gt;
In the default configuration, PostfixAdmin knows about quotas, but they are not enforced.   Documentation on the web mentions the [http://vda.sourceforge.net vda patch to postfix] to enforce quotas.  The only bad thing... its a &#039;&#039;patch&#039;&#039;.   Postfix and Dovecot are both conservative systems, so if the patch isn&#039;t in the upstream source, we&#039;ll assume there&#039;s a good reason.   There is a way of using quotas without patches - and it involves using dovecot&#039;s [http://wiki.dovecot.org/LDA deliver] lda for local delivery.&lt;br /&gt;
&lt;br /&gt;
Note: As of Jan 2010, the documention is confusing, with multiple versions of dovecot, PostfixAdmin, and Mysql referenced.  These instructions apply to:&lt;br /&gt;
* Postgresql 8.4.2 &lt;br /&gt;
* PostfixAdmin 2.3 &lt;br /&gt;
* Dovecot 1.2.10&lt;br /&gt;
* Postfix 2.6.5&lt;br /&gt;
&lt;br /&gt;
Presumably later versions will work the same, but if not, please update the documentation and versions above.&lt;br /&gt;
&lt;br /&gt;
* Update /etc/dovecot/dovecot.conf (old lines shown commented out):&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
# old postfix &lt;br /&gt;
#       userdb static {&lt;br /&gt;
#               args =  uid=1006 gid=1006 home=/var/mail/domains/%d/%n&lt;br /&gt;
#               }&lt;br /&gt;
&lt;br /&gt;
# new quota support:&lt;br /&gt;
        userdb prefetch {&lt;br /&gt;
                }&lt;br /&gt;
&lt;br /&gt;
        userdb sql {&lt;br /&gt;
                args = /etc/dovecot/dovecot-sql.conf&lt;br /&gt;
                }&lt;br /&gt;
&lt;br /&gt;
        socket listen {&lt;br /&gt;
                client {&lt;br /&gt;
                        path    = /var/spool/postfix/private/dovecot-auth.sock&lt;br /&gt;
                        mode    = 0660&lt;br /&gt;
                        user    = postfix&lt;br /&gt;
                        group   = postfix&lt;br /&gt;
                        }&lt;br /&gt;
                # These lines below are for the deliver lda&lt;br /&gt;
                master {&lt;br /&gt;
                        path =  /var/run/dovecot/auth-master&lt;br /&gt;
                        mode    = 0660&lt;br /&gt;
                        user    = vmail&lt;br /&gt;
                        group   = vmail&lt;br /&gt;
                        }&lt;br /&gt;
                }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
protocol imap {                                                               &lt;br /&gt;
         mail_plugins = quota imap_quota                                       &lt;br /&gt;
         }                                                                     &lt;br /&gt;
                                                                              &lt;br /&gt;
protocol pop3 {                                                               &lt;br /&gt;
         mail_plugins = quota                                                  &lt;br /&gt;
         }                                                                     &lt;br /&gt;
                                                                              &lt;br /&gt;
dict {                                                                        &lt;br /&gt;
        quotadict = pgsql:/etc/dovecot/dovecot-dict-quota.conf                &lt;br /&gt;
        }                                                                     &lt;br /&gt;
                                                                              &lt;br /&gt;
plugin {                                                                      &lt;br /&gt;
         quota = dict:user::proxy::quotadict                                   &lt;br /&gt;
         }                                                     &lt;br /&gt;
                                                              &lt;br /&gt;
protocol lda {                                                &lt;br /&gt;
   postmaster_address = postmaster@host.example.com&lt;br /&gt;
   mail_plugins = quota                                        &lt;br /&gt;
   auth_socket_path =  /var/run/dovecot/auth-master&lt;br /&gt;
   sendmail_path = /usr/sbin/sendmail&lt;br /&gt;
}                                                                            &lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
 &lt;br /&gt;
You should already have a &amp;lt;tt&amp;gt;socket-&amp;gt; listen-&amp;gt; client&amp;lt;/tt&amp;gt; section, but it is listed above to show where it goes in relationship to the &amp;lt;tt&amp;gt;socket -&amp;gt; listen -&amp;gt; master&amp;lt;/tt&amp;gt; section&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* edit &amp;lt;tt&amp;gt;/etc/dovecot/dovecot-sql.conf&amp;lt;/tt&amp;gt; and replace the user and password queries with the following (you may not have a user_query yet - add it):&lt;br /&gt;
&lt;br /&gt;
 password_query = select username as user, password, 1006 as userdb_uid, 1006 as userdb_gid, &#039;*:bytes=&#039; || quota as userdb_quota_rule from mailbox  where local_part = &#039;%n&#039; and domain = &#039;%d&#039;&lt;br /&gt;
 user_query = select maildir as home, 1006 as uid, 1006 as gid, &#039;*:bytes=&#039; || quota  as quota_rule from mailbox where local_part = &#039;%n&#039; and domain =&#039;%d&#039;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* create &amp;lt;tt&amp;gt;/etc/dovecot/dovecot-dict-quota.conf&amp;lt;/tt&amp;gt;&lt;br /&gt;
 connect = host=localhost dbname=postfix user=postfix password=********&lt;br /&gt;
 &lt;br /&gt;
 map {&lt;br /&gt;
         pattern = priv/quota/storage&lt;br /&gt;
         table = quota2&lt;br /&gt;
         username_field =username&lt;br /&gt;
         value_field = bytes&lt;br /&gt;
 }&lt;br /&gt;
 &lt;br /&gt;
 map {&lt;br /&gt;
        pattern= priv/quota/messages&lt;br /&gt;
        table = quota2&lt;br /&gt;
        username_field = username&lt;br /&gt;
        value_field = messages&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
Side note: [http://wiki.dovecot.org/Quota/Dict The Dovecot Quota Documentation] mentions the need for a trigger with pgsql.  This was created in the PostfixAdmin install, which is why you instantiated the pgsql language when creating the database.  If not, you will need to create the trigger, to reference the quota2 table, not the quota table mentioned in the dovecot docs.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* create a new transport for the dovecot lda.   Add the following to  /etc/postfix/master.cf:&lt;br /&gt;
 # The dovecot deliver lda&lt;br /&gt;
 dovecot   unix  -       n       n       -       -       pipe&lt;br /&gt;
   flags=DRhu user=vmail:vmail argv=/usr/libexec/dovecot/deliver -f ${sender} -d ${user}@${nexthop}&lt;br /&gt;
&lt;br /&gt;
* Edit the /etc/postfix/main.cf.  Replace &lt;br /&gt;
 virtual_transport = virtual &lt;br /&gt;
with&lt;br /&gt;
 virtual_transport = dovecot&lt;br /&gt;
 dovecot_destination_recipient_limit = 1&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;TODO&#039;&#039;&#039;  This will cause over-quota emails to bounce.   Which could be a source of backscatter.   We need a way of checking quota limits after RBL checking but before the message is accepted in the queue.&lt;br /&gt;
&lt;br /&gt;
=== WebMail (RoundCube) ===&lt;br /&gt;
&lt;br /&gt;
[http://roundcube.net/ RoundCube] is an &amp;quot;ajax /Web2.0&amp;quot; web-mail client.  These instructions are for the Alpine Linux 1.10 repository &lt;br /&gt;
&lt;br /&gt;
* Add the package and related php modules:&lt;br /&gt;
 apk add roundcubemail php-xml php-openssl php-mcrypt php-gd php-iconv&lt;br /&gt;
&lt;br /&gt;
* link the roundcube application back into the docroot&lt;br /&gt;
 ln -s /usr/share/webapps/roundcube /var/www/domains/host.example.com/www/roundcube&lt;br /&gt;
&lt;br /&gt;
* follow the instructions in /usr/share/webapps/roundcube/INSTALL:&lt;br /&gt;
 cd /usr/share/webapps/roundcube&lt;br /&gt;
 chown -R lighttpd:lighttpd temp logs&lt;br /&gt;
 &lt;br /&gt;
 su postgres&lt;br /&gt;
 createuser roundcube&lt;br /&gt;
   Shall the new role be a superuser? (y/n) n&lt;br /&gt;
   Shall the new role be allowed to create databases? (y/n) n&lt;br /&gt;
   Shall the new role be allowed to create more new roles? (y/n) y&lt;br /&gt;
 createdb -O roundcube -E UNICODE -T template0 roundcubemail&lt;br /&gt;
 psql roundcubemail&lt;br /&gt;
   roundcubemail=# ALTER USER roundcube WITH PASSWORD &#039;the_new_password&#039;;&lt;br /&gt;
   roundcubemail=# \c - roundcube&lt;br /&gt;
   roundcubemail=&amp;gt; \i /usr/share/webapps/roundcube/SQL/postgres.initial.sql&lt;br /&gt;
   roundcubemail=&amp;gt; \q&lt;br /&gt;
 exit&lt;br /&gt;
&lt;br /&gt;
* edit /etc/php/php.ini and set date.timezone to your local timezone, or to UTC&lt;br /&gt;
&lt;br /&gt;
* restart lighttpd to verify the new php libraries are used&lt;br /&gt;
 /etc/init.d/lighttpd restart&lt;br /&gt;
&lt;br /&gt;
* Point your browser to http://host.example.com/roundcube/installer&lt;br /&gt;
* Start installation&lt;br /&gt;
&lt;br /&gt;
For the specific configuration parameters in the install step:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!Property&lt;br /&gt;
!Setting&lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;enable_spellcheck&#039;&#039; ||   disabled &lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;identities_level&#039;&#039; ||  one identity with possibility to edit all params but not email address &lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;log driver&#039;&#039; || syslog &lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;sylog_id&#039;&#039; || roundcube &lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;syslog_facility&#039;&#039; || mailsubsystem &lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;db_dnsw&#039;&#039; || pgsql properties, as described above &lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;imap_host&#039;&#039; || 127.0.0.1 &lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;auto_create_user&#039;&#039; || enabled &lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;smtp_server&#039;&#039; ||  127.0.0.1&lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;smtp_port&#039;&#039; ||  25&lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;smtp_user/smtp_pass&#039;&#039; ||  enable &#039;&#039;Use Current IMAP username and password for SMTP authentication&#039;&#039;&lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;smtp_log&#039;&#039; ||  enable (optional, but gives additional log record)&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
The other items can be left at default settings, or adjusted if desired.&lt;br /&gt;
&lt;br /&gt;
* Follow the instructions in step 3 of the install to copy the files to the server&lt;br /&gt;
* You should now be able to get to roundcube at http://host.example.com/roundcube&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
After its working, the INSTALL file recommends removing the install directory.   If you want to keep the installer around later, you can simply change the ownership and permissions.  So do &#039;&#039;&#039;one&#039;&#039;&#039; of the following:&lt;br /&gt;
 cd /usr/share/webapps/roundcube&lt;br /&gt;
 rm -rf LICENSE UPGRADING INSTALL README CHANGELOG  SQL installer&lt;br /&gt;
or&lt;br /&gt;
 cd /usr/share/webapps/roundcube&lt;br /&gt;
 chown -R root:root LICENSE UPGRADING INSTALL README CHANGELOG  SQL installer&lt;br /&gt;
 chmod -R 600 LICENSE UPGRADING INSTALL README CHANGELOG SQL &lt;br /&gt;
 chmod 700 SQL installer&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== OpenLDAP based Address Book ===&lt;br /&gt;
&lt;br /&gt;
This OpenLDAP configuration uses the SQL backend, which represents information stored in PostgreSQL as an LDAP subtree for Address Book functionality for email lookups, user authentication or even &lt;br /&gt;
replication account information between sites. This procedure uses some metainformation to translate LDAP queries to SQL queries, leaving relational schema untouched, which allows SQL and LDAP &lt;br /&gt;
applications to inter-operate without replication, and exchange data as needed. The SQL backend uses UnixODBC to connect to PostgresSQL. &lt;br /&gt;
&lt;br /&gt;
* Install OpenLDAP and ODBC&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
apk add openldap libldap openldap-back-sql php-ldap unixodbc psqlodbc ca-certificates&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Note&#039;&#039;&#039;: Perhaps some packages should be installed from &amp;quot;edge&amp;quot; repository&lt;br /&gt;
&lt;br /&gt;
* Update &amp;quot;postfix&amp;quot; database (it will add &#039;id&#039; columns to mailbox and domain tables, also will create tables and views to represent LDAP metainformation)&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Note&#039;&#039;&#039;: These instructions are for example domain example.com. So make sure you replaced all entries of &#039;example&#039; and &#039;com&#039; according to your domain name parts.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
cat - &amp;lt;&amp;lt;EOF | psql -U postgres postfix&lt;br /&gt;
ALTER TABLE domain ADD COLUMN id SERIAL; &lt;br /&gt;
ALTER TABLE mailbox ADD COLUMN id SERIAL; &lt;br /&gt;
&lt;br /&gt;
CREATE TABLE ldap_entry_objclasses (&lt;br /&gt;
    entry_id integer NOT NULL,&lt;br /&gt;
    oc_name character varying(64)&lt;br /&gt;
);&lt;br /&gt;
&lt;br /&gt;
CREATE TABLE ldap_oc_mappings (&lt;br /&gt;
    id integer SERIAL,&lt;br /&gt;
    name character varying(64) NOT NULL,&lt;br /&gt;
    keytbl character varying(64) NOT NULL,&lt;br /&gt;
    keycol character varying(64) NOT NULL,&lt;br /&gt;
    create_proc character varying(255),&lt;br /&gt;
    delete_proc character varying(255),&lt;br /&gt;
    expect_return integer NOT NULL,&lt;br /&gt;
    PRIMARY KEY(id)&lt;br /&gt;
);&lt;br /&gt;
&lt;br /&gt;
CREATE TABLE ldap_attr_mappings_test (&lt;br /&gt;
    id integer SERIAL,&lt;br /&gt;
    oc_map_id integer NOT NULL REFERENCES ldap_oc_mappings(id),&lt;br /&gt;
    name character varying(255) NOT NULL,&lt;br /&gt;
    sel_expr character varying(255) NOT NULL,&lt;br /&gt;
    sel_expr_u character varying(255),&lt;br /&gt;
    from_tbls character varying(255) NOT NULL,&lt;br /&gt;
    join_where character varying(255),&lt;br /&gt;
    add_proc character varying(255),&lt;br /&gt;
    delete_proc character varying(255),&lt;br /&gt;
    param_order integer NOT NULL,&lt;br /&gt;
    expect_return integer NOT NULL,&lt;br /&gt;
    PRIMARY KEY(id)&lt;br /&gt;
);&lt;br /&gt;
&lt;br /&gt;
CREATE VIEW ldap_dcs AS&lt;br /&gt;
    (SELECT (domain.id + 100000) AS id, &lt;br /&gt;
            (((&#039;dc=&#039;::text || split_part((domain.domain)::text, &#039;.&#039;::text, 1)) || &#039;,dc=&#039;::text) || &lt;br /&gt;
            CASE WHEN (split_part((domain.domain)::text, &#039;.&#039;::text, 2) = &#039;com&#039;::text) THEN split_part((domain.domain)::text, &#039;.&#039;::text, 2) &lt;br /&gt;
                 ELSE ((split_part((domain.domain)::text, &#039;.&#039;::text, 2) || &#039;,dc=&#039;::text) || split_part((domain.domain)::text, &#039;.&#039;::text, 3)) &lt;br /&gt;
            END) AS dn, &lt;br /&gt;
            1 AS oc_map_id, &lt;br /&gt;
            100000 AS parent, &lt;br /&gt;
            0 AS keyval, &lt;br /&gt;
            domain.domain&lt;br /&gt;
     FROM domain &lt;br /&gt;
     WHERE domain.domain &amp;lt;&amp;gt; &#039;ALL&#039; &lt;br /&gt;
      UNION &lt;br /&gt;
     SELECT 100000 AS id, &lt;br /&gt;
           &#039;dc=com&#039; AS dn, &lt;br /&gt;
           1 AS oc_map_id, &lt;br /&gt;
           0 AS parent, &lt;br /&gt;
           0 AS keyval, &lt;br /&gt;
           &#039;com&#039; AS domain);&lt;br /&gt;
&lt;br /&gt;
CREATE VIEW ldap_entries AS&lt;br /&gt;
    SELECT mailbox.id, &lt;br /&gt;
    (((((&#039;cn=&#039;::text || initcap(replace(split_part((mailbox.username)::text, &#039;@&#039;::text, 1), &#039;.&#039;::text, &#039; &#039;::text))) || &#039;,dc=&#039;::text) || &lt;br /&gt;
          split_part(split_part((mailbox.username)::text, &#039;@&#039;::text, 2), &#039;.&#039;::text, 1)) || &#039;,dc=&#039;::text) || &lt;br /&gt;
             CASE WHEN (split_part(split_part((mailbox.username)::text, &#039;@&#039;::text, 2), &#039;.&#039;::text, 2) = &#039;com&#039;::text) &lt;br /&gt;
                  THEN split_part(split_part((mailbox.username)::text, &#039;@&#039;::text, 2), &#039;.&#039;::text, 2) &lt;br /&gt;
                  ELSE ((split_part(split_part((mailbox.username)::text, &#039;@&#039;::text, 2), &#039;.&#039;::text, 2) || &#039;,dc=&#039;::text) || &lt;br /&gt;
                         split_part(split_part((mailbox.username)::text, &#039;@&#039;::text, 2), &#039;.&#039;::text, 3)) &lt;br /&gt;
             END) AS dn, &lt;br /&gt;
          1 AS oc_map_id, &lt;br /&gt;
          (SELECT ldap_dcs.id &lt;br /&gt;
           FROM ldap_dcs &lt;br /&gt;
           WHERE ((ldap_dcs.domain)::text = (mailbox.domain)::text)) AS parent, &lt;br /&gt;
           mailbox.id AS keyval &lt;br /&gt;
           FROM mailbox &lt;br /&gt;
           UNION &lt;br /&gt;
           SELECT ldap_dcs.id,  &lt;br /&gt;
                  ldap_dcs.dn, &lt;br /&gt;
                  ldap_dcs.oc_map_id, &lt;br /&gt;
                  ldap_dcs.parent, &lt;br /&gt;
                  ldap_dcs.keyval &lt;br /&gt;
           FROM ldap_dcs;&lt;br /&gt;
EOF&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* Fill out LDAP tables according to following example (make sure to separate values with TABs):&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
cat - &amp;lt;&amp;lt;EOF | psql -U postgres postfix&lt;br /&gt;
COPY ldap_attr_mappings (id, oc_map_id, name, sel_expr, sel_expr_u, from_tbls, join_where, add_proc, delete_proc, param_order, expect_return) FROM stdin;&lt;br /&gt;
1	1	displayName	mailbox.name	\N	mailbox	\N	\N	\N	3	0&lt;br /&gt;
2	1	mail	mailbox.username	\N	mailbox	\N	\N	\N	3	0&lt;br /&gt;
3	1	cn	mailbox.name	\N	mailbox	\N	\N	\N	3	0&lt;br /&gt;
4	1	userPassword	&#039;{CRYPT}&#039;||mailbox.password	\N	mailbox	\N	\N	\N	3	0&lt;br /&gt;
\.&lt;br /&gt;
&lt;br /&gt;
COPY ldap_oc_mappings (id, name, keytbl, keycol, create_proc, delete_proc, expect_return) FROM stdin;&lt;br /&gt;
1	exampleBox	mailbox	id	\N	\N	1&lt;br /&gt;
\.&lt;br /&gt;
EOF&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* Check that &amp;quot;ldap_dcs&amp;quot; view presens something like this:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
echo &#039;select * from ldap_dcs&#039; | psql -U postgres postfix&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
   id   |             dn              | oc_map_id | parent | keyval |       domain       &lt;br /&gt;
--------+-----------------------------+-----------+--------+--------+--------------------&lt;br /&gt;
 100000 | dc=com                      |         1 |      0 |      0 | com&lt;br /&gt;
 100001 | dc=example,dc=com           |         1 | 100000 |      0 | example.com&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* Check that &amp;quot;ldap_entries&amp;quot; view presens something like this:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
echo &#039;select * from ldap_entries&#039; | psql -U postgres postfix&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
   id   |                          dn                           | oc_map_id | parent | keyval &lt;br /&gt;
--------+-------------------------------------------------------+-----------+--------+--------&lt;br /&gt;
    1   | cn=address1,dc=example,dc=com                         |         1 | 100001 |    1&lt;br /&gt;
...&lt;br /&gt;
   123  | cn=address123,dc=example,dc=com                       |         1 | 100001 |    1&lt;br /&gt;
 100000 | dc=com                                                |         1 |      0 |    0&lt;br /&gt;
 100001 | dc=example,dc=com                                     |         1 | 100000 |    0&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* Configure ODBC parameters&lt;br /&gt;
&lt;br /&gt;
Edit /etc/odbc.ini:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
[PostgreSQL]&lt;br /&gt;
Description             = Connection to Postgres&lt;br /&gt;
Driver                  = PostgreSQL&lt;br /&gt;
Trace                   = Yes&lt;br /&gt;
TraceFile               = sql.log&lt;br /&gt;
Database                = postfix&lt;br /&gt;
Servername              = 127.0.0.1&lt;br /&gt;
UserName                =&lt;br /&gt;
Password                =&lt;br /&gt;
Port                    = 5432&lt;br /&gt;
Protocol                = 6.4&lt;br /&gt;
ReadOnly                = No&lt;br /&gt;
RowVersining            = No&lt;br /&gt;
ShowSystemTables        = No&lt;br /&gt;
ShowOidColumn           = No&lt;br /&gt;
FakeOidIndex            = No&lt;br /&gt;
ConnSettings            =&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Edit /etc/odbcinst.ini:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
[PostgreSQL]&lt;br /&gt;
Description     = PostgreSQL driver for Linux&lt;br /&gt;
Driver          = /usr/lib/psqlodbcw.so&lt;br /&gt;
Setup           = /usr/lib/libodbcpsqlS.so&lt;br /&gt;
FileUsage       = 1&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* Test ODBC connection&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
echo &amp;quot;select * from domain;&amp;quot; | isql PostgreSQL postgres&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* Provide permission to certificate for LDAP server&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
chown ldap /etc/lighttpd/server-bundle.pem&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* Edit LDAP schema&lt;br /&gt;
&lt;br /&gt;
Edit /etc/openldap/schema/example.com.schema:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
attributetype ( 0.9.2342.19200300.100.1.3&lt;br /&gt;
	NAME ( &#039;mail&#039; &#039;rfc822Mailbox&#039; )&lt;br /&gt;
	DESC &#039;RFC1274: RFC822 Mailbox&#039;&lt;br /&gt;
        EQUALITY caseIgnoreIA5Match&lt;br /&gt;
        SUBSTR caseIgnoreIA5SubstringsMatch&lt;br /&gt;
        SYNTAX 1.3.6.1.4.1.1466.115.121.1.26{256} )&lt;br /&gt;
&lt;br /&gt;
attributetype ( 2.16.840.1.113730.3.1.241&lt;br /&gt;
	NAME &#039;displayName&#039;&lt;br /&gt;
	DESC &#039;RFC2798: preferred name to be used when displaying entries&#039;&lt;br /&gt;
	EQUALITY caseIgnoreMatch&lt;br /&gt;
	SUBSTR caseIgnoreSubstringsMatch&lt;br /&gt;
	SYNTAX 1.3.6.1.4.1.1466.115.121.1.15&lt;br /&gt;
	SINGLE-VALUE )&lt;br /&gt;
&lt;br /&gt;
objectclass   ( 2.16.840.1.113730.3.2.2&lt;br /&gt;
        NAME &#039;exampleBox&#039;&lt;br /&gt;
	DESC &#039;example.com mailbox&#039;&lt;br /&gt;
	MUST ( displayName $ mail $ userPassword )&lt;br /&gt;
	)&lt;br /&gt;
&lt;br /&gt;
# RFC 1274 + RFC 2247&lt;br /&gt;
attributetype ( 0.9.2342.19200300.100.1.25&lt;br /&gt;
        NAME ( &#039;dc&#039; &#039;domainComponent&#039; )&lt;br /&gt;
        DESC &#039;RFC1274/2247: domain component&#039;&lt;br /&gt;
        EQUALITY caseIgnoreIA5Match&lt;br /&gt;
        SUBSTR caseIgnoreIA5SubstringsMatch&lt;br /&gt;
        SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 SINGLE-VALUE )&lt;br /&gt;
&lt;br /&gt;
attributetype ( 2.5.4.46 NAME &#039;dnQualifier&#039;&lt;br /&gt;
        DESC &#039;RFC2256: DN qualifier&#039;&lt;br /&gt;
        EQUALITY caseIgnoreMatch&lt;br /&gt;
        ORDERING caseIgnoreOrderingMatch&lt;br /&gt;
        SUBSTR caseIgnoreSubstringsMatch&lt;br /&gt;
        SYNTAX 1.3.6.1.4.1.1466.115.121.1.44 )&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* Configure LDAP server&lt;br /&gt;
&lt;br /&gt;
Edit /etc/openldap/slapd.conf:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
include         /etc/openldap/schema/example.com.schema&lt;br /&gt;
pidfile         /var/run/openldap/slapd.pid&lt;br /&gt;
argsfile        /var/run/openldap/slapd.args&lt;br /&gt;
&lt;br /&gt;
TLSCipherSuite HIGH&lt;br /&gt;
TLSCACertificateFile /etc/lighttpd/ca-crt.pem&lt;br /&gt;
TLSCertificateFile /etc/lighttpd/server-bundle.pem&lt;br /&gt;
TLSCertificateKeyFile /etc/lighttpd/server-bundle.pem&lt;br /&gt;
TLSVerifyClient never &lt;br /&gt;
&lt;br /&gt;
# This is needed for proper representation of MD5-CRYPT format stored in database&lt;br /&gt;
#  see more details in http://strugglers.net/~andy/blog/2010/01/23/openldap-and-md5crypt/&lt;br /&gt;
password-hash  {CRYPT}&lt;br /&gt;
password-crypt-salt-format &amp;quot;$1$%.8s&amp;quot;&lt;br /&gt;
&lt;br /&gt;
loglevel        stats&lt;br /&gt;
moduleload	/usr/lib/openldap/back_sql.so&lt;br /&gt;
sizelimit 3000&lt;br /&gt;
&lt;br /&gt;
database        sql&lt;br /&gt;
&lt;br /&gt;
dbname		PostgreSQL&lt;br /&gt;
dbuser		postfix&lt;br /&gt;
dbpasswd	*****&lt;br /&gt;
&lt;br /&gt;
suffix          &amp;quot;dc=example,dc=com&amp;quot;&lt;br /&gt;
rootdn          &amp;quot;cn=admin,dc=example,dc=com&amp;quot;&lt;br /&gt;
rootpw		{MD5}&amp;lt;Hashed password for root dn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
upper_func      &amp;quot;upper&amp;quot;&lt;br /&gt;
strcast_func    &amp;quot;text&amp;quot;&lt;br /&gt;
concat_pattern  &amp;quot;?||?&amp;quot;&lt;br /&gt;
has_ldapinfo_dn_ru      no&lt;br /&gt;
lastmod         off&lt;br /&gt;
&lt;br /&gt;
access to attrs=userPassword by * auth&lt;br /&gt;
&lt;br /&gt;
access to * by peername.ip=127.0.0.1 read&lt;br /&gt;
            ### by peername.ip=&amp;lt;IP&amp;gt;%&amp;lt;netmask&amp;gt; read&lt;br /&gt;
            ### by peername.ip=&amp;lt;IP&amp;gt; read&lt;br /&gt;
	    by users read&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* Set permissions for slapd.conf&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
chown ldap:ldap /etc/openldap/slapd.conf&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* Configure startup parameters to make sure that LDAP server start AFTER PostgreSQL and listens on localhost with clear text and public IP with SSL&lt;br /&gt;
&lt;br /&gt;
Edit /etc/conf.d/slapd:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
echo rc_need=&amp;quot;postgresql&amp;quot; &lt;br /&gt;
OPTS=&amp;quot;-h &#039;ldaps:// ldap://127.0.0.1&#039;&amp;quot;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* Start LDAP server&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
rc-update add slapd default&lt;br /&gt;
/etc/init.d/slapd start&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* Configure LDAP client utilities&lt;br /&gt;
&lt;br /&gt;
Edit /etc/openldap/ldap.conf&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
BASE	dc=example,dc=com&lt;br /&gt;
URI	ldaps://host.example.com&lt;br /&gt;
&lt;br /&gt;
TLS_CACERT /etc/lighttpd/ca-crt.pem&lt;br /&gt;
TLS_CERT /etc/lighttpd/server-bundle.pem&lt;br /&gt;
TLS_KEY /etc/lighttpd/server-bundle.pem&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* Test LDAP server&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
ldapsearch -z 3&lt;br /&gt;
ldapsearch -z 3 -x -W -D cn=admin,dc=example,dc=com&lt;br /&gt;
ldapsearch -z 3 -x -W -D cn=address1,dc=example,dc=com&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* Configure RoundCube webmail for email lookups&lt;br /&gt;
&lt;br /&gt;
Edit /usr/share/webapps/roundcube/config/main.inc.php:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
$rcmail_config[&#039;ldap_debug&#039;] = false;&lt;br /&gt;
...&lt;br /&gt;
$rcmail_config[&#039;address_book_type&#039;] = &#039;ldap&#039;;&lt;br /&gt;
&lt;br /&gt;
$rcmail_config[&#039;ldap_public&#039;][&#039;example.com&#039;] = array(&lt;br /&gt;
  &#039;name&#039;          =&amp;gt; &#039;example.com&#039;,&lt;br /&gt;
  &#039;hosts&#039;         =&amp;gt; array(&#039;127.0.0.1&#039;),&lt;br /&gt;
  &#039;port&#039;          =&amp;gt; 389,&lt;br /&gt;
  &#039;use_tls&#039;         =&amp;gt; false,&lt;br /&gt;
  &#039;user_specific&#039; =&amp;gt; false,&lt;br /&gt;
  &#039;base_dn&#039;       =&amp;gt; &#039;dc=example,dc=com&#039;,&lt;br /&gt;
  &#039;bind_dn&#039;       =&amp;gt; &#039;&#039;,&lt;br /&gt;
  &#039;bind_pass&#039;     =&amp;gt; &#039;&#039;,&lt;br /&gt;
  &#039;writable&#039;      =&amp;gt; false,&lt;br /&gt;
  &#039;LDAP_Object_Classes&#039; =&amp;gt; array(&amp;quot;top&amp;quot;, &amp;quot;exampleBox&amp;quot;),&lt;br /&gt;
  &#039;required_fields&#039;     =&amp;gt; array(&amp;quot;cn&amp;quot;, &amp;quot;sn&amp;quot;, &amp;quot;mail&amp;quot;),&lt;br /&gt;
  &#039;LDAP_rdn&#039;      =&amp;gt; &#039;mail&#039;,&lt;br /&gt;
  &#039;ldap_version&#039;  =&amp;gt; 3,&lt;br /&gt;
  &#039;search_fields&#039; =&amp;gt; array(&#039;mail&#039;, &#039;cn&#039;, &#039;sn&#039;, &#039;givenName&#039;),&lt;br /&gt;
  &#039;name_field&#039;    =&amp;gt; &#039;cn&#039;,&lt;br /&gt;
  &#039;email_field&#039;   =&amp;gt; &#039;mail&#039;,&lt;br /&gt;
  &#039;surname_field&#039; =&amp;gt; &#039;sn&#039;,&lt;br /&gt;
  &#039;firstname_field&#039; =&amp;gt; &#039;gn&#039;,&lt;br /&gt;
  &#039;sort&#039;          =&amp;gt; &#039;cn&#039;,&lt;br /&gt;
  &#039;scope&#039;         =&amp;gt; &#039;sub&#039;,&lt;br /&gt;
  &#039;filter&#039;        =&amp;gt; &#039;(objectClass=*)&#039;, // Construct here any filter you need&lt;br /&gt;
  &#039;fuzzy_search&#039;  =&amp;gt; true);&lt;br /&gt;
&lt;br /&gt;
$rcmail_config[&#039;autocomplete_addressbooks&#039;] = array(&#039;example.com&#039;);&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== log rotation ==&lt;br /&gt;
&lt;br /&gt;
Ensure the busybox cron service is started and is configured to auto-start:&lt;br /&gt;
&lt;br /&gt;
 /etc/init.d/cron start&lt;br /&gt;
 rc-update add cron default&lt;br /&gt;
&lt;br /&gt;
Add log rotate:&lt;br /&gt;
&lt;br /&gt;
 apk add logrotate&lt;br /&gt;
&lt;br /&gt;
Edit &#039;&#039;/etc/logrotate.conf&#039;&#039; as desired, but the defaults should be sufficient for most people.&lt;br /&gt;
&lt;br /&gt;
== Optional: Configure Web Server Virtual Domains ==&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Note:&#039;&#039;&#039; These steps can be done &#039;&#039;instead of&#039;&#039; the default lighttpd configuration above, which allows you to access the ACF, PostfixAdmin and Roundcube interfaces as subfolders of one web service.&lt;br /&gt;
&lt;br /&gt;
This server hosts three separate web applications, and these can be handled as three &#039;&#039;different&#039;&#039; virtual domains on the same web server. They will be distinguished by their DNS names, so you can choose domains for the three separate services (or at least the ones you want to publish):&lt;br /&gt;
&lt;br /&gt;
* ACF - Alpine Configuration Framework for managing the server&lt;br /&gt;
* PostfixAdmin - for managing the postfix installation&lt;br /&gt;
* RoundCube - for accessing individual mailboxes&lt;br /&gt;
&lt;br /&gt;
Choose three different domains (from here on known as ACF_DOMAIN, POSTFIXADMIN_DOMAIN, and ROUNDCUBE_DOMAIN) and configure DNS for all three to point to the IP address of your host. These should be DNS &#039;&#039;&#039;A&#039;&#039;&#039; records.&lt;br /&gt;
&lt;br /&gt;
Then, configure lighttpd to handle the three separate domains by editing /etc/lighttpd/lighttpd.conf:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 $HTTP[&amp;quot;host&amp;quot;] == &amp;quot;ACF_DOMAIN&amp;quot; {&lt;br /&gt;
	simple-vhost.server-root   = &amp;quot;/var/www/domains/&amp;quot;&lt;br /&gt;
	simple-vhost.default-host  = &amp;quot;/ACF_DOMAIN/&amp;quot;&lt;br /&gt;
	simple-vhost.document-root = &amp;quot;www/&amp;quot;&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
 $HTTP[&amp;quot;host&amp;quot;] == &amp;quot;POSTFIXADMIN_DOMAIN&amp;quot; {&lt;br /&gt;
	simple-vhost.server-root   = &amp;quot;/var/www/domains/&amp;quot;&lt;br /&gt;
	simple-vhost.default-host  = &amp;quot;/POSTFIXADMIN_DOMAIN/&amp;quot;&lt;br /&gt;
	simple-vhost.document-root = &amp;quot;www/&amp;quot;&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
 $HTTP[&amp;quot;host&amp;quot;] == &amp;quot;ROUNDCUBE_DOMAIN&amp;quot; {&lt;br /&gt;
	simple-vhost.server-root   = &amp;quot;/var/www/domains/&amp;quot;&lt;br /&gt;
	simple-vhost.default-host  = &amp;quot;/ROUNDCUBE_DOMAIN/&amp;quot;&lt;br /&gt;
	simple-vhost.document-root = &amp;quot;www/&amp;quot;&lt;br /&gt;
 }&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
And, then link the appropriate www directories.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  mkdir -p /var/www/domains/ACF_DOMAIN&lt;br /&gt;
  ln -s /usr/share/acf/www /var/www/domains/ACF_DOMAIN/www&lt;br /&gt;
&lt;br /&gt;
  mkdir -p /var/www/domains/POSTFIXADMIN_DOMAIN&lt;br /&gt;
  ln -s /var/www/domains/host.example.com/www/postfixadmin /var/www/domains/POSTFIXADMIN_DOMAIN/www&lt;br /&gt;
&lt;br /&gt;
  mkdir -p /var/www/domains/ROUNDCUBE_DOMAIN&lt;br /&gt;
  ln -s /usr/share/webapps/roundcube /var/www/domains/ROUNDCUBE_DOMAIN/www&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;/div&gt;</summary>
		<author><name>Djhughes</name></author>
	</entry>
	<entry>
		<id>https://wiki.alpinelinux.org/w/index.php?title=ISP_Mail_Server_HowTo&amp;diff=3497</id>
		<title>ISP Mail Server HowTo</title>
		<link rel="alternate" type="text/html" href="https://wiki.alpinelinux.org/w/index.php?title=ISP_Mail_Server_HowTo&amp;diff=3497"/>
		<updated>2010-03-18T09:41:00Z</updated>

		<summary type="html">&lt;p&gt;Djhughes: corrected path&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== A Full Service Mail Server ==&lt;br /&gt;
&lt;br /&gt;
The goal of this document is to describe how to set up postfix, dovecot, clamav, dspam, roundecube, and postfixadmin for a full-featured &amp;quot;ISP&amp;quot; level mail server.&lt;br /&gt;
&lt;br /&gt;
The server must provide:&lt;br /&gt;
&lt;br /&gt;
* multiple virtual domains&lt;br /&gt;
* admins for each domain (to add/remove virtual accounts)&lt;br /&gt;
* Quota support per domain / account&lt;br /&gt;
* downloading email via IMAP / IMAPS / POP3 / POP3S&lt;br /&gt;
* relaying email for authenticated users with TLS or SSL (Submission / SMTPS protocol)&lt;br /&gt;
* Standard filters (virus/spam/rbl/etc)&lt;br /&gt;
* Web mail client&lt;br /&gt;
* Value Add services&lt;br /&gt;
&lt;br /&gt;
== Set up Lighttpd + PHP ==&lt;br /&gt;
&lt;br /&gt;
PostfixAdmin needs php pgpsql and imap modules, so we do it in this step.&lt;br /&gt;
&lt;br /&gt;
  apk add lighttpd php php-pgsql php-imap&lt;br /&gt;
&lt;br /&gt;
Stop and remove mini_httpd, and move ACF to lighttpd;  We are setting this up to be a multi-domain virtual web server (replace host.example.com with the actual domain):&lt;br /&gt;
&lt;br /&gt;
  mkdir -p /var/www/domains/host.example.com/www&lt;br /&gt;
  ln -s /usr/share/acf/www /var/www/domains/host.example.com/www/acf&lt;br /&gt;
&lt;br /&gt;
Edit /var/www/domains/host.example.com/index.html to put a simple redirection page:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;lt;!DOCTYPE HTML PUBLIC &amp;quot;-//W3C//DTD HTML 4.01//EN&amp;quot; &amp;quot;http://www.w3.org/TR/html4/strict.dtd&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;html lang=&amp;quot;en&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;head&amp;gt;&lt;br /&gt;
&amp;lt;meta http-equiv=&amp;quot;Content-Type&amp;quot; content=&amp;quot;text/html; charset=ISO-8859-1&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;title&amp;gt;host.example.com Redirector&amp;lt;/title&amp;gt;&lt;br /&gt;
&amp;lt;/head&amp;gt;&lt;br /&gt;
&amp;lt;body&amp;gt;&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;&amp;lt;a href=&amp;quot;/acf&amp;quot;&amp;gt;ACF&amp;lt;/a&amp;gt;&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;&amp;lt;a href=&amp;quot;/postfixadmin&amp;quot;&amp;gt;PostfixAdmin&amp;lt;/a&amp;gt;&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;&amp;lt;a href=&amp;quot;/roundcube&amp;quot;&amp;gt;Roundcube&amp;lt;/a&amp;gt;&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
&amp;lt;/body&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Edit /etc/lighttpd/mod_cgi.conf to serve haserl files by adding a &amp;quot;&amp;quot; =&amp;gt; &amp;quot;&amp;quot; cgi handler and to treat /acf/cgi-bin as a CGI directory (remove the &#039;^&#039;)&lt;br /&gt;
&lt;br /&gt;
 $HTTP[&amp;quot;url&amp;quot;] =~ &amp;quot;/cgi-bin/&amp;quot; {&lt;br /&gt;
     # disable directory listings&lt;br /&gt;
     dir-listing.activate = &amp;quot;disable&amp;quot;&lt;br /&gt;
     # only allow cgi&#039;s in this directory&lt;br /&gt;
     cgi.assign = (&lt;br /&gt;
 		&amp;quot;.pl&amp;quot;	=&amp;gt;	&amp;quot;/usr/bin/perl&amp;quot;,&lt;br /&gt;
 		&amp;quot;.cgi&amp;quot;	=&amp;gt;	&amp;quot;/usr/bin/perl&amp;quot;,&lt;br /&gt;
 		&amp;quot;&amp;quot; =&amp;gt; &amp;quot;&amp;quot;&lt;br /&gt;
 	)&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
Add these lines to /etc/lighttpd/lighttpd.conf to point to the new document root, and set it up to listen on port 443 (replace &#039;&#039;host.example.com&#039;&#039; with the actual domain and &#039;&#039;ip_address_of_server&#039;&#039; with the actual IP address):&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
simple-vhost.server-root   = &amp;quot;/var/www/domains/&amp;quot;&lt;br /&gt;
simple-vhost.default-host  = &amp;quot;/host.example.com/&amp;quot;&lt;br /&gt;
simple-vhost.document-root = &amp;quot;www/&amp;quot;&lt;br /&gt;
&lt;br /&gt;
$SERVER[&amp;quot;socket&amp;quot;] == &amp;quot;ip_address_of_server:443&amp;quot; {&lt;br /&gt;
ssl.engine    = &amp;quot;enable&amp;quot;&lt;br /&gt;
ssl.pemfile   = &amp;quot;/etc/lighttpd/server-bundle.pem&amp;quot;&lt;br /&gt;
ssl.ca-file   = &amp;quot;/etc/lighttpd/ca-crt.pem&amp;quot;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Ensure that the simple_vhosts module is loaded, as well as the cgi config scripts by uncommenting the following lines in /etc/lighttpd/lighttpd.conf&lt;br /&gt;
&lt;br /&gt;
 server.modules = (&lt;br /&gt;
     #  other modules may be listed&lt;br /&gt;
     &amp;quot;mod_simple_vhost&amp;quot;, &lt;br /&gt;
     #  other modules may be listed&lt;br /&gt;
  .&lt;br /&gt;
  .&lt;br /&gt;
  .&lt;br /&gt;
     include &amp;quot;mod_cgi.conf&amp;quot;&lt;br /&gt;
 &lt;br /&gt;
     include &amp;quot;mod_fastcgi.conf&amp;quot;&lt;br /&gt;
 &lt;br /&gt;
&lt;br /&gt;
Get a web certificate, and install it.  If you want to use a self-signed cert, you can use [[Generating SSL certs with ACF]] or [[Generating SSL certs with ACF 1.9]].  If you create a certificate with ACF, you can create the &amp;quot;server-bundle.pem&amp;quot; and the &amp;quot;ca-crt.pem&amp;quot; file with these commands:&lt;br /&gt;
&lt;br /&gt;
  openssl pkcs12 -nokeys -cacerts -in certificate.pfx  -out /etc/lighttpd/ca-crt.pem&lt;br /&gt;
  openssl pkcs12 -nodes -in certifcate.pfx -out /etc/lighttpd/server-bundle.pem&lt;br /&gt;
  chown root:root /etc/lighttpd/server-bundle.pem&lt;br /&gt;
  chmod 400 /etc/lighttpd/server-bundle.pem&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Note:&#039;&#039;&#039; The server certificate &#039;&#039;and&#039;&#039; key are in the server-bundle.pem file, so it is critical that the file be read-only by user &amp;quot;root&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
 Editme: We should probably only serve ACF to restricted hosts&lt;br /&gt;
&lt;br /&gt;
Stop and remove mini_httpd; start lighttpd, test&lt;br /&gt;
&lt;br /&gt;
  /etc/init.d/mini_httpd stop&lt;br /&gt;
  rc-update del mini_httpd&lt;br /&gt;
  apk del mini_httpd&lt;br /&gt;
  rc-update add lighttpd&lt;br /&gt;
  /etc/init.d/lighttpd start&lt;br /&gt;
&lt;br /&gt;
At this point you should be able to see ACF being served with lighttpd (Note: this will work well with alpine 1.10. With earlier versions there will be problems.)  https://host.example.com/acf/&lt;br /&gt;
&lt;br /&gt;
== Install Postgresql ==&lt;br /&gt;
&lt;br /&gt;
Add and configure postgresql&lt;br /&gt;
&lt;br /&gt;
  apk add acf-postgresql postgresql-client&lt;br /&gt;
  /etc/init.d/postgresql setup&lt;br /&gt;
  /etc/init.d/postgresql start&lt;br /&gt;
  rc-update add postgresql&lt;br /&gt;
&lt;br /&gt;
At this point any user can connect to the sql server with &amp;quot;trust&amp;quot; mechanism.  If you want to enforce password authentication (you probably do) edit /var/lib/postgresql/8.4/data/pg_hba.conf&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
  Editme: What should we recommend?&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Create the postfix database:&lt;br /&gt;
&lt;br /&gt;
  psql -U postgres&lt;br /&gt;
   create user postfix with password &#039;******&#039;;&lt;br /&gt;
   create database postfix owner postfix;&lt;br /&gt;
   \c postfix&lt;br /&gt;
   create language plpgsql;&lt;br /&gt;
   \q&lt;br /&gt;
&lt;br /&gt;
(Of course, use your selected password where ******* is shown above.)&lt;br /&gt;
&lt;br /&gt;
== Install PostfixAdmin ==&lt;br /&gt;
&lt;br /&gt;
We are going to install the postfix admin web front-end before we install the mail server.  This just creates an interface to populate the SQL tables that postfix and dovecot will use.&lt;br /&gt;
&lt;br /&gt;
Download PostfixAdmin from Sourceforge.  When these instructions were written, 2.3 was the current release, so (replace host.example.com with the actual domain):&lt;br /&gt;
 wget http://downloads.sourceforge.net/project/postfixadmin/postfixadmin/postfixadmin_2.3.tar.gz&lt;br /&gt;
 tar zxvf postfixadmin_2.3.tar.gz&lt;br /&gt;
 mkdir -p /var/www/domains/host.example.com/www/postfixadmin&lt;br /&gt;
 mv postfixadmin-2.3/* /var/www/domains/host.example.com/www/postfixadmin&lt;br /&gt;
 rm -rf postfixadmin*&lt;br /&gt;
&lt;br /&gt;
Edit /var/www/domains/host.example.com/www/postfixadmin/config.inc.php and modify at least these lines (replace host.example.com with the actual domain):&lt;br /&gt;
&lt;br /&gt;
 $CONF[&#039;configured&#039;] = true;&lt;br /&gt;
 $CONF[&#039;setup_password&#039;] = &amp;quot;&amp;quot;;  &amp;lt;&amp;lt; Don&#039;t change this yet&lt;br /&gt;
 $CONF[&#039;database_type&#039;] = &#039;pgsql&#039;;&lt;br /&gt;
 $CONF[&#039;database_host&#039;] = &#039;localhost&#039;;&lt;br /&gt;
 $CONF[&#039;database_user&#039;] = &#039;postfix&#039;;&lt;br /&gt;
 $CONF[&#039;database_password&#039;] = &#039;*****&#039;;   &amp;lt;&amp;lt; The password you chose above&lt;br /&gt;
 $CONF[&#039;database_name&#039;] = &#039;postfix&#039;;&lt;br /&gt;
 $CONF[&#039;database_prefix&#039;] = &amp;quot;&amp;quot;;&lt;br /&gt;
 $CONF[&#039;admin_email&#039;] = &#039;you@some.email.com&#039;;  &amp;lt;&amp;lt; Your email address &lt;br /&gt;
 $CONF[&#039;encrypt&#039;] = &#039;md5crypt&#039;;&lt;br /&gt;
 $CONF[&#039;authlib_default_flavor&#039;] = &#039;md5raw&#039;;&lt;br /&gt;
 $CONF[&#039;dovecotpw&#039;] = &amp;quot;/usr/sbin/dovecotpw&amp;quot;;&lt;br /&gt;
 $CONF[&#039;domain_path&#039;] = &#039;YES&#039;;&lt;br /&gt;
 $CONF[&#039;domain_in_mailbox&#039;] = &#039;NO&#039;;&lt;br /&gt;
 $CONF[&#039;aliases&#039;] = &#039;10&#039;;                       &lt;br /&gt;
 $CONF[&#039;mailboxes&#039;] = &#039;10&#039;;&lt;br /&gt;
 $CONF[&#039;maxquota&#039;] = &#039;10&#039;;&lt;br /&gt;
 $CONF[&#039;quota&#039;] = &#039;YES&#039;;&lt;br /&gt;
 $CONF[&#039;quota_multiplier&#039;] = &#039;1024000&#039;;&lt;br /&gt;
 $CONF[&#039;vacation&#039;] = &#039;NO&#039;; &lt;br /&gt;
 $CONF[&#039;vacation_control&#039;] =&#039;NO&#039;;&lt;br /&gt;
 $CONF[&#039;vacation_control_admin&#039;] = &#039;NO&#039;;&lt;br /&gt;
 $CONF[&#039;alias_control&#039;] = &#039;YES&#039;;&lt;br /&gt;
 $CONF[&#039;alias_control_admin&#039;] = &#039;YES&#039;;&lt;br /&gt;
 $CONF[&#039;special_alias_control&#039;] = &#039;YES&#039;;&lt;br /&gt;
 $CONF[&#039;fetchmail&#039;] = &#039;NO&#039;;&lt;br /&gt;
 $CONF[&#039;user_footer_link&#039;] = &amp;quot;http://host.example.com/postfixadmin&amp;quot;;&lt;br /&gt;
 $CONF[&#039;footer_link&#039;] = &#039;http://host.example.com/postfixadmin/main.php&#039;;&lt;br /&gt;
 $CONF[&#039;create_mailbox_subdirs_prefix&#039;]=&amp;quot;&amp;quot;;  &lt;br /&gt;
 $CONF[&#039;used_quotas&#039;] = &#039;YES&#039;;   &lt;br /&gt;
 $CONF[&#039;new_quota_table&#039;] = &#039;YES&#039;;  &lt;br /&gt;
&lt;br /&gt;
You should further edit /var/www/domains/host.example.com/www/postfixadmin/config.inc.php and replace all instances of &amp;quot;change-this-to-your.domain.tld&amp;quot; with your actual mail domain. This can be done with busybox sed (replace example.com with your domain name):&lt;br /&gt;
&lt;br /&gt;
 sed -i -e &#039;s/change-this-to-your.domain.tld/example.com/g&#039; /var/www/domains/host.example.com/www/postfixadmin/config.inc.php&lt;br /&gt;
&lt;br /&gt;
Go to http://host.example.com/postfixadmin/setup.php&lt;br /&gt;
&lt;br /&gt;
Create the password hash, add it to the config.inc.php file&lt;br /&gt;
&lt;br /&gt;
Go back to http://host.example.com/postfixadmin/setup.php&lt;br /&gt;
&lt;br /&gt;
Create superadmin account.&lt;br /&gt;
&lt;br /&gt;
== Install Postfix ==&lt;br /&gt;
&lt;br /&gt;
Create a user for the virtual mail delivery, and get its uid/gid (you&#039;ll need the numeric uid/gid for postfix)&lt;br /&gt;
&lt;br /&gt;
 adduser vmail -H -D -s /bin/false&lt;br /&gt;
 grep vmail /etc/passwd&lt;br /&gt;
&lt;br /&gt;
(In examples below, we use 1006/1006 for the uid/gid)&lt;br /&gt;
&lt;br /&gt;
Create the mail directory, and assign vmail as the owner&lt;br /&gt;
 mkdir -p /var/mail/domains&lt;br /&gt;
 chown -R vmail:vmail /var/mail/domains&lt;br /&gt;
 &lt;br /&gt;
&lt;br /&gt;
Install postfix&lt;br /&gt;
&lt;br /&gt;
 apk add acf-postfix postfix-pgsql&lt;br /&gt;
&lt;br /&gt;
Edit the /etc/postfix/main.cf file. Here&#039;s an example (don&#039;t forget to replace the uid/gid):&lt;br /&gt;
&lt;br /&gt;
 myhostname=host.example.com&lt;br /&gt;
 mydomain=example.com&lt;br /&gt;
 &lt;br /&gt;
 mydestination = localhost.$mydomain, localhost&lt;br /&gt;
 mynetworks_style = subnet&lt;br /&gt;
 mynetworks = 127.0.0.0/8&lt;br /&gt;
 &lt;br /&gt;
 virtual_mailbox_domains = proxy:pgsql:/etc/postfix/sql/pgsql_virtual_domains_maps.cf&lt;br /&gt;
 virtual_alias_maps = proxy:pgsql:/etc/postfix/sql/pgsql_virtual_alias_maps.cf,&lt;br /&gt;
        proxy:pgsql:/etc/postfix/sql/pgsql_virtual_alias_domain_maps.cf,&lt;br /&gt;
        proxy:pgsql:/etc/postfix/sql/pgsql_virtual_alias_domain_catchall_maps.cf&lt;br /&gt;
 &lt;br /&gt;
 virtual_mailbox_maps = proxy:pgsql:/etc/postfix/sql/pgsql_virtual_mailbox_maps.cf,&lt;br /&gt;
        proxy:pgsql:/etc/postfix/sql/pgsql_virtual_alias_domain_mailbox_maps.cf&lt;br /&gt;
 &lt;br /&gt;
 virtual_mailbox_base = /var/mail/domains/&lt;br /&gt;
 virtual_gid_maps = static:1006&lt;br /&gt;
 virtual_uid_maps = static:1006&lt;br /&gt;
 virtual_minimum_uid = 100&lt;br /&gt;
 virtual_transport = virtual&lt;br /&gt;
 &lt;br /&gt;
 &lt;br /&gt;
 # This next command means you must create a virtual&lt;br /&gt;
 # domain for the host itself - ALL mail goes through&lt;br /&gt;
 # The virtual transport&lt;br /&gt;
 &lt;br /&gt;
 mailbox_transport = virtual&lt;br /&gt;
 local_transport = virtual&lt;br /&gt;
 local_transport_maps = $virtual_mailbox_maps&lt;br /&gt;
 &lt;br /&gt;
 smtpd_helo_required = yes&lt;br /&gt;
 disable_vrfy_command = yes&lt;br /&gt;
 message_size_limit = 10240000&lt;br /&gt;
 queue_minfree = 51200000&lt;br /&gt;
 &lt;br /&gt;
 smtpd_sender_restrictions =&lt;br /&gt;
        permit_mynetworks,&lt;br /&gt;
        reject_non_fqdn_sender,&lt;br /&gt;
        reject_unknown_sender_domain&lt;br /&gt;
 &lt;br /&gt;
 smtpd_recipient_restrictions =&lt;br /&gt;
        reject_non_fqdn_recipient,&lt;br /&gt;
        reject_unknown_recipient_domain,&lt;br /&gt;
        permit_mynetworks,&lt;br /&gt;
        permit_sasl_authenticated,&lt;br /&gt;
        reject_unauth_destination,&lt;br /&gt;
        reject_rbl_client dnsbl.sorbs.net,&lt;br /&gt;
        reject_rbl_client zen.spamhaus.org,&lt;br /&gt;
        reject_rbl_client bl.spamcop.net&lt;br /&gt;
 &lt;br /&gt;
 smtpd_data_restrictions = reject_unauth_pipelining&lt;br /&gt;
 &lt;br /&gt;
 # we will use this later - This prevents cleartext authentication&lt;br /&gt;
 # for relaying&lt;br /&gt;
 smtpd_tls_auth_only = yes&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Now we need to create a *bunch* of files so that postfix can get the delivery information out of sql. Here&#039;s a shell script to create the scripts.  Change PGPW to the password for the postfix user of the postfix SQL database.&lt;br /&gt;
&lt;br /&gt;
 cd /etc/postfix&lt;br /&gt;
 mkdir sql&lt;br /&gt;
 PGPW=&amp;quot;ChangeMe&amp;quot;&lt;br /&gt;
 &lt;br /&gt;
 cat - &amp;lt;&amp;lt;EOF &amp;gt;sql/pgsql_virtual_alias_domain_catchall_maps.cf&lt;br /&gt;
 user=postfix&lt;br /&gt;
 password = $PGPW&lt;br /&gt;
 hosts = localhost&lt;br /&gt;
 dbname = postfix&lt;br /&gt;
 query = Select goto From alias,alias_domain where alias_domain.alias_domain = &#039;%d&#039; and alias.address = &#039;@&#039; ||  alias_domain.target_domain and alias.active = true and alias_domain.active= true &lt;br /&gt;
 EOF&lt;br /&gt;
 &lt;br /&gt;
 cat - &amp;lt;&amp;lt;EOF &amp;gt;sql/pgsql_virtual_alias_domain_mailbox_maps.cf&lt;br /&gt;
 user=postfix&lt;br /&gt;
 password = $PGPW&lt;br /&gt;
 hosts = localhost&lt;br /&gt;
 dbname = postfix&lt;br /&gt;
 query = Select maildir from mailbox,alias_domain where alias_domain.alias_domain = &#039;%d&#039; and mailbox.username = &#039;%u&#039; || &#039;@&#039; || alias_domain.target_domain and mailbox.active = true and alias_domain.active&lt;br /&gt;
 EOF&lt;br /&gt;
 &lt;br /&gt;
 cat - &amp;lt;&amp;lt;EOF &amp;gt;sql/pgsql_virtual_alias_domain_maps.cf&lt;br /&gt;
 user=postfix&lt;br /&gt;
 password = $PGPW&lt;br /&gt;
 hosts = localhost&lt;br /&gt;
 dbname = postfix&lt;br /&gt;
 query = select goto from alias,alias_domain where alias_domain.alias_domain=&#039;%d&#039; and alias.address = &#039;%u&#039; || &#039;@&#039; || alias_domain.target_domain and alias.active= true and alias_domain.active= true&lt;br /&gt;
 EOF&lt;br /&gt;
 &lt;br /&gt;
 cat - &amp;lt;&amp;lt;EOF &amp;gt;sql/pgsql_virtual_alias_maps.cf&lt;br /&gt;
 user=postfix&lt;br /&gt;
 password = $PGPW&lt;br /&gt;
 hosts = localhost&lt;br /&gt;
 dbname = postfix&lt;br /&gt;
 query = Select goto From alias Where address=&#039;%s&#039; and active =&#039;1&#039;&lt;br /&gt;
 EOF&lt;br /&gt;
 &lt;br /&gt;
 cat - &amp;lt;&amp;lt;EOF &amp;gt;sql/pgsql_virtual_domains_maps.cf&lt;br /&gt;
 user=postfix&lt;br /&gt;
 password = $PGPW&lt;br /&gt;
 hosts = localhost&lt;br /&gt;
 dbname = postfix&lt;br /&gt;
 query = Select domain from domain where domain=&#039;%s&#039; and active=&#039;1&#039;&lt;br /&gt;
 EOF&lt;br /&gt;
 &lt;br /&gt;
 cat - &amp;lt;&amp;lt;EOF &amp;gt;sql/pgsql_virtual_mailbox_maps.cf&lt;br /&gt;
 user=postfix&lt;br /&gt;
 password = $PGPW&lt;br /&gt;
 hosts = localhost&lt;br /&gt;
 dbname = postfix&lt;br /&gt;
 query = Select maildir from mailbox where username=&#039;%s&#039; and active=true&lt;br /&gt;
 EOF&lt;br /&gt;
 &lt;br /&gt;
 chown -R postfix:postfix sql&lt;br /&gt;
 chmod 640 sql/*&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
At this point you should be able to start up postfix&lt;br /&gt;
 &lt;br /&gt;
 newaliases  # so postfix is happy...&lt;br /&gt;
 /etc/init.d/postfix start&lt;br /&gt;
 rc-update add postfix&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Create a domain in PostfixAdmin and test ===&lt;br /&gt;
&lt;br /&gt;
Go to http://host.example.com/postfixadmin/&lt;br /&gt;
&lt;br /&gt;
Log in using the superadmin account, create a domain for the local box (e.g. example.com), and create a user mailbox (e.g. root).&lt;br /&gt;
&lt;br /&gt;
From the machine, send a test message:&lt;br /&gt;
&lt;br /&gt;
 sendmail -t root@example.com&lt;br /&gt;
 subject: test&lt;br /&gt;
 .&lt;br /&gt;
 ^d&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
In /var/log/mail.log (or /var/log/messages, if you still have busybox syslogd running) you should see the message queued.  The message should be in /var/mail/domains/example.com/root/new&lt;br /&gt;
&lt;br /&gt;
== Install Dovecot ==&lt;br /&gt;
&lt;br /&gt;
Dovecot is the POP3/IMAP server to retrieve mail.&lt;br /&gt;
&lt;br /&gt;
As before, we install dovecot: &lt;br /&gt;
&lt;br /&gt;
 apk add acf-dovecot dovecot-pgsql&lt;br /&gt;
&lt;br /&gt;
edit /etc/dovecot/dovecot.conf&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 # Select only the protocols you wish to support - all are listed in the next line&lt;br /&gt;
 protocols               =       imap imaps pop pop3s&lt;br /&gt;
 log_path                =       /var/log/dovecot.log&lt;br /&gt;
 info_log_path           =       /var/log/dovecot-info.log&lt;br /&gt;
 disable_plaintext_auth  =       no&lt;br /&gt;
&lt;br /&gt;
 # Authenticated IMAP&lt;br /&gt;
 ssl                     =       yes&lt;br /&gt;
 ssl_cert_file           =       /etc/lighttpd/server-bundle.pem&lt;br /&gt;
 ssl_key_file            =       /etc/lighttpd/server-bundle.pem&lt;br /&gt;
 auth_verbose            =       yes&lt;br /&gt;
 auth_debug              =       no&lt;br /&gt;
 mail_location           =       maildir:/var/mail/domains/%d/%n&lt;br /&gt;
 auth default    {&lt;br /&gt;
        mechanisms = plain&lt;br /&gt;
        passdb sql {&lt;br /&gt;
                args = /etc/dovecot/dovecot-sql.conf&lt;br /&gt;
                }&lt;br /&gt;
        userdb static {&lt;br /&gt;
                args =  uid=1006 gid=1006 home=/var/mail/domains/%d/%n&lt;br /&gt;
                }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Be sure to replace the uid and gid with the appropriate values for the vmail user.&lt;br /&gt;
&lt;br /&gt;
We need a certificate for SSL/TLS authentication, so in the example above, we use the lighttpd cert. That way when the cert is renewed/replaced, Dovecot will have access to the new cert as well.  &lt;br /&gt;
&lt;br /&gt;
Create the /etc/dovecot/dovecot-sql.conf file:&lt;br /&gt;
&lt;br /&gt;
 driver = pgsql&lt;br /&gt;
 connect = host=localhost dbname=postfix user=postfix password=********&lt;br /&gt;
 password_query = select username,password from mailbox where local_part = &#039;%n&#039; and domain = &#039;%d&#039;&lt;br /&gt;
 default_pass_scheme =  MD5-CRYPT&lt;br /&gt;
&lt;br /&gt;
Again, change the password above to your postfix user password, and protect the file from prying eyes:&lt;br /&gt;
&lt;br /&gt;
 chown root:root /etc/dovecot/dovecot-sql.conf&lt;br /&gt;
 chmod 600 /etc/dovecot/dovecot-sql.conf&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Start dovecot&lt;br /&gt;
 /etc/init.d/dovecot start&lt;br /&gt;
 rc-update add dovecot&lt;br /&gt;
&lt;br /&gt;
== Testing ==&lt;br /&gt;
&lt;br /&gt;
Make sure your firewall allows in ports 25(SMTP) 110 (POP3), 995 (POP3S), 143(IMAP), 993(IMAPS), or whatever subset you support.  &lt;br /&gt;
 &lt;br /&gt;
At this point, you should be able to:&lt;br /&gt;
 * Create a new domain and add users with PostfixAdmin&lt;br /&gt;
 * Send mail to those users via SMTP to port 25&lt;br /&gt;
 * Retrieve mail using the user&#039;s full email and password (e.g. username: user@example.com  password: ChangeMe)&lt;br /&gt;
&lt;br /&gt;
== Value Add Features ==&lt;br /&gt;
&lt;br /&gt;
If you followed the guide above, you now have a functional mail server with many interconnected parts.  The features below assume that the server is already running as described above.  You should be able to add any or all of these features below to further enhance the mail service.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Virus Scanning ===&lt;br /&gt;
&lt;br /&gt;
This procedure uses clamav and the postfix content_filter mechanism to scan inbound and outbound email for viruses.  Infected emails are dropped.  Clean emails are tagged with a &amp;quot;scanned by clamav&amp;quot; header.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* Install clamav and clamsmtp:&lt;br /&gt;
 apk add acf-clamav clamsmtp&lt;br /&gt;
* Edit the /etc/clamav/clamd.conf file if desired (not necessary in most cases)&lt;br /&gt;
* Edit /etc/clamsmtpd.conf and verify the following lines&lt;br /&gt;
 OutAddress: 10026&lt;br /&gt;
 Listen: 127.0.0.1:10025                                               &lt;br /&gt;
 Header: X-Virus-Scanned: ClamAV using ClamSMTP&lt;br /&gt;
 Action: drop&lt;br /&gt;
 User: clamav                                                      &lt;br /&gt;
* Start the daemons&lt;br /&gt;
 rc-update add clamd&lt;br /&gt;
 rc-update add clamsmtpd&lt;br /&gt;
 /etc/init.d/clamd start&lt;br /&gt;
 /etc/init.d/clamsmtpd start&lt;br /&gt;
* Verify clamsmtp is listening on port 10025:&lt;br /&gt;
 netstat -anp | grep clamsmtp&lt;br /&gt;
* [http://memberwebs.com/stef/software/clamsmtp/postfix.html Following the clamsmtp instructions]&lt;br /&gt;
** edit /etc/postfix/main.cf and add:&lt;br /&gt;
 content_filter = scan:[127.0.0.1]:10025                                                      &lt;br /&gt;
** edit /etc/postfix/master.cf and add&lt;br /&gt;
 # AV scan filter (used by content_filter)&lt;br /&gt;
 scan      unix  -       -       n       -       16      smtp&lt;br /&gt;
         -o smtp_send_xforward_command=yes&lt;br /&gt;
         -o smtp_enforce_tls=no&lt;br /&gt;
 # For injecting mail back into postfix from the filter&lt;br /&gt;
 127.0.0.1:10026 inet  n -       n       -       16      smtpd&lt;br /&gt;
         -o content_filter=&lt;br /&gt;
         -o receive_override_options=no_unknown_recipient_checks,no_header_body_checks&lt;br /&gt;
         -o smtpd_helo_restrictions=&lt;br /&gt;
         -o smtpd_client_restrictions=&lt;br /&gt;
         -o smtpd_sender_restrictions=&lt;br /&gt;
         -o smtpd_recipient_restrictions=permit_mynetworks,reject&lt;br /&gt;
         -o mynetworks_style=host&lt;br /&gt;
         -o smtpd_authorized_xforward_hosts=127.0.0.0/8&lt;br /&gt;
* postfix reload&lt;br /&gt;
* Send and email into a local virtual domain - it should have the &#039;&#039;X-Virus-Scanned: ClamAV using ClamSMTP&#039;&#039; header.&lt;br /&gt;
&lt;br /&gt;
=== Relay for Authenticated Users ===&lt;br /&gt;
&lt;br /&gt;
As configured above, the mail server accepts email from the Internet, but it does not relay email.  If it is a perimeter exchanger for a protected network, then you can add the protected networks to the &#039;&#039;mynetworks&#039;&#039; configuration line in /etc/postfix/main.cf&lt;br /&gt;
&lt;br /&gt;
This configuration change allows &#039;&#039;remote&#039;&#039; users to authenticate against the mail server and relay through it.  The rules for relaying are:&lt;br /&gt;
* Only authenticated users can relay&lt;br /&gt;
* Authentication Credentials must be encrypted with TLS or SSL&lt;br /&gt;
* Allow Submission and SMTPS ports for relaying (many consumer networks block port 25 - SMTP by default)&lt;br /&gt;
The process uses the dovecot authentication mechanism (used with IMAPS) to authenticate users before they are allowed to relay through postfix.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* Edit /etc/dovecot/dovecot.conf and add:&lt;br /&gt;
 # this is for postfix SASL (authenticated users can relay through us)&lt;br /&gt;
 socket listen {&lt;br /&gt;
                client {&lt;br /&gt;
                        path    = /var/spool/postfix/private/dovecot-auth.sock&lt;br /&gt;
                        mode    = 0660&lt;br /&gt;
                        user    = postfix&lt;br /&gt;
                        group   = postfix&lt;br /&gt;
                        }&lt;br /&gt;
                }&lt;br /&gt;
        }&lt;br /&gt;
* Restart dovecot&lt;br /&gt;
 /etc/init.d/dovecot restart&lt;br /&gt;
* Edit /etc/postfix/main.cf and add:&lt;br /&gt;
 # TLS Stuff -- since we allow SASL with tls *only*, we have to set up TLS first                    &lt;br /&gt;
 &lt;br /&gt;
 smtpd_tls_cert_file = /etc/lighttpd/server-bundle.pem&lt;br /&gt;
 smtpd_tls_key_file = /etc/lighttpd/server-bundle.pem&lt;br /&gt;
 smtpd_tls_CAfile = /etc/lighttpd/ca-crt.pem&lt;br /&gt;
 # If tls_security_level is set to &amp;quot;encrypt&amp;quot;, then SMTP rejects &lt;br /&gt;
 # unencrypted email (e.g. normal mail) which is bad.&lt;br /&gt;
 # By setting it to &amp;quot;may&amp;quot; you get TLS encrypted mail from google, slashdot, and other &lt;br /&gt;
 # interesting places.  Check your logs to see who&lt;br /&gt;
 smtpd_tls_security_level = may&lt;br /&gt;
 # Log info about the negotiated encryption levels&lt;br /&gt;
 smtpd_tls_received_header = yes&lt;br /&gt;
 smtpd_tls_loglevel = 1&lt;br /&gt;
 &lt;br /&gt;
 # SASL - this allows senders to authenticiate themselves&lt;br /&gt;
 # This along with &amp;quot;permit_sasl_authenticated&amp;quot; in smtpd_recipient_restrictions allows relaying&lt;br /&gt;
 smtpd_sasl_type = dovecot&lt;br /&gt;
 smtpd_sasl_path = private/dovecot-auth.sock&lt;br /&gt;
 smtpd_sasl_auth_enable = yes&lt;br /&gt;
 smtpd_sasl_authenticated_header = yes&lt;br /&gt;
 smtpd_tls_auth_only = yes&lt;br /&gt;
* Edit /etc/postfix/master.cf and enable the submission and smtps transports.  They are probably already at the top of your  master.cf file, just commented out:&lt;br /&gt;
 submission inet n       -       n       -       -       smtpd&lt;br /&gt;
   -o smtpd_tls_security_level=encrypt&lt;br /&gt;
   -o smtpd_sasl_auth_enable=yes&lt;br /&gt;
   -o smtpd_client_restrictions=permit_sasl_authenticated,reject&lt;br /&gt;
   -o milter_macro_daemon_name=ORIGINATING&lt;br /&gt;
 smtps     inet  n       -       n       -       -       smtpd&lt;br /&gt;
   -o smtpd_tls_security_level=encrypt&lt;br /&gt;
   -o smtpd_tls_wrappermode=yes&lt;br /&gt;
   -o smtpd_sasl_auth_enable=yes&lt;br /&gt;
   -o smtpd_client_restrictions=permit_sasl_authenticated,reject&lt;br /&gt;
   -o milter_macro_daemon_name=ORIGINATING&lt;br /&gt;
*Verfiy submission and smtps are defined in /etc/services&lt;br /&gt;
 grep &amp;quot;submission\|ssmtp&amp;quot; /etc/services&lt;br /&gt;
 submission	587/tcp				# mail message submission&lt;br /&gt;
 submission	587/udp&lt;br /&gt;
 smtps		465/tcp		ssmtp		# smtp protocol over TLS/SSL&lt;br /&gt;
 smtps		465/udp		ssmtp&lt;br /&gt;
* Restart postfix&lt;br /&gt;
 postfix reload&lt;br /&gt;
&lt;br /&gt;
At this point, you should be able to set up a mail client to relay through the server with TLS (port 587) or SSL (port 465)  Note that &amp;quot;plain&amp;quot; authentication is used because the underlying link is encrypted.  For example, in Thunderbird leave &amp;quot;secure authentication&amp;quot; unchecked, and choose STARTTLS (or TLS) for the connection security.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Mailbox Quotas ===&lt;br /&gt;
&lt;br /&gt;
In the default configuration, PostfixAdmin knows about quotas, but they are not enforced.   Documentation on the web mentions the [http://vda.sourceforge.net vda patch to postfix] to enforce quotas.  The only bad thing... its a &#039;&#039;patch&#039;&#039;.   Postfix and Dovecot are both conservative systems, so if the patch isn&#039;t in the upstream source, we&#039;ll assume there&#039;s a good reason.   There is a way of using quotas without patches - and it involves using dovecot&#039;s [http://wiki.dovecot.org/LDA deliver] lda for local delivery.&lt;br /&gt;
&lt;br /&gt;
Note: As of Jan 2010, the documention is confusing, with multiple versions of dovecot, PostfixAdmin, and Mysql referenced.  These instructions apply to:&lt;br /&gt;
* Postgresql 8.4.2 &lt;br /&gt;
* PostfixAdmin 2.3 &lt;br /&gt;
* Dovecot 1.2.10&lt;br /&gt;
* Postfix 2.6.5&lt;br /&gt;
&lt;br /&gt;
Presumably later versions will work the same, but if not, please update the documentation and versions above.&lt;br /&gt;
&lt;br /&gt;
* Update /etc/dovecot/dovecot.conf (old lines shown commented out):&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
# old postfix &lt;br /&gt;
#       userdb static {&lt;br /&gt;
#               args =  uid=1006 gid=1006 home=/var/mail/domains/%d/%n&lt;br /&gt;
#               }&lt;br /&gt;
&lt;br /&gt;
# new quota support:&lt;br /&gt;
        userdb prefetch {&lt;br /&gt;
                }&lt;br /&gt;
&lt;br /&gt;
        userdb sql {&lt;br /&gt;
                args = /etc/dovecot/dovecot-sql.conf&lt;br /&gt;
                }&lt;br /&gt;
&lt;br /&gt;
        socket listen {&lt;br /&gt;
                client {&lt;br /&gt;
                        path    = /var/spool/postfix/private/dovecot-auth.sock&lt;br /&gt;
                        mode    = 0660&lt;br /&gt;
                        user    = postfix&lt;br /&gt;
                        group   = postfix&lt;br /&gt;
                        }&lt;br /&gt;
                # These lines below are for the deliver lda&lt;br /&gt;
                master {&lt;br /&gt;
                        path =  /var/run/dovecot/auth-master&lt;br /&gt;
                        mode    = 0660&lt;br /&gt;
                        user    = vmail&lt;br /&gt;
                        group   = vmail&lt;br /&gt;
                        }&lt;br /&gt;
                }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
protocol imap {                                                               &lt;br /&gt;
         mail_plugins = quota imap_quota                                       &lt;br /&gt;
         }                                                                     &lt;br /&gt;
                                                                              &lt;br /&gt;
protocol pop3 {                                                               &lt;br /&gt;
         mail_plugins = quota                                                  &lt;br /&gt;
         }                                                                     &lt;br /&gt;
                                                                              &lt;br /&gt;
dict {                                                                        &lt;br /&gt;
        quotadict = pgsql:/etc/dovecot/dovecot-dict-quota.conf                &lt;br /&gt;
        }                                                                     &lt;br /&gt;
                                                                              &lt;br /&gt;
plugin {                                                                      &lt;br /&gt;
         quota = dict:user::proxy::quotadict                                   &lt;br /&gt;
         }                                                     &lt;br /&gt;
                                                              &lt;br /&gt;
protocol lda {                                                &lt;br /&gt;
   postmaster_address = postmaster@host.example.com&lt;br /&gt;
   mail_plugins = quota                                        &lt;br /&gt;
   auth_socket_path =  /var/run/dovecot/auth-master&lt;br /&gt;
   sendmail_path = /usr/sbin/sendmail&lt;br /&gt;
}                                                                            &lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
 &lt;br /&gt;
You should already have a &amp;lt;tt&amp;gt;socket-&amp;gt; listen-&amp;gt; client&amp;lt;/tt&amp;gt; section, but it is listed above to show where it goes in relationship to the &amp;lt;tt&amp;gt;socket -&amp;gt; listen -&amp;gt; master&amp;lt;/tt&amp;gt; section&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* edit &amp;lt;tt&amp;gt;/etc/dovecot/dovecot-sql.conf&amp;lt;/tt&amp;gt; and replace the user and password queries with the following (you may not have a user_query yet - add it):&lt;br /&gt;
&lt;br /&gt;
 password_query = select username as user, password, 1006 as userdb_uid, 1006 as userdb_gid, &#039;*:bytes=&#039; || quota as userdb_quota_rule from mailbox  where local_part = &#039;%n&#039; and domain = &#039;%d&#039;&lt;br /&gt;
 user_query = select maildir as home, 1006 as uid, 1006 as gid, &#039;*:bytes=&#039; || quota  as quota_rule from mailbox where local_part = &#039;%n&#039; and domain =&#039;%d&#039;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* create &amp;lt;tt&amp;gt;/etc/dovecot/dovecot-dict-quota.conf&amp;lt;/tt&amp;gt;&lt;br /&gt;
 connect = host=localhost dbname=postfix user=postfix password=********&lt;br /&gt;
 &lt;br /&gt;
 map {&lt;br /&gt;
         pattern = priv/quota/storage&lt;br /&gt;
         table = quota2&lt;br /&gt;
         username_field =username&lt;br /&gt;
         value_field = bytes&lt;br /&gt;
 }&lt;br /&gt;
 &lt;br /&gt;
 map {&lt;br /&gt;
        pattern= priv/quota/messages&lt;br /&gt;
        table = quota2&lt;br /&gt;
        username_field = username&lt;br /&gt;
        value_field = messages&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
Side note: [http://wiki.dovecot.org/Quota/Dict The Dovecot Quota Documentation] mentions the need for a trigger with pgsql.  This was created in the PostfixAdmin install, which is why you instantiated the pgsql language when creating the database.  If not, you will need to create the trigger, to reference the quota2 table, not the quota table mentioned in the dovecot docs.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* create a new transport for the dovecot lda.   Add the following to  /etc/postfix/master.cf:&lt;br /&gt;
 # The dovecot deliver lda&lt;br /&gt;
 dovecot   unix  -       n       n       -       -       pipe&lt;br /&gt;
   flags=DRhu user=vmail:vmail argv=/usr/libexec/dovecot/deliver -f ${sender} -d ${user}@${nexthop}&lt;br /&gt;
&lt;br /&gt;
* Edit the /etc/postfix/main.cf.  Replace &lt;br /&gt;
 virtual_transport = virtual &lt;br /&gt;
with&lt;br /&gt;
 virtual_transport = dovecot&lt;br /&gt;
 dovecot_destination_recipient_limit = 1&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;TODO&#039;&#039;&#039;  This will cause over-quota emails to bounce.   Which could be a source of backscatter.   We need a way of checking quota limits after RBL checking but before the message is accepted in the queue.&lt;br /&gt;
&lt;br /&gt;
=== WebMail (RoundCube) ===&lt;br /&gt;
&lt;br /&gt;
[http://roundcube.net/ RoundCube] is an &amp;quot;ajax /Web2.0&amp;quot; web-mail client.  These instructions are for the Alpine Linux 1.10 repository &lt;br /&gt;
&lt;br /&gt;
* Add the package and related php modules:&lt;br /&gt;
 apk add roundcubemail php-xml php-openssl php-mcrypt php-gd php-iconv&lt;br /&gt;
&lt;br /&gt;
* link the roundcube application back into the docroot&lt;br /&gt;
 ln -s /usr/share/webapps/roundcube /var/www/domains/host.example.com/www/roundcube&lt;br /&gt;
&lt;br /&gt;
* follow the instructions in /usr/share/webapps/roundcube/INSTALL:&lt;br /&gt;
 cd /usr/share/webapps/roundcube&lt;br /&gt;
 chown -R lighttpd:lighttpd temp logs&lt;br /&gt;
 &lt;br /&gt;
 su postgres&lt;br /&gt;
 createuser roundcube&lt;br /&gt;
   Shall the new role be a superuser? (y/n) n&lt;br /&gt;
   Shall the new role be allowed to create databases? (y/n) n&lt;br /&gt;
   Shall the new role be allowed to create more new roles? (y/n) y&lt;br /&gt;
 createdb -O roundcube -E UNICODE -T template0 roundcubemail&lt;br /&gt;
 psql roundcubemail&lt;br /&gt;
   roundcubemail=# ALTER USER roundcube WITH PASSWORD &#039;the_new_password&#039;;&lt;br /&gt;
   roundcubemail=# \c - roundcube&lt;br /&gt;
   roundcubemail=&amp;gt; \i /usr/share/webapps/roundcube/SQL/postgres.initial.sql&lt;br /&gt;
   roundcubemail=&amp;gt; \q&lt;br /&gt;
 exit&lt;br /&gt;
&lt;br /&gt;
* edit /etc/php/php.ini and set date.timezone to your local timezone, or to UTC&lt;br /&gt;
&lt;br /&gt;
* restart lighttpd to verify the new php libraries are used&lt;br /&gt;
 /etc/init.d/lighttpd restart&lt;br /&gt;
&lt;br /&gt;
* Point your browser to http://host.example.com/roundcube/installer&lt;br /&gt;
* Start installation&lt;br /&gt;
&lt;br /&gt;
For the specific configuration parameters in the install step:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!Property&lt;br /&gt;
!Setting&lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;enable_spellcheck&#039;&#039; ||   disabled &lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;identities_level&#039;&#039; ||  one identity with possibility to edit all params but not email address &lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;log driver&#039;&#039; || syslog &lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;sylog_id&#039;&#039; || roundcube &lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;syslog_facility&#039;&#039; || mailsubsystem &lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;db_dnsw&#039;&#039; || pgsql properties, as described above &lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;imap_host&#039;&#039; || 127.0.0.1 &lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;auto_create_user&#039;&#039; || enabled &lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;smtp_server&#039;&#039; ||  127.0.0.1&lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;smtp_port&#039;&#039; ||  25&lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;smtp_user/smtp_pass&#039;&#039; ||  enable &#039;&#039;Use Current IMAP username and password for SMTP authentication&#039;&#039;&lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;smtp_log&#039;&#039; ||  enable (optional, but gives additional log record)&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
The other items can be left at default settings, or adjusted if desired.&lt;br /&gt;
&lt;br /&gt;
* Follow the instructions in step 3 of the install to copy the files to the server&lt;br /&gt;
* You should now be able to get to roundcube at http://host.example.com/roundcube&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
After its working, the INSTALL file recommends removing the install directory.   If you want to keep the installer around later, you can simply change the ownership and permissions.  So do &#039;&#039;&#039;one&#039;&#039;&#039; of the following:&lt;br /&gt;
 cd /usr/share/webapps/roundcube&lt;br /&gt;
 rm -rf LICENSE UPGRADING INSTALL README CHANGELOG  SQL installer&lt;br /&gt;
or&lt;br /&gt;
 cd /usr/share/webapps/roundcube&lt;br /&gt;
 chown -R root:root LICENSE UPGRADING INSTALL README CHANGELOG  SQL installer&lt;br /&gt;
 chmod -R 600 LICENSE UPGRADING INSTALL README CHANGELOG SQL &lt;br /&gt;
 chmod 700 SQL installer&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== OpenLDAP based Address Book ===&lt;br /&gt;
&lt;br /&gt;
This OpenLDAP configuration uses the SQL backend, which represents information stored in PostgreSQL as an LDAP subtree for Address Book functionality for email lookups, user authentication or even &lt;br /&gt;
replication account information between sites. This procedure uses some metainformation to translate LDAP queries to SQL queries, leaving relational schema untouched, which allows SQL and LDAP &lt;br /&gt;
applications to inter-operate without replication, and exchange data as needed. The SQL backend uses UnixODBC to connect to PostgresSQL. &lt;br /&gt;
&lt;br /&gt;
* Install OpenLDAP and ODBC&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
apk add openldap libldap openldap-back-sql php-ldap unixodbc psqlodbc ca-certificates&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Note&#039;&#039;&#039;: Perhaps some packages should be installed from &amp;quot;edge&amp;quot; repository&lt;br /&gt;
&lt;br /&gt;
* Update &amp;quot;postfix&amp;quot; database (it will add &#039;id&#039; columns to mailbox and domain tables, also will create tables and views to represent LDAP metainformation)&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Note&#039;&#039;&#039;: These instructions are for example domain example.com. So make sure you replaced all entries of &#039;example&#039; and &#039;com&#039; according to your domain name parts.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
cat - &amp;lt;&amp;lt;EOF | psql -U postgres postfix&lt;br /&gt;
ALTER TABLE domain ADD COLUMN id SERIAL; &lt;br /&gt;
ALTER TABLE mailbox ADD COLUMN id SERIAL; &lt;br /&gt;
&lt;br /&gt;
CREATE TABLE ldap_entry_objclasses (&lt;br /&gt;
    entry_id integer NOT NULL,&lt;br /&gt;
    oc_name character varying(64)&lt;br /&gt;
);&lt;br /&gt;
&lt;br /&gt;
CREATE TABLE ldap_oc_mappings (&lt;br /&gt;
    id integer SERIAL,&lt;br /&gt;
    name character varying(64) NOT NULL,&lt;br /&gt;
    keytbl character varying(64) NOT NULL,&lt;br /&gt;
    keycol character varying(64) NOT NULL,&lt;br /&gt;
    create_proc character varying(255),&lt;br /&gt;
    delete_proc character varying(255),&lt;br /&gt;
    expect_return integer NOT NULL,&lt;br /&gt;
    PRIMARY KEY(id)&lt;br /&gt;
);&lt;br /&gt;
&lt;br /&gt;
CREATE TABLE ldap_attr_mappings_test (&lt;br /&gt;
    id integer SERIAL,&lt;br /&gt;
    oc_map_id integer NOT NULL REFERENCES ldap_oc_mappings(id),&lt;br /&gt;
    name character varying(255) NOT NULL,&lt;br /&gt;
    sel_expr character varying(255) NOT NULL,&lt;br /&gt;
    sel_expr_u character varying(255),&lt;br /&gt;
    from_tbls character varying(255) NOT NULL,&lt;br /&gt;
    join_where character varying(255),&lt;br /&gt;
    add_proc character varying(255),&lt;br /&gt;
    delete_proc character varying(255),&lt;br /&gt;
    param_order integer NOT NULL,&lt;br /&gt;
    expect_return integer NOT NULL,&lt;br /&gt;
    PRIMARY KEY(id)&lt;br /&gt;
);&lt;br /&gt;
&lt;br /&gt;
CREATE VIEW ldap_dcs AS&lt;br /&gt;
    (SELECT (domain.id + 100000) AS id, &lt;br /&gt;
            (((&#039;dc=&#039;::text || split_part((domain.domain)::text, &#039;.&#039;::text, 1)) || &#039;,dc=&#039;::text) || &lt;br /&gt;
            CASE WHEN (split_part((domain.domain)::text, &#039;.&#039;::text, 2) = &#039;com&#039;::text) THEN split_part((domain.domain)::text, &#039;.&#039;::text, 2) &lt;br /&gt;
                 ELSE ((split_part((domain.domain)::text, &#039;.&#039;::text, 2) || &#039;,dc=&#039;::text) || split_part((domain.domain)::text, &#039;.&#039;::text, 3)) &lt;br /&gt;
            END) AS dn, &lt;br /&gt;
            1 AS oc_map_id, &lt;br /&gt;
            100000 AS parent, &lt;br /&gt;
            0 AS keyval, &lt;br /&gt;
            domain.domain&lt;br /&gt;
     FROM domain &lt;br /&gt;
     WHERE domain.domain &amp;lt;&amp;gt; &#039;ALL&#039; &lt;br /&gt;
      UNION &lt;br /&gt;
     SELECT 100000 AS id, &lt;br /&gt;
           &#039;dc=com&#039; AS dn, &lt;br /&gt;
           1 AS oc_map_id, &lt;br /&gt;
           0 AS parent, &lt;br /&gt;
           0 AS keyval, &lt;br /&gt;
           &#039;com&#039; AS domain);&lt;br /&gt;
&lt;br /&gt;
CREATE VIEW ldap_entries AS&lt;br /&gt;
    SELECT mailbox.id, &lt;br /&gt;
    (((((&#039;cn=&#039;::text || initcap(replace(split_part((mailbox.username)::text, &#039;@&#039;::text, 1), &#039;.&#039;::text, &#039; &#039;::text))) || &#039;,dc=&#039;::text) || &lt;br /&gt;
          split_part(split_part((mailbox.username)::text, &#039;@&#039;::text, 2), &#039;.&#039;::text, 1)) || &#039;,dc=&#039;::text) || &lt;br /&gt;
             CASE WHEN (split_part(split_part((mailbox.username)::text, &#039;@&#039;::text, 2), &#039;.&#039;::text, 2) = &#039;com&#039;::text) &lt;br /&gt;
                  THEN split_part(split_part((mailbox.username)::text, &#039;@&#039;::text, 2), &#039;.&#039;::text, 2) &lt;br /&gt;
                  ELSE ((split_part(split_part((mailbox.username)::text, &#039;@&#039;::text, 2), &#039;.&#039;::text, 2) || &#039;,dc=&#039;::text) || &lt;br /&gt;
                         split_part(split_part((mailbox.username)::text, &#039;@&#039;::text, 2), &#039;.&#039;::text, 3)) &lt;br /&gt;
             END) AS dn, &lt;br /&gt;
          1 AS oc_map_id, &lt;br /&gt;
          (SELECT ldap_dcs.id &lt;br /&gt;
           FROM ldap_dcs &lt;br /&gt;
           WHERE ((ldap_dcs.domain)::text = (mailbox.domain)::text)) AS parent, &lt;br /&gt;
           mailbox.id AS keyval &lt;br /&gt;
           FROM mailbox &lt;br /&gt;
           UNION &lt;br /&gt;
           SELECT ldap_dcs.id,  &lt;br /&gt;
                  ldap_dcs.dn, &lt;br /&gt;
                  ldap_dcs.oc_map_id, &lt;br /&gt;
                  ldap_dcs.parent, &lt;br /&gt;
                  ldap_dcs.keyval &lt;br /&gt;
           FROM ldap_dcs;&lt;br /&gt;
EOF&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* Fill out LDAP tables according to following example (make sure to separate values with TABs):&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
cat - &amp;lt;&amp;lt;EOF | psql -U postgres postfix&lt;br /&gt;
COPY ldap_attr_mappings (id, oc_map_id, name, sel_expr, sel_expr_u, from_tbls, join_where, add_proc, delete_proc, param_order, expect_return) FROM stdin;&lt;br /&gt;
1	1	displayName	mailbox.name	\N	mailbox	\N	\N	\N	3	0&lt;br /&gt;
2	1	mail	mailbox.username	\N	mailbox	\N	\N	\N	3	0&lt;br /&gt;
3	1	cn	mailbox.name	\N	mailbox	\N	\N	\N	3	0&lt;br /&gt;
4	1	userPassword	&#039;{CRYPT}&#039;||mailbox.password	\N	mailbox	\N	\N	\N	3	0&lt;br /&gt;
\.&lt;br /&gt;
&lt;br /&gt;
COPY ldap_oc_mappings (id, name, keytbl, keycol, create_proc, delete_proc, expect_return) FROM stdin;&lt;br /&gt;
1	exampleBox	mailbox	id	\N	\N	1&lt;br /&gt;
\.&lt;br /&gt;
EOF&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* Check that &amp;quot;ldap_dcs&amp;quot; view presens something like this:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
echo &#039;select * from ldap_dcs&#039; | psql -U postgres postfix&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
   id   |             dn              | oc_map_id | parent | keyval |       domain       &lt;br /&gt;
--------+-----------------------------+-----------+--------+--------+--------------------&lt;br /&gt;
 100000 | dc=com                      |         1 |      0 |      0 | com&lt;br /&gt;
 100001 | dc=example,dc=com           |         1 | 100000 |      0 | example.com&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* Check that &amp;quot;ldap_entries&amp;quot; view presens something like this:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
echo &#039;select * from ldap_entries&#039; | psql -U postgres postfix&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
   id   |                          dn                           | oc_map_id | parent | keyval &lt;br /&gt;
--------+-------------------------------------------------------+-----------+--------+--------&lt;br /&gt;
    1   | cn=address1,dc=example,dc=com                         |         1 | 100001 |    1&lt;br /&gt;
...&lt;br /&gt;
   123  | cn=address123,dc=example,dc=com                       |         1 | 100001 |    1&lt;br /&gt;
 100000 | dc=com                                                |         1 |      0 |    0&lt;br /&gt;
 100001 | dc=example,dc=com                                     |         1 | 100000 |    0&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* Configure ODBC parameters&lt;br /&gt;
&lt;br /&gt;
Edit /etc/odbc.ini:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
[PostgreSQL]&lt;br /&gt;
Description             = Connection to Postgres&lt;br /&gt;
Driver                  = PostgreSQL&lt;br /&gt;
Trace                   = Yes&lt;br /&gt;
TraceFile               = sql.log&lt;br /&gt;
Database                = postfix&lt;br /&gt;
Servername              = 127.0.0.1&lt;br /&gt;
UserName                =&lt;br /&gt;
Password                =&lt;br /&gt;
Port                    = 5432&lt;br /&gt;
Protocol                = 6.4&lt;br /&gt;
ReadOnly                = No&lt;br /&gt;
RowVersining            = No&lt;br /&gt;
ShowSystemTables        = No&lt;br /&gt;
ShowOidColumn           = No&lt;br /&gt;
FakeOidIndex            = No&lt;br /&gt;
ConnSettings            =&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Edit /etc/odbcinst.ini:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
[PostgreSQL]&lt;br /&gt;
Description     = PostgreSQL driver for Linux&lt;br /&gt;
Driver          = /usr/lib/psqlodbcw.so&lt;br /&gt;
Setup           = /usr/lib/libodbcpsqlS.so&lt;br /&gt;
FileUsage       = 1&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* Test ODBC connection&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
echo &amp;quot;select * from domain;&amp;quot; | isql PostgreSQL postgres&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* Provide permission to certificate for LDAP server&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
chown ldap /etc/lighttpd/server-bundle.pem&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* Edit LDAP schema&lt;br /&gt;
&lt;br /&gt;
Edit /etc/openldap/schema/example.com.schema:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
attributetype ( 0.9.2342.19200300.100.1.3&lt;br /&gt;
	NAME ( &#039;mail&#039; &#039;rfc822Mailbox&#039; )&lt;br /&gt;
	DESC &#039;RFC1274: RFC822 Mailbox&#039;&lt;br /&gt;
        EQUALITY caseIgnoreIA5Match&lt;br /&gt;
        SUBSTR caseIgnoreIA5SubstringsMatch&lt;br /&gt;
        SYNTAX 1.3.6.1.4.1.1466.115.121.1.26{256} )&lt;br /&gt;
&lt;br /&gt;
attributetype ( 2.16.840.1.113730.3.1.241&lt;br /&gt;
	NAME &#039;displayName&#039;&lt;br /&gt;
	DESC &#039;RFC2798: preferred name to be used when displaying entries&#039;&lt;br /&gt;
	EQUALITY caseIgnoreMatch&lt;br /&gt;
	SUBSTR caseIgnoreSubstringsMatch&lt;br /&gt;
	SYNTAX 1.3.6.1.4.1.1466.115.121.1.15&lt;br /&gt;
	SINGLE-VALUE )&lt;br /&gt;
&lt;br /&gt;
objectclass   ( 2.16.840.1.113730.3.2.2&lt;br /&gt;
        NAME &#039;exampleBox&#039;&lt;br /&gt;
	DESC &#039;example.com mailbox&#039;&lt;br /&gt;
	MUST ( displayName $ mail $ userPassword )&lt;br /&gt;
	)&lt;br /&gt;
&lt;br /&gt;
# RFC 1274 + RFC 2247&lt;br /&gt;
attributetype ( 0.9.2342.19200300.100.1.25&lt;br /&gt;
        NAME ( &#039;dc&#039; &#039;domainComponent&#039; )&lt;br /&gt;
        DESC &#039;RFC1274/2247: domain component&#039;&lt;br /&gt;
        EQUALITY caseIgnoreIA5Match&lt;br /&gt;
        SUBSTR caseIgnoreIA5SubstringsMatch&lt;br /&gt;
        SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 SINGLE-VALUE )&lt;br /&gt;
&lt;br /&gt;
attributetype ( 2.5.4.46 NAME &#039;dnQualifier&#039;&lt;br /&gt;
        DESC &#039;RFC2256: DN qualifier&#039;&lt;br /&gt;
        EQUALITY caseIgnoreMatch&lt;br /&gt;
        ORDERING caseIgnoreOrderingMatch&lt;br /&gt;
        SUBSTR caseIgnoreSubstringsMatch&lt;br /&gt;
        SYNTAX 1.3.6.1.4.1.1466.115.121.1.44 )&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* Configure LDAP server&lt;br /&gt;
&lt;br /&gt;
Edit /etc/openldap/slapd.conf:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
include         /etc/openldap/schema/example.com.schema&lt;br /&gt;
pidfile         /var/run/openldap/slapd.pid&lt;br /&gt;
argsfile        /var/run/openldap/slapd.args&lt;br /&gt;
&lt;br /&gt;
TLSCipherSuite HIGH&lt;br /&gt;
TLSCACertificateFile /etc/lighttpd/ca-crt.pem&lt;br /&gt;
TLSCertificateFile /etc/lighttpd/server-bundle.pem&lt;br /&gt;
TLSCertificateKeyFile /etc/lighttpd/server-bundle.pem&lt;br /&gt;
TLSVerifyClient never &lt;br /&gt;
&lt;br /&gt;
# This is needed for proper representation of MD5-CRYPT format stored in database&lt;br /&gt;
#  see more details in http://strugglers.net/~andy/blog/2010/01/23/openldap-and-md5crypt/&lt;br /&gt;
password-hash  {CRYPT}&lt;br /&gt;
password-crypt-salt-format &amp;quot;$1$%.8s&amp;quot;&lt;br /&gt;
&lt;br /&gt;
loglevel        stats&lt;br /&gt;
moduleload	/usr/lib/openldap/back_sql.so&lt;br /&gt;
sizelimit 3000&lt;br /&gt;
&lt;br /&gt;
database        sql&lt;br /&gt;
&lt;br /&gt;
dbname		PostgreSQL&lt;br /&gt;
dbuser		postfix&lt;br /&gt;
dbpasswd	*****&lt;br /&gt;
&lt;br /&gt;
suffix          &amp;quot;dc=example,dc=com&amp;quot;&lt;br /&gt;
rootdn          &amp;quot;cn=admin,dc=example,dc=com&amp;quot;&lt;br /&gt;
rootpw		{MD5}&amp;lt;Hashed password for root dn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
upper_func      &amp;quot;upper&amp;quot;&lt;br /&gt;
strcast_func    &amp;quot;text&amp;quot;&lt;br /&gt;
concat_pattern  &amp;quot;?||?&amp;quot;&lt;br /&gt;
has_ldapinfo_dn_ru      no&lt;br /&gt;
lastmod         off&lt;br /&gt;
&lt;br /&gt;
access to attrs=userPassword by * auth&lt;br /&gt;
&lt;br /&gt;
access to * by peername.ip=127.0.0.1 read&lt;br /&gt;
            ### by peername.ip=&amp;lt;IP&amp;gt;%&amp;lt;netmask&amp;gt; read&lt;br /&gt;
            ### by peername.ip=&amp;lt;IP&amp;gt; read&lt;br /&gt;
	    by users read&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* Set permissions for slapd.conf&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
chown ldap:ldap /etc/openldap/slapd.conf&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* Configure startup parameters to make sure that LDAP server start AFTER PostgreSQL and listens on localhost with clear text and public IP with SSL&lt;br /&gt;
&lt;br /&gt;
Edit /etc/conf.d/slapd:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
echo rc_need=&amp;quot;postgresql&amp;quot; &lt;br /&gt;
OPTS=&amp;quot;-h &#039;ldaps:// ldap://127.0.0.1&#039;&amp;quot;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* Start LDAP server&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
rc-update add slapd default&lt;br /&gt;
/etc/init.d/slapd start&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* Configure LDAP client utilities&lt;br /&gt;
&lt;br /&gt;
Edit /etc/openldap/ldap.conf&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
BASE	dc=example,dc=com&lt;br /&gt;
URI	ldaps://host.example.com&lt;br /&gt;
&lt;br /&gt;
TLS_CACERT /etc/lighttpd/ca-crt.pem&lt;br /&gt;
TLS_CERT /etc/lighttpd/server-bundle.pem&lt;br /&gt;
TLS_KEY /etc/lighttpd/server-bundle.pem&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* Test LDAP server&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
ldapsearch -z 3&lt;br /&gt;
ldapsearch -z 3 -x -W -D cn=admin,dc=example,dc=com&lt;br /&gt;
ldapsearch -z 3 -x -W -D cn=address1,dc=example,dc=com&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* Configure RoundCube webmail for email lookups&lt;br /&gt;
&lt;br /&gt;
Edit /usr/share/webapps/roundcube/config/main.inc.php:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
$rcmail_config[&#039;ldap_debug&#039;] = false;&lt;br /&gt;
...&lt;br /&gt;
$rcmail_config[&#039;address_book_type&#039;] = &#039;ldap&#039;;&lt;br /&gt;
&lt;br /&gt;
$rcmail_config[&#039;ldap_public&#039;][&#039;example.com&#039;] = array(&lt;br /&gt;
  &#039;name&#039;          =&amp;gt; &#039;example.com&#039;,&lt;br /&gt;
  &#039;hosts&#039;         =&amp;gt; array(&#039;127.0.0.1&#039;),&lt;br /&gt;
  &#039;port&#039;          =&amp;gt; 389,&lt;br /&gt;
  &#039;use_tls&#039;         =&amp;gt; false,&lt;br /&gt;
  &#039;user_specific&#039; =&amp;gt; false,&lt;br /&gt;
  &#039;base_dn&#039;       =&amp;gt; &#039;dc=example,dc=com&#039;,&lt;br /&gt;
  &#039;bind_dn&#039;       =&amp;gt; &#039;&#039;,&lt;br /&gt;
  &#039;bind_pass&#039;     =&amp;gt; &#039;&#039;,&lt;br /&gt;
  &#039;writable&#039;      =&amp;gt; false,&lt;br /&gt;
  &#039;LDAP_Object_Classes&#039; =&amp;gt; array(&amp;quot;top&amp;quot;, &amp;quot;exampleBox&amp;quot;),&lt;br /&gt;
  &#039;required_fields&#039;     =&amp;gt; array(&amp;quot;cn&amp;quot;, &amp;quot;sn&amp;quot;, &amp;quot;mail&amp;quot;),&lt;br /&gt;
  &#039;LDAP_rdn&#039;      =&amp;gt; &#039;mail&#039;,&lt;br /&gt;
  &#039;ldap_version&#039;  =&amp;gt; 3,&lt;br /&gt;
  &#039;search_fields&#039; =&amp;gt; array(&#039;mail&#039;, &#039;cn&#039;, &#039;sn&#039;, &#039;givenName&#039;),&lt;br /&gt;
  &#039;name_field&#039;    =&amp;gt; &#039;cn&#039;,&lt;br /&gt;
  &#039;email_field&#039;   =&amp;gt; &#039;mail&#039;,&lt;br /&gt;
  &#039;surname_field&#039; =&amp;gt; &#039;sn&#039;,&lt;br /&gt;
  &#039;firstname_field&#039; =&amp;gt; &#039;gn&#039;,&lt;br /&gt;
  &#039;sort&#039;          =&amp;gt; &#039;cn&#039;,&lt;br /&gt;
  &#039;scope&#039;         =&amp;gt; &#039;sub&#039;,&lt;br /&gt;
  &#039;filter&#039;        =&amp;gt; &#039;(objectClass=*)&#039;, // Construct here any filter you need&lt;br /&gt;
  &#039;fuzzy_search&#039;  =&amp;gt; true);&lt;br /&gt;
&lt;br /&gt;
$rcmail_config[&#039;autocomplete_addressbooks&#039;] = array(&#039;example.com&#039;);&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== log rotation ==&lt;br /&gt;
&lt;br /&gt;
Ensure the busybox cron service is started and is configured to auto-start:&lt;br /&gt;
&lt;br /&gt;
 /etc/init.d/cron start&lt;br /&gt;
 rc-update add cron default&lt;br /&gt;
&lt;br /&gt;
Add log rotate:&lt;br /&gt;
&lt;br /&gt;
 apk add logrotate&lt;br /&gt;
&lt;br /&gt;
Edit &#039;&#039;/etc/logrotate.conf&#039;&#039; as desired, but the defaults should be sufficient for most people.&lt;br /&gt;
&lt;br /&gt;
== Configure DNS ==&lt;br /&gt;
&lt;br /&gt;
This server hosts three separate web applications, and these can be handled as three different virtual domains on the same web server. They will be distinguished by their DNS names, so you can choose domains for the three separate services (or at least the ones you want to publish):&lt;br /&gt;
&lt;br /&gt;
* ACF - Alpine Configuration Framework for managing the server&lt;br /&gt;
* PostfixAdmin - for managing the postfix installation&lt;br /&gt;
* RoundCube - for accessing individual mailboxes&lt;br /&gt;
&lt;br /&gt;
Choose three different domains (from here on known as ACF_DOMAIN, POSTFIXADMIN_DOMAIN, and ROUNDCUBE_DOMAIN) and configure DNS for all three to point to the IP address of your host. These should be DNS A records.&lt;br /&gt;
&lt;br /&gt;
Then, configure lighttpd to handle the three separate domains by editing /etc/lighttpd/lighttpd.conf:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 $HTTP[&amp;quot;host&amp;quot;] == &amp;quot;ACF_DOMAIN&amp;quot; {&lt;br /&gt;
	simple-vhost.server-root   = &amp;quot;/var/www/domains/&amp;quot;&lt;br /&gt;
	simple-vhost.default-host  = &amp;quot;/ACF_DOMAIN/&amp;quot;&lt;br /&gt;
	simple-vhost.document-root = &amp;quot;www/&amp;quot;&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
 $HTTP[&amp;quot;host&amp;quot;] == &amp;quot;POSTFIXADMIN_DOMAIN&amp;quot; {&lt;br /&gt;
	simple-vhost.server-root   = &amp;quot;/var/www/domains/&amp;quot;&lt;br /&gt;
	simple-vhost.default-host  = &amp;quot;/POSTFIXADMIN_DOMAIN/&amp;quot;&lt;br /&gt;
	simple-vhost.document-root = &amp;quot;www/&amp;quot;&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
 $HTTP[&amp;quot;host&amp;quot;] == &amp;quot;ROUNDCUBE_DOMAIN&amp;quot; {&lt;br /&gt;
	simple-vhost.server-root   = &amp;quot;/var/www/domains/&amp;quot;&lt;br /&gt;
	simple-vhost.default-host  = &amp;quot;/ROUNDCUBE_DOMAIN/&amp;quot;&lt;br /&gt;
	simple-vhost.document-root = &amp;quot;www/&amp;quot;&lt;br /&gt;
 }&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
And, then link the appropriate www directories.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  mkdir -p /var/www/domains/ACF_DOMAIN&lt;br /&gt;
  ln -s /usr/share/acf/www /var/www/domains/ACF_DOMAIN/www&lt;br /&gt;
&lt;br /&gt;
  mkdir -p /var/www/domains/POSTFIXADMIN_DOMAIN&lt;br /&gt;
  ln -s /var/www/domains/host.example.com/www/postfixadmin /var/www/domains/POSTFIXADMIN_DOMAIN/www&lt;br /&gt;
&lt;br /&gt;
  mkdir -p /var/www/domains/ROUNDCUBE_DOMAIN&lt;br /&gt;
  ln -s /usr/share/webapps/roundcube /var/www/domains/ROUNDCUBE_DOMAIN/www&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;/div&gt;</summary>
		<author><name>Djhughes</name></author>
	</entry>
	<entry>
		<id>https://wiki.alpinelinux.org/w/index.php?title=ISP_Mail_Server_HowTo&amp;diff=3496</id>
		<title>ISP Mail Server HowTo</title>
		<link rel="alternate" type="text/html" href="https://wiki.alpinelinux.org/w/index.php?title=ISP_Mail_Server_HowTo&amp;diff=3496"/>
		<updated>2010-03-18T09:35:29Z</updated>

		<summary type="html">&lt;p&gt;Djhughes: typo, removed freshclam, as clamd depends on freshclam which starts when clam starts up&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== A Full Service Mail Server ==&lt;br /&gt;
&lt;br /&gt;
The goal of this document is to describe how to set up postfix, dovecot, clamav, dspam, roundecube, and postfixadmin for a full-featured &amp;quot;ISP&amp;quot; level mail server.&lt;br /&gt;
&lt;br /&gt;
The server must provide:&lt;br /&gt;
&lt;br /&gt;
* multiple virtual domains&lt;br /&gt;
* admins for each domain (to add/remove virtual accounts)&lt;br /&gt;
* Quota support per domain / account&lt;br /&gt;
* downloading email via IMAP / IMAPS / POP3 / POP3S&lt;br /&gt;
* relaying email for authenticated users with TLS or SSL (Submission / SMTPS protocol)&lt;br /&gt;
* Standard filters (virus/spam/rbl/etc)&lt;br /&gt;
* Web mail client&lt;br /&gt;
* Value Add services&lt;br /&gt;
&lt;br /&gt;
== Set up Lighttpd + PHP ==&lt;br /&gt;
&lt;br /&gt;
PostfixAdmin needs php pgpsql and imap modules, so we do it in this step.&lt;br /&gt;
&lt;br /&gt;
  apk add lighttpd php php-pgsql php-imap&lt;br /&gt;
&lt;br /&gt;
Stop and remove mini_httpd, and move ACF to lighttpd;  We are setting this up to be a multi-domain virtual web server (replace host.example.com with the actual domain):&lt;br /&gt;
&lt;br /&gt;
  mkdir -p /var/www/domains/host.example.com/www&lt;br /&gt;
  ln -s /usr/share/acf/www /var/www/domains/host.example.com/www/acf&lt;br /&gt;
&lt;br /&gt;
Edit /var/www/domains/host.example.com/index.html to put a simple redirection page:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;lt;!DOCTYPE HTML PUBLIC &amp;quot;-//W3C//DTD HTML 4.01//EN&amp;quot; &amp;quot;http://www.w3.org/TR/html4/strict.dtd&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;html lang=&amp;quot;en&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;head&amp;gt;&lt;br /&gt;
&amp;lt;meta http-equiv=&amp;quot;Content-Type&amp;quot; content=&amp;quot;text/html; charset=ISO-8859-1&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;title&amp;gt;host.example.com Redirector&amp;lt;/title&amp;gt;&lt;br /&gt;
&amp;lt;/head&amp;gt;&lt;br /&gt;
&amp;lt;body&amp;gt;&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;&amp;lt;a href=&amp;quot;/acf&amp;quot;&amp;gt;ACF&amp;lt;/a&amp;gt;&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;&amp;lt;a href=&amp;quot;/postfixadmin&amp;quot;&amp;gt;PostfixAdmin&amp;lt;/a&amp;gt;&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;&amp;lt;a href=&amp;quot;/roundcube&amp;quot;&amp;gt;Roundcube&amp;lt;/a&amp;gt;&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
&amp;lt;/body&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Edit /etc/lighttpd/mod_cgi.conf to serve haserl files by adding a &amp;quot;&amp;quot; =&amp;gt; &amp;quot;&amp;quot; cgi handler and to treat /acf/cgi-bin as a CGI directory (remove the &#039;^&#039;)&lt;br /&gt;
&lt;br /&gt;
 $HTTP[&amp;quot;url&amp;quot;] =~ &amp;quot;/cgi-bin/&amp;quot; {&lt;br /&gt;
     # disable directory listings&lt;br /&gt;
     dir-listing.activate = &amp;quot;disable&amp;quot;&lt;br /&gt;
     # only allow cgi&#039;s in this directory&lt;br /&gt;
     cgi.assign = (&lt;br /&gt;
 		&amp;quot;.pl&amp;quot;	=&amp;gt;	&amp;quot;/usr/bin/perl&amp;quot;,&lt;br /&gt;
 		&amp;quot;.cgi&amp;quot;	=&amp;gt;	&amp;quot;/usr/bin/perl&amp;quot;,&lt;br /&gt;
 		&amp;quot;&amp;quot; =&amp;gt; &amp;quot;&amp;quot;&lt;br /&gt;
 	)&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
Add these lines to /etc/lighttpd/lighttpd.conf to point to the new document root, and set it up to listen on port 443 (replace &#039;&#039;host.example.com&#039;&#039; with the actual domain and &#039;&#039;ip_address_of_server&#039;&#039; with the actual IP address):&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
simple-vhost.server-root   = &amp;quot;/var/www/domains/&amp;quot;&lt;br /&gt;
simple-vhost.default-host  = &amp;quot;/host.example.com/&amp;quot;&lt;br /&gt;
simple-vhost.document-root = &amp;quot;www/&amp;quot;&lt;br /&gt;
&lt;br /&gt;
$SERVER[&amp;quot;socket&amp;quot;] == &amp;quot;ip_address_of_server:443&amp;quot; {&lt;br /&gt;
ssl.engine    = &amp;quot;enable&amp;quot;&lt;br /&gt;
ssl.pemfile   = &amp;quot;/etc/lighttpd/server-bundle.pem&amp;quot;&lt;br /&gt;
ssl.ca-file   = &amp;quot;/etc/lighttpd/ca-crt.pem&amp;quot;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Ensure that the simple_vhosts module is loaded, as well as the cgi config scripts by uncommenting the following lines in /etc/lighttpd/lighttpd.conf&lt;br /&gt;
&lt;br /&gt;
 server.modules = (&lt;br /&gt;
     #  other modules may be listed&lt;br /&gt;
     &amp;quot;mod_simple_vhost&amp;quot;, &lt;br /&gt;
     #  other modules may be listed&lt;br /&gt;
  .&lt;br /&gt;
  .&lt;br /&gt;
  .&lt;br /&gt;
     include &amp;quot;mod_cgi.conf&amp;quot;&lt;br /&gt;
 &lt;br /&gt;
     include &amp;quot;mod_fastcgi.conf&amp;quot;&lt;br /&gt;
 &lt;br /&gt;
&lt;br /&gt;
Get a web certificate, and install it.  If you want to use a self-signed cert, you can use [[Generating SSL certs with ACF]] or [[Generating SSL certs with ACF 1.9]].  If you create a certificate with ACF, you can create the &amp;quot;server-bundle.pem&amp;quot; and the &amp;quot;ca-crt.pem&amp;quot; file with these commands:&lt;br /&gt;
&lt;br /&gt;
  openssl pkcs12 -nokeys -cacerts -in certificate.pfx  -out /etc/lighttpd/ca-crt.pem&lt;br /&gt;
  openssl pkcs12 -nodes -in certifcate.pfx -out /etc/lighttpd/server-bundle.pem&lt;br /&gt;
  chown root:root /etc/lighttpd/server-bundle.pem&lt;br /&gt;
  chmod 400 /etc/lighttpd/server-bundle.pem&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Note:&#039;&#039;&#039; The server certificate &#039;&#039;and&#039;&#039; key are in the server-bundle.pem file, so it is critical that the file be read-only by user &amp;quot;root&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
 Editme: We should probably only serve ACF to restricted hosts&lt;br /&gt;
&lt;br /&gt;
Stop and remove mini_httpd; start lighttpd, test&lt;br /&gt;
&lt;br /&gt;
  /etc/init.d/mini_httpd stop&lt;br /&gt;
  rc-update del mini_httpd&lt;br /&gt;
  apk del mini_httpd&lt;br /&gt;
  rc-update add lighttpd&lt;br /&gt;
  /etc/init.d/lighttpd start&lt;br /&gt;
&lt;br /&gt;
At this point you should be able to see ACF being served with lighttpd (Note: this will work well with alpine 1.10. With earlier versions there will be problems.)  https://host.example.com/acf/&lt;br /&gt;
&lt;br /&gt;
== Install Postgresql ==&lt;br /&gt;
&lt;br /&gt;
Add and configure postgresql&lt;br /&gt;
&lt;br /&gt;
  apk add acf-postgresql postgresql-client&lt;br /&gt;
  /etc/init.d/postgresql setup&lt;br /&gt;
  /etc/init.d/postgresql start&lt;br /&gt;
  rc-update add postgresql&lt;br /&gt;
&lt;br /&gt;
At this point any user can connect to the sql server with &amp;quot;trust&amp;quot; mechanism.  If you want to enforce password authentication (you probably do) edit /var/lib/postgresql/8.4/data/pg_hba.conf&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
  Editme: What should we recommend?&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Create the postfix database:&lt;br /&gt;
&lt;br /&gt;
  psql -U postgres&lt;br /&gt;
   create user postfix with password &#039;******&#039;;&lt;br /&gt;
   create database postfix owner postfix;&lt;br /&gt;
   \c postfix&lt;br /&gt;
   create language plpgsql;&lt;br /&gt;
   \q&lt;br /&gt;
&lt;br /&gt;
(Of course, use your selected password where ******* is shown above.)&lt;br /&gt;
&lt;br /&gt;
== Install PostfixAdmin ==&lt;br /&gt;
&lt;br /&gt;
We are going to install the postfix admin web front-end before we install the mail server.  This just creates an interface to populate the SQL tables that postfix and dovecot will use.&lt;br /&gt;
&lt;br /&gt;
Download PostfixAdmin from Sourceforge.  When these instructions were written, 2.3 was the current release, so (replace host.example.com with the actual domain):&lt;br /&gt;
 wget http://downloads.sourceforge.net/project/postfixadmin/postfixadmin/postfixadmin_2.3.tar.gz&lt;br /&gt;
 tar zxvf postfixadmin_2.3.tar.gz&lt;br /&gt;
 mkdir -p /var/www/domains/host.example.com/www/postfixadmin&lt;br /&gt;
 mv postfixadmin-2.3/* /var/www/domains/host.example.com/www/postfixadmin&lt;br /&gt;
 rm -rf postfixadmin*&lt;br /&gt;
&lt;br /&gt;
Edit /var/www/domains/host.example.com/www/postfixadmin/config.inc.php and modify at least these lines (replace host.example.com with the actual domain):&lt;br /&gt;
&lt;br /&gt;
 $CONF[&#039;configured&#039;] = true;&lt;br /&gt;
 $CONF[&#039;setup_password&#039;] = &amp;quot;&amp;quot;;  &amp;lt;&amp;lt; Don&#039;t change this yet&lt;br /&gt;
 $CONF[&#039;database_type&#039;] = &#039;pgsql&#039;;&lt;br /&gt;
 $CONF[&#039;database_host&#039;] = &#039;localhost&#039;;&lt;br /&gt;
 $CONF[&#039;database_user&#039;] = &#039;postfix&#039;;&lt;br /&gt;
 $CONF[&#039;database_password&#039;] = &#039;*****&#039;;   &amp;lt;&amp;lt; The password you chose above&lt;br /&gt;
 $CONF[&#039;database_name&#039;] = &#039;postfix&#039;;&lt;br /&gt;
 $CONF[&#039;database_prefix&#039;] = &amp;quot;&amp;quot;;&lt;br /&gt;
 $CONF[&#039;admin_email&#039;] = &#039;you@some.email.com&#039;;  &amp;lt;&amp;lt; Your email address &lt;br /&gt;
 $CONF[&#039;encrypt&#039;] = &#039;md5crypt&#039;;&lt;br /&gt;
 $CONF[&#039;authlib_default_flavor&#039;] = &#039;md5raw&#039;;&lt;br /&gt;
 $CONF[&#039;dovecotpw&#039;] = &amp;quot;/usr/sbin/dovecotpw&amp;quot;;&lt;br /&gt;
 $CONF[&#039;domain_path&#039;] = &#039;YES&#039;;&lt;br /&gt;
 $CONF[&#039;domain_in_mailbox&#039;] = &#039;NO&#039;;&lt;br /&gt;
 $CONF[&#039;aliases&#039;] = &#039;10&#039;;                       &lt;br /&gt;
 $CONF[&#039;mailboxes&#039;] = &#039;10&#039;;&lt;br /&gt;
 $CONF[&#039;maxquota&#039;] = &#039;10&#039;;&lt;br /&gt;
 $CONF[&#039;quota&#039;] = &#039;YES&#039;;&lt;br /&gt;
 $CONF[&#039;quota_multiplier&#039;] = &#039;1024000&#039;;&lt;br /&gt;
 $CONF[&#039;vacation&#039;] = &#039;NO&#039;; &lt;br /&gt;
 $CONF[&#039;vacation_control&#039;] =&#039;NO&#039;;&lt;br /&gt;
 $CONF[&#039;vacation_control_admin&#039;] = &#039;NO&#039;;&lt;br /&gt;
 $CONF[&#039;alias_control&#039;] = &#039;YES&#039;;&lt;br /&gt;
 $CONF[&#039;alias_control_admin&#039;] = &#039;YES&#039;;&lt;br /&gt;
 $CONF[&#039;special_alias_control&#039;] = &#039;YES&#039;;&lt;br /&gt;
 $CONF[&#039;fetchmail&#039;] = &#039;NO&#039;;&lt;br /&gt;
 $CONF[&#039;user_footer_link&#039;] = &amp;quot;http://host.example.com/postfixadmin&amp;quot;;&lt;br /&gt;
 $CONF[&#039;footer_link&#039;] = &#039;http://host.example.com/postfixadmin/main.php&#039;;&lt;br /&gt;
 $CONF[&#039;create_mailbox_subdirs_prefix&#039;]=&amp;quot;&amp;quot;;  &lt;br /&gt;
 $CONF[&#039;used_quotas&#039;] = &#039;YES&#039;;   &lt;br /&gt;
 $CONF[&#039;new_quota_table&#039;] = &#039;YES&#039;;  &lt;br /&gt;
&lt;br /&gt;
You should further edit /var/www/domains/host.example.com/www/postfixadmin/config.inc.php and replace all instances of &amp;quot;change-this-to-your.domain.tld&amp;quot; with your actual mail domain. This can be done with busybox sed (replace example.com with your domain name):&lt;br /&gt;
&lt;br /&gt;
 sed -i -e &#039;s/change-this-to-your.domain.tld/example.com/g&#039; /var/www/domains/host.example.com/www/postfixadmin/config.inc.php&lt;br /&gt;
&lt;br /&gt;
Go to http://host.example.com/postfixadmin/setup.php&lt;br /&gt;
&lt;br /&gt;
Create the password hash, add it to the config.inc.php file&lt;br /&gt;
&lt;br /&gt;
Go back to http://host.example.com/postfixadmin/setup.php&lt;br /&gt;
&lt;br /&gt;
Create superadmin account.&lt;br /&gt;
&lt;br /&gt;
== Install Postfix ==&lt;br /&gt;
&lt;br /&gt;
Create a user for the virtual mail delivery, and get its uid/gid (you&#039;ll need the numeric uid/gid for postfix)&lt;br /&gt;
&lt;br /&gt;
 adduser vmail -H -D -s /bin/false&lt;br /&gt;
 grep vmail /etc/passwd&lt;br /&gt;
&lt;br /&gt;
(In examples below, we use 1006/1006 for the uid/gid)&lt;br /&gt;
&lt;br /&gt;
Create the mail directory, and assign vmail as the owner&lt;br /&gt;
 mkdir -p /var/mail/domains&lt;br /&gt;
 chown -R vmail:vmail /var/mail/domains&lt;br /&gt;
 &lt;br /&gt;
&lt;br /&gt;
Install postfix&lt;br /&gt;
&lt;br /&gt;
 apk add acf-postfix postfix-pgsql&lt;br /&gt;
&lt;br /&gt;
Edit the /etc/postfix/main.cf file. Here&#039;s an example (don&#039;t forget to replace the uid/gid):&lt;br /&gt;
&lt;br /&gt;
 myhostname=host.example.com&lt;br /&gt;
 mydomain=example.com&lt;br /&gt;
 &lt;br /&gt;
 mydestination = localhost.$mydomain, localhost&lt;br /&gt;
 mynetworks_style = subnet&lt;br /&gt;
 mynetworks = 127.0.0.0/8&lt;br /&gt;
 &lt;br /&gt;
 virtual_mailbox_domains = proxy:pgsql:/etc/postfix/sql/pgsql_virtual_domains_maps.cf&lt;br /&gt;
 virtual_alias_maps = proxy:pgsql:/etc/postfix/sql/pgsql_virtual_alias_maps.cf,&lt;br /&gt;
        proxy:pgsql:/etc/postfix/sql/pgsql_virtual_alias_domain_maps.cf,&lt;br /&gt;
        proxy:pgsql:/etc/postfix/sql/pgsql_virtual_alias_domain_catchall_maps.cf&lt;br /&gt;
 &lt;br /&gt;
 virtual_mailbox_maps = proxy:pgsql:/etc/postfix/sql/pgsql_virtual_mailbox_maps.cf,&lt;br /&gt;
        proxy:pgsql:/etc/postfix/sql/pgsql_virtual_alias_domain_mailbox_maps.cf&lt;br /&gt;
 &lt;br /&gt;
 virtual_mailbox_base = /var/mail/domains/&lt;br /&gt;
 virtual_gid_maps = static:1006&lt;br /&gt;
 virtual_uid_maps = static:1006&lt;br /&gt;
 virtual_minimum_uid = 100&lt;br /&gt;
 virtual_transport = virtual&lt;br /&gt;
 &lt;br /&gt;
 &lt;br /&gt;
 # This next command means you must create a virtual&lt;br /&gt;
 # domain for the host itself - ALL mail goes through&lt;br /&gt;
 # The virtual transport&lt;br /&gt;
 &lt;br /&gt;
 mailbox_transport = virtual&lt;br /&gt;
 local_transport = virtual&lt;br /&gt;
 local_transport_maps = $virtual_mailbox_maps&lt;br /&gt;
 &lt;br /&gt;
 smtpd_helo_required = yes&lt;br /&gt;
 disable_vrfy_command = yes&lt;br /&gt;
 message_size_limit = 10240000&lt;br /&gt;
 queue_minfree = 51200000&lt;br /&gt;
 &lt;br /&gt;
 smtpd_sender_restrictions =&lt;br /&gt;
        permit_mynetworks,&lt;br /&gt;
        reject_non_fqdn_sender,&lt;br /&gt;
        reject_unknown_sender_domain&lt;br /&gt;
 &lt;br /&gt;
 smtpd_recipient_restrictions =&lt;br /&gt;
        reject_non_fqdn_recipient,&lt;br /&gt;
        reject_unknown_recipient_domain,&lt;br /&gt;
        permit_mynetworks,&lt;br /&gt;
        permit_sasl_authenticated,&lt;br /&gt;
        reject_unauth_destination,&lt;br /&gt;
        reject_rbl_client dnsbl.sorbs.net,&lt;br /&gt;
        reject_rbl_client zen.spamhaus.org,&lt;br /&gt;
        reject_rbl_client bl.spamcop.net&lt;br /&gt;
 &lt;br /&gt;
 smtpd_data_restrictions = reject_unauth_pipelining&lt;br /&gt;
 &lt;br /&gt;
 # we will use this later - This prevents cleartext authentication&lt;br /&gt;
 # for relaying&lt;br /&gt;
 smtpd_tls_auth_only = yes&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Now we need to create a *bunch* of files so that postfix can get the delivery information out of sql. Here&#039;s a shell script to create the scripts.  Change PGPW to the password for the postfix user of the postfix SQL database.&lt;br /&gt;
&lt;br /&gt;
 cd /etc/postfix&lt;br /&gt;
 mkdir sql&lt;br /&gt;
 PGPW=&amp;quot;ChangeMe&amp;quot;&lt;br /&gt;
 &lt;br /&gt;
 cat - &amp;lt;&amp;lt;EOF &amp;gt;sql/pgsql_virtual_alias_domain_catchall_maps.cf&lt;br /&gt;
 user=postfix&lt;br /&gt;
 password = $PGPW&lt;br /&gt;
 hosts = localhost&lt;br /&gt;
 dbname = postfix&lt;br /&gt;
 query = Select goto From alias,alias_domain where alias_domain.alias_domain = &#039;%d&#039; and alias.address = &#039;@&#039; ||  alias_domain.target_domain and alias.active = true and alias_domain.active= true &lt;br /&gt;
 EOF&lt;br /&gt;
 &lt;br /&gt;
 cat - &amp;lt;&amp;lt;EOF &amp;gt;sql/pgsql_virtual_alias_domain_mailbox_maps.cf&lt;br /&gt;
 user=postfix&lt;br /&gt;
 password = $PGPW&lt;br /&gt;
 hosts = localhost&lt;br /&gt;
 dbname = postfix&lt;br /&gt;
 query = Select maildir from mailbox,alias_domain where alias_domain.alias_domain = &#039;%d&#039; and mailbox.username = &#039;%u&#039; || &#039;@&#039; || alias_domain.target_domain and mailbox.active = true and alias_domain.active&lt;br /&gt;
 EOF&lt;br /&gt;
 &lt;br /&gt;
 cat - &amp;lt;&amp;lt;EOF &amp;gt;sql/pgsql_virtual_alias_domain_maps.cf&lt;br /&gt;
 user=postfix&lt;br /&gt;
 password = $PGPW&lt;br /&gt;
 hosts = localhost&lt;br /&gt;
 dbname = postfix&lt;br /&gt;
 query = select goto from alias,alias_domain where alias_domain.alias_domain=&#039;%d&#039; and alias.address = &#039;%u&#039; || &#039;@&#039; || alias_domain.target_domain and alias.active= true and alias_domain.active= true&lt;br /&gt;
 EOF&lt;br /&gt;
 &lt;br /&gt;
 cat - &amp;lt;&amp;lt;EOF &amp;gt;sql/pgsql_virtual_alias_maps.cf&lt;br /&gt;
 user=postfix&lt;br /&gt;
 password = $PGPW&lt;br /&gt;
 hosts = localhost&lt;br /&gt;
 dbname = postfix&lt;br /&gt;
 query = Select goto From alias Where address=&#039;%s&#039; and active =&#039;1&#039;&lt;br /&gt;
 EOF&lt;br /&gt;
 &lt;br /&gt;
 cat - &amp;lt;&amp;lt;EOF &amp;gt;sql/pgsql_virtual_domains_maps.cf&lt;br /&gt;
 user=postfix&lt;br /&gt;
 password = $PGPW&lt;br /&gt;
 hosts = localhost&lt;br /&gt;
 dbname = postfix&lt;br /&gt;
 query = Select domain from domain where domain=&#039;%s&#039; and active=&#039;1&#039;&lt;br /&gt;
 EOF&lt;br /&gt;
 &lt;br /&gt;
 cat - &amp;lt;&amp;lt;EOF &amp;gt;sql/pgsql_virtual_mailbox_maps.cf&lt;br /&gt;
 user=postfix&lt;br /&gt;
 password = $PGPW&lt;br /&gt;
 hosts = localhost&lt;br /&gt;
 dbname = postfix&lt;br /&gt;
 query = Select maildir from mailbox where username=&#039;%s&#039; and active=true&lt;br /&gt;
 EOF&lt;br /&gt;
 &lt;br /&gt;
 chown -R postfix:postfix sql&lt;br /&gt;
 chmod 640 sql/*&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
At this point you should be able to start up postfix&lt;br /&gt;
 &lt;br /&gt;
 newaliases  # so postfix is happy...&lt;br /&gt;
 /etc/init.d/postfix start&lt;br /&gt;
 rc-update add postfix&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Create a domain in PostfixAdmin and test ===&lt;br /&gt;
&lt;br /&gt;
Go to http://host.example.com/postfixadmin/&lt;br /&gt;
&lt;br /&gt;
Log in using the superadmin account, create a domain for the local box (e.g. example.com), and create a user mailbox (e.g. root).&lt;br /&gt;
&lt;br /&gt;
From the machine, send a test message:&lt;br /&gt;
&lt;br /&gt;
 sendmail -t root@example.com&lt;br /&gt;
 subject: test&lt;br /&gt;
 .&lt;br /&gt;
 ^d&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
In /var/log/mail.log (or /var/log/messages, if you still have busybox syslogd running) you should see the message queued.  The message should be in /var/mail/domains/example.com/root/new&lt;br /&gt;
&lt;br /&gt;
== Install Dovecot ==&lt;br /&gt;
&lt;br /&gt;
Dovecot is the POP3/IMAP server to retrieve mail.&lt;br /&gt;
&lt;br /&gt;
As before, we install dovecot: &lt;br /&gt;
&lt;br /&gt;
 apk add acf-dovecot dovecot-pgsql&lt;br /&gt;
&lt;br /&gt;
edit /etc/dovecot/dovecot.conf&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 # Select only the protocols you wish to support - all are listed in the next line&lt;br /&gt;
 protocols               =       imap imaps pop pop3s&lt;br /&gt;
 log_path                =       /var/log/dovecot.log&lt;br /&gt;
 info_log_path           =       /var/log/dovecot-info.log&lt;br /&gt;
 disable_plaintext_auth  =       no&lt;br /&gt;
&lt;br /&gt;
 # Authenticated IMAP&lt;br /&gt;
 ssl                     =       yes&lt;br /&gt;
 ssl_cert_file           =       /etc/lighttpd/server-bundle.pem&lt;br /&gt;
 ssl_key_file            =       /etc/lighttpd/server-bundle.pem&lt;br /&gt;
 auth_verbose            =       yes&lt;br /&gt;
 auth_debug              =       no&lt;br /&gt;
 mail_location           =       maildir:/var/mail/domains/%d/%n&lt;br /&gt;
 auth default    {&lt;br /&gt;
        mechanisms = plain&lt;br /&gt;
        passdb sql {&lt;br /&gt;
                args = /etc/dovecot/dovecot-sql.conf&lt;br /&gt;
                }&lt;br /&gt;
        userdb static {&lt;br /&gt;
                args =  uid=1006 gid=1006 home=/var/mail/domains/%d/%n&lt;br /&gt;
                }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Be sure to replace the uid and gid with the appropriate values for the vmail user.&lt;br /&gt;
&lt;br /&gt;
We need a certificate for SSL/TLS authentication, so in the example above, we use the lighttpd cert. That way when the cert is renewed/replaced, Dovecot will have access to the new cert as well.  &lt;br /&gt;
&lt;br /&gt;
Create the /etc/dovecot/dovecot-sql.conf file:&lt;br /&gt;
&lt;br /&gt;
 driver = pgsql&lt;br /&gt;
 connect = host=localhost dbname=postfix user=postfix password=********&lt;br /&gt;
 password_query = select username,password from mailbox where local_part = &#039;%n&#039; and domain = &#039;%d&#039;&lt;br /&gt;
 default_pass_scheme =  MD5-CRYPT&lt;br /&gt;
&lt;br /&gt;
Again, change the password above to your postfix user password, and protect the file from prying eyes:&lt;br /&gt;
&lt;br /&gt;
 chown root:root /etc/dovecot/dovecot-sql.conf&lt;br /&gt;
 chmod 600 /etc/dovecot/dovecot-sql.conf&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Start dovecot&lt;br /&gt;
 /etc/init.d/dovecot start&lt;br /&gt;
 rc-update add dovecot&lt;br /&gt;
&lt;br /&gt;
== Testing ==&lt;br /&gt;
&lt;br /&gt;
Make sure your firewall allows in ports 25(SMTP) 110 (POP3), 995 (POP3S), 143(IMAP), 993(IMAPS), or whatever subset you support.  &lt;br /&gt;
 &lt;br /&gt;
At this point, you should be able to:&lt;br /&gt;
 * Create a new domain and add users with PostfixAdmin&lt;br /&gt;
 * Send mail to those users via SMTP to port 25&lt;br /&gt;
 * Retrieve mail using the user&#039;s full email and password (e.g. username: user@example.com  password: ChangeMe)&lt;br /&gt;
&lt;br /&gt;
== Value Add Features ==&lt;br /&gt;
&lt;br /&gt;
If you followed the guide above, you now have a functional mail server with many interconnected parts.  The features below assume that the server is already running as described above.  You should be able to add any or all of these features below to further enhance the mail service.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Virus Scanning ===&lt;br /&gt;
&lt;br /&gt;
This procedure uses clamav and the postfix content_filter mechanism to scan inbound and outbound email for viruses.  Infected emails are dropped.  Clean emails are tagged with a &amp;quot;scanned by clamav&amp;quot; header.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* Install clamav and clamsmtp:&lt;br /&gt;
 apk add acf-clamav clamsmtp&lt;br /&gt;
* Edit the /etc/clamav/clamd.conf file if desired (not necessary in most cases)&lt;br /&gt;
* Edit /etc/clamsmtpd.conf and verify the following lines&lt;br /&gt;
 OutAddress: 10026&lt;br /&gt;
 Listen: 127.0.0.1:10025                                               &lt;br /&gt;
 Header: X-Virus-Scanned: ClamAV using ClamSMTP&lt;br /&gt;
 Action: drop&lt;br /&gt;
 User: clamav                                                      &lt;br /&gt;
* Start the daemons&lt;br /&gt;
 rc-update add clamd&lt;br /&gt;
 rc-update add clamsmtpd&lt;br /&gt;
 /etc/init.d/clamd start&lt;br /&gt;
 /etc/init.d/clamsmtpd start&lt;br /&gt;
* Verify clamsmtp is listening on port 10025:&lt;br /&gt;
 netstat -anp | grep clamsmtp&lt;br /&gt;
* [http://memberwebs.com/stef/software/clamsmtp/postfix.html Following the clamsmtp instructions]&lt;br /&gt;
** edit /etc/postfix/main.cf and add:&lt;br /&gt;
 content_filter = scan:[127.0.0.1]:10025                                                      &lt;br /&gt;
** edit /etc/postfix/master.cf and add&lt;br /&gt;
 # AV scan filter (used by content_filter)&lt;br /&gt;
 scan      unix  -       -       n       -       16      smtp&lt;br /&gt;
         -o smtp_send_xforward_command=yes&lt;br /&gt;
         -o smtp_enforce_tls=no&lt;br /&gt;
 # For injecting mail back into postfix from the filter&lt;br /&gt;
 127.0.0.1:10026 inet  n -       n       -       16      smtpd&lt;br /&gt;
         -o content_filter=&lt;br /&gt;
         -o receive_override_options=no_unknown_recipient_checks,no_header_body_checks&lt;br /&gt;
         -o smtpd_helo_restrictions=&lt;br /&gt;
         -o smtpd_client_restrictions=&lt;br /&gt;
         -o smtpd_sender_restrictions=&lt;br /&gt;
         -o smtpd_recipient_restrictions=permit_mynetworks,reject&lt;br /&gt;
         -o mynetworks_style=host&lt;br /&gt;
         -o smtpd_authorized_xforward_hosts=127.0.0.0/8&lt;br /&gt;
* postfix reload&lt;br /&gt;
* Send and email into a local virtual domain - it should have the &#039;&#039;X-Virus-Scanned: ClamAV using ClamSMTP&#039;&#039; header.&lt;br /&gt;
&lt;br /&gt;
=== Relay for Authenticated Users ===&lt;br /&gt;
&lt;br /&gt;
As configured above, the mail server accepts email from the Internet, but it does not relay email.  If it is a perimeter exchanger for a protected network, then you can add the protected networks to the &#039;&#039;mynetworks&#039;&#039; configuration line in /etc/postfix/main.cf&lt;br /&gt;
&lt;br /&gt;
This configuration change allows &#039;&#039;remote&#039;&#039; users to authenticate against the mail server and relay through it.  The rules for relaying are:&lt;br /&gt;
* Only authenticated users can relay&lt;br /&gt;
* Authentication Credentials must be encrypted with TLS or SSL&lt;br /&gt;
* Allow Submission and SMTPS ports for relaying (many consumer networks block port 25 - SMTP by default)&lt;br /&gt;
The process uses the dovecot authentication mechanism (used with IMAPS) to authenticate users before they are allowed to relay through postfix.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* Edit /etc/dovecot/dovecot.conf and add:&lt;br /&gt;
 # this is for postfix SASL (authenticated users can relay through us)&lt;br /&gt;
 socket listen {&lt;br /&gt;
                client {&lt;br /&gt;
                        path    = /var/spool/postfix/private/dovecot-auth.sock&lt;br /&gt;
                        mode    = 0660&lt;br /&gt;
                        user    = postfix&lt;br /&gt;
                        group   = postfix&lt;br /&gt;
                        }&lt;br /&gt;
                }&lt;br /&gt;
        }&lt;br /&gt;
* Restart dovecot&lt;br /&gt;
 /etc/init.d/dovecot restart&lt;br /&gt;
* Edit /etc/postfix/main.cf and add:&lt;br /&gt;
 # TLS Stuff -- since we allow SASL with tls *only*, we have to set up TLS first                    &lt;br /&gt;
 &lt;br /&gt;
 smtpd_tls_cert_file = /etc/lighttpd/server-bundle.pem&lt;br /&gt;
 smtpd_tls_key_file = /etc/lighttpd/server-bundle.pem&lt;br /&gt;
 smtpd_tls_CAfile = /etc/lighttpd/ca-crt.pem&lt;br /&gt;
 # If tls_security_level is set to &amp;quot;encrypt&amp;quot;, then SMTP rejects &lt;br /&gt;
 # unencrypted email (e.g. normal mail) which is bad.&lt;br /&gt;
 # By setting it to &amp;quot;may&amp;quot; you get TLS encrypted mail from google, slashdot, and other &lt;br /&gt;
 # interesting places.  Check your logs to see who&lt;br /&gt;
 smtpd_tls_security_level = may&lt;br /&gt;
 # Log info about the negotiated encryption levels&lt;br /&gt;
 smtpd_tls_received_header = yes&lt;br /&gt;
 smtpd_tls_loglevel = 1&lt;br /&gt;
 &lt;br /&gt;
 # SASL - this allows senders to authenticiate themselves&lt;br /&gt;
 # This along with &amp;quot;permit_sasl_authenticated&amp;quot; in smtpd_recipient_restrictions allows relaying&lt;br /&gt;
 smtpd_sasl_type = dovecot&lt;br /&gt;
 smtpd_sasl_path = private/dovecot-auth.sock&lt;br /&gt;
 smtpd_sasl_auth_enable = yes&lt;br /&gt;
 smtpd_sasl_authenticated_header = yes&lt;br /&gt;
 smtpd_tls_auth_only = yes&lt;br /&gt;
* Edit /etc/postfix/master.cf and enable the submission and smtps transports.  They are probably already at the top of your  master.cf file, just commented out:&lt;br /&gt;
 submission inet n       -       n       -       -       smtpd&lt;br /&gt;
   -o smtpd_tls_security_level=encrypt&lt;br /&gt;
   -o smtpd_sasl_auth_enable=yes&lt;br /&gt;
   -o smtpd_client_restrictions=permit_sasl_authenticated,reject&lt;br /&gt;
   -o milter_macro_daemon_name=ORIGINATING&lt;br /&gt;
 smtps     inet  n       -       n       -       -       smtpd&lt;br /&gt;
   -o smtpd_tls_security_level=encrypt&lt;br /&gt;
   -o smtpd_tls_wrappermode=yes&lt;br /&gt;
   -o smtpd_sasl_auth_enable=yes&lt;br /&gt;
   -o smtpd_client_restrictions=permit_sasl_authenticated,reject&lt;br /&gt;
   -o milter_macro_daemon_name=ORIGINATING&lt;br /&gt;
*Verfiy submission and smtps are defined in /etc/services&lt;br /&gt;
 grep &amp;quot;submission\|ssmtp&amp;quot; /etc/services&lt;br /&gt;
 submission	587/tcp				# mail message submission&lt;br /&gt;
 submission	587/udp&lt;br /&gt;
 smtps		465/tcp		ssmtp		# smtp protocol over TLS/SSL&lt;br /&gt;
 smtps		465/udp		ssmtp&lt;br /&gt;
* Restart postfix&lt;br /&gt;
 postfix reload&lt;br /&gt;
&lt;br /&gt;
At this point, you should be able to set up a mail client to relay through the server with TLS (port 587) or SSL (port 465)  Note that &amp;quot;plain&amp;quot; authentication is used because the underlying link is encrypted.  For example, in Thunderbird leave &amp;quot;secure authentication&amp;quot; unchecked, and choose STARTTLS (or TLS) for the connection security.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Mailbox Quotas ===&lt;br /&gt;
&lt;br /&gt;
In the default configuration, PostfixAdmin knows about quotas, but they are not enforced.   Documentation on the web mentions the [http://vda.sourceforge.net vda patch to postfix] to enforce quotas.  The only bad thing... its a &#039;&#039;patch&#039;&#039;.   Postfix and Dovecot are both conservative systems, so if the patch isn&#039;t in the upstream source, we&#039;ll assume there&#039;s a good reason.   There is a way of using quotas without patches - and it involves using dovecot&#039;s [http://wiki.dovecot.org/LDA deliver] lda for local delivery.&lt;br /&gt;
&lt;br /&gt;
Note: As of Jan 2010, the documention is confusing, with multiple versions of dovecot, PostfixAdmin, and Mysql referenced.  These instructions apply to:&lt;br /&gt;
* Postgresql 8.4.2 &lt;br /&gt;
* PostfixAdmin 2.3 &lt;br /&gt;
* Dovecot 1.2.10&lt;br /&gt;
* Postfix 2.6.5&lt;br /&gt;
&lt;br /&gt;
Presumably later versions will work the same, but if not, please update the documentation and versions above.&lt;br /&gt;
&lt;br /&gt;
* Update /etc/dovecot.conf (old lines shown commented out):&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
# old postfix &lt;br /&gt;
#       userdb static {&lt;br /&gt;
#               args =  uid=1006 gid=1006 home=/var/mail/domains/%d/%n&lt;br /&gt;
#               }&lt;br /&gt;
&lt;br /&gt;
# new quota support:&lt;br /&gt;
        userdb prefetch {&lt;br /&gt;
                }&lt;br /&gt;
&lt;br /&gt;
        userdb sql {&lt;br /&gt;
                args = /etc/dovecot/dovecot-sql.conf&lt;br /&gt;
                }&lt;br /&gt;
&lt;br /&gt;
        socket listen {&lt;br /&gt;
                client {&lt;br /&gt;
                        path    = /var/spool/postfix/private/dovecot-auth.sock&lt;br /&gt;
                        mode    = 0660&lt;br /&gt;
                        user    = postfix&lt;br /&gt;
                        group   = postfix&lt;br /&gt;
                        }&lt;br /&gt;
                # These lines below are for the deliver lda&lt;br /&gt;
                master {&lt;br /&gt;
                        path =  /var/run/dovecot/auth-master&lt;br /&gt;
                        mode    = 0660&lt;br /&gt;
                        user    = vmail&lt;br /&gt;
                        group   = vmail&lt;br /&gt;
                        }&lt;br /&gt;
                }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
protocol imap {                                                               &lt;br /&gt;
         mail_plugins = quota imap_quota                                       &lt;br /&gt;
         }                                                                     &lt;br /&gt;
                                                                              &lt;br /&gt;
protocol pop3 {                                                               &lt;br /&gt;
         mail_plugins = quota                                                  &lt;br /&gt;
         }                                                                     &lt;br /&gt;
                                                                              &lt;br /&gt;
dict {                                                                        &lt;br /&gt;
        quotadict = pgsql:/etc/dovecot/dovecot-dict-quota.conf                &lt;br /&gt;
        }                                                                     &lt;br /&gt;
                                                                              &lt;br /&gt;
plugin {                                                                      &lt;br /&gt;
         quota = dict:user::proxy::quotadict                                   &lt;br /&gt;
         }                                                     &lt;br /&gt;
                                                              &lt;br /&gt;
protocol lda {                                                &lt;br /&gt;
   postmaster_address = postmaster@host.example.com&lt;br /&gt;
   mail_plugins = quota                                        &lt;br /&gt;
   auth_socket_path =  /var/run/dovecot/auth-master&lt;br /&gt;
   sendmail_path = /usr/sbin/sendmail&lt;br /&gt;
}                                                                            &lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
 &lt;br /&gt;
You should already have a &amp;lt;tt&amp;gt;socket-&amp;gt; listen-&amp;gt; client&amp;lt;/tt&amp;gt; section, but it is listed above to show where it goes in relationship to the &amp;lt;tt&amp;gt;socket -&amp;gt; listen -&amp;gt; master&amp;lt;/tt&amp;gt; section&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* edit &amp;lt;tt&amp;gt;/etc/dovecot/dovecot-sql.conf&amp;lt;/tt&amp;gt; and replace the user and password queries with the following (you may not have a user_query yet - add it):&lt;br /&gt;
&lt;br /&gt;
 password_query = select username as user, password, 1006 as userdb_uid, 1006 as userdb_gid, &#039;*:bytes=&#039; || quota as userdb_quota_rule from mailbox  where local_part = &#039;%n&#039; and domain = &#039;%d&#039;&lt;br /&gt;
 user_query = select maildir as home, 1006 as uid, 1006 as gid, &#039;*:bytes=&#039; || quota  as quota_rule from mailbox where local_part = &#039;%n&#039; and domain =&#039;%d&#039;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* create &amp;lt;tt&amp;gt;/etc/dovecot/dovecot-dict-quota.conf&amp;lt;/tt&amp;gt;&lt;br /&gt;
 connect = host=localhost dbname=postfix user=postfix password=********&lt;br /&gt;
 &lt;br /&gt;
 map {&lt;br /&gt;
         pattern = priv/quota/storage&lt;br /&gt;
         table = quota2&lt;br /&gt;
         username_field =username&lt;br /&gt;
         value_field = bytes&lt;br /&gt;
 }&lt;br /&gt;
 &lt;br /&gt;
 map {&lt;br /&gt;
        pattern= priv/quota/messages&lt;br /&gt;
        table = quota2&lt;br /&gt;
        username_field = username&lt;br /&gt;
        value_field = messages&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
Side note: [http://wiki.dovecot.org/Quota/Dict The Dovecot Quota Documentation] mentions the need for a trigger with pgsql.  This was created in the PostfixAdmin install, which is why you instantiated the pgsql language when creating the database.  If not, you will need to create the trigger, to reference the quota2 table, not the quota table mentioned in the dovecot docs.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* create a new transport for the dovecot lda.   Add the following to  /etc/postfix/master.cf:&lt;br /&gt;
 # The dovecot deliver lda&lt;br /&gt;
 dovecot   unix  -       n       n       -       -       pipe&lt;br /&gt;
   flags=DRhu user=vmail:vmail argv=/usr/libexec/dovecot/deliver -f ${sender} -d ${user}@${nexthop}&lt;br /&gt;
&lt;br /&gt;
* Edit the /etc/postfix/main.cf.  Replace &lt;br /&gt;
 virtual_transport = virtual &lt;br /&gt;
with&lt;br /&gt;
 virtual_transport = dovecot&lt;br /&gt;
 dovecot_destination_recipient_limit = 1&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;TODO&#039;&#039;&#039;  This will cause over-quota emails to bounce.   Which could be a source of backscatter.   We need a way of checking quota limits after RBL checking but before the message is accepted in the queue.&lt;br /&gt;
&lt;br /&gt;
=== WebMail (RoundCube) ===&lt;br /&gt;
&lt;br /&gt;
[http://roundcube.net/ RoundCube] is an &amp;quot;ajax /Web2.0&amp;quot; web-mail client.  These instructions are for the Alpine Linux 1.10 repository &lt;br /&gt;
&lt;br /&gt;
* Add the package and related php modules:&lt;br /&gt;
 apk add roundcubemail php-xml php-openssl php-mcrypt php-gd php-iconv&lt;br /&gt;
&lt;br /&gt;
* link the roundcube application back into the docroot&lt;br /&gt;
 ln -s /usr/share/webapps/roundcube /var/www/domains/host.example.com/www/roundcube&lt;br /&gt;
&lt;br /&gt;
* follow the instructions in /usr/share/webapps/roundcube/INSTALL:&lt;br /&gt;
 cd /usr/share/webapps/roundcube&lt;br /&gt;
 chown -R lighttpd:lighttpd temp logs&lt;br /&gt;
 &lt;br /&gt;
 su postgres&lt;br /&gt;
 createuser roundcube&lt;br /&gt;
   Shall the new role be a superuser? (y/n) n&lt;br /&gt;
   Shall the new role be allowed to create databases? (y/n) n&lt;br /&gt;
   Shall the new role be allowed to create more new roles? (y/n) y&lt;br /&gt;
 createdb -O roundcube -E UNICODE -T template0 roundcubemail&lt;br /&gt;
 psql roundcubemail&lt;br /&gt;
   roundcubemail=# ALTER USER roundcube WITH PASSWORD &#039;the_new_password&#039;;&lt;br /&gt;
   roundcubemail=# \c - roundcube&lt;br /&gt;
   roundcubemail=&amp;gt; \i /usr/share/webapps/roundcube/SQL/postgres.initial.sql&lt;br /&gt;
   roundcubemail=&amp;gt; \q&lt;br /&gt;
 exit&lt;br /&gt;
&lt;br /&gt;
* edit /etc/php/php.ini and set date.timezone to your local timezone, or to UTC&lt;br /&gt;
&lt;br /&gt;
* restart lighttpd to verify the new php libraries are used&lt;br /&gt;
 /etc/init.d/lighttpd restart&lt;br /&gt;
&lt;br /&gt;
* Point your browser to http://host.example.com/roundcube/installer&lt;br /&gt;
* Start installation&lt;br /&gt;
&lt;br /&gt;
For the specific configuration parameters in the install step:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!Property&lt;br /&gt;
!Setting&lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;enable_spellcheck&#039;&#039; ||   disabled &lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;identities_level&#039;&#039; ||  one identity with possibility to edit all params but not email address &lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;log driver&#039;&#039; || syslog &lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;sylog_id&#039;&#039; || roundcube &lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;syslog_facility&#039;&#039; || mailsubsystem &lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;db_dnsw&#039;&#039; || pgsql properties, as described above &lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;imap_host&#039;&#039; || 127.0.0.1 &lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;auto_create_user&#039;&#039; || enabled &lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;smtp_server&#039;&#039; ||  127.0.0.1&lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;smtp_port&#039;&#039; ||  25&lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;smtp_user/smtp_pass&#039;&#039; ||  enable &#039;&#039;Use Current IMAP username and password for SMTP authentication&#039;&#039;&lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;smtp_log&#039;&#039; ||  enable (optional, but gives additional log record)&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
The other items can be left at default settings, or adjusted if desired.&lt;br /&gt;
&lt;br /&gt;
* Follow the instructions in step 3 of the install to copy the files to the server&lt;br /&gt;
* You should now be able to get to roundcube at http://host.example.com/roundcube&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
After its working, the INSTALL file recommends removing the install directory.   If you want to keep the installer around later, you can simply change the ownership and permissions.  So do &#039;&#039;&#039;one&#039;&#039;&#039; of the following:&lt;br /&gt;
 cd /usr/share/webapps/roundcube&lt;br /&gt;
 rm -rf LICENSE UPGRADING INSTALL README CHANGELOG  SQL installer&lt;br /&gt;
or&lt;br /&gt;
 cd /usr/share/webapps/roundcube&lt;br /&gt;
 chown -R root:root LICENSE UPGRADING INSTALL README CHANGELOG  SQL installer&lt;br /&gt;
 chmod -R 600 LICENSE UPGRADING INSTALL README CHANGELOG SQL &lt;br /&gt;
 chmod 700 SQL installer&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== OpenLDAP based Address Book ===&lt;br /&gt;
&lt;br /&gt;
This OpenLDAP configuration uses the SQL backend, which represents information stored in PostgreSQL as an LDAP subtree for Address Book functionality for email lookups, user authentication or even &lt;br /&gt;
replication account information between sites. This procedure uses some metainformation to translate LDAP queries to SQL queries, leaving relational schema untouched, which allows SQL and LDAP &lt;br /&gt;
applications to inter-operate without replication, and exchange data as needed. The SQL backend uses UnixODBC to connect to PostgresSQL. &lt;br /&gt;
&lt;br /&gt;
* Install OpenLDAP and ODBC&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
apk add openldap libldap openldap-back-sql php-ldap unixodbc psqlodbc ca-certificates&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Note&#039;&#039;&#039;: Perhaps some packages should be installed from &amp;quot;edge&amp;quot; repository&lt;br /&gt;
&lt;br /&gt;
* Update &amp;quot;postfix&amp;quot; database (it will add &#039;id&#039; columns to mailbox and domain tables, also will create tables and views to represent LDAP metainformation)&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Note&#039;&#039;&#039;: These instructions are for example domain example.com. So make sure you replaced all entries of &#039;example&#039; and &#039;com&#039; according to your domain name parts.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
cat - &amp;lt;&amp;lt;EOF | psql -U postgres postfix&lt;br /&gt;
ALTER TABLE domain ADD COLUMN id SERIAL; &lt;br /&gt;
ALTER TABLE mailbox ADD COLUMN id SERIAL; &lt;br /&gt;
&lt;br /&gt;
CREATE TABLE ldap_entry_objclasses (&lt;br /&gt;
    entry_id integer NOT NULL,&lt;br /&gt;
    oc_name character varying(64)&lt;br /&gt;
);&lt;br /&gt;
&lt;br /&gt;
CREATE TABLE ldap_oc_mappings (&lt;br /&gt;
    id integer SERIAL,&lt;br /&gt;
    name character varying(64) NOT NULL,&lt;br /&gt;
    keytbl character varying(64) NOT NULL,&lt;br /&gt;
    keycol character varying(64) NOT NULL,&lt;br /&gt;
    create_proc character varying(255),&lt;br /&gt;
    delete_proc character varying(255),&lt;br /&gt;
    expect_return integer NOT NULL,&lt;br /&gt;
    PRIMARY KEY(id)&lt;br /&gt;
);&lt;br /&gt;
&lt;br /&gt;
CREATE TABLE ldap_attr_mappings_test (&lt;br /&gt;
    id integer SERIAL,&lt;br /&gt;
    oc_map_id integer NOT NULL REFERENCES ldap_oc_mappings(id),&lt;br /&gt;
    name character varying(255) NOT NULL,&lt;br /&gt;
    sel_expr character varying(255) NOT NULL,&lt;br /&gt;
    sel_expr_u character varying(255),&lt;br /&gt;
    from_tbls character varying(255) NOT NULL,&lt;br /&gt;
    join_where character varying(255),&lt;br /&gt;
    add_proc character varying(255),&lt;br /&gt;
    delete_proc character varying(255),&lt;br /&gt;
    param_order integer NOT NULL,&lt;br /&gt;
    expect_return integer NOT NULL,&lt;br /&gt;
    PRIMARY KEY(id)&lt;br /&gt;
);&lt;br /&gt;
&lt;br /&gt;
CREATE VIEW ldap_dcs AS&lt;br /&gt;
    (SELECT (domain.id + 100000) AS id, &lt;br /&gt;
            (((&#039;dc=&#039;::text || split_part((domain.domain)::text, &#039;.&#039;::text, 1)) || &#039;,dc=&#039;::text) || &lt;br /&gt;
            CASE WHEN (split_part((domain.domain)::text, &#039;.&#039;::text, 2) = &#039;com&#039;::text) THEN split_part((domain.domain)::text, &#039;.&#039;::text, 2) &lt;br /&gt;
                 ELSE ((split_part((domain.domain)::text, &#039;.&#039;::text, 2) || &#039;,dc=&#039;::text) || split_part((domain.domain)::text, &#039;.&#039;::text, 3)) &lt;br /&gt;
            END) AS dn, &lt;br /&gt;
            1 AS oc_map_id, &lt;br /&gt;
            100000 AS parent, &lt;br /&gt;
            0 AS keyval, &lt;br /&gt;
            domain.domain&lt;br /&gt;
     FROM domain &lt;br /&gt;
     WHERE domain.domain &amp;lt;&amp;gt; &#039;ALL&#039; &lt;br /&gt;
      UNION &lt;br /&gt;
     SELECT 100000 AS id, &lt;br /&gt;
           &#039;dc=com&#039; AS dn, &lt;br /&gt;
           1 AS oc_map_id, &lt;br /&gt;
           0 AS parent, &lt;br /&gt;
           0 AS keyval, &lt;br /&gt;
           &#039;com&#039; AS domain);&lt;br /&gt;
&lt;br /&gt;
CREATE VIEW ldap_entries AS&lt;br /&gt;
    SELECT mailbox.id, &lt;br /&gt;
    (((((&#039;cn=&#039;::text || initcap(replace(split_part((mailbox.username)::text, &#039;@&#039;::text, 1), &#039;.&#039;::text, &#039; &#039;::text))) || &#039;,dc=&#039;::text) || &lt;br /&gt;
          split_part(split_part((mailbox.username)::text, &#039;@&#039;::text, 2), &#039;.&#039;::text, 1)) || &#039;,dc=&#039;::text) || &lt;br /&gt;
             CASE WHEN (split_part(split_part((mailbox.username)::text, &#039;@&#039;::text, 2), &#039;.&#039;::text, 2) = &#039;com&#039;::text) &lt;br /&gt;
                  THEN split_part(split_part((mailbox.username)::text, &#039;@&#039;::text, 2), &#039;.&#039;::text, 2) &lt;br /&gt;
                  ELSE ((split_part(split_part((mailbox.username)::text, &#039;@&#039;::text, 2), &#039;.&#039;::text, 2) || &#039;,dc=&#039;::text) || &lt;br /&gt;
                         split_part(split_part((mailbox.username)::text, &#039;@&#039;::text, 2), &#039;.&#039;::text, 3)) &lt;br /&gt;
             END) AS dn, &lt;br /&gt;
          1 AS oc_map_id, &lt;br /&gt;
          (SELECT ldap_dcs.id &lt;br /&gt;
           FROM ldap_dcs &lt;br /&gt;
           WHERE ((ldap_dcs.domain)::text = (mailbox.domain)::text)) AS parent, &lt;br /&gt;
           mailbox.id AS keyval &lt;br /&gt;
           FROM mailbox &lt;br /&gt;
           UNION &lt;br /&gt;
           SELECT ldap_dcs.id,  &lt;br /&gt;
                  ldap_dcs.dn, &lt;br /&gt;
                  ldap_dcs.oc_map_id, &lt;br /&gt;
                  ldap_dcs.parent, &lt;br /&gt;
                  ldap_dcs.keyval &lt;br /&gt;
           FROM ldap_dcs;&lt;br /&gt;
EOF&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* Fill out LDAP tables according to following example (make sure to separate values with TABs):&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
cat - &amp;lt;&amp;lt;EOF | psql -U postgres postfix&lt;br /&gt;
COPY ldap_attr_mappings (id, oc_map_id, name, sel_expr, sel_expr_u, from_tbls, join_where, add_proc, delete_proc, param_order, expect_return) FROM stdin;&lt;br /&gt;
1	1	displayName	mailbox.name	\N	mailbox	\N	\N	\N	3	0&lt;br /&gt;
2	1	mail	mailbox.username	\N	mailbox	\N	\N	\N	3	0&lt;br /&gt;
3	1	cn	mailbox.name	\N	mailbox	\N	\N	\N	3	0&lt;br /&gt;
4	1	userPassword	&#039;{CRYPT}&#039;||mailbox.password	\N	mailbox	\N	\N	\N	3	0&lt;br /&gt;
\.&lt;br /&gt;
&lt;br /&gt;
COPY ldap_oc_mappings (id, name, keytbl, keycol, create_proc, delete_proc, expect_return) FROM stdin;&lt;br /&gt;
1	exampleBox	mailbox	id	\N	\N	1&lt;br /&gt;
\.&lt;br /&gt;
EOF&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* Check that &amp;quot;ldap_dcs&amp;quot; view presens something like this:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
echo &#039;select * from ldap_dcs&#039; | psql -U postgres postfix&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
   id   |             dn              | oc_map_id | parent | keyval |       domain       &lt;br /&gt;
--------+-----------------------------+-----------+--------+--------+--------------------&lt;br /&gt;
 100000 | dc=com                      |         1 |      0 |      0 | com&lt;br /&gt;
 100001 | dc=example,dc=com           |         1 | 100000 |      0 | example.com&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* Check that &amp;quot;ldap_entries&amp;quot; view presens something like this:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
echo &#039;select * from ldap_entries&#039; | psql -U postgres postfix&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
   id   |                          dn                           | oc_map_id | parent | keyval &lt;br /&gt;
--------+-------------------------------------------------------+-----------+--------+--------&lt;br /&gt;
    1   | cn=address1,dc=example,dc=com                         |         1 | 100001 |    1&lt;br /&gt;
...&lt;br /&gt;
   123  | cn=address123,dc=example,dc=com                       |         1 | 100001 |    1&lt;br /&gt;
 100000 | dc=com                                                |         1 |      0 |    0&lt;br /&gt;
 100001 | dc=example,dc=com                                     |         1 | 100000 |    0&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* Configure ODBC parameters&lt;br /&gt;
&lt;br /&gt;
Edit /etc/odbc.ini:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
[PostgreSQL]&lt;br /&gt;
Description             = Connection to Postgres&lt;br /&gt;
Driver                  = PostgreSQL&lt;br /&gt;
Trace                   = Yes&lt;br /&gt;
TraceFile               = sql.log&lt;br /&gt;
Database                = postfix&lt;br /&gt;
Servername              = 127.0.0.1&lt;br /&gt;
UserName                =&lt;br /&gt;
Password                =&lt;br /&gt;
Port                    = 5432&lt;br /&gt;
Protocol                = 6.4&lt;br /&gt;
ReadOnly                = No&lt;br /&gt;
RowVersining            = No&lt;br /&gt;
ShowSystemTables        = No&lt;br /&gt;
ShowOidColumn           = No&lt;br /&gt;
FakeOidIndex            = No&lt;br /&gt;
ConnSettings            =&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Edit /etc/odbcinst.ini:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
[PostgreSQL]&lt;br /&gt;
Description     = PostgreSQL driver for Linux&lt;br /&gt;
Driver          = /usr/lib/psqlodbcw.so&lt;br /&gt;
Setup           = /usr/lib/libodbcpsqlS.so&lt;br /&gt;
FileUsage       = 1&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* Test ODBC connection&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
echo &amp;quot;select * from domain;&amp;quot; | isql PostgreSQL postgres&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* Provide permission to certificate for LDAP server&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
chown ldap /etc/lighttpd/server-bundle.pem&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* Edit LDAP schema&lt;br /&gt;
&lt;br /&gt;
Edit /etc/openldap/schema/example.com.schema:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
attributetype ( 0.9.2342.19200300.100.1.3&lt;br /&gt;
	NAME ( &#039;mail&#039; &#039;rfc822Mailbox&#039; )&lt;br /&gt;
	DESC &#039;RFC1274: RFC822 Mailbox&#039;&lt;br /&gt;
        EQUALITY caseIgnoreIA5Match&lt;br /&gt;
        SUBSTR caseIgnoreIA5SubstringsMatch&lt;br /&gt;
        SYNTAX 1.3.6.1.4.1.1466.115.121.1.26{256} )&lt;br /&gt;
&lt;br /&gt;
attributetype ( 2.16.840.1.113730.3.1.241&lt;br /&gt;
	NAME &#039;displayName&#039;&lt;br /&gt;
	DESC &#039;RFC2798: preferred name to be used when displaying entries&#039;&lt;br /&gt;
	EQUALITY caseIgnoreMatch&lt;br /&gt;
	SUBSTR caseIgnoreSubstringsMatch&lt;br /&gt;
	SYNTAX 1.3.6.1.4.1.1466.115.121.1.15&lt;br /&gt;
	SINGLE-VALUE )&lt;br /&gt;
&lt;br /&gt;
objectclass   ( 2.16.840.1.113730.3.2.2&lt;br /&gt;
        NAME &#039;exampleBox&#039;&lt;br /&gt;
	DESC &#039;example.com mailbox&#039;&lt;br /&gt;
	MUST ( displayName $ mail $ userPassword )&lt;br /&gt;
	)&lt;br /&gt;
&lt;br /&gt;
# RFC 1274 + RFC 2247&lt;br /&gt;
attributetype ( 0.9.2342.19200300.100.1.25&lt;br /&gt;
        NAME ( &#039;dc&#039; &#039;domainComponent&#039; )&lt;br /&gt;
        DESC &#039;RFC1274/2247: domain component&#039;&lt;br /&gt;
        EQUALITY caseIgnoreIA5Match&lt;br /&gt;
        SUBSTR caseIgnoreIA5SubstringsMatch&lt;br /&gt;
        SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 SINGLE-VALUE )&lt;br /&gt;
&lt;br /&gt;
attributetype ( 2.5.4.46 NAME &#039;dnQualifier&#039;&lt;br /&gt;
        DESC &#039;RFC2256: DN qualifier&#039;&lt;br /&gt;
        EQUALITY caseIgnoreMatch&lt;br /&gt;
        ORDERING caseIgnoreOrderingMatch&lt;br /&gt;
        SUBSTR caseIgnoreSubstringsMatch&lt;br /&gt;
        SYNTAX 1.3.6.1.4.1.1466.115.121.1.44 )&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* Configure LDAP server&lt;br /&gt;
&lt;br /&gt;
Edit /etc/openldap/slapd.conf:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
include         /etc/openldap/schema/example.com.schema&lt;br /&gt;
pidfile         /var/run/openldap/slapd.pid&lt;br /&gt;
argsfile        /var/run/openldap/slapd.args&lt;br /&gt;
&lt;br /&gt;
TLSCipherSuite HIGH&lt;br /&gt;
TLSCACertificateFile /etc/lighttpd/ca-crt.pem&lt;br /&gt;
TLSCertificateFile /etc/lighttpd/server-bundle.pem&lt;br /&gt;
TLSCertificateKeyFile /etc/lighttpd/server-bundle.pem&lt;br /&gt;
TLSVerifyClient never &lt;br /&gt;
&lt;br /&gt;
# This is needed for proper representation of MD5-CRYPT format stored in database&lt;br /&gt;
#  see more details in http://strugglers.net/~andy/blog/2010/01/23/openldap-and-md5crypt/&lt;br /&gt;
password-hash  {CRYPT}&lt;br /&gt;
password-crypt-salt-format &amp;quot;$1$%.8s&amp;quot;&lt;br /&gt;
&lt;br /&gt;
loglevel        stats&lt;br /&gt;
moduleload	/usr/lib/openldap/back_sql.so&lt;br /&gt;
sizelimit 3000&lt;br /&gt;
&lt;br /&gt;
database        sql&lt;br /&gt;
&lt;br /&gt;
dbname		PostgreSQL&lt;br /&gt;
dbuser		postfix&lt;br /&gt;
dbpasswd	*****&lt;br /&gt;
&lt;br /&gt;
suffix          &amp;quot;dc=example,dc=com&amp;quot;&lt;br /&gt;
rootdn          &amp;quot;cn=admin,dc=example,dc=com&amp;quot;&lt;br /&gt;
rootpw		{MD5}&amp;lt;Hashed password for root dn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
upper_func      &amp;quot;upper&amp;quot;&lt;br /&gt;
strcast_func    &amp;quot;text&amp;quot;&lt;br /&gt;
concat_pattern  &amp;quot;?||?&amp;quot;&lt;br /&gt;
has_ldapinfo_dn_ru      no&lt;br /&gt;
lastmod         off&lt;br /&gt;
&lt;br /&gt;
access to attrs=userPassword by * auth&lt;br /&gt;
&lt;br /&gt;
access to * by peername.ip=127.0.0.1 read&lt;br /&gt;
            ### by peername.ip=&amp;lt;IP&amp;gt;%&amp;lt;netmask&amp;gt; read&lt;br /&gt;
            ### by peername.ip=&amp;lt;IP&amp;gt; read&lt;br /&gt;
	    by users read&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* Set permissions for slapd.conf&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
chown ldap:ldap /etc/openldap/slapd.conf&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* Configure startup parameters to make sure that LDAP server start AFTER PostgreSQL and listens on localhost with clear text and public IP with SSL&lt;br /&gt;
&lt;br /&gt;
Edit /etc/conf.d/slapd:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
echo rc_need=&amp;quot;postgresql&amp;quot; &lt;br /&gt;
OPTS=&amp;quot;-h &#039;ldaps:// ldap://127.0.0.1&#039;&amp;quot;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* Start LDAP server&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
rc-update add slapd default&lt;br /&gt;
/etc/init.d/slapd start&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* Configure LDAP client utilities&lt;br /&gt;
&lt;br /&gt;
Edit /etc/openldap/ldap.conf&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
BASE	dc=example,dc=com&lt;br /&gt;
URI	ldaps://host.example.com&lt;br /&gt;
&lt;br /&gt;
TLS_CACERT /etc/lighttpd/ca-crt.pem&lt;br /&gt;
TLS_CERT /etc/lighttpd/server-bundle.pem&lt;br /&gt;
TLS_KEY /etc/lighttpd/server-bundle.pem&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* Test LDAP server&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
ldapsearch -z 3&lt;br /&gt;
ldapsearch -z 3 -x -W -D cn=admin,dc=example,dc=com&lt;br /&gt;
ldapsearch -z 3 -x -W -D cn=address1,dc=example,dc=com&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* Configure RoundCube webmail for email lookups&lt;br /&gt;
&lt;br /&gt;
Edit /usr/share/webapps/roundcube/config/main.inc.php:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
$rcmail_config[&#039;ldap_debug&#039;] = false;&lt;br /&gt;
...&lt;br /&gt;
$rcmail_config[&#039;address_book_type&#039;] = &#039;ldap&#039;;&lt;br /&gt;
&lt;br /&gt;
$rcmail_config[&#039;ldap_public&#039;][&#039;example.com&#039;] = array(&lt;br /&gt;
  &#039;name&#039;          =&amp;gt; &#039;example.com&#039;,&lt;br /&gt;
  &#039;hosts&#039;         =&amp;gt; array(&#039;127.0.0.1&#039;),&lt;br /&gt;
  &#039;port&#039;          =&amp;gt; 389,&lt;br /&gt;
  &#039;use_tls&#039;         =&amp;gt; false,&lt;br /&gt;
  &#039;user_specific&#039; =&amp;gt; false,&lt;br /&gt;
  &#039;base_dn&#039;       =&amp;gt; &#039;dc=example,dc=com&#039;,&lt;br /&gt;
  &#039;bind_dn&#039;       =&amp;gt; &#039;&#039;,&lt;br /&gt;
  &#039;bind_pass&#039;     =&amp;gt; &#039;&#039;,&lt;br /&gt;
  &#039;writable&#039;      =&amp;gt; false,&lt;br /&gt;
  &#039;LDAP_Object_Classes&#039; =&amp;gt; array(&amp;quot;top&amp;quot;, &amp;quot;exampleBox&amp;quot;),&lt;br /&gt;
  &#039;required_fields&#039;     =&amp;gt; array(&amp;quot;cn&amp;quot;, &amp;quot;sn&amp;quot;, &amp;quot;mail&amp;quot;),&lt;br /&gt;
  &#039;LDAP_rdn&#039;      =&amp;gt; &#039;mail&#039;,&lt;br /&gt;
  &#039;ldap_version&#039;  =&amp;gt; 3,&lt;br /&gt;
  &#039;search_fields&#039; =&amp;gt; array(&#039;mail&#039;, &#039;cn&#039;, &#039;sn&#039;, &#039;givenName&#039;),&lt;br /&gt;
  &#039;name_field&#039;    =&amp;gt; &#039;cn&#039;,&lt;br /&gt;
  &#039;email_field&#039;   =&amp;gt; &#039;mail&#039;,&lt;br /&gt;
  &#039;surname_field&#039; =&amp;gt; &#039;sn&#039;,&lt;br /&gt;
  &#039;firstname_field&#039; =&amp;gt; &#039;gn&#039;,&lt;br /&gt;
  &#039;sort&#039;          =&amp;gt; &#039;cn&#039;,&lt;br /&gt;
  &#039;scope&#039;         =&amp;gt; &#039;sub&#039;,&lt;br /&gt;
  &#039;filter&#039;        =&amp;gt; &#039;(objectClass=*)&#039;, // Construct here any filter you need&lt;br /&gt;
  &#039;fuzzy_search&#039;  =&amp;gt; true);&lt;br /&gt;
&lt;br /&gt;
$rcmail_config[&#039;autocomplete_addressbooks&#039;] = array(&#039;example.com&#039;);&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== log rotation ==&lt;br /&gt;
&lt;br /&gt;
Ensure the busybox cron service is started and is configured to auto-start:&lt;br /&gt;
&lt;br /&gt;
 /etc/init.d/cron start&lt;br /&gt;
 rc-update add cron default&lt;br /&gt;
&lt;br /&gt;
Add log rotate:&lt;br /&gt;
&lt;br /&gt;
 apk add logrotate&lt;br /&gt;
&lt;br /&gt;
Edit &#039;&#039;/etc/logrotate.conf&#039;&#039; as desired, but the defaults should be sufficient for most people.&lt;br /&gt;
&lt;br /&gt;
== Configure DNS ==&lt;br /&gt;
&lt;br /&gt;
This server hosts three separate web applications, and these can be handled as three different virtual domains on the same web server. They will be distinguished by their DNS names, so you can choose domains for the three separate services (or at least the ones you want to publish):&lt;br /&gt;
&lt;br /&gt;
* ACF - Alpine Configuration Framework for managing the server&lt;br /&gt;
* PostfixAdmin - for managing the postfix installation&lt;br /&gt;
* RoundCube - for accessing individual mailboxes&lt;br /&gt;
&lt;br /&gt;
Choose three different domains (from here on known as ACF_DOMAIN, POSTFIXADMIN_DOMAIN, and ROUNDCUBE_DOMAIN) and configure DNS for all three to point to the IP address of your host. These should be DNS A records.&lt;br /&gt;
&lt;br /&gt;
Then, configure lighttpd to handle the three separate domains by editing /etc/lighttpd/lighttpd.conf:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 $HTTP[&amp;quot;host&amp;quot;] == &amp;quot;ACF_DOMAIN&amp;quot; {&lt;br /&gt;
	simple-vhost.server-root   = &amp;quot;/var/www/domains/&amp;quot;&lt;br /&gt;
	simple-vhost.default-host  = &amp;quot;/ACF_DOMAIN/&amp;quot;&lt;br /&gt;
	simple-vhost.document-root = &amp;quot;www/&amp;quot;&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
 $HTTP[&amp;quot;host&amp;quot;] == &amp;quot;POSTFIXADMIN_DOMAIN&amp;quot; {&lt;br /&gt;
	simple-vhost.server-root   = &amp;quot;/var/www/domains/&amp;quot;&lt;br /&gt;
	simple-vhost.default-host  = &amp;quot;/POSTFIXADMIN_DOMAIN/&amp;quot;&lt;br /&gt;
	simple-vhost.document-root = &amp;quot;www/&amp;quot;&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
 $HTTP[&amp;quot;host&amp;quot;] == &amp;quot;ROUNDCUBE_DOMAIN&amp;quot; {&lt;br /&gt;
	simple-vhost.server-root   = &amp;quot;/var/www/domains/&amp;quot;&lt;br /&gt;
	simple-vhost.default-host  = &amp;quot;/ROUNDCUBE_DOMAIN/&amp;quot;&lt;br /&gt;
	simple-vhost.document-root = &amp;quot;www/&amp;quot;&lt;br /&gt;
 }&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
And, then link the appropriate www directories.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  mkdir -p /var/www/domains/ACF_DOMAIN&lt;br /&gt;
  ln -s /usr/share/acf/www /var/www/domains/ACF_DOMAIN/www&lt;br /&gt;
&lt;br /&gt;
  mkdir -p /var/www/domains/POSTFIXADMIN_DOMAIN&lt;br /&gt;
  ln -s /var/www/domains/host.example.com/www/postfixadmin /var/www/domains/POSTFIXADMIN_DOMAIN/www&lt;br /&gt;
&lt;br /&gt;
  mkdir -p /var/www/domains/ROUNDCUBE_DOMAIN&lt;br /&gt;
  ln -s /usr/share/webapps/roundcube /var/www/domains/ROUNDCUBE_DOMAIN/www&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;/div&gt;</summary>
		<author><name>Djhughes</name></author>
	</entry>
	<entry>
		<id>https://wiki.alpinelinux.org/w/index.php?title=ISP_Mail_Server_HowTo&amp;diff=3495</id>
		<title>ISP Mail Server HowTo</title>
		<link rel="alternate" type="text/html" href="https://wiki.alpinelinux.org/w/index.php?title=ISP_Mail_Server_HowTo&amp;diff=3495"/>
		<updated>2010-03-18T07:29:46Z</updated>

		<summary type="html">&lt;p&gt;Djhughes: sed command to replace text&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== A Full Service Mail Server ==&lt;br /&gt;
&lt;br /&gt;
The goal of this document is to describe how to set up postfix, dovecot, clamav, dspam, roundecube, and postfixadmin for a full-featured &amp;quot;ISP&amp;quot; level mail server.&lt;br /&gt;
&lt;br /&gt;
The server must provide:&lt;br /&gt;
&lt;br /&gt;
* multiple virtual domains&lt;br /&gt;
* admins for each domain (to add/remove virtual accounts)&lt;br /&gt;
* Quota support per domain / account&lt;br /&gt;
* downloading email via IMAP / IMAPS / POP3 / POP3S&lt;br /&gt;
* relaying email for authenticated users with TLS or SSL (Submission / SMTPS protocol)&lt;br /&gt;
* Standard filters (virus/spam/rbl/etc)&lt;br /&gt;
* Web mail client&lt;br /&gt;
* Value Add services&lt;br /&gt;
&lt;br /&gt;
== Set up Lighttpd + PHP ==&lt;br /&gt;
&lt;br /&gt;
PostfixAdmin needs php pgpsql and imap modules, so we do it in this step.&lt;br /&gt;
&lt;br /&gt;
  apk add lighttpd php php-pgsql php-imap&lt;br /&gt;
&lt;br /&gt;
Stop and remove mini_httpd, and move ACF to lighttpd;  We are setting this up to be a multi-domain virtual web server (replace host.example.com with the actual domain):&lt;br /&gt;
&lt;br /&gt;
  mkdir -p /var/www/domains/host.example.com/www&lt;br /&gt;
  ln -s /usr/share/acf/www /var/www/domains/host.example.com/www/acf&lt;br /&gt;
&lt;br /&gt;
Edit /var/www/domains/host.example.com/index.html to put a simple redirection page:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;lt;!DOCTYPE HTML PUBLIC &amp;quot;-//W3C//DTD HTML 4.01//EN&amp;quot; &amp;quot;http://www.w3.org/TR/html4/strict.dtd&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;html lang=&amp;quot;en&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;head&amp;gt;&lt;br /&gt;
&amp;lt;meta http-equiv=&amp;quot;Content-Type&amp;quot; content=&amp;quot;text/html; charset=ISO-8859-1&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;title&amp;gt;host.example.com Redirector&amp;lt;/title&amp;gt;&lt;br /&gt;
&amp;lt;/head&amp;gt;&lt;br /&gt;
&amp;lt;body&amp;gt;&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;&amp;lt;a href=&amp;quot;/acf&amp;quot;&amp;gt;ACF&amp;lt;/a&amp;gt;&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;&amp;lt;a href=&amp;quot;/postfixadmin&amp;quot;&amp;gt;PostfixAdmin&amp;lt;/a&amp;gt;&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;&amp;lt;a href=&amp;quot;/roundcube&amp;quot;&amp;gt;Roundcube&amp;lt;/a&amp;gt;&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
&amp;lt;/body&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Edit /etc/lighttpd/mod_cgi.conf to serve haserl files by adding a &amp;quot;&amp;quot; =&amp;gt; &amp;quot;&amp;quot; cgi handler and to treat /acf/cgi-bin as a CGI directory (remove the &#039;^&#039;)&lt;br /&gt;
&lt;br /&gt;
 $HTTP[&amp;quot;url&amp;quot;] =~ &amp;quot;/cgi-bin/&amp;quot; {&lt;br /&gt;
     # disable directory listings&lt;br /&gt;
     dir-listing.activate = &amp;quot;disable&amp;quot;&lt;br /&gt;
     # only allow cgi&#039;s in this directory&lt;br /&gt;
     cgi.assign = (&lt;br /&gt;
 		&amp;quot;.pl&amp;quot;	=&amp;gt;	&amp;quot;/usr/bin/perl&amp;quot;,&lt;br /&gt;
 		&amp;quot;.cgi&amp;quot;	=&amp;gt;	&amp;quot;/usr/bin/perl&amp;quot;,&lt;br /&gt;
 		&amp;quot;&amp;quot; =&amp;gt; &amp;quot;&amp;quot;&lt;br /&gt;
 	)&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
Add these lines to /etc/lighttpd/lighttpd.conf to point to the new document root, and set it up to listen on port 443 (replace &#039;&#039;host.example.com&#039;&#039; with the actual domain and &#039;&#039;ip_address_of_server&#039;&#039; with the actual IP address):&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
simple-vhost.server-root   = &amp;quot;/var/www/domains/&amp;quot;&lt;br /&gt;
simple-vhost.default-host  = &amp;quot;/host.example.com/&amp;quot;&lt;br /&gt;
simple-vhost.document-root = &amp;quot;www/&amp;quot;&lt;br /&gt;
&lt;br /&gt;
$SERVER[&amp;quot;socket&amp;quot;] == &amp;quot;ip_address_of_server:443&amp;quot; {&lt;br /&gt;
ssl.engine    = &amp;quot;enable&amp;quot;&lt;br /&gt;
ssl.pemfile   = &amp;quot;/etc/lighttpd/server-bundle.pem&amp;quot;&lt;br /&gt;
ssl.ca-file   = &amp;quot;/etc/lighttpd/ca-crt.pem&amp;quot;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Ensure that the simple_vhosts module is loaded, as well as the cgi config scripts by uncommenting the following lines in /etc/lighttpd/lighttpd.conf&lt;br /&gt;
&lt;br /&gt;
 server.modules = (&lt;br /&gt;
     #  other modules may be listed&lt;br /&gt;
     &amp;quot;mod_simple_vhost&amp;quot;, &lt;br /&gt;
     #  other modules may be listed&lt;br /&gt;
  .&lt;br /&gt;
  .&lt;br /&gt;
  .&lt;br /&gt;
     include &amp;quot;mod_cgi.conf&amp;quot;&lt;br /&gt;
 &lt;br /&gt;
     include &amp;quot;mod_fastcgi.conf&amp;quot;&lt;br /&gt;
 &lt;br /&gt;
&lt;br /&gt;
Get a web certificate, and install it.  If you want to use a self-signed cert, you can use [[Generating SSL certs with ACF]] or [[Generating SSL certs with ACF 1.9]].  If you create a certificate with ACF, you can create the &amp;quot;server-bundle.pem&amp;quot; and the &amp;quot;ca-crt.pem&amp;quot; file with these commands:&lt;br /&gt;
&lt;br /&gt;
  openssl pkcs12 -nokeys -cacerts -in certificate.pfx  -out /etc/lighttpd/ca-crt.pem&lt;br /&gt;
  openssl pkcs12 -nodes -in certifcate.pfx -out /etc/lighttpd/server-bundle.pem&lt;br /&gt;
  chown root:root /etc/lighttpd/server-bundle.pem&lt;br /&gt;
  chmod 400 /etc/lighttpd/server-bundle.pem&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Note:&#039;&#039;&#039; The server certificate &#039;&#039;and&#039;&#039; key are in the server-bundle.pem file, so it is critical that the file be read-only by user &amp;quot;root&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
 Editme: We should probably only serve ACF to restricted hosts&lt;br /&gt;
&lt;br /&gt;
Stop and remove mini_httpd; start lighttpd, test&lt;br /&gt;
&lt;br /&gt;
  /etc/init.d/mini_httpd stop&lt;br /&gt;
  rc-update del mini_httpd&lt;br /&gt;
  apk del mini_httpd&lt;br /&gt;
  rc-update add lighttpd&lt;br /&gt;
  /etc/init.d/lighttpd start&lt;br /&gt;
&lt;br /&gt;
At this point you should be able to see ACF being served with lighttpd (Note: this will work well with alpine 1.10. With earlier versions there will be problems.)  https://host.example.com/acf/&lt;br /&gt;
&lt;br /&gt;
== Install Postgresql ==&lt;br /&gt;
&lt;br /&gt;
Add and configure postgresql&lt;br /&gt;
&lt;br /&gt;
  apk add acf-postgresql postgresql-client&lt;br /&gt;
  /etc/init.d/postgresql setup&lt;br /&gt;
  /etc/init.d/postgresql start&lt;br /&gt;
  rc-update add postgresql&lt;br /&gt;
&lt;br /&gt;
At this point any user can connect to the sql server with &amp;quot;trust&amp;quot; mechanism.  If you want to enforce password authentication (you probably do) edit /var/lib/postgresql/8.4/data/pg_hba.conf&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
  Editme: What should we recommend?&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Create the postfix database:&lt;br /&gt;
&lt;br /&gt;
  psql -U postgres&lt;br /&gt;
   create user postfix with password &#039;******&#039;;&lt;br /&gt;
   create database postfix owner postfix;&lt;br /&gt;
   \c postfix&lt;br /&gt;
   create language plpgsql;&lt;br /&gt;
   \q&lt;br /&gt;
&lt;br /&gt;
(Of course, use your selected password where ******* is shown above.)&lt;br /&gt;
&lt;br /&gt;
== Install PostfixAdmin ==&lt;br /&gt;
&lt;br /&gt;
We are going to install the postfix admin web front-end before we install the mail server.  This just creates an interface to populate the SQL tables that postfix and dovecot will use.&lt;br /&gt;
&lt;br /&gt;
Download PostfixAdmin from Sourceforge.  When these instructions were written, 2.3 was the current release, so (replace host.example.com with the actual domain):&lt;br /&gt;
 wget http://downloads.sourceforge.net/project/postfixadmin/postfixadmin/postfixadmin_2.3.tar.gz&lt;br /&gt;
 tar zxvf postfixadmin_2.3.tar.gz&lt;br /&gt;
 mkdir -p /var/www/domains/host.example.com/www/postfixadmin&lt;br /&gt;
 mv postfixadmin-2.3/* /var/www/domains/host.example.com/www/postfixadmin&lt;br /&gt;
 rm -rf postfixadmin*&lt;br /&gt;
&lt;br /&gt;
Edit /var/www/domains/host.example.com/www/postfixadmin/config.inc.php and modify at least these lines (replace host.example.com with the actual domain):&lt;br /&gt;
&lt;br /&gt;
 $CONF[&#039;configured&#039;] = true;&lt;br /&gt;
 $CONF[&#039;setup_password&#039;] = &amp;quot;&amp;quot;;  &amp;lt;&amp;lt; Don&#039;t change this yet&lt;br /&gt;
 $CONF[&#039;database_type&#039;] = &#039;pgsql&#039;;&lt;br /&gt;
 $CONF[&#039;database_host&#039;] = &#039;localhost&#039;;&lt;br /&gt;
 $CONF[&#039;database_user&#039;] = &#039;postfix&#039;;&lt;br /&gt;
 $CONF[&#039;database_password&#039;] = &#039;*****&#039;;   &amp;lt;&amp;lt; The password you chose above&lt;br /&gt;
 $CONF[&#039;database_name&#039;] = &#039;postfix&#039;;&lt;br /&gt;
 $CONF[&#039;database_prefix&#039;] = &amp;quot;&amp;quot;;&lt;br /&gt;
 $CONF[&#039;admin_email&#039;] = &#039;you@some.email.com&#039;;  &amp;lt;&amp;lt; Your email address &lt;br /&gt;
 $CONF[&#039;encrypt&#039;] = &#039;md5crypt&#039;;&lt;br /&gt;
 $CONF[&#039;authlib_default_flavor&#039;] = &#039;md5raw&#039;;&lt;br /&gt;
 $CONF[&#039;dovecotpw&#039;] = &amp;quot;/usr/sbin/dovecotpw&amp;quot;;&lt;br /&gt;
 $CONF[&#039;domain_path&#039;] = &#039;YES&#039;;&lt;br /&gt;
 $CONF[&#039;domain_in_mailbox&#039;] = &#039;NO&#039;;&lt;br /&gt;
 $CONF[&#039;aliases&#039;] = &#039;10&#039;;                       &lt;br /&gt;
 $CONF[&#039;mailboxes&#039;] = &#039;10&#039;;&lt;br /&gt;
 $CONF[&#039;maxquota&#039;] = &#039;10&#039;;&lt;br /&gt;
 $CONF[&#039;quota&#039;] = &#039;YES&#039;;&lt;br /&gt;
 $CONF[&#039;quota_multiplier&#039;] = &#039;1024000&#039;;&lt;br /&gt;
 $CONF[&#039;vacation&#039;] = &#039;NO&#039;; &lt;br /&gt;
 $CONF[&#039;vacation_control&#039;] =&#039;NO&#039;;&lt;br /&gt;
 $CONF[&#039;vacation_control_admin&#039;] = &#039;NO&#039;;&lt;br /&gt;
 $CONF[&#039;alias_control&#039;] = &#039;YES&#039;;&lt;br /&gt;
 $CONF[&#039;alias_control_admin&#039;] = &#039;YES&#039;;&lt;br /&gt;
 $CONF[&#039;special_alias_control&#039;] = &#039;YES&#039;;&lt;br /&gt;
 $CONF[&#039;fetchmail&#039;] = &#039;NO&#039;;&lt;br /&gt;
 $CONF[&#039;user_footer_link&#039;] = &amp;quot;http://host.example.com/postfixadmin&amp;quot;;&lt;br /&gt;
 $CONF[&#039;footer_link&#039;] = &#039;http://host.example.com/postfixadmin/main.php&#039;;&lt;br /&gt;
 $CONF[&#039;create_mailbox_subdirs_prefix&#039;]=&amp;quot;&amp;quot;;  &lt;br /&gt;
 $CONF[&#039;used_quotas&#039;] = &#039;YES&#039;;   &lt;br /&gt;
 $CONF[&#039;new_quota_table&#039;] = &#039;YES&#039;;  &lt;br /&gt;
&lt;br /&gt;
You should further edit /var/www/domains/host.example.com/www/postfixadmin/config.inc.php and replace all instances of &amp;quot;change-this-to-your.domain.tld&amp;quot; with your actual mail domain. This can be done with busybox sed (replace example.com with your domain name):&lt;br /&gt;
&lt;br /&gt;
 sed -i -e &#039;s/change-this-to-your.domain.tld/example.com/g&#039; /var/www/domains/host.example.com/www/postfixadmin/config.inc.php&lt;br /&gt;
&lt;br /&gt;
Go to http://host.example.com/postfixadmin/setup.php&lt;br /&gt;
&lt;br /&gt;
Create the password hash, add it to the config.inc.php file&lt;br /&gt;
&lt;br /&gt;
Go back to http://host.example.com/postfixadmin/setup.php&lt;br /&gt;
&lt;br /&gt;
Create superadmin account.&lt;br /&gt;
&lt;br /&gt;
== Install Postfix ==&lt;br /&gt;
&lt;br /&gt;
Create a user for the virtual mail delivery, and get its uid/gid (you&#039;ll need the numeric uid/gid for postfix)&lt;br /&gt;
&lt;br /&gt;
 adduser vmail -H -D -s /bin/false&lt;br /&gt;
 grep vmail /etc/passwd&lt;br /&gt;
&lt;br /&gt;
(In examples below, we use 1006/1006 for the uid/gid)&lt;br /&gt;
&lt;br /&gt;
Create the mail directory, and assign vmail as the owner&lt;br /&gt;
 mkdir -p /var/mail/domains&lt;br /&gt;
 chown -R vmail:vmail /var/mail/domains&lt;br /&gt;
 &lt;br /&gt;
&lt;br /&gt;
Install postfix&lt;br /&gt;
&lt;br /&gt;
 apk add acf-postfix postfix-pgsql&lt;br /&gt;
&lt;br /&gt;
Edit the /etc/postfix/main.cf file. Here&#039;s an example (don&#039;t forget to replace the uid/gid):&lt;br /&gt;
&lt;br /&gt;
 myhostname=host.example.com&lt;br /&gt;
 mydomain=example.com&lt;br /&gt;
 &lt;br /&gt;
 mydestination = localhost.$mydomain, localhost&lt;br /&gt;
 mynetworks_style = subnet&lt;br /&gt;
 mynetworks = 127.0.0.0/8&lt;br /&gt;
 &lt;br /&gt;
 virtual_mailbox_domains = proxy:pgsql:/etc/postfix/sql/pgsql_virtual_domains_maps.cf&lt;br /&gt;
 virtual_alias_maps = proxy:pgsql:/etc/postfix/sql/pgsql_virtual_alias_maps.cf,&lt;br /&gt;
        proxy:pgsql:/etc/postfix/sql/pgsql_virtual_alias_domain_maps.cf,&lt;br /&gt;
        proxy:pgsql:/etc/postfix/sql/pgsql_virtual_alias_domain_catchall_maps.cf&lt;br /&gt;
 &lt;br /&gt;
 virtual_mailbox_maps = proxy:pgsql:/etc/postfix/sql/pgsql_virtual_mailbox_maps.cf,&lt;br /&gt;
        proxy:pgsql:/etc/postfix/sql/pgsql_virtual_alias_domain_mailbox_maps.cf&lt;br /&gt;
 &lt;br /&gt;
 virtual_mailbox_base = /var/mail/domains/&lt;br /&gt;
 virtual_gid_maps = static:1006&lt;br /&gt;
 virtual_uid_maps = static:1006&lt;br /&gt;
 virtual_minimum_uid = 100&lt;br /&gt;
 virtual_transport = virtual&lt;br /&gt;
 &lt;br /&gt;
 &lt;br /&gt;
 # This next command means you must create a virtual&lt;br /&gt;
 # domain for the host itself - ALL mail goes through&lt;br /&gt;
 # The virtual transport&lt;br /&gt;
 &lt;br /&gt;
 mailbox_transport = virtual&lt;br /&gt;
 local_transport = virtual&lt;br /&gt;
 local_transport_maps = $virtual_mailbox_maps&lt;br /&gt;
 &lt;br /&gt;
 smtpd_helo_required = yes&lt;br /&gt;
 disable_vrfy_command = yes&lt;br /&gt;
 message_size_limit = 10240000&lt;br /&gt;
 queue_minfree = 51200000&lt;br /&gt;
 &lt;br /&gt;
 smtpd_sender_restrictions =&lt;br /&gt;
        permit_mynetworks,&lt;br /&gt;
        reject_non_fqdn_sender,&lt;br /&gt;
        reject_unknown_sender_domain&lt;br /&gt;
 &lt;br /&gt;
 smtpd_recipient_restrictions =&lt;br /&gt;
        reject_non_fqdn_recipient,&lt;br /&gt;
        reject_unknown_recipient_domain,&lt;br /&gt;
        permit_mynetworks,&lt;br /&gt;
        permit_sasl_authenticated,&lt;br /&gt;
        reject_unauth_destination,&lt;br /&gt;
        reject_rbl_client dnsbl.sorbs.net,&lt;br /&gt;
        reject_rbl_client zen.spamhaus.org,&lt;br /&gt;
        reject_rbl_client bl.spamcop.net&lt;br /&gt;
 &lt;br /&gt;
 smtpd_data_restrictions = reject_unauth_pipelining&lt;br /&gt;
 &lt;br /&gt;
 # we will use this later - This prevents cleartext authentication&lt;br /&gt;
 # for relaying&lt;br /&gt;
 smtpd_tls_auth_only = yes&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Now we need to create a *bunch* of files so that postfix can get the delivery information out of sql. Here&#039;s a shell script to create the scripts.  Change PGPW to the password for the postfix user of the postfix SQL database.&lt;br /&gt;
&lt;br /&gt;
 cd /etc/postfix&lt;br /&gt;
 mkdir sql&lt;br /&gt;
 PGPW=&amp;quot;ChangeMe&amp;quot;&lt;br /&gt;
 &lt;br /&gt;
 cat - &amp;lt;&amp;lt;EOF &amp;gt;sql/pgsql_virtual_alias_domain_catchall_maps.cf&lt;br /&gt;
 user=postfix&lt;br /&gt;
 password = $PGPW&lt;br /&gt;
 hosts = localhost&lt;br /&gt;
 dbname = postfix&lt;br /&gt;
 query = Select goto From alias,alias_domain where alias_domain.alias_domain = &#039;%d&#039; and alias.address = &#039;@&#039; ||  alias_domain.target_domain and alias.active = true and alias_domain.active= true &lt;br /&gt;
 EOF&lt;br /&gt;
 &lt;br /&gt;
 cat - &amp;lt;&amp;lt;EOF &amp;gt;sql/pgsql_virtual_alias_domain_mailbox_maps.cf&lt;br /&gt;
 user=postfix&lt;br /&gt;
 password = $PGPW&lt;br /&gt;
 hosts = localhost&lt;br /&gt;
 dbname = postfix&lt;br /&gt;
 query = Select maildir from mailbox,alias_domain where alias_domain.alias_domain = &#039;%d&#039; and mailbox.username = &#039;%u&#039; || &#039;@&#039; || alias_domain.target_domain and mailbox.active = true and alias_domain.active&lt;br /&gt;
 EOF&lt;br /&gt;
 &lt;br /&gt;
 cat - &amp;lt;&amp;lt;EOF &amp;gt;sql/pgsql_virtual_alias_domain_maps.cf&lt;br /&gt;
 user=postfix&lt;br /&gt;
 password = $PGPW&lt;br /&gt;
 hosts = localhost&lt;br /&gt;
 dbname = postfix&lt;br /&gt;
 query = select goto from alias,alias_domain where alias_domain.alias_domain=&#039;%d&#039; and alias.address = &#039;%u&#039; || &#039;@&#039; || alias_domain.target_domain and alias.active= true and alias_domain.active= true&lt;br /&gt;
 EOF&lt;br /&gt;
 &lt;br /&gt;
 cat - &amp;lt;&amp;lt;EOF &amp;gt;sql/pgsql_virtual_alias_maps.cf&lt;br /&gt;
 user=postfix&lt;br /&gt;
 password = $PGPW&lt;br /&gt;
 hosts = localhost&lt;br /&gt;
 dbname = postfix&lt;br /&gt;
 query = Select goto From alias Where address=&#039;%s&#039; and active =&#039;1&#039;&lt;br /&gt;
 EOF&lt;br /&gt;
 &lt;br /&gt;
 cat - &amp;lt;&amp;lt;EOF &amp;gt;sql/pgsql_virtual_domains_maps.cf&lt;br /&gt;
 user=postfix&lt;br /&gt;
 password = $PGPW&lt;br /&gt;
 hosts = localhost&lt;br /&gt;
 dbname = postfix&lt;br /&gt;
 query = Select domain from domain where domain=&#039;%s&#039; and active=&#039;1&#039;&lt;br /&gt;
 EOF&lt;br /&gt;
 &lt;br /&gt;
 cat - &amp;lt;&amp;lt;EOF &amp;gt;sql/pgsql_virtual_mailbox_maps.cf&lt;br /&gt;
 user=postfix&lt;br /&gt;
 password = $PGPW&lt;br /&gt;
 hosts = localhost&lt;br /&gt;
 dbname = postfix&lt;br /&gt;
 query = Select maildir from mailbox where username=&#039;%s&#039; and active=true&lt;br /&gt;
 EOF&lt;br /&gt;
 &lt;br /&gt;
 chown -R postfix:postfix sql&lt;br /&gt;
 chmod 640 sql/*&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
At this point you should be able to start up postfix&lt;br /&gt;
 &lt;br /&gt;
 newaliases  # so postfix is happy...&lt;br /&gt;
 /etc/init.d/postfix start&lt;br /&gt;
 rc-update add postfix&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Create a domain in PostfixAdmin and test ===&lt;br /&gt;
&lt;br /&gt;
Go to http://host.example.com/postfixadmin/&lt;br /&gt;
&lt;br /&gt;
Log in using the superadmin account, create a domain for the local box (e.g. example.com), and create a user mailbox (e.g. root).&lt;br /&gt;
&lt;br /&gt;
From the machine, send a test message:&lt;br /&gt;
&lt;br /&gt;
 sendmail -t root@example.com&lt;br /&gt;
 subject: test&lt;br /&gt;
 .&lt;br /&gt;
 ^d&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
In /var/log/mail.log (or /var/log/messages, if you still have busybox syslogd running) you should see the message queued.  The message should be in /var/mail/domains/example.com/root/new&lt;br /&gt;
&lt;br /&gt;
== Install Dovecot ==&lt;br /&gt;
&lt;br /&gt;
Dovecot is the POP3/IMAP server to retrieve mail.&lt;br /&gt;
&lt;br /&gt;
As before, we install dovecot: &lt;br /&gt;
&lt;br /&gt;
 apk add acf-dovecot dovecot-pgsql&lt;br /&gt;
&lt;br /&gt;
edit /etc/dovecot/dovecot.conf&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 # Select only the protocols you wish to support - all are listed in the next line&lt;br /&gt;
 protocols               =       imap imaps pop pop3s&lt;br /&gt;
 log_path                =       /var/log/dovecot.log&lt;br /&gt;
 info_log_path           =       /var/log/dovecot-info.log&lt;br /&gt;
 disable_plaintext_auth  =       no&lt;br /&gt;
&lt;br /&gt;
 # Authenticated IMAP&lt;br /&gt;
 ssl                     =       yes&lt;br /&gt;
 ssl_cert_file           =       /etc/lighttpd/server-bundle.pem&lt;br /&gt;
 ssl_key_file            =       /etc/lighttpd/server-bundle.pem&lt;br /&gt;
 auth_verbose            =       yes&lt;br /&gt;
 auth_debug              =       no&lt;br /&gt;
 mail_location           =       maildir:/var/mail/domains/%d/%n&lt;br /&gt;
 auth default    {&lt;br /&gt;
        mechanisms = plain&lt;br /&gt;
        passdb sql {&lt;br /&gt;
                args = /etc/dovecot/dovecot-sql.conf&lt;br /&gt;
                }&lt;br /&gt;
        userdb static {&lt;br /&gt;
                args =  uid=1006 gid=1006 home=/var/mail/domains/%d/%n&lt;br /&gt;
                }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Be sure to replace the uid and gid with the appropriate values for the vmail user.&lt;br /&gt;
&lt;br /&gt;
We need a certificate for SSL/TLS authentication, so in the example above, we use the lighttpd cert. That way when the cert is renewed/replaced, Dovecot will have access to the new cert as well.  &lt;br /&gt;
&lt;br /&gt;
Create the /etc/dovecot/dovecot-sql.conf file:&lt;br /&gt;
&lt;br /&gt;
 driver = pgsql&lt;br /&gt;
 connect = host=localhost dbname=postfix user=postfix password=********&lt;br /&gt;
 password_query = select username,password from mailbox where local_part = &#039;%n&#039; and domain = &#039;%d&#039;&lt;br /&gt;
 default_pass_scheme =  MD5-CRYPT&lt;br /&gt;
&lt;br /&gt;
Again, change the password above to your postfix user password, and protect the file from prying eyes:&lt;br /&gt;
&lt;br /&gt;
 chown root:root /etc/dovecot/dovecot-sql.conf&lt;br /&gt;
 chmod 600 /etc/dovecot/dovecot-sql.conf&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Start dovecot&lt;br /&gt;
 /etc/init.d/dovecot start&lt;br /&gt;
 rc-update add dovecot&lt;br /&gt;
&lt;br /&gt;
== Testing ==&lt;br /&gt;
&lt;br /&gt;
Make sure your firewall allows in ports 25(SMTP) 110 (POP3), 995 (POP3S), 143(IMAP), 993(IMAPS), or whatever subset you support.  &lt;br /&gt;
 &lt;br /&gt;
At this point, you should be able to:&lt;br /&gt;
 * Create a new domain and add users with PostfixAdmin&lt;br /&gt;
 * Send mail to those users via SMTP to port 25&lt;br /&gt;
 * Retrieve mail using the user&#039;s full email and password (e.g. username: user@example.com  password: ChangeMe)&lt;br /&gt;
&lt;br /&gt;
== Value Add Features ==&lt;br /&gt;
&lt;br /&gt;
If you followed the guide above, you now have a functional mail server with many interconnected parts.  The features below assume that the server is already running as described above.  You should be able to add any or all of these features below to further enhance the mail service.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Virus Scanning ===&lt;br /&gt;
&lt;br /&gt;
This procedure uses clamav and the postfix content_filter mechanism to scan inbound and outbound email for viruses.  Infected emails are dropped.  Clean emails are tagged with a &amp;quot;scanned by clamav&amp;quot; header.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* Install clamav and clamsmtp:&lt;br /&gt;
 apk add acf-clamav clamsmtp&lt;br /&gt;
* Edit the /etc/clamav/clamd.conf file if desired (not necessary in most cases)&lt;br /&gt;
* Edit /etc/clamsmtpd.conf and verify the following lines&lt;br /&gt;
 OutAddress: 10026&lt;br /&gt;
 Listen: 127.0.0.1:10025                                               &lt;br /&gt;
 Header: X-Virus-Scanned: ClamAV using ClamSMTP&lt;br /&gt;
 Action: drop&lt;br /&gt;
 User: clamav                                                      &lt;br /&gt;
* Start the daemons&lt;br /&gt;
 rc-update add clamd&lt;br /&gt;
 rc-update add freshclam&lt;br /&gt;
 rc-update add clamsmtp&lt;br /&gt;
 /etc/init.d/clamd start&lt;br /&gt;
 /etc/init.d/freshclam start&lt;br /&gt;
 /etc/init.d/clamsmtp start&lt;br /&gt;
* Verify clamsmtp is listening on port 10025:&lt;br /&gt;
 netstat -anp | grep clamsmtp&lt;br /&gt;
* [http://memberwebs.com/stef/software/clamsmtp/postfix.html Following the clamsmtp instructions]&lt;br /&gt;
** edit /etc/postfix/main.cf and add:&lt;br /&gt;
 content_filter = scan:[127.0.0.1]:10025                                                      &lt;br /&gt;
** edit /etc/postfix/master.cf and add&lt;br /&gt;
 # AV scan filter (used by content_filter)&lt;br /&gt;
 scan      unix  -       -       n       -       16      smtp&lt;br /&gt;
         -o smtp_send_xforward_command=yes&lt;br /&gt;
         -o smtp_enforce_tls=no&lt;br /&gt;
 # For injecting mail back into postfix from the filter&lt;br /&gt;
 127.0.0.1:10026 inet  n -       n       -       16      smtpd&lt;br /&gt;
         -o content_filter=&lt;br /&gt;
         -o receive_override_options=no_unknown_recipient_checks,no_header_body_checks&lt;br /&gt;
         -o smtpd_helo_restrictions=&lt;br /&gt;
         -o smtpd_client_restrictions=&lt;br /&gt;
         -o smtpd_sender_restrictions=&lt;br /&gt;
         -o smtpd_recipient_restrictions=permit_mynetworks,reject&lt;br /&gt;
         -o mynetworks_style=host&lt;br /&gt;
         -o smtpd_authorized_xforward_hosts=127.0.0.0/8&lt;br /&gt;
* postfix reload&lt;br /&gt;
* Send and email into a local virtual domain - it should have the &#039;&#039;X-Virus-Scanned: ClamAV using ClamSMTP&#039;&#039; header.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Relay for Authenticated Users ===&lt;br /&gt;
&lt;br /&gt;
As configured above, the mail server accepts email from the Internet, but it does not relay email.  If it is a perimeter exchanger for a protected network, then you can add the protected networks to the &#039;&#039;mynetworks&#039;&#039; configuration line in /etc/postfix/main.cf&lt;br /&gt;
&lt;br /&gt;
This configuration change allows &#039;&#039;remote&#039;&#039; users to authenticate against the mail server and relay through it.  The rules for relaying are:&lt;br /&gt;
* Only authenticated users can relay&lt;br /&gt;
* Authentication Credentials must be encrypted with TLS or SSL&lt;br /&gt;
* Allow Submission and SMTPS ports for relaying (many consumer networks block port 25 - SMTP by default)&lt;br /&gt;
The process uses the dovecot authentication mechanism (used with IMAPS) to authenticate users before they are allowed to relay through postfix.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* Edit /etc/dovecot/dovecot.conf and add:&lt;br /&gt;
 # this is for postfix SASL (authenticated users can relay through us)&lt;br /&gt;
 socket listen {&lt;br /&gt;
                client {&lt;br /&gt;
                        path    = /var/spool/postfix/private/dovecot-auth.sock&lt;br /&gt;
                        mode    = 0660&lt;br /&gt;
                        user    = postfix&lt;br /&gt;
                        group   = postfix&lt;br /&gt;
                        }&lt;br /&gt;
                }&lt;br /&gt;
        }&lt;br /&gt;
* Restart dovecot&lt;br /&gt;
 /etc/init.d/dovecot restart&lt;br /&gt;
* Edit /etc/postfix/main.cf and add:&lt;br /&gt;
 # TLS Stuff -- since we allow SASL with tls *only*, we have to set up TLS first                    &lt;br /&gt;
 &lt;br /&gt;
 smtpd_tls_cert_file = /etc/lighttpd/server-bundle.pem&lt;br /&gt;
 smtpd_tls_key_file = /etc/lighttpd/server-bundle.pem&lt;br /&gt;
 smtpd_tls_CAfile = /etc/lighttpd/ca-crt.pem&lt;br /&gt;
 # If tls_security_level is set to &amp;quot;encrypt&amp;quot;, then SMTP rejects &lt;br /&gt;
 # unencrypted email (e.g. normal mail) which is bad.&lt;br /&gt;
 # By setting it to &amp;quot;may&amp;quot; you get TLS encrypted mail from google, slashdot, and other &lt;br /&gt;
 # interesting places.  Check your logs to see who&lt;br /&gt;
 smtpd_tls_security_level = may&lt;br /&gt;
 # Log info about the negotiated encryption levels&lt;br /&gt;
 smtpd_tls_received_header = yes&lt;br /&gt;
 smtpd_tls_loglevel = 1&lt;br /&gt;
 &lt;br /&gt;
 # SASL - this allows senders to authenticiate themselves&lt;br /&gt;
 # This along with &amp;quot;permit_sasl_authenticated&amp;quot; in smtpd_recipient_restrictions allows relaying&lt;br /&gt;
 smtpd_sasl_type = dovecot&lt;br /&gt;
 smtpd_sasl_path = private/dovecot-auth.sock&lt;br /&gt;
 smtpd_sasl_auth_enable = yes&lt;br /&gt;
 smtpd_sasl_authenticated_header = yes&lt;br /&gt;
 smtpd_tls_auth_only = yes&lt;br /&gt;
* Edit /etc/postfix/master.cf and enable the submission and smtps transports.  They are probably already at the top of your  master.cf file, just commented out:&lt;br /&gt;
 submission inet n       -       n       -       -       smtpd&lt;br /&gt;
   -o smtpd_tls_security_level=encrypt&lt;br /&gt;
   -o smtpd_sasl_auth_enable=yes&lt;br /&gt;
   -o smtpd_client_restrictions=permit_sasl_authenticated,reject&lt;br /&gt;
   -o milter_macro_daemon_name=ORIGINATING&lt;br /&gt;
 smtps     inet  n       -       n       -       -       smtpd&lt;br /&gt;
   -o smtpd_tls_security_level=encrypt&lt;br /&gt;
   -o smtpd_tls_wrappermode=yes&lt;br /&gt;
   -o smtpd_sasl_auth_enable=yes&lt;br /&gt;
   -o smtpd_client_restrictions=permit_sasl_authenticated,reject&lt;br /&gt;
   -o milter_macro_daemon_name=ORIGINATING&lt;br /&gt;
*Verfiy submission and smtps are defined in /etc/services&lt;br /&gt;
 grep &amp;quot;submission\|ssmtp&amp;quot; /etc/services&lt;br /&gt;
 submission	587/tcp				# mail message submission&lt;br /&gt;
 submission	587/udp&lt;br /&gt;
 smtps		465/tcp		ssmtp		# smtp protocol over TLS/SSL&lt;br /&gt;
 smtps		465/udp		ssmtp&lt;br /&gt;
* Restart postfix&lt;br /&gt;
 postfix reload&lt;br /&gt;
&lt;br /&gt;
At this point, you should be able to set up a mail client to relay through the server with TLS (port 587) or SSL (port 465)  Note that &amp;quot;plain&amp;quot; authentication is used because the underlying link is encrypted.  For example, in Thunderbird leave &amp;quot;secure authentication&amp;quot; unchecked, and choose STARTTLS (or TLS) for the connection security.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Mailbox Quotas ===&lt;br /&gt;
&lt;br /&gt;
In the default configuration, PostfixAdmin knows about quotas, but they are not enforced.   Documentation on the web mentions the [http://vda.sourceforge.net vda patch to postfix] to enforce quotas.  The only bad thing... its a &#039;&#039;patch&#039;&#039;.   Postfix and Dovecot are both conservative systems, so if the patch isn&#039;t in the upstream source, we&#039;ll assume there&#039;s a good reason.   There is a way of using quotas without patches - and it involves using dovecot&#039;s [http://wiki.dovecot.org/LDA deliver] lda for local delivery.&lt;br /&gt;
&lt;br /&gt;
Note: As of Jan 2010, the documention is confusing, with multiple versions of dovecot, PostfixAdmin, and Mysql referenced.  These instructions apply to:&lt;br /&gt;
* Postgresql 8.4.2 &lt;br /&gt;
* PostfixAdmin 2.3 &lt;br /&gt;
* Dovecot 1.2.10&lt;br /&gt;
* Postfix 2.6.5&lt;br /&gt;
&lt;br /&gt;
Presumably later versions will work the same, but if not, please update the documentation and versions above.&lt;br /&gt;
&lt;br /&gt;
* Update /etc/dovecot.conf (old lines shown commented out):&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
# old postfix &lt;br /&gt;
#       userdb static {&lt;br /&gt;
#               args =  uid=1006 gid=1006 home=/var/mail/domains/%d/%n&lt;br /&gt;
#               }&lt;br /&gt;
&lt;br /&gt;
# new quota support:&lt;br /&gt;
        userdb prefetch {&lt;br /&gt;
                }&lt;br /&gt;
&lt;br /&gt;
        userdb sql {&lt;br /&gt;
                args = /etc/dovecot/dovecot-sql.conf&lt;br /&gt;
                }&lt;br /&gt;
&lt;br /&gt;
        socket listen {&lt;br /&gt;
                client {&lt;br /&gt;
                        path    = /var/spool/postfix/private/dovecot-auth.sock&lt;br /&gt;
                        mode    = 0660&lt;br /&gt;
                        user    = postfix&lt;br /&gt;
                        group   = postfix&lt;br /&gt;
                        }&lt;br /&gt;
                # These lines below are for the deliver lda&lt;br /&gt;
                master {&lt;br /&gt;
                        path =  /var/run/dovecot/auth-master&lt;br /&gt;
                        mode    = 0660&lt;br /&gt;
                        user    = vmail&lt;br /&gt;
                        group   = vmail&lt;br /&gt;
                        }&lt;br /&gt;
                }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
protocol imap {                                                               &lt;br /&gt;
         mail_plugins = quota imap_quota                                       &lt;br /&gt;
         }                                                                     &lt;br /&gt;
                                                                              &lt;br /&gt;
protocol pop3 {                                                               &lt;br /&gt;
         mail_plugins = quota                                                  &lt;br /&gt;
         }                                                                     &lt;br /&gt;
                                                                              &lt;br /&gt;
dict {                                                                        &lt;br /&gt;
        quotadict = pgsql:/etc/dovecot/dovecot-dict-quota.conf                &lt;br /&gt;
        }                                                                     &lt;br /&gt;
                                                                              &lt;br /&gt;
plugin {                                                                      &lt;br /&gt;
         quota = dict:user::proxy::quotadict                                   &lt;br /&gt;
         }                                                     &lt;br /&gt;
                                                              &lt;br /&gt;
protocol lda {                                                &lt;br /&gt;
   postmaster_address = postmaster@host.example.com&lt;br /&gt;
   mail_plugins = quota                                        &lt;br /&gt;
   auth_socket_path =  /var/run/dovecot/auth-master&lt;br /&gt;
   sendmail_path = /usr/sbin/sendmail&lt;br /&gt;
}                                                                            &lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
 &lt;br /&gt;
You should already have a &amp;lt;tt&amp;gt;socket-&amp;gt; listen-&amp;gt; client&amp;lt;/tt&amp;gt; section, but it is listed above to show where it goes in relationship to the &amp;lt;tt&amp;gt;socket -&amp;gt; listen -&amp;gt; master&amp;lt;/tt&amp;gt; section&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* edit &amp;lt;tt&amp;gt;/etc/dovecot/dovecot-sql.conf&amp;lt;/tt&amp;gt; and replace the user and password queries with the following (you may not have a user_query yet - add it):&lt;br /&gt;
&lt;br /&gt;
 password_query = select username as user, password, 1006 as userdb_uid, 1006 as userdb_gid, &#039;*:bytes=&#039; || quota as userdb_quota_rule from mailbox  where local_part = &#039;%n&#039; and domain = &#039;%d&#039;&lt;br /&gt;
 user_query = select maildir as home, 1006 as uid, 1006 as gid, &#039;*:bytes=&#039; || quota  as quota_rule from mailbox where local_part = &#039;%n&#039; and domain =&#039;%d&#039;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* create &amp;lt;tt&amp;gt;/etc/dovecot/dovecot-dict-quota.conf&amp;lt;/tt&amp;gt;&lt;br /&gt;
 connect = host=localhost dbname=postfix user=postfix password=********&lt;br /&gt;
 &lt;br /&gt;
 map {&lt;br /&gt;
         pattern = priv/quota/storage&lt;br /&gt;
         table = quota2&lt;br /&gt;
         username_field =username&lt;br /&gt;
         value_field = bytes&lt;br /&gt;
 }&lt;br /&gt;
 &lt;br /&gt;
 map {&lt;br /&gt;
        pattern= priv/quota/messages&lt;br /&gt;
        table = quota2&lt;br /&gt;
        username_field = username&lt;br /&gt;
        value_field = messages&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
Side note: [http://wiki.dovecot.org/Quota/Dict The Dovecot Quota Documentation] mentions the need for a trigger with pgsql.  This was created in the PostfixAdmin install, which is why you instantiated the pgsql language when creating the database.  If not, you will need to create the trigger, to reference the quota2 table, not the quota table mentioned in the dovecot docs.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* create a new transport for the dovecot lda.   Add the following to  /etc/postfix/master.cf:&lt;br /&gt;
 # The dovecot deliver lda&lt;br /&gt;
 dovecot   unix  -       n       n       -       -       pipe&lt;br /&gt;
   flags=DRhu user=vmail:vmail argv=/usr/libexec/dovecot/deliver -f ${sender} -d ${user}@${nexthop}&lt;br /&gt;
&lt;br /&gt;
* Edit the /etc/postfix/main.cf.  Replace &lt;br /&gt;
 virtual_transport = virtual &lt;br /&gt;
with&lt;br /&gt;
 virtual_transport = dovecot&lt;br /&gt;
 dovecot_destination_recipient_limit = 1&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;TODO&#039;&#039;&#039;  This will cause over-quota emails to bounce.   Which could be a source of backscatter.   We need a way of checking quota limits after RBL checking but before the message is accepted in the queue.&lt;br /&gt;
&lt;br /&gt;
=== WebMail (RoundCube) ===&lt;br /&gt;
&lt;br /&gt;
[http://roundcube.net/ RoundCube] is an &amp;quot;ajax /Web2.0&amp;quot; web-mail client.  These instructions are for the Alpine Linux 1.10 repository &lt;br /&gt;
&lt;br /&gt;
* Add the package and related php modules:&lt;br /&gt;
 apk add roundcubemail php-xml php-openssl php-mcrypt php-gd php-iconv&lt;br /&gt;
&lt;br /&gt;
* link the roundcube application back into the docroot&lt;br /&gt;
 ln -s /usr/share/webapps/roundcube /var/www/domains/host.example.com/www/roundcube&lt;br /&gt;
&lt;br /&gt;
* follow the instructions in /usr/share/webapps/roundcube/INSTALL:&lt;br /&gt;
 cd /usr/share/webapps/roundcube&lt;br /&gt;
 chown -R lighttpd:lighttpd temp logs&lt;br /&gt;
 &lt;br /&gt;
 su postgres&lt;br /&gt;
 createuser roundcube&lt;br /&gt;
   Shall the new role be a superuser? (y/n) n&lt;br /&gt;
   Shall the new role be allowed to create databases? (y/n) n&lt;br /&gt;
   Shall the new role be allowed to create more new roles? (y/n) y&lt;br /&gt;
 createdb -O roundcube -E UNICODE -T template0 roundcubemail&lt;br /&gt;
 psql roundcubemail&lt;br /&gt;
   roundcubemail=# ALTER USER roundcube WITH PASSWORD &#039;the_new_password&#039;;&lt;br /&gt;
   roundcubemail=# \c - roundcube&lt;br /&gt;
   roundcubemail=&amp;gt; \i /usr/share/webapps/roundcube/SQL/postgres.initial.sql&lt;br /&gt;
   roundcubemail=&amp;gt; \q&lt;br /&gt;
 exit&lt;br /&gt;
&lt;br /&gt;
* edit /etc/php/php.ini and set date.timezone to your local timezone, or to UTC&lt;br /&gt;
&lt;br /&gt;
* restart lighttpd to verify the new php libraries are used&lt;br /&gt;
 /etc/init.d/lighttpd restart&lt;br /&gt;
&lt;br /&gt;
* Point your browser to http://host.example.com/roundcube/installer&lt;br /&gt;
* Start installation&lt;br /&gt;
&lt;br /&gt;
For the specific configuration parameters in the install step:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!Property&lt;br /&gt;
!Setting&lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;enable_spellcheck&#039;&#039; ||   disabled &lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;identities_level&#039;&#039; ||  one identity with possibility to edit all params but not email address &lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;log driver&#039;&#039; || syslog &lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;sylog_id&#039;&#039; || roundcube &lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;syslog_facility&#039;&#039; || mailsubsystem &lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;db_dnsw&#039;&#039; || pgsql properties, as described above &lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;imap_host&#039;&#039; || 127.0.0.1 &lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;auto_create_user&#039;&#039; || enabled &lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;smtp_server&#039;&#039; ||  127.0.0.1&lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;smtp_port&#039;&#039; ||  25&lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;smtp_user/smtp_pass&#039;&#039; ||  enable &#039;&#039;Use Current IMAP username and password for SMTP authentication&#039;&#039;&lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;smtp_log&#039;&#039; ||  enable (optional, but gives additional log record)&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
The other items can be left at default settings, or adjusted if desired.&lt;br /&gt;
&lt;br /&gt;
* Follow the instructions in step 3 of the install to copy the files to the server&lt;br /&gt;
* You should now be able to get to roundcube at http://host.example.com/roundcube&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
After its working, the INSTALL file recommends removing the install directory.   If you want to keep the installer around later, you can simply change the ownership and permissions.  So do &#039;&#039;&#039;one&#039;&#039;&#039; of the following:&lt;br /&gt;
 cd /usr/share/webapps/roundcube&lt;br /&gt;
 rm -rf LICENSE UPGRADING INSTALL README CHANGELOG  SQL installer&lt;br /&gt;
or&lt;br /&gt;
 cd /usr/share/webapps/roundcube&lt;br /&gt;
 chown -R root:root LICENSE UPGRADING INSTALL README CHANGELOG  SQL installer&lt;br /&gt;
 chmod -R 600 LICENSE UPGRADING INSTALL README CHANGELOG SQL &lt;br /&gt;
 chmod 700 SQL installer&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== OpenLDAP based Address Book ===&lt;br /&gt;
&lt;br /&gt;
This OpenLDAP configuration uses the SQL backend, which represents information stored in PostgreSQL as an LDAP subtree for Address Book functionality for email lookups, user authentication or even &lt;br /&gt;
replication account information between sites. This procedure uses some metainformation to translate LDAP queries to SQL queries, leaving relational schema untouched, which allows SQL and LDAP &lt;br /&gt;
applications to inter-operate without replication, and exchange data as needed. The SQL backend uses UnixODBC to connect to PostgresSQL. &lt;br /&gt;
&lt;br /&gt;
* Install OpenLDAP and ODBC&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
apk add openldap libldap openldap-back-sql php-ldap unixodbc psqlodbc ca-certificates&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Note&#039;&#039;&#039;: Perhaps some packages should be installed from &amp;quot;edge&amp;quot; repository&lt;br /&gt;
&lt;br /&gt;
* Update &amp;quot;postfix&amp;quot; database (it will add &#039;id&#039; columns to mailbox and domain tables, also will create tables and views to represent LDAP metainformation)&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Note&#039;&#039;&#039;: These instructions are for example domain example.com. So make sure you replaced all entries of &#039;example&#039; and &#039;com&#039; according to your domain name parts.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
cat - &amp;lt;&amp;lt;EOF | psql -U postgres postfix&lt;br /&gt;
ALTER TABLE domain ADD COLUMN id SERIAL; &lt;br /&gt;
ALTER TABLE mailbox ADD COLUMN id SERIAL; &lt;br /&gt;
&lt;br /&gt;
CREATE TABLE ldap_entry_objclasses (&lt;br /&gt;
    entry_id integer NOT NULL,&lt;br /&gt;
    oc_name character varying(64)&lt;br /&gt;
);&lt;br /&gt;
&lt;br /&gt;
CREATE TABLE ldap_oc_mappings (&lt;br /&gt;
    id integer SERIAL,&lt;br /&gt;
    name character varying(64) NOT NULL,&lt;br /&gt;
    keytbl character varying(64) NOT NULL,&lt;br /&gt;
    keycol character varying(64) NOT NULL,&lt;br /&gt;
    create_proc character varying(255),&lt;br /&gt;
    delete_proc character varying(255),&lt;br /&gt;
    expect_return integer NOT NULL,&lt;br /&gt;
    PRIMARY KEY(id)&lt;br /&gt;
);&lt;br /&gt;
&lt;br /&gt;
CREATE TABLE ldap_attr_mappings_test (&lt;br /&gt;
    id integer SERIAL,&lt;br /&gt;
    oc_map_id integer NOT NULL REFERENCES ldap_oc_mappings(id),&lt;br /&gt;
    name character varying(255) NOT NULL,&lt;br /&gt;
    sel_expr character varying(255) NOT NULL,&lt;br /&gt;
    sel_expr_u character varying(255),&lt;br /&gt;
    from_tbls character varying(255) NOT NULL,&lt;br /&gt;
    join_where character varying(255),&lt;br /&gt;
    add_proc character varying(255),&lt;br /&gt;
    delete_proc character varying(255),&lt;br /&gt;
    param_order integer NOT NULL,&lt;br /&gt;
    expect_return integer NOT NULL,&lt;br /&gt;
    PRIMARY KEY(id)&lt;br /&gt;
);&lt;br /&gt;
&lt;br /&gt;
CREATE VIEW ldap_dcs AS&lt;br /&gt;
    (SELECT (domain.id + 100000) AS id, &lt;br /&gt;
            (((&#039;dc=&#039;::text || split_part((domain.domain)::text, &#039;.&#039;::text, 1)) || &#039;,dc=&#039;::text) || &lt;br /&gt;
            CASE WHEN (split_part((domain.domain)::text, &#039;.&#039;::text, 2) = &#039;com&#039;::text) THEN split_part((domain.domain)::text, &#039;.&#039;::text, 2) &lt;br /&gt;
                 ELSE ((split_part((domain.domain)::text, &#039;.&#039;::text, 2) || &#039;,dc=&#039;::text) || split_part((domain.domain)::text, &#039;.&#039;::text, 3)) &lt;br /&gt;
            END) AS dn, &lt;br /&gt;
            1 AS oc_map_id, &lt;br /&gt;
            100000 AS parent, &lt;br /&gt;
            0 AS keyval, &lt;br /&gt;
            domain.domain&lt;br /&gt;
     FROM domain &lt;br /&gt;
     WHERE domain.domain &amp;lt;&amp;gt; &#039;ALL&#039; &lt;br /&gt;
      UNION &lt;br /&gt;
     SELECT 100000 AS id, &lt;br /&gt;
           &#039;dc=com&#039; AS dn, &lt;br /&gt;
           1 AS oc_map_id, &lt;br /&gt;
           0 AS parent, &lt;br /&gt;
           0 AS keyval, &lt;br /&gt;
           &#039;com&#039; AS domain);&lt;br /&gt;
&lt;br /&gt;
CREATE VIEW ldap_entries AS&lt;br /&gt;
    SELECT mailbox.id, &lt;br /&gt;
    (((((&#039;cn=&#039;::text || initcap(replace(split_part((mailbox.username)::text, &#039;@&#039;::text, 1), &#039;.&#039;::text, &#039; &#039;::text))) || &#039;,dc=&#039;::text) || &lt;br /&gt;
          split_part(split_part((mailbox.username)::text, &#039;@&#039;::text, 2), &#039;.&#039;::text, 1)) || &#039;,dc=&#039;::text) || &lt;br /&gt;
             CASE WHEN (split_part(split_part((mailbox.username)::text, &#039;@&#039;::text, 2), &#039;.&#039;::text, 2) = &#039;com&#039;::text) &lt;br /&gt;
                  THEN split_part(split_part((mailbox.username)::text, &#039;@&#039;::text, 2), &#039;.&#039;::text, 2) &lt;br /&gt;
                  ELSE ((split_part(split_part((mailbox.username)::text, &#039;@&#039;::text, 2), &#039;.&#039;::text, 2) || &#039;,dc=&#039;::text) || &lt;br /&gt;
                         split_part(split_part((mailbox.username)::text, &#039;@&#039;::text, 2), &#039;.&#039;::text, 3)) &lt;br /&gt;
             END) AS dn, &lt;br /&gt;
          1 AS oc_map_id, &lt;br /&gt;
          (SELECT ldap_dcs.id &lt;br /&gt;
           FROM ldap_dcs &lt;br /&gt;
           WHERE ((ldap_dcs.domain)::text = (mailbox.domain)::text)) AS parent, &lt;br /&gt;
           mailbox.id AS keyval &lt;br /&gt;
           FROM mailbox &lt;br /&gt;
           UNION &lt;br /&gt;
           SELECT ldap_dcs.id,  &lt;br /&gt;
                  ldap_dcs.dn, &lt;br /&gt;
                  ldap_dcs.oc_map_id, &lt;br /&gt;
                  ldap_dcs.parent, &lt;br /&gt;
                  ldap_dcs.keyval &lt;br /&gt;
           FROM ldap_dcs;&lt;br /&gt;
EOF&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* Fill out LDAP tables according to following example (make sure to separate values with TABs):&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
cat - &amp;lt;&amp;lt;EOF | psql -U postgres postfix&lt;br /&gt;
COPY ldap_attr_mappings (id, oc_map_id, name, sel_expr, sel_expr_u, from_tbls, join_where, add_proc, delete_proc, param_order, expect_return) FROM stdin;&lt;br /&gt;
1	1	displayName	mailbox.name	\N	mailbox	\N	\N	\N	3	0&lt;br /&gt;
2	1	mail	mailbox.username	\N	mailbox	\N	\N	\N	3	0&lt;br /&gt;
3	1	cn	mailbox.name	\N	mailbox	\N	\N	\N	3	0&lt;br /&gt;
4	1	userPassword	&#039;{CRYPT}&#039;||mailbox.password	\N	mailbox	\N	\N	\N	3	0&lt;br /&gt;
\.&lt;br /&gt;
&lt;br /&gt;
COPY ldap_oc_mappings (id, name, keytbl, keycol, create_proc, delete_proc, expect_return) FROM stdin;&lt;br /&gt;
1	exampleBox	mailbox	id	\N	\N	1&lt;br /&gt;
\.&lt;br /&gt;
EOF&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* Check that &amp;quot;ldap_dcs&amp;quot; view presens something like this:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
echo &#039;select * from ldap_dcs&#039; | psql -U postgres postfix&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
   id   |             dn              | oc_map_id | parent | keyval |       domain       &lt;br /&gt;
--------+-----------------------------+-----------+--------+--------+--------------------&lt;br /&gt;
 100000 | dc=com                      |         1 |      0 |      0 | com&lt;br /&gt;
 100001 | dc=example,dc=com           |         1 | 100000 |      0 | example.com&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* Check that &amp;quot;ldap_entries&amp;quot; view presens something like this:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
echo &#039;select * from ldap_entries&#039; | psql -U postgres postfix&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
   id   |                          dn                           | oc_map_id | parent | keyval &lt;br /&gt;
--------+-------------------------------------------------------+-----------+--------+--------&lt;br /&gt;
    1   | cn=address1,dc=example,dc=com                         |         1 | 100001 |    1&lt;br /&gt;
...&lt;br /&gt;
   123  | cn=address123,dc=example,dc=com                       |         1 | 100001 |    1&lt;br /&gt;
 100000 | dc=com                                                |         1 |      0 |    0&lt;br /&gt;
 100001 | dc=example,dc=com                                     |         1 | 100000 |    0&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* Configure ODBC parameters&lt;br /&gt;
&lt;br /&gt;
Edit /etc/odbc.ini:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
[PostgreSQL]&lt;br /&gt;
Description             = Connection to Postgres&lt;br /&gt;
Driver                  = PostgreSQL&lt;br /&gt;
Trace                   = Yes&lt;br /&gt;
TraceFile               = sql.log&lt;br /&gt;
Database                = postfix&lt;br /&gt;
Servername              = 127.0.0.1&lt;br /&gt;
UserName                =&lt;br /&gt;
Password                =&lt;br /&gt;
Port                    = 5432&lt;br /&gt;
Protocol                = 6.4&lt;br /&gt;
ReadOnly                = No&lt;br /&gt;
RowVersining            = No&lt;br /&gt;
ShowSystemTables        = No&lt;br /&gt;
ShowOidColumn           = No&lt;br /&gt;
FakeOidIndex            = No&lt;br /&gt;
ConnSettings            =&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Edit /etc/odbcinst.ini:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
[PostgreSQL]&lt;br /&gt;
Description     = PostgreSQL driver for Linux&lt;br /&gt;
Driver          = /usr/lib/psqlodbcw.so&lt;br /&gt;
Setup           = /usr/lib/libodbcpsqlS.so&lt;br /&gt;
FileUsage       = 1&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* Test ODBC connection&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
echo &amp;quot;select * from domain;&amp;quot; | isql PostgreSQL postgres&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* Provide permission to certificate for LDAP server&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
chown ldap /etc/lighttpd/server-bundle.pem&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* Edit LDAP schema&lt;br /&gt;
&lt;br /&gt;
Edit /etc/openldap/schema/example.com.schema:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
attributetype ( 0.9.2342.19200300.100.1.3&lt;br /&gt;
	NAME ( &#039;mail&#039; &#039;rfc822Mailbox&#039; )&lt;br /&gt;
	DESC &#039;RFC1274: RFC822 Mailbox&#039;&lt;br /&gt;
        EQUALITY caseIgnoreIA5Match&lt;br /&gt;
        SUBSTR caseIgnoreIA5SubstringsMatch&lt;br /&gt;
        SYNTAX 1.3.6.1.4.1.1466.115.121.1.26{256} )&lt;br /&gt;
&lt;br /&gt;
attributetype ( 2.16.840.1.113730.3.1.241&lt;br /&gt;
	NAME &#039;displayName&#039;&lt;br /&gt;
	DESC &#039;RFC2798: preferred name to be used when displaying entries&#039;&lt;br /&gt;
	EQUALITY caseIgnoreMatch&lt;br /&gt;
	SUBSTR caseIgnoreSubstringsMatch&lt;br /&gt;
	SYNTAX 1.3.6.1.4.1.1466.115.121.1.15&lt;br /&gt;
	SINGLE-VALUE )&lt;br /&gt;
&lt;br /&gt;
objectclass   ( 2.16.840.1.113730.3.2.2&lt;br /&gt;
        NAME &#039;exampleBox&#039;&lt;br /&gt;
	DESC &#039;example.com mailbox&#039;&lt;br /&gt;
	MUST ( displayName $ mail $ userPassword )&lt;br /&gt;
	)&lt;br /&gt;
&lt;br /&gt;
# RFC 1274 + RFC 2247&lt;br /&gt;
attributetype ( 0.9.2342.19200300.100.1.25&lt;br /&gt;
        NAME ( &#039;dc&#039; &#039;domainComponent&#039; )&lt;br /&gt;
        DESC &#039;RFC1274/2247: domain component&#039;&lt;br /&gt;
        EQUALITY caseIgnoreIA5Match&lt;br /&gt;
        SUBSTR caseIgnoreIA5SubstringsMatch&lt;br /&gt;
        SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 SINGLE-VALUE )&lt;br /&gt;
&lt;br /&gt;
attributetype ( 2.5.4.46 NAME &#039;dnQualifier&#039;&lt;br /&gt;
        DESC &#039;RFC2256: DN qualifier&#039;&lt;br /&gt;
        EQUALITY caseIgnoreMatch&lt;br /&gt;
        ORDERING caseIgnoreOrderingMatch&lt;br /&gt;
        SUBSTR caseIgnoreSubstringsMatch&lt;br /&gt;
        SYNTAX 1.3.6.1.4.1.1466.115.121.1.44 )&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* Configure LDAP server&lt;br /&gt;
&lt;br /&gt;
Edit /etc/openldap/slapd.conf:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
include         /etc/openldap/schema/example.com.schema&lt;br /&gt;
pidfile         /var/run/openldap/slapd.pid&lt;br /&gt;
argsfile        /var/run/openldap/slapd.args&lt;br /&gt;
&lt;br /&gt;
TLSCipherSuite HIGH&lt;br /&gt;
TLSCACertificateFile /etc/lighttpd/ca-crt.pem&lt;br /&gt;
TLSCertificateFile /etc/lighttpd/server-bundle.pem&lt;br /&gt;
TLSCertificateKeyFile /etc/lighttpd/server-bundle.pem&lt;br /&gt;
TLSVerifyClient never &lt;br /&gt;
&lt;br /&gt;
# This is needed for proper representation of MD5-CRYPT format stored in database&lt;br /&gt;
#  see more details in http://strugglers.net/~andy/blog/2010/01/23/openldap-and-md5crypt/&lt;br /&gt;
password-hash  {CRYPT}&lt;br /&gt;
password-crypt-salt-format &amp;quot;$1$%.8s&amp;quot;&lt;br /&gt;
&lt;br /&gt;
loglevel        stats&lt;br /&gt;
moduleload	/usr/lib/openldap/back_sql.so&lt;br /&gt;
sizelimit 3000&lt;br /&gt;
&lt;br /&gt;
database        sql&lt;br /&gt;
&lt;br /&gt;
dbname		PostgreSQL&lt;br /&gt;
dbuser		postfix&lt;br /&gt;
dbpasswd	*****&lt;br /&gt;
&lt;br /&gt;
suffix          &amp;quot;dc=example,dc=com&amp;quot;&lt;br /&gt;
rootdn          &amp;quot;cn=admin,dc=example,dc=com&amp;quot;&lt;br /&gt;
rootpw		{MD5}&amp;lt;Hashed password for root dn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
upper_func      &amp;quot;upper&amp;quot;&lt;br /&gt;
strcast_func    &amp;quot;text&amp;quot;&lt;br /&gt;
concat_pattern  &amp;quot;?||?&amp;quot;&lt;br /&gt;
has_ldapinfo_dn_ru      no&lt;br /&gt;
lastmod         off&lt;br /&gt;
&lt;br /&gt;
access to attrs=userPassword by * auth&lt;br /&gt;
&lt;br /&gt;
access to * by peername.ip=127.0.0.1 read&lt;br /&gt;
            ### by peername.ip=&amp;lt;IP&amp;gt;%&amp;lt;netmask&amp;gt; read&lt;br /&gt;
            ### by peername.ip=&amp;lt;IP&amp;gt; read&lt;br /&gt;
	    by users read&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* Set permissions for slapd.conf&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
chown ldap:ldap /etc/openldap/slapd.conf&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* Configure startup parameters to make sure that LDAP server start AFTER PostgreSQL and listens on localhost with clear text and public IP with SSL&lt;br /&gt;
&lt;br /&gt;
Edit /etc/conf.d/slapd:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
echo rc_need=&amp;quot;postgresql&amp;quot; &lt;br /&gt;
OPTS=&amp;quot;-h &#039;ldaps:// ldap://127.0.0.1&#039;&amp;quot;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* Start LDAP server&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
rc-update add slapd default&lt;br /&gt;
/etc/init.d/slapd start&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* Configure LDAP client utilities&lt;br /&gt;
&lt;br /&gt;
Edit /etc/openldap/ldap.conf&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
BASE	dc=example,dc=com&lt;br /&gt;
URI	ldaps://host.example.com&lt;br /&gt;
&lt;br /&gt;
TLS_CACERT /etc/lighttpd/ca-crt.pem&lt;br /&gt;
TLS_CERT /etc/lighttpd/server-bundle.pem&lt;br /&gt;
TLS_KEY /etc/lighttpd/server-bundle.pem&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* Test LDAP server&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
ldapsearch -z 3&lt;br /&gt;
ldapsearch -z 3 -x -W -D cn=admin,dc=example,dc=com&lt;br /&gt;
ldapsearch -z 3 -x -W -D cn=address1,dc=example,dc=com&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* Configure RoundCube webmail for email lookups&lt;br /&gt;
&lt;br /&gt;
Edit /usr/share/webapps/roundcube/config/main.inc.php:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
$rcmail_config[&#039;ldap_debug&#039;] = false;&lt;br /&gt;
...&lt;br /&gt;
$rcmail_config[&#039;address_book_type&#039;] = &#039;ldap&#039;;&lt;br /&gt;
&lt;br /&gt;
$rcmail_config[&#039;ldap_public&#039;][&#039;example.com&#039;] = array(&lt;br /&gt;
  &#039;name&#039;          =&amp;gt; &#039;example.com&#039;,&lt;br /&gt;
  &#039;hosts&#039;         =&amp;gt; array(&#039;127.0.0.1&#039;),&lt;br /&gt;
  &#039;port&#039;          =&amp;gt; 389,&lt;br /&gt;
  &#039;use_tls&#039;         =&amp;gt; false,&lt;br /&gt;
  &#039;user_specific&#039; =&amp;gt; false,&lt;br /&gt;
  &#039;base_dn&#039;       =&amp;gt; &#039;dc=example,dc=com&#039;,&lt;br /&gt;
  &#039;bind_dn&#039;       =&amp;gt; &#039;&#039;,&lt;br /&gt;
  &#039;bind_pass&#039;     =&amp;gt; &#039;&#039;,&lt;br /&gt;
  &#039;writable&#039;      =&amp;gt; false,&lt;br /&gt;
  &#039;LDAP_Object_Classes&#039; =&amp;gt; array(&amp;quot;top&amp;quot;, &amp;quot;exampleBox&amp;quot;),&lt;br /&gt;
  &#039;required_fields&#039;     =&amp;gt; array(&amp;quot;cn&amp;quot;, &amp;quot;sn&amp;quot;, &amp;quot;mail&amp;quot;),&lt;br /&gt;
  &#039;LDAP_rdn&#039;      =&amp;gt; &#039;mail&#039;,&lt;br /&gt;
  &#039;ldap_version&#039;  =&amp;gt; 3,&lt;br /&gt;
  &#039;search_fields&#039; =&amp;gt; array(&#039;mail&#039;, &#039;cn&#039;, &#039;sn&#039;, &#039;givenName&#039;),&lt;br /&gt;
  &#039;name_field&#039;    =&amp;gt; &#039;cn&#039;,&lt;br /&gt;
  &#039;email_field&#039;   =&amp;gt; &#039;mail&#039;,&lt;br /&gt;
  &#039;surname_field&#039; =&amp;gt; &#039;sn&#039;,&lt;br /&gt;
  &#039;firstname_field&#039; =&amp;gt; &#039;gn&#039;,&lt;br /&gt;
  &#039;sort&#039;          =&amp;gt; &#039;cn&#039;,&lt;br /&gt;
  &#039;scope&#039;         =&amp;gt; &#039;sub&#039;,&lt;br /&gt;
  &#039;filter&#039;        =&amp;gt; &#039;(objectClass=*)&#039;, // Construct here any filter you need&lt;br /&gt;
  &#039;fuzzy_search&#039;  =&amp;gt; true);&lt;br /&gt;
&lt;br /&gt;
$rcmail_config[&#039;autocomplete_addressbooks&#039;] = array(&#039;example.com&#039;);&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== log rotation ==&lt;br /&gt;
&lt;br /&gt;
Ensure the busybox cron service is started and is configured to auto-start:&lt;br /&gt;
&lt;br /&gt;
 /etc/init.d/cron start&lt;br /&gt;
 rc-update add cron default&lt;br /&gt;
&lt;br /&gt;
Add log rotate:&lt;br /&gt;
&lt;br /&gt;
 apk add logrotate&lt;br /&gt;
&lt;br /&gt;
Edit &#039;&#039;/etc/logrotate.conf&#039;&#039; as desired, but the defaults should be sufficient for most people.&lt;br /&gt;
&lt;br /&gt;
== Configure DNS ==&lt;br /&gt;
&lt;br /&gt;
This server hosts three separate web applications, and these can be handled as three different virtual domains on the same web server. They will be distinguished by their DNS names, so you can choose domains for the three separate services (or at least the ones you want to publish):&lt;br /&gt;
&lt;br /&gt;
* ACF - Alpine Configuration Framework for managing the server&lt;br /&gt;
* PostfixAdmin - for managing the postfix installation&lt;br /&gt;
* RoundCube - for accessing individual mailboxes&lt;br /&gt;
&lt;br /&gt;
Choose three different domains (from here on known as ACF_DOMAIN, POSTFIXADMIN_DOMAIN, and ROUNDCUBE_DOMAIN) and configure DNS for all three to point to the IP address of your host. These should be DNS A records.&lt;br /&gt;
&lt;br /&gt;
Then, configure lighttpd to handle the three separate domains by editing /etc/lighttpd/lighttpd.conf:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 $HTTP[&amp;quot;host&amp;quot;] == &amp;quot;ACF_DOMAIN&amp;quot; {&lt;br /&gt;
	simple-vhost.server-root   = &amp;quot;/var/www/domains/&amp;quot;&lt;br /&gt;
	simple-vhost.default-host  = &amp;quot;/ACF_DOMAIN/&amp;quot;&lt;br /&gt;
	simple-vhost.document-root = &amp;quot;www/&amp;quot;&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
 $HTTP[&amp;quot;host&amp;quot;] == &amp;quot;POSTFIXADMIN_DOMAIN&amp;quot; {&lt;br /&gt;
	simple-vhost.server-root   = &amp;quot;/var/www/domains/&amp;quot;&lt;br /&gt;
	simple-vhost.default-host  = &amp;quot;/POSTFIXADMIN_DOMAIN/&amp;quot;&lt;br /&gt;
	simple-vhost.document-root = &amp;quot;www/&amp;quot;&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
 $HTTP[&amp;quot;host&amp;quot;] == &amp;quot;ROUNDCUBE_DOMAIN&amp;quot; {&lt;br /&gt;
	simple-vhost.server-root   = &amp;quot;/var/www/domains/&amp;quot;&lt;br /&gt;
	simple-vhost.default-host  = &amp;quot;/ROUNDCUBE_DOMAIN/&amp;quot;&lt;br /&gt;
	simple-vhost.document-root = &amp;quot;www/&amp;quot;&lt;br /&gt;
 }&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
And, then link the appropriate www directories.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  mkdir -p /var/www/domains/ACF_DOMAIN&lt;br /&gt;
  ln -s /usr/share/acf/www /var/www/domains/ACF_DOMAIN/www&lt;br /&gt;
&lt;br /&gt;
  mkdir -p /var/www/domains/POSTFIXADMIN_DOMAIN&lt;br /&gt;
  ln -s /var/www/domains/host.example.com/www/postfixadmin /var/www/domains/POSTFIXADMIN_DOMAIN/www&lt;br /&gt;
&lt;br /&gt;
  mkdir -p /var/www/domains/ROUNDCUBE_DOMAIN&lt;br /&gt;
  ln -s /usr/share/webapps/roundcube /var/www/domains/ROUNDCUBE_DOMAIN/www&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;/div&gt;</summary>
		<author><name>Djhughes</name></author>
	</entry>
	<entry>
		<id>https://wiki.alpinelinux.org/w/index.php?title=ISP_Mail_Server_HowTo&amp;diff=3494</id>
		<title>ISP Mail Server HowTo</title>
		<link rel="alternate" type="text/html" href="https://wiki.alpinelinux.org/w/index.php?title=ISP_Mail_Server_HowTo&amp;diff=3494"/>
		<updated>2010-03-18T06:41:53Z</updated>

		<summary type="html">&lt;p&gt;Djhughes: formatting&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== A Full Service Mail Server ==&lt;br /&gt;
&lt;br /&gt;
The goal of this document is to describe how to set up postfix, dovecot, clamav, dspam, roundecube, and postfixadmin for a full-featured &amp;quot;ISP&amp;quot; level mail server.&lt;br /&gt;
&lt;br /&gt;
The server must provide:&lt;br /&gt;
&lt;br /&gt;
* multiple virtual domains&lt;br /&gt;
* admins for each domain (to add/remove virtual accounts)&lt;br /&gt;
* Quota support per domain / account&lt;br /&gt;
* downloading email via IMAP / IMAPS / POP3 / POP3S&lt;br /&gt;
* relaying email for authenticated users with TLS or SSL (Submission / SMTPS protocol)&lt;br /&gt;
* Standard filters (virus/spam/rbl/etc)&lt;br /&gt;
* Web mail client&lt;br /&gt;
* Value Add services&lt;br /&gt;
&lt;br /&gt;
== Set up Lighttpd + PHP ==&lt;br /&gt;
&lt;br /&gt;
PostfixAdmin needs php pgpsql and imap modules, so we do it in this step.&lt;br /&gt;
&lt;br /&gt;
  apk add lighttpd php php-pgsql php-imap&lt;br /&gt;
&lt;br /&gt;
Stop and remove mini_httpd, and move ACF to lighttpd;  We are setting this up to be a multi-domain virtual web server (replace host.example.com with the actual domain):&lt;br /&gt;
&lt;br /&gt;
  mkdir -p /var/www/domains/host.example.com/www&lt;br /&gt;
  ln -s /usr/share/acf/www /var/www/domains/host.example.com/www/acf&lt;br /&gt;
&lt;br /&gt;
Edit /var/www/domains/host.example.com/index.html to put a simple redirection page:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;lt;!DOCTYPE HTML PUBLIC &amp;quot;-//W3C//DTD HTML 4.01//EN&amp;quot; &amp;quot;http://www.w3.org/TR/html4/strict.dtd&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;html lang=&amp;quot;en&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;head&amp;gt;&lt;br /&gt;
&amp;lt;meta http-equiv=&amp;quot;Content-Type&amp;quot; content=&amp;quot;text/html; charset=ISO-8859-1&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;title&amp;gt;host.example.com Redirector&amp;lt;/title&amp;gt;&lt;br /&gt;
&amp;lt;/head&amp;gt;&lt;br /&gt;
&amp;lt;body&amp;gt;&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;&amp;lt;a href=&amp;quot;/acf&amp;quot;&amp;gt;ACF&amp;lt;/a&amp;gt;&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;&amp;lt;a href=&amp;quot;/postfixadmin&amp;quot;&amp;gt;PostfixAdmin&amp;lt;/a&amp;gt;&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;&amp;lt;a href=&amp;quot;/roundcube&amp;quot;&amp;gt;Roundcube&amp;lt;/a&amp;gt;&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
&amp;lt;/body&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Edit /etc/lighttpd/mod_cgi.conf to serve haserl files by adding a &amp;quot;&amp;quot; =&amp;gt; &amp;quot;&amp;quot; cgi handler and to treat /acf/cgi-bin as a CGI directory (remove the &#039;^&#039;)&lt;br /&gt;
&lt;br /&gt;
 $HTTP[&amp;quot;url&amp;quot;] =~ &amp;quot;/cgi-bin/&amp;quot; {&lt;br /&gt;
     # disable directory listings&lt;br /&gt;
     dir-listing.activate = &amp;quot;disable&amp;quot;&lt;br /&gt;
     # only allow cgi&#039;s in this directory&lt;br /&gt;
     cgi.assign = (&lt;br /&gt;
 		&amp;quot;.pl&amp;quot;	=&amp;gt;	&amp;quot;/usr/bin/perl&amp;quot;,&lt;br /&gt;
 		&amp;quot;.cgi&amp;quot;	=&amp;gt;	&amp;quot;/usr/bin/perl&amp;quot;,&lt;br /&gt;
 		&amp;quot;&amp;quot; =&amp;gt; &amp;quot;&amp;quot;&lt;br /&gt;
 	)&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
Add these lines to /etc/lighttpd/lighttpd.conf to point to the new document root, and set it up to listen on port 443 (replace &#039;&#039;host.example.com&#039;&#039; with the actual domain and &#039;&#039;ip_address_of_server&#039;&#039; with the actual IP address):&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
simple-vhost.server-root   = &amp;quot;/var/www/domains/&amp;quot;&lt;br /&gt;
simple-vhost.default-host  = &amp;quot;/host.example.com/&amp;quot;&lt;br /&gt;
simple-vhost.document-root = &amp;quot;www/&amp;quot;&lt;br /&gt;
&lt;br /&gt;
$SERVER[&amp;quot;socket&amp;quot;] == &amp;quot;ip_address_of_server:443&amp;quot; {&lt;br /&gt;
ssl.engine    = &amp;quot;enable&amp;quot;&lt;br /&gt;
ssl.pemfile   = &amp;quot;/etc/lighttpd/server-bundle.pem&amp;quot;&lt;br /&gt;
ssl.ca-file   = &amp;quot;/etc/lighttpd/ca-crt.pem&amp;quot;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Ensure that the simple_vhosts module is loaded, as well as the cgi config scripts by uncommenting the following lines in /etc/lighttpd/lighttpd.conf&lt;br /&gt;
&lt;br /&gt;
 server.modules = (&lt;br /&gt;
     #  other modules may be listed&lt;br /&gt;
     &amp;quot;mod_simple_vhost&amp;quot;, &lt;br /&gt;
     #  other modules may be listed&lt;br /&gt;
  .&lt;br /&gt;
  .&lt;br /&gt;
  .&lt;br /&gt;
     include &amp;quot;mod_cgi.conf&amp;quot;&lt;br /&gt;
 &lt;br /&gt;
     include &amp;quot;mod_fastcgi.conf&amp;quot;&lt;br /&gt;
 &lt;br /&gt;
&lt;br /&gt;
Get a web certificate, and install it.  If you want to use a self-signed cert, you can use [[Generating SSL certs with ACF]] or [[Generating SSL certs with ACF 1.9]].  If you create a certificate with ACF, you can create the &amp;quot;server-bundle.pem&amp;quot; and the &amp;quot;ca-crt.pem&amp;quot; file with these commands:&lt;br /&gt;
&lt;br /&gt;
  openssl pkcs12 -nokeys -cacerts -in certificate.pfx  -out /etc/lighttpd/ca-crt.pem&lt;br /&gt;
  openssl pkcs12 -nodes -in certifcate.pfx -out /etc/lighttpd/server-bundle.pem&lt;br /&gt;
  chown root:root /etc/lighttpd/server-bundle.pem&lt;br /&gt;
  chmod 400 /etc/lighttpd/server-bundle.pem&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Note:&#039;&#039;&#039; The server certificate &#039;&#039;and&#039;&#039; key are in the server-bundle.pem file, so it is critical that the file be read-only by user &amp;quot;root&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
 Editme: We should probably only serve ACF to restricted hosts&lt;br /&gt;
&lt;br /&gt;
Stop and remove mini_httpd; start lighttpd, test&lt;br /&gt;
&lt;br /&gt;
  /etc/init.d/mini_httpd stop&lt;br /&gt;
  rc-update del mini_httpd&lt;br /&gt;
  apk del mini_httpd&lt;br /&gt;
  rc-update add lighttpd&lt;br /&gt;
  /etc/init.d/lighttpd start&lt;br /&gt;
&lt;br /&gt;
At this point you should be able to see ACF being served with lighttpd (Note: this will work well with alpine 1.10. With earlier versions there will be problems.)  https://host.example.com/acf/&lt;br /&gt;
&lt;br /&gt;
== Install Postgresql ==&lt;br /&gt;
&lt;br /&gt;
Add and configure postgresql&lt;br /&gt;
&lt;br /&gt;
  apk add acf-postgresql postgresql-client&lt;br /&gt;
  /etc/init.d/postgresql setup&lt;br /&gt;
  /etc/init.d/postgresql start&lt;br /&gt;
  rc-update add postgresql&lt;br /&gt;
&lt;br /&gt;
At this point any user can connect to the sql server with &amp;quot;trust&amp;quot; mechanism.  If you want to enforce password authentication (you probably do) edit /var/lib/postgresql/8.4/data/pg_hba.conf&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
  Editme: What should we recommend?&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Create the postfix database:&lt;br /&gt;
&lt;br /&gt;
  psql -U postgres&lt;br /&gt;
   create user postfix with password &#039;******&#039;;&lt;br /&gt;
   create database postfix owner postfix;&lt;br /&gt;
   \c postfix&lt;br /&gt;
   create language plpgsql;&lt;br /&gt;
   \q&lt;br /&gt;
&lt;br /&gt;
(Of course, use your selected password where ******* is shown above.)&lt;br /&gt;
&lt;br /&gt;
== Install PostfixAdmin ==&lt;br /&gt;
&lt;br /&gt;
We are going to install the postfix admin web front-end before we install the mail server.  This just creates an interface to populate the SQL tables that postfix and dovecot will use.&lt;br /&gt;
&lt;br /&gt;
Download PostfixAdmin from Sourceforge.  When these instructions were written, 2.3 was the current release, so (replace host.example.com with the actual domain):&lt;br /&gt;
 wget http://downloads.sourceforge.net/project/postfixadmin/postfixadmin/postfixadmin_2.3.tar.gz&lt;br /&gt;
 tar zxvf postfixadmin_2.3.tar.gz&lt;br /&gt;
 mkdir -p /var/www/domains/host.example.com/www/postfixadmin&lt;br /&gt;
 mv postfixadmin-2.3/* /var/www/domains/host.example.com/www/postfixadmin&lt;br /&gt;
 rm -rf postfixadmin*&lt;br /&gt;
&lt;br /&gt;
Edit /var/www/domains/host.example.com/www/postfixadmin/config.inc.php and modify at least these lines (replace host.example.com with the actual domain):&lt;br /&gt;
&lt;br /&gt;
 $CONF[&#039;configured&#039;] = true;&lt;br /&gt;
 $CONF[&#039;setup_password&#039;] = &amp;quot;&amp;quot;;  &amp;lt;&amp;lt; Don&#039;t change this yet&lt;br /&gt;
 $CONF[&#039;database_type&#039;] = &#039;pgsql&#039;;&lt;br /&gt;
 $CONF[&#039;database_host&#039;] = &#039;localhost&#039;;&lt;br /&gt;
 $CONF[&#039;database_user&#039;] = &#039;postfix&#039;;&lt;br /&gt;
 $CONF[&#039;database_password&#039;] = &#039;*****&#039;;   &amp;lt;&amp;lt; The password you chose above&lt;br /&gt;
 $CONF[&#039;database_name&#039;] = &#039;postfix&#039;;&lt;br /&gt;
 $CONF[&#039;database_prefix&#039;] = &amp;quot;&amp;quot;;&lt;br /&gt;
 $CONF[&#039;admin_email&#039;] = &#039;you@some.email.com&#039;;  &amp;lt;&amp;lt; Your email address &lt;br /&gt;
 $CONF[&#039;encrypt&#039;] = &#039;md5crypt&#039;;&lt;br /&gt;
 $CONF[&#039;authlib_default_flavor&#039;] = &#039;md5raw&#039;;&lt;br /&gt;
 $CONF[&#039;dovecotpw&#039;] = &amp;quot;/usr/sbin/dovecotpw&amp;quot;;&lt;br /&gt;
 $CONF[&#039;domain_path&#039;] = &#039;YES&#039;;&lt;br /&gt;
 $CONF[&#039;domain_in_mailbox&#039;] = &#039;NO&#039;;&lt;br /&gt;
 $CONF[&#039;aliases&#039;] = &#039;10&#039;;                       &lt;br /&gt;
 $CONF[&#039;mailboxes&#039;] = &#039;10&#039;;&lt;br /&gt;
 $CONF[&#039;maxquota&#039;] = &#039;10&#039;;&lt;br /&gt;
 $CONF[&#039;quota&#039;] = &#039;YES&#039;;&lt;br /&gt;
 $CONF[&#039;quota_multiplier&#039;] = &#039;1024000&#039;;&lt;br /&gt;
 $CONF[&#039;vacation&#039;] = &#039;NO&#039;; &lt;br /&gt;
 $CONF[&#039;vacation_control&#039;] =&#039;NO&#039;;&lt;br /&gt;
 $CONF[&#039;vacation_control_admin&#039;] = &#039;NO&#039;;&lt;br /&gt;
 $CONF[&#039;alias_control&#039;] = &#039;YES&#039;;&lt;br /&gt;
 $CONF[&#039;alias_control_admin&#039;] = &#039;YES&#039;;&lt;br /&gt;
 $CONF[&#039;special_alias_control&#039;] = &#039;YES&#039;;&lt;br /&gt;
 $CONF[&#039;fetchmail&#039;] = &#039;NO&#039;;&lt;br /&gt;
 $CONF[&#039;user_footer_link&#039;] = &amp;quot;http://host.example.com/postfixadmin&amp;quot;;&lt;br /&gt;
 $CONF[&#039;footer_link&#039;] = &#039;http://host.example.com/postfixadmin/main.php&#039;;&lt;br /&gt;
 $CONF[&#039;create_mailbox_subdirs_prefix&#039;]=&amp;quot;&amp;quot;;  &lt;br /&gt;
 $CONF[&#039;used_quotas&#039;] = &#039;YES&#039;;   &lt;br /&gt;
 $CONF[&#039;new_quota_table&#039;] = &#039;YES&#039;;  &lt;br /&gt;
&lt;br /&gt;
You should further edit /var/www/domains/host.example.com/www/postfixadmin/config.inc.php and replace all instances of &amp;quot;change-this-to-your.domain.tld&amp;quot; with your actual mail domain.&lt;br /&gt;
&lt;br /&gt;
Go to http://host.example.com/postfixadmin/setup.php&lt;br /&gt;
&lt;br /&gt;
Create the password hash, add it to the config.inc.php file&lt;br /&gt;
&lt;br /&gt;
Go back to http://host.example.com/postfixadmin/setup.php&lt;br /&gt;
&lt;br /&gt;
Create superadmin account.&lt;br /&gt;
&lt;br /&gt;
== Install Postfix ==&lt;br /&gt;
&lt;br /&gt;
Create a user for the virtual mail delivery, and get its uid/gid (you&#039;ll need the numeric uid/gid for postfix)&lt;br /&gt;
&lt;br /&gt;
 adduser vmail -H -D -s /bin/false&lt;br /&gt;
 grep vmail /etc/passwd&lt;br /&gt;
&lt;br /&gt;
(In examples below, we use 1006/1006 for the uid/gid)&lt;br /&gt;
&lt;br /&gt;
Create the mail directory, and assign vmail as the owner&lt;br /&gt;
 mkdir -p /var/mail/domains&lt;br /&gt;
 chown -R vmail:vmail /var/mail/domains&lt;br /&gt;
 &lt;br /&gt;
&lt;br /&gt;
Install postfix&lt;br /&gt;
&lt;br /&gt;
 apk add acf-postfix postfix-pgsql&lt;br /&gt;
&lt;br /&gt;
Edit the /etc/postfix/main.cf file. Here&#039;s an example (don&#039;t forget to replace the uid/gid):&lt;br /&gt;
&lt;br /&gt;
 myhostname=host.example.com&lt;br /&gt;
 mydomain=example.com&lt;br /&gt;
 &lt;br /&gt;
 mydestination = localhost.$mydomain, localhost&lt;br /&gt;
 mynetworks_style = subnet&lt;br /&gt;
 mynetworks = 127.0.0.0/8&lt;br /&gt;
 &lt;br /&gt;
 virtual_mailbox_domains = proxy:pgsql:/etc/postfix/sql/pgsql_virtual_domains_maps.cf&lt;br /&gt;
 virtual_alias_maps = proxy:pgsql:/etc/postfix/sql/pgsql_virtual_alias_maps.cf,&lt;br /&gt;
        proxy:pgsql:/etc/postfix/sql/pgsql_virtual_alias_domain_maps.cf,&lt;br /&gt;
        proxy:pgsql:/etc/postfix/sql/pgsql_virtual_alias_domain_catchall_maps.cf&lt;br /&gt;
 &lt;br /&gt;
 virtual_mailbox_maps = proxy:pgsql:/etc/postfix/sql/pgsql_virtual_mailbox_maps.cf,&lt;br /&gt;
        proxy:pgsql:/etc/postfix/sql/pgsql_virtual_alias_domain_mailbox_maps.cf&lt;br /&gt;
 &lt;br /&gt;
 virtual_mailbox_base = /var/mail/domains/&lt;br /&gt;
 virtual_gid_maps = static:1006&lt;br /&gt;
 virtual_uid_maps = static:1006&lt;br /&gt;
 virtual_minimum_uid = 100&lt;br /&gt;
 virtual_transport = virtual&lt;br /&gt;
 &lt;br /&gt;
 &lt;br /&gt;
 # This next command means you must create a virtual&lt;br /&gt;
 # domain for the host itself - ALL mail goes through&lt;br /&gt;
 # The virtual transport&lt;br /&gt;
 &lt;br /&gt;
 mailbox_transport = virtual&lt;br /&gt;
 local_transport = virtual&lt;br /&gt;
 local_transport_maps = $virtual_mailbox_maps&lt;br /&gt;
 &lt;br /&gt;
 smtpd_helo_required = yes&lt;br /&gt;
 disable_vrfy_command = yes&lt;br /&gt;
 message_size_limit = 10240000&lt;br /&gt;
 queue_minfree = 51200000&lt;br /&gt;
 &lt;br /&gt;
 smtpd_sender_restrictions =&lt;br /&gt;
        permit_mynetworks,&lt;br /&gt;
        reject_non_fqdn_sender,&lt;br /&gt;
        reject_unknown_sender_domain&lt;br /&gt;
 &lt;br /&gt;
 smtpd_recipient_restrictions =&lt;br /&gt;
        reject_non_fqdn_recipient,&lt;br /&gt;
        reject_unknown_recipient_domain,&lt;br /&gt;
        permit_mynetworks,&lt;br /&gt;
        permit_sasl_authenticated,&lt;br /&gt;
        reject_unauth_destination,&lt;br /&gt;
        reject_rbl_client dnsbl.sorbs.net,&lt;br /&gt;
        reject_rbl_client zen.spamhaus.org,&lt;br /&gt;
        reject_rbl_client bl.spamcop.net&lt;br /&gt;
 &lt;br /&gt;
 smtpd_data_restrictions = reject_unauth_pipelining&lt;br /&gt;
 &lt;br /&gt;
 # we will use this later - This prevents cleartext authentication&lt;br /&gt;
 # for relaying&lt;br /&gt;
 smtpd_tls_auth_only = yes&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Now we need to create a *bunch* of files so that postfix can get the delivery information out of sql. Here&#039;s a shell script to create the scripts.  Change PGPW to the password for the postfix user of the postfix SQL database.&lt;br /&gt;
&lt;br /&gt;
 cd /etc/postfix&lt;br /&gt;
 mkdir sql&lt;br /&gt;
 PGPW=&amp;quot;ChangeMe&amp;quot;&lt;br /&gt;
 &lt;br /&gt;
 cat - &amp;lt;&amp;lt;EOF &amp;gt;sql/pgsql_virtual_alias_domain_catchall_maps.cf&lt;br /&gt;
 user=postfix&lt;br /&gt;
 password = $PGPW&lt;br /&gt;
 hosts = localhost&lt;br /&gt;
 dbname = postfix&lt;br /&gt;
 query = Select goto From alias,alias_domain where alias_domain.alias_domain = &#039;%d&#039; and alias.address = &#039;@&#039; ||  alias_domain.target_domain and alias.active = true and alias_domain.active= true &lt;br /&gt;
 EOF&lt;br /&gt;
 &lt;br /&gt;
 cat - &amp;lt;&amp;lt;EOF &amp;gt;sql/pgsql_virtual_alias_domain_mailbox_maps.cf&lt;br /&gt;
 user=postfix&lt;br /&gt;
 password = $PGPW&lt;br /&gt;
 hosts = localhost&lt;br /&gt;
 dbname = postfix&lt;br /&gt;
 query = Select maildir from mailbox,alias_domain where alias_domain.alias_domain = &#039;%d&#039; and mailbox.username = &#039;%u&#039; || &#039;@&#039; || alias_domain.target_domain and mailbox.active = true and alias_domain.active&lt;br /&gt;
 EOF&lt;br /&gt;
 &lt;br /&gt;
 cat - &amp;lt;&amp;lt;EOF &amp;gt;sql/pgsql_virtual_alias_domain_maps.cf&lt;br /&gt;
 user=postfix&lt;br /&gt;
 password = $PGPW&lt;br /&gt;
 hosts = localhost&lt;br /&gt;
 dbname = postfix&lt;br /&gt;
 query = select goto from alias,alias_domain where alias_domain.alias_domain=&#039;%d&#039; and alias.address = &#039;%u&#039; || &#039;@&#039; || alias_domain.target_domain and alias.active= true and alias_domain.active= true&lt;br /&gt;
 EOF&lt;br /&gt;
 &lt;br /&gt;
 cat - &amp;lt;&amp;lt;EOF &amp;gt;sql/pgsql_virtual_alias_maps.cf&lt;br /&gt;
 user=postfix&lt;br /&gt;
 password = $PGPW&lt;br /&gt;
 hosts = localhost&lt;br /&gt;
 dbname = postfix&lt;br /&gt;
 query = Select goto From alias Where address=&#039;%s&#039; and active =&#039;1&#039;&lt;br /&gt;
 EOF&lt;br /&gt;
 &lt;br /&gt;
 cat - &amp;lt;&amp;lt;EOF &amp;gt;sql/pgsql_virtual_domains_maps.cf&lt;br /&gt;
 user=postfix&lt;br /&gt;
 password = $PGPW&lt;br /&gt;
 hosts = localhost&lt;br /&gt;
 dbname = postfix&lt;br /&gt;
 query = Select domain from domain where domain=&#039;%s&#039; and active=&#039;1&#039;&lt;br /&gt;
 EOF&lt;br /&gt;
 &lt;br /&gt;
 cat - &amp;lt;&amp;lt;EOF &amp;gt;sql/pgsql_virtual_mailbox_maps.cf&lt;br /&gt;
 user=postfix&lt;br /&gt;
 password = $PGPW&lt;br /&gt;
 hosts = localhost&lt;br /&gt;
 dbname = postfix&lt;br /&gt;
 query = Select maildir from mailbox where username=&#039;%s&#039; and active=true&lt;br /&gt;
 EOF&lt;br /&gt;
 &lt;br /&gt;
 chown -R postfix:postfix sql&lt;br /&gt;
 chmod 640 sql/*&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
At this point you should be able to start up postfix&lt;br /&gt;
 &lt;br /&gt;
 newaliases  # so postfix is happy...&lt;br /&gt;
 /etc/init.d/postfix start&lt;br /&gt;
 rc-update add postfix&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Create a domain in PostfixAdmin and test ===&lt;br /&gt;
&lt;br /&gt;
Go to http://host.example.com/postfixadmin/&lt;br /&gt;
&lt;br /&gt;
Log in using the superadmin account, create a domain for the local box (e.g. example.com), and create a user mailbox (e.g. root).&lt;br /&gt;
&lt;br /&gt;
From the machine, send a test message:&lt;br /&gt;
&lt;br /&gt;
 sendmail -t root@example.com&lt;br /&gt;
 subject: test&lt;br /&gt;
 .&lt;br /&gt;
 ^d&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
In /var/log/mail.log (or /var/log/messages, if you still have busybox syslogd running) you should see the message queued.  The message should be in /var/mail/domains/example.com/root/new&lt;br /&gt;
&lt;br /&gt;
== Install Dovecot ==&lt;br /&gt;
&lt;br /&gt;
Dovecot is the POP3/IMAP server to retrieve mail.&lt;br /&gt;
&lt;br /&gt;
As before, we install dovecot: &lt;br /&gt;
&lt;br /&gt;
 apk add acf-dovecot dovecot-pgsql&lt;br /&gt;
&lt;br /&gt;
edit /etc/dovecot/dovecot.conf&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 # Select only the protocols you wish to support - all are listed in the next line&lt;br /&gt;
 protocols               =       imap imaps pop pop3s&lt;br /&gt;
 log_path                =       /var/log/dovecot.log&lt;br /&gt;
 info_log_path           =       /var/log/dovecot-info.log&lt;br /&gt;
 disable_plaintext_auth  =       no&lt;br /&gt;
&lt;br /&gt;
 # Authenticated IMAP&lt;br /&gt;
 ssl                     =       yes&lt;br /&gt;
 ssl_cert_file           =       /etc/lighttpd/server-bundle.pem&lt;br /&gt;
 ssl_key_file            =       /etc/lighttpd/server-bundle.pem&lt;br /&gt;
 auth_verbose            =       yes&lt;br /&gt;
 auth_debug              =       no&lt;br /&gt;
 mail_location           =       maildir:/var/mail/domains/%d/%n&lt;br /&gt;
 auth default    {&lt;br /&gt;
        mechanisms = plain&lt;br /&gt;
        passdb sql {&lt;br /&gt;
                args = /etc/dovecot/dovecot-sql.conf&lt;br /&gt;
                }&lt;br /&gt;
        userdb static {&lt;br /&gt;
                args =  uid=1006 gid=1006 home=/var/mail/domains/%d/%n&lt;br /&gt;
                }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Be sure to replace the uid and gid with the appropriate values for the vmail user.&lt;br /&gt;
&lt;br /&gt;
We need a certificate for SSL/TLS authentication, so in the example above, we use the lighttpd cert. That way when the cert is renewed/replaced, Dovecot will have access to the new cert as well.  &lt;br /&gt;
&lt;br /&gt;
Create the /etc/dovecot/dovecot-sql.conf file:&lt;br /&gt;
&lt;br /&gt;
 driver = pgsql&lt;br /&gt;
 connect = host=localhost dbname=postfix user=postfix password=********&lt;br /&gt;
 password_query = select username,password from mailbox where local_part = &#039;%n&#039; and domain = &#039;%d&#039;&lt;br /&gt;
 default_pass_scheme =  MD5-CRYPT&lt;br /&gt;
&lt;br /&gt;
Again, change the password above to your postfix user password, and protect the file from prying eyes:&lt;br /&gt;
&lt;br /&gt;
 chown root:root /etc/dovecot/dovecot-sql.conf&lt;br /&gt;
 chmod 600 /etc/dovecot/dovecot-sql.conf&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Start dovecot&lt;br /&gt;
 /etc/init.d/dovecot start&lt;br /&gt;
 rc-update add dovecot&lt;br /&gt;
&lt;br /&gt;
== Testing ==&lt;br /&gt;
&lt;br /&gt;
Make sure your firewall allows in ports 25(SMTP) 110 (POP3), 995 (POP3S), 143(IMAP), 993(IMAPS), or whatever subset you support.  &lt;br /&gt;
 &lt;br /&gt;
At this point, you should be able to:&lt;br /&gt;
 * Create a new domain and add users with PostfixAdmin&lt;br /&gt;
 * Send mail to those users via SMTP to port 25&lt;br /&gt;
 * Retrieve mail using the user&#039;s full email and password (e.g. username: user@example.com  password: ChangeMe)&lt;br /&gt;
&lt;br /&gt;
== Value Add Features ==&lt;br /&gt;
&lt;br /&gt;
If you followed the guide above, you now have a functional mail server with many interconnected parts.  The features below assume that the server is already running as described above.  You should be able to add any or all of these features below to further enhance the mail service.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Virus Scanning ===&lt;br /&gt;
&lt;br /&gt;
This procedure uses clamav and the postfix content_filter mechanism to scan inbound and outbound email for viruses.  Infected emails are dropped.  Clean emails are tagged with a &amp;quot;scanned by clamav&amp;quot; header.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* Install clamav and clamsmtp:&lt;br /&gt;
 apk add acf-clamav clamsmtp&lt;br /&gt;
* Edit the /etc/clamav/clamd.conf file if desired (not necessary in most cases)&lt;br /&gt;
* Edit /etc/clamsmtpd.conf and verify the following lines&lt;br /&gt;
 OutAddress: 10026&lt;br /&gt;
 Listen: 127.0.0.1:10025                                               &lt;br /&gt;
 Header: X-Virus-Scanned: ClamAV using ClamSMTP&lt;br /&gt;
 Action: drop&lt;br /&gt;
 User: clamav                                                      &lt;br /&gt;
* Start the daemons&lt;br /&gt;
 rc-update add clamd&lt;br /&gt;
 rc-update add freshclam&lt;br /&gt;
 rc-update add clamsmtp&lt;br /&gt;
 /etc/init.d/clamd start&lt;br /&gt;
 /etc/init.d/freshclam start&lt;br /&gt;
 /etc/init.d/clamsmtp start&lt;br /&gt;
* Verify clamsmtp is listening on port 10025:&lt;br /&gt;
 netstat -anp | grep clamsmtp&lt;br /&gt;
* [http://memberwebs.com/stef/software/clamsmtp/postfix.html Following the clamsmtp instructions]&lt;br /&gt;
** edit /etc/postfix/main.cf and add:&lt;br /&gt;
 content_filter = scan:[127.0.0.1]:10025                                                      &lt;br /&gt;
** edit /etc/postfix/master.cf and add&lt;br /&gt;
 # AV scan filter (used by content_filter)&lt;br /&gt;
 scan      unix  -       -       n       -       16      smtp&lt;br /&gt;
         -o smtp_send_xforward_command=yes&lt;br /&gt;
         -o smtp_enforce_tls=no&lt;br /&gt;
 # For injecting mail back into postfix from the filter&lt;br /&gt;
 127.0.0.1:10026 inet  n -       n       -       16      smtpd&lt;br /&gt;
         -o content_filter=&lt;br /&gt;
         -o receive_override_options=no_unknown_recipient_checks,no_header_body_checks&lt;br /&gt;
         -o smtpd_helo_restrictions=&lt;br /&gt;
         -o smtpd_client_restrictions=&lt;br /&gt;
         -o smtpd_sender_restrictions=&lt;br /&gt;
         -o smtpd_recipient_restrictions=permit_mynetworks,reject&lt;br /&gt;
         -o mynetworks_style=host&lt;br /&gt;
         -o smtpd_authorized_xforward_hosts=127.0.0.0/8&lt;br /&gt;
* postfix reload&lt;br /&gt;
* Send and email into a local virtual domain - it should have the &#039;&#039;X-Virus-Scanned: ClamAV using ClamSMTP&#039;&#039; header.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Relay for Authenticated Users ===&lt;br /&gt;
&lt;br /&gt;
As configured above, the mail server accepts email from the Internet, but it does not relay email.  If it is a perimeter exchanger for a protected network, then you can add the protected networks to the &#039;&#039;mynetworks&#039;&#039; configuration line in /etc/postfix/main.cf&lt;br /&gt;
&lt;br /&gt;
This configuration change allows &#039;&#039;remote&#039;&#039; users to authenticate against the mail server and relay through it.  The rules for relaying are:&lt;br /&gt;
* Only authenticated users can relay&lt;br /&gt;
* Authentication Credentials must be encrypted with TLS or SSL&lt;br /&gt;
* Allow Submission and SMTPS ports for relaying (many consumer networks block port 25 - SMTP by default)&lt;br /&gt;
The process uses the dovecot authentication mechanism (used with IMAPS) to authenticate users before they are allowed to relay through postfix.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* Edit /etc/dovecot/dovecot.conf and add:&lt;br /&gt;
 # this is for postfix SASL (authenticated users can relay through us)&lt;br /&gt;
 socket listen {&lt;br /&gt;
                client {&lt;br /&gt;
                        path    = /var/spool/postfix/private/dovecot-auth.sock&lt;br /&gt;
                        mode    = 0660&lt;br /&gt;
                        user    = postfix&lt;br /&gt;
                        group   = postfix&lt;br /&gt;
                        }&lt;br /&gt;
                }&lt;br /&gt;
        }&lt;br /&gt;
* Restart dovecot&lt;br /&gt;
 /etc/init.d/dovecot restart&lt;br /&gt;
* Edit /etc/postfix/main.cf and add:&lt;br /&gt;
 # TLS Stuff -- since we allow SASL with tls *only*, we have to set up TLS first                    &lt;br /&gt;
 &lt;br /&gt;
 smtpd_tls_cert_file = /etc/lighttpd/server-bundle.pem&lt;br /&gt;
 smtpd_tls_key_file = /etc/lighttpd/server-bundle.pem&lt;br /&gt;
 smtpd_tls_CAfile = /etc/lighttpd/ca-crt.pem&lt;br /&gt;
 # If tls_security_level is set to &amp;quot;encrypt&amp;quot;, then SMTP rejects &lt;br /&gt;
 # unencrypted email (e.g. normal mail) which is bad.&lt;br /&gt;
 # By setting it to &amp;quot;may&amp;quot; you get TLS encrypted mail from google, slashdot, and other &lt;br /&gt;
 # interesting places.  Check your logs to see who&lt;br /&gt;
 smtpd_tls_security_level = may&lt;br /&gt;
 # Log info about the negotiated encryption levels&lt;br /&gt;
 smtpd_tls_received_header = yes&lt;br /&gt;
 smtpd_tls_loglevel = 1&lt;br /&gt;
 &lt;br /&gt;
 # SASL - this allows senders to authenticiate themselves&lt;br /&gt;
 # This along with &amp;quot;permit_sasl_authenticated&amp;quot; in smtpd_recipient_restrictions allows relaying&lt;br /&gt;
 smtpd_sasl_type = dovecot&lt;br /&gt;
 smtpd_sasl_path = private/dovecot-auth.sock&lt;br /&gt;
 smtpd_sasl_auth_enable = yes&lt;br /&gt;
 smtpd_sasl_authenticated_header = yes&lt;br /&gt;
 smtpd_tls_auth_only = yes&lt;br /&gt;
* Edit /etc/postfix/master.cf and enable the submission and smtps transports.  They are probably already at the top of your  master.cf file, just commented out:&lt;br /&gt;
 submission inet n       -       n       -       -       smtpd&lt;br /&gt;
   -o smtpd_tls_security_level=encrypt&lt;br /&gt;
   -o smtpd_sasl_auth_enable=yes&lt;br /&gt;
   -o smtpd_client_restrictions=permit_sasl_authenticated,reject&lt;br /&gt;
   -o milter_macro_daemon_name=ORIGINATING&lt;br /&gt;
 smtps     inet  n       -       n       -       -       smtpd&lt;br /&gt;
   -o smtpd_tls_security_level=encrypt&lt;br /&gt;
   -o smtpd_tls_wrappermode=yes&lt;br /&gt;
   -o smtpd_sasl_auth_enable=yes&lt;br /&gt;
   -o smtpd_client_restrictions=permit_sasl_authenticated,reject&lt;br /&gt;
   -o milter_macro_daemon_name=ORIGINATING&lt;br /&gt;
*Verfiy submission and smtps are defined in /etc/services&lt;br /&gt;
 grep &amp;quot;submission\|ssmtp&amp;quot; /etc/services&lt;br /&gt;
 submission	587/tcp				# mail message submission&lt;br /&gt;
 submission	587/udp&lt;br /&gt;
 smtps		465/tcp		ssmtp		# smtp protocol over TLS/SSL&lt;br /&gt;
 smtps		465/udp		ssmtp&lt;br /&gt;
* Restart postfix&lt;br /&gt;
 postfix reload&lt;br /&gt;
&lt;br /&gt;
At this point, you should be able to set up a mail client to relay through the server with TLS (port 587) or SSL (port 465)  Note that &amp;quot;plain&amp;quot; authentication is used because the underlying link is encrypted.  For example, in Thunderbird leave &amp;quot;secure authentication&amp;quot; unchecked, and choose STARTTLS (or TLS) for the connection security.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Mailbox Quotas ===&lt;br /&gt;
&lt;br /&gt;
In the default configuration, PostfixAdmin knows about quotas, but they are not enforced.   Documentation on the web mentions the [http://vda.sourceforge.net vda patch to postfix] to enforce quotas.  The only bad thing... its a &#039;&#039;patch&#039;&#039;.   Postfix and Dovecot are both conservative systems, so if the patch isn&#039;t in the upstream source, we&#039;ll assume there&#039;s a good reason.   There is a way of using quotas without patches - and it involves using dovecot&#039;s [http://wiki.dovecot.org/LDA deliver] lda for local delivery.&lt;br /&gt;
&lt;br /&gt;
Note: As of Jan 2010, the documention is confusing, with multiple versions of dovecot, PostfixAdmin, and Mysql referenced.  These instructions apply to:&lt;br /&gt;
* Postgresql 8.4.2 &lt;br /&gt;
* PostfixAdmin 2.3 &lt;br /&gt;
* Dovecot 1.2.10&lt;br /&gt;
* Postfix 2.6.5&lt;br /&gt;
&lt;br /&gt;
Presumably later versions will work the same, but if not, please update the documentation and versions above.&lt;br /&gt;
&lt;br /&gt;
* Update /etc/dovecot.conf (old lines shown commented out):&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
# old postfix &lt;br /&gt;
#       userdb static {&lt;br /&gt;
#               args =  uid=1006 gid=1006 home=/var/mail/domains/%d/%n&lt;br /&gt;
#               }&lt;br /&gt;
&lt;br /&gt;
# new quota support:&lt;br /&gt;
        userdb prefetch {&lt;br /&gt;
                }&lt;br /&gt;
&lt;br /&gt;
        userdb sql {&lt;br /&gt;
                args = /etc/dovecot/dovecot-sql.conf&lt;br /&gt;
                }&lt;br /&gt;
&lt;br /&gt;
        socket listen {&lt;br /&gt;
                client {&lt;br /&gt;
                        path    = /var/spool/postfix/private/dovecot-auth.sock&lt;br /&gt;
                        mode    = 0660&lt;br /&gt;
                        user    = postfix&lt;br /&gt;
                        group   = postfix&lt;br /&gt;
                        }&lt;br /&gt;
                # These lines below are for the deliver lda&lt;br /&gt;
                master {&lt;br /&gt;
                        path =  /var/run/dovecot/auth-master&lt;br /&gt;
                        mode    = 0660&lt;br /&gt;
                        user    = vmail&lt;br /&gt;
                        group   = vmail&lt;br /&gt;
                        }&lt;br /&gt;
                }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
protocol imap {                                                               &lt;br /&gt;
         mail_plugins = quota imap_quota                                       &lt;br /&gt;
         }                                                                     &lt;br /&gt;
                                                                              &lt;br /&gt;
protocol pop3 {                                                               &lt;br /&gt;
         mail_plugins = quota                                                  &lt;br /&gt;
         }                                                                     &lt;br /&gt;
                                                                              &lt;br /&gt;
dict {                                                                        &lt;br /&gt;
        quotadict = pgsql:/etc/dovecot/dovecot-dict-quota.conf                &lt;br /&gt;
        }                                                                     &lt;br /&gt;
                                                                              &lt;br /&gt;
plugin {                                                                      &lt;br /&gt;
         quota = dict:user::proxy::quotadict                                   &lt;br /&gt;
         }                                                     &lt;br /&gt;
                                                              &lt;br /&gt;
protocol lda {                                                &lt;br /&gt;
   postmaster_address = postmaster@host.example.com&lt;br /&gt;
   mail_plugins = quota                                        &lt;br /&gt;
   auth_socket_path =  /var/run/dovecot/auth-master&lt;br /&gt;
   sendmail_path = /usr/sbin/sendmail&lt;br /&gt;
}                                                                            &lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
 &lt;br /&gt;
You should already have a &amp;lt;tt&amp;gt;socket-&amp;gt; listen-&amp;gt; client&amp;lt;/tt&amp;gt; section, but it is listed above to show where it goes in relationship to the &amp;lt;tt&amp;gt;socket -&amp;gt; listen -&amp;gt; master&amp;lt;/tt&amp;gt; section&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* edit &amp;lt;tt&amp;gt;/etc/dovecot/dovecot-sql.conf&amp;lt;/tt&amp;gt; and replace the user and password queries with the following (you may not have a user_query yet - add it):&lt;br /&gt;
&lt;br /&gt;
 password_query = select username as user, password, 1006 as userdb_uid, 1006 as userdb_gid, &#039;*:bytes=&#039; || quota as userdb_quota_rule from mailbox  where local_part = &#039;%n&#039; and domain = &#039;%d&#039;&lt;br /&gt;
 user_query = select maildir as home, 1006 as uid, 1006 as gid, &#039;*:bytes=&#039; || quota  as quota_rule from mailbox where local_part = &#039;%n&#039; and domain =&#039;%d&#039;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* create &amp;lt;tt&amp;gt;/etc/dovecot/dovecot-dict-quota.conf&amp;lt;/tt&amp;gt;&lt;br /&gt;
 connect = host=localhost dbname=postfix user=postfix password=********&lt;br /&gt;
 &lt;br /&gt;
 map {&lt;br /&gt;
         pattern = priv/quota/storage&lt;br /&gt;
         table = quota2&lt;br /&gt;
         username_field =username&lt;br /&gt;
         value_field = bytes&lt;br /&gt;
 }&lt;br /&gt;
 &lt;br /&gt;
 map {&lt;br /&gt;
        pattern= priv/quota/messages&lt;br /&gt;
        table = quota2&lt;br /&gt;
        username_field = username&lt;br /&gt;
        value_field = messages&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
Side note: [http://wiki.dovecot.org/Quota/Dict The Dovecot Quota Documentation] mentions the need for a trigger with pgsql.  This was created in the PostfixAdmin install, which is why you instantiated the pgsql language when creating the database.  If not, you will need to create the trigger, to reference the quota2 table, not the quota table mentioned in the dovecot docs.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* create a new transport for the dovecot lda.   Add the following to  /etc/postfix/master.cf:&lt;br /&gt;
 # The dovecot deliver lda&lt;br /&gt;
 dovecot   unix  -       n       n       -       -       pipe&lt;br /&gt;
   flags=DRhu user=vmail:vmail argv=/usr/libexec/dovecot/deliver -f ${sender} -d ${user}@${nexthop}&lt;br /&gt;
&lt;br /&gt;
* Edit the /etc/postfix/main.cf.  Replace &lt;br /&gt;
 virtual_transport = virtual &lt;br /&gt;
with&lt;br /&gt;
 virtual_transport = dovecot&lt;br /&gt;
 dovecot_destination_recipient_limit = 1&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;TODO&#039;&#039;&#039;  This will cause over-quota emails to bounce.   Which could be a source of backscatter.   We need a way of checking quota limits after RBL checking but before the message is accepted in the queue.&lt;br /&gt;
&lt;br /&gt;
=== WebMail (RoundCube) ===&lt;br /&gt;
&lt;br /&gt;
[http://roundcube.net/ RoundCube] is an &amp;quot;ajax /Web2.0&amp;quot; web-mail client.  These instructions are for the Alpine Linux 1.10 repository &lt;br /&gt;
&lt;br /&gt;
* Add the package and related php modules:&lt;br /&gt;
 apk add roundcubemail php-xml php-openssl php-mcrypt php-gd php-iconv&lt;br /&gt;
&lt;br /&gt;
* link the roundcube application back into the docroot&lt;br /&gt;
 ln -s /usr/share/webapps/roundcube /var/www/domains/host.example.com/www/roundcube&lt;br /&gt;
&lt;br /&gt;
* follow the instructions in /usr/share/webapps/roundcube/INSTALL:&lt;br /&gt;
 cd /usr/share/webapps/roundcube&lt;br /&gt;
 chown -R lighttpd:lighttpd temp logs&lt;br /&gt;
 &lt;br /&gt;
 su postgres&lt;br /&gt;
 createuser roundcube&lt;br /&gt;
   Shall the new role be a superuser? (y/n) n&lt;br /&gt;
   Shall the new role be allowed to create databases? (y/n) n&lt;br /&gt;
   Shall the new role be allowed to create more new roles? (y/n) y&lt;br /&gt;
 createdb -O roundcube -E UNICODE -T template0 roundcubemail&lt;br /&gt;
 psql roundcubemail&lt;br /&gt;
   roundcubemail=# ALTER USER roundcube WITH PASSWORD &#039;the_new_password&#039;;&lt;br /&gt;
   roundcubemail=# \c - roundcube&lt;br /&gt;
   roundcubemail=&amp;gt; \i /usr/share/webapps/roundcube/SQL/postgres.initial.sql&lt;br /&gt;
   roundcubemail=&amp;gt; \q&lt;br /&gt;
 exit&lt;br /&gt;
&lt;br /&gt;
* edit /etc/php/php.ini and set date.timezone to your local timezone, or to UTC&lt;br /&gt;
&lt;br /&gt;
* restart lighttpd to verify the new php libraries are used&lt;br /&gt;
 /etc/init.d/lighttpd restart&lt;br /&gt;
&lt;br /&gt;
* Point your browser to http://host.example.com/roundcube/installer&lt;br /&gt;
* Start installation&lt;br /&gt;
&lt;br /&gt;
For the specific configuration parameters in the install step:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!Property&lt;br /&gt;
!Setting&lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;enable_spellcheck&#039;&#039; ||   disabled &lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;identities_level&#039;&#039; ||  one identity with possibility to edit all params but not email address &lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;log driver&#039;&#039; || syslog &lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;sylog_id&#039;&#039; || roundcube &lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;syslog_facility&#039;&#039; || mailsubsystem &lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;db_dnsw&#039;&#039; || pgsql properties, as described above &lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;imap_host&#039;&#039; || 127.0.0.1 &lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;auto_create_user&#039;&#039; || enabled &lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;smtp_server&#039;&#039; ||  127.0.0.1&lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;smtp_port&#039;&#039; ||  25&lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;smtp_user/smtp_pass&#039;&#039; ||  enable &#039;&#039;Use Current IMAP username and password for SMTP authentication&#039;&#039;&lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;smtp_log&#039;&#039; ||  enable (optional, but gives additional log record)&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
The other items can be left at default settings, or adjusted if desired.&lt;br /&gt;
&lt;br /&gt;
* Follow the instructions in step 3 of the install to copy the files to the server&lt;br /&gt;
* You should now be able to get to roundcube at http://host.example.com/roundcube&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
After its working, the INSTALL file recommends removing the install directory.   If you want to keep the installer around later, you can simply change the ownership and permissions.  So do &#039;&#039;&#039;one&#039;&#039;&#039; of the following:&lt;br /&gt;
 cd /usr/share/webapps/roundcube&lt;br /&gt;
 rm -rf LICENSE UPGRADING INSTALL README CHANGELOG  SQL installer&lt;br /&gt;
or&lt;br /&gt;
 cd /usr/share/webapps/roundcube&lt;br /&gt;
 chown -R root:root LICENSE UPGRADING INSTALL README CHANGELOG  SQL installer&lt;br /&gt;
 chmod -R 600 LICENSE UPGRADING INSTALL README CHANGELOG SQL &lt;br /&gt;
 chmod 700 SQL installer&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== OpenLDAP based Address Book ===&lt;br /&gt;
&lt;br /&gt;
This OpenLDAP configuration uses the SQL backend, which represents information stored in PostgreSQL as an LDAP subtree for Address Book functionality for email lookups, user authentication or even &lt;br /&gt;
replication account information between sites. This procedure uses some metainformation to translate LDAP queries to SQL queries, leaving relational schema untouched, which allows SQL and LDAP &lt;br /&gt;
applications to inter-operate without replication, and exchange data as needed. The SQL backend uses UnixODBC to connect to PostgresSQL. &lt;br /&gt;
&lt;br /&gt;
* Install OpenLDAP and ODBC&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
apk add openldap libldap openldap-back-sql php-ldap unixodbc psqlodbc ca-certificates&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Note&#039;&#039;&#039;: Perhaps some packages should be installed from &amp;quot;edge&amp;quot; repository&lt;br /&gt;
&lt;br /&gt;
* Update &amp;quot;postfix&amp;quot; database (it will add &#039;id&#039; columns to mailbox and domain tables, also will create tables and views to represent LDAP metainformation)&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Note&#039;&#039;&#039;: These instructions are for example domain example.com. So make sure you replaced all entries of &#039;example&#039; and &#039;com&#039; according to your domain name parts.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
cat - &amp;lt;&amp;lt;EOF | psql -U postgres postfix&lt;br /&gt;
ALTER TABLE domain ADD COLUMN id SERIAL; &lt;br /&gt;
ALTER TABLE mailbox ADD COLUMN id SERIAL; &lt;br /&gt;
&lt;br /&gt;
CREATE TABLE ldap_entry_objclasses (&lt;br /&gt;
    entry_id integer NOT NULL,&lt;br /&gt;
    oc_name character varying(64)&lt;br /&gt;
);&lt;br /&gt;
&lt;br /&gt;
CREATE TABLE ldap_oc_mappings (&lt;br /&gt;
    id integer SERIAL,&lt;br /&gt;
    name character varying(64) NOT NULL,&lt;br /&gt;
    keytbl character varying(64) NOT NULL,&lt;br /&gt;
    keycol character varying(64) NOT NULL,&lt;br /&gt;
    create_proc character varying(255),&lt;br /&gt;
    delete_proc character varying(255),&lt;br /&gt;
    expect_return integer NOT NULL,&lt;br /&gt;
    PRIMARY KEY(id)&lt;br /&gt;
);&lt;br /&gt;
&lt;br /&gt;
CREATE TABLE ldap_attr_mappings_test (&lt;br /&gt;
    id integer SERIAL,&lt;br /&gt;
    oc_map_id integer NOT NULL REFERENCES ldap_oc_mappings(id),&lt;br /&gt;
    name character varying(255) NOT NULL,&lt;br /&gt;
    sel_expr character varying(255) NOT NULL,&lt;br /&gt;
    sel_expr_u character varying(255),&lt;br /&gt;
    from_tbls character varying(255) NOT NULL,&lt;br /&gt;
    join_where character varying(255),&lt;br /&gt;
    add_proc character varying(255),&lt;br /&gt;
    delete_proc character varying(255),&lt;br /&gt;
    param_order integer NOT NULL,&lt;br /&gt;
    expect_return integer NOT NULL,&lt;br /&gt;
    PRIMARY KEY(id)&lt;br /&gt;
);&lt;br /&gt;
&lt;br /&gt;
CREATE VIEW ldap_dcs AS&lt;br /&gt;
    (SELECT (domain.id + 100000) AS id, &lt;br /&gt;
            (((&#039;dc=&#039;::text || split_part((domain.domain)::text, &#039;.&#039;::text, 1)) || &#039;,dc=&#039;::text) || &lt;br /&gt;
            CASE WHEN (split_part((domain.domain)::text, &#039;.&#039;::text, 2) = &#039;com&#039;::text) THEN split_part((domain.domain)::text, &#039;.&#039;::text, 2) &lt;br /&gt;
                 ELSE ((split_part((domain.domain)::text, &#039;.&#039;::text, 2) || &#039;,dc=&#039;::text) || split_part((domain.domain)::text, &#039;.&#039;::text, 3)) &lt;br /&gt;
            END) AS dn, &lt;br /&gt;
            1 AS oc_map_id, &lt;br /&gt;
            100000 AS parent, &lt;br /&gt;
            0 AS keyval, &lt;br /&gt;
            domain.domain&lt;br /&gt;
     FROM domain &lt;br /&gt;
     WHERE domain.domain &amp;lt;&amp;gt; &#039;ALL&#039; &lt;br /&gt;
      UNION &lt;br /&gt;
     SELECT 100000 AS id, &lt;br /&gt;
           &#039;dc=com&#039; AS dn, &lt;br /&gt;
           1 AS oc_map_id, &lt;br /&gt;
           0 AS parent, &lt;br /&gt;
           0 AS keyval, &lt;br /&gt;
           &#039;com&#039; AS domain);&lt;br /&gt;
&lt;br /&gt;
CREATE VIEW ldap_entries AS&lt;br /&gt;
    SELECT mailbox.id, &lt;br /&gt;
    (((((&#039;cn=&#039;::text || initcap(replace(split_part((mailbox.username)::text, &#039;@&#039;::text, 1), &#039;.&#039;::text, &#039; &#039;::text))) || &#039;,dc=&#039;::text) || &lt;br /&gt;
          split_part(split_part((mailbox.username)::text, &#039;@&#039;::text, 2), &#039;.&#039;::text, 1)) || &#039;,dc=&#039;::text) || &lt;br /&gt;
             CASE WHEN (split_part(split_part((mailbox.username)::text, &#039;@&#039;::text, 2), &#039;.&#039;::text, 2) = &#039;com&#039;::text) &lt;br /&gt;
                  THEN split_part(split_part((mailbox.username)::text, &#039;@&#039;::text, 2), &#039;.&#039;::text, 2) &lt;br /&gt;
                  ELSE ((split_part(split_part((mailbox.username)::text, &#039;@&#039;::text, 2), &#039;.&#039;::text, 2) || &#039;,dc=&#039;::text) || &lt;br /&gt;
                         split_part(split_part((mailbox.username)::text, &#039;@&#039;::text, 2), &#039;.&#039;::text, 3)) &lt;br /&gt;
             END) AS dn, &lt;br /&gt;
          1 AS oc_map_id, &lt;br /&gt;
          (SELECT ldap_dcs.id &lt;br /&gt;
           FROM ldap_dcs &lt;br /&gt;
           WHERE ((ldap_dcs.domain)::text = (mailbox.domain)::text)) AS parent, &lt;br /&gt;
           mailbox.id AS keyval &lt;br /&gt;
           FROM mailbox &lt;br /&gt;
           UNION &lt;br /&gt;
           SELECT ldap_dcs.id,  &lt;br /&gt;
                  ldap_dcs.dn, &lt;br /&gt;
                  ldap_dcs.oc_map_id, &lt;br /&gt;
                  ldap_dcs.parent, &lt;br /&gt;
                  ldap_dcs.keyval &lt;br /&gt;
           FROM ldap_dcs;&lt;br /&gt;
EOF&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* Fill out LDAP tables according to following example (make sure to separate values with TABs):&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
cat - &amp;lt;&amp;lt;EOF | psql -U postgres postfix&lt;br /&gt;
COPY ldap_attr_mappings (id, oc_map_id, name, sel_expr, sel_expr_u, from_tbls, join_where, add_proc, delete_proc, param_order, expect_return) FROM stdin;&lt;br /&gt;
1	1	displayName	mailbox.name	\N	mailbox	\N	\N	\N	3	0&lt;br /&gt;
2	1	mail	mailbox.username	\N	mailbox	\N	\N	\N	3	0&lt;br /&gt;
3	1	cn	mailbox.name	\N	mailbox	\N	\N	\N	3	0&lt;br /&gt;
4	1	userPassword	&#039;{CRYPT}&#039;||mailbox.password	\N	mailbox	\N	\N	\N	3	0&lt;br /&gt;
\.&lt;br /&gt;
&lt;br /&gt;
COPY ldap_oc_mappings (id, name, keytbl, keycol, create_proc, delete_proc, expect_return) FROM stdin;&lt;br /&gt;
1	exampleBox	mailbox	id	\N	\N	1&lt;br /&gt;
\.&lt;br /&gt;
EOF&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* Check that &amp;quot;ldap_dcs&amp;quot; view presens something like this:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
echo &#039;select * from ldap_dcs&#039; | psql -U postgres postfix&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
   id   |             dn              | oc_map_id | parent | keyval |       domain       &lt;br /&gt;
--------+-----------------------------+-----------+--------+--------+--------------------&lt;br /&gt;
 100000 | dc=com                      |         1 |      0 |      0 | com&lt;br /&gt;
 100001 | dc=example,dc=com           |         1 | 100000 |      0 | example.com&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* Check that &amp;quot;ldap_entries&amp;quot; view presens something like this:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
echo &#039;select * from ldap_entries&#039; | psql -U postgres postfix&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
   id   |                          dn                           | oc_map_id | parent | keyval &lt;br /&gt;
--------+-------------------------------------------------------+-----------+--------+--------&lt;br /&gt;
    1   | cn=address1,dc=example,dc=com                         |         1 | 100001 |    1&lt;br /&gt;
...&lt;br /&gt;
   123  | cn=address123,dc=example,dc=com                       |         1 | 100001 |    1&lt;br /&gt;
 100000 | dc=com                                                |         1 |      0 |    0&lt;br /&gt;
 100001 | dc=example,dc=com                                     |         1 | 100000 |    0&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* Configure ODBC parameters&lt;br /&gt;
&lt;br /&gt;
Edit /etc/odbc.ini:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
[PostgreSQL]&lt;br /&gt;
Description             = Connection to Postgres&lt;br /&gt;
Driver                  = PostgreSQL&lt;br /&gt;
Trace                   = Yes&lt;br /&gt;
TraceFile               = sql.log&lt;br /&gt;
Database                = postfix&lt;br /&gt;
Servername              = 127.0.0.1&lt;br /&gt;
UserName                =&lt;br /&gt;
Password                =&lt;br /&gt;
Port                    = 5432&lt;br /&gt;
Protocol                = 6.4&lt;br /&gt;
ReadOnly                = No&lt;br /&gt;
RowVersining            = No&lt;br /&gt;
ShowSystemTables        = No&lt;br /&gt;
ShowOidColumn           = No&lt;br /&gt;
FakeOidIndex            = No&lt;br /&gt;
ConnSettings            =&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Edit /etc/odbcinst.ini:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
[PostgreSQL]&lt;br /&gt;
Description     = PostgreSQL driver for Linux&lt;br /&gt;
Driver          = /usr/lib/psqlodbcw.so&lt;br /&gt;
Setup           = /usr/lib/libodbcpsqlS.so&lt;br /&gt;
FileUsage       = 1&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* Test ODBC connection&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
echo &amp;quot;select * from domain;&amp;quot; | isql PostgreSQL postgres&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* Provide permission to certificate for LDAP server&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
chown ldap /etc/lighttpd/server-bundle.pem&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* Edit LDAP schema&lt;br /&gt;
&lt;br /&gt;
Edit /etc/openldap/schema/example.com.schema:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
attributetype ( 0.9.2342.19200300.100.1.3&lt;br /&gt;
	NAME ( &#039;mail&#039; &#039;rfc822Mailbox&#039; )&lt;br /&gt;
	DESC &#039;RFC1274: RFC822 Mailbox&#039;&lt;br /&gt;
        EQUALITY caseIgnoreIA5Match&lt;br /&gt;
        SUBSTR caseIgnoreIA5SubstringsMatch&lt;br /&gt;
        SYNTAX 1.3.6.1.4.1.1466.115.121.1.26{256} )&lt;br /&gt;
&lt;br /&gt;
attributetype ( 2.16.840.1.113730.3.1.241&lt;br /&gt;
	NAME &#039;displayName&#039;&lt;br /&gt;
	DESC &#039;RFC2798: preferred name to be used when displaying entries&#039;&lt;br /&gt;
	EQUALITY caseIgnoreMatch&lt;br /&gt;
	SUBSTR caseIgnoreSubstringsMatch&lt;br /&gt;
	SYNTAX 1.3.6.1.4.1.1466.115.121.1.15&lt;br /&gt;
	SINGLE-VALUE )&lt;br /&gt;
&lt;br /&gt;
objectclass   ( 2.16.840.1.113730.3.2.2&lt;br /&gt;
        NAME &#039;exampleBox&#039;&lt;br /&gt;
	DESC &#039;example.com mailbox&#039;&lt;br /&gt;
	MUST ( displayName $ mail $ userPassword )&lt;br /&gt;
	)&lt;br /&gt;
&lt;br /&gt;
# RFC 1274 + RFC 2247&lt;br /&gt;
attributetype ( 0.9.2342.19200300.100.1.25&lt;br /&gt;
        NAME ( &#039;dc&#039; &#039;domainComponent&#039; )&lt;br /&gt;
        DESC &#039;RFC1274/2247: domain component&#039;&lt;br /&gt;
        EQUALITY caseIgnoreIA5Match&lt;br /&gt;
        SUBSTR caseIgnoreIA5SubstringsMatch&lt;br /&gt;
        SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 SINGLE-VALUE )&lt;br /&gt;
&lt;br /&gt;
attributetype ( 2.5.4.46 NAME &#039;dnQualifier&#039;&lt;br /&gt;
        DESC &#039;RFC2256: DN qualifier&#039;&lt;br /&gt;
        EQUALITY caseIgnoreMatch&lt;br /&gt;
        ORDERING caseIgnoreOrderingMatch&lt;br /&gt;
        SUBSTR caseIgnoreSubstringsMatch&lt;br /&gt;
        SYNTAX 1.3.6.1.4.1.1466.115.121.1.44 )&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* Configure LDAP server&lt;br /&gt;
&lt;br /&gt;
Edit /etc/openldap/slapd.conf:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
include         /etc/openldap/schema/example.com.schema&lt;br /&gt;
pidfile         /var/run/openldap/slapd.pid&lt;br /&gt;
argsfile        /var/run/openldap/slapd.args&lt;br /&gt;
&lt;br /&gt;
TLSCipherSuite HIGH&lt;br /&gt;
TLSCACertificateFile /etc/lighttpd/ca-crt.pem&lt;br /&gt;
TLSCertificateFile /etc/lighttpd/server-bundle.pem&lt;br /&gt;
TLSCertificateKeyFile /etc/lighttpd/server-bundle.pem&lt;br /&gt;
TLSVerifyClient never &lt;br /&gt;
&lt;br /&gt;
# This is needed for proper representation of MD5-CRYPT format stored in database&lt;br /&gt;
#  see more details in http://strugglers.net/~andy/blog/2010/01/23/openldap-and-md5crypt/&lt;br /&gt;
password-hash  {CRYPT}&lt;br /&gt;
password-crypt-salt-format &amp;quot;$1$%.8s&amp;quot;&lt;br /&gt;
&lt;br /&gt;
loglevel        stats&lt;br /&gt;
moduleload	/usr/lib/openldap/back_sql.so&lt;br /&gt;
sizelimit 3000&lt;br /&gt;
&lt;br /&gt;
database        sql&lt;br /&gt;
&lt;br /&gt;
dbname		PostgreSQL&lt;br /&gt;
dbuser		postfix&lt;br /&gt;
dbpasswd	*****&lt;br /&gt;
&lt;br /&gt;
suffix          &amp;quot;dc=example,dc=com&amp;quot;&lt;br /&gt;
rootdn          &amp;quot;cn=admin,dc=example,dc=com&amp;quot;&lt;br /&gt;
rootpw		{MD5}&amp;lt;Hashed password for root dn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
upper_func      &amp;quot;upper&amp;quot;&lt;br /&gt;
strcast_func    &amp;quot;text&amp;quot;&lt;br /&gt;
concat_pattern  &amp;quot;?||?&amp;quot;&lt;br /&gt;
has_ldapinfo_dn_ru      no&lt;br /&gt;
lastmod         off&lt;br /&gt;
&lt;br /&gt;
access to attrs=userPassword by * auth&lt;br /&gt;
&lt;br /&gt;
access to * by peername.ip=127.0.0.1 read&lt;br /&gt;
            ### by peername.ip=&amp;lt;IP&amp;gt;%&amp;lt;netmask&amp;gt; read&lt;br /&gt;
            ### by peername.ip=&amp;lt;IP&amp;gt; read&lt;br /&gt;
	    by users read&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* Set permissions for slapd.conf&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
chown ldap:ldap /etc/openldap/slapd.conf&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* Configure startup parameters to make sure that LDAP server start AFTER PostgreSQL and listens on localhost with clear text and public IP with SSL&lt;br /&gt;
&lt;br /&gt;
Edit /etc/conf.d/slapd:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
echo rc_need=&amp;quot;postgresql&amp;quot; &lt;br /&gt;
OPTS=&amp;quot;-h &#039;ldaps:// ldap://127.0.0.1&#039;&amp;quot;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* Start LDAP server&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
rc-update add slapd default&lt;br /&gt;
/etc/init.d/slapd start&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* Configure LDAP client utilities&lt;br /&gt;
&lt;br /&gt;
Edit /etc/openldap/ldap.conf&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
BASE	dc=example,dc=com&lt;br /&gt;
URI	ldaps://host.example.com&lt;br /&gt;
&lt;br /&gt;
TLS_CACERT /etc/lighttpd/ca-crt.pem&lt;br /&gt;
TLS_CERT /etc/lighttpd/server-bundle.pem&lt;br /&gt;
TLS_KEY /etc/lighttpd/server-bundle.pem&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* Test LDAP server&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
ldapsearch -z 3&lt;br /&gt;
ldapsearch -z 3 -x -W -D cn=admin,dc=example,dc=com&lt;br /&gt;
ldapsearch -z 3 -x -W -D cn=address1,dc=example,dc=com&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* Configure RoundCube webmail for email lookups&lt;br /&gt;
&lt;br /&gt;
Edit /usr/share/webapps/roundcube/config/main.inc.php:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
$rcmail_config[&#039;ldap_debug&#039;] = false;&lt;br /&gt;
...&lt;br /&gt;
$rcmail_config[&#039;address_book_type&#039;] = &#039;ldap&#039;;&lt;br /&gt;
&lt;br /&gt;
$rcmail_config[&#039;ldap_public&#039;][&#039;example.com&#039;] = array(&lt;br /&gt;
  &#039;name&#039;          =&amp;gt; &#039;example.com&#039;,&lt;br /&gt;
  &#039;hosts&#039;         =&amp;gt; array(&#039;127.0.0.1&#039;),&lt;br /&gt;
  &#039;port&#039;          =&amp;gt; 389,&lt;br /&gt;
  &#039;use_tls&#039;         =&amp;gt; false,&lt;br /&gt;
  &#039;user_specific&#039; =&amp;gt; false,&lt;br /&gt;
  &#039;base_dn&#039;       =&amp;gt; &#039;dc=example,dc=com&#039;,&lt;br /&gt;
  &#039;bind_dn&#039;       =&amp;gt; &#039;&#039;,&lt;br /&gt;
  &#039;bind_pass&#039;     =&amp;gt; &#039;&#039;,&lt;br /&gt;
  &#039;writable&#039;      =&amp;gt; false,&lt;br /&gt;
  &#039;LDAP_Object_Classes&#039; =&amp;gt; array(&amp;quot;top&amp;quot;, &amp;quot;exampleBox&amp;quot;),&lt;br /&gt;
  &#039;required_fields&#039;     =&amp;gt; array(&amp;quot;cn&amp;quot;, &amp;quot;sn&amp;quot;, &amp;quot;mail&amp;quot;),&lt;br /&gt;
  &#039;LDAP_rdn&#039;      =&amp;gt; &#039;mail&#039;,&lt;br /&gt;
  &#039;ldap_version&#039;  =&amp;gt; 3,&lt;br /&gt;
  &#039;search_fields&#039; =&amp;gt; array(&#039;mail&#039;, &#039;cn&#039;, &#039;sn&#039;, &#039;givenName&#039;),&lt;br /&gt;
  &#039;name_field&#039;    =&amp;gt; &#039;cn&#039;,&lt;br /&gt;
  &#039;email_field&#039;   =&amp;gt; &#039;mail&#039;,&lt;br /&gt;
  &#039;surname_field&#039; =&amp;gt; &#039;sn&#039;,&lt;br /&gt;
  &#039;firstname_field&#039; =&amp;gt; &#039;gn&#039;,&lt;br /&gt;
  &#039;sort&#039;          =&amp;gt; &#039;cn&#039;,&lt;br /&gt;
  &#039;scope&#039;         =&amp;gt; &#039;sub&#039;,&lt;br /&gt;
  &#039;filter&#039;        =&amp;gt; &#039;(objectClass=*)&#039;, // Construct here any filter you need&lt;br /&gt;
  &#039;fuzzy_search&#039;  =&amp;gt; true);&lt;br /&gt;
&lt;br /&gt;
$rcmail_config[&#039;autocomplete_addressbooks&#039;] = array(&#039;example.com&#039;);&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== log rotation ==&lt;br /&gt;
&lt;br /&gt;
Ensure the busybox cron service is started and is configured to auto-start:&lt;br /&gt;
&lt;br /&gt;
 /etc/init.d/cron start&lt;br /&gt;
 rc-update add cron default&lt;br /&gt;
&lt;br /&gt;
Add log rotate:&lt;br /&gt;
&lt;br /&gt;
 apk add logrotate&lt;br /&gt;
&lt;br /&gt;
Edit &#039;&#039;/etc/logrotate.conf&#039;&#039; as desired, but the defaults should be sufficient for most people.&lt;br /&gt;
&lt;br /&gt;
== Configure DNS ==&lt;br /&gt;
&lt;br /&gt;
This server hosts three separate web applications, and these can be handled as three different virtual domains on the same web server. They will be distinguished by their DNS names, so you can choose domains for the three separate services (or at least the ones you want to publish):&lt;br /&gt;
&lt;br /&gt;
* ACF - Alpine Configuration Framework for managing the server&lt;br /&gt;
* PostfixAdmin - for managing the postfix installation&lt;br /&gt;
* RoundCube - for accessing individual mailboxes&lt;br /&gt;
&lt;br /&gt;
Choose three different domains (from here on known as ACF_DOMAIN, POSTFIXADMIN_DOMAIN, and ROUNDCUBE_DOMAIN) and configure DNS for all three to point to the IP address of your host. These should be DNS A records.&lt;br /&gt;
&lt;br /&gt;
Then, configure lighttpd to handle the three separate domains by editing /etc/lighttpd/lighttpd.conf:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 $HTTP[&amp;quot;host&amp;quot;] == &amp;quot;ACF_DOMAIN&amp;quot; {&lt;br /&gt;
	simple-vhost.server-root   = &amp;quot;/var/www/domains/&amp;quot;&lt;br /&gt;
	simple-vhost.default-host  = &amp;quot;/ACF_DOMAIN/&amp;quot;&lt;br /&gt;
	simple-vhost.document-root = &amp;quot;www/&amp;quot;&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
 $HTTP[&amp;quot;host&amp;quot;] == &amp;quot;POSTFIXADMIN_DOMAIN&amp;quot; {&lt;br /&gt;
	simple-vhost.server-root   = &amp;quot;/var/www/domains/&amp;quot;&lt;br /&gt;
	simple-vhost.default-host  = &amp;quot;/POSTFIXADMIN_DOMAIN/&amp;quot;&lt;br /&gt;
	simple-vhost.document-root = &amp;quot;www/&amp;quot;&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
 $HTTP[&amp;quot;host&amp;quot;] == &amp;quot;ROUNDCUBE_DOMAIN&amp;quot; {&lt;br /&gt;
	simple-vhost.server-root   = &amp;quot;/var/www/domains/&amp;quot;&lt;br /&gt;
	simple-vhost.default-host  = &amp;quot;/ROUNDCUBE_DOMAIN/&amp;quot;&lt;br /&gt;
	simple-vhost.document-root = &amp;quot;www/&amp;quot;&lt;br /&gt;
 }&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
And, then link the appropriate www directories.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  mkdir -p /var/www/domains/ACF_DOMAIN&lt;br /&gt;
  ln -s /usr/share/acf/www /var/www/domains/ACF_DOMAIN/www&lt;br /&gt;
&lt;br /&gt;
  mkdir -p /var/www/domains/POSTFIXADMIN_DOMAIN&lt;br /&gt;
  ln -s /var/www/domains/host.example.com/www/postfixadmin /var/www/domains/POSTFIXADMIN_DOMAIN/www&lt;br /&gt;
&lt;br /&gt;
  mkdir -p /var/www/domains/ROUNDCUBE_DOMAIN&lt;br /&gt;
  ln -s /usr/share/webapps/roundcube /var/www/domains/ROUNDCUBE_DOMAIN/www&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;/div&gt;</summary>
		<author><name>Djhughes</name></author>
	</entry>
	<entry>
		<id>https://wiki.alpinelinux.org/w/index.php?title=Template:Latest_1.9_alpine_iso-filename&amp;diff=3485</id>
		<title>Template:Latest 1.9 alpine iso-filename</title>
		<link rel="alternate" type="text/html" href="https://wiki.alpinelinux.org/w/index.php?title=Template:Latest_1.9_alpine_iso-filename&amp;diff=3485"/>
		<updated>2010-03-12T07:17:11Z</updated>

		<summary type="html">&lt;p&gt;Djhughes: Updated to 1.9.3&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;alpine-1.9.3-x86.iso&lt;/div&gt;</summary>
		<author><name>Djhughes</name></author>
	</entry>
	<entry>
		<id>https://wiki.alpinelinux.org/w/index.php?title=ISP_Mail_Server_HowTo&amp;diff=3364</id>
		<title>ISP Mail Server HowTo</title>
		<link rel="alternate" type="text/html" href="https://wiki.alpinelinux.org/w/index.php?title=ISP_Mail_Server_HowTo&amp;diff=3364"/>
		<updated>2010-02-19T09:55:36Z</updated>

		<summary type="html">&lt;p&gt;Djhughes: corrected typo&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== A Full Service Mail Server ==&lt;br /&gt;
&lt;br /&gt;
The goal of this document is to describe how to set up postfix, dovecot, clamav, dspam, roundecube, and postfixadmin for a full-featured &amp;quot;ISP&amp;quot; level mail server.&lt;br /&gt;
&lt;br /&gt;
The server must provide:&lt;br /&gt;
&lt;br /&gt;
* multiple virtual domains&lt;br /&gt;
* admins for each domain (to add/remove virtual accounts)&lt;br /&gt;
* Quota support per domain / account&lt;br /&gt;
* downloading email via IMAP / IMAPS / POP3 / POP3S&lt;br /&gt;
* relaying email for authenticated users with TLS or SSL (Submission / SMTPS protocol)&lt;br /&gt;
* Standard filters (virus/spam/rbl/etc)&lt;br /&gt;
* Web mail client&lt;br /&gt;
* Value Add services&lt;br /&gt;
&lt;br /&gt;
== Set up Lighttpd + PHP ==&lt;br /&gt;
&lt;br /&gt;
PostfixAdmin needs php pgpsql and imap modules, so we do it in this step.&lt;br /&gt;
&lt;br /&gt;
  apk add lighttpd php php-pgsql php-imap&lt;br /&gt;
&lt;br /&gt;
Stop and remove mini_httpd, and move ACF to lighttpd;  We are setting this up to be a multi-domain virtual web server (replace host.example.com with the actual domain):&lt;br /&gt;
&lt;br /&gt;
  mkdir -p /var/www/domains/host.example.com/www&lt;br /&gt;
  ln -s /usr/share/acf/www /var/www/domains/host.example.com/www/acf&lt;br /&gt;
&lt;br /&gt;
Edit /var/www/domains/host.example.com/index.html to put a simple redirection page:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;lt;!DOCTYPE HTML PUBLIC &amp;quot;-//W3C//DTD HTML 4.01//EN&amp;quot; &amp;quot;http://www.w3.org/TR/html4/strict.dtd&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;html lang=&amp;quot;en&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;head&amp;gt;&lt;br /&gt;
&amp;lt;meta http-equiv=&amp;quot;Content-Type&amp;quot; content=&amp;quot;text/html; charset=ISO-8859-1&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;title&amp;gt;host.example.com Redirector&amp;lt;/title&amp;gt;&lt;br /&gt;
&amp;lt;/head&amp;gt;&lt;br /&gt;
&amp;lt;body&amp;gt;&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;&amp;lt;a href=&amp;quot;/acf&amp;quot;&amp;gt;ACF&amp;lt;/a&amp;gt;&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;&amp;lt;a href=&amp;quot;/postfixadmin&amp;quot;&amp;gt;PostfixAdmin&amp;lt;/a&amp;gt;&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;&amp;lt;a href=&amp;quot;/roundcube&amp;quot;&amp;gt;Roundcube&amp;lt;/a&amp;gt;&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
&amp;lt;/body&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Edit /etc/lighttpd/mod_cgi.conf to serve haserl files by adding a &amp;quot;&amp;quot; =&amp;gt; &amp;quot;&amp;quot; cgi handler and to treat /acf/cgi-bin as a CGI directory (remove the &#039;^&#039;)&lt;br /&gt;
&lt;br /&gt;
 $HTTP[&amp;quot;url&amp;quot;] =~ &amp;quot;/cgi-bin/&amp;quot; {&lt;br /&gt;
     # disable directory listings&lt;br /&gt;
     dir-listing.activate = &amp;quot;disable&amp;quot;&lt;br /&gt;
     # only allow cgi&#039;s in this directory&lt;br /&gt;
     cgi.assign = (&lt;br /&gt;
 		&amp;quot;.pl&amp;quot;	=&amp;gt;	&amp;quot;/usr/bin/perl&amp;quot;,&lt;br /&gt;
 		&amp;quot;.cgi&amp;quot;	=&amp;gt;	&amp;quot;/usr/bin/perl&amp;quot;,&lt;br /&gt;
 		&amp;quot;&amp;quot; =&amp;gt; &amp;quot;&amp;quot;&lt;br /&gt;
 	)&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
Add these lines to /etc/lighttpd/lighttpd.conf to point to the new document root, and set it up to listen on port 443 (replace &#039;&#039;host.example.com&#039;&#039; with the actual domain and &#039;&#039;ip_address_of_server&#039;&#039; with the actual IP address):&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
 simple-vhost.server-root   = &amp;quot;/var/www/domains/&amp;quot;&lt;br /&gt;
 simple-vhost.default-host  = &amp;quot;/host.example.com/&amp;quot;&lt;br /&gt;
 simple-vhost.document-root = &amp;quot;www/&amp;quot;&lt;br /&gt;
&lt;br /&gt;
 $SERVER[&amp;quot;socket&amp;quot;] == &amp;quot;ip_address_of_server:443&amp;quot; {&lt;br /&gt;
 ssl.engine    = &amp;quot;enable&amp;quot;&lt;br /&gt;
 ssl.pemfile   = &amp;quot;/etc/lighttpd/server-bundle.pem&amp;quot;&lt;br /&gt;
 ssl.ca-file   = &amp;quot;/etc/lighttpd/ca-crt.pem&amp;quot;&lt;br /&gt;
 }&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Ensure that the simple_vhosts module is loaded, as well as the cgi config scripts by uncommenting the following lines in /etc/lighttpd/lighttpd.conf&lt;br /&gt;
&lt;br /&gt;
 server.modules = (&lt;br /&gt;
     #  other modules may be listed&lt;br /&gt;
     &amp;quot;mod_simple_vhost&amp;quot;, &lt;br /&gt;
     #  other modules may be listed&lt;br /&gt;
  .&lt;br /&gt;
  .&lt;br /&gt;
  .&lt;br /&gt;
     include &amp;quot;mod_cgi.conf&amp;quot;&lt;br /&gt;
 &lt;br /&gt;
     include &amp;quot;mod_fastcgi.conf&amp;quot;&lt;br /&gt;
 &lt;br /&gt;
&lt;br /&gt;
Get a web certificate, and install it.  If you want to use a self-signed cert, you can use [[Generating SSL certs with ACF]] or [[Generating SSL certs with ACF 1.9]].  If you create a certificate with ACF, you can create the &amp;quot;server-bundle.pem&amp;quot; and the &amp;quot;ca-crt.pem&amp;quot; file with these commands:&lt;br /&gt;
&lt;br /&gt;
  openssl pkcs12 -nokeys -cacerts -in certificate.pfx  -out /etc/lighttpd/ca-crt.pem&lt;br /&gt;
  openssl pkcs12 -nodes -in certifcate.pfx -out /etc/lighttpd/server-bundle.pem&lt;br /&gt;
  chown root:root /etc/lighttpd/server-bundle.pem&lt;br /&gt;
  chmod 400 /etc/lighttpd/server-bundle.pem&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Note:&#039;&#039;&#039; The server certificate &#039;&#039;and&#039;&#039; key are in the server-bundle.pem file, so it is critical that the file be read-only by user &amp;quot;root&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
 Editme: We should probably only serve ACF to restricted hosts&lt;br /&gt;
&lt;br /&gt;
Stop and remove mini_httpd; start lighttpd, test&lt;br /&gt;
&lt;br /&gt;
  /etc/init.d/mini_httpd stop&lt;br /&gt;
  rc-update del mini_httpd&lt;br /&gt;
  apk del mini_httpd&lt;br /&gt;
  rc-update add lighttpd&lt;br /&gt;
  /etc/init.d/lighttpd start&lt;br /&gt;
&lt;br /&gt;
At this point you should be able to see ACF being served with lighttpd (Note: this will work well with alpine 1.10. With earlier versions there will be problems.)  https://host.example.com/acf/&lt;br /&gt;
&lt;br /&gt;
== Install Postgresql ==&lt;br /&gt;
&lt;br /&gt;
Add and configure postgresql&lt;br /&gt;
&lt;br /&gt;
  apk add acf-postgresql postgresql-client&lt;br /&gt;
  /etc/init.d/postgresql setup&lt;br /&gt;
  /etc/init.d/postgresql start&lt;br /&gt;
  rc-update add postgresql&lt;br /&gt;
&lt;br /&gt;
At this point any user can connect to the sql server with &amp;quot;trust&amp;quot; mechanism.  If you want to enforce password authentication (you probably do) edit /var/lib/postgresql/8.4/data/pg_hba.conf&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
  Editme: What should we recommend?&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Create the postfix database:&lt;br /&gt;
&lt;br /&gt;
  psql -U postgres&lt;br /&gt;
   create user postfix with password &#039;******&#039;;&lt;br /&gt;
   create database postfix owner postfix;&lt;br /&gt;
   \c postfix&lt;br /&gt;
   create language plpgsql;&lt;br /&gt;
   \q&lt;br /&gt;
&lt;br /&gt;
(Of course, use your selected password where ******* is shown above.)&lt;br /&gt;
&lt;br /&gt;
== Install PostfixAdmin ==&lt;br /&gt;
&lt;br /&gt;
We are going to install the postfix admin web front-end before we install the mail server.  This just creates an interface to populate the SQL tables that postfix and dovecot will use.&lt;br /&gt;
&lt;br /&gt;
Download PostfixAdmin from Sourceforge.  When these instructions were written, 2.3 was the current release, so (replace host.example.com with the actual domain):&lt;br /&gt;
 wget http://downloads.sourceforge.net/project/postfixadmin/postfixadmin/postfixadmin_2.3.tar.gz&lt;br /&gt;
 tar zxvf postfixadmin_2.3.tar.gz&lt;br /&gt;
 mkdir -p /var/www/domains/host.example.com/www/postfixadmin&lt;br /&gt;
 mv postfixadmin-2.3/* /var/www/domains/host.example.com/www/postfixadmin&lt;br /&gt;
 rm -rf postfixadmin*&lt;br /&gt;
&lt;br /&gt;
Edit /var/www/domains/host.example.com/www/postfixadmin/config.inc.php and modify at least these lines (replace host.example.com with the actual domain):&lt;br /&gt;
&lt;br /&gt;
 $CONF[&#039;configured&#039;] = true;&lt;br /&gt;
 $CONF[&#039;setup_password&#039;] = &amp;quot;&amp;quot;;  &amp;lt;&amp;lt; Don&#039;t change this yet&lt;br /&gt;
 $CONF[&#039;database_type&#039;] = &#039;pgsql&#039;;&lt;br /&gt;
 $CONF[&#039;database_host&#039;] = &#039;localhost&#039;;&lt;br /&gt;
 $CONF[&#039;database_user&#039;] = &#039;postfix&#039;;&lt;br /&gt;
 $CONF[&#039;database_password&#039;] = &#039;*****&#039;;   &amp;lt;&amp;lt; The password you chose above&lt;br /&gt;
 $CONF[&#039;database_name&#039;] = &#039;postfix&#039;;&lt;br /&gt;
 $CONF[&#039;database_prefix&#039;] = &amp;quot;&amp;quot;;&lt;br /&gt;
 $CONF[&#039;admin_email&#039;] = &#039;you@some.email.com&#039;;  &amp;lt;&amp;lt; Your email address &lt;br /&gt;
 $CONF[&#039;encrypt&#039;] = &#039;md5crypt&#039;;&lt;br /&gt;
 $CONF[&#039;authlib_default_flavor&#039;] = &#039;md5raw&#039;;&lt;br /&gt;
 $CONF[&#039;dovecotpw&#039;] = &amp;quot;/usr/sbin/dovecotpw&amp;quot;;&lt;br /&gt;
 $CONF[&#039;domain_path&#039;] = &#039;YES&#039;;&lt;br /&gt;
 $CONF[&#039;domain_in_mailbox&#039;] = &#039;NO&#039;;&lt;br /&gt;
 $CONF[&#039;aliases&#039;] = &#039;10&#039;;                       &lt;br /&gt;
 $CONF[&#039;mailboxes&#039;] = &#039;10&#039;;&lt;br /&gt;
 $CONF[&#039;maxquota&#039;] = &#039;10&#039;;&lt;br /&gt;
 $CONF[&#039;quota&#039;] = &#039;YES&#039;;&lt;br /&gt;
 $CONF[&#039;quota_multiplier&#039;] = &#039;1024000&#039;;&lt;br /&gt;
 $CONF[&#039;vacation&#039;] = &#039;NO&#039;; &lt;br /&gt;
 $CONF[&#039;vacation_control&#039;] =&#039;NO&#039;;&lt;br /&gt;
 $CONF[&#039;vacation_control_admin&#039;] = &#039;NO&#039;;&lt;br /&gt;
 $CONF[&#039;alias_control&#039;] = &#039;YES&#039;;&lt;br /&gt;
 $CONF[&#039;alias_control_admin&#039;] = &#039;YES&#039;;&lt;br /&gt;
 $CONF[&#039;special_alias_control&#039;] = &#039;YES&#039;;&lt;br /&gt;
 $CONF[&#039;fetchmail&#039;] = &#039;NO&#039;;&lt;br /&gt;
 $CONF[&#039;user_footer_link&#039;] = &amp;quot;http://host.example.com/postfixadmin&amp;quot;;&lt;br /&gt;
 $CONF[&#039;footer_link&#039;] = &#039;http://host.example.com/postfixadmin/main.php&#039;;&lt;br /&gt;
 $CONF[&#039;create_mailbox_subdirs_prefix&#039;]=&amp;quot;&amp;quot;;  &lt;br /&gt;
 $CONF[&#039;used_quotas&#039;] = &#039;YES&#039;;   &lt;br /&gt;
 $CONF[&#039;new_quota_table&#039;] = &#039;YES&#039;;  &lt;br /&gt;
&lt;br /&gt;
You should further edit /var/www/domains/host.example.com/www/postfixadmin/config.inc.php and replace all instances of &amp;quot;change-this-to-your.domain.tld&amp;quot; with your actual mail domain.&lt;br /&gt;
&lt;br /&gt;
Go to http://host.example.com/postfixadmin/setup.php&lt;br /&gt;
&lt;br /&gt;
Create the password hash, add it to the config.inc.php file&lt;br /&gt;
&lt;br /&gt;
Go back to http://host.example.com/postfixadmin/setup.php&lt;br /&gt;
&lt;br /&gt;
Create superadmin account.&lt;br /&gt;
&lt;br /&gt;
== Install Postfix ==&lt;br /&gt;
&lt;br /&gt;
Create a user for the virtual mail delivery, and get its uid/gid (you&#039;ll need the numeric uid/gid for postfix)&lt;br /&gt;
&lt;br /&gt;
 adduser vmail -H -D -s /bin/false&lt;br /&gt;
 grep vmail /etc/passwd&lt;br /&gt;
&lt;br /&gt;
(In examples below, we use 1006/1006 for the uid/gid)&lt;br /&gt;
&lt;br /&gt;
Create the mail directory, and assign vmail as the owner&lt;br /&gt;
 mkdir -p /var/mail/domains&lt;br /&gt;
 chown -R vmail:vmail /var/mail/domains&lt;br /&gt;
 &lt;br /&gt;
&lt;br /&gt;
Install postfix&lt;br /&gt;
&lt;br /&gt;
 apk add acf-postfix postfix-pgsql&lt;br /&gt;
&lt;br /&gt;
Edit the /etc/postfix/main.cf file. Here&#039;s an example (don&#039;t forget to replace the uid/gid):&lt;br /&gt;
&lt;br /&gt;
 myhostname=host.example.com&lt;br /&gt;
 mydomain=example.com&lt;br /&gt;
 &lt;br /&gt;
 mydestination = localhost.$mydomain, localhost&lt;br /&gt;
 mynetworks_style = subnet&lt;br /&gt;
 mynetworks = 127.0.0.0/8&lt;br /&gt;
 &lt;br /&gt;
 virtual_mailbox_domains = proxy:pgsql:/etc/postfix/sql/pgsql_virtual_domains_maps.cf&lt;br /&gt;
 virtual_alias_maps = proxy:pgsql:/etc/postfix/sql/pgsql_virtual_alias_maps.cf,&lt;br /&gt;
        proxy:pgsql:/etc/postfix/sql/pgsql_virtual_alias_domain_maps.cf,&lt;br /&gt;
        proxy:pgsql:/etc/postfix/sql/pgsql_virtual_alias_domain_catchall_maps.cf&lt;br /&gt;
 &lt;br /&gt;
 virtual_mailbox_maps = proxy:pgsql:/etc/postfix/sql/pgsql_virtual_mailbox_maps.cf,&lt;br /&gt;
        proxy:pgsql:/etc/postfix/sql/pgsql_virtual_alias_domain_mailbox_maps.cf&lt;br /&gt;
 &lt;br /&gt;
 virtual_mailbox_base = /var/mail/domains/&lt;br /&gt;
 virtual_gid_maps = static:1006&lt;br /&gt;
 virtual_uid_maps = static:1006&lt;br /&gt;
 virtual_minimum_uid = 100&lt;br /&gt;
 virtual_transport = virtual&lt;br /&gt;
 &lt;br /&gt;
 &lt;br /&gt;
 # This next command means you must create a virtual&lt;br /&gt;
 # domain for the host itself - ALL mail goes through&lt;br /&gt;
 # The virtual transport&lt;br /&gt;
 &lt;br /&gt;
 mailbox_transport = virtual&lt;br /&gt;
 local_transport = virtual&lt;br /&gt;
 local_transport_maps = $virtual_mailbox_maps&lt;br /&gt;
 &lt;br /&gt;
 smtpd_helo_required = yes&lt;br /&gt;
 disable_vrfy_command = yes&lt;br /&gt;
 message_size_limit = 10240000&lt;br /&gt;
 queue_minfree = 51200000&lt;br /&gt;
 &lt;br /&gt;
 smtpd_sender_restrictions =&lt;br /&gt;
        permit_mynetworks,&lt;br /&gt;
        reject_non_fqdn_sender,&lt;br /&gt;
        reject_unknown_sender_domain&lt;br /&gt;
 &lt;br /&gt;
 smtpd_recipient_restrictions =&lt;br /&gt;
        reject_non_fqdn_recipient,&lt;br /&gt;
        reject_unknown_recipient_domain,&lt;br /&gt;
        permit_mynetworks,&lt;br /&gt;
        permit_sasl_authenticated,&lt;br /&gt;
        reject_unauth_destination,&lt;br /&gt;
        reject_rbl_client dnsbl.sorbs.net,&lt;br /&gt;
        reject_rbl_client zen.spamhaus.org,&lt;br /&gt;
        reject_rbl_client bl.spamcop.net&lt;br /&gt;
 &lt;br /&gt;
 smtpd_data_restrictions = reject_unauth_pipelining&lt;br /&gt;
 &lt;br /&gt;
 # we will use this later - This prevents cleartext authentication&lt;br /&gt;
 # for relaying&lt;br /&gt;
 smtpd_tls_auth_only = yes&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Now we need to create a *bunch* of files so that postfix can get the delivery information out of sql. Here&#039;s a shell script to create the scripts.  Change PGPW to the password for the postfix user of the postfix SQL database.&lt;br /&gt;
&lt;br /&gt;
 cd /etc/postfix&lt;br /&gt;
 mkdir sql&lt;br /&gt;
 PGPW=&amp;quot;ChangeMe&amp;quot;&lt;br /&gt;
 &lt;br /&gt;
 cat - &amp;lt;&amp;lt;EOF &amp;gt;sql/pgsql_virtual_alias_domain_catchall_maps.cf&lt;br /&gt;
 user=postfix&lt;br /&gt;
 password = $PGPW&lt;br /&gt;
 hosts = localhost&lt;br /&gt;
 dbname = postfix&lt;br /&gt;
 query = Select goto From alias,alias_domain where alias_domain.alias_domain = &#039;%d&#039; and alias.address = &#039;@&#039; ||  alias_domain.target_domain and alias.active = true and alias_domain.active= true &lt;br /&gt;
 EOF&lt;br /&gt;
 &lt;br /&gt;
 cat - &amp;lt;&amp;lt;EOF &amp;gt;sql/pgsql_virtual_alias_domain_mailbox_maps.cf&lt;br /&gt;
 user=postfix&lt;br /&gt;
 password = $PGPW&lt;br /&gt;
 hosts = localhost&lt;br /&gt;
 dbname = postfix&lt;br /&gt;
 query = Select maildir from mailbox,alias_domain where alias_domain.alias_domain = &#039;%d&#039; and mailbox.username = &#039;%u&#039; || &#039;@&#039; || alias_domain.target_domain and mailbox.active = true and alias_domain.active&lt;br /&gt;
 EOF&lt;br /&gt;
 &lt;br /&gt;
 cat - &amp;lt;&amp;lt;EOF &amp;gt;sql/pgsql_virtual_alias_domain_maps.cf&lt;br /&gt;
 user=postfix&lt;br /&gt;
 password = $PGPW&lt;br /&gt;
 hosts = localhost&lt;br /&gt;
 dbname = postfix&lt;br /&gt;
 query = select goto from alias,alias_domain where alias_domain.alias_domain=&#039;%d&#039; and alias.address = &#039;%u&#039; || &#039;@&#039; || alias_domain.target_domain and alias.active= true and alias_domain.active= true&lt;br /&gt;
 EOF&lt;br /&gt;
 &lt;br /&gt;
 cat - &amp;lt;&amp;lt;EOF &amp;gt;sql/pgsql_virtual_alias_maps.cf&lt;br /&gt;
 user=postfix&lt;br /&gt;
 password = $PGPW&lt;br /&gt;
 hosts = localhost&lt;br /&gt;
 dbname = postfix&lt;br /&gt;
 query = Select goto From alias Where address=&#039;%s&#039; and active =&#039;1&#039;&lt;br /&gt;
 EOF&lt;br /&gt;
 &lt;br /&gt;
 cat - &amp;lt;&amp;lt;EOF &amp;gt;sql/pgsql_virtual_domains_maps.cf&lt;br /&gt;
 user=postfix&lt;br /&gt;
 password = $PGPW&lt;br /&gt;
 hosts = localhost&lt;br /&gt;
 dbname = postfix&lt;br /&gt;
 query = Select domain from domain where domain=&#039;%s&#039; and active=&#039;1&#039;&lt;br /&gt;
 EOF&lt;br /&gt;
 &lt;br /&gt;
 cat - &amp;lt;&amp;lt;EOF &amp;gt;sql/pgsql_virtual_mailbox_maps.cf&lt;br /&gt;
 user=postfix&lt;br /&gt;
 password = $PGPW&lt;br /&gt;
 hosts = localhost&lt;br /&gt;
 dbname = postfix&lt;br /&gt;
 query = Select maildir from mailbox where username=&#039;%s&#039; and active=true&lt;br /&gt;
 EOF&lt;br /&gt;
 &lt;br /&gt;
 chown -R postfix:postfix sql&lt;br /&gt;
 chmod 640 sql/*&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
At this point you should be able to start up postfix&lt;br /&gt;
 &lt;br /&gt;
 newaliases  # so postfix is happy...&lt;br /&gt;
 /etc/init.d/postfix start&lt;br /&gt;
 rc-update add postfix&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Create a domain in PostfixAdmin and test ===&lt;br /&gt;
&lt;br /&gt;
Go to http://host.example.com/postfixadmin/&lt;br /&gt;
&lt;br /&gt;
Log in using the superadmin account, create a domain for the local box (e.g. example.com), and create a user mailbox (e.g. root).&lt;br /&gt;
&lt;br /&gt;
From the machine, send a test message:&lt;br /&gt;
&lt;br /&gt;
 sendmail -t root@example.com&lt;br /&gt;
 subject: test&lt;br /&gt;
 .&lt;br /&gt;
 ^d&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
In /var/log/mail.log (or /var/log/messages, if you still have busybox syslogd running) you should see the message queued.  The message should be in /var/mail/domains/example.com/root/new&lt;br /&gt;
&lt;br /&gt;
== Install Dovecot ==&lt;br /&gt;
&lt;br /&gt;
Dovecot is the POP3/IMAP server to retrieve mail.&lt;br /&gt;
&lt;br /&gt;
As before, we install dovecot: &lt;br /&gt;
&lt;br /&gt;
 apk add acf-dovecot dovecot-pgsql&lt;br /&gt;
&lt;br /&gt;
edit /etc/dovecot/dovecot.conf&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 # Select only the protocols you wish to support - all are listed in the next line&lt;br /&gt;
 protocols               =       imap imaps pop pop3s&lt;br /&gt;
 log_path                =       /var/log/dovecot.log&lt;br /&gt;
 info_log_path           =       /var/log/dovecot-info.log&lt;br /&gt;
 disable_plaintext_auth  =       no&lt;br /&gt;
&lt;br /&gt;
 # Authenticated IMAP&lt;br /&gt;
 ssl                     =       yes&lt;br /&gt;
 ssl_cert_file           =       /etc/lighttpd/server-bundle.pem&lt;br /&gt;
 ssl_key_file            =       /etc/lighttpd/server-bundle.pem&lt;br /&gt;
 auth_verbose            =       yes&lt;br /&gt;
 auth_debug              =       no&lt;br /&gt;
 mail_location           =       maildir:/var/mail/domains/%d/%n&lt;br /&gt;
 auth default    {&lt;br /&gt;
        mechanisms = plain&lt;br /&gt;
        passdb sql {&lt;br /&gt;
                args = /etc/dovecot/dovecot-sql.conf&lt;br /&gt;
                }&lt;br /&gt;
        userdb static {&lt;br /&gt;
                args =  uid=1006 gid=1006 home=/var/mail/domains/%d/%n&lt;br /&gt;
                }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
We need a certificate for SSL/TLS authentication, so in the example above, we use the lighttpd cert. That way when the cert is renewed/replaced, Dovecot will have access to the new cert as well.  &lt;br /&gt;
&lt;br /&gt;
Create the /etc/dovecot/dovecot-sql.conf file:&lt;br /&gt;
&lt;br /&gt;
 driver = pgsql&lt;br /&gt;
 connect = host=localhost dbname=postfix user=postfix password=********&lt;br /&gt;
 password_query = select username,password from mailbox where local_part = &#039;%n&#039; and domain = &#039;%d&#039;&lt;br /&gt;
 default_pass_scheme =  MD5-CRYPT&lt;br /&gt;
&lt;br /&gt;
Again, change the password above to your postfix user password, and protect the file from prying eyes:&lt;br /&gt;
&lt;br /&gt;
 chown root:root /etc/dovecot/dovecot-sql.conf&lt;br /&gt;
 chmod 600 /etc/dovecot/dovecot-sql.conf&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Start dovecot&lt;br /&gt;
 /etc/init.d/dovecot start&lt;br /&gt;
 rc-update add dovecot&lt;br /&gt;
&lt;br /&gt;
== Testing ==&lt;br /&gt;
&lt;br /&gt;
Make sure your firewall allows in ports 25(SMTP) 110 (POP3), 995 (POP3S), 143(IMAP), 993(IMAPS), or whatever subset you support.  &lt;br /&gt;
 &lt;br /&gt;
At this point, you should be able to:&lt;br /&gt;
 * Create a new domain and add users with PostfixAdmin&lt;br /&gt;
 * Send mail to those users via SMTP to port 25&lt;br /&gt;
 * Retrieve mail using the user&#039;s full email and password (e.g. username: user@example.com  password: ChangeM&lt;br /&gt;
&lt;br /&gt;
== Value Add Features ==&lt;br /&gt;
&lt;br /&gt;
If you followed the guide above, you now have a functional mail server with many interconnected parts.  The features below assume that the server is already running as described above.  You should be able to add any or all of these features below to further enhance the mail service.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Virus Scanning ===&lt;br /&gt;
&lt;br /&gt;
This procedure uses clamav and the postfix content_filter mechanism to scan inbound and outbound email for viruses.  Infected emails are dropped.  Clean emails are tagged with a &amp;quot;scanned by clamav&amp;quot; header.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* Install clamav and clamsmtp:&lt;br /&gt;
 apk add acf-clamav clamsmtp&lt;br /&gt;
* Edit the /etc/clamav/clamd.conf file if desired (not necessary in most cases)&lt;br /&gt;
* Edit /etc/clamsmtpd.conf and verify the following lines&lt;br /&gt;
 OutAddress: 10026&lt;br /&gt;
 Listen: 127.0.0.1:10025                                               &lt;br /&gt;
 Header: X-Virus-Scanned: ClamAV using ClamSMTP&lt;br /&gt;
 Action: drop&lt;br /&gt;
 User: clamav                                                      &lt;br /&gt;
* Start the daemons&lt;br /&gt;
 rc-update add clamd&lt;br /&gt;
 rc-update add freshclam&lt;br /&gt;
 rc-update add clamsmtp&lt;br /&gt;
 /etc/init.d/clamd start&lt;br /&gt;
 /etc/init.d/freshclam start&lt;br /&gt;
 /etc/init.d/clamsmtp start&lt;br /&gt;
* Verify clamsmtp is listening on port 10025:&lt;br /&gt;
 netstat -anp | grep clamsmtp&lt;br /&gt;
* [http://memberwebs.com/stef/software/clamsmtp/postfix.html Following the clamsmtp instructions]&lt;br /&gt;
** edit /etc/postfix/main.cf and add:&lt;br /&gt;
 content_filter = scan:[127.0.0.1]:10025                                                      &lt;br /&gt;
** edit /etc/postfix/master.cf and add&lt;br /&gt;
 # AV scan filter (used by content_filter)&lt;br /&gt;
 scan      unix  -       -       n       -       16      smtp&lt;br /&gt;
         -o smtp_send_xforward_command=yes&lt;br /&gt;
         -o smtp_enforce_tls=no&lt;br /&gt;
 # For injecting mail back into postfix from the filter&lt;br /&gt;
 127.0.0.1:10026 inet  n -       n       -       16      smtpd&lt;br /&gt;
         -o content_filter=&lt;br /&gt;
         -o receive_override_options=no_unknown_recipient_checks,no_header_body_checks&lt;br /&gt;
         -o smtpd_helo_restrictions=&lt;br /&gt;
         -o smtpd_client_restrictions=&lt;br /&gt;
         -o smtpd_sender_restrictions=&lt;br /&gt;
         -o smtpd_recipient_restrictions=permit_mynetworks,reject&lt;br /&gt;
         -o mynetworks_style=host&lt;br /&gt;
         -o smtpd_authorized_xforward_hosts=127.0.0.0/8&lt;br /&gt;
* postfix reload&lt;br /&gt;
* Send and email into a local virtual domain - it should have the &#039;&#039;X-Virus-Scanned: ClamAV using ClamSMTP&#039;&#039; header.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Relay for Authenticated Users ===&lt;br /&gt;
&lt;br /&gt;
As configured above, the mail server accepts email from the Internet, but it does not relay email.  If it is a perimeter exchanger for a protected network, then you can add the protected networks to the &#039;&#039;mynetworks&#039;&#039; configuration line in /etc/postfix/main.cf&lt;br /&gt;
&lt;br /&gt;
This configuration change allows &#039;&#039;remote&#039;&#039; users to authenticate against the mail server and relay through it.  The rules for relaying are:&lt;br /&gt;
* Only authenticated users can relay&lt;br /&gt;
* Authentication Credentials must be encrypted with TLS or SSL&lt;br /&gt;
* Allow Submission and SMTPS ports for relaying (many consumer networks block port 25 - SMTP by default)&lt;br /&gt;
The process uses the dovecot authentication mechanism (used with IMAPS) to authenticate users before they are allowed to relay through postfix.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* Edit /etc/dovecot/dovecot.conf and add:&lt;br /&gt;
 # this is for postfix SASL (authenticated users can relay through us)&lt;br /&gt;
 socket listen {&lt;br /&gt;
                client {&lt;br /&gt;
                        path    = /var/spool/postfix/private/dovecot-auth.sock&lt;br /&gt;
                        mode    = 0660&lt;br /&gt;
                        user    = postfix&lt;br /&gt;
                        group   = postfix&lt;br /&gt;
                        }&lt;br /&gt;
                }&lt;br /&gt;
        }&lt;br /&gt;
* Restart dovecot&lt;br /&gt;
 /etc/init.d/dovecot restart&lt;br /&gt;
* Edit /etc/postfix/main.cf and add:&lt;br /&gt;
 # TLS Stuff -- since we allow SASL with tls *only*, we have to set up TLS first                    &lt;br /&gt;
 &lt;br /&gt;
 smtpd_tls_cert_file = /etc/lighttpd/server-bundle.pem&lt;br /&gt;
 smtpd_tls_key_file = /etc/lighttpd/server-bundle.pem&lt;br /&gt;
 smtpd_tls_CAfile = /etc/lighttpd/ca-crt.pem&lt;br /&gt;
 # If tls_security_level is set to &amp;quot;encrypt&amp;quot;, then SMTP rejects &lt;br /&gt;
 # unencrypted email (e.g. normal mail) which is bad.&lt;br /&gt;
 # By setting it to &amp;quot;may&amp;quot; you get TLS encrypted mail from google, slashdot, and other &lt;br /&gt;
 # interesting places.  Check your logs to see who&lt;br /&gt;
 smtpd_tls_security_level = may&lt;br /&gt;
 # Log info about the negotiated encryption levels&lt;br /&gt;
 smtpd_tls_received_header = yes&lt;br /&gt;
 smtpd_tls_loglevel = 1&lt;br /&gt;
 &lt;br /&gt;
 # SASL - this allows senders to authenticiate themselves&lt;br /&gt;
 # This along with &amp;quot;permit_sasl_authenticated&amp;quot; in smtpd_recipient_restrictions allows relaying&lt;br /&gt;
 smtpd_sasl_type = dovecot&lt;br /&gt;
 smtpd_sasl_path = private/dovecot-auth.sock&lt;br /&gt;
 smtpd_sasl_auth_enable = yes&lt;br /&gt;
 smtpd_sasl_authenticated_header = yes&lt;br /&gt;
 smtpd_tls_auth_only = yes&lt;br /&gt;
* Edit /etc/postfix/master.cf and enable the submission and smtps transports.  They are probably already at the top of your  master.cf file, just commented out:&lt;br /&gt;
 submission inet n       -       n       -       -       smtpd&lt;br /&gt;
   -o smtpd_tls_security_level=encrypt&lt;br /&gt;
   -o smtpd_sasl_auth_enable=yes&lt;br /&gt;
   -o smtpd_client_restrictions=permit_sasl_authenticated,reject&lt;br /&gt;
   -o milter_macro_daemon_name=ORIGINATING&lt;br /&gt;
 smtps     inet  n       -       n       -       -       smtpd&lt;br /&gt;
   -o smtpd_tls_security_level=encrypt&lt;br /&gt;
   -o smtpd_tls_wrappermode=yes&lt;br /&gt;
   -o smtpd_sasl_auth_enable=yes&lt;br /&gt;
   -o smtpd_client_restrictions=permit_sasl_authenticated,reject&lt;br /&gt;
   -o milter_macro_daemon_name=ORIGINATING&lt;br /&gt;
*Verfiy submission and smtps are defined in /etc/services&lt;br /&gt;
 grep &amp;quot;submission\|ssmtp&amp;quot; /etc/services&lt;br /&gt;
 submission	587/tcp				# mail message submission&lt;br /&gt;
 submission	587/udp&lt;br /&gt;
 smtps		465/tcp		ssmtp		# smtp protocol over TLS/SSL&lt;br /&gt;
 smtps		465/udp		ssmtp&lt;br /&gt;
* Restart postfix&lt;br /&gt;
 postfix reload&lt;br /&gt;
&lt;br /&gt;
At this point, you should be able to set up a mail client to relay through the server with TLS (port 587) or SSL (port 465)  Note that &amp;quot;plain&amp;quot; authentication is used because the underlying link is encrypted.  For example, in Thunderbird leave &amp;quot;secure authentication&amp;quot; unchecked, and choose STARTTLS (or TLS) for the connection security.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Mailbox Quotas ===&lt;br /&gt;
&lt;br /&gt;
In the default configuration, PostfixAdmin knows about quotas, but they are not enforced.   Documentation on the web mentions the [http://vda.sourceforge.net vda patch to postfix] to enforce quotas.  The only bad thing... its a &#039;&#039;patch&#039;&#039;.   Postfix and Dovecot are both conservative systems, so if the patch isn&#039;t in the upstream source, we&#039;ll assume there&#039;s a good reason.   There is a way of using quotas without patches - and it involves using dovecot&#039;s [http://wiki.dovecot.org/LDA deliver] lda for local delivery.&lt;br /&gt;
&lt;br /&gt;
Note: As of Jan 2010, the documention is confusing, with multiple versions of dovecot, PostfixAdmin, and Mysql referenced.  These instructions apply to:&lt;br /&gt;
* Postgresql 8.4.2 &lt;br /&gt;
* PostfixAdmin 2.3 &lt;br /&gt;
* Dovecot 1.2.10&lt;br /&gt;
* Postfix 2.6.5&lt;br /&gt;
&lt;br /&gt;
Presumably later versions will work the same, but if not, please update the documentation and versions above.&lt;br /&gt;
&lt;br /&gt;
* Update /etc/dovecot.conf (old lines shown commented out):&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
# old postfix &lt;br /&gt;
#       userdb static {&lt;br /&gt;
#               args =  uid=1006 gid=1006 home=/var/mail/domains/%d/%n&lt;br /&gt;
#               }&lt;br /&gt;
&lt;br /&gt;
# new quota support:&lt;br /&gt;
        userdb prefetch {&lt;br /&gt;
                }&lt;br /&gt;
&lt;br /&gt;
        userdb sql {&lt;br /&gt;
                args = /etc/dovecot/dovecot-sql.conf&lt;br /&gt;
                }&lt;br /&gt;
&lt;br /&gt;
        socket listen {&lt;br /&gt;
                client {&lt;br /&gt;
                        path    = /var/spool/postfix/private/dovecot-auth.sock&lt;br /&gt;
                        mode    = 0660&lt;br /&gt;
                        user    = postfix&lt;br /&gt;
                        group   = postfix&lt;br /&gt;
                        }&lt;br /&gt;
                # These lines below are for the deliver lda&lt;br /&gt;
                master {&lt;br /&gt;
                        path =  /var/run/dovecot/auth-master&lt;br /&gt;
                        mode    = 0660&lt;br /&gt;
                        user    = vmail&lt;br /&gt;
                        group   = vmail&lt;br /&gt;
                        }&lt;br /&gt;
                }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
protocol imap {                                                               &lt;br /&gt;
         mail_plugins = quota imap_quota                                       &lt;br /&gt;
         }                                                                     &lt;br /&gt;
                                                                              &lt;br /&gt;
protocol pop3 {                                                               &lt;br /&gt;
         mail_plugins = quota                                                  &lt;br /&gt;
         }                                                                     &lt;br /&gt;
                                                                              &lt;br /&gt;
dict {                                                                        &lt;br /&gt;
        quotadict = pgsql:/etc/dovecot/dovecot-dict-quota.conf                &lt;br /&gt;
        }                                                                     &lt;br /&gt;
                                                                              &lt;br /&gt;
plugin {                                                                      &lt;br /&gt;
         quota = dict:user::proxy::quotadict                                   &lt;br /&gt;
         }                                                     &lt;br /&gt;
                                                              &lt;br /&gt;
protocol lda {                                                &lt;br /&gt;
   postmaster_address = postmaster@host.example.com&lt;br /&gt;
   mail_plugins = quota                                        &lt;br /&gt;
   auth_socket_path =  /var/run/dovecot/auth-master&lt;br /&gt;
   sendmail_path = /usr/sbin/sendmail&lt;br /&gt;
}                                                                            &lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
 &lt;br /&gt;
You should already have a &amp;lt;tt&amp;gt;socket-&amp;gt; listen-&amp;gt; client&amp;lt;/tt&amp;gt; section, but it is listed above to show where it goes in relationship to the &amp;lt;tt&amp;gt;socket -&amp;gt; listen -&amp;gt; master&amp;lt;/tt&amp;gt; section&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* edit &amp;lt;tt&amp;gt;/etc/dovecot/dovecot-sql.conf&amp;lt;/tt&amp;gt; and replace the user and password queries with the following (you may not have a user_query yet - add it):&lt;br /&gt;
&lt;br /&gt;
 password_query = select username as user, password, 1006 as userdb_uid, 1006 as userdb_gid, &#039;*:bytes=&#039; || quota as userdb_quota_rule from mailbox  where local_part = &#039;%n&#039; and domain = &#039;%d&#039;&lt;br /&gt;
 user_query = select maildir as home, 1006 as uid, 1006 as gid, &#039;*:bytes=&#039; || quota  as quota_rule from mailbox where local_part = &#039;%n&#039; and domain =&#039;%d&#039;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* create &amp;lt;tt&amp;gt;/etc/dovecot/dovecot-dict-quota.conf&amp;lt;/tt&amp;gt;&lt;br /&gt;
 connect = host=localhost dbname=postfix user=postfix password=********&lt;br /&gt;
 &lt;br /&gt;
 map {&lt;br /&gt;
         pattern = priv/quota/storage&lt;br /&gt;
         table = quota2&lt;br /&gt;
         username_field =username&lt;br /&gt;
         value_field = bytes&lt;br /&gt;
 }&lt;br /&gt;
 &lt;br /&gt;
 map {&lt;br /&gt;
        pattern= priv/quota/messages&lt;br /&gt;
        table = quota2&lt;br /&gt;
        username_field = username&lt;br /&gt;
        value_field = messages&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
Side note: [http://wiki.dovecot.org/Quota/Dict The Dovecot Quota Documentation] mentions the need for a trigger with pgsql.  This was created in the PostfixAdmin install, which is why you instantiated the pgsql language when creating the database.  If not, you will need to create the trigger, to reference the quota2 table, not the quota table mentioned in the dovecot docs.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* create a new transport for the dovecot lda.   Add the following to  /etc/postfix/master.cf:&lt;br /&gt;
 # The dovecot deliver lda&lt;br /&gt;
 dovecot   unix  -       n       n       -       -       pipe&lt;br /&gt;
   flags=DRhu user=vmail:vmail argv=/usr/libexec/dovecot/deliver -f ${sender} -d ${user}@${nexthop}&lt;br /&gt;
&lt;br /&gt;
* Edit the /etc/postfix/main.cf.  Replace &lt;br /&gt;
 virtual_transport = virtual &lt;br /&gt;
with&lt;br /&gt;
 virtual_transport = dovecot&lt;br /&gt;
 dovecot_destination_recipient_limit = 1&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;TODO&#039;&#039;&#039;  This will cause over-quota emails to bounce.   Which could be a source of backscatter.   We need a way of checking quota limits after RBL checking but before the message is accepted in the queue.&lt;br /&gt;
&lt;br /&gt;
=== WebMail (RoundCube) ===&lt;br /&gt;
&lt;br /&gt;
[http://roundcube.net/ RoundCube] is an &amp;quot;ajax /Web2.0&amp;quot; web-mail client.  These instructions are for the Alpine Linux 1.10 repository &lt;br /&gt;
&lt;br /&gt;
* Add the package and related php modules:&lt;br /&gt;
 apk add roundcubemail php-xml php-openssl php-mcrypt php-gd php-iconv&lt;br /&gt;
&lt;br /&gt;
* link the roundcube application back into the docroot&lt;br /&gt;
 ln -s /usr/share/webapps/roundcube /var/www/domains/host.example.com/www/roundcube&lt;br /&gt;
&lt;br /&gt;
* follow the instructions in /usr/share/webapps/roundcube/INSTALL:&lt;br /&gt;
 chown -R lighttpd:lighttpd temp logs&lt;br /&gt;
 &lt;br /&gt;
 su postgres&lt;br /&gt;
 createuser roundcube&lt;br /&gt;
   Shall the new role be a superuser? (y/n) n&lt;br /&gt;
   Shall the new role be allowed to create databases? (y/n) n&lt;br /&gt;
   Shall the new role be allowed to create more new roles? (y/n) y&lt;br /&gt;
 createdb -O roundcube -E UNICODE -T template0 roundcubemail&lt;br /&gt;
 psql roundcubemail&lt;br /&gt;
   roundcubemail=# ALTER USER roundcube WITH PASSWORD &#039;the_new_password&#039;;&lt;br /&gt;
   roundcubemail=# \c - roundcube&lt;br /&gt;
   \i /usr/share/webapps/roundcube/SQL/postgres.initial.sql&lt;br /&gt;
   \q&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* restart lighttpd to verify the new php libraries are used&lt;br /&gt;
 /etc/init.d/lighttpd restart&lt;br /&gt;
&lt;br /&gt;
* Point your browser to http://host.example.com/roundcube/installer&lt;br /&gt;
** Begin installation&lt;br /&gt;
** Follow the instructions in step 3 of the install to copy the files to the server&lt;br /&gt;
* edit /etc/php/php.ini and edit date.timezone to your local timezone, or to UTC&lt;br /&gt;
* if necessary (e.g. you had to reset the local timezone) restart lighttpd to reload php&lt;br /&gt;
 /etc/init.d/lighttpd restart&lt;br /&gt;
* You should now be able to get to roundcube at http://host.example.com/roundcube&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
For the specific configuration parameters in the install step:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!Property&lt;br /&gt;
!Setting&lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;enable_spellcheck&#039;&#039; ||   disabled &lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;identities_level&#039;&#039; ||  one identity with possibility to edit all params but not email address &lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;log driver&#039;&#039; || syslog &lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;sylog_id&#039;&#039; || roundcube &lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;syslog_facility&#039;&#039; || mailsubsystem &lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;db_dnsw&#039;&#039; || pgsql properties, as described above &lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;imap_host&#039;&#039; || 127.0.0.1 &lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;auto_create_user&#039;&#039; || enabled &lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;smtp_server&#039;&#039; ||  127.0.0.1&lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;smtp_port&#039;&#039; ||  25&lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;smtp_user/smtp_pass&#039;&#039; ||  enable &#039;&#039;Use Current IMAP username and password for SMTP authentication&#039;&#039;&lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;smtp_log&#039;&#039; ||  enable (optional, but gives additional log record)&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
The other items can be left at default settings, or adjusted if desired.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
After its working, the INSTALL file recommends removing the install directory.   If you want to keep the installer around later, you can simply change the ownership and permissions.  So do &#039;&#039;&#039;one&#039;&#039;&#039; of the following:&lt;br /&gt;
 cd /usr/share/webapps/roundcube&lt;br /&gt;
 rm -rf LICENSE UPGRADING INSTALL README CHANGELOG  SQL installer&lt;br /&gt;
or&lt;br /&gt;
 cd /usr/share/webapps/roundcube&lt;br /&gt;
 chown -R root:root LICENSE UPGRADING INSTALL README CHANGELOG  SQL installer&lt;br /&gt;
 chmod -R 600 LICENSE UPGRADING INSTALL README CHANGELOG SQL &lt;br /&gt;
 chmod 700 SQL installer&lt;br /&gt;
&lt;br /&gt;
== log rotation ==&lt;br /&gt;
&lt;br /&gt;
Ensure the busybox cron service is started and is configured to auto-start:&lt;br /&gt;
&lt;br /&gt;
 /etc/init.d/cron start&lt;br /&gt;
 rc-update add cron default&lt;br /&gt;
&lt;br /&gt;
Add log rotate:&lt;br /&gt;
&lt;br /&gt;
 apk add logrotate&lt;br /&gt;
&lt;br /&gt;
Edit &#039;&#039;/etc/logrotate.conf&#039;&#039; as desired, but the defaults should be sufficient for most people.&lt;br /&gt;
&lt;br /&gt;
== Configure DNS ==&lt;br /&gt;
&lt;br /&gt;
This server hosts three separate web applications, and these can be handled as three different virtual domains on the same web server. They will be distinguished by their DNS names, so you can choose domains for the three separate services (or at least the ones you want to publish):&lt;br /&gt;
&lt;br /&gt;
* ACF - Alpine Configuration Framework for managing the server&lt;br /&gt;
* PostfixAdmin - for managing the postfix installation&lt;br /&gt;
* RoundCube - for accessing individual mailboxes&lt;br /&gt;
&lt;br /&gt;
Choose three different domains (from here on known as ACF_DOMAIN, POSTFIXADMIN_DOMAIN, and ROUNDCUBE_DOMAIN) and configure DNS for all three to point to the IP address of your host. These should be DNS A records.&lt;br /&gt;
&lt;br /&gt;
Then, configure lighttpd to handle the three separate domains by editing /etc/lighttpd/lighttpd.conf:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 $HTTP[&amp;quot;host&amp;quot;] == &amp;quot;ACF_DOMAIN&amp;quot; {&lt;br /&gt;
	simple-vhost.server-root   = &amp;quot;/var/www/domains/&amp;quot;&lt;br /&gt;
	simple-vhost.default-host  = &amp;quot;/ACF_DOMAIN/&amp;quot;&lt;br /&gt;
	simple-vhost.document-root = &amp;quot;www/&amp;quot;&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
 $HTTP[&amp;quot;host&amp;quot;] == &amp;quot;POSTFIXADMIN_DOMAIN&amp;quot; {&lt;br /&gt;
	simple-vhost.server-root   = &amp;quot;/var/www/domains/&amp;quot;&lt;br /&gt;
	simple-vhost.default-host  = &amp;quot;/POSTFIXADMIN_DOMAIN/&amp;quot;&lt;br /&gt;
	simple-vhost.document-root = &amp;quot;www/&amp;quot;&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
 $HTTP[&amp;quot;host&amp;quot;] == &amp;quot;ROUNDCUBE_DOMAIN&amp;quot; {&lt;br /&gt;
	simple-vhost.server-root   = &amp;quot;/var/www/domains/&amp;quot;&lt;br /&gt;
	simple-vhost.default-host  = &amp;quot;/ROUNDCUBE_DOMAIN/&amp;quot;&lt;br /&gt;
	simple-vhost.document-root = &amp;quot;www/&amp;quot;&lt;br /&gt;
 }&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
And, then link the appropriate www directories.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  mkdir -p /var/www/domains/ACF_DOMAIN&lt;br /&gt;
  ln -s /usr/share/acf/www /var/www/domains/ACF_DOMAIN/www&lt;br /&gt;
&lt;br /&gt;
  mkdir -p /var/www/domains/POSTFIXADMIN_DOMAIN&lt;br /&gt;
  ln -s /var/www/domains/host.example.com/www/postfixadmin /var/www/domains/POSTFIXADMIN_DOMAIN/www&lt;br /&gt;
&lt;br /&gt;
  mkdir -p /var/www/domains/ROUNDCUBE_DOMAIN&lt;br /&gt;
  ln -s /usr/share/webapps/roundcube /var/www/domains/ROUNDCUBE_DOMAIN/www&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;/div&gt;</summary>
		<author><name>Djhughes</name></author>
	</entry>
	<entry>
		<id>https://wiki.alpinelinux.org/w/index.php?title=ISP_Mail_Server_HowTo&amp;diff=3352</id>
		<title>ISP Mail Server HowTo</title>
		<link rel="alternate" type="text/html" href="https://wiki.alpinelinux.org/w/index.php?title=ISP_Mail_Server_HowTo&amp;diff=3352"/>
		<updated>2010-02-17T13:41:30Z</updated>

		<summary type="html">&lt;p&gt;Djhughes: Added some steps for logrotation.&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== A Full Service Mail Server ==&lt;br /&gt;
&lt;br /&gt;
The goal of this document is to describe how to set up postfix, dovecot, clamav, dspam, roundecube, and postfixadmin for a full-featured &amp;quot;ISP&amp;quot; level mail server.&lt;br /&gt;
&lt;br /&gt;
The server must provide:&lt;br /&gt;
&lt;br /&gt;
* multiple virtual domains&lt;br /&gt;
* admins for each domain (to add/remove virtual accounts)&lt;br /&gt;
* Quota support per domain / account&lt;br /&gt;
* downloading email via IMAP / IMAPS / POP3 / POP3S&lt;br /&gt;
* relaying email for authenticated users with TLS or SSL (Submission / SMTPS protocol)&lt;br /&gt;
* Standard filters (virus/spam/rbl/etc)&lt;br /&gt;
* Web mail client&lt;br /&gt;
* Value Add services&lt;br /&gt;
&lt;br /&gt;
== Configure DNS ==&lt;br /&gt;
&lt;br /&gt;
This server will host three separate virtual domains on the same web server. They will be distinguished by their DNS names, so you must choose three domains for the three separate services:&lt;br /&gt;
&lt;br /&gt;
* ACF - Alpine Configuration Framework for managing the server&lt;br /&gt;
* PostfixAdmin - for managing the postfix installation&lt;br /&gt;
* RoundCube - for accessing individual mailboxes&lt;br /&gt;
&lt;br /&gt;
Choose three different domains (from here on known as ACF_DOMAIN, POSTFIXADMIN_DOMAIN, and ROUNDCUBE_DOMAIN) and configure DNS for all three to point to the IP address of your host. These should be DNS A records.&lt;br /&gt;
&lt;br /&gt;
== Set up Lighttpd + PHP ==&lt;br /&gt;
&lt;br /&gt;
PostfixAdmin needs php pgpsql and imap modules, so we do it in this step.&lt;br /&gt;
&lt;br /&gt;
  apk add lighttpd php php-pgsql php-imap&lt;br /&gt;
&lt;br /&gt;
Stop and remove mini_httpd, and move ACF to lighttpd;  We are setting this up to be a multi-domain virtual web server (replace ACF_DOMAIN with the actual domain):&lt;br /&gt;
&lt;br /&gt;
  mkdir -p /var/www/domains/ACF_DOMAIN&lt;br /&gt;
  ln -s /usr/share/acf/www /var/www/domains/ACF_DOMAIN/www&lt;br /&gt;
&lt;br /&gt;
Edit /etc/lighttpd/mod_cgi.conf to serve haserl files by adding a &amp;quot;&amp;quot; =&amp;gt; &amp;quot;&amp;quot; cgi handler&lt;br /&gt;
&lt;br /&gt;
 $HTTP[&amp;quot;url&amp;quot;] =~ &amp;quot;^/cgi-bin/&amp;quot; {&lt;br /&gt;
     # disable directory listings&lt;br /&gt;
     dir-listing.activate = &amp;quot;disable&amp;quot;&lt;br /&gt;
     # only allow cgi&#039;s in this directory&lt;br /&gt;
     cgi.assign = (&lt;br /&gt;
 		&amp;quot;.pl&amp;quot;	=&amp;gt;	&amp;quot;/usr/bin/perl&amp;quot;,&lt;br /&gt;
 		&amp;quot;.cgi&amp;quot;	=&amp;gt;	&amp;quot;/usr/bin/perl&amp;quot;,&lt;br /&gt;
 		&amp;quot;&amp;quot; =&amp;gt; &amp;quot;&amp;quot;&lt;br /&gt;
 	)&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
Add these lines to /etc/lighttpd/lighttpd.conf to point to the new document root, and set it up to listen on port 443 (replace &#039;&#039;ROUNDCUBE_DOMAIN&#039;&#039; with the roundcube domain and &#039;&#039;ip_address_of_server&#039;&#039; with the actual IP address):&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
 simple-vhost.server-root   = &amp;quot;/var/www/domains/&amp;quot;&lt;br /&gt;
 simple-vhost.default-host  = &amp;quot;/ROUNDCUBE_DOMAIN/&amp;quot;&lt;br /&gt;
 simple-vhost.document-root = &amp;quot;www/&amp;quot;&lt;br /&gt;
&lt;br /&gt;
 $HTTP[&amp;quot;host&amp;quot;] == &amp;quot;POSTFIXADMIN_DOMAIN&amp;quot; {&lt;br /&gt;
	simple-vhost.server-root   = &amp;quot;/var/www/domains/&amp;quot;&lt;br /&gt;
	simple-vhost.default-host  = &amp;quot;/POSTFIXADMIN_DOMAIN/&amp;quot;&lt;br /&gt;
	simple-vhost.document-root = &amp;quot;www/&amp;quot;&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
 $HTTP[&amp;quot;host&amp;quot;] == &amp;quot;ACF_DOMAIN&amp;quot; {&lt;br /&gt;
	simple-vhost.server-root   = &amp;quot;/var/www/domains/&amp;quot;&lt;br /&gt;
	simple-vhost.default-host  = &amp;quot;/ACF_DOMAIN/&amp;quot;&lt;br /&gt;
	simple-vhost.document-root = &amp;quot;www/&amp;quot;&lt;br /&gt;
 } &lt;br /&gt;
 $SERVER[&amp;quot;socket&amp;quot;] == &amp;quot;ip_address_of_server:443&amp;quot; {&lt;br /&gt;
 ssl.engine    = &amp;quot;enable&amp;quot;&lt;br /&gt;
 ssl.pemfile   = &amp;quot;/etc/lighttpd/server-bundle.pem&amp;quot;&lt;br /&gt;
 ssl.ca-file   = &amp;quot;/etc/lighttpd/ca-crt.pem&amp;quot;&lt;br /&gt;
 }&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Ensure that the simple_vhosts module is loaded, as well as the cgi config scripts by uncommenting the following lines in /etc/lighttpd/lighttpd.conf&lt;br /&gt;
&lt;br /&gt;
 server.modules = (&lt;br /&gt;
     #  other modules may be listed&lt;br /&gt;
     &amp;quot;mod_simple_vhost&amp;quot;, &lt;br /&gt;
     #  other modules may be listed&lt;br /&gt;
  .&lt;br /&gt;
  .&lt;br /&gt;
  .&lt;br /&gt;
     include &amp;quot;mod_cgi.conf&amp;quot;&lt;br /&gt;
 &lt;br /&gt;
     include &amp;quot;mod_fastcgi.conf&amp;quot;&lt;br /&gt;
 &lt;br /&gt;
&lt;br /&gt;
Get a web certificate, and install it.  If you want to use a self-signed cert, you can use [[Generating SSL certs with ACF]] or [[Generating SSL certs with ACF 1.9]].  If you create a certificate with ACF, you can create the &amp;quot;server-bundle.pem&amp;quot; and the &amp;quot;ca-crt.pem&amp;quot; file with these commands:&lt;br /&gt;
&lt;br /&gt;
  openssl pkcs12 -nokeys -cacerts -in certificate.pfx  -out /etc/lighttpd/ca-crt.pem&lt;br /&gt;
  openssl pkcs12 -nodes -in certifcate.pfx -out /etc/lighttpd/server-bundle.pem&lt;br /&gt;
  chown root:root /etc/lighttpd/server-bundle.pem&lt;br /&gt;
  chmod 400 /etc/lighttpd/server-bundle.pem&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Note:&#039;&#039;&#039; The server certificate &#039;&#039;and&#039;&#039; key are in the server-bundle.pem file, so it is critical that the file be read-only by user &amp;quot;root&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
 Editme: We should probably only serve ACF to restricted hosts&lt;br /&gt;
&lt;br /&gt;
Stop and remove mini_httpd; start lighttpd, test&lt;br /&gt;
&lt;br /&gt;
  /etc/init.d/mini_httpd stop&lt;br /&gt;
  rc-update del mini_httpd&lt;br /&gt;
  apk del mini_httpd&lt;br /&gt;
  rc-update add lighttpd&lt;br /&gt;
  /etc/init.d/lighttpd start&lt;br /&gt;
&lt;br /&gt;
At this point you should be able to see ACF being served with lighttpd:  https://ACF_DOMAIN/&lt;br /&gt;
&lt;br /&gt;
== Install Postgresql ==&lt;br /&gt;
&lt;br /&gt;
Add and configure postgresql&lt;br /&gt;
&lt;br /&gt;
  apk add acf-postgresql postgresql-client&lt;br /&gt;
  /etc/init.d/postgresql setup&lt;br /&gt;
  /etc/init.d/postgresql start&lt;br /&gt;
  rc-update add postgresql&lt;br /&gt;
&lt;br /&gt;
At this point any user can connect to the sql server with &amp;quot;trust&amp;quot; mechanism.  If you want to enforce password authentication (you probably do) edit /var/lib/postgresql/8.4/data/pg_hba.conf&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
  Editme: What should we recommend?&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Create the postfix database:&lt;br /&gt;
&lt;br /&gt;
  psql -U postgres&lt;br /&gt;
   create user postfix with password &#039;******&#039;;&lt;br /&gt;
   create database postfix owner postfix;&lt;br /&gt;
   \c postfix&lt;br /&gt;
   create language plpgsql;&lt;br /&gt;
   \q&lt;br /&gt;
&lt;br /&gt;
(Of course, use your selected password where ******* is shown above.)&lt;br /&gt;
&lt;br /&gt;
== Install PostfixAdmin ==&lt;br /&gt;
&lt;br /&gt;
We are going to install the postfix admin web front-end before we install the mail server.  This just creates an interface to populate the SQL tables that postfix and dovecot will use.&lt;br /&gt;
&lt;br /&gt;
Download PostfixAdmin from Sourceforge.  When these instructions were written, 2.3 was the current release, so (replace POSTFIXADMIN_DOMAIN with the actual domain):&lt;br /&gt;
 wget http://downloads.sourceforge.net/project/postfixadmin/postfixadmin/postfixadmin_2.3.tar.gz&lt;br /&gt;
 tar zxvf postfixadmin_2.3.tar.gz&lt;br /&gt;
 mkdir -p /var/www/domains/POSTFIXADMIN_DOMAIN/www&lt;br /&gt;
 mv postfixadmin-2.3/* /var/www/domains/POSTFIXADMIN_DOMAIN/www&lt;br /&gt;
 rm -rf postfixadmin*&lt;br /&gt;
&lt;br /&gt;
Edit /var/www/domains/POSTFIXADMIN_DOMAIN/www/config.inc.php and modify at least these lines (replace POSTFIXADMIN_DOMAIN with the actual domain):&lt;br /&gt;
&lt;br /&gt;
 $CONF[&#039;configured&#039;] = true;&lt;br /&gt;
 $CONF[&#039;setup_password&#039;] = &amp;quot;&amp;quot;;  &amp;lt;&amp;lt; Don&#039;t change this yet&lt;br /&gt;
 $CONF[&#039;database_type&#039;] = &#039;pgsql&#039;;&lt;br /&gt;
 $CONF[&#039;database_host&#039;] = &#039;localhost&#039;;&lt;br /&gt;
 $CONF[&#039;database_user&#039;] = &#039;postfix&#039;;&lt;br /&gt;
 $CONF[&#039;database_password&#039;] = &#039;*****&#039;;   &amp;lt;&amp;lt; The password you chose above&lt;br /&gt;
 $CONF[&#039;database_name&#039;] = &#039;postfix&#039;;&lt;br /&gt;
 $CONF[&#039;database_prefix&#039;] = &#039;&#039;;&lt;br /&gt;
 $CONF[&#039;admin_email&#039;] = &#039;you@some.email.com&#039;;  &amp;lt;&amp;lt; Your email address &lt;br /&gt;
 $CONF[&#039;encrypt&#039;] = &#039;md5crypt&#039;;&lt;br /&gt;
 $CONF[&#039;authlib_default_flavor&#039;] = &#039;md5raw&#039;;&lt;br /&gt;
 $CONF[&#039;dovecotpw&#039;] = &amp;quot;/usr/sbin/dovecotpw&amp;quot;;&lt;br /&gt;
 $CONF[&#039;domain_path&#039;] = &#039;YES&#039;;&lt;br /&gt;
 $CONF[&#039;domain_in_mailbox&#039;] = &#039;NO&#039;;&lt;br /&gt;
 $CONF[&#039;aliases&#039;] = &#039;10&#039;;                       &lt;br /&gt;
 $CONF[&#039;mailboxes&#039;] = &#039;10&#039;;&lt;br /&gt;
 $CONF[&#039;maxquota&#039;] = &#039;10&#039;;&lt;br /&gt;
 $CONF[&#039;vacation&#039;] = &#039;NO&#039;; &lt;br /&gt;
 $CONF[&#039;vacation_control&#039;] =&#039;NO&#039;;&lt;br /&gt;
 $CONF[&#039;vacation_control_admin&#039;] = &#039;NO&#039;;&lt;br /&gt;
 $CONF[&#039;create_mailbox_subdirs_prefix&#039;]=&amp;quot;&amp;quot;;  &lt;br /&gt;
 $CONF[&#039;quota&#039;] = &#039;YES&#039;;&lt;br /&gt;
 $CONF[&#039;quota_multiplier&#039;] = &#039;1024000&#039;;&lt;br /&gt;
 $CONF[&#039;used_quotas&#039;] = &#039;YES&#039;;   &lt;br /&gt;
 $CONF[&#039;new_quota_table&#039;] = &#039;YES&#039;;  &lt;br /&gt;
 $CONF[&#039;alias_control&#039;] = &#039;YES&#039;;&lt;br /&gt;
 $CONF[&#039;alias_control_admin&#039;] = &#039;YES&#039;;&lt;br /&gt;
 $CONF[&#039;special_alias_control&#039;] = &#039;YES&#039;;&lt;br /&gt;
 $CONF[&#039;fetchmail&#039;] = &#039;NO&#039;;&lt;br /&gt;
 $CONF[&#039;user_footer_link&#039;] = &amp;quot;http://POSTFIXADMIN_DOMAIN&amp;quot;;&lt;br /&gt;
 $CONF[&#039;footer_link&#039;] = &#039;http://POSTFIXADMIN_DOMAIN/main.php&#039;;&lt;br /&gt;
&lt;br /&gt;
You should further edit /var/www/domains/POSTFIXADMIN_DOMAIN/www/config.inc.php and replace all instances of &amp;quot;change-this-to-your.domain.tld&amp;quot; with your actual mail domain.&lt;br /&gt;
&lt;br /&gt;
Go to http://POSTFIXADMIN_DOMAIN/setup.php&lt;br /&gt;
&lt;br /&gt;
Create the password hash, add it to the config.inc.php file&lt;br /&gt;
&lt;br /&gt;
Go back to http://POSTFIXADMIN_DOMAIN/setup.php&lt;br /&gt;
&lt;br /&gt;
Create superadmin account.&lt;br /&gt;
&lt;br /&gt;
== Install Postfix ==&lt;br /&gt;
&lt;br /&gt;
Create a user for the virtual mail delivery, and get its uid/gid (you&#039;ll need the numeric uid/gid for postfix)&lt;br /&gt;
&lt;br /&gt;
 adduser vmail -H -D -s /bin/false&lt;br /&gt;
 grep vmail /etc/passwd&lt;br /&gt;
&lt;br /&gt;
(In examples below, we use 1006/1006 for the uid/gid)&lt;br /&gt;
&lt;br /&gt;
Create the mail directory, and assign vmail as the owner&lt;br /&gt;
 mkdir -p /var/mail/domains&lt;br /&gt;
 chown -R vmail:vmail /var/mail/domains&lt;br /&gt;
 &lt;br /&gt;
&lt;br /&gt;
Install postfix&lt;br /&gt;
&lt;br /&gt;
 apk add acf-postfix postfix-pgsql&lt;br /&gt;
&lt;br /&gt;
Edit the /etc/postfix/main.cf file  Here&#039;s an example:&lt;br /&gt;
&lt;br /&gt;
 myhostname=host.example.com&lt;br /&gt;
 mydomain=example.com&lt;br /&gt;
 &lt;br /&gt;
 mydestination = localhost.$mydomains, localhost&lt;br /&gt;
 mynetworks_style = subnet&lt;br /&gt;
 mynetworks = 127.0.0.0/8&lt;br /&gt;
 &lt;br /&gt;
 virtual_mailbox_domains = proxy:pgsql:/etc/postfix/sql/pgsql_virtual_domains_maps.cf&lt;br /&gt;
 virtual_alias_maps = proxy:pgsql:/etc/postfix/sql/pgsql_virtual_alias_maps.cf,&lt;br /&gt;
        proxy:pgsql:/etc/postfix/sql/pgsql_virtual_alias_domain_maps.cf,&lt;br /&gt;
        proxy:pgsql:/etc/postfix/sql/pgsql_virtual_alias_domain_catchall_maps.cf&lt;br /&gt;
 &lt;br /&gt;
 virtual_mailbox_maps = proxy:pgsql:/etc/postfix/sql/pgsql_virtual_mailbox_maps.cf,&lt;br /&gt;
        proxy:pgsql:/etc/postfix/sql/pgsql_virtual_alias_domain_mailbox_maps.cf&lt;br /&gt;
 &lt;br /&gt;
 virtual_mailbox_base = /var/mail/domains/&lt;br /&gt;
 virtual_gid_maps = static:1006&lt;br /&gt;
 virtual_uid_maps = static:1006&lt;br /&gt;
 virtual_minimum_uid = 100&lt;br /&gt;
 virtual_transport = virtual&lt;br /&gt;
 &lt;br /&gt;
 &lt;br /&gt;
 # This next command means you must create a virtual&lt;br /&gt;
 # domain for the host itself - ALL mail goes through&lt;br /&gt;
 # The virtual transport&lt;br /&gt;
 &lt;br /&gt;
 mailbox_transport = virtual&lt;br /&gt;
 local_transport = virtual&lt;br /&gt;
 local_transport_maps = $virtual_mailbox_maps&lt;br /&gt;
 &lt;br /&gt;
 smtpd_helo_required = yes&lt;br /&gt;
 disable_vrfy_command = yes&lt;br /&gt;
 message_size_limit = 10240000&lt;br /&gt;
 queue_minfree = 51200000&lt;br /&gt;
 &lt;br /&gt;
 smtpd_sender_restrictions =&lt;br /&gt;
        permit_mynetworks,&lt;br /&gt;
        reject_non_fqdn_sender,&lt;br /&gt;
        reject_unknown_sender_domain&lt;br /&gt;
 &lt;br /&gt;
 smtpd_recipient_restrictions =&lt;br /&gt;
        reject_non_fqdn_recipient,&lt;br /&gt;
        reject_unknown_recipient_domain,&lt;br /&gt;
        permit_mynetworks,&lt;br /&gt;
        permit_sasl_authenticated,&lt;br /&gt;
        reject_unauth_destination,&lt;br /&gt;
        reject_rbl_client dnsbl.sorbs.net,&lt;br /&gt;
        reject_rbl_client zen.spamhaus.org,&lt;br /&gt;
        reject_rbl_client bl.spamcop.net&lt;br /&gt;
 &lt;br /&gt;
 smtpd_data_restrictions = reject_unauth_pipelining&lt;br /&gt;
 &lt;br /&gt;
 # we will use this later - This prevents cleartext authentication&lt;br /&gt;
 # for relaying&lt;br /&gt;
 smtpd_tls_auth_only = yes&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Now we need to create a *bunch* of files so that postfix can get the delivery information out of sql. Here&#039;s a shell script to create the scripts.  Change PGPW to the password for the postfix user of the postfix SQL database.&lt;br /&gt;
&lt;br /&gt;
 cd /etc/postfix&lt;br /&gt;
 mkdir sql&lt;br /&gt;
 PGPW=&amp;quot;ChangeMe&amp;quot;&lt;br /&gt;
 &lt;br /&gt;
 cat - &amp;lt;&amp;lt;EOF &amp;gt;sql/pgsql_virtual_alias_domain_catchall_maps.cf&lt;br /&gt;
 user=postfix&lt;br /&gt;
 password = $PGPW&lt;br /&gt;
 hosts = localhost&lt;br /&gt;
 dbname = postfix&lt;br /&gt;
 query = Select goto From alias,alias_domain where alias_domain.alias_domain = &#039;%d&#039; and alias.address = &#039;@&#039; ||  alias_domain.target_domain and alias.active = true and alias_domain.active= true &lt;br /&gt;
 EOF&lt;br /&gt;
 &lt;br /&gt;
 cat - &amp;lt;&amp;lt;EOF &amp;gt;sql/pgsql_virtual_alias_domain_mailbox_maps.cf&lt;br /&gt;
 user=postfix&lt;br /&gt;
 password = $PGPW&lt;br /&gt;
 hosts = localhost&lt;br /&gt;
 dbname = postfix&lt;br /&gt;
 query = Select maildir from mailbox,alias_domain where alias_domain.alias_domain = &#039;%d&#039; and mailbox.username = &#039;%u&#039; || &#039;@&#039; || alias_domain.target_domain and mailbox.active = true and alias_domain.active&lt;br /&gt;
 EOF&lt;br /&gt;
 &lt;br /&gt;
 cat - &amp;lt;&amp;lt;EOF &amp;gt;sql/pgsql_virtual_alias_domain_maps.cf&lt;br /&gt;
 user=postfix&lt;br /&gt;
 password = $PGPW&lt;br /&gt;
 hosts = localhost&lt;br /&gt;
 dbname = postfix&lt;br /&gt;
 query = select goto from alias,alias_domain where alias_domain.alias_domain=&#039;%d&#039; and alias.address = &#039;%u&#039; || &#039;@&#039; || alias_domain.target_domain and alias.active= true and alias_domain.active= true&lt;br /&gt;
 EOF&lt;br /&gt;
 &lt;br /&gt;
 cat - &amp;lt;&amp;lt;EOF &amp;gt;sql/pgsql_virtual_alias_maps.cf&lt;br /&gt;
 user=postfix&lt;br /&gt;
 password = $PGPW&lt;br /&gt;
 hosts = localhost&lt;br /&gt;
 dbname = postfix&lt;br /&gt;
 query = Select goto From alias Where address=&#039;%s&#039; and active =&#039;1&#039;&lt;br /&gt;
 EOF&lt;br /&gt;
 &lt;br /&gt;
 cat - &amp;lt;&amp;lt;EOF &amp;gt;sql/pgsql_virtual_domains_maps.cf&lt;br /&gt;
 user=postfix&lt;br /&gt;
 password = $PGPW&lt;br /&gt;
 hosts = localhost&lt;br /&gt;
 dbname = postfix&lt;br /&gt;
 query = Select domain from domain where domain=&#039;%s&#039; and active=&#039;1&#039;&lt;br /&gt;
 EOF&lt;br /&gt;
 &lt;br /&gt;
 cat - &amp;lt;&amp;lt;EOF &amp;gt;sql/pgsql_virtual_mailbox_maps.cf&lt;br /&gt;
 user=postfix&lt;br /&gt;
 password = $PGPW&lt;br /&gt;
 hosts = localhost&lt;br /&gt;
 dbname = postfix&lt;br /&gt;
 query = Select maildir from mailbox where username=&#039;%s&#039; and active=true&lt;br /&gt;
 EOF&lt;br /&gt;
 &lt;br /&gt;
 chown -R postfix:postfix sql&lt;br /&gt;
 chmod 640 sql/*&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
At this point you should be able to start up postfix&lt;br /&gt;
 &lt;br /&gt;
 newaliases  # so postfix is happy...&lt;br /&gt;
 /etc/init.d/postfix start&lt;br /&gt;
 rc-update add postfix&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Create a domain in PostfixAdmin and test ===&lt;br /&gt;
&lt;br /&gt;
Go to http://POSTFIXADMIN_DOMAIN/&lt;br /&gt;
&lt;br /&gt;
Log in using the superadmin account, create a domain for the local box (e.g. example.com), and create a user mailbox (e.g. root).&lt;br /&gt;
&lt;br /&gt;
From the machine, send a test message:&lt;br /&gt;
&lt;br /&gt;
 sendmail -t root@example.com&lt;br /&gt;
 subject: test&lt;br /&gt;
 .&lt;br /&gt;
 ^d&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
In /var/log/mail.log (or /var/log/messages, if you still have busybox syslogd running) you should see the message queued.  The message should be in /var/mail/domains/example.com/root/new&lt;br /&gt;
&lt;br /&gt;
== Install Dovecot ==&lt;br /&gt;
&lt;br /&gt;
Dovecot is the POP3/IMAP server to retrieve mail.&lt;br /&gt;
&lt;br /&gt;
As before, we install dovecot: &lt;br /&gt;
&lt;br /&gt;
 apk add acf-dovecot dovecot-pgsql&lt;br /&gt;
&lt;br /&gt;
edit /etc/dovecot/dovecot.conf&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 # Select only the protocols you wish to support - all are listed in the next line&lt;br /&gt;
 protocols               =       imap imaps pop pop3s&lt;br /&gt;
 log_path                =       /var/log/dovecot.log&lt;br /&gt;
 info_log_path           =       /var/log/dovecot-info.log&lt;br /&gt;
 disable_plaintext_auth  =       no&lt;br /&gt;
&lt;br /&gt;
 # Authenticated IMAP&lt;br /&gt;
 ssl                     =       yes&lt;br /&gt;
 ssl_cert_file           =       /etc/lighttpd/server-bundle.pem&lt;br /&gt;
 ssl_key_file            =       /etc/lighttpd/server-bundle.pem&lt;br /&gt;
 auth_verbose            =       yes&lt;br /&gt;
 auth_debug              =       no&lt;br /&gt;
 mail_location           =       maildir:/var/mail/domains/%d/%n&lt;br /&gt;
 auth default    {&lt;br /&gt;
        mechanisms = plain&lt;br /&gt;
        passdb sql {&lt;br /&gt;
                args = /etc/dovecot/dovecot-sql.conf&lt;br /&gt;
                }&lt;br /&gt;
        userdb static {&lt;br /&gt;
                args =  uid=1006 gid=1006 home=/var/mail/domains/%d/%n&lt;br /&gt;
                }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
We need a certificate for SSL/TLS authentication, so in the example above, we use the lighttpd cert. That way when the cert is renewed/replaced, Dovecot will have access to the new cert as well.  &lt;br /&gt;
&lt;br /&gt;
Create the /etc/dovecot/dovecot-sql.conf file:&lt;br /&gt;
&lt;br /&gt;
 driver = pgsql&lt;br /&gt;
 connect = host=localhost dbname=postfix user=postfix password=********&lt;br /&gt;
 password_query = select username,password from mailbox where local_part = &#039;%n&#039; and domain = &#039;%d&#039;&lt;br /&gt;
 default_pass_scheme =  MD5-CRYPT&lt;br /&gt;
&lt;br /&gt;
Again, change the password above to your postfix user password, and protect the file from prying eyes:&lt;br /&gt;
&lt;br /&gt;
 chown root:root /etc/dovecot/dovecot-sql.conf&lt;br /&gt;
 chmod 600 /etc/dovecot/dovecot-sql.conf&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Start dovecot&lt;br /&gt;
 /etc/init.d/dovecot start&lt;br /&gt;
 rc-update add dovecot&lt;br /&gt;
&lt;br /&gt;
== Testing ==&lt;br /&gt;
&lt;br /&gt;
Make sure your firewall allows in ports 25(SMTP) 110 (POP3), 995 (POP3S), 143(IMAP), 993(IMAPS), or whatever subset you support.  &lt;br /&gt;
 &lt;br /&gt;
At this point, you should be able to:&lt;br /&gt;
 * Create a new domain and add users with PostfixAdmin&lt;br /&gt;
 * Send mail to those users via SMTP to port 25&lt;br /&gt;
 * Retrieve mail using the user&#039;s full email and password (e.g. username: user@example.com  password: ChangeM&lt;br /&gt;
&lt;br /&gt;
== Value Add Features ==&lt;br /&gt;
&lt;br /&gt;
If you followed the guide above, you now have a functional mail server with many interconnected parts.  The features below assume that the server is already running as described above.  You should be able to add any or all of these features below to further enhance the mail service.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Virus Scanning ===&lt;br /&gt;
&lt;br /&gt;
This procedure uses clamav and the postfix content_filter mechanism to scan inbound and outbound email for viruses.  Infected emails are dropped.  Clean emails are tagged with a &amp;quot;scanned by clamav&amp;quot; header.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* Install clamav and clamsmtp:&lt;br /&gt;
 apk add acf-clamav clamsmtp&lt;br /&gt;
* Edit the /etc/clamav/clamd.conf file if desired (not necessary in most cases)&lt;br /&gt;
* Edit /etc/clamsmtpd.conf and verify the following lines&lt;br /&gt;
 OutAddress: 10026&lt;br /&gt;
 Listen: 127.0.0.1:10025                                               &lt;br /&gt;
 Header: X-Virus-Scanned: ClamAV using ClamSMTP&lt;br /&gt;
 Action: drop&lt;br /&gt;
 User: clamav                                                      &lt;br /&gt;
* Start the daemons&lt;br /&gt;
 rc-update add clamd&lt;br /&gt;
 rc-update add freshclam&lt;br /&gt;
 rc-update add clamsmtp&lt;br /&gt;
 /etc/init.d/clamd start&lt;br /&gt;
 /etc/init.d/freshclam start&lt;br /&gt;
 /etc/init.d/clamsmtp start&lt;br /&gt;
* Verify clamsmtp is listening on port 10025:&lt;br /&gt;
 netstat -anp | grep clamsmtp&lt;br /&gt;
* [http://memberwebs.com/stef/software/clamsmtp/postfix.html Following the clamsmtp instructions]&lt;br /&gt;
** edit /etc/postfix/main.cf and add:&lt;br /&gt;
 content_filter = scan:[127.0.0.1]:10025                                                      &lt;br /&gt;
** edit /etc/postfix/master.cf and add&lt;br /&gt;
 # AV scan filter (used by content_filter)&lt;br /&gt;
 scan      unix  -       -       n       -       16      smtp&lt;br /&gt;
         -o smtp_send_xforward_command=yes&lt;br /&gt;
         -o smtp_enforce_tls=no&lt;br /&gt;
 # For injecting mail back into postfix from the filter&lt;br /&gt;
 127.0.0.1:10026 inet  n -       n       -       16      smtpd&lt;br /&gt;
         -o content_filter=&lt;br /&gt;
         -o receive_override_options=no_unknown_recipient_checks,no_header_body_checks&lt;br /&gt;
         -o smtpd_helo_restrictions=&lt;br /&gt;
         -o smtpd_client_restrictions=&lt;br /&gt;
         -o smtpd_sender_restrictions=&lt;br /&gt;
         -o smtpd_recipient_restrictions=permit_mynetworks,reject&lt;br /&gt;
         -o mynetworks_style=host&lt;br /&gt;
         -o smtpd_authorized_xforward_hosts=127.0.0.0/8&lt;br /&gt;
* postfix reload&lt;br /&gt;
* Send and email into a local virtual domain - it should have the &#039;&#039;X-Virus-Scanned: ClamAV using ClamSMTP&#039;&#039; header.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Relay for Authenticated Users ===&lt;br /&gt;
&lt;br /&gt;
As configured above, the mail server accepts email from the Internet, but it does not relay email.  If it is a perimeter exchanger for a protected network, then you can add the protected networks to the &#039;&#039;mynetworks&#039;&#039; configuration line in /etc/postfix/main.cf&lt;br /&gt;
&lt;br /&gt;
This configuration change allows &#039;&#039;remote&#039;&#039; users to authenticate against the mail server and relay through it.  The rules for relaying are:&lt;br /&gt;
* Only authenticated users can relay&lt;br /&gt;
* Authentication Credentials must be encrypted with TLS or SSL&lt;br /&gt;
* Allow Submission and SMTPS ports for relaying (many consumer networks block port 25 - SMTP by default)&lt;br /&gt;
The process uses the dovecot authentication mechanism (used with IMAPS) to authenticate users before they are allowed to relay through postfix.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* Edit /etc/dovecot/dovecot.conf and add:&lt;br /&gt;
 # this is for postfix SASL (authenticated users can relay through us)&lt;br /&gt;
 socket listen {&lt;br /&gt;
                client {&lt;br /&gt;
                        path    = /var/spool/postfix/private/dovecot-auth.sock&lt;br /&gt;
                        mode    = 0660&lt;br /&gt;
                        user    = postfix&lt;br /&gt;
                        group   = postfix&lt;br /&gt;
                        }&lt;br /&gt;
                }&lt;br /&gt;
        }&lt;br /&gt;
* Restart dovecot&lt;br /&gt;
 /etc/init.d/dovecot restart&lt;br /&gt;
* Edit /etc/postfix/main.cf and add:&lt;br /&gt;
 # TLS Stuff -- since we allow SASL with tls *only*, we have to set up TLS first                    &lt;br /&gt;
 &lt;br /&gt;
 smtpd_tls_cert_file = /etc/lighttpd/server-bundle.pem&lt;br /&gt;
 smtpd_tls_key_file = /etc/lighttpd/server-bundle.pem&lt;br /&gt;
 smtpd_tls_CAfile = /etc/lighttpd/ca-crt.pem&lt;br /&gt;
 # If tls_security_level is set to &amp;quot;encrypt&amp;quot;, then SMTP rejects &lt;br /&gt;
 # unencrypted email (e.g. normal mail) which is bad.&lt;br /&gt;
 # By setting it to &amp;quot;may&amp;quot; you get TLS encrypted mail from google, slashdot, and other &lt;br /&gt;
 # interesting places.  Check your logs to see who&lt;br /&gt;
 smtpd_tls_security_level = may&lt;br /&gt;
 # Log info about the negotiated encryption levels&lt;br /&gt;
 smtpd_tls_received_header = yes&lt;br /&gt;
 smtpd_tls_loglevel = 1&lt;br /&gt;
 &lt;br /&gt;
 # SASL - this allows senders to authenticiate themselves&lt;br /&gt;
 # This along with &amp;quot;permit_sasl_authenticated&amp;quot; in smtpd_recipient_restrictions allows relaying&lt;br /&gt;
 smtpd_sasl_type = dovecot&lt;br /&gt;
 smtpd_sasl_path = private/dovecot-auth.sock&lt;br /&gt;
 smtpd_sasl_auth_enable = yes&lt;br /&gt;
 smtpd_sasl_authenticated_header = yes&lt;br /&gt;
 smtpd_tls_auth_only = yes&lt;br /&gt;
* Edit /etc/postfix/master.cf and enable the submission and smtps transports.  They are probably already at the top of your  master.cf file, just commented out:&lt;br /&gt;
 submission inet n       -       n       -       -       smtpd&lt;br /&gt;
   -o smtpd_tls_security_level=encrypt&lt;br /&gt;
   -o smtpd_sasl_auth_enable=yes&lt;br /&gt;
   -o smtpd_client_restrictions=permit_sasl_authenticated,reject&lt;br /&gt;
   -o milter_macro_daemon_name=ORIGINATING&lt;br /&gt;
 smtps     inet  n       -       n       -       -       smtpd&lt;br /&gt;
   -o smtpd_tls_security_level=encrypt&lt;br /&gt;
   -o smtpd_tls_wrappermode=yes&lt;br /&gt;
   -o smtpd_sasl_auth_enable=yes&lt;br /&gt;
   -o smtpd_client_restrictions=permit_sasl_authenticated,reject&lt;br /&gt;
   -o milter_macro_daemon_name=ORIGINATING&lt;br /&gt;
*Verfiy submission and smtps are defined in /etc/services&lt;br /&gt;
 grep &amp;quot;submission\|ssmtp&amp;quot; /etc/services&lt;br /&gt;
 submission	587/tcp				# mail message submission&lt;br /&gt;
 submission	587/udp&lt;br /&gt;
 smtps		465/tcp		ssmtp		# smtp protocol over TLS/SSL&lt;br /&gt;
 smtps		465/udp		ssmtp&lt;br /&gt;
* Restart postfix&lt;br /&gt;
 postfix reload&lt;br /&gt;
&lt;br /&gt;
At this point, you should be able to set up a mail client to relay through the server with TLS (port 587) or SSL (port 465)  Note that &amp;quot;plain&amp;quot; authentication is used because the underlying link is encrypted.  For example, in Thunderbird leave &amp;quot;secure authentication&amp;quot; unchecked, and choose STARTTLS (or TLS) for the connection security.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Mailbox Quotas ===&lt;br /&gt;
&lt;br /&gt;
In the default configuration, PostfixAdmin knows about quotas, but they are not enforced.   Documentation on the web mentions the [http://vda.sourceforge.net vda patch to postifx] to enforce quotas.  The only bad thing... its a &#039;&#039;patch&#039;&#039;.   Postfix and Dovecot are both conservative systems, so if the patch isn&#039;t in the upstream source, we&#039;ll assume there&#039;s a good reason.   There is a way of using quotas without patches - and it involves using the dovecot&#039;s [http://wiki.dovecot.org/LDA deliver] lda for local delivery.&lt;br /&gt;
&lt;br /&gt;
Note: As of Jan 2010, the documention is confusing, with multiple versions of dovecot, PostfixAdmin, and Mysql referenced.  These instructions apply to:&lt;br /&gt;
* Postgresql 8.4.2 &lt;br /&gt;
* PostfixAdmin 2.3 &lt;br /&gt;
* Dovecot 1.2.10&lt;br /&gt;
* Postfix 2.6.5&lt;br /&gt;
&lt;br /&gt;
Presumably later versions will work the same, but if not, please update the documentation and versions above.&lt;br /&gt;
&lt;br /&gt;
* Update /etc/dovecot.conf (old lines shown commented out):&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
# old postfix &lt;br /&gt;
#       userdb static {&lt;br /&gt;
#               args =  uid=1006 gid=1006 home=/var/mail/domains/%d/%n&lt;br /&gt;
#               }&lt;br /&gt;
&lt;br /&gt;
# new quota support:&lt;br /&gt;
        userdb prefetch {&lt;br /&gt;
                }&lt;br /&gt;
&lt;br /&gt;
        userdb sql {&lt;br /&gt;
                args = /etc/dovecot/dovecot-sql.conf&lt;br /&gt;
                }&lt;br /&gt;
&lt;br /&gt;
        socket listen {&lt;br /&gt;
                client {&lt;br /&gt;
                        path    = /var/spool/postfix/private/dovecot-auth.sock&lt;br /&gt;
                        mode    = 0660&lt;br /&gt;
                        user    = postfix&lt;br /&gt;
                        group   = postfix&lt;br /&gt;
                        }&lt;br /&gt;
                # These lines below are for the deliver lda&lt;br /&gt;
                master {&lt;br /&gt;
                        path =  /var/run/dovecot/auth-master&lt;br /&gt;
                        mode    = 0660&lt;br /&gt;
                        user    = vmail&lt;br /&gt;
                        group   = vmail&lt;br /&gt;
                        }&lt;br /&gt;
                }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
protocol imap {                                                               &lt;br /&gt;
         mail_plugins = quota imap_quota                                       &lt;br /&gt;
         }                                                                     &lt;br /&gt;
                                                                              &lt;br /&gt;
protocol pop3 {                                                               &lt;br /&gt;
         mail_plugins = quota                                                  &lt;br /&gt;
         }                                                                     &lt;br /&gt;
                                                                              &lt;br /&gt;
dict {                                                                        &lt;br /&gt;
        quotadict = pgsql:/etc/dovecot/dovecot-dict-quota.conf                &lt;br /&gt;
        }                                                                     &lt;br /&gt;
                                                                              &lt;br /&gt;
plugin {                                                                      &lt;br /&gt;
         quota = dict:user::proxy::quotadict                                   &lt;br /&gt;
         }                                                     &lt;br /&gt;
                                                              &lt;br /&gt;
protocol lda {                                                &lt;br /&gt;
   postmaster_address = postmaster@host.example.com&lt;br /&gt;
   mail_plugins = quota                                        &lt;br /&gt;
   auth_socket_path =  /var/run/dovecot/auth-master&lt;br /&gt;
   sendmail_path = /usr/sbin/sendmail&lt;br /&gt;
}                                                                            &lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
 &lt;br /&gt;
You should already have a &amp;lt;tt&amp;gt;socket-&amp;gt; listen-&amp;gt; client&amp;lt;/tt&amp;gt; section, but it is listed above to show where it goes in relationship to the &amp;lt;tt&amp;gt;socket -&amp;gt; listen -&amp;gt; master&amp;lt;/tt&amp;gt; section&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* edit &amp;lt;tt&amp;gt;/etc/dovecot/dovecot-sql.conf&amp;lt;/tt&amp;gt; and replace the user and password queries with the following (you may not have a user_query yet - add it):&lt;br /&gt;
&lt;br /&gt;
 password_query = select username as user, password, 1006 as userdb_uid, 1006 as userdb_gid, &#039;*:bytes=&#039; || quota as userdb_quota_rule from mailbox  where local_part = &#039;%n&#039; and domain = &#039;%d&#039;&lt;br /&gt;
 user_query = select maildir as home, 1006 as uid, 1006 as gid, &#039;*:bytes=&#039; || quota  as quota_rule from mailbox where local_part = &#039;%n&#039; and domain =&#039;%d&#039;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* create &amp;lt;tt&amp;gt;/etc/dovecot/dovecot-dict-quota.conf&amp;lt;/tt&amp;gt;&lt;br /&gt;
 connect = host=localhost dbname=postfix user=postfix password=********&lt;br /&gt;
 &lt;br /&gt;
 map {&lt;br /&gt;
         pattern = priv/quota/storage&lt;br /&gt;
         table = quota2&lt;br /&gt;
         username_field =username&lt;br /&gt;
         value_field = bytes&lt;br /&gt;
 }&lt;br /&gt;
 &lt;br /&gt;
 map {&lt;br /&gt;
        pattern= priv/quota/messages&lt;br /&gt;
        table = quota2&lt;br /&gt;
        username_field = username&lt;br /&gt;
        value_field = messages&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
Side note: [http://wiki.dovecot.org/Quota/Dict The Dovecot Quota Documentation] mentions the need for a trigger with pgsql.  This was created in the PostfixAdmin install, which is why you instantiated the pgsql language when creating the database.  If not, you will need to create the trigger, to reference the quota2 table, not the quota table mentioned in the dovecot docs.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* create a new transport for the dovecot lda.   Add the following to  /etc/postfix/master.cf:&lt;br /&gt;
 # The dovecot deliver lda&lt;br /&gt;
 dovecot   unix  -       n       n       -       -       pipe&lt;br /&gt;
   flags=DRhu user=vmail:vmail argv=/usr/libexec/dovecot/deliver -f ${sender} -d ${user}@${nexthop}&lt;br /&gt;
&lt;br /&gt;
* Edit the /etc/postfix/main.cf.  Replace &lt;br /&gt;
 virtual_transport = virtual &lt;br /&gt;
with&lt;br /&gt;
 virtual_transport = dovecot&lt;br /&gt;
 dovecot_destination_recipient_limit = 1&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;TODO&#039;&#039;&#039;  This will cause over-quota emails to bounce.   Which could be a source of backscatter.   We need a way of checking quota limits after RBL checking but before the message is accepted in the queue.&lt;br /&gt;
&lt;br /&gt;
=== WebMail (RoundCube) ===&lt;br /&gt;
&lt;br /&gt;
[http://roundcube.net/ RoundCube] is an &amp;quot;ajax /Web2.0&amp;quot; web-mail client.  These instructions are for the Alpine Linux 1.10 repository &lt;br /&gt;
&lt;br /&gt;
* Add the package and related php modules:&lt;br /&gt;
 apk add roundcubemail php-xml php-openssl php-mcrypt php-gd php-iconv&lt;br /&gt;
&lt;br /&gt;
* link the roundcube application back into the docroot&lt;br /&gt;
 ln -s /usr/share/webapps/roundcube /var/www/domains/host.example.com/www/roundcube&lt;br /&gt;
&lt;br /&gt;
* follow the instructions in /usr/share/webapps/roundcube/INSTALL:&lt;br /&gt;
 chown -R lighttpd:lighttpd temp logs&lt;br /&gt;
 &lt;br /&gt;
 su postgres&lt;br /&gt;
 createuser roundcube&lt;br /&gt;
   Shall the new role be a superuser? (y/n) n&lt;br /&gt;
   Shall the new role be allowed to create databases? (y/n) n&lt;br /&gt;
   Shall the new role be allowed to create more new roles? (y/n) y&lt;br /&gt;
 createdb -O roundcube -E UNICODE -T template0 roundcubemail&lt;br /&gt;
 psql roundcubemail&lt;br /&gt;
   roundcubemail=# ALTER USER roundcube WITH PASSWORD &#039;the_new_password&#039;;&lt;br /&gt;
   roundcubemail=# \c - roundcube&lt;br /&gt;
   \i /usr/share/webapps/roundcube/SQL/postgres.initial.sql&lt;br /&gt;
   \q&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* restart lighttpd to verify the new php libraries are used&lt;br /&gt;
 /etc/init.d/lighttpd restart&lt;br /&gt;
&lt;br /&gt;
* Point your browser to http://host.example.com/roundcube/installer&lt;br /&gt;
** Begin installation&lt;br /&gt;
** Follow the instructions in step 3 of the install to copy the files to the server&lt;br /&gt;
* edit /etc/php/php.ini and edit date.timezone to your local timezone, or to UTC&lt;br /&gt;
* if necessary (e.g. you had to reset the local timezone) restart lighttpd to reload php&lt;br /&gt;
 /etc/init.d/lighttpd restart&lt;br /&gt;
* You should now be able to get to roundcube at http://host.example.com/roundcube&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
For the specific configuration parameters in the install step:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!Property&lt;br /&gt;
!Setting&lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;enable_spellcheck&#039;&#039; ||   disabled &lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;identities_level&#039;&#039; ||  one identity with possibility to edit all params but not email address &lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;log driver&#039;&#039; || syslog &lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;sylog_id&#039;&#039; || roundcube &lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;syslog_facility&#039;&#039; || mailsubsystem &lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;db_dnsw&#039;&#039; || pgsql properties, as described above &lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;imap_host&#039;&#039; || 127.0.0.1 &lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;auto_create_user&#039;&#039; || enabled &lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;smtp_server&#039;&#039; ||  127.0.0.1&lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;smtp_port&#039;&#039; ||  25&lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;smtp_user/smtp_pass&#039;&#039; ||  enable &#039;&#039;Use Current IMAP username and password for SMTP authentication&#039;&#039;&lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;smtp_log&#039;&#039; ||  enable (optional, but gives additional log record)&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
The other items can be left at default settings, or adjusted if desired.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
After its working, the INSTALL file recommends removing the install directory.   If you want to keep the installer around later, you can simply change the ownership and permissions.  So do &#039;&#039;&#039;one&#039;&#039;&#039; of the following:&lt;br /&gt;
 cd /usr/share/webapps/roundcube&lt;br /&gt;
 rm -rf LICENSE UPGRADING INSTALL README CHANGELOG  SQL installer&lt;br /&gt;
or&lt;br /&gt;
 cd /usr/share/webapps/roundcube&lt;br /&gt;
 chown -R root:root LICENSE UPGRADING INSTALL README CHANGELOG  SQL installer&lt;br /&gt;
 chmod -R 600 LICENSE UPGRADING INSTALL README CHANGELOG SQL &lt;br /&gt;
 chmod 700 SQL installer&lt;br /&gt;
&lt;br /&gt;
== log rotation ==&lt;br /&gt;
&lt;br /&gt;
Ensure the busybox cron service is started and is configured to auto-start:&lt;br /&gt;
&lt;br /&gt;
 /etc/init.d/cron start&lt;br /&gt;
 rc-update add cron default&lt;br /&gt;
&lt;br /&gt;
Add log rotate:&lt;br /&gt;
&lt;br /&gt;
 apk add logrotate&lt;br /&gt;
&lt;br /&gt;
Edit &#039;&#039;/etc/logrotate.conf&#039;&#039; as desired, but the defaults should be sufficient for most people.&lt;br /&gt;
&lt;br /&gt;
----&lt;/div&gt;</summary>
		<author><name>Djhughes</name></author>
	</entry>
	<entry>
		<id>https://wiki.alpinelinux.org/w/index.php?title=ISP_Mail_Server_HowTo&amp;diff=3351</id>
		<title>ISP Mail Server HowTo</title>
		<link rel="alternate" type="text/html" href="https://wiki.alpinelinux.org/w/index.php?title=ISP_Mail_Server_HowTo&amp;diff=3351"/>
		<updated>2010-02-16T14:16:17Z</updated>

		<summary type="html">&lt;p&gt;Djhughes: added missing &amp;quot;}&amp;quot;&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== A Full Service Mail Server ==&lt;br /&gt;
&lt;br /&gt;
The goal of this document is to describe how to set up postfix, dovecot, clamav, dspam, roundecube, and postfixadmin for a full-featured &amp;quot;ISP&amp;quot; level mail server.&lt;br /&gt;
&lt;br /&gt;
The server must provide:&lt;br /&gt;
&lt;br /&gt;
* multiple virtual domains&lt;br /&gt;
* admins for each domain (to add/remove virtual accounts)&lt;br /&gt;
* Quota support per domain / account&lt;br /&gt;
* downloading email via IMAP / IMAPS / POP3 / POP3S&lt;br /&gt;
* relaying email for authenticated users with TLS or SSL (Submission / SMTPS protocol)&lt;br /&gt;
* Standard filters (virus/spam/rbl/etc)&lt;br /&gt;
* Web mail client&lt;br /&gt;
* Value Add services&lt;br /&gt;
&lt;br /&gt;
== Configure DNS ==&lt;br /&gt;
&lt;br /&gt;
This server will host three separate virtual domains on the same web server. They will be distinguished by their DNS names, so you must choose three domains for the three separate services:&lt;br /&gt;
&lt;br /&gt;
* ACF - Alpine Configuration Framework for managing the server&lt;br /&gt;
* PostfixAdmin - for managing the postfix installation&lt;br /&gt;
* RoundCube - for accessing individual mailboxes&lt;br /&gt;
&lt;br /&gt;
Choose three different domains (from here on known as ACF_DOMAIN, POSTFIXADMIN_DOMAIN, and ROUNDCUBE_DOMAIN) and configure DNS for all three to point to the IP address of your host. These should be DNS A records.&lt;br /&gt;
&lt;br /&gt;
== Set up Lighttpd + PHP ==&lt;br /&gt;
&lt;br /&gt;
PostfixAdmin needs php pgpsql and imap modules, so we do it in this step.&lt;br /&gt;
&lt;br /&gt;
  apk add lighttpd php php-pgsql php-imap&lt;br /&gt;
&lt;br /&gt;
Stop and remove mini_httpd, and move ACF to lighttpd;  We are setting this up to be a multi-domain virtual web server (replace ACF_DOMAIN with the actual domain):&lt;br /&gt;
&lt;br /&gt;
  mkdir -p /var/www/domains/ACF_DOMAIN&lt;br /&gt;
  ln -s /usr/share/acf/www /var/www/domains/ACF_DOMAIN/www&lt;br /&gt;
&lt;br /&gt;
Edit /etc/lighttpd/mod_cgi.conf to serve haserl files by adding a &amp;quot;&amp;quot; =&amp;gt; &amp;quot;&amp;quot; cgi handler&lt;br /&gt;
&lt;br /&gt;
 $HTTP[&amp;quot;url&amp;quot;] =~ &amp;quot;^/cgi-bin/&amp;quot; {&lt;br /&gt;
     # disable directory listings&lt;br /&gt;
     dir-listing.activate = &amp;quot;disable&amp;quot;&lt;br /&gt;
     # only allow cgi&#039;s in this directory&lt;br /&gt;
     cgi.assign = (&lt;br /&gt;
 		&amp;quot;.pl&amp;quot;	=&amp;gt;	&amp;quot;/usr/bin/perl&amp;quot;,&lt;br /&gt;
 		&amp;quot;.cgi&amp;quot;	=&amp;gt;	&amp;quot;/usr/bin/perl&amp;quot;,&lt;br /&gt;
 		&amp;quot;&amp;quot; =&amp;gt; &amp;quot;&amp;quot;&lt;br /&gt;
 	)&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
Add these lines to /etc/lighttpd/lighttpd.conf to point to the new document root, and set it up to listen on port 443 (replace &#039;&#039;ROUNDCUBE_DOMAIN&#039;&#039; with the roundcube domain and &#039;&#039;ip_address_of_server&#039;&#039; with the actual IP address):&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
 simple-vhost.server-root   = &amp;quot;/var/www/domains/&amp;quot;&lt;br /&gt;
 simple-vhost.default-host  = &amp;quot;/ROUNDCUBE_DOMAIN/&amp;quot;&lt;br /&gt;
 simple-vhost.document-root = &amp;quot;www/&amp;quot;&lt;br /&gt;
&lt;br /&gt;
 $HTTP[&amp;quot;host&amp;quot;] == &amp;quot;POSTFIXADMIN_DOMAIN&amp;quot; {&lt;br /&gt;
	simple-vhost.server-root   = &amp;quot;/var/www/domains/&amp;quot;&lt;br /&gt;
	simple-vhost.default-host  = &amp;quot;/POSTFIXADMIN_DOMAIN/&amp;quot;&lt;br /&gt;
	simple-vhost.document-root = &amp;quot;www/&amp;quot;&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
 $HTTP[&amp;quot;host&amp;quot;] == &amp;quot;ACF_DOMAIN&amp;quot; {&lt;br /&gt;
	simple-vhost.server-root   = &amp;quot;/var/www/domains/&amp;quot;&lt;br /&gt;
	simple-vhost.default-host  = &amp;quot;/ACF_DOMAIN/&amp;quot;&lt;br /&gt;
	simple-vhost.document-root = &amp;quot;www/&amp;quot;&lt;br /&gt;
 } &lt;br /&gt;
 $SERVER[&amp;quot;socket&amp;quot;] == &amp;quot;ip_address_of_server:443&amp;quot; {&lt;br /&gt;
 ssl.engine    = &amp;quot;enable&amp;quot;&lt;br /&gt;
 ssl.pemfile   = &amp;quot;/etc/lighttpd/server-bundle.pem&amp;quot;&lt;br /&gt;
 ssl.ca-file   = &amp;quot;/etc/lighttpd/ca-crt.pem&amp;quot;&lt;br /&gt;
 }&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Ensure that the simple_vhosts module is loaded, as well as the cgi config scripts by uncommenting the following lines in /etc/lighttpd/lighttpd.conf&lt;br /&gt;
&lt;br /&gt;
 server.modules = (&lt;br /&gt;
     #  other modules may be listed&lt;br /&gt;
     &amp;quot;mod_simple_vhost&amp;quot;, &lt;br /&gt;
     #  other modules may be listed&lt;br /&gt;
  .&lt;br /&gt;
  .&lt;br /&gt;
  .&lt;br /&gt;
     include &amp;quot;mod_cgi.conf&amp;quot;&lt;br /&gt;
 &lt;br /&gt;
     include &amp;quot;mod_fastcgi.conf&amp;quot;&lt;br /&gt;
 &lt;br /&gt;
&lt;br /&gt;
Get a web certificate, and install it.  If you want to use a self-signed cert, you can use [[Generating SSL certs with ACF]] or [[Generating SSL certs with ACF 1.9]].  If you create a certificate with ACF, you can create the &amp;quot;server-bundle.pem&amp;quot; and the &amp;quot;ca-crt.pem&amp;quot; file with these commands:&lt;br /&gt;
&lt;br /&gt;
  openssl pkcs12 -nokeys -cacerts -in certificate.pfx  -out /etc/lighttpd/ca-crt.pem&lt;br /&gt;
  openssl pkcs12 -nodes -in certifcate.pfx -out /etc/lighttpd/server-bundle.pem&lt;br /&gt;
  chown root:root /etc/lighttpd/server-bundle.pem&lt;br /&gt;
  chmod 400 /etc/lighttpd/server-bundle.pem&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Note:&#039;&#039;&#039; The server certificate &#039;&#039;and&#039;&#039; key are in the server-bundle.pem file, so it is critical that the file be read-only by user &amp;quot;root&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
 Editme: We should probably only serve ACF to restricted hosts&lt;br /&gt;
&lt;br /&gt;
Stop and remove mini_httpd; start lighttpd, test&lt;br /&gt;
&lt;br /&gt;
  /etc/init.d/mini_httpd stop&lt;br /&gt;
  rc-update del mini_httpd&lt;br /&gt;
  apk del mini_httpd&lt;br /&gt;
  rc-update add lighttpd&lt;br /&gt;
  /etc/init.d/lighttpd start&lt;br /&gt;
&lt;br /&gt;
At this point you should be able to see ACF being served with lighttpd:  https://ACF_DOMAIN/&lt;br /&gt;
&lt;br /&gt;
== Install Postgresql ==&lt;br /&gt;
&lt;br /&gt;
Add and configure postgresql&lt;br /&gt;
&lt;br /&gt;
  apk add acf-postgresql postgresql-client&lt;br /&gt;
  /etc/init.d/postgresql setup&lt;br /&gt;
  /etc/init.d/postgresql start&lt;br /&gt;
  rc-update add postgresql&lt;br /&gt;
&lt;br /&gt;
At this point any user can connect to the sql server with &amp;quot;trust&amp;quot; mechanism.  If you want to enforce password authentication (you probably do) edit /var/lib/postgresql/8.4/data/pg_hba.conf&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
  Editme: What should we recommend?&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Create the postfix database:&lt;br /&gt;
&lt;br /&gt;
  psql -U postgres&lt;br /&gt;
   create user postfix with password &#039;******&#039;;&lt;br /&gt;
   create database postfix owner postfix;&lt;br /&gt;
   \c postfix&lt;br /&gt;
   create language plpgsql;&lt;br /&gt;
   \q&lt;br /&gt;
&lt;br /&gt;
(Of course, use your selected password where ******* is shown above.)&lt;br /&gt;
&lt;br /&gt;
== Install PostfixAdmin ==&lt;br /&gt;
&lt;br /&gt;
We are going to install the postfix admin web front-end before we install the mail server.  This just creates an interface to populate the SQL tables that postfix and dovecot will use.&lt;br /&gt;
&lt;br /&gt;
Download PostfixAdmin from Sourceforge.  When these instructions were written, 2.3 was the current release, so (replace POSTFIXADMIN_DOMAIN with the actual domain):&lt;br /&gt;
 wget http://downloads.sourceforge.net/project/postfixadmin/postfixadmin/postfixadmin_2.3.tar.gz&lt;br /&gt;
 tar zxvf postfixadmin_2.3.tar.gz&lt;br /&gt;
 mkdir -p /var/www/domains/POSTFIXADMIN_DOMAIN/www&lt;br /&gt;
 mv postfixadmin-2.3/* /var/www/domains/POSTFIXADMIN_DOMAIN/www&lt;br /&gt;
 rm -rf postfixadmin*&lt;br /&gt;
&lt;br /&gt;
Edit /var/www/domains/POSTFIXADMIN_DOMAIN/www/config.inc.php and modify at least these lines (replace POSTFIXADMIN_DOMAIN with the actual domain):&lt;br /&gt;
&lt;br /&gt;
 $CONF[&#039;configured&#039;] = true;&lt;br /&gt;
 $CONF[&#039;setup_password&#039;] = &amp;quot;&amp;quot;;  &amp;lt;&amp;lt; Don&#039;t change this yet&lt;br /&gt;
 $CONF[&#039;database_type&#039;] = &#039;pgsql&#039;;&lt;br /&gt;
 $CONF[&#039;database_host&#039;] = &#039;localhost&#039;;&lt;br /&gt;
 $CONF[&#039;database_user&#039;] = &#039;postfix&#039;;&lt;br /&gt;
 $CONF[&#039;database_password&#039;] = &#039;*****&#039;;   &amp;lt;&amp;lt; The password you chose above&lt;br /&gt;
 $CONF[&#039;database_name&#039;] = &#039;postfix&#039;;&lt;br /&gt;
 $CONF[&#039;database_prefix&#039;] = &#039;&#039;;&lt;br /&gt;
 $CONF[&#039;admin_email&#039;] = &#039;you@some.email.com&#039;;  &amp;lt;&amp;lt; Your email address &lt;br /&gt;
 $CONF[&#039;encrypt&#039;] = &#039;md5crypt&#039;;&lt;br /&gt;
 $CONF[&#039;authlib_default_flavor&#039;] = &#039;md5raw&#039;;&lt;br /&gt;
 $CONF[&#039;dovecotpw&#039;] = &amp;quot;/usr/sbin/dovecotpw&amp;quot;;&lt;br /&gt;
 $CONF[&#039;domain_path&#039;] = &#039;YES&#039;;&lt;br /&gt;
 $CONF[&#039;domain_in_mailbox&#039;] = &#039;NO&#039;;&lt;br /&gt;
 $CONF[&#039;aliases&#039;] = &#039;10&#039;;                       &lt;br /&gt;
 $CONF[&#039;mailboxes&#039;] = &#039;10&#039;;&lt;br /&gt;
 $CONF[&#039;maxquota&#039;] = &#039;10&#039;;&lt;br /&gt;
 $CONF[&#039;vacation&#039;] = &#039;NO&#039;; &lt;br /&gt;
 $CONF[&#039;vacation_control&#039;] =&#039;NO&#039;;&lt;br /&gt;
 $CONF[&#039;vacation_control_admin&#039;] = &#039;NO&#039;;&lt;br /&gt;
 $CONF[&#039;create_mailbox_subdirs_prefix&#039;]=&amp;quot;&amp;quot;;  &lt;br /&gt;
 $CONF[&#039;quota&#039;] = &#039;YES&#039;;&lt;br /&gt;
 $CONF[&#039;quota_multiplier&#039;] = &#039;1024000&#039;;&lt;br /&gt;
 $CONF[&#039;used_quotas&#039;] = &#039;YES&#039;;   &lt;br /&gt;
 $CONF[&#039;new_quota_table&#039;] = &#039;YES&#039;;  &lt;br /&gt;
 $CONF[&#039;alias_control&#039;] = &#039;YES&#039;;&lt;br /&gt;
 $CONF[&#039;alias_control_admin&#039;] = &#039;YES&#039;;&lt;br /&gt;
 $CONF[&#039;special_alias_control&#039;] = &#039;YES&#039;;&lt;br /&gt;
 $CONF[&#039;fetchmail&#039;] = &#039;NO&#039;;&lt;br /&gt;
 $CONF[&#039;user_footer_link&#039;] = &amp;quot;http://POSTFIXADMIN_DOMAIN&amp;quot;;&lt;br /&gt;
 $CONF[&#039;footer_link&#039;] = &#039;http://POSTFIXADMIN_DOMAIN/main.php&#039;;&lt;br /&gt;
&lt;br /&gt;
You should further edit /var/www/domains/POSTFIXADMIN_DOMAIN/www/config.inc.php and replace all instances of &amp;quot;change-this-to-your.domain.tld&amp;quot; with your actual mail domain.&lt;br /&gt;
&lt;br /&gt;
Go to http://POSTFIXADMIN_DOMAIN/setup.php&lt;br /&gt;
&lt;br /&gt;
Create the password hash, add it to the config.inc.php file&lt;br /&gt;
&lt;br /&gt;
Go back to http://POSTFIXADMIN_DOMAIN/setup.php&lt;br /&gt;
&lt;br /&gt;
Create superadmin account.&lt;br /&gt;
&lt;br /&gt;
== Install Postfix ==&lt;br /&gt;
&lt;br /&gt;
Create a user for the virtual mail delivery, and get its uid/gid (you&#039;ll need the numeric uid/gid for postfix)&lt;br /&gt;
&lt;br /&gt;
 adduser vmail -H -D -s /bin/false&lt;br /&gt;
 grep vmail /etc/passwd&lt;br /&gt;
&lt;br /&gt;
(In examples below, we use 1006/1006 for the uid/gid)&lt;br /&gt;
&lt;br /&gt;
Create the mail directory, and assign vmail as the owner&lt;br /&gt;
 mkdir -p /var/mail/domains&lt;br /&gt;
 chown -R vmail:vmail /var/mail/domains&lt;br /&gt;
 &lt;br /&gt;
&lt;br /&gt;
Install postfix&lt;br /&gt;
&lt;br /&gt;
 apk add acf-postfix postfix-pgsql&lt;br /&gt;
&lt;br /&gt;
Edit the /etc/postfix/main.cf file  Here&#039;s an example:&lt;br /&gt;
&lt;br /&gt;
 myhostname=host.example.com&lt;br /&gt;
 mydomain=example.com&lt;br /&gt;
 &lt;br /&gt;
 mydestination = localhost.$mydomains, localhost&lt;br /&gt;
 mynetworks_style = subnet&lt;br /&gt;
 mynetworks = 127.0.0.0/8&lt;br /&gt;
 &lt;br /&gt;
 virtual_mailbox_domains = proxy:pgsql:/etc/postfix/sql/pgsql_virtual_domains_maps.cf&lt;br /&gt;
 virtual_alias_maps = proxy:pgsql:/etc/postfix/sql/pgsql_virtual_alias_maps.cf,&lt;br /&gt;
        proxy:pgsql:/etc/postfix/sql/pgsql_virtual_alias_domain_maps.cf,&lt;br /&gt;
        proxy:pgsql:/etc/postfix/sql/pgsql_virtual_alias_domain_catchall_maps.cf&lt;br /&gt;
 &lt;br /&gt;
 virtual_mailbox_maps = proxy:pgsql:/etc/postfix/sql/pgsql_virtual_mailbox_maps.cf,&lt;br /&gt;
        proxy:pgsql:/etc/postfix/sql/pgsql_virtual_alias_domain_mailbox_maps.cf&lt;br /&gt;
 &lt;br /&gt;
 virtual_mailbox_base = /var/mail/domains/&lt;br /&gt;
 virtual_gid_maps = static:1006&lt;br /&gt;
 virtual_uid_maps = static:1006&lt;br /&gt;
 virtual_minimum_uid = 100&lt;br /&gt;
 virtual_transport = virtual&lt;br /&gt;
 &lt;br /&gt;
 &lt;br /&gt;
 # This next command means you must create a virtual&lt;br /&gt;
 # domain for the host itself - ALL mail goes through&lt;br /&gt;
 # The virtual transport&lt;br /&gt;
 &lt;br /&gt;
 mailbox_transport = virtual&lt;br /&gt;
 local_transport = virtual&lt;br /&gt;
 local_transport_maps = $virtual_mailbox_maps&lt;br /&gt;
 &lt;br /&gt;
 smtpd_helo_required = yes&lt;br /&gt;
 disable_vrfy_command = yes&lt;br /&gt;
 message_size_limit = 10240000&lt;br /&gt;
 queue_minfree = 51200000&lt;br /&gt;
 &lt;br /&gt;
 smtpd_sender_restrictions =&lt;br /&gt;
        permit_mynetworks,&lt;br /&gt;
        reject_non_fqdn_sender,&lt;br /&gt;
        reject_unknown_sender_domain&lt;br /&gt;
 &lt;br /&gt;
 smtpd_recipient_restrictions =&lt;br /&gt;
        reject_non_fqdn_recipient,&lt;br /&gt;
        reject_unknown_recipient_domain,&lt;br /&gt;
        permit_mynetworks,&lt;br /&gt;
        permit_sasl_authenticated,&lt;br /&gt;
        reject_unauth_destination,&lt;br /&gt;
        reject_rbl_client dnsbl.sorbs.net,&lt;br /&gt;
        reject_rbl_client zen.spamhaus.org,&lt;br /&gt;
        reject_rbl_client bl.spamcop.net&lt;br /&gt;
 &lt;br /&gt;
 smtpd_data_restrictions = reject_unauth_pipelining&lt;br /&gt;
 &lt;br /&gt;
 # we will use this later - This prevents cleartext authentication&lt;br /&gt;
 # for relaying&lt;br /&gt;
 smtpd_tls_auth_only = yes&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Now we need to create a *bunch* of files so that postfix can get the delivery information out of sql. Here&#039;s a shell script to create the scripts.  Change PGPW to the password for the postfix user of the postfix SQL database.&lt;br /&gt;
&lt;br /&gt;
 cd /etc/postfix&lt;br /&gt;
 mkdir sql&lt;br /&gt;
 PGPW=&amp;quot;ChangeMe&amp;quot;&lt;br /&gt;
 &lt;br /&gt;
 cat - &amp;lt;&amp;lt;EOF &amp;gt;sql/pgsql_virtual_alias_domain_catchall_maps.cf&lt;br /&gt;
 user=postfix&lt;br /&gt;
 password = $PGPW&lt;br /&gt;
 hosts = localhost&lt;br /&gt;
 dbname = postfix&lt;br /&gt;
 query = Select goto From alias,alias_domain where alias_domain.alias_domain = &#039;%d&#039; and alias.address = &#039;@&#039; ||  alias_domain.target_domain and alias.active = true and alias_domain.active= true &lt;br /&gt;
 EOF&lt;br /&gt;
 &lt;br /&gt;
 cat - &amp;lt;&amp;lt;EOF &amp;gt;sql/pgsql_virtual_alias_domain_mailbox_maps.cf&lt;br /&gt;
 user=postfix&lt;br /&gt;
 password = $PGPW&lt;br /&gt;
 hosts = localhost&lt;br /&gt;
 dbname = postfix&lt;br /&gt;
 query = Select maildir from mailbox,alias_domain where alias_domain.alias_domain = &#039;%d&#039; and mailbox.username = &#039;%u&#039; || &#039;@&#039; || alias_domain.target_domain and mailbox.active = true and alias_domain.active&lt;br /&gt;
 EOF&lt;br /&gt;
 &lt;br /&gt;
 cat - &amp;lt;&amp;lt;EOF &amp;gt;sql/pgsql_virtual_alias_domain_maps.cf&lt;br /&gt;
 user=postfix&lt;br /&gt;
 password = $PGPW&lt;br /&gt;
 hosts = localhost&lt;br /&gt;
 dbname = postfix&lt;br /&gt;
 query = select goto from alias,alias_domain where alias_domain.alias_domain=&#039;%d&#039; and alias.address = &#039;%u&#039; || &#039;@&#039; || alias_domain.target_domain and alias.active= true and alias_domain.active= true&lt;br /&gt;
 EOF&lt;br /&gt;
 &lt;br /&gt;
 cat - &amp;lt;&amp;lt;EOF &amp;gt;sql/pgsql_virtual_alias_maps.cf&lt;br /&gt;
 user=postfix&lt;br /&gt;
 password = $PGPW&lt;br /&gt;
 hosts = localhost&lt;br /&gt;
 dbname = postfix&lt;br /&gt;
 query = Select goto From alias Where address=&#039;%s&#039; and active =&#039;1&#039;&lt;br /&gt;
 EOF&lt;br /&gt;
 &lt;br /&gt;
 cat - &amp;lt;&amp;lt;EOF &amp;gt;sql/pgsql_virtual_domains_maps.cf&lt;br /&gt;
 user=postfix&lt;br /&gt;
 password = $PGPW&lt;br /&gt;
 hosts = localhost&lt;br /&gt;
 dbname = postfix&lt;br /&gt;
 query = Select domain from domain where domain=&#039;%s&#039; and active=&#039;1&#039;&lt;br /&gt;
 EOF&lt;br /&gt;
 &lt;br /&gt;
 cat - &amp;lt;&amp;lt;EOF &amp;gt;sql/pgsql_virtual_mailbox_maps.cf&lt;br /&gt;
 user=postfix&lt;br /&gt;
 password = $PGPW&lt;br /&gt;
 hosts = localhost&lt;br /&gt;
 dbname = postfix&lt;br /&gt;
 query = Select maildir from mailbox where username=&#039;%s&#039; and active=true&lt;br /&gt;
 EOF&lt;br /&gt;
 &lt;br /&gt;
 chown -R postfix:postfix sql&lt;br /&gt;
 chmod 640 sql/*&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
At this point you should be able to start up postfix&lt;br /&gt;
 &lt;br /&gt;
 newaliases  # so postfix is happy...&lt;br /&gt;
 /etc/init.d/postfix start&lt;br /&gt;
 rc-update add postfix&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Create a domain in PostfixAdmin and test ===&lt;br /&gt;
&lt;br /&gt;
Go to http://POSTFIXADMIN_DOMAIN/&lt;br /&gt;
&lt;br /&gt;
Log in using the superadmin account, create a domain for the local box (e.g. example.com), and create a user mailbox (e.g. root).&lt;br /&gt;
&lt;br /&gt;
From the machine, send a test message:&lt;br /&gt;
&lt;br /&gt;
 sendmail -t root@example.com&lt;br /&gt;
 subject: test&lt;br /&gt;
 .&lt;br /&gt;
 ^d&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
In /var/log/mail.log (or /var/log/messages, if you still have busybox syslogd running) you should see the message queued.  The message should be in /var/mail/domains/example.com/root/new&lt;br /&gt;
&lt;br /&gt;
== Install Dovecot ==&lt;br /&gt;
&lt;br /&gt;
Dovecot is the POP3/IMAP server to retrieve mail.&lt;br /&gt;
&lt;br /&gt;
As before, we install dovecot: &lt;br /&gt;
&lt;br /&gt;
 apk add acf-dovecot dovecot-pgsql&lt;br /&gt;
&lt;br /&gt;
edit /etc/dovecot/dovecot.conf&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 # Select only the protocols you wish to support - all are listed in the next line&lt;br /&gt;
 protocols               =       imap imaps pop pop3s&lt;br /&gt;
 log_path                =       /var/log/dovecot.log&lt;br /&gt;
 info_log_path           =       /var/log/dovecot-info.log&lt;br /&gt;
 disable_plaintext_auth  =       no&lt;br /&gt;
&lt;br /&gt;
 # Authenticated IMAP&lt;br /&gt;
 ssl                     =       yes&lt;br /&gt;
 ssl_cert_file           =       /etc/lighttpd/server-bundle.pem&lt;br /&gt;
 ssl_key_file            =       /etc/lighttpd/server-bundle.pem&lt;br /&gt;
 auth_verbose            =       yes&lt;br /&gt;
 auth_debug              =       no&lt;br /&gt;
 mail_location           =       maildir:/var/mail/domains/%d/%n&lt;br /&gt;
 auth default    {&lt;br /&gt;
        mechanisms = plain&lt;br /&gt;
        passdb sql {&lt;br /&gt;
                args = /etc/dovecot/dovecot-sql.conf&lt;br /&gt;
                }&lt;br /&gt;
        userdb static {&lt;br /&gt;
                args =  uid=1006 gid=1006 home=/var/mail/domains/%d/%n&lt;br /&gt;
                }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
We need a certificate for SSL/TLS authentication, so in the example above, we use the lighttpd cert. That way when the cert is renewed/replaced, Dovecot will have access to the new cert as well.  &lt;br /&gt;
&lt;br /&gt;
Create the /etc/dovecot/dovecot-sql.conf file:&lt;br /&gt;
&lt;br /&gt;
 driver = pgsql&lt;br /&gt;
 connect = host=localhost dbname=postfix user=postfix password=********&lt;br /&gt;
 password_query = select username,password from mailbox where local_part = &#039;%n&#039; and domain = &#039;%d&#039;&lt;br /&gt;
 default_pass_scheme =  MD5-CRYPT&lt;br /&gt;
&lt;br /&gt;
Again, change the password above to your postfix user password, and protect the file from prying eyes:&lt;br /&gt;
&lt;br /&gt;
 chown root:root /etc/dovecot/dovecot-sql.conf&lt;br /&gt;
 chmod 600 /etc/dovecot/dovecot-sql.conf&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Start dovecot&lt;br /&gt;
 /etc/init.d/dovecot start&lt;br /&gt;
 rc-update add dovecot&lt;br /&gt;
&lt;br /&gt;
== Testing ==&lt;br /&gt;
&lt;br /&gt;
Make sure your firewall allows in ports 25(SMTP) 110 (POP3), 995 (POP3S), 143(IMAP), 993(IMAPS), or whatever subset you support.  &lt;br /&gt;
 &lt;br /&gt;
At this point, you should be able to:&lt;br /&gt;
 * Create a new domain and add users with PostfixAdmin&lt;br /&gt;
 * Send mail to those users via SMTP to port 25&lt;br /&gt;
 * Retrieve mail using the user&#039;s full email and password (e.g. username: user@example.com  password: ChangeM&lt;br /&gt;
&lt;br /&gt;
== Value Add Features ==&lt;br /&gt;
&lt;br /&gt;
If you followed the guide above, you now have a functional mail server with many interconnected parts.  The features below assume that the server is already running as described above.  You should be able to add any or all of these features below to further enhance the mail service.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Virus Scanning ===&lt;br /&gt;
&lt;br /&gt;
This procedure uses clamav and the postfix content_filter mechanism to scan inbound and outbound email for viruses.  Infected emails are dropped.  Clean emails are tagged with a &amp;quot;scanned by clamav&amp;quot; header.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* Install clamav and clamsmtp:&lt;br /&gt;
 apk add acf-clamav clamsmtp&lt;br /&gt;
* Edit the /etc/clamav/clamd.conf file if desired (not necessary in most cases)&lt;br /&gt;
* Edit /etc/clamsmtpd.conf and verify the following lines&lt;br /&gt;
 OutAddress: 10026&lt;br /&gt;
 Listen: 127.0.0.1:10025                                               &lt;br /&gt;
 Header: X-Virus-Scanned: ClamAV using ClamSMTP&lt;br /&gt;
 Action: drop&lt;br /&gt;
 User: clamav                                                      &lt;br /&gt;
* Start the daemons&lt;br /&gt;
 rc-update add clamd&lt;br /&gt;
 rc-update add freshclam&lt;br /&gt;
 rc-update add clamsmtp&lt;br /&gt;
 /etc/init.d/clamd start&lt;br /&gt;
 /etc/init.d/freshclam start&lt;br /&gt;
 /etc/init.d/clamsmtp start&lt;br /&gt;
* Verify clamsmtp is listening on port 10025:&lt;br /&gt;
 netstat -anp | grep clamsmtp&lt;br /&gt;
* [http://memberwebs.com/stef/software/clamsmtp/postfix.html Following the clamsmtp instructions]&lt;br /&gt;
** edit /etc/postfix/main.cf and add:&lt;br /&gt;
 content_filter = scan:[127.0.0.1]:10025                                                      &lt;br /&gt;
** edit /etc/postfix/master.cf and add&lt;br /&gt;
 # AV scan filter (used by content_filter)&lt;br /&gt;
 scan      unix  -       -       n       -       16      smtp&lt;br /&gt;
         -o smtp_send_xforward_command=yes&lt;br /&gt;
         -o smtp_enforce_tls=no&lt;br /&gt;
 # For injecting mail back into postfix from the filter&lt;br /&gt;
 127.0.0.1:10026 inet  n -       n       -       16      smtpd&lt;br /&gt;
         -o content_filter=&lt;br /&gt;
         -o receive_override_options=no_unknown_recipient_checks,no_header_body_checks&lt;br /&gt;
         -o smtpd_helo_restrictions=&lt;br /&gt;
         -o smtpd_client_restrictions=&lt;br /&gt;
         -o smtpd_sender_restrictions=&lt;br /&gt;
         -o smtpd_recipient_restrictions=permit_mynetworks,reject&lt;br /&gt;
         -o mynetworks_style=host&lt;br /&gt;
         -o smtpd_authorized_xforward_hosts=127.0.0.0/8&lt;br /&gt;
* postfix reload&lt;br /&gt;
* Send and email into a local virtual domain - it should have the &#039;&#039;X-Virus-Scanned: ClamAV using ClamSMTP&#039;&#039; header.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Relay for Authenticated Users ===&lt;br /&gt;
&lt;br /&gt;
As configured above, the mail server accepts email from the Internet, but it does not relay email.  If it is a perimeter exchanger for a protected network, then you can add the protected networks to the &#039;&#039;mynetworks&#039;&#039; configuration line in /etc/postfix/main.cf&lt;br /&gt;
&lt;br /&gt;
This configuration change allows &#039;&#039;remote&#039;&#039; users to authenticate against the mail server and relay through it.  The rules for relaying are:&lt;br /&gt;
* Only authenticated users can relay&lt;br /&gt;
* Authentication Credentials must be encrypted with TLS or SSL&lt;br /&gt;
* Allow Submission and SMTPS ports for relaying (many consumer networks block port 25 - SMTP by default)&lt;br /&gt;
The process uses the dovecot authentication mechanism (used with IMAPS) to authenticate users before they are allowed to relay through postfix.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* Edit /etc/dovecot/dovecot.conf and add:&lt;br /&gt;
 # this is for postfix SASL (authenticated users can relay through us)&lt;br /&gt;
 socket listen {&lt;br /&gt;
                client {&lt;br /&gt;
                        path    = /var/spool/postfix/private/dovecot-auth.sock&lt;br /&gt;
                        mode    = 0660&lt;br /&gt;
                        user    = postfix&lt;br /&gt;
                        group   = postfix&lt;br /&gt;
                        }&lt;br /&gt;
                }&lt;br /&gt;
        }&lt;br /&gt;
* Restart dovecot&lt;br /&gt;
 /etc/init.d/dovecot restart&lt;br /&gt;
* Edit /etc/postfix/main.cf and add:&lt;br /&gt;
 # TLS Stuff -- since we allow SASL with tls *only*, we have to set up TLS first                    &lt;br /&gt;
 &lt;br /&gt;
 smtpd_tls_cert_file = /etc/lighttpd/server-bundle.pem&lt;br /&gt;
 smtpd_tls_key_file = /etc/lighttpd/server-bundle.pem&lt;br /&gt;
 smtpd_tls_CAfile = /etc/lighttpd/ca-crt.pem&lt;br /&gt;
 # If tls_security_level is set to &amp;quot;encrypt&amp;quot;, then SMTP rejects &lt;br /&gt;
 # unencrypted email (e.g. normal mail) which is bad.&lt;br /&gt;
 # By setting it to &amp;quot;may&amp;quot; you get TLS encrypted mail from google, slashdot, and other &lt;br /&gt;
 # interesting places.  Check your logs to see who&lt;br /&gt;
 smtpd_tls_security_level = may&lt;br /&gt;
 # Log info about the negotiated encryption levels&lt;br /&gt;
 smtpd_tls_received_header = yes&lt;br /&gt;
 smtpd_tls_loglevel = 1&lt;br /&gt;
 &lt;br /&gt;
 # SASL - this allows senders to authenticiate themselves&lt;br /&gt;
 # This along with &amp;quot;permit_sasl_authenticated&amp;quot; in smtpd_recipient_restrictions allows relaying&lt;br /&gt;
 smtpd_sasl_type = dovecot&lt;br /&gt;
 smtpd_sasl_path = private/dovecot-auth.sock&lt;br /&gt;
 smtpd_sasl_auth_enable = yes&lt;br /&gt;
 smtpd_sasl_authenticated_header = yes&lt;br /&gt;
 smtpd_tls_auth_only = yes&lt;br /&gt;
* Edit /etc/postfix/master.cf and enable the submission and smtps transports.  They are probably already at the top of your  master.cf file, just commented out:&lt;br /&gt;
 submission inet n       -       n       -       -       smtpd&lt;br /&gt;
   -o smtpd_tls_security_level=encrypt&lt;br /&gt;
   -o smtpd_sasl_auth_enable=yes&lt;br /&gt;
   -o smtpd_client_restrictions=permit_sasl_authenticated,reject&lt;br /&gt;
   -o milter_macro_daemon_name=ORIGINATING&lt;br /&gt;
 smtps     inet  n       -       n       -       -       smtpd&lt;br /&gt;
   -o smtpd_tls_security_level=encrypt&lt;br /&gt;
   -o smtpd_tls_wrappermode=yes&lt;br /&gt;
   -o smtpd_sasl_auth_enable=yes&lt;br /&gt;
   -o smtpd_client_restrictions=permit_sasl_authenticated,reject&lt;br /&gt;
   -o milter_macro_daemon_name=ORIGINATING&lt;br /&gt;
*Verfiy submission and smtps are defined in /etc/services&lt;br /&gt;
 grep &amp;quot;submission\|ssmtp&amp;quot; /etc/services&lt;br /&gt;
 submission	587/tcp				# mail message submission&lt;br /&gt;
 submission	587/udp&lt;br /&gt;
 smtps		465/tcp		ssmtp		# smtp protocol over TLS/SSL&lt;br /&gt;
 smtps		465/udp		ssmtp&lt;br /&gt;
* Restart postfix&lt;br /&gt;
 postfix reload&lt;br /&gt;
&lt;br /&gt;
At this point, you should be able to set up a mail client to relay through the server with TLS (port 587) or SSL (port 465)  Note that &amp;quot;plain&amp;quot; authentication is used because the underlying link is encrypted.  For example, in Thunderbird leave &amp;quot;secure authentication&amp;quot; unchecked, and choose STARTTLS (or TLS) for the connection security.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Mailbox Quotas ===&lt;br /&gt;
&lt;br /&gt;
In the default configuration, PostfixAdmin knows about quotas, but they are not enforced.   Documentation on the web mentions the [http://vda.sourceforge.net vda patch to postifx] to enforce quotas.  The only bad thing... its a &#039;&#039;patch&#039;&#039;.   Postfix and Dovecot are both conservative systems, so if the patch isn&#039;t in the upstream source, we&#039;ll assume there&#039;s a good reason.   There is a way of using quotas without patches - and it involves using the dovecot&#039;s [http://wiki.dovecot.org/LDA deliver] lda for local delivery.&lt;br /&gt;
&lt;br /&gt;
Note: As of Jan 2010, the documention is confusing, with multiple versions of dovecot, PostfixAdmin, and Mysql referenced.  These instructions apply to:&lt;br /&gt;
* Postgresql 8.4.2 &lt;br /&gt;
* PostfixAdmin 2.3 &lt;br /&gt;
* Dovecot 1.2.10&lt;br /&gt;
* Postfix 2.6.5&lt;br /&gt;
&lt;br /&gt;
Presumably later versions will work the same, but if not, please update the documentation and versions above.&lt;br /&gt;
&lt;br /&gt;
* Update /etc/dovecot.conf (old lines shown commented out):&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
# old postfix &lt;br /&gt;
#       userdb static {&lt;br /&gt;
#               args =  uid=1006 gid=1006 home=/var/mail/domains/%d/%n&lt;br /&gt;
#               }&lt;br /&gt;
&lt;br /&gt;
# new quota support:&lt;br /&gt;
        userdb prefetch {&lt;br /&gt;
                }&lt;br /&gt;
&lt;br /&gt;
        userdb sql {&lt;br /&gt;
                args = /etc/dovecot/dovecot-sql.conf&lt;br /&gt;
                }&lt;br /&gt;
&lt;br /&gt;
        socket listen {&lt;br /&gt;
                client {&lt;br /&gt;
                        path    = /var/spool/postfix/private/dovecot-auth.sock&lt;br /&gt;
                        mode    = 0660&lt;br /&gt;
                        user    = postfix&lt;br /&gt;
                        group   = postfix&lt;br /&gt;
                        }&lt;br /&gt;
                # These lines below are for the deliver lda&lt;br /&gt;
                master {&lt;br /&gt;
                        path =  /var/run/dovecot/auth-master&lt;br /&gt;
                        mode    = 0660&lt;br /&gt;
                        user    = vmail&lt;br /&gt;
                        group   = vmail&lt;br /&gt;
                        }&lt;br /&gt;
                }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
protocol imap {                                                               &lt;br /&gt;
         mail_plugins = quota imap_quota                                       &lt;br /&gt;
         }                                                                     &lt;br /&gt;
                                                                              &lt;br /&gt;
protocol pop3 {                                                               &lt;br /&gt;
         mail_plugins = quota                                                  &lt;br /&gt;
         }                                                                     &lt;br /&gt;
                                                                              &lt;br /&gt;
dict {                                                                        &lt;br /&gt;
        quotadict = pgsql:/etc/dovecot/dovecot-dict-quota.conf                &lt;br /&gt;
        }                                                                     &lt;br /&gt;
                                                                              &lt;br /&gt;
plugin {                                                                      &lt;br /&gt;
         quota = dict:user::proxy::quotadict                                   &lt;br /&gt;
         }                                                     &lt;br /&gt;
                                                              &lt;br /&gt;
protocol lda {                                                &lt;br /&gt;
   postmaster_address = postmaster@host.example.com&lt;br /&gt;
   mail_plugins = quota                                        &lt;br /&gt;
   auth_socket_path =  /var/run/dovecot/auth-master&lt;br /&gt;
   sendmail_path = /usr/sbin/sendmail&lt;br /&gt;
}                                                                            &lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
 &lt;br /&gt;
You should already have a &amp;lt;tt&amp;gt;socket-&amp;gt; listen-&amp;gt; client&amp;lt;/tt&amp;gt; section, but it is listed above to show where it goes in relationship to the &amp;lt;tt&amp;gt;socket -&amp;gt; listen -&amp;gt; master&amp;lt;/tt&amp;gt; section&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* edit &amp;lt;tt&amp;gt;/etc/dovecot/dovecot-sql.conf&amp;lt;/tt&amp;gt; and replace the user and password queries with the following (you may not have a user_query yet - add it):&lt;br /&gt;
&lt;br /&gt;
 password_query = select username as user, password, 1006 as userdb_uid, 1006 as userdb_gid, &#039;*:bytes=&#039; || quota as userdb_quota_rule from mailbox  where local_part = &#039;%n&#039; and domain = &#039;%d&#039;&lt;br /&gt;
 user_query = select maildir as home, 1006 as uid, 1006 as gid, &#039;*:bytes=&#039; || quota  as quota_rule from mailbox where local_part = &#039;%n&#039; and domain =&#039;%d&#039;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* create &amp;lt;tt&amp;gt;/etc/dovecot/dovecot-dict-quota.conf&amp;lt;/tt&amp;gt;&lt;br /&gt;
 connect = host=localhost dbname=postfix user=postfix password=********&lt;br /&gt;
 &lt;br /&gt;
 map {&lt;br /&gt;
         pattern = priv/quota/storage&lt;br /&gt;
         table = quota2&lt;br /&gt;
         username_field =username&lt;br /&gt;
         value_field = bytes&lt;br /&gt;
 }&lt;br /&gt;
 &lt;br /&gt;
 map {&lt;br /&gt;
        pattern= priv/quota/messages&lt;br /&gt;
        table = quota2&lt;br /&gt;
        username_field = username&lt;br /&gt;
        value_field = messages&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
Side note: [http://wiki.dovecot.org/Quota/Dict The Dovecot Quota Documentation] mentions the need for a trigger with pgsql.  This was created in the PostfixAdmin install, which is why you instantiated the pgsql language when creating the database.  If not, you will need to create the trigger, to reference the quota2 table, not the quota table mentioned in the dovecot docs.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* create a new transport for the dovecot lda.   Add the following to  /etc/postfix/master.cf:&lt;br /&gt;
 # The dovecot deliver lda&lt;br /&gt;
 dovecot   unix  -       n       n       -       -       pipe&lt;br /&gt;
   flags=DRhu user=vmail:vmail argv=/usr/libexec/dovecot/deliver -f ${sender} -d ${user}@${nexthop}&lt;br /&gt;
&lt;br /&gt;
* Edit the /etc/postfix/main.cf.  Replace &lt;br /&gt;
 virtual_transport = virtual &lt;br /&gt;
with&lt;br /&gt;
 virtual_transport = dovecot&lt;br /&gt;
 dovecot_destination_recipient_limit = 1&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;TODO&#039;&#039;&#039;  This will cause over-quota emails to bounce.   Which could be a source of backscatter.   We need a way of checking quota limits after RBL checking but before the message is accepted in the queue.&lt;br /&gt;
&lt;br /&gt;
=== WebMail (RoundCube) ===&lt;br /&gt;
&lt;br /&gt;
[http://roundcube.net/ RoundCube] is an &amp;quot;ajax /Web2.0&amp;quot; web-mail client.  These instructions are for the Alpine Linux 1.10 repository &lt;br /&gt;
&lt;br /&gt;
* Add the package and related php modules:&lt;br /&gt;
 apk add roundcubemail php-xml php-openssl php-mcrypt php-gd php-iconv&lt;br /&gt;
&lt;br /&gt;
* link the roundcube application back into the docroot&lt;br /&gt;
 ln -s /usr/share/webapps/roundcube /var/www/domains/host.example.com/www/roundcube&lt;br /&gt;
&lt;br /&gt;
* follow the instructions in /usr/share/webapps/roundcube/INSTALL:&lt;br /&gt;
 chown -R lighttpd:lighttpd temp logs&lt;br /&gt;
 &lt;br /&gt;
 su postgres&lt;br /&gt;
 createuser roundcube&lt;br /&gt;
   Shall the new role be a superuser? (y/n) n&lt;br /&gt;
   Shall the new role be allowed to create databases? (y/n) n&lt;br /&gt;
   Shall the new role be allowed to create more new roles? (y/n) y&lt;br /&gt;
 createdb -O roundcube -E UNICODE -T template0 roundcubemail&lt;br /&gt;
 psql roundcubemail&lt;br /&gt;
   roundcubemail=# ALTER USER roundcube WITH PASSWORD &#039;the_new_password&#039;;&lt;br /&gt;
   roundcubemail=# \c - roundcube&lt;br /&gt;
   \i /usr/share/webapps/roundcube/SQL/postgres.initial.sql&lt;br /&gt;
   \q&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* restart lighttpd to verify the new php libraries are used&lt;br /&gt;
 /etc/init.d/lighttpd restart&lt;br /&gt;
&lt;br /&gt;
* Point your browser to http://host.example.com/roundcube/installer&lt;br /&gt;
** Begin installation&lt;br /&gt;
** Follow the instructions in step 3 of the install to copy the files to the server&lt;br /&gt;
* edit /etc/php/php.ini and edit date.timezone to your local timezone, or to UTC&lt;br /&gt;
* if necessary (e.g. you had to reset the local timezone) restart lighttpd to reload php&lt;br /&gt;
 /etc/init.d/lighttpd restart&lt;br /&gt;
* You should now be able to get to roundcube at http://host.example.com/roundcube&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
For the specific configuration parameters in the install step:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!Property&lt;br /&gt;
!Setting&lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;enable_spellcheck&#039;&#039; ||   disabled &lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;identities_level&#039;&#039; ||  one identity with possibility to edit all params but not email address &lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;log driver&#039;&#039; || syslog &lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;sylog_id&#039;&#039; || roundcube &lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;syslog_facility&#039;&#039; || mailsubsystem &lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;db_dnsw&#039;&#039; || pgsql properties, as described above &lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;imap_host&#039;&#039; || 127.0.0.1 &lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;auto_create_user&#039;&#039; || enabled &lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;smtp_server&#039;&#039; ||  127.0.0.1&lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;smtp_port&#039;&#039; ||  25&lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;smtp_user/smtp_pass&#039;&#039; ||  enable &#039;&#039;Use Current IMAP username and password for SMTP authentication&#039;&#039;&lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;smtp_log&#039;&#039; ||  enable (optional, but gives additional log record)&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
The other items can be left at default settings, or adjusted if desired.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
After its working, the INSTALL file recommends removing the install directory.   If you want to keep the installer around later, you can simply change the ownership and permissions.  So do &#039;&#039;&#039;one&#039;&#039;&#039; of the following:&lt;br /&gt;
 cd /usr/share/webapps/roundcube&lt;br /&gt;
 rm -rf LICENSE UPGRADING INSTALL README CHANGELOG  SQL installer&lt;br /&gt;
or&lt;br /&gt;
 cd /usr/share/webapps/roundcube&lt;br /&gt;
 chown -R root:root LICENSE UPGRADING INSTALL README CHANGELOG  SQL installer&lt;br /&gt;
 chmod -R 600 LICENSE UPGRADING INSTALL README CHANGELOG SQL &lt;br /&gt;
 chmod 700 SQL installer&lt;br /&gt;
&lt;br /&gt;
== log rotation ==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
Special thanks to DHughes for providing a 3 page email on how to set up postgres,postfix,PostfixAdmin,dovecot and roundcube.  It was the clearer than all the other guides available on the Net. Thanks!&lt;/div&gt;</summary>
		<author><name>Djhughes</name></author>
	</entry>
	<entry>
		<id>https://wiki.alpinelinux.org/w/index.php?title=ISP_Mail_Server_HowTo&amp;diff=3350</id>
		<title>ISP Mail Server HowTo</title>
		<link rel="alternate" type="text/html" href="https://wiki.alpinelinux.org/w/index.php?title=ISP_Mail_Server_HowTo&amp;diff=3350"/>
		<updated>2010-02-16T09:36:52Z</updated>

		<summary type="html">&lt;p&gt;Djhughes: tidied up code&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== A Full Service Mail Server ==&lt;br /&gt;
&lt;br /&gt;
The goal of this document is to describe how to set up postfix, dovecot, clamav, dspam, roundecube, and postfixadmin for a full-featured &amp;quot;ISP&amp;quot; level mail server.&lt;br /&gt;
&lt;br /&gt;
The server must provide:&lt;br /&gt;
&lt;br /&gt;
* multiple virtual domains&lt;br /&gt;
* admins for each domain (to add/remove virtual accounts)&lt;br /&gt;
* Quota support per domain / account&lt;br /&gt;
* downloading email via IMAP / IMAPS / POP3 / POP3S&lt;br /&gt;
* relaying email for authenticated users with TLS or SSL (Submission / SMTPS protocol)&lt;br /&gt;
* Standard filters (virus/spam/rbl/etc)&lt;br /&gt;
* Web mail client&lt;br /&gt;
* Value Add services&lt;br /&gt;
&lt;br /&gt;
== Configure DNS ==&lt;br /&gt;
&lt;br /&gt;
This server will host three separate virtual domains on the same web server. They will be distinguished by their DNS names, so you must choose three domains for the three separate services:&lt;br /&gt;
&lt;br /&gt;
* ACF - Alpine Configuration Framework for managing the server&lt;br /&gt;
* PostfixAdmin - for managing the postfix installation&lt;br /&gt;
* RoundCube - for accessing individual mailboxes&lt;br /&gt;
&lt;br /&gt;
Choose three different domains (from here on known as ACF_DOMAIN, POSTFIXADMIN_DOMAIN, and ROUNDCUBE_DOMAIN) and configure DNS for all three to point to the IP address of your host. These should be DNS A records.&lt;br /&gt;
&lt;br /&gt;
== Set up Lighttpd + PHP ==&lt;br /&gt;
&lt;br /&gt;
PostfixAdmin needs php pgpsql and imap modules, so we do it in this step.&lt;br /&gt;
&lt;br /&gt;
  apk add lighttpd php php-pgsql php-imap&lt;br /&gt;
&lt;br /&gt;
Stop and remove mini_httpd, and move ACF to lighttpd;  We are setting this up to be a multi-domain virtual web server (replace ACF_DOMAIN with the actual domain):&lt;br /&gt;
&lt;br /&gt;
  mkdir -p /var/www/domains/ACF_DOMAIN&lt;br /&gt;
  ln -s /usr/share/acf/www /var/www/domains/ACF_DOMAIN/www&lt;br /&gt;
&lt;br /&gt;
Edit /etc/lighttpd/mod_cgi.conf to serve haserl files by adding a &amp;quot;&amp;quot; =&amp;gt; &amp;quot;&amp;quot; cgi handler&lt;br /&gt;
&lt;br /&gt;
 $HTTP[&amp;quot;url&amp;quot;] =~ &amp;quot;^/cgi-bin/&amp;quot; {&lt;br /&gt;
     # disable directory listings&lt;br /&gt;
     dir-listing.activate = &amp;quot;disable&amp;quot;&lt;br /&gt;
     # only allow cgi&#039;s in this directory&lt;br /&gt;
     cgi.assign = (&lt;br /&gt;
 		&amp;quot;.pl&amp;quot;	=&amp;gt;	&amp;quot;/usr/bin/perl&amp;quot;,&lt;br /&gt;
 		&amp;quot;.cgi&amp;quot;	=&amp;gt;	&amp;quot;/usr/bin/perl&amp;quot;,&lt;br /&gt;
 		&amp;quot;&amp;quot; =&amp;gt; &amp;quot;&amp;quot;&lt;br /&gt;
 	)&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
Add these lines to /etc/lighttpd/lighttpd.conf to point to the new document root, and set it up to listen on port 443 (replace &#039;&#039;ROUNDCUBE_DOMAIN&#039;&#039; with the roundcube domain and &#039;&#039;ip_address_of_server&#039;&#039; with the actual IP address):&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
 simple-vhost.server-root   = &amp;quot;/var/www/domains/&amp;quot;&lt;br /&gt;
 simple-vhost.default-host  = &amp;quot;/ROUNDCUBE_DOMAIN/&amp;quot;&lt;br /&gt;
 simple-vhost.document-root = &amp;quot;www/&amp;quot;&lt;br /&gt;
&lt;br /&gt;
 $HTTP[&amp;quot;host&amp;quot;] == &amp;quot;POSTFIXADMIN_DOMAIN&amp;quot; {&lt;br /&gt;
	simple-vhost.server-root   = &amp;quot;/var/www/domains/&amp;quot;&lt;br /&gt;
	simple-vhost.default-host  = &amp;quot;/POSTFIXADMIN_DOMAIN/&amp;quot;&lt;br /&gt;
	simple-vhost.document-root = &amp;quot;www/&amp;quot;&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
 $HTTP[&amp;quot;host&amp;quot;] == &amp;quot;ACF_DOMAIN&amp;quot; {&lt;br /&gt;
	simple-vhost.server-root   = &amp;quot;/var/www/domains/&amp;quot;&lt;br /&gt;
	simple-vhost.default-host  = &amp;quot;/ACF_DOMAIN/&amp;quot;&lt;br /&gt;
	simple-vhost.document-root = &amp;quot;www/&amp;quot;&lt;br /&gt;
 } &lt;br /&gt;
 $SERVER[&amp;quot;socket&amp;quot;] == &amp;quot;ip_address_of_server:443&amp;quot; {&lt;br /&gt;
 ssl.engine    = &amp;quot;enable&amp;quot;&lt;br /&gt;
 ssl.pemfile   = &amp;quot;/etc/lighttpd/server-bundle.pem&amp;quot;&lt;br /&gt;
 ssl.ca-file   = &amp;quot;/etc/lighttpd/ca-crt.pem&amp;quot;&lt;br /&gt;
 }&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Ensure that the simple_vhosts module is loaded, as well as the cgi config scripts by uncommenting the following lines in /etc/lighttpd/lighttpd.conf&lt;br /&gt;
&lt;br /&gt;
 server.modules = (&lt;br /&gt;
     #  other modules may be listed&lt;br /&gt;
     &amp;quot;mod_simple_vhost&amp;quot;, &lt;br /&gt;
     #  other modules may be listed&lt;br /&gt;
  .&lt;br /&gt;
  .&lt;br /&gt;
  .&lt;br /&gt;
     include &amp;quot;mod_cgi.conf&amp;quot;&lt;br /&gt;
 &lt;br /&gt;
     include &amp;quot;mod_fastcgi.conf&amp;quot;&lt;br /&gt;
 &lt;br /&gt;
&lt;br /&gt;
Get a web certificate, and install it.  If you want to use a self-signed cert, you can use [[Generating SSL certs with ACF]] or [[Generating SSL certs with ACF 1.9]].  If you create a certificate with ACF, you can create the &amp;quot;server-bundle.pem&amp;quot; and the &amp;quot;ca-crt.pem&amp;quot; file with these commands:&lt;br /&gt;
&lt;br /&gt;
  openssl pkcs12 -nokeys -cacerts -in certificate.pfx  -out /etc/lighttpd/ca-crt.pem&lt;br /&gt;
  openssl pkcs12 -nodes -in certifcate.pfx -out /etc/lighttpd/server-bundle.pem&lt;br /&gt;
  chown root:root /etc/lighttpd/server-bundle.pem&lt;br /&gt;
  chmod 400 /etc/lighttpd/server-bundle.pem&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Note:&#039;&#039;&#039; The server certificate &#039;&#039;and&#039;&#039; key are in the server-bundle.pem file, so it is critical that the file be read-only by user &amp;quot;root&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
 Editme: We should probably only serve ACF to restricted hosts&lt;br /&gt;
&lt;br /&gt;
Stop and remove mini_httpd; start lighttpd, test&lt;br /&gt;
&lt;br /&gt;
  /etc/init.d/mini_httpd stop&lt;br /&gt;
  rc-update del mini_httpd&lt;br /&gt;
  apk del mini_httpd&lt;br /&gt;
  rc-update add lighttpd&lt;br /&gt;
  /etc/init.d/lighttpd start&lt;br /&gt;
&lt;br /&gt;
At this point you should be able to see ACF being served with lighttpd:  https://ACF_DOMAIN/&lt;br /&gt;
&lt;br /&gt;
== Install Postgresql ==&lt;br /&gt;
&lt;br /&gt;
Add and configure postgresql&lt;br /&gt;
&lt;br /&gt;
  apk add acf-postgresql postgresql-client&lt;br /&gt;
  /etc/init.d/postgresql setup&lt;br /&gt;
  /etc/init.d/postgresql start&lt;br /&gt;
  rc-update add postgresql&lt;br /&gt;
&lt;br /&gt;
At this point any user can connect to the sql server with &amp;quot;trust&amp;quot; mechanism.  If you want to enforce password authentication (you probably do) edit /var/lib/postgresql/8.4/data/pg_hba.conf&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
  Editme: What should we recommend?&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Create the postfix database:&lt;br /&gt;
&lt;br /&gt;
  psql -U postgres&lt;br /&gt;
   create user postfix with password &#039;******&#039;;&lt;br /&gt;
   create database postfix owner postfix;&lt;br /&gt;
   \c postfix&lt;br /&gt;
   create language plpgsql;&lt;br /&gt;
   \q&lt;br /&gt;
&lt;br /&gt;
(Of course, use your selected password where ******* is shown above.)&lt;br /&gt;
&lt;br /&gt;
== Install PostfixAdmin ==&lt;br /&gt;
&lt;br /&gt;
We are going to install the postfix admin web front-end before we install the mail server.  This just creates an interface to populate the SQL tables that postfix and dovecot will use.&lt;br /&gt;
&lt;br /&gt;
Download PostfixAdmin from Sourceforge.  When these instructions were written, 2.3 was the current release, so (replace POSTFIXADMIN_DOMAIN with the actual domain):&lt;br /&gt;
 wget http://downloads.sourceforge.net/project/postfixadmin/postfixadmin/postfixadmin_2.3.tar.gz&lt;br /&gt;
 tar zxvf postfixadmin_2.3.tar.gz&lt;br /&gt;
 mkdir -p /var/www/domains/POSTFIXADMIN_DOMAIN/www&lt;br /&gt;
 mv postfixadmin-2.3/* /var/www/domains/POSTFIXADMIN_DOMAIN/www&lt;br /&gt;
 rm -rf postfixadmin*&lt;br /&gt;
&lt;br /&gt;
Edit /var/www/domains/POSTFIXADMIN_DOMAIN/www/config.inc.php and modify at least these lines (replace POSTFIXADMIN_DOMAIN with the actual domain):&lt;br /&gt;
&lt;br /&gt;
 $CONF[&#039;configured&#039;] = true;&lt;br /&gt;
 $CONF[&#039;setup_password&#039;] = &amp;quot;&amp;quot;;  &amp;lt;&amp;lt; Don&#039;t change this yet&lt;br /&gt;
 $CONF[&#039;database_type&#039;] = &#039;pgsql&#039;;&lt;br /&gt;
 $CONF[&#039;database_host&#039;] = &#039;localhost&#039;;&lt;br /&gt;
 $CONF[&#039;database_user&#039;] = &#039;postfix&#039;;&lt;br /&gt;
 $CONF[&#039;database_password&#039;] = &#039;*****&#039;;   &amp;lt;&amp;lt; The password you chose above&lt;br /&gt;
 $CONF[&#039;database_name&#039;] = &#039;postfix&#039;;&lt;br /&gt;
 $CONF[&#039;database_prefix&#039;] = &#039;&#039;;&lt;br /&gt;
 $CONF[&#039;admin_email&#039;] = &#039;you@some.email.com&#039;;  &amp;lt;&amp;lt; Your email address &lt;br /&gt;
 $CONF[&#039;encrypt&#039;] = &#039;md5crypt&#039;;&lt;br /&gt;
 $CONF[&#039;authlib_default_flavor&#039;] = &#039;md5raw&#039;;&lt;br /&gt;
 $CONF[&#039;dovecotpw&#039;] = &amp;quot;/usr/sbin/dovecotpw&amp;quot;;&lt;br /&gt;
 $CONF[&#039;domain_path&#039;] = &#039;YES&#039;;&lt;br /&gt;
 $CONF[&#039;domain_in_mailbox&#039;] = &#039;NO&#039;;&lt;br /&gt;
 $CONF[&#039;aliases&#039;] = &#039;10&#039;;                       &lt;br /&gt;
 $CONF[&#039;mailboxes&#039;] = &#039;10&#039;;&lt;br /&gt;
 $CONF[&#039;maxquota&#039;] = &#039;10&#039;;&lt;br /&gt;
 $CONF[&#039;vacation&#039;] = &#039;NO&#039;; &lt;br /&gt;
 $CONF[&#039;vacation_control&#039;] =&#039;NO&#039;;&lt;br /&gt;
 $CONF[&#039;vacation_control_admin&#039;] = &#039;NO&#039;;&lt;br /&gt;
 $CONF[&#039;create_mailbox_subdirs_prefix&#039;]=&amp;quot;&amp;quot;;  &lt;br /&gt;
 $CONF[&#039;quota&#039;] = &#039;YES&#039;;&lt;br /&gt;
 $CONF[&#039;quota_multiplier&#039;] = &#039;1024000&#039;;&lt;br /&gt;
 $CONF[&#039;used_quotas&#039;] = &#039;YES&#039;;   &lt;br /&gt;
 $CONF[&#039;new_quota_table&#039;] = &#039;YES&#039;;  &lt;br /&gt;
 $CONF[&#039;alias_control&#039;] = &#039;YES&#039;;&lt;br /&gt;
 $CONF[&#039;alias_control_admin&#039;] = &#039;YES&#039;;&lt;br /&gt;
 $CONF[&#039;special_alias_control&#039;] = &#039;YES&#039;;&lt;br /&gt;
 $CONF[&#039;fetchmail&#039;] = &#039;NO&#039;;&lt;br /&gt;
 $CONF[&#039;user_footer_link&#039;] = &amp;quot;http://POSTFIXADMIN_DOMAIN&amp;quot;;&lt;br /&gt;
 $CONF[&#039;footer_link&#039;] = &#039;http://POSTFIXADMIN_DOMAIN/main.php&#039;;&lt;br /&gt;
&lt;br /&gt;
You should further edit /var/www/domains/POSTFIXADMIN_DOMAIN/www/config.inc.php and replace all instances of &amp;quot;change-this-to-your.domain.tld&amp;quot; with your actual mail domain.&lt;br /&gt;
&lt;br /&gt;
Go to http://POSTFIXADMIN_DOMAIN/setup.php&lt;br /&gt;
&lt;br /&gt;
Create the password hash, add it to the config.inc.php file&lt;br /&gt;
&lt;br /&gt;
Go back to http://POSTFIXADMIN_DOMAIN/setup.php&lt;br /&gt;
&lt;br /&gt;
Create superadmin account.&lt;br /&gt;
&lt;br /&gt;
== Install Postfix ==&lt;br /&gt;
&lt;br /&gt;
Create a user for the virtual mail delivery, and get its uid/gid (you&#039;ll need the numeric uid/gid for postfix)&lt;br /&gt;
&lt;br /&gt;
 adduser vmail -H -D -s /bin/false&lt;br /&gt;
 grep vmail /etc/passwd&lt;br /&gt;
&lt;br /&gt;
(In examples below, we use 1006/1006 for the uid/gid)&lt;br /&gt;
&lt;br /&gt;
Create the mail directory, and assign vmail as the owner&lt;br /&gt;
 mkdir -p /var/mail/domains&lt;br /&gt;
 chown -R vmail:vmail /var/mail/domains&lt;br /&gt;
 &lt;br /&gt;
&lt;br /&gt;
Install postfix&lt;br /&gt;
&lt;br /&gt;
 apk add acf-postfix postfix-pgsql&lt;br /&gt;
&lt;br /&gt;
Edit the /etc/postfix/main.cf file  Here&#039;s an example:&lt;br /&gt;
&lt;br /&gt;
 myhostname=host.example.com&lt;br /&gt;
 mydomain=example.com&lt;br /&gt;
 &lt;br /&gt;
 mydestination = localhost.$mydomains, localhost&lt;br /&gt;
 mynetworks_style = subnet&lt;br /&gt;
 mynetworks = 127.0.0.0/8&lt;br /&gt;
 &lt;br /&gt;
 virtual_mailbox_domains = proxy:pgsql:/etc/postfix/sql/pgsql_virtual_domains_maps.cf&lt;br /&gt;
 virtual_alias_maps = proxy:pgsql:/etc/postfix/sql/pgsql_virtual_alias_maps.cf,&lt;br /&gt;
        proxy:pgsql:/etc/postfix/sql/pgsql_virtual_alias_domain_maps.cf,&lt;br /&gt;
        proxy:pgsql:/etc/postfix/sql/pgsql_virtual_alias_domain_catchall_maps.cf&lt;br /&gt;
 &lt;br /&gt;
 virtual_mailbox_maps = proxy:pgsql:/etc/postfix/sql/pgsql_virtual_mailbox_maps.cf,&lt;br /&gt;
        proxy:pgsql:/etc/postfix/sql/pgsql_virtual_alias_domain_mailbox_maps.cf&lt;br /&gt;
 &lt;br /&gt;
 virtual_mailbox_base = /var/mail/domains/&lt;br /&gt;
 virtual_gid_maps = static:1006&lt;br /&gt;
 virtual_uid_maps = static:1006&lt;br /&gt;
 virtual_minimum_uid = 100&lt;br /&gt;
 virtual_transport = virtual&lt;br /&gt;
 &lt;br /&gt;
 &lt;br /&gt;
 # This next command means you must create a virtual&lt;br /&gt;
 # domain for the host itself - ALL mail goes through&lt;br /&gt;
 # The virtual transport&lt;br /&gt;
 &lt;br /&gt;
 mailbox_transport = virtual&lt;br /&gt;
 local_transport = virtual&lt;br /&gt;
 local_transport_maps = $virtual_mailbox_maps&lt;br /&gt;
 &lt;br /&gt;
 smtpd_helo_required = yes&lt;br /&gt;
 disable_vrfy_command = yes&lt;br /&gt;
 message_size_limit = 10240000&lt;br /&gt;
 queue_minfree = 51200000&lt;br /&gt;
 &lt;br /&gt;
 smtpd_sender_restrictions =&lt;br /&gt;
        permit_mynetworks,&lt;br /&gt;
        reject_non_fqdn_sender,&lt;br /&gt;
        reject_unknown_sender_domain&lt;br /&gt;
 &lt;br /&gt;
 smtpd_recipient_restrictions =&lt;br /&gt;
        reject_non_fqdn_recipient,&lt;br /&gt;
        reject_unknown_recipient_domain,&lt;br /&gt;
        permit_mynetworks,&lt;br /&gt;
        permit_sasl_authenticated,&lt;br /&gt;
        reject_unauth_destination,&lt;br /&gt;
        reject_rbl_client dnsbl.sorbs.net,&lt;br /&gt;
        reject_rbl_client zen.spamhaus.org,&lt;br /&gt;
        reject_rbl_client bl.spamcop.net&lt;br /&gt;
 &lt;br /&gt;
 smtpd_data_restrictions = reject_unauth_pipelining&lt;br /&gt;
 &lt;br /&gt;
 # we will use this later - This prevents cleartext authentication&lt;br /&gt;
 # for relaying&lt;br /&gt;
 smtpd_tls_auth_only = yes&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Now we need to create a *bunch* of files so that postfix can get the delivery information out of sql. Here&#039;s a shell script to create the scripts.  Change PGPW to the password for the postfix user of the postfix SQL database.&lt;br /&gt;
&lt;br /&gt;
 cd /etc/postfix&lt;br /&gt;
 mkdir sql&lt;br /&gt;
 PGPW=&amp;quot;ChangeMe&amp;quot;&lt;br /&gt;
 &lt;br /&gt;
 cat - &amp;lt;&amp;lt;EOF &amp;gt;sql/pgsql_virtual_alias_domain_catchall_maps.cf&lt;br /&gt;
 user=postfix&lt;br /&gt;
 password = $PGPW&lt;br /&gt;
 hosts = localhost&lt;br /&gt;
 dbname = postfix&lt;br /&gt;
 query = Select goto From alias,alias_domain where alias_domain.alias_domain = &#039;%d&#039; and alias.address = &#039;@&#039; ||  alias_domain.target_domain and alias.active = true and alias_domain.active= true &lt;br /&gt;
 EOF&lt;br /&gt;
 &lt;br /&gt;
 cat - &amp;lt;&amp;lt;EOF &amp;gt;sql/pgsql_virtual_alias_domain_mailbox_maps.cf&lt;br /&gt;
 user=postfix&lt;br /&gt;
 password = $PGPW&lt;br /&gt;
 hosts = localhost&lt;br /&gt;
 dbname = postfix&lt;br /&gt;
 query = Select maildir from mailbox,alias_domain where alias_domain.alias_domain = &#039;%d&#039; and mailbox.username = &#039;%u&#039; || &#039;@&#039; || alias_domain.target_domain and mailbox.active = true and alias_domain.active&lt;br /&gt;
 EOF&lt;br /&gt;
 &lt;br /&gt;
 cat - &amp;lt;&amp;lt;EOF &amp;gt;sql/pgsql_virtual_alias_domain_maps.cf&lt;br /&gt;
 user=postfix&lt;br /&gt;
 password = $PGPW&lt;br /&gt;
 hosts = localhost&lt;br /&gt;
 dbname = postfix&lt;br /&gt;
 query = select goto from alias,alias_domain where alias_domain.alias_domain=&#039;%d&#039; and alias.address = &#039;%u&#039; || &#039;@&#039; || alias_domain.target_domain and alias.active= true and alias_domain.active= true&lt;br /&gt;
 EOF&lt;br /&gt;
 &lt;br /&gt;
 cat - &amp;lt;&amp;lt;EOF &amp;gt;sql/pgsql_virtual_alias_maps.cf&lt;br /&gt;
 user=postfix&lt;br /&gt;
 password = $PGPW&lt;br /&gt;
 hosts = localhost&lt;br /&gt;
 dbname = postfix&lt;br /&gt;
 query = Select goto From alias Where address=&#039;%s&#039; and active =&#039;1&#039;&lt;br /&gt;
 EOF&lt;br /&gt;
 &lt;br /&gt;
 cat - &amp;lt;&amp;lt;EOF &amp;gt;sql/pgsql_virtual_domains_maps.cf&lt;br /&gt;
 user=postfix&lt;br /&gt;
 password = $PGPW&lt;br /&gt;
 hosts = localhost&lt;br /&gt;
 dbname = postfix&lt;br /&gt;
 query = Select domain from domain where domain=&#039;%s&#039; and active=&#039;1&#039;&lt;br /&gt;
 EOF&lt;br /&gt;
 &lt;br /&gt;
 cat - &amp;lt;&amp;lt;EOF &amp;gt;sql/pgsql_virtual_mailbox_maps.cf&lt;br /&gt;
 user=postfix&lt;br /&gt;
 password = $PGPW&lt;br /&gt;
 hosts = localhost&lt;br /&gt;
 dbname = postfix&lt;br /&gt;
 query = Select maildir from mailbox where username=&#039;%s&#039; and active=true&lt;br /&gt;
 EOF&lt;br /&gt;
 &lt;br /&gt;
 chown -R postfix:postfix sql&lt;br /&gt;
 chmod 640 sql/*&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
At this point you should be able to start up postfix&lt;br /&gt;
 &lt;br /&gt;
 newaliases  # so postfix is happy...&lt;br /&gt;
 /etc/init.d/postfix start&lt;br /&gt;
 rc-update add postfix&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Create a domain in PostfixAdmin and test ===&lt;br /&gt;
&lt;br /&gt;
Go to http://POSTFIXADMIN_DOMAIN/&lt;br /&gt;
&lt;br /&gt;
Log in using the superadmin account, create a domain for the local box (e.g. example.com), and create a user mailbox (e.g. root).&lt;br /&gt;
&lt;br /&gt;
From the machine, send a test message:&lt;br /&gt;
&lt;br /&gt;
 sendmail -t root@example.com&lt;br /&gt;
 subject: test&lt;br /&gt;
 .&lt;br /&gt;
 ^d&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
In /var/log/mail.log (or /var/log/messages, if you still have busybox syslogd running) you should see the message queued.  The message should be in /var/mail/domains/example.com/root/new&lt;br /&gt;
&lt;br /&gt;
== Install Dovecot ==&lt;br /&gt;
&lt;br /&gt;
Dovecot is the POP3/IMAP server to retrieve mail.&lt;br /&gt;
&lt;br /&gt;
As before, we install dovecot: &lt;br /&gt;
&lt;br /&gt;
 apk add acf-dovecot dovecot-pgsql&lt;br /&gt;
&lt;br /&gt;
edit /etc/dovecot/dovecot.conf&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 # Select only the protocols you wish to support - all are listed in the next line&lt;br /&gt;
 protocols               =       imap imaps pop pop3s&lt;br /&gt;
 log_path                =       /var/log/dovecot.log&lt;br /&gt;
 info_log_path           =       /var/log/dovecot-info.log&lt;br /&gt;
 disable_plaintext_auth  =       no&lt;br /&gt;
&lt;br /&gt;
 # Authenticated IMAP&lt;br /&gt;
 ssl                     =       yes&lt;br /&gt;
 ssl_cert_file           =       /etc/lighttpd/server-bundle.pem&lt;br /&gt;
 ssl_key_file            =       /etc/lighttpd/server-bundle.pem&lt;br /&gt;
 auth_verbose            =       yes&lt;br /&gt;
 auth_debug              =       no&lt;br /&gt;
 mail_location           =       maildir:/var/mail/domains/%d/%n&lt;br /&gt;
 auth default    {&lt;br /&gt;
        mechanisms = plain&lt;br /&gt;
        passdb sql {&lt;br /&gt;
                args = /etc/dovecot/dovecot-sql.conf&lt;br /&gt;
                }&lt;br /&gt;
        userdb static {&lt;br /&gt;
                args =  uid=1006 gid=1006 home=/var/mail/domains/%d/%n&lt;br /&gt;
                }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
We need a certificate for SSL/TLS authentication, so in the example above, we use the lighttpd cert. That way when the cert is renewed/replaced, Dovecot will have access to the new cert as well.  &lt;br /&gt;
&lt;br /&gt;
Create the /etc/dovecot/dovecot-sql.conf file:&lt;br /&gt;
&lt;br /&gt;
 driver = pgsql&lt;br /&gt;
 connect = host=localhost dbname=postfix user=postfix password=********&lt;br /&gt;
 password_query = select username,password from mailbox where local_part = &#039;%n&#039; and domain = &#039;%d&#039;&lt;br /&gt;
 default_pass_scheme =  MD5-CRYPT&lt;br /&gt;
&lt;br /&gt;
Again, change the password above to your postfix user password, and protect the file from prying eyes:&lt;br /&gt;
&lt;br /&gt;
 chown root:root /etc/dovecot/dovecot-sql.conf&lt;br /&gt;
 chmod 600 /etc/dovecot/dovecot-sql.conf&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Start dovecot&lt;br /&gt;
 /etc/init.d/dovecot start&lt;br /&gt;
 rc-update add dovecot&lt;br /&gt;
&lt;br /&gt;
== Testing ==&lt;br /&gt;
&lt;br /&gt;
Make sure your firewall allows in ports 25(SMTP) 110 (POP3), 995 (POP3S), 143(IMAP), 993(IMAPS), or whatever subset you support.  &lt;br /&gt;
 &lt;br /&gt;
At this point, you should be able to:&lt;br /&gt;
 * Create a new domain and add users with PostfixAdmin&lt;br /&gt;
 * Send mail to those users via SMTP to port 25&lt;br /&gt;
 * Retrieve mail using the user&#039;s full email and password (e.g. username: user@example.com  password: ChangeM&lt;br /&gt;
&lt;br /&gt;
== Value Add Features ==&lt;br /&gt;
&lt;br /&gt;
If you followed the guide above, you now have a functional mail server with many interconnected parts.  The features below assume that the server is already running as described above.  You should be able to add any or all of these features below to further enhance the mail service.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Virus Scanning ===&lt;br /&gt;
&lt;br /&gt;
This procedure uses clamav and the postfix content_filter mechanism to scan inbound and outbound email for viruses.  Infected emails are dropped.  Clean emails are tagged with a &amp;quot;scanned by clamav&amp;quot; header.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* Install clamav and clamsmtp:&lt;br /&gt;
 apk add acf-clamav clamsmtp&lt;br /&gt;
* Edit the /etc/clamav/clamd.conf file if desired (not necessary in most cases)&lt;br /&gt;
* Edit /etc/clamsmtpd.conf and verify the following lines&lt;br /&gt;
 OutAddress: 10026&lt;br /&gt;
 Listen: 127.0.0.1:10025                                               &lt;br /&gt;
 Header: X-Virus-Scanned: ClamAV using ClamSMTP&lt;br /&gt;
 Action: drop&lt;br /&gt;
 User: clamav                                                      &lt;br /&gt;
* Start the daemons&lt;br /&gt;
 rc-update add clamd&lt;br /&gt;
 rc-update add freshclam&lt;br /&gt;
 rc-update add clamsmtp&lt;br /&gt;
 /etc/init.d/clamd start&lt;br /&gt;
 /etc/init.d/freshclam start&lt;br /&gt;
 /etc/init.d/clamsmtp start&lt;br /&gt;
* Verify clamsmtp is listening on port 10025:&lt;br /&gt;
 netstat -anp | grep clamsmtp&lt;br /&gt;
* [http://memberwebs.com/stef/software/clamsmtp/postfix.html Following the clamsmtp instructions]&lt;br /&gt;
** edit /etc/postfix/main.cf and add:&lt;br /&gt;
 content_filter = scan:[127.0.0.1]:10025                                                      &lt;br /&gt;
** edit /etc/postfix/master.cf and add&lt;br /&gt;
 # AV scan filter (used by content_filter)&lt;br /&gt;
 scan      unix  -       -       n       -       16      smtp&lt;br /&gt;
         -o smtp_send_xforward_command=yes&lt;br /&gt;
         -o smtp_enforce_tls=no&lt;br /&gt;
 # For injecting mail back into postfix from the filter&lt;br /&gt;
 127.0.0.1:10026 inet  n -       n       -       16      smtpd&lt;br /&gt;
         -o content_filter=&lt;br /&gt;
         -o receive_override_options=no_unknown_recipient_checks,no_header_body_checks&lt;br /&gt;
         -o smtpd_helo_restrictions=&lt;br /&gt;
         -o smtpd_client_restrictions=&lt;br /&gt;
         -o smtpd_sender_restrictions=&lt;br /&gt;
         -o smtpd_recipient_restrictions=permit_mynetworks,reject&lt;br /&gt;
         -o mynetworks_style=host&lt;br /&gt;
         -o smtpd_authorized_xforward_hosts=127.0.0.0/8&lt;br /&gt;
* postfix reload&lt;br /&gt;
* Send and email into a local virtual domain - it should have the &#039;&#039;X-Virus-Scanned: ClamAV using ClamSMTP&#039;&#039; header.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Relay for Authenticated Users ===&lt;br /&gt;
&lt;br /&gt;
As configured above, the mail server accepts email from the Internet, but it does not relay email.  If it is a perimeter exchanger for a protected network, then you can add the protected networks to the &#039;&#039;mynetworks&#039;&#039; configuration line in /etc/postfix/main.cf&lt;br /&gt;
&lt;br /&gt;
This configuration change allows &#039;&#039;remote&#039;&#039; users to authenticate against the mail server and relay through it.  The rules for relaying are:&lt;br /&gt;
* Only authenticated users can relay&lt;br /&gt;
* Authentication Credentials must be encrypted with TLS or SSL&lt;br /&gt;
* Allow Submission and SMTPS ports for relaying (many consumer networks block port 25 - SMTP by default)&lt;br /&gt;
The process uses the dovecot authentication mechanism (used with IMAPS) to authenticate users before they are allowed to relay through postfix.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* Edit /etc/dovecot/dovecot.conf and add:&lt;br /&gt;
 # this is for postfix SASL (authenticated users can relay through us)&lt;br /&gt;
 socket listen {&lt;br /&gt;
                client {&lt;br /&gt;
                        path    = /var/spool/postfix/private/dovecot-auth.sock&lt;br /&gt;
                        mode    = 0660&lt;br /&gt;
                        user    = postfix&lt;br /&gt;
                        group   = postfix&lt;br /&gt;
                        }&lt;br /&gt;
                }&lt;br /&gt;
        }&lt;br /&gt;
* Restart dovecot&lt;br /&gt;
 /etc/init.d/dovecot restart&lt;br /&gt;
* Edit /etc/postfix/main.cf and add:&lt;br /&gt;
 # TLS Stuff -- since we allow SASL with tls *only*, we have to set up TLS first                    &lt;br /&gt;
 &lt;br /&gt;
 smtpd_tls_cert_file = /etc/lighttpd/server-bundle.pem&lt;br /&gt;
 smtpd_tls_key_file = /etc/lighttpd/server-bundle.pem&lt;br /&gt;
 smtpd_tls_CAfile = /etc/lighttpd/ca-crt.pem&lt;br /&gt;
 # If tls_security_level is set to &amp;quot;encrypt&amp;quot;, then SMTP rejects &lt;br /&gt;
 # unencrypted email (e.g. normal mail) which is bad.&lt;br /&gt;
 # By setting it to &amp;quot;may&amp;quot; you get TLS encrypted mail from google, slashdot, and other &lt;br /&gt;
 # interesting places.  Check your logs to see who&lt;br /&gt;
 smtpd_tls_security_level = may&lt;br /&gt;
 # Log info about the negotiated encryption levels&lt;br /&gt;
 smtpd_tls_received_header = yes&lt;br /&gt;
 smtpd_tls_loglevel = 1&lt;br /&gt;
 &lt;br /&gt;
 # SASL - this allows senders to authenticiate themselves&lt;br /&gt;
 # This along with &amp;quot;permit_sasl_authenticated&amp;quot; in smtpd_recipient_restrictions allows relaying&lt;br /&gt;
 smtpd_sasl_type = dovecot&lt;br /&gt;
 smtpd_sasl_path = private/dovecot-auth.sock&lt;br /&gt;
 smtpd_sasl_auth_enable = yes&lt;br /&gt;
 smtpd_sasl_authenticated_header = yes&lt;br /&gt;
 smtpd_tls_auth_only = yes&lt;br /&gt;
* Edit /etc/postfix/master.cf and enable the submission and smtps transports.  They are probably already at the top of your  master.cf file, just commented out:&lt;br /&gt;
 submission inet n       -       n       -       -       smtpd&lt;br /&gt;
   -o smtpd_tls_security_level=encrypt&lt;br /&gt;
   -o smtpd_sasl_auth_enable=yes&lt;br /&gt;
   -o smtpd_client_restrictions=permit_sasl_authenticated,reject&lt;br /&gt;
   -o milter_macro_daemon_name=ORIGINATING&lt;br /&gt;
 smtps     inet  n       -       n       -       -       smtpd&lt;br /&gt;
   -o smtpd_tls_security_level=encrypt&lt;br /&gt;
   -o smtpd_tls_wrappermode=yes&lt;br /&gt;
   -o smtpd_sasl_auth_enable=yes&lt;br /&gt;
   -o smtpd_client_restrictions=permit_sasl_authenticated,reject&lt;br /&gt;
   -o milter_macro_daemon_name=ORIGINATING&lt;br /&gt;
*Verfiy submission and smtps are defined in /etc/services&lt;br /&gt;
 grep &amp;quot;submission\|ssmtp&amp;quot; /etc/services&lt;br /&gt;
 submission	587/tcp				# mail message submission&lt;br /&gt;
 submission	587/udp&lt;br /&gt;
 smtps		465/tcp		ssmtp		# smtp protocol over TLS/SSL&lt;br /&gt;
 smtps		465/udp		ssmtp&lt;br /&gt;
* Restart postfix&lt;br /&gt;
 postfix reload&lt;br /&gt;
&lt;br /&gt;
At this point, you should be able to set up a mail client to relay through the server with TLS (port 587) or SSL (port 465)  Note that &amp;quot;plain&amp;quot; authentication is used because the underlying link is encrypted.  For example, in Thunderbird leave &amp;quot;secure authentication&amp;quot; unchecked, and choose STARTTLS (or TLS) for the connection security.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Mailbox Quotas ===&lt;br /&gt;
&lt;br /&gt;
In the default configuration, PostfixAdmin knows about quotas, but they are not enforced.   Documentation on the web mentions the [http://vda.sourceforge.net vda patch to postifx] to enforce quotas.  The only bad thing... its a &#039;&#039;patch&#039;&#039;.   Postfix and Dovecot are both conservative systems, so if the patch isn&#039;t in the upstream source, we&#039;ll assume there&#039;s a good reason.   There is a way of using quotas without patches - and it involves using the dovecot&#039;s [http://wiki.dovecot.org/LDA deliver] lda for local delivery.&lt;br /&gt;
&lt;br /&gt;
Note: As of Jan 2010, the documention is confusing, with multiple versions of dovecot, PostfixAdmin, and Mysql referenced.  These instructions apply to:&lt;br /&gt;
* Postgresql 8.4.2 &lt;br /&gt;
* PostfixAdmin 2.3 &lt;br /&gt;
* Dovecot 1.2.10&lt;br /&gt;
* Postfix 2.6.5&lt;br /&gt;
&lt;br /&gt;
Presumably later versions will work the same, but if not, please update the documentation and versions above.&lt;br /&gt;
&lt;br /&gt;
* Update /etc/dovecot.conf (old lines shown commented out):&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
# old postfix &lt;br /&gt;
#       userdb static {&lt;br /&gt;
#               args =  uid=1006 gid=1006 home=/var/mail/domains/%d/%n&lt;br /&gt;
#               }&lt;br /&gt;
&lt;br /&gt;
# new quota support:&lt;br /&gt;
        userdb prefetch {&lt;br /&gt;
                }&lt;br /&gt;
&lt;br /&gt;
        userdb sql {&lt;br /&gt;
                args = /etc/dovecot/dovecot-sql.conf&lt;br /&gt;
                }&lt;br /&gt;
&lt;br /&gt;
        socket listen {&lt;br /&gt;
                client {&lt;br /&gt;
                        path    = /var/spool/postfix/private/dovecot-auth.sock&lt;br /&gt;
                        mode    = 0660&lt;br /&gt;
                        user    = postfix&lt;br /&gt;
                        group   = postfix&lt;br /&gt;
                        }&lt;br /&gt;
                # These lines below are for the deliver lda&lt;br /&gt;
                master {&lt;br /&gt;
                        path =  /var/run/dovecot/auth-master&lt;br /&gt;
                        mode    = 0660&lt;br /&gt;
                        user    = vmail&lt;br /&gt;
                        group   = vmail&lt;br /&gt;
                        }&lt;br /&gt;
                }&lt;br /&gt;
 &lt;br /&gt;
protocol imap {                                                               &lt;br /&gt;
         mail_plugins = quota imap_quota                                       &lt;br /&gt;
         }                                                                     &lt;br /&gt;
                                                                              &lt;br /&gt;
protocol pop3 {                                                               &lt;br /&gt;
         mail_plugins = quota                                                  &lt;br /&gt;
         }                                                                     &lt;br /&gt;
                                                                              &lt;br /&gt;
dict {                                                                        &lt;br /&gt;
        quotadict = pgsql:/etc/dovecot/dovecot-dict-quota.conf                &lt;br /&gt;
        }                                                                     &lt;br /&gt;
                                                                              &lt;br /&gt;
plugin {                                                                      &lt;br /&gt;
         quota = dict:user::proxy::quotadict                                   &lt;br /&gt;
         }                                                     &lt;br /&gt;
                                                              &lt;br /&gt;
protocol lda {                                                &lt;br /&gt;
   postmaster_address = postmaster@host.example.com&lt;br /&gt;
   mail_plugins = quota                                        &lt;br /&gt;
   auth_socket_path =  /var/run/dovecot/auth-master&lt;br /&gt;
   sendmail_path = /usr/sbin/sendmail&lt;br /&gt;
}                                                                            &lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
 &lt;br /&gt;
You should already have a &amp;lt;tt&amp;gt;socket-&amp;gt; listen-&amp;gt; client&amp;lt;/tt&amp;gt; section, but it is listed above to show where it goes in relationship to the &amp;lt;tt&amp;gt;socket -&amp;gt; listen -&amp;gt; master&amp;lt;/tt&amp;gt; section&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* edit &amp;lt;tt&amp;gt;/etc/dovecot/dovecot-sql.conf&amp;lt;/tt&amp;gt; and replace the user and password queries with the following (you may not have a user_query yet - add it):&lt;br /&gt;
&lt;br /&gt;
 password_query = select username as user, password, 1006 as userdb_uid, 1006 as userdb_gid, &#039;*:bytes=&#039; || quota as userdb_quota_rule from mailbox  where local_part = &#039;%n&#039; and domain = &#039;%d&#039;&lt;br /&gt;
 user_query = select maildir as home, 1006 as uid, 1006 as gid, &#039;*:bytes=&#039; || quota  as quota_rule from mailbox where local_part = &#039;%n&#039; and domain =&#039;%d&#039;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* create &amp;lt;tt&amp;gt;/etc/dovecot/dovecot-dict-quota.conf&amp;lt;/tt&amp;gt;&lt;br /&gt;
 connect = host=localhost dbname=postfix user=postfix password=********&lt;br /&gt;
 &lt;br /&gt;
 map {&lt;br /&gt;
         pattern = priv/quota/storage&lt;br /&gt;
         table = quota2&lt;br /&gt;
         username_field =username&lt;br /&gt;
         value_field = bytes&lt;br /&gt;
 }&lt;br /&gt;
 &lt;br /&gt;
 map {&lt;br /&gt;
        pattern= priv/quota/messages&lt;br /&gt;
        table = quota2&lt;br /&gt;
        username_field = username&lt;br /&gt;
        value_field = messages&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
Side note: [http://wiki.dovecot.org/Quota/Dict The Dovecot Quota Documentation] mentions the need for a trigger with pgsql.  This was created in the PostfixAdmin install, which is why you instantiated the pgsql language when creating the database.  If not, you will need to create the trigger, to reference the quota2 table, not the quota table mentioned in the dovecot docs.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* create a new transport for the dovecot lda.   Add the following to  /etc/postfix/master.cf:&lt;br /&gt;
 # The dovecot deliver lda&lt;br /&gt;
 dovecot   unix  -       n       n       -       -       pipe&lt;br /&gt;
   flags=DRhu user=vmail:vmail argv=/usr/libexec/dovecot/deliver -f ${sender} -d ${user}@${nexthop}&lt;br /&gt;
&lt;br /&gt;
* Edit the /etc/postfix/main.cf.  Replace &lt;br /&gt;
 virtual_transport = virtual &lt;br /&gt;
with&lt;br /&gt;
 virtual_transport = dovecot&lt;br /&gt;
 dovecot_destination_recipient_limit = 1&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;TODO&#039;&#039;&#039;  This will cause over-quota emails to bounce.   Which could be a source of backscatter.   We need a way of checking quota limits after RBL checking but before the message is accepted in the queue.&lt;br /&gt;
&lt;br /&gt;
=== WebMail (RoundCube) ===&lt;br /&gt;
&lt;br /&gt;
[http://roundcube.net/ RoundCube] is an &amp;quot;ajax /Web2.0&amp;quot; web-mail client.  These instructions are for the Alpine Linux 1.10 repository &lt;br /&gt;
&lt;br /&gt;
* Add the package and related php modules:&lt;br /&gt;
 apk add roundcubemail php-xml php-openssl php-mcrypt php-gd php-iconv&lt;br /&gt;
&lt;br /&gt;
* link the roundcube application back into the docroot&lt;br /&gt;
 ln -s /usr/share/webapps/roundcube /var/www/domains/host.example.com/www/roundcube&lt;br /&gt;
&lt;br /&gt;
* follow the instructions in /usr/share/webapps/roundcube/INSTALL:&lt;br /&gt;
 chown -R lighttpd:lighttpd temp logs&lt;br /&gt;
 &lt;br /&gt;
 su postgres&lt;br /&gt;
 createuser roundcube&lt;br /&gt;
   Shall the new role be a superuser? (y/n) n&lt;br /&gt;
   Shall the new role be allowed to create databases? (y/n) n&lt;br /&gt;
   Shall the new role be allowed to create more new roles? (y/n) y&lt;br /&gt;
 createdb -O roundcube -E UNICODE -T template0 roundcubemail&lt;br /&gt;
 psql roundcubemail&lt;br /&gt;
   roundcubemail=# ALTER USER roundcube WITH PASSWORD &#039;the_new_password&#039;;&lt;br /&gt;
   roundcubemail=# \c - roundcube&lt;br /&gt;
   \i /usr/share/webapps/roundcube/SQL/postgres.initial.sql&lt;br /&gt;
   \q&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* restart lighttpd to verify the new php libraries are used&lt;br /&gt;
 /etc/init.d/lighttpd restart&lt;br /&gt;
&lt;br /&gt;
* Point your browser to http://host.example.com/roundcube/installer&lt;br /&gt;
** Begin installation&lt;br /&gt;
** Follow the instructions in step 3 of the install to copy the files to the server&lt;br /&gt;
* edit /etc/php/php.ini and edit date.timezone to your local timezone, or to UTC&lt;br /&gt;
* if necessary (e.g. you had to reset the local timezone) restart lighttpd to reload php&lt;br /&gt;
 /etc/init.d/lighttpd restart&lt;br /&gt;
* You should now be able to get to roundcube at http://host.example.com/roundcube&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
For the specific configuration parameters in the install step:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!Property&lt;br /&gt;
!Setting&lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;enable_spellcheck&#039;&#039; ||   disabled &lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;identities_level&#039;&#039; ||  one identity with possibility to edit all params but not email address &lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;log driver&#039;&#039; || syslog &lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;sylog_id&#039;&#039; || roundcube &lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;syslog_facility&#039;&#039; || mailsubsystem &lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;db_dnsw&#039;&#039; || pgsql properties, as described above &lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;imap_host&#039;&#039; || 127.0.0.1 &lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;auto_create_user&#039;&#039; || enabled &lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;smtp_server&#039;&#039; ||  127.0.0.1&lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;smtp_port&#039;&#039; ||  25&lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;smtp_user/smtp_pass&#039;&#039; ||  enable &#039;&#039;Use Current IMAP username and password for SMTP authentication&#039;&#039;&lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;smtp_log&#039;&#039; ||  enable (optional, but gives additional log record)&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
The other items can be left at default settings, or adjusted if desired.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
After its working, the INSTALL file recommends removing the install directory.   If you want to keep the installer around later, you can simply change the ownership and permissions.  So do &#039;&#039;&#039;one&#039;&#039;&#039; of the following:&lt;br /&gt;
 cd /usr/share/webapps/roundcube&lt;br /&gt;
 rm -rf LICENSE UPGRADING INSTALL README CHANGELOG  SQL installer&lt;br /&gt;
or&lt;br /&gt;
 cd /usr/share/webapps/roundcube&lt;br /&gt;
 chown -R root:root LICENSE UPGRADING INSTALL README CHANGELOG  SQL installer&lt;br /&gt;
 chmod -R 600 LICENSE UPGRADING INSTALL README CHANGELOG SQL &lt;br /&gt;
 chmod 700 SQL installer&lt;br /&gt;
&lt;br /&gt;
== log rotation ==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
Special thanks to DHughes for providing a 3 page email on how to set up postgres,postfix,PostfixAdmin,dovecot and roundcube.  It was the clearer than all the other guides available on the Net. Thanks!&lt;/div&gt;</summary>
		<author><name>Djhughes</name></author>
	</entry>
	<entry>
		<id>https://wiki.alpinelinux.org/w/index.php?title=ISP_Mail_Server_HowTo&amp;diff=3349</id>
		<title>ISP Mail Server HowTo</title>
		<link rel="alternate" type="text/html" href="https://wiki.alpinelinux.org/w/index.php?title=ISP_Mail_Server_HowTo&amp;diff=3349"/>
		<updated>2010-02-16T09:09:07Z</updated>

		<summary type="html">&lt;p&gt;Djhughes: Undo revision 3348 by Djhughes (Talk) - removed incorrect domain name&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== A Full Service Mail Server ==&lt;br /&gt;
&lt;br /&gt;
The goal of this document is to describe how to set up postfix, dovecot, clamav, dspam, roundecube, and postfixadmin for a full-featured &amp;quot;ISP&amp;quot; level mail server.&lt;br /&gt;
&lt;br /&gt;
The server must provide:&lt;br /&gt;
&lt;br /&gt;
* multiple virtual domains&lt;br /&gt;
* admins for each domain (to add/remove virtual accounts)&lt;br /&gt;
* Quota support per domain / account&lt;br /&gt;
* downloading email via IMAP / IMAPS / POP3 / POP3S&lt;br /&gt;
* relaying email for authenticated users with TLS or SSL (Submission / SMTPS protocol)&lt;br /&gt;
* Standard filters (virus/spam/rbl/etc)&lt;br /&gt;
* Web mail client&lt;br /&gt;
* Value Add services&lt;br /&gt;
&lt;br /&gt;
== Configure DNS ==&lt;br /&gt;
&lt;br /&gt;
This server will host three separate virtual domains on the same web server. They will be distinguished by their DNS names, so you must choose three domains for the three separate services:&lt;br /&gt;
&lt;br /&gt;
* ACF - Alpine Configuration Framework for managing the server&lt;br /&gt;
* PostfixAdmin - for managing the postfix installation&lt;br /&gt;
* RoundCube - for accessing individual mailboxes&lt;br /&gt;
&lt;br /&gt;
Choose three different domains (from here on known as ACF_DOMAIN, POSTFIXADMIN_DOMAIN, and ROUNDCUBE_DOMAIN) and configure DNS for all three to point to the IP address of your host. These should be DNS A records.&lt;br /&gt;
&lt;br /&gt;
== Set up Lighttpd + PHP ==&lt;br /&gt;
&lt;br /&gt;
PostfixAdmin needs php pgpsql and imap modules, so we do it in this step.&lt;br /&gt;
&lt;br /&gt;
  apk add lighttpd php php-pgsql php-imap&lt;br /&gt;
&lt;br /&gt;
Stop and remove mini_httpd, and move ACF to lighttpd;  We are setting this up to be a multi-domain virtual web server (replace ACF_DOMAIN with the actual domain):&lt;br /&gt;
&lt;br /&gt;
  mkdir -p /var/www/domains/ACF_DOMAIN&lt;br /&gt;
  ln -s /usr/share/acf/www /var/www/domains/ACF_DOMAIN/www&lt;br /&gt;
&lt;br /&gt;
Edit /etc/lighttpd/mod_cgi.conf to serve haserl files by adding a &amp;quot;&amp;quot; =&amp;gt; &amp;quot;&amp;quot; cgi handler&lt;br /&gt;
&lt;br /&gt;
 $HTTP[&amp;quot;url&amp;quot;] =~ &amp;quot;^/cgi-bin/&amp;quot; {&lt;br /&gt;
     # disable directory listings&lt;br /&gt;
     dir-listing.activate = &amp;quot;disable&amp;quot;&lt;br /&gt;
     # only allow cgi&#039;s in this directory&lt;br /&gt;
     cgi.assign = (&lt;br /&gt;
 		&amp;quot;.pl&amp;quot;	=&amp;gt;	&amp;quot;/usr/bin/perl&amp;quot;,&lt;br /&gt;
 		&amp;quot;.cgi&amp;quot;	=&amp;gt;	&amp;quot;/usr/bin/perl&amp;quot;,&lt;br /&gt;
 		&amp;quot;&amp;quot; =&amp;gt; &amp;quot;&amp;quot;&lt;br /&gt;
 	)&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
Add these lines to /etc/lighttpd/lighttpd.conf to point to the new document root, and set it up to listen on port 443 (replace &#039;&#039;ROUNDCUBE_DOMAIN&#039;&#039; with the roundcube domain and &#039;&#039;ip_address_of_server&#039;&#039; with the actual IP address):&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
 simple-vhost.server-root   = &amp;quot;/var/www/domains/&amp;quot;&lt;br /&gt;
 simple-vhost.default-host  = &amp;quot;/ROUNDCUBE_DOMAIN/&amp;quot;&lt;br /&gt;
 simple-vhost.document-root = &amp;quot;www/&amp;quot;&lt;br /&gt;
&lt;br /&gt;
 $HTTP[&amp;quot;host&amp;quot;] == &amp;quot;POSTFIXADMIN_DOMAIN&amp;quot; {&lt;br /&gt;
	simple-vhost.server-root   = &amp;quot;/var/www/domains/&amp;quot;&lt;br /&gt;
	simple-vhost.default-host  = &amp;quot;/POSTFIXADMIN_DOMAIN/&amp;quot;&lt;br /&gt;
	simple-vhost.document-root = &amp;quot;www/&amp;quot;&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
 $HTTP[&amp;quot;host&amp;quot;] == &amp;quot;ACF_DOMAIN&amp;quot; {&lt;br /&gt;
	simple-vhost.server-root   = &amp;quot;/var/www/domains/&amp;quot;&lt;br /&gt;
	simple-vhost.default-host  = &amp;quot;/ACF_DOMAIN/&amp;quot;&lt;br /&gt;
	simple-vhost.document-root = &amp;quot;www/&amp;quot;&lt;br /&gt;
 } &lt;br /&gt;
 $SERVER[&amp;quot;socket&amp;quot;] == &amp;quot;ip_address_of_server:443&amp;quot; {&lt;br /&gt;
 ssl.engine    = &amp;quot;enable&amp;quot;&lt;br /&gt;
 ssl.pemfile   = &amp;quot;/etc/lighttpd/server-bundle.pem&amp;quot;&lt;br /&gt;
 ssl.ca-file   = &amp;quot;/etc/lighttpd/ca-crt.pem&amp;quot;&lt;br /&gt;
 }&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Ensure that the simple_vhosts module is loaded, as well as the cgi config scripts by uncommenting the following lines in /etc/lighttpd/lighttpd.conf&lt;br /&gt;
&lt;br /&gt;
 server.modules = (&lt;br /&gt;
     #  other modules may be listed&lt;br /&gt;
     &amp;quot;mod_simple_vhost&amp;quot;, &lt;br /&gt;
     #  other modules may be listed&lt;br /&gt;
  .&lt;br /&gt;
  .&lt;br /&gt;
  .&lt;br /&gt;
     include &amp;quot;mod_cgi.conf&amp;quot;&lt;br /&gt;
 &lt;br /&gt;
     include &amp;quot;mod_fastcgi.conf&amp;quot;&lt;br /&gt;
 &lt;br /&gt;
&lt;br /&gt;
Get a web certificate, and install it.  If you want to use a self-signed cert, you can use [[Generating SSL certs with ACF]] or [[Generating SSL certs with ACF 1.9]].  If you create a certificate with ACF, you can create the &amp;quot;server-bundle.pem&amp;quot; and the &amp;quot;ca-crt.pem&amp;quot; file with these commands:&lt;br /&gt;
&lt;br /&gt;
  openssl pkcs12 -nokeys -cacerts -in certificate.pfx  -out /etc/lighttpd/ca-crt.pem&lt;br /&gt;
  openssl pkcs12 -nodes -in certifcate.pfx -out /etc/lighttpd/server-bundle.pem&lt;br /&gt;
  chown root:root /etc/lighttpd/server-bundle.pem&lt;br /&gt;
  chmod 400 /etc/lighttpd/server-bundle.pem&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Note:&#039;&#039;&#039; The server certificate &#039;&#039;and&#039;&#039; key are in the server-bundle.pem file, so it is critical that the file be read-only by user &amp;quot;root&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
 Editme: We should probably only serve ACF to restricted hosts&lt;br /&gt;
&lt;br /&gt;
Stop and remove mini_httpd; start lighttpd, test&lt;br /&gt;
&lt;br /&gt;
  /etc/init.d/mini_httpd stop&lt;br /&gt;
  rc-update del mini_httpd&lt;br /&gt;
  apk del mini_httpd&lt;br /&gt;
  rc-update add lighttpd&lt;br /&gt;
  /etc/init.d/lighttpd start&lt;br /&gt;
&lt;br /&gt;
At this point you should be able to see ACF being served with lighttpd:  https://ACF_DOMAIN/&lt;br /&gt;
&lt;br /&gt;
== Install Postgresql ==&lt;br /&gt;
&lt;br /&gt;
Add and configure postgresql&lt;br /&gt;
&lt;br /&gt;
  apk add acf-postgresql postgresql-client&lt;br /&gt;
  /etc/init.d/postgresql setup&lt;br /&gt;
  /etc/init.d/postgresql start&lt;br /&gt;
  rc-update add postgresql&lt;br /&gt;
&lt;br /&gt;
At this point any user can connect to the sql server with &amp;quot;trust&amp;quot; mechanism.  If you want to enforce password authentication (you probably do) edit /var/lib/postgresql/8.4/data/pg_hba.conf&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
  Editme: What should we recommend?&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Create the postfix database:&lt;br /&gt;
&lt;br /&gt;
  psql -U postgres&lt;br /&gt;
   create user postfix with password &#039;******&#039;;&lt;br /&gt;
   create database postfix owner postfix;&lt;br /&gt;
   \c postfix&lt;br /&gt;
   create language plpgsql;&lt;br /&gt;
   \q&lt;br /&gt;
&lt;br /&gt;
(Of course, use your selected password where ******* is shown above.)&lt;br /&gt;
&lt;br /&gt;
== Install PostfixAdmin ==&lt;br /&gt;
&lt;br /&gt;
We are going to install the postfix admin web front-end before we install the mail server.  This just creates an interface to populate the SQL tables that postfix and dovecot will use.&lt;br /&gt;
&lt;br /&gt;
Download PostfixAdmin from Sourceforge.  When these instructions were written, 2.3 was the current release, so (replace POSTFIXADMIN_DOMAIN with the actual domain):&lt;br /&gt;
 wget http://downloads.sourceforge.net/project/postfixadmin/postfixadmin/postfixadmin_2.3.tar.gz&lt;br /&gt;
 tar zxvf postfixadmin_2.3.tar.gz&lt;br /&gt;
 mkdir -p /var/www/domains/POSTFIXADMIN_DOMAIN/www&lt;br /&gt;
 mv postfixadmin-2.3/* /var/www/domains/POSTFIXADMIN_DOMAIN/www&lt;br /&gt;
 rm -rf postfixadmin*&lt;br /&gt;
&lt;br /&gt;
Edit /var/www/domains/POSTFIXADMIN_DOMAIN/www/config.inc.php and modify at least these lines (replace POSTFIXADMIN_DOMAIN with the actual domain):&lt;br /&gt;
&lt;br /&gt;
 $CONF[&#039;configured&#039;] = true;&lt;br /&gt;
 $CONF[&#039;setup_password&#039;] = &amp;quot;&amp;quot;;  &amp;lt;&amp;lt; Don&#039;t change this yet&lt;br /&gt;
 $CONF[&#039;database_type&#039;] = &#039;pgsql&#039;;&lt;br /&gt;
 $CONF[&#039;database_host&#039;] = &#039;localhost&#039;;&lt;br /&gt;
 $CONF[&#039;database_user&#039;] = &#039;postfix&#039;;&lt;br /&gt;
 $CONF[&#039;database_password&#039;] = &#039;*****&#039;;   &amp;lt;&amp;lt; The password you chose above&lt;br /&gt;
 $CONF[&#039;database_name&#039;] = &#039;postfix&#039;;&lt;br /&gt;
 $CONF[&#039;database_prefix&#039;] = &#039;&#039;;&lt;br /&gt;
 $CONF[&#039;admin_email&#039;] = &#039;you@some.email.com&#039;;  &amp;lt;&amp;lt; Your email address &lt;br /&gt;
 $CONF[&#039;encrypt&#039;] = &#039;md5crypt&#039;;&lt;br /&gt;
 $CONF[&#039;authlib_default_flavor&#039;] = &#039;md5raw&#039;;&lt;br /&gt;
 $CONF[&#039;dovecotpw&#039;] = &amp;quot;/usr/sbin/dovecotpw&amp;quot;;&lt;br /&gt;
 $CONF[&#039;domain_path&#039;] = &#039;YES&#039;;&lt;br /&gt;
 $CONF[&#039;domain_in_mailbox&#039;] = &#039;NO&#039;;&lt;br /&gt;
 $CONF[&#039;aliases&#039;] = &#039;10&#039;;                       &lt;br /&gt;
 $CONF[&#039;mailboxes&#039;] = &#039;10&#039;;&lt;br /&gt;
 $CONF[&#039;maxquota&#039;] = &#039;10&#039;;&lt;br /&gt;
 $CONF[&#039;vacation&#039;] = &#039;NO&#039;; &lt;br /&gt;
 $CONF[&#039;vacation_control&#039;] =&#039;NO&#039;;&lt;br /&gt;
 $CONF[&#039;vacation_control_admin&#039;] = &#039;NO&#039;;&lt;br /&gt;
 $CONF[&#039;create_mailbox_subdirs_prefix&#039;]=&amp;quot;&amp;quot;;  &lt;br /&gt;
 $CONF[&#039;quota&#039;] = &#039;YES&#039;;&lt;br /&gt;
 $CONF[&#039;quota_multiplier&#039;] = &#039;1024000&#039;;&lt;br /&gt;
 $CONF[&#039;used_quotas&#039;] = &#039;YES&#039;;   &lt;br /&gt;
 $CONF[&#039;new_quota_table&#039;] = &#039;YES&#039;;  &lt;br /&gt;
 $CONF[&#039;alias_control&#039;] = &#039;YES&#039;;&lt;br /&gt;
 $CONF[&#039;alias_control_admin&#039;] = &#039;YES&#039;;&lt;br /&gt;
 $CONF[&#039;special_alias_control&#039;] = &#039;YES&#039;;&lt;br /&gt;
 $CONF[&#039;fetchmail&#039;] = &#039;NO&#039;;&lt;br /&gt;
 $CONF[&#039;user_footer_link&#039;] = &amp;quot;http://POSTFIXADMIN_DOMAIN&amp;quot;;&lt;br /&gt;
 $CONF[&#039;footer_link&#039;] = &#039;http://POSTFIXADMIN_DOMAIN/main.php&#039;;&lt;br /&gt;
&lt;br /&gt;
You should further edit /var/www/domains/POSTFIXADMIN_DOMAIN/www/config.inc.php and replace all instances of &amp;quot;change-this-to-your.domain.tld&amp;quot; with your actual mail domain.&lt;br /&gt;
&lt;br /&gt;
Go to http://POSTFIXADMIN_DOMAIN/setup.php&lt;br /&gt;
&lt;br /&gt;
Create the password hash, add it to the config.inc.php file&lt;br /&gt;
&lt;br /&gt;
Go back to http://POSTFIXADMIN_DOMAIN/setup.php&lt;br /&gt;
&lt;br /&gt;
Create superadmin account.&lt;br /&gt;
&lt;br /&gt;
== Install Postfix ==&lt;br /&gt;
&lt;br /&gt;
Create a user for the virtual mail delivery, and get its uid/gid (you&#039;ll need the numeric uid/gid for postfix)&lt;br /&gt;
&lt;br /&gt;
 adduser vmail -H -D -s /bin/false&lt;br /&gt;
 grep vmail /etc/passwd&lt;br /&gt;
&lt;br /&gt;
(In examples below, we use 1006/1006 for the uid/gid)&lt;br /&gt;
&lt;br /&gt;
Create the mail directory, and assign vmail as the owner&lt;br /&gt;
 mkdir -p /var/mail/domains&lt;br /&gt;
 chown -R vmail:vmail /var/mail/domains&lt;br /&gt;
 &lt;br /&gt;
&lt;br /&gt;
Install postfix&lt;br /&gt;
&lt;br /&gt;
 apk add acf-postfix postfix-pgsql&lt;br /&gt;
&lt;br /&gt;
Edit the /etc/postfix/main.cf file  Here&#039;s an example:&lt;br /&gt;
&lt;br /&gt;
 myhostname=host.example.com&lt;br /&gt;
 mydomain=example.com&lt;br /&gt;
 &lt;br /&gt;
 mydestination = localhost.$mydomains, localhost&lt;br /&gt;
 mynetworks_style = subnet&lt;br /&gt;
 mynetworks = 127.0.0.0/8&lt;br /&gt;
 &lt;br /&gt;
 virtual_mailbox_domains = proxy:pgsql:/etc/postfix/sql/pgsql_virtual_domains_maps.cf&lt;br /&gt;
 virtual_alias_maps = proxy:pgsql:/etc/postfix/sql/pgsql_virtual_alias_maps.cf,&lt;br /&gt;
        proxy:pgsql:/etc/postfix/sql/pgsql_virtual_alias_domain_maps.cf,&lt;br /&gt;
        proxy:pgsql:/etc/postfix/sql/pgsql_virtual_alias_domain_catchall_maps.cf&lt;br /&gt;
 &lt;br /&gt;
 virtual_mailbox_maps = proxy:pgsql:/etc/postfix/sql/pgsql_virtual_mailbox_maps.cf,&lt;br /&gt;
        proxy:pgsql:/etc/postfix/sql/pgsql_virtual_alias_domain_mailbox_maps.cf&lt;br /&gt;
 &lt;br /&gt;
 virtual_mailbox_base = /var/mail/domains/&lt;br /&gt;
 virtual_gid_maps = static:1006&lt;br /&gt;
 virtual_uid_maps = static:1006&lt;br /&gt;
 virtual_minimum_uid = 100&lt;br /&gt;
 virtual_transport = virtual&lt;br /&gt;
 &lt;br /&gt;
 &lt;br /&gt;
 # This next command means you must create a virtual&lt;br /&gt;
 # domain for the host itself - ALL mail goes through&lt;br /&gt;
 # The virtual transport&lt;br /&gt;
 &lt;br /&gt;
 mailbox_transport = virtual&lt;br /&gt;
 local_transport = virtual&lt;br /&gt;
 local_transport_maps = $virtual_mailbox_maps&lt;br /&gt;
 &lt;br /&gt;
 smtpd_helo_required = yes&lt;br /&gt;
 disable_vrfy_command = yes&lt;br /&gt;
 message_size_limit = 10240000&lt;br /&gt;
 queue_minfree = 51200000&lt;br /&gt;
 &lt;br /&gt;
 smtpd_sender_restrictions =&lt;br /&gt;
        permit_mynetworks,&lt;br /&gt;
        reject_non_fqdn_sender,&lt;br /&gt;
        reject_unknown_sender_domain&lt;br /&gt;
 &lt;br /&gt;
 smtpd_recipient_restrictions =&lt;br /&gt;
        reject_non_fqdn_recipient,&lt;br /&gt;
        reject_unknown_recipient_domain,&lt;br /&gt;
        permit_mynetworks,&lt;br /&gt;
        permit_sasl_authenticated,&lt;br /&gt;
        reject_unauth_destination,&lt;br /&gt;
        reject_rbl_client dnsbl.sorbs.net,&lt;br /&gt;
        reject_rbl_client zen.spamhaus.org,&lt;br /&gt;
        reject_rbl_client bl.spamcop.net&lt;br /&gt;
 &lt;br /&gt;
 smtpd_data_restrictions = reject_unauth_pipelining&lt;br /&gt;
 &lt;br /&gt;
 # we will use this later - This prevents cleartext authentication&lt;br /&gt;
 # for relaying&lt;br /&gt;
 smtpd_tls_auth_only = yes&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Now we need to create a *bunch* of files so that postfix can get the delivery information out of sql. Here&#039;s a shell script to create the scripts.  Change PGPW to the password for the postfix user of the postfix SQL database.&lt;br /&gt;
&lt;br /&gt;
 cd /etc/postfix&lt;br /&gt;
 mkdir sql&lt;br /&gt;
 PGPW=&amp;quot;ChangeMe&amp;quot;&lt;br /&gt;
 &lt;br /&gt;
 cat - &amp;lt;&amp;lt;EOF &amp;gt;sql/pgsql_virtual_alias_domain_catchall_maps.cf&lt;br /&gt;
 user=postfix&lt;br /&gt;
 password = $PGPW&lt;br /&gt;
 hosts = localhost&lt;br /&gt;
 dbname = postfix&lt;br /&gt;
 query = Select goto From alias,alias_domain where alias_domain.alias_domain = &#039;%d&#039; and alias.address = &#039;@&#039; ||  alias_domain.target_domain and alias.active = true and alias_domain.active= true &lt;br /&gt;
 EOF&lt;br /&gt;
 &lt;br /&gt;
 cat - &amp;lt;&amp;lt;EOF &amp;gt;sql/pgsql_virtual_alias_domain_mailbox_maps.cf&lt;br /&gt;
 user=postfix&lt;br /&gt;
 password = $PGPW&lt;br /&gt;
 hosts = localhost&lt;br /&gt;
 dbname = postfix&lt;br /&gt;
 query = Select maildir from mailbox,alias_domain where alias_domain.alias_domain = &#039;%d&#039; and mailbox.username = &#039;%u&#039; || &#039;@&#039; || alias_domain.target_domain and mailbox.active = true and alias_domain.active&lt;br /&gt;
 EOF&lt;br /&gt;
 &lt;br /&gt;
 cat - &amp;lt;&amp;lt;EOF &amp;gt;sql/pgsql_virtual_alias_domain_maps.cf&lt;br /&gt;
 user=postfix&lt;br /&gt;
 password = $PGPW&lt;br /&gt;
 hosts = localhost&lt;br /&gt;
 dbname = postfix&lt;br /&gt;
 query = select goto from alias,alias_domain where alias_domain.alias_domain=&#039;%d&#039; and alias.address = &#039;%u&#039; || &#039;@&#039; || alias_domain.target_domain and alias.active= true and alias_domain.active= true&lt;br /&gt;
 EOF&lt;br /&gt;
 &lt;br /&gt;
 cat - &amp;lt;&amp;lt;EOF &amp;gt;sql/pgsql_virtual_alias_maps.cf&lt;br /&gt;
 user=postfix&lt;br /&gt;
 password = $PGPW&lt;br /&gt;
 hosts = localhost&lt;br /&gt;
 dbname = postfix&lt;br /&gt;
 query = Select goto From alias Where address=&#039;%s&#039; and active =&#039;1&#039;&lt;br /&gt;
 EOF&lt;br /&gt;
 &lt;br /&gt;
 cat - &amp;lt;&amp;lt;EOF &amp;gt;sql/pgsql_virtual_domains_maps.cf&lt;br /&gt;
 user=postfix&lt;br /&gt;
 password = $PGPW&lt;br /&gt;
 hosts = localhost&lt;br /&gt;
 dbname = postfix&lt;br /&gt;
 query = Select domain from domain where domain=&#039;%s&#039; and active=&#039;1&#039;&lt;br /&gt;
 EOF&lt;br /&gt;
 &lt;br /&gt;
 cat - &amp;lt;&amp;lt;EOF &amp;gt;sql/pgsql_virtual_mailbox_maps.cf&lt;br /&gt;
 user=postfix&lt;br /&gt;
 password = $PGPW&lt;br /&gt;
 hosts = localhost&lt;br /&gt;
 dbname = postfix&lt;br /&gt;
 query = Select maildir from mailbox where username=&#039;%s&#039; and active=true&lt;br /&gt;
 EOF&lt;br /&gt;
 &lt;br /&gt;
 chown -R postfix:postfix sql&lt;br /&gt;
 chmod 640 sql/*&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
At this point you should be able to start up postfix&lt;br /&gt;
 &lt;br /&gt;
 newaliases  # so postfix is happy...&lt;br /&gt;
 /etc/init.d/postfix start&lt;br /&gt;
 rc-update add postfix&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Create a domain in PostfixAdmin and test ===&lt;br /&gt;
&lt;br /&gt;
Go to http://POSTFIXADMIN_DOMAIN/&lt;br /&gt;
&lt;br /&gt;
Log in using the superadmin account, create a domain for the local box (e.g. example.com), and create a user mailbox (e.g. root).&lt;br /&gt;
&lt;br /&gt;
From the machine, send a test message:&lt;br /&gt;
&lt;br /&gt;
 sendmail -t root@example.com&lt;br /&gt;
 subject: test&lt;br /&gt;
 .&lt;br /&gt;
 ^d&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
In /var/log/mail.log (or /var/log/messages, if you still have busybox syslogd running) you should see the message queued.  The message should be in /var/mail/domains/example.com/root/new&lt;br /&gt;
&lt;br /&gt;
== Install Dovecot ==&lt;br /&gt;
&lt;br /&gt;
Dovecot is the POP3/IMAP server to retrieve mail.&lt;br /&gt;
&lt;br /&gt;
As before, we install dovecot: &lt;br /&gt;
&lt;br /&gt;
 apk add acf-dovecot dovecot-pgsql&lt;br /&gt;
&lt;br /&gt;
edit /etc/dovecot/dovecot.conf&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 # Select only the protocols you wish to support - all are listed in the next line&lt;br /&gt;
 protocols               =       imap imaps pop pop3s&lt;br /&gt;
 log_path                =       /var/log/dovecot.log&lt;br /&gt;
 info_log_path           =       /var/log/dovecot-info.log&lt;br /&gt;
 disable_plaintext_auth  =       no&lt;br /&gt;
&lt;br /&gt;
 # Authenticated IMAP&lt;br /&gt;
 ssl                     =       yes&lt;br /&gt;
 ssl_cert_file           =       /etc/lighttpd/server-bundle.pem&lt;br /&gt;
 ssl_key_file            =       /etc/lighttpd/server-bundle.pem&lt;br /&gt;
 auth_verbose            =       yes&lt;br /&gt;
 auth_debug              =       no&lt;br /&gt;
 mail_location           =       maildir:/var/mail/domains/%d/%n&lt;br /&gt;
 auth default    {&lt;br /&gt;
        mechanisms = plain&lt;br /&gt;
        passdb sql {&lt;br /&gt;
                args = /etc/dovecot/dovecot-sql.conf&lt;br /&gt;
                }&lt;br /&gt;
        userdb static {&lt;br /&gt;
                args =  uid=1006 gid=1006 home=/var/mail/domains/%d/%n&lt;br /&gt;
                }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
We need a certificate for SSL/TLS authentication, so in the example above, we use the lighttpd cert. That way when the cert is renewed/replaced, Dovecot will have access to the new cert as well.  &lt;br /&gt;
&lt;br /&gt;
Create the /etc/dovecot/dovecot-sql.conf file:&lt;br /&gt;
&lt;br /&gt;
 driver = pgsql&lt;br /&gt;
 connect = host=localhost dbname=postfix user=postfix password=********&lt;br /&gt;
 password_query = select username,password from mailbox where local_part = &#039;%n&#039; and domain = &#039;%d&#039;&lt;br /&gt;
 default_pass_scheme =  MD5-CRYPT&lt;br /&gt;
&lt;br /&gt;
Again, change the password above to your postfix user password, and protect the file from prying eyes:&lt;br /&gt;
&lt;br /&gt;
 chown root:root /etc/dovecot/dovecot-sql.conf&lt;br /&gt;
 chmod 600 /etc/dovecot/dovecot-sql.conf&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Start dovecot&lt;br /&gt;
 /etc/init.d/dovecot start&lt;br /&gt;
 rc-update add dovecot&lt;br /&gt;
&lt;br /&gt;
== Testing ==&lt;br /&gt;
&lt;br /&gt;
Make sure your firewall allows in ports 25(SMTP) 110 (POP3), 995 (POP3S), 143(IMAP), 993(IMAPS), or whatever subset you support.  &lt;br /&gt;
 &lt;br /&gt;
At this point, you should be able to:&lt;br /&gt;
 * Create a new domain and add users with PostfixAdmin&lt;br /&gt;
 * Send mail to those users via SMTP to port 25&lt;br /&gt;
 * Retrieve mail using the user&#039;s full email and password (e.g. username: user@example.com  password: ChangeM&lt;br /&gt;
&lt;br /&gt;
== Value Add Features ==&lt;br /&gt;
&lt;br /&gt;
If you followed the guide above, you now have a functional mail server with many interconnected parts.  The features below assume that the server is already running as described above.  You should be able to add any or all of these features below to further enhance the mail service.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Virus Scanning ===&lt;br /&gt;
&lt;br /&gt;
This procedure uses clamav and the postfix content_filter mechanism to scan inbound and outbound email for viruses.  Infected emails are dropped.  Clean emails are tagged with a &amp;quot;scanned by clamav&amp;quot; header.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* Install clamav and clamsmtp:&lt;br /&gt;
 apk add acf-clamav clamsmtp&lt;br /&gt;
* Edit the /etc/clamav/clamd.conf file if desired (not necessary in most cases)&lt;br /&gt;
* Edit /etc/clamsmtpd.conf and verify the following lines&lt;br /&gt;
 OutAddress: 10026&lt;br /&gt;
 Listen: 127.0.0.1:10025                                               &lt;br /&gt;
 Header: X-Virus-Scanned: ClamAV using ClamSMTP&lt;br /&gt;
 Action: drop&lt;br /&gt;
 User: clamav                                                      &lt;br /&gt;
* Start the daemons&lt;br /&gt;
 rc-update add clamd&lt;br /&gt;
 rc-update add freshclam&lt;br /&gt;
 rc-update add clamsmtp&lt;br /&gt;
 /etc/init.d/clamd start&lt;br /&gt;
 /etc/init.d/freshclam start&lt;br /&gt;
 /etc/init.d/clamsmtp start&lt;br /&gt;
* Verify clamsmtp is listening on port 10025:&lt;br /&gt;
 netstat -anp | grep clamsmtp&lt;br /&gt;
* [http://memberwebs.com/stef/software/clamsmtp/postfix.html Following the clamsmtp instructions]&lt;br /&gt;
** edit /etc/postfix/main.cf and add:&lt;br /&gt;
 content_filter = scan:[127.0.0.1]:10025                                                      &lt;br /&gt;
** edit /etc/postfix/master.cf and add&lt;br /&gt;
 # AV scan filter (used by content_filter)&lt;br /&gt;
 scan      unix  -       -       n       -       16      smtp&lt;br /&gt;
         -o smtp_send_xforward_command=yes&lt;br /&gt;
         -o smtp_enforce_tls=no&lt;br /&gt;
 # For injecting mail back into postfix from the filter&lt;br /&gt;
 127.0.0.1:10026 inet  n -       n       -       16      smtpd&lt;br /&gt;
         -o content_filter=&lt;br /&gt;
         -o receive_override_options=no_unknown_recipient_checks,no_header_body_checks&lt;br /&gt;
         -o smtpd_helo_restrictions=&lt;br /&gt;
         -o smtpd_client_restrictions=&lt;br /&gt;
         -o smtpd_sender_restrictions=&lt;br /&gt;
         -o smtpd_recipient_restrictions=permit_mynetworks,reject&lt;br /&gt;
         -o mynetworks_style=host&lt;br /&gt;
         -o smtpd_authorized_xforward_hosts=127.0.0.0/8&lt;br /&gt;
* postfix reload&lt;br /&gt;
* Send and email into a local virtual domain - it should have the &#039;&#039;X-Virus-Scanned: ClamAV using ClamSMTP&#039;&#039; header.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Relay for Authenticated Users ===&lt;br /&gt;
&lt;br /&gt;
As configured above, the mail server accepts email from the Internet, but it does not relay email.  If it is a perimeter exchanger for a protected network, then you can add the protected networks to the &#039;&#039;mynetworks&#039;&#039; configuration line in /etc/postfix/main.cf&lt;br /&gt;
&lt;br /&gt;
This configuration change allows &#039;&#039;remote&#039;&#039; users to authenticate against the mail server and relay through it.  The rules for relaying are:&lt;br /&gt;
* Only authenticated users can relay&lt;br /&gt;
* Authentication Credentials must be encrypted with TLS or SSL&lt;br /&gt;
* Allow Submission and SMTPS ports for relaying (many consumer networks block port 25 - SMTP by default)&lt;br /&gt;
The process uses the dovecot authentication mechanism (used with IMAPS) to authenticate users before they are allowed to relay through postfix.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* Edit /etc/dovecot/dovecot.conf and add:&lt;br /&gt;
 # this is for postfix SASL (authenticated users can relay through us)&lt;br /&gt;
 socket listen {&lt;br /&gt;
                client {&lt;br /&gt;
                        path    = /var/spool/postfix/private/dovecot-auth.sock&lt;br /&gt;
                        mode    = 0660&lt;br /&gt;
                        user    = postfix&lt;br /&gt;
                        group   = postfix&lt;br /&gt;
                        }&lt;br /&gt;
                }&lt;br /&gt;
        }&lt;br /&gt;
* Restart dovecot&lt;br /&gt;
 /etc/init.d/dovecot restart&lt;br /&gt;
* Edit /etc/postfix/main.cf and add:&lt;br /&gt;
 # TLS Stuff -- since we allow SASL with tls *only*, we have to set up TLS first                    &lt;br /&gt;
 &lt;br /&gt;
 smtpd_tls_cert_file = /etc/lighttpd/server-bundle.pem&lt;br /&gt;
 smtpd_tls_key_file = /etc/lighttpd/server-bundle.pem&lt;br /&gt;
 smtpd_tls_CAfile = /etc/lighttpd/ca-crt.pem&lt;br /&gt;
 # If tls_security_level is set to &amp;quot;encrypt&amp;quot;, then SMTP rejects &lt;br /&gt;
 # unencrypted email (e.g. normal mail) which is bad.&lt;br /&gt;
 # By setting it to &amp;quot;may&amp;quot; you get TLS encrypted mail from google, slashdot, and other &lt;br /&gt;
 # interesting places.  Check your logs to see who&lt;br /&gt;
 smtpd_tls_security_level = may&lt;br /&gt;
 # Log info about the negotiated encryption levels&lt;br /&gt;
 smtpd_tls_received_header = yes&lt;br /&gt;
 smtpd_tls_loglevel = 1&lt;br /&gt;
 &lt;br /&gt;
 # SASL - this allows senders to authenticiate themselves&lt;br /&gt;
 # This along with &amp;quot;permit_sasl_authenticated&amp;quot; in smtpd_recipient_restrictions allows relaying&lt;br /&gt;
 smtpd_sasl_type = dovecot&lt;br /&gt;
 smtpd_sasl_path = private/dovecot-auth.sock&lt;br /&gt;
 smtpd_sasl_auth_enable = yes&lt;br /&gt;
 smtpd_sasl_authenticated_header = yes&lt;br /&gt;
 smtpd_tls_auth_only = yes&lt;br /&gt;
* Edit /etc/postfix/master.cf and enable the submission and smtps transports.  They are probably already at the top of your  master.cf file, just commented out:&lt;br /&gt;
 submission inet n       -       n       -       -       smtpd&lt;br /&gt;
   -o smtpd_tls_security_level=encrypt&lt;br /&gt;
   -o smtpd_sasl_auth_enable=yes&lt;br /&gt;
   -o smtpd_client_restrictions=permit_sasl_authenticated,reject&lt;br /&gt;
   -o milter_macro_daemon_name=ORIGINATING&lt;br /&gt;
 smtps     inet  n       -       n       -       -       smtpd&lt;br /&gt;
   -o smtpd_tls_security_level=encrypt&lt;br /&gt;
   -o smtpd_tls_wrappermode=yes&lt;br /&gt;
   -o smtpd_sasl_auth_enable=yes&lt;br /&gt;
   -o smtpd_client_restrictions=permit_sasl_authenticated,reject&lt;br /&gt;
   -o milter_macro_daemon_name=ORIGINATING&lt;br /&gt;
*Verfiy submission and smtps are defined in /etc/services&lt;br /&gt;
 grep &amp;quot;submission\|ssmtp&amp;quot; /etc/services&lt;br /&gt;
 submission	587/tcp				# mail message submission&lt;br /&gt;
 submission	587/udp&lt;br /&gt;
 smtps		465/tcp		ssmtp		# smtp protocol over TLS/SSL&lt;br /&gt;
 smtps		465/udp		ssmtp&lt;br /&gt;
* Restart postfix&lt;br /&gt;
 postfix reload&lt;br /&gt;
&lt;br /&gt;
At this point, you should be able to set up a mail client to relay through the server with TLS (port 587) or SSL (port 465)  Note that &amp;quot;plain&amp;quot; authentication is used because the underlying link is encrypted.  For example, in Thunderbird leave &amp;quot;secure authentication&amp;quot; unchecked, and choose STARTTLS (or TLS) for the connection security.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Mailbox Quotas ===&lt;br /&gt;
&lt;br /&gt;
In the default configuration, PostfixAdmin knows about quotas, but they are not enforced.   Documentation on the web mentions the [http://vda.sourceforge.net vda patch to postifx] to enforce quotas.  The only bad thing... its a &#039;&#039;patch&#039;&#039;.   Postfix and Dovecot are both conservative systems, so if the patch isn&#039;t in the upstream source, we&#039;ll assume there&#039;s a good reason.   There is a way of using quotas without patches - and it involves using the dovecot&#039;s [http://wiki.dovecot.org/LDA deliver] lda for local delivery.&lt;br /&gt;
&lt;br /&gt;
Note: As of Jan 2010, the documention is confusing, with multiple versions of dovecot, PostfixAdmin, and Mysql referenced.  These instructions apply to:&lt;br /&gt;
* Postgresql 8.4.2 &lt;br /&gt;
* PostfixAdmin 2.3 &lt;br /&gt;
* Dovecot 1.2.10&lt;br /&gt;
* Postfix 2.6.5&lt;br /&gt;
&lt;br /&gt;
Presumably later versions will work the same, but if not, please update the documentation and versions above.&lt;br /&gt;
&lt;br /&gt;
* Update /etc/dovecot.conf (old lines shown commented out):&lt;br /&gt;
 # old postfix &lt;br /&gt;
 #       userdb static {&lt;br /&gt;
 #               args =  uid=1006 gid=1006 home=/var/mail/domains/%d/%n&lt;br /&gt;
 #               }&lt;br /&gt;
 &lt;br /&gt;
 # new quota support:&lt;br /&gt;
        userdb prefetch {&lt;br /&gt;
                }&lt;br /&gt;
&lt;br /&gt;
        userdb sql {&lt;br /&gt;
                args = /etc/dovecot/dovecot-sql.conf&lt;br /&gt;
                }&lt;br /&gt;
&lt;br /&gt;
        socket listen {&lt;br /&gt;
                client {&lt;br /&gt;
                        path    = /var/spool/postfix/private/dovecot-auth.sock&lt;br /&gt;
                        mode    = 0660&lt;br /&gt;
                        user    = postfix&lt;br /&gt;
                        group   = postfix&lt;br /&gt;
                        }&lt;br /&gt;
                # These lines below are for the deliver lda&lt;br /&gt;
                master {&lt;br /&gt;
                        path =  /var/run/dovecot/auth-master&lt;br /&gt;
                        mode    = 0660&lt;br /&gt;
                        user    = vmail&lt;br /&gt;
                        group   = vmail&lt;br /&gt;
                        }&lt;br /&gt;
                }&lt;br /&gt;
 &lt;br /&gt;
 protocol imap {                                                               &lt;br /&gt;
         mail_plugins = quota imap_quota                                       &lt;br /&gt;
         }                                                                     &lt;br /&gt;
                                                                              &lt;br /&gt;
 protocol pop3 {                                                               &lt;br /&gt;
         mail_plugins = quota                                                  &lt;br /&gt;
         }                                                                     &lt;br /&gt;
                                                                              &lt;br /&gt;
 dict {                                                                        &lt;br /&gt;
        quotadict = pgsql:/etc/dovecot/dovecot-dict-quota.conf                &lt;br /&gt;
        }                                                                     &lt;br /&gt;
                                                                              &lt;br /&gt;
 plugin {                                                                      &lt;br /&gt;
         quota = dict:user::proxy::quotadict                                   &lt;br /&gt;
         }                                                     &lt;br /&gt;
                                                              &lt;br /&gt;
 protocol lda {                                                &lt;br /&gt;
   postmaster_address = postmaster@host.example.com&lt;br /&gt;
   mail_plugins = quota                                        &lt;br /&gt;
   auth_socket_path =  /var/run/dovecot/auth-master&lt;br /&gt;
   sendmail_path = /usr/sbin/sendmail&lt;br /&gt;
 }                                                                            &lt;br /&gt;
    &lt;br /&gt;
You should already have a &amp;lt;tt&amp;gt;socket-&amp;gt; listen-&amp;gt; client&amp;lt;/tt&amp;gt; section, but it is listed above to show where it goes in relationship to the &amp;lt;tt&amp;gt;socket -&amp;gt; listen -&amp;gt; master&amp;lt;/tt&amp;gt; section&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* edit &amp;lt;tt&amp;gt;/etc/dovecot/dovecot-sql.conf&amp;lt;/tt&amp;gt; and replace the user and password queries with the following (you may not have a user_query yet - add it):&lt;br /&gt;
&lt;br /&gt;
 password_query = select username as user, password, 1006 as userdb_uid, 1006 as userdb_gid, &#039;*:bytes=&#039; || quota as userdb_quota_rule from mailbox  where local_part = &#039;%n&#039; and domain = &#039;%d&#039;&lt;br /&gt;
 user_query = select maildir as home, 1006 as uid, 1006 as gid, &#039;*:bytes=&#039; || quota  as quota_rule from mailbox where local_part = &#039;%n&#039; and domain =&#039;%d&#039;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* create &amp;lt;tt&amp;gt;/etc/dovecot/dovecot-dict-quota.conf&amp;lt;/tt&amp;gt;&lt;br /&gt;
 connect = host=localhost dbname=postfix user=postfix password=********&lt;br /&gt;
 &lt;br /&gt;
 map {&lt;br /&gt;
         pattern = priv/quota/storage&lt;br /&gt;
         table = quota2&lt;br /&gt;
         username_field =username&lt;br /&gt;
         value_field = bytes&lt;br /&gt;
 }&lt;br /&gt;
 &lt;br /&gt;
 map {&lt;br /&gt;
        pattern= priv/quota/messages&lt;br /&gt;
        table = quota2&lt;br /&gt;
        username_field = username&lt;br /&gt;
        value_field = messages&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
Side note: [http://wiki.dovecot.org/Quota/Dict The Dovecot Quota Documentation] mentions the need for a trigger with pgsql.  This was created in the PostfixAdmin install, which is why you instantiated the pgsql language when creating the database.  If not, you will need to create the trigger, to reference the quota2 table, not the quota table mentioned in the dovecot docs.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* create a new transport for the dovecot lda.   Add the following to  /etc/postfix/master.cf:&lt;br /&gt;
 # The dovecot deliver lda&lt;br /&gt;
 dovecot   unix  -       n       n       -       -       pipe&lt;br /&gt;
   flags=DRhu user=vmail:vmail argv=/usr/libexec/dovecot/deliver -f ${sender} -d ${user}@${nexthop}&lt;br /&gt;
&lt;br /&gt;
* Edit the /etc/postfix/main.cf.  Replace &lt;br /&gt;
 virtual_transport = virtual &lt;br /&gt;
with&lt;br /&gt;
 virtual_transport = dovecot&lt;br /&gt;
 dovecot_destination_recipient_limit = 1&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;TODO&#039;&#039;&#039;  This will cause over-quota emails to bounce.   Which could be a source of backscatter.   We need a way of checking quota limits after RBL checking but before the message is accepted in the queue.&lt;br /&gt;
&lt;br /&gt;
=== WebMail (RoundCube) ===&lt;br /&gt;
&lt;br /&gt;
[http://roundcube.net/ RoundCube] is an &amp;quot;ajax /Web2.0&amp;quot; web-mail client.  These instructions are for the Alpine Linux 1.10 repository &lt;br /&gt;
&lt;br /&gt;
* Add the package and related php modules:&lt;br /&gt;
 apk add roundcubemail php-xml php-openssl php-mcrypt php-gd php-iconv&lt;br /&gt;
&lt;br /&gt;
* link the roundcube application back into the docroot&lt;br /&gt;
 ln -s /usr/share/webapps/roundcube /var/www/domains/host.example.com/www/roundcube&lt;br /&gt;
&lt;br /&gt;
* follow the instructions in /usr/share/webapps/roundcube/INSTALL:&lt;br /&gt;
 chown -R lighttpd:lighttpd temp logs&lt;br /&gt;
 &lt;br /&gt;
 su postgres&lt;br /&gt;
 createuser roundcube&lt;br /&gt;
   Shall the new role be a superuser? (y/n) n&lt;br /&gt;
   Shall the new role be allowed to create databases? (y/n) n&lt;br /&gt;
   Shall the new role be allowed to create more new roles? (y/n) y&lt;br /&gt;
 createdb -O roundcube -E UNICODE -T template0 roundcubemail&lt;br /&gt;
 psql roundcubemail&lt;br /&gt;
   roundcubemail=# ALTER USER roundcube WITH PASSWORD &#039;the_new_password&#039;;&lt;br /&gt;
   roundcubemail=# \c - roundcube&lt;br /&gt;
   \i /usr/share/webapps/roundcube/SQL/postgres.initial.sql&lt;br /&gt;
   \q&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* restart lighttpd to verify the new php libraries are used&lt;br /&gt;
 /etc/init.d/lighttpd restart&lt;br /&gt;
&lt;br /&gt;
* Point your browser to http://host.example.com/roundcube/installer&lt;br /&gt;
** Begin installation&lt;br /&gt;
** Follow the instructions in step 3 of the install to copy the files to the server&lt;br /&gt;
* edit /etc/php/php.ini and edit date.timezone to your local timezone, or to UTC&lt;br /&gt;
* if necessary (e.g. you had to reset the local timezone) restart lighttpd to reload php&lt;br /&gt;
 /etc/init.d/lighttpd restart&lt;br /&gt;
* You should now be able to get to roundcube at http://host.example.com/roundcube&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
For the specific configuration parameters in the install step:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!Property&lt;br /&gt;
!Setting&lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;enable_spellcheck&#039;&#039; ||   disabled &lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;identities_level&#039;&#039; ||  one identity with possibility to edit all params but not email address &lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;log driver&#039;&#039; || syslog &lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;sylog_id&#039;&#039; || roundcube &lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;syslog_facility&#039;&#039; || mailsubsystem &lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;db_dnsw&#039;&#039; || pgsql properties, as described above &lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;imap_host&#039;&#039; || 127.0.0.1 &lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;auto_create_user&#039;&#039; || enabled &lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;smtp_server&#039;&#039; ||  127.0.0.1&lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;smtp_port&#039;&#039; ||  25&lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;smtp_user/smtp_pass&#039;&#039; ||  enable &#039;&#039;Use Current IMAP username and password for SMTP authentication&#039;&#039;&lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;smtp_log&#039;&#039; ||  enable (optional, but gives additional log record)&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
The other items can be left at default settings, or adjusted if desired.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
After its working, the INSTALL file recommends removing the install directory.   If you want to keep the installer around later, you can simply change the ownership and permissions.  So do &#039;&#039;&#039;one&#039;&#039;&#039; of the following:&lt;br /&gt;
 cd /usr/share/webapps/roundcube&lt;br /&gt;
 rm -rf LICENSE UPGRADING INSTALL README CHANGELOG  SQL installer&lt;br /&gt;
or&lt;br /&gt;
 cd /usr/share/webapps/roundcube&lt;br /&gt;
 chown -R root:root LICENSE UPGRADING INSTALL README CHANGELOG  SQL installer&lt;br /&gt;
 chmod -R 600 LICENSE UPGRADING INSTALL README CHANGELOG SQL &lt;br /&gt;
 chmod 700 SQL installer&lt;br /&gt;
&lt;br /&gt;
== log rotation ==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
Special thanks to DHughes for providing a 3 page email on how to set up postgres,postfix,PostfixAdmin,dovecot and roundcube.  It was the clearer than all the other guides available on the Net. Thanks!&lt;/div&gt;</summary>
		<author><name>Djhughes</name></author>
	</entry>
	<entry>
		<id>https://wiki.alpinelinux.org/w/index.php?title=ISP_Mail_Server_HowTo&amp;diff=3348</id>
		<title>ISP Mail Server HowTo</title>
		<link rel="alternate" type="text/html" href="https://wiki.alpinelinux.org/w/index.php?title=ISP_Mail_Server_HowTo&amp;diff=3348"/>
		<updated>2010-02-16T09:06:12Z</updated>

		<summary type="html">&lt;p&gt;Djhughes: changed config according to what actually worked for me&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== A Full Service Mail Server ==&lt;br /&gt;
&lt;br /&gt;
The goal of this document is to describe how to set up postfix, dovecot, clamav, dspam, roundecube, and postfixadmin for a full-featured &amp;quot;ISP&amp;quot; level mail server.&lt;br /&gt;
&lt;br /&gt;
The server must provide:&lt;br /&gt;
&lt;br /&gt;
* multiple virtual domains&lt;br /&gt;
* admins for each domain (to add/remove virtual accounts)&lt;br /&gt;
* Quota support per domain / account&lt;br /&gt;
* downloading email via IMAP / IMAPS / POP3 / POP3S&lt;br /&gt;
* relaying email for authenticated users with TLS or SSL (Submission / SMTPS protocol)&lt;br /&gt;
* Standard filters (virus/spam/rbl/etc)&lt;br /&gt;
* Web mail client&lt;br /&gt;
* Value Add services&lt;br /&gt;
&lt;br /&gt;
== Configure DNS ==&lt;br /&gt;
&lt;br /&gt;
This server will host three separate virtual domains on the same web server. They will be distinguished by their DNS names, so you must choose three domains for the three separate services:&lt;br /&gt;
&lt;br /&gt;
* ACF - Alpine Configuration Framework for managing the server&lt;br /&gt;
* PostfixAdmin - for managing the postfix installation&lt;br /&gt;
* RoundCube - for accessing individual mailboxes&lt;br /&gt;
&lt;br /&gt;
Choose three different domains (from here on known as ACF_DOMAIN, POSTFIXADMIN_DOMAIN, and ROUNDCUBE_DOMAIN) and configure DNS for all three to point to the IP address of your host. These should be DNS A records.&lt;br /&gt;
&lt;br /&gt;
== Set up Lighttpd + PHP ==&lt;br /&gt;
&lt;br /&gt;
PostfixAdmin needs php pgpsql and imap modules, so we do it in this step.&lt;br /&gt;
&lt;br /&gt;
  apk add lighttpd php php-pgsql php-imap&lt;br /&gt;
&lt;br /&gt;
Stop and remove mini_httpd, and move ACF to lighttpd;  We are setting this up to be a multi-domain virtual web server (replace ACF_DOMAIN with the actual domain):&lt;br /&gt;
&lt;br /&gt;
  mkdir -p /var/www/domains/ACF_DOMAIN&lt;br /&gt;
  ln -s /usr/share/acf/www /var/www/domains/ACF_DOMAIN/www&lt;br /&gt;
&lt;br /&gt;
Edit /etc/lighttpd/mod_cgi.conf to serve haserl files by adding a &amp;quot;&amp;quot; =&amp;gt; &amp;quot;&amp;quot; cgi handler&lt;br /&gt;
&lt;br /&gt;
 $HTTP[&amp;quot;url&amp;quot;] =~ &amp;quot;^/cgi-bin/&amp;quot; {&lt;br /&gt;
     # disable directory listings&lt;br /&gt;
     dir-listing.activate = &amp;quot;disable&amp;quot;&lt;br /&gt;
     # only allow cgi&#039;s in this directory&lt;br /&gt;
     cgi.assign = (&lt;br /&gt;
 		&amp;quot;.pl&amp;quot;	=&amp;gt;	&amp;quot;/usr/bin/perl&amp;quot;,&lt;br /&gt;
 		&amp;quot;.cgi&amp;quot;	=&amp;gt;	&amp;quot;/usr/bin/perl&amp;quot;,&lt;br /&gt;
 		&amp;quot;&amp;quot; =&amp;gt; &amp;quot;&amp;quot;&lt;br /&gt;
 	)&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
Add these lines to /etc/lighttpd/lighttpd.conf to point to the new document root, and set it up to listen on port 443 (replace &#039;&#039;ROUNDCUBE_DOMAIN&#039;&#039; with the roundcube domain and &#039;&#039;ip_address_of_server&#039;&#039; with the actual IP address):&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
 simple-vhost.server-root   = &amp;quot;/var/www/domains/&amp;quot;&lt;br /&gt;
 simple-vhost.default-host  = &amp;quot;/ROUNDCUBE_DOMAIN/&amp;quot;&lt;br /&gt;
 simple-vhost.document-root = &amp;quot;www/&amp;quot;&lt;br /&gt;
&lt;br /&gt;
 $HTTP[&amp;quot;host&amp;quot;] == &amp;quot;POSTFIXADMIN_DOMAIN.rundu.zaf.wtbts.net&amp;quot; {&lt;br /&gt;
	simple-vhost.server-root   = &amp;quot;/var/www/domains/&amp;quot;&lt;br /&gt;
	simple-vhost.default-host  = &amp;quot;/POSTFIXADMIN_DOMAIN/&amp;quot;&lt;br /&gt;
	simple-vhost.document-root = &amp;quot;www/&amp;quot;&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
 $HTTP[&amp;quot;host&amp;quot;] == &amp;quot;ACF_DOMAIN.rundu.zaf.wtbts.net&amp;quot; {&lt;br /&gt;
	simple-vhost.server-root   = &amp;quot;/var/www/domains/&amp;quot;&lt;br /&gt;
	simple-vhost.default-host  = &amp;quot;/ACF_DOMAIN/&amp;quot;&lt;br /&gt;
	simple-vhost.document-root = &amp;quot;www/&amp;quot;&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
 $SERVER[&amp;quot;socket&amp;quot;] == &amp;quot;ip_address_of_server:443&amp;quot; {&lt;br /&gt;
 ssl.engine    = &amp;quot;enable&amp;quot;&lt;br /&gt;
 ssl.pemfile   = &amp;quot;/etc/lighttpd/server-bundle.pem&amp;quot;&lt;br /&gt;
 ssl.ca-file   = &amp;quot;/etc/lighttpd/ca-crt.pem&amp;quot;&lt;br /&gt;
 }&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Ensure that the simple_vhosts module is loaded, as well as the cgi config scripts by uncommenting the following lines in /etc/lighttpd/lighttpd.conf&lt;br /&gt;
&lt;br /&gt;
 server.modules = (&lt;br /&gt;
     #  other modules may be listed&lt;br /&gt;
     &amp;quot;mod_simple_vhost&amp;quot;, &lt;br /&gt;
     #  other modules may be listed&lt;br /&gt;
  .&lt;br /&gt;
  .&lt;br /&gt;
  .&lt;br /&gt;
     include &amp;quot;mod_cgi.conf&amp;quot;&lt;br /&gt;
 &lt;br /&gt;
     include &amp;quot;mod_fastcgi.conf&amp;quot;&lt;br /&gt;
 &lt;br /&gt;
&lt;br /&gt;
Get a web certificate, and install it.  If you want to use a self-signed cert, you can use [[Generating SSL certs with ACF]] or [[Generating SSL certs with ACF 1.9]].  If you create a certificate with ACF, you can create the &amp;quot;server-bundle.pem&amp;quot; and the &amp;quot;ca-crt.pem&amp;quot; file with these commands:&lt;br /&gt;
&lt;br /&gt;
  openssl pkcs12 -nokeys -cacerts -in certificate.pfx  -out /etc/lighttpd/ca-crt.pem&lt;br /&gt;
  openssl pkcs12 -nodes -in certifcate.pfx -out /etc/lighttpd/server-bundle.pem&lt;br /&gt;
  chown root:root /etc/lighttpd/server-bundle.pem&lt;br /&gt;
  chmod 400 /etc/lighttpd/server-bundle.pem&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Note:&#039;&#039;&#039; The server certificate &#039;&#039;and&#039;&#039; key are in the server-bundle.pem file, so it is critical that the file be read-only by user &amp;quot;root&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
 Editme: We should probably only serve ACF to restricted hosts&lt;br /&gt;
&lt;br /&gt;
Stop and remove mini_httpd; start lighttpd, test&lt;br /&gt;
&lt;br /&gt;
  /etc/init.d/mini_httpd stop&lt;br /&gt;
  rc-update del mini_httpd&lt;br /&gt;
  apk del mini_httpd&lt;br /&gt;
  rc-update add lighttpd&lt;br /&gt;
  /etc/init.d/lighttpd start&lt;br /&gt;
&lt;br /&gt;
At this point you should be able to see ACF being served with lighttpd:  https://ACF_DOMAIN/&lt;br /&gt;
&lt;br /&gt;
== Install Postgresql ==&lt;br /&gt;
&lt;br /&gt;
Add and configure postgresql&lt;br /&gt;
&lt;br /&gt;
  apk add acf-postgresql postgresql-client&lt;br /&gt;
  /etc/init.d/postgresql setup&lt;br /&gt;
  /etc/init.d/postgresql start&lt;br /&gt;
  rc-update add postgresql&lt;br /&gt;
&lt;br /&gt;
At this point any user can connect to the sql server with &amp;quot;trust&amp;quot; mechanism.  If you want to enforce password authentication (you probably do) edit /var/lib/postgresql/8.4/data/pg_hba.conf&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
  Editme: What should we recommend?&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Create the postfix database:&lt;br /&gt;
&lt;br /&gt;
  psql -U postgres&lt;br /&gt;
   create user postfix with password &#039;******&#039;;&lt;br /&gt;
   create database postfix owner postfix;&lt;br /&gt;
   \c postfix&lt;br /&gt;
   create language plpgsql;&lt;br /&gt;
   \q&lt;br /&gt;
&lt;br /&gt;
(Of course, use your selected password where ******* is shown above.)&lt;br /&gt;
&lt;br /&gt;
== Install PostfixAdmin ==&lt;br /&gt;
&lt;br /&gt;
We are going to install the postfix admin web front-end before we install the mail server.  This just creates an interface to populate the SQL tables that postfix and dovecot will use.&lt;br /&gt;
&lt;br /&gt;
Download PostfixAdmin from Sourceforge.  When these instructions were written, 2.3 was the current release, so (replace POSTFIXADMIN_DOMAIN with the actual domain):&lt;br /&gt;
 wget http://downloads.sourceforge.net/project/postfixadmin/postfixadmin/postfixadmin_2.3.tar.gz&lt;br /&gt;
 tar zxvf postfixadmin_2.3.tar.gz&lt;br /&gt;
 mkdir -p /var/www/domains/POSTFIXADMIN_DOMAIN/www&lt;br /&gt;
 mv postfixadmin-2.3/* /var/www/domains/POSTFIXADMIN_DOMAIN/www&lt;br /&gt;
 rm -rf postfixadmin*&lt;br /&gt;
&lt;br /&gt;
Edit /var/www/domains/POSTFIXADMIN_DOMAIN/www/config.inc.php and modify at least these lines (replace POSTFIXADMIN_DOMAIN with the actual domain):&lt;br /&gt;
&lt;br /&gt;
 $CONF[&#039;configured&#039;] = true;&lt;br /&gt;
 $CONF[&#039;setup_password&#039;] = &amp;quot;&amp;quot;;  &amp;lt;&amp;lt; Don&#039;t change this yet&lt;br /&gt;
 $CONF[&#039;database_type&#039;] = &#039;pgsql&#039;;&lt;br /&gt;
 $CONF[&#039;database_host&#039;] = &#039;localhost&#039;;&lt;br /&gt;
 $CONF[&#039;database_user&#039;] = &#039;postfix&#039;;&lt;br /&gt;
 $CONF[&#039;database_password&#039;] = &#039;*****&#039;;   &amp;lt;&amp;lt; The password you chose above&lt;br /&gt;
 $CONF[&#039;database_name&#039;] = &#039;postfix&#039;;&lt;br /&gt;
 $CONF[&#039;database_prefix&#039;] = &#039;&#039;;&lt;br /&gt;
 $CONF[&#039;admin_email&#039;] = &#039;you@some.email.com&#039;;  &amp;lt;&amp;lt; Your email address &lt;br /&gt;
 $CONF[&#039;encrypt&#039;] = &#039;md5crypt&#039;;&lt;br /&gt;
 $CONF[&#039;authlib_default_flavor&#039;] = &#039;md5raw&#039;;&lt;br /&gt;
 $CONF[&#039;dovecotpw&#039;] = &amp;quot;/usr/sbin/dovecotpw&amp;quot;;&lt;br /&gt;
 $CONF[&#039;domain_path&#039;] = &#039;YES&#039;;&lt;br /&gt;
 $CONF[&#039;domain_in_mailbox&#039;] = &#039;NO&#039;;&lt;br /&gt;
 $CONF[&#039;aliases&#039;] = &#039;10&#039;;                       &lt;br /&gt;
 $CONF[&#039;mailboxes&#039;] = &#039;10&#039;;&lt;br /&gt;
 $CONF[&#039;maxquota&#039;] = &#039;10&#039;;&lt;br /&gt;
 $CONF[&#039;vacation&#039;] = &#039;NO&#039;; &lt;br /&gt;
 $CONF[&#039;vacation_control&#039;] =&#039;NO&#039;;&lt;br /&gt;
 $CONF[&#039;vacation_control_admin&#039;] = &#039;NO&#039;;&lt;br /&gt;
 $CONF[&#039;create_mailbox_subdirs_prefix&#039;]=&amp;quot;&amp;quot;;  &lt;br /&gt;
 $CONF[&#039;quota&#039;] = &#039;YES&#039;;&lt;br /&gt;
 $CONF[&#039;quota_multiplier&#039;] = &#039;1024000&#039;;&lt;br /&gt;
 $CONF[&#039;used_quotas&#039;] = &#039;YES&#039;;   &lt;br /&gt;
 $CONF[&#039;new_quota_table&#039;] = &#039;YES&#039;;  &lt;br /&gt;
 $CONF[&#039;alias_control&#039;] = &#039;YES&#039;;&lt;br /&gt;
 $CONF[&#039;alias_control_admin&#039;] = &#039;YES&#039;;&lt;br /&gt;
 $CONF[&#039;special_alias_control&#039;] = &#039;YES&#039;;&lt;br /&gt;
 $CONF[&#039;fetchmail&#039;] = &#039;NO&#039;;&lt;br /&gt;
 $CONF[&#039;user_footer_link&#039;] = &amp;quot;http://POSTFIXADMIN_DOMAIN&amp;quot;;&lt;br /&gt;
 $CONF[&#039;footer_link&#039;] = &#039;http://POSTFIXADMIN_DOMAIN/main.php&#039;;&lt;br /&gt;
&lt;br /&gt;
You should further edit /var/www/domains/POSTFIXADMIN_DOMAIN/www/config.inc.php and replace all instances of &amp;quot;change-this-to-your.domain.tld&amp;quot; with your actual mail domain.&lt;br /&gt;
&lt;br /&gt;
Go to http://POSTFIXADMIN_DOMAIN/setup.php&lt;br /&gt;
&lt;br /&gt;
Create the password hash, add it to the config.inc.php file&lt;br /&gt;
&lt;br /&gt;
Go back to http://POSTFIXADMIN_DOMAIN/setup.php&lt;br /&gt;
&lt;br /&gt;
Create superadmin account.&lt;br /&gt;
&lt;br /&gt;
== Install Postfix ==&lt;br /&gt;
&lt;br /&gt;
Create a user for the virtual mail delivery, and get its uid/gid (you&#039;ll need the numeric uid/gid for postfix)&lt;br /&gt;
&lt;br /&gt;
 adduser vmail -H -D -s /bin/false&lt;br /&gt;
 grep vmail /etc/passwd&lt;br /&gt;
&lt;br /&gt;
(In examples below, we use 1006/1006 for the uid/gid)&lt;br /&gt;
&lt;br /&gt;
Create the mail directory, and assign vmail as the owner&lt;br /&gt;
 mkdir -p /var/mail/domains&lt;br /&gt;
 chown -R vmail:vmail /var/mail/domains&lt;br /&gt;
 &lt;br /&gt;
&lt;br /&gt;
Install postfix&lt;br /&gt;
&lt;br /&gt;
 apk add acf-postfix postfix-pgsql&lt;br /&gt;
&lt;br /&gt;
Edit the /etc/postfix/main.cf file  Here&#039;s an example:&lt;br /&gt;
&lt;br /&gt;
 myhostname=host.example.com&lt;br /&gt;
 mydomain=example.com&lt;br /&gt;
 &lt;br /&gt;
 mydestination = localhost.$mydomains, localhost&lt;br /&gt;
 mynetworks_style = subnet&lt;br /&gt;
 mynetworks = 127.0.0.0/8&lt;br /&gt;
 &lt;br /&gt;
 virtual_mailbox_domains = proxy:pgsql:/etc/postfix/sql/pgsql_virtual_domains_maps.cf&lt;br /&gt;
 virtual_alias_maps = proxy:pgsql:/etc/postfix/sql/pgsql_virtual_alias_maps.cf,&lt;br /&gt;
        proxy:pgsql:/etc/postfix/sql/pgsql_virtual_alias_domain_maps.cf,&lt;br /&gt;
        proxy:pgsql:/etc/postfix/sql/pgsql_virtual_alias_domain_catchall_maps.cf&lt;br /&gt;
 &lt;br /&gt;
 virtual_mailbox_maps = proxy:pgsql:/etc/postfix/sql/pgsql_virtual_mailbox_maps.cf,&lt;br /&gt;
        proxy:pgsql:/etc/postfix/sql/pgsql_virtual_alias_domain_mailbox_maps.cf&lt;br /&gt;
 &lt;br /&gt;
 virtual_mailbox_base = /var/mail/domains/&lt;br /&gt;
 virtual_gid_maps = static:1006&lt;br /&gt;
 virtual_uid_maps = static:1006&lt;br /&gt;
 virtual_minimum_uid = 100&lt;br /&gt;
 virtual_transport = virtual&lt;br /&gt;
 &lt;br /&gt;
 &lt;br /&gt;
 # This next command means you must create a virtual&lt;br /&gt;
 # domain for the host itself - ALL mail goes through&lt;br /&gt;
 # The virtual transport&lt;br /&gt;
 &lt;br /&gt;
 mailbox_transport = virtual&lt;br /&gt;
 local_transport = virtual&lt;br /&gt;
 local_transport_maps = $virtual_mailbox_maps&lt;br /&gt;
 &lt;br /&gt;
 smtpd_helo_required = yes&lt;br /&gt;
 disable_vrfy_command = yes&lt;br /&gt;
 message_size_limit = 10240000&lt;br /&gt;
 queue_minfree = 51200000&lt;br /&gt;
 &lt;br /&gt;
 smtpd_sender_restrictions =&lt;br /&gt;
        permit_mynetworks,&lt;br /&gt;
        reject_non_fqdn_sender,&lt;br /&gt;
        reject_unknown_sender_domain&lt;br /&gt;
 &lt;br /&gt;
 smtpd_recipient_restrictions =&lt;br /&gt;
        reject_non_fqdn_recipient,&lt;br /&gt;
        reject_unknown_recipient_domain,&lt;br /&gt;
        permit_mynetworks,&lt;br /&gt;
        permit_sasl_authenticated,&lt;br /&gt;
        reject_unauth_destination,&lt;br /&gt;
        reject_rbl_client dnsbl.sorbs.net,&lt;br /&gt;
        reject_rbl_client zen.spamhaus.org,&lt;br /&gt;
        reject_rbl_client bl.spamcop.net&lt;br /&gt;
 &lt;br /&gt;
 smtpd_data_restrictions = reject_unauth_pipelining&lt;br /&gt;
 &lt;br /&gt;
 # we will use this later - This prevents cleartext authentication&lt;br /&gt;
 # for relaying&lt;br /&gt;
 smtpd_tls_auth_only = yes&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Now we need to create a *bunch* of files so that postfix can get the delivery information out of sql. Here&#039;s a shell script to create the scripts.  Change PGPW to the password for the postfix user of the postfix SQL database.&lt;br /&gt;
&lt;br /&gt;
 cd /etc/postfix&lt;br /&gt;
 mkdir sql&lt;br /&gt;
 PGPW=&amp;quot;ChangeMe&amp;quot;&lt;br /&gt;
 &lt;br /&gt;
 cat - &amp;lt;&amp;lt;EOF &amp;gt;sql/pgsql_virtual_alias_domain_catchall_maps.cf&lt;br /&gt;
 user=postfix&lt;br /&gt;
 password = $PGPW&lt;br /&gt;
 hosts = localhost&lt;br /&gt;
 dbname = postfix&lt;br /&gt;
 query = Select goto From alias,alias_domain where alias_domain.alias_domain = &#039;%d&#039; and alias.address = &#039;@&#039; ||  alias_domain.target_domain and alias.active = true and alias_domain.active= true &lt;br /&gt;
 EOF&lt;br /&gt;
 &lt;br /&gt;
 cat - &amp;lt;&amp;lt;EOF &amp;gt;sql/pgsql_virtual_alias_domain_mailbox_maps.cf&lt;br /&gt;
 user=postfix&lt;br /&gt;
 password = $PGPW&lt;br /&gt;
 hosts = localhost&lt;br /&gt;
 dbname = postfix&lt;br /&gt;
 query = Select maildir from mailbox,alias_domain where alias_domain.alias_domain = &#039;%d&#039; and mailbox.username = &#039;%u&#039; || &#039;@&#039; || alias_domain.target_domain and mailbox.active = true and alias_domain.active&lt;br /&gt;
 EOF&lt;br /&gt;
 &lt;br /&gt;
 cat - &amp;lt;&amp;lt;EOF &amp;gt;sql/pgsql_virtual_alias_domain_maps.cf&lt;br /&gt;
 user=postfix&lt;br /&gt;
 password = $PGPW&lt;br /&gt;
 hosts = localhost&lt;br /&gt;
 dbname = postfix&lt;br /&gt;
 query = select goto from alias,alias_domain where alias_domain.alias_domain=&#039;%d&#039; and alias.address = &#039;%u&#039; || &#039;@&#039; || alias_domain.target_domain and alias.active= true and alias_domain.active= true&lt;br /&gt;
 EOF&lt;br /&gt;
 &lt;br /&gt;
 cat - &amp;lt;&amp;lt;EOF &amp;gt;sql/pgsql_virtual_alias_maps.cf&lt;br /&gt;
 user=postfix&lt;br /&gt;
 password = $PGPW&lt;br /&gt;
 hosts = localhost&lt;br /&gt;
 dbname = postfix&lt;br /&gt;
 query = Select goto From alias Where address=&#039;%s&#039; and active =&#039;1&#039;&lt;br /&gt;
 EOF&lt;br /&gt;
 &lt;br /&gt;
 cat - &amp;lt;&amp;lt;EOF &amp;gt;sql/pgsql_virtual_domains_maps.cf&lt;br /&gt;
 user=postfix&lt;br /&gt;
 password = $PGPW&lt;br /&gt;
 hosts = localhost&lt;br /&gt;
 dbname = postfix&lt;br /&gt;
 query = Select domain from domain where domain=&#039;%s&#039; and active=&#039;1&#039;&lt;br /&gt;
 EOF&lt;br /&gt;
 &lt;br /&gt;
 cat - &amp;lt;&amp;lt;EOF &amp;gt;sql/pgsql_virtual_mailbox_maps.cf&lt;br /&gt;
 user=postfix&lt;br /&gt;
 password = $PGPW&lt;br /&gt;
 hosts = localhost&lt;br /&gt;
 dbname = postfix&lt;br /&gt;
 query = Select maildir from mailbox where username=&#039;%s&#039; and active=true&lt;br /&gt;
 EOF&lt;br /&gt;
 &lt;br /&gt;
 chown -R postfix:postfix sql&lt;br /&gt;
 chmod 640 sql/*&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
At this point you should be able to start up postfix&lt;br /&gt;
 &lt;br /&gt;
 newaliases  # so postfix is happy...&lt;br /&gt;
 /etc/init.d/postfix start&lt;br /&gt;
 rc-update add postfix&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Create a domain in PostfixAdmin and test ===&lt;br /&gt;
&lt;br /&gt;
Go to http://POSTFIXADMIN_DOMAIN/&lt;br /&gt;
&lt;br /&gt;
Log in using the superadmin account, create a domain for the local box (e.g. example.com), and create a user mailbox (e.g. root).&lt;br /&gt;
&lt;br /&gt;
From the machine, send a test message:&lt;br /&gt;
&lt;br /&gt;
 sendmail -t root@example.com&lt;br /&gt;
 subject: test&lt;br /&gt;
 .&lt;br /&gt;
 ^d&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
In /var/log/mail.log (or /var/log/messages, if you still have busybox syslogd running) you should see the message queued.  The message should be in /var/mail/domains/example.com/root/new&lt;br /&gt;
&lt;br /&gt;
== Install Dovecot ==&lt;br /&gt;
&lt;br /&gt;
Dovecot is the POP3/IMAP server to retrieve mail.&lt;br /&gt;
&lt;br /&gt;
As before, we install dovecot: &lt;br /&gt;
&lt;br /&gt;
 apk add acf-dovecot dovecot-pgsql&lt;br /&gt;
&lt;br /&gt;
edit /etc/dovecot/dovecot.conf&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 # Select only the protocols you wish to support - all are listed in the next line&lt;br /&gt;
 protocols               =       imap imaps pop pop3s&lt;br /&gt;
 log_path                =       /var/log/dovecot.log&lt;br /&gt;
 info_log_path           =       /var/log/dovecot-info.log&lt;br /&gt;
 disable_plaintext_auth  =       no&lt;br /&gt;
&lt;br /&gt;
 # Authenticated IMAP&lt;br /&gt;
 ssl                     =       yes&lt;br /&gt;
 ssl_cert_file           =       /etc/lighttpd/server-bundle.pem&lt;br /&gt;
 ssl_key_file            =       /etc/lighttpd/server-bundle.pem&lt;br /&gt;
 auth_verbose            =       yes&lt;br /&gt;
 auth_debug              =       no&lt;br /&gt;
 mail_location           =       maildir:/var/mail/domains/%d/%n&lt;br /&gt;
 auth default    {&lt;br /&gt;
        mechanisms = plain&lt;br /&gt;
        passdb sql {&lt;br /&gt;
                args = /etc/dovecot/dovecot-sql.conf&lt;br /&gt;
                }&lt;br /&gt;
        userdb static {&lt;br /&gt;
                args =  uid=1006 gid=1006 home=/var/mail/domains/%d/%n&lt;br /&gt;
                }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
We need a certificate for SSL/TLS authentication, so in the example above, we use the lighttpd cert. That way when the cert is renewed/replaced, Dovecot will have access to the new cert as well.  &lt;br /&gt;
&lt;br /&gt;
Create the /etc/dovecot/dovecot-sql.conf file:&lt;br /&gt;
&lt;br /&gt;
 driver = pgsql&lt;br /&gt;
 connect = host=localhost dbname=postfix user=postfix password=********&lt;br /&gt;
 password_query = select username,password from mailbox where local_part = &#039;%n&#039; and domain = &#039;%d&#039;&lt;br /&gt;
 default_pass_scheme =  MD5-CRYPT&lt;br /&gt;
&lt;br /&gt;
Again, change the password above to your postfix user password, and protect the file from prying eyes:&lt;br /&gt;
&lt;br /&gt;
 chown root:root /etc/dovecot/dovecot-sql.conf&lt;br /&gt;
 chmod 600 /etc/dovecot/dovecot-sql.conf&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Start dovecot&lt;br /&gt;
 /etc/init.d/dovecot start&lt;br /&gt;
 rc-update add dovecot&lt;br /&gt;
&lt;br /&gt;
== Testing ==&lt;br /&gt;
&lt;br /&gt;
Make sure your firewall allows in ports 25(SMTP) 110 (POP3), 995 (POP3S), 143(IMAP), 993(IMAPS), or whatever subset you support.  &lt;br /&gt;
 &lt;br /&gt;
At this point, you should be able to:&lt;br /&gt;
 * Create a new domain and add users with PostfixAdmin&lt;br /&gt;
 * Send mail to those users via SMTP to port 25&lt;br /&gt;
 * Retrieve mail using the user&#039;s full email and password (e.g. username: user@example.com  password: ChangeM&lt;br /&gt;
&lt;br /&gt;
== Value Add Features ==&lt;br /&gt;
&lt;br /&gt;
If you followed the guide above, you now have a functional mail server with many interconnected parts.  The features below assume that the server is already running as described above.  You should be able to add any or all of these features below to further enhance the mail service.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Virus Scanning ===&lt;br /&gt;
&lt;br /&gt;
This procedure uses clamav and the postfix content_filter mechanism to scan inbound and outbound email for viruses.  Infected emails are dropped.  Clean emails are tagged with a &amp;quot;scanned by clamav&amp;quot; header.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* Install clamav and clamsmtp:&lt;br /&gt;
 apk add acf-clamav clamsmtp&lt;br /&gt;
* Edit the /etc/clamav/clamd.conf file if desired (not necessary in most cases)&lt;br /&gt;
* Edit /etc/clamsmtpd.conf and verify the following lines&lt;br /&gt;
 OutAddress: 10026&lt;br /&gt;
 Listen: 127.0.0.1:10025                                               &lt;br /&gt;
 Header: X-Virus-Scanned: ClamAV using ClamSMTP&lt;br /&gt;
 Action: drop&lt;br /&gt;
 User: clamav                                                      &lt;br /&gt;
* Start the daemons&lt;br /&gt;
 rc-update add clamd&lt;br /&gt;
 rc-update add freshclam&lt;br /&gt;
 rc-update add clamsmtp&lt;br /&gt;
 /etc/init.d/clamd start&lt;br /&gt;
 /etc/init.d/freshclam start&lt;br /&gt;
 /etc/init.d/clamsmtp start&lt;br /&gt;
* Verify clamsmtp is listening on port 10025:&lt;br /&gt;
 netstat -anp | grep clamsmtp&lt;br /&gt;
* [http://memberwebs.com/stef/software/clamsmtp/postfix.html Following the clamsmtp instructions]&lt;br /&gt;
** edit /etc/postfix/main.cf and add:&lt;br /&gt;
 content_filter = scan:[127.0.0.1]:10025                                                      &lt;br /&gt;
** edit /etc/postfix/master.cf and add&lt;br /&gt;
 # AV scan filter (used by content_filter)&lt;br /&gt;
 scan      unix  -       -       n       -       16      smtp&lt;br /&gt;
         -o smtp_send_xforward_command=yes&lt;br /&gt;
         -o smtp_enforce_tls=no&lt;br /&gt;
 # For injecting mail back into postfix from the filter&lt;br /&gt;
 127.0.0.1:10026 inet  n -       n       -       16      smtpd&lt;br /&gt;
         -o content_filter=&lt;br /&gt;
         -o receive_override_options=no_unknown_recipient_checks,no_header_body_checks&lt;br /&gt;
         -o smtpd_helo_restrictions=&lt;br /&gt;
         -o smtpd_client_restrictions=&lt;br /&gt;
         -o smtpd_sender_restrictions=&lt;br /&gt;
         -o smtpd_recipient_restrictions=permit_mynetworks,reject&lt;br /&gt;
         -o mynetworks_style=host&lt;br /&gt;
         -o smtpd_authorized_xforward_hosts=127.0.0.0/8&lt;br /&gt;
* postfix reload&lt;br /&gt;
* Send and email into a local virtual domain - it should have the &#039;&#039;X-Virus-Scanned: ClamAV using ClamSMTP&#039;&#039; header.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Relay for Authenticated Users ===&lt;br /&gt;
&lt;br /&gt;
As configured above, the mail server accepts email from the Internet, but it does not relay email.  If it is a perimeter exchanger for a protected network, then you can add the protected networks to the &#039;&#039;mynetworks&#039;&#039; configuration line in /etc/postfix/main.cf&lt;br /&gt;
&lt;br /&gt;
This configuration change allows &#039;&#039;remote&#039;&#039; users to authenticate against the mail server and relay through it.  The rules for relaying are:&lt;br /&gt;
* Only authenticated users can relay&lt;br /&gt;
* Authentication Credentials must be encrypted with TLS or SSL&lt;br /&gt;
* Allow Submission and SMTPS ports for relaying (many consumer networks block port 25 - SMTP by default)&lt;br /&gt;
The process uses the dovecot authentication mechanism (used with IMAPS) to authenticate users before they are allowed to relay through postfix.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* Edit /etc/dovecot/dovecot.conf and add:&lt;br /&gt;
 # this is for postfix SASL (authenticated users can relay through us)&lt;br /&gt;
 socket listen {&lt;br /&gt;
                client {&lt;br /&gt;
                        path    = /var/spool/postfix/private/dovecot-auth.sock&lt;br /&gt;
                        mode    = 0660&lt;br /&gt;
                        user    = postfix&lt;br /&gt;
                        group   = postfix&lt;br /&gt;
                        }&lt;br /&gt;
                }&lt;br /&gt;
        }&lt;br /&gt;
* Restart dovecot&lt;br /&gt;
 /etc/init.d/dovecot restart&lt;br /&gt;
* Edit /etc/postfix/main.cf and add:&lt;br /&gt;
 # TLS Stuff -- since we allow SASL with tls *only*, we have to set up TLS first                    &lt;br /&gt;
 &lt;br /&gt;
 smtpd_tls_cert_file = /etc/lighttpd/server-bundle.pem&lt;br /&gt;
 smtpd_tls_key_file = /etc/lighttpd/server-bundle.pem&lt;br /&gt;
 smtpd_tls_CAfile = /etc/lighttpd/ca-crt.pem&lt;br /&gt;
 # If tls_security_level is set to &amp;quot;encrypt&amp;quot;, then SMTP rejects &lt;br /&gt;
 # unencrypted email (e.g. normal mail) which is bad.&lt;br /&gt;
 # By setting it to &amp;quot;may&amp;quot; you get TLS encrypted mail from google, slashdot, and other &lt;br /&gt;
 # interesting places.  Check your logs to see who&lt;br /&gt;
 smtpd_tls_security_level = may&lt;br /&gt;
 # Log info about the negotiated encryption levels&lt;br /&gt;
 smtpd_tls_received_header = yes&lt;br /&gt;
 smtpd_tls_loglevel = 1&lt;br /&gt;
 &lt;br /&gt;
 # SASL - this allows senders to authenticiate themselves&lt;br /&gt;
 # This along with &amp;quot;permit_sasl_authenticated&amp;quot; in smtpd_recipient_restrictions allows relaying&lt;br /&gt;
 smtpd_sasl_type = dovecot&lt;br /&gt;
 smtpd_sasl_path = private/dovecot-auth.sock&lt;br /&gt;
 smtpd_sasl_auth_enable = yes&lt;br /&gt;
 smtpd_sasl_authenticated_header = yes&lt;br /&gt;
 smtpd_tls_auth_only = yes&lt;br /&gt;
* Edit /etc/postfix/master.cf and enable the submission and smtps transports.  They are probably already at the top of your  master.cf file, just commented out:&lt;br /&gt;
 submission inet n       -       n       -       -       smtpd&lt;br /&gt;
   -o smtpd_tls_security_level=encrypt&lt;br /&gt;
   -o smtpd_sasl_auth_enable=yes&lt;br /&gt;
   -o smtpd_client_restrictions=permit_sasl_authenticated,reject&lt;br /&gt;
   -o milter_macro_daemon_name=ORIGINATING&lt;br /&gt;
 smtps     inet  n       -       n       -       -       smtpd&lt;br /&gt;
   -o smtpd_tls_security_level=encrypt&lt;br /&gt;
   -o smtpd_tls_wrappermode=yes&lt;br /&gt;
   -o smtpd_sasl_auth_enable=yes&lt;br /&gt;
   -o smtpd_client_restrictions=permit_sasl_authenticated,reject&lt;br /&gt;
   -o milter_macro_daemon_name=ORIGINATING&lt;br /&gt;
*Verfiy submission and smtps are defined in /etc/services&lt;br /&gt;
 grep &amp;quot;submission\|ssmtp&amp;quot; /etc/services&lt;br /&gt;
 submission	587/tcp				# mail message submission&lt;br /&gt;
 submission	587/udp&lt;br /&gt;
 smtps		465/tcp		ssmtp		# smtp protocol over TLS/SSL&lt;br /&gt;
 smtps		465/udp		ssmtp&lt;br /&gt;
* Restart postfix&lt;br /&gt;
 postfix reload&lt;br /&gt;
&lt;br /&gt;
At this point, you should be able to set up a mail client to relay through the server with TLS (port 587) or SSL (port 465)  Note that &amp;quot;plain&amp;quot; authentication is used because the underlying link is encrypted.  For example, in Thunderbird leave &amp;quot;secure authentication&amp;quot; unchecked, and choose STARTTLS (or TLS) for the connection security.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Mailbox Quotas ===&lt;br /&gt;
&lt;br /&gt;
In the default configuration, PostfixAdmin knows about quotas, but they are not enforced.   Documentation on the web mentions the [http://vda.sourceforge.net vda patch to postifx] to enforce quotas.  The only bad thing... its a &#039;&#039;patch&#039;&#039;.   Postfix and Dovecot are both conservative systems, so if the patch isn&#039;t in the upstream source, we&#039;ll assume there&#039;s a good reason.   There is a way of using quotas without patches - and it involves using the dovecot&#039;s [http://wiki.dovecot.org/LDA deliver] lda for local delivery.&lt;br /&gt;
&lt;br /&gt;
Note: As of Jan 2010, the documention is confusing, with multiple versions of dovecot, PostfixAdmin, and Mysql referenced.  These instructions apply to:&lt;br /&gt;
* Postgresql 8.4.2 &lt;br /&gt;
* PostfixAdmin 2.3 &lt;br /&gt;
* Dovecot 1.2.10&lt;br /&gt;
* Postfix 2.6.5&lt;br /&gt;
&lt;br /&gt;
Presumably later versions will work the same, but if not, please update the documentation and versions above.&lt;br /&gt;
&lt;br /&gt;
* Update /etc/dovecot.conf (old lines shown commented out):&lt;br /&gt;
 # old postfix &lt;br /&gt;
 #       userdb static {&lt;br /&gt;
 #               args =  uid=1006 gid=1006 home=/var/mail/domains/%d/%n&lt;br /&gt;
 #               }&lt;br /&gt;
 &lt;br /&gt;
 # new quota support:&lt;br /&gt;
        userdb prefetch {&lt;br /&gt;
                }&lt;br /&gt;
&lt;br /&gt;
        userdb sql {&lt;br /&gt;
                args = /etc/dovecot/dovecot-sql.conf&lt;br /&gt;
                }&lt;br /&gt;
&lt;br /&gt;
        socket listen {&lt;br /&gt;
                client {&lt;br /&gt;
                        path    = /var/spool/postfix/private/dovecot-auth.sock&lt;br /&gt;
                        mode    = 0660&lt;br /&gt;
                        user    = postfix&lt;br /&gt;
                        group   = postfix&lt;br /&gt;
                        }&lt;br /&gt;
                # These lines below are for the deliver lda&lt;br /&gt;
                master {&lt;br /&gt;
                        path =  /var/run/dovecot/auth-master&lt;br /&gt;
                        mode    = 0660&lt;br /&gt;
                        user    = vmail&lt;br /&gt;
                        group   = vmail&lt;br /&gt;
                        }&lt;br /&gt;
                }&lt;br /&gt;
 &lt;br /&gt;
 protocol imap {                                                               &lt;br /&gt;
         mail_plugins = quota imap_quota                                       &lt;br /&gt;
         }                                                                     &lt;br /&gt;
                                                                              &lt;br /&gt;
 protocol pop3 {                                                               &lt;br /&gt;
         mail_plugins = quota                                                  &lt;br /&gt;
         }                                                                     &lt;br /&gt;
                                                                              &lt;br /&gt;
 dict {                                                                        &lt;br /&gt;
        quotadict = pgsql:/etc/dovecot/dovecot-dict-quota.conf                &lt;br /&gt;
        }                                                                     &lt;br /&gt;
                                                                              &lt;br /&gt;
 plugin {                                                                      &lt;br /&gt;
         quota = dict:user::proxy::quotadict                                   &lt;br /&gt;
         }                                                     &lt;br /&gt;
                                                              &lt;br /&gt;
 protocol lda {                                                &lt;br /&gt;
   postmaster_address = postmaster@host.example.com&lt;br /&gt;
   mail_plugins = quota                                        &lt;br /&gt;
   auth_socket_path =  /var/run/dovecot/auth-master&lt;br /&gt;
   sendmail_path = /usr/sbin/sendmail&lt;br /&gt;
 }                                                                            &lt;br /&gt;
    &lt;br /&gt;
You should already have a &amp;lt;tt&amp;gt;socket-&amp;gt; listen-&amp;gt; client&amp;lt;/tt&amp;gt; section, but it is listed above to show where it goes in relationship to the &amp;lt;tt&amp;gt;socket -&amp;gt; listen -&amp;gt; master&amp;lt;/tt&amp;gt; section&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* edit &amp;lt;tt&amp;gt;/etc/dovecot/dovecot-sql.conf&amp;lt;/tt&amp;gt; and replace the user and password queries with the following (you may not have a user_query yet - add it):&lt;br /&gt;
&lt;br /&gt;
 password_query = select username as user, password, 1006 as userdb_uid, 1006 as userdb_gid, &#039;*:bytes=&#039; || quota as userdb_quota_rule from mailbox  where local_part = &#039;%n&#039; and domain = &#039;%d&#039;&lt;br /&gt;
 user_query = select maildir as home, 1006 as uid, 1006 as gid, &#039;*:bytes=&#039; || quota  as quota_rule from mailbox where local_part = &#039;%n&#039; and domain =&#039;%d&#039;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* create &amp;lt;tt&amp;gt;/etc/dovecot/dovecot-dict-quota.conf&amp;lt;/tt&amp;gt;&lt;br /&gt;
 connect = host=localhost dbname=postfix user=postfix password=********&lt;br /&gt;
 &lt;br /&gt;
 map {&lt;br /&gt;
         pattern = priv/quota/storage&lt;br /&gt;
         table = quota2&lt;br /&gt;
         username_field =username&lt;br /&gt;
         value_field = bytes&lt;br /&gt;
 }&lt;br /&gt;
 &lt;br /&gt;
 map {&lt;br /&gt;
        pattern= priv/quota/messages&lt;br /&gt;
        table = quota2&lt;br /&gt;
        username_field = username&lt;br /&gt;
        value_field = messages&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
Side note: [http://wiki.dovecot.org/Quota/Dict The Dovecot Quota Documentation] mentions the need for a trigger with pgsql.  This was created in the PostfixAdmin install, which is why you instantiated the pgsql language when creating the database.  If not, you will need to create the trigger, to reference the quota2 table, not the quota table mentioned in the dovecot docs.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* create a new transport for the dovecot lda.   Add the following to  /etc/postfix/master.cf:&lt;br /&gt;
 # The dovecot deliver lda&lt;br /&gt;
 dovecot   unix  -       n       n       -       -       pipe&lt;br /&gt;
   flags=DRhu user=vmail:vmail argv=/usr/libexec/dovecot/deliver -f ${sender} -d ${user}@${nexthop}&lt;br /&gt;
&lt;br /&gt;
* Edit the /etc/postfix/main.cf.  Replace &lt;br /&gt;
 virtual_transport = virtual &lt;br /&gt;
with&lt;br /&gt;
 virtual_transport = dovecot&lt;br /&gt;
 dovecot_destination_recipient_limit = 1&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;TODO&#039;&#039;&#039;  This will cause over-quota emails to bounce.   Which could be a source of backscatter.   We need a way of checking quota limits after RBL checking but before the message is accepted in the queue.&lt;br /&gt;
&lt;br /&gt;
=== WebMail (RoundCube) ===&lt;br /&gt;
&lt;br /&gt;
[http://roundcube.net/ RoundCube] is an &amp;quot;ajax /Web2.0&amp;quot; web-mail client.  These instructions are for the Alpine Linux 1.10 repository &lt;br /&gt;
&lt;br /&gt;
* Add the package and related php modules:&lt;br /&gt;
 apk add roundcubemail php-xml php-openssl php-mcrypt php-gd php-iconv&lt;br /&gt;
&lt;br /&gt;
* link the roundcube application back into the docroot&lt;br /&gt;
 ln -s /usr/share/webapps/roundcube /var/www/domains/host.example.com/www/roundcube&lt;br /&gt;
&lt;br /&gt;
* follow the instructions in /usr/share/webapps/roundcube/INSTALL:&lt;br /&gt;
 chown -R lighttpd:lighttpd temp logs&lt;br /&gt;
 &lt;br /&gt;
 su postgres&lt;br /&gt;
 createuser roundcube&lt;br /&gt;
   Shall the new role be a superuser? (y/n) n&lt;br /&gt;
   Shall the new role be allowed to create databases? (y/n) n&lt;br /&gt;
   Shall the new role be allowed to create more new roles? (y/n) y&lt;br /&gt;
 createdb -O roundcube -E UNICODE -T template0 roundcubemail&lt;br /&gt;
 psql roundcubemail&lt;br /&gt;
   roundcubemail=# ALTER USER roundcube WITH PASSWORD &#039;the_new_password&#039;;&lt;br /&gt;
   roundcubemail=# \c - roundcube&lt;br /&gt;
   \i /usr/share/webapps/roundcube/SQL/postgres.initial.sql&lt;br /&gt;
   \q&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* restart lighttpd to verify the new php libraries are used&lt;br /&gt;
 /etc/init.d/lighttpd restart&lt;br /&gt;
&lt;br /&gt;
* Point your browser to http://host.example.com/roundcube/installer&lt;br /&gt;
** Begin installation&lt;br /&gt;
** Follow the instructions in step 3 of the install to copy the files to the server&lt;br /&gt;
* edit /etc/php/php.ini and edit date.timezone to your local timezone, or to UTC&lt;br /&gt;
* if necessary (e.g. you had to reset the local timezone) restart lighttpd to reload php&lt;br /&gt;
 /etc/init.d/lighttpd restart&lt;br /&gt;
* You should now be able to get to roundcube at http://host.example.com/roundcube&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
For the specific configuration parameters in the install step:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!Property&lt;br /&gt;
!Setting&lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;enable_spellcheck&#039;&#039; ||   disabled &lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;identities_level&#039;&#039; ||  one identity with possibility to edit all params but not email address &lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;log driver&#039;&#039; || syslog &lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;sylog_id&#039;&#039; || roundcube &lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;syslog_facility&#039;&#039; || mailsubsystem &lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;db_dnsw&#039;&#039; || pgsql properties, as described above &lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;imap_host&#039;&#039; || 127.0.0.1 &lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;auto_create_user&#039;&#039; || enabled &lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;smtp_server&#039;&#039; ||  127.0.0.1&lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;smtp_port&#039;&#039; ||  25&lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;smtp_user/smtp_pass&#039;&#039; ||  enable &#039;&#039;Use Current IMAP username and password for SMTP authentication&#039;&#039;&lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;smtp_log&#039;&#039; ||  enable (optional, but gives additional log record)&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
The other items can be left at default settings, or adjusted if desired.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
After its working, the INSTALL file recommends removing the install directory.   If you want to keep the installer around later, you can simply change the ownership and permissions.  So do &#039;&#039;&#039;one&#039;&#039;&#039; of the following:&lt;br /&gt;
 cd /usr/share/webapps/roundcube&lt;br /&gt;
 rm -rf LICENSE UPGRADING INSTALL README CHANGELOG  SQL installer&lt;br /&gt;
or&lt;br /&gt;
 cd /usr/share/webapps/roundcube&lt;br /&gt;
 chown -R root:root LICENSE UPGRADING INSTALL README CHANGELOG  SQL installer&lt;br /&gt;
 chmod -R 600 LICENSE UPGRADING INSTALL README CHANGELOG SQL &lt;br /&gt;
 chmod 700 SQL installer&lt;br /&gt;
&lt;br /&gt;
== log rotation ==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
Special thanks to DHughes for providing a 3 page email on how to set up postgres,postfix,PostfixAdmin,dovecot and roundcube.  It was the clearer than all the other guides available on the Net. Thanks!&lt;/div&gt;</summary>
		<author><name>Djhughes</name></author>
	</entry>
	<entry>
		<id>https://wiki.alpinelinux.org/w/index.php?title=ISP_Mail_Server_HowTo&amp;diff=3347</id>
		<title>ISP Mail Server HowTo</title>
		<link rel="alternate" type="text/html" href="https://wiki.alpinelinux.org/w/index.php?title=ISP_Mail_Server_HowTo&amp;diff=3347"/>
		<updated>2010-02-16T08:42:25Z</updated>

		<summary type="html">&lt;p&gt;Djhughes: specify dns A records&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== A Full Service Mail Server ==&lt;br /&gt;
&lt;br /&gt;
The goal of this document is to describe how to set up postfix, dovecot, clamav, dspam, roundecube, and postfixadmin for a full-featured &amp;quot;ISP&amp;quot; level mail server.&lt;br /&gt;
&lt;br /&gt;
The server must provide:&lt;br /&gt;
&lt;br /&gt;
* multiple virtual domains&lt;br /&gt;
* admins for each domain (to add/remove virtual accounts)&lt;br /&gt;
* Quota support per domain / account&lt;br /&gt;
* downloading email via IMAP / IMAPS / POP3 / POP3S&lt;br /&gt;
* relaying email for authenticated users with TLS or SSL (Submission / SMTPS protocol)&lt;br /&gt;
* Standard filters (virus/spam/rbl/etc)&lt;br /&gt;
* Web mail client&lt;br /&gt;
* Value Add services&lt;br /&gt;
&lt;br /&gt;
== Configure DNS ==&lt;br /&gt;
&lt;br /&gt;
This server will host three separate virtual domains on the same web server. They will be distinguished by their DNS names, so you must choose three domains for the three separate services:&lt;br /&gt;
&lt;br /&gt;
* ACF - Alpine Configuration Framework for managing the server&lt;br /&gt;
* PostfixAdmin - for managing the postfix installation&lt;br /&gt;
* RoundCube - for accessing individual mailboxes&lt;br /&gt;
&lt;br /&gt;
Choose three different domains (from here on known as ACF_DOMAIN, POSTFIXADMIN_DOMAIN, and ROUNDCUBE_DOMAIN) and configure DNS for all three to point to the IP address of your host. These should be DNS A records.&lt;br /&gt;
&lt;br /&gt;
== Set up Lighttpd + PHP ==&lt;br /&gt;
&lt;br /&gt;
PostfixAdmin needs php pgpsql and imap modules, so we do it in this step.&lt;br /&gt;
&lt;br /&gt;
  apk add lighttpd php php-pgsql php-imap&lt;br /&gt;
&lt;br /&gt;
Stop and remove mini_httpd, and move ACF to lighttpd;  We are setting this up to be a multi-domain virtual web server (replace ACF_DOMAIN with the actual domain):&lt;br /&gt;
&lt;br /&gt;
  mkdir -p /var/www/domains/ACF_DOMAIN&lt;br /&gt;
  ln -s /usr/share/acf/www /var/www/domains/ACF_DOMAIN/www&lt;br /&gt;
&lt;br /&gt;
Edit /etc/lighttpd/mod_cgi.conf to serve haserl files by adding a &amp;quot;&amp;quot; =&amp;gt; &amp;quot;&amp;quot; cgi handler&lt;br /&gt;
&lt;br /&gt;
 $HTTP[&amp;quot;url&amp;quot;] =~ &amp;quot;^/cgi-bin/&amp;quot; {&lt;br /&gt;
     # disable directory listings&lt;br /&gt;
     dir-listing.activate = &amp;quot;disable&amp;quot;&lt;br /&gt;
     # only allow cgi&#039;s in this directory&lt;br /&gt;
     cgi.assign = (&lt;br /&gt;
 		&amp;quot;.pl&amp;quot;	=&amp;gt;	&amp;quot;/usr/bin/perl&amp;quot;,&lt;br /&gt;
 		&amp;quot;.cgi&amp;quot;	=&amp;gt;	&amp;quot;/usr/bin/perl&amp;quot;,&lt;br /&gt;
 		&amp;quot;&amp;quot; =&amp;gt; &amp;quot;&amp;quot;&lt;br /&gt;
 	)&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
Add these lines to /etc/lighttpd/lighttpd.conf to point to the new document root, and set it up to listen on port 443 (replace &#039;&#039;ROUNDCUBE_DOMAIN&#039;&#039; with the roundcube domain and &#039;&#039;ip_address_of_server&#039;&#039; with the actual IP address):&lt;br /&gt;
&lt;br /&gt;
 simple-vhost.server-root   = &amp;quot;/var/www/domains/&amp;quot;&lt;br /&gt;
 simple-vhost.default-host  = &amp;quot;/ROUNDCUBE_DOMAIN/&amp;quot;&lt;br /&gt;
 simple-vhost.document-root = &amp;quot;www/&amp;quot;&lt;br /&gt;
 &lt;br /&gt;
 $SERVER[&amp;quot;socket&amp;quot;] == &amp;quot;ip_address_of_server:443&amp;quot; {&lt;br /&gt;
 ssl.engine    = &amp;quot;enable&amp;quot;&lt;br /&gt;
 ssl.pemfile   = &amp;quot;/etc/lighttpd/server-bundle.pem&amp;quot;&lt;br /&gt;
 ssl.ca-file   = &amp;quot;/etc/lighttpd/ca-crt.pem&amp;quot;&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
Ensure that the simple_vhosts module is loaded, as well as the cgi config scripts by uncommenting the following lines in /etc/lighttpd/lighttpd.conf&lt;br /&gt;
&lt;br /&gt;
 server.modules = (&lt;br /&gt;
     #  other modules may be listed&lt;br /&gt;
     &amp;quot;mod_simple_vhost&amp;quot;, &lt;br /&gt;
     #  other modules may be listed&lt;br /&gt;
  .&lt;br /&gt;
  .&lt;br /&gt;
  .&lt;br /&gt;
     include &amp;quot;mod_cgi.conf&amp;quot;&lt;br /&gt;
 &lt;br /&gt;
     include &amp;quot;mod_fastcgi.conf&amp;quot;&lt;br /&gt;
 &lt;br /&gt;
&lt;br /&gt;
Get a web certificate, and install it.  If you want to use a self-signed cert, you can use [[Generating SSL certs with ACF]] or [[Generating SSL certs with ACF 1.9]].  If you create a certificate with ACF, you can create the &amp;quot;server-bundle.pem&amp;quot; and the &amp;quot;ca-crt.pem&amp;quot; file with these commands:&lt;br /&gt;
&lt;br /&gt;
  openssl pkcs12 -nokeys -cacerts -in certificate.pfx  -out /etc/lighttpd/ca-crt.pem&lt;br /&gt;
  openssl pkcs12 -nodes -in certifcate.pfx -out /etc/lighttpd/server-bundle.pem&lt;br /&gt;
  chown root:root /etc/lighttpd/server-bundle.pem&lt;br /&gt;
  chmod 400 /etc/lighttpd/server-bundle.pem&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Note:&#039;&#039;&#039; The server certificate &#039;&#039;and&#039;&#039; key are in the server-bundle.pem file, so it is critical that the file be read-only by user &amp;quot;root&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
 Editme: We should probably only serve ACF to restricted hosts&lt;br /&gt;
&lt;br /&gt;
Stop and remove mini_httpd; start lighttpd, test&lt;br /&gt;
&lt;br /&gt;
  /etc/init.d/mini_httpd stop&lt;br /&gt;
  rc-update del mini_httpd&lt;br /&gt;
  apk del mini_httpd&lt;br /&gt;
  rc-update add lighttpd&lt;br /&gt;
  /etc/init.d/lighttpd start&lt;br /&gt;
&lt;br /&gt;
At this point you should be able to see ACF being served with lighttpd:  https://ACF_DOMAIN/&lt;br /&gt;
&lt;br /&gt;
== Install Postgresql ==&lt;br /&gt;
&lt;br /&gt;
Add and configure postgresql&lt;br /&gt;
&lt;br /&gt;
  apk add acf-postgresql postgresql-client&lt;br /&gt;
  /etc/init.d/postgresql setup&lt;br /&gt;
  /etc/init.d/postgresql start&lt;br /&gt;
  rc-update add postgresql&lt;br /&gt;
&lt;br /&gt;
At this point any user can connect to the sql server with &amp;quot;trust&amp;quot; mechanism.  If you want to enforce password authentication (you probably do) edit /var/lib/postgresql/8.4/data/pg_hba.conf&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
  Editme: What should we recommend?&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Create the postfix database:&lt;br /&gt;
&lt;br /&gt;
  psql -U postgres&lt;br /&gt;
   create user postfix with password &#039;******&#039;;&lt;br /&gt;
   create database postfix owner postfix;&lt;br /&gt;
   \c postfix&lt;br /&gt;
   create language plpgsql;&lt;br /&gt;
   \q&lt;br /&gt;
&lt;br /&gt;
(Of course, use your selected password where ******* is shown above.)&lt;br /&gt;
&lt;br /&gt;
== Install PostfixAdmin ==&lt;br /&gt;
&lt;br /&gt;
We are going to install the postfix admin web front-end before we install the mail server.  This just creates an interface to populate the SQL tables that postfix and dovecot will use.&lt;br /&gt;
&lt;br /&gt;
Download PostfixAdmin from Sourceforge.  When these instructions were written, 2.3 was the current release, so (replace POSTFIXADMIN_DOMAIN with the actual domain):&lt;br /&gt;
 wget http://downloads.sourceforge.net/project/postfixadmin/postfixadmin/postfixadmin_2.3.tar.gz&lt;br /&gt;
 tar zxvf postfixadmin_2.3.tar.gz&lt;br /&gt;
 mkdir -p /var/www/domains/POSTFIXADMIN_DOMAIN/www&lt;br /&gt;
 mv postfixadmin-2.3/* /var/www/domains/POSTFIXADMIN_DOMAIN/www&lt;br /&gt;
 rm -rf postfixadmin*&lt;br /&gt;
&lt;br /&gt;
Edit /var/www/domains/POSTFIXADMIN_DOMAIN/www/config.inc.php and modify at least these lines (replace POSTFIXADMIN_DOMAIN with the actual domain):&lt;br /&gt;
&lt;br /&gt;
 $CONF[&#039;configured&#039;] = true;&lt;br /&gt;
 $CONF[&#039;setup_password&#039;] = &amp;quot;&amp;quot;;  &amp;lt;&amp;lt; Don&#039;t change this yet&lt;br /&gt;
 $CONF[&#039;database_type&#039;] = &#039;pgsql&#039;;&lt;br /&gt;
 $CONF[&#039;database_host&#039;] = &#039;localhost&#039;;&lt;br /&gt;
 $CONF[&#039;database_user&#039;] = &#039;postfix&#039;;&lt;br /&gt;
 $CONF[&#039;database_password&#039;] = &#039;*****&#039;;   &amp;lt;&amp;lt; The password you chose above&lt;br /&gt;
 $CONF[&#039;database_name&#039;] = &#039;postfix&#039;;&lt;br /&gt;
 $CONF[&#039;database_prefix&#039;] = &#039;&#039;;&lt;br /&gt;
 $CONF[&#039;admin_email&#039;] = &#039;you@some.email.com&#039;;  &amp;lt;&amp;lt; Your email address &lt;br /&gt;
 $CONF[&#039;encrypt&#039;] = &#039;md5crypt&#039;;&lt;br /&gt;
 $CONF[&#039;authlib_default_flavor&#039;] = &#039;md5raw&#039;;&lt;br /&gt;
 $CONF[&#039;dovecotpw&#039;] = &amp;quot;/usr/sbin/dovecotpw&amp;quot;;&lt;br /&gt;
 $CONF[&#039;domain_path&#039;] = &#039;YES&#039;;&lt;br /&gt;
 $CONF[&#039;domain_in_mailbox&#039;] = &#039;NO&#039;;&lt;br /&gt;
 $CONF[&#039;aliases&#039;] = &#039;10&#039;;                       &lt;br /&gt;
 $CONF[&#039;mailboxes&#039;] = &#039;10&#039;;&lt;br /&gt;
 $CONF[&#039;maxquota&#039;] = &#039;10&#039;;&lt;br /&gt;
 $CONF[&#039;vacation&#039;] = &#039;NO&#039;; &lt;br /&gt;
 $CONF[&#039;vacation_control&#039;] =&#039;NO&#039;;&lt;br /&gt;
 $CONF[&#039;vacation_control_admin&#039;] = &#039;NO&#039;;&lt;br /&gt;
 $CONF[&#039;create_mailbox_subdirs_prefix&#039;]=&amp;quot;&amp;quot;;  &lt;br /&gt;
 $CONF[&#039;quota&#039;] = &#039;YES&#039;;&lt;br /&gt;
 $CONF[&#039;quota_multiplier&#039;] = &#039;1024000&#039;;&lt;br /&gt;
 $CONF[&#039;used_quotas&#039;] = &#039;YES&#039;;   &lt;br /&gt;
 $CONF[&#039;new_quota_table&#039;] = &#039;YES&#039;;  &lt;br /&gt;
 $CONF[&#039;alias_control&#039;] = &#039;YES&#039;;&lt;br /&gt;
 $CONF[&#039;alias_control_admin&#039;] = &#039;YES&#039;;&lt;br /&gt;
 $CONF[&#039;special_alias_control&#039;] = &#039;YES&#039;;&lt;br /&gt;
 $CONF[&#039;fetchmail&#039;] = &#039;NO&#039;;&lt;br /&gt;
 $CONF[&#039;user_footer_link&#039;] = &amp;quot;http://POSTFIXADMIN_DOMAIN&amp;quot;;&lt;br /&gt;
 $CONF[&#039;footer_link&#039;] = &#039;http://POSTFIXADMIN_DOMAIN/main.php&#039;;&lt;br /&gt;
&lt;br /&gt;
You should further edit /var/www/domains/POSTFIXADMIN_DOMAIN/www/config.inc.php and replace all instances of &amp;quot;change-this-to-your.domain.tld&amp;quot; with your actual mail domain.&lt;br /&gt;
&lt;br /&gt;
Go to http://POSTFIXADMIN_DOMAIN/setup.php&lt;br /&gt;
&lt;br /&gt;
Create the password hash, add it to the config.inc.php file&lt;br /&gt;
&lt;br /&gt;
Go back to http://POSTFIXADMIN_DOMAIN/setup.php&lt;br /&gt;
&lt;br /&gt;
Create superadmin account.&lt;br /&gt;
&lt;br /&gt;
== Install Postfix ==&lt;br /&gt;
&lt;br /&gt;
Create a user for the virtual mail delivery, and get its uid/gid (you&#039;ll need the numeric uid/gid for postfix)&lt;br /&gt;
&lt;br /&gt;
 adduser vmail -H -D -s /bin/false&lt;br /&gt;
 grep vmail /etc/passwd&lt;br /&gt;
&lt;br /&gt;
(In examples below, we use 1006/1006 for the uid/gid)&lt;br /&gt;
&lt;br /&gt;
Create the mail directory, and assign vmail as the owner&lt;br /&gt;
 mkdir -p /var/mail/domains&lt;br /&gt;
 chown -R vmail:vmail /var/mail/domains&lt;br /&gt;
 &lt;br /&gt;
&lt;br /&gt;
Install postfix&lt;br /&gt;
&lt;br /&gt;
 apk add acf-postfix postfix-pgsql&lt;br /&gt;
&lt;br /&gt;
Edit the /etc/postfix/main.cf file  Here&#039;s an example:&lt;br /&gt;
&lt;br /&gt;
 myhostname=host.example.com&lt;br /&gt;
 mydomain=example.com&lt;br /&gt;
 &lt;br /&gt;
 mydestination = localhost.$mydomains, localhost&lt;br /&gt;
 mynetworks_style = subnet&lt;br /&gt;
 mynetworks = 127.0.0.0/8&lt;br /&gt;
 &lt;br /&gt;
 virtual_mailbox_domains = proxy:pgsql:/etc/postfix/sql/pgsql_virtual_domains_maps.cf&lt;br /&gt;
 virtual_alias_maps = proxy:pgsql:/etc/postfix/sql/pgsql_virtual_alias_maps.cf,&lt;br /&gt;
        proxy:pgsql:/etc/postfix/sql/pgsql_virtual_alias_domain_maps.cf,&lt;br /&gt;
        proxy:pgsql:/etc/postfix/sql/pgsql_virtual_alias_domain_catchall_maps.cf&lt;br /&gt;
 &lt;br /&gt;
 virtual_mailbox_maps = proxy:pgsql:/etc/postfix/sql/pgsql_virtual_mailbox_maps.cf,&lt;br /&gt;
        proxy:pgsql:/etc/postfix/sql/pgsql_virtual_alias_domain_mailbox_maps.cf&lt;br /&gt;
 &lt;br /&gt;
 virtual_mailbox_base = /var/mail/domains/&lt;br /&gt;
 virtual_gid_maps = static:1006&lt;br /&gt;
 virtual_uid_maps = static:1006&lt;br /&gt;
 virtual_minimum_uid = 100&lt;br /&gt;
 virtual_transport = virtual&lt;br /&gt;
 &lt;br /&gt;
 &lt;br /&gt;
 # This next command means you must create a virtual&lt;br /&gt;
 # domain for the host itself - ALL mail goes through&lt;br /&gt;
 # The virtual transport&lt;br /&gt;
 &lt;br /&gt;
 mailbox_transport = virtual&lt;br /&gt;
 local_transport = virtual&lt;br /&gt;
 local_transport_maps = $virtual_mailbox_maps&lt;br /&gt;
 &lt;br /&gt;
 smtpd_helo_required = yes&lt;br /&gt;
 disable_vrfy_command = yes&lt;br /&gt;
 message_size_limit = 10240000&lt;br /&gt;
 queue_minfree = 51200000&lt;br /&gt;
 &lt;br /&gt;
 smtpd_sender_restrictions =&lt;br /&gt;
        permit_mynetworks,&lt;br /&gt;
        reject_non_fqdn_sender,&lt;br /&gt;
        reject_unknown_sender_domain&lt;br /&gt;
 &lt;br /&gt;
 smtpd_recipient_restrictions =&lt;br /&gt;
        reject_non_fqdn_recipient,&lt;br /&gt;
        reject_unknown_recipient_domain,&lt;br /&gt;
        permit_mynetworks,&lt;br /&gt;
        permit_sasl_authenticated,&lt;br /&gt;
        reject_unauth_destination,&lt;br /&gt;
        reject_rbl_client dnsbl.sorbs.net,&lt;br /&gt;
        reject_rbl_client zen.spamhaus.org,&lt;br /&gt;
        reject_rbl_client bl.spamcop.net&lt;br /&gt;
 &lt;br /&gt;
 smtpd_data_restrictions = reject_unauth_pipelining&lt;br /&gt;
 &lt;br /&gt;
 # we will use this later - This prevents cleartext authentication&lt;br /&gt;
 # for relaying&lt;br /&gt;
 smtpd_tls_auth_only = yes&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Now we need to create a *bunch* of files so that postfix can get the delivery information out of sql. Here&#039;s a shell script to create the scripts.  Change PGPW to the password for the postfix user of the postfix SQL database.&lt;br /&gt;
&lt;br /&gt;
 cd /etc/postfix&lt;br /&gt;
 mkdir sql&lt;br /&gt;
 PGPW=&amp;quot;ChangeMe&amp;quot;&lt;br /&gt;
 &lt;br /&gt;
 cat - &amp;lt;&amp;lt;EOF &amp;gt;sql/pgsql_virtual_alias_domain_catchall_maps.cf&lt;br /&gt;
 user=postfix&lt;br /&gt;
 password = $PGPW&lt;br /&gt;
 hosts = localhost&lt;br /&gt;
 dbname = postfix&lt;br /&gt;
 query = Select goto From alias,alias_domain where alias_domain.alias_domain = &#039;%d&#039; and alias.address = &#039;@&#039; ||  alias_domain.target_domain and alias.active = true and alias_domain.active= true &lt;br /&gt;
 EOF&lt;br /&gt;
 &lt;br /&gt;
 cat - &amp;lt;&amp;lt;EOF &amp;gt;sql/pgsql_virtual_alias_domain_mailbox_maps.cf&lt;br /&gt;
 user=postfix&lt;br /&gt;
 password = $PGPW&lt;br /&gt;
 hosts = localhost&lt;br /&gt;
 dbname = postfix&lt;br /&gt;
 query = Select maildir from mailbox,alias_domain where alias_domain.alias_domain = &#039;%d&#039; and mailbox.username = &#039;%u&#039; || &#039;@&#039; || alias_domain.target_domain and mailbox.active = true and alias_domain.active&lt;br /&gt;
 EOF&lt;br /&gt;
 &lt;br /&gt;
 cat - &amp;lt;&amp;lt;EOF &amp;gt;sql/pgsql_virtual_alias_domain_maps.cf&lt;br /&gt;
 user=postfix&lt;br /&gt;
 password = $PGPW&lt;br /&gt;
 hosts = localhost&lt;br /&gt;
 dbname = postfix&lt;br /&gt;
 query = select goto from alias,alias_domain where alias_domain.alias_domain=&#039;%d&#039; and alias.address = &#039;%u&#039; || &#039;@&#039; || alias_domain.target_domain and alias.active= true and alias_domain.active= true&lt;br /&gt;
 EOF&lt;br /&gt;
 &lt;br /&gt;
 cat - &amp;lt;&amp;lt;EOF &amp;gt;sql/pgsql_virtual_alias_maps.cf&lt;br /&gt;
 user=postfix&lt;br /&gt;
 password = $PGPW&lt;br /&gt;
 hosts = localhost&lt;br /&gt;
 dbname = postfix&lt;br /&gt;
 query = Select goto From alias Where address=&#039;%s&#039; and active =&#039;1&#039;&lt;br /&gt;
 EOF&lt;br /&gt;
 &lt;br /&gt;
 cat - &amp;lt;&amp;lt;EOF &amp;gt;sql/pgsql_virtual_domains_maps.cf&lt;br /&gt;
 user=postfix&lt;br /&gt;
 password = $PGPW&lt;br /&gt;
 hosts = localhost&lt;br /&gt;
 dbname = postfix&lt;br /&gt;
 query = Select domain from domain where domain=&#039;%s&#039; and active=&#039;1&#039;&lt;br /&gt;
 EOF&lt;br /&gt;
 &lt;br /&gt;
 cat - &amp;lt;&amp;lt;EOF &amp;gt;sql/pgsql_virtual_mailbox_maps.cf&lt;br /&gt;
 user=postfix&lt;br /&gt;
 password = $PGPW&lt;br /&gt;
 hosts = localhost&lt;br /&gt;
 dbname = postfix&lt;br /&gt;
 query = Select maildir from mailbox where username=&#039;%s&#039; and active=true&lt;br /&gt;
 EOF&lt;br /&gt;
 &lt;br /&gt;
 chown -R postfix:postfix sql&lt;br /&gt;
 chmod 640 sql/*&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
At this point you should be able to start up postfix&lt;br /&gt;
 &lt;br /&gt;
 newaliases  # so postfix is happy...&lt;br /&gt;
 /etc/init.d/postfix start&lt;br /&gt;
 rc-update add postfix&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Create a domain in PostfixAdmin and test ===&lt;br /&gt;
&lt;br /&gt;
Go to http://POSTFIXADMIN_DOMAIN/&lt;br /&gt;
&lt;br /&gt;
Log in using the superadmin account, create a domain for the local box (e.g. example.com), and create a user mailbox (e.g. root).&lt;br /&gt;
&lt;br /&gt;
From the machine, send a test message:&lt;br /&gt;
&lt;br /&gt;
 sendmail -t root@example.com&lt;br /&gt;
 subject: test&lt;br /&gt;
 .&lt;br /&gt;
 ^d&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
In /var/log/mail.log (or /var/log/messages, if you still have busybox syslogd running) you should see the message queued.  The message should be in /var/mail/domains/example.com/root/new&lt;br /&gt;
&lt;br /&gt;
== Install Dovecot ==&lt;br /&gt;
&lt;br /&gt;
Dovecot is the POP3/IMAP server to retrieve mail.&lt;br /&gt;
&lt;br /&gt;
As before, we install dovecot: &lt;br /&gt;
&lt;br /&gt;
 apk add acf-dovecot dovecot-pgsql&lt;br /&gt;
&lt;br /&gt;
edit /etc/dovecot/dovecot.conf&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 # Select only the protocols you wish to support - all are listed in the next line&lt;br /&gt;
 protocols               =       imap imaps pop pop3s&lt;br /&gt;
 log_path                =       /var/log/dovecot.log&lt;br /&gt;
 info_log_path           =       /var/log/dovecot-info.log&lt;br /&gt;
 disable_plaintext_auth  =       no&lt;br /&gt;
&lt;br /&gt;
 # Authenticated IMAP&lt;br /&gt;
 ssl                     =       yes&lt;br /&gt;
 ssl_cert_file           =       /etc/lighttpd/server-bundle.pem&lt;br /&gt;
 ssl_key_file            =       /etc/lighttpd/server-bundle.pem&lt;br /&gt;
 auth_verbose            =       yes&lt;br /&gt;
 auth_debug              =       no&lt;br /&gt;
 mail_location           =       maildir:/var/mail/domains/%d/%n&lt;br /&gt;
 auth default    {&lt;br /&gt;
        mechanisms = plain&lt;br /&gt;
        passdb sql {&lt;br /&gt;
                args = /etc/dovecot/dovecot-sql.conf&lt;br /&gt;
                }&lt;br /&gt;
        userdb static {&lt;br /&gt;
                args =  uid=1006 gid=1006 home=/var/mail/domains/%d/%n&lt;br /&gt;
                }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
We need a certificate for SSL/TLS authentication, so in the example above, we use the lighttpd cert. That way when the cert is renewed/replaced, Dovecot will have access to the new cert as well.  &lt;br /&gt;
&lt;br /&gt;
Create the /etc/dovecot/dovecot-sql.conf file:&lt;br /&gt;
&lt;br /&gt;
 driver = pgsql&lt;br /&gt;
 connect = host=localhost dbname=postfix user=postfix password=********&lt;br /&gt;
 password_query = select username,password from mailbox where local_part = &#039;%n&#039; and domain = &#039;%d&#039;&lt;br /&gt;
 default_pass_scheme =  MD5-CRYPT&lt;br /&gt;
&lt;br /&gt;
Again, change the password above to your postfix user password, and protect the file from prying eyes:&lt;br /&gt;
&lt;br /&gt;
 chown root:root /etc/dovecot/dovecot-sql.conf&lt;br /&gt;
 chmod 600 /etc/dovecot/dovecot-sql.conf&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Start dovecot&lt;br /&gt;
 /etc/init.d/dovecot start&lt;br /&gt;
 rc-update add dovecot&lt;br /&gt;
&lt;br /&gt;
== Testing ==&lt;br /&gt;
&lt;br /&gt;
Make sure your firewall allows in ports 25(SMTP) 110 (POP3), 995 (POP3S), 143(IMAP), 993(IMAPS), or whatever subset you support.  &lt;br /&gt;
 &lt;br /&gt;
At this point, you should be able to:&lt;br /&gt;
 * Create a new domain and add users with PostfixAdmin&lt;br /&gt;
 * Send mail to those users via SMTP to port 25&lt;br /&gt;
 * Retrieve mail using the user&#039;s full email and password (e.g. username: user@example.com  password: ChangeM&lt;br /&gt;
&lt;br /&gt;
== Value Add Features ==&lt;br /&gt;
&lt;br /&gt;
If you followed the guide above, you now have a functional mail server with many interconnected parts.  The features below assume that the server is already running as described above.  You should be able to add any or all of these features below to further enhance the mail service.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Virus Scanning ===&lt;br /&gt;
&lt;br /&gt;
This procedure uses clamav and the postfix content_filter mechanism to scan inbound and outbound email for viruses.  Infected emails are dropped.  Clean emails are tagged with a &amp;quot;scanned by clamav&amp;quot; header.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* Install clamav and clamsmtp:&lt;br /&gt;
 apk add acf-clamav clamsmtp&lt;br /&gt;
* Edit the /etc/clamav/clamd.conf file if desired (not necessary in most cases)&lt;br /&gt;
* Edit /etc/clamsmtpd.conf and verify the following lines&lt;br /&gt;
 OutAddress: 10026&lt;br /&gt;
 Listen: 127.0.0.1:10025                                               &lt;br /&gt;
 Header: X-Virus-Scanned: ClamAV using ClamSMTP&lt;br /&gt;
 Action: drop&lt;br /&gt;
 User: clamav                                                      &lt;br /&gt;
* Start the daemons&lt;br /&gt;
 rc-update add clamd&lt;br /&gt;
 rc-update add freshclam&lt;br /&gt;
 rc-update add clamsmtp&lt;br /&gt;
 /etc/init.d/clamd start&lt;br /&gt;
 /etc/init.d/freshclam start&lt;br /&gt;
 /etc/init.d/clamsmtp start&lt;br /&gt;
* Verify clamsmtp is listening on port 10025:&lt;br /&gt;
 netstat -anp | grep clamsmtp&lt;br /&gt;
* [http://memberwebs.com/stef/software/clamsmtp/postfix.html Following the clamsmtp instructions]&lt;br /&gt;
** edit /etc/postfix/main.cf and add:&lt;br /&gt;
 content_filter = scan:[127.0.0.1]:10025                                                      &lt;br /&gt;
** edit /etc/postfix/master.cf and add&lt;br /&gt;
 # AV scan filter (used by content_filter)&lt;br /&gt;
 scan      unix  -       -       n       -       16      smtp&lt;br /&gt;
         -o smtp_send_xforward_command=yes&lt;br /&gt;
         -o smtp_enforce_tls=no&lt;br /&gt;
 # For injecting mail back into postfix from the filter&lt;br /&gt;
 127.0.0.1:10026 inet  n -       n       -       16      smtpd&lt;br /&gt;
         -o content_filter=&lt;br /&gt;
         -o receive_override_options=no_unknown_recipient_checks,no_header_body_checks&lt;br /&gt;
         -o smtpd_helo_restrictions=&lt;br /&gt;
         -o smtpd_client_restrictions=&lt;br /&gt;
         -o smtpd_sender_restrictions=&lt;br /&gt;
         -o smtpd_recipient_restrictions=permit_mynetworks,reject&lt;br /&gt;
         -o mynetworks_style=host&lt;br /&gt;
         -o smtpd_authorized_xforward_hosts=127.0.0.0/8&lt;br /&gt;
* postfix reload&lt;br /&gt;
* Send and email into a local virtual domain - it should have the &#039;&#039;X-Virus-Scanned: ClamAV using ClamSMTP&#039;&#039; header.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Relay for Authenticated Users ===&lt;br /&gt;
&lt;br /&gt;
As configured above, the mail server accepts email from the Internet, but it does not relay email.  If it is a perimeter exchanger for a protected network, then you can add the protected networks to the &#039;&#039;mynetworks&#039;&#039; configuration line in /etc/postfix/main.cf&lt;br /&gt;
&lt;br /&gt;
This configuration change allows &#039;&#039;remote&#039;&#039; users to authenticate against the mail server and relay through it.  The rules for relaying are:&lt;br /&gt;
* Only authenticated users can relay&lt;br /&gt;
* Authentication Credentials must be encrypted with TLS or SSL&lt;br /&gt;
* Allow Submission and SMTPS ports for relaying (many consumer networks block port 25 - SMTP by default)&lt;br /&gt;
The process uses the dovecot authentication mechanism (used with IMAPS) to authenticate users before they are allowed to relay through postfix.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* Edit /etc/dovecot/dovecot.conf and add:&lt;br /&gt;
 # this is for postfix SASL (authenticated users can relay through us)&lt;br /&gt;
 socket listen {&lt;br /&gt;
                client {&lt;br /&gt;
                        path    = /var/spool/postfix/private/dovecot-auth.sock&lt;br /&gt;
                        mode    = 0660&lt;br /&gt;
                        user    = postfix&lt;br /&gt;
                        group   = postfix&lt;br /&gt;
                        }&lt;br /&gt;
                }&lt;br /&gt;
        }&lt;br /&gt;
* Restart dovecot&lt;br /&gt;
 /etc/init.d/dovecot restart&lt;br /&gt;
* Edit /etc/postfix/main.cf and add:&lt;br /&gt;
 # TLS Stuff -- since we allow SASL with tls *only*, we have to set up TLS first                    &lt;br /&gt;
 &lt;br /&gt;
 smtpd_tls_cert_file = /etc/lighttpd/server-bundle.pem&lt;br /&gt;
 smtpd_tls_key_file = /etc/lighttpd/server-bundle.pem&lt;br /&gt;
 smtpd_tls_CAfile = /etc/lighttpd/ca-crt.pem&lt;br /&gt;
 # If tls_security_level is set to &amp;quot;encrypt&amp;quot;, then SMTP rejects &lt;br /&gt;
 # unencrypted email (e.g. normal mail) which is bad.&lt;br /&gt;
 # By setting it to &amp;quot;may&amp;quot; you get TLS encrypted mail from google, slashdot, and other &lt;br /&gt;
 # interesting places.  Check your logs to see who&lt;br /&gt;
 smtpd_tls_security_level = may&lt;br /&gt;
 # Log info about the negotiated encryption levels&lt;br /&gt;
 smtpd_tls_received_header = yes&lt;br /&gt;
 smtpd_tls_loglevel = 1&lt;br /&gt;
 &lt;br /&gt;
 # SASL - this allows senders to authenticiate themselves&lt;br /&gt;
 # This along with &amp;quot;permit_sasl_authenticated&amp;quot; in smtpd_recipient_restrictions allows relaying&lt;br /&gt;
 smtpd_sasl_type = dovecot&lt;br /&gt;
 smtpd_sasl_path = private/dovecot-auth.sock&lt;br /&gt;
 smtpd_sasl_auth_enable = yes&lt;br /&gt;
 smtpd_sasl_authenticated_header = yes&lt;br /&gt;
 smtpd_tls_auth_only = yes&lt;br /&gt;
* Edit /etc/postfix/master.cf and enable the submission and smtps transports.  They are probably already at the top of your  master.cf file, just commented out:&lt;br /&gt;
 submission inet n       -       n       -       -       smtpd&lt;br /&gt;
   -o smtpd_tls_security_level=encrypt&lt;br /&gt;
   -o smtpd_sasl_auth_enable=yes&lt;br /&gt;
   -o smtpd_client_restrictions=permit_sasl_authenticated,reject&lt;br /&gt;
   -o milter_macro_daemon_name=ORIGINATING&lt;br /&gt;
 smtps     inet  n       -       n       -       -       smtpd&lt;br /&gt;
   -o smtpd_tls_security_level=encrypt&lt;br /&gt;
   -o smtpd_tls_wrappermode=yes&lt;br /&gt;
   -o smtpd_sasl_auth_enable=yes&lt;br /&gt;
   -o smtpd_client_restrictions=permit_sasl_authenticated,reject&lt;br /&gt;
   -o milter_macro_daemon_name=ORIGINATING&lt;br /&gt;
*Verfiy submission and smtps are defined in /etc/services&lt;br /&gt;
 grep &amp;quot;submission\|ssmtp&amp;quot; /etc/services&lt;br /&gt;
 submission	587/tcp				# mail message submission&lt;br /&gt;
 submission	587/udp&lt;br /&gt;
 smtps		465/tcp		ssmtp		# smtp protocol over TLS/SSL&lt;br /&gt;
 smtps		465/udp		ssmtp&lt;br /&gt;
* Restart postfix&lt;br /&gt;
 postfix reload&lt;br /&gt;
&lt;br /&gt;
At this point, you should be able to set up a mail client to relay through the server with TLS (port 587) or SSL (port 465)  Note that &amp;quot;plain&amp;quot; authentication is used because the underlying link is encrypted.  For example, in Thunderbird leave &amp;quot;secure authentication&amp;quot; unchecked, and choose STARTTLS (or TLS) for the connection security.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Mailbox Quotas ===&lt;br /&gt;
&lt;br /&gt;
In the default configuration, PostfixAdmin knows about quotas, but they are not enforced.   Documentation on the web mentions the [http://vda.sourceforge.net vda patch to postifx] to enforce quotas.  The only bad thing... its a &#039;&#039;patch&#039;&#039;.   Postfix and Dovecot are both conservative systems, so if the patch isn&#039;t in the upstream source, we&#039;ll assume there&#039;s a good reason.   There is a way of using quotas without patches - and it involves using the dovecot&#039;s [http://wiki.dovecot.org/LDA deliver] lda for local delivery.&lt;br /&gt;
&lt;br /&gt;
Note: As of Jan 2010, the documention is confusing, with multiple versions of dovecot, PostfixAdmin, and Mysql referenced.  These instructions apply to:&lt;br /&gt;
* Postgresql 8.4.2 &lt;br /&gt;
* PostfixAdmin 2.3 &lt;br /&gt;
* Dovecot 1.2.10&lt;br /&gt;
* Postfix 2.6.5&lt;br /&gt;
&lt;br /&gt;
Presumably later versions will work the same, but if not, please update the documentation and versions above.&lt;br /&gt;
&lt;br /&gt;
* Update /etc/dovecot.conf (old lines shown commented out):&lt;br /&gt;
 # old postfix &lt;br /&gt;
 #       userdb static {&lt;br /&gt;
 #               args =  uid=1006 gid=1006 home=/var/mail/domains/%d/%n&lt;br /&gt;
 #               }&lt;br /&gt;
 &lt;br /&gt;
 # new quota support:&lt;br /&gt;
        userdb prefetch {&lt;br /&gt;
                }&lt;br /&gt;
&lt;br /&gt;
        userdb sql {&lt;br /&gt;
                args = /etc/dovecot/dovecot-sql.conf&lt;br /&gt;
                }&lt;br /&gt;
&lt;br /&gt;
        socket listen {&lt;br /&gt;
                client {&lt;br /&gt;
                        path    = /var/spool/postfix/private/dovecot-auth.sock&lt;br /&gt;
                        mode    = 0660&lt;br /&gt;
                        user    = postfix&lt;br /&gt;
                        group   = postfix&lt;br /&gt;
                        }&lt;br /&gt;
                # These lines below are for the deliver lda&lt;br /&gt;
                master {&lt;br /&gt;
                        path =  /var/run/dovecot/auth-master&lt;br /&gt;
                        mode    = 0660&lt;br /&gt;
                        user    = vmail&lt;br /&gt;
                        group   = vmail&lt;br /&gt;
                        }&lt;br /&gt;
                }&lt;br /&gt;
 &lt;br /&gt;
 protocol imap {                                                               &lt;br /&gt;
         mail_plugins = quota imap_quota                                       &lt;br /&gt;
         }                                                                     &lt;br /&gt;
                                                                              &lt;br /&gt;
 protocol pop3 {                                                               &lt;br /&gt;
         mail_plugins = quota                                                  &lt;br /&gt;
         }                                                                     &lt;br /&gt;
                                                                              &lt;br /&gt;
 dict {                                                                        &lt;br /&gt;
        quotadict = pgsql:/etc/dovecot/dovecot-dict-quota.conf                &lt;br /&gt;
        }                                                                     &lt;br /&gt;
                                                                              &lt;br /&gt;
 plugin {                                                                      &lt;br /&gt;
         quota = dict:user::proxy::quotadict                                   &lt;br /&gt;
         }                                                     &lt;br /&gt;
                                                              &lt;br /&gt;
 protocol lda {                                                &lt;br /&gt;
   postmaster_address = postmaster@host.example.com&lt;br /&gt;
   mail_plugins = quota                                        &lt;br /&gt;
   auth_socket_path =  /var/run/dovecot/auth-master&lt;br /&gt;
   sendmail_path = /usr/sbin/sendmail&lt;br /&gt;
 }                                                                            &lt;br /&gt;
    &lt;br /&gt;
You should already have a &amp;lt;tt&amp;gt;socket-&amp;gt; listen-&amp;gt; client&amp;lt;/tt&amp;gt; section, but it is listed above to show where it goes in relationship to the &amp;lt;tt&amp;gt;socket -&amp;gt; listen -&amp;gt; master&amp;lt;/tt&amp;gt; section&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* edit &amp;lt;tt&amp;gt;/etc/dovecot/dovecot-sql.conf&amp;lt;/tt&amp;gt; and replace the user and password queries with the following (you may not have a user_query yet - add it):&lt;br /&gt;
&lt;br /&gt;
 password_query = select username as user, password, 1006 as userdb_uid, 1006 as userdb_gid, &#039;*:bytes=&#039; || quota as userdb_quota_rule from mailbox  where local_part = &#039;%n&#039; and domain = &#039;%d&#039;&lt;br /&gt;
 user_query = select maildir as home, 1006 as uid, 1006 as gid, &#039;*:bytes=&#039; || quota  as quota_rule from mailbox where local_part = &#039;%n&#039; and domain =&#039;%d&#039;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* create &amp;lt;tt&amp;gt;/etc/dovecot/dovecot-dict-quota.conf&amp;lt;/tt&amp;gt;&lt;br /&gt;
 connect = host=localhost dbname=postfix user=postfix password=********&lt;br /&gt;
 &lt;br /&gt;
 map {&lt;br /&gt;
         pattern = priv/quota/storage&lt;br /&gt;
         table = quota2&lt;br /&gt;
         username_field =username&lt;br /&gt;
         value_field = bytes&lt;br /&gt;
 }&lt;br /&gt;
 &lt;br /&gt;
 map {&lt;br /&gt;
        pattern= priv/quota/messages&lt;br /&gt;
        table = quota2&lt;br /&gt;
        username_field = username&lt;br /&gt;
        value_field = messages&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
Side note: [http://wiki.dovecot.org/Quota/Dict The Dovecot Quota Documentation] mentions the need for a trigger with pgsql.  This was created in the PostfixAdmin install, which is why you instantiated the pgsql language when creating the database.  If not, you will need to create the trigger, to reference the quota2 table, not the quota table mentioned in the dovecot docs.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* create a new transport for the dovecot lda.   Add the following to  /etc/postfix/master.cf:&lt;br /&gt;
 # The dovecot deliver lda&lt;br /&gt;
 dovecot   unix  -       n       n       -       -       pipe&lt;br /&gt;
   flags=DRhu user=vmail:vmail argv=/usr/libexec/dovecot/deliver -f ${sender} -d ${user}@${nexthop}&lt;br /&gt;
&lt;br /&gt;
* Edit the /etc/postfix/main.cf.  Replace &lt;br /&gt;
 virtual_transport = virtual &lt;br /&gt;
with&lt;br /&gt;
 virtual_transport = dovecot&lt;br /&gt;
 dovecot_destination_recipient_limit = 1&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;TODO&#039;&#039;&#039;  This will cause over-quota emails to bounce.   Which could be a source of backscatter.   We need a way of checking quota limits after RBL checking but before the message is accepted in the queue.&lt;br /&gt;
&lt;br /&gt;
=== WebMail (RoundCube) ===&lt;br /&gt;
&lt;br /&gt;
[http://roundcube.net/ RoundCube] is an &amp;quot;ajax /Web2.0&amp;quot; web-mail client.  These instructions are for the Alpine Linux 1.10 repository &lt;br /&gt;
&lt;br /&gt;
* Add the package and related php modules:&lt;br /&gt;
 apk add roundcubemail php-xml php-openssl php-mcrypt php-gd php-iconv&lt;br /&gt;
&lt;br /&gt;
* link the roundcube application back into the docroot&lt;br /&gt;
 ln -s /usr/share/webapps/roundcube /var/www/domains/host.example.com/www/roundcube&lt;br /&gt;
&lt;br /&gt;
* follow the instructions in /usr/share/webapps/roundcube/INSTALL:&lt;br /&gt;
 chown -R lighttpd:lighttpd temp logs&lt;br /&gt;
 &lt;br /&gt;
 su postgres&lt;br /&gt;
 createuser roundcube&lt;br /&gt;
   Shall the new role be a superuser? (y/n) n&lt;br /&gt;
   Shall the new role be allowed to create databases? (y/n) n&lt;br /&gt;
   Shall the new role be allowed to create more new roles? (y/n) y&lt;br /&gt;
 createdb -O roundcube -E UNICODE -T template0 roundcubemail&lt;br /&gt;
 psql roundcubemail&lt;br /&gt;
   roundcubemail=# ALTER USER roundcube WITH PASSWORD &#039;the_new_password&#039;;&lt;br /&gt;
   roundcubemail=# \c - roundcube&lt;br /&gt;
   \i /usr/share/webapps/roundcube/SQL/postgres.initial.sql&lt;br /&gt;
   \q&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* restart lighttpd to verify the new php libraries are used&lt;br /&gt;
 /etc/init.d/lighttpd restart&lt;br /&gt;
&lt;br /&gt;
* Point your browser to http://host.example.com/roundcube/installer&lt;br /&gt;
** Begin installation&lt;br /&gt;
** Follow the instructions in step 3 of the install to copy the files to the server&lt;br /&gt;
* edit /etc/php/php.ini and edit date.timezone to your local timezone, or to UTC&lt;br /&gt;
* if necessary (e.g. you had to reset the local timezone) restart lighttpd to reload php&lt;br /&gt;
 /etc/init.d/lighttpd restart&lt;br /&gt;
* You should now be able to get to roundcube at http://host.example.com/roundcube&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
For the specific configuration parameters in the install step:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!Property&lt;br /&gt;
!Setting&lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;enable_spellcheck&#039;&#039; ||   disabled &lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;identities_level&#039;&#039; ||  one identity with possibility to edit all params but not email address &lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;log driver&#039;&#039; || syslog &lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;sylog_id&#039;&#039; || roundcube &lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;syslog_facility&#039;&#039; || mailsubsystem &lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;db_dnsw&#039;&#039; || pgsql properties, as described above &lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;imap_host&#039;&#039; || 127.0.0.1 &lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;auto_create_user&#039;&#039; || enabled &lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;smtp_server&#039;&#039; ||  127.0.0.1&lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;smtp_port&#039;&#039; ||  25&lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;smtp_user/smtp_pass&#039;&#039; ||  enable &#039;&#039;Use Current IMAP username and password for SMTP authentication&#039;&#039;&lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;smtp_log&#039;&#039; ||  enable (optional, but gives additional log record)&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
The other items can be left at default settings, or adjusted if desired.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
After its working, the INSTALL file recommends removing the install directory.   If you want to keep the installer around later, you can simply change the ownership and permissions.  So do &#039;&#039;&#039;one&#039;&#039;&#039; of the following:&lt;br /&gt;
 cd /usr/share/webapps/roundcube&lt;br /&gt;
 rm -rf LICENSE UPGRADING INSTALL README CHANGELOG  SQL installer&lt;br /&gt;
or&lt;br /&gt;
 cd /usr/share/webapps/roundcube&lt;br /&gt;
 chown -R root:root LICENSE UPGRADING INSTALL README CHANGELOG  SQL installer&lt;br /&gt;
 chmod -R 600 LICENSE UPGRADING INSTALL README CHANGELOG SQL &lt;br /&gt;
 chmod 700 SQL installer&lt;br /&gt;
&lt;br /&gt;
== log rotation ==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
Special thanks to DHughes for providing a 3 page email on how to set up postgres,postfix,PostfixAdmin,dovecot and roundcube.  It was the clearer than all the other guides available on the Net. Thanks!&lt;/div&gt;</summary>
		<author><name>Djhughes</name></author>
	</entry>
	<entry>
		<id>https://wiki.alpinelinux.org/w/index.php?title=ISP_Mail_Server_HowTo&amp;diff=3346</id>
		<title>ISP Mail Server HowTo</title>
		<link rel="alternate" type="text/html" href="https://wiki.alpinelinux.org/w/index.php?title=ISP_Mail_Server_HowTo&amp;diff=3346"/>
		<updated>2010-02-15T19:14:17Z</updated>

		<summary type="html">&lt;p&gt;Djhughes: config file typo&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== A Full Service Mail Server ==&lt;br /&gt;
&lt;br /&gt;
The goal of this document is to describe how to set up postfix, dovecot, clamav, dspam, roundecube, and postfixadmin for a full-featured &amp;quot;ISP&amp;quot; level mail server.&lt;br /&gt;
&lt;br /&gt;
The server must provide:&lt;br /&gt;
&lt;br /&gt;
* multiple virtual domains&lt;br /&gt;
* admins for each domain (to add/remove virtual accounts)&lt;br /&gt;
* Quota support per domain / account&lt;br /&gt;
* downloading email via IMAP / IMAPS / POP3 / POP3S&lt;br /&gt;
* relaying email for authenticated users with TLS or SSL (Submission / SMTPS protocol)&lt;br /&gt;
* Standard filters (virus/spam/rbl/etc)&lt;br /&gt;
* Web mail client&lt;br /&gt;
* Value Add services&lt;br /&gt;
&lt;br /&gt;
== Configure DNS ==&lt;br /&gt;
&lt;br /&gt;
This server will host three separate virtual domains on the same web server. They will be distinguished by their domains, so you must choose three domains for the three separate services:&lt;br /&gt;
&lt;br /&gt;
* ACF - Alpine Configuration Framework for managing the server&lt;br /&gt;
* PostfixAdmin - for managing the postfix installation&lt;br /&gt;
* RoundCube - for accessing individual mailboxes&lt;br /&gt;
&lt;br /&gt;
Choose three different domains (from here on known as ACF_DOMAIN, POSTFIXADMIN_DOMAIN, and ROUNDCUBE_DOMAIN) and configure DNS for all three to point to the IP address of your host.&lt;br /&gt;
&lt;br /&gt;
== Set up Lighttpd + PHP ==&lt;br /&gt;
&lt;br /&gt;
PostfixAdmin needs php pgpsql and imap modules, so we do it in this step.&lt;br /&gt;
&lt;br /&gt;
  apk add lighttpd php php-pgsql php-imap&lt;br /&gt;
&lt;br /&gt;
Stop and remove mini_httpd, and move ACF to lighttpd;  We are setting this up to be a multi-domain virtual web server (replace ACF_DOMAIN with the actual domain):&lt;br /&gt;
&lt;br /&gt;
  mkdir -p /var/www/domains/ACF_DOMAIN&lt;br /&gt;
  ln -s /usr/share/acf/www /var/www/domains/ACF_DOMAIN/www&lt;br /&gt;
&lt;br /&gt;
Edit /etc/lighttpd/mod_cgi.conf to serve haserl files by adding a &amp;quot;&amp;quot; =&amp;gt; &amp;quot;&amp;quot; cgi handler&lt;br /&gt;
&lt;br /&gt;
 $HTTP[&amp;quot;url&amp;quot;] =~ &amp;quot;^/cgi-bin/&amp;quot; {&lt;br /&gt;
     # disable directory listings&lt;br /&gt;
     dir-listing.activate = &amp;quot;disable&amp;quot;&lt;br /&gt;
     # only allow cgi&#039;s in this directory&lt;br /&gt;
     cgi.assign = (&lt;br /&gt;
 		&amp;quot;.pl&amp;quot;	=&amp;gt;	&amp;quot;/usr/bin/perl&amp;quot;,&lt;br /&gt;
 		&amp;quot;.cgi&amp;quot;	=&amp;gt;	&amp;quot;/usr/bin/perl&amp;quot;,&lt;br /&gt;
 		&amp;quot;&amp;quot; =&amp;gt; &amp;quot;&amp;quot;&lt;br /&gt;
 	)&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
Add these lines to /etc/lighttpd/lighttpd.conf to point to the new document root, and set it up to listen on port 443 (replace &#039;&#039;ROUNDCUBE_DOMAIN&#039;&#039; with the roundcube domain and &#039;&#039;ip_address_of_server&#039;&#039; with the actual IP address):&lt;br /&gt;
&lt;br /&gt;
 simple-vhost.server-root   = &amp;quot;/var/www/domains/&amp;quot;&lt;br /&gt;
 simple-vhost.default-host  = &amp;quot;/ROUNDCUBE_DOMAIN/&amp;quot;&lt;br /&gt;
 simple-vhost.document-root = &amp;quot;www/&amp;quot;&lt;br /&gt;
 &lt;br /&gt;
 $SERVER[&amp;quot;socket&amp;quot;] == &amp;quot;ip_address_of_server:443&amp;quot; {&lt;br /&gt;
 ssl.engine    = &amp;quot;enable&amp;quot;&lt;br /&gt;
 ssl.pemfile   = &amp;quot;/etc/lighttpd/server-bundle.pem&amp;quot;&lt;br /&gt;
 ssl.ca-file   = &amp;quot;/etc/lighttpd/ca-crt.pem&amp;quot;&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
Ensure that the simple_vhosts module is loaded, as well as the cgi config scripts by uncommenting the following lines in /etc/lighttpd/lighttpd.conf&lt;br /&gt;
&lt;br /&gt;
 server.modules = (&lt;br /&gt;
     #  other modules may be listed&lt;br /&gt;
     &amp;quot;mod_simple_vhost&amp;quot;, &lt;br /&gt;
     #  other modules may be listed&lt;br /&gt;
  .&lt;br /&gt;
  .&lt;br /&gt;
  .&lt;br /&gt;
     include &amp;quot;mod_cgi.conf&amp;quot;&lt;br /&gt;
 &lt;br /&gt;
     include &amp;quot;mod_fastcgi.conf&amp;quot;&lt;br /&gt;
 &lt;br /&gt;
&lt;br /&gt;
Get a web certificate, and install it.  If you want to use a self-signed cert, you can use [[Generating SSL certs with ACF]] or [[Generating SSL certs with ACF 1.9]].  If you create a certificate with ACF, you can create the &amp;quot;server-bundle.pem&amp;quot; and the &amp;quot;ca-crt.pem&amp;quot; file with these commands:&lt;br /&gt;
&lt;br /&gt;
  openssl pkcs12 -nokeys -cacerts -in certificate.pfx  -out /etc/lighttpd/ca-crt.pem&lt;br /&gt;
  openssl pkcs12 -nodes -in certifcate.pfx -out /etc/lighttpd/server-bundle.pem&lt;br /&gt;
  chown root:root /etc/lighttpd/server-bundle.pem&lt;br /&gt;
  chmod 400 /etc/lighttpd/server-bundle.pem&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Note:&#039;&#039;&#039; The server certificate &#039;&#039;and&#039;&#039; key are in the server-bundle.pem file, so it is critical that the file be read-only by user &amp;quot;root&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
 Editme: We should probably only serve ACF to restricted hosts&lt;br /&gt;
&lt;br /&gt;
Stop and remove mini_httpd; start lighttpd, test&lt;br /&gt;
&lt;br /&gt;
  /etc/init.d/mini_httpd stop&lt;br /&gt;
  rc-update del mini_httpd&lt;br /&gt;
  apk del mini_httpd&lt;br /&gt;
  rc-update add lighttpd&lt;br /&gt;
  /etc/init.d/lighttpd start&lt;br /&gt;
&lt;br /&gt;
At this point you should be able to see ACF being served with lighttpd:  https://ACF_DOMAIN/&lt;br /&gt;
&lt;br /&gt;
== Install Postgresql ==&lt;br /&gt;
&lt;br /&gt;
Add and configure postgresql&lt;br /&gt;
&lt;br /&gt;
  apk add acf-postgresql postgresql-client&lt;br /&gt;
  /etc/init.d/postgresql setup&lt;br /&gt;
  /etc/init.d/postgresql start&lt;br /&gt;
  rc-update add postgresql&lt;br /&gt;
&lt;br /&gt;
At this point any user can connect to the sql server with &amp;quot;trust&amp;quot; mechanism.  If you want to enforce password authentication (you probably do) edit /var/lib/postgresql/8.4/data/pg_hba.conf&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
  Editme: What should we recommend?&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Create the postfix database:&lt;br /&gt;
&lt;br /&gt;
  psql -U postgres&lt;br /&gt;
   create user postfix with password &#039;******&#039;;&lt;br /&gt;
   create database postfix owner postfix;&lt;br /&gt;
   \c postfix&lt;br /&gt;
   create language plpgsql;&lt;br /&gt;
   \q&lt;br /&gt;
&lt;br /&gt;
(Of course, use your selected password where ******* is shown above.)&lt;br /&gt;
&lt;br /&gt;
== Install PostfixAdmin ==&lt;br /&gt;
&lt;br /&gt;
We are going to install the postfix admin web front-end before we install the mail server.  This just creates an interface to populate the SQL tables that postfix and dovecot will use.&lt;br /&gt;
&lt;br /&gt;
Download PostfixAdmin from Sourceforge.  When these instructions were written, 2.3 was the current release, so (replace POSTFIXADMIN_DOMAIN with the actual domain):&lt;br /&gt;
 wget http://downloads.sourceforge.net/project/postfixadmin/postfixadmin/postfixadmin_2.3.tar.gz&lt;br /&gt;
 tar zxvf postfixadmin_2.3.tar.gz&lt;br /&gt;
 mkdir -p /var/www/domains/POSTFIXADMIN_DOMAIN/www&lt;br /&gt;
 mv postfixadmin-2.3/* /var/www/domains/POSTFIXADMIN_DOMAIN/www&lt;br /&gt;
 rm -rf postfixadmin*&lt;br /&gt;
&lt;br /&gt;
Edit /var/www/domains/POSTFIXADMIN_DOMAIN/www/config.inc.php and modify at least these lines (replace POSTFIXADMIN_DOMAIN with the actual domain):&lt;br /&gt;
&lt;br /&gt;
 $CONF[&#039;configured&#039;] = true;&lt;br /&gt;
 $CONF[&#039;setup_password&#039;] = &amp;quot;&amp;quot;;  &amp;lt;&amp;lt; Don&#039;t change this yet&lt;br /&gt;
 $CONF[&#039;database_type&#039;] = &#039;pgsql&#039;;&lt;br /&gt;
 $CONF[&#039;database_host&#039;] = &#039;localhost&#039;;&lt;br /&gt;
 $CONF[&#039;database_user&#039;] = &#039;postfix&#039;;&lt;br /&gt;
 $CONF[&#039;database_password&#039;] = &#039;*****&#039;;   &amp;lt;&amp;lt; The password you chose above&lt;br /&gt;
 $CONF[&#039;database_name&#039;] = &#039;postfix&#039;;&lt;br /&gt;
 $CONF[&#039;database_prefix&#039;] = &#039;&#039;;&lt;br /&gt;
 $CONF[&#039;admin_email&#039;] = &#039;you@some.email.com&#039;;  &amp;lt;&amp;lt; Your email address &lt;br /&gt;
 $CONF[&#039;encrypt&#039;] = &#039;md5crypt&#039;;&lt;br /&gt;
 $CONF[&#039;authlib_default_flavor&#039;] = &#039;md5raw&#039;;&lt;br /&gt;
 $CONF[&#039;dovecotpw&#039;] = &amp;quot;/usr/sbin/dovecotpw&amp;quot;;&lt;br /&gt;
 $CONF[&#039;domain_path&#039;] = &#039;YES&#039;;&lt;br /&gt;
 $CONF[&#039;domain_in_mailbox&#039;] = &#039;NO&#039;;&lt;br /&gt;
 $CONF[&#039;aliases&#039;] = &#039;10&#039;;                       &lt;br /&gt;
 $CONF[&#039;mailboxes&#039;] = &#039;10&#039;;&lt;br /&gt;
 $CONF[&#039;maxquota&#039;] = &#039;10&#039;;&lt;br /&gt;
 $CONF[&#039;vacation&#039;] = &#039;NO&#039;; &lt;br /&gt;
 $CONF[&#039;vacation_control&#039;] =&#039;NO&#039;;&lt;br /&gt;
 $CONF[&#039;vacation_control_admin&#039;] = &#039;NO&#039;;&lt;br /&gt;
 $CONF[&#039;create_mailbox_subdirs_prefix&#039;]=&amp;quot;&amp;quot;;  &lt;br /&gt;
 $CONF[&#039;quota&#039;] = &#039;YES&#039;;&lt;br /&gt;
 $CONF[&#039;quota_multiplier&#039;] = &#039;1024000&#039;;&lt;br /&gt;
 $CONF[&#039;used_quotas&#039;] = &#039;YES&#039;;   &lt;br /&gt;
 $CONF[&#039;new_quota_table&#039;] = &#039;YES&#039;;  &lt;br /&gt;
 $CONF[&#039;alias_control&#039;] = &#039;YES&#039;;&lt;br /&gt;
 $CONF[&#039;alias_control_admin&#039;] = &#039;YES&#039;;&lt;br /&gt;
 $CONF[&#039;special_alias_control&#039;] = &#039;YES&#039;;&lt;br /&gt;
 $CONF[&#039;fetchmail&#039;] = &#039;NO&#039;;&lt;br /&gt;
 $CONF[&#039;user_footer_link&#039;] = &amp;quot;http://POSTFIXADMIN_DOMAIN&amp;quot;;&lt;br /&gt;
 $CONF[&#039;footer_link&#039;] = &#039;http://POSTFIXADMIN_DOMAIN/main.php&#039;;&lt;br /&gt;
&lt;br /&gt;
You should further edit /var/www/domains/POSTFIXADMIN_DOMAIN/www/config.inc.php and replace all instances of &amp;quot;change-this-to-your.domain.tld&amp;quot; with your actual mail domain.&lt;br /&gt;
&lt;br /&gt;
Go to http://POSTFIXADMIN_DOMAIN/setup.php&lt;br /&gt;
&lt;br /&gt;
Create the password hash, add it to the config.inc.php file&lt;br /&gt;
&lt;br /&gt;
Go back to http://POSTFIXADMIN_DOMAIN/setup.php&lt;br /&gt;
&lt;br /&gt;
Create superadmin account.&lt;br /&gt;
&lt;br /&gt;
== Install Postfix ==&lt;br /&gt;
&lt;br /&gt;
Create a user for the virtual mail delivery, and get its uid/gid (you&#039;ll need the numeric uid/gid for postfix)&lt;br /&gt;
&lt;br /&gt;
 adduser vmail -H -D -s /bin/false&lt;br /&gt;
 grep vmail /etc/passwd&lt;br /&gt;
&lt;br /&gt;
(In examples below, we use 1006/1006 for the uid/gid)&lt;br /&gt;
&lt;br /&gt;
Create the mail directory, and assign vmail as the owner&lt;br /&gt;
 mkdir -p /var/mail/domains&lt;br /&gt;
 chown -R vmail:vmail /var/mail/domains&lt;br /&gt;
 &lt;br /&gt;
&lt;br /&gt;
Install postfix&lt;br /&gt;
&lt;br /&gt;
 apk add acf-postfix postfix-pgsql&lt;br /&gt;
&lt;br /&gt;
Edit the /etc/postfix/main.cf file  Here&#039;s an example:&lt;br /&gt;
&lt;br /&gt;
 myhostname=host.example.com&lt;br /&gt;
 mydomain=example.com&lt;br /&gt;
 &lt;br /&gt;
 mydestination = localhost.$mydomains, localhost&lt;br /&gt;
 mynetworks_style = subnet&lt;br /&gt;
 mynetworks = 127.0.0.0/8&lt;br /&gt;
 &lt;br /&gt;
 virtual_mailbox_domains = proxy:pgsql:/etc/postfix/sql/pgsql_virtual_domains_maps.cf&lt;br /&gt;
 virtual_alias_maps = proxy:pgsql:/etc/postfix/sql/pgsql_virtual_alias_maps.cf,&lt;br /&gt;
        proxy:pgsql:/etc/postfix/sql/pgsql_virtual_alias_domain_maps.cf,&lt;br /&gt;
        proxy:pgsql:/etc/postfix/sql/pgsql_virtual_alias_domain_catchall_maps.cf&lt;br /&gt;
 &lt;br /&gt;
 virtual_mailbox_maps = proxy:pgsql:/etc/postfix/sql/pgsql_virtual_mailbox_maps.cf,&lt;br /&gt;
        proxy:pgsql:/etc/postfix/sql/pgsql_virtual_alias_domain_mailbox_maps.cf&lt;br /&gt;
 &lt;br /&gt;
 virtual_mailbox_base = /var/mail/domains/&lt;br /&gt;
 virtual_gid_maps = static:1006&lt;br /&gt;
 virtual_uid_maps = static:1006&lt;br /&gt;
 virtual_minimum_uid = 100&lt;br /&gt;
 virtual_transport = virtual&lt;br /&gt;
 &lt;br /&gt;
 &lt;br /&gt;
 # This next command means you must create a virtual&lt;br /&gt;
 # domain for the host itself - ALL mail goes through&lt;br /&gt;
 # The virtual transport&lt;br /&gt;
 &lt;br /&gt;
 mailbox_transport = virtual&lt;br /&gt;
 local_transport = virtual&lt;br /&gt;
 local_transport_maps = $virtual_mailbox_maps&lt;br /&gt;
 &lt;br /&gt;
 smtpd_helo_required = yes&lt;br /&gt;
 disable_vrfy_command = yes&lt;br /&gt;
 message_size_limit = 10240000&lt;br /&gt;
 queue_minfree = 51200000&lt;br /&gt;
 &lt;br /&gt;
 smtpd_sender_restrictions =&lt;br /&gt;
        permit_mynetworks,&lt;br /&gt;
        reject_non_fqdn_sender,&lt;br /&gt;
        reject_unknown_sender_domain&lt;br /&gt;
 &lt;br /&gt;
 smtpd_recipient_restrictions =&lt;br /&gt;
        reject_non_fqdn_recipient,&lt;br /&gt;
        reject_unknown_recipient_domain,&lt;br /&gt;
        permit_mynetworks,&lt;br /&gt;
        permit_sasl_authenticated,&lt;br /&gt;
        reject_unauth_destination,&lt;br /&gt;
        reject_rbl_client dnsbl.sorbs.net,&lt;br /&gt;
        reject_rbl_client zen.spamhaus.org,&lt;br /&gt;
        reject_rbl_client bl.spamcop.net&lt;br /&gt;
 &lt;br /&gt;
 smtpd_data_restrictions = reject_unauth_pipelining&lt;br /&gt;
 &lt;br /&gt;
 # we will use this later - This prevents cleartext authentication&lt;br /&gt;
 # for relaying&lt;br /&gt;
 smtpd_tls_auth_only = yes&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Now we need to create a *bunch* of files so that postfix can get the delivery information out of sql. Here&#039;s a shell script to create the scripts.  Change PGPW to the password for the postfix user of the postfix SQL database.&lt;br /&gt;
&lt;br /&gt;
 cd /etc/postfix&lt;br /&gt;
 mkdir sql&lt;br /&gt;
 PGPW=&amp;quot;ChangeMe&amp;quot;&lt;br /&gt;
 &lt;br /&gt;
 cat - &amp;lt;&amp;lt;EOF &amp;gt;sql/pgsql_virtual_alias_domain_catchall_maps.cf&lt;br /&gt;
 user=postfix&lt;br /&gt;
 password = $PGPW&lt;br /&gt;
 hosts = localhost&lt;br /&gt;
 dbname = postfix&lt;br /&gt;
 query = Select goto From alias,alias_domain where alias_domain.alias_domain = &#039;%d&#039; and alias.address = &#039;@&#039; ||  alias_domain.target_domain and alias.active = true and alias_domain.active= true &lt;br /&gt;
 EOF&lt;br /&gt;
 &lt;br /&gt;
 cat - &amp;lt;&amp;lt;EOF &amp;gt;sql/pgsql_virtual_alias_domain_mailbox_maps.cf&lt;br /&gt;
 user=postfix&lt;br /&gt;
 password = $PGPW&lt;br /&gt;
 hosts = localhost&lt;br /&gt;
 dbname = postfix&lt;br /&gt;
 query = Select maildir from mailbox,alias_domain where alias_domain.alias_domain = &#039;%d&#039; and mailbox.username = &#039;%u&#039; || &#039;@&#039; || alias_domain.target_domain and mailbox.active = true and alias_domain.active&lt;br /&gt;
 EOF&lt;br /&gt;
 &lt;br /&gt;
 cat - &amp;lt;&amp;lt;EOF &amp;gt;sql/pgsql_virtual_alias_domain_maps.cf&lt;br /&gt;
 user=postfix&lt;br /&gt;
 password = $PGPW&lt;br /&gt;
 hosts = localhost&lt;br /&gt;
 dbname = postfix&lt;br /&gt;
 query = select goto from alias,alias_domain where alias_domain.alias_domain=&#039;%d&#039; and alias.address = &#039;%u&#039; || &#039;@&#039; || alias_domain.target_domain and alias.active= true and alias_domain.active= true&lt;br /&gt;
 EOF&lt;br /&gt;
 &lt;br /&gt;
 cat - &amp;lt;&amp;lt;EOF &amp;gt;sql/pgsql_virtual_alias_maps.cf&lt;br /&gt;
 user=postfix&lt;br /&gt;
 password = $PGPW&lt;br /&gt;
 hosts = localhost&lt;br /&gt;
 dbname = postfix&lt;br /&gt;
 query = Select goto From alias Where address=&#039;%s&#039; and active =&#039;1&#039;&lt;br /&gt;
 EOF&lt;br /&gt;
 &lt;br /&gt;
 cat - &amp;lt;&amp;lt;EOF &amp;gt;sql/pgsql_virtual_domains_maps.cf&lt;br /&gt;
 user=postfix&lt;br /&gt;
 password = $PGPW&lt;br /&gt;
 hosts = localhost&lt;br /&gt;
 dbname = postfix&lt;br /&gt;
 query = Select domain from domain where domain=&#039;%s&#039; and active=&#039;1&#039;&lt;br /&gt;
 EOF&lt;br /&gt;
 &lt;br /&gt;
 cat - &amp;lt;&amp;lt;EOF &amp;gt;sql/pgsql_virtual_mailbox_maps.cf&lt;br /&gt;
 user=postfix&lt;br /&gt;
 password = $PGPW&lt;br /&gt;
 hosts = localhost&lt;br /&gt;
 dbname = postfix&lt;br /&gt;
 query = Select maildir from mailbox where username=&#039;%s&#039; and active=true&lt;br /&gt;
 EOF&lt;br /&gt;
 &lt;br /&gt;
 chown -R postfix:postfix sql&lt;br /&gt;
 chmod 640 sql/*&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
At this point you should be able to start up postfix&lt;br /&gt;
 &lt;br /&gt;
 newaliases  # so postfix is happy...&lt;br /&gt;
 /etc/init.d/postfix start&lt;br /&gt;
 rc-update add postfix&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Create a domain in PostfixAdmin and test ===&lt;br /&gt;
&lt;br /&gt;
Go to http://POSTFIXADMIN_DOMAIN/&lt;br /&gt;
&lt;br /&gt;
Log in using the superadmin account, create a domain for the local box (e.g. example.com), and create a user mailbox (e.g. root).&lt;br /&gt;
&lt;br /&gt;
From the machine, send a test message:&lt;br /&gt;
&lt;br /&gt;
 sendmail -t root@example.com&lt;br /&gt;
 subject: test&lt;br /&gt;
 .&lt;br /&gt;
 ^d&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
In /var/log/mail.log (or /var/log/messages, if you still have busybox syslogd running) you should see the message queued.  The message should be in /var/mail/domains/example.com/root/new&lt;br /&gt;
&lt;br /&gt;
== Install Dovecot ==&lt;br /&gt;
&lt;br /&gt;
Dovecot is the POP3/IMAP server to retrieve mail.&lt;br /&gt;
&lt;br /&gt;
As before, we install dovecot: &lt;br /&gt;
&lt;br /&gt;
 apk add acf-dovecot dovecot-pgsql&lt;br /&gt;
&lt;br /&gt;
edit /etc/dovecot/dovecot.conf&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 # Select only the protocols you wish to support - all are listed in the next line&lt;br /&gt;
 protocols               =       imap imaps pop pop3s&lt;br /&gt;
 log_path                =       /var/log/dovecot.log&lt;br /&gt;
 info_log_path           =       /var/log/dovecot-info.log&lt;br /&gt;
 disable_plaintext_auth  =       no&lt;br /&gt;
&lt;br /&gt;
 # Authenticated IMAP&lt;br /&gt;
 ssl                     =       yes&lt;br /&gt;
 ssl_cert_file           =       /etc/lighttpd/server-bundle.pem&lt;br /&gt;
 ssl_key_file            =       /etc/lighttpd/server-bundle.pem&lt;br /&gt;
 auth_verbose            =       yes&lt;br /&gt;
 auth_debug              =       no&lt;br /&gt;
 mail_location           =       maildir:/var/mail/domains/%d/%n&lt;br /&gt;
 auth default    {&lt;br /&gt;
        mechanisms = plain&lt;br /&gt;
        passdb sql {&lt;br /&gt;
                args = /etc/dovecot/dovecot-sql.conf&lt;br /&gt;
                }&lt;br /&gt;
        userdb static {&lt;br /&gt;
                args =  uid=1006 gid=1006 home=/var/mail/domains/%d/%n&lt;br /&gt;
                }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
We need a certificate for SSL/TLS authentication, so in the example above, we use the lighttpd cert. That way when the cert is renewed/replaced, Dovecot will have access to the new cert as well.  &lt;br /&gt;
&lt;br /&gt;
Create the /etc/dovecot/dovecot-sql.conf file:&lt;br /&gt;
&lt;br /&gt;
 driver = pgsql&lt;br /&gt;
 connect = host=localhost dbname=postfix user=postfix password=********&lt;br /&gt;
 password_query = select username,password from mailbox where local_part = &#039;%n&#039; and domain = &#039;%d&#039;&lt;br /&gt;
 default_pass_scheme =  MD5-CRYPT&lt;br /&gt;
&lt;br /&gt;
Again, change the password above to your postfix user password, and protect the file from prying eyes:&lt;br /&gt;
&lt;br /&gt;
 chown root:root /etc/dovecot/dovecot-sql.conf&lt;br /&gt;
 chmod 600 /etc/dovecot/dovecot-sql.conf&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Start dovecot&lt;br /&gt;
 /etc/init.d/dovecot start&lt;br /&gt;
 rc-update add dovecot&lt;br /&gt;
&lt;br /&gt;
== Testing ==&lt;br /&gt;
&lt;br /&gt;
Make sure your firewall allows in ports 25(SMTP) 110 (POP3), 995 (POP3S), 143(IMAP), 993(IMAPS), or whatever subset you support.  &lt;br /&gt;
 &lt;br /&gt;
At this point, you should be able to:&lt;br /&gt;
 * Create a new domain and add users with PostfixAdmin&lt;br /&gt;
 * Send mail to those users via SMTP to port 25&lt;br /&gt;
 * Retrieve mail using the user&#039;s full email and password (e.g. username: user@example.com  password: ChangeM&lt;br /&gt;
&lt;br /&gt;
== Value Add Features ==&lt;br /&gt;
&lt;br /&gt;
If you followed the guide above, you now have a functional mail server with many interconnected parts.  The features below assume that the server is already running as described above.  You should be able to add any or all of these features below to further enhance the mail service.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Virus Scanning ===&lt;br /&gt;
&lt;br /&gt;
This procedure uses clamav and the postfix content_filter mechanism to scan inbound and outbound email for viruses.  Infected emails are dropped.  Clean emails are tagged with a &amp;quot;scanned by clamav&amp;quot; header.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* Install clamav and clamsmtp:&lt;br /&gt;
 apk add acf-clamav clamsmtp&lt;br /&gt;
* Edit the /etc/clamav/clamd.conf file if desired (not necessary in most cases)&lt;br /&gt;
* Edit /etc/clamsmtpd.conf and verify the following lines&lt;br /&gt;
 OutAddress: 10026&lt;br /&gt;
 Listen: 127.0.0.1:10025                                               &lt;br /&gt;
 Header: X-Virus-Scanned: ClamAV using ClamSMTP&lt;br /&gt;
 Action: drop&lt;br /&gt;
 User: clamav                                                      &lt;br /&gt;
* Start the daemons&lt;br /&gt;
 rc-update add clamd&lt;br /&gt;
 rc-update add freshclam&lt;br /&gt;
 rc-update add clamsmtp&lt;br /&gt;
 /etc/init.d/clamd start&lt;br /&gt;
 /etc/init.d/freshclam start&lt;br /&gt;
 /etc/init.d/clamsmtp start&lt;br /&gt;
* Verify clamsmtp is listening on port 10025:&lt;br /&gt;
 netstat -anp | grep clamsmtp&lt;br /&gt;
* [http://memberwebs.com/stef/software/clamsmtp/postfix.html Following the clamsmtp instructions]&lt;br /&gt;
** edit /etc/postfix/main.cf and add:&lt;br /&gt;
 content_filter = scan:[127.0.0.1]:10025                                                      &lt;br /&gt;
** edit /etc/postfix/master.cf and add&lt;br /&gt;
 # AV scan filter (used by content_filter)&lt;br /&gt;
 scan      unix  -       -       n       -       16      smtp&lt;br /&gt;
         -o smtp_send_xforward_command=yes&lt;br /&gt;
         -o smtp_enforce_tls=no&lt;br /&gt;
 # For injecting mail back into postfix from the filter&lt;br /&gt;
 127.0.0.1:10026 inet  n -       n       -       16      smtpd&lt;br /&gt;
         -o content_filter=&lt;br /&gt;
         -o receive_override_options=no_unknown_recipient_checks,no_header_body_checks&lt;br /&gt;
         -o smtpd_helo_restrictions=&lt;br /&gt;
         -o smtpd_client_restrictions=&lt;br /&gt;
         -o smtpd_sender_restrictions=&lt;br /&gt;
         -o smtpd_recipient_restrictions=permit_mynetworks,reject&lt;br /&gt;
         -o mynetworks_style=host&lt;br /&gt;
         -o smtpd_authorized_xforward_hosts=127.0.0.0/8&lt;br /&gt;
* postfix reload&lt;br /&gt;
* Send and email into a local virtual domain - it should have the &#039;&#039;X-Virus-Scanned: ClamAV using ClamSMTP&#039;&#039; header.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Relay for Authenticated Users ===&lt;br /&gt;
&lt;br /&gt;
As configured above, the mail server accepts email from the Internet, but it does not relay email.  If it is a perimeter exchanger for a protected network, then you can add the protected networks to the &#039;&#039;mynetworks&#039;&#039; configuration line in /etc/postfix/main.cf&lt;br /&gt;
&lt;br /&gt;
This configuration change allows &#039;&#039;remote&#039;&#039; users to authenticate against the mail server and relay through it.  The rules for relaying are:&lt;br /&gt;
* Only authenticated users can relay&lt;br /&gt;
* Authentication Credentials must be encrypted with TLS or SSL&lt;br /&gt;
* Allow Submission and SMTPS ports for relaying (many consumer networks block port 25 - SMTP by default)&lt;br /&gt;
The process uses the dovecot authentication mechanism (used with IMAPS) to authenticate users before they are allowed to relay through postfix.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* Edit /etc/dovecot/dovecot.conf and add:&lt;br /&gt;
 # this is for postfix SASL (authenticated users can relay through us)&lt;br /&gt;
 socket listen {&lt;br /&gt;
                client {&lt;br /&gt;
                        path    = /var/spool/postfix/private/dovecot-auth.sock&lt;br /&gt;
                        mode    = 0660&lt;br /&gt;
                        user    = postfix&lt;br /&gt;
                        group   = postfix&lt;br /&gt;
                        }&lt;br /&gt;
                }&lt;br /&gt;
        }&lt;br /&gt;
* Restart dovecot&lt;br /&gt;
 /etc/init.d/dovecot restart&lt;br /&gt;
* Edit /etc/postfix/main.cf and add:&lt;br /&gt;
 # TLS Stuff -- since we allow SASL with tls *only*, we have to set up TLS first                    &lt;br /&gt;
 &lt;br /&gt;
 smtpd_tls_cert_file = /etc/lighttpd/server-bundle.pem&lt;br /&gt;
 smtpd_tls_key_file = /etc/lighttpd/server-bundle.pem&lt;br /&gt;
 smtpd_tls_CAfile = /etc/lighttpd/ca-crt.pem&lt;br /&gt;
 # If tls_security_level is set to &amp;quot;encrypt&amp;quot;, then SMTP rejects &lt;br /&gt;
 # unencrypted email (e.g. normal mail) which is bad.&lt;br /&gt;
 # By setting it to &amp;quot;may&amp;quot; you get TLS encrypted mail from google, slashdot, and other &lt;br /&gt;
 # interesting places.  Check your logs to see who&lt;br /&gt;
 smtpd_tls_security_level = may&lt;br /&gt;
 # Log info about the negotiated encryption levels&lt;br /&gt;
 smtpd_tls_received_header = yes&lt;br /&gt;
 smtpd_tls_loglevel = 1&lt;br /&gt;
 &lt;br /&gt;
 # SASL - this allows senders to authenticiate themselves&lt;br /&gt;
 # This along with &amp;quot;permit_sasl_authenticated&amp;quot; in smtpd_recipient_restrictions allows relaying&lt;br /&gt;
 smtpd_sasl_type = dovecot&lt;br /&gt;
 smtpd_sasl_path = private/dovecot-auth.sock&lt;br /&gt;
 smtpd_sasl_auth_enable = yes&lt;br /&gt;
 smtpd_sasl_authenticated_header = yes&lt;br /&gt;
 smtpd_tls_auth_only = yes&lt;br /&gt;
* Edit /etc/postfix/master.cf and enable the submission and smtps transports.  They are probably already at the top of your  master.cf file, just commented out:&lt;br /&gt;
 submission inet n       -       n       -       -       smtpd&lt;br /&gt;
   -o smtpd_tls_security_level=encrypt&lt;br /&gt;
   -o smtpd_sasl_auth_enable=yes&lt;br /&gt;
   -o smtpd_client_restrictions=permit_sasl_authenticated,reject&lt;br /&gt;
   -o milter_macro_daemon_name=ORIGINATING&lt;br /&gt;
 smtps     inet  n       -       n       -       -       smtpd&lt;br /&gt;
   -o smtpd_tls_security_level=encrypt&lt;br /&gt;
   -o smtpd_tls_wrappermode=yes&lt;br /&gt;
   -o smtpd_sasl_auth_enable=yes&lt;br /&gt;
   -o smtpd_client_restrictions=permit_sasl_authenticated,reject&lt;br /&gt;
   -o milter_macro_daemon_name=ORIGINATING&lt;br /&gt;
*Verfiy submission and smtps are defined in /etc/services&lt;br /&gt;
 grep &amp;quot;submission\|ssmtp&amp;quot; /etc/services&lt;br /&gt;
 submission	587/tcp				# mail message submission&lt;br /&gt;
 submission	587/udp&lt;br /&gt;
 smtps		465/tcp		ssmtp		# smtp protocol over TLS/SSL&lt;br /&gt;
 smtps		465/udp		ssmtp&lt;br /&gt;
* Restart postfix&lt;br /&gt;
 postfix reload&lt;br /&gt;
&lt;br /&gt;
At this point, you should be able to set up a mail client to relay through the server with TLS (port 587) or SSL (port 465)  Note that &amp;quot;plain&amp;quot; authentication is used because the underlying link is encrypted.  For example, in Thunderbird leave &amp;quot;secure authentication&amp;quot; unchecked, and choose STARTTLS (or TLS) for the connection security.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Mailbox Quotas ===&lt;br /&gt;
&lt;br /&gt;
In the default configuration, PostfixAdmin knows about quotas, but they are not enforced.   Documentation on the web mentions the [http://vda.sourceforge.net vda patch to postifx] to enforce quotas.  The only bad thing... its a &#039;&#039;patch&#039;&#039;.   Postfix and Dovecot are both conservative systems, so if the patch isn&#039;t in the upstream source, we&#039;ll assume there&#039;s a good reason.   There is a way of using quotas without patches - and it involves using the dovecot&#039;s [http://wiki.dovecot.org/LDA deliver] lda for local delivery.&lt;br /&gt;
&lt;br /&gt;
Note: As of Jan 2010, the documention is confusing, with multiple versions of dovecot, PostfixAdmin, and Mysql referenced.  These instructions apply to:&lt;br /&gt;
* Postgresql 8.4.2 &lt;br /&gt;
* PostfixAdmin 2.3 &lt;br /&gt;
* Dovecot 1.2.10&lt;br /&gt;
* Postfix 2.6.5&lt;br /&gt;
&lt;br /&gt;
Presumably later versions will work the same, but if not, please update the documentation and versions above.&lt;br /&gt;
&lt;br /&gt;
* Update /etc/dovecot.conf (old lines shown commented out):&lt;br /&gt;
 # old postfix &lt;br /&gt;
 #       userdb static {&lt;br /&gt;
 #               args =  uid=1006 gid=1006 home=/var/mail/domains/%d/%n&lt;br /&gt;
 #               }&lt;br /&gt;
 &lt;br /&gt;
 # new quota support:&lt;br /&gt;
        userdb prefetch {&lt;br /&gt;
                }&lt;br /&gt;
&lt;br /&gt;
        userdb sql {&lt;br /&gt;
                args = /etc/dovecot/dovecot-sql.conf&lt;br /&gt;
                }&lt;br /&gt;
&lt;br /&gt;
        socket listen {&lt;br /&gt;
                client {&lt;br /&gt;
                        path    = /var/spool/postfix/private/dovecot-auth.sock&lt;br /&gt;
                        mode    = 0660&lt;br /&gt;
                        user    = postfix&lt;br /&gt;
                        group   = postfix&lt;br /&gt;
                        }&lt;br /&gt;
                # These lines below are for the deliver lda&lt;br /&gt;
                master {&lt;br /&gt;
                        path =  /var/run/dovecot/auth-master&lt;br /&gt;
                        mode    = 0660&lt;br /&gt;
                        user    = vmail&lt;br /&gt;
                        group   = vmail&lt;br /&gt;
                        }&lt;br /&gt;
                }&lt;br /&gt;
 &lt;br /&gt;
 protocol imap {                                                               &lt;br /&gt;
         mail_plugins = quota imap_quota                                       &lt;br /&gt;
         }                                                                     &lt;br /&gt;
                                                                              &lt;br /&gt;
 protocol pop3 {                                                               &lt;br /&gt;
         mail_plugins = quota                                                  &lt;br /&gt;
         }                                                                     &lt;br /&gt;
                                                                              &lt;br /&gt;
 dict {                                                                        &lt;br /&gt;
        quotadict = pgsql:/etc/dovecot/dovecot-dict-quota.conf                &lt;br /&gt;
        }                                                                     &lt;br /&gt;
                                                                              &lt;br /&gt;
 plugin {                                                                      &lt;br /&gt;
         quota = dict:user::proxy::quotadict                                   &lt;br /&gt;
         }                                                     &lt;br /&gt;
                                                              &lt;br /&gt;
 protocol lda {                                                &lt;br /&gt;
   postmaster_address = postmaster@host.example.com&lt;br /&gt;
   mail_plugins = quota                                        &lt;br /&gt;
   auth_socket_path =  /var/run/dovecot/auth-master&lt;br /&gt;
   sendmail_path = /usr/sbin/sendmail&lt;br /&gt;
 }                                                                            &lt;br /&gt;
    &lt;br /&gt;
You should already have a &amp;lt;tt&amp;gt;socket-&amp;gt; listen-&amp;gt; client&amp;lt;/tt&amp;gt; section, but it is listed above to show where it goes in relationship to the &amp;lt;tt&amp;gt;socket -&amp;gt; listen -&amp;gt; master&amp;lt;/tt&amp;gt; section&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* edit &amp;lt;tt&amp;gt;/etc/dovecot/dovecot-sql.conf&amp;lt;/tt&amp;gt; and replace the user and password queries with the following (you may not have a user_query yet - add it):&lt;br /&gt;
&lt;br /&gt;
 password_query = select username as user, password, 1006 as userdb_uid, 1006 as userdb_gid, &#039;*:bytes=&#039; || quota as userdb_quota_rule from mailbox  where local_part = &#039;%n&#039; and domain = &#039;%d&#039;&lt;br /&gt;
 user_query = select maildir as home, 1006 as uid, 1006 as gid, &#039;*:bytes=&#039; || quota  as quota_rule from mailbox where local_part = &#039;%n&#039; and domain =&#039;%d&#039;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* create &amp;lt;tt&amp;gt;/etc/dovecot/dovecot-dict-quota.conf&amp;lt;/tt&amp;gt;&lt;br /&gt;
 connect = host=localhost dbname=postfix user=postfix password=********&lt;br /&gt;
 &lt;br /&gt;
 map {&lt;br /&gt;
         pattern = priv/quota/storage&lt;br /&gt;
         table = quota2&lt;br /&gt;
         username_field =username&lt;br /&gt;
         value_field = bytes&lt;br /&gt;
 }&lt;br /&gt;
 &lt;br /&gt;
 map {&lt;br /&gt;
        pattern= priv/quota/messages&lt;br /&gt;
        table = quota2&lt;br /&gt;
        username_field = username&lt;br /&gt;
        value_field = messages&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
Side note: [http://wiki.dovecot.org/Quota/Dict The Dovecot Quota Documentation] mentions the need for a trigger with pgsql.  This was created in the PostfixAdmin install, which is why you instantiated the pgsql language when creating the database.  If not, you will need to create the trigger, to reference the quota2 table, not the quota table mentioned in the dovecot docs.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* create a new transport for the dovecot lda.   Add the following to  /etc/postfix/master.cf:&lt;br /&gt;
 # The dovecot deliver lda&lt;br /&gt;
 dovecot   unix  -       n       n       -       -       pipe&lt;br /&gt;
   flags=DRhu user=vmail:vmail argv=/usr/libexec/dovecot/deliver -f ${sender} -d ${user}@${nexthop}&lt;br /&gt;
&lt;br /&gt;
* Edit the /etc/postfix/main.cf.  Replace &lt;br /&gt;
 virtual_transport = virtual &lt;br /&gt;
with&lt;br /&gt;
 virtual_transport = dovecot&lt;br /&gt;
 dovecot_destination_recipient_limit = 1&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;TODO&#039;&#039;&#039;  This will cause over-quota emails to bounce.   Which could be a source of backscatter.   We need a way of checking quota limits after RBL checking but before the message is accepted in the queue.&lt;br /&gt;
&lt;br /&gt;
=== WebMail (RoundCube) ===&lt;br /&gt;
&lt;br /&gt;
[http://roundcube.net/ RoundCube] is an &amp;quot;ajax /Web2.0&amp;quot; web-mail client.  These instructions are for the Alpine Linux 1.10 repository &lt;br /&gt;
&lt;br /&gt;
* Add the package and related php modules:&lt;br /&gt;
 apk add roundcubemail php-xml php-openssl php-mcrypt php-gd php-iconv&lt;br /&gt;
&lt;br /&gt;
* link the roundcube application back into the docroot&lt;br /&gt;
 ln -s /usr/share/webapps/roundcube /var/www/domains/host.example.com/www/roundcube&lt;br /&gt;
&lt;br /&gt;
* follow the instructions in /usr/share/webapps/roundcube/INSTALL:&lt;br /&gt;
 chown -R lighttpd:lighttpd temp logs&lt;br /&gt;
 &lt;br /&gt;
 su postgres&lt;br /&gt;
 createuser roundcube&lt;br /&gt;
   Shall the new role be a superuser? (y/n) n&lt;br /&gt;
   Shall the new role be allowed to create databases? (y/n) n&lt;br /&gt;
   Shall the new role be allowed to create more new roles? (y/n) y&lt;br /&gt;
 createdb -O roundcube -E UNICODE -T template0 roundcubemail&lt;br /&gt;
 psql roundcubemail&lt;br /&gt;
   roundcubemail=# ALTER USER roundcube WITH PASSWORD &#039;the_new_password&#039;;&lt;br /&gt;
   roundcubemail=# \c - roundcube&lt;br /&gt;
   \i /usr/share/webapps/roundcube/SQL/postgres.initial.sql&lt;br /&gt;
   \q&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* restart lighttpd to verify the new php libraries are used&lt;br /&gt;
 /etc/init.d/lighttpd restart&lt;br /&gt;
&lt;br /&gt;
* Point your browser to http://host.example.com/roundcube/installer&lt;br /&gt;
** Begin installation&lt;br /&gt;
** Follow the instructions in step 3 of the install to copy the files to the server&lt;br /&gt;
* edit /etc/php/php.ini and edit date.timezone to your local timezone, or to UTC&lt;br /&gt;
* if necessary (e.g. you had to reset the local timezone) restart lighttpd to reload php&lt;br /&gt;
 /etc/init.d/lighttpd restart&lt;br /&gt;
* You should now be able to get to roundcube at http://host.example.com/roundcube&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
For the specific configuration parameters in the install step:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!Property&lt;br /&gt;
!Setting&lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;enable_spellcheck&#039;&#039; ||   disabled &lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;identities_level&#039;&#039; ||  one identity with possibility to edit all params but not email address &lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;log driver&#039;&#039; || syslog &lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;sylog_id&#039;&#039; || roundcube &lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;syslog_facility&#039;&#039; || mailsubsystem &lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;db_dnsw&#039;&#039; || pgsql properties, as described above &lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;imap_host&#039;&#039; || 127.0.0.1 &lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;auto_create_user&#039;&#039; || enabled &lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;smtp_server&#039;&#039; ||  127.0.0.1&lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;smtp_port&#039;&#039; ||  25&lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;smtp_user/smtp_pass&#039;&#039; ||  enable &#039;&#039;Use Current IMAP username and password for SMTP authentication&#039;&#039;&lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;smtp_log&#039;&#039; ||  enable (optional, but gives additional log record)&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
The other items can be left at default settings, or adjusted if desired.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
After its working, the INSTALL file recommends removing the install directory.   If you want to keep the installer around later, you can simply change the ownership and permissions.  So do &#039;&#039;&#039;one&#039;&#039;&#039; of the following:&lt;br /&gt;
 cd /usr/share/webapps/roundcube&lt;br /&gt;
 rm -rf LICENSE UPGRADING INSTALL README CHANGELOG  SQL installer&lt;br /&gt;
or&lt;br /&gt;
 cd /usr/share/webapps/roundcube&lt;br /&gt;
 chown -R root:root LICENSE UPGRADING INSTALL README CHANGELOG  SQL installer&lt;br /&gt;
 chmod -R 600 LICENSE UPGRADING INSTALL README CHANGELOG SQL &lt;br /&gt;
 chmod 700 SQL installer&lt;br /&gt;
&lt;br /&gt;
== log rotation ==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
Special thanks to DHughes for providing a 3 page email on how to set up postgres,postfix,PostfixAdmin,dovecot and roundcube.  It was the clearer than all the other guides available on the Net. Thanks!&lt;/div&gt;</summary>
		<author><name>Djhughes</name></author>
	</entry>
</feed>