<?xml version="1.0"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="de">
	<id>https://wiki.my-network.at/api.php?action=feedcontributions&amp;feedformat=atom&amp;user=Admin</id>
	<title>TurnKey+MediaWiki - Benutzerbeiträge [de]</title>
	<link rel="self" type="application/atom+xml" href="https://wiki.my-network.at/api.php?action=feedcontributions&amp;feedformat=atom&amp;user=Admin"/>
	<link rel="alternate" type="text/html" href="https://wiki.my-network.at/index.php/Spezial:Beitr%C3%A4ge/Admin"/>
	<updated>2026-07-22T22:01:04Z</updated>
	<subtitle>Benutzerbeiträge</subtitle>
	<generator>MediaWiki 1.35.1</generator>
	<entry>
		<id>https://wiki.my-network.at/index.php?title=Sonoff/Tasmota_Verbrauchs-Historie_f%C3%BCr_Tag,_Woche,_Monat,_Jahr&amp;diff=39</id>
		<title>Sonoff/Tasmota Verbrauchs-Historie für Tag, Woche, Monat, Jahr</title>
		<link rel="alternate" type="text/html" href="https://wiki.my-network.at/index.php?title=Sonoff/Tasmota_Verbrauchs-Historie_f%C3%BCr_Tag,_Woche,_Monat,_Jahr&amp;diff=39"/>
		<updated>2022-08-24T15:24:24Z</updated>

		<summary type="html">&lt;p&gt;Admin: Die Seite wurde neu angelegt: „Dieses Skript ist eine Abwandlung des Skriptes, welches bereits für die[https://www.kreyenborg.koeln/shelly-verbrauchs-historie-fuer-tag-woche-monat-jahr/ She…“&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Dieses Skript ist eine Abwandlung des Skriptes, welches bereits für die[https://www.kreyenborg.koeln/shelly-verbrauchs-historie-fuer-tag-woche-monat-jahr/ Shelly Adapter]&lt;br /&gt;
&lt;br /&gt;
zur Verfügung steht. Hier werden die Tasmota und Sonoff Geräte unterstützt.&amp;lt;p&amp;gt;Folgende Verbrauchswerte stehen in der Historie für jeden der Sonoff Geräte zur Verfügung:&amp;lt;/p&amp;gt;&amp;lt;figure class=&amp;quot;wp-block-table is-style-stripes&amp;quot;&amp;gt;&lt;br /&gt;
{|&amp;lt;thead&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
! Funktion&lt;br /&gt;
! Beschreibung&amp;lt;/thead&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| Verbrauch heute&lt;br /&gt;
| abgefragter Verbrauch heute&lt;br /&gt;
|-&lt;br /&gt;
| Verbrauch gestern&lt;br /&gt;
| abgefragter Verbrauch gestern&lt;br /&gt;
|-&lt;br /&gt;
| Verbrauch diese Woche&lt;br /&gt;
| abgefragter Verbrauch für die gesamte Woche&lt;br /&gt;
|-&lt;br /&gt;
| Verbrauch letzte Woche&lt;br /&gt;
| abgefragter Verbrauch für die gesamte letzte Woche&lt;br /&gt;
|-&lt;br /&gt;
| Verbrauch dieser Monat&lt;br /&gt;
| abgefragter Verbrauch für den gesamten Monat&lt;br /&gt;
|-&lt;br /&gt;
| Verbrauch letzter Monat&lt;br /&gt;
| abgefragter Verbrauch für den gesamten letzten Monat&lt;br /&gt;
|-&lt;br /&gt;
| Verbrauch dieses Jahr&lt;br /&gt;
| abgefragter Verbrauch für das gesamte Jahr&lt;br /&gt;
|-&lt;br /&gt;
| Verbrauch letztes Jahr&lt;br /&gt;
| abgefragter Verbrauch für das gesamte letzte Jahr&lt;br /&gt;
|-&lt;br /&gt;
| Verbrauch Gesamt&lt;br /&gt;
| abgefragter Verbrauch gesamt&lt;br /&gt;
|-&lt;br /&gt;
| Name&lt;br /&gt;
| Zugewiesener Name des Sonoff zum einfachen Wiederfinden&lt;br /&gt;
|}&lt;br /&gt;
&amp;lt;/figure&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Sonoff Adapter im IO Broker installieren.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;p&amp;gt;Nach kurzer Zeit stehen die Datenpunkte aller gefundenen Sonoff Geräte unter&amp;amp;nbsp;&amp;lt;code&amp;gt;sonoff.0&amp;lt;/code&amp;gt;&amp;amp;nbsp;zur Verfügung.&amp;lt;/p&amp;gt;&lt;br /&gt;
=== &amp;lt;span id=&amp;quot;Skript&amp;quot; class=&amp;quot;ez-toc-section&amp;quot;&amp;gt;&amp;lt;/span&amp;gt;Skript&amp;lt;span class=&amp;quot;ez-toc-section-end&amp;quot;&amp;gt;&amp;lt;/span&amp;gt; ===&lt;br /&gt;
&amp;lt;div class=&amp;quot;enlighter-default enlighter-v-standard enlighter-t-classic enlighter-hover enlighter-linenumbers&amp;quot;&amp;gt;&amp;lt;div class=&amp;quot;enlighter-toolbar-top enlighter-toolbar&amp;quot;&amp;gt;&amp;lt;div class=&amp;quot;enlighter-btn enlighter-btn-raw&amp;quot; title=&amp;quot;Plain text&amp;quot;&amp;gt;&amp;lt;br&amp;gt;&amp;lt;/div&amp;gt;&amp;lt;div class=&amp;quot;enlighter-btn enlighter-btn-copy&amp;quot; title=&amp;quot;Copy to clipboard&amp;quot;&amp;gt;&amp;lt;br&amp;gt;&amp;lt;/div&amp;gt;&amp;lt;div class=&amp;quot;enlighter-btn enlighter-btn-window&amp;quot; title=&amp;quot;Open code in new window&amp;quot;&amp;gt;&amp;lt;br&amp;gt;&amp;lt;/div&amp;gt;&amp;lt;/div&amp;gt;&amp;lt;div class=&amp;quot;enlighter&amp;quot;&amp;gt;&amp;lt;div&amp;gt;&amp;lt;div&amp;gt;&amp;lt;span class=&amp;quot;enlighter-c1&amp;quot;&amp;gt;/*&amp;lt;/span&amp;gt;&amp;lt;/div&amp;gt;&amp;lt;/div&amp;gt;&amp;lt;div&amp;gt;&amp;lt;div&amp;gt;&amp;lt;span class=&amp;quot;enlighter-c1&amp;quot;&amp;gt; * @copyright 2020 Stephan Kreyenborg &amp;amp;lt;stephan@kreyenborg.koeln&amp;amp;gt;&amp;lt;/span&amp;gt;&amp;lt;/div&amp;gt;&amp;lt;/div&amp;gt;&amp;lt;div&amp;gt;&amp;lt;div&amp;gt;&amp;lt;span class=&amp;quot;enlighter-c1&amp;quot;&amp;gt; *&amp;lt;/span&amp;gt;&amp;lt;/div&amp;gt;&amp;lt;/div&amp;gt;&amp;lt;div&amp;gt;&amp;lt;div&amp;gt;&amp;lt;span class=&amp;quot;enlighter-c1&amp;quot;&amp;gt; * @author 2020 Stephan Kreyenborg &amp;amp;lt;stephan@kreyenborg.koeln&amp;amp;gt;&amp;lt;/span&amp;gt;&amp;lt;/div&amp;gt;&amp;lt;/div&amp;gt;&amp;lt;div&amp;gt;&amp;lt;div&amp;gt;&amp;lt;span class=&amp;quot;enlighter-c1&amp;quot;&amp;gt; *&amp;lt;/span&amp;gt;&amp;lt;/div&amp;gt;&amp;lt;/div&amp;gt;&amp;lt;div&amp;gt;&amp;lt;div&amp;gt;&amp;lt;span class=&amp;quot;enlighter-c1&amp;quot;&amp;gt; * Dieses Skript dient zur freien Verwendung in ioBroker zur Verbrauchserfassung der Tasmota Geräte.&amp;lt;/span&amp;gt;&amp;lt;/div&amp;gt;&amp;lt;/div&amp;gt;&amp;lt;div&amp;gt;&amp;lt;div&amp;gt;&amp;lt;span class=&amp;quot;enlighter-c1&amp;quot;&amp;gt; * Jegliche Verantwortung liegt beim Benutzer. Das Skript wurde unter Berücksichtigung der bestmöglichen Nutzung&amp;lt;/span&amp;gt;&amp;lt;/div&amp;gt;&amp;lt;/div&amp;gt;&amp;lt;div&amp;gt;&amp;lt;div&amp;gt;&amp;lt;span class=&amp;quot;enlighter-c1&amp;quot;&amp;gt; * und Performance entwickelt.&amp;lt;/span&amp;gt;&amp;lt;/div&amp;gt;&amp;lt;/div&amp;gt;&amp;lt;div&amp;gt;&amp;lt;div&amp;gt;&amp;lt;span class=&amp;quot;enlighter-c1&amp;quot;&amp;gt; * Der Entwickler versichert, das keine böswilligen Systemeingriffe im originalen Skript vorhanden sind.&amp;lt;/span&amp;gt;&amp;lt;/div&amp;gt;&amp;lt;/div&amp;gt;&amp;lt;div&amp;gt;&amp;lt;div&amp;gt;&amp;lt;span class=&amp;quot;enlighter-c1&amp;quot;&amp;gt; *&amp;lt;/span&amp;gt;&amp;lt;/div&amp;gt;&amp;lt;/div&amp;gt;&amp;lt;div&amp;gt;&amp;lt;div&amp;gt;&amp;lt;span class=&amp;quot;enlighter-c1&amp;quot;&amp;gt; * Sollte das Skript wider Erwarten nicht korrekt funktionieren, so hast Du jederzeit die Möglichkeit, Dich auf&amp;lt;/span&amp;gt;&amp;lt;/div&amp;gt;&amp;lt;/div&amp;gt;&amp;lt;div&amp;gt;&amp;lt;div&amp;gt;&amp;lt;span class=&amp;quot;enlighter-c1&amp;quot;&amp;gt; * https://www.kreyenborg.koeln&amp;lt;/span&amp;gt;&amp;lt;/div&amp;gt;&amp;lt;/div&amp;gt;&amp;lt;div&amp;gt;&amp;lt;div&amp;gt;&amp;lt;span class=&amp;quot;enlighter-c1&amp;quot;&amp;gt; * für Unterstützung zu melden. Jedes Skript besitzt seine eigene Kommentarseite, auf der,&amp;lt;/span&amp;gt;&amp;lt;/div&amp;gt;&amp;lt;/div&amp;gt;&amp;lt;div&amp;gt;&amp;lt;div&amp;gt;&amp;lt;span class=&amp;quot;enlighter-c1&amp;quot;&amp;gt; * nach zeitlicher Möglichkeit des Autors, Hilfe angeboten wird. Ein Anrecht hierauf besteht nicht!&amp;lt;/span&amp;gt;&amp;lt;/div&amp;gt;&amp;lt;/div&amp;gt;&amp;lt;div&amp;gt;&amp;lt;div&amp;gt;&amp;lt;span class=&amp;quot;enlighter-c1&amp;quot;&amp;gt; *&amp;lt;/span&amp;gt;&amp;lt;/div&amp;gt;&amp;lt;/div&amp;gt;&amp;lt;div&amp;gt;&amp;lt;div&amp;gt;&amp;lt;span class=&amp;quot;enlighter-c1&amp;quot;&amp;gt; * Ansprüche gegenüber Dritten bestehen nicht.&amp;lt;/span&amp;gt;&amp;lt;/div&amp;gt;&amp;lt;/div&amp;gt;&amp;lt;div&amp;gt;&amp;lt;div&amp;gt;&amp;lt;span class=&amp;quot;enlighter-c1&amp;quot;&amp;gt; *&amp;lt;/span&amp;gt;&amp;lt;/div&amp;gt;&amp;lt;/div&amp;gt;&amp;lt;div&amp;gt;&amp;lt;div&amp;gt;&amp;lt;span class=&amp;quot;enlighter-c1&amp;quot;&amp;gt; * Skript Name: Tasmota-Verbrauch&amp;lt;/span&amp;gt;&amp;lt;/div&amp;gt;&amp;lt;/div&amp;gt;&amp;lt;div&amp;gt;&amp;lt;div&amp;gt;&amp;lt;span class=&amp;quot;enlighter-c1&amp;quot;&amp;gt; * Skript Version: 1.1&amp;lt;/span&amp;gt;&amp;lt;/div&amp;gt;&amp;lt;/div&amp;gt;&amp;lt;div&amp;gt;&amp;lt;div&amp;gt;&amp;lt;span class=&amp;quot;enlighter-c1&amp;quot;&amp;gt; * Erstell-Datum: 19. März 2021&amp;lt;/span&amp;gt;&amp;lt;/div&amp;gt;&amp;lt;/div&amp;gt;&amp;lt;div&amp;gt;&amp;lt;div&amp;gt;&amp;lt;span class=&amp;quot;enlighter-c1&amp;quot;&amp;gt; *&amp;lt;/span&amp;gt;&amp;lt;/div&amp;gt;&amp;lt;/div&amp;gt;&amp;lt;div&amp;gt;&amp;lt;div&amp;gt;&amp;lt;span class=&amp;quot;enlighter-c1&amp;quot;&amp;gt; */&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;enlighter-text&amp;quot;&amp;gt;&amp;lt;/span&amp;gt;&amp;lt;/div&amp;gt;&amp;lt;/div&amp;gt;&amp;lt;div&amp;gt;&amp;lt;div&amp;gt;&amp;lt;br&amp;gt;&amp;lt;/div&amp;gt;&amp;lt;/div&amp;gt;&amp;lt;div&amp;gt;&amp;lt;div&amp;gt;&amp;lt;span class=&amp;quot;enlighter-text&amp;quot;&amp;gt;&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;enlighter-c0&amp;quot;&amp;gt;// Datenpunkte neu erstellen&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;enlighter-text&amp;quot;&amp;gt;&amp;lt;/span&amp;gt;&amp;lt;/div&amp;gt;&amp;lt;/div&amp;gt;&amp;lt;div&amp;gt;&amp;lt;div&amp;gt;&amp;lt;span class=&amp;quot;enlighter-text&amp;quot;&amp;gt;&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;enlighter-k2&amp;quot;&amp;gt;var&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;enlighter-text&amp;quot;&amp;gt; ueberschreiben = &amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;enlighter-e0&amp;quot;&amp;gt;false&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;enlighter-text&amp;quot;&amp;gt;;&amp;lt;/span&amp;gt;&amp;lt;/div&amp;gt;&amp;lt;/div&amp;gt;&amp;lt;div&amp;gt;&amp;lt;div&amp;gt;&amp;lt;br&amp;gt;&amp;lt;/div&amp;gt;&amp;lt;/div&amp;gt;&amp;lt;div&amp;gt;&amp;lt;div&amp;gt;&amp;lt;span class=&amp;quot;enlighter-text&amp;quot;&amp;gt;&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;enlighter-c0&amp;quot;&amp;gt;// Hauptdatenpunkt unterhalb javascript&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;enlighter-text&amp;quot;&amp;gt;&amp;lt;/span&amp;gt;&amp;lt;/div&amp;gt;&amp;lt;/div&amp;gt;&amp;lt;div&amp;gt;&amp;lt;div&amp;gt;&amp;lt;span class=&amp;quot;enlighter-text&amp;quot;&amp;gt;&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;enlighter-k2&amp;quot;&amp;gt;var&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;enlighter-text&amp;quot;&amp;gt; datenpunkt = &amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;enlighter-s0&amp;quot;&amp;gt;&amp;quot;TasmotaVerbrauch.&amp;quot;&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;enlighter-text&amp;quot;&amp;gt;;&amp;lt;/span&amp;gt;&amp;lt;/div&amp;gt;&amp;lt;/div&amp;gt;&amp;lt;div&amp;gt;&amp;lt;div&amp;gt;&amp;lt;br&amp;gt;&amp;lt;/div&amp;gt;&amp;lt;/div&amp;gt;&amp;lt;div&amp;gt;&amp;lt;div&amp;gt;&amp;lt;span class=&amp;quot;enlighter-text&amp;quot;&amp;gt;&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;enlighter-c0&amp;quot;&amp;gt;// Verbrauchs Objekte der einzelnen Tasmota&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;enlighter-text&amp;quot;&amp;gt;&amp;lt;/span&amp;gt;&amp;lt;/div&amp;gt;&amp;lt;/div&amp;gt;&amp;lt;div&amp;gt;&amp;lt;div&amp;gt;&amp;lt;span class=&amp;quot;enlighter-text&amp;quot;&amp;gt;&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;enlighter-k2&amp;quot;&amp;gt;const&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;enlighter-text&amp;quot;&amp;gt; objekt = &amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;enlighter-g1&amp;quot;&amp;gt;[&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;enlighter-s0&amp;quot;&amp;gt;&amp;quot;gesamt&amp;quot;&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;enlighter-text&amp;quot;&amp;gt;, &amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;enlighter-s0&amp;quot;&amp;gt;&amp;quot;dieses_jahr&amp;quot;&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;enlighter-text&amp;quot;&amp;gt;, &amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;enlighter-s0&amp;quot;&amp;gt;&amp;quot;letztes_jahr&amp;quot;&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;enlighter-text&amp;quot;&amp;gt;, &amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;enlighter-s0&amp;quot;&amp;gt;&amp;quot;letzter_monat&amp;quot;&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;enlighter-text&amp;quot;&amp;gt;, &amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;enlighter-s0&amp;quot;&amp;gt;&amp;quot;dieser_monat&amp;quot;&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;enlighter-text&amp;quot;&amp;gt;, &amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;enlighter-s0&amp;quot;&amp;gt;&amp;quot;letzte_woche&amp;quot;&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;enlighter-text&amp;quot;&amp;gt;,&amp;lt;/span&amp;gt;&amp;lt;/div&amp;gt;&amp;lt;/div&amp;gt;&amp;lt;div&amp;gt;&amp;lt;div&amp;gt;&amp;lt;span class=&amp;quot;enlighter-text&amp;quot;&amp;gt; &amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;enlighter-s0&amp;quot;&amp;gt;&amp;quot;diese_woche&amp;quot;&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;enlighter-text&amp;quot;&amp;gt;, &amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;enlighter-s0&amp;quot;&amp;gt;&amp;quot;gestern&amp;quot;&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;enlighter-text&amp;quot;&amp;gt;, &amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;enlighter-s0&amp;quot;&amp;gt;&amp;quot;heute&amp;quot;&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;enlighter-text&amp;quot;&amp;gt;, &amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;enlighter-s0&amp;quot;&amp;gt;&amp;quot;alter_wert&amp;quot;&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;enlighter-text&amp;quot;&amp;gt;, &amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;enlighter-s0&amp;quot;&amp;gt;&amp;quot;aktueller_wert&amp;quot;&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;enlighter-g1&amp;quot;&amp;gt;]&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;enlighter-text&amp;quot;&amp;gt;;&amp;lt;/span&amp;gt;&amp;lt;/div&amp;gt;&amp;lt;/div&amp;gt;&amp;lt;div&amp;gt;&amp;lt;div&amp;gt;&amp;lt;br&amp;gt;&amp;lt;/div&amp;gt;&amp;lt;/div&amp;gt;&amp;lt;div&amp;gt;&amp;lt;div&amp;gt;&amp;lt;span class=&amp;quot;enlighter-text&amp;quot;&amp;gt;&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;enlighter-c0&amp;quot;&amp;gt;// Beschreibung der Objekte&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;enlighter-text&amp;quot;&amp;gt;&amp;lt;/span&amp;gt;&amp;lt;/div&amp;gt;&amp;lt;/div&amp;gt;&amp;lt;div&amp;gt;&amp;lt;div&amp;gt;&amp;lt;span class=&amp;quot;enlighter-text&amp;quot;&amp;gt;&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;enlighter-k2&amp;quot;&amp;gt;const&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;enlighter-text&amp;quot;&amp;gt; beschreibung = &amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;enlighter-g1&amp;quot;&amp;gt;[&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;enlighter-s0&amp;quot;&amp;gt;&amp;quot;Gesamter Vebrauch des Tasmota&amp;quot;&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;enlighter-text&amp;quot;&amp;gt;, &amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;enlighter-s0&amp;quot;&amp;gt;&amp;quot;Verbrauch aktuelles Jahr&amp;quot;&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;enlighter-text&amp;quot;&amp;gt;, &amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;enlighter-s0&amp;quot;&amp;gt;&amp;quot;Verbrauch letztes Jahr&amp;quot;&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;enlighter-text&amp;quot;&amp;gt;,&amp;lt;/span&amp;gt;&amp;lt;/div&amp;gt;&amp;lt;/div&amp;gt;&amp;lt;div&amp;gt;&amp;lt;div&amp;gt;&amp;lt;span class=&amp;quot;enlighter-text&amp;quot;&amp;gt; &amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;enlighter-s0&amp;quot;&amp;gt;&amp;quot;Verbrauch letzten Monat&amp;quot;&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;enlighter-text&amp;quot;&amp;gt;, &amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;enlighter-s0&amp;quot;&amp;gt;&amp;quot;Verbrauch aktueller Monat&amp;quot;&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;enlighter-text&amp;quot;&amp;gt;, &amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;enlighter-s0&amp;quot;&amp;gt;&amp;quot;Verbrauch letzte Woche&amp;quot;&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;enlighter-text&amp;quot;&amp;gt;, &amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;enlighter-s0&amp;quot;&amp;gt;&amp;quot;Verbrauch diese Woche&amp;quot;&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;enlighter-text&amp;quot;&amp;gt;,&amp;lt;/span&amp;gt;&amp;lt;/div&amp;gt;&amp;lt;/div&amp;gt;&amp;lt;div&amp;gt;&amp;lt;div&amp;gt;&amp;lt;span class=&amp;quot;enlighter-text&amp;quot;&amp;gt; &amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;enlighter-s0&amp;quot;&amp;gt;&amp;quot;Verbrauch gestern&amp;quot;&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;enlighter-text&amp;quot;&amp;gt;, &amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;enlighter-s0&amp;quot;&amp;gt;&amp;quot;Verbrauch heute&amp;quot;&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;enlighter-text&amp;quot;&amp;gt;, &amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;enlighter-s0&amp;quot;&amp;gt;&amp;quot;Messwert alt&amp;quot;&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;enlighter-text&amp;quot;&amp;gt;, &amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;enlighter-s0&amp;quot;&amp;gt;&amp;quot;Messwert neu&amp;quot;&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;enlighter-g1&amp;quot;&amp;gt;]&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;enlighter-text&amp;quot;&amp;gt;;&amp;lt;/span&amp;gt;&amp;lt;/div&amp;gt;&amp;lt;/div&amp;gt;&amp;lt;div&amp;gt;&amp;lt;div&amp;gt;&amp;lt;br&amp;gt;&amp;lt;/div&amp;gt;&amp;lt;/div&amp;gt;&amp;lt;div&amp;gt;&amp;lt;div&amp;gt;&amp;lt;span class=&amp;quot;enlighter-text&amp;quot;&amp;gt;&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;enlighter-c0&amp;quot;&amp;gt;// Datenpunkt der Tasmota Geräte (Standard: sonoff.0)&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;enlighter-text&amp;quot;&amp;gt;&amp;lt;/span&amp;gt;&amp;lt;/div&amp;gt;&amp;lt;/div&amp;gt;&amp;lt;div&amp;gt;&amp;lt;div&amp;gt;&amp;lt;span class=&amp;quot;enlighter-text&amp;quot;&amp;gt;&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;enlighter-k2&amp;quot;&amp;gt;var&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;enlighter-text&amp;quot;&amp;gt; tasmota_dp = &amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;enlighter-s0&amp;quot;&amp;gt;&amp;quot;sonoff.0&amp;quot;&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;enlighter-text&amp;quot;&amp;gt;;&amp;lt;/span&amp;gt;&amp;lt;/div&amp;gt;&amp;lt;/div&amp;gt;&amp;lt;div&amp;gt;&amp;lt;div&amp;gt;&amp;lt;br&amp;gt;&amp;lt;/div&amp;gt;&amp;lt;/div&amp;gt;&amp;lt;div&amp;gt;&amp;lt;div&amp;gt;&amp;lt;span class=&amp;quot;enlighter-text&amp;quot;&amp;gt;&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;enlighter-c0&amp;quot;&amp;gt;// Datenpunkte der Tasmota (!!! Bitte nicht ändern !!!)&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;enlighter-text&amp;quot;&amp;gt;&amp;lt;/span&amp;gt;&amp;lt;/div&amp;gt;&amp;lt;/div&amp;gt;&amp;lt;div&amp;gt;&amp;lt;div&amp;gt;&amp;lt;span class=&amp;quot;enlighter-text&amp;quot;&amp;gt;&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;enlighter-k2&amp;quot;&amp;gt;const&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;enlighter-text&amp;quot;&amp;gt; tasmotaDps = $&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;enlighter-g1&amp;quot;&amp;gt;(&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;enlighter-s0&amp;quot;&amp;gt;'state[id='&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;enlighter-text&amp;quot;&amp;gt; + tasmota_dp + &amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;enlighter-s0&amp;quot;&amp;gt;'.*.ENERGY_Total]'&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;enlighter-g1&amp;quot;&amp;gt;)&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;enlighter-text&amp;quot;&amp;gt;;&amp;lt;/span&amp;gt;&amp;lt;/div&amp;gt;&amp;lt;/div&amp;gt;&amp;lt;div&amp;gt;&amp;lt;div&amp;gt;&amp;lt;br&amp;gt;&amp;lt;/div&amp;gt;&amp;lt;/div&amp;gt;&amp;lt;div&amp;gt;&amp;lt;div&amp;gt;&amp;lt;span class=&amp;quot;enlighter-text&amp;quot;&amp;gt;&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;enlighter-c0&amp;quot;&amp;gt;// Datenpunkte der Tasmota Namen (!!! Bitte nicht ändern !!!)&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;enlighter-text&amp;quot;&amp;gt;&amp;lt;/span&amp;gt;&amp;lt;/div&amp;gt;&amp;lt;/div&amp;gt;&amp;lt;div&amp;gt;&amp;lt;div&amp;gt;&amp;lt;span class=&amp;quot;enlighter-text&amp;quot;&amp;gt;&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;enlighter-k2&amp;quot;&amp;gt;const&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;enlighter-text&amp;quot;&amp;gt; tasmotaDpsName = $&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;enlighter-g1&amp;quot;&amp;gt;(&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;enlighter-s0&amp;quot;&amp;gt;'state[id='&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;enlighter-text&amp;quot;&amp;gt; + tasmota_dp + &amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;enlighter-s0&amp;quot;&amp;gt;'.*.DeviceName]'&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;enlighter-g1&amp;quot;&amp;gt;)&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;enlighter-text&amp;quot;&amp;gt;;&amp;lt;/span&amp;gt;&amp;lt;/div&amp;gt;&amp;lt;/div&amp;gt;&amp;lt;div&amp;gt;&amp;lt;div&amp;gt;&amp;lt;br&amp;gt;&amp;lt;/div&amp;gt;&amp;lt;/div&amp;gt;&amp;lt;div&amp;gt;&amp;lt;div&amp;gt;&amp;lt;span class=&amp;quot;enlighter-text&amp;quot;&amp;gt;&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;enlighter-c0&amp;quot;&amp;gt;// Tasmota Verbrauch aktualisieren - nachts um 00:00 Uhr&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;enlighter-text&amp;quot;&amp;gt;&amp;lt;/span&amp;gt;&amp;lt;/div&amp;gt;&amp;lt;/div&amp;gt;&amp;lt;div&amp;gt;&amp;lt;div&amp;gt;&amp;lt;span class=&amp;quot;enlighter-text&amp;quot;&amp;gt;&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;enlighter-k0&amp;quot;&amp;gt;function&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;enlighter-text&amp;quot;&amp;gt; &amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;enlighter-m0&amp;quot;&amp;gt;tasmota_vebrauch_tag&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;enlighter-g1&amp;quot;&amp;gt;(&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;enlighter-g1&amp;quot;&amp;gt;)&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;enlighter-text&amp;quot;&amp;gt; &amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;enlighter-g1&amp;quot;&amp;gt;{&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;enlighter-text&amp;quot;&amp;gt;&amp;lt;/span&amp;gt;&amp;lt;/div&amp;gt;&amp;lt;/div&amp;gt;&amp;lt;div&amp;gt;&amp;lt;div&amp;gt;&amp;lt;span class=&amp;quot;enlighter-text&amp;quot;&amp;gt; &amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;enlighter-c0&amp;quot;&amp;gt;// Nochmals das Tagesupdate durchlaufen, damit die restlichen Werte gelesen werden&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;enlighter-text&amp;quot;&amp;gt;&amp;lt;/span&amp;gt;&amp;lt;/div&amp;gt;&amp;lt;/div&amp;gt;&amp;lt;div&amp;gt;&amp;lt;div&amp;gt;&amp;lt;span class=&amp;quot;enlighter-text&amp;quot;&amp;gt; &amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;enlighter-m0&amp;quot;&amp;gt;tasmota_verbrauch_update&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;enlighter-g1&amp;quot;&amp;gt;(&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;enlighter-g1&amp;quot;&amp;gt;)&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;enlighter-text&amp;quot;&amp;gt;;&amp;lt;/span&amp;gt;&amp;lt;/div&amp;gt;&amp;lt;/div&amp;gt;&amp;lt;div&amp;gt;&amp;lt;div&amp;gt;&amp;lt;br&amp;gt;&amp;lt;/div&amp;gt;&amp;lt;/div&amp;gt;&amp;lt;div&amp;gt;&amp;lt;div&amp;gt;&amp;lt;span class=&amp;quot;enlighter-text&amp;quot;&amp;gt; &amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;enlighter-c0&amp;quot;&amp;gt;// Datumsvariable&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;enlighter-text&amp;quot;&amp;gt;&amp;lt;/span&amp;gt;&amp;lt;/div&amp;gt;&amp;lt;/div&amp;gt;&amp;lt;div&amp;gt;&amp;lt;div&amp;gt;&amp;lt;span class=&amp;quot;enlighter-text&amp;quot;&amp;gt; &amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;enlighter-k2&amp;quot;&amp;gt;var&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;enlighter-text&amp;quot;&amp;gt; heute = &amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;enlighter-k3&amp;quot;&amp;gt;new&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;enlighter-text&amp;quot;&amp;gt; &amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;enlighter-m0&amp;quot;&amp;gt;Date&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;enlighter-g1&amp;quot;&amp;gt;(&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;enlighter-g1&amp;quot;&amp;gt;)&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;enlighter-text&amp;quot;&amp;gt;;&amp;lt;/span&amp;gt;&amp;lt;/div&amp;gt;&amp;lt;/div&amp;gt;&amp;lt;div&amp;gt;&amp;lt;div&amp;gt;&amp;lt;br&amp;gt;&amp;lt;/div&amp;gt;&amp;lt;/div&amp;gt;&amp;lt;div&amp;gt;&amp;lt;div&amp;gt;&amp;lt;span class=&amp;quot;enlighter-text&amp;quot;&amp;gt; &amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;enlighter-c0&amp;quot;&amp;gt;// Heute zu Gestern verschieben. Täglich um 00:00 Uhr&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;enlighter-text&amp;quot;&amp;gt;&amp;lt;/span&amp;gt;&amp;lt;/div&amp;gt;&amp;lt;/div&amp;gt;&amp;lt;div&amp;gt;&amp;lt;div&amp;gt;&amp;lt;span class=&amp;quot;enlighter-text&amp;quot;&amp;gt; &amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;enlighter-m0&amp;quot;&amp;gt;verschiebe_verbrauch_objekt&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;enlighter-g1&amp;quot;&amp;gt;(&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;enlighter-s0&amp;quot;&amp;gt;&amp;quot;heute&amp;quot;&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;enlighter-text&amp;quot;&amp;gt;, &amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;enlighter-s0&amp;quot;&amp;gt;&amp;quot;gestern&amp;quot;&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;enlighter-g1&amp;quot;&amp;gt;)&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;enlighter-text&amp;quot;&amp;gt;;&amp;lt;/span&amp;gt;&amp;lt;/div&amp;gt;&amp;lt;/div&amp;gt;&amp;lt;div&amp;gt;&amp;lt;div&amp;gt;&amp;lt;span class=&amp;quot;enlighter-text&amp;quot;&amp;gt; &amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;enlighter-m0&amp;quot;&amp;gt;log&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;enlighter-text&amp;quot;&amp;gt; &amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;enlighter-g1&amp;quot;&amp;gt;(&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;enlighter-s0&amp;quot;&amp;gt;&amp;quot;Tasmota Verbrauch: Werte für gestern und heute aktualisiert!&amp;quot;&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;enlighter-g1&amp;quot;&amp;gt;)&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;enlighter-text&amp;quot;&amp;gt;;&amp;lt;/span&amp;gt;&amp;lt;/div&amp;gt;&amp;lt;/div&amp;gt;&amp;lt;div&amp;gt;&amp;lt;div&amp;gt;&amp;lt;br&amp;gt;&amp;lt;/div&amp;gt;&amp;lt;/div&amp;gt;&amp;lt;div&amp;gt;&amp;lt;div&amp;gt;&amp;lt;span class=&amp;quot;enlighter-text&amp;quot;&amp;gt; &amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;enlighter-c0&amp;quot;&amp;gt;// aktuelle Woche in letzte Woche verschieben. Am Montag um 00:00 Uhr&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;enlighter-text&amp;quot;&amp;gt;&amp;lt;/span&amp;gt;&amp;lt;/div&amp;gt;&amp;lt;/div&amp;gt;&amp;lt;div&amp;gt;&amp;lt;div&amp;gt;&amp;lt;span class=&amp;quot;enlighter-text&amp;quot;&amp;gt; &amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;enlighter-k1&amp;quot;&amp;gt;if&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;enlighter-text&amp;quot;&amp;gt; &amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;enlighter-g1&amp;quot;&amp;gt;(&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;enlighter-text&amp;quot;&amp;gt;heute.&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;enlighter-m3&amp;quot;&amp;gt;getDay&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;enlighter-g1&amp;quot;&amp;gt;(&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;enlighter-g1&amp;quot;&amp;gt;)&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;enlighter-text&amp;quot;&amp;gt; === &amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;enlighter-n1&amp;quot;&amp;gt;1&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;enlighter-g1&amp;quot;&amp;gt;)&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;enlighter-text&amp;quot;&amp;gt; &amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;enlighter-g1&amp;quot;&amp;gt;{&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;enlighter-text&amp;quot;&amp;gt;&amp;lt;/span&amp;gt;&amp;lt;/div&amp;gt;&amp;lt;/div&amp;gt;&amp;lt;div&amp;gt;&amp;lt;div&amp;gt;&amp;lt;span class=&amp;quot;enlighter-text&amp;quot;&amp;gt; &amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;enlighter-m0&amp;quot;&amp;gt;verschiebe_verbrauch_objekt&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;enlighter-g1&amp;quot;&amp;gt;(&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;enlighter-s0&amp;quot;&amp;gt;&amp;quot;diese_woche&amp;quot;&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;enlighter-text&amp;quot;&amp;gt;, &amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;enlighter-s0&amp;quot;&amp;gt;&amp;quot;letzte_woche&amp;quot;&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;enlighter-g1&amp;quot;&amp;gt;)&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;enlighter-text&amp;quot;&amp;gt;;&amp;lt;/span&amp;gt;&amp;lt;/div&amp;gt;&amp;lt;/div&amp;gt;&amp;lt;div&amp;gt;&amp;lt;div&amp;gt;&amp;lt;span class=&amp;quot;enlighter-text&amp;quot;&amp;gt; &amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;enlighter-m0&amp;quot;&amp;gt;log&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;enlighter-text&amp;quot;&amp;gt; &amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;enlighter-g1&amp;quot;&amp;gt;(&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;enlighter-s0&amp;quot;&amp;gt;&amp;quot;Tasmota Verbrauch: Werte für diese und letzte Woche aktualisiert!&amp;quot;&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;enlighter-g1&amp;quot;&amp;gt;)&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;enlighter-text&amp;quot;&amp;gt;;&amp;lt;/span&amp;gt;&amp;lt;/div&amp;gt;&amp;lt;/div&amp;gt;&amp;lt;div&amp;gt;&amp;lt;div&amp;gt;&amp;lt;span class=&amp;quot;enlighter-text&amp;quot;&amp;gt; &amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;enlighter-g1&amp;quot;&amp;gt;}&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;enlighter-text&amp;quot;&amp;gt;&amp;lt;/span&amp;gt;&amp;lt;/div&amp;gt;&amp;lt;/div&amp;gt;&amp;lt;div&amp;gt;&amp;lt;div&amp;gt;&amp;lt;br&amp;gt;&amp;lt;/div&amp;gt;&amp;lt;/div&amp;gt;&amp;lt;div&amp;gt;&amp;lt;div&amp;gt;&amp;lt;span class=&amp;quot;enlighter-text&amp;quot;&amp;gt; &amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;enlighter-c0&amp;quot;&amp;gt;// aktueller Monat in letzten Monat verschieben. Am 1. des Monats um 00:00 Uhr&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;enlighter-text&amp;quot;&amp;gt;&amp;lt;/span&amp;gt;&amp;lt;/div&amp;gt;&amp;lt;/div&amp;gt;&amp;lt;div&amp;gt;&amp;lt;div&amp;gt;&amp;lt;span class=&amp;quot;enlighter-text&amp;quot;&amp;gt; &amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;enlighter-k1&amp;quot;&amp;gt;if&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;enlighter-text&amp;quot;&amp;gt; &amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;enlighter-g1&amp;quot;&amp;gt;(&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;enlighter-text&amp;quot;&amp;gt;heute.&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;enlighter-m3&amp;quot;&amp;gt;getDate&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;enlighter-g1&amp;quot;&amp;gt;(&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;enlighter-g1&amp;quot;&amp;gt;)&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;enlighter-text&amp;quot;&amp;gt; === &amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;enlighter-n1&amp;quot;&amp;gt;1&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;enlighter-g1&amp;quot;&amp;gt;)&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;enlighter-text&amp;quot;&amp;gt; &amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;enlighter-g1&amp;quot;&amp;gt;{&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;enlighter-text&amp;quot;&amp;gt;&amp;lt;/span&amp;gt;&amp;lt;/div&amp;gt;&amp;lt;/div&amp;gt;&amp;lt;div&amp;gt;&amp;lt;div&amp;gt;&amp;lt;span class=&amp;quot;enlighter-text&amp;quot;&amp;gt; &amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;enlighter-m0&amp;quot;&amp;gt;verschiebe_verbrauch_objekt&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;enlighter-g1&amp;quot;&amp;gt;(&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;enlighter-s0&amp;quot;&amp;gt;&amp;quot;dieser_monat&amp;quot;&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;enlighter-text&amp;quot;&amp;gt;, &amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;enlighter-s0&amp;quot;&amp;gt;&amp;quot;letzter_monat&amp;quot;&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;enlighter-g1&amp;quot;&amp;gt;)&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;enlighter-text&amp;quot;&amp;gt;;&amp;lt;/span&amp;gt;&amp;lt;/div&amp;gt;&amp;lt;/div&amp;gt;&amp;lt;div&amp;gt;&amp;lt;div&amp;gt;&amp;lt;span class=&amp;quot;enlighter-text&amp;quot;&amp;gt; &amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;enlighter-m0&amp;quot;&amp;gt;log&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;enlighter-text&amp;quot;&amp;gt; &amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;enlighter-g1&amp;quot;&amp;gt;(&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;enlighter-s0&amp;quot;&amp;gt;&amp;quot;Tasmota Verbrauch: Werte für diesen und letzten Monat aktualisiert!&amp;quot;&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;enlighter-g1&amp;quot;&amp;gt;)&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;enlighter-text&amp;quot;&amp;gt;;&amp;lt;/span&amp;gt;&amp;lt;/div&amp;gt;&amp;lt;/div&amp;gt;&amp;lt;div&amp;gt;&amp;lt;div&amp;gt;&amp;lt;span class=&amp;quot;enlighter-text&amp;quot;&amp;gt; &amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;enlighter-g1&amp;quot;&amp;gt;}&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;enlighter-text&amp;quot;&amp;gt;&amp;lt;/span&amp;gt;&amp;lt;/div&amp;gt;&amp;lt;/div&amp;gt;&amp;lt;div&amp;gt;&amp;lt;div&amp;gt;&amp;lt;br&amp;gt;&amp;lt;/div&amp;gt;&amp;lt;/div&amp;gt;&amp;lt;div&amp;gt;&amp;lt;div&amp;gt;&amp;lt;span class=&amp;quot;enlighter-text&amp;quot;&amp;gt; &amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;enlighter-c0&amp;quot;&amp;gt;// aktuelles Jahr in letztes Jahr verschieben. Am 1. des Monats am 1. Monat um 00:00 Uhr&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;enlighter-text&amp;quot;&amp;gt;&amp;lt;/span&amp;gt;&amp;lt;/div&amp;gt;&amp;lt;/div&amp;gt;&amp;lt;div&amp;gt;&amp;lt;div&amp;gt;&amp;lt;span class=&amp;quot;enlighter-text&amp;quot;&amp;gt; &amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;enlighter-k1&amp;quot;&amp;gt;if&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;enlighter-text&amp;quot;&amp;gt; &amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;enlighter-g1&amp;quot;&amp;gt;(&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;enlighter-text&amp;quot;&amp;gt;heute.&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;enlighter-m3&amp;quot;&amp;gt;getDate&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;enlighter-g1&amp;quot;&amp;gt;(&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;enlighter-g1&amp;quot;&amp;gt;)&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;enlighter-text&amp;quot;&amp;gt; === &amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;enlighter-n1&amp;quot;&amp;gt;1&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;enlighter-text&amp;quot;&amp;gt; &amp;amp;&amp;amp; heute.&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;enlighter-m3&amp;quot;&amp;gt;getMonth&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;enlighter-g1&amp;quot;&amp;gt;(&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;enlighter-g1&amp;quot;&amp;gt;)&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;enlighter-text&amp;quot;&amp;gt; === &amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;enlighter-n1&amp;quot;&amp;gt;0&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;enlighter-g1&amp;quot;&amp;gt;)&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;enlighter-text&amp;quot;&amp;gt; &amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;enlighter-g1&amp;quot;&amp;gt;{&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;enlighter-text&amp;quot;&amp;gt;&amp;lt;/span&amp;gt;&amp;lt;/div&amp;gt;&amp;lt;/div&amp;gt;&amp;lt;div&amp;gt;&amp;lt;div&amp;gt;&amp;lt;span class=&amp;quot;enlighter-text&amp;quot;&amp;gt; &amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;enlighter-m0&amp;quot;&amp;gt;verschiebe_verbrauch_objekt&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;enlighter-g1&amp;quot;&amp;gt;(&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;enlighter-s0&amp;quot;&amp;gt;&amp;quot;dieses_jahr&amp;quot;&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;enlighter-text&amp;quot;&amp;gt;, &amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;enlighter-s0&amp;quot;&amp;gt;&amp;quot;letztes_jahr&amp;quot;&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;enlighter-g1&amp;quot;&amp;gt;)&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;enlighter-text&amp;quot;&amp;gt;;&amp;lt;/span&amp;gt;&amp;lt;/div&amp;gt;&amp;lt;/div&amp;gt;&amp;lt;div&amp;gt;&amp;lt;div&amp;gt;&amp;lt;span class=&amp;quot;enlighter-text&amp;quot;&amp;gt; &amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;enlighter-m0&amp;quot;&amp;gt;log&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;enlighter-text&amp;quot;&amp;gt; &amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;enlighter-g1&amp;quot;&amp;gt;(&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;enlighter-s0&amp;quot;&amp;gt;&amp;quot;Tasmota Verbrauch: Werte für dieses und letztes Jahr aktualisiert!&amp;quot;&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;enlighter-g1&amp;quot;&amp;gt;)&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;enlighter-text&amp;quot;&amp;gt;;&amp;lt;/span&amp;gt;&amp;lt;/div&amp;gt;&amp;lt;/div&amp;gt;&amp;lt;div&amp;gt;&amp;lt;div&amp;gt;&amp;lt;span class=&amp;quot;enlighter-text&amp;quot;&amp;gt; &amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;enlighter-g1&amp;quot;&amp;gt;}&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;enlighter-text&amp;quot;&amp;gt;&amp;lt;/span&amp;gt;&amp;lt;/div&amp;gt;&amp;lt;/div&amp;gt;&amp;lt;div&amp;gt;&amp;lt;div&amp;gt;&amp;lt;span class=&amp;quot;enlighter-text&amp;quot;&amp;gt;&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;enlighter-g1&amp;quot;&amp;gt;}&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;enlighter-text&amp;quot;&amp;gt;&amp;lt;/span&amp;gt;&amp;lt;/div&amp;gt;&amp;lt;/div&amp;gt;&amp;lt;div&amp;gt;&amp;lt;div&amp;gt;&amp;lt;br&amp;gt;&amp;lt;/div&amp;gt;&amp;lt;/div&amp;gt;&amp;lt;div&amp;gt;&amp;lt;div&amp;gt;&amp;lt;span class=&amp;quot;enlighter-text&amp;quot;&amp;gt;&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;enlighter-c0&amp;quot;&amp;gt;// Tagesverbrauch alle 15 Min von der Original Variable des Tasmota in eigene Variable kopieren&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;enlighter-text&amp;quot;&amp;gt;&amp;lt;/span&amp;gt;&amp;lt;/div&amp;gt;&amp;lt;/div&amp;gt;&amp;lt;div&amp;gt;&amp;lt;div&amp;gt;&amp;lt;span class=&amp;quot;enlighter-text&amp;quot;&amp;gt;&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;enlighter-k0&amp;quot;&amp;gt;function&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;enlighter-text&amp;quot;&amp;gt; &amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;enlighter-m0&amp;quot;&amp;gt;tasmota_verbrauch_update&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;enlighter-g1&amp;quot;&amp;gt;(&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;enlighter-g1&amp;quot;&amp;gt;)&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;enlighter-text&amp;quot;&amp;gt; &amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;enlighter-g1&amp;quot;&amp;gt;{&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;enlighter-text&amp;quot;&amp;gt;&amp;lt;/span&amp;gt;&amp;lt;/div&amp;gt;&amp;lt;/div&amp;gt;&amp;lt;div&amp;gt;&amp;lt;div&amp;gt;&amp;lt;span class=&amp;quot;enlighter-text&amp;quot;&amp;gt; &amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;enlighter-k2&amp;quot;&amp;gt;var&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;enlighter-text&amp;quot;&amp;gt; anzahl_updates = &amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;enlighter-n1&amp;quot;&amp;gt;0&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;enlighter-text&amp;quot;&amp;gt;;&amp;lt;/span&amp;gt;&amp;lt;/div&amp;gt;&amp;lt;/div&amp;gt;&amp;lt;div&amp;gt;&amp;lt;div&amp;gt;&amp;lt;span class=&amp;quot;enlighter-text&amp;quot;&amp;gt; &amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;enlighter-k2&amp;quot;&amp;gt;var&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;enlighter-text&amp;quot;&amp;gt; anzahl_reboots = &amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;enlighter-n1&amp;quot;&amp;gt;0&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;enlighter-text&amp;quot;&amp;gt;;&amp;lt;/span&amp;gt;&amp;lt;/div&amp;gt;&amp;lt;/div&amp;gt;&amp;lt;div&amp;gt;&amp;lt;div&amp;gt;&amp;lt;span class=&amp;quot;enlighter-text&amp;quot;&amp;gt; &amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;enlighter-k2&amp;quot;&amp;gt;var&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;enlighter-text&amp;quot;&amp;gt; anzahl_gleich = &amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;enlighter-n1&amp;quot;&amp;gt;0&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;enlighter-text&amp;quot;&amp;gt;;&amp;lt;/span&amp;gt;&amp;lt;/div&amp;gt;&amp;lt;/div&amp;gt;&amp;lt;div&amp;gt;&amp;lt;div&amp;gt;&amp;lt;span class=&amp;quot;enlighter-text&amp;quot;&amp;gt; tasmotaDps.&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;enlighter-m3&amp;quot;&amp;gt;each&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;enlighter-g1&amp;quot;&amp;gt;(&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;enlighter-k0&amp;quot;&amp;gt;function&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;enlighter-text&amp;quot;&amp;gt; &amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;enlighter-g1&amp;quot;&amp;gt;(&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;enlighter-text&amp;quot;&amp;gt;id, i&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;enlighter-g1&amp;quot;&amp;gt;)&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;enlighter-text&amp;quot;&amp;gt; &amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;enlighter-g1&amp;quot;&amp;gt;{&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;enlighter-text&amp;quot;&amp;gt;&amp;lt;/span&amp;gt;&amp;lt;/div&amp;gt;&amp;lt;/div&amp;gt;&amp;lt;div&amp;gt;&amp;lt;div&amp;gt;&amp;lt;span class=&amp;quot;enlighter-text&amp;quot;&amp;gt; &amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;enlighter-k2&amp;quot;&amp;gt;var&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;enlighter-text&amp;quot;&amp;gt; tasmota_verbrauch = &amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;enlighter-m0&amp;quot;&amp;gt;getState&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;enlighter-g1&amp;quot;&amp;gt;(&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;enlighter-text&amp;quot;&amp;gt;id&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;enlighter-g1&amp;quot;&amp;gt;)&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;enlighter-text&amp;quot;&amp;gt;.&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;enlighter-m3&amp;quot;&amp;gt;val&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;enlighter-text&amp;quot;&amp;gt;;&amp;lt;/span&amp;gt;&amp;lt;/div&amp;gt;&amp;lt;/div&amp;gt;&amp;lt;div&amp;gt;&amp;lt;div&amp;gt;&amp;lt;span class=&amp;quot;enlighter-text&amp;quot;&amp;gt; &amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;enlighter-c0&amp;quot;&amp;gt;// Einige Tasmota haben keine Verbrauchswerte (noch nicht)&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;enlighter-text&amp;quot;&amp;gt;&amp;lt;/span&amp;gt;&amp;lt;/div&amp;gt;&amp;lt;/div&amp;gt;&amp;lt;div&amp;gt;&amp;lt;div&amp;gt;&amp;lt;span class=&amp;quot;enlighter-text&amp;quot;&amp;gt; &amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;enlighter-k1&amp;quot;&amp;gt;if&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;enlighter-text&amp;quot;&amp;gt; &amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;enlighter-g1&amp;quot;&amp;gt;(&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;enlighter-text&amp;quot;&amp;gt;tasmota_verbrauch != &amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;enlighter-e1&amp;quot;&amp;gt;null&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;enlighter-g1&amp;quot;&amp;gt;)&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;enlighter-text&amp;quot;&amp;gt; &amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;enlighter-g1&amp;quot;&amp;gt;{&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;enlighter-text&amp;quot;&amp;gt;&amp;lt;/span&amp;gt;&amp;lt;/div&amp;gt;&amp;lt;/div&amp;gt;&amp;lt;div&amp;gt;&amp;lt;div&amp;gt;&amp;lt;span class=&amp;quot;enlighter-text&amp;quot;&amp;gt; &amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;enlighter-c0&amp;quot;&amp;gt;// Hole aktuellen Wert, um zu kontrollieren, ob ein Reboot stattgefunden hat&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;enlighter-text&amp;quot;&amp;gt;&amp;lt;/span&amp;gt;&amp;lt;/div&amp;gt;&amp;lt;/div&amp;gt;&amp;lt;div&amp;gt;&amp;lt;div&amp;gt;&amp;lt;span class=&amp;quot;enlighter-text&amp;quot;&amp;gt; &amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;enlighter-k2&amp;quot;&amp;gt;var&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;enlighter-text&amp;quot;&amp;gt; aktueller_wert = &amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;enlighter-m0&amp;quot;&amp;gt;getState&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;enlighter-g1&amp;quot;&amp;gt;(&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;enlighter-m0&amp;quot;&amp;gt;tasmota_DP&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;enlighter-g1&amp;quot;&amp;gt;(&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;enlighter-text&amp;quot;&amp;gt;id&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;enlighter-g1&amp;quot;&amp;gt;)&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;enlighter-text&amp;quot;&amp;gt; + &amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;enlighter-s0&amp;quot;&amp;gt;&amp;quot;aktueller_wert&amp;quot;&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;enlighter-g1&amp;quot;&amp;gt;)&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;enlighter-text&amp;quot;&amp;gt;.&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;enlighter-m3&amp;quot;&amp;gt;val&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;enlighter-text&amp;quot;&amp;gt;;&amp;lt;/span&amp;gt;&amp;lt;/div&amp;gt;&amp;lt;/div&amp;gt;&amp;lt;div&amp;gt;&amp;lt;div&amp;gt;&amp;lt;span class=&amp;quot;enlighter-text&amp;quot;&amp;gt; &amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;enlighter-k2&amp;quot;&amp;gt;var&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;enlighter-text&amp;quot;&amp;gt; alter_wert = &amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;enlighter-n1&amp;quot;&amp;gt;0&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;enlighter-text&amp;quot;&amp;gt;;&amp;lt;/span&amp;gt;&amp;lt;/div&amp;gt;&amp;lt;/div&amp;gt;&amp;lt;div&amp;gt;&amp;lt;div&amp;gt;&amp;lt;span class=&amp;quot;enlighter-text&amp;quot;&amp;gt; &amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;enlighter-c0&amp;quot;&amp;gt;// Prüfe alten und neuen Wert&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;enlighter-text&amp;quot;&amp;gt;&amp;lt;/span&amp;gt;&amp;lt;/div&amp;gt;&amp;lt;/div&amp;gt;&amp;lt;div&amp;gt;&amp;lt;div&amp;gt;&amp;lt;span class=&amp;quot;enlighter-text&amp;quot;&amp;gt; &amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;enlighter-k1&amp;quot;&amp;gt;if&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;enlighter-text&amp;quot;&amp;gt; &amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;enlighter-g1&amp;quot;&amp;gt;(&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;enlighter-text&amp;quot;&amp;gt;tasmota_verbrauch &amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;enlighter-g1&amp;quot;&amp;gt;&amp;amp;gt;&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;enlighter-text&amp;quot;&amp;gt; aktueller_wert&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;enlighter-g1&amp;quot;&amp;gt;)&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;enlighter-text&amp;quot;&amp;gt; &amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;enlighter-g1&amp;quot;&amp;gt;{&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;enlighter-text&amp;quot;&amp;gt;&amp;lt;/span&amp;gt;&amp;lt;/div&amp;gt;&amp;lt;/div&amp;gt;&amp;lt;div&amp;gt;&amp;lt;div&amp;gt;&amp;lt;span class=&amp;quot;enlighter-text&amp;quot;&amp;gt; &amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;enlighter-c0&amp;quot;&amp;gt;// Verbrauchswert ist größer als alter Wert -&amp;amp;gt; es wurde kein Reboot durchgeführt&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;enlighter-text&amp;quot;&amp;gt;&amp;lt;/span&amp;gt;&amp;lt;/div&amp;gt;&amp;lt;/div&amp;gt;&amp;lt;div&amp;gt;&amp;lt;div&amp;gt;&amp;lt;span class=&amp;quot;enlighter-text&amp;quot;&amp;gt; &amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;enlighter-m0&amp;quot;&amp;gt;setState&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;enlighter-g1&amp;quot;&amp;gt;(&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;enlighter-m0&amp;quot;&amp;gt;tasmota_DP&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;enlighter-g1&amp;quot;&amp;gt;(&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;enlighter-text&amp;quot;&amp;gt;id&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;enlighter-g1&amp;quot;&amp;gt;)&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;enlighter-text&amp;quot;&amp;gt; + &amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;enlighter-s0&amp;quot;&amp;gt;&amp;quot;alter_wert&amp;quot;&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;enlighter-text&amp;quot;&amp;gt;, aktueller_wert,&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;enlighter-e0&amp;quot;&amp;gt;true&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;enlighter-g1&amp;quot;&amp;gt;)&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;enlighter-text&amp;quot;&amp;gt;;&amp;lt;/span&amp;gt;&amp;lt;/div&amp;gt;&amp;lt;/div&amp;gt;&amp;lt;div&amp;gt;&amp;lt;div&amp;gt;&amp;lt;span class=&amp;quot;enlighter-text&amp;quot;&amp;gt; alter_wert = aktueller_wert;&amp;lt;/span&amp;gt;&amp;lt;/div&amp;gt;&amp;lt;/div&amp;gt;&amp;lt;div&amp;gt;&amp;lt;div&amp;gt;&amp;lt;span class=&amp;quot;enlighter-text&amp;quot;&amp;gt; anzahl_updates++;&amp;lt;/span&amp;gt;&amp;lt;/div&amp;gt;&amp;lt;/div&amp;gt;&amp;lt;div&amp;gt;&amp;lt;div&amp;gt;&amp;lt;span class=&amp;quot;enlighter-text&amp;quot;&amp;gt; &amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;enlighter-g1&amp;quot;&amp;gt;}&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;enlighter-text&amp;quot;&amp;gt;&amp;lt;/span&amp;gt;&amp;lt;/div&amp;gt;&amp;lt;/div&amp;gt;&amp;lt;div&amp;gt;&amp;lt;div&amp;gt;&amp;lt;span class=&amp;quot;enlighter-text&amp;quot;&amp;gt; &amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;enlighter-k1&amp;quot;&amp;gt;if&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;enlighter-text&amp;quot;&amp;gt; &amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;enlighter-g1&amp;quot;&amp;gt;(&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;enlighter-text&amp;quot;&amp;gt;aktueller_wert &amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;enlighter-g1&amp;quot;&amp;gt;&amp;amp;gt;&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;enlighter-text&amp;quot;&amp;gt; tasmota_verbrauch&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;enlighter-g1&amp;quot;&amp;gt;)&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;enlighter-text&amp;quot;&amp;gt; &amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;enlighter-g1&amp;quot;&amp;gt;{&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;enlighter-text&amp;quot;&amp;gt;&amp;lt;/span&amp;gt;&amp;lt;/div&amp;gt;&amp;lt;/div&amp;gt;&amp;lt;div&amp;gt;&amp;lt;div&amp;gt;&amp;lt;span class=&amp;quot;enlighter-text&amp;quot;&amp;gt; &amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;enlighter-c0&amp;quot;&amp;gt;// Verbrauchswert ist kleiner als alter Wert -&amp;amp;gt; es wurde ein Reboot durchgeführt&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;enlighter-text&amp;quot;&amp;gt;&amp;lt;/span&amp;gt;&amp;lt;/div&amp;gt;&amp;lt;/div&amp;gt;&amp;lt;div&amp;gt;&amp;lt;div&amp;gt;&amp;lt;span class=&amp;quot;enlighter-text&amp;quot;&amp;gt; &amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;enlighter-m0&amp;quot;&amp;gt;setState&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;enlighter-g1&amp;quot;&amp;gt;(&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;enlighter-m0&amp;quot;&amp;gt;tasmota_DP&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;enlighter-g1&amp;quot;&amp;gt;(&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;enlighter-text&amp;quot;&amp;gt;id&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;enlighter-g1&amp;quot;&amp;gt;)&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;enlighter-text&amp;quot;&amp;gt; + &amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;enlighter-s0&amp;quot;&amp;gt;&amp;quot;alter_wert&amp;quot;&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;enlighter-text&amp;quot;&amp;gt;, &amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;enlighter-n1&amp;quot;&amp;gt;0&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;enlighter-text&amp;quot;&amp;gt;,&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;enlighter-e0&amp;quot;&amp;gt;true&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;enlighter-g1&amp;quot;&amp;gt;)&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;enlighter-text&amp;quot;&amp;gt;;&amp;lt;/span&amp;gt;&amp;lt;/div&amp;gt;&amp;lt;/div&amp;gt;&amp;lt;div&amp;gt;&amp;lt;div&amp;gt;&amp;lt;span class=&amp;quot;enlighter-text&amp;quot;&amp;gt; alter_wert = tasmota_verbrauch;&amp;lt;/span&amp;gt;&amp;lt;/div&amp;gt;&amp;lt;/div&amp;gt;&amp;lt;div&amp;gt;&amp;lt;div&amp;gt;&amp;lt;span class=&amp;quot;enlighter-text&amp;quot;&amp;gt; anzahl_reboots++;&amp;lt;/span&amp;gt;&amp;lt;/div&amp;gt;&amp;lt;/div&amp;gt;&amp;lt;div&amp;gt;&amp;lt;div&amp;gt;&amp;lt;span class=&amp;quot;enlighter-text&amp;quot;&amp;gt; &amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;enlighter-g1&amp;quot;&amp;gt;}&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;enlighter-text&amp;quot;&amp;gt;&amp;lt;/span&amp;gt;&amp;lt;/div&amp;gt;&amp;lt;/div&amp;gt;&amp;lt;div&amp;gt;&amp;lt;div&amp;gt;&amp;lt;span class=&amp;quot;enlighter-text&amp;quot;&amp;gt; &amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;enlighter-k1&amp;quot;&amp;gt;if&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;enlighter-text&amp;quot;&amp;gt; &amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;enlighter-g1&amp;quot;&amp;gt;(&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;enlighter-text&amp;quot;&amp;gt;tasmota_verbrauch == aktueller_wert&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;enlighter-g1&amp;quot;&amp;gt;)&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;enlighter-text&amp;quot;&amp;gt; &amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;enlighter-g1&amp;quot;&amp;gt;{&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;enlighter-text&amp;quot;&amp;gt;&amp;lt;/span&amp;gt;&amp;lt;/div&amp;gt;&amp;lt;/div&amp;gt;&amp;lt;div&amp;gt;&amp;lt;div&amp;gt;&amp;lt;span class=&amp;quot;enlighter-text&amp;quot;&amp;gt; &amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;enlighter-c0&amp;quot;&amp;gt;// Verbrauchswert ist gleich wie alter Wert -&amp;amp;gt; kein Update notwendig&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;enlighter-text&amp;quot;&amp;gt;&amp;lt;/span&amp;gt;&amp;lt;/div&amp;gt;&amp;lt;/div&amp;gt;&amp;lt;div&amp;gt;&amp;lt;div&amp;gt;&amp;lt;span class=&amp;quot;enlighter-text&amp;quot;&amp;gt; alter_wert = aktueller_wert;&amp;lt;/span&amp;gt;&amp;lt;/div&amp;gt;&amp;lt;/div&amp;gt;&amp;lt;div&amp;gt;&amp;lt;div&amp;gt;&amp;lt;span class=&amp;quot;enlighter-text&amp;quot;&amp;gt; anzahl_gleich++;&amp;lt;/span&amp;gt;&amp;lt;/div&amp;gt;&amp;lt;/div&amp;gt;&amp;lt;div&amp;gt;&amp;lt;div&amp;gt;&amp;lt;span class=&amp;quot;enlighter-text&amp;quot;&amp;gt; &amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;enlighter-g1&amp;quot;&amp;gt;}&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;enlighter-text&amp;quot;&amp;gt;&amp;lt;/span&amp;gt;&amp;lt;/div&amp;gt;&amp;lt;/div&amp;gt;&amp;lt;div&amp;gt;&amp;lt;div&amp;gt;&amp;lt;br&amp;gt;&amp;lt;/div&amp;gt;&amp;lt;/div&amp;gt;&amp;lt;div&amp;gt;&amp;lt;div&amp;gt;&amp;lt;span class=&amp;quot;enlighter-text&amp;quot;&amp;gt; &amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;enlighter-m0&amp;quot;&amp;gt;setState&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;enlighter-g1&amp;quot;&amp;gt;(&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;enlighter-m0&amp;quot;&amp;gt;tasmota_DP&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;enlighter-g1&amp;quot;&amp;gt;(&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;enlighter-text&amp;quot;&amp;gt;id&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;enlighter-g1&amp;quot;&amp;gt;)&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;enlighter-text&amp;quot;&amp;gt; + &amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;enlighter-s0&amp;quot;&amp;gt;&amp;quot;aktueller_wert&amp;quot;&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;enlighter-text&amp;quot;&amp;gt;, tasmota_verbrauch&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;enlighter-g1&amp;quot;&amp;gt;)&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;enlighter-text&amp;quot;&amp;gt;;&amp;lt;/span&amp;gt;&amp;lt;/div&amp;gt;&amp;lt;/div&amp;gt;&amp;lt;div&amp;gt;&amp;lt;div&amp;gt;&amp;lt;span class=&amp;quot;enlighter-text&amp;quot;&amp;gt; &amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;enlighter-c0&amp;quot;&amp;gt;// Alter und neuer Wert -&amp;amp;gt; aktuelle Differenz&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;enlighter-text&amp;quot;&amp;gt;&amp;lt;/span&amp;gt;&amp;lt;/div&amp;gt;&amp;lt;/div&amp;gt;&amp;lt;div&amp;gt;&amp;lt;div&amp;gt;&amp;lt;br&amp;gt;&amp;lt;/div&amp;gt;&amp;lt;/div&amp;gt;&amp;lt;div&amp;gt;&amp;lt;div&amp;gt;&amp;lt;span class=&amp;quot;enlighter-text&amp;quot;&amp;gt; &amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;enlighter-k2&amp;quot;&amp;gt;var&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;enlighter-text&amp;quot;&amp;gt; verbrauch = &amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;enlighter-m0&amp;quot;&amp;gt;parseFloat&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;enlighter-g1&amp;quot;&amp;gt;(&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;enlighter-text&amp;quot;&amp;gt;tasmota_verbrauch&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;enlighter-g1&amp;quot;&amp;gt;)&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;enlighter-text&amp;quot;&amp;gt; - alter_wert;&amp;lt;/span&amp;gt;&amp;lt;/div&amp;gt;&amp;lt;/div&amp;gt;&amp;lt;div&amp;gt;&amp;lt;div&amp;gt;&amp;lt;span class=&amp;quot;enlighter-text&amp;quot;&amp;gt; &amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;enlighter-c0&amp;quot;&amp;gt;// Tagesverbrauch aktualisieren&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;enlighter-text&amp;quot;&amp;gt;&amp;lt;/span&amp;gt;&amp;lt;/div&amp;gt;&amp;lt;/div&amp;gt;&amp;lt;div&amp;gt;&amp;lt;div&amp;gt;&amp;lt;span class=&amp;quot;enlighter-text&amp;quot;&amp;gt; &amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;enlighter-m0&amp;quot;&amp;gt;aktualisiere_vebrauch_objekt&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;enlighter-g1&amp;quot;&amp;gt;(&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;enlighter-text&amp;quot;&amp;gt;id, &amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;enlighter-s0&amp;quot;&amp;gt;&amp;quot;heute&amp;quot;&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;enlighter-text&amp;quot;&amp;gt;, verbrauch&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;enlighter-g1&amp;quot;&amp;gt;)&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;enlighter-text&amp;quot;&amp;gt;;&amp;lt;/span&amp;gt;&amp;lt;/div&amp;gt;&amp;lt;/div&amp;gt;&amp;lt;div&amp;gt;&amp;lt;div&amp;gt;&amp;lt;br&amp;gt;&amp;lt;/div&amp;gt;&amp;lt;/div&amp;gt;&amp;lt;div&amp;gt;&amp;lt;div&amp;gt;&amp;lt;span class=&amp;quot;enlighter-text&amp;quot;&amp;gt; &amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;enlighter-c0&amp;quot;&amp;gt;// Wochenverbrauch aktualisieren&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;enlighter-text&amp;quot;&amp;gt;&amp;lt;/span&amp;gt;&amp;lt;/div&amp;gt;&amp;lt;/div&amp;gt;&amp;lt;div&amp;gt;&amp;lt;div&amp;gt;&amp;lt;span class=&amp;quot;enlighter-text&amp;quot;&amp;gt; &amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;enlighter-m0&amp;quot;&amp;gt;aktualisiere_vebrauch_objekt&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;enlighter-g1&amp;quot;&amp;gt;(&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;enlighter-text&amp;quot;&amp;gt;id, &amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;enlighter-s0&amp;quot;&amp;gt;&amp;quot;diese_woche&amp;quot;&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;enlighter-text&amp;quot;&amp;gt;, verbrauch&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;enlighter-g1&amp;quot;&amp;gt;)&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;enlighter-text&amp;quot;&amp;gt;;&amp;lt;/span&amp;gt;&amp;lt;/div&amp;gt;&amp;lt;/div&amp;gt;&amp;lt;div&amp;gt;&amp;lt;div&amp;gt;&amp;lt;br&amp;gt;&amp;lt;/div&amp;gt;&amp;lt;/div&amp;gt;&amp;lt;div&amp;gt;&amp;lt;div&amp;gt;&amp;lt;span class=&amp;quot;enlighter-text&amp;quot;&amp;gt; &amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;enlighter-c0&amp;quot;&amp;gt;// Monatsverbrauch aktualisieren&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;enlighter-text&amp;quot;&amp;gt;&amp;lt;/span&amp;gt;&amp;lt;/div&amp;gt;&amp;lt;/div&amp;gt;&amp;lt;div&amp;gt;&amp;lt;div&amp;gt;&amp;lt;span class=&amp;quot;enlighter-text&amp;quot;&amp;gt; &amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;enlighter-m0&amp;quot;&amp;gt;aktualisiere_vebrauch_objekt&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;enlighter-g1&amp;quot;&amp;gt;(&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;enlighter-text&amp;quot;&amp;gt;id, &amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;enlighter-s0&amp;quot;&amp;gt;&amp;quot;dieser_monat&amp;quot;&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;enlighter-text&amp;quot;&amp;gt;, verbrauch&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;enlighter-g1&amp;quot;&amp;gt;)&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;enlighter-text&amp;quot;&amp;gt;;&amp;lt;/span&amp;gt;&amp;lt;/div&amp;gt;&amp;lt;/div&amp;gt;&amp;lt;div&amp;gt;&amp;lt;div&amp;gt;&amp;lt;br&amp;gt;&amp;lt;/div&amp;gt;&amp;lt;/div&amp;gt;&amp;lt;div&amp;gt;&amp;lt;div&amp;gt;&amp;lt;span class=&amp;quot;enlighter-text&amp;quot;&amp;gt; &amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;enlighter-c0&amp;quot;&amp;gt;// Jahresverbrauch aktualisieren&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;enlighter-text&amp;quot;&amp;gt;&amp;lt;/span&amp;gt;&amp;lt;/div&amp;gt;&amp;lt;/div&amp;gt;&amp;lt;div&amp;gt;&amp;lt;div&amp;gt;&amp;lt;span class=&amp;quot;enlighter-text&amp;quot;&amp;gt; &amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;enlighter-m0&amp;quot;&amp;gt;aktualisiere_vebrauch_objekt&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;enlighter-g1&amp;quot;&amp;gt;(&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;enlighter-text&amp;quot;&amp;gt;id, &amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;enlighter-s0&amp;quot;&amp;gt;&amp;quot;dieses_jahr&amp;quot;&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;enlighter-text&amp;quot;&amp;gt;, verbrauch&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;enlighter-g1&amp;quot;&amp;gt;)&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;enlighter-text&amp;quot;&amp;gt;;&amp;lt;/span&amp;gt;&amp;lt;/div&amp;gt;&amp;lt;/div&amp;gt;&amp;lt;div&amp;gt;&amp;lt;div&amp;gt;&amp;lt;br&amp;gt;&amp;lt;/div&amp;gt;&amp;lt;/div&amp;gt;&amp;lt;div&amp;gt;&amp;lt;div&amp;gt;&amp;lt;span class=&amp;quot;enlighter-text&amp;quot;&amp;gt; &amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;enlighter-c0&amp;quot;&amp;gt;// Gesamten Vebrauch aktualisieren&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;enlighter-text&amp;quot;&amp;gt;&amp;lt;/span&amp;gt;&amp;lt;/div&amp;gt;&amp;lt;/div&amp;gt;&amp;lt;div&amp;gt;&amp;lt;div&amp;gt;&amp;lt;span class=&amp;quot;enlighter-text&amp;quot;&amp;gt; &amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;enlighter-m0&amp;quot;&amp;gt;aktualisiere_vebrauch_objekt&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;enlighter-g1&amp;quot;&amp;gt;(&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;enlighter-text&amp;quot;&amp;gt;id, &amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;enlighter-s0&amp;quot;&amp;gt;&amp;quot;gesamt&amp;quot;&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;enlighter-text&amp;quot;&amp;gt;, verbrauch&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;enlighter-g1&amp;quot;&amp;gt;)&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;enlighter-text&amp;quot;&amp;gt;;&amp;lt;/span&amp;gt;&amp;lt;/div&amp;gt;&amp;lt;/div&amp;gt;&amp;lt;div&amp;gt;&amp;lt;div&amp;gt;&amp;lt;span class=&amp;quot;enlighter-text&amp;quot;&amp;gt; &amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;enlighter-g1&amp;quot;&amp;gt;}&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;enlighter-text&amp;quot;&amp;gt;&amp;lt;/span&amp;gt;&amp;lt;/div&amp;gt;&amp;lt;/div&amp;gt;&amp;lt;div&amp;gt;&amp;lt;div&amp;gt;&amp;lt;span class=&amp;quot;enlighter-text&amp;quot;&amp;gt; &amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;enlighter-g1&amp;quot;&amp;gt;}&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;enlighter-g1&amp;quot;&amp;gt;)&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;enlighter-text&amp;quot;&amp;gt;;&amp;lt;/span&amp;gt;&amp;lt;/div&amp;gt;&amp;lt;/div&amp;gt;&amp;lt;div&amp;gt;&amp;lt;div&amp;gt;&amp;lt;span class=&amp;quot;enlighter-text&amp;quot;&amp;gt; &amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;enlighter-m0&amp;quot;&amp;gt;aktualisiere_namen&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;enlighter-g1&amp;quot;&amp;gt;(&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;enlighter-g1&amp;quot;&amp;gt;)&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;enlighter-text&amp;quot;&amp;gt;;&amp;lt;/span&amp;gt;&amp;lt;/div&amp;gt;&amp;lt;/div&amp;gt;&amp;lt;div&amp;gt;&amp;lt;div&amp;gt;&amp;lt;span class=&amp;quot;enlighter-text&amp;quot;&amp;gt; &amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;enlighter-m0&amp;quot;&amp;gt;log&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;enlighter-g1&amp;quot;&amp;gt;(&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;enlighter-s0&amp;quot;&amp;gt;&amp;quot;Tasmota Verbrauch: Verbrauchswerte aktualisiert: &amp;quot;&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;enlighter-text&amp;quot;&amp;gt; + anzahl_updates + &amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;enlighter-s0&amp;quot;&amp;gt;&amp;quot; | Reboots korrigiert: &amp;quot;&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;enlighter-text&amp;quot;&amp;gt; + anzahl_reboots + &amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;enlighter-s0&amp;quot;&amp;gt;&amp;quot; | Unveränderte Werte: &amp;quot;&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;enlighter-text&amp;quot;&amp;gt; + anzahl_gleich&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;enlighter-g1&amp;quot;&amp;gt;)&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;enlighter-text&amp;quot;&amp;gt;;&amp;lt;/span&amp;gt;&amp;lt;/div&amp;gt;&amp;lt;/div&amp;gt;&amp;lt;div&amp;gt;&amp;lt;div&amp;gt;&amp;lt;span class=&amp;quot;enlighter-text&amp;quot;&amp;gt;&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;enlighter-g1&amp;quot;&amp;gt;}&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;enlighter-text&amp;quot;&amp;gt;&amp;lt;/span&amp;gt;&amp;lt;/div&amp;gt;&amp;lt;/div&amp;gt;&amp;lt;div&amp;gt;&amp;lt;div&amp;gt;&amp;lt;br&amp;gt;&amp;lt;/div&amp;gt;&amp;lt;/div&amp;gt;&amp;lt;div&amp;gt;&amp;lt;div&amp;gt;&amp;lt;span class=&amp;quot;enlighter-text&amp;quot;&amp;gt;&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;enlighter-c0&amp;quot;&amp;gt;// aktualisiert das jeweilige Verbrauchs-Objekt und addiert den Verbrauch dazu&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;enlighter-text&amp;quot;&amp;gt;&amp;lt;/span&amp;gt;&amp;lt;/div&amp;gt;&amp;lt;/div&amp;gt;&amp;lt;div&amp;gt;&amp;lt;div&amp;gt;&amp;lt;span class=&amp;quot;enlighter-text&amp;quot;&amp;gt;&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;enlighter-k0&amp;quot;&amp;gt;function&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;enlighter-text&amp;quot;&amp;gt; &amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;enlighter-m0&amp;quot;&amp;gt;aktualisiere_vebrauch_objekt&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;enlighter-g1&amp;quot;&amp;gt;(&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;enlighter-text&amp;quot;&amp;gt;dp, objekt, wert&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;enlighter-g1&amp;quot;&amp;gt;)&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;enlighter-text&amp;quot;&amp;gt; &amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;enlighter-g1&amp;quot;&amp;gt;{&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;enlighter-text&amp;quot;&amp;gt;&amp;lt;/span&amp;gt;&amp;lt;/div&amp;gt;&amp;lt;/div&amp;gt;&amp;lt;div&amp;gt;&amp;lt;div&amp;gt;&amp;lt;span class=&amp;quot;enlighter-text&amp;quot;&amp;gt; &amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;enlighter-k2&amp;quot;&amp;gt;var&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;enlighter-text&amp;quot;&amp;gt; verbrauch = &amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;enlighter-m0&amp;quot;&amp;gt;parseFloat&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;enlighter-g1&amp;quot;&amp;gt;(&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;enlighter-m0&amp;quot;&amp;gt;getState&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;enlighter-g1&amp;quot;&amp;gt;(&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;enlighter-m0&amp;quot;&amp;gt;tasmota_DP&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;enlighter-g1&amp;quot;&amp;gt;(&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;enlighter-text&amp;quot;&amp;gt;dp&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;enlighter-g1&amp;quot;&amp;gt;)&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;enlighter-text&amp;quot;&amp;gt; + objekt&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;enlighter-g1&amp;quot;&amp;gt;)&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;enlighter-text&amp;quot;&amp;gt;.&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;enlighter-m3&amp;quot;&amp;gt;val&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;enlighter-g1&amp;quot;&amp;gt;)&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;enlighter-text&amp;quot;&amp;gt; + &amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;enlighter-m0&amp;quot;&amp;gt;parseFloat&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;enlighter-g1&amp;quot;&amp;gt;(&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;enlighter-text&amp;quot;&amp;gt;wert&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;enlighter-g1&amp;quot;&amp;gt;)&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;enlighter-text&amp;quot;&amp;gt;;&amp;lt;/span&amp;gt;&amp;lt;/div&amp;gt;&amp;lt;/div&amp;gt;&amp;lt;div&amp;gt;&amp;lt;div&amp;gt;&amp;lt;span class=&amp;quot;enlighter-text&amp;quot;&amp;gt; verbrauch = &amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;enlighter-m0&amp;quot;&amp;gt;parseFloat&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;enlighter-g1&amp;quot;&amp;gt;(&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;enlighter-text&amp;quot;&amp;gt;verbrauch.&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;enlighter-m3&amp;quot;&amp;gt;toFixed&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;enlighter-g1&amp;quot;&amp;gt;(&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;enlighter-n1&amp;quot;&amp;gt;3&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;enlighter-g1&amp;quot;&amp;gt;)&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;enlighter-g1&amp;quot;&amp;gt;)&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;enlighter-text&amp;quot;&amp;gt;;&amp;lt;/span&amp;gt;&amp;lt;/div&amp;gt;&amp;lt;/div&amp;gt;&amp;lt;div&amp;gt;&amp;lt;div&amp;gt;&amp;lt;span class=&amp;quot;enlighter-text&amp;quot;&amp;gt; &amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;enlighter-m0&amp;quot;&amp;gt;setState&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;enlighter-g1&amp;quot;&amp;gt;(&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;enlighter-m0&amp;quot;&amp;gt;tasmota_DP&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;enlighter-g1&amp;quot;&amp;gt;(&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;enlighter-text&amp;quot;&amp;gt;dp&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;enlighter-g1&amp;quot;&amp;gt;)&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;enlighter-text&amp;quot;&amp;gt; + objekt, verbrauch,&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;enlighter-e0&amp;quot;&amp;gt;true&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;enlighter-g1&amp;quot;&amp;gt;)&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;enlighter-text&amp;quot;&amp;gt;;&amp;lt;/span&amp;gt;&amp;lt;/div&amp;gt;&amp;lt;/div&amp;gt;&amp;lt;div&amp;gt;&amp;lt;div&amp;gt;&amp;lt;span class=&amp;quot;enlighter-text&amp;quot;&amp;gt;&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;enlighter-g1&amp;quot;&amp;gt;}&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;enlighter-text&amp;quot;&amp;gt;&amp;lt;/span&amp;gt;&amp;lt;/div&amp;gt;&amp;lt;/div&amp;gt;&amp;lt;div&amp;gt;&amp;lt;div&amp;gt;&amp;lt;br&amp;gt;&amp;lt;/div&amp;gt;&amp;lt;/div&amp;gt;&amp;lt;div&amp;gt;&amp;lt;div&amp;gt;&amp;lt;span class=&amp;quot;enlighter-text&amp;quot;&amp;gt;&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;enlighter-c0&amp;quot;&amp;gt;// Verschiebt das jeweilige Verbrauchs-Objekt und nullt den Ursprung (Tag, Woche, Monat, Jahr)&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;enlighter-text&amp;quot;&amp;gt;&amp;lt;/span&amp;gt;&amp;lt;/div&amp;gt;&amp;lt;/div&amp;gt;&amp;lt;div&amp;gt;&amp;lt;div&amp;gt;&amp;lt;span class=&amp;quot;enlighter-text&amp;quot;&amp;gt;&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;enlighter-k0&amp;quot;&amp;gt;function&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;enlighter-text&amp;quot;&amp;gt; &amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;enlighter-m0&amp;quot;&amp;gt;verschiebe_verbrauch_objekt&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;enlighter-g1&amp;quot;&amp;gt;(&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;enlighter-text&amp;quot;&amp;gt;von, nach&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;enlighter-g1&amp;quot;&amp;gt;)&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;enlighter-text&amp;quot;&amp;gt; &amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;enlighter-g1&amp;quot;&amp;gt;{&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;enlighter-text&amp;quot;&amp;gt;&amp;lt;/span&amp;gt;&amp;lt;/div&amp;gt;&amp;lt;/div&amp;gt;&amp;lt;div&amp;gt;&amp;lt;div&amp;gt;&amp;lt;span class=&amp;quot;enlighter-text&amp;quot;&amp;gt; $&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;enlighter-g1&amp;quot;&amp;gt;(&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;enlighter-s0&amp;quot;&amp;gt;'state[id=*.'&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;enlighter-text&amp;quot;&amp;gt; + datenpunkt + &amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;enlighter-s0&amp;quot;&amp;gt;'*.'&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;enlighter-text&amp;quot;&amp;gt; + von + &amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;enlighter-s0&amp;quot;&amp;gt;']'&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;enlighter-g1&amp;quot;&amp;gt;)&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;enlighter-text&amp;quot;&amp;gt;.&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;enlighter-m3&amp;quot;&amp;gt;each&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;enlighter-g1&amp;quot;&amp;gt;(&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;enlighter-k0&amp;quot;&amp;gt;function&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;enlighter-text&amp;quot;&amp;gt; &amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;enlighter-g1&amp;quot;&amp;gt;(&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;enlighter-text&amp;quot;&amp;gt;id, i&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;enlighter-g1&amp;quot;&amp;gt;)&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;enlighter-text&amp;quot;&amp;gt; &amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;enlighter-g1&amp;quot;&amp;gt;{&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;enlighter-text&amp;quot;&amp;gt;&amp;lt;/span&amp;gt;&amp;lt;/div&amp;gt;&amp;lt;/div&amp;gt;&amp;lt;div&amp;gt;&amp;lt;div&amp;gt;&amp;lt;span class=&amp;quot;enlighter-text&amp;quot;&amp;gt; &amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;enlighter-c0&amp;quot;&amp;gt;// Temporärer Gruppen-Datenpunkt&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;enlighter-text&amp;quot;&amp;gt;&amp;lt;/span&amp;gt;&amp;lt;/div&amp;gt;&amp;lt;/div&amp;gt;&amp;lt;div&amp;gt;&amp;lt;div&amp;gt;&amp;lt;span class=&amp;quot;enlighter-text&amp;quot;&amp;gt; &amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;enlighter-k2&amp;quot;&amp;gt;var&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;enlighter-text&amp;quot;&amp;gt; tmp_dp = id.&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;enlighter-m3&amp;quot;&amp;gt;slice&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;enlighter-g1&amp;quot;&amp;gt;(&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;enlighter-n1&amp;quot;&amp;gt;0&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;enlighter-text&amp;quot;&amp;gt;, -&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;enlighter-g1&amp;quot;&amp;gt;(&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;enlighter-text&amp;quot;&amp;gt;von.&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;enlighter-m3&amp;quot;&amp;gt;length&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;enlighter-g1&amp;quot;&amp;gt;)&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;enlighter-g1&amp;quot;&amp;gt;)&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;enlighter-text&amp;quot;&amp;gt;;&amp;lt;/span&amp;gt;&amp;lt;/div&amp;gt;&amp;lt;/div&amp;gt;&amp;lt;div&amp;gt;&amp;lt;div&amp;gt;&amp;lt;span class=&amp;quot;enlighter-text&amp;quot;&amp;gt; &amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;enlighter-k2&amp;quot;&amp;gt;var&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;enlighter-text&amp;quot;&amp;gt; verbrauch = &amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;enlighter-m0&amp;quot;&amp;gt;getState&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;enlighter-g1&amp;quot;&amp;gt;(&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;enlighter-text&amp;quot;&amp;gt;id&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;enlighter-g1&amp;quot;&amp;gt;)&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;enlighter-text&amp;quot;&amp;gt;.&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;enlighter-m3&amp;quot;&amp;gt;val&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;enlighter-text&amp;quot;&amp;gt;;&amp;lt;/span&amp;gt;&amp;lt;/div&amp;gt;&amp;lt;/div&amp;gt;&amp;lt;div&amp;gt;&amp;lt;div&amp;gt;&amp;lt;span class=&amp;quot;enlighter-text&amp;quot;&amp;gt; &amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;enlighter-k1&amp;quot;&amp;gt;if&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;enlighter-text&amp;quot;&amp;gt; &amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;enlighter-g1&amp;quot;&amp;gt;(&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;enlighter-text&amp;quot;&amp;gt;verbrauch != &amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;enlighter-e1&amp;quot;&amp;gt;null&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;enlighter-g1&amp;quot;&amp;gt;)&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;enlighter-text&amp;quot;&amp;gt; &amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;enlighter-g1&amp;quot;&amp;gt;{&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;enlighter-text&amp;quot;&amp;gt;&amp;lt;/span&amp;gt;&amp;lt;/div&amp;gt;&amp;lt;/div&amp;gt;&amp;lt;div&amp;gt;&amp;lt;div&amp;gt;&amp;lt;span class=&amp;quot;enlighter-text&amp;quot;&amp;gt; &amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;enlighter-m0&amp;quot;&amp;gt;setState&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;enlighter-g1&amp;quot;&amp;gt;(&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;enlighter-text&amp;quot;&amp;gt;tmp_dp + nach, verbrauch,&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;enlighter-e0&amp;quot;&amp;gt;true&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;enlighter-g1&amp;quot;&amp;gt;)&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;enlighter-text&amp;quot;&amp;gt;;&amp;lt;/span&amp;gt;&amp;lt;/div&amp;gt;&amp;lt;/div&amp;gt;&amp;lt;div&amp;gt;&amp;lt;div&amp;gt;&amp;lt;span class=&amp;quot;enlighter-text&amp;quot;&amp;gt; &amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;enlighter-g1&amp;quot;&amp;gt;}&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;enlighter-text&amp;quot;&amp;gt;&amp;lt;/span&amp;gt;&amp;lt;/div&amp;gt;&amp;lt;/div&amp;gt;&amp;lt;div&amp;gt;&amp;lt;div&amp;gt;&amp;lt;span class=&amp;quot;enlighter-text&amp;quot;&amp;gt; &amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;enlighter-c0&amp;quot;&amp;gt;// Setze heute zurück&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;enlighter-text&amp;quot;&amp;gt;&amp;lt;/span&amp;gt;&amp;lt;/div&amp;gt;&amp;lt;/div&amp;gt;&amp;lt;div&amp;gt;&amp;lt;div&amp;gt;&amp;lt;span class=&amp;quot;enlighter-text&amp;quot;&amp;gt; &amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;enlighter-m0&amp;quot;&amp;gt;setState&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;enlighter-g1&amp;quot;&amp;gt;(&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;enlighter-text&amp;quot;&amp;gt;id, &amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;enlighter-n1&amp;quot;&amp;gt;0&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;enlighter-text&amp;quot;&amp;gt;,&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;enlighter-e0&amp;quot;&amp;gt;true&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;enlighter-g1&amp;quot;&amp;gt;)&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;enlighter-text&amp;quot;&amp;gt;;&amp;lt;/span&amp;gt;&amp;lt;/div&amp;gt;&amp;lt;/div&amp;gt;&amp;lt;div&amp;gt;&amp;lt;div&amp;gt;&amp;lt;span class=&amp;quot;enlighter-text&amp;quot;&amp;gt; &amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;enlighter-g1&amp;quot;&amp;gt;}&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;enlighter-g1&amp;quot;&amp;gt;)&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;enlighter-text&amp;quot;&amp;gt;;&amp;lt;/span&amp;gt;&amp;lt;/div&amp;gt;&amp;lt;/div&amp;gt;&amp;lt;div&amp;gt;&amp;lt;div&amp;gt;&amp;lt;span class=&amp;quot;enlighter-text&amp;quot;&amp;gt;&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;enlighter-g1&amp;quot;&amp;gt;}&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;enlighter-text&amp;quot;&amp;gt;&amp;lt;/span&amp;gt;&amp;lt;/div&amp;gt;&amp;lt;/div&amp;gt;&amp;lt;div&amp;gt;&amp;lt;div&amp;gt;&amp;lt;br&amp;gt;&amp;lt;/div&amp;gt;&amp;lt;/div&amp;gt;&amp;lt;div&amp;gt;&amp;lt;div&amp;gt;&amp;lt;span class=&amp;quot;enlighter-text&amp;quot;&amp;gt;&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;enlighter-c0&amp;quot;&amp;gt;// Funktion um die aktuellen Namen der Tasmota abzuholen&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;enlighter-text&amp;quot;&amp;gt;&amp;lt;/span&amp;gt;&amp;lt;/div&amp;gt;&amp;lt;/div&amp;gt;&amp;lt;div&amp;gt;&amp;lt;div&amp;gt;&amp;lt;span class=&amp;quot;enlighter-text&amp;quot;&amp;gt;&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;enlighter-k0&amp;quot;&amp;gt;function&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;enlighter-text&amp;quot;&amp;gt; &amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;enlighter-m0&amp;quot;&amp;gt;aktualisiere_namen&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;enlighter-g1&amp;quot;&amp;gt;(&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;enlighter-g1&amp;quot;&amp;gt;)&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;enlighter-text&amp;quot;&amp;gt; &amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;enlighter-g1&amp;quot;&amp;gt;{&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;enlighter-text&amp;quot;&amp;gt;&amp;lt;/span&amp;gt;&amp;lt;/div&amp;gt;&amp;lt;/div&amp;gt;&amp;lt;div&amp;gt;&amp;lt;div&amp;gt;&amp;lt;span class=&amp;quot;enlighter-text&amp;quot;&amp;gt; tasmotaDpsName.&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;enlighter-m3&amp;quot;&amp;gt;each&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;enlighter-g1&amp;quot;&amp;gt;(&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;enlighter-k0&amp;quot;&amp;gt;function&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;enlighter-text&amp;quot;&amp;gt; &amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;enlighter-g1&amp;quot;&amp;gt;(&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;enlighter-text&amp;quot;&amp;gt;id, i&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;enlighter-g1&amp;quot;&amp;gt;)&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;enlighter-text&amp;quot;&amp;gt; &amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;enlighter-g1&amp;quot;&amp;gt;{&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;enlighter-text&amp;quot;&amp;gt;&amp;lt;/span&amp;gt;&amp;lt;/div&amp;gt;&amp;lt;/div&amp;gt;&amp;lt;div&amp;gt;&amp;lt;div&amp;gt;&amp;lt;span class=&amp;quot;enlighter-text&amp;quot;&amp;gt; &amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;enlighter-m0&amp;quot;&amp;gt;setState&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;enlighter-g1&amp;quot;&amp;gt;(&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;enlighter-m0&amp;quot;&amp;gt;tasmota_DP_Name&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;enlighter-g1&amp;quot;&amp;gt;(&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;enlighter-text&amp;quot;&amp;gt;id&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;enlighter-g1&amp;quot;&amp;gt;)&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;enlighter-text&amp;quot;&amp;gt;,&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;enlighter-m0&amp;quot;&amp;gt;String&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;enlighter-g1&amp;quot;&amp;gt;(&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;enlighter-m0&amp;quot;&amp;gt;getState&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;enlighter-g1&amp;quot;&amp;gt;(&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;enlighter-text&amp;quot;&amp;gt;id&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;enlighter-g1&amp;quot;&amp;gt;)&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;enlighter-text&amp;quot;&amp;gt;.&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;enlighter-m3&amp;quot;&amp;gt;val&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;enlighter-g1&amp;quot;&amp;gt;)&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;enlighter-text&amp;quot;&amp;gt;,&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;enlighter-e0&amp;quot;&amp;gt;true&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;enlighter-g1&amp;quot;&amp;gt;)&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;enlighter-text&amp;quot;&amp;gt;;&amp;lt;/span&amp;gt;&amp;lt;/div&amp;gt;&amp;lt;/div&amp;gt;&amp;lt;div&amp;gt;&amp;lt;div&amp;gt;&amp;lt;span class=&amp;quot;enlighter-text&amp;quot;&amp;gt; &amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;enlighter-g1&amp;quot;&amp;gt;}&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;enlighter-g1&amp;quot;&amp;gt;)&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;enlighter-text&amp;quot;&amp;gt;;&amp;lt;/span&amp;gt;&amp;lt;/div&amp;gt;&amp;lt;/div&amp;gt;&amp;lt;div&amp;gt;&amp;lt;div&amp;gt;&amp;lt;span class=&amp;quot;enlighter-text&amp;quot;&amp;gt;&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;enlighter-g1&amp;quot;&amp;gt;}&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;enlighter-text&amp;quot;&amp;gt;&amp;lt;/span&amp;gt;&amp;lt;/div&amp;gt;&amp;lt;/div&amp;gt;&amp;lt;div&amp;gt;&amp;lt;div&amp;gt;&amp;lt;br&amp;gt;&amp;lt;/div&amp;gt;&amp;lt;/div&amp;gt;&amp;lt;div&amp;gt;&amp;lt;div&amp;gt;&amp;lt;span class=&amp;quot;enlighter-text&amp;quot;&amp;gt;&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;enlighter-c0&amp;quot;&amp;gt;// Erstelle die benötigten Datenpunkte&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;enlighter-text&amp;quot;&amp;gt;&amp;lt;/span&amp;gt;&amp;lt;/div&amp;gt;&amp;lt;/div&amp;gt;&amp;lt;div&amp;gt;&amp;lt;div&amp;gt;&amp;lt;span class=&amp;quot;enlighter-text&amp;quot;&amp;gt;&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;enlighter-k0&amp;quot;&amp;gt;function&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;enlighter-text&amp;quot;&amp;gt; &amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;enlighter-m0&amp;quot;&amp;gt;datenpunkte_erstellen&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;enlighter-g1&amp;quot;&amp;gt;(&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;enlighter-g1&amp;quot;&amp;gt;)&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;enlighter-text&amp;quot;&amp;gt; &amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;enlighter-g1&amp;quot;&amp;gt;{&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;enlighter-text&amp;quot;&amp;gt;&amp;lt;/span&amp;gt;&amp;lt;/div&amp;gt;&amp;lt;/div&amp;gt;&amp;lt;div&amp;gt;&amp;lt;div&amp;gt;&amp;lt;span class=&amp;quot;enlighter-text&amp;quot;&amp;gt; &amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;enlighter-c0&amp;quot;&amp;gt;// Anzahl der gefundenen Tasmota&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;enlighter-text&amp;quot;&amp;gt;&amp;lt;/span&amp;gt;&amp;lt;/div&amp;gt;&amp;lt;/div&amp;gt;&amp;lt;div&amp;gt;&amp;lt;div&amp;gt;&amp;lt;span class=&amp;quot;enlighter-text&amp;quot;&amp;gt; &amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;enlighter-k2&amp;quot;&amp;gt;var&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;enlighter-text&amp;quot;&amp;gt; anzahl = tasmotaDps.&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;enlighter-m3&amp;quot;&amp;gt;length&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;enlighter-text&amp;quot;&amp;gt;;&amp;lt;/span&amp;gt;&amp;lt;/div&amp;gt;&amp;lt;/div&amp;gt;&amp;lt;div&amp;gt;&amp;lt;div&amp;gt;&amp;lt;br&amp;gt;&amp;lt;/div&amp;gt;&amp;lt;/div&amp;gt;&amp;lt;div&amp;gt;&amp;lt;div&amp;gt;&amp;lt;span class=&amp;quot;enlighter-text&amp;quot;&amp;gt; tasmotaDps.&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;enlighter-m3&amp;quot;&amp;gt;each&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;enlighter-g1&amp;quot;&amp;gt;(&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;enlighter-k0&amp;quot;&amp;gt;function&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;enlighter-text&amp;quot;&amp;gt; &amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;enlighter-g1&amp;quot;&amp;gt;(&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;enlighter-text&amp;quot;&amp;gt;id, j&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;enlighter-g1&amp;quot;&amp;gt;)&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;enlighter-text&amp;quot;&amp;gt; &amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;enlighter-g1&amp;quot;&amp;gt;{&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;enlighter-text&amp;quot;&amp;gt;&amp;lt;/span&amp;gt;&amp;lt;/div&amp;gt;&amp;lt;/div&amp;gt;&amp;lt;div&amp;gt;&amp;lt;div&amp;gt;&amp;lt;span class=&amp;quot;enlighter-text&amp;quot;&amp;gt; &amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;enlighter-k2&amp;quot;&amp;gt;var&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;enlighter-text&amp;quot;&amp;gt; initial_wert = &amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;enlighter-n1&amp;quot;&amp;gt;0&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;enlighter-text&amp;quot;&amp;gt;;&amp;lt;/span&amp;gt;&amp;lt;/div&amp;gt;&amp;lt;/div&amp;gt;&amp;lt;div&amp;gt;&amp;lt;div&amp;gt;&amp;lt;span class=&amp;quot;enlighter-text&amp;quot;&amp;gt; &amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;enlighter-k1&amp;quot;&amp;gt;for&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;enlighter-text&amp;quot;&amp;gt; &amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;enlighter-g1&amp;quot;&amp;gt;(&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;enlighter-k2&amp;quot;&amp;gt;var&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;enlighter-text&amp;quot;&amp;gt; i = &amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;enlighter-n1&amp;quot;&amp;gt;0&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;enlighter-text&amp;quot;&amp;gt;; &amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;enlighter-m0&amp;quot;&amp;gt;i&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;enlighter-text&amp;quot;&amp;gt; &amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;enlighter-g1&amp;quot;&amp;gt;&amp;amp;lt;&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;enlighter-text&amp;quot;&amp;gt; objekt.&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;enlighter-m3&amp;quot;&amp;gt;length&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;enlighter-text&amp;quot;&amp;gt;; i++&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;enlighter-g1&amp;quot;&amp;gt;)&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;enlighter-text&amp;quot;&amp;gt; &amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;enlighter-g1&amp;quot;&amp;gt;{&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;enlighter-text&amp;quot;&amp;gt;&amp;lt;/span&amp;gt;&amp;lt;/div&amp;gt;&amp;lt;/div&amp;gt;&amp;lt;div&amp;gt;&amp;lt;div&amp;gt;&amp;lt;span class=&amp;quot;enlighter-text&amp;quot;&amp;gt; &amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;enlighter-c0&amp;quot;&amp;gt;// Startwerte werden nur bei alter_wert und aktueller_wert eingetragen&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;enlighter-text&amp;quot;&amp;gt;&amp;lt;/span&amp;gt;&amp;lt;/div&amp;gt;&amp;lt;/div&amp;gt;&amp;lt;div&amp;gt;&amp;lt;div&amp;gt;&amp;lt;span class=&amp;quot;enlighter-text&amp;quot;&amp;gt; &amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;enlighter-k1&amp;quot;&amp;gt;if&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;enlighter-text&amp;quot;&amp;gt; &amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;enlighter-g1&amp;quot;&amp;gt;(&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;enlighter-text&amp;quot;&amp;gt;i &amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;enlighter-g1&amp;quot;&amp;gt;&amp;amp;gt;&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;enlighter-text&amp;quot;&amp;gt; &amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;enlighter-n1&amp;quot;&amp;gt;8&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;enlighter-g1&amp;quot;&amp;gt;)&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;enlighter-text&amp;quot;&amp;gt; &amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;enlighter-g1&amp;quot;&amp;gt;{&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;enlighter-text&amp;quot;&amp;gt;&amp;lt;/span&amp;gt;&amp;lt;/div&amp;gt;&amp;lt;/div&amp;gt;&amp;lt;div&amp;gt;&amp;lt;div&amp;gt;&amp;lt;span class=&amp;quot;enlighter-text&amp;quot;&amp;gt; initial_wert = &amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;enlighter-m0&amp;quot;&amp;gt;getState&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;enlighter-g1&amp;quot;&amp;gt;(&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;enlighter-text&amp;quot;&amp;gt;id&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;enlighter-g1&amp;quot;&amp;gt;)&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;enlighter-text&amp;quot;&amp;gt;.&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;enlighter-m3&amp;quot;&amp;gt;val&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;enlighter-text&amp;quot;&amp;gt;;&amp;lt;/span&amp;gt;&amp;lt;/div&amp;gt;&amp;lt;/div&amp;gt;&amp;lt;div&amp;gt;&amp;lt;div&amp;gt;&amp;lt;span class=&amp;quot;enlighter-text&amp;quot;&amp;gt; &amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;enlighter-g1&amp;quot;&amp;gt;}&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;enlighter-text&amp;quot;&amp;gt;&amp;lt;/span&amp;gt;&amp;lt;/div&amp;gt;&amp;lt;/div&amp;gt;&amp;lt;div&amp;gt;&amp;lt;div&amp;gt;&amp;lt;span class=&amp;quot;enlighter-text&amp;quot;&amp;gt; &amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;enlighter-m0&amp;quot;&amp;gt;createState&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;enlighter-g1&amp;quot;&amp;gt;(&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;enlighter-m0&amp;quot;&amp;gt;tasmota_DP&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;enlighter-g1&amp;quot;&amp;gt;(&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;enlighter-text&amp;quot;&amp;gt;id&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;enlighter-g1&amp;quot;&amp;gt;)&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;enlighter-text&amp;quot;&amp;gt; + objekt&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;enlighter-g1&amp;quot;&amp;gt;[&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;enlighter-text&amp;quot;&amp;gt;i&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;enlighter-g1&amp;quot;&amp;gt;]&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;enlighter-text&amp;quot;&amp;gt;, initial_wert, ueberschreiben, &amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;enlighter-g1&amp;quot;&amp;gt;{&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;enlighter-text&amp;quot;&amp;gt;&amp;lt;/span&amp;gt;&amp;lt;/div&amp;gt;&amp;lt;/div&amp;gt;&amp;lt;div&amp;gt;&amp;lt;div&amp;gt;&amp;lt;span class=&amp;quot;enlighter-text&amp;quot;&amp;gt; name: beschreibung&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;enlighter-g1&amp;quot;&amp;gt;[&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;enlighter-text&amp;quot;&amp;gt;i&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;enlighter-g1&amp;quot;&amp;gt;]&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;enlighter-text&amp;quot;&amp;gt;,&amp;lt;/span&amp;gt;&amp;lt;/div&amp;gt;&amp;lt;/div&amp;gt;&amp;lt;div&amp;gt;&amp;lt;div&amp;gt;&amp;lt;span class=&amp;quot;enlighter-text&amp;quot;&amp;gt; desc: beschreibung&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;enlighter-g1&amp;quot;&amp;gt;[&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;enlighter-text&amp;quot;&amp;gt;i&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;enlighter-g1&amp;quot;&amp;gt;]&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;enlighter-text&amp;quot;&amp;gt;,&amp;lt;/span&amp;gt;&amp;lt;/div&amp;gt;&amp;lt;/div&amp;gt;&amp;lt;div&amp;gt;&amp;lt;div&amp;gt;&amp;lt;span class=&amp;quot;enlighter-text&amp;quot;&amp;gt; &amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;enlighter-k2&amp;quot;&amp;gt;type&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;enlighter-text&amp;quot;&amp;gt;: &amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;enlighter-s0&amp;quot;&amp;gt;&amp;quot;number&amp;quot;&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;enlighter-text&amp;quot;&amp;gt;,&amp;lt;/span&amp;gt;&amp;lt;/div&amp;gt;&amp;lt;/div&amp;gt;&amp;lt;div&amp;gt;&amp;lt;div&amp;gt;&amp;lt;span class=&amp;quot;enlighter-text&amp;quot;&amp;gt; role: &amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;enlighter-s0&amp;quot;&amp;gt;&amp;quot;value.power&amp;quot;&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;enlighter-text&amp;quot;&amp;gt;,&amp;lt;/span&amp;gt;&amp;lt;/div&amp;gt;&amp;lt;/div&amp;gt;&amp;lt;div&amp;gt;&amp;lt;div&amp;gt;&amp;lt;span class=&amp;quot;enlighter-text&amp;quot;&amp;gt; unit: &amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;enlighter-s0&amp;quot;&amp;gt;&amp;quot;kWh&amp;quot;&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;enlighter-text&amp;quot;&amp;gt;&amp;lt;/span&amp;gt;&amp;lt;/div&amp;gt;&amp;lt;/div&amp;gt;&amp;lt;div&amp;gt;&amp;lt;div&amp;gt;&amp;lt;span class=&amp;quot;enlighter-text&amp;quot;&amp;gt; &amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;enlighter-g1&amp;quot;&amp;gt;}&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;enlighter-g1&amp;quot;&amp;gt;)&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;enlighter-text&amp;quot;&amp;gt;;&amp;lt;/span&amp;gt;&amp;lt;/div&amp;gt;&amp;lt;/div&amp;gt;&amp;lt;div&amp;gt;&amp;lt;div&amp;gt;&amp;lt;span class=&amp;quot;enlighter-text&amp;quot;&amp;gt; &amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;enlighter-g1&amp;quot;&amp;gt;}&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;enlighter-text&amp;quot;&amp;gt;&amp;lt;/span&amp;gt;&amp;lt;/div&amp;gt;&amp;lt;/div&amp;gt;&amp;lt;div&amp;gt;&amp;lt;div&amp;gt;&amp;lt;span class=&amp;quot;enlighter-text&amp;quot;&amp;gt; &amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;enlighter-g1&amp;quot;&amp;gt;}&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;enlighter-g1&amp;quot;&amp;gt;)&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;enlighter-text&amp;quot;&amp;gt;;&amp;lt;/span&amp;gt;&amp;lt;/div&amp;gt;&amp;lt;/div&amp;gt;&amp;lt;div&amp;gt;&amp;lt;div&amp;gt;&amp;lt;br&amp;gt;&amp;lt;/div&amp;gt;&amp;lt;/div&amp;gt;&amp;lt;div&amp;gt;&amp;lt;div&amp;gt;&amp;lt;span class=&amp;quot;enlighter-text&amp;quot;&amp;gt; &amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;enlighter-c0&amp;quot;&amp;gt;// Alle Datenpunkte erstellt. Frage ersten Verbrauch ab!&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;enlighter-text&amp;quot;&amp;gt;&amp;lt;/span&amp;gt;&amp;lt;/div&amp;gt;&amp;lt;/div&amp;gt;&amp;lt;div&amp;gt;&amp;lt;div&amp;gt;&amp;lt;span class=&amp;quot;enlighter-text&amp;quot;&amp;gt; &amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;enlighter-m0&amp;quot;&amp;gt;log&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;enlighter-g1&amp;quot;&amp;gt;(&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;enlighter-s0&amp;quot;&amp;gt;&amp;quot;Tasmota Verbrauch: Datenpunkte erstellt! Erster Verbrauch steht nach 1 Minute zur Verfügung! Anzahl gefundener Tasmota Datenpunkte: &amp;quot;&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;enlighter-text&amp;quot;&amp;gt; + anzahl&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;enlighter-g1&amp;quot;&amp;gt;)&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;enlighter-text&amp;quot;&amp;gt;;&amp;lt;/span&amp;gt;&amp;lt;/div&amp;gt;&amp;lt;/div&amp;gt;&amp;lt;div&amp;gt;&amp;lt;div&amp;gt;&amp;lt;span class=&amp;quot;enlighter-text&amp;quot;&amp;gt; &amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;enlighter-m0&amp;quot;&amp;gt;setTimeout&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;enlighter-g1&amp;quot;&amp;gt;(&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;enlighter-text&amp;quot;&amp;gt;tasmota_verbrauch_update, &amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;enlighter-n1&amp;quot;&amp;gt;20000&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;enlighter-g1&amp;quot;&amp;gt;)&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;enlighter-text&amp;quot;&amp;gt;;&amp;lt;/span&amp;gt;&amp;lt;/div&amp;gt;&amp;lt;/div&amp;gt;&amp;lt;div&amp;gt;&amp;lt;div&amp;gt;&amp;lt;br&amp;gt;&amp;lt;/div&amp;gt;&amp;lt;/div&amp;gt;&amp;lt;div&amp;gt;&amp;lt;div&amp;gt;&amp;lt;span class=&amp;quot;enlighter-text&amp;quot;&amp;gt; &amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;enlighter-c0&amp;quot;&amp;gt;// Datenpunkte für die Namen der Tasmota erstellen&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;enlighter-text&amp;quot;&amp;gt;&amp;lt;/span&amp;gt;&amp;lt;/div&amp;gt;&amp;lt;/div&amp;gt;&amp;lt;div&amp;gt;&amp;lt;div&amp;gt;&amp;lt;span class=&amp;quot;enlighter-text&amp;quot;&amp;gt; tasmotaDpsName.&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;enlighter-m3&amp;quot;&amp;gt;each&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;enlighter-g1&amp;quot;&amp;gt;(&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;enlighter-k0&amp;quot;&amp;gt;function&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;enlighter-g1&amp;quot;&amp;gt;(&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;enlighter-text&amp;quot;&amp;gt;id, j&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;enlighter-g1&amp;quot;&amp;gt;)&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;enlighter-text&amp;quot;&amp;gt; &amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;enlighter-g1&amp;quot;&amp;gt;{&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;enlighter-text&amp;quot;&amp;gt;&amp;lt;/span&amp;gt;&amp;lt;/div&amp;gt;&amp;lt;/div&amp;gt;&amp;lt;div&amp;gt;&amp;lt;div&amp;gt;&amp;lt;span class=&amp;quot;enlighter-text&amp;quot;&amp;gt; &amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;enlighter-m0&amp;quot;&amp;gt;createState&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;enlighter-g1&amp;quot;&amp;gt;(&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;enlighter-m0&amp;quot;&amp;gt;tasmota_DP_Name&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;enlighter-g1&amp;quot;&amp;gt;(&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;enlighter-text&amp;quot;&amp;gt;id&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;enlighter-g1&amp;quot;&amp;gt;)&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;enlighter-text&amp;quot;&amp;gt;, &amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;enlighter-s0&amp;quot;&amp;gt;&amp;quot;&amp;quot;&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;enlighter-text&amp;quot;&amp;gt;, ueberschreiben, &amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;enlighter-g1&amp;quot;&amp;gt;{&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;enlighter-text&amp;quot;&amp;gt;&amp;lt;/span&amp;gt;&amp;lt;/div&amp;gt;&amp;lt;/div&amp;gt;&amp;lt;div&amp;gt;&amp;lt;div&amp;gt;&amp;lt;span class=&amp;quot;enlighter-text&amp;quot;&amp;gt; name: &amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;enlighter-s0&amp;quot;&amp;gt;&amp;quot;Name des Tasmota&amp;quot;&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;enlighter-text&amp;quot;&amp;gt;,&amp;lt;/span&amp;gt;&amp;lt;/div&amp;gt;&amp;lt;/div&amp;gt;&amp;lt;div&amp;gt;&amp;lt;div&amp;gt;&amp;lt;span class=&amp;quot;enlighter-text&amp;quot;&amp;gt; desc: &amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;enlighter-s0&amp;quot;&amp;gt;&amp;quot;Name des Tasmota&amp;quot;&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;enlighter-text&amp;quot;&amp;gt;,&amp;lt;/span&amp;gt;&amp;lt;/div&amp;gt;&amp;lt;/div&amp;gt;&amp;lt;div&amp;gt;&amp;lt;div&amp;gt;&amp;lt;span class=&amp;quot;enlighter-text&amp;quot;&amp;gt; &amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;enlighter-k2&amp;quot;&amp;gt;type&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;enlighter-text&amp;quot;&amp;gt;: &amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;enlighter-s0&amp;quot;&amp;gt;&amp;quot;string&amp;quot;&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;enlighter-text&amp;quot;&amp;gt;,&amp;lt;/span&amp;gt;&amp;lt;/div&amp;gt;&amp;lt;/div&amp;gt;&amp;lt;div&amp;gt;&amp;lt;div&amp;gt;&amp;lt;span class=&amp;quot;enlighter-text&amp;quot;&amp;gt; role: &amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;enlighter-s0&amp;quot;&amp;gt;&amp;quot;value&amp;quot;&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;enlighter-text&amp;quot;&amp;gt;,&amp;lt;/span&amp;gt;&amp;lt;/div&amp;gt;&amp;lt;/div&amp;gt;&amp;lt;div&amp;gt;&amp;lt;div&amp;gt;&amp;lt;span class=&amp;quot;enlighter-text&amp;quot;&amp;gt; unit: &amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;enlighter-s0&amp;quot;&amp;gt;&amp;quot;&amp;quot;&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;enlighter-text&amp;quot;&amp;gt;&amp;lt;/span&amp;gt;&amp;lt;/div&amp;gt;&amp;lt;/div&amp;gt;&amp;lt;div&amp;gt;&amp;lt;div&amp;gt;&amp;lt;span class=&amp;quot;enlighter-text&amp;quot;&amp;gt; &amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;enlighter-g1&amp;quot;&amp;gt;}&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;enlighter-g1&amp;quot;&amp;gt;)&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;enlighter-text&amp;quot;&amp;gt;;&amp;lt;/span&amp;gt;&amp;lt;/div&amp;gt;&amp;lt;/div&amp;gt;&amp;lt;div&amp;gt;&amp;lt;div&amp;gt;&amp;lt;span class=&amp;quot;enlighter-text&amp;quot;&amp;gt; &amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;enlighter-g1&amp;quot;&amp;gt;}&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;enlighter-g1&amp;quot;&amp;gt;)&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;enlighter-text&amp;quot;&amp;gt;;&amp;lt;/span&amp;gt;&amp;lt;/div&amp;gt;&amp;lt;/div&amp;gt;&amp;lt;div&amp;gt;&amp;lt;div&amp;gt;&amp;lt;span class=&amp;quot;enlighter-text&amp;quot;&amp;gt;&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;enlighter-g1&amp;quot;&amp;gt;}&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;enlighter-text&amp;quot;&amp;gt;&amp;lt;/span&amp;gt;&amp;lt;/div&amp;gt;&amp;lt;/div&amp;gt;&amp;lt;div&amp;gt;&amp;lt;div&amp;gt;&amp;lt;br&amp;gt;&amp;lt;/div&amp;gt;&amp;lt;/div&amp;gt;&amp;lt;div&amp;gt;&amp;lt;div&amp;gt;&amp;lt;span class=&amp;quot;enlighter-text&amp;quot;&amp;gt;&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;enlighter-k0&amp;quot;&amp;gt;function&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;enlighter-text&amp;quot;&amp;gt; &amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;enlighter-m0&amp;quot;&amp;gt;tasmota_DP&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;enlighter-g1&amp;quot;&amp;gt;(&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;enlighter-text&amp;quot;&amp;gt;dp&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;enlighter-g1&amp;quot;&amp;gt;)&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;enlighter-text&amp;quot;&amp;gt; &amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;enlighter-g1&amp;quot;&amp;gt;{&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;enlighter-text&amp;quot;&amp;gt;&amp;lt;/span&amp;gt;&amp;lt;/div&amp;gt;&amp;lt;/div&amp;gt;&amp;lt;div&amp;gt;&amp;lt;div&amp;gt;&amp;lt;span class=&amp;quot;enlighter-text&amp;quot;&amp;gt; dp = dp.&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;enlighter-m3&amp;quot;&amp;gt;split&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;enlighter-g1&amp;quot;&amp;gt;(&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;enlighter-s0&amp;quot;&amp;gt;&amp;quot;.&amp;quot;&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;enlighter-g1&amp;quot;&amp;gt;)&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;enlighter-text&amp;quot;&amp;gt;;&amp;lt;/span&amp;gt;&amp;lt;/div&amp;gt;&amp;lt;/div&amp;gt;&amp;lt;div&amp;gt;&amp;lt;div&amp;gt;&amp;lt;span class=&amp;quot;enlighter-text&amp;quot;&amp;gt; dp = datenpunkt + dp&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;enlighter-g1&amp;quot;&amp;gt;[&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;enlighter-n1&amp;quot;&amp;gt;2&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;enlighter-g1&amp;quot;&amp;gt;]&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;enlighter-text&amp;quot;&amp;gt; + &amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;enlighter-s0&amp;quot;&amp;gt;&amp;quot;.&amp;quot;&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;enlighter-text&amp;quot;&amp;gt;;&amp;lt;/span&amp;gt;&amp;lt;/div&amp;gt;&amp;lt;/div&amp;gt;&amp;lt;div&amp;gt;&amp;lt;div&amp;gt;&amp;lt;span class=&amp;quot;enlighter-text&amp;quot;&amp;gt; &amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;enlighter-k0&amp;quot;&amp;gt;return&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;enlighter-text&amp;quot;&amp;gt; dp;&amp;lt;/span&amp;gt;&amp;lt;/div&amp;gt;&amp;lt;/div&amp;gt;&amp;lt;div&amp;gt;&amp;lt;div&amp;gt;&amp;lt;span class=&amp;quot;enlighter-text&amp;quot;&amp;gt;&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;enlighter-g1&amp;quot;&amp;gt;}&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;enlighter-text&amp;quot;&amp;gt;&amp;lt;/span&amp;gt;&amp;lt;/div&amp;gt;&amp;lt;/div&amp;gt;&amp;lt;div&amp;gt;&amp;lt;div&amp;gt;&amp;lt;br&amp;gt;&amp;lt;/div&amp;gt;&amp;lt;/div&amp;gt;&amp;lt;div&amp;gt;&amp;lt;div&amp;gt;&amp;lt;span class=&amp;quot;enlighter-text&amp;quot;&amp;gt;&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;enlighter-k0&amp;quot;&amp;gt;function&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;enlighter-text&amp;quot;&amp;gt; &amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;enlighter-m0&amp;quot;&amp;gt;tasmota_DP_Name&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;enlighter-g1&amp;quot;&amp;gt;(&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;enlighter-text&amp;quot;&amp;gt;dp&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;enlighter-g1&amp;quot;&amp;gt;)&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;enlighter-text&amp;quot;&amp;gt; &amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;enlighter-g1&amp;quot;&amp;gt;{&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;enlighter-text&amp;quot;&amp;gt;&amp;lt;/span&amp;gt;&amp;lt;/div&amp;gt;&amp;lt;/div&amp;gt;&amp;lt;div&amp;gt;&amp;lt;div&amp;gt;&amp;lt;span class=&amp;quot;enlighter-text&amp;quot;&amp;gt; dp = dp.&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;enlighter-m3&amp;quot;&amp;gt;split&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;enlighter-g1&amp;quot;&amp;gt;(&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;enlighter-s0&amp;quot;&amp;gt;&amp;quot;.&amp;quot;&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;enlighter-g1&amp;quot;&amp;gt;)&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;enlighter-text&amp;quot;&amp;gt;;&amp;lt;/span&amp;gt;&amp;lt;/div&amp;gt;&amp;lt;/div&amp;gt;&amp;lt;div&amp;gt;&amp;lt;div&amp;gt;&amp;lt;span class=&amp;quot;enlighter-text&amp;quot;&amp;gt; dp = datenpunkt + dp&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;enlighter-g1&amp;quot;&amp;gt;[&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;enlighter-n1&amp;quot;&amp;gt;2&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;enlighter-g1&amp;quot;&amp;gt;]&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;enlighter-text&amp;quot;&amp;gt; + &amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;enlighter-s0&amp;quot;&amp;gt;&amp;quot;.&amp;quot;&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;enlighter-text&amp;quot;&amp;gt; + dp&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;enlighter-g1&amp;quot;&amp;gt;[&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;enlighter-n1&amp;quot;&amp;gt;3&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;enlighter-g1&amp;quot;&amp;gt;]&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;enlighter-text&amp;quot;&amp;gt;;&amp;lt;/span&amp;gt;&amp;lt;/div&amp;gt;&amp;lt;/div&amp;gt;&amp;lt;div&amp;gt;&amp;lt;div&amp;gt;&amp;lt;span class=&amp;quot;enlighter-text&amp;quot;&amp;gt; &amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;enlighter-k0&amp;quot;&amp;gt;return&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;enlighter-text&amp;quot;&amp;gt; dp;&amp;lt;/span&amp;gt;&amp;lt;/div&amp;gt;&amp;lt;/div&amp;gt;&amp;lt;div&amp;gt;&amp;lt;div&amp;gt;&amp;lt;span class=&amp;quot;enlighter-text&amp;quot;&amp;gt;&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;enlighter-g1&amp;quot;&amp;gt;}&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;enlighter-text&amp;quot;&amp;gt;&amp;lt;/span&amp;gt;&amp;lt;/div&amp;gt;&amp;lt;/div&amp;gt;&amp;lt;div&amp;gt;&amp;lt;div&amp;gt;&amp;lt;br&amp;gt;&amp;lt;/div&amp;gt;&amp;lt;/div&amp;gt;&amp;lt;div&amp;gt;&amp;lt;div&amp;gt;&amp;lt;span class=&amp;quot;enlighter-text&amp;quot;&amp;gt;&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;enlighter-k0&amp;quot;&amp;gt;function&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;enlighter-text&amp;quot;&amp;gt; &amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;enlighter-m0&amp;quot;&amp;gt;tasmota_verbrauch_erster_start&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;enlighter-g1&amp;quot;&amp;gt;(&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;enlighter-g1&amp;quot;&amp;gt;)&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;enlighter-text&amp;quot;&amp;gt; &amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;enlighter-g1&amp;quot;&amp;gt;{&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;enlighter-text&amp;quot;&amp;gt;&amp;lt;/span&amp;gt;&amp;lt;/div&amp;gt;&amp;lt;/div&amp;gt;&amp;lt;div&amp;gt;&amp;lt;div&amp;gt;&amp;lt;span class=&amp;quot;enlighter-text&amp;quot;&amp;gt; &amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;enlighter-m0&amp;quot;&amp;gt;log&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;enlighter-g1&amp;quot;&amp;gt;(&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;enlighter-s0&amp;quot;&amp;gt;&amp;quot;Tasmota Verbrauch: Erster Start des Skriptes! Datenpunkte werden erstellt!&amp;quot;&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;enlighter-g1&amp;quot;&amp;gt;)&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;enlighter-text&amp;quot;&amp;gt;;&amp;lt;/span&amp;gt;&amp;lt;/div&amp;gt;&amp;lt;/div&amp;gt;&amp;lt;div&amp;gt;&amp;lt;div&amp;gt;&amp;lt;span class=&amp;quot;enlighter-text&amp;quot;&amp;gt; &amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;enlighter-c0&amp;quot;&amp;gt;// Datenpunkte werden erstellt&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;enlighter-text&amp;quot;&amp;gt;&amp;lt;/span&amp;gt;&amp;lt;/div&amp;gt;&amp;lt;/div&amp;gt;&amp;lt;div&amp;gt;&amp;lt;div&amp;gt;&amp;lt;span class=&amp;quot;enlighter-text&amp;quot;&amp;gt; &amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;enlighter-m0&amp;quot;&amp;gt;datenpunkte_erstellen&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;enlighter-g1&amp;quot;&amp;gt;(&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;enlighter-g1&amp;quot;&amp;gt;)&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;enlighter-text&amp;quot;&amp;gt;;&amp;lt;/span&amp;gt;&amp;lt;/div&amp;gt;&amp;lt;/div&amp;gt;&amp;lt;div&amp;gt;&amp;lt;div&amp;gt;&amp;lt;span class=&amp;quot;enlighter-text&amp;quot;&amp;gt;&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;enlighter-g1&amp;quot;&amp;gt;}&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;enlighter-text&amp;quot;&amp;gt;&amp;lt;/span&amp;gt;&amp;lt;/div&amp;gt;&amp;lt;/div&amp;gt;&amp;lt;div&amp;gt;&amp;lt;div&amp;gt;&amp;lt;br&amp;gt;&amp;lt;/div&amp;gt;&amp;lt;/div&amp;gt;&amp;lt;div&amp;gt;&amp;lt;div&amp;gt;&amp;lt;span class=&amp;quot;enlighter-text&amp;quot;&amp;gt;&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;enlighter-c0&amp;quot;&amp;gt;// Erster Start und Initialisierung&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;enlighter-text&amp;quot;&amp;gt;&amp;lt;/span&amp;gt;&amp;lt;/div&amp;gt;&amp;lt;/div&amp;gt;&amp;lt;div&amp;gt;&amp;lt;div&amp;gt;&amp;lt;span class=&amp;quot;enlighter-text&amp;quot;&amp;gt;&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;enlighter-m0&amp;quot;&amp;gt;tasmota_verbrauch_erster_start&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;enlighter-g1&amp;quot;&amp;gt;(&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;enlighter-g1&amp;quot;&amp;gt;)&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;enlighter-text&amp;quot;&amp;gt;;&amp;lt;/span&amp;gt;&amp;lt;/div&amp;gt;&amp;lt;/div&amp;gt;&amp;lt;div&amp;gt;&amp;lt;div&amp;gt;&amp;lt;br&amp;gt;&amp;lt;/div&amp;gt;&amp;lt;/div&amp;gt;&amp;lt;div&amp;gt;&amp;lt;div&amp;gt;&amp;lt;span class=&amp;quot;enlighter-text&amp;quot;&amp;gt;&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;enlighter-c0&amp;quot;&amp;gt;// Alle 15 Minuten das Skript für den Tagesverbrauch ausführen&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;enlighter-text&amp;quot;&amp;gt;&amp;lt;/span&amp;gt;&amp;lt;/div&amp;gt;&amp;lt;/div&amp;gt;&amp;lt;div&amp;gt;&amp;lt;div&amp;gt;&amp;lt;span class=&amp;quot;enlighter-text&amp;quot;&amp;gt;&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;enlighter-m0&amp;quot;&amp;gt;schedule&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;enlighter-g1&amp;quot;&amp;gt;(&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;enlighter-s0&amp;quot;&amp;gt;'*/15 * * * *'&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;enlighter-text&amp;quot;&amp;gt;, tasmota_verbrauch_update&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;enlighter-g1&amp;quot;&amp;gt;)&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;enlighter-text&amp;quot;&amp;gt;;&amp;lt;/span&amp;gt;&amp;lt;/div&amp;gt;&amp;lt;/div&amp;gt;&amp;lt;div&amp;gt;&amp;lt;div&amp;gt;&amp;lt;br&amp;gt;&amp;lt;/div&amp;gt;&amp;lt;/div&amp;gt;&amp;lt;div&amp;gt;&amp;lt;div&amp;gt;&amp;lt;span class=&amp;quot;enlighter-text&amp;quot;&amp;gt;&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;enlighter-c0&amp;quot;&amp;gt;// Nachts um 24 Uhr werden die Werte in andere Variablen gespeichert, um den Verlauf zu erstellen&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;enlighter-text&amp;quot;&amp;gt;&amp;lt;/span&amp;gt;&amp;lt;/div&amp;gt;&amp;lt;/div&amp;gt;&amp;lt;div&amp;gt;&amp;lt;div&amp;gt;&amp;lt;span class=&amp;quot;enlighter-text&amp;quot;&amp;gt;&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;enlighter-m0&amp;quot;&amp;gt;schedule&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;enlighter-g1&amp;quot;&amp;gt;(&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;enlighter-s0&amp;quot;&amp;gt;'0 0 * * *'&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;enlighter-text&amp;quot;&amp;gt;, tasmota_vebrauch_tag&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;enlighter-g1&amp;quot;&amp;gt;)&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;enlighter-text&amp;quot;&amp;gt;;&amp;lt;/span&amp;gt;&amp;lt;/div&amp;gt;&amp;lt;/div&amp;gt;&amp;lt;/div&amp;gt;&amp;lt;/div&amp;gt;&lt;/div&gt;</summary>
		<author><name>Admin</name></author>
	</entry>
	<entry>
		<id>https://wiki.my-network.at/index.php?title=Raspberry_S.USV&amp;diff=38</id>
		<title>Raspberry S.USV</title>
		<link rel="alternate" type="text/html" href="https://wiki.my-network.at/index.php?title=Raspberry_S.USV&amp;diff=38"/>
		<updated>2022-08-24T12:00:13Z</updated>

		<summary type="html">&lt;p&gt;Admin: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&amp;lt;p dir=&amp;quot;auto&amp;quot;&amp;gt;'''Skript um USV Zustände auszulesen, unter IO-Broker anzeigen und Datenpunkte zu erstellen,'''&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p dir=&amp;quot;auto&amp;quot;&amp;gt;Unter&amp;lt;/p&amp;gt;&lt;br /&gt;
[https://forum.iobroker.net/topic/15963/www.s-usv.com www.s-usv.com]&amp;lt;p dir=&amp;quot;auto&amp;quot;&amp;gt;sind verschiedene Varianten der &amp;quot;S.USV Pi uninterrupted power supply&amp;quot; erhältlich.&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p dir=&amp;quot;auto&amp;quot;&amp;gt;Dies sind Aufsteckplatinen für den Raspberry Pi, die eine unterbrechungsfreie Stromversorgung ermöglichen und insbesondere auch ein Wiederanlaufen bei Rückkehr des Stomnetzes erlauben.&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p dir=&amp;quot;auto&amp;quot;&amp;gt;Zur Ansteuerung der S.USV wird ein Daemon installiert, der sich um das Herunterfahren (auch zeitgesteuert) kümmert.&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p dir=&amp;quot;auto&amp;quot;&amp;gt;Dazu gibt es ein Program '''susv''', mit dessen Hilfe man verschiedene Einstellungen vornehmen kann und vor allem auch den aktuellen Status abfragen kann. Letzteres macht dieses Skript und erzeugt aus dem Status eine Reihe von Datenpunkten:&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p dir=&amp;quot;auto&amp;quot;&amp;gt;Hier nun das Skript:&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;blockquote&amp;gt;&amp;lt;p dir=&amp;quot;auto&amp;quot;&amp;gt;! // Script to drive the S.USV Pi uninterrupted power supply&amp;lt;br&amp;gt;! // See&amp;lt;/p&amp;gt;&lt;br /&gt;
[http://www.s-usv.de/ http://www.s-usv.de]&amp;lt;p dir=&amp;quot;auto&amp;quot;&amp;gt;for details.&amp;lt;br&amp;gt;! // NOTE: This script uses the S.USV demon and client software&amp;lt;br&amp;gt;! // (available on same website) so you must install it before.&amp;lt;br&amp;gt;! // Version 1.3, October 2018, Ralf Schaefer&amp;lt;br&amp;gt;! // –----------- Configuration variables -------------&amp;lt;br&amp;gt;! var PollTime = 60; // how often will we poll the usv (in sec)&amp;lt;br&amp;gt;! var susv = '/opt/susvd/susv'; // where is the susv client executable&amp;lt;br&amp;gt;! var idUSV = 'USV.'; // prefix for object tree&amp;lt;br&amp;gt;! var logLevel = 0; // set to 1 for some logging messages&amp;lt;br&amp;gt;! // ------------- Do not modify below this point -------------&amp;lt;br&amp;gt;! var idModel = idUSV + 'Model';&amp;lt;br&amp;gt;! var idFirmware = idUSV + 'FirmwareVersion';&amp;lt;br&amp;gt;! var idSoftware = idUSV + 'SoftwareVersion';&amp;lt;br&amp;gt;! var idHardware = idUSV + 'HardwareVersion';&amp;lt;br&amp;gt;! var idMailNotification = idUSV + 'MailNotification';&amp;lt;br&amp;gt;! var idTimedBoot = idUSV + 'TimedBoot';&amp;lt;br&amp;gt;! var idBootTime = idUSV + 'BootTime';&amp;lt;br&amp;gt;! var idTimedShutdown = idUSV + 'TimedShutdown';&amp;lt;br&amp;gt;! var idShutdownTime = idUSV + 'ShutdownTime';&amp;lt;br&amp;gt;! var idSUSVOK = idUSV + 'SUSVOK';&amp;lt;br&amp;gt;! var idMainsOk = idUSV + 'MainsOK';&amp;lt;br&amp;gt;! var idPoweringSource = idUSV + 'PoweringSource';&amp;lt;br&amp;gt;! var idChargingCircuit = idUSV + 'ChargingCircuit';&amp;lt;br&amp;gt;! var idCharging = idUSV + 'Charging';&amp;lt;br&amp;gt;! var idVoltageIn = idUSV + 'VoltageIn';&amp;lt;br&amp;gt;! var idVoltageInDeviation = idUSV + 'VoltageInDeviation';&amp;lt;br&amp;gt;! var idBatteryCapacity = idUSV + 'BatteryCapacity';&amp;lt;br&amp;gt;! var idBatteryVoltage = idUSV + 'BatteryVoltage';&amp;lt;br&amp;gt;! var idPowerBattery = idUSV + 'PowerBattery';&amp;lt;br&amp;gt;! var idVISBatteryLevel = idUSV + 'BatteryLevel';&amp;lt;br&amp;gt;! var idShutdownTimer = idUSV + 'ShutdownTimer';&amp;lt;br&amp;gt;! var idAutostart = idUSV + 'Autostart';&amp;lt;br&amp;gt;! var idSleepTimer = idUSV + 'SleepTimer';&amp;lt;br&amp;gt;! createState(idModel, 0, { name: 'Model', type: 'string' }); // 'Basic', '???''&amp;lt;br&amp;gt;! createState(idFirmware, 0, { name: 'Firmware version', type: 'string' }); // '2.61'&amp;lt;br&amp;gt;! createState(idSoftware, 0, { name: 'Software version', type: 'string' }); // '2.40'&amp;lt;br&amp;gt;! createState(idHardware, 0, { name: 'Hardware version', type: 'string' }); // '2.1'&amp;lt;br&amp;gt;! createState(idMailNotification, 0, { name: 'Mail notification', type: 'boolean' });&amp;lt;br&amp;gt;! createState(idTimedBoot, 0, { name: 'Timed boot', type: 'boolean' }); // 'HH:mm:ss'&amp;lt;br&amp;gt;! createState(idBootTime, 0, { name: 'Boot time', type: 'string' });&amp;lt;br&amp;gt;! createState(idTimedShutdown, 0, { name: 'Timed shutdown', type: 'boolean' });&amp;lt;br&amp;gt;! createState(idShutdownTime, 0, { name: 'Shutdown time', type: 'string' }); // 'HH:mm:ss'&amp;lt;br&amp;gt;! createState(idSUSVOK, 0, { name: 'Zugriff auf SUSV ok', type: 'boolean' });&amp;lt;br&amp;gt;! createState(idMainsOk, false, { name: 'Netz vorhanden', type: 'boolean' }); // true if PoweringSource != 'Battery'&amp;lt;br&amp;gt;! createState(idPoweringSource, '', { name: 'Energiequelle', type: 'string' }); // 'Primary', 'Battery'&amp;lt;br&amp;gt;! createState(idChargingCircuit, '', { name: 'Batterielader', type: 'string' }); // 'ONLINE', 'OFFLINE'&amp;lt;br&amp;gt;! createState(idCharging, false, { name: 'Akku wird geladen', type: 'boolean' }); // true if battery is charged&amp;lt;br&amp;gt;! createState(idVoltageIn, 0, { name: 'Eingangsspannung', type: 'number', min: 0, max: 5.5, unit: 'V' });&amp;lt;br&amp;gt;! createState(idVoltageInDeviation, 0, { name: 'Abweichung Eingangsspannung', type: 'number', min: -20, max: 20, unit: &amp;quot;%&amp;quot; }); // deviation from 5.00V&amp;lt;br&amp;gt;! createState(idBatteryCapacity, 0, { name: 'Verbleibende Akkukapazitaet', type: 'number', min: 0, max: 100, unit: &amp;quot;%&amp;quot; });&amp;lt;br&amp;gt;! createState(idBatteryVoltage, 0, { name: 'Akkuspannung', type: 'number', min: 0, max: 5.5, unit: 'V' });&amp;lt;br&amp;gt;! createState(idPowerBattery, 0, { name: 'Batteriestrom', type: 'number', min: 0, max: 2000, unit: 'mA' }); // 0 if PoweringSource != 'Battery'&amp;lt;br&amp;gt;! createState(idVISBatteryLevel, 0, { name: 'Batterielevel (0..4 für VIS)', type: 'number', min: 0, max: 4 }); // can be used in VIS to switch icons&amp;lt;br&amp;gt;! createState(idShutdownTimer, 0, { name: 'Shutdown timer', type: 'number' }); //&amp;lt;br&amp;gt;! createState(idAutostart, false, { name: 'Autostart', type: 'boolean' }); // 'enabled' ??&amp;lt;br&amp;gt;! createState(idSleepTimer, 0, { name: 'Sleep timer', type: 'number' }); //&amp;lt;br&amp;gt;! // Backup variables - we want to call setState only on value changes&amp;lt;br&amp;gt;! var vModel = null;&amp;lt;br&amp;gt;! var vFirmware = null;&amp;lt;br&amp;gt;! var vSoftware = null;&amp;lt;br&amp;gt;! var vHardware = null;&amp;lt;br&amp;gt;! var vMailNotification = null;&amp;lt;br&amp;gt;! var vTimedBoot = null;&amp;lt;br&amp;gt;! var vBootTime = null;&amp;lt;br&amp;gt;! var vTimedShutdown = null;&amp;lt;br&amp;gt;! var vShutdownTime = null;&amp;lt;br&amp;gt;! var vMainsOk = null;&amp;lt;br&amp;gt;! var vPoweringSource = null;&amp;lt;br&amp;gt;! var vChargingCircuit = null;&amp;lt;br&amp;gt;! var vCharging = null;&amp;lt;br&amp;gt;! var vVoltageIn = null;&amp;lt;br&amp;gt;! var vVoltageInDeviation = null;&amp;lt;br&amp;gt;! var vBatteryCapacity = null;&amp;lt;br&amp;gt;! var vBatteryVoltage = null;&amp;lt;br&amp;gt;! var vPowerBattery = null;&amp;lt;br&amp;gt;! var vVISBatteryLevel = null;&amp;lt;br&amp;gt;! var vShutdownTimer = null;&amp;lt;br&amp;gt;! var vAutostart = null;&amp;lt;br&amp;gt;! var vSleepTimer = null;&amp;lt;br&amp;gt;! function GetUSVStatus() {&amp;lt;br&amp;gt;! var SWVersion = '';&amp;lt;br&amp;gt;! exec(susv + ' -status', function(err, stdout, stderr) {&amp;lt;br&amp;gt;! if (err) {&amp;lt;br&amp;gt;! log(err + ': ' + stdout);&amp;lt;br&amp;gt;! setState(idSUSVOK, false, true);&amp;lt;br&amp;gt;! return;&amp;lt;br&amp;gt;! }&amp;lt;br&amp;gt;! else&amp;lt;br&amp;gt;! {&amp;lt;br&amp;gt;! // Unlike other values we set the state always, to have a recent time stamp&amp;lt;br&amp;gt;! setState(idSUSVOK, true, true);&amp;lt;br&amp;gt;! }&amp;lt;br&amp;gt;! stdout = stdout.split('\n');&amp;lt;br&amp;gt;! stdout.forEach(function(line) {&amp;lt;br&amp;gt;! var v;&amp;lt;br&amp;gt;! if (contains(line, 'Model:'))&amp;lt;br&amp;gt;! {&amp;lt;br&amp;gt;! v = snip(line, ' ');&amp;lt;br&amp;gt;! if (vModel !== v)&amp;lt;br&amp;gt;! setState(idModel, vModel = v, true);&amp;lt;br&amp;gt;! }&amp;lt;br&amp;gt;! else if (contains(line, 'Firmware Version'))&amp;lt;br&amp;gt;! {&amp;lt;br&amp;gt;! v = snip(line, ' ');&amp;lt;br&amp;gt;! if (vFirmware !== v)&amp;lt;br&amp;gt;! setState(idFirmware, vFirmware = v, true);&amp;lt;br&amp;gt;! }&amp;lt;br&amp;gt;! else if (contains(line, 'Software Version'))&amp;lt;br&amp;gt;! {&amp;lt;br&amp;gt;! v = snip(line, ' ');&amp;lt;br&amp;gt;! if (v !== '2.20' &amp;amp;&amp;amp; v !== '2.33' &amp;amp;&amp;amp; v !== '2.40')&amp;lt;br&amp;gt;! log('Unexpected software version ' + v + ', possibly not all values are correctly identified.')&amp;lt;br&amp;gt;! if (vSoftware !== v)&amp;lt;br&amp;gt;! setState(idSoftware, vSoftware = v, true);&amp;lt;br&amp;gt;! }&amp;lt;br&amp;gt;! else if (contains(line, 'Hardware Version'))&amp;lt;br&amp;gt;! {&amp;lt;br&amp;gt;! v = snip(line, ' ');&amp;lt;br&amp;gt;! if (vHardware !== v)&amp;lt;br&amp;gt;! setState(idHardware, vHardware = v, true);&amp;lt;br&amp;gt;! }&amp;lt;br&amp;gt;! else if (contains(line, 'Mail notification'))&amp;lt;br&amp;gt;! {&amp;lt;br&amp;gt;! v = snip(line, ' ');&amp;lt;br&amp;gt;! v = (v == 'Enabled');&amp;lt;br&amp;gt;! if (vMailNotification !== v)&amp;lt;br&amp;gt;! setState(idMailNotification, vMailNotification = v, true);&amp;lt;br&amp;gt;! }&amp;lt;br&amp;gt;! else if (contains(line, 'Timed Boot'))&amp;lt;br&amp;gt;! {&amp;lt;br&amp;gt;! v = snip(line, ' ');&amp;lt;br&amp;gt;! v = (v == 'Enabled');&amp;lt;br&amp;gt;! if (vTimedBoot !== v)&amp;lt;br&amp;gt;! setState(idTimedBoot, vTimedBoot = v, true);&amp;lt;br&amp;gt;! }&amp;lt;br&amp;gt;! else if (contains(line, 'Boot time'))&amp;lt;br&amp;gt;! {&amp;lt;br&amp;gt;! v = snip(line, ' ');&amp;lt;br&amp;gt;! if (vBootTime !== v)&amp;lt;br&amp;gt;! setState(idBootTime, vBootTime = v, true);&amp;lt;br&amp;gt;! }&amp;lt;br&amp;gt;! else if (contains(line, 'Timed Shutdown'))&amp;lt;br&amp;gt;! {&amp;lt;br&amp;gt;! v = snip(line, ' ');&amp;lt;br&amp;gt;! v = (v == 'Enabled');&amp;lt;br&amp;gt;! if (vTimedShutdown !== v)&amp;lt;br&amp;gt;! setState(idTimedShutdown, vTimedShutdown = v, true);&amp;lt;br&amp;gt;! }&amp;lt;br&amp;gt;! else if (contains(line, 'Shutdown time:'))&amp;lt;br&amp;gt;! {&amp;lt;br&amp;gt;! v = snip(line, ' ');&amp;lt;br&amp;gt;! if (vShutdownTime !== v)&amp;lt;br&amp;gt;! setState(idShutdownTime, vShutdownTime = v, true);&amp;lt;br&amp;gt;! }&amp;lt;br&amp;gt;! else if (contains(line, 'Powering Source'))&amp;lt;br&amp;gt;! {&amp;lt;br&amp;gt;! v = snip(line, ' ');&amp;lt;br&amp;gt;! if (logLevel)&amp;lt;br&amp;gt;! log('PowerSource v=' + v);&amp;lt;br&amp;gt;! if (vPoweringSource !== v)&amp;lt;br&amp;gt;! setState(idPoweringSource, vPoweringSource = v, true);&amp;lt;br&amp;gt;! v = (v != 'Battery');&amp;lt;br&amp;gt;! if (logLevel)&amp;lt;br&amp;gt;! log('MainOK v=' + v);&amp;lt;br&amp;gt;! if (vMainsOk !== v)&amp;lt;br&amp;gt;! setState(idMainsOk, vMainsOk = v, true);&amp;lt;br&amp;gt;! }&amp;lt;br&amp;gt;! else if (contains(line, 'Charging circuit'))&amp;lt;br&amp;gt;! {&amp;lt;br&amp;gt;! v = snip(line, ' ');&amp;lt;br&amp;gt;! if (vChargingCircuit !== v)&amp;lt;br&amp;gt;! setState(idChargingCircuit, vChargingCircuit = v, true);&amp;lt;br&amp;gt;! v = (v != 'OFFLINE');&amp;lt;br&amp;gt;! if (vCharging !== v)&amp;lt;br&amp;gt;! setState(idCharging, vCharging = v, true);&amp;lt;br&amp;gt;! }&amp;lt;br&amp;gt;! else if (contains(line, 'Voltage in'))&amp;lt;br&amp;gt;! {&amp;lt;br&amp;gt;! v = parseFloat(snip(line, ' V'));&amp;lt;br&amp;gt;! if (vVoltageIn !== v)&amp;lt;br&amp;gt;! setState(idVoltageIn, vVoltageIn = v, true);&amp;lt;br&amp;gt;! v = Math.round((v-5)/v''100''10)/10;&amp;lt;br&amp;gt;! if (vVoltageInDeviation !== v)&amp;lt;br&amp;gt;! setState(idVoltageInDeviation, vVoltageInDeviation = v, true);&amp;lt;br&amp;gt;! }&amp;lt;br&amp;gt;! else if (contains(line, 'Battery capacity'))&amp;lt;br&amp;gt;! {&amp;lt;br&amp;gt;! v = parseInt(snip(line, '%'));&amp;lt;br&amp;gt;! if (vBatteryCapacity !== v)&amp;lt;br&amp;gt;! setState(idBatteryCapacity, vBatteryCapacity = v, true);&amp;lt;br&amp;gt;! v = Math.round(parseInt(v) / 25); // 0..100% --&amp;amp;gt; 0..4&amp;lt;br&amp;gt;! if (vVISBatteryLevel !== v)&amp;lt;br&amp;gt;! setState(idVISBatteryLevel, vVISBatteryLevel = v, true);&amp;lt;br&amp;gt;! }&amp;lt;br&amp;gt;! else if (contains(line, 'Battery voltage'))&amp;lt;br&amp;gt;! {&amp;lt;br&amp;gt;! v = parseFloat(snip(line, 'V'));&amp;lt;br&amp;gt;! if (vBatteryVoltage !== v)&amp;lt;br&amp;gt;! setState(idBatteryVoltage, vBatteryVoltage = v, true);&amp;lt;br&amp;gt;! }&amp;lt;br&amp;gt;! else if (contains(line, 'Power Battery'))&amp;lt;br&amp;gt;! {&amp;lt;br&amp;gt;! v = parseFloat(snip(line, ' mA'));&amp;lt;br&amp;gt;! if (vPowerBattery !== v)&amp;lt;br&amp;gt;! setState(idPowerBattery, vPowerBattery = v, true);&amp;lt;br&amp;gt;! }&amp;lt;br&amp;gt;! else if (contains(line, 'Shutdown timer'))&amp;lt;br&amp;gt;! {&amp;lt;br&amp;gt;! v = parseInt(snip(line, ' '));&amp;lt;br&amp;gt;! if (vShutdownTimer !== v)&amp;lt;br&amp;gt;! setState(idShutdownTimer, vShutdownTimer = v, true);&amp;lt;br&amp;gt;! }&amp;lt;br&amp;gt;! else if (contains(line, 'Autostart'))&amp;lt;br&amp;gt;! {&amp;lt;br&amp;gt;! v = snip(line, ' ');&amp;lt;br&amp;gt;! v = (v == 'enabled');&amp;lt;br&amp;gt;! if (vAutostart !== v)&amp;lt;br&amp;gt;! setState(idAutostart, vAutostart = v, true);&amp;lt;br&amp;gt;! }&amp;lt;br&amp;gt;! else if (contains(line, 'Sleep timer'))&amp;lt;br&amp;gt;! {&amp;lt;br&amp;gt;! v = parseFloat(snip(line, ' '));&amp;lt;br&amp;gt;! if (vSleepTimer !== v)&amp;lt;br&amp;gt;! setState(idSleepTimer, vSleepTimer = v, true);&amp;lt;br&amp;gt;! }&amp;lt;br&amp;gt;! });&amp;lt;br&amp;gt;! });&amp;lt;br&amp;gt;! }&amp;lt;br&amp;gt;! setInterval(GetUSVStatus, PollTime * 1000);&amp;lt;br&amp;gt;! // Return true if needle is found in hay, false otherwise&amp;lt;br&amp;gt;! function contains(hay, needle) {&amp;lt;br&amp;gt;! return hay.indexOf(needle) &amp;amp;gt; -1;&amp;lt;br&amp;gt;! }&amp;lt;br&amp;gt;! // snip out everything between the colon and the specified end tag.&amp;lt;br&amp;gt;! // Example:&amp;lt;br&amp;gt;! // snip('* Battery capacity: 69.60% *', '%') =&amp;amp;gt; '69.60'&amp;lt;br&amp;gt;! function snip(line, endtag) {&amp;lt;br&amp;gt;! var idx = line.indexOf(':');&amp;lt;br&amp;gt;! if (idx &amp;amp;lt; 1)&amp;lt;br&amp;gt;! return '';&amp;lt;br&amp;gt;! line = line.substring(idx + 2);&amp;lt;br&amp;gt;! idx = line.indexOf(endtag);&amp;lt;br&amp;gt;! if (idx &amp;amp;lt; 1)&amp;lt;br&amp;gt;! return '';&amp;lt;br&amp;gt;! return line.substring(0, idx);&amp;lt;br&amp;gt;! }&amp;lt;/p&amp;gt;&amp;lt;/blockquote&amp;gt;&lt;/div&gt;</summary>
		<author><name>Admin</name></author>
	</entry>
	<entry>
		<id>https://wiki.my-network.at/index.php?title=Datei:SUSVpi_Manual_Rev1_4_GER.pdf&amp;diff=37</id>
		<title>Datei:SUSVpi Manual Rev1 4 GER.pdf</title>
		<link rel="alternate" type="text/html" href="https://wiki.my-network.at/index.php?title=Datei:SUSVpi_Manual_Rev1_4_GER.pdf&amp;diff=37"/>
		<updated>2022-08-24T11:58:02Z</updated>

		<summary type="html">&lt;p&gt;Admin: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;/div&gt;</summary>
		<author><name>Admin</name></author>
	</entry>
	<entry>
		<id>https://wiki.my-network.at/index.php?title=Dovecot_Mailserver&amp;diff=36</id>
		<title>Dovecot Mailserver</title>
		<link rel="alternate" type="text/html" href="https://wiki.my-network.at/index.php?title=Dovecot_Mailserver&amp;diff=36"/>
		<updated>2022-08-24T11:49:38Z</updated>

		<summary type="html">&lt;p&gt;Admin: /* Fragen und Antworten */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&amp;lt;header&amp;gt;&lt;br /&gt;
= Mailserver mit Dovecot, Postfix, MySQL und Rspamd unter Debian 10 Buster [v1.0] =&lt;br /&gt;
&amp;lt;div class=&amp;quot;translations&amp;quot;&amp;gt;&amp;lt;br&amp;gt;&amp;lt;/div&amp;gt;&amp;lt;/header&amp;gt;&lt;br /&gt;
== Mailserver-Funktionen ==&lt;br /&gt;
&amp;lt;p&amp;gt;Damit ihr einen Eindruck vom Funktionsumfang des fertigen Mailsetups bekommt, hier einige Merkmale:&amp;lt;/p&amp;gt;&lt;br /&gt;
*Senden und Empfangen von E-Mails für beliebige Domains&lt;br /&gt;
*Flexible Einrichtung von Domains, Mailaccounts, Aliasen, Weiterleitungen und Regeln für die Transportverschlüsselung über ein MySQL-Backend zur Laufzeit&lt;br /&gt;
*Nutzer-spezifisch begrenztes Mailbox-Volumen&lt;br /&gt;
*Einrichtung allgemeiner und Nutzer-spezifischer Sieve-Filterregeln zum Filtern und/oder Umsortieren eingehender E-Mails&lt;br /&gt;
*Zuverlässige und moderne Spamerkennung via Rspamd (+ Weboberfläche für Spam-Statistiken)&lt;br /&gt;
*“Send only” Accounts z.B. für NextCloud / Forensoftware / …&lt;br /&gt;
*DKIM-und ARC-Signierung ausgehender E-Mails&lt;br /&gt;
*Mailclient Autokonfiguration&lt;br /&gt;
*Domain Catch-All&lt;br /&gt;
&amp;lt;p&amp;gt;Eine '''Weboberfläche''' / ein '''Management-Tool''' zur Verwaltung dieses Setups biete ich selbst nach wie vor nicht an. In der Zwischenzeit haben aber andere User Lösungen veröffentlicht, z.B.&amp;lt;/p&amp;gt;&lt;br /&gt;
*Florian Kapfenberger:[https://github.com/phiilu/mailman Mailman]''(nicht zu verwechseln mit Mailman, dem Mailinglist-Manager!)''&lt;br /&gt;
*Andreas Bresch:[https://github.com/Andreas-Bresch/vmailManage/ VmailManage]&lt;br /&gt;
&lt;br /&gt;
*Henrik Halbritter:[https://github.com/Halbritter/MailAdmin/releases MailAdmin]&lt;br /&gt;
*awidegreen:[https://github.com/awidegreen/vmail-rs vmail-rs](CLI-Tool!)&lt;br /&gt;
*pprugger:[https://github.com/pprugger/vmail-admin vmail-admin]&lt;br /&gt;
*Kekskurse:[https://github.com/kekskurse/go-mail-admin Go-Mail-Admin]&lt;br /&gt;
&amp;lt;div class=&amp;quot;tip&amp;quot;&amp;gt;Das Datenbank-Layout und die Struktur des &amp;lt;code&amp;gt;/var/vmail&amp;lt;/code&amp;gt;-Verzeichnisses haben sich im Vergleich zur vorherigen Anleitung ''nicht'' geändert. Ein Update älterer Setups ist also einfach realisierbar.&amp;lt;/div&amp;gt;&amp;lt;hr&amp;gt;&lt;br /&gt;
== Verwendete Software ==&lt;br /&gt;
&lt;br /&gt;
*Debian 10 “Buster”&lt;br /&gt;
*Postfix&lt;br /&gt;
*Dovecot&lt;br /&gt;
*Rspamd&lt;br /&gt;
*Redis&lt;br /&gt;
*MariaDB&lt;br /&gt;
*Nginx&lt;br /&gt;
&lt;br /&gt;
== Gegebenheiten ==&lt;br /&gt;
&amp;lt;p&amp;gt;In dieser Anleitung kommen folgende Domains vor:&amp;lt;/p&amp;gt;&lt;br /&gt;
*&amp;lt;code&amp;gt;mysystems.tld&amp;lt;/code&amp;gt;: Übergeordnete, primäre Domain&lt;br /&gt;
*&amp;lt;code&amp;gt;mail.mysystems.tld&amp;lt;/code&amp;gt;: Subdomain, unter der der Mailserver verfügbar sein soll (FQDN des Mailsystems)&lt;br /&gt;
*&amp;lt;code&amp;gt;imap.mysystems.tld&amp;lt;/code&amp;gt;: Alias auf mail.mysystems.tld, wird von vielen Mailclient automatisch gesucht und gefunden&lt;br /&gt;
*&amp;lt;code&amp;gt;smtp.mysystems.tld&amp;lt;/code&amp;gt;: Dasselbe für den SMTP-Dienst&lt;br /&gt;
*&amp;lt;code&amp;gt;domain2.tld&amp;lt;/code&amp;gt;: Eine zweite Domain neben mysystems.tld, für die E-Mails gesendet und empfangen werden sollen&lt;br /&gt;
*&amp;lt;code&amp;gt;domain3.tld&amp;lt;/code&amp;gt;: Eine dritte Domain, für die E-Mails gesendet und empfangen werden sollen&lt;br /&gt;
&amp;lt;p&amp;gt;'''Diese Domains müssen in der ''gesamten'' Anleitung selbstverständlich durch eigene ersetzt werden!'''&amp;lt;br&amp;gt;Auf domain2.tld und domain3.tld kann verzichtet werden, wenn der Mailserver nur für eine Domain (nur für “@mysystems.tld”-Adressen) genutzt werden soll.&amp;lt;/p&amp;gt;&amp;lt;p&amp;gt;Folgende IP-Adressen werden beispielhaft in Konfigurationen genannt und müssen ebenfalls durch die IP-Adressen des jeweiligen Servers ersetzt werden:&amp;lt;/p&amp;gt;&lt;br /&gt;
*&amp;lt;code&amp;gt;2001:db8::1&amp;lt;/code&amp;gt; (IPv6-Adresse des Mailservers)&lt;br /&gt;
*&amp;lt;code&amp;gt;203.0.113.1&amp;lt;/code&amp;gt; (IPv4-Adresse des Mailservers)&lt;br /&gt;
&lt;br /&gt;
== Grundvoraussetzungen für den Mailserver ==&lt;br /&gt;
&lt;br /&gt;
*Ein virtueller oder dedizierter Server mit bereits installiertem Debian 10 Buster&amp;lt;br&amp;gt;(“Standard-Systemwerkzeuge” und “SSH” bei der Installation angewählt)&lt;br /&gt;
*Mindestens eine eigene Domain + volle Kontrolle über die DNS-Zone&lt;br /&gt;
&amp;lt;p&amp;gt;Ein kleiner, virtueller Server auf KVM-Basis ist in den meisten Fällen völlig ausreichend. Ich empfehle für kleine, private Setups zwei CPU-Kerne und 1-2 GB RAM. Virtuelle Server kann man z.B. bei&amp;lt;/p&amp;gt;[https://servercow.de/vserver Servercow]&amp;lt;p&amp;gt;oder&amp;lt;/p&amp;gt;[https://hetzner.cloud/?ref=H6gtsnaMZj6N Hetzner]&amp;lt;p&amp;gt;preisgünstig bekommen.&amp;lt;/p&amp;gt;&lt;br /&gt;
== Komponenten eines vollständigen Mailsystems ==&lt;br /&gt;
&amp;lt;figure&amp;gt;&amp;lt;figcaption&amp;gt;Mailserver Schema&amp;lt;/figcaption&amp;gt;&amp;lt;/figure&amp;gt;&amp;lt;p&amp;gt;Welche Softwarekomponenten verwendet werden, wisst ihr bereits. Doch welche Software übernimmt welche Aufgaben?&amp;lt;/p&amp;gt;&lt;br /&gt;
=== Dovecot ===&lt;br /&gt;
&amp;lt;p&amp;gt;Dovecot ist ein weit verbreiteter MDA (Mail Delivery Agent) und IMAP-Server. Er sortiert ankommende E-Mails in die Postfächer des jeweiligen Empfängers ein und stellt eine Schnittstelle zum Abrufen der Mailbox bereit (IMAP). Außerdem wird Dovecot in diesem Setup von Postfix als sog. SASL-Authentifizierungsserver genutzt: Postfix fragt Dovecot, ob ein bestimmter Benutzer berechtigt ist, sich am System anzumelden.&amp;lt;/p&amp;gt;&lt;br /&gt;
=== Postfix ===&lt;br /&gt;
&amp;lt;p&amp;gt;Postfix wird oft zusammen mit Dovecot eingesetzt. Der populäre MTA (Mail Transfer Agent) kümmert sich um alles, was mit dem Transport der E-Mail zu tun hat: Vom E-Mail Client zum eigenen Mailserver, und von dort aus zum jeweiligen Zielserver. Außerdem nimmt Postfix E-Mails von fremden Servern an und leitet sie an den MDA Dovecot weiter. Antispam-Software wird i.d.R. direkt in Postfix integriert, um eintreffende Spammails erst gar nicht in die Mailbox des Nutzers gelangen zu lassen.&amp;lt;/p&amp;gt;&amp;lt;p&amp;gt;''Anmerkung: Postfix ist “der eigentliche Mailserver”. E-Mails können ohne weiteres einzig und allein mit Postfix gesendet und empfangen werden. Alle weiteren Komponenten wie Dovecot und Rspamd machen uns das Leben allerdings einfacher ;-)''&amp;lt;/p&amp;gt;&lt;br /&gt;
=== MariaDB (MySQL-Datenbank) ===&lt;br /&gt;
&amp;lt;p&amp;gt;Dovecot und Postfix werden so konfiguriert, dass sie eine MySQL-Datenbank als Backend (Datenbasis) nutzen. In der Datenbank werden zu nutzende Domains, Benutzer, Aliase und weitere Daten gespeichert. Durch einfaches Hinzufügen oder Entfernen von Datensätzen in oder aus Datenbanktabellen können neue Benutzer oder Aliase angelegt oder gelöscht werden. Der Vorteil eines Datenbank-Backends ist, dass sich der Mailserver damit sehr einfach verwalten lässt: So ließe sich zur Benutzerverwaltung beispielsweise eine Weboberfläche in PHP entwickeln, die die MySQL-Datenbank verändert. Die Serverkonfiguration muss dann nicht manuell geändert werden.&amp;lt;/p&amp;gt;&lt;br /&gt;
=== Rspamd ===&lt;br /&gt;
&amp;lt;p&amp;gt;Rspamd ist ein Filtersystem, das in Postfix integriert wird und eingehende E-Mails überprüft. Spammails werden von Rspamd erkannt und nicht an den Benutzer zugestellt bzw. aussortiert. Außerdem fügt Rspamd bei ausgehenden E-Mails eine DKIM-Signatur hinzu, sodass fremde Mailserver eigene Mails nicht als verdächtig einstufen.&amp;lt;/p&amp;gt;&lt;br /&gt;
=== Nginx ===&lt;br /&gt;
&amp;lt;p&amp;gt;Nginx ist ein weit verbreiteter und schlanker Webserver / Webproxy. In diesem Setup hat er mehrere Aufgaben: Zum einen kann er als Endpunkt für den Ausstellungsprozess von Let’s Encrypt-Zertifikaten dienen, zum anderen als Proxy für die Rspamd-Weboberfläche, oder um die Autokonfigurationsdatei für Mailclients anzubieten.&amp;lt;/p&amp;gt;&lt;br /&gt;
=== Redis ===&lt;br /&gt;
&amp;lt;p&amp;gt;Redis ist ein hochperformanter In-memory Key-Value-Store, also eine sehr einfache, schnelle Datenbank, welche Schlüssel-Wert-Paare effizient im Speicher ablegen kann. Rspamd nutzt Redis, um einige Daten zwischenzuspeichern (wie z.B. zuletzt überprüfte Mailserver).&amp;lt;/p&amp;gt;&lt;br /&gt;
== Vorbereitungen ==&lt;br /&gt;
=== Tipp: Reinen Tisch machen ===&lt;br /&gt;
&amp;lt;p&amp;gt;Wenn ihr den Server vorher schon für etwas anderes (oder sogar ein anderes Mail-Setup) verwendet habt, stellt sicher, dass Reste aus alten Installationen das neue Setup nicht behindern. Speziell vorherige Mailserver-Versuche sollten rückstandslos entfernt werden (inkl. der zugehörigen Konfigurationsdateien). Am besten ist natürlich – falls möglich – eine komplette Neuinstallation des Servers. Ich empfehle, den Mailserver als eigenständiges System zu betreiben und auf demselben Host keine anderen Dienste zu installieren, um die Integrität des Mailsystems sicherzustellen.&amp;lt;/p&amp;gt;&amp;lt;p&amp;gt;Im Folgenden gehe ich von einem frisch installierten Debian 10 Buster aus (zusätzlich nur “Standard-Systemwerkzeuge” und SSH installiert).&amp;lt;/p&amp;gt;&lt;br /&gt;
=== Login als Root ===&lt;br /&gt;
&amp;lt;p&amp;gt;Bei der Installation von Debian wird ein normaler Benutzeraccount, z.B. “thomas” eingerichtet, zu dem ihr euch via Passwort verbinden könnt. Der Root-Account ist standardmäßig nicht direkt zugänglich, sondern nur über den Umweg via “su”. Für diese Anleitung werden permanent Root-Rechte benötigt. Öffnet nach dem Login am Server also am besten eine Root-Kommandozeile via&amp;lt;/p&amp;gt;&amp;lt;pre&amp;gt;&amp;lt;code&amp;gt;su -&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;/pre&amp;gt;&amp;lt;p&amp;gt;Gebt dann das Passwort für euren root-User ein.&amp;lt;/p&amp;gt;&lt;br /&gt;
=== System aktualisieren ===&lt;br /&gt;
&amp;lt;p&amp;gt;Bevor ihr neue Software-Pakete installiert, solltet ihr mittels&amp;lt;/p&amp;gt;&amp;lt;pre&amp;gt;&amp;lt;code&amp;gt;apt update &amp;amp;&amp;amp; apt upgrade&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;/pre&amp;gt;&amp;lt;p&amp;gt;sicherstellen, dass euer System aktuell ist. Bei der Gelegenheit bietet sich auch gleich ein Reboot an, um einen möglicherweise aktualisierten Linux-Kernel zu laden.&amp;lt;/p&amp;gt;&lt;br /&gt;
=== Hostname und Server-FQDN setzen ===&lt;br /&gt;
&amp;lt;p&amp;gt;Euer Server bekommt zwei Namen, über die er identifiziert werden kann:&amp;lt;/p&amp;gt;&lt;br /&gt;
*Lokalen Hostnamen: Für die Identifizierung des Servers innerhalb der eigenen Infrastruktur, z.B. “mail”&lt;br /&gt;
*FQDN (Fully Qualified Domain Name): Für die weltweite Identifizierung im Internet, z.B. “mail.mysystems.tld”&lt;br /&gt;
&amp;lt;p&amp;gt;Der FQDN muss nicht zwingend etwas mit den Domains zu tun haben, für die später E-Mails gesendet und empfangen werden sollen. Wichtig ist nur, dass euer künftiger Mailserver einen solchen Namen hat, der auch über das DNS zur Server-IP-Adresse aufgelöst werden kann (dazu gleich mehr im Abschnitt “Einrichtung des DNS”). Den lokalen Hostnamen setzt ihr wie folgt:&amp;lt;/p&amp;gt;&amp;lt;pre&amp;gt;&amp;lt;code&amp;gt;hostnamectl set-hostname --static mail&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;/pre&amp;gt;&amp;lt;p&amp;gt;In der Hosts-Datei &amp;lt;code&amp;gt;/etc/hosts&amp;lt;/code&amp;gt; sollten FQDN und lokaler Hostname hinterlegt sein. Die Datei kann beispielsweise so aussehen:&amp;lt;/p&amp;gt;&amp;lt;pre&amp;gt;&amp;lt;code&amp;gt;127.0.0.1	localhost&lt;br /&gt;
127.0.1.1	mail.mysystems.tld	mail&lt;br /&gt;
&lt;br /&gt;
::1         localhost ip6-localhost ip6-loopback&lt;br /&gt;
ff02::1     ip6-allnodes&lt;br /&gt;
ff02::2     ip6-allrouters&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;/pre&amp;gt;&amp;lt;p&amp;gt;Die Ausgaben der Kommandos &amp;lt;code&amp;gt;hostname&amp;lt;/code&amp;gt; und &amp;lt;code&amp;gt;hostname --fqdn&amp;lt;/code&amp;gt; sollten nach den Änderungen wie folgt aussehen:&amp;lt;/p&amp;gt;&amp;lt;pre&amp;gt;&amp;lt;code&amp;gt;root@mail:~# hostname&lt;br /&gt;
mail&lt;br /&gt;
root@mail:~# hostname --fqdn&lt;br /&gt;
mail.mysystems.tld&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;/pre&amp;gt;&amp;lt;p&amp;gt;Der FQDN (in diesem Beispiel “mail.mysystems.tld”) wird außerdem nach &amp;lt;code&amp;gt;/etc/mailname&amp;lt;/code&amp;gt; geschrieben:&amp;lt;/p&amp;gt;&amp;lt;pre&amp;gt;&amp;lt;code&amp;gt;echo $(hostname -f) &amp;amp;gt; /etc/mailname&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;/pre&amp;gt;&amp;lt;p&amp;gt;''(Der Hostname im Shell-Prompt z.B. &amp;lt;code&amp;gt;root@meinhost:&amp;lt;/code&amp;gt; passt sich erst nach einem erneuten Login an.)''&amp;lt;/p&amp;gt;&lt;br /&gt;
=== Unbound DNS Resolver installieren ===&lt;br /&gt;
&amp;lt;p&amp;gt;Das Mailsystem benötigt einen funktionierenden DNS-Server (Resolver), sodass die Herkunft von E-Mails überprüft werden kann. Auch der Rspamd-Spamfilter verlässt sich bei der Bewertung von Spammails auf DNS-Dienste. Eine schnelle Namesauflösung bringt also Performancevorteile für das ganze Mailsystem. Für den Zugriff auf Spamhaus-Blocklists kann es sogar notwendig sein, seinen eigenen DNS-Resolver zu nutzen, weil z.B. Zugriffe über das Google DNS blockiert werden. Deshalb (und um die Sicherheit im Bezug auf Abhängigkeiten zu fremden Systemen zu verbessern) empfehle ich die Nutzung eines eigenen, lokalen DNS-Resolvers.&amp;lt;/p&amp;gt;&amp;lt;p&amp;gt;Unbound installieren:&amp;lt;/p&amp;gt;&amp;lt;pre&amp;gt;&amp;lt;code&amp;gt;apt install unbound&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;/pre&amp;gt;&amp;lt;div class=&amp;quot;tip&amp;quot;&amp;gt;Für die nächsten Kommandos muss müssen die Pakete &amp;lt;code&amp;gt;dnsutils&amp;lt;/code&amp;gt; und &amp;lt;code&amp;gt;resolvconf&amp;lt;/code&amp;gt; installiert sein. Wenn bei der Installation von Debian die “Standard-Systemwerkzeuge” ausgewählt wurden, sind die &amp;lt;code&amp;gt;dnsutils&amp;lt;/code&amp;gt; schon installiert.&amp;lt;/div&amp;gt;&amp;lt;p&amp;gt;Ein &amp;lt;code&amp;gt;dig @::1 denic.de +short +dnssec&amp;lt;/code&amp;gt; sollte eine ähnliche Ausgabe wie folgt erzeugen:&amp;lt;/p&amp;gt;&amp;lt;pre&amp;gt;&amp;lt;code&amp;gt;# dig @::1 denic.de +short +dnssec&lt;br /&gt;
A 8 2 3600 20170814090000 20170731090000 26155 denic.de. Jo90qnkLkZ6gI4qNHj19BMguFuGof9hCPhdeSh/fSePSQ/WXlWMmfjW1 sNDJ/bcITRMyz8DQdDzmWPDIeSJ/qPyfoZ+BjUZxtaXcs0BAl4KX8q7h R05TGmAbgPhrYBoUKJkU/q8T+jWKHAJRUeWbCd8QOJsJbneGcUKxRAPe i6Rq51/OL/id6zUCtalhclah2TfLLaqku9PmKwjbGdZm11BXSr8b56LB WX/rdLIrKWNpE+jHGAUMmDsZL84Kx3Oo&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;/pre&amp;gt;&amp;lt;p&amp;gt;Wenn der &amp;lt;code&amp;gt;dig&amp;lt;/code&amp;gt;-Befehl funktioniert hat, kann der lokale Resolver als primärer Resolver gesetzt werden:&amp;lt;/p&amp;gt;&amp;lt;pre&amp;gt;&amp;lt;code&amp;gt;apt install resolvconf&lt;br /&gt;
echo &amp;quot;nameserver ::1&amp;quot; &amp;amp;gt;&amp;amp;gt; /etc/resolvconf/resolv.conf.d/head&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;/pre&amp;gt;&amp;lt;p&amp;gt;ein &amp;lt;code&amp;gt;nslookup denic.de | grep Server&amp;lt;/code&amp;gt; sollte nun&amp;lt;/p&amp;gt;&amp;lt;pre&amp;gt;&amp;lt;code&amp;gt;Server:		::1&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;/pre&amp;gt;&amp;lt;p&amp;gt;zurückliefern. Damit ist der lokale DNS-Resolver als Haupt-Resolver einsatzbereit.&amp;lt;/p&amp;gt;&lt;br /&gt;
== Einrichtung des DNS ==&lt;br /&gt;
&amp;lt;p&amp;gt;Zu Beginn dieser Anleitung wurde für den Mailserver der FQDN “mail.mysystems.tld” festgelegt. Für diesen Domain-Namen werden nun A-Records im DNS-Zonefile der Domain “mysystems.tld” erstellt. Loggt euch bei eurem Domain-Provider ein und legt die folgenden Einträge an – der erste für die IPv4-IP-Adresse des Mailservers, die zweite für die IPv6-Adresse. (Beispiel!):&amp;lt;/p&amp;gt;&amp;lt;p&amp;gt;Achtet im Folgenden vor allem auf den abschließenden Punkt in den Domainnamen!&amp;lt;/p&amp;gt;&amp;lt;pre&amp;gt;&amp;lt;code&amp;gt;mail.mysystems.tld. 86400 IN A    203.0.113.1&lt;br /&gt;
mail.mysystems.tld. 86400 IN AAAA 2001:db8::1&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;/pre&amp;gt;&amp;lt;p&amp;gt;“mail.mysystems.tld” ist damit im DNS bekannt. Wenn keine IPv6-Adresse genutzt wird, kann der zweite Record entfallen. Bleiben noch “imap.mysystems.tld” und “smtp.mysystems.tld”, die als Alias-Domains für “mail.mysystems.tld” angelegt werden. Sie sind nicht unbedingt notwendig, werden von vielen Mailclient aber gesucht und sind so üblich:&amp;lt;/p&amp;gt;&amp;lt;pre&amp;gt;&amp;lt;code&amp;gt;imap.mysystems.tld. 86400 IN CNAME mail.mysystems.tld.&lt;br /&gt;
smtp.mysystems.tld. 86400 IN CNAME mail.mysystems.tld.&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;/pre&amp;gt;&amp;lt;p&amp;gt;Mailclients können sich damit schon über imap.mysystems.tld und smtp.mysystems.tld zum Mailserver verbinden. Andere Mailserver suchen bei der E-Mail-Übermittlung allerdings nicht nach A- oder CNAME-Records, sondern nach MX-Records. Ein MX-Record zeigt, welcher Mailserver für die E-Mails zu einer Domain zuständig ist. In meinem Beispiel soll sich unser Mailserver neben den E-Mails für mysystems.tld auch um die Mails für domain2.tld und domain3.tld kümmern.&amp;lt;/p&amp;gt;&amp;lt;p&amp;gt;Im Zonefile der Domain “mysystems.tld” wird dazu dieser Record angelegt:&amp;lt;/p&amp;gt;&amp;lt;pre&amp;gt;&amp;lt;code&amp;gt;mysystems.tld. 86400 IN MX 0 mail.mysystems.tld.&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;/pre&amp;gt;&amp;lt;p&amp;gt;In die Zonefiles der anderen Domains werden entsprechend die Records&amp;lt;/p&amp;gt;&amp;lt;pre&amp;gt;&amp;lt;code&amp;gt;domain2.tld. 86400 IN MX 0 mail.mysystems.tld.&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;/pre&amp;gt;&amp;lt;p&amp;gt;und&amp;lt;/p&amp;gt;&amp;lt;pre&amp;gt;&amp;lt;code&amp;gt;domain3.tld. 86400 IN MX 0 mail.mysystems.tld.&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;/pre&amp;gt;&amp;lt;p&amp;gt;angelegt.&amp;lt;/p&amp;gt;&lt;br /&gt;
=== Reverse DNS ===&lt;br /&gt;
&amp;lt;p&amp;gt;Des weiteren muss ein sog. Reverse-DNS-Record / PTR für den FQDN des Mailservers angelegt werden. Dieser entspricht der Umkehrung eines normalen DNS-Records und ordnet einer IP-Adresse einen Hostnamen zu. Diesen Record kann nur der Inhaber des Netzes anlegen, aus dem eure IP-Adresse stammt. Möglicherweise könnt ihr so einen Reverse-DNS-Record in der Verwaltungsoberfläche eures Serveranbieters setzen, oder ihr bittet den Support, das zu tun. Der Domain-Name, der mit der IP-Adresse verknüpft werden muss, ist der FQDN eures Mailservers. In meinem Beispiel mail.mysystems.tld. Denkt daran, für alle vom Mailserver genutzten, öffentlichen IP-Adressen einen solchen Record zu erstellen. In dieser Anleitung wird eine IPv4- und eine IPv6-Adresse verwendet.&amp;lt;/p&amp;gt;&lt;br /&gt;
=== SPF-Records ===&lt;br /&gt;
&amp;lt;p&amp;gt;Im Kampf gegen Spam und Phishing wurde das sog. Sender Policy Framework entwickelt (Siehe auch Beitrag: “&amp;lt;/p&amp;gt;[https://thomas-leister.de/voraussetzungen-email-versand-gro%C3%9Fe-provider/ Voraussetzungen für den Versand zu großen E-Mail Providern]&amp;lt;p&amp;gt;&amp;quot;). Obwohl es sich nur als eingeschränkt brauchbar erwiesen hat, erwarten die meisten Mailprovider gültige SPF-Records für andere Mailserver und prüfen diese. SPF-Einträge werden im Zonefile aller Domains erstellt, für die ein Mailserver E-Mails verschickt, und geben an, welche Server für eine Domain sendeberechtigt sind. Für unsere Domain mysystems.tld wird der folgende Record im Zonefile von mysystems.tld angelegt:&amp;lt;/p&amp;gt;&amp;lt;pre&amp;gt;&amp;lt;code&amp;gt;mysystems.tld. 3600 IN TXT v=spf1 a:mail.mysystems.tld mx ?all&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;/pre&amp;gt;&amp;lt;p&amp;gt;Hiermit erhält nur der im A-Record “mail.msystems.tld” genannte Server für mysystems.tld eine Sendeberechtigung. Die Neutral-Einstellung “?all” sorgt dafür, dass E-Mails von anderen Servern trotzdem angenommen werden sollen. Damit gehen wir Problemen beim Mail-Forwarding aus dem Weg. Wir erstellen den SPF-Record also eigentlich nur, damit andere Mailserver unseren Server wegen des existierenden Records positiv bewerten – nicht, weil er seinen Nutzen entfalten soll.&amp;lt;/p&amp;gt;&amp;lt;p&amp;gt;In den Zonefiles der beiden Domains “domain2.tld” und “domain3.tld” wird (angepasst auf die Domain) jeweils dieser Record angelegt:&amp;lt;/p&amp;gt;&amp;lt;pre&amp;gt;&amp;lt;code&amp;gt;domain2.tld. 3600 IN TXT v=spf1 include:mysystems.tld ?all&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;/pre&amp;gt;&amp;lt;p&amp;gt;Über das “include” wird der erste Record der Domain mysystems.tld eingebunden.&amp;lt;/p&amp;gt;&lt;br /&gt;
=== DMARC Records ===&lt;br /&gt;
&amp;lt;p&amp;gt;DMARC-Einträge bestimmen, was ein fremder Mailserver tun soll, wenn eine von ihm empfangene Mail nach SPF- und DKIM-Checks offenbar nicht vom korrekten Mailserver stammt (wenn der Absender also gefälscht wurde). Es ist vernünftig, andere Mailserver anzuweisen, solche E-Mails nicht zu akzeptieren:&amp;lt;/p&amp;gt;&amp;lt;pre&amp;gt;&amp;lt;code&amp;gt;_dmarc.mysystems.tld.   3600    IN TXT    v=DMARC1; p=reject;&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;/pre&amp;gt;&amp;lt;p&amp;gt;Der Record wird entsprechend auch für die anderen Domains gesetzt:&amp;lt;/p&amp;gt;&amp;lt;pre&amp;gt;&amp;lt;code&amp;gt;_dmarc.domain2.tld.   3600    IN TXT    v=DMARC1; p=reject;&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;/pre&amp;gt;&amp;lt;p&amp;gt;Einen DMARC-Record mit einer abweichenden Policy könnt ihr euch unter&amp;lt;/p&amp;gt;[https://elasticemail.com/dmarc/ https://elasticemail.com/dmarc/]&amp;lt;p&amp;gt;selbst generieren lassen.&amp;lt;/p&amp;gt;&lt;br /&gt;
== Erstkonfiguration Nginx Webserver ==&lt;br /&gt;
&amp;lt;p&amp;gt;Wie bereits angemerkt, übernimmt Nginx in diesem Setup verschiedene Aufgaben. Für’s erste dient er aber nur als HTTP-Endpunkt, um Let’s Encrypt Zertifikate zu beantragen. Das ist zwar prinzipiell auch ohne Nginx im standalone-Modus möglich, macht uns aber das Leben einfacher, wenn wir ihn sowieso in Betrieb haben ''(=&amp;amp;gt; belegte Ports durch Nginx, ACME client …)''.&amp;lt;/p&amp;gt;&amp;lt;p&amp;gt;Dazu wird Nginx installiert …&amp;lt;/p&amp;gt;&amp;lt;pre&amp;gt;&amp;lt;code&amp;gt;apt install nginx&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;/pre&amp;gt;&amp;lt;p&amp;gt;… und unter &amp;lt;code&amp;gt;/etc/nginx/sites-available/mail.mysystems.tld&amp;lt;/code&amp;gt; eine neue Konfiguration mit diesem Inhalt angelegt:&amp;lt;/p&amp;gt;&amp;lt;pre&amp;gt;&amp;lt;code&amp;gt;server {&lt;br /&gt;
        listen 80;&lt;br /&gt;
        listen [::]:80;&lt;br /&gt;
#       listen 443 ssl http2;&lt;br /&gt;
#       listen [::]:443 ssl http2;&lt;br /&gt;
&lt;br /&gt;
        server_name mail.mysystems.tld imap.mysystems.tld smtp.mysystems.tld;&lt;br /&gt;
&lt;br /&gt;
#       ssl_certificate /etc/acme.sh/mail.mysystems.tld/fullchain.pem;&lt;br /&gt;
#       ssl_certificate_key /etc/acme.sh/mail.mysystems.tld/privkey.pem;&lt;br /&gt;
&lt;br /&gt;
#       add_header Strict-Transport-Security max-age=15768000;&lt;br /&gt;
&lt;br /&gt;
#       if ($ssl_protocol = &amp;quot;&amp;quot;) {&lt;br /&gt;
#           return 301 https://$server_name$request_uri;&lt;br /&gt;
#       }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;/pre&amp;gt;&amp;lt;p&amp;gt;Einige Zeilen sind zu diesem Zeitpunkt bewusst auskommentiert und werden später wieder aktiviert, sobald TLS-Zertifikate verfügbar sind.&amp;lt;/p&amp;gt;&amp;lt;p&amp;gt;Der neue vHost kann nun aktiviert werden:&amp;lt;/p&amp;gt;&amp;lt;pre&amp;gt;&amp;lt;code&amp;gt;ln -s /etc/nginx/sites-available/mail.mysystems.tld /etc/nginx/sites-enabled/mail.mysystems.tld&lt;br /&gt;
systemctl reload nginx&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;/pre&amp;gt;&lt;br /&gt;
== Beantragung der TLS-Zertifikate (via Let’s Encrypt) ==&lt;br /&gt;
&amp;lt;p&amp;gt;Gültige TLS-Zertifikate von anerkannten Zertifizierungsstellen (CAs) sind heute für jeden Mailserver ein “muss”. Immer mehr Mailsysteme verweigern zurecht den Empfang über ungesicherte Verbindungen. Was früher (vor allem für den privaten Einsatz) noch ein bedeutender Kostenfaktor war, bekommt man heute Dank Let’s Encrypt kostenlos und sehr unkompliziert. Im folgenden beziehe ich mich daher auf die Generierung von Let’s Encrypt-Zertifikaten. Selbstverständlich können stattdessen auch Zertifikate anderer CAs genutzt werden.&amp;lt;/p&amp;gt;&amp;lt;p&amp;gt;Für Postfix und Dovecot benötigen wir Zertifikate zu folgenden Domains:&amp;lt;/p&amp;gt;&lt;br /&gt;
*mail.mysystems.tld&lt;br /&gt;
*imap.mysystems.tld&lt;br /&gt;
*smtp.mysystems.tld&lt;br /&gt;
&amp;lt;p&amp;gt;Um die Zertifikate von der Let’s Encrypt Zertifizierungsstelle abholen, nutze ich das schlanke&amp;lt;/p&amp;gt;[https://github.com/acmesh-official/acme.sh acme.sh Script]&amp;lt;p&amp;gt;. Dieses verfügt über einen “Nginx-Mode”, in dem das Script den Nginx Webserver automatisch so konfiguriert, dass die Domains von LE verifiziert werden können.&amp;lt;/p&amp;gt;&amp;lt;p&amp;gt;acme.sh installieren:&amp;lt;/p&amp;gt;&amp;lt;pre&amp;gt;&amp;lt;code&amp;gt;curl https://get.acme.sh | sh&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;/pre&amp;gt;&amp;lt;div class=&amp;quot;tip&amp;quot;&amp;gt;Der Hinweis, welcher besagt, dass socat installiert werden solle, kann ignoriert werden. Socat wird in unserem Fall nicht benötigt.&amp;lt;/div&amp;gt;&amp;lt;p&amp;gt;Nach der Installation muss das Shell-Profil neu geladen werden, damit das “acme.sh” Kommando verfügbar gemacht wird:&amp;lt;/p&amp;gt;&amp;lt;pre&amp;gt;&amp;lt;code&amp;gt;source ~/.profile&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;/pre&amp;gt;&amp;lt;p&amp;gt;Zertifikate beantragen und herunterladen:&amp;lt;/p&amp;gt;&amp;lt;pre&amp;gt;&amp;lt;code&amp;gt;acme.sh --issue --server letsencrypt --nginx \&lt;br /&gt;
    -d mail.mysystems.tld \&lt;br /&gt;
    -d imap.mysystems.tld \&lt;br /&gt;
    -d smtp.mysystems.tld&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;/pre&amp;gt;&amp;lt;p&amp;gt;Zertifikate installieren:&amp;lt;/p&amp;gt;&amp;lt;pre&amp;gt;&amp;lt;code&amp;gt;mkdir -p /etc/acme.sh/mail.mysystems.tld&lt;br /&gt;
acme.sh --install-cert -d mail.mysystems.tld \&lt;br /&gt;
    --key-file       /etc/acme.sh/mail.mysystems.tld/privkey.pem  \&lt;br /&gt;
    --fullchain-file /etc/acme.sh/mail.mysystems.tld/fullchain.pem \&lt;br /&gt;
    --reloadcmd     &amp;quot;systemctl reload nginx; systemctl restart dovecot; systemctl restart postfix;&amp;quot;&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;/pre&amp;gt;&amp;lt;p&amp;gt;Infolge unseres Reload-Commands wird Acme.sh versuchen, Dovecot und Postfix neu zu laden. Da beide Softwarepakete noch nicht installiert sind, werden euch Fehler angezeigt. Ihr könnt diese zum gegenwärtigen Zeitpunkt aber ignorieren.&amp;lt;/p&amp;gt;&amp;lt;p&amp;gt;Die vorher im Nginx auskommentierten Zeilen in &amp;lt;code&amp;gt;/etc/nginx/sites-available/mail.mysystems.tld&amp;lt;/code&amp;gt; können durch entfernen der Hashzeichen nun aktiviert und Nginx mittels&amp;lt;/p&amp;gt;&amp;lt;pre&amp;gt;&amp;lt;code&amp;gt;nginx -t&lt;br /&gt;
systemctl reload nginx&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;/pre&amp;gt;&amp;lt;p&amp;gt;getestet und neu gestartet werden.&amp;lt;/p&amp;gt;&amp;lt;p&amp;gt;Für die Autokonfiguration der Mailclients wird später noch ein Zertifikat für eine weitere Domain beantragt - doch das kann erst einmal warten.&amp;lt;/p&amp;gt;&amp;lt;p&amp;gt;Damit die automatische Zertifikatserneuerung funktioniert, wird noch der Cronjob für acme.sh aktiviert:&amp;lt;/p&amp;gt;&amp;lt;pre&amp;gt;&amp;lt;code&amp;gt; acme.sh --install-cronjob&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;/pre&amp;gt;&lt;br /&gt;
== MySQL Datenbank einrichten ==&lt;br /&gt;
&amp;lt;p&amp;gt;Informationen über zu verwaltende Domains, Benutzer, Weiterleitungen und sonstige Einstellungen soll der Mailserver aus einer MySQL-Datenbank ziehen. Das hat den Vorteil, dass der Server im laufenden Betrieb flexibel angepasst werden kann, ohne die Konfigurationsdateien ändern zu müssen. Die Datenbank ermöglicht uns außerdem ein virtualisiertes Mailserver-Setup: Die Benutzer auf den Mailservern müssen nicht mehr als reale Linux-Benutzer im System registriert sein, sondern nur noch in der Datenbank eingetragen werden.&amp;lt;/p&amp;gt;&amp;lt;p&amp;gt;Als DBMS wird die neue Debian-Standard-MySQL-Datenbank “MariaDB” installiert:&amp;lt;/p&amp;gt;&amp;lt;pre&amp;gt;&amp;lt;code&amp;gt;apt install mariadb-server&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;/pre&amp;gt;&amp;lt;p&amp;gt;Nach der Installation sollte MariaDB bereits gestartet sein. Den Status könnt ihr mittels &amp;lt;code&amp;gt;systemctl status mysql&amp;lt;/code&amp;gt;(nicht “mariadb!&amp;quot;) überprüfen. Falls das nicht der Fall ist, startet den Datenbankserver: &amp;lt;code&amp;gt;systemctl start mysql&amp;lt;/code&amp;gt;.&amp;lt;/p&amp;gt;&amp;lt;p&amp;gt;Standardmäßig kann sich nur der root-Systemuser am Datenbankserver anmelden. Authentifiziert wird er dabei automatisch via PAM, sodass keine zusätzliche Passworteingabe notwendig ist. Die einfache Eingabe von&amp;lt;/p&amp;gt;&amp;lt;pre&amp;gt;&amp;lt;code&amp;gt;mysql&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;/pre&amp;gt;&amp;lt;p&amp;gt;bringt euch in eine MySQL Root Shell. Über diese werden nun ein paar SQL-Befehle ausgeführt.&amp;lt;/p&amp;gt;&amp;lt;p&amp;gt;Ein SQL-Kommando endet immer mit einem Semikolon &amp;lt;code&amp;gt;;&amp;lt;/code&amp;gt;. Mehrzeilige Befehle könnt ihr ohne weiteres einfach mit ENTER umbrechen, so wie sie im Folgenden dargestellt werden. Achtet auf den Unterschied zwischen “Tick” (&amp;lt;code&amp;gt;'&amp;lt;/code&amp;gt;) und “Backtick” (&amp;lt;code&amp;gt; \&amp;lt;/code&amp;gt; `) – der Backtick wird mit Shift + 2x Accent-Taste erzeugt. Kopiert die SQL-Statements am besten direkt in eure Zwischenanlage, statt sie mühsam abzutippen.&amp;lt;/p&amp;gt;&amp;lt;p&amp;gt;Im ersten Schritt wird eine neue Datenbank “vmail” angelegt.&amp;lt;/p&amp;gt;&amp;lt;pre&amp;gt;&amp;lt;code&amp;gt;create database vmail&lt;br /&gt;
    CHARACTER SET 'utf8';&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;/pre&amp;gt;&amp;lt;p&amp;gt;Ein neuer DB-User &amp;lt;code&amp;gt;vmail&amp;lt;/code&amp;gt; mit dem Passwort &amp;lt;code&amp;gt;vmaildbpass&amp;lt;/code&amp;gt; bekommt Zugriff auf diese neue Datenbank ''(Wählt ein eigenes Passwort statt “vmaildbpass”!)'':&amp;lt;/p&amp;gt;&amp;lt;div class=&amp;quot;warning&amp;quot;&amp;gt;Nutzt für &amp;lt;code&amp;gt;vmaildbpass&amp;lt;/code&amp;gt; nur die Zeichen 0-9 a-z und A-z. Einigen Berichten nach können Sonderzeichen zu Problemen führen.&amp;lt;/div&amp;gt;&amp;lt;pre&amp;gt;&amp;lt;code&amp;gt;grant select on vmail.* to 'vmail'@'localhost' identified by 'vmaildbpass';&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;/pre&amp;gt;&amp;lt;p&amp;gt;Alle weiteren Kommandos zu Erstellung der Datenbank-Tabellen sollen sich auf die eben erzeugte Datenbank beziehen:&amp;lt;/p&amp;gt;&amp;lt;pre&amp;gt;&amp;lt;code&amp;gt;use vmail;&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;/pre&amp;gt;&amp;lt;p&amp;gt;Das Mail-Setup soll 4 verschiedene Tabellen nutzen. Kopiert die SQL-Statements einzeln und nacheinander in die MySQL-Kommandozeile und bestätigt jedes mal mit [Enter]. Anpassungen sind nicht notwendig.&amp;lt;/p&amp;gt;&lt;br /&gt;
=== Domain-Tabelle ===&lt;br /&gt;
&amp;lt;p&amp;gt;Die Domain-Tabelle enthält alle Domains, die mit dem Mailserver genutzt werden sollen.&amp;lt;/p&amp;gt;&amp;lt;pre&amp;gt;&amp;lt;code&amp;gt;CREATE TABLE `domains` (&lt;br /&gt;
    `id` int unsigned NOT NULL AUTO_INCREMENT,&lt;br /&gt;
    `domain` varchar(255) NOT NULL,&lt;br /&gt;
    PRIMARY KEY (`id`),&lt;br /&gt;
    UNIQUE KEY (`domain`)&lt;br /&gt;
);&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;/pre&amp;gt;&lt;br /&gt;
=== Account-Tabelle ===&lt;br /&gt;
&amp;lt;pre&amp;gt;&amp;lt;code&amp;gt;CREATE TABLE `accounts` (&lt;br /&gt;
    `id` int unsigned NOT NULL AUTO_INCREMENT,&lt;br /&gt;
    `username` varchar(64) NOT NULL,&lt;br /&gt;
    `domain` varchar(255) NOT NULL,&lt;br /&gt;
    `password` varchar(255) NOT NULL,&lt;br /&gt;
    `quota` int unsigned DEFAULT '0',&lt;br /&gt;
    `enabled` boolean DEFAULT '0',&lt;br /&gt;
    `sendonly` boolean DEFAULT '0',&lt;br /&gt;
    PRIMARY KEY (id),&lt;br /&gt;
    UNIQUE KEY (`username`, `domain`),&lt;br /&gt;
    FOREIGN KEY (`domain`) REFERENCES `domains` (`domain`)&lt;br /&gt;
);&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;/pre&amp;gt;&amp;lt;p&amp;gt;Die Account-Tabelle enthält alle Mailserver-Accounts. Das Feld “quota” enthält die Volumenbegrenzung für die Mailbox in MB (Megabyte). Im Feld “enabled” wird über einen bool’schen Wert festgelegt, ob ein Account aktiv ist, oder nicht. So können einzelne User temporär deaktiviert werden, ohne gelöscht werden zu müssen. “sendonly” wird auf “true” gesetzt, wenn der Account nur zum Senden von E-Mails genutzt werden soll – nicht aber zum Empfang. Das kann beispielsweise für Foren- oder Blogsoftware sinnvoll sein, die mit ihrem Account nur E-Mails verschicken soll.&amp;lt;/p&amp;gt;&lt;br /&gt;
=== Alias-Tabelle ===&lt;br /&gt;
&amp;lt;pre&amp;gt;&amp;lt;code&amp;gt;CREATE TABLE `aliases` (&lt;br /&gt;
    `id` int unsigned NOT NULL AUTO_INCREMENT,&lt;br /&gt;
    `source_username` varchar(64),&lt;br /&gt;
    `source_domain` varchar(255) NOT NULL,&lt;br /&gt;
    `destination_username` varchar(64) NOT NULL,&lt;br /&gt;
    `destination_domain` varchar(255) NOT NULL,&lt;br /&gt;
    `enabled` boolean DEFAULT '0',&lt;br /&gt;
    PRIMARY KEY (`id`),&lt;br /&gt;
    UNIQUE KEY (`source_username`, `source_domain`, `destination_username`, `destination_domain`),&lt;br /&gt;
    FOREIGN KEY (`source_domain`) REFERENCES `domains` (`domain`)&lt;br /&gt;
);&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;/pre&amp;gt;&amp;lt;p&amp;gt;Die Alias-Tabelle enthält alle Weiterleitungen / Aliase und ist eigentlich selbsterklärend. Zur temporären Deaktivierung von Weiterleitungsadressen gibt es wieder ein “enabled”-Feld.&amp;lt;/p&amp;gt;&lt;br /&gt;
=== TLS Policy-Tabelle ===&lt;br /&gt;
&amp;lt;pre&amp;gt;&amp;lt;code&amp;gt;CREATE TABLE `tlspolicies` (&lt;br /&gt;
    `id` int unsigned NOT NULL AUTO_INCREMENT,&lt;br /&gt;
    `domain` varchar(255) NOT NULL,&lt;br /&gt;
    `policy` enum('none', 'may', 'encrypt', 'dane', 'dane-only', 'fingerprint', 'verify', 'secure') NOT NULL,&lt;br /&gt;
    `params` varchar(255),&lt;br /&gt;
    PRIMARY KEY (`id`),&lt;br /&gt;
    UNIQUE KEY (`domain`)&lt;br /&gt;
);&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;/pre&amp;gt;&amp;lt;p&amp;gt;Mithilfe der TLS Policy Tabelle kann festgelegt werden, für welche Empfängerdomains bestimmte Sicherheitsbeschränkungen beim Mailtransport gelten sollen. Für einzelne Domains, z.B. “gmx.de” kann beispielsweise angegeben werden, dass diese E-Mails nur noch verschlüsselt übertragen werden dürfen. Mehr dazu später.&amp;lt;/p&amp;gt;&amp;lt;p&amp;gt;Die Datenbank wird mit Datensätzen befüllt, sobald die Server fertig konfiguriert sind. Bis dahin könnt ihr die MySQL-Kommandozeile mit &amp;lt;code&amp;gt;quit;&amp;lt;/code&amp;gt; verlassen.&amp;lt;/p&amp;gt;&lt;br /&gt;
== vmail-Benutzer und -Verzeichnis einrichten ==&lt;br /&gt;
&amp;lt;p&amp;gt;Alle Mailboxen werden direkt im Dateisystem des Debian Servers abgelegt. Für die Zugriffe auf die Mailbox-Verzeichnisse wird ein eigener Benutzer “vmail” (“Virtual Mail”) erstellt, unter dem die Zugriffe von Dovecot und anderen Komponenten des Mailservers geschehen sollen. Einerseits wird so verhindert, dass Mailserver-Komponenten auf sensible Systemverzeichnisse Zugriff bekommen, andererseits können wir so die Mailboxen vor dem Zugriff von außen schützen. Nur vmail (und root) dürfen auf die Mailboxen zugreifen.&amp;lt;/p&amp;gt;&amp;lt;p&amp;gt;Das Verzeichnis &amp;lt;code&amp;gt;/var/vmail/&amp;lt;/code&amp;gt; soll alle Mailserver-relevanten Dateien (also Mailboxen und Filterscripts) enthalten und wird für den vmail-User als Home Directory festgelegt.&amp;lt;/p&amp;gt;&amp;lt;p&amp;gt;vmail-Benutzer erstellen:&amp;lt;/p&amp;gt;&amp;lt;pre&amp;gt;&amp;lt;code&amp;gt;useradd --create-home --home-dir /var/vmail --user-group --shell /usr/sbin/nologin vmail&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;/pre&amp;gt;&amp;lt;p&amp;gt;vmail Unterverzeichnisse erstellen:&amp;lt;/p&amp;gt;&amp;lt;pre&amp;gt;&amp;lt;code&amp;gt;mkdir /var/vmail/mailboxes&lt;br /&gt;
mkdir -p /var/vmail/sieve/global&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;/pre&amp;gt;&amp;lt;p&amp;gt;Verzeichnis &amp;lt;code&amp;gt;/var/vmail&amp;lt;/code&amp;gt; rekursiv an vmail-User übereignen und Verzeichnisrechte passend setzen:&amp;lt;/p&amp;gt;&amp;lt;pre&amp;gt;&amp;lt;code&amp;gt;chown -R vmail /var/vmail&lt;br /&gt;
chgrp -R vmail /var/vmail&lt;br /&gt;
chmod -R 770 /var/vmail&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;/pre&amp;gt;&lt;br /&gt;
== Dovecot installieren und konfigurieren ==&lt;br /&gt;
&amp;lt;p&amp;gt;Nachdem die Datenbank und der vmail-User angelegt wurden, widmen wir uns nun dem Dovecot-Server. Wie bereits erwähnt, verwaltet dieser Server die Mailboxen und bekommt daher (in der Gestalt des vmail-Users) exklusiv Zugriff auf &amp;lt;code&amp;gt;/var/vmail/&amp;lt;/code&amp;gt;. Zuerst müssen jedoch alle Serverkomponenten installiert werden:&amp;lt;/p&amp;gt;&amp;lt;pre&amp;gt;&amp;lt;code&amp;gt;apt install dovecot-core dovecot-imapd dovecot-lmtpd dovecot-mysql dovecot-sieve dovecot-managesieved&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;/pre&amp;gt;&lt;br /&gt;
*&amp;lt;code&amp;gt;dovecot-core&amp;lt;/code&amp;gt;: Dovecot-Kern&lt;br /&gt;
*&amp;lt;code&amp;gt;dovecot-imapd&amp;lt;/code&amp;gt;: Fügt IMAP-Funktionalität hinzu&lt;br /&gt;
*&amp;lt;code&amp;gt;dovecot-lmtp&amp;lt;/code&amp;gt;: Fügt LMTP (Local Mail Transfer Protocol)-Funktionalität hinzu; LMTP wird als MTP-Protokoll zwischen Postfix und Dovecot genutzt&lt;br /&gt;
*&amp;lt;code&amp;gt;dovecot-mysql&amp;lt;/code&amp;gt;: Lässt Dovecot mit der MySQL-Datenbank zusammenarbeiten&lt;br /&gt;
*&amp;lt;code&amp;gt;dovecot-sieve&amp;lt;/code&amp;gt;: Fügt Filterfunktionalität hinzu&lt;br /&gt;
*&amp;lt;code&amp;gt;dovecot-managesieved&amp;lt;/code&amp;gt;: Stellt eine Schnittstelle zur Einrichtung der Filter via Mailclient bereit&lt;br /&gt;
&amp;lt;p&amp;gt;Nach der Installation wird Dovecot automatisch gestartet. Beendet Dovecot, solange wir keine fertige Konfiguration haben:&amp;lt;/p&amp;gt;&amp;lt;pre&amp;gt;&amp;lt;code&amp;gt;systemctl stop dovecot&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;/pre&amp;gt;&amp;lt;p&amp;gt;Nun geht es an die Konfiguration. Die Dovecot-Konfigurationsdateien liegen im Verzeichnis &amp;lt;code&amp;gt;/etc/dovecot/&amp;lt;/code&amp;gt;. Dort könnt ihr schon einige Konfigurationen sehen, die bei der Installation angelegt wurden. Wir werden die Konfiguration von Grund auf neu aufsetzen - deshalb wird zuerst einmal die gesamte Dovecot-Konfiguration gelöscht:&amp;lt;/p&amp;gt;&amp;lt;pre&amp;gt;&amp;lt;code&amp;gt;rm -r /etc/dovecot/*&lt;br /&gt;
cd /etc/dovecot&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;/pre&amp;gt;&amp;lt;p&amp;gt;Für Dovecot reichen die folgenden zwei Konfigurationsdateien (&amp;lt;code&amp;gt;dovecot.conf&amp;lt;/code&amp;gt; und &amp;lt;code&amp;gt;dovecot-sql.conf&amp;lt;/code&amp;gt;) aus. Erstellt die beiden Dateien im Verzeichnis &amp;lt;code&amp;gt;/etc/dovecot/&amp;lt;/code&amp;gt;.&amp;lt;/p&amp;gt;&lt;br /&gt;
=== Hauptkonfigurationsdatei &amp;lt;code&amp;gt;/etc/dovecot/dovecot.conf&amp;lt;/code&amp;gt; ===&lt;br /&gt;
&amp;lt;pre&amp;gt;&amp;lt;code&amp;gt;##&lt;br /&gt;
## Aktivierte Protokolle&lt;br /&gt;
##&lt;br /&gt;
&lt;br /&gt;
protocols = imap lmtp sieve &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
##&lt;br /&gt;
## TLS Config&lt;br /&gt;
## Quelle: https://ssl-config.mozilla.org/#server=dovecot&amp;amp;version=2.3.9&amp;amp;config=intermediate&amp;amp;openssl=1.1.1d&amp;amp;guideline=5.4&lt;br /&gt;
##&lt;br /&gt;
&lt;br /&gt;
ssl = required&lt;br /&gt;
ssl_cert = &amp;amp;lt;/etc/acme.sh/mail.mysystems.tld/fullchain.pem&lt;br /&gt;
ssl_key = &amp;amp;lt;/etc/acme.sh/mail.mysystems.tld/privkey.pem&lt;br /&gt;
ssl_dh = &amp;amp;lt;/etc/dovecot/dh4096.pem&lt;br /&gt;
ssl_min_protocol = TLSv1.2&lt;br /&gt;
ssl_cipher_list = ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384&lt;br /&gt;
ssl_prefer_server_ciphers = no&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
##&lt;br /&gt;
## Dovecot services&lt;br /&gt;
##&lt;br /&gt;
&lt;br /&gt;
service imap-login {&lt;br /&gt;
    inet_listener imap {&lt;br /&gt;
        port = 143&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
service managesieve-login {&lt;br /&gt;
    inet_listener sieve {&lt;br /&gt;
        port = 4190&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
service lmtp {&lt;br /&gt;
    unix_listener /var/spool/postfix/private/dovecot-lmtp {&lt;br /&gt;
        mode = 0660&lt;br /&gt;
        group = postfix&lt;br /&gt;
        user = postfix&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    user = vmail&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
service auth {&lt;br /&gt;
    ### Auth socket für Postfix&lt;br /&gt;
    unix_listener /var/spool/postfix/private/auth {&lt;br /&gt;
        mode = 0660&lt;br /&gt;
        user = postfix&lt;br /&gt;
        group = postfix&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    ### Auth socket für LMTP-Dienst&lt;br /&gt;
    unix_listener auth-userdb {&lt;br /&gt;
        mode = 0660&lt;br /&gt;
        user = vmail&lt;br /&gt;
        group = vmail&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
##&lt;br /&gt;
##  Protocol settings&lt;br /&gt;
##&lt;br /&gt;
&lt;br /&gt;
protocol imap {&lt;br /&gt;
    mail_plugins = $mail_plugins quota imap_quota imap_sieve&lt;br /&gt;
    mail_max_userip_connections = 20&lt;br /&gt;
    imap_idle_notify_interval = 29 mins&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
protocol lmtp {&lt;br /&gt;
    postmaster_address = postmaster@mysystems.tld&lt;br /&gt;
    mail_plugins = $mail_plugins sieve notify push_notification&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
##&lt;br /&gt;
## Client authentication&lt;br /&gt;
##&lt;br /&gt;
&lt;br /&gt;
disable_plaintext_auth = yes&lt;br /&gt;
auth_mechanisms = plain login&lt;br /&gt;
auth_username_format = %Lu&lt;br /&gt;
&lt;br /&gt;
passdb {&lt;br /&gt;
    driver = sql&lt;br /&gt;
    args = /etc/dovecot/dovecot-sql.conf&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
userdb {&lt;br /&gt;
    driver = sql&lt;br /&gt;
    args = /etc/dovecot/dovecot-sql.conf&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
##&lt;br /&gt;
## Address tagging&lt;br /&gt;
##&lt;br /&gt;
recipient_delimiter = +&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
##&lt;br /&gt;
## Mail location&lt;br /&gt;
##&lt;br /&gt;
&lt;br /&gt;
mail_uid = vmail&lt;br /&gt;
mail_gid = vmail&lt;br /&gt;
mail_privileged_group = vmail&lt;br /&gt;
&lt;br /&gt;
mail_home = /var/vmail/mailboxes/%d/%n&lt;br /&gt;
mail_location = maildir:~/mail:LAYOUT=fs&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
##&lt;br /&gt;
## Mailbox configuration&lt;br /&gt;
##&lt;br /&gt;
&lt;br /&gt;
namespace inbox {&lt;br /&gt;
    inbox = yes&lt;br /&gt;
&lt;br /&gt;
    mailbox Spam {&lt;br /&gt;
        auto = subscribe&lt;br /&gt;
        special_use = \Junk&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    mailbox Trash {&lt;br /&gt;
        auto = subscribe&lt;br /&gt;
        special_use = \Trash&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    mailbox Drafts {&lt;br /&gt;
        auto = subscribe&lt;br /&gt;
        special_use = \Drafts&lt;br /&gt;
    }&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;
&lt;br /&gt;
##&lt;br /&gt;
## Mail plugins&lt;br /&gt;
##&lt;br /&gt;
&lt;br /&gt;
plugin {&lt;br /&gt;
    sieve_plugins = sieve_imapsieve sieve_extprograms&lt;br /&gt;
    sieve_before = /var/vmail/sieve/global/spam-global.sieve&lt;br /&gt;
    sieve = file:/var/vmail/sieve/%d/%n/scripts;active=/var/vmail/sieve/%d/%n/active-script.sieve&lt;br /&gt;
&lt;br /&gt;
    ###&lt;br /&gt;
    ### Spam learning&lt;br /&gt;
    ###&lt;br /&gt;
    # From elsewhere to Spam folder&lt;br /&gt;
    imapsieve_mailbox1_name = Spam&lt;br /&gt;
    imapsieve_mailbox1_causes = COPY&lt;br /&gt;
    imapsieve_mailbox1_before = file:/var/vmail/sieve/global/learn-spam.sieve&lt;br /&gt;
&lt;br /&gt;
    # From Spam folder to elsewhere&lt;br /&gt;
    imapsieve_mailbox2_name = *&lt;br /&gt;
    imapsieve_mailbox2_from = Spam&lt;br /&gt;
    imapsieve_mailbox2_causes = COPY&lt;br /&gt;
    imapsieve_mailbox2_before = file:/var/vmail/sieve/global/learn-ham.sieve&lt;br /&gt;
&lt;br /&gt;
    sieve_pipe_bin_dir = /usr/bin&lt;br /&gt;
    sieve_global_extensions = +vnd.dovecot.pipe&lt;br /&gt;
&lt;br /&gt;
    quota = maildir:User quota&lt;br /&gt;
    quota_exceeded_message = Benutzer %u hat das Speichervolumen überschritten. / User %u has exhausted allowed storage space.&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;/pre&amp;gt;&amp;lt;p&amp;gt;Anzupassende Stellen:&amp;lt;/p&amp;gt;&lt;br /&gt;
*&amp;lt;code&amp;gt;ssl_cert&amp;lt;/code&amp;gt;: Pfad zur Zertifikatsdatei&lt;br /&gt;
*&amp;lt;code&amp;gt;ssl_key&amp;lt;/code&amp;gt;: Pfad zur Zertifikatsdatei&lt;br /&gt;
*&amp;lt;code&amp;gt;postmaster_address&amp;lt;/code&amp;gt;: Domain anpassen&lt;br /&gt;
&lt;br /&gt;
==== Erklärung ====&lt;br /&gt;
&amp;lt;p&amp;gt;&amp;lt;code&amp;gt;dovecot.conf&amp;lt;/code&amp;gt; ist die Hauptkonfigurationsdatei des Dovecot-Servers:&amp;lt;/p&amp;gt;&amp;lt;p&amp;gt;'''Dovecot Services:''' Im darauf folgenden Abschnitt werden die Dovecot Services konfiguriert. Dazu gehört z.B. der Dienst “imap-login”, der auf eingehende Verbindungen von E-Mail Clients auf Port 143 horcht. Auch “managesieve-login” kommuniziert mit dem Mailclient, wenn dieser eine Funktion zur Bearbeitung Server-seitiger Filterscripte mitbringt. Die anderen Dienste werden intern genutzt: Der lmtp-Dienst stellt eine Schnittstelle bereit, über die Postfix empfangene Mails an die Mailbox übergeben kann. Der “auth” Dienst wird vom LMTP-Dienst genutzt, um die Existenz von Benutzern zu überprüfen, aber auch von Postfix, um den Login am Postfix-Server zu überprüfen. Mit “mode”, “user” und “group” wird bestimmt, welcher Systemuser Zugriff auf den Dienst haben soll (Analog zu den Dateirechten – der Socket für den Dienst ist nichts anderes als eine Datei).&amp;lt;/p&amp;gt;&amp;lt;p&amp;gt;'''Protocol settings:''' Für die verwendeten Protokolle können zusätzliche Einstellungen gesetzt werden – u.A. auch, welche Erweiterungen im Zusammenhang mit dem Protokoll genutzt werden sollen. “quota” und “imap_quota” sind notwendig, um das maximale Volumen einer Mailbox festsetzen zu können. Beim lmtp-Protokoll kann auf diese Erweiterungen verzichtet werden: Hier wird nur die Sieve-Erweiterung zum Filtern von E-Mails benötigt.&amp;lt;/p&amp;gt;&amp;lt;p&amp;gt;'''Client Authentication:''' Die Zeilen&amp;lt;/p&amp;gt;&amp;lt;pre&amp;gt;&amp;lt;code&amp;gt;disable_plaintext_auth = yes&lt;br /&gt;
auth_mechanisms = plain login&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;/pre&amp;gt;&amp;lt;p&amp;gt;scheinen sich zu widersprechen, schließlich wird die Klartext-Authentifizierung abgeschaltet. Doch tatsächlich wird sie das nur für unverschlüsselte Verbindungen. TLS-Verschlüsselte Verbindungen bleiben davon unberührt, sodass in der nächsten Zeile die “plain” Authentifizierung mit Klartext-Passwörtern wieder angeboten werden kann. Das wird aus zwei Gründen getan:&amp;lt;/p&amp;gt;&lt;br /&gt;
*“Klartext” tut uns hier nicht weh – schließlich ist die Verbindung sowieso (zwingend) verschlüsselt.&lt;br /&gt;
*Alle Mailclients unterstützen die Klartextauthentifizierung. Andere Loginmechanismen werden weniger gut unterstützt und sind aufwendiger.&lt;br /&gt;
&amp;lt;p&amp;gt;Wir konzentrieren uns deshalb auf die klassische Klartextauthentifizierung. Wie bereits erwähnt: Da unsere Verbindung ohnehin verschlüsselt ist, ist das in diesem Fall nicht sicherheitsrelevant.&amp;lt;/p&amp;gt;&amp;lt;p&amp;gt;Für &amp;lt;code&amp;gt;passdb&amp;lt;/code&amp;gt; und &amp;lt;code&amp;gt;userdb&amp;lt;/code&amp;gt; wird jeweils der Pfad zur SQL-Datei eingestellt. Dort befindt sich jeweils eine passende SQL-Query. Die “passdb” wird befragt, wenn es um die Authentifizierung von Usern geht, die “userdb”, wenn die Existenz eines bestimmten E-Mail Kontos überprüft werden soll, oder benutzerdefinierte Einstellungen geladen werden müssen, wie z.B. das Mailbox-Kontingent (“Quota”).&amp;lt;/p&amp;gt;&amp;lt;p&amp;gt;'''Mail location:''' In diesem Abschnitt wird definiert, unter welchem Systemuser Dovecot auf Dateisystem-Ebene mit E-Mails hantieren soll. Außerdem wird ein Pfad-Schema festgelegt, das bestimmt, nach welcher Struktur die Mailbox-Verzeichnisse angelegt werden sollen. %d steht für die Domain des Accounts und %n für den Benutzernamen vor dem @. Der Pfad zu einer Benutzermailbox lautet z.B.: &amp;lt;code&amp;gt;/var/vmail/mailboxes/mysystems.tld/admin/mail/&amp;lt;/code&amp;gt;&amp;lt;/p&amp;gt;&amp;lt;p&amp;gt;'''Mailbox Configuration:''' In der Mailbox eines jeden Users soll sich standardmäßig ein “Spam”-Ordner befinden, in die ein passendes Sieve-Filterskript verdächtige E-Mails verschieben soll.&amp;lt;/p&amp;gt;&amp;lt;p&amp;gt;'''Mail Plugins:''' Hier werden die Details zu den Erweiterungen &amp;lt;code&amp;gt;sieve&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;quota&amp;lt;/code&amp;gt; und &amp;lt;code&amp;gt;imapsieve&amp;lt;/code&amp;gt; definiert. Das Script unter &amp;lt;code&amp;gt;sieve_before&amp;lt;/code&amp;gt; wird für alle User (unabhängig von den eigenen Einstellungen) immer ausgeführt. Es hat die Aufgabe, durch Rspamd markierte Mails in den Spam-Ordner zu verschieben. &amp;lt;code&amp;gt;sieve_dir&amp;lt;/code&amp;gt; definiert das Schema für den Ort, an dem benutzerdefinierte Scripts abgelegt werden. Das aktive Skript eines Nutzers soll jeweils über den symbolischen Link &amp;lt;code&amp;gt;active-script.sieve&amp;lt;/code&amp;gt; zugänglich sein. Die &amp;lt;code&amp;gt;imapsieve&amp;lt;/code&amp;gt; Einstellungen lassen den IMAP-Server Verschiebevorgängezwischen Mailbox-Ordnern erkennen, sodass Rspamd aus einer Neuordnung lernen kann.&amp;lt;/p&amp;gt;&lt;br /&gt;
=== Diffie-Hellman Parameter für Dovecot generieren ===&lt;br /&gt;
&amp;lt;p&amp;gt;In neueren Versionen generiert Dovecot die Diffie-Hellman-Parameter für TLS-Verbindungen nicht mehr selbst. Also müssen wir selbst Hand anlegen und die Parameter mittels OpenSSL-Tool generieren lassen:&amp;lt;/p&amp;gt;&amp;lt;pre&amp;gt;&amp;lt;code&amp;gt;openssl dhparam -out /etc/dovecot/dh4096.pem 4096 &lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;/pre&amp;gt;&amp;lt;p&amp;gt;Das kann je nach Auslastung des Mailservers durchaus eine viertel Stunde oder länger dauern. Um den Vorhang zu beschleunigen, kann ein sog. Entropy Harvester wie z.B. &amp;lt;code&amp;gt;haveged&amp;lt;/code&amp;gt; installiert werden (&amp;lt;code&amp;gt;apt install haveged&amp;lt;/code&amp;gt;).&amp;lt;/p&amp;gt;&lt;br /&gt;
=== SQL-Konfgurationsdatei &amp;lt;code&amp;gt;/etc/dovecot/dovecot-sql.conf&amp;lt;/code&amp;gt; ===&lt;br /&gt;
&amp;lt;pre&amp;gt;&amp;lt;code&amp;gt;driver=mysql&lt;br /&gt;
connect = &amp;quot;host=localhost dbname=vmail user=vmail password=vmaildbpass&amp;quot;&lt;br /&gt;
default_pass_scheme = SHA512-CRYPT&lt;br /&gt;
&lt;br /&gt;
password_query = SELECT username AS user, domain, password FROM accounts WHERE username = '%Ln' AND domain = '%Ld' and enabled = true;&lt;br /&gt;
user_query = SELECT concat('*:storage=', quota, 'M') AS quota_rule FROM accounts WHERE username = '%Ln' AND domain = '%Ld' AND sendonly = false;&lt;br /&gt;
iterate_query = SELECT username, domain FROM accounts where sendonly = false;&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;/pre&amp;gt;&amp;lt;p&amp;gt;Anzupassende Stellen:&amp;lt;/p&amp;gt;&lt;br /&gt;
*Datenbankpasswort “vmaildbpass”&lt;br /&gt;
&amp;lt;p&amp;gt;&amp;lt;code&amp;gt;dovecot-sql.conf&amp;lt;/code&amp;gt; enthält sensible Datenbank-Zugangsdaten und wird deshalb geschützt:&amp;lt;/p&amp;gt;&amp;lt;pre&amp;gt;&amp;lt;code&amp;gt;chmod 440 dovecot-sql.conf&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;/pre&amp;gt;&lt;br /&gt;
==== Erklärung ====&lt;br /&gt;
&amp;lt;p&amp;gt;Die Konfigurationsdatei &amp;lt;code&amp;gt;dovecot-sql.conf&amp;lt;/code&amp;gt; enthält alle SQL-relevanten Einstellungen:&amp;lt;/p&amp;gt;&lt;br /&gt;
*&amp;lt;code&amp;gt;driver&amp;lt;/code&amp;gt;: Welcher Datenbank-Treiber soll genutzt werden?&lt;br /&gt;
*&amp;lt;code&amp;gt;connect&amp;lt;/code&amp;gt;: Informationen zur Datenbankverbindung&lt;br /&gt;
*&amp;lt;code&amp;gt;default_pass_scheme&amp;lt;/code&amp;gt;: Standardmäßig angenommenes Hash-Schema, wenn es in der Datenbank nicht explizit angegeben ist, z.B. mit vorangestelltem {SHA512-CRYPT}.&lt;br /&gt;
*&amp;lt;code&amp;gt;password_query&amp;lt;/code&amp;gt;: SQL Query für die Überprüfung des User-Logins. Stimmen Benutzername und Passwort überein? Existiert der Benutzer und ist er aktiviert?&lt;br /&gt;
*&amp;lt;code&amp;gt;user_query&amp;lt;/code&amp;gt;: SQL-Query zum Abholen aller Benutzer-spezifischen Einstellungen. In diesem Fall: Maximales Mailbox-Volumen (“Quota”).&lt;br /&gt;
*&amp;lt;code&amp;gt;iterate_query&amp;lt;/code&amp;gt;: SQL-Query zur Abfrage aller verfügbarer Benutzer. Benutzer, die keine Mails empfangen können (sendonly=true) sind für Dovecot nicht interessant und werden nicht mit ausgegeben.&lt;br /&gt;
&lt;br /&gt;
=== Globales Sieve-Filterscript für Spam ===&lt;br /&gt;
&amp;lt;p&amp;gt;Unter &amp;lt;code&amp;gt;/var/vmail/sieve/global/&amp;lt;/code&amp;gt; wird das Sieve-Filterscript &amp;lt;code&amp;gt;spam-global.sieve&amp;lt;/code&amp;gt; erstellt, das erkannte Spammails in den Unterordner “Spam” jeder Mailbox einsortiert. Rspamd markiert erkannte E-Mails mit einem speziellen Spam-Header, den das Script erkennt. Inhalt von &amp;lt;code&amp;gt;spam-global.sieve&amp;lt;/code&amp;gt;:&amp;lt;/p&amp;gt;&amp;lt;pre&amp;gt;&amp;lt;code&amp;gt;require &amp;quot;fileinto&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
if header :contains &amp;quot;X-Spam-Flag&amp;quot; &amp;quot;YES&amp;quot; {&lt;br /&gt;
    fileinto &amp;quot;Spam&amp;quot;;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
if header :is &amp;quot;X-Spam&amp;quot; &amp;quot;Yes&amp;quot; {&lt;br /&gt;
    fileinto &amp;quot;Spam&amp;quot;;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;/pre&amp;gt;&lt;br /&gt;
=== Spam Learning mit Rspamd ===&lt;br /&gt;
&amp;lt;p&amp;gt;Beim Verschieben von Spammails in den Spam-Ordner bzw. dem Herausverschieben falsch beurteilter Mails in den Posteingang soll ein Lernprozess von Rspamd ausgelöst werden, sodass der Filter aus falschen Einschätzungen lernt und so mit der Zeit immer besser wird.&amp;lt;/p&amp;gt;&amp;lt;p&amp;gt;Dazu werden zwei Sieve-Scripts in &amp;lt;code&amp;gt;/var/vmail/sieve/global/&amp;lt;/code&amp;gt; angelegt:&amp;lt;/p&amp;gt;&amp;lt;p&amp;gt;&amp;lt;code&amp;gt;learn-spam.sieve&amp;lt;/code&amp;gt;&amp;lt;/p&amp;gt;&amp;lt;pre&amp;gt;&amp;lt;code&amp;gt;require [&amp;quot;vnd.dovecot.pipe&amp;quot;, &amp;quot;copy&amp;quot;, &amp;quot;imapsieve&amp;quot;];&lt;br /&gt;
pipe :copy &amp;quot;rspamc&amp;quot; [&amp;quot;learn_spam&amp;quot;];&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;/pre&amp;gt;&amp;lt;p&amp;gt;&amp;lt;code&amp;gt;learn-ham.sieve&amp;lt;/code&amp;gt;&amp;lt;/p&amp;gt;&amp;lt;pre&amp;gt;&amp;lt;code&amp;gt;require [&amp;quot;vnd.dovecot.pipe&amp;quot;, &amp;quot;copy&amp;quot;, &amp;quot;imapsieve&amp;quot;, &amp;quot;environment&amp;quot;, &amp;quot;variables&amp;quot;];&lt;br /&gt;
&lt;br /&gt;
if environment :matches &amp;quot;imap.mailbox&amp;quot; &amp;quot;*&amp;quot; {&lt;br /&gt;
    set &amp;quot;mailbox&amp;quot; &amp;quot;${1}&amp;quot;;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
if string &amp;quot;${mailbox}&amp;quot; &amp;quot;Trash&amp;quot; {&lt;br /&gt;
    stop;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
pipe :copy &amp;quot;rspamc&amp;quot; [&amp;quot;learn_ham&amp;quot;];&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;/pre&amp;gt;&amp;lt;p&amp;gt;Das &amp;lt;code&amp;gt;learn-ham.sieve&amp;lt;/code&amp;gt; Script besitzt noch einen Check, der überprüft, ob eine E-Mail aus dem Spam in den Papierkorb verschoben wurde. In diesem Fall sollen die betroffenen Mails ja nicht wieder als “Ham” markiert werden, daher wird in so einem Fall die Ausführung des Lernvorgangs verhindert.&amp;lt;/p&amp;gt;&lt;br /&gt;
== Postfix installieren und konfigurieren ==&lt;br /&gt;
&amp;lt;p&amp;gt;Für unseren Postfix-Server benötigen wir nur zwei Pakete: Das Kernpaket &amp;lt;code&amp;gt;postfix&amp;lt;/code&amp;gt; und die Komponente &amp;lt;code&amp;gt;postfix-mysql&amp;lt;/code&amp;gt;, die Postfix mit der MySQL-Datenbank kommunizieren lässt.&amp;lt;/p&amp;gt;&amp;lt;pre&amp;gt;&amp;lt;code&amp;gt;apt install postfix postfix-mysql&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;/pre&amp;gt;&amp;lt;p&amp;gt;Während der Installation werdet ihr nach der “Allgemeinen Art der Konfiguration” gefragt. Wählt an dieser Stelle “Keine Konfiguration” und beendet den Postfix-Server wieder:&amp;lt;/p&amp;gt;&amp;lt;pre&amp;gt;&amp;lt;code&amp;gt;systemctl stop postfix&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;/pre&amp;gt;&amp;lt;p&amp;gt;Im Postfix-Konfigurationsverzeichnis &amp;lt;code&amp;gt;/etc/postfix&amp;lt;/code&amp;gt; befinden sich trotz unserer Wahl “Keine Konfiguration” ein paar Konfigurationsdateien, die zunächst entfernt werden:&amp;lt;/p&amp;gt;&amp;lt;pre&amp;gt;&amp;lt;code&amp;gt;cd /etc/postfix&lt;br /&gt;
rm -r sasl&lt;br /&gt;
rm master.cf main.cf.proto master.cf.proto&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;/pre&amp;gt;&amp;lt;p&amp;gt;Legt dann folgende Dateien im Verzeichnis &amp;lt;code&amp;gt;/etc/postfix&amp;lt;/code&amp;gt; an:&amp;lt;/p&amp;gt;&lt;br /&gt;
=== &amp;lt;code&amp;gt;/etc/postfix/main.cf&amp;lt;/code&amp;gt; ===&lt;br /&gt;
&amp;lt;pre&amp;gt;&amp;lt;code&amp;gt;##&lt;br /&gt;
## Netzwerkeinstellungen&lt;br /&gt;
##&lt;br /&gt;
&lt;br /&gt;
mynetworks = 127.0.0.0/8 [::ffff:127.0.0.0]/104 [::1]/128&lt;br /&gt;
inet_interfaces = 127.0.0.1, ::1, 203.0.113.1, 2001:db8::1&lt;br /&gt;
myhostname = mail.mysystems.tld&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
##&lt;br /&gt;
## Mail-Queue Einstellungen&lt;br /&gt;
##&lt;br /&gt;
&lt;br /&gt;
maximal_queue_lifetime = 1h&lt;br /&gt;
bounce_queue_lifetime = 1h&lt;br /&gt;
maximal_backoff_time = 15m&lt;br /&gt;
minimal_backoff_time = 5m&lt;br /&gt;
queue_run_delay = 5m&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
##&lt;br /&gt;
## TLS Einstellungen&lt;br /&gt;
## Quelle: https://ssl-config.mozilla.org/#server=postfix&amp;amp;version=3.4.8&amp;amp;config=intermediate&amp;amp;openssl=1.1.1d&amp;amp;guideline=5.4&lt;br /&gt;
##&lt;br /&gt;
&lt;br /&gt;
### Allgemein&lt;br /&gt;
tls_preempt_cipherlist = no&lt;br /&gt;
tls_ssl_options = NO_COMPRESSION&lt;br /&gt;
tls_medium_cipherlist = ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384&lt;br /&gt;
&lt;br /&gt;
### Ausgehende SMTP-Verbindungen (Postfix als Sender)&lt;br /&gt;
smtp_tls_security_level = dane&lt;br /&gt;
smtp_dns_support_level = dnssec&lt;br /&gt;
smtp_tls_policy_maps = proxy:mysql:/etc/postfix/sql/tls-policy.cf&lt;br /&gt;
smtp_tls_session_cache_database = btree:${data_directory}/smtp_scache&lt;br /&gt;
smtp_tls_ciphers = medium&lt;br /&gt;
smtp_tls_CAfile = /etc/ssl/certs/ca-certificates.crt&lt;br /&gt;
&lt;br /&gt;
### Eingehende SMTP-Verbindungen&lt;br /&gt;
smtpd_tls_security_level = may&lt;br /&gt;
smtpd_tls_auth_only = yes&lt;br /&gt;
smtpd_tls_ciphers = medium&lt;br /&gt;
smtpd_tls_mandatory_protocols = !SSLv2, !SSLv3, !TLSv1, !TLSv1.1&lt;br /&gt;
smtpd_tls_protocols = !SSLv2, !SSLv3, !TLSv1, !TLSv1.1&lt;br /&gt;
smtpd_tls_session_cache_database = btree:${data_directory}/smtpd_scache&lt;br /&gt;
smtpd_tls_cert_file=/etc/acme.sh/mail.mysystems.tld/fullchain.pem&lt;br /&gt;
smtpd_tls_key_file=/etc/acme.sh/mail.mysystems.tld/privkey.pem&lt;br /&gt;
smtpd_tls_dh1024_param_file = /etc/postfix/dh2048.pem&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
##&lt;br /&gt;
## Lokale Mailzustellung an Dovecot&lt;br /&gt;
##&lt;br /&gt;
&lt;br /&gt;
virtual_transport = lmtp:unix:private/dovecot-lmtp&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
##&lt;br /&gt;
## Spamfilter und DKIM-Signaturen via Rspamd&lt;br /&gt;
##&lt;br /&gt;
&lt;br /&gt;
smtpd_milters = inet:localhost:11332&lt;br /&gt;
non_smtpd_milters = inet:localhost:11332&lt;br /&gt;
milter_protocol = 6&lt;br /&gt;
milter_mail_macros =  i {mail_addr} {client_addr} {client_name} {auth_authen}&lt;br /&gt;
milter_default_action = accept&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
##&lt;br /&gt;
## Server Restrictions für Clients, Empfänger und Relaying&lt;br /&gt;
## (im Bezug auf S2S-Verbindungen. Mailclient-Verbindungen werden in master.cf im Submission-Bereich konfiguriert)&lt;br /&gt;
##&lt;br /&gt;
&lt;br /&gt;
### Bedingungen, damit Postfix als Relay arbeitet (für Clients)&lt;br /&gt;
smtpd_relay_restrictions =      reject_non_fqdn_recipient&lt;br /&gt;
                                reject_unknown_recipient_domain&lt;br /&gt;
                                permit_mynetworks&lt;br /&gt;
                                reject_unauth_destination&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
### Bedingungen, damit Postfix ankommende E-Mails als Empfängerserver entgegennimmt (zusätzlich zu relay-Bedingungen)&lt;br /&gt;
### check_recipient_access prüft, ob ein account sendonly ist&lt;br /&gt;
smtpd_recipient_restrictions = check_recipient_access proxy:mysql:/etc/postfix/sql/recipient-access.cf&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
### Bedingungen, die SMTP-Clients erfüllen müssen (sendende Server)&lt;br /&gt;
smtpd_client_restrictions =     permit_mynetworks&lt;br /&gt;
                                check_client_access hash:/etc/postfix/without_ptr&lt;br /&gt;
                                reject_unknown_client_hostname&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
### Wenn fremde Server eine Verbindung herstellen, müssen sie einen gültigen Hostnamen im HELO haben.&lt;br /&gt;
smtpd_helo_required = yes&lt;br /&gt;
smtpd_helo_restrictions =   permit_mynetworks&lt;br /&gt;
                            reject_invalid_helo_hostname&lt;br /&gt;
                            reject_non_fqdn_helo_hostname&lt;br /&gt;
                            reject_unknown_helo_hostname&lt;br /&gt;
&lt;br /&gt;
# Clients blockieren, wenn sie versuchen zu früh zu senden&lt;br /&gt;
smtpd_data_restrictions = reject_unauth_pipelining&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
##&lt;br /&gt;
## Restrictions für MUAs (Mail user agents)&lt;br /&gt;
##&lt;br /&gt;
&lt;br /&gt;
mua_relay_restrictions = reject_non_fqdn_recipient,reject_unknown_recipient_domain,permit_mynetworks,permit_sasl_authenticated,reject&lt;br /&gt;
mua_sender_restrictions = permit_mynetworks,reject_non_fqdn_sender,reject_sender_login_mismatch,permit_sasl_authenticated,reject&lt;br /&gt;
mua_client_restrictions = permit_mynetworks,permit_sasl_authenticated,reject&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
##&lt;br /&gt;
## MySQL Abfragen&lt;br /&gt;
##&lt;br /&gt;
&lt;br /&gt;
proxy_read_maps =       proxy:mysql:/etc/postfix/sql/aliases.cf&lt;br /&gt;
                        proxy:mysql:/etc/postfix/sql/accounts.cf&lt;br /&gt;
                        proxy:mysql:/etc/postfix/sql/domains.cf&lt;br /&gt;
                        proxy:mysql:/etc/postfix/sql/recipient-access.cf&lt;br /&gt;
                        proxy:mysql:/etc/postfix/sql/sender-login-maps.cf&lt;br /&gt;
                        proxy:mysql:/etc/postfix/sql/tls-policy.cf&lt;br /&gt;
&lt;br /&gt;
virtual_alias_maps = proxy:mysql:/etc/postfix/sql/aliases.cf&lt;br /&gt;
virtual_mailbox_maps = proxy:mysql:/etc/postfix/sql/accounts.cf&lt;br /&gt;
virtual_mailbox_domains = proxy:mysql:/etc/postfix/sql/domains.cf&lt;br /&gt;
local_recipient_maps = $virtual_mailbox_maps&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
##&lt;br /&gt;
## Sonstiges&lt;br /&gt;
##&lt;br /&gt;
&lt;br /&gt;
### Maximale Größe der gesamten Mailbox (soll von Dovecot festgelegt werden, 0 = unbegrenzt)&lt;br /&gt;
mailbox_size_limit = 0&lt;br /&gt;
&lt;br /&gt;
### Maximale Größe eingehender E-Mails in Bytes (50 MB)&lt;br /&gt;
message_size_limit = 52428800&lt;br /&gt;
&lt;br /&gt;
### Keine System-Benachrichtigung für Benutzer bei neuer E-Mail&lt;br /&gt;
biff = no&lt;br /&gt;
&lt;br /&gt;
### Nutzer müssen immer volle E-Mail Adresse angeben - nicht nur Hostname&lt;br /&gt;
append_dot_mydomain = no&lt;br /&gt;
&lt;br /&gt;
### Trenn-Zeichen für &amp;quot;Address Tagging&amp;quot;&lt;br /&gt;
recipient_delimiter = +&lt;br /&gt;
&lt;br /&gt;
### Keine Rückschlüsse auf benutzte Mailadressen zulassen&lt;br /&gt;
disable_vrfy_command = yes&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;/pre&amp;gt;&amp;lt;p&amp;gt;Anzupassen:&amp;lt;/p&amp;gt;&lt;br /&gt;
*&amp;lt;code&amp;gt;inet_interfaces&amp;lt;/code&amp;gt;: IP-Adressen &amp;lt;code&amp;gt;203.0.113.1, 2001:db8::1&amp;lt;/code&amp;gt; müssen durch eigene IPv4- (und optional IPv6)-Adresse ersetzt werden.&lt;br /&gt;
*&amp;lt;code&amp;gt;myhostname&amp;lt;/code&amp;gt;: Ersetzen durch eigenen Hostnamen&lt;br /&gt;
*&amp;lt;code&amp;gt;smtpd_tls_cert_file&amp;lt;/code&amp;gt;: Pfad zur Zertifikatsdatei&lt;br /&gt;
*&amp;lt;code&amp;gt;smtpd_tls_key_file&amp;lt;/code&amp;gt;: Pfad zur Zertifikatsdatei&lt;br /&gt;
&lt;br /&gt;
==== Diffie-Hellman-Parameter für Postfix generieren ====&lt;br /&gt;
&amp;lt;p&amp;gt;Neben Dovecot bekommt auch Postfix “von Hand generierte” DH-Parameter. Hier allerdings nur 2048 Bit starke, um zu älteren Mailservern kompatibel zu bleiben.&amp;lt;/p&amp;gt;&amp;lt;pre&amp;gt;&amp;lt;code&amp;gt;openssl dhparam -out /etc/postfix/dh2048.pem 2048&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;/pre&amp;gt;&amp;lt;p&amp;gt;Wundert euch übrigens nicht über das &amp;lt;code&amp;gt;1024&amp;lt;/code&amp;gt; in der Einstellung &amp;lt;code&amp;gt;smtpd_tls_dh1024_param_file&amp;lt;/code&amp;gt; - das ist nur Teil des Namens und hat keine Bedeutung für die Schlüssellänge.&amp;lt;/p&amp;gt;&amp;lt;div class=&amp;quot;warning&amp;quot;&amp;gt;&amp;lt;p&amp;gt;Wenn der Mailserver (entgegen meiner Empfehlung) nicht einen &amp;lt;code&amp;gt;mail.domain.tld&amp;lt;/code&amp;gt; Hostnamen hat, sondern unter dem Domainnamen läuft (&amp;lt;code&amp;gt;domain.tld&amp;lt;/code&amp;gt;), muss zur Konfiguration eine Zeile mit&amp;lt;/p&amp;gt;&amp;lt;pre&amp;gt;&amp;lt;code&amp;gt;mydestination =&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;/pre&amp;gt;&amp;lt;p&amp;gt;(ohne Inhalt nach dem “=&amp;quot;) hinzugefügt werden, sonst werden E-Mails an der falschen Stelle gespeichert.&amp;lt;/p&amp;gt;&amp;lt;/div&amp;gt;&lt;br /&gt;
==== Erklärung ====&lt;br /&gt;
&amp;lt;p&amp;gt;'''Netzwerkeinstellungen:'''&amp;lt;/p&amp;gt;&lt;br /&gt;
*&amp;lt;code&amp;gt;mynetworks&amp;lt;/code&amp;gt;: Anfragen von diesen IP-Adressen / aus diesen IP-Adressbereichen werden von Postfix gesondert behandelt (Verwendung für “mynetworks” in den Restrictions). Üblicherweise werden hier die lokalen Adressbereiche und IP-Adressen aus dem eigenen Netz eingetragen, z.B. von anderen eigenen, vertrauenswürdigen Servern.&lt;br /&gt;
*&amp;lt;code&amp;gt;inet_interfaces&amp;lt;/code&amp;gt;: Auf diesen IP-Adressen soll Postfix seine Ports öffnen. Die IP-Adressen müssen an den eigenen Server angepasst werden.&lt;br /&gt;
*&amp;lt;code&amp;gt;myhostname&amp;lt;/code&amp;gt;: Der Hostname des Mailservers, wie er bei der Mailverarbeitung genutzt werden soll.&lt;br /&gt;
&amp;lt;p&amp;gt;'''Mail-Queue Einstellungen:'''&amp;lt;/p&amp;gt;&amp;lt;p&amp;gt;E-Mails in Postfix werden “gequeued”, d.h. in eine Warteschlange eingetragen, die regelmäßig abgearbeitet wird. Wenn Mails nicht zustellbar sind, verbleiben sie eine gewisse Zeit in der Queue, bis ihre Lebenszeit abgelaufen ist, und sie aus der Queue entfernt werden. Der Absender der E-Mail bekommt dann eine entsprechende Nachricht, in der er über die Unzustellbarkeit informiert wird.&amp;lt;/p&amp;gt;&lt;br /&gt;
*&amp;lt;code&amp;gt;maximal_queue_lifetime&amp;lt;/code&amp;gt;: Lebensdauer einer normalen Nachricht in der Queue. Wenn eine E-Mail innerhalb einer Stunde nicht zugestellt werden konnte, wird sie aus der Queue entfernt und der Absender benachrichtigt.&lt;br /&gt;
*&amp;lt;code&amp;gt;bounce_queue_lifetime&amp;lt;/code&amp;gt;: Lebensdauer einer Unzustellbarkeits-Benachrichtigung in der Queue.&lt;br /&gt;
*&amp;lt;code&amp;gt;maximal_backoff_time&amp;lt;/code&amp;gt;: Maximale Zeit, die verstreichen darf, bis für eine E-Mail ein neuer Zustellversuch gestartet wird.&lt;br /&gt;
*&amp;lt;code&amp;gt;minimal_backoff_time&amp;lt;/code&amp;gt;: Zeit, die mindestens verstrichen sein muss, bis ein neuer Zustellversuch gestartet wird.&lt;br /&gt;
*&amp;lt;code&amp;gt;queue_run_delay&amp;lt;/code&amp;gt;: Intervall, in dem die Queue nach nicht zustellbaren E-Mails durchsucht wird.&lt;br /&gt;
&amp;lt;p&amp;gt;'''TLS-Einstellungen:'''&amp;lt;/p&amp;gt;&amp;lt;p&amp;gt;Kompression wird abgeschaltet und (wie bei Dovecot) eine Cipherlist vorgegeben, sodass die bestmögliche Verschlüsselung zwischen Client und Server genutzt wird. Im ersten Teilabschnitt werden die “smtp”-spezifischen TLS-Einstellungen festgelegt – d.h. die Einstellungen, die Postfix als sendenden Kommunikationspartner (Mail-Client) betreffen.&amp;lt;/p&amp;gt;&lt;br /&gt;
*&amp;lt;code&amp;gt;smtp_tls_security_level&amp;lt;/code&amp;gt;: Standard-TLS-Policy, wenn sie in der Datenbank für die Empfängerdomain nicht anders spezifiziert wurde: “dane” kontrolliert zunächst, ob für den Empfängerserver ein TLSA-Eintrag (DANE) im DNS vorliegt. Wenn das der Fall ist, wird eine verschlüsselte Verbindung erzwungen und das vorgezeigte Serverzertifikat mittels TLSA-Eintrag verifiziert. Sollte kein TLSA-Eintrag verfügbar sein, fällt Postfix in die Policy “may” zurück und verschlüsselt nur, wenn der andere Server das unterstützt. Zertifikate werden dabei nicht validiert. Sollten vorhandene TLSA-Einträge ungültig sein, wird stattdessen die “encrypt” Policy genutzt, welche zwar zwingend verschlüsselt, aber Zertifikate ebenfalls nicht validiert. Mehr zu den TLS-Policies folgt später.&lt;br /&gt;
*&amp;lt;code&amp;gt;smtp_dns_support_level&amp;lt;/code&amp;gt;: DNSSEC-gesicherte DNS-Lookups aktiveren und nutzen, falls möglich&lt;br /&gt;
*&amp;lt;code&amp;gt;smtpd_tls_policy_maps&amp;lt;/code&amp;gt;: Verweist auf die SQL-Queries, mit denen Empfängerdomain-spezifische TLS-Einstellungen geladen werden&lt;br /&gt;
*&amp;lt;code&amp;gt;smtp_tls_protocols&amp;lt;/code&amp;gt;: Veraltete SSL/TLS-Protokolle werden deaktiviert&lt;br /&gt;
&amp;lt;p&amp;gt;Nun zum zweiten TLS-Block: Dieser gilt für eingehende Verbindungen. Sowohl für andere Server, als auch Mailclients. Wieder werden SSL v2 und 3 deaktiviert und eine starke Cipherlist ausgewählt. Eingehende Verbindungen können verschlüsselt sein, müssen aber nicht.&amp;lt;/p&amp;gt;&amp;lt;p&amp;gt;'''LMTP-Service:'''&amp;lt;/p&amp;gt;&amp;lt;p&amp;gt;&amp;lt;code&amp;gt;virtual_transport&amp;lt;/code&amp;gt; übermittelt verarbeitete, eingehende E-Mails an den LMTP-Service von Dovecot, der sich dann um die Einordnung der Mail in die passende Mailbox kümmert.&amp;lt;/p&amp;gt;&amp;lt;p&amp;gt;'''Spamfilter und DKIM-Signaturen via Rspamd:'''&amp;lt;/p&amp;gt;&amp;lt;p&amp;gt;Dieser Abschnitt definiert den Rspam-Daemon als Milter für ein- und ausgehende E-Mails. Eingehende E-Mails werden durch Rspamd auf ihre Seriosität geprüft - ausgehende werden mit einem DKIM-Schlüssel signiert.&amp;lt;/p&amp;gt;&amp;lt;p&amp;gt;'''Server Restrictions:'''&amp;lt;/p&amp;gt;&amp;lt;p&amp;gt;Die Blöcke unter “Server restrictions” sind besonders wichtig für die Sicherheit des Mailservers. Falsch eingestellt erlauben sie den unberechtigten Versand von E-Mails (Stichwort “Open Relay”). Der Mailserver wird dann als Spam-Schleuder missbraucht und landet sehr schnell auf einer Blacklist. Damit das nicht passiert, sollten die Restrictions (Beschränkungen) sorgfältig eingestellt und mit einem passenden Open Relay Detektor überprüft sein.&amp;lt;/p&amp;gt;&amp;lt;p&amp;gt;Die Restrictions werden in Leserichtung nacheinander abgearbeitet. Am Ende jeder Verarbeitung steht immer ein “permit” oder “reject”. Für das bessere Verständnis ein Beispiel:&amp;lt;/p&amp;gt;&amp;lt;pre&amp;gt;&amp;lt;code&amp;gt;smtpd_relay_restrictions =      reject_non_fqdn_recipient&lt;br /&gt;
                                reject_unknown_recipient_domain&lt;br /&gt;
                                permit_mynetworks&lt;br /&gt;
                                reject_unauth_destination&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;/pre&amp;gt;&amp;lt;p&amp;gt;&amp;lt;code&amp;gt;smtpd_relay_restrictions&amp;lt;/code&amp;gt; bestimmt die Bedingungen, unter der Postfix als Mail-Relay (“Vermittlungsstelle”) arbeitet. Unser Postfix soll nur in drei Fällen auf eingehende E-Mails reagieren:&amp;lt;/p&amp;gt;&lt;br /&gt;
*Wenn ein Mailclient eine E-Mail via Postfix ins Internet schicken will&lt;br /&gt;
*Wenn ein fremder Mailserver eine E-Mail an unseren Postfix schickt&lt;br /&gt;
*Wenn vom Mailserver selbst aus eine Mail verschickt werden soll&lt;br /&gt;
&amp;lt;p&amp;gt;Um den ersten Fall wird sich in der &amp;lt;code&amp;gt;master.cf&amp;lt;/code&amp;gt; Datei gekümmert. Dort werden die Relay Restrictions im Submission-Bereich so überschrieben, dass Mailclients nicht am freien Versenden gehindert werden. Aktuell interessieren daher nur die letzten beiden Anfrage-Typen. Die erste Zeile der Restriction lautet &amp;lt;code&amp;gt;reject_non_fqdn_recipien&amp;lt;/code&amp;gt;. Sollte die Empfängeradresse keine vollwertige E-Mail Adresse sein, wird die Anfrage an Postfix direkt mit einem &amp;lt;code&amp;gt;reject&amp;lt;/code&amp;gt;abgewiesen. Alle anderen Checks finden dann nicht mehr statt. Das führt dazu, dass Postfix eine Weiterverarbeitung nur akzeptiert, wenn die zu verarbeitende E-Mail einen gültigen Empfänger hat. Ähnliches gilt für &amp;lt;code&amp;gt;reject_unknown_recipient_domain&amp;lt;/code&amp;gt;: Wenn die Empfängerdomain keinen gültigen MX- oder A-Eintrag im DNS hat (und der Zielserver damit nicht feststeht), wird die E-Mail abgelehnt.&amp;lt;/p&amp;gt;&amp;lt;p&amp;gt;Die darauf folgende Zeile enthält die “Restriction” &amp;lt;code&amp;gt;permit_mynetwork&amp;lt;/code&amp;gt;. Wenn der Anfragesteller lokal ist (bzw. seine IP in &amp;lt;code&amp;gt;mynetworks&amp;lt;/code&amp;gt; vermerkt ist), wird er mit einem &amp;lt;code&amp;gt;permit&amp;lt;/code&amp;gt; durchgewunken und die E-Mail wird weiter verarbeitet. Weitere Checks finden dann nicht statt. Sollte er nicht in mynetworks vermerkt sein, wird der letzte Check durchgeführt: &amp;lt;code&amp;gt;reject_unauth_destination&amp;lt;/code&amp;gt; kann nur bestanden werden, wenn die zu verarbeitende E-Mail an eine Empfängeradresse dieses Mailsystems geht. Sollte bis zum Ende der restriction-Definition noch kein &amp;lt;code&amp;gt;permit&amp;lt;/code&amp;gt; oder &amp;lt;code&amp;gt;reject&amp;lt;/code&amp;gt; ausgelöst worden sein, wird automatisch ein &amp;lt;code&amp;gt;permit&amp;lt;/code&amp;gt; ausgelöst und die jeweilige Aktion erlaubt.&amp;lt;/p&amp;gt;&amp;lt;p&amp;gt;Alle anderen Restriction-Definitionen funktionieren ähnlich: Die Kriterien werden nacheinander überprüft. Beginnt ein Kriterium mit einem &amp;lt;code&amp;gt;reject&amp;lt;/code&amp;gt;, wird bei Zutreffen ein &amp;lt;code&amp;gt;reject&amp;lt;/code&amp;gt; ausgelöst, beginnt es mit einem &amp;lt;code&amp;gt;permit&amp;lt;/code&amp;gt;, wird ein &amp;lt;code&amp;gt;permit&amp;lt;/code&amp;gt;ausgelöst. In beiden Fällen werden die nachfolgenden Kriterien nicht mehr überprüft.&amp;lt;/p&amp;gt;&lt;br /&gt;
*&amp;lt;code&amp;gt;smtpd_relay_restrictions&amp;lt;/code&amp;gt;: Kriterien, die überprüft werden, wenn Anfragen am Postfix-Server eintreffen (Von fremden Mailservern oder vom eigenen Server aus, z.B. via sendmail)&lt;br /&gt;
*&amp;lt;code&amp;gt;smtpd_recipient_restrictions&amp;lt;/code&amp;gt;: Kriterien, die zusätzlich zu den relay_restrictions geprüft werden. Nur bei bestehen der Checks wird eine E-Mail auf dem lokalen System angenommen und an die Empfänger-Mailbox geschickt. An dieser Stelle wird über eine SQL-Abfrage nachgefragt, ob ein bestimmter Empfänger E-Mails empfangen können soll (=&amp;amp;gt; Siehe Option in der Datenbank, Accounts nur zum Versenden freizuschalten).&lt;br /&gt;
*&amp;lt;code&amp;gt;smtpd_client-restrictions&amp;lt;/code&amp;gt;: Kriterien, auf die hin andere Server überprüft werden, wenn Kontakt zum Postfix-Server hergestellt wird. (Müssen gültigen Hostnamen und Reverse-DNS-Eintrag haben)&lt;br /&gt;
*&amp;lt;code&amp;gt;smtpd_helo_restrictions&amp;lt;/code&amp;gt;: Fremde Server müssen zu Beginn ihren gültigen Hostnamen nennen.&lt;br /&gt;
*&amp;lt;code&amp;gt;smtpd_data_restrictions&amp;lt;/code&amp;gt;: Ungeduldige Server sind oft Spammer.&lt;br /&gt;
&amp;lt;p&amp;gt;'''MySQL-Abfragen:'''&amp;lt;/p&amp;gt;&amp;lt;p&amp;gt;Hier sind die Pfade zu den übrigen SQL-Dateien angegeben, die Postfix benötigt, um Daten aus der Datenbank abfragen zu können.&amp;lt;/p&amp;gt;&lt;br /&gt;
=== &amp;lt;code&amp;gt;/etc/postfix/master.cf&amp;lt;/code&amp;gt; ===&lt;br /&gt;
&amp;lt;pre&amp;gt;&amp;lt;code&amp;gt;# ==========================================================================&lt;br /&gt;
# service type  private unpriv  chroot  wakeup  maxproc command + args&lt;br /&gt;
#               (yes)   (yes)   (no)    (never) (100)&lt;br /&gt;
# ==========================================================================&lt;br /&gt;
###&lt;br /&gt;
### SMTP-Serverbindungen aus dem Internet&lt;br /&gt;
### Authentifizuerung hier nicht erlaubt (Anmeldung nur via smtps/submission!)&lt;br /&gt;
smtp      inet  n       -       y       -       1       smtpd     &lt;br /&gt;
    -o smtpd_sasl_auth_enable=no&lt;br /&gt;
###&lt;br /&gt;
### SMTPS Service (Submission mit implizitem TLS - ohne STARTTLS) - Port 465&lt;br /&gt;
### Für Mailclients gelten andere Regeln, als für andere Mailserver (siehe smtpd_ in main.cf)&lt;br /&gt;
###&lt;br /&gt;
smtps     inet  n       -       y       -       -       smtpd&lt;br /&gt;
    -o syslog_name=postfix/smtps&lt;br /&gt;
    -o smtpd_tls_wrappermode=yes&lt;br /&gt;
    -o smtpd_tls_security_level=encrypt&lt;br /&gt;
    -o smtpd_sasl_auth_enable=yes&lt;br /&gt;
    -o smtpd_sasl_type=dovecot&lt;br /&gt;
    -o smtpd_sasl_path=private/auth&lt;br /&gt;
    -o smtpd_sasl_security_options=noanonymous&lt;br /&gt;
    -o smtpd_client_restrictions=$mua_client_restrictions&lt;br /&gt;
    -o smtpd_sender_restrictions=$mua_sender_restrictions&lt;br /&gt;
    -o smtpd_relay_restrictions=$mua_relay_restrictions&lt;br /&gt;
    -o milter_macro_daemon_name=ORIGINATING&lt;br /&gt;
    -o smtpd_sender_login_maps=proxy:mysql:/etc/postfix/sql/sender-login-maps.cf&lt;br /&gt;
    -o smtpd_helo_required=no&lt;br /&gt;
    -o smtpd_helo_restrictions=&lt;br /&gt;
    -o cleanup_service_name=submission-header-cleanup&lt;br /&gt;
###&lt;br /&gt;
### Submission-Zugang für Clients (mit STARTTLS - für Rückwärtskompatibilität) - Port 587&lt;br /&gt;
###&lt;br /&gt;
submission inet n       -       y       -       -       smtpd&lt;br /&gt;
    -o syslog_name=postfix/submission&lt;br /&gt;
    -o smtpd_tls_security_level=encrypt&lt;br /&gt;
    -o smtpd_sasl_auth_enable=yes&lt;br /&gt;
    -o smtpd_sasl_type=dovecot&lt;br /&gt;
    -o smtpd_sasl_path=private/auth&lt;br /&gt;
    -o smtpd_sasl_security_options=noanonymous&lt;br /&gt;
    -o smtpd_client_restrictions=$mua_client_restrictions&lt;br /&gt;
    -o smtpd_sender_restrictions=$mua_sender_restrictions&lt;br /&gt;
    -o smtpd_relay_restrictions=$mua_relay_restrictions&lt;br /&gt;
    -o milter_macro_daemon_name=ORIGINATING&lt;br /&gt;
    -o smtpd_sender_login_maps=proxy:mysql:/etc/postfix/sql/sender-login-maps.cf&lt;br /&gt;
    -o smtpd_helo_required=no&lt;br /&gt;
    -o smtpd_helo_restrictions=&lt;br /&gt;
    -o cleanup_service_name=submission-header-cleanup&lt;br /&gt;
###&lt;br /&gt;
### Weitere wichtige Dienste für den Serverbetrieb&lt;br /&gt;
###&lt;br /&gt;
pickup    unix  n       -       y       60      1       pickup&lt;br /&gt;
cleanup   unix  n       -       y       -       0       cleanup&lt;br /&gt;
qmgr      unix  n       -       n       300     1       qmgr&lt;br /&gt;
tlsmgr    unix  -       -       y       1000?   1       tlsmgr&lt;br /&gt;
rewrite   unix  -       -       y       -       -       trivial-rewrite&lt;br /&gt;
bounce    unix  -       -       y       -       0       bounce&lt;br /&gt;
defer     unix  -       -       y       -       0       bounce&lt;br /&gt;
trace     unix  -       -       y       -       0       bounce&lt;br /&gt;
verify    unix  -       -       y       -       1       verify&lt;br /&gt;
flush     unix  n       -       y       1000?   0       flush&lt;br /&gt;
proxymap  unix  -       -       n       -       -       proxymap&lt;br /&gt;
proxywrite unix -       -       n       -       1       proxymap&lt;br /&gt;
smtp      unix  -       -       y       -       -       smtp&lt;br /&gt;
relay     unix  -       -       y       -       -       smtp&lt;br /&gt;
showq     unix  n       -       y       -       -       showq&lt;br /&gt;
error     unix  -       -       y       -       -       error&lt;br /&gt;
retry     unix  -       -       y       -       -       error&lt;br /&gt;
discard   unix  -       -       y       -       -       discard&lt;br /&gt;
local     unix  -       n       n       -       -       local&lt;br /&gt;
virtual   unix  -       n       n       -       -       virtual&lt;br /&gt;
lmtp      unix  -       -       y       -       -       lmtp&lt;br /&gt;
anvil     unix  -       -       y       -       1       anvil&lt;br /&gt;
scache    unix  -       -       y       -       1       scache&lt;br /&gt;
###&lt;br /&gt;
### Cleanup-Service um MUA header zu entfernen&lt;br /&gt;
###&lt;br /&gt;
submission-header-cleanup unix n - n    -       0       cleanup&lt;br /&gt;
    -o header_checks=regexp:/etc/postfix/submission_header_cleanup&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;/pre&amp;gt;&amp;lt;p&amp;gt;Die &amp;lt;code&amp;gt;/etc/postfix/master.cf&amp;lt;/code&amp;gt; Datei will ich euch nur im Groben erklären. Wichtig zu wissen ist, dass hier die Definition und Konfiguration der verschiedenen Postfix-Dienste wie z.B. smtpd (eingehende SMTP-Verbindungen) und smtp (ausgehende SMTP-Verbindungen) passiert. Gut zu erkennen ist, dass über ein &amp;lt;code&amp;gt;-o&amp;lt;/code&amp;gt; weitere Parameter an einen Dienst übergeben werden. So beispielsweise beim &amp;lt;code&amp;gt;smtps&amp;lt;/code&amp;gt;-Dienst, der auf Port 465 für die SMTP-Kommunikation mit den Mailclients bereitsteht: Die hier angegebenen Einstellungen z.B. zu &amp;lt;code&amp;gt;smtpd_relay_restrictions&amp;lt;/code&amp;gt; überschreiben die Einstellungen in der main.cf – allerdings nur für diesen einen spezifischen Dienst! Ein gutes Beispiel ist die Einstellung &amp;lt;code&amp;gt;smtpd_tls_security_level=encrypt&amp;lt;/code&amp;gt;, die im Submission-Block steht. In der &amp;lt;code&amp;gt;main.cf&amp;lt;/code&amp;gt; hatten wir hier “may” definiert, um keine Server auszuschließen, die TLS nicht beherrschen. Da smtpd-Einstellungen aber sowohl für andere Server als auch für Mailclient gelten, wäre damit auch zu den Mailclients gesagt: “Ihr könnt verschlüsselte Verbindungen herstellen – müsst aber nicht”. Das wollen wir selbstverständlich nicht! Mailclients sollen eine verschlüsselte Verbindung herstellen müssen! Deshalb wird die smtpd-Einstellung speziell für den &amp;lt;code&amp;gt;smtps&amp;lt;/code&amp;gt;-Dienst mithilfe der &amp;lt;code&amp;gt;-o&amp;lt;/code&amp;gt; Option überschrieben und auf “encrypt” gesetzt.&amp;lt;/p&amp;gt;&amp;lt;p&amp;gt;Der &amp;lt;code&amp;gt;smtps&amp;lt;/code&amp;gt; Service am Anfang der Datei ist der SMTP-Dienst, zu dem sich Mailclients später verbinden sollen. Eine Verbindung ist hier nur über direktes TLS (nicht StartTLS!) möglich. Für Clients, die sich zu Port 587 verbinden wollen, steht weiterhin der &amp;lt;code&amp;gt;submission&amp;lt;/code&amp;gt; Service darunter bereit (auch wenn er in vielen Fällen nicht mehr notwendig sein sollte).&amp;lt;/p&amp;gt;&amp;lt;p&amp;gt;Für besseren Datenschutz wird der “Received”-Header (+ weitere Datenschutz-relevante Header) bei eingehenden E-Mails entfernt, wenn sie über den &amp;lt;code&amp;gt;smtps&amp;lt;/code&amp;gt;-Port eintreffen. Die meisten E-Mail-Clients senden ihren Namen und die Version mit. Zusätzlich vermerkt Postfix bei eingehenden E-Mails, von welcher IP-Adresse die E-Mail stammt. Auf diese Informationen können wir verzichten, deshalb werden sie mithilfe eines kleinen zusätzlichen Dienstes &amp;lt;code&amp;gt;submission-header-cleanup&amp;lt;/code&amp;gt; (am Ende der Konfiguration) aus der E-Mail gelöscht. Im &amp;lt;code&amp;gt;smtps&amp;lt;/code&amp;gt;- und Submission-Bereich wird via &amp;lt;code&amp;gt;cleanup_service_name&amp;lt;/code&amp;gt; festgelegt, dass bei eingehenden Mails auf diesen Services der Filter anzuwenden ist. Die Filterregeln befinden sich in der Datei &amp;lt;code&amp;gt;/etc/postfix/submission_header_cleanup&amp;lt;/code&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
=== Header Cleanup Regeln ===&lt;br /&gt;
&amp;lt;p&amp;gt;Unter &amp;lt;code&amp;gt;/etc/postfix/submission_header_cleanup&amp;lt;/code&amp;gt; wird eine Datei mit folgendem Inhalt angelegt:&amp;lt;/p&amp;gt;&amp;lt;pre&amp;gt;&amp;lt;code&amp;gt;### Entfernt Datenschutz-relevante Header aus E-Mails von MTUAs&lt;br /&gt;
&lt;br /&gt;
/^Received:/            IGNORE&lt;br /&gt;
/^X-Originating-IP:/    IGNORE&lt;br /&gt;
/^X-Mailer:/            IGNORE&lt;br /&gt;
/^User-Agent:/          IGNORE&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;/pre&amp;gt;&lt;br /&gt;
=== SQL-Konfiguration ===&lt;br /&gt;
&amp;lt;p&amp;gt;Neben der Haupt-Konfiguration main.cf und der Service-Konfiguration master.cf werden noch ein paar Konfigurationsdateien innerhalb des Unterverzeichnisses &amp;lt;code&amp;gt;sql/&amp;lt;/code&amp;gt; angelegt, die die SQL-Queries für die Datenabfragen an die Datenbank enthalten:&amp;lt;/p&amp;gt;&amp;lt;pre&amp;gt;&amp;lt;code&amp;gt;mkdir /etc/postfix/sql &amp;amp;&amp;amp; cd $_&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;/pre&amp;gt;&amp;lt;p&amp;gt;Erstellt dann die folgenden Konfigurationsdateien mit dem zugehörigen Inhalt:&amp;lt;/p&amp;gt;&amp;lt;p&amp;gt;&amp;lt;code&amp;gt;accounts.cf&amp;lt;/code&amp;gt;&amp;lt;/p&amp;gt;&amp;lt;pre&amp;gt;&amp;lt;code&amp;gt;user = vmail&lt;br /&gt;
password = vmaildbpass&lt;br /&gt;
hosts = unix:/run/mysqld/mysqld.sock&lt;br /&gt;
dbname = vmail&lt;br /&gt;
query = select 1 as found from accounts where username = '%u' and domain = '%d' and enabled = true LIMIT 1;&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;/pre&amp;gt;&amp;lt;p&amp;gt;&amp;lt;code&amp;gt;aliases.cf&amp;lt;/code&amp;gt;&amp;lt;/p&amp;gt;&amp;lt;pre&amp;gt;&amp;lt;code&amp;gt;user = vmail&lt;br /&gt;
password = vmaildbpass&lt;br /&gt;
hosts = unix:/run/mysqld/mysqld.sock&lt;br /&gt;
dbname = vmail&lt;br /&gt;
query = SELECT DISTINCT concat(destination_username, '@', destination_domain) AS destinations FROM aliases&lt;br /&gt;
        WHERE (source_username = '%u' OR source_username IS NULL) AND source_domain = '%d'&lt;br /&gt;
        AND enabled = true&lt;br /&gt;
        AND NOT EXISTS (SELECT id FROM accounts WHERE username = '%u' and domain = '%d');&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;/pre&amp;gt;&amp;lt;p&amp;gt;&amp;lt;code&amp;gt;domains.cf&amp;lt;/code&amp;gt;&amp;lt;/p&amp;gt;&amp;lt;pre&amp;gt;&amp;lt;code&amp;gt;user = vmail&lt;br /&gt;
password = vmaildbpass&lt;br /&gt;
hosts = unix:/run/mysqld/mysqld.sock&lt;br /&gt;
dbname = vmail&lt;br /&gt;
query = SELECT domain FROM domains WHERE domain='%s';&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;/pre&amp;gt;&amp;lt;p&amp;gt;&amp;lt;code&amp;gt;recipient-access.cf&amp;lt;/code&amp;gt;&amp;lt;/p&amp;gt;&amp;lt;pre&amp;gt;&amp;lt;code&amp;gt;user = vmail&lt;br /&gt;
password = vmaildbpass&lt;br /&gt;
hosts = unix:/run/mysqld/mysqld.sock&lt;br /&gt;
dbname = vmail&lt;br /&gt;
query = select if(sendonly = true, 'REJECT', 'OK') AS access from accounts where username = '%u' and domain = '%d' and enabled = true LIMIT 1;&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;/pre&amp;gt;&amp;lt;p&amp;gt;&amp;lt;code&amp;gt;sender-login-maps.cf&amp;lt;/code&amp;gt;&amp;lt;/p&amp;gt;&amp;lt;pre&amp;gt;&amp;lt;code&amp;gt;user = vmail&lt;br /&gt;
password = vmaildbpass&lt;br /&gt;
hosts = unix:/run/mysqld/mysqld.sock&lt;br /&gt;
dbname = vmail&lt;br /&gt;
query = select concat(username, '@', domain) as 'owns' from accounts where username = '%u' AND domain = '%d' and enabled = true union select &lt;br /&gt;
        concat(destination_username, '@', destination_domain) AS 'owns' from aliases &lt;br /&gt;
        where source_username = '%u' and source_domain = '%d' and enabled = true;&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;/pre&amp;gt;&amp;lt;p&amp;gt;&amp;lt;code&amp;gt;tls-policy.cf&amp;lt;/code&amp;gt;&amp;lt;/p&amp;gt;&amp;lt;pre&amp;gt;&amp;lt;code&amp;gt;user = vmail&lt;br /&gt;
password = vmaildbpass&lt;br /&gt;
hosts = unix:/run/mysqld/mysqld.sock&lt;br /&gt;
dbname = vmail&lt;br /&gt;
query = SELECT policy, params FROM tlspolicies WHERE domain = '%s';&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;/pre&amp;gt;&amp;lt;p&amp;gt;'''Vergesst nicht, &amp;lt;code&amp;gt;vmaildbpass&amp;lt;/code&amp;gt; in jeder der Dateien durch euer eigenes Passwort zu ersetzen!'''&amp;lt;/p&amp;gt;&amp;lt;p&amp;gt;Alle SQL-Konfgurationsdateien in &amp;lt;code&amp;gt;/etc/postfix/sql&amp;lt;/code&amp;gt; werden vor dem Zugriff durch unberechtigte User geschützt:&amp;lt;/p&amp;gt;&amp;lt;pre&amp;gt;&amp;lt;code&amp;gt;chown -R root:postfix /etc/postfix/sql&lt;br /&gt;
chmod g+x /etc/postfix/sql&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;/pre&amp;gt;&lt;br /&gt;
=== Weitere Postfix-Konfigurationsdateien ===&lt;br /&gt;
&amp;lt;p&amp;gt;Außerdem gibt es noch eine weitere Datei &amp;lt;code&amp;gt;/etc/postfix/without_ptr&amp;lt;/code&amp;gt;, die zunächst leer bleiben kann:&amp;lt;/p&amp;gt;&amp;lt;pre&amp;gt;&amp;lt;code&amp;gt;touch /etc/postfix/without_ptr&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;/pre&amp;gt;&amp;lt;p&amp;gt;Die Datei kann später einmal Einträge wie den folgenden beinhalten:&amp;lt;/p&amp;gt;&amp;lt;pre&amp;gt;&amp;lt;code&amp;gt;[2001:db8::beef] OK&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;/pre&amp;gt;&amp;lt;p&amp;gt;Der Server mit der IP &amp;lt;code&amp;gt;2001:db8::beef&amp;lt;/code&amp;gt; muss dann keinen gültigen PTR-Record (Reverse DNS) mehr besitzen und wird trotzdem akzeptiert. Die &amp;lt;code&amp;gt;without_ptr&amp;lt;/code&amp;gt;-Datei muss dann nach jeder Änderung in eine Datenbankdatei umgewandelt und Postfix neu geladen werden:&amp;lt;/p&amp;gt;&amp;lt;pre&amp;gt;&amp;lt;code&amp;gt;postmap /etc/postfix/without_ptr&lt;br /&gt;
systemctl reload postfix&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;/pre&amp;gt;&amp;lt;p&amp;gt;Im Moment reicht es aber aus, einfach nur eine leere Datenbankdatei zu generieren:&amp;lt;/p&amp;gt;&amp;lt;pre&amp;gt;&amp;lt;code&amp;gt;postmap /etc/postfix/without_ptr&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;/pre&amp;gt;&amp;lt;p&amp;gt;Zum Schluss wird einmal&amp;lt;/p&amp;gt;&amp;lt;pre&amp;gt;&amp;lt;code&amp;gt;newaliases&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;/pre&amp;gt;&amp;lt;p&amp;gt;ausgeführt, um die Alias-Datei &amp;lt;code&amp;gt;/etc/aliases.db&amp;lt;/code&amp;gt; zu generieren, die Postfix standardmäßig erwartet.&amp;lt;/p&amp;gt;&lt;br /&gt;
== Rspamd ==&lt;br /&gt;
&amp;lt;p&amp;gt;Da die Rspamd-Pakete für Debian nicht besonders aktuell sind und&amp;lt;/p&amp;gt;[https://rspamd.com/downloads.html#debian-standard-repos-notes offiziell davon abgeraten wird]&amp;lt;p&amp;gt;, diese zu nutzen, nutzen wir an dieser Stelle das Debian-Repository des Rspamd-Projekts:&amp;lt;/p&amp;gt;&amp;lt;pre&amp;gt;&amp;lt;code&amp;gt;apt install -y lsb-release wget&lt;br /&gt;
wget -O- https://rspamd.com/apt-stable/gpg.key | apt-key add -&lt;br /&gt;
echo &amp;quot;deb http://rspamd.com/apt-stable/ $(lsb_release -c -s) main&amp;quot; &amp;amp;gt; /etc/apt/sources.list.d/rspamd.list&lt;br /&gt;
echo &amp;quot;deb-src http://rspamd.com/apt-stable/ $(lsb_release -c -s) main&amp;quot; &amp;amp;gt;&amp;amp;gt; /etc/apt/sources.list.d/rspamd.list&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;/pre&amp;gt;&amp;lt;p&amp;gt;Paketquellen aktualisieren und Rspamd installieren&amp;lt;/p&amp;gt;&amp;lt;pre&amp;gt;&amp;lt;code&amp;gt;apt update&lt;br /&gt;
apt install rspamd&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;/pre&amp;gt;&amp;lt;p&amp;gt;Rspamd stoppen:&amp;lt;/p&amp;gt;&amp;lt;pre&amp;gt;&amp;lt;code&amp;gt;systemctl stop rspamd&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;/pre&amp;gt;&amp;lt;figure&amp;gt;&amp;lt;figcaption&amp;gt;Rspamd Webinterface&amp;lt;/figcaption&amp;gt;&amp;lt;/figure&amp;gt;&lt;br /&gt;
=== Grundkonfiguration ===&lt;br /&gt;
&amp;lt;p&amp;gt;Die Konfiguration von Rspamd wird im Verzeichnis &amp;lt;code&amp;gt;/etc/rspamd/local.d/&amp;lt;/code&amp;gt; abgelegt. Die folgenden Konfigurationsdateien werden darin erstellt:&amp;lt;/p&amp;gt;&amp;lt;p&amp;gt;&amp;lt;code&amp;gt;/etc/rspamd/local.d/worker-controller.inc&amp;lt;/code&amp;gt;: Einstellung des Worker controllers: Passwort für den Zugriff via Weboberfläche, z.B.:&amp;lt;/p&amp;gt;&amp;lt;pre&amp;gt;&amp;lt;code&amp;gt;password = &amp;quot;$2$qecacwgrz13owkag4gqcy5y7yeqh7yh4$y6i6gn5q3538tzsn19ojchuudoauw3rzdj1z74h5us4gd3jj5e8y&amp;quot;;&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;/pre&amp;gt;&amp;lt;p&amp;gt;Der Passworthash (&amp;lt;code&amp;gt;$2$qecacwg...&amp;lt;/code&amp;gt;) wird via&amp;lt;/p&amp;gt;&amp;lt;pre&amp;gt;&amp;lt;code&amp;gt;rspamadm pw&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;/pre&amp;gt;&amp;lt;p&amp;gt;generiert und in die Datei eingefügt. Vergesst nicht das abschließende &amp;lt;code&amp;gt;&amp;quot;;&amp;lt;/code&amp;gt;!&amp;lt;/p&amp;gt;&amp;lt;p&amp;gt;&amp;lt;code&amp;gt;/etc/rspamd/local.d/logging.inc&amp;lt;/code&amp;gt;: Error logging&amp;lt;/p&amp;gt;&amp;lt;pre&amp;gt;&amp;lt;code&amp;gt;type = &amp;quot;syslog&amp;quot;;&lt;br /&gt;
level = &amp;quot;warning&amp;quot;;&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;/pre&amp;gt;&amp;lt;p&amp;gt;Milter Headers &amp;lt;code&amp;gt;/etc/rspamd/local.d/milter_headers.conf&amp;lt;/code&amp;gt;&amp;lt;/p&amp;gt;&amp;lt;pre&amp;gt;&amp;lt;code&amp;gt;use = [&amp;quot;x-spamd-bar&amp;quot;, &amp;quot;x-spam-level&amp;quot;, &amp;quot;authentication-results&amp;quot;];&lt;br /&gt;
authenticated_headers = [&amp;quot;authentication-results&amp;quot;];&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;/pre&amp;gt;&amp;lt;p&amp;gt;Redis für den Bayes’schen Filter nutzen: &amp;lt;code&amp;gt;/etc/rspamd/local.d/classifier-bayes.conf&amp;lt;/code&amp;gt;&amp;lt;/p&amp;gt;&amp;lt;pre&amp;gt;&amp;lt;code&amp;gt;backend = &amp;quot;redis&amp;quot;;&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;/pre&amp;gt;&amp;lt;p&amp;gt;…und in &amp;lt;code&amp;gt;/etc/rspamd/local.d/redis.conf&amp;lt;/code&amp;gt;:&amp;lt;/p&amp;gt;&amp;lt;pre&amp;gt;&amp;lt;code&amp;gt;servers = &amp;quot;127.0.0.1&amp;quot;;&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;/pre&amp;gt;&amp;lt;p&amp;gt;Für den Bayes’schen Filter (Textanalyse) wird “Auto-Learning” aktiviert:&amp;lt;/p&amp;gt;&amp;lt;p&amp;gt;&amp;lt;code&amp;gt;/etc/rspamd/override.d/classifier-bayes.conf&amp;lt;/code&amp;gt;:&amp;lt;/p&amp;gt;&amp;lt;pre&amp;gt;&amp;lt;code&amp;gt;autolearn = true;&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;/pre&amp;gt;&amp;lt;p&amp;gt;Wird eine E-Mail bereits beim Empfang abgelehnt, weil sie ausgrund der Metadaten offensichtlich von einem Spammer kommt, nutzt Rspamd die Gelegenheit und lernt, dass der Text in dieser E-Mail als Spam einzustufen ist. So wird die Erkennungsrate mit jeder Spammail besser. (&amp;lt;/p&amp;gt;[https://rspamd.com/doc/configuration/statistic.html https://rspamd.com/doc/configuration/statistic.html]&amp;lt;p&amp;gt;)&amp;lt;/p&amp;gt;&lt;br /&gt;
=== Manuell gepflegte Black-/Whitelists ===&lt;br /&gt;
&amp;lt;p&amp;gt;Über das Multimap-Modul kann das Verhalten von Rspamd für bestimmte E-Mail-Merkmale personalisiert gesteuert werden. Merkmale können zum Beispiel die Absender-IP-Adresse oder die Absendermailadresse sein. Für beide registrieren wir in &amp;lt;code&amp;gt;/etc/rspamd/local.d/multimap.conf&amp;lt;/code&amp;gt; jeweils eine Black- und eine Whitelist:&amp;lt;/p&amp;gt;&amp;lt;pre&amp;gt;&amp;lt;code&amp;gt;WHITELIST_IP {&lt;br /&gt;
    type = &amp;quot;ip&amp;quot;;&lt;br /&gt;
    map = &amp;quot;$CONFDIR/local.d/whitelist_ip.map&amp;quot;;&lt;br /&gt;
    description = &amp;quot;Local ip whitelist&amp;quot;;&lt;br /&gt;
    action = &amp;quot;accept&amp;quot;;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
WHITELIST_FROM {&lt;br /&gt;
        type = &amp;quot;from&amp;quot;;&lt;br /&gt;
        map = &amp;quot;$CONFDIR/local.d/whitelist_from.map&amp;quot;;&lt;br /&gt;
        description = &amp;quot;Local from whitelist&amp;quot;;&lt;br /&gt;
        action = &amp;quot;accept&amp;quot;;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
BLACKLIST_IP {&lt;br /&gt;
        type = &amp;quot;ip&amp;quot;;&lt;br /&gt;
        map = &amp;quot;$CONFDIR/local.d/blacklist_ip.map&amp;quot;;&lt;br /&gt;
        description = &amp;quot;Local ip blacklist&amp;quot;;&lt;br /&gt;
        action = &amp;quot;reject&amp;quot;;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
BLACKLIST_FROM {&lt;br /&gt;
        type = &amp;quot;from&amp;quot;;&lt;br /&gt;
        map = &amp;quot;$CONFDIR/local.d/blacklist_from.map&amp;quot;;&lt;br /&gt;
        description = &amp;quot;Local from blacklist&amp;quot;;&lt;br /&gt;
        action = &amp;quot;reject&amp;quot;;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;/pre&amp;gt;&amp;lt;p&amp;gt;Für alle vier Listen werden nun Listendateien erstellt:&amp;lt;/p&amp;gt;&amp;lt;pre&amp;gt;&amp;lt;code&amp;gt;cd /etc/rspamd/local.d&lt;br /&gt;
touch whitelist_ip.map&lt;br /&gt;
touch whitelist_from.map&lt;br /&gt;
touch blacklist_ip.map&lt;br /&gt;
touch blacklist_from.map&lt;br /&gt;
cd - &lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;/pre&amp;gt;&amp;lt;p&amp;gt;“IP”-Listen können IPv6- und IPv4-Adressen bzw. Adressbereiche enthalten - in jeder Zeile ein Eintrag. “From”-Listen enthalten vollständige Absendermailadressen. Die Listen können zunächst leer bleiben. Sie eignen sich gut, wenn man später einmal für einzelne Absender oder Server Ausnahmen einstellen möchte.&amp;lt;/p&amp;gt;&lt;br /&gt;
=== DKIM Signing ===&lt;br /&gt;
&amp;lt;p&amp;gt;Rspamd übernimmt auch das Signieren von ausgehenden E-Mails. Damit signiert werden kann, muss zunächst ein Signing Key generiert werden. Der Parameter &amp;lt;code&amp;gt;-s 2020&amp;lt;/code&amp;gt; gibt den sogenannten Selektor an - einen Namen für den Key (hier das Erstellungsjahr).&amp;lt;/p&amp;gt;&amp;lt;pre&amp;gt;&amp;lt;code&amp;gt;mkdir /var/lib/rspamd/dkim/&lt;br /&gt;
rspamadm dkim_keygen -b 2048 -s 2020 -k /var/lib/rspamd/dkim/2020.key &amp;amp;gt; /var/lib/rspamd/dkim/2020.txt&lt;br /&gt;
chown -R _rspamd:_rspamd /var/lib/rspamd/dkim&lt;br /&gt;
chmod 440 /var/lib/rspamd/dkim/*&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;/pre&amp;gt;&amp;lt;p&amp;gt;Zum Signing Key (&amp;lt;code&amp;gt;/var/lib/rspamd/dkim/2020.key&amp;lt;/code&amp;gt;) gehört ein dazu passender Public Key, welcher in Form eines vorbereiteten DNS-Records in der Datei &amp;lt;code&amp;gt;/var/lib/rspamd/dkim/2020.txt&amp;lt;/code&amp;gt; liegt.&amp;lt;/p&amp;gt;&amp;lt;p&amp;gt;DKIM Record ausgeben lassen:&amp;lt;/p&amp;gt;&amp;lt;pre&amp;gt;&amp;lt;code&amp;gt;cat /var/lib/rspamd/dkim/2020.txt&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;/pre&amp;gt;&amp;lt;p&amp;gt;Die Ausgabe sieht z.B. so aus:&amp;lt;/p&amp;gt;&amp;lt;pre&amp;gt;&amp;lt;code&amp;gt;2020._domainkey IN TXT ( &amp;quot;v=DKIM1; k=rsa; &amp;quot;&lt;br /&gt;
    &amp;quot;p=MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA2/al5HqXUpe+HUazCr6t9lv2VOZLR369PPB4t+dgljZQvgUsIKoYzfS/w9NagS32xZYxi1dtlDWuRfTU/ahHO2MYzE0zHE4lMfwb6VkNCG+pM6bAkCwc5cFvyRygwxAPEiHAtmtU5b0i9LY25Z/ZWgyBxEWZ0Wf+hLjYHvnvMqewPsduUqKVjDOdUqeBb1VAu3WFErOAGVUYfKqFX&amp;quot;&lt;br /&gt;
    &amp;quot;+yfz36Alb7/OMAort8A5Vo5t5k0vxTHzkYYg5KB6tLS8jngrNucGjyNL5+k0ijPs3yT7WpTGL3U3SEa8cX8WvOO1fIpWQz4yyZJJ1Mm62+FskSc7BHjdiMHE64Id/UBDDVjxwIDAQAB&amp;quot;&lt;br /&gt;
) ;&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;/pre&amp;gt;&amp;lt;p&amp;gt;Der Werte-Abschnitt des Records (beginnend mit &amp;lt;code&amp;gt;v=DKIM1&amp;lt;/code&amp;gt; bis zum Ende der Zeichenkolonne - hier &amp;lt;code&amp;gt;AQAB&amp;lt;/code&amp;gt;) muss in einen neuen DNS-Record gepflanzt werden. Dabei werden Zeilenumbrüche und Anführungsstriche entfernt. Je nach DNS-Hoster muss ein neuer Eintrag geringfügig anders formatiert werden. Ich habe den Schritt im Screenshot beispielhaft für den Hoster&amp;lt;/p&amp;gt;[https://www.core-networks.de/ Core-Networks.de]&amp;lt;p&amp;gt;mit dem Selector “2020” und meiner Beispieldomain “mysystems.tld” durchgeführt:&amp;lt;/p&amp;gt;&amp;lt;figure&amp;gt;&amp;lt;figcaption&amp;gt;core-networks.de Screenshot mit DKIM Record&amp;lt;/figcaption&amp;gt;&amp;lt;/figure&amp;gt;&amp;lt;p&amp;gt;Wichtig: Der Selektor “2020” wird im DNS-Record zusammen mit &amp;lt;code&amp;gt;._domainkey&amp;lt;/code&amp;gt; als Name verwendet! Der DKIM-Record muss '''für jede verwendete Domain (domain2.tld, domain2.tld) im jeweiligen Zonefile erstellt werden!'''&amp;lt;/p&amp;gt;&amp;lt;div class=&amp;quot;tip&amp;quot;&amp;gt;Sollte der Record vom DNS-Hoster nicht akzeptiert werden, hilft es in einigen Fällen, die Schlüssellänge von 2048 Bit auf 1024 Bit zu reduzieren. Dazu das &amp;lt;code&amp;gt;rspamadm dkim_keygen&amp;lt;/code&amp;gt;Kommando nochmals mit &amp;lt;code&amp;gt;-b 1024&amp;lt;/code&amp;gt; statt mit &amp;lt;code&amp;gt;-b 2048&amp;lt;/code&amp;gt; ausführen.&amp;lt;/div&amp;gt;&amp;lt;p&amp;gt;Der erzeugte DKIM-Key und der verwendete Selektor werden in der Konfigurationsdatei &amp;lt;code&amp;gt;/etc/rspamd/local.d/dkim_signing.conf&amp;lt;/code&amp;gt; angegeben:&amp;lt;/p&amp;gt;&amp;lt;pre&amp;gt;&amp;lt;code&amp;gt;path = &amp;quot;/var/lib/rspamd/dkim/$selector.key&amp;quot;;&lt;br /&gt;
selector = &amp;quot;2020&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
### Enable DKIM signing for alias sender addresses&lt;br /&gt;
allow_username_mismatch = true;&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;/pre&amp;gt;&amp;lt;p&amp;gt;Diese Konfiguration wird in die Datei &amp;lt;code&amp;gt;/etc/rspamd/local.d/arc.conf&amp;lt;/code&amp;gt; kopiert, sodass das&amp;lt;/p&amp;gt;[https://rspamd.com/doc/modules/arc.html ARC-Modul]&amp;lt;p&amp;gt;korrekt arbeiten kann. Es greift auf dieselben Einstellungen zurück:&amp;lt;/p&amp;gt;&amp;lt;pre&amp;gt;&amp;lt;code&amp;gt;cp -R /etc/rspamd/local.d/dkim_signing.conf /etc/rspamd/local.d/arc.conf&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;/pre&amp;gt;&lt;br /&gt;
== Redis als Cache und Key-Value Store für Rspamd-Module ==&lt;br /&gt;
&amp;lt;p&amp;gt;Rspamd verwendet Redis als Cache. Die Installation ist trivial:&amp;lt;/p&amp;gt;&amp;lt;pre&amp;gt;&amp;lt;code&amp;gt;apt install redis-server&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;/pre&amp;gt;&amp;lt;p&amp;gt;In der Rspamd-Konfiguration wurde Redis bereits als Caching-Datenbank eingetragen.&amp;lt;/p&amp;gt;&lt;br /&gt;
== Rspamd starten ==&lt;br /&gt;
&amp;lt;p&amp;gt;Rspamd kann nun gestartet werden:&amp;lt;/p&amp;gt;&amp;lt;pre&amp;gt;&amp;lt;code&amp;gt;systemctl start rspamd&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;/pre&amp;gt;&lt;br /&gt;
== Nginx Proxy für Rspamd Weboberfläche ==&lt;br /&gt;
&amp;lt;p&amp;gt;Für den bequemen und sicheren Zugriff auf die Rspamd-Weboberfläche kann dieser ein Nginx HTTP-Proxy vorgeschaltet werden. Nginx kümmert sich dann um die Absicherung der Verbindung via HTTPS. Wer nur selten auf die Rspamd-Weboberfläche zugreift, kann auf diesen Schritt verzichten und stattdessen auch über einen SSH-Tunnel auf das Interface zugreifen (&amp;lt;/p&amp;gt;[https://thomas-leister.de/mailserver-debian-buster/#ssh-tunnel siehe unten]&amp;lt;p&amp;gt;).&amp;lt;/p&amp;gt;&amp;lt;p&amp;gt;Für den Rspamd-Webproxy wird in &amp;lt;code&amp;gt;/etc/nginx/sites-available/mail.mysystems.tld&amp;lt;/code&amp;gt; ein &amp;lt;code&amp;gt;location&amp;lt;/code&amp;gt; Block wie folgt hinzugefügt:&amp;lt;/p&amp;gt;&amp;lt;pre&amp;gt;&amp;lt;code&amp;gt;server {&lt;br /&gt;
        listen 80;&lt;br /&gt;
        listen [::]:80;&lt;br /&gt;
        listen 443 ssl http2;&lt;br /&gt;
        listen [::]:443 ssl http2;&lt;br /&gt;
&lt;br /&gt;
        server_name mail.mysystems.tld imap.mysystems.tld smtp.mysystems.tld;&lt;br /&gt;
&lt;br /&gt;
        ssl_certificate /etc/acme.sh/mail.mysystems.tld/fullchain.pem;&lt;br /&gt;
        ssl_certificate_key /etc/acme.sh/mail.mysystems.tld/privkey.pem;&lt;br /&gt;
&lt;br /&gt;
        add_header Strict-Transport-Security max-age=15768000;&lt;br /&gt;
&lt;br /&gt;
        location /rspamd/ {&lt;br /&gt;
                proxy_pass http://localhost:11334/;&lt;br /&gt;
                proxy_set_header Host $host;&lt;br /&gt;
                proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
        if ($ssl_protocol = &amp;quot;&amp;quot;) {&lt;br /&gt;
            return 301 https://$server_name$request_uri;&lt;br /&gt;
        }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;/pre&amp;gt;&amp;lt;p&amp;gt;Anzupassen:&amp;lt;/p&amp;gt;&lt;br /&gt;
*ssl_certificate: Pfad zu Zertifikat&lt;br /&gt;
*ssl_certificate_key: Pfad zu Zertifikat&lt;br /&gt;
*server_name&lt;br /&gt;
&amp;lt;p&amp;gt;Konfiguration testen und Nginx neu laden:&amp;lt;/p&amp;gt;&amp;lt;pre&amp;gt;&amp;lt;code&amp;gt;nginx -t&lt;br /&gt;
systemctl reload nginx&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;/pre&amp;gt;&lt;br /&gt;
== Weboberfläche aufrufen ==&lt;br /&gt;
&amp;lt;p&amp;gt;Unter&amp;lt;/p&amp;gt;[https://mail.mysystems.tld/rspamd/ https://mail.mysystems.tld/rspamd/]&amp;lt;p&amp;gt;ist die Rspamd-Weboberfläche nun erreichbar. Als Passwort wird das weiter oben erzeugte Passwort für die Weboberfläche verwendet.&amp;lt;/p&amp;gt;&lt;br /&gt;
== Via SSH-Tunnel mit der Weboberfläche verbinden (Alternative) ==&lt;br /&gt;
&amp;lt;p&amp;gt;Statt über Nginx kann man auch mithilfe eines SSH-Tunnels eine sichere Verbindung zur Rspamd-Weboberfläche aufbauen. Dazu benötigt man auf dem lokalen Rechner allerdings einen SSH-Client. Der SSH-Befehl&amp;lt;/p&amp;gt;&amp;lt;pre&amp;gt;&amp;lt;code&amp;gt;ssh -L 8080:localhost:11334 benutzer@mail.mysystems.tld -N&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;/pre&amp;gt;&amp;lt;p&amp;gt;verknüpft den Port des Webinterfaces (&amp;lt;code&amp;gt;11334&amp;lt;/code&amp;gt;) mit Port &amp;lt;code&amp;gt;8080&amp;lt;/code&amp;gt; des lokalen Systems. Im lokalen Webbrowser kann die Oberfläche nun unter http://localhost:8080 erreicht werden. Mit STRG+C wird die Verbindung wieder getrennt.&amp;lt;/p&amp;gt;&lt;br /&gt;
== Rspamd mit bestehenden Spam-E-Mails trainieren (optional) ==&lt;br /&gt;
&amp;lt;p&amp;gt;Wer einige Mails im Maildir-Format (jede E-Mail ist eine Datei) vorliegen hat, kann Rspamd mit über das rspamc-Werkzeug trainieren. Dabei ist es ist vorteilhaft, nicht nur Spammail-Beispiele zu trainieren, sondern auch Beispiele für erwünschte E-Mails. Im folgenden Beispiel wurde das Mailbox-Verzeichnis eines älteren Mailservers importiert:&amp;lt;/p&amp;gt;&amp;lt;p&amp;gt;E-Mails in einem Verzeichnis als '''Spam''' antrainieren:&amp;lt;/p&amp;gt;&amp;lt;pre&amp;gt;&amp;lt;code&amp;gt;find ./oldserver/var/vmail/mailboxes/*/*/mail/Spam/cur -type f -exec /usr/bin/rspamc learn_spam {} \;&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;/pre&amp;gt;&amp;lt;p&amp;gt;E-Mails in einem Verzeichnis als '''Ham''' (harmlos) antrainieren:&amp;lt;/p&amp;gt;&amp;lt;pre&amp;gt;&amp;lt;code&amp;gt;find ./oldserver/var/vmail/mailboxes/*/*/mail/cur -type f -exec /usr/bin/rspamc learn_ham {} \;&lt;br /&gt;
find ./oldserver/var/vmail/mailboxes/*/*/mail/Sent/cur -type f -exec /usr/bin/rspamc learn_ham {} \;&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;/pre&amp;gt;&amp;lt;p&amp;gt;Auf der Rspamd-Weboberfläche wird nach dem Training eine entsprechend höhere Anzahl an gelernten E-Mails angezeigt.&amp;lt;/p&amp;gt;&lt;br /&gt;
== Autoconfig für Mozilla Thunderbird (Optional) ==&lt;br /&gt;
&amp;lt;p&amp;gt;Mozilla Thunderbird (und andere Mailclients) versuchen bei der Einrichtung eines neuen Mailkontos automatisch, die korrekten Adressen und Einstellungen für IMAP- und SMTP-Server zu&amp;lt;/p&amp;gt;[https://developer.mozilla.org/en-US/docs/Mozilla/Thunderbird/Autoconfiguration ermitteln]&amp;lt;p&amp;gt;. Die Autokonfiguration gibt uns die Möglichkeit, unter einer festgelegten Adresse &amp;lt;code&amp;gt;https://autoconfig.&amp;amp;lt;maildomain&amp;amp;gt;.tld/mail/config-v1.1.xml&amp;lt;/code&amp;gt;Informationen zum Mailserver zu hinterlegen, sodass der Benutzer bei der Verknüpfung seines Mailkontos nichts anderes als seine Mailadresse und das Passwort anzugeben braucht. Alle weiteren Informationen wie z.B. Art der Verschlüsselung oder Port bezieht Thunderbird aus der XML-Datei.&amp;lt;/p&amp;gt;&amp;lt;p&amp;gt;Da die Servereinstellungen in diesem Setup für alle Domains identisch sind, soll die XML-Datei unter &amp;lt;code&amp;gt;https://autoconfig.mysystems.tld/mail/config-v1.1.xml&amp;lt;/code&amp;gt; zentral auf dem Mailserver verfügbar gemacht werden. Sollten neben der “mysystems.tld” Domain noch die Domains “domain1.tld” und “domain2.tld” für E-Mail mitgenutzt werden, kann mittels HTTP-Proxies auf den Zielservern dieser Domains auf die zentrale Adresse weitergeleitet werden. Doch zunächst soll es nur um den mail.mysystems.tld Mailserver gehen …&amp;lt;/p&amp;gt;&lt;br /&gt;
=== DNS-Record anlegen ===&lt;br /&gt;
&amp;lt;p&amp;gt;Für die neue autoconfig.mysystems.tld Subdomain wird ein passender CNAME-Record im DNS angelegt, welcher auf den Mailserver zeigt:&amp;lt;/p&amp;gt;&amp;lt;pre&amp;gt;&amp;lt;code&amp;gt;autoconfig.mysystems.tld. 86400 IN CNAME mail.mysystems.tld.&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;/pre&amp;gt;&lt;br /&gt;
=== Autoconfig auf dem Mailserver einrichten ===&lt;br /&gt;
&amp;lt;p&amp;gt;Um die Datei auf dem Server anzubieten, wird ein weiterer Virtual Host für den Nginx-Webserver angelegt:&amp;lt;/p&amp;gt;&amp;lt;p&amp;gt;&amp;lt;code&amp;gt;/etc/nginx/sites-available/autoconfig.mysystems.tld&amp;lt;/code&amp;gt;&amp;lt;/p&amp;gt;&amp;lt;pre&amp;gt;&amp;lt;code&amp;gt;server {&lt;br /&gt;
        listen 80;&lt;br /&gt;
        listen [::]:80;&lt;br /&gt;
#        listen 443 ssl http2;&lt;br /&gt;
#        listen [::]:443 ssl http2;&lt;br /&gt;
&lt;br /&gt;
        server_name autoconfig.mysystems.tld;&lt;br /&gt;
&lt;br /&gt;
#        ssl_certificate /etc/acme.sh/autoconfig.mysystems.tld/fullchain.pem;&lt;br /&gt;
#        ssl_certificate_key /etc/acme.sh/autoconfig.mysystems.tld/privkey.pem;&lt;br /&gt;
&lt;br /&gt;
#        add_header Strict-Transport-Security max-age=15768000;&lt;br /&gt;
&lt;br /&gt;
#        if ($ssl_protocol = &amp;quot;&amp;quot;) {&lt;br /&gt;
#            return 301 https://$server_name$request_uri;&lt;br /&gt;
#        }&lt;br /&gt;
&lt;br /&gt;
        root /var/www/mysystems.tld/autoconfig.mysystems.tld;&lt;br /&gt;
&lt;br /&gt;
        location / {&lt;br /&gt;
                add_header Content-Type text/xml;&lt;br /&gt;
                charset utf-8;&lt;br /&gt;
        }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;/pre&amp;gt;&amp;lt;p&amp;gt;''Wie auch bei der ersten Nginx-Konfiguration sind hier zunächst ein paar Zeilen auskommentiert, weil noch keine passenden TLS-Zertifikate vorhanden sind.''&amp;lt;/p&amp;gt;&amp;lt;p&amp;gt;Konfiguration aktivieren, Nginx Config prüfen und neu laden:&amp;lt;/p&amp;gt;&amp;lt;pre&amp;gt;&amp;lt;code&amp;gt;ln -s /etc/nginx/sites-available/autoconfig.mysystems.tld /etc/nginx/sites-enabled/autoconfig.mysystems.tld&lt;br /&gt;
nginx -t&lt;br /&gt;
systemctl reload nginx&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;/pre&amp;gt;&amp;lt;p&amp;gt;Für den neuen vHost wird ein Webroot directory angelegt:&amp;lt;/p&amp;gt;&amp;lt;pre&amp;gt;&amp;lt;code&amp;gt;mkdir -p /var/www/mysystems.tld/autoconfig.mysystems.tld/mail/&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;/pre&amp;gt;&amp;lt;p&amp;gt;und die XML-Konfiguration darin abgelegt:&amp;lt;/p&amp;gt;&amp;lt;p&amp;gt;&amp;lt;code&amp;gt;config-v1.1.xml&amp;lt;/code&amp;gt;&amp;lt;/p&amp;gt;&amp;lt;pre&amp;gt;&amp;lt;code&amp;gt;&amp;amp;lt;?xml version=&amp;quot;1.0&amp;quot; encoding=&amp;quot;UTF-8&amp;quot;?&amp;amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;amp;lt;clientConfig version=&amp;quot;1.1&amp;quot;&amp;amp;gt;&lt;br /&gt;
  &amp;amp;lt;emailProvider id=&amp;quot;mysystems.tld&amp;quot;&amp;amp;gt;&lt;br /&gt;
    &amp;amp;lt;domain&amp;amp;gt;mysystems.tld&amp;amp;lt;/domain&amp;amp;gt;&lt;br /&gt;
    &amp;amp;lt;displayName&amp;amp;gt;mysystems.tld Mail&amp;amp;lt;/displayName&amp;amp;gt;&lt;br /&gt;
    &amp;amp;lt;displayShortName&amp;amp;gt;mysystems.tld&amp;amp;lt;/displayShortName&amp;amp;gt;&lt;br /&gt;
    &amp;amp;lt;incomingServer type=&amp;quot;imap&amp;quot;&amp;amp;gt;&lt;br /&gt;
      &amp;amp;lt;hostname&amp;amp;gt;imap.mysystems.tld&amp;amp;lt;/hostname&amp;amp;gt;&lt;br /&gt;
      &amp;amp;lt;port&amp;amp;gt;993&amp;amp;lt;/port&amp;amp;gt;&lt;br /&gt;
      &amp;amp;lt;socketType&amp;amp;gt;SSL&amp;amp;lt;/socketType&amp;amp;gt;&lt;br /&gt;
      &amp;amp;lt;authentication&amp;amp;gt;password-cleartext&amp;amp;lt;/authentication&amp;amp;gt;&lt;br /&gt;
      &amp;amp;lt;username&amp;amp;gt;%EMAILADDRESS%&amp;amp;lt;/username&amp;amp;gt;&lt;br /&gt;
    &amp;amp;lt;/incomingServer&amp;amp;gt;&lt;br /&gt;
    &amp;amp;lt;outgoingServer type=&amp;quot;smtp&amp;quot;&amp;amp;gt;&lt;br /&gt;
      &amp;amp;lt;hostname&amp;amp;gt;smtp.mysystems.tld&amp;amp;lt;/hostname&amp;amp;gt;&lt;br /&gt;
      &amp;amp;lt;port&amp;amp;gt;465&amp;amp;lt;/port&amp;amp;gt;&lt;br /&gt;
      &amp;amp;lt;socketType&amp;amp;gt;SSL&amp;amp;lt;/socketType&amp;amp;gt;&lt;br /&gt;
      &amp;amp;lt;authentication&amp;amp;gt;password-cleartext&amp;amp;lt;/authentication&amp;amp;gt;&lt;br /&gt;
      &amp;amp;lt;username&amp;amp;gt;%EMAILADDRESS%&amp;amp;lt;/username&amp;amp;gt;&lt;br /&gt;
    &amp;amp;lt;/outgoingServer&amp;amp;gt;&lt;br /&gt;
  &amp;amp;lt;/emailProvider&amp;amp;gt;&lt;br /&gt;
&amp;amp;lt;/clientConfig&amp;amp;gt;&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;/pre&amp;gt;&amp;lt;p&amp;gt;Nun wird für autoconfig.mysystems.tld noch ein DNS-Record angelegt:&amp;lt;/p&amp;gt;&amp;lt;pre&amp;gt;&amp;lt;code&amp;gt;autoconfig.mysystems.tld IN CNAME mail.mysystems.tld.&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;/pre&amp;gt;&amp;lt;p&amp;gt;TLS-Zertifikat beantragen und installieren:&amp;lt;/p&amp;gt;&amp;lt;pre&amp;gt;&amp;lt;code&amp;gt;acme.sh --issue --server letsencrypt --nginx -d autoconfig.mysystems.tld&lt;br /&gt;
mkdir -p /etc/acme.sh/autoconfig.mysystems.tld&lt;br /&gt;
acme.sh --install-cert -d autoconfig.mysystems.tld \&lt;br /&gt;
    --key-file /etc/acme.sh/autoconfig.mysystems.tld/privkey.pem  \&lt;br /&gt;
    --fullchain-file /etc/acme.sh/autoconfig.mysystems.tld/fullchain.pem \&lt;br /&gt;
    --reloadcmd &amp;quot;systemctl reload nginx&amp;quot;&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;/pre&amp;gt;&amp;lt;p&amp;gt;'''Die auskommentierten Zeilen können nun entfernt und Nginx neu geladen werden:'''&amp;lt;/p&amp;gt;&amp;lt;pre&amp;gt;&amp;lt;code&amp;gt;systemctl reload nginx&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;/pre&amp;gt;&lt;br /&gt;
=== Optional: Autoconfig Proxy für weitere Maildomains einrichten ===&lt;br /&gt;
&amp;lt;p&amp;gt;Auf den (Web-)Servern, auf welche die weiteren Domains “domain1.tld” und “domain2.tld” verweisen, wird im Nginx jeweils ein vHost für “autoconfig.domain1.tld” bzw. “autoconfig.domain2.tld” angelegt:&amp;lt;/p&amp;gt;&amp;lt;p&amp;gt;&amp;lt;code&amp;gt;/etc/nginx/sites-available/autoconfig.domain1.tld&amp;lt;/code&amp;gt;&amp;lt;/p&amp;gt;&amp;lt;pre&amp;gt;&amp;lt;code&amp;gt;server {&lt;br /&gt;
        listen 80;&lt;br /&gt;
        listen [::]:80;&lt;br /&gt;
#       listen 443 ssl http2;&lt;br /&gt;
#       listen [::]:443 ssl http2;&lt;br /&gt;
&lt;br /&gt;
        server_name autoconfig.domain1.tld;&lt;br /&gt;
&lt;br /&gt;
#       ssl_certificate /etc/acme.sh/autoconfig.mysystems.tld/fullchain.pem;&lt;br /&gt;
#       ssl_certificate_key /etc/acme.sh/autoconfig.mysystems.tld/key.pem;&lt;br /&gt;
&lt;br /&gt;
#       add_header Strict-Transport-Security max-age=15768000;&lt;br /&gt;
&lt;br /&gt;
#       if ($ssl_protocol = &amp;quot;&amp;quot;) {&lt;br /&gt;
#           return 301 https://$server_name$request_uri;&lt;br /&gt;
#       }      &lt;br /&gt;
&lt;br /&gt;
        location / {&lt;br /&gt;
                proxy_pass https://[fd80::1]:443;&lt;br /&gt;
                proxy_set_header HOST $host;&lt;br /&gt;
        }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;/pre&amp;gt;&amp;lt;p&amp;gt;Anzupassen:&amp;lt;/p&amp;gt;&lt;br /&gt;
*&amp;lt;code&amp;gt;server_name&amp;lt;/code&amp;gt;&lt;br /&gt;
*IP-Adresse des Mailsystems &amp;lt;code&amp;gt;mail.mysytems.tld&amp;lt;/code&amp;gt; bei &amp;lt;code&amp;gt;proxy_pass&amp;lt;/code&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;''Die &amp;lt;code&amp;gt;proxy_pass&amp;lt;/code&amp;gt; Anweisung nutzt die IPv6-Adresse &amp;lt;code&amp;gt;fd::80&amp;lt;/code&amp;gt; statt des Hostnamens unseres Mailservers, da Nginx direkt nach dem Booten noch keinen DNS-Resolver zur Namensauflösung verfügbar hat.''&amp;lt;/p&amp;gt;&amp;lt;p&amp;gt;Ein DNS-Eintrag für die neue Subdomain darf nicht fehlen:&amp;lt;/p&amp;gt;&amp;lt;pre&amp;gt;&amp;lt;code&amp;gt;autoconfig.domain1.tld IN CNAME domain1.tld.&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;/pre&amp;gt;&amp;lt;p&amp;gt;Auch dieser VirtualHost sollte mit einem passenden TLS-Zertifikat abgesichert werden:&amp;lt;/p&amp;gt;&amp;lt;pre&amp;gt;&amp;lt;code&amp;gt;acme.sh --issue --server letsencrypt --nginx -d autoconfig.domain1.tld&lt;br /&gt;
mkdir -p /etc/acme.sh/autoconfig.domain1.tld&lt;br /&gt;
acme.sh --install-cert -d autoconfig.domain1.tld \&lt;br /&gt;
    --key-file /etc/acme.sh/autoconfig.domain1.tld/privkey.pem  \&lt;br /&gt;
    --fullchain-file /etc/acme.sh/autoconfig.domain1.tld/fullchain.pem \&lt;br /&gt;
    --reloadcmd &amp;quot;systemctl reload nginx&amp;quot;&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;/pre&amp;gt;&amp;lt;p&amp;gt;Die auskommentierten Zeilen in der Nginx Konfiguration können nun auskommentiert werden.&amp;lt;/p&amp;gt;&amp;lt;p&amp;gt;Aktivieren der Konfiguration und Neuladen des Webservers:&amp;lt;/p&amp;gt;&amp;lt;pre&amp;gt;&amp;lt;code&amp;gt;ln -s /etc/nginx/sites-available/autoconfig.domain1.tld /etc/nginx/sites-enabled/autoconfig.domain1.tld&lt;br /&gt;
nginx -t&lt;br /&gt;
systemctl reload nginx&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;/pre&amp;gt;&amp;lt;p&amp;gt;Ein Aufruf von&amp;lt;/p&amp;gt;[https://autoconfig.domain1.tld/mail/config-v1.1.xml https://autoconfig.domain1.tld/mail/config-v1.1.xml]&amp;lt;p&amp;gt;sollte nun dieselbe XML-Datei anzeigen, die bereits auf dem Mailserver unter &amp;lt;code&amp;gt;autoconfig.mysystems.tld&amp;lt;/code&amp;gt; hinterlegt wurde. Diese XML-Datei muss nun analog zu &amp;lt;code&amp;gt;mysystems.tld&amp;lt;/code&amp;gt; um &amp;lt;code&amp;gt;domain1.tld&amp;lt;/code&amp;gt; erweitert werden, z.B. so:&amp;lt;/p&amp;gt;&amp;lt;pre&amp;gt;&amp;lt;code&amp;gt;&amp;amp;lt;?xml version=&amp;quot;1.0&amp;quot; encoding=&amp;quot;UTF-8&amp;quot;?&amp;amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;amp;lt;clientConfig version=&amp;quot;1.1&amp;quot;&amp;amp;gt;&lt;br /&gt;
  &amp;amp;lt;emailProvider id=&amp;quot;mysystems.tld&amp;quot;&amp;amp;gt;&lt;br /&gt;
    &amp;amp;lt;domain&amp;amp;gt;mysystems.tld&amp;amp;lt;/domain&amp;amp;gt;&lt;br /&gt;
    &amp;amp;lt;displayName&amp;amp;gt;mysystems.tld Mail&amp;amp;lt;/displayName&amp;amp;gt;&lt;br /&gt;
    &amp;amp;lt;displayShortName&amp;amp;gt;mysystems.tld&amp;amp;lt;/displayShortName&amp;amp;gt;&lt;br /&gt;
    &amp;amp;lt;incomingServer type=&amp;quot;imap&amp;quot;&amp;amp;gt;&lt;br /&gt;
      &amp;amp;lt;hostname&amp;amp;gt;imap.mysystems.tld&amp;amp;lt;/hostname&amp;amp;gt;&lt;br /&gt;
      &amp;amp;lt;port&amp;amp;gt;993&amp;amp;lt;/port&amp;amp;gt;&lt;br /&gt;
      &amp;amp;lt;socketType&amp;amp;gt;SSL&amp;amp;lt;/socketType&amp;amp;gt;&lt;br /&gt;
      &amp;amp;lt;authentication&amp;amp;gt;password-cleartext&amp;amp;lt;/authentication&amp;amp;gt;&lt;br /&gt;
      &amp;amp;lt;username&amp;amp;gt;%EMAILADDRESS%&amp;amp;lt;/username&amp;amp;gt;&lt;br /&gt;
    &amp;amp;lt;/incomingServer&amp;amp;gt;&lt;br /&gt;
    &amp;amp;lt;outgoingServer type=&amp;quot;smtp&amp;quot;&amp;amp;gt;&lt;br /&gt;
      &amp;amp;lt;hostname&amp;amp;gt;smtp.mysystems.tld&amp;amp;lt;/hostname&amp;amp;gt;&lt;br /&gt;
      &amp;amp;lt;port&amp;amp;gt;465&amp;amp;lt;/port&amp;amp;gt;&lt;br /&gt;
      &amp;amp;lt;socketType&amp;amp;gt;SSL&amp;amp;lt;/socketType&amp;amp;gt;&lt;br /&gt;
      &amp;amp;lt;authentication&amp;amp;gt;password-cleartext&amp;amp;lt;/authentication&amp;amp;gt;&lt;br /&gt;
      &amp;amp;lt;username&amp;amp;gt;%EMAILADDRESS%&amp;amp;lt;/username&amp;amp;gt;&lt;br /&gt;
    &amp;amp;lt;/outgoingServer&amp;amp;gt;&lt;br /&gt;
  &amp;amp;lt;/emailProvider&amp;amp;gt;&lt;br /&gt;
&lt;br /&gt;
  &amp;amp;lt;emailProvider id=&amp;quot;domain1.tld&amp;quot;&amp;amp;gt;&lt;br /&gt;
    &amp;amp;lt;domain&amp;amp;gt;domain1.tld&amp;amp;lt;/domain&amp;amp;gt;&lt;br /&gt;
    &amp;amp;lt;displayName&amp;amp;gt;domain1.tld Mail&amp;amp;lt;/displayName&amp;amp;gt;&lt;br /&gt;
    &amp;amp;lt;displayShortName&amp;amp;gt;domain1.tld&amp;amp;lt;/displayShortName&amp;amp;gt;&lt;br /&gt;
    &amp;amp;lt;incomingServer type=&amp;quot;imap&amp;quot;&amp;amp;gt;&lt;br /&gt;
      &amp;amp;lt;hostname&amp;amp;gt;imap.mysystems.tld&amp;amp;lt;/hostname&amp;amp;gt;&lt;br /&gt;
      &amp;amp;lt;port&amp;amp;gt;993&amp;amp;lt;/port&amp;amp;gt;&lt;br /&gt;
      &amp;amp;lt;socketType&amp;amp;gt;SSL&amp;amp;lt;/socketType&amp;amp;gt;&lt;br /&gt;
      &amp;amp;lt;authentication&amp;amp;gt;password-cleartext&amp;amp;lt;/authentication&amp;amp;gt;&lt;br /&gt;
      &amp;amp;lt;username&amp;amp;gt;%EMAILADDRESS%&amp;amp;lt;/username&amp;amp;gt;&lt;br /&gt;
    &amp;amp;lt;/incomingServer&amp;amp;gt;&lt;br /&gt;
    &amp;amp;lt;outgoingServer type=&amp;quot;smtp&amp;quot;&amp;amp;gt;&lt;br /&gt;
      &amp;amp;lt;hostname&amp;amp;gt;smtp.mysystems.tld&amp;amp;lt;/hostname&amp;amp;gt;&lt;br /&gt;
      &amp;amp;lt;port&amp;amp;gt;465&amp;amp;lt;/port&amp;amp;gt;&lt;br /&gt;
      &amp;amp;lt;socketType&amp;amp;gt;SSL&amp;amp;lt;/socketType&amp;amp;gt;&lt;br /&gt;
      &amp;amp;lt;authentication&amp;amp;gt;password-cleartext&amp;amp;lt;/authentication&amp;amp;gt;&lt;br /&gt;
      &amp;amp;lt;username&amp;amp;gt;%EMAILADDRESS%&amp;amp;lt;/username&amp;amp;gt;&lt;br /&gt;
    &amp;amp;lt;/outgoingServer&amp;amp;gt;&lt;br /&gt;
  &amp;amp;lt;/emailProvider&amp;amp;gt;&lt;br /&gt;
&amp;amp;lt;/clientConfig&amp;amp;gt;&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;/pre&amp;gt;&amp;lt;p&amp;gt;Für “domain2.tld” ist genauso vorzugehen.&amp;lt;/p&amp;gt;&lt;br /&gt;
== Domains, Accounts, Aliase und TLS-Policies in Datenbank definieren ==&lt;br /&gt;
&amp;lt;p&amp;gt;Bevor der Mailserver sinnvoll genutzt werden kann, müssen noch Domains und Benutzer im der MySQL-Datenbank registriert werden. Loggt euch wieder auf der MySQL-Kommandozeile ein:&amp;lt;/p&amp;gt;&amp;lt;pre&amp;gt;&amp;lt;code&amp;gt;mysql&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;/pre&amp;gt;&amp;lt;p&amp;gt;… und wechselt in die vmail-Datenbank:&amp;lt;/p&amp;gt;&amp;lt;pre&amp;gt;&amp;lt;code&amp;gt;use vmail;&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;/pre&amp;gt;&lt;br /&gt;
=== Neue Domain anlegen ===&lt;br /&gt;
&amp;lt;p&amp;gt;Damit ein neuer Benutzeraccount oder ein neuer Alias angelegt werden kann, muss die zu nutzende Domain zuvor im Mailsystem bekannt gemacht werden. Postfix verarbeitet nur E-Mails an Domains, die in der “domains”-Tabelle eingetragen sind:&amp;lt;/p&amp;gt;&amp;lt;pre&amp;gt;&amp;lt;code&amp;gt;insert into domains (domain) values ('mysystems.tld');&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;/pre&amp;gt;&lt;br /&gt;
=== Neuen E-Mail-Account anlegen ===&lt;br /&gt;
&amp;lt;p&amp;gt;Wenn die Benutzerdomain in der Domain-Tabelle angelegt ist, kann ein neuer Benutzeraccount für den Mailserver erstellt werden. Bevor das passende SQL-Kommando eingegeben und abgeschickt wird, wird jedoch zu nächst ein Passwort-Hash des gewünschten Passworts für den Account erzeugt. Mit&amp;lt;/p&amp;gt;&amp;lt;pre&amp;gt;&amp;lt;code&amp;gt;doveadm pw -s SHA512-CRYPT&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;/pre&amp;gt;&amp;lt;p&amp;gt;'''(in der Bash Shell! - Nicht in der MySQL Shell!)''' kann ein solcher Hash erzeugt werden. Beispiel für einen ausgegebenen Hash:&amp;lt;/p&amp;gt;&amp;lt;pre&amp;gt;&amp;lt;code&amp;gt;{SHA512-CRYPT}$6$wHyJsS.doo39xoCu$KI1N4l.Vd0ZWYj5BYLI8AdK7ACwAZaM18gSy7Bko0dG2Hvli4.KfAmLk2ztFVP.R4T7oqiu7clKBehCTc4GGw0&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;/pre&amp;gt;&amp;lt;p&amp;gt;Dieser Hash ist für jedes Passwort einzigartig und ändert sich sogar bei jeder Generierung. Legt den Hash am besten gleich in eurer Zwischenablage oder einem Textdokument ab - ihr benötigt ihn gleich!&amp;lt;/p&amp;gt;&amp;lt;div class=&amp;quot;warning&amp;quot;&amp;gt;Verwendet auch an dieser Stelle möglichst nur die Zeichen 0-9, a-z und A-z. Sonderzeichen können Probleme verursachen. Wenn eure Passwörter einigermaßen lang sind, reicht das völlig aus. Sonderzeichen bringen dann ohnehin keinen nennenswerten Sicherheitsgewinn.&amp;lt;/div&amp;gt;&amp;lt;p&amp;gt;Das SQL-Kommando zum Erzeugen eines neuen Accounts lautet:&amp;lt;/p&amp;gt;&amp;lt;pre&amp;gt;&amp;lt;code&amp;gt;insert into accounts (username, domain, password, quota, enabled, sendonly) values ('user1', 'mysystems.tld', '{SHA512-CRYPT}$6$wHyJsS[...]', 2048, true, false);&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;/pre&amp;gt;&amp;lt;p&amp;gt;In das “Password”-Feld wird der Hash vollständig eingetragen (hier: gekürzt).&amp;lt;/p&amp;gt;&amp;lt;p&amp;gt;Legt am besten gleich den &amp;lt;code&amp;gt;postmaster@mysystems.tld&amp;lt;/code&amp;gt; Account an. Er sollte auf jedem Mailserver vorhanden sein, um den Administrator bei technischen Problemen mit dem Server erreichen zu können.&amp;lt;/p&amp;gt;&lt;br /&gt;
=== Neuen Alias anlegen ===&lt;br /&gt;
&amp;lt;pre&amp;gt;&amp;lt;code&amp;gt;insert into aliases (source_username, source_domain, destination_username, destination_domain, enabled) values ('alias', 'mysystems.tld', 'user1', 'mysystems.tld', true);&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;/pre&amp;gt;&amp;lt;p&amp;gt;… legt einen Alias für den Benutzer “&amp;lt;/p&amp;gt;[mailto:user1@mysystems.tld user1@mysystems.tld]&amp;lt;p&amp;gt;” an. E-Mails an “&amp;lt;/p&amp;gt;[mailto:alias@mysystems.tld alias@mysystems.tld]&amp;lt;p&amp;gt;” werden dann an die Mailbox dieses Users zugestellt.&amp;lt;/p&amp;gt;&amp;lt;p&amp;gt;Als Zieladressen können auch E-Mail-Konten auf fremden Servern angegeben werden. Postfix leitet diese E-Mails dann weiter. Dabei kann es allerdings zu Problemen mit SPF-Records kommen – schließlich schickt Postfix unter bestimmten Umständen E-Mails unter fremden Domains, für die er laut SPF-Record nicht zuständig ist. SRS (Sender Rewriting Scheme) ist eine Lösung für dieses Problem. Von Erweiterungen, die schwerwiegende Design-Fehler einer Technik wie SPF korrigieren, halte ich allerdings nicht besonders viel, sodass ich euch empfehle, den SPF-Record (wie oben) auf einem “?all” gestellt zu lassen und auf Weiterleitungen zu fremden Servern möglichst zu verzichten. Aliase von lokalen Adressen auf andere lokale Adressen sind kein Problem.&amp;lt;/p&amp;gt;&amp;lt;p&amp;gt;Wenn ein '''E-Mail-Verteiler''' eingerichtet werden soll, werden mehrere Datensätze mit derselben Quelladresse eingerichtet, also z.B. so:&amp;lt;/p&amp;gt;&amp;lt;pre&amp;gt;&amp;lt;code&amp;gt;team@domain.tld =&amp;amp;gt; user1@domain.tld&lt;br /&gt;
team@domain.tld =&amp;amp;gt; user2@domain.tld&lt;br /&gt;
team@domain.tld =&amp;amp;gt; user3@domain.tld&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;/pre&amp;gt;&amp;lt;p&amp;gt;Ein '''Catch-All''' hingegen kann erreicht werden, indem der &amp;lt;code&amp;gt;source_username&amp;lt;/code&amp;gt; auf &amp;lt;code&amp;gt;null&amp;lt;/code&amp;gt; gesetzt wird, z.B. so:&amp;lt;/p&amp;gt;&amp;lt;pre&amp;gt;&amp;lt;code&amp;gt;insert into aliases (source_username, source_domain, destination_username, destination_domain, enabled) values (null, 'domain1.tld', 'catchall', 'mysystems.tld', true);&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;/pre&amp;gt;&amp;lt;p&amp;gt;Ein Catch-All kann mit anderen Aliasen auf derselben Domain ko-existieren und “fängt” alle Benutzernamen auf der jeweiligen Domain auf, für die noch kein Alias gesetzt wurde. So kann man Mails zentral aufsammeln, welche an Mailboxen verschickt wurden, die auf dem Mailserver nicht existieren. Beachtet, dass dadurch das Spamaufkommen ggf. höher ist.&amp;lt;/p&amp;gt;&lt;br /&gt;
=== Neue TLS-Policy anlegen (optional) ===&lt;br /&gt;
&amp;lt;p&amp;gt;Mithilfe der TLS Policy-Tabelle kann festgelegt werden, mit welchen Sicherheitsfeatures mit den Mailservern einer bestimmten Domain kommuniziert werden soll. Wenn für die Domain “thomas-leister.de” beispielsweise “dane-only” in “policy” festgelegt wird, wird die Verbindung zu Mailservern dieser Domain nur noch gültig sein, wenn sie DANE-authentifiziert und verschlüsselt ist. Mögliche Policies sind:&amp;lt;/p&amp;gt;&lt;br /&gt;
*&amp;lt;code&amp;gt;none&amp;lt;/code&amp;gt;: Keine Verschlüsselung nutzen, auch wenn der andere Mailserver das unterstützt.&lt;br /&gt;
*&amp;lt;code&amp;gt;may&amp;lt;/code&amp;gt;: Verschlüsseln, wenn der andere Server dies unterstützt, aber keine Zertifikatsprüfung (self-signed Zertifikate werden akzeptiert).&lt;br /&gt;
*&amp;lt;code&amp;gt;encrypt&amp;lt;/code&amp;gt;: Zwingend Verschlüsseln, allerdings keine Zertifikatsprüfung (self-signed Zertifikate werden akzeptiert).&lt;br /&gt;
*&amp;lt;code&amp;gt;dane&amp;lt;/code&amp;gt;: Wenn gültige TLSA-Records gefunden werden, wird zwingend verschlüsselt und das Zertifikat mittels DANE verifiziert. Falls ungültige TLSA-Records gefunden werden, wird auf “encrypt” zurückgegriffen. Falls gar keine TLSA-Records gefunden werden, wird “may” genutzt.&lt;br /&gt;
*&amp;lt;code&amp;gt;dane-only&amp;lt;/code&amp;gt;: Nur verschlüsselte Verbindungen. Gültige TLSA-Records für den Hostnamen müssen existieren (DANE)&lt;br /&gt;
*&amp;lt;code&amp;gt;verify&amp;lt;/code&amp;gt;: Nur verschlüsselte Verbindungen + Prüfung der CA. Der Hostname aus dem MX DNS-Record muss im Zertifikat enthalten sein. (Basiert auf Vertrauen in korrekte DNS-Daten)&lt;br /&gt;
*&amp;lt;code&amp;gt;secure&amp;lt;/code&amp;gt;: Nur verschlüsselte Verbindungen + Prüfung der CA. Der andere Mailserver muss (standardmäßig) einen Hostnamen haben, der “.domain.tld” oder nur “domain.tld” entspricht. Dieser Hostname muss im Zertifikat enthalten sein. Auf das DNS wird nicht zurückgegriffen (Sicherheitsvorteil gegenüber “verify). Beispiel: Eine E-Mail an[mailto:user@web.de user@web.de]soll gesendet werden. Der MX-Mailserver von Web.de dürfte dann nur den Hostnamen “web.de” oder eine Subdomain davon als Hostnamen haben, z.B. mx.web.de. Eine Verbindung zu mx.web.net wäre nicht zulässig.&lt;br /&gt;
&amp;lt;p&amp;gt;Für Domains der großen Anbieter wie gmx.de, web.de und der Telekom kann man “secure” wählen. Bei Posteo und Mailbox.org sogar “dane-only”. Für alle Provider, die keine gültigen TLS-Zertifikate einsetzen, kann “encrypt” gewählt werden. Standardeinstellung für alle anderen Mailserver ist “dane” (siehe main.cf der Postfix Config).&amp;lt;/p&amp;gt;&amp;lt;p&amp;gt;Das Feld “params” wird mit zusätzlichen Infos gefüllt, wenn sie für einen Policy-Typ erforderlich sind, z.B. für einen “secure” Eintrag zu GMX:&amp;lt;/p&amp;gt;&amp;lt;pre&amp;gt;&amp;lt;code&amp;gt;insert into tlspolicies (domain, policy, params) values ('gmx.de', 'secure', 'match=.gmx.net');&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;/pre&amp;gt;&amp;lt;p&amp;gt;Standardmäßig überprüft Postfix bei “secure” – wie oben bereits erwähnt – ob die Empfängerdomain (gmx.de) im Zertifikat des Zielservers vorhanden ist. Bei GMX (und vielen anderen großen Anbietern) ist das allerdings nicht der Fall: Die Mailserver-Zertifikate von GMX sind nur für gmx.net + Subdomains gültig. Ließe man den Datenbank-Eintrag für GMX ohne weitere Einstellungen auf “secure” stehen, könnten an GMX keine Mails mehr übermittelt werden. Deshalb ist es wichtig, für GMX festzulegen, dass im Zertifikat nicht nach “gmx.de” sondern nach “gmx.net” gesucht werden soll. Das können wir mithilfe des Felds “params” und der “match=…” Zeichenkette tun. Wenn nach mehreren Domains gesucht werden soll, können auch mehrere angegeben werden, z.B. so: “match=.gmx.net:.gmx.ch”. Die zusätzlichen Angaben in “params” sind allerdings nicht für jeden Mailprovider notwendig. GMX ist eine Ausnahme – genauso wie z.B. Yahoo. Ob ihr in “params” einen “match”-String angeben müsst, könnt ihr z.B. über&amp;lt;/p&amp;gt;[https://de.ssl-tools.net/ https://de.ssl-tools.net/]&amp;lt;p&amp;gt;herausfinden. Wenn die 2-nd-Level-Domain des Mailservers von der Domain der Mailadressen abweicht, muss ein passender match-String angegeben werden.&amp;lt;/p&amp;gt;&amp;lt;p&amp;gt;Andere Einstellungen wie “dane-only” erfordern keine zusätzlichen Angaben in “params”:&amp;lt;/p&amp;gt;&amp;lt;pre&amp;gt;&amp;lt;code&amp;gt;insert into tlspolicies (domain, policy) values ('mailbox.org', 'dane-only');&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;/pre&amp;gt;&amp;lt;p&amp;gt;In diesem Fall wird mit den Mailservern von mailbox.org nur noch DANE-gesichert und verschlüsselt kommuniziert. Die MySQL-Kommandozeile kann mit einem &amp;lt;code&amp;gt;quit;&amp;lt;/code&amp;gt; wieder verlassen werden.&amp;lt;/p&amp;gt;&lt;br /&gt;
== Optional: Firewall konfigurieren ==&lt;br /&gt;
&amp;lt;p&amp;gt;Wer vor / auf dem Mailserver eine Firewall betreibt, die den Zugriff auf Ports beschränkt, sollte zuerst alle Mailserver-Ports freischalten:&amp;lt;/p&amp;gt;&amp;lt;pre&amp;gt;&amp;lt;code&amp;gt;IMAP:           143/tcp&lt;br /&gt;
IMAPS:          993/tcp&lt;br /&gt;
Submission:     587/tcp&lt;br /&gt;
SMTPS:          465/tcp&lt;br /&gt;
SMTP:            25/tcp&lt;br /&gt;
ManageSieve:   4190/tcp&lt;br /&gt;
Web HTTP:        80/tcp&lt;br /&gt;
Web HTTPS:      443/tcp&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;/pre&amp;gt;&amp;lt;p&amp;gt;'''Denkt unbedingt daran, auch eure IPv6-Ports zu öffnen!''' - Euer Mailsetup spricht IPv6! :-) Die Ports 143 und 587 können geschlossen bleiben, wenn keine StartTLS-basierenden Verbindung genutzt werden sollen (siehe Hinweis weiter unten).&amp;lt;/p&amp;gt;&lt;br /&gt;
== Start all the things! ==&lt;br /&gt;
&amp;lt;p&amp;gt;Euer neuer Mailserver ist jetzt fertig konfiguriert. Zeit für einen ersten Start!&amp;lt;/p&amp;gt;&amp;lt;pre&amp;gt;&amp;lt;code&amp;gt;systemctl start dovecot&lt;br /&gt;
systemctl start postfix&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;/pre&amp;gt;&amp;lt;div class=&amp;quot;warning&amp;quot;&amp;gt;&amp;lt;p&amp;gt;Wegen des Bugs&amp;lt;/p&amp;gt;[https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=877992 #877992]&amp;lt;p&amp;gt;startet Postfix nach einem Reboot nicht mehr. Abhilfe schafft folgendes Kommando:&amp;lt;/p&amp;gt;&amp;lt;pre&amp;gt;&amp;lt;code&amp;gt;systemctl enable postfix@-&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;/pre&amp;gt;&amp;lt;p&amp;gt;(beachte das Minuszeichen &amp;lt;code&amp;gt;-&amp;lt;/code&amp;gt; am Ende!)&amp;lt;/p&amp;gt;&amp;lt;/div&amp;gt;&amp;lt;p&amp;gt;Kontrolliert am besten gleich die Logfiles nach auffälligen Fehlern. Ich empfehle das “tail” Tool in einer separaten Terminal-Sitzung. Neue Log-Einträge erscheinen damit sofort auf dem Bildschirm:&amp;lt;/p&amp;gt;&amp;lt;pre&amp;gt;&amp;lt;code&amp;gt;tail -f /var/log/syslog&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;/pre&amp;gt;&amp;lt;p&amp;gt;bzw.&amp;lt;/p&amp;gt;&amp;lt;pre&amp;gt;&amp;lt;code&amp;gt;tail -f /var/log/mail.log&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;/pre&amp;gt;&amp;lt;p&amp;gt;Wenn ihr hier Fehler entdeckt, seht nach, ob ihr alle erforderlichen Änderungen an den Konfigurationsdateien durchgeführt habt (oder ob sich noch beispielhafte Hashes oder Beispieldomains darin befinden).&amp;lt;/p&amp;gt;&lt;br /&gt;
== Eine Verbindung zum Mailserver herstellen ==&lt;br /&gt;
&amp;lt;figure&amp;gt;&amp;lt;figcaption&amp;gt;Mailserver Logindaten für Thunderbird&amp;lt;/figcaption&amp;gt;&amp;lt;/figure&amp;gt;&amp;lt;p&amp;gt;Eine Verbindung könnt ihr über jeden IMAP-fähigen E-Mail-Client und den folgenden Verbindungsparametern herstellen:&amp;lt;/p&amp;gt;&lt;br /&gt;
*IMAP(S)&lt;br /&gt;
**Host: imap.mysystems.tld&lt;br /&gt;
**Port: 993&lt;br /&gt;
**Verschlüsselung: TLS&lt;br /&gt;
**(dieser Server gilt auch für domain2 und domain3, falls vorhanden!)&lt;br /&gt;
*SMTP(S)&lt;br /&gt;
**Host: smtp.mysystems.tld&lt;br /&gt;
**Port: 465&lt;br /&gt;
**Verschlüsselung: TLS&lt;br /&gt;
**(dieser Server gilt auch für domain2 und domain3, falls vorhanden!)&lt;br /&gt;
*Managesieve (optional, zur Konfiguration der benutzerspezifischen Sieve-Filterregeln)&lt;br /&gt;
**Host: imap.mysystems.tld&lt;br /&gt;
**Port: 4190&lt;br /&gt;
**Verschlüsselung: StartTLS&lt;br /&gt;
*Benutzername: Die '''vollständige''' E-Mail-Adresse, also @&amp;amp;lt;domain.tld&amp;amp;gt;&lt;br /&gt;
*Passwort: Sollte bekannt sein ;-)&lt;br /&gt;
&amp;lt;p&amp;gt;Sollten Verbindungen über die IMAPS (993) und SMTPS (465) Ports nicht möglich sein, kann auch auf die StartTLS-Ports zurückgegriffen werden:&amp;lt;/p&amp;gt;&lt;br /&gt;
*IMAP-Server:&lt;br /&gt;
**Host: mail.mysystems.tld&lt;br /&gt;
**Port: 143&lt;br /&gt;
**Verschlüsselung: StartTLS&lt;br /&gt;
*SMTP-Server:&lt;br /&gt;
**Host: mail.mysystems.tld&lt;br /&gt;
**Port: 587&lt;br /&gt;
**Verschlüsselung: StartTLS&lt;br /&gt;
&amp;lt;p&amp;gt;Die IETF (Internet Engineering Task Force) empfiehlt seit 2018 allerdings, auf StartTLS Verbindungen zu verzichten, und auf native TLS-Verbindungen zu setzen:&amp;lt;/p&amp;gt;[https://tools.ietf.org/html/rfc8314 https://tools.ietf.org/html/rfc8314]&amp;lt;div class=&amp;quot;tip&amp;quot;&amp;gt;Der erste Login kann ein paar Sekunden in Anspruch nehmen - habt etwas Gedult. Dovecot legt im Hintergrund die Verzeichnisstruktur für den neuen Benutzer an.&amp;lt;/div&amp;gt;&lt;br /&gt;
== Spamfilter testen ==&lt;br /&gt;
&amp;lt;p&amp;gt;Schickt einfach eine E-Mail mit dem Text&amp;lt;/p&amp;gt;&amp;lt;pre&amp;gt;&amp;lt;code&amp;gt;XJS*C4JDBQADN1.NSBN3*2IDNEN*GTUBE-STANDARD-ANTI-UBE-TEST-EMAIL*C.34X&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;/pre&amp;gt;&amp;lt;p&amp;gt;an einen Account eures neuen Mailservers. Die E-Mail sollte nicht ankommen und im Rspamd-Webinterface erscheint ein entsprechender rot markierter Eintrag in der History.&amp;lt;/p&amp;gt;&lt;br /&gt;
== Debugging ==&lt;br /&gt;
&amp;lt;p&amp;gt;Sollten Probleme auftreten, hilft ein Blick ins Log!&amp;lt;/p&amp;gt;&amp;lt;p&amp;gt;Das Rspamd Log kannst du z.B. so einsehen und live mitlesen:&amp;lt;/p&amp;gt;&amp;lt;pre&amp;gt;&amp;lt;code&amp;gt;journalctl -f -u rspamd&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;/pre&amp;gt;&amp;lt;p&amp;gt;Postfix so:&amp;lt;/p&amp;gt;&amp;lt;pre&amp;gt;&amp;lt;code&amp;gt;journalctl -f -u postfix@-.service&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;/pre&amp;gt;&amp;lt;p&amp;gt;… und Dovecot so:&amp;lt;/p&amp;gt;&amp;lt;pre&amp;gt;&amp;lt;code&amp;gt;journalctl -f -u dovecot&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;/pre&amp;gt;&amp;lt;hr&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;hr&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Fragen und AntwortenWelche Daten sollte ich für Backups Sichern? ==&lt;br /&gt;
&amp;lt;p&amp;gt;Folgende Verzeichnisse sollten ins Backup aufgenommen werden:&amp;lt;/p&amp;gt;&lt;br /&gt;
*&amp;lt;code&amp;gt;/etc/postfix&amp;lt;/code&amp;gt; (Postfix Konfiguration)&lt;br /&gt;
*&amp;lt;code&amp;gt;/etc/dovecot&amp;lt;/code&amp;gt; (Dovecot Konfiguration)&lt;br /&gt;
*&amp;lt;code&amp;gt;/etc/rspamd&amp;lt;/code&amp;gt; (Rspamd Konfiguration)&lt;br /&gt;
*&amp;lt;code&amp;gt;/var/vmail&amp;lt;/code&amp;gt; (E-Mails, Benutzerkonteneinstellungen und Sieve-Filter)&lt;br /&gt;
*&amp;lt;code&amp;gt;/var/lib/rspamd/dkim&amp;lt;/code&amp;gt; (DKIM-Schlüssel)&lt;br /&gt;
*&amp;lt;code&amp;gt;/var/www/mysystems.tld/autoconfig.mysystems.tld&amp;lt;/code&amp;gt; (Autoconfig-Datei)&lt;br /&gt;
&amp;lt;p&amp;gt;Außerdem sollte unbedingt regelmäßig ein MySQL-Dump der &amp;lt;code&amp;gt;vmail&amp;lt;/code&amp;gt; Datenbank generiert, in eine Datei geschrieben und ins Backup aufgenommen werden:&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;pre&amp;gt;&amp;lt;code&amp;gt;mysqldump vmail &amp;amp;gt; /root/backups/vmail.sql&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Häufige Fehler ==&lt;br /&gt;
=== “fatal: no SASL authentication mechanisms” / “SASL: Connect to private/auth failed: No such file or directory” ===&lt;br /&gt;
&amp;lt;p&amp;gt;Das Problem: Postfix kann Benutzer nicht authentifizieren, weil in /var/spool/postfix/private kein “auth” Socket verfügbar ist. Eigentlich sollte Dovecot diesen Socket bereitstellen. Der Fehler ist also bei Dovecot zu suchen – nicht bei Postfix. Leider hat die Erfahrung gezeigt, dass ein Vertipper nicht zwingend in der Socket-Konfiguration&amp;lt;/p&amp;gt;&amp;lt;pre&amp;gt;&amp;lt;code&amp;gt;unix_listener /var/spool/postfix/private/auth {&lt;br /&gt;
    mode = 0660&lt;br /&gt;
    user = postfix&lt;br /&gt;
    group = postfix&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;/pre&amp;gt;&amp;lt;p&amp;gt;vorhanden sein muss. Es kommt immer wieder vor, dass der Fehler irgendwo anders in der Dovecot-Konfiguration liegt. Dovecot verschweigt einem dann den Fehler und erstellt den auth-Socket für Postfix nicht. Es lohnt sich in so einem Fall, noch einmal die ganze Dovecot-Konfiguration nach Fehlern abzusuchen.&amp;lt;/p&amp;gt;&lt;br /&gt;
=== “5.7.1 Service unavailable; client [1.3.3.7] blocked using zen.spamhaus.org” ===&lt;br /&gt;
&amp;lt;p&amp;gt;Das Problem: Der Mailserver akzeptiert keine E-Mails vom Mailclient und gibt die oben genannte Fehlermeldung zurück.&amp;lt;/p&amp;gt;&amp;lt;p&amp;gt;Das Problem lässt sich sehr einfach lösen, indem statt SMTP-Port 25 der SMTS-Port 465 oder Submission-Port 587 für den Mailversand im Mailclient konfiguriert wird. Auf Port 25 ist eine Blacklist aktiv, welche viele IP-Adressen z.B. aus DSL-Adressbereichen enthält. Diese Einschränkung gilt für die beiden anderen Ports nicht. Mailclients sollten niemals Port 25 zum versenden Nutzen.&amp;lt;/p&amp;gt;&lt;br /&gt;
=== Mailclient verbindet sich nicht zum Server ===&lt;br /&gt;
&lt;br /&gt;
*Evtl. blockiert der Virenschutz die Verbindung?&lt;br /&gt;
*Blockiert die Server-Firewall die Verbindung von außen?&lt;br /&gt;
*Ist die richtige Serveradresse angegeben? (siehe Verbindungseinstellungen oben)&lt;br /&gt;
*Werden die richtigen Ports genutzt und ist der Verschlüsselungstyp richtig eingestellt?&lt;/div&gt;</summary>
		<author><name>Admin</name></author>
	</entry>
	<entry>
		<id>https://wiki.my-network.at/index.php?title=Dovecot_Mailserver&amp;diff=35</id>
		<title>Dovecot Mailserver</title>
		<link rel="alternate" type="text/html" href="https://wiki.my-network.at/index.php?title=Dovecot_Mailserver&amp;diff=35"/>
		<updated>2022-08-24T11:48:25Z</updated>

		<summary type="html">&lt;p&gt;Admin: /* Das war’s auch schon! Hat dir diese Anleitung geholfen? */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&amp;lt;header&amp;gt;&lt;br /&gt;
= Mailserver mit Dovecot, Postfix, MySQL und Rspamd unter Debian 10 Buster [v1.0] =&lt;br /&gt;
&amp;lt;div class=&amp;quot;translations&amp;quot;&amp;gt;&amp;lt;br&amp;gt;&amp;lt;/div&amp;gt;&amp;lt;/header&amp;gt;&lt;br /&gt;
== Mailserver-Funktionen ==&lt;br /&gt;
&amp;lt;p&amp;gt;Damit ihr einen Eindruck vom Funktionsumfang des fertigen Mailsetups bekommt, hier einige Merkmale:&amp;lt;/p&amp;gt;&lt;br /&gt;
*Senden und Empfangen von E-Mails für beliebige Domains&lt;br /&gt;
*Flexible Einrichtung von Domains, Mailaccounts, Aliasen, Weiterleitungen und Regeln für die Transportverschlüsselung über ein MySQL-Backend zur Laufzeit&lt;br /&gt;
*Nutzer-spezifisch begrenztes Mailbox-Volumen&lt;br /&gt;
*Einrichtung allgemeiner und Nutzer-spezifischer Sieve-Filterregeln zum Filtern und/oder Umsortieren eingehender E-Mails&lt;br /&gt;
*Zuverlässige und moderne Spamerkennung via Rspamd (+ Weboberfläche für Spam-Statistiken)&lt;br /&gt;
*“Send only” Accounts z.B. für NextCloud / Forensoftware / …&lt;br /&gt;
*DKIM-und ARC-Signierung ausgehender E-Mails&lt;br /&gt;
*Mailclient Autokonfiguration&lt;br /&gt;
*Domain Catch-All&lt;br /&gt;
&amp;lt;p&amp;gt;Eine '''Weboberfläche''' / ein '''Management-Tool''' zur Verwaltung dieses Setups biete ich selbst nach wie vor nicht an. In der Zwischenzeit haben aber andere User Lösungen veröffentlicht, z.B.&amp;lt;/p&amp;gt;&lt;br /&gt;
*Florian Kapfenberger:[https://github.com/phiilu/mailman Mailman]''(nicht zu verwechseln mit Mailman, dem Mailinglist-Manager!)''&lt;br /&gt;
*Andreas Bresch:[https://github.com/Andreas-Bresch/vmailManage/ VmailManage]&lt;br /&gt;
&lt;br /&gt;
*Henrik Halbritter:[https://github.com/Halbritter/MailAdmin/releases MailAdmin]&lt;br /&gt;
*awidegreen:[https://github.com/awidegreen/vmail-rs vmail-rs](CLI-Tool!)&lt;br /&gt;
*pprugger:[https://github.com/pprugger/vmail-admin vmail-admin]&lt;br /&gt;
*Kekskurse:[https://github.com/kekskurse/go-mail-admin Go-Mail-Admin]&lt;br /&gt;
&amp;lt;div class=&amp;quot;tip&amp;quot;&amp;gt;Das Datenbank-Layout und die Struktur des &amp;lt;code&amp;gt;/var/vmail&amp;lt;/code&amp;gt;-Verzeichnisses haben sich im Vergleich zur vorherigen Anleitung ''nicht'' geändert. Ein Update älterer Setups ist also einfach realisierbar.&amp;lt;/div&amp;gt;&amp;lt;hr&amp;gt;&lt;br /&gt;
== Verwendete Software ==&lt;br /&gt;
&lt;br /&gt;
*Debian 10 “Buster”&lt;br /&gt;
*Postfix&lt;br /&gt;
*Dovecot&lt;br /&gt;
*Rspamd&lt;br /&gt;
*Redis&lt;br /&gt;
*MariaDB&lt;br /&gt;
*Nginx&lt;br /&gt;
&lt;br /&gt;
== Gegebenheiten ==&lt;br /&gt;
&amp;lt;p&amp;gt;In dieser Anleitung kommen folgende Domains vor:&amp;lt;/p&amp;gt;&lt;br /&gt;
*&amp;lt;code&amp;gt;mysystems.tld&amp;lt;/code&amp;gt;: Übergeordnete, primäre Domain&lt;br /&gt;
*&amp;lt;code&amp;gt;mail.mysystems.tld&amp;lt;/code&amp;gt;: Subdomain, unter der der Mailserver verfügbar sein soll (FQDN des Mailsystems)&lt;br /&gt;
*&amp;lt;code&amp;gt;imap.mysystems.tld&amp;lt;/code&amp;gt;: Alias auf mail.mysystems.tld, wird von vielen Mailclient automatisch gesucht und gefunden&lt;br /&gt;
*&amp;lt;code&amp;gt;smtp.mysystems.tld&amp;lt;/code&amp;gt;: Dasselbe für den SMTP-Dienst&lt;br /&gt;
*&amp;lt;code&amp;gt;domain2.tld&amp;lt;/code&amp;gt;: Eine zweite Domain neben mysystems.tld, für die E-Mails gesendet und empfangen werden sollen&lt;br /&gt;
*&amp;lt;code&amp;gt;domain3.tld&amp;lt;/code&amp;gt;: Eine dritte Domain, für die E-Mails gesendet und empfangen werden sollen&lt;br /&gt;
&amp;lt;p&amp;gt;'''Diese Domains müssen in der ''gesamten'' Anleitung selbstverständlich durch eigene ersetzt werden!'''&amp;lt;br&amp;gt;Auf domain2.tld und domain3.tld kann verzichtet werden, wenn der Mailserver nur für eine Domain (nur für “@mysystems.tld”-Adressen) genutzt werden soll.&amp;lt;/p&amp;gt;&amp;lt;p&amp;gt;Folgende IP-Adressen werden beispielhaft in Konfigurationen genannt und müssen ebenfalls durch die IP-Adressen des jeweiligen Servers ersetzt werden:&amp;lt;/p&amp;gt;&lt;br /&gt;
*&amp;lt;code&amp;gt;2001:db8::1&amp;lt;/code&amp;gt; (IPv6-Adresse des Mailservers)&lt;br /&gt;
*&amp;lt;code&amp;gt;203.0.113.1&amp;lt;/code&amp;gt; (IPv4-Adresse des Mailservers)&lt;br /&gt;
&lt;br /&gt;
== Grundvoraussetzungen für den Mailserver ==&lt;br /&gt;
&lt;br /&gt;
*Ein virtueller oder dedizierter Server mit bereits installiertem Debian 10 Buster&amp;lt;br&amp;gt;(“Standard-Systemwerkzeuge” und “SSH” bei der Installation angewählt)&lt;br /&gt;
*Mindestens eine eigene Domain + volle Kontrolle über die DNS-Zone&lt;br /&gt;
&amp;lt;p&amp;gt;Ein kleiner, virtueller Server auf KVM-Basis ist in den meisten Fällen völlig ausreichend. Ich empfehle für kleine, private Setups zwei CPU-Kerne und 1-2 GB RAM. Virtuelle Server kann man z.B. bei&amp;lt;/p&amp;gt;[https://servercow.de/vserver Servercow]&amp;lt;p&amp;gt;oder&amp;lt;/p&amp;gt;[https://hetzner.cloud/?ref=H6gtsnaMZj6N Hetzner]&amp;lt;p&amp;gt;preisgünstig bekommen.&amp;lt;/p&amp;gt;&lt;br /&gt;
== Komponenten eines vollständigen Mailsystems ==&lt;br /&gt;
&amp;lt;figure&amp;gt;&amp;lt;figcaption&amp;gt;Mailserver Schema&amp;lt;/figcaption&amp;gt;&amp;lt;/figure&amp;gt;&amp;lt;p&amp;gt;Welche Softwarekomponenten verwendet werden, wisst ihr bereits. Doch welche Software übernimmt welche Aufgaben?&amp;lt;/p&amp;gt;&lt;br /&gt;
=== Dovecot ===&lt;br /&gt;
&amp;lt;p&amp;gt;Dovecot ist ein weit verbreiteter MDA (Mail Delivery Agent) und IMAP-Server. Er sortiert ankommende E-Mails in die Postfächer des jeweiligen Empfängers ein und stellt eine Schnittstelle zum Abrufen der Mailbox bereit (IMAP). Außerdem wird Dovecot in diesem Setup von Postfix als sog. SASL-Authentifizierungsserver genutzt: Postfix fragt Dovecot, ob ein bestimmter Benutzer berechtigt ist, sich am System anzumelden.&amp;lt;/p&amp;gt;&lt;br /&gt;
=== Postfix ===&lt;br /&gt;
&amp;lt;p&amp;gt;Postfix wird oft zusammen mit Dovecot eingesetzt. Der populäre MTA (Mail Transfer Agent) kümmert sich um alles, was mit dem Transport der E-Mail zu tun hat: Vom E-Mail Client zum eigenen Mailserver, und von dort aus zum jeweiligen Zielserver. Außerdem nimmt Postfix E-Mails von fremden Servern an und leitet sie an den MDA Dovecot weiter. Antispam-Software wird i.d.R. direkt in Postfix integriert, um eintreffende Spammails erst gar nicht in die Mailbox des Nutzers gelangen zu lassen.&amp;lt;/p&amp;gt;&amp;lt;p&amp;gt;''Anmerkung: Postfix ist “der eigentliche Mailserver”. E-Mails können ohne weiteres einzig und allein mit Postfix gesendet und empfangen werden. Alle weiteren Komponenten wie Dovecot und Rspamd machen uns das Leben allerdings einfacher ;-)''&amp;lt;/p&amp;gt;&lt;br /&gt;
=== MariaDB (MySQL-Datenbank) ===&lt;br /&gt;
&amp;lt;p&amp;gt;Dovecot und Postfix werden so konfiguriert, dass sie eine MySQL-Datenbank als Backend (Datenbasis) nutzen. In der Datenbank werden zu nutzende Domains, Benutzer, Aliase und weitere Daten gespeichert. Durch einfaches Hinzufügen oder Entfernen von Datensätzen in oder aus Datenbanktabellen können neue Benutzer oder Aliase angelegt oder gelöscht werden. Der Vorteil eines Datenbank-Backends ist, dass sich der Mailserver damit sehr einfach verwalten lässt: So ließe sich zur Benutzerverwaltung beispielsweise eine Weboberfläche in PHP entwickeln, die die MySQL-Datenbank verändert. Die Serverkonfiguration muss dann nicht manuell geändert werden.&amp;lt;/p&amp;gt;&lt;br /&gt;
=== Rspamd ===&lt;br /&gt;
&amp;lt;p&amp;gt;Rspamd ist ein Filtersystem, das in Postfix integriert wird und eingehende E-Mails überprüft. Spammails werden von Rspamd erkannt und nicht an den Benutzer zugestellt bzw. aussortiert. Außerdem fügt Rspamd bei ausgehenden E-Mails eine DKIM-Signatur hinzu, sodass fremde Mailserver eigene Mails nicht als verdächtig einstufen.&amp;lt;/p&amp;gt;&lt;br /&gt;
=== Nginx ===&lt;br /&gt;
&amp;lt;p&amp;gt;Nginx ist ein weit verbreiteter und schlanker Webserver / Webproxy. In diesem Setup hat er mehrere Aufgaben: Zum einen kann er als Endpunkt für den Ausstellungsprozess von Let’s Encrypt-Zertifikaten dienen, zum anderen als Proxy für die Rspamd-Weboberfläche, oder um die Autokonfigurationsdatei für Mailclients anzubieten.&amp;lt;/p&amp;gt;&lt;br /&gt;
=== Redis ===&lt;br /&gt;
&amp;lt;p&amp;gt;Redis ist ein hochperformanter In-memory Key-Value-Store, also eine sehr einfache, schnelle Datenbank, welche Schlüssel-Wert-Paare effizient im Speicher ablegen kann. Rspamd nutzt Redis, um einige Daten zwischenzuspeichern (wie z.B. zuletzt überprüfte Mailserver).&amp;lt;/p&amp;gt;&lt;br /&gt;
== Vorbereitungen ==&lt;br /&gt;
=== Tipp: Reinen Tisch machen ===&lt;br /&gt;
&amp;lt;p&amp;gt;Wenn ihr den Server vorher schon für etwas anderes (oder sogar ein anderes Mail-Setup) verwendet habt, stellt sicher, dass Reste aus alten Installationen das neue Setup nicht behindern. Speziell vorherige Mailserver-Versuche sollten rückstandslos entfernt werden (inkl. der zugehörigen Konfigurationsdateien). Am besten ist natürlich – falls möglich – eine komplette Neuinstallation des Servers. Ich empfehle, den Mailserver als eigenständiges System zu betreiben und auf demselben Host keine anderen Dienste zu installieren, um die Integrität des Mailsystems sicherzustellen.&amp;lt;/p&amp;gt;&amp;lt;p&amp;gt;Im Folgenden gehe ich von einem frisch installierten Debian 10 Buster aus (zusätzlich nur “Standard-Systemwerkzeuge” und SSH installiert).&amp;lt;/p&amp;gt;&lt;br /&gt;
=== Login als Root ===&lt;br /&gt;
&amp;lt;p&amp;gt;Bei der Installation von Debian wird ein normaler Benutzeraccount, z.B. “thomas” eingerichtet, zu dem ihr euch via Passwort verbinden könnt. Der Root-Account ist standardmäßig nicht direkt zugänglich, sondern nur über den Umweg via “su”. Für diese Anleitung werden permanent Root-Rechte benötigt. Öffnet nach dem Login am Server also am besten eine Root-Kommandozeile via&amp;lt;/p&amp;gt;&amp;lt;pre&amp;gt;&amp;lt;code&amp;gt;su -&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;/pre&amp;gt;&amp;lt;p&amp;gt;Gebt dann das Passwort für euren root-User ein.&amp;lt;/p&amp;gt;&lt;br /&gt;
=== System aktualisieren ===&lt;br /&gt;
&amp;lt;p&amp;gt;Bevor ihr neue Software-Pakete installiert, solltet ihr mittels&amp;lt;/p&amp;gt;&amp;lt;pre&amp;gt;&amp;lt;code&amp;gt;apt update &amp;amp;&amp;amp; apt upgrade&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;/pre&amp;gt;&amp;lt;p&amp;gt;sicherstellen, dass euer System aktuell ist. Bei der Gelegenheit bietet sich auch gleich ein Reboot an, um einen möglicherweise aktualisierten Linux-Kernel zu laden.&amp;lt;/p&amp;gt;&lt;br /&gt;
=== Hostname und Server-FQDN setzen ===&lt;br /&gt;
&amp;lt;p&amp;gt;Euer Server bekommt zwei Namen, über die er identifiziert werden kann:&amp;lt;/p&amp;gt;&lt;br /&gt;
*Lokalen Hostnamen: Für die Identifizierung des Servers innerhalb der eigenen Infrastruktur, z.B. “mail”&lt;br /&gt;
*FQDN (Fully Qualified Domain Name): Für die weltweite Identifizierung im Internet, z.B. “mail.mysystems.tld”&lt;br /&gt;
&amp;lt;p&amp;gt;Der FQDN muss nicht zwingend etwas mit den Domains zu tun haben, für die später E-Mails gesendet und empfangen werden sollen. Wichtig ist nur, dass euer künftiger Mailserver einen solchen Namen hat, der auch über das DNS zur Server-IP-Adresse aufgelöst werden kann (dazu gleich mehr im Abschnitt “Einrichtung des DNS”). Den lokalen Hostnamen setzt ihr wie folgt:&amp;lt;/p&amp;gt;&amp;lt;pre&amp;gt;&amp;lt;code&amp;gt;hostnamectl set-hostname --static mail&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;/pre&amp;gt;&amp;lt;p&amp;gt;In der Hosts-Datei &amp;lt;code&amp;gt;/etc/hosts&amp;lt;/code&amp;gt; sollten FQDN und lokaler Hostname hinterlegt sein. Die Datei kann beispielsweise so aussehen:&amp;lt;/p&amp;gt;&amp;lt;pre&amp;gt;&amp;lt;code&amp;gt;127.0.0.1	localhost&lt;br /&gt;
127.0.1.1	mail.mysystems.tld	mail&lt;br /&gt;
&lt;br /&gt;
::1         localhost ip6-localhost ip6-loopback&lt;br /&gt;
ff02::1     ip6-allnodes&lt;br /&gt;
ff02::2     ip6-allrouters&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;/pre&amp;gt;&amp;lt;p&amp;gt;Die Ausgaben der Kommandos &amp;lt;code&amp;gt;hostname&amp;lt;/code&amp;gt; und &amp;lt;code&amp;gt;hostname --fqdn&amp;lt;/code&amp;gt; sollten nach den Änderungen wie folgt aussehen:&amp;lt;/p&amp;gt;&amp;lt;pre&amp;gt;&amp;lt;code&amp;gt;root@mail:~# hostname&lt;br /&gt;
mail&lt;br /&gt;
root@mail:~# hostname --fqdn&lt;br /&gt;
mail.mysystems.tld&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;/pre&amp;gt;&amp;lt;p&amp;gt;Der FQDN (in diesem Beispiel “mail.mysystems.tld”) wird außerdem nach &amp;lt;code&amp;gt;/etc/mailname&amp;lt;/code&amp;gt; geschrieben:&amp;lt;/p&amp;gt;&amp;lt;pre&amp;gt;&amp;lt;code&amp;gt;echo $(hostname -f) &amp;amp;gt; /etc/mailname&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;/pre&amp;gt;&amp;lt;p&amp;gt;''(Der Hostname im Shell-Prompt z.B. &amp;lt;code&amp;gt;root@meinhost:&amp;lt;/code&amp;gt; passt sich erst nach einem erneuten Login an.)''&amp;lt;/p&amp;gt;&lt;br /&gt;
=== Unbound DNS Resolver installieren ===&lt;br /&gt;
&amp;lt;p&amp;gt;Das Mailsystem benötigt einen funktionierenden DNS-Server (Resolver), sodass die Herkunft von E-Mails überprüft werden kann. Auch der Rspamd-Spamfilter verlässt sich bei der Bewertung von Spammails auf DNS-Dienste. Eine schnelle Namesauflösung bringt also Performancevorteile für das ganze Mailsystem. Für den Zugriff auf Spamhaus-Blocklists kann es sogar notwendig sein, seinen eigenen DNS-Resolver zu nutzen, weil z.B. Zugriffe über das Google DNS blockiert werden. Deshalb (und um die Sicherheit im Bezug auf Abhängigkeiten zu fremden Systemen zu verbessern) empfehle ich die Nutzung eines eigenen, lokalen DNS-Resolvers.&amp;lt;/p&amp;gt;&amp;lt;p&amp;gt;Unbound installieren:&amp;lt;/p&amp;gt;&amp;lt;pre&amp;gt;&amp;lt;code&amp;gt;apt install unbound&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;/pre&amp;gt;&amp;lt;div class=&amp;quot;tip&amp;quot;&amp;gt;Für die nächsten Kommandos muss müssen die Pakete &amp;lt;code&amp;gt;dnsutils&amp;lt;/code&amp;gt; und &amp;lt;code&amp;gt;resolvconf&amp;lt;/code&amp;gt; installiert sein. Wenn bei der Installation von Debian die “Standard-Systemwerkzeuge” ausgewählt wurden, sind die &amp;lt;code&amp;gt;dnsutils&amp;lt;/code&amp;gt; schon installiert.&amp;lt;/div&amp;gt;&amp;lt;p&amp;gt;Ein &amp;lt;code&amp;gt;dig @::1 denic.de +short +dnssec&amp;lt;/code&amp;gt; sollte eine ähnliche Ausgabe wie folgt erzeugen:&amp;lt;/p&amp;gt;&amp;lt;pre&amp;gt;&amp;lt;code&amp;gt;# dig @::1 denic.de +short +dnssec&lt;br /&gt;
A 8 2 3600 20170814090000 20170731090000 26155 denic.de. Jo90qnkLkZ6gI4qNHj19BMguFuGof9hCPhdeSh/fSePSQ/WXlWMmfjW1 sNDJ/bcITRMyz8DQdDzmWPDIeSJ/qPyfoZ+BjUZxtaXcs0BAl4KX8q7h R05TGmAbgPhrYBoUKJkU/q8T+jWKHAJRUeWbCd8QOJsJbneGcUKxRAPe i6Rq51/OL/id6zUCtalhclah2TfLLaqku9PmKwjbGdZm11BXSr8b56LB WX/rdLIrKWNpE+jHGAUMmDsZL84Kx3Oo&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;/pre&amp;gt;&amp;lt;p&amp;gt;Wenn der &amp;lt;code&amp;gt;dig&amp;lt;/code&amp;gt;-Befehl funktioniert hat, kann der lokale Resolver als primärer Resolver gesetzt werden:&amp;lt;/p&amp;gt;&amp;lt;pre&amp;gt;&amp;lt;code&amp;gt;apt install resolvconf&lt;br /&gt;
echo &amp;quot;nameserver ::1&amp;quot; &amp;amp;gt;&amp;amp;gt; /etc/resolvconf/resolv.conf.d/head&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;/pre&amp;gt;&amp;lt;p&amp;gt;ein &amp;lt;code&amp;gt;nslookup denic.de | grep Server&amp;lt;/code&amp;gt; sollte nun&amp;lt;/p&amp;gt;&amp;lt;pre&amp;gt;&amp;lt;code&amp;gt;Server:		::1&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;/pre&amp;gt;&amp;lt;p&amp;gt;zurückliefern. Damit ist der lokale DNS-Resolver als Haupt-Resolver einsatzbereit.&amp;lt;/p&amp;gt;&lt;br /&gt;
== Einrichtung des DNS ==&lt;br /&gt;
&amp;lt;p&amp;gt;Zu Beginn dieser Anleitung wurde für den Mailserver der FQDN “mail.mysystems.tld” festgelegt. Für diesen Domain-Namen werden nun A-Records im DNS-Zonefile der Domain “mysystems.tld” erstellt. Loggt euch bei eurem Domain-Provider ein und legt die folgenden Einträge an – der erste für die IPv4-IP-Adresse des Mailservers, die zweite für die IPv6-Adresse. (Beispiel!):&amp;lt;/p&amp;gt;&amp;lt;p&amp;gt;Achtet im Folgenden vor allem auf den abschließenden Punkt in den Domainnamen!&amp;lt;/p&amp;gt;&amp;lt;pre&amp;gt;&amp;lt;code&amp;gt;mail.mysystems.tld. 86400 IN A    203.0.113.1&lt;br /&gt;
mail.mysystems.tld. 86400 IN AAAA 2001:db8::1&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;/pre&amp;gt;&amp;lt;p&amp;gt;“mail.mysystems.tld” ist damit im DNS bekannt. Wenn keine IPv6-Adresse genutzt wird, kann der zweite Record entfallen. Bleiben noch “imap.mysystems.tld” und “smtp.mysystems.tld”, die als Alias-Domains für “mail.mysystems.tld” angelegt werden. Sie sind nicht unbedingt notwendig, werden von vielen Mailclient aber gesucht und sind so üblich:&amp;lt;/p&amp;gt;&amp;lt;pre&amp;gt;&amp;lt;code&amp;gt;imap.mysystems.tld. 86400 IN CNAME mail.mysystems.tld.&lt;br /&gt;
smtp.mysystems.tld. 86400 IN CNAME mail.mysystems.tld.&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;/pre&amp;gt;&amp;lt;p&amp;gt;Mailclients können sich damit schon über imap.mysystems.tld und smtp.mysystems.tld zum Mailserver verbinden. Andere Mailserver suchen bei der E-Mail-Übermittlung allerdings nicht nach A- oder CNAME-Records, sondern nach MX-Records. Ein MX-Record zeigt, welcher Mailserver für die E-Mails zu einer Domain zuständig ist. In meinem Beispiel soll sich unser Mailserver neben den E-Mails für mysystems.tld auch um die Mails für domain2.tld und domain3.tld kümmern.&amp;lt;/p&amp;gt;&amp;lt;p&amp;gt;Im Zonefile der Domain “mysystems.tld” wird dazu dieser Record angelegt:&amp;lt;/p&amp;gt;&amp;lt;pre&amp;gt;&amp;lt;code&amp;gt;mysystems.tld. 86400 IN MX 0 mail.mysystems.tld.&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;/pre&amp;gt;&amp;lt;p&amp;gt;In die Zonefiles der anderen Domains werden entsprechend die Records&amp;lt;/p&amp;gt;&amp;lt;pre&amp;gt;&amp;lt;code&amp;gt;domain2.tld. 86400 IN MX 0 mail.mysystems.tld.&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;/pre&amp;gt;&amp;lt;p&amp;gt;und&amp;lt;/p&amp;gt;&amp;lt;pre&amp;gt;&amp;lt;code&amp;gt;domain3.tld. 86400 IN MX 0 mail.mysystems.tld.&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;/pre&amp;gt;&amp;lt;p&amp;gt;angelegt.&amp;lt;/p&amp;gt;&lt;br /&gt;
=== Reverse DNS ===&lt;br /&gt;
&amp;lt;p&amp;gt;Des weiteren muss ein sog. Reverse-DNS-Record / PTR für den FQDN des Mailservers angelegt werden. Dieser entspricht der Umkehrung eines normalen DNS-Records und ordnet einer IP-Adresse einen Hostnamen zu. Diesen Record kann nur der Inhaber des Netzes anlegen, aus dem eure IP-Adresse stammt. Möglicherweise könnt ihr so einen Reverse-DNS-Record in der Verwaltungsoberfläche eures Serveranbieters setzen, oder ihr bittet den Support, das zu tun. Der Domain-Name, der mit der IP-Adresse verknüpft werden muss, ist der FQDN eures Mailservers. In meinem Beispiel mail.mysystems.tld. Denkt daran, für alle vom Mailserver genutzten, öffentlichen IP-Adressen einen solchen Record zu erstellen. In dieser Anleitung wird eine IPv4- und eine IPv6-Adresse verwendet.&amp;lt;/p&amp;gt;&lt;br /&gt;
=== SPF-Records ===&lt;br /&gt;
&amp;lt;p&amp;gt;Im Kampf gegen Spam und Phishing wurde das sog. Sender Policy Framework entwickelt (Siehe auch Beitrag: “&amp;lt;/p&amp;gt;[https://thomas-leister.de/voraussetzungen-email-versand-gro%C3%9Fe-provider/ Voraussetzungen für den Versand zu großen E-Mail Providern]&amp;lt;p&amp;gt;&amp;quot;). Obwohl es sich nur als eingeschränkt brauchbar erwiesen hat, erwarten die meisten Mailprovider gültige SPF-Records für andere Mailserver und prüfen diese. SPF-Einträge werden im Zonefile aller Domains erstellt, für die ein Mailserver E-Mails verschickt, und geben an, welche Server für eine Domain sendeberechtigt sind. Für unsere Domain mysystems.tld wird der folgende Record im Zonefile von mysystems.tld angelegt:&amp;lt;/p&amp;gt;&amp;lt;pre&amp;gt;&amp;lt;code&amp;gt;mysystems.tld. 3600 IN TXT v=spf1 a:mail.mysystems.tld mx ?all&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;/pre&amp;gt;&amp;lt;p&amp;gt;Hiermit erhält nur der im A-Record “mail.msystems.tld” genannte Server für mysystems.tld eine Sendeberechtigung. Die Neutral-Einstellung “?all” sorgt dafür, dass E-Mails von anderen Servern trotzdem angenommen werden sollen. Damit gehen wir Problemen beim Mail-Forwarding aus dem Weg. Wir erstellen den SPF-Record also eigentlich nur, damit andere Mailserver unseren Server wegen des existierenden Records positiv bewerten – nicht, weil er seinen Nutzen entfalten soll.&amp;lt;/p&amp;gt;&amp;lt;p&amp;gt;In den Zonefiles der beiden Domains “domain2.tld” und “domain3.tld” wird (angepasst auf die Domain) jeweils dieser Record angelegt:&amp;lt;/p&amp;gt;&amp;lt;pre&amp;gt;&amp;lt;code&amp;gt;domain2.tld. 3600 IN TXT v=spf1 include:mysystems.tld ?all&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;/pre&amp;gt;&amp;lt;p&amp;gt;Über das “include” wird der erste Record der Domain mysystems.tld eingebunden.&amp;lt;/p&amp;gt;&lt;br /&gt;
=== DMARC Records ===&lt;br /&gt;
&amp;lt;p&amp;gt;DMARC-Einträge bestimmen, was ein fremder Mailserver tun soll, wenn eine von ihm empfangene Mail nach SPF- und DKIM-Checks offenbar nicht vom korrekten Mailserver stammt (wenn der Absender also gefälscht wurde). Es ist vernünftig, andere Mailserver anzuweisen, solche E-Mails nicht zu akzeptieren:&amp;lt;/p&amp;gt;&amp;lt;pre&amp;gt;&amp;lt;code&amp;gt;_dmarc.mysystems.tld.   3600    IN TXT    v=DMARC1; p=reject;&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;/pre&amp;gt;&amp;lt;p&amp;gt;Der Record wird entsprechend auch für die anderen Domains gesetzt:&amp;lt;/p&amp;gt;&amp;lt;pre&amp;gt;&amp;lt;code&amp;gt;_dmarc.domain2.tld.   3600    IN TXT    v=DMARC1; p=reject;&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;/pre&amp;gt;&amp;lt;p&amp;gt;Einen DMARC-Record mit einer abweichenden Policy könnt ihr euch unter&amp;lt;/p&amp;gt;[https://elasticemail.com/dmarc/ https://elasticemail.com/dmarc/]&amp;lt;p&amp;gt;selbst generieren lassen.&amp;lt;/p&amp;gt;&lt;br /&gt;
== Erstkonfiguration Nginx Webserver ==&lt;br /&gt;
&amp;lt;p&amp;gt;Wie bereits angemerkt, übernimmt Nginx in diesem Setup verschiedene Aufgaben. Für’s erste dient er aber nur als HTTP-Endpunkt, um Let’s Encrypt Zertifikate zu beantragen. Das ist zwar prinzipiell auch ohne Nginx im standalone-Modus möglich, macht uns aber das Leben einfacher, wenn wir ihn sowieso in Betrieb haben ''(=&amp;amp;gt; belegte Ports durch Nginx, ACME client …)''.&amp;lt;/p&amp;gt;&amp;lt;p&amp;gt;Dazu wird Nginx installiert …&amp;lt;/p&amp;gt;&amp;lt;pre&amp;gt;&amp;lt;code&amp;gt;apt install nginx&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;/pre&amp;gt;&amp;lt;p&amp;gt;… und unter &amp;lt;code&amp;gt;/etc/nginx/sites-available/mail.mysystems.tld&amp;lt;/code&amp;gt; eine neue Konfiguration mit diesem Inhalt angelegt:&amp;lt;/p&amp;gt;&amp;lt;pre&amp;gt;&amp;lt;code&amp;gt;server {&lt;br /&gt;
        listen 80;&lt;br /&gt;
        listen [::]:80;&lt;br /&gt;
#       listen 443 ssl http2;&lt;br /&gt;
#       listen [::]:443 ssl http2;&lt;br /&gt;
&lt;br /&gt;
        server_name mail.mysystems.tld imap.mysystems.tld smtp.mysystems.tld;&lt;br /&gt;
&lt;br /&gt;
#       ssl_certificate /etc/acme.sh/mail.mysystems.tld/fullchain.pem;&lt;br /&gt;
#       ssl_certificate_key /etc/acme.sh/mail.mysystems.tld/privkey.pem;&lt;br /&gt;
&lt;br /&gt;
#       add_header Strict-Transport-Security max-age=15768000;&lt;br /&gt;
&lt;br /&gt;
#       if ($ssl_protocol = &amp;quot;&amp;quot;) {&lt;br /&gt;
#           return 301 https://$server_name$request_uri;&lt;br /&gt;
#       }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;/pre&amp;gt;&amp;lt;p&amp;gt;Einige Zeilen sind zu diesem Zeitpunkt bewusst auskommentiert und werden später wieder aktiviert, sobald TLS-Zertifikate verfügbar sind.&amp;lt;/p&amp;gt;&amp;lt;p&amp;gt;Der neue vHost kann nun aktiviert werden:&amp;lt;/p&amp;gt;&amp;lt;pre&amp;gt;&amp;lt;code&amp;gt;ln -s /etc/nginx/sites-available/mail.mysystems.tld /etc/nginx/sites-enabled/mail.mysystems.tld&lt;br /&gt;
systemctl reload nginx&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;/pre&amp;gt;&lt;br /&gt;
== Beantragung der TLS-Zertifikate (via Let’s Encrypt) ==&lt;br /&gt;
&amp;lt;p&amp;gt;Gültige TLS-Zertifikate von anerkannten Zertifizierungsstellen (CAs) sind heute für jeden Mailserver ein “muss”. Immer mehr Mailsysteme verweigern zurecht den Empfang über ungesicherte Verbindungen. Was früher (vor allem für den privaten Einsatz) noch ein bedeutender Kostenfaktor war, bekommt man heute Dank Let’s Encrypt kostenlos und sehr unkompliziert. Im folgenden beziehe ich mich daher auf die Generierung von Let’s Encrypt-Zertifikaten. Selbstverständlich können stattdessen auch Zertifikate anderer CAs genutzt werden.&amp;lt;/p&amp;gt;&amp;lt;p&amp;gt;Für Postfix und Dovecot benötigen wir Zertifikate zu folgenden Domains:&amp;lt;/p&amp;gt;&lt;br /&gt;
*mail.mysystems.tld&lt;br /&gt;
*imap.mysystems.tld&lt;br /&gt;
*smtp.mysystems.tld&lt;br /&gt;
&amp;lt;p&amp;gt;Um die Zertifikate von der Let’s Encrypt Zertifizierungsstelle abholen, nutze ich das schlanke&amp;lt;/p&amp;gt;[https://github.com/acmesh-official/acme.sh acme.sh Script]&amp;lt;p&amp;gt;. Dieses verfügt über einen “Nginx-Mode”, in dem das Script den Nginx Webserver automatisch so konfiguriert, dass die Domains von LE verifiziert werden können.&amp;lt;/p&amp;gt;&amp;lt;p&amp;gt;acme.sh installieren:&amp;lt;/p&amp;gt;&amp;lt;pre&amp;gt;&amp;lt;code&amp;gt;curl https://get.acme.sh | sh&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;/pre&amp;gt;&amp;lt;div class=&amp;quot;tip&amp;quot;&amp;gt;Der Hinweis, welcher besagt, dass socat installiert werden solle, kann ignoriert werden. Socat wird in unserem Fall nicht benötigt.&amp;lt;/div&amp;gt;&amp;lt;p&amp;gt;Nach der Installation muss das Shell-Profil neu geladen werden, damit das “acme.sh” Kommando verfügbar gemacht wird:&amp;lt;/p&amp;gt;&amp;lt;pre&amp;gt;&amp;lt;code&amp;gt;source ~/.profile&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;/pre&amp;gt;&amp;lt;p&amp;gt;Zertifikate beantragen und herunterladen:&amp;lt;/p&amp;gt;&amp;lt;pre&amp;gt;&amp;lt;code&amp;gt;acme.sh --issue --server letsencrypt --nginx \&lt;br /&gt;
    -d mail.mysystems.tld \&lt;br /&gt;
    -d imap.mysystems.tld \&lt;br /&gt;
    -d smtp.mysystems.tld&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;/pre&amp;gt;&amp;lt;p&amp;gt;Zertifikate installieren:&amp;lt;/p&amp;gt;&amp;lt;pre&amp;gt;&amp;lt;code&amp;gt;mkdir -p /etc/acme.sh/mail.mysystems.tld&lt;br /&gt;
acme.sh --install-cert -d mail.mysystems.tld \&lt;br /&gt;
    --key-file       /etc/acme.sh/mail.mysystems.tld/privkey.pem  \&lt;br /&gt;
    --fullchain-file /etc/acme.sh/mail.mysystems.tld/fullchain.pem \&lt;br /&gt;
    --reloadcmd     &amp;quot;systemctl reload nginx; systemctl restart dovecot; systemctl restart postfix;&amp;quot;&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;/pre&amp;gt;&amp;lt;p&amp;gt;Infolge unseres Reload-Commands wird Acme.sh versuchen, Dovecot und Postfix neu zu laden. Da beide Softwarepakete noch nicht installiert sind, werden euch Fehler angezeigt. Ihr könnt diese zum gegenwärtigen Zeitpunkt aber ignorieren.&amp;lt;/p&amp;gt;&amp;lt;p&amp;gt;Die vorher im Nginx auskommentierten Zeilen in &amp;lt;code&amp;gt;/etc/nginx/sites-available/mail.mysystems.tld&amp;lt;/code&amp;gt; können durch entfernen der Hashzeichen nun aktiviert und Nginx mittels&amp;lt;/p&amp;gt;&amp;lt;pre&amp;gt;&amp;lt;code&amp;gt;nginx -t&lt;br /&gt;
systemctl reload nginx&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;/pre&amp;gt;&amp;lt;p&amp;gt;getestet und neu gestartet werden.&amp;lt;/p&amp;gt;&amp;lt;p&amp;gt;Für die Autokonfiguration der Mailclients wird später noch ein Zertifikat für eine weitere Domain beantragt - doch das kann erst einmal warten.&amp;lt;/p&amp;gt;&amp;lt;p&amp;gt;Damit die automatische Zertifikatserneuerung funktioniert, wird noch der Cronjob für acme.sh aktiviert:&amp;lt;/p&amp;gt;&amp;lt;pre&amp;gt;&amp;lt;code&amp;gt; acme.sh --install-cronjob&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;/pre&amp;gt;&lt;br /&gt;
== MySQL Datenbank einrichten ==&lt;br /&gt;
&amp;lt;p&amp;gt;Informationen über zu verwaltende Domains, Benutzer, Weiterleitungen und sonstige Einstellungen soll der Mailserver aus einer MySQL-Datenbank ziehen. Das hat den Vorteil, dass der Server im laufenden Betrieb flexibel angepasst werden kann, ohne die Konfigurationsdateien ändern zu müssen. Die Datenbank ermöglicht uns außerdem ein virtualisiertes Mailserver-Setup: Die Benutzer auf den Mailservern müssen nicht mehr als reale Linux-Benutzer im System registriert sein, sondern nur noch in der Datenbank eingetragen werden.&amp;lt;/p&amp;gt;&amp;lt;p&amp;gt;Als DBMS wird die neue Debian-Standard-MySQL-Datenbank “MariaDB” installiert:&amp;lt;/p&amp;gt;&amp;lt;pre&amp;gt;&amp;lt;code&amp;gt;apt install mariadb-server&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;/pre&amp;gt;&amp;lt;p&amp;gt;Nach der Installation sollte MariaDB bereits gestartet sein. Den Status könnt ihr mittels &amp;lt;code&amp;gt;systemctl status mysql&amp;lt;/code&amp;gt;(nicht “mariadb!&amp;quot;) überprüfen. Falls das nicht der Fall ist, startet den Datenbankserver: &amp;lt;code&amp;gt;systemctl start mysql&amp;lt;/code&amp;gt;.&amp;lt;/p&amp;gt;&amp;lt;p&amp;gt;Standardmäßig kann sich nur der root-Systemuser am Datenbankserver anmelden. Authentifiziert wird er dabei automatisch via PAM, sodass keine zusätzliche Passworteingabe notwendig ist. Die einfache Eingabe von&amp;lt;/p&amp;gt;&amp;lt;pre&amp;gt;&amp;lt;code&amp;gt;mysql&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;/pre&amp;gt;&amp;lt;p&amp;gt;bringt euch in eine MySQL Root Shell. Über diese werden nun ein paar SQL-Befehle ausgeführt.&amp;lt;/p&amp;gt;&amp;lt;p&amp;gt;Ein SQL-Kommando endet immer mit einem Semikolon &amp;lt;code&amp;gt;;&amp;lt;/code&amp;gt;. Mehrzeilige Befehle könnt ihr ohne weiteres einfach mit ENTER umbrechen, so wie sie im Folgenden dargestellt werden. Achtet auf den Unterschied zwischen “Tick” (&amp;lt;code&amp;gt;'&amp;lt;/code&amp;gt;) und “Backtick” (&amp;lt;code&amp;gt; \&amp;lt;/code&amp;gt; `) – der Backtick wird mit Shift + 2x Accent-Taste erzeugt. Kopiert die SQL-Statements am besten direkt in eure Zwischenanlage, statt sie mühsam abzutippen.&amp;lt;/p&amp;gt;&amp;lt;p&amp;gt;Im ersten Schritt wird eine neue Datenbank “vmail” angelegt.&amp;lt;/p&amp;gt;&amp;lt;pre&amp;gt;&amp;lt;code&amp;gt;create database vmail&lt;br /&gt;
    CHARACTER SET 'utf8';&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;/pre&amp;gt;&amp;lt;p&amp;gt;Ein neuer DB-User &amp;lt;code&amp;gt;vmail&amp;lt;/code&amp;gt; mit dem Passwort &amp;lt;code&amp;gt;vmaildbpass&amp;lt;/code&amp;gt; bekommt Zugriff auf diese neue Datenbank ''(Wählt ein eigenes Passwort statt “vmaildbpass”!)'':&amp;lt;/p&amp;gt;&amp;lt;div class=&amp;quot;warning&amp;quot;&amp;gt;Nutzt für &amp;lt;code&amp;gt;vmaildbpass&amp;lt;/code&amp;gt; nur die Zeichen 0-9 a-z und A-z. Einigen Berichten nach können Sonderzeichen zu Problemen führen.&amp;lt;/div&amp;gt;&amp;lt;pre&amp;gt;&amp;lt;code&amp;gt;grant select on vmail.* to 'vmail'@'localhost' identified by 'vmaildbpass';&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;/pre&amp;gt;&amp;lt;p&amp;gt;Alle weiteren Kommandos zu Erstellung der Datenbank-Tabellen sollen sich auf die eben erzeugte Datenbank beziehen:&amp;lt;/p&amp;gt;&amp;lt;pre&amp;gt;&amp;lt;code&amp;gt;use vmail;&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;/pre&amp;gt;&amp;lt;p&amp;gt;Das Mail-Setup soll 4 verschiedene Tabellen nutzen. Kopiert die SQL-Statements einzeln und nacheinander in die MySQL-Kommandozeile und bestätigt jedes mal mit [Enter]. Anpassungen sind nicht notwendig.&amp;lt;/p&amp;gt;&lt;br /&gt;
=== Domain-Tabelle ===&lt;br /&gt;
&amp;lt;p&amp;gt;Die Domain-Tabelle enthält alle Domains, die mit dem Mailserver genutzt werden sollen.&amp;lt;/p&amp;gt;&amp;lt;pre&amp;gt;&amp;lt;code&amp;gt;CREATE TABLE `domains` (&lt;br /&gt;
    `id` int unsigned NOT NULL AUTO_INCREMENT,&lt;br /&gt;
    `domain` varchar(255) NOT NULL,&lt;br /&gt;
    PRIMARY KEY (`id`),&lt;br /&gt;
    UNIQUE KEY (`domain`)&lt;br /&gt;
);&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;/pre&amp;gt;&lt;br /&gt;
=== Account-Tabelle ===&lt;br /&gt;
&amp;lt;pre&amp;gt;&amp;lt;code&amp;gt;CREATE TABLE `accounts` (&lt;br /&gt;
    `id` int unsigned NOT NULL AUTO_INCREMENT,&lt;br /&gt;
    `username` varchar(64) NOT NULL,&lt;br /&gt;
    `domain` varchar(255) NOT NULL,&lt;br /&gt;
    `password` varchar(255) NOT NULL,&lt;br /&gt;
    `quota` int unsigned DEFAULT '0',&lt;br /&gt;
    `enabled` boolean DEFAULT '0',&lt;br /&gt;
    `sendonly` boolean DEFAULT '0',&lt;br /&gt;
    PRIMARY KEY (id),&lt;br /&gt;
    UNIQUE KEY (`username`, `domain`),&lt;br /&gt;
    FOREIGN KEY (`domain`) REFERENCES `domains` (`domain`)&lt;br /&gt;
);&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;/pre&amp;gt;&amp;lt;p&amp;gt;Die Account-Tabelle enthält alle Mailserver-Accounts. Das Feld “quota” enthält die Volumenbegrenzung für die Mailbox in MB (Megabyte). Im Feld “enabled” wird über einen bool’schen Wert festgelegt, ob ein Account aktiv ist, oder nicht. So können einzelne User temporär deaktiviert werden, ohne gelöscht werden zu müssen. “sendonly” wird auf “true” gesetzt, wenn der Account nur zum Senden von E-Mails genutzt werden soll – nicht aber zum Empfang. Das kann beispielsweise für Foren- oder Blogsoftware sinnvoll sein, die mit ihrem Account nur E-Mails verschicken soll.&amp;lt;/p&amp;gt;&lt;br /&gt;
=== Alias-Tabelle ===&lt;br /&gt;
&amp;lt;pre&amp;gt;&amp;lt;code&amp;gt;CREATE TABLE `aliases` (&lt;br /&gt;
    `id` int unsigned NOT NULL AUTO_INCREMENT,&lt;br /&gt;
    `source_username` varchar(64),&lt;br /&gt;
    `source_domain` varchar(255) NOT NULL,&lt;br /&gt;
    `destination_username` varchar(64) NOT NULL,&lt;br /&gt;
    `destination_domain` varchar(255) NOT NULL,&lt;br /&gt;
    `enabled` boolean DEFAULT '0',&lt;br /&gt;
    PRIMARY KEY (`id`),&lt;br /&gt;
    UNIQUE KEY (`source_username`, `source_domain`, `destination_username`, `destination_domain`),&lt;br /&gt;
    FOREIGN KEY (`source_domain`) REFERENCES `domains` (`domain`)&lt;br /&gt;
);&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;/pre&amp;gt;&amp;lt;p&amp;gt;Die Alias-Tabelle enthält alle Weiterleitungen / Aliase und ist eigentlich selbsterklärend. Zur temporären Deaktivierung von Weiterleitungsadressen gibt es wieder ein “enabled”-Feld.&amp;lt;/p&amp;gt;&lt;br /&gt;
=== TLS Policy-Tabelle ===&lt;br /&gt;
&amp;lt;pre&amp;gt;&amp;lt;code&amp;gt;CREATE TABLE `tlspolicies` (&lt;br /&gt;
    `id` int unsigned NOT NULL AUTO_INCREMENT,&lt;br /&gt;
    `domain` varchar(255) NOT NULL,&lt;br /&gt;
    `policy` enum('none', 'may', 'encrypt', 'dane', 'dane-only', 'fingerprint', 'verify', 'secure') NOT NULL,&lt;br /&gt;
    `params` varchar(255),&lt;br /&gt;
    PRIMARY KEY (`id`),&lt;br /&gt;
    UNIQUE KEY (`domain`)&lt;br /&gt;
);&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;/pre&amp;gt;&amp;lt;p&amp;gt;Mithilfe der TLS Policy Tabelle kann festgelegt werden, für welche Empfängerdomains bestimmte Sicherheitsbeschränkungen beim Mailtransport gelten sollen. Für einzelne Domains, z.B. “gmx.de” kann beispielsweise angegeben werden, dass diese E-Mails nur noch verschlüsselt übertragen werden dürfen. Mehr dazu später.&amp;lt;/p&amp;gt;&amp;lt;p&amp;gt;Die Datenbank wird mit Datensätzen befüllt, sobald die Server fertig konfiguriert sind. Bis dahin könnt ihr die MySQL-Kommandozeile mit &amp;lt;code&amp;gt;quit;&amp;lt;/code&amp;gt; verlassen.&amp;lt;/p&amp;gt;&lt;br /&gt;
== vmail-Benutzer und -Verzeichnis einrichten ==&lt;br /&gt;
&amp;lt;p&amp;gt;Alle Mailboxen werden direkt im Dateisystem des Debian Servers abgelegt. Für die Zugriffe auf die Mailbox-Verzeichnisse wird ein eigener Benutzer “vmail” (“Virtual Mail”) erstellt, unter dem die Zugriffe von Dovecot und anderen Komponenten des Mailservers geschehen sollen. Einerseits wird so verhindert, dass Mailserver-Komponenten auf sensible Systemverzeichnisse Zugriff bekommen, andererseits können wir so die Mailboxen vor dem Zugriff von außen schützen. Nur vmail (und root) dürfen auf die Mailboxen zugreifen.&amp;lt;/p&amp;gt;&amp;lt;p&amp;gt;Das Verzeichnis &amp;lt;code&amp;gt;/var/vmail/&amp;lt;/code&amp;gt; soll alle Mailserver-relevanten Dateien (also Mailboxen und Filterscripts) enthalten und wird für den vmail-User als Home Directory festgelegt.&amp;lt;/p&amp;gt;&amp;lt;p&amp;gt;vmail-Benutzer erstellen:&amp;lt;/p&amp;gt;&amp;lt;pre&amp;gt;&amp;lt;code&amp;gt;useradd --create-home --home-dir /var/vmail --user-group --shell /usr/sbin/nologin vmail&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;/pre&amp;gt;&amp;lt;p&amp;gt;vmail Unterverzeichnisse erstellen:&amp;lt;/p&amp;gt;&amp;lt;pre&amp;gt;&amp;lt;code&amp;gt;mkdir /var/vmail/mailboxes&lt;br /&gt;
mkdir -p /var/vmail/sieve/global&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;/pre&amp;gt;&amp;lt;p&amp;gt;Verzeichnis &amp;lt;code&amp;gt;/var/vmail&amp;lt;/code&amp;gt; rekursiv an vmail-User übereignen und Verzeichnisrechte passend setzen:&amp;lt;/p&amp;gt;&amp;lt;pre&amp;gt;&amp;lt;code&amp;gt;chown -R vmail /var/vmail&lt;br /&gt;
chgrp -R vmail /var/vmail&lt;br /&gt;
chmod -R 770 /var/vmail&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;/pre&amp;gt;&lt;br /&gt;
== Dovecot installieren und konfigurieren ==&lt;br /&gt;
&amp;lt;p&amp;gt;Nachdem die Datenbank und der vmail-User angelegt wurden, widmen wir uns nun dem Dovecot-Server. Wie bereits erwähnt, verwaltet dieser Server die Mailboxen und bekommt daher (in der Gestalt des vmail-Users) exklusiv Zugriff auf &amp;lt;code&amp;gt;/var/vmail/&amp;lt;/code&amp;gt;. Zuerst müssen jedoch alle Serverkomponenten installiert werden:&amp;lt;/p&amp;gt;&amp;lt;pre&amp;gt;&amp;lt;code&amp;gt;apt install dovecot-core dovecot-imapd dovecot-lmtpd dovecot-mysql dovecot-sieve dovecot-managesieved&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;/pre&amp;gt;&lt;br /&gt;
*&amp;lt;code&amp;gt;dovecot-core&amp;lt;/code&amp;gt;: Dovecot-Kern&lt;br /&gt;
*&amp;lt;code&amp;gt;dovecot-imapd&amp;lt;/code&amp;gt;: Fügt IMAP-Funktionalität hinzu&lt;br /&gt;
*&amp;lt;code&amp;gt;dovecot-lmtp&amp;lt;/code&amp;gt;: Fügt LMTP (Local Mail Transfer Protocol)-Funktionalität hinzu; LMTP wird als MTP-Protokoll zwischen Postfix und Dovecot genutzt&lt;br /&gt;
*&amp;lt;code&amp;gt;dovecot-mysql&amp;lt;/code&amp;gt;: Lässt Dovecot mit der MySQL-Datenbank zusammenarbeiten&lt;br /&gt;
*&amp;lt;code&amp;gt;dovecot-sieve&amp;lt;/code&amp;gt;: Fügt Filterfunktionalität hinzu&lt;br /&gt;
*&amp;lt;code&amp;gt;dovecot-managesieved&amp;lt;/code&amp;gt;: Stellt eine Schnittstelle zur Einrichtung der Filter via Mailclient bereit&lt;br /&gt;
&amp;lt;p&amp;gt;Nach der Installation wird Dovecot automatisch gestartet. Beendet Dovecot, solange wir keine fertige Konfiguration haben:&amp;lt;/p&amp;gt;&amp;lt;pre&amp;gt;&amp;lt;code&amp;gt;systemctl stop dovecot&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;/pre&amp;gt;&amp;lt;p&amp;gt;Nun geht es an die Konfiguration. Die Dovecot-Konfigurationsdateien liegen im Verzeichnis &amp;lt;code&amp;gt;/etc/dovecot/&amp;lt;/code&amp;gt;. Dort könnt ihr schon einige Konfigurationen sehen, die bei der Installation angelegt wurden. Wir werden die Konfiguration von Grund auf neu aufsetzen - deshalb wird zuerst einmal die gesamte Dovecot-Konfiguration gelöscht:&amp;lt;/p&amp;gt;&amp;lt;pre&amp;gt;&amp;lt;code&amp;gt;rm -r /etc/dovecot/*&lt;br /&gt;
cd /etc/dovecot&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;/pre&amp;gt;&amp;lt;p&amp;gt;Für Dovecot reichen die folgenden zwei Konfigurationsdateien (&amp;lt;code&amp;gt;dovecot.conf&amp;lt;/code&amp;gt; und &amp;lt;code&amp;gt;dovecot-sql.conf&amp;lt;/code&amp;gt;) aus. Erstellt die beiden Dateien im Verzeichnis &amp;lt;code&amp;gt;/etc/dovecot/&amp;lt;/code&amp;gt;.&amp;lt;/p&amp;gt;&lt;br /&gt;
=== Hauptkonfigurationsdatei &amp;lt;code&amp;gt;/etc/dovecot/dovecot.conf&amp;lt;/code&amp;gt; ===&lt;br /&gt;
&amp;lt;pre&amp;gt;&amp;lt;code&amp;gt;##&lt;br /&gt;
## Aktivierte Protokolle&lt;br /&gt;
##&lt;br /&gt;
&lt;br /&gt;
protocols = imap lmtp sieve &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
##&lt;br /&gt;
## TLS Config&lt;br /&gt;
## Quelle: https://ssl-config.mozilla.org/#server=dovecot&amp;amp;version=2.3.9&amp;amp;config=intermediate&amp;amp;openssl=1.1.1d&amp;amp;guideline=5.4&lt;br /&gt;
##&lt;br /&gt;
&lt;br /&gt;
ssl = required&lt;br /&gt;
ssl_cert = &amp;amp;lt;/etc/acme.sh/mail.mysystems.tld/fullchain.pem&lt;br /&gt;
ssl_key = &amp;amp;lt;/etc/acme.sh/mail.mysystems.tld/privkey.pem&lt;br /&gt;
ssl_dh = &amp;amp;lt;/etc/dovecot/dh4096.pem&lt;br /&gt;
ssl_min_protocol = TLSv1.2&lt;br /&gt;
ssl_cipher_list = ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384&lt;br /&gt;
ssl_prefer_server_ciphers = no&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
##&lt;br /&gt;
## Dovecot services&lt;br /&gt;
##&lt;br /&gt;
&lt;br /&gt;
service imap-login {&lt;br /&gt;
    inet_listener imap {&lt;br /&gt;
        port = 143&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
service managesieve-login {&lt;br /&gt;
    inet_listener sieve {&lt;br /&gt;
        port = 4190&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
service lmtp {&lt;br /&gt;
    unix_listener /var/spool/postfix/private/dovecot-lmtp {&lt;br /&gt;
        mode = 0660&lt;br /&gt;
        group = postfix&lt;br /&gt;
        user = postfix&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    user = vmail&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
service auth {&lt;br /&gt;
    ### Auth socket für Postfix&lt;br /&gt;
    unix_listener /var/spool/postfix/private/auth {&lt;br /&gt;
        mode = 0660&lt;br /&gt;
        user = postfix&lt;br /&gt;
        group = postfix&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    ### Auth socket für LMTP-Dienst&lt;br /&gt;
    unix_listener auth-userdb {&lt;br /&gt;
        mode = 0660&lt;br /&gt;
        user = vmail&lt;br /&gt;
        group = vmail&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
##&lt;br /&gt;
##  Protocol settings&lt;br /&gt;
##&lt;br /&gt;
&lt;br /&gt;
protocol imap {&lt;br /&gt;
    mail_plugins = $mail_plugins quota imap_quota imap_sieve&lt;br /&gt;
    mail_max_userip_connections = 20&lt;br /&gt;
    imap_idle_notify_interval = 29 mins&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
protocol lmtp {&lt;br /&gt;
    postmaster_address = postmaster@mysystems.tld&lt;br /&gt;
    mail_plugins = $mail_plugins sieve notify push_notification&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
##&lt;br /&gt;
## Client authentication&lt;br /&gt;
##&lt;br /&gt;
&lt;br /&gt;
disable_plaintext_auth = yes&lt;br /&gt;
auth_mechanisms = plain login&lt;br /&gt;
auth_username_format = %Lu&lt;br /&gt;
&lt;br /&gt;
passdb {&lt;br /&gt;
    driver = sql&lt;br /&gt;
    args = /etc/dovecot/dovecot-sql.conf&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
userdb {&lt;br /&gt;
    driver = sql&lt;br /&gt;
    args = /etc/dovecot/dovecot-sql.conf&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
##&lt;br /&gt;
## Address tagging&lt;br /&gt;
##&lt;br /&gt;
recipient_delimiter = +&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
##&lt;br /&gt;
## Mail location&lt;br /&gt;
##&lt;br /&gt;
&lt;br /&gt;
mail_uid = vmail&lt;br /&gt;
mail_gid = vmail&lt;br /&gt;
mail_privileged_group = vmail&lt;br /&gt;
&lt;br /&gt;
mail_home = /var/vmail/mailboxes/%d/%n&lt;br /&gt;
mail_location = maildir:~/mail:LAYOUT=fs&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
##&lt;br /&gt;
## Mailbox configuration&lt;br /&gt;
##&lt;br /&gt;
&lt;br /&gt;
namespace inbox {&lt;br /&gt;
    inbox = yes&lt;br /&gt;
&lt;br /&gt;
    mailbox Spam {&lt;br /&gt;
        auto = subscribe&lt;br /&gt;
        special_use = \Junk&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    mailbox Trash {&lt;br /&gt;
        auto = subscribe&lt;br /&gt;
        special_use = \Trash&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    mailbox Drafts {&lt;br /&gt;
        auto = subscribe&lt;br /&gt;
        special_use = \Drafts&lt;br /&gt;
    }&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;
&lt;br /&gt;
##&lt;br /&gt;
## Mail plugins&lt;br /&gt;
##&lt;br /&gt;
&lt;br /&gt;
plugin {&lt;br /&gt;
    sieve_plugins = sieve_imapsieve sieve_extprograms&lt;br /&gt;
    sieve_before = /var/vmail/sieve/global/spam-global.sieve&lt;br /&gt;
    sieve = file:/var/vmail/sieve/%d/%n/scripts;active=/var/vmail/sieve/%d/%n/active-script.sieve&lt;br /&gt;
&lt;br /&gt;
    ###&lt;br /&gt;
    ### Spam learning&lt;br /&gt;
    ###&lt;br /&gt;
    # From elsewhere to Spam folder&lt;br /&gt;
    imapsieve_mailbox1_name = Spam&lt;br /&gt;
    imapsieve_mailbox1_causes = COPY&lt;br /&gt;
    imapsieve_mailbox1_before = file:/var/vmail/sieve/global/learn-spam.sieve&lt;br /&gt;
&lt;br /&gt;
    # From Spam folder to elsewhere&lt;br /&gt;
    imapsieve_mailbox2_name = *&lt;br /&gt;
    imapsieve_mailbox2_from = Spam&lt;br /&gt;
    imapsieve_mailbox2_causes = COPY&lt;br /&gt;
    imapsieve_mailbox2_before = file:/var/vmail/sieve/global/learn-ham.sieve&lt;br /&gt;
&lt;br /&gt;
    sieve_pipe_bin_dir = /usr/bin&lt;br /&gt;
    sieve_global_extensions = +vnd.dovecot.pipe&lt;br /&gt;
&lt;br /&gt;
    quota = maildir:User quota&lt;br /&gt;
    quota_exceeded_message = Benutzer %u hat das Speichervolumen überschritten. / User %u has exhausted allowed storage space.&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;/pre&amp;gt;&amp;lt;p&amp;gt;Anzupassende Stellen:&amp;lt;/p&amp;gt;&lt;br /&gt;
*&amp;lt;code&amp;gt;ssl_cert&amp;lt;/code&amp;gt;: Pfad zur Zertifikatsdatei&lt;br /&gt;
*&amp;lt;code&amp;gt;ssl_key&amp;lt;/code&amp;gt;: Pfad zur Zertifikatsdatei&lt;br /&gt;
*&amp;lt;code&amp;gt;postmaster_address&amp;lt;/code&amp;gt;: Domain anpassen&lt;br /&gt;
&lt;br /&gt;
==== Erklärung ====&lt;br /&gt;
&amp;lt;p&amp;gt;&amp;lt;code&amp;gt;dovecot.conf&amp;lt;/code&amp;gt; ist die Hauptkonfigurationsdatei des Dovecot-Servers:&amp;lt;/p&amp;gt;&amp;lt;p&amp;gt;'''Dovecot Services:''' Im darauf folgenden Abschnitt werden die Dovecot Services konfiguriert. Dazu gehört z.B. der Dienst “imap-login”, der auf eingehende Verbindungen von E-Mail Clients auf Port 143 horcht. Auch “managesieve-login” kommuniziert mit dem Mailclient, wenn dieser eine Funktion zur Bearbeitung Server-seitiger Filterscripte mitbringt. Die anderen Dienste werden intern genutzt: Der lmtp-Dienst stellt eine Schnittstelle bereit, über die Postfix empfangene Mails an die Mailbox übergeben kann. Der “auth” Dienst wird vom LMTP-Dienst genutzt, um die Existenz von Benutzern zu überprüfen, aber auch von Postfix, um den Login am Postfix-Server zu überprüfen. Mit “mode”, “user” und “group” wird bestimmt, welcher Systemuser Zugriff auf den Dienst haben soll (Analog zu den Dateirechten – der Socket für den Dienst ist nichts anderes als eine Datei).&amp;lt;/p&amp;gt;&amp;lt;p&amp;gt;'''Protocol settings:''' Für die verwendeten Protokolle können zusätzliche Einstellungen gesetzt werden – u.A. auch, welche Erweiterungen im Zusammenhang mit dem Protokoll genutzt werden sollen. “quota” und “imap_quota” sind notwendig, um das maximale Volumen einer Mailbox festsetzen zu können. Beim lmtp-Protokoll kann auf diese Erweiterungen verzichtet werden: Hier wird nur die Sieve-Erweiterung zum Filtern von E-Mails benötigt.&amp;lt;/p&amp;gt;&amp;lt;p&amp;gt;'''Client Authentication:''' Die Zeilen&amp;lt;/p&amp;gt;&amp;lt;pre&amp;gt;&amp;lt;code&amp;gt;disable_plaintext_auth = yes&lt;br /&gt;
auth_mechanisms = plain login&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;/pre&amp;gt;&amp;lt;p&amp;gt;scheinen sich zu widersprechen, schließlich wird die Klartext-Authentifizierung abgeschaltet. Doch tatsächlich wird sie das nur für unverschlüsselte Verbindungen. TLS-Verschlüsselte Verbindungen bleiben davon unberührt, sodass in der nächsten Zeile die “plain” Authentifizierung mit Klartext-Passwörtern wieder angeboten werden kann. Das wird aus zwei Gründen getan:&amp;lt;/p&amp;gt;&lt;br /&gt;
*“Klartext” tut uns hier nicht weh – schließlich ist die Verbindung sowieso (zwingend) verschlüsselt.&lt;br /&gt;
*Alle Mailclients unterstützen die Klartextauthentifizierung. Andere Loginmechanismen werden weniger gut unterstützt und sind aufwendiger.&lt;br /&gt;
&amp;lt;p&amp;gt;Wir konzentrieren uns deshalb auf die klassische Klartextauthentifizierung. Wie bereits erwähnt: Da unsere Verbindung ohnehin verschlüsselt ist, ist das in diesem Fall nicht sicherheitsrelevant.&amp;lt;/p&amp;gt;&amp;lt;p&amp;gt;Für &amp;lt;code&amp;gt;passdb&amp;lt;/code&amp;gt; und &amp;lt;code&amp;gt;userdb&amp;lt;/code&amp;gt; wird jeweils der Pfad zur SQL-Datei eingestellt. Dort befindt sich jeweils eine passende SQL-Query. Die “passdb” wird befragt, wenn es um die Authentifizierung von Usern geht, die “userdb”, wenn die Existenz eines bestimmten E-Mail Kontos überprüft werden soll, oder benutzerdefinierte Einstellungen geladen werden müssen, wie z.B. das Mailbox-Kontingent (“Quota”).&amp;lt;/p&amp;gt;&amp;lt;p&amp;gt;'''Mail location:''' In diesem Abschnitt wird definiert, unter welchem Systemuser Dovecot auf Dateisystem-Ebene mit E-Mails hantieren soll. Außerdem wird ein Pfad-Schema festgelegt, das bestimmt, nach welcher Struktur die Mailbox-Verzeichnisse angelegt werden sollen. %d steht für die Domain des Accounts und %n für den Benutzernamen vor dem @. Der Pfad zu einer Benutzermailbox lautet z.B.: &amp;lt;code&amp;gt;/var/vmail/mailboxes/mysystems.tld/admin/mail/&amp;lt;/code&amp;gt;&amp;lt;/p&amp;gt;&amp;lt;p&amp;gt;'''Mailbox Configuration:''' In der Mailbox eines jeden Users soll sich standardmäßig ein “Spam”-Ordner befinden, in die ein passendes Sieve-Filterskript verdächtige E-Mails verschieben soll.&amp;lt;/p&amp;gt;&amp;lt;p&amp;gt;'''Mail Plugins:''' Hier werden die Details zu den Erweiterungen &amp;lt;code&amp;gt;sieve&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;quota&amp;lt;/code&amp;gt; und &amp;lt;code&amp;gt;imapsieve&amp;lt;/code&amp;gt; definiert. Das Script unter &amp;lt;code&amp;gt;sieve_before&amp;lt;/code&amp;gt; wird für alle User (unabhängig von den eigenen Einstellungen) immer ausgeführt. Es hat die Aufgabe, durch Rspamd markierte Mails in den Spam-Ordner zu verschieben. &amp;lt;code&amp;gt;sieve_dir&amp;lt;/code&amp;gt; definiert das Schema für den Ort, an dem benutzerdefinierte Scripts abgelegt werden. Das aktive Skript eines Nutzers soll jeweils über den symbolischen Link &amp;lt;code&amp;gt;active-script.sieve&amp;lt;/code&amp;gt; zugänglich sein. Die &amp;lt;code&amp;gt;imapsieve&amp;lt;/code&amp;gt; Einstellungen lassen den IMAP-Server Verschiebevorgängezwischen Mailbox-Ordnern erkennen, sodass Rspamd aus einer Neuordnung lernen kann.&amp;lt;/p&amp;gt;&lt;br /&gt;
=== Diffie-Hellman Parameter für Dovecot generieren ===&lt;br /&gt;
&amp;lt;p&amp;gt;In neueren Versionen generiert Dovecot die Diffie-Hellman-Parameter für TLS-Verbindungen nicht mehr selbst. Also müssen wir selbst Hand anlegen und die Parameter mittels OpenSSL-Tool generieren lassen:&amp;lt;/p&amp;gt;&amp;lt;pre&amp;gt;&amp;lt;code&amp;gt;openssl dhparam -out /etc/dovecot/dh4096.pem 4096 &lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;/pre&amp;gt;&amp;lt;p&amp;gt;Das kann je nach Auslastung des Mailservers durchaus eine viertel Stunde oder länger dauern. Um den Vorhang zu beschleunigen, kann ein sog. Entropy Harvester wie z.B. &amp;lt;code&amp;gt;haveged&amp;lt;/code&amp;gt; installiert werden (&amp;lt;code&amp;gt;apt install haveged&amp;lt;/code&amp;gt;).&amp;lt;/p&amp;gt;&lt;br /&gt;
=== SQL-Konfgurationsdatei &amp;lt;code&amp;gt;/etc/dovecot/dovecot-sql.conf&amp;lt;/code&amp;gt; ===&lt;br /&gt;
&amp;lt;pre&amp;gt;&amp;lt;code&amp;gt;driver=mysql&lt;br /&gt;
connect = &amp;quot;host=localhost dbname=vmail user=vmail password=vmaildbpass&amp;quot;&lt;br /&gt;
default_pass_scheme = SHA512-CRYPT&lt;br /&gt;
&lt;br /&gt;
password_query = SELECT username AS user, domain, password FROM accounts WHERE username = '%Ln' AND domain = '%Ld' and enabled = true;&lt;br /&gt;
user_query = SELECT concat('*:storage=', quota, 'M') AS quota_rule FROM accounts WHERE username = '%Ln' AND domain = '%Ld' AND sendonly = false;&lt;br /&gt;
iterate_query = SELECT username, domain FROM accounts where sendonly = false;&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;/pre&amp;gt;&amp;lt;p&amp;gt;Anzupassende Stellen:&amp;lt;/p&amp;gt;&lt;br /&gt;
*Datenbankpasswort “vmaildbpass”&lt;br /&gt;
&amp;lt;p&amp;gt;&amp;lt;code&amp;gt;dovecot-sql.conf&amp;lt;/code&amp;gt; enthält sensible Datenbank-Zugangsdaten und wird deshalb geschützt:&amp;lt;/p&amp;gt;&amp;lt;pre&amp;gt;&amp;lt;code&amp;gt;chmod 440 dovecot-sql.conf&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;/pre&amp;gt;&lt;br /&gt;
==== Erklärung ====&lt;br /&gt;
&amp;lt;p&amp;gt;Die Konfigurationsdatei &amp;lt;code&amp;gt;dovecot-sql.conf&amp;lt;/code&amp;gt; enthält alle SQL-relevanten Einstellungen:&amp;lt;/p&amp;gt;&lt;br /&gt;
*&amp;lt;code&amp;gt;driver&amp;lt;/code&amp;gt;: Welcher Datenbank-Treiber soll genutzt werden?&lt;br /&gt;
*&amp;lt;code&amp;gt;connect&amp;lt;/code&amp;gt;: Informationen zur Datenbankverbindung&lt;br /&gt;
*&amp;lt;code&amp;gt;default_pass_scheme&amp;lt;/code&amp;gt;: Standardmäßig angenommenes Hash-Schema, wenn es in der Datenbank nicht explizit angegeben ist, z.B. mit vorangestelltem {SHA512-CRYPT}.&lt;br /&gt;
*&amp;lt;code&amp;gt;password_query&amp;lt;/code&amp;gt;: SQL Query für die Überprüfung des User-Logins. Stimmen Benutzername und Passwort überein? Existiert der Benutzer und ist er aktiviert?&lt;br /&gt;
*&amp;lt;code&amp;gt;user_query&amp;lt;/code&amp;gt;: SQL-Query zum Abholen aller Benutzer-spezifischen Einstellungen. In diesem Fall: Maximales Mailbox-Volumen (“Quota”).&lt;br /&gt;
*&amp;lt;code&amp;gt;iterate_query&amp;lt;/code&amp;gt;: SQL-Query zur Abfrage aller verfügbarer Benutzer. Benutzer, die keine Mails empfangen können (sendonly=true) sind für Dovecot nicht interessant und werden nicht mit ausgegeben.&lt;br /&gt;
&lt;br /&gt;
=== Globales Sieve-Filterscript für Spam ===&lt;br /&gt;
&amp;lt;p&amp;gt;Unter &amp;lt;code&amp;gt;/var/vmail/sieve/global/&amp;lt;/code&amp;gt; wird das Sieve-Filterscript &amp;lt;code&amp;gt;spam-global.sieve&amp;lt;/code&amp;gt; erstellt, das erkannte Spammails in den Unterordner “Spam” jeder Mailbox einsortiert. Rspamd markiert erkannte E-Mails mit einem speziellen Spam-Header, den das Script erkennt. Inhalt von &amp;lt;code&amp;gt;spam-global.sieve&amp;lt;/code&amp;gt;:&amp;lt;/p&amp;gt;&amp;lt;pre&amp;gt;&amp;lt;code&amp;gt;require &amp;quot;fileinto&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
if header :contains &amp;quot;X-Spam-Flag&amp;quot; &amp;quot;YES&amp;quot; {&lt;br /&gt;
    fileinto &amp;quot;Spam&amp;quot;;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
if header :is &amp;quot;X-Spam&amp;quot; &amp;quot;Yes&amp;quot; {&lt;br /&gt;
    fileinto &amp;quot;Spam&amp;quot;;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;/pre&amp;gt;&lt;br /&gt;
=== Spam Learning mit Rspamd ===&lt;br /&gt;
&amp;lt;p&amp;gt;Beim Verschieben von Spammails in den Spam-Ordner bzw. dem Herausverschieben falsch beurteilter Mails in den Posteingang soll ein Lernprozess von Rspamd ausgelöst werden, sodass der Filter aus falschen Einschätzungen lernt und so mit der Zeit immer besser wird.&amp;lt;/p&amp;gt;&amp;lt;p&amp;gt;Dazu werden zwei Sieve-Scripts in &amp;lt;code&amp;gt;/var/vmail/sieve/global/&amp;lt;/code&amp;gt; angelegt:&amp;lt;/p&amp;gt;&amp;lt;p&amp;gt;&amp;lt;code&amp;gt;learn-spam.sieve&amp;lt;/code&amp;gt;&amp;lt;/p&amp;gt;&amp;lt;pre&amp;gt;&amp;lt;code&amp;gt;require [&amp;quot;vnd.dovecot.pipe&amp;quot;, &amp;quot;copy&amp;quot;, &amp;quot;imapsieve&amp;quot;];&lt;br /&gt;
pipe :copy &amp;quot;rspamc&amp;quot; [&amp;quot;learn_spam&amp;quot;];&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;/pre&amp;gt;&amp;lt;p&amp;gt;&amp;lt;code&amp;gt;learn-ham.sieve&amp;lt;/code&amp;gt;&amp;lt;/p&amp;gt;&amp;lt;pre&amp;gt;&amp;lt;code&amp;gt;require [&amp;quot;vnd.dovecot.pipe&amp;quot;, &amp;quot;copy&amp;quot;, &amp;quot;imapsieve&amp;quot;, &amp;quot;environment&amp;quot;, &amp;quot;variables&amp;quot;];&lt;br /&gt;
&lt;br /&gt;
if environment :matches &amp;quot;imap.mailbox&amp;quot; &amp;quot;*&amp;quot; {&lt;br /&gt;
    set &amp;quot;mailbox&amp;quot; &amp;quot;${1}&amp;quot;;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
if string &amp;quot;${mailbox}&amp;quot; &amp;quot;Trash&amp;quot; {&lt;br /&gt;
    stop;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
pipe :copy &amp;quot;rspamc&amp;quot; [&amp;quot;learn_ham&amp;quot;];&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;/pre&amp;gt;&amp;lt;p&amp;gt;Das &amp;lt;code&amp;gt;learn-ham.sieve&amp;lt;/code&amp;gt; Script besitzt noch einen Check, der überprüft, ob eine E-Mail aus dem Spam in den Papierkorb verschoben wurde. In diesem Fall sollen die betroffenen Mails ja nicht wieder als “Ham” markiert werden, daher wird in so einem Fall die Ausführung des Lernvorgangs verhindert.&amp;lt;/p&amp;gt;&lt;br /&gt;
== Postfix installieren und konfigurieren ==&lt;br /&gt;
&amp;lt;p&amp;gt;Für unseren Postfix-Server benötigen wir nur zwei Pakete: Das Kernpaket &amp;lt;code&amp;gt;postfix&amp;lt;/code&amp;gt; und die Komponente &amp;lt;code&amp;gt;postfix-mysql&amp;lt;/code&amp;gt;, die Postfix mit der MySQL-Datenbank kommunizieren lässt.&amp;lt;/p&amp;gt;&amp;lt;pre&amp;gt;&amp;lt;code&amp;gt;apt install postfix postfix-mysql&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;/pre&amp;gt;&amp;lt;p&amp;gt;Während der Installation werdet ihr nach der “Allgemeinen Art der Konfiguration” gefragt. Wählt an dieser Stelle “Keine Konfiguration” und beendet den Postfix-Server wieder:&amp;lt;/p&amp;gt;&amp;lt;pre&amp;gt;&amp;lt;code&amp;gt;systemctl stop postfix&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;/pre&amp;gt;&amp;lt;p&amp;gt;Im Postfix-Konfigurationsverzeichnis &amp;lt;code&amp;gt;/etc/postfix&amp;lt;/code&amp;gt; befinden sich trotz unserer Wahl “Keine Konfiguration” ein paar Konfigurationsdateien, die zunächst entfernt werden:&amp;lt;/p&amp;gt;&amp;lt;pre&amp;gt;&amp;lt;code&amp;gt;cd /etc/postfix&lt;br /&gt;
rm -r sasl&lt;br /&gt;
rm master.cf main.cf.proto master.cf.proto&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;/pre&amp;gt;&amp;lt;p&amp;gt;Legt dann folgende Dateien im Verzeichnis &amp;lt;code&amp;gt;/etc/postfix&amp;lt;/code&amp;gt; an:&amp;lt;/p&amp;gt;&lt;br /&gt;
=== &amp;lt;code&amp;gt;/etc/postfix/main.cf&amp;lt;/code&amp;gt; ===&lt;br /&gt;
&amp;lt;pre&amp;gt;&amp;lt;code&amp;gt;##&lt;br /&gt;
## Netzwerkeinstellungen&lt;br /&gt;
##&lt;br /&gt;
&lt;br /&gt;
mynetworks = 127.0.0.0/8 [::ffff:127.0.0.0]/104 [::1]/128&lt;br /&gt;
inet_interfaces = 127.0.0.1, ::1, 203.0.113.1, 2001:db8::1&lt;br /&gt;
myhostname = mail.mysystems.tld&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
##&lt;br /&gt;
## Mail-Queue Einstellungen&lt;br /&gt;
##&lt;br /&gt;
&lt;br /&gt;
maximal_queue_lifetime = 1h&lt;br /&gt;
bounce_queue_lifetime = 1h&lt;br /&gt;
maximal_backoff_time = 15m&lt;br /&gt;
minimal_backoff_time = 5m&lt;br /&gt;
queue_run_delay = 5m&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
##&lt;br /&gt;
## TLS Einstellungen&lt;br /&gt;
## Quelle: https://ssl-config.mozilla.org/#server=postfix&amp;amp;version=3.4.8&amp;amp;config=intermediate&amp;amp;openssl=1.1.1d&amp;amp;guideline=5.4&lt;br /&gt;
##&lt;br /&gt;
&lt;br /&gt;
### Allgemein&lt;br /&gt;
tls_preempt_cipherlist = no&lt;br /&gt;
tls_ssl_options = NO_COMPRESSION&lt;br /&gt;
tls_medium_cipherlist = ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384&lt;br /&gt;
&lt;br /&gt;
### Ausgehende SMTP-Verbindungen (Postfix als Sender)&lt;br /&gt;
smtp_tls_security_level = dane&lt;br /&gt;
smtp_dns_support_level = dnssec&lt;br /&gt;
smtp_tls_policy_maps = proxy:mysql:/etc/postfix/sql/tls-policy.cf&lt;br /&gt;
smtp_tls_session_cache_database = btree:${data_directory}/smtp_scache&lt;br /&gt;
smtp_tls_ciphers = medium&lt;br /&gt;
smtp_tls_CAfile = /etc/ssl/certs/ca-certificates.crt&lt;br /&gt;
&lt;br /&gt;
### Eingehende SMTP-Verbindungen&lt;br /&gt;
smtpd_tls_security_level = may&lt;br /&gt;
smtpd_tls_auth_only = yes&lt;br /&gt;
smtpd_tls_ciphers = medium&lt;br /&gt;
smtpd_tls_mandatory_protocols = !SSLv2, !SSLv3, !TLSv1, !TLSv1.1&lt;br /&gt;
smtpd_tls_protocols = !SSLv2, !SSLv3, !TLSv1, !TLSv1.1&lt;br /&gt;
smtpd_tls_session_cache_database = btree:${data_directory}/smtpd_scache&lt;br /&gt;
smtpd_tls_cert_file=/etc/acme.sh/mail.mysystems.tld/fullchain.pem&lt;br /&gt;
smtpd_tls_key_file=/etc/acme.sh/mail.mysystems.tld/privkey.pem&lt;br /&gt;
smtpd_tls_dh1024_param_file = /etc/postfix/dh2048.pem&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
##&lt;br /&gt;
## Lokale Mailzustellung an Dovecot&lt;br /&gt;
##&lt;br /&gt;
&lt;br /&gt;
virtual_transport = lmtp:unix:private/dovecot-lmtp&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
##&lt;br /&gt;
## Spamfilter und DKIM-Signaturen via Rspamd&lt;br /&gt;
##&lt;br /&gt;
&lt;br /&gt;
smtpd_milters = inet:localhost:11332&lt;br /&gt;
non_smtpd_milters = inet:localhost:11332&lt;br /&gt;
milter_protocol = 6&lt;br /&gt;
milter_mail_macros =  i {mail_addr} {client_addr} {client_name} {auth_authen}&lt;br /&gt;
milter_default_action = accept&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
##&lt;br /&gt;
## Server Restrictions für Clients, Empfänger und Relaying&lt;br /&gt;
## (im Bezug auf S2S-Verbindungen. Mailclient-Verbindungen werden in master.cf im Submission-Bereich konfiguriert)&lt;br /&gt;
##&lt;br /&gt;
&lt;br /&gt;
### Bedingungen, damit Postfix als Relay arbeitet (für Clients)&lt;br /&gt;
smtpd_relay_restrictions =      reject_non_fqdn_recipient&lt;br /&gt;
                                reject_unknown_recipient_domain&lt;br /&gt;
                                permit_mynetworks&lt;br /&gt;
                                reject_unauth_destination&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
### Bedingungen, damit Postfix ankommende E-Mails als Empfängerserver entgegennimmt (zusätzlich zu relay-Bedingungen)&lt;br /&gt;
### check_recipient_access prüft, ob ein account sendonly ist&lt;br /&gt;
smtpd_recipient_restrictions = check_recipient_access proxy:mysql:/etc/postfix/sql/recipient-access.cf&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
### Bedingungen, die SMTP-Clients erfüllen müssen (sendende Server)&lt;br /&gt;
smtpd_client_restrictions =     permit_mynetworks&lt;br /&gt;
                                check_client_access hash:/etc/postfix/without_ptr&lt;br /&gt;
                                reject_unknown_client_hostname&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
### Wenn fremde Server eine Verbindung herstellen, müssen sie einen gültigen Hostnamen im HELO haben.&lt;br /&gt;
smtpd_helo_required = yes&lt;br /&gt;
smtpd_helo_restrictions =   permit_mynetworks&lt;br /&gt;
                            reject_invalid_helo_hostname&lt;br /&gt;
                            reject_non_fqdn_helo_hostname&lt;br /&gt;
                            reject_unknown_helo_hostname&lt;br /&gt;
&lt;br /&gt;
# Clients blockieren, wenn sie versuchen zu früh zu senden&lt;br /&gt;
smtpd_data_restrictions = reject_unauth_pipelining&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
##&lt;br /&gt;
## Restrictions für MUAs (Mail user agents)&lt;br /&gt;
##&lt;br /&gt;
&lt;br /&gt;
mua_relay_restrictions = reject_non_fqdn_recipient,reject_unknown_recipient_domain,permit_mynetworks,permit_sasl_authenticated,reject&lt;br /&gt;
mua_sender_restrictions = permit_mynetworks,reject_non_fqdn_sender,reject_sender_login_mismatch,permit_sasl_authenticated,reject&lt;br /&gt;
mua_client_restrictions = permit_mynetworks,permit_sasl_authenticated,reject&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
##&lt;br /&gt;
## MySQL Abfragen&lt;br /&gt;
##&lt;br /&gt;
&lt;br /&gt;
proxy_read_maps =       proxy:mysql:/etc/postfix/sql/aliases.cf&lt;br /&gt;
                        proxy:mysql:/etc/postfix/sql/accounts.cf&lt;br /&gt;
                        proxy:mysql:/etc/postfix/sql/domains.cf&lt;br /&gt;
                        proxy:mysql:/etc/postfix/sql/recipient-access.cf&lt;br /&gt;
                        proxy:mysql:/etc/postfix/sql/sender-login-maps.cf&lt;br /&gt;
                        proxy:mysql:/etc/postfix/sql/tls-policy.cf&lt;br /&gt;
&lt;br /&gt;
virtual_alias_maps = proxy:mysql:/etc/postfix/sql/aliases.cf&lt;br /&gt;
virtual_mailbox_maps = proxy:mysql:/etc/postfix/sql/accounts.cf&lt;br /&gt;
virtual_mailbox_domains = proxy:mysql:/etc/postfix/sql/domains.cf&lt;br /&gt;
local_recipient_maps = $virtual_mailbox_maps&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
##&lt;br /&gt;
## Sonstiges&lt;br /&gt;
##&lt;br /&gt;
&lt;br /&gt;
### Maximale Größe der gesamten Mailbox (soll von Dovecot festgelegt werden, 0 = unbegrenzt)&lt;br /&gt;
mailbox_size_limit = 0&lt;br /&gt;
&lt;br /&gt;
### Maximale Größe eingehender E-Mails in Bytes (50 MB)&lt;br /&gt;
message_size_limit = 52428800&lt;br /&gt;
&lt;br /&gt;
### Keine System-Benachrichtigung für Benutzer bei neuer E-Mail&lt;br /&gt;
biff = no&lt;br /&gt;
&lt;br /&gt;
### Nutzer müssen immer volle E-Mail Adresse angeben - nicht nur Hostname&lt;br /&gt;
append_dot_mydomain = no&lt;br /&gt;
&lt;br /&gt;
### Trenn-Zeichen für &amp;quot;Address Tagging&amp;quot;&lt;br /&gt;
recipient_delimiter = +&lt;br /&gt;
&lt;br /&gt;
### Keine Rückschlüsse auf benutzte Mailadressen zulassen&lt;br /&gt;
disable_vrfy_command = yes&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;/pre&amp;gt;&amp;lt;p&amp;gt;Anzupassen:&amp;lt;/p&amp;gt;&lt;br /&gt;
*&amp;lt;code&amp;gt;inet_interfaces&amp;lt;/code&amp;gt;: IP-Adressen &amp;lt;code&amp;gt;203.0.113.1, 2001:db8::1&amp;lt;/code&amp;gt; müssen durch eigene IPv4- (und optional IPv6)-Adresse ersetzt werden.&lt;br /&gt;
*&amp;lt;code&amp;gt;myhostname&amp;lt;/code&amp;gt;: Ersetzen durch eigenen Hostnamen&lt;br /&gt;
*&amp;lt;code&amp;gt;smtpd_tls_cert_file&amp;lt;/code&amp;gt;: Pfad zur Zertifikatsdatei&lt;br /&gt;
*&amp;lt;code&amp;gt;smtpd_tls_key_file&amp;lt;/code&amp;gt;: Pfad zur Zertifikatsdatei&lt;br /&gt;
&lt;br /&gt;
==== Diffie-Hellman-Parameter für Postfix generieren ====&lt;br /&gt;
&amp;lt;p&amp;gt;Neben Dovecot bekommt auch Postfix “von Hand generierte” DH-Parameter. Hier allerdings nur 2048 Bit starke, um zu älteren Mailservern kompatibel zu bleiben.&amp;lt;/p&amp;gt;&amp;lt;pre&amp;gt;&amp;lt;code&amp;gt;openssl dhparam -out /etc/postfix/dh2048.pem 2048&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;/pre&amp;gt;&amp;lt;p&amp;gt;Wundert euch übrigens nicht über das &amp;lt;code&amp;gt;1024&amp;lt;/code&amp;gt; in der Einstellung &amp;lt;code&amp;gt;smtpd_tls_dh1024_param_file&amp;lt;/code&amp;gt; - das ist nur Teil des Namens und hat keine Bedeutung für die Schlüssellänge.&amp;lt;/p&amp;gt;&amp;lt;div class=&amp;quot;warning&amp;quot;&amp;gt;&amp;lt;p&amp;gt;Wenn der Mailserver (entgegen meiner Empfehlung) nicht einen &amp;lt;code&amp;gt;mail.domain.tld&amp;lt;/code&amp;gt; Hostnamen hat, sondern unter dem Domainnamen läuft (&amp;lt;code&amp;gt;domain.tld&amp;lt;/code&amp;gt;), muss zur Konfiguration eine Zeile mit&amp;lt;/p&amp;gt;&amp;lt;pre&amp;gt;&amp;lt;code&amp;gt;mydestination =&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;/pre&amp;gt;&amp;lt;p&amp;gt;(ohne Inhalt nach dem “=&amp;quot;) hinzugefügt werden, sonst werden E-Mails an der falschen Stelle gespeichert.&amp;lt;/p&amp;gt;&amp;lt;/div&amp;gt;&lt;br /&gt;
==== Erklärung ====&lt;br /&gt;
&amp;lt;p&amp;gt;'''Netzwerkeinstellungen:'''&amp;lt;/p&amp;gt;&lt;br /&gt;
*&amp;lt;code&amp;gt;mynetworks&amp;lt;/code&amp;gt;: Anfragen von diesen IP-Adressen / aus diesen IP-Adressbereichen werden von Postfix gesondert behandelt (Verwendung für “mynetworks” in den Restrictions). Üblicherweise werden hier die lokalen Adressbereiche und IP-Adressen aus dem eigenen Netz eingetragen, z.B. von anderen eigenen, vertrauenswürdigen Servern.&lt;br /&gt;
*&amp;lt;code&amp;gt;inet_interfaces&amp;lt;/code&amp;gt;: Auf diesen IP-Adressen soll Postfix seine Ports öffnen. Die IP-Adressen müssen an den eigenen Server angepasst werden.&lt;br /&gt;
*&amp;lt;code&amp;gt;myhostname&amp;lt;/code&amp;gt;: Der Hostname des Mailservers, wie er bei der Mailverarbeitung genutzt werden soll.&lt;br /&gt;
&amp;lt;p&amp;gt;'''Mail-Queue Einstellungen:'''&amp;lt;/p&amp;gt;&amp;lt;p&amp;gt;E-Mails in Postfix werden “gequeued”, d.h. in eine Warteschlange eingetragen, die regelmäßig abgearbeitet wird. Wenn Mails nicht zustellbar sind, verbleiben sie eine gewisse Zeit in der Queue, bis ihre Lebenszeit abgelaufen ist, und sie aus der Queue entfernt werden. Der Absender der E-Mail bekommt dann eine entsprechende Nachricht, in der er über die Unzustellbarkeit informiert wird.&amp;lt;/p&amp;gt;&lt;br /&gt;
*&amp;lt;code&amp;gt;maximal_queue_lifetime&amp;lt;/code&amp;gt;: Lebensdauer einer normalen Nachricht in der Queue. Wenn eine E-Mail innerhalb einer Stunde nicht zugestellt werden konnte, wird sie aus der Queue entfernt und der Absender benachrichtigt.&lt;br /&gt;
*&amp;lt;code&amp;gt;bounce_queue_lifetime&amp;lt;/code&amp;gt;: Lebensdauer einer Unzustellbarkeits-Benachrichtigung in der Queue.&lt;br /&gt;
*&amp;lt;code&amp;gt;maximal_backoff_time&amp;lt;/code&amp;gt;: Maximale Zeit, die verstreichen darf, bis für eine E-Mail ein neuer Zustellversuch gestartet wird.&lt;br /&gt;
*&amp;lt;code&amp;gt;minimal_backoff_time&amp;lt;/code&amp;gt;: Zeit, die mindestens verstrichen sein muss, bis ein neuer Zustellversuch gestartet wird.&lt;br /&gt;
*&amp;lt;code&amp;gt;queue_run_delay&amp;lt;/code&amp;gt;: Intervall, in dem die Queue nach nicht zustellbaren E-Mails durchsucht wird.&lt;br /&gt;
&amp;lt;p&amp;gt;'''TLS-Einstellungen:'''&amp;lt;/p&amp;gt;&amp;lt;p&amp;gt;Kompression wird abgeschaltet und (wie bei Dovecot) eine Cipherlist vorgegeben, sodass die bestmögliche Verschlüsselung zwischen Client und Server genutzt wird. Im ersten Teilabschnitt werden die “smtp”-spezifischen TLS-Einstellungen festgelegt – d.h. die Einstellungen, die Postfix als sendenden Kommunikationspartner (Mail-Client) betreffen.&amp;lt;/p&amp;gt;&lt;br /&gt;
*&amp;lt;code&amp;gt;smtp_tls_security_level&amp;lt;/code&amp;gt;: Standard-TLS-Policy, wenn sie in der Datenbank für die Empfängerdomain nicht anders spezifiziert wurde: “dane” kontrolliert zunächst, ob für den Empfängerserver ein TLSA-Eintrag (DANE) im DNS vorliegt. Wenn das der Fall ist, wird eine verschlüsselte Verbindung erzwungen und das vorgezeigte Serverzertifikat mittels TLSA-Eintrag verifiziert. Sollte kein TLSA-Eintrag verfügbar sein, fällt Postfix in die Policy “may” zurück und verschlüsselt nur, wenn der andere Server das unterstützt. Zertifikate werden dabei nicht validiert. Sollten vorhandene TLSA-Einträge ungültig sein, wird stattdessen die “encrypt” Policy genutzt, welche zwar zwingend verschlüsselt, aber Zertifikate ebenfalls nicht validiert. Mehr zu den TLS-Policies folgt später.&lt;br /&gt;
*&amp;lt;code&amp;gt;smtp_dns_support_level&amp;lt;/code&amp;gt;: DNSSEC-gesicherte DNS-Lookups aktiveren und nutzen, falls möglich&lt;br /&gt;
*&amp;lt;code&amp;gt;smtpd_tls_policy_maps&amp;lt;/code&amp;gt;: Verweist auf die SQL-Queries, mit denen Empfängerdomain-spezifische TLS-Einstellungen geladen werden&lt;br /&gt;
*&amp;lt;code&amp;gt;smtp_tls_protocols&amp;lt;/code&amp;gt;: Veraltete SSL/TLS-Protokolle werden deaktiviert&lt;br /&gt;
&amp;lt;p&amp;gt;Nun zum zweiten TLS-Block: Dieser gilt für eingehende Verbindungen. Sowohl für andere Server, als auch Mailclients. Wieder werden SSL v2 und 3 deaktiviert und eine starke Cipherlist ausgewählt. Eingehende Verbindungen können verschlüsselt sein, müssen aber nicht.&amp;lt;/p&amp;gt;&amp;lt;p&amp;gt;'''LMTP-Service:'''&amp;lt;/p&amp;gt;&amp;lt;p&amp;gt;&amp;lt;code&amp;gt;virtual_transport&amp;lt;/code&amp;gt; übermittelt verarbeitete, eingehende E-Mails an den LMTP-Service von Dovecot, der sich dann um die Einordnung der Mail in die passende Mailbox kümmert.&amp;lt;/p&amp;gt;&amp;lt;p&amp;gt;'''Spamfilter und DKIM-Signaturen via Rspamd:'''&amp;lt;/p&amp;gt;&amp;lt;p&amp;gt;Dieser Abschnitt definiert den Rspam-Daemon als Milter für ein- und ausgehende E-Mails. Eingehende E-Mails werden durch Rspamd auf ihre Seriosität geprüft - ausgehende werden mit einem DKIM-Schlüssel signiert.&amp;lt;/p&amp;gt;&amp;lt;p&amp;gt;'''Server Restrictions:'''&amp;lt;/p&amp;gt;&amp;lt;p&amp;gt;Die Blöcke unter “Server restrictions” sind besonders wichtig für die Sicherheit des Mailservers. Falsch eingestellt erlauben sie den unberechtigten Versand von E-Mails (Stichwort “Open Relay”). Der Mailserver wird dann als Spam-Schleuder missbraucht und landet sehr schnell auf einer Blacklist. Damit das nicht passiert, sollten die Restrictions (Beschränkungen) sorgfältig eingestellt und mit einem passenden Open Relay Detektor überprüft sein.&amp;lt;/p&amp;gt;&amp;lt;p&amp;gt;Die Restrictions werden in Leserichtung nacheinander abgearbeitet. Am Ende jeder Verarbeitung steht immer ein “permit” oder “reject”. Für das bessere Verständnis ein Beispiel:&amp;lt;/p&amp;gt;&amp;lt;pre&amp;gt;&amp;lt;code&amp;gt;smtpd_relay_restrictions =      reject_non_fqdn_recipient&lt;br /&gt;
                                reject_unknown_recipient_domain&lt;br /&gt;
                                permit_mynetworks&lt;br /&gt;
                                reject_unauth_destination&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;/pre&amp;gt;&amp;lt;p&amp;gt;&amp;lt;code&amp;gt;smtpd_relay_restrictions&amp;lt;/code&amp;gt; bestimmt die Bedingungen, unter der Postfix als Mail-Relay (“Vermittlungsstelle”) arbeitet. Unser Postfix soll nur in drei Fällen auf eingehende E-Mails reagieren:&amp;lt;/p&amp;gt;&lt;br /&gt;
*Wenn ein Mailclient eine E-Mail via Postfix ins Internet schicken will&lt;br /&gt;
*Wenn ein fremder Mailserver eine E-Mail an unseren Postfix schickt&lt;br /&gt;
*Wenn vom Mailserver selbst aus eine Mail verschickt werden soll&lt;br /&gt;
&amp;lt;p&amp;gt;Um den ersten Fall wird sich in der &amp;lt;code&amp;gt;master.cf&amp;lt;/code&amp;gt; Datei gekümmert. Dort werden die Relay Restrictions im Submission-Bereich so überschrieben, dass Mailclients nicht am freien Versenden gehindert werden. Aktuell interessieren daher nur die letzten beiden Anfrage-Typen. Die erste Zeile der Restriction lautet &amp;lt;code&amp;gt;reject_non_fqdn_recipien&amp;lt;/code&amp;gt;. Sollte die Empfängeradresse keine vollwertige E-Mail Adresse sein, wird die Anfrage an Postfix direkt mit einem &amp;lt;code&amp;gt;reject&amp;lt;/code&amp;gt;abgewiesen. Alle anderen Checks finden dann nicht mehr statt. Das führt dazu, dass Postfix eine Weiterverarbeitung nur akzeptiert, wenn die zu verarbeitende E-Mail einen gültigen Empfänger hat. Ähnliches gilt für &amp;lt;code&amp;gt;reject_unknown_recipient_domain&amp;lt;/code&amp;gt;: Wenn die Empfängerdomain keinen gültigen MX- oder A-Eintrag im DNS hat (und der Zielserver damit nicht feststeht), wird die E-Mail abgelehnt.&amp;lt;/p&amp;gt;&amp;lt;p&amp;gt;Die darauf folgende Zeile enthält die “Restriction” &amp;lt;code&amp;gt;permit_mynetwork&amp;lt;/code&amp;gt;. Wenn der Anfragesteller lokal ist (bzw. seine IP in &amp;lt;code&amp;gt;mynetworks&amp;lt;/code&amp;gt; vermerkt ist), wird er mit einem &amp;lt;code&amp;gt;permit&amp;lt;/code&amp;gt; durchgewunken und die E-Mail wird weiter verarbeitet. Weitere Checks finden dann nicht statt. Sollte er nicht in mynetworks vermerkt sein, wird der letzte Check durchgeführt: &amp;lt;code&amp;gt;reject_unauth_destination&amp;lt;/code&amp;gt; kann nur bestanden werden, wenn die zu verarbeitende E-Mail an eine Empfängeradresse dieses Mailsystems geht. Sollte bis zum Ende der restriction-Definition noch kein &amp;lt;code&amp;gt;permit&amp;lt;/code&amp;gt; oder &amp;lt;code&amp;gt;reject&amp;lt;/code&amp;gt; ausgelöst worden sein, wird automatisch ein &amp;lt;code&amp;gt;permit&amp;lt;/code&amp;gt; ausgelöst und die jeweilige Aktion erlaubt.&amp;lt;/p&amp;gt;&amp;lt;p&amp;gt;Alle anderen Restriction-Definitionen funktionieren ähnlich: Die Kriterien werden nacheinander überprüft. Beginnt ein Kriterium mit einem &amp;lt;code&amp;gt;reject&amp;lt;/code&amp;gt;, wird bei Zutreffen ein &amp;lt;code&amp;gt;reject&amp;lt;/code&amp;gt; ausgelöst, beginnt es mit einem &amp;lt;code&amp;gt;permit&amp;lt;/code&amp;gt;, wird ein &amp;lt;code&amp;gt;permit&amp;lt;/code&amp;gt;ausgelöst. In beiden Fällen werden die nachfolgenden Kriterien nicht mehr überprüft.&amp;lt;/p&amp;gt;&lt;br /&gt;
*&amp;lt;code&amp;gt;smtpd_relay_restrictions&amp;lt;/code&amp;gt;: Kriterien, die überprüft werden, wenn Anfragen am Postfix-Server eintreffen (Von fremden Mailservern oder vom eigenen Server aus, z.B. via sendmail)&lt;br /&gt;
*&amp;lt;code&amp;gt;smtpd_recipient_restrictions&amp;lt;/code&amp;gt;: Kriterien, die zusätzlich zu den relay_restrictions geprüft werden. Nur bei bestehen der Checks wird eine E-Mail auf dem lokalen System angenommen und an die Empfänger-Mailbox geschickt. An dieser Stelle wird über eine SQL-Abfrage nachgefragt, ob ein bestimmter Empfänger E-Mails empfangen können soll (=&amp;amp;gt; Siehe Option in der Datenbank, Accounts nur zum Versenden freizuschalten).&lt;br /&gt;
*&amp;lt;code&amp;gt;smtpd_client-restrictions&amp;lt;/code&amp;gt;: Kriterien, auf die hin andere Server überprüft werden, wenn Kontakt zum Postfix-Server hergestellt wird. (Müssen gültigen Hostnamen und Reverse-DNS-Eintrag haben)&lt;br /&gt;
*&amp;lt;code&amp;gt;smtpd_helo_restrictions&amp;lt;/code&amp;gt;: Fremde Server müssen zu Beginn ihren gültigen Hostnamen nennen.&lt;br /&gt;
*&amp;lt;code&amp;gt;smtpd_data_restrictions&amp;lt;/code&amp;gt;: Ungeduldige Server sind oft Spammer.&lt;br /&gt;
&amp;lt;p&amp;gt;'''MySQL-Abfragen:'''&amp;lt;/p&amp;gt;&amp;lt;p&amp;gt;Hier sind die Pfade zu den übrigen SQL-Dateien angegeben, die Postfix benötigt, um Daten aus der Datenbank abfragen zu können.&amp;lt;/p&amp;gt;&lt;br /&gt;
=== &amp;lt;code&amp;gt;/etc/postfix/master.cf&amp;lt;/code&amp;gt; ===&lt;br /&gt;
&amp;lt;pre&amp;gt;&amp;lt;code&amp;gt;# ==========================================================================&lt;br /&gt;
# service type  private unpriv  chroot  wakeup  maxproc command + args&lt;br /&gt;
#               (yes)   (yes)   (no)    (never) (100)&lt;br /&gt;
# ==========================================================================&lt;br /&gt;
###&lt;br /&gt;
### SMTP-Serverbindungen aus dem Internet&lt;br /&gt;
### Authentifizuerung hier nicht erlaubt (Anmeldung nur via smtps/submission!)&lt;br /&gt;
smtp      inet  n       -       y       -       1       smtpd     &lt;br /&gt;
    -o smtpd_sasl_auth_enable=no&lt;br /&gt;
###&lt;br /&gt;
### SMTPS Service (Submission mit implizitem TLS - ohne STARTTLS) - Port 465&lt;br /&gt;
### Für Mailclients gelten andere Regeln, als für andere Mailserver (siehe smtpd_ in main.cf)&lt;br /&gt;
###&lt;br /&gt;
smtps     inet  n       -       y       -       -       smtpd&lt;br /&gt;
    -o syslog_name=postfix/smtps&lt;br /&gt;
    -o smtpd_tls_wrappermode=yes&lt;br /&gt;
    -o smtpd_tls_security_level=encrypt&lt;br /&gt;
    -o smtpd_sasl_auth_enable=yes&lt;br /&gt;
    -o smtpd_sasl_type=dovecot&lt;br /&gt;
    -o smtpd_sasl_path=private/auth&lt;br /&gt;
    -o smtpd_sasl_security_options=noanonymous&lt;br /&gt;
    -o smtpd_client_restrictions=$mua_client_restrictions&lt;br /&gt;
    -o smtpd_sender_restrictions=$mua_sender_restrictions&lt;br /&gt;
    -o smtpd_relay_restrictions=$mua_relay_restrictions&lt;br /&gt;
    -o milter_macro_daemon_name=ORIGINATING&lt;br /&gt;
    -o smtpd_sender_login_maps=proxy:mysql:/etc/postfix/sql/sender-login-maps.cf&lt;br /&gt;
    -o smtpd_helo_required=no&lt;br /&gt;
    -o smtpd_helo_restrictions=&lt;br /&gt;
    -o cleanup_service_name=submission-header-cleanup&lt;br /&gt;
###&lt;br /&gt;
### Submission-Zugang für Clients (mit STARTTLS - für Rückwärtskompatibilität) - Port 587&lt;br /&gt;
###&lt;br /&gt;
submission inet n       -       y       -       -       smtpd&lt;br /&gt;
    -o syslog_name=postfix/submission&lt;br /&gt;
    -o smtpd_tls_security_level=encrypt&lt;br /&gt;
    -o smtpd_sasl_auth_enable=yes&lt;br /&gt;
    -o smtpd_sasl_type=dovecot&lt;br /&gt;
    -o smtpd_sasl_path=private/auth&lt;br /&gt;
    -o smtpd_sasl_security_options=noanonymous&lt;br /&gt;
    -o smtpd_client_restrictions=$mua_client_restrictions&lt;br /&gt;
    -o smtpd_sender_restrictions=$mua_sender_restrictions&lt;br /&gt;
    -o smtpd_relay_restrictions=$mua_relay_restrictions&lt;br /&gt;
    -o milter_macro_daemon_name=ORIGINATING&lt;br /&gt;
    -o smtpd_sender_login_maps=proxy:mysql:/etc/postfix/sql/sender-login-maps.cf&lt;br /&gt;
    -o smtpd_helo_required=no&lt;br /&gt;
    -o smtpd_helo_restrictions=&lt;br /&gt;
    -o cleanup_service_name=submission-header-cleanup&lt;br /&gt;
###&lt;br /&gt;
### Weitere wichtige Dienste für den Serverbetrieb&lt;br /&gt;
###&lt;br /&gt;
pickup    unix  n       -       y       60      1       pickup&lt;br /&gt;
cleanup   unix  n       -       y       -       0       cleanup&lt;br /&gt;
qmgr      unix  n       -       n       300     1       qmgr&lt;br /&gt;
tlsmgr    unix  -       -       y       1000?   1       tlsmgr&lt;br /&gt;
rewrite   unix  -       -       y       -       -       trivial-rewrite&lt;br /&gt;
bounce    unix  -       -       y       -       0       bounce&lt;br /&gt;
defer     unix  -       -       y       -       0       bounce&lt;br /&gt;
trace     unix  -       -       y       -       0       bounce&lt;br /&gt;
verify    unix  -       -       y       -       1       verify&lt;br /&gt;
flush     unix  n       -       y       1000?   0       flush&lt;br /&gt;
proxymap  unix  -       -       n       -       -       proxymap&lt;br /&gt;
proxywrite unix -       -       n       -       1       proxymap&lt;br /&gt;
smtp      unix  -       -       y       -       -       smtp&lt;br /&gt;
relay     unix  -       -       y       -       -       smtp&lt;br /&gt;
showq     unix  n       -       y       -       -       showq&lt;br /&gt;
error     unix  -       -       y       -       -       error&lt;br /&gt;
retry     unix  -       -       y       -       -       error&lt;br /&gt;
discard   unix  -       -       y       -       -       discard&lt;br /&gt;
local     unix  -       n       n       -       -       local&lt;br /&gt;
virtual   unix  -       n       n       -       -       virtual&lt;br /&gt;
lmtp      unix  -       -       y       -       -       lmtp&lt;br /&gt;
anvil     unix  -       -       y       -       1       anvil&lt;br /&gt;
scache    unix  -       -       y       -       1       scache&lt;br /&gt;
###&lt;br /&gt;
### Cleanup-Service um MUA header zu entfernen&lt;br /&gt;
###&lt;br /&gt;
submission-header-cleanup unix n - n    -       0       cleanup&lt;br /&gt;
    -o header_checks=regexp:/etc/postfix/submission_header_cleanup&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;/pre&amp;gt;&amp;lt;p&amp;gt;Die &amp;lt;code&amp;gt;/etc/postfix/master.cf&amp;lt;/code&amp;gt; Datei will ich euch nur im Groben erklären. Wichtig zu wissen ist, dass hier die Definition und Konfiguration der verschiedenen Postfix-Dienste wie z.B. smtpd (eingehende SMTP-Verbindungen) und smtp (ausgehende SMTP-Verbindungen) passiert. Gut zu erkennen ist, dass über ein &amp;lt;code&amp;gt;-o&amp;lt;/code&amp;gt; weitere Parameter an einen Dienst übergeben werden. So beispielsweise beim &amp;lt;code&amp;gt;smtps&amp;lt;/code&amp;gt;-Dienst, der auf Port 465 für die SMTP-Kommunikation mit den Mailclients bereitsteht: Die hier angegebenen Einstellungen z.B. zu &amp;lt;code&amp;gt;smtpd_relay_restrictions&amp;lt;/code&amp;gt; überschreiben die Einstellungen in der main.cf – allerdings nur für diesen einen spezifischen Dienst! Ein gutes Beispiel ist die Einstellung &amp;lt;code&amp;gt;smtpd_tls_security_level=encrypt&amp;lt;/code&amp;gt;, die im Submission-Block steht. In der &amp;lt;code&amp;gt;main.cf&amp;lt;/code&amp;gt; hatten wir hier “may” definiert, um keine Server auszuschließen, die TLS nicht beherrschen. Da smtpd-Einstellungen aber sowohl für andere Server als auch für Mailclient gelten, wäre damit auch zu den Mailclients gesagt: “Ihr könnt verschlüsselte Verbindungen herstellen – müsst aber nicht”. Das wollen wir selbstverständlich nicht! Mailclients sollen eine verschlüsselte Verbindung herstellen müssen! Deshalb wird die smtpd-Einstellung speziell für den &amp;lt;code&amp;gt;smtps&amp;lt;/code&amp;gt;-Dienst mithilfe der &amp;lt;code&amp;gt;-o&amp;lt;/code&amp;gt; Option überschrieben und auf “encrypt” gesetzt.&amp;lt;/p&amp;gt;&amp;lt;p&amp;gt;Der &amp;lt;code&amp;gt;smtps&amp;lt;/code&amp;gt; Service am Anfang der Datei ist der SMTP-Dienst, zu dem sich Mailclients später verbinden sollen. Eine Verbindung ist hier nur über direktes TLS (nicht StartTLS!) möglich. Für Clients, die sich zu Port 587 verbinden wollen, steht weiterhin der &amp;lt;code&amp;gt;submission&amp;lt;/code&amp;gt; Service darunter bereit (auch wenn er in vielen Fällen nicht mehr notwendig sein sollte).&amp;lt;/p&amp;gt;&amp;lt;p&amp;gt;Für besseren Datenschutz wird der “Received”-Header (+ weitere Datenschutz-relevante Header) bei eingehenden E-Mails entfernt, wenn sie über den &amp;lt;code&amp;gt;smtps&amp;lt;/code&amp;gt;-Port eintreffen. Die meisten E-Mail-Clients senden ihren Namen und die Version mit. Zusätzlich vermerkt Postfix bei eingehenden E-Mails, von welcher IP-Adresse die E-Mail stammt. Auf diese Informationen können wir verzichten, deshalb werden sie mithilfe eines kleinen zusätzlichen Dienstes &amp;lt;code&amp;gt;submission-header-cleanup&amp;lt;/code&amp;gt; (am Ende der Konfiguration) aus der E-Mail gelöscht. Im &amp;lt;code&amp;gt;smtps&amp;lt;/code&amp;gt;- und Submission-Bereich wird via &amp;lt;code&amp;gt;cleanup_service_name&amp;lt;/code&amp;gt; festgelegt, dass bei eingehenden Mails auf diesen Services der Filter anzuwenden ist. Die Filterregeln befinden sich in der Datei &amp;lt;code&amp;gt;/etc/postfix/submission_header_cleanup&amp;lt;/code&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
=== Header Cleanup Regeln ===&lt;br /&gt;
&amp;lt;p&amp;gt;Unter &amp;lt;code&amp;gt;/etc/postfix/submission_header_cleanup&amp;lt;/code&amp;gt; wird eine Datei mit folgendem Inhalt angelegt:&amp;lt;/p&amp;gt;&amp;lt;pre&amp;gt;&amp;lt;code&amp;gt;### Entfernt Datenschutz-relevante Header aus E-Mails von MTUAs&lt;br /&gt;
&lt;br /&gt;
/^Received:/            IGNORE&lt;br /&gt;
/^X-Originating-IP:/    IGNORE&lt;br /&gt;
/^X-Mailer:/            IGNORE&lt;br /&gt;
/^User-Agent:/          IGNORE&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;/pre&amp;gt;&lt;br /&gt;
=== SQL-Konfiguration ===&lt;br /&gt;
&amp;lt;p&amp;gt;Neben der Haupt-Konfiguration main.cf und der Service-Konfiguration master.cf werden noch ein paar Konfigurationsdateien innerhalb des Unterverzeichnisses &amp;lt;code&amp;gt;sql/&amp;lt;/code&amp;gt; angelegt, die die SQL-Queries für die Datenabfragen an die Datenbank enthalten:&amp;lt;/p&amp;gt;&amp;lt;pre&amp;gt;&amp;lt;code&amp;gt;mkdir /etc/postfix/sql &amp;amp;&amp;amp; cd $_&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;/pre&amp;gt;&amp;lt;p&amp;gt;Erstellt dann die folgenden Konfigurationsdateien mit dem zugehörigen Inhalt:&amp;lt;/p&amp;gt;&amp;lt;p&amp;gt;&amp;lt;code&amp;gt;accounts.cf&amp;lt;/code&amp;gt;&amp;lt;/p&amp;gt;&amp;lt;pre&amp;gt;&amp;lt;code&amp;gt;user = vmail&lt;br /&gt;
password = vmaildbpass&lt;br /&gt;
hosts = unix:/run/mysqld/mysqld.sock&lt;br /&gt;
dbname = vmail&lt;br /&gt;
query = select 1 as found from accounts where username = '%u' and domain = '%d' and enabled = true LIMIT 1;&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;/pre&amp;gt;&amp;lt;p&amp;gt;&amp;lt;code&amp;gt;aliases.cf&amp;lt;/code&amp;gt;&amp;lt;/p&amp;gt;&amp;lt;pre&amp;gt;&amp;lt;code&amp;gt;user = vmail&lt;br /&gt;
password = vmaildbpass&lt;br /&gt;
hosts = unix:/run/mysqld/mysqld.sock&lt;br /&gt;
dbname = vmail&lt;br /&gt;
query = SELECT DISTINCT concat(destination_username, '@', destination_domain) AS destinations FROM aliases&lt;br /&gt;
        WHERE (source_username = '%u' OR source_username IS NULL) AND source_domain = '%d'&lt;br /&gt;
        AND enabled = true&lt;br /&gt;
        AND NOT EXISTS (SELECT id FROM accounts WHERE username = '%u' and domain = '%d');&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;/pre&amp;gt;&amp;lt;p&amp;gt;&amp;lt;code&amp;gt;domains.cf&amp;lt;/code&amp;gt;&amp;lt;/p&amp;gt;&amp;lt;pre&amp;gt;&amp;lt;code&amp;gt;user = vmail&lt;br /&gt;
password = vmaildbpass&lt;br /&gt;
hosts = unix:/run/mysqld/mysqld.sock&lt;br /&gt;
dbname = vmail&lt;br /&gt;
query = SELECT domain FROM domains WHERE domain='%s';&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;/pre&amp;gt;&amp;lt;p&amp;gt;&amp;lt;code&amp;gt;recipient-access.cf&amp;lt;/code&amp;gt;&amp;lt;/p&amp;gt;&amp;lt;pre&amp;gt;&amp;lt;code&amp;gt;user = vmail&lt;br /&gt;
password = vmaildbpass&lt;br /&gt;
hosts = unix:/run/mysqld/mysqld.sock&lt;br /&gt;
dbname = vmail&lt;br /&gt;
query = select if(sendonly = true, 'REJECT', 'OK') AS access from accounts where username = '%u' and domain = '%d' and enabled = true LIMIT 1;&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;/pre&amp;gt;&amp;lt;p&amp;gt;&amp;lt;code&amp;gt;sender-login-maps.cf&amp;lt;/code&amp;gt;&amp;lt;/p&amp;gt;&amp;lt;pre&amp;gt;&amp;lt;code&amp;gt;user = vmail&lt;br /&gt;
password = vmaildbpass&lt;br /&gt;
hosts = unix:/run/mysqld/mysqld.sock&lt;br /&gt;
dbname = vmail&lt;br /&gt;
query = select concat(username, '@', domain) as 'owns' from accounts where username = '%u' AND domain = '%d' and enabled = true union select &lt;br /&gt;
        concat(destination_username, '@', destination_domain) AS 'owns' from aliases &lt;br /&gt;
        where source_username = '%u' and source_domain = '%d' and enabled = true;&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;/pre&amp;gt;&amp;lt;p&amp;gt;&amp;lt;code&amp;gt;tls-policy.cf&amp;lt;/code&amp;gt;&amp;lt;/p&amp;gt;&amp;lt;pre&amp;gt;&amp;lt;code&amp;gt;user = vmail&lt;br /&gt;
password = vmaildbpass&lt;br /&gt;
hosts = unix:/run/mysqld/mysqld.sock&lt;br /&gt;
dbname = vmail&lt;br /&gt;
query = SELECT policy, params FROM tlspolicies WHERE domain = '%s';&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;/pre&amp;gt;&amp;lt;p&amp;gt;'''Vergesst nicht, &amp;lt;code&amp;gt;vmaildbpass&amp;lt;/code&amp;gt; in jeder der Dateien durch euer eigenes Passwort zu ersetzen!'''&amp;lt;/p&amp;gt;&amp;lt;p&amp;gt;Alle SQL-Konfgurationsdateien in &amp;lt;code&amp;gt;/etc/postfix/sql&amp;lt;/code&amp;gt; werden vor dem Zugriff durch unberechtigte User geschützt:&amp;lt;/p&amp;gt;&amp;lt;pre&amp;gt;&amp;lt;code&amp;gt;chown -R root:postfix /etc/postfix/sql&lt;br /&gt;
chmod g+x /etc/postfix/sql&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;/pre&amp;gt;&lt;br /&gt;
=== Weitere Postfix-Konfigurationsdateien ===&lt;br /&gt;
&amp;lt;p&amp;gt;Außerdem gibt es noch eine weitere Datei &amp;lt;code&amp;gt;/etc/postfix/without_ptr&amp;lt;/code&amp;gt;, die zunächst leer bleiben kann:&amp;lt;/p&amp;gt;&amp;lt;pre&amp;gt;&amp;lt;code&amp;gt;touch /etc/postfix/without_ptr&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;/pre&amp;gt;&amp;lt;p&amp;gt;Die Datei kann später einmal Einträge wie den folgenden beinhalten:&amp;lt;/p&amp;gt;&amp;lt;pre&amp;gt;&amp;lt;code&amp;gt;[2001:db8::beef] OK&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;/pre&amp;gt;&amp;lt;p&amp;gt;Der Server mit der IP &amp;lt;code&amp;gt;2001:db8::beef&amp;lt;/code&amp;gt; muss dann keinen gültigen PTR-Record (Reverse DNS) mehr besitzen und wird trotzdem akzeptiert. Die &amp;lt;code&amp;gt;without_ptr&amp;lt;/code&amp;gt;-Datei muss dann nach jeder Änderung in eine Datenbankdatei umgewandelt und Postfix neu geladen werden:&amp;lt;/p&amp;gt;&amp;lt;pre&amp;gt;&amp;lt;code&amp;gt;postmap /etc/postfix/without_ptr&lt;br /&gt;
systemctl reload postfix&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;/pre&amp;gt;&amp;lt;p&amp;gt;Im Moment reicht es aber aus, einfach nur eine leere Datenbankdatei zu generieren:&amp;lt;/p&amp;gt;&amp;lt;pre&amp;gt;&amp;lt;code&amp;gt;postmap /etc/postfix/without_ptr&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;/pre&amp;gt;&amp;lt;p&amp;gt;Zum Schluss wird einmal&amp;lt;/p&amp;gt;&amp;lt;pre&amp;gt;&amp;lt;code&amp;gt;newaliases&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;/pre&amp;gt;&amp;lt;p&amp;gt;ausgeführt, um die Alias-Datei &amp;lt;code&amp;gt;/etc/aliases.db&amp;lt;/code&amp;gt; zu generieren, die Postfix standardmäßig erwartet.&amp;lt;/p&amp;gt;&lt;br /&gt;
== Rspamd ==&lt;br /&gt;
&amp;lt;p&amp;gt;Da die Rspamd-Pakete für Debian nicht besonders aktuell sind und&amp;lt;/p&amp;gt;[https://rspamd.com/downloads.html#debian-standard-repos-notes offiziell davon abgeraten wird]&amp;lt;p&amp;gt;, diese zu nutzen, nutzen wir an dieser Stelle das Debian-Repository des Rspamd-Projekts:&amp;lt;/p&amp;gt;&amp;lt;pre&amp;gt;&amp;lt;code&amp;gt;apt install -y lsb-release wget&lt;br /&gt;
wget -O- https://rspamd.com/apt-stable/gpg.key | apt-key add -&lt;br /&gt;
echo &amp;quot;deb http://rspamd.com/apt-stable/ $(lsb_release -c -s) main&amp;quot; &amp;amp;gt; /etc/apt/sources.list.d/rspamd.list&lt;br /&gt;
echo &amp;quot;deb-src http://rspamd.com/apt-stable/ $(lsb_release -c -s) main&amp;quot; &amp;amp;gt;&amp;amp;gt; /etc/apt/sources.list.d/rspamd.list&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;/pre&amp;gt;&amp;lt;p&amp;gt;Paketquellen aktualisieren und Rspamd installieren&amp;lt;/p&amp;gt;&amp;lt;pre&amp;gt;&amp;lt;code&amp;gt;apt update&lt;br /&gt;
apt install rspamd&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;/pre&amp;gt;&amp;lt;p&amp;gt;Rspamd stoppen:&amp;lt;/p&amp;gt;&amp;lt;pre&amp;gt;&amp;lt;code&amp;gt;systemctl stop rspamd&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;/pre&amp;gt;&amp;lt;figure&amp;gt;&amp;lt;figcaption&amp;gt;Rspamd Webinterface&amp;lt;/figcaption&amp;gt;&amp;lt;/figure&amp;gt;&lt;br /&gt;
=== Grundkonfiguration ===&lt;br /&gt;
&amp;lt;p&amp;gt;Die Konfiguration von Rspamd wird im Verzeichnis &amp;lt;code&amp;gt;/etc/rspamd/local.d/&amp;lt;/code&amp;gt; abgelegt. Die folgenden Konfigurationsdateien werden darin erstellt:&amp;lt;/p&amp;gt;&amp;lt;p&amp;gt;&amp;lt;code&amp;gt;/etc/rspamd/local.d/worker-controller.inc&amp;lt;/code&amp;gt;: Einstellung des Worker controllers: Passwort für den Zugriff via Weboberfläche, z.B.:&amp;lt;/p&amp;gt;&amp;lt;pre&amp;gt;&amp;lt;code&amp;gt;password = &amp;quot;$2$qecacwgrz13owkag4gqcy5y7yeqh7yh4$y6i6gn5q3538tzsn19ojchuudoauw3rzdj1z74h5us4gd3jj5e8y&amp;quot;;&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;/pre&amp;gt;&amp;lt;p&amp;gt;Der Passworthash (&amp;lt;code&amp;gt;$2$qecacwg...&amp;lt;/code&amp;gt;) wird via&amp;lt;/p&amp;gt;&amp;lt;pre&amp;gt;&amp;lt;code&amp;gt;rspamadm pw&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;/pre&amp;gt;&amp;lt;p&amp;gt;generiert und in die Datei eingefügt. Vergesst nicht das abschließende &amp;lt;code&amp;gt;&amp;quot;;&amp;lt;/code&amp;gt;!&amp;lt;/p&amp;gt;&amp;lt;p&amp;gt;&amp;lt;code&amp;gt;/etc/rspamd/local.d/logging.inc&amp;lt;/code&amp;gt;: Error logging&amp;lt;/p&amp;gt;&amp;lt;pre&amp;gt;&amp;lt;code&amp;gt;type = &amp;quot;syslog&amp;quot;;&lt;br /&gt;
level = &amp;quot;warning&amp;quot;;&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;/pre&amp;gt;&amp;lt;p&amp;gt;Milter Headers &amp;lt;code&amp;gt;/etc/rspamd/local.d/milter_headers.conf&amp;lt;/code&amp;gt;&amp;lt;/p&amp;gt;&amp;lt;pre&amp;gt;&amp;lt;code&amp;gt;use = [&amp;quot;x-spamd-bar&amp;quot;, &amp;quot;x-spam-level&amp;quot;, &amp;quot;authentication-results&amp;quot;];&lt;br /&gt;
authenticated_headers = [&amp;quot;authentication-results&amp;quot;];&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;/pre&amp;gt;&amp;lt;p&amp;gt;Redis für den Bayes’schen Filter nutzen: &amp;lt;code&amp;gt;/etc/rspamd/local.d/classifier-bayes.conf&amp;lt;/code&amp;gt;&amp;lt;/p&amp;gt;&amp;lt;pre&amp;gt;&amp;lt;code&amp;gt;backend = &amp;quot;redis&amp;quot;;&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;/pre&amp;gt;&amp;lt;p&amp;gt;…und in &amp;lt;code&amp;gt;/etc/rspamd/local.d/redis.conf&amp;lt;/code&amp;gt;:&amp;lt;/p&amp;gt;&amp;lt;pre&amp;gt;&amp;lt;code&amp;gt;servers = &amp;quot;127.0.0.1&amp;quot;;&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;/pre&amp;gt;&amp;lt;p&amp;gt;Für den Bayes’schen Filter (Textanalyse) wird “Auto-Learning” aktiviert:&amp;lt;/p&amp;gt;&amp;lt;p&amp;gt;&amp;lt;code&amp;gt;/etc/rspamd/override.d/classifier-bayes.conf&amp;lt;/code&amp;gt;:&amp;lt;/p&amp;gt;&amp;lt;pre&amp;gt;&amp;lt;code&amp;gt;autolearn = true;&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;/pre&amp;gt;&amp;lt;p&amp;gt;Wird eine E-Mail bereits beim Empfang abgelehnt, weil sie ausgrund der Metadaten offensichtlich von einem Spammer kommt, nutzt Rspamd die Gelegenheit und lernt, dass der Text in dieser E-Mail als Spam einzustufen ist. So wird die Erkennungsrate mit jeder Spammail besser. (&amp;lt;/p&amp;gt;[https://rspamd.com/doc/configuration/statistic.html https://rspamd.com/doc/configuration/statistic.html]&amp;lt;p&amp;gt;)&amp;lt;/p&amp;gt;&lt;br /&gt;
=== Manuell gepflegte Black-/Whitelists ===&lt;br /&gt;
&amp;lt;p&amp;gt;Über das Multimap-Modul kann das Verhalten von Rspamd für bestimmte E-Mail-Merkmale personalisiert gesteuert werden. Merkmale können zum Beispiel die Absender-IP-Adresse oder die Absendermailadresse sein. Für beide registrieren wir in &amp;lt;code&amp;gt;/etc/rspamd/local.d/multimap.conf&amp;lt;/code&amp;gt; jeweils eine Black- und eine Whitelist:&amp;lt;/p&amp;gt;&amp;lt;pre&amp;gt;&amp;lt;code&amp;gt;WHITELIST_IP {&lt;br /&gt;
    type = &amp;quot;ip&amp;quot;;&lt;br /&gt;
    map = &amp;quot;$CONFDIR/local.d/whitelist_ip.map&amp;quot;;&lt;br /&gt;
    description = &amp;quot;Local ip whitelist&amp;quot;;&lt;br /&gt;
    action = &amp;quot;accept&amp;quot;;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
WHITELIST_FROM {&lt;br /&gt;
        type = &amp;quot;from&amp;quot;;&lt;br /&gt;
        map = &amp;quot;$CONFDIR/local.d/whitelist_from.map&amp;quot;;&lt;br /&gt;
        description = &amp;quot;Local from whitelist&amp;quot;;&lt;br /&gt;
        action = &amp;quot;accept&amp;quot;;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
BLACKLIST_IP {&lt;br /&gt;
        type = &amp;quot;ip&amp;quot;;&lt;br /&gt;
        map = &amp;quot;$CONFDIR/local.d/blacklist_ip.map&amp;quot;;&lt;br /&gt;
        description = &amp;quot;Local ip blacklist&amp;quot;;&lt;br /&gt;
        action = &amp;quot;reject&amp;quot;;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
BLACKLIST_FROM {&lt;br /&gt;
        type = &amp;quot;from&amp;quot;;&lt;br /&gt;
        map = &amp;quot;$CONFDIR/local.d/blacklist_from.map&amp;quot;;&lt;br /&gt;
        description = &amp;quot;Local from blacklist&amp;quot;;&lt;br /&gt;
        action = &amp;quot;reject&amp;quot;;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;/pre&amp;gt;&amp;lt;p&amp;gt;Für alle vier Listen werden nun Listendateien erstellt:&amp;lt;/p&amp;gt;&amp;lt;pre&amp;gt;&amp;lt;code&amp;gt;cd /etc/rspamd/local.d&lt;br /&gt;
touch whitelist_ip.map&lt;br /&gt;
touch whitelist_from.map&lt;br /&gt;
touch blacklist_ip.map&lt;br /&gt;
touch blacklist_from.map&lt;br /&gt;
cd - &lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;/pre&amp;gt;&amp;lt;p&amp;gt;“IP”-Listen können IPv6- und IPv4-Adressen bzw. Adressbereiche enthalten - in jeder Zeile ein Eintrag. “From”-Listen enthalten vollständige Absendermailadressen. Die Listen können zunächst leer bleiben. Sie eignen sich gut, wenn man später einmal für einzelne Absender oder Server Ausnahmen einstellen möchte.&amp;lt;/p&amp;gt;&lt;br /&gt;
=== DKIM Signing ===&lt;br /&gt;
&amp;lt;p&amp;gt;Rspamd übernimmt auch das Signieren von ausgehenden E-Mails. Damit signiert werden kann, muss zunächst ein Signing Key generiert werden. Der Parameter &amp;lt;code&amp;gt;-s 2020&amp;lt;/code&amp;gt; gibt den sogenannten Selektor an - einen Namen für den Key (hier das Erstellungsjahr).&amp;lt;/p&amp;gt;&amp;lt;pre&amp;gt;&amp;lt;code&amp;gt;mkdir /var/lib/rspamd/dkim/&lt;br /&gt;
rspamadm dkim_keygen -b 2048 -s 2020 -k /var/lib/rspamd/dkim/2020.key &amp;amp;gt; /var/lib/rspamd/dkim/2020.txt&lt;br /&gt;
chown -R _rspamd:_rspamd /var/lib/rspamd/dkim&lt;br /&gt;
chmod 440 /var/lib/rspamd/dkim/*&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;/pre&amp;gt;&amp;lt;p&amp;gt;Zum Signing Key (&amp;lt;code&amp;gt;/var/lib/rspamd/dkim/2020.key&amp;lt;/code&amp;gt;) gehört ein dazu passender Public Key, welcher in Form eines vorbereiteten DNS-Records in der Datei &amp;lt;code&amp;gt;/var/lib/rspamd/dkim/2020.txt&amp;lt;/code&amp;gt; liegt.&amp;lt;/p&amp;gt;&amp;lt;p&amp;gt;DKIM Record ausgeben lassen:&amp;lt;/p&amp;gt;&amp;lt;pre&amp;gt;&amp;lt;code&amp;gt;cat /var/lib/rspamd/dkim/2020.txt&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;/pre&amp;gt;&amp;lt;p&amp;gt;Die Ausgabe sieht z.B. so aus:&amp;lt;/p&amp;gt;&amp;lt;pre&amp;gt;&amp;lt;code&amp;gt;2020._domainkey IN TXT ( &amp;quot;v=DKIM1; k=rsa; &amp;quot;&lt;br /&gt;
    &amp;quot;p=MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA2/al5HqXUpe+HUazCr6t9lv2VOZLR369PPB4t+dgljZQvgUsIKoYzfS/w9NagS32xZYxi1dtlDWuRfTU/ahHO2MYzE0zHE4lMfwb6VkNCG+pM6bAkCwc5cFvyRygwxAPEiHAtmtU5b0i9LY25Z/ZWgyBxEWZ0Wf+hLjYHvnvMqewPsduUqKVjDOdUqeBb1VAu3WFErOAGVUYfKqFX&amp;quot;&lt;br /&gt;
    &amp;quot;+yfz36Alb7/OMAort8A5Vo5t5k0vxTHzkYYg5KB6tLS8jngrNucGjyNL5+k0ijPs3yT7WpTGL3U3SEa8cX8WvOO1fIpWQz4yyZJJ1Mm62+FskSc7BHjdiMHE64Id/UBDDVjxwIDAQAB&amp;quot;&lt;br /&gt;
) ;&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;/pre&amp;gt;&amp;lt;p&amp;gt;Der Werte-Abschnitt des Records (beginnend mit &amp;lt;code&amp;gt;v=DKIM1&amp;lt;/code&amp;gt; bis zum Ende der Zeichenkolonne - hier &amp;lt;code&amp;gt;AQAB&amp;lt;/code&amp;gt;) muss in einen neuen DNS-Record gepflanzt werden. Dabei werden Zeilenumbrüche und Anführungsstriche entfernt. Je nach DNS-Hoster muss ein neuer Eintrag geringfügig anders formatiert werden. Ich habe den Schritt im Screenshot beispielhaft für den Hoster&amp;lt;/p&amp;gt;[https://www.core-networks.de/ Core-Networks.de]&amp;lt;p&amp;gt;mit dem Selector “2020” und meiner Beispieldomain “mysystems.tld” durchgeführt:&amp;lt;/p&amp;gt;&amp;lt;figure&amp;gt;&amp;lt;figcaption&amp;gt;core-networks.de Screenshot mit DKIM Record&amp;lt;/figcaption&amp;gt;&amp;lt;/figure&amp;gt;&amp;lt;p&amp;gt;Wichtig: Der Selektor “2020” wird im DNS-Record zusammen mit &amp;lt;code&amp;gt;._domainkey&amp;lt;/code&amp;gt; als Name verwendet! Der DKIM-Record muss '''für jede verwendete Domain (domain2.tld, domain2.tld) im jeweiligen Zonefile erstellt werden!'''&amp;lt;/p&amp;gt;&amp;lt;div class=&amp;quot;tip&amp;quot;&amp;gt;Sollte der Record vom DNS-Hoster nicht akzeptiert werden, hilft es in einigen Fällen, die Schlüssellänge von 2048 Bit auf 1024 Bit zu reduzieren. Dazu das &amp;lt;code&amp;gt;rspamadm dkim_keygen&amp;lt;/code&amp;gt;Kommando nochmals mit &amp;lt;code&amp;gt;-b 1024&amp;lt;/code&amp;gt; statt mit &amp;lt;code&amp;gt;-b 2048&amp;lt;/code&amp;gt; ausführen.&amp;lt;/div&amp;gt;&amp;lt;p&amp;gt;Der erzeugte DKIM-Key und der verwendete Selektor werden in der Konfigurationsdatei &amp;lt;code&amp;gt;/etc/rspamd/local.d/dkim_signing.conf&amp;lt;/code&amp;gt; angegeben:&amp;lt;/p&amp;gt;&amp;lt;pre&amp;gt;&amp;lt;code&amp;gt;path = &amp;quot;/var/lib/rspamd/dkim/$selector.key&amp;quot;;&lt;br /&gt;
selector = &amp;quot;2020&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
### Enable DKIM signing for alias sender addresses&lt;br /&gt;
allow_username_mismatch = true;&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;/pre&amp;gt;&amp;lt;p&amp;gt;Diese Konfiguration wird in die Datei &amp;lt;code&amp;gt;/etc/rspamd/local.d/arc.conf&amp;lt;/code&amp;gt; kopiert, sodass das&amp;lt;/p&amp;gt;[https://rspamd.com/doc/modules/arc.html ARC-Modul]&amp;lt;p&amp;gt;korrekt arbeiten kann. Es greift auf dieselben Einstellungen zurück:&amp;lt;/p&amp;gt;&amp;lt;pre&amp;gt;&amp;lt;code&amp;gt;cp -R /etc/rspamd/local.d/dkim_signing.conf /etc/rspamd/local.d/arc.conf&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;/pre&amp;gt;&lt;br /&gt;
== Redis als Cache und Key-Value Store für Rspamd-Module ==&lt;br /&gt;
&amp;lt;p&amp;gt;Rspamd verwendet Redis als Cache. Die Installation ist trivial:&amp;lt;/p&amp;gt;&amp;lt;pre&amp;gt;&amp;lt;code&amp;gt;apt install redis-server&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;/pre&amp;gt;&amp;lt;p&amp;gt;In der Rspamd-Konfiguration wurde Redis bereits als Caching-Datenbank eingetragen.&amp;lt;/p&amp;gt;&lt;br /&gt;
== Rspamd starten ==&lt;br /&gt;
&amp;lt;p&amp;gt;Rspamd kann nun gestartet werden:&amp;lt;/p&amp;gt;&amp;lt;pre&amp;gt;&amp;lt;code&amp;gt;systemctl start rspamd&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;/pre&amp;gt;&lt;br /&gt;
== Nginx Proxy für Rspamd Weboberfläche ==&lt;br /&gt;
&amp;lt;p&amp;gt;Für den bequemen und sicheren Zugriff auf die Rspamd-Weboberfläche kann dieser ein Nginx HTTP-Proxy vorgeschaltet werden. Nginx kümmert sich dann um die Absicherung der Verbindung via HTTPS. Wer nur selten auf die Rspamd-Weboberfläche zugreift, kann auf diesen Schritt verzichten und stattdessen auch über einen SSH-Tunnel auf das Interface zugreifen (&amp;lt;/p&amp;gt;[https://thomas-leister.de/mailserver-debian-buster/#ssh-tunnel siehe unten]&amp;lt;p&amp;gt;).&amp;lt;/p&amp;gt;&amp;lt;p&amp;gt;Für den Rspamd-Webproxy wird in &amp;lt;code&amp;gt;/etc/nginx/sites-available/mail.mysystems.tld&amp;lt;/code&amp;gt; ein &amp;lt;code&amp;gt;location&amp;lt;/code&amp;gt; Block wie folgt hinzugefügt:&amp;lt;/p&amp;gt;&amp;lt;pre&amp;gt;&amp;lt;code&amp;gt;server {&lt;br /&gt;
        listen 80;&lt;br /&gt;
        listen [::]:80;&lt;br /&gt;
        listen 443 ssl http2;&lt;br /&gt;
        listen [::]:443 ssl http2;&lt;br /&gt;
&lt;br /&gt;
        server_name mail.mysystems.tld imap.mysystems.tld smtp.mysystems.tld;&lt;br /&gt;
&lt;br /&gt;
        ssl_certificate /etc/acme.sh/mail.mysystems.tld/fullchain.pem;&lt;br /&gt;
        ssl_certificate_key /etc/acme.sh/mail.mysystems.tld/privkey.pem;&lt;br /&gt;
&lt;br /&gt;
        add_header Strict-Transport-Security max-age=15768000;&lt;br /&gt;
&lt;br /&gt;
        location /rspamd/ {&lt;br /&gt;
                proxy_pass http://localhost:11334/;&lt;br /&gt;
                proxy_set_header Host $host;&lt;br /&gt;
                proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
        if ($ssl_protocol = &amp;quot;&amp;quot;) {&lt;br /&gt;
            return 301 https://$server_name$request_uri;&lt;br /&gt;
        }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;/pre&amp;gt;&amp;lt;p&amp;gt;Anzupassen:&amp;lt;/p&amp;gt;&lt;br /&gt;
*ssl_certificate: Pfad zu Zertifikat&lt;br /&gt;
*ssl_certificate_key: Pfad zu Zertifikat&lt;br /&gt;
*server_name&lt;br /&gt;
&amp;lt;p&amp;gt;Konfiguration testen und Nginx neu laden:&amp;lt;/p&amp;gt;&amp;lt;pre&amp;gt;&amp;lt;code&amp;gt;nginx -t&lt;br /&gt;
systemctl reload nginx&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;/pre&amp;gt;&lt;br /&gt;
== Weboberfläche aufrufen ==&lt;br /&gt;
&amp;lt;p&amp;gt;Unter&amp;lt;/p&amp;gt;[https://mail.mysystems.tld/rspamd/ https://mail.mysystems.tld/rspamd/]&amp;lt;p&amp;gt;ist die Rspamd-Weboberfläche nun erreichbar. Als Passwort wird das weiter oben erzeugte Passwort für die Weboberfläche verwendet.&amp;lt;/p&amp;gt;&lt;br /&gt;
== Via SSH-Tunnel mit der Weboberfläche verbinden (Alternative) ==&lt;br /&gt;
&amp;lt;p&amp;gt;Statt über Nginx kann man auch mithilfe eines SSH-Tunnels eine sichere Verbindung zur Rspamd-Weboberfläche aufbauen. Dazu benötigt man auf dem lokalen Rechner allerdings einen SSH-Client. Der SSH-Befehl&amp;lt;/p&amp;gt;&amp;lt;pre&amp;gt;&amp;lt;code&amp;gt;ssh -L 8080:localhost:11334 benutzer@mail.mysystems.tld -N&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;/pre&amp;gt;&amp;lt;p&amp;gt;verknüpft den Port des Webinterfaces (&amp;lt;code&amp;gt;11334&amp;lt;/code&amp;gt;) mit Port &amp;lt;code&amp;gt;8080&amp;lt;/code&amp;gt; des lokalen Systems. Im lokalen Webbrowser kann die Oberfläche nun unter http://localhost:8080 erreicht werden. Mit STRG+C wird die Verbindung wieder getrennt.&amp;lt;/p&amp;gt;&lt;br /&gt;
== Rspamd mit bestehenden Spam-E-Mails trainieren (optional) ==&lt;br /&gt;
&amp;lt;p&amp;gt;Wer einige Mails im Maildir-Format (jede E-Mail ist eine Datei) vorliegen hat, kann Rspamd mit über das rspamc-Werkzeug trainieren. Dabei ist es ist vorteilhaft, nicht nur Spammail-Beispiele zu trainieren, sondern auch Beispiele für erwünschte E-Mails. Im folgenden Beispiel wurde das Mailbox-Verzeichnis eines älteren Mailservers importiert:&amp;lt;/p&amp;gt;&amp;lt;p&amp;gt;E-Mails in einem Verzeichnis als '''Spam''' antrainieren:&amp;lt;/p&amp;gt;&amp;lt;pre&amp;gt;&amp;lt;code&amp;gt;find ./oldserver/var/vmail/mailboxes/*/*/mail/Spam/cur -type f -exec /usr/bin/rspamc learn_spam {} \;&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;/pre&amp;gt;&amp;lt;p&amp;gt;E-Mails in einem Verzeichnis als '''Ham''' (harmlos) antrainieren:&amp;lt;/p&amp;gt;&amp;lt;pre&amp;gt;&amp;lt;code&amp;gt;find ./oldserver/var/vmail/mailboxes/*/*/mail/cur -type f -exec /usr/bin/rspamc learn_ham {} \;&lt;br /&gt;
find ./oldserver/var/vmail/mailboxes/*/*/mail/Sent/cur -type f -exec /usr/bin/rspamc learn_ham {} \;&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;/pre&amp;gt;&amp;lt;p&amp;gt;Auf der Rspamd-Weboberfläche wird nach dem Training eine entsprechend höhere Anzahl an gelernten E-Mails angezeigt.&amp;lt;/p&amp;gt;&lt;br /&gt;
== Autoconfig für Mozilla Thunderbird (Optional) ==&lt;br /&gt;
&amp;lt;p&amp;gt;Mozilla Thunderbird (und andere Mailclients) versuchen bei der Einrichtung eines neuen Mailkontos automatisch, die korrekten Adressen und Einstellungen für IMAP- und SMTP-Server zu&amp;lt;/p&amp;gt;[https://developer.mozilla.org/en-US/docs/Mozilla/Thunderbird/Autoconfiguration ermitteln]&amp;lt;p&amp;gt;. Die Autokonfiguration gibt uns die Möglichkeit, unter einer festgelegten Adresse &amp;lt;code&amp;gt;https://autoconfig.&amp;amp;lt;maildomain&amp;amp;gt;.tld/mail/config-v1.1.xml&amp;lt;/code&amp;gt;Informationen zum Mailserver zu hinterlegen, sodass der Benutzer bei der Verknüpfung seines Mailkontos nichts anderes als seine Mailadresse und das Passwort anzugeben braucht. Alle weiteren Informationen wie z.B. Art der Verschlüsselung oder Port bezieht Thunderbird aus der XML-Datei.&amp;lt;/p&amp;gt;&amp;lt;p&amp;gt;Da die Servereinstellungen in diesem Setup für alle Domains identisch sind, soll die XML-Datei unter &amp;lt;code&amp;gt;https://autoconfig.mysystems.tld/mail/config-v1.1.xml&amp;lt;/code&amp;gt; zentral auf dem Mailserver verfügbar gemacht werden. Sollten neben der “mysystems.tld” Domain noch die Domains “domain1.tld” und “domain2.tld” für E-Mail mitgenutzt werden, kann mittels HTTP-Proxies auf den Zielservern dieser Domains auf die zentrale Adresse weitergeleitet werden. Doch zunächst soll es nur um den mail.mysystems.tld Mailserver gehen …&amp;lt;/p&amp;gt;&lt;br /&gt;
=== DNS-Record anlegen ===&lt;br /&gt;
&amp;lt;p&amp;gt;Für die neue autoconfig.mysystems.tld Subdomain wird ein passender CNAME-Record im DNS angelegt, welcher auf den Mailserver zeigt:&amp;lt;/p&amp;gt;&amp;lt;pre&amp;gt;&amp;lt;code&amp;gt;autoconfig.mysystems.tld. 86400 IN CNAME mail.mysystems.tld.&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;/pre&amp;gt;&lt;br /&gt;
=== Autoconfig auf dem Mailserver einrichten ===&lt;br /&gt;
&amp;lt;p&amp;gt;Um die Datei auf dem Server anzubieten, wird ein weiterer Virtual Host für den Nginx-Webserver angelegt:&amp;lt;/p&amp;gt;&amp;lt;p&amp;gt;&amp;lt;code&amp;gt;/etc/nginx/sites-available/autoconfig.mysystems.tld&amp;lt;/code&amp;gt;&amp;lt;/p&amp;gt;&amp;lt;pre&amp;gt;&amp;lt;code&amp;gt;server {&lt;br /&gt;
        listen 80;&lt;br /&gt;
        listen [::]:80;&lt;br /&gt;
#        listen 443 ssl http2;&lt;br /&gt;
#        listen [::]:443 ssl http2;&lt;br /&gt;
&lt;br /&gt;
        server_name autoconfig.mysystems.tld;&lt;br /&gt;
&lt;br /&gt;
#        ssl_certificate /etc/acme.sh/autoconfig.mysystems.tld/fullchain.pem;&lt;br /&gt;
#        ssl_certificate_key /etc/acme.sh/autoconfig.mysystems.tld/privkey.pem;&lt;br /&gt;
&lt;br /&gt;
#        add_header Strict-Transport-Security max-age=15768000;&lt;br /&gt;
&lt;br /&gt;
#        if ($ssl_protocol = &amp;quot;&amp;quot;) {&lt;br /&gt;
#            return 301 https://$server_name$request_uri;&lt;br /&gt;
#        }&lt;br /&gt;
&lt;br /&gt;
        root /var/www/mysystems.tld/autoconfig.mysystems.tld;&lt;br /&gt;
&lt;br /&gt;
        location / {&lt;br /&gt;
                add_header Content-Type text/xml;&lt;br /&gt;
                charset utf-8;&lt;br /&gt;
        }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;/pre&amp;gt;&amp;lt;p&amp;gt;''Wie auch bei der ersten Nginx-Konfiguration sind hier zunächst ein paar Zeilen auskommentiert, weil noch keine passenden TLS-Zertifikate vorhanden sind.''&amp;lt;/p&amp;gt;&amp;lt;p&amp;gt;Konfiguration aktivieren, Nginx Config prüfen und neu laden:&amp;lt;/p&amp;gt;&amp;lt;pre&amp;gt;&amp;lt;code&amp;gt;ln -s /etc/nginx/sites-available/autoconfig.mysystems.tld /etc/nginx/sites-enabled/autoconfig.mysystems.tld&lt;br /&gt;
nginx -t&lt;br /&gt;
systemctl reload nginx&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;/pre&amp;gt;&amp;lt;p&amp;gt;Für den neuen vHost wird ein Webroot directory angelegt:&amp;lt;/p&amp;gt;&amp;lt;pre&amp;gt;&amp;lt;code&amp;gt;mkdir -p /var/www/mysystems.tld/autoconfig.mysystems.tld/mail/&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;/pre&amp;gt;&amp;lt;p&amp;gt;und die XML-Konfiguration darin abgelegt:&amp;lt;/p&amp;gt;&amp;lt;p&amp;gt;&amp;lt;code&amp;gt;config-v1.1.xml&amp;lt;/code&amp;gt;&amp;lt;/p&amp;gt;&amp;lt;pre&amp;gt;&amp;lt;code&amp;gt;&amp;amp;lt;?xml version=&amp;quot;1.0&amp;quot; encoding=&amp;quot;UTF-8&amp;quot;?&amp;amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;amp;lt;clientConfig version=&amp;quot;1.1&amp;quot;&amp;amp;gt;&lt;br /&gt;
  &amp;amp;lt;emailProvider id=&amp;quot;mysystems.tld&amp;quot;&amp;amp;gt;&lt;br /&gt;
    &amp;amp;lt;domain&amp;amp;gt;mysystems.tld&amp;amp;lt;/domain&amp;amp;gt;&lt;br /&gt;
    &amp;amp;lt;displayName&amp;amp;gt;mysystems.tld Mail&amp;amp;lt;/displayName&amp;amp;gt;&lt;br /&gt;
    &amp;amp;lt;displayShortName&amp;amp;gt;mysystems.tld&amp;amp;lt;/displayShortName&amp;amp;gt;&lt;br /&gt;
    &amp;amp;lt;incomingServer type=&amp;quot;imap&amp;quot;&amp;amp;gt;&lt;br /&gt;
      &amp;amp;lt;hostname&amp;amp;gt;imap.mysystems.tld&amp;amp;lt;/hostname&amp;amp;gt;&lt;br /&gt;
      &amp;amp;lt;port&amp;amp;gt;993&amp;amp;lt;/port&amp;amp;gt;&lt;br /&gt;
      &amp;amp;lt;socketType&amp;amp;gt;SSL&amp;amp;lt;/socketType&amp;amp;gt;&lt;br /&gt;
      &amp;amp;lt;authentication&amp;amp;gt;password-cleartext&amp;amp;lt;/authentication&amp;amp;gt;&lt;br /&gt;
      &amp;amp;lt;username&amp;amp;gt;%EMAILADDRESS%&amp;amp;lt;/username&amp;amp;gt;&lt;br /&gt;
    &amp;amp;lt;/incomingServer&amp;amp;gt;&lt;br /&gt;
    &amp;amp;lt;outgoingServer type=&amp;quot;smtp&amp;quot;&amp;amp;gt;&lt;br /&gt;
      &amp;amp;lt;hostname&amp;amp;gt;smtp.mysystems.tld&amp;amp;lt;/hostname&amp;amp;gt;&lt;br /&gt;
      &amp;amp;lt;port&amp;amp;gt;465&amp;amp;lt;/port&amp;amp;gt;&lt;br /&gt;
      &amp;amp;lt;socketType&amp;amp;gt;SSL&amp;amp;lt;/socketType&amp;amp;gt;&lt;br /&gt;
      &amp;amp;lt;authentication&amp;amp;gt;password-cleartext&amp;amp;lt;/authentication&amp;amp;gt;&lt;br /&gt;
      &amp;amp;lt;username&amp;amp;gt;%EMAILADDRESS%&amp;amp;lt;/username&amp;amp;gt;&lt;br /&gt;
    &amp;amp;lt;/outgoingServer&amp;amp;gt;&lt;br /&gt;
  &amp;amp;lt;/emailProvider&amp;amp;gt;&lt;br /&gt;
&amp;amp;lt;/clientConfig&amp;amp;gt;&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;/pre&amp;gt;&amp;lt;p&amp;gt;Nun wird für autoconfig.mysystems.tld noch ein DNS-Record angelegt:&amp;lt;/p&amp;gt;&amp;lt;pre&amp;gt;&amp;lt;code&amp;gt;autoconfig.mysystems.tld IN CNAME mail.mysystems.tld.&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;/pre&amp;gt;&amp;lt;p&amp;gt;TLS-Zertifikat beantragen und installieren:&amp;lt;/p&amp;gt;&amp;lt;pre&amp;gt;&amp;lt;code&amp;gt;acme.sh --issue --server letsencrypt --nginx -d autoconfig.mysystems.tld&lt;br /&gt;
mkdir -p /etc/acme.sh/autoconfig.mysystems.tld&lt;br /&gt;
acme.sh --install-cert -d autoconfig.mysystems.tld \&lt;br /&gt;
    --key-file /etc/acme.sh/autoconfig.mysystems.tld/privkey.pem  \&lt;br /&gt;
    --fullchain-file /etc/acme.sh/autoconfig.mysystems.tld/fullchain.pem \&lt;br /&gt;
    --reloadcmd &amp;quot;systemctl reload nginx&amp;quot;&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;/pre&amp;gt;&amp;lt;p&amp;gt;'''Die auskommentierten Zeilen können nun entfernt und Nginx neu geladen werden:'''&amp;lt;/p&amp;gt;&amp;lt;pre&amp;gt;&amp;lt;code&amp;gt;systemctl reload nginx&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;/pre&amp;gt;&lt;br /&gt;
=== Optional: Autoconfig Proxy für weitere Maildomains einrichten ===&lt;br /&gt;
&amp;lt;p&amp;gt;Auf den (Web-)Servern, auf welche die weiteren Domains “domain1.tld” und “domain2.tld” verweisen, wird im Nginx jeweils ein vHost für “autoconfig.domain1.tld” bzw. “autoconfig.domain2.tld” angelegt:&amp;lt;/p&amp;gt;&amp;lt;p&amp;gt;&amp;lt;code&amp;gt;/etc/nginx/sites-available/autoconfig.domain1.tld&amp;lt;/code&amp;gt;&amp;lt;/p&amp;gt;&amp;lt;pre&amp;gt;&amp;lt;code&amp;gt;server {&lt;br /&gt;
        listen 80;&lt;br /&gt;
        listen [::]:80;&lt;br /&gt;
#       listen 443 ssl http2;&lt;br /&gt;
#       listen [::]:443 ssl http2;&lt;br /&gt;
&lt;br /&gt;
        server_name autoconfig.domain1.tld;&lt;br /&gt;
&lt;br /&gt;
#       ssl_certificate /etc/acme.sh/autoconfig.mysystems.tld/fullchain.pem;&lt;br /&gt;
#       ssl_certificate_key /etc/acme.sh/autoconfig.mysystems.tld/key.pem;&lt;br /&gt;
&lt;br /&gt;
#       add_header Strict-Transport-Security max-age=15768000;&lt;br /&gt;
&lt;br /&gt;
#       if ($ssl_protocol = &amp;quot;&amp;quot;) {&lt;br /&gt;
#           return 301 https://$server_name$request_uri;&lt;br /&gt;
#       }      &lt;br /&gt;
&lt;br /&gt;
        location / {&lt;br /&gt;
                proxy_pass https://[fd80::1]:443;&lt;br /&gt;
                proxy_set_header HOST $host;&lt;br /&gt;
        }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;/pre&amp;gt;&amp;lt;p&amp;gt;Anzupassen:&amp;lt;/p&amp;gt;&lt;br /&gt;
*&amp;lt;code&amp;gt;server_name&amp;lt;/code&amp;gt;&lt;br /&gt;
*IP-Adresse des Mailsystems &amp;lt;code&amp;gt;mail.mysytems.tld&amp;lt;/code&amp;gt; bei &amp;lt;code&amp;gt;proxy_pass&amp;lt;/code&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;''Die &amp;lt;code&amp;gt;proxy_pass&amp;lt;/code&amp;gt; Anweisung nutzt die IPv6-Adresse &amp;lt;code&amp;gt;fd::80&amp;lt;/code&amp;gt; statt des Hostnamens unseres Mailservers, da Nginx direkt nach dem Booten noch keinen DNS-Resolver zur Namensauflösung verfügbar hat.''&amp;lt;/p&amp;gt;&amp;lt;p&amp;gt;Ein DNS-Eintrag für die neue Subdomain darf nicht fehlen:&amp;lt;/p&amp;gt;&amp;lt;pre&amp;gt;&amp;lt;code&amp;gt;autoconfig.domain1.tld IN CNAME domain1.tld.&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;/pre&amp;gt;&amp;lt;p&amp;gt;Auch dieser VirtualHost sollte mit einem passenden TLS-Zertifikat abgesichert werden:&amp;lt;/p&amp;gt;&amp;lt;pre&amp;gt;&amp;lt;code&amp;gt;acme.sh --issue --server letsencrypt --nginx -d autoconfig.domain1.tld&lt;br /&gt;
mkdir -p /etc/acme.sh/autoconfig.domain1.tld&lt;br /&gt;
acme.sh --install-cert -d autoconfig.domain1.tld \&lt;br /&gt;
    --key-file /etc/acme.sh/autoconfig.domain1.tld/privkey.pem  \&lt;br /&gt;
    --fullchain-file /etc/acme.sh/autoconfig.domain1.tld/fullchain.pem \&lt;br /&gt;
    --reloadcmd &amp;quot;systemctl reload nginx&amp;quot;&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;/pre&amp;gt;&amp;lt;p&amp;gt;Die auskommentierten Zeilen in der Nginx Konfiguration können nun auskommentiert werden.&amp;lt;/p&amp;gt;&amp;lt;p&amp;gt;Aktivieren der Konfiguration und Neuladen des Webservers:&amp;lt;/p&amp;gt;&amp;lt;pre&amp;gt;&amp;lt;code&amp;gt;ln -s /etc/nginx/sites-available/autoconfig.domain1.tld /etc/nginx/sites-enabled/autoconfig.domain1.tld&lt;br /&gt;
nginx -t&lt;br /&gt;
systemctl reload nginx&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;/pre&amp;gt;&amp;lt;p&amp;gt;Ein Aufruf von&amp;lt;/p&amp;gt;[https://autoconfig.domain1.tld/mail/config-v1.1.xml https://autoconfig.domain1.tld/mail/config-v1.1.xml]&amp;lt;p&amp;gt;sollte nun dieselbe XML-Datei anzeigen, die bereits auf dem Mailserver unter &amp;lt;code&amp;gt;autoconfig.mysystems.tld&amp;lt;/code&amp;gt; hinterlegt wurde. Diese XML-Datei muss nun analog zu &amp;lt;code&amp;gt;mysystems.tld&amp;lt;/code&amp;gt; um &amp;lt;code&amp;gt;domain1.tld&amp;lt;/code&amp;gt; erweitert werden, z.B. so:&amp;lt;/p&amp;gt;&amp;lt;pre&amp;gt;&amp;lt;code&amp;gt;&amp;amp;lt;?xml version=&amp;quot;1.0&amp;quot; encoding=&amp;quot;UTF-8&amp;quot;?&amp;amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;amp;lt;clientConfig version=&amp;quot;1.1&amp;quot;&amp;amp;gt;&lt;br /&gt;
  &amp;amp;lt;emailProvider id=&amp;quot;mysystems.tld&amp;quot;&amp;amp;gt;&lt;br /&gt;
    &amp;amp;lt;domain&amp;amp;gt;mysystems.tld&amp;amp;lt;/domain&amp;amp;gt;&lt;br /&gt;
    &amp;amp;lt;displayName&amp;amp;gt;mysystems.tld Mail&amp;amp;lt;/displayName&amp;amp;gt;&lt;br /&gt;
    &amp;amp;lt;displayShortName&amp;amp;gt;mysystems.tld&amp;amp;lt;/displayShortName&amp;amp;gt;&lt;br /&gt;
    &amp;amp;lt;incomingServer type=&amp;quot;imap&amp;quot;&amp;amp;gt;&lt;br /&gt;
      &amp;amp;lt;hostname&amp;amp;gt;imap.mysystems.tld&amp;amp;lt;/hostname&amp;amp;gt;&lt;br /&gt;
      &amp;amp;lt;port&amp;amp;gt;993&amp;amp;lt;/port&amp;amp;gt;&lt;br /&gt;
      &amp;amp;lt;socketType&amp;amp;gt;SSL&amp;amp;lt;/socketType&amp;amp;gt;&lt;br /&gt;
      &amp;amp;lt;authentication&amp;amp;gt;password-cleartext&amp;amp;lt;/authentication&amp;amp;gt;&lt;br /&gt;
      &amp;amp;lt;username&amp;amp;gt;%EMAILADDRESS%&amp;amp;lt;/username&amp;amp;gt;&lt;br /&gt;
    &amp;amp;lt;/incomingServer&amp;amp;gt;&lt;br /&gt;
    &amp;amp;lt;outgoingServer type=&amp;quot;smtp&amp;quot;&amp;amp;gt;&lt;br /&gt;
      &amp;amp;lt;hostname&amp;amp;gt;smtp.mysystems.tld&amp;amp;lt;/hostname&amp;amp;gt;&lt;br /&gt;
      &amp;amp;lt;port&amp;amp;gt;465&amp;amp;lt;/port&amp;amp;gt;&lt;br /&gt;
      &amp;amp;lt;socketType&amp;amp;gt;SSL&amp;amp;lt;/socketType&amp;amp;gt;&lt;br /&gt;
      &amp;amp;lt;authentication&amp;amp;gt;password-cleartext&amp;amp;lt;/authentication&amp;amp;gt;&lt;br /&gt;
      &amp;amp;lt;username&amp;amp;gt;%EMAILADDRESS%&amp;amp;lt;/username&amp;amp;gt;&lt;br /&gt;
    &amp;amp;lt;/outgoingServer&amp;amp;gt;&lt;br /&gt;
  &amp;amp;lt;/emailProvider&amp;amp;gt;&lt;br /&gt;
&lt;br /&gt;
  &amp;amp;lt;emailProvider id=&amp;quot;domain1.tld&amp;quot;&amp;amp;gt;&lt;br /&gt;
    &amp;amp;lt;domain&amp;amp;gt;domain1.tld&amp;amp;lt;/domain&amp;amp;gt;&lt;br /&gt;
    &amp;amp;lt;displayName&amp;amp;gt;domain1.tld Mail&amp;amp;lt;/displayName&amp;amp;gt;&lt;br /&gt;
    &amp;amp;lt;displayShortName&amp;amp;gt;domain1.tld&amp;amp;lt;/displayShortName&amp;amp;gt;&lt;br /&gt;
    &amp;amp;lt;incomingServer type=&amp;quot;imap&amp;quot;&amp;amp;gt;&lt;br /&gt;
      &amp;amp;lt;hostname&amp;amp;gt;imap.mysystems.tld&amp;amp;lt;/hostname&amp;amp;gt;&lt;br /&gt;
      &amp;amp;lt;port&amp;amp;gt;993&amp;amp;lt;/port&amp;amp;gt;&lt;br /&gt;
      &amp;amp;lt;socketType&amp;amp;gt;SSL&amp;amp;lt;/socketType&amp;amp;gt;&lt;br /&gt;
      &amp;amp;lt;authentication&amp;amp;gt;password-cleartext&amp;amp;lt;/authentication&amp;amp;gt;&lt;br /&gt;
      &amp;amp;lt;username&amp;amp;gt;%EMAILADDRESS%&amp;amp;lt;/username&amp;amp;gt;&lt;br /&gt;
    &amp;amp;lt;/incomingServer&amp;amp;gt;&lt;br /&gt;
    &amp;amp;lt;outgoingServer type=&amp;quot;smtp&amp;quot;&amp;amp;gt;&lt;br /&gt;
      &amp;amp;lt;hostname&amp;amp;gt;smtp.mysystems.tld&amp;amp;lt;/hostname&amp;amp;gt;&lt;br /&gt;
      &amp;amp;lt;port&amp;amp;gt;465&amp;amp;lt;/port&amp;amp;gt;&lt;br /&gt;
      &amp;amp;lt;socketType&amp;amp;gt;SSL&amp;amp;lt;/socketType&amp;amp;gt;&lt;br /&gt;
      &amp;amp;lt;authentication&amp;amp;gt;password-cleartext&amp;amp;lt;/authentication&amp;amp;gt;&lt;br /&gt;
      &amp;amp;lt;username&amp;amp;gt;%EMAILADDRESS%&amp;amp;lt;/username&amp;amp;gt;&lt;br /&gt;
    &amp;amp;lt;/outgoingServer&amp;amp;gt;&lt;br /&gt;
  &amp;amp;lt;/emailProvider&amp;amp;gt;&lt;br /&gt;
&amp;amp;lt;/clientConfig&amp;amp;gt;&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;/pre&amp;gt;&amp;lt;p&amp;gt;Für “domain2.tld” ist genauso vorzugehen.&amp;lt;/p&amp;gt;&lt;br /&gt;
== Domains, Accounts, Aliase und TLS-Policies in Datenbank definieren ==&lt;br /&gt;
&amp;lt;p&amp;gt;Bevor der Mailserver sinnvoll genutzt werden kann, müssen noch Domains und Benutzer im der MySQL-Datenbank registriert werden. Loggt euch wieder auf der MySQL-Kommandozeile ein:&amp;lt;/p&amp;gt;&amp;lt;pre&amp;gt;&amp;lt;code&amp;gt;mysql&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;/pre&amp;gt;&amp;lt;p&amp;gt;… und wechselt in die vmail-Datenbank:&amp;lt;/p&amp;gt;&amp;lt;pre&amp;gt;&amp;lt;code&amp;gt;use vmail;&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;/pre&amp;gt;&lt;br /&gt;
=== Neue Domain anlegen ===&lt;br /&gt;
&amp;lt;p&amp;gt;Damit ein neuer Benutzeraccount oder ein neuer Alias angelegt werden kann, muss die zu nutzende Domain zuvor im Mailsystem bekannt gemacht werden. Postfix verarbeitet nur E-Mails an Domains, die in der “domains”-Tabelle eingetragen sind:&amp;lt;/p&amp;gt;&amp;lt;pre&amp;gt;&amp;lt;code&amp;gt;insert into domains (domain) values ('mysystems.tld');&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;/pre&amp;gt;&lt;br /&gt;
=== Neuen E-Mail-Account anlegen ===&lt;br /&gt;
&amp;lt;p&amp;gt;Wenn die Benutzerdomain in der Domain-Tabelle angelegt ist, kann ein neuer Benutzeraccount für den Mailserver erstellt werden. Bevor das passende SQL-Kommando eingegeben und abgeschickt wird, wird jedoch zu nächst ein Passwort-Hash des gewünschten Passworts für den Account erzeugt. Mit&amp;lt;/p&amp;gt;&amp;lt;pre&amp;gt;&amp;lt;code&amp;gt;doveadm pw -s SHA512-CRYPT&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;/pre&amp;gt;&amp;lt;p&amp;gt;'''(in der Bash Shell! - Nicht in der MySQL Shell!)''' kann ein solcher Hash erzeugt werden. Beispiel für einen ausgegebenen Hash:&amp;lt;/p&amp;gt;&amp;lt;pre&amp;gt;&amp;lt;code&amp;gt;{SHA512-CRYPT}$6$wHyJsS.doo39xoCu$KI1N4l.Vd0ZWYj5BYLI8AdK7ACwAZaM18gSy7Bko0dG2Hvli4.KfAmLk2ztFVP.R4T7oqiu7clKBehCTc4GGw0&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;/pre&amp;gt;&amp;lt;p&amp;gt;Dieser Hash ist für jedes Passwort einzigartig und ändert sich sogar bei jeder Generierung. Legt den Hash am besten gleich in eurer Zwischenablage oder einem Textdokument ab - ihr benötigt ihn gleich!&amp;lt;/p&amp;gt;&amp;lt;div class=&amp;quot;warning&amp;quot;&amp;gt;Verwendet auch an dieser Stelle möglichst nur die Zeichen 0-9, a-z und A-z. Sonderzeichen können Probleme verursachen. Wenn eure Passwörter einigermaßen lang sind, reicht das völlig aus. Sonderzeichen bringen dann ohnehin keinen nennenswerten Sicherheitsgewinn.&amp;lt;/div&amp;gt;&amp;lt;p&amp;gt;Das SQL-Kommando zum Erzeugen eines neuen Accounts lautet:&amp;lt;/p&amp;gt;&amp;lt;pre&amp;gt;&amp;lt;code&amp;gt;insert into accounts (username, domain, password, quota, enabled, sendonly) values ('user1', 'mysystems.tld', '{SHA512-CRYPT}$6$wHyJsS[...]', 2048, true, false);&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;/pre&amp;gt;&amp;lt;p&amp;gt;In das “Password”-Feld wird der Hash vollständig eingetragen (hier: gekürzt).&amp;lt;/p&amp;gt;&amp;lt;p&amp;gt;Legt am besten gleich den &amp;lt;code&amp;gt;postmaster@mysystems.tld&amp;lt;/code&amp;gt; Account an. Er sollte auf jedem Mailserver vorhanden sein, um den Administrator bei technischen Problemen mit dem Server erreichen zu können.&amp;lt;/p&amp;gt;&lt;br /&gt;
=== Neuen Alias anlegen ===&lt;br /&gt;
&amp;lt;pre&amp;gt;&amp;lt;code&amp;gt;insert into aliases (source_username, source_domain, destination_username, destination_domain, enabled) values ('alias', 'mysystems.tld', 'user1', 'mysystems.tld', true);&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;/pre&amp;gt;&amp;lt;p&amp;gt;… legt einen Alias für den Benutzer “&amp;lt;/p&amp;gt;[mailto:user1@mysystems.tld user1@mysystems.tld]&amp;lt;p&amp;gt;” an. E-Mails an “&amp;lt;/p&amp;gt;[mailto:alias@mysystems.tld alias@mysystems.tld]&amp;lt;p&amp;gt;” werden dann an die Mailbox dieses Users zugestellt.&amp;lt;/p&amp;gt;&amp;lt;p&amp;gt;Als Zieladressen können auch E-Mail-Konten auf fremden Servern angegeben werden. Postfix leitet diese E-Mails dann weiter. Dabei kann es allerdings zu Problemen mit SPF-Records kommen – schließlich schickt Postfix unter bestimmten Umständen E-Mails unter fremden Domains, für die er laut SPF-Record nicht zuständig ist. SRS (Sender Rewriting Scheme) ist eine Lösung für dieses Problem. Von Erweiterungen, die schwerwiegende Design-Fehler einer Technik wie SPF korrigieren, halte ich allerdings nicht besonders viel, sodass ich euch empfehle, den SPF-Record (wie oben) auf einem “?all” gestellt zu lassen und auf Weiterleitungen zu fremden Servern möglichst zu verzichten. Aliase von lokalen Adressen auf andere lokale Adressen sind kein Problem.&amp;lt;/p&amp;gt;&amp;lt;p&amp;gt;Wenn ein '''E-Mail-Verteiler''' eingerichtet werden soll, werden mehrere Datensätze mit derselben Quelladresse eingerichtet, also z.B. so:&amp;lt;/p&amp;gt;&amp;lt;pre&amp;gt;&amp;lt;code&amp;gt;team@domain.tld =&amp;amp;gt; user1@domain.tld&lt;br /&gt;
team@domain.tld =&amp;amp;gt; user2@domain.tld&lt;br /&gt;
team@domain.tld =&amp;amp;gt; user3@domain.tld&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;/pre&amp;gt;&amp;lt;p&amp;gt;Ein '''Catch-All''' hingegen kann erreicht werden, indem der &amp;lt;code&amp;gt;source_username&amp;lt;/code&amp;gt; auf &amp;lt;code&amp;gt;null&amp;lt;/code&amp;gt; gesetzt wird, z.B. so:&amp;lt;/p&amp;gt;&amp;lt;pre&amp;gt;&amp;lt;code&amp;gt;insert into aliases (source_username, source_domain, destination_username, destination_domain, enabled) values (null, 'domain1.tld', 'catchall', 'mysystems.tld', true);&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;/pre&amp;gt;&amp;lt;p&amp;gt;Ein Catch-All kann mit anderen Aliasen auf derselben Domain ko-existieren und “fängt” alle Benutzernamen auf der jeweiligen Domain auf, für die noch kein Alias gesetzt wurde. So kann man Mails zentral aufsammeln, welche an Mailboxen verschickt wurden, die auf dem Mailserver nicht existieren. Beachtet, dass dadurch das Spamaufkommen ggf. höher ist.&amp;lt;/p&amp;gt;&lt;br /&gt;
=== Neue TLS-Policy anlegen (optional) ===&lt;br /&gt;
&amp;lt;p&amp;gt;Mithilfe der TLS Policy-Tabelle kann festgelegt werden, mit welchen Sicherheitsfeatures mit den Mailservern einer bestimmten Domain kommuniziert werden soll. Wenn für die Domain “thomas-leister.de” beispielsweise “dane-only” in “policy” festgelegt wird, wird die Verbindung zu Mailservern dieser Domain nur noch gültig sein, wenn sie DANE-authentifiziert und verschlüsselt ist. Mögliche Policies sind:&amp;lt;/p&amp;gt;&lt;br /&gt;
*&amp;lt;code&amp;gt;none&amp;lt;/code&amp;gt;: Keine Verschlüsselung nutzen, auch wenn der andere Mailserver das unterstützt.&lt;br /&gt;
*&amp;lt;code&amp;gt;may&amp;lt;/code&amp;gt;: Verschlüsseln, wenn der andere Server dies unterstützt, aber keine Zertifikatsprüfung (self-signed Zertifikate werden akzeptiert).&lt;br /&gt;
*&amp;lt;code&amp;gt;encrypt&amp;lt;/code&amp;gt;: Zwingend Verschlüsseln, allerdings keine Zertifikatsprüfung (self-signed Zertifikate werden akzeptiert).&lt;br /&gt;
*&amp;lt;code&amp;gt;dane&amp;lt;/code&amp;gt;: Wenn gültige TLSA-Records gefunden werden, wird zwingend verschlüsselt und das Zertifikat mittels DANE verifiziert. Falls ungültige TLSA-Records gefunden werden, wird auf “encrypt” zurückgegriffen. Falls gar keine TLSA-Records gefunden werden, wird “may” genutzt.&lt;br /&gt;
*&amp;lt;code&amp;gt;dane-only&amp;lt;/code&amp;gt;: Nur verschlüsselte Verbindungen. Gültige TLSA-Records für den Hostnamen müssen existieren (DANE)&lt;br /&gt;
*&amp;lt;code&amp;gt;verify&amp;lt;/code&amp;gt;: Nur verschlüsselte Verbindungen + Prüfung der CA. Der Hostname aus dem MX DNS-Record muss im Zertifikat enthalten sein. (Basiert auf Vertrauen in korrekte DNS-Daten)&lt;br /&gt;
*&amp;lt;code&amp;gt;secure&amp;lt;/code&amp;gt;: Nur verschlüsselte Verbindungen + Prüfung der CA. Der andere Mailserver muss (standardmäßig) einen Hostnamen haben, der “.domain.tld” oder nur “domain.tld” entspricht. Dieser Hostname muss im Zertifikat enthalten sein. Auf das DNS wird nicht zurückgegriffen (Sicherheitsvorteil gegenüber “verify). Beispiel: Eine E-Mail an[mailto:user@web.de user@web.de]soll gesendet werden. Der MX-Mailserver von Web.de dürfte dann nur den Hostnamen “web.de” oder eine Subdomain davon als Hostnamen haben, z.B. mx.web.de. Eine Verbindung zu mx.web.net wäre nicht zulässig.&lt;br /&gt;
&amp;lt;p&amp;gt;Für Domains der großen Anbieter wie gmx.de, web.de und der Telekom kann man “secure” wählen. Bei Posteo und Mailbox.org sogar “dane-only”. Für alle Provider, die keine gültigen TLS-Zertifikate einsetzen, kann “encrypt” gewählt werden. Standardeinstellung für alle anderen Mailserver ist “dane” (siehe main.cf der Postfix Config).&amp;lt;/p&amp;gt;&amp;lt;p&amp;gt;Das Feld “params” wird mit zusätzlichen Infos gefüllt, wenn sie für einen Policy-Typ erforderlich sind, z.B. für einen “secure” Eintrag zu GMX:&amp;lt;/p&amp;gt;&amp;lt;pre&amp;gt;&amp;lt;code&amp;gt;insert into tlspolicies (domain, policy, params) values ('gmx.de', 'secure', 'match=.gmx.net');&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;/pre&amp;gt;&amp;lt;p&amp;gt;Standardmäßig überprüft Postfix bei “secure” – wie oben bereits erwähnt – ob die Empfängerdomain (gmx.de) im Zertifikat des Zielservers vorhanden ist. Bei GMX (und vielen anderen großen Anbietern) ist das allerdings nicht der Fall: Die Mailserver-Zertifikate von GMX sind nur für gmx.net + Subdomains gültig. Ließe man den Datenbank-Eintrag für GMX ohne weitere Einstellungen auf “secure” stehen, könnten an GMX keine Mails mehr übermittelt werden. Deshalb ist es wichtig, für GMX festzulegen, dass im Zertifikat nicht nach “gmx.de” sondern nach “gmx.net” gesucht werden soll. Das können wir mithilfe des Felds “params” und der “match=…” Zeichenkette tun. Wenn nach mehreren Domains gesucht werden soll, können auch mehrere angegeben werden, z.B. so: “match=.gmx.net:.gmx.ch”. Die zusätzlichen Angaben in “params” sind allerdings nicht für jeden Mailprovider notwendig. GMX ist eine Ausnahme – genauso wie z.B. Yahoo. Ob ihr in “params” einen “match”-String angeben müsst, könnt ihr z.B. über&amp;lt;/p&amp;gt;[https://de.ssl-tools.net/ https://de.ssl-tools.net/]&amp;lt;p&amp;gt;herausfinden. Wenn die 2-nd-Level-Domain des Mailservers von der Domain der Mailadressen abweicht, muss ein passender match-String angegeben werden.&amp;lt;/p&amp;gt;&amp;lt;p&amp;gt;Andere Einstellungen wie “dane-only” erfordern keine zusätzlichen Angaben in “params”:&amp;lt;/p&amp;gt;&amp;lt;pre&amp;gt;&amp;lt;code&amp;gt;insert into tlspolicies (domain, policy) values ('mailbox.org', 'dane-only');&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;/pre&amp;gt;&amp;lt;p&amp;gt;In diesem Fall wird mit den Mailservern von mailbox.org nur noch DANE-gesichert und verschlüsselt kommuniziert. Die MySQL-Kommandozeile kann mit einem &amp;lt;code&amp;gt;quit;&amp;lt;/code&amp;gt; wieder verlassen werden.&amp;lt;/p&amp;gt;&lt;br /&gt;
== Optional: Firewall konfigurieren ==&lt;br /&gt;
&amp;lt;p&amp;gt;Wer vor / auf dem Mailserver eine Firewall betreibt, die den Zugriff auf Ports beschränkt, sollte zuerst alle Mailserver-Ports freischalten:&amp;lt;/p&amp;gt;&amp;lt;pre&amp;gt;&amp;lt;code&amp;gt;IMAP:           143/tcp&lt;br /&gt;
IMAPS:          993/tcp&lt;br /&gt;
Submission:     587/tcp&lt;br /&gt;
SMTPS:          465/tcp&lt;br /&gt;
SMTP:            25/tcp&lt;br /&gt;
ManageSieve:   4190/tcp&lt;br /&gt;
Web HTTP:        80/tcp&lt;br /&gt;
Web HTTPS:      443/tcp&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;/pre&amp;gt;&amp;lt;p&amp;gt;'''Denkt unbedingt daran, auch eure IPv6-Ports zu öffnen!''' - Euer Mailsetup spricht IPv6! :-) Die Ports 143 und 587 können geschlossen bleiben, wenn keine StartTLS-basierenden Verbindung genutzt werden sollen (siehe Hinweis weiter unten).&amp;lt;/p&amp;gt;&lt;br /&gt;
== Start all the things! ==&lt;br /&gt;
&amp;lt;p&amp;gt;Euer neuer Mailserver ist jetzt fertig konfiguriert. Zeit für einen ersten Start!&amp;lt;/p&amp;gt;&amp;lt;pre&amp;gt;&amp;lt;code&amp;gt;systemctl start dovecot&lt;br /&gt;
systemctl start postfix&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;/pre&amp;gt;&amp;lt;div class=&amp;quot;warning&amp;quot;&amp;gt;&amp;lt;p&amp;gt;Wegen des Bugs&amp;lt;/p&amp;gt;[https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=877992 #877992]&amp;lt;p&amp;gt;startet Postfix nach einem Reboot nicht mehr. Abhilfe schafft folgendes Kommando:&amp;lt;/p&amp;gt;&amp;lt;pre&amp;gt;&amp;lt;code&amp;gt;systemctl enable postfix@-&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;/pre&amp;gt;&amp;lt;p&amp;gt;(beachte das Minuszeichen &amp;lt;code&amp;gt;-&amp;lt;/code&amp;gt; am Ende!)&amp;lt;/p&amp;gt;&amp;lt;/div&amp;gt;&amp;lt;p&amp;gt;Kontrolliert am besten gleich die Logfiles nach auffälligen Fehlern. Ich empfehle das “tail” Tool in einer separaten Terminal-Sitzung. Neue Log-Einträge erscheinen damit sofort auf dem Bildschirm:&amp;lt;/p&amp;gt;&amp;lt;pre&amp;gt;&amp;lt;code&amp;gt;tail -f /var/log/syslog&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;/pre&amp;gt;&amp;lt;p&amp;gt;bzw.&amp;lt;/p&amp;gt;&amp;lt;pre&amp;gt;&amp;lt;code&amp;gt;tail -f /var/log/mail.log&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;/pre&amp;gt;&amp;lt;p&amp;gt;Wenn ihr hier Fehler entdeckt, seht nach, ob ihr alle erforderlichen Änderungen an den Konfigurationsdateien durchgeführt habt (oder ob sich noch beispielhafte Hashes oder Beispieldomains darin befinden).&amp;lt;/p&amp;gt;&lt;br /&gt;
== Eine Verbindung zum Mailserver herstellen ==&lt;br /&gt;
&amp;lt;figure&amp;gt;&amp;lt;figcaption&amp;gt;Mailserver Logindaten für Thunderbird&amp;lt;/figcaption&amp;gt;&amp;lt;/figure&amp;gt;&amp;lt;p&amp;gt;Eine Verbindung könnt ihr über jeden IMAP-fähigen E-Mail-Client und den folgenden Verbindungsparametern herstellen:&amp;lt;/p&amp;gt;&lt;br /&gt;
*IMAP(S)&lt;br /&gt;
**Host: imap.mysystems.tld&lt;br /&gt;
**Port: 993&lt;br /&gt;
**Verschlüsselung: TLS&lt;br /&gt;
**(dieser Server gilt auch für domain2 und domain3, falls vorhanden!)&lt;br /&gt;
*SMTP(S)&lt;br /&gt;
**Host: smtp.mysystems.tld&lt;br /&gt;
**Port: 465&lt;br /&gt;
**Verschlüsselung: TLS&lt;br /&gt;
**(dieser Server gilt auch für domain2 und domain3, falls vorhanden!)&lt;br /&gt;
*Managesieve (optional, zur Konfiguration der benutzerspezifischen Sieve-Filterregeln)&lt;br /&gt;
**Host: imap.mysystems.tld&lt;br /&gt;
**Port: 4190&lt;br /&gt;
**Verschlüsselung: StartTLS&lt;br /&gt;
*Benutzername: Die '''vollständige''' E-Mail-Adresse, also @&amp;amp;lt;domain.tld&amp;amp;gt;&lt;br /&gt;
*Passwort: Sollte bekannt sein ;-)&lt;br /&gt;
&amp;lt;p&amp;gt;Sollten Verbindungen über die IMAPS (993) und SMTPS (465) Ports nicht möglich sein, kann auch auf die StartTLS-Ports zurückgegriffen werden:&amp;lt;/p&amp;gt;&lt;br /&gt;
*IMAP-Server:&lt;br /&gt;
**Host: mail.mysystems.tld&lt;br /&gt;
**Port: 143&lt;br /&gt;
**Verschlüsselung: StartTLS&lt;br /&gt;
*SMTP-Server:&lt;br /&gt;
**Host: mail.mysystems.tld&lt;br /&gt;
**Port: 587&lt;br /&gt;
**Verschlüsselung: StartTLS&lt;br /&gt;
&amp;lt;p&amp;gt;Die IETF (Internet Engineering Task Force) empfiehlt seit 2018 allerdings, auf StartTLS Verbindungen zu verzichten, und auf native TLS-Verbindungen zu setzen:&amp;lt;/p&amp;gt;[https://tools.ietf.org/html/rfc8314 https://tools.ietf.org/html/rfc8314]&amp;lt;div class=&amp;quot;tip&amp;quot;&amp;gt;Der erste Login kann ein paar Sekunden in Anspruch nehmen - habt etwas Gedult. Dovecot legt im Hintergrund die Verzeichnisstruktur für den neuen Benutzer an.&amp;lt;/div&amp;gt;&lt;br /&gt;
== Spamfilter testen ==&lt;br /&gt;
&amp;lt;p&amp;gt;Schickt einfach eine E-Mail mit dem Text&amp;lt;/p&amp;gt;&amp;lt;pre&amp;gt;&amp;lt;code&amp;gt;XJS*C4JDBQADN1.NSBN3*2IDNEN*GTUBE-STANDARD-ANTI-UBE-TEST-EMAIL*C.34X&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;/pre&amp;gt;&amp;lt;p&amp;gt;an einen Account eures neuen Mailservers. Die E-Mail sollte nicht ankommen und im Rspamd-Webinterface erscheint ein entsprechender rot markierter Eintrag in der History.&amp;lt;/p&amp;gt;&lt;br /&gt;
== Debugging ==&lt;br /&gt;
&amp;lt;p&amp;gt;Sollten Probleme auftreten, hilft ein Blick ins Log!&amp;lt;/p&amp;gt;&amp;lt;p&amp;gt;Das Rspamd Log kannst du z.B. so einsehen und live mitlesen:&amp;lt;/p&amp;gt;&amp;lt;pre&amp;gt;&amp;lt;code&amp;gt;journalctl -f -u rspamd&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;/pre&amp;gt;&amp;lt;p&amp;gt;Postfix so:&amp;lt;/p&amp;gt;&amp;lt;pre&amp;gt;&amp;lt;code&amp;gt;journalctl -f -u postfix@-.service&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;/pre&amp;gt;&amp;lt;p&amp;gt;… und Dovecot so:&amp;lt;/p&amp;gt;&amp;lt;pre&amp;gt;&amp;lt;code&amp;gt;journalctl -f -u dovecot&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;/pre&amp;gt;&amp;lt;hr&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;hr&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Fragen und Antworten ==&lt;br /&gt;
=== “Darf ich deine Anleitung übernehmen?” ===&lt;br /&gt;
&amp;lt;p&amp;gt;Nein. Du kannst dir sicherlich vorstellen, dass hinter meiner Anleitung viel Mühe und Arbeit steckt. Ich stelle sie nicht frei zur Verfügung und bitte darum, meinen Text nicht ohne ausdrückliche Zustimmung zu re-publizieren (auch nicht in privaten, aber öffentlich zugänglichen Blogs!). Also ein klares “Nein” zu Copy &amp;amp; Paste + Wiederveröffentlichung. Private, nicht-öffentliche Kopien oder Kopien für den Firmen-internen Gebrauch sind natürlich erlaubt. Es geht mir auch darum, diesen Beitrag nicht auf irgendeinem fremden Blog wiederzufinden, der womöglich sogar noch Geld mit fremden Content verdient. Verlinken ist natürlich absolut erlaubt und ausdrücklich erwünscht ;-)&amp;lt;/p&amp;gt;&lt;br /&gt;
=== “Wieso veröffentlichst du deine Anleitung auf deinem Blog und nicht in einem Wiki?” ===&lt;br /&gt;
&amp;lt;p&amp;gt;Weil ich hier die volle Kontrolle habe. Was hier steht, ist in sich konsistent und kein Flickenteppich. In den gängigen Wikis darf dieser Beitrag natürlich gerne ergänzend verlinkt werden.&amp;lt;/p&amp;gt;&amp;lt;p&amp;gt;'''Ich habe das ''nicht getestet''!'''&amp;lt;/p&amp;gt;&lt;br /&gt;
=== Welche Daten sollte ich für Backups Sichern? ===&lt;br /&gt;
&amp;lt;p&amp;gt;Folgende Verzeichnisse sollten ins Backup aufgenommen werden:&amp;lt;/p&amp;gt;&lt;br /&gt;
*&amp;lt;code&amp;gt;/etc/postfix&amp;lt;/code&amp;gt; (Postfix Konfiguration)&lt;br /&gt;
*&amp;lt;code&amp;gt;/etc/dovecot&amp;lt;/code&amp;gt; (Dovecot Konfiguration)&lt;br /&gt;
*&amp;lt;code&amp;gt;/etc/rspamd&amp;lt;/code&amp;gt; (Rspamd Konfiguration)&lt;br /&gt;
*&amp;lt;code&amp;gt;/var/vmail&amp;lt;/code&amp;gt; (E-Mails, Benutzerkonteneinstellungen und Sieve-Filter)&lt;br /&gt;
*&amp;lt;code&amp;gt;/var/lib/rspamd/dkim&amp;lt;/code&amp;gt; (DKIM-Schlüssel)&lt;br /&gt;
*&amp;lt;code&amp;gt;/var/www/mysystems.tld/autoconfig.mysystems.tld&amp;lt;/code&amp;gt; (Autoconfig-Datei)&lt;br /&gt;
&amp;lt;p&amp;gt;Außerdem sollte unbedingt regelmäßig ein MySQL-Dump der &amp;lt;code&amp;gt;vmail&amp;lt;/code&amp;gt; Datenbank generiert, in eine Datei geschrieben und ins Backup aufgenommen werden:&amp;lt;/p&amp;gt;&amp;lt;pre&amp;gt;&amp;lt;code&amp;gt;mysqldump vmail &amp;amp;gt; /root/backups/vmail.sql&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;/pre&amp;gt;&lt;br /&gt;
== Häufige Fehler ==&lt;br /&gt;
=== “fatal: no SASL authentication mechanisms” / “SASL: Connect to private/auth failed: No such file or directory” ===&lt;br /&gt;
&amp;lt;p&amp;gt;Das Problem: Postfix kann Benutzer nicht authentifizieren, weil in /var/spool/postfix/private kein “auth” Socket verfügbar ist. Eigentlich sollte Dovecot diesen Socket bereitstellen. Der Fehler ist also bei Dovecot zu suchen – nicht bei Postfix. Leider hat die Erfahrung gezeigt, dass ein Vertipper nicht zwingend in der Socket-Konfiguration&amp;lt;/p&amp;gt;&amp;lt;pre&amp;gt;&amp;lt;code&amp;gt;unix_listener /var/spool/postfix/private/auth {&lt;br /&gt;
    mode = 0660&lt;br /&gt;
    user = postfix&lt;br /&gt;
    group = postfix&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;/pre&amp;gt;&amp;lt;p&amp;gt;vorhanden sein muss. Es kommt immer wieder vor, dass der Fehler irgendwo anders in der Dovecot-Konfiguration liegt. Dovecot verschweigt einem dann den Fehler und erstellt den auth-Socket für Postfix nicht. Es lohnt sich in so einem Fall, noch einmal die ganze Dovecot-Konfiguration nach Fehlern abzusuchen.&amp;lt;/p&amp;gt;&lt;br /&gt;
=== “5.7.1 Service unavailable; client [1.3.3.7] blocked using zen.spamhaus.org” ===&lt;br /&gt;
&amp;lt;p&amp;gt;Das Problem: Der Mailserver akzeptiert keine E-Mails vom Mailclient und gibt die oben genannte Fehlermeldung zurück.&amp;lt;/p&amp;gt;&amp;lt;p&amp;gt;Das Problem lässt sich sehr einfach lösen, indem statt SMTP-Port 25 der SMTS-Port 465 oder Submission-Port 587 für den Mailversand im Mailclient konfiguriert wird. Auf Port 25 ist eine Blacklist aktiv, welche viele IP-Adressen z.B. aus DSL-Adressbereichen enthält. Diese Einschränkung gilt für die beiden anderen Ports nicht. Mailclients sollten niemals Port 25 zum versenden Nutzen.&amp;lt;/p&amp;gt;&lt;br /&gt;
=== Mailclient verbindet sich nicht zum Server ===&lt;br /&gt;
&lt;br /&gt;
*Evtl. blockiert der Virenschutz die Verbindung?&lt;br /&gt;
*Blockiert die Server-Firewall die Verbindung von außen?&lt;br /&gt;
*Ist die richtige Serveradresse angegeben? (siehe Verbindungseinstellungen oben)&lt;br /&gt;
*Werden die richtigen Ports genutzt und ist der Verschlüsselungstyp richtig eingestellt?&lt;/div&gt;</summary>
		<author><name>Admin</name></author>
	</entry>
	<entry>
		<id>https://wiki.my-network.at/index.php?title=Dovecot_Mailserver&amp;diff=34</id>
		<title>Dovecot Mailserver</title>
		<link rel="alternate" type="text/html" href="https://wiki.my-network.at/index.php?title=Dovecot_Mailserver&amp;diff=34"/>
		<updated>2022-08-24T11:47:53Z</updated>

		<summary type="html">&lt;p&gt;Admin: Die Seite wurde neu angelegt: „&amp;lt;header&amp;gt; = Mailserver mit Dovecot, Postfix, MySQL und Rspamd unter Debian 10 Buster [v1.0] = &amp;lt;div class=&amp;quot;translations&amp;quot;&amp;gt;&amp;lt;br&amp;gt;&amp;lt;/div&amp;gt;&amp;lt;/header&amp;gt; == Mailserver-Funkti…“&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&amp;lt;header&amp;gt;&lt;br /&gt;
= Mailserver mit Dovecot, Postfix, MySQL und Rspamd unter Debian 10 Buster [v1.0] =&lt;br /&gt;
&amp;lt;div class=&amp;quot;translations&amp;quot;&amp;gt;&amp;lt;br&amp;gt;&amp;lt;/div&amp;gt;&amp;lt;/header&amp;gt;&lt;br /&gt;
== Mailserver-Funktionen ==&lt;br /&gt;
&amp;lt;p&amp;gt;Damit ihr einen Eindruck vom Funktionsumfang des fertigen Mailsetups bekommt, hier einige Merkmale:&amp;lt;/p&amp;gt;&lt;br /&gt;
*Senden und Empfangen von E-Mails für beliebige Domains&lt;br /&gt;
*Flexible Einrichtung von Domains, Mailaccounts, Aliasen, Weiterleitungen und Regeln für die Transportverschlüsselung über ein MySQL-Backend zur Laufzeit&lt;br /&gt;
*Nutzer-spezifisch begrenztes Mailbox-Volumen&lt;br /&gt;
*Einrichtung allgemeiner und Nutzer-spezifischer Sieve-Filterregeln zum Filtern und/oder Umsortieren eingehender E-Mails&lt;br /&gt;
*Zuverlässige und moderne Spamerkennung via Rspamd (+ Weboberfläche für Spam-Statistiken)&lt;br /&gt;
*“Send only” Accounts z.B. für NextCloud / Forensoftware / …&lt;br /&gt;
*DKIM-und ARC-Signierung ausgehender E-Mails&lt;br /&gt;
*Mailclient Autokonfiguration&lt;br /&gt;
*Domain Catch-All&lt;br /&gt;
&amp;lt;p&amp;gt;Eine '''Weboberfläche''' / ein '''Management-Tool''' zur Verwaltung dieses Setups biete ich selbst nach wie vor nicht an. In der Zwischenzeit haben aber andere User Lösungen veröffentlicht, z.B.&amp;lt;/p&amp;gt;&lt;br /&gt;
*Florian Kapfenberger:[https://github.com/phiilu/mailman Mailman]''(nicht zu verwechseln mit Mailman, dem Mailinglist-Manager!)''&lt;br /&gt;
*Andreas Bresch:[https://github.com/Andreas-Bresch/vmailManage/ VmailManage]&lt;br /&gt;
&lt;br /&gt;
*Henrik Halbritter:[https://github.com/Halbritter/MailAdmin/releases MailAdmin]&lt;br /&gt;
*awidegreen:[https://github.com/awidegreen/vmail-rs vmail-rs](CLI-Tool!)&lt;br /&gt;
*pprugger:[https://github.com/pprugger/vmail-admin vmail-admin]&lt;br /&gt;
*Kekskurse:[https://github.com/kekskurse/go-mail-admin Go-Mail-Admin]&lt;br /&gt;
&amp;lt;div class=&amp;quot;tip&amp;quot;&amp;gt;Das Datenbank-Layout und die Struktur des &amp;lt;code&amp;gt;/var/vmail&amp;lt;/code&amp;gt;-Verzeichnisses haben sich im Vergleich zur vorherigen Anleitung ''nicht'' geändert. Ein Update älterer Setups ist also einfach realisierbar.&amp;lt;/div&amp;gt;&amp;lt;hr&amp;gt;&lt;br /&gt;
== Verwendete Software ==&lt;br /&gt;
&lt;br /&gt;
*Debian 10 “Buster”&lt;br /&gt;
*Postfix&lt;br /&gt;
*Dovecot&lt;br /&gt;
*Rspamd&lt;br /&gt;
*Redis&lt;br /&gt;
*MariaDB&lt;br /&gt;
*Nginx&lt;br /&gt;
&lt;br /&gt;
== Gegebenheiten ==&lt;br /&gt;
&amp;lt;p&amp;gt;In dieser Anleitung kommen folgende Domains vor:&amp;lt;/p&amp;gt;&lt;br /&gt;
*&amp;lt;code&amp;gt;mysystems.tld&amp;lt;/code&amp;gt;: Übergeordnete, primäre Domain&lt;br /&gt;
*&amp;lt;code&amp;gt;mail.mysystems.tld&amp;lt;/code&amp;gt;: Subdomain, unter der der Mailserver verfügbar sein soll (FQDN des Mailsystems)&lt;br /&gt;
*&amp;lt;code&amp;gt;imap.mysystems.tld&amp;lt;/code&amp;gt;: Alias auf mail.mysystems.tld, wird von vielen Mailclient automatisch gesucht und gefunden&lt;br /&gt;
*&amp;lt;code&amp;gt;smtp.mysystems.tld&amp;lt;/code&amp;gt;: Dasselbe für den SMTP-Dienst&lt;br /&gt;
*&amp;lt;code&amp;gt;domain2.tld&amp;lt;/code&amp;gt;: Eine zweite Domain neben mysystems.tld, für die E-Mails gesendet und empfangen werden sollen&lt;br /&gt;
*&amp;lt;code&amp;gt;domain3.tld&amp;lt;/code&amp;gt;: Eine dritte Domain, für die E-Mails gesendet und empfangen werden sollen&lt;br /&gt;
&amp;lt;p&amp;gt;'''Diese Domains müssen in der ''gesamten'' Anleitung selbstverständlich durch eigene ersetzt werden!'''&amp;lt;br&amp;gt;Auf domain2.tld und domain3.tld kann verzichtet werden, wenn der Mailserver nur für eine Domain (nur für “@mysystems.tld”-Adressen) genutzt werden soll.&amp;lt;/p&amp;gt;&amp;lt;p&amp;gt;Folgende IP-Adressen werden beispielhaft in Konfigurationen genannt und müssen ebenfalls durch die IP-Adressen des jeweiligen Servers ersetzt werden:&amp;lt;/p&amp;gt;&lt;br /&gt;
*&amp;lt;code&amp;gt;2001:db8::1&amp;lt;/code&amp;gt; (IPv6-Adresse des Mailservers)&lt;br /&gt;
*&amp;lt;code&amp;gt;203.0.113.1&amp;lt;/code&amp;gt; (IPv4-Adresse des Mailservers)&lt;br /&gt;
&lt;br /&gt;
== Grundvoraussetzungen für den Mailserver ==&lt;br /&gt;
&lt;br /&gt;
*Ein virtueller oder dedizierter Server mit bereits installiertem Debian 10 Buster&amp;lt;br&amp;gt;(“Standard-Systemwerkzeuge” und “SSH” bei der Installation angewählt)&lt;br /&gt;
*Mindestens eine eigene Domain + volle Kontrolle über die DNS-Zone&lt;br /&gt;
&amp;lt;p&amp;gt;Ein kleiner, virtueller Server auf KVM-Basis ist in den meisten Fällen völlig ausreichend. Ich empfehle für kleine, private Setups zwei CPU-Kerne und 1-2 GB RAM. Virtuelle Server kann man z.B. bei&amp;lt;/p&amp;gt;[https://servercow.de/vserver Servercow]&amp;lt;p&amp;gt;oder&amp;lt;/p&amp;gt;[https://hetzner.cloud/?ref=H6gtsnaMZj6N Hetzner]&amp;lt;p&amp;gt;preisgünstig bekommen.&amp;lt;/p&amp;gt;&lt;br /&gt;
== Komponenten eines vollständigen Mailsystems ==&lt;br /&gt;
&amp;lt;figure&amp;gt;&amp;lt;figcaption&amp;gt;Mailserver Schema&amp;lt;/figcaption&amp;gt;&amp;lt;/figure&amp;gt;&amp;lt;p&amp;gt;Welche Softwarekomponenten verwendet werden, wisst ihr bereits. Doch welche Software übernimmt welche Aufgaben?&amp;lt;/p&amp;gt;&lt;br /&gt;
=== Dovecot ===&lt;br /&gt;
&amp;lt;p&amp;gt;Dovecot ist ein weit verbreiteter MDA (Mail Delivery Agent) und IMAP-Server. Er sortiert ankommende E-Mails in die Postfächer des jeweiligen Empfängers ein und stellt eine Schnittstelle zum Abrufen der Mailbox bereit (IMAP). Außerdem wird Dovecot in diesem Setup von Postfix als sog. SASL-Authentifizierungsserver genutzt: Postfix fragt Dovecot, ob ein bestimmter Benutzer berechtigt ist, sich am System anzumelden.&amp;lt;/p&amp;gt;&lt;br /&gt;
=== Postfix ===&lt;br /&gt;
&amp;lt;p&amp;gt;Postfix wird oft zusammen mit Dovecot eingesetzt. Der populäre MTA (Mail Transfer Agent) kümmert sich um alles, was mit dem Transport der E-Mail zu tun hat: Vom E-Mail Client zum eigenen Mailserver, und von dort aus zum jeweiligen Zielserver. Außerdem nimmt Postfix E-Mails von fremden Servern an und leitet sie an den MDA Dovecot weiter. Antispam-Software wird i.d.R. direkt in Postfix integriert, um eintreffende Spammails erst gar nicht in die Mailbox des Nutzers gelangen zu lassen.&amp;lt;/p&amp;gt;&amp;lt;p&amp;gt;''Anmerkung: Postfix ist “der eigentliche Mailserver”. E-Mails können ohne weiteres einzig und allein mit Postfix gesendet und empfangen werden. Alle weiteren Komponenten wie Dovecot und Rspamd machen uns das Leben allerdings einfacher ;-)''&amp;lt;/p&amp;gt;&lt;br /&gt;
=== MariaDB (MySQL-Datenbank) ===&lt;br /&gt;
&amp;lt;p&amp;gt;Dovecot und Postfix werden so konfiguriert, dass sie eine MySQL-Datenbank als Backend (Datenbasis) nutzen. In der Datenbank werden zu nutzende Domains, Benutzer, Aliase und weitere Daten gespeichert. Durch einfaches Hinzufügen oder Entfernen von Datensätzen in oder aus Datenbanktabellen können neue Benutzer oder Aliase angelegt oder gelöscht werden. Der Vorteil eines Datenbank-Backends ist, dass sich der Mailserver damit sehr einfach verwalten lässt: So ließe sich zur Benutzerverwaltung beispielsweise eine Weboberfläche in PHP entwickeln, die die MySQL-Datenbank verändert. Die Serverkonfiguration muss dann nicht manuell geändert werden.&amp;lt;/p&amp;gt;&lt;br /&gt;
=== Rspamd ===&lt;br /&gt;
&amp;lt;p&amp;gt;Rspamd ist ein Filtersystem, das in Postfix integriert wird und eingehende E-Mails überprüft. Spammails werden von Rspamd erkannt und nicht an den Benutzer zugestellt bzw. aussortiert. Außerdem fügt Rspamd bei ausgehenden E-Mails eine DKIM-Signatur hinzu, sodass fremde Mailserver eigene Mails nicht als verdächtig einstufen.&amp;lt;/p&amp;gt;&lt;br /&gt;
=== Nginx ===&lt;br /&gt;
&amp;lt;p&amp;gt;Nginx ist ein weit verbreiteter und schlanker Webserver / Webproxy. In diesem Setup hat er mehrere Aufgaben: Zum einen kann er als Endpunkt für den Ausstellungsprozess von Let’s Encrypt-Zertifikaten dienen, zum anderen als Proxy für die Rspamd-Weboberfläche, oder um die Autokonfigurationsdatei für Mailclients anzubieten.&amp;lt;/p&amp;gt;&lt;br /&gt;
=== Redis ===&lt;br /&gt;
&amp;lt;p&amp;gt;Redis ist ein hochperformanter In-memory Key-Value-Store, also eine sehr einfache, schnelle Datenbank, welche Schlüssel-Wert-Paare effizient im Speicher ablegen kann. Rspamd nutzt Redis, um einige Daten zwischenzuspeichern (wie z.B. zuletzt überprüfte Mailserver).&amp;lt;/p&amp;gt;&lt;br /&gt;
== Vorbereitungen ==&lt;br /&gt;
=== Tipp: Reinen Tisch machen ===&lt;br /&gt;
&amp;lt;p&amp;gt;Wenn ihr den Server vorher schon für etwas anderes (oder sogar ein anderes Mail-Setup) verwendet habt, stellt sicher, dass Reste aus alten Installationen das neue Setup nicht behindern. Speziell vorherige Mailserver-Versuche sollten rückstandslos entfernt werden (inkl. der zugehörigen Konfigurationsdateien). Am besten ist natürlich – falls möglich – eine komplette Neuinstallation des Servers. Ich empfehle, den Mailserver als eigenständiges System zu betreiben und auf demselben Host keine anderen Dienste zu installieren, um die Integrität des Mailsystems sicherzustellen.&amp;lt;/p&amp;gt;&amp;lt;p&amp;gt;Im Folgenden gehe ich von einem frisch installierten Debian 10 Buster aus (zusätzlich nur “Standard-Systemwerkzeuge” und SSH installiert).&amp;lt;/p&amp;gt;&lt;br /&gt;
=== Login als Root ===&lt;br /&gt;
&amp;lt;p&amp;gt;Bei der Installation von Debian wird ein normaler Benutzeraccount, z.B. “thomas” eingerichtet, zu dem ihr euch via Passwort verbinden könnt. Der Root-Account ist standardmäßig nicht direkt zugänglich, sondern nur über den Umweg via “su”. Für diese Anleitung werden permanent Root-Rechte benötigt. Öffnet nach dem Login am Server also am besten eine Root-Kommandozeile via&amp;lt;/p&amp;gt;&amp;lt;pre&amp;gt;&amp;lt;code&amp;gt;su -&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;/pre&amp;gt;&amp;lt;p&amp;gt;Gebt dann das Passwort für euren root-User ein.&amp;lt;/p&amp;gt;&lt;br /&gt;
=== System aktualisieren ===&lt;br /&gt;
&amp;lt;p&amp;gt;Bevor ihr neue Software-Pakete installiert, solltet ihr mittels&amp;lt;/p&amp;gt;&amp;lt;pre&amp;gt;&amp;lt;code&amp;gt;apt update &amp;amp;&amp;amp; apt upgrade&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;/pre&amp;gt;&amp;lt;p&amp;gt;sicherstellen, dass euer System aktuell ist. Bei der Gelegenheit bietet sich auch gleich ein Reboot an, um einen möglicherweise aktualisierten Linux-Kernel zu laden.&amp;lt;/p&amp;gt;&lt;br /&gt;
=== Hostname und Server-FQDN setzen ===&lt;br /&gt;
&amp;lt;p&amp;gt;Euer Server bekommt zwei Namen, über die er identifiziert werden kann:&amp;lt;/p&amp;gt;&lt;br /&gt;
*Lokalen Hostnamen: Für die Identifizierung des Servers innerhalb der eigenen Infrastruktur, z.B. “mail”&lt;br /&gt;
*FQDN (Fully Qualified Domain Name): Für die weltweite Identifizierung im Internet, z.B. “mail.mysystems.tld”&lt;br /&gt;
&amp;lt;p&amp;gt;Der FQDN muss nicht zwingend etwas mit den Domains zu tun haben, für die später E-Mails gesendet und empfangen werden sollen. Wichtig ist nur, dass euer künftiger Mailserver einen solchen Namen hat, der auch über das DNS zur Server-IP-Adresse aufgelöst werden kann (dazu gleich mehr im Abschnitt “Einrichtung des DNS”). Den lokalen Hostnamen setzt ihr wie folgt:&amp;lt;/p&amp;gt;&amp;lt;pre&amp;gt;&amp;lt;code&amp;gt;hostnamectl set-hostname --static mail&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;/pre&amp;gt;&amp;lt;p&amp;gt;In der Hosts-Datei &amp;lt;code&amp;gt;/etc/hosts&amp;lt;/code&amp;gt; sollten FQDN und lokaler Hostname hinterlegt sein. Die Datei kann beispielsweise so aussehen:&amp;lt;/p&amp;gt;&amp;lt;pre&amp;gt;&amp;lt;code&amp;gt;127.0.0.1	localhost&lt;br /&gt;
127.0.1.1	mail.mysystems.tld	mail&lt;br /&gt;
&lt;br /&gt;
::1         localhost ip6-localhost ip6-loopback&lt;br /&gt;
ff02::1     ip6-allnodes&lt;br /&gt;
ff02::2     ip6-allrouters&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;/pre&amp;gt;&amp;lt;p&amp;gt;Die Ausgaben der Kommandos &amp;lt;code&amp;gt;hostname&amp;lt;/code&amp;gt; und &amp;lt;code&amp;gt;hostname --fqdn&amp;lt;/code&amp;gt; sollten nach den Änderungen wie folgt aussehen:&amp;lt;/p&amp;gt;&amp;lt;pre&amp;gt;&amp;lt;code&amp;gt;root@mail:~# hostname&lt;br /&gt;
mail&lt;br /&gt;
root@mail:~# hostname --fqdn&lt;br /&gt;
mail.mysystems.tld&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;/pre&amp;gt;&amp;lt;p&amp;gt;Der FQDN (in diesem Beispiel “mail.mysystems.tld”) wird außerdem nach &amp;lt;code&amp;gt;/etc/mailname&amp;lt;/code&amp;gt; geschrieben:&amp;lt;/p&amp;gt;&amp;lt;pre&amp;gt;&amp;lt;code&amp;gt;echo $(hostname -f) &amp;amp;gt; /etc/mailname&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;/pre&amp;gt;&amp;lt;p&amp;gt;''(Der Hostname im Shell-Prompt z.B. &amp;lt;code&amp;gt;root@meinhost:&amp;lt;/code&amp;gt; passt sich erst nach einem erneuten Login an.)''&amp;lt;/p&amp;gt;&lt;br /&gt;
=== Unbound DNS Resolver installieren ===&lt;br /&gt;
&amp;lt;p&amp;gt;Das Mailsystem benötigt einen funktionierenden DNS-Server (Resolver), sodass die Herkunft von E-Mails überprüft werden kann. Auch der Rspamd-Spamfilter verlässt sich bei der Bewertung von Spammails auf DNS-Dienste. Eine schnelle Namesauflösung bringt also Performancevorteile für das ganze Mailsystem. Für den Zugriff auf Spamhaus-Blocklists kann es sogar notwendig sein, seinen eigenen DNS-Resolver zu nutzen, weil z.B. Zugriffe über das Google DNS blockiert werden. Deshalb (und um die Sicherheit im Bezug auf Abhängigkeiten zu fremden Systemen zu verbessern) empfehle ich die Nutzung eines eigenen, lokalen DNS-Resolvers.&amp;lt;/p&amp;gt;&amp;lt;p&amp;gt;Unbound installieren:&amp;lt;/p&amp;gt;&amp;lt;pre&amp;gt;&amp;lt;code&amp;gt;apt install unbound&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;/pre&amp;gt;&amp;lt;div class=&amp;quot;tip&amp;quot;&amp;gt;Für die nächsten Kommandos muss müssen die Pakete &amp;lt;code&amp;gt;dnsutils&amp;lt;/code&amp;gt; und &amp;lt;code&amp;gt;resolvconf&amp;lt;/code&amp;gt; installiert sein. Wenn bei der Installation von Debian die “Standard-Systemwerkzeuge” ausgewählt wurden, sind die &amp;lt;code&amp;gt;dnsutils&amp;lt;/code&amp;gt; schon installiert.&amp;lt;/div&amp;gt;&amp;lt;p&amp;gt;Ein &amp;lt;code&amp;gt;dig @::1 denic.de +short +dnssec&amp;lt;/code&amp;gt; sollte eine ähnliche Ausgabe wie folgt erzeugen:&amp;lt;/p&amp;gt;&amp;lt;pre&amp;gt;&amp;lt;code&amp;gt;# dig @::1 denic.de +short +dnssec&lt;br /&gt;
A 8 2 3600 20170814090000 20170731090000 26155 denic.de. Jo90qnkLkZ6gI4qNHj19BMguFuGof9hCPhdeSh/fSePSQ/WXlWMmfjW1 sNDJ/bcITRMyz8DQdDzmWPDIeSJ/qPyfoZ+BjUZxtaXcs0BAl4KX8q7h R05TGmAbgPhrYBoUKJkU/q8T+jWKHAJRUeWbCd8QOJsJbneGcUKxRAPe i6Rq51/OL/id6zUCtalhclah2TfLLaqku9PmKwjbGdZm11BXSr8b56LB WX/rdLIrKWNpE+jHGAUMmDsZL84Kx3Oo&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;/pre&amp;gt;&amp;lt;p&amp;gt;Wenn der &amp;lt;code&amp;gt;dig&amp;lt;/code&amp;gt;-Befehl funktioniert hat, kann der lokale Resolver als primärer Resolver gesetzt werden:&amp;lt;/p&amp;gt;&amp;lt;pre&amp;gt;&amp;lt;code&amp;gt;apt install resolvconf&lt;br /&gt;
echo &amp;quot;nameserver ::1&amp;quot; &amp;amp;gt;&amp;amp;gt; /etc/resolvconf/resolv.conf.d/head&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;/pre&amp;gt;&amp;lt;p&amp;gt;ein &amp;lt;code&amp;gt;nslookup denic.de | grep Server&amp;lt;/code&amp;gt; sollte nun&amp;lt;/p&amp;gt;&amp;lt;pre&amp;gt;&amp;lt;code&amp;gt;Server:		::1&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;/pre&amp;gt;&amp;lt;p&amp;gt;zurückliefern. Damit ist der lokale DNS-Resolver als Haupt-Resolver einsatzbereit.&amp;lt;/p&amp;gt;&lt;br /&gt;
== Einrichtung des DNS ==&lt;br /&gt;
&amp;lt;p&amp;gt;Zu Beginn dieser Anleitung wurde für den Mailserver der FQDN “mail.mysystems.tld” festgelegt. Für diesen Domain-Namen werden nun A-Records im DNS-Zonefile der Domain “mysystems.tld” erstellt. Loggt euch bei eurem Domain-Provider ein und legt die folgenden Einträge an – der erste für die IPv4-IP-Adresse des Mailservers, die zweite für die IPv6-Adresse. (Beispiel!):&amp;lt;/p&amp;gt;&amp;lt;p&amp;gt;Achtet im Folgenden vor allem auf den abschließenden Punkt in den Domainnamen!&amp;lt;/p&amp;gt;&amp;lt;pre&amp;gt;&amp;lt;code&amp;gt;mail.mysystems.tld. 86400 IN A    203.0.113.1&lt;br /&gt;
mail.mysystems.tld. 86400 IN AAAA 2001:db8::1&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;/pre&amp;gt;&amp;lt;p&amp;gt;“mail.mysystems.tld” ist damit im DNS bekannt. Wenn keine IPv6-Adresse genutzt wird, kann der zweite Record entfallen. Bleiben noch “imap.mysystems.tld” und “smtp.mysystems.tld”, die als Alias-Domains für “mail.mysystems.tld” angelegt werden. Sie sind nicht unbedingt notwendig, werden von vielen Mailclient aber gesucht und sind so üblich:&amp;lt;/p&amp;gt;&amp;lt;pre&amp;gt;&amp;lt;code&amp;gt;imap.mysystems.tld. 86400 IN CNAME mail.mysystems.tld.&lt;br /&gt;
smtp.mysystems.tld. 86400 IN CNAME mail.mysystems.tld.&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;/pre&amp;gt;&amp;lt;p&amp;gt;Mailclients können sich damit schon über imap.mysystems.tld und smtp.mysystems.tld zum Mailserver verbinden. Andere Mailserver suchen bei der E-Mail-Übermittlung allerdings nicht nach A- oder CNAME-Records, sondern nach MX-Records. Ein MX-Record zeigt, welcher Mailserver für die E-Mails zu einer Domain zuständig ist. In meinem Beispiel soll sich unser Mailserver neben den E-Mails für mysystems.tld auch um die Mails für domain2.tld und domain3.tld kümmern.&amp;lt;/p&amp;gt;&amp;lt;p&amp;gt;Im Zonefile der Domain “mysystems.tld” wird dazu dieser Record angelegt:&amp;lt;/p&amp;gt;&amp;lt;pre&amp;gt;&amp;lt;code&amp;gt;mysystems.tld. 86400 IN MX 0 mail.mysystems.tld.&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;/pre&amp;gt;&amp;lt;p&amp;gt;In die Zonefiles der anderen Domains werden entsprechend die Records&amp;lt;/p&amp;gt;&amp;lt;pre&amp;gt;&amp;lt;code&amp;gt;domain2.tld. 86400 IN MX 0 mail.mysystems.tld.&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;/pre&amp;gt;&amp;lt;p&amp;gt;und&amp;lt;/p&amp;gt;&amp;lt;pre&amp;gt;&amp;lt;code&amp;gt;domain3.tld. 86400 IN MX 0 mail.mysystems.tld.&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;/pre&amp;gt;&amp;lt;p&amp;gt;angelegt.&amp;lt;/p&amp;gt;&lt;br /&gt;
=== Reverse DNS ===&lt;br /&gt;
&amp;lt;p&amp;gt;Des weiteren muss ein sog. Reverse-DNS-Record / PTR für den FQDN des Mailservers angelegt werden. Dieser entspricht der Umkehrung eines normalen DNS-Records und ordnet einer IP-Adresse einen Hostnamen zu. Diesen Record kann nur der Inhaber des Netzes anlegen, aus dem eure IP-Adresse stammt. Möglicherweise könnt ihr so einen Reverse-DNS-Record in der Verwaltungsoberfläche eures Serveranbieters setzen, oder ihr bittet den Support, das zu tun. Der Domain-Name, der mit der IP-Adresse verknüpft werden muss, ist der FQDN eures Mailservers. In meinem Beispiel mail.mysystems.tld. Denkt daran, für alle vom Mailserver genutzten, öffentlichen IP-Adressen einen solchen Record zu erstellen. In dieser Anleitung wird eine IPv4- und eine IPv6-Adresse verwendet.&amp;lt;/p&amp;gt;&lt;br /&gt;
=== SPF-Records ===&lt;br /&gt;
&amp;lt;p&amp;gt;Im Kampf gegen Spam und Phishing wurde das sog. Sender Policy Framework entwickelt (Siehe auch Beitrag: “&amp;lt;/p&amp;gt;[https://thomas-leister.de/voraussetzungen-email-versand-gro%C3%9Fe-provider/ Voraussetzungen für den Versand zu großen E-Mail Providern]&amp;lt;p&amp;gt;&amp;quot;). Obwohl es sich nur als eingeschränkt brauchbar erwiesen hat, erwarten die meisten Mailprovider gültige SPF-Records für andere Mailserver und prüfen diese. SPF-Einträge werden im Zonefile aller Domains erstellt, für die ein Mailserver E-Mails verschickt, und geben an, welche Server für eine Domain sendeberechtigt sind. Für unsere Domain mysystems.tld wird der folgende Record im Zonefile von mysystems.tld angelegt:&amp;lt;/p&amp;gt;&amp;lt;pre&amp;gt;&amp;lt;code&amp;gt;mysystems.tld. 3600 IN TXT v=spf1 a:mail.mysystems.tld mx ?all&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;/pre&amp;gt;&amp;lt;p&amp;gt;Hiermit erhält nur der im A-Record “mail.msystems.tld” genannte Server für mysystems.tld eine Sendeberechtigung. Die Neutral-Einstellung “?all” sorgt dafür, dass E-Mails von anderen Servern trotzdem angenommen werden sollen. Damit gehen wir Problemen beim Mail-Forwarding aus dem Weg. Wir erstellen den SPF-Record also eigentlich nur, damit andere Mailserver unseren Server wegen des existierenden Records positiv bewerten – nicht, weil er seinen Nutzen entfalten soll.&amp;lt;/p&amp;gt;&amp;lt;p&amp;gt;In den Zonefiles der beiden Domains “domain2.tld” und “domain3.tld” wird (angepasst auf die Domain) jeweils dieser Record angelegt:&amp;lt;/p&amp;gt;&amp;lt;pre&amp;gt;&amp;lt;code&amp;gt;domain2.tld. 3600 IN TXT v=spf1 include:mysystems.tld ?all&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;/pre&amp;gt;&amp;lt;p&amp;gt;Über das “include” wird der erste Record der Domain mysystems.tld eingebunden.&amp;lt;/p&amp;gt;&lt;br /&gt;
=== DMARC Records ===&lt;br /&gt;
&amp;lt;p&amp;gt;DMARC-Einträge bestimmen, was ein fremder Mailserver tun soll, wenn eine von ihm empfangene Mail nach SPF- und DKIM-Checks offenbar nicht vom korrekten Mailserver stammt (wenn der Absender also gefälscht wurde). Es ist vernünftig, andere Mailserver anzuweisen, solche E-Mails nicht zu akzeptieren:&amp;lt;/p&amp;gt;&amp;lt;pre&amp;gt;&amp;lt;code&amp;gt;_dmarc.mysystems.tld.   3600    IN TXT    v=DMARC1; p=reject;&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;/pre&amp;gt;&amp;lt;p&amp;gt;Der Record wird entsprechend auch für die anderen Domains gesetzt:&amp;lt;/p&amp;gt;&amp;lt;pre&amp;gt;&amp;lt;code&amp;gt;_dmarc.domain2.tld.   3600    IN TXT    v=DMARC1; p=reject;&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;/pre&amp;gt;&amp;lt;p&amp;gt;Einen DMARC-Record mit einer abweichenden Policy könnt ihr euch unter&amp;lt;/p&amp;gt;[https://elasticemail.com/dmarc/ https://elasticemail.com/dmarc/]&amp;lt;p&amp;gt;selbst generieren lassen.&amp;lt;/p&amp;gt;&lt;br /&gt;
== Erstkonfiguration Nginx Webserver ==&lt;br /&gt;
&amp;lt;p&amp;gt;Wie bereits angemerkt, übernimmt Nginx in diesem Setup verschiedene Aufgaben. Für’s erste dient er aber nur als HTTP-Endpunkt, um Let’s Encrypt Zertifikate zu beantragen. Das ist zwar prinzipiell auch ohne Nginx im standalone-Modus möglich, macht uns aber das Leben einfacher, wenn wir ihn sowieso in Betrieb haben ''(=&amp;amp;gt; belegte Ports durch Nginx, ACME client …)''.&amp;lt;/p&amp;gt;&amp;lt;p&amp;gt;Dazu wird Nginx installiert …&amp;lt;/p&amp;gt;&amp;lt;pre&amp;gt;&amp;lt;code&amp;gt;apt install nginx&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;/pre&amp;gt;&amp;lt;p&amp;gt;… und unter &amp;lt;code&amp;gt;/etc/nginx/sites-available/mail.mysystems.tld&amp;lt;/code&amp;gt; eine neue Konfiguration mit diesem Inhalt angelegt:&amp;lt;/p&amp;gt;&amp;lt;pre&amp;gt;&amp;lt;code&amp;gt;server {&lt;br /&gt;
        listen 80;&lt;br /&gt;
        listen [::]:80;&lt;br /&gt;
#       listen 443 ssl http2;&lt;br /&gt;
#       listen [::]:443 ssl http2;&lt;br /&gt;
&lt;br /&gt;
        server_name mail.mysystems.tld imap.mysystems.tld smtp.mysystems.tld;&lt;br /&gt;
&lt;br /&gt;
#       ssl_certificate /etc/acme.sh/mail.mysystems.tld/fullchain.pem;&lt;br /&gt;
#       ssl_certificate_key /etc/acme.sh/mail.mysystems.tld/privkey.pem;&lt;br /&gt;
&lt;br /&gt;
#       add_header Strict-Transport-Security max-age=15768000;&lt;br /&gt;
&lt;br /&gt;
#       if ($ssl_protocol = &amp;quot;&amp;quot;) {&lt;br /&gt;
#           return 301 https://$server_name$request_uri;&lt;br /&gt;
#       }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;/pre&amp;gt;&amp;lt;p&amp;gt;Einige Zeilen sind zu diesem Zeitpunkt bewusst auskommentiert und werden später wieder aktiviert, sobald TLS-Zertifikate verfügbar sind.&amp;lt;/p&amp;gt;&amp;lt;p&amp;gt;Der neue vHost kann nun aktiviert werden:&amp;lt;/p&amp;gt;&amp;lt;pre&amp;gt;&amp;lt;code&amp;gt;ln -s /etc/nginx/sites-available/mail.mysystems.tld /etc/nginx/sites-enabled/mail.mysystems.tld&lt;br /&gt;
systemctl reload nginx&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;/pre&amp;gt;&lt;br /&gt;
== Beantragung der TLS-Zertifikate (via Let’s Encrypt) ==&lt;br /&gt;
&amp;lt;p&amp;gt;Gültige TLS-Zertifikate von anerkannten Zertifizierungsstellen (CAs) sind heute für jeden Mailserver ein “muss”. Immer mehr Mailsysteme verweigern zurecht den Empfang über ungesicherte Verbindungen. Was früher (vor allem für den privaten Einsatz) noch ein bedeutender Kostenfaktor war, bekommt man heute Dank Let’s Encrypt kostenlos und sehr unkompliziert. Im folgenden beziehe ich mich daher auf die Generierung von Let’s Encrypt-Zertifikaten. Selbstverständlich können stattdessen auch Zertifikate anderer CAs genutzt werden.&amp;lt;/p&amp;gt;&amp;lt;p&amp;gt;Für Postfix und Dovecot benötigen wir Zertifikate zu folgenden Domains:&amp;lt;/p&amp;gt;&lt;br /&gt;
*mail.mysystems.tld&lt;br /&gt;
*imap.mysystems.tld&lt;br /&gt;
*smtp.mysystems.tld&lt;br /&gt;
&amp;lt;p&amp;gt;Um die Zertifikate von der Let’s Encrypt Zertifizierungsstelle abholen, nutze ich das schlanke&amp;lt;/p&amp;gt;[https://github.com/acmesh-official/acme.sh acme.sh Script]&amp;lt;p&amp;gt;. Dieses verfügt über einen “Nginx-Mode”, in dem das Script den Nginx Webserver automatisch so konfiguriert, dass die Domains von LE verifiziert werden können.&amp;lt;/p&amp;gt;&amp;lt;p&amp;gt;acme.sh installieren:&amp;lt;/p&amp;gt;&amp;lt;pre&amp;gt;&amp;lt;code&amp;gt;curl https://get.acme.sh | sh&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;/pre&amp;gt;&amp;lt;div class=&amp;quot;tip&amp;quot;&amp;gt;Der Hinweis, welcher besagt, dass socat installiert werden solle, kann ignoriert werden. Socat wird in unserem Fall nicht benötigt.&amp;lt;/div&amp;gt;&amp;lt;p&amp;gt;Nach der Installation muss das Shell-Profil neu geladen werden, damit das “acme.sh” Kommando verfügbar gemacht wird:&amp;lt;/p&amp;gt;&amp;lt;pre&amp;gt;&amp;lt;code&amp;gt;source ~/.profile&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;/pre&amp;gt;&amp;lt;p&amp;gt;Zertifikate beantragen und herunterladen:&amp;lt;/p&amp;gt;&amp;lt;pre&amp;gt;&amp;lt;code&amp;gt;acme.sh --issue --server letsencrypt --nginx \&lt;br /&gt;
    -d mail.mysystems.tld \&lt;br /&gt;
    -d imap.mysystems.tld \&lt;br /&gt;
    -d smtp.mysystems.tld&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;/pre&amp;gt;&amp;lt;p&amp;gt;Zertifikate installieren:&amp;lt;/p&amp;gt;&amp;lt;pre&amp;gt;&amp;lt;code&amp;gt;mkdir -p /etc/acme.sh/mail.mysystems.tld&lt;br /&gt;
acme.sh --install-cert -d mail.mysystems.tld \&lt;br /&gt;
    --key-file       /etc/acme.sh/mail.mysystems.tld/privkey.pem  \&lt;br /&gt;
    --fullchain-file /etc/acme.sh/mail.mysystems.tld/fullchain.pem \&lt;br /&gt;
    --reloadcmd     &amp;quot;systemctl reload nginx; systemctl restart dovecot; systemctl restart postfix;&amp;quot;&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;/pre&amp;gt;&amp;lt;p&amp;gt;Infolge unseres Reload-Commands wird Acme.sh versuchen, Dovecot und Postfix neu zu laden. Da beide Softwarepakete noch nicht installiert sind, werden euch Fehler angezeigt. Ihr könnt diese zum gegenwärtigen Zeitpunkt aber ignorieren.&amp;lt;/p&amp;gt;&amp;lt;p&amp;gt;Die vorher im Nginx auskommentierten Zeilen in &amp;lt;code&amp;gt;/etc/nginx/sites-available/mail.mysystems.tld&amp;lt;/code&amp;gt; können durch entfernen der Hashzeichen nun aktiviert und Nginx mittels&amp;lt;/p&amp;gt;&amp;lt;pre&amp;gt;&amp;lt;code&amp;gt;nginx -t&lt;br /&gt;
systemctl reload nginx&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;/pre&amp;gt;&amp;lt;p&amp;gt;getestet und neu gestartet werden.&amp;lt;/p&amp;gt;&amp;lt;p&amp;gt;Für die Autokonfiguration der Mailclients wird später noch ein Zertifikat für eine weitere Domain beantragt - doch das kann erst einmal warten.&amp;lt;/p&amp;gt;&amp;lt;p&amp;gt;Damit die automatische Zertifikatserneuerung funktioniert, wird noch der Cronjob für acme.sh aktiviert:&amp;lt;/p&amp;gt;&amp;lt;pre&amp;gt;&amp;lt;code&amp;gt; acme.sh --install-cronjob&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;/pre&amp;gt;&lt;br /&gt;
== MySQL Datenbank einrichten ==&lt;br /&gt;
&amp;lt;p&amp;gt;Informationen über zu verwaltende Domains, Benutzer, Weiterleitungen und sonstige Einstellungen soll der Mailserver aus einer MySQL-Datenbank ziehen. Das hat den Vorteil, dass der Server im laufenden Betrieb flexibel angepasst werden kann, ohne die Konfigurationsdateien ändern zu müssen. Die Datenbank ermöglicht uns außerdem ein virtualisiertes Mailserver-Setup: Die Benutzer auf den Mailservern müssen nicht mehr als reale Linux-Benutzer im System registriert sein, sondern nur noch in der Datenbank eingetragen werden.&amp;lt;/p&amp;gt;&amp;lt;p&amp;gt;Als DBMS wird die neue Debian-Standard-MySQL-Datenbank “MariaDB” installiert:&amp;lt;/p&amp;gt;&amp;lt;pre&amp;gt;&amp;lt;code&amp;gt;apt install mariadb-server&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;/pre&amp;gt;&amp;lt;p&amp;gt;Nach der Installation sollte MariaDB bereits gestartet sein. Den Status könnt ihr mittels &amp;lt;code&amp;gt;systemctl status mysql&amp;lt;/code&amp;gt;(nicht “mariadb!&amp;quot;) überprüfen. Falls das nicht der Fall ist, startet den Datenbankserver: &amp;lt;code&amp;gt;systemctl start mysql&amp;lt;/code&amp;gt;.&amp;lt;/p&amp;gt;&amp;lt;p&amp;gt;Standardmäßig kann sich nur der root-Systemuser am Datenbankserver anmelden. Authentifiziert wird er dabei automatisch via PAM, sodass keine zusätzliche Passworteingabe notwendig ist. Die einfache Eingabe von&amp;lt;/p&amp;gt;&amp;lt;pre&amp;gt;&amp;lt;code&amp;gt;mysql&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;/pre&amp;gt;&amp;lt;p&amp;gt;bringt euch in eine MySQL Root Shell. Über diese werden nun ein paar SQL-Befehle ausgeführt.&amp;lt;/p&amp;gt;&amp;lt;p&amp;gt;Ein SQL-Kommando endet immer mit einem Semikolon &amp;lt;code&amp;gt;;&amp;lt;/code&amp;gt;. Mehrzeilige Befehle könnt ihr ohne weiteres einfach mit ENTER umbrechen, so wie sie im Folgenden dargestellt werden. Achtet auf den Unterschied zwischen “Tick” (&amp;lt;code&amp;gt;'&amp;lt;/code&amp;gt;) und “Backtick” (&amp;lt;code&amp;gt; \&amp;lt;/code&amp;gt; `) – der Backtick wird mit Shift + 2x Accent-Taste erzeugt. Kopiert die SQL-Statements am besten direkt in eure Zwischenanlage, statt sie mühsam abzutippen.&amp;lt;/p&amp;gt;&amp;lt;p&amp;gt;Im ersten Schritt wird eine neue Datenbank “vmail” angelegt.&amp;lt;/p&amp;gt;&amp;lt;pre&amp;gt;&amp;lt;code&amp;gt;create database vmail&lt;br /&gt;
    CHARACTER SET 'utf8';&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;/pre&amp;gt;&amp;lt;p&amp;gt;Ein neuer DB-User &amp;lt;code&amp;gt;vmail&amp;lt;/code&amp;gt; mit dem Passwort &amp;lt;code&amp;gt;vmaildbpass&amp;lt;/code&amp;gt; bekommt Zugriff auf diese neue Datenbank ''(Wählt ein eigenes Passwort statt “vmaildbpass”!)'':&amp;lt;/p&amp;gt;&amp;lt;div class=&amp;quot;warning&amp;quot;&amp;gt;Nutzt für &amp;lt;code&amp;gt;vmaildbpass&amp;lt;/code&amp;gt; nur die Zeichen 0-9 a-z und A-z. Einigen Berichten nach können Sonderzeichen zu Problemen führen.&amp;lt;/div&amp;gt;&amp;lt;pre&amp;gt;&amp;lt;code&amp;gt;grant select on vmail.* to 'vmail'@'localhost' identified by 'vmaildbpass';&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;/pre&amp;gt;&amp;lt;p&amp;gt;Alle weiteren Kommandos zu Erstellung der Datenbank-Tabellen sollen sich auf die eben erzeugte Datenbank beziehen:&amp;lt;/p&amp;gt;&amp;lt;pre&amp;gt;&amp;lt;code&amp;gt;use vmail;&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;/pre&amp;gt;&amp;lt;p&amp;gt;Das Mail-Setup soll 4 verschiedene Tabellen nutzen. Kopiert die SQL-Statements einzeln und nacheinander in die MySQL-Kommandozeile und bestätigt jedes mal mit [Enter]. Anpassungen sind nicht notwendig.&amp;lt;/p&amp;gt;&lt;br /&gt;
=== Domain-Tabelle ===&lt;br /&gt;
&amp;lt;p&amp;gt;Die Domain-Tabelle enthält alle Domains, die mit dem Mailserver genutzt werden sollen.&amp;lt;/p&amp;gt;&amp;lt;pre&amp;gt;&amp;lt;code&amp;gt;CREATE TABLE `domains` (&lt;br /&gt;
    `id` int unsigned NOT NULL AUTO_INCREMENT,&lt;br /&gt;
    `domain` varchar(255) NOT NULL,&lt;br /&gt;
    PRIMARY KEY (`id`),&lt;br /&gt;
    UNIQUE KEY (`domain`)&lt;br /&gt;
);&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;/pre&amp;gt;&lt;br /&gt;
=== Account-Tabelle ===&lt;br /&gt;
&amp;lt;pre&amp;gt;&amp;lt;code&amp;gt;CREATE TABLE `accounts` (&lt;br /&gt;
    `id` int unsigned NOT NULL AUTO_INCREMENT,&lt;br /&gt;
    `username` varchar(64) NOT NULL,&lt;br /&gt;
    `domain` varchar(255) NOT NULL,&lt;br /&gt;
    `password` varchar(255) NOT NULL,&lt;br /&gt;
    `quota` int unsigned DEFAULT '0',&lt;br /&gt;
    `enabled` boolean DEFAULT '0',&lt;br /&gt;
    `sendonly` boolean DEFAULT '0',&lt;br /&gt;
    PRIMARY KEY (id),&lt;br /&gt;
    UNIQUE KEY (`username`, `domain`),&lt;br /&gt;
    FOREIGN KEY (`domain`) REFERENCES `domains` (`domain`)&lt;br /&gt;
);&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;/pre&amp;gt;&amp;lt;p&amp;gt;Die Account-Tabelle enthält alle Mailserver-Accounts. Das Feld “quota” enthält die Volumenbegrenzung für die Mailbox in MB (Megabyte). Im Feld “enabled” wird über einen bool’schen Wert festgelegt, ob ein Account aktiv ist, oder nicht. So können einzelne User temporär deaktiviert werden, ohne gelöscht werden zu müssen. “sendonly” wird auf “true” gesetzt, wenn der Account nur zum Senden von E-Mails genutzt werden soll – nicht aber zum Empfang. Das kann beispielsweise für Foren- oder Blogsoftware sinnvoll sein, die mit ihrem Account nur E-Mails verschicken soll.&amp;lt;/p&amp;gt;&lt;br /&gt;
=== Alias-Tabelle ===&lt;br /&gt;
&amp;lt;pre&amp;gt;&amp;lt;code&amp;gt;CREATE TABLE `aliases` (&lt;br /&gt;
    `id` int unsigned NOT NULL AUTO_INCREMENT,&lt;br /&gt;
    `source_username` varchar(64),&lt;br /&gt;
    `source_domain` varchar(255) NOT NULL,&lt;br /&gt;
    `destination_username` varchar(64) NOT NULL,&lt;br /&gt;
    `destination_domain` varchar(255) NOT NULL,&lt;br /&gt;
    `enabled` boolean DEFAULT '0',&lt;br /&gt;
    PRIMARY KEY (`id`),&lt;br /&gt;
    UNIQUE KEY (`source_username`, `source_domain`, `destination_username`, `destination_domain`),&lt;br /&gt;
    FOREIGN KEY (`source_domain`) REFERENCES `domains` (`domain`)&lt;br /&gt;
);&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;/pre&amp;gt;&amp;lt;p&amp;gt;Die Alias-Tabelle enthält alle Weiterleitungen / Aliase und ist eigentlich selbsterklärend. Zur temporären Deaktivierung von Weiterleitungsadressen gibt es wieder ein “enabled”-Feld.&amp;lt;/p&amp;gt;&lt;br /&gt;
=== TLS Policy-Tabelle ===&lt;br /&gt;
&amp;lt;pre&amp;gt;&amp;lt;code&amp;gt;CREATE TABLE `tlspolicies` (&lt;br /&gt;
    `id` int unsigned NOT NULL AUTO_INCREMENT,&lt;br /&gt;
    `domain` varchar(255) NOT NULL,&lt;br /&gt;
    `policy` enum('none', 'may', 'encrypt', 'dane', 'dane-only', 'fingerprint', 'verify', 'secure') NOT NULL,&lt;br /&gt;
    `params` varchar(255),&lt;br /&gt;
    PRIMARY KEY (`id`),&lt;br /&gt;
    UNIQUE KEY (`domain`)&lt;br /&gt;
);&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;/pre&amp;gt;&amp;lt;p&amp;gt;Mithilfe der TLS Policy Tabelle kann festgelegt werden, für welche Empfängerdomains bestimmte Sicherheitsbeschränkungen beim Mailtransport gelten sollen. Für einzelne Domains, z.B. “gmx.de” kann beispielsweise angegeben werden, dass diese E-Mails nur noch verschlüsselt übertragen werden dürfen. Mehr dazu später.&amp;lt;/p&amp;gt;&amp;lt;p&amp;gt;Die Datenbank wird mit Datensätzen befüllt, sobald die Server fertig konfiguriert sind. Bis dahin könnt ihr die MySQL-Kommandozeile mit &amp;lt;code&amp;gt;quit;&amp;lt;/code&amp;gt; verlassen.&amp;lt;/p&amp;gt;&lt;br /&gt;
== vmail-Benutzer und -Verzeichnis einrichten ==&lt;br /&gt;
&amp;lt;p&amp;gt;Alle Mailboxen werden direkt im Dateisystem des Debian Servers abgelegt. Für die Zugriffe auf die Mailbox-Verzeichnisse wird ein eigener Benutzer “vmail” (“Virtual Mail”) erstellt, unter dem die Zugriffe von Dovecot und anderen Komponenten des Mailservers geschehen sollen. Einerseits wird so verhindert, dass Mailserver-Komponenten auf sensible Systemverzeichnisse Zugriff bekommen, andererseits können wir so die Mailboxen vor dem Zugriff von außen schützen. Nur vmail (und root) dürfen auf die Mailboxen zugreifen.&amp;lt;/p&amp;gt;&amp;lt;p&amp;gt;Das Verzeichnis &amp;lt;code&amp;gt;/var/vmail/&amp;lt;/code&amp;gt; soll alle Mailserver-relevanten Dateien (also Mailboxen und Filterscripts) enthalten und wird für den vmail-User als Home Directory festgelegt.&amp;lt;/p&amp;gt;&amp;lt;p&amp;gt;vmail-Benutzer erstellen:&amp;lt;/p&amp;gt;&amp;lt;pre&amp;gt;&amp;lt;code&amp;gt;useradd --create-home --home-dir /var/vmail --user-group --shell /usr/sbin/nologin vmail&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;/pre&amp;gt;&amp;lt;p&amp;gt;vmail Unterverzeichnisse erstellen:&amp;lt;/p&amp;gt;&amp;lt;pre&amp;gt;&amp;lt;code&amp;gt;mkdir /var/vmail/mailboxes&lt;br /&gt;
mkdir -p /var/vmail/sieve/global&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;/pre&amp;gt;&amp;lt;p&amp;gt;Verzeichnis &amp;lt;code&amp;gt;/var/vmail&amp;lt;/code&amp;gt; rekursiv an vmail-User übereignen und Verzeichnisrechte passend setzen:&amp;lt;/p&amp;gt;&amp;lt;pre&amp;gt;&amp;lt;code&amp;gt;chown -R vmail /var/vmail&lt;br /&gt;
chgrp -R vmail /var/vmail&lt;br /&gt;
chmod -R 770 /var/vmail&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;/pre&amp;gt;&lt;br /&gt;
== Dovecot installieren und konfigurieren ==&lt;br /&gt;
&amp;lt;p&amp;gt;Nachdem die Datenbank und der vmail-User angelegt wurden, widmen wir uns nun dem Dovecot-Server. Wie bereits erwähnt, verwaltet dieser Server die Mailboxen und bekommt daher (in der Gestalt des vmail-Users) exklusiv Zugriff auf &amp;lt;code&amp;gt;/var/vmail/&amp;lt;/code&amp;gt;. Zuerst müssen jedoch alle Serverkomponenten installiert werden:&amp;lt;/p&amp;gt;&amp;lt;pre&amp;gt;&amp;lt;code&amp;gt;apt install dovecot-core dovecot-imapd dovecot-lmtpd dovecot-mysql dovecot-sieve dovecot-managesieved&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;/pre&amp;gt;&lt;br /&gt;
*&amp;lt;code&amp;gt;dovecot-core&amp;lt;/code&amp;gt;: Dovecot-Kern&lt;br /&gt;
*&amp;lt;code&amp;gt;dovecot-imapd&amp;lt;/code&amp;gt;: Fügt IMAP-Funktionalität hinzu&lt;br /&gt;
*&amp;lt;code&amp;gt;dovecot-lmtp&amp;lt;/code&amp;gt;: Fügt LMTP (Local Mail Transfer Protocol)-Funktionalität hinzu; LMTP wird als MTP-Protokoll zwischen Postfix und Dovecot genutzt&lt;br /&gt;
*&amp;lt;code&amp;gt;dovecot-mysql&amp;lt;/code&amp;gt;: Lässt Dovecot mit der MySQL-Datenbank zusammenarbeiten&lt;br /&gt;
*&amp;lt;code&amp;gt;dovecot-sieve&amp;lt;/code&amp;gt;: Fügt Filterfunktionalität hinzu&lt;br /&gt;
*&amp;lt;code&amp;gt;dovecot-managesieved&amp;lt;/code&amp;gt;: Stellt eine Schnittstelle zur Einrichtung der Filter via Mailclient bereit&lt;br /&gt;
&amp;lt;p&amp;gt;Nach der Installation wird Dovecot automatisch gestartet. Beendet Dovecot, solange wir keine fertige Konfiguration haben:&amp;lt;/p&amp;gt;&amp;lt;pre&amp;gt;&amp;lt;code&amp;gt;systemctl stop dovecot&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;/pre&amp;gt;&amp;lt;p&amp;gt;Nun geht es an die Konfiguration. Die Dovecot-Konfigurationsdateien liegen im Verzeichnis &amp;lt;code&amp;gt;/etc/dovecot/&amp;lt;/code&amp;gt;. Dort könnt ihr schon einige Konfigurationen sehen, die bei der Installation angelegt wurden. Wir werden die Konfiguration von Grund auf neu aufsetzen - deshalb wird zuerst einmal die gesamte Dovecot-Konfiguration gelöscht:&amp;lt;/p&amp;gt;&amp;lt;pre&amp;gt;&amp;lt;code&amp;gt;rm -r /etc/dovecot/*&lt;br /&gt;
cd /etc/dovecot&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;/pre&amp;gt;&amp;lt;p&amp;gt;Für Dovecot reichen die folgenden zwei Konfigurationsdateien (&amp;lt;code&amp;gt;dovecot.conf&amp;lt;/code&amp;gt; und &amp;lt;code&amp;gt;dovecot-sql.conf&amp;lt;/code&amp;gt;) aus. Erstellt die beiden Dateien im Verzeichnis &amp;lt;code&amp;gt;/etc/dovecot/&amp;lt;/code&amp;gt;.&amp;lt;/p&amp;gt;&lt;br /&gt;
=== Hauptkonfigurationsdatei &amp;lt;code&amp;gt;/etc/dovecot/dovecot.conf&amp;lt;/code&amp;gt; ===&lt;br /&gt;
&amp;lt;pre&amp;gt;&amp;lt;code&amp;gt;##&lt;br /&gt;
## Aktivierte Protokolle&lt;br /&gt;
##&lt;br /&gt;
&lt;br /&gt;
protocols = imap lmtp sieve &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
##&lt;br /&gt;
## TLS Config&lt;br /&gt;
## Quelle: https://ssl-config.mozilla.org/#server=dovecot&amp;amp;version=2.3.9&amp;amp;config=intermediate&amp;amp;openssl=1.1.1d&amp;amp;guideline=5.4&lt;br /&gt;
##&lt;br /&gt;
&lt;br /&gt;
ssl = required&lt;br /&gt;
ssl_cert = &amp;amp;lt;/etc/acme.sh/mail.mysystems.tld/fullchain.pem&lt;br /&gt;
ssl_key = &amp;amp;lt;/etc/acme.sh/mail.mysystems.tld/privkey.pem&lt;br /&gt;
ssl_dh = &amp;amp;lt;/etc/dovecot/dh4096.pem&lt;br /&gt;
ssl_min_protocol = TLSv1.2&lt;br /&gt;
ssl_cipher_list = ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384&lt;br /&gt;
ssl_prefer_server_ciphers = no&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
##&lt;br /&gt;
## Dovecot services&lt;br /&gt;
##&lt;br /&gt;
&lt;br /&gt;
service imap-login {&lt;br /&gt;
    inet_listener imap {&lt;br /&gt;
        port = 143&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
service managesieve-login {&lt;br /&gt;
    inet_listener sieve {&lt;br /&gt;
        port = 4190&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
service lmtp {&lt;br /&gt;
    unix_listener /var/spool/postfix/private/dovecot-lmtp {&lt;br /&gt;
        mode = 0660&lt;br /&gt;
        group = postfix&lt;br /&gt;
        user = postfix&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    user = vmail&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
service auth {&lt;br /&gt;
    ### Auth socket für Postfix&lt;br /&gt;
    unix_listener /var/spool/postfix/private/auth {&lt;br /&gt;
        mode = 0660&lt;br /&gt;
        user = postfix&lt;br /&gt;
        group = postfix&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    ### Auth socket für LMTP-Dienst&lt;br /&gt;
    unix_listener auth-userdb {&lt;br /&gt;
        mode = 0660&lt;br /&gt;
        user = vmail&lt;br /&gt;
        group = vmail&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
##&lt;br /&gt;
##  Protocol settings&lt;br /&gt;
##&lt;br /&gt;
&lt;br /&gt;
protocol imap {&lt;br /&gt;
    mail_plugins = $mail_plugins quota imap_quota imap_sieve&lt;br /&gt;
    mail_max_userip_connections = 20&lt;br /&gt;
    imap_idle_notify_interval = 29 mins&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
protocol lmtp {&lt;br /&gt;
    postmaster_address = postmaster@mysystems.tld&lt;br /&gt;
    mail_plugins = $mail_plugins sieve notify push_notification&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
##&lt;br /&gt;
## Client authentication&lt;br /&gt;
##&lt;br /&gt;
&lt;br /&gt;
disable_plaintext_auth = yes&lt;br /&gt;
auth_mechanisms = plain login&lt;br /&gt;
auth_username_format = %Lu&lt;br /&gt;
&lt;br /&gt;
passdb {&lt;br /&gt;
    driver = sql&lt;br /&gt;
    args = /etc/dovecot/dovecot-sql.conf&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
userdb {&lt;br /&gt;
    driver = sql&lt;br /&gt;
    args = /etc/dovecot/dovecot-sql.conf&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
##&lt;br /&gt;
## Address tagging&lt;br /&gt;
##&lt;br /&gt;
recipient_delimiter = +&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
##&lt;br /&gt;
## Mail location&lt;br /&gt;
##&lt;br /&gt;
&lt;br /&gt;
mail_uid = vmail&lt;br /&gt;
mail_gid = vmail&lt;br /&gt;
mail_privileged_group = vmail&lt;br /&gt;
&lt;br /&gt;
mail_home = /var/vmail/mailboxes/%d/%n&lt;br /&gt;
mail_location = maildir:~/mail:LAYOUT=fs&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
##&lt;br /&gt;
## Mailbox configuration&lt;br /&gt;
##&lt;br /&gt;
&lt;br /&gt;
namespace inbox {&lt;br /&gt;
    inbox = yes&lt;br /&gt;
&lt;br /&gt;
    mailbox Spam {&lt;br /&gt;
        auto = subscribe&lt;br /&gt;
        special_use = \Junk&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    mailbox Trash {&lt;br /&gt;
        auto = subscribe&lt;br /&gt;
        special_use = \Trash&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    mailbox Drafts {&lt;br /&gt;
        auto = subscribe&lt;br /&gt;
        special_use = \Drafts&lt;br /&gt;
    }&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;
&lt;br /&gt;
##&lt;br /&gt;
## Mail plugins&lt;br /&gt;
##&lt;br /&gt;
&lt;br /&gt;
plugin {&lt;br /&gt;
    sieve_plugins = sieve_imapsieve sieve_extprograms&lt;br /&gt;
    sieve_before = /var/vmail/sieve/global/spam-global.sieve&lt;br /&gt;
    sieve = file:/var/vmail/sieve/%d/%n/scripts;active=/var/vmail/sieve/%d/%n/active-script.sieve&lt;br /&gt;
&lt;br /&gt;
    ###&lt;br /&gt;
    ### Spam learning&lt;br /&gt;
    ###&lt;br /&gt;
    # From elsewhere to Spam folder&lt;br /&gt;
    imapsieve_mailbox1_name = Spam&lt;br /&gt;
    imapsieve_mailbox1_causes = COPY&lt;br /&gt;
    imapsieve_mailbox1_before = file:/var/vmail/sieve/global/learn-spam.sieve&lt;br /&gt;
&lt;br /&gt;
    # From Spam folder to elsewhere&lt;br /&gt;
    imapsieve_mailbox2_name = *&lt;br /&gt;
    imapsieve_mailbox2_from = Spam&lt;br /&gt;
    imapsieve_mailbox2_causes = COPY&lt;br /&gt;
    imapsieve_mailbox2_before = file:/var/vmail/sieve/global/learn-ham.sieve&lt;br /&gt;
&lt;br /&gt;
    sieve_pipe_bin_dir = /usr/bin&lt;br /&gt;
    sieve_global_extensions = +vnd.dovecot.pipe&lt;br /&gt;
&lt;br /&gt;
    quota = maildir:User quota&lt;br /&gt;
    quota_exceeded_message = Benutzer %u hat das Speichervolumen überschritten. / User %u has exhausted allowed storage space.&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;/pre&amp;gt;&amp;lt;p&amp;gt;Anzupassende Stellen:&amp;lt;/p&amp;gt;&lt;br /&gt;
*&amp;lt;code&amp;gt;ssl_cert&amp;lt;/code&amp;gt;: Pfad zur Zertifikatsdatei&lt;br /&gt;
*&amp;lt;code&amp;gt;ssl_key&amp;lt;/code&amp;gt;: Pfad zur Zertifikatsdatei&lt;br /&gt;
*&amp;lt;code&amp;gt;postmaster_address&amp;lt;/code&amp;gt;: Domain anpassen&lt;br /&gt;
&lt;br /&gt;
==== Erklärung ====&lt;br /&gt;
&amp;lt;p&amp;gt;&amp;lt;code&amp;gt;dovecot.conf&amp;lt;/code&amp;gt; ist die Hauptkonfigurationsdatei des Dovecot-Servers:&amp;lt;/p&amp;gt;&amp;lt;p&amp;gt;'''Dovecot Services:''' Im darauf folgenden Abschnitt werden die Dovecot Services konfiguriert. Dazu gehört z.B. der Dienst “imap-login”, der auf eingehende Verbindungen von E-Mail Clients auf Port 143 horcht. Auch “managesieve-login” kommuniziert mit dem Mailclient, wenn dieser eine Funktion zur Bearbeitung Server-seitiger Filterscripte mitbringt. Die anderen Dienste werden intern genutzt: Der lmtp-Dienst stellt eine Schnittstelle bereit, über die Postfix empfangene Mails an die Mailbox übergeben kann. Der “auth” Dienst wird vom LMTP-Dienst genutzt, um die Existenz von Benutzern zu überprüfen, aber auch von Postfix, um den Login am Postfix-Server zu überprüfen. Mit “mode”, “user” und “group” wird bestimmt, welcher Systemuser Zugriff auf den Dienst haben soll (Analog zu den Dateirechten – der Socket für den Dienst ist nichts anderes als eine Datei).&amp;lt;/p&amp;gt;&amp;lt;p&amp;gt;'''Protocol settings:''' Für die verwendeten Protokolle können zusätzliche Einstellungen gesetzt werden – u.A. auch, welche Erweiterungen im Zusammenhang mit dem Protokoll genutzt werden sollen. “quota” und “imap_quota” sind notwendig, um das maximale Volumen einer Mailbox festsetzen zu können. Beim lmtp-Protokoll kann auf diese Erweiterungen verzichtet werden: Hier wird nur die Sieve-Erweiterung zum Filtern von E-Mails benötigt.&amp;lt;/p&amp;gt;&amp;lt;p&amp;gt;'''Client Authentication:''' Die Zeilen&amp;lt;/p&amp;gt;&amp;lt;pre&amp;gt;&amp;lt;code&amp;gt;disable_plaintext_auth = yes&lt;br /&gt;
auth_mechanisms = plain login&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;/pre&amp;gt;&amp;lt;p&amp;gt;scheinen sich zu widersprechen, schließlich wird die Klartext-Authentifizierung abgeschaltet. Doch tatsächlich wird sie das nur für unverschlüsselte Verbindungen. TLS-Verschlüsselte Verbindungen bleiben davon unberührt, sodass in der nächsten Zeile die “plain” Authentifizierung mit Klartext-Passwörtern wieder angeboten werden kann. Das wird aus zwei Gründen getan:&amp;lt;/p&amp;gt;&lt;br /&gt;
*“Klartext” tut uns hier nicht weh – schließlich ist die Verbindung sowieso (zwingend) verschlüsselt.&lt;br /&gt;
*Alle Mailclients unterstützen die Klartextauthentifizierung. Andere Loginmechanismen werden weniger gut unterstützt und sind aufwendiger.&lt;br /&gt;
&amp;lt;p&amp;gt;Wir konzentrieren uns deshalb auf die klassische Klartextauthentifizierung. Wie bereits erwähnt: Da unsere Verbindung ohnehin verschlüsselt ist, ist das in diesem Fall nicht sicherheitsrelevant.&amp;lt;/p&amp;gt;&amp;lt;p&amp;gt;Für &amp;lt;code&amp;gt;passdb&amp;lt;/code&amp;gt; und &amp;lt;code&amp;gt;userdb&amp;lt;/code&amp;gt; wird jeweils der Pfad zur SQL-Datei eingestellt. Dort befindt sich jeweils eine passende SQL-Query. Die “passdb” wird befragt, wenn es um die Authentifizierung von Usern geht, die “userdb”, wenn die Existenz eines bestimmten E-Mail Kontos überprüft werden soll, oder benutzerdefinierte Einstellungen geladen werden müssen, wie z.B. das Mailbox-Kontingent (“Quota”).&amp;lt;/p&amp;gt;&amp;lt;p&amp;gt;'''Mail location:''' In diesem Abschnitt wird definiert, unter welchem Systemuser Dovecot auf Dateisystem-Ebene mit E-Mails hantieren soll. Außerdem wird ein Pfad-Schema festgelegt, das bestimmt, nach welcher Struktur die Mailbox-Verzeichnisse angelegt werden sollen. %d steht für die Domain des Accounts und %n für den Benutzernamen vor dem @. Der Pfad zu einer Benutzermailbox lautet z.B.: &amp;lt;code&amp;gt;/var/vmail/mailboxes/mysystems.tld/admin/mail/&amp;lt;/code&amp;gt;&amp;lt;/p&amp;gt;&amp;lt;p&amp;gt;'''Mailbox Configuration:''' In der Mailbox eines jeden Users soll sich standardmäßig ein “Spam”-Ordner befinden, in die ein passendes Sieve-Filterskript verdächtige E-Mails verschieben soll.&amp;lt;/p&amp;gt;&amp;lt;p&amp;gt;'''Mail Plugins:''' Hier werden die Details zu den Erweiterungen &amp;lt;code&amp;gt;sieve&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;quota&amp;lt;/code&amp;gt; und &amp;lt;code&amp;gt;imapsieve&amp;lt;/code&amp;gt; definiert. Das Script unter &amp;lt;code&amp;gt;sieve_before&amp;lt;/code&amp;gt; wird für alle User (unabhängig von den eigenen Einstellungen) immer ausgeführt. Es hat die Aufgabe, durch Rspamd markierte Mails in den Spam-Ordner zu verschieben. &amp;lt;code&amp;gt;sieve_dir&amp;lt;/code&amp;gt; definiert das Schema für den Ort, an dem benutzerdefinierte Scripts abgelegt werden. Das aktive Skript eines Nutzers soll jeweils über den symbolischen Link &amp;lt;code&amp;gt;active-script.sieve&amp;lt;/code&amp;gt; zugänglich sein. Die &amp;lt;code&amp;gt;imapsieve&amp;lt;/code&amp;gt; Einstellungen lassen den IMAP-Server Verschiebevorgängezwischen Mailbox-Ordnern erkennen, sodass Rspamd aus einer Neuordnung lernen kann.&amp;lt;/p&amp;gt;&lt;br /&gt;
=== Diffie-Hellman Parameter für Dovecot generieren ===&lt;br /&gt;
&amp;lt;p&amp;gt;In neueren Versionen generiert Dovecot die Diffie-Hellman-Parameter für TLS-Verbindungen nicht mehr selbst. Also müssen wir selbst Hand anlegen und die Parameter mittels OpenSSL-Tool generieren lassen:&amp;lt;/p&amp;gt;&amp;lt;pre&amp;gt;&amp;lt;code&amp;gt;openssl dhparam -out /etc/dovecot/dh4096.pem 4096 &lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;/pre&amp;gt;&amp;lt;p&amp;gt;Das kann je nach Auslastung des Mailservers durchaus eine viertel Stunde oder länger dauern. Um den Vorhang zu beschleunigen, kann ein sog. Entropy Harvester wie z.B. &amp;lt;code&amp;gt;haveged&amp;lt;/code&amp;gt; installiert werden (&amp;lt;code&amp;gt;apt install haveged&amp;lt;/code&amp;gt;).&amp;lt;/p&amp;gt;&lt;br /&gt;
=== SQL-Konfgurationsdatei &amp;lt;code&amp;gt;/etc/dovecot/dovecot-sql.conf&amp;lt;/code&amp;gt; ===&lt;br /&gt;
&amp;lt;pre&amp;gt;&amp;lt;code&amp;gt;driver=mysql&lt;br /&gt;
connect = &amp;quot;host=localhost dbname=vmail user=vmail password=vmaildbpass&amp;quot;&lt;br /&gt;
default_pass_scheme = SHA512-CRYPT&lt;br /&gt;
&lt;br /&gt;
password_query = SELECT username AS user, domain, password FROM accounts WHERE username = '%Ln' AND domain = '%Ld' and enabled = true;&lt;br /&gt;
user_query = SELECT concat('*:storage=', quota, 'M') AS quota_rule FROM accounts WHERE username = '%Ln' AND domain = '%Ld' AND sendonly = false;&lt;br /&gt;
iterate_query = SELECT username, domain FROM accounts where sendonly = false;&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;/pre&amp;gt;&amp;lt;p&amp;gt;Anzupassende Stellen:&amp;lt;/p&amp;gt;&lt;br /&gt;
*Datenbankpasswort “vmaildbpass”&lt;br /&gt;
&amp;lt;p&amp;gt;&amp;lt;code&amp;gt;dovecot-sql.conf&amp;lt;/code&amp;gt; enthält sensible Datenbank-Zugangsdaten und wird deshalb geschützt:&amp;lt;/p&amp;gt;&amp;lt;pre&amp;gt;&amp;lt;code&amp;gt;chmod 440 dovecot-sql.conf&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;/pre&amp;gt;&lt;br /&gt;
==== Erklärung ====&lt;br /&gt;
&amp;lt;p&amp;gt;Die Konfigurationsdatei &amp;lt;code&amp;gt;dovecot-sql.conf&amp;lt;/code&amp;gt; enthält alle SQL-relevanten Einstellungen:&amp;lt;/p&amp;gt;&lt;br /&gt;
*&amp;lt;code&amp;gt;driver&amp;lt;/code&amp;gt;: Welcher Datenbank-Treiber soll genutzt werden?&lt;br /&gt;
*&amp;lt;code&amp;gt;connect&amp;lt;/code&amp;gt;: Informationen zur Datenbankverbindung&lt;br /&gt;
*&amp;lt;code&amp;gt;default_pass_scheme&amp;lt;/code&amp;gt;: Standardmäßig angenommenes Hash-Schema, wenn es in der Datenbank nicht explizit angegeben ist, z.B. mit vorangestelltem {SHA512-CRYPT}.&lt;br /&gt;
*&amp;lt;code&amp;gt;password_query&amp;lt;/code&amp;gt;: SQL Query für die Überprüfung des User-Logins. Stimmen Benutzername und Passwort überein? Existiert der Benutzer und ist er aktiviert?&lt;br /&gt;
*&amp;lt;code&amp;gt;user_query&amp;lt;/code&amp;gt;: SQL-Query zum Abholen aller Benutzer-spezifischen Einstellungen. In diesem Fall: Maximales Mailbox-Volumen (“Quota”).&lt;br /&gt;
*&amp;lt;code&amp;gt;iterate_query&amp;lt;/code&amp;gt;: SQL-Query zur Abfrage aller verfügbarer Benutzer. Benutzer, die keine Mails empfangen können (sendonly=true) sind für Dovecot nicht interessant und werden nicht mit ausgegeben.&lt;br /&gt;
&lt;br /&gt;
=== Globales Sieve-Filterscript für Spam ===&lt;br /&gt;
&amp;lt;p&amp;gt;Unter &amp;lt;code&amp;gt;/var/vmail/sieve/global/&amp;lt;/code&amp;gt; wird das Sieve-Filterscript &amp;lt;code&amp;gt;spam-global.sieve&amp;lt;/code&amp;gt; erstellt, das erkannte Spammails in den Unterordner “Spam” jeder Mailbox einsortiert. Rspamd markiert erkannte E-Mails mit einem speziellen Spam-Header, den das Script erkennt. Inhalt von &amp;lt;code&amp;gt;spam-global.sieve&amp;lt;/code&amp;gt;:&amp;lt;/p&amp;gt;&amp;lt;pre&amp;gt;&amp;lt;code&amp;gt;require &amp;quot;fileinto&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
if header :contains &amp;quot;X-Spam-Flag&amp;quot; &amp;quot;YES&amp;quot; {&lt;br /&gt;
    fileinto &amp;quot;Spam&amp;quot;;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
if header :is &amp;quot;X-Spam&amp;quot; &amp;quot;Yes&amp;quot; {&lt;br /&gt;
    fileinto &amp;quot;Spam&amp;quot;;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;/pre&amp;gt;&lt;br /&gt;
=== Spam Learning mit Rspamd ===&lt;br /&gt;
&amp;lt;p&amp;gt;Beim Verschieben von Spammails in den Spam-Ordner bzw. dem Herausverschieben falsch beurteilter Mails in den Posteingang soll ein Lernprozess von Rspamd ausgelöst werden, sodass der Filter aus falschen Einschätzungen lernt und so mit der Zeit immer besser wird.&amp;lt;/p&amp;gt;&amp;lt;p&amp;gt;Dazu werden zwei Sieve-Scripts in &amp;lt;code&amp;gt;/var/vmail/sieve/global/&amp;lt;/code&amp;gt; angelegt:&amp;lt;/p&amp;gt;&amp;lt;p&amp;gt;&amp;lt;code&amp;gt;learn-spam.sieve&amp;lt;/code&amp;gt;&amp;lt;/p&amp;gt;&amp;lt;pre&amp;gt;&amp;lt;code&amp;gt;require [&amp;quot;vnd.dovecot.pipe&amp;quot;, &amp;quot;copy&amp;quot;, &amp;quot;imapsieve&amp;quot;];&lt;br /&gt;
pipe :copy &amp;quot;rspamc&amp;quot; [&amp;quot;learn_spam&amp;quot;];&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;/pre&amp;gt;&amp;lt;p&amp;gt;&amp;lt;code&amp;gt;learn-ham.sieve&amp;lt;/code&amp;gt;&amp;lt;/p&amp;gt;&amp;lt;pre&amp;gt;&amp;lt;code&amp;gt;require [&amp;quot;vnd.dovecot.pipe&amp;quot;, &amp;quot;copy&amp;quot;, &amp;quot;imapsieve&amp;quot;, &amp;quot;environment&amp;quot;, &amp;quot;variables&amp;quot;];&lt;br /&gt;
&lt;br /&gt;
if environment :matches &amp;quot;imap.mailbox&amp;quot; &amp;quot;*&amp;quot; {&lt;br /&gt;
    set &amp;quot;mailbox&amp;quot; &amp;quot;${1}&amp;quot;;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
if string &amp;quot;${mailbox}&amp;quot; &amp;quot;Trash&amp;quot; {&lt;br /&gt;
    stop;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
pipe :copy &amp;quot;rspamc&amp;quot; [&amp;quot;learn_ham&amp;quot;];&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;/pre&amp;gt;&amp;lt;p&amp;gt;Das &amp;lt;code&amp;gt;learn-ham.sieve&amp;lt;/code&amp;gt; Script besitzt noch einen Check, der überprüft, ob eine E-Mail aus dem Spam in den Papierkorb verschoben wurde. In diesem Fall sollen die betroffenen Mails ja nicht wieder als “Ham” markiert werden, daher wird in so einem Fall die Ausführung des Lernvorgangs verhindert.&amp;lt;/p&amp;gt;&lt;br /&gt;
== Postfix installieren und konfigurieren ==&lt;br /&gt;
&amp;lt;p&amp;gt;Für unseren Postfix-Server benötigen wir nur zwei Pakete: Das Kernpaket &amp;lt;code&amp;gt;postfix&amp;lt;/code&amp;gt; und die Komponente &amp;lt;code&amp;gt;postfix-mysql&amp;lt;/code&amp;gt;, die Postfix mit der MySQL-Datenbank kommunizieren lässt.&amp;lt;/p&amp;gt;&amp;lt;pre&amp;gt;&amp;lt;code&amp;gt;apt install postfix postfix-mysql&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;/pre&amp;gt;&amp;lt;p&amp;gt;Während der Installation werdet ihr nach der “Allgemeinen Art der Konfiguration” gefragt. Wählt an dieser Stelle “Keine Konfiguration” und beendet den Postfix-Server wieder:&amp;lt;/p&amp;gt;&amp;lt;pre&amp;gt;&amp;lt;code&amp;gt;systemctl stop postfix&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;/pre&amp;gt;&amp;lt;p&amp;gt;Im Postfix-Konfigurationsverzeichnis &amp;lt;code&amp;gt;/etc/postfix&amp;lt;/code&amp;gt; befinden sich trotz unserer Wahl “Keine Konfiguration” ein paar Konfigurationsdateien, die zunächst entfernt werden:&amp;lt;/p&amp;gt;&amp;lt;pre&amp;gt;&amp;lt;code&amp;gt;cd /etc/postfix&lt;br /&gt;
rm -r sasl&lt;br /&gt;
rm master.cf main.cf.proto master.cf.proto&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;/pre&amp;gt;&amp;lt;p&amp;gt;Legt dann folgende Dateien im Verzeichnis &amp;lt;code&amp;gt;/etc/postfix&amp;lt;/code&amp;gt; an:&amp;lt;/p&amp;gt;&lt;br /&gt;
=== &amp;lt;code&amp;gt;/etc/postfix/main.cf&amp;lt;/code&amp;gt; ===&lt;br /&gt;
&amp;lt;pre&amp;gt;&amp;lt;code&amp;gt;##&lt;br /&gt;
## Netzwerkeinstellungen&lt;br /&gt;
##&lt;br /&gt;
&lt;br /&gt;
mynetworks = 127.0.0.0/8 [::ffff:127.0.0.0]/104 [::1]/128&lt;br /&gt;
inet_interfaces = 127.0.0.1, ::1, 203.0.113.1, 2001:db8::1&lt;br /&gt;
myhostname = mail.mysystems.tld&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
##&lt;br /&gt;
## Mail-Queue Einstellungen&lt;br /&gt;
##&lt;br /&gt;
&lt;br /&gt;
maximal_queue_lifetime = 1h&lt;br /&gt;
bounce_queue_lifetime = 1h&lt;br /&gt;
maximal_backoff_time = 15m&lt;br /&gt;
minimal_backoff_time = 5m&lt;br /&gt;
queue_run_delay = 5m&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
##&lt;br /&gt;
## TLS Einstellungen&lt;br /&gt;
## Quelle: https://ssl-config.mozilla.org/#server=postfix&amp;amp;version=3.4.8&amp;amp;config=intermediate&amp;amp;openssl=1.1.1d&amp;amp;guideline=5.4&lt;br /&gt;
##&lt;br /&gt;
&lt;br /&gt;
### Allgemein&lt;br /&gt;
tls_preempt_cipherlist = no&lt;br /&gt;
tls_ssl_options = NO_COMPRESSION&lt;br /&gt;
tls_medium_cipherlist = ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384&lt;br /&gt;
&lt;br /&gt;
### Ausgehende SMTP-Verbindungen (Postfix als Sender)&lt;br /&gt;
smtp_tls_security_level = dane&lt;br /&gt;
smtp_dns_support_level = dnssec&lt;br /&gt;
smtp_tls_policy_maps = proxy:mysql:/etc/postfix/sql/tls-policy.cf&lt;br /&gt;
smtp_tls_session_cache_database = btree:${data_directory}/smtp_scache&lt;br /&gt;
smtp_tls_ciphers = medium&lt;br /&gt;
smtp_tls_CAfile = /etc/ssl/certs/ca-certificates.crt&lt;br /&gt;
&lt;br /&gt;
### Eingehende SMTP-Verbindungen&lt;br /&gt;
smtpd_tls_security_level = may&lt;br /&gt;
smtpd_tls_auth_only = yes&lt;br /&gt;
smtpd_tls_ciphers = medium&lt;br /&gt;
smtpd_tls_mandatory_protocols = !SSLv2, !SSLv3, !TLSv1, !TLSv1.1&lt;br /&gt;
smtpd_tls_protocols = !SSLv2, !SSLv3, !TLSv1, !TLSv1.1&lt;br /&gt;
smtpd_tls_session_cache_database = btree:${data_directory}/smtpd_scache&lt;br /&gt;
smtpd_tls_cert_file=/etc/acme.sh/mail.mysystems.tld/fullchain.pem&lt;br /&gt;
smtpd_tls_key_file=/etc/acme.sh/mail.mysystems.tld/privkey.pem&lt;br /&gt;
smtpd_tls_dh1024_param_file = /etc/postfix/dh2048.pem&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
##&lt;br /&gt;
## Lokale Mailzustellung an Dovecot&lt;br /&gt;
##&lt;br /&gt;
&lt;br /&gt;
virtual_transport = lmtp:unix:private/dovecot-lmtp&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
##&lt;br /&gt;
## Spamfilter und DKIM-Signaturen via Rspamd&lt;br /&gt;
##&lt;br /&gt;
&lt;br /&gt;
smtpd_milters = inet:localhost:11332&lt;br /&gt;
non_smtpd_milters = inet:localhost:11332&lt;br /&gt;
milter_protocol = 6&lt;br /&gt;
milter_mail_macros =  i {mail_addr} {client_addr} {client_name} {auth_authen}&lt;br /&gt;
milter_default_action = accept&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
##&lt;br /&gt;
## Server Restrictions für Clients, Empfänger und Relaying&lt;br /&gt;
## (im Bezug auf S2S-Verbindungen. Mailclient-Verbindungen werden in master.cf im Submission-Bereich konfiguriert)&lt;br /&gt;
##&lt;br /&gt;
&lt;br /&gt;
### Bedingungen, damit Postfix als Relay arbeitet (für Clients)&lt;br /&gt;
smtpd_relay_restrictions =      reject_non_fqdn_recipient&lt;br /&gt;
                                reject_unknown_recipient_domain&lt;br /&gt;
                                permit_mynetworks&lt;br /&gt;
                                reject_unauth_destination&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
### Bedingungen, damit Postfix ankommende E-Mails als Empfängerserver entgegennimmt (zusätzlich zu relay-Bedingungen)&lt;br /&gt;
### check_recipient_access prüft, ob ein account sendonly ist&lt;br /&gt;
smtpd_recipient_restrictions = check_recipient_access proxy:mysql:/etc/postfix/sql/recipient-access.cf&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
### Bedingungen, die SMTP-Clients erfüllen müssen (sendende Server)&lt;br /&gt;
smtpd_client_restrictions =     permit_mynetworks&lt;br /&gt;
                                check_client_access hash:/etc/postfix/without_ptr&lt;br /&gt;
                                reject_unknown_client_hostname&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
### Wenn fremde Server eine Verbindung herstellen, müssen sie einen gültigen Hostnamen im HELO haben.&lt;br /&gt;
smtpd_helo_required = yes&lt;br /&gt;
smtpd_helo_restrictions =   permit_mynetworks&lt;br /&gt;
                            reject_invalid_helo_hostname&lt;br /&gt;
                            reject_non_fqdn_helo_hostname&lt;br /&gt;
                            reject_unknown_helo_hostname&lt;br /&gt;
&lt;br /&gt;
# Clients blockieren, wenn sie versuchen zu früh zu senden&lt;br /&gt;
smtpd_data_restrictions = reject_unauth_pipelining&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
##&lt;br /&gt;
## Restrictions für MUAs (Mail user agents)&lt;br /&gt;
##&lt;br /&gt;
&lt;br /&gt;
mua_relay_restrictions = reject_non_fqdn_recipient,reject_unknown_recipient_domain,permit_mynetworks,permit_sasl_authenticated,reject&lt;br /&gt;
mua_sender_restrictions = permit_mynetworks,reject_non_fqdn_sender,reject_sender_login_mismatch,permit_sasl_authenticated,reject&lt;br /&gt;
mua_client_restrictions = permit_mynetworks,permit_sasl_authenticated,reject&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
##&lt;br /&gt;
## MySQL Abfragen&lt;br /&gt;
##&lt;br /&gt;
&lt;br /&gt;
proxy_read_maps =       proxy:mysql:/etc/postfix/sql/aliases.cf&lt;br /&gt;
                        proxy:mysql:/etc/postfix/sql/accounts.cf&lt;br /&gt;
                        proxy:mysql:/etc/postfix/sql/domains.cf&lt;br /&gt;
                        proxy:mysql:/etc/postfix/sql/recipient-access.cf&lt;br /&gt;
                        proxy:mysql:/etc/postfix/sql/sender-login-maps.cf&lt;br /&gt;
                        proxy:mysql:/etc/postfix/sql/tls-policy.cf&lt;br /&gt;
&lt;br /&gt;
virtual_alias_maps = proxy:mysql:/etc/postfix/sql/aliases.cf&lt;br /&gt;
virtual_mailbox_maps = proxy:mysql:/etc/postfix/sql/accounts.cf&lt;br /&gt;
virtual_mailbox_domains = proxy:mysql:/etc/postfix/sql/domains.cf&lt;br /&gt;
local_recipient_maps = $virtual_mailbox_maps&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
##&lt;br /&gt;
## Sonstiges&lt;br /&gt;
##&lt;br /&gt;
&lt;br /&gt;
### Maximale Größe der gesamten Mailbox (soll von Dovecot festgelegt werden, 0 = unbegrenzt)&lt;br /&gt;
mailbox_size_limit = 0&lt;br /&gt;
&lt;br /&gt;
### Maximale Größe eingehender E-Mails in Bytes (50 MB)&lt;br /&gt;
message_size_limit = 52428800&lt;br /&gt;
&lt;br /&gt;
### Keine System-Benachrichtigung für Benutzer bei neuer E-Mail&lt;br /&gt;
biff = no&lt;br /&gt;
&lt;br /&gt;
### Nutzer müssen immer volle E-Mail Adresse angeben - nicht nur Hostname&lt;br /&gt;
append_dot_mydomain = no&lt;br /&gt;
&lt;br /&gt;
### Trenn-Zeichen für &amp;quot;Address Tagging&amp;quot;&lt;br /&gt;
recipient_delimiter = +&lt;br /&gt;
&lt;br /&gt;
### Keine Rückschlüsse auf benutzte Mailadressen zulassen&lt;br /&gt;
disable_vrfy_command = yes&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;/pre&amp;gt;&amp;lt;p&amp;gt;Anzupassen:&amp;lt;/p&amp;gt;&lt;br /&gt;
*&amp;lt;code&amp;gt;inet_interfaces&amp;lt;/code&amp;gt;: IP-Adressen &amp;lt;code&amp;gt;203.0.113.1, 2001:db8::1&amp;lt;/code&amp;gt; müssen durch eigene IPv4- (und optional IPv6)-Adresse ersetzt werden.&lt;br /&gt;
*&amp;lt;code&amp;gt;myhostname&amp;lt;/code&amp;gt;: Ersetzen durch eigenen Hostnamen&lt;br /&gt;
*&amp;lt;code&amp;gt;smtpd_tls_cert_file&amp;lt;/code&amp;gt;: Pfad zur Zertifikatsdatei&lt;br /&gt;
*&amp;lt;code&amp;gt;smtpd_tls_key_file&amp;lt;/code&amp;gt;: Pfad zur Zertifikatsdatei&lt;br /&gt;
&lt;br /&gt;
==== Diffie-Hellman-Parameter für Postfix generieren ====&lt;br /&gt;
&amp;lt;p&amp;gt;Neben Dovecot bekommt auch Postfix “von Hand generierte” DH-Parameter. Hier allerdings nur 2048 Bit starke, um zu älteren Mailservern kompatibel zu bleiben.&amp;lt;/p&amp;gt;&amp;lt;pre&amp;gt;&amp;lt;code&amp;gt;openssl dhparam -out /etc/postfix/dh2048.pem 2048&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;/pre&amp;gt;&amp;lt;p&amp;gt;Wundert euch übrigens nicht über das &amp;lt;code&amp;gt;1024&amp;lt;/code&amp;gt; in der Einstellung &amp;lt;code&amp;gt;smtpd_tls_dh1024_param_file&amp;lt;/code&amp;gt; - das ist nur Teil des Namens und hat keine Bedeutung für die Schlüssellänge.&amp;lt;/p&amp;gt;&amp;lt;div class=&amp;quot;warning&amp;quot;&amp;gt;&amp;lt;p&amp;gt;Wenn der Mailserver (entgegen meiner Empfehlung) nicht einen &amp;lt;code&amp;gt;mail.domain.tld&amp;lt;/code&amp;gt; Hostnamen hat, sondern unter dem Domainnamen läuft (&amp;lt;code&amp;gt;domain.tld&amp;lt;/code&amp;gt;), muss zur Konfiguration eine Zeile mit&amp;lt;/p&amp;gt;&amp;lt;pre&amp;gt;&amp;lt;code&amp;gt;mydestination =&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;/pre&amp;gt;&amp;lt;p&amp;gt;(ohne Inhalt nach dem “=&amp;quot;) hinzugefügt werden, sonst werden E-Mails an der falschen Stelle gespeichert.&amp;lt;/p&amp;gt;&amp;lt;/div&amp;gt;&lt;br /&gt;
==== Erklärung ====&lt;br /&gt;
&amp;lt;p&amp;gt;'''Netzwerkeinstellungen:'''&amp;lt;/p&amp;gt;&lt;br /&gt;
*&amp;lt;code&amp;gt;mynetworks&amp;lt;/code&amp;gt;: Anfragen von diesen IP-Adressen / aus diesen IP-Adressbereichen werden von Postfix gesondert behandelt (Verwendung für “mynetworks” in den Restrictions). Üblicherweise werden hier die lokalen Adressbereiche und IP-Adressen aus dem eigenen Netz eingetragen, z.B. von anderen eigenen, vertrauenswürdigen Servern.&lt;br /&gt;
*&amp;lt;code&amp;gt;inet_interfaces&amp;lt;/code&amp;gt;: Auf diesen IP-Adressen soll Postfix seine Ports öffnen. Die IP-Adressen müssen an den eigenen Server angepasst werden.&lt;br /&gt;
*&amp;lt;code&amp;gt;myhostname&amp;lt;/code&amp;gt;: Der Hostname des Mailservers, wie er bei der Mailverarbeitung genutzt werden soll.&lt;br /&gt;
&amp;lt;p&amp;gt;'''Mail-Queue Einstellungen:'''&amp;lt;/p&amp;gt;&amp;lt;p&amp;gt;E-Mails in Postfix werden “gequeued”, d.h. in eine Warteschlange eingetragen, die regelmäßig abgearbeitet wird. Wenn Mails nicht zustellbar sind, verbleiben sie eine gewisse Zeit in der Queue, bis ihre Lebenszeit abgelaufen ist, und sie aus der Queue entfernt werden. Der Absender der E-Mail bekommt dann eine entsprechende Nachricht, in der er über die Unzustellbarkeit informiert wird.&amp;lt;/p&amp;gt;&lt;br /&gt;
*&amp;lt;code&amp;gt;maximal_queue_lifetime&amp;lt;/code&amp;gt;: Lebensdauer einer normalen Nachricht in der Queue. Wenn eine E-Mail innerhalb einer Stunde nicht zugestellt werden konnte, wird sie aus der Queue entfernt und der Absender benachrichtigt.&lt;br /&gt;
*&amp;lt;code&amp;gt;bounce_queue_lifetime&amp;lt;/code&amp;gt;: Lebensdauer einer Unzustellbarkeits-Benachrichtigung in der Queue.&lt;br /&gt;
*&amp;lt;code&amp;gt;maximal_backoff_time&amp;lt;/code&amp;gt;: Maximale Zeit, die verstreichen darf, bis für eine E-Mail ein neuer Zustellversuch gestartet wird.&lt;br /&gt;
*&amp;lt;code&amp;gt;minimal_backoff_time&amp;lt;/code&amp;gt;: Zeit, die mindestens verstrichen sein muss, bis ein neuer Zustellversuch gestartet wird.&lt;br /&gt;
*&amp;lt;code&amp;gt;queue_run_delay&amp;lt;/code&amp;gt;: Intervall, in dem die Queue nach nicht zustellbaren E-Mails durchsucht wird.&lt;br /&gt;
&amp;lt;p&amp;gt;'''TLS-Einstellungen:'''&amp;lt;/p&amp;gt;&amp;lt;p&amp;gt;Kompression wird abgeschaltet und (wie bei Dovecot) eine Cipherlist vorgegeben, sodass die bestmögliche Verschlüsselung zwischen Client und Server genutzt wird. Im ersten Teilabschnitt werden die “smtp”-spezifischen TLS-Einstellungen festgelegt – d.h. die Einstellungen, die Postfix als sendenden Kommunikationspartner (Mail-Client) betreffen.&amp;lt;/p&amp;gt;&lt;br /&gt;
*&amp;lt;code&amp;gt;smtp_tls_security_level&amp;lt;/code&amp;gt;: Standard-TLS-Policy, wenn sie in der Datenbank für die Empfängerdomain nicht anders spezifiziert wurde: “dane” kontrolliert zunächst, ob für den Empfängerserver ein TLSA-Eintrag (DANE) im DNS vorliegt. Wenn das der Fall ist, wird eine verschlüsselte Verbindung erzwungen und das vorgezeigte Serverzertifikat mittels TLSA-Eintrag verifiziert. Sollte kein TLSA-Eintrag verfügbar sein, fällt Postfix in die Policy “may” zurück und verschlüsselt nur, wenn der andere Server das unterstützt. Zertifikate werden dabei nicht validiert. Sollten vorhandene TLSA-Einträge ungültig sein, wird stattdessen die “encrypt” Policy genutzt, welche zwar zwingend verschlüsselt, aber Zertifikate ebenfalls nicht validiert. Mehr zu den TLS-Policies folgt später.&lt;br /&gt;
*&amp;lt;code&amp;gt;smtp_dns_support_level&amp;lt;/code&amp;gt;: DNSSEC-gesicherte DNS-Lookups aktiveren und nutzen, falls möglich&lt;br /&gt;
*&amp;lt;code&amp;gt;smtpd_tls_policy_maps&amp;lt;/code&amp;gt;: Verweist auf die SQL-Queries, mit denen Empfängerdomain-spezifische TLS-Einstellungen geladen werden&lt;br /&gt;
*&amp;lt;code&amp;gt;smtp_tls_protocols&amp;lt;/code&amp;gt;: Veraltete SSL/TLS-Protokolle werden deaktiviert&lt;br /&gt;
&amp;lt;p&amp;gt;Nun zum zweiten TLS-Block: Dieser gilt für eingehende Verbindungen. Sowohl für andere Server, als auch Mailclients. Wieder werden SSL v2 und 3 deaktiviert und eine starke Cipherlist ausgewählt. Eingehende Verbindungen können verschlüsselt sein, müssen aber nicht.&amp;lt;/p&amp;gt;&amp;lt;p&amp;gt;'''LMTP-Service:'''&amp;lt;/p&amp;gt;&amp;lt;p&amp;gt;&amp;lt;code&amp;gt;virtual_transport&amp;lt;/code&amp;gt; übermittelt verarbeitete, eingehende E-Mails an den LMTP-Service von Dovecot, der sich dann um die Einordnung der Mail in die passende Mailbox kümmert.&amp;lt;/p&amp;gt;&amp;lt;p&amp;gt;'''Spamfilter und DKIM-Signaturen via Rspamd:'''&amp;lt;/p&amp;gt;&amp;lt;p&amp;gt;Dieser Abschnitt definiert den Rspam-Daemon als Milter für ein- und ausgehende E-Mails. Eingehende E-Mails werden durch Rspamd auf ihre Seriosität geprüft - ausgehende werden mit einem DKIM-Schlüssel signiert.&amp;lt;/p&amp;gt;&amp;lt;p&amp;gt;'''Server Restrictions:'''&amp;lt;/p&amp;gt;&amp;lt;p&amp;gt;Die Blöcke unter “Server restrictions” sind besonders wichtig für die Sicherheit des Mailservers. Falsch eingestellt erlauben sie den unberechtigten Versand von E-Mails (Stichwort “Open Relay”). Der Mailserver wird dann als Spam-Schleuder missbraucht und landet sehr schnell auf einer Blacklist. Damit das nicht passiert, sollten die Restrictions (Beschränkungen) sorgfältig eingestellt und mit einem passenden Open Relay Detektor überprüft sein.&amp;lt;/p&amp;gt;&amp;lt;p&amp;gt;Die Restrictions werden in Leserichtung nacheinander abgearbeitet. Am Ende jeder Verarbeitung steht immer ein “permit” oder “reject”. Für das bessere Verständnis ein Beispiel:&amp;lt;/p&amp;gt;&amp;lt;pre&amp;gt;&amp;lt;code&amp;gt;smtpd_relay_restrictions =      reject_non_fqdn_recipient&lt;br /&gt;
                                reject_unknown_recipient_domain&lt;br /&gt;
                                permit_mynetworks&lt;br /&gt;
                                reject_unauth_destination&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;/pre&amp;gt;&amp;lt;p&amp;gt;&amp;lt;code&amp;gt;smtpd_relay_restrictions&amp;lt;/code&amp;gt; bestimmt die Bedingungen, unter der Postfix als Mail-Relay (“Vermittlungsstelle”) arbeitet. Unser Postfix soll nur in drei Fällen auf eingehende E-Mails reagieren:&amp;lt;/p&amp;gt;&lt;br /&gt;
*Wenn ein Mailclient eine E-Mail via Postfix ins Internet schicken will&lt;br /&gt;
*Wenn ein fremder Mailserver eine E-Mail an unseren Postfix schickt&lt;br /&gt;
*Wenn vom Mailserver selbst aus eine Mail verschickt werden soll&lt;br /&gt;
&amp;lt;p&amp;gt;Um den ersten Fall wird sich in der &amp;lt;code&amp;gt;master.cf&amp;lt;/code&amp;gt; Datei gekümmert. Dort werden die Relay Restrictions im Submission-Bereich so überschrieben, dass Mailclients nicht am freien Versenden gehindert werden. Aktuell interessieren daher nur die letzten beiden Anfrage-Typen. Die erste Zeile der Restriction lautet &amp;lt;code&amp;gt;reject_non_fqdn_recipien&amp;lt;/code&amp;gt;. Sollte die Empfängeradresse keine vollwertige E-Mail Adresse sein, wird die Anfrage an Postfix direkt mit einem &amp;lt;code&amp;gt;reject&amp;lt;/code&amp;gt;abgewiesen. Alle anderen Checks finden dann nicht mehr statt. Das führt dazu, dass Postfix eine Weiterverarbeitung nur akzeptiert, wenn die zu verarbeitende E-Mail einen gültigen Empfänger hat. Ähnliches gilt für &amp;lt;code&amp;gt;reject_unknown_recipient_domain&amp;lt;/code&amp;gt;: Wenn die Empfängerdomain keinen gültigen MX- oder A-Eintrag im DNS hat (und der Zielserver damit nicht feststeht), wird die E-Mail abgelehnt.&amp;lt;/p&amp;gt;&amp;lt;p&amp;gt;Die darauf folgende Zeile enthält die “Restriction” &amp;lt;code&amp;gt;permit_mynetwork&amp;lt;/code&amp;gt;. Wenn der Anfragesteller lokal ist (bzw. seine IP in &amp;lt;code&amp;gt;mynetworks&amp;lt;/code&amp;gt; vermerkt ist), wird er mit einem &amp;lt;code&amp;gt;permit&amp;lt;/code&amp;gt; durchgewunken und die E-Mail wird weiter verarbeitet. Weitere Checks finden dann nicht statt. Sollte er nicht in mynetworks vermerkt sein, wird der letzte Check durchgeführt: &amp;lt;code&amp;gt;reject_unauth_destination&amp;lt;/code&amp;gt; kann nur bestanden werden, wenn die zu verarbeitende E-Mail an eine Empfängeradresse dieses Mailsystems geht. Sollte bis zum Ende der restriction-Definition noch kein &amp;lt;code&amp;gt;permit&amp;lt;/code&amp;gt; oder &amp;lt;code&amp;gt;reject&amp;lt;/code&amp;gt; ausgelöst worden sein, wird automatisch ein &amp;lt;code&amp;gt;permit&amp;lt;/code&amp;gt; ausgelöst und die jeweilige Aktion erlaubt.&amp;lt;/p&amp;gt;&amp;lt;p&amp;gt;Alle anderen Restriction-Definitionen funktionieren ähnlich: Die Kriterien werden nacheinander überprüft. Beginnt ein Kriterium mit einem &amp;lt;code&amp;gt;reject&amp;lt;/code&amp;gt;, wird bei Zutreffen ein &amp;lt;code&amp;gt;reject&amp;lt;/code&amp;gt; ausgelöst, beginnt es mit einem &amp;lt;code&amp;gt;permit&amp;lt;/code&amp;gt;, wird ein &amp;lt;code&amp;gt;permit&amp;lt;/code&amp;gt;ausgelöst. In beiden Fällen werden die nachfolgenden Kriterien nicht mehr überprüft.&amp;lt;/p&amp;gt;&lt;br /&gt;
*&amp;lt;code&amp;gt;smtpd_relay_restrictions&amp;lt;/code&amp;gt;: Kriterien, die überprüft werden, wenn Anfragen am Postfix-Server eintreffen (Von fremden Mailservern oder vom eigenen Server aus, z.B. via sendmail)&lt;br /&gt;
*&amp;lt;code&amp;gt;smtpd_recipient_restrictions&amp;lt;/code&amp;gt;: Kriterien, die zusätzlich zu den relay_restrictions geprüft werden. Nur bei bestehen der Checks wird eine E-Mail auf dem lokalen System angenommen und an die Empfänger-Mailbox geschickt. An dieser Stelle wird über eine SQL-Abfrage nachgefragt, ob ein bestimmter Empfänger E-Mails empfangen können soll (=&amp;amp;gt; Siehe Option in der Datenbank, Accounts nur zum Versenden freizuschalten).&lt;br /&gt;
*&amp;lt;code&amp;gt;smtpd_client-restrictions&amp;lt;/code&amp;gt;: Kriterien, auf die hin andere Server überprüft werden, wenn Kontakt zum Postfix-Server hergestellt wird. (Müssen gültigen Hostnamen und Reverse-DNS-Eintrag haben)&lt;br /&gt;
*&amp;lt;code&amp;gt;smtpd_helo_restrictions&amp;lt;/code&amp;gt;: Fremde Server müssen zu Beginn ihren gültigen Hostnamen nennen.&lt;br /&gt;
*&amp;lt;code&amp;gt;smtpd_data_restrictions&amp;lt;/code&amp;gt;: Ungeduldige Server sind oft Spammer.&lt;br /&gt;
&amp;lt;p&amp;gt;'''MySQL-Abfragen:'''&amp;lt;/p&amp;gt;&amp;lt;p&amp;gt;Hier sind die Pfade zu den übrigen SQL-Dateien angegeben, die Postfix benötigt, um Daten aus der Datenbank abfragen zu können.&amp;lt;/p&amp;gt;&lt;br /&gt;
=== &amp;lt;code&amp;gt;/etc/postfix/master.cf&amp;lt;/code&amp;gt; ===&lt;br /&gt;
&amp;lt;pre&amp;gt;&amp;lt;code&amp;gt;# ==========================================================================&lt;br /&gt;
# service type  private unpriv  chroot  wakeup  maxproc command + args&lt;br /&gt;
#               (yes)   (yes)   (no)    (never) (100)&lt;br /&gt;
# ==========================================================================&lt;br /&gt;
###&lt;br /&gt;
### SMTP-Serverbindungen aus dem Internet&lt;br /&gt;
### Authentifizuerung hier nicht erlaubt (Anmeldung nur via smtps/submission!)&lt;br /&gt;
smtp      inet  n       -       y       -       1       smtpd     &lt;br /&gt;
    -o smtpd_sasl_auth_enable=no&lt;br /&gt;
###&lt;br /&gt;
### SMTPS Service (Submission mit implizitem TLS - ohne STARTTLS) - Port 465&lt;br /&gt;
### Für Mailclients gelten andere Regeln, als für andere Mailserver (siehe smtpd_ in main.cf)&lt;br /&gt;
###&lt;br /&gt;
smtps     inet  n       -       y       -       -       smtpd&lt;br /&gt;
    -o syslog_name=postfix/smtps&lt;br /&gt;
    -o smtpd_tls_wrappermode=yes&lt;br /&gt;
    -o smtpd_tls_security_level=encrypt&lt;br /&gt;
    -o smtpd_sasl_auth_enable=yes&lt;br /&gt;
    -o smtpd_sasl_type=dovecot&lt;br /&gt;
    -o smtpd_sasl_path=private/auth&lt;br /&gt;
    -o smtpd_sasl_security_options=noanonymous&lt;br /&gt;
    -o smtpd_client_restrictions=$mua_client_restrictions&lt;br /&gt;
    -o smtpd_sender_restrictions=$mua_sender_restrictions&lt;br /&gt;
    -o smtpd_relay_restrictions=$mua_relay_restrictions&lt;br /&gt;
    -o milter_macro_daemon_name=ORIGINATING&lt;br /&gt;
    -o smtpd_sender_login_maps=proxy:mysql:/etc/postfix/sql/sender-login-maps.cf&lt;br /&gt;
    -o smtpd_helo_required=no&lt;br /&gt;
    -o smtpd_helo_restrictions=&lt;br /&gt;
    -o cleanup_service_name=submission-header-cleanup&lt;br /&gt;
###&lt;br /&gt;
### Submission-Zugang für Clients (mit STARTTLS - für Rückwärtskompatibilität) - Port 587&lt;br /&gt;
###&lt;br /&gt;
submission inet n       -       y       -       -       smtpd&lt;br /&gt;
    -o syslog_name=postfix/submission&lt;br /&gt;
    -o smtpd_tls_security_level=encrypt&lt;br /&gt;
    -o smtpd_sasl_auth_enable=yes&lt;br /&gt;
    -o smtpd_sasl_type=dovecot&lt;br /&gt;
    -o smtpd_sasl_path=private/auth&lt;br /&gt;
    -o smtpd_sasl_security_options=noanonymous&lt;br /&gt;
    -o smtpd_client_restrictions=$mua_client_restrictions&lt;br /&gt;
    -o smtpd_sender_restrictions=$mua_sender_restrictions&lt;br /&gt;
    -o smtpd_relay_restrictions=$mua_relay_restrictions&lt;br /&gt;
    -o milter_macro_daemon_name=ORIGINATING&lt;br /&gt;
    -o smtpd_sender_login_maps=proxy:mysql:/etc/postfix/sql/sender-login-maps.cf&lt;br /&gt;
    -o smtpd_helo_required=no&lt;br /&gt;
    -o smtpd_helo_restrictions=&lt;br /&gt;
    -o cleanup_service_name=submission-header-cleanup&lt;br /&gt;
###&lt;br /&gt;
### Weitere wichtige Dienste für den Serverbetrieb&lt;br /&gt;
###&lt;br /&gt;
pickup    unix  n       -       y       60      1       pickup&lt;br /&gt;
cleanup   unix  n       -       y       -       0       cleanup&lt;br /&gt;
qmgr      unix  n       -       n       300     1       qmgr&lt;br /&gt;
tlsmgr    unix  -       -       y       1000?   1       tlsmgr&lt;br /&gt;
rewrite   unix  -       -       y       -       -       trivial-rewrite&lt;br /&gt;
bounce    unix  -       -       y       -       0       bounce&lt;br /&gt;
defer     unix  -       -       y       -       0       bounce&lt;br /&gt;
trace     unix  -       -       y       -       0       bounce&lt;br /&gt;
verify    unix  -       -       y       -       1       verify&lt;br /&gt;
flush     unix  n       -       y       1000?   0       flush&lt;br /&gt;
proxymap  unix  -       -       n       -       -       proxymap&lt;br /&gt;
proxywrite unix -       -       n       -       1       proxymap&lt;br /&gt;
smtp      unix  -       -       y       -       -       smtp&lt;br /&gt;
relay     unix  -       -       y       -       -       smtp&lt;br /&gt;
showq     unix  n       -       y       -       -       showq&lt;br /&gt;
error     unix  -       -       y       -       -       error&lt;br /&gt;
retry     unix  -       -       y       -       -       error&lt;br /&gt;
discard   unix  -       -       y       -       -       discard&lt;br /&gt;
local     unix  -       n       n       -       -       local&lt;br /&gt;
virtual   unix  -       n       n       -       -       virtual&lt;br /&gt;
lmtp      unix  -       -       y       -       -       lmtp&lt;br /&gt;
anvil     unix  -       -       y       -       1       anvil&lt;br /&gt;
scache    unix  -       -       y       -       1       scache&lt;br /&gt;
###&lt;br /&gt;
### Cleanup-Service um MUA header zu entfernen&lt;br /&gt;
###&lt;br /&gt;
submission-header-cleanup unix n - n    -       0       cleanup&lt;br /&gt;
    -o header_checks=regexp:/etc/postfix/submission_header_cleanup&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;/pre&amp;gt;&amp;lt;p&amp;gt;Die &amp;lt;code&amp;gt;/etc/postfix/master.cf&amp;lt;/code&amp;gt; Datei will ich euch nur im Groben erklären. Wichtig zu wissen ist, dass hier die Definition und Konfiguration der verschiedenen Postfix-Dienste wie z.B. smtpd (eingehende SMTP-Verbindungen) und smtp (ausgehende SMTP-Verbindungen) passiert. Gut zu erkennen ist, dass über ein &amp;lt;code&amp;gt;-o&amp;lt;/code&amp;gt; weitere Parameter an einen Dienst übergeben werden. So beispielsweise beim &amp;lt;code&amp;gt;smtps&amp;lt;/code&amp;gt;-Dienst, der auf Port 465 für die SMTP-Kommunikation mit den Mailclients bereitsteht: Die hier angegebenen Einstellungen z.B. zu &amp;lt;code&amp;gt;smtpd_relay_restrictions&amp;lt;/code&amp;gt; überschreiben die Einstellungen in der main.cf – allerdings nur für diesen einen spezifischen Dienst! Ein gutes Beispiel ist die Einstellung &amp;lt;code&amp;gt;smtpd_tls_security_level=encrypt&amp;lt;/code&amp;gt;, die im Submission-Block steht. In der &amp;lt;code&amp;gt;main.cf&amp;lt;/code&amp;gt; hatten wir hier “may” definiert, um keine Server auszuschließen, die TLS nicht beherrschen. Da smtpd-Einstellungen aber sowohl für andere Server als auch für Mailclient gelten, wäre damit auch zu den Mailclients gesagt: “Ihr könnt verschlüsselte Verbindungen herstellen – müsst aber nicht”. Das wollen wir selbstverständlich nicht! Mailclients sollen eine verschlüsselte Verbindung herstellen müssen! Deshalb wird die smtpd-Einstellung speziell für den &amp;lt;code&amp;gt;smtps&amp;lt;/code&amp;gt;-Dienst mithilfe der &amp;lt;code&amp;gt;-o&amp;lt;/code&amp;gt; Option überschrieben und auf “encrypt” gesetzt.&amp;lt;/p&amp;gt;&amp;lt;p&amp;gt;Der &amp;lt;code&amp;gt;smtps&amp;lt;/code&amp;gt; Service am Anfang der Datei ist der SMTP-Dienst, zu dem sich Mailclients später verbinden sollen. Eine Verbindung ist hier nur über direktes TLS (nicht StartTLS!) möglich. Für Clients, die sich zu Port 587 verbinden wollen, steht weiterhin der &amp;lt;code&amp;gt;submission&amp;lt;/code&amp;gt; Service darunter bereit (auch wenn er in vielen Fällen nicht mehr notwendig sein sollte).&amp;lt;/p&amp;gt;&amp;lt;p&amp;gt;Für besseren Datenschutz wird der “Received”-Header (+ weitere Datenschutz-relevante Header) bei eingehenden E-Mails entfernt, wenn sie über den &amp;lt;code&amp;gt;smtps&amp;lt;/code&amp;gt;-Port eintreffen. Die meisten E-Mail-Clients senden ihren Namen und die Version mit. Zusätzlich vermerkt Postfix bei eingehenden E-Mails, von welcher IP-Adresse die E-Mail stammt. Auf diese Informationen können wir verzichten, deshalb werden sie mithilfe eines kleinen zusätzlichen Dienstes &amp;lt;code&amp;gt;submission-header-cleanup&amp;lt;/code&amp;gt; (am Ende der Konfiguration) aus der E-Mail gelöscht. Im &amp;lt;code&amp;gt;smtps&amp;lt;/code&amp;gt;- und Submission-Bereich wird via &amp;lt;code&amp;gt;cleanup_service_name&amp;lt;/code&amp;gt; festgelegt, dass bei eingehenden Mails auf diesen Services der Filter anzuwenden ist. Die Filterregeln befinden sich in der Datei &amp;lt;code&amp;gt;/etc/postfix/submission_header_cleanup&amp;lt;/code&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
=== Header Cleanup Regeln ===&lt;br /&gt;
&amp;lt;p&amp;gt;Unter &amp;lt;code&amp;gt;/etc/postfix/submission_header_cleanup&amp;lt;/code&amp;gt; wird eine Datei mit folgendem Inhalt angelegt:&amp;lt;/p&amp;gt;&amp;lt;pre&amp;gt;&amp;lt;code&amp;gt;### Entfernt Datenschutz-relevante Header aus E-Mails von MTUAs&lt;br /&gt;
&lt;br /&gt;
/^Received:/            IGNORE&lt;br /&gt;
/^X-Originating-IP:/    IGNORE&lt;br /&gt;
/^X-Mailer:/            IGNORE&lt;br /&gt;
/^User-Agent:/          IGNORE&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;/pre&amp;gt;&lt;br /&gt;
=== SQL-Konfiguration ===&lt;br /&gt;
&amp;lt;p&amp;gt;Neben der Haupt-Konfiguration main.cf und der Service-Konfiguration master.cf werden noch ein paar Konfigurationsdateien innerhalb des Unterverzeichnisses &amp;lt;code&amp;gt;sql/&amp;lt;/code&amp;gt; angelegt, die die SQL-Queries für die Datenabfragen an die Datenbank enthalten:&amp;lt;/p&amp;gt;&amp;lt;pre&amp;gt;&amp;lt;code&amp;gt;mkdir /etc/postfix/sql &amp;amp;&amp;amp; cd $_&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;/pre&amp;gt;&amp;lt;p&amp;gt;Erstellt dann die folgenden Konfigurationsdateien mit dem zugehörigen Inhalt:&amp;lt;/p&amp;gt;&amp;lt;p&amp;gt;&amp;lt;code&amp;gt;accounts.cf&amp;lt;/code&amp;gt;&amp;lt;/p&amp;gt;&amp;lt;pre&amp;gt;&amp;lt;code&amp;gt;user = vmail&lt;br /&gt;
password = vmaildbpass&lt;br /&gt;
hosts = unix:/run/mysqld/mysqld.sock&lt;br /&gt;
dbname = vmail&lt;br /&gt;
query = select 1 as found from accounts where username = '%u' and domain = '%d' and enabled = true LIMIT 1;&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;/pre&amp;gt;&amp;lt;p&amp;gt;&amp;lt;code&amp;gt;aliases.cf&amp;lt;/code&amp;gt;&amp;lt;/p&amp;gt;&amp;lt;pre&amp;gt;&amp;lt;code&amp;gt;user = vmail&lt;br /&gt;
password = vmaildbpass&lt;br /&gt;
hosts = unix:/run/mysqld/mysqld.sock&lt;br /&gt;
dbname = vmail&lt;br /&gt;
query = SELECT DISTINCT concat(destination_username, '@', destination_domain) AS destinations FROM aliases&lt;br /&gt;
        WHERE (source_username = '%u' OR source_username IS NULL) AND source_domain = '%d'&lt;br /&gt;
        AND enabled = true&lt;br /&gt;
        AND NOT EXISTS (SELECT id FROM accounts WHERE username = '%u' and domain = '%d');&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;/pre&amp;gt;&amp;lt;p&amp;gt;&amp;lt;code&amp;gt;domains.cf&amp;lt;/code&amp;gt;&amp;lt;/p&amp;gt;&amp;lt;pre&amp;gt;&amp;lt;code&amp;gt;user = vmail&lt;br /&gt;
password = vmaildbpass&lt;br /&gt;
hosts = unix:/run/mysqld/mysqld.sock&lt;br /&gt;
dbname = vmail&lt;br /&gt;
query = SELECT domain FROM domains WHERE domain='%s';&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;/pre&amp;gt;&amp;lt;p&amp;gt;&amp;lt;code&amp;gt;recipient-access.cf&amp;lt;/code&amp;gt;&amp;lt;/p&amp;gt;&amp;lt;pre&amp;gt;&amp;lt;code&amp;gt;user = vmail&lt;br /&gt;
password = vmaildbpass&lt;br /&gt;
hosts = unix:/run/mysqld/mysqld.sock&lt;br /&gt;
dbname = vmail&lt;br /&gt;
query = select if(sendonly = true, 'REJECT', 'OK') AS access from accounts where username = '%u' and domain = '%d' and enabled = true LIMIT 1;&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;/pre&amp;gt;&amp;lt;p&amp;gt;&amp;lt;code&amp;gt;sender-login-maps.cf&amp;lt;/code&amp;gt;&amp;lt;/p&amp;gt;&amp;lt;pre&amp;gt;&amp;lt;code&amp;gt;user = vmail&lt;br /&gt;
password = vmaildbpass&lt;br /&gt;
hosts = unix:/run/mysqld/mysqld.sock&lt;br /&gt;
dbname = vmail&lt;br /&gt;
query = select concat(username, '@', domain) as 'owns' from accounts where username = '%u' AND domain = '%d' and enabled = true union select &lt;br /&gt;
        concat(destination_username, '@', destination_domain) AS 'owns' from aliases &lt;br /&gt;
        where source_username = '%u' and source_domain = '%d' and enabled = true;&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;/pre&amp;gt;&amp;lt;p&amp;gt;&amp;lt;code&amp;gt;tls-policy.cf&amp;lt;/code&amp;gt;&amp;lt;/p&amp;gt;&amp;lt;pre&amp;gt;&amp;lt;code&amp;gt;user = vmail&lt;br /&gt;
password = vmaildbpass&lt;br /&gt;
hosts = unix:/run/mysqld/mysqld.sock&lt;br /&gt;
dbname = vmail&lt;br /&gt;
query = SELECT policy, params FROM tlspolicies WHERE domain = '%s';&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;/pre&amp;gt;&amp;lt;p&amp;gt;'''Vergesst nicht, &amp;lt;code&amp;gt;vmaildbpass&amp;lt;/code&amp;gt; in jeder der Dateien durch euer eigenes Passwort zu ersetzen!'''&amp;lt;/p&amp;gt;&amp;lt;p&amp;gt;Alle SQL-Konfgurationsdateien in &amp;lt;code&amp;gt;/etc/postfix/sql&amp;lt;/code&amp;gt; werden vor dem Zugriff durch unberechtigte User geschützt:&amp;lt;/p&amp;gt;&amp;lt;pre&amp;gt;&amp;lt;code&amp;gt;chown -R root:postfix /etc/postfix/sql&lt;br /&gt;
chmod g+x /etc/postfix/sql&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;/pre&amp;gt;&lt;br /&gt;
=== Weitere Postfix-Konfigurationsdateien ===&lt;br /&gt;
&amp;lt;p&amp;gt;Außerdem gibt es noch eine weitere Datei &amp;lt;code&amp;gt;/etc/postfix/without_ptr&amp;lt;/code&amp;gt;, die zunächst leer bleiben kann:&amp;lt;/p&amp;gt;&amp;lt;pre&amp;gt;&amp;lt;code&amp;gt;touch /etc/postfix/without_ptr&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;/pre&amp;gt;&amp;lt;p&amp;gt;Die Datei kann später einmal Einträge wie den folgenden beinhalten:&amp;lt;/p&amp;gt;&amp;lt;pre&amp;gt;&amp;lt;code&amp;gt;[2001:db8::beef] OK&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;/pre&amp;gt;&amp;lt;p&amp;gt;Der Server mit der IP &amp;lt;code&amp;gt;2001:db8::beef&amp;lt;/code&amp;gt; muss dann keinen gültigen PTR-Record (Reverse DNS) mehr besitzen und wird trotzdem akzeptiert. Die &amp;lt;code&amp;gt;without_ptr&amp;lt;/code&amp;gt;-Datei muss dann nach jeder Änderung in eine Datenbankdatei umgewandelt und Postfix neu geladen werden:&amp;lt;/p&amp;gt;&amp;lt;pre&amp;gt;&amp;lt;code&amp;gt;postmap /etc/postfix/without_ptr&lt;br /&gt;
systemctl reload postfix&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;/pre&amp;gt;&amp;lt;p&amp;gt;Im Moment reicht es aber aus, einfach nur eine leere Datenbankdatei zu generieren:&amp;lt;/p&amp;gt;&amp;lt;pre&amp;gt;&amp;lt;code&amp;gt;postmap /etc/postfix/without_ptr&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;/pre&amp;gt;&amp;lt;p&amp;gt;Zum Schluss wird einmal&amp;lt;/p&amp;gt;&amp;lt;pre&amp;gt;&amp;lt;code&amp;gt;newaliases&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;/pre&amp;gt;&amp;lt;p&amp;gt;ausgeführt, um die Alias-Datei &amp;lt;code&amp;gt;/etc/aliases.db&amp;lt;/code&amp;gt; zu generieren, die Postfix standardmäßig erwartet.&amp;lt;/p&amp;gt;&lt;br /&gt;
== Rspamd ==&lt;br /&gt;
&amp;lt;p&amp;gt;Da die Rspamd-Pakete für Debian nicht besonders aktuell sind und&amp;lt;/p&amp;gt;[https://rspamd.com/downloads.html#debian-standard-repos-notes offiziell davon abgeraten wird]&amp;lt;p&amp;gt;, diese zu nutzen, nutzen wir an dieser Stelle das Debian-Repository des Rspamd-Projekts:&amp;lt;/p&amp;gt;&amp;lt;pre&amp;gt;&amp;lt;code&amp;gt;apt install -y lsb-release wget&lt;br /&gt;
wget -O- https://rspamd.com/apt-stable/gpg.key | apt-key add -&lt;br /&gt;
echo &amp;quot;deb http://rspamd.com/apt-stable/ $(lsb_release -c -s) main&amp;quot; &amp;amp;gt; /etc/apt/sources.list.d/rspamd.list&lt;br /&gt;
echo &amp;quot;deb-src http://rspamd.com/apt-stable/ $(lsb_release -c -s) main&amp;quot; &amp;amp;gt;&amp;amp;gt; /etc/apt/sources.list.d/rspamd.list&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;/pre&amp;gt;&amp;lt;p&amp;gt;Paketquellen aktualisieren und Rspamd installieren&amp;lt;/p&amp;gt;&amp;lt;pre&amp;gt;&amp;lt;code&amp;gt;apt update&lt;br /&gt;
apt install rspamd&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;/pre&amp;gt;&amp;lt;p&amp;gt;Rspamd stoppen:&amp;lt;/p&amp;gt;&amp;lt;pre&amp;gt;&amp;lt;code&amp;gt;systemctl stop rspamd&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;/pre&amp;gt;&amp;lt;figure&amp;gt;&amp;lt;figcaption&amp;gt;Rspamd Webinterface&amp;lt;/figcaption&amp;gt;&amp;lt;/figure&amp;gt;&lt;br /&gt;
=== Grundkonfiguration ===&lt;br /&gt;
&amp;lt;p&amp;gt;Die Konfiguration von Rspamd wird im Verzeichnis &amp;lt;code&amp;gt;/etc/rspamd/local.d/&amp;lt;/code&amp;gt; abgelegt. Die folgenden Konfigurationsdateien werden darin erstellt:&amp;lt;/p&amp;gt;&amp;lt;p&amp;gt;&amp;lt;code&amp;gt;/etc/rspamd/local.d/worker-controller.inc&amp;lt;/code&amp;gt;: Einstellung des Worker controllers: Passwort für den Zugriff via Weboberfläche, z.B.:&amp;lt;/p&amp;gt;&amp;lt;pre&amp;gt;&amp;lt;code&amp;gt;password = &amp;quot;$2$qecacwgrz13owkag4gqcy5y7yeqh7yh4$y6i6gn5q3538tzsn19ojchuudoauw3rzdj1z74h5us4gd3jj5e8y&amp;quot;;&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;/pre&amp;gt;&amp;lt;p&amp;gt;Der Passworthash (&amp;lt;code&amp;gt;$2$qecacwg...&amp;lt;/code&amp;gt;) wird via&amp;lt;/p&amp;gt;&amp;lt;pre&amp;gt;&amp;lt;code&amp;gt;rspamadm pw&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;/pre&amp;gt;&amp;lt;p&amp;gt;generiert und in die Datei eingefügt. Vergesst nicht das abschließende &amp;lt;code&amp;gt;&amp;quot;;&amp;lt;/code&amp;gt;!&amp;lt;/p&amp;gt;&amp;lt;p&amp;gt;&amp;lt;code&amp;gt;/etc/rspamd/local.d/logging.inc&amp;lt;/code&amp;gt;: Error logging&amp;lt;/p&amp;gt;&amp;lt;pre&amp;gt;&amp;lt;code&amp;gt;type = &amp;quot;syslog&amp;quot;;&lt;br /&gt;
level = &amp;quot;warning&amp;quot;;&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;/pre&amp;gt;&amp;lt;p&amp;gt;Milter Headers &amp;lt;code&amp;gt;/etc/rspamd/local.d/milter_headers.conf&amp;lt;/code&amp;gt;&amp;lt;/p&amp;gt;&amp;lt;pre&amp;gt;&amp;lt;code&amp;gt;use = [&amp;quot;x-spamd-bar&amp;quot;, &amp;quot;x-spam-level&amp;quot;, &amp;quot;authentication-results&amp;quot;];&lt;br /&gt;
authenticated_headers = [&amp;quot;authentication-results&amp;quot;];&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;/pre&amp;gt;&amp;lt;p&amp;gt;Redis für den Bayes’schen Filter nutzen: &amp;lt;code&amp;gt;/etc/rspamd/local.d/classifier-bayes.conf&amp;lt;/code&amp;gt;&amp;lt;/p&amp;gt;&amp;lt;pre&amp;gt;&amp;lt;code&amp;gt;backend = &amp;quot;redis&amp;quot;;&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;/pre&amp;gt;&amp;lt;p&amp;gt;…und in &amp;lt;code&amp;gt;/etc/rspamd/local.d/redis.conf&amp;lt;/code&amp;gt;:&amp;lt;/p&amp;gt;&amp;lt;pre&amp;gt;&amp;lt;code&amp;gt;servers = &amp;quot;127.0.0.1&amp;quot;;&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;/pre&amp;gt;&amp;lt;p&amp;gt;Für den Bayes’schen Filter (Textanalyse) wird “Auto-Learning” aktiviert:&amp;lt;/p&amp;gt;&amp;lt;p&amp;gt;&amp;lt;code&amp;gt;/etc/rspamd/override.d/classifier-bayes.conf&amp;lt;/code&amp;gt;:&amp;lt;/p&amp;gt;&amp;lt;pre&amp;gt;&amp;lt;code&amp;gt;autolearn = true;&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;/pre&amp;gt;&amp;lt;p&amp;gt;Wird eine E-Mail bereits beim Empfang abgelehnt, weil sie ausgrund der Metadaten offensichtlich von einem Spammer kommt, nutzt Rspamd die Gelegenheit und lernt, dass der Text in dieser E-Mail als Spam einzustufen ist. So wird die Erkennungsrate mit jeder Spammail besser. (&amp;lt;/p&amp;gt;[https://rspamd.com/doc/configuration/statistic.html https://rspamd.com/doc/configuration/statistic.html]&amp;lt;p&amp;gt;)&amp;lt;/p&amp;gt;&lt;br /&gt;
=== Manuell gepflegte Black-/Whitelists ===&lt;br /&gt;
&amp;lt;p&amp;gt;Über das Multimap-Modul kann das Verhalten von Rspamd für bestimmte E-Mail-Merkmale personalisiert gesteuert werden. Merkmale können zum Beispiel die Absender-IP-Adresse oder die Absendermailadresse sein. Für beide registrieren wir in &amp;lt;code&amp;gt;/etc/rspamd/local.d/multimap.conf&amp;lt;/code&amp;gt; jeweils eine Black- und eine Whitelist:&amp;lt;/p&amp;gt;&amp;lt;pre&amp;gt;&amp;lt;code&amp;gt;WHITELIST_IP {&lt;br /&gt;
    type = &amp;quot;ip&amp;quot;;&lt;br /&gt;
    map = &amp;quot;$CONFDIR/local.d/whitelist_ip.map&amp;quot;;&lt;br /&gt;
    description = &amp;quot;Local ip whitelist&amp;quot;;&lt;br /&gt;
    action = &amp;quot;accept&amp;quot;;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
WHITELIST_FROM {&lt;br /&gt;
        type = &amp;quot;from&amp;quot;;&lt;br /&gt;
        map = &amp;quot;$CONFDIR/local.d/whitelist_from.map&amp;quot;;&lt;br /&gt;
        description = &amp;quot;Local from whitelist&amp;quot;;&lt;br /&gt;
        action = &amp;quot;accept&amp;quot;;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
BLACKLIST_IP {&lt;br /&gt;
        type = &amp;quot;ip&amp;quot;;&lt;br /&gt;
        map = &amp;quot;$CONFDIR/local.d/blacklist_ip.map&amp;quot;;&lt;br /&gt;
        description = &amp;quot;Local ip blacklist&amp;quot;;&lt;br /&gt;
        action = &amp;quot;reject&amp;quot;;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
BLACKLIST_FROM {&lt;br /&gt;
        type = &amp;quot;from&amp;quot;;&lt;br /&gt;
        map = &amp;quot;$CONFDIR/local.d/blacklist_from.map&amp;quot;;&lt;br /&gt;
        description = &amp;quot;Local from blacklist&amp;quot;;&lt;br /&gt;
        action = &amp;quot;reject&amp;quot;;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;/pre&amp;gt;&amp;lt;p&amp;gt;Für alle vier Listen werden nun Listendateien erstellt:&amp;lt;/p&amp;gt;&amp;lt;pre&amp;gt;&amp;lt;code&amp;gt;cd /etc/rspamd/local.d&lt;br /&gt;
touch whitelist_ip.map&lt;br /&gt;
touch whitelist_from.map&lt;br /&gt;
touch blacklist_ip.map&lt;br /&gt;
touch blacklist_from.map&lt;br /&gt;
cd - &lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;/pre&amp;gt;&amp;lt;p&amp;gt;“IP”-Listen können IPv6- und IPv4-Adressen bzw. Adressbereiche enthalten - in jeder Zeile ein Eintrag. “From”-Listen enthalten vollständige Absendermailadressen. Die Listen können zunächst leer bleiben. Sie eignen sich gut, wenn man später einmal für einzelne Absender oder Server Ausnahmen einstellen möchte.&amp;lt;/p&amp;gt;&lt;br /&gt;
=== DKIM Signing ===&lt;br /&gt;
&amp;lt;p&amp;gt;Rspamd übernimmt auch das Signieren von ausgehenden E-Mails. Damit signiert werden kann, muss zunächst ein Signing Key generiert werden. Der Parameter &amp;lt;code&amp;gt;-s 2020&amp;lt;/code&amp;gt; gibt den sogenannten Selektor an - einen Namen für den Key (hier das Erstellungsjahr).&amp;lt;/p&amp;gt;&amp;lt;pre&amp;gt;&amp;lt;code&amp;gt;mkdir /var/lib/rspamd/dkim/&lt;br /&gt;
rspamadm dkim_keygen -b 2048 -s 2020 -k /var/lib/rspamd/dkim/2020.key &amp;amp;gt; /var/lib/rspamd/dkim/2020.txt&lt;br /&gt;
chown -R _rspamd:_rspamd /var/lib/rspamd/dkim&lt;br /&gt;
chmod 440 /var/lib/rspamd/dkim/*&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;/pre&amp;gt;&amp;lt;p&amp;gt;Zum Signing Key (&amp;lt;code&amp;gt;/var/lib/rspamd/dkim/2020.key&amp;lt;/code&amp;gt;) gehört ein dazu passender Public Key, welcher in Form eines vorbereiteten DNS-Records in der Datei &amp;lt;code&amp;gt;/var/lib/rspamd/dkim/2020.txt&amp;lt;/code&amp;gt; liegt.&amp;lt;/p&amp;gt;&amp;lt;p&amp;gt;DKIM Record ausgeben lassen:&amp;lt;/p&amp;gt;&amp;lt;pre&amp;gt;&amp;lt;code&amp;gt;cat /var/lib/rspamd/dkim/2020.txt&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;/pre&amp;gt;&amp;lt;p&amp;gt;Die Ausgabe sieht z.B. so aus:&amp;lt;/p&amp;gt;&amp;lt;pre&amp;gt;&amp;lt;code&amp;gt;2020._domainkey IN TXT ( &amp;quot;v=DKIM1; k=rsa; &amp;quot;&lt;br /&gt;
    &amp;quot;p=MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA2/al5HqXUpe+HUazCr6t9lv2VOZLR369PPB4t+dgljZQvgUsIKoYzfS/w9NagS32xZYxi1dtlDWuRfTU/ahHO2MYzE0zHE4lMfwb6VkNCG+pM6bAkCwc5cFvyRygwxAPEiHAtmtU5b0i9LY25Z/ZWgyBxEWZ0Wf+hLjYHvnvMqewPsduUqKVjDOdUqeBb1VAu3WFErOAGVUYfKqFX&amp;quot;&lt;br /&gt;
    &amp;quot;+yfz36Alb7/OMAort8A5Vo5t5k0vxTHzkYYg5KB6tLS8jngrNucGjyNL5+k0ijPs3yT7WpTGL3U3SEa8cX8WvOO1fIpWQz4yyZJJ1Mm62+FskSc7BHjdiMHE64Id/UBDDVjxwIDAQAB&amp;quot;&lt;br /&gt;
) ;&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;/pre&amp;gt;&amp;lt;p&amp;gt;Der Werte-Abschnitt des Records (beginnend mit &amp;lt;code&amp;gt;v=DKIM1&amp;lt;/code&amp;gt; bis zum Ende der Zeichenkolonne - hier &amp;lt;code&amp;gt;AQAB&amp;lt;/code&amp;gt;) muss in einen neuen DNS-Record gepflanzt werden. Dabei werden Zeilenumbrüche und Anführungsstriche entfernt. Je nach DNS-Hoster muss ein neuer Eintrag geringfügig anders formatiert werden. Ich habe den Schritt im Screenshot beispielhaft für den Hoster&amp;lt;/p&amp;gt;[https://www.core-networks.de/ Core-Networks.de]&amp;lt;p&amp;gt;mit dem Selector “2020” und meiner Beispieldomain “mysystems.tld” durchgeführt:&amp;lt;/p&amp;gt;&amp;lt;figure&amp;gt;&amp;lt;figcaption&amp;gt;core-networks.de Screenshot mit DKIM Record&amp;lt;/figcaption&amp;gt;&amp;lt;/figure&amp;gt;&amp;lt;p&amp;gt;Wichtig: Der Selektor “2020” wird im DNS-Record zusammen mit &amp;lt;code&amp;gt;._domainkey&amp;lt;/code&amp;gt; als Name verwendet! Der DKIM-Record muss '''für jede verwendete Domain (domain2.tld, domain2.tld) im jeweiligen Zonefile erstellt werden!'''&amp;lt;/p&amp;gt;&amp;lt;div class=&amp;quot;tip&amp;quot;&amp;gt;Sollte der Record vom DNS-Hoster nicht akzeptiert werden, hilft es in einigen Fällen, die Schlüssellänge von 2048 Bit auf 1024 Bit zu reduzieren. Dazu das &amp;lt;code&amp;gt;rspamadm dkim_keygen&amp;lt;/code&amp;gt;Kommando nochmals mit &amp;lt;code&amp;gt;-b 1024&amp;lt;/code&amp;gt; statt mit &amp;lt;code&amp;gt;-b 2048&amp;lt;/code&amp;gt; ausführen.&amp;lt;/div&amp;gt;&amp;lt;p&amp;gt;Der erzeugte DKIM-Key und der verwendete Selektor werden in der Konfigurationsdatei &amp;lt;code&amp;gt;/etc/rspamd/local.d/dkim_signing.conf&amp;lt;/code&amp;gt; angegeben:&amp;lt;/p&amp;gt;&amp;lt;pre&amp;gt;&amp;lt;code&amp;gt;path = &amp;quot;/var/lib/rspamd/dkim/$selector.key&amp;quot;;&lt;br /&gt;
selector = &amp;quot;2020&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
### Enable DKIM signing for alias sender addresses&lt;br /&gt;
allow_username_mismatch = true;&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;/pre&amp;gt;&amp;lt;p&amp;gt;Diese Konfiguration wird in die Datei &amp;lt;code&amp;gt;/etc/rspamd/local.d/arc.conf&amp;lt;/code&amp;gt; kopiert, sodass das&amp;lt;/p&amp;gt;[https://rspamd.com/doc/modules/arc.html ARC-Modul]&amp;lt;p&amp;gt;korrekt arbeiten kann. Es greift auf dieselben Einstellungen zurück:&amp;lt;/p&amp;gt;&amp;lt;pre&amp;gt;&amp;lt;code&amp;gt;cp -R /etc/rspamd/local.d/dkim_signing.conf /etc/rspamd/local.d/arc.conf&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;/pre&amp;gt;&lt;br /&gt;
== Redis als Cache und Key-Value Store für Rspamd-Module ==&lt;br /&gt;
&amp;lt;p&amp;gt;Rspamd verwendet Redis als Cache. Die Installation ist trivial:&amp;lt;/p&amp;gt;&amp;lt;pre&amp;gt;&amp;lt;code&amp;gt;apt install redis-server&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;/pre&amp;gt;&amp;lt;p&amp;gt;In der Rspamd-Konfiguration wurde Redis bereits als Caching-Datenbank eingetragen.&amp;lt;/p&amp;gt;&lt;br /&gt;
== Rspamd starten ==&lt;br /&gt;
&amp;lt;p&amp;gt;Rspamd kann nun gestartet werden:&amp;lt;/p&amp;gt;&amp;lt;pre&amp;gt;&amp;lt;code&amp;gt;systemctl start rspamd&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;/pre&amp;gt;&lt;br /&gt;
== Nginx Proxy für Rspamd Weboberfläche ==&lt;br /&gt;
&amp;lt;p&amp;gt;Für den bequemen und sicheren Zugriff auf die Rspamd-Weboberfläche kann dieser ein Nginx HTTP-Proxy vorgeschaltet werden. Nginx kümmert sich dann um die Absicherung der Verbindung via HTTPS. Wer nur selten auf die Rspamd-Weboberfläche zugreift, kann auf diesen Schritt verzichten und stattdessen auch über einen SSH-Tunnel auf das Interface zugreifen (&amp;lt;/p&amp;gt;[https://thomas-leister.de/mailserver-debian-buster/#ssh-tunnel siehe unten]&amp;lt;p&amp;gt;).&amp;lt;/p&amp;gt;&amp;lt;p&amp;gt;Für den Rspamd-Webproxy wird in &amp;lt;code&amp;gt;/etc/nginx/sites-available/mail.mysystems.tld&amp;lt;/code&amp;gt; ein &amp;lt;code&amp;gt;location&amp;lt;/code&amp;gt; Block wie folgt hinzugefügt:&amp;lt;/p&amp;gt;&amp;lt;pre&amp;gt;&amp;lt;code&amp;gt;server {&lt;br /&gt;
        listen 80;&lt;br /&gt;
        listen [::]:80;&lt;br /&gt;
        listen 443 ssl http2;&lt;br /&gt;
        listen [::]:443 ssl http2;&lt;br /&gt;
&lt;br /&gt;
        server_name mail.mysystems.tld imap.mysystems.tld smtp.mysystems.tld;&lt;br /&gt;
&lt;br /&gt;
        ssl_certificate /etc/acme.sh/mail.mysystems.tld/fullchain.pem;&lt;br /&gt;
        ssl_certificate_key /etc/acme.sh/mail.mysystems.tld/privkey.pem;&lt;br /&gt;
&lt;br /&gt;
        add_header Strict-Transport-Security max-age=15768000;&lt;br /&gt;
&lt;br /&gt;
        location /rspamd/ {&lt;br /&gt;
                proxy_pass http://localhost:11334/;&lt;br /&gt;
                proxy_set_header Host $host;&lt;br /&gt;
                proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
        if ($ssl_protocol = &amp;quot;&amp;quot;) {&lt;br /&gt;
            return 301 https://$server_name$request_uri;&lt;br /&gt;
        }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;/pre&amp;gt;&amp;lt;p&amp;gt;Anzupassen:&amp;lt;/p&amp;gt;&lt;br /&gt;
*ssl_certificate: Pfad zu Zertifikat&lt;br /&gt;
*ssl_certificate_key: Pfad zu Zertifikat&lt;br /&gt;
*server_name&lt;br /&gt;
&amp;lt;p&amp;gt;Konfiguration testen und Nginx neu laden:&amp;lt;/p&amp;gt;&amp;lt;pre&amp;gt;&amp;lt;code&amp;gt;nginx -t&lt;br /&gt;
systemctl reload nginx&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;/pre&amp;gt;&lt;br /&gt;
== Weboberfläche aufrufen ==&lt;br /&gt;
&amp;lt;p&amp;gt;Unter&amp;lt;/p&amp;gt;[https://mail.mysystems.tld/rspamd/ https://mail.mysystems.tld/rspamd/]&amp;lt;p&amp;gt;ist die Rspamd-Weboberfläche nun erreichbar. Als Passwort wird das weiter oben erzeugte Passwort für die Weboberfläche verwendet.&amp;lt;/p&amp;gt;&lt;br /&gt;
== Via SSH-Tunnel mit der Weboberfläche verbinden (Alternative) ==&lt;br /&gt;
&amp;lt;p&amp;gt;Statt über Nginx kann man auch mithilfe eines SSH-Tunnels eine sichere Verbindung zur Rspamd-Weboberfläche aufbauen. Dazu benötigt man auf dem lokalen Rechner allerdings einen SSH-Client. Der SSH-Befehl&amp;lt;/p&amp;gt;&amp;lt;pre&amp;gt;&amp;lt;code&amp;gt;ssh -L 8080:localhost:11334 benutzer@mail.mysystems.tld -N&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;/pre&amp;gt;&amp;lt;p&amp;gt;verknüpft den Port des Webinterfaces (&amp;lt;code&amp;gt;11334&amp;lt;/code&amp;gt;) mit Port &amp;lt;code&amp;gt;8080&amp;lt;/code&amp;gt; des lokalen Systems. Im lokalen Webbrowser kann die Oberfläche nun unter http://localhost:8080 erreicht werden. Mit STRG+C wird die Verbindung wieder getrennt.&amp;lt;/p&amp;gt;&lt;br /&gt;
== Rspamd mit bestehenden Spam-E-Mails trainieren (optional) ==&lt;br /&gt;
&amp;lt;p&amp;gt;Wer einige Mails im Maildir-Format (jede E-Mail ist eine Datei) vorliegen hat, kann Rspamd mit über das rspamc-Werkzeug trainieren. Dabei ist es ist vorteilhaft, nicht nur Spammail-Beispiele zu trainieren, sondern auch Beispiele für erwünschte E-Mails. Im folgenden Beispiel wurde das Mailbox-Verzeichnis eines älteren Mailservers importiert:&amp;lt;/p&amp;gt;&amp;lt;p&amp;gt;E-Mails in einem Verzeichnis als '''Spam''' antrainieren:&amp;lt;/p&amp;gt;&amp;lt;pre&amp;gt;&amp;lt;code&amp;gt;find ./oldserver/var/vmail/mailboxes/*/*/mail/Spam/cur -type f -exec /usr/bin/rspamc learn_spam {} \;&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;/pre&amp;gt;&amp;lt;p&amp;gt;E-Mails in einem Verzeichnis als '''Ham''' (harmlos) antrainieren:&amp;lt;/p&amp;gt;&amp;lt;pre&amp;gt;&amp;lt;code&amp;gt;find ./oldserver/var/vmail/mailboxes/*/*/mail/cur -type f -exec /usr/bin/rspamc learn_ham {} \;&lt;br /&gt;
find ./oldserver/var/vmail/mailboxes/*/*/mail/Sent/cur -type f -exec /usr/bin/rspamc learn_ham {} \;&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;/pre&amp;gt;&amp;lt;p&amp;gt;Auf der Rspamd-Weboberfläche wird nach dem Training eine entsprechend höhere Anzahl an gelernten E-Mails angezeigt.&amp;lt;/p&amp;gt;&lt;br /&gt;
== Autoconfig für Mozilla Thunderbird (Optional) ==&lt;br /&gt;
&amp;lt;p&amp;gt;Mozilla Thunderbird (und andere Mailclients) versuchen bei der Einrichtung eines neuen Mailkontos automatisch, die korrekten Adressen und Einstellungen für IMAP- und SMTP-Server zu&amp;lt;/p&amp;gt;[https://developer.mozilla.org/en-US/docs/Mozilla/Thunderbird/Autoconfiguration ermitteln]&amp;lt;p&amp;gt;. Die Autokonfiguration gibt uns die Möglichkeit, unter einer festgelegten Adresse &amp;lt;code&amp;gt;https://autoconfig.&amp;amp;lt;maildomain&amp;amp;gt;.tld/mail/config-v1.1.xml&amp;lt;/code&amp;gt;Informationen zum Mailserver zu hinterlegen, sodass der Benutzer bei der Verknüpfung seines Mailkontos nichts anderes als seine Mailadresse und das Passwort anzugeben braucht. Alle weiteren Informationen wie z.B. Art der Verschlüsselung oder Port bezieht Thunderbird aus der XML-Datei.&amp;lt;/p&amp;gt;&amp;lt;p&amp;gt;Da die Servereinstellungen in diesem Setup für alle Domains identisch sind, soll die XML-Datei unter &amp;lt;code&amp;gt;https://autoconfig.mysystems.tld/mail/config-v1.1.xml&amp;lt;/code&amp;gt; zentral auf dem Mailserver verfügbar gemacht werden. Sollten neben der “mysystems.tld” Domain noch die Domains “domain1.tld” und “domain2.tld” für E-Mail mitgenutzt werden, kann mittels HTTP-Proxies auf den Zielservern dieser Domains auf die zentrale Adresse weitergeleitet werden. Doch zunächst soll es nur um den mail.mysystems.tld Mailserver gehen …&amp;lt;/p&amp;gt;&lt;br /&gt;
=== DNS-Record anlegen ===&lt;br /&gt;
&amp;lt;p&amp;gt;Für die neue autoconfig.mysystems.tld Subdomain wird ein passender CNAME-Record im DNS angelegt, welcher auf den Mailserver zeigt:&amp;lt;/p&amp;gt;&amp;lt;pre&amp;gt;&amp;lt;code&amp;gt;autoconfig.mysystems.tld. 86400 IN CNAME mail.mysystems.tld.&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;/pre&amp;gt;&lt;br /&gt;
=== Autoconfig auf dem Mailserver einrichten ===&lt;br /&gt;
&amp;lt;p&amp;gt;Um die Datei auf dem Server anzubieten, wird ein weiterer Virtual Host für den Nginx-Webserver angelegt:&amp;lt;/p&amp;gt;&amp;lt;p&amp;gt;&amp;lt;code&amp;gt;/etc/nginx/sites-available/autoconfig.mysystems.tld&amp;lt;/code&amp;gt;&amp;lt;/p&amp;gt;&amp;lt;pre&amp;gt;&amp;lt;code&amp;gt;server {&lt;br /&gt;
        listen 80;&lt;br /&gt;
        listen [::]:80;&lt;br /&gt;
#        listen 443 ssl http2;&lt;br /&gt;
#        listen [::]:443 ssl http2;&lt;br /&gt;
&lt;br /&gt;
        server_name autoconfig.mysystems.tld;&lt;br /&gt;
&lt;br /&gt;
#        ssl_certificate /etc/acme.sh/autoconfig.mysystems.tld/fullchain.pem;&lt;br /&gt;
#        ssl_certificate_key /etc/acme.sh/autoconfig.mysystems.tld/privkey.pem;&lt;br /&gt;
&lt;br /&gt;
#        add_header Strict-Transport-Security max-age=15768000;&lt;br /&gt;
&lt;br /&gt;
#        if ($ssl_protocol = &amp;quot;&amp;quot;) {&lt;br /&gt;
#            return 301 https://$server_name$request_uri;&lt;br /&gt;
#        }&lt;br /&gt;
&lt;br /&gt;
        root /var/www/mysystems.tld/autoconfig.mysystems.tld;&lt;br /&gt;
&lt;br /&gt;
        location / {&lt;br /&gt;
                add_header Content-Type text/xml;&lt;br /&gt;
                charset utf-8;&lt;br /&gt;
        }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;/pre&amp;gt;&amp;lt;p&amp;gt;''Wie auch bei der ersten Nginx-Konfiguration sind hier zunächst ein paar Zeilen auskommentiert, weil noch keine passenden TLS-Zertifikate vorhanden sind.''&amp;lt;/p&amp;gt;&amp;lt;p&amp;gt;Konfiguration aktivieren, Nginx Config prüfen und neu laden:&amp;lt;/p&amp;gt;&amp;lt;pre&amp;gt;&amp;lt;code&amp;gt;ln -s /etc/nginx/sites-available/autoconfig.mysystems.tld /etc/nginx/sites-enabled/autoconfig.mysystems.tld&lt;br /&gt;
nginx -t&lt;br /&gt;
systemctl reload nginx&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;/pre&amp;gt;&amp;lt;p&amp;gt;Für den neuen vHost wird ein Webroot directory angelegt:&amp;lt;/p&amp;gt;&amp;lt;pre&amp;gt;&amp;lt;code&amp;gt;mkdir -p /var/www/mysystems.tld/autoconfig.mysystems.tld/mail/&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;/pre&amp;gt;&amp;lt;p&amp;gt;und die XML-Konfiguration darin abgelegt:&amp;lt;/p&amp;gt;&amp;lt;p&amp;gt;&amp;lt;code&amp;gt;config-v1.1.xml&amp;lt;/code&amp;gt;&amp;lt;/p&amp;gt;&amp;lt;pre&amp;gt;&amp;lt;code&amp;gt;&amp;amp;lt;?xml version=&amp;quot;1.0&amp;quot; encoding=&amp;quot;UTF-8&amp;quot;?&amp;amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;amp;lt;clientConfig version=&amp;quot;1.1&amp;quot;&amp;amp;gt;&lt;br /&gt;
  &amp;amp;lt;emailProvider id=&amp;quot;mysystems.tld&amp;quot;&amp;amp;gt;&lt;br /&gt;
    &amp;amp;lt;domain&amp;amp;gt;mysystems.tld&amp;amp;lt;/domain&amp;amp;gt;&lt;br /&gt;
    &amp;amp;lt;displayName&amp;amp;gt;mysystems.tld Mail&amp;amp;lt;/displayName&amp;amp;gt;&lt;br /&gt;
    &amp;amp;lt;displayShortName&amp;amp;gt;mysystems.tld&amp;amp;lt;/displayShortName&amp;amp;gt;&lt;br /&gt;
    &amp;amp;lt;incomingServer type=&amp;quot;imap&amp;quot;&amp;amp;gt;&lt;br /&gt;
      &amp;amp;lt;hostname&amp;amp;gt;imap.mysystems.tld&amp;amp;lt;/hostname&amp;amp;gt;&lt;br /&gt;
      &amp;amp;lt;port&amp;amp;gt;993&amp;amp;lt;/port&amp;amp;gt;&lt;br /&gt;
      &amp;amp;lt;socketType&amp;amp;gt;SSL&amp;amp;lt;/socketType&amp;amp;gt;&lt;br /&gt;
      &amp;amp;lt;authentication&amp;amp;gt;password-cleartext&amp;amp;lt;/authentication&amp;amp;gt;&lt;br /&gt;
      &amp;amp;lt;username&amp;amp;gt;%EMAILADDRESS%&amp;amp;lt;/username&amp;amp;gt;&lt;br /&gt;
    &amp;amp;lt;/incomingServer&amp;amp;gt;&lt;br /&gt;
    &amp;amp;lt;outgoingServer type=&amp;quot;smtp&amp;quot;&amp;amp;gt;&lt;br /&gt;
      &amp;amp;lt;hostname&amp;amp;gt;smtp.mysystems.tld&amp;amp;lt;/hostname&amp;amp;gt;&lt;br /&gt;
      &amp;amp;lt;port&amp;amp;gt;465&amp;amp;lt;/port&amp;amp;gt;&lt;br /&gt;
      &amp;amp;lt;socketType&amp;amp;gt;SSL&amp;amp;lt;/socketType&amp;amp;gt;&lt;br /&gt;
      &amp;amp;lt;authentication&amp;amp;gt;password-cleartext&amp;amp;lt;/authentication&amp;amp;gt;&lt;br /&gt;
      &amp;amp;lt;username&amp;amp;gt;%EMAILADDRESS%&amp;amp;lt;/username&amp;amp;gt;&lt;br /&gt;
    &amp;amp;lt;/outgoingServer&amp;amp;gt;&lt;br /&gt;
  &amp;amp;lt;/emailProvider&amp;amp;gt;&lt;br /&gt;
&amp;amp;lt;/clientConfig&amp;amp;gt;&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;/pre&amp;gt;&amp;lt;p&amp;gt;Nun wird für autoconfig.mysystems.tld noch ein DNS-Record angelegt:&amp;lt;/p&amp;gt;&amp;lt;pre&amp;gt;&amp;lt;code&amp;gt;autoconfig.mysystems.tld IN CNAME mail.mysystems.tld.&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;/pre&amp;gt;&amp;lt;p&amp;gt;TLS-Zertifikat beantragen und installieren:&amp;lt;/p&amp;gt;&amp;lt;pre&amp;gt;&amp;lt;code&amp;gt;acme.sh --issue --server letsencrypt --nginx -d autoconfig.mysystems.tld&lt;br /&gt;
mkdir -p /etc/acme.sh/autoconfig.mysystems.tld&lt;br /&gt;
acme.sh --install-cert -d autoconfig.mysystems.tld \&lt;br /&gt;
    --key-file /etc/acme.sh/autoconfig.mysystems.tld/privkey.pem  \&lt;br /&gt;
    --fullchain-file /etc/acme.sh/autoconfig.mysystems.tld/fullchain.pem \&lt;br /&gt;
    --reloadcmd &amp;quot;systemctl reload nginx&amp;quot;&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;/pre&amp;gt;&amp;lt;p&amp;gt;'''Die auskommentierten Zeilen können nun entfernt und Nginx neu geladen werden:'''&amp;lt;/p&amp;gt;&amp;lt;pre&amp;gt;&amp;lt;code&amp;gt;systemctl reload nginx&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;/pre&amp;gt;&lt;br /&gt;
=== Optional: Autoconfig Proxy für weitere Maildomains einrichten ===&lt;br /&gt;
&amp;lt;p&amp;gt;Auf den (Web-)Servern, auf welche die weiteren Domains “domain1.tld” und “domain2.tld” verweisen, wird im Nginx jeweils ein vHost für “autoconfig.domain1.tld” bzw. “autoconfig.domain2.tld” angelegt:&amp;lt;/p&amp;gt;&amp;lt;p&amp;gt;&amp;lt;code&amp;gt;/etc/nginx/sites-available/autoconfig.domain1.tld&amp;lt;/code&amp;gt;&amp;lt;/p&amp;gt;&amp;lt;pre&amp;gt;&amp;lt;code&amp;gt;server {&lt;br /&gt;
        listen 80;&lt;br /&gt;
        listen [::]:80;&lt;br /&gt;
#       listen 443 ssl http2;&lt;br /&gt;
#       listen [::]:443 ssl http2;&lt;br /&gt;
&lt;br /&gt;
        server_name autoconfig.domain1.tld;&lt;br /&gt;
&lt;br /&gt;
#       ssl_certificate /etc/acme.sh/autoconfig.mysystems.tld/fullchain.pem;&lt;br /&gt;
#       ssl_certificate_key /etc/acme.sh/autoconfig.mysystems.tld/key.pem;&lt;br /&gt;
&lt;br /&gt;
#       add_header Strict-Transport-Security max-age=15768000;&lt;br /&gt;
&lt;br /&gt;
#       if ($ssl_protocol = &amp;quot;&amp;quot;) {&lt;br /&gt;
#           return 301 https://$server_name$request_uri;&lt;br /&gt;
#       }      &lt;br /&gt;
&lt;br /&gt;
        location / {&lt;br /&gt;
                proxy_pass https://[fd80::1]:443;&lt;br /&gt;
                proxy_set_header HOST $host;&lt;br /&gt;
        }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;/pre&amp;gt;&amp;lt;p&amp;gt;Anzupassen:&amp;lt;/p&amp;gt;&lt;br /&gt;
*&amp;lt;code&amp;gt;server_name&amp;lt;/code&amp;gt;&lt;br /&gt;
*IP-Adresse des Mailsystems &amp;lt;code&amp;gt;mail.mysytems.tld&amp;lt;/code&amp;gt; bei &amp;lt;code&amp;gt;proxy_pass&amp;lt;/code&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;''Die &amp;lt;code&amp;gt;proxy_pass&amp;lt;/code&amp;gt; Anweisung nutzt die IPv6-Adresse &amp;lt;code&amp;gt;fd::80&amp;lt;/code&amp;gt; statt des Hostnamens unseres Mailservers, da Nginx direkt nach dem Booten noch keinen DNS-Resolver zur Namensauflösung verfügbar hat.''&amp;lt;/p&amp;gt;&amp;lt;p&amp;gt;Ein DNS-Eintrag für die neue Subdomain darf nicht fehlen:&amp;lt;/p&amp;gt;&amp;lt;pre&amp;gt;&amp;lt;code&amp;gt;autoconfig.domain1.tld IN CNAME domain1.tld.&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;/pre&amp;gt;&amp;lt;p&amp;gt;Auch dieser VirtualHost sollte mit einem passenden TLS-Zertifikat abgesichert werden:&amp;lt;/p&amp;gt;&amp;lt;pre&amp;gt;&amp;lt;code&amp;gt;acme.sh --issue --server letsencrypt --nginx -d autoconfig.domain1.tld&lt;br /&gt;
mkdir -p /etc/acme.sh/autoconfig.domain1.tld&lt;br /&gt;
acme.sh --install-cert -d autoconfig.domain1.tld \&lt;br /&gt;
    --key-file /etc/acme.sh/autoconfig.domain1.tld/privkey.pem  \&lt;br /&gt;
    --fullchain-file /etc/acme.sh/autoconfig.domain1.tld/fullchain.pem \&lt;br /&gt;
    --reloadcmd &amp;quot;systemctl reload nginx&amp;quot;&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;/pre&amp;gt;&amp;lt;p&amp;gt;Die auskommentierten Zeilen in der Nginx Konfiguration können nun auskommentiert werden.&amp;lt;/p&amp;gt;&amp;lt;p&amp;gt;Aktivieren der Konfiguration und Neuladen des Webservers:&amp;lt;/p&amp;gt;&amp;lt;pre&amp;gt;&amp;lt;code&amp;gt;ln -s /etc/nginx/sites-available/autoconfig.domain1.tld /etc/nginx/sites-enabled/autoconfig.domain1.tld&lt;br /&gt;
nginx -t&lt;br /&gt;
systemctl reload nginx&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;/pre&amp;gt;&amp;lt;p&amp;gt;Ein Aufruf von&amp;lt;/p&amp;gt;[https://autoconfig.domain1.tld/mail/config-v1.1.xml https://autoconfig.domain1.tld/mail/config-v1.1.xml]&amp;lt;p&amp;gt;sollte nun dieselbe XML-Datei anzeigen, die bereits auf dem Mailserver unter &amp;lt;code&amp;gt;autoconfig.mysystems.tld&amp;lt;/code&amp;gt; hinterlegt wurde. Diese XML-Datei muss nun analog zu &amp;lt;code&amp;gt;mysystems.tld&amp;lt;/code&amp;gt; um &amp;lt;code&amp;gt;domain1.tld&amp;lt;/code&amp;gt; erweitert werden, z.B. so:&amp;lt;/p&amp;gt;&amp;lt;pre&amp;gt;&amp;lt;code&amp;gt;&amp;amp;lt;?xml version=&amp;quot;1.0&amp;quot; encoding=&amp;quot;UTF-8&amp;quot;?&amp;amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;amp;lt;clientConfig version=&amp;quot;1.1&amp;quot;&amp;amp;gt;&lt;br /&gt;
  &amp;amp;lt;emailProvider id=&amp;quot;mysystems.tld&amp;quot;&amp;amp;gt;&lt;br /&gt;
    &amp;amp;lt;domain&amp;amp;gt;mysystems.tld&amp;amp;lt;/domain&amp;amp;gt;&lt;br /&gt;
    &amp;amp;lt;displayName&amp;amp;gt;mysystems.tld Mail&amp;amp;lt;/displayName&amp;amp;gt;&lt;br /&gt;
    &amp;amp;lt;displayShortName&amp;amp;gt;mysystems.tld&amp;amp;lt;/displayShortName&amp;amp;gt;&lt;br /&gt;
    &amp;amp;lt;incomingServer type=&amp;quot;imap&amp;quot;&amp;amp;gt;&lt;br /&gt;
      &amp;amp;lt;hostname&amp;amp;gt;imap.mysystems.tld&amp;amp;lt;/hostname&amp;amp;gt;&lt;br /&gt;
      &amp;amp;lt;port&amp;amp;gt;993&amp;amp;lt;/port&amp;amp;gt;&lt;br /&gt;
      &amp;amp;lt;socketType&amp;amp;gt;SSL&amp;amp;lt;/socketType&amp;amp;gt;&lt;br /&gt;
      &amp;amp;lt;authentication&amp;amp;gt;password-cleartext&amp;amp;lt;/authentication&amp;amp;gt;&lt;br /&gt;
      &amp;amp;lt;username&amp;amp;gt;%EMAILADDRESS%&amp;amp;lt;/username&amp;amp;gt;&lt;br /&gt;
    &amp;amp;lt;/incomingServer&amp;amp;gt;&lt;br /&gt;
    &amp;amp;lt;outgoingServer type=&amp;quot;smtp&amp;quot;&amp;amp;gt;&lt;br /&gt;
      &amp;amp;lt;hostname&amp;amp;gt;smtp.mysystems.tld&amp;amp;lt;/hostname&amp;amp;gt;&lt;br /&gt;
      &amp;amp;lt;port&amp;amp;gt;465&amp;amp;lt;/port&amp;amp;gt;&lt;br /&gt;
      &amp;amp;lt;socketType&amp;amp;gt;SSL&amp;amp;lt;/socketType&amp;amp;gt;&lt;br /&gt;
      &amp;amp;lt;authentication&amp;amp;gt;password-cleartext&amp;amp;lt;/authentication&amp;amp;gt;&lt;br /&gt;
      &amp;amp;lt;username&amp;amp;gt;%EMAILADDRESS%&amp;amp;lt;/username&amp;amp;gt;&lt;br /&gt;
    &amp;amp;lt;/outgoingServer&amp;amp;gt;&lt;br /&gt;
  &amp;amp;lt;/emailProvider&amp;amp;gt;&lt;br /&gt;
&lt;br /&gt;
  &amp;amp;lt;emailProvider id=&amp;quot;domain1.tld&amp;quot;&amp;amp;gt;&lt;br /&gt;
    &amp;amp;lt;domain&amp;amp;gt;domain1.tld&amp;amp;lt;/domain&amp;amp;gt;&lt;br /&gt;
    &amp;amp;lt;displayName&amp;amp;gt;domain1.tld Mail&amp;amp;lt;/displayName&amp;amp;gt;&lt;br /&gt;
    &amp;amp;lt;displayShortName&amp;amp;gt;domain1.tld&amp;amp;lt;/displayShortName&amp;amp;gt;&lt;br /&gt;
    &amp;amp;lt;incomingServer type=&amp;quot;imap&amp;quot;&amp;amp;gt;&lt;br /&gt;
      &amp;amp;lt;hostname&amp;amp;gt;imap.mysystems.tld&amp;amp;lt;/hostname&amp;amp;gt;&lt;br /&gt;
      &amp;amp;lt;port&amp;amp;gt;993&amp;amp;lt;/port&amp;amp;gt;&lt;br /&gt;
      &amp;amp;lt;socketType&amp;amp;gt;SSL&amp;amp;lt;/socketType&amp;amp;gt;&lt;br /&gt;
      &amp;amp;lt;authentication&amp;amp;gt;password-cleartext&amp;amp;lt;/authentication&amp;amp;gt;&lt;br /&gt;
      &amp;amp;lt;username&amp;amp;gt;%EMAILADDRESS%&amp;amp;lt;/username&amp;amp;gt;&lt;br /&gt;
    &amp;amp;lt;/incomingServer&amp;amp;gt;&lt;br /&gt;
    &amp;amp;lt;outgoingServer type=&amp;quot;smtp&amp;quot;&amp;amp;gt;&lt;br /&gt;
      &amp;amp;lt;hostname&amp;amp;gt;smtp.mysystems.tld&amp;amp;lt;/hostname&amp;amp;gt;&lt;br /&gt;
      &amp;amp;lt;port&amp;amp;gt;465&amp;amp;lt;/port&amp;amp;gt;&lt;br /&gt;
      &amp;amp;lt;socketType&amp;amp;gt;SSL&amp;amp;lt;/socketType&amp;amp;gt;&lt;br /&gt;
      &amp;amp;lt;authentication&amp;amp;gt;password-cleartext&amp;amp;lt;/authentication&amp;amp;gt;&lt;br /&gt;
      &amp;amp;lt;username&amp;amp;gt;%EMAILADDRESS%&amp;amp;lt;/username&amp;amp;gt;&lt;br /&gt;
    &amp;amp;lt;/outgoingServer&amp;amp;gt;&lt;br /&gt;
  &amp;amp;lt;/emailProvider&amp;amp;gt;&lt;br /&gt;
&amp;amp;lt;/clientConfig&amp;amp;gt;&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;/pre&amp;gt;&amp;lt;p&amp;gt;Für “domain2.tld” ist genauso vorzugehen.&amp;lt;/p&amp;gt;&lt;br /&gt;
== Domains, Accounts, Aliase und TLS-Policies in Datenbank definieren ==&lt;br /&gt;
&amp;lt;p&amp;gt;Bevor der Mailserver sinnvoll genutzt werden kann, müssen noch Domains und Benutzer im der MySQL-Datenbank registriert werden. Loggt euch wieder auf der MySQL-Kommandozeile ein:&amp;lt;/p&amp;gt;&amp;lt;pre&amp;gt;&amp;lt;code&amp;gt;mysql&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;/pre&amp;gt;&amp;lt;p&amp;gt;… und wechselt in die vmail-Datenbank:&amp;lt;/p&amp;gt;&amp;lt;pre&amp;gt;&amp;lt;code&amp;gt;use vmail;&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;/pre&amp;gt;&lt;br /&gt;
=== Neue Domain anlegen ===&lt;br /&gt;
&amp;lt;p&amp;gt;Damit ein neuer Benutzeraccount oder ein neuer Alias angelegt werden kann, muss die zu nutzende Domain zuvor im Mailsystem bekannt gemacht werden. Postfix verarbeitet nur E-Mails an Domains, die in der “domains”-Tabelle eingetragen sind:&amp;lt;/p&amp;gt;&amp;lt;pre&amp;gt;&amp;lt;code&amp;gt;insert into domains (domain) values ('mysystems.tld');&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;/pre&amp;gt;&lt;br /&gt;
=== Neuen E-Mail-Account anlegen ===&lt;br /&gt;
&amp;lt;p&amp;gt;Wenn die Benutzerdomain in der Domain-Tabelle angelegt ist, kann ein neuer Benutzeraccount für den Mailserver erstellt werden. Bevor das passende SQL-Kommando eingegeben und abgeschickt wird, wird jedoch zu nächst ein Passwort-Hash des gewünschten Passworts für den Account erzeugt. Mit&amp;lt;/p&amp;gt;&amp;lt;pre&amp;gt;&amp;lt;code&amp;gt;doveadm pw -s SHA512-CRYPT&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;/pre&amp;gt;&amp;lt;p&amp;gt;'''(in der Bash Shell! - Nicht in der MySQL Shell!)''' kann ein solcher Hash erzeugt werden. Beispiel für einen ausgegebenen Hash:&amp;lt;/p&amp;gt;&amp;lt;pre&amp;gt;&amp;lt;code&amp;gt;{SHA512-CRYPT}$6$wHyJsS.doo39xoCu$KI1N4l.Vd0ZWYj5BYLI8AdK7ACwAZaM18gSy7Bko0dG2Hvli4.KfAmLk2ztFVP.R4T7oqiu7clKBehCTc4GGw0&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;/pre&amp;gt;&amp;lt;p&amp;gt;Dieser Hash ist für jedes Passwort einzigartig und ändert sich sogar bei jeder Generierung. Legt den Hash am besten gleich in eurer Zwischenablage oder einem Textdokument ab - ihr benötigt ihn gleich!&amp;lt;/p&amp;gt;&amp;lt;div class=&amp;quot;warning&amp;quot;&amp;gt;Verwendet auch an dieser Stelle möglichst nur die Zeichen 0-9, a-z und A-z. Sonderzeichen können Probleme verursachen. Wenn eure Passwörter einigermaßen lang sind, reicht das völlig aus. Sonderzeichen bringen dann ohnehin keinen nennenswerten Sicherheitsgewinn.&amp;lt;/div&amp;gt;&amp;lt;p&amp;gt;Das SQL-Kommando zum Erzeugen eines neuen Accounts lautet:&amp;lt;/p&amp;gt;&amp;lt;pre&amp;gt;&amp;lt;code&amp;gt;insert into accounts (username, domain, password, quota, enabled, sendonly) values ('user1', 'mysystems.tld', '{SHA512-CRYPT}$6$wHyJsS[...]', 2048, true, false);&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;/pre&amp;gt;&amp;lt;p&amp;gt;In das “Password”-Feld wird der Hash vollständig eingetragen (hier: gekürzt).&amp;lt;/p&amp;gt;&amp;lt;p&amp;gt;Legt am besten gleich den &amp;lt;code&amp;gt;postmaster@mysystems.tld&amp;lt;/code&amp;gt; Account an. Er sollte auf jedem Mailserver vorhanden sein, um den Administrator bei technischen Problemen mit dem Server erreichen zu können.&amp;lt;/p&amp;gt;&lt;br /&gt;
=== Neuen Alias anlegen ===&lt;br /&gt;
&amp;lt;pre&amp;gt;&amp;lt;code&amp;gt;insert into aliases (source_username, source_domain, destination_username, destination_domain, enabled) values ('alias', 'mysystems.tld', 'user1', 'mysystems.tld', true);&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;/pre&amp;gt;&amp;lt;p&amp;gt;… legt einen Alias für den Benutzer “&amp;lt;/p&amp;gt;[mailto:user1@mysystems.tld user1@mysystems.tld]&amp;lt;p&amp;gt;” an. E-Mails an “&amp;lt;/p&amp;gt;[mailto:alias@mysystems.tld alias@mysystems.tld]&amp;lt;p&amp;gt;” werden dann an die Mailbox dieses Users zugestellt.&amp;lt;/p&amp;gt;&amp;lt;p&amp;gt;Als Zieladressen können auch E-Mail-Konten auf fremden Servern angegeben werden. Postfix leitet diese E-Mails dann weiter. Dabei kann es allerdings zu Problemen mit SPF-Records kommen – schließlich schickt Postfix unter bestimmten Umständen E-Mails unter fremden Domains, für die er laut SPF-Record nicht zuständig ist. SRS (Sender Rewriting Scheme) ist eine Lösung für dieses Problem. Von Erweiterungen, die schwerwiegende Design-Fehler einer Technik wie SPF korrigieren, halte ich allerdings nicht besonders viel, sodass ich euch empfehle, den SPF-Record (wie oben) auf einem “?all” gestellt zu lassen und auf Weiterleitungen zu fremden Servern möglichst zu verzichten. Aliase von lokalen Adressen auf andere lokale Adressen sind kein Problem.&amp;lt;/p&amp;gt;&amp;lt;p&amp;gt;Wenn ein '''E-Mail-Verteiler''' eingerichtet werden soll, werden mehrere Datensätze mit derselben Quelladresse eingerichtet, also z.B. so:&amp;lt;/p&amp;gt;&amp;lt;pre&amp;gt;&amp;lt;code&amp;gt;team@domain.tld =&amp;amp;gt; user1@domain.tld&lt;br /&gt;
team@domain.tld =&amp;amp;gt; user2@domain.tld&lt;br /&gt;
team@domain.tld =&amp;amp;gt; user3@domain.tld&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;/pre&amp;gt;&amp;lt;p&amp;gt;Ein '''Catch-All''' hingegen kann erreicht werden, indem der &amp;lt;code&amp;gt;source_username&amp;lt;/code&amp;gt; auf &amp;lt;code&amp;gt;null&amp;lt;/code&amp;gt; gesetzt wird, z.B. so:&amp;lt;/p&amp;gt;&amp;lt;pre&amp;gt;&amp;lt;code&amp;gt;insert into aliases (source_username, source_domain, destination_username, destination_domain, enabled) values (null, 'domain1.tld', 'catchall', 'mysystems.tld', true);&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;/pre&amp;gt;&amp;lt;p&amp;gt;Ein Catch-All kann mit anderen Aliasen auf derselben Domain ko-existieren und “fängt” alle Benutzernamen auf der jeweiligen Domain auf, für die noch kein Alias gesetzt wurde. So kann man Mails zentral aufsammeln, welche an Mailboxen verschickt wurden, die auf dem Mailserver nicht existieren. Beachtet, dass dadurch das Spamaufkommen ggf. höher ist.&amp;lt;/p&amp;gt;&lt;br /&gt;
=== Neue TLS-Policy anlegen (optional) ===&lt;br /&gt;
&amp;lt;p&amp;gt;Mithilfe der TLS Policy-Tabelle kann festgelegt werden, mit welchen Sicherheitsfeatures mit den Mailservern einer bestimmten Domain kommuniziert werden soll. Wenn für die Domain “thomas-leister.de” beispielsweise “dane-only” in “policy” festgelegt wird, wird die Verbindung zu Mailservern dieser Domain nur noch gültig sein, wenn sie DANE-authentifiziert und verschlüsselt ist. Mögliche Policies sind:&amp;lt;/p&amp;gt;&lt;br /&gt;
*&amp;lt;code&amp;gt;none&amp;lt;/code&amp;gt;: Keine Verschlüsselung nutzen, auch wenn der andere Mailserver das unterstützt.&lt;br /&gt;
*&amp;lt;code&amp;gt;may&amp;lt;/code&amp;gt;: Verschlüsseln, wenn der andere Server dies unterstützt, aber keine Zertifikatsprüfung (self-signed Zertifikate werden akzeptiert).&lt;br /&gt;
*&amp;lt;code&amp;gt;encrypt&amp;lt;/code&amp;gt;: Zwingend Verschlüsseln, allerdings keine Zertifikatsprüfung (self-signed Zertifikate werden akzeptiert).&lt;br /&gt;
*&amp;lt;code&amp;gt;dane&amp;lt;/code&amp;gt;: Wenn gültige TLSA-Records gefunden werden, wird zwingend verschlüsselt und das Zertifikat mittels DANE verifiziert. Falls ungültige TLSA-Records gefunden werden, wird auf “encrypt” zurückgegriffen. Falls gar keine TLSA-Records gefunden werden, wird “may” genutzt.&lt;br /&gt;
*&amp;lt;code&amp;gt;dane-only&amp;lt;/code&amp;gt;: Nur verschlüsselte Verbindungen. Gültige TLSA-Records für den Hostnamen müssen existieren (DANE)&lt;br /&gt;
*&amp;lt;code&amp;gt;verify&amp;lt;/code&amp;gt;: Nur verschlüsselte Verbindungen + Prüfung der CA. Der Hostname aus dem MX DNS-Record muss im Zertifikat enthalten sein. (Basiert auf Vertrauen in korrekte DNS-Daten)&lt;br /&gt;
*&amp;lt;code&amp;gt;secure&amp;lt;/code&amp;gt;: Nur verschlüsselte Verbindungen + Prüfung der CA. Der andere Mailserver muss (standardmäßig) einen Hostnamen haben, der “.domain.tld” oder nur “domain.tld” entspricht. Dieser Hostname muss im Zertifikat enthalten sein. Auf das DNS wird nicht zurückgegriffen (Sicherheitsvorteil gegenüber “verify). Beispiel: Eine E-Mail an[mailto:user@web.de user@web.de]soll gesendet werden. Der MX-Mailserver von Web.de dürfte dann nur den Hostnamen “web.de” oder eine Subdomain davon als Hostnamen haben, z.B. mx.web.de. Eine Verbindung zu mx.web.net wäre nicht zulässig.&lt;br /&gt;
&amp;lt;p&amp;gt;Für Domains der großen Anbieter wie gmx.de, web.de und der Telekom kann man “secure” wählen. Bei Posteo und Mailbox.org sogar “dane-only”. Für alle Provider, die keine gültigen TLS-Zertifikate einsetzen, kann “encrypt” gewählt werden. Standardeinstellung für alle anderen Mailserver ist “dane” (siehe main.cf der Postfix Config).&amp;lt;/p&amp;gt;&amp;lt;p&amp;gt;Das Feld “params” wird mit zusätzlichen Infos gefüllt, wenn sie für einen Policy-Typ erforderlich sind, z.B. für einen “secure” Eintrag zu GMX:&amp;lt;/p&amp;gt;&amp;lt;pre&amp;gt;&amp;lt;code&amp;gt;insert into tlspolicies (domain, policy, params) values ('gmx.de', 'secure', 'match=.gmx.net');&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;/pre&amp;gt;&amp;lt;p&amp;gt;Standardmäßig überprüft Postfix bei “secure” – wie oben bereits erwähnt – ob die Empfängerdomain (gmx.de) im Zertifikat des Zielservers vorhanden ist. Bei GMX (und vielen anderen großen Anbietern) ist das allerdings nicht der Fall: Die Mailserver-Zertifikate von GMX sind nur für gmx.net + Subdomains gültig. Ließe man den Datenbank-Eintrag für GMX ohne weitere Einstellungen auf “secure” stehen, könnten an GMX keine Mails mehr übermittelt werden. Deshalb ist es wichtig, für GMX festzulegen, dass im Zertifikat nicht nach “gmx.de” sondern nach “gmx.net” gesucht werden soll. Das können wir mithilfe des Felds “params” und der “match=…” Zeichenkette tun. Wenn nach mehreren Domains gesucht werden soll, können auch mehrere angegeben werden, z.B. so: “match=.gmx.net:.gmx.ch”. Die zusätzlichen Angaben in “params” sind allerdings nicht für jeden Mailprovider notwendig. GMX ist eine Ausnahme – genauso wie z.B. Yahoo. Ob ihr in “params” einen “match”-String angeben müsst, könnt ihr z.B. über&amp;lt;/p&amp;gt;[https://de.ssl-tools.net/ https://de.ssl-tools.net/]&amp;lt;p&amp;gt;herausfinden. Wenn die 2-nd-Level-Domain des Mailservers von der Domain der Mailadressen abweicht, muss ein passender match-String angegeben werden.&amp;lt;/p&amp;gt;&amp;lt;p&amp;gt;Andere Einstellungen wie “dane-only” erfordern keine zusätzlichen Angaben in “params”:&amp;lt;/p&amp;gt;&amp;lt;pre&amp;gt;&amp;lt;code&amp;gt;insert into tlspolicies (domain, policy) values ('mailbox.org', 'dane-only');&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;/pre&amp;gt;&amp;lt;p&amp;gt;In diesem Fall wird mit den Mailservern von mailbox.org nur noch DANE-gesichert und verschlüsselt kommuniziert. Die MySQL-Kommandozeile kann mit einem &amp;lt;code&amp;gt;quit;&amp;lt;/code&amp;gt; wieder verlassen werden.&amp;lt;/p&amp;gt;&lt;br /&gt;
== Optional: Firewall konfigurieren ==&lt;br /&gt;
&amp;lt;p&amp;gt;Wer vor / auf dem Mailserver eine Firewall betreibt, die den Zugriff auf Ports beschränkt, sollte zuerst alle Mailserver-Ports freischalten:&amp;lt;/p&amp;gt;&amp;lt;pre&amp;gt;&amp;lt;code&amp;gt;IMAP:           143/tcp&lt;br /&gt;
IMAPS:          993/tcp&lt;br /&gt;
Submission:     587/tcp&lt;br /&gt;
SMTPS:          465/tcp&lt;br /&gt;
SMTP:            25/tcp&lt;br /&gt;
ManageSieve:   4190/tcp&lt;br /&gt;
Web HTTP:        80/tcp&lt;br /&gt;
Web HTTPS:      443/tcp&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;/pre&amp;gt;&amp;lt;p&amp;gt;'''Denkt unbedingt daran, auch eure IPv6-Ports zu öffnen!''' - Euer Mailsetup spricht IPv6! :-) Die Ports 143 und 587 können geschlossen bleiben, wenn keine StartTLS-basierenden Verbindung genutzt werden sollen (siehe Hinweis weiter unten).&amp;lt;/p&amp;gt;&lt;br /&gt;
== Start all the things! ==&lt;br /&gt;
&amp;lt;p&amp;gt;Euer neuer Mailserver ist jetzt fertig konfiguriert. Zeit für einen ersten Start!&amp;lt;/p&amp;gt;&amp;lt;pre&amp;gt;&amp;lt;code&amp;gt;systemctl start dovecot&lt;br /&gt;
systemctl start postfix&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;/pre&amp;gt;&amp;lt;div class=&amp;quot;warning&amp;quot;&amp;gt;&amp;lt;p&amp;gt;Wegen des Bugs&amp;lt;/p&amp;gt;[https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=877992 #877992]&amp;lt;p&amp;gt;startet Postfix nach einem Reboot nicht mehr. Abhilfe schafft folgendes Kommando:&amp;lt;/p&amp;gt;&amp;lt;pre&amp;gt;&amp;lt;code&amp;gt;systemctl enable postfix@-&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;/pre&amp;gt;&amp;lt;p&amp;gt;(beachte das Minuszeichen &amp;lt;code&amp;gt;-&amp;lt;/code&amp;gt; am Ende!)&amp;lt;/p&amp;gt;&amp;lt;/div&amp;gt;&amp;lt;p&amp;gt;Kontrolliert am besten gleich die Logfiles nach auffälligen Fehlern. Ich empfehle das “tail” Tool in einer separaten Terminal-Sitzung. Neue Log-Einträge erscheinen damit sofort auf dem Bildschirm:&amp;lt;/p&amp;gt;&amp;lt;pre&amp;gt;&amp;lt;code&amp;gt;tail -f /var/log/syslog&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;/pre&amp;gt;&amp;lt;p&amp;gt;bzw.&amp;lt;/p&amp;gt;&amp;lt;pre&amp;gt;&amp;lt;code&amp;gt;tail -f /var/log/mail.log&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;/pre&amp;gt;&amp;lt;p&amp;gt;Wenn ihr hier Fehler entdeckt, seht nach, ob ihr alle erforderlichen Änderungen an den Konfigurationsdateien durchgeführt habt (oder ob sich noch beispielhafte Hashes oder Beispieldomains darin befinden).&amp;lt;/p&amp;gt;&lt;br /&gt;
== Eine Verbindung zum Mailserver herstellen ==&lt;br /&gt;
&amp;lt;figure&amp;gt;&amp;lt;figcaption&amp;gt;Mailserver Logindaten für Thunderbird&amp;lt;/figcaption&amp;gt;&amp;lt;/figure&amp;gt;&amp;lt;p&amp;gt;Eine Verbindung könnt ihr über jeden IMAP-fähigen E-Mail-Client und den folgenden Verbindungsparametern herstellen:&amp;lt;/p&amp;gt;&lt;br /&gt;
*IMAP(S)&lt;br /&gt;
**Host: imap.mysystems.tld&lt;br /&gt;
**Port: 993&lt;br /&gt;
**Verschlüsselung: TLS&lt;br /&gt;
**(dieser Server gilt auch für domain2 und domain3, falls vorhanden!)&lt;br /&gt;
*SMTP(S)&lt;br /&gt;
**Host: smtp.mysystems.tld&lt;br /&gt;
**Port: 465&lt;br /&gt;
**Verschlüsselung: TLS&lt;br /&gt;
**(dieser Server gilt auch für domain2 und domain3, falls vorhanden!)&lt;br /&gt;
*Managesieve (optional, zur Konfiguration der benutzerspezifischen Sieve-Filterregeln)&lt;br /&gt;
**Host: imap.mysystems.tld&lt;br /&gt;
**Port: 4190&lt;br /&gt;
**Verschlüsselung: StartTLS&lt;br /&gt;
*Benutzername: Die '''vollständige''' E-Mail-Adresse, also @&amp;amp;lt;domain.tld&amp;amp;gt;&lt;br /&gt;
*Passwort: Sollte bekannt sein ;-)&lt;br /&gt;
&amp;lt;p&amp;gt;Sollten Verbindungen über die IMAPS (993) und SMTPS (465) Ports nicht möglich sein, kann auch auf die StartTLS-Ports zurückgegriffen werden:&amp;lt;/p&amp;gt;&lt;br /&gt;
*IMAP-Server:&lt;br /&gt;
**Host: mail.mysystems.tld&lt;br /&gt;
**Port: 143&lt;br /&gt;
**Verschlüsselung: StartTLS&lt;br /&gt;
*SMTP-Server:&lt;br /&gt;
**Host: mail.mysystems.tld&lt;br /&gt;
**Port: 587&lt;br /&gt;
**Verschlüsselung: StartTLS&lt;br /&gt;
&amp;lt;p&amp;gt;Die IETF (Internet Engineering Task Force) empfiehlt seit 2018 allerdings, auf StartTLS Verbindungen zu verzichten, und auf native TLS-Verbindungen zu setzen:&amp;lt;/p&amp;gt;[https://tools.ietf.org/html/rfc8314 https://tools.ietf.org/html/rfc8314]&amp;lt;div class=&amp;quot;tip&amp;quot;&amp;gt;Der erste Login kann ein paar Sekunden in Anspruch nehmen - habt etwas Gedult. Dovecot legt im Hintergrund die Verzeichnisstruktur für den neuen Benutzer an.&amp;lt;/div&amp;gt;&lt;br /&gt;
== Spamfilter testen ==&lt;br /&gt;
&amp;lt;p&amp;gt;Schickt einfach eine E-Mail mit dem Text&amp;lt;/p&amp;gt;&amp;lt;pre&amp;gt;&amp;lt;code&amp;gt;XJS*C4JDBQADN1.NSBN3*2IDNEN*GTUBE-STANDARD-ANTI-UBE-TEST-EMAIL*C.34X&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;/pre&amp;gt;&amp;lt;p&amp;gt;an einen Account eures neuen Mailservers. Die E-Mail sollte nicht ankommen und im Rspamd-Webinterface erscheint ein entsprechender rot markierter Eintrag in der History.&amp;lt;/p&amp;gt;&lt;br /&gt;
== Debugging ==&lt;br /&gt;
&amp;lt;p&amp;gt;Sollten Probleme auftreten, hilft ein Blick ins Log!&amp;lt;/p&amp;gt;&amp;lt;p&amp;gt;Das Rspamd Log kannst du z.B. so einsehen und live mitlesen:&amp;lt;/p&amp;gt;&amp;lt;pre&amp;gt;&amp;lt;code&amp;gt;journalctl -f -u rspamd&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;/pre&amp;gt;&amp;lt;p&amp;gt;Postfix so:&amp;lt;/p&amp;gt;&amp;lt;pre&amp;gt;&amp;lt;code&amp;gt;journalctl -f -u postfix@-.service&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;/pre&amp;gt;&amp;lt;p&amp;gt;… und Dovecot so:&amp;lt;/p&amp;gt;&amp;lt;pre&amp;gt;&amp;lt;code&amp;gt;journalctl -f -u dovecot&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;/pre&amp;gt;&amp;lt;hr&amp;gt;&lt;br /&gt;
== Das war’s auch schon! Hat dir diese Anleitung geholfen? ==&lt;br /&gt;
&amp;lt;p&amp;gt;Wenn ich dir mit dieser Anleitung helfen konnte, deinen Mailserver aufzusetzen, ist dir das vielleicht ein paar Euro wert.&amp;lt;/p&amp;gt;&amp;lt;p&amp;gt;Wie du dir sicherlich vorstellen kannst, war es eine Menge Arbeit, diese Anleitung zu schreiben und zu erproben. Daher freue ich mich natürlich riesig über eine Motivationsstütze und finanzielle Hilfe, um Testserver und -Umgebungen bezahlen zu können, oder mir nach getaner Arbeit ein kühles Bier zu leisten.&amp;lt;/p&amp;gt;&amp;lt;p&amp;gt;&amp;lt;br&amp;gt;&amp;lt;/p&amp;gt;&amp;lt;p&amp;gt;Wie du mir etwas zukommen lassen kannst, erfährst du hier:&amp;lt;/p&amp;gt;[https://thomas-leister.de/unterstuetzen/ Unterstützen]&amp;lt;p&amp;gt;Herzlichen Dank!&amp;lt;/p&amp;gt;&amp;lt;hr&amp;gt;&lt;br /&gt;
== Fragen und Antworten ==&lt;br /&gt;
=== “Darf ich deine Anleitung übernehmen?” ===&lt;br /&gt;
&amp;lt;p&amp;gt;Nein. Du kannst dir sicherlich vorstellen, dass hinter meiner Anleitung viel Mühe und Arbeit steckt. Ich stelle sie nicht frei zur Verfügung und bitte darum, meinen Text nicht ohne ausdrückliche Zustimmung zu re-publizieren (auch nicht in privaten, aber öffentlich zugänglichen Blogs!). Also ein klares “Nein” zu Copy &amp;amp; Paste + Wiederveröffentlichung. Private, nicht-öffentliche Kopien oder Kopien für den Firmen-internen Gebrauch sind natürlich erlaubt. Es geht mir auch darum, diesen Beitrag nicht auf irgendeinem fremden Blog wiederzufinden, der womöglich sogar noch Geld mit fremden Content verdient. Verlinken ist natürlich absolut erlaubt und ausdrücklich erwünscht ;-)&amp;lt;/p&amp;gt;&lt;br /&gt;
=== “Wieso veröffentlichst du deine Anleitung auf deinem Blog und nicht in einem Wiki?” ===&lt;br /&gt;
&amp;lt;p&amp;gt;Weil ich hier die volle Kontrolle habe. Was hier steht, ist in sich konsistent und kein Flickenteppich. In den gängigen Wikis darf dieser Beitrag natürlich gerne ergänzend verlinkt werden.&amp;lt;/p&amp;gt;&amp;lt;p&amp;gt;'''Ich habe das ''nicht getestet''!'''&amp;lt;/p&amp;gt;&lt;br /&gt;
=== Welche Daten sollte ich für Backups Sichern? ===&lt;br /&gt;
&amp;lt;p&amp;gt;Folgende Verzeichnisse sollten ins Backup aufgenommen werden:&amp;lt;/p&amp;gt;&lt;br /&gt;
*&amp;lt;code&amp;gt;/etc/postfix&amp;lt;/code&amp;gt; (Postfix Konfiguration)&lt;br /&gt;
*&amp;lt;code&amp;gt;/etc/dovecot&amp;lt;/code&amp;gt; (Dovecot Konfiguration)&lt;br /&gt;
*&amp;lt;code&amp;gt;/etc/rspamd&amp;lt;/code&amp;gt; (Rspamd Konfiguration)&lt;br /&gt;
*&amp;lt;code&amp;gt;/var/vmail&amp;lt;/code&amp;gt; (E-Mails, Benutzerkonteneinstellungen und Sieve-Filter)&lt;br /&gt;
*&amp;lt;code&amp;gt;/var/lib/rspamd/dkim&amp;lt;/code&amp;gt; (DKIM-Schlüssel)&lt;br /&gt;
*&amp;lt;code&amp;gt;/var/www/mysystems.tld/autoconfig.mysystems.tld&amp;lt;/code&amp;gt; (Autoconfig-Datei)&lt;br /&gt;
&amp;lt;p&amp;gt;Außerdem sollte unbedingt regelmäßig ein MySQL-Dump der &amp;lt;code&amp;gt;vmail&amp;lt;/code&amp;gt; Datenbank generiert, in eine Datei geschrieben und ins Backup aufgenommen werden:&amp;lt;/p&amp;gt;&amp;lt;pre&amp;gt;&amp;lt;code&amp;gt;mysqldump vmail &amp;amp;gt; /root/backups/vmail.sql&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;/pre&amp;gt;&lt;br /&gt;
== Häufige Fehler ==&lt;br /&gt;
=== “fatal: no SASL authentication mechanisms” / “SASL: Connect to private/auth failed: No such file or directory” ===&lt;br /&gt;
&amp;lt;p&amp;gt;Das Problem: Postfix kann Benutzer nicht authentifizieren, weil in /var/spool/postfix/private kein “auth” Socket verfügbar ist. Eigentlich sollte Dovecot diesen Socket bereitstellen. Der Fehler ist also bei Dovecot zu suchen – nicht bei Postfix. Leider hat die Erfahrung gezeigt, dass ein Vertipper nicht zwingend in der Socket-Konfiguration&amp;lt;/p&amp;gt;&amp;lt;pre&amp;gt;&amp;lt;code&amp;gt;unix_listener /var/spool/postfix/private/auth {&lt;br /&gt;
    mode = 0660&lt;br /&gt;
    user = postfix&lt;br /&gt;
    group = postfix&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;/pre&amp;gt;&amp;lt;p&amp;gt;vorhanden sein muss. Es kommt immer wieder vor, dass der Fehler irgendwo anders in der Dovecot-Konfiguration liegt. Dovecot verschweigt einem dann den Fehler und erstellt den auth-Socket für Postfix nicht. Es lohnt sich in so einem Fall, noch einmal die ganze Dovecot-Konfiguration nach Fehlern abzusuchen.&amp;lt;/p&amp;gt;&lt;br /&gt;
=== “5.7.1 Service unavailable; client [1.3.3.7] blocked using zen.spamhaus.org” ===&lt;br /&gt;
&amp;lt;p&amp;gt;Das Problem: Der Mailserver akzeptiert keine E-Mails vom Mailclient und gibt die oben genannte Fehlermeldung zurück.&amp;lt;/p&amp;gt;&amp;lt;p&amp;gt;Das Problem lässt sich sehr einfach lösen, indem statt SMTP-Port 25 der SMTS-Port 465 oder Submission-Port 587 für den Mailversand im Mailclient konfiguriert wird. Auf Port 25 ist eine Blacklist aktiv, welche viele IP-Adressen z.B. aus DSL-Adressbereichen enthält. Diese Einschränkung gilt für die beiden anderen Ports nicht. Mailclients sollten niemals Port 25 zum versenden Nutzen.&amp;lt;/p&amp;gt;&lt;br /&gt;
=== Mailclient verbindet sich nicht zum Server ===&lt;br /&gt;
&lt;br /&gt;
*Evtl. blockiert der Virenschutz die Verbindung?&lt;br /&gt;
*Blockiert die Server-Firewall die Verbindung von außen?&lt;br /&gt;
*Ist die richtige Serveradresse angegeben? (siehe Verbindungseinstellungen oben)&lt;br /&gt;
*Werden die richtigen Ports genutzt und ist der Verschlüsselungstyp richtig eingestellt?&lt;/div&gt;</summary>
		<author><name>Admin</name></author>
	</entry>
	<entry>
		<id>https://wiki.my-network.at/index.php?title=Debian_10_upgrade&amp;diff=33</id>
		<title>Debian 10 upgrade</title>
		<link rel="alternate" type="text/html" href="https://wiki.my-network.at/index.php?title=Debian_10_upgrade&amp;diff=33"/>
		<updated>2022-08-24T11:43:18Z</updated>

		<summary type="html">&lt;p&gt;Admin: Die Seite wurde neu angelegt: „&amp;lt;p&amp;gt;Debian 11, codenamed ‘bullseye’ was released on August 10th after nearly two years of development. This is a stable release and will receive support for…“&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&amp;lt;p&amp;gt;Debian 11, codenamed ‘bullseye’ was released on August 10th after nearly two years of development. This is a stable release and will receive support for the next 5 years just like any other Debian stable version. Debian 11 comes with major software improvements and other enhancements which include:&amp;lt;/p&amp;gt;&lt;br /&gt;
*Linux Kernel&amp;amp;nbsp; 5.10 LTS. This is an improvement from Kernel 4.19 that was used by Debian 10 Buster.&lt;br /&gt;
*New versions of Desktop environments including GNOME 3.38, MATE 1.24, KDE Plasma 5.20, LXDE 11, LXQt 0.16, and Xfce 4.16.&lt;br /&gt;
*A new theme known as the Homeworld theme that was inspired by an art style born in Germany called Bauhaus movement.&lt;br /&gt;
*In Debian 11, over 40,000 software packages have newer versions. With Debian 11, you will get LibreOffice 7.0, Apache 2.4.48, MariaDB 10.5, Python 3.9.1, and PostgreSQL 13 to mention a few. You can have a glance at the entire list by heading over to the release notes.&lt;br /&gt;
*CUPS and driverless printing.&lt;br /&gt;
*Support for exFAT filesystem.&lt;br /&gt;
*Support for numerous architectures:&amp;amp;nbsp; 64-bit &amp;amp; 32-bit PC, 64-bit ARM (Arch 64. IBM System Z, POWER Processors, EABI ARM, 64-bit MIPS among others.&lt;br /&gt;
&amp;lt;p&amp;gt;That was just an overview of what Debian 11 provides. Let’s now focus on how you can upgrade from Debian 10 Buster to Debian 11.&amp;lt;/p&amp;gt;&lt;br /&gt;
== Step 1)  Perform a backup of all your files ==&lt;br /&gt;
&amp;lt;p&amp;gt;Before upgrading to a new OS release, it’s always recommended to have a backup of all your files. This ensures that your files are safe in case something goes wrong during the upgrade that can lead to file corruption. Here is a list of&amp;lt;/p&amp;gt;[https://www.linuxtechi.com/top-12-open-source-backup-tools-linux-systems/ backup &amp;amp; recovery software tools]&amp;lt;p&amp;gt;that you can use to safely backup all your data before proceeding.&amp;lt;span id=&amp;quot;ezoic-pub-ad-placeholder-166&amp;quot; class=&amp;quot;ezoic-adpicker-ad&amp;quot;&amp;gt;&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;ezoic-ad ezoic-at-0 medrectangle-3 medrectangle-3166 adtester-container adtester-container-166&amp;quot; data-ez-name=&amp;quot;linuxtechi_com-medrectangle-3&amp;quot;&amp;gt;&amp;lt;span id=&amp;quot;div-gpt-ad-linuxtechi_com-medrectangle-3-0&amp;quot; class=&amp;quot;ezoic-ad&amp;quot; ezaw=&amp;quot;728&amp;quot; ezah=&amp;quot;90&amp;quot;&amp;gt;&amp;lt;/span&amp;gt;&amp;lt;/span&amp;gt;&amp;lt;/p&amp;gt;&amp;lt;div class=&amp;quot;vNVr3pNr&amp;quot;&amp;gt;&amp;lt;br&amp;gt;&amp;lt;/div&amp;gt;&lt;br /&gt;
== Step 2) Update package lists &amp;amp; Upgrade packages ==&lt;br /&gt;
&amp;lt;p&amp;gt;We will start by verifying that we are currently using Debian Buster as shown&amp;lt;/p&amp;gt;&amp;lt;pre&amp;gt;$ cat /etc/os-release&amp;lt;/pre&amp;gt;&amp;lt;p&amp;gt;Alternatively, you can run the command:&amp;lt;/p&amp;gt;&amp;lt;pre&amp;gt;$ cat /etc/debian_version&amp;lt;/pre&amp;gt;&amp;lt;p&amp;gt;Next, proceed and update the package index and upgrade the software packages by running:&amp;lt;/p&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;span class=&amp;quot;ezoic-autoinsert-ad ezoic-under_first_paragraph&amp;quot;&amp;gt;&amp;lt;/span&amp;gt;&amp;lt;pre&amp;gt;$ sudo apt update -y &amp;amp;&amp;amp; sudo apt upgrade -y&amp;lt;/pre&amp;gt;&amp;lt;p&amp;gt;Next, run the dist-upgrade command shown. In addition to upgrading the packages, it also handles changing of dependencies with new versions of packages installed.&amp;lt;/p&amp;gt;&amp;lt;pre&amp;gt;$ sudo apt dist-upgrade&amp;lt;/pre&amp;gt;&lt;br /&gt;
== Step 3) Update Package Repository&amp;lt;br&amp;gt; ==&lt;br /&gt;
&amp;lt;p&amp;gt;Debian repositories are defined in the /etc/apt/sources.list file and the /etc/apt/sources.list.d/directory.&amp;amp;nbsp; We need to replace Debian 10 repositories with Debian 11 repositories.&amp;lt;/p&amp;gt;&amp;lt;p&amp;gt;To achieve this, in the&amp;amp;nbsp; /etc/apt/sources.list file , we need to replace the buster keyword with bullseye using the&amp;lt;/p&amp;gt;[https://www.linuxtechi.com/20-sed-command-examples-linux-users/ sed command]&amp;lt;p&amp;gt;as provided.&amp;lt;/p&amp;gt;&amp;lt;pre&amp;gt;$ sudo sed -i 's/buster/bullseye/g' /etc/apt/sources.list&amp;lt;/pre&amp;gt;&amp;lt;p&amp;gt;Thereafter, locate the following debian-security &amp;amp;nbsp;lines in the&amp;amp;nbsp; sources.list file:&amp;lt;/p&amp;gt;&amp;lt;pre&amp;gt;deb http://security.debian.org/debian-security bullseye/updates main&lt;br /&gt;
deb-src http://security.debian.org/debian-security bullseye/updates main&amp;lt;/pre&amp;gt;&amp;lt;p&amp;gt;And replace them with following lines:&amp;lt;/p&amp;gt;&amp;lt;pre&amp;gt;deb https://deb.debian.org/debian-security bullseye-security main contrib&lt;br /&gt;
deb-src https://deb.debian.org/debian-security bullseye-security main contrib&amp;lt;/pre&amp;gt;&amp;lt;p&amp;gt;The&amp;amp;nbsp; sources.list file should finally look as follows:&amp;lt;/p&amp;gt;&amp;lt;pre&amp;gt;deb http://deb.debian.org/debian bullseye main&lt;br /&gt;
deb-src http://deb.debian.org/debian bullseye main&lt;br /&gt;
deb https://deb.debian.org/debian-security bullseye-security main contrib&lt;br /&gt;
deb-src https://deb.debian.org/debian-security bullseye-security main contrib&lt;br /&gt;
deb http://deb.debian.org/debian bullseye-updates main&lt;br /&gt;
deb-src http://deb.debian.org/debian bullseye-updates main&lt;br /&gt;
deb http://deb.debian.org/debian bullseye-backports main&lt;br /&gt;
deb-src http://deb.debian.org/debian bullseye-backports main&amp;lt;/pre&amp;gt;&amp;lt;p&amp;gt;After modifying the sources.list file, update the package lists to let your system aware of the new repositories.&amp;lt;/p&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;span class=&amp;quot;ezoic-ad ezoic-at-0 medrectangle-4 medrectangle-4340 adtester-container adtester-container-340&amp;quot; data-ez-name=&amp;quot;linuxtechi_com-medrectangle-4&amp;quot;&amp;gt;&amp;lt;span class=&amp;quot;ezoic-ad&amp;quot; ezaw=&amp;quot;580&amp;quot; ezah=&amp;quot;400&amp;quot;&amp;gt;&amp;lt;span class=&amp;quot;ezoic-autoinsert-ad ezoic-mid_content&amp;quot;&amp;gt;&amp;lt;/span&amp;gt;&amp;lt;span id=&amp;quot;ez-clearholder-box-4&amp;quot;&amp;gt;&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;ezoic-ad ezoic-at-0 box-4 box-4260 adtester-container adtester-container-260&amp;quot; data-ez-name=&amp;quot;linuxtechi_com-box-4&amp;quot;&amp;gt;&amp;lt;span class=&amp;quot;ezoic-ad&amp;quot; ezaw=&amp;quot;728&amp;quot; ezah=&amp;quot;90&amp;quot;&amp;gt;&amp;lt;/span&amp;gt;&amp;lt;/span&amp;gt;&amp;lt;/span&amp;gt;&amp;lt;/span&amp;gt;&amp;lt;pre&amp;gt;$ sudo apt update&amp;lt;/pre&amp;gt;&lt;br /&gt;
== Step 4)  Perform minimal system upgrade ==&lt;br /&gt;
&amp;lt;p&amp;gt;Performing a full system upgrade will remove numerous packages that you might want to keep – and this is not recommended. As a workaround, the developers have recommended a two-stage upgrade process that will gracefully upgrade Debian Buster to Debian Bullseye. We have the minimal upgrade process which is soon followed by the full-upgrade.&amp;lt;/p&amp;gt;&amp;lt;p&amp;gt;The minimal upgrade upgrades all the existing packages without installing new ones or purging the existing ones. To perform the minimal upgrade, run the command:&amp;lt;/p&amp;gt;&amp;lt;pre&amp;gt;$ sudo apt upgrade --without-new-pkgs&amp;lt;/pre&amp;gt;&amp;lt;p&amp;gt;During the upgrade process, a pop-up prompt will appear requesting you to restart system services when certain libraries such as libpam and libc are upgraded. Select ‘Yes’ and press ENTER.&amp;lt;/p&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;span class=&amp;quot;ezoic-ad ezoic-at-0 medrectangle-4 medrectangle-4340 adtester-container adtester-container-340&amp;quot; data-ez-name=&amp;quot;linuxtechi_com-medrectangle-4&amp;quot;&amp;gt;&amp;lt;span class=&amp;quot;ezoic-ad&amp;quot; ezaw=&amp;quot;580&amp;quot; ezah=&amp;quot;400&amp;quot;&amp;gt;&amp;lt;span class=&amp;quot;ezoic-ad ezoic-at-0 box-4 box-4260 adtester-container adtester-container-260&amp;quot; data-ez-name=&amp;quot;linuxtechi_com-box-4&amp;quot;&amp;gt;&amp;lt;span class=&amp;quot;ezoic-ad&amp;quot; ezaw=&amp;quot;728&amp;quot; ezah=&amp;quot;90&amp;quot;&amp;gt;&amp;lt;span class=&amp;quot;ezoic-autoinsert-ad ezoic-long_content&amp;quot;&amp;gt;&amp;lt;/span&amp;gt;&amp;lt;span id=&amp;quot;ez-clearholder-banner-1&amp;quot;&amp;gt;&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;ezoic-ad ezoic-at-0 banner-1 banner-1360 adtester-container adtester-container-360&amp;quot; data-ez-name=&amp;quot;linuxtechi_com-banner-1&amp;quot;&amp;gt;&amp;lt;/span&amp;gt;&amp;lt;/span&amp;gt;&amp;lt;/span&amp;gt;&amp;lt;/span&amp;gt;&amp;lt;/span&amp;gt;&lt;br /&gt;
== Step 5) Perform full upgrade to Debian 11 ==&lt;br /&gt;
&amp;lt;p&amp;gt;This is the last step and the most crucial part of the upgrade. The full upgrade upgrades the entire Debain 10 system to Debian 11. It installs the latest packages that come with Debian 11 and resolves dependency issues. This might take a while depending on your bandwidth.&amp;lt;/p&amp;gt;&amp;lt;pre&amp;gt;$ sudo apt full-upgrade&amp;lt;/pre&amp;gt;&amp;lt;p&amp;gt;Once again, some additional prompts will appear. For example, you will be asked what you want to do about the chrony.conf file. Here, I chose to keep the local version installed.&amp;lt;/p&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;span class=&amp;quot;ezoic-ad ezoic-at-0 medrectangle-4 medrectangle-4340 adtester-container adtester-container-340&amp;quot; data-ez-name=&amp;quot;linuxtechi_com-medrectangle-4&amp;quot;&amp;gt;&amp;lt;span class=&amp;quot;ezoic-ad&amp;quot; ezaw=&amp;quot;580&amp;quot; ezah=&amp;quot;400&amp;quot;&amp;gt;&amp;lt;span class=&amp;quot;ezoic-ad ezoic-at-0 box-4 box-4260 adtester-container adtester-container-260&amp;quot; data-ez-name=&amp;quot;linuxtechi_com-box-4&amp;quot;&amp;gt;&amp;lt;span class=&amp;quot;ezoic-ad&amp;quot; ezaw=&amp;quot;728&amp;quot; ezah=&amp;quot;90&amp;quot;&amp;gt;&amp;lt;span class=&amp;quot;ezoic-ad ezoic-at-0 banner-1 banner-1360 adtester-container adtester-container-360&amp;quot; data-ez-name=&amp;quot;linuxtechi_com-banner-1&amp;quot;&amp;gt;&amp;lt;span class=&amp;quot;ezoic-autoinsert-ad ezoic-longer_content&amp;quot;&amp;gt;&amp;lt;/span&amp;gt;&amp;lt;span id=&amp;quot;ez-clearholder-large-leaderboard-2&amp;quot;&amp;gt;&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;ezoic-ad ezoic-at-0 large-leaderboard-2 large-leaderboard-2550 adtester-container adtester-container-550&amp;quot; data-ez-name=&amp;quot;linuxtechi_com-large-leaderboard-2&amp;quot;&amp;gt;&amp;lt;span class=&amp;quot;ezoic-ad&amp;quot; ezaw=&amp;quot;336&amp;quot; ezah=&amp;quot;280&amp;quot;&amp;gt;&amp;lt;/span&amp;gt;&amp;lt;/span&amp;gt;&amp;lt;/span&amp;gt;&amp;lt;/span&amp;gt;&amp;lt;/span&amp;gt;&amp;lt;/span&amp;gt;&amp;lt;/span&amp;gt;&amp;lt;p&amp;gt;For the Openssh-server file, again, I chose to keep the local version installed as well.&amp;lt;/p&amp;gt;&amp;lt;p&amp;gt;Once the upgrade is completed then reboot the system with beneath command,&amp;lt;/p&amp;gt;&amp;lt;pre&amp;gt;$ sudo reboot&amp;lt;/pre&amp;gt;&amp;lt;p&amp;gt;When you log in, verify the version of Debian you are running&amp;lt;/p&amp;gt;&amp;lt;pre&amp;gt;$ cat /etc/os-release&lt;br /&gt;
$ cat /etc/debian_version&amp;lt;/pre&amp;gt;&amp;lt;p&amp;gt;Your system will now be running Debian 11 Bullseye.&amp;lt;/p&amp;gt;&amp;lt;pre&amp;gt;$ lsb_release -a&amp;lt;/pre&amp;gt;&lt;/div&gt;</summary>
		<author><name>Admin</name></author>
	</entry>
	<entry>
		<id>https://wiki.my-network.at/index.php?title=Hauptseite&amp;diff=32</id>
		<title>Hauptseite</title>
		<link rel="alternate" type="text/html" href="https://wiki.my-network.at/index.php?title=Hauptseite&amp;diff=32"/>
		<updated>2022-08-24T11:39:25Z</updated>

		<summary type="html">&lt;p&gt;Admin: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&amp;lt;span style=&amp;quot;font-size: 24pt;&amp;quot;&amp;gt;Hier entsteht ein kleines privates Wikipedia&amp;lt;/span&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;span style=&amp;quot;font-size: 14pt;&amp;quot;&amp;gt;&amp;lt;span style=&amp;quot;text-decoration: underline;&amp;quot; &amp;gt;[https://wiki.my-network.at/index.php/Spezial:Alle_Seiten Zur Übersicht der Wiki Seiten hier entlang ]&amp;lt;/span&amp;gt;&amp;lt;/span&amp;gt;&lt;br /&gt;
&amp;lt;span style=&amp;quot;font-size: 14pt;&amp;quot;&amp;gt;oder einfach links auf &amp;quot;Alle Seiten&amp;quot; klicken.&amp;lt;/span&amp;gt;&lt;/div&gt;</summary>
		<author><name>Admin</name></author>
	</entry>
	<entry>
		<id>https://wiki.my-network.at/index.php?title=Hauptseite&amp;diff=31</id>
		<title>Hauptseite</title>
		<link rel="alternate" type="text/html" href="https://wiki.my-network.at/index.php?title=Hauptseite&amp;diff=31"/>
		<updated>2022-08-24T11:37:29Z</updated>

		<summary type="html">&lt;p&gt;Admin: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&amp;lt;span style=&amp;quot;font-size: 24pt;&amp;quot;&amp;gt;Hier entsteht ein kleines privates Wikipedia&amp;lt;/span&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;span style=&amp;quot;font-size: 14pt;&amp;quot;&amp;gt;[https://wiki.my-network.at/index.php/Spezial:Alle_Seiten Zur Übersicht der Wiki Seiten hier entlang]&amp;lt;/span&amp;gt;&lt;br /&gt;
&amp;lt;span style=&amp;quot;font-size: 14pt;&amp;quot;&amp;gt;&amp;lt;/span&amp;gt;&lt;br /&gt;
&amp;lt;span style=&amp;quot;font-size: 14pt;&amp;quot;&amp;gt;oder einfach links auf &amp;quot;Alle Seiten&amp;quot; klicken.&amp;lt;/span&amp;gt;&lt;/div&gt;</summary>
		<author><name>Admin</name></author>
	</entry>
	<entry>
		<id>https://wiki.my-network.at/index.php?title=Hauptseite&amp;diff=30</id>
		<title>Hauptseite</title>
		<link rel="alternate" type="text/html" href="https://wiki.my-network.at/index.php?title=Hauptseite&amp;diff=30"/>
		<updated>2022-08-24T11:35:56Z</updated>

		<summary type="html">&lt;p&gt;Admin: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&amp;lt;span style=&amp;quot;font-size: 24pt;&amp;quot;&amp;gt;Hier entsteht ein kleines privates Wikipedia&amp;lt;/span&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;span style=&amp;quot;font-size: 14pt;&amp;quot;&amp;gt;[https://wiki.my-network.at/index.php/Spezial:Alle_Seiten Zur Übersicht der Wiki Seiten hier entlang]&amp;lt;/span&amp;gt;&lt;br /&gt;
&amp;lt;span style=&amp;quot;font-size: 14pt;&amp;quot;&amp;gt;oder einfach links auf &amp;quot;Alle Seiten&amp;quot; klicken.&amp;lt;/span&amp;gt;&lt;/div&gt;</summary>
		<author><name>Admin</name></author>
	</entry>
	<entry>
		<id>https://wiki.my-network.at/index.php?title=Hauptseite&amp;diff=29</id>
		<title>Hauptseite</title>
		<link rel="alternate" type="text/html" href="https://wiki.my-network.at/index.php?title=Hauptseite&amp;diff=29"/>
		<updated>2022-08-24T11:35:41Z</updated>

		<summary type="html">&lt;p&gt;Admin: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&amp;lt;span style=&amp;quot;font-size: 24pt;&amp;quot; &amp;gt;Hier entsteht ein kleines privates Wikipedia&amp;lt;/span&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;span style=&amp;quot;font-size: 14pt;&amp;quot; &amp;gt;[https://wiki.my-network.at/index.php/Spezial:Alle_Seiten Zur Übersicht der Wiki Seiten hier entlang]&amp;lt;/span&amp;gt;&lt;br /&gt;
&amp;lt;span style=&amp;quot;font-size: 14pt;&amp;quot; &amp;gt;oder einfach links auf &amp;quot;Alle Seiten&amp;quot; klicken&amp;lt;/span&amp;gt;&lt;/div&gt;</summary>
		<author><name>Admin</name></author>
	</entry>
	<entry>
		<id>https://wiki.my-network.at/index.php?title=Raspberry_S.USV&amp;diff=28</id>
		<title>Raspberry S.USV</title>
		<link rel="alternate" type="text/html" href="https://wiki.my-network.at/index.php?title=Raspberry_S.USV&amp;diff=28"/>
		<updated>2022-08-24T11:30:25Z</updated>

		<summary type="html">&lt;p&gt;Admin: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&amp;lt;p dir=&amp;quot;auto&amp;quot;&amp;gt;'''Skript um USV Zustände auszulesen und unter IO-Broker anzeigen Datenpunkte zu erstellen,'''&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p dir=&amp;quot;auto&amp;quot;&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p dir=&amp;quot;auto&amp;quot;&amp;gt;Unter&amp;lt;/p&amp;gt;&lt;br /&gt;
[https://forum.iobroker.net/topic/15963/www.s-usv.com www.s-usv.com]&amp;lt;p dir=&amp;quot;auto&amp;quot;&amp;gt;sind verschiedene Varianten der &amp;quot;S.USV Pi uninterrupted power supply&amp;quot; erhältlich.&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p dir=&amp;quot;auto&amp;quot;&amp;gt;Dies sind Aufsteckplatinen für den Raspberry Pi, die eine unterbrechungsfreie Stromversorgung ermöglichen und insbesondere auch ein Wiederanlaufen bei Rückkehr des Stomnetzes erlauben.&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p dir=&amp;quot;auto&amp;quot;&amp;gt;Zur Ansteuerung der S.USV wird ein Daemon installiert, der sich um das Herunterfahren (auch zeitgesteuert) kümmert.&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p dir=&amp;quot;auto&amp;quot;&amp;gt;Dazu gibt es ein Program '''susv''', mit dessen Hilfe man verschiedene Einstellungen vornehmen kann und vor allem auch den aktuellen Status abfragen kann. Letzteres macht dieses Skript und erzeugt aus dem Status eine Reihe von Datenpunkten:&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p dir=&amp;quot;auto&amp;quot;&amp;gt;Hier nun das Skript:&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;blockquote&amp;gt;&amp;lt;p dir=&amp;quot;auto&amp;quot;&amp;gt;! // Script to drive the S.USV Pi uninterrupted power supply&amp;lt;br&amp;gt;! // See&amp;lt;/p&amp;gt;&lt;br /&gt;
[http://www.s-usv.de/ http://www.s-usv.de]&amp;lt;p dir=&amp;quot;auto&amp;quot;&amp;gt;for details.&amp;lt;br&amp;gt;! // NOTE: This script uses the S.USV demon and client software&amp;lt;br&amp;gt;! // (available on same website) so you must install it before.&amp;lt;br&amp;gt;! // Version 1.3, October 2018, Ralf Schaefer&amp;lt;br&amp;gt;! // –----------- Configuration variables -------------&amp;lt;br&amp;gt;! var PollTime = 60; // how often will we poll the usv (in sec)&amp;lt;br&amp;gt;! var susv = '/opt/susvd/susv'; // where is the susv client executable&amp;lt;br&amp;gt;! var idUSV = 'USV.'; // prefix for object tree&amp;lt;br&amp;gt;! var logLevel = 0; // set to 1 for some logging messages&amp;lt;br&amp;gt;! // ------------- Do not modify below this point -------------&amp;lt;br&amp;gt;! var idModel = idUSV + 'Model';&amp;lt;br&amp;gt;! var idFirmware = idUSV + 'FirmwareVersion';&amp;lt;br&amp;gt;! var idSoftware = idUSV + 'SoftwareVersion';&amp;lt;br&amp;gt;! var idHardware = idUSV + 'HardwareVersion';&amp;lt;br&amp;gt;! var idMailNotification = idUSV + 'MailNotification';&amp;lt;br&amp;gt;! var idTimedBoot = idUSV + 'TimedBoot';&amp;lt;br&amp;gt;! var idBootTime = idUSV + 'BootTime';&amp;lt;br&amp;gt;! var idTimedShutdown = idUSV + 'TimedShutdown';&amp;lt;br&amp;gt;! var idShutdownTime = idUSV + 'ShutdownTime';&amp;lt;br&amp;gt;! var idSUSVOK = idUSV + 'SUSVOK';&amp;lt;br&amp;gt;! var idMainsOk = idUSV + 'MainsOK';&amp;lt;br&amp;gt;! var idPoweringSource = idUSV + 'PoweringSource';&amp;lt;br&amp;gt;! var idChargingCircuit = idUSV + 'ChargingCircuit';&amp;lt;br&amp;gt;! var idCharging = idUSV + 'Charging';&amp;lt;br&amp;gt;! var idVoltageIn = idUSV + 'VoltageIn';&amp;lt;br&amp;gt;! var idVoltageInDeviation = idUSV + 'VoltageInDeviation';&amp;lt;br&amp;gt;! var idBatteryCapacity = idUSV + 'BatteryCapacity';&amp;lt;br&amp;gt;! var idBatteryVoltage = idUSV + 'BatteryVoltage';&amp;lt;br&amp;gt;! var idPowerBattery = idUSV + 'PowerBattery';&amp;lt;br&amp;gt;! var idVISBatteryLevel = idUSV + 'BatteryLevel';&amp;lt;br&amp;gt;! var idShutdownTimer = idUSV + 'ShutdownTimer';&amp;lt;br&amp;gt;! var idAutostart = idUSV + 'Autostart';&amp;lt;br&amp;gt;! var idSleepTimer = idUSV + 'SleepTimer';&amp;lt;br&amp;gt;! createState(idModel, 0, { name: 'Model', type: 'string' }); // 'Basic', '???''&amp;lt;br&amp;gt;! createState(idFirmware, 0, { name: 'Firmware version', type: 'string' }); // '2.61'&amp;lt;br&amp;gt;! createState(idSoftware, 0, { name: 'Software version', type: 'string' }); // '2.40'&amp;lt;br&amp;gt;! createState(idHardware, 0, { name: 'Hardware version', type: 'string' }); // '2.1'&amp;lt;br&amp;gt;! createState(idMailNotification, 0, { name: 'Mail notification', type: 'boolean' });&amp;lt;br&amp;gt;! createState(idTimedBoot, 0, { name: 'Timed boot', type: 'boolean' }); // 'HH:mm:ss'&amp;lt;br&amp;gt;! createState(idBootTime, 0, { name: 'Boot time', type: 'string' });&amp;lt;br&amp;gt;! createState(idTimedShutdown, 0, { name: 'Timed shutdown', type: 'boolean' });&amp;lt;br&amp;gt;! createState(idShutdownTime, 0, { name: 'Shutdown time', type: 'string' }); // 'HH:mm:ss'&amp;lt;br&amp;gt;! createState(idSUSVOK, 0, { name: 'Zugriff auf SUSV ok', type: 'boolean' });&amp;lt;br&amp;gt;! createState(idMainsOk, false, { name: 'Netz vorhanden', type: 'boolean' }); // true if PoweringSource != 'Battery'&amp;lt;br&amp;gt;! createState(idPoweringSource, '', { name: 'Energiequelle', type: 'string' }); // 'Primary', 'Battery'&amp;lt;br&amp;gt;! createState(idChargingCircuit, '', { name: 'Batterielader', type: 'string' }); // 'ONLINE', 'OFFLINE'&amp;lt;br&amp;gt;! createState(idCharging, false, { name: 'Akku wird geladen', type: 'boolean' }); // true if battery is charged&amp;lt;br&amp;gt;! createState(idVoltageIn, 0, { name: 'Eingangsspannung', type: 'number', min: 0, max: 5.5, unit: 'V' });&amp;lt;br&amp;gt;! createState(idVoltageInDeviation, 0, { name: 'Abweichung Eingangsspannung', type: 'number', min: -20, max: 20, unit: &amp;quot;%&amp;quot; }); // deviation from 5.00V&amp;lt;br&amp;gt;! createState(idBatteryCapacity, 0, { name: 'Verbleibende Akkukapazitaet', type: 'number', min: 0, max: 100, unit: &amp;quot;%&amp;quot; });&amp;lt;br&amp;gt;! createState(idBatteryVoltage, 0, { name: 'Akkuspannung', type: 'number', min: 0, max: 5.5, unit: 'V' });&amp;lt;br&amp;gt;! createState(idPowerBattery, 0, { name: 'Batteriestrom', type: 'number', min: 0, max: 2000, unit: 'mA' }); // 0 if PoweringSource != 'Battery'&amp;lt;br&amp;gt;! createState(idVISBatteryLevel, 0, { name: 'Batterielevel (0..4 für VIS)', type: 'number', min: 0, max: 4 }); // can be used in VIS to switch icons&amp;lt;br&amp;gt;! createState(idShutdownTimer, 0, { name: 'Shutdown timer', type: 'number' }); //&amp;lt;br&amp;gt;! createState(idAutostart, false, { name: 'Autostart', type: 'boolean' }); // 'enabled' ??&amp;lt;br&amp;gt;! createState(idSleepTimer, 0, { name: 'Sleep timer', type: 'number' }); //&amp;lt;br&amp;gt;! // Backup variables - we want to call setState only on value changes&amp;lt;br&amp;gt;! var vModel = null;&amp;lt;br&amp;gt;! var vFirmware = null;&amp;lt;br&amp;gt;! var vSoftware = null;&amp;lt;br&amp;gt;! var vHardware = null;&amp;lt;br&amp;gt;! var vMailNotification = null;&amp;lt;br&amp;gt;! var vTimedBoot = null;&amp;lt;br&amp;gt;! var vBootTime = null;&amp;lt;br&amp;gt;! var vTimedShutdown = null;&amp;lt;br&amp;gt;! var vShutdownTime = null;&amp;lt;br&amp;gt;! var vMainsOk = null;&amp;lt;br&amp;gt;! var vPoweringSource = null;&amp;lt;br&amp;gt;! var vChargingCircuit = null;&amp;lt;br&amp;gt;! var vCharging = null;&amp;lt;br&amp;gt;! var vVoltageIn = null;&amp;lt;br&amp;gt;! var vVoltageInDeviation = null;&amp;lt;br&amp;gt;! var vBatteryCapacity = null;&amp;lt;br&amp;gt;! var vBatteryVoltage = null;&amp;lt;br&amp;gt;! var vPowerBattery = null;&amp;lt;br&amp;gt;! var vVISBatteryLevel = null;&amp;lt;br&amp;gt;! var vShutdownTimer = null;&amp;lt;br&amp;gt;! var vAutostart = null;&amp;lt;br&amp;gt;! var vSleepTimer = null;&amp;lt;br&amp;gt;! function GetUSVStatus() {&amp;lt;br&amp;gt;! var SWVersion = '';&amp;lt;br&amp;gt;! exec(susv + ' -status', function(err, stdout, stderr) {&amp;lt;br&amp;gt;! if (err) {&amp;lt;br&amp;gt;! log(err + ': ' + stdout);&amp;lt;br&amp;gt;! setState(idSUSVOK, false, true);&amp;lt;br&amp;gt;! return;&amp;lt;br&amp;gt;! }&amp;lt;br&amp;gt;! else&amp;lt;br&amp;gt;! {&amp;lt;br&amp;gt;! // Unlike other values we set the state always, to have a recent time stamp&amp;lt;br&amp;gt;! setState(idSUSVOK, true, true);&amp;lt;br&amp;gt;! }&amp;lt;br&amp;gt;! stdout = stdout.split('\n');&amp;lt;br&amp;gt;! stdout.forEach(function(line) {&amp;lt;br&amp;gt;! var v;&amp;lt;br&amp;gt;! if (contains(line, 'Model:'))&amp;lt;br&amp;gt;! {&amp;lt;br&amp;gt;! v = snip(line, ' ');&amp;lt;br&amp;gt;! if (vModel !== v)&amp;lt;br&amp;gt;! setState(idModel, vModel = v, true);&amp;lt;br&amp;gt;! }&amp;lt;br&amp;gt;! else if (contains(line, 'Firmware Version'))&amp;lt;br&amp;gt;! {&amp;lt;br&amp;gt;! v = snip(line, ' ');&amp;lt;br&amp;gt;! if (vFirmware !== v)&amp;lt;br&amp;gt;! setState(idFirmware, vFirmware = v, true);&amp;lt;br&amp;gt;! }&amp;lt;br&amp;gt;! else if (contains(line, 'Software Version'))&amp;lt;br&amp;gt;! {&amp;lt;br&amp;gt;! v = snip(line, ' ');&amp;lt;br&amp;gt;! if (v !== '2.20' &amp;amp;&amp;amp; v !== '2.33' &amp;amp;&amp;amp; v !== '2.40')&amp;lt;br&amp;gt;! log('Unexpected software version ' + v + ', possibly not all values are correctly identified.')&amp;lt;br&amp;gt;! if (vSoftware !== v)&amp;lt;br&amp;gt;! setState(idSoftware, vSoftware = v, true);&amp;lt;br&amp;gt;! }&amp;lt;br&amp;gt;! else if (contains(line, 'Hardware Version'))&amp;lt;br&amp;gt;! {&amp;lt;br&amp;gt;! v = snip(line, ' ');&amp;lt;br&amp;gt;! if (vHardware !== v)&amp;lt;br&amp;gt;! setState(idHardware, vHardware = v, true);&amp;lt;br&amp;gt;! }&amp;lt;br&amp;gt;! else if (contains(line, 'Mail notification'))&amp;lt;br&amp;gt;! {&amp;lt;br&amp;gt;! v = snip(line, ' ');&amp;lt;br&amp;gt;! v = (v == 'Enabled');&amp;lt;br&amp;gt;! if (vMailNotification !== v)&amp;lt;br&amp;gt;! setState(idMailNotification, vMailNotification = v, true);&amp;lt;br&amp;gt;! }&amp;lt;br&amp;gt;! else if (contains(line, 'Timed Boot'))&amp;lt;br&amp;gt;! {&amp;lt;br&amp;gt;! v = snip(line, ' ');&amp;lt;br&amp;gt;! v = (v == 'Enabled');&amp;lt;br&amp;gt;! if (vTimedBoot !== v)&amp;lt;br&amp;gt;! setState(idTimedBoot, vTimedBoot = v, true);&amp;lt;br&amp;gt;! }&amp;lt;br&amp;gt;! else if (contains(line, 'Boot time'))&amp;lt;br&amp;gt;! {&amp;lt;br&amp;gt;! v = snip(line, ' ');&amp;lt;br&amp;gt;! if (vBootTime !== v)&amp;lt;br&amp;gt;! setState(idBootTime, vBootTime = v, true);&amp;lt;br&amp;gt;! }&amp;lt;br&amp;gt;! else if (contains(line, 'Timed Shutdown'))&amp;lt;br&amp;gt;! {&amp;lt;br&amp;gt;! v = snip(line, ' ');&amp;lt;br&amp;gt;! v = (v == 'Enabled');&amp;lt;br&amp;gt;! if (vTimedShutdown !== v)&amp;lt;br&amp;gt;! setState(idTimedShutdown, vTimedShutdown = v, true);&amp;lt;br&amp;gt;! }&amp;lt;br&amp;gt;! else if (contains(line, 'Shutdown time:'))&amp;lt;br&amp;gt;! {&amp;lt;br&amp;gt;! v = snip(line, ' ');&amp;lt;br&amp;gt;! if (vShutdownTime !== v)&amp;lt;br&amp;gt;! setState(idShutdownTime, vShutdownTime = v, true);&amp;lt;br&amp;gt;! }&amp;lt;br&amp;gt;! else if (contains(line, 'Powering Source'))&amp;lt;br&amp;gt;! {&amp;lt;br&amp;gt;! v = snip(line, ' ');&amp;lt;br&amp;gt;! if (logLevel)&amp;lt;br&amp;gt;! log('PowerSource v=' + v);&amp;lt;br&amp;gt;! if (vPoweringSource !== v)&amp;lt;br&amp;gt;! setState(idPoweringSource, vPoweringSource = v, true);&amp;lt;br&amp;gt;! v = (v != 'Battery');&amp;lt;br&amp;gt;! if (logLevel)&amp;lt;br&amp;gt;! log('MainOK v=' + v);&amp;lt;br&amp;gt;! if (vMainsOk !== v)&amp;lt;br&amp;gt;! setState(idMainsOk, vMainsOk = v, true);&amp;lt;br&amp;gt;! }&amp;lt;br&amp;gt;! else if (contains(line, 'Charging circuit'))&amp;lt;br&amp;gt;! {&amp;lt;br&amp;gt;! v = snip(line, ' ');&amp;lt;br&amp;gt;! if (vChargingCircuit !== v)&amp;lt;br&amp;gt;! setState(idChargingCircuit, vChargingCircuit = v, true);&amp;lt;br&amp;gt;! v = (v != 'OFFLINE');&amp;lt;br&amp;gt;! if (vCharging !== v)&amp;lt;br&amp;gt;! setState(idCharging, vCharging = v, true);&amp;lt;br&amp;gt;! }&amp;lt;br&amp;gt;! else if (contains(line, 'Voltage in'))&amp;lt;br&amp;gt;! {&amp;lt;br&amp;gt;! v = parseFloat(snip(line, ' V'));&amp;lt;br&amp;gt;! if (vVoltageIn !== v)&amp;lt;br&amp;gt;! setState(idVoltageIn, vVoltageIn = v, true);&amp;lt;br&amp;gt;! v = Math.round((v-5)/v''100''10)/10;&amp;lt;br&amp;gt;! if (vVoltageInDeviation !== v)&amp;lt;br&amp;gt;! setState(idVoltageInDeviation, vVoltageInDeviation = v, true);&amp;lt;br&amp;gt;! }&amp;lt;br&amp;gt;! else if (contains(line, 'Battery capacity'))&amp;lt;br&amp;gt;! {&amp;lt;br&amp;gt;! v = parseInt(snip(line, '%'));&amp;lt;br&amp;gt;! if (vBatteryCapacity !== v)&amp;lt;br&amp;gt;! setState(idBatteryCapacity, vBatteryCapacity = v, true);&amp;lt;br&amp;gt;! v = Math.round(parseInt(v) / 25); // 0..100% --&amp;amp;gt; 0..4&amp;lt;br&amp;gt;! if (vVISBatteryLevel !== v)&amp;lt;br&amp;gt;! setState(idVISBatteryLevel, vVISBatteryLevel = v, true);&amp;lt;br&amp;gt;! }&amp;lt;br&amp;gt;! else if (contains(line, 'Battery voltage'))&amp;lt;br&amp;gt;! {&amp;lt;br&amp;gt;! v = parseFloat(snip(line, 'V'));&amp;lt;br&amp;gt;! if (vBatteryVoltage !== v)&amp;lt;br&amp;gt;! setState(idBatteryVoltage, vBatteryVoltage = v, true);&amp;lt;br&amp;gt;! }&amp;lt;br&amp;gt;! else if (contains(line, 'Power Battery'))&amp;lt;br&amp;gt;! {&amp;lt;br&amp;gt;! v = parseFloat(snip(line, ' mA'));&amp;lt;br&amp;gt;! if (vPowerBattery !== v)&amp;lt;br&amp;gt;! setState(idPowerBattery, vPowerBattery = v, true);&amp;lt;br&amp;gt;! }&amp;lt;br&amp;gt;! else if (contains(line, 'Shutdown timer'))&amp;lt;br&amp;gt;! {&amp;lt;br&amp;gt;! v = parseInt(snip(line, ' '));&amp;lt;br&amp;gt;! if (vShutdownTimer !== v)&amp;lt;br&amp;gt;! setState(idShutdownTimer, vShutdownTimer = v, true);&amp;lt;br&amp;gt;! }&amp;lt;br&amp;gt;! else if (contains(line, 'Autostart'))&amp;lt;br&amp;gt;! {&amp;lt;br&amp;gt;! v = snip(line, ' ');&amp;lt;br&amp;gt;! v = (v == 'enabled');&amp;lt;br&amp;gt;! if (vAutostart !== v)&amp;lt;br&amp;gt;! setState(idAutostart, vAutostart = v, true);&amp;lt;br&amp;gt;! }&amp;lt;br&amp;gt;! else if (contains(line, 'Sleep timer'))&amp;lt;br&amp;gt;! {&amp;lt;br&amp;gt;! v = parseFloat(snip(line, ' '));&amp;lt;br&amp;gt;! if (vSleepTimer !== v)&amp;lt;br&amp;gt;! setState(idSleepTimer, vSleepTimer = v, true);&amp;lt;br&amp;gt;! }&amp;lt;br&amp;gt;! });&amp;lt;br&amp;gt;! });&amp;lt;br&amp;gt;! }&amp;lt;br&amp;gt;! setInterval(GetUSVStatus, PollTime * 1000);&amp;lt;br&amp;gt;! // Return true if needle is found in hay, false otherwise&amp;lt;br&amp;gt;! function contains(hay, needle) {&amp;lt;br&amp;gt;! return hay.indexOf(needle) &amp;amp;gt; -1;&amp;lt;br&amp;gt;! }&amp;lt;br&amp;gt;! // snip out everything between the colon and the specified end tag.&amp;lt;br&amp;gt;! // Example:&amp;lt;br&amp;gt;! // snip('* Battery capacity: 69.60% *', '%') =&amp;amp;gt; '69.60'&amp;lt;br&amp;gt;! function snip(line, endtag) {&amp;lt;br&amp;gt;! var idx = line.indexOf(':');&amp;lt;br&amp;gt;! if (idx &amp;amp;lt; 1)&amp;lt;br&amp;gt;! return '';&amp;lt;br&amp;gt;! line = line.substring(idx + 2);&amp;lt;br&amp;gt;! idx = line.indexOf(endtag);&amp;lt;br&amp;gt;! if (idx &amp;amp;lt; 1)&amp;lt;br&amp;gt;! return '';&amp;lt;br&amp;gt;! return line.substring(0, idx);&amp;lt;br&amp;gt;! }&amp;lt;/p&amp;gt;&amp;lt;/blockquote&amp;gt;&lt;/div&gt;</summary>
		<author><name>Admin</name></author>
	</entry>
	<entry>
		<id>https://wiki.my-network.at/index.php?title=Raspberry_S.USV&amp;diff=27</id>
		<title>Raspberry S.USV</title>
		<link rel="alternate" type="text/html" href="https://wiki.my-network.at/index.php?title=Raspberry_S.USV&amp;diff=27"/>
		<updated>2022-08-24T11:28:27Z</updated>

		<summary type="html">&lt;p&gt;Admin: Die Seite wurde neu angelegt: „&amp;lt;p dir=&amp;quot;auto&amp;quot;&amp;gt;Unter&amp;lt;/p&amp;gt;[https://forum.iobroker.net/topic/15963/www.s-usv.com www.s-usv.com]&amp;lt;p dir=&amp;quot;auto&amp;quot;&amp;gt;sind verschiedene Varianten der &amp;quot;S.USV Pi uninterrupte…“&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&amp;lt;p dir=&amp;quot;auto&amp;quot;&amp;gt;Unter&amp;lt;/p&amp;gt;[https://forum.iobroker.net/topic/15963/www.s-usv.com www.s-usv.com]&amp;lt;p dir=&amp;quot;auto&amp;quot;&amp;gt;sind verschiedene Varianten der &amp;quot;S.USV Pi uninterrupted power supply&amp;quot; erhältlich.&amp;lt;/p&amp;gt;&amp;lt;p dir=&amp;quot;auto&amp;quot;&amp;gt;Dies sind Aufsteckplatinen für den Raspberry Pi, die eine unterbrechungsfreie Stromversorgung ermöglichen und insbesondere auch ein Wiederanlaufen bei Rückkehr des Stomnetzes erlauben.&amp;lt;/p&amp;gt;&amp;lt;p dir=&amp;quot;auto&amp;quot;&amp;gt;Zur Ansteuerung der S.USV wird ein Daemon installiert, der sich um das Herunterfahren (auch zeitgesteuert) kümmert.&amp;lt;/p&amp;gt;&amp;lt;p dir=&amp;quot;auto&amp;quot;&amp;gt;Dazu gibt es ein Program '''susv''', mit dessen Hilfe man verschiedene Einstellungen vornehmen kann und vor allem auch den aktuellen Status abfragen kann. Letzteres macht dieses Skript und erzeugt aus dem Status eine Reihe von Datenpunkten:&amp;lt;/p&amp;gt;&amp;lt;p dir=&amp;quot;auto&amp;quot;&amp;gt;Hier nun das Skript:&amp;lt;/p&amp;gt;&amp;lt;blockquote&amp;gt;&amp;lt;p dir=&amp;quot;auto&amp;quot;&amp;gt;! // Script to drive the S.USV Pi uninterrupted power supply&amp;lt;br&amp;gt;! // See&amp;lt;/p&amp;gt;[http://www.s-usv.de/ http://www.s-usv.de]&amp;lt;p dir=&amp;quot;auto&amp;quot;&amp;gt;for details.&amp;lt;br&amp;gt;! // NOTE: This script uses the S.USV demon and client software&amp;lt;br&amp;gt;! // (available on same website) so you must install it before.&amp;lt;br&amp;gt;! // Version 1.3, October 2018, Ralf Schaefer&amp;lt;br&amp;gt;! // –----------- Configuration variables -------------&amp;lt;br&amp;gt;! var PollTime = 60; // how often will we poll the usv (in sec)&amp;lt;br&amp;gt;! var susv = '/opt/susvd/susv'; // where is the susv client executable&amp;lt;br&amp;gt;! var idUSV = 'USV.'; // prefix for object tree&amp;lt;br&amp;gt;! var logLevel = 0; // set to 1 for some logging messages&amp;lt;br&amp;gt;! // ------------- Do not modify below this point -------------&amp;lt;br&amp;gt;! var idModel = idUSV + 'Model';&amp;lt;br&amp;gt;! var idFirmware = idUSV + 'FirmwareVersion';&amp;lt;br&amp;gt;! var idSoftware = idUSV + 'SoftwareVersion';&amp;lt;br&amp;gt;! var idHardware = idUSV + 'HardwareVersion';&amp;lt;br&amp;gt;! var idMailNotification = idUSV + 'MailNotification';&amp;lt;br&amp;gt;! var idTimedBoot = idUSV + 'TimedBoot';&amp;lt;br&amp;gt;! var idBootTime = idUSV + 'BootTime';&amp;lt;br&amp;gt;! var idTimedShutdown = idUSV + 'TimedShutdown';&amp;lt;br&amp;gt;! var idShutdownTime = idUSV + 'ShutdownTime';&amp;lt;br&amp;gt;! var idSUSVOK = idUSV + 'SUSVOK';&amp;lt;br&amp;gt;! var idMainsOk = idUSV + 'MainsOK';&amp;lt;br&amp;gt;! var idPoweringSource = idUSV + 'PoweringSource';&amp;lt;br&amp;gt;! var idChargingCircuit = idUSV + 'ChargingCircuit';&amp;lt;br&amp;gt;! var idCharging = idUSV + 'Charging';&amp;lt;br&amp;gt;! var idVoltageIn = idUSV + 'VoltageIn';&amp;lt;br&amp;gt;! var idVoltageInDeviation = idUSV + 'VoltageInDeviation';&amp;lt;br&amp;gt;! var idBatteryCapacity = idUSV + 'BatteryCapacity';&amp;lt;br&amp;gt;! var idBatteryVoltage = idUSV + 'BatteryVoltage';&amp;lt;br&amp;gt;! var idPowerBattery = idUSV + 'PowerBattery';&amp;lt;br&amp;gt;! var idVISBatteryLevel = idUSV + 'BatteryLevel';&amp;lt;br&amp;gt;! var idShutdownTimer = idUSV + 'ShutdownTimer';&amp;lt;br&amp;gt;! var idAutostart = idUSV + 'Autostart';&amp;lt;br&amp;gt;! var idSleepTimer = idUSV + 'SleepTimer';&amp;lt;br&amp;gt;! createState(idModel, 0, { name: 'Model', type: 'string' }); // 'Basic', '???''&amp;lt;br&amp;gt;! createState(idFirmware, 0, { name: 'Firmware version', type: 'string' }); // '2.61'&amp;lt;br&amp;gt;! createState(idSoftware, 0, { name: 'Software version', type: 'string' }); // '2.40'&amp;lt;br&amp;gt;! createState(idHardware, 0, { name: 'Hardware version', type: 'string' }); // '2.1'&amp;lt;br&amp;gt;! createState(idMailNotification, 0, { name: 'Mail notification', type: 'boolean' });&amp;lt;br&amp;gt;! createState(idTimedBoot, 0, { name: 'Timed boot', type: 'boolean' }); // 'HH:mm:ss'&amp;lt;br&amp;gt;! createState(idBootTime, 0, { name: 'Boot time', type: 'string' });&amp;lt;br&amp;gt;! createState(idTimedShutdown, 0, { name: 'Timed shutdown', type: 'boolean' });&amp;lt;br&amp;gt;! createState(idShutdownTime, 0, { name: 'Shutdown time', type: 'string' }); // 'HH:mm:ss'&amp;lt;br&amp;gt;! createState(idSUSVOK, 0, { name: 'Zugriff auf SUSV ok', type: 'boolean' });&amp;lt;br&amp;gt;! createState(idMainsOk, false, { name: 'Netz vorhanden', type: 'boolean' }); // true if PoweringSource != 'Battery'&amp;lt;br&amp;gt;! createState(idPoweringSource, '', { name: 'Energiequelle', type: 'string' }); // 'Primary', 'Battery'&amp;lt;br&amp;gt;! createState(idChargingCircuit, '', { name: 'Batterielader', type: 'string' }); // 'ONLINE', 'OFFLINE'&amp;lt;br&amp;gt;! createState(idCharging, false, { name: 'Akku wird geladen', type: 'boolean' }); // true if battery is charged&amp;lt;br&amp;gt;! createState(idVoltageIn, 0, { name: 'Eingangsspannung', type: 'number', min: 0, max: 5.5, unit: 'V' });&amp;lt;br&amp;gt;! createState(idVoltageInDeviation, 0, { name: 'Abweichung Eingangsspannung', type: 'number', min: -20, max: 20, unit: &amp;quot;%&amp;quot; }); // deviation from 5.00V&amp;lt;br&amp;gt;! createState(idBatteryCapacity, 0, { name: 'Verbleibende Akkukapazitaet', type: 'number', min: 0, max: 100, unit: &amp;quot;%&amp;quot; });&amp;lt;br&amp;gt;! createState(idBatteryVoltage, 0, { name: 'Akkuspannung', type: 'number', min: 0, max: 5.5, unit: 'V' });&amp;lt;br&amp;gt;! createState(idPowerBattery, 0, { name: 'Batteriestrom', type: 'number', min: 0, max: 2000, unit: 'mA' }); // 0 if PoweringSource != 'Battery'&amp;lt;br&amp;gt;! createState(idVISBatteryLevel, 0, { name: 'Batterielevel (0..4 für VIS)', type: 'number', min: 0, max: 4 }); // can be used in VIS to switch icons&amp;lt;br&amp;gt;! createState(idShutdownTimer, 0, { name: 'Shutdown timer', type: 'number' }); //&amp;lt;br&amp;gt;! createState(idAutostart, false, { name: 'Autostart', type: 'boolean' }); // 'enabled' ??&amp;lt;br&amp;gt;! createState(idSleepTimer, 0, { name: 'Sleep timer', type: 'number' }); //&amp;lt;br&amp;gt;! // Backup variables - we want to call setState only on value changes&amp;lt;br&amp;gt;! var vModel = null;&amp;lt;br&amp;gt;! var vFirmware = null;&amp;lt;br&amp;gt;! var vSoftware = null;&amp;lt;br&amp;gt;! var vHardware = null;&amp;lt;br&amp;gt;! var vMailNotification = null;&amp;lt;br&amp;gt;! var vTimedBoot = null;&amp;lt;br&amp;gt;! var vBootTime = null;&amp;lt;br&amp;gt;! var vTimedShutdown = null;&amp;lt;br&amp;gt;! var vShutdownTime = null;&amp;lt;br&amp;gt;! var vMainsOk = null;&amp;lt;br&amp;gt;! var vPoweringSource = null;&amp;lt;br&amp;gt;! var vChargingCircuit = null;&amp;lt;br&amp;gt;! var vCharging = null;&amp;lt;br&amp;gt;! var vVoltageIn = null;&amp;lt;br&amp;gt;! var vVoltageInDeviation = null;&amp;lt;br&amp;gt;! var vBatteryCapacity = null;&amp;lt;br&amp;gt;! var vBatteryVoltage = null;&amp;lt;br&amp;gt;! var vPowerBattery = null;&amp;lt;br&amp;gt;! var vVISBatteryLevel = null;&amp;lt;br&amp;gt;! var vShutdownTimer = null;&amp;lt;br&amp;gt;! var vAutostart = null;&amp;lt;br&amp;gt;! var vSleepTimer = null;&amp;lt;br&amp;gt;! function GetUSVStatus() {&amp;lt;br&amp;gt;! var SWVersion = '';&amp;lt;br&amp;gt;! exec(susv + ' -status', function(err, stdout, stderr) {&amp;lt;br&amp;gt;! if (err) {&amp;lt;br&amp;gt;! log(err + ': ' + stdout);&amp;lt;br&amp;gt;! setState(idSUSVOK, false, true);&amp;lt;br&amp;gt;! return;&amp;lt;br&amp;gt;! }&amp;lt;br&amp;gt;! else&amp;lt;br&amp;gt;! {&amp;lt;br&amp;gt;! // Unlike other values we set the state always, to have a recent time stamp&amp;lt;br&amp;gt;! setState(idSUSVOK, true, true);&amp;lt;br&amp;gt;! }&amp;lt;br&amp;gt;! stdout = stdout.split('\n');&amp;lt;br&amp;gt;! stdout.forEach(function(line) {&amp;lt;br&amp;gt;! var v;&amp;lt;br&amp;gt;! if (contains(line, 'Model:'))&amp;lt;br&amp;gt;! {&amp;lt;br&amp;gt;! v = snip(line, ' ');&amp;lt;br&amp;gt;! if (vModel !== v)&amp;lt;br&amp;gt;! setState(idModel, vModel = v, true);&amp;lt;br&amp;gt;! }&amp;lt;br&amp;gt;! else if (contains(line, 'Firmware Version'))&amp;lt;br&amp;gt;! {&amp;lt;br&amp;gt;! v = snip(line, ' ');&amp;lt;br&amp;gt;! if (vFirmware !== v)&amp;lt;br&amp;gt;! setState(idFirmware, vFirmware = v, true);&amp;lt;br&amp;gt;! }&amp;lt;br&amp;gt;! else if (contains(line, 'Software Version'))&amp;lt;br&amp;gt;! {&amp;lt;br&amp;gt;! v = snip(line, ' ');&amp;lt;br&amp;gt;! if (v !== '2.20' &amp;amp;&amp;amp; v !== '2.33' &amp;amp;&amp;amp; v !== '2.40')&amp;lt;br&amp;gt;! log('Unexpected software version ' + v + ', possibly not all values are correctly identified.')&amp;lt;br&amp;gt;! if (vSoftware !== v)&amp;lt;br&amp;gt;! setState(idSoftware, vSoftware = v, true);&amp;lt;br&amp;gt;! }&amp;lt;br&amp;gt;! else if (contains(line, 'Hardware Version'))&amp;lt;br&amp;gt;! {&amp;lt;br&amp;gt;! v = snip(line, ' ');&amp;lt;br&amp;gt;! if (vHardware !== v)&amp;lt;br&amp;gt;! setState(idHardware, vHardware = v, true);&amp;lt;br&amp;gt;! }&amp;lt;br&amp;gt;! else if (contains(line, 'Mail notification'))&amp;lt;br&amp;gt;! {&amp;lt;br&amp;gt;! v = snip(line, ' ');&amp;lt;br&amp;gt;! v = (v == 'Enabled');&amp;lt;br&amp;gt;! if (vMailNotification !== v)&amp;lt;br&amp;gt;! setState(idMailNotification, vMailNotification = v, true);&amp;lt;br&amp;gt;! }&amp;lt;br&amp;gt;! else if (contains(line, 'Timed Boot'))&amp;lt;br&amp;gt;! {&amp;lt;br&amp;gt;! v = snip(line, ' ');&amp;lt;br&amp;gt;! v = (v == 'Enabled');&amp;lt;br&amp;gt;! if (vTimedBoot !== v)&amp;lt;br&amp;gt;! setState(idTimedBoot, vTimedBoot = v, true);&amp;lt;br&amp;gt;! }&amp;lt;br&amp;gt;! else if (contains(line, 'Boot time'))&amp;lt;br&amp;gt;! {&amp;lt;br&amp;gt;! v = snip(line, ' ');&amp;lt;br&amp;gt;! if (vBootTime !== v)&amp;lt;br&amp;gt;! setState(idBootTime, vBootTime = v, true);&amp;lt;br&amp;gt;! }&amp;lt;br&amp;gt;! else if (contains(line, 'Timed Shutdown'))&amp;lt;br&amp;gt;! {&amp;lt;br&amp;gt;! v = snip(line, ' ');&amp;lt;br&amp;gt;! v = (v == 'Enabled');&amp;lt;br&amp;gt;! if (vTimedShutdown !== v)&amp;lt;br&amp;gt;! setState(idTimedShutdown, vTimedShutdown = v, true);&amp;lt;br&amp;gt;! }&amp;lt;br&amp;gt;! else if (contains(line, 'Shutdown time:'))&amp;lt;br&amp;gt;! {&amp;lt;br&amp;gt;! v = snip(line, ' ');&amp;lt;br&amp;gt;! if (vShutdownTime !== v)&amp;lt;br&amp;gt;! setState(idShutdownTime, vShutdownTime = v, true);&amp;lt;br&amp;gt;! }&amp;lt;br&amp;gt;! else if (contains(line, 'Powering Source'))&amp;lt;br&amp;gt;! {&amp;lt;br&amp;gt;! v = snip(line, ' ');&amp;lt;br&amp;gt;! if (logLevel)&amp;lt;br&amp;gt;! log('PowerSource v=' + v);&amp;lt;br&amp;gt;! if (vPoweringSource !== v)&amp;lt;br&amp;gt;! setState(idPoweringSource, vPoweringSource = v, true);&amp;lt;br&amp;gt;! v = (v != 'Battery');&amp;lt;br&amp;gt;! if (logLevel)&amp;lt;br&amp;gt;! log('MainOK v=' + v);&amp;lt;br&amp;gt;! if (vMainsOk !== v)&amp;lt;br&amp;gt;! setState(idMainsOk, vMainsOk = v, true);&amp;lt;br&amp;gt;! }&amp;lt;br&amp;gt;! else if (contains(line, 'Charging circuit'))&amp;lt;br&amp;gt;! {&amp;lt;br&amp;gt;! v = snip(line, ' ');&amp;lt;br&amp;gt;! if (vChargingCircuit !== v)&amp;lt;br&amp;gt;! setState(idChargingCircuit, vChargingCircuit = v, true);&amp;lt;br&amp;gt;! v = (v != 'OFFLINE');&amp;lt;br&amp;gt;! if (vCharging !== v)&amp;lt;br&amp;gt;! setState(idCharging, vCharging = v, true);&amp;lt;br&amp;gt;! }&amp;lt;br&amp;gt;! else if (contains(line, 'Voltage in'))&amp;lt;br&amp;gt;! {&amp;lt;br&amp;gt;! v = parseFloat(snip(line, ' V'));&amp;lt;br&amp;gt;! if (vVoltageIn !== v)&amp;lt;br&amp;gt;! setState(idVoltageIn, vVoltageIn = v, true);&amp;lt;br&amp;gt;! v = Math.round((v-5)/v''100''10)/10;&amp;lt;br&amp;gt;! if (vVoltageInDeviation !== v)&amp;lt;br&amp;gt;! setState(idVoltageInDeviation, vVoltageInDeviation = v, true);&amp;lt;br&amp;gt;! }&amp;lt;br&amp;gt;! else if (contains(line, 'Battery capacity'))&amp;lt;br&amp;gt;! {&amp;lt;br&amp;gt;! v = parseInt(snip(line, '%'));&amp;lt;br&amp;gt;! if (vBatteryCapacity !== v)&amp;lt;br&amp;gt;! setState(idBatteryCapacity, vBatteryCapacity = v, true);&amp;lt;br&amp;gt;! v = Math.round(parseInt(v) / 25); // 0..100% --&amp;amp;gt; 0..4&amp;lt;br&amp;gt;! if (vVISBatteryLevel !== v)&amp;lt;br&amp;gt;! setState(idVISBatteryLevel, vVISBatteryLevel = v, true);&amp;lt;br&amp;gt;! }&amp;lt;br&amp;gt;! else if (contains(line, 'Battery voltage'))&amp;lt;br&amp;gt;! {&amp;lt;br&amp;gt;! v = parseFloat(snip(line, 'V'));&amp;lt;br&amp;gt;! if (vBatteryVoltage !== v)&amp;lt;br&amp;gt;! setState(idBatteryVoltage, vBatteryVoltage = v, true);&amp;lt;br&amp;gt;! }&amp;lt;br&amp;gt;! else if (contains(line, 'Power Battery'))&amp;lt;br&amp;gt;! {&amp;lt;br&amp;gt;! v = parseFloat(snip(line, ' mA'));&amp;lt;br&amp;gt;! if (vPowerBattery !== v)&amp;lt;br&amp;gt;! setState(idPowerBattery, vPowerBattery = v, true);&amp;lt;br&amp;gt;! }&amp;lt;br&amp;gt;! else if (contains(line, 'Shutdown timer'))&amp;lt;br&amp;gt;! {&amp;lt;br&amp;gt;! v = parseInt(snip(line, ' '));&amp;lt;br&amp;gt;! if (vShutdownTimer !== v)&amp;lt;br&amp;gt;! setState(idShutdownTimer, vShutdownTimer = v, true);&amp;lt;br&amp;gt;! }&amp;lt;br&amp;gt;! else if (contains(line, 'Autostart'))&amp;lt;br&amp;gt;! {&amp;lt;br&amp;gt;! v = snip(line, ' ');&amp;lt;br&amp;gt;! v = (v == 'enabled');&amp;lt;br&amp;gt;! if (vAutostart !== v)&amp;lt;br&amp;gt;! setState(idAutostart, vAutostart = v, true);&amp;lt;br&amp;gt;! }&amp;lt;br&amp;gt;! else if (contains(line, 'Sleep timer'))&amp;lt;br&amp;gt;! {&amp;lt;br&amp;gt;! v = parseFloat(snip(line, ' '));&amp;lt;br&amp;gt;! if (vSleepTimer !== v)&amp;lt;br&amp;gt;! setState(idSleepTimer, vSleepTimer = v, true);&amp;lt;br&amp;gt;! }&amp;lt;br&amp;gt;! });&amp;lt;br&amp;gt;! });&amp;lt;br&amp;gt;! }&amp;lt;br&amp;gt;! setInterval(GetUSVStatus, PollTime * 1000);&amp;lt;br&amp;gt;! // Return true if needle is found in hay, false otherwise&amp;lt;br&amp;gt;! function contains(hay, needle) {&amp;lt;br&amp;gt;! return hay.indexOf(needle) &amp;amp;gt; -1;&amp;lt;br&amp;gt;! }&amp;lt;br&amp;gt;! // snip out everything between the colon and the specified end tag.&amp;lt;br&amp;gt;! // Example:&amp;lt;br&amp;gt;! // snip('* Battery capacity: 69.60% *', '%') =&amp;amp;gt; '69.60'&amp;lt;br&amp;gt;! function snip(line, endtag) {&amp;lt;br&amp;gt;! var idx = line.indexOf(':');&amp;lt;br&amp;gt;! if (idx &amp;amp;lt; 1)&amp;lt;br&amp;gt;! return '';&amp;lt;br&amp;gt;! line = line.substring(idx + 2);&amp;lt;br&amp;gt;! idx = line.indexOf(endtag);&amp;lt;br&amp;gt;! if (idx &amp;amp;lt; 1)&amp;lt;br&amp;gt;! return '';&amp;lt;br&amp;gt;! return line.substring(0, idx);&amp;lt;br&amp;gt;! }&amp;lt;/p&amp;gt;&amp;lt;/blockquote&amp;gt;&lt;/div&gt;</summary>
		<author><name>Admin</name></author>
	</entry>
	<entry>
		<id>https://wiki.my-network.at/index.php?title=Proxmox&amp;diff=26</id>
		<title>Proxmox</title>
		<link rel="alternate" type="text/html" href="https://wiki.my-network.at/index.php?title=Proxmox&amp;diff=26"/>
		<updated>2022-08-24T11:10:45Z</updated>

		<summary type="html">&lt;p&gt;Admin: Die Seite wurde neu angelegt: „= Proxmox VE Installation und Grundkonfiguration = &amp;lt;div class=&amp;quot;clear&amp;quot;&amp;gt;Im folgenden Beitrag gehe ich auf die Konfigurationsmöglichkeiten einer Proxmox VE Basis…“&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= Proxmox VE Installation und Grundkonfiguration =&lt;br /&gt;
&amp;lt;div class=&amp;quot;clear&amp;quot;&amp;gt;Im folgenden Beitrag gehe ich auf die Konfigurationsmöglichkeiten einer Proxmox VE Basisinstallation ein. Für den Beitrag habe ich noch PVE 6.4 installiert, da kurz darauf PVE 7.0 released wurde, habe ich Änderungen in dieser Version noch in den Beitrag einfließen lassen.&amp;lt;br&amp;gt;&amp;lt;/div&amp;gt;&amp;lt;div class=&amp;quot;entry themeform&amp;quot;&amp;gt;&amp;lt;div class=&amp;quot;entry-inner&amp;quot;&amp;gt;&lt;br /&gt;
===== Installation =====&lt;br /&gt;
&amp;lt;p&amp;gt;Die eigentliche Grundinstallation von PVE ist im Wiki vom Proxmox hier (&amp;lt;/p&amp;gt;[https://pve.proxmox.com/wiki/Installation https://pve.proxmox.com/wiki/Installation]&amp;lt;p&amp;gt;) ganz gut dokumentiert, daher gehe ich auf die Installation nicht mehr groß ein.&amp;lt;/p&amp;gt;&lt;br /&gt;
===== Grundkonfiguration =====&lt;br /&gt;
&amp;lt;p&amp;gt;Im Anschluss an die Installation nehme ich über die Web UI und SSH einige Grundeinstellungen vor.&amp;lt;/p&amp;gt;&amp;lt;p&amp;gt;'''No-Subscription Warning'''&amp;lt;/p&amp;gt;&amp;lt;p&amp;gt;Ohne Subscription erscheint in der Web-GUI von Proxmox bei jedem Login eine Warnmeldung, dass das System ohne Subscription betrieben wird. Dies ist trotzdem ganz legal, allerdings ist die Meldung sehr störend, kann aber glücklicherweise deaktiviert werden.&amp;lt;/p&amp;gt;&amp;lt;p&amp;gt;Dazu verbindet man sich im ersten Schritt per SSH mit dem PVE Host. Danach sichert man die Datei, die für die Deaktivierung angepasst werden muss und öffnet die Datei mit nano:&amp;lt;/p&amp;gt;&amp;lt;pre class=&amp;quot;wp-block-preformatted&amp;quot;&amp;gt;cp /usr/share/javascript/proxmox-widget-toolkit/proxmoxlib.js /usr/share/javascript/proxmox-widget-toolkit/proxmoxlib.js.bak&lt;br /&gt;
nano /usr/share/javascript/proxmox-widget-toolkit/proxmoxlib.js&amp;lt;/pre&amp;gt;&amp;lt;p&amp;gt;In der &amp;lt;code&amp;gt;proxmoxlib.js&amp;lt;/code&amp;gt; Datei sucht man in &amp;lt;code&amp;gt;nano&amp;lt;/code&amp;gt; mit Ctrl+W nach dem Suchbegriff ''&amp;lt;code&amp;gt;No valid subscription&amp;lt;/code&amp;gt;''. Die Ergebniszeile sieht wie folgt aus:&amp;lt;/p&amp;gt;&amp;lt;pre class=&amp;quot;wp-block-preformatted&amp;quot;&amp;gt;...&lt;br /&gt;
Ext.Msg.show({&lt;br /&gt;
  title: gettext('No valid subscription'),&lt;br /&gt;
...&amp;lt;/pre&amp;gt;&amp;lt;p&amp;gt;Der Eintrag &amp;lt;code&amp;gt;Ext.Msg.show&amp;lt;/code&amp;gt; wird gegen den Eintrag &amp;lt;code&amp;gt;void&amp;lt;/code&amp;gt; getauscht und die Datei mit Ctrl+X gespeichert:&amp;lt;/p&amp;gt;&amp;lt;pre class=&amp;quot;wp-block-preformatted&amp;quot;&amp;gt;...&lt;br /&gt;
void({&lt;br /&gt;
  title: gettext('No valid subscription'),&lt;br /&gt;
...&amp;lt;/pre&amp;gt;&amp;lt;p&amp;gt;Danach muss nur noch der PVE Web Service neu gestartet werden, um die Änderung zu aktivieren:&amp;lt;/p&amp;gt;&amp;lt;pre class=&amp;quot;wp-block-preformatted&amp;quot;&amp;gt;systemctl restart pveproxy.service&amp;lt;/pre&amp;gt;&amp;lt;p&amp;gt;Nach einem Versionsupdate kann es vorkommen, dass die obige Konfiguration erneut durchgeführt werden muss!&amp;lt;/p&amp;gt;&amp;lt;p&amp;gt;'''No-Subscription Repository'''&amp;lt;/p&amp;gt;&amp;lt;p&amp;gt;Da ich keine Subscription habe, deaktiviere das Enterprise Repository und lege eine Sources-Datei an für das No-Subscription Repository.&amp;lt;/p&amp;gt;&amp;lt;pre class=&amp;quot;wp-block-preformatted&amp;quot;&amp;gt;mv /etc/apt/sources.list.d/pve-enterprise.list /etc/apt/sources.list.d/pve-enterprise.list.bak&lt;br /&gt;
nano /etc/apt/sources.list.d/pve-no-subscription.list&amp;lt;/pre&amp;gt;&amp;lt;p&amp;gt;In der neu erstellte Sources-Datei ist folgender Eintrag hinzuzufügen:&amp;lt;/p&amp;gt;&amp;lt;pre class=&amp;quot;wp-block-preformatted&amp;quot;&amp;gt;# PVE 6.x&lt;br /&gt;
&amp;lt;tt&amp;gt;deb http://download.proxmox.com/debian/pve buster pve-no-subscription&amp;lt;/tt&amp;gt;&lt;br /&gt;
# PVE 7.x&lt;br /&gt;
&amp;lt;tt&amp;gt;deb http://download.proxmox.com/debian/pve bullseye pve-no-subscription&amp;lt;/tt&amp;gt;&amp;lt;/pre&amp;gt;&amp;lt;p&amp;gt;''Update/Änderung in PVE 7.0''&amp;lt;/p&amp;gt;&amp;lt;p&amp;gt;Mit PVE 7.0 wurde die Möglichkeit geschaffen, die Repositories über die Web GUI auszuwählen. Zu finden ist die Option unter dem Server-Node im Menü Updates -&amp;amp;gt; Repositories. Der Eintrag in der &amp;lt;code&amp;gt;pve-no-subscription.list&amp;lt;/code&amp;gt; wird nur für das Update von 6.x auf 7.x benötigt.&amp;lt;/p&amp;gt;&amp;lt;p&amp;gt;'''Open vSwitch'''&amp;lt;/p&amp;gt;&amp;lt;p&amp;gt;Optional kann man auch noch Open vSwitch (OVS) nachinstallieren, falls man das Feature nutzen möchte:&amp;lt;/p&amp;gt;&amp;lt;pre class=&amp;quot;wp-block-preformatted&amp;quot;&amp;gt;apt update&lt;br /&gt;
apt install openvswitch-switch&amp;lt;/pre&amp;gt;&amp;lt;p&amp;gt;Mir reichen in meinen Installationen die normalen Linux Netzwerk-Bridges und benötige daher OVS nicht.&amp;lt;/p&amp;gt;&amp;lt;p&amp;gt;'''ifupdown2'''&amp;lt;/p&amp;gt;&amp;lt;p&amp;gt;Um Änderungen an der Netzwerkkonfiguration in der PVE GUI auch im laufenden Betrieb ohne Neustart zu ermöglichen, installiere ich noch das dazu benötigte &amp;lt;code&amp;gt;ifupdown2&amp;lt;/code&amp;gt; Tool.&amp;lt;/p&amp;gt;&amp;lt;pre class=&amp;quot;wp-block-preformatted&amp;quot;&amp;gt;apt install ifupdown2&amp;lt;/pre&amp;gt;&amp;lt;p&amp;gt;''Update/Änderung in PVE 7.0''&amp;lt;/p&amp;gt;&amp;lt;p&amp;gt;In PVE 7.0 wurde &amp;lt;code&amp;gt;ifupdown2&amp;lt;/code&amp;gt; in die Basisinstallation integriert und muss nicht mehr nachinstalliert werden.&amp;lt;/p&amp;gt;&amp;lt;p&amp;gt;'''ZFS File System Konfiguration / ZFS ARC Tuning'''&amp;lt;/p&amp;gt;&amp;lt;p&amp;gt;Wie in einem anderen Beitrag beschrieben, habe ich 2 Server, ein Produktivsystem und ein Testsystem; in beiden Systemen sind 2 Data Disks, die ich per ZFS mit RAID 1 zu einem logischen Volume zusammenschließe. Für die Nutzung von ZFS ist jedoch einiges zu beachten.&amp;lt;/p&amp;gt;&amp;lt;p&amp;gt;ARC (Adaptive Replacement Cache) ist eine Funktion von ZFS, die Daten, auf die am häufigsten zugegriffen wird, im RAM speichert und so extrem schnelle Lesevorgänge für diese Ressourcen ermöglicht. Das ist an sich eine sinnvolle Funktion, aber die standardmäßige maximale Größe für ARC beträgt 50% des gesamten System-RAMs. Auf einem File Server macht eine Einstellung von 50% oder sogar noch mehr durchaus Sinn, aber Proxmox VE ist ja nun mal kein File Server sondern ein Hypervisor. Da RAM einerseits teuer ist und andererseits der RAM für ein System begrenzt ist, drehe ich die Einstellung in meiner Installation daher herunter.&amp;lt;/p&amp;gt;&amp;lt;p&amp;gt;Es gibt viele Empfehlungen, wie viel RAM für ARC verwendet werden soll. Häufig trifft man dabei auf den Wert 1 GB pro TB ZFS Speicher, mindestens jedoch 8 GB. Meine Server haben jeweils eine 500 GB ZFS RAID 1 Disk, d.h. rein nach diesem TB Wert würde 1 GB für ARC reichen. Zudem verfügen meine Server über 32 GB, bzw. 64 GB RAM. Daher bleibe ich erst mal unter der Empfehlung und limitiere ARC erstmal auf 2 GB, bzw. 4 GB. Sollte das zu Performance Problemen führen, kann auf 8 GB erhöht werden. 1 GB RAM bzw. 2 GB RAM konfiguriere ich als Minimalwert.&amp;lt;/p&amp;gt;&amp;lt;p&amp;gt;Diese Werte müssen in Bytes angegeben werden und können wie folgt berechnet werden:&amp;lt;br&amp;gt;GB * 1024 = MB -&amp;amp;gt; MB * 1024 = KB -&amp;amp;gt; KB * 1024 = Bytes&amp;lt;br&amp;gt;Daraus ergeben sich folgende Werte:&amp;lt;br&amp;gt;8GB = 8589934592 Bytes&amp;lt;br&amp;gt;4GB = 4294967296 Bytes&amp;lt;br&amp;gt;2GB = 2147483648 Bytes&amp;lt;br&amp;gt;1GB = 1073741824 Bytes&amp;lt;/p&amp;gt;&amp;lt;p&amp;gt;Um ARC zu konfigurieren, ist mit dem folgenden Befehl die &amp;lt;code&amp;gt;zfs.conf&amp;lt;/code&amp;gt; Datei zu editieren (wird neu angelegt, falls sie noch nicht existiert):&amp;lt;/p&amp;gt;&amp;lt;pre class=&amp;quot;wp-block-preformatted&amp;quot;&amp;gt;nano /etc/modprobe.d/zfs.conf&amp;lt;/pre&amp;gt;&amp;lt;p&amp;gt;Dort trage ich folgende Werte ein:&amp;lt;/p&amp;gt;&amp;lt;p&amp;gt;''Produktivserver''&amp;lt;/p&amp;gt;&amp;lt;pre class=&amp;quot;wp-block-preformatted&amp;quot;&amp;gt;options zfs zfs_arc_min=2147483648&lt;br /&gt;
options zfs zfs_arc_max=4294967296&amp;lt;/pre&amp;gt;&amp;lt;p&amp;gt;''Testserver''&amp;lt;/p&amp;gt;&amp;lt;pre class=&amp;quot;wp-block-preformatted&amp;quot;&amp;gt;options zfs zfs_arc_min=1073741824&lt;br /&gt;
options zfs zfs_arc_max=2147483648&amp;lt;/pre&amp;gt;&amp;lt;p&amp;gt;Da ich UEFI Systeme verwende, muss die Kernel Liste aktualisiert werden, damit das aktualisierte RAM File System verwendet wird (bei BIOS nicht notwendig):&amp;lt;/p&amp;gt;&amp;lt;pre class=&amp;quot;wp-block-preformatted&amp;quot;&amp;gt;pve-efiboot-tool refresh&amp;lt;/pre&amp;gt;&amp;lt;p&amp;gt;Für das eigentliche PVS System verwende ich eine separate EXT4 formatierte LVM Disk. Dadurch ist die Konfiguration von ZFS für meine System fertig. Wer jedoch auch das System auf einer ZFS Disk installiert, muss auch das initiale RAM Dateisystem anpassen, damit die Änderung wirksam wird vor dem Mounten des ZFS Volumes.&amp;lt;/p&amp;gt;&amp;lt;pre class=&amp;quot;wp-block-preformatted&amp;quot;&amp;gt;update-initramfs -u&amp;lt;/pre&amp;gt;&amp;lt;p&amp;gt;Damit obige Änderungen wirksam werden, muss das System abschließend nun noch gebootet werden.&amp;lt;/p&amp;gt;&amp;lt;p&amp;gt;'''Replication Runner Syslog Messages'''&amp;lt;/p&amp;gt;&amp;lt;p&amp;gt;Wer den Replication Runner unverändert lässt, dem werden im Syslog von PVE minütliche Einträge wie diese auffallen:&amp;lt;/p&amp;gt;&amp;lt;pre class=&amp;quot;wp-block-preformatted&amp;quot;&amp;gt;systemd[1]: Starting Proxmox VE replication runner...&amp;lt;/pre&amp;gt;&amp;lt;p&amp;gt;Um diese Meldung zu unterbinden, lässt sich der entsprechende Dienst einfach deaktivieren:&amp;lt;/p&amp;gt;&amp;lt;pre class=&amp;quot;wp-block-preformatted&amp;quot;&amp;gt;systemctl disable pvesr.timer&amp;lt;/pre&amp;gt;&amp;lt;p&amp;gt;Wer den Dienst nicht komplett abschalten möchte, kann alternativ das Intervall ändern, in denen der Replication Runner ausgeführt wird:&amp;lt;/p&amp;gt;&amp;lt;pre class=&amp;quot;wp-block-preformatted&amp;quot;&amp;gt;nano /lib/systemd/system/pvesr.timer&amp;lt;/pre&amp;gt;&amp;lt;p&amp;gt;Hier ändere ich den Eintrag …&amp;lt;/p&amp;gt;&amp;lt;pre class=&amp;quot;wp-block-preformatted&amp;quot;&amp;gt;[Timer]&lt;br /&gt;
OnCalendar=minutely&amp;lt;/pre&amp;gt;&amp;lt;p&amp;gt;… in …&amp;lt;/p&amp;gt;&amp;lt;pre class=&amp;quot;wp-block-preformatted&amp;quot;&amp;gt;[Timer]&lt;br /&gt;
OnCalendar=monthly&amp;lt;/pre&amp;gt;&amp;lt;p&amp;gt;Danach läuft der Replication Runner nur noch einmal monatlich.&amp;lt;/p&amp;gt;&amp;lt;p&amp;gt;'''Netzwerk Konfiguration'''&amp;lt;/p&amp;gt;&amp;lt;p&amp;gt;In meinen Systemen befinden sich je 4 NICs. Diese teile ich wie folgt auf:&amp;lt;br&amp;gt;NIC 1&amp;amp;nbsp; &amp;amp;gt; LAN Bond 1/2&amp;lt;br&amp;gt;NIC 2&amp;amp;nbsp; &amp;amp;gt; LAN Bond 2/2&amp;lt;br&amp;gt;NIC 3&amp;amp;nbsp; &amp;amp;gt; DMZ&amp;lt;br&amp;gt;NIC 4&amp;amp;nbsp; &amp;amp;gt; SAN&amp;lt;/p&amp;gt;&amp;lt;p&amp;gt;Besonders bei der Konfiguration des Bonds hatte ich massive Probleme. Das Löschen der vmbr0, Anlegen von bond0 mit Member eno0 eno1 (oder wie die IFs im System halt heißen), Anlegen von vmbr0 mit Member bond0 und IP Konfiguration, Anwenden der Konfiguration hat bei mir dazu geführt, dass das System nicht mehr erreichbar ist.&amp;lt;/p&amp;gt;&amp;lt;p&amp;gt;Die Lösung war bei mir:&amp;lt;br&amp;gt;Löschen der vmbr0, anlegen von bond0 mit Member eno0, anlegen von vmbr0 mit Member bond0 und IP Konfiguration, anwenden der Konfiguration; danach hinzufügen von eno1 zu bond0, anwenden der Konfiguration&amp;lt;/p&amp;gt;&amp;lt;p&amp;gt;Warum das so ist, konnte ich noch nicht nachvollziehen, Hinweise dazu sind natürlich willkommen.&amp;lt;/p&amp;gt;&amp;lt;p&amp;gt;Wichtig ist auch zu beachten, dass PVE ggf. bei der Bildung von Bridges und Bonds eigene MAC-Adressen vergibt und sich diese bei einem Major Release Update auch gerne mal ändern. Dies tritt auf, wenn die physikalischen Bond-Members automatisch starten.&amp;lt;/p&amp;gt;&amp;lt;p&amp;gt;Welche MACs verwendet werden, lässt sich mit folgendem Befehl anschauen:&amp;lt;/p&amp;gt;&amp;lt;pre class=&amp;quot;wp-block-preformatted&amp;quot;&amp;gt;ip -c link&amp;lt;/pre&amp;gt;&amp;lt;p&amp;gt;Die Ausgabe sieht dann z.B. wie folgt aus, wenn die Bond-Members automatisch starten:&amp;lt;/p&amp;gt;&amp;lt;pre class=&amp;quot;wp-block-preformatted&amp;quot;&amp;gt;1: lo: &amp;amp;lt;LOOPBACK,UP,LOWER_UP&amp;amp;gt; mtu 65536 qdisc noqueue state UNKNOWN mode DEFAULT group default qlen 1000&lt;br /&gt;
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00&lt;br /&gt;
2: eno1: &amp;amp;lt;BROADCAST,MULTICAST,SLAVE,UP,LOWER_UP&amp;amp;gt; mtu 1500 qdisc mq master bond1 state UP mode DEFAULT group default qlen 1000&lt;br /&gt;
    link/ether '''f6:76:43:97:f6:a4''' brd ff:ff:ff:ff:ff:ff permaddr ac:1f:6b:44:cd:18&lt;br /&gt;
    altname enp5s0f0&lt;br /&gt;
3: eno2: &amp;amp;lt;BROADCAST,MULTICAST,SLAVE,UP,LOWER_UP&amp;amp;gt; mtu 1500 qdisc mq master bond1 state UP mode DEFAULT group default qlen 1000&lt;br /&gt;
    link/ether '''f6:76:43:97:f6:a4''' brd ff:ff:ff:ff:ff:ff permaddr ac:1f:6b:44:cd:19&lt;br /&gt;
    altname enp5s0f1&lt;br /&gt;
4: eno3: &amp;amp;lt;BROADCAST,MULTICAST,UP,LOWER_UP&amp;amp;gt; mtu 1500 qdisc mq master vmbr2 state UP mode DEFAULT group default qlen 1000&lt;br /&gt;
    link/ether ac:1f:6b:44:cd:1a brd ff:ff:ff:ff:ff:ff&lt;br /&gt;
    altname enp7s0f0&lt;br /&gt;
5: eno4: &amp;amp;lt;BROADCAST,MULTICAST,UP,LOWER_UP&amp;amp;gt; mtu 1500 qdisc mq master vmbr3 state UP mode DEFAULT group default qlen 1000&lt;br /&gt;
    link/ether ac:1f:6b:44:cd:1b brd ff:ff:ff:ff:ff:ff&lt;br /&gt;
    altname enp7s0f1&lt;br /&gt;
6: bond1: &amp;amp;lt;BROADCAST,MULTICAST,MASTER,UP,LOWER_UP&amp;amp;gt; mtu 1500 qdisc noqueue master vmbr1 state UP mode DEFAULT group default qlen 1000&lt;br /&gt;
    link/ether '''f6:76:43:97:f6:a4''' brd ff:ff:ff:ff:ff:ff&lt;br /&gt;
7: vmbr1: &amp;amp;lt;BROADCAST,MULTICAST,UP,LOWER_UP&amp;amp;gt; mtu 1500 qdisc noqueue state UP mode DEFAULT group default qlen 1000&lt;br /&gt;
    link/ether '''f6:76:43:97:f6:a4''' brd ff:ff:ff:ff:ff:ff&lt;br /&gt;
8: vmbr2: &amp;amp;lt;BROADCAST,MULTICAST,UP,LOWER_UP&amp;amp;gt; mtu 1500 qdisc noqueue state UP mode DEFAULT group default qlen 1000&lt;br /&gt;
    link/ether ac:1f:6b:44:cd:1a brd ff:ff:ff:ff:ff:ff&lt;br /&gt;
9: vmbr3: &amp;amp;lt;BROADCAST,MULTICAST,UP,LOWER_UP&amp;amp;gt; mtu 1500 qdisc noqueue state UP mode DEFAULT group default qlen 1000&lt;br /&gt;
    link/ether ac:1f:6b:44:cd:1b brd ff:ff:ff:ff:ff:ff&amp;lt;/pre&amp;gt;&amp;lt;p&amp;gt;Wie man in diesem Beispiel sieht, vergibt PVE für alle Member-NICs des Bonds, für den Bond selbst und für die Bridge des Bonds eine neue MAC-Adresse. Wie geschrieben, kann diese sich jedoch unter Umständen ändern. Um dies zu vermeiden, gibt es 2 Optionen:&amp;lt;/p&amp;gt;&lt;br /&gt;
#Konfiguration einer statischen MAC für die Bridge&lt;br /&gt;
#Deaktivierung des Autostarts für die physikalischen NIC Members des Bonds&lt;br /&gt;
&amp;lt;p&amp;gt;Warum ist es wichtig, mit welchen MAC-Adressen der PVE Server daherkommt? In meinem Fall, weil ich eine Firewall mit MAC-based Policies verwende. Ändert sich also die MAC, muss das jeweilige Firewall Objekt angepasst werden, sonst funktionieren die Freischaltungen nicht mehr.&amp;lt;/p&amp;gt;&amp;lt;p&amp;gt;''Konfiguration einer statischen MAC''&amp;lt;/p&amp;gt;&amp;lt;p&amp;gt;Leider lässt sich die vergebene MAC-Adresse nicht in der PVE-GUI konfigurieren. Um diese anzupassen und persistent zu halten, muss über die Shell die Datei &amp;lt;code&amp;gt;/etc/network/interfaces&amp;lt;/code&amp;gt; mit z.B. &amp;lt;code&amp;gt;nano&amp;lt;/code&amp;gt; angepasst werden, indem ein Parameter &amp;lt;code&amp;gt;hwaddress&amp;lt;/code&amp;gt; in die entsprechende Bridge-Konfiguration eingefügt wird, also in meinem Beispiel:&amp;lt;/p&amp;gt;&amp;lt;pre class=&amp;quot;wp-block-preformatted&amp;quot;&amp;gt;auto vmbr1&lt;br /&gt;
iface vmbr1 inet static&lt;br /&gt;
	'''hwaddress f6:76:43:97:f6:a4'''&lt;br /&gt;
        address 10.x.x.x/24&lt;br /&gt;
        gateway 10.x.x.1&lt;br /&gt;
        bridge-ports bond1&lt;br /&gt;
        bridge-stp off&lt;br /&gt;
        bridge-fd 0&amp;lt;/pre&amp;gt;&amp;lt;p&amp;gt;''Deaktivierung des Autostarts für die phsikalischen NIC Members des Bonds''&amp;lt;/p&amp;gt;&amp;lt;p&amp;gt;Der Autostart der NICs muss ebenfalls über die Datei &amp;lt;code&amp;gt;/etc/network/interfaces&amp;lt;/code&amp;gt; durchgeführt werden. Dazu muss bei allen betroffenen NICs der &amp;lt;code&amp;gt;auto&amp;lt;/code&amp;gt; Parameter entfernt oder auskommentiert werden. Wichtig! Die Änderung funktioniert nur, wenn keine VM auf die Bridge und den Bond gebunden wird, dessen Slaves die NICs sind.&amp;lt;/p&amp;gt;&amp;lt;pre class=&amp;quot;wp-block-preformatted&amp;quot;&amp;gt;&amp;lt;s&amp;gt;&amp;lt;span class=&amp;quot;has-inline-color has-vivid-red-color&amp;quot;&amp;gt;auto eno1&amp;lt;/span&amp;gt;&amp;lt;/s&amp;gt;&lt;br /&gt;
iface eno1 inet manual&lt;br /&gt;
&lt;br /&gt;
&amp;lt;s&amp;gt;&amp;lt;span class=&amp;quot;has-inline-color has-vivid-red-color&amp;quot;&amp;gt;auto eno2&amp;lt;/span&amp;gt;&amp;lt;/s&amp;gt;&lt;br /&gt;
iface eno2 inet manual&amp;lt;/pre&amp;gt;&amp;lt;p&amp;gt;Abschließend muss die neue Konfiguration noch angewendet werden. Dazu ist der Befehl &amp;lt;code&amp;gt;ifreload -a&amp;lt;/code&amp;gt;. Danach sieht die Ausgabe von &amp;lt;code&amp;gt;ip -c link&amp;lt;/code&amp;gt; nun so aus:&amp;lt;/p&amp;gt;&amp;lt;pre class=&amp;quot;wp-block-preformatted&amp;quot;&amp;gt;1: lo: &amp;amp;lt;LOOPBACK,UP,LOWER_UP&amp;amp;gt; mtu 65536 qdisc noqueue state UNKNOWN mode DEFAULT group default qlen 1000&lt;br /&gt;
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00&lt;br /&gt;
2: eno1: &amp;amp;lt;BROADCAST,MULTICAST,SLAVE,UP,LOWER_UP&amp;amp;gt; mtu 1500 qdisc mq master bond1 state UP mode DEFAULT group default qlen 1000&lt;br /&gt;
    link/ether '''ac:1f:6b:44:cd:18''' brd ff:ff:ff:ff:ff:ff&lt;br /&gt;
    altname enp5s0f0&lt;br /&gt;
3: eno2: &amp;amp;lt;BROADCAST,MULTICAST,SLAVE,UP,LOWER_UP&amp;amp;gt; mtu 1500 qdisc mq master bond1 state UP mode DEFAULT group default qlen 1000&lt;br /&gt;
    link/ether '''ac:1f:6b:44:cd:18''' brd ff:ff:ff:ff:ff:ff permaddr ac:1f:6b:44:cd:19&lt;br /&gt;
    altname enp5s0f1&lt;br /&gt;
4: eno3: &amp;amp;lt;BROADCAST,MULTICAST,UP,LOWER_UP&amp;amp;gt; mtu 1500 qdisc mq master vmbr2 state UP mode DEFAULT group default qlen 1000&lt;br /&gt;
    link/ether ac:1f:6b:44:cd:1a brd ff:ff:ff:ff:ff:ff&lt;br /&gt;
    altname enp7s0f0&lt;br /&gt;
5: eno4: &amp;amp;lt;BROADCAST,MULTICAST,UP,LOWER_UP&amp;amp;gt; mtu 1500 qdisc mq master vmbr3 state UP mode DEFAULT group default qlen 1000&lt;br /&gt;
    link/ether ac:1f:6b:44:cd:1b brd ff:ff:ff:ff:ff:ff&lt;br /&gt;
    altname enp7s0f1&lt;br /&gt;
6: bond1: &amp;amp;lt;BROADCAST,MULTICAST,MASTER,UP,LOWER_UP&amp;amp;gt; mtu 1500 qdisc noqueue master vmbr1 state UP mode DEFAULT group default qlen 1000&lt;br /&gt;
    link/ether '''ac:1f:6b:44:cd:18''' brd ff:ff:ff:ff:ff:ff&lt;br /&gt;
7: vmbr1: &amp;amp;lt;BROADCAST,MULTICAST,UP,LOWER_UP&amp;amp;gt; mtu 1500 qdisc noqueue state UP mode DEFAULT group default qlen 1000&lt;br /&gt;
    link/ether '''ac:1f:6b:44:cd:18''' brd ff:ff:ff:ff:ff:ff&lt;br /&gt;
8: vmbr2: &amp;amp;lt;BROADCAST,MULTICAST,UP,LOWER_UP&amp;amp;gt; mtu 1500 qdisc noqueue state UP mode DEFAULT group default qlen 1000&lt;br /&gt;
    link/ether ac:1f:6b:44:cd:1a brd ff:ff:ff:ff:ff:ff&lt;br /&gt;
9: vmbr3: &amp;amp;lt;BROADCAST,MULTICAST,UP,LOWER_UP&amp;amp;gt; mtu 1500 qdisc noqueue state UP mode DEFAULT group default qlen 1000&lt;br /&gt;
    link/ether ac:1f:6b:44:cd:1b brd ff:ff:ff:ff:ff:ff&amp;lt;/pre&amp;gt;&amp;lt;p&amp;gt;Leider bleibt diese Korrektur nicht persitent – warum auch immer. Der &amp;lt;code&amp;gt;auto&amp;lt;/code&amp;gt; Parameter bleibt zwar raus, die „virtuelle“ MAC wird aber beim Reboot wieder erzeugt. D.h. die Korrektur ist bei jedem Reboot per cron-Job auszuführen:&amp;lt;/p&amp;gt;&amp;lt;pre class=&amp;quot;wp-block-preformatted&amp;quot;&amp;gt;@reboot ifreload -a&amp;lt;/pre&amp;gt;&amp;lt;p&amp;gt;'''NTP Server'''&amp;lt;/p&amp;gt;&amp;lt;p&amp;gt;Da Proxmox VE auf Debian basiert, versucht das System sein Zeit standardmäßig mit den debian.pool.ntp.org Servern zu synchronisieren. Dazu verwendet PVE den Daemon ''systemd-timesyncd''. Um eigene Server zu hinterlegen, muss daher die Datei &amp;lt;code&amp;gt;/etc/systemd/timesynd.conf&amp;lt;/code&amp;gt; mit z.B. &amp;lt;code&amp;gt;nano&amp;lt;/code&amp;gt; angepasst werden (mehrere Server werden mit Leerzeichen getrennt angegeben), z.B.:&amp;lt;/p&amp;gt;&amp;lt;pre class=&amp;quot;wp-block-preformatted&amp;quot;&amp;gt;[Time]&lt;br /&gt;
NTP=de.pool.ntp.org&amp;lt;/pre&amp;gt;&amp;lt;p&amp;gt;Danach muss nur noch der entsprechende Dienst neu gestartet werden, damit die Änderung aktiv wird:&amp;lt;/p&amp;gt;&amp;lt;pre class=&amp;quot;wp-block-preformatted&amp;quot;&amp;gt;systemctl restart systemd-timesyncd&amp;lt;/pre&amp;gt;&amp;lt;p&amp;gt;Die Änderung kann geprüft werden entweder mit den Befehlen &amp;lt;code&amp;gt;systemctl status systemd-timesynd&amp;lt;/code&amp;gt; oder &amp;lt;code&amp;gt;journalctl --since -1h -u systemd-timesyncd&amp;lt;/code&amp;gt;.&amp;lt;/p&amp;gt;&amp;lt;hr class=&amp;quot;wp-block-separator&amp;quot;&amp;gt;&amp;lt;/div&amp;gt;&amp;lt;/div&amp;gt;&lt;/div&gt;</summary>
		<author><name>Admin</name></author>
	</entry>
	<entry>
		<id>https://wiki.my-network.at/index.php?title=Hauptseite&amp;diff=25</id>
		<title>Hauptseite</title>
		<link rel="alternate" type="text/html" href="https://wiki.my-network.at/index.php?title=Hauptseite&amp;diff=25"/>
		<updated>2022-08-24T10:42:41Z</updated>

		<summary type="html">&lt;p&gt;Admin: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&amp;lt;span style=&amp;quot;font-size: 36pt;&amp;quot;&amp;gt;Hier entsteht ein kleines privates Wikipedia&amp;lt;/span&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;span style=&amp;quot;font-size: 24pt;&amp;quot;&amp;gt;[https://wiki.my-network.at/index.php/Spezial:Alle_Seiten Zur Übersicht der Wiki Seiten hier entlang]&amp;lt;/span&amp;gt;&lt;/div&gt;</summary>
		<author><name>Admin</name></author>
	</entry>
	<entry>
		<id>https://wiki.my-network.at/index.php?title=Hauptseite&amp;diff=24</id>
		<title>Hauptseite</title>
		<link rel="alternate" type="text/html" href="https://wiki.my-network.at/index.php?title=Hauptseite&amp;diff=24"/>
		<updated>2022-08-24T10:41:32Z</updated>

		<summary type="html">&lt;p&gt;Admin: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&amp;lt;span style=&amp;quot;font-size: 36pt;&amp;quot;&amp;gt;Hier entsteht ein kleines privates Wikipedia&amp;lt;/span&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;span style=&amp;quot;font-size: 24pt;&amp;quot;&amp;gt;[https://wiki.my-network.at/index.php/Spezial:Alle Zur Übersicht der Wiki Seiten hier entlang]&amp;lt;/span&amp;gt;&lt;/div&gt;</summary>
		<author><name>Admin</name></author>
	</entry>
	<entry>
		<id>https://wiki.my-network.at/index.php?title=Hauptseite&amp;diff=23</id>
		<title>Hauptseite</title>
		<link rel="alternate" type="text/html" href="https://wiki.my-network.at/index.php?title=Hauptseite&amp;diff=23"/>
		<updated>2022-08-24T10:40:09Z</updated>

		<summary type="html">&lt;p&gt;Admin: Die Seite wurde neu angelegt: „&amp;lt;span style=&amp;quot;font-size: 36pt;&amp;quot; &amp;gt;Hier entsteht ein kleines privates Wikipedia&amp;lt;/span&amp;gt;  &amp;lt;span style=&amp;quot;font-size: 24pt;&amp;quot; &amp;gt;https://wiki.my-network.at/index.php/Spe…“&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&amp;lt;span style=&amp;quot;font-size: 36pt;&amp;quot; &amp;gt;Hier entsteht ein kleines privates Wikipedia&amp;lt;/span&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;span style=&amp;quot;font-size: 24pt;&amp;quot; &amp;gt;[[https://wiki.my-network.at/index.php/Spezial:Alle Seiten|Zur Übersicht der Wiki Seiten hier entlang]]&amp;lt;/span&amp;gt;&lt;/div&gt;</summary>
		<author><name>Admin</name></author>
	</entry>
	<entry>
		<id>https://wiki.my-network.at/index.php?title=Unifi_Controller_updaten&amp;diff=22</id>
		<title>Unifi Controller updaten</title>
		<link rel="alternate" type="text/html" href="https://wiki.my-network.at/index.php?title=Unifi_Controller_updaten&amp;diff=22"/>
		<updated>2022-05-27T14:15:49Z</updated>

		<summary type="html">&lt;p&gt;Admin: Die Seite wurde neu angelegt: „==== 1. Unifi Controller Backup erstellen ==== &amp;lt;p&amp;gt;Navigieren Sie in der Unifi Controller UI zu SETTINGS –&amp;amp;gt; System –&amp;amp;gt; Maintenance –&amp;amp;gt; Backup / Res…“&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==== 1. Unifi Controller Backup erstellen ====&lt;br /&gt;
&amp;lt;p&amp;gt;Navigieren Sie in der Unifi Controller UI zu SETTINGS –&amp;amp;gt; System –&amp;amp;gt; Maintenance –&amp;amp;gt; Backup / Restore&amp;lt;/p&amp;gt;&amp;lt;figure class=&amp;quot;wp-block-image size-large&amp;quot;&amp;gt;&amp;lt;p&amp;gt;Wählen Sie '''''No Limit''''' aus und klicken Sie anschliessend auf '''''Download Backup'''''.&amp;lt;/p&amp;gt;&amp;lt;figure class=&amp;quot;wp-block-image size-full&amp;quot;&amp;gt;&lt;br /&gt;
==== 2. Über SSH auf den Unifi Controller zugreifen ====&lt;br /&gt;
&amp;lt;p&amp;gt;Um über ssh auf den Unifi Controller Server zuzugreifen, können Sie den Befehl '''''ssh benutzername@hostname''''' auf den Unifi Controller zuzugreifen. Beispielsweise könnte der Befehl dann wie folgt aussehen:&amp;lt;/p&amp;gt;&amp;lt;pre class=&amp;quot;wp-block-preformatted&amp;quot;&amp;gt;ssh root@192.168.1.12&amp;lt;/pre&amp;gt;&lt;br /&gt;
==== 3. apt-source hinzufügen &amp;amp; update &amp;amp; upgrade durchführen ====&lt;br /&gt;
&amp;lt;p&amp;gt;Unter Ubuntu geben Sie zusätzlich zum Befehl unten noch ''sudo -s'' ein, um Root rechte zu erhalten.&amp;lt;/p&amp;gt;&amp;lt;pre class=&amp;quot;wp-block-preformatted&amp;quot;&amp;gt;sudo -s&amp;lt;/pre&amp;gt;&amp;lt;p&amp;gt;Unter Debian nutzen Sie nur den folgenden Befehl.&amp;lt;/p&amp;gt;&amp;lt;pre class=&amp;quot;wp-block-preformatted&amp;quot;&amp;gt;service unifi stop &amp;amp;&amp;amp; echo &amp;quot;deb https://www.ui.com/downloads/unifi/debian stable ubiquiti&amp;quot; &amp;amp;gt; /etc/apt/sources.list.d/100-ubnt-unifi.list &amp;amp;&amp;amp; apt update &amp;amp;&amp;amp; apt install unifi -y &amp;amp;&amp;amp; service unifi start&lt;br /&gt;
&amp;lt;/pre&amp;gt;&amp;lt;p&amp;gt;Der obenstehende Befehl stoppt den Unifi Controller, fügt einen Eintrag in die apt sources Liste hinzu, führt ein update durch, installiert den neusten verfügbaren Unifi Controller und startet diesen wieder.&amp;lt;/p&amp;gt;&amp;lt;/figure&amp;gt;&amp;lt;/figure&amp;gt;&lt;/div&gt;</summary>
		<author><name>Admin</name></author>
	</entry>
	<entry>
		<id>https://wiki.my-network.at/index.php?title=Unifi_Controller&amp;diff=21</id>
		<title>Unifi Controller</title>
		<link rel="alternate" type="text/html" href="https://wiki.my-network.at/index.php?title=Unifi_Controller&amp;diff=21"/>
		<updated>2022-05-27T14:12:26Z</updated>

		<summary type="html">&lt;p&gt;Admin: Die Seite wurde neu angelegt: „==== 1. Über SSH auf den Unifi Controller zugreifen ==== &amp;lt;p&amp;gt;Um über ssh auf den Unifi Controller Server zuzugreifen, können Sie den Befehl '''''ssh benutzer…“&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==== 1. Über SSH auf den Unifi Controller zugreifen ====&lt;br /&gt;
&amp;lt;p&amp;gt;Um über ssh auf den Unifi Controller Server zuzugreifen, können Sie den Befehl '''''ssh benutzername@hostname''''' auf den Unifi Controller zuzugreifen. Beispielsweise könnte der Befehl dann wie folgt aussehen:&amp;lt;/p&amp;gt;&amp;lt;pre class=&amp;quot;wp-block-preformatted&amp;quot;&amp;gt;ssh root@192.168.1.12&amp;lt;/pre&amp;gt;&amp;lt;p&amp;gt;Unter Ubuntu geben Sie nun zusätzlich noch ''sudo -s'' ein, um Root rechte zu erhalten.&amp;lt;/p&amp;gt;&amp;lt;pre class=&amp;quot;wp-block-preformatted&amp;quot;&amp;gt;sudo -s&amp;lt;/pre&amp;gt;&lt;br /&gt;
==== 2. Update &amp;amp; Upgrade durchführen ====&lt;br /&gt;
&amp;lt;pre class=&amp;quot;wp-block-preformatted&amp;quot;&amp;gt;apt update &amp;amp;&amp;amp; apt upgrade -y&amp;lt;/pre&amp;gt;&lt;br /&gt;
==== 3. Dependencies installieren ====&lt;br /&gt;
&amp;lt;pre class=&amp;quot;wp-block-preformatted&amp;quot;&amp;gt;apt install ca-certificates wget -y&amp;lt;/pre&amp;gt;&lt;br /&gt;
==== 4. Unifi Controller installieren – Install Script herunterladen. ====&lt;br /&gt;
&amp;lt;p&amp;gt;Mit folgendem Befehl laden Sie das install Script herunter.&amp;lt;/p&amp;gt;&amp;lt;pre class=&amp;quot;wp-block-preformatted&amp;quot;&amp;gt;wget https://get.glennr.nl/unifi/install/unifi-7.0.23.sh&amp;lt;/pre&amp;gt;&amp;lt;p&amp;gt;Falls Sie eine neuere Version installieren möchten, ersetzen Sie «unifi-7.0.23.sh» mit der neueren Version.&amp;lt;/p&amp;gt;&lt;br /&gt;
==== 5. Installation durchführen ====&lt;br /&gt;
&amp;lt;pre class=&amp;quot;wp-block-preformatted&amp;quot;&amp;gt;bash unifi-7.0.23.sh&amp;lt;/pre&amp;gt;&amp;lt;p&amp;gt;Auch bei diesem Befehl verwenden Sie die Version, welche sie installieren möchten.&amp;lt;/p&amp;gt;&amp;lt;div class=&amp;quot;wp-block-jetpack-slideshow aligncenter&amp;quot; data-effect=&amp;quot;slide&amp;quot; data-jetpack-block-initialized=&amp;quot;true&amp;quot;&amp;gt;&amp;lt;div class=&amp;quot;wp-block-jetpack-slideshow_container swiper-container swiper-container-initialized swiper-container-horizontal swiper-container-pointer-events wp-swiper-initialized&amp;quot;&amp;gt;&lt;br /&gt;
*&amp;lt;figure&amp;gt;&amp;lt;figcaption class=&amp;quot;wp-block-jetpack-slideshow_caption gallery-caption&amp;quot;&amp;gt;Nun ist die Installation abgeschlossen und Sie können über die Web UI auf den Unifi Controller zugreifen.&amp;lt;/figcaption&amp;gt;&amp;lt;/figure&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&amp;lt;/div&amp;gt;&lt;/div&gt;</summary>
		<author><name>Admin</name></author>
	</entry>
	<entry>
		<id>https://wiki.my-network.at/index.php?title=MediaWiki:Sidebar&amp;diff=20</id>
		<title>MediaWiki:Sidebar</title>
		<link rel="alternate" type="text/html" href="https://wiki.my-network.at/index.php?title=MediaWiki:Sidebar&amp;diff=20"/>
		<updated>2022-04-09T18:23:06Z</updated>

		<summary type="html">&lt;p&gt;Admin: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;br /&gt;
* navigation&lt;br /&gt;
** mainpage|mainpage-description&lt;br /&gt;
** recentchanges-url|recentchanges&lt;br /&gt;
** randompage-url|randompage&lt;br /&gt;
** helppage|help-mediawiki&lt;br /&gt;
** Special:AllPages|allpages&lt;br /&gt;
* SEARCH&lt;br /&gt;
* TOOLBOX&lt;br /&gt;
* LANGUAGES&lt;/div&gt;</summary>
		<author><name>Admin</name></author>
	</entry>
	<entry>
		<id>https://wiki.my-network.at/index.php?title=MediaWiki:Sidebar&amp;diff=19</id>
		<title>MediaWiki:Sidebar</title>
		<link rel="alternate" type="text/html" href="https://wiki.my-network.at/index.php?title=MediaWiki:Sidebar&amp;diff=19"/>
		<updated>2022-04-09T18:22:18Z</updated>

		<summary type="html">&lt;p&gt;Admin: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;br /&gt;
* navigation&lt;br /&gt;
** Special:AllPages|allpages&lt;br /&gt;
** mainpage|mainpage-description&lt;br /&gt;
** recentchanges-url|recentchanges&lt;br /&gt;
** randompage-url|randompage&lt;br /&gt;
** helppage|help-mediawiki&lt;br /&gt;
* SEARCH&lt;br /&gt;
* TOOLBOX&lt;br /&gt;
* LANGUAGES&lt;/div&gt;</summary>
		<author><name>Admin</name></author>
	</entry>
	<entry>
		<id>https://wiki.my-network.at/index.php?title=MediaWiki:Sidebar&amp;diff=18</id>
		<title>MediaWiki:Sidebar</title>
		<link rel="alternate" type="text/html" href="https://wiki.my-network.at/index.php?title=MediaWiki:Sidebar&amp;diff=18"/>
		<updated>2022-04-06T09:44:04Z</updated>

		<summary type="html">&lt;p&gt;Admin: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;br /&gt;
* navigation&lt;br /&gt;
** mainpage|mainpage-description&lt;br /&gt;
** recentchanges-url|recentchanges&lt;br /&gt;
** randompage-url|randompage&lt;br /&gt;
** helppage|help-mediawiki&lt;br /&gt;
** Special:AllPages|allpages&lt;br /&gt;
* SEARCH&lt;br /&gt;
* TOOLBOX&lt;br /&gt;
* LANGUAGES&lt;/div&gt;</summary>
		<author><name>Admin</name></author>
	</entry>
	<entry>
		<id>https://wiki.my-network.at/index.php?title=MediaWiki:Sidebar&amp;diff=17</id>
		<title>MediaWiki:Sidebar</title>
		<link rel="alternate" type="text/html" href="https://wiki.my-network.at/index.php?title=MediaWiki:Sidebar&amp;diff=17"/>
		<updated>2022-04-06T09:43:50Z</updated>

		<summary type="html">&lt;p&gt;Admin: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;br /&gt;
* navigation&lt;br /&gt;
** mainpage|mainpage-description&lt;br /&gt;
** recentchanges-url|recentchanges&lt;br /&gt;
** randompage-url|randompage&lt;br /&gt;
** helppage|help-mediawiki&lt;br /&gt;
** Special:AllPages|allpages&lt;br /&gt;
* SEARCH&lt;/div&gt;</summary>
		<author><name>Admin</name></author>
	</entry>
	<entry>
		<id>https://wiki.my-network.at/index.php?title=Main_Page&amp;diff=16</id>
		<title>Main Page</title>
		<link rel="alternate" type="text/html" href="https://wiki.my-network.at/index.php?title=Main_Page&amp;diff=16"/>
		<updated>2022-04-06T09:38:29Z</updated>

		<summary type="html">&lt;p&gt;Admin: Replaced content with &amp;quot;Meine private Wiki Seite&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&amp;quot;&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Meine private Wiki Seite&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;/div&gt;</summary>
		<author><name>Admin</name></author>
	</entry>
	<entry>
		<id>https://wiki.my-network.at/index.php?title=MediaWiki:Sidebar&amp;diff=15</id>
		<title>MediaWiki:Sidebar</title>
		<link rel="alternate" type="text/html" href="https://wiki.my-network.at/index.php?title=MediaWiki:Sidebar&amp;diff=15"/>
		<updated>2022-04-06T09:37:08Z</updated>

		<summary type="html">&lt;p&gt;Admin: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;br /&gt;
* navigation&lt;br /&gt;
** mainpage|mainpage-description&lt;br /&gt;
** recentchanges-url|recentchanges&lt;br /&gt;
** randompage-url|randompage&lt;br /&gt;
** helppage|help-mediawiki&lt;br /&gt;
** Special:AllPages|allpages&lt;br /&gt;
* SEARCH&lt;br /&gt;
* TOOLBOX&lt;br /&gt;
* LANGUAGES&lt;/div&gt;</summary>
		<author><name>Admin</name></author>
	</entry>
	<entry>
		<id>https://wiki.my-network.at/index.php?title=MediaWiki:Sidebar&amp;diff=14</id>
		<title>MediaWiki:Sidebar</title>
		<link rel="alternate" type="text/html" href="https://wiki.my-network.at/index.php?title=MediaWiki:Sidebar&amp;diff=14"/>
		<updated>2022-04-06T09:35:47Z</updated>

		<summary type="html">&lt;p&gt;Admin: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;br /&gt;
* navigation&lt;br /&gt;
** mainpage|mainpage-description&lt;br /&gt;
** recentchanges-url|recentchanges&lt;br /&gt;
** randompage-url|randompage&lt;br /&gt;
** helppage|help-mediawiki&lt;br /&gt;
** Special:AllPages|allpages&lt;br /&gt;
** SEARCH&lt;br /&gt;
* TOOLBOX&lt;br /&gt;
* LANGUAGES&lt;/div&gt;</summary>
		<author><name>Admin</name></author>
	</entry>
	<entry>
		<id>https://wiki.my-network.at/index.php?title=MediaWiki:Sidebar&amp;diff=13</id>
		<title>MediaWiki:Sidebar</title>
		<link rel="alternate" type="text/html" href="https://wiki.my-network.at/index.php?title=MediaWiki:Sidebar&amp;diff=13"/>
		<updated>2022-04-06T09:25:01Z</updated>

		<summary type="html">&lt;p&gt;Admin: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;br /&gt;
* navigation&lt;br /&gt;
** mainpage|mainpage-description&lt;br /&gt;
** recentchanges-url|recentchanges&lt;br /&gt;
** randompage-url|randompage&lt;br /&gt;
** helppage|help-mediawiki&lt;br /&gt;
** Special:AllPages|allpages&lt;br /&gt;
* SEARCH&lt;br /&gt;
* TOOLBOX&lt;br /&gt;
* LANGUAGES&lt;/div&gt;</summary>
		<author><name>Admin</name></author>
	</entry>
	<entry>
		<id>https://wiki.my-network.at/index.php?title=MediaWiki:Sidebar&amp;diff=12</id>
		<title>MediaWiki:Sidebar</title>
		<link rel="alternate" type="text/html" href="https://wiki.my-network.at/index.php?title=MediaWiki:Sidebar&amp;diff=12"/>
		<updated>2022-04-06T09:20:43Z</updated>

		<summary type="html">&lt;p&gt;Admin: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;br /&gt;
* navigation&lt;br /&gt;
** mainpage|mainpage-description&lt;br /&gt;
** recentchanges-url|recentchanges&lt;br /&gt;
** randompage-url|randompage&lt;br /&gt;
** helppage|help-mediawiki&lt;br /&gt;
* SEARCH&lt;br /&gt;
* TOOLBOX&lt;br /&gt;
* LANGUAGES&lt;/div&gt;</summary>
		<author><name>Admin</name></author>
	</entry>
	<entry>
		<id>https://wiki.my-network.at/index.php?title=MediaWiki:Sidebar&amp;diff=11</id>
		<title>MediaWiki:Sidebar</title>
		<link rel="alternate" type="text/html" href="https://wiki.my-network.at/index.php?title=MediaWiki:Sidebar&amp;diff=11"/>
		<updated>2022-04-06T09:20:06Z</updated>

		<summary type="html">&lt;p&gt;Admin: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;br /&gt;
* navigation&lt;br /&gt;
** mainpage|mainpage-description&lt;br /&gt;
//** recentchanges-url|recentchanges&lt;br /&gt;
** randompage-url|randompage&lt;br /&gt;
** helppage|help-mediawiki&lt;br /&gt;
* SEARCH&lt;br /&gt;
* TOOLBOX&lt;br /&gt;
* LANGUAGES&lt;/div&gt;</summary>
		<author><name>Admin</name></author>
	</entry>
	<entry>
		<id>https://wiki.my-network.at/index.php?title=MediaWiki:Sidebar&amp;diff=10</id>
		<title>MediaWiki:Sidebar</title>
		<link rel="alternate" type="text/html" href="https://wiki.my-network.at/index.php?title=MediaWiki:Sidebar&amp;diff=10"/>
		<updated>2022-04-06T09:19:41Z</updated>

		<summary type="html">&lt;p&gt;Admin: Created page with &amp;quot; * navigation ** mainpage|mainpage-description * recentchanges-url|recentchanges ** randompage-url|randompage ** helppage|help-mediawiki * SEARCH * TOOLBOX * LANGUAGES&amp;quot;&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;br /&gt;
* navigation&lt;br /&gt;
** mainpage|mainpage-description&lt;br /&gt;
* recentchanges-url|recentchanges&lt;br /&gt;
** randompage-url|randompage&lt;br /&gt;
** helppage|help-mediawiki&lt;br /&gt;
* SEARCH&lt;br /&gt;
* TOOLBOX&lt;br /&gt;
* LANGUAGES&lt;/div&gt;</summary>
		<author><name>Admin</name></author>
	</entry>
	<entry>
		<id>https://wiki.my-network.at/index.php?title=Magic_Mirror&amp;diff=9</id>
		<title>Magic Mirror</title>
		<link rel="alternate" type="text/html" href="https://wiki.my-network.at/index.php?title=Magic_Mirror&amp;diff=9"/>
		<updated>2022-04-04T17:57:42Z</updated>

		<summary type="html">&lt;p&gt;Admin: Created page with &amp;quot;Magic Mirror update:  In Magic Mirror Ordner wechseln.&amp;lt;pre&amp;gt;git pull &amp;amp;&amp;amp; npm install --only=prod --omit=dev &amp;lt;/pre&amp;gt; Modul update:  in Magic Mirror Modul Ordner wechseln.&amp;amp;nbsp;&amp;lt;pr...&amp;quot;&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Magic Mirror update:&lt;br /&gt;
&lt;br /&gt;
In Magic Mirror Ordner wechseln.&amp;lt;pre&amp;gt;git pull &amp;amp;&amp;amp; npm install --only=prod --omit=dev&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Modul update:&lt;br /&gt;
&lt;br /&gt;
in Magic Mirror Modul Ordner wechseln.&amp;amp;nbsp;&amp;lt;pre&amp;gt;git pull&amp;lt;/pre&amp;gt;&lt;/div&gt;</summary>
		<author><name>Admin</name></author>
	</entry>
	<entry>
		<id>https://wiki.my-network.at/index.php?title=Backup&amp;diff=8</id>
		<title>Backup</title>
		<link rel="alternate" type="text/html" href="https://wiki.my-network.at/index.php?title=Backup&amp;diff=8"/>
		<updated>2022-04-04T16:59:11Z</updated>

		<summary type="html">&lt;p&gt;Admin: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Backup mit dd und Image auf Netzwerkfreigabe speichern.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;mkdir /tmp/backup&lt;br /&gt;
mount -t cifs -o username=BENUTZER,password=PASSWORT //192.168.x.yy/Ordner/Ablage/ /tmp/backup/&lt;br /&gt;
dd bs=4M if=/dev/mmcblk0 &amp;amp;nbsp;| gzip -c &amp;amp;gt;/tmp/backup/MediaCenter-SZ-`date +%d%m%y`.img.gz&lt;br /&gt;
umount /tmp/backup&amp;lt;/pre&amp;gt;&lt;/div&gt;</summary>
		<author><name>Admin</name></author>
	</entry>
	<entry>
		<id>https://wiki.my-network.at/index.php?title=Backup&amp;diff=7</id>
		<title>Backup</title>
		<link rel="alternate" type="text/html" href="https://wiki.my-network.at/index.php?title=Backup&amp;diff=7"/>
		<updated>2022-04-04T16:58:28Z</updated>

		<summary type="html">&lt;p&gt;Admin: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Backup mit dd und Image auf Netzwerkfreigabe speichern.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;mkdir /tmp/backup&lt;br /&gt;
&amp;lt;br&amp;gt;mount -t cifs -o username=BENUTZER,password=PASSWORT //192.168.x.yy/Ordner/Ablage/ /tmp/backup/&lt;br /&gt;
&amp;lt;br&amp;gt;dd bs=4M if=/dev/mmcblk0 &amp;amp;nbsp;| gzip -c &amp;amp;gt;/tmp/backup/MediaCenter-SZ-`date +%d%m%y`.img.gz&lt;br /&gt;
&amp;lt;br&amp;gt;umount /tmp/backup&amp;lt;br&amp;gt;&amp;lt;/pre&amp;gt;&lt;/div&gt;</summary>
		<author><name>Admin</name></author>
	</entry>
	<entry>
		<id>https://wiki.my-network.at/index.php?title=Backup&amp;diff=6</id>
		<title>Backup</title>
		<link rel="alternate" type="text/html" href="https://wiki.my-network.at/index.php?title=Backup&amp;diff=6"/>
		<updated>2022-04-04T16:56:45Z</updated>

		<summary type="html">&lt;p&gt;Admin: Created page with &amp;quot;Backup mit dd und Image auf Netzwerkfreigabe speichern.  &amp;lt;pre&amp;gt;mkdir /tmp/backup&amp;lt;br&amp;gt;mount -t cifs -o username=BENUTZER,password=PASSWORT //192.168.x.yy/Ordner/Ablage/ /tmp/back...&amp;quot;&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Backup mit dd und Image auf Netzwerkfreigabe speichern.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;mkdir /tmp/backup&amp;lt;br&amp;gt;mount -t cifs -o username=BENUTZER,password=PASSWORT //192.168.x.yy/Ordner/Ablage/ /tmp/backup/&amp;lt;br&amp;gt;dd bs=4M if=/dev/mmcblk0 &amp;amp;nbsp;| gzip -c &amp;amp;gt;/tmp/backup/MediaCenter-SZ-`date +%d%m%y`.img.gz&amp;lt;br&amp;gt;umount /tmp/backup&amp;lt;br&amp;gt;&amp;lt;/pre&amp;gt;&lt;/div&gt;</summary>
		<author><name>Admin</name></author>
	</entry>
	<entry>
		<id>https://wiki.my-network.at/index.php?title=Raspberry&amp;diff=5</id>
		<title>Raspberry</title>
		<link rel="alternate" type="text/html" href="https://wiki.my-network.at/index.php?title=Raspberry&amp;diff=5"/>
		<updated>2022-04-04T16:48:24Z</updated>

		<summary type="html">&lt;p&gt;Admin: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Headless Einrichtung:&amp;lt;p&amp;gt;Mitunter ist es praktisch, wenn Sie einen Raspberry Pi auf Anhieb über das WLAN via SSH bedienen können. Das gibt Ihnen die Möglichkeit, ohne angeschlossene Maus und Tastatur mit der Konfiguration zu beginnen — zumindest soweit, wie Sie dies via SSH im Textmodus durchführen können.&amp;lt;/p&amp;gt;&amp;lt;p&amp;gt;Dazu kopieren Sie das Raspbian- oder das Raspbian-Lite-Image wie üblich auf eine SD-Karte, z.B. mit dem Programm Etcher oder Pibaker&amp;lt;/p&amp;gt;&amp;lt;p&amp;gt;. Danach platzieren Sie (noch auf Ihrem PC) in der Boot-Partition der SD-Karte zwei Dateien:&amp;lt;/p&amp;gt;&lt;br /&gt;
*Die leere Datei &amp;lt;code&amp;gt;ssh&amp;lt;/code&amp;gt; bewirkt, dass der SSH-Dienst sofort aktiviert wird. (Bei aktuellen Raspbian-Versionen ist dies ja nicht mehr der Fall.)&amp;lt;p&amp;gt;&amp;lt;br&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
*&amp;lt;p&amp;gt;Und die Datei &amp;lt;code&amp;gt;wpa_supplicant.conf&amp;lt;/code&amp;gt; enthält die WLAN-Konfiguration. Sie wird beim ersten Start des Raspberry Pi in das Verzeichnis &amp;lt;code&amp;gt;/etc/wpa_supplicant&amp;lt;/code&amp;gt; kopiert. Die Datei muss die Bezeichnung des WLANs (SSID) und dessen Passwort enthalten. Dabei gilt dieser Aufbau.&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;pre&amp;gt;&amp;lt;code&amp;gt;country=AT&lt;br /&gt;
ctrl_interface=DIR=/var/run/wpa_supplicant GROUP=netdev&lt;br /&gt;
update_config=1&lt;br /&gt;
&lt;br /&gt;
network={&lt;br /&gt;
    ssid=&amp;quot;NETWORK-NAME&amp;quot;&lt;br /&gt;
    psk=&amp;quot;NETWORK-PASSWORD&amp;quot;&lt;br /&gt;
}&amp;lt;/code&amp;gt;&amp;lt;/pre&amp;gt;&lt;/div&gt;</summary>
		<author><name>Admin</name></author>
	</entry>
	<entry>
		<id>https://wiki.my-network.at/index.php?title=Raspberry&amp;diff=3</id>
		<title>Raspberry</title>
		<link rel="alternate" type="text/html" href="https://wiki.my-network.at/index.php?title=Raspberry&amp;diff=3"/>
		<updated>2022-01-18T17:39:04Z</updated>

		<summary type="html">&lt;p&gt;Admin: Created page with &amp;quot;Raspberry&amp;quot;&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Raspberry&lt;/div&gt;</summary>
		<author><name>Admin</name></author>
	</entry>
	<entry>
		<id>https://wiki.my-network.at/index.php?title=Main_Page&amp;diff=2</id>
		<title>Main Page</title>
		<link rel="alternate" type="text/html" href="https://wiki.my-network.at/index.php?title=Main_Page&amp;diff=2"/>
		<updated>2021-02-26T07:40:24Z</updated>

		<summary type="html">&lt;p&gt;Admin: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Welcome to MediaWiki.&amp;lt;br&amp;gt;&lt;br /&gt;
Consult the [http://meta.wikimedia.org/wiki/Help:Contents User's Guide]&lt;br /&gt;
for information on using the wiki software.&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
== Getting started ==&lt;br /&gt;
* Log in as '''Admin''' and start your wiki!&lt;br /&gt;
* [https://www.turnkeylinux.org/mediawiki TurnKey Linux MediaWiki appliance release notes]&lt;br /&gt;
* [http://www.mediawiki.org/wiki/Manual:Configuration_settings MediaWiki Configuration settings list]&lt;br /&gt;
* [http://www.mediawiki.org/wiki/Manual:FAQ MediaWiki FAQ]&lt;br /&gt;
* [http://lists.wikimedia.org/mailman/listinfo/mediawiki-announce MediaWiki release mailing list]&lt;/div&gt;</summary>
		<author><name>Admin</name></author>
	</entry>
</feed>