<?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=Nangel</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=Nangel"/>
	<link rel="alternate" type="text/html" href="https://wiki.alpinelinux.org/wiki/Special:Contributions/Nangel"/>
	<updated>2026-05-02T18:32:10Z</updated>
	<subtitle>User contributions</subtitle>
	<generator>MediaWiki 1.40.0</generator>
	<entry>
		<id>https://wiki.alpinelinux.org/w/index.php?title=Talk:Cron&amp;diff=30909</id>
		<title>Talk:Cron</title>
		<link rel="alternate" type="text/html" href="https://wiki.alpinelinux.org/w/index.php?title=Talk:Cron&amp;diff=30909"/>
		<updated>2025-09-15T16:45:13Z</updated>

		<summary type="html">&lt;p&gt;Nangel: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Hello. My name is Grey, I am a beginner with Alpine Linux. I would like to know how I can change mac address on my PC running alpine linux 3.22 std. In Debian, I open the terminal and type &amp;quot;sudo crontab -e&amp;quot;, I go to the bottom of the script and I add &amp;quot;@reboot macchanger -r wlan0&amp;quot;, I save it, and when I reboot my PC, it changes mac address automatically. How can I do it in Alpine? Thank you very much for your kind help. Grey&lt;br /&gt;
:Hi [[User:Grey|Grey]], You can use the following command {{ic|$ apk search Cmd:macchanger}} to find the package that contains the command of interest i.e  {{ic|macchanger-1.7.0-r3}} . The output shows that the package name is {{pkg|macchanger}} and it can be installed using {{ic|# apk add macchanger}}. Please refer to [[apk]] page for more info. In future, please consider using other [[Support]] channels like [[IRC]] etc... -  [[User:Prabuanand|Prabuanand]] ([[User talk:Prabuanand|talk]]) 13:43, 15 September 2025 (UTC)&lt;br /&gt;
&lt;br /&gt;
:Hi [[User:Grey|Grey]], if you don&#039;t want to add an extra apk to your system, and you are using ifupdown-ng (should be default these days), add the following pre-up command to your stanza for your wlan0 interface.  For example:&lt;br /&gt;
&lt;br /&gt;
  auto wlan0&lt;br /&gt;
  iface wlan0 inet dhcp&lt;br /&gt;
        .&lt;br /&gt;
        .&lt;br /&gt;
        .&lt;br /&gt;
        # **** To get our special mac addr *****&lt;br /&gt;
        pre-up ip link set $IFACE addr de:ad:be:ef:ca:fe&lt;br /&gt;
        .&lt;br /&gt;
        .&lt;br /&gt;
        .&lt;br /&gt;
        &lt;br /&gt;
&lt;br /&gt;
Just another alternative.&lt;/div&gt;</summary>
		<author><name>Nangel</name></author>
	</entry>
	<entry>
		<id>https://wiki.alpinelinux.org/w/index.php?title=Talk:Alpine_configuration_management_scripts&amp;diff=27095</id>
		<title>Talk:Alpine configuration management scripts</title>
		<link rel="alternate" type="text/html" href="https://wiki.alpinelinux.org/w/index.php?title=Talk:Alpine_configuration_management_scripts&amp;diff=27095"/>
		<updated>2024-08-19T11:10:03Z</updated>

		<summary type="html">&lt;p&gt;Nangel: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Automate Alpine Linux installation ==&lt;br /&gt;
&lt;br /&gt;
I am trying to achieve unattended Alpine Linux installation. I went through the Alpine automatic installation guide via setup-alpine script, but when I follow this guide there are many manual interventions are needed during the installation!&lt;br /&gt;
one during writing the root user name, another time when creating the answer file (setup-alpine -c answerfileName), editing the answer file, calling the actual installation command (setup-alpine -f answerfileName) and reset the root password. Is there any way to include the answer file inside the ISO image and select the root user by default before starting the installation and set its password as well after the installation is done (something similar to the kickstart file in the debian distros) ?&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;!-- Template:Unsigned --&amp;gt;&amp;lt;span class=&amp;quot;autosigned&amp;quot; style=&amp;quot;font-size:85%;&amp;quot;&amp;gt;—&amp;amp;nbsp;Preceding unsigned comments added by [[User:Khaled.elgohary|Khaled.elgohary ]] ([[User talk:Khaled.elgohary #top|talk]] • [[Special:Contributions/Khaled.elgohary |contribs]]) 12:20, 7 February 2022‎&amp;lt;/span&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The [[https://wiki.alpinelinux.org/wiki/Alpine_setup_scripts#setup-alpine| setup-alpine]] section currently gives instructions that may appear to be contradictory: &lt;br /&gt;
&lt;br /&gt;
&amp;quot;17. if installation mode selected during setup-disk was &amp;quot;data&amp;quot; instead of &amp;quot;sys&amp;quot;, then: setup-lbu [/media/sdb1]&lt;br /&gt;
&lt;br /&gt;
18. if installation mode selected during setup-disk was &amp;quot;data&amp;quot; instead of &amp;quot;sys&amp;quot;, then: setup-apkcache [/media/sdb1/cache | none]&amp;quot;&lt;br /&gt;
&lt;br /&gt;
One of these presumably refers to the case for &amp;quot;sys&amp;quot;, but which?&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
---&lt;br /&gt;
&lt;br /&gt;
Both are correct and refer to the same situation.   If you set up a disk for &amp;quot;data&amp;quot;, then the installation is &amp;quot;run-from-RAM&amp;quot;, but with a disk for &amp;quot;data&amp;quot;.  In that case, you want to use lbu to keep the in-RAM configs on the boot media.   You also want apkcache to be able to update the apks on the boot media.   - nangel&lt;/div&gt;</summary>
		<author><name>Nangel</name></author>
	</entry>
	<entry>
		<id>https://wiki.alpinelinux.org/w/index.php?title=Talk:Using_Unbound_as_an_Ad-blocker&amp;diff=26400</id>
		<title>Talk:Using Unbound as an Ad-blocker</title>
		<link rel="alternate" type="text/html" href="https://wiki.alpinelinux.org/w/index.php?title=Talk:Using_Unbound_as_an_Ad-blocker&amp;diff=26400"/>
		<updated>2024-02-16T03:47:27Z</updated>

		<summary type="html">&lt;p&gt;Nangel: Done.&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==Mention of modern browsers&#039; attempts to bypass DNS blocking of ad servers==&lt;br /&gt;
The article could also use an entire section explaining how modern browsers, especially Chrome, attempt to use DNS over HTTPS to bypass the system configured DNS server under the guise of privacy (but lets face it, Google has financial incentive to prevent people from blocking ad.doubleclick.com)... An unbound configuration that prevents bootstrapping of popular DoH servers could help. Something like:&lt;br /&gt;
&amp;lt;div class=&amp;quot;toccolours mw-collapsible mw-collapsed&amp;quot;&amp;gt;&amp;lt;div class=&amp;quot;mw-collapsible-content&amp;quot;&amp;gt;&amp;lt;pre&amp;gt;&lt;br /&gt;
server:&lt;br /&gt;
#These three domains require special handling&lt;br /&gt;
local-zone: &amp;quot;resolver.arpa&amp;quot; redirect&lt;br /&gt;
local-zone: &amp;quot;doh.dns.apple.com&amp;quot; redirect&lt;br /&gt;
local-zone: &amp;quot;use-application-dns.net&amp;quot; always_nxdomain&lt;br /&gt;
local-zone: &amp;quot;cloudflare-dns.com&amp;quot; static&lt;br /&gt;
local-zone: &amp;quot;dns-tunnel-check.googlezip.net&amp;quot; always_refuse&lt;br /&gt;
#All other domains, lie and provide our own IP&lt;br /&gt;
local-data: &amp;quot;doh.dns.apple.com.v.aaplimg.com. 120 IN A 192.168.0.1&amp;quot;&lt;br /&gt;
local-data: &amp;quot;doh.42l.fr. 120 IN A 192.168.0.1&amp;quot;&lt;br /&gt;
local-data: &amp;quot;i.233py.com. 120 IN A 192.168.0.1&amp;quot;&lt;br /&gt;
local-data: &amp;quot;i.233py.com.a.bdydns.com. 120 IN A 192.168.0.1&amp;quot;&lt;br /&gt;
local-data: &amp;quot;opencdn.jomodns.com. 120 IN A 192.168.0.1&amp;quot;&lt;br /&gt;
local-data: &amp;quot;dns.233py.com. 120 IN A 192.168.0.1&amp;quot;&lt;br /&gt;
local-data: &amp;quot;dns.233py.com.cdn.cloudflare.net. 120 IN A 192.168.0.1&amp;quot;&lt;br /&gt;
local-data: &amp;quot;edns.233py.com. 120 IN A 192.168.0.1&amp;quot;&lt;br /&gt;
local-data: &amp;quot;ndns.233py.com. 120 IN A 192.168.0.1&amp;quot;&lt;br /&gt;
local-data: &amp;quot;sdns.233py.com. 120 IN A 192.168.0.1&amp;quot;&lt;br /&gt;
local-data: &amp;quot;wdns.233py.com. 120 IN A 192.168.0.1&amp;quot;&lt;br /&gt;
local-data: &amp;quot;dns-gcp.aaflalo.me. 120 IN A 192.168.0.1&amp;quot;&lt;br /&gt;
local-data: &amp;quot;dns-nyc.aaflalo.me. 120 IN A 192.168.0.1&amp;quot;&lt;br /&gt;
local-data: &amp;quot;dns.aaflalo.me. 120 IN A 192.168.0.1&amp;quot;&lt;br /&gt;
local-data: &amp;quot;doh.abmb.win. 120 IN A 192.168.0.1&amp;quot;&lt;br /&gt;
local-data: &amp;quot;doh2.abmb.win. 120 IN A 192.168.0.1&amp;quot;&lt;br /&gt;
local-data: &amp;quot;dns.adguard.com. 120 IN A 192.168.0.1&amp;quot;&lt;br /&gt;
local-data: &amp;quot;dns-family.adguard.com. 120 IN A 192.168.0.1&amp;quot;&lt;br /&gt;
local-data: &amp;quot;dns-unfiltered.adguard.com. 120 IN A 192.168.0.1&amp;quot;&lt;br /&gt;
local-data: &amp;quot;dns.adguard-dns.com. 120 IN A 192.168.0.1&amp;quot;&lt;br /&gt;
local-data: &amp;quot;family.adguard-dns.com. 120 IN A 192.168.0.1&amp;quot;&lt;br /&gt;
local-data: &amp;quot;unfiltered.adguard-dns.com. 120 IN A 192.168.0.1&amp;quot;&lt;br /&gt;
local-data: &amp;quot;doh.nl.ahadns.net. 120 IN A 192.168.0.1&amp;quot;&lt;br /&gt;
local-data: &amp;quot;doh.in.ahadns.net. 120 IN A 192.168.0.1&amp;quot;&lt;br /&gt;
local-data: &amp;quot;doh.la.ahadns.net. 120 IN A 192.168.0.1&amp;quot;&lt;br /&gt;
local-data: &amp;quot;doh.ny.ahadns.net. 120 IN A 192.168.0.1&amp;quot;&lt;br /&gt;
local-data: &amp;quot;doh.pl.ahadns.net. 120 IN A 192.168.0.1&amp;quot;&lt;br /&gt;
local-data: &amp;quot;doh.it.ahadns.net. 120 IN A 192.168.0.1&amp;quot;&lt;br /&gt;
local-data: &amp;quot;doh.es.ahadns.net. 120 IN A 192.168.0.1&amp;quot;&lt;br /&gt;
local-data: &amp;quot;doh.no.ahadns.net. 120 IN A 192.168.0.1&amp;quot;&lt;br /&gt;
local-data: &amp;quot;doh.chi.ahadns.net. 120 IN A 192.168.0.1&amp;quot;&lt;br /&gt;
local-data: &amp;quot;doh.au.ahadns.net. 120 IN A 192.168.0.1&amp;quot;&lt;br /&gt;
local-data: &amp;quot;dot.nl.ahadns.net. 120 IN A 192.168.0.1&amp;quot;&lt;br /&gt;
local-data: &amp;quot;dot.in.ahadns.net. 120 IN A 192.168.0.1&amp;quot;&lt;br /&gt;
local-data: &amp;quot;dot.la.ahadns.net. 120 IN A 192.168.0.1&amp;quot;&lt;br /&gt;
local-data: &amp;quot;dot.ny.ahadns.net. 120 IN A 192.168.0.1&amp;quot;&lt;br /&gt;
local-data: &amp;quot;dot.pl.ahadns.net. 120 IN A 192.168.0.1&amp;quot;&lt;br /&gt;
local-data: &amp;quot;dot.it.ahadns.net. 120 IN A 192.168.0.1&amp;quot;&lt;br /&gt;
local-data: &amp;quot;dot.es.ahadns.net. 120 IN A 192.168.0.1&amp;quot;&lt;br /&gt;
local-data: &amp;quot;dot.no.ahadns.net. 120 IN A 192.168.0.1&amp;quot;&lt;br /&gt;
local-data: &amp;quot;dot.chi.ahadns.net. 120 IN A 192.168.0.1&amp;quot;&lt;br /&gt;
local-data: &amp;quot;dot.au.ahadns.net. 120 IN A 192.168.0.1&amp;quot;&lt;br /&gt;
local-data: &amp;quot;dnses.alekberg.net. 120 IN A 192.168.0.1&amp;quot;&lt;br /&gt;
local-data: &amp;quot;dnsnl.alekberg.net. 120 IN A 192.168.0.1&amp;quot;&lt;br /&gt;
local-data: &amp;quot;dnsse.alekberg.net. 120 IN A 192.168.0.1&amp;quot;&lt;br /&gt;
local-data: &amp;quot;dns.alidns.com. 120 IN A 192.168.0.1&amp;quot;&lt;br /&gt;
local-data: &amp;quot;doh.appliedprivacy.net. 120 IN A 192.168.0.1&amp;quot;&lt;br /&gt;
local-data: &amp;quot;doh.applied-privacy.net. 120 IN A 192.168.0.1&amp;quot;&lt;br /&gt;
local-data: &amp;quot;dot1.applied-privacy.net. 120 IN A 192.168.0.1&amp;quot;&lt;br /&gt;
local-data: &amp;quot;doh.armadillodns.net. 120 IN A 192.168.0.1&amp;quot;&lt;br /&gt;
local-data: &amp;quot;dohtrial.att.net. 120 IN A 192.168.0.1&amp;quot;&lt;br /&gt;
local-data: &amp;quot;doh1.blahdns.com. 120 IN A 192.168.0.1&amp;quot;&lt;br /&gt;
local-data: &amp;quot;doh1.b-cdn.net. 120 IN A 192.168.0.1&amp;quot;&lt;br /&gt;
local-data: &amp;quot;doh2.blahdns.com. 120 IN A 192.168.0.1&amp;quot;&lt;br /&gt;
local-data: &amp;quot;doh2.b-cdn.net. 120 IN A 192.168.0.1&amp;quot;&lt;br /&gt;
local-data: &amp;quot;dot-ch.blahdns.com. 120 IN A 192.168.0.1&amp;quot;&lt;br /&gt;
local-data: &amp;quot;doh-ch.blahdns.com. 120 IN A 192.168.0.1&amp;quot;&lt;br /&gt;
local-data: &amp;quot;dot-fi.blahdns.com. 120 IN A 192.168.0.1&amp;quot;&lt;br /&gt;
local-data: &amp;quot;doh-fi.blahdns.com. 120 IN A 192.168.0.1&amp;quot;&lt;br /&gt;
local-data: &amp;quot;dot-de.blahdns.com. 120 IN A 192.168.0.1&amp;quot;&lt;br /&gt;
local-data: &amp;quot;doh-de.blahdns.com. 120 IN A 192.168.0.1&amp;quot;&lt;br /&gt;
local-data: &amp;quot;dot-jp.blahdns.com. 120 IN A 192.168.0.1&amp;quot;&lt;br /&gt;
local-data: &amp;quot;doh-jp.blahdns.com. 120 IN A 192.168.0.1&amp;quot;&lt;br /&gt;
local-data: &amp;quot;dot-sg.blahdns.com. 120 IN A 192.168.0.1&amp;quot;&lt;br /&gt;
local-data: &amp;quot;doh-sg.blahdns.com. 120 IN A 192.168.0.1&amp;quot;&lt;br /&gt;
local-data: &amp;quot;doh.blockerdns.com. 120 IN A 192.168.0.1&amp;quot;&lt;br /&gt;
local-data: &amp;quot;doh.bortzmeyer.fr. 120 IN A 192.168.0.1&amp;quot;&lt;br /&gt;
local-data: &amp;quot;dns.brahma.world. 120 IN A 192.168.0.1&amp;quot;&lt;br /&gt;
local-data: &amp;quot;bravedns.com. 120 IN A 192.168.0.1&amp;quot;&lt;br /&gt;
local-data: &amp;quot;doh.captnemo.in. 120 IN A 192.168.0.1&amp;quot;&lt;br /&gt;
local-data: &amp;quot;ibuki.cgnat.net. 120 IN A 192.168.0.1&amp;quot;&lt;br /&gt;
local-data: &amp;quot;canadianshield.cira.ca. 120 IN A 192.168.0.1&amp;quot;&lt;br /&gt;
local-data: &amp;quot;dns.cloudflare.com. 120 IN A 192.168.0.1&amp;quot;&lt;br /&gt;
local-data: &amp;quot;one.one.one.one. 120 IN A 192.168.0.1&amp;quot;&lt;br /&gt;
local-data: &amp;quot;cloudflare-gateway.com. 120 IN A 192.168.0.1&amp;quot;&lt;br /&gt;
local-data: &amp;quot;doh.cleanbrowsing.org. 120 IN A 192.168.0.1&amp;quot;&lt;br /&gt;
local-data: &amp;quot;security-filter-dns.cleanbrowsing.org. 120 IN A 192.168.0.1&amp;quot;&lt;br /&gt;
local-data: &amp;quot;adult-filter-dns.cleanbrowsing.org. 120 IN A 192.168.0.1&amp;quot;&lt;br /&gt;
local-data: &amp;quot;family-filter-dns.cleanbrowsing.org. 120 IN A 192.168.0.1&amp;quot;&lt;br /&gt;
local-data: &amp;quot;dns.cmrg.net. 120 IN A 192.168.0.1&amp;quot;&lt;br /&gt;
local-data: &amp;quot;commons.host. 120 IN A 192.168.0.1&amp;quot;&lt;br /&gt;
local-data: &amp;quot;dns.containerpi.com. 120 IN A 192.168.0.1&amp;quot;&lt;br /&gt;
local-data: &amp;quot;dohdot.coxlab.net. 120 IN A 192.168.0.1&amp;quot;&lt;br /&gt;
local-data: &amp;quot;doh.crypto.sx. 120 IN A 192.168.0.1&amp;quot;&lt;br /&gt;
local-data: &amp;quot;jit.ddns.net. 120 IN A 192.168.0.1&amp;quot;&lt;br /&gt;
local-data: &amp;quot;dns.decloudus.com. 120 IN A 192.168.0.1&amp;quot;&lt;br /&gt;
local-data: &amp;quot;doh.defaultroutes.de. 120 IN A 192.168.0.1&amp;quot;&lt;br /&gt;
local-data: &amp;quot;dns.developer.li. 120 IN A 192.168.0.1&amp;quot;&lt;br /&gt;
local-data: &amp;quot;dns2.developer.li. 120 IN A 192.168.0.1&amp;quot;&lt;br /&gt;
local-data: &amp;quot;dns.digitale-gesellschaft.ch. 120 IN A 192.168.0.1&amp;quot;&lt;br /&gt;
local-data: &amp;quot;dns1.digitale-gesellschaft.ch. 120 IN A 192.168.0.1&amp;quot;&lt;br /&gt;
local-data: &amp;quot;dns2.digitale-gesellschaft.ch. 120 IN A 192.168.0.1&amp;quot;&lt;br /&gt;
local-data: &amp;quot;doh.disconnect.app. 120 IN A 192.168.0.1&amp;quot;&lt;br /&gt;
local-data: &amp;quot;ns1.recursive.dnsbycomodo.com. 120 IN A 192.168.0.1&amp;quot;&lt;br /&gt;
local-data: &amp;quot;ns2.recursive.dnsbycomodo.com. 120 IN A 192.168.0.1&amp;quot;&lt;br /&gt;
local-data: &amp;quot;dnsforge.de. 120 IN A 192.168.0.1&amp;quot;&lt;br /&gt;
local-data: &amp;quot;dns.google. 120 IN A 192.168.0.1&amp;quot;&lt;br /&gt;
local-data: &amp;quot;dns.dnshome.de. 120 IN A 192.168.0.1&amp;quot;&lt;br /&gt;
local-data: &amp;quot;dns1.dnscrypt.ca. 120 IN A 192.168.0.1&amp;quot;&lt;br /&gt;
local-data: &amp;quot;dns2.dnscrypt.ca. 120 IN A 192.168.0.1&amp;quot;&lt;br /&gt;
local-data: &amp;quot;doh.dnslify.com. 120 IN A 192.168.0.1&amp;quot;&lt;br /&gt;
local-data: &amp;quot;a.ns.dnslify.com. 120 IN A 192.168.0.1&amp;quot;&lt;br /&gt;
local-data: &amp;quot;b.ns.dnslify.com. 120 IN A 192.168.0.1&amp;quot;&lt;br /&gt;
local-data: &amp;quot;a.safe.ns.dnslify.com. 120 IN A 192.168.0.1&amp;quot;&lt;br /&gt;
local-data: &amp;quot;b.safe.ns.dnslify.com. 120 IN A 192.168.0.1&amp;quot;&lt;br /&gt;
local-data: &amp;quot;a.family.ns.dnslify.com. 120 IN A 192.168.0.1&amp;quot;&lt;br /&gt;
local-data: &amp;quot;b.family.ns.dnslify.com. 120 IN A 192.168.0.1&amp;quot;&lt;br /&gt;
local-data: &amp;quot;dns.dnsoverhttps.net. 120 IN A 192.168.0.1&amp;quot;&lt;br /&gt;
local-data: &amp;quot;dns.dns-over-https.com. 120 IN A 192.168.0.1&amp;quot;&lt;br /&gt;
local-data: &amp;quot;adblock-dot.dnswarden.com. 120 IN A 192.168.0.1&amp;quot;&lt;br /&gt;
local-data: &amp;quot;adult-filter-dot.dnswarden.com. 120 IN A 192.168.0.1&amp;quot;&lt;br /&gt;
local-data: &amp;quot;doh.dnswarden.com. 120 IN A 192.168.0.1&amp;quot;&lt;br /&gt;
local-data: &amp;quot;ecs-doh.dnswarden.com. 120 IN A 192.168.0.1&amp;quot;&lt;br /&gt;
local-data: &amp;quot;uncensored-dot.dnswarden.com. 120 IN A 192.168.0.1&amp;quot;&lt;br /&gt;
local-data: &amp;quot;doh.li. 120 IN A 192.168.0.1&amp;quot;&lt;br /&gt;
local-data: &amp;quot;doh.ffmuc.net. 120 IN A 192.168.0.1&amp;quot;&lt;br /&gt;
local-data: &amp;quot;dot.ffmuc.net. 120 IN A 192.168.0.1&amp;quot;&lt;br /&gt;
local-data: &amp;quot;rdns.faelix.net. 120 IN A 192.168.0.1&amp;quot;&lt;br /&gt;
local-data: &amp;quot;pdns.faelix.net. 120 IN A 192.168.0.1&amp;quot;&lt;br /&gt;
local-data: &amp;quot;dns.flatuslifir.is. 120 IN A 192.168.0.1&amp;quot;&lt;br /&gt;
local-data: &amp;quot;dns.google.com. 120 IN A 192.168.0.1&amp;quot;&lt;br /&gt;
local-data: &amp;quot;google-public-dns-a.google.com. 120 IN A 192.168.0.1&amp;quot;&lt;br /&gt;
local-data: &amp;quot;google-public-dns-b.google.com. 120 IN A 192.168.0.1&amp;quot;&lt;br /&gt;
local-data: &amp;quot;query.hdns.io. 120 IN A 192.168.0.1&amp;quot;&lt;br /&gt;
local-data: &amp;quot;ordns.he.net. 120 IN A 192.168.0.1&amp;quot;&lt;br /&gt;
local-data: &amp;quot;dns.hostux.net. 120 IN A 192.168.0.1&amp;quot;&lt;br /&gt;
local-data: &amp;quot;opennic.i2pd.xyz. 120 IN A 192.168.0.1&amp;quot;&lt;br /&gt;
local-data: &amp;quot;public.dns.iij.jp. 120 IN A 192.168.0.1&amp;quot;&lt;br /&gt;
local-data: &amp;quot;jcdns.fun. 120 IN A 192.168.0.1&amp;quot;&lt;br /&gt;
local-data: &amp;quot;us1.dns.lavate.ch. 120 IN A 192.168.0.1&amp;quot;&lt;br /&gt;
local-data: &amp;quot;eu1.dns.lavate.ch. 120 IN A 192.168.0.1&amp;quot;&lt;br /&gt;
local-data: &amp;quot;resolver-eu.lelux.fi. 120 IN A 192.168.0.1&amp;quot;&lt;br /&gt;
local-data: &amp;quot;doh.libredns.org. 120 IN A 192.168.0.1&amp;quot;&lt;br /&gt;
local-data: &amp;quot;dot.libredns.gr.com. 120 IN A 192.168.0.1&amp;quot;&lt;br /&gt;
local-data: &amp;quot;dot.libredns.gr. 120 IN A 192.168.0.1&amp;quot;&lt;br /&gt;
local-data: &amp;quot;doh.libredns.gr. 120 IN A 192.168.0.1&amp;quot;&lt;br /&gt;
local-data: &amp;quot;jarjar.meganerd.nl. 120 IN A 192.168.0.1&amp;quot;&lt;br /&gt;
local-data: &amp;quot;dns.mrkaran.dev. 120 IN A 192.168.0.1&amp;quot;&lt;br /&gt;
local-data: &amp;quot;adblock.mydns.network. 120 IN A 192.168.0.1&amp;quot;&lt;br /&gt;
local-data: &amp;quot;dns.neutopia.org. 120 IN A 192.168.0.1&amp;quot;&lt;br /&gt;
local-data: &amp;quot;dns.aa.net.uk. 120 IN A 192.168.0.1&amp;quot;&lt;br /&gt;
local-data: &amp;quot;doh.netweaver.uk. 120 IN A 192.168.0.1&amp;quot;&lt;br /&gt;
local-data: &amp;quot;dns.nextdns.io. 120 IN A 192.168.0.1&amp;quot;&lt;br /&gt;
local-data: &amp;quot;dns1.nextdns.io. 120 IN A 192.168.0.1&amp;quot;&lt;br /&gt;
local-data: &amp;quot;dns2.nextdns.io. 120 IN A 192.168.0.1&amp;quot;&lt;br /&gt;
local-data: &amp;quot;odvr.nic.cz. 120 IN A 192.168.0.1&amp;quot;&lt;br /&gt;
local-data: &amp;quot;dns.nixnet.xyz. 120 IN A 192.168.0.1&amp;quot;&lt;br /&gt;
local-data: &amp;quot;lv1.nixnet.xyz. 120 IN A 192.168.0.1&amp;quot;&lt;br /&gt;
local-data: &amp;quot;ny1.nixnet.xyz. 120 IN A 192.168.0.1&amp;quot;&lt;br /&gt;
local-data: &amp;quot;lux1.nixnet.xyz. 120 IN A 192.168.0.1&amp;quot;&lt;br /&gt;
local-data: &amp;quot;dns.njal.la. 120 IN A 192.168.0.1&amp;quot;&lt;br /&gt;
local-data: &amp;quot;doh.opendns.com. 120 IN A 192.168.0.1&amp;quot;&lt;br /&gt;
local-data: &amp;quot;doh.familyshield.opendns.com. 120 IN A 192.168.0.1&amp;quot;&lt;br /&gt;
local-data: &amp;quot;doh.sandbox.opendns.com. 120 IN A 192.168.0.1&amp;quot;&lt;br /&gt;
local-data: &amp;quot;resolver1.opendns.com. 120 IN A 192.168.0.1&amp;quot;&lt;br /&gt;
local-data: &amp;quot;resolver2.opendns.com. 120 IN A 192.168.0.1&amp;quot;&lt;br /&gt;
local-data: &amp;quot;resolver1-fs.opendns.com. 120 IN A 192.168.0.1&amp;quot;&lt;br /&gt;
local-data: &amp;quot;resolver2-fs.opendns.com. 120 IN A 192.168.0.1&amp;quot;&lt;br /&gt;
local-data: &amp;quot;dns.oszx.co. 120 IN A 192.168.0.1&amp;quot;&lt;br /&gt;
local-data: &amp;quot;a.passcloud.xyz. 120 IN A 192.168.0.1&amp;quot;&lt;br /&gt;
local-data: &amp;quot;i.passcloud.xyz. 120 IN A 192.168.0.1&amp;quot;&lt;br /&gt;
local-data: &amp;quot;doh.post-factum.tk. 120 IN A 192.168.0.1&amp;quot;&lt;br /&gt;
local-data: &amp;quot;doh.powerdns.org. 120 IN A 192.168.0.1&amp;quot;&lt;br /&gt;
local-data: &amp;quot;rpz-public-resolver1.rrdns.pch.net. 120 IN A 192.168.0.1&amp;quot;&lt;br /&gt;
local-data: &amp;quot;dns.pumplex.com. 120 IN A 192.168.0.1&amp;quot;&lt;br /&gt;
local-data: &amp;quot;dns.quad9.net. 120 IN A 192.168.0.1&amp;quot;&lt;br /&gt;
local-data: &amp;quot;dns9.quad9.net. 120 IN A 192.168.0.1&amp;quot;&lt;br /&gt;
local-data: &amp;quot;dns10.quad9.net. 120 IN A 192.168.0.1&amp;quot;&lt;br /&gt;
local-data: &amp;quot;dns11.quad9.net. 120 IN A 192.168.0.1&amp;quot;&lt;br /&gt;
local-data: &amp;quot;dns12.quad9.net. 120 IN A 192.168.0.1&amp;quot;&lt;br /&gt;
local-data: &amp;quot;dns13.quad9.net. 120 IN A 192.168.0.1&amp;quot;&lt;br /&gt;
local-data: &amp;quot;dns-nosec.quad9.net. 120 IN A 192.168.0.1&amp;quot;&lt;br /&gt;
local-data: &amp;quot;dns.rubyfish.cn. 120 IN A 192.168.0.1&amp;quot;&lt;br /&gt;
local-data: &amp;quot;ea-dns.rubyfish.cn. 120 IN A 192.168.0.1&amp;quot;&lt;br /&gt;
local-data: &amp;quot;uw-dns.rubyfish.cn. 120 IN A 192.168.0.1&amp;quot;&lt;br /&gt;
local-data: &amp;quot;rumpelsepp.org. 120 IN A 192.168.0.1&amp;quot;&lt;br /&gt;
local-data: &amp;quot;dns1.ryan-palmer.com. 120 IN A 192.168.0.1&amp;quot;&lt;br /&gt;
local-data: &amp;quot;doh.securedns.eu. 120 IN A 192.168.0.1&amp;quot;&lt;br /&gt;
local-data: &amp;quot;ads-doh.securedns.eu. 120 IN A 192.168.0.1&amp;quot;&lt;br /&gt;
local-data: &amp;quot;dot.securedns.eu. 120 IN A 192.168.0.1&amp;quot;&lt;br /&gt;
local-data: &amp;quot;doh.seby.io. 120 IN A 192.168.0.1&amp;quot;&lt;br /&gt;
local-data: &amp;quot;doh-2.seby.io. 120 IN A 192.168.0.1&amp;quot;&lt;br /&gt;
local-data: &amp;quot;dot.seby.io. 120 IN A 192.168.0.1&amp;quot;&lt;br /&gt;
local-data: &amp;quot;2.dnscrypt-cert.dns.seby.io. 120 IN A 192.168.0.1&amp;quot;&lt;br /&gt;
local-data: &amp;quot;dnsovertls.sinodun.com. 120 IN A 192.168.0.1&amp;quot;&lt;br /&gt;
local-data: &amp;quot;dnsovertls1.sinodun.com. 120 IN A 192.168.0.1&amp;quot;&lt;br /&gt;
local-data: &amp;quot;dnsovertls2.sinodun.com. 120 IN A 192.168.0.1&amp;quot;&lt;br /&gt;
local-data: &amp;quot;dnsovertls3.sinodun.com. 120 IN A 192.168.0.1&amp;quot;&lt;br /&gt;
local-data: &amp;quot;fi.doh.dns.snopyta.org. 120 IN A 192.168.0.1&amp;quot;&lt;br /&gt;
local-data: &amp;quot;fi.dot.dns.snopyta.org. 120 IN A 192.168.0.1&amp;quot;&lt;br /&gt;
local-data: &amp;quot;dns.switch.ch. 120 IN A 192.168.0.1&amp;quot;&lt;br /&gt;
local-data: &amp;quot;ibksturm.synology.me. 120 IN A 192.168.0.1&amp;quot;&lt;br /&gt;
local-data: &amp;quot;dns.t53.de. 120 IN A 192.168.0.1&amp;quot;&lt;br /&gt;
local-data: &amp;quot;dns.therifleman.name. 120 IN A 192.168.0.1&amp;quot;&lt;br /&gt;
local-data: &amp;quot;doh.tiar.app. 120 IN A 192.168.0.1&amp;quot;&lt;br /&gt;
local-data: &amp;quot;dot.tiar.app. 120 IN A 192.168.0.1&amp;quot;&lt;br /&gt;
local-data: &amp;quot;doh.tiarap.org. 120 IN A 192.168.0.1&amp;quot;&lt;br /&gt;
local-data: &amp;quot;jp.tiar.app. 120 IN A 192.168.0.1&amp;quot;&lt;br /&gt;
local-data: &amp;quot;jp.tiarap.org. 120 IN A 192.168.0.1&amp;quot;&lt;br /&gt;
local-data: &amp;quot;dns.twnic.tw. 120 IN A 192.168.0.1&amp;quot;&lt;br /&gt;
local-data: &amp;quot;doh.this.web.id. 120 IN A 192.168.0.1&amp;quot;&lt;br /&gt;
local-data: &amp;quot;dns.wugui.zone. 120 IN A 192.168.0.1&amp;quot;&lt;br /&gt;
local-data: &amp;quot;dns-asia.wugui.zone. 120 IN A 192.168.0.1&amp;quot;&lt;br /&gt;
local-data: &amp;quot;adfree.usableprivacy.net. 120 IN A 192.168.0.1&amp;quot;&lt;br /&gt;
local-data: &amp;quot;doh.xfinity.com. 120 IN A 192.168.0.1&amp;quot;&lt;br /&gt;
local-data: &amp;quot;doh.gslb2.xfinity.com. 120 IN A 192.168.0.1&amp;quot;&lt;br /&gt;
local-data: &amp;quot;fdns1.dismail.de. 120 IN A 192.168.0.1&amp;quot;&lt;br /&gt;
local-data: &amp;quot;fdns2.dismail.de. 120 IN A 192.168.0.1&amp;quot;&lt;br /&gt;
local-data: &amp;quot;anycast.censurfridns.dk. 120 IN A 192.168.0.1&amp;quot;&lt;br /&gt;
local-data: &amp;quot;unicast.censurfridns.dk. 120 IN A 192.168.0.1&amp;quot;&lt;br /&gt;
local-data: &amp;quot;anycast.uncensoreddns.org. 120 IN A 192.168.0.1&amp;quot;&lt;br /&gt;
local-data: &amp;quot;unicast.uncensoreddns.org. 120 IN A 192.168.0.1&amp;quot;&lt;br /&gt;
local-data: &amp;quot;dns.comss.one. 120 IN A 192.168.0.1&amp;quot;&lt;br /&gt;
local-data: &amp;quot;dns.east.comss.one. 120 IN A 192.168.0.1&amp;quot;&lt;br /&gt;
local-data: &amp;quot;dns-doh.dnsforfamily.com. 120 IN A 192.168.0.1&amp;quot;&lt;br /&gt;
local-data: &amp;quot;dns-dot.dnsforfamily.com. 120 IN A 192.168.0.1&amp;quot;&lt;br /&gt;
local-data: &amp;quot;dns.cfiec.net. 120 IN A 192.168.0.1&amp;quot;&lt;br /&gt;
local-data: &amp;quot;asia.dnscepat.id. 120 IN A 192.168.0.1&amp;quot;&lt;br /&gt;
local-data: &amp;quot;eropa.dnscepat.id. 120 IN A 192.168.0.1&amp;quot;&lt;br /&gt;
local-data: &amp;quot;doh.360.cn. 120 IN A 192.168.0.1&amp;quot;&lt;br /&gt;
local-data: &amp;quot;dot.360.cn. 120 IN A 192.168.0.1&amp;quot;&lt;br /&gt;
local-data: &amp;quot;doh.pub. 120 IN A 192.168.0.1&amp;quot;&lt;br /&gt;
local-data: &amp;quot;dns.pub. 120 IN A 192.168.0.1&amp;quot;&lt;br /&gt;
local-data: &amp;quot;dot.pub. 120 IN A 192.168.0.1&amp;quot;&lt;br /&gt;
local-data: &amp;quot;kaitain.restena.lu. 120 IN A 192.168.0.1&amp;quot;&lt;br /&gt;
local-data: &amp;quot;getdnsapi.net. 120 IN A 192.168.0.1&amp;quot;&lt;br /&gt;
local-data: &amp;quot;dns.larsdebruin.net. 120 IN A 192.168.0.1&amp;quot;&lt;br /&gt;
local-data: &amp;quot;dns-tls.bitwiseshift.net. 120 IN A 192.168.0.1&amp;quot;&lt;br /&gt;
local-data: &amp;quot;ns1.dnsprivacy.at. 120 IN A 192.168.0.1&amp;quot;&lt;br /&gt;
local-data: &amp;quot;ns2.dnsprivacy.at. 120 IN A 192.168.0.1&amp;quot;&lt;br /&gt;
local-data: &amp;quot;dns.bitgeek.in. 120 IN A 192.168.0.1&amp;quot;&lt;br /&gt;
local-data: &amp;quot;privacydns.go6lab.si. 120 IN A 192.168.0.1&amp;quot;&lt;br /&gt;
local-data: &amp;quot;dnsotls.lab.nic.cl. 120 IN A 192.168.0.1&amp;quot;&lt;br /&gt;
local-data: &amp;quot;tls-dns-u.odvr.dns-oarc.net. 120 IN A 192.168.0.1&amp;quot;&lt;br /&gt;
local-data: &amp;quot;doh.centraleu.pi-dns.com. 120 IN A 192.168.0.1&amp;quot;&lt;br /&gt;
local-data: &amp;quot;dot.centraleu.pi-dns.com. 120 IN A 192.168.0.1&amp;quot;&lt;br /&gt;
local-data: &amp;quot;doh.northeu.pi-dns.com. 120 IN A 192.168.0.1&amp;quot;&lt;br /&gt;
local-data: &amp;quot;dot.northeu.pi-dns.com. 120 IN A 192.168.0.1&amp;quot;&lt;br /&gt;
local-data: &amp;quot;doh.westus.pi-dns.com. 120 IN A 192.168.0.1&amp;quot;&lt;br /&gt;
local-data: &amp;quot;dot.westus.pi-dns.com. 120 IN A 192.168.0.1&amp;quot;&lt;br /&gt;
local-data: &amp;quot;doh.eastus.pi-dns.com. 120 IN A 192.168.0.1&amp;quot;&lt;br /&gt;
local-data: &amp;quot;dot.eastus.pi-dns.com. 120 IN A 192.168.0.1&amp;quot;&lt;br /&gt;
local-data: &amp;quot;doh.eastau.pi-dns.com. 120 IN A 192.168.0.1&amp;quot;&lt;br /&gt;
local-data: &amp;quot;dot.eastau.pi-dns.com. 120 IN A 192.168.0.1&amp;quot;&lt;br /&gt;
local-data: &amp;quot;doh.eastas.pi-dns.com. 120 IN A 192.168.0.1&amp;quot;&lt;br /&gt;
local-data: &amp;quot;dot.eastas.pi-dns.com. 120 IN A 192.168.0.1&amp;quot;&lt;br /&gt;
local-data: &amp;quot;doh.pi-dns.com. 120 IN A 192.168.0.1&amp;quot;&lt;br /&gt;
local-data: &amp;quot;freedns.controld.com. 120 IN A 192.168.0.1&amp;quot;&lt;br /&gt;
local-data: &amp;quot;doh.mullvad.net. 120 IN A 192.168.0.1&amp;quot;&lt;br /&gt;
local-data: &amp;quot;dns.arapurayil.com. 120 IN A 192.168.0.1&amp;quot;&lt;br /&gt;
local-data: &amp;quot;dot.xfinity.com. 120 IN A 192.168.0.1&amp;quot;&lt;br /&gt;
local-data: &amp;quot;dot.cox.net. 120 IN A 192.168.0.1&amp;quot;&lt;br /&gt;
local-data: &amp;quot;doh.cox.net. 120 IN A 192.168.0.1&amp;quot;&lt;br /&gt;
local-data: &amp;quot;dns.sb. 120 IN A 192.168.0.1&amp;quot;&lt;br /&gt;
local-data: &amp;quot;8888.google. 120 IN A 192.168.0.1&amp;quot;&lt;br /&gt;
local-data: &amp;quot;doh.quickline.ch. 120 IN A 192.168.0.1&amp;quot;&lt;br /&gt;
local-data: &amp;quot;doh-02.spectrum.com. 120 IN A 192.168.0.1&amp;quot;&lt;br /&gt;
local-data: &amp;quot;doh-01.spectrum.com. 120 IN A 192.168.0.1&amp;quot;&lt;br /&gt;
local-data: &amp;quot;mask.icloud.com. 120 IN A 192.168.0.1&amp;quot;&lt;br /&gt;
local-data: &amp;quot;mask-h2.icloud.com. 120 IN A 192.168.0.1&amp;quot;&lt;br /&gt;
local-data: &amp;quot;dandelionsprout.asuscomm.com. 120 IN A 192.168.0.1&amp;quot;&lt;br /&gt;
local-data: &amp;quot;basic.rethinkdns.com. 120 IN A 192.168.0.1&amp;quot;&lt;br /&gt;
local-data: &amp;quot;max.rethinkdns.com. 120 IN A 192.168.0.1&amp;quot;&lt;br /&gt;
local-data: &amp;quot;dns.levonet.sk. 120 IN A 192.168.0.1&amp;quot;&lt;br /&gt;
local-data: &amp;quot;chromium.dns.nextdns.io. 120 IN A 192.168.0.1&amp;quot;&lt;br /&gt;
local-data: &amp;quot;dot.quickline.ch. 120 IN A 192.168.0.1&amp;quot;&lt;br /&gt;
local-data: &amp;quot;doh.quickline.ch. 120 IN A 192.168.0.1&amp;quot;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&amp;lt;/div&amp;gt;&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;amp;ndash;[[User:zcrayfish|zcrayfish]] &amp;lt;small&amp;gt;([[User talk:zcrayfish|talk]]•[[Special:Contributions/zcrayfish|contribs]]•[[Special:EmailUser/zcrayfish|send email]])&amp;lt;/small&amp;gt; 06:51, 15 February 2024 (UTC)&lt;/div&gt;</summary>
		<author><name>Nangel</name></author>
	</entry>
	<entry>
		<id>https://wiki.alpinelinux.org/w/index.php?title=Using_Unbound_as_an_Ad-blocker&amp;diff=26399</id>
		<title>Using Unbound as an Ad-blocker</title>
		<link rel="alternate" type="text/html" href="https://wiki.alpinelinux.org/w/index.php?title=Using_Unbound_as_an_Ad-blocker&amp;diff=26399"/>
		<updated>2024-02-16T03:46:42Z</updated>

		<summary type="html">&lt;p&gt;Nangel: /* Background */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Basic Components ==&lt;br /&gt;
&lt;br /&gt;
You should have {{Pkg|dnsmasq}} (or another DHCP server) and [[Setting_up_unbound_DNS_server|unbound]] both working on your network.  &lt;br /&gt;
&lt;br /&gt;
== Setting up Unbound To Block/Refuse unwanted addresses ==&lt;br /&gt;
&lt;br /&gt;
There are a number of freely available blacklists on the net.  The installer mentioned above uses these lists by default:&lt;br /&gt;
*https://raw.githubusercontent.com/StevenBlack/hosts/master/hosts&lt;br /&gt;
*https://sysctl.org/cameleon/hosts&lt;br /&gt;
*https://s3.amazonaws.com/lists.disconnect.me/simple_tracking.txt&lt;br /&gt;
*https://s3.amazonaws.com/lists.disconnect.me/simple_ad.txt&lt;br /&gt;
&lt;br /&gt;
Alternatively, there is a set of curated lists at https://github.com/StevenBlack/hosts. There are various categories of lists there. The format of the file is a &amp;quot;host&amp;quot; (so you can put it in {{path|/etc/hosts}} and be done). We will use the hosts file format:&lt;br /&gt;
&lt;br /&gt;
unbound needs to include the &amp;lt;code&amp;gt;blacklists.conf&amp;lt;/code&amp;gt; file into its main configuration. To do so, we need to create the include file in the following format:&lt;br /&gt;
&lt;br /&gt;
{{Cat|/etc/unbound/blacklists.conf|server:&lt;br /&gt;
&lt;br /&gt;
local-zone: &amp;quot;bad-site.com&amp;quot; refuse&lt;br /&gt;
local-zone: &amp;quot;bad-bad-site.com&amp;quot; refuse&lt;br /&gt;
local-zone: &amp;quot;xyz.ads-r-us.com&amp;quot; refuse}}&lt;br /&gt;
&lt;br /&gt;
Here is an example shell script to download the&lt;br /&gt;
[https://raw.githubusercontent.com/StevenBlack/hosts/master/hosts StevenBlack]&lt;br /&gt;
hosts file, and then format it for unbound:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#!/bin/sh&lt;br /&gt;
&lt;br /&gt;
echo &amp;quot;server:&amp;quot; &amp;gt;/etc/unbound/blacklist.conf&lt;br /&gt;
curl -s https://raw.githubusercontent.com/StevenBlack/hosts/master/hosts | \&lt;br /&gt;
        grep ^0.0.0.0 - | \&lt;br /&gt;
        sed &#039;s/ #.*$//;&lt;br /&gt;
        s/^0.0.0.0 \(.*\)/local-zone: &amp;quot;\1&amp;quot; refuse/&#039; \&lt;br /&gt;
        &amp;gt;&amp;gt;/etc/unbound/blacklist.conf&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
You can run this once, or as part of a periodic cron task.&lt;br /&gt;
&lt;br /&gt;
In the {{path|/etc/unbound/unbound.conf}}, add the following line somewhere in the config:&lt;br /&gt;
&lt;br /&gt;
{{Cat|/etc/unbound/unbound.conf|#include &amp;quot;/etc/unbound/blacklist.conf&amp;quot;}}&lt;br /&gt;
&lt;br /&gt;
Reload unbound, and verify the config loads.&lt;br /&gt;
&lt;br /&gt;
== Dnsmasq configuration ==&lt;br /&gt;
&lt;br /&gt;
Dnsmasq defaults to using the resolver in {{path|/etc/resolv.conf}} — if unbound is listening on &amp;lt;code&amp;gt;127.0.0.1&amp;lt;/code&amp;gt;, then have it use that as the resolver.&lt;br /&gt;
&lt;br /&gt;
Alternatively, if unbound is running on another interface, or on a separate machine — use the dhcp-option configuration in dnsmasq:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
dhcp-option=6,[ip-of-unbound-server]&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Enjoy Ad-Free browsing!&lt;br /&gt;
&lt;br /&gt;
[[Category:Networking]]&lt;/div&gt;</summary>
		<author><name>Nangel</name></author>
	</entry>
	<entry>
		<id>https://wiki.alpinelinux.org/w/index.php?title=Dynamic_Multipoint_VPN_(DMVPN)_Phase_3_with_Quagga_NHRPd&amp;diff=23999</id>
		<title>Dynamic Multipoint VPN (DMVPN) Phase 3 with Quagga NHRPd</title>
		<link rel="alternate" type="text/html" href="https://wiki.alpinelinux.org/w/index.php?title=Dynamic_Multipoint_VPN_(DMVPN)_Phase_3_with_Quagga_NHRPd&amp;diff=23999"/>
		<updated>2023-07-29T21:44:06Z</updated>

		<summary type="html">&lt;p&gt;Nangel: /* Awall */  Update link on differences between phase 1,2,3&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{merge|Dynamic Multipoint VPN (DMVPN)}}&lt;br /&gt;
{{TOC right}}&lt;br /&gt;
&lt;br /&gt;
= THIS DOC IS STILL A DRAFT =&lt;br /&gt;
&lt;br /&gt;
= Overview =&lt;br /&gt;
This is a follow-up of the most famous document [http://wiki.alpinelinux.org/wiki/Dynamic_Multipoint_VPN_(DMVPN)],&lt;br /&gt;
since opennhrp has been rewritten as quagga plugin [1], supporting interoperability with new Cisco&#039;s FlexVPN and Strongswan.&lt;br /&gt;
&lt;br /&gt;
This NHRP implementation has some limits yet (Multicast is not ready, so you need to use BGP rather than OSPF), though is usable in a production environment.&lt;br /&gt;
&lt;br /&gt;
{{Note|This document assumes that all Alpine installations are run in [[Installation#Basics|diskless mode]] and that the configuration is saved on USB key}}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
This How-To will show you how to configure a DMVPN solution with this key items:&lt;br /&gt;
&lt;br /&gt;
.1 VPN setup with Strongswan with PSK for the authentication (same PSK between all of the spokes and hub)&lt;br /&gt;
&lt;br /&gt;
.2 DMVPN setup with quagga.nhrpd; &lt;br /&gt;
&lt;br /&gt;
.3 iBGP used for announce LAN subnet&lt;br /&gt;
&lt;br /&gt;
.4 Awall rules to allow NHRP shortcuts between spokes&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
The goal is making private network of spoke&#039;s nodes and hub to communicate each other over VPN created dynamically.&lt;br /&gt;
Routes are learned via BGP, and hte IPSEC VPN is authenticated via PSK.&lt;br /&gt;
&lt;br /&gt;
The logical setup is configured as shown:&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
= Terminology =&lt;br /&gt;
;NBMA: &#039;&#039;Non-Broadcast Multi-Access&#039;&#039; network as described in [http://tools.ietf.org/html/rfc2332 RFC 2332]&lt;br /&gt;
&lt;br /&gt;
;Hub: the &#039;&#039;Next Hop Server&#039;&#039; (NHS) performing the Next Hop Resolution Protocol service within the NBMA cloud.&lt;br /&gt;
&lt;br /&gt;
;Spoke: the &#039;&#039;Next Hop Resolution Protocol Client&#039;&#039; (NHC) which initiates NHRP requests of various types in order to obtain access to the NHRP service.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
= Hardware =&lt;br /&gt;
&lt;br /&gt;
For supporting VIA Padlock engine enable its modules:&lt;br /&gt;
&lt;br /&gt;
{{Cmd|echo -e &amp;quot;padlock_aes\npadlock-sha&amp;quot; &amp;gt;&amp;gt; /etc/modules}}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
= Alpine Installation =&lt;br /&gt;
&lt;br /&gt;
Follow the instructions on  http://wiki.alpinelinux.org/wiki/Create_a_Bootable_USB about how to create a bootable USB.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
= Spoke Nodes =&lt;br /&gt;
&lt;br /&gt;
== Spoke Node 1 ==&lt;br /&gt;
&lt;br /&gt;
== Networking ==&lt;br /&gt;
&lt;br /&gt;
We&#039;re going to setup the spoke node 1 as follow:&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
{|class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!&#039;&#039;&#039;Host&#039;&#039;&#039;&lt;br /&gt;
!&#039;&#039;&#039;Interface&#039;&#039;&#039;&lt;br /&gt;
!&#039;&#039;&#039;Description&#039;&#039;&#039;&lt;br /&gt;
!&#039;&#039;&#039;Subnet&#039;&#039;&#039;&lt;br /&gt;
|-&lt;br /&gt;
|rowspan=&amp;quot;3&amp;quot;|Spoke 1&lt;br /&gt;
|eth0&lt;br /&gt;
|Internet&lt;br /&gt;
|DHCP&lt;br /&gt;
|-&lt;br /&gt;
|eth1&lt;br /&gt;
|LAN&lt;br /&gt;
|192.168.10.0/24&lt;br /&gt;
|-&lt;br /&gt;
|gre1&lt;br /&gt;
|Tunnel&lt;br /&gt;
|172.16.1.1 &lt;br /&gt;
|-&lt;br /&gt;
|rowspan=&amp;quot;3&amp;quot;|Spoke 2&lt;br /&gt;
|eth0&lt;br /&gt;
|Internet&lt;br /&gt;
|DHCP&lt;br /&gt;
|-&lt;br /&gt;
|eth1&lt;br /&gt;
|LAN&lt;br /&gt;
|192.168.20.0/24&lt;br /&gt;
|-&lt;br /&gt;
|gre1&lt;br /&gt;
|Tunnel&lt;br /&gt;
|172.16.2.1 &lt;br /&gt;
|-&lt;br /&gt;
|rowspan=&amp;quot;3&amp;quot;|Spoke 3&lt;br /&gt;
|eth0&lt;br /&gt;
|Internet&lt;br /&gt;
|90.100.150.200&lt;br /&gt;
|-&lt;br /&gt;
|eth1&lt;br /&gt;
|LAN&lt;br /&gt;
|192.168.30.0/24&lt;br /&gt;
|-&lt;br /&gt;
|gre1&lt;br /&gt;
|Tunnel&lt;br /&gt;
|172.16.3.1 &lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
With your favorite editor open &amp;lt;code&amp;gt;/etc/network/interfaces&amp;lt;/code&amp;gt; and add interfaces:&lt;br /&gt;
&lt;br /&gt;
{{cat|/etc/network/interfaces|&lt;br /&gt;
auto lo&lt;br /&gt;
iface lo inet loopback&lt;br /&gt;
&lt;br /&gt;
auto eth0&lt;br /&gt;
iface eth0 inet dhcp&lt;br /&gt;
        &lt;br /&gt;
auto eth1&lt;br /&gt;
iface eth1 inet static&lt;br /&gt;
        address 192.168.10.1&lt;br /&gt;
        netmask 255.255.255.0&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== SSH ==&lt;br /&gt;
Remove password authentication and DNS reverse lookup:&lt;br /&gt;
&lt;br /&gt;
{{Cmd|sed -i &amp;quot;s/.PasswordAuthentication yes/PasswordAuthentication no/&amp;quot; /etc/ssh/sshd_config&lt;br /&gt;
sed -i &amp;quot;s/.UseDNS yes/UseDNS no/&amp;quot; /etc/ssh/sshd_config}}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Restart ssh:&lt;br /&gt;
{{Cmd|/etc/init.d/sshd restart}}&lt;br /&gt;
&lt;br /&gt;
== GRE Tunnel ==&lt;br /&gt;
With your favorite editor open &amp;lt;code&amp;gt;/etc/network/interfaces&amp;lt;/code&amp;gt; and add the following:&lt;br /&gt;
&lt;br /&gt;
{{cat|/etc/network/interfaces|&amp;lt;nowiki&amp;gt;&lt;br /&gt;
auto gre1&lt;br /&gt;
iface gre1 inet static&lt;br /&gt;
        pre-up ip tunnel add gre1 mode gre key 42 ttl 64 dev eth0 || true&lt;br /&gt;
        address 172.16.1.1&lt;br /&gt;
        netmask 255.255.255.255&lt;br /&gt;
        post-down ip tunnel del $IFACE || true&lt;br /&gt;
&amp;lt;/nowiki&amp;gt;}}&lt;br /&gt;
&lt;br /&gt;
Bring up the new &amp;lt;code&amp;gt;gre1&amp;lt;/code&amp;gt; interface:&lt;br /&gt;
&lt;br /&gt;
{{Cmd|ifup gre1}}&lt;br /&gt;
&lt;br /&gt;
== IPSEC ==&lt;br /&gt;
Install package(s):&lt;br /&gt;
&lt;br /&gt;
{{Cmd|apk add strongswan&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
{{cat|/etc/swanctl/swanctl.conf|&amp;lt;nowiki&amp;gt;&lt;br /&gt;
connections {&lt;br /&gt;
        dmvpn {&lt;br /&gt;
                version = 2&lt;br /&gt;
                pull = no&lt;br /&gt;
                mobike = no&lt;br /&gt;
                dpd_delay = 15&lt;br /&gt;
                dpd_timeout = 30&lt;br /&gt;
                fragmentation = yes&lt;br /&gt;
                unique = replace&lt;br /&gt;
                rekey_time = 4h&lt;br /&gt;
                reauth_time = 13h&lt;br /&gt;
                proposals = aes256-sha512-ecp384&lt;br /&gt;
                local {&lt;br /&gt;
                        auth = psk&lt;br /&gt;
                        id = spoke1&lt;br /&gt;
                }&lt;br /&gt;
                remote {&lt;br /&gt;
                        auth = psk&lt;br /&gt;
                }&lt;br /&gt;
                children {&lt;br /&gt;
                        dmvpn {&lt;br /&gt;
                                esp_proposals = aes256-sha512-ecp384&lt;br /&gt;
                                local_ts = dynamic[gre]&lt;br /&gt;
                                remote_ts = dynamic[gre]&lt;br /&gt;
                                inactivity = 90m&lt;br /&gt;
                                rekey_time = 100m&lt;br /&gt;
                                mode = transport&lt;br /&gt;
                                dpd_action = clear&lt;br /&gt;
                                reqid = 1&lt;br /&gt;
                        }&lt;br /&gt;
                }&lt;br /&gt;
        }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/nowiki&amp;gt;}}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
{{cat|/etc/ipsec.secrets|&lt;br /&gt;
# /etc/ipsec.secrets - strongSwan IPsec secrets file&lt;br /&gt;
&lt;br /&gt;
%any : PSK &amp;quot;cisco12345678987654321&amp;quot;&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
Start service(s):&lt;br /&gt;
&lt;br /&gt;
{{Cmd|/etc/init.d/charon start&lt;br /&gt;
rc-update add charon}}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Routing ==&lt;br /&gt;
&lt;br /&gt;
This section will configure the routing protocol suite quagga patched with NHRP support.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
{{Cmd|apk add quagga-nhrp&lt;br /&gt;
touch /etc/quagga/zebra.conf /etc/quagga/bgpd.conf /etc/quagga/nhrpd.conf}}}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Fix permissions:&lt;br /&gt;
{{Cmd|chown -R quagga:quagga /etc/quagga}}}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Start all the daemons:&lt;br /&gt;
&lt;br /&gt;
{{Cmd|/etc/init.d/zebra start&lt;br /&gt;
/etc/init.d/bgpd start&lt;br /&gt;
/etc/init.d/nhrpd start&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
Configure it to start from boot:&lt;br /&gt;
{{Cmd|rc-update add zebra nhrpd bgpd}}&lt;br /&gt;
&lt;br /&gt;
Now  we&#039;re going to configure it with &amp;lt;code&amp;gt;vtysh&amp;lt;/code&amp;gt; cli:&lt;br /&gt;
&lt;br /&gt;
{{Cmd|vtysh&lt;br /&gt;
&lt;br /&gt;
configure terminal&lt;br /&gt;
log syslog&lt;br /&gt;
debug nhrp common&lt;br /&gt;
&lt;br /&gt;
router bgp 65000&lt;br /&gt;
 bgp router-id 172.16.1.1&lt;br /&gt;
 network 192.168.10.0/24&lt;br /&gt;
 neighbor spokes-ibgp peer-group&lt;br /&gt;
 neighbor spokes-ibgp remote-as 65000&lt;br /&gt;
 neighbor spokes-ibgp ebgp-multihop 1&lt;br /&gt;
 neighbor spokes-ibgp disable-connected-check&lt;br /&gt;
 neighbor spokes-ibgp advertisement-interval 1&lt;br /&gt;
 neighbor spokes-ibgp next-hop-self&lt;br /&gt;
 neighbor spokes-ibgp soft-reconfiguration inbound&lt;br /&gt;
 neighbor 172.16.0.1 peer-group spokes-ibgp&lt;br /&gt;
exit&lt;br /&gt;
&lt;br /&gt;
nhrp nflog-group 1&lt;br /&gt;
interface gre1&lt;br /&gt;
 ip nhrp network-id 1&lt;br /&gt;
 ip nhrp nhs dynamic nbma 50.60.70.80&lt;br /&gt;
 ip nhrp registration no-unique&lt;br /&gt;
 ip nhrp shortcut&lt;br /&gt;
 ipv6 nd suppress-ra&lt;br /&gt;
 no link-detect&lt;br /&gt;
 tunnel protection vici profile dmvpn&lt;br /&gt;
 tunnel source eth0&lt;br /&gt;
 exit&lt;br /&gt;
write mem&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
= Hub Node =&lt;br /&gt;
&lt;br /&gt;
We will document only what changes from the Spoke node setup.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Networking ==&lt;br /&gt;
&lt;br /&gt;
The NHS (Hub) has the following settings:&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
{|class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!&#039;&#039;&#039;Host&#039;&#039;&#039;&lt;br /&gt;
!&#039;&#039;&#039;Interface&#039;&#039;&#039;&lt;br /&gt;
!&#039;&#039;&#039;Description&#039;&#039;&#039;&lt;br /&gt;
!&#039;&#039;&#039;Subnet&#039;&#039;&#039;&lt;br /&gt;
|-&lt;br /&gt;
|rowspan=&amp;quot;2&amp;quot;|Hub&lt;br /&gt;
|eth0&lt;br /&gt;
|Internet&lt;br /&gt;
|50.60.70.80&lt;br /&gt;
|-&lt;br /&gt;
|eth1&lt;br /&gt;
|LAN&lt;br /&gt;
|192.168.1.0/24&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
With your favorite editor open &amp;lt;code&amp;gt;/etc/network/interfaces&amp;lt;/code&amp;gt; and add interfaces:&lt;br /&gt;
&lt;br /&gt;
{{cat|/etc/network/interfaces|&lt;br /&gt;
auto lo&lt;br /&gt;
iface lo inet loopback&lt;br /&gt;
&lt;br /&gt;
auto eth0&lt;br /&gt;
iface eth0 inet static&lt;br /&gt;
    address 50.60.70.80&lt;br /&gt;
    netmask 255.255.255.0&lt;br /&gt;
    gateway 50.60.70.1&lt;br /&gt;
        &lt;br /&gt;
auto eth1&lt;br /&gt;
iface eth1 inet static&lt;br /&gt;
        address 192.168.1.1&lt;br /&gt;
        netmask 255.255.255.0&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== GRE Tunnel ==&lt;br /&gt;
With your favorite editor open &amp;lt;code&amp;gt;/etc/network/interfaces&amp;lt;/code&amp;gt; and add the following:&lt;br /&gt;
&lt;br /&gt;
{{cat|/etc/network/interfaces|&amp;lt;nowiki&amp;gt;&lt;br /&gt;
auto gre1&lt;br /&gt;
iface gre1 inet static&lt;br /&gt;
        pre-up ip tunnel add gre1 mode gre key 42 ttl 64 dev eth0 || true&lt;br /&gt;
        address 172.16.0.1&lt;br /&gt;
        netmask 255.255.255.255&lt;br /&gt;
        post-down ip tunnel del $IFACE || true&lt;br /&gt;
&amp;lt;/nowiki&amp;gt;}}&lt;br /&gt;
&lt;br /&gt;
Bring up the new gre1 interface:&lt;br /&gt;
&lt;br /&gt;
{{Cmd|ifup gre1}}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Routing ==&lt;br /&gt;
&lt;br /&gt;
Again, routing is configured directly with &amp;lt;code&amp;gt;vtysh&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
{{Cmd|vtysh&lt;br /&gt;
&lt;br /&gt;
configure terminal&lt;br /&gt;
log syslog&lt;br /&gt;
debug nhrp common&lt;br /&gt;
&lt;br /&gt;
router bgp 65000&lt;br /&gt;
 bgp router-id 172.16.0.1&lt;br /&gt;
 bgp deterministic-med&lt;br /&gt;
 network 172.16.0.0/16&lt;br /&gt;
 redistribute nhrp&lt;br /&gt;
 neighbor spokes-ibgp peer-group&lt;br /&gt;
 neighbor spokes-ibgp remote-as 65000&lt;br /&gt;
 neighbor spokes-ibgp ebgp-multihop 1&lt;br /&gt;
 neighbor spokes-ibgp disable-connected-check&lt;br /&gt;
 neighbor spokes-ibgp route-reflector-client&lt;br /&gt;
 neighbor spokes-ibgp next-hop-self all&lt;br /&gt;
 neighbor spokes-ibgp advertisement-interval 1&lt;br /&gt;
 neighbor spokes-ibgp soft-reconfiguration inbound&lt;br /&gt;
 neighbor 172.16.1.1 peer-group spokes-ibgp&lt;br /&gt;
exit&lt;br /&gt;
&lt;br /&gt;
interface gre1&lt;br /&gt;
 ip nhrp network-id 1&lt;br /&gt;
 ip nhrp nhs dynamic nbma 50.60.70.80&lt;br /&gt;
 ip nhrp registration no-unique&lt;br /&gt;
 ip nhrp shortcut&lt;br /&gt;
 ipv6 nd suppress-ra&lt;br /&gt;
 no link-detect&lt;br /&gt;
 tunnel protection vici profile dmvpn&lt;br /&gt;
 tunnel source eth0&lt;br /&gt;
 exit&lt;br /&gt;
write mem&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Add the lines &amp;lt;code&amp;gt;neighbor %Spoke1_GRE_IP%...&amp;lt;/code&amp;gt; for each spoke node you have.&lt;br /&gt;
For instance, if you want to add spoke node with gre1 address 172.16.3.1: &lt;br /&gt;
&lt;br /&gt;
{{Cmd|vtysh&lt;br /&gt;
conf t&lt;br /&gt;
router bgp 65000&lt;br /&gt;
neighbor 172.16.3.1 peer-group spokes-ibgp&lt;br /&gt;
exit&lt;br /&gt;
write mem&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Awall ==&lt;br /&gt;
&lt;br /&gt;
Differently from DMVPN Phase 2, in the Phase 3 DMVPN the HUB is the default gateway for all the spokes, then the spokes are able to communicate directly each other by means of NHRP redirects.&lt;br /&gt;
&lt;br /&gt;
(For a good explanation of the differences between Phase 1, Phase 2 and Phase 3 DMVPN, see https://ine.com/blog/2008-12-23-dmvpn-phase-3).&lt;br /&gt;
&lt;br /&gt;
This is implemented by sending traffic indication notifications with iptables nflog.&lt;br /&gt;
&lt;br /&gt;
This is the  complete firewall configuration for the HUB, using Alpine Firewall Framework, Awall [http://wiki.alpinelinux.org/wiki/Alpine_Wall].&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
With your favorite editor open &amp;lt;code&amp;gt;/etc/awall/optional/zones.json&amp;lt;/code&amp;gt;:&lt;br /&gt;
&lt;br /&gt;
{{cat|/etc/awall/optional/zones.json|&amp;lt;nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
{&lt;br /&gt;
  &amp;quot;description&amp;quot;: &amp;quot;Zones - zone definition for management&amp;quot;,&lt;br /&gt;
&lt;br /&gt;
  &amp;quot;variable&amp;quot;: {&lt;br /&gt;
        &amp;quot;SUBNETS&amp;quot;: [ &amp;quot;192.168.0.0/16&amp;quot;, &amp;quot;172.16.0.0/16&amp;quot; ]&lt;br /&gt;
  },&lt;br /&gt;
&lt;br /&gt;
  &amp;quot;zone&amp;quot;: {&lt;br /&gt;
    &amp;quot;DMVPN&amp;quot;: { &amp;quot;addr&amp;quot;: &amp;quot;$SUBNETS&amp;quot; }&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/nowiki&amp;gt;}}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Now, create &amp;lt;code&amp;gt;/etc/awall/optional/inet.json&amp;lt;/code&amp;gt;:&lt;br /&gt;
&lt;br /&gt;
{{cat|/etc/awall/optional/inet.json|&amp;lt;nowiki&amp;gt;&lt;br /&gt;
{&lt;br /&gt;
  &amp;quot;description&amp;quot;: &amp;quot;Internet - Host Management (rate limited)&amp;quot;,&lt;br /&gt;
&lt;br /&gt;
  &amp;quot;zone&amp;quot;: {&lt;br /&gt;
    &amp;quot;INET&amp;quot;: { &amp;quot;iface&amp;quot;: &amp;quot;eth0&amp;quot; }&lt;br /&gt;
  },&lt;br /&gt;
&lt;br /&gt;
  &amp;quot;policy&amp;quot;: [&lt;br /&gt;
    { &amp;quot;in&amp;quot;: &amp;quot;INET&amp;quot;, &amp;quot;action&amp;quot;: &amp;quot;drop&amp;quot; }&lt;br /&gt;
  ],&lt;br /&gt;
&lt;br /&gt;
  &amp;quot;filter&amp;quot;: [&lt;br /&gt;
    {&lt;br /&gt;
      &amp;quot;in&amp;quot;: &amp;quot;INET&amp;quot;,&lt;br /&gt;
      &amp;quot;out&amp;quot;: &amp;quot;_fw&amp;quot;,&lt;br /&gt;
      &amp;quot;service&amp;quot;: &amp;quot;ping&amp;quot;,&lt;br /&gt;
      &amp;quot;action&amp;quot;: &amp;quot;accept&amp;quot;,&lt;br /&gt;
      &amp;quot;flow-limit&amp;quot;: { &amp;quot;count&amp;quot;: 10, &amp;quot;interval&amp;quot;: 6 }&lt;br /&gt;
    },&lt;br /&gt;
    {&lt;br /&gt;
      &amp;quot;in&amp;quot;: &amp;quot;INET&amp;quot;,&lt;br /&gt;
      &amp;quot;out&amp;quot;: &amp;quot;_fw&amp;quot;,&lt;br /&gt;
      &amp;quot;service&amp;quot;: &amp;quot;ssh&amp;quot;,&lt;br /&gt;
      &amp;quot;action&amp;quot;: &amp;quot;accept&amp;quot;,&lt;br /&gt;
      &amp;quot;conn-limit&amp;quot;: { &amp;quot;count&amp;quot;: 3, &amp;quot;interval&amp;quot;: 60 }&lt;br /&gt;
    },&lt;br /&gt;
    {&lt;br /&gt;
      &amp;quot;in&amp;quot;: &amp;quot;_fw&amp;quot;,&lt;br /&gt;
      &amp;quot;out&amp;quot;: &amp;quot;INET&amp;quot;,&lt;br /&gt;
      &amp;quot;service&amp;quot;: [ &amp;quot;dns&amp;quot;, &amp;quot;http&amp;quot;, &amp;quot;ntp&amp;quot; ],&lt;br /&gt;
      &amp;quot;action&amp;quot;: &amp;quot;accept&amp;quot;&lt;br /&gt;
    },&lt;br /&gt;
    {&lt;br /&gt;
      &amp;quot;in&amp;quot;: &amp;quot;_fw&amp;quot;,&lt;br /&gt;
      &amp;quot;service&amp;quot;: [ &amp;quot;ping&amp;quot;, &amp;quot;ssh&amp;quot; ],&lt;br /&gt;
      &amp;quot;action&amp;quot;: &amp;quot;accept&amp;quot;&lt;br /&gt;
    }&lt;br /&gt;
  ]&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/nowiki&amp;gt;}}&lt;br /&gt;
&lt;br /&gt;
Now, the DMVPN rule:&lt;br /&gt;
&lt;br /&gt;
{{cat|/etc/awall/optional/dmvpn.json|&amp;lt;nowiki&amp;gt;&lt;br /&gt;
{&lt;br /&gt;
  &amp;quot;description&amp;quot;: &amp;quot;DMVPN specific rules&amp;quot;,&lt;br /&gt;
&lt;br /&gt;
  &amp;quot;import&amp;quot;: [ &amp;quot;inet&amp;quot;, &amp;quot;zones&amp;quot; ],&lt;br /&gt;
&lt;br /&gt;
  &amp;quot;variable&amp;quot;: {&lt;br /&gt;
    &amp;quot;HUB&amp;quot;: true&lt;br /&gt;
  },&lt;br /&gt;
&lt;br /&gt;
  &amp;quot;policy&amp;quot;: [&lt;br /&gt;
    { &amp;quot;in&amp;quot;: &amp;quot;DMVPN&amp;quot;, &amp;quot;out&amp;quot;: &amp;quot;DMVPN&amp;quot;, &amp;quot;action&amp;quot;: &amp;quot;accept&amp;quot; }&lt;br /&gt;
  ],&lt;br /&gt;
&lt;br /&gt;
  &amp;quot;zone&amp;quot;: {&lt;br /&gt;
    &amp;quot;DMVPN&amp;quot;: { &amp;quot;iface&amp;quot;: &amp;quot;gre1&amp;quot;, &amp;quot;addr&amp;quot;: &amp;quot;$SUBNETS&amp;quot;, &amp;quot;route-back&amp;quot;: &amp;quot;$HUB&amp;quot; }&lt;br /&gt;
  },&lt;br /&gt;
&lt;br /&gt;
  &amp;quot;filter&amp;quot;: [&lt;br /&gt;
    { &amp;quot;in&amp;quot;: &amp;quot;INET&amp;quot;, &amp;quot;out&amp;quot;: &amp;quot;_fw&amp;quot;, &amp;quot;service&amp;quot;: &amp;quot;ipsec&amp;quot;, &amp;quot;action&amp;quot;: &amp;quot;accept&amp;quot; },&lt;br /&gt;
    { &amp;quot;in&amp;quot;: &amp;quot;_fw&amp;quot;, &amp;quot;out&amp;quot;: &amp;quot;INET&amp;quot;, &amp;quot;service&amp;quot;: &amp;quot;ipsec&amp;quot;, &amp;quot;action&amp;quot;: &amp;quot;accept&amp;quot; },&lt;br /&gt;
    {&lt;br /&gt;
      &amp;quot;in&amp;quot;: &amp;quot;INET&amp;quot;,&lt;br /&gt;
      &amp;quot;out&amp;quot;: &amp;quot;_fw&amp;quot;,&lt;br /&gt;
      &amp;quot;ipsec&amp;quot;: &amp;quot;in&amp;quot;,&lt;br /&gt;
      &amp;quot;service&amp;quot;: &amp;quot;gre&amp;quot;,&lt;br /&gt;
      &amp;quot;action&amp;quot;: &amp;quot;accept&amp;quot;&lt;br /&gt;
    },&lt;br /&gt;
    {&lt;br /&gt;
      &amp;quot;in&amp;quot;: &amp;quot;_fw&amp;quot;,&lt;br /&gt;
      &amp;quot;out&amp;quot;: &amp;quot;INET&amp;quot;,&lt;br /&gt;
      &amp;quot;ipsec&amp;quot;: &amp;quot;out&amp;quot;,&lt;br /&gt;
      &amp;quot;service&amp;quot;: &amp;quot;gre&amp;quot;,&lt;br /&gt;
      &amp;quot;action&amp;quot;: &amp;quot;accept&amp;quot;&lt;br /&gt;
    },&lt;br /&gt;
&lt;br /&gt;
    { &amp;quot;in&amp;quot;: &amp;quot;_fw&amp;quot;, &amp;quot;out&amp;quot;: &amp;quot;DMVPN&amp;quot;, &amp;quot;service&amp;quot;: &amp;quot;bgp&amp;quot;, &amp;quot;action&amp;quot;: &amp;quot;accept&amp;quot; },&lt;br /&gt;
    { &amp;quot;in&amp;quot;: &amp;quot;DMVPN&amp;quot;, &amp;quot;out&amp;quot;: &amp;quot;_fw&amp;quot;, &amp;quot;service&amp;quot;: &amp;quot;bgp&amp;quot;, &amp;quot;action&amp;quot;: &amp;quot;accept&amp;quot;},&lt;br /&gt;
    { &amp;quot;out&amp;quot;: &amp;quot;INET&amp;quot;, &amp;quot;dest&amp;quot;: &amp;quot;$SUBNETS&amp;quot;, &amp;quot;action&amp;quot;: &amp;quot;reject&amp;quot; }&lt;br /&gt;
  ]&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/nowiki&amp;gt;}}&lt;br /&gt;
&lt;br /&gt;
Management interface allowed traffic:&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
{{cat|/etc/awall/optional/management.json|&amp;lt;nowiki&amp;gt;&lt;br /&gt;
{&lt;br /&gt;
  &amp;quot;description&amp;quot;: &amp;quot;Host Management (ssh, https, ping)&amp;quot;,&lt;br /&gt;
&lt;br /&gt;
  &amp;quot;import&amp;quot;: [ &amp;quot;zones&amp;quot; ],&lt;br /&gt;
&lt;br /&gt;
  &amp;quot;policy&amp;quot;: [&lt;br /&gt;
    { &amp;quot;in&amp;quot;: &amp;quot;DMVPN&amp;quot;, &amp;quot;out&amp;quot;: &amp;quot;_fw&amp;quot;, &amp;quot;action&amp;quot;: &amp;quot;reject&amp;quot; }&lt;br /&gt;
  ],&lt;br /&gt;
&lt;br /&gt;
  &amp;quot;filter&amp;quot;: [&lt;br /&gt;
    {&lt;br /&gt;
      &amp;quot;in&amp;quot;: &amp;quot;DMVPN&amp;quot;,&lt;br /&gt;
      &amp;quot;out&amp;quot;: &amp;quot;_fw&amp;quot;,&lt;br /&gt;
      &amp;quot;service&amp;quot;: [ &amp;quot;ping&amp;quot;, &amp;quot;ssh&amp;quot;, &amp;quot;https&amp;quot;, &amp;quot;bgp&amp;quot; ],&lt;br /&gt;
      &amp;quot;action&amp;quot;: &amp;quot;accept&amp;quot;&lt;br /&gt;
    },&lt;br /&gt;
    {&lt;br /&gt;
      &amp;quot;in&amp;quot;: &amp;quot;_fw&amp;quot;,&lt;br /&gt;
      &amp;quot;out&amp;quot;: &amp;quot;DMVPN&amp;quot;,&lt;br /&gt;
      &amp;quot;service&amp;quot;: [ &amp;quot;ping&amp;quot;, &amp;quot;ssh&amp;quot;, &amp;quot;http&amp;quot;, &amp;quot;http-alt&amp;quot;, &amp;quot;https&amp;quot;, &amp;quot;dns&amp;quot;, &amp;quot;ntp&amp;quot; ],&lt;br /&gt;
      &amp;quot;action&amp;quot;: &amp;quot;accept&amp;quot;&lt;br /&gt;
    }&lt;br /&gt;
  ]&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/nowiki&amp;gt;}}&lt;br /&gt;
&lt;br /&gt;
NHRP redirects rule:&lt;br /&gt;
&lt;br /&gt;
{{cat|/etc/awall/optional/vpnredirect.json|&amp;lt;nowiki&amp;gt;&lt;br /&gt;
{&lt;br /&gt;
  &amp;quot;description&amp;quot;: &amp;quot;NHRP Traffic Indication Probe&amp;quot;,&lt;br /&gt;
&lt;br /&gt;
  &amp;quot;log&amp;quot;: {&lt;br /&gt;
    &amp;quot;dmvpn&amp;quot;: {&lt;br /&gt;
       &amp;quot;mode&amp;quot;: &amp;quot;nflog&amp;quot;,&lt;br /&gt;
       &amp;quot;group&amp;quot;: 1,&lt;br /&gt;
       &amp;quot;range&amp;quot;: 128,&lt;br /&gt;
       &amp;quot;limit&amp;quot;: {&lt;br /&gt;
          &amp;quot;count&amp;quot;: 6,&lt;br /&gt;
          &amp;quot;interval&amp;quot;: 60,&lt;br /&gt;
          &amp;quot;mask&amp;quot;: {&lt;br /&gt;
             &amp;quot;inet&amp;quot;: { &amp;quot;src&amp;quot;: 16, &amp;quot;dest&amp;quot;: 16 },&lt;br /&gt;
             &amp;quot;inet6&amp;quot;: { &amp;quot;src&amp;quot;: 48, &amp;quot;dest&amp;quot;: 48 }&lt;br /&gt;
          }&lt;br /&gt;
       }&lt;br /&gt;
    }&lt;br /&gt;
  },&lt;br /&gt;
&lt;br /&gt;
  &amp;quot;packet-log&amp;quot;: [ { &amp;quot;in&amp;quot;: &amp;quot;DMVPN&amp;quot;, &amp;quot;out&amp;quot;: &amp;quot;DMVPN&amp;quot;, &amp;quot;log&amp;quot;: &amp;quot;dmvpn&amp;quot; } ]&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/nowiki&amp;gt;}}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Enable awall rules:&lt;br /&gt;
&lt;br /&gt;
{{Cmd|awall enable zones&lt;br /&gt;
awall enable inet&lt;br /&gt;
awall enable dmvpn&lt;br /&gt;
awall enable vpnredirect&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
Apply awall rules:&lt;br /&gt;
&lt;br /&gt;
{{Cmd|awall activate -f &lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
== IPSEC ==&lt;br /&gt;
Install package(s):&lt;br /&gt;
&lt;br /&gt;
{{Cmd|apk add strongswan&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
{{cat|/etc/swanctl/swanctl.conf|&amp;lt;nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
connections {&lt;br /&gt;
        dmvpn {&lt;br /&gt;
                version = 2&lt;br /&gt;
                pull = no&lt;br /&gt;
                mobike = no&lt;br /&gt;
                dpd_delay = 15&lt;br /&gt;
                dpd_timeout = 30&lt;br /&gt;
                fragmentation = yes&lt;br /&gt;
                unique = replace&lt;br /&gt;
                rekey_time = 4h&lt;br /&gt;
                reauth_time = 13h&lt;br /&gt;
                proposals = aes256-sha512-ecp384&lt;br /&gt;
                local {&lt;br /&gt;
                        auth = psk&lt;br /&gt;
                        id = hub&lt;br /&gt;
                }&lt;br /&gt;
                remote {&lt;br /&gt;
                        auth = psk&lt;br /&gt;
                }&lt;br /&gt;
                children {&lt;br /&gt;
                        dmvpn {&lt;br /&gt;
                                esp_proposals = aes256-sha512-ecp384&lt;br /&gt;
                                local_ts = dynamic[gre]&lt;br /&gt;
                                remote_ts = dynamic[gre]&lt;br /&gt;
                                inactivity = 90m&lt;br /&gt;
                                rekey_time = 100m&lt;br /&gt;
                                mode = transport&lt;br /&gt;
                                dpd_action = clear&lt;br /&gt;
                                reqid = 1&lt;br /&gt;
                        }&lt;br /&gt;
                }&lt;br /&gt;
        }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/nowiki&amp;gt;}}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
{{cat|/etc/ipsec.secrets|&lt;br /&gt;
# /etc/ipsec.secrets - strongSwan IPsec secrets file&lt;br /&gt;
&lt;br /&gt;
%any : PSK &amp;quot;cisco12345678987654321&amp;quot;&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
Start service(s):&lt;br /&gt;
&lt;br /&gt;
{{Cmd|/etc/init.d/charon start&lt;br /&gt;
rc-update add charon}}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Now, test if it works.&lt;br /&gt;
In this example, spoke 1 tries to connect to spoke 3, who announces his subnet 192.168.30.0/24 via iBGP, the gre1 address is 172.16.3.1 and the public ip address is 90.100.150.200.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
The first traffic goes from through the HUB.&lt;br /&gt;
&lt;br /&gt;
{{Cmd|spoke1:~/root# traceroute -n 192.168.30.1&lt;br /&gt;
traceroute to 192.168.30.1 (192.168.30.1), 30 hops max, 38 byte packets&lt;br /&gt;
 1  172.16.0.1  0.664 ms  0.461 ms  0.457 ms&lt;br /&gt;
 2  192.168.30.1  0.907 ms  0.776 ms  0.771 ms&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
Then, once the VPN is created, the traffic goes directly to the spoke node.&lt;br /&gt;
 &lt;br /&gt;
{{Cmd|spoke1:~/root# traceroute -n 192.168.30.1&lt;br /&gt;
traceroute to 192.168.30.1 (192.168.30.1), 30 hops max, 38 byte packets&lt;br /&gt;
 1  192.168.30.1  0.456 ms  0.385 ms  0.357 ms&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
With &amp;lt;code&amp;gt;ipsec --status-all&amp;lt;/code&amp;gt; you can see alle the VPNs created:&lt;br /&gt;
&lt;br /&gt;
{{Cmd|spoke1:~/root# ipsec statusall&amp;lt;nowiki&amp;gt;&lt;br /&gt;
Status of IKE charon daemon (strongSwan 5.3.2, Linux 3.18.20-1-grsec, i686):&lt;br /&gt;
  uptime: 9 days, since Aug 28 14:22:27 2015&lt;br /&gt;
  worker threads: 11 of 16 idle, 5/0/0/0 working, job queue: 0/0/0/0, scheduled: 28&lt;br /&gt;
  loaded plugins: charon random nonce x509 revocation constraints pubkey pkcs1 pkcs7 pkcs8 pkcs12 pgp dnskey sshkey pem openssl fips-prf gmp xcbc cmac curl sqlite attr kernel-netlink resolve socket-default farp stroke vici updown eap-identity eap-sim eap-aka eap-aka-3gpp2 eap-simaka-pseudonym eap-simaka-reauth eap-md5 eap-mschapv2 eap-radius eap-tls xauth-generic xauth-eap dhcp unity&lt;br /&gt;
Listening IP addresses:&lt;br /&gt;
  192.168.10.1&lt;br /&gt;
  172.17.50.1&lt;br /&gt;
  172.16.1.1&lt;br /&gt;
Connections:&lt;br /&gt;
       dmvpn:  %any...%any  IKEv2, dpddelay=15s&lt;br /&gt;
       dmvpn:   local:  [spoke1] uses pre-shared key authentication&lt;br /&gt;
       dmvpn:   remote: uses pre-shared key authentication&lt;br /&gt;
       dmvpn:   child:  dynamic[gre] === dynamic[gre] TRANSPORT, dpdaction=clear&lt;br /&gt;
Security Associations (3 up, 0 connecting):&lt;br /&gt;
       dmvpn[121]: ESTABLISHED 4 seconds ago, 172.17.50.1[spoke1]...90.100.150.200[spoke3]&lt;br /&gt;
       dmvpn[121]: IKEv2 SPIs: c770729967ea636c_i 0de8ffedbe32f21c_r*, rekeying in 3 hours, pre-shared key reauthentication in 12 hours&lt;br /&gt;
       dmvpn[121]: IKE proposal: AES_CBC_256/HMAC_SHA2_512_256/PRF_HMAC_SHA2_512/ECP_384&lt;br /&gt;
       dmvpn{187}:  INSTALLED, TRANSPORT, reqid 1, ESP in UDP SPIs: c132e6c3_i c49ae122_o&lt;br /&gt;
       dmvpn{187}:  AES_CBC_256/HMAC_SHA2_512_256, 469 bytes_i (6 pkts, 2s ago), 326 bytes_o (6 pkts, 2s ago), rekeying in 90 minutes&lt;br /&gt;
       dmvpn{187}:   172.17.50.1/32[gre] === 90.100.150.200/32[gre] &lt;br /&gt;
       dmvpn[120]: ESTABLISHED 8 seconds ago, 172.17.50.1[spoke1]...90.100.150.200[spoke3]&lt;br /&gt;
       dmvpn[120]: IKEv2 SPIs: 46f81c8ec9a4b753_i* f768298b31ebe4da_r, rekeying in 3 hours, pre-shared key reauthentication in 11 hours&lt;br /&gt;
       dmvpn[120]: IKE proposal: AES_CBC_256/HMAC_SHA2_512_256/PRF_HMAC_SHA2_512/ECP_384&lt;br /&gt;
       dmvpn{186}:  INSTALLED, TRANSPORT, reqid 1, ESP in UDP SPIs: cad2c1c9_i cd5a287c_o&lt;br /&gt;
       dmvpn{186}:  AES_CBC_256/HMAC_SHA2_512_256, 74 bytes_i (1 pkt, 2s ago), 46 bytes_o (1 pkt, 2s ago), rekeying in 91 minutes&lt;br /&gt;
       dmvpn{186}:   172.17.50.1/32[gre] === 90.100.150.200/32[gre] &lt;br /&gt;
       dmvpn[119]: ESTABLISHED 2 hours ago, 172.17.50.1[spoke1]...50.60.70.80[hub]&lt;br /&gt;
       dmvpn[119]: IKEv2 SPIs: 0e999ad802ced9cc_i* 6eaa469463601437_r, rekeying in 84 minutes, pre-shared key reauthentication in 8 hours&lt;br /&gt;
       dmvpn[119]: IKE proposal: AES_CBC_256/HMAC_SHA2_512_256/PRF_HMAC_SHA2_512/ECP_384&lt;br /&gt;
       dmvpn{185}:  INSTALLED, TRANSPORT, reqid 1, ESP in UDP SPIs: c84d6035_i cb72cd30_o&lt;br /&gt;
       dmvpn{185}:  AES_CBC_256/HMAC_SHA2_512_256, 35764 bytes_i (473 pkts, 0s ago), 38266 bytes_o (384 pkts, 0s ago), rekeying in 46 minutes&lt;br /&gt;
       dmvpn{185}:   172.17.50.1/32[gre] === 50.60.70.80/32[gre] &lt;br /&gt;
&amp;lt;/nowiki&amp;gt;}}&lt;br /&gt;
&lt;br /&gt;
= See also =&lt;br /&gt;
* [[Dynamic Multipoint VPN (DMVPN)]]&lt;br /&gt;
* [[Setup of DMVPN on Alpine linux]]&lt;br /&gt;
&lt;br /&gt;
[[category: VPN]]&lt;/div&gt;</summary>
		<author><name>Nangel</name></author>
	</entry>
	<entry>
		<id>https://wiki.alpinelinux.org/w/index.php?title=Tutorials_and_Howtos&amp;diff=23534</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=23534"/>
		<updated>2023-05-28T16:01:00Z</updated>

		<summary type="html">&lt;p&gt;Nangel: /* HTTP */  Delete Reference to Cherokee&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Todo|This material has been re-organized..., but grouping should be checked: &#039;&#039;&#039;Howtos are smaller articles&#039;&#039;&#039; and &#039;&#039;&#039;tutorials are more detailed document&#039;&#039;&#039;}}&lt;br /&gt;
&lt;br /&gt;
[[Image:package_edutainment.svg|right|link=]]&lt;br /&gt;
{{TOC left}}&lt;br /&gt;
&#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;
&lt;br /&gt;
&#039;&#039;&#039;The tutorials are hands-on&#039;&#039;&#039; and the reader is expected to try and achieve the goals described in each step, possibly with the help of a good example. The output in one step is the starting point for the following step.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Howtos are smaller articles&#039;&#039;&#039; explaining how to perform a particular task with Alpine Linux, that expects a minimal knowledge from reader to perform actions.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;IMPORTANT:&#039;&#039;&#039; contributions on those pages must be complete articles as well as requesting topics to be covered, don&#039;t override already made contributions. If you want to request a topic, please add your request in this page&#039;s [[Talk:Tutorials_and_Howtos|Discussion]].&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
{{Clear}}&lt;br /&gt;
&lt;br /&gt;
= Howtos =&lt;br /&gt;
&lt;br /&gt;
== Applications ==&lt;br /&gt;
&lt;br /&gt;
=== Miscellaneous ===&lt;br /&gt;
&lt;br /&gt;
* [[Ansible]] &#039;&#039;(Configuration management)&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
=== Monitoring ===&lt;br /&gt;
&lt;br /&gt;
* [[Awstats]] &#039;&#039;(Free log file analyzer)&#039;&#039;&lt;br /&gt;
* [[Cacti: traffic analysis and monitoring network]] &#039;&#039;(Front-end for rrdtool networking monitor)&#039;&#039;&lt;br /&gt;
* [[Cvechecker]] &#039;&#039;(Compare installed packages for Common Vulnerabilities Exposure)&#039;&#039; &amp;lt;!-- Monitoring and Security --&amp;gt;&lt;br /&gt;
* [[Dglog]] &#039;&#039;(Log analyzer for the web content filter DansGuardian)&#039;&#039;&lt;br /&gt;
* [[Linfo]]&lt;br /&gt;
* [[Obtaining user information via SNMP]] &#039;&#039;(Using squark-auth-snmp as a Squid authentication helper)&#039;&#039; &amp;lt;!-- Networking and Server, &amp;lt;== Using squark-auth-snmp --&amp;gt;&lt;br /&gt;
* [[PhpSysInfo]] &#039;&#039;(A simple application that displays information about the host it&#039;s running on)&#039;&#039;&lt;br /&gt;
* [[Piwik]] &#039;&#039;(A real time web analytics software program)&#039;&#039;&lt;br /&gt;
* [[Setting up A Network Monitoring and Inventory System]] &#039;&#039;(Nagios + OpenAudit and related components)&#039;&#039; &amp;lt;!-- draft, solution, Networking and Monitoring and Server --&amp;gt;&lt;br /&gt;
** [[Setting up NRPE daemon]] &#039;&#039;(Performs remote Nagios checks)&#039;&#039; &amp;lt;!-- Networking and Monitoring --&amp;gt;&lt;br /&gt;
* [[Setting Up Fprobe And Ntop|Ntop]] &#039;&#039;(NetFlow collection and analysis using a remote fprobe instance)&#039;&#039; &amp;lt;!-- Networking and Monitoring --&amp;gt;&lt;br /&gt;
* [[Setting up lm_sensors]]&lt;br /&gt;
* [[SqStat]] &#039;&#039;(Script to look at active squid users connections)&#039;&#039;&lt;br /&gt;
* [[Traffic monitoring]] &amp;lt;!-- Networking and Monitoring --&amp;gt;&lt;br /&gt;
** [[Setting up monitoring using rrdtool (and rrdcollect)]]&lt;br /&gt;
** [[Setting up traffic monitoring using rrdtool (and snmp)]] &amp;lt;!-- Monitoring --&amp;gt;&lt;br /&gt;
* [[Zabbix|Zabbix - the professional complete manager]] &#039;&#039;(Monitor and track the status of network services and hardware)&#039;&#039;&lt;br /&gt;
* [[ZoneMinder video camera security and surveillance]]&lt;br /&gt;
&lt;br /&gt;
=== Networking ===&lt;br /&gt;
&lt;br /&gt;
* Alpine Wall &#039;&#039;(a new firewall management framework)&#039;&#039;&lt;br /&gt;
** [[Alpine Wall]]&lt;br /&gt;
** [[Alpine Wall User&#039;s Guide]] &lt;br /&gt;
** [[How-To Alpine Wall]]&lt;br /&gt;
* [[Freeradius Active Directory Integration]]&lt;br /&gt;
* [[GNUnet]]&lt;br /&gt;
* [[Setting up a OpenVPN server|OpenVPN server]] &#039;&#039;(Allowing single users or devices to remotely connect to your network)&#039;&#039;&lt;br /&gt;
* [[OpenVSwitch]]&lt;br /&gt;
* [[Using Alpine on Windows domain with IPSEC isolation]]&lt;br /&gt;
* [[Configure a Wireguard interface (wg)|Wireguard]]&lt;br /&gt;
&lt;br /&gt;
=== Telephony ===&lt;br /&gt;
&lt;br /&gt;
* [[Freepbx on Alpine Linux]]&lt;br /&gt;
* [[FreePBX V3]] &#039;&#039;(FreeSWITCH, Asterisk GUI web acces tool)&#039;&#039;&lt;br /&gt;
* [[Sending SMS using gnokii]]&lt;br /&gt;
* [[Setting up Zaptel/Asterisk on Alpine]]&lt;br /&gt;
* [[Kamailio]] &#039;&#039;(SIP Server, formerly OpenSER)&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
== Backup and data migration ==&lt;br /&gt;
&lt;br /&gt;
* [[Alpine local backup|Alpine local backup (lbu)]] &#039;&#039;(Permanently store your modifications in case your box needs reboot)&#039;&#039;&lt;br /&gt;
** [[Back Up a Flash Memory Installation]]&lt;br /&gt;
** [[Manually editing a existing apkovl]]&lt;br /&gt;
* [[Migrating data]]&lt;br /&gt;
* [[Rsnapshot]] - setting up periodic backups&lt;br /&gt;
&lt;br /&gt;
== Desktop ==&lt;br /&gt;
&lt;br /&gt;
* [[Alpine and UEFI]]&lt;br /&gt;
* [[Default applications]]&lt;br /&gt;
* Desktop cloud&lt;br /&gt;
** [[EyeOS]] &#039;&#039;(Cloud Computing Desktop)&#039;&#039;&lt;br /&gt;
** [[Nextcloud]] &#039;&#039;(Self hostable cloud suite - Dropbox Alternative)&#039;&#039;&lt;br /&gt;
** [[Oneye]] &#039;&#039;(Cloud Computing Desktop - Dropbox Alternative)&#039;&#039;&lt;br /&gt;
** [[OwnCloud]] &#039;&#039;(Installing OwnCloud)&#039;&#039;&lt;br /&gt;
** [[Seafile: setting up your own private cloud]]&lt;br /&gt;
* [[Desktop environments and Window managers]] (overall information only)&lt;br /&gt;
* [[Printer Setup]]&lt;br /&gt;
* [[Remote Desktop Server]]&lt;br /&gt;
* [[Sound Setup]]&lt;br /&gt;
** [[PipeWire]]&lt;br /&gt;
* [[Suspend on LID close]]&lt;br /&gt;
* [[Alpine setup scripts#setup-xorg-base|Xorg Setup]]&lt;br /&gt;
&lt;br /&gt;
== Networking ==&lt;br /&gt;
&lt;br /&gt;
* [[Bluetooth]] - Instructions for installing and configuring Bluetooth&lt;br /&gt;
* [[Bonding]] - Bond (or aggregate) multiple ethernet interfaces&lt;br /&gt;
* [[Bridge]] - Configuring a network bridge&lt;br /&gt;
** [[Bridge wlan0 to eth0]]&lt;br /&gt;
* [[Configure Networking]]&lt;br /&gt;
* [[How to configure static routes]]&lt;br /&gt;
* Modem&lt;br /&gt;
** [[Using HSDPA modem]]&lt;br /&gt;
** [[Using serial modem]]&lt;br /&gt;
* [[Multi ISP]] &#039;&#039;(Dual-ISP setup with load-balancing and automatic failover)&#039;&#039;&lt;br /&gt;
* [[PXE boot]]&lt;br /&gt;
* [[Setting up Satellite Internet Connection|Satellite Internet Connection setup]]&lt;br /&gt;
* Wi-Fi&lt;br /&gt;
** [[Wi-Fi|Connecting to a wireless access point]]&lt;br /&gt;
** [[How to setup a wireless access point]] &#039;&#039;(Setting up Secure Wireless AP w/ WPA encryption with bridge to wired network)&#039;&#039;&lt;br /&gt;
* [[Vlan]]&lt;br /&gt;
&lt;br /&gt;
== Other Architectures ==&lt;br /&gt;
&lt;br /&gt;
=== ARM ===&lt;br /&gt;
&lt;br /&gt;
* [[Alpine on ARM]]&lt;br /&gt;
&lt;br /&gt;
==== Raspberry Pi ====&lt;br /&gt;
&lt;br /&gt;
* [[Raspberry Pi Bluetooth Speaker|Raspberry Pi - Bluetooth Speaker]]&lt;br /&gt;
* [[Raspberry Pi|Raspberry Pi - Installation]]&lt;br /&gt;
* [[Linux Router with VPN on a Raspberry Pi|Raspberry Pi - Router with VPN]]&lt;br /&gt;
* [[Linux Router with VPN on a Raspberry Pi (IPv6)|Raspberry Pi - Router with VPN (IPv6)]]&lt;br /&gt;
* [[Classic install or sys mode on Raspberry Pi|Raspberry Pi - Sys mode install]]&lt;br /&gt;
* [[RPI Video Receiver|Raspberry Pi - Video Receiver]] &#039;&#039;(network video decoder using Rasperry Pi and omxplayer)&#039;&#039;&lt;br /&gt;
* [[Raspberry Pi 3 - Browser Client]] - kiosk or digital sign&lt;br /&gt;
* [[Raspberry Pi 3 - Configuring it as wireless access point -AP Mode]]&lt;br /&gt;
* [[Raspberry Pi 3 - Setting Up Bluetooth]]&lt;br /&gt;
* [[Raspberry Pi 4 - Persistent system acting as a NAS and Time Machine]]&lt;br /&gt;
* [[How to set up Alpine as a wireless router|Raspberry Pi Zero W - Wireless router]] &#039;&#039;(Setting up a firewalled, Wireless AP with wired network on a Pi Zero W)&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
=== IBM Z (IBM z Systems) ===&lt;br /&gt;
&lt;br /&gt;
* [[s390x|s390x - Installation]]&lt;br /&gt;
&lt;br /&gt;
=== PowerPC ===&lt;br /&gt;
&lt;br /&gt;
* [[Ppc64le|Powerpc64le - Installation]]&lt;br /&gt;
&lt;br /&gt;
== Post-Install ==&lt;br /&gt;
&lt;br /&gt;
* [[CPU frequency scaling]]&lt;br /&gt;
* [[Repositories#Enabling_the_community_repository|Enable Community repository]] &#039;&#039;(Providing additional packages)&#039;&#039;&lt;br /&gt;
* [[Enable Serial Console on Boot]]&lt;br /&gt;
* [[Alpine Linux Init System|Init System (OpenRC)]] &#039;&#039;(Configure a service to automatically boot at next reboot)&#039;&#039;&lt;br /&gt;
** [[Multiple Instances of Services|Init System - Multiple Instances of Services]]&lt;br /&gt;
** [[Writing Init Scripts|Init System - Writing Init Scripts]]&lt;br /&gt;
* [[Installing Oracle Java|Oracle Java (installation)]]&lt;br /&gt;
* [[IPTV How To|Internet Protocol television (IPTV)]]&lt;br /&gt;
* [[Alpine Linux package management|Package Management (apk)]] &#039;&#039;(How to add/remove packages on your Alpine)&#039;&#039;&lt;br /&gt;
** [[Comparison with other distros|Package Management - Comparison with other distros]]&lt;br /&gt;
* [[Running glibc programs]]&lt;br /&gt;
* [[Setting up a new user]]&lt;br /&gt;
* [[Upgrading Alpine]]&lt;br /&gt;
&lt;br /&gt;
== Remote Administration ==&lt;br /&gt;
&lt;br /&gt;
* ACF&lt;br /&gt;
** [[Changing passwords for ACF|ACF - changing passwords]]&lt;br /&gt;
** [[Generating SSL certs with ACF]] &amp;lt;!-- Generating SSL certs with ACF 1.9 --&amp;gt;&lt;br /&gt;
** [[setup-acf| ACF - setup]] &#039;&#039;(Configures ACF (webconfiguration/webmin) so you can manage your box through https)&#039;&#039;&lt;br /&gt;
* [[Setting up a SSH server]] &#039;&#039;(Using ssh is a good way to administer your box remotely)&#039;&#039;&lt;br /&gt;
** [[HOWTO OpenSSH 2FA with password and Google Authenticator |OpenSSH 2FA]] &#039;&#039;(A simple two factor setup for OpenSSH)&#039;&#039;&lt;br /&gt;
* [[OpenVCP]] &#039;&#039;(VServer Control Panel)&#039;&#039;&lt;br /&gt;
* [[PhpMyAdmin]] &#039;&#039;(Web-based administration tool for MYSQL)&#039;&#039;&lt;br /&gt;
* [[PhpPgAdmin]] &#039;&#039;(Web-based administration tool for PostgreSQL)&#039;&#039;&lt;br /&gt;
* [[Webmin]] &#039;&#039;(A web-based interface for Linux system)&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
== Server ==&lt;br /&gt;
&lt;br /&gt;
* [[Hosting services on Alpine]] &#039;&#039;(Hosting mail, webservices and other services)&#039;&#039;&lt;br /&gt;
* [[Hosting Web/Email services on Alpine]]&lt;br /&gt;
&lt;br /&gt;
=== DNS ===&lt;br /&gt;
&lt;br /&gt;
* [[DNSCrypt-Proxy]] &#039;&#039;Encrypt and authenticate DNS calls from your system&#039;&#039;&lt;br /&gt;
* [[Setting up nsd DNS server]]&lt;br /&gt;
* [[Setting up unbound DNS server]]&lt;br /&gt;
* [[TinyDNS Format]]&lt;br /&gt;
&lt;br /&gt;
=== HTTP ===&lt;br /&gt;
&lt;br /&gt;
* [[Apache]]&lt;br /&gt;
** [[Apache with php-fpm]]&lt;br /&gt;
** [[Setting Up Apache with PHP]]&lt;br /&gt;
** [[Apache authentication: NTLM Single Signon]]&lt;br /&gt;
* [[Darkhttpd]]&lt;br /&gt;
* [[Lighttpd]]&lt;br /&gt;
** [[Lighttpd Advanced security]]&lt;br /&gt;
** [[Setting Up Lighttpd With FastCGI]]&lt;br /&gt;
* [[Nginx]]&lt;br /&gt;
** [[Nginx as reverse proxy with acme (letsencrypt)]]&lt;br /&gt;
** [[Nginx with PHP]]&lt;br /&gt;
* Squid Proxy&lt;br /&gt;
** [[Obtaining user information via SNMP]] &#039;&#039;(Using squark-auth-snmp as a Squid authentication helper)&#039;&#039; &amp;lt;!-- Networking and Server, &amp;lt;== Using squark-auth-snmp --&amp;gt;&lt;br /&gt;
** [[Setting up Explicit Squid Proxy]]&lt;br /&gt;
** [[Setting up Transparent Squid Proxy]] &#039;&#039;(Covers Squid proxy and URL Filtering system)&#039;&#039;&lt;br /&gt;
** [[SqStat]] &#039;&#039;(Script to look at active squid users connections)&#039;&#039;&lt;br /&gt;
* [[Tomcat]]&lt;br /&gt;
&lt;br /&gt;
==== Hostable Content ====&lt;br /&gt;
&lt;br /&gt;
* [[DokuWiki]]&lt;br /&gt;
* [[Drupal]] &#039;&#039;(Content Management System (CMS) written in PHP)&#039;&#039;&lt;br /&gt;
* [[Kopano]] &#039;&#039;(Microsoft Outlook compatible Groupware)&#039;&#039;&lt;br /&gt;
* [[Mahara]] &#039;&#039;(E-portfolio and social networking system)&#039;&#039;&lt;br /&gt;
* [[MediaWiki]] &#039;&#039;(Free web-based wiki software application)&#039;&#039;&lt;br /&gt;
* [[Pastebin]] &#039;&#039;(Pastebin software application)&#039;&#039;&lt;br /&gt;
* [[Phpizabi]] &#039;&#039;(Social Networking Platform)&#039;&#039;&lt;br /&gt;
* [[Statusnet]] &#039;&#039;(Microblogging Platform)&#039;&#039;&lt;br /&gt;
* [[WordPress]] &#039;&#039;(Web software to create website or blog)&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
=== IRC ===&lt;br /&gt;
&lt;br /&gt;
* [[How To Setup Your Own IRC Network]] &#039;&#039;(Using {{Pkg|charybdis}} and {{Pkg|atheme-iris}})&#039;&#039;&lt;br /&gt;
* [[NgIRCd]] &#039;&#039;(Server for Internet Relay Chat/IRC)&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
=== Mail ===&lt;br /&gt;
&lt;br /&gt;
* Exim/Dovecot&lt;br /&gt;
** [[Small-Time Email with Exim and Dovecot]] &#039;&#039;(A simple configuration for your home network.)&lt;br /&gt;
** [[Setting up dovecot with imap and ssl]]&lt;br /&gt;
* [[relay email to gmail (msmtp, mailx, sendmail]]&lt;br /&gt;
* [[Roundcube]] &#039;&#039;(Webmail system)&#039;&#039;&lt;br /&gt;
* [[Setting up postfix with virtual domains]]&lt;br /&gt;
* Server protection&lt;br /&gt;
** [[Protecting your email server with Alpine]]&lt;br /&gt;
** [[Setting up clamsmtp]]&lt;br /&gt;
&lt;br /&gt;
=== Other Servers ===&lt;br /&gt;
&lt;br /&gt;
* [[Chrony and GPSD | Chrony, gpsd, and a garmin LVC 18 as a Stratum 1 NTP source ]]&lt;br /&gt;
* [[Glpi]] &#039;&#039;(Manage inventory of technical resources)&#039;&#039;&lt;br /&gt;
* [[How to setup a Alpine Linux mirror]]&lt;br /&gt;
* [[Setting up a nfs-server|nfs-server]]&lt;br /&gt;
* [[Odoo]]&lt;br /&gt;
* [[Configure OpenLDAP | OpenLDAP]] &#039;&#039;(Installing and configuring the Alpine package for OpenLDAP)&#039;&#039;&lt;br /&gt;
* [[Setting up a samba-ad-dc|samba-ad-dc]] &#039;&#039;(Active Directory compatible domain controller)&#039;&#039;&lt;br /&gt;
* [[Setting up a samba-server|samba-server]] &#039;&#039;(standard file sharing)&#039;&#039;&lt;br /&gt;
* [[Setting up Transmission (bittorrent) with Clutch WebUI]]&lt;br /&gt;
* [[UniFi Controller]]&lt;br /&gt;
&lt;br /&gt;
=== Software development ===&lt;br /&gt;
&lt;br /&gt;
* [[Cgit]]&lt;br /&gt;
* [[OsTicket]] &#039;&#039;(Ticket system)&#039;&#039;&lt;br /&gt;
* [[Patchwork]] &#039;&#039;(Patch review management system)&#039;&#039;&lt;br /&gt;
* [[Redmine]] &#039;&#039;(Project management system)&#039;&#039;&lt;br /&gt;
* [[Request Tracker]] &#039;&#039;(Ticket system)&#039;&#039;&lt;br /&gt;
* [[Setting up trac wiki|Trac]] &#039;&#039;(Enhanced wiki and issue tracking system for software development projects)&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
== Storage ==&lt;br /&gt;
&lt;br /&gt;
* [[Setting up disks manually|Disk setup (manual)]]&lt;br /&gt;
* [[Disk Replication with DRBD|DRBD: Disk Replication]]&lt;br /&gt;
* [[Filesystems]]&lt;br /&gt;
** [[Burning ISOs]]&lt;br /&gt;
* [[Setting up iSCSI|iSCSI Setup]]&lt;br /&gt;
** [[iSCSI Raid and Clustered File Systems]]&lt;br /&gt;
** [[Linux iSCSI Target (TCM)|iSCSI Target (TCM)/LinuxIO (LIO)]]&lt;br /&gt;
* [[Setting up Logical Volumes with LVM|LVM Setup]]&lt;br /&gt;
** [[Setting up LVM on GPT-labeled disks|LVM on GPT-labeled disks]]&lt;br /&gt;
** [[Installing on GPT LVM|LVM on GPT-labeled disks (updated)]]&lt;br /&gt;
** [[LVM on LUKS]]&lt;br /&gt;
* RAID&lt;br /&gt;
** [[Raid Administration]]&lt;br /&gt;
** [[Setting up a software RAID array]]&lt;br /&gt;
* ZFS&lt;br /&gt;
** [[Root on ZFS with native encryption]]&lt;br /&gt;
** [[Setting up ZFS on LUKS]]&lt;br /&gt;
** [[Setting up ZFS with native encryption]]&lt;br /&gt;
&lt;br /&gt;
== Virtualization ==&lt;br /&gt;
&lt;br /&gt;
* [[Docker]]&lt;br /&gt;
* [[Installing Alpine in a virtual machine]]&lt;br /&gt;
** [[Install Alpine on VMware ESXi]]&lt;br /&gt;
* [[KVM]] &#039;&#039;(Setting up Alpine as a KVM hypervisor)&#039;&#039;&lt;br /&gt;
* [[LXC]] &#039;&#039;(Setting up a Linux container in Alpine Linux)&#039;&#039;&lt;br /&gt;
* [[QEMU]]&lt;br /&gt;
* Xen&lt;br /&gt;
** [[Xen Dom0]] &#039;&#039;(Setting up Alpine as a dom0 for Xen hypervisor)&#039;&#039;&lt;br /&gt;
** [[Xen Dom0 on USB or SD]]&lt;br /&gt;
** [[Create Alpine Linux PV DomU|Xen DomU (paravirtualized)]]&lt;br /&gt;
** [[Xen LiveCD]]&lt;br /&gt;
** [[Xen PCI Passthrough]]&lt;br /&gt;
&lt;br /&gt;
= Tutorials =&lt;br /&gt;
&lt;br /&gt;
== Miscellaneous ==&lt;br /&gt;
&lt;br /&gt;
* [[Dynamic Multipoint VPN (DMVPN)]] combined with [[Small Office Services]]&lt;br /&gt;
* [[DIY Fully working Alpine Linux for Allwinner and Other ARM SOCs]]&lt;br /&gt;
* [[Experiences with OpenVPN-client on ALIX.2D3]]&lt;br /&gt;
* [[Fault Tolerant Routing with Alpine Linux]]&lt;br /&gt;
* [[High Availability High Performance Web Cache]] &#039;&#039;(uCarp + HAProxy for High Availability Services such as Squid web proxy)&#039;&#039;&lt;br /&gt;
* [[High performance SCST iSCSI Target on Linux software Raid]]&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;
** [[ISP Mail Server Upgrade 2.x]]&lt;br /&gt;
** [[ISP Mail Server 2.x HowTo]] &#039;&#039;(Beta, please test)&#039;&#039;&lt;br /&gt;
** [[ISP Mail Server 3.x HowTo]]&lt;br /&gt;
* [[Replacing non-Alpine Linux with Alpine remotely]]&lt;br /&gt;
* [[Setting up A Network Monitoring and Inventory System]] &#039;&#039;(Nagios + OpenAudit and related components)&#039;&#039; &amp;lt;!-- draft --&amp;gt;&lt;br /&gt;
* [[Streaming Security Camera Video with VLC]]&lt;br /&gt;
&lt;br /&gt;
== Newbie corner ==&lt;br /&gt;
&lt;br /&gt;
* [[How to get regular stuff working]] &#039;&#039;some notes on need-to-know topics&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
== Servers ==&lt;br /&gt;
&lt;br /&gt;
* [[Alpine production deploy]]&lt;br /&gt;
** [[Production Web server: Lighttpd|Production web server: Lighttpd‎‎]]&lt;br /&gt;
** [[Production DataBases : mysql|Production database: MySql]]&lt;br /&gt;
** [[Production LAMP system: Lighttpd + PHP + MySQL‎‎]]&lt;br /&gt;
* Alpine production monitoring&lt;br /&gt;
** [[Cacti: traffic analysis and monitoring network]]&lt;br /&gt;
** [[Zabbix|Zabbix - the professional complete manager]]&lt;br /&gt;
* Kubernetes&lt;br /&gt;
** [[K8s]] Building a K8s Cluster on Alpine Linux&lt;/div&gt;</summary>
		<author><name>Nangel</name></author>
	</entry>
	<entry>
		<id>https://wiki.alpinelinux.org/w/index.php?title=Hosting_services_on_Alpine&amp;diff=23533</id>
		<title>Hosting services on Alpine</title>
		<link rel="alternate" type="text/html" href="https://wiki.alpinelinux.org/w/index.php?title=Hosting_services_on_Alpine&amp;diff=23533"/>
		<updated>2023-05-28T16:00:34Z</updated>

		<summary type="html">&lt;p&gt;Nangel: /* Web */  Delete reference to Cherokee&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= Introduction =&lt;br /&gt;
Alpine is well suited for hosting email-, web- or other network-related services.&amp;lt;BR&amp;gt;&lt;br /&gt;
Your biggest task is to figure out what you want your system to do.&lt;br /&gt;
&lt;br /&gt;
== Preparing Alpine ==&lt;br /&gt;
First you need to get alpine up and running.&amp;lt;BR&amp;gt;&lt;br /&gt;
Follow the [[Installation]] instructions on how to get your Alpine booted.&lt;br /&gt;
&lt;br /&gt;
If nothing else is mentioned in the below instructions, you should use the latest stable release:{{downloads|alpine}}&lt;br /&gt;
&lt;br /&gt;
=== VServer or not ===&lt;br /&gt;
VServer itself has nothing to do with the various services.&amp;lt;BR&amp;gt;&lt;br /&gt;
But if you intend to run multiple services on same box (e.g. mail and webhosting) it might be wise to run the various services in separate vserver-guests.&lt;br /&gt;
&lt;br /&gt;
* [[Setting up a basic vserver]] | &#039;&#039;Basic information on how to set up vserver hosts/guests&#039;&#039;&lt;br /&gt;
{{warning| the package &#039;&#039;&#039;util-vserver&#039;&#039;&#039; is currently unavailable since, at least, Alpine Linux 3.3. }}&lt;br /&gt;
&lt;br /&gt;
== Mail ==&lt;br /&gt;
We split the &#039;Mail&#039; section into various tasks.&amp;lt;BR&amp;gt;&lt;br /&gt;
One task is to gather and process mail. Some other task would be to prevent spam and virus etc.&amp;lt;BR&amp;gt;&lt;br /&gt;
Finally we need to make sure the user can fetch/read his mail.&lt;br /&gt;
&lt;br /&gt;
=== Receive mail ===&lt;br /&gt;
&lt;br /&gt;
* [[Setting up postfix with virtual domains]] | &#039;&#039;Postfix can be configured in multiple ways - Here we do it with virtual domains&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
=== Processing mail - Virus protection ===&lt;br /&gt;
&lt;br /&gt;
* [[Protecting_your_email_server_with_Alpine#Setting_up_the_Virus_scanner|Setting up ClamAV for Postfix]] | &#039;&#039;Referrers to [[Setting_up_postfix_with_virtual_domains]] instructions&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
=== Processing mail - Spam protection ===&lt;br /&gt;
&lt;br /&gt;
* [[Protecting_your_email_server_with_Alpine#Setting_up_the_Greylisting_Server|Setting up Gross for Postfix]] | &#039;&#039;Referrers to [[Setting_up_postfix_with_virtual_domains]] instructions&#039;&#039;&lt;br /&gt;
* [[Protecting_your_email_server_with_Alpine#Setting_up_the_SMTP_filter|Setting up ClamSMTP]] | &#039;&#039;Use ClamSMTP to provide advanced content and virus filtering for spam&#039;&#039;&lt;br /&gt;
* [[Protecting_your_email_server_with_Alpine#Setting_up_SaneSecurity_.26_MSRBL_extra_definitions|Setting up SaneSecurity &amp;amp; MSRBL extra definitions]] | &#039;&#039;Another good way of catching SPAM is Sanesecurity and MSRBL definitions&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
=== Delivering mail to the user ===&lt;br /&gt;
&lt;br /&gt;
* [[Setting up dovecot with imap and ssl]] | &#039;&#039;Secure way to fetch you mail from the mailer daemon&#039;&#039;&lt;br /&gt;
* [[Setting up dovecot with imap and tls]] | &#039;&#039;Secure way to fetch you mail from the mailer daemon&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
=== Other Mail-related documents ===&lt;br /&gt;
&lt;br /&gt;
* [[Hosting Web/Email services on Alpine]] | &#039;&#039;Describes multiple services on same document&#039;&#039;&lt;br /&gt;
* [[Protecting your email server with Alpine]] | &#039;&#039;Describes multiple services on same document&#039;&#039;&lt;br /&gt;
* [[ISP_Mail_Server_3.x_HowTo]]&lt;br /&gt;
&lt;br /&gt;
== Web ==&lt;br /&gt;
&lt;br /&gt;
* [[Setting up trac wiki]] | &#039;&#039;A ticket/wiki system&#039;&#039;&lt;br /&gt;
* [[Lighttpd]] | &#039;&#039;Lighttpd web server&#039;&#039;&lt;br /&gt;
* [[Apache]] | &#039;&#039;Apache web server&#039;&#039;&lt;br /&gt;
* [[Darkhttpd]] | &#039;&#039;Darkhttpd web server&#039;&#039;&lt;br /&gt;
* [[Nginx]] | &#039;&#039;Nginx web server&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
== SSH ==&lt;br /&gt;
&lt;br /&gt;
* [[Setting up a SSH server]] | &#039;&#039;OpenSSH and Dropbear SSH servers&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
== DNS ==&lt;br /&gt;
&lt;br /&gt;
* [[Setting up unbound DNS server]] | &#039;&#039;A validating, recursive, and caching DNS resolver that supports DNSSEC&#039;&#039;&lt;br /&gt;
* [[Setting up nsd DNS server]] | &#039;&#039;An authoritative-only DNS server&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
== Proxy ==&lt;br /&gt;
&lt;br /&gt;
* [[Setting up Explicit Squid Proxy]] | &#039;&#039;Configuring an explicit Squid proxy server&#039;&#039;&lt;br /&gt;
* [[Setting up Transparent Squid Proxy]] | &#039;&#039;Configuring a transparent Squid proxy server&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
= Also see =&lt;br /&gt;
&lt;br /&gt;
You&#039;ll probably also want to look at [[Tutorials and Howtos]]&lt;br /&gt;
&lt;br /&gt;
[[Category:Server]]&lt;br /&gt;
[[Category:Mail]]&lt;/div&gt;</summary>
		<author><name>Nangel</name></author>
	</entry>
	<entry>
		<id>https://wiki.alpinelinux.org/w/index.php?title=Main_Page&amp;diff=21479</id>
		<title>Main Page</title>
		<link rel="alternate" type="text/html" href="https://wiki.alpinelinux.org/w/index.php?title=Main_Page&amp;diff=21479"/>
		<updated>2022-01-11T22:07:56Z</updated>

		<summary type="html">&lt;p&gt;Nangel: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Warning| Please note as of 12 Jan 2022 00:00:00 UTC all new wiki pages are licensed as CC-BY-SA-4.0.&lt;br /&gt;
See [[Privacy Policy|https://wiki.alpinelinux.org/wiki/Alpine_Linux:Privacy_policy]] for more details.  &lt;br /&gt;
Existing pages retain the old license.}}&lt;br /&gt;
&lt;br /&gt;
__NOEDITSECTION__&lt;br /&gt;
__NOTOC__&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
= Welcome to Alpine Linux Wiki=&lt;br /&gt;
&#039;&#039;&#039;[http://alpinelinux.org/about Alpine Linux]&#039;&#039;&#039; is a security-oriented, lightweight Linux distribution based on [https://musl.libc.org/ musl libc] and [http://busybox.net Busybox].&lt;br /&gt;
&lt;br /&gt;
Here is a [[Alpine Linux:Overview|more detailed overview]] of what makes our distribution distinctive; and a [[comparison with other distros]].&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br /&amp;gt;&lt;br /&gt;
{|style=&amp;quot;margin: 1em auto 1em auto&amp;quot;&lt;br /&gt;
|style=&amp;quot;width:64px;&amp;quot;|[[image:hdd_mount.svg|64px|link=Installation]] &lt;br /&gt;
|&#039;&#039;&#039;[[Installation]]&#039;&#039;&#039; &amp;lt;br/&amp;gt; Installing Alpine Linux&lt;br /&gt;
|[[image:filetypes.svg|64px|link=FAQ]]&lt;br /&gt;
|&#039;&#039;&#039;[[FAQ|FAQ]]&#039;&#039;&#039; &amp;lt;br/&amp;gt; Frequently Asked Questions&lt;br /&gt;
|[[image:bookcase.svg|64px|link=Glossary]]&lt;br /&gt;
|&#039;&#039;&#039;[[Glossary]]&#039;&#039;&#039;&lt;br /&gt;
|-&lt;br /&gt;
|[[image:package_edutainment.svg|64px|link=Tutorials and Howtos]]&lt;br /&gt;
|&#039;&#039;&#039;[[Tutorials and Howtos]]&#039;&#039;&#039; &amp;lt;br/&amp;gt;Basic and advanced configuration tasks&lt;br /&gt;
|[[image:package_system.svg|64px|link=Developer Documentation]]&lt;br /&gt;
|&#039;&#039;&#039;[[Developer Documentation]]&#039;&#039;&#039; &amp;lt;br/&amp;gt; Alpine Linux Development &lt;br /&gt;
|[[image:kuser.svg|64px|link=Contribute]]&lt;br /&gt;
|&#039;&#039;&#039;[[Contribute]]&#039;&#039;&#039; &amp;lt;br/&amp;gt; Contribute to Alpine Linux&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
* [[Alpine Linux:Releases|Current releases]]&lt;br /&gt;
* [[Alpine Linux:Listings|Links to other sites with information about Alpine]]&lt;/div&gt;</summary>
		<author><name>Nangel</name></author>
	</entry>
	<entry>
		<id>https://wiki.alpinelinux.org/w/index.php?title=Main_Page&amp;diff=21478</id>
		<title>Main Page</title>
		<link rel="alternate" type="text/html" href="https://wiki.alpinelinux.org/w/index.php?title=Main_Page&amp;diff=21478"/>
		<updated>2022-01-11T21:09:38Z</updated>

		<summary type="html">&lt;p&gt;Nangel: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Warning| Please note as of 12 Jan 2022 00:00:00 UTC all new wiki pages are licensed as CC-BY-SA-4.0 See [https://wiki.alpinelinux.org/wiki/Alpine_Linux:Privacy_policy] for more details.  Existing pages retain the old license.}}&lt;br /&gt;
&lt;br /&gt;
__NOEDITSECTION__&lt;br /&gt;
__NOTOC__&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
= Welcome to Alpine Linux Wiki=&lt;br /&gt;
&#039;&#039;&#039;[http://alpinelinux.org/about Alpine Linux]&#039;&#039;&#039; is a security-oriented, lightweight Linux distribution based on [https://musl.libc.org/ musl libc] and [http://busybox.net Busybox].&lt;br /&gt;
&lt;br /&gt;
Here is a [[Alpine Linux:Overview|more detailed overview]] of what makes our distribution distinctive; and a [[comparison with other distros]].&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br /&amp;gt;&lt;br /&gt;
{|style=&amp;quot;margin: 1em auto 1em auto&amp;quot;&lt;br /&gt;
|style=&amp;quot;width:64px;&amp;quot;|[[image:hdd_mount.svg|64px|link=Installation]] &lt;br /&gt;
|&#039;&#039;&#039;[[Installation]]&#039;&#039;&#039; &amp;lt;br/&amp;gt; Installing Alpine Linux&lt;br /&gt;
|[[image:filetypes.svg|64px|link=FAQ]]&lt;br /&gt;
|&#039;&#039;&#039;[[FAQ|FAQ]]&#039;&#039;&#039; &amp;lt;br/&amp;gt; Frequently Asked Questions&lt;br /&gt;
|[[image:bookcase.svg|64px|link=Glossary]]&lt;br /&gt;
|&#039;&#039;&#039;[[Glossary]]&#039;&#039;&#039;&lt;br /&gt;
|-&lt;br /&gt;
|[[image:package_edutainment.svg|64px|link=Tutorials and Howtos]]&lt;br /&gt;
|&#039;&#039;&#039;[[Tutorials and Howtos]]&#039;&#039;&#039; &amp;lt;br/&amp;gt;Basic and advanced configuration tasks&lt;br /&gt;
|[[image:package_system.svg|64px|link=Developer Documentation]]&lt;br /&gt;
|&#039;&#039;&#039;[[Developer Documentation]]&#039;&#039;&#039; &amp;lt;br/&amp;gt; Alpine Linux Development &lt;br /&gt;
|[[image:kuser.svg|64px|link=Contribute]]&lt;br /&gt;
|&#039;&#039;&#039;[[Contribute]]&#039;&#039;&#039; &amp;lt;br/&amp;gt; Contribute to Alpine Linux&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
* [[Alpine Linux:Releases|Current releases]]&lt;br /&gt;
* [[Alpine Linux:Listings|Links to other sites with information about Alpine]]&lt;/div&gt;</summary>
		<author><name>Nangel</name></author>
	</entry>
	<entry>
		<id>https://wiki.alpinelinux.org/w/index.php?title=Main_Page&amp;diff=21477</id>
		<title>Main Page</title>
		<link rel="alternate" type="text/html" href="https://wiki.alpinelinux.org/w/index.php?title=Main_Page&amp;diff=21477"/>
		<updated>2022-01-11T21:09:02Z</updated>

		<summary type="html">&lt;p&gt;Nangel: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Warning| Please note as of 12 Jan 2022 UTC all new wiki pages are licensed as CC-BY-SA-4.0 See [https://wiki.alpinelinux.org/wiki/Alpine_Linux:Privacy_policy] for more details.  Existing pages retain the old license.}}&lt;br /&gt;
&lt;br /&gt;
__NOEDITSECTION__&lt;br /&gt;
__NOTOC__&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
= Welcome to Alpine Linux Wiki=&lt;br /&gt;
&#039;&#039;&#039;[http://alpinelinux.org/about Alpine Linux]&#039;&#039;&#039; is a security-oriented, lightweight Linux distribution based on [https://musl.libc.org/ musl libc] and [http://busybox.net Busybox].&lt;br /&gt;
&lt;br /&gt;
Here is a [[Alpine Linux:Overview|more detailed overview]] of what makes our distribution distinctive; and a [[comparison with other distros]].&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br /&amp;gt;&lt;br /&gt;
{|style=&amp;quot;margin: 1em auto 1em auto&amp;quot;&lt;br /&gt;
|style=&amp;quot;width:64px;&amp;quot;|[[image:hdd_mount.svg|64px|link=Installation]] &lt;br /&gt;
|&#039;&#039;&#039;[[Installation]]&#039;&#039;&#039; &amp;lt;br/&amp;gt; Installing Alpine Linux&lt;br /&gt;
|[[image:filetypes.svg|64px|link=FAQ]]&lt;br /&gt;
|&#039;&#039;&#039;[[FAQ|FAQ]]&#039;&#039;&#039; &amp;lt;br/&amp;gt; Frequently Asked Questions&lt;br /&gt;
|[[image:bookcase.svg|64px|link=Glossary]]&lt;br /&gt;
|&#039;&#039;&#039;[[Glossary]]&#039;&#039;&#039;&lt;br /&gt;
|-&lt;br /&gt;
|[[image:package_edutainment.svg|64px|link=Tutorials and Howtos]]&lt;br /&gt;
|&#039;&#039;&#039;[[Tutorials and Howtos]]&#039;&#039;&#039; &amp;lt;br/&amp;gt;Basic and advanced configuration tasks&lt;br /&gt;
|[[image:package_system.svg|64px|link=Developer Documentation]]&lt;br /&gt;
|&#039;&#039;&#039;[[Developer Documentation]]&#039;&#039;&#039; &amp;lt;br/&amp;gt; Alpine Linux Development &lt;br /&gt;
|[[image:kuser.svg|64px|link=Contribute]]&lt;br /&gt;
|&#039;&#039;&#039;[[Contribute]]&#039;&#039;&#039; &amp;lt;br/&amp;gt; Contribute to Alpine Linux&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
* [[Alpine Linux:Releases|Current releases]]&lt;br /&gt;
* [[Alpine Linux:Listings|Links to other sites with information about Alpine]]&lt;/div&gt;</summary>
		<author><name>Nangel</name></author>
	</entry>
	<entry>
		<id>https://wiki.alpinelinux.org/w/index.php?title=Main_Page&amp;diff=21476</id>
		<title>Main Page</title>
		<link rel="alternate" type="text/html" href="https://wiki.alpinelinux.org/w/index.php?title=Main_Page&amp;diff=21476"/>
		<updated>2022-01-11T21:08:13Z</updated>

		<summary type="html">&lt;p&gt;Nangel: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Warning| Please note as of 12 Jan 2022 UTC all new wiki pages are licensed as CC-BY-SA-4. See [https://wiki.alpinelinux.org/wiki/Alpine_Linux:Privacy_policy] for more details.  Existing pages retain the old license.}}&lt;br /&gt;
&lt;br /&gt;
__NOEDITSECTION__&lt;br /&gt;
__NOTOC__&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
= Welcome to Alpine Linux Wiki=&lt;br /&gt;
&#039;&#039;&#039;[http://alpinelinux.org/about Alpine Linux]&#039;&#039;&#039; is a security-oriented, lightweight Linux distribution based on [https://musl.libc.org/ musl libc] and [http://busybox.net Busybox].&lt;br /&gt;
&lt;br /&gt;
Here is a [[Alpine Linux:Overview|more detailed overview]] of what makes our distribution distinctive; and a [[comparison with other distros]].&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br /&amp;gt;&lt;br /&gt;
{|style=&amp;quot;margin: 1em auto 1em auto&amp;quot;&lt;br /&gt;
|style=&amp;quot;width:64px;&amp;quot;|[[image:hdd_mount.svg|64px|link=Installation]] &lt;br /&gt;
|&#039;&#039;&#039;[[Installation]]&#039;&#039;&#039; &amp;lt;br/&amp;gt; Installing Alpine Linux&lt;br /&gt;
|[[image:filetypes.svg|64px|link=FAQ]]&lt;br /&gt;
|&#039;&#039;&#039;[[FAQ|FAQ]]&#039;&#039;&#039; &amp;lt;br/&amp;gt; Frequently Asked Questions&lt;br /&gt;
|[[image:bookcase.svg|64px|link=Glossary]]&lt;br /&gt;
|&#039;&#039;&#039;[[Glossary]]&#039;&#039;&#039;&lt;br /&gt;
|-&lt;br /&gt;
|[[image:package_edutainment.svg|64px|link=Tutorials and Howtos]]&lt;br /&gt;
|&#039;&#039;&#039;[[Tutorials and Howtos]]&#039;&#039;&#039; &amp;lt;br/&amp;gt;Basic and advanced configuration tasks&lt;br /&gt;
|[[image:package_system.svg|64px|link=Developer Documentation]]&lt;br /&gt;
|&#039;&#039;&#039;[[Developer Documentation]]&#039;&#039;&#039; &amp;lt;br/&amp;gt; Alpine Linux Development &lt;br /&gt;
|[[image:kuser.svg|64px|link=Contribute]]&lt;br /&gt;
|&#039;&#039;&#039;[[Contribute]]&#039;&#039;&#039; &amp;lt;br/&amp;gt; Contribute to Alpine Linux&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
* [[Alpine Linux:Releases|Current releases]]&lt;br /&gt;
* [[Alpine Linux:Listings|Links to other sites with information about Alpine]]&lt;/div&gt;</summary>
		<author><name>Nangel</name></author>
	</entry>
	<entry>
		<id>https://wiki.alpinelinux.org/w/index.php?title=Main_Page&amp;diff=21475</id>
		<title>Main Page</title>
		<link rel="alternate" type="text/html" href="https://wiki.alpinelinux.org/w/index.php?title=Main_Page&amp;diff=21475"/>
		<updated>2022-01-11T21:06:19Z</updated>

		<summary type="html">&lt;p&gt;Nangel: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Warning| Please note as of 12 Jan 2022 UTC all new wiki pages are licensed as CC-BY-CA. See [https://wiki.alpinelinux.org/wiki/Alpine_Linux:Privacy_policy] for more details.  Existing pages retain the old license.}}&lt;br /&gt;
&lt;br /&gt;
__NOEDITSECTION__&lt;br /&gt;
__NOTOC__&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
= Welcome to Alpine Linux Wiki=&lt;br /&gt;
&#039;&#039;&#039;[http://alpinelinux.org/about Alpine Linux]&#039;&#039;&#039; is a security-oriented, lightweight Linux distribution based on [https://musl.libc.org/ musl libc] and [http://busybox.net Busybox].&lt;br /&gt;
&lt;br /&gt;
Here is a [[Alpine Linux:Overview|more detailed overview]] of what makes our distribution distinctive; and a [[comparison with other distros]].&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br /&amp;gt;&lt;br /&gt;
{|style=&amp;quot;margin: 1em auto 1em auto&amp;quot;&lt;br /&gt;
|style=&amp;quot;width:64px;&amp;quot;|[[image:hdd_mount.svg|64px|link=Installation]] &lt;br /&gt;
|&#039;&#039;&#039;[[Installation]]&#039;&#039;&#039; &amp;lt;br/&amp;gt; Installing Alpine Linux&lt;br /&gt;
|[[image:filetypes.svg|64px|link=FAQ]]&lt;br /&gt;
|&#039;&#039;&#039;[[FAQ|FAQ]]&#039;&#039;&#039; &amp;lt;br/&amp;gt; Frequently Asked Questions&lt;br /&gt;
|[[image:bookcase.svg|64px|link=Glossary]]&lt;br /&gt;
|&#039;&#039;&#039;[[Glossary]]&#039;&#039;&#039;&lt;br /&gt;
|-&lt;br /&gt;
|[[image:package_edutainment.svg|64px|link=Tutorials and Howtos]]&lt;br /&gt;
|&#039;&#039;&#039;[[Tutorials and Howtos]]&#039;&#039;&#039; &amp;lt;br/&amp;gt;Basic and advanced configuration tasks&lt;br /&gt;
|[[image:package_system.svg|64px|link=Developer Documentation]]&lt;br /&gt;
|&#039;&#039;&#039;[[Developer Documentation]]&#039;&#039;&#039; &amp;lt;br/&amp;gt; Alpine Linux Development &lt;br /&gt;
|[[image:kuser.svg|64px|link=Contribute]]&lt;br /&gt;
|&#039;&#039;&#039;[[Contribute]]&#039;&#039;&#039; &amp;lt;br/&amp;gt; Contribute to Alpine Linux&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
* [[Alpine Linux:Releases|Current releases]]&lt;br /&gt;
* [[Alpine Linux:Listings|Links to other sites with information about Alpine]]&lt;/div&gt;</summary>
		<author><name>Nangel</name></author>
	</entry>
	<entry>
		<id>https://wiki.alpinelinux.org/w/index.php?title=Main_Page&amp;diff=21474</id>
		<title>Main Page</title>
		<link rel="alternate" type="text/html" href="https://wiki.alpinelinux.org/w/index.php?title=Main_Page&amp;diff=21474"/>
		<updated>2022-01-11T21:02:33Z</updated>

		<summary type="html">&lt;p&gt;Nangel: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Please note as of 12 Jan 2022 UTC all new wiki pages are licensed as CC-BY-CA. See [[https://wiki.alpinelinux.org/wiki/Alpine_Linux:Privacy_policy]] for more details.  Existing pages retain the old license.&lt;br /&gt;
&lt;br /&gt;
__NOEDITSECTION__&lt;br /&gt;
__NOTOC__&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
= Welcome to Alpine Linux Wiki=&lt;br /&gt;
&#039;&#039;&#039;[http://alpinelinux.org/about Alpine Linux]&#039;&#039;&#039; is a security-oriented, lightweight Linux distribution based on [https://musl.libc.org/ musl libc] and [http://busybox.net Busybox].&lt;br /&gt;
&lt;br /&gt;
Here is a [[Alpine Linux:Overview|more detailed overview]] of what makes our distribution distinctive; and a [[comparison with other distros]].&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br /&amp;gt;&lt;br /&gt;
{|style=&amp;quot;margin: 1em auto 1em auto&amp;quot;&lt;br /&gt;
|style=&amp;quot;width:64px;&amp;quot;|[[image:hdd_mount.svg|64px|link=Installation]] &lt;br /&gt;
|&#039;&#039;&#039;[[Installation]]&#039;&#039;&#039; &amp;lt;br/&amp;gt; Installing Alpine Linux&lt;br /&gt;
|[[image:filetypes.svg|64px|link=FAQ]]&lt;br /&gt;
|&#039;&#039;&#039;[[FAQ|FAQ]]&#039;&#039;&#039; &amp;lt;br/&amp;gt; Frequently Asked Questions&lt;br /&gt;
|[[image:bookcase.svg|64px|link=Glossary]]&lt;br /&gt;
|&#039;&#039;&#039;[[Glossary]]&#039;&#039;&#039;&lt;br /&gt;
|-&lt;br /&gt;
|[[image:package_edutainment.svg|64px|link=Tutorials and Howtos]]&lt;br /&gt;
|&#039;&#039;&#039;[[Tutorials and Howtos]]&#039;&#039;&#039; &amp;lt;br/&amp;gt;Basic and advanced configuration tasks&lt;br /&gt;
|[[image:package_system.svg|64px|link=Developer Documentation]]&lt;br /&gt;
|&#039;&#039;&#039;[[Developer Documentation]]&#039;&#039;&#039; &amp;lt;br/&amp;gt; Alpine Linux Development &lt;br /&gt;
|[[image:kuser.svg|64px|link=Contribute]]&lt;br /&gt;
|&#039;&#039;&#039;[[Contribute]]&#039;&#039;&#039; &amp;lt;br/&amp;gt; Contribute to Alpine Linux&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
* [[Alpine Linux:Releases|Current releases]]&lt;br /&gt;
* [[Alpine Linux:Listings|Links to other sites with information about Alpine]]&lt;/div&gt;</summary>
		<author><name>Nangel</name></author>
	</entry>
	<entry>
		<id>https://wiki.alpinelinux.org/w/index.php?title=Main_Page&amp;diff=21473</id>
		<title>Main Page</title>
		<link rel="alternate" type="text/html" href="https://wiki.alpinelinux.org/w/index.php?title=Main_Page&amp;diff=21473"/>
		<updated>2022-01-11T21:01:46Z</updated>

		<summary type="html">&lt;p&gt;Nangel: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Please note as if 12 Jan 2022 UTC all new wiki pages are licensed as CC-BY-CA. See [[https://https://wiki.alpinelinux.org/wiki/Alpine_Linux:Privacy_policy]] for more details.  Existing pages retain the old license.&lt;br /&gt;
&lt;br /&gt;
__NOEDITSECTION__&lt;br /&gt;
__NOTOC__&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
= Welcome to Alpine Linux Wiki=&lt;br /&gt;
&#039;&#039;&#039;[http://alpinelinux.org/about Alpine Linux]&#039;&#039;&#039; is a security-oriented, lightweight Linux distribution based on [https://musl.libc.org/ musl libc] and [http://busybox.net Busybox].&lt;br /&gt;
&lt;br /&gt;
Here is a [[Alpine Linux:Overview|more detailed overview]] of what makes our distribution distinctive; and a [[comparison with other distros]].&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br /&amp;gt;&lt;br /&gt;
{|style=&amp;quot;margin: 1em auto 1em auto&amp;quot;&lt;br /&gt;
|style=&amp;quot;width:64px;&amp;quot;|[[image:hdd_mount.svg|64px|link=Installation]] &lt;br /&gt;
|&#039;&#039;&#039;[[Installation]]&#039;&#039;&#039; &amp;lt;br/&amp;gt; Installing Alpine Linux&lt;br /&gt;
|[[image:filetypes.svg|64px|link=FAQ]]&lt;br /&gt;
|&#039;&#039;&#039;[[FAQ|FAQ]]&#039;&#039;&#039; &amp;lt;br/&amp;gt; Frequently Asked Questions&lt;br /&gt;
|[[image:bookcase.svg|64px|link=Glossary]]&lt;br /&gt;
|&#039;&#039;&#039;[[Glossary]]&#039;&#039;&#039;&lt;br /&gt;
|-&lt;br /&gt;
|[[image:package_edutainment.svg|64px|link=Tutorials and Howtos]]&lt;br /&gt;
|&#039;&#039;&#039;[[Tutorials and Howtos]]&#039;&#039;&#039; &amp;lt;br/&amp;gt;Basic and advanced configuration tasks&lt;br /&gt;
|[[image:package_system.svg|64px|link=Developer Documentation]]&lt;br /&gt;
|&#039;&#039;&#039;[[Developer Documentation]]&#039;&#039;&#039; &amp;lt;br/&amp;gt; Alpine Linux Development &lt;br /&gt;
|[[image:kuser.svg|64px|link=Contribute]]&lt;br /&gt;
|&#039;&#039;&#039;[[Contribute]]&#039;&#039;&#039; &amp;lt;br/&amp;gt; Contribute to Alpine Linux&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
* [[Alpine Linux:Releases|Current releases]]&lt;br /&gt;
* [[Alpine Linux:Listings|Links to other sites with information about Alpine]]&lt;/div&gt;</summary>
		<author><name>Nangel</name></author>
	</entry>
	<entry>
		<id>https://wiki.alpinelinux.org/w/index.php?title=Zabbix&amp;diff=20194</id>
		<title>Zabbix</title>
		<link rel="alternate" type="text/html" href="https://wiki.alpinelinux.org/w/index.php?title=Zabbix&amp;diff=20194"/>
		<updated>2021-10-12T13:42:07Z</updated>

		<summary type="html">&lt;p&gt;Nangel: Added link to McKayguard&amp;#039;s version&lt;/p&gt;
&lt;hr /&gt;
&lt;div&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. this guide has been updated to zabbix 3.0}}&lt;br /&gt;
{{Note|There is an alternate set of instructions here [[Zabbix_-_cgi_and_mysql]].}}&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;
For Zabbix you will have to install following two extra packages otherwise Zabbix will not run.&lt;br /&gt;
1.  php7-mbstring   2. php7-pgsql&lt;br /&gt;
&lt;br /&gt;
To Install these two packages  &lt;br /&gt;
{{Cmd|apk add php7-mbstring php7-pgsql}}&lt;br /&gt;
= Configure PostgreSQL =&lt;br /&gt;
&lt;br /&gt;
Install PostgreSQL&lt;br /&gt;
&lt;br /&gt;
{{Cmd|apk add postgresql postgresql-client}}&lt;br /&gt;
&lt;br /&gt;
Now configure PostgreSQL:&lt;br /&gt;
{{Cmd|/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/database/postgresql&lt;br /&gt;
cat schema.sql | psql -U zabbix zabbix&lt;br /&gt;
cat images.sql | psql -U zabbix zabbix&lt;br /&gt;
cat data.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/php7/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;
Also comment  (doc_root &amp;amp; user_dir )  by putting # before these.  &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;br /&gt;
&lt;br /&gt;
[[Category:Monitoring]]&lt;br /&gt;
[[Category:PHP]]&lt;br /&gt;
[[Category:SQL]]&lt;/div&gt;</summary>
		<author><name>Nangel</name></author>
	</entry>
	<entry>
		<id>https://wiki.alpinelinux.org/w/index.php?title=Zabbix&amp;diff=20193</id>
		<title>Zabbix</title>
		<link rel="alternate" type="text/html" href="https://wiki.alpinelinux.org/w/index.php?title=Zabbix&amp;diff=20193"/>
		<updated>2021-10-12T13:35:35Z</updated>

		<summary type="html">&lt;p&gt;Nangel: Revert Zabbix to pre cgi+mysql; add link to Zabbix+cgi+mysql&lt;/p&gt;
&lt;hr /&gt;
&lt;div&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. this guide has been updated to zabbix 3.0}}&lt;br /&gt;
&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;
For Zabbix you will have to install following two extra packages otherwise Zabbix will not run.&lt;br /&gt;
1.  php7-mbstring   2. php7-pgsql&lt;br /&gt;
&lt;br /&gt;
To Install these two packages  &lt;br /&gt;
{{Cmd|apk add php7-mbstring php7-pgsql}}&lt;br /&gt;
= Configure PostgreSQL =&lt;br /&gt;
&lt;br /&gt;
Install PostgreSQL&lt;br /&gt;
&lt;br /&gt;
{{Cmd|apk add postgresql postgresql-client}}&lt;br /&gt;
&lt;br /&gt;
Now configure PostgreSQL:&lt;br /&gt;
{{Cmd|/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/database/postgresql&lt;br /&gt;
cat schema.sql | psql -U zabbix zabbix&lt;br /&gt;
cat images.sql | psql -U zabbix zabbix&lt;br /&gt;
cat data.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/php7/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;
Also comment  (doc_root &amp;amp; user_dir )  by putting # before these.  &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;br /&gt;
&lt;br /&gt;
[[Category:Monitoring]]&lt;br /&gt;
[[Category:PHP]]&lt;br /&gt;
[[Category:SQL]]&lt;/div&gt;</summary>
		<author><name>Nangel</name></author>
	</entry>
	<entry>
		<id>https://wiki.alpinelinux.org/w/index.php?title=Talk:Zabbix_-_cgi_and_mysql&amp;diff=20192</id>
		<title>Talk:Zabbix - cgi and mysql</title>
		<link rel="alternate" type="text/html" href="https://wiki.alpinelinux.org/w/index.php?title=Talk:Zabbix_-_cgi_and_mysql&amp;diff=20192"/>
		<updated>2021-10-12T13:31:50Z</updated>

		<summary type="html">&lt;p&gt;Nangel: Nangel moved page Talk:Zabbix to Talk:Zabbix - cgi and mysql without leaving a redirect: As alpineuser mentioned, this page significantly changed the original - moving to a separate page&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==Possible Obfuscation / Abuse==&lt;br /&gt;
It appears that someone has taken the article from a manageable &amp;lt;40 command line entries and 6K bytes to&lt;br /&gt;
20K bytes, and now command line entries that number 100-200+:&lt;br /&gt;
https://wiki.alpinelinux.org/w/index.php?title=Zabbix&amp;amp;type=revision&amp;amp;diff=19688&amp;amp;oldid=17984&lt;br /&gt;
&lt;br /&gt;
Can Mckaygerhard justify the need for this additional&lt;br /&gt;
complexity, or is this obfuscation? It looks like the latter. It is written with spelling errors/rushed, has non-idiomatic use of sed (# instead of / dividers), and lists non existent links like alpine newbie lamers, and refers to zabbix as a curse. It&#039;s also much more LOC.&lt;br /&gt;
&lt;br /&gt;
Consider that I tested the old guide, and it works fine (v3.14) except that I had to copy the zabbix.conf.php from a different zabbix install to this since the database type doesn&#039;t populate during the setup.php install (essentially bypassing it). And the js on the web console only worked with certain browsers.&lt;br /&gt;
&lt;br /&gt;
Given that the old guide will suffice for the majority of users, I suggest the old one is reinstated, and Mckagerhard&#039;s additions can be left as a second option for those interested in more details. The old guide uses fastcgi, and postgres. Mckagerhard&#039;s guide uses cgi, and mysql. Since they are distinct guides, they can be kept separate.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;!-- Template:Unsigned --&amp;gt;&amp;lt;span class=&amp;quot;autosigned&amp;quot; style=&amp;quot;font-size:85%;&amp;quot;&amp;gt;—&amp;amp;nbsp;Preceding unsigned comments added by [[User:Alpineuser|Alpineuser]] ([[User talk:Alpineuser#top|talk]] • [[Special:Contributions/Alpineuser|contribs]]) 10:21, 20 July 2021&amp;lt;/span&amp;gt;&lt;/div&gt;</summary>
		<author><name>Nangel</name></author>
	</entry>
	<entry>
		<id>https://wiki.alpinelinux.org/w/index.php?title=Zabbix_-_cgi_and_mysql&amp;diff=20191</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=20191"/>
		<updated>2021-10-12T13:31:50Z</updated>

		<summary type="html">&lt;p&gt;Nangel: Nangel moved page Zabbix to Zabbix - cgi and mysql without leaving a redirect: As alpineuser mentioned, this page significantly changed the original - moving to a separate page&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Zabbix is the most popular monitoring manager in open source world, there&#039;s monitoring itself only like [[Cacti:_traffic_analysis_and_monitoring_network|catci]], but the hint is that &#039;&#039;&#039;&#039;&#039;Zabbix&#039;&#039;&#039; is manager also, &#039;&#039;&#039;is ipv6 ready! fully supported&#039;&#039;&#039;, also featured proxy-server for hidden and firewalled networks.&#039;&#039; Its like nagios one but more big, cutting edge and professional.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;In the wiki there are two approaches for its use&#039;&#039;&#039;, [[Production_monitoring_:_zabbix|the professional one]] (for servers and deploys) and the fast and simple usage (for developers and/or enthusiasts). For more curses on that (of course focused on alpine) check [http://qgqlochekone.blogspot.com/search/?q=zabbix Complete alpine documentation on english for zabbix curse]&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;This documentation is divided in two big parts.. the prerequisites and the installation&#039;&#039;&#039; of zabbix minimal infrastructure. The first part are in sync with the current alpine wiki pages of [https://wiki.alpinelinux.org/wiki/Category:Production Production pages]&lt;br /&gt;
&lt;br /&gt;
Note: There is a possibility that this page may have been complexified / obfuscated. See the talk page or review an earlier edit: https://wiki.alpinelinux.org/w/index.php?title=Zabbix&amp;amp;oldid=17984.&lt;br /&gt;
[[File:Zabbix-5-alpine.png|thumb]]&lt;br /&gt;
&lt;br /&gt;
= Where to use zabbix and alpine =&lt;br /&gt;
&lt;br /&gt;
Since Zabbix it focuses on hosts: So &#039;&#039;&#039;is the right choice for monitoring distributed networks&#039;&#039;&#039; (was originally developed for monitoring servers).&lt;br /&gt;
&lt;br /&gt;
In cases where there is no option to install an agent, Zabbix offers basic agentless monitoring. With it, you can check the availability of network services, as well as execute remote commands&lt;br /&gt;
&lt;br /&gt;
== Zabbix infraestructure ==&lt;br /&gt;
&lt;br /&gt;
Zabbix is divided into &#039;&#039;&#039;two large parts: server(s) and agent(s)&#039;&#039;&#039;, and yes &amp;quot;servers&amp;quot; cos can be centralized or decentralized due the &amp;quot;proxyes&amp;quot; semi-servers.&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;The servers&#039;&#039;&#039;: represent all the &#039;&#039;&#039;recollected data&#039;&#039;&#039; and &#039;&#039;&#039;has management capabilities&#039;&#039;&#039;. Each one if are more than one, collects and stores statistical data.&lt;br /&gt;
* &#039;&#039;&#039;The agents&#039;&#039;&#039;: represent each host, the clients, those machines or devices from which data is collected. Those support both passive (polling) and active checks (trapping).&lt;br /&gt;
* &#039;&#039;&#039;The proxys&#039;&#039;&#039;: represent a server that can act as man-in-the-middle for distributed load, cases of hideden networking or firewalled, of course &#039;&#039;&#039;with management capabilities cos act as server&#039;&#039;&#039; for those agents/hosts.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Passive checks&#039;&#039;&#039; mean that the Zabbix server requests a value from the Zabbix agent, and the agent processes the request and returns the value to the Zabbix server.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Active checks&#039;&#039;&#039; mean that the Zabbix agent requests a list of active checks from the Zabbix server and then periodically sends the results.&lt;br /&gt;
&lt;br /&gt;
[[File:Zabbix-agent-server-proxy-main-remote.jpg|center]]&lt;br /&gt;
&lt;br /&gt;
= Part 1 Pre-requisites: php, webserver and database =&lt;br /&gt;
&lt;br /&gt;
{{:Production_LAMP_system:_Lighttpd_+_PHP_+_MySQL}}&lt;br /&gt;
&lt;br /&gt;
= Part 2: zabbix =&lt;br /&gt;
&lt;br /&gt;
Zabbix depends on which type of database you will use, here we will show you how to doit with mysql, as more easy to use, for production is recommended posrgresql as in &lt;br /&gt;
&lt;br /&gt;
== 1. install zabbix packages ==&lt;br /&gt;
&lt;br /&gt;
Remenber that Zabbix has 3 components, and the server is the main one&lt;br /&gt;
&lt;br /&gt;
* Central servers to represent the data ( can be one zabbix server, o combined zabbix server with more zabbix proxies)&lt;br /&gt;
* Clients hosts to monitored (that is made by Agents, SNMP or just ICMP)&lt;br /&gt;
* Distributed proxy servers (that is only need for hosts behind firewall or closed networks)&lt;br /&gt;
&lt;br /&gt;
In the server we need the central base service at leas, and of course one agent for monitoring that server:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;lt;nowiki&amp;gt;&lt;br /&gt;
cat &amp;gt; /etc/apk/repositories &amp;lt;&amp;lt; EOF&lt;br /&gt;
http://dl-4.alpinelinux.org/alpine/v$(cat /etc/alpine-release | cut -d&#039;.&#039; -f1,2)/main&lt;br /&gt;
http://dl-4.alpinelinux.org/alpine/v$(cat /etc/alpine-release | cut -d&#039;.&#039; -f1,2)/community&lt;br /&gt;
EOF&lt;br /&gt;
&lt;br /&gt;
apk update&lt;br /&gt;
&lt;br /&gt;
apk add zabbix zabbix-mysql zabbix-webif zabbix-setup zabbix-utils zabbix-agentd&lt;br /&gt;
&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Now lest configure the server and the UI frontend in that server:&lt;br /&gt;
&lt;br /&gt;
== 2. Configure the base service ==&lt;br /&gt;
&lt;br /&gt;
Server zabbix, or proxy one always need a main database, the service of monitoring is running with it, the UI and agents always send the data to the zabbix server or zabbix proxy (and from proxy to server).&lt;br /&gt;
&lt;br /&gt;
{{Warning|The &#039;&#039;&#039;zabbix service DB user is &amp;lt;code&amp;gt;zabbixdb&amp;lt;/code&amp;gt; and NOT &amp;lt;code&amp;gt;zabbix&amp;lt;/code&amp;gt;&#039;&#039;&#039;, the user &amp;lt;code&amp;gt;zabbixdb&amp;lt;/code&amp;gt; whatever you use postgresql or mysql, will not be used with password for agent monitoring, cos in postgresql will use the &amp;lt;code&amp;gt;ident&amp;lt;/code&amp;gt; way autentication, and in mysql will use the &amp;lt;code&amp;gt;socket&amp;lt;/code&amp;gt; way autentication: &#039;&#039;&#039;this makes sense cos user agent is &amp;lt;code&amp;gt;zabbix&amp;lt;/code&amp;gt; and does not have home.&#039;&#039;&#039; This is the correct and most secure way.}}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;lt;nowiki&amp;gt;&lt;br /&gt;
mysql -u root -e &amp;quot;CREATE USER &#039;zabbix&#039;@&#039;localhost&#039; IDENTIFIED VIA mysql_native_password USING PASSWORD(&#039;clavezabix&#039;);&amp;quot;&lt;br /&gt;
mysql -u root -e &amp;quot;CREATE DATABASE zabbix CHARACTER SET utf8 COLLATE utf8_bin;&amp;quot;&lt;br /&gt;
mysql -u root -e &amp;quot;GRANT ALL PRIVILEGES ON zabbixdb.* TO &#039;zabbixdb&#039;@&#039;localhost&#039; WITH GRANT OPTION;&amp;quot;&lt;br /&gt;
&lt;br /&gt;
mysql -u zabbixdb --password=clavezabix zabbixdb &amp;lt; /usr/share/zabbix/database/mysql/schema.sql&lt;br /&gt;
mysql -u zabbixdb --password=clavezabix zabbixdb &amp;lt; /usr/share/zabbix/database/mysql/images.sql&lt;br /&gt;
mysql -u zabbixdb --password=clavezabix zabbixdb &amp;lt; /usr/share/zabbix/database/mysql/data.sql&lt;br /&gt;
&lt;br /&gt;
sed -i &#039;s|.*DBHost.*=.*|DBHost=localhost|g&#039; /etc/zabbix/zabbix_server.conf&lt;br /&gt;
sed -i &#039;s|DBName.*=.*|DBName=zabbixdb|g&#039; /etc/zabbix/zabbix_server.conf&lt;br /&gt;
sed -i &#039;s|.*DBPassword.*=.*|DBPassword=zabbixdb.db.1.com.1|g&#039; /etc/zabbix/zabbix_server.conf&lt;br /&gt;
sed -i &#039;s|.*DBUser.*=.*|DBUser=zabbixdb|g&#039; /etc/zabbix/zabbix_server.conf&lt;br /&gt;
sed -i &#039;s|.*DBSocket.*=.*|DBSocket=/run/mysqld/mysqld.sock|g&#039; /etc/zabbix/zabbix_server.conf&lt;br /&gt;
sed -i &#039;s|.*Fping6Location.*=.*|Fping6Location=|g&#039; /etc/zabbix/zabbix_server.conf&lt;br /&gt;
sed -i &#039;s|.*FpingLocation.*=.*|FpingLocation=/usr/sbin/fping|g&#039; /etc/zabbix/zabbix_server.conf&lt;br /&gt;
sed -i &#039;s|Nostname=.*|Nostname=monitor.zabbixnetwork|g&#039; /etc/zabbix/zabbix_server.conf&lt;br /&gt;
sed -i &#039;s|.*SourceIP.*=.*|SourceIP=0.0.0.0|g&#039; /etc/zabbix/zabbix_server.conf&lt;br /&gt;
&lt;br /&gt;
chown root:zabbix /usr/sbin/fping&lt;br /&gt;
&lt;br /&gt;
rc-update add zabbix-server default&lt;br /&gt;
&lt;br /&gt;
rc-service zabbix-server restart&lt;br /&gt;
&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
{{Note|Remenber that the hostname of the server is &amp;lt;nowiki&amp;gt;monitor.zabbixnetwork&amp;lt;/nowiki&amp;gt;, you can use the ip address too, but this name must be the same in the config files for active or passive servers, the web ui configured hostname server and/or zabbix configured hostname proxy server.}}&lt;br /&gt;
&lt;br /&gt;
== 3. Setup and configure web frontend ==&lt;br /&gt;
&lt;br /&gt;
The main server can be managed with the zabbix-frontend:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;lt;nowiki&amp;gt;&lt;br /&gt;
cp /usr/share/webapps/zabbix/conf/zabbix.conf.php.example /usr/share/webapps/zabbix/conf/zabbix.conf.php&lt;br /&gt;
&lt;br /&gt;
sed -i &amp;quot;s|.*DB\[&#039;TYPE&#039;\].*=.*|\$DB\[&#039;TYPE&#039;\] = &#039;MYSQL&#039;;|g&amp;quot; /usr/share/webapps/zabbix/conf/zabbix.conf.php&lt;br /&gt;
sed -i &amp;quot;s|.*DB\[&#039;SERVER&#039;\].*=.*|\$DB\[&#039;SERVER&#039;\] = &#039;localhost&#039;;|g&amp;quot; /usr/share/webapps/zabbix/conf/zabbix.conf.php&lt;br /&gt;
sed -i &amp;quot;s|.*DB\[&#039;DATABASE&#039;\].*=.*|\$DB\[&#039;DATABASE&#039;\] = &#039;zabbixdb&#039;;|g&amp;quot; /usr/share/webapps/zabbix/conf/zabbix.conf.php&lt;br /&gt;
sed -i &amp;quot;s|.*DB\[&#039;USER&#039;\].*=.*|\$DB\[&#039;USER&#039;\] = &#039;zabbixdb&#039;;|g&amp;quot; /usr/share/webapps/zabbix/conf/zabbix.conf.php&lt;br /&gt;
sed -i &amp;quot;s|.*DB\[&#039;PASSWORD&#039;\].*=.*|\$DB\[&#039;PASSWORD&#039;\] = &#039;zabbixdb.db.1.com.1&#039;;|g&amp;quot; /usr/share/webapps/zabbix/conf/zabbix.conf.php&lt;br /&gt;
sed -i &amp;quot;s|.*ZBX_SERVER_PORT.*=.*|\$ZBX_SERVER_PORT = &#039;10051&#039;;|g&amp;quot; /usr/share/webapps/zabbix/conf/zabbix.conf.php&lt;br /&gt;
sed -i &amp;quot;s|.*ZBX_SERVER_NAME.*=.*|\$ZBX_SERVER_NAME = &#039;monitor.ruices&#039;;|g&amp;quot; /usr/share/webapps/zabbix/conf/zabbix.conf.php&lt;br /&gt;
sed -i &amp;quot;s|.*IMAGE_FORMAT_DEFAULT.*=.*|\$IMAGE_FORMAT_DEFAULT = IMAGE_FORMAT_GIF;|g&amp;quot; /usr/share/webapps/zabbix/conf/zabbix.conf.php&lt;br /&gt;
sed -i &amp;quot;s|.*ZBX_SERVER.*=.*&#039;localhost&#039;;|\$ZBX_SERVER = &#039;localhost&#039;;|g&amp;quot; /usr/share/webapps/zabbix/conf/zabbix.conf.php&lt;br /&gt;
&lt;br /&gt;
cat &amp;gt; /usr/share/webapps/zabbix/.user.ini &amp;lt;&amp;lt; EOF&lt;br /&gt;
date.timezone = &amp;quot;America/Caracas&amp;quot;&lt;br /&gt;
display_errors  =  Off&lt;br /&gt;
log_errors  =  On&lt;br /&gt;
upload_max_filesize  =  16M&lt;br /&gt;
post_max_size  =  24M&lt;br /&gt;
memory_limit  =  512M&lt;br /&gt;
register_globals  =  Off&lt;br /&gt;
magic_quotes_gpc  =  Off&lt;br /&gt;
magic_quotes_runtime  =  Off&lt;br /&gt;
session.auto_start  = 0&lt;br /&gt;
mbstring.func_overload = 0&lt;br /&gt;
max_execution_time = 600&lt;br /&gt;
max_input_time = 600&lt;br /&gt;
EOF&lt;br /&gt;
&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
We do not use the stupid link of direct put on htdocs, we are professional and we use aliasing, &lt;br /&gt;
now lest configure the webserver to server the frontend by web:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;lt;nowiki&amp;gt;&lt;br /&gt;
cat &amp;gt; /etc/lighttpd/mod_zabbix.conf &amp;lt;&amp;lt; EOF&lt;br /&gt;
alias.url += (&lt;br /&gt;
     &amp;quot;/zabbix/&amp;quot;    =&amp;gt;    &amp;quot;/usr/share/webapps/zabbix/&amp;quot;&lt;br /&gt;
)&lt;br /&gt;
\$HTTP[&amp;quot;url&amp;quot;] =~ &amp;quot;^/zabbix/&amp;quot; {&lt;br /&gt;
    dir-listing.activate = &amp;quot;disable&amp;quot;&lt;br /&gt;
}&lt;br /&gt;
EOF&lt;br /&gt;
&lt;br /&gt;
sed -i &#039;s#\#.*mod_rewrite.*,.*#    &amp;quot;mod_rewrite&amp;quot;,#g&#039; /etc/lighttpd/lighttpd.conf&lt;br /&gt;
sed -i &#039;s#\#.*mod_alias.*,.*#    &amp;quot;mod_alias&amp;quot;,#g&#039; /etc/lighttpd/lighttpd.conf&lt;br /&gt;
sed -i &#039;s#\#.*mod_accesslog.*,.*#    &amp;quot;mod_accesslog&amp;quot;,#g&#039; /etc/lighttpd/lighttpd.conf&lt;br /&gt;
sed -i &#039;s#\#.*mod_setenv.*,.*#    &amp;quot;mod_setenv&amp;quot;,#g&#039; /etc/lighttpd/lighttpd.conf&lt;br /&gt;
sed -i &#039;s#\#.*mod_redirect.*,.*#    &amp;quot;mod_redirect&amp;quot;,#g&#039; /etc/lighttpd/lighttpd.conf&lt;br /&gt;
&lt;br /&gt;
sed -i &#039;s#.*include &amp;quot;mod_cgi.conf&amp;quot;.*#   include &amp;quot;mod_cgi.conf&amp;quot;#g&#039; /etc/lighttpd/lighttpd.conf&lt;br /&gt;
&lt;br /&gt;
check=&amp;quot;&amp;quot;;check=$(grep &#039;include &amp;quot;mod_zabbix.conf&#039; /etc/lighttpd/lighttpd.conf);[[ &amp;quot;$check&amp;quot; != &amp;quot;&amp;quot; ]] &amp;amp;&amp;amp; echo listo || sed -i &#039;s#.*include &amp;quot;mod_fastcgi_fpm.conf&amp;quot;.*#include &amp;quot;mod_fastcgi_fpm.conf&amp;quot;\ninclude &amp;quot;mod_zabbix.conf&amp;quot;#g&#039; /etc/lighttpd/lighttpd.conf&lt;br /&gt;
&lt;br /&gt;
chown -R lighttpd:www-data /usr/share/webapps/zabbix/&lt;br /&gt;
&lt;br /&gt;
rc-service lighttpd restart&lt;br /&gt;
&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
You should now be able to browse to the Zabbix frontend: http://yourservername/zabbix/ or in http://localhost/zabbix.&lt;br /&gt;
&lt;br /&gt;
The 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/4.0/manual/installation)&lt;br /&gt;
&lt;br /&gt;
There&#039;s no need to web setup cos we made all in cli as best hackers admins.&lt;br /&gt;
&lt;br /&gt;
== Zabbix tools for items maps or scripts ==&lt;br /&gt;
&lt;br /&gt;
There&#039;s no complete features in busybox so need more tools, also, Zabbix requires special permissions to use tools&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;lt;nowiki&amp;gt;&lt;br /&gt;
apk add bash fping tcptraceroute coreutils net-snmp-tools nmap perl rrdtool ttf-dejavu net-snmp-libs&lt;br /&gt;
&lt;br /&gt;
chown root:zabbix /usr/sbin/fping&lt;br /&gt;
&lt;br /&gt;
chmod u+s /usr/bin/ping&lt;br /&gt;
&lt;br /&gt;
chmod u+s /bin/ping&lt;br /&gt;
&lt;br /&gt;
chmod u+s /usr/bin/nmap &lt;br /&gt;
&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
{{Warning|this is preferable to use sudo, that has more issues in security holes, so set ui bit is a security mess buyt less than the crap usage or &amp;quot;sudo&amp;quot;, cos these tools are need to run as root to right usage}}&lt;br /&gt;
&lt;br /&gt;
= Zabbix and the Monitored host =&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Zabbix can monitor almost any device system&#039;&#039;&#039;, including Alpine Linux hosts, home computers, celphones, network devices, etc.&lt;br /&gt;
&lt;br /&gt;
== types of monitoring ==&lt;br /&gt;
&lt;br /&gt;
The &#039;&#039;&#039;zabbix agent&#039;&#039;&#039; is a zabbix service that runs on computers and is fully feartured, the &#039;&#039;&#039;SNMP(Simple Network Manager Protocol)&#039;&#039;&#039; is a common standard protocol and is the second most supported, the &#039;&#039;&#039;ICMP(Internet Control Message Protocol)&#039;&#039;&#039; is the most used and simples way but most limited, check the features:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Feature !! By Agent !! By SNMP !! By ICMP&lt;br /&gt;
|-&lt;br /&gt;
| Ping to check alive (direct ip) || Yes || Yes but with zabbbix proxy if firewall || Only on direct ip, no firewall&lt;br /&gt;
|-&lt;br /&gt;
| Retreive data from programs (direct ping) || Yes || Yes but with zabbbix proxy if firewall  || No&lt;br /&gt;
|-&lt;br /&gt;
| Send commands to manage || Yes || Yes but using zabbix proxy if firewall || No&lt;br /&gt;
|-&lt;br /&gt;
| Runs on any device || No, only computers || Mostly any network device || Yes&lt;br /&gt;
|-&lt;br /&gt;
| Runs on any OS || YEs, limited in androita and mainframes || Yes || Yes&lt;br /&gt;
|-&lt;br /&gt;
| Requires provilegies || Not necesary for most fearures || It depends || No&lt;br /&gt;
|}&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;
== Monitoring by Zabbix Agents ==&lt;br /&gt;
&lt;br /&gt;
The agent way to monitoring is the most complete featured, but only applies to computers host, becouse the zabbiz-agent software is only available for those devices, for networking devices you must use ICMP or SNMP (check next subsection).&lt;br /&gt;
&lt;br /&gt;
So, install the agent package and configure it on each host to be monitored/managed (on server too):&lt;br /&gt;
&lt;br /&gt;
{{Note|Remenber that the hostname of the server is &amp;lt;nowiki&amp;gt;monitor.zabbixnetwork&amp;lt;/nowiki&amp;gt;, you can use the ip address too, but this name must be the same in the config files for active or passive servers, the web ui configured hostname server and/or zabbix configured hostname proxy server.}}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;lt;nowiki&amp;gt;&lt;br /&gt;
cat &amp;gt; /etc/apk/repositories &amp;lt;&amp;lt; EOF&lt;br /&gt;
http://dl-4.alpinelinux.org/alpine/v$(cat /etc/alpine-release | cut -d&#039;.&#039; -f1,2)/main&lt;br /&gt;
http://dl-4.alpinelinux.org/alpine/v$(cat /etc/alpine-release | cut -d&#039;.&#039; -f1,2)/community&lt;br /&gt;
EOF&lt;br /&gt;
&lt;br /&gt;
apk update&lt;br /&gt;
&lt;br /&gt;
apk add zabbix-agent net-snmp-libs net-snmp-agent-libs&lt;br /&gt;
&lt;br /&gt;
sed -i &#039;s|.*ListenPort.*=.*|ListenPort=10050|g&#039; /etc/zabbix/zabbix_agentd.conf&lt;br /&gt;
sed -i &#039;s|.*Hostname=.*|Hostname=monitordhost1|g&#039; /etc/zabbix/zabbix_agentd.conf&lt;br /&gt;
sed -i &#039;s|Server =.*|Server=localhost,monitor.zabbixnetwork|g&#039; /etc/zabbix/zabbix_agentd.conf&lt;br /&gt;
sed -i &#039;s|ServerActive.*=.*|ServerActive=localhost,monitor.zabbixnetwork |g&#039; /etc/zabbix/zabbix_agentd.conf|g&#039; /etc/zabbix/zabbix_agentd.conf&lt;br /&gt;
sed -i &#039;s|.*EnableRemoteCommands.*=.*|EnableRemoteCommands=1|g&#039; /etc/zabbix/zabbix_agentd.conf&lt;br /&gt;
sed -i &#039;s|.*LogRemoteCommands.*=.*|LogRemoteCommands=1|g&#039; /etc/zabbix/zabbix_agentd.conf&lt;br /&gt;
sed -i &#039;s|# Include=.*|Include=/etc/zabbix/zabbix_agentd.d/*.conf|&#039; /etc/zabbix/zabbix_agentd.conf&lt;br /&gt;
&lt;br /&gt;
rc-update add zabbix-agentd default&lt;br /&gt;
&lt;br /&gt;
rc-service zabbix-agentd restart&lt;br /&gt;
&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
{{Note|The configured hostname in agent here is &amp;lt;nowiki&amp;gt;monitordhost1&amp;lt;/nowiki&amp;gt;, you can use the ip address too, but this name must be the same in the config files for active or passive host configured in the web ui, if the agent way will be used.}}&lt;br /&gt;
&lt;br /&gt;
{{Warning|The &#039;&#039;&#039;zabbix service DB user is &amp;lt;code&amp;gt;zabbixdb&amp;lt;/code&amp;gt; and NOT &amp;lt;code&amp;gt;zabbix&amp;lt;/code&amp;gt;&#039;&#039;&#039;, the user &amp;lt;code&amp;gt;zabbixdb&amp;lt;/code&amp;gt; whatever you use postgresql or mysql, will not be used with password for agent monitoring, cos in postgresql will use the &amp;lt;code&amp;gt;ident&amp;lt;/code&amp;gt; way autentication, and in mysql will use the &amp;lt;code&amp;gt;socket&amp;lt;/code&amp;gt; way autentication: &#039;&#039;&#039;this makes sense cos user agent is &amp;lt;code&amp;gt;zabbix&amp;lt;/code&amp;gt; and does not have home.&#039;&#039;&#039; This is the correct and most secure way.}}&lt;br /&gt;
&lt;br /&gt;
== Monitor by SNMP protocol ==&lt;br /&gt;
&lt;br /&gt;
Then in each monitor system, you shoul define a community word due ISP&#039;s always will punish if you used &amp;lt;code&amp;gt;public&amp;lt;/code&amp;gt; and open SNMP to world, inclusivelly you shoul protect inside your private network too, so on each host to be monitored you shoul made those commands to configure SNMP (including the zabbix server) using the &amp;lt;code&amp;gt;&amp;lt;/code&amp;gt;:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;lt;nowiki&amp;gt;&lt;br /&gt;
apk add net-snmp net-snmp-libs net-snmp-agent-libs net-snmp-perl net-snmp-tools&lt;br /&gt;
&lt;br /&gt;
cat &amp;gt; /etc/snmp/snmpd.conf &amp;lt;&amp;lt; EOF&lt;br /&gt;
view systemonly included .1.3.6.1.2.1.1&lt;br /&gt;
view systemonly included .1.3.6.1.2.1.25.1&lt;br /&gt;
rocommunity  monitor&lt;br /&gt;
rocommunity  public localhost&lt;br /&gt;
rocommunity  public default -V systemonly&lt;br /&gt;
sysLocation    client host at monitor.zabbixnetwork&lt;br /&gt;
sysContact     infoadmin &amp;lt;venenux@venenux.net&amp;gt;&lt;br /&gt;
sysServices    72&lt;br /&gt;
EOF&lt;br /&gt;
&lt;br /&gt;
rc-update add snmpd default&lt;br /&gt;
&lt;br /&gt;
rc-service snmpd restart &lt;br /&gt;
&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This will allow to any host consult SNMP v2c with word &amp;quot;monitor&amp;quot;, but is best you use if have distributed network a SNMP v3 autentiated. &lt;br /&gt;
&lt;br /&gt;
{{Warning|So in zabbix web ui you must use &amp;quot;monitor&amp;quot; in the community word.}}&lt;br /&gt;
&lt;br /&gt;
== DB monitoring ==&lt;br /&gt;
&lt;br /&gt;
Due limitations any host server that will have and database, must have and agent aither have behind or not have direct zabbix server/proxy connection.&lt;br /&gt;
&lt;br /&gt;
In this case we used Mysql as example&lt;br /&gt;
&lt;br /&gt;
=== on the monitored side: DBMS server to monitor ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;lt;nowiki&amp;gt;&lt;br /&gt;
apk add zabbix-agent&lt;br /&gt;
&lt;br /&gt;
sed -i &#039;s|.*ListenPort.*=.*|ListenPort=10050|g&#039; /etc/zabbix/zabbix_agentd.conf&lt;br /&gt;
sed -i &#039;s|.*Hostname=.*|Hostname=theDBserver|g&#039; /etc/zabbix/zabbix_agentd.conf&lt;br /&gt;
sed -i &#039;s|Server =.*|Server=monitor.zabbixnetwork|g&#039; /etc/zabbix/zabbix_agentd.conf&lt;br /&gt;
sed -i &#039;s|ServerActive.*=.*|ServerActive=monitor.zabbixnetwork|g&#039; /etc/zabbix/zabbix_agentd.conf&lt;br /&gt;
sed -i &#039;s|.*EnableRemoteCommands.*=.*|EnableRemoteCommands=1|g&#039; /etc/zabbix/zabbix_agentd.conf&lt;br /&gt;
sed -i &#039;s|.*LogRemoteCommands.*=.*|LogRemoteCommands=1|g&#039; /etc/zabbix/zabbix_agentd.conf&lt;br /&gt;
sed -i &#039;s|# Include=|Include=/etc/zabbix/zabbix_agentd.d/*.conf|g&#039; /etc/zabbix/zabbix_agentd.conf&lt;br /&gt;
&lt;br /&gt;
rc-update add zabbix-agentd default&lt;br /&gt;
&lt;br /&gt;
rc-service zabbix-agentd restart&lt;br /&gt;
&lt;br /&gt;
apk add mariadb-client &lt;br /&gt;
&lt;br /&gt;
wget -O /etc/zabbix/zabbix-agent/userparameter_mysql.conf &amp;quot;https://git.zabbix.com/projects/ZBX/repos/zabbix/browse/conf/zabbix_agentd/userparameter_mysql.conf?at=release/5.0&amp;quot;&lt;br /&gt;
&lt;br /&gt;
mysql -u root -e &amp;quot;CREATE USER &#039;zabbix&#039;@&#039;localhost&#039; IDENTIFIED VIA mysql_native_password USING PASSWORD(&#039;zabbix.db.1.com.1&#039;);&amp;quot;&lt;br /&gt;
mysql -u root -e &amp;quot;GRANT USAGE,REPLICATION CLIENT,PROCESS,SHOW DATABASES,SHOW VIEW ON *.* TO &#039;zabbix&#039;@&#039;localhost&#039;;&amp;quot;&lt;br /&gt;
&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
{{Note|The configured hostname in agent here is &amp;lt;nowiki&amp;gt;theDBserver&amp;lt;/nowiki&amp;gt;, you can use the ip address too, but this name must be the same in the config files for active or passive host configured in the web ui, if the agent way will be used to monitor this server host.}}&lt;br /&gt;
&lt;br /&gt;
{{Warning|An new issue of missing files is on alpine zabbix packages so read [https://gitlab.alpinelinux.org/alpine/aports/-/issues/12791 &amp;lt;nowiki&amp;gt;https://gitlab.alpinelinux.org/alpine/aports/-/issues/12791&amp;lt;/nowiki&amp;gt;], for files that you could download manually}}&lt;br /&gt;
&lt;br /&gt;
=== on the zabbix server side: to configure the monitored host ===&lt;br /&gt;
&lt;br /&gt;
Use the &#039;&#039;template DB mysql&#039;&#039; o &#039;&#039;DB postgresql&#039;&#039; on the configured host and remenber that hostname in the configured host must be the same in the hostname configured in the agent configuration file of the monitored host.&lt;br /&gt;
&lt;br /&gt;
For most details check the next section crash course:&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;br /&gt;
&lt;br /&gt;
== See also ==&lt;br /&gt;
&lt;br /&gt;
* [[Cacti:_traffic_analysis_and_monitoring_network]]&lt;br /&gt;
&lt;br /&gt;
== External resources and complete guides ==&lt;br /&gt;
&lt;br /&gt;
* [http://qgqlochekone.blogspot.com/search/?q=zabbix Complete alpine documentation on englilsh for zabbix curse]&lt;br /&gt;
* [https://vegnuli.wordpress.com/?s=zabbix Complete alpine documentation on spanish for zabbix curse]&lt;br /&gt;
&lt;br /&gt;
[[Category:Monitoring]]&lt;br /&gt;
[[Category:PHP]]&lt;br /&gt;
[[Category:SQL]]&lt;/div&gt;</summary>
		<author><name>Nangel</name></author>
	</entry>
	<entry>
		<id>https://wiki.alpinelinux.org/w/index.php?title=MediaWiki:Copyright&amp;diff=18566</id>
		<title>MediaWiki:Copyright</title>
		<link rel="alternate" type="text/html" href="https://wiki.alpinelinux.org/w/index.php?title=MediaWiki:Copyright&amp;diff=18566"/>
		<updated>2021-01-12T23:14:43Z</updated>

		<summary type="html">&lt;p&gt;Nangel: Update Copyright notice to 2021&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&amp;lt;div align=&amp;quot;right&amp;quot;&amp;gt;&amp;lt;div id=&amp;quot;footer-inner&amp;quot;&amp;gt; &lt;br /&gt;
  &amp;lt;p&amp;gt;&amp;lt;a href=&amp;quot;Privacy_Policy#Copyright&amp;quot;&amp;gt;&amp;amp;copy; Copyright 2008-2021 Alpine Linux Development Team&amp;lt;/a&amp;gt; &lt;br /&gt;
  all rights reserved &amp;lt;/div&amp;gt;&amp;lt;/div&amp;gt;&lt;/div&gt;</summary>
		<author><name>Nangel</name></author>
	</entry>
	<entry>
		<id>https://wiki.alpinelinux.org/w/index.php?title=Alpine_Linux:Releases&amp;diff=18126</id>
		<title>Alpine Linux:Releases</title>
		<link rel="alternate" type="text/html" href="https://wiki.alpinelinux.org/w/index.php?title=Alpine_Linux:Releases&amp;diff=18126"/>
		<updated>2020-10-21T11:46:28Z</updated>

		<summary type="html">&lt;p&gt;Nangel: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;There are several releases of Alpine Linux available at the same time. There is no fixed release cycle but typically every 6 month we make a snapshot of &#039;&#039;&#039;[[Edge|edge]]&#039;&#039;&#039; and make a release. We support the main repository for each stable release for a certain  amount of time, normally for 2 years. We can do security fixes beyond that on request and when patches are available.&lt;br /&gt;
 &lt;br /&gt;
The latest release of Alpine Linux is: &#039;&#039;&#039;3.12.1&#039;&#039;&#039; [https://alpinelinux.org/posts/Alpine-3.12.1-released.html Release notes], [http://git.alpinelinux.org/cgit/aports/log/?h=v3.12.1 git log]&lt;br /&gt;
&lt;br /&gt;
{| cellpadding=&amp;quot;5&amp;quot; border=&amp;quot;1&amp;quot; class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Branch&lt;br /&gt;
! Branch Date&lt;br /&gt;
! Latest Release&lt;br /&gt;
! Previous minor releases&lt;br /&gt;
! Directory name&lt;br /&gt;
! Updates&lt;br /&gt;
! End of Support&lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;&#039;[[edge]]&#039;&#039;&#039;&lt;br /&gt;
| current&lt;br /&gt;
| rolling&lt;br /&gt;
| -&lt;br /&gt;
| [http://dl-cdn.alpinelinux.org/alpine/edge/ edge]&lt;br /&gt;
| development&lt;br /&gt;
| n/a&lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;&#039;v3.12&#039;&#039;&#039;&lt;br /&gt;
| [http://git.alpinelinux.org/cgit/aports/log/?h=3.11-stable 2020-05-29]&lt;br /&gt;
| [http://alpinelinux.org/posts/Alpine-3.12.1-released.html 3.12.1]&lt;br /&gt;
| [http://alpinelinux.org/posts/Alpine-3.12.0-released.html 3.12.0]&lt;br /&gt;
| [http://dl-cdn.alpinelinux.org/alpine/v3.12/ v3.12] &lt;br /&gt;
| bug fixes&lt;br /&gt;
| &amp;lt;span style=&amp;quot;color: green;&amp;quot;&amp;gt;2022-05-01&amp;lt;/span&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;&#039;v3.11&#039;&#039;&#039;&lt;br /&gt;
| [http://git.alpinelinux.org/cgit/aports/log/?h=3.11-stable 2019-12-19]&lt;br /&gt;
| [http://alpinelinux.org/posts/Alpine-3.11.6-released.html 3.11.6]&lt;br /&gt;
| [http://alpinelinux.org/posts/Alpine-3.11.0-released.html 3.11.0], [http://alpinelinux.org/posts/Alpine-3.11.2-released.html 3.11.2], [http://alpinelinux.org/posts/Alpine-3.11.3-released.html 3.11.3], [http://alpinelinux.org/posts/Alpine-3.11.5-released.html 3.11.5]&lt;br /&gt;
| [http://dl-cdn.alpinelinux.org/alpine/v3.11/ v3.11] &lt;br /&gt;
| security fixes only&lt;br /&gt;
| &amp;lt;span style=&amp;quot;color: green;&amp;quot;&amp;gt;2021-11-01&amp;lt;/span&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;&#039;v3.10&#039;&#039;&#039;&lt;br /&gt;
| [http://git.alpinelinux.org/cgit/aports/log/?h=3.10-stable 2019-06-19]&lt;br /&gt;
| [http://alpinelinux.org/posts/Alpine-3.9.6-and-3.10.5-released.html 3.10.5]&lt;br /&gt;
| [http://alpinelinux.org/posts/Alpine-3.10.0-released.html 3.10.0], [http://alpinelinux.org/posts/Alpine-3.10.1-released.html 3.10.1], [http://alpinelinux.org/posts/Alpine-3.10.2-released.html 3.10.2], [http://alpinelinux.org/posts/Alpine-3.10.3-released.html 3.10.3]&lt;br /&gt;
| [http://dl-cdn.alpinelinux.org/alpine/v3.10/ v3.10] &lt;br /&gt;
| security fixes only&lt;br /&gt;
| &amp;lt;span style=&amp;quot;color: green;&amp;quot;&amp;gt;2021-05-01&amp;lt;/span&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;&#039;v3.9&#039;&#039;&#039;&lt;br /&gt;
| [http://git.alpinelinux.org/cgit/aports/log/?h=3.9-stable 2019-01-29]&lt;br /&gt;
| [http://alpinelinux.org/posts/Alpine-3.9.6-and-3.10.5-released.html 3.9.6]&lt;br /&gt;
| [http://alpinelinux.org/posts/Alpine-3.9.0-released.html 3.9.0], [http://alpinelinux.org/posts/Alpine-3.9.1-released.html 3.9.1], [http://alpinelinux.org/posts/Alpine-3.9.2-released.html 3.9.2], [http://alpinelinux.org/posts/Alpine-3.9.3-released.html 3.9.3], [http://alpinelinux.org/posts/Alpine-3.9.4-released.html 3.9.4]&lt;br /&gt;
| [http://dl-cdn.alpinelinux.org/alpine/v3.9/ v3.9] &lt;br /&gt;
| security fixes only&lt;br /&gt;
| &amp;lt;span style=&amp;quot;color: orange;&amp;quot;&amp;gt;2020-11-01&amp;lt;/span&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;&#039;v3.8&#039;&#039;&#039;&lt;br /&gt;
| [http://git.alpinelinux.org/cgit/aports/log/?h=3.8-stable 2018-06-26]&lt;br /&gt;
| [http://alpinelinux.org/posts/Alpine-3.8.2-released.html 3.8.2]&lt;br /&gt;
| [http://alpinelinux.org/posts/Alpine-3.8.0-released.html 3.8.0], [http://alpinelinux.org/posts/Alpine-3.8.1-released.html 3.8.1]&lt;br /&gt;
| [http://dl-cdn.alpinelinux.org/alpine/v3.8/ v3.8] &lt;br /&gt;
| on request only&lt;br /&gt;
| &amp;lt;span style=&amp;quot;color: red;&amp;quot;&amp;gt;2020-05-01&amp;lt;/span&amp;gt;&lt;br /&gt;
&lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;&#039;v3.7&#039;&#039;&#039;&lt;br /&gt;
| [http://git.alpinelinux.org/cgit/aports/log/?h=3.7-stable 2017-11-30]&lt;br /&gt;
| [http://alpinelinux.org/posts/Alpine-3.7.0-released.html 3.7.0]&lt;br /&gt;
| -&lt;br /&gt;
| [http://dl-cdn.alpinelinux.org/alpine/v3.7/ v3.7] &lt;br /&gt;
| on request only&lt;br /&gt;
| &amp;lt;span style=&amp;quot;color: red;&amp;quot;&amp;gt;2019-11-01&amp;lt;/span&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;&#039;v3.6&#039;&#039;&#039;&lt;br /&gt;
| [http://git.alpinelinux.org/cgit/aports/log/?h=3.6-stable 2017-05-24]&lt;br /&gt;
| [http://alpinelinux.org/posts/Alpine-3.6.2-released.html 3.6.2]&lt;br /&gt;
| [http://alpinelinux.org/posts/Alpine-3.6.0-released.html 3.6.0], [http://alpinelinux.org/posts/Alpine-3.6.1-released.html 3.6.1]&lt;br /&gt;
| [http://dl-cdn.alpinelinux.org/alpine/v3.6/ v3.6] &lt;br /&gt;
| on request only&lt;br /&gt;
| &amp;lt;span style=&amp;quot;color: red;&amp;quot;&amp;gt;2019-05-01&amp;lt;/span&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;&#039;v3.5&#039;&#039;&#039;&lt;br /&gt;
| [http://git.alpinelinux.org/cgit/aports/log/?h=3.5-stable 2016-12-22]&lt;br /&gt;
| [http://alpinelinux.org/posts/Alpine-3.5.2-released.html 3.5.2]&lt;br /&gt;
| [http://alpinelinux.org/posts/Alpine-3.5.0-released.html 3.5.0], [http://alpinelinux.org/posts/Alpine-3.5.1-released.html 3.5.1]&lt;br /&gt;
| [http://dl-cdn.alpinelinux.org/alpine/v3.5/ v3.5] &lt;br /&gt;
| on request only&lt;br /&gt;
| &amp;lt;span style=&amp;quot;color: red;&amp;quot;&amp;gt;2018-11-01&amp;lt;/span&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;&#039;v3.4&#039;&#039;&#039;&lt;br /&gt;
| [http://git.alpinelinux.org/cgit/aports/log/?h=3.4-stable 2016-05-31]&lt;br /&gt;
| [http://alpinelinux.org/posts/Alpine-3.4.6-released.html 3.4.6]&lt;br /&gt;
| [http://alpinelinux.org/posts/Alpine-3.4.0-released.html 3.4.0], [http://alpinelinux.org/posts/Alpine-3.4.1-released.html 3.4.1], [http://alpinelinux.org/posts/Alpine-3.4.2-released.html 3.4.2], [http://alpinelinux.org/posts/Alpine-3.4.3-released.html 3.4.3], [http://alpinelinux.org/posts/Alpine-3.4.4-released.html 3.4.4], [http://alpinelinux.org/posts/Alpine-3.4.5-released.html 3.4.5]&lt;br /&gt;
| [http://dl-cdn.alpinelinux.org/alpine/v3.4/ v3.4]&lt;br /&gt;
| on request only&lt;br /&gt;
| &amp;lt;span style=&amp;quot;color: red;&amp;quot;&amp;gt;2018-05-01&amp;lt;/span&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;&#039;v3.3&#039;&#039;&#039;&lt;br /&gt;
| [http://git.alpinelinux.org/cgit/aports/log/?h=3.3-stable 2016-01-06]&lt;br /&gt;
| [http://alpinelinux.org/posts/Alpine-3.3.3-released.html 3.3.3]&lt;br /&gt;
| [http://alpinelinux.org/posts/Alpine-3.3.0-released.html 3.3.0], [http://alpinelinux.org/posts/Alpine-3.3.1-released.html 3.3.1], [http://alpinelinux.org/posts/Alpine-3.3.2-released.html 3.3.2]&lt;br /&gt;
| [http://nl.alpinelinux.org/alpine/v3.3/ v3.3]&lt;br /&gt;
| on request only&lt;br /&gt;
| &amp;lt;span style=&amp;quot;color: red;&amp;quot;&amp;gt;2017-11-01&amp;lt;/span&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;&#039;v3.2&#039;&#039;&#039;&lt;br /&gt;
| [http://git.alpinelinux.org/cgit/aports/log/?h=3.2-stable 2015-05-26]&lt;br /&gt;
| [http://alpinelinux.org/posts/Alpine-3.2.3-released.html 3.2.3]&lt;br /&gt;
| [http://alpinelinux.org/posts/Alpine-3.2.0-released.html 3.2.0], [http://alpinelinux.org/posts/Alpine-3.2.1-released.html 3.2.1], [http://alpinelinux.org/posts/Alpine-3.2.2-released.html 3.2.2]&lt;br /&gt;
| [http://nl.alpinelinux.org/alpine/v3.2/ v3.2]&lt;br /&gt;
| on request only&lt;br /&gt;
| &amp;lt;span style=&amp;quot;color: red;&amp;quot;&amp;gt;2017-05-01&amp;lt;/span&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;&#039;v3.1&#039;&#039;&#039;&lt;br /&gt;
| [http://git.alpinelinux.org/cgit/aports/log/?h=3.1-stable 2014-12-10]&lt;br /&gt;
| [http://alpinelinux.org/posts/Alpine-3.1.4-released.html 3.1.4]&lt;br /&gt;
| [http://alpinelinux.org/release-3.1.0 3.1.0], [http://alpinelinux.org/release-3.1.1 3.1.1], [http://alpinelinux.org/posts/Alpine-3.1.2-released.html 3.1.2], [http://alpinelinux.org/posts/Alpine-3.1.3-released.html 3.1.3]&lt;br /&gt;
| [http://nl.alpinelinux.org/alpine/v3.1/ v3.1]&lt;br /&gt;
| on request only&lt;br /&gt;
| &amp;lt;span style=&amp;quot;color: red;&amp;quot;&amp;gt;2016-11-01&amp;lt;/span&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;&#039;v3.0&#039;&#039;&#039;&lt;br /&gt;
| [http://git.alpinelinux.org/cgit/aports/log/?h=3.0-stable 2014-06-04]&lt;br /&gt;
| [http://alpinelinux.org/release-3.0.6 3.0.6]&lt;br /&gt;
| [http://alpinelinux.org/release-3.0.0 3.0.0], [http://alpinelinux.org/release-3.0.1 3.0.1], [http://alpinelinux.org/release-3.0.2 3.0.2], [http://alpinelinux.org/release-3.0.3 3.0.3], [http://alpinelinux.org/release-3.0.4 3.0.4], [http://alpinelinux.org/release-3.0.5 3.0.5]&lt;br /&gt;
| [http://nl.alpinelinux.org/alpine/v3.0/ v3.0]&lt;br /&gt;
| on request only&lt;br /&gt;
| &amp;lt;span style=&amp;quot;color: red;&amp;quot;&amp;gt;2016-05-01&amp;lt;/span&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;&#039;v2.7&#039;&#039;&#039;&lt;br /&gt;
| [http://git.alpinelinux.org/cgit/aports/log/?h=2.7-stable 2013-11-08]&lt;br /&gt;
| [http://alpinelinux.org/release-2.7.9 2.7.9]&lt;br /&gt;
| [http://alpinelinux.org/release-2.7.0 2.7.0], [http://alpinelinux.org/release-2.7.1 2.7.1], [http://alpinelinux.org/release-2.7.2 2.7.2], [http://alpinelinux.org/release-2.7.3 2.7.3], [http://alpinelinux.org/release-2.7.4 2.7.4], [http://alpinelinux.org/release-2.7.5 2.7.5], [http://alpinelinux.org/release-2.7.6 2.7.6], [http://alpinelinux.org/release-2.7.7 2.7.7], [http://alpinelinux.org/release-2.7.8 2.7.8]&lt;br /&gt;
| [http://nl.alpinelinux.org/alpine/v2.7/ v2.7]&lt;br /&gt;
| on request only&lt;br /&gt;
| &amp;lt;span style=&amp;quot;color: red;&amp;quot;&amp;gt;2015-11-01&amp;lt;/span&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;&#039;v2.6&#039;&#039;&#039;&lt;br /&gt;
| [http://git.alpinelinux.org/cgit/aports/log/?h=2.6-stable 2013-05-17]&lt;br /&gt;
| [http://alpinelinux.org/release-2.6.6 2.6.6]&lt;br /&gt;
| [http://alpinelinux.org/release-2.6.0 2.6.0], [http://alpinelinux.org/release-2.6.1 2.6.1], [http://alpinelinux.org/release-2.6.2 2.6.2], [http://alpinelinux.org/release-2.6.3 2.6.3], [http://alpinelinux.org/release-2.6.4 2.6.4], [http://alpinelinux.org/release-2.6.5 2.6.5]&lt;br /&gt;
| [http://nl.alpinelinux.org/alpine/v2.6/ v2.6]&lt;br /&gt;
| on request only&lt;br /&gt;
| &amp;lt;span style=&amp;quot;color: red;&amp;quot;&amp;gt;2015-05-01&amp;lt;/span&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;&#039;v2.5&#039;&#039;&#039;&lt;br /&gt;
| [http://git.alpinelinux.org/cgit/aports/log/?h=2.5-stable 2012-11-07]&lt;br /&gt;
| [http://alpinelinux.org/release-2.5.4 2.5.4]&lt;br /&gt;
| [http://alpinelinux.org/release-2.5.0 2.5.0], [http://alpinelinux.org/release-2.5.1 2.5.1], [http://alpinelinux.org/release-2.5.2 2.5.2], [http://alpinelinux.org/release-2.5.3 2.5.3]&lt;br /&gt;
| [http://nl.alpinelinux.org/alpine/v2.5/ v2.5]&lt;br /&gt;
| on request only&lt;br /&gt;
| &amp;lt;span style=&amp;quot;color: red;&amp;quot;&amp;gt;2014-11-01&amp;lt;/span&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;&#039;v2.4&#039;&#039;&#039;&lt;br /&gt;
| [http://git.alpinelinux.org/cgit/aports/log/?h=2.4-stable 2012-05-02]&lt;br /&gt;
| [http://alpinelinux.org/release-2.4.11 2.4.11]&lt;br /&gt;
| [http://alpinelinux.org/node/13811 2.4.0], [http://alpinelinux.org/node/13812 2.4.1], [http://alpinelinux.org/node/13845 2.4.2], [http://alpinelinux.org/node/13906 2.4.3], [http://alpinelinux.org/release-2.4.4 2.4.4], [http://alpinelinux.org/release-2.4.5 2.4.5], [http://alpinelinux.org/release-2.4.6 2.4.6], [http://alpinelinux.org/release-2.4.7 2.4.7], 2.4.8, [http://alpinelinux.org/node/14664 2.4.9], [http://alpinelinux.org/release-2.4.10 2.4.10]&lt;br /&gt;
| [http://nl.alpinelinux.org/alpine/v2.4/ v2.4]&lt;br /&gt;
| on request only&lt;br /&gt;
| &amp;lt;span style=&amp;quot;color: red;&amp;quot;&amp;gt;2014-05-01&amp;lt;/span&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;&#039;v2.3&#039;&#039;&#039;&lt;br /&gt;
| [http://git.alpinelinux.org/cgit/aports/log/?h=2.3-stable 2011-11-01]&lt;br /&gt;
| [http://alpinelinux.org/node/13503 2.3.6]&lt;br /&gt;
| [http://alpinelinux.org/node/6841 2.3.0], [http://alpinelinux.org/node/6866 2.3.1], [http://alpinelinux.org/node/6911 2.3.2], [http://alpinelinux.org/node/6999 2.3.3], [http://alpinelinux.org/node/13466 2.3.4 &amp;amp; 2.3.5]&lt;br /&gt;
| [http://nl.alpinelinux.org/alpine/v2.3/ v2.3]&lt;br /&gt;
| on request only&lt;br /&gt;
| &amp;lt;span style=&amp;quot;color: red;&amp;quot;&amp;gt;2013-11-01&amp;lt;/span&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;&#039;v2.2&#039;&#039;&#039;&lt;br /&gt;
| [http://git.alpinelinux.org/cgit/aports/log/?h=2.2-stable 2011-05-03]&lt;br /&gt;
| [http://alpinelinux.org/node/6455 2.2.3]&lt;br /&gt;
| [http://alpinelinux.org/node/5237 2.2.0], [http://lists.alpinelinux.org/alpine-devel/1618.html 2.2.1], [http://alpinelinux.org/node/5955 2.2.2]&lt;br /&gt;
| [http://nl.alpinelinux.org/alpine/v2.2/ v2.2]&lt;br /&gt;
| on request only&lt;br /&gt;
| &amp;lt;span style=&amp;quot;color: red;&amp;quot;&amp;gt;2013-05-01&amp;lt;/span&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;&#039;v2.1&#039;&#039;&#039;&lt;br /&gt;
| [http://git.alpinelinux.org/cgit/aports/log/?h=2.1-stable 2010-11-01]&lt;br /&gt;
| [http://alpinelinux.org/node/5236 2.1.6]&lt;br /&gt;
| [[Release_Notes_for_Alpine_2.1.0|2.1.0]], [[Release_Notes_for_Alpine_2.1.1|2.1.1]], [[Release_Notes_for_Alpine_2.1.2|2.1.2]], [[Release_Notes_for_Alpine_2.1.3|2.1.3]], [http://alpinelinux.org/node/5230 2.1.4], [http://alpinelinux.org/node/5235 2.1.5]&lt;br /&gt;
| [http://nl.alpinelinux.org/alpine/v2.1/ v2.1]&lt;br /&gt;
| on request only&lt;br /&gt;
| &amp;lt;span style=&amp;quot;color: red;&amp;quot;&amp;gt;2012-11-01&amp;lt;/span&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;&#039;v2.0&#039;&#039;&#039;&lt;br /&gt;
| [http://git.alpinelinux.org/cgit/aports/log/?h=2.0-stable 2010-08-16]&lt;br /&gt;
| [http://wiki.alpinelinux.org/wiki/Release_Notes_for_Alpine_2.0.3 2.0.3]&lt;br /&gt;
| [[Release_Notes_for_Alpine_2.0.0|2.0.0]], [[Release_Notes_for_Alpine_2.0.1|2.0.1]], [[Release_Notes_for_Alpine_2.0.2|2.0.2]]&lt;br /&gt;
| [http://nl.alpinelinux.org/alpine/v2.0/ v2.0]&lt;br /&gt;
| on request only&lt;br /&gt;
| &amp;lt;span style=&amp;quot;color: red;&amp;quot;&amp;gt;2012-04-01&amp;lt;/span&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
An archive for [[older releases]] is also available.&lt;/div&gt;</summary>
		<author><name>Nangel</name></author>
	</entry>
	<entry>
		<id>https://wiki.alpinelinux.org/w/index.php?title=Category_talk:Wiki&amp;diff=18107</id>
		<title>Category talk:Wiki</title>
		<link rel="alternate" type="text/html" href="https://wiki.alpinelinux.org/w/index.php?title=Category_talk:Wiki&amp;diff=18107"/>
		<updated>2020-10-17T19:47:00Z</updated>

		<summary type="html">&lt;p&gt;Nangel: Answer question - Mark page for deletion.&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;I am interested in installing polyml on Alpine x86&lt;br /&gt;
I notice there is a package in testing, but it fails to install since it seems to require some 64-bit libraries.&lt;br /&gt;
There is no maintainer listed, so my question is:&lt;br /&gt;
How could I become maintainer so I can fix that package?&lt;br /&gt;
I will build polyml from source to do that.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Hi - This is a good place to start: https://wiki.alpinelinux.org/wiki/Alpine_newbie_developer&lt;/div&gt;</summary>
		<author><name>Nangel</name></author>
	</entry>
	<entry>
		<id>https://wiki.alpinelinux.org/w/index.php?title=OrenHumphery962&amp;diff=18072</id>
		<title>OrenHumphery962</title>
		<link rel="alternate" type="text/html" href="https://wiki.alpinelinux.org/w/index.php?title=OrenHumphery962&amp;diff=18072"/>
		<updated>2020-09-13T14:18:08Z</updated>

		<summary type="html">&lt;p&gt;Nangel: Nangel moved page OrenHumphery962 to Spam&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;#REDIRECT [[Spam]]&lt;/div&gt;</summary>
		<author><name>Nangel</name></author>
	</entry>
	<entry>
		<id>https://wiki.alpinelinux.org/w/index.php?title=User:OrenHumphery962&amp;diff=18070</id>
		<title>User:OrenHumphery962</title>
		<link rel="alternate" type="text/html" href="https://wiki.alpinelinux.org/w/index.php?title=User:OrenHumphery962&amp;diff=18070"/>
		<updated>2020-09-13T14:17:53Z</updated>

		<summary type="html">&lt;p&gt;Nangel: Nangel moved page User:OrenHumphery962 to OrenHumphery962&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;#REDIRECT [[OrenHumphery962]]&lt;/div&gt;</summary>
		<author><name>Nangel</name></author>
	</entry>
	<entry>
		<id>https://wiki.alpinelinux.org/w/index.php?title=Setting_up_a_laptop&amp;diff=17295</id>
		<title>Setting up a laptop</title>
		<link rel="alternate" type="text/html" href="https://wiki.alpinelinux.org/w/index.php?title=Setting_up_a_laptop&amp;diff=17295"/>
		<updated>2020-04-26T21:45:39Z</updated>

		<summary type="html">&lt;p&gt;Nangel: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Draft}}&lt;br /&gt;
&lt;br /&gt;
This guide is about a project to create a &#039;&#039;&#039;secured laptop&#039;&#039;&#039;.  For this project we take in consideration ways to extend battery life.  It covers tools and daemons that are must haves for a laptop setup.&lt;br /&gt;
&lt;br /&gt;
== Guide features ==&lt;br /&gt;
&lt;br /&gt;
*Deniable full disk encryption&lt;br /&gt;
*Two factor authentication (physical object (USB key), mind) &lt;br /&gt;
*Encrypted swap and hibernation&lt;br /&gt;
*Encrypted home on top of encrypted drive&lt;br /&gt;
*Memory sanitation&lt;br /&gt;
*Dynamic power modes&lt;br /&gt;
*Feature keys support&lt;br /&gt;
&lt;br /&gt;
== Rubberhose Attack ==&lt;br /&gt;
&lt;br /&gt;
Just a reminder that all attacks are subjected to the Rubberhose Attack dilemma, you either give up your encryption keys or be tortured with a rubberhose with the possibly of death.  See [https://en.wikipedia.org/wiki/Rubber-hose_cryptanalysis Wikipedia article].  We try to present [https://en.wikipedia.org/wiki/Deniable_encryption  deniable encryption (Wikipedia)] to avoid a rubberhose attack scenario.  In this article we use the words plausible deniability interchangeably with deniable encryption.  To achieve this we use a facade and require no metadata fingerprints to expose or hint of encrypted or hidden containers or hint as in detect of existence of an encrypted disk.  The keys should be stored using steganography where we dilute the randomness into the facade.  It also requires you not to brag about encryption or mention it because that is an invitation for the attacker to torture the victim.  Deniable encryption requires you not put encrypted as an entry title to your bootloader.  There shouldn&#039;t be an entry for your facade bootloader to the encrypted drive.&lt;br /&gt;
&lt;br /&gt;
== Why full disk? ==&lt;br /&gt;
&lt;br /&gt;
The full disk encryption provides sort of some plausible deniability or a valid alibi that you didn&#039;t encrypt it.  Is the drive just random noise, broken, or is it really encrypted?  The other reason is that it implies that everything is protected.&lt;br /&gt;
&lt;br /&gt;
But there could be problems if not done right.  For example, cryptsetup does leave a plaintext marking or some hints by default that it has been encrypted when using luks/luks2 mode if a detached header with option &amp;lt;code&amp;gt;--header &amp;lt;path&amp;gt;&amp;lt;/code&amp;gt; is not presented.[https://www.lisenet.com/2013/luks-add-keys-backup-and-restore-volume-header/][http://man7.org/linux/man-pages/man8/cryptsetup.8.html]  To gain credibility that we didn&#039;t really do the encryption, you have to wipe the +3 MiB region based on the number of key slots used; or store the headers on an external device.&lt;br /&gt;
&lt;br /&gt;
If you did deniable encryption incorrectly, it is possible to erase and restore the header.  This presents an opportunity to improve obfuscation.  When you pull out the USB key, it should erase the header but store it on the USB key atomically as in completely.  If you plug in the USB key, it will restore back the header.  cryptsetup has luks actions luksHeaderBackup and luksHeaderRestore to do this.&lt;br /&gt;
&lt;br /&gt;
== Starting at the beginning ==&lt;br /&gt;
&lt;br /&gt;
Grab a USB thumb drive with Alpine.  Set it up as usual but don&#039;t let it touch your drive yet.  Then, install all the tools into memory ramdisk but not in the hard drive yet.  The hard drive will be obliterated.&lt;br /&gt;
&lt;br /&gt;
You will then install Alpine using the steps:&lt;br /&gt;
&lt;br /&gt;
First you need WiFi, to get it run do the command below but say no or skip  the hard drive setup stuff:&lt;br /&gt;
&lt;br /&gt;
  setup-alpine&lt;br /&gt;
&lt;br /&gt;
Then, you need to install some tools into RAM temporarly:&lt;br /&gt;
  apk add e2fsprogs grub grub-bios grub-efi mkinitfs nano&lt;br /&gt;
&lt;br /&gt;
== Randomizing the drive with pseudorandom urandom entropy ==&lt;br /&gt;
&lt;br /&gt;
The first part is to erase the drive with random noise but in practical time.  There are many techniques to do this but should be done in one day or two minimum.&lt;br /&gt;
&lt;br /&gt;
You can use shred or dd to accomplish this depending on your needs and the availability of entropy.  Some techniques take longer.  Cryptologist Bruce Schneier recommended 7 times with specified pattern.  See [https://en.wikipedia.org/wiki/Data_erasure Wikipedia Article].  For practical purposes, we just do it random in one pass.  It should be random so that the facade of random noise hides the encrypted data which resembles noise.&lt;br /&gt;
&lt;br /&gt;
To list the drives on the system do &amp;lt;code&amp;gt;fdisk -l&amp;lt;/code&amp;gt;.  &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;IMPORTANT: make sure you wipe the right specific drive.&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
To wipe the disk with random entropy do:&lt;br /&gt;
&lt;br /&gt;
  dd if=/dev/urandom of=/dev/sda&lt;br /&gt;
&lt;br /&gt;
== Creating GPG keys ==&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;As of this time, Alpine&#039;s mkinitfs does only one factor authentication with passphrase.&#039;&#039;&#039; You need to manually edit the initramfs-init.in in mkinitfs to support two factor authentication using cryptsetup.&lt;br /&gt;
&lt;br /&gt;
After you have scrambled the drive, you want to create your GPG keys.  You will use these keys to set the password(s) for your cryptsetup-luks partitions.  These keys should be stored on a USB thumb drive or other memory device but should not be on the USB boot thumb drive or on the encrypted drive.  The key should be a random 128 bit key wrapped in GPG and protected with a password.&lt;br /&gt;
&lt;br /&gt;
If you are using x, you need to do &amp;lt;code&amp;gt;sudo apk add pinentry-gtk&amp;lt;/code&amp;gt; to display password prompt properly for the next step.&lt;br /&gt;
&lt;br /&gt;
To install openssl and gpg do:&lt;br /&gt;
&lt;br /&gt;
  apk add openssl gnupg&lt;br /&gt;
&lt;br /&gt;
Then, to generate a key:&lt;br /&gt;
&lt;br /&gt;
  export GPG_TTY=$(tty) &amp;amp;&amp;amp; openssl rand -base64 512 | gpg --symmetric --cipher-algo aes --armor &amp;gt; /mnt/usb/$(openssl rand -hex 12)&lt;br /&gt;
&lt;br /&gt;
(Make sure your usb is mounted on /mnt/usb first.)&lt;br /&gt;
&lt;br /&gt;
The long file name comes from &amp;lt;code&amp;gt;openssl rand -hex 12&amp;lt;/code&amp;gt; so that we enhance plausible deniability.  The attacker cannot determine the purpose of the key.  Is it used for GitHub? for Email?&lt;br /&gt;
&lt;br /&gt;
The first part will produce 512 random bytes in wrap it in base64.  The random data will be piped to gpg which will wrap it in AES as ciphertext which again gets wrapped in base64 ascii armor.  For every partition including swap in some cases, you should create more gpg keys and store them in your USB thumb drives.  After you have produced your gpg keys, you will then use them as a password for cryptsetup/luks.&lt;br /&gt;
&lt;br /&gt;
You can replace aes above with the ones listed in &amp;lt;code&amp;gt;gpg --version&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
There should be a password generated for the swap.  This is to resume for your hibernate.  If you don&#039;t want to hibernate, then password is not required and all you need to do is to create/format the partition each time you boot without a password or with a one time random password.&lt;br /&gt;
&lt;br /&gt;
== Hiding the keys using steganography ==&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;WARNING:&#039;&#039; This section is considered experimental.  It requires the tool and the dependencies to be placed on another USB separate from the key files, the bootloaders, and encrypted disks.  The tool and dependencies need to be packaged together.  We decentralize these components so that the attacker doesn&#039;t connect the dots easily or immediately jumps to the conclusion for the requirements to decrypt.  Steghide automatically uses 128-bit AES in CBC mode to encrypt data.  This can be change if you don&#039;t like or trust AES with the -e option.  Use &amp;lt;code&amp;gt;steghide encinfo&amp;lt;/code&amp;gt; for other ciphers and modes.&lt;br /&gt;
&lt;br /&gt;
Fortunately, Alpine has a package for steganography called steghide.  To install steghide do:&lt;br /&gt;
&lt;br /&gt;
  apk add steghide&lt;br /&gt;
&lt;br /&gt;
You will place the keyfile in an image file.  The facade image file should be large enough that there is no apparent discernible difference between the original and the modified.  Do not use a small image with a small filesize.&lt;br /&gt;
&lt;br /&gt;
As mentioned previously luks headers could be 3MB large or more and an jpeg image file is not suitable.  Use another format like .au/.wav or another steganography utility that handles mp3s.  The mp3/wav should be fairly large enough to dilute the header.  So, something with long content is suitable.&lt;br /&gt;
&lt;br /&gt;
There are two basic commands to use with steghide embed and extract,&lt;br /&gt;
&lt;br /&gt;
To embed do:&lt;br /&gt;
&lt;br /&gt;
  steghide embed -ef key.gpg -cf image.jpg&lt;br /&gt;
&lt;br /&gt;
To extract do:&lt;br /&gt;
&lt;br /&gt;
  steghide extract -xf key.gpg -sf image.jpg&lt;br /&gt;
&lt;br /&gt;
To get a file list of files to ship out, use:&lt;br /&gt;
&lt;br /&gt;
  apk info -L libgcc libmcrypt libmhash libstdc++ libjpeg-turbo steghide&lt;br /&gt;
&lt;br /&gt;
== Full disk encryption with with cryptsetup-luks volumes ==&lt;br /&gt;
&lt;br /&gt;
=== Partitioning scheme ===&lt;br /&gt;
&lt;br /&gt;
This section presents a conceptual layout.  It should not be a knee-jerk approval to automatically use the partition tool which would compromise your plausible deniability.&lt;br /&gt;
&lt;br /&gt;
For the facade, we use an Ubuntu Live CD (or less skilled distro) to present the impression that we are not sophisticated or tech savvy enough to implement encryption.  Windows is also acceptable even better.  The immutable Live CD and immutable partition ensures that you are not compromised by a third party attacker that implants evidence.&lt;br /&gt;
&lt;br /&gt;
There could be possibly two bootloaders, one for the facade and the other to the encrypted drive stored on an external device.&lt;br /&gt;
&lt;br /&gt;
==== Luks ====&lt;br /&gt;
&lt;br /&gt;
Plausible deniability only works if you can demonstrate no existence of partitions 2, 3, 4 and no fingerprints/plaintext introduced by cfdisk and cryptsetup-luks.  Use something like TestDisk, fdisk -l, or gparted and a disk editor (hex editor for disks).&lt;br /&gt;
&lt;br /&gt;
{| cellpadding=&amp;quot;5&amp;quot; border=&amp;quot;1&amp;quot; class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!#&lt;br /&gt;
!Name&lt;br /&gt;
!Mount point&lt;br /&gt;
!Notes&lt;br /&gt;
|-&lt;br /&gt;
| 1&lt;br /&gt;
| facade&lt;br /&gt;
| /&lt;br /&gt;
| (optional) The facade partition contains a pristine normal operating system or Ubuntu Live CD image to lure the attacker in attempt to boost the confidence of the attacker convincing them that there is no encryption on the device.&lt;br /&gt;
|-&lt;br /&gt;
| 2&lt;br /&gt;
| swap&lt;br /&gt;
| &lt;br /&gt;
| It should be the same size as your ram for x86_64.  Rationale: it should contain the whole ram image.&lt;br /&gt;
|-&lt;br /&gt;
| 3&lt;br /&gt;
| root&lt;br /&gt;
| /&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
| 4&lt;br /&gt;
| rescue&lt;br /&gt;
| /&lt;br /&gt;
| This should contain the Alpine image.&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
==== Plain dm-crypt ====&lt;br /&gt;
&lt;br /&gt;
Plausible deniability only works if you are able to present #2 as being unused space or untampered.  To check use something like TestDisk, gparted and a disk editor (hex editor for disks).&lt;br /&gt;
&lt;br /&gt;
{| cellpadding=&amp;quot;5&amp;quot; border=&amp;quot;1&amp;quot; class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!#&lt;br /&gt;
!Name&lt;br /&gt;
!Mount point&lt;br /&gt;
!Notes&lt;br /&gt;
|-&lt;br /&gt;
| 1&lt;br /&gt;
| facade&lt;br /&gt;
| /&lt;br /&gt;
| (optional) The facade partition contains a pristine normal operating system or Ubuntu Live CD image to lure the attacker in attempt to boost the confidence of the attacker convincing them that there is no encryption on the device.&lt;br /&gt;
|-&lt;br /&gt;
| 2&lt;br /&gt;
| vgroot&lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
|-&lt;br /&gt;
| 2_1&lt;br /&gt;
| vgroot-root&lt;br /&gt;
| /&lt;br /&gt;
| &lt;br /&gt;
|-&lt;br /&gt;
| 2_2&lt;br /&gt;
| vgroot-swap&lt;br /&gt;
| &lt;br /&gt;
| It should be the same size as your ram for x86_64.  Rationale: it should contain the whole ram image.&lt;br /&gt;
|-&lt;br /&gt;
| 2_3&lt;br /&gt;
| vgroot-rescue&lt;br /&gt;
| /&lt;br /&gt;
| This should contain the Alpine image.&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== Installing cryptsetup ===&lt;br /&gt;
&lt;br /&gt;
To install cryptsetup you need the package below&lt;br /&gt;
&lt;br /&gt;
  apk add cryptsetup&lt;br /&gt;
&lt;br /&gt;
=== Choosing ciphers ===&lt;br /&gt;
&lt;br /&gt;
When you create your luks drives, you need to decide on the type of ciphers and hashing techniques to use.  The ciphers that you want to use are ones are up to you, but it should be one that is hasn&#039;t been cracked yet or has not suffered a lot of cryptanalysis attacks.  The ones that you might want to use is AES which is hardware accelerated in some Intel CPUs that have the AES-NI cpuflag which you can check by &amp;lt;code&amp;gt;cat /proc/cpuinfo&amp;lt;/code&amp;gt;.  Also consider the ciphers that are SIMD optimized such as serpent and twofish that are available in the Linux kernel.  Also consider ciphers that are unpopular but known to be secure such as Blowfish (which Wikipedia claims to be attacked and the author recommended Twofish).[https://en.wikipedia.org/wiki/Cipher_security_summary]  If it is hardware accelerated, it will save battery life and minimize CPU usage.&lt;br /&gt;
&lt;br /&gt;
For some ciphers weakness also see [https://en.wikipedia.org/wiki/Cipher_security_summary Cipher security summary (Wikipedia)].&lt;br /&gt;
&lt;br /&gt;
For some hash function weaknesses also see [https://en.wikipedia.org/wiki/Hash_function_security_summary Hash function security summary (Wikipedia)].&lt;br /&gt;
&lt;br /&gt;
Generally speaking, the swap partition should use a fast cipher.  You want to lower the latency or delay of the memory subsystem as a consequence of being encrypted.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;IMPORTANT:&#039;&#039;&#039; Please read the [[Setting_up_a_laptop#Important_notes | Important notes]] section for details about the problems with AES encryption.&lt;br /&gt;
&lt;br /&gt;
If you don&#039;t trust AES shills and endorsed by the NSA, you can try another different one.  Another advantage of using a public vetted cipher is that it provides confidence that it works.&lt;br /&gt;
&lt;br /&gt;
Something like KHAZAD wouldn&#039;t work on &amp;lt;code&amp;gt;cryptsetup benchmark&amp;lt;/code&amp;gt;.  KHAZAD itself is insecure.  Wikipedia reported 5 out of 8 rounds been cracked.[https://en.wikipedia.org/wiki/KHAZAD]&lt;br /&gt;
&lt;br /&gt;
For AES-128 7 out of 10, AES-192 8 out of 12, AES-256-bit 9 out 14 rounds have been cracked according to Wikipedia.[https://en.wikipedia.org/wiki/Advanced_Encryption_Standard]&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;IMPORTANT: Do not use sha1 as the hashing algorithm.&#039;&#039;&#039;  It already has already been compromised.&lt;br /&gt;
&lt;br /&gt;
=== Getting the available ciphers ===&lt;br /&gt;
&lt;br /&gt;
To check the availability of a cipher or hash function use:&lt;br /&gt;
  find $(find /lib/modules -name &amp;quot;crypto&amp;quot; -type d) -type f -name &amp;quot;*.ko&amp;quot; | sort&lt;br /&gt;
&lt;br /&gt;
To check if a cipher is loaded and passed its own tests use:&lt;br /&gt;
  cat /proc/crypto&lt;br /&gt;
&lt;br /&gt;
To test some popular ciphers and hashes do:&lt;br /&gt;
&lt;br /&gt;
  cryptsetup benchmark&lt;br /&gt;
&lt;br /&gt;
The top set is associated with the hashing algorithms.  The bottom set are the ciphers.  Use the commands below but replace the cipher and/or hash algorithm with your preferences.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;cryptsetup benchmark&amp;lt;/code&amp;gt; actually doesn&#039;t show all the ciphers like Anubis.  The cipher should also have CBC and/or XTS block cipher mode of operation to encrypt larger block sizes.  AES for example has a block size of 128.  &lt;br /&gt;
&lt;br /&gt;
To test if the unpopular but uncracked cipher works use sometime like:&lt;br /&gt;
  cryptsetup benchmark --cipher anubis&lt;br /&gt;
&lt;br /&gt;
=== General steps for cryptsetup ===&lt;br /&gt;
&lt;br /&gt;
==== Original method with fdisk with no plausible deniability ====&lt;br /&gt;
&lt;br /&gt;
In this method &amp;lt;code&amp;gt;--type luks&amp;lt;/code&amp;gt; is implied which generates metadata.&lt;br /&gt;
&lt;br /&gt;
If you want plausible deniability for luks, you need to pass &amp;lt;code&amp;gt;--header &amp;lt;path&amp;gt;&amp;lt;/code&amp;gt; to all the luks commands, where &amp;lt;code&amp;gt;&amp;lt;path&amp;gt;&amp;lt;/code&amp;gt; is a unix path like /mnt/usb/d6ae10eda66704c8.  The random name comes from &amp;lt;code&amp;gt;openssl rand -hex 8&amp;lt;/code&amp;gt;.  The header is transferred to the external device (but no mention of the key slot area but ciphertext being transferred) in the man page.  The information in that file should be obfuscated with encryption if there is plaintext or fingerprint in it just in case. Then, it should be decrypted when reused.&lt;br /&gt;
&lt;br /&gt;
You need to install cfdisk if you prefer the interactive ncurses console method:&lt;br /&gt;
&lt;br /&gt;
  apk add cfdisk&lt;br /&gt;
&lt;br /&gt;
{|| cellpadding=&amp;quot;5&amp;quot; border=&amp;quot;1&amp;quot; class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!#&lt;br /&gt;
!Step&lt;br /&gt;
!Command&lt;br /&gt;
|-&lt;br /&gt;
| 1&lt;br /&gt;
| Use cfdisk to create partitions.  Make two partitions--a system partition and a swap partition&lt;br /&gt;
| &amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;cfdisk&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| 2&lt;br /&gt;
| Create and format the luks device&lt;br /&gt;
| &amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;cryptsetup --cipher aes-cbc-essiv:sha256 --key-size 256 luksFormat /dev/sda1 /mnt/usb/$(ls)&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| 3&lt;br /&gt;
| Open the luks device&lt;br /&gt;
| &amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;cryptsetup --key-file /mnt/usb/$(ls) luksOpen /dev/sda1 root&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| 4&lt;br /&gt;
| Format the decrypted drive with filesystem&lt;br /&gt;
| &amp;lt;code&amp;gt;mkfs.ext4 /dev/mapper/root&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| 5&lt;br /&gt;
| Create the mount point&lt;br /&gt;
| &amp;lt;code&amp;gt;mkdir -p /mnt/root&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| 6&lt;br /&gt;
| Mount the root partition&lt;br /&gt;
| &amp;lt;code&amp;gt;mount /dev/mapper/root /mnt/root&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| 7&lt;br /&gt;
| Create swap&lt;br /&gt;
| cryptsetup -c blowfish -h sha256 -d /dev/urandom --key-file /mnt/usb/59022506d9f4a714 create swap /dev/sda2 &lt;br /&gt;
|-&lt;br /&gt;
| 8&lt;br /&gt;
| Use swap&lt;br /&gt;
| mkswap /dev/mapper/swap &amp;amp;&amp;amp; swapon /dev/mapper/swap&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
==== Improved method with plausible deniability ====&lt;br /&gt;
&lt;br /&gt;
This method requires lvm2.  To install:&lt;br /&gt;
&lt;br /&gt;
  apk add lvm2&lt;br /&gt;
&lt;br /&gt;
{|| cellpadding=&amp;quot;5&amp;quot; border=&amp;quot;1&amp;quot; class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!#&lt;br /&gt;
!Step&lt;br /&gt;
!Command&lt;br /&gt;
|-&lt;br /&gt;
| 1&lt;br /&gt;
| Open the &#039;&#039;plain dm-crypt&#039;&#039; device generating no metadata&lt;br /&gt;
| &amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;cryptsetup open --type plain --cipher aes-cbc-essiv:sha256 --key-size 256 --key-file /mnt/usb/$(ls) /dev/sda pvroot&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| 2&lt;br /&gt;
| Physical volume create with LVM&lt;br /&gt;
| &amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;pvcreate /dev/mapper/pvroot&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| 3&lt;br /&gt;
| Volume group create with LVM&lt;br /&gt;
| &amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;vgcreate vgroot /dev/mapper/pvroot&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| 4&lt;br /&gt;
| Logical volume create the swap volume with LVM&lt;br /&gt;
| &amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;lvcreate -L 4G vgroot -n swap&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| 5&lt;br /&gt;
| Logical volume create the root volume with LVM&lt;br /&gt;
| &amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;lvcreate -L 2T vgroot -n root&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| 6&lt;br /&gt;
| Logical volume create the rescue volume with LVM&lt;br /&gt;
| &amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;lvcreate -L 110M vgroot -n rescue&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| 7&lt;br /&gt;
| Format the root volume with filesystem&lt;br /&gt;
| &amp;lt;code&amp;gt;mkfs.ext4 /dev/mapper/vgroot-root&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| 8&lt;br /&gt;
| Format the swap volume and activate it&lt;br /&gt;
| &amp;lt;code&amp;gt;mkswap /dev/mapper/vgroot-swap &amp;amp;&amp;amp; swapon /dev/mapper/vgroot-swap&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| 9&lt;br /&gt;
| Format the rescue volume with filesystem&lt;br /&gt;
| &amp;lt;code&amp;gt;mkfs.ext4 /dev/mapper/vgroot-rescue&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| 10&lt;br /&gt;
| Create mount point for root volume&lt;br /&gt;
| &amp;lt;code&amp;gt;mkdir -p /mnt/root&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| 11&lt;br /&gt;
| Mount the root volume&lt;br /&gt;
| &amp;lt;code&amp;gt;mount /dev/mapper/vgroot-root /mnt/root&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== Configuring OpenRC dmcrypt and setting up fstab ===&lt;br /&gt;
&lt;br /&gt;
You need to tell OpenRC init scripts to decrypt the volumes.  See &amp;lt;code&amp;gt;/etc/conf.d/dmcrypt&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
You need to add the service to boot well because it needs to decrypt the root volume before OpenRC starts running commands from it.  So you need to do:&lt;br /&gt;
&lt;br /&gt;
  rc-update add dmcrypt boot&lt;br /&gt;
&lt;br /&gt;
==== /etc/init.d/dmcrypt ====&lt;br /&gt;
The dmcrypt OpenRC service will attempt to decrypt the drive using information provided in &#039;&#039;/etc/conf.d/dmcrypt&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
For &#039;&#039;luks&#039;&#039;:&lt;br /&gt;
&lt;br /&gt;
{{Cat|/etc/conf.d/dmcrypt|&amp;lt;nowiki&amp;gt;&lt;br /&gt;
  # Mounting root may not be necessary since it is already mounted.&lt;br /&gt;
  target=root&lt;br /&gt;
  source=&#039;/dev/sda1&#039;&lt;br /&gt;
  key=&#039;/mnt/usb/2a667ec72774b0d5&#039;&lt;br /&gt;
&lt;br /&gt;
  swap=swap&lt;br /&gt;
  source=&#039;/dev/sda2&#039;&lt;br /&gt;
  key=&#039;/mnt/usb/59022506d9f4a714&#039;&lt;br /&gt;
&amp;lt;/nowiki&amp;gt;}}&lt;br /&gt;
&lt;br /&gt;
For &#039;&#039;plain dm-crypt&#039;&#039;:&lt;br /&gt;
&lt;br /&gt;
{{Cat|/etc/conf.d/dmcrypt|&amp;lt;nowiki&amp;gt;&lt;br /&gt;
  # Mounting root is likely not required since you already mounted it before OpenRC starts to do its thing.&lt;br /&gt;
  target=root&lt;br /&gt;
  source=&#039;/dev/sda&#039;&lt;br /&gt;
  key=&#039;/mnt/usb/2a667ec72774b0d5&#039;&lt;br /&gt;
  options=&#039;--type plain --cipher aes-cbc-essiv:sha256 --key-size 256&#039;&lt;br /&gt;
&lt;br /&gt;
  swap=swap&lt;br /&gt;
  source=&#039;/dev/sda2&#039;&lt;br /&gt;
  key=&#039;/mnt/usb/59022506d9f4a714&#039;&lt;br /&gt;
  pre_mount=&#039;vgchange -ay vgroot ; lvchange -ay vgroot/swap&#039;&lt;br /&gt;
&amp;lt;/nowiki&amp;gt;}}&lt;br /&gt;
&lt;br /&gt;
dm-crypt will just mount the encrypted &#039;&#039;plain dm-crypt&#039;&#039; drive or the &#039;&#039;luks&#039;&#039; partition.  What you need to do next is set up fstab located at /etc/fstab.  Examples are shown below.&lt;br /&gt;
&lt;br /&gt;
==== /etc/fstab ====&lt;br /&gt;
&lt;br /&gt;
To mount &#039;&#039;plain dm-crypt&#039;&#039; device with fstab:&lt;br /&gt;
&lt;br /&gt;
{{Cat|/etc/fstab|&lt;br /&gt;
  /dev/sdb                  /boot	ext4	defaults  0 0&lt;br /&gt;
  /dev/mapper/root          /		ext4	defaults  0 1&lt;br /&gt;
  /dev/mapper/swap          none	swap	sw        0 0&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
To mount &#039;&#039;lvm&#039;&#039; volumes with fstab:&lt;br /&gt;
&lt;br /&gt;
{{Cat|/etc/fstab|&lt;br /&gt;
  /dev/sdb                  /boot	ext4	defaults  0 0&lt;br /&gt;
  /dev/mapper/vgroot-root   /		ext4	defaults  0 1&lt;br /&gt;
  /dev/mapper/vgroot-swap   none	swap	sw        0 0&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
=== How to recover from a bad setup ===&lt;br /&gt;
&lt;br /&gt;
Many times you will not get it right perfectly the first try.  To recover from this situation, you need to reopen the &#039;&#039;plain dm-crypt&#039;&#039; drive or the &#039;&#039;luks&#039;&#039; drive and then remount everything back.&lt;br /&gt;
&lt;br /&gt;
To recover from &#039;&#039;luks&#039;&#039;:&lt;br /&gt;
  cryptsetup --key-file /mnt/usb/2a667ec72774b0d5 luksOpen /dev/sda1 root&lt;br /&gt;
  mkdir -p /mnt/root&lt;br /&gt;
  mount /dev/mapper/root /mnt/root&lt;br /&gt;
&lt;br /&gt;
To recover from the &#039;&#039;plain dm-crypt&#039;&#039;:&lt;br /&gt;
  cryptsetup open --type plain --cipher aes-cbc-essiv:sha256 --key-size 256 --key-file /mnt/usb/$(ls) /dev/sda root&lt;br /&gt;
  vgchange -ay vgroot&lt;br /&gt;
  lvchange -ay vgroot/root&lt;br /&gt;
  mkdir -p /mnt/root&lt;br /&gt;
  mount /dev/mapper/vgroot-swap /mnt/root&lt;br /&gt;
&lt;br /&gt;
== Next step: Full blown Alpine installation ==&lt;br /&gt;
&lt;br /&gt;
We will setup the /mnt/root encrypted partition:&lt;br /&gt;
  apk add --root=/mnt/root --initdb $(cat /etc/apk/world)&lt;br /&gt;
&lt;br /&gt;
Then, enable edge repositories in both files including community and testing:&lt;br /&gt;
  nano /etc/apk/repositories /mnt/root/etc/apk/repositories&lt;br /&gt;
&lt;br /&gt;
Then, copy the necessary files:&lt;br /&gt;
  cp /etc/resolv.conf /mnt/root/etc&lt;br /&gt;
&lt;br /&gt;
Then, install the basic utils:&lt;br /&gt;
  apk add --root=/mnt/root dhcpcd chrony networkmanager wireless-tools wpa_supplicant&lt;br /&gt;
  apk add --root=/mnt/root grub mkinitfs e2fsprogs grub-bios grub-efi&lt;br /&gt;
  apk add --root=/mnt/root sudo nano&lt;br /&gt;
  apk add --root=/mnt/root linux-lts&lt;br /&gt;
&lt;br /&gt;
Then, you need to mount your usb on to /boot:&lt;br /&gt;
  mount /dev/sdb /boot&lt;br /&gt;
&lt;br /&gt;
Edit grub:&lt;br /&gt;
  nano /boot/grub/grub.cfg&lt;br /&gt;
&lt;br /&gt;
Then, install grub on the usb:&lt;br /&gt;
  grub-install --force /dev/sdb&lt;br /&gt;
&lt;br /&gt;
Then, prepare chroot:&lt;br /&gt;
  mount --bind /dev /mnt/root/dev&lt;br /&gt;
  mount --bind /sys /mnt/root/sys&lt;br /&gt;
  cp /etc/reslov.conf /mnt/root/etc&lt;br /&gt;
&lt;br /&gt;
Then, chroot:&lt;br /&gt;
  chroot /mnt/root /bin/sh&lt;br /&gt;
&lt;br /&gt;
Set the root administrator password:&lt;br /&gt;
  passwd&lt;br /&gt;
&lt;br /&gt;
The root password should be very difficult to deter you from using it and force you to use sudo&lt;br /&gt;
&lt;br /&gt;
Edit sudo so that wheel group has administrative :&lt;br /&gt;
  EDITOR=nano visudo&lt;br /&gt;
&lt;br /&gt;
Set:&lt;br /&gt;
  ## Uncomment to allow members of group wheel to execute any command       &lt;br /&gt;
  %wheel ALL=(ALL) ALL                                                 &lt;br /&gt;
&lt;br /&gt;
Then, add wheel (administrator) user:&lt;br /&gt;
  useradd -m myname&lt;br /&gt;
  usermod -a -G video,audio,wheel myname&lt;br /&gt;
&lt;br /&gt;
log in that user:&lt;br /&gt;
  su myname&lt;br /&gt;
&lt;br /&gt;
Then, update and upgrade it&lt;br /&gt;
  sudo apk update&lt;br /&gt;
  sudo apk upgrade&lt;br /&gt;
&lt;br /&gt;
Then, setup xorg:&lt;br /&gt;
  sudo setup-xorg-base&lt;br /&gt;
  sudo apk search xf86-video | sort&lt;br /&gt;
  # pick your video driver&lt;br /&gt;
  sudo apk add xf86-video-adi&lt;br /&gt;
  # pick your opengl driver&lt;br /&gt;
  sudo apk search mesa-dri* | sort&lt;br /&gt;
  sudo apk add mesa-dri-ati  &lt;br /&gt;
&lt;br /&gt;
Then, keep piling on:&lt;br /&gt;
  sudo apk add firefox dwm xfce4-terminal alsa-utils keepassx xfce4 xchat&lt;br /&gt;
  sudo apk add font-noto-emoji terminus-font leafpad xsetroot # See [[Emojis]] to complete installation&lt;br /&gt;
  sudo apk add xf86-input-mouse xf86-input-keyboard&lt;br /&gt;
&lt;br /&gt;
Then, set the desktop:&lt;br /&gt;
  nano .xinitrc&lt;br /&gt;
&lt;br /&gt;
Put both but comment with a # one of them if you don&#039;t want it,&lt;br /&gt;
  #while true; do xsetroot -name &amp;quot;$( date +&amp;quot;%a %b %d %I:%M:%S %Y&amp;quot; )&amp;quot; ; sleep 1; done &amp;amp;&lt;br /&gt;
  #exec dwm&lt;br /&gt;
  exec xfce4-session&lt;br /&gt;
&lt;br /&gt;
For the above xsetroot statement used to provide information in the statusbar for dwm, consider adding information about the battery level.  This information can be found in sysfs at /sys/class/power_supply/BAT0/.&lt;br /&gt;
&lt;br /&gt;
  sync&lt;br /&gt;
  sudo reboot&lt;br /&gt;
&lt;br /&gt;
== Hacking mkinitfs to support cryptsetup with GPG keys ==&lt;br /&gt;
&lt;br /&gt;
This section describes how to assemble a custom initscript chain in multiple parts.  It could be extended with three-factor authentication which adds biometrics along side with mind and physical object.&lt;br /&gt;
&lt;br /&gt;
Most entry to secure systems are not fully automated or do not allow things to quickly pass through freely and often guarded.  This process may seem like a hassle, but it should dissuade the rubberhosers from jumping to the conclusion of the possibility of the existence of a encrypted drive.&lt;br /&gt;
&lt;br /&gt;
Here is the steps required so that the facade initscripts and dependencies are free from encryption.&lt;br /&gt;
* You will separate and archive cryptsetup, ciphers kernel modules, hash function kernel modules, and any additional obfuscation dependencies, and another continuation initscript discussed below.  You need to make sure that you copy /etc/mkinitfs/mkinitfs.conf to your home directory and strip out those features without those modules.&lt;br /&gt;
* You will hide this archive in a mp3 file with another tool you will package or you can use steghide&#039;s .au/.wav support, but .au seems too conspicuous or strange by current trends.&lt;br /&gt;
&lt;br /&gt;
Here we try to clean up the facade so that it presents itself as free without cryptography.  You need the following changes to your initramfs to avoid a sensitive rubberhoser:&lt;br /&gt;
* You will delete everything in the custom initramfs-init referring to encryption.  This includes cryptroot, cryptdm, crypt-anything, etc init options.&lt;br /&gt;
* You need to delete references in nlplug-findfs to cryptsetup and recompile the mkinitfs package.&lt;br /&gt;
* You could program the init script to boot into a facade partition but drop into sh if a hidden special keypress sequence is met.&lt;br /&gt;
&lt;br /&gt;
You need to create a custom init continuation script:&lt;br /&gt;
* Your initscript should drop into single mode which you will mount the encrypted path manually. &lt;br /&gt;
* You will manually steg-unhide the encrypted archive hidden in the mp3 file and extract it to the ramdisk.&lt;br /&gt;
* You will run the custom init continuation script manually.&lt;br /&gt;
* This custom init continuation will automate the process of extracting the gpg keys from another device and image files into the ramdisk.  This will then automate the mounting of the encrypted drive.  This resume continuation script should handle both cold boot and hibernate.&lt;br /&gt;
* You will finish resuming running the other half of mkinitfs-init or specifically where the points after where it typically will mount cryptsetup and hibernate devices.&lt;br /&gt;
&lt;br /&gt;
If you use a USB keyboard, you will unlock the encrypted devices in early userspace. You will need to either compile the USB keyboard drivers in the kernel or you need to add additional modules when generating the mkinitfs.  You will need the hid, hid-generic, ehci-hcd, uhci-hcd, usbcore driver and add those paths in a customized &amp;lt;code&amp;gt;/etc/mkinitfs/features.d/usb-keyboard.modules&amp;lt;/code&amp;gt;.  It should be separate from usb.modules because apk updates may overwrite it.  Use the &amp;lt;code&amp;gt;lsmod&amp;lt;/code&amp;gt; utility from the kmod package to find what drivers your USB keyboard uses.&lt;br /&gt;
&lt;br /&gt;
You need to generate the final mkinitfs.&lt;br /&gt;
First you need the kernelversion to pass into mkinitfs.  To obtain that information do &amp;lt;code&amp;gt;ls /lib/modules&amp;lt;/code&amp;gt; which will show some folders.  Once you found it pass it to mkinitrafs by doing and replacing kernelversion below:&lt;br /&gt;
&lt;br /&gt;
  sudo mkinitramfs -i $HOMEDIR/initramfs-init -c &amp;quot;$HOMEDIR&amp;quot;/mkinitfs.conf kernelversion&lt;br /&gt;
&lt;br /&gt;
The $HOMEDIR should be replaced with the full path if you are not root.&lt;br /&gt;
&lt;br /&gt;
==  Install the bootloader in the USB thumb drive ==&lt;br /&gt;
&lt;br /&gt;
To install grub, you need to install grub on the ramdisk first on the host.  &lt;br /&gt;
&lt;br /&gt;
  apk add grub&lt;br /&gt;
&lt;br /&gt;
To get a list of partitions&lt;br /&gt;
&lt;br /&gt;
  fdisk -l&lt;br /&gt;
&lt;br /&gt;
Mount the boot partition in /boot&lt;br /&gt;
&lt;br /&gt;
  mount /dev/sdb /boot&lt;br /&gt;
&lt;br /&gt;
Make changes to grub&#039;s configuration &lt;br /&gt;
&lt;br /&gt;
  nano /boot/grub/grub.cfg&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;You need to customize the initramfs in order to use GPG keys since there is no support from it.&#039;&#039;&#039;  &lt;br /&gt;
&lt;br /&gt;
The steps here below assumes that these custom initramfs features have been implemented.  &lt;br /&gt;
&lt;br /&gt;
The following boot loader settings is &#039;&#039;&#039;not sufficient&#039;&#039;&#039; for deniable encryption because it exposes the fact that an encrypted drive exists because an attacker can discover that encryption was used through the edit option of the grub menu.  To protect yourself from a rubberhose attack, you really need to customize the initramfs so that references to anything mentioning encryption, ciphers, hashing are not explicitly mentioned.  These configurations should be considered an intermediate form for used in debugging purposes.  In addition, the attacker just can inspect grub.cfg files directly.&lt;br /&gt;
&lt;br /&gt;
The following are just examples to just get it working but should be modified so that it doesn&#039;t hint to the rubberhoser of a hidden partition or encrypted partitions.&lt;br /&gt;
&lt;br /&gt;
The entry should look like:&lt;br /&gt;
&lt;br /&gt;
For &#039;luks&#039;&lt;br /&gt;
&lt;br /&gt;
{{cat|/boot/grub/grub.cfg|&amp;lt;nowiki&amp;gt;&lt;br /&gt;
default=0&lt;br /&gt;
timeout=0&lt;br /&gt;
&lt;br /&gt;
menuentry &#039;Windows 10&#039; {&lt;br /&gt;
	set root=(hd0,2)&lt;br /&gt;
        chainloader +1&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
menuentry &#039;Alpine Linux&#039; {&lt;br /&gt;
	set root=(hd1,1)&lt;br /&gt;
	linux /vmlinuz-hardened root=/dev/mapper/root rw modules=sd-mod,usb-storage,ext4,dm-crypt,aes-x86_64,sha256-mb cryptroot=/dev/sda1 cryptdm=root&lt;br /&gt;
	initrd /initramfs-hardened&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
menuentry &#039;Alpine Linux (Rescue)&#039; {&lt;br /&gt;
	set root=(hd1,1)&lt;br /&gt;
	linux /vmlinuz-hardened root=/dev/mapper/root rw modules=sd-mod,usb-storage,ext4,dm-crypt,aes-x86_64,sha256-mb cryptroot=/dev/sda4 cryptdm=root&lt;br /&gt;
	initrd /initramfs-hardened&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
if keystatus; then&lt;br /&gt;
  if keystatus --ctrl; then&lt;br /&gt;
    set timeout=-1&lt;br /&gt;
  else&lt;br /&gt;
    set timeout=0&lt;br /&gt;
  fi&lt;br /&gt;
fi&lt;br /&gt;
&amp;lt;/nowiki&amp;gt;}}&lt;br /&gt;
&lt;br /&gt;
For &#039;plain dm-crypt&#039;:&lt;br /&gt;
&lt;br /&gt;
The stock mkinitfs may not support plain dm-crypt.  It looks like it only supports luks.  Customization of the initramfs is required.&lt;br /&gt;
&lt;br /&gt;
{{cat|/boot/grub/grub.cfg|&amp;lt;nowiki&amp;gt;&lt;br /&gt;
default=0&lt;br /&gt;
timeout=0&lt;br /&gt;
&lt;br /&gt;
menuentry &#039;Windows 10&#039; {&lt;br /&gt;
	set root=(hd0,2)&lt;br /&gt;
        chainloader +1&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
menuentry &#039;Alpine Linux&#039; {&lt;br /&gt;
	set root=(hd1,1)&lt;br /&gt;
	linux /vmlinuz-hardened root=/dev/mapper/vgroot-root rw modules=sd-mod,usb-storage,ext4,dm-crypt,dm-mod,dm-snapshot,aes-x86_64,sha256-mb cryptroot=/dev/sda cryptdm=root&lt;br /&gt;
	initrd /initramfs-hardened&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
menuentry &#039;Alpine Linux (Rescue)&#039; {&lt;br /&gt;
	set root=(hd1,1)&lt;br /&gt;
	linux /vmlinuz-hardened root=/dev/mapper/vgroot-rescue rw modules=sd-mod,usb-storage,ext4,dm-crypt,dm-mod,dm-snapshot,aes-x86_64,sha256-mb cryptroot=/dev/sda cryptdm=rescue&lt;br /&gt;
	initrd /initramfs-hardened&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
if keystatus; then&lt;br /&gt;
  if keystatus --ctrl; then&lt;br /&gt;
    set timeout=-1&lt;br /&gt;
  else&lt;br /&gt;
    set timeout=0&lt;br /&gt;
  fi&lt;br /&gt;
fi&lt;br /&gt;
&amp;lt;/nowiki&amp;gt;}}&lt;br /&gt;
&lt;br /&gt;
The source code of grub could possibly be modified and recompiled to use other non-standard keys.  See [https://github.com/lemenkov/grub2/blob/master/grub-core/commands/keystatus.c].  Ideally, it should be not so obvious or accessible for the attacker.&lt;br /&gt;
&lt;br /&gt;
The above grub.cfg is applied to the USB bootloader.  For the facade bootloader, you just want the Windows 10 or Ubuntu entry, nothing more.&lt;br /&gt;
&lt;br /&gt;
For the modules parameter, you need to add your crypto modules.&lt;br /&gt;
Use &amp;lt;code&amp;gt;find /lib/modules/ -name &amp;quot;*aes*&amp;quot;&amp;lt;/code&amp;gt; where aes is the basename for your cipher or hash algorithm&lt;br /&gt;
Use &amp;lt;code&amp;gt;blkid&amp;lt;/code&amp;gt; to obtain the UUID of your device&lt;br /&gt;
&lt;br /&gt;
Install it to your USB thumb drive&lt;br /&gt;
&lt;br /&gt;
  grub-install /dev/sdb&lt;br /&gt;
&lt;br /&gt;
== Home mounting with eCryptfs ==&lt;br /&gt;
&lt;br /&gt;
We use eCryptfs to encrypt home.  The rationale for having another encrypted file system is that if you leave your laptop unattended on break or accidentally leave your USB key in, your data will not be accessible.  The other rationale is that if another person wants to use your computer, you can just log off and the data will be kept hidden and encrypted.  When you log off due to inactivity, your home directory will be unmounted and encrypted.  eCryptfs will encrypt/decrypt the filename and the contents and will sit on top of ext4 which sits on top of luks.&lt;br /&gt;
&lt;br /&gt;
To install ecryptfs-utils:&lt;br /&gt;
&lt;br /&gt;
  sudo apk add ecryptfs-utils&lt;br /&gt;
&lt;br /&gt;
This does one factor authentication mostly with just the password, but it should be modified to use the USB key too.  You need to reconfigure pam with the pam_usb.so which is not in Alpine aports.&lt;br /&gt;
&lt;br /&gt;
You need to use the pam_ecryptfs PAM module.&lt;br /&gt;
&lt;br /&gt;
== Locking it down ==&lt;br /&gt;
&lt;br /&gt;
Many times you will leave your laptop behind with people you trust.  The following tools will help lock down the system.&lt;br /&gt;
&lt;br /&gt;
=== physlock ===&lt;br /&gt;
&lt;br /&gt;
This will auto lock the tty and when you return will prompt for password.&lt;br /&gt;
&lt;br /&gt;
To install physlock:&lt;br /&gt;
&lt;br /&gt;
  sudo apk add physlock&lt;br /&gt;
&lt;br /&gt;
It is currently bugged.  See [https://bugs.alpinelinux.org/issues/3282].  physlock likely doesn&#039;t do two-factor authentication but it should.&lt;br /&gt;
&lt;br /&gt;
You need to create custom script that will monitor idle time in TTY then call physlock.  You load this script when you log on.&lt;br /&gt;
&lt;br /&gt;
=== xscreensaver ===&lt;br /&gt;
&lt;br /&gt;
This will lock you out of xserver&lt;br /&gt;
&lt;br /&gt;
To install xscreensaver:&lt;br /&gt;
&lt;br /&gt;
  sudo apk add xscreensaver&lt;br /&gt;
&lt;br /&gt;
=== USB key udev rule ===&lt;br /&gt;
&lt;br /&gt;
You need to add a new udev rule that will suspend-to-ram or hibernate and log off once you pull the USB key.  When you come back on, you should do 2 factor authentication to restore back everything.  Hibernation and suspend-to-ram might mitigate cold-boot attack (but unlikely see notes at the bottom of the page) to extract plaintext private data and encryption keys in memory.&lt;br /&gt;
&lt;br /&gt;
To find out the details of your USB do:&lt;br /&gt;
&lt;br /&gt;
  udevadm monitor --udev -p&lt;br /&gt;
&lt;br /&gt;
The output should look like:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
UDEV  [181762.722853] add      /devices/pci0000:00/0000:00:13.2/usb2/2-5/2-5:1.0/host6/target6:0:0/6:0:0:0/block/sdc (block)&lt;br /&gt;
ACTION=add&lt;br /&gt;
DEVLINKS=/dev/disk/by-id/usb-Kingston_MSFT_NORB_MSFTLAKDA300EB3021790009-0:0 /dev/disk/by-path/pci-0000:00:13.2-usb-0:5:1.0-scsi-0:0:0:0 /dev/disk/by-uuid/5A96-03E4&lt;br /&gt;
DEVNAME=/dev/sdc&lt;br /&gt;
DEVPATH=/devices/pci0000:00/0000:00:13.2/usb2/2-5/2-5:1.0/host6/target6:0:0/6:0:0:0/block/sdc&lt;br /&gt;
DEVTYPE=disk&lt;br /&gt;
ID_BUS=usb&lt;br /&gt;
ID_FS_TYPE=vfat&lt;br /&gt;
ID_FS_USAGE=filesystem&lt;br /&gt;
ID_FS_UUID=5A96-03E4&lt;br /&gt;
ID_FS_UUID_ENC=5A96-03E4&lt;br /&gt;
ID_FS_VERSION=FAT32&lt;br /&gt;
ID_INSTANCE=0:0&lt;br /&gt;
ID_MODEL=MSFT_NORB&lt;br /&gt;
ID_MODEL_ENC=MSFT\x20NORB\x20\x20\x20\x20\x20\x20\x20&lt;br /&gt;
ID_MODEL_ID=1645&lt;br /&gt;
ID_PATH=pci-0000:00:13.2-usb-0:5:1.0-scsi-0:0:0:0&lt;br /&gt;
ID_PATH_TAG=pci-0000_00_13_2-usb-0_5_1_0-scsi-0_0_0_0&lt;br /&gt;
ID_REVISION=PMAP&lt;br /&gt;
ID_SERIAL=Kingston_MSFT_NORB_MSFTLAKDA300EB3021790009-0:0&lt;br /&gt;
ID_SERIAL_SHORT=MSFTLAKDA300EB3021790009&lt;br /&gt;
ID_TYPE=disk&lt;br /&gt;
ID_USB_DRIVER=usb-storage&lt;br /&gt;
ID_USB_INTERFACES=:080650:&lt;br /&gt;
ID_USB_INTERFACE_NUM=00&lt;br /&gt;
ID_VENDOR=Kingston&lt;br /&gt;
ID_VENDOR_ENC=Kingston&lt;br /&gt;
ID_VENDOR_ID=0951&lt;br /&gt;
MAJOR=8&lt;br /&gt;
MINOR=32&lt;br /&gt;
SEQNUM=2027&lt;br /&gt;
SUBSYSTEM=block&lt;br /&gt;
USEC_INITIALIZED=1762722168&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
You want to extract the &amp;lt;code&amp;gt;ID_SERIAL_SHORT=MSFTLAKDA300EB3021790009&amp;lt;/code&amp;gt; or whatever is associated with your USB thumb drive.&lt;br /&gt;
&lt;br /&gt;
You need pm-utils for ps-suspend.  So to install it do:&lt;br /&gt;
&lt;br /&gt;
  sudo apk add pm-utils&lt;br /&gt;
&lt;br /&gt;
You will create a udev rules so that when you pull out the USB, it will suspend-to-ram or you can use your own script.  To do that create a file with the following contents:&lt;br /&gt;
&lt;br /&gt;
{{Cat|/etc/udev/rules.d/50-usb-thumb-drive.rules|&amp;lt;nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
ACTION==&amp;quot;remove&amp;quot;, SUBSYSTEM==&amp;quot;usb&amp;quot;, ENV{ID_SERIAL_SHORT}==&amp;quot;MSFTLAKDA300EB3021790009&amp;quot;, RUN+=&amp;quot;/usr/sbin/pm-suspend&amp;quot;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/nowiki&amp;gt;}}&lt;br /&gt;
&lt;br /&gt;
== Extending battery life ==&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;WARNING: If you do not use the proper mitigation for cold boot attack, you are better off auto-shutdowning the laptop instead of using suspend or hibernate.&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
=== ACPI ===&lt;br /&gt;
&lt;br /&gt;
ACPI is a good daemon to use to execute certain scripts when laptop events are triggered.&lt;br /&gt;
&lt;br /&gt;
To install ACPI do:&lt;br /&gt;
&lt;br /&gt;
  apk add acpi&lt;br /&gt;
&lt;br /&gt;
The events to pay attention to are:&lt;br /&gt;
&lt;br /&gt;
{|  cellpadding=&amp;quot;5&amp;quot; border=&amp;quot;1&amp;quot; class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Event&lt;br /&gt;
! ACPI Event&lt;br /&gt;
! What your script should do&lt;br /&gt;
|-&lt;br /&gt;
| lid close&lt;br /&gt;
|&lt;br /&gt;
| log off ttys and suspend-to-ram.  ALSA should either set the volume to 0 for the sound card or the sound driver be unloaded.  It might be a good idea to kill or mute any music or movie players if the sound loops loudly after lid open.&lt;br /&gt;
|-&lt;br /&gt;
| lid open&lt;br /&gt;
|&lt;br /&gt;
| lock all ttys and all xservers should be locked, possibly reinitialize ALSA and the sound system.&lt;br /&gt;
|-&lt;br /&gt;
| tapped power button&lt;br /&gt;
|&lt;br /&gt;
| lock all ttys and suspend-to-ram&lt;br /&gt;
|-&lt;br /&gt;
| held power button&lt;br /&gt;
|&lt;br /&gt;
| hibernate&lt;br /&gt;
|-&lt;br /&gt;
| unplugged power&lt;br /&gt;
|&lt;br /&gt;
| should switch to &#039;conservative&#039; cpufreq governor at above 25% power ; &#039;powersave&#039; governor at 25%.  set hdparam spindown rate lower.&lt;br /&gt;
|-&lt;br /&gt;
| plugged power&lt;br /&gt;
|&lt;br /&gt;
| should switch to &#039;performance&#039; governor.  disable hdparam spindown.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
The purpose of the power governor is to regulate the running frequency (GHz) of the processor.&lt;br /&gt;
&lt;br /&gt;
Certain event handlers are are managed through laptop-mode-tools.  If you don&#039;t want the dependency, then you could write ACPI handler scripts.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;acpi_listen&amp;lt;/code&amp;gt; can be used to retrieve the event name.&lt;br /&gt;
&lt;br /&gt;
TODO: put scripts below&lt;br /&gt;
&lt;br /&gt;
=== Adjusting the backlight dynamically ===&lt;br /&gt;
&lt;br /&gt;
The backlight may be controlled using sysfs.  The setting is a descendant of &amp;lt;code&amp;gt;/sys/class/backlight/&amp;lt;/code&amp;gt;.  The feature may allow you to echo a value to it.  Use trial and error to discover the values.&lt;br /&gt;
&lt;br /&gt;
The adjustment of the backlight should be function of battery life.  So if it is like 33% battery life, you want to run it near lowest settings but readable.  For 50 percent battery energy maybe 40% light.  For 90% battery maybe 75% light.&lt;br /&gt;
&lt;br /&gt;
=== hdparm ===&lt;br /&gt;
&lt;br /&gt;
To install hdparam do:&lt;br /&gt;
&lt;br /&gt;
  sudo apk add hdparm&lt;br /&gt;
&lt;br /&gt;
The settings that laptop-mode-tools messes with is the &amp;lt;code&amp;gt;-S&amp;lt;/code&amp;gt; or the spindown timeout.  It was also hinted that acoustic setting &amp;lt;code&amp;gt;-M&amp;lt;/code&amp;gt; is associated with the speed meaning that louder is faster and quieter is slower which could contribute to the amount of energy used or reduced.&lt;br /&gt;
&lt;br /&gt;
Again you want something like laptop-mode-tools or ACPI to dynamically adjust the settings based on ACPI events.&lt;br /&gt;
&lt;br /&gt;
=== laptop-mode-tools ===&lt;br /&gt;
&lt;br /&gt;
This is currently not in aports but worthy mentioning.  It should really be packaged.  This is a set of scripts to define a power policies.  You can manage all the settings in one place here like the hard drive idle spindown time, CPU governor control, dynamic LCD backlight behavior based on running on battery or AC power supply.&lt;br /&gt;
&lt;br /&gt;
=== cpufreqd ===&lt;br /&gt;
&lt;br /&gt;
This is a useful daemon for regulating power.&lt;br /&gt;
&lt;br /&gt;
To install cpufreqd do:&lt;br /&gt;
&lt;br /&gt;
  sudo apk add cpufreqd&lt;br /&gt;
&lt;br /&gt;
Make sure you add the service:&lt;br /&gt;
&lt;br /&gt;
  sudo rc-update add cpufreqd&lt;br /&gt;
&lt;br /&gt;
=== LCD screen refresh rate ===&lt;br /&gt;
&lt;br /&gt;
The refresh rate sets the maximum framerate.  The more frames pushed the more energy consumed on the battery.  You want this adjusted dynamically per certain events.  For gaming, you want it to be the highest as possible for the laptop and vsync off.  For battery use and traveling, you want it capped at 60 FPS/60 Hz or lower but dynamically adjust when you plug in the AC power supply.  You can adjust the framerate with xrandr.  For movies and YouTube, you want 60FPS and vsync on.&lt;br /&gt;
&lt;br /&gt;
== Hacking the kernel ==&lt;br /&gt;
&lt;br /&gt;
You should refer to the [[Custom Kernel]] page for details.&lt;br /&gt;
&lt;br /&gt;
== Hibernation ==&lt;br /&gt;
&lt;br /&gt;
See [[Custom_Kernel#Hibernation_to_prevent_data_loss|Hibernation to prevent data loss]].&lt;br /&gt;
&lt;br /&gt;
== WiFi management ==&lt;br /&gt;
&lt;br /&gt;
Since you are using WiFi, you need a better WiFi management to quickly find open access WiFi access points.  We don&#039;t have all day to debug complexities of WiFi settings while away from home.&lt;br /&gt;
&lt;br /&gt;
To install NetworkManager do:&lt;br /&gt;
&lt;br /&gt;
  sudo apk add networkmanager&lt;br /&gt;
&lt;br /&gt;
To find WiFi access points use the &amp;lt;code&amp;gt;nmtui&amp;lt;/code&amp;gt; ncurses interface.&lt;br /&gt;
&lt;br /&gt;
You also need other programs so install them as well:&lt;br /&gt;
&lt;br /&gt;
  apk add wpa-supplicant dhcpcd chrony macchanger wireless-tools iputils&lt;br /&gt;
&lt;br /&gt;
What these programs do:&lt;br /&gt;
&lt;br /&gt;
* wpa-supplicant -- for WPA encryption&lt;br /&gt;
* dhcpcd -- for getting a dynamic IP address&lt;br /&gt;
* chrony -- for fixing the time with the atomic clock&lt;br /&gt;
* wireless-tools -- for additional information&lt;br /&gt;
* macchanger -- for protecting against WiFi access discrimination or increased anonymity.  (optional)&lt;br /&gt;
* iputils -- for the ping command (optional)&lt;br /&gt;
&lt;br /&gt;
You also need to add those services:&lt;br /&gt;
&lt;br /&gt;
  rc-update add chrony&lt;br /&gt;
  rc-update add wpa-supplicant&lt;br /&gt;
  rc-update add dhcpcd&lt;br /&gt;
  rc-update add networkmanager&lt;br /&gt;
&lt;br /&gt;
To start the services manually (or just reboot):&lt;br /&gt;
&lt;br /&gt;
  /etc/init.d/chrony start&lt;br /&gt;
  /etc/init.d/wpa-supplicant start&lt;br /&gt;
  /etc/init.d/dhcpcd start&lt;br /&gt;
  /etc/init.d networkmanager start&lt;br /&gt;
&lt;br /&gt;
== Additional tools ==&lt;br /&gt;
&lt;br /&gt;
=== actkbd ===&lt;br /&gt;
&lt;br /&gt;
To control the sound with fn function keys, you need this daemon.  It is currently not in aports.  You could override the design and meaning of those keys with your own scripts and utilities.  This daemon gives you that freedom.&lt;br /&gt;
&lt;br /&gt;
If your laptop contains a brightness key, you want to set that up with this program.  See also [[Setting_up_a_laptop#Adjusting_the_backlight_dynamically | Adjusting the backlight dynamically]].&lt;br /&gt;
&lt;br /&gt;
=== secure-delete ===&lt;br /&gt;
&lt;br /&gt;
Want to prevent cold-boot attack or decrypted keys in memory falling in the wrong hands?  This maybe could work who knows?  From research from cold boot attack, the data can actually stay in memory in minutes, just enough time for a hacker to copy the contents of the memory to a USB thumb drive.&lt;br /&gt;
&lt;br /&gt;
To install secure-delete do:&lt;br /&gt;
&lt;br /&gt;
  sudo apk add secure-delete&lt;br /&gt;
&lt;br /&gt;
smem only works for unused ram.[https://github.com/gordonrs/thc-secure-delete]  If you use the vanilla kernel, this may work.  If you use grsecurity, it will automatically sanitize memory if you enable it (but not enabled by default in the Alpine hardened kernel) when the memory page is freed.[https://en.wikibooks.org/wiki/Grsecurity/Appendix/Grsecurity_and_PaX_Configuration_Options#Sanitize_all_freed_memory]&lt;br /&gt;
&lt;br /&gt;
Close all important programs then call smem.&lt;br /&gt;
&lt;br /&gt;
You call smem in your shutdown script or auto-logoff script.&lt;br /&gt;
&lt;br /&gt;
You can call create a OpenRC shutdown script to run smem when most programs and services are closed.  This will erase all your sensitive plaintext private data just in case.&lt;br /&gt;
&lt;br /&gt;
You may want to create a wrapper script to call smem after your program closes.&lt;br /&gt;
&lt;br /&gt;
You need to write a custom script that does the following:&lt;br /&gt;
  * kill all running processes associated with your user account&lt;br /&gt;
  * auto logoff terminals&lt;br /&gt;
  * for the last terminal closed including all idle xservers, unmount your user home&lt;br /&gt;
  * (optional) use smem to wipe all your plaintext private data in memory after all closed programs in case of cold boot attack&lt;br /&gt;
&lt;br /&gt;
=== Sharing presentations over HDMI ===&lt;br /&gt;
&lt;br /&gt;
If you want to use your laptop to share presentation over HDMI connection, you need libxinerama and xrandr.&lt;br /&gt;
&lt;br /&gt;
To install libxinerama and xrandr do:&lt;br /&gt;
&lt;br /&gt;
  sudo apk add libxinerama xrandr&lt;br /&gt;
&lt;br /&gt;
== Important notes ==&lt;br /&gt;
&lt;br /&gt;
If you lose or break your USB key, that is it and you cannot decrypt your drive.  It would be wise to make a backup of it.&lt;br /&gt;
&lt;br /&gt;
By default, suspend-to-ram or hibernate will not sufficiently clear the AES encryption keys off ram in those phases which would invite a cold boot attack.  This has been covered by the TRESOR kernel patch.[https://en.wikipedia.org/wiki/TRESOR][https://www1.cs.fau.de/tresor]  This patch hasn&#039;t been updated since the 4.x kernel series.[https://www1.cs.fau.de/tresor].  This patch currently only works on 32-bit x86 Linux with SSE and MMX, and on processors with the AES-NI instruction set for x86_64 Linux.  TRESOR doesn&#039;t work with DMA attack, but it can be mitigated by disabling DMA.[https://old.iseclab.org/papers/acsac2012dma.pdf]  The 32-bit version of TRESOR has only a key size of 128.  The AES-NI version of TRESOR has a largest key size of 256 bit.  See [[Setting_up_a_laptop#Choosing_ciphers | Choosing ciphers]] for the number of rounds cracked.&lt;br /&gt;
&lt;br /&gt;
Loop-Amnesia works with LoopAES and is only for 64 bit Linux and only supports 128 bit keys but can result in data loss if their recommendations are not followed. [http://moongate.ydns.eu/amnesia.html]&lt;br /&gt;
&lt;br /&gt;
Please read the Wikipedia article on Cold Boot Attack especially the mitigation section.[https://en.wikipedia.org/wiki/Cold_boot_attack] Full disk encryption will not protect your data especially for older hardware if you do not have the proper mitigation (implying not full proof) prerequisites such as a patched kernel, memory scrambling, permanent memory module mounting for example.&lt;br /&gt;
&lt;br /&gt;
If you have a different but fully encrypted device like iPad, you still can be rubberhosed or interrogated with a perfect deniable encrypted laptop.  This guide doesn&#039;t protect you from that possibility.  If you do not want to be rubberhosed, don&#039;t possess those devices.&lt;br /&gt;
&lt;br /&gt;
Additional tips to mitigate against a DMA Attack to exfiltrate encryption keys:&lt;br /&gt;
&lt;br /&gt;
Disable DMA in the BIOS and set the password for the BIOS according to Wikipedia.[https://en.wikipedia.org/wiki/DMA_attack]&lt;br /&gt;
&lt;br /&gt;
Blacklist kernel modules that use DMA and any unused expansion modules (FireWire, CardBus, ExpressCard, Thunderbolt, USB 3.0, PCI Express and hotplug modules) that use DMA.&lt;br /&gt;
&lt;br /&gt;
You may need a custom (or customize a) BIOS or use Intel TXT or TPM which will authenticate the boot devices or boot from specific serial numbers not just any.  For cold boot attack, it is not required to remove the RAM but to to slow down the rate of decay of the RAM module with liquid air in addition an USB thumb drive containing an encryption key retriever bypassing the operating system.[https://youtu.be/XfUlRsE3ymQ]&lt;br /&gt;
&lt;br /&gt;
[[Category:Installation]]&lt;br /&gt;
[[category: desktop]]&lt;/div&gt;</summary>
		<author><name>Nangel</name></author>
	</entry>
	<entry>
		<id>https://wiki.alpinelinux.org/w/index.php?title=Main_Page&amp;diff=17109</id>
		<title>Main Page</title>
		<link rel="alternate" type="text/html" href="https://wiki.alpinelinux.org/w/index.php?title=Main_Page&amp;diff=17109"/>
		<updated>2020-03-22T15:55:39Z</updated>

		<summary type="html">&lt;p&gt;Nangel: update musl libc link&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;__NOEDITSECTION__&lt;br /&gt;
__NOTOC__&lt;br /&gt;
= Welcome to Alpine Linux Wiki=&lt;br /&gt;
&#039;&#039;&#039;[http://alpinelinux.org/about Alpine Linux]&#039;&#039;&#039; is a security-oriented, lightweight Linux distribution based on [https://musl.libc.org/ musl libc] and [http://busybox.net Busybox].&lt;br /&gt;
&lt;br /&gt;
Here is a [[Alpine Linux:Overview|more detailed overview]] of what makes our distribution distinctive; and a [[comparison with other distros]].&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br /&amp;gt;&lt;br /&gt;
{|style=&amp;quot;margin: 1em auto 1em auto&amp;quot;&lt;br /&gt;
|style=&amp;quot;width:64px;&amp;quot;|[[image:hdd_mount.svg|64px|link=Installation]] &lt;br /&gt;
|&#039;&#039;&#039;[[Installation]]&#039;&#039;&#039; &amp;lt;br/&amp;gt; Installing Alpine Linux&lt;br /&gt;
|[[image:filetypes.svg|64px|link=FAQ]]&lt;br /&gt;
|&#039;&#039;&#039;[[FAQ|FAQ]]&#039;&#039;&#039; &amp;lt;br/&amp;gt; Frequently Asked Questions&lt;br /&gt;
|[[image:bookcase.svg|64px|link=Glossary]]&lt;br /&gt;
|&#039;&#039;&#039;[[Glossary]]&#039;&#039;&#039;&lt;br /&gt;
|-&lt;br /&gt;
|[[image:package_edutainment.svg|64px|link=Tutorials and Howtos]]&lt;br /&gt;
|&#039;&#039;&#039;[[Tutorials and Howtos]]&#039;&#039;&#039; &amp;lt;br/&amp;gt;Basic and advanced configuration tasks&lt;br /&gt;
|[[image:package_system.svg|64px|link=Developer Documentation]]&lt;br /&gt;
|&#039;&#039;&#039;[[Developer Documentation]]&#039;&#039;&#039; &amp;lt;br/&amp;gt; Alpine Linux Development &lt;br /&gt;
|[[image:kuser.svg|64px|link=Contribute]]&lt;br /&gt;
|&#039;&#039;&#039;[[Contribute]]&#039;&#039;&#039; &amp;lt;br/&amp;gt; Contribute to Alpine Linux&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
* [[Alpine Linux:Releases|Current releases]]&lt;br /&gt;
* [[Alpine Linux:Listings|Links to other sites with information about Alpine]]&lt;/div&gt;</summary>
		<author><name>Nangel</name></author>
	</entry>
	<entry>
		<id>https://wiki.alpinelinux.org/w/index.php?title=Gaming_on_Alpine&amp;diff=16984</id>
		<title>Gaming on Alpine</title>
		<link rel="alternate" type="text/html" href="https://wiki.alpinelinux.org/w/index.php?title=Gaming_on_Alpine&amp;diff=16984"/>
		<updated>2020-03-03T10:34:04Z</updated>

		<summary type="html">&lt;p&gt;Nangel: /* List of games available on Alpine Linux */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&#039;&#039;&#039;Gaming on Alpine&#039;&#039;&#039; is a thing.&lt;br /&gt;
&lt;br /&gt;
== Installing games ==&lt;br /&gt;
&lt;br /&gt;
 sudo apk add micro-tetris&lt;br /&gt;
&lt;br /&gt;
== Permissions ==&lt;br /&gt;
&lt;br /&gt;
To make sure your account is in the games group.  You could do.&lt;br /&gt;
&lt;br /&gt;
 sudo gpasswd -a name games&lt;br /&gt;
&lt;br /&gt;
Log off then relog back on.&lt;br /&gt;
&lt;br /&gt;
== List of games available on Alpine Linux ==&lt;br /&gt;
&lt;br /&gt;
* [http://www.advancemame.it/ AdvanceMAME] - advancemame -- Arcade Simulator&lt;br /&gt;
* [https://wiki.gnome.org/Apps/Aisleriot Aisleriot] - aisleriot -- Solitaire card games&lt;br /&gt;
* [http://frotz.sourceforge.net/ Frotz] - frotz -- Z machine (Infocom interactive fiction) Interpreter&lt;br /&gt;
* [http://home.flightgear.org FlightGear] - flightgear -- Flight Simulator&lt;br /&gt;
* [https://freedoom.github.io/ Freedoom]+[https://www.chocolate-doom.org/ Chocolate Doom] - freedoom, chocolate-doom -- a free Doom game and an  engine to run it&lt;br /&gt;
* [https://en.wikipedia.org/wiki/GNU_Chess GNU Chess] - gnuchess -- Play chess against the computer&lt;br /&gt;
* [https://github.com/troglobit/tetris Micro Tetris] - micro-tetris -- Uses ANSI escape sequences and can fit in embedded devices&lt;br /&gt;
* [https://www.minetest.net/ Minetest] - minetest -- An Inspired Minecraft game&lt;br /&gt;
* [https://openrct2.org/ OpenRCT2] - OpenRCT2 -- Re-implementation of RollerCoaster Tycoon 2&lt;br /&gt;
* [https://en.wikipedia.org/wiki/OpenTTD OpenTTD] - openttd -- A business simulation game&lt;br /&gt;
* [https://www.nethack.org NetHack] - Rogue-like dungeon crawler&lt;br /&gt;
* [https://supertuxkart.net/Main_Page SuperTuxKart] - Kart racing game with OSS mascots&lt;br /&gt;
* [http://www.xonotic.org/ Xonotic] - xonotic -- A FPS arena game&lt;br /&gt;
&lt;br /&gt;
== Game related software ==&lt;br /&gt;
&lt;br /&gt;
* [https://en.wikipedia.org/wiki/Wine_(software) Wine] - wine -- It is typically used to play Windows games - You may need to chroot/multiboot as 32-bit Alpine to use 32 bit Windows games.  If you use x86_64, you can only run 64 bit Windows programs.&lt;br /&gt;
* [https://obsproject.com/ OBS Studio] - obs-studio -- It is used to live stream a gaming session&lt;/div&gt;</summary>
		<author><name>Nangel</name></author>
	</entry>
	<entry>
		<id>https://wiki.alpinelinux.org/w/index.php?title=MediaWiki:Copyright&amp;diff=16934</id>
		<title>MediaWiki:Copyright</title>
		<link rel="alternate" type="text/html" href="https://wiki.alpinelinux.org/w/index.php?title=MediaWiki:Copyright&amp;diff=16934"/>
		<updated>2020-02-22T01:56:40Z</updated>

		<summary type="html">&lt;p&gt;Nangel: Its 2020 ya&amp;#039;ll&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&amp;lt;div align=&amp;quot;right&amp;quot;&amp;gt;&amp;lt;div id=&amp;quot;footer-inner&amp;quot;&amp;gt; &lt;br /&gt;
  &amp;lt;p&amp;gt;&amp;lt;a href=&amp;quot;Privacy_Policy#Copyright&amp;quot;&amp;gt;&amp;amp;copy; Copyright 2008-2020 Alpine Linux Development Team&amp;lt;/a&amp;gt; &lt;br /&gt;
  all rights reserved &amp;lt;/div&amp;gt;&amp;lt;/div&amp;gt;&lt;/div&gt;</summary>
		<author><name>Nangel</name></author>
	</entry>
	<entry>
		<id>https://wiki.alpinelinux.org/w/index.php?title=Using_Unbound_as_an_Ad-blocker&amp;diff=16931</id>
		<title>Using Unbound as an Ad-blocker</title>
		<link rel="alternate" type="text/html" href="https://wiki.alpinelinux.org/w/index.php?title=Using_Unbound_as_an_Ad-blocker&amp;diff=16931"/>
		<updated>2020-02-21T20:03:10Z</updated>

		<summary type="html">&lt;p&gt;Nangel: How to do pi-hole without pi-hole&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Background == &lt;br /&gt;
&lt;br /&gt;
There is a fairly popular software product that acts as a DNS blocker for Advertisements and Malware.  It runs on the Raspberry &amp;lt;span style=&amp;quot;color: red&amp;quot;&amp;gt;Pi-&amp;lt;/span&amp;gt; and claims to be a DNS Black &amp;lt;span style=&amp;quot;color: red&amp;quot;&amp;gt;Hole&amp;lt;/span&amp;gt;.  It extends dnsmasq with filtering based on a downloadable blacklist.   There is a [https://gitlab.alpinelinux.org/alpine/aports/issues/9489 package request] for this software to run on Alpine Linux.&lt;br /&gt;
&lt;br /&gt;
The binary does compile on Alpine, however there is an extensive list of extraneous files, directories and packages that must be installed to get the modified version of dnsmasq to start.  The &amp;quot;basic installer&amp;quot; is over 2600 lines of Bash code.  &lt;br /&gt;
&lt;br /&gt;
Our goal is to get 80% of the functionality with 10% of the work.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Basic Components ==&lt;br /&gt;
&lt;br /&gt;
You should have dnsmasq (or another DHCP server) and [https://wiki.alpinelinux.org/wiki/Setting_up_unbound_DNS_server unbound] both working on your network.  &lt;br /&gt;
&lt;br /&gt;
== Setting up Unbound To Block/Refuse unwanted addresses ==&lt;br /&gt;
&lt;br /&gt;
There are a number of freely available blacklists on the net.  The installer mentioned above uses these lists by default:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
https://raw.githubusercontent.com/StevenBlack/hosts/master/hosts&lt;br /&gt;
https://mirror1.malwaredomains.com/files/justdomains&lt;br /&gt;
http://sysctl.org/cameleon/hosts&lt;br /&gt;
https://s3.amazonaws.com/lists.disconnect.me/simple_tracking.txt&lt;br /&gt;
https://s3.amazonaws.com/lists.disconnect.me/simple_ad.txt&lt;br /&gt;
https://hosts-file.net/ad_servers.txt&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Alternatively, there is a set of curated lists at https://github.com/StevenBlack/hosts.   There are various categories of lists there.   The format of the file is a &amp;quot;host&amp;quot; (so you can put it in /etc/hosts and be done.)   We will use the hosts file format:&lt;br /&gt;
&lt;br /&gt;
unbound needs to include the &amp;quot;blacklists.conf&amp;quot; file into its main configuration.  To do so, we need to create the include file in the following format:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
server:&lt;br /&gt;
&lt;br /&gt;
local-zone: &amp;quot;bad-site.com&amp;quot; refuse&lt;br /&gt;
local-zone: &amp;quot;bad-bad-site.com&amp;quot; refuse&lt;br /&gt;
local-zone: &amp;quot;xyz.ads-r-us.com&amp;quot; refuse&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Here is an example shell script to download the StevenBlack hosts format file, and then format it for unbound:&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#!/bin/sh&lt;br /&gt;
&lt;br /&gt;
echo &amp;quot;server:&amp;quot; &amp;gt;/etc/unbound/blacklist.conf&lt;br /&gt;
curl -s https://raw.githubusercontent.com/StevenBlack/hosts/master/hosts | \&lt;br /&gt;
        grep ^0.0.0.0 - | \&lt;br /&gt;
        sed &#039;s/ #.*$//;&lt;br /&gt;
        s/^0.0.0.0 \(.*\)/local-zone: &amp;quot;\1&amp;quot; refuse/&#039; \&lt;br /&gt;
        &amp;gt;&amp;gt;/etc/unbound/blacklist.conf&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
You can run this once, or as part of a periodic cron task.&lt;br /&gt;
&lt;br /&gt;
In the /etc/unbound/unbound.conf, add the following line somewhere in the config:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#include &amp;quot;/etc/unbound/blacklist.conf&amp;quot;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Reload unbound, and verify the config loads.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Dnsmasq configuration ==&lt;br /&gt;
&lt;br /&gt;
Dnsmasq defaults to using the resolver in /etc/resolv.conf - if unbound is listening on 127.0.0.1, then have it use that as the resolver.&lt;br /&gt;
&lt;br /&gt;
Alternatively, if unbound is running on another interface, or on a separate machine - use the dhcp-option configuration in dnsmasq:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
dhcp-option=6,[ip-of-unbound-server]&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Enjoy Ad-Free browsing!&lt;/div&gt;</summary>
		<author><name>Nangel</name></author>
	</entry>
	<entry>
		<id>https://wiki.alpinelinux.org/w/index.php?title=Chrony_and_GPSD&amp;diff=16862</id>
		<title>Chrony and GPSD</title>
		<link rel="alternate" type="text/html" href="https://wiki.alpinelinux.org/w/index.php?title=Chrony_and_GPSD&amp;diff=16862"/>
		<updated>2020-02-06T20:57:38Z</updated>

		<summary type="html">&lt;p&gt;Nangel: update to include the /dev/pps0 clock source&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;br /&gt;
Sources such as:&lt;br /&gt;
&lt;br /&gt;
* http://www.rjsystems.nl/en/2100-ntpd-garmin-gps-18-lvc-gpsd.php&lt;br /&gt;
* http://lists.ntp.org/pipermail/questions/2005-November/007878.html&lt;br /&gt;
&lt;br /&gt;
Describe how to wire a Garmin gps 18 lvc to a serial port to grab the PPS (pulse-per-second) signal to create a Stratum 1 timesource.  Other sources show using ntpd, and the [http://gpsd.berlios.de/gpsd.html gpsd man page] provides config snippets.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Alpine Linux gpsd package 3.9-r1 and higher has the necessary pps code to interface with chrony.   This page lists all of the files for a complete, working example:&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* /etc/modules needs to list the pps_ldisc module - you&#039;ll need to manually load it if not doing a reboot&lt;br /&gt;
{{Cat|/etc/modules|pps_ldisc}}&lt;br /&gt;
* If the GPS 18 LVC is on /dev/ttyS1, then:&lt;br /&gt;
{{Cat|/etc/conf.d/gpsd|&amp;lt;nowiki&amp;gt;&lt;br /&gt;
# Copyright 1999-2010 Gentoo Foundation&lt;br /&gt;
# Distributed under the terms of the GNU General Public License v2&lt;br /&gt;
&lt;br /&gt;
# Config file for gpsd server&lt;br /&gt;
# Optional arguments&lt;br /&gt;
#  Options include:&lt;br /&gt;
#   -b                        = bluetooth-safe: open data sources read-only&lt;br /&gt;
#   -n                        = don&#039;t wait for client connects to poll GPS&lt;br /&gt;
#   -N                        = don&#039;t go into background&lt;br /&gt;
#   -F sockfile               = specify control socket location&lt;br /&gt;
#   -G                        = make gpsd listen on INADDR_ANY&lt;br /&gt;
#   -D integer (default 0)    = set debug level&lt;br /&gt;
#   -S integer (default 2947) = set port for daemon&lt;br /&gt;
&lt;br /&gt;
GPSD_OPTIONS=&amp;quot;-n -b&amp;quot;&lt;br /&gt;
DEVICES=&amp;quot;/dev/ttyS1&amp;quot;&lt;br /&gt;
GPSD_SOCKET=&amp;quot;/var/run/gpsd.sock&amp;quot;&lt;br /&gt;
BAUDRATE=&amp;quot;4800&amp;quot;&lt;br /&gt;
&lt;br /&gt;
# Serial setup&lt;br /&gt;
#&lt;br /&gt;
# For serial interfaces, options such as low_latency are recommended&lt;br /&gt;
# Also, http://catb.org/gpsd/upstream-bugs.html#tiocmwait recommends&lt;br /&gt;
#   setting the baudrate with stty&lt;br /&gt;
# Uncomment the following lines if using a serial device:&lt;br /&gt;
#&lt;br /&gt;
/bin/stty -F ${DEVICE} ${BAUDRATE}&lt;br /&gt;
/bin/setserial ${DEVICE} low_latency&lt;br /&gt;
&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
{{Note|As of v3.11, the init.d and conf.d files have been merged from gentoo.&lt;br /&gt;
The purpose is to allow gpsd to start without editing /etc/conf.d/gpsd.&lt;br /&gt;
Note that while gpsd will now start without editing the conf.d file, it will do so with no gps devices attached.  &lt;br /&gt;
&lt;br /&gt;
Also note that if you are using a serial device it is still recommended to add the stty and setserial commands as noted in the example configuration above.}}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* This shows all four methods of getting time from gpsd:&lt;br /&gt;
{{Cat|/etc/chrony/chrony.conf|&amp;lt;nowiki&amp;gt;&lt;br /&gt;
server 0.pool.ntp.org&lt;br /&gt;
server 1.pool.ntp.org&lt;br /&gt;
server 2.pool.ntp.org&lt;br /&gt;
&lt;br /&gt;
initstepslew 30 0.pool.ntp.org 1.pool.ntp.org 2.pool.ntp.org&lt;br /&gt;
&lt;br /&gt;
# SHM0 from gpsd is the NEMA data at 4800bps, so is not very accurate&lt;br /&gt;
refclock SHM 0  delay 0.5 refid NEMA&lt;br /&gt;
&lt;br /&gt;
# SHM1 from gpsd (if present) is from the kernel PPS_LDISC&lt;br /&gt;
# module.  It includes PPS and will be accurate to a few ns&lt;br /&gt;
refclock SHM 1 offset 0.0 delay 0.1 refid NEMA+&lt;br /&gt;
&lt;br /&gt;
# SOCK protocol also includes PPS data and &lt;br /&gt;
# it also provides time within a few ns&lt;br /&gt;
refclock SOCK /var/run/chrony.ttyS1.sock delay 0.0 refid SOCK&lt;br /&gt;
&lt;br /&gt;
# PPS is from the /dev/pps0 device.  Note that&lt;br /&gt;
# chronyd creates the /var/run/chrony.ttyS1.sock device, but&lt;br /&gt;
# gpsd creates the /dev/pps0 device&lt;br /&gt;
# openrc rules start gpsd /after/ chronyd, so /dev/pps0 &lt;br /&gt;
#   is not created until after chronyd is started&lt;br /&gt;
#   If you want to use pps0, either edit the openrc rules&lt;br /&gt;
#   or add this source after gpsd is started&lt;br /&gt;
&lt;br /&gt;
# refclock PPS /dev/pps0 refid PPS&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
# If you see something in ns... its good.&lt;br /&gt;
#          1 second =&lt;br /&gt;
#       1000 ms =&lt;br /&gt;
#    1000000 us =&lt;br /&gt;
# 1000000000 ns&lt;br /&gt;
&lt;br /&gt;
logchange 0.5&lt;br /&gt;
local stratum 10&lt;br /&gt;
&lt;br /&gt;
logdir /var/log/chrony&lt;br /&gt;
&lt;br /&gt;
keyfile /etc/chrony/chrony.keys&lt;br /&gt;
commandkey 10&lt;br /&gt;
&lt;br /&gt;
dumpdir /var/log/chrony&lt;br /&gt;
driftfile /var/log/chrony/chrony.drift&lt;br /&gt;
&lt;br /&gt;
allow all&lt;br /&gt;
&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
== Chronyc ==&lt;br /&gt;
&lt;br /&gt;
If everything is working correctly, a chronyc &#039;sources&#039; command should look like this:&lt;br /&gt;
&lt;br /&gt;
 chronyc&amp;gt; sources&lt;br /&gt;
 210 Number of sources = 6&lt;br /&gt;
 MS Name/IP address         Stratum Poll Reach LastRx Last sample&lt;br /&gt;
 ===============================================================================&lt;br /&gt;
 #x NEMA                          0   4   377    14   +684ms[ +684ms] +/-  252ms&lt;br /&gt;
 #+ PPS                           0   4   377    13  +2040ns[+2060ns] +/-   50ms&lt;br /&gt;
 #* SOCK                          0   4   377     7   +225ns[ +245ns] +/- 2217ns&lt;br /&gt;
 ^? tick.tock.com                 2  10   377   318  -5144us[-5144us] +/-   72ms&lt;br /&gt;
 ^? time.keeper.net               3  10   377   720  -4571us[-4567us] +/-  139ms&lt;br /&gt;
 ^? dead.time.server.org          0  10     0   10y     +0ns[   +0ns] +/-    0ns&lt;br /&gt;
&lt;br /&gt;
* NEMA (SHM0)  is &amp;quot;x&amp;quot; - its really unstable&lt;br /&gt;
* PPS (SHM1) is good, but the delay of 0.1 makes it the not-preferred master&lt;br /&gt;
* SOCK is the preferred master&lt;br /&gt;
* The other NTP servers are only used if the local server goes down.&lt;br /&gt;
&lt;br /&gt;
== Notes ==&lt;br /&gt;
&lt;br /&gt;
* In /etc/chrony/chrony.conf, there are four possible time sources:&lt;br /&gt;
** SHM 0  (NEMA serial data)&lt;br /&gt;
** SHM 1  (NEMA with PPS)&lt;br /&gt;
** SOCK   (PPS &#039;proprietary&#039; gpsd/chrony interface)&lt;br /&gt;
** PPS    (PPS only from the serial interface pulse)&lt;br /&gt;
* You only need 1 of them, although 3 are shown above&lt;br /&gt;
* In the example above, SHM1 is specified with a delay of 0.1 to prevent it from competing with the SOCK protocol&lt;br /&gt;
** If you prefer to use the SHM1  source instead of SOCK, then either:&lt;br /&gt;
*** comment out the SOCK protocol line&lt;br /&gt;
*** or reverse the delay values.&lt;br /&gt;
* Note that the SHM0 source (NEMA only, no PPS) is set to a higher delay - don&#039;t use it if you have PPS available.&lt;br /&gt;
** An example of where you would want to use SHM0 is a USB based gps receiver - they don&#039;t have the PPS line&lt;br /&gt;
* Chrony creates the SOCK interface; chrony should be started before gpsd.   If you restart chronyd for some reason, make sure you restart gpsd after.&lt;br /&gt;
* The SHM0 interface can be used with USB based gps devices.   In this case, use /dev/ttyUSBX in the /etc/conf.d/gpsd file, and leave the stty and setserial lines commented out.&lt;br /&gt;
&lt;br /&gt;
[[Category:Server]]&lt;br /&gt;
[[Category:Networking]]&lt;/div&gt;</summary>
		<author><name>Nangel</name></author>
	</entry>
	<entry>
		<id>https://wiki.alpinelinux.org/w/index.php?title=Chrony_and_GPSD&amp;diff=16861</id>
		<title>Chrony and GPSD</title>
		<link rel="alternate" type="text/html" href="https://wiki.alpinelinux.org/w/index.php?title=Chrony_and_GPSD&amp;diff=16861"/>
		<updated>2020-02-06T20:52:21Z</updated>

		<summary type="html">&lt;p&gt;Nangel: update conf.d/gpsd to match new gentoo init script&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;br /&gt;
Sources such as:&lt;br /&gt;
&lt;br /&gt;
* http://www.rjsystems.nl/en/2100-ntpd-garmin-gps-18-lvc-gpsd.php&lt;br /&gt;
* http://lists.ntp.org/pipermail/questions/2005-November/007878.html&lt;br /&gt;
&lt;br /&gt;
Describe how to wire a Garmin gps 18 lvc to a serial port to grab the PPS (pulse-per-second) signal to create a Stratum 1 timesource.  Other sources show using ntpd, and the [http://gpsd.berlios.de/gpsd.html gpsd man page] provides config snippets.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Alpine Linux gpsd package 3.9-r1 and higher has the necessary pps code to interface with chrony.   This page lists all of the files for a complete, working example:&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* /etc/modules needs to list the pps_ldisc module - you&#039;ll need to manually load it if not doing a reboot&lt;br /&gt;
{{Cat|/etc/modules|pps_ldisc}}&lt;br /&gt;
* If the GPS 18 LVC is on /dev/ttyS1, then:&lt;br /&gt;
{{Cat|/etc/conf.d/gpsd|&amp;lt;nowiki&amp;gt;&lt;br /&gt;
# Copyright 1999-2010 Gentoo Foundation&lt;br /&gt;
# Distributed under the terms of the GNU General Public License v2&lt;br /&gt;
&lt;br /&gt;
# Config file for gpsd server&lt;br /&gt;
# Optional arguments&lt;br /&gt;
#  Options include:&lt;br /&gt;
#   -b                        = bluetooth-safe: open data sources read-only&lt;br /&gt;
#   -n                        = don&#039;t wait for client connects to poll GPS&lt;br /&gt;
#   -N                        = don&#039;t go into background&lt;br /&gt;
#   -F sockfile               = specify control socket location&lt;br /&gt;
#   -G                        = make gpsd listen on INADDR_ANY&lt;br /&gt;
#   -D integer (default 0)    = set debug level&lt;br /&gt;
#   -S integer (default 2947) = set port for daemon&lt;br /&gt;
&lt;br /&gt;
GPSD_OPTIONS=&amp;quot;-n -b&amp;quot;&lt;br /&gt;
DEVICES=&amp;quot;/dev/ttyS1&amp;quot;&lt;br /&gt;
GPSD_SOCKET=&amp;quot;/var/run/gpsd.sock&amp;quot;&lt;br /&gt;
BAUDRATE=&amp;quot;4800&amp;quot;&lt;br /&gt;
&lt;br /&gt;
# Serial setup&lt;br /&gt;
#&lt;br /&gt;
# For serial interfaces, options such as low_latency are recommended&lt;br /&gt;
# Also, http://catb.org/gpsd/upstream-bugs.html#tiocmwait recommends&lt;br /&gt;
#   setting the baudrate with stty&lt;br /&gt;
# Uncomment the following lines if using a serial device:&lt;br /&gt;
#&lt;br /&gt;
/bin/stty -F ${DEVICE} ${BAUDRATE}&lt;br /&gt;
/bin/setserial ${DEVICE} low_latency&lt;br /&gt;
&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
{{Note|As of v3.11, the init.d and conf.d files have been merged from gentoo.&lt;br /&gt;
The purpose is to allow gpsd to start without editing /etc/conf.d/gpsd.&lt;br /&gt;
Note that while gpsd will now start without editing the conf.d file, it will do so with no gps devices attached.  &lt;br /&gt;
&lt;br /&gt;
Also note that if you are using a serial device it is still recommended to add the stty and setserial commands as noted in the example configuration above.}}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* This shows all three methods of getting time from gpsd:&lt;br /&gt;
{{Cat|/etc/chrony/chrony.conf|&amp;lt;nowiki&amp;gt;&lt;br /&gt;
server 0.pool.ntp.org&lt;br /&gt;
server 1.pool.ntp.org&lt;br /&gt;
server 2.pool.ntp.org&lt;br /&gt;
&lt;br /&gt;
initstepslew 30 0.pool.ntp.org 1.pool.ntp.org 2.pool.ntp.org&lt;br /&gt;
&lt;br /&gt;
# SHM0 from gpsd is the NEMA data at 4800bps, so is not very accurate&lt;br /&gt;
refclock SHM 0  delay 0.5 refid NEMA&lt;br /&gt;
&lt;br /&gt;
# SHM1 from gpsd (if present) is from the kernel PPS_LDISC&lt;br /&gt;
# module.  It includes PPS and will be accurate to a few ns&lt;br /&gt;
refclock SHM 1 offset 0.0 delay 0.1 refid PPS&lt;br /&gt;
&lt;br /&gt;
# SOCK protocol also includes PPS data and &lt;br /&gt;
# it also provides time within a few ns&lt;br /&gt;
refclock SOCK /var/run/chrony.ttyS1.sock delay 0.0 refid SOCK&lt;br /&gt;
&lt;br /&gt;
# If you see something in ns... its good.&lt;br /&gt;
#          1 second =&lt;br /&gt;
#       1000 ms =&lt;br /&gt;
#    1000000 us =&lt;br /&gt;
# 1000000000 ns&lt;br /&gt;
&lt;br /&gt;
logchange 0.5&lt;br /&gt;
local stratum 10&lt;br /&gt;
&lt;br /&gt;
logdir /var/log/chrony&lt;br /&gt;
&lt;br /&gt;
keyfile /etc/chrony/chrony.keys&lt;br /&gt;
commandkey 10&lt;br /&gt;
&lt;br /&gt;
dumpdir /var/log/chrony&lt;br /&gt;
driftfile /var/log/chrony/chrony.drift&lt;br /&gt;
&lt;br /&gt;
allow all&lt;br /&gt;
&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
== Chronyc ==&lt;br /&gt;
&lt;br /&gt;
If everything is working correctly, a chronyc &#039;sources&#039; command should look like this:&lt;br /&gt;
&lt;br /&gt;
 chronyc&amp;gt; sources&lt;br /&gt;
 210 Number of sources = 6&lt;br /&gt;
 MS Name/IP address         Stratum Poll Reach LastRx Last sample&lt;br /&gt;
 ===============================================================================&lt;br /&gt;
 #x NEMA                          0   4   377    14   +684ms[ +684ms] +/-  252ms&lt;br /&gt;
 #+ PPS                           0   4   377    13  +2040ns[+2060ns] +/-   50ms&lt;br /&gt;
 #* SOCK                          0   4   377     7   +225ns[ +245ns] +/- 2217ns&lt;br /&gt;
 ^? tick.tock.com                 2  10   377   318  -5144us[-5144us] +/-   72ms&lt;br /&gt;
 ^? time.keeper.net               3  10   377   720  -4571us[-4567us] +/-  139ms&lt;br /&gt;
 ^? dead.time.server.org          0  10     0   10y     +0ns[   +0ns] +/-    0ns&lt;br /&gt;
&lt;br /&gt;
* NEMA (SHM0)  is &amp;quot;x&amp;quot; - its really unstable&lt;br /&gt;
* PPS (SHM1) is good, but the delay of 0.1 makes it the not-preferred master&lt;br /&gt;
* SOCK is the preferred master&lt;br /&gt;
* The other NTP servers are only used if the local server goes down.&lt;br /&gt;
&lt;br /&gt;
== Notes ==&lt;br /&gt;
&lt;br /&gt;
* In /etc/chrony/chrony.conf, there are three possible time sources:&lt;br /&gt;
** SHM 0  (NEMA serial data)&lt;br /&gt;
** SHM 1  (NEMA with PPS)&lt;br /&gt;
** SOCK   (PPS &#039;proprietary&#039; gpsd/chrony interface)&lt;br /&gt;
* You only need 1 of them, although all 3 are shown above&lt;br /&gt;
* In the example above, SHM1 is specified with a delay of 0.1 to prevent it from competing with the SOCK protocol&lt;br /&gt;
** If you prefer to use the SHM1  source instead of SOCK, then either:&lt;br /&gt;
*** comment out the SOCK protocol line&lt;br /&gt;
*** or reverse the delay values.&lt;br /&gt;
* Note that the SHM0 source (NEMA only, no PPS) is set to a higher delay - don&#039;t use it if you have PPS available.&lt;br /&gt;
** An example of where you would want to use SHM0 is a USB based gps receiver - they don&#039;t have the PPS line&lt;br /&gt;
* Chrony creates the SOCK interface; chrony should be started before gpsd.   If you restart chronyd for some reason, make sure you restart gpsd after.&lt;br /&gt;
* The SHM0 interface can be used with USB based gps devices.   In this case, use /dev/ttyUSBX in the /etc/conf.d/gpsd file, and leave the stty and setserial lines commented out.&lt;br /&gt;
&lt;br /&gt;
[[Category:Server]]&lt;br /&gt;
[[Category:Networking]]&lt;/div&gt;</summary>
		<author><name>Nangel</name></author>
	</entry>
	<entry>
		<id>https://wiki.alpinelinux.org/w/index.php?title=Chrony_and_GPSD&amp;diff=16860</id>
		<title>Chrony and GPSD</title>
		<link rel="alternate" type="text/html" href="https://wiki.alpinelinux.org/w/index.php?title=Chrony_and_GPSD&amp;diff=16860"/>
		<updated>2020-02-06T20:50:10Z</updated>

		<summary type="html">&lt;p&gt;Nangel: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;br /&gt;
Sources such as:&lt;br /&gt;
&lt;br /&gt;
* http://www.rjsystems.nl/en/2100-ntpd-garmin-gps-18-lvc-gpsd.php&lt;br /&gt;
* http://lists.ntp.org/pipermail/questions/2005-November/007878.html&lt;br /&gt;
&lt;br /&gt;
Describe how to wire a Garmin gps 18 lvc to a serial port to grab the PPS (pulse-per-second) signal to create a Stratum 1 timesource.  Other sources show using ntpd, and the [http://gpsd.berlios.de/gpsd.html gpsd man page] provides config snippets.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Alpine Linux gpsd package 3.9-r1 and higher has the necessary pps code to interface with chrony.   This page lists all of the files for a complete, working example:&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* /etc/modules needs to list the pps_ldisc module - you&#039;ll need to manually load it if not doing a reboot&lt;br /&gt;
{{Cat|/etc/modules|pps_ldisc}}&lt;br /&gt;
* If the GPS 18 LVC is on /dev/ttyS1, then:&lt;br /&gt;
{{Cat|/etc/conf.d/gpsd|&amp;lt;nowiki&amp;gt;&lt;br /&gt;
# The GPS device (/dev/ttyUSB0, /dev/ttyS0, ...)&lt;br /&gt;
 &lt;br /&gt;
DEVICE=&amp;quot;/dev/ttyS1&amp;quot;&lt;br /&gt;
BAUDRATE=&amp;quot;4800&amp;quot;&lt;br /&gt;
&lt;br /&gt;
# Optional arguments&lt;br /&gt;
#  Options include:&lt;br /&gt;
#   -b                        = bluetooth-safe: open data sources read-only&lt;br /&gt;
#   -n                        = don&#039;t wait for client connects to poll GPS&lt;br /&gt;
#   -N                        = don&#039;t go into background&lt;br /&gt;
#   -F sockfile               = specify control socket location&lt;br /&gt;
#   -G                        = make gpsd listen on INADDR_ANY&lt;br /&gt;
#   -D integer (default 0)    = set debug level&lt;br /&gt;
#   -S integer (default 2947) = set port for daemon&lt;br /&gt;
&lt;br /&gt;
ARGS=&amp;quot;-n -b&amp;quot;&lt;br /&gt;
&lt;br /&gt;
# Serial setup&lt;br /&gt;
#&lt;br /&gt;
# For serial interfaces, options such as low_latency are recommended&lt;br /&gt;
# Also, http://catb.org/gpsd/upstream-bugs.html#tiocmwait recommends&lt;br /&gt;
#   setting the baudrate with stty&lt;br /&gt;
# Uncomment the following lines if using a serial device:&lt;br /&gt;
#&lt;br /&gt;
/bin/stty -F ${DEVICE} ${BAUDRATE}&lt;br /&gt;
/bin/setserial ${DEVICE} low_latency&lt;br /&gt;
&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
{{Note|As of v3.11, the init.d and conf.d files have been merged from gentoo.&lt;br /&gt;
The purpose is to allow gpsd to start without editing /etc/conf.d/gpsd.&lt;br /&gt;
Note that while gpsd will now start without editing the conf.d file, it will do so with no gps devices attached.  &lt;br /&gt;
&lt;br /&gt;
Also note that if you are using a serial device it is still recommended to add the stty and setserial commands as noted in the example configuration above.}}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* This shows all three methods of getting time from gpsd:&lt;br /&gt;
{{Cat|/etc/chrony/chrony.conf|&amp;lt;nowiki&amp;gt;&lt;br /&gt;
server 0.pool.ntp.org&lt;br /&gt;
server 1.pool.ntp.org&lt;br /&gt;
server 2.pool.ntp.org&lt;br /&gt;
&lt;br /&gt;
initstepslew 30 0.pool.ntp.org 1.pool.ntp.org 2.pool.ntp.org&lt;br /&gt;
&lt;br /&gt;
# SHM0 from gpsd is the NEMA data at 4800bps, so is not very accurate&lt;br /&gt;
refclock SHM 0  delay 0.5 refid NEMA&lt;br /&gt;
&lt;br /&gt;
# SHM1 from gpsd (if present) is from the kernel PPS_LDISC&lt;br /&gt;
# module.  It includes PPS and will be accurate to a few ns&lt;br /&gt;
refclock SHM 1 offset 0.0 delay 0.1 refid PPS&lt;br /&gt;
&lt;br /&gt;
# SOCK protocol also includes PPS data and &lt;br /&gt;
# it also provides time within a few ns&lt;br /&gt;
refclock SOCK /var/run/chrony.ttyS1.sock delay 0.0 refid SOCK&lt;br /&gt;
&lt;br /&gt;
# If you see something in ns... its good.&lt;br /&gt;
#          1 second =&lt;br /&gt;
#       1000 ms =&lt;br /&gt;
#    1000000 us =&lt;br /&gt;
# 1000000000 ns&lt;br /&gt;
&lt;br /&gt;
logchange 0.5&lt;br /&gt;
local stratum 10&lt;br /&gt;
&lt;br /&gt;
logdir /var/log/chrony&lt;br /&gt;
&lt;br /&gt;
keyfile /etc/chrony/chrony.keys&lt;br /&gt;
commandkey 10&lt;br /&gt;
&lt;br /&gt;
dumpdir /var/log/chrony&lt;br /&gt;
driftfile /var/log/chrony/chrony.drift&lt;br /&gt;
&lt;br /&gt;
allow all&lt;br /&gt;
&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
== Chronyc ==&lt;br /&gt;
&lt;br /&gt;
If everything is working correctly, a chronyc &#039;sources&#039; command should look like this:&lt;br /&gt;
&lt;br /&gt;
 chronyc&amp;gt; sources&lt;br /&gt;
 210 Number of sources = 6&lt;br /&gt;
 MS Name/IP address         Stratum Poll Reach LastRx Last sample&lt;br /&gt;
 ===============================================================================&lt;br /&gt;
 #x NEMA                          0   4   377    14   +684ms[ +684ms] +/-  252ms&lt;br /&gt;
 #+ PPS                           0   4   377    13  +2040ns[+2060ns] +/-   50ms&lt;br /&gt;
 #* SOCK                          0   4   377     7   +225ns[ +245ns] +/- 2217ns&lt;br /&gt;
 ^? tick.tock.com                 2  10   377   318  -5144us[-5144us] +/-   72ms&lt;br /&gt;
 ^? time.keeper.net               3  10   377   720  -4571us[-4567us] +/-  139ms&lt;br /&gt;
 ^? dead.time.server.org          0  10     0   10y     +0ns[   +0ns] +/-    0ns&lt;br /&gt;
&lt;br /&gt;
* NEMA (SHM0)  is &amp;quot;x&amp;quot; - its really unstable&lt;br /&gt;
* PPS (SHM1) is good, but the delay of 0.1 makes it the not-preferred master&lt;br /&gt;
* SOCK is the preferred master&lt;br /&gt;
* The other NTP servers are only used if the local server goes down.&lt;br /&gt;
&lt;br /&gt;
== Notes ==&lt;br /&gt;
&lt;br /&gt;
* In /etc/chrony/chrony.conf, there are three possible time sources:&lt;br /&gt;
** SHM 0  (NEMA serial data)&lt;br /&gt;
** SHM 1  (NEMA with PPS)&lt;br /&gt;
** SOCK   (PPS &#039;proprietary&#039; gpsd/chrony interface)&lt;br /&gt;
* You only need 1 of them, although all 3 are shown above&lt;br /&gt;
* In the example above, SHM1 is specified with a delay of 0.1 to prevent it from competing with the SOCK protocol&lt;br /&gt;
** If you prefer to use the SHM1  source instead of SOCK, then either:&lt;br /&gt;
*** comment out the SOCK protocol line&lt;br /&gt;
*** or reverse the delay values.&lt;br /&gt;
* Note that the SHM0 source (NEMA only, no PPS) is set to a higher delay - don&#039;t use it if you have PPS available.&lt;br /&gt;
** An example of where you would want to use SHM0 is a USB based gps receiver - they don&#039;t have the PPS line&lt;br /&gt;
* Chrony creates the SOCK interface; chrony should be started before gpsd.   If you restart chronyd for some reason, make sure you restart gpsd after.&lt;br /&gt;
* The SHM0 interface can be used with USB based gps devices.   In this case, use /dev/ttyUSBX in the /etc/conf.d/gpsd file, and leave the stty and setserial lines commented out.&lt;br /&gt;
&lt;br /&gt;
[[Category:Server]]&lt;br /&gt;
[[Category:Networking]]&lt;/div&gt;</summary>
		<author><name>Nangel</name></author>
	</entry>
	<entry>
		<id>https://wiki.alpinelinux.org/w/index.php?title=Gaming_on_Alpine&amp;diff=16056</id>
		<title>Gaming on Alpine</title>
		<link rel="alternate" type="text/html" href="https://wiki.alpinelinux.org/w/index.php?title=Gaming_on_Alpine&amp;diff=16056"/>
		<updated>2019-07-10T20:49:19Z</updated>

		<summary type="html">&lt;p&gt;Nangel: /* List of games available on Alpine Linux */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&#039;&#039;&#039;Gaming on Alpine&#039;&#039;&#039; is a thing.&lt;br /&gt;
&lt;br /&gt;
== Installing games ==&lt;br /&gt;
&lt;br /&gt;
 sudo apk add micro-tetris&lt;br /&gt;
&lt;br /&gt;
== Permissions ==&lt;br /&gt;
&lt;br /&gt;
To make sure your account is in the games group.  You could do.&lt;br /&gt;
&lt;br /&gt;
 sudo gpasswd -a name games&lt;br /&gt;
&lt;br /&gt;
Log off then relog back on.&lt;br /&gt;
&lt;br /&gt;
== List of games available on Alpine Linux ==&lt;br /&gt;
&lt;br /&gt;
* [http://www.advancemame.it/ AdvanceMAME] - advancemame -- Arcade Simulator&lt;br /&gt;
* [http://frotz.sourceforge.net/ Frotz] - frotz -- Z machine (Infocom interactive fiction) Interpreter&lt;br /&gt;
* [http://home.flightgear.org FlightGear] - flightgear -- Flight Simulator&lt;br /&gt;
* [https://en.wikipedia.org/wiki/GNU_Chess GNU Chess] - gnuchess -- Play chess against the computer&lt;br /&gt;
* [https://github.com/troglobit/tetris Micro Tetris] - micro-tetris -- Uses ANSI escape sequences and can fit in embedded devices&lt;br /&gt;
* [https://www.minetest.net/ Minetest] - minetest -- An Inspired Minecraft game&lt;br /&gt;
* [https://openrct2.org/ OpenRCT2] - OpenRCT2 -- Re-implementation of RollerCoaster Tycoon 2&lt;br /&gt;
* [https://en.wikipedia.org/wiki/OpenTTD OpenTTD] - openttd -- A business simulation game&lt;br /&gt;
* [https://www.nethack.org NetHack] - Rogue-like dungeon crawler&lt;br /&gt;
* [http://www.xonotic.org/ Xonotic] - xonotic -- A FPS arena game&lt;br /&gt;
&lt;br /&gt;
== Game related software ==&lt;br /&gt;
&lt;br /&gt;
* [https://en.wikipedia.org/wiki/Wine_(software) Wine] - wine -- It is typically used to play Windows games - You may need to chroot/multiboot as 32-bit Alpine to use 32 bit Windows games.  If you use x86_64, you can only run 64 bit Windows programs.&lt;br /&gt;
* [https://obsproject.com/ OBS Studio] - obs-studio -- It is used to live stream a gaming session&lt;/div&gt;</summary>
		<author><name>Nangel</name></author>
	</entry>
	<entry>
		<id>https://wiki.alpinelinux.org/w/index.php?title=Gaming_on_Alpine&amp;diff=16028</id>
		<title>Gaming on Alpine</title>
		<link rel="alternate" type="text/html" href="https://wiki.alpinelinux.org/w/index.php?title=Gaming_on_Alpine&amp;diff=16028"/>
		<updated>2019-06-28T12:44:30Z</updated>

		<summary type="html">&lt;p&gt;Nangel: /* List of games available on Alpine Linux */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&#039;&#039;&#039;Gaming on Alpine&#039;&#039;&#039; is a thing.&lt;br /&gt;
&lt;br /&gt;
== Installing games ==&lt;br /&gt;
&lt;br /&gt;
 sudo apk add micro-tetris&lt;br /&gt;
&lt;br /&gt;
== Permissions ==&lt;br /&gt;
&lt;br /&gt;
To make sure your account is in the games group.  You could do.&lt;br /&gt;
&lt;br /&gt;
 sudo gpasswd -a name games&lt;br /&gt;
&lt;br /&gt;
Log off then relog back on.&lt;br /&gt;
&lt;br /&gt;
== List of games available on Alpine Linux ==&lt;br /&gt;
&lt;br /&gt;
* [http://www.advancemame.it/ AdvanceMAME] - advancemame -- Arcade Simulator&lt;br /&gt;
* [http://frotz.sourceforge.net/ Frotz] - frotz -- Z machine (Infocom interactive fiction) Interpreter&lt;br /&gt;
* [http://home.flightgear.org FlightGear] - flightgear -- Flight Simulator&lt;br /&gt;
* [https://en.wikipedia.org/wiki/GNU_Chess GNU Chess] - gnuchess -- Play chess against the computer&lt;br /&gt;
* [https://github.com/troglobit/tetris Micro Tetris] - micro-tetris -- Uses ANSI escape sequences and can fit in embedded devices&lt;br /&gt;
* [https://www.minetest.net/ Minetest] - minetest -- An Inspired Minecraft game&lt;br /&gt;
* [https://en.wikipedia.org/wiki/OpenTTD OpenTTD] - openttd -- A business simulation game&lt;br /&gt;
* [https://www.nethack.org NetHack] - Rogue-like dungeon crawler&lt;br /&gt;
* [http://www.xonotic.org/ Xonotic] - xonotic -- A FPS arena game&lt;br /&gt;
&lt;br /&gt;
== Game related software ==&lt;br /&gt;
&lt;br /&gt;
* [https://en.wikipedia.org/wiki/Wine_(software) Wine] - wine -- It is typically used to play Windows games - You may need to chroot/multiboot as 32-bit Alpine to use 32 bit Windows games.  If you use x86_64, you can only run 64 bit Windows programs.&lt;br /&gt;
* [https://obsproject.com/ OBS Studio] - obs-studio -- It is used to live stream a gaming session&lt;/div&gt;</summary>
		<author><name>Nangel</name></author>
	</entry>
	<entry>
		<id>https://wiki.alpinelinux.org/w/index.php?title=MediaWiki:Copyright&amp;diff=15664</id>
		<title>MediaWiki:Copyright</title>
		<link rel="alternate" type="text/html" href="https://wiki.alpinelinux.org/w/index.php?title=MediaWiki:Copyright&amp;diff=15664"/>
		<updated>2019-01-10T22:27:56Z</updated>

		<summary type="html">&lt;p&gt;Nangel: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&amp;lt;div align=&amp;quot;right&amp;quot;&amp;gt;&amp;lt;div id=&amp;quot;footer-inner&amp;quot;&amp;gt; &lt;br /&gt;
  &amp;lt;p&amp;gt;&amp;lt;a href=&amp;quot;Privacy_Policy#Copyright&amp;quot;&amp;gt;&amp;amp;copy; Copyright 2008-2019 Alpine Linux Development Team&amp;lt;/a&amp;gt; &lt;br /&gt;
  all rights reserved &amp;lt;/div&amp;gt;&amp;lt;/div&amp;gt;&lt;/div&gt;</summary>
		<author><name>Nangel</name></author>
	</entry>
	<entry>
		<id>https://wiki.alpinelinux.org/w/index.php?title=Setting_up_a_VPN_with_tinc&amp;diff=15360</id>
		<title>Setting up a VPN with tinc</title>
		<link rel="alternate" type="text/html" href="https://wiki.alpinelinux.org/w/index.php?title=Setting_up_a_VPN_with_tinc&amp;diff=15360"/>
		<updated>2018-07-24T18:54:29Z</updated>

		<summary type="html">&lt;p&gt;Nangel: tt&amp;gt;&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;These instructions will create a routed mesh network with multiple protected networks behind each node.  While it is possible to set up separate tinc daemons with separate vpn names, we will &amp;quot;trunk&amp;quot; all the traffic over a single tinc vpn.  These instructions do not create an extended bridged &amp;quot;ethernet LAN&amp;quot; - it creates a set of routed networks.&lt;br /&gt;
&lt;br /&gt;
= Network Topology =&lt;br /&gt;
&lt;br /&gt;
Our example network topology looks like the following chart.   Example.com has three offices:  Aspen, Boulder, and Carbondale.   Each office has two networks.  Alpine Linux is used as the firwall/router/gateway at each office, and tinc will be installed on the gateway.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tt&amp;gt;&lt;br /&gt;
&lt;br /&gt;
   ASPEN  [10.1.0.1] --------------\&lt;br /&gt;
                                   |&lt;br /&gt;
 192.168.10.0/24                   |&lt;br /&gt;
 192.160.110.0/24              [INTERNET]------------------ [10.3.0.1] CARBONDALE&lt;br /&gt;
                                   |&lt;br /&gt;
                                   |                            192.168.30.0/24&lt;br /&gt;
  BOULDER [10.2.0.1] --------------/                            192.168.130.0/24&lt;br /&gt;
  &lt;br /&gt;
 192.168.20.0/24&lt;br /&gt;
 192.168.120.0/24&lt;br /&gt;
&amp;lt;/tt&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The Tinc VPN itself will use the dedicated network 192.168.0.0/29.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
= Install And Configure Common Tinc Settings =&lt;br /&gt;
&lt;br /&gt;
On all three routers:&lt;br /&gt;
&lt;br /&gt;
== Install Tinc ==&lt;br /&gt;
&lt;br /&gt;
  {{Cmd|apk add tinc}}&lt;br /&gt;
&lt;br /&gt;
== Load Tun module ==&lt;br /&gt;
&lt;br /&gt;
  {{Cmd|modprobe tun}}&lt;br /&gt;
  {{Cmd|echo &amp;quot;tun&amp;quot; &amp;gt;&amp;gt; /etc/modules}}&lt;br /&gt;
&lt;br /&gt;
== Create the directory tree For Tinc Configuration ==&lt;br /&gt;
 &lt;br /&gt;
  We need to create a name for our VPN.  In this example, we will call it &amp;quot;mesh&amp;quot;.  A network interface will be created with the network name.&lt;br /&gt;
&lt;br /&gt;
  {{Cmd|mkdir -p /etc/tinc/mesh/hosts}}&lt;br /&gt;
 &lt;br /&gt;
== Tell the tinc daemon which network(s) to load ==&lt;br /&gt;
&lt;br /&gt;
  {{Cmd|echo NETWORK: mesh &amp;gt; /etc/conf.d/tinc.networks}}&lt;br /&gt;
&lt;br /&gt;
= Install And Configure Per Server Settings =&lt;br /&gt;
&lt;br /&gt;
On each router, create a /etc/tinc/mesh/tinc.conf file.  This example is for Aspen:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tt&amp;gt;&lt;br /&gt;
 Name=aspen&lt;br /&gt;
 Device=/dev/net/tun&lt;br /&gt;
&amp;lt;/tt&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Change the Name to be Boulder and Carbondale on the other servers.&lt;br /&gt;
&lt;br /&gt;
On each router, create a /etc/tinc/mesh/tinc-up script.  Again for Aspen:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tt&amp;gt;&lt;br /&gt;
 # This is for Aspen&lt;br /&gt;
 ip link set $INTERFACE up&lt;br /&gt;
 ip addr add 192.168.0.1/29 dev $INTERFACE&lt;br /&gt;
 &lt;br /&gt;
 # route TO Aspen (leave commented out on Aspen&lt;br /&gt;
 #    uncomment on the other two)&lt;br /&gt;
 # ip route add 192.168.10.0/24 dev $INTERFACE&lt;br /&gt;
 # ip route add 192.168.110.0/24 dev $INTERFACE&lt;br /&gt;
 &lt;br /&gt;
 # route TO Boulder (leave commented out on Boulder&lt;br /&gt;
 #    uncomment on the other two)&lt;br /&gt;
 ip route add 192.168.20.0/24 dev $INTERFACE&lt;br /&gt;
 ip route add 192.168.120.0/24 dev $INTERFACE&lt;br /&gt;
 &lt;br /&gt;
 # route TO Carbondale (leave commented out on Carbondale&lt;br /&gt;
 #    uncomment on the other two)&lt;br /&gt;
 ip route add 192.168.30.0/24 dev $INTERFACE&lt;br /&gt;
 ip route add 192.168.130.0/24 dev $INTERFACE&lt;br /&gt;
&amp;lt;/tt&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The ip route statements tells the local gateway to route traffic bound for the other two campuses through the tinc VPN interface.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Make the script executable:&lt;br /&gt;
&lt;br /&gt;
{{Cmd|chmod a+x /etc/tinc/mesh/tinc-up}}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Create the site specific configuration file ==&lt;br /&gt;
&lt;br /&gt;
Each site has a specific configuration file &#039;&#039;that is shared will all other sites&#039;&#039;. &lt;br /&gt;
&lt;br /&gt;
=== Aspen ===&lt;br /&gt;
&lt;br /&gt;
Create /etc/tinc/mesh/hosts/aspen:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tt&amp;gt;&lt;br /&gt;
 Subnet = 192.168.0.1/32&lt;br /&gt;
 Address = 10.1.0.1&lt;br /&gt;
 ConnectTo = boulder&lt;br /&gt;
 ConnectTo = carbondale&lt;br /&gt;
 &lt;br /&gt;
 Subnet = 192.168.10.0/24&lt;br /&gt;
 Subnet = 192.168.110.0/24&lt;br /&gt;
&amp;lt;/tt&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Boulder ===&lt;br /&gt;
&lt;br /&gt;
Create /etc/tinc/mesh/hosts/boulder:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tt&amp;gt;&lt;br /&gt;
 Subnet = 192.168.0.2/32&lt;br /&gt;
 Address = 10.2.0.1&lt;br /&gt;
 ConnectTo = aspen&lt;br /&gt;
 ConnectTo = carbondale&lt;br /&gt;
 &lt;br /&gt;
 Subnet = 192.168.20.0/24&lt;br /&gt;
 Subnet = 192.168.120.0/24&lt;br /&gt;
&amp;lt;/tt&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Carbondale ===&lt;br /&gt;
&lt;br /&gt;
Create /etc/tinc/mesh/hosts/carbondale:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tt&amp;gt;&lt;br /&gt;
 Subnet = 192.168.0.3/32&lt;br /&gt;
 Address = 10.3.0.1&lt;br /&gt;
 ConnectTo = aspen&lt;br /&gt;
 ConnectTo = boulder&lt;br /&gt;
&lt;br /&gt;
 Subnet = 192.168.30.0/24&lt;br /&gt;
 Subnet = 192.168.130.0/24&lt;br /&gt;
&amp;lt;/tt&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Note that while in the tinc-up script we specify a /29 mask (entire broadcast domain) the host file contains a /32 mask.  This may be counterintuitive, but it is what allows the tinc daemon to know which broadcast packets are for &#039;&#039;this&#039;&#039; instance.&lt;br /&gt;
&lt;br /&gt;
Also note that while we add the routes for all the other networks in the tinc-up script, we add only the subnets for &#039;&#039;this&#039;&#039; instance in the host file.&lt;br /&gt;
&lt;br /&gt;
The ConnectTo statements connect to both of the other nodes.  This creates a mesh network.  If there are explicit ConnectTo statements between all nodes, then if, for instance, connectivity between Aspen and Carbondale is lost, traffic will flow Aspen-&amp;gt;Boulder-&amp;gt;Carbondale.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Create the public and private keys ==&lt;br /&gt;
&lt;br /&gt;
On each node, run:&lt;br /&gt;
&lt;br /&gt;
{{Cmd|tincd -n mesh -K}}&lt;br /&gt;
&lt;br /&gt;
It will generate the public and private RSA keys, and prompt you if its ok to put them in:&lt;br /&gt;
&lt;br /&gt;
 /etc/tinc/mesh/rsa_key.priv&lt;br /&gt;
 /etc/tinc/mesh/hosts/&#039;&#039;hostname&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
This is acceptable.&lt;br /&gt;
&lt;br /&gt;
== Copy the host file to the other hosts ==&lt;br /&gt;
&lt;br /&gt;
For each node, scp (or other means) the /etc/tinc/mesh/hosts/&#039;&#039;hostname&#039;&#039; file to the other node.  In the end, the hosts directory on all three nodes will have three identical files.&lt;br /&gt;
&lt;br /&gt;
== Directory tree for a running tinc configuration ==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tt&amp;gt;&lt;br /&gt;
 /etc/tinc&lt;br /&gt;
 /etc/tinc/mesh&lt;br /&gt;
 /etc/tinc/mesh/rsa_key.priv               &amp;lt;- unique to each host&lt;br /&gt;
 /etc/tinc/mesh/tinc.conf                  &amp;lt;- unique to each host&lt;br /&gt;
 /etc/tinc/mesh/tinc-up                    &amp;lt;- unique to each host&lt;br /&gt;
 /etc/tinc/mesh/hosts &lt;br /&gt;
 /etc/tinc/mesh/hosts/aspen                &amp;lt;- same on all hosts&lt;br /&gt;
 /etc/tinc/mesh/hosts/boulder              &amp;lt;- same on all hosts&lt;br /&gt;
 /etc/tinc/mesh/hosts/carbondale           &amp;lt;- same on all hosts&lt;br /&gt;
&amp;lt;/tt&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Start tincd ==&lt;br /&gt;
&lt;br /&gt;
 rc-update add tincd&lt;br /&gt;
 openrc&lt;br /&gt;
 lbu ci&lt;br /&gt;
&lt;br /&gt;
If the gateways forward ipv4, and there are no other firewall rules between sites, you should be able to ping any host from any other site.&lt;/div&gt;</summary>
		<author><name>Nangel</name></author>
	</entry>
	<entry>
		<id>https://wiki.alpinelinux.org/w/index.php?title=Development_using_git:Documentation&amp;diff=15358</id>
		<title>Development using git:Documentation</title>
		<link rel="alternate" type="text/html" href="https://wiki.alpinelinux.org/w/index.php?title=Development_using_git:Documentation&amp;diff=15358"/>
		<updated>2018-07-23T17:25:35Z</updated>

		<summary type="html">&lt;p&gt;Nangel: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;* [http://www.kernel.org/pub/software/scm/git/docs/ Git Tutorial]&lt;br /&gt;
* [http://git.or.cz/course/svn.html Git - SVN Crash Course] (quickstart if you know svn) &lt;br /&gt;
* [http://cworth.org/hgbook-git/tour/ A tour of git: the basics] &#039;&#039;&#039;Recommended&#039;&#039;&#039; &lt;br /&gt;
* [http://book.git-scm.com/ The Git Community Book]&lt;br /&gt;
* [https://jwiegley.github.io/git-from-the-bottom-up/  Git From the Bottom Up]&lt;br /&gt;
* [http://sourcemage.org/Git%20guide Very good Git guide]&lt;br /&gt;
&lt;br /&gt;
[[Category:Development]]&lt;/div&gt;</summary>
		<author><name>Nangel</name></author>
	</entry>
	<entry>
		<id>https://wiki.alpinelinux.org/w/index.php?title=Gaming_on_Alpine&amp;diff=14485</id>
		<title>Gaming on Alpine</title>
		<link rel="alternate" type="text/html" href="https://wiki.alpinelinux.org/w/index.php?title=Gaming_on_Alpine&amp;diff=14485"/>
		<updated>2018-02-09T21:51:12Z</updated>

		<summary type="html">&lt;p&gt;Nangel: /* List of games available on Alpine Linux */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&#039;&#039;&#039;Gaming on Alpine&#039;&#039;&#039; is a thing.&lt;br /&gt;
&lt;br /&gt;
== Installing games ==&lt;br /&gt;
&lt;br /&gt;
 sudo apk add micro-tetris&lt;br /&gt;
&lt;br /&gt;
== Permissions ==&lt;br /&gt;
&lt;br /&gt;
To make sure your account is in the games group.  You could do.&lt;br /&gt;
&lt;br /&gt;
 sudo gpasswd -a name games&lt;br /&gt;
&lt;br /&gt;
Log off then relog back on.&lt;br /&gt;
&lt;br /&gt;
== List of games available on Alpine Linux ==&lt;br /&gt;
&lt;br /&gt;
* [http://www.advancemame.it/ AdvanceMAME] - advancemame -- Arcade Simulator&lt;br /&gt;
* [http://frotz.sourceforge.net/ Frotz] - frotz -- Z machine (Infocom interactive fiction) Interpreter&lt;br /&gt;
* [http://home.flightgear.org FlightGear] - flightgear -- Flight Simulator&lt;br /&gt;
* [https://en.wikipedia.org/wiki/GNU_Chess GNU Chess] - gnuchess -- Play chess against the computer&lt;br /&gt;
* [https://github.com/troglobit/tetris Micro Tetris] - micro-tetris -- Uses ANSI escape sequences and can fit in embedded devices&lt;br /&gt;
* [https://www.minetest.net/ Minetest] - minetest -- An Inspired Minecraft game&lt;br /&gt;
* [https://en.wikipedia.org/wiki/OpenTTD OpenTTD] - openttd -- A business simulation game&lt;br /&gt;
* [http://www.xonotic.org/ Xonotic] - xonotic -- A FPS arena game&lt;br /&gt;
&lt;br /&gt;
== Game related software ==&lt;br /&gt;
&lt;br /&gt;
* [https://en.wikipedia.org/wiki/Wine_(software) Wine] - wine -- It is typically used to play windows games&lt;br /&gt;
* [https://obsproject.com/ OBS Studio] - obs-studio -- It is used to live stream a gaming session&lt;/div&gt;</summary>
		<author><name>Nangel</name></author>
	</entry>
	<entry>
		<id>https://wiki.alpinelinux.org/w/index.php?title=Gaming_on_Alpine&amp;diff=14464</id>
		<title>Gaming on Alpine</title>
		<link rel="alternate" type="text/html" href="https://wiki.alpinelinux.org/w/index.php?title=Gaming_on_Alpine&amp;diff=14464"/>
		<updated>2018-02-07T16:50:28Z</updated>

		<summary type="html">&lt;p&gt;Nangel: /* List of games available on Alpine Linux */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&#039;&#039;&#039;Gaming on Alpine&#039;&#039;&#039; is a thing.&lt;br /&gt;
&lt;br /&gt;
== Installing games ==&lt;br /&gt;
&lt;br /&gt;
 sudo apk add micro-tetris&lt;br /&gt;
&lt;br /&gt;
== List of games available on Alpine Linux ==&lt;br /&gt;
&lt;br /&gt;
* [http://www.advancemame.it/ AdvanceMAME]-- Arcade Simulator&lt;br /&gt;
* [http://home.flightgear.org FlightGear] -- Flight Simulator&lt;br /&gt;
* [https://en.wikipedia.org/wiki/GNU_Chess GNU Chess] - gnuchess -- Play chess against the computer&lt;br /&gt;
* [https://github.com/troglobit/tetris Micro Tetris] - micro-tetris -- Uses ANSI escape sequences and can fit in embedded devices&lt;br /&gt;
* [https://www.minetest.net/ Minetest] - minetest -- An Inspired Minecraft game&lt;br /&gt;
* [https://en.wikipedia.org/wiki/OpenTTD OpenTTD] - openttd -- A business simulation game&lt;br /&gt;
* [http://www.xonotic.org/ Xonotic] - xonotic -- A FPS arena game&lt;br /&gt;
&lt;br /&gt;
== Game related software ==&lt;br /&gt;
&lt;br /&gt;
* [https://en.wikipedia.org/wiki/Wine_(software) Wine] - wine -- It is typically used to play windows games&lt;br /&gt;
* [https://obsproject.com/ OBS Studio] - obs-studio -- It is used to live stream a gaming session&lt;/div&gt;</summary>
		<author><name>Nangel</name></author>
	</entry>
	<entry>
		<id>https://wiki.alpinelinux.org/w/index.php?title=Gaming_on_Alpine&amp;diff=14463</id>
		<title>Gaming on Alpine</title>
		<link rel="alternate" type="text/html" href="https://wiki.alpinelinux.org/w/index.php?title=Gaming_on_Alpine&amp;diff=14463"/>
		<updated>2018-02-07T16:49:30Z</updated>

		<summary type="html">&lt;p&gt;Nangel: /* List of games available on Alpine Linux */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&#039;&#039;&#039;Gaming on Alpine&#039;&#039;&#039; is a thing.&lt;br /&gt;
&lt;br /&gt;
== Installing games ==&lt;br /&gt;
&lt;br /&gt;
 sudo apk add micro-tetris&lt;br /&gt;
&lt;br /&gt;
== List of games available on Alpine Linux ==&lt;br /&gt;
&lt;br /&gt;
* [http://www.advancemame.it/] - AdvanveMAME -- Arcade Simulator&lt;br /&gt;
* [http://home.flightgear.org] - Flightgear -- Flight Simulator&lt;br /&gt;
* [https://en.wikipedia.org/wiki/GNU_Chess GNU Chess] - gnuchess -- Play chess against the computer&lt;br /&gt;
* [https://github.com/troglobit/tetris Micro Tetris] - micro-tetris -- Uses ANSI escape sequences and can fit in embedded devices&lt;br /&gt;
* [https://www.minetest.net/ Minetest] - minetest -- An Inspired Minecraft game&lt;br /&gt;
* [https://en.wikipedia.org/wiki/OpenTTD OpenTTD] - openttd -- A business simulation game&lt;br /&gt;
* [http://www.xonotic.org/ Xonotic] - xonotic -- A FPS arena game&lt;br /&gt;
&lt;br /&gt;
== Game related software ==&lt;br /&gt;
&lt;br /&gt;
* [https://en.wikipedia.org/wiki/Wine_(software) Wine] - wine -- It is typically used to play windows games&lt;br /&gt;
* [https://obsproject.com/ OBS Studio] - obs-studio -- It is used to live stream a gaming session&lt;/div&gt;</summary>
		<author><name>Nangel</name></author>
	</entry>
	<entry>
		<id>https://wiki.alpinelinux.org/w/index.php?title=User_talk:Nangel&amp;diff=14253</id>
		<title>User talk:Nangel</title>
		<link rel="alternate" type="text/html" href="https://wiki.alpinelinux.org/w/index.php?title=User_talk:Nangel&amp;diff=14253"/>
		<updated>2017-12-31T23:15:53Z</updated>

		<summary type="html">&lt;p&gt;Nangel: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== HAProxy TLS frontend for LXC http backends ==&lt;br /&gt;
&lt;br /&gt;
We are going to use HAProxy to do TLS negotiation for several LXC containers serving various websites. LetsEncrypt TLS keys will be maintained on the HAProxy service.  &lt;br /&gt;
&lt;br /&gt;
=== HAProxy and LetsEncrypt ===&lt;br /&gt;
&lt;br /&gt;
1. Set up DNS to point all the domains to the haproxy address(es):&lt;br /&gt;
       curly.example.com   A 192.168.0.1&lt;br /&gt;
       larry.example.com   A 192.168.0.1&lt;br /&gt;
       moe.example.com   A 192.168.0.1&lt;br /&gt;
&lt;br /&gt;
2. Get some httpd server running on 127.0.0.1&lt;br /&gt;
This will only be used for the let&#039;s encrypt auth challenge, so we will use busybox httpd.&lt;br /&gt;
  apk add busybox-extras&lt;br /&gt;
  /etc/conf.d/httpd:&lt;br /&gt;
    # Config for running busybox httpd on loopback address&lt;br /&gt;
    # We use it for the ACME auth challenge with Lets Encrypt&lt;br /&gt;
                                                                 &lt;br /&gt;
    HTTPD_OPTS=&amp;quot;-p 127.0.0.1:80 -u nobody:nobody -h /etc/haproxy/www&amp;quot;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
  /etc/haproxy/haproxy.cfg&lt;br /&gt;
global&lt;br /&gt;
 uid 65534&lt;br /&gt;
 gid 65534&lt;br /&gt;
 log /dev/log uucp&lt;br /&gt;
 maxconn 8000&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
defaults&lt;br /&gt;
  maxconn 8000&lt;br /&gt;
  timeout connect 15s&lt;br /&gt;
  timeout server 30m&lt;br /&gt;
  timeout client 30m&lt;br /&gt;
  option tcpka&lt;br /&gt;
  log global&lt;br /&gt;
  option tcplog&lt;br /&gt;
  option log-health-checks&lt;br /&gt;
  option log-separate-errors&lt;br /&gt;
  option forwardfor&lt;br /&gt;
  option http-server-close&lt;br /&gt;
  mode http&lt;br /&gt;
&lt;br /&gt;
 stats enable&lt;br /&gt;
 stats uri /stats&lt;br /&gt;
 stats realm haproxy\ stats&lt;br /&gt;
 stats auth letmein:password&lt;br /&gt;
&lt;br /&gt;
# For the &amp;quot;./well-known&amp;quot; uris - we send to the local &lt;br /&gt;
# busybox httpd process.  This is so haproxy has access&lt;br /&gt;
# to the certs from LetsEncrypt &lt;br /&gt;
frontend http-in&lt;br /&gt;
        mode http&lt;br /&gt;
        bind &amp;lt;public_ip&amp;gt;:80&lt;br /&gt;
        acl is_acme_uri path_beg /.well-known&lt;br /&gt;
        use_backend letsencrypt if is_acme_uri&lt;br /&gt;
&lt;br /&gt;
backend letsencrypt&lt;br /&gt;
        server letsencrypt 127.0.0.1&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
rc-update add http&lt;br /&gt;
rc-update add haproxy&lt;br /&gt;
openrc&lt;br /&gt;
&lt;br /&gt;
3. Set up acme-client&lt;br /&gt;
  apk add acme-client&lt;/div&gt;</summary>
		<author><name>Nangel</name></author>
	</entry>
	<entry>
		<id>https://wiki.alpinelinux.org/w/index.php?title=LXC&amp;diff=13769</id>
		<title>LXC</title>
		<link rel="alternate" type="text/html" href="https://wiki.alpinelinux.org/w/index.php?title=LXC&amp;diff=13769"/>
		<updated>2017-09-13T15:32:03Z</updated>

		<summary type="html">&lt;p&gt;Nangel: /* Ubuntu template */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[http://lxc.sourceforge.net/ Linux Containers (LXC)] provides containers similar BSD Jails, Linux VServer and Solaris Zones. It gives the impression of virtualization, but shares the kernel and resources with the &amp;quot;host&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
== Installation ==&lt;br /&gt;
Install the required packages:&lt;br /&gt;
{{Cmd|apk add lxc bridge}}&lt;br /&gt;
&lt;br /&gt;
If you want to create containers other then type alpine you will need lxc-templates&lt;br /&gt;
&lt;br /&gt;
{{Cmd|apk add lxc-templates}}&lt;br /&gt;
&lt;br /&gt;
== Prepare network on host ==&lt;br /&gt;
Set up a [[bridge]] on the host. Example &#039;&#039;/etc/network/interfaces&#039;&#039;:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
auto br0&lt;br /&gt;
iface br0 inet dhcp&lt;br /&gt;
    bridge-ports eth0&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Create a network configuration template for the guests, &#039;&#039;/etc/lxc/lxc.conf&#039;&#039;:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
lxc.network.type = veth&lt;br /&gt;
lxc.network.link = br0&lt;br /&gt;
lxc.network.flags = up&lt;br /&gt;
lxc.network.hwaddr = fe:xx:xx:xx:xx:xx&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Grsecurity restrictions ==&lt;br /&gt;
&lt;br /&gt;
Some restrictions will be applied when using a grsecurity kernel (Alpine Linux default kernel).&lt;br /&gt;
The most notable is the use of lxc-attach which will not be allowed because of GRKERNSEC_CHROOT_CAPS.&lt;br /&gt;
To solve this we will have to disable this grsec restriction by creating a sysctl profile for lxc.&lt;br /&gt;
Create the following file &#039;&#039;/etc/sysctl.d/10-lxc.conf&#039;&#039; and add:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
kernel.grsecurity.chroot_caps = 0&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
There are a few other restrictions that can prevent proper container functionality. &lt;br /&gt;
When things do not work as expected always check the kernel log with dmesg to see if grsec prevented things from happening.&lt;br /&gt;
&lt;br /&gt;
Other possible restrictions are:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
kernel.grsecurity.chroot_deny_chroot = 0&lt;br /&gt;
kernel.grsecurity.chroot_deny_mount = 0&lt;br /&gt;
kernel.grsecurity.chroot_deny_mknod = 0&lt;br /&gt;
kernel.grsecurity.chroot_deny_chmod = 0&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
When you finished creating your new sysctl profile you can apply it by restarting sysctl service&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
rc-service sysctl restart&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
NOTE: Always consult the [https://en.wikibooks.org/wiki/Grsecurity/Appendix/Grsecurity_and_PaX_Configuration_Options Grsecurity documentation] before applying these settings.&lt;br /&gt;
&lt;br /&gt;
== Create a guest ==&lt;br /&gt;
&lt;br /&gt;
=== Alpine Template ===&lt;br /&gt;
&lt;br /&gt;
{{Cmd|lxc-create -n guest1 -f /etc/lxc/lxc.conf -t alpine}}&lt;br /&gt;
&lt;br /&gt;
This will create a &#039;&#039;/var/lib/lxc/guest1&#039;&#039; directory with a &#039;&#039;config&#039;&#039; file and a &#039;&#039;rootfs&#039;&#039; directory.&lt;br /&gt;
&lt;br /&gt;
Note that by default alpine template &#039;&#039;&#039;does not have networking service on&#039;&#039;&#039;, you will need to add it using lxc-console&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
If running on x86_64 architecture, it is possible to create a 32bit guest:&lt;br /&gt;
&lt;br /&gt;
{{Cmd|lxc-create -n guest1 -f /etc/lxc/lxc.conf -t alpine -- --arch x86}}&lt;br /&gt;
&lt;br /&gt;
=== Debian template ===&lt;br /&gt;
&lt;br /&gt;
In order to create a debian template container you will need to install some packages:&lt;br /&gt;
&lt;br /&gt;
{{Cmd|apk add debootstrap rsync}}&lt;br /&gt;
&lt;br /&gt;
Also you will need to turn off some grsecurity chroot options otherwise the debootstrap will fail:&lt;br /&gt;
&lt;br /&gt;
{{Cmd|echo 0 &amp;gt; /proc/sys/kernel/grsecurity/chroot_caps&lt;br /&gt;
echo 0 &amp;gt; /proc/sys/kernel/grsecurity/chroot_deny_chroot&lt;br /&gt;
echo 0 &amp;gt; /proc/sys/kernel/grsecurity/chroot_deny_mount&lt;br /&gt;
echo 0 &amp;gt; /proc/sys/kernel/grsecurity/chroot_deny_mknod&lt;br /&gt;
echo 0 &amp;gt; /proc/sys/kernel/grsecurity/chroot_deny_chmod&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
Please remember to turn them back on, or just simply reboot the system.&lt;br /&gt;
&lt;br /&gt;
Now you can run:&lt;br /&gt;
{{Cmd|SUITE{{=}}wheezy lxc-create -n guest1 -f /etc/lxc/lxc.conf -t debian}}&lt;br /&gt;
&lt;br /&gt;
=== Ubuntu template ===&lt;br /&gt;
&lt;br /&gt;
In order to create an ubuntu template container you will need to turn off some grsecurity chroot options:&lt;br /&gt;
&lt;br /&gt;
{{Cmd|echo 0 &amp;gt; /proc/sys/kernel/grsecurity/chroot_caps&lt;br /&gt;
echo 0 &amp;gt; /proc/sys/kernel/grsecurity/chroot_deny_chroot&lt;br /&gt;
echo 0 &amp;gt; /proc/sys/kernel/grsecurity/chroot_deny_mount&lt;br /&gt;
echo 0 &amp;gt; /proc/sys/kernel/grsecurity/chroot_deny_mknod&lt;br /&gt;
echo 0 &amp;gt; /proc/sys/kernel/grsecurity/chroot_deny_chmod&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
Please remember to turn them back on, or just simply reboot the system.&lt;br /&gt;
&lt;br /&gt;
Now you can run (replace %MIRROR% with the actual hostname, for example: http://us.archive.ubuntu.com/ubuntu/)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
lxc-create -n guest2 -f /etc/lxc/default.conf -t ubuntu -- -r xenial -a amd64 -u user --password secretpassword --mirror $MIRROR&lt;br /&gt;
&lt;br /&gt;
=== Unprivileged LXC images (Debian / Ubuntu / Centos etc..) ===&lt;br /&gt;
&lt;br /&gt;
{{Cmd|apk add gnupg xz&lt;br /&gt;
lxc-create -n container-name -t download}}&lt;br /&gt;
&amp;amp; choose the Distribution | Release | Architecture.&lt;br /&gt;
&lt;br /&gt;
To be able to login to a Debian container you currently need to:&lt;br /&gt;
{{Cmd|rm /lib/systemd/system/container-getty\@.service}}&lt;br /&gt;
&lt;br /&gt;
You can also [http://without-systemd.org/wiki/index.php/How_to_remove_systemd_from_a_Debian_jessie/sid_installationers remove Systemd from the container].&lt;br /&gt;
&lt;br /&gt;
== Starting/Stopping the guest ==&lt;br /&gt;
Create a symlink to the &#039;&#039;/etc/init.d/lxc&#039;&#039; script for your guest.&lt;br /&gt;
{{Cmd|ln -s lxc /etc/init.d/lxc.guest1}}&lt;br /&gt;
&lt;br /&gt;
You can start your guest with:&lt;br /&gt;
{{Cmd|/etc/init.d/lxc.guest1 start}}&lt;br /&gt;
&lt;br /&gt;
Stop it with:&lt;br /&gt;
{{Cmd|/etc/init.d/lxc.guest1 stop}}&lt;br /&gt;
&lt;br /&gt;
Make it autostart on boot up with:&lt;br /&gt;
{{Cmd| rc-update add lxc.guest1}}&lt;br /&gt;
&lt;br /&gt;
You can also add to the container config: &amp;lt;code&amp;gt;lxc.start.auto = 1&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;amp; {{Cmd|rc-update add lxc}}&lt;br /&gt;
&lt;br /&gt;
to autostart containers by the lxc service only.&lt;br /&gt;
&lt;br /&gt;
== Connecting to the guest ==&lt;br /&gt;
By default sshd is not installed, so you will have to attach to the container or connect to the virtual console. This is done with:&lt;br /&gt;
&lt;br /&gt;
=== Attach to container ===&lt;br /&gt;
&lt;br /&gt;
{{Cmd|lxc-attach -n guest1}}&lt;br /&gt;
&lt;br /&gt;
Just type exit to detach the container again (please do check the grsec notes above)&lt;br /&gt;
&lt;br /&gt;
=== Connect to virtual console ===&lt;br /&gt;
&lt;br /&gt;
{{Cmd|lxc-console -n guest1}}&lt;br /&gt;
&lt;br /&gt;
To disconnect from it, press {{key|Ctrl}}+{{key|a}} {{key|q}}&lt;br /&gt;
&lt;br /&gt;
== Deleting a guest ==&lt;br /&gt;
Make sure the guest is stopped and run:&lt;br /&gt;
{{Cmd|lxc-destroy -n guest1}}&lt;br /&gt;
This will erase everything, without asking any questions. It is equivalent to: {{Cmd|rm -r /var/lib/lxc/guest1}}&lt;br /&gt;
&lt;br /&gt;
== Advanced ==&lt;br /&gt;
&lt;br /&gt;
=== Creating a LXC container without modifying your network interfaces ===&lt;br /&gt;
&lt;br /&gt;
The problem with bridging is that the interface you bridge gets replaced with your new bridge interface.&lt;br /&gt;
That is to say that say you have an interface eth0 that you want to bridge, your eth0 interface gets replaced with the br0 interface that you create. It also means that the interface you use needs to be placed into promiscuous mode to catch all the traffic that could de destined to the other side of the bridge, which again may not be what you want.&lt;br /&gt;
&lt;br /&gt;
The solution is to create a dummy network interface, bridge that, and set up NAT so that traffic out of your bridge interface gets pushed through the interface of your choice.&lt;br /&gt;
&lt;br /&gt;
So, first, lets create that dummy interface (thanks to ncopa for talking me out of macvlan and pointing out the dummy interface kernel module)&lt;br /&gt;
&lt;br /&gt;
{{Cmd|modprobe dummy}}&lt;br /&gt;
&lt;br /&gt;
This will create a dummy interface called dummy0 on your host.&lt;br /&gt;
&lt;br /&gt;
Now we will create a bridge called br0&lt;br /&gt;
&lt;br /&gt;
{{Cmd |brctl addbr br0&lt;br /&gt;
brctl setfd br0 0 }}&lt;br /&gt;
&lt;br /&gt;
and then make that dummy interface one end of the bridge&lt;br /&gt;
&lt;br /&gt;
{{Cmd | brctl addif br0 dummy0 }}&lt;br /&gt;
&lt;br /&gt;
Next, let&#039;s give that bridged interface a reason to exists&lt;br /&gt;
&lt;br /&gt;
{{ Cmd | ifconfig br0 192.168.1.1 netmask 255.255.255.0 up}}&lt;br /&gt;
&lt;br /&gt;
Create a file for your container, let&#039;s say /etc/lxc/bridgenat.conf, with the following settings.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
lxc.network.type = veth&lt;br /&gt;
lxc.network.flags = up&lt;br /&gt;
lxc.network.link = br0&lt;br /&gt;
lxc.network.name = eth1&lt;br /&gt;
lxc.network.ipv4 = 192.168.1.2/24&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
and build your container with that file&lt;br /&gt;
&lt;br /&gt;
{{ Cmd | lxc-create -n alpine -f /etc/lxc/bridgenat.conf -t alpine }}&lt;br /&gt;
&lt;br /&gt;
You should now be able to ping your container from your hosts, and your host from your container.&lt;br /&gt;
&lt;br /&gt;
Your container needs to know where to push traffic that isn&#039;t within it&#039;s subnet. To do so, we tell the container to route through the bridge interface br0&lt;br /&gt;
From inside the container run&lt;br /&gt;
&lt;br /&gt;
{{ Cmd | route add default gw 192.168.1.1 }}&lt;br /&gt;
&lt;br /&gt;
The next step is you push the traffic coming from your private subnet over br0 out through your internet facing interface, or any interface you chose&lt;br /&gt;
&lt;br /&gt;
We are messing with your IP tables here, so make sure these settings don&#039;t conflict with anything you may have already set up, obviously.&lt;br /&gt;
&lt;br /&gt;
Say eth0 was your internet facing network interface, and br0 is the name of the bridge you made earlier, we&#039;d do this:&lt;br /&gt;
&lt;br /&gt;
{{ Cmd | echo 1 &amp;gt; /proc/sys/net/ipv4/ip_forward&lt;br /&gt;
iptables --table nat --append POSTROUTING --out-interface eth0 -j MASQUERADE&lt;br /&gt;
iptables --append FORWARD --in-interface br0 -j ACCEPT&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
Now you should be able to route through your bridge interface to the internet facing interface of your host from your container, just like at home!&lt;br /&gt;
&lt;br /&gt;
You could also have a dhcp server running on your host, and set it up to give IP addresses from your private subnet to any container that requests it, and then have one template for multiple alpine LXC containers, perfect for alpine development :)&lt;br /&gt;
&lt;br /&gt;
=== Using static IP ===&lt;br /&gt;
&lt;br /&gt;
If you&#039;re using static IP, you need to configure this properly on guest&#039;s /etc/network/interfaces. To stay on the above example, modify &#039;&#039;/var/lib/lxc/guest1/rootfs/etc/network/interfaces&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
from&lt;br /&gt;
&lt;br /&gt;
 #auto lo&lt;br /&gt;
     iface lo inet loopback&lt;br /&gt;
 auto eth0&lt;br /&gt;
     iface eth0 inet &#039;&#039;&#039;dhcp&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
to &lt;br /&gt;
&lt;br /&gt;
 #auto lo&lt;br /&gt;
     iface lo inet loopback&lt;br /&gt;
 auto eth0&lt;br /&gt;
     iface eth0 inet &#039;&#039;&#039;static&#039;&#039;&#039;&lt;br /&gt;
     address &amp;lt;lxc-container-ip&amp;gt;   # IP which the lxc container should use&lt;br /&gt;
     gateway &amp;lt;gateway-ip&amp;gt;         # IP of gateway to use, mostly same as on lxc-host&lt;br /&gt;
     netmask &amp;lt;netmask&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== mem and swap ===&lt;br /&gt;
&lt;br /&gt;
{{Cmd|vim /boot/extlinux.conf}}&lt;br /&gt;
&lt;br /&gt;
{{Cmd|&lt;br /&gt;
  APPEND initrd{{=}}initramfs-3.10.13-1-grsec root{{=}}UUID{{=}}7cd8789f-5659-40f8-9548-ae8f89c918ab modules{{=}}sd-mod,usb-storage,ext4 quiet cgroup_enable{{=}}memory swapaccount{{=}}1&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
=== checkconfig ===&lt;br /&gt;
{{Cmd|lxc-checkconfig}}&lt;br /&gt;
&lt;br /&gt;
{{Cmd|&lt;br /&gt;
Kernel configuration not found at /proc/config.gz; searching...&lt;br /&gt;
Kernel configuration found at /boot/config-3.10.13-1-grsec&lt;br /&gt;
--- Namespaces ---&lt;br /&gt;
Namespaces: enabled&lt;br /&gt;
Utsname namespace: enabled&lt;br /&gt;
Ipc namespace: enabled&lt;br /&gt;
Pid namespace: enabled&lt;br /&gt;
User namespace: missing&lt;br /&gt;
Network namespace: enabled&lt;br /&gt;
Multiple /dev/pts instances: enabled&lt;br /&gt;
&lt;br /&gt;
--- Control groups ---&lt;br /&gt;
Cgroup: enabled&lt;br /&gt;
Cgroup clone_children flag: enabled&lt;br /&gt;
Cgroup device: enabled&lt;br /&gt;
Cgroup sched: enabled&lt;br /&gt;
Cgroup cpu account: enabled&lt;br /&gt;
Cgroup memory controller: missing&lt;br /&gt;
Cgroup cpuset: enabled&lt;br /&gt;
&lt;br /&gt;
--- Misc ---&lt;br /&gt;
Veth pair device: enabled&lt;br /&gt;
Macvlan: enabled&lt;br /&gt;
Vlan: enabled&lt;br /&gt;
File capabilities: enabled&lt;br /&gt;
&lt;br /&gt;
Note : Before booting a new kernel, you can check its configuration&lt;br /&gt;
usage : CONFIG{{=}}/path/to/config /usr/bin/lxc-checkconfig&lt;br /&gt;
&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
=== VirtualBox ===&lt;br /&gt;
&lt;br /&gt;
In order for network to work on containers you need to set &amp;quot;Promiscuous Mode&amp;quot; to &amp;quot;Allow All&amp;quot; in VirtualBox settings for the network adapter.&lt;br /&gt;
&lt;br /&gt;
[[File:VirtualBoxNetworkAdapter.jpg]]&lt;br /&gt;
&lt;br /&gt;
[[Category:Virtualization]]&lt;br /&gt;
&lt;br /&gt;
=== postgreSQL ===&lt;br /&gt;
&lt;br /&gt;
Inside the container run: {{Cmd|chmod go+w /dev/null}} to fix {{Cmd|rc-service postgresql start}}&lt;br /&gt;
&lt;br /&gt;
=== openVPN ===&lt;br /&gt;
&lt;br /&gt;
see [[Setting_up_a_OpenVPN_server#openVPN_and_LXC]]&lt;br /&gt;
&lt;br /&gt;
== LXC 1.0 Additional information ==&lt;br /&gt;
&lt;br /&gt;
Some info regarding new features in LXC 1.0&lt;br /&gt;
 &lt;br /&gt;
https://www.stgraber.org/2013/12/20/lxc-1-0-blog-post-series/&lt;/div&gt;</summary>
		<author><name>Nangel</name></author>
	</entry>
	<entry>
		<id>https://wiki.alpinelinux.org/w/index.php?title=LXC&amp;diff=13768</id>
		<title>LXC</title>
		<link rel="alternate" type="text/html" href="https://wiki.alpinelinux.org/w/index.php?title=LXC&amp;diff=13768"/>
		<updated>2017-09-12T14:51:48Z</updated>

		<summary type="html">&lt;p&gt;Nangel: /* Ubuntu template */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[http://lxc.sourceforge.net/ Linux Containers (LXC)] provides containers similar BSD Jails, Linux VServer and Solaris Zones. It gives the impression of virtualization, but shares the kernel and resources with the &amp;quot;host&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
== Installation ==&lt;br /&gt;
Install the required packages:&lt;br /&gt;
{{Cmd|apk add lxc bridge}}&lt;br /&gt;
&lt;br /&gt;
If you want to create containers other then type alpine you will need lxc-templates&lt;br /&gt;
&lt;br /&gt;
{{Cmd|apk add lxc-templates}}&lt;br /&gt;
&lt;br /&gt;
== Prepare network on host ==&lt;br /&gt;
Set up a [[bridge]] on the host. Example &#039;&#039;/etc/network/interfaces&#039;&#039;:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
auto br0&lt;br /&gt;
iface br0 inet dhcp&lt;br /&gt;
    bridge-ports eth0&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Create a network configuration template for the guests, &#039;&#039;/etc/lxc/lxc.conf&#039;&#039;:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
lxc.network.type = veth&lt;br /&gt;
lxc.network.link = br0&lt;br /&gt;
lxc.network.flags = up&lt;br /&gt;
lxc.network.hwaddr = fe:xx:xx:xx:xx:xx&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Grsecurity restrictions ==&lt;br /&gt;
&lt;br /&gt;
Some restrictions will be applied when using a grsecurity kernel (Alpine Linux default kernel).&lt;br /&gt;
The most notable is the use of lxc-attach which will not be allowed because of GRKERNSEC_CHROOT_CAPS.&lt;br /&gt;
To solve this we will have to disable this grsec restriction by creating a sysctl profile for lxc.&lt;br /&gt;
Create the following file &#039;&#039;/etc/sysctl.d/10-lxc.conf&#039;&#039; and add:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
kernel.grsecurity.chroot_caps = 0&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
There are a few other restrictions that can prevent proper container functionality. &lt;br /&gt;
When things do not work as expected always check the kernel log with dmesg to see if grsec prevented things from happening.&lt;br /&gt;
&lt;br /&gt;
Other possible restrictions are:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
kernel.grsecurity.chroot_deny_chroot = 0&lt;br /&gt;
kernel.grsecurity.chroot_deny_mount = 0&lt;br /&gt;
kernel.grsecurity.chroot_deny_mknod = 0&lt;br /&gt;
kernel.grsecurity.chroot_deny_chmod = 0&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
When you finished creating your new sysctl profile you can apply it by restarting sysctl service&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
rc-service sysctl restart&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
NOTE: Always consult the [https://en.wikibooks.org/wiki/Grsecurity/Appendix/Grsecurity_and_PaX_Configuration_Options Grsecurity documentation] before applying these settings.&lt;br /&gt;
&lt;br /&gt;
== Create a guest ==&lt;br /&gt;
&lt;br /&gt;
=== Alpine Template ===&lt;br /&gt;
&lt;br /&gt;
{{Cmd|lxc-create -n guest1 -f /etc/lxc/lxc.conf -t alpine}}&lt;br /&gt;
&lt;br /&gt;
This will create a &#039;&#039;/var/lib/lxc/guest1&#039;&#039; directory with a &#039;&#039;config&#039;&#039; file and a &#039;&#039;rootfs&#039;&#039; directory.&lt;br /&gt;
&lt;br /&gt;
Note that by default alpine template &#039;&#039;&#039;does not have networking service on&#039;&#039;&#039;, you will need to add it using lxc-console&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
If running on x86_64 architecture, it is possible to create a 32bit guest:&lt;br /&gt;
&lt;br /&gt;
{{Cmd|lxc-create -n guest1 -f /etc/lxc/lxc.conf -t alpine -- --arch x86}}&lt;br /&gt;
&lt;br /&gt;
=== Debian template ===&lt;br /&gt;
&lt;br /&gt;
In order to create a debian template container you will need to install some packages:&lt;br /&gt;
&lt;br /&gt;
{{Cmd|apk add debootstrap rsync}}&lt;br /&gt;
&lt;br /&gt;
Also you will need to turn off some grsecurity chroot options otherwise the debootstrap will fail:&lt;br /&gt;
&lt;br /&gt;
{{Cmd|echo 0 &amp;gt; /proc/sys/kernel/grsecurity/chroot_caps&lt;br /&gt;
echo 0 &amp;gt; /proc/sys/kernel/grsecurity/chroot_deny_chroot&lt;br /&gt;
echo 0 &amp;gt; /proc/sys/kernel/grsecurity/chroot_deny_mount&lt;br /&gt;
echo 0 &amp;gt; /proc/sys/kernel/grsecurity/chroot_deny_mknod&lt;br /&gt;
echo 0 &amp;gt; /proc/sys/kernel/grsecurity/chroot_deny_chmod&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
Please remember to turn them back on, or just simply reboot the system.&lt;br /&gt;
&lt;br /&gt;
Now you can run:&lt;br /&gt;
{{Cmd|SUITE{{=}}wheezy lxc-create -n guest1 -f /etc/lxc/lxc.conf -t debian}}&lt;br /&gt;
&lt;br /&gt;
=== Ubuntu template ===&lt;br /&gt;
&lt;br /&gt;
In order to create an ubuntu template container you will need to turn off some grsecurity chroot options:&lt;br /&gt;
&lt;br /&gt;
{{Cmd|echo 0 &amp;gt; /proc/sys/kernel/grsecurity/chroot_caps&lt;br /&gt;
echo 0 &amp;gt; /proc/sys/kernel/grsecurity/chroot_deny_chroot&lt;br /&gt;
echo 0 &amp;gt; /proc/sys/kernel/grsecurity/chroot_deny_mount&lt;br /&gt;
echo 0 &amp;gt; /proc/sys/kernel/grsecurity/chroot_deny_mknod&lt;br /&gt;
echo 0 &amp;gt; /proc/sys/kernel/grsecurity/chroot_deny_chmod&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
Please remember to turn them back on, or just simply reboot the system.&lt;br /&gt;
&lt;br /&gt;
Now you can run (replace %MIRROR% with the actual hostname, for example: http://us.archive.ubuntu.com/ubuntu/)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
lxc-create -n guest2 -f /etc/lxc/lxc.conf -t ubuntu -- -r xenial -a amd64 -u user --password secretpassword --mirror $MIRROR&lt;br /&gt;
&lt;br /&gt;
=== Unprivileged LXC images (Debian / Ubuntu / Centos etc..) ===&lt;br /&gt;
&lt;br /&gt;
{{Cmd|apk add gnupg xz&lt;br /&gt;
lxc-create -n container-name -t download}}&lt;br /&gt;
&amp;amp; choose the Distribution | Release | Architecture.&lt;br /&gt;
&lt;br /&gt;
To be able to login to a Debian container you currently need to:&lt;br /&gt;
{{Cmd|rm /lib/systemd/system/container-getty\@.service}}&lt;br /&gt;
&lt;br /&gt;
You can also [http://without-systemd.org/wiki/index.php/How_to_remove_systemd_from_a_Debian_jessie/sid_installationers remove Systemd from the container].&lt;br /&gt;
&lt;br /&gt;
== Starting/Stopping the guest ==&lt;br /&gt;
Create a symlink to the &#039;&#039;/etc/init.d/lxc&#039;&#039; script for your guest.&lt;br /&gt;
{{Cmd|ln -s lxc /etc/init.d/lxc.guest1}}&lt;br /&gt;
&lt;br /&gt;
You can start your guest with:&lt;br /&gt;
{{Cmd|/etc/init.d/lxc.guest1 start}}&lt;br /&gt;
&lt;br /&gt;
Stop it with:&lt;br /&gt;
{{Cmd|/etc/init.d/lxc.guest1 stop}}&lt;br /&gt;
&lt;br /&gt;
Make it autostart on boot up with:&lt;br /&gt;
{{Cmd| rc-update add lxc.guest1}}&lt;br /&gt;
&lt;br /&gt;
You can also add to the container config: &amp;lt;code&amp;gt;lxc.start.auto = 1&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;amp; {{Cmd|rc-update add lxc}}&lt;br /&gt;
&lt;br /&gt;
to autostart containers by the lxc service only.&lt;br /&gt;
&lt;br /&gt;
== Connecting to the guest ==&lt;br /&gt;
By default sshd is not installed, so you will have to attach to the container or connect to the virtual console. This is done with:&lt;br /&gt;
&lt;br /&gt;
=== Attach to container ===&lt;br /&gt;
&lt;br /&gt;
{{Cmd|lxc-attach -n guest1}}&lt;br /&gt;
&lt;br /&gt;
Just type exit to detach the container again (please do check the grsec notes above)&lt;br /&gt;
&lt;br /&gt;
=== Connect to virtual console ===&lt;br /&gt;
&lt;br /&gt;
{{Cmd|lxc-console -n guest1}}&lt;br /&gt;
&lt;br /&gt;
To disconnect from it, press {{key|Ctrl}}+{{key|a}} {{key|q}}&lt;br /&gt;
&lt;br /&gt;
== Deleting a guest ==&lt;br /&gt;
Make sure the guest is stopped and run:&lt;br /&gt;
{{Cmd|lxc-destroy -n guest1}}&lt;br /&gt;
This will erase everything, without asking any questions. It is equivalent to: {{Cmd|rm -r /var/lib/lxc/guest1}}&lt;br /&gt;
&lt;br /&gt;
== Advanced ==&lt;br /&gt;
&lt;br /&gt;
=== Creating a LXC container without modifying your network interfaces ===&lt;br /&gt;
&lt;br /&gt;
The problem with bridging is that the interface you bridge gets replaced with your new bridge interface.&lt;br /&gt;
That is to say that say you have an interface eth0 that you want to bridge, your eth0 interface gets replaced with the br0 interface that you create. It also means that the interface you use needs to be placed into promiscuous mode to catch all the traffic that could de destined to the other side of the bridge, which again may not be what you want.&lt;br /&gt;
&lt;br /&gt;
The solution is to create a dummy network interface, bridge that, and set up NAT so that traffic out of your bridge interface gets pushed through the interface of your choice.&lt;br /&gt;
&lt;br /&gt;
So, first, lets create that dummy interface (thanks to ncopa for talking me out of macvlan and pointing out the dummy interface kernel module)&lt;br /&gt;
&lt;br /&gt;
{{Cmd|modprobe dummy}}&lt;br /&gt;
&lt;br /&gt;
This will create a dummy interface called dummy0 on your host.&lt;br /&gt;
&lt;br /&gt;
Now we will create a bridge called br0&lt;br /&gt;
&lt;br /&gt;
{{Cmd |brctl addbr br0&lt;br /&gt;
brctl setfd br0 0 }}&lt;br /&gt;
&lt;br /&gt;
and then make that dummy interface one end of the bridge&lt;br /&gt;
&lt;br /&gt;
{{Cmd | brctl addif br0 dummy0 }}&lt;br /&gt;
&lt;br /&gt;
Next, let&#039;s give that bridged interface a reason to exists&lt;br /&gt;
&lt;br /&gt;
{{ Cmd | ifconfig br0 192.168.1.1 netmask 255.255.255.0 up}}&lt;br /&gt;
&lt;br /&gt;
Create a file for your container, let&#039;s say /etc/lxc/bridgenat.conf, with the following settings.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
lxc.network.type = veth&lt;br /&gt;
lxc.network.flags = up&lt;br /&gt;
lxc.network.link = br0&lt;br /&gt;
lxc.network.name = eth1&lt;br /&gt;
lxc.network.ipv4 = 192.168.1.2/24&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
and build your container with that file&lt;br /&gt;
&lt;br /&gt;
{{ Cmd | lxc-create -n alpine -f /etc/lxc/bridgenat.conf -t alpine }}&lt;br /&gt;
&lt;br /&gt;
You should now be able to ping your container from your hosts, and your host from your container.&lt;br /&gt;
&lt;br /&gt;
Your container needs to know where to push traffic that isn&#039;t within it&#039;s subnet. To do so, we tell the container to route through the bridge interface br0&lt;br /&gt;
From inside the container run&lt;br /&gt;
&lt;br /&gt;
{{ Cmd | route add default gw 192.168.1.1 }}&lt;br /&gt;
&lt;br /&gt;
The next step is you push the traffic coming from your private subnet over br0 out through your internet facing interface, or any interface you chose&lt;br /&gt;
&lt;br /&gt;
We are messing with your IP tables here, so make sure these settings don&#039;t conflict with anything you may have already set up, obviously.&lt;br /&gt;
&lt;br /&gt;
Say eth0 was your internet facing network interface, and br0 is the name of the bridge you made earlier, we&#039;d do this:&lt;br /&gt;
&lt;br /&gt;
{{ Cmd | echo 1 &amp;gt; /proc/sys/net/ipv4/ip_forward&lt;br /&gt;
iptables --table nat --append POSTROUTING --out-interface eth0 -j MASQUERADE&lt;br /&gt;
iptables --append FORWARD --in-interface br0 -j ACCEPT&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
Now you should be able to route through your bridge interface to the internet facing interface of your host from your container, just like at home!&lt;br /&gt;
&lt;br /&gt;
You could also have a dhcp server running on your host, and set it up to give IP addresses from your private subnet to any container that requests it, and then have one template for multiple alpine LXC containers, perfect for alpine development :)&lt;br /&gt;
&lt;br /&gt;
=== Using static IP ===&lt;br /&gt;
&lt;br /&gt;
If you&#039;re using static IP, you need to configure this properly on guest&#039;s /etc/network/interfaces. To stay on the above example, modify &#039;&#039;/var/lib/lxc/guest1/rootfs/etc/network/interfaces&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
from&lt;br /&gt;
&lt;br /&gt;
 #auto lo&lt;br /&gt;
     iface lo inet loopback&lt;br /&gt;
 auto eth0&lt;br /&gt;
     iface eth0 inet &#039;&#039;&#039;dhcp&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
to &lt;br /&gt;
&lt;br /&gt;
 #auto lo&lt;br /&gt;
     iface lo inet loopback&lt;br /&gt;
 auto eth0&lt;br /&gt;
     iface eth0 inet &#039;&#039;&#039;static&#039;&#039;&#039;&lt;br /&gt;
     address &amp;lt;lxc-container-ip&amp;gt;   # IP which the lxc container should use&lt;br /&gt;
     gateway &amp;lt;gateway-ip&amp;gt;         # IP of gateway to use, mostly same as on lxc-host&lt;br /&gt;
     netmask &amp;lt;netmask&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== mem and swap ===&lt;br /&gt;
&lt;br /&gt;
{{Cmd|vim /boot/extlinux.conf}}&lt;br /&gt;
&lt;br /&gt;
{{Cmd|&lt;br /&gt;
  APPEND initrd{{=}}initramfs-3.10.13-1-grsec root{{=}}UUID{{=}}7cd8789f-5659-40f8-9548-ae8f89c918ab modules{{=}}sd-mod,usb-storage,ext4 quiet cgroup_enable{{=}}memory swapaccount{{=}}1&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
=== checkconfig ===&lt;br /&gt;
{{Cmd|lxc-checkconfig}}&lt;br /&gt;
&lt;br /&gt;
{{Cmd|&lt;br /&gt;
Kernel configuration not found at /proc/config.gz; searching...&lt;br /&gt;
Kernel configuration found at /boot/config-3.10.13-1-grsec&lt;br /&gt;
--- Namespaces ---&lt;br /&gt;
Namespaces: enabled&lt;br /&gt;
Utsname namespace: enabled&lt;br /&gt;
Ipc namespace: enabled&lt;br /&gt;
Pid namespace: enabled&lt;br /&gt;
User namespace: missing&lt;br /&gt;
Network namespace: enabled&lt;br /&gt;
Multiple /dev/pts instances: enabled&lt;br /&gt;
&lt;br /&gt;
--- Control groups ---&lt;br /&gt;
Cgroup: enabled&lt;br /&gt;
Cgroup clone_children flag: enabled&lt;br /&gt;
Cgroup device: enabled&lt;br /&gt;
Cgroup sched: enabled&lt;br /&gt;
Cgroup cpu account: enabled&lt;br /&gt;
Cgroup memory controller: missing&lt;br /&gt;
Cgroup cpuset: enabled&lt;br /&gt;
&lt;br /&gt;
--- Misc ---&lt;br /&gt;
Veth pair device: enabled&lt;br /&gt;
Macvlan: enabled&lt;br /&gt;
Vlan: enabled&lt;br /&gt;
File capabilities: enabled&lt;br /&gt;
&lt;br /&gt;
Note : Before booting a new kernel, you can check its configuration&lt;br /&gt;
usage : CONFIG{{=}}/path/to/config /usr/bin/lxc-checkconfig&lt;br /&gt;
&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
=== VirtualBox ===&lt;br /&gt;
&lt;br /&gt;
In order for network to work on containers you need to set &amp;quot;Promiscuous Mode&amp;quot; to &amp;quot;Allow All&amp;quot; in VirtualBox settings for the network adapter.&lt;br /&gt;
&lt;br /&gt;
[[File:VirtualBoxNetworkAdapter.jpg]]&lt;br /&gt;
&lt;br /&gt;
[[Category:Virtualization]]&lt;br /&gt;
&lt;br /&gt;
=== postgreSQL ===&lt;br /&gt;
&lt;br /&gt;
Inside the container run: {{Cmd|chmod go+w /dev/null}} to fix {{Cmd|rc-service postgresql start}}&lt;br /&gt;
&lt;br /&gt;
=== openVPN ===&lt;br /&gt;
&lt;br /&gt;
see [[Setting_up_a_OpenVPN_server#openVPN_and_LXC]]&lt;br /&gt;
&lt;br /&gt;
== LXC 1.0 Additional information ==&lt;br /&gt;
&lt;br /&gt;
Some info regarding new features in LXC 1.0&lt;br /&gt;
 &lt;br /&gt;
https://www.stgraber.org/2013/12/20/lxc-1-0-blog-post-series/&lt;/div&gt;</summary>
		<author><name>Nangel</name></author>
	</entry>
	<entry>
		<id>https://wiki.alpinelinux.org/w/index.php?title=Install_Alpine_on_Amazon_EC2&amp;diff=13725</id>
		<title>Install Alpine on Amazon EC2</title>
		<link rel="alternate" type="text/html" href="https://wiki.alpinelinux.org/w/index.php?title=Install_Alpine_on_Amazon_EC2&amp;diff=13725"/>
		<updated>2017-08-08T16:53:24Z</updated>

		<summary type="html">&lt;p&gt;Nangel: /* Create an EBS backed Alpine Linux AMI */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;The goal here is to have a &amp;quot;1GB&amp;quot; (the smallest possible) EBS &#039;virtual usb stick&#039; that can boot and run Alpine Linux.  &lt;br /&gt;
&lt;br /&gt;
= Create an EBS backed Alpine Linux AMI =&lt;br /&gt;
&lt;br /&gt;
{{Note|You need to do this process at least once in each availability region.  EBS can&#039;t be shared between Ireland and California, for instance.}}&lt;br /&gt;
&lt;br /&gt;
* Create an Amazon instance in the desired availability region.  A micro instance is fine - we will need it only long enough to create our EBS usb stick.&lt;br /&gt;
* Create a new 1GB EBS volume &lt;br /&gt;
* Attach the new volume to the running instance&lt;br /&gt;
* The new volume will have a name like /dev/xvdf or such&lt;br /&gt;
* Format the volume as ext4 {{Cmd|mke2fs -t ext4 /dev/xvdf}}  &#039;&#039;Do not partition it - just format the whole volume&#039;&#039;&lt;br /&gt;
* wget a &#039;&#039;&#039;x86_64&#039;&#039;&#039; iso and extract it to the new volume. 32bit will not work. &lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
wget http://dl-4.alpinelinux.org/alpine/v3.6/releases/x86_64/alpine-virt-3.6.2-x86_64.iso&lt;br /&gt;
mkdir target&lt;br /&gt;
mkdir source&lt;br /&gt;
mount /dev/xvdf target&lt;br /&gt;
mount -o loop alpine-virt-3.6.2-x86_64.iso source&lt;br /&gt;
cp -av source/boot target&lt;br /&gt;
cp -av source/apks target&lt;br /&gt;
umount source&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
* Create a grub.conf on the new partition.  &lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
mkdir -p target/boot/grub&lt;br /&gt;
cat - &amp;gt;target/boot/grub/grub.conf &amp;lt;&amp;lt;EOF &lt;br /&gt;
default=0&lt;br /&gt;
timeout=3&lt;br /&gt;
hiddenmenu&lt;br /&gt;
&lt;br /&gt;
title Alpine Linux&lt;br /&gt;
root (hd0)&lt;br /&gt;
kernel /boot/vmlinuz-virthardened alpine_dev=xvda1:ext4 modules=loop,squashfs,sd-mod,ext4 console=hvc0 pax_nouderef BOOT_IMAGE=/boot/vmlinuz-virthardened&lt;br /&gt;
initrd /boot/initramfs-virthardened&lt;br /&gt;
EOF&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
:* Syslinux automatically adds BOOT_IMAGE to the kernel command line; grub does not, so make sure you specify it in the grub.conf&lt;br /&gt;
:* You do not need any other grub files.&lt;br /&gt;
* symlink the grub.conf to menu.lst&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
ln -sf ./grub.conf target/boot/grub/menu.lst&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
* Create an amazon.apkovl.tar.gz file to put on the target &lt;br /&gt;
** This is probably easiest on a local alpine linux instance.  Make sure the following are configured:&lt;br /&gt;
*** eth0 uses dhcp&lt;br /&gt;
*** networking is set to autostart&lt;br /&gt;
*** sshd is installed and set to autostart&lt;br /&gt;
*** Your ssh public key is in /root/.ssh/authorized_keys&lt;br /&gt;
*** The root password is set to something&lt;br /&gt;
*** lbu include root/.ssh&lt;br /&gt;
*** (optional) - Delete the /etc/ssh/*key* files, so they are created on the new box&lt;br /&gt;
** {{Cmd|lbu package amazon.apkovl.tar.gz}} {{Warning|If you are packaging on a 32bit box, manually delete etc/apk/arch from the apkovl.tar.gz file}}&lt;br /&gt;
** Copy amazon.apkovl.tar.gz to target/ &lt;br /&gt;
* Unmount target&lt;br /&gt;
* &#039;&#039;&#039;Do the following from the Amazon web interface&#039;&#039;&#039;&lt;br /&gt;
** Detach the new volume&lt;br /&gt;
** Make note of the volume ID&lt;br /&gt;
** Launch NEW instance.  Use defaults, amazon linux, micro; we are going to canibalize it in a bit, so defaults are fine here.&lt;br /&gt;
** Once the instance starts, &#039;&#039;stop&#039;&#039; but &#039;&#039;do not terminate&#039;&#039; the instance.&lt;br /&gt;
** Under EBS, detach the existing volume, and attach the alpine linux volume as /dev/sda1 (note the 1 at the end)&lt;br /&gt;
** Restart the instance&lt;br /&gt;
* Log in and make sure it works&lt;br /&gt;
* Do any final cleanups necessary, and if necessary lbu ci&lt;br /&gt;
** Only make configs that are appropriate for an AMI, we are going to snapshot this instance and create an AMI out of it&lt;br /&gt;
* Again from the Amazon web interface&lt;br /&gt;
** Delete the 8GB volume that is no longer needed&lt;br /&gt;
** &#039;&#039;Stop&#039;&#039; but do not terminate the instance&lt;br /&gt;
** Right click the stopped instance and choose &#039;Create Image (EBS AMI)&#039;&lt;br /&gt;
*** Image name should be unique for the image - example AlpineLinux-2.4.5&lt;br /&gt;
*** Description can be anything - example &#039;Base AlpineLinux Installation - no services&#039;&lt;br /&gt;
* Done. &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Category:Virtualization]]&lt;/div&gt;</summary>
		<author><name>Nangel</name></author>
	</entry>
	<entry>
		<id>https://wiki.alpinelinux.org/w/index.php?title=Install_Alpine_on_Amazon_EC2&amp;diff=13694</id>
		<title>Install Alpine on Amazon EC2</title>
		<link rel="alternate" type="text/html" href="https://wiki.alpinelinux.org/w/index.php?title=Install_Alpine_on_Amazon_EC2&amp;diff=13694"/>
		<updated>2017-07-21T17:18:57Z</updated>

		<summary type="html">&lt;p&gt;Nangel: /* Create an EBS backed Alpine Linux AMI */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;The goal here is to have a &amp;quot;1GB&amp;quot; (the smallest possible) EBS &#039;virtual usb stick&#039; that can boot and run Alpine Linux.  &lt;br /&gt;
&lt;br /&gt;
= Create an EBS backed Alpine Linux AMI =&lt;br /&gt;
&lt;br /&gt;
{{Note|You need to do this process at least once in each availability region.  EBS can&#039;t be shared between Ireland and California, for instance.}}&lt;br /&gt;
&lt;br /&gt;
* Create an Amazon instance in the desired availability region.  A micro instance is fine - we will need it only long enough to create our EBS usb stick.&lt;br /&gt;
* Create a new 1GB EBS volume &lt;br /&gt;
* Attach the new volume to the running instance&lt;br /&gt;
* The new volume will have a name like /dev/xvdf or such&lt;br /&gt;
* Format the volume as ext4 {{Cmd|mke2fs -t ext4 /dev/xvdf}}  &#039;&#039;Do not partition it - just format the whole volume&#039;&#039;&lt;br /&gt;
* wget a &#039;&#039;&#039;x86_64&#039;&#039;&#039; iso and extract it to the new volume. 32bit will not work. &lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
wget http://dl-4.alpinelinux.org/alpine/v3.6/releases/x86_64/alpine-virt-3.6.2-x86_64.iso&lt;br /&gt;
mkdir target&lt;br /&gt;
mkdir source&lt;br /&gt;
mount /dev/xvdf target&lt;br /&gt;
mount -o loop alpine-virt-3.6.2-x86_64.iso source&lt;br /&gt;
cp -av source/boot target&lt;br /&gt;
cp -av source/apks target&lt;br /&gt;
umount source&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
* Create a grub.conf on the new partition.  &lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
mkdir -p target/boot/grub&lt;br /&gt;
cat - &amp;gt;target/boot/grub/grub.conf &amp;lt;&amp;lt;EOF &lt;br /&gt;
default=0&lt;br /&gt;
timeout=3&lt;br /&gt;
hiddenmenu&lt;br /&gt;
&lt;br /&gt;
title Alpine Linux&lt;br /&gt;
root (hd0)&lt;br /&gt;
kernel /boot/vmlinuz-virthardened alpine_dev=xvda1:ext4 modules=loop,squashfs,sd-mod,ext4 console=hvc0 pax_nouderef BOOT_IMAGE=/boot/vmlinuz-virthardened&lt;br /&gt;
initrd /boot/initramfs-virthardened&lt;br /&gt;
EOF&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
:* Syslinux automatically adds BOOT_IMAGE to the kernel command line; grub does not, so make sure you specify it in the grub.conf&lt;br /&gt;
:* You do not need any other grub files - just boot.conf&lt;br /&gt;
* symlink the grub.conf to menu.lst&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
ln -sf ./grub.conf target/boot/grub/menu.lst&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
* Create an amazon.apkovl.tar.gz file to put on the target &lt;br /&gt;
** This is probably easiest on a local alpine linux instance.  Make sure the following are configured:&lt;br /&gt;
*** eth0 uses dhcp&lt;br /&gt;
*** networking is set to autostart&lt;br /&gt;
*** sshd is installed and set to autostart&lt;br /&gt;
*** Your ssh public key is in /root/.ssh/authorized_keys&lt;br /&gt;
*** The root password is set to something&lt;br /&gt;
*** lbu include root/.ssh&lt;br /&gt;
*** (optional) - Delete the /etc/ssh/*key* files, so they are created on the new box&lt;br /&gt;
** {{Cmd|lbu package amazon.apkovl.tar.gz}} {{Warning|If you are packaging on a 32bit box, manually delete etc/apk/arch from the apkovl.tar.gz file}}&lt;br /&gt;
** Copy amazon.apkovl.tar.gz to target/ &lt;br /&gt;
* Unmount target&lt;br /&gt;
* &#039;&#039;&#039;Do the following from the Amazon web interface&#039;&#039;&#039;&lt;br /&gt;
** Detach the new volume&lt;br /&gt;
** Make note of the volume ID&lt;br /&gt;
** Launch NEW instance.  Use defaults, amazon linux, micro; we are going to canibalize it in a bit, so defaults are fine here.&lt;br /&gt;
** Once the instance starts, &#039;&#039;stop&#039;&#039; but &#039;&#039;do not terminate&#039;&#039; the instance.&lt;br /&gt;
** Under EBS, detach the existing volume, and attach the alpine linux volume as /dev/sda1 (note the 1 at the end)&lt;br /&gt;
** Restart the instance&lt;br /&gt;
* Log in and make sure it works&lt;br /&gt;
* Do any final cleanups necessary, and if necessary lbu ci&lt;br /&gt;
** Only make configs that are appropriate for an AMI, we are going to snapshot this instance and create an AMI out of it&lt;br /&gt;
* Again from the Amazon web interface&lt;br /&gt;
** Delete the 8GB volume that is no longer needed&lt;br /&gt;
** &#039;&#039;Stop&#039;&#039; but do not terminate the instance&lt;br /&gt;
** Right click the stopped instance and choose &#039;Create Image (EBS AMI)&#039;&lt;br /&gt;
*** Image name should be unique for the image - example AlpineLinux-2.4.5&lt;br /&gt;
*** Description can be anything - example &#039;Base AlpineLinux Installation - no services&#039;&lt;br /&gt;
* Done. &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Category:Virtualization]]&lt;/div&gt;</summary>
		<author><name>Nangel</name></author>
	</entry>
	<entry>
		<id>https://wiki.alpinelinux.org/w/index.php?title=Install_Alpine_on_Amazon_EC2&amp;diff=13677</id>
		<title>Install Alpine on Amazon EC2</title>
		<link rel="alternate" type="text/html" href="https://wiki.alpinelinux.org/w/index.php?title=Install_Alpine_on_Amazon_EC2&amp;diff=13677"/>
		<updated>2017-07-08T15:29:57Z</updated>

		<summary type="html">&lt;p&gt;Nangel: Update for 3.6.2 alpine-virt image&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;The goal here is to have a &amp;quot;1GB&amp;quot; (the smallest possible) EBS &#039;virtual usb stick&#039; that can boot and run Alpine Linux.  &lt;br /&gt;
&lt;br /&gt;
= Create an EBS backed Alpine Linux AMI =&lt;br /&gt;
&lt;br /&gt;
{{Note|You need to do this process at least once in each availability region.  EBS can&#039;t be shared between Ireland and California, for instance.}}&lt;br /&gt;
&lt;br /&gt;
* Create an Amazon instance in the desired availability region.  A micro instance is fine - we will need it only long enough to create our EBS usb stick.&lt;br /&gt;
* Create a new 1GB EBS volume &lt;br /&gt;
* Attach the new volume to the running instance&lt;br /&gt;
* The new volume will have a name like /dev/xvdf or such&lt;br /&gt;
* Format the volume as ext4 {{Cmd|mke2fs -t ext4 /dev/xvdf}}  &#039;&#039;Do not partition it - just format the whole volume&#039;&#039;&lt;br /&gt;
* wget a &#039;&#039;&#039;x86_64&#039;&#039;&#039; iso and extract it to the new volume. 32bit will not work. &lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
wget http://dl-4.alpinelinux.org/alpine/v2.4/releases/x86_64/alpine-virt-3.6.2-x86_64.iso&lt;br /&gt;
mkdir target&lt;br /&gt;
mkdir source&lt;br /&gt;
mount /dev/xvdf target&lt;br /&gt;
mount -o loop alpine-virt-3.6.2-x86_64.iso source&lt;br /&gt;
cp -av source/boot target&lt;br /&gt;
cp -av source/apks target&lt;br /&gt;
umount source&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
* Create a grub.conf on the new partition.  &lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
mkdir -p target/boot/grub&lt;br /&gt;
cat - &amp;gt;target/boot/grub/grub.conf &amp;lt;&amp;lt;EOF &lt;br /&gt;
default=0&lt;br /&gt;
timeout=3&lt;br /&gt;
hiddenmenu&lt;br /&gt;
&lt;br /&gt;
title Alpine Linux&lt;br /&gt;
root (hd0)&lt;br /&gt;
kernel /boot/vmlinuz-virthardened alpine_dev=xvda1:ext4 modules=loop,squashfs,sd-mod,ext4 console=hvc0 pax_nouderef BOOT_IMAGE=/boot/vmlinuz-virthardened&lt;br /&gt;
initrd /boot/initramfs-virthardened&lt;br /&gt;
EOF&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
:* Syslinux automatically adds BOOT_IMAGE to the kernel command line; grub does not, so make sure you specify it in the grub.conf&lt;br /&gt;
:* You do not need any other grub files - just boot.conf&lt;br /&gt;
* symlink the grub.conf to menu.lst&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
ln -sf ./grub.conf target/boot/grub/menu.lst&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
* Create an amazon.apkovl.tar.gz file to put on the target &lt;br /&gt;
** This is probably easiest on a local alpine linux instance.  Make sure the following are configured:&lt;br /&gt;
*** eth0 uses dhcp&lt;br /&gt;
*** networking is set to autostart&lt;br /&gt;
*** sshd is installed and set to autostart&lt;br /&gt;
*** Your ssh public key is in /root/.ssh/authorized_keys&lt;br /&gt;
*** The root password is set to something&lt;br /&gt;
*** lbu include root/.ssh&lt;br /&gt;
*** (optional) - Delete the /etc/ssh/*key* files, so they are created on the new box&lt;br /&gt;
** {{Cmd|lbu package amazon.apkovl.tar.gz}} {{Warning|If you are packaging on a 32bit box, manually delete etc/apk/arch from the apkovl.tar.gz file}}&lt;br /&gt;
** Copy amazon.apkovl.tar.gz to target/ &lt;br /&gt;
* Unmount target&lt;br /&gt;
* &#039;&#039;&#039;Do the following from the Amazon web interface&#039;&#039;&#039;&lt;br /&gt;
** Detach the new volume&lt;br /&gt;
** Make note of the volume ID&lt;br /&gt;
** Launch NEW instance.  Use defaults, amazon linux, micro; we are going to canibalize it in a bit, so defaults are fine here.&lt;br /&gt;
** Once the instance starts, &#039;&#039;stop&#039;&#039; but &#039;&#039;do not terminate&#039;&#039; the instance.&lt;br /&gt;
** Under EBS, detach the existing volume, and attach the alpine linux volume as /dev/sda1 (note the 1 at the end)&lt;br /&gt;
** Restart the instance&lt;br /&gt;
* Log in and make sure it works&lt;br /&gt;
* Do any final cleanups necessary, and if necessary lbu ci&lt;br /&gt;
** Only make configs that are appropriate for an AMI, we are going to snapshot this instance and create an AMI out of it&lt;br /&gt;
* Again from the Amazon web interface&lt;br /&gt;
** Delete the 8GB volume that is no longer needed&lt;br /&gt;
** &#039;&#039;Stop&#039;&#039; but do not terminate the instance&lt;br /&gt;
** Right click the stopped instance and choose &#039;Create Image (EBS AMI)&#039;&lt;br /&gt;
*** Image name should be unique for the image - example AlpineLinux-2.4.5&lt;br /&gt;
*** Description can be anything - example &#039;Base AlpineLinux Installation - no services&#039;&lt;br /&gt;
* Done. &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Category:Virtualization]]&lt;/div&gt;</summary>
		<author><name>Nangel</name></author>
	</entry>
	<entry>
		<id>https://wiki.alpinelinux.org/w/index.php?title=Apk_internals&amp;diff=13394</id>
		<title>Apk internals</title>
		<link rel="alternate" type="text/html" href="https://wiki.alpinelinux.org/w/index.php?title=Apk_internals&amp;diff=13394"/>
		<updated>2017-05-25T21:58:26Z</updated>

		<summary type="html">&lt;p&gt;Nangel: /* Internals of apk */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;=Internals of apk=&lt;br /&gt;
&lt;br /&gt;
&amp;quot;It&#039;s a secret to all!&amp;quot;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[https://git.alpinelinux.org/cgit/apk-tools/ Read the Source, Luke!]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
See [[TODO:apk]].&lt;/div&gt;</summary>
		<author><name>Nangel</name></author>
	</entry>
	<entry>
		<id>https://wiki.alpinelinux.org/w/index.php?title=MediaWiki:Copyright&amp;diff=13307</id>
		<title>MediaWiki:Copyright</title>
		<link rel="alternate" type="text/html" href="https://wiki.alpinelinux.org/w/index.php?title=MediaWiki:Copyright&amp;diff=13307"/>
		<updated>2017-04-27T17:11:32Z</updated>

		<summary type="html">&lt;p&gt;Nangel: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&amp;lt;div align=&amp;quot;right&amp;quot;&amp;gt;&amp;lt;div id=&amp;quot;footer-inner&amp;quot;&amp;gt; &lt;br /&gt;
  &amp;lt;p&amp;gt;&amp;lt;a href=&amp;quot;Privacy_Policy#Copyright&amp;quot;&amp;gt;&amp;amp;copy; Copyright 2008-2017 Alpine Linux Development Team&amp;lt;/a&amp;gt; &lt;br /&gt;
  all rights reserved &amp;lt;/div&amp;gt;&amp;lt;/div&amp;gt;&lt;/div&gt;</summary>
		<author><name>Nangel</name></author>
	</entry>
	<entry>
		<id>https://wiki.alpinelinux.org/w/index.php?title=ISP_Mail_Server_3.x_HowTo&amp;diff=13064</id>
		<title>ISP Mail Server 3.x HowTo</title>
		<link rel="alternate" type="text/html" href="https://wiki.alpinelinux.org/w/index.php?title=ISP_Mail_Server_3.x_HowTo&amp;diff=13064"/>
		<updated>2016-11-27T23:51:55Z</updated>

		<summary type="html">&lt;p&gt;Nangel: /* Install Dovecot */  new way to specify a cert in a file&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Draft|This is a work in progress based on migrating alpinelinux mail servers to 3.x}}&lt;br /&gt;
&lt;br /&gt;
== A Full Service Mail Server ==&lt;br /&gt;
&lt;br /&gt;
This document describes installation process for the Alpine Linux 3.x platform. 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. This document superceeds the previous [[ISP Mail Server 2.x HowTo]] instructions for Alpine 2.x.  For this guide, we start with a server &#039;&#039;without&#039;&#039; ACF installed.&lt;br /&gt;
&lt;br /&gt;
The server provides:&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-cgi php-pgsql php-imap&lt;br /&gt;
&lt;br /&gt;
We are setting this up to be a multi-domain virtual web server (replace host.example.com with the actual domain):&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;mkdir -p /var/www/domains/host.example.com/www&lt;br /&gt;
cat &amp;lt;&amp;lt;-EOF &amp;gt;/var/www/domains/host.example.com/www/index.html&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;/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;
EOF&lt;br /&gt;
&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Get a web certificate, and install it.  There are several options:&lt;br /&gt;
# Use a self-signed certificate, such as [[Generating SSL certs with ACF]] &lt;br /&gt;
# Use the certificate created with &#039;&#039;&#039;setup-acf&#039;&#039;&#039;, if you installed ACF&lt;br /&gt;
# Get a certificate from a trusted root Certificate Authority, such as StartSSL.com, Thawte.com, Verisign.com, etc.&lt;br /&gt;
&lt;br /&gt;
These instructions will use a certificate issued from a self-signed ACF based CA&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;
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_fastcgi.conf&amp;quot;&lt;br /&gt;
&lt;br /&gt;
start lighttpd, test:&lt;br /&gt;
&lt;br /&gt;
  rc-update add lighttpd&lt;br /&gt;
  rc&lt;br /&gt;
&lt;br /&gt;
At this point you should be able to see the redirect page:  https://host.example.com/&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 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/9.0/data/pg_hba.conf. Since by default &amp;quot;trust&amp;quot; mechanism is for local connections only we assume using trust password-less access as safe.&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;
   \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.93 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.93/postfixadmin-2.93.tar.gz&lt;br /&gt;
 tar zxvf postfixadmin-2.93.tar.gz&lt;br /&gt;
 mkdir -p /var/www/domains/host.example.com/www/postfixadmin&lt;br /&gt;
 mv  postfixadmin-2.3.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;dovecot:SHA512-CRYPT&#039;;&lt;br /&gt;
 $CONF[&#039;authlib_default_flavor&#039;] = &#039;SHA&#039;;&lt;br /&gt;
 $CONF[&#039;dovecotpw&#039;] = &amp;quot;/usr/bin/doveadm pw&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;
&#039;&#039;&#039;NOTE:&#039;&#039;&#039; Check http://sourceforge.net/tracker/index.php?func=detail&amp;amp;aid=2859165&amp;amp;group_id=191583&amp;amp;atid=937964 if you have bug on listing domains page.&lt;br /&gt;
&lt;br /&gt;
== Install Postfix ==&lt;br /&gt;
&lt;br /&gt;
 &lt;br /&gt;
Install postfix&lt;br /&gt;
&lt;br /&gt;
 apk add postfix postfix-pgsql postfix-pcre&lt;br /&gt;
&lt;br /&gt;
The install should create a vmail user; you&#039;ll need the numeric uid/gid for the postfix main.cf file.&lt;br /&gt;
&lt;br /&gt;
 grep vmail /etc/passwd&lt;br /&gt;
&lt;br /&gt;
(we will use 102:105 in the examples below)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Create the mail directory, and assign vmail as the owner:&lt;br /&gt;
&lt;br /&gt;
 mkdir -p /var/mail/domains&lt;br /&gt;
 chown -R vmail:postdrop /var/mail/domains&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;
 # New install - don&#039;t need to be backward compatible &lt;br /&gt;
 compatibility_level = 2 &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:105&lt;br /&gt;
 virtual_uid_maps = static:102&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;
 &lt;br /&gt;
 # 100MB size limit&lt;br /&gt;
 message_size_limit = 104857600&lt;br /&gt;
 virtual_mailbox_limit = 104857600&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;
 # Silence the EAI warning on alpine linux&lt;br /&gt;
 smtputf8_enable = no&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;
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;
=== 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;
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;
Install dovecot: &lt;br /&gt;
&lt;br /&gt;
 apk add 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;
auth_mechanisms = plain login&lt;br /&gt;
auth_username_format = %Lu&lt;br /&gt;
#auth_verbose = yes&lt;br /&gt;
#auth_debug = yes&lt;br /&gt;
#auth_debug_passwords = no&lt;br /&gt;
&lt;br /&gt;
disable_plaintext_auth = no&lt;br /&gt;
&lt;br /&gt;
mail_location = maildir:/var/mail/domains/%d/%n&lt;br /&gt;
&lt;br /&gt;
first_valid_gid = 105&lt;br /&gt;
first_valid_uid = 102&lt;br /&gt;
last_valid_gid = 105&lt;br /&gt;
last_valid_uid = 102&lt;br /&gt;
&lt;br /&gt;
log_timestamp = &amp;quot;%Y-%m-%d %H:%M:%S &amp;quot;&lt;br /&gt;
login_greeting = IMAP server ready&lt;br /&gt;
&lt;br /&gt;
protocols = imap&lt;br /&gt;
&lt;br /&gt;
service anvil {&lt;br /&gt;
  client_limit = 2100&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
ssl_cert = &amp;lt;/etc/lighttpd/server-bundle.pem&lt;br /&gt;
ssl_key = &amp;lt;/etc/lighttpd/server-bundle.pem&lt;br /&gt;
&lt;br /&gt;
userdb {&lt;br /&gt;
  args = uid=102 gid=105 home=/var/mail/domains/%d/%n&lt;br /&gt;
  driver = static&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
passdb {&lt;br /&gt;
  args = /etc/dovecot/dovecot-sql.conf&lt;br /&gt;
  driver = sql&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
namespace inbox {&lt;br /&gt;
        inbox = yes&lt;br /&gt;
&lt;br /&gt;
        mailbox Trash {&lt;br /&gt;
                auto = create&lt;br /&gt;
                special_use = \Trash&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
        mailbox Spam {&lt;br /&gt;
                auto = no&lt;br /&gt;
                special_use = \Junk&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
        mailbox Ham {&lt;br /&gt;
                auto = no&lt;br /&gt;
        }&lt;br /&gt;
        mailbox Sent {&lt;br /&gt;
                auto = subscribe&lt;br /&gt;
                special_use = \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 =  SHA512-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;
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;
=== 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;
* 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;
* Edit /etc/dovecot/dovecot.conf and add the following:&lt;br /&gt;
# this is for postfix SASL (authenticated users can relay through us)&lt;br /&gt;
&lt;br /&gt;
 service auth {&lt;br /&gt;
  unix_listener /var/spool/postfix/private/auth {&lt;br /&gt;
    group = postfix&lt;br /&gt;
    mode = 0660&lt;br /&gt;
    user = postfix&lt;br /&gt;
  }&lt;br /&gt;
  unix_listener /var/spool/postfix/auth-master {&lt;br /&gt;
    group = postfix&lt;br /&gt;
    mode = 0660&lt;br /&gt;
    user = vmail&lt;br /&gt;
  }&lt;br /&gt;
  user = root&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/auth&lt;br /&gt;
 smtpd_sasl_auth_enable = yes&lt;br /&gt;
 smtpd_sasl_authenticated_header = yes&lt;br /&gt;
 broken_sasl_auth_clients = 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://wiki2.dovecot.org/LDA deliver] lda for local delivery.&lt;br /&gt;
&lt;br /&gt;
* Replace /etc/dovecot/dovecot.conf with the following:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
auth_mechanisms = plain login&lt;br /&gt;
auth_username_format = %Lu&lt;br /&gt;
#auth_verbose = yes&lt;br /&gt;
#auth_debug = yes&lt;br /&gt;
#auth_debug_passwords = no&lt;br /&gt;
&lt;br /&gt;
disable_plaintext_auth = no&lt;br /&gt;
&lt;br /&gt;
info_log_path = /var/log/dovecot-info.log&lt;br /&gt;
log_path = /var/log/dovecot.log&lt;br /&gt;
&lt;br /&gt;
mail_location = maildir:/var/mail/domains/%d/%n&lt;br /&gt;
&lt;br /&gt;
first_valid_gid = 1000&lt;br /&gt;
first_valid_uid = 1000&lt;br /&gt;
last_valid_gid = 65535&lt;br /&gt;
last_valid_uid = 65535&lt;br /&gt;
&lt;br /&gt;
log_timestamp = &amp;quot;%Y-%m-%d %H:%M:%S &amp;quot;&lt;br /&gt;
login_greeting = IMAP server ready&lt;br /&gt;
&lt;br /&gt;
protocols = imap&lt;br /&gt;
&lt;br /&gt;
service anvil {&lt;br /&gt;
  client_limit = 2100&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
service auth {&lt;br /&gt;
  unix_listener /var/spool/postfix/auth-master {&lt;br /&gt;
    group = postfix&lt;br /&gt;
    mode = 0660&lt;br /&gt;
    user = vmail&lt;br /&gt;
  }&lt;br /&gt;
  unix_listener /var/spool/postfix/private/auth {&lt;br /&gt;
    group = postfix&lt;br /&gt;
    mode = 0660&lt;br /&gt;
    user = postfix&lt;br /&gt;
  }&lt;br /&gt;
  user = root&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
service imap-login {&lt;br /&gt;
  inet_listener imap {&lt;br /&gt;
    address = 127.0.0.1&lt;br /&gt;
    port = 143&lt;br /&gt;
  }&lt;br /&gt;
  inet_listener imaps {&lt;br /&gt;
    address = *&lt;br /&gt;
    port = 993&lt;br /&gt;
  }&lt;br /&gt;
  process_limit = 1024&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
service pop3-login {&lt;br /&gt;
  process_limit = 1024&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
service dict {&lt;br /&gt;
  unix_listener dict {&lt;br /&gt;
    group =&lt;br /&gt;
    mode = 0600&lt;br /&gt;
    user = vmail&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
ssl_ca = &amp;lt;/etc/ssl/certs/&amp;lt;CA Certificate file&amp;gt;&lt;br /&gt;
ssl_cert = &amp;lt;/etc/ssl/private/&amp;lt;Public part of certificate file&amp;gt;&lt;br /&gt;
ssl_key = &amp;lt;/etc/ssl/private/&amp;lt;Private part of certificate file&amp;gt;&lt;br /&gt;
&lt;br /&gt;
passdb {&lt;br /&gt;
  args = /etc/dovecot/dovecot-pgsql.conf&lt;br /&gt;
  driver = sql&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
userdb {&lt;br /&gt;
  driver = prefetch&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
userdb {&lt;br /&gt;
  args = /etc/dovecot/dovecot-pgsql.conf&lt;br /&gt;
  driver = sql&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
plugin {&lt;br /&gt;
  quota = dict:user::proxy::quotadict&lt;br /&gt;
&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;
protocol imap {&lt;br /&gt;
  mail_plugins = autocreate 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;
protocol lda {&lt;br /&gt;
  auth_socket_path = /var/spool/postfix/auth-master&lt;br /&gt;
  mail_plugins = quota&lt;br /&gt;
  postmaster_address = postmaster@host.example.com&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;
* 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;
* 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 dovecot:root /etc/dovecot/dovecot-sql.conf&lt;br /&gt;
  chmod 600 /etc/dovecot/dovecot-sql.conf&lt;br /&gt;
  chown dovecot: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://wiki2.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 2.2 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/auth&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 followed section &#039;&#039;Relay_for_Authenticated_Users&#039;&#039;.&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;
&lt;br /&gt;
 apk add roundcubemail php-xml php-openssl php-mcrypt php-gd php-iconv php-dom php-intl php-pdo php-ldap php-pdo_pgsql php-zlib&lt;br /&gt;
&lt;br /&gt;
* Link the roundcube application back into the docroot&lt;br /&gt;
&lt;br /&gt;
 ln -s /usr/share/webapps/roundcube /var/www/domains/host.example.com/www/roundcube&lt;br /&gt;
&lt;br /&gt;
* Install &#039;&#039;roundcubemail-install&#039;&#039; package&lt;br /&gt;
&lt;br /&gt;
 apk add roundcubemail-installer&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 /var/log/roundcube&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;
&lt;br /&gt;
 /etc/init.d/lighttpd restart&lt;br /&gt;
&lt;br /&gt;
* Get the additional php modules needed:&lt;br /&gt;
 apk add curl php-phar git&lt;br /&gt;
 cd /usr/share/webapps/roundcube&lt;br /&gt;
 curl -sS https://getcomposer.org/installer | php&lt;br /&gt;
 cp composer.json-dist composer.json&lt;br /&gt;
 # Note - As of 11 Aug 2015, with Roundcube 1.1.2, there is a regression that is &lt;br /&gt;
 # fixed here: https://github.com/roundcube/roundcubemail/commit/b3e9764c311a39012de1fa8ffd0fe874fbb322ef&lt;br /&gt;
 # Update your composer.json accordingly:&lt;br /&gt;
 # -        &amp;quot;pear/mail_mime&amp;quot;: &amp;quot;&amp;gt;=1.9.0&amp;quot;,&lt;br /&gt;
 # -        &amp;quot;pear/net_smtp&amp;quot;: &amp;quot;dev-master&amp;quot;&lt;br /&gt;
 # +        &amp;quot;pear-pear.php.net/mail_mime&amp;quot;: &amp;quot;&amp;gt;=1.9.0&amp;quot;,&lt;br /&gt;
 # +        &amp;quot;pear-pear.php.net/net_smtp&amp;quot;: &amp;quot;&amp;gt;=1.6.3&amp;quot;&lt;br /&gt;
 php composer.phar install --no-dev &lt;br /&gt;
&lt;br /&gt;
* Point your browser to https://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;default port&#039;&#039; || 143&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 2 of the install to copy the files to the server&lt;br /&gt;
* You should now be able to get to roundcube at https://host.example.com/roundcube&lt;br /&gt;
&lt;br /&gt;
* After its working, the INSTALL file recommends removing the install directory.&lt;br /&gt;
&lt;br /&gt;
 apk del roundcubemail-installer&lt;br /&gt;
&lt;br /&gt;
* Disable installer mode in /etc/roundcube/main.inc.php file:&lt;br /&gt;
&lt;br /&gt;
 $rcmail_config[&#039;enable_installer&#039;] = false;&lt;br /&gt;
&lt;br /&gt;
* Change the ownership and permissions&lt;br /&gt;
&lt;br /&gt;
 cd /usr/share/webapps/roundcube&lt;br /&gt;
 chown -R root:root LICENSE UPGRADING INSTALL README CHANGELOG&lt;br /&gt;
 chmod -R 600 LICENSE UPGRADING INSTALL README CHANGELOG &lt;br /&gt;
&lt;br /&gt;
* If needed customize logos such as &#039;&#039;&#039;watermark.gif&#039;&#039;&#039;, &#039;&#039;&#039;roundcube_logo.gif&#039;&#039;&#039;, &#039;&#039;&#039;favicon.ico&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
* If you would like to disable displaying of standard logos update template files accordingly&lt;br /&gt;
&lt;br /&gt;
* Comment all entries like &#039;&#039;&#039;&amp;lt;div ... img src=&amp;quot;/images/roundcube_logo.png&amp;quot;...&#039;&#039;&#039; in files:&lt;br /&gt;
&lt;br /&gt;
 includes/header.html &lt;br /&gt;
 templates/error.html&lt;br /&gt;
 templates/messageprint.html&lt;br /&gt;
 templates/login.html&lt;br /&gt;
 templates/printmessage.html&lt;br /&gt;
&lt;br /&gt;
* Comment all entries like &#039;&#039;&#039;&amp;lt;img src=&amp;quot;/images/watermark.gif&amp;quot;...&#039;&#039;&#039; in files:&lt;br /&gt;
&lt;br /&gt;
 templates/identities.html&lt;br /&gt;
 templates/messageerror.html&lt;br /&gt;
 watermark.html&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;
* Enable &#039;&#039;create_default_folders&#039;&#039; for RoundCube&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;create_default_folders&#039;] = TRUE;&lt;br /&gt;
...&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 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 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;
* 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;
&#039;&#039;&#039;&#039;&#039;Question to experts: Is this normal to have in this script &amp;quot;WARNING:  nonstandard use of \\ in a string literal&amp;quot;?&#039;&#039;&#039;&#039;&#039;&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;
# Uncomment next five TLS... lines if you want to use LDAPs (secured). Probably you don&#039;t want it...&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. In case you uncommented TLS lines in slapd.conf use this string: OPTS=&amp;quot;-h &#039;ldaps:// ldap://&#039;&amp;quot;&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;ldap://&#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. In case you uncommented TLS lines in slapd.conf replace ldap with ldaps&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	ldap://host.example.com&lt;br /&gt;
&lt;br /&gt;
# Uncomment next three TLS... lines if you want to use LDAPs (secured). Probably you don&#039;t want it...&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 /etc/roundcube/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;br /&gt;
&lt;br /&gt;
== Optional: Enable compression in Lighttpd ==&lt;br /&gt;
&lt;br /&gt;
* Uncomment &#039;&#039;mod_compress&#039;&#039; and &#039;&#039;mod_setenv&#039;&#039; and modify website section as follows&lt;br /&gt;
&lt;br /&gt;
 mkdir -p /var/lib/lighttpd/cache&lt;br /&gt;
 chown lighttpd:lighttpd  /var/lib/lighttpd/cache&lt;br /&gt;
&lt;br /&gt;
 vi /etc/lighttpd/lighttpd.conf&lt;br /&gt;
&lt;br /&gt;
 ...&lt;br /&gt;
 &amp;quot;mod_setenv&amp;quot;,&lt;br /&gt;
 &amp;quot;mod_compress&amp;quot;,&lt;br /&gt;
 ...&lt;br /&gt;
 $HTTP[&amp;quot;host&amp;quot;] == &amp;quot;ROUNDCUBE_DOMAIN&amp;quot; {&lt;br /&gt;
  ...&lt;br /&gt;
  static-file.etags = &amp;quot;enable&amp;quot;&lt;br /&gt;
  etag.use-mtime = &amp;quot;enable&amp;quot;&lt;br /&gt;
  $HTTP[&amp;quot;url&amp;quot;] =~ &amp;quot;^/(plugins|skins|program)&amp;quot; { setenv.add-response-header  = ( &amp;quot;Cache-Control&amp;quot; =&amp;gt; &amp;quot;public, max-age=2592000&amp;quot;) }&lt;br /&gt;
  compress.cache-dir   = var.statedir + &amp;quot;/cache/compress&amp;quot;&lt;br /&gt;
  compress.filetype = (&amp;quot;text/plain&amp;quot;, &amp;quot;text/html&amp;quot;, &amp;quot;text/javascript&amp;quot;, &amp;quot;text/css&amp;quot;, &amp;quot;text/xml&amp;quot;, &amp;quot;image/gif&amp;quot;, &amp;quot;image/png&amp;quot;)&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
[[Category:Mail]]&lt;br /&gt;
[[Category:PHP]]&lt;br /&gt;
[[Category:SQL]]&lt;br /&gt;
[[Category:ACF]]&lt;/div&gt;</summary>
		<author><name>Nangel</name></author>
	</entry>
	<entry>
		<id>https://wiki.alpinelinux.org/w/index.php?title=ISP_Mail_Server_3.x_HowTo&amp;diff=13063</id>
		<title>ISP Mail Server 3.x HowTo</title>
		<link rel="alternate" type="text/html" href="https://wiki.alpinelinux.org/w/index.php?title=ISP_Mail_Server_3.x_HowTo&amp;diff=13063"/>
		<updated>2016-11-27T23:44:21Z</updated>

		<summary type="html">&lt;p&gt;Nangel: /* Install Dovecot */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Draft|This is a work in progress based on migrating alpinelinux mail servers to 3.x}}&lt;br /&gt;
&lt;br /&gt;
== A Full Service Mail Server ==&lt;br /&gt;
&lt;br /&gt;
This document describes installation process for the Alpine Linux 3.x platform. 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. This document superceeds the previous [[ISP Mail Server 2.x HowTo]] instructions for Alpine 2.x.  For this guide, we start with a server &#039;&#039;without&#039;&#039; ACF installed.&lt;br /&gt;
&lt;br /&gt;
The server provides:&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-cgi php-pgsql php-imap&lt;br /&gt;
&lt;br /&gt;
We are setting this up to be a multi-domain virtual web server (replace host.example.com with the actual domain):&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;mkdir -p /var/www/domains/host.example.com/www&lt;br /&gt;
cat &amp;lt;&amp;lt;-EOF &amp;gt;/var/www/domains/host.example.com/www/index.html&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;/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;
EOF&lt;br /&gt;
&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Get a web certificate, and install it.  There are several options:&lt;br /&gt;
# Use a self-signed certificate, such as [[Generating SSL certs with ACF]] &lt;br /&gt;
# Use the certificate created with &#039;&#039;&#039;setup-acf&#039;&#039;&#039;, if you installed ACF&lt;br /&gt;
# Get a certificate from a trusted root Certificate Authority, such as StartSSL.com, Thawte.com, Verisign.com, etc.&lt;br /&gt;
&lt;br /&gt;
These instructions will use a certificate issued from a self-signed ACF based CA&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;
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_fastcgi.conf&amp;quot;&lt;br /&gt;
&lt;br /&gt;
start lighttpd, test:&lt;br /&gt;
&lt;br /&gt;
  rc-update add lighttpd&lt;br /&gt;
  rc&lt;br /&gt;
&lt;br /&gt;
At this point you should be able to see the redirect page:  https://host.example.com/&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 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/9.0/data/pg_hba.conf. Since by default &amp;quot;trust&amp;quot; mechanism is for local connections only we assume using trust password-less access as safe.&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;
   \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.93 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.93/postfixadmin-2.93.tar.gz&lt;br /&gt;
 tar zxvf postfixadmin-2.93.tar.gz&lt;br /&gt;
 mkdir -p /var/www/domains/host.example.com/www/postfixadmin&lt;br /&gt;
 mv  postfixadmin-2.3.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;dovecot:SHA512-CRYPT&#039;;&lt;br /&gt;
 $CONF[&#039;authlib_default_flavor&#039;] = &#039;SHA&#039;;&lt;br /&gt;
 $CONF[&#039;dovecotpw&#039;] = &amp;quot;/usr/bin/doveadm pw&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;
&#039;&#039;&#039;NOTE:&#039;&#039;&#039; Check http://sourceforge.net/tracker/index.php?func=detail&amp;amp;aid=2859165&amp;amp;group_id=191583&amp;amp;atid=937964 if you have bug on listing domains page.&lt;br /&gt;
&lt;br /&gt;
== Install Postfix ==&lt;br /&gt;
&lt;br /&gt;
 &lt;br /&gt;
Install postfix&lt;br /&gt;
&lt;br /&gt;
 apk add postfix postfix-pgsql postfix-pcre&lt;br /&gt;
&lt;br /&gt;
The install should create a vmail user; you&#039;ll need the numeric uid/gid for the postfix main.cf file.&lt;br /&gt;
&lt;br /&gt;
 grep vmail /etc/passwd&lt;br /&gt;
&lt;br /&gt;
(we will use 102:105 in the examples below)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Create the mail directory, and assign vmail as the owner:&lt;br /&gt;
&lt;br /&gt;
 mkdir -p /var/mail/domains&lt;br /&gt;
 chown -R vmail:postdrop /var/mail/domains&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;
 # New install - don&#039;t need to be backward compatible &lt;br /&gt;
 compatibility_level = 2 &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:105&lt;br /&gt;
 virtual_uid_maps = static:102&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;
 &lt;br /&gt;
 # 100MB size limit&lt;br /&gt;
 message_size_limit = 104857600&lt;br /&gt;
 virtual_mailbox_limit = 104857600&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;
 # Silence the EAI warning on alpine linux&lt;br /&gt;
 smtputf8_enable = no&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;
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;
=== 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;
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;
Install dovecot: &lt;br /&gt;
&lt;br /&gt;
 apk add 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;
auth_mechanisms = plain login&lt;br /&gt;
auth_username_format = %Lu&lt;br /&gt;
#auth_verbose = yes&lt;br /&gt;
#auth_debug = yes&lt;br /&gt;
#auth_debug_passwords = no&lt;br /&gt;
&lt;br /&gt;
disable_plaintext_auth = no&lt;br /&gt;
&lt;br /&gt;
mail_location = maildir:/var/mail/domains/%d/%n&lt;br /&gt;
&lt;br /&gt;
first_valid_gid = 105&lt;br /&gt;
first_valid_uid = 102&lt;br /&gt;
last_valid_gid = 105&lt;br /&gt;
last_valid_uid = 102&lt;br /&gt;
&lt;br /&gt;
log_timestamp = &amp;quot;%Y-%m-%d %H:%M:%S &amp;quot;&lt;br /&gt;
login_greeting = IMAP server ready&lt;br /&gt;
&lt;br /&gt;
protocols = imap&lt;br /&gt;
&lt;br /&gt;
service anvil {&lt;br /&gt;
  client_limit = 2100&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
ssl_cert = /etc/lighttpd/server-bundle.pem&lt;br /&gt;
ssl_key = /etc/lighttpd/server-bundle.pem&lt;br /&gt;
&lt;br /&gt;
userdb {&lt;br /&gt;
  args = uid=102 gid=105 home=/var/mail/domains/%d/%n&lt;br /&gt;
  driver = static&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
passdb {&lt;br /&gt;
  args = /etc/dovecot/dovecot-sql.conf&lt;br /&gt;
  driver = sql&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
namespace inbox {&lt;br /&gt;
        inbox = yes&lt;br /&gt;
&lt;br /&gt;
        mailbox Trash {&lt;br /&gt;
                auto = create&lt;br /&gt;
                special_use = \Trash&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
        mailbox Spam {&lt;br /&gt;
                auto = no&lt;br /&gt;
                special_use = \Junk&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
        mailbox Ham {&lt;br /&gt;
                auto = no&lt;br /&gt;
        }&lt;br /&gt;
        mailbox Sent {&lt;br /&gt;
                auto = subscribe&lt;br /&gt;
                special_use = \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 =  SHA512-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;
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;
=== 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;
* 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;
* Edit /etc/dovecot/dovecot.conf and add the following:&lt;br /&gt;
# this is for postfix SASL (authenticated users can relay through us)&lt;br /&gt;
&lt;br /&gt;
 service auth {&lt;br /&gt;
  unix_listener /var/spool/postfix/private/auth {&lt;br /&gt;
    group = postfix&lt;br /&gt;
    mode = 0660&lt;br /&gt;
    user = postfix&lt;br /&gt;
  }&lt;br /&gt;
  unix_listener /var/spool/postfix/auth-master {&lt;br /&gt;
    group = postfix&lt;br /&gt;
    mode = 0660&lt;br /&gt;
    user = vmail&lt;br /&gt;
  }&lt;br /&gt;
  user = root&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/auth&lt;br /&gt;
 smtpd_sasl_auth_enable = yes&lt;br /&gt;
 smtpd_sasl_authenticated_header = yes&lt;br /&gt;
 broken_sasl_auth_clients = 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://wiki2.dovecot.org/LDA deliver] lda for local delivery.&lt;br /&gt;
&lt;br /&gt;
* Replace /etc/dovecot/dovecot.conf with the following:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
auth_mechanisms = plain login&lt;br /&gt;
auth_username_format = %Lu&lt;br /&gt;
#auth_verbose = yes&lt;br /&gt;
#auth_debug = yes&lt;br /&gt;
#auth_debug_passwords = no&lt;br /&gt;
&lt;br /&gt;
disable_plaintext_auth = no&lt;br /&gt;
&lt;br /&gt;
info_log_path = /var/log/dovecot-info.log&lt;br /&gt;
log_path = /var/log/dovecot.log&lt;br /&gt;
&lt;br /&gt;
mail_location = maildir:/var/mail/domains/%d/%n&lt;br /&gt;
&lt;br /&gt;
first_valid_gid = 1000&lt;br /&gt;
first_valid_uid = 1000&lt;br /&gt;
last_valid_gid = 65535&lt;br /&gt;
last_valid_uid = 65535&lt;br /&gt;
&lt;br /&gt;
log_timestamp = &amp;quot;%Y-%m-%d %H:%M:%S &amp;quot;&lt;br /&gt;
login_greeting = IMAP server ready&lt;br /&gt;
&lt;br /&gt;
protocols = imap&lt;br /&gt;
&lt;br /&gt;
service anvil {&lt;br /&gt;
  client_limit = 2100&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
service auth {&lt;br /&gt;
  unix_listener /var/spool/postfix/auth-master {&lt;br /&gt;
    group = postfix&lt;br /&gt;
    mode = 0660&lt;br /&gt;
    user = vmail&lt;br /&gt;
  }&lt;br /&gt;
  unix_listener /var/spool/postfix/private/auth {&lt;br /&gt;
    group = postfix&lt;br /&gt;
    mode = 0660&lt;br /&gt;
    user = postfix&lt;br /&gt;
  }&lt;br /&gt;
  user = root&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
service imap-login {&lt;br /&gt;
  inet_listener imap {&lt;br /&gt;
    address = 127.0.0.1&lt;br /&gt;
    port = 143&lt;br /&gt;
  }&lt;br /&gt;
  inet_listener imaps {&lt;br /&gt;
    address = *&lt;br /&gt;
    port = 993&lt;br /&gt;
  }&lt;br /&gt;
  process_limit = 1024&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
service pop3-login {&lt;br /&gt;
  process_limit = 1024&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
service dict {&lt;br /&gt;
  unix_listener dict {&lt;br /&gt;
    group =&lt;br /&gt;
    mode = 0600&lt;br /&gt;
    user = vmail&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
ssl_ca = &amp;lt;/etc/ssl/certs/&amp;lt;CA Certificate file&amp;gt;&lt;br /&gt;
ssl_cert = &amp;lt;/etc/ssl/private/&amp;lt;Public part of certificate file&amp;gt;&lt;br /&gt;
ssl_key = &amp;lt;/etc/ssl/private/&amp;lt;Private part of certificate file&amp;gt;&lt;br /&gt;
&lt;br /&gt;
passdb {&lt;br /&gt;
  args = /etc/dovecot/dovecot-pgsql.conf&lt;br /&gt;
  driver = sql&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
userdb {&lt;br /&gt;
  driver = prefetch&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
userdb {&lt;br /&gt;
  args = /etc/dovecot/dovecot-pgsql.conf&lt;br /&gt;
  driver = sql&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
plugin {&lt;br /&gt;
  quota = dict:user::proxy::quotadict&lt;br /&gt;
&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;
protocol imap {&lt;br /&gt;
  mail_plugins = autocreate 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;
protocol lda {&lt;br /&gt;
  auth_socket_path = /var/spool/postfix/auth-master&lt;br /&gt;
  mail_plugins = quota&lt;br /&gt;
  postmaster_address = postmaster@host.example.com&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;
* 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;
* 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 dovecot:root /etc/dovecot/dovecot-sql.conf&lt;br /&gt;
  chmod 600 /etc/dovecot/dovecot-sql.conf&lt;br /&gt;
  chown dovecot: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://wiki2.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 2.2 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/auth&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 followed section &#039;&#039;Relay_for_Authenticated_Users&#039;&#039;.&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;
&lt;br /&gt;
 apk add roundcubemail php-xml php-openssl php-mcrypt php-gd php-iconv php-dom php-intl php-pdo php-ldap php-pdo_pgsql php-zlib&lt;br /&gt;
&lt;br /&gt;
* Link the roundcube application back into the docroot&lt;br /&gt;
&lt;br /&gt;
 ln -s /usr/share/webapps/roundcube /var/www/domains/host.example.com/www/roundcube&lt;br /&gt;
&lt;br /&gt;
* Install &#039;&#039;roundcubemail-install&#039;&#039; package&lt;br /&gt;
&lt;br /&gt;
 apk add roundcubemail-installer&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 /var/log/roundcube&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;
&lt;br /&gt;
 /etc/init.d/lighttpd restart&lt;br /&gt;
&lt;br /&gt;
* Get the additional php modules needed:&lt;br /&gt;
 apk add curl php-phar git&lt;br /&gt;
 cd /usr/share/webapps/roundcube&lt;br /&gt;
 curl -sS https://getcomposer.org/installer | php&lt;br /&gt;
 cp composer.json-dist composer.json&lt;br /&gt;
 # Note - As of 11 Aug 2015, with Roundcube 1.1.2, there is a regression that is &lt;br /&gt;
 # fixed here: https://github.com/roundcube/roundcubemail/commit/b3e9764c311a39012de1fa8ffd0fe874fbb322ef&lt;br /&gt;
 # Update your composer.json accordingly:&lt;br /&gt;
 # -        &amp;quot;pear/mail_mime&amp;quot;: &amp;quot;&amp;gt;=1.9.0&amp;quot;,&lt;br /&gt;
 # -        &amp;quot;pear/net_smtp&amp;quot;: &amp;quot;dev-master&amp;quot;&lt;br /&gt;
 # +        &amp;quot;pear-pear.php.net/mail_mime&amp;quot;: &amp;quot;&amp;gt;=1.9.0&amp;quot;,&lt;br /&gt;
 # +        &amp;quot;pear-pear.php.net/net_smtp&amp;quot;: &amp;quot;&amp;gt;=1.6.3&amp;quot;&lt;br /&gt;
 php composer.phar install --no-dev &lt;br /&gt;
&lt;br /&gt;
* Point your browser to https://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;default port&#039;&#039; || 143&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 2 of the install to copy the files to the server&lt;br /&gt;
* You should now be able to get to roundcube at https://host.example.com/roundcube&lt;br /&gt;
&lt;br /&gt;
* After its working, the INSTALL file recommends removing the install directory.&lt;br /&gt;
&lt;br /&gt;
 apk del roundcubemail-installer&lt;br /&gt;
&lt;br /&gt;
* Disable installer mode in /etc/roundcube/main.inc.php file:&lt;br /&gt;
&lt;br /&gt;
 $rcmail_config[&#039;enable_installer&#039;] = false;&lt;br /&gt;
&lt;br /&gt;
* Change the ownership and permissions&lt;br /&gt;
&lt;br /&gt;
 cd /usr/share/webapps/roundcube&lt;br /&gt;
 chown -R root:root LICENSE UPGRADING INSTALL README CHANGELOG&lt;br /&gt;
 chmod -R 600 LICENSE UPGRADING INSTALL README CHANGELOG &lt;br /&gt;
&lt;br /&gt;
* If needed customize logos such as &#039;&#039;&#039;watermark.gif&#039;&#039;&#039;, &#039;&#039;&#039;roundcube_logo.gif&#039;&#039;&#039;, &#039;&#039;&#039;favicon.ico&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
* If you would like to disable displaying of standard logos update template files accordingly&lt;br /&gt;
&lt;br /&gt;
* Comment all entries like &#039;&#039;&#039;&amp;lt;div ... img src=&amp;quot;/images/roundcube_logo.png&amp;quot;...&#039;&#039;&#039; in files:&lt;br /&gt;
&lt;br /&gt;
 includes/header.html &lt;br /&gt;
 templates/error.html&lt;br /&gt;
 templates/messageprint.html&lt;br /&gt;
 templates/login.html&lt;br /&gt;
 templates/printmessage.html&lt;br /&gt;
&lt;br /&gt;
* Comment all entries like &#039;&#039;&#039;&amp;lt;img src=&amp;quot;/images/watermark.gif&amp;quot;...&#039;&#039;&#039; in files:&lt;br /&gt;
&lt;br /&gt;
 templates/identities.html&lt;br /&gt;
 templates/messageerror.html&lt;br /&gt;
 watermark.html&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;
* Enable &#039;&#039;create_default_folders&#039;&#039; for RoundCube&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;create_default_folders&#039;] = TRUE;&lt;br /&gt;
...&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 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 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;
* 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;
&#039;&#039;&#039;&#039;&#039;Question to experts: Is this normal to have in this script &amp;quot;WARNING:  nonstandard use of \\ in a string literal&amp;quot;?&#039;&#039;&#039;&#039;&#039;&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;
# Uncomment next five TLS... lines if you want to use LDAPs (secured). Probably you don&#039;t want it...&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. In case you uncommented TLS lines in slapd.conf use this string: OPTS=&amp;quot;-h &#039;ldaps:// ldap://&#039;&amp;quot;&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;ldap://&#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. In case you uncommented TLS lines in slapd.conf replace ldap with ldaps&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	ldap://host.example.com&lt;br /&gt;
&lt;br /&gt;
# Uncomment next three TLS... lines if you want to use LDAPs (secured). Probably you don&#039;t want it...&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 /etc/roundcube/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;br /&gt;
&lt;br /&gt;
== Optional: Enable compression in Lighttpd ==&lt;br /&gt;
&lt;br /&gt;
* Uncomment &#039;&#039;mod_compress&#039;&#039; and &#039;&#039;mod_setenv&#039;&#039; and modify website section as follows&lt;br /&gt;
&lt;br /&gt;
 mkdir -p /var/lib/lighttpd/cache&lt;br /&gt;
 chown lighttpd:lighttpd  /var/lib/lighttpd/cache&lt;br /&gt;
&lt;br /&gt;
 vi /etc/lighttpd/lighttpd.conf&lt;br /&gt;
&lt;br /&gt;
 ...&lt;br /&gt;
 &amp;quot;mod_setenv&amp;quot;,&lt;br /&gt;
 &amp;quot;mod_compress&amp;quot;,&lt;br /&gt;
 ...&lt;br /&gt;
 $HTTP[&amp;quot;host&amp;quot;] == &amp;quot;ROUNDCUBE_DOMAIN&amp;quot; {&lt;br /&gt;
  ...&lt;br /&gt;
  static-file.etags = &amp;quot;enable&amp;quot;&lt;br /&gt;
  etag.use-mtime = &amp;quot;enable&amp;quot;&lt;br /&gt;
  $HTTP[&amp;quot;url&amp;quot;] =~ &amp;quot;^/(plugins|skins|program)&amp;quot; { setenv.add-response-header  = ( &amp;quot;Cache-Control&amp;quot; =&amp;gt; &amp;quot;public, max-age=2592000&amp;quot;) }&lt;br /&gt;
  compress.cache-dir   = var.statedir + &amp;quot;/cache/compress&amp;quot;&lt;br /&gt;
  compress.filetype = (&amp;quot;text/plain&amp;quot;, &amp;quot;text/html&amp;quot;, &amp;quot;text/javascript&amp;quot;, &amp;quot;text/css&amp;quot;, &amp;quot;text/xml&amp;quot;, &amp;quot;image/gif&amp;quot;, &amp;quot;image/png&amp;quot;)&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
[[Category:Mail]]&lt;br /&gt;
[[Category:PHP]]&lt;br /&gt;
[[Category:SQL]]&lt;br /&gt;
[[Category:ACF]]&lt;/div&gt;</summary>
		<author><name>Nangel</name></author>
	</entry>
	<entry>
		<id>https://wiki.alpinelinux.org/w/index.php?title=ISP_Mail_Server_3.x_HowTo&amp;diff=13062</id>
		<title>ISP Mail Server 3.x HowTo</title>
		<link rel="alternate" type="text/html" href="https://wiki.alpinelinux.org/w/index.php?title=ISP_Mail_Server_3.x_HowTo&amp;diff=13062"/>
		<updated>2016-11-27T15:57:59Z</updated>

		<summary type="html">&lt;p&gt;Nangel: /* Install Dovecot */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Draft|This is a work in progress based on migrating alpinelinux mail servers to 3.x}}&lt;br /&gt;
&lt;br /&gt;
== A Full Service Mail Server ==&lt;br /&gt;
&lt;br /&gt;
This document describes installation process for the Alpine Linux 3.x platform. 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. This document superceeds the previous [[ISP Mail Server 2.x HowTo]] instructions for Alpine 2.x.  For this guide, we start with a server &#039;&#039;without&#039;&#039; ACF installed.&lt;br /&gt;
&lt;br /&gt;
The server provides:&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-cgi php-pgsql php-imap&lt;br /&gt;
&lt;br /&gt;
We are setting this up to be a multi-domain virtual web server (replace host.example.com with the actual domain):&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;mkdir -p /var/www/domains/host.example.com/www&lt;br /&gt;
cat &amp;lt;&amp;lt;-EOF &amp;gt;/var/www/domains/host.example.com/www/index.html&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;/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;
EOF&lt;br /&gt;
&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Get a web certificate, and install it.  There are several options:&lt;br /&gt;
# Use a self-signed certificate, such as [[Generating SSL certs with ACF]] &lt;br /&gt;
# Use the certificate created with &#039;&#039;&#039;setup-acf&#039;&#039;&#039;, if you installed ACF&lt;br /&gt;
# Get a certificate from a trusted root Certificate Authority, such as StartSSL.com, Thawte.com, Verisign.com, etc.&lt;br /&gt;
&lt;br /&gt;
These instructions will use a certificate issued from a self-signed ACF based CA&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;
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_fastcgi.conf&amp;quot;&lt;br /&gt;
&lt;br /&gt;
start lighttpd, test:&lt;br /&gt;
&lt;br /&gt;
  rc-update add lighttpd&lt;br /&gt;
  rc&lt;br /&gt;
&lt;br /&gt;
At this point you should be able to see the redirect page:  https://host.example.com/&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 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/9.0/data/pg_hba.conf. Since by default &amp;quot;trust&amp;quot; mechanism is for local connections only we assume using trust password-less access as safe.&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;
   \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.93 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.93/postfixadmin-2.93.tar.gz&lt;br /&gt;
 tar zxvf postfixadmin-2.93.tar.gz&lt;br /&gt;
 mkdir -p /var/www/domains/host.example.com/www/postfixadmin&lt;br /&gt;
 mv  postfixadmin-2.3.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;dovecot:SHA512-CRYPT&#039;;&lt;br /&gt;
 $CONF[&#039;authlib_default_flavor&#039;] = &#039;SHA&#039;;&lt;br /&gt;
 $CONF[&#039;dovecotpw&#039;] = &amp;quot;/usr/bin/doveadm pw&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;
&#039;&#039;&#039;NOTE:&#039;&#039;&#039; Check http://sourceforge.net/tracker/index.php?func=detail&amp;amp;aid=2859165&amp;amp;group_id=191583&amp;amp;atid=937964 if you have bug on listing domains page.&lt;br /&gt;
&lt;br /&gt;
== Install Postfix ==&lt;br /&gt;
&lt;br /&gt;
 &lt;br /&gt;
Install postfix&lt;br /&gt;
&lt;br /&gt;
 apk add postfix postfix-pgsql postfix-pcre&lt;br /&gt;
&lt;br /&gt;
The install should create a vmail user; you&#039;ll need the numeric uid/gid for the postfix main.cf file.&lt;br /&gt;
&lt;br /&gt;
 grep vmail /etc/passwd&lt;br /&gt;
&lt;br /&gt;
(we will use 102:105 in the examples below)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Create the mail directory, and assign vmail as the owner:&lt;br /&gt;
&lt;br /&gt;
 mkdir -p /var/mail/domains&lt;br /&gt;
 chown -R vmail:postdrop /var/mail/domains&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;
 # New install - don&#039;t need to be backward compatible &lt;br /&gt;
 compatibility_level = 2 &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:105&lt;br /&gt;
 virtual_uid_maps = static:102&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;
 &lt;br /&gt;
 # 100MB size limit&lt;br /&gt;
 message_size_limit = 104857600&lt;br /&gt;
 virtual_mailbox_limit = 104857600&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;
 # Silence the EAI warning on alpine linux&lt;br /&gt;
 smtputf8_enable = no&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;
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;
=== 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;
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;
Install dovecot: &lt;br /&gt;
&lt;br /&gt;
 apk add 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;
auth_mechanisms = plain login&lt;br /&gt;
auth_username_format = %Lu&lt;br /&gt;
#auth_verbose = yes&lt;br /&gt;
#auth_debug = yes&lt;br /&gt;
#auth_debug_passwords = no&lt;br /&gt;
&lt;br /&gt;
disable_plaintext_auth = no&lt;br /&gt;
&lt;br /&gt;
mail_location = maildir:/var/mail/domains/%d/%n&lt;br /&gt;
&lt;br /&gt;
first_valid_gid = 105&lt;br /&gt;
first_valid_uid = 102&lt;br /&gt;
last_valid_gid = 105&lt;br /&gt;
last_valid_uid = 102&lt;br /&gt;
&lt;br /&gt;
log_timestamp = &amp;quot;%Y-%m-%d %H:%M:%S &amp;quot;&lt;br /&gt;
login_greeting = IMAP server ready&lt;br /&gt;
&lt;br /&gt;
protocols = imap&lt;br /&gt;
&lt;br /&gt;
service anvil {&lt;br /&gt;
  client_limit = 2100&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
ssl_cert = /etc/lighttpd/server-bundle.pem&lt;br /&gt;
ssl_key = /etc/lighttpd/server-bundle.pem&lt;br /&gt;
&lt;br /&gt;
userdb {&lt;br /&gt;
  args = uid=102 gid=105 home=/var/mail/domains/%d/%n&lt;br /&gt;
  driver = static&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
passdb {&lt;br /&gt;
  args = /etc/dovecot/dovecot-sql.conf&lt;br /&gt;
  driver = sql&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
namespace inbox {&lt;br /&gt;
        inbox = yes&lt;br /&gt;
&lt;br /&gt;
        mailbox Trash {&lt;br /&gt;
                auto = create&lt;br /&gt;
                special_use = \Trash&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
        mailbox Spam {&lt;br /&gt;
                auto = no&lt;br /&gt;
                special_use = \Junk&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
        mailbox Ham {&lt;br /&gt;
                auto = no&lt;br /&gt;
        }&lt;br /&gt;
        mailbox Sent {&lt;br /&gt;
                auto = subscribe&lt;br /&gt;
                special_use = \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;
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;
=== 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;
* 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;
* Edit /etc/dovecot/dovecot.conf and add the following:&lt;br /&gt;
# this is for postfix SASL (authenticated users can relay through us)&lt;br /&gt;
&lt;br /&gt;
 service auth {&lt;br /&gt;
  unix_listener /var/spool/postfix/private/auth {&lt;br /&gt;
    group = postfix&lt;br /&gt;
    mode = 0660&lt;br /&gt;
    user = postfix&lt;br /&gt;
  }&lt;br /&gt;
  unix_listener /var/spool/postfix/auth-master {&lt;br /&gt;
    group = postfix&lt;br /&gt;
    mode = 0660&lt;br /&gt;
    user = vmail&lt;br /&gt;
  }&lt;br /&gt;
  user = root&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/auth&lt;br /&gt;
 smtpd_sasl_auth_enable = yes&lt;br /&gt;
 smtpd_sasl_authenticated_header = yes&lt;br /&gt;
 broken_sasl_auth_clients = 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://wiki2.dovecot.org/LDA deliver] lda for local delivery.&lt;br /&gt;
&lt;br /&gt;
* Replace /etc/dovecot/dovecot.conf with the following:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
auth_mechanisms = plain login&lt;br /&gt;
auth_username_format = %Lu&lt;br /&gt;
#auth_verbose = yes&lt;br /&gt;
#auth_debug = yes&lt;br /&gt;
#auth_debug_passwords = no&lt;br /&gt;
&lt;br /&gt;
disable_plaintext_auth = no&lt;br /&gt;
&lt;br /&gt;
info_log_path = /var/log/dovecot-info.log&lt;br /&gt;
log_path = /var/log/dovecot.log&lt;br /&gt;
&lt;br /&gt;
mail_location = maildir:/var/mail/domains/%d/%n&lt;br /&gt;
&lt;br /&gt;
first_valid_gid = 1000&lt;br /&gt;
first_valid_uid = 1000&lt;br /&gt;
last_valid_gid = 65535&lt;br /&gt;
last_valid_uid = 65535&lt;br /&gt;
&lt;br /&gt;
log_timestamp = &amp;quot;%Y-%m-%d %H:%M:%S &amp;quot;&lt;br /&gt;
login_greeting = IMAP server ready&lt;br /&gt;
&lt;br /&gt;
protocols = imap&lt;br /&gt;
&lt;br /&gt;
service anvil {&lt;br /&gt;
  client_limit = 2100&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
service auth {&lt;br /&gt;
  unix_listener /var/spool/postfix/auth-master {&lt;br /&gt;
    group = postfix&lt;br /&gt;
    mode = 0660&lt;br /&gt;
    user = vmail&lt;br /&gt;
  }&lt;br /&gt;
  unix_listener /var/spool/postfix/private/auth {&lt;br /&gt;
    group = postfix&lt;br /&gt;
    mode = 0660&lt;br /&gt;
    user = postfix&lt;br /&gt;
  }&lt;br /&gt;
  user = root&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
service imap-login {&lt;br /&gt;
  inet_listener imap {&lt;br /&gt;
    address = 127.0.0.1&lt;br /&gt;
    port = 143&lt;br /&gt;
  }&lt;br /&gt;
  inet_listener imaps {&lt;br /&gt;
    address = *&lt;br /&gt;
    port = 993&lt;br /&gt;
  }&lt;br /&gt;
  process_limit = 1024&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
service pop3-login {&lt;br /&gt;
  process_limit = 1024&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
service dict {&lt;br /&gt;
  unix_listener dict {&lt;br /&gt;
    group =&lt;br /&gt;
    mode = 0600&lt;br /&gt;
    user = vmail&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
ssl_ca = &amp;lt;/etc/ssl/certs/&amp;lt;CA Certificate file&amp;gt;&lt;br /&gt;
ssl_cert = &amp;lt;/etc/ssl/private/&amp;lt;Public part of certificate file&amp;gt;&lt;br /&gt;
ssl_key = &amp;lt;/etc/ssl/private/&amp;lt;Private part of certificate file&amp;gt;&lt;br /&gt;
&lt;br /&gt;
passdb {&lt;br /&gt;
  args = /etc/dovecot/dovecot-pgsql.conf&lt;br /&gt;
  driver = sql&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
userdb {&lt;br /&gt;
  driver = prefetch&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
userdb {&lt;br /&gt;
  args = /etc/dovecot/dovecot-pgsql.conf&lt;br /&gt;
  driver = sql&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
plugin {&lt;br /&gt;
  quota = dict:user::proxy::quotadict&lt;br /&gt;
&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;
protocol imap {&lt;br /&gt;
  mail_plugins = autocreate 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;
protocol lda {&lt;br /&gt;
  auth_socket_path = /var/spool/postfix/auth-master&lt;br /&gt;
  mail_plugins = quota&lt;br /&gt;
  postmaster_address = postmaster@host.example.com&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;
* 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;
* 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 dovecot:root /etc/dovecot/dovecot-sql.conf&lt;br /&gt;
  chmod 600 /etc/dovecot/dovecot-sql.conf&lt;br /&gt;
  chown dovecot: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://wiki2.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 2.2 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/auth&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 followed section &#039;&#039;Relay_for_Authenticated_Users&#039;&#039;.&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;
&lt;br /&gt;
 apk add roundcubemail php-xml php-openssl php-mcrypt php-gd php-iconv php-dom php-intl php-pdo php-ldap php-pdo_pgsql php-zlib&lt;br /&gt;
&lt;br /&gt;
* Link the roundcube application back into the docroot&lt;br /&gt;
&lt;br /&gt;
 ln -s /usr/share/webapps/roundcube /var/www/domains/host.example.com/www/roundcube&lt;br /&gt;
&lt;br /&gt;
* Install &#039;&#039;roundcubemail-install&#039;&#039; package&lt;br /&gt;
&lt;br /&gt;
 apk add roundcubemail-installer&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 /var/log/roundcube&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;
&lt;br /&gt;
 /etc/init.d/lighttpd restart&lt;br /&gt;
&lt;br /&gt;
* Get the additional php modules needed:&lt;br /&gt;
 apk add curl php-phar git&lt;br /&gt;
 cd /usr/share/webapps/roundcube&lt;br /&gt;
 curl -sS https://getcomposer.org/installer | php&lt;br /&gt;
 cp composer.json-dist composer.json&lt;br /&gt;
 # Note - As of 11 Aug 2015, with Roundcube 1.1.2, there is a regression that is &lt;br /&gt;
 # fixed here: https://github.com/roundcube/roundcubemail/commit/b3e9764c311a39012de1fa8ffd0fe874fbb322ef&lt;br /&gt;
 # Update your composer.json accordingly:&lt;br /&gt;
 # -        &amp;quot;pear/mail_mime&amp;quot;: &amp;quot;&amp;gt;=1.9.0&amp;quot;,&lt;br /&gt;
 # -        &amp;quot;pear/net_smtp&amp;quot;: &amp;quot;dev-master&amp;quot;&lt;br /&gt;
 # +        &amp;quot;pear-pear.php.net/mail_mime&amp;quot;: &amp;quot;&amp;gt;=1.9.0&amp;quot;,&lt;br /&gt;
 # +        &amp;quot;pear-pear.php.net/net_smtp&amp;quot;: &amp;quot;&amp;gt;=1.6.3&amp;quot;&lt;br /&gt;
 php composer.phar install --no-dev &lt;br /&gt;
&lt;br /&gt;
* Point your browser to https://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;default port&#039;&#039; || 143&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 2 of the install to copy the files to the server&lt;br /&gt;
* You should now be able to get to roundcube at https://host.example.com/roundcube&lt;br /&gt;
&lt;br /&gt;
* After its working, the INSTALL file recommends removing the install directory.&lt;br /&gt;
&lt;br /&gt;
 apk del roundcubemail-installer&lt;br /&gt;
&lt;br /&gt;
* Disable installer mode in /etc/roundcube/main.inc.php file:&lt;br /&gt;
&lt;br /&gt;
 $rcmail_config[&#039;enable_installer&#039;] = false;&lt;br /&gt;
&lt;br /&gt;
* Change the ownership and permissions&lt;br /&gt;
&lt;br /&gt;
 cd /usr/share/webapps/roundcube&lt;br /&gt;
 chown -R root:root LICENSE UPGRADING INSTALL README CHANGELOG&lt;br /&gt;
 chmod -R 600 LICENSE UPGRADING INSTALL README CHANGELOG &lt;br /&gt;
&lt;br /&gt;
* If needed customize logos such as &#039;&#039;&#039;watermark.gif&#039;&#039;&#039;, &#039;&#039;&#039;roundcube_logo.gif&#039;&#039;&#039;, &#039;&#039;&#039;favicon.ico&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
* If you would like to disable displaying of standard logos update template files accordingly&lt;br /&gt;
&lt;br /&gt;
* Comment all entries like &#039;&#039;&#039;&amp;lt;div ... img src=&amp;quot;/images/roundcube_logo.png&amp;quot;...&#039;&#039;&#039; in files:&lt;br /&gt;
&lt;br /&gt;
 includes/header.html &lt;br /&gt;
 templates/error.html&lt;br /&gt;
 templates/messageprint.html&lt;br /&gt;
 templates/login.html&lt;br /&gt;
 templates/printmessage.html&lt;br /&gt;
&lt;br /&gt;
* Comment all entries like &#039;&#039;&#039;&amp;lt;img src=&amp;quot;/images/watermark.gif&amp;quot;...&#039;&#039;&#039; in files:&lt;br /&gt;
&lt;br /&gt;
 templates/identities.html&lt;br /&gt;
 templates/messageerror.html&lt;br /&gt;
 watermark.html&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;
* Enable &#039;&#039;create_default_folders&#039;&#039; for RoundCube&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;create_default_folders&#039;] = TRUE;&lt;br /&gt;
...&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 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 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;
* 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;
&#039;&#039;&#039;&#039;&#039;Question to experts: Is this normal to have in this script &amp;quot;WARNING:  nonstandard use of \\ in a string literal&amp;quot;?&#039;&#039;&#039;&#039;&#039;&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;
# Uncomment next five TLS... lines if you want to use LDAPs (secured). Probably you don&#039;t want it...&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. In case you uncommented TLS lines in slapd.conf use this string: OPTS=&amp;quot;-h &#039;ldaps:// ldap://&#039;&amp;quot;&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;ldap://&#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. In case you uncommented TLS lines in slapd.conf replace ldap with ldaps&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	ldap://host.example.com&lt;br /&gt;
&lt;br /&gt;
# Uncomment next three TLS... lines if you want to use LDAPs (secured). Probably you don&#039;t want it...&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 /etc/roundcube/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;br /&gt;
&lt;br /&gt;
== Optional: Enable compression in Lighttpd ==&lt;br /&gt;
&lt;br /&gt;
* Uncomment &#039;&#039;mod_compress&#039;&#039; and &#039;&#039;mod_setenv&#039;&#039; and modify website section as follows&lt;br /&gt;
&lt;br /&gt;
 mkdir -p /var/lib/lighttpd/cache&lt;br /&gt;
 chown lighttpd:lighttpd  /var/lib/lighttpd/cache&lt;br /&gt;
&lt;br /&gt;
 vi /etc/lighttpd/lighttpd.conf&lt;br /&gt;
&lt;br /&gt;
 ...&lt;br /&gt;
 &amp;quot;mod_setenv&amp;quot;,&lt;br /&gt;
 &amp;quot;mod_compress&amp;quot;,&lt;br /&gt;
 ...&lt;br /&gt;
 $HTTP[&amp;quot;host&amp;quot;] == &amp;quot;ROUNDCUBE_DOMAIN&amp;quot; {&lt;br /&gt;
  ...&lt;br /&gt;
  static-file.etags = &amp;quot;enable&amp;quot;&lt;br /&gt;
  etag.use-mtime = &amp;quot;enable&amp;quot;&lt;br /&gt;
  $HTTP[&amp;quot;url&amp;quot;] =~ &amp;quot;^/(plugins|skins|program)&amp;quot; { setenv.add-response-header  = ( &amp;quot;Cache-Control&amp;quot; =&amp;gt; &amp;quot;public, max-age=2592000&amp;quot;) }&lt;br /&gt;
  compress.cache-dir   = var.statedir + &amp;quot;/cache/compress&amp;quot;&lt;br /&gt;
  compress.filetype = (&amp;quot;text/plain&amp;quot;, &amp;quot;text/html&amp;quot;, &amp;quot;text/javascript&amp;quot;, &amp;quot;text/css&amp;quot;, &amp;quot;text/xml&amp;quot;, &amp;quot;image/gif&amp;quot;, &amp;quot;image/png&amp;quot;)&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
[[Category:Mail]]&lt;br /&gt;
[[Category:PHP]]&lt;br /&gt;
[[Category:SQL]]&lt;br /&gt;
[[Category:ACF]]&lt;/div&gt;</summary>
		<author><name>Nangel</name></author>
	</entry>
</feed>