<?xml version="1.0"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="de">
	<id>https://wiki.hostsharing.net/api.php?action=feedcontributions&amp;feedformat=atom&amp;user=Apc00-tony</id>
	<title>Hostsharing Wiki - Benutzerbeiträge [de]</title>
	<link rel="self" type="application/atom+xml" href="https://wiki.hostsharing.net/api.php?action=feedcontributions&amp;feedformat=atom&amp;user=Apc00-tony"/>
	<link rel="alternate" type="text/html" href="https://wiki.hostsharing.net/index.php?title=Spezial:Beitr%C3%A4ge/Apc00-tony"/>
	<updated>2026-04-25T21:11:28Z</updated>
	<subtitle>Benutzerbeiträge</subtitle>
	<generator>MediaWiki 1.43.8</generator>
	<entry>
		<id>https://wiki.hostsharing.net/index.php?title=Traffic&amp;diff=7319</id>
		<title>Traffic</title>
		<link rel="alternate" type="text/html" href="https://wiki.hostsharing.net/index.php?title=Traffic&amp;diff=7319"/>
		<updated>2025-03-24T13:21:48Z</updated>

		<summary type="html">&lt;p&gt;Apc00-tony: /* Viel Traffic durch Login-Versuche auf Wordpress-Seiten */ Tippfehler behoben. Für den Fall, daß jemand cuttet und pästet.&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Als Traffic bezeichnet man Datenverkehr zwischen zwei Computersystemen.&lt;br /&gt;
&lt;br /&gt;
Dies beinhaltet [[Logging#HTTP-Traffic|Web]], [[Logging#Mail-Traffic|Mail]] und [[Logging#FTP-Traffic|FTP]] Verbindungen.&lt;br /&gt;
&lt;br /&gt;
==Traffic Ursachen erkennen==&lt;br /&gt;
&lt;br /&gt;
Hostsharing teilt per Mail mit, wenn der tägliche Durchschnitt an gebuchtem Traffic überschritten wurde. In der Mail steht, welches Paket den Traffic verursacht hat und die Warnung, dass Konsequenzen für die Monatsabrechnungen entstehen können. Wer nicht selbst die Ursachen des zusätzlichen Traffic kennt, kann sie mit folgenden Methoden ergründen:&lt;br /&gt;
&lt;br /&gt;
Als erstes einfach mal den Log ansehen und durchscrollen.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=shell&amp;gt;&lt;br /&gt;
less ~/var/web.log&lt;br /&gt;
less ~/var/web.log-yesterday&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Da kann man oft schon alleine durch Ansehen gleichförmige Strukturen erkennen, z.B. massenhafte Login-Versuche auf einen Wordpress Blog, die sehr viel Traffic generieren.&lt;br /&gt;
&lt;br /&gt;
==Webzugriffe analysieren==&lt;br /&gt;
&lt;br /&gt;
Diese Idee von Michael Hierweck: Wie bekomme ich heraus, welche Web-Zugriffe für mein Traffic-Volumen&lt;br /&gt;
maßgeblich verantwortlich sind?&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=shell line&amp;gt;&lt;br /&gt;
cat $HOME/var/web.log |cut -d &#039; &#039; -f11 |  grep -o &#039;[0-9]*&#039; | sort -n |uniq -c |sed -e&#039;s/^ *//&#039; \&lt;br /&gt;
	|while read FACTOR SUM; do&lt;br /&gt;
		echo &amp;quot;$((${FACTOR} * ${SUM})) ${FACTOR} ${SUM}&amp;quot;;&lt;br /&gt;
	done |sort -n&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
* Zeile 1: Traffic aus dem Log extrahieren, sortieren, zählen.&lt;br /&gt;
* Zeile 2: über die Einträge wandern&lt;br /&gt;
* Zeile 3: Produkt aus Zugriffen und Einzelvolumen berechnen&lt;br /&gt;
* Zeile 4: Ausgabe von Produkt, Zugriffen und Einzelvolume je Zugriff&lt;br /&gt;
* Zeile 5: sortieren&lt;br /&gt;
&lt;br /&gt;
Das Ganze als Einzeiler zum Kopieren, Einfügen und Ausführen im Terminal:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=shell&amp;gt;&lt;br /&gt;
cat $HOME/var/web.log |cut -d &#039; &#039; -f11 |  grep -o &#039;[0-9]*&#039; | sort -n |uniq -c |sed -e&#039;s/^ *//&#039;|while read FACTOR SUM; do echo &amp;quot;$((${FACTOR} * ${SUM})) ${FACTOR} ${SUM}&amp;quot;;done |sort -n&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Dieser Skript gibt den Traffic aus, den gleichförmige Einzelzugriffe generieren, die größten Brocken stehen unten. Z.B.:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=output line&amp;gt;&lt;br /&gt;
219558 6 36593&lt;br /&gt;
232288 14 16592&lt;br /&gt;
239998 22 10909&lt;br /&gt;
270812 2 135406&lt;br /&gt;
304520 5 60904&lt;br /&gt;
318248 14 22732&lt;br /&gt;
559062 14 39933&lt;br /&gt;
602760 20 30138&lt;br /&gt;
711496 8 88937&lt;br /&gt;
2325929 101 23029&lt;br /&gt;
2351668 29 81092&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Ganz unten sieht man, dass 29 Zugriffe mit je 81092 Bytes zusammen 2351668 Bytes Traffic gekostet haben. In diesem Fall kann man nun ganz simpel im Log nach der dritten Zahl greppen und in less anzeigen, z.B. so:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=shell&amp;gt;&lt;br /&gt;
grep 81092 $HOME/var/web.log | less&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Wenn ich dieses Script öfter brauche ... ===&lt;br /&gt;
&lt;br /&gt;
lohnt es sich, daraus ein kleines Programm zu machen.&lt;br /&gt;
Dazu einfach&lt;br /&gt;
 &lt;br /&gt;
* Texteditor Eurer Wahl öffnen&lt;br /&gt;
* Script-Text hier kopieren und in den Editor einfügen&lt;br /&gt;
Hier noch mal eine etwas erweiterte Version&lt;br /&gt;
&amp;lt;syntaxhighlight lang=shell line&amp;gt;&lt;br /&gt;
#!/bin/bash&lt;br /&gt;
echo ---------------------------------------------------------------&lt;br /&gt;
echo ------------- Top 10 Traffic_Verusacher heute -----------------&lt;br /&gt;
echo ---------------------------------------------------------------&lt;br /&gt;
echo Gesamtvolumen, Zugriffe, Einzelvolumen&lt;br /&gt;
cat $HOME/var/web.log |cut -d &#039; &#039; -f11 |  grep -o &#039;[0-9]*&#039; | sort -n |uniq -c |sed -e&#039;s/^ *//&#039; \&lt;br /&gt;
	|while read FACTOR SUM; do&lt;br /&gt;
		echo &amp;quot;$((${FACTOR} * ${SUM})) ${FACTOR} ${SUM}&amp;quot;;&lt;br /&gt;
	done |sort -n -r|head -10&lt;br /&gt;
&lt;br /&gt;
echo &lt;br /&gt;
echo ---------------------------------------------------------------&lt;br /&gt;
echo ------------- Top 10 Traffic_Verusacher gestern ---------------&lt;br /&gt;
echo ---------------------------------------------------------------&lt;br /&gt;
echo &lt;br /&gt;
echo Gesamtvolumen, Zugriffe, Einzelvolumen&lt;br /&gt;
cat $HOME/var/web.log-yesterday |cut -d &#039; &#039; -f11 |  grep -o &#039;[0-9]*&#039; | sort -n |uniq -c |sed -e&#039;s/^ *//&#039; \&lt;br /&gt;
	|while read FACTOR SUM; do&lt;br /&gt;
		echo &amp;quot;$((${FACTOR} * ${SUM})) ${FACTOR} ${SUM}&amp;quot;;&lt;br /&gt;
	done |sort -n -r|head -10&lt;br /&gt;
echo&lt;br /&gt;
echo Sie koennen nun nach dem Versacher suchen, indem sie die &lt;br /&gt;
echo Logfiles des Tages nach dem Einzelvolumen durchsuchen&lt;br /&gt;
echo &#039;Befehl: grep 81092 $HOME/var/web.log | less&#039;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
* Script als Datei ohne Erweiterung unter einem griffigen Namen wie &amp;quot;volumenauswertung&amp;quot; speichern&lt;br /&gt;
* Scriptdatei in das Home-Verzeichnis des Paket-Users auf dem Server laden.&lt;br /&gt;
* Permission x zufügen, um das Skript ausführbar zu machen.(In WinSCP: Rechtsklick auf Datei, Eigenschaften-Dialog öffnen, X-Eigenschaft für den Eigentümer setzen)  &lt;br /&gt;
&lt;br /&gt;
Nun kann man dieses Script jederzeit mit ./volumenauswertung starten.&lt;br /&gt;
&lt;br /&gt;
== Wie erkenne ich, welche Webseite gestern am meisten Traffic Volumen hatte? ==&lt;br /&gt;
&lt;br /&gt;
Dieser Einzeiler sollte es zeigen (Datum entsprechend ändern):&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=shell&amp;gt;&lt;br /&gt;
for f in ${HOME}/var/web-*-20230401*; do echo $f; gunzip -c $f | perl -nE &#039;/\[.+\] &amp;quot;.+&amp;quot; \d+ (\d+)/; $sum += $1; END { printf(&amp;quot;%.1f&amp;quot;, $sum/1024/1024); print &amp;quot; MB\n&amp;quot;}&#039;; done&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Wie bekomme ich IPs mit massenhaften Web-Zugriffen erkannt und gesperrt? ==&lt;br /&gt;
&lt;br /&gt;
IPs mit mehrstelligen Zugriffen werden so gefunden (Hier alle IPs mit vierstelligen Zugriffen, beachte die Ziffer 4 im Ausdruck &amp;quot;egrep &#039;^[0-9]{4,} .*$&#039;&amp;quot;):&lt;br /&gt;
&amp;lt;syntaxhighlight lang=shell&amp;gt;&lt;br /&gt;
cat ${HOME}/var/web.log |cut -d &#039; &#039; -f2 | sort | uniq -c |sed -e&#039;s/^ *//&#039; | egrep &#039;^[0-9]{4,} .*$&#039;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Als Paketadmin alle IPs mit 10.000 und mehr Web-Zugriffen aus dem&lt;br /&gt;
heutigen Log filtern und dafür Sperreinträge erzeugen, die man in die&lt;br /&gt;
.htaccess kopieren kann:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=shell line&amp;gt;&lt;br /&gt;
cat ${HOME}/var/web.log |cut -d &#039; &#039; -f2 |sort |uniq -c \&lt;br /&gt;
	|sed -e&#039;s/^ *//&#039; | egrep &#039;^[0-9]{5,} .*$&#039; |cut -d &#039; &#039;  -f 2 \&lt;br /&gt;
	|xargs -n1 -r -I XXX echo &amp;quot;deny from XXX&amp;quot;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* Zeile 1: Log auswerten und IPs extrahieren und zählen&lt;br /&gt;
* Zeile 2: Filtern (Mit der Anweisung &#039;&#039;&#039;egrep &#039;^[0-9]{5,} .*$&#039;&#039;&#039;&#039; werden durch die Ziffer 5 nur die gefundenen Einträge mit einer fünfstelligen Anzahl von Zugriffen gefunden. Ändert man 5 in 4, werden analog alle Einträge mit vierstelligen Zugriffszahlen gefunden.&lt;br /&gt;
* Zeile 3: Einträge erzeugen&lt;br /&gt;
&lt;br /&gt;
== Troubleshooting ==&lt;br /&gt;
=== Viel Traffic durch Login-Versuche auf Wordpress-Seiten ===&lt;br /&gt;
Login-Versuche auf Wordpress-Seiten können viel Traffic verursachen. Auf folgende Weise können wir diesen Traffic vermeiden, weil stumpfe Login-Roboter nicht an der [https://httpd.apache.org/docs/2.4/howto/auth.html Basic Authentication von Apache] vorbei kommen.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=shell&amp;gt;&lt;br /&gt;
cd /home/pacs/&amp;lt;xyz00&amp;gt;/users/&amp;lt;user&amp;gt;/doms/&amp;lt;domain&amp;gt;&lt;br /&gt;
vi .htaccess&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Wir geben zur Datei &#039;&#039;.htaccess&#039;&#039; den folgenden Inhalt hinzu.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=shell&amp;gt;&lt;br /&gt;
&amp;lt;Files wp-login.php&amp;gt;&lt;br /&gt;
  AuthName &amp;quot;Protect against silly robots, User username, Pw s3cr3t&amp;quot;&lt;br /&gt;
  AuthType Basic&lt;br /&gt;
  AuthUserFile /home/pacs/&amp;lt;xyz00&amp;gt;/users/&amp;lt;user&amp;gt;/doms/&amp;lt;domain&amp;gt;/.htpasswd&lt;br /&gt;
  Require valid-user&lt;br /&gt;
&amp;lt;/Files&amp;gt; &lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Wir generieren den Hash für das Passwort &#039;&#039;s3cr3t&#039;&#039; für den Benutzer &#039;&#039;username&#039;&#039; mit dem &#039;&#039;htpasswd&#039;&#039; Tool auf folgende Weise.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=shell&amp;gt;&lt;br /&gt;
cd /home/pacs/&amp;lt;xyz00&amp;gt;/users/&amp;lt;user&amp;gt;/doms/&amp;lt;domain&amp;gt;&lt;br /&gt;
htpasswd -b -c .htpasswd username s3cr3t&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Falls das Benutzer-Formular der Wordpress-Instanz im Browser über die Adresse &#039;&#039;&amp;lt;domain&amp;gt;/wp-login.php&#039;&#039; erreichbar ist, werden wir in Zukunft als Erstes von Apache und als Zweites von Wordpress nach Benutzer und Passwort gefragt.&lt;br /&gt;
&lt;br /&gt;
[[Kategorie:HSDoku]]&lt;br /&gt;
[[Kategorie:Glossar]]&lt;br /&gt;
[[Kategorie:Traffic]]&lt;br /&gt;
[[Kategorie:WebStatistik]]&lt;/div&gt;</summary>
		<author><name>Apc00-tony</name></author>
	</entry>
	<entry>
		<id>https://wiki.hostsharing.net/index.php?title=Diskussion:Mlmmj&amp;diff=7201</id>
		<title>Diskussion:Mlmmj</title>
		<link rel="alternate" type="text/html" href="https://wiki.hostsharing.net/index.php?title=Diskussion:Mlmmj&amp;diff=7201"/>
		<updated>2025-01-03T12:17:33Z</updated>

		<summary type="html">&lt;p&gt;Apc00-tony: /* Mlmmj und DKIM */ Added explanation of script&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= Mlmmj und DKIM =&lt;br /&gt;
&lt;br /&gt;
Testweise habe ich E-Mail so geändert, dass sie &amp;quot;sauber&amp;quot; von Listenserver als Absender kommen und an den Empfänger gehen.&lt;br /&gt;
&lt;br /&gt;
Ein Skript zum Umschreiben des From:-Header:&lt;br /&gt;
&lt;br /&gt;
  $ cat bin/receive-message &lt;br /&gt;
  #!/bin/bash&lt;br /&gt;
  sed -e &amp;quot;s/^From:\([^&amp;lt;]*\)&amp;lt;.*/From:\1&amp;lt;$1@hs-example.de&amp;gt;/&amp;quot;|/usr/bin/mlmmj-recieve -L /home/pacs/xyz00/users/lists/mlmmj/$1/&lt;br /&gt;
&lt;br /&gt;
Damit wird vor der Übergabe an Mlmmj die From:-Zeile einer eingehenden Listenmail so umgeschrieben, daß der Realname erhalten bleibt und die Adresse mit der des Verteilers ersetzt wird – also bspw. von &amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;From: &amp;quot;Hinz Kunz&amp;quot; &amp;lt;hinzkunz@example.com&amp;gt;&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt; in &amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;From: &amp;quot;Hinz Kunz&amp;quot; &amp;lt;meinverteiler@hs-example.de&amp;gt;&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt;. (Der Name des Verteilers ergibt sich aus dem Parameter $1: siehe den Aufruf von receive-message in der .procmailrc unten.)&lt;br /&gt;
&lt;br /&gt;
.forward und .procmailrc:&lt;br /&gt;
&lt;br /&gt;
  $ cat .forward &lt;br /&gt;
  &amp;quot;|/usr/bin/procmail -p&amp;quot;&lt;br /&gt;
&lt;br /&gt;
  $ cat .procmailrc &lt;br /&gt;
  SHELL=/bin/sh&lt;br /&gt;
  HOMEDIR=/home/pacs/xyz00/users/lists&lt;br /&gt;
  MAILDIR=/home/pacs/xyz00/users/lists/Maildir&lt;br /&gt;
  PMDIR=/home/pacs/xyz00/users/lists&lt;br /&gt;
  VERBOSE=yes&lt;br /&gt;
  LOGFILE=/home/pacs/xyz00/users/lists/var/procmail.log&lt;br /&gt;
  DEFAULT&lt;br /&gt;
  &lt;br /&gt;
  :0:&lt;br /&gt;
  * ^X-Original-To: ()\/[^@+]+&lt;br /&gt;
  |/home/pacs/xyz00/users/lists/bin/receive-message ${MATCH}&lt;br /&gt;
  &lt;br /&gt;
  :0&lt;br /&gt;
  { EXITCODE 67 }&lt;br /&gt;
&lt;br /&gt;
Im &amp;quot;control&amp;quot;-Ordner sorge ich dafür, dass der To:-Header, die Message-ID und die DKIM-Signatur gelöscht werden:&lt;br /&gt;
&lt;br /&gt;
  $ cat delheaders &lt;br /&gt;
  DKIM-Signature:&lt;br /&gt;
  To:&lt;br /&gt;
  Message-ID:&lt;br /&gt;
&lt;br /&gt;
  $ touch addtohdr&lt;br /&gt;
&lt;br /&gt;
Das Flag &amp;quot;addtohdr&amp;quot; sorgt dafür, dass mlmmj einen To:-Header an den endgültigen Empfänger der E-Mail einfügt.&lt;/div&gt;</summary>
		<author><name>Apc00-tony</name></author>
	</entry>
	<entry>
		<id>https://wiki.hostsharing.net/index.php?title=Vorlage:Veraltet&amp;diff=7143</id>
		<title>Vorlage:Veraltet</title>
		<link rel="alternate" type="text/html" href="https://wiki.hostsharing.net/index.php?title=Vorlage:Veraltet&amp;diff=7143"/>
		<updated>2024-12-03T11:57:15Z</updated>

		<summary type="html">&lt;p&gt;Apc00-tony: Änderung 7142 von Apc00-tony (Diskussion) rückgängig gemacht.&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&amp;lt;noinclude&amp;gt;&lt;br /&gt;
== Verwendung ==&lt;br /&gt;
&lt;br /&gt;
Um eine Seite als veraltet zu kennzeichnen, gib einfach am Anfang der Seite folgendes ein:&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;{{Veraltet}}&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Dadurch erscheint folgender Hinweis am Anfang der Seite; außerdem wird die Seite automatisch in die Kategorie &amp;quot;Baustelle&amp;quot; aufgenommen:&lt;br /&gt;
&amp;lt;/noinclude&amp;gt;&lt;br /&gt;
{{Textkasten|rot|Veraltet|Der Grund steht in der [[{{TALKPAGENAME}}|Diskussionsseite]]}}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;includeonly&amp;gt;[[Kategorie:Baustelle]]&amp;lt;/includeonly&amp;gt;&amp;lt;noinclude&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Kategorie:Textkasten]]&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/noinclude&amp;gt;&lt;/div&gt;</summary>
		<author><name>Apc00-tony</name></author>
	</entry>
	<entry>
		<id>https://wiki.hostsharing.net/index.php?title=Vorlage:Veraltet&amp;diff=7142</id>
		<title>Vorlage:Veraltet</title>
		<link rel="alternate" type="text/html" href="https://wiki.hostsharing.net/index.php?title=Vorlage:Veraltet&amp;diff=7142"/>
		<updated>2024-12-03T11:56:53Z</updated>

		<summary type="html">&lt;p&gt;Apc00-tony: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&amp;lt;noinclude&amp;gt;&lt;br /&gt;
== Verwendung ==&lt;br /&gt;
&lt;br /&gt;
Um eine Seite als veraltet zu kennzeichnen, gib einfach am Anfang der Seite folgendes ein:&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;{{Veraltet}}&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Dadurch erscheint folgender Hinweis am Anfang der Seite; außerdem wird die Seite automatisch in die Kategorie &amp;quot;Baustelle&amp;quot; aufgenommen:&lt;br /&gt;
&amp;lt;/noinclude&amp;gt;&lt;br /&gt;
{{Textkasten|rot|Veraltet|Der Grund steht in der [[{{TALKPAGENAME}}|Diskussionsseite]].}}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;includeonly&amp;gt;[[Kategorie:Baustelle]]&amp;lt;/includeonly&amp;gt;&amp;lt;noinclude&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Kategorie:Textkasten]]&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/noinclude&amp;gt;&lt;/div&gt;</summary>
		<author><name>Apc00-tony</name></author>
	</entry>
	<entry>
		<id>https://wiki.hostsharing.net/index.php?title=Cron&amp;diff=7141</id>
		<title>Cron</title>
		<link rel="alternate" type="text/html" href="https://wiki.hostsharing.net/index.php?title=Cron&amp;diff=7141"/>
		<updated>2024-12-03T11:49:59Z</updated>

		<summary type="html">&lt;p&gt;Apc00-tony: Zeichensetzung&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Cron wird ersetzt durch [[Prozessmanagement mit systemd im Userspace#Zeitgesteuerte_Ausführung_mit_systemd|Systemd Timer]].&lt;br /&gt;
&lt;br /&gt;
{{Veraltet}}&lt;br /&gt;
{{Löschkandidat}}&lt;br /&gt;
&lt;br /&gt;
Cron ist ein UNIX-Dienst, mit dem regelmäßige Jobs ausgeführt werden können, ohne dass der Benutzer dabei am System angemeldet sein muss. Dazu wird mit dem Kommando crontab die Konfiguration erstellt, aus der das System entnehmen kann, welches Kommando zu welcher Zeit auszuführen ist. Den Rest erledigt dann ein Systemprozess, der jede Minute überprüft, ob für einen User ein Job auszuführen ist.&lt;br /&gt;
=== Crontab ===&lt;br /&gt;
Mit crontab wird sowohl das Kommando zum Erstellen, Ändern und Löschen der eigenen Konfiguration als auch das dabei benutzte Dateiformat bezeichnet. Deshalb bekommt man die Beschreibung des Kommandos mit man 1 crontab und die Beschreibung des Formates mit man 5 crontab angezeigt.&lt;br /&gt;
&lt;br /&gt;
Anzeigen der aktuellen Konfiguration:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=shell&amp;gt;&lt;br /&gt;
crontab -l&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Löschen der kompletten Konfiguration:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=shell&amp;gt;&lt;br /&gt;
crontab -r&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Ändern der Konfiguration:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=shell&amp;gt;&lt;br /&gt;
crontab -e&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Crontab von einer Datei starten:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=shell&amp;gt;&lt;br /&gt;
crontab myjob&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Der beim Editieren verwendete Editor wird durch die Umgebungsvariablen EDITOR und VISUAL bestimmt. Der Default ist vi. Alternativ kann man folgenden Weg gehen:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=shell&amp;gt;&lt;br /&gt;
xyz00@hopi:~$crontab -l &amp;gt; myjobs&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Dann die Datei myjobs mit einem beliebigen Editor anpassen. Anschließend den cronjob von der Datei myjobs starten und die Datei löschen:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=shell&amp;gt;&lt;br /&gt;
xyz00@hopi:~$ crontab myjobs&lt;br /&gt;
&lt;br /&gt;
xyz00@hopi:~$ rm myjobs&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
=== Dateiformat ===&lt;br /&gt;
Kommentare werden mit # am Zeilenanfang gekennzeichnet. Eine Befehlszeile in der Crontab-Datei besteht aus sechs durch Leerzeichen getrennten Feldern, wobei die ersten fünf Felder den Zeitpunkt der Ausführung festlegen und der Rest der Zeile das auszuführende Kommando bestimmt. Die ersten fünf Felder sind:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=shell&amp;gt;&lt;br /&gt;
    * Minute (0-59)&lt;br /&gt;
    * Stunde (0-23)&lt;br /&gt;
    * Tag des Monats (1-31)&lt;br /&gt;
    * Monat (1-12 oder JAN-DEC)&lt;br /&gt;
    * Wochentag (0-7; 0 und 7 entsprechen jeweils Sonntag oder SUN-SAT) &lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Ein Stern * steht dabei für alle möglichen Werte eines Feldes. Die Felder können auch als Bereich (z.B. 2-4) und Liste (z.B. 3,6,8) angegeben werden. Auch lassen sich Schrittweiten für ein Feld angeben(z.B. */2). Dies kann auch kombiniert werden (z.B. 4-54/10).&lt;br /&gt;
&lt;br /&gt;
Das dritte und fünfte Feld können beide den Tag der Ausführung bezeichnen. Sind beide gesetzt, also nicht *, so wird der Job ausgeführt, wenn einer der beiden Bedingungen erfüllt ist.&lt;br /&gt;
&lt;br /&gt;
Statt einer Zeitangabe kann auch &amp;lt;code&amp;gt;@reboot&amp;lt;/code&amp;gt; verwendet werden. In diesem Fall wird z.B. ein Dienst nach dem Neustart des Servers wieder gestartet.&lt;br /&gt;
&lt;br /&gt;
=== Umgebungsvariablen ===&lt;br /&gt;
Folgende Umgebungsvariablen können in der crontab-Datei gesetzt werden:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=ini line&amp;gt;&lt;br /&gt;
PWD&lt;br /&gt;
&lt;br /&gt;
LOGNAME&lt;br /&gt;
&lt;br /&gt;
SHLVL&lt;br /&gt;
&lt;br /&gt;
SHELL&lt;br /&gt;
&lt;br /&gt;
HOME&lt;br /&gt;
&lt;br /&gt;
PATH&lt;br /&gt;
&lt;br /&gt;
MAILTO&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Beispiel ===&lt;br /&gt;
&amp;lt;syntaxhighlight lang=shell line&amp;gt;&lt;br /&gt;
# Alle Meldungen per Mail an diesen User schicken&lt;br /&gt;
MAILTO=xyz00&lt;br /&gt;
&lt;br /&gt;
# bei einem Neustart des Servers soll der Monit Dienst gestartet werden&lt;br /&gt;
@reboot rm -f $HOME/var/run/* &amp;amp;&amp;amp; /usr/bin/monit -c &amp;quot;$HOME/.monitrc&amp;quot;&lt;br /&gt;
&lt;br /&gt;
# Fuenf Minuten nach Mitternacht&lt;br /&gt;
5 0 * * * $HOME/bin/daily.job &amp;gt;&amp;gt; $HOME/tmp/out 2&amp;gt;&amp;amp;1&lt;br /&gt;
&lt;br /&gt;
# Um 14:15 an jedem Monatsersten&lt;br /&gt;
15 14 1 * * $HOME/bin/monthly&lt;br /&gt;
&lt;br /&gt;
# 0:23, 2:23, 4:23, 6:23 ... 22:23&lt;br /&gt;
23 0-23/2 * * * echo &amp;quot;run 23 minutes after midn, 2am, 4am ..., everyday&amp;quot;&lt;br /&gt;
&lt;br /&gt;
# Jeden Sonntag um 4:05&lt;br /&gt;
5 4 * * sun echo &amp;quot;run at 5 after 4 every sunday&amp;quot;&lt;br /&gt;
&lt;br /&gt;
# Jeden Freitag und jeden 1. des Monats um 4:05&lt;br /&gt;
5 4 1 * 5 echo &amp;quot;run at 5 after 4 every friday and every 1st&amp;quot;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Eine vollständige Beschreibung ist in der Manpage vorhanden: man 5 crontab.&lt;br /&gt;
&lt;br /&gt;
=== Performancehinweise ===&lt;br /&gt;
&lt;br /&gt;
Da Cronjobs einen erheblichen Teil der Systemlast ausmachen, sollen die folgenden Grundregeln beachtet werden:&lt;br /&gt;
&lt;br /&gt;
* Jobs wenn möglich über Nacht laufen lassen.&lt;br /&gt;
* Priorität des Jobs mit nice reduzieren.&lt;br /&gt;
* Glatte Minutenwerte (0,5,10,15,20,...) vermeiden. Statt */10 kann man auch 7-57/10 verwenden. &lt;br /&gt;
&lt;br /&gt;
=== Fehlerquellen ===&lt;br /&gt;
&lt;br /&gt;
Manchmal funktioniert ein Script interaktiv in der Shell ohne Probleme, wird aber beim Eintrag in die Crontab anscheinend nicht ausgeführt. Eine Ursache kann die fehlerhafte Spezifikation der Ausführungszeit in der Crontab sein. Außerdem haben die Login-Shell und cron unterschiedliche Umgebungsvariablen. Neben dem aktuellen Arbeitsverzeichnis kann PATH unterschiedlich für cron und die Login-Shell sein.&lt;br /&gt;
&lt;br /&gt;
Login-Shell: /usr/local/bin/su wird zuerst gefunden.&lt;br /&gt;
&lt;br /&gt;
cron: /bin/su wird zuerst gefunden.&lt;br /&gt;
&lt;br /&gt;
Wenn Cronjobs nicht ausgeführt werden, dann befinden sich die aufgerufenen Programme häufig auch in anderen Verzeichnissen.&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
[[Kategorie:HSDoku]]&lt;br /&gt;
[[Kategorie:Glossar]]&lt;/div&gt;</summary>
		<author><name>Apc00-tony</name></author>
	</entry>
	<entry>
		<id>https://wiki.hostsharing.net/index.php?title=Mlmmj&amp;diff=6661</id>
		<title>Mlmmj</title>
		<link rel="alternate" type="text/html" href="https://wiki.hostsharing.net/index.php?title=Mlmmj&amp;diff=6661"/>
		<updated>2024-05-31T14:34:23Z</updated>

		<summary type="html">&lt;p&gt;Apc00-tony: /* Lösung 2 */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[http://www.mlmmj.org/ mlmmj], angeblich eine Abkürzung für &amp;quot;Mailing List Management Made Joyful&amp;quot;, ist ein Programm, mit dem in einem Hostsharing Paket E-Mail-Verteiler realisiert werden kann.&lt;br /&gt;
&lt;br /&gt;
Wer noch nicht weiß, was ein E-Mail-Verteiler machen soll oder wie, lese veilleicht auch den Wikipedia-Artikel:&lt;br /&gt;
[http://de.wikipedia.org/wiki/Mailingliste Mailingliste]&lt;br /&gt;
&lt;br /&gt;
Eine leistungsfähigere Alternative zu mlmmj könnte [[Mailman_3_installieren|Mailman 3]] sein.&lt;br /&gt;
&lt;br /&gt;
Diese Anleitung beschreibt die Einrichtung einer Mailingliste für eine Domain in einem Hostsharing-Webspace.&lt;br /&gt;
&lt;br /&gt;
== Voraussetzungen  ==&lt;br /&gt;
&lt;br /&gt;
Das Debian Paket [http://packages.debian.org/search?keywords=mlmmj mlmmj] ist auf den Shared-Hosting-Servern bereits installiert. (Wer die Software selbst kompilieren möchte kann aktuellen Source-Code bei [https://codeberg.org/mlmmj/mlmmj|codeberg.org] finden.)&lt;br /&gt;
&lt;br /&gt;
Für den Betrieb der Mailingliste empfiehlt sich das Anlegen eines eigenen Users für diesen Zweck mit hsadmin.&lt;br /&gt;
&lt;br /&gt;
In dieser Anleitung heißt das Paket &#039;&#039;xyz00&#039;&#039; und der für Mailinglisten eingesetzte User &#039;&#039;xyz00-list&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
Die E-Mail-Adresse der einzurichtende Mailing-Liste soll &#039;&#039;discuss@example.org&#039;&#039; sein. Den lokalen Teil dieser Adresse, &#039;&#039;discuss&#039;&#039;, ist der Listenname. Der Listenname darf auf keinen Fall das Plus-Zeichen (+) enthalten, weil dies ein Sonderbedeutung für die Listensteuerung hat: &#039;&#039;mlmmj&#039;&#039; wird nämlich Befehle der Abonnenten über erweiterte Adressen annehmen, wie z.B. &#039;&#039;discuss+help@example.org&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
Die Domain &#039;&#039;example.org&#039;&#039; muss dazu bei einem beliebigen User im Paket &#039;&#039;xyz00&#039;&#039; [[aufgeschaltet]] sein. (&amp;quot;Aufgeschaltet&amp;quot; bedeutet, daß diese Domain bei Hostsharing gehostet wird und der Domainname als Verzeichnis /home/pacs/xyz00/*User*/doms/example.org/ erscheint.)&lt;br /&gt;
&lt;br /&gt;
== Einrichtung ==&lt;br /&gt;
&lt;br /&gt;
Ich melde mich über SSH auf der Hostsharing-Console als der Paketuser &#039;&#039;xyz00&#039;&#039; an.&lt;br /&gt;
&lt;br /&gt;
Im Shell kann ich dann durch den Befehl &#039;&#039;hsscript -i&#039;&#039; das Verwaltungswerkzeug [[hsadmin]] interaktiv ausführen:&lt;br /&gt;
&lt;br /&gt;
  xyz00@h03:~$ hsscript -i&lt;br /&gt;
  Password: *************&lt;br /&gt;
  xyz00@hsadmin&amp;gt; &lt;br /&gt;
&lt;br /&gt;
In &#039;&#039;hsadmin&#039;&#039; werden User und E-Mail-Adresse angelegt.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=shell&amp;gt;&lt;br /&gt;
xyz00@hsadmin&amp;gt; user.add({set:{name:&#039;xyz00-list&#039;,comment:&#039;Mailingliste Discuss&#039;,shell:&#039;/bin/bash&#039;,password:&#039;geheimnis&#039;}})&lt;br /&gt;
xyz00@hsadmin&amp;gt; emailaddress.add({set:{target:&#039;xyz00-list&#039;,localpart:&#039;discuss&#039;,domain:&#039;example.org&#039;}})&lt;br /&gt;
xyz00@hsadmin&amp;gt; bye&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Mit dem Parameter &amp;quot;target&amp;quot; wird die für diese Adresse eingehende Post zunächst in das Postfach des Users xyz00-list abgelegt.&lt;br /&gt;
&lt;br /&gt;
Für den User xyz00-list lege ich in seinem Heimat-Verzeichnis das Unterverzeichnis &amp;lt;tt&amp;gt;mlmmj&amp;lt;/tt&amp;gt; an:&lt;br /&gt;
&lt;br /&gt;
  mkdir /home/pacs/xyz00/users/list/mlmmj&lt;br /&gt;
&lt;br /&gt;
Dann lege ich die Mailingliste mit folgendem Kommando an:&lt;br /&gt;
&lt;br /&gt;
  mlmmj-make-ml -L discuss -s /home/pacs/xyz00/users/list/mlmmj&lt;br /&gt;
&lt;br /&gt;
Das Skript &#039;&#039;mlmmj-make-ml&#039;&#039; fragt weitere Parameter der Mailingliste ab:&lt;br /&gt;
&lt;br /&gt;
  The Domain for the List? [] : example.org&lt;br /&gt;
  The emailaddress of the list owner? [postmaster] : webmaster@example.org&lt;br /&gt;
  For the list texts you can choose between the following languages or&lt;br /&gt;
  give an absolute path to a directory containing the texts.&lt;br /&gt;
  Available languages:&lt;br /&gt;
  cz  da	de  en	es  fr	it  nl	ru&lt;br /&gt;
  The path to texts for the list? [en] : de&lt;br /&gt;
&lt;br /&gt;
Das skript &#039;&#039;mlmmj-make-ml&#039;&#039; legt daraufhin unter &amp;quot;/home/pacs/xyz00/users/list/mlmmj&amp;quot; ein Verzeichnis &amp;quot;discuss&amp;quot; an, das die Datenstruktur zur Verwaltung der Mailingliste enthält.&lt;br /&gt;
&lt;br /&gt;
Weitere Konfigurationen der Liste erfolgen durch das Anlegen von Dateien im&lt;br /&gt;
Verzeichnis &amp;quot;/home/pacs/xyz00/users/list/mlmmj/discuss/control&amp;quot;.&lt;br /&gt;
Die Konfigurationsmöglichkeiten finden Sie auf der [http://mlmmj.org/docs/tunables/ Internetseite von mlmmj].&lt;br /&gt;
&lt;br /&gt;
Damit mlmmj die Verteilung der Post übernimmt, muß ich im Heimat-Verzeichnis des users xyz00-list die Datei &amp;lt;tt&amp;gt;.forward&amp;lt;/tt&amp;gt; mit folgenden Inhalt (INKLUSIVE der Anführungszeichen!) erstellen:&lt;br /&gt;
&lt;br /&gt;
  &amp;quot;|/usr/bin/mlmmj-recieve -L /home/pacs/xyz00/users/list/mlmmj/discuss/&amp;quot;&lt;br /&gt;
&lt;br /&gt;
(Ja, &#039;&#039;receive&#039;&#039; schreibt sich mit &#039;&#039;-ei-&#039;&#039;, aber mlmmj hält einen symbolischen Link bereit für diejenigen, die in englischer Rechtschreibung unsicher sind:)&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=shell&amp;gt;&lt;br /&gt;
xyz00-list@h03:~$ ls -la /usr/bin/mlmmj-rec*&lt;br /&gt;
-rwxr-xr-x 1 root root 27104 Sep 25  2018 /usr/bin/mlmmj-receive&lt;br /&gt;
lrwxrwxrwx 1 root root    13 Sep 25  2018 /usr/bin/mlmmj-recieve -&amp;gt; mlmmj-receive&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Die &amp;lt;tt&amp;gt;.forward&amp;lt;/tt&amp;gt;-Datei sorgt dafür, dass eingehende E-Mails an das User-Postfach an das Programm &#039;&#039;mlmmj-recieve&#039;&#039; übergeben werden.&lt;br /&gt;
&lt;br /&gt;
Für regelmäßige Aufgaben der Listen-Managers definiere ich die&lt;br /&gt;
[[Cron|crontab]] wie folgt (immer noch als &#039;&#039;xyz00-list&#039;&#039;):&lt;br /&gt;
&lt;br /&gt;
  xyz00-list@h03:~$ crontab -e&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=shell line&amp;gt;&lt;br /&gt;
MAILTO=webmaster@example.org&lt;br /&gt;
PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/X11R6/bin&lt;br /&gt;
HOME=/home/pacs/xyz00/users/list&lt;br /&gt;
SHELL=/bin/bash&lt;br /&gt;
LANG=en_US.UTF-8&lt;br /&gt;
# m h  dom mon dow   command&lt;br /&gt;
28 */4 * * * /usr/bin/mlmmj-maintd -d /home/pacs/xyz00/users/list/mlmmj -F&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Zum Schluss rufe ich das Skript mlmmj-sub auf, um die E-Mail-Adressen der gewünschten Abonnenten des Verteilers einzutragen:&lt;br /&gt;
&lt;br /&gt;
 /usr/bin/mlmmj-sub -L /home/pacs/xyz00/users/list/mlmmj/discuss -a klaus.muster@gmx.de -c &lt;br /&gt;
 /usr/bin/mlmmj-sub -L /home/pacs/xyz00/users/list/mlmmj/discuss -a sabine.beispiel@arcor.de -c &lt;br /&gt;
&lt;br /&gt;
Dabei bewirkt &amp;quot;-c&amp;quot;, dass der Abonnent eine Begrüßungs-Nachricht erhält. Alternativ kann man &amp;quot;-C&amp;quot; (großes C) angeben: dann muss der Abonnent das Abo durch Antworten auf die Nachricht bestätigen.&lt;br /&gt;
&lt;br /&gt;
== weitere Optionen  ==&lt;br /&gt;
&lt;br /&gt;
Noch ein paar Dinge, die Sie möglicherweise einstellen wollen:&lt;br /&gt;
&lt;br /&gt;
Ein Prefix in der Betreffzeile setzen, z.B.: &amp;quot;[discuss]&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
 echo &amp;quot;[discuss]&amp;quot; &amp;gt; /home/pacs/xyz00/users/list/mlmmj/discuss/control/prefix&lt;br /&gt;
&lt;br /&gt;
Wenn die Liste nur E-Mails von eingetragenen Abonnenten weiterleiten soll:&lt;br /&gt;
&lt;br /&gt;
 touch /home/pacs/xyz00/users/list/mlmmj/discuss/control/subonlypost&lt;br /&gt;
&lt;br /&gt;
Damit der Listen-Owner weitere Abonnements bestätigen muss:&lt;br /&gt;
&lt;br /&gt;
 touch /home/pacs/xyz00/users/list/mlmmj/discuss/control/submod&lt;br /&gt;
&lt;br /&gt;
Einen &amp;quot;Reply-To:&amp;quot;-Header setzen, damit Antwort-Mails standardmäßig an die Mailing-Liste gehen:&lt;br /&gt;
&lt;br /&gt;
  echo &amp;quot;Reply-To:&amp;quot; &amp;gt; /home/pacs/xyz00/users/list/mlmmj/discuss/control/delheaders&lt;br /&gt;
  echo &amp;quot;Reply-To: discuss@example.org&amp;quot; &amp;gt; /home/pacs/xyz00/users/list/mlmmj/discuss/control/customheaders&lt;br /&gt;
&lt;br /&gt;
Weitere Möglichkeiten finden Sie (wie oben bereits angegeben) &lt;br /&gt;
auf der [http://mlmmj.org/docs/tunables/ Internetseite von mlmmj].&lt;br /&gt;
&lt;br /&gt;
=== Achtung: DKIM ===&lt;br /&gt;
&lt;br /&gt;
Mlmmj gibt die Möglichkeit, mit &#039;&#039;&#039;delheaders&#039;&#039;&#039; und &#039;&#039;&#039;customheaders&#039;&#039;&#039; die Header der durchgeleiteten Mail umfangreich zu ändern. Allerdings tragen Mails heute häufig kryptografische Signaturen der sendenden Mailserver. Eine DKIM-Signatur sichert damit in der Regel die Integrität des Body der Mail sowie der Header &#039;&#039;Subject:&#039;&#039;, &#039;&#039;From:&#039;&#039;, &#039;&#039;To:&#039;&#039;, &#039;&#039;Date:&#039;&#039;, &#039;&#039;From&#039;&#039;, und oft auch &#039;&#039;Reply-To:&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
Wird zum Beispiel mit einem Prefix das Subject geändert oder ein Footer angehängt, macht dies die DKIM-Signatur ungültig. Das ist für viele Mailprovider ein Grund die Nachricht abzuweisen.&lt;br /&gt;
&lt;br /&gt;
== Zur Konfiguration im Browser ==&lt;br /&gt;
&lt;br /&gt;
Die Original-Distribution von &#039;&#039;mlmmj&#039;&#039; enthält ein paar einfache PHP- und Perl-Skripte.  Das sind Beispiele für Subscribe-/Unsubscribe-Formulare, ein Admin-Formular zum Eintragen und Löschen von Abonnements und eine Seite mit der gesamten Listen-Konfiguration.&lt;br /&gt;
&lt;br /&gt;
Wer es sich ansehen möchte:&lt;br /&gt;
&lt;br /&gt;
Als Paket-Admin eine Domain aufschalten:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=shell&amp;gt;&lt;br /&gt;
hsscript -u xyz00 -e &amp;quot;domain.add({set:{name:&#039;lists.example.org&#039;,user:&#039;xyz00-list&#039;}})&amp;quot;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Und weiter als &amp;quot;xyz00-list&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
Download der neuesten Version der Sourcen von mlmmj von http://mlmmj.org/downloads/ (noch besser: Download des aktuellen Debian-Pakets von [https://packages.debian.org/bookworm/all/mlmmj-php-web-admin/download debian.org]: da sind einige veraltete PHP-Ausdrücke schon herausgepatcht) und diese in einem temporären Verzeichnis entpacken (mit tar oder dpkg-deb).&lt;br /&gt;
&lt;br /&gt;
Unter &amp;quot;/mlmmj-$versionsnummer/contrib/web/php-admin/&amp;quot;, oder beim .deb-Paket unter &amp;quot;usr/share/mlmmj-...&amp;quot;, findet sich die PHP-Admin-Anwendung. Also ...&lt;br /&gt;
&lt;br /&gt;
* den Inhalt diese Verzeichnisses nach &amp;quot;/home/pacs/xyz00/users/list/doms/lists.example.org/&amp;quot; packen;&lt;br /&gt;
* in &amp;quot;/home/pacs/xyz00/users/list/doms/lists.example.org/conf/config.php&amp;quot; die Variable &amp;quot;$topdir&amp;quot; anpassen;&lt;br /&gt;
* die Dateien aus &amp;quot;/home/pacs/xyz00/users/list/doms/lists.example.org/htdocs/&amp;quot; nach &amp;quot;/home/pacs/xyz00/users/list/doms/lists.example.org/htdocs-ssl/&amp;quot; verschieben;&lt;br /&gt;
* Beim .deb-Paket die config.php, die templates/ und die tunables.pl aus etc/ nach example.org/conf/ verschieben;&lt;br /&gt;
* in &amp;quot;/home/pacs/xyz00/users/list/mlmmj&amp;quot; und in &amp;quot;/home/pacs/xyz00/users/list/doms/lists.example.org/htdocs-ssl/&amp;quot; eine &amp;quot;.htaccess&amp;quot; mit folgendem Inhalt ablegen: &lt;br /&gt;
&amp;lt;syntaxhighlight lang=apache line&amp;gt;&lt;br /&gt;
Require valid-user&lt;br /&gt;
AuthType Basic&lt;br /&gt;
AuthName &amp;quot;mlmmj web-interface&amp;quot;&lt;br /&gt;
AuthUserFile /home/pacs/xyz00/users/list/doms/lists.example.org/etc/htpasswd&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
* Und schließlich die &amp;quot;htpasswd&amp;quot;-Datei anlegen.&lt;br /&gt;
&lt;br /&gt;
 cd /home/pacs/xyz00/users/list/doms/lists.example.org/etc/&lt;br /&gt;
 htpasswd -c htpasswd listadmin&lt;br /&gt;
&lt;br /&gt;
* Ein Passwort angeben.&lt;br /&gt;
&lt;br /&gt;
Nun enthält diese PHP-Anwendung, wenn man sie nicht dem Debian-Paket entnommen hat, leider noch eine Zeile, die schon seit PHP 7 nicht mehr lauffähig ist. Also muß man noch&lt;br /&gt;
&lt;br /&gt;
* in &amp;lt;tt&amp;gt;.../htdocs-ssl/index.php&amp;lt;/tt&amp;gt; folgende Änderung vornehmen:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=diff line&amp;gt;&lt;br /&gt;
@@ -38,4 +38,5 @@&lt;br /&gt;
 # use scandir to have alphabetical order &lt;br /&gt;
 foreach (scandir($topdir) as $file) {&lt;br /&gt;
-    if (!ereg(&amp;quot;^\.&amp;quot;,$file))&lt;br /&gt;
+# ereg obsolete!! Vormals:    if (!ereg(&amp;quot;^\.&amp;quot;,$file))&lt;br /&gt;
+    if (!preg_match(&#039;/^\./&#039;,$file))&lt;br /&gt;
     {&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
und das Ergebnis auf https://lists.example.org anschauen.&lt;br /&gt;
&lt;br /&gt;
== Mehrere Mailinglisten betreiben ==&lt;br /&gt;
&lt;br /&gt;
Wenn mehrere Mailinglisten in einem Account und mit einer Admin-Oberfläche betrieben werden soll, empfiehlt sich die Nutzung von Procmail für den Aufruf von &#039;&#039;mlmmj&#039;&#039; für die jeweiligen Liste mit ihrem Daten-Verzeichnis.&lt;br /&gt;
&lt;br /&gt;
Dazu trägt man in der Datei &amp;lt;tt&amp;gt;.forward&amp;lt;/tt&amp;gt; statt des Aufrufs von &#039;&#039;mlmmj-recieve&#039;&#039; einen Aufruf von &#039;&#039;procmail&#039;&#039; ein:&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
 |/usr/bin/procmail&lt;br /&gt;
&lt;br /&gt;
Die Konfiguration von Procmail kann generisch erfolgen. Dazu legt man eine Datei &amp;lt;tt&amp;gt;.procmailrc&amp;lt;/tt&amp;gt; mit folgendem Inhalt ins $HOME des Users:&lt;br /&gt;
&lt;br /&gt;
 SHELL=/bin/sh&lt;br /&gt;
 HOMEDIR=/home/pacs/xyz00/users/list&lt;br /&gt;
 MAILDIR=/home/pacs/xyz00/users/list/Maildir&lt;br /&gt;
 PMDIR=/home/pacs/xyz00/users/list&lt;br /&gt;
 VERBOSE=yes&lt;br /&gt;
 LOGFILE=/home/pacs/xyz00/users/list/var/procmail.log&lt;br /&gt;
 DEFAULT&lt;br /&gt;
 &lt;br /&gt;
 :0:&lt;br /&gt;
 * ^X-Original-To: ()\/[^@+]+&lt;br /&gt;
 |/usr/bin/mlmmj-receive -F -L /home/pacs/xyz00/users/list/mlmmj/${MATCH}/&lt;br /&gt;
 &lt;br /&gt;
 :0&lt;br /&gt;
 { EXITCODE 67 }&lt;br /&gt;
&lt;br /&gt;
Bitte dafür sorgen, dass das Verzeichnis &#039;&#039;/home/pacs/xyz00/users/list/var&#039;&#039; existiert.&lt;br /&gt;
&lt;br /&gt;
Der kryptische reguläre Ausdruck hinter dem Header &#039;&#039;X-Original-To:&#039;&#039; passt auf den Beginn der E-Mail-Adresse bis zum ersten &#039;&#039;@&#039;&#039;- oder &#039;&#039;+&#039;&#039;-Zeichen. In der Variable &#039;&#039;MATCH&#039;&#039; steht also der Name der Mailingliste, d.h. der Name der Verzeichnisses, in dem die Liste verwaltet wird.&lt;br /&gt;
&lt;br /&gt;
Sehr wichtig ist die Zeile &#039;&#039;DEFAULT&#039;&#039; zu Beginn der &#039;&#039;.procmailrc&#039;&#039;. Die Variable &#039;&#039;DEFAULT&#039;&#039; wird von &#039;&#039;procmail&#039;&#039; gesetzt. Wir sorgen mit dieser Zeile dafür, dass sie wieder undefiniert ist. Diese Variable wird intern von &#039;&#039;mlmmj&#039;&#039; benutzt, wenn sie gesetzt ist. Das führt in Kombination mit &#039;&#039;procmail&#039;&#039; zu Fehlfunktionen (vgl. Links).&lt;br /&gt;
&lt;br /&gt;
===Groß- und Kleinschreibung===&lt;br /&gt;
&lt;br /&gt;
Achtung, mit der Groß- und Kleinschreibung von Listennamen gibt es bei dieser Procmail-Lösung eine kleine Tücke. Procmail übernimmt in die Variable $MATCH genau die in der X-Original-To-Headerzeile vorgefundene Schreibweise, und diese kann denkbarerweise &amp;quot;Listen-Name&amp;quot; oder &amp;quot;listen-name&amp;quot; oder &amp;quot;Listen-name&amp;quot; sein. &amp;lt;tt&amp;gt;mlmmj&amp;lt;/tt&amp;gt; hingegen wird diesen Wert in Unix-Manier mit dem genauen Verzeichnisnamen &amp;lt;tt&amp;gt;${HOME}/mlmmj/listen-name&amp;lt;/tt&amp;gt; vergleichen, und bei unterschiedlicher Schreibweise die Mail nicht verteilen.&lt;br /&gt;
&lt;br /&gt;
====Lösung 1====&lt;br /&gt;
&lt;br /&gt;
Eine teilweise Lösung besteht darin, den Listennamen in dem &amp;lt;tt&amp;gt;mlmmj&amp;lt;/tt&amp;gt;-Aufruf in der &amp;lt;tt&amp;gt;.procmailrc&amp;lt;/tt&amp;gt; in Kleinbuchstaben umzuschreiben. Dann lautet das Rezept so:&lt;br /&gt;
&lt;br /&gt;
 :0:&lt;br /&gt;
 * ^X-Original-To: ()\/[^@+]+&lt;br /&gt;
 |/usr/bin/mlmmj-receive -F -L /home/pacs/xyz00/users/list/mlmmj/$(echo ${MATCH} | tr [:upper:] [:lower:])/&lt;br /&gt;
&lt;br /&gt;
Der Rest der Datei muß gleich bleiben, wie weiter oben angezeigt.&lt;br /&gt;
&lt;br /&gt;
In diesem Fall müssen aber alle Mailing-Listen ohne Großbuchstaben im Namen angelegt werden!&lt;br /&gt;
&lt;br /&gt;
(Man kann auch in &amp;lt;tt&amp;gt;${HOME}/mlmmj/&amp;lt;/tt&amp;gt; durch kleingeschriebene Symlinks großgeschriebene Listennamen ansprechbar machen:&lt;br /&gt;
&lt;br /&gt;
  xyz00-list@h02:~$ ls -lA mlmmj/&lt;br /&gt;
  total 8&lt;br /&gt;
  -rw-r--r--  1 xyz00-list xyz00  148 Feb  1 16:56 .htaccess&lt;br /&gt;
  lrwxrwxrwx  1 xyz00-list xyz00   10 Feb  2 18:01 mitglieder -&amp;gt; Mitglieder&lt;br /&gt;
  drwxr-xr-x 15 xyz00-list xyz00 4096 Feb  2 16:53 Mitglieder&lt;br /&gt;
&lt;br /&gt;
====Lösung 2====&lt;br /&gt;
&lt;br /&gt;
Bash kann bei der Auflösung von Variablen die Groß- und Kleinschreibung manipulieren. (Siehe dazu bei der Zeichenfolge &amp;lt;tt&amp;gt;,,&amp;lt;/tt&amp;gt; in &amp;lt;tt&amp;gt;man bash&amp;lt;/tt&amp;gt;.) Dann ist &amp;lt;tt&amp;gt;$(echo ${MATCH} | tr [:upper:] [:lower:])&amp;lt;/tt&amp;gt; gleichbedeutend mit &amp;lt;tt&amp;gt;${MATCH,,}&amp;lt;/tt&amp;gt;. Allerdings braucht procmail einige Überredung, um Bash zu verwenden.&lt;br /&gt;
&lt;br /&gt;
 SHELL=/bin/bash&lt;br /&gt;
 SHELLMETAS=&amp;amp;|&amp;lt;&amp;gt;~;?*[{&lt;br /&gt;
 HOMEDIR= ...&lt;br /&gt;
&lt;br /&gt;
...&lt;br /&gt;
&lt;br /&gt;
 :0:&lt;br /&gt;
 * ^X-Original-To: ()\/[^@+]+&lt;br /&gt;
 |/usr/bin/mlmmj-receive -F -L /home/pacs/xyz00/users/list/mlmmj/${MATCH,,}/&lt;br /&gt;
 &lt;br /&gt;
Die Tücke ist, daß procmail den in SHELL angegebenen Shell nur dann verwendet, wenn die Befehlszeile eines der in SHELLMETAS angegebenen Zeichen enthält. Und das &#039;|&#039; am Anfang der Zeile zählt dabei nicht! In diesem Beispiel ist es das Zeichen &amp;lt;tt&amp;gt;{&amp;lt;/tt&amp;gt;, das den Einsatz von Bash auslöst.&lt;br /&gt;
&lt;br /&gt;
Beide Lösungen scheinen zu funktionieren; Angabe ohne Gewähr.&lt;br /&gt;
&lt;br /&gt;
== Links ==&lt;br /&gt;
&lt;br /&gt;
* http://mlmmj.org/ Projektseite&lt;br /&gt;
* https://codeberg.org/mlmmj mlmmj auf Codeberg&lt;br /&gt;
* https://github.com/tchapi/mlmmj-simple-web-interface ein Admin-Interface in NodeJS&lt;br /&gt;
* [https://web.archive.org/web/20221228110514/https://www.tablix.org/~avian/blog/archives/2010/04/the_faulty_default/ https://www.tablix.org/~avian/blog/archives/2010/04/the_faulty_default/ (via web.archive.org)] Nutzung von mlmmj in Verbindung mit Procmail&lt;br /&gt;
* [https://gist.github.com/kboss/7c9593f0fd9219406226c4f11256b98a Einfaches Python-Script zum Massenimport aus einem Texfile.] Geht bestimmt auch eleganter mit purem Bash&lt;br /&gt;
* Ein Self-Service zum Subscriben/Unsubscriben lässt sich in Form von Mail-to-Links in Webseiten einbinden. Beispiele gibt es bei Hostsharing für die öffentlichen &amp;quot;public&amp;quot;-Mailinglisten: https://www.hostsharing.net/lists/public-discussion/ . Alternativ auf https://github.com/hblasum/mlmmj-php-web-simplified ein Webfrontend mit dem sich Benutzerinnen und Benutzer selbst ein-/austragen können (Vereinfachung von mlmmj-php-web von Christoph Thiel).&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
[[Kategorie:HSDoku]]&lt;br /&gt;
[[Kategorie:Installationsanleitungen]]&lt;br /&gt;
[[Kategorie:Software]]&lt;br /&gt;
[[Kategorie:Mailinglisten]]&lt;br /&gt;
[[Kategorie:E-Mail]]&lt;/div&gt;</summary>
		<author><name>Apc00-tony</name></author>
	</entry>
	<entry>
		<id>https://wiki.hostsharing.net/index.php?title=Mlmmj&amp;diff=6660</id>
		<title>Mlmmj</title>
		<link rel="alternate" type="text/html" href="https://wiki.hostsharing.net/index.php?title=Mlmmj&amp;diff=6660"/>
		<updated>2024-05-31T14:33:40Z</updated>

		<summary type="html">&lt;p&gt;Apc00-tony: /* Lösung 2 */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[http://www.mlmmj.org/ mlmmj], angeblich eine Abkürzung für &amp;quot;Mailing List Management Made Joyful&amp;quot;, ist ein Programm, mit dem in einem Hostsharing Paket E-Mail-Verteiler realisiert werden kann.&lt;br /&gt;
&lt;br /&gt;
Wer noch nicht weiß, was ein E-Mail-Verteiler machen soll oder wie, lese veilleicht auch den Wikipedia-Artikel:&lt;br /&gt;
[http://de.wikipedia.org/wiki/Mailingliste Mailingliste]&lt;br /&gt;
&lt;br /&gt;
Eine leistungsfähigere Alternative zu mlmmj könnte [[Mailman_3_installieren|Mailman 3]] sein.&lt;br /&gt;
&lt;br /&gt;
Diese Anleitung beschreibt die Einrichtung einer Mailingliste für eine Domain in einem Hostsharing-Webspace.&lt;br /&gt;
&lt;br /&gt;
== Voraussetzungen  ==&lt;br /&gt;
&lt;br /&gt;
Das Debian Paket [http://packages.debian.org/search?keywords=mlmmj mlmmj] ist auf den Shared-Hosting-Servern bereits installiert. (Wer die Software selbst kompilieren möchte kann aktuellen Source-Code bei [https://codeberg.org/mlmmj/mlmmj|codeberg.org] finden.)&lt;br /&gt;
&lt;br /&gt;
Für den Betrieb der Mailingliste empfiehlt sich das Anlegen eines eigenen Users für diesen Zweck mit hsadmin.&lt;br /&gt;
&lt;br /&gt;
In dieser Anleitung heißt das Paket &#039;&#039;xyz00&#039;&#039; und der für Mailinglisten eingesetzte User &#039;&#039;xyz00-list&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
Die E-Mail-Adresse der einzurichtende Mailing-Liste soll &#039;&#039;discuss@example.org&#039;&#039; sein. Den lokalen Teil dieser Adresse, &#039;&#039;discuss&#039;&#039;, ist der Listenname. Der Listenname darf auf keinen Fall das Plus-Zeichen (+) enthalten, weil dies ein Sonderbedeutung für die Listensteuerung hat: &#039;&#039;mlmmj&#039;&#039; wird nämlich Befehle der Abonnenten über erweiterte Adressen annehmen, wie z.B. &#039;&#039;discuss+help@example.org&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
Die Domain &#039;&#039;example.org&#039;&#039; muss dazu bei einem beliebigen User im Paket &#039;&#039;xyz00&#039;&#039; [[aufgeschaltet]] sein. (&amp;quot;Aufgeschaltet&amp;quot; bedeutet, daß diese Domain bei Hostsharing gehostet wird und der Domainname als Verzeichnis /home/pacs/xyz00/*User*/doms/example.org/ erscheint.)&lt;br /&gt;
&lt;br /&gt;
== Einrichtung ==&lt;br /&gt;
&lt;br /&gt;
Ich melde mich über SSH auf der Hostsharing-Console als der Paketuser &#039;&#039;xyz00&#039;&#039; an.&lt;br /&gt;
&lt;br /&gt;
Im Shell kann ich dann durch den Befehl &#039;&#039;hsscript -i&#039;&#039; das Verwaltungswerkzeug [[hsadmin]] interaktiv ausführen:&lt;br /&gt;
&lt;br /&gt;
  xyz00@h03:~$ hsscript -i&lt;br /&gt;
  Password: *************&lt;br /&gt;
  xyz00@hsadmin&amp;gt; &lt;br /&gt;
&lt;br /&gt;
In &#039;&#039;hsadmin&#039;&#039; werden User und E-Mail-Adresse angelegt.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=shell&amp;gt;&lt;br /&gt;
xyz00@hsadmin&amp;gt; user.add({set:{name:&#039;xyz00-list&#039;,comment:&#039;Mailingliste Discuss&#039;,shell:&#039;/bin/bash&#039;,password:&#039;geheimnis&#039;}})&lt;br /&gt;
xyz00@hsadmin&amp;gt; emailaddress.add({set:{target:&#039;xyz00-list&#039;,localpart:&#039;discuss&#039;,domain:&#039;example.org&#039;}})&lt;br /&gt;
xyz00@hsadmin&amp;gt; bye&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Mit dem Parameter &amp;quot;target&amp;quot; wird die für diese Adresse eingehende Post zunächst in das Postfach des Users xyz00-list abgelegt.&lt;br /&gt;
&lt;br /&gt;
Für den User xyz00-list lege ich in seinem Heimat-Verzeichnis das Unterverzeichnis &amp;lt;tt&amp;gt;mlmmj&amp;lt;/tt&amp;gt; an:&lt;br /&gt;
&lt;br /&gt;
  mkdir /home/pacs/xyz00/users/list/mlmmj&lt;br /&gt;
&lt;br /&gt;
Dann lege ich die Mailingliste mit folgendem Kommando an:&lt;br /&gt;
&lt;br /&gt;
  mlmmj-make-ml -L discuss -s /home/pacs/xyz00/users/list/mlmmj&lt;br /&gt;
&lt;br /&gt;
Das Skript &#039;&#039;mlmmj-make-ml&#039;&#039; fragt weitere Parameter der Mailingliste ab:&lt;br /&gt;
&lt;br /&gt;
  The Domain for the List? [] : example.org&lt;br /&gt;
  The emailaddress of the list owner? [postmaster] : webmaster@example.org&lt;br /&gt;
  For the list texts you can choose between the following languages or&lt;br /&gt;
  give an absolute path to a directory containing the texts.&lt;br /&gt;
  Available languages:&lt;br /&gt;
  cz  da	de  en	es  fr	it  nl	ru&lt;br /&gt;
  The path to texts for the list? [en] : de&lt;br /&gt;
&lt;br /&gt;
Das skript &#039;&#039;mlmmj-make-ml&#039;&#039; legt daraufhin unter &amp;quot;/home/pacs/xyz00/users/list/mlmmj&amp;quot; ein Verzeichnis &amp;quot;discuss&amp;quot; an, das die Datenstruktur zur Verwaltung der Mailingliste enthält.&lt;br /&gt;
&lt;br /&gt;
Weitere Konfigurationen der Liste erfolgen durch das Anlegen von Dateien im&lt;br /&gt;
Verzeichnis &amp;quot;/home/pacs/xyz00/users/list/mlmmj/discuss/control&amp;quot;.&lt;br /&gt;
Die Konfigurationsmöglichkeiten finden Sie auf der [http://mlmmj.org/docs/tunables/ Internetseite von mlmmj].&lt;br /&gt;
&lt;br /&gt;
Damit mlmmj die Verteilung der Post übernimmt, muß ich im Heimat-Verzeichnis des users xyz00-list die Datei &amp;lt;tt&amp;gt;.forward&amp;lt;/tt&amp;gt; mit folgenden Inhalt (INKLUSIVE der Anführungszeichen!) erstellen:&lt;br /&gt;
&lt;br /&gt;
  &amp;quot;|/usr/bin/mlmmj-recieve -L /home/pacs/xyz00/users/list/mlmmj/discuss/&amp;quot;&lt;br /&gt;
&lt;br /&gt;
(Ja, &#039;&#039;receive&#039;&#039; schreibt sich mit &#039;&#039;-ei-&#039;&#039;, aber mlmmj hält einen symbolischen Link bereit für diejenigen, die in englischer Rechtschreibung unsicher sind:)&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=shell&amp;gt;&lt;br /&gt;
xyz00-list@h03:~$ ls -la /usr/bin/mlmmj-rec*&lt;br /&gt;
-rwxr-xr-x 1 root root 27104 Sep 25  2018 /usr/bin/mlmmj-receive&lt;br /&gt;
lrwxrwxrwx 1 root root    13 Sep 25  2018 /usr/bin/mlmmj-recieve -&amp;gt; mlmmj-receive&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Die &amp;lt;tt&amp;gt;.forward&amp;lt;/tt&amp;gt;-Datei sorgt dafür, dass eingehende E-Mails an das User-Postfach an das Programm &#039;&#039;mlmmj-recieve&#039;&#039; übergeben werden.&lt;br /&gt;
&lt;br /&gt;
Für regelmäßige Aufgaben der Listen-Managers definiere ich die&lt;br /&gt;
[[Cron|crontab]] wie folgt (immer noch als &#039;&#039;xyz00-list&#039;&#039;):&lt;br /&gt;
&lt;br /&gt;
  xyz00-list@h03:~$ crontab -e&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=shell line&amp;gt;&lt;br /&gt;
MAILTO=webmaster@example.org&lt;br /&gt;
PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/X11R6/bin&lt;br /&gt;
HOME=/home/pacs/xyz00/users/list&lt;br /&gt;
SHELL=/bin/bash&lt;br /&gt;
LANG=en_US.UTF-8&lt;br /&gt;
# m h  dom mon dow   command&lt;br /&gt;
28 */4 * * * /usr/bin/mlmmj-maintd -d /home/pacs/xyz00/users/list/mlmmj -F&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Zum Schluss rufe ich das Skript mlmmj-sub auf, um die E-Mail-Adressen der gewünschten Abonnenten des Verteilers einzutragen:&lt;br /&gt;
&lt;br /&gt;
 /usr/bin/mlmmj-sub -L /home/pacs/xyz00/users/list/mlmmj/discuss -a klaus.muster@gmx.de -c &lt;br /&gt;
 /usr/bin/mlmmj-sub -L /home/pacs/xyz00/users/list/mlmmj/discuss -a sabine.beispiel@arcor.de -c &lt;br /&gt;
&lt;br /&gt;
Dabei bewirkt &amp;quot;-c&amp;quot;, dass der Abonnent eine Begrüßungs-Nachricht erhält. Alternativ kann man &amp;quot;-C&amp;quot; (großes C) angeben: dann muss der Abonnent das Abo durch Antworten auf die Nachricht bestätigen.&lt;br /&gt;
&lt;br /&gt;
== weitere Optionen  ==&lt;br /&gt;
&lt;br /&gt;
Noch ein paar Dinge, die Sie möglicherweise einstellen wollen:&lt;br /&gt;
&lt;br /&gt;
Ein Prefix in der Betreffzeile setzen, z.B.: &amp;quot;[discuss]&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
 echo &amp;quot;[discuss]&amp;quot; &amp;gt; /home/pacs/xyz00/users/list/mlmmj/discuss/control/prefix&lt;br /&gt;
&lt;br /&gt;
Wenn die Liste nur E-Mails von eingetragenen Abonnenten weiterleiten soll:&lt;br /&gt;
&lt;br /&gt;
 touch /home/pacs/xyz00/users/list/mlmmj/discuss/control/subonlypost&lt;br /&gt;
&lt;br /&gt;
Damit der Listen-Owner weitere Abonnements bestätigen muss:&lt;br /&gt;
&lt;br /&gt;
 touch /home/pacs/xyz00/users/list/mlmmj/discuss/control/submod&lt;br /&gt;
&lt;br /&gt;
Einen &amp;quot;Reply-To:&amp;quot;-Header setzen, damit Antwort-Mails standardmäßig an die Mailing-Liste gehen:&lt;br /&gt;
&lt;br /&gt;
  echo &amp;quot;Reply-To:&amp;quot; &amp;gt; /home/pacs/xyz00/users/list/mlmmj/discuss/control/delheaders&lt;br /&gt;
  echo &amp;quot;Reply-To: discuss@example.org&amp;quot; &amp;gt; /home/pacs/xyz00/users/list/mlmmj/discuss/control/customheaders&lt;br /&gt;
&lt;br /&gt;
Weitere Möglichkeiten finden Sie (wie oben bereits angegeben) &lt;br /&gt;
auf der [http://mlmmj.org/docs/tunables/ Internetseite von mlmmj].&lt;br /&gt;
&lt;br /&gt;
=== Achtung: DKIM ===&lt;br /&gt;
&lt;br /&gt;
Mlmmj gibt die Möglichkeit, mit &#039;&#039;&#039;delheaders&#039;&#039;&#039; und &#039;&#039;&#039;customheaders&#039;&#039;&#039; die Header der durchgeleiteten Mail umfangreich zu ändern. Allerdings tragen Mails heute häufig kryptografische Signaturen der sendenden Mailserver. Eine DKIM-Signatur sichert damit in der Regel die Integrität des Body der Mail sowie der Header &#039;&#039;Subject:&#039;&#039;, &#039;&#039;From:&#039;&#039;, &#039;&#039;To:&#039;&#039;, &#039;&#039;Date:&#039;&#039;, &#039;&#039;From&#039;&#039;, und oft auch &#039;&#039;Reply-To:&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
Wird zum Beispiel mit einem Prefix das Subject geändert oder ein Footer angehängt, macht dies die DKIM-Signatur ungültig. Das ist für viele Mailprovider ein Grund die Nachricht abzuweisen.&lt;br /&gt;
&lt;br /&gt;
== Zur Konfiguration im Browser ==&lt;br /&gt;
&lt;br /&gt;
Die Original-Distribution von &#039;&#039;mlmmj&#039;&#039; enthält ein paar einfache PHP- und Perl-Skripte.  Das sind Beispiele für Subscribe-/Unsubscribe-Formulare, ein Admin-Formular zum Eintragen und Löschen von Abonnements und eine Seite mit der gesamten Listen-Konfiguration.&lt;br /&gt;
&lt;br /&gt;
Wer es sich ansehen möchte:&lt;br /&gt;
&lt;br /&gt;
Als Paket-Admin eine Domain aufschalten:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=shell&amp;gt;&lt;br /&gt;
hsscript -u xyz00 -e &amp;quot;domain.add({set:{name:&#039;lists.example.org&#039;,user:&#039;xyz00-list&#039;}})&amp;quot;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Und weiter als &amp;quot;xyz00-list&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
Download der neuesten Version der Sourcen von mlmmj von http://mlmmj.org/downloads/ (noch besser: Download des aktuellen Debian-Pakets von [https://packages.debian.org/bookworm/all/mlmmj-php-web-admin/download debian.org]: da sind einige veraltete PHP-Ausdrücke schon herausgepatcht) und diese in einem temporären Verzeichnis entpacken (mit tar oder dpkg-deb).&lt;br /&gt;
&lt;br /&gt;
Unter &amp;quot;/mlmmj-$versionsnummer/contrib/web/php-admin/&amp;quot;, oder beim .deb-Paket unter &amp;quot;usr/share/mlmmj-...&amp;quot;, findet sich die PHP-Admin-Anwendung. Also ...&lt;br /&gt;
&lt;br /&gt;
* den Inhalt diese Verzeichnisses nach &amp;quot;/home/pacs/xyz00/users/list/doms/lists.example.org/&amp;quot; packen;&lt;br /&gt;
* in &amp;quot;/home/pacs/xyz00/users/list/doms/lists.example.org/conf/config.php&amp;quot; die Variable &amp;quot;$topdir&amp;quot; anpassen;&lt;br /&gt;
* die Dateien aus &amp;quot;/home/pacs/xyz00/users/list/doms/lists.example.org/htdocs/&amp;quot; nach &amp;quot;/home/pacs/xyz00/users/list/doms/lists.example.org/htdocs-ssl/&amp;quot; verschieben;&lt;br /&gt;
* Beim .deb-Paket die config.php, die templates/ und die tunables.pl aus etc/ nach example.org/conf/ verschieben;&lt;br /&gt;
* in &amp;quot;/home/pacs/xyz00/users/list/mlmmj&amp;quot; und in &amp;quot;/home/pacs/xyz00/users/list/doms/lists.example.org/htdocs-ssl/&amp;quot; eine &amp;quot;.htaccess&amp;quot; mit folgendem Inhalt ablegen: &lt;br /&gt;
&amp;lt;syntaxhighlight lang=apache line&amp;gt;&lt;br /&gt;
Require valid-user&lt;br /&gt;
AuthType Basic&lt;br /&gt;
AuthName &amp;quot;mlmmj web-interface&amp;quot;&lt;br /&gt;
AuthUserFile /home/pacs/xyz00/users/list/doms/lists.example.org/etc/htpasswd&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
* Und schließlich die &amp;quot;htpasswd&amp;quot;-Datei anlegen.&lt;br /&gt;
&lt;br /&gt;
 cd /home/pacs/xyz00/users/list/doms/lists.example.org/etc/&lt;br /&gt;
 htpasswd -c htpasswd listadmin&lt;br /&gt;
&lt;br /&gt;
* Ein Passwort angeben.&lt;br /&gt;
&lt;br /&gt;
Nun enthält diese PHP-Anwendung, wenn man sie nicht dem Debian-Paket entnommen hat, leider noch eine Zeile, die schon seit PHP 7 nicht mehr lauffähig ist. Also muß man noch&lt;br /&gt;
&lt;br /&gt;
* in &amp;lt;tt&amp;gt;.../htdocs-ssl/index.php&amp;lt;/tt&amp;gt; folgende Änderung vornehmen:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=diff line&amp;gt;&lt;br /&gt;
@@ -38,4 +38,5 @@&lt;br /&gt;
 # use scandir to have alphabetical order &lt;br /&gt;
 foreach (scandir($topdir) as $file) {&lt;br /&gt;
-    if (!ereg(&amp;quot;^\.&amp;quot;,$file))&lt;br /&gt;
+# ereg obsolete!! Vormals:    if (!ereg(&amp;quot;^\.&amp;quot;,$file))&lt;br /&gt;
+    if (!preg_match(&#039;/^\./&#039;,$file))&lt;br /&gt;
     {&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
und das Ergebnis auf https://lists.example.org anschauen.&lt;br /&gt;
&lt;br /&gt;
== Mehrere Mailinglisten betreiben ==&lt;br /&gt;
&lt;br /&gt;
Wenn mehrere Mailinglisten in einem Account und mit einer Admin-Oberfläche betrieben werden soll, empfiehlt sich die Nutzung von Procmail für den Aufruf von &#039;&#039;mlmmj&#039;&#039; für die jeweiligen Liste mit ihrem Daten-Verzeichnis.&lt;br /&gt;
&lt;br /&gt;
Dazu trägt man in der Datei &amp;lt;tt&amp;gt;.forward&amp;lt;/tt&amp;gt; statt des Aufrufs von &#039;&#039;mlmmj-recieve&#039;&#039; einen Aufruf von &#039;&#039;procmail&#039;&#039; ein:&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
 |/usr/bin/procmail&lt;br /&gt;
&lt;br /&gt;
Die Konfiguration von Procmail kann generisch erfolgen. Dazu legt man eine Datei &amp;lt;tt&amp;gt;.procmailrc&amp;lt;/tt&amp;gt; mit folgendem Inhalt ins $HOME des Users:&lt;br /&gt;
&lt;br /&gt;
 SHELL=/bin/sh&lt;br /&gt;
 HOMEDIR=/home/pacs/xyz00/users/list&lt;br /&gt;
 MAILDIR=/home/pacs/xyz00/users/list/Maildir&lt;br /&gt;
 PMDIR=/home/pacs/xyz00/users/list&lt;br /&gt;
 VERBOSE=yes&lt;br /&gt;
 LOGFILE=/home/pacs/xyz00/users/list/var/procmail.log&lt;br /&gt;
 DEFAULT&lt;br /&gt;
 &lt;br /&gt;
 :0:&lt;br /&gt;
 * ^X-Original-To: ()\/[^@+]+&lt;br /&gt;
 |/usr/bin/mlmmj-receive -F -L /home/pacs/xyz00/users/list/mlmmj/${MATCH}/&lt;br /&gt;
 &lt;br /&gt;
 :0&lt;br /&gt;
 { EXITCODE 67 }&lt;br /&gt;
&lt;br /&gt;
Bitte dafür sorgen, dass das Verzeichnis &#039;&#039;/home/pacs/xyz00/users/list/var&#039;&#039; existiert.&lt;br /&gt;
&lt;br /&gt;
Der kryptische reguläre Ausdruck hinter dem Header &#039;&#039;X-Original-To:&#039;&#039; passt auf den Beginn der E-Mail-Adresse bis zum ersten &#039;&#039;@&#039;&#039;- oder &#039;&#039;+&#039;&#039;-Zeichen. In der Variable &#039;&#039;MATCH&#039;&#039; steht also der Name der Mailingliste, d.h. der Name der Verzeichnisses, in dem die Liste verwaltet wird.&lt;br /&gt;
&lt;br /&gt;
Sehr wichtig ist die Zeile &#039;&#039;DEFAULT&#039;&#039; zu Beginn der &#039;&#039;.procmailrc&#039;&#039;. Die Variable &#039;&#039;DEFAULT&#039;&#039; wird von &#039;&#039;procmail&#039;&#039; gesetzt. Wir sorgen mit dieser Zeile dafür, dass sie wieder undefiniert ist. Diese Variable wird intern von &#039;&#039;mlmmj&#039;&#039; benutzt, wenn sie gesetzt ist. Das führt in Kombination mit &#039;&#039;procmail&#039;&#039; zu Fehlfunktionen (vgl. Links).&lt;br /&gt;
&lt;br /&gt;
===Groß- und Kleinschreibung===&lt;br /&gt;
&lt;br /&gt;
Achtung, mit der Groß- und Kleinschreibung von Listennamen gibt es bei dieser Procmail-Lösung eine kleine Tücke. Procmail übernimmt in die Variable $MATCH genau die in der X-Original-To-Headerzeile vorgefundene Schreibweise, und diese kann denkbarerweise &amp;quot;Listen-Name&amp;quot; oder &amp;quot;listen-name&amp;quot; oder &amp;quot;Listen-name&amp;quot; sein. &amp;lt;tt&amp;gt;mlmmj&amp;lt;/tt&amp;gt; hingegen wird diesen Wert in Unix-Manier mit dem genauen Verzeichnisnamen &amp;lt;tt&amp;gt;${HOME}/mlmmj/listen-name&amp;lt;/tt&amp;gt; vergleichen, und bei unterschiedlicher Schreibweise die Mail nicht verteilen.&lt;br /&gt;
&lt;br /&gt;
====Lösung 1====&lt;br /&gt;
&lt;br /&gt;
Eine teilweise Lösung besteht darin, den Listennamen in dem &amp;lt;tt&amp;gt;mlmmj&amp;lt;/tt&amp;gt;-Aufruf in der &amp;lt;tt&amp;gt;.procmailrc&amp;lt;/tt&amp;gt; in Kleinbuchstaben umzuschreiben. Dann lautet das Rezept so:&lt;br /&gt;
&lt;br /&gt;
 :0:&lt;br /&gt;
 * ^X-Original-To: ()\/[^@+]+&lt;br /&gt;
 |/usr/bin/mlmmj-receive -F -L /home/pacs/xyz00/users/list/mlmmj/$(echo ${MATCH} | tr [:upper:] [:lower:])/&lt;br /&gt;
&lt;br /&gt;
Der Rest der Datei muß gleich bleiben, wie weiter oben angezeigt.&lt;br /&gt;
&lt;br /&gt;
In diesem Fall müssen aber alle Mailing-Listen ohne Großbuchstaben im Namen angelegt werden!&lt;br /&gt;
&lt;br /&gt;
(Man kann auch in &amp;lt;tt&amp;gt;${HOME}/mlmmj/&amp;lt;/tt&amp;gt; durch kleingeschriebene Symlinks großgeschriebene Listennamen ansprechbar machen:&lt;br /&gt;
&lt;br /&gt;
  xyz00-list@h02:~$ ls -lA mlmmj/&lt;br /&gt;
  total 8&lt;br /&gt;
  -rw-r--r--  1 xyz00-list xyz00  148 Feb  1 16:56 .htaccess&lt;br /&gt;
  lrwxrwxrwx  1 xyz00-list xyz00   10 Feb  2 18:01 mitglieder -&amp;gt; Mitglieder&lt;br /&gt;
  drwxr-xr-x 15 xyz00-list xyz00 4096 Feb  2 16:53 Mitglieder&lt;br /&gt;
&lt;br /&gt;
====Lösung 2====&lt;br /&gt;
&lt;br /&gt;
Bash kann bei der Auflösung von Variablen die Groß- und Kleinschreibung manipulieren. (Siehe dazu bei der Zeichenfolge &amp;lt;tt&amp;gt;,,&amp;lt;/tt&amp;gt; in &amp;lt;tt&amp;gt;man bash&amp;lt;/tt&amp;gt;.) Dann ist &amp;lt;tt&amp;gt;$(echo ${MATCH} | tr [:upper:] [:lower:])&amp;lt;/tt&amp;gt; gleichbedeutend mit &amp;lt;tt&amp;gt;${MATCH,,}&amp;lt;/tt&amp;gt;. Allerdings braucht procmail einige Überredung, um Bash zu verwenden.&lt;br /&gt;
&lt;br /&gt;
 SHELL=/bin/bash&lt;br /&gt;
 SHELLMETAS=&amp;amp;|&amp;lt;&amp;gt;~;?*[{&lt;br /&gt;
 HOMEDIR= ...&lt;br /&gt;
&lt;br /&gt;
...&lt;br /&gt;
&lt;br /&gt;
 :0:&lt;br /&gt;
 * ^X-Original-To: ()\/[^@+]+&lt;br /&gt;
 |/usr/bin/mlmmj-receive -F -L /home/pacs/xyz00/users/list/mlmmj/${MATCH,,}/&lt;br /&gt;
 &lt;br /&gt;
Die Tücke ist, daß procmail den in SHELL angegebenen Shell nur dann verwendet, wenn in der Befehlszeile eines der in SHELLMETAS angegebenen Zeichen enthält. Und das &#039;|&#039; am Anfang der Zeile zählt dabei nicht! In diesem Beispiel ist es das Zeichen &amp;lt;tt&amp;gt;{&amp;lt;/tt&amp;gt;, das den Einsatz von Bash auslöst.&lt;br /&gt;
&lt;br /&gt;
Beide Lösungen scheinen zu funktionieren; Angabe ohne Gewähr.&lt;br /&gt;
&lt;br /&gt;
== Links ==&lt;br /&gt;
&lt;br /&gt;
* http://mlmmj.org/ Projektseite&lt;br /&gt;
* https://codeberg.org/mlmmj mlmmj auf Codeberg&lt;br /&gt;
* https://github.com/tchapi/mlmmj-simple-web-interface ein Admin-Interface in NodeJS&lt;br /&gt;
* [https://web.archive.org/web/20221228110514/https://www.tablix.org/~avian/blog/archives/2010/04/the_faulty_default/ https://www.tablix.org/~avian/blog/archives/2010/04/the_faulty_default/ (via web.archive.org)] Nutzung von mlmmj in Verbindung mit Procmail&lt;br /&gt;
* [https://gist.github.com/kboss/7c9593f0fd9219406226c4f11256b98a Einfaches Python-Script zum Massenimport aus einem Texfile.] Geht bestimmt auch eleganter mit purem Bash&lt;br /&gt;
* Ein Self-Service zum Subscriben/Unsubscriben lässt sich in Form von Mail-to-Links in Webseiten einbinden. Beispiele gibt es bei Hostsharing für die öffentlichen &amp;quot;public&amp;quot;-Mailinglisten: https://www.hostsharing.net/lists/public-discussion/ . Alternativ auf https://github.com/hblasum/mlmmj-php-web-simplified ein Webfrontend mit dem sich Benutzerinnen und Benutzer selbst ein-/austragen können (Vereinfachung von mlmmj-php-web von Christoph Thiel).&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
[[Kategorie:HSDoku]]&lt;br /&gt;
[[Kategorie:Installationsanleitungen]]&lt;br /&gt;
[[Kategorie:Software]]&lt;br /&gt;
[[Kategorie:Mailinglisten]]&lt;br /&gt;
[[Kategorie:E-Mail]]&lt;/div&gt;</summary>
		<author><name>Apc00-tony</name></author>
	</entry>
	<entry>
		<id>https://wiki.hostsharing.net/index.php?title=Mlmmj&amp;diff=6659</id>
		<title>Mlmmj</title>
		<link rel="alternate" type="text/html" href="https://wiki.hostsharing.net/index.php?title=Mlmmj&amp;diff=6659"/>
		<updated>2024-05-31T14:31:13Z</updated>

		<summary type="html">&lt;p&gt;Apc00-tony: /* Groß- und Kleinschreibung */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[http://www.mlmmj.org/ mlmmj], angeblich eine Abkürzung für &amp;quot;Mailing List Management Made Joyful&amp;quot;, ist ein Programm, mit dem in einem Hostsharing Paket E-Mail-Verteiler realisiert werden kann.&lt;br /&gt;
&lt;br /&gt;
Wer noch nicht weiß, was ein E-Mail-Verteiler machen soll oder wie, lese veilleicht auch den Wikipedia-Artikel:&lt;br /&gt;
[http://de.wikipedia.org/wiki/Mailingliste Mailingliste]&lt;br /&gt;
&lt;br /&gt;
Eine leistungsfähigere Alternative zu mlmmj könnte [[Mailman_3_installieren|Mailman 3]] sein.&lt;br /&gt;
&lt;br /&gt;
Diese Anleitung beschreibt die Einrichtung einer Mailingliste für eine Domain in einem Hostsharing-Webspace.&lt;br /&gt;
&lt;br /&gt;
== Voraussetzungen  ==&lt;br /&gt;
&lt;br /&gt;
Das Debian Paket [http://packages.debian.org/search?keywords=mlmmj mlmmj] ist auf den Shared-Hosting-Servern bereits installiert. (Wer die Software selbst kompilieren möchte kann aktuellen Source-Code bei [https://codeberg.org/mlmmj/mlmmj|codeberg.org] finden.)&lt;br /&gt;
&lt;br /&gt;
Für den Betrieb der Mailingliste empfiehlt sich das Anlegen eines eigenen Users für diesen Zweck mit hsadmin.&lt;br /&gt;
&lt;br /&gt;
In dieser Anleitung heißt das Paket &#039;&#039;xyz00&#039;&#039; und der für Mailinglisten eingesetzte User &#039;&#039;xyz00-list&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
Die E-Mail-Adresse der einzurichtende Mailing-Liste soll &#039;&#039;discuss@example.org&#039;&#039; sein. Den lokalen Teil dieser Adresse, &#039;&#039;discuss&#039;&#039;, ist der Listenname. Der Listenname darf auf keinen Fall das Plus-Zeichen (+) enthalten, weil dies ein Sonderbedeutung für die Listensteuerung hat: &#039;&#039;mlmmj&#039;&#039; wird nämlich Befehle der Abonnenten über erweiterte Adressen annehmen, wie z.B. &#039;&#039;discuss+help@example.org&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
Die Domain &#039;&#039;example.org&#039;&#039; muss dazu bei einem beliebigen User im Paket &#039;&#039;xyz00&#039;&#039; [[aufgeschaltet]] sein. (&amp;quot;Aufgeschaltet&amp;quot; bedeutet, daß diese Domain bei Hostsharing gehostet wird und der Domainname als Verzeichnis /home/pacs/xyz00/*User*/doms/example.org/ erscheint.)&lt;br /&gt;
&lt;br /&gt;
== Einrichtung ==&lt;br /&gt;
&lt;br /&gt;
Ich melde mich über SSH auf der Hostsharing-Console als der Paketuser &#039;&#039;xyz00&#039;&#039; an.&lt;br /&gt;
&lt;br /&gt;
Im Shell kann ich dann durch den Befehl &#039;&#039;hsscript -i&#039;&#039; das Verwaltungswerkzeug [[hsadmin]] interaktiv ausführen:&lt;br /&gt;
&lt;br /&gt;
  xyz00@h03:~$ hsscript -i&lt;br /&gt;
  Password: *************&lt;br /&gt;
  xyz00@hsadmin&amp;gt; &lt;br /&gt;
&lt;br /&gt;
In &#039;&#039;hsadmin&#039;&#039; werden User und E-Mail-Adresse angelegt.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=shell&amp;gt;&lt;br /&gt;
xyz00@hsadmin&amp;gt; user.add({set:{name:&#039;xyz00-list&#039;,comment:&#039;Mailingliste Discuss&#039;,shell:&#039;/bin/bash&#039;,password:&#039;geheimnis&#039;}})&lt;br /&gt;
xyz00@hsadmin&amp;gt; emailaddress.add({set:{target:&#039;xyz00-list&#039;,localpart:&#039;discuss&#039;,domain:&#039;example.org&#039;}})&lt;br /&gt;
xyz00@hsadmin&amp;gt; bye&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Mit dem Parameter &amp;quot;target&amp;quot; wird die für diese Adresse eingehende Post zunächst in das Postfach des Users xyz00-list abgelegt.&lt;br /&gt;
&lt;br /&gt;
Für den User xyz00-list lege ich in seinem Heimat-Verzeichnis das Unterverzeichnis &amp;lt;tt&amp;gt;mlmmj&amp;lt;/tt&amp;gt; an:&lt;br /&gt;
&lt;br /&gt;
  mkdir /home/pacs/xyz00/users/list/mlmmj&lt;br /&gt;
&lt;br /&gt;
Dann lege ich die Mailingliste mit folgendem Kommando an:&lt;br /&gt;
&lt;br /&gt;
  mlmmj-make-ml -L discuss -s /home/pacs/xyz00/users/list/mlmmj&lt;br /&gt;
&lt;br /&gt;
Das Skript &#039;&#039;mlmmj-make-ml&#039;&#039; fragt weitere Parameter der Mailingliste ab:&lt;br /&gt;
&lt;br /&gt;
  The Domain for the List? [] : example.org&lt;br /&gt;
  The emailaddress of the list owner? [postmaster] : webmaster@example.org&lt;br /&gt;
  For the list texts you can choose between the following languages or&lt;br /&gt;
  give an absolute path to a directory containing the texts.&lt;br /&gt;
  Available languages:&lt;br /&gt;
  cz  da	de  en	es  fr	it  nl	ru&lt;br /&gt;
  The path to texts for the list? [en] : de&lt;br /&gt;
&lt;br /&gt;
Das skript &#039;&#039;mlmmj-make-ml&#039;&#039; legt daraufhin unter &amp;quot;/home/pacs/xyz00/users/list/mlmmj&amp;quot; ein Verzeichnis &amp;quot;discuss&amp;quot; an, das die Datenstruktur zur Verwaltung der Mailingliste enthält.&lt;br /&gt;
&lt;br /&gt;
Weitere Konfigurationen der Liste erfolgen durch das Anlegen von Dateien im&lt;br /&gt;
Verzeichnis &amp;quot;/home/pacs/xyz00/users/list/mlmmj/discuss/control&amp;quot;.&lt;br /&gt;
Die Konfigurationsmöglichkeiten finden Sie auf der [http://mlmmj.org/docs/tunables/ Internetseite von mlmmj].&lt;br /&gt;
&lt;br /&gt;
Damit mlmmj die Verteilung der Post übernimmt, muß ich im Heimat-Verzeichnis des users xyz00-list die Datei &amp;lt;tt&amp;gt;.forward&amp;lt;/tt&amp;gt; mit folgenden Inhalt (INKLUSIVE der Anführungszeichen!) erstellen:&lt;br /&gt;
&lt;br /&gt;
  &amp;quot;|/usr/bin/mlmmj-recieve -L /home/pacs/xyz00/users/list/mlmmj/discuss/&amp;quot;&lt;br /&gt;
&lt;br /&gt;
(Ja, &#039;&#039;receive&#039;&#039; schreibt sich mit &#039;&#039;-ei-&#039;&#039;, aber mlmmj hält einen symbolischen Link bereit für diejenigen, die in englischer Rechtschreibung unsicher sind:)&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=shell&amp;gt;&lt;br /&gt;
xyz00-list@h03:~$ ls -la /usr/bin/mlmmj-rec*&lt;br /&gt;
-rwxr-xr-x 1 root root 27104 Sep 25  2018 /usr/bin/mlmmj-receive&lt;br /&gt;
lrwxrwxrwx 1 root root    13 Sep 25  2018 /usr/bin/mlmmj-recieve -&amp;gt; mlmmj-receive&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Die &amp;lt;tt&amp;gt;.forward&amp;lt;/tt&amp;gt;-Datei sorgt dafür, dass eingehende E-Mails an das User-Postfach an das Programm &#039;&#039;mlmmj-recieve&#039;&#039; übergeben werden.&lt;br /&gt;
&lt;br /&gt;
Für regelmäßige Aufgaben der Listen-Managers definiere ich die&lt;br /&gt;
[[Cron|crontab]] wie folgt (immer noch als &#039;&#039;xyz00-list&#039;&#039;):&lt;br /&gt;
&lt;br /&gt;
  xyz00-list@h03:~$ crontab -e&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=shell line&amp;gt;&lt;br /&gt;
MAILTO=webmaster@example.org&lt;br /&gt;
PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/X11R6/bin&lt;br /&gt;
HOME=/home/pacs/xyz00/users/list&lt;br /&gt;
SHELL=/bin/bash&lt;br /&gt;
LANG=en_US.UTF-8&lt;br /&gt;
# m h  dom mon dow   command&lt;br /&gt;
28 */4 * * * /usr/bin/mlmmj-maintd -d /home/pacs/xyz00/users/list/mlmmj -F&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Zum Schluss rufe ich das Skript mlmmj-sub auf, um die E-Mail-Adressen der gewünschten Abonnenten des Verteilers einzutragen:&lt;br /&gt;
&lt;br /&gt;
 /usr/bin/mlmmj-sub -L /home/pacs/xyz00/users/list/mlmmj/discuss -a klaus.muster@gmx.de -c &lt;br /&gt;
 /usr/bin/mlmmj-sub -L /home/pacs/xyz00/users/list/mlmmj/discuss -a sabine.beispiel@arcor.de -c &lt;br /&gt;
&lt;br /&gt;
Dabei bewirkt &amp;quot;-c&amp;quot;, dass der Abonnent eine Begrüßungs-Nachricht erhält. Alternativ kann man &amp;quot;-C&amp;quot; (großes C) angeben: dann muss der Abonnent das Abo durch Antworten auf die Nachricht bestätigen.&lt;br /&gt;
&lt;br /&gt;
== weitere Optionen  ==&lt;br /&gt;
&lt;br /&gt;
Noch ein paar Dinge, die Sie möglicherweise einstellen wollen:&lt;br /&gt;
&lt;br /&gt;
Ein Prefix in der Betreffzeile setzen, z.B.: &amp;quot;[discuss]&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
 echo &amp;quot;[discuss]&amp;quot; &amp;gt; /home/pacs/xyz00/users/list/mlmmj/discuss/control/prefix&lt;br /&gt;
&lt;br /&gt;
Wenn die Liste nur E-Mails von eingetragenen Abonnenten weiterleiten soll:&lt;br /&gt;
&lt;br /&gt;
 touch /home/pacs/xyz00/users/list/mlmmj/discuss/control/subonlypost&lt;br /&gt;
&lt;br /&gt;
Damit der Listen-Owner weitere Abonnements bestätigen muss:&lt;br /&gt;
&lt;br /&gt;
 touch /home/pacs/xyz00/users/list/mlmmj/discuss/control/submod&lt;br /&gt;
&lt;br /&gt;
Einen &amp;quot;Reply-To:&amp;quot;-Header setzen, damit Antwort-Mails standardmäßig an die Mailing-Liste gehen:&lt;br /&gt;
&lt;br /&gt;
  echo &amp;quot;Reply-To:&amp;quot; &amp;gt; /home/pacs/xyz00/users/list/mlmmj/discuss/control/delheaders&lt;br /&gt;
  echo &amp;quot;Reply-To: discuss@example.org&amp;quot; &amp;gt; /home/pacs/xyz00/users/list/mlmmj/discuss/control/customheaders&lt;br /&gt;
&lt;br /&gt;
Weitere Möglichkeiten finden Sie (wie oben bereits angegeben) &lt;br /&gt;
auf der [http://mlmmj.org/docs/tunables/ Internetseite von mlmmj].&lt;br /&gt;
&lt;br /&gt;
=== Achtung: DKIM ===&lt;br /&gt;
&lt;br /&gt;
Mlmmj gibt die Möglichkeit, mit &#039;&#039;&#039;delheaders&#039;&#039;&#039; und &#039;&#039;&#039;customheaders&#039;&#039;&#039; die Header der durchgeleiteten Mail umfangreich zu ändern. Allerdings tragen Mails heute häufig kryptografische Signaturen der sendenden Mailserver. Eine DKIM-Signatur sichert damit in der Regel die Integrität des Body der Mail sowie der Header &#039;&#039;Subject:&#039;&#039;, &#039;&#039;From:&#039;&#039;, &#039;&#039;To:&#039;&#039;, &#039;&#039;Date:&#039;&#039;, &#039;&#039;From&#039;&#039;, und oft auch &#039;&#039;Reply-To:&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
Wird zum Beispiel mit einem Prefix das Subject geändert oder ein Footer angehängt, macht dies die DKIM-Signatur ungültig. Das ist für viele Mailprovider ein Grund die Nachricht abzuweisen.&lt;br /&gt;
&lt;br /&gt;
== Zur Konfiguration im Browser ==&lt;br /&gt;
&lt;br /&gt;
Die Original-Distribution von &#039;&#039;mlmmj&#039;&#039; enthält ein paar einfache PHP- und Perl-Skripte.  Das sind Beispiele für Subscribe-/Unsubscribe-Formulare, ein Admin-Formular zum Eintragen und Löschen von Abonnements und eine Seite mit der gesamten Listen-Konfiguration.&lt;br /&gt;
&lt;br /&gt;
Wer es sich ansehen möchte:&lt;br /&gt;
&lt;br /&gt;
Als Paket-Admin eine Domain aufschalten:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=shell&amp;gt;&lt;br /&gt;
hsscript -u xyz00 -e &amp;quot;domain.add({set:{name:&#039;lists.example.org&#039;,user:&#039;xyz00-list&#039;}})&amp;quot;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Und weiter als &amp;quot;xyz00-list&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
Download der neuesten Version der Sourcen von mlmmj von http://mlmmj.org/downloads/ (noch besser: Download des aktuellen Debian-Pakets von [https://packages.debian.org/bookworm/all/mlmmj-php-web-admin/download debian.org]: da sind einige veraltete PHP-Ausdrücke schon herausgepatcht) und diese in einem temporären Verzeichnis entpacken (mit tar oder dpkg-deb).&lt;br /&gt;
&lt;br /&gt;
Unter &amp;quot;/mlmmj-$versionsnummer/contrib/web/php-admin/&amp;quot;, oder beim .deb-Paket unter &amp;quot;usr/share/mlmmj-...&amp;quot;, findet sich die PHP-Admin-Anwendung. Also ...&lt;br /&gt;
&lt;br /&gt;
* den Inhalt diese Verzeichnisses nach &amp;quot;/home/pacs/xyz00/users/list/doms/lists.example.org/&amp;quot; packen;&lt;br /&gt;
* in &amp;quot;/home/pacs/xyz00/users/list/doms/lists.example.org/conf/config.php&amp;quot; die Variable &amp;quot;$topdir&amp;quot; anpassen;&lt;br /&gt;
* die Dateien aus &amp;quot;/home/pacs/xyz00/users/list/doms/lists.example.org/htdocs/&amp;quot; nach &amp;quot;/home/pacs/xyz00/users/list/doms/lists.example.org/htdocs-ssl/&amp;quot; verschieben;&lt;br /&gt;
* Beim .deb-Paket die config.php, die templates/ und die tunables.pl aus etc/ nach example.org/conf/ verschieben;&lt;br /&gt;
* in &amp;quot;/home/pacs/xyz00/users/list/mlmmj&amp;quot; und in &amp;quot;/home/pacs/xyz00/users/list/doms/lists.example.org/htdocs-ssl/&amp;quot; eine &amp;quot;.htaccess&amp;quot; mit folgendem Inhalt ablegen: &lt;br /&gt;
&amp;lt;syntaxhighlight lang=apache line&amp;gt;&lt;br /&gt;
Require valid-user&lt;br /&gt;
AuthType Basic&lt;br /&gt;
AuthName &amp;quot;mlmmj web-interface&amp;quot;&lt;br /&gt;
AuthUserFile /home/pacs/xyz00/users/list/doms/lists.example.org/etc/htpasswd&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
* Und schließlich die &amp;quot;htpasswd&amp;quot;-Datei anlegen.&lt;br /&gt;
&lt;br /&gt;
 cd /home/pacs/xyz00/users/list/doms/lists.example.org/etc/&lt;br /&gt;
 htpasswd -c htpasswd listadmin&lt;br /&gt;
&lt;br /&gt;
* Ein Passwort angeben.&lt;br /&gt;
&lt;br /&gt;
Nun enthält diese PHP-Anwendung, wenn man sie nicht dem Debian-Paket entnommen hat, leider noch eine Zeile, die schon seit PHP 7 nicht mehr lauffähig ist. Also muß man noch&lt;br /&gt;
&lt;br /&gt;
* in &amp;lt;tt&amp;gt;.../htdocs-ssl/index.php&amp;lt;/tt&amp;gt; folgende Änderung vornehmen:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=diff line&amp;gt;&lt;br /&gt;
@@ -38,4 +38,5 @@&lt;br /&gt;
 # use scandir to have alphabetical order &lt;br /&gt;
 foreach (scandir($topdir) as $file) {&lt;br /&gt;
-    if (!ereg(&amp;quot;^\.&amp;quot;,$file))&lt;br /&gt;
+# ereg obsolete!! Vormals:    if (!ereg(&amp;quot;^\.&amp;quot;,$file))&lt;br /&gt;
+    if (!preg_match(&#039;/^\./&#039;,$file))&lt;br /&gt;
     {&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
und das Ergebnis auf https://lists.example.org anschauen.&lt;br /&gt;
&lt;br /&gt;
== Mehrere Mailinglisten betreiben ==&lt;br /&gt;
&lt;br /&gt;
Wenn mehrere Mailinglisten in einem Account und mit einer Admin-Oberfläche betrieben werden soll, empfiehlt sich die Nutzung von Procmail für den Aufruf von &#039;&#039;mlmmj&#039;&#039; für die jeweiligen Liste mit ihrem Daten-Verzeichnis.&lt;br /&gt;
&lt;br /&gt;
Dazu trägt man in der Datei &amp;lt;tt&amp;gt;.forward&amp;lt;/tt&amp;gt; statt des Aufrufs von &#039;&#039;mlmmj-recieve&#039;&#039; einen Aufruf von &#039;&#039;procmail&#039;&#039; ein:&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
 |/usr/bin/procmail&lt;br /&gt;
&lt;br /&gt;
Die Konfiguration von Procmail kann generisch erfolgen. Dazu legt man eine Datei &amp;lt;tt&amp;gt;.procmailrc&amp;lt;/tt&amp;gt; mit folgendem Inhalt ins $HOME des Users:&lt;br /&gt;
&lt;br /&gt;
 SHELL=/bin/sh&lt;br /&gt;
 HOMEDIR=/home/pacs/xyz00/users/list&lt;br /&gt;
 MAILDIR=/home/pacs/xyz00/users/list/Maildir&lt;br /&gt;
 PMDIR=/home/pacs/xyz00/users/list&lt;br /&gt;
 VERBOSE=yes&lt;br /&gt;
 LOGFILE=/home/pacs/xyz00/users/list/var/procmail.log&lt;br /&gt;
 DEFAULT&lt;br /&gt;
 &lt;br /&gt;
 :0:&lt;br /&gt;
 * ^X-Original-To: ()\/[^@+]+&lt;br /&gt;
 |/usr/bin/mlmmj-receive -F -L /home/pacs/xyz00/users/list/mlmmj/${MATCH}/&lt;br /&gt;
 &lt;br /&gt;
 :0&lt;br /&gt;
 { EXITCODE 67 }&lt;br /&gt;
&lt;br /&gt;
Bitte dafür sorgen, dass das Verzeichnis &#039;&#039;/home/pacs/xyz00/users/list/var&#039;&#039; existiert.&lt;br /&gt;
&lt;br /&gt;
Der kryptische reguläre Ausdruck hinter dem Header &#039;&#039;X-Original-To:&#039;&#039; passt auf den Beginn der E-Mail-Adresse bis zum ersten &#039;&#039;@&#039;&#039;- oder &#039;&#039;+&#039;&#039;-Zeichen. In der Variable &#039;&#039;MATCH&#039;&#039; steht also der Name der Mailingliste, d.h. der Name der Verzeichnisses, in dem die Liste verwaltet wird.&lt;br /&gt;
&lt;br /&gt;
Sehr wichtig ist die Zeile &#039;&#039;DEFAULT&#039;&#039; zu Beginn der &#039;&#039;.procmailrc&#039;&#039;. Die Variable &#039;&#039;DEFAULT&#039;&#039; wird von &#039;&#039;procmail&#039;&#039; gesetzt. Wir sorgen mit dieser Zeile dafür, dass sie wieder undefiniert ist. Diese Variable wird intern von &#039;&#039;mlmmj&#039;&#039; benutzt, wenn sie gesetzt ist. Das führt in Kombination mit &#039;&#039;procmail&#039;&#039; zu Fehlfunktionen (vgl. Links).&lt;br /&gt;
&lt;br /&gt;
===Groß- und Kleinschreibung===&lt;br /&gt;
&lt;br /&gt;
Achtung, mit der Groß- und Kleinschreibung von Listennamen gibt es bei dieser Procmail-Lösung eine kleine Tücke. Procmail übernimmt in die Variable $MATCH genau die in der X-Original-To-Headerzeile vorgefundene Schreibweise, und diese kann denkbarerweise &amp;quot;Listen-Name&amp;quot; oder &amp;quot;listen-name&amp;quot; oder &amp;quot;Listen-name&amp;quot; sein. &amp;lt;tt&amp;gt;mlmmj&amp;lt;/tt&amp;gt; hingegen wird diesen Wert in Unix-Manier mit dem genauen Verzeichnisnamen &amp;lt;tt&amp;gt;${HOME}/mlmmj/listen-name&amp;lt;/tt&amp;gt; vergleichen, und bei unterschiedlicher Schreibweise die Mail nicht verteilen.&lt;br /&gt;
&lt;br /&gt;
====Lösung 1====&lt;br /&gt;
&lt;br /&gt;
Eine teilweise Lösung besteht darin, den Listennamen in dem &amp;lt;tt&amp;gt;mlmmj&amp;lt;/tt&amp;gt;-Aufruf in der &amp;lt;tt&amp;gt;.procmailrc&amp;lt;/tt&amp;gt; in Kleinbuchstaben umzuschreiben. Dann lautet das Rezept so:&lt;br /&gt;
&lt;br /&gt;
 :0:&lt;br /&gt;
 * ^X-Original-To: ()\/[^@+]+&lt;br /&gt;
 |/usr/bin/mlmmj-receive -F -L /home/pacs/xyz00/users/list/mlmmj/$(echo ${MATCH} | tr [:upper:] [:lower:])/&lt;br /&gt;
&lt;br /&gt;
Der Rest der Datei muß gleich bleiben, wie weiter oben angezeigt.&lt;br /&gt;
&lt;br /&gt;
In diesem Fall müssen aber alle Mailing-Listen ohne Großbuchstaben im Namen angelegt werden!&lt;br /&gt;
&lt;br /&gt;
(Man kann auch in &amp;lt;tt&amp;gt;${HOME}/mlmmj/&amp;lt;/tt&amp;gt; durch kleingeschriebene Symlinks großgeschriebene Listennamen ansprechbar machen:&lt;br /&gt;
&lt;br /&gt;
  xyz00-list@h02:~$ ls -lA mlmmj/&lt;br /&gt;
  total 8&lt;br /&gt;
  -rw-r--r--  1 xyz00-list xyz00  148 Feb  1 16:56 .htaccess&lt;br /&gt;
  lrwxrwxrwx  1 xyz00-list xyz00   10 Feb  2 18:01 mitglieder -&amp;gt; Mitglieder&lt;br /&gt;
  drwxr-xr-x 15 xyz00-list xyz00 4096 Feb  2 16:53 Mitglieder&lt;br /&gt;
&lt;br /&gt;
====Lösung 2====&lt;br /&gt;
&lt;br /&gt;
Bash kann bei der Auflösung von Variablen die Groß- und Kleinschreibung manipulieren. (Siehe dazu bei der Zeichenfolge &amp;lt;tt&amp;gt;,,&amp;lt;/tt&amp;gt; in &amp;lt;tt&amp;gt;man bash&amp;lt;/tt&amp;gt;.) Dann ist &amp;lt;code&amp;gt;$(echo ${MATCH} | tr [:upper:] [:lower:])&amp;lt;/code&amp;gt; gleichbedeutend mit &amp;lt;code&amp;gt;${MATCH,,}&amp;lt;/code&amp;gt;. Allerdings braucht procmail einige Überredung, um Bash zu verwenden.&lt;br /&gt;
&lt;br /&gt;
 SHELL=/bin/bash&lt;br /&gt;
 SHELLMETAS=&amp;amp;|&amp;lt;&amp;gt;~;?*[{&lt;br /&gt;
 HOMEDIR= ...&lt;br /&gt;
&lt;br /&gt;
...&lt;br /&gt;
&lt;br /&gt;
 :0:&lt;br /&gt;
 * ^X-Original-To: ()\/[^@+]+&lt;br /&gt;
 |/usr/bin/mlmmj-receive -F -L /home/pacs/xyz00/users/list/mlmmj/${MATCH,,}/&lt;br /&gt;
 &lt;br /&gt;
Die Tücke ist, daß procmail den in SHELL angegebenen Shell nur dann verwendet, wenn in der Befehlszeile eines der in SHELLMETAS angegebenen Zeichen enthält. Und das &#039;|&#039; am Anfang der Zeile zählt dabei nicht! In diesem Beispiel ist es das Zeichen &amp;lt;tt&amp;gt;{&amp;lt;/tt&amp;gt;, das den Einsatz von Bash auslöst.&lt;br /&gt;
&lt;br /&gt;
Beide Lösungen scheinen zu funktionieren; Angabe ohne Gewähr.&lt;br /&gt;
&lt;br /&gt;
== Links ==&lt;br /&gt;
&lt;br /&gt;
* http://mlmmj.org/ Projektseite&lt;br /&gt;
* https://codeberg.org/mlmmj mlmmj auf Codeberg&lt;br /&gt;
* https://github.com/tchapi/mlmmj-simple-web-interface ein Admin-Interface in NodeJS&lt;br /&gt;
* [https://web.archive.org/web/20221228110514/https://www.tablix.org/~avian/blog/archives/2010/04/the_faulty_default/ https://www.tablix.org/~avian/blog/archives/2010/04/the_faulty_default/ (via web.archive.org)] Nutzung von mlmmj in Verbindung mit Procmail&lt;br /&gt;
* [https://gist.github.com/kboss/7c9593f0fd9219406226c4f11256b98a Einfaches Python-Script zum Massenimport aus einem Texfile.] Geht bestimmt auch eleganter mit purem Bash&lt;br /&gt;
* Ein Self-Service zum Subscriben/Unsubscriben lässt sich in Form von Mail-to-Links in Webseiten einbinden. Beispiele gibt es bei Hostsharing für die öffentlichen &amp;quot;public&amp;quot;-Mailinglisten: https://www.hostsharing.net/lists/public-discussion/ . Alternativ auf https://github.com/hblasum/mlmmj-php-web-simplified ein Webfrontend mit dem sich Benutzerinnen und Benutzer selbst ein-/austragen können (Vereinfachung von mlmmj-php-web von Christoph Thiel).&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
[[Kategorie:HSDoku]]&lt;br /&gt;
[[Kategorie:Installationsanleitungen]]&lt;br /&gt;
[[Kategorie:Software]]&lt;br /&gt;
[[Kategorie:Mailinglisten]]&lt;br /&gt;
[[Kategorie:E-Mail]]&lt;/div&gt;</summary>
		<author><name>Apc00-tony</name></author>
	</entry>
	<entry>
		<id>https://wiki.hostsharing.net/index.php?title=Mlmmj&amp;diff=6658</id>
		<title>Mlmmj</title>
		<link rel="alternate" type="text/html" href="https://wiki.hostsharing.net/index.php?title=Mlmmj&amp;diff=6658"/>
		<updated>2024-05-31T14:24:44Z</updated>

		<summary type="html">&lt;p&gt;Apc00-tony: /* Mehrere Mailinglisten betreiben */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[http://www.mlmmj.org/ mlmmj], angeblich eine Abkürzung für &amp;quot;Mailing List Management Made Joyful&amp;quot;, ist ein Programm, mit dem in einem Hostsharing Paket E-Mail-Verteiler realisiert werden kann.&lt;br /&gt;
&lt;br /&gt;
Wer noch nicht weiß, was ein E-Mail-Verteiler machen soll oder wie, lese veilleicht auch den Wikipedia-Artikel:&lt;br /&gt;
[http://de.wikipedia.org/wiki/Mailingliste Mailingliste]&lt;br /&gt;
&lt;br /&gt;
Eine leistungsfähigere Alternative zu mlmmj könnte [[Mailman_3_installieren|Mailman 3]] sein.&lt;br /&gt;
&lt;br /&gt;
Diese Anleitung beschreibt die Einrichtung einer Mailingliste für eine Domain in einem Hostsharing-Webspace.&lt;br /&gt;
&lt;br /&gt;
== Voraussetzungen  ==&lt;br /&gt;
&lt;br /&gt;
Das Debian Paket [http://packages.debian.org/search?keywords=mlmmj mlmmj] ist auf den Shared-Hosting-Servern bereits installiert. (Wer die Software selbst kompilieren möchte kann aktuellen Source-Code bei [https://codeberg.org/mlmmj/mlmmj|codeberg.org] finden.)&lt;br /&gt;
&lt;br /&gt;
Für den Betrieb der Mailingliste empfiehlt sich das Anlegen eines eigenen Users für diesen Zweck mit hsadmin.&lt;br /&gt;
&lt;br /&gt;
In dieser Anleitung heißt das Paket &#039;&#039;xyz00&#039;&#039; und der für Mailinglisten eingesetzte User &#039;&#039;xyz00-list&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
Die E-Mail-Adresse der einzurichtende Mailing-Liste soll &#039;&#039;discuss@example.org&#039;&#039; sein. Den lokalen Teil dieser Adresse, &#039;&#039;discuss&#039;&#039;, ist der Listenname. Der Listenname darf auf keinen Fall das Plus-Zeichen (+) enthalten, weil dies ein Sonderbedeutung für die Listensteuerung hat: &#039;&#039;mlmmj&#039;&#039; wird nämlich Befehle der Abonnenten über erweiterte Adressen annehmen, wie z.B. &#039;&#039;discuss+help@example.org&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
Die Domain &#039;&#039;example.org&#039;&#039; muss dazu bei einem beliebigen User im Paket &#039;&#039;xyz00&#039;&#039; [[aufgeschaltet]] sein. (&amp;quot;Aufgeschaltet&amp;quot; bedeutet, daß diese Domain bei Hostsharing gehostet wird und der Domainname als Verzeichnis /home/pacs/xyz00/*User*/doms/example.org/ erscheint.)&lt;br /&gt;
&lt;br /&gt;
== Einrichtung ==&lt;br /&gt;
&lt;br /&gt;
Ich melde mich über SSH auf der Hostsharing-Console als der Paketuser &#039;&#039;xyz00&#039;&#039; an.&lt;br /&gt;
&lt;br /&gt;
Im Shell kann ich dann durch den Befehl &#039;&#039;hsscript -i&#039;&#039; das Verwaltungswerkzeug [[hsadmin]] interaktiv ausführen:&lt;br /&gt;
&lt;br /&gt;
  xyz00@h03:~$ hsscript -i&lt;br /&gt;
  Password: *************&lt;br /&gt;
  xyz00@hsadmin&amp;gt; &lt;br /&gt;
&lt;br /&gt;
In &#039;&#039;hsadmin&#039;&#039; werden User und E-Mail-Adresse angelegt.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=shell&amp;gt;&lt;br /&gt;
xyz00@hsadmin&amp;gt; user.add({set:{name:&#039;xyz00-list&#039;,comment:&#039;Mailingliste Discuss&#039;,shell:&#039;/bin/bash&#039;,password:&#039;geheimnis&#039;}})&lt;br /&gt;
xyz00@hsadmin&amp;gt; emailaddress.add({set:{target:&#039;xyz00-list&#039;,localpart:&#039;discuss&#039;,domain:&#039;example.org&#039;}})&lt;br /&gt;
xyz00@hsadmin&amp;gt; bye&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Mit dem Parameter &amp;quot;target&amp;quot; wird die für diese Adresse eingehende Post zunächst in das Postfach des Users xyz00-list abgelegt.&lt;br /&gt;
&lt;br /&gt;
Für den User xyz00-list lege ich in seinem Heimat-Verzeichnis das Unterverzeichnis &amp;lt;tt&amp;gt;mlmmj&amp;lt;/tt&amp;gt; an:&lt;br /&gt;
&lt;br /&gt;
  mkdir /home/pacs/xyz00/users/list/mlmmj&lt;br /&gt;
&lt;br /&gt;
Dann lege ich die Mailingliste mit folgendem Kommando an:&lt;br /&gt;
&lt;br /&gt;
  mlmmj-make-ml -L discuss -s /home/pacs/xyz00/users/list/mlmmj&lt;br /&gt;
&lt;br /&gt;
Das Skript &#039;&#039;mlmmj-make-ml&#039;&#039; fragt weitere Parameter der Mailingliste ab:&lt;br /&gt;
&lt;br /&gt;
  The Domain for the List? [] : example.org&lt;br /&gt;
  The emailaddress of the list owner? [postmaster] : webmaster@example.org&lt;br /&gt;
  For the list texts you can choose between the following languages or&lt;br /&gt;
  give an absolute path to a directory containing the texts.&lt;br /&gt;
  Available languages:&lt;br /&gt;
  cz  da	de  en	es  fr	it  nl	ru&lt;br /&gt;
  The path to texts for the list? [en] : de&lt;br /&gt;
&lt;br /&gt;
Das skript &#039;&#039;mlmmj-make-ml&#039;&#039; legt daraufhin unter &amp;quot;/home/pacs/xyz00/users/list/mlmmj&amp;quot; ein Verzeichnis &amp;quot;discuss&amp;quot; an, das die Datenstruktur zur Verwaltung der Mailingliste enthält.&lt;br /&gt;
&lt;br /&gt;
Weitere Konfigurationen der Liste erfolgen durch das Anlegen von Dateien im&lt;br /&gt;
Verzeichnis &amp;quot;/home/pacs/xyz00/users/list/mlmmj/discuss/control&amp;quot;.&lt;br /&gt;
Die Konfigurationsmöglichkeiten finden Sie auf der [http://mlmmj.org/docs/tunables/ Internetseite von mlmmj].&lt;br /&gt;
&lt;br /&gt;
Damit mlmmj die Verteilung der Post übernimmt, muß ich im Heimat-Verzeichnis des users xyz00-list die Datei &amp;lt;tt&amp;gt;.forward&amp;lt;/tt&amp;gt; mit folgenden Inhalt (INKLUSIVE der Anführungszeichen!) erstellen:&lt;br /&gt;
&lt;br /&gt;
  &amp;quot;|/usr/bin/mlmmj-recieve -L /home/pacs/xyz00/users/list/mlmmj/discuss/&amp;quot;&lt;br /&gt;
&lt;br /&gt;
(Ja, &#039;&#039;receive&#039;&#039; schreibt sich mit &#039;&#039;-ei-&#039;&#039;, aber mlmmj hält einen symbolischen Link bereit für diejenigen, die in englischer Rechtschreibung unsicher sind:)&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=shell&amp;gt;&lt;br /&gt;
xyz00-list@h03:~$ ls -la /usr/bin/mlmmj-rec*&lt;br /&gt;
-rwxr-xr-x 1 root root 27104 Sep 25  2018 /usr/bin/mlmmj-receive&lt;br /&gt;
lrwxrwxrwx 1 root root    13 Sep 25  2018 /usr/bin/mlmmj-recieve -&amp;gt; mlmmj-receive&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Die &amp;lt;tt&amp;gt;.forward&amp;lt;/tt&amp;gt;-Datei sorgt dafür, dass eingehende E-Mails an das User-Postfach an das Programm &#039;&#039;mlmmj-recieve&#039;&#039; übergeben werden.&lt;br /&gt;
&lt;br /&gt;
Für regelmäßige Aufgaben der Listen-Managers definiere ich die&lt;br /&gt;
[[Cron|crontab]] wie folgt (immer noch als &#039;&#039;xyz00-list&#039;&#039;):&lt;br /&gt;
&lt;br /&gt;
  xyz00-list@h03:~$ crontab -e&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=shell line&amp;gt;&lt;br /&gt;
MAILTO=webmaster@example.org&lt;br /&gt;
PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/X11R6/bin&lt;br /&gt;
HOME=/home/pacs/xyz00/users/list&lt;br /&gt;
SHELL=/bin/bash&lt;br /&gt;
LANG=en_US.UTF-8&lt;br /&gt;
# m h  dom mon dow   command&lt;br /&gt;
28 */4 * * * /usr/bin/mlmmj-maintd -d /home/pacs/xyz00/users/list/mlmmj -F&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Zum Schluss rufe ich das Skript mlmmj-sub auf, um die E-Mail-Adressen der gewünschten Abonnenten des Verteilers einzutragen:&lt;br /&gt;
&lt;br /&gt;
 /usr/bin/mlmmj-sub -L /home/pacs/xyz00/users/list/mlmmj/discuss -a klaus.muster@gmx.de -c &lt;br /&gt;
 /usr/bin/mlmmj-sub -L /home/pacs/xyz00/users/list/mlmmj/discuss -a sabine.beispiel@arcor.de -c &lt;br /&gt;
&lt;br /&gt;
Dabei bewirkt &amp;quot;-c&amp;quot;, dass der Abonnent eine Begrüßungs-Nachricht erhält. Alternativ kann man &amp;quot;-C&amp;quot; (großes C) angeben: dann muss der Abonnent das Abo durch Antworten auf die Nachricht bestätigen.&lt;br /&gt;
&lt;br /&gt;
== weitere Optionen  ==&lt;br /&gt;
&lt;br /&gt;
Noch ein paar Dinge, die Sie möglicherweise einstellen wollen:&lt;br /&gt;
&lt;br /&gt;
Ein Prefix in der Betreffzeile setzen, z.B.: &amp;quot;[discuss]&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
 echo &amp;quot;[discuss]&amp;quot; &amp;gt; /home/pacs/xyz00/users/list/mlmmj/discuss/control/prefix&lt;br /&gt;
&lt;br /&gt;
Wenn die Liste nur E-Mails von eingetragenen Abonnenten weiterleiten soll:&lt;br /&gt;
&lt;br /&gt;
 touch /home/pacs/xyz00/users/list/mlmmj/discuss/control/subonlypost&lt;br /&gt;
&lt;br /&gt;
Damit der Listen-Owner weitere Abonnements bestätigen muss:&lt;br /&gt;
&lt;br /&gt;
 touch /home/pacs/xyz00/users/list/mlmmj/discuss/control/submod&lt;br /&gt;
&lt;br /&gt;
Einen &amp;quot;Reply-To:&amp;quot;-Header setzen, damit Antwort-Mails standardmäßig an die Mailing-Liste gehen:&lt;br /&gt;
&lt;br /&gt;
  echo &amp;quot;Reply-To:&amp;quot; &amp;gt; /home/pacs/xyz00/users/list/mlmmj/discuss/control/delheaders&lt;br /&gt;
  echo &amp;quot;Reply-To: discuss@example.org&amp;quot; &amp;gt; /home/pacs/xyz00/users/list/mlmmj/discuss/control/customheaders&lt;br /&gt;
&lt;br /&gt;
Weitere Möglichkeiten finden Sie (wie oben bereits angegeben) &lt;br /&gt;
auf der [http://mlmmj.org/docs/tunables/ Internetseite von mlmmj].&lt;br /&gt;
&lt;br /&gt;
=== Achtung: DKIM ===&lt;br /&gt;
&lt;br /&gt;
Mlmmj gibt die Möglichkeit, mit &#039;&#039;&#039;delheaders&#039;&#039;&#039; und &#039;&#039;&#039;customheaders&#039;&#039;&#039; die Header der durchgeleiteten Mail umfangreich zu ändern. Allerdings tragen Mails heute häufig kryptografische Signaturen der sendenden Mailserver. Eine DKIM-Signatur sichert damit in der Regel die Integrität des Body der Mail sowie der Header &#039;&#039;Subject:&#039;&#039;, &#039;&#039;From:&#039;&#039;, &#039;&#039;To:&#039;&#039;, &#039;&#039;Date:&#039;&#039;, &#039;&#039;From&#039;&#039;, und oft auch &#039;&#039;Reply-To:&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
Wird zum Beispiel mit einem Prefix das Subject geändert oder ein Footer angehängt, macht dies die DKIM-Signatur ungültig. Das ist für viele Mailprovider ein Grund die Nachricht abzuweisen.&lt;br /&gt;
&lt;br /&gt;
== Zur Konfiguration im Browser ==&lt;br /&gt;
&lt;br /&gt;
Die Original-Distribution von &#039;&#039;mlmmj&#039;&#039; enthält ein paar einfache PHP- und Perl-Skripte.  Das sind Beispiele für Subscribe-/Unsubscribe-Formulare, ein Admin-Formular zum Eintragen und Löschen von Abonnements und eine Seite mit der gesamten Listen-Konfiguration.&lt;br /&gt;
&lt;br /&gt;
Wer es sich ansehen möchte:&lt;br /&gt;
&lt;br /&gt;
Als Paket-Admin eine Domain aufschalten:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=shell&amp;gt;&lt;br /&gt;
hsscript -u xyz00 -e &amp;quot;domain.add({set:{name:&#039;lists.example.org&#039;,user:&#039;xyz00-list&#039;}})&amp;quot;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Und weiter als &amp;quot;xyz00-list&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
Download der neuesten Version der Sourcen von mlmmj von http://mlmmj.org/downloads/ (noch besser: Download des aktuellen Debian-Pakets von [https://packages.debian.org/bookworm/all/mlmmj-php-web-admin/download debian.org]: da sind einige veraltete PHP-Ausdrücke schon herausgepatcht) und diese in einem temporären Verzeichnis entpacken (mit tar oder dpkg-deb).&lt;br /&gt;
&lt;br /&gt;
Unter &amp;quot;/mlmmj-$versionsnummer/contrib/web/php-admin/&amp;quot;, oder beim .deb-Paket unter &amp;quot;usr/share/mlmmj-...&amp;quot;, findet sich die PHP-Admin-Anwendung. Also ...&lt;br /&gt;
&lt;br /&gt;
* den Inhalt diese Verzeichnisses nach &amp;quot;/home/pacs/xyz00/users/list/doms/lists.example.org/&amp;quot; packen;&lt;br /&gt;
* in &amp;quot;/home/pacs/xyz00/users/list/doms/lists.example.org/conf/config.php&amp;quot; die Variable &amp;quot;$topdir&amp;quot; anpassen;&lt;br /&gt;
* die Dateien aus &amp;quot;/home/pacs/xyz00/users/list/doms/lists.example.org/htdocs/&amp;quot; nach &amp;quot;/home/pacs/xyz00/users/list/doms/lists.example.org/htdocs-ssl/&amp;quot; verschieben;&lt;br /&gt;
* Beim .deb-Paket die config.php, die templates/ und die tunables.pl aus etc/ nach example.org/conf/ verschieben;&lt;br /&gt;
* in &amp;quot;/home/pacs/xyz00/users/list/mlmmj&amp;quot; und in &amp;quot;/home/pacs/xyz00/users/list/doms/lists.example.org/htdocs-ssl/&amp;quot; eine &amp;quot;.htaccess&amp;quot; mit folgendem Inhalt ablegen: &lt;br /&gt;
&amp;lt;syntaxhighlight lang=apache line&amp;gt;&lt;br /&gt;
Require valid-user&lt;br /&gt;
AuthType Basic&lt;br /&gt;
AuthName &amp;quot;mlmmj web-interface&amp;quot;&lt;br /&gt;
AuthUserFile /home/pacs/xyz00/users/list/doms/lists.example.org/etc/htpasswd&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
* Und schließlich die &amp;quot;htpasswd&amp;quot;-Datei anlegen.&lt;br /&gt;
&lt;br /&gt;
 cd /home/pacs/xyz00/users/list/doms/lists.example.org/etc/&lt;br /&gt;
 htpasswd -c htpasswd listadmin&lt;br /&gt;
&lt;br /&gt;
* Ein Passwort angeben.&lt;br /&gt;
&lt;br /&gt;
Nun enthält diese PHP-Anwendung, wenn man sie nicht dem Debian-Paket entnommen hat, leider noch eine Zeile, die schon seit PHP 7 nicht mehr lauffähig ist. Also muß man noch&lt;br /&gt;
&lt;br /&gt;
* in &amp;lt;tt&amp;gt;.../htdocs-ssl/index.php&amp;lt;/tt&amp;gt; folgende Änderung vornehmen:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=diff line&amp;gt;&lt;br /&gt;
@@ -38,4 +38,5 @@&lt;br /&gt;
 # use scandir to have alphabetical order &lt;br /&gt;
 foreach (scandir($topdir) as $file) {&lt;br /&gt;
-    if (!ereg(&amp;quot;^\.&amp;quot;,$file))&lt;br /&gt;
+# ereg obsolete!! Vormals:    if (!ereg(&amp;quot;^\.&amp;quot;,$file))&lt;br /&gt;
+    if (!preg_match(&#039;/^\./&#039;,$file))&lt;br /&gt;
     {&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
und das Ergebnis auf https://lists.example.org anschauen.&lt;br /&gt;
&lt;br /&gt;
== Mehrere Mailinglisten betreiben ==&lt;br /&gt;
&lt;br /&gt;
Wenn mehrere Mailinglisten in einem Account und mit einer Admin-Oberfläche betrieben werden soll, empfiehlt sich die Nutzung von Procmail für den Aufruf von &#039;&#039;mlmmj&#039;&#039; für die jeweiligen Liste mit ihrem Daten-Verzeichnis.&lt;br /&gt;
&lt;br /&gt;
Dazu trägt man in der Datei &amp;lt;tt&amp;gt;.forward&amp;lt;/tt&amp;gt; statt des Aufrufs von &#039;&#039;mlmmj-recieve&#039;&#039; einen Aufruf von &#039;&#039;procmail&#039;&#039; ein:&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
 |/usr/bin/procmail&lt;br /&gt;
&lt;br /&gt;
Die Konfiguration von Procmail kann generisch erfolgen. Dazu legt man eine Datei &amp;lt;tt&amp;gt;.procmailrc&amp;lt;/tt&amp;gt; mit folgendem Inhalt ins $HOME des Users:&lt;br /&gt;
&lt;br /&gt;
 SHELL=/bin/sh&lt;br /&gt;
 HOMEDIR=/home/pacs/xyz00/users/list&lt;br /&gt;
 MAILDIR=/home/pacs/xyz00/users/list/Maildir&lt;br /&gt;
 PMDIR=/home/pacs/xyz00/users/list&lt;br /&gt;
 VERBOSE=yes&lt;br /&gt;
 LOGFILE=/home/pacs/xyz00/users/list/var/procmail.log&lt;br /&gt;
 DEFAULT&lt;br /&gt;
 &lt;br /&gt;
 :0:&lt;br /&gt;
 * ^X-Original-To: ()\/[^@+]+&lt;br /&gt;
 |/usr/bin/mlmmj-receive -F -L /home/pacs/xyz00/users/list/mlmmj/${MATCH}/&lt;br /&gt;
 &lt;br /&gt;
 :0&lt;br /&gt;
 { EXITCODE 67 }&lt;br /&gt;
&lt;br /&gt;
Bitte dafür sorgen, dass das Verzeichnis &#039;&#039;/home/pacs/xyz00/users/list/var&#039;&#039; existiert.&lt;br /&gt;
&lt;br /&gt;
Der kryptische reguläre Ausdruck hinter dem Header &#039;&#039;X-Original-To:&#039;&#039; passt auf den Beginn der E-Mail-Adresse bis zum ersten &#039;&#039;@&#039;&#039;- oder &#039;&#039;+&#039;&#039;-Zeichen. In der Variable &#039;&#039;MATCH&#039;&#039; steht also der Name der Mailingliste, d.h. der Name der Verzeichnisses, in dem die Liste verwaltet wird.&lt;br /&gt;
&lt;br /&gt;
Sehr wichtig ist die Zeile &#039;&#039;DEFAULT&#039;&#039; zu Beginn der &#039;&#039;.procmailrc&#039;&#039;. Die Variable &#039;&#039;DEFAULT&#039;&#039; wird von &#039;&#039;procmail&#039;&#039; gesetzt. Wir sorgen mit dieser Zeile dafür, dass sie wieder undefiniert ist. Diese Variable wird intern von &#039;&#039;mlmmj&#039;&#039; benutzt, wenn sie gesetzt ist. Das führt in Kombination mit &#039;&#039;procmail&#039;&#039; zu Fehlfunktionen (vgl. Links).&lt;br /&gt;
&lt;br /&gt;
===Groß- und Kleinschreibung===&lt;br /&gt;
&lt;br /&gt;
Achtung, mit der Groß- und Kleinschreibung von Listennamen gibt es bei dieser Procmail-Lösung eine kleine Tücke. Procmail übernimmt in die Variable $MATCH genau die in der X-Original-To-Headerzeile vorgefundene Schreibweise, und diese kann denkbarerweise &amp;quot;Listen-Name&amp;quot; oder &amp;quot;listen-name&amp;quot; oder &amp;quot;Listen-name&amp;quot; sein. &amp;lt;tt&amp;gt;mlmmj&amp;lt;/tt&amp;gt; hingegen wird diesen Wert in Unix-Manier mit dem genauen Verzeichnisnamen &amp;lt;tt&amp;gt;${HOME}/mlmmj/listen-name&amp;lt;/tt&amp;gt; vergleichen, und bei unterschiedlicher Schreibweise die Mail nicht verteilen.&lt;br /&gt;
&lt;br /&gt;
====Lösung 1====&lt;br /&gt;
&lt;br /&gt;
Eine teilweise Lösung besteht darin, den Listennamen in dem &amp;lt;tt&amp;gt;mlmmj&amp;lt;/tt&amp;gt;-Aufruf in der &amp;lt;tt&amp;gt;.procmailrc&amp;lt;/tt&amp;gt; in Kleinbuchstaben umzuschreiben. Dann lautet das Rezept so:&lt;br /&gt;
&lt;br /&gt;
 :0:&lt;br /&gt;
 * ^X-Original-To: ()\/[^@+]+&lt;br /&gt;
 |/usr/bin/mlmmj-receive -F -L /home/pacs/xyz00/users/list/mlmmj/$(echo ${MATCH} | tr [:upper:] [:lower:])/&lt;br /&gt;
&lt;br /&gt;
Der Rest der Datei muß gleich bleiben, wie weiter oben angezeigt.&lt;br /&gt;
&lt;br /&gt;
In diesem Fall müssen aber alle Mailing-Listen ohne Großbuchstaben im Namen angelegt werden!&lt;br /&gt;
&lt;br /&gt;
(Man kann auch in &amp;lt;tt&amp;gt;${HOME}/mlmmj/&amp;lt;/tt&amp;gt; durch kleingeschriebene Symlinks großgeschriebene Listennamen ansprechbar machen:&lt;br /&gt;
&lt;br /&gt;
  xyz00-list@h02:~$ ls -lA mlmmj/&lt;br /&gt;
  total 8&lt;br /&gt;
  -rw-r--r--  1 xyz00-list xyz00  148 Feb  1 16:56 .htaccess&lt;br /&gt;
  lrwxrwxrwx  1 xyz00-list xyz00   10 Feb  2 18:01 mitglieder -&amp;gt; Mitglieder&lt;br /&gt;
  drwxr-xr-x 15 xyz00-list xyz00 4096 Feb  2 16:53 Mitglieder&lt;br /&gt;
&lt;br /&gt;
====Lösung 2====&lt;br /&gt;
&lt;br /&gt;
Bash kann bei der Auflösung von Variablen die Groß- und Kleinschreibung manipulieren. (Siehe dazu bei der Zeichenfolge &amp;lt;tt&amp;gt;,,&amp;lt;/tt&amp;gt; in &amp;lt;tt&amp;gt;man bash&amp;lt;/tt&amp;gt;.) Dann ist &amp;lt;code&amp;gt;$(echo ${MATCH} | tr [:upper:] [:lower:])&amp;lt;/code&amp;gt; gleichbedeutend mit &amp;lt;code&amp;gt;${MATCH,,}&amp;lt;/code&amp;gt;. Allerdings braucht procmail einige Überredung, um Bash zu verwenden.&lt;br /&gt;
&lt;br /&gt;
 SHELL=/bin/bash&lt;br /&gt;
 SHELLMETAS=&amp;amp;|&amp;lt;&amp;gt;~;?*[{&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
...&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
 HOMEDIR=/home/pacs/xyz00/users/list&lt;br /&gt;
 MAILDIR=/home/pacs/xyz00/users/list/Maildir&lt;br /&gt;
 PMDIR=/home/pacs/xyz00/users/list&lt;br /&gt;
 VERBOSE=yes&lt;br /&gt;
 LOGFILE=/home/pacs/xyz00/users/list/var/procmail.log&lt;br /&gt;
 DEFAULT&lt;br /&gt;
 &lt;br /&gt;
 :0:&lt;br /&gt;
 * ^X-Original-To: ()\/[^@+]+&lt;br /&gt;
 |/usr/bin/mlmmj-receive -F -L /home/pacs/xyz00/users/list/mlmmj/${MATCH}/&lt;br /&gt;
 &lt;br /&gt;
 :0&lt;br /&gt;
 { EXITCODE 67 }&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Beides scheint zu funktionieren; Angabe ohne Gewähr.)&lt;br /&gt;
&lt;br /&gt;
== Links ==&lt;br /&gt;
&lt;br /&gt;
* http://mlmmj.org/ Projektseite&lt;br /&gt;
* https://codeberg.org/mlmmj mlmmj auf Codeberg&lt;br /&gt;
* https://github.com/tchapi/mlmmj-simple-web-interface ein Admin-Interface in NodeJS&lt;br /&gt;
* [https://web.archive.org/web/20221228110514/https://www.tablix.org/~avian/blog/archives/2010/04/the_faulty_default/ https://www.tablix.org/~avian/blog/archives/2010/04/the_faulty_default/ (via web.archive.org)] Nutzung von mlmmj in Verbindung mit Procmail&lt;br /&gt;
* [https://gist.github.com/kboss/7c9593f0fd9219406226c4f11256b98a Einfaches Python-Script zum Massenimport aus einem Texfile.] Geht bestimmt auch eleganter mit purem Bash&lt;br /&gt;
* Ein Self-Service zum Subscriben/Unsubscriben lässt sich in Form von Mail-to-Links in Webseiten einbinden. Beispiele gibt es bei Hostsharing für die öffentlichen &amp;quot;public&amp;quot;-Mailinglisten: https://www.hostsharing.net/lists/public-discussion/ . Alternativ auf https://github.com/hblasum/mlmmj-php-web-simplified ein Webfrontend mit dem sich Benutzerinnen und Benutzer selbst ein-/austragen können (Vereinfachung von mlmmj-php-web von Christoph Thiel).&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
[[Kategorie:HSDoku]]&lt;br /&gt;
[[Kategorie:Installationsanleitungen]]&lt;br /&gt;
[[Kategorie:Software]]&lt;br /&gt;
[[Kategorie:Mailinglisten]]&lt;br /&gt;
[[Kategorie:E-Mail]]&lt;/div&gt;</summary>
		<author><name>Apc00-tony</name></author>
	</entry>
	<entry>
		<id>https://wiki.hostsharing.net/index.php?title=PHP&amp;diff=6419</id>
		<title>PHP</title>
		<link rel="alternate" type="text/html" href="https://wiki.hostsharing.net/index.php?title=PHP&amp;diff=6419"/>
		<updated>2024-02-15T11:50:32Z</updated>

		<summary type="html">&lt;p&gt;Apc00-tony: /* Alternative: PATH Variable setzen */ Format&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;PHP wird bei Hostsharing per FastCGI ausgeführt. Dafür wird in jedem Domainverzeichnis unter &amp;quot;fastcgi/&amp;quot; und &amp;quot;fastcgi-ssl/&amp;quot; eine &amp;quot;hs-phpstub&amp;quot;-Datei angelegt. Der Apache Webserver ist konfiguriert .php Dateien über diesen &amp;quot;Stub&amp;quot; mit den Rechten des Users auszuführen.&lt;br /&gt;
&lt;br /&gt;
Zur Wiederherstellung des originalen &amp;quot;hs-phpstub&amp;quot; ist dieser zentral im Verzeichnis &lt;br /&gt;
&lt;br /&gt;
  /usr/local/src/phpstub&lt;br /&gt;
&lt;br /&gt;
abgelegt.&lt;br /&gt;
&lt;br /&gt;
Anwender, die lediglich PHP-Dateien hochgeladen haben, brauchen ausdrücklich keine eigene php.ini.&lt;br /&gt;
&lt;br /&gt;
=== Auswahl der PHP-Version === &lt;br /&gt;
&lt;br /&gt;
In HSAdmin kann pro Domain festgelegt werden, welche PHP-Version der &amp;quot;hs-phpstub&amp;quot; für das Ausführen von PHP-Skripten verwendet. Zur Zeit werden die PHP-Version 8.2, 8.1, 8.0 und 7.4 unterstützt.&lt;br /&gt;
&lt;br /&gt;
=== Anpassung der PHP Konfiguration === &lt;br /&gt;
&lt;br /&gt;
Die Datei &amp;quot;php.ini&amp;quot; wird zur Konfiguration des PHP-Intergreters verwendet. Die Voreinstellungen können pro Domain überschrieben werden. Dazu legt der Domain-Administrator im Verzeichnis &amp;quot;fastcgi-ssl/&amp;quot; (bzw. &amp;quot;fastcgi/&amp;quot;) eine eigene Datei &amp;quot;php.ini&amp;quot; an.&lt;br /&gt;
&lt;br /&gt;
Der komplette Pfad zu dieser Datei lautet zum Beispiel&lt;br /&gt;
(für den Webspace &amp;quot;xyz00&amp;quot; den Domain-User &amp;quot;xyz00-meinbenutzer&amp;quot; und die Domain &amp;quot;meinedomain.de&amp;quot;):&lt;br /&gt;
&lt;br /&gt;
  /home/pacs/xyz00/users/meinbenutzer/doms/meinedomain.de/fastcgi-ssl/php.ini &lt;br /&gt;
&lt;br /&gt;
In dieser Datei müssen nicht alle Konfigurationsoptionen von PHP definiert sein, sondern nur die, die sich gegenüber der Standard php.ini ändern sollen. Diese liegt in /etc/php/VERSIONSNUMMER/cgi und kann dort eingesehen werden.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Achtung:&#039;&#039;&#039; Kommentare nicht mit # einleiten (kann zu unerwarteten Fehlkonfigurationen führen), Kommentarzeichen ist das Semikolon &amp;quot;;&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
Häufig anzupassen sind z.B.:&lt;br /&gt;
&lt;br /&gt;
* die Content-Type charset= Vorgabe für den HTTP Header.&lt;br /&gt;
&lt;br /&gt;
* der maximal verwendbare Hauptspeicher (memory_limit).&lt;br /&gt;
&lt;br /&gt;
* die maximale Größe hochgeladener Dateien (post_max_size).&lt;br /&gt;
&lt;br /&gt;
* die aktiven Extensions.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Beispiel einer php.ini: &lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 ------8&amp;lt; SCHNIPP &amp;gt;8------&lt;br /&gt;
 [..]&lt;br /&gt;
 memory_limit = 128M (default)&lt;br /&gt;
 post_max_size = 8M (default)&lt;br /&gt;
 upload_max_filesize = 2M (default)&lt;br /&gt;
 display_errors = Off (default)&lt;br /&gt;
 log_errors = Off (default)&lt;br /&gt;
 error_log = /home/pacs/xyz00/users/meinbenutzer/doms/meinedomain.de/fastcgi-ssl/php_errors.log&lt;br /&gt;
&lt;br /&gt;
 [..]&lt;br /&gt;
 default_charset = &amp;quot;UTF-8&amp;quot;&lt;br /&gt;
 ; (ist sonst iso-8859-1)&lt;br /&gt;
 ; Der charset kann aber wiederum durch einen Funktionsaufruf&lt;br /&gt;
 ; header(&amp;quot;Content-Type: text/html; charset=iso-8859-1&amp;quot;)&lt;br /&gt;
 ; im PHP-Skript überschrieben werden (sofern output_buffering = On).&lt;br /&gt;
 ------8&amp;lt; SCHNIPP &amp;gt;8------&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Beachte:&#039;&#039;&#039; Eine geänderte php.ini Konfiguration wird mit FastCGI erst übernommen, wenn die PHP Prozesse des Users (die über längere Zeit laufen bleiben) neu gestartet werden.&lt;br /&gt;
&lt;br /&gt;
Man kann ein Neustarten der PHP Prozesse mit dem folgenden Kommando erzwingen:&lt;br /&gt;
&lt;br /&gt;
  killall -u $USER -r php&lt;br /&gt;
&lt;br /&gt;
$USER enhält als Umgebungsvariable den aktuell angemeldeten Benutzer und muss nicht durch den Benutzernamen (xyz00 oder xyz00-user) ersetzt werden. Nur die Prozesse des angemeldeten Users $USER werden gelöscht. &amp;quot;-r&amp;quot; bewirkt, dass der Ausdruck &amp;quot;php&amp;quot; als regulärer Ausdruck interpretiert wird. Intern heißen die sichtbaren Prozesse nicht &amp;quot;php&amp;quot; sondern beispielsweise &amp;quot;php7.4&amp;quot;&lt;br /&gt;
&lt;br /&gt;
=== PHP Sicherheit ===&lt;br /&gt;
&lt;br /&gt;
==== open_basedir ====&lt;br /&gt;
&lt;br /&gt;
Sofern der PHP Parameter open_basdir nicht gesetzt ist (Vorgabe) können (kompromittierte) php Skripte an alle Dateien des Users kommen, ohne einen extra Shellzugang installieren zu müssen und dadurch entdeckt zu werden.&lt;br /&gt;
&lt;br /&gt;
Die Passwortabfrage von Hsadmin bringt eine Abhilfe für die zentralen Dienste. (Sofern Du dein Passwort nicht in eine Datei schreibst und die Abfrage so wieder ausschaltest, wovon besser abzusehen ist.) Doch alle Daten auf die Du als Benutzer zugreifen kannst sind prinzipiell den PHP-Skripten ausgeliefert.&lt;br /&gt;
&lt;br /&gt;
Mit open_basedir wird festgelegt in welchen Verzeichnissen PHP Skripte lesen und schreiben dürfen. Geprüft wird dabei ob der zu öffnende Pfad mit dem angegebene Pfad beginnt. Es ist daher wichtig ob sich am Ende ein &amp;quot;/&amp;quot; befindet oder nicht. Ein open_basedir von /home/doms/example.org/subs/www (ohne /) erlaubt somit z.B. auch Zugriffe auf die Subdomain www2 etc.&lt;br /&gt;
&lt;br /&gt;
Beispielzeile für die php.ini:&lt;br /&gt;
 open_basedir = /home/doms/example.org/subs/&lt;br /&gt;
&lt;br /&gt;
Wenn man mehrere Subdomains hat und diese isolieren möchte, ist dies durch Aufschaltung von lokalen Subdomains auf verschiedene User möglich. (Siehe https://doc.hostsharing.net/users/administration/domain/index.html )&lt;br /&gt;
&lt;br /&gt;
==== Sicherheitskritische Funktionen ====&lt;br /&gt;
&lt;br /&gt;
Weitere Dinge die deaktiviert werden sollten, wenn sie nicht benötigt werden, was im allgemeinen der Fall ist, sind: Das öffnen von URLs als Dateien,&lt;br /&gt;
&lt;br /&gt;
 allow_url_fopen = Off&lt;br /&gt;
&lt;br /&gt;
und die Ausführung von Systembefehlen.&lt;br /&gt;
&lt;br /&gt;
 disable_functions = show_source, system, passthru, shell_exec, exec, phpinfo, popen, proc_open&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===  eigene PHP Konfigurationen und verschiedene nebeneinander verwenden ===&lt;br /&gt;
&lt;br /&gt;
Um verschiedene PHP Konfigurationen nebeneinander zu verwenden, kopierst Du einen eigenen &amp;quot;phpstub&amp;quot; in ein Unterzeichnis von (fast)cgi(-ssl) und mappst (Einträge in der .htaccess) nach Belieben deine PHP Dateien darauf. &lt;br /&gt;
So können beliebig viele Konfigurationen bei einer Domain nebeneinander genutzt werden.&lt;br /&gt;
&lt;br /&gt;
==== Beispiel muster.example.com ==== &lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
mkdir ~/doms/example.com/fastcgi/muster&lt;br /&gt;
cp ~/doms/example.com/fastcgi/phpstub ~/doms/example.com/fastcgi/muster/phpstub&lt;br /&gt;
&lt;br /&gt;
und wenn benötigt:&lt;br /&gt;
vi ~/doms/example.com/fastcgi/muster/php.ini&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Anschließend muss der Apache Webserver noch angewiesen werden auch diese bestimmte Konfiguration von PHP zu verwenden. Dazu werden der [[.htaccess]] Datei im DocumentRoot der Sub-Domain zwei Zeilen hinzugefügt bzw. eine .htaccess mit den zwei Zeilen angelegt. &lt;br /&gt;
Im Beispiel handelt es sich um die Domain muster.example.com, also:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 cd ~/doms/example.com/subs/muster&lt;br /&gt;
 vi .htaccess&lt;br /&gt;
&lt;br /&gt;
 AddType application/x-httpd-phpfastcgi .php&lt;br /&gt;
 Action application/x-httpd-phpfastcgi /fastcgi-bin/muster/phpstub&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Vorinstallierte PHP Version wechseln ==&lt;br /&gt;
&lt;br /&gt;
Hostsharing stellt neben der aktuellen Standardversion PHP 8.2 auch die Versionen PHP 7.4, 8.0 und 8.1 zur Verfügung.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===PHP 8.2 für ssh-Zugang per Shell aktivieren===&lt;br /&gt;
&lt;br /&gt;
Möchte man an der Shell immer /usr/bin/php8.0 statt /usr/bin/php aufrufen, dann kann der Befehl auch in die Datei &amp;quot;~/.profile&amp;quot; ergänzt werden  mit der Zeile: &lt;br /&gt;
&amp;lt;pre&amp;gt;alias php=&#039;/usr/bin/php8.0&#039;&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Nach Aktualisierung der Datei &amp;quot;~/.profile&amp;quot; noch eingeben &lt;br /&gt;
&amp;lt;pre&amp;gt;$ source ~/.profile&amp;lt;/pre&amp;gt;&lt;br /&gt;
Dann sollte der Aufruf php -v die version php 8.0 zurückgeben. &lt;br /&gt;
&lt;br /&gt;
Gleiches gilt natürlich auch andere bei HS verfügbare PHP Versionen.&lt;br /&gt;
&lt;br /&gt;
==== Alternative: &amp;lt;tt&amp;gt;PATH&amp;lt;/tt&amp;gt; Variable setzen ====&lt;br /&gt;
&lt;br /&gt;
Eine Alternative ist die Nutzung einer alternativen Verlinkung und das setzen eines eigenen Pfades&lt;br /&gt;
Composer, oder andere php Scripte können auch als Programme php aufrufen, wenn sie dazu die Version aus &amp;lt;tt&amp;gt;/usr/bin/env&amp;lt;/tt&amp;gt; nutzen, bekommen Sie die Standard PHP version geliefert, beispielsweise php7.4.&lt;br /&gt;
Dieser Aufruf umgeht jeglichen Alias in &amp;lt;tt&amp;gt;~/.profile&amp;lt;/tt&amp;gt; oder &amp;lt;tt&amp;gt;~/.bash_profile&amp;lt;/tt&amp;gt;.&lt;br /&gt;
Welche verlinkung in &amp;lt;tt&amp;gt;/usr/bin/env&amp;lt;/tt&amp;gt; gesetzt ist lässt sich überprüfen durch den Befehl:&lt;br /&gt;
&amp;lt;pre&amp;gt;$ which php&amp;lt;/pre&amp;gt;&lt;br /&gt;
sollte ergeben:&lt;br /&gt;
&amp;lt;pre&amp;gt;/usr/bin/php&amp;lt;/pre&amp;gt; (und dies ist verlinkt mit irgendeiner System PHP Version zum Beispiel php7.4&lt;br /&gt;
&lt;br /&gt;
Anstelle der Nutzung also eines Alias wird nun einfach ein symbolischer Link an eine gewünschte Position gesetzt, zum Beispiel mit:&lt;br /&gt;
&amp;lt;pre&amp;gt;$ mkdir /home/doms/example.com/app/php8.2&amp;lt;/pre&amp;gt;&lt;br /&gt;
&amp;lt;pre&amp;gt;$ ln -s /usr/bin/php8.2 /home/doms/example.com/app/php8.2/&amp;lt;strong&amp;gt;php&amp;lt;/strong&amp;gt;&amp;lt;/pre&amp;gt; (wichtig, es muss hier als &amp;quot;php&amp;quot; benannt werden&amp;quot;&lt;br /&gt;
Nun wird der Pfad um diesen Punkt erweitert:&lt;br /&gt;
in &amp;lt;tt&amp;gt;~/.profile&amp;lt;/tt&amp;gt; oder &amp;lt;tt&amp;gt;~/.bash_profile&amp;lt;/tt&amp;gt;&lt;br /&gt;
&amp;lt;pre&amp;gt;PATH=&amp;quot;/home/doms/example.com/app/php8.2:$PATH&amp;quot;&amp;lt;/pre&amp;gt;&lt;br /&gt;
Nun liegt der Pfad noch vor dem Systempfad, was sich durch den Befehl&lt;br /&gt;
&amp;lt;pre&amp;gt;$ echo $PATH&amp;lt;/pre&amp;gt; überprüfen lässt:&lt;br /&gt;
hier steht jetzt so etwas wie:&lt;br /&gt;
&amp;lt;pre&amp;gt;&amp;lt;strong&amp;gt;/home/doms/example.com/app/php8.2&amp;lt;/strong&amp;gt;:/usr/local/bin:/usr/bin:/bin:/usr/local/games:/usr/games&amp;lt;/pre&amp;gt;&lt;br /&gt;
das heißt, bevor der Aufruf des Befehls php in /usr/bin/ danach sucht, hat er das Script &amp;quot;php&amp;quot; schon in dem neu erstellten Ordner gefunden und ruft diesen auf.&lt;br /&gt;
Diese &amp;lt;tt&amp;gt;PATH&amp;lt;/tt&amp;gt; Variable funktioniert nun natürlich genauso für alle Bash / cli Eingaben und ersetzt die Vergabe von Alias.&lt;br /&gt;
&amp;lt;pre&amp;gt;$ which php&amp;lt;/pre&amp;gt; ergibt nun:&lt;br /&gt;
&amp;lt;pre&amp;gt;/home/doms/example.com/app/php8.2/php&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Eigene PHP Version ==&lt;br /&gt;
Es kann auch eine eigene PHP Version im Paket installiert werden.&lt;br /&gt;
Eine Kurzanleitung ist unter [[Eigene_PHP_Version]] beschrieben.&lt;br /&gt;
&lt;br /&gt;
== Eigener PHP FPM Prozess ==&lt;br /&gt;
&lt;br /&gt;
auf einem Managed Server kann jeder Nutzer nach belieben auch php-fpm als eigenen Prozess starten.&lt;br /&gt;
Ein paar Notizen dazu finden sich auf der Seite [[PHP_FPM]].&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
[[Kategorie:HSDoku]]&lt;br /&gt;
[[Kategorie:Installationsanleitungen]]&lt;br /&gt;
[[Kategorie:Software]]&lt;br /&gt;
[[Kategorie:Glossar]]&lt;br /&gt;
[[Kategorie:WWW]]&lt;/div&gt;</summary>
		<author><name>Apc00-tony</name></author>
	</entry>
	<entry>
		<id>https://wiki.hostsharing.net/index.php?title=DAViCal_installieren&amp;diff=6418</id>
		<title>DAViCal installieren</title>
		<link rel="alternate" type="text/html" href="https://wiki.hostsharing.net/index.php?title=DAViCal_installieren&amp;diff=6418"/>
		<updated>2024-02-14T13:51:47Z</updated>

		<summary type="html">&lt;p&gt;Apc00-tony: /* Quellen */ Source now at davical.org.&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Allgemein ==&lt;br /&gt;
=== Beschreibung ===&lt;br /&gt;
[http://www.davical.org/ DAViCal] ist ein Server für die Verwaltung von Kalendern über das [http://caldav.calconnect.org/ CalDAV-Protokoll]. Die Kalenderdaten können mit allen CalDAV-fähigen Client-Programmen gelesen und geschrieben werden, z.B. Thunderbird mit [http://www.mozilla.org/projects/calendar/lightning/ Lightning], Evolution, Mulberry, iCal, oder iPhone.&lt;br /&gt;
&lt;br /&gt;
Das CalDAV-Protokoll bietet viele Funktionen, die noch nicht von allen Clients unterstützt werden, darunter Serien, Erinnerungen, Einladungen, Ressourcen, Arbeitsgruppen etc.&lt;br /&gt;
&lt;br /&gt;
DAViCal ist in PHP geschrieben, lizensiert unter GPL.&lt;br /&gt;
&lt;br /&gt;
DAViCal erlaubt auch über das WebDAV-Protokoll Kalender zu lesen, aber nicht zu modifizieren.&lt;br /&gt;
&lt;br /&gt;
=== Voraussetzungen ===&lt;br /&gt;
&lt;br /&gt;
DAViCal erfordert folgende technische Ressourcen:&lt;br /&gt;
* PostgreSQL&lt;br /&gt;
* Webserver mit PHP5&lt;br /&gt;
* Perl für den Installationsvorgang&lt;br /&gt;
* Ein Dateisystem mit erweiterten Attributen.&lt;br /&gt;
&lt;br /&gt;
Die Installations-Anleitung auf der Projekt-Homepage geht davon aus, daß mal als Administrator auf den Server zugreifen kann. Die Anleitung hier beschreibt, wie man konkret DAViCal in der Shared-Hosting-Umgebung bei Hostsharing installiert und betreibt.&lt;br /&gt;
&lt;br /&gt;
== Installation ==&lt;br /&gt;
&lt;br /&gt;
=== Design ===&lt;br /&gt;
&lt;br /&gt;
Diese Installationsanleitung beschreibt, wie DAViCal in einer eigens dafür [[Domainverwaltung#Lokale_Subdomains_durch_Aufschalten.3B_Delegieren|aufgeschalteten Subdomain]] über SSL betrieben wird. Für andere Konfigurationen, wie z.B. die Installation von DAViCal in einer als Unterverzeichnis von &amp;lt;tt&amp;gt;~/doms/&#039;&#039;domain&#039;&#039;/subs/&amp;lt;/tt&amp;gt; erstellten Subdomain, muß dieses Verfahren leicht angepaßt werden.&lt;br /&gt;
&lt;br /&gt;
Der Vorteil einer Installation in einer aufgeschalteten Subdomain ist, daß die Installation leicht von anderen Domaininhalten, PHP-Konfigurationen, oder sogar von anderen Domain-Administratoren, isoliert werden kann.&lt;br /&gt;
&lt;br /&gt;
=== Subdomain aufschalten ===&lt;br /&gt;
&lt;br /&gt;
Im Folgenden werden folgende Domainkonfigurationsdaten als Beispiel verwendet:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|- class=&amp;quot;hintergrundfarbe5&amp;quot;&lt;br /&gt;
! Typ                                          !! Wert                                !! Beschreibung&lt;br /&gt;
|-&lt;br /&gt;
| Subdomain || &amp;lt;tt&amp;gt;cal.example.org&amp;lt;/tt&amp;gt;  || Die Subdomain, unter der ein DAViCal-Server laufen soll&lt;br /&gt;
|-&lt;br /&gt;
| Domain-Admin || &amp;lt;tt&amp;gt;xyz00-hans&amp;lt;/tt&amp;gt; || Der User, dem die Subdomain delegiert wurde&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== Quellen ===&lt;br /&gt;
&lt;br /&gt;
Neben dem Sourcecode vom eigentlichen DAViCal-Programm wird auch die PHP-Bibliothek [http://andrew.mcmillan.net.nz/projects/awl &#039;&#039;Andrew&#039;s Web Libraries&#039;&#039;] benötigt. Diese stammt vom gleichen Entwickler.&lt;br /&gt;
&lt;br /&gt;
Die jeweils neusten Versionen befinden sich unter:&lt;br /&gt;
* DAViCal: https://www.davical.org/downloads/&lt;br /&gt;
* AWL: https://www.davical.org/downloads/&lt;br /&gt;
&lt;br /&gt;
Hier jeweils die Source-Dateien (&amp;lt;tt&amp;gt;*.tar.xz&amp;lt;/tt&amp;gt;) benutzen.&lt;br /&gt;
&lt;br /&gt;
==== Download ====&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&amp;lt;nowiki&amp;gt;&lt;br /&gt;
$ cd ~/doms/cal.example.org/var&lt;br /&gt;
$ wget http://debian.mcmillan.net.nz/packages/awl/awl-0.53.tar.gz&lt;br /&gt;
$ wget http://debian.mcmillan.net.nz/packages/davical/davical-1.1.1.tar.gz&lt;br /&gt;
&amp;lt;/nowiki&amp;gt;&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Auspacken ====&lt;br /&gt;
&lt;br /&gt;
Um die Dateien für den Betrieb in der Serverumgebung lesbar zu machen, die Dateierzeungsmaske temporär auf 022 setzen:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&amp;lt;nowiki&amp;gt;&lt;br /&gt;
$ umask 022&lt;br /&gt;
&amp;lt;/nowiki&amp;gt;&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Dann die heruntergeladenen Tarballs mit &amp;lt;tt&amp;gt;tar&amp;lt;/tt&amp;gt; auspacken:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&amp;lt;nowiki&amp;gt;&lt;br /&gt;
$ tar xfvz awl-0.46.tar.gz&lt;br /&gt;
$ tar xfvz davical-0.9.9.4.tar.gz&lt;br /&gt;
&amp;lt;/nowiki&amp;gt;&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Dann zwei symbolische Links mit den generischen Namen &amp;lt;tt&amp;gt;davical&amp;lt;/tt&amp;gt; und &amp;lt;tt&amp;gt;awl&amp;lt;/tt&amp;gt; erzeugen, die auf die installierten Versionen zeigen (dies erleichtert einen späteren Versionswechsel):&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&amp;lt;nowiki&amp;gt;&lt;br /&gt;
$ ln -s  awl-0.53  awl&lt;br /&gt;
$ ln -s  davical-1.1.1  davical&lt;br /&gt;
&amp;lt;/nowiki&amp;gt;&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Und zum Schluß die ursprüngliche Dateierzeugungsmaske wiederherstellen:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&amp;lt;nowiki&amp;gt;&lt;br /&gt;
$ umask 077&lt;br /&gt;
&amp;lt;/nowiki&amp;gt;&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== PostgreSQL vorbereiten ===&lt;br /&gt;
&lt;br /&gt;
DAViCal benötigt eine eigene PostgreSQL-Datenbank sowie 2 Datenbanknutzer.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
DAViCal enthält ein eigenes Installations-Skript, das die erforderlichen Datenbank, Datenbanknutzer, prozedurale Sprache, und Datenbanktabellen anlegt und initialisiert. Dies liegt unter &amp;lt;tt&amp;gt;davical/dba/create-database.sh&amp;lt;/tt&amp;gt;. Allerdings basiert das Skript auf der Annahme, daß man Superuser-Rechte hat, was in der Shared-Hosting-Umgebung nicht der Fall ist. In diesem Abschnitt wird deshalb beschrieben, wie man die entsprechenden Vorgänge in Hostsharing &amp;quot;von Hand&amp;quot; bewerkstelligt.&lt;br /&gt;
&lt;br /&gt;
==== Datenbank und Datenbanknutzer anlegen ====&lt;br /&gt;
&lt;br /&gt;
In dieser Anleitung werden folgende Namen für die Datenbank und deren Nutzer verwendet. Das Paket-Kürzel &amp;lt;tt&amp;gt;xyz00&amp;lt;/tt&amp;gt; ist natürlich durch das des betreffenden Pakets zu ersetzen.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|- class=&amp;quot;hintergrundfarbe5&amp;quot;&lt;br /&gt;
! Typ                                          !! Wert                                !! Beschreibung&lt;br /&gt;
|-&lt;br /&gt;
| DB-Admin || &amp;lt;tt&amp;gt;xyz00_davical_dba&amp;lt;/tt&amp;gt; || Der PostgreSQL-Nutzer, dem die Datenbank gehört und der administrative Tätigkeiten durchführt.&lt;br /&gt;
|-&lt;br /&gt;
| DB-Nutzer || &amp;lt;tt&amp;gt;xyz00_davical_app&amp;lt;/tt&amp;gt; || Der PostgreSQL-Nutzername, den DAViCal benutzt, um in der Datenbank zu lesen und zu schreiben.&lt;br /&gt;
|-&lt;br /&gt;
| Datenbank || &amp;lt;tt&amp;gt;xyz00_davical&amp;lt;/tt&amp;gt;  || Die PostgreSQL-Datenbank, die DAViCals Daten enthält.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
==== Umgebungsvariablen und PostgreSQL-Paßwort ====&lt;br /&gt;
&lt;br /&gt;
Die Nutzer und die Datenbank können über [[Hsadmin]] angelegt werden. Siehe dazu die Anleitungen auf der Seite [[PostgreSQL]] und [[Datenbanken]]. Diese Schritte müssen ggf. vom Paket-Admin vorgenommen werden.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&amp;lt;nowiki&amp;gt;&lt;br /&gt;
$ su xyz00&lt;br /&gt;
$ hsadmin -c postgresqluser.add --set:name=xyz00_davical_dba --set:password=geheim&lt;br /&gt;
$ hsadmin -c postgresqluser.add --set:name=xyz00_davical_app --set:password=geheim&lt;br /&gt;
&amp;lt;/nowiki&amp;gt;&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Als Besitzer der DAViCal-Datenbank &amp;lt;tt&amp;gt;xyz00_davical_dba&amp;lt;/tt&amp;gt; angeben; als Zeichenkodierung ist das Default &amp;lt;tt&amp;gt;UTF-8&amp;lt;/tt&amp;gt; richtig:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&amp;lt;nowiki&amp;gt;&lt;br /&gt;
$ hsadmin -c postgresqldb.add --set:name=xyz00_davical --set:owner=xyz00_davical_dba&lt;br /&gt;
$ exit&lt;br /&gt;
&amp;lt;/nowiki&amp;gt;&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Sowohl für die weitere Installation als auch für den Betrieb des Servers ist es am einfachsten, die Passwörter in eine &amp;lt;tt&amp;gt;[http://www.postgresql.org/docs/9.0/interactive/libpq-pgpass.html .pgpass]&amp;lt;/tt&amp;gt;-Datei zu schreiben: so müssen sie weder in den PHP-Dateien angegeben noch während der Installation manuell eingegeben werden.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&amp;lt;nowiki&amp;gt;&lt;br /&gt;
$ echo &amp;quot;localhost:5432:*:xyz00_davical_dba:geheimes_passwort&amp;quot; &amp;gt;&amp;gt; ~/.pgpass&lt;br /&gt;
$ echo &amp;quot;localhost:5432:*:xyz00_davical_app:geheimes_passwort&amp;quot; &amp;gt;&amp;gt; ~/.pgpass&lt;br /&gt;
$ chmod 0600 ~/.pgpass&lt;br /&gt;
&amp;lt;/nowiki&amp;gt;&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Zur weiteren Bequemlichkeit Umgebungsvariablen setzen, so daß beim Aufruf von &amp;lt;tt&amp;gt;psql&amp;lt;/tt&amp;gt; über die Kommandozeile keine Datenbank- und Nutzernamen eingegeben werden müssen. Diese Angaben gehen mit Beenden der Shell-Sitzung verloren.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&amp;lt;nowiki&amp;gt;&lt;br /&gt;
$ PGHOST=localhost &lt;br /&gt;
$ PGUSER=xyz00_davical_dba&lt;br /&gt;
$ PGDATABASE=xyz00_davical &lt;br /&gt;
$ export PGHOST PGUSER PGDATABASE &lt;br /&gt;
&amp;lt;/nowiki&amp;gt;&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== PL/pgSQL installieren ====&lt;br /&gt;
&lt;br /&gt;
In der Datenbank wird die prozedurale Sprache PL/pgSQL benötigt. Diese wird durch den folgenden Befehl angelegt:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&amp;lt;nowiki&amp;gt;&lt;br /&gt;
$ psql -A -c &amp;quot;CREATE LANGUAGE plpgsql;&amp;quot;&lt;br /&gt;
&amp;lt;/nowiki&amp;gt;&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Datenbank-Tabellen anlegen und initialisieren ====&lt;br /&gt;
&lt;br /&gt;
Die folgenden Befehle zum Anlegen der Datenbanktabellen können in dieser Form einfach nacheinander ausgeführt werden, wenn wie oben beschrieben die Umgebungsvariablen &amp;lt;tt&amp;gt;PGHOST&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;PGUSER&amp;lt;/tt&amp;gt; und &amp;lt;tt&amp;gt;PGDATABASE&amp;lt;/tt&amp;gt; gesetzt wurden und die &amp;lt;tt&amp;gt;.pgpass&amp;lt;/tt&amp;gt;-Datei geschrieben wurde.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&amp;lt;nowiki&amp;gt;&lt;br /&gt;
$ psql -A -f awl/dba/awl-tables.sql&lt;br /&gt;
$ psql -A -f awl/dba/schema-management.sql&lt;br /&gt;
$ psql -A -f davical/dba/davical.sql&lt;br /&gt;
$ ./davical/dba/update-davical-database –dbhost=${PGHOST} –dbuser=${PGUSER} –dbname=${PGDATABASE} --appuser=${PGDATABASE}_app&lt;br /&gt;
$ psql -A -f davical/dba/base-data.sql&lt;br /&gt;
&amp;lt;/nowiki&amp;gt;&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Für den DAViCal-Admin muß noch ein Passwort gesetzt werden &amp;amp;ndash; &#039;&amp;lt;tt&amp;gt;**&amp;lt;/tt&amp;gt;&#039; vor dem Passwort ist hier wichtig.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&amp;lt;nowiki&amp;gt;&lt;br /&gt;
$ psql -A -c &amp;quot;UPDATE usr SET password = &#039;**geheim&#039; WHERE user_no = 1;&amp;quot;&lt;br /&gt;
&amp;lt;/nowiki&amp;gt;&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Konfiguration ===&lt;br /&gt;
&lt;br /&gt;
DAViCal wird durch Angaben in der PHP-Datei &amp;lt;tt&amp;gt;davical/config/config.php&amp;lt;/tt&amp;gt; konfiguriert. Der folgende Befehl erzeugt eine Beispiel-Datei; weitere Beispiele befinden sich im Verzeichnis &amp;lt;tt&amp;gt;davical/config/&amp;lt;/tt&amp;gt;. Die Konfigurationsparameter sind im [http://wiki.davical.org/w/Configuration DAViCal-Wiki] beschrieben.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&amp;lt;nowiki&amp;gt;&lt;br /&gt;
$ cat &amp;gt; davical/config/config.php&lt;br /&gt;
   $c-&amp;gt;pg_connect[] = &amp;quot;dbname=xyz00_davical user=xyz00_davical_app host=localhost&amp;quot;; &lt;br /&gt;
   $c-&amp;gt;use_persistent = true; &lt;br /&gt;
   $c-&amp;gt;sysabbr     = &#039;cal@example.org&#039;; &lt;br /&gt;
   $c-&amp;gt;admin_email = &#039;admin@cal.example.org&#039;; &lt;br /&gt;
   $c-&amp;gt;system_name = &#039;CalDAV Server example.org&#039;; &lt;br /&gt;
   $c-&amp;gt;default_locale = &#039;de_DE&#039;; &lt;br /&gt;
   $c-&amp;gt;template_usr = array( &#039;active&#039; =&amp;gt; true, &lt;br /&gt;
                             &#039;locale&#039; =&amp;gt; &#039;de_DE&#039;, &lt;br /&gt;
                             &#039;date_format_type&#039; =&amp;gt; &#039;E&#039;, &lt;br /&gt;
                             &#039;email_ok&#039; =&amp;gt; date(&#039;Y-m-d&#039;) &lt;br /&gt;
                           ); &lt;br /&gt;
^D&lt;br /&gt;
&amp;lt;/nowiki&amp;gt;&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Fast-CGI-Patch ===&lt;br /&gt;
&lt;br /&gt;
Bei der Benutzung von Fast-CGI werden die HTTP_AUTHORIZATION-Zeilen der HTTP-Anfragen  normalerweise nicht weitergeleitet. Dieses Problem wird auch im DAViCal-Wiki in einem entsprechenden [http://wiki.davical.org/w/FastCGI FAQ-Eintrag] behandelt. Die dort angeführte Lösung beruht allerdings wieder einmal auf der Annahme, daß man Superuser-Rechte hat.&lt;br /&gt;
&lt;br /&gt;
In der Shared-Hosting-Umgebung von Hostsharing kann die notwendige Anpassung über eine Rewrite-Anweisung in der &amp;lt;tt&amp;gt;.htaccess&amp;lt;/tt&amp;gt;-Datei gemacht werden:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&amp;lt;nowiki&amp;gt;&lt;br /&gt;
$ cd ~/doms/cal.example.org/var/davical/htdocs&lt;br /&gt;
$ cat &amp;gt;&amp;gt; .htaccess&lt;br /&gt;
RewriteEngine On&lt;br /&gt;
RewriteRule .* - [E=HTTP_AUTHORIZATION:%{HTTP:Authorization},L]&lt;br /&gt;
^D&lt;br /&gt;
&amp;lt;/nowiki&amp;gt;&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Zur Zeit enthält die mit DAViCal mitgelieferte Datei &amp;lt;tt&amp;gt;.htaccess&amp;lt;/tt&amp;gt; nur auskommentierte Beispielanweisungen. Für alle Fälle sollte man aber darauf achten, daß man den bestehenden Inhalt von &amp;lt;tt&amp;gt;.htaccess&amp;lt;/tt&amp;gt; nicht überschreibt: d.h. die neuen Eingaben mit &amp;lt;tt&amp;gt;&amp;gt;&amp;gt;&amp;lt;/tt&amp;gt; der bestehenden Datei &#039;&#039;&#039;anhängen&#039;&#039;&#039;. Die neue Rewrite-Regel muß die letzte Regel in der &amp;lt;tt&amp;gt;.htaccess&amp;lt;/tt&amp;gt; sein. Die Datei muß zudem für Apache lesbar sein:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&amp;lt;nowiki&amp;gt;&lt;br /&gt;
$ chmod 0644 .htaccess&lt;br /&gt;
&amp;lt;/nowiki&amp;gt;&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Darüberhinaus muß noch die Datei &amp;lt;tt&amp;gt;davical/inc/HTTPAuthSession.php&amp;lt;/tt&amp;gt; angepasst werden. Hier ist die Variable &amp;lt;tt&amp;gt;$_SERVER[&amp;quot;AUTHORIZATION&amp;quot;]&amp;lt;/tt&amp;gt; ersetzt werden durch &amp;lt;tt&amp;gt;$_SERVER[&amp;quot;REDIRECT_HTTP_AUTHORIZATION&amp;quot;]&amp;lt;/tt&amp;gt;. Außerdem gibt es noch einen Bug: Es wird an einer Stelle &amp;lt;tt&amp;gt;split()&amp;lt;/tt&amp;gt; statt &amp;lt;tt&amp;gt;explode&amp;lt;/tt&amp;gt; benutzt. &amp;lt;tt&amp;gt;split()&amp;lt;/tt&amp;gt; ist seit PHP 5.3.0 &#039;&#039;deprecated&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
 @@ -101,10 +101,10 @@&lt;br /&gt;
      /**&lt;br /&gt;
      * Get HTTP Auth to work with PHP+FastCGI&lt;br /&gt;
      */&lt;br /&gt;
      if ( !isset($_SERVER[&#039;AUTHORIZATION&#039;]) &amp;amp;&amp;amp; isset($_SERVER[&#039;HTTP_AUTHORIZATION&#039;]) &amp;amp;&amp;amp; !empty($_SERVER[&#039;HTTP_AUTHORIZATION&#039;]))&lt;br /&gt;
        $_SERVER[&#039;AUTHORIZATION&#039;] = $_SERVER[&#039;HTTP_AUTHORIZATION&#039;];&lt;br /&gt;
 &amp;lt;span style=&amp;quot;background-color:lightsalmon&amp;quot;&amp;gt;-    if (isset($_SERVER[&amp;quot;&amp;lt;span style=&amp;quot;color:red&amp;quot;&amp;gt;AUTHORIZATION&amp;lt;/span&amp;gt;&amp;quot;]) &amp;amp;&amp;amp; !empty($_SERVER[&amp;quot;&amp;lt;span style=&amp;quot;color:red&amp;quot;&amp;gt;AUTHORIZATION&amp;lt;/span&amp;gt;&amp;quot;])) {&amp;lt;/span&amp;gt;&lt;br /&gt;
 &amp;lt;span style=&amp;quot;background-color:lightsalmon&amp;quot;&amp;gt;-      list ($type, $cred) = &amp;lt;span style=&amp;quot;color:red&amp;quot;&amp;gt;split&amp;lt;/span&amp;gt; (&amp;quot; &amp;quot;, $_SERVER[&#039;&amp;lt;span style=&amp;quot;color:red&amp;quot;&amp;gt;AUTHORIZATION&amp;lt;/span&amp;gt;&#039;]);&amp;lt;/span&amp;gt;&lt;br /&gt;
 &amp;lt;span style=&amp;quot;background-color:lightgreen&amp;quot;&amp;gt;+    if (isset($_SERVER[&amp;quot;&amp;lt;span style=&amp;quot;color:green&amp;quot;&amp;gt;REDIRECT_HTTP_AUTHORIZATION&amp;lt;/span&amp;gt;&amp;quot;]) &amp;amp;&amp;amp; !empty($_SERVER[&amp;quot;&amp;lt;span style=&amp;quot;color:green&amp;quot;&amp;gt;REDIRECT_HTTP_AUTHORIZATION&amp;lt;/span&amp;gt;&amp;quot;])) {&amp;lt;/span&amp;gt;&lt;br /&gt;
 &amp;lt;span style=&amp;quot;background-color:lightgreen&amp;quot;&amp;gt;+      list ($type, $cred) = &amp;lt;span style=&amp;quot;color:green&amp;quot;&amp;gt;explode&amp;lt;/span&amp;gt; (&amp;quot; &amp;quot;, $_SERVER[&#039;&amp;lt;span style=&amp;quot;color:green&amp;quot;&amp;gt;REDIRECT_HTTP_AUTHORIZATION&amp;lt;/span&amp;gt;&#039;]);&amp;lt;/span&amp;gt;&lt;br /&gt;
        if ($type == &#039;Basic&#039;) {&lt;br /&gt;
          list ($user, $pass) = explode (&amp;quot;:&amp;quot;, base64_decode($cred));&lt;br /&gt;
          $_SERVER[&#039;PHP_AUTH_USER&#039;] = $user;                                                                                                    }&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Webspace aktivieren ===&lt;br /&gt;
&lt;br /&gt;
Schließlich muß die Installation noch mit dem Webspace verknüpft werden.&lt;br /&gt;
&amp;lt;pre&amp;gt;&amp;lt;nowiki&amp;gt;&lt;br /&gt;
$ cd ~/doms/cal.example.org&lt;br /&gt;
$ rm -r htdocs-ssl&lt;br /&gt;
$ ln -s var/davical/htdocs htdocs-ssl&lt;br /&gt;
&amp;lt;/nowiki&amp;gt;&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[Bild:DAViCAl-home.png‎|miniatur|400px|right|Die Login-Seite der DAViCal-Web-Oberfläche]]&lt;br /&gt;
&lt;br /&gt;
Die URL des User-Interfaces lautet jetzt &#039;&#039;&#039;&amp;lt;tt&amp;gt;&amp;lt;nowiki&amp;gt;https://cal.example.org/&amp;lt;/nowiki&amp;gt;&amp;lt;/tt&amp;gt;&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
Wenn alles richtig gemacht wurde, erscheint an dieser URL die Login-Seite.&lt;br /&gt;
&lt;br /&gt;
Falls nicht, sorge mit &amp;lt;tt&amp;gt;chmod a+rx var/davical/htdocs&amp;lt;/tt&amp;gt; dafür, daß das Verzeichnis für Apache lesbar ist, und kontrolliere notfalls auch die Rechte der darin befindlichen Dateien.&lt;br /&gt;
&lt;br /&gt;
== Nutzung ==&lt;br /&gt;
&lt;br /&gt;
=== User anlegen und konfigurieren ===&lt;br /&gt;
&lt;br /&gt;
Im User-Interface muß man sich als Admin (oder Nutzer mit Adminrechten) einloggen um neue Nutzer anzulegen.&lt;br /&gt;
&lt;br /&gt;
Um einen neuen Nutzer anzulegen: &#039;&#039;&#039;Menu&#039;&#039;&#039; &amp;amp;rarr; &#039;&#039;&#039;User Functions&#039;&#039;&#039; &amp;amp;rarr; &#039;&#039;&#039;Create Principal&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|- class=&amp;quot;hintergrundfarbe5&amp;quot;&lt;br /&gt;
! Feld                                          !! Wert                                !! Beschreibung&lt;br /&gt;
|-&lt;br /&gt;
| Principal ID || &#039;&#039;New Principal&#039;&#039;  || Bei neuen Nutzern wird das Feld automatisch beim Anlegen gefüllt&lt;br /&gt;
|-&lt;br /&gt;
| Username || hans || Nutzername für den Kalender. Der Username ist Bestandteil der Kalender-URL&lt;br /&gt;
|-&lt;br /&gt;
| Change Password || geheimespasswort || &lt;br /&gt;
|-&lt;br /&gt;
| Confirm Password || geheimespasswort || &lt;br /&gt;
|-&lt;br /&gt;
| Fullname || Hans Meier || Der Name des Nutzers&lt;br /&gt;
|-&lt;br /&gt;
| Email Address || hans@example.org || Über die E-Mail-Adresse ist der Nutzer für andere Nutzer im System zu finden, z.B. für Einladungen&lt;br /&gt;
|-&lt;br /&gt;
| Locale || Deutsch || &lt;br /&gt;
|-&lt;br /&gt;
| Date Format Style || European || &lt;br /&gt;
|-&lt;br /&gt;
| Principal Type || Person || Üblicherweise Person für einen natürlichen Nutzer (hier können auch Ressourcen und Gruppen angelegt werden)&lt;br /&gt;
|-&lt;br /&gt;
| Administrator || &amp;amp;ndash; || Falls der User Adminrechte bekommen soll&lt;br /&gt;
|-&lt;br /&gt;
| Active || X || Soll der Nutzer aktiv geführt werden?&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Beim Anlegen des &#039;&#039;&#039;ersten&#039;&#039;&#039; Nutzers erscheint eine Fehlermeldung: &lt;br /&gt;
&lt;br /&gt;
 &amp;lt;span style=&amp;quot;background-color:lightsalmon&amp;quot;&amp;gt;ERROR: SQL error &amp;quot;23505&amp;quot; - ERROR: duplicate key value violates unique constraint &amp;quot;principal_pkey&amp;quot;&amp;quot; &lt;br /&gt;
 Home calendar added. &amp;lt;/span&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Dies ist ein Bug. Siehe auch [http://lists.morphoss.com/pipermail/davical-dev/2011/000117.html Thread in Dev-Mailingliste].&lt;br /&gt;
&lt;br /&gt;
Zum Umgehen des Bugs einfach den Nutzer nochmal anlegen und dann funktioniert alles ;-)&lt;br /&gt;
&lt;br /&gt;
=== Zugriff über Client-Programme ===&lt;br /&gt;
&lt;br /&gt;
Der Zugriff auf den Kalender erfolgt über die URL: &#039;&#039;&#039;&amp;lt;tt&amp;gt;&amp;lt;nowiki&amp;gt;https://cal.example.org/caldav.php/user/home&amp;lt;/nowiki&amp;gt;&amp;lt;/tt&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
* user = Name des angelegte Nutzers, also z.B. &#039;&#039;&#039;&amp;lt;tt&amp;gt;hans&amp;lt;/tt&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
* home = Name des angelegten Kalenders; dies ist standardmäßig &#039;&#039;&#039;&amp;lt;tt&amp;gt;home&amp;lt;/tt&amp;gt;&#039;&#039;&#039;. Andere Kalender (&#039;&#039;collection&#039;&#039;) können im User-Interface vom Nutzer angelegt werden, oder durch einen Client, der MKCALENDAR implementiert hat, so z.B. iCal oder Mulberry&lt;br /&gt;
&lt;br /&gt;
==== Beispiel Thunderbird ====&lt;br /&gt;
&lt;br /&gt;
Ist in Thunderbird die Lightning-Erweiterung installiert, dann kann der Kalender folgendermaßen eingerichtet werden:&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Menu&#039;&#039;&#039; &amp;amp;rarr; &#039;&#039;&#039;Datei&#039;&#039;&#039; &amp;amp;rarr; &#039;&#039;&#039;Neu&#039;&#039;&#039; &amp;amp;rarr; &#039;&#039;&#039;Kalender&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Auf den Folgenden Seiten ist auszuwählen:&lt;br /&gt;
* &#039;&#039;Im Netzwerk&#039;&#039;&lt;br /&gt;
* &#039;&#039;CalDAV&#039;&#039;&lt;br /&gt;
* Spezifische Angaben&lt;br /&gt;
** Name: z.B. &#039;&#039;hans@example&#039;&#039;&lt;br /&gt;
** Farbe: auswählen in welcher Farbe der Kalender angezeigt werden soll&lt;br /&gt;
** Alarm: ja&lt;br /&gt;
** Email: E-Mail auswählen&lt;br /&gt;
&lt;br /&gt;
Zusätzlich wird es wahrscheinlich noch eine Wahrnung geben, daß das SSL-Zertifikat ungültig ist, da in der Standard Hostsharing Konfiguration das hostsharing-Zertifikat ausgeliefert wird. Dieses muß dann noch importiert und akzeptiert werden.&lt;br /&gt;
&lt;br /&gt;
Thunderbird fragt dann noch nach Nuternamen und Passwort und wenn man erlaubt diese im Programm zu speichern, dann loggt sich Thunderbird zukünfitg selbständig ein.&lt;br /&gt;
&lt;br /&gt;
===== Mehrere Kalender auf gleichem Server =====&lt;br /&gt;
&lt;br /&gt;
Hat man mehrere Kalender auf dem gleichen Server &amp;amp;ndash; also z.B. mehrere User oder für einen User mehrere &#039;&#039;collections&#039;&#039;, dann kann Thunderbird diese nicht unterscheiden. Der Passwort-Manager arbeitet auf Grundlage der Domain. Siehe auch [https://bugzilla.mozilla.org/show_bug.cgi?id=247486 Bugzilla].&lt;br /&gt;
&lt;br /&gt;
Diesen Bug kann man relativ einfach umgehen, indem man weitere Subdomains anlegt, die auf die gleiche Installation verweisen, also z.B.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&amp;lt;nowiki&amp;gt;&lt;br /&gt;
$ cd /home/doms/example.org/subs-ssl&lt;br /&gt;
$ mkdir cal1&lt;br /&gt;
$ mkdir cal2&lt;br /&gt;
&amp;lt;/nowiki&amp;gt;&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
und jeweils eine &amp;lt;tt&amp;gt;.htaccess&amp;lt;/tt&amp;gt; in die neuen Verzeichnis mit folgendem Inhalt schreibt:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&amp;lt;nowiki&amp;gt;&lt;br /&gt;
RewriteEngine on&lt;br /&gt;
RewriteRule ^.htaccess$ - [F]&lt;br /&gt;
RewriteRule ^(.*)$ https://cal.example.org/$1 [P]&lt;br /&gt;
&amp;lt;/nowiki&amp;gt;&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Nicht vergessen:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&amp;lt;nowiki&amp;gt;&lt;br /&gt;
chmod 0644 cal1/.htaccess&lt;br /&gt;
chmod 0644 cal2/.htaccess&lt;br /&gt;
&amp;lt;/nowiki&amp;gt;&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Hat man z.B. für User &amp;lt;tt&amp;gt;hans&amp;lt;/tt&amp;gt; die Kalender &amp;lt;tt&amp;gt;home&amp;lt;/tt&amp;gt; und &amp;lt;tt&amp;gt;work&amp;lt;/tt&amp;gt; und für User &amp;lt;tt&amp;gt;maria&amp;lt;/tt&amp;gt; den Kalender &amp;lt;tt&amp;gt;home&amp;lt;/tt&amp;gt; und möchte diese aus derselben Thunderbird-Instanz benutzen, können folgende URL&#039;s in Thundebrird konfiguriert werden:&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;&amp;lt;tt&amp;gt;&amp;lt;nowiki&amp;gt;https://cal.example.org/caldav.php/hans/home&amp;lt;/nowiki&amp;gt;&amp;lt;/tt&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
* &#039;&#039;&#039;&amp;lt;tt&amp;gt;&amp;lt;nowiki&amp;gt;https://cal1.example.org/caldav.php/hans/work&amp;lt;/nowiki&amp;gt;&amp;lt;/tt&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
* &#039;&#039;&#039;&amp;lt;tt&amp;gt;&amp;lt;nowiki&amp;gt;https://cal2.example.org/caldav.php/maria/home&amp;lt;/nowiki&amp;gt;&amp;lt;/tt&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
== URL Rewriting für kürzere URL&#039;s ==&lt;br /&gt;
&lt;br /&gt;
TODO: .htaccess Beispiel&lt;br /&gt;
&lt;br /&gt;
== Weiterführende Links ==&lt;br /&gt;
&lt;br /&gt;
* WIKI von DAViCal: http://wiki.davical.org&lt;br /&gt;
** [http://wiki.davical.org/w/CalDAV_Clients CalDAV Clients]&lt;br /&gt;
&lt;br /&gt;
* Alternativen&lt;br /&gt;
** [[RadicaleCalDAVServer]]&lt;br /&gt;
** [[ChandlerServer]]&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
[[Kategorie:HSDoku]]&lt;br /&gt;
[[Kategorie:Installationsanleitungen]]&lt;br /&gt;
[[Kategorie:CalDAV]]&lt;/div&gt;</summary>
		<author><name>Apc00-tony</name></author>
	</entry>
	<entry>
		<id>https://wiki.hostsharing.net/index.php?title=Benutzer:Apc00-tony/Dynamisches_DNS&amp;diff=6414</id>
		<title>Benutzer:Apc00-tony/Dynamisches DNS</title>
		<link rel="alternate" type="text/html" href="https://wiki.hostsharing.net/index.php?title=Benutzer:Apc00-tony/Dynamisches_DNS&amp;diff=6414"/>
		<updated>2024-02-08T19:12:40Z</updated>

		<summary type="html">&lt;p&gt;Apc00-tony: Veraltet-tag bei Adminsitration&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Update 2023: Ich habe die Verwaltung über Befehlszeile durch eine PHP-Web-Oberfläche ersetzt; Details irgendwo ... ah, [https://ddns.crawfords.de/verwaltung/ddnsadminhints?name=acanthus_crawford_berlin hier]. Meine Hostsharing-DDNS-Lösung läuft übrigens schon lange einwandfrei; ich benutze sie dazu, ein VPN zwischen meinen Fritz!Box-LANS zu Hause und im Büro zu realisieren sowie um auf ein Backup- und Music-Server (ein Raspberry Pi) zu Hause von unterwegs zuzugreifen.&lt;br /&gt;
&lt;br /&gt;
((Provisorischer Vorspann: Auf Grund einer Mailing-Listen-Diskussion habe ich angefangen, Dynamisches DNS über einen CGI-Skript bei Hostsharing zu realisieren. Meine Lösung habe ich dann vorgestellt; sie wurde für nicht ausreichend selbsterklärend befunden und fand wenig Akzeptanz. Hier also der Versuch, die Sache zu dokumentieren.))&lt;br /&gt;
&lt;br /&gt;
Mit der regelmäßigen Aufnahme von benutzerspezifischen Zonefiles in seiner DNS-Konfiguration bietet  Hostsharing alles, was man braucht, um &amp;amp;bdquo;dynamisches DNS&amp;amp;ldquo; in Eigenregie zu realisieren.&lt;br /&gt;
&lt;br /&gt;
Das heißt, wenn ich mindestens eine Domain bei Hostsharing verwalte, und mindestens eine Einwahlverbindung (oder DSL-Verbindung) ins Internet mit wechselnder IP-Adresse über irgendeinen ISP für meinen Arbeitsplatzrechner zu Hause betreibe, dann kann ich dem Arbeitsplatzrechner über die DNS-Server von Hostsharing einen vollqualifizieren Domainnamen zuweisen, der der jeweiligen IP-Adresse meiner Einwahlleitung zugeordnet ist.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
(ASCII-Art-Diagramm der beschriebenen Konstellation)&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Im Folgenden wird eine real existierende Implementierung von Dynamischem DNS (&amp;amp;bdquo;DDNS&amp;amp;ldquo;) beschrieben. Die verschiedenen Elemente könnten durchaus anders realisiert werden; die beschriebene Implementierung könnte durchaus verbessert werden. Sie dient hier der Illustration.&lt;br /&gt;
&lt;br /&gt;
In der folgenden Beschreibung werden diese Beispielwerte benutzt:&lt;br /&gt;
* Ein Hostsharing-Mitglied hat ein Account als Paket-Admin mit Kennung xyz00.&lt;br /&gt;
* Im Paket xyz00 gibt es einen Domain-Admin namens xyz00-benutzername.&lt;br /&gt;
* Dieser Domain-Admin verwaltet bei Hostsharing die Domains example.com und beispiel.de.&lt;br /&gt;
* Ein Benutzer hat zu Hause (oder im Büro) einen Arbeitsplatzrechner hinter der marktüblichen DSL-Leitung, die von seinem ISP bereitgestellt wird.&lt;br /&gt;
* Dieser Arbeitsplatzrechner (oder der Router, der seine Internetverbindung steuert) bekommt vom ISP immer wechselnde IP-Adressen zugewiesen.&lt;br /&gt;
* Dennoch möchte der Benutzer seinen Arbeitsplatzrechner aus dem Internet unter dem Hostnamen einwahl.example.com ansprechen können.&lt;br /&gt;
&lt;br /&gt;
Dazu kann ein System wie Hostsharing, das authoritative DNS-Informationen für viele Domains bereitstellt, auch veränderliche DNS-Information über dynamisch verbundene Rechner verwalten &amp;amp;ndash; sofern das ressourcenschonend gemacht werden kann ohne andere Funktionen zu stören.&lt;br /&gt;
&lt;br /&gt;
== Aufgaben des Servers ==&lt;br /&gt;
&lt;br /&gt;
Um einem Rechner mit wechselnder IP-Adresse einen DDNS-Eintrag zu bieten, muß der Hostsharing-Server folgendes leisten (in ungefährer Reihenfolge der Ereignisse):&lt;br /&gt;
&lt;br /&gt;
# Eine Anfrage entgegennehmen, beispielsweise über HTTPS, von einem entfernten Rechner, der einen DNS-Eintrag für seine momentane IP-Adresse wünscht. &lt;br /&gt;
# Prüfen, ob die Anfrage einen berechtigten DDNS-Dienst-Usernamen mit zugehörigem Paßwort enthält.&lt;br /&gt;
# Prüfen, ob die Anfrage einen gültigen Domainnamen betrifft, den der Server bieten darf.&lt;br /&gt;
# Prüfen, ob die Domain example.com demselben Benutzer gehört, unter dessen Namen der Dynamisches-DNS-Server läuft.&lt;br /&gt;
# Eine gültige [[Zonefile]] mit &amp;amp;ndash; neben dem bisherigen Inhalt &amp;amp;ndash; einem A-Eintrag für einwahl.example.com in /home/pacs/xyz00/users/benutzername/doms/example.com/pri.example.com schreiben.&lt;br /&gt;
# Dem Client eine Bestätigung oder ggf. eine Fehlermeldung als Antwort senden.&lt;br /&gt;
# In irgendeiner Datenbank den momentan eingestellter Status all seiner DDNS-Einträge speichern.&lt;br /&gt;
# In einer Logdatei protokollieren, daß obiges getan wurde, oder ggf. welche Fehler traten auf.&lt;br /&gt;
&lt;br /&gt;
== Aufgaben des Clients ==&lt;br /&gt;
Bevor ich anfange, meinen Arbeitsplatzrechner so zu konfigurieren, daß er bei welchem Server auch immer einen DDNS-Eintrag anfordert, muß ich mich als verantwortlicher Benutzer dieses Rechners und der dazugehörigen Internetverbindung &amp;amp;ndash; das heißt, als Mensch &amp;amp;ndash; mit dem Betreiber des dynamisches-DNS-Servers vereinbaren, daß ich das darf und welchen Eintrag ich bekommen kann. Im Folgenden wird vorausgesetzt, daß solche Vereinbarungen getroffen und die Parameter geklärt wurden.&lt;br /&gt;
&lt;br /&gt;
Der DDNS-Client muß aus Server-Sicht nur wenig leisten:&lt;br /&gt;
&lt;br /&gt;
# Eine Anfrage senden, beispielsweise über HTTPS, an einen entfernten Rechner, der einen Eintrag ins DNS für die momentane IP-Adresse des Clients vornehmen kann.&amp;lt;br /&amp;gt;Diese Anfrage muß einem festgelegten Format entsprechen und muß gültige Werte für die Authorisation des Clients, den gewünschten Domainnamen, und eventuell andere Parameter enthalten.&lt;br /&gt;
# Eine Antwort des Servers entgegennehmen und als Erfolgs- oder Fehlermeldung auswerten.&lt;br /&gt;
# Von überflüssigen Anfragen absehen: das heißt bei Erfolg, nicht wiederholt den gleichen Eintrag erneut wünschen; bei Fehlern, nicht die gleiche fehlerhafte Anfrage erneut schicken.&lt;br /&gt;
&lt;br /&gt;
== Kommunikation zwischen Client und Server ==&lt;br /&gt;
&lt;br /&gt;
Ein einziges Nachrichtenpaar von Anfrage und Antwort genügt, um einen DDNS-Eintrag einzurichten: Der Client teilt die IP-Adresse und den Domainnamen mit, die in einem DNS-Eintrag verbunden werden sollen; der Server bestätigt den Auftrag.&lt;br /&gt;
&lt;br /&gt;
In der Beispielimplementierung erfolgt die Kommunikation über HTTP, und die Anfrage des Clients könnte so aussehen:&lt;br /&gt;
&lt;br /&gt;
  GET /cgi-bin/ddns?hostname=einwahl.example.com&amp;amp;myip=87.65.43.21 HTTP/1.1&lt;br /&gt;
  Host: ddns.beispiel.de&lt;br /&gt;
  User-Agent: Fritz!Box DDNS/1.0.1&lt;br /&gt;
  Authorization: Basic QWxhZGRpbjpvcGVuIHNlc2FtZQ==&lt;br /&gt;
&lt;br /&gt;
Bei Erhalt dieser Anfrage ruft Apache das CGI-Programm .../doms/ddns.beispiel.de/cgi-ssl/ddns auf. Das Fragezeichen trennt den Programmnamen von einem &amp;quot;Query-String&amp;quot;, in dem zwei Metavariablen definiert und übergeben werden. Die erste Metavariable, hostname, hat den Wert &amp;quot;einwahl.example.com&amp;quot;; die zweite, myip, hat den Wert &amp;quot;87.65.43.21&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
Das Server-Programm, hier &#039;&#039;ddns&#039;&#039;, prüft diese Informationen auf Form und Berechtigung, und schreibt gegebenenfalls einen entsprechenden Eintrag in einer Zonefile. Es schreibt auch verschiedene Informationen in die Standardausgabe. Wenn es die Standardausgabe geschlossen wird &amp;amp;ndash; also spätestens bei Programmende &amp;amp;ndash; schickt Apache diese Informationen als Antwort an den anfragenden Rechner zurück.&lt;br /&gt;
&lt;br /&gt;
Im Falle unserer Beispielimplementierung sieht die Antwort bei Erfolg so aus: &lt;br /&gt;
&lt;br /&gt;
  HTTP/1.1 200 OK&lt;br /&gt;
  Date: Wed, 22 Apr 2020 08:35:15 GMT&lt;br /&gt;
  Server: Apache&lt;br /&gt;
  Content-Length: 17&lt;br /&gt;
  Content-Type: text/plain; charset=ISO-8859-1&lt;br /&gt;
 &lt;br /&gt;
  good 87.65.43.21&lt;br /&gt;
&lt;br /&gt;
=== Das DDNS-Protokoll von DynDNS.org ===&lt;br /&gt;
&lt;br /&gt;
In den 90er Jahren, bevor das Internet so durchgehend vergeschäftlicht wurde, boten einige Organisationen kostenlose DDNS-Dienste an. Ein sehr beliebtes Angebot war das von DynDNS.org. Das DDNS-Protokoll von diesem Dienst wurde sogar in Einwahl-Routern einprogrammiert und der Dienst wurde von ISPs und Router-Herstellern als Leistungsmerkmal beworben.&lt;br /&gt;
&lt;br /&gt;
DynDNS.org gehört inzwischen Oracle und bietet keine kostenlose Dienste mehr. Dennoch wird das DDNS-Protokoll von DynDNS.org in der vorliegenden Beispielimplementierung übernommen in der Hoffnung, daß die Kompatibilität mit einigen gängigen Einwahl-Routern von Vorteil sein kann. Es gibt noch eine kurze Online-Dokumentation der [https://help.dyn.com/remote-access-api/perform-update/ Anfrage] und [https://help.dyn.com/remote-access-api/perform-update/ Antwortnachrichten].&lt;br /&gt;
&lt;br /&gt;
Das gesammte Protokoll sieht einen einzigen Nachrichtenaustausch aus Anfrage und Antwort vor. Die Anfrage kann mehrere Argumente enthalten; die Antwort kann verschiedene Code-Wörtern enthalten. Übrigens können in einer einzigen Anfrage mehrere DNS-Einträge gewünscht werden. In diesem Fall kann die Antwort mehrzeilig ausfallen.&lt;br /&gt;
&lt;br /&gt;
Das Verhalten von Server und Client bei künftigen Kommunikationsvorgängen wird unter Umständen von vorangegangenen Kommunikationsergebnissen beeinflußt: nach wiederholten fehlerhaften oder redundanten Anfragen kann der Server weitere Anfragen des Benutzers verweigern; nach wiederholten Fehlermeldungen sollte ein Client aufhören, immer dieselbe Anfrage zu schicken. Und für den Fall, daß mehrere Clients dynamische DNS-Einträge in derselben Domain example.com bestellen, muß der Server den Stand aller Client-Einträge intern speichern, damit er nicht mit einer neuen Zonefile einen früher erstellten Eintrag löscht. Zu diesen Fragen siehe den Abschnitt &#039;&#039;&#039;[[#Sukzessive_Kommunikationsabläufe]]&#039;&#039;&#039; nach der Beschreibung von Anfragen und Antworten unten.&lt;br /&gt;
&lt;br /&gt;
====Anfrage====&lt;br /&gt;
&lt;br /&gt;
Die Anfrage in Form eines URL übergibt dem DDNS-Programm in einem &#039;Query-String&#039; einige Metavariablen. Das heißt, in einem URL der Form&lt;br /&gt;
&lt;br /&gt;
  &amp;lt;nowiki&amp;gt;https://benutzername:passwort@ddns.beisiel.de/cgi-bin/ddns?hostname=einwahl.example.com&amp;amp;myip=87.65.43.21&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
signalisert das Fragezeichen, daß ein Query-String folgt. In einem solchen Query-String können in der Beispielimplementierung folgende Metavariablen definiert werden:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|- class=&amp;quot;hintergrundfarbe5&amp;quot;&lt;br /&gt;
! Variable !! Beispiel !! Bemerkungen&lt;br /&gt;
|-&lt;br /&gt;
| hostname || &amp;lt;tt&amp;gt;hostname=einwahl.example.com&amp;lt;/tt&amp;gt;&amp;lt;br /&amp;gt;&amp;lt;div style=&amp;quot;font-size:smaller;&amp;quot;&amp;gt;&amp;lt;tt&amp;gt;hostname=eins.example.com,zwei.example.com[,...]&amp;lt;/tt&amp;gt;&amp;lt;/div&amp;gt; ||&lt;br /&gt;
Muß ein vollständig qualifizierter Domain-Name (&amp;quot;FQDN&amp;quot;) sein; &amp;lt;tt&amp;gt;example.com&amp;lt;/tt&amp;gt; muß eine vom Besitzer des DDNS-Programms verwaltete Domain sein. Genaugenommen kann der Wert eine durch Kommata gegliederte Liste mehrerer gültiger Domainnamen sein, falls mehrere Einträge mit derselben IP-Adresse gewünscht werden.&lt;br /&gt;
|-&lt;br /&gt;
| myip || &amp;lt;tt&amp;gt;myip=87.65.43.21&amp;lt;/tt&amp;gt;||&lt;br /&gt;
Kann entfallen; kann vom Server ignoriert werden. Maßgeblich ist dann die IP-Adresse des Absenders, wie sie vom Web-Server mitgeteilt wird.&lt;br /&gt;
|-&lt;br /&gt;
| mx || &amp;lt;tt&amp;gt;mx=87.65.43.21&amp;lt;/tt&amp;gt;&amp;lt;br /&amp;gt;&amp;lt;tt&amp;gt;mx=NOCHG&amp;lt;/tt&amp;gt;&amp;lt;br /&amp;gt; ||&lt;br /&gt;
Neben dem A-Eintrag möchte der Client auch einen MX-Eintrag. Der Wert &amp;lt;tt&amp;gt;NOCHG&amp;lt;/tt&amp;gt; (für &amp;amp;bdquo;no change&amp;amp;ldquo;) bedeutet, der bestehende MX-Eintrag (oder seine Abwesenheit) soll nicht geändert werden. &lt;br /&gt;
|-&lt;br /&gt;
| backmx || &amp;lt;tt&amp;gt;backmx=YES&amp;lt;/tt&amp;gt;&amp;lt;br /&amp;gt;&amp;lt;tt&amp;gt;backmx=NOCHG&amp;lt;/tt&amp;gt;&amp;lt;br /&amp;gt;&amp;lt;tt&amp;gt;backmx=NO&amp;lt;/tt&amp;gt;   ||&lt;br /&gt;
Falls &amp;lt;tt&amp;gt;YES&amp;lt;/tt&amp;gt;, wird ein zweiter MX-Eintrag erzeugt, der &amp;lt;tt&amp;gt;einwahl.example.com&amp;lt;/tt&amp;gt; als Mail-Server für &amp;lt;tt&amp;gt;einwahl.example.com&amp;lt;/tt&amp;gt; nennt. Dieser Eintrag hat eine niedrigere Präferenzzahl (also eine höhere Priorität) als der mit &amp;lt;tt&amp;gt;mx&amp;lt;/tt&amp;gt; angeforderten Eintrag.&lt;br /&gt;
|-&lt;br /&gt;
| wildcard || &amp;lt;tt&amp;gt;wildcard=ON&amp;lt;/tt&amp;gt;&amp;lt;br /&amp;gt;&amp;lt;tt&amp;gt;wildcard=NOCHG&amp;lt;/tt&amp;gt;&amp;lt;br /&amp;gt;&amp;lt;tt&amp;gt;wildcard=OFF&amp;lt;/tt&amp;gt; ||&lt;br /&gt;
Neben dem A-Eintrag für den Domainnamen &amp;lt;tt&amp;gt;einwahl.example.com&amp;lt;/tt&amp;gt; wünscht der Client auch einen Eintrag für beliebige Subdomains, also &amp;lt;tt&amp;gt;*.einwahl.example.com&amp;lt;/tt&amp;gt;, mit der gleichen IP-Adresse.&lt;br /&gt;
|-&lt;br /&gt;
| offline ||&amp;lt;tt&amp;gt;offline=YES&amp;lt;/tt&amp;gt;&amp;lt;br /&amp;gt;&amp;lt;tt&amp;gt;offline=NOCHG&amp;lt;/tt&amp;gt;||&lt;br /&gt;
Falls &amp;lt;tt&amp;gt;YES&amp;lt;/tt&amp;gt;, wird ein DNS-Eintrag für &amp;lt;tt&amp;gt;einwahl.example.com&amp;lt;/tt&amp;gt; aus der Zonefile getilgt. Gegebenenfalls wird der Hostname dann auf Grund eines parallelen Wildcard-Eintrags für &amp;lt;tt&amp;gt;*.example.com&amp;lt;/tt&amp;gt; einer anderen IP-Adresse zugeordnet werden.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;!-- IPv6? --&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Alle Parameter bis auf hostname können entfallen. Bei nichtdokumentierten Argumenten ist das Verhalten undefiniert&amp;amp;trade;.&lt;br /&gt;
&lt;br /&gt;
====Antwort====&lt;br /&gt;
&lt;br /&gt;
Die Antwort auf eine erfolgreiche HTTP-Anfrage besteht im häufigsten Fall aus einigen Header-Zeilen, gefolgt vom Inhalt der gewünschten Text- oder andere Datei. Ein Status-Code in der ersten Header-Zeile gibt an, ob die Anfrage bedient werden kann oder kreist andernfalls den Grund für die Enttäuschung ein.&lt;br /&gt;
&lt;br /&gt;
Die vorliegende Beispielimplementierung von DDNS schickt einen der üblichen HTTP-Status-Codes &amp;quot;200 OK&amp;quot; oder &amp;quot;500 Internal Server Error&amp;quot;, gefolgt von einer kurzen Textnachricht nach dem HTTP-Header. Bei diesem Programm  ist &amp;amp;ndash; laut Gebrauchshinweise von DynDNS.org &amp;amp;ndash; &#039;&#039;nicht&#039;&#039; der Status-Code im Header, sondern der Inhalt der Nachricht  die definierte, maßgebliche Ergebnismeldung des Programms.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|- class=&amp;quot;hintergrundfarbe5&amp;quot;&lt;br /&gt;
! Meldung !! Bedeutung !! Bemerkungen&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;good&amp;amp;nbsp;&amp;amp;lt;IP&amp;amp;nbsp;number&amp;amp;gt;&amp;lt;/tt&amp;gt; ||&lt;br /&gt;
Der gewünschte DNS-Eintrag wurde erfolgreich in einer Zonefile eingetragen. &lt;br /&gt;
|| Es kann natürlich noch einige Minuten dauern, bis die Zonefile vom Hostsharing-Roboter abgelesen wird und der Inhalt in die BIND-Konfiguration übernommen.&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;good&amp;amp;nbsp;0.0.0.0&amp;lt;/tt&amp;gt; ||&lt;br /&gt;
Das Argument &amp;lt;tt&amp;gt;offline=YES&amp;lt;/tt&amp;gt; wurde empfangen und verarbeitet.&lt;br /&gt;
|| Der Domainname hat also keinen dynamischen DNS-Eintrag mehr.&lt;br /&gt;
|-&lt;br /&gt;
&amp;lt;!-- We don&#039;t do this!&lt;br /&gt;
| &amp;lt;tt&amp;gt;good&amp;amp;nbsp;127.0.0.1&amp;lt;/tt&amp;gt; ||&lt;br /&gt;
Die Anfrage entsprach nicht den Erfordernissen des Servers.&lt;br /&gt;
|| Trotz des Worts &amp;lt;tt&amp;gt;good&amp;lt;/tt&amp;gt; war die Anfrage nicht erfolgreich, falls in der Rückmeldung die IP-Adresse mit &amp;lt;tt&amp;gt;127.0.0.1&amp;lt;/tt&amp;gt; angegeben wird. Dieser verwirrende Fehlercode ist aus unerklärlichen Gründen in der Spezifikation von DynDNS.org so definiert.&lt;br /&gt;
|-&lt;br /&gt;
--&amp;gt;&lt;br /&gt;
| &amp;lt;tt&amp;gt;nochg&amp;amp;nbsp;&amp;amp;lt;IP&amp;amp;nbsp;number&amp;amp;gt;&amp;lt;/tt&amp;gt; ||&lt;br /&gt;
Der gewünschte DNS-Eintrag war bereits vorhanden. &lt;br /&gt;
|| Der Server selbst macht keine DNS-Abfrage, um das zu vermitteln: die &amp;amp;bdquo;no change&amp;amp;ldquo;-Antwort besagt nur, daß eine Anfrage für diesen Eintrag bereits mit Erfolg quittiert wurde.&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;notfqdn&amp;lt;/tt&amp;gt; ||&lt;br /&gt;
Fehlschlag: der gewünschte Domainname ist nicht gültig, oder es wurde keiner angegeben.&lt;br /&gt;
|| ...&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;nohost&amp;lt;/tt&amp;gt; ||&lt;br /&gt;
Fehlschlag: der gewünschte Domainname ist gehört nicht zu denen, die für diesen Benutzer des DDNS-Dienstes konfiguriert sind.&lt;br /&gt;
|| Siehe den Abschnitt [[#Administration|Administration]] weiter unten.&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;badauth&amp;lt;/tt&amp;gt; ||&lt;br /&gt;
Fehlschlag: Die Kombination von Benutzernamen und Paßwort entsprach keinem DDNS-Account, oder das Account ist momentan gesperrt.&lt;br /&gt;
|| Ein gesperrtes Account kann nur der Domain-Admin mittels des Administrationswerkzeugs wieder freigeben: siehe den Abschnit [[#Administration|Administration]] weiter unten.&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;abuse&amp;lt;/tt&amp;gt; ||&lt;br /&gt;
Fehlschlag: der gewünschte Domainname ist wegen vorangeganger Fehlschläge oder überflüssiger Aufrufe gesperrt.&lt;br /&gt;
|| Siehe den Abschnitt [[#Sukzessive_Kommunikationsabläufe|Sukzessive Kommunikationsabläufe]] unten.&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;911&amp;lt;/tt&amp;gt; ||&lt;br /&gt;
Fehlschlag: Das Server-Programm hat einen internen Fehler festgestellt.&lt;br /&gt;
|| Das Problem liegt nicht in der Anfrage an sich.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Man kann sich durchaus eine sinnreichere Kommunikation zwischen Client und Server vorstellen, doch das hier beschriebene Protokoll ist eben von DynDNS.org verwendet worden und wird in gängigen Routern implementiert, also wird es in der vorliegenden DDNS-Implementierung nachgebildet.&lt;br /&gt;
&lt;br /&gt;
=== Sukzessive Kommunikationsabläufe ===&lt;br /&gt;
Der Server muß sich zwischen einzelnen Aufrufen einiges merken, um Ressourcen zu schonen und um zu verhindern, daß einmal vergebene DDNS-Einträge von neuen Anfragen, die dieselbe übergeordnete Domain betreffen, durch Überschreiben  verlorengehen.&lt;br /&gt;
&lt;br /&gt;
==== Mißbrauch und Benutzersperrung ====&lt;br /&gt;
Zur Schonung von Ressourcen muß sich die Implementierung weigern, sich mit zuvielen fehlerhaften oder auch nur überflüssigen Anfragen zu beschäftigen. Dazu führt der Server eine Strichliste über solche Anfragen jedes Clients und sperrt nach einer bestimmten Anzahl solcher Anfragen den Benutzernamen oder einzelne Domainnamen gegen die weitere Nutzung des Dienstes.&lt;br /&gt;
&lt;br /&gt;
Mißbrauchspunkte gegen einen einzelnen Domainnamen gibt es für:&lt;br /&gt;
* eine Anfrage, die keinen neuen DNS-Eintrag (und keine Änderung oder Löschung eines Eintrags) erfordert, sondern bestehende Merkmale nur wiederholt&lt;br /&gt;
&lt;br /&gt;
Mißbrauchspunkte gegen einen Benutzernamen gibt es für:&lt;br /&gt;
* die Angabe eines Domainnamens, der in der Dienstkonfiguration dem anfragenden Benutzernamen nicht zugeordnet ist&lt;br /&gt;
* die Angabe eines Domainnamen in einer Domain, die nicht demselben Hostsharing-Domain-Admin gehört, der den DDNS-Dienst anbietet&lt;br /&gt;
* die Angabe eines Domainnamens, der in der Dienstkonfiguration bereits wegen mißbräuchlicher Anfragen gesperrt ist (siehe oben)&lt;br /&gt;
&lt;br /&gt;
Um eine Sperrung aufzuheben, wird in der Regel eine Handlung durch den Administrator erforderlich sein.&lt;br /&gt;
&lt;br /&gt;
==== Mehrere dynamische Subdomains in derselben Domain ====&lt;br /&gt;
Sobald zwei verschiedene DDNS-Einträge in derselben Domain verlangt werden &amp;amp;ndash; beispielsweise home.example.com und office.example.com &amp;amp;ndash; wird es notwendig, bei jeder neuen Zonefile für example.com eventuell frühere Einträge zu konservieren. Der Rechner zu Hause weiß beim Bestellen seines DDNS-Eintrags nichts vom Rechner im Büro und umgekehrt. Der Server muß in irgendeiner Form über bereits vergebene Einträge Buch führen und bei einer neuen Anfrage, die example.com betrifft, alle bereits aktiven DDNS-Einträge für example.com mit in die neue Zonefile aufnehmen &amp;amp;ndash auch wenn sie auf Anfragen verschiedener Benutzer zurückgehen.&lt;br /&gt;
&lt;br /&gt;
==== Datenbank ====&lt;br /&gt;
In der Beispielimplementierung werden diese Informationen in einer SQLite-Datenbank gespeichert.&lt;br /&gt;
&lt;br /&gt;
== Sicherheit ==&lt;br /&gt;
=== Rechte ===&lt;br /&gt;
Die &#039;&#039;&#039;Benutzerrechte&#039;&#039;&#039; werden durch das Hostsharing-System kontrolliert. Sowohl das CGI-Programm als auch das [[#Administration|Administrationswerkzeug]] werden mit den Rechten des Domain-Admins (xyz00-benutzername in unserem Beispiel) ausgeführt, also kann dieses Programm nur die Domains bearbeiten, die von xyz00-benutzername verwaltet werden.&lt;br /&gt;
&lt;br /&gt;
=== Authentifizierung ===&lt;br /&gt;
In der Beispielimplementierung (wie auch seinerzeit bei DynDNS.org) wird das CGI-Programm durch einen .htaccess-Eintrag geschützt, der HTTP-Basic-Authentication vorschreibt. Also wird das Programm eigentlich mit einem URL der form&lt;br /&gt;
&lt;br /&gt;
  &amp;lt;nowiki&amp;gt;https://ddnsaccount:passwort@ddns.example.com/cgi-bin/ddns?hostname=...&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
aufgerufen.&lt;br /&gt;
&lt;br /&gt;
=== Verschlüsselung ===&lt;br /&gt;
Das CGI-Programm sollte nur in example.com/cgi-ssl/ installiert werden, nicht in example.com/cgi/. Damit ist die Kommunikation zwischen Client und Server durch SSL verschlüsselt.&lt;br /&gt;
&lt;br /&gt;
== Administration ==&lt;br /&gt;
&lt;br /&gt;
Der Verwalter des DDNS-Programms trägt berechtigte Benutzer und die ihnen zugeteilten Domainnamen in die Datenbank des Programms ein mit Hilfe eines kleinen Hilfsprogramms. Das ist im vorliegenden Fall ein menügesteuertes Programm für die Befehlszeile, daß die naheliegenden Funktionen anbietet: Account hinzufügen, löschen, sperren, entsperren, Paßwort setzen, ändern; Domainnamen hinzufügen, ändern, entsperren, löschen; Accounts und Domainnamen mit aktuellem Status auflisten. Die Funktionen sind auch über Befehlszeilenargumente verfügbar, also skriptfähig.&lt;br /&gt;
&lt;br /&gt;
Eine Übersicht der Funktionen des Administrationswerkzeugs gibt dieses selbst aus:&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Achtung, veraltet: inzwischen ist die Verwaltungsoberfläche für&lt;br /&gt;
die hier beschriebene Implementierung web-basiert.&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
xyz00-benutzername@h02:~$ bin/ddnsadmin -h&lt;br /&gt;
ddnsadmin.pl: Verwaltungswerkzeug für ddns&lt;br /&gt;
&lt;br /&gt;
Verwendung:&lt;br /&gt;
    ddnsadmin -A{[ahlusf]} [&amp;lt;Account&amp;gt;] [-f &amp;lt;DB-Datei&amp;gt;]&lt;br /&gt;
    ddnsadmin -D{[ahlsf]} [&amp;lt;Domain&amp;gt;] -A &amp;lt;Account&amp;gt; [-f &amp;lt;DB-Datei&amp;gt;]&lt;br /&gt;
    ddnsadmin -E &amp;lt;Einstellung&amp;gt; &amp;lt;Wert&amp;gt; [-f &amp;lt;DB-Datei&amp;gt;]&lt;br /&gt;
    ddnsadmin [-f &amp;lt;DB-Datei&amp;gt;] [-n]&lt;br /&gt;
&lt;br /&gt;
Wenn keine Option oder nur -f &amp;lt;DB-Datei&amp;gt; angegeben wird, bietet&lt;br /&gt;
ddnsadmin.pl eine interaktive Menüoberfläche.&lt;br /&gt;
&lt;br /&gt;
Optionen:&lt;br /&gt;
    -f &amp;lt;DB-Datei&amp;gt;                    Angegebene Datenbankdatei verwenden&lt;br /&gt;
    -n                               Neue, leere Datenbank erzeugen&lt;br /&gt;
    -Aa  [&amp;lt;Account&amp;gt;]                 Account(s) auflisten&lt;br /&gt;
    -Ah &amp;lt;Account&amp;gt; &amp;lt;Paßwort&amp;gt;          Account hinzufügen&lt;br /&gt;
    -A{lsf} &amp;lt;Account&amp;gt;                Account löschen, sperren, freigeben&lt;br /&gt;
    -Au &amp;lt;Account&amp;gt; &amp;lt;Name&amp;gt;             Account umbenennen&lt;br /&gt;
    -A  &amp;lt;Account&amp;gt; -Da [&amp;lt;Domain&amp;gt;]     Domain(s) auflisten&lt;br /&gt;
    -A  &amp;lt;Account&amp;gt; -D{hlsf} &amp;lt;Domain&amp;gt;  Domain hinzufügen,&lt;br /&gt;
                                     löschen, sperren, freigeben&lt;br /&gt;
    -E &amp;lt;Einstellung&amp;gt; &amp;lt;Wert&amp;gt;          Einstellung ändern&lt;br /&gt;
    -h                               Diese Übersicht ausgeben&lt;br /&gt;
&lt;br /&gt;
Einstellungen: &lt;br /&gt;
    maxacctabuse    Anzahl der mißbräuchlichen Aufrufe,&lt;br /&gt;
                    bevor ein Account gesperrt wird&lt;br /&gt;
    maxhostabuse    Anzahl der mißbräuchlichen Aufrufe,&lt;br /&gt;
                    bevor ein Domainname gesperrt wird&lt;br /&gt;
    safeinterval    Mindestabstand zwischen redundanten Aufrufen&lt;br /&gt;
                    (in Sekunden)&lt;br /&gt;
    cgihost         Server, der das DDNS-Skript bereithält&lt;br /&gt;
&lt;br /&gt;
xyz00-benutzername@h02:~$ &lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Eine Auflistung des momentanen Inhalts der DDNS-Datenbank durch das Administrationswerkzeug könnte beispielsweise so aussehen:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  xyz00-benutzername@h02:~$ bin/ddnsadmin.pl -Aa&lt;br /&gt;
  1.  papst	Mißbrauch: 0; gesperrt: nein&lt;br /&gt;
  	avignon.example.com&lt;br /&gt;
  		zuletzt aktiv am Sun Apr 26 22:24:49 2020&lt;br /&gt;
  		mit IP-Nr. 87.65.43.21; MX: 0;  Backup-MX: nein;&lt;br /&gt;
  		Subdomains: nein; Mißbrauch: 0;  gesperrt: nein&lt;br /&gt;
  	vatican.beispiel.de&lt;br /&gt;
  		zuletzt aktiv am Sun Apr 26 22:24:49 2020&lt;br /&gt;
  		mit IP-Nr. 87.65.43.21; MX: 0;  Backup-MX: nein;&lt;br /&gt;
  		Subdomains: nein; Mißbrauch: 0;  gesperrt: nein&lt;br /&gt;
  2.  kaiser	Mißbrauch: 4; gesperrt: ja&lt;br /&gt;
  	augsburg.beispiel.de&lt;br /&gt;
  		zuletzt aktiv am Fri Apr 24 16:13:49 2020&lt;br /&gt;
  		mit IP-Nr. 64.82.31.75; MX: 0;  Backup-MX: nein;&lt;br /&gt;
  		Subdomains: nein; Mißbrauch: 0;  gesperrt: ja&lt;br /&gt;
  3.  luther	Mißbrauch: 1; gesperrt: nein&lt;br /&gt;
  	wittenberg.example.com&lt;br /&gt;
  		zuletzt aktiv am Mon Apr 27 10:12:49 2020&lt;br /&gt;
  		mit IP-Nr. 78.56.34.12; MX: 0;  Backup-MX: nein;&lt;br /&gt;
  		Subdomains: nein; Mißbrauch: 1;  gesperrt: nein&lt;br /&gt;
  xyz00-benutzername@h02:~$&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Das DDNS-Account &amp;amp;bdquo;kaiser&amp;amp;ldquo; in dieser Auflistung ist wohl auf Grund fehlerhafter Anfragen automatisch gesperrt worden. Der Inhaber wird sich wohl bald melden, um nach Korrektur seiner Client-Konfiguration die Aufhebung der Sperre zu wünschen.&lt;br /&gt;
&lt;br /&gt;
=== Log ===&lt;br /&gt;
Alle Anfragen werden in einer täglich wechselnden Log-Datei protokolliert, entweder schlicht oder ausführlich, je nachdem, ob eine Variable &amp;lt;tt&amp;gt;verbose&amp;lt;/tt&amp;gt; wahr ist.&lt;br /&gt;
Ein ausführlicher Log-Eintrag sieht so aus:&lt;br /&gt;
&lt;br /&gt;
  Sun Apr 26 20:21:45 2020  ddns aufgerufen von papst&lt;br /&gt;
  			unter 84.185.97.8&lt;br /&gt;
  	URL: &amp;lt;nowiki&amp;gt;https://ddns.example.com/cgi-bin/ddns.cgi?hostname=&lt;br /&gt;
  			avignon.example.com,vatican.beispiel.de&amp;amp;&lt;br /&gt;
  			myip=84.185.97.8&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
  	Verwende IP 84.185.97.8 (= 1421435144)&lt;br /&gt;
  	DB-Version: 1&lt;br /&gt;
  	Skript und DB exklusiv geöffnet&lt;br /&gt;
  	avignon.example.com: IP: 84.185.97.8; MX: 0; Backup-MX: nein;&lt;br /&gt;
  			Wildcard: nein; Mißbrauch: 0; gesperrt: nein &lt;br /&gt;
  	vatican.beispiel.de: IP: 84.185.97.8; MX: 0; Backup-MX: nein;&lt;br /&gt;
  			Wildcard: nein; Mißbrauch: 0; gesperrt: nein &lt;br /&gt;
  	Betroffene Zonen: example.com, beispiel.de&lt;br /&gt;
  	Temporärdatei example.com_hxNa.new geschrieben&lt;br /&gt;
  	Zonendatei /home/pacs/xyz00/users/benutzername/doms/example.com/&lt;br /&gt;
  			etc/pri.example.com eingestellt&lt;br /&gt;
  	Temporärdatei beispiel.de_6HcO.new geschrieben&lt;br /&gt;
  	Zonendatei /home/pacs/xyz00/users/benutzername/doms/beispiel.de/&lt;br /&gt;
  			etc/pri.beispiel.de eingestellt&lt;br /&gt;
  	Abgeschlossen: 	Fertig&lt;br /&gt;
&lt;br /&gt;
Wenn &amp;lt;tt&amp;gt;verbose&amp;lt;/tt&amp;gt; auf falsch gesetzt ist, sind die Log-Einträge einzeilig.&lt;/div&gt;</summary>
		<author><name>Apc00-tony</name></author>
	</entry>
	<entry>
		<id>https://wiki.hostsharing.net/index.php?title=Mlmmj&amp;diff=6411</id>
		<title>Mlmmj</title>
		<link rel="alternate" type="text/html" href="https://wiki.hostsharing.net/index.php?title=Mlmmj&amp;diff=6411"/>
		<updated>2024-02-04T12:28:38Z</updated>

		<summary type="html">&lt;p&gt;Apc00-tony: Paar Details aus E-Mail-Diskussion hinzugefügt&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[http://www.mlmmj.org/ mlmmj], angeblich eine Abkürzung für &amp;quot;Mailing List Management Made Joyful&amp;quot;, ist ein Programm, mit dem in einem Hostsharing Paket E-Mail-Verteiler realisiert werden kann.&lt;br /&gt;
&lt;br /&gt;
Wer noch nicht weiß, was ein E-Mail-Verteiler machen soll oder wie, lese veilleicht auch den Wikipedia-Artikel:&lt;br /&gt;
[http://de.wikipedia.org/wiki/Mailingliste Mailingliste]&lt;br /&gt;
&lt;br /&gt;
Eine leistungsfähigere Alternative zu mlmmj könnte [[Mailman_3_installieren|Mailman 3]] sein.&lt;br /&gt;
&lt;br /&gt;
Diese Anleitung beschreibt die Einrichtung einer Mailingliste für eine Domain in einem Hostsharing-Webspace.&lt;br /&gt;
&lt;br /&gt;
== Voraussetzungen  ==&lt;br /&gt;
&lt;br /&gt;
Das Debian Paket [http://packages.debian.org/search?keywords=mlmmj mlmmj] ist auf den Shared-Hosting-Servern bereits installiert. (Wer die Software selbst kompilieren möchte kann aktuellen Source-Code bei [https://codeberg.org/mlmmj/mlmmj|codeberg.org] finden.)&lt;br /&gt;
&lt;br /&gt;
Für den Betrieb der Mailingliste empfiehlt sich das Anlegen eines eigenen Users für diesen Zweck mit hsadmin.&lt;br /&gt;
&lt;br /&gt;
In dieser Anleitung heißt das Paket &#039;&#039;xyz00&#039;&#039; und der für Mailinglisten eingesetzte User &#039;&#039;xyz00-list&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
Die E-Mail-Adresse der einzurichtende Mailing-Liste soll &#039;&#039;discuss@example.org&#039;&#039; sein. Den lokalen Teil dieser Adresse, &#039;&#039;discuss&#039;&#039;, ist der Listenname. Der Listenname darf auf keinen Fall das Plus-Zeichen (+) enthalten, weil dies ein Sonderbedeutung für die Listensteuerung hat: &#039;&#039;mlmmj&#039;&#039; wird nämlich Befehle der Abonnenten über erweiterte Adressen annehmen, wie z.B. &#039;&#039;discuss+help@example.org&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
Die Domain &#039;&#039;example.org&#039;&#039; muss dazu bei einem beliebigen User im Paket &#039;&#039;xyz00&#039;&#039; [[aufgeschaltet]] sein. (&amp;quot;Aufgeschaltet&amp;quot; bedeutet, daß diese Domain bei Hostsharing gehostet wird und der Domainname als Verzeichnis /home/pacs/xyz00/*User*/doms/example.org/ erscheint.)&lt;br /&gt;
&lt;br /&gt;
== Einrichtung ==&lt;br /&gt;
&lt;br /&gt;
Ich melde mich über SSH auf der Hostsharing-Console als der Paketuser &#039;&#039;xyz00&#039;&#039; an.&lt;br /&gt;
&lt;br /&gt;
Im Shell kann ich dann durch den Befehl &#039;&#039;hsscript -i&#039;&#039; das Verwaltungswerkzeug [[hsadmin]] interaktiv ausführen:&lt;br /&gt;
&lt;br /&gt;
  xyz00@h03:~$ hsscript -i&lt;br /&gt;
  Password: *************&lt;br /&gt;
  xyz00@hsadmin&amp;gt; &lt;br /&gt;
&lt;br /&gt;
In &#039;&#039;hsadmin&#039;&#039; werden User und E-Mail-Adresse angelegt.&lt;br /&gt;
&lt;br /&gt;
  xyz00@hsadmin&amp;gt; user.add({set:{name:&#039;xyz00-list&#039;,comment:&#039;Mailingliste Discuss&#039;,shell:&#039;/bin/bash&#039;,password:&#039;geheimnis&#039;}})&lt;br /&gt;
  xyz00@hsadmin&amp;gt; emailaddress.add({set:{target:&#039;xyz00-list&#039;,localpart:&#039;discuss&#039;,domain:&#039;example.org&#039;}})&lt;br /&gt;
  xyz00@hsadmin&amp;gt; bye&lt;br /&gt;
&lt;br /&gt;
Mit dem Parameter &amp;quot;target&amp;quot; wird die für diese Adresse eingehende Post zunächst in das Postfach des Users xyz00-list abgelegt.&lt;br /&gt;
&lt;br /&gt;
Für den User xyz00-list lege ich in seinem Heimat-Verzeichnis das Unterverzeichnis &amp;lt;tt&amp;gt;mlmmj&amp;lt;/tt&amp;gt; an:&lt;br /&gt;
&lt;br /&gt;
  mkdir /home/pacs/xyz00/users/list/mlmmj&lt;br /&gt;
&lt;br /&gt;
Dann lege ich die Mailingliste mit folgendem Kommando an:&lt;br /&gt;
&lt;br /&gt;
  mlmmj-make-ml -L discuss -s /home/pacs/xyz00/users/list/mlmmj&lt;br /&gt;
&lt;br /&gt;
Das Skript &#039;&#039;mlmmj-make-ml&#039;&#039; fragt weitere Parameter der Mailingliste ab:&lt;br /&gt;
&lt;br /&gt;
  The Domain for the List? [] : example.org&lt;br /&gt;
  The emailaddress of the list owner? [postmaster] : webmaster@example.org&lt;br /&gt;
  For the list texts you can choose between the following languages or&lt;br /&gt;
  give an absolute path to a directory containing the texts.&lt;br /&gt;
  Available languages:&lt;br /&gt;
  cz  da	de  en	es  fr	it  nl	ru&lt;br /&gt;
  The path to texts for the list? [en] : de&lt;br /&gt;
&lt;br /&gt;
Das skript &#039;&#039;mlmmj-make-ml&#039;&#039; legt daraufhin unter &amp;quot;/home/pacs/xyz00/users/list/mlmmj&amp;quot; ein Verzeichnis &amp;quot;discuss&amp;quot; an, das die Datenstruktur zur Verwaltung der Mailingliste enthält.&lt;br /&gt;
&lt;br /&gt;
Weitere Konfigurationen der Liste erfolgen durch das Anlegen von Dateien im&lt;br /&gt;
Verzeichnis &amp;quot;/home/pacs/xyz00/users/list/mlmmj/discuss/control&amp;quot;.&lt;br /&gt;
Die Konfigurationsmöglichkeiten finden Sie auf der [http://mlmmj.org/docs/tunables/ Internetseite von mlmmj].&lt;br /&gt;
&lt;br /&gt;
Damit mlmmj die Verteilung der Post übernimmt, muß ich im Heimat-Verzeichnis des users xyz00-list die Datei &amp;lt;tt&amp;gt;.forward&amp;lt;/tt&amp;gt; mit folgenden Inhalt (INKLUSIVE der Anführungszeichen!) erstellen:&lt;br /&gt;
&lt;br /&gt;
  &amp;quot;|/usr/bin/mlmmj-recieve -L /home/pacs/xyz00/users/list/mlmmj/discuss/&amp;quot;&lt;br /&gt;
&lt;br /&gt;
(Ja, &#039;&#039;receive&#039;&#039; schreibt sich mit &#039;&#039;-ei-&#039;&#039;, aber mlmmj hält einen symbolischen Link bereit für diejenigen, die in englischer Rechtschreibung unsicher sind:)&lt;br /&gt;
&lt;br /&gt;
   xyz00-list@h03:~$ ls -la /usr/bin/mlmmj-rec*&lt;br /&gt;
   -rwxr-xr-x 1 root root 27104 Sep 25  2018 /usr/bin/mlmmj-receive&lt;br /&gt;
   lrwxrwxrwx 1 root root    13 Sep 25  2018 /usr/bin/mlmmj-recieve -&amp;gt; mlmmj-receive&lt;br /&gt;
&lt;br /&gt;
Die &amp;lt;tt&amp;gt;.forward&amp;lt;/tt&amp;gt;-Datei sorgt dafür, dass eingehende E-Mails an das User-Postfach an das Programm &#039;&#039;mlmmj-recieve&#039;&#039; übergeben werden.&lt;br /&gt;
&lt;br /&gt;
Für regelmäßige Aufgaben der Listen-Managers definiere ich die&lt;br /&gt;
[[Cron|crontab]] wie folgt (immer noch als &#039;&#039;xyz00-list&#039;&#039;):&lt;br /&gt;
&lt;br /&gt;
  xyz00-list@h03:~$ crontab -e&lt;br /&gt;
&lt;br /&gt;
 MAILTO=webmaster@example.org&lt;br /&gt;
 PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/X11R6/bin&lt;br /&gt;
 HOME=/home/pacs/xyz00/users/list&lt;br /&gt;
 SHELL=/bin/bash&lt;br /&gt;
 LANG=en_US.UTF-8&lt;br /&gt;
 # m h  dom mon dow   command&lt;br /&gt;
 28 */4 * * * /usr/bin/mlmmj-maintd -d /home/pacs/xyz00/users/list/mlmmj -F&lt;br /&gt;
&lt;br /&gt;
Zum Schluss rufe ich das Skript mlmmj-sub auf, um die E-Mail-Adressen der gewünschten Abonnenten des Verteilers einzutragen:&lt;br /&gt;
&lt;br /&gt;
 /usr/bin/mlmmj-sub -L /home/pacs/xyz00/users/list/mlmmj/discuss -a klaus.muster@gmx.de -c &lt;br /&gt;
 /usr/bin/mlmmj-sub -L /home/pacs/xyz00/users/list/mlmmj/discuss -a sabine.beispiel@arcor.de -c &lt;br /&gt;
&lt;br /&gt;
Dabei bewirkt &amp;quot;-c&amp;quot;, dass der Abonnent eine Begrüßungs-Nachricht erhält. Alternativ kann man &amp;quot;-C&amp;quot; (großes C) angeben: dann muss der Abonnent das Abo durch Antworten auf die Nachricht bestätigen.&lt;br /&gt;
&lt;br /&gt;
== weitere Optionen  ==&lt;br /&gt;
&lt;br /&gt;
Noch ein paar Dinge, die Sie möglicherweise einstellen wollen:&lt;br /&gt;
&lt;br /&gt;
Ein Prefix in der Betreffzeile setzen, z.B.: &amp;quot;[discuss]&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
 echo &amp;quot;[discuss]&amp;quot; &amp;gt; /home/pacs/xyz00/users/list/mlmmj/discuss/control/prefix&lt;br /&gt;
&lt;br /&gt;
Wenn die Liste nur E-Mails von eingetragenen Abonnenten weiterleiten soll:&lt;br /&gt;
&lt;br /&gt;
 touch /home/pacs/xyz00/users/list/mlmmj/discuss/control/subonlypost&lt;br /&gt;
&lt;br /&gt;
Damit der Listen-Owner weitere Abonnements bestätigen muss:&lt;br /&gt;
&lt;br /&gt;
 touch /home/pacs/xyz00/users/list/mlmmj/discuss/control/submod&lt;br /&gt;
&lt;br /&gt;
Einen &amp;quot;Reply-To:&amp;quot;-Header setzen, damit Antwort-Mails standardmäßig an die Mailing-Liste gehen:&lt;br /&gt;
&lt;br /&gt;
  echo &amp;quot;Reply-To:&amp;quot; &amp;gt; /home/pacs/xyz00/users/list/mlmmj/discuss/control/delheaders&lt;br /&gt;
  echo &amp;quot;Reply-To: discuss@example.org&amp;quot; &amp;gt; /home/pacs/xyz00/users/list/mlmmj/discuss/control/customheaders&lt;br /&gt;
&lt;br /&gt;
Weitere Möglichkeiten finden Sie (wie oben bereits angegeben) &lt;br /&gt;
auf der [http://mlmmj.org/docs/tunables/ Internetseite von mlmmj].&lt;br /&gt;
&lt;br /&gt;
== Zur Konfiguration im Browser ==&lt;br /&gt;
&lt;br /&gt;
Die Original-Distribution von &#039;&#039;mlmmj&#039;&#039; enthält ein paar einfache PHP- und Perl-Skripte.  Das sind Beispiele für Subscribe-/Unsubscribe-Formulare, ein Admin-Formular zum Eintragen und Löschen von Abonnements und eine Seite mit der gesamten Listen-Konfiguration.&lt;br /&gt;
&lt;br /&gt;
Wer es sich ansehen möchte:&lt;br /&gt;
&lt;br /&gt;
Als Paket-Admin eine Domain aufschalten:&lt;br /&gt;
&lt;br /&gt;
 hsscript -u xyz00 -e &amp;quot;domain.add({set:{name:&#039;lists.example.org&#039;,user:&#039;xyz00-list&#039;}})&amp;quot;&lt;br /&gt;
&lt;br /&gt;
Und weiter als &amp;quot;xyz00-list&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
Download der neuesten Version der Sourcen von mlmmj von http://mlmmj.org/downloads/ (noch besser: Download des aktuellen Debian-Pakets von [https://packages.debian.org/bookworm/all/mlmmj-php-web-admin/download debian.org]: da sind einige veraltete PHP-Ausdrücke schon herausgepatcht) und diese in einem temporären Verzeichnis entpacken (mit tar oder dpkg-deb).&lt;br /&gt;
&lt;br /&gt;
Unter &amp;quot;/mlmmj-$versionsnummer/contrib/web/php-admin/&amp;quot;, oder beim .deb-Paket unter &amp;quot;usr/share/mlmmj-...&amp;quot;, findet sich die PHP-Admin-Anwendung. Also ...&lt;br /&gt;
&lt;br /&gt;
* den Inhalt diese Verzeichnisses nach &amp;quot;/home/pacs/xyz00/users/list/doms/lists.example.org/&amp;quot; packen;&lt;br /&gt;
* in &amp;quot;/home/pacs/xyz00/users/list/doms/lists.example.org/conf/config.php&amp;quot; die Variable &amp;quot;$topdir&amp;quot; anpassen;&lt;br /&gt;
* die Dateien aus &amp;quot;/home/pacs/xyz00/users/list/doms/lists.example.org/htdocs/&amp;quot; nach &amp;quot;/home/pacs/xyz00/users/list/doms/lists.example.org/htdocs-ssl/&amp;quot; verschieben;&lt;br /&gt;
* Beim .deb-Paket die config.php, die templates/ und die tunables.pl aus etc/ nach example.org/conf/ verschieben;&lt;br /&gt;
* in &amp;quot;/home/pacs/xyz00/users/list/mlmmj&amp;quot; und in &amp;quot;/home/pacs/xyz00/users/list/doms/lists.example.org/htdocs-ssl/&amp;quot; eine &amp;quot;.htaccess&amp;quot; mit folgendem Inhalt ablegen: &lt;br /&gt;
 &lt;br /&gt;
 Require valid-user&lt;br /&gt;
 AuthType Basic&lt;br /&gt;
 AuthName &amp;quot;mlmmj web-interface&amp;quot;&lt;br /&gt;
 AuthUserFile /home/pacs/xyz00/users/list/doms/lists.example.org/etc/htpasswd&lt;br /&gt;
&lt;br /&gt;
* Und schließlich die &amp;quot;htpasswd&amp;quot;-Datei anlegen.&lt;br /&gt;
&lt;br /&gt;
 cd /home/pacs/xyz00/users/list/doms/lists.example.org/etc/&lt;br /&gt;
 htpasswd -c htpasswd listadmin&lt;br /&gt;
&lt;br /&gt;
* Ein Passwort angeben.&lt;br /&gt;
&lt;br /&gt;
Nun enthält diese PHP-Anwendung, wenn man sie nicht dem Debian-Paket entnommen hat, leider noch eine Zeile, die schon seit PHP 7 nicht mehr lauffähig ist. Also muß man noch&lt;br /&gt;
&lt;br /&gt;
* in &amp;lt;tt&amp;gt;.../htdocs-ssl/index.php&amp;lt;/tt&amp;gt; folgende Änderung vornehmen:&lt;br /&gt;
&lt;br /&gt;
  @@ -38,4 +38,5 @@&lt;br /&gt;
   # use scandir to have alphabetical order &lt;br /&gt;
   foreach (scandir($topdir) as $file) {&lt;br /&gt;
  -    if (!ereg(&amp;quot;^\.&amp;quot;,$file))&lt;br /&gt;
  +# ereg obsolete!! Vormals:    if (!ereg(&amp;quot;^\.&amp;quot;,$file))&lt;br /&gt;
  +    if (!preg_match(&#039;/^\./&#039;,$file))&lt;br /&gt;
       {&lt;br /&gt;
&lt;br /&gt;
und das Ergebnis auf https://lists.example.org anschauen.&lt;br /&gt;
&lt;br /&gt;
== Mehrere Mailinglisten betreiben ==&lt;br /&gt;
&lt;br /&gt;
Wenn mehrere Mailinglisten in einem Account und mit einer Admin-Oberfläche betrieben werden soll, empfiehlt sich die Nutzung von Procmail für den Aufruf von &#039;&#039;mlmmj&#039;&#039; für die jeweiligen Liste mit ihrem Daten-Verzeichnis.&lt;br /&gt;
&lt;br /&gt;
Dazu trägt man in der Datei &amp;lt;tt&amp;gt;.forward&amp;lt;/tt&amp;gt; statt des Aufrufs von &#039;&#039;mlmmj-recieve&#039;&#039; einen Aufruf von &#039;&#039;procmail&#039;&#039; ein:&lt;br /&gt;
&lt;br /&gt;
 |/usr/bin/procmail&lt;br /&gt;
&lt;br /&gt;
Die Konfiguration von Procmail kann generisch erfolgen. Dazu legt man eine Datei &amp;lt;tt&amp;gt;.procmailrc&amp;lt;/tt&amp;gt; mit folgendem Inhalt ins $HOME des Users:&lt;br /&gt;
&lt;br /&gt;
 SHELL=/bin/sh&lt;br /&gt;
 HOMEDIR=/home/pacs/xyz00/users/list&lt;br /&gt;
 MAILDIR=/home/pacs/xyz00/users/list/Maildir&lt;br /&gt;
 PMDIR=/home/pacs/xyz00/users/list&lt;br /&gt;
 VERBOSE=yes&lt;br /&gt;
 LOGFILE=/home/pacs/xyz00/users/list/var/procmail.log&lt;br /&gt;
 DEFAULT&lt;br /&gt;
 &lt;br /&gt;
 :0:&lt;br /&gt;
 * ^X-Original-To: ()\/[^@+]+&lt;br /&gt;
 |/usr/bin/mlmmj-receive -F -L /home/pacs/xyz00/users/list/mlmmj/${MATCH}/&lt;br /&gt;
 &lt;br /&gt;
 :0&lt;br /&gt;
 { EXITCODE 67 }&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Der kryptische reguläre Ausdruck hinter dem Header &#039;&#039;X-Original-To:&#039;&#039; passt auf den Beginn der E-Mail-Adresse bis zum ersten &#039;&#039;@&#039;&#039;- oder &#039;&#039;+&#039;&#039;-Zeichen. In der Variable &#039;&#039;MATCH&#039;&#039; steht also der Name der Mailingliste, d.h. der Name der Verzeichnisses, in dem die Liste verwaltet wird.&lt;br /&gt;
&lt;br /&gt;
Sehr wichtig ist die Zeile &#039;&#039;DEFAULT&#039;&#039; zu Beginn der &#039;&#039;.procmailrc&#039;&#039;. Die Variable &#039;&#039;DEFAULT&#039;&#039; wird von &#039;&#039;procmail&#039;&#039; gesetzt. Wir sorgen mit dieser Zeile dafür, dass sie wieder undefiniert ist. Diese Variable wird intern von &#039;&#039;mlmmj&#039;&#039; benutzt, wenn sie gesetzt ist. Das führt in Kombination mit &#039;&#039;procmail&#039;&#039; zu Fehlfunktionen (vgl. Links).&lt;br /&gt;
&lt;br /&gt;
Achtung, mit der Groß- und Kleinschreibung von Listennamen gibt es bei dieser Procmail-Lösung eine kleine Tücke. Procmail übernimmt in die Variable $MATCH genau die in der X-Original-To-Headerzeile vorgefundene Schreibweise, und diese kann denkbarerweise &amp;quot;Listen-Name&amp;quot; oder &amp;quot;listen-name&amp;quot; oder &amp;quot;Listen-name&amp;quot; sein. &amp;lt;tt&amp;gt;mlmmj&amp;lt;/tt&amp;gt; hingegen wird diesen Wert in Unix-Manier mit dem genauen Verzeichnisnamen &amp;lt;tt&amp;gt;${HOME}/mlmmj/listen-name&amp;lt;/tt&amp;gt; vergleichen, und bei unterschiedlicher Schreibweise die Mail nicht verteilen.&lt;br /&gt;
&lt;br /&gt;
Eine teilweise Lösung besteht darin, den Listennamen in dem &amp;lt;tt&amp;gt;mlmmj&amp;lt;/tt&amp;gt;-Aufruf in der &amp;lt;tt&amp;gt;.procmailrc&amp;lt;/tt&amp;gt; in Kleinbuchstaben umzuschreiben. Dann lautet das Rezept so:&lt;br /&gt;
&lt;br /&gt;
 :0:&lt;br /&gt;
 * ^X-Original-To: ()\/[^@+]+&lt;br /&gt;
 |/usr/bin/mlmmj-receive -F -L /home/pacs/xyz00/users/list/mlmmj/$(echo ${MATCH} | tr [:upper:] [:lower:])/&lt;br /&gt;
&lt;br /&gt;
Der Rest der Datei muß gleich bleiben, wie weiter oben angezeigt.&lt;br /&gt;
&lt;br /&gt;
In diesem Fall müssen aber alle Mailing-Listen ohne Großbuchstaben im Namen angelegt werden!&lt;br /&gt;
&lt;br /&gt;
(Man kann auch in &amp;lt;tt&amp;gt;${HOME}/mlmmj/&amp;lt;/tt&amp;gt; durch kleingeschriebene Symlinks großgeschriebene Listennamen ansprechbar machen:&lt;br /&gt;
&lt;br /&gt;
  xyz00-list@h02:~$ ls -lA mlmmj/&lt;br /&gt;
  total 8&lt;br /&gt;
  -rw-r--r--  1 xyz00-list xyz00  148 Feb  1 16:56 .htaccess&lt;br /&gt;
  lrwxrwxrwx  1 xyz00-list xyz00   10 Feb  2 18:01 mitglieder -&amp;gt; Mitglieder&lt;br /&gt;
  drwxr-xr-x 15 xyz00-list xyz00 4096 Feb  2 16:53 Mitglieder&lt;br /&gt;
&lt;br /&gt;
Das scheint zu funktionieren; Angabe ohne Gewähr.)&lt;br /&gt;
&lt;br /&gt;
== Links ==&lt;br /&gt;
&lt;br /&gt;
* http://mlmmj.org/ Projektseite&lt;br /&gt;
* https://codeberg.org/mlmmj mlmmj auf Codeberg&lt;br /&gt;
* https://github.com/tchapi/mlmmj-simple-web-interface ein Admin-Interface in NodeJS&lt;br /&gt;
* https://www.tablix.org/~avian/blog/archives/2010/04/the_faulty_default/ Nutzung von mlmmj in Verbindung mit Procmail&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
[[Kategorie:HSDoku]]&lt;br /&gt;
[[Kategorie:Installationsanleitungen]]&lt;br /&gt;
[[Kategorie:Software]]&lt;br /&gt;
[[Kategorie:Mailinglisten]]&lt;br /&gt;
[[Kategorie:E-Mail]]&lt;/div&gt;</summary>
		<author><name>Apc00-tony</name></author>
	</entry>
	<entry>
		<id>https://wiki.hostsharing.net/index.php?title=Mlmmj&amp;diff=6410</id>
		<title>Mlmmj</title>
		<link rel="alternate" type="text/html" href="https://wiki.hostsharing.net/index.php?title=Mlmmj&amp;diff=6410"/>
		<updated>2024-02-03T10:04:04Z</updated>

		<summary type="html">&lt;p&gt;Apc00-tony: /* Zur Konfiguration im Browser */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[http://www.mlmmj.org/ mlmmj], angeblich eine Abkürzung für &amp;quot;Mailing List Management Made Joyful&amp;quot;, ist ein Programm, mit dem in einem Hostsharing Paket E-Mail-Verteiler realisiert werden kann.&lt;br /&gt;
&lt;br /&gt;
Wer noch nicht weiß, was ein E-Mail-Verteiler machen soll oder wie, lese veilleicht auch den Wikipedia-Artikel:&lt;br /&gt;
[http://de.wikipedia.org/wiki/Mailingliste Mailingliste]&lt;br /&gt;
&lt;br /&gt;
Eine leistungsfähigere Alternative zu mlmmj könnte [[Mailman_3_installieren|Mailman 3]] sein.&lt;br /&gt;
&lt;br /&gt;
Diese Anleitung beschreibt die Einrichtung einer Mailingliste für eine Domain in einem Hostsharing-Webspace.&lt;br /&gt;
&lt;br /&gt;
== Voraussetzungen  ==&lt;br /&gt;
&lt;br /&gt;
Das Debian Paket [http://packages.debian.org/search?keywords=mlmmj mlmmj] ist auf den Shared-Hosting-Servern bereits installiert.&lt;br /&gt;
&lt;br /&gt;
Für den Betrieb der Mailingliste empfiehlt sich das Anlegen eines eigenen Users für diesen Zweck mit hsadmin.&lt;br /&gt;
&lt;br /&gt;
In dieser Anleitung heißt das Paket &#039;&#039;xyz00&#039;&#039; und der für Mailinglisten eingesetzte User &#039;&#039;xyz00-list&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
Die E-Mail-Adresse der einzurichtende Mailing-Liste soll &#039;&#039;discuss@example.org&#039;&#039; sein.&lt;br /&gt;
&lt;br /&gt;
Die Domain &#039;&#039;example.org&#039;&#039; muss dazu bei einem beliebigen User im Paket &#039;&#039;xyz00&#039;&#039; [[aufgeschaltet]] sein. (&amp;quot;Aufgeschaltet&amp;quot; bedeutet, daß diese Domain bei Hostsharing gehostet wird und der Domainname als Verzeichnis /home/pacs/xyz00/*User*/doms/example.org/ erscheint.)&lt;br /&gt;
&lt;br /&gt;
== Einrichtung ==&lt;br /&gt;
&lt;br /&gt;
Ich melde mich über SSH auf der Hostsharing-Console als der Paketuser &#039;&#039;xyz00&#039;&#039; an.&lt;br /&gt;
&lt;br /&gt;
Im Shell kann ich dann durch den Befehl &#039;&#039;hsscript -i&#039;&#039; das Verwaltungswerkzeug [[hsadmin]] interaktiv ausführen:&lt;br /&gt;
&lt;br /&gt;
  xyz00@h03:~$ hsscript -i&lt;br /&gt;
  Password: *************&lt;br /&gt;
  xyz00@hsadmin&amp;gt; &lt;br /&gt;
&lt;br /&gt;
In &#039;&#039;hsadmin&#039;&#039; werden User und E-Mail-Adresse angelegt.&lt;br /&gt;
&lt;br /&gt;
  xyz00@hsadmin&amp;gt; user.add({set:{name:&#039;xyz00-list&#039;,comment:&#039;Mailingliste Discuss&#039;,shell:&#039;/bin/bash&#039;,password:&#039;geheimnis&#039;}})&lt;br /&gt;
  xyz00@hsadmin&amp;gt; emailaddress.add({set:{target:&#039;xyz00-list&#039;,localpart:&#039;discuss&#039;,domain:&#039;example.org&#039;}})&lt;br /&gt;
  xyz00@hsadmin&amp;gt; bye&lt;br /&gt;
&lt;br /&gt;
Mit dem Parameter &amp;quot;target&amp;quot; wird die für diese Adresse eingehende Post zunächst in das Postfach des Users xyz00-list abgelegt.&lt;br /&gt;
&lt;br /&gt;
Für den User xyz00-list lege ich in seinem Heimat-Verzeichnis das Unterverzeichnis &amp;lt;tt&amp;gt;mlmmj&amp;lt;/tt&amp;gt; an:&lt;br /&gt;
&lt;br /&gt;
  mkdir /home/pacs/xyz00/users/list/mlmmj&lt;br /&gt;
&lt;br /&gt;
Dann lege ich die Mailingliste mit folgendem Kommando an:&lt;br /&gt;
&lt;br /&gt;
  mlmmj-make-ml -L discuss -s /home/pacs/xyz00/users/list/mlmmj&lt;br /&gt;
&lt;br /&gt;
Das Skript &#039;&#039;mlmmj-make-ml&#039;&#039; fragt weitere Parameter der Mailingliste ab:&lt;br /&gt;
&lt;br /&gt;
  The Domain for the List? [] : example.org&lt;br /&gt;
  The emailaddress of the list owner? [postmaster] : webmaster@example.org&lt;br /&gt;
  For the list texts you can choose between the following languages or&lt;br /&gt;
  give an absolute path to a directory containing the texts.&lt;br /&gt;
  Available languages:&lt;br /&gt;
  cz  da	de  en	es  fr	it  nl	ru&lt;br /&gt;
  The path to texts for the list? [en] : de&lt;br /&gt;
&lt;br /&gt;
Das skript &#039;&#039;mlmmj-make-ml&#039;&#039; legt daraufhin unter &amp;quot;/home/pacs/xyz00/users/list/mlmmj&amp;quot; ein Verzeichnis &amp;quot;discuss&amp;quot; an, das die Datenstruktur zur Verwaltung der Mailingliste enthält.&lt;br /&gt;
&lt;br /&gt;
Weitere Konfigurationen der Liste erfolgen durch das Anlegen von Dateien im&lt;br /&gt;
Verzeichnis &amp;quot;/home/pacs/xyz00/users/list/mlmmj/discuss/control&amp;quot;.&lt;br /&gt;
Die Konfigurationsmöglichkeiten finden Sie auf der [http://mlmmj.org/docs/tunables/ Internetseite von mlmmj].&lt;br /&gt;
&lt;br /&gt;
Damit mlmmj die Verteilung der Post übernimmt, muß ich im Heimat-Verzeichnis des users xyz00-list die Datei &amp;lt;tt&amp;gt;.forward&amp;lt;/tt&amp;gt; mit folgenden Inhalt (INKLUSIVE der Anführungszeichen!) erstellen:&lt;br /&gt;
&lt;br /&gt;
  &amp;quot;|/usr/bin/mlmmj-recieve -L /home/pacs/xyz00/users/list/mlmmj/discuss/&amp;quot;&lt;br /&gt;
&lt;br /&gt;
(Ja, &#039;&#039;receive&#039;&#039; schreibt sich mit &#039;&#039;-ei-&#039;&#039;, aber mlmmj hält einen symbolischen Link bereit für diejenigen, die in englischer Rechtschreibung unsicher sind:)&lt;br /&gt;
&lt;br /&gt;
   xyz00-list@h03:~$ ls -la /usr/bin/mlmmj-rec*&lt;br /&gt;
   -rwxr-xr-x 1 root root 27104 Sep 25  2018 /usr/bin/mlmmj-receive&lt;br /&gt;
   lrwxrwxrwx 1 root root    13 Sep 25  2018 /usr/bin/mlmmj-recieve -&amp;gt; mlmmj-receive&lt;br /&gt;
&lt;br /&gt;
Die &amp;lt;tt&amp;gt;.forward&amp;lt;/tt&amp;gt;-Datei sorgt dafür, dass eingehende E-Mails an das User-Postfach an das Programm &#039;&#039;mlmmj-recieve&#039;&#039; übergeben werden.&lt;br /&gt;
&lt;br /&gt;
Für regelmäßige Aufgaben der Listen-Managers definiere ich die&lt;br /&gt;
[[Cron|crontab]] wie folgt (immer noch als &#039;&#039;xyz00-list&#039;&#039;):&lt;br /&gt;
&lt;br /&gt;
  xyz00-list@h03:~$ crontab -e&lt;br /&gt;
&lt;br /&gt;
 MAILTO=webmaster@example.org&lt;br /&gt;
 PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/X11R6/bin&lt;br /&gt;
 HOME=/home/pacs/xyz00/users/list&lt;br /&gt;
 SHELL=/bin/bash&lt;br /&gt;
 LANG=en_US.UTF-8&lt;br /&gt;
 # m h  dom mon dow   command&lt;br /&gt;
 28 */4 * * * /usr/bin/mlmmj-maintd -d /home/pacs/xyz00/users/list/mlmmj -F&lt;br /&gt;
&lt;br /&gt;
Zum Schluss rufe ich das Skript mlmmj-sub auf, um die E-Mail-Adressen der gewünschten Abonnenten des Verteilers einzutragen:&lt;br /&gt;
&lt;br /&gt;
 /usr/bin/mlmmj-sub -L /home/pacs/xyz00/users/list/mlmmj/discuss -a klaus.muster@gmx.de -c &lt;br /&gt;
 /usr/bin/mlmmj-sub -L /home/pacs/xyz00/users/list/mlmmj/discuss -a sabine.beispiel@arcor.de -c &lt;br /&gt;
&lt;br /&gt;
Dabei bewirkt &amp;quot;-c&amp;quot;, dass der Abonnent eine Begrüßungs-Nachricht erhält. Alternativ kann man &amp;quot;-C&amp;quot; (großes C) angeben: dann muss der Abonnent das Abo durch Antworten auf die Nachricht bestätigen.&lt;br /&gt;
&lt;br /&gt;
== weitere Optionen  ==&lt;br /&gt;
&lt;br /&gt;
Noch ein paar Dinge, die Sie möglicherweise einstellen wollen:&lt;br /&gt;
&lt;br /&gt;
Ein Prefix in der Betreffzeile setzen, z.B.: &amp;quot;[discuss]&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
 echo &amp;quot;[discuss]&amp;quot; &amp;gt; /home/pacs/xyz00/users/list/mlmmj/discuss/control/prefix&lt;br /&gt;
&lt;br /&gt;
Wenn die Liste nur E-Mails von eingetragenen Abonnenten weiterleiten soll:&lt;br /&gt;
&lt;br /&gt;
 touch /home/pacs/xyz00/users/list/mlmmj/discuss/control/subonlypost&lt;br /&gt;
&lt;br /&gt;
Damit der Listen-Owner weitere Abonnements bestätigen muss:&lt;br /&gt;
&lt;br /&gt;
 touch /home/pacs/xyz00/users/list/mlmmj/discuss/control/submod&lt;br /&gt;
&lt;br /&gt;
Einen &amp;quot;Reply-To:&amp;quot;-Header setzen, damit Antwort-Mails standardmäßig an die Mailing-Liste gehen:&lt;br /&gt;
&lt;br /&gt;
  echo &amp;quot;Reply-To:&amp;quot; &amp;gt; /home/pacs/xyz00/users/list/mlmmj/discuss/control/delheaders&lt;br /&gt;
  echo &amp;quot;Reply-To: discuss@example.org&amp;quot; &amp;gt; /home/pacs/xyz00/users/list/mlmmj/discuss/control/customheaders&lt;br /&gt;
&lt;br /&gt;
Weitere Möglichkeiten finden Sie (wie oben bereits angegeben) &lt;br /&gt;
auf der [http://mlmmj.org/docs/tunables/ Internetseite von mlmmj].&lt;br /&gt;
&lt;br /&gt;
== Zur Konfiguration im Browser ==&lt;br /&gt;
&lt;br /&gt;
Die Original-Distribution von &#039;&#039;mlmmj&#039;&#039; enthält ein paar einfache PHP- und Perl-Skripte.  Das sind Beispiele für Subscribe-/Unsubscribe-Formulare, ein Admin-Formular zum Eintragen und Löschen von Abonnements und eine Seite mit der gesamten Listen-Konfiguration.&lt;br /&gt;
&lt;br /&gt;
Wer es sich ansehen möchte:&lt;br /&gt;
&lt;br /&gt;
Als Paket-Admin eine Domain aufschalten:&lt;br /&gt;
&lt;br /&gt;
 hsscript -u xyz00 -e &amp;quot;domain.add({set:{name:&#039;lists.example.org&#039;,user:&#039;xyz00-list&#039;}})&amp;quot;&lt;br /&gt;
&lt;br /&gt;
Und weiter als &amp;quot;xyz00-list&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
Download der neuesten Version der Sourcen von mlmmj von http://mlmmj.org/downloads/ (noch besser: Download des aktuellen Debian-Pakets von [https://packages.debian.org/bookworm/all/mlmmj-php-web-admin/download debian.org]: da sind einige veraltete PHP-Ausdrücke schon herausgepatcht) und diese in einem temporären Verzeichnis entpacken (mit tar oder dpkg-deb).&lt;br /&gt;
&lt;br /&gt;
Unter &amp;quot;/mlmmj-$versionsnummer/contrib/web/php-admin/&amp;quot;, oder beim .deb-Paket unter &amp;quot;usr/share/mlmmj-...&amp;quot;, findet sich die PHP-Admin-Anwendung. Also ...&lt;br /&gt;
&lt;br /&gt;
* den Inhalt diese Verzeichnisses nach &amp;quot;/home/pacs/xyz00/users/list/doms/lists.example.org/&amp;quot; packen;&lt;br /&gt;
* in &amp;quot;/home/pacs/xyz00/users/list/doms/lists.example.org/conf/config.php&amp;quot; die Variable &amp;quot;$topdir&amp;quot; anpassen;&lt;br /&gt;
* die Dateien aus &amp;quot;/home/pacs/xyz00/users/list/doms/lists.example.org/htdocs/&amp;quot; nach &amp;quot;/home/pacs/xyz00/users/list/doms/lists.example.org/htdocs-ssl/&amp;quot; verschieben;&lt;br /&gt;
* Beim .deb-Paket die config.php, die templates/ und die tunables.pl aus etc/ nach example.org/conf/ verschieben;&lt;br /&gt;
* in &amp;quot;/home/pacs/xyz00/users/list/mlmmj&amp;quot; und in &amp;quot;/home/pacs/xyz00/users/list/doms/lists.example.org/htdocs-ssl/&amp;quot; eine &amp;quot;.htaccess&amp;quot; mit folgendem Inhalt ablegen: &lt;br /&gt;
 &lt;br /&gt;
 Require valid-user&lt;br /&gt;
 AuthType Basic&lt;br /&gt;
 AuthName &amp;quot;mlmmj web-interface&amp;quot;&lt;br /&gt;
 AuthUserFile /home/pacs/xyz00/users/list/doms/lists.example.org/etc/htpasswd&lt;br /&gt;
&lt;br /&gt;
* Und schließlich die &amp;quot;htpasswd&amp;quot;-Datei anlegen.&lt;br /&gt;
&lt;br /&gt;
 cd /home/pacs/xyz00/users/list/doms/lists.example.org/etc/&lt;br /&gt;
 htpasswd -c htpasswd listadmin&lt;br /&gt;
&lt;br /&gt;
* Ein Passwort angeben.&lt;br /&gt;
&lt;br /&gt;
Nun enthält diese PHP-Anwendung, wenn man sie nicht dem Debian-Paket entnommen hat, leider noch eine Zeile, die schon seit PHP 7 nicht mehr lauffähig ist. Also muß man noch&lt;br /&gt;
&lt;br /&gt;
* in &amp;lt;tt&amp;gt;.../htdocs-ssl/index.php&amp;lt;/tt&amp;gt; folgende Änderung vornehmen:&lt;br /&gt;
&lt;br /&gt;
  @@ -38,4 +38,5 @@&lt;br /&gt;
   # use scandir to have alphabetical order &lt;br /&gt;
   foreach (scandir($topdir) as $file) {&lt;br /&gt;
  -    if (!ereg(&amp;quot;^\.&amp;quot;,$file))&lt;br /&gt;
  +# ereg obsolete!! Vormals:    if (!ereg(&amp;quot;^\.&amp;quot;,$file))&lt;br /&gt;
  +    if (!preg_match(&#039;/^\./&#039;,$file))&lt;br /&gt;
       {&lt;br /&gt;
&lt;br /&gt;
und das Ergebnis auf https://lists.example.org anschauen.&lt;br /&gt;
&lt;br /&gt;
== Mehrere Mailinglisten betreiben ==&lt;br /&gt;
&lt;br /&gt;
Wenn mehrere Mailinglisten in einem Account und mit einer Admin-Oberfläche betrieben werden soll, empfiehlt sich die Nutzung von Procmail für den Aufruf von &#039;&#039;mlmmj&#039;&#039; für die jeweiligen Liste mit ihrem Daten-Verzeichnis.&lt;br /&gt;
&lt;br /&gt;
Dazu trägt man in der Datei &amp;lt;tt&amp;gt;.forward&amp;lt;/tt&amp;gt; statt des Aufrufs von &#039;&#039;mlmmj-recieve&#039;&#039; einen Aufruf von &#039;&#039;procmail&#039;&#039; ein:&lt;br /&gt;
&lt;br /&gt;
 |/usr/bin/procmail&lt;br /&gt;
&lt;br /&gt;
Die Konfiguration von Procmail kann generisch erfolgen. Dazu legt man eine Datei &amp;lt;tt&amp;gt;.procmailrc&amp;lt;/tt&amp;gt; mit folgendem Inhalt ins $HOME des Users:&lt;br /&gt;
&lt;br /&gt;
 SHELL=/bin/sh&lt;br /&gt;
 HOMEDIR=/home/pacs/xyz00/users/list&lt;br /&gt;
 MAILDIR=/home/pacs/xyz00/users/list/Maildir&lt;br /&gt;
 PMDIR=/home/pacs/xyz00/users/list&lt;br /&gt;
 VERBOSE=yes&lt;br /&gt;
 LOGFILE=/home/pacs/xyz00/users/list/var/procmail.log&lt;br /&gt;
 DEFAULT&lt;br /&gt;
 &lt;br /&gt;
 :0:&lt;br /&gt;
 * ^X-Original-To: ()\/[^@+]+&lt;br /&gt;
 |/usr/bin/mlmmj-receive -F -L /home/pacs/xyz00/users/list/mlmmj/${MATCH}/&lt;br /&gt;
 &lt;br /&gt;
 :0&lt;br /&gt;
 { EXITCODE 67 }&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Der kryptische reguläre Ausdruck hinter dem Header &#039;&#039;X-Original-To:&#039;&#039; passt auf den Beginn der E-Mail-Adresse bis zum ersten &#039;&#039;@&#039;&#039;- oder &#039;&#039;+&#039;&#039;-Zeichen. In der Variable &#039;&#039;MATCH&#039;&#039; steht also der Name der Mailingliste, d.h. der Name der Verzeichnisses, in dem die Liste verwaltet wird.&lt;br /&gt;
&lt;br /&gt;
Sehr wichtig ist die Zeile &#039;&#039;DEFAULT&#039;&#039; zu Beginn der &#039;&#039;.procmailrc&#039;&#039;. Die Variable &#039;&#039;DEFAULT&#039;&#039; wird von &#039;&#039;procmail&#039;&#039; gesetzt. Wir sorgen mit dieser Zeile dafür, dass sie wieder undefiniert ist. Diese Variable wird intern von &#039;&#039;mlmmj&#039;&#039; benutzt, wenn sie gesetzt ist. Das führt in Kombination mit &#039;&#039;procmail&#039;&#039; zu Fehlfunktionen (vgl. Links).&lt;br /&gt;
&lt;br /&gt;
Achtung, mit der Groß- und Kleinschreibung von Listennamen gibt es bei dieser Procmail-Lösung eine kleine Tücke. Procmail übernimmt in die Variable $MATCH genau die in der X-Original-To-Headerzeile vorgefundene Schreibweise, und diese kann denkbarerweise &amp;quot;Listen-Name&amp;quot; oder &amp;quot;listen-name&amp;quot; oder &amp;quot;Listen-name&amp;quot; sein. &amp;lt;tt&amp;gt;mlmmj&amp;lt;/tt&amp;gt; hingegen wird diesen Wert in Unix-Manier mit dem genauen Verzeichnisnamen &amp;lt;tt&amp;gt;${HOME}/mlmmj/listen-name&amp;lt;/tt&amp;gt; vergleichen, und bei unterschiedlicher Schreibweise die Mail nicht verteilen.&lt;br /&gt;
&lt;br /&gt;
Eine teilweise Lösung besteht darin, den Listennamen in dem &amp;lt;tt&amp;gt;mlmmj&amp;lt;/tt&amp;gt;-Aufruf in der &amp;lt;tt&amp;gt;.procmailrc&amp;lt;/tt&amp;gt; in Kleinbuchstaben umzuschreiben. Dann lautet das Rezept so:&lt;br /&gt;
&lt;br /&gt;
 :0:&lt;br /&gt;
 * ^X-Original-To: ()\/[^@+]+&lt;br /&gt;
 |/usr/bin/mlmmj-receive -F -L /home/pacs/xyz00/users/list/mlmmj/$(echo ${MATCH} | tr A-Z a-z)/&lt;br /&gt;
&lt;br /&gt;
Der Rest der Datei muß gleich bleiben, wie weiter oben angezeigt.&lt;br /&gt;
&lt;br /&gt;
In diesem Fall müssen aber alle Mailing-Listen ohne Großbuchstaben im Namen angelegt werden!&lt;br /&gt;
&lt;br /&gt;
(Man kann auch in &amp;lt;tt&amp;gt;${HOME}/mlmmj/&amp;lt;/tt&amp;gt; durch kleingeschriebene Symlinks großgeschriebene Listennamen ansprechbar machen:&lt;br /&gt;
&lt;br /&gt;
  xyz00-list@h02:~$ ls -lA mlmmj/&lt;br /&gt;
  total 8&lt;br /&gt;
  -rw-r--r--  1 xyz00-list xyz00  148 Feb  1 16:56 .htaccess&lt;br /&gt;
  lrwxrwxrwx  1 xyz00-list xyz00   10 Feb  2 18:01 mitglieder -&amp;gt; Mitglieder&lt;br /&gt;
  drwxr-xr-x 15 xyz00-list xyz00 4096 Feb  2 16:53 Mitglieder&lt;br /&gt;
&lt;br /&gt;
Das scheint zu funktionieren; Angabe ohne Gewähr.)&lt;br /&gt;
&lt;br /&gt;
== Links ==&lt;br /&gt;
&lt;br /&gt;
* http://mlmmj.org/ Projektseite&lt;br /&gt;
* https://codeberg.org/mlmmj mlmmj auf Codeberg&lt;br /&gt;
* https://github.com/tchapi/mlmmj-simple-web-interface ein Admin-Interface in NodeJS&lt;br /&gt;
* https://www.tablix.org/~avian/blog/archives/2010/04/the_faulty_default/ Nutzung von mlmmj in Verbindung mit Procmail&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
[[Kategorie:HSDoku]]&lt;br /&gt;
[[Kategorie:Installationsanleitungen]]&lt;br /&gt;
[[Kategorie:Software]]&lt;br /&gt;
[[Kategorie:Mailinglisten]]&lt;br /&gt;
[[Kategorie:E-Mail]]&lt;/div&gt;</summary>
		<author><name>Apc00-tony</name></author>
	</entry>
	<entry>
		<id>https://wiki.hostsharing.net/index.php?title=Mlmmj&amp;diff=6409</id>
		<title>Mlmmj</title>
		<link rel="alternate" type="text/html" href="https://wiki.hostsharing.net/index.php?title=Mlmmj&amp;diff=6409"/>
		<updated>2024-02-03T09:57:47Z</updated>

		<summary type="html">&lt;p&gt;Apc00-tony: /* Zur Konfiguration im Browser */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[http://www.mlmmj.org/ mlmmj], angeblich eine Abkürzung für &amp;quot;Mailing List Management Made Joyful&amp;quot;, ist ein Programm, mit dem in einem Hostsharing Paket E-Mail-Verteiler realisiert werden kann.&lt;br /&gt;
&lt;br /&gt;
Wer noch nicht weiß, was ein E-Mail-Verteiler machen soll oder wie, lese veilleicht auch den Wikipedia-Artikel:&lt;br /&gt;
[http://de.wikipedia.org/wiki/Mailingliste Mailingliste]&lt;br /&gt;
&lt;br /&gt;
Eine leistungsfähigere Alternative zu mlmmj könnte [[Mailman_3_installieren|Mailman 3]] sein.&lt;br /&gt;
&lt;br /&gt;
Diese Anleitung beschreibt die Einrichtung einer Mailingliste für eine Domain in einem Hostsharing-Webspace.&lt;br /&gt;
&lt;br /&gt;
== Voraussetzungen  ==&lt;br /&gt;
&lt;br /&gt;
Das Debian Paket [http://packages.debian.org/search?keywords=mlmmj mlmmj] ist auf den Shared-Hosting-Servern bereits installiert.&lt;br /&gt;
&lt;br /&gt;
Für den Betrieb der Mailingliste empfiehlt sich das Anlegen eines eigenen Users für diesen Zweck mit hsadmin.&lt;br /&gt;
&lt;br /&gt;
In dieser Anleitung heißt das Paket &#039;&#039;xyz00&#039;&#039; und der für Mailinglisten eingesetzte User &#039;&#039;xyz00-list&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
Die E-Mail-Adresse der einzurichtende Mailing-Liste soll &#039;&#039;discuss@example.org&#039;&#039; sein.&lt;br /&gt;
&lt;br /&gt;
Die Domain &#039;&#039;example.org&#039;&#039; muss dazu bei einem beliebigen User im Paket &#039;&#039;xyz00&#039;&#039; [[aufgeschaltet]] sein. (&amp;quot;Aufgeschaltet&amp;quot; bedeutet, daß diese Domain bei Hostsharing gehostet wird und der Domainname als Verzeichnis /home/pacs/xyz00/*User*/doms/example.org/ erscheint.)&lt;br /&gt;
&lt;br /&gt;
== Einrichtung ==&lt;br /&gt;
&lt;br /&gt;
Ich melde mich über SSH auf der Hostsharing-Console als der Paketuser &#039;&#039;xyz00&#039;&#039; an.&lt;br /&gt;
&lt;br /&gt;
Im Shell kann ich dann durch den Befehl &#039;&#039;hsscript -i&#039;&#039; das Verwaltungswerkzeug [[hsadmin]] interaktiv ausführen:&lt;br /&gt;
&lt;br /&gt;
  xyz00@h03:~$ hsscript -i&lt;br /&gt;
  Password: *************&lt;br /&gt;
  xyz00@hsadmin&amp;gt; &lt;br /&gt;
&lt;br /&gt;
In &#039;&#039;hsadmin&#039;&#039; werden User und E-Mail-Adresse angelegt.&lt;br /&gt;
&lt;br /&gt;
  xyz00@hsadmin&amp;gt; user.add({set:{name:&#039;xyz00-list&#039;,comment:&#039;Mailingliste Discuss&#039;,shell:&#039;/bin/bash&#039;,password:&#039;geheimnis&#039;}})&lt;br /&gt;
  xyz00@hsadmin&amp;gt; emailaddress.add({set:{target:&#039;xyz00-list&#039;,localpart:&#039;discuss&#039;,domain:&#039;example.org&#039;}})&lt;br /&gt;
  xyz00@hsadmin&amp;gt; bye&lt;br /&gt;
&lt;br /&gt;
Mit dem Parameter &amp;quot;target&amp;quot; wird die für diese Adresse eingehende Post zunächst in das Postfach des Users xyz00-list abgelegt.&lt;br /&gt;
&lt;br /&gt;
Für den User xyz00-list lege ich in seinem Heimat-Verzeichnis das Unterverzeichnis &amp;lt;tt&amp;gt;mlmmj&amp;lt;/tt&amp;gt; an:&lt;br /&gt;
&lt;br /&gt;
  mkdir /home/pacs/xyz00/users/list/mlmmj&lt;br /&gt;
&lt;br /&gt;
Dann lege ich die Mailingliste mit folgendem Kommando an:&lt;br /&gt;
&lt;br /&gt;
  mlmmj-make-ml -L discuss -s /home/pacs/xyz00/users/list/mlmmj&lt;br /&gt;
&lt;br /&gt;
Das Skript &#039;&#039;mlmmj-make-ml&#039;&#039; fragt weitere Parameter der Mailingliste ab:&lt;br /&gt;
&lt;br /&gt;
  The Domain for the List? [] : example.org&lt;br /&gt;
  The emailaddress of the list owner? [postmaster] : webmaster@example.org&lt;br /&gt;
  For the list texts you can choose between the following languages or&lt;br /&gt;
  give an absolute path to a directory containing the texts.&lt;br /&gt;
  Available languages:&lt;br /&gt;
  cz  da	de  en	es  fr	it  nl	ru&lt;br /&gt;
  The path to texts for the list? [en] : de&lt;br /&gt;
&lt;br /&gt;
Das skript &#039;&#039;mlmmj-make-ml&#039;&#039; legt daraufhin unter &amp;quot;/home/pacs/xyz00/users/list/mlmmj&amp;quot; ein Verzeichnis &amp;quot;discuss&amp;quot; an, das die Datenstruktur zur Verwaltung der Mailingliste enthält.&lt;br /&gt;
&lt;br /&gt;
Weitere Konfigurationen der Liste erfolgen durch das Anlegen von Dateien im&lt;br /&gt;
Verzeichnis &amp;quot;/home/pacs/xyz00/users/list/mlmmj/discuss/control&amp;quot;.&lt;br /&gt;
Die Konfigurationsmöglichkeiten finden Sie auf der [http://mlmmj.org/docs/tunables/ Internetseite von mlmmj].&lt;br /&gt;
&lt;br /&gt;
Damit mlmmj die Verteilung der Post übernimmt, muß ich im Heimat-Verzeichnis des users xyz00-list die Datei &amp;lt;tt&amp;gt;.forward&amp;lt;/tt&amp;gt; mit folgenden Inhalt (INKLUSIVE der Anführungszeichen!) erstellen:&lt;br /&gt;
&lt;br /&gt;
  &amp;quot;|/usr/bin/mlmmj-recieve -L /home/pacs/xyz00/users/list/mlmmj/discuss/&amp;quot;&lt;br /&gt;
&lt;br /&gt;
(Ja, &#039;&#039;receive&#039;&#039; schreibt sich mit &#039;&#039;-ei-&#039;&#039;, aber mlmmj hält einen symbolischen Link bereit für diejenigen, die in englischer Rechtschreibung unsicher sind:)&lt;br /&gt;
&lt;br /&gt;
   xyz00-list@h03:~$ ls -la /usr/bin/mlmmj-rec*&lt;br /&gt;
   -rwxr-xr-x 1 root root 27104 Sep 25  2018 /usr/bin/mlmmj-receive&lt;br /&gt;
   lrwxrwxrwx 1 root root    13 Sep 25  2018 /usr/bin/mlmmj-recieve -&amp;gt; mlmmj-receive&lt;br /&gt;
&lt;br /&gt;
Die &amp;lt;tt&amp;gt;.forward&amp;lt;/tt&amp;gt;-Datei sorgt dafür, dass eingehende E-Mails an das User-Postfach an das Programm &#039;&#039;mlmmj-recieve&#039;&#039; übergeben werden.&lt;br /&gt;
&lt;br /&gt;
Für regelmäßige Aufgaben der Listen-Managers definiere ich die&lt;br /&gt;
[[Cron|crontab]] wie folgt (immer noch als &#039;&#039;xyz00-list&#039;&#039;):&lt;br /&gt;
&lt;br /&gt;
  xyz00-list@h03:~$ crontab -e&lt;br /&gt;
&lt;br /&gt;
 MAILTO=webmaster@example.org&lt;br /&gt;
 PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/X11R6/bin&lt;br /&gt;
 HOME=/home/pacs/xyz00/users/list&lt;br /&gt;
 SHELL=/bin/bash&lt;br /&gt;
 LANG=en_US.UTF-8&lt;br /&gt;
 # m h  dom mon dow   command&lt;br /&gt;
 28 */4 * * * /usr/bin/mlmmj-maintd -d /home/pacs/xyz00/users/list/mlmmj -F&lt;br /&gt;
&lt;br /&gt;
Zum Schluss rufe ich das Skript mlmmj-sub auf, um die E-Mail-Adressen der gewünschten Abonnenten des Verteilers einzutragen:&lt;br /&gt;
&lt;br /&gt;
 /usr/bin/mlmmj-sub -L /home/pacs/xyz00/users/list/mlmmj/discuss -a klaus.muster@gmx.de -c &lt;br /&gt;
 /usr/bin/mlmmj-sub -L /home/pacs/xyz00/users/list/mlmmj/discuss -a sabine.beispiel@arcor.de -c &lt;br /&gt;
&lt;br /&gt;
Dabei bewirkt &amp;quot;-c&amp;quot;, dass der Abonnent eine Begrüßungs-Nachricht erhält. Alternativ kann man &amp;quot;-C&amp;quot; (großes C) angeben: dann muss der Abonnent das Abo durch Antworten auf die Nachricht bestätigen.&lt;br /&gt;
&lt;br /&gt;
== weitere Optionen  ==&lt;br /&gt;
&lt;br /&gt;
Noch ein paar Dinge, die Sie möglicherweise einstellen wollen:&lt;br /&gt;
&lt;br /&gt;
Ein Prefix in der Betreffzeile setzen, z.B.: &amp;quot;[discuss]&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
 echo &amp;quot;[discuss]&amp;quot; &amp;gt; /home/pacs/xyz00/users/list/mlmmj/discuss/control/prefix&lt;br /&gt;
&lt;br /&gt;
Wenn die Liste nur E-Mails von eingetragenen Abonnenten weiterleiten soll:&lt;br /&gt;
&lt;br /&gt;
 touch /home/pacs/xyz00/users/list/mlmmj/discuss/control/subonlypost&lt;br /&gt;
&lt;br /&gt;
Damit der Listen-Owner weitere Abonnements bestätigen muss:&lt;br /&gt;
&lt;br /&gt;
 touch /home/pacs/xyz00/users/list/mlmmj/discuss/control/submod&lt;br /&gt;
&lt;br /&gt;
Einen &amp;quot;Reply-To:&amp;quot;-Header setzen, damit Antwort-Mails standardmäßig an die Mailing-Liste gehen:&lt;br /&gt;
&lt;br /&gt;
  echo &amp;quot;Reply-To:&amp;quot; &amp;gt; /home/pacs/xyz00/users/list/mlmmj/discuss/control/delheaders&lt;br /&gt;
  echo &amp;quot;Reply-To: discuss@example.org&amp;quot; &amp;gt; /home/pacs/xyz00/users/list/mlmmj/discuss/control/customheaders&lt;br /&gt;
&lt;br /&gt;
Weitere Möglichkeiten finden Sie (wie oben bereits angegeben) &lt;br /&gt;
auf der [http://mlmmj.org/docs/tunables/ Internetseite von mlmmj].&lt;br /&gt;
&lt;br /&gt;
== Zur Konfiguration im Browser ==&lt;br /&gt;
&lt;br /&gt;
Die Original-Distribution von &#039;&#039;mlmmj&#039;&#039; enthält ein paar einfache PHP- und Perl-Skripte.  Das sind Beispiele für Subscribe-/Unsubscribe-Formulare, ein Admin-Formular zum Eintragen und Löschen von Abonnements und eine Seite mit der gesamten Listen-Konfiguration.&lt;br /&gt;
&lt;br /&gt;
Wer es sich ansehen möchte:&lt;br /&gt;
&lt;br /&gt;
Als Paket-Admin eine Domain aufschalten:&lt;br /&gt;
&lt;br /&gt;
 hsscript -u xyz00 -e &amp;quot;domain.add({set:{name:&#039;lists.example.org&#039;,user:&#039;xyz00-list&#039;}})&amp;quot;&lt;br /&gt;
&lt;br /&gt;
Und weiter als &amp;quot;xyz00-list&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
Download der neuesten Version der Sourcen von mlmmj von http://mlmmj.org/downloads/ (noch besser: Download des aktuellen Debian-Pakets von [https://packages.debian.org/bookworm/all/mlmmj-php-web-admin/download debian.org]: da sind einige veraltete PHP-Ausdrücke schon herausgepatcht) und diese in einem temporären Verzeichnis entpacken (mit tar oder dpkg-deb).&lt;br /&gt;
&lt;br /&gt;
Unter &amp;quot;/mlmmj-$versionsnummer/contrib/web/php-admin/&amp;quot;, oder beim .deb-Paket unter &amp;quot;usr/share/mlmmj-...&amp;quot;, findet sich die PHP-Admin-Anwendung. Also ...&lt;br /&gt;
&lt;br /&gt;
* den Inhalt diese Verzeichnisses nach &amp;quot;/home/pacs/xyz00/users/list/doms/lists.example.org/&amp;quot; packen;&lt;br /&gt;
* in &amp;quot;/home/pacs/xyz00/users/list/doms/lists.example.org/conf/config.php&amp;quot; die Variable &amp;quot;$topdir&amp;quot; anpassen;&lt;br /&gt;
* die Dateien aus &amp;quot;/home/pacs/xyz00/users/list/doms/lists.example.org/htdocs/&amp;quot; nach &amp;quot;/home/pacs/xyz00/users/list/doms/lists.example.org/htdocs-ssl/&amp;quot; verschieben;&lt;br /&gt;
* Beim .deb-Paket die config.php, die templates/ und die tunables.pl aus etc/ nach example.org/conf/ verschieben;&lt;br /&gt;
* in &amp;quot;/home/pacs/xyz00/users/list/mlmmj&amp;quot; und in &amp;quot;/home/pacs/xyz00/users/list/doms/lists.example.org/htdocs-ssl/&amp;quot; eine &amp;quot;.htaccess&amp;quot; mit folgendem Inhalt ablegen: &lt;br /&gt;
 &lt;br /&gt;
 Require valid-user&lt;br /&gt;
 AuthType Basic&lt;br /&gt;
 AuthName &amp;quot;mlmmj web-interface&amp;quot;&lt;br /&gt;
 AuthUserFile /home/pacs/xyz00/users/list/doms/lists.example.org/etc/htpasswd&lt;br /&gt;
&lt;br /&gt;
* Und schließlich die &amp;quot;htpasswd&amp;quot;-Datei anlegen.&lt;br /&gt;
&lt;br /&gt;
 cd /home/pacs/xyz00/users/list/doms/lists.example.org/etc/&lt;br /&gt;
 htpasswd -c htpasswd listadmin&lt;br /&gt;
&lt;br /&gt;
* Ein Passwort angeben.&lt;br /&gt;
&lt;br /&gt;
Nun enthält diese PHP-Anwendung leider noch eine Zeile, die schon seit PHP 7 nicht mehr lauffähig ist. Also muß man noch&lt;br /&gt;
&lt;br /&gt;
* in &amp;lt;tt&amp;gt;.../htdocs-ssl/index.php&amp;lt;/tt&amp;gt; folgende Änderung vornehmen:&lt;br /&gt;
&lt;br /&gt;
  @@ -38,4 +38,5 @@&lt;br /&gt;
   # use scandir to have alphabetical order &lt;br /&gt;
   foreach (scandir($topdir) as $file) {&lt;br /&gt;
  -    if (!ereg(&amp;quot;^\.&amp;quot;,$file))&lt;br /&gt;
  +# ereg obsolete!! Vormals:    if (!ereg(&amp;quot;^\.&amp;quot;,$file))&lt;br /&gt;
  +    if (!preg_match(&#039;/^\./&#039;,$file))&lt;br /&gt;
       {&lt;br /&gt;
&lt;br /&gt;
und das Ergebnis auf https://lists.example.org anschauen.&lt;br /&gt;
&lt;br /&gt;
== Mehrere Mailinglisten betreiben ==&lt;br /&gt;
&lt;br /&gt;
Wenn mehrere Mailinglisten in einem Account und mit einer Admin-Oberfläche betrieben werden soll, empfiehlt sich die Nutzung von Procmail für den Aufruf von &#039;&#039;mlmmj&#039;&#039; für die jeweiligen Liste mit ihrem Daten-Verzeichnis.&lt;br /&gt;
&lt;br /&gt;
Dazu trägt man in der Datei &amp;lt;tt&amp;gt;.forward&amp;lt;/tt&amp;gt; statt des Aufrufs von &#039;&#039;mlmmj-recieve&#039;&#039; einen Aufruf von &#039;&#039;procmail&#039;&#039; ein:&lt;br /&gt;
&lt;br /&gt;
 |/usr/bin/procmail&lt;br /&gt;
&lt;br /&gt;
Die Konfiguration von Procmail kann generisch erfolgen. Dazu legt man eine Datei &amp;lt;tt&amp;gt;.procmailrc&amp;lt;/tt&amp;gt; mit folgendem Inhalt ins $HOME des Users:&lt;br /&gt;
&lt;br /&gt;
 SHELL=/bin/sh&lt;br /&gt;
 HOMEDIR=/home/pacs/xyz00/users/list&lt;br /&gt;
 MAILDIR=/home/pacs/xyz00/users/list/Maildir&lt;br /&gt;
 PMDIR=/home/pacs/xyz00/users/list&lt;br /&gt;
 VERBOSE=yes&lt;br /&gt;
 LOGFILE=/home/pacs/xyz00/users/list/var/procmail.log&lt;br /&gt;
 DEFAULT&lt;br /&gt;
 &lt;br /&gt;
 :0:&lt;br /&gt;
 * ^X-Original-To: ()\/[^@+]+&lt;br /&gt;
 |/usr/bin/mlmmj-receive -F -L /home/pacs/xyz00/users/list/mlmmj/${MATCH}/&lt;br /&gt;
 &lt;br /&gt;
 :0&lt;br /&gt;
 { EXITCODE 67 }&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Der kryptische reguläre Ausdruck hinter dem Header &#039;&#039;X-Original-To:&#039;&#039; passt auf den Beginn der E-Mail-Adresse bis zum ersten &#039;&#039;@&#039;&#039;- oder &#039;&#039;+&#039;&#039;-Zeichen. In der Variable &#039;&#039;MATCH&#039;&#039; steht also der Name der Mailingliste, d.h. der Name der Verzeichnisses, in dem die Liste verwaltet wird.&lt;br /&gt;
&lt;br /&gt;
Sehr wichtig ist die Zeile &#039;&#039;DEFAULT&#039;&#039; zu Beginn der &#039;&#039;.procmailrc&#039;&#039;. Die Variable &#039;&#039;DEFAULT&#039;&#039; wird von &#039;&#039;procmail&#039;&#039; gesetzt. Wir sorgen mit dieser Zeile dafür, dass sie wieder undefiniert ist. Diese Variable wird intern von &#039;&#039;mlmmj&#039;&#039; benutzt, wenn sie gesetzt ist. Das führt in Kombination mit &#039;&#039;procmail&#039;&#039; zu Fehlfunktionen (vgl. Links).&lt;br /&gt;
&lt;br /&gt;
Achtung, mit der Groß- und Kleinschreibung von Listennamen gibt es bei dieser Procmail-Lösung eine kleine Tücke. Procmail übernimmt in die Variable $MATCH genau die in der X-Original-To-Headerzeile vorgefundene Schreibweise, und diese kann denkbarerweise &amp;quot;Listen-Name&amp;quot; oder &amp;quot;listen-name&amp;quot; oder &amp;quot;Listen-name&amp;quot; sein. &amp;lt;tt&amp;gt;mlmmj&amp;lt;/tt&amp;gt; hingegen wird diesen Wert in Unix-Manier mit dem genauen Verzeichnisnamen &amp;lt;tt&amp;gt;${HOME}/mlmmj/listen-name&amp;lt;/tt&amp;gt; vergleichen, und bei unterschiedlicher Schreibweise die Mail nicht verteilen.&lt;br /&gt;
&lt;br /&gt;
Eine teilweise Lösung besteht darin, den Listennamen in dem &amp;lt;tt&amp;gt;mlmmj&amp;lt;/tt&amp;gt;-Aufruf in der &amp;lt;tt&amp;gt;.procmailrc&amp;lt;/tt&amp;gt; in Kleinbuchstaben umzuschreiben. Dann lautet das Rezept so:&lt;br /&gt;
&lt;br /&gt;
 :0:&lt;br /&gt;
 * ^X-Original-To: ()\/[^@+]+&lt;br /&gt;
 |/usr/bin/mlmmj-receive -F -L /home/pacs/xyz00/users/list/mlmmj/$(echo ${MATCH} | tr A-Z a-z)/&lt;br /&gt;
&lt;br /&gt;
Der Rest der Datei muß gleich bleiben, wie weiter oben angezeigt.&lt;br /&gt;
&lt;br /&gt;
In diesem Fall müssen aber alle Mailing-Listen ohne Großbuchstaben im Namen angelegt werden!&lt;br /&gt;
&lt;br /&gt;
(Man kann auch in &amp;lt;tt&amp;gt;${HOME}/mlmmj/&amp;lt;/tt&amp;gt; durch kleingeschriebene Symlinks großgeschriebene Listennamen ansprechbar machen:&lt;br /&gt;
&lt;br /&gt;
  xyz00-list@h02:~$ ls -lA mlmmj/&lt;br /&gt;
  total 8&lt;br /&gt;
  -rw-r--r--  1 xyz00-list xyz00  148 Feb  1 16:56 .htaccess&lt;br /&gt;
  lrwxrwxrwx  1 xyz00-list xyz00   10 Feb  2 18:01 mitglieder -&amp;gt; Mitglieder&lt;br /&gt;
  drwxr-xr-x 15 xyz00-list xyz00 4096 Feb  2 16:53 Mitglieder&lt;br /&gt;
&lt;br /&gt;
Das scheint zu funktionieren; Angabe ohne Gewähr.)&lt;br /&gt;
&lt;br /&gt;
== Links ==&lt;br /&gt;
&lt;br /&gt;
* http://mlmmj.org/ Projektseite&lt;br /&gt;
* https://codeberg.org/mlmmj mlmmj auf Codeberg&lt;br /&gt;
* https://github.com/tchapi/mlmmj-simple-web-interface ein Admin-Interface in NodeJS&lt;br /&gt;
* https://www.tablix.org/~avian/blog/archives/2010/04/the_faulty_default/ Nutzung von mlmmj in Verbindung mit Procmail&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
[[Kategorie:HSDoku]]&lt;br /&gt;
[[Kategorie:Installationsanleitungen]]&lt;br /&gt;
[[Kategorie:Software]]&lt;br /&gt;
[[Kategorie:Mailinglisten]]&lt;br /&gt;
[[Kategorie:E-Mail]]&lt;/div&gt;</summary>
		<author><name>Apc00-tony</name></author>
	</entry>
	<entry>
		<id>https://wiki.hostsharing.net/index.php?title=Mlmmj&amp;diff=6408</id>
		<title>Mlmmj</title>
		<link rel="alternate" type="text/html" href="https://wiki.hostsharing.net/index.php?title=Mlmmj&amp;diff=6408"/>
		<updated>2024-02-03T09:56:24Z</updated>

		<summary type="html">&lt;p&gt;Apc00-tony: /* Zur Konfiguration im Browser */ web-admin aus debian&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[http://www.mlmmj.org/ mlmmj], angeblich eine Abkürzung für &amp;quot;Mailing List Management Made Joyful&amp;quot;, ist ein Programm, mit dem in einem Hostsharing Paket E-Mail-Verteiler realisiert werden kann.&lt;br /&gt;
&lt;br /&gt;
Wer noch nicht weiß, was ein E-Mail-Verteiler machen soll oder wie, lese veilleicht auch den Wikipedia-Artikel:&lt;br /&gt;
[http://de.wikipedia.org/wiki/Mailingliste Mailingliste]&lt;br /&gt;
&lt;br /&gt;
Eine leistungsfähigere Alternative zu mlmmj könnte [[Mailman_3_installieren|Mailman 3]] sein.&lt;br /&gt;
&lt;br /&gt;
Diese Anleitung beschreibt die Einrichtung einer Mailingliste für eine Domain in einem Hostsharing-Webspace.&lt;br /&gt;
&lt;br /&gt;
== Voraussetzungen  ==&lt;br /&gt;
&lt;br /&gt;
Das Debian Paket [http://packages.debian.org/search?keywords=mlmmj mlmmj] ist auf den Shared-Hosting-Servern bereits installiert.&lt;br /&gt;
&lt;br /&gt;
Für den Betrieb der Mailingliste empfiehlt sich das Anlegen eines eigenen Users für diesen Zweck mit hsadmin.&lt;br /&gt;
&lt;br /&gt;
In dieser Anleitung heißt das Paket &#039;&#039;xyz00&#039;&#039; und der für Mailinglisten eingesetzte User &#039;&#039;xyz00-list&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
Die E-Mail-Adresse der einzurichtende Mailing-Liste soll &#039;&#039;discuss@example.org&#039;&#039; sein.&lt;br /&gt;
&lt;br /&gt;
Die Domain &#039;&#039;example.org&#039;&#039; muss dazu bei einem beliebigen User im Paket &#039;&#039;xyz00&#039;&#039; [[aufgeschaltet]] sein. (&amp;quot;Aufgeschaltet&amp;quot; bedeutet, daß diese Domain bei Hostsharing gehostet wird und der Domainname als Verzeichnis /home/pacs/xyz00/*User*/doms/example.org/ erscheint.)&lt;br /&gt;
&lt;br /&gt;
== Einrichtung ==&lt;br /&gt;
&lt;br /&gt;
Ich melde mich über SSH auf der Hostsharing-Console als der Paketuser &#039;&#039;xyz00&#039;&#039; an.&lt;br /&gt;
&lt;br /&gt;
Im Shell kann ich dann durch den Befehl &#039;&#039;hsscript -i&#039;&#039; das Verwaltungswerkzeug [[hsadmin]] interaktiv ausführen:&lt;br /&gt;
&lt;br /&gt;
  xyz00@h03:~$ hsscript -i&lt;br /&gt;
  Password: *************&lt;br /&gt;
  xyz00@hsadmin&amp;gt; &lt;br /&gt;
&lt;br /&gt;
In &#039;&#039;hsadmin&#039;&#039; werden User und E-Mail-Adresse angelegt.&lt;br /&gt;
&lt;br /&gt;
  xyz00@hsadmin&amp;gt; user.add({set:{name:&#039;xyz00-list&#039;,comment:&#039;Mailingliste Discuss&#039;,shell:&#039;/bin/bash&#039;,password:&#039;geheimnis&#039;}})&lt;br /&gt;
  xyz00@hsadmin&amp;gt; emailaddress.add({set:{target:&#039;xyz00-list&#039;,localpart:&#039;discuss&#039;,domain:&#039;example.org&#039;}})&lt;br /&gt;
  xyz00@hsadmin&amp;gt; bye&lt;br /&gt;
&lt;br /&gt;
Mit dem Parameter &amp;quot;target&amp;quot; wird die für diese Adresse eingehende Post zunächst in das Postfach des Users xyz00-list abgelegt.&lt;br /&gt;
&lt;br /&gt;
Für den User xyz00-list lege ich in seinem Heimat-Verzeichnis das Unterverzeichnis &amp;lt;tt&amp;gt;mlmmj&amp;lt;/tt&amp;gt; an:&lt;br /&gt;
&lt;br /&gt;
  mkdir /home/pacs/xyz00/users/list/mlmmj&lt;br /&gt;
&lt;br /&gt;
Dann lege ich die Mailingliste mit folgendem Kommando an:&lt;br /&gt;
&lt;br /&gt;
  mlmmj-make-ml -L discuss -s /home/pacs/xyz00/users/list/mlmmj&lt;br /&gt;
&lt;br /&gt;
Das Skript &#039;&#039;mlmmj-make-ml&#039;&#039; fragt weitere Parameter der Mailingliste ab:&lt;br /&gt;
&lt;br /&gt;
  The Domain for the List? [] : example.org&lt;br /&gt;
  The emailaddress of the list owner? [postmaster] : webmaster@example.org&lt;br /&gt;
  For the list texts you can choose between the following languages or&lt;br /&gt;
  give an absolute path to a directory containing the texts.&lt;br /&gt;
  Available languages:&lt;br /&gt;
  cz  da	de  en	es  fr	it  nl	ru&lt;br /&gt;
  The path to texts for the list? [en] : de&lt;br /&gt;
&lt;br /&gt;
Das skript &#039;&#039;mlmmj-make-ml&#039;&#039; legt daraufhin unter &amp;quot;/home/pacs/xyz00/users/list/mlmmj&amp;quot; ein Verzeichnis &amp;quot;discuss&amp;quot; an, das die Datenstruktur zur Verwaltung der Mailingliste enthält.&lt;br /&gt;
&lt;br /&gt;
Weitere Konfigurationen der Liste erfolgen durch das Anlegen von Dateien im&lt;br /&gt;
Verzeichnis &amp;quot;/home/pacs/xyz00/users/list/mlmmj/discuss/control&amp;quot;.&lt;br /&gt;
Die Konfigurationsmöglichkeiten finden Sie auf der [http://mlmmj.org/docs/tunables/ Internetseite von mlmmj].&lt;br /&gt;
&lt;br /&gt;
Damit mlmmj die Verteilung der Post übernimmt, muß ich im Heimat-Verzeichnis des users xyz00-list die Datei &amp;lt;tt&amp;gt;.forward&amp;lt;/tt&amp;gt; mit folgenden Inhalt (INKLUSIVE der Anführungszeichen!) erstellen:&lt;br /&gt;
&lt;br /&gt;
  &amp;quot;|/usr/bin/mlmmj-recieve -L /home/pacs/xyz00/users/list/mlmmj/discuss/&amp;quot;&lt;br /&gt;
&lt;br /&gt;
(Ja, &#039;&#039;receive&#039;&#039; schreibt sich mit &#039;&#039;-ei-&#039;&#039;, aber mlmmj hält einen symbolischen Link bereit für diejenigen, die in englischer Rechtschreibung unsicher sind:)&lt;br /&gt;
&lt;br /&gt;
   xyz00-list@h03:~$ ls -la /usr/bin/mlmmj-rec*&lt;br /&gt;
   -rwxr-xr-x 1 root root 27104 Sep 25  2018 /usr/bin/mlmmj-receive&lt;br /&gt;
   lrwxrwxrwx 1 root root    13 Sep 25  2018 /usr/bin/mlmmj-recieve -&amp;gt; mlmmj-receive&lt;br /&gt;
&lt;br /&gt;
Die &amp;lt;tt&amp;gt;.forward&amp;lt;/tt&amp;gt;-Datei sorgt dafür, dass eingehende E-Mails an das User-Postfach an das Programm &#039;&#039;mlmmj-recieve&#039;&#039; übergeben werden.&lt;br /&gt;
&lt;br /&gt;
Für regelmäßige Aufgaben der Listen-Managers definiere ich die&lt;br /&gt;
[[Cron|crontab]] wie folgt (immer noch als &#039;&#039;xyz00-list&#039;&#039;):&lt;br /&gt;
&lt;br /&gt;
  xyz00-list@h03:~$ crontab -e&lt;br /&gt;
&lt;br /&gt;
 MAILTO=webmaster@example.org&lt;br /&gt;
 PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/X11R6/bin&lt;br /&gt;
 HOME=/home/pacs/xyz00/users/list&lt;br /&gt;
 SHELL=/bin/bash&lt;br /&gt;
 LANG=en_US.UTF-8&lt;br /&gt;
 # m h  dom mon dow   command&lt;br /&gt;
 28 */4 * * * /usr/bin/mlmmj-maintd -d /home/pacs/xyz00/users/list/mlmmj -F&lt;br /&gt;
&lt;br /&gt;
Zum Schluss rufe ich das Skript mlmmj-sub auf, um die E-Mail-Adressen der gewünschten Abonnenten des Verteilers einzutragen:&lt;br /&gt;
&lt;br /&gt;
 /usr/bin/mlmmj-sub -L /home/pacs/xyz00/users/list/mlmmj/discuss -a klaus.muster@gmx.de -c &lt;br /&gt;
 /usr/bin/mlmmj-sub -L /home/pacs/xyz00/users/list/mlmmj/discuss -a sabine.beispiel@arcor.de -c &lt;br /&gt;
&lt;br /&gt;
Dabei bewirkt &amp;quot;-c&amp;quot;, dass der Abonnent eine Begrüßungs-Nachricht erhält. Alternativ kann man &amp;quot;-C&amp;quot; (großes C) angeben: dann muss der Abonnent das Abo durch Antworten auf die Nachricht bestätigen.&lt;br /&gt;
&lt;br /&gt;
== weitere Optionen  ==&lt;br /&gt;
&lt;br /&gt;
Noch ein paar Dinge, die Sie möglicherweise einstellen wollen:&lt;br /&gt;
&lt;br /&gt;
Ein Prefix in der Betreffzeile setzen, z.B.: &amp;quot;[discuss]&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
 echo &amp;quot;[discuss]&amp;quot; &amp;gt; /home/pacs/xyz00/users/list/mlmmj/discuss/control/prefix&lt;br /&gt;
&lt;br /&gt;
Wenn die Liste nur E-Mails von eingetragenen Abonnenten weiterleiten soll:&lt;br /&gt;
&lt;br /&gt;
 touch /home/pacs/xyz00/users/list/mlmmj/discuss/control/subonlypost&lt;br /&gt;
&lt;br /&gt;
Damit der Listen-Owner weitere Abonnements bestätigen muss:&lt;br /&gt;
&lt;br /&gt;
 touch /home/pacs/xyz00/users/list/mlmmj/discuss/control/submod&lt;br /&gt;
&lt;br /&gt;
Einen &amp;quot;Reply-To:&amp;quot;-Header setzen, damit Antwort-Mails standardmäßig an die Mailing-Liste gehen:&lt;br /&gt;
&lt;br /&gt;
  echo &amp;quot;Reply-To:&amp;quot; &amp;gt; /home/pacs/xyz00/users/list/mlmmj/discuss/control/delheaders&lt;br /&gt;
  echo &amp;quot;Reply-To: discuss@example.org&amp;quot; &amp;gt; /home/pacs/xyz00/users/list/mlmmj/discuss/control/customheaders&lt;br /&gt;
&lt;br /&gt;
Weitere Möglichkeiten finden Sie (wie oben bereits angegeben) &lt;br /&gt;
auf der [http://mlmmj.org/docs/tunables/ Internetseite von mlmmj].&lt;br /&gt;
&lt;br /&gt;
== Zur Konfiguration im Browser ==&lt;br /&gt;
&lt;br /&gt;
Die Original-Distribution von &#039;&#039;mlmmj&#039;&#039; enthält ein paar einfache PHP- und Perl-Skripte.  Das sind Beispiele für Subscribe-/Unsubscribe-Formulare, ein Admin-Formular zum Eintragen und Löschen von Abonnements und eine Seite mit der gesamten Listen-Konfiguration.&lt;br /&gt;
&lt;br /&gt;
Wer es sich ansehen möchte:&lt;br /&gt;
&lt;br /&gt;
Als Paket-Admin eine Domain aufschalten:&lt;br /&gt;
&lt;br /&gt;
 hsscript -u xyz00 -e &amp;quot;domain.add({set:{name:&#039;lists.example.org&#039;,user:&#039;xyz00-list&#039;}})&amp;quot;&lt;br /&gt;
&lt;br /&gt;
Und weiter als &amp;quot;xyz00-list&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
Download der neuesten Version der Sourcen von mlmmj von http://mlmmj.org/downloads/ (noch besser: Download des aktuellen Debian-Pakets von [https://packages.debian.org/bookworm/all/mlmmj-php-web-admin/download]: da sind einige veraltete PHP-Ausdrücke schon herausgepatcht) und diese in einem temporären Verzeichnis entpacken (mit tar oder dpkg-deb).&lt;br /&gt;
&lt;br /&gt;
Unter &amp;quot;/mlmmj-$versionsnummer/contrib/web/php-admin/&amp;quot;, oder beim .deb-Paket unter &amp;quot;usr/share/mlmmj-...&amp;quot;, findet sich die PHP-Admin-Anwendung. Also ...&lt;br /&gt;
&lt;br /&gt;
* den Inhalt diese Verzeichnisses nach &amp;quot;/home/pacs/xyz00/users/list/doms/lists.example.org/&amp;quot; packen;&lt;br /&gt;
* in &amp;quot;/home/pacs/xyz00/users/list/doms/lists.example.org/conf/config.php&amp;quot; die Variable &amp;quot;$topdir&amp;quot; anpassen;&lt;br /&gt;
* die Dateien aus &amp;quot;/home/pacs/xyz00/users/list/doms/lists.example.org/htdocs/&amp;quot; nach &amp;quot;/home/pacs/xyz00/users/list/doms/lists.example.org/htdocs-ssl/&amp;quot; verschieben;&lt;br /&gt;
* Beim .deb-Paket die config.php, die templates/ und die tunables.pl aus etc/ nach example.org/conf/ verschieben;&lt;br /&gt;
* in &amp;quot;/home/pacs/xyz00/users/list/mlmmj&amp;quot; und in &amp;quot;/home/pacs/xyz00/users/list/doms/lists.example.org/htdocs-ssl/&amp;quot; eine &amp;quot;.htaccess&amp;quot; mit folgendem Inhalt ablegen: &lt;br /&gt;
 &lt;br /&gt;
 Require valid-user&lt;br /&gt;
 AuthType Basic&lt;br /&gt;
 AuthName &amp;quot;mlmmj web-interface&amp;quot;&lt;br /&gt;
 AuthUserFile /home/pacs/xyz00/users/list/doms/lists.example.org/etc/htpasswd&lt;br /&gt;
&lt;br /&gt;
* Und schließlich die &amp;quot;htpasswd&amp;quot;-Datei anlegen.&lt;br /&gt;
&lt;br /&gt;
 cd /home/pacs/xyz00/users/list/doms/lists.example.org/etc/&lt;br /&gt;
 htpasswd -c htpasswd listadmin&lt;br /&gt;
&lt;br /&gt;
* Ein Passwort angeben.&lt;br /&gt;
&lt;br /&gt;
Nun enthält diese PHP-Anwendung leider noch eine Zeile, die schon seit PHP 7 nicht mehr lauffähig ist. Also muß man noch&lt;br /&gt;
&lt;br /&gt;
* in &amp;lt;tt&amp;gt;.../htdocs-ssl/index.php&amp;lt;/tt&amp;gt; folgende Änderung vornehmen:&lt;br /&gt;
&lt;br /&gt;
  @@ -38,4 +38,5 @@&lt;br /&gt;
   # use scandir to have alphabetical order &lt;br /&gt;
   foreach (scandir($topdir) as $file) {&lt;br /&gt;
  -    if (!ereg(&amp;quot;^\.&amp;quot;,$file))&lt;br /&gt;
  +# ereg obsolete!! Vormals:    if (!ereg(&amp;quot;^\.&amp;quot;,$file))&lt;br /&gt;
  +    if (!preg_match(&#039;/^\./&#039;,$file))&lt;br /&gt;
       {&lt;br /&gt;
&lt;br /&gt;
und das Ergebnis auf https://lists.example.org anschauen.&lt;br /&gt;
&lt;br /&gt;
== Mehrere Mailinglisten betreiben ==&lt;br /&gt;
&lt;br /&gt;
Wenn mehrere Mailinglisten in einem Account und mit einer Admin-Oberfläche betrieben werden soll, empfiehlt sich die Nutzung von Procmail für den Aufruf von &#039;&#039;mlmmj&#039;&#039; für die jeweiligen Liste mit ihrem Daten-Verzeichnis.&lt;br /&gt;
&lt;br /&gt;
Dazu trägt man in der Datei &amp;lt;tt&amp;gt;.forward&amp;lt;/tt&amp;gt; statt des Aufrufs von &#039;&#039;mlmmj-recieve&#039;&#039; einen Aufruf von &#039;&#039;procmail&#039;&#039; ein:&lt;br /&gt;
&lt;br /&gt;
 |/usr/bin/procmail&lt;br /&gt;
&lt;br /&gt;
Die Konfiguration von Procmail kann generisch erfolgen. Dazu legt man eine Datei &amp;lt;tt&amp;gt;.procmailrc&amp;lt;/tt&amp;gt; mit folgendem Inhalt ins $HOME des Users:&lt;br /&gt;
&lt;br /&gt;
 SHELL=/bin/sh&lt;br /&gt;
 HOMEDIR=/home/pacs/xyz00/users/list&lt;br /&gt;
 MAILDIR=/home/pacs/xyz00/users/list/Maildir&lt;br /&gt;
 PMDIR=/home/pacs/xyz00/users/list&lt;br /&gt;
 VERBOSE=yes&lt;br /&gt;
 LOGFILE=/home/pacs/xyz00/users/list/var/procmail.log&lt;br /&gt;
 DEFAULT&lt;br /&gt;
 &lt;br /&gt;
 :0:&lt;br /&gt;
 * ^X-Original-To: ()\/[^@+]+&lt;br /&gt;
 |/usr/bin/mlmmj-receive -F -L /home/pacs/xyz00/users/list/mlmmj/${MATCH}/&lt;br /&gt;
 &lt;br /&gt;
 :0&lt;br /&gt;
 { EXITCODE 67 }&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Der kryptische reguläre Ausdruck hinter dem Header &#039;&#039;X-Original-To:&#039;&#039; passt auf den Beginn der E-Mail-Adresse bis zum ersten &#039;&#039;@&#039;&#039;- oder &#039;&#039;+&#039;&#039;-Zeichen. In der Variable &#039;&#039;MATCH&#039;&#039; steht also der Name der Mailingliste, d.h. der Name der Verzeichnisses, in dem die Liste verwaltet wird.&lt;br /&gt;
&lt;br /&gt;
Sehr wichtig ist die Zeile &#039;&#039;DEFAULT&#039;&#039; zu Beginn der &#039;&#039;.procmailrc&#039;&#039;. Die Variable &#039;&#039;DEFAULT&#039;&#039; wird von &#039;&#039;procmail&#039;&#039; gesetzt. Wir sorgen mit dieser Zeile dafür, dass sie wieder undefiniert ist. Diese Variable wird intern von &#039;&#039;mlmmj&#039;&#039; benutzt, wenn sie gesetzt ist. Das führt in Kombination mit &#039;&#039;procmail&#039;&#039; zu Fehlfunktionen (vgl. Links).&lt;br /&gt;
&lt;br /&gt;
Achtung, mit der Groß- und Kleinschreibung von Listennamen gibt es bei dieser Procmail-Lösung eine kleine Tücke. Procmail übernimmt in die Variable $MATCH genau die in der X-Original-To-Headerzeile vorgefundene Schreibweise, und diese kann denkbarerweise &amp;quot;Listen-Name&amp;quot; oder &amp;quot;listen-name&amp;quot; oder &amp;quot;Listen-name&amp;quot; sein. &amp;lt;tt&amp;gt;mlmmj&amp;lt;/tt&amp;gt; hingegen wird diesen Wert in Unix-Manier mit dem genauen Verzeichnisnamen &amp;lt;tt&amp;gt;${HOME}/mlmmj/listen-name&amp;lt;/tt&amp;gt; vergleichen, und bei unterschiedlicher Schreibweise die Mail nicht verteilen.&lt;br /&gt;
&lt;br /&gt;
Eine teilweise Lösung besteht darin, den Listennamen in dem &amp;lt;tt&amp;gt;mlmmj&amp;lt;/tt&amp;gt;-Aufruf in der &amp;lt;tt&amp;gt;.procmailrc&amp;lt;/tt&amp;gt; in Kleinbuchstaben umzuschreiben. Dann lautet das Rezept so:&lt;br /&gt;
&lt;br /&gt;
 :0:&lt;br /&gt;
 * ^X-Original-To: ()\/[^@+]+&lt;br /&gt;
 |/usr/bin/mlmmj-receive -F -L /home/pacs/xyz00/users/list/mlmmj/$(echo ${MATCH} | tr A-Z a-z)/&lt;br /&gt;
&lt;br /&gt;
Der Rest der Datei muß gleich bleiben, wie weiter oben angezeigt.&lt;br /&gt;
&lt;br /&gt;
In diesem Fall müssen aber alle Mailing-Listen ohne Großbuchstaben im Namen angelegt werden!&lt;br /&gt;
&lt;br /&gt;
(Man kann auch in &amp;lt;tt&amp;gt;${HOME}/mlmmj/&amp;lt;/tt&amp;gt; durch kleingeschriebene Symlinks großgeschriebene Listennamen ansprechbar machen:&lt;br /&gt;
&lt;br /&gt;
  xyz00-list@h02:~$ ls -lA mlmmj/&lt;br /&gt;
  total 8&lt;br /&gt;
  -rw-r--r--  1 xyz00-list xyz00  148 Feb  1 16:56 .htaccess&lt;br /&gt;
  lrwxrwxrwx  1 xyz00-list xyz00   10 Feb  2 18:01 mitglieder -&amp;gt; Mitglieder&lt;br /&gt;
  drwxr-xr-x 15 xyz00-list xyz00 4096 Feb  2 16:53 Mitglieder&lt;br /&gt;
&lt;br /&gt;
Das scheint zu funktionieren; Angabe ohne Gewähr.)&lt;br /&gt;
&lt;br /&gt;
== Links ==&lt;br /&gt;
&lt;br /&gt;
* http://mlmmj.org/ Projektseite&lt;br /&gt;
* https://codeberg.org/mlmmj mlmmj auf Codeberg&lt;br /&gt;
* https://github.com/tchapi/mlmmj-simple-web-interface ein Admin-Interface in NodeJS&lt;br /&gt;
* https://www.tablix.org/~avian/blog/archives/2010/04/the_faulty_default/ Nutzung von mlmmj in Verbindung mit Procmail&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
[[Kategorie:HSDoku]]&lt;br /&gt;
[[Kategorie:Installationsanleitungen]]&lt;br /&gt;
[[Kategorie:Software]]&lt;br /&gt;
[[Kategorie:Mailinglisten]]&lt;br /&gt;
[[Kategorie:E-Mail]]&lt;/div&gt;</summary>
		<author><name>Apc00-tony</name></author>
	</entry>
	<entry>
		<id>https://wiki.hostsharing.net/index.php?title=Mlmmj&amp;diff=6407</id>
		<title>Mlmmj</title>
		<link rel="alternate" type="text/html" href="https://wiki.hostsharing.net/index.php?title=Mlmmj&amp;diff=6407"/>
		<updated>2024-02-03T09:48:21Z</updated>

		<summary type="html">&lt;p&gt;Apc00-tony: /* Mehrere Mailinglisten betreiben */ Tücken bei Procmail&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[http://www.mlmmj.org/ mlmmj], angeblich eine Abkürzung für &amp;quot;Mailing List Management Made Joyful&amp;quot;, ist ein Programm, mit dem in einem Hostsharing Paket E-Mail-Verteiler realisiert werden kann.&lt;br /&gt;
&lt;br /&gt;
Wer noch nicht weiß, was ein E-Mail-Verteiler machen soll oder wie, lese veilleicht auch den Wikipedia-Artikel:&lt;br /&gt;
[http://de.wikipedia.org/wiki/Mailingliste Mailingliste]&lt;br /&gt;
&lt;br /&gt;
Eine leistungsfähigere Alternative zu mlmmj könnte [[Mailman_3_installieren|Mailman 3]] sein.&lt;br /&gt;
&lt;br /&gt;
Diese Anleitung beschreibt die Einrichtung einer Mailingliste für eine Domain in einem Hostsharing-Webspace.&lt;br /&gt;
&lt;br /&gt;
== Voraussetzungen  ==&lt;br /&gt;
&lt;br /&gt;
Das Debian Paket [http://packages.debian.org/search?keywords=mlmmj mlmmj] ist auf den Shared-Hosting-Servern bereits installiert.&lt;br /&gt;
&lt;br /&gt;
Für den Betrieb der Mailingliste empfiehlt sich das Anlegen eines eigenen Users für diesen Zweck mit hsadmin.&lt;br /&gt;
&lt;br /&gt;
In dieser Anleitung heißt das Paket &#039;&#039;xyz00&#039;&#039; und der für Mailinglisten eingesetzte User &#039;&#039;xyz00-list&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
Die E-Mail-Adresse der einzurichtende Mailing-Liste soll &#039;&#039;discuss@example.org&#039;&#039; sein.&lt;br /&gt;
&lt;br /&gt;
Die Domain &#039;&#039;example.org&#039;&#039; muss dazu bei einem beliebigen User im Paket &#039;&#039;xyz00&#039;&#039; [[aufgeschaltet]] sein. (&amp;quot;Aufgeschaltet&amp;quot; bedeutet, daß diese Domain bei Hostsharing gehostet wird und der Domainname als Verzeichnis /home/pacs/xyz00/*User*/doms/example.org/ erscheint.)&lt;br /&gt;
&lt;br /&gt;
== Einrichtung ==&lt;br /&gt;
&lt;br /&gt;
Ich melde mich über SSH auf der Hostsharing-Console als der Paketuser &#039;&#039;xyz00&#039;&#039; an.&lt;br /&gt;
&lt;br /&gt;
Im Shell kann ich dann durch den Befehl &#039;&#039;hsscript -i&#039;&#039; das Verwaltungswerkzeug [[hsadmin]] interaktiv ausführen:&lt;br /&gt;
&lt;br /&gt;
  xyz00@h03:~$ hsscript -i&lt;br /&gt;
  Password: *************&lt;br /&gt;
  xyz00@hsadmin&amp;gt; &lt;br /&gt;
&lt;br /&gt;
In &#039;&#039;hsadmin&#039;&#039; werden User und E-Mail-Adresse angelegt.&lt;br /&gt;
&lt;br /&gt;
  xyz00@hsadmin&amp;gt; user.add({set:{name:&#039;xyz00-list&#039;,comment:&#039;Mailingliste Discuss&#039;,shell:&#039;/bin/bash&#039;,password:&#039;geheimnis&#039;}})&lt;br /&gt;
  xyz00@hsadmin&amp;gt; emailaddress.add({set:{target:&#039;xyz00-list&#039;,localpart:&#039;discuss&#039;,domain:&#039;example.org&#039;}})&lt;br /&gt;
  xyz00@hsadmin&amp;gt; bye&lt;br /&gt;
&lt;br /&gt;
Mit dem Parameter &amp;quot;target&amp;quot; wird die für diese Adresse eingehende Post zunächst in das Postfach des Users xyz00-list abgelegt.&lt;br /&gt;
&lt;br /&gt;
Für den User xyz00-list lege ich in seinem Heimat-Verzeichnis das Unterverzeichnis &amp;lt;tt&amp;gt;mlmmj&amp;lt;/tt&amp;gt; an:&lt;br /&gt;
&lt;br /&gt;
  mkdir /home/pacs/xyz00/users/list/mlmmj&lt;br /&gt;
&lt;br /&gt;
Dann lege ich die Mailingliste mit folgendem Kommando an:&lt;br /&gt;
&lt;br /&gt;
  mlmmj-make-ml -L discuss -s /home/pacs/xyz00/users/list/mlmmj&lt;br /&gt;
&lt;br /&gt;
Das Skript &#039;&#039;mlmmj-make-ml&#039;&#039; fragt weitere Parameter der Mailingliste ab:&lt;br /&gt;
&lt;br /&gt;
  The Domain for the List? [] : example.org&lt;br /&gt;
  The emailaddress of the list owner? [postmaster] : webmaster@example.org&lt;br /&gt;
  For the list texts you can choose between the following languages or&lt;br /&gt;
  give an absolute path to a directory containing the texts.&lt;br /&gt;
  Available languages:&lt;br /&gt;
  cz  da	de  en	es  fr	it  nl	ru&lt;br /&gt;
  The path to texts for the list? [en] : de&lt;br /&gt;
&lt;br /&gt;
Das skript &#039;&#039;mlmmj-make-ml&#039;&#039; legt daraufhin unter &amp;quot;/home/pacs/xyz00/users/list/mlmmj&amp;quot; ein Verzeichnis &amp;quot;discuss&amp;quot; an, das die Datenstruktur zur Verwaltung der Mailingliste enthält.&lt;br /&gt;
&lt;br /&gt;
Weitere Konfigurationen der Liste erfolgen durch das Anlegen von Dateien im&lt;br /&gt;
Verzeichnis &amp;quot;/home/pacs/xyz00/users/list/mlmmj/discuss/control&amp;quot;.&lt;br /&gt;
Die Konfigurationsmöglichkeiten finden Sie auf der [http://mlmmj.org/docs/tunables/ Internetseite von mlmmj].&lt;br /&gt;
&lt;br /&gt;
Damit mlmmj die Verteilung der Post übernimmt, muß ich im Heimat-Verzeichnis des users xyz00-list die Datei &amp;lt;tt&amp;gt;.forward&amp;lt;/tt&amp;gt; mit folgenden Inhalt (INKLUSIVE der Anführungszeichen!) erstellen:&lt;br /&gt;
&lt;br /&gt;
  &amp;quot;|/usr/bin/mlmmj-recieve -L /home/pacs/xyz00/users/list/mlmmj/discuss/&amp;quot;&lt;br /&gt;
&lt;br /&gt;
(Ja, &#039;&#039;receive&#039;&#039; schreibt sich mit &#039;&#039;-ei-&#039;&#039;, aber mlmmj hält einen symbolischen Link bereit für diejenigen, die in englischer Rechtschreibung unsicher sind:)&lt;br /&gt;
&lt;br /&gt;
   xyz00-list@h03:~$ ls -la /usr/bin/mlmmj-rec*&lt;br /&gt;
   -rwxr-xr-x 1 root root 27104 Sep 25  2018 /usr/bin/mlmmj-receive&lt;br /&gt;
   lrwxrwxrwx 1 root root    13 Sep 25  2018 /usr/bin/mlmmj-recieve -&amp;gt; mlmmj-receive&lt;br /&gt;
&lt;br /&gt;
Die &amp;lt;tt&amp;gt;.forward&amp;lt;/tt&amp;gt;-Datei sorgt dafür, dass eingehende E-Mails an das User-Postfach an das Programm &#039;&#039;mlmmj-recieve&#039;&#039; übergeben werden.&lt;br /&gt;
&lt;br /&gt;
Für regelmäßige Aufgaben der Listen-Managers definiere ich die&lt;br /&gt;
[[Cron|crontab]] wie folgt (immer noch als &#039;&#039;xyz00-list&#039;&#039;):&lt;br /&gt;
&lt;br /&gt;
  xyz00-list@h03:~$ crontab -e&lt;br /&gt;
&lt;br /&gt;
 MAILTO=webmaster@example.org&lt;br /&gt;
 PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/X11R6/bin&lt;br /&gt;
 HOME=/home/pacs/xyz00/users/list&lt;br /&gt;
 SHELL=/bin/bash&lt;br /&gt;
 LANG=en_US.UTF-8&lt;br /&gt;
 # m h  dom mon dow   command&lt;br /&gt;
 28 */4 * * * /usr/bin/mlmmj-maintd -d /home/pacs/xyz00/users/list/mlmmj -F&lt;br /&gt;
&lt;br /&gt;
Zum Schluss rufe ich das Skript mlmmj-sub auf, um die E-Mail-Adressen der gewünschten Abonnenten des Verteilers einzutragen:&lt;br /&gt;
&lt;br /&gt;
 /usr/bin/mlmmj-sub -L /home/pacs/xyz00/users/list/mlmmj/discuss -a klaus.muster@gmx.de -c &lt;br /&gt;
 /usr/bin/mlmmj-sub -L /home/pacs/xyz00/users/list/mlmmj/discuss -a sabine.beispiel@arcor.de -c &lt;br /&gt;
&lt;br /&gt;
Dabei bewirkt &amp;quot;-c&amp;quot;, dass der Abonnent eine Begrüßungs-Nachricht erhält. Alternativ kann man &amp;quot;-C&amp;quot; (großes C) angeben: dann muss der Abonnent das Abo durch Antworten auf die Nachricht bestätigen.&lt;br /&gt;
&lt;br /&gt;
== weitere Optionen  ==&lt;br /&gt;
&lt;br /&gt;
Noch ein paar Dinge, die Sie möglicherweise einstellen wollen:&lt;br /&gt;
&lt;br /&gt;
Ein Prefix in der Betreffzeile setzen, z.B.: &amp;quot;[discuss]&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
 echo &amp;quot;[discuss]&amp;quot; &amp;gt; /home/pacs/xyz00/users/list/mlmmj/discuss/control/prefix&lt;br /&gt;
&lt;br /&gt;
Wenn die Liste nur E-Mails von eingetragenen Abonnenten weiterleiten soll:&lt;br /&gt;
&lt;br /&gt;
 touch /home/pacs/xyz00/users/list/mlmmj/discuss/control/subonlypost&lt;br /&gt;
&lt;br /&gt;
Damit der Listen-Owner weitere Abonnements bestätigen muss:&lt;br /&gt;
&lt;br /&gt;
 touch /home/pacs/xyz00/users/list/mlmmj/discuss/control/submod&lt;br /&gt;
&lt;br /&gt;
Einen &amp;quot;Reply-To:&amp;quot;-Header setzen, damit Antwort-Mails standardmäßig an die Mailing-Liste gehen:&lt;br /&gt;
&lt;br /&gt;
  echo &amp;quot;Reply-To:&amp;quot; &amp;gt; /home/pacs/xyz00/users/list/mlmmj/discuss/control/delheaders&lt;br /&gt;
  echo &amp;quot;Reply-To: discuss@example.org&amp;quot; &amp;gt; /home/pacs/xyz00/users/list/mlmmj/discuss/control/customheaders&lt;br /&gt;
&lt;br /&gt;
Weitere Möglichkeiten finden Sie (wie oben bereits angegeben) &lt;br /&gt;
auf der [http://mlmmj.org/docs/tunables/ Internetseite von mlmmj].&lt;br /&gt;
&lt;br /&gt;
== Zur Konfiguration im Browser ==&lt;br /&gt;
&lt;br /&gt;
Die Original-Distribution von &#039;&#039;mlmmj&#039;&#039; enthält ein paar einfache PHP- und Perl-Skripte.  Das sind Beispiele für Subscribe-/Unsubscribe-Formulare, ein Admin-Formular zum Eintragen und Löschen von Abonnements und eine Seite mit der gesamten Listen-Konfiguration.&lt;br /&gt;
&lt;br /&gt;
Wer es sich ansehen möchte:&lt;br /&gt;
&lt;br /&gt;
Als Paket-Admin eine Domain aufschalten:&lt;br /&gt;
&lt;br /&gt;
 hsscript -u xyz00 -e &amp;quot;domain.add({set:{name:&#039;lists.example.org&#039;,user:&#039;xyz00-list&#039;}})&amp;quot;&lt;br /&gt;
&lt;br /&gt;
Und weiter als &amp;quot;xyz00-list&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
Download der neuesten Version der Sourcen von mlmmj von http://mlmmj.org/downloads/ und diese in einem temporären Verzeichnis entpacken.&lt;br /&gt;
&lt;br /&gt;
Unter &amp;quot;/mlmmj-$versionsnummer/contrib/web/php-admin/&amp;quot; findet sich die PHP-Admin-Anwendung. Also ... &lt;br /&gt;
&lt;br /&gt;
* den Inhalt diese Verzeichnisses nach &amp;quot;/home/pacs/xyz00/users/list/doms/lists.example.org/&amp;quot; packen;&lt;br /&gt;
* in &amp;quot;/home/pacs/xyz00/users/list/doms/lists.example.org/conf/config.php&amp;quot; die Variable &amp;quot;$topdir&amp;quot; anpassen;&lt;br /&gt;
* die Dateien aus &amp;quot;/home/pacs/xyz00/users/list/doms/lists.example.org/htdocs/&amp;quot; nach &amp;quot;/home/pacs/xyz00/users/list/doms/lists.example.org/htdocs-ssl/&amp;quot; verschieben;&lt;br /&gt;
* in &amp;quot;/home/pacs/xyz00/users/list/mlmmj&amp;quot; und in &amp;quot;/home/pacs/xyz00/users/list/doms/lists.example.org/htdocs-ssl/&amp;quot; eine &amp;quot;.htaccess&amp;quot; mit folgendem Inhalt ablegen: &lt;br /&gt;
 &lt;br /&gt;
 Require valid-user&lt;br /&gt;
 AuthType Basic&lt;br /&gt;
 AuthName &amp;quot;mlmmj web-interface&amp;quot;&lt;br /&gt;
 AuthUserFile /home/pacs/xyz00/users/list/doms/lists.example.org/etc/htpasswd&lt;br /&gt;
&lt;br /&gt;
* Und schließlich die &amp;quot;htpasswd&amp;quot;-Datei anlegen.&lt;br /&gt;
&lt;br /&gt;
 cd /home/pacs/xyz00/users/list/doms/lists.example.org/etc/&lt;br /&gt;
 htpasswd -c htpasswd listadmin&lt;br /&gt;
&lt;br /&gt;
* Ein Passwort angeben.&lt;br /&gt;
&lt;br /&gt;
Nun enthält diese PHP-Anwendung leider noch eine Zeile, die schon seit PHP 7 nicht mehr lauffähig ist. Also muß man noch&lt;br /&gt;
&lt;br /&gt;
* in &amp;lt;tt&amp;gt;.../htdocs-ssl/index.php&amp;lt;/tt&amp;gt; folgende Änderung vornehmen:&lt;br /&gt;
&lt;br /&gt;
  @@ -38,4 +38,5 @@&lt;br /&gt;
   # use scandir to have alphabetical order &lt;br /&gt;
   foreach (scandir($topdir) as $file) {&lt;br /&gt;
  -    if (!ereg(&amp;quot;^\.&amp;quot;,$file))&lt;br /&gt;
  +# ereg obsolete!! Vormals:    if (!ereg(&amp;quot;^\.&amp;quot;,$file))&lt;br /&gt;
  +    if (!preg_match(&#039;/^\./&#039;,$file))&lt;br /&gt;
       {&lt;br /&gt;
&lt;br /&gt;
und das Ergebnis auf https://lists.example.org anschauen.&lt;br /&gt;
&lt;br /&gt;
== Mehrere Mailinglisten betreiben ==&lt;br /&gt;
&lt;br /&gt;
Wenn mehrere Mailinglisten in einem Account und mit einer Admin-Oberfläche betrieben werden soll, empfiehlt sich die Nutzung von Procmail für den Aufruf von &#039;&#039;mlmmj&#039;&#039; für die jeweiligen Liste mit ihrem Daten-Verzeichnis.&lt;br /&gt;
&lt;br /&gt;
Dazu trägt man in der Datei &amp;lt;tt&amp;gt;.forward&amp;lt;/tt&amp;gt; statt des Aufrufs von &#039;&#039;mlmmj-recieve&#039;&#039; einen Aufruf von &#039;&#039;procmail&#039;&#039; ein:&lt;br /&gt;
&lt;br /&gt;
 |/usr/bin/procmail&lt;br /&gt;
&lt;br /&gt;
Die Konfiguration von Procmail kann generisch erfolgen. Dazu legt man eine Datei &amp;lt;tt&amp;gt;.procmailrc&amp;lt;/tt&amp;gt; mit folgendem Inhalt ins $HOME des Users:&lt;br /&gt;
&lt;br /&gt;
 SHELL=/bin/sh&lt;br /&gt;
 HOMEDIR=/home/pacs/xyz00/users/list&lt;br /&gt;
 MAILDIR=/home/pacs/xyz00/users/list/Maildir&lt;br /&gt;
 PMDIR=/home/pacs/xyz00/users/list&lt;br /&gt;
 VERBOSE=yes&lt;br /&gt;
 LOGFILE=/home/pacs/xyz00/users/list/var/procmail.log&lt;br /&gt;
 DEFAULT&lt;br /&gt;
 &lt;br /&gt;
 :0:&lt;br /&gt;
 * ^X-Original-To: ()\/[^@+]+&lt;br /&gt;
 |/usr/bin/mlmmj-receive -F -L /home/pacs/xyz00/users/list/mlmmj/${MATCH}/&lt;br /&gt;
 &lt;br /&gt;
 :0&lt;br /&gt;
 { EXITCODE 67 }&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Der kryptische reguläre Ausdruck hinter dem Header &#039;&#039;X-Original-To:&#039;&#039; passt auf den Beginn der E-Mail-Adresse bis zum ersten &#039;&#039;@&#039;&#039;- oder &#039;&#039;+&#039;&#039;-Zeichen. In der Variable &#039;&#039;MATCH&#039;&#039; steht also der Name der Mailingliste, d.h. der Name der Verzeichnisses, in dem die Liste verwaltet wird.&lt;br /&gt;
&lt;br /&gt;
Sehr wichtig ist die Zeile &#039;&#039;DEFAULT&#039;&#039; zu Beginn der &#039;&#039;.procmailrc&#039;&#039;. Die Variable &#039;&#039;DEFAULT&#039;&#039; wird von &#039;&#039;procmail&#039;&#039; gesetzt. Wir sorgen mit dieser Zeile dafür, dass sie wieder undefiniert ist. Diese Variable wird intern von &#039;&#039;mlmmj&#039;&#039; benutzt, wenn sie gesetzt ist. Das führt in Kombination mit &#039;&#039;procmail&#039;&#039; zu Fehlfunktionen (vgl. Links).&lt;br /&gt;
&lt;br /&gt;
Achtung, mit der Groß- und Kleinschreibung von Listennamen gibt es bei dieser Procmail-Lösung eine kleine Tücke. Procmail übernimmt in die Variable $MATCH genau die in der X-Original-To-Headerzeile vorgefundene Schreibweise, und diese kann denkbarerweise &amp;quot;Listen-Name&amp;quot; oder &amp;quot;listen-name&amp;quot; oder &amp;quot;Listen-name&amp;quot; sein. &amp;lt;tt&amp;gt;mlmmj&amp;lt;/tt&amp;gt; hingegen wird diesen Wert in Unix-Manier mit dem genauen Verzeichnisnamen &amp;lt;tt&amp;gt;${HOME}/mlmmj/listen-name&amp;lt;/tt&amp;gt; vergleichen, und bei unterschiedlicher Schreibweise die Mail nicht verteilen.&lt;br /&gt;
&lt;br /&gt;
Eine teilweise Lösung besteht darin, den Listennamen in dem &amp;lt;tt&amp;gt;mlmmj&amp;lt;/tt&amp;gt;-Aufruf in der &amp;lt;tt&amp;gt;.procmailrc&amp;lt;/tt&amp;gt; in Kleinbuchstaben umzuschreiben. Dann lautet das Rezept so:&lt;br /&gt;
&lt;br /&gt;
 :0:&lt;br /&gt;
 * ^X-Original-To: ()\/[^@+]+&lt;br /&gt;
 |/usr/bin/mlmmj-receive -F -L /home/pacs/xyz00/users/list/mlmmj/$(echo ${MATCH} | tr A-Z a-z)/&lt;br /&gt;
&lt;br /&gt;
Der Rest der Datei muß gleich bleiben, wie weiter oben angezeigt.&lt;br /&gt;
&lt;br /&gt;
In diesem Fall müssen aber alle Mailing-Listen ohne Großbuchstaben im Namen angelegt werden!&lt;br /&gt;
&lt;br /&gt;
(Man kann auch in &amp;lt;tt&amp;gt;${HOME}/mlmmj/&amp;lt;/tt&amp;gt; durch kleingeschriebene Symlinks großgeschriebene Listennamen ansprechbar machen:&lt;br /&gt;
&lt;br /&gt;
  xyz00-list@h02:~$ ls -lA mlmmj/&lt;br /&gt;
  total 8&lt;br /&gt;
  -rw-r--r--  1 xyz00-list xyz00  148 Feb  1 16:56 .htaccess&lt;br /&gt;
  lrwxrwxrwx  1 xyz00-list xyz00   10 Feb  2 18:01 mitglieder -&amp;gt; Mitglieder&lt;br /&gt;
  drwxr-xr-x 15 xyz00-list xyz00 4096 Feb  2 16:53 Mitglieder&lt;br /&gt;
&lt;br /&gt;
Das scheint zu funktionieren; Angabe ohne Gewähr.)&lt;br /&gt;
&lt;br /&gt;
== Links ==&lt;br /&gt;
&lt;br /&gt;
* http://mlmmj.org/ Projektseite&lt;br /&gt;
* https://codeberg.org/mlmmj mlmmj auf Codeberg&lt;br /&gt;
* https://github.com/tchapi/mlmmj-simple-web-interface ein Admin-Interface in NodeJS&lt;br /&gt;
* https://www.tablix.org/~avian/blog/archives/2010/04/the_faulty_default/ Nutzung von mlmmj in Verbindung mit Procmail&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
[[Kategorie:HSDoku]]&lt;br /&gt;
[[Kategorie:Installationsanleitungen]]&lt;br /&gt;
[[Kategorie:Software]]&lt;br /&gt;
[[Kategorie:Mailinglisten]]&lt;br /&gt;
[[Kategorie:E-Mail]]&lt;/div&gt;</summary>
		<author><name>Apc00-tony</name></author>
	</entry>
	<entry>
		<id>https://wiki.hostsharing.net/index.php?title=Mlmmj&amp;diff=6406</id>
		<title>Mlmmj</title>
		<link rel="alternate" type="text/html" href="https://wiki.hostsharing.net/index.php?title=Mlmmj&amp;diff=6406"/>
		<updated>2024-02-02T11:26:15Z</updated>

		<summary type="html">&lt;p&gt;Apc00-tony: /* Zur Konfiguration im Browser */ diff verbessert&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[http://www.mlmmj.org/ mlmmj], angeblich eine Abkürzung für &amp;quot;Mailing List Management Made Joyful&amp;quot;, ist ein Programm, mit dem in einem Hostsharing Paket E-Mail-Verteiler realisiert werden kann.&lt;br /&gt;
&lt;br /&gt;
Wer noch nicht weiß, was ein E-Mail-Verteiler machen soll oder wie, lese veilleicht auch den Wikipedia-Artikel:&lt;br /&gt;
[http://de.wikipedia.org/wiki/Mailingliste Mailingliste]&lt;br /&gt;
&lt;br /&gt;
Eine leistungsfähigere Alternative zu mlmmj könnte [[Mailman_3_installieren|Mailman 3]] sein.&lt;br /&gt;
&lt;br /&gt;
Diese Anleitung beschreibt die Einrichtung einer Mailingliste für eine Domain in einem Hostsharing-Webspace.&lt;br /&gt;
&lt;br /&gt;
== Voraussetzungen  ==&lt;br /&gt;
&lt;br /&gt;
Das Debian Paket [http://packages.debian.org/search?keywords=mlmmj mlmmj] ist auf den Shared-Hosting-Servern bereits installiert.&lt;br /&gt;
&lt;br /&gt;
Für den Betrieb der Mailingliste empfiehlt sich das Anlegen eines eigenen Users für diesen Zweck mit hsadmin.&lt;br /&gt;
&lt;br /&gt;
In dieser Anleitung heißt das Paket &#039;&#039;xyz00&#039;&#039; und der für Mailinglisten eingesetzte User &#039;&#039;xyz00-list&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
Die E-Mail-Adresse der einzurichtende Mailing-Liste soll &#039;&#039;discuss@example.org&#039;&#039; sein.&lt;br /&gt;
&lt;br /&gt;
Die Domain &#039;&#039;example.org&#039;&#039; muss dazu bei einem beliebigen User im Paket &#039;&#039;xyz00&#039;&#039; [[aufgeschaltet]] sein. (&amp;quot;Aufgeschaltet&amp;quot; bedeutet, daß diese Domain bei Hostsharing gehostet wird und der Domainname als Verzeichnis /home/pacs/xyz00/*User*/doms/example.org/ erscheint.)&lt;br /&gt;
&lt;br /&gt;
== Einrichtung ==&lt;br /&gt;
&lt;br /&gt;
Ich melde mich über SSH auf der Hostsharing-Console als der Paketuser &#039;&#039;xyz00&#039;&#039; an.&lt;br /&gt;
&lt;br /&gt;
Im Shell kann ich dann durch den Befehl &#039;&#039;hsscript -i&#039;&#039; das Verwaltungswerkzeug [[hsadmin]] interaktiv ausführen:&lt;br /&gt;
&lt;br /&gt;
  xyz00@h03:~$ hsscript -i&lt;br /&gt;
  Password: *************&lt;br /&gt;
  xyz00@hsadmin&amp;gt; &lt;br /&gt;
&lt;br /&gt;
In &#039;&#039;hsadmin&#039;&#039; werden User und E-Mail-Adresse angelegt.&lt;br /&gt;
&lt;br /&gt;
  xyz00@hsadmin&amp;gt; user.add({set:{name:&#039;xyz00-list&#039;,comment:&#039;Mailingliste Discuss&#039;,shell:&#039;/bin/bash&#039;,password:&#039;geheimnis&#039;}})&lt;br /&gt;
  xyz00@hsadmin&amp;gt; emailaddress.add({set:{target:&#039;xyz00-list&#039;,localpart:&#039;discuss&#039;,domain:&#039;example.org&#039;}})&lt;br /&gt;
  xyz00@hsadmin&amp;gt; bye&lt;br /&gt;
&lt;br /&gt;
Mit dem Parameter &amp;quot;target&amp;quot; wird die für diese Adresse eingehende Post zunächst in das Postfach des Users xyz00-list abgelegt.&lt;br /&gt;
&lt;br /&gt;
Für den User xyz00-list lege ich in seinem Heimat-Verzeichnis das Unterverzeichnis &amp;lt;tt&amp;gt;mlmmj&amp;lt;/tt&amp;gt; an:&lt;br /&gt;
&lt;br /&gt;
  mkdir /home/pacs/xyz00/users/list/mlmmj&lt;br /&gt;
&lt;br /&gt;
Dann lege ich die Mailingliste mit folgendem Kommando an:&lt;br /&gt;
&lt;br /&gt;
  mlmmj-make-ml -L discuss -s /home/pacs/xyz00/users/list/mlmmj&lt;br /&gt;
&lt;br /&gt;
Das Skript &#039;&#039;mlmmj-make-ml&#039;&#039; fragt weitere Parameter der Mailingliste ab:&lt;br /&gt;
&lt;br /&gt;
  The Domain for the List? [] : example.org&lt;br /&gt;
  The emailaddress of the list owner? [postmaster] : webmaster@example.org&lt;br /&gt;
  For the list texts you can choose between the following languages or&lt;br /&gt;
  give an absolute path to a directory containing the texts.&lt;br /&gt;
  Available languages:&lt;br /&gt;
  cz  da	de  en	es  fr	it  nl	ru&lt;br /&gt;
  The path to texts for the list? [en] : de&lt;br /&gt;
&lt;br /&gt;
Das skript &#039;&#039;mlmmj-make-ml&#039;&#039; legt daraufhin unter &amp;quot;/home/pacs/xyz00/users/list/mlmmj&amp;quot; ein Verzeichnis &amp;quot;discuss&amp;quot; an, das die Datenstruktur zur Verwaltung der Mailingliste enthält.&lt;br /&gt;
&lt;br /&gt;
Weitere Konfigurationen der Liste erfolgen durch das Anlegen von Dateien im&lt;br /&gt;
Verzeichnis &amp;quot;/home/pacs/xyz00/users/list/mlmmj/discuss/control&amp;quot;.&lt;br /&gt;
Die Konfigurationsmöglichkeiten finden Sie auf der [http://mlmmj.org/docs/tunables/ Internetseite von mlmmj].&lt;br /&gt;
&lt;br /&gt;
Damit mlmmj die Verteilung der Post übernimmt, muß ich im Heimat-Verzeichnis des users xyz00-list die Datei &amp;lt;tt&amp;gt;.forward&amp;lt;/tt&amp;gt; mit folgenden Inhalt (INKLUSIVE der Anführungszeichen!) erstellen:&lt;br /&gt;
&lt;br /&gt;
  &amp;quot;|/usr/bin/mlmmj-recieve -L /home/pacs/xyz00/users/list/mlmmj/discuss/&amp;quot;&lt;br /&gt;
&lt;br /&gt;
(Ja, &#039;&#039;receive&#039;&#039; schreibt sich mit &#039;&#039;-ei-&#039;&#039;, aber mlmmj hält einen symbolischen Link bereit für diejenigen, die in englischer Rechtschreibung unsicher sind:)&lt;br /&gt;
&lt;br /&gt;
   xyz00-list@h03:~$ ls -la /usr/bin/mlmmj-rec*&lt;br /&gt;
   -rwxr-xr-x 1 root root 27104 Sep 25  2018 /usr/bin/mlmmj-receive&lt;br /&gt;
   lrwxrwxrwx 1 root root    13 Sep 25  2018 /usr/bin/mlmmj-recieve -&amp;gt; mlmmj-receive&lt;br /&gt;
&lt;br /&gt;
Die &amp;lt;tt&amp;gt;.forward&amp;lt;/tt&amp;gt;-Datei sorgt dafür, dass eingehende E-Mails an das User-Postfach an das Programm &#039;&#039;mlmmj-recieve&#039;&#039; übergeben werden.&lt;br /&gt;
&lt;br /&gt;
Für regelmäßige Aufgaben der Listen-Managers definiere ich die&lt;br /&gt;
[[Cron|crontab]] wie folgt (immer noch als &#039;&#039;xyz00-list&#039;&#039;):&lt;br /&gt;
&lt;br /&gt;
  xyz00-list@h03:~$ crontab -e&lt;br /&gt;
&lt;br /&gt;
 MAILTO=webmaster@example.org&lt;br /&gt;
 PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/X11R6/bin&lt;br /&gt;
 HOME=/home/pacs/xyz00/users/list&lt;br /&gt;
 SHELL=/bin/bash&lt;br /&gt;
 LANG=en_US.UTF-8&lt;br /&gt;
 # m h  dom mon dow   command&lt;br /&gt;
 28 */4 * * * /usr/bin/mlmmj-maintd -d /home/pacs/xyz00/users/list/mlmmj -F&lt;br /&gt;
&lt;br /&gt;
Zum Schluss rufe ich das Skript mlmmj-sub auf, um die E-Mail-Adressen der gewünschten Abonnenten des Verteilers einzutragen:&lt;br /&gt;
&lt;br /&gt;
 /usr/bin/mlmmj-sub -L /home/pacs/xyz00/users/list/mlmmj/discuss -a klaus.muster@gmx.de -c &lt;br /&gt;
 /usr/bin/mlmmj-sub -L /home/pacs/xyz00/users/list/mlmmj/discuss -a sabine.beispiel@arcor.de -c &lt;br /&gt;
&lt;br /&gt;
Dabei bewirkt &amp;quot;-c&amp;quot;, dass der Abonnent eine Begrüßungs-Nachricht erhält. Alternativ kann man &amp;quot;-C&amp;quot; (großes C) angeben: dann muss der Abonnent das Abo durch Antworten auf die Nachricht bestätigen.&lt;br /&gt;
&lt;br /&gt;
== weitere Optionen  ==&lt;br /&gt;
&lt;br /&gt;
Noch ein paar Dinge, die Sie möglicherweise einstellen wollen:&lt;br /&gt;
&lt;br /&gt;
Ein Prefix in der Betreffzeile setzen, z.B.: &amp;quot;[discuss]&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
 echo &amp;quot;[discuss]&amp;quot; &amp;gt; /home/pacs/xyz00/users/list/mlmmj/discuss/control/prefix&lt;br /&gt;
&lt;br /&gt;
Wenn die Liste nur E-Mails von eingetragenen Abonnenten weiterleiten soll:&lt;br /&gt;
&lt;br /&gt;
 touch /home/pacs/xyz00/users/list/mlmmj/discuss/control/subonlypost&lt;br /&gt;
&lt;br /&gt;
Damit der Listen-Owner weitere Abonnements bestätigen muss:&lt;br /&gt;
&lt;br /&gt;
 touch /home/pacs/xyz00/users/list/mlmmj/discuss/control/submod&lt;br /&gt;
&lt;br /&gt;
Einen &amp;quot;Reply-To:&amp;quot;-Header setzen, damit Antwort-Mails standardmäßig an die Mailing-Liste gehen:&lt;br /&gt;
&lt;br /&gt;
  echo &amp;quot;Reply-To:&amp;quot; &amp;gt; /home/pacs/xyz00/users/list/mlmmj/discuss/control/delheaders&lt;br /&gt;
  echo &amp;quot;Reply-To: discuss@example.org&amp;quot; &amp;gt; /home/pacs/xyz00/users/list/mlmmj/discuss/control/customheaders&lt;br /&gt;
&lt;br /&gt;
Weitere Möglichkeiten finden Sie (wie oben bereits angegeben) &lt;br /&gt;
auf der [http://mlmmj.org/docs/tunables/ Internetseite von mlmmj].&lt;br /&gt;
&lt;br /&gt;
== Zur Konfiguration im Browser ==&lt;br /&gt;
&lt;br /&gt;
Die Original-Distribution von &#039;&#039;mlmmj&#039;&#039; enthält ein paar einfache PHP- und Perl-Skripte.  Das sind Beispiele für Subscribe-/Unsubscribe-Formulare, ein Admin-Formular zum Eintragen und Löschen von Abonnements und eine Seite mit der gesamten Listen-Konfiguration.&lt;br /&gt;
&lt;br /&gt;
Wer es sich ansehen möchte:&lt;br /&gt;
&lt;br /&gt;
Als Paket-Admin eine Domain aufschalten:&lt;br /&gt;
&lt;br /&gt;
 hsscript -u xyz00 -e &amp;quot;domain.add({set:{name:&#039;lists.example.org&#039;,user:&#039;xyz00-list&#039;}})&amp;quot;&lt;br /&gt;
&lt;br /&gt;
Und weiter als &amp;quot;xyz00-list&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
Download der neuesten Version der Sourcen von mlmmj von http://mlmmj.org/downloads/ und diese in einem temporären Verzeichnis entpacken.&lt;br /&gt;
&lt;br /&gt;
Unter &amp;quot;/mlmmj-$versionsnummer/contrib/web/php-admin/&amp;quot; findet sich die PHP-Admin-Anwendung. Also ... &lt;br /&gt;
&lt;br /&gt;
* den Inhalt diese Verzeichnisses nach &amp;quot;/home/pacs/xyz00/users/list/doms/lists.example.org/&amp;quot; packen;&lt;br /&gt;
* in &amp;quot;/home/pacs/xyz00/users/list/doms/lists.example.org/conf/config.php&amp;quot; die Variable &amp;quot;$topdir&amp;quot; anpassen;&lt;br /&gt;
* die Dateien aus &amp;quot;/home/pacs/xyz00/users/list/doms/lists.example.org/htdocs/&amp;quot; nach &amp;quot;/home/pacs/xyz00/users/list/doms/lists.example.org/htdocs-ssl/&amp;quot; verschieben;&lt;br /&gt;
* in &amp;quot;/home/pacs/xyz00/users/list/mlmmj&amp;quot; und in &amp;quot;/home/pacs/xyz00/users/list/doms/lists.example.org/htdocs-ssl/&amp;quot; eine &amp;quot;.htaccess&amp;quot; mit folgendem Inhalt ablegen: &lt;br /&gt;
 &lt;br /&gt;
 Require valid-user&lt;br /&gt;
 AuthType Basic&lt;br /&gt;
 AuthName &amp;quot;mlmmj web-interface&amp;quot;&lt;br /&gt;
 AuthUserFile /home/pacs/xyz00/users/list/doms/lists.example.org/etc/htpasswd&lt;br /&gt;
&lt;br /&gt;
* Und schließlich die &amp;quot;htpasswd&amp;quot;-Datei anlegen.&lt;br /&gt;
&lt;br /&gt;
 cd /home/pacs/xyz00/users/list/doms/lists.example.org/etc/&lt;br /&gt;
 htpasswd -c htpasswd listadmin&lt;br /&gt;
&lt;br /&gt;
* Ein Passwort angeben.&lt;br /&gt;
&lt;br /&gt;
Nun enthält diese PHP-Anwendung leider noch eine Zeile, die schon seit PHP 7 nicht mehr lauffähig ist. Also muß man noch&lt;br /&gt;
&lt;br /&gt;
* in &amp;lt;tt&amp;gt;.../htdocs-ssl/index.php&amp;lt;/tt&amp;gt; folgende Änderung vornehmen:&lt;br /&gt;
&lt;br /&gt;
  @@ -38,4 +38,5 @@&lt;br /&gt;
   # use scandir to have alphabetical order &lt;br /&gt;
   foreach (scandir($topdir) as $file) {&lt;br /&gt;
  -    if (!ereg(&amp;quot;^\.&amp;quot;,$file))&lt;br /&gt;
  +# ereg obsolete!! Vormals:    if (!ereg(&amp;quot;^\.&amp;quot;,$file))&lt;br /&gt;
  +    if (!preg_match(&#039;/^\./&#039;,$file))&lt;br /&gt;
       {&lt;br /&gt;
&lt;br /&gt;
und das Ergebnis auf https://lists.example.org anschauen.&lt;br /&gt;
&lt;br /&gt;
== Mehrere Mailinglisten betreiben ==&lt;br /&gt;
&lt;br /&gt;
Wenn mehrere Mailinglisten in einem Account und mit einer Admin-Oberfläche betrieben werden soll, empfiehlt sich die Nutzung von Procmail für den Aufruf von &#039;&#039;mlmmj&#039;&#039; für die jeweiligen Liste mit ihrem Daten-Verzeichnis.&lt;br /&gt;
&lt;br /&gt;
Dazu trägt man in der Date &#039;&#039;.forward&#039;&#039; statt des Aufrufs von &#039;&#039;mlmmj-recieve&#039;&#039; einen Aufruf von &#039;&#039;procmail&#039;&#039; ein:&lt;br /&gt;
&lt;br /&gt;
 |/usr/bin/procmail&lt;br /&gt;
&lt;br /&gt;
Die Konfiguration von Procmail kann generisch erfolgen. Dazu legt man eine Datei &#039;&#039;.procmailrc&#039;&#039; mit folgendem Inhalt ins $HOME des Users:&lt;br /&gt;
&lt;br /&gt;
 SHELL=/bin/sh&lt;br /&gt;
 HOMEDIR=/home/pacs/xyz00/users/list&lt;br /&gt;
 MAILDIR=/home/pacs/xyz00/users/list/Maildir&lt;br /&gt;
 PMDIR=/home/pacs/xyz00/users/list&lt;br /&gt;
 VERBOSE=yes&lt;br /&gt;
 LOGFILE=/home/pacs/xyz00/users/list/var/procmail.log&lt;br /&gt;
 DEFAULT&lt;br /&gt;
 &lt;br /&gt;
 :0:&lt;br /&gt;
 * ^X-Original-To: ()\/[^@+]+&lt;br /&gt;
 |/usr/bin/mlmmj-receive -F -L /home/pacs/xyz00/users/list/mlmmj/${MATCH}/&lt;br /&gt;
 &lt;br /&gt;
 :0&lt;br /&gt;
 { EXITCODE 67 }&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Der kryptische reguläre Ausdruck hinter dem Header &#039;&#039;X-Original-To:&#039;&#039; passt auf den Beginn der E-Mail-Adresse bis zum ersten &#039;&#039;@&#039;&#039;- oder &#039;&#039;+&#039;&#039;-Zeichen. In der Variable &#039;&#039;MATCH&#039;&#039; steht also der Name der Mailingliste, d.h. der Name der Verzeichnisses, in dem die Liste verwaltet wird.&lt;br /&gt;
&lt;br /&gt;
Sehr wichtig ist die Zeile &#039;&#039;DEFAULT&#039;&#039; zu Beginn der &#039;&#039;.procmailrc&#039;&#039;. Die Variable &#039;&#039;DEFAULT&#039;&#039; wird von &#039;&#039;procmail&#039;&#039; gesetzt. Wir sorgen mit dieser Zeile dafür, dass sie wieder undefiniert ist. Diese Variable wird intern von &#039;&#039;mlmmj&#039;&#039; benutzt, wenn sie gesetzt ist. Das führt in Kombination mit &#039;&#039;procmail&#039;&#039; zu Fehlfunktionen (vgl. Links).&lt;br /&gt;
&lt;br /&gt;
== Links ==&lt;br /&gt;
&lt;br /&gt;
* http://mlmmj.org/ Projektseite&lt;br /&gt;
* https://codeberg.org/mlmmj mlmmj auf Codeberg&lt;br /&gt;
* https://github.com/tchapi/mlmmj-simple-web-interface ein Admin-Interface in NodeJS&lt;br /&gt;
* https://www.tablix.org/~avian/blog/archives/2010/04/the_faulty_default/ Nutzung von mlmmj in Verbindung mit Procmail&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
[[Kategorie:HSDoku]]&lt;br /&gt;
[[Kategorie:Installationsanleitungen]]&lt;br /&gt;
[[Kategorie:Software]]&lt;br /&gt;
[[Kategorie:Mailinglisten]]&lt;br /&gt;
[[Kategorie:E-Mail]]&lt;/div&gt;</summary>
		<author><name>Apc00-tony</name></author>
	</entry>
	<entry>
		<id>https://wiki.hostsharing.net/index.php?title=Mlmmj&amp;diff=6405</id>
		<title>Mlmmj</title>
		<link rel="alternate" type="text/html" href="https://wiki.hostsharing.net/index.php?title=Mlmmj&amp;diff=6405"/>
		<updated>2024-02-02T11:24:15Z</updated>

		<summary type="html">&lt;p&gt;Apc00-tony: /* Zur Konfiguration im Browser */ Patch vonnöten&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[http://www.mlmmj.org/ mlmmj], angeblich eine Abkürzung für &amp;quot;Mailing List Management Made Joyful&amp;quot;, ist ein Programm, mit dem in einem Hostsharing Paket E-Mail-Verteiler realisiert werden kann.&lt;br /&gt;
&lt;br /&gt;
Wer noch nicht weiß, was ein E-Mail-Verteiler machen soll oder wie, lese veilleicht auch den Wikipedia-Artikel:&lt;br /&gt;
[http://de.wikipedia.org/wiki/Mailingliste Mailingliste]&lt;br /&gt;
&lt;br /&gt;
Eine leistungsfähigere Alternative zu mlmmj könnte [[Mailman_3_installieren|Mailman 3]] sein.&lt;br /&gt;
&lt;br /&gt;
Diese Anleitung beschreibt die Einrichtung einer Mailingliste für eine Domain in einem Hostsharing-Webspace.&lt;br /&gt;
&lt;br /&gt;
== Voraussetzungen  ==&lt;br /&gt;
&lt;br /&gt;
Das Debian Paket [http://packages.debian.org/search?keywords=mlmmj mlmmj] ist auf den Shared-Hosting-Servern bereits installiert.&lt;br /&gt;
&lt;br /&gt;
Für den Betrieb der Mailingliste empfiehlt sich das Anlegen eines eigenen Users für diesen Zweck mit hsadmin.&lt;br /&gt;
&lt;br /&gt;
In dieser Anleitung heißt das Paket &#039;&#039;xyz00&#039;&#039; und der für Mailinglisten eingesetzte User &#039;&#039;xyz00-list&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
Die E-Mail-Adresse der einzurichtende Mailing-Liste soll &#039;&#039;discuss@example.org&#039;&#039; sein.&lt;br /&gt;
&lt;br /&gt;
Die Domain &#039;&#039;example.org&#039;&#039; muss dazu bei einem beliebigen User im Paket &#039;&#039;xyz00&#039;&#039; [[aufgeschaltet]] sein. (&amp;quot;Aufgeschaltet&amp;quot; bedeutet, daß diese Domain bei Hostsharing gehostet wird und der Domainname als Verzeichnis /home/pacs/xyz00/*User*/doms/example.org/ erscheint.)&lt;br /&gt;
&lt;br /&gt;
== Einrichtung ==&lt;br /&gt;
&lt;br /&gt;
Ich melde mich über SSH auf der Hostsharing-Console als der Paketuser &#039;&#039;xyz00&#039;&#039; an.&lt;br /&gt;
&lt;br /&gt;
Im Shell kann ich dann durch den Befehl &#039;&#039;hsscript -i&#039;&#039; das Verwaltungswerkzeug [[hsadmin]] interaktiv ausführen:&lt;br /&gt;
&lt;br /&gt;
  xyz00@h03:~$ hsscript -i&lt;br /&gt;
  Password: *************&lt;br /&gt;
  xyz00@hsadmin&amp;gt; &lt;br /&gt;
&lt;br /&gt;
In &#039;&#039;hsadmin&#039;&#039; werden User und E-Mail-Adresse angelegt.&lt;br /&gt;
&lt;br /&gt;
  xyz00@hsadmin&amp;gt; user.add({set:{name:&#039;xyz00-list&#039;,comment:&#039;Mailingliste Discuss&#039;,shell:&#039;/bin/bash&#039;,password:&#039;geheimnis&#039;}})&lt;br /&gt;
  xyz00@hsadmin&amp;gt; emailaddress.add({set:{target:&#039;xyz00-list&#039;,localpart:&#039;discuss&#039;,domain:&#039;example.org&#039;}})&lt;br /&gt;
  xyz00@hsadmin&amp;gt; bye&lt;br /&gt;
&lt;br /&gt;
Mit dem Parameter &amp;quot;target&amp;quot; wird die für diese Adresse eingehende Post zunächst in das Postfach des Users xyz00-list abgelegt.&lt;br /&gt;
&lt;br /&gt;
Für den User xyz00-list lege ich in seinem Heimat-Verzeichnis das Unterverzeichnis &amp;lt;tt&amp;gt;mlmmj&amp;lt;/tt&amp;gt; an:&lt;br /&gt;
&lt;br /&gt;
  mkdir /home/pacs/xyz00/users/list/mlmmj&lt;br /&gt;
&lt;br /&gt;
Dann lege ich die Mailingliste mit folgendem Kommando an:&lt;br /&gt;
&lt;br /&gt;
  mlmmj-make-ml -L discuss -s /home/pacs/xyz00/users/list/mlmmj&lt;br /&gt;
&lt;br /&gt;
Das Skript &#039;&#039;mlmmj-make-ml&#039;&#039; fragt weitere Parameter der Mailingliste ab:&lt;br /&gt;
&lt;br /&gt;
  The Domain for the List? [] : example.org&lt;br /&gt;
  The emailaddress of the list owner? [postmaster] : webmaster@example.org&lt;br /&gt;
  For the list texts you can choose between the following languages or&lt;br /&gt;
  give an absolute path to a directory containing the texts.&lt;br /&gt;
  Available languages:&lt;br /&gt;
  cz  da	de  en	es  fr	it  nl	ru&lt;br /&gt;
  The path to texts for the list? [en] : de&lt;br /&gt;
&lt;br /&gt;
Das skript &#039;&#039;mlmmj-make-ml&#039;&#039; legt daraufhin unter &amp;quot;/home/pacs/xyz00/users/list/mlmmj&amp;quot; ein Verzeichnis &amp;quot;discuss&amp;quot; an, das die Datenstruktur zur Verwaltung der Mailingliste enthält.&lt;br /&gt;
&lt;br /&gt;
Weitere Konfigurationen der Liste erfolgen durch das Anlegen von Dateien im&lt;br /&gt;
Verzeichnis &amp;quot;/home/pacs/xyz00/users/list/mlmmj/discuss/control&amp;quot;.&lt;br /&gt;
Die Konfigurationsmöglichkeiten finden Sie auf der [http://mlmmj.org/docs/tunables/ Internetseite von mlmmj].&lt;br /&gt;
&lt;br /&gt;
Damit mlmmj die Verteilung der Post übernimmt, muß ich im Heimat-Verzeichnis des users xyz00-list die Datei &amp;lt;tt&amp;gt;.forward&amp;lt;/tt&amp;gt; mit folgenden Inhalt (INKLUSIVE der Anführungszeichen!) erstellen:&lt;br /&gt;
&lt;br /&gt;
  &amp;quot;|/usr/bin/mlmmj-recieve -L /home/pacs/xyz00/users/list/mlmmj/discuss/&amp;quot;&lt;br /&gt;
&lt;br /&gt;
(Ja, &#039;&#039;receive&#039;&#039; schreibt sich mit &#039;&#039;-ei-&#039;&#039;, aber mlmmj hält einen symbolischen Link bereit für diejenigen, die in englischer Rechtschreibung unsicher sind:)&lt;br /&gt;
&lt;br /&gt;
   xyz00-list@h03:~$ ls -la /usr/bin/mlmmj-rec*&lt;br /&gt;
   -rwxr-xr-x 1 root root 27104 Sep 25  2018 /usr/bin/mlmmj-receive&lt;br /&gt;
   lrwxrwxrwx 1 root root    13 Sep 25  2018 /usr/bin/mlmmj-recieve -&amp;gt; mlmmj-receive&lt;br /&gt;
&lt;br /&gt;
Die &amp;lt;tt&amp;gt;.forward&amp;lt;/tt&amp;gt;-Datei sorgt dafür, dass eingehende E-Mails an das User-Postfach an das Programm &#039;&#039;mlmmj-recieve&#039;&#039; übergeben werden.&lt;br /&gt;
&lt;br /&gt;
Für regelmäßige Aufgaben der Listen-Managers definiere ich die&lt;br /&gt;
[[Cron|crontab]] wie folgt (immer noch als &#039;&#039;xyz00-list&#039;&#039;):&lt;br /&gt;
&lt;br /&gt;
  xyz00-list@h03:~$ crontab -e&lt;br /&gt;
&lt;br /&gt;
 MAILTO=webmaster@example.org&lt;br /&gt;
 PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/X11R6/bin&lt;br /&gt;
 HOME=/home/pacs/xyz00/users/list&lt;br /&gt;
 SHELL=/bin/bash&lt;br /&gt;
 LANG=en_US.UTF-8&lt;br /&gt;
 # m h  dom mon dow   command&lt;br /&gt;
 28 */4 * * * /usr/bin/mlmmj-maintd -d /home/pacs/xyz00/users/list/mlmmj -F&lt;br /&gt;
&lt;br /&gt;
Zum Schluss rufe ich das Skript mlmmj-sub auf, um die E-Mail-Adressen der gewünschten Abonnenten des Verteilers einzutragen:&lt;br /&gt;
&lt;br /&gt;
 /usr/bin/mlmmj-sub -L /home/pacs/xyz00/users/list/mlmmj/discuss -a klaus.muster@gmx.de -c &lt;br /&gt;
 /usr/bin/mlmmj-sub -L /home/pacs/xyz00/users/list/mlmmj/discuss -a sabine.beispiel@arcor.de -c &lt;br /&gt;
&lt;br /&gt;
Dabei bewirkt &amp;quot;-c&amp;quot;, dass der Abonnent eine Begrüßungs-Nachricht erhält. Alternativ kann man &amp;quot;-C&amp;quot; (großes C) angeben: dann muss der Abonnent das Abo durch Antworten auf die Nachricht bestätigen.&lt;br /&gt;
&lt;br /&gt;
== weitere Optionen  ==&lt;br /&gt;
&lt;br /&gt;
Noch ein paar Dinge, die Sie möglicherweise einstellen wollen:&lt;br /&gt;
&lt;br /&gt;
Ein Prefix in der Betreffzeile setzen, z.B.: &amp;quot;[discuss]&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
 echo &amp;quot;[discuss]&amp;quot; &amp;gt; /home/pacs/xyz00/users/list/mlmmj/discuss/control/prefix&lt;br /&gt;
&lt;br /&gt;
Wenn die Liste nur E-Mails von eingetragenen Abonnenten weiterleiten soll:&lt;br /&gt;
&lt;br /&gt;
 touch /home/pacs/xyz00/users/list/mlmmj/discuss/control/subonlypost&lt;br /&gt;
&lt;br /&gt;
Damit der Listen-Owner weitere Abonnements bestätigen muss:&lt;br /&gt;
&lt;br /&gt;
 touch /home/pacs/xyz00/users/list/mlmmj/discuss/control/submod&lt;br /&gt;
&lt;br /&gt;
Einen &amp;quot;Reply-To:&amp;quot;-Header setzen, damit Antwort-Mails standardmäßig an die Mailing-Liste gehen:&lt;br /&gt;
&lt;br /&gt;
  echo &amp;quot;Reply-To:&amp;quot; &amp;gt; /home/pacs/xyz00/users/list/mlmmj/discuss/control/delheaders&lt;br /&gt;
  echo &amp;quot;Reply-To: discuss@example.org&amp;quot; &amp;gt; /home/pacs/xyz00/users/list/mlmmj/discuss/control/customheaders&lt;br /&gt;
&lt;br /&gt;
Weitere Möglichkeiten finden Sie (wie oben bereits angegeben) &lt;br /&gt;
auf der [http://mlmmj.org/docs/tunables/ Internetseite von mlmmj].&lt;br /&gt;
&lt;br /&gt;
== Zur Konfiguration im Browser ==&lt;br /&gt;
&lt;br /&gt;
Die Original-Distribution von &#039;&#039;mlmmj&#039;&#039; enthält ein paar einfache PHP- und Perl-Skripte.  Das sind Beispiele für Subscribe-/Unsubscribe-Formulare, ein Admin-Formular zum Eintragen und Löschen von Abonnements und eine Seite mit der gesamten Listen-Konfiguration.&lt;br /&gt;
&lt;br /&gt;
Wer es sich ansehen möchte:&lt;br /&gt;
&lt;br /&gt;
Als Paket-Admin eine Domain aufschalten:&lt;br /&gt;
&lt;br /&gt;
 hsscript -u xyz00 -e &amp;quot;domain.add({set:{name:&#039;lists.example.org&#039;,user:&#039;xyz00-list&#039;}})&amp;quot;&lt;br /&gt;
&lt;br /&gt;
Und weiter als &amp;quot;xyz00-list&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
Download der neuesten Version der Sourcen von mlmmj von http://mlmmj.org/downloads/ und diese in einem temporären Verzeichnis entpacken.&lt;br /&gt;
&lt;br /&gt;
Unter &amp;quot;/mlmmj-$versionsnummer/contrib/web/php-admin/&amp;quot; findet sich die PHP-Admin-Anwendung. Also ... &lt;br /&gt;
&lt;br /&gt;
* den Inhalt diese Verzeichnisses nach &amp;quot;/home/pacs/xyz00/users/list/doms/lists.example.org/&amp;quot; packen;&lt;br /&gt;
* in &amp;quot;/home/pacs/xyz00/users/list/doms/lists.example.org/conf/config.php&amp;quot; die Variable &amp;quot;$topdir&amp;quot; anpassen;&lt;br /&gt;
* die Dateien aus &amp;quot;/home/pacs/xyz00/users/list/doms/lists.example.org/htdocs/&amp;quot; nach &amp;quot;/home/pacs/xyz00/users/list/doms/lists.example.org/htdocs-ssl/&amp;quot; verschieben;&lt;br /&gt;
* in &amp;quot;/home/pacs/xyz00/users/list/mlmmj&amp;quot; und in &amp;quot;/home/pacs/xyz00/users/list/doms/lists.example.org/htdocs-ssl/&amp;quot; eine &amp;quot;.htaccess&amp;quot; mit folgendem Inhalt ablegen: &lt;br /&gt;
 &lt;br /&gt;
 Require valid-user&lt;br /&gt;
 AuthType Basic&lt;br /&gt;
 AuthName &amp;quot;mlmmj web-interface&amp;quot;&lt;br /&gt;
 AuthUserFile /home/pacs/xyz00/users/list/doms/lists.example.org/etc/htpasswd&lt;br /&gt;
&lt;br /&gt;
* Und schließlich die &amp;quot;htpasswd&amp;quot;-Datei anlegen.&lt;br /&gt;
&lt;br /&gt;
 cd /home/pacs/xyz00/users/list/doms/lists.example.org/etc/&lt;br /&gt;
 htpasswd -c htpasswd listadmin&lt;br /&gt;
&lt;br /&gt;
* Ein Passwort angeben.&lt;br /&gt;
&lt;br /&gt;
Nun enthält diese PHP-Anwendung leider noch eine Zeile, die schon seit PHP 7 nicht mehr lauffähig ist. Also muß man noch&lt;br /&gt;
&lt;br /&gt;
* in &amp;lt;tt&amp;gt;.../htdocs-ssl/index.php&amp;lt;/tt&amp;gt; folgende Änderung vornehmen:&lt;br /&gt;
&lt;br /&gt;
  @@ -38,6 +38,7 @@&lt;br /&gt;
   # use scandir to have alphabetical order &lt;br /&gt;
   foreach (scandir($topdir) as $file) {&lt;br /&gt;
  -    if (!ereg(&amp;quot;^\.&amp;quot;,$file))&lt;br /&gt;
  +# ereg obsolete!! Vormals:    if (!ereg(&amp;quot;^\.&amp;quot;,$file))&lt;br /&gt;
  +    if (!preg_match(&#039;/^\./&#039;,$file))&lt;br /&gt;
       {&lt;br /&gt;
   	$lists .= &amp;quot;&amp;lt;p&amp;gt;&amp;quot;.htmlentities($file).&amp;quot;&amp;lt;br/&amp;gt;\n&amp;quot;;&lt;br /&gt;
   	$lists .= &amp;quot;&amp;lt;a href=\&amp;quot;edit.php?list=&amp;quot;.urlencode($file).&amp;quot;\&amp;quot;&amp;gt;Config&amp;lt;/a&amp;gt; - &amp;lt;a href=\&amp;quot;subscribers.php?list=&amp;quot;.urlencode($file).&amp;quot;\&amp;quot;&amp;gt;Subscribers&amp;lt;/a&amp;gt;\n&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
 und das Ergebnis auf https://lists.example.org anschauen.&lt;br /&gt;
&lt;br /&gt;
== Mehrere Mailinglisten betreiben ==&lt;br /&gt;
&lt;br /&gt;
Wenn mehrere Mailinglisten in einem Account und mit einer Admin-Oberfläche betrieben werden soll, empfiehlt sich die Nutzung von Procmail für den Aufruf von &#039;&#039;mlmmj&#039;&#039; für die jeweiligen Liste mit ihrem Daten-Verzeichnis.&lt;br /&gt;
&lt;br /&gt;
Dazu trägt man in der Date &#039;&#039;.forward&#039;&#039; statt des Aufrufs von &#039;&#039;mlmmj-recieve&#039;&#039; einen Aufruf von &#039;&#039;procmail&#039;&#039; ein:&lt;br /&gt;
&lt;br /&gt;
 |/usr/bin/procmail&lt;br /&gt;
&lt;br /&gt;
Die Konfiguration von Procmail kann generisch erfolgen. Dazu legt man eine Datei &#039;&#039;.procmailrc&#039;&#039; mit folgendem Inhalt ins $HOME des Users:&lt;br /&gt;
&lt;br /&gt;
 SHELL=/bin/sh&lt;br /&gt;
 HOMEDIR=/home/pacs/xyz00/users/list&lt;br /&gt;
 MAILDIR=/home/pacs/xyz00/users/list/Maildir&lt;br /&gt;
 PMDIR=/home/pacs/xyz00/users/list&lt;br /&gt;
 VERBOSE=yes&lt;br /&gt;
 LOGFILE=/home/pacs/xyz00/users/list/var/procmail.log&lt;br /&gt;
 DEFAULT&lt;br /&gt;
 &lt;br /&gt;
 :0:&lt;br /&gt;
 * ^X-Original-To: ()\/[^@+]+&lt;br /&gt;
 |/usr/bin/mlmmj-receive -F -L /home/pacs/xyz00/users/list/mlmmj/${MATCH}/&lt;br /&gt;
 &lt;br /&gt;
 :0&lt;br /&gt;
 { EXITCODE 67 }&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Der kryptische reguläre Ausdruck hinter dem Header &#039;&#039;X-Original-To:&#039;&#039; passt auf den Beginn der E-Mail-Adresse bis zum ersten &#039;&#039;@&#039;&#039;- oder &#039;&#039;+&#039;&#039;-Zeichen. In der Variable &#039;&#039;MATCH&#039;&#039; steht also der Name der Mailingliste, d.h. der Name der Verzeichnisses, in dem die Liste verwaltet wird.&lt;br /&gt;
&lt;br /&gt;
Sehr wichtig ist die Zeile &#039;&#039;DEFAULT&#039;&#039; zu Beginn der &#039;&#039;.procmailrc&#039;&#039;. Die Variable &#039;&#039;DEFAULT&#039;&#039; wird von &#039;&#039;procmail&#039;&#039; gesetzt. Wir sorgen mit dieser Zeile dafür, dass sie wieder undefiniert ist. Diese Variable wird intern von &#039;&#039;mlmmj&#039;&#039; benutzt, wenn sie gesetzt ist. Das führt in Kombination mit &#039;&#039;procmail&#039;&#039; zu Fehlfunktionen (vgl. Links).&lt;br /&gt;
&lt;br /&gt;
== Links ==&lt;br /&gt;
&lt;br /&gt;
* http://mlmmj.org/ Projektseite&lt;br /&gt;
* https://codeberg.org/mlmmj mlmmj auf Codeberg&lt;br /&gt;
* https://github.com/tchapi/mlmmj-simple-web-interface ein Admin-Interface in NodeJS&lt;br /&gt;
* https://www.tablix.org/~avian/blog/archives/2010/04/the_faulty_default/ Nutzung von mlmmj in Verbindung mit Procmail&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
[[Kategorie:HSDoku]]&lt;br /&gt;
[[Kategorie:Installationsanleitungen]]&lt;br /&gt;
[[Kategorie:Software]]&lt;br /&gt;
[[Kategorie:Mailinglisten]]&lt;br /&gt;
[[Kategorie:E-Mail]]&lt;/div&gt;</summary>
		<author><name>Apc00-tony</name></author>
	</entry>
	<entry>
		<id>https://wiki.hostsharing.net/index.php?title=Mlmmj&amp;diff=6403</id>
		<title>Mlmmj</title>
		<link rel="alternate" type="text/html" href="https://wiki.hostsharing.net/index.php?title=Mlmmj&amp;diff=6403"/>
		<updated>2024-02-01T15:38:01Z</updated>

		<summary type="html">&lt;p&gt;Apc00-tony: Wiki-links&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[http://www.mlmmj.org/ mlmmj], angeblich eine Abkürzung für &amp;quot;Mailing List Management Made Joyful&amp;quot;, ist ein Programm, mit dem in einem Hostsharing Paket E-Mail-Verteiler realisiert werden kann.&lt;br /&gt;
&lt;br /&gt;
Wer noch nicht weiß, was ein E-Mail-Verteiler machen soll oder wie, lese veilleicht auch den Wikipedia-Artikel:&lt;br /&gt;
[http://de.wikipedia.org/wiki/Mailingliste Mailingliste]&lt;br /&gt;
&lt;br /&gt;
Eine leistungsfähigere Alternative zu mlmmj könnte [[Mailman_3_installieren|Mailman 3]] sein.&lt;br /&gt;
&lt;br /&gt;
Diese Anleitung beschreibt die Einrichtung einer Mailingliste für eine Domain in einem Hostsharing-Webspace.&lt;br /&gt;
&lt;br /&gt;
== Voraussetzungen  ==&lt;br /&gt;
&lt;br /&gt;
Das Debian Paket [http://packages.debian.org/search?keywords=mlmmj mlmmj] ist auf den Shared-Hosting-Servern bereits installiert.&lt;br /&gt;
&lt;br /&gt;
Für den Betrieb der Mailingliste empfiehlt sich das Anlegen eines eigenen Users für diesen Zweck mit hsadmin.&lt;br /&gt;
&lt;br /&gt;
In dieser Anleitung heißt das Paket &#039;&#039;xyz00&#039;&#039; und der für Mailinglisten eingesetzte User &#039;&#039;xyz00-list&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
Die E-Mail-Adresse der einzurichtende Mailing-Liste soll &#039;&#039;discuss@example.org&#039;&#039; sein.&lt;br /&gt;
&lt;br /&gt;
Die Domain &#039;&#039;example.org&#039;&#039; muss dazu bei einem beliebigen User im Paket &#039;&#039;xyz00&#039;&#039; [[aufgeschaltet]] sein. (&amp;quot;Aufgeschaltet&amp;quot; bedeutet, daß diese Domain bei Hostsharing gehostet wird und der Domainname als Verzeichnis /home/pacs/xyz00/*User*/doms/example.org/ erscheint.)&lt;br /&gt;
&lt;br /&gt;
== Einrichtung ==&lt;br /&gt;
&lt;br /&gt;
Ich melde mich über SSH auf der Hostsharing-Console als der Paketuser &#039;&#039;xyz00&#039;&#039; an.&lt;br /&gt;
&lt;br /&gt;
Im Shell kann ich dann durch den Befehl &#039;&#039;hsscript -i&#039;&#039; das Verwaltungswerkzeug [[hsadmin]] interaktiv ausführen:&lt;br /&gt;
&lt;br /&gt;
  xyz00@h03:~$ hsscript -i&lt;br /&gt;
  Password: *************&lt;br /&gt;
  xyz00@hsadmin&amp;gt; &lt;br /&gt;
&lt;br /&gt;
In &#039;&#039;hsadmin&#039;&#039; werden User und E-Mail-Adresse angelegt.&lt;br /&gt;
&lt;br /&gt;
  xyz00@hsadmin&amp;gt; user.add({set:{name:&#039;xyz00-list&#039;,comment:&#039;Mailingliste Discuss&#039;,shell:&#039;/bin/bash&#039;,password:&#039;geheimnis&#039;}})&lt;br /&gt;
  xyz00@hsadmin&amp;gt; emailaddress.add({set:{target:&#039;xyz00-list&#039;,localpart:&#039;discuss&#039;,domain:&#039;example.org&#039;}})&lt;br /&gt;
  xyz00@hsadmin&amp;gt; bye&lt;br /&gt;
&lt;br /&gt;
Mit dem Parameter &amp;quot;target&amp;quot; wird die für diese Adresse eingehende Post zunächst in das Postfach des Users xyz00-list abgelegt.&lt;br /&gt;
&lt;br /&gt;
Für den User xyz00-list lege ich in seinem Heimat-Verzeichnis das Unterverzeichnis &amp;lt;tt&amp;gt;mlmmj&amp;lt;/tt&amp;gt; an:&lt;br /&gt;
&lt;br /&gt;
  mkdir /home/pacs/xyz00/users/list/mlmmj&lt;br /&gt;
&lt;br /&gt;
Dann lege ich die Mailingliste mit folgendem Kommando an:&lt;br /&gt;
&lt;br /&gt;
  mlmmj-make-ml -L discuss -s /home/pacs/xyz00/users/list/mlmmj&lt;br /&gt;
&lt;br /&gt;
Das Skript &#039;&#039;mlmmj-make-ml&#039;&#039; fragt weitere Parameter der Mailingliste ab:&lt;br /&gt;
&lt;br /&gt;
  The Domain for the List? [] : example.org&lt;br /&gt;
  The emailaddress of the list owner? [postmaster] : webmaster@example.org&lt;br /&gt;
  For the list texts you can choose between the following languages or&lt;br /&gt;
  give an absolute path to a directory containing the texts.&lt;br /&gt;
  Available languages:&lt;br /&gt;
  cz  da	de  en	es  fr	it  nl	ru&lt;br /&gt;
  The path to texts for the list? [en] : de&lt;br /&gt;
&lt;br /&gt;
Das skript &#039;&#039;mlmmj-make-ml&#039;&#039; legt daraufhin unter &amp;quot;/home/pacs/xyz00/users/list/mlmmj&amp;quot; ein Verzeichnis &amp;quot;discuss&amp;quot; an, das die Datenstruktur zur Verwaltung der Mailingliste enthält.&lt;br /&gt;
&lt;br /&gt;
Weitere Konfigurationen der Liste erfolgen durch das Anlegen von Dateien im&lt;br /&gt;
Verzeichnis &amp;quot;/home/pacs/xyz00/users/list/mlmmj/discuss/control&amp;quot;.&lt;br /&gt;
Die Konfigurationsmöglichkeiten finden Sie auf der [http://mlmmj.org/docs/tunables/ Internetseite von mlmmj].&lt;br /&gt;
&lt;br /&gt;
Damit mlmmj die Verteilung der Post übernimmt, muß ich im Heimat-Verzeichnis des users xyz00-list die Datei &amp;lt;tt&amp;gt;.forward&amp;lt;/tt&amp;gt; mit folgenden Inhalt (INKLUSIVE der Anführungszeichen!) erstellen:&lt;br /&gt;
&lt;br /&gt;
  &amp;quot;|/usr/bin/mlmmj-recieve -L /home/pacs/xyz00/users/list/mlmmj/discuss/&amp;quot;&lt;br /&gt;
&lt;br /&gt;
(Ja, &#039;&#039;receive&#039;&#039; schreibt sich mit &#039;&#039;-ei-&#039;&#039;, aber mlmmj hält einen symbolischen Link bereit für diejenigen, die in englischer Rechtschreibung unsicher sind:)&lt;br /&gt;
&lt;br /&gt;
   xyz00-list@h03:~$ ls -la /usr/bin/mlmmj-rec*&lt;br /&gt;
   -rwxr-xr-x 1 root root 27104 Sep 25  2018 /usr/bin/mlmmj-receive&lt;br /&gt;
   lrwxrwxrwx 1 root root    13 Sep 25  2018 /usr/bin/mlmmj-recieve -&amp;gt; mlmmj-receive&lt;br /&gt;
&lt;br /&gt;
Die &amp;lt;tt&amp;gt;.forward&amp;lt;/tt&amp;gt;-Datei sorgt dafür, dass eingehende E-Mails an das User-Postfach an das Programm &#039;&#039;mlmmj-recieve&#039;&#039; übergeben werden.&lt;br /&gt;
&lt;br /&gt;
Für regelmäßige Aufgaben der Listen-Managers definiere ich die&lt;br /&gt;
[[Cron|crontab]] wie folgt (immer noch als &#039;&#039;xyz00-list&#039;&#039;):&lt;br /&gt;
&lt;br /&gt;
  xyz00-list@h03:~$ crontab -e&lt;br /&gt;
&lt;br /&gt;
 MAILTO=webmaster@example.org&lt;br /&gt;
 PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/X11R6/bin&lt;br /&gt;
 HOME=/home/pacs/xyz00/users/list&lt;br /&gt;
 SHELL=/bin/bash&lt;br /&gt;
 LANG=en_US.UTF-8&lt;br /&gt;
 # m h  dom mon dow   command&lt;br /&gt;
 28 */4 * * * /usr/bin/mlmmj-maintd -d /home/pacs/xyz00/users/list/mlmmj -F&lt;br /&gt;
&lt;br /&gt;
Zum Schluss rufe ich das Skript mlmmj-sub auf, um die E-Mail-Adressen der gewünschten Abonnenten des Verteilers einzutragen:&lt;br /&gt;
&lt;br /&gt;
 /usr/bin/mlmmj-sub -L /home/pacs/xyz00/users/list/mlmmj/discuss -a klaus.muster@gmx.de -c &lt;br /&gt;
 /usr/bin/mlmmj-sub -L /home/pacs/xyz00/users/list/mlmmj/discuss -a sabine.beispiel@arcor.de -c &lt;br /&gt;
&lt;br /&gt;
Dabei bewirkt &amp;quot;-c&amp;quot;, dass der Abonnent eine Begrüßungs-Nachricht erhält. Alternativ kann man &amp;quot;-C&amp;quot; (großes C) angeben: dann muss der Abonnent das Abo durch Antworten auf die Nachricht bestätigen.&lt;br /&gt;
&lt;br /&gt;
== weitere Optionen  ==&lt;br /&gt;
&lt;br /&gt;
Noch ein paar Dinge, die Sie möglicherweise einstellen wollen:&lt;br /&gt;
&lt;br /&gt;
Ein Prefix in der Betreffzeile setzen, z.B.: &amp;quot;[discuss]&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
 echo &amp;quot;[discuss]&amp;quot; &amp;gt; /home/pacs/xyz00/users/list/mlmmj/discuss/control/prefix&lt;br /&gt;
&lt;br /&gt;
Wenn die Liste nur E-Mails von eingetragenen Abonnenten weiterleiten soll:&lt;br /&gt;
&lt;br /&gt;
 touch /home/pacs/xyz00/users/list/mlmmj/discuss/control/subonlypost&lt;br /&gt;
&lt;br /&gt;
Damit der Listen-Owner weitere Abonnements bestätigen muss:&lt;br /&gt;
&lt;br /&gt;
 touch /home/pacs/xyz00/users/list/mlmmj/discuss/control/submod&lt;br /&gt;
&lt;br /&gt;
Einen &amp;quot;Reply-To:&amp;quot;-Header setzen, damit Antwort-Mails standardmäßig an die Mailing-Liste gehen:&lt;br /&gt;
&lt;br /&gt;
  echo &amp;quot;Reply-To:&amp;quot; &amp;gt; /home/pacs/xyz00/users/list/mlmmj/discuss/control/delheaders&lt;br /&gt;
  echo &amp;quot;Reply-To: discuss@example.org&amp;quot; &amp;gt; /home/pacs/xyz00/users/list/mlmmj/discuss/control/customheaders&lt;br /&gt;
&lt;br /&gt;
Weitere Möglichkeiten finden Sie (wie oben bereits angegeben) &lt;br /&gt;
auf der [http://mlmmj.org/docs/tunables/ Internetseite von mlmmj].&lt;br /&gt;
&lt;br /&gt;
== Zur Konfiguration im Browser ==&lt;br /&gt;
&lt;br /&gt;
Die Original-Distribution von &#039;&#039;mlmmj&#039;&#039; enthält ein paar einfache PHP- und Perl-Skripte.  Das sind Beispiele für Subscribe-/Unsubscribe-Formulare, ein Admin-Formular zum Eintragen und Löschen von Abonnements und eine Seite mit der gesamten Listen-Konfiguration.&lt;br /&gt;
&lt;br /&gt;
Wer es sich ansehen möchte:&lt;br /&gt;
&lt;br /&gt;
Als Paket-Admin eine Domain aufschalten:&lt;br /&gt;
&lt;br /&gt;
 hsscript -u xyz00 -e &amp;quot;domain.add({set:{name:&#039;lists.example.org&#039;,user:&#039;xyz00-list&#039;}})&amp;quot;&lt;br /&gt;
&lt;br /&gt;
Und weiter als &amp;quot;xyz00-list&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
Download der neuesten Version der Sourcen von mlmmj von http://mlmmj.org/downloads/ und diese in einem temporären Verzeichnis entpacken.&lt;br /&gt;
&lt;br /&gt;
Unter &amp;quot;/mlmmj-$versionsnummer/contrib/web/php-admin/&amp;quot; findet sich die PHP-Admin-Anwendung.&lt;br /&gt;
&lt;br /&gt;
Also den Inhalt diese Verzeichnisses nach &amp;quot;/home/pacs/xyz00/users/list/doms/lists.example.org/&amp;quot; packen,&lt;br /&gt;
* in &amp;quot;/home/pacs/xyz00/users/list/doms/lists.example.org/conf/config.php&amp;quot; die Variable &amp;quot;$topdir&amp;quot; anpassen&lt;br /&gt;
* die Dateien aus &amp;quot;/home/pacs/xyz00/users/list/doms/lists.example.org/htdocs/&amp;quot; nach &amp;quot;/home/pacs/xyz00/users/list/doms/lists.example.org/htdocs-ssl/&amp;quot; verschieben&lt;br /&gt;
* in &amp;quot;/home/pacs/xyz00/users/list/mlmmj&amp;quot; und in &amp;quot;/home/pacs/xyz00/users/list/doms/lists.example.org/htdocs-ssl/&amp;quot; eine &amp;quot;.htaccess&amp;quot; mit folgendem Inhalt ablegen: &lt;br /&gt;
 &lt;br /&gt;
 Require valid-user&lt;br /&gt;
 AuthType Basic&lt;br /&gt;
 AuthName &amp;quot;mlmmj web-interface&amp;quot;&lt;br /&gt;
 AuthUserFile /home/pacs/xyz00/users/list/doms/lists.example.org/etc/htpasswd&lt;br /&gt;
&lt;br /&gt;
Und schließlich die &amp;quot;htpasswd&amp;quot;-Datei anlegen.&lt;br /&gt;
&lt;br /&gt;
 cd /home/pacs/xyz00/users/list/doms/lists.example.org/etc/&lt;br /&gt;
 htpasswd -c htpasswd listadmin&lt;br /&gt;
&lt;br /&gt;
Ein Passwort angeben und auf&lt;br /&gt;
https://lists.example.org schauen.&lt;br /&gt;
&lt;br /&gt;
== Mehrere Mailinglisten betreiben ==&lt;br /&gt;
&lt;br /&gt;
Wenn mehrere Mailinglisten in einem Account und mit einer Admin-Oberfläche betrieben werden soll, empfiehlt sich die Nutzung von Procmail für den Aufruf von &#039;&#039;mlmmj&#039;&#039; für die jeweiligen Liste mit ihrem Daten-Verzeichnis.&lt;br /&gt;
&lt;br /&gt;
Dazu trägt man in der Date &#039;&#039;.forward&#039;&#039; statt des Aufrufs von &#039;&#039;mlmmj-recieve&#039;&#039; einen Aufruf von &#039;&#039;procmail&#039;&#039; ein:&lt;br /&gt;
&lt;br /&gt;
 |/usr/bin/procmail&lt;br /&gt;
&lt;br /&gt;
Die Konfiguration von Procmail kann generisch erfolgen. Dazu legt man eine Datei &#039;&#039;.procmailrc&#039;&#039; mit folgendem Inhalt ins $HOME des Users:&lt;br /&gt;
&lt;br /&gt;
 SHELL=/bin/sh&lt;br /&gt;
 HOMEDIR=/home/pacs/xyz00/users/list&lt;br /&gt;
 MAILDIR=/home/pacs/xyz00/users/list/Maildir&lt;br /&gt;
 PMDIR=/home/pacs/xyz00/users/list&lt;br /&gt;
 VERBOSE=yes&lt;br /&gt;
 LOGFILE=/home/pacs/xyz00/users/list/var/procmail.log&lt;br /&gt;
 DEFAULT&lt;br /&gt;
 &lt;br /&gt;
 :0:&lt;br /&gt;
 * ^X-Original-To: ()\/[^@+]+&lt;br /&gt;
 |/usr/bin/mlmmj-receive -F -L /home/pacs/xyz00/users/list/mlmmj/${MATCH}/&lt;br /&gt;
 &lt;br /&gt;
 :0&lt;br /&gt;
 { EXITCODE 67 }&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Der kryptische reguläre Ausdruck hinter dem Header &#039;&#039;X-Original-To:&#039;&#039; passt auf den Beginn der E-Mail-Adresse bis zum ersten &#039;&#039;@&#039;&#039;- oder &#039;&#039;+&#039;&#039;-Zeichen. In der Variable &#039;&#039;MATCH&#039;&#039; steht also der Name der Mailingliste, d.h. der Name der Verzeichnisses, in dem die Liste verwaltet wird.&lt;br /&gt;
&lt;br /&gt;
Sehr wichtig ist die Zeile &#039;&#039;DEFAULT&#039;&#039; zu Beginn der &#039;&#039;.procmailrc&#039;&#039;. Die Variable &#039;&#039;DEFAULT&#039;&#039; wird von &#039;&#039;procmail&#039;&#039; gesetzt. Wir sorgen mit dieser Zeile dafür, dass sie wieder undefiniert ist. Diese Variable wird intern von &#039;&#039;mlmmj&#039;&#039; benutzt, wenn sie gesetzt ist. Das führt in Kombination mit &#039;&#039;procmail&#039;&#039; zu Fehlfunktionen (vgl. Links).&lt;br /&gt;
&lt;br /&gt;
== Links ==&lt;br /&gt;
&lt;br /&gt;
* http://mlmmj.org/ Projektseite&lt;br /&gt;
* https://codeberg.org/mlmmj mlmmj auf Codeberg&lt;br /&gt;
* https://github.com/tchapi/mlmmj-simple-web-interface ein Admin-Interface in NodeJS&lt;br /&gt;
* https://www.tablix.org/~avian/blog/archives/2010/04/the_faulty_default/ Nutzung von mlmmj in Verbindung mit Procmail&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
[[Kategorie:HSDoku]]&lt;br /&gt;
[[Kategorie:Installationsanleitungen]]&lt;br /&gt;
[[Kategorie:Software]]&lt;br /&gt;
[[Kategorie:Mailinglisten]]&lt;br /&gt;
[[Kategorie:E-Mail]]&lt;/div&gt;</summary>
		<author><name>Apc00-tony</name></author>
	</entry>
	<entry>
		<id>https://wiki.hostsharing.net/index.php?title=Mlmmj&amp;diff=6402</id>
		<title>Mlmmj</title>
		<link rel="alternate" type="text/html" href="https://wiki.hostsharing.net/index.php?title=Mlmmj&amp;diff=6402"/>
		<updated>2024-02-01T14:10:41Z</updated>

		<summary type="html">&lt;p&gt;Apc00-tony: /* mlmmj */ Gliederung&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[http://www.mlmmj.org/ mlmmj], angeblich eine Abkürzung für &amp;quot;Mailing List Management Made Joyful&amp;quot;, ist ein Programm, mit dem in einem Hostsharing Paket E-Mail-Verteiler realisiert werden kann.&lt;br /&gt;
&lt;br /&gt;
Wer noch nicht weiß, was ein E-Mail-Verteiler machen soll oder wie, lese veilleicht auch den Wikipedia-Artikel:&lt;br /&gt;
[http://de.wikipedia.org/wiki/Mailingliste Mailingliste]&lt;br /&gt;
&lt;br /&gt;
Eine leistungsfähigere Alternative zu mlmmj könnte [[Mailman_3_installieren|Mailman 3]] sein.&lt;br /&gt;
&lt;br /&gt;
Diese Anleitung beschreibt die Einrichtung einer Mailingliste für eine Domain in einem Hostsharing-Webspace.&lt;br /&gt;
&lt;br /&gt;
== Voraussetzungen  ==&lt;br /&gt;
&lt;br /&gt;
Das Debian Paket [http://packages.debian.org/search?keywords=mlmmj mlmmj] ist auf den Shared-Hosting-Servern bereits installiert.&lt;br /&gt;
&lt;br /&gt;
Für den Betrieb der Mailingliste empfiehlt sich das Anlegen eines eigenen Users für diesen Zweck mit hsadmin.&lt;br /&gt;
&lt;br /&gt;
In dieser Anleitung heißt das Paket &#039;&#039;xyz00&#039;&#039; und der für Mailinglisten eingesetzte User &#039;&#039;xyz00-list&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
Die E-Mail-Adresse der einzurichtende Mailing-Liste soll &#039;&#039;discuss@example.org&#039;&#039; sein.&lt;br /&gt;
&lt;br /&gt;
Die Domain &#039;&#039;example.org&#039;&#039; muss dazu bei einem beliebigen User im Paket &#039;&#039;xyz00&#039;&#039; [[aufgeschaltet]] sein. (&amp;quot;Aufgeschaltet&amp;quot; bedeutet, daß diese Domain bei Hostsharing gehostet wird und der Domainname als Verzeichnis /home/pacs/xyz00/*User*/doms/example.org/ erscheint.)&lt;br /&gt;
&lt;br /&gt;
== Einrichtung ==&lt;br /&gt;
&lt;br /&gt;
Ich melde mich über SSH auf der Hostsharing-Console als der Paketuser &#039;&#039;xyz00&#039;&#039; an.&lt;br /&gt;
&lt;br /&gt;
Im Shell kann ich dann durch den Befehl &#039;&#039;hsscript -i&#039;&#039; das Verwaltungswerkzeug &#039;&#039;hsadmin&#039;&#039; interaktiv ausführen:&lt;br /&gt;
&lt;br /&gt;
  xyz00@h03:~$ hsscript -i&lt;br /&gt;
  Password: *************&lt;br /&gt;
  xyz00@hsadmin&amp;gt; &lt;br /&gt;
&lt;br /&gt;
In &#039;&#039;hsadmin&#039;&#039; werden User und E-Mail-Adresse angelegt.&lt;br /&gt;
&lt;br /&gt;
  xyz00@hsadmin&amp;gt; user.add({set:{name:&#039;xyz00-list&#039;,comment:&#039;Mailingliste Discuss&#039;,shell:&#039;/bin/bash&#039;,password:&#039;geheimnis&#039;}})&lt;br /&gt;
  xyz00@hsadmin&amp;gt; emailaddress.add({set:{target:&#039;xyz00-list&#039;,localpart:&#039;discuss&#039;,domain:&#039;example.org&#039;}})&lt;br /&gt;
  xyz00@hsadmin&amp;gt; bye&lt;br /&gt;
&lt;br /&gt;
Mit dem Parameter &amp;quot;target&amp;quot; wird die für diese Adresse eingehende Post zunächst in das Postfach des Users xyz00-list abgelegt.&lt;br /&gt;
&lt;br /&gt;
Für den User xyz00-list lege ich in seinem Heimat-Verzeichnis das Unterverzeichnis &amp;quot;mlmmj&amp;quot; an:&lt;br /&gt;
&lt;br /&gt;
  mkdir /home/pacs/xyz00/users/list/mlmmj&lt;br /&gt;
&lt;br /&gt;
Dann lege ich die Mailingliste mit folgendem Kommando an:&lt;br /&gt;
&lt;br /&gt;
  mlmmj-make-ml -L discuss -s /home/pacs/xyz00/users/list/mlmmj&lt;br /&gt;
&lt;br /&gt;
Das Skript &#039;&#039;mlmmj-make-ml&#039;&#039; fragt weitere Parameter der Mailingliste ab:&lt;br /&gt;
&lt;br /&gt;
  The Domain for the List? [] : example.org&lt;br /&gt;
  The emailaddress of the list owner? [postmaster] : webmaster@example.org&lt;br /&gt;
  For the list texts you can choose between the following languages or&lt;br /&gt;
  give an absolute path to a directory containing the texts.&lt;br /&gt;
  Available languages:&lt;br /&gt;
  cz  da	de  en	es  fr	it  nl	ru&lt;br /&gt;
  The path to texts for the list? [en] : de&lt;br /&gt;
&lt;br /&gt;
Das skript &#039;&#039;mlmmj-make-ml&#039;&#039; legt daraufhin unter &amp;quot;/home/pacs/xyz00/users/list/mlmmj&amp;quot; ein Verzeichnis &amp;quot;discuss&amp;quot; an, das die Datenstruktur zur Verwaltung der Mailingliste enthält.&lt;br /&gt;
&lt;br /&gt;
Weitere Konfigurationen der Liste erfolgen durch das Anlegen von Dateien im&lt;br /&gt;
Verzeichnis &amp;quot;/home/pacs/xyz00/users/list/mlmmj/discuss/control&amp;quot;.&lt;br /&gt;
Die Konfigurationsmöglichkeiten finden Sie auf der [http://mlmmj.org/docs/tunables/ Internetseite von mlmmj].&lt;br /&gt;
&lt;br /&gt;
Damit mlmmj die Verteilung der Post übernimmt, muß ich im Heimat-Verzeichnis des users xyz00-list die Datei &amp;lt;tt&amp;gt;.forward&amp;lt;/tt&amp;gt; mit folgenden Inhalt (INKLUSIVE der Anführungszeichen!) erstellen:&lt;br /&gt;
&lt;br /&gt;
  &amp;quot;|/usr/bin/mlmmj-recieve -L /home/pacs/xyz00/users/list/mlmmj/discuss/&amp;quot;&lt;br /&gt;
&lt;br /&gt;
(Ja, &#039;&#039;receive&#039;&#039; schreibt sich mit &#039;&#039;-ei-&#039;&#039;, aber mlmmj hält einen symbolischen Link bereit für diejenigen, die in englischer Rechtschreibung unsicher sind:)&lt;br /&gt;
&lt;br /&gt;
   xyz00-list@h03:~$ ls -la /usr/bin/mlmmj-rec*&lt;br /&gt;
   -rwxr-xr-x 1 root root 27104 Sep 25  2018 /usr/bin/mlmmj-receive&lt;br /&gt;
   lrwxrwxrwx 1 root root    13 Sep 25  2018 /usr/bin/mlmmj-recieve -&amp;gt; mlmmj-receive&lt;br /&gt;
&lt;br /&gt;
Die &amp;lt;tt&amp;gt;.forward&amp;lt;/tt&amp;gt;-Datei sorgt dafür, dass eingehende E-Mails an das User-Postfach an das Programm &#039;&#039;mlmmj-recieve&#039;&#039; übergeben werden.&lt;br /&gt;
&lt;br /&gt;
Für regelmäßige Aufgaben der Listen-Managers definiere ich die&lt;br /&gt;
crontab wie folgt (immer noch als &#039;&#039;xyz00-list&#039;&#039;):&lt;br /&gt;
&lt;br /&gt;
  xyz00-list@h03:~$ crontab -e&lt;br /&gt;
&lt;br /&gt;
 MAILTO=webmaster@example.org&lt;br /&gt;
 PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/X11R6/bin&lt;br /&gt;
 HOME=/home/pacs/xyz00/users/list&lt;br /&gt;
 SHELL=/bin/bash&lt;br /&gt;
 LANG=en_US.UTF-8&lt;br /&gt;
 # m h  dom mon dow   command&lt;br /&gt;
 28 */4 * * * /usr/bin/mlmmj-maintd -d /home/pacs/xyz00/users/list/mlmmj -F&lt;br /&gt;
&lt;br /&gt;
Zum Schluss rufe ich das Skript mlmmj-sub auf, um die E-Mail-Adressen der gewünschten Abonnenten des Verteilers einzutragen:&lt;br /&gt;
&lt;br /&gt;
 /usr/bin/mlmmj-sub -L /home/pacs/xyz00/users/list/mlmmj/discuss -a klaus.muster@gmx.de -c &lt;br /&gt;
 /usr/bin/mlmmj-sub -L /home/pacs/xyz00/users/list/mlmmj/discuss -a sabine.beispiel@arcor.de -c &lt;br /&gt;
&lt;br /&gt;
Dabei bewirkt &amp;quot;-c&amp;quot;, dass der Abonnent eine Begrüßungs-Nachricht erhält. Alternativ kann man &amp;quot;-C&amp;quot; (großes C) angeben: dann muss der Abonnent das Abo durch Antworten auf die Nachricht bestätigen.&lt;br /&gt;
&lt;br /&gt;
== weitere Optionen  ==&lt;br /&gt;
&lt;br /&gt;
Noch ein paar Dinge, die Sie möglicherweise einstellen wollen:&lt;br /&gt;
&lt;br /&gt;
Ein Prefix in der Betreffzeile setzen, z.B.: &amp;quot;[discuss]&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
 echo &amp;quot;[discuss]&amp;quot; &amp;gt; /home/pacs/xyz00/users/list/mlmmj/discuss/control/prefix&lt;br /&gt;
&lt;br /&gt;
Wenn die Liste nur E-Mails von eingetragenen Abonnenten weiterleiten soll:&lt;br /&gt;
&lt;br /&gt;
 touch /home/pacs/xyz00/users/list/mlmmj/discuss/control/subonlypost&lt;br /&gt;
&lt;br /&gt;
Damit der Listen-Owner weitere Abonnements bestätigen muss:&lt;br /&gt;
&lt;br /&gt;
 touch /home/pacs/xyz00/users/list/mlmmj/discuss/control/submod&lt;br /&gt;
&lt;br /&gt;
Einen &amp;quot;Reply-To:&amp;quot;-Header setzen, damit Antwort-Mails standardmäßig an die Mailing-Liste gehen:&lt;br /&gt;
&lt;br /&gt;
  echo &amp;quot;Reply-To:&amp;quot; &amp;gt; /home/pacs/xyz00/users/list/mlmmj/discuss/control/delheaders&lt;br /&gt;
  echo &amp;quot;Reply-To: discuss@example.org&amp;quot; &amp;gt; /home/pacs/xyz00/users/list/mlmmj/discuss/control/customheaders&lt;br /&gt;
&lt;br /&gt;
Weitere Möglichkeiten finden Sie (wie oben bereits angegeben) &lt;br /&gt;
auf der [http://mlmmj.org/docs/tunables/ Internetseite von mlmmj].&lt;br /&gt;
&lt;br /&gt;
== Zur Konfiguration im Browser ==&lt;br /&gt;
&lt;br /&gt;
Die Original-Distribution von &#039;&#039;mlmmj&#039;&#039; enthält ein paar einfache PHP- und Perl-Skripte.  Das sind Beispiele für Subscribe-/Unsubscribe-Formulare, ein Admin-Formular zum Eintragen und Löschen von Abonnements und eine Seite mit der gesamten Listen-Konfiguration.&lt;br /&gt;
&lt;br /&gt;
Wer es sich ansehen möchte:&lt;br /&gt;
&lt;br /&gt;
Als Paket-Admin eine Domain aufschalten:&lt;br /&gt;
&lt;br /&gt;
 hsscript -u xyz00 -e &amp;quot;domain.add({set:{name:&#039;lists.example.org&#039;,user:&#039;xyz00-list&#039;}})&amp;quot;&lt;br /&gt;
&lt;br /&gt;
Und weiter als &amp;quot;xyz00-list&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
Download der neuesten Version der Sourcen von mlmmj von http://mlmmj.org/downloads/ und diese in einem temporären Verzeichnis entpacken.&lt;br /&gt;
&lt;br /&gt;
Unter &amp;quot;/mlmmj-$versionsnummer/contrib/web/php-admin/&amp;quot; findet sich die PHP-Admin-Anwendung.&lt;br /&gt;
&lt;br /&gt;
Also den Inhalt diese Verzeichnisses nach &amp;quot;/home/pacs/xyz00/users/list/doms/lists.example.org/&amp;quot; packen,&lt;br /&gt;
* in &amp;quot;/home/pacs/xyz00/users/list/doms/lists.example.org/conf/config.php&amp;quot; die Variable &amp;quot;$topdir&amp;quot; anpassen&lt;br /&gt;
* die Dateien aus &amp;quot;/home/pacs/xyz00/users/list/doms/lists.example.org/htdocs/&amp;quot; nach &amp;quot;/home/pacs/xyz00/users/list/doms/lists.example.org/htdocs-ssl/&amp;quot; verschieben&lt;br /&gt;
* in &amp;quot;/home/pacs/xyz00/users/list/mlmmj&amp;quot; und in &amp;quot;/home/pacs/xyz00/users/list/doms/lists.example.org/htdocs-ssl/&amp;quot; eine &amp;quot;.htaccess&amp;quot; mit folgendem Inhalt ablegen: &lt;br /&gt;
 &lt;br /&gt;
 Require valid-user&lt;br /&gt;
 AuthType Basic&lt;br /&gt;
 AuthName &amp;quot;mlmmj web-interface&amp;quot;&lt;br /&gt;
 AuthUserFile /home/pacs/xyz00/users/list/doms/lists.example.org/etc/htpasswd&lt;br /&gt;
&lt;br /&gt;
Und schließlich die &amp;quot;htpasswd&amp;quot;-Datei anlegen.&lt;br /&gt;
&lt;br /&gt;
 cd /home/pacs/xyz00/users/list/doms/lists.example.org/etc/&lt;br /&gt;
 htpasswd -c htpasswd listadmin&lt;br /&gt;
&lt;br /&gt;
Ein Passwort angeben und auf&lt;br /&gt;
https://lists.example.org schauen.&lt;br /&gt;
&lt;br /&gt;
== Mehrere Mailinglisten betreiben ==&lt;br /&gt;
&lt;br /&gt;
Wenn mehrere Mailinglisten in einem Account und mit einer Admin-Oberfläche betrieben werden soll, empfiehlt sich die Nutzung von Procmail für den Aufruf von &#039;&#039;mlmmj&#039;&#039; für die jeweiligen Liste mit ihrem Daten-Verzeichnis.&lt;br /&gt;
&lt;br /&gt;
Dazu trägt man in der Date &#039;&#039;.forward&#039;&#039; statt des Aufrufs von &#039;&#039;mlmmj-recieve&#039;&#039; einen Aufruf von &#039;&#039;procmail&#039;&#039; ein:&lt;br /&gt;
&lt;br /&gt;
 |/usr/bin/procmail&lt;br /&gt;
&lt;br /&gt;
Die Konfiguration von Procmail kann generisch erfolgen. Dazu legt man eine Datei &#039;&#039;.procmailrc&#039;&#039; mit folgendem Inhalt ins $HOME des Users:&lt;br /&gt;
&lt;br /&gt;
 SHELL=/bin/sh&lt;br /&gt;
 HOMEDIR=/home/pacs/xyz00/users/list&lt;br /&gt;
 MAILDIR=/home/pacs/xyz00/users/list/Maildir&lt;br /&gt;
 PMDIR=/home/pacs/xyz00/users/list&lt;br /&gt;
 VERBOSE=yes&lt;br /&gt;
 LOGFILE=/home/pacs/xyz00/users/list/var/procmail.log&lt;br /&gt;
 DEFAULT&lt;br /&gt;
 &lt;br /&gt;
 :0:&lt;br /&gt;
 * ^X-Original-To: ()\/[^@+]+&lt;br /&gt;
 |/usr/bin/mlmmj-receive -F -L /home/pacs/xyz00/users/list/mlmmj/${MATCH}/&lt;br /&gt;
 &lt;br /&gt;
 :0&lt;br /&gt;
 { EXITCODE 67 }&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Der kryptische reguläre Ausdruck hinter dem Header &#039;&#039;X-Original-To:&#039;&#039; passt auf den Beginn der E-Mail-Adresse bis zum ersten &#039;&#039;@&#039;&#039;- oder &#039;&#039;+&#039;&#039;-Zeichen. In der Variable &#039;&#039;MATCH&#039;&#039; steht also der Name der Mailingliste, d.h. der Name der Verzeichnisses, in dem die Liste verwaltet wird.&lt;br /&gt;
&lt;br /&gt;
Sehr wichtig ist die Zeile &#039;&#039;DEFAULT&#039;&#039; zu Beginn der &#039;&#039;.procmailrc&#039;&#039;. Die Variable &#039;&#039;DEFAULT&#039;&#039; wird von &#039;&#039;procmail&#039;&#039; gesetzt. Wir sorgen mit dieser Zeile dafür, dass sie wieder undefiniert ist. Diese Variable wird intern von &#039;&#039;mlmmj&#039;&#039; benutzt, wenn sie gesetzt ist. Das führt in Kombination mit &#039;&#039;procmail&#039;&#039; zu Fehlfunktionen (vgl. Links).&lt;br /&gt;
&lt;br /&gt;
== Links ==&lt;br /&gt;
&lt;br /&gt;
* http://mlmmj.org/ Projektseite&lt;br /&gt;
* https://codeberg.org/mlmmj mlmmj auf Codeberg&lt;br /&gt;
* https://github.com/tchapi/mlmmj-simple-web-interface ein Admin-Interface in NodeJS&lt;br /&gt;
* https://www.tablix.org/~avian/blog/archives/2010/04/the_faulty_default/ Nutzung von mlmmj in Verbindung mit Procmail&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
[[Kategorie:HSDoku]]&lt;br /&gt;
[[Kategorie:Installationsanleitungen]]&lt;br /&gt;
[[Kategorie:Software]]&lt;br /&gt;
[[Kategorie:Mailinglisten]]&lt;br /&gt;
[[Kategorie:E-Mail]]&lt;/div&gt;</summary>
		<author><name>Apc00-tony</name></author>
	</entry>
	<entry>
		<id>https://wiki.hostsharing.net/index.php?title=Mlmmj&amp;diff=6401</id>
		<title>Mlmmj</title>
		<link rel="alternate" type="text/html" href="https://wiki.hostsharing.net/index.php?title=Mlmmj&amp;diff=6401"/>
		<updated>2024-02-01T14:08:45Z</updated>

		<summary type="html">&lt;p&gt;Apc00-tony: Gliederung&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[http://www.mlmmj.org/ mlmmj], angeblich eine Abkürzung für &amp;quot;Mailing List Management Made Joyful&amp;quot;, ist ein Programm, mit dem in einem Hostsharing Paket E-Mail-Verteiler realisiert werden kann.&lt;br /&gt;
&lt;br /&gt;
Wer noch nicht weiß, was ein E-Mail-Verteiler machen soll oder wie, lese veilleicht auch den Wikipedia-Artikel:&lt;br /&gt;
[http://de.wikipedia.org/wiki/Mailingliste Mailingliste]&lt;br /&gt;
&lt;br /&gt;
Eine leistungsfähigere Alternative zu mlmmj könnte [[Mailman_3_installieren|Mailman 3]] sein.&lt;br /&gt;
&lt;br /&gt;
Diese Anleitung beschreibt die Einrichtung einer Mailingliste für eine Domain in einem Hostsharing-Webspace.&lt;br /&gt;
&lt;br /&gt;
== mlmmj ==&lt;br /&gt;
&lt;br /&gt;
Das Debian Paket [http://packages.debian.org/search?keywords=mlmmj mlmmj] ist auf den Shared-Hosting-Servern bereits installiert.&lt;br /&gt;
&lt;br /&gt;
=== Voraussetzungen  ===&lt;br /&gt;
&lt;br /&gt;
Für den Betrieb der Mailingliste empfiehlt sich das Anlegen eines eigenen Users für diesen Zweck mit hsadmin.&lt;br /&gt;
&lt;br /&gt;
In dieser Anleitung heißt das Paket &#039;&#039;xyz00&#039;&#039; und der für Mailinglisten eingesetzte User &#039;&#039;xyz00-list&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
Die E-Mail-Adresse der einzurichtende Mailing-Liste soll &#039;&#039;discuss@example.org&#039;&#039; sein.&lt;br /&gt;
&lt;br /&gt;
Die Domain &#039;&#039;example.org&#039;&#039; muss dazu bei einem beliebigen User im Paket &#039;&#039;xyz00&#039;&#039; [[aufgeschaltet]] sein. (&amp;quot;Aufgeschaltet&amp;quot; bedeutet, daß diese Domain bei Hostsharing gehostet wird und der Domainname als Verzeichnis /home/pacs/xyz00/*User*/doms/example.org/ erscheint.)&lt;br /&gt;
&lt;br /&gt;
=== Einrichtung  ===&lt;br /&gt;
&lt;br /&gt;
Ich melde mich über SSH auf der Hostsharing-Console als der Paketuser &#039;&#039;xyz00&#039;&#039; an.&lt;br /&gt;
&lt;br /&gt;
Im Shell kann ich dann durch den Befehl &#039;&#039;hsscript -i&#039;&#039; das Verwaltungswerkzeug &#039;&#039;hsadmin&#039;&#039; interaktiv ausführen:&lt;br /&gt;
&lt;br /&gt;
  xyz00@h03:~$ hsscript -i&lt;br /&gt;
  Password: *************&lt;br /&gt;
  xyz00@hsadmin&amp;gt; &lt;br /&gt;
&lt;br /&gt;
In &#039;&#039;hsadmin&#039;&#039; werden User und E-Mail-Adresse angelegt.&lt;br /&gt;
&lt;br /&gt;
  xyz00@hsadmin&amp;gt; user.add({set:{name:&#039;xyz00-list&#039;,comment:&#039;Mailingliste Discuss&#039;,shell:&#039;/bin/bash&#039;,password:&#039;geheimnis&#039;}})&lt;br /&gt;
  xyz00@hsadmin&amp;gt; emailaddress.add({set:{target:&#039;xyz00-list&#039;,localpart:&#039;discuss&#039;,domain:&#039;example.org&#039;}})&lt;br /&gt;
  xyz00@hsadmin&amp;gt; bye&lt;br /&gt;
&lt;br /&gt;
Mit dem Parameter &amp;quot;target&amp;quot; wird die für diese Adresse eingehende Post zunächst in das Postfach des Users xyz00-list abgelegt.&lt;br /&gt;
&lt;br /&gt;
Für den User xyz00-list lege ich in seinem Heimat-Verzeichnis das Unterverzeichnis &amp;quot;mlmmj&amp;quot; an:&lt;br /&gt;
&lt;br /&gt;
  mkdir /home/pacs/xyz00/users/list/mlmmj&lt;br /&gt;
&lt;br /&gt;
Dann lege ich die Mailingliste mit folgendem Kommando an:&lt;br /&gt;
&lt;br /&gt;
  mlmmj-make-ml -L discuss -s /home/pacs/xyz00/users/list/mlmmj&lt;br /&gt;
&lt;br /&gt;
Das Skript &#039;&#039;mlmmj-make-ml&#039;&#039; fragt weitere Parameter der Mailingliste ab:&lt;br /&gt;
&lt;br /&gt;
  The Domain for the List? [] : example.org&lt;br /&gt;
  The emailaddress of the list owner? [postmaster] : webmaster@example.org&lt;br /&gt;
  For the list texts you can choose between the following languages or&lt;br /&gt;
  give an absolute path to a directory containing the texts.&lt;br /&gt;
  Available languages:&lt;br /&gt;
  cz  da	de  en	es  fr	it  nl	ru&lt;br /&gt;
  The path to texts for the list? [en] : de&lt;br /&gt;
&lt;br /&gt;
Das skript &#039;&#039;mlmmj-make-ml&#039;&#039; legt daraufhin unter &amp;quot;/home/pacs/xyz00/users/list/mlmmj&amp;quot; ein Verzeichnis &amp;quot;discuss&amp;quot; an, das die Datenstruktur zur Verwaltung der Mailingliste enthält.&lt;br /&gt;
&lt;br /&gt;
Weitere Konfigurationen der Liste erfolgen durch das Anlegen von Dateien im&lt;br /&gt;
Verzeichnis &amp;quot;/home/pacs/xyz00/users/list/mlmmj/discuss/control&amp;quot;.&lt;br /&gt;
Die Konfigurationsmöglichkeiten finden Sie auf der [http://mlmmj.org/docs/tunables/ Internetseite von mlmmj].&lt;br /&gt;
&lt;br /&gt;
Damit mlmmj die Verteilung der Post übernimmt, muß ich im Heimat-Verzeichnis des users xyz00-list die Datei &amp;lt;tt&amp;gt;.forward&amp;lt;/tt&amp;gt; mit folgenden Inhalt (INKLUSIVE der Anführungszeichen!) erstellen:&lt;br /&gt;
&lt;br /&gt;
  &amp;quot;|/usr/bin/mlmmj-recieve -L /home/pacs/xyz00/users/list/mlmmj/discuss/&amp;quot;&lt;br /&gt;
&lt;br /&gt;
(Ja, &#039;&#039;receive&#039;&#039; schreibt sich mit &#039;&#039;-ei-&#039;&#039;, aber mlmmj hält einen symbolischen Link bereit für diejenigen, die in englischer Rechtschreibung unsicher sind:)&lt;br /&gt;
&lt;br /&gt;
   xyz00-list@h03:~$ ls -la /usr/bin/mlmmj-rec*&lt;br /&gt;
   -rwxr-xr-x 1 root root 27104 Sep 25  2018 /usr/bin/mlmmj-receive&lt;br /&gt;
   lrwxrwxrwx 1 root root    13 Sep 25  2018 /usr/bin/mlmmj-recieve -&amp;gt; mlmmj-receive&lt;br /&gt;
&lt;br /&gt;
Die &amp;lt;tt&amp;gt;.forward&amp;lt;/tt&amp;gt;-Datei sorgt dafür, dass eingehende E-Mails an das User-Postfach an das Programm &#039;&#039;mlmmj-recieve&#039;&#039; übergeben werden.&lt;br /&gt;
&lt;br /&gt;
Für regelmäßige Aufgaben der Listen-Managers definiere ich die&lt;br /&gt;
crontab wie folgt (immer noch als &#039;&#039;xyz00-list&#039;&#039;):&lt;br /&gt;
&lt;br /&gt;
  xyz00-list@h03:~$ crontab -e&lt;br /&gt;
&lt;br /&gt;
 MAILTO=webmaster@example.org&lt;br /&gt;
 PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/X11R6/bin&lt;br /&gt;
 HOME=/home/pacs/xyz00/users/list&lt;br /&gt;
 SHELL=/bin/bash&lt;br /&gt;
 LANG=en_US.UTF-8&lt;br /&gt;
 # m h  dom mon dow   command&lt;br /&gt;
 28 */4 * * * /usr/bin/mlmmj-maintd -d /home/pacs/xyz00/users/list/mlmmj -F&lt;br /&gt;
&lt;br /&gt;
Zum Schluss rufe ich das Skript mlmmj-sub auf, um die E-Mail-Adressen der gewünschten Abonnenten des Verteilers einzutragen:&lt;br /&gt;
&lt;br /&gt;
 /usr/bin/mlmmj-sub -L /home/pacs/xyz00/users/list/mlmmj/discuss -a klaus.muster@gmx.de -c &lt;br /&gt;
 /usr/bin/mlmmj-sub -L /home/pacs/xyz00/users/list/mlmmj/discuss -a sabine.beispiel@arcor.de -c &lt;br /&gt;
&lt;br /&gt;
Dabei bewirkt &amp;quot;-c&amp;quot;, dass der Abonnent eine Begrüßungs-Nachricht erhält. Alternativ kann man &amp;quot;-C&amp;quot; (großes C) angeben: dann muss der Abonnent das Abo durch Antworten auf die Nachricht bestätigen.&lt;br /&gt;
&lt;br /&gt;
=== weitere Konfiguration  ===&lt;br /&gt;
&lt;br /&gt;
Noch ein paar Dinge, die Sie möglicherweise einstellen wollen:&lt;br /&gt;
&lt;br /&gt;
Ein Prefix in der Betreffzeile setzen, z.B.: &amp;quot;[discuss]&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
 echo &amp;quot;[discuss]&amp;quot; &amp;gt; /home/pacs/xyz00/users/list/mlmmj/discuss/control/prefix&lt;br /&gt;
&lt;br /&gt;
Wenn die Liste nur E-Mails von eingetragenen Abonnenten weiterleiten soll:&lt;br /&gt;
&lt;br /&gt;
 touch /home/pacs/xyz00/users/list/mlmmj/discuss/control/subonlypost&lt;br /&gt;
&lt;br /&gt;
Damit der Listen-Owner weitere Abonnements bestätigen muss:&lt;br /&gt;
&lt;br /&gt;
 touch /home/pacs/xyz00/users/list/mlmmj/discuss/control/submod&lt;br /&gt;
&lt;br /&gt;
Einen &amp;quot;Reply-To:&amp;quot;-Header setzen, damit Antwort-Mails standardmäßig an die Mailing-Liste gehen:&lt;br /&gt;
&lt;br /&gt;
  echo &amp;quot;Reply-To:&amp;quot; &amp;gt; /home/pacs/xyz00/users/list/mlmmj/discuss/control/delheaders&lt;br /&gt;
  echo &amp;quot;Reply-To: discuss@example.org&amp;quot; &amp;gt; /home/pacs/xyz00/users/list/mlmmj/discuss/control/customheaders&lt;br /&gt;
&lt;br /&gt;
Weitere Möglichkeiten finden Sie (wie oben bereits angegeben) &lt;br /&gt;
auf der [http://mlmmj.org/docs/tunables/ Internetseite von mlmmj].&lt;br /&gt;
&lt;br /&gt;
=== Konfiguration im Browser ===&lt;br /&gt;
&lt;br /&gt;
Die Original-Distribution von &#039;&#039;mlmmj&#039;&#039; enthält ein paar einfache PHP- und Perl-Skripte.  Das sind Beispiele für Subscribe-/Unsubscribe-Formulare, ein Admin-Formular zum Eintragen und Löschen von Abonnements und eine Seite mit der gesamten Listen-Konfiguration.&lt;br /&gt;
&lt;br /&gt;
Wer es sich ansehen möchte:&lt;br /&gt;
&lt;br /&gt;
Als Paket-Admin eine Domain aufschalten:&lt;br /&gt;
&lt;br /&gt;
 hsscript -u xyz00 -e &amp;quot;domain.add({set:{name:&#039;lists.example.org&#039;,user:&#039;xyz00-list&#039;}})&amp;quot;&lt;br /&gt;
&lt;br /&gt;
Und weiter als &amp;quot;xyz00-list&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
Download der neuesten Version der Sourcen von mlmmj von http://mlmmj.org/downloads/ und diese in einem temporären Verzeichnis entpacken.&lt;br /&gt;
&lt;br /&gt;
Unter &amp;quot;/mlmmj-$versionsnummer/contrib/web/php-admin/&amp;quot; findet sich die PHP-Admin-Anwendung.&lt;br /&gt;
&lt;br /&gt;
Also den Inhalt diese Verzeichnisses nach &amp;quot;/home/pacs/xyz00/users/list/doms/lists.example.org/&amp;quot; packen,&lt;br /&gt;
* in &amp;quot;/home/pacs/xyz00/users/list/doms/lists.example.org/conf/config.php&amp;quot; die Variable &amp;quot;$topdir&amp;quot; anpassen&lt;br /&gt;
* die Dateien aus &amp;quot;/home/pacs/xyz00/users/list/doms/lists.example.org/htdocs/&amp;quot; nach &amp;quot;/home/pacs/xyz00/users/list/doms/lists.example.org/htdocs-ssl/&amp;quot; verschieben&lt;br /&gt;
* in &amp;quot;/home/pacs/xyz00/users/list/mlmmj&amp;quot; und in &amp;quot;/home/pacs/xyz00/users/list/doms/lists.example.org/htdocs-ssl/&amp;quot; eine &amp;quot;.htaccess&amp;quot; mit folgendem Inhalt ablegen: &lt;br /&gt;
 &lt;br /&gt;
 Require valid-user&lt;br /&gt;
 AuthType Basic&lt;br /&gt;
 AuthName &amp;quot;mlmmj web-interface&amp;quot;&lt;br /&gt;
 AuthUserFile /home/pacs/xyz00/users/list/doms/lists.example.org/etc/htpasswd&lt;br /&gt;
&lt;br /&gt;
Und schließlich die &amp;quot;htpasswd&amp;quot;-Datei anlegen.&lt;br /&gt;
&lt;br /&gt;
 cd /home/pacs/xyz00/users/list/doms/lists.example.org/etc/&lt;br /&gt;
 htpasswd -c htpasswd listadmin&lt;br /&gt;
&lt;br /&gt;
Ein Passwort angeben und auf&lt;br /&gt;
https://lists.example.org schauen.&lt;br /&gt;
&lt;br /&gt;
== Mehrere Mailinglisten betreiben ==&lt;br /&gt;
&lt;br /&gt;
Wenn mehrere Mailinglisten in einem Account und mit einer Admin-Oberfläche betrieben werden soll, empfiehlt sich die Nutzung von Procmail für den Aufruf von &#039;&#039;mlmmj&#039;&#039; für die jeweiligen Liste mit ihrem Daten-Verzeichnis.&lt;br /&gt;
&lt;br /&gt;
Dazu trägt man in der Date &#039;&#039;.forward&#039;&#039; statt des Aufrufs von &#039;&#039;mlmmj-recieve&#039;&#039; einen Aufruf von &#039;&#039;procmail&#039;&#039; ein:&lt;br /&gt;
&lt;br /&gt;
 |/usr/bin/procmail&lt;br /&gt;
&lt;br /&gt;
Die Konfiguration von Procmail kann generisch erfolgen. Dazu legt man eine Datei &#039;&#039;.procmailrc&#039;&#039; mit folgendem Inhalt ins $HOME des Users:&lt;br /&gt;
&lt;br /&gt;
 SHELL=/bin/sh&lt;br /&gt;
 HOMEDIR=/home/pacs/xyz00/users/list&lt;br /&gt;
 MAILDIR=/home/pacs/xyz00/users/list/Maildir&lt;br /&gt;
 PMDIR=/home/pacs/xyz00/users/list&lt;br /&gt;
 VERBOSE=yes&lt;br /&gt;
 LOGFILE=/home/pacs/xyz00/users/list/var/procmail.log&lt;br /&gt;
 DEFAULT&lt;br /&gt;
 &lt;br /&gt;
 :0:&lt;br /&gt;
 * ^X-Original-To: ()\/[^@+]+&lt;br /&gt;
 |/usr/bin/mlmmj-receive -F -L /home/pacs/xyz00/users/list/mlmmj/${MATCH}/&lt;br /&gt;
 &lt;br /&gt;
 :0&lt;br /&gt;
 { EXITCODE 67 }&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Der kryptische reguläre Ausdruck hinter dem Header &#039;&#039;X-Original-To:&#039;&#039; passt auf den Beginn der E-Mail-Adresse bis zum ersten &#039;&#039;@&#039;&#039;- oder &#039;&#039;+&#039;&#039;-Zeichen. In der Variable &#039;&#039;MATCH&#039;&#039; steht also der Name der Mailingliste, d.h. der Name der Verzeichnisses, in dem die Liste verwaltet wird.&lt;br /&gt;
&lt;br /&gt;
Sehr wichtig ist die Zeile &#039;&#039;DEFAULT&#039;&#039; zu Beginn der &#039;&#039;.procmailrc&#039;&#039;. Die Variable &#039;&#039;DEFAULT&#039;&#039; wird von &#039;&#039;procmail&#039;&#039; gesetzt. Wir sorgen mit dieser Zeile dafür, dass sie wieder undefiniert ist. Diese Variable wird intern von &#039;&#039;mlmmj&#039;&#039; benutzt, wenn sie gesetzt ist. Das führt in Kombination mit &#039;&#039;procmail&#039;&#039; zu Fehlfunktionen (vgl. Links).&lt;br /&gt;
&lt;br /&gt;
== Links ==&lt;br /&gt;
&lt;br /&gt;
* http://mlmmj.org/ Projektseite&lt;br /&gt;
* https://codeberg.org/mlmmj mlmmj auf Codeberg&lt;br /&gt;
* https://github.com/tchapi/mlmmj-simple-web-interface ein Admin-Interface in NodeJS&lt;br /&gt;
* https://www.tablix.org/~avian/blog/archives/2010/04/the_faulty_default/ Nutzung von mlmmj in Verbindung mit Procmail&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
[[Kategorie:HSDoku]]&lt;br /&gt;
[[Kategorie:Installationsanleitungen]]&lt;br /&gt;
[[Kategorie:Software]]&lt;br /&gt;
[[Kategorie:Mailinglisten]]&lt;br /&gt;
[[Kategorie:E-Mail]]&lt;/div&gt;</summary>
		<author><name>Apc00-tony</name></author>
	</entry>
	<entry>
		<id>https://wiki.hostsharing.net/index.php?title=Mailman_Installieren&amp;diff=6400</id>
		<title>Mailman Installieren</title>
		<link rel="alternate" type="text/html" href="https://wiki.hostsharing.net/index.php?title=Mailman_Installieren&amp;diff=6400"/>
		<updated>2024-02-01T14:07:25Z</updated>

		<summary type="html">&lt;p&gt;Apc00-tony: Lede: Mailman 2 obsolet!&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Achtung! Mailman 2 benötigt Python 2.7; das wird von den bei Hostsharing aktiven aktuellen Debian GNU/Linux-Betriebssystemen &#039;&#039;&#039;nicht mehr unterstützt&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
Alternativen sind [[Mailman_3_installieren|Mailman 3]] und [[mlmmj]].&lt;br /&gt;
&lt;br /&gt;
Adieu, Mailman 2, es war sehr schön mit dir.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Vorab: Die Wahl von Mailman 2 ==&lt;br /&gt;
&lt;br /&gt;
Mailman 2 hängt von Python 2.7 ab und wird damit voraussichtlich nur noch eine begrenzte Nutzungsdauer haben. Mailman 3 ist jetzt verfügbar (siehe [[Mailman_3_installieren]]), aber deutlich schwerer und komplexer im Betrieb. Es gibt auch weniger leistungsfähige Software, um E-Mail-Verteiler zu betreiben, wie beispielsweise [[mlmmj]]. Für eine Diskussion der Situation im Oktober 2019, siehe das HS-Support-Archiv ab [https://lists.hostsharing.net/archiv/support/2019-October/067243.html hier.]&lt;br /&gt;
&lt;br /&gt;
== Mailman 2 installieren == &lt;br /&gt;
&lt;br /&gt;
(zuletzt getestet mit mailman-2.1.29; Installation durch Paketuser)&lt;br /&gt;
&lt;br /&gt;
Vielen Dank an alle Benutzer, die Verbesserungen beisteuern!&lt;br /&gt;
&lt;br /&gt;
=== Unter welchem Account installieren? ===&lt;br /&gt;
&lt;br /&gt;
Mailman kann vom Paketadmin (beipsielsweise &amp;quot;xyz00&amp;quot;) oder von einem Paketuser (bspw. &amp;quot;xyz00-listen&amp;quot;) installiert werden. Letzteres ist dringend empfohlen, denn wenn Mailman vom Paketadmin installiert wird, haben ausnahmslos alle Paketuser direkten Zugriff auf die Mailman-Daten, und bei Sicherheitslücken in Mailman wäre eventuell eine Rechte-Eskalierung auf Paketadmin-Ebene potentiell zu befürchten.&lt;br /&gt;
&lt;br /&gt;
Dem Paketuser, unter dem Mailman installiert wird, können mehrere Subdomains aufschaltet werden, und Mailinglisten können auch die Domainnamen verwenden, die anderen Paketusern gehören.&lt;br /&gt;
&lt;br /&gt;
Vorteil der Installation als Paketuser ist, dass nur dieser direkten Zugriff auf die Mailmandaten hat und mailman ohne Paketadminrechte läuft. Während der Emailauslieferung gelten (wie immer bei der Mailweiterleitung durch .forward-Dateien oder durch procmail) die Rechte des Paketusers, dem die Mailman-Installation gehört.&lt;br /&gt;
&lt;br /&gt;
Nachteil der Installation als Paketuser ist lediglich, dass die Paketdomain mit dem SSL Zertifikat von Hostsharing nicht genutzt werden kann.&amp;lt;!-- Aktualisieren? --&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Einen User und eine Domain anlegen ===&lt;br /&gt;
&lt;br /&gt;
Unter admin.hostsharing.net als xyz00 anmelden; den User xyz00-listen erzeugen; die Domain listen.example.com mit &amp;quot;Domain-User&amp;quot; xyz00-listen anlegen. Aus admin.hostsharing.net abmelden.&lt;br /&gt;
&lt;br /&gt;
Mit [[Login_mit_SSH|SSH]] an hostsharing.net als xyz00-listen anmelden. Die Redirect-Zeile aus &amp;lt;tt&amp;gt;&amp;lt;nowiki&amp;gt;~/doms/listen.example.com/htdocs-ssl/.htaccess&amp;lt;/nowiki&amp;gt;&amp;lt;/tt&amp;gt; löschen:&lt;br /&gt;
&lt;br /&gt;
 ~$ echo &amp;quot;&amp;quot; &amp;gt; ~/doms/listen.example.com/htdocs-ssl/.htaccess&lt;br /&gt;
&lt;br /&gt;
Die Default-Subdomains www.* löschen:&lt;br /&gt;
&lt;br /&gt;
   ~$ rm -r doms/listen.example.com/subs/www/&lt;br /&gt;
   ~$ rm -r doms/listen.example.com/subs-ssl/www/&lt;br /&gt;
&lt;br /&gt;
=== Sourcen besorgen und entpacken ===&lt;br /&gt;
&lt;br /&gt;
Unter http://www.gnu.org/software/mailman/ die aktuelle Software besorgen. Dort findet sich ein Link zu den 2er-Versionen von Mailman (http://ftp.gnu.org/gnu/mailman/). Die letzte Version downloaden ...&lt;br /&gt;
&lt;br /&gt;
 ~$ wget http://ftp.gnu.org/gnu/mailman/mailman-2.1.29.tgz&lt;br /&gt;
&lt;br /&gt;
... und entpacken:&lt;br /&gt;
&lt;br /&gt;
 ~$ tar -xzvf mailman-2.1.29.tgz&lt;br /&gt;
&lt;br /&gt;
Ab diesem Augenblick gibt es ein Verzeichnis namens &amp;lt;tt&amp;gt;mailman-2.1.29/&amp;lt;/tt&amp;gt;. Darin liegt die nunmehr entpackte &#039;&#039;Quellcode&#039;&#039; der Mailman-Software. Nach dem Kompilieren (folgt unten) wird die fertig kompilierte, gebrauchsfähige Mailman-Software in dem zusätzlich vorhandenen Verzeichnis &amp;lt;tt&amp;gt;mailman/&amp;lt;/tt&amp;gt; liegen. (Dieses Verzeichnis wird beim Konfigurieren der Source als &amp;quot;prefix&amp;quot; angegeben.)&lt;br /&gt;
&lt;br /&gt;
=== var-Verzeichnis für Log-Dateien anlegen ===&lt;br /&gt;
&lt;br /&gt;
Bei der Installation als Paketuser (xyz00-listen):&lt;br /&gt;
 ~$ cd &amp;amp;&amp;amp; mkdir -p mailman/var&lt;br /&gt;
 ~$ chmod 02775 mailman/var&lt;br /&gt;
&lt;br /&gt;
Bei der Installation als Paketadmin (xyz00):&lt;br /&gt;
 ~$ cd &amp;amp;&amp;amp; mkdir var/mailman&lt;br /&gt;
 ~$ chmod 02775 var/mailman&lt;br /&gt;
&lt;br /&gt;
=== Mailman konfigurieren ===&lt;br /&gt;
&lt;br /&gt;
In das Source-Verzeichnis wechseln:&lt;br /&gt;
&lt;br /&gt;
 ~$ cd mailman-2.1.29&lt;br /&gt;
&lt;br /&gt;
Bei der Installation durch den Paketuser (xyz00-listen):&lt;br /&gt;
      ~/mailman-2.1.29$ ./configure --prefix=/home/pacs/xyz00/users/listen/mailman \&lt;br /&gt;
              --with-username=xyz00-listen \&lt;br /&gt;
              --with-groupname=xyz00 \&lt;br /&gt;
              --with-var-prefix=/home/pacs/xyz00/users/listen/mailman/var \&lt;br /&gt;
              --with-cgi-gid=xyz00 \&lt;br /&gt;
              --with-mail-gid=xyz00&lt;br /&gt;
&lt;br /&gt;
Bei der Installation durch den Paketadmin (xyz00):&lt;br /&gt;
      ~/mailman-2.1.29$ ./configure --prefix=/home/pacs/xyz00/mailman \&lt;br /&gt;
              --with-username=xyz00 \&lt;br /&gt;
              --with-groupname=xyz00 \&lt;br /&gt;
              --with-var-prefix=/home/pacs/xyz00/var/mailman \&lt;br /&gt;
              --with-cgi-gid=xyz00 \&lt;br /&gt;
              --with-mail-gid=nogroup&lt;br /&gt;
&lt;br /&gt;
(Die Rückwärtsschrägstriche &amp;quot;\&amp;quot; am Zeilenende bedeuten, dass der Befehl in der nächsten Zeile weitergeht. Alternativ können alle Argumente in eine Zeile getippt werden.)&lt;br /&gt;
&lt;br /&gt;
=== Mailman kompilieren ===&lt;br /&gt;
&lt;br /&gt;
 ~/mailman-2.1.29$ make&lt;br /&gt;
 ~/mailman-2.1.29$ make install&lt;br /&gt;
&lt;br /&gt;
=== Datenrechte prüfen ===&lt;br /&gt;
&lt;br /&gt;
Sicherheitshalber die Dateirechte durch Mailmans mitgeliefertes Tool prüfen und ggf. korrigieren lassen:&lt;br /&gt;
&lt;br /&gt;
 ~/mailman-2.1.29$ cd ..      &lt;br /&gt;
 ~$ mailman/bin/check_perms -f&lt;br /&gt;
&lt;br /&gt;
== Die neue Mailman-Installation konfigurieren ==&lt;br /&gt;
&lt;br /&gt;
=== Konfigurationsdatei &amp;lt;tt&amp;gt;mm_cfg.py&amp;lt;/tt&amp;gt; editieren ===&lt;br /&gt;
&lt;br /&gt;
 ~$ nano mailman/Mailman/mm_cfg.py&lt;br /&gt;
      &lt;br /&gt;
Eine Beispielkonfiguration für listen.example.com könnte so aussehen:&lt;br /&gt;
&lt;br /&gt;
 [...]&lt;br /&gt;
      ##################################################&lt;br /&gt;
      # Put YOUR site-specific settings below this line.&lt;br /&gt;
      # -*- python -*-&lt;br /&gt;
 &lt;br /&gt;
      DEFAULT_HOST_NAME = &#039;listen.example.com&#039;&lt;br /&gt;
      DEFAULT_EMAIL_HOST = &#039;listen.example.com&#039;&lt;br /&gt;
      DEFAULT_URL_HOST = &#039;listen.example.com&#039;&lt;br /&gt;
      add_virtualhost(DEFAULT_URL_HOST, DEFAULT_EMAIL_HOST)&lt;br /&gt;
      add_virtualhost(zweite.listendomain.com, zweite.listendomain.com)&lt;br /&gt;
 &lt;br /&gt;
      DEFAULT_SERVER_LANGUAGE = &#039;de&#039;&lt;br /&gt;
 &lt;br /&gt;
      DEFAULT_URL_PATTERN = &#039;http://%s/&#039;&lt;br /&gt;
  &lt;br /&gt;
      # Es wird der HS Mailversand für Bulkmail verwendet:&lt;br /&gt;
      SMTPHOST = &#039;localhost&#039;&lt;br /&gt;
      SMTPPORT = 4587 &lt;br /&gt;
      SMTP_AUTH = True&lt;br /&gt;
      SMTP_USER = &#039;xyz00-listen&#039;&lt;br /&gt;
      SMTP_PASSWD = &#039;das-passwort-des-o.-g.-users&#039;&lt;br /&gt;
      SMTP_USE_TLS = True&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
In &amp;lt;tt&amp;gt;~/mailman/Mailman/Defaults.py&amp;lt;/tt&amp;gt; sieht man, was in mm_cfg.py alles angepasst werden kann.&lt;br /&gt;
&lt;br /&gt;
==== Mailman gegen Subscription Spam härten ====&lt;br /&gt;
&lt;br /&gt;
Mailman wird gelegentlich von böswilligen Crackern benutzt, die damit sogenannten Subscription Spam erzeugen. Dabei wird eine Mailadresse von Bots an Mailman zur Eintragung übergeben. Diese Mailadresse wird daraufhin brav von Mailman angeschrieben. Wenn das tausende von Mailmans auf der ganzen Welt zugleich machen, wird die Mailadresse zugespammt. Hier ist die Abhilfe:&lt;br /&gt;
&lt;br /&gt;
Die Idee kommt von https://www.ralfj.de/blog/2018/06/02/mailman-subscription-spam.html&lt;br /&gt;
&lt;br /&gt;
Auf der Kommandozeile ein zufälliges Secret-String erstellen:&lt;br /&gt;
 openssl rand -base64 18&lt;br /&gt;
&lt;br /&gt;
Und dann in die Konfigurationsdatei den erzeugten String einfügen:&lt;br /&gt;
&lt;br /&gt;
 SUBSCRIBE_FORM_SECRET = &#039;&amp;lt;Secret-String&amp;gt;&#039;&lt;br /&gt;
&lt;br /&gt;
=== CGI-Programme in die Domain kopieren ===&lt;br /&gt;
&lt;br /&gt;
Bei der Installation als Paketuser (xyz00-listen):&lt;br /&gt;
&lt;br /&gt;
Die fertig kompilierten CGIs von Mailman müssen in das CGI-Verzeichnis der Domain (oder der Domains), auf der das Webfrontend von Mailman laufen soll, kopiert werden. Symbolische Links sind nicht ausreichend.&lt;br /&gt;
&lt;br /&gt;
 ~$ mkdir ~/doms/listen.example.com/cgi-ssl/mailman&lt;br /&gt;
 ~$ cp mailman/cgi-bin/* doms/listen.example.com/cgi-ssl/mailman/&lt;br /&gt;
&lt;br /&gt;
Zusätzlich muss das sticky-Flag von den kopierten Dateien entfernt werden:&lt;br /&gt;
&lt;br /&gt;
 ~$ chmod g-s ~/doms/listen.example.com/cgi/mailman/*&lt;br /&gt;
&lt;br /&gt;
Bei der Installation als Paketadmin (xyz00): &lt;br /&gt;
&lt;br /&gt;
Die CGI-Programme können im Mailman-Verzeichnis bleiben. Im CGI-Verzeichnis von jeder Domain, auf der das Mailman-Webfrontend laufen soll, werden symbolische Links dazu erstellt: &lt;br /&gt;
&lt;br /&gt;
 ~$ cd doms/listen.example.com/cgi-ssl&lt;br /&gt;
 ~/doms/listen.example.com/cgi-ssl$ ln -s ../../../mailman/cgi-bin mailman&lt;br /&gt;
&lt;br /&gt;
===  Mailman-Icons in die Domains kopieren ===&lt;br /&gt;
&lt;br /&gt;
Die Icons können wahlweise verlinkt oder kopiert werden:&lt;br /&gt;
&lt;br /&gt;
 ~$ cd doms/listen.example.com/htdocs-ssl&lt;br /&gt;
 ~/doms/listen.example.com/htdocs-ssl$ ln -s ../../../mailman/icons&lt;br /&gt;
&lt;br /&gt;
oder&lt;br /&gt;
&lt;br /&gt;
 ~$ cp -R mailman/icons doms/listen.example.com/htdocs-ssl/&lt;br /&gt;
&lt;br /&gt;
=== Die Datei .htaccess bearbeiten ===&lt;br /&gt;
&lt;br /&gt;
Bei einer dedizierten Mailman-Domain sollte man dafür sorgen, dass Mailman nicht nur unter &amp;lt;tt&amp;gt;&amp;lt;nowiki&amp;gt;https://listen.example.com/cgi-bin/mailman&amp;lt;/nowiki&amp;gt;&amp;lt;/tt&amp;gt;, sondern auch unter &amp;lt;tt&amp;gt;&amp;lt;nowiki&amp;gt;https://listen.example.com/&amp;lt;/nowiki&amp;gt;&amp;lt;/tt&amp;gt;  erreichbar ist.&lt;br /&gt;
&lt;br /&gt;
Dazu werden in &amp;lt;tt&amp;gt;&amp;lt;nowiki&amp;gt;~/doms/listen.example.com/htdocs-ssl/.htaccess&amp;lt;/nowiki&amp;gt;&amp;lt;/tt&amp;gt; folgende Rewrite-Anweisungen eintragen.&lt;br /&gt;
&lt;br /&gt;
 RewriteEngine On&lt;br /&gt;
 RewriteCond	%{REQUEST_URI}		!^/icons/&lt;br /&gt;
 RewriteRule	^(.*)$			/cgi-bin/mailman/$1&lt;br /&gt;
 RewriteRule	^/cgi-bin/mailman/$	/cgi-bin/mailman/listinfo&lt;br /&gt;
&lt;br /&gt;
Beachte dabei die zweite Zeile: Anfragen für Icons sollen &#039;&#039;nicht&#039;&#039; umgeschrieben werden.&lt;br /&gt;
&lt;br /&gt;
Wenn Mailman z.B. auf einer als Unterverzeichnis angelegten Subdomain läuft und unter &amp;lt;tt&amp;gt;&amp;lt;nowiki&amp;gt;https://www.example.com/mailman&amp;lt;/nowiki&amp;gt;&amp;lt;/tt&amp;gt; statt &amp;lt;tt&amp;gt;&amp;lt;nowiki&amp;gt;https://www.example.com/cgi-bin/mailman&amp;lt;/nowiki&amp;gt;&amp;lt;/tt&amp;gt; erreichbar sein soll, hilft folgendes in der &amp;lt;tt&amp;gt;&amp;lt;nowiki&amp;gt;~/doms/example.com/subs-ssl/www/.htaccess&amp;lt;/nowiki&amp;gt;&amp;lt;/tt&amp;gt;:&lt;br /&gt;
&lt;br /&gt;
 RewriteEngine On&lt;br /&gt;
 RewriteCond	%{REQUEST_URI}		!^/icons/&lt;br /&gt;
 RewriteRule    ^mailman/(.*)$          /cgi-bin/mailman/$1&lt;br /&gt;
 RewriteRule    ^/cgi-bin/mailman/$	/cgi-bin/mailman/listinfo&lt;br /&gt;
&lt;br /&gt;
(In diesem Fall kann die Zeile &amp;lt;tt&amp;gt;DEFAULT_URL_PATTERN...&amp;lt;/tt&amp;gt; in der &amp;lt;tt&amp;gt;mm_cfg.py&amp;lt;/tt&amp;gt; auskommentiert werden.)&lt;br /&gt;
&lt;br /&gt;
=== Hauptpasswort setzen ===&lt;br /&gt;
&lt;br /&gt;
Das &amp;quot;site password&amp;quot; ist in Mailman eine Art Generalschlüssel: es wird neben dem jeweiligen Admin- oder Moderator-Passwort überall in der Weboberfläche für sämtliche Mailing-Listen akzeptiert. Also vorsichtig wählen! Das &amp;quot;site password&amp;quot; einrichten mit dem Befehl: &lt;br /&gt;
&lt;br /&gt;
 ~$ mailman/bin/mmsitepass&lt;br /&gt;
&lt;br /&gt;
=== Cronjobs einrichten ===&lt;br /&gt;
&lt;br /&gt;
In die [[Cron |Crontab]] werden Befehle eingetragen, um die Mail-Warteschlange abzuarbeiten, Logs zu löschen, usw.:&lt;br /&gt;
&lt;br /&gt;
 # Warteschlange jede Minute bearbeiten:&lt;br /&gt;
 * * * * *	~/mailman/bin/qrunner -o -r All&lt;br /&gt;
 # Verarbeitungslogs in der 47ten Minute jeder Stunde löschen:&lt;br /&gt;
 47 * * * *	rm -f ~/var/mailman/logs/qrunner&lt;br /&gt;
&lt;br /&gt;
Damit übernimmt cron die Funktion des qrunner-Dämons, der normalerweise auf einem Mailman-Server laufen sollte.&lt;br /&gt;
&lt;br /&gt;
Das Logfile wird stündlich gelöscht, da es sonst sehr schnell sehr groß wird. Falls Mailman von einem Paketuser (bspw. &amp;quot;xyz00-listen&amp;quot;) installiert wurde, sollte die letzte Zeile im Beispiel oben so lauten:&lt;br /&gt;
&lt;br /&gt;
 47 * * * * rm -f ~/mailman/var/logs/qrunner&lt;br /&gt;
&lt;br /&gt;
... entsprechend dem beim Konfigurieren angegebenen &amp;lt;tt&amp;gt;var&amp;lt;/tt&amp;gt;-Verzeichnis, siehe oben.&lt;br /&gt;
&lt;br /&gt;
Zudem müssen noch die von Mailman ohnehin vorgesehenen cron-Aufträge aus &amp;lt;tt&amp;gt;~/mailman/cron/crontab.in&amp;lt;/tt&amp;gt; dem crontab des Users angehängt werden:&lt;br /&gt;
&lt;br /&gt;
 crontab -l &amp;gt; mycronjobs.tmp&lt;br /&gt;
 cat ~/mailman/cron/crontab.in &amp;gt;&amp;gt; mycronjobs.tmp&lt;br /&gt;
 crontab mycronjobs.tmp&lt;br /&gt;
&lt;br /&gt;
== Mailinglisten einrichten ==&lt;br /&gt;
&lt;br /&gt;
Jetzt läuft die Software; nun können die eigentlichen Verteiler angelegt werden. Als erster &#039;&#039;&#039;muß&#039;&#039;&#039; ein Hauptverteiler (&amp;quot;site list&amp;quot;) eingerichtet werden. Dieser Verteiler dient u.a. als Absender der Paßwort-Erinnerungen an die Abonnenten aller Mailinglisten. Er hat standardmäßig den Namen &amp;quot;mailman&amp;quot;. Falls ein anderer Name verwendet werden soll, muß dieser mit der Anweisung &lt;br /&gt;
&lt;br /&gt;
 MAILMAN_SITE_LIST = &#039;sitelistname&#039;&lt;br /&gt;
&lt;br /&gt;
in der Konfigurationsdatei &amp;lt;tt&amp;gt;mailman/Mailman/mm_cfg.py&amp;lt;/tt&amp;gt; eingetragen werden.&lt;br /&gt;
&lt;br /&gt;
=== Den Hauptverteiler &amp;quot;mailman&amp;quot; anlegen ===&lt;br /&gt;
&lt;br /&gt;
Die &amp;quot;site list&amp;quot; mit dem Namen &amp;quot;mailman&amp;quot; ist die Mailingliste der lokalen Mailman-Administratoren. Sie wird zur einwandfreien Funktion von Mailman benötigt.&lt;br /&gt;
&lt;br /&gt;
Mit dem Mailman-Befehl newlist den Verteiler anlegen:&lt;br /&gt;
&lt;br /&gt;
 ~$ mailman/bin/newlist mailman&lt;br /&gt;
 Enter the email of the person running the list: admin@xyz00.hostsharing.net&lt;br /&gt;
 Initial mailman password:&lt;br /&gt;
&lt;br /&gt;
(Der Befehl newlist kann – alternativ zur Weboberfläche – später benutzt werden, um gewöhnliche Mailinglisten anzulegen.)&lt;br /&gt;
&lt;br /&gt;
Nur dieses eine Mal für die &amp;quot;site list&amp;quot; müssen wir die Konfigurationsvorgaben laden. (Gewöhnliche Mailinglisten werden später über die Weboberfläche konfiguriert.)&lt;br /&gt;
&lt;br /&gt;
Falls mailman vom Paketuser (bspw. &amp;quot;xyz00-listen&amp;quot;) installiert wurde:&lt;br /&gt;
&lt;br /&gt;
 ~$ mailman/bin/config_list -i ~/mailman/var/data/sitelist.cfg mailman&lt;br /&gt;
&lt;br /&gt;
Falls mailman vom Paketadmin (&amp;quot;xyz00&amp;quot;) installiert wurde:&lt;br /&gt;
&lt;br /&gt;
 ~$ mailman/bin/config_list -i ~/var/mailman/data/sitelist.cfg mailman&lt;br /&gt;
&lt;br /&gt;
Diese Konfigurationsdatei soll &#039;&#039;&#039;nicht&#039;&#039;&#039; auf gewöhnliche Mailinglisten anwendet werden.&lt;br /&gt;
&lt;br /&gt;
=== E-Mail Adressen bei Mailman einrichten ===&lt;br /&gt;
&lt;br /&gt;
Sobald ein neuer Verteiler angelegt worden ist, sendet Mailman eine E-Mail an den dabei eingetragenen Listenadministrator. Diese E-Mail enthält die Anweisung, E-Mail-Aliases für den neuen Verteiler und für die verschiedenen Mailman-Funktionen anzulegen. Bei Hostsharing wird die Zustellung von E-Mails an Mailman anders geregelt: alle E-Mails an Mailman werden an erweiterte &#039;&#039;E-Mail-Adressen&#039;&#039; des Mailman-Users xyz00-listen geschickt. Diese Adressen haben die form &amp;lt;tt&amp;gt;xyz00-listen&#039;&#039;&#039;+&#039;&#039;&#039;&amp;lt;liste&amp;gt;[_funktion]&amp;lt;/tt&amp;gt;. E-Mails an diese Adressen werden dann durch Pipe-Anweisungen in &#039;&#039;.forward-Dateien&#039;&#039; im Home-Verzeichnis des Mailman-Users mit den entsprechenden Argumenten an Mailman übergeben. &lt;br /&gt;
&lt;br /&gt;
Falls Mailman von einem Paketuser (bspw. &amp;quot;xyz00-listen&amp;quot;) installiert wurde, werden  &#039;&#039;E-Mail-Adressen&#039;&#039; durch [https://doc.hostsharing.net/users/administration/hsadmin/index.html hsadmin (bzw. das Befehlszeilentool hsscript)] eingerichtet; die &#039;&#039;.forward-Dateien&#039;&#039; werden durch [[Login_mit_SSH|Shell-Befehle]] angelegt.&lt;br /&gt;
&lt;br /&gt;
Das folgende Beispiel zeigt die Befehle, mit denen in einer interaktiven hsscript-Sitzung die E-Mail-Adressen für die Hauptliste &amp;quot;mailman&amp;quot; eingerichtet werden. (Für spätere Mailinglisten wird in den Argumenten &amp;quot;mailman&amp;quot; durch den Namen der Mailingliste ersetzt.)&lt;br /&gt;
&lt;br /&gt;
   hsscript -u xyz00 -i&lt;br /&gt;
   [hsscript verlangt die Eingabe des Passworts vom Paketadmin xyz00; dann können diese Befehle eingegeben werden:]&lt;br /&gt;
   emailaddress.add ({set:{domain:&#039;listen.example.com&#039;,localpart:&#039;mailman&#039;,target:&#039;xyz00-listen+mailman&#039;}})&lt;br /&gt;
   emailaddress.add ({set:{domain:&#039;listen.example.com&#039;,localpart:&#039;mailman-admin&#039;,target:&#039;xyz00-listen+mailman-admin&#039;}})&lt;br /&gt;
   emailaddress.add ({set:{domain:&#039;listen.example.com&#039;,localpart:&#039;mailman-bounces&#039;,target:&#039;xyz00-listen+mailman-bounces&#039;}})&lt;br /&gt;
   emailaddress.add ({set:{domain:&#039;listen.example.com&#039;,localpart:&#039;mailman-confirm&#039;,target:&#039;xyz00-listen+mailman-confirm&#039;}})&lt;br /&gt;
   emailaddress.add ({set:{domain:&#039;listen.example.com&#039;,localpart:&#039;mailman-join&#039;,target:&#039;xyz00-listen+mailman-join&#039;}})&lt;br /&gt;
   emailaddress.add ({set:{domain:&#039;listen.example.com&#039;,localpart:&#039;mailman-leave&#039;,target:&#039;xyz00-listen+mailman-leave&#039;}})&lt;br /&gt;
   emailaddress.add ({set:{domain:&#039;listen.example.com&#039;,localpart:&#039;mailman-owner&#039;,target:&#039;xyz00-listen+mailman-owner&#039;}})&lt;br /&gt;
   emailaddress.add ({set:{domain:&#039;listen.example.com&#039;,localpart:&#039;mailman-request&#039;,target:&#039;xyz00-listen+mailman-request&#039;}})&lt;br /&gt;
   emailaddress.add ({set:{domain:&#039;listen.example.com&#039;,localpart:&#039;mailman-subscribe&#039;,target:&#039;xyz00-listen+mailman-subscribe&#039;}})&lt;br /&gt;
   emailaddress.add ({set:{domain:&#039;listen.example.com&#039;,localpart:&#039;mailman-unsubscribe&#039;,target:&#039;xyz00-listen+mailman-unsubscribe&#039;}})&lt;br /&gt;
&lt;br /&gt;
Die korrekte Einrichtung der E-Mail-Adressen kann in der Web-Oberfläche von hsadmin kontrolliert werden.&lt;br /&gt;
&lt;br /&gt;
Für jede der soeben eingerichteten Adressen wird nun eine &amp;lt;tt&amp;gt;.forward&amp;lt;/tt&amp;gt;-Datei im Homeverzeichnis des Users xyz00-listen angelegt. Die Dateinamen bestehen aus der Zeichenfolge &amp;lt;tt&amp;gt;.forward+&amp;lt;/tt&amp;gt; gefolgt vom Namen der ausführen soll. Der Inhalt der jeweiligen &amp;lt;tt&amp;gt;.forward&amp;lt;/tt&amp;gt;-Datei legt die Weiterleitung der Mail durch einen Pipe an Mailman fest, mit dem jeweiligen Befehl als Argument:&lt;br /&gt;
&lt;br /&gt;
   &amp;quot;|/home/pacs/xyz00/users/listen/mailman/mail/mailman [Befehl] [Listenname]&amp;quot;&lt;br /&gt;
&lt;br /&gt;
Zum Beispiel wird die &amp;lt;tt&amp;gt;.forward&amp;lt;/tt&amp;gt;-Datei .forward+mailman-subscribe verwendet, wenn eine E-Mail an die Adresse &amp;lt;tt&amp;gt;mailman-subscribe@listen.example.com&amp;lt;/tt&amp;gt; eingeht. Aufgrund der oben eingerichteten E-Mail-Adresse mit dem Ziel &amp;lt;tt&amp;gt;xyz00-listen+mailman-subscribe&amp;lt;/tt&amp;gt; wertet der Mail-Transfer-Agent die &amp;lt;tt&amp;gt;.forward&amp;lt;/tt&amp;gt;-Datei &amp;lt;tt&amp;gt;.forward+mailman-subscribe&amp;lt;/tt&amp;gt; im Home-Verzeichnis des Users xyz00-listen aus, und entsprechend ihrem Inhalt wird die Mail an die Mailman-Software mit den Argumenten &amp;quot;subscribe mailman&amp;quot; übergeben.&lt;br /&gt;
&lt;br /&gt;
Das folgende Beispiel zeigt die Befehle, mit denen an der Befehlszeilenaufforderung der Shell die &amp;lt;tt&amp;gt;.forward&amp;lt;/tt&amp;gt;-Dateien für die Hauptliste &amp;quot;mailman&amp;quot; eingerichtet werden. (Für spätere Mailinglisten wird in den Argumenten und in den Namen der &amp;lt;tt&amp;gt;.forward&amp;lt;/tt&amp;gt;-Dateien &amp;quot;mailman&amp;quot; durch den Namen der Mailingliste ersetzt, jedoch &#039;&#039;&#039;nicht&#039;&#039;&#039; in der Pfadangabe zum Mailman-Programm selbst; diese ändert sich ja nicht.)&lt;br /&gt;
&lt;br /&gt;
 echo &#039;admin@xyz00.hostsharing.net&#039; &amp;gt; .forward # Weiterleitung von cron Fehlern etc an Paketadmin.&lt;br /&gt;
 echo &#039;&amp;quot;|/home/pacs/xyz00/users/listen/mailman/mail/mailman post mailman&amp;quot;&#039; &amp;gt; .forward+mailman&lt;br /&gt;
 echo &#039;&amp;quot;|/home/pacs/xyz00/users/listen/mailman/mail/mailman admin mailman&amp;quot;&#039; &amp;gt; .forward+mailman-admin&lt;br /&gt;
 echo &#039;&amp;quot;|/home/pacs/xyz00/users/listen/mailman/mail/mailman bounces mailman&amp;quot;&#039; &amp;gt; .forward+mailman-bounces&lt;br /&gt;
 echo &#039;&amp;quot;|/home/pacs/xyz00/users/listen/mailman/mail/mailman confirm mailman&amp;quot;&#039; &amp;gt; .forward+mailman-confirm&lt;br /&gt;
 echo &#039;&amp;quot;|/home/pacs/xyz00/users/listen/mailman/mail/mailman join mailman&amp;quot;&#039; &amp;gt; .forward+mailman-join&lt;br /&gt;
 echo &#039;&amp;quot;|/home/pacs/xyz00/users/listen/mailman/mail/mailman leave mailman&amp;quot;&#039; &amp;gt; .forward+mailman-leave&lt;br /&gt;
 echo &#039;&amp;quot;|/home/pacs/xyz00/users/listen/mailman/mail/mailman owner mailman&amp;quot;&#039; &amp;gt; .forward+mailman-owner&lt;br /&gt;
 echo &#039;&amp;quot;|/home/pacs/xyz00/users/listen/mailman/mail/mailman request mailman&amp;quot;&#039; &amp;gt; .forward+mailman-request&lt;br /&gt;
 echo &#039;&amp;quot;|/home/pacs/xyz00/users/listen/mailman/mail/mailman subscribe mailman&amp;quot;&#039; &amp;gt; .forward+mailman-subscribe&lt;br /&gt;
 echo &#039;&amp;quot;|/home/pacs/xyz00/users/listen/mailman/mail/mailman unsubscribe mailman&amp;quot;&#039; &amp;gt; .forward+mailman-unsubscribe&lt;br /&gt;
&lt;br /&gt;
Die vielen Befehle können von dieser Anleitung kopiert und nach Anpassung auf den tatsächlichen Unsernamen in die SSH-Sitzung kopiert werden. Noch leichter ist es, mit einem Editor einen Shell-Skript namens &amp;lt;tt&amp;gt;~/bin/mailmanaddresses&amp;lt;/tt&amp;gt; mit folgendem Inhalt zu erstellen:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#!/bin/bash&lt;br /&gt;
# Add e-mail addresses and dot-forward files for mailman lists.&lt;br /&gt;
#&lt;br /&gt;
&lt;br /&gt;
# All the sanity checks.&lt;br /&gt;
&lt;br /&gt;
if [ &amp;quot;$3&amp;quot; = &amp;quot;&amp;quot; -o &amp;quot;$2&amp;quot; = &amp;quot;&amp;quot; -o &amp;quot;$1&amp;quot; = &amp;quot;&amp;quot; ] ; then&lt;br /&gt;
    echo &amp;quot;Syntax: $0 listname domainname listowner\n&amp;quot; &lt;br /&gt;
    exit&lt;br /&gt;
fi&lt;br /&gt;
&lt;br /&gt;
if [ &amp;quot;$4&amp;quot; != &amp;quot;&amp;quot; ] ; then&lt;br /&gt;
    echo &amp;quot;Syntax: $0 listname domainname listowner\n&amp;quot; &lt;br /&gt;
    exit&lt;br /&gt;
fi&lt;br /&gt;
&lt;br /&gt;
if [ &amp;quot;`pwd`&amp;quot; != &amp;quot;`echo ~`&amp;quot; ] ; then&lt;br /&gt;
    echo &amp;quot;Run this script from your home directory.\n&amp;quot; &lt;br /&gt;
    exit&lt;br /&gt;
fi&lt;br /&gt;
&lt;br /&gt;
if [ ! -d &amp;quot;../${3:6}&amp;quot; ] ; then&lt;br /&gt;
	echo &amp;quot;There&#039;s no user named $3.&amp;quot;&lt;br /&gt;
	exit&lt;br /&gt;
else&lt;br /&gt;
	echo &amp;quot;You may be asked for a password for $3.&amp;quot;&lt;br /&gt;
fi&lt;br /&gt;
&lt;br /&gt;
if [ ! -d &amp;quot;./mailman/Mailman&amp;quot; ] ; then&lt;br /&gt;
	echo &amp;quot;Are you sure you have a Mailman installation?&amp;quot;&lt;br /&gt;
	exit&lt;br /&gt;
fi&lt;br /&gt;
&lt;br /&gt;
# hsscript fails with a &amp;quot;no result&amp;quot; and 255 if $2 (domain name) is not valid.&lt;br /&gt;
# It also fails if a requested address already exists.&lt;br /&gt;
# scriptexpr contains the expanded variables. Avoid spaces, because it&#039;s unquoted in the hsscript call.&lt;br /&gt;
&lt;br /&gt;
# Add the base list address and its forward file:&lt;br /&gt;
scriptexpr=&amp;quot;emailaddress.add({set:{localpart:\&amp;quot;$1\&amp;quot;,target:\&amp;quot;xyz00-lists+$1\&amp;quot;,domain:\&amp;quot;$2\&amp;quot;}})&amp;quot;&lt;br /&gt;
hsscript -r$3 -u$3 -e $scriptexpr&lt;br /&gt;
if [ &amp;quot;$?&amp;quot; != &amp;quot;0&amp;quot; ] ; then echo &amp;quot;hsscript failed to add address with localpart $1&amp;quot; ; exit ; fi&lt;br /&gt;
echo &amp;quot;\&amp;quot;|/home/pacs/xyz00/users/lists/mailman/mail/mailman post $1\&amp;quot;&amp;quot; &amp;gt; .forward+$1&lt;br /&gt;
if [ &amp;quot;$?&amp;quot; != &amp;quot;0&amp;quot; ] ; then echo &amp;quot;failed to create a forward file for posts&amp;quot; ; exit ; fi&lt;br /&gt;
&lt;br /&gt;
# Now do the same for all the suffixes&lt;br /&gt;
for subpart in admin bounces confirm join leave owner request subscribe unsubscribe&lt;br /&gt;
do&lt;br /&gt;
    scriptexpr=&amp;quot;emailaddress.add({set:{localpart:\&amp;quot;$1-${subpart}\&amp;quot;,target:\&amp;quot;xyz00-lists+$1-${subpart}\&amp;quot;,domain:\&amp;quot;$2\&amp;quot;}})&amp;quot;&lt;br /&gt;
    hsscript -r$3 -u$3 -e $scriptexpr&lt;br /&gt;
    if [ &amp;quot;$?&amp;quot; != &amp;quot;0&amp;quot; ] ; then echo &amp;quot;hsscript failed on subpart ${subpart}&amp;quot; ; exit ; fi&lt;br /&gt;
    echo &amp;quot;\&amp;quot;|/home/pacs/xyz00/users/lists/mailman/mail/mailman $subpart $1\&amp;quot;&amp;quot; &amp;gt; .forward+$1-$subpart&lt;br /&gt;
    if [ &amp;quot;$?&amp;quot; != &amp;quot;0&amp;quot; ] ; then echo &amp;quot;failed to create a forward file for ${subpart}&amp;quot; ; exit ; fi&lt;br /&gt;
done&lt;br /&gt;
&lt;br /&gt;
echo &amp;quot;$0 ran to the end and finished with $?&amp;quot;&lt;br /&gt;
exit&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Der Skript muß als ausführbar gekennzeichnet werden:&lt;br /&gt;
&lt;br /&gt;
  ~$ chmod u+x bin/mailmanaddresses&lt;br /&gt;
&lt;br /&gt;
Die Erstellung eines Skripts um die Adressen wieder zu entfernen wird dem Leser überlassen.&lt;br /&gt;
(Der hsscript-Befehl lautet &amp;lt;tt&amp;gt;hsscript -r&amp;lt;listenowner&amp;gt; -u&amp;lt;listenowner&amp;gt; -e &#039;emailaddress.remove({where:{localpart:&amp;quot;&amp;lt;listenname[-suffix]&amp;gt;&amp;quot;,target:&amp;quot;&amp;lt;mailman-owner+listenname-suffix&amp;quot;,domain:&amp;quot;dommainname&amp;quot;}})&#039;&amp;lt;/tt&amp;gt;.)&lt;br /&gt;
&lt;br /&gt;
=== Administration ===&lt;br /&gt;
&lt;br /&gt;
Als erstes sollte man als Administrator der neuen Mailman-Installation die Liste &amp;quot;mailman&amp;quot; selbst abonnieren. Die Liste &amp;quot;mailman&amp;quot; kann aber unter &amp;lt;tt&amp;gt;&amp;lt;nowiki&amp;gt;https://listen.example.com/mailman/admin/mailman&amp;lt;/nowiki&amp;gt;&amp;lt;/tt&amp;gt; verwaltet werden.&lt;br /&gt;
&lt;br /&gt;
Die Hauptseite der Mailman-Web-Verwaltung ist in unserem Beispiel (mit den oben angegebenen Rewrite-Anweisungen in der Datei &amp;lt;tt&amp;gt;.htaccess&amp;lt;/tt&amp;gt;) &amp;lt;tt&amp;gt;&amp;lt;nowiki&amp;gt;https://listen.example.com/mailman/admin/&amp;lt;/nowiki&amp;gt;&amp;lt;/tt&amp;gt;. Diese Seite enthält Links zu den bisher eingerichteten Mailinglisten (außer &amp;quot;mailman&amp;quot;) und einen Link, um neue Mailinglisten anzulegen (&amp;lt;tt&amp;gt;&amp;lt;nowiki&amp;gt;https://listen.example.com/mailman/create&amp;lt;/nowiki&amp;gt;&amp;lt;/tt&amp;gt;). Das Anlegen einer neuen Mailingliste geschieht entweder über diesen Link oder (wie oben) in der Shell mit dem Befehl:&lt;br /&gt;
&lt;br /&gt;
 ~$ mailman/bin/newlist &amp;lt;Listenname&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In beiden Fällen müssen zusätzlich die E-Mail-Adressen und die &amp;lt;tt&amp;gt;.forward&amp;lt;/tt&amp;gt;-Dateien wie bei dem Einrichten der Liste &amp;quot;mailman&amp;quot; nach Verfahren im obigen Abschnitt angelegt werden.&lt;br /&gt;
&lt;br /&gt;
Für die Verwaltung der Mailinglisten im Alltag, d.h. den Umgang mit Bounces, Spam, Abonnenten usw., siehe u.a. die [https://wiki.list.org/ Mailman-Wiki].&lt;br /&gt;
&lt;br /&gt;
== Feintuning == &lt;br /&gt;
&lt;br /&gt;
Wer will, kann auch noch etwas Platz sparen. Die normale Mailmaninstallation schlägt mit über 20 MB zu Buche...&lt;br /&gt;
&lt;br /&gt;
Mit den folgenden Tips kann man das auf ca. 6 MB reduzieren :)&lt;br /&gt;
&lt;br /&gt;
Es kann natürlich sein, dass ich zuviel lösche, aber bei mir funktioniert&#039;s. Wenn ihr also sicher(er) sein wollt, dass euch der Mailman nicht um die Ohren fliegt, macht das nicht!&lt;br /&gt;
&lt;br /&gt;
*  ~/mailman/cgi-bin und ~/mailman/icons können gelöscht werden, falls sie an andere Stelle kopiert worden sind.&lt;br /&gt;
* Die nicht benötigten Sprachen in ~/mailman/messages löschen.&lt;br /&gt;
* Die nicht benötigten Sprachen in ~/mailman/templates löschen (bis auf englisch).&lt;br /&gt;
* ~/mailman/tests kann, soweit ich das sehe, komplett gelöscht werden.&lt;br /&gt;
* Falls man koreanisch und japanisch nicht braucht, kann man folgendes machen:&lt;br /&gt;
* in ~/mailman/bin/paths.py, ~/mailman/cron/paths.py und ~/mailman/scripts/paths.py die Zeilen:&lt;br /&gt;
&lt;br /&gt;
 # In a normal interactive Python environment, the japanese.pth and korean.pth&lt;br /&gt;
 # files would be imported automatically.  But because we inhibit the importing&lt;br /&gt;
 # of the site module, we need to be explicit about importing these codecs.&lt;br /&gt;
 if not jaok:&lt;br /&gt;
     import japanese&lt;br /&gt;
 # As of KoreanCodecs 2.0.5, you had to do the second import to get the Korean&lt;br /&gt;
 # codecs installed, however leave the first import in there in case an upgrade&lt;br /&gt;
 # changes this.&lt;br /&gt;
 if not kook:&lt;br /&gt;
     import korean&lt;br /&gt;
     import korean.aliases&lt;br /&gt;
&lt;br /&gt;
auskommentieren.&lt;br /&gt;
&lt;br /&gt;
Dann kann man ~/mailman/pythonlib/japanese, ~/mailman/pythonlib/korean, ~/mailman/pythonlib/korean.pth sowie ~/mailman/pythonlib/lib löschen.&lt;br /&gt;
   &lt;br /&gt;
Man kann auch noch die Debug-Informationen aus den binaries strippen:&lt;br /&gt;
&lt;br /&gt;
 strip ~/mailman/mail/mailman&lt;br /&gt;
 strip ~/mailman/cgi-bin/*&lt;br /&gt;
&lt;br /&gt;
Falls die CGIs nicht gesymlinkt wurden:&lt;br /&gt;
&lt;br /&gt;
 strip ~/doms/listen.example.com/cgi/mailman/*&lt;br /&gt;
&lt;br /&gt;
== Multidomainfähigkeit ==&lt;br /&gt;
&lt;br /&gt;
Seit Mailman 2.x kann eine Mailman-Installation unter gewissen Einschränkungen für mehrere Domains verwendet werden. Hier soll kurz gezeigt werden, was geht und wie es geht.&lt;br /&gt;
&lt;br /&gt;
=== Anleitung ===&lt;br /&gt;
&lt;br /&gt;
Logischerweise muss das Webfrontend (die CGIs) auf allen Domains installiert werden.&lt;br /&gt;
&lt;br /&gt;
Wenn man nun Mailinglisten mit newlist neu anlegt, muss man den Hostnamen für das Webfontend mit angeben, und zwar so:&lt;br /&gt;
&lt;br /&gt;
 ~$ mailman/bin/newlist listenname@listen.example.com&lt;br /&gt;
&lt;br /&gt;
Es ist ggf. wichtig, dass in der mm_cfg.py eine entsprechende add_virtualhost-Direktive für www.example.com steht, die der Frontend-URL einen Host-Part für die Mailadressen zuordnet. Ist eine solche Direktive nicht vorhanden, so wird listen.example.com sowohl als URL für das Webfrontend wie auch als Hostpart für E-Mailadressen verwendet. (Was für separate aufgeschaltete Domains wie z.B. listen.example.com gerade zutrifft.)&lt;br /&gt;
&lt;br /&gt;
Liegt das Frondend nicht auf der Maildomain ist es wichtig, dass ihr Mailman sagt, für welches die zugehörige Maildomain ist. Dies tut ihr in der Datei ~/mailman/Mailman/mm_cfg.py:&lt;br /&gt;
&lt;br /&gt;
Also z.B.&lt;br /&gt;
 DEFAULT_URL_HOST = &#039;www.example.com&#039;&lt;br /&gt;
 DEFAULT_EMAIL_HOST = &#039;listen.example.com&#039;&lt;br /&gt;
 add_virtualhost(DEFAULT_URL_HOST,DEFAULT_EMAIL_HOST)&lt;br /&gt;
&lt;br /&gt;
und&lt;br /&gt;
 add_virtualhost(&#039;www.zoopnet.de&#039;, &#039;lists.zoopnet.de&#039;)&lt;br /&gt;
&lt;br /&gt;
Das bedeutet, dass Mailman per default davon ausgeht, dass alle Listen für die Domain example.com sind.&lt;br /&gt;
Alle weiteren add_virtualhost-Direktiven ordnen einem Hostnamen für das Webfrontend (z.B. www.zoopnet.de) einen Hostpart für die Adresse der Mailinglisten (z.B. lists.zoopnet.de) zu.&lt;br /&gt;
&lt;br /&gt;
Tip von Raimund Specht: Lässt man den zweiten Parameter weg, also schreibt z.B. add_virtualhost(&#039;www.example.org&#039;), dann benutzt Mailman als Hostpart alles was nach dem ersten Punkt steht, hier also example.org als Maildomain.&lt;br /&gt;
 &lt;br /&gt;
&lt;br /&gt;
Prinzipiell war&#039;s das. Man muss die Listeneinträge natürlich immer in die richtige virtusertable eintragen, und für gleichnamige Mailinglisten auf verschiedenen Domains (mailman@*) verschidene +Ergänzungen bzw. aliase verwenden. :)&lt;br /&gt;
&lt;br /&gt;
=== Probleme ===&lt;br /&gt;
&lt;br /&gt;
Verschiedene Listen mit gleichem Namen (also z.B. liste@example1.com und liste@example2.com) sind mit Mailman 2.1 leider nicht möglich.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Tips und Tricks ==&lt;br /&gt;
&lt;br /&gt;
=== URL Änderungen ===&lt;br /&gt;
Nach URL Änderungen stimmen Links im Web-Interface nicht mehr und Listen werden nicht mehr angezeigt.&lt;br /&gt;
Es sind dann, zusätzlich zur Anpassung der mm_cfg.py, schon bestehende Listen und Archive mit folgendem Befehl zu aktualisieren:&lt;br /&gt;
 ~/mailman/bin/withlist -l -r fix_url &amp;lt;Listen_Name&amp;gt; -v -u &amp;lt;Neue_Url&amp;gt;&lt;br /&gt;
&amp;lt;Listen_Name&amp;gt; steht für die Mailingliste, die bearbeitet werden soll. &amp;lt;Neue_Url&amp;gt; für die neue URL/Webadresse des Webinterfaces.&lt;br /&gt;
&lt;br /&gt;
=== Weitere Cron-Jobs zur Mailinglisten Verwaltung ===&lt;br /&gt;
&lt;br /&gt;
Folgende Cronjobs helfen bei der Verwaltung und sind User freundlich:&lt;br /&gt;
&lt;br /&gt;
&amp;lt; In Arbeit &amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Referenzen ==&lt;br /&gt;
&lt;br /&gt;
Lösung zur installation als Domainadmin (xyz00-listen) statt Paketadmin (xyz00): https://lists.hostsharing.net/archiv/support/2009-June/019414.html&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Ältere Anleitung für Installation als Domain-Admin (xyz00-listen): &amp;lt;http://lists.hostsharing.net/archiv/support/2005-January/012426.html&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;quot;Kleine Tools&amp;quot; auf http://hs.andreasloesch.de/, wobei das &#039;pac-mm-install&#039; wahrscheinlich nicht aktuell (genug) ist&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
[[Kategorie:HSDoku]]&lt;br /&gt;
[[Kategorie:Installationsanleitungen]]&lt;br /&gt;
[[Kategorie:Software]]&lt;br /&gt;
[[Kategorie:Mailinglisten]]&lt;br /&gt;
[[Kategorie:E-Mail]]&lt;br /&gt;
[[Kategorie:Python]]&lt;/div&gt;</summary>
		<author><name>Apc00-tony</name></author>
	</entry>
	<entry>
		<id>https://wiki.hostsharing.net/index.php?title=Mlmmj&amp;diff=6389</id>
		<title>Mlmmj</title>
		<link rel="alternate" type="text/html" href="https://wiki.hostsharing.net/index.php?title=Mlmmj&amp;diff=6389"/>
		<updated>2024-01-31T16:32:33Z</updated>

		<summary type="html">&lt;p&gt;Apc00-tony: Hauptteil auf Lesbarkeit überarbeitet&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Mailing List Management Made Joyful ==&lt;br /&gt;
&lt;br /&gt;
[http://www.mlmmj.org/ mlmmj] ist ein Programm, mit dem in einem Hostsharing Paket E-Mail-Verteiler realisiert werden kann.&lt;br /&gt;
&lt;br /&gt;
Wer noch nicht weiß, was ein E-Mail-Verteiler machen soll oder wie, lese veilleicht auch den Wikipedia-Artikel:&lt;br /&gt;
[http://de.wikipedia.org/wiki/Mailingliste Mailingliste]&lt;br /&gt;
&lt;br /&gt;
Eine leistungsfähigere Alternative zu mlmmj könnte [[Mailman_3_installieren|Mailman 3]] sein.&lt;br /&gt;
&lt;br /&gt;
Diese Anleitung beschreibt die Einrichtung einer Mailingliste für eine Domain in einem Hostsharing-Webspace.&lt;br /&gt;
&lt;br /&gt;
== mlmmj ==&lt;br /&gt;
&lt;br /&gt;
Das Debian Paket [http://packages.debian.org/search?keywords=mlmmj mlmmj] ist auf den Shared-Hosting-Servern bereits installiert.&lt;br /&gt;
&lt;br /&gt;
=== Voraussetzungen  ===&lt;br /&gt;
&lt;br /&gt;
Für den Betrieb der Mailingliste empfiehlt sich das Anlegen eines eigenen Users für diesen Zweck mit hsadmin.&lt;br /&gt;
&lt;br /&gt;
In dieser Anleitung heißt das Paket &#039;&#039;xyz00&#039;&#039; und der für Mailinglisten eingesetzte User &#039;&#039;xyz00-list&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
Die E-Mail-Adresse der einzurichtende Mailing-Liste soll &#039;&#039;discuss@example.org&#039;&#039; sein.&lt;br /&gt;
&lt;br /&gt;
Die Domain &#039;&#039;example.org&#039;&#039; muss dazu bei einem beliebigen User im Paket &#039;&#039;xyz00&#039;&#039; [[aufgeschaltet]] sein. (&amp;quot;Aufgeschaltet&amp;quot; bedeutet, daß diese Domain bei Hostsharing gehostet wird und der Domainname als Verzeichnis /home/pacs/xyz00/*User*/doms/example.org/ erscheint.)&lt;br /&gt;
&lt;br /&gt;
=== Einrichtung  ===&lt;br /&gt;
&lt;br /&gt;
Ich melde mich über SSH auf der Hostsharing-Console als der Paketuser &#039;&#039;xyz00&#039;&#039; an.&lt;br /&gt;
&lt;br /&gt;
Im Shell kann ich dann durch den Befehl &#039;&#039;hsscript -i&#039;&#039; das Verwaltungswerkzeug &#039;&#039;hsadmin&#039;&#039; interaktiv ausführen:&lt;br /&gt;
&lt;br /&gt;
  xyz00@h03:~$ hsscript -i&lt;br /&gt;
  Password: *************&lt;br /&gt;
  xyz00@hsadmin&amp;gt; &lt;br /&gt;
&lt;br /&gt;
In &#039;&#039;hsadmin&#039;&#039; werden User und E-Mail-Adresse angelegt.&lt;br /&gt;
&lt;br /&gt;
  xyz00@hsadmin&amp;gt; user.add({set:{name:&#039;xyz00-list&#039;,comment:&#039;Mailingliste Discuss&#039;,shell:&#039;/bin/bash&#039;,password:&#039;geheimnis&#039;}})&lt;br /&gt;
  xyz00@hsadmin&amp;gt; emailaddress.add({set:{target:&#039;xyz00-list&#039;,localpart:&#039;discuss&#039;,domain:&#039;example.org&#039;}})&lt;br /&gt;
  xyz00@hsadmin&amp;gt; bye&lt;br /&gt;
&lt;br /&gt;
Mit dem Parameter &amp;quot;target&amp;quot; wird die für diese Adresse eingehende Post zunächst in das Postfach des Users xyz00-list abgelegt.&lt;br /&gt;
&lt;br /&gt;
Für den User xyz00-list lege ich in seinem Heimat-Verzeichnis das Unterverzeichnis &amp;quot;mlmmj&amp;quot; an:&lt;br /&gt;
&lt;br /&gt;
  mkdir /home/pacs/xyz00/users/list/mlmmj&lt;br /&gt;
&lt;br /&gt;
Dann lege ich die Mailingliste mit folgendem Kommando an:&lt;br /&gt;
&lt;br /&gt;
  mlmmj-make-ml -L discuss -s /home/pacs/xyz00/users/list/mlmmj&lt;br /&gt;
&lt;br /&gt;
Das Skript &#039;&#039;mlmmj-make-ml&#039;&#039; fragt weitere Parameter der Mailingliste ab:&lt;br /&gt;
&lt;br /&gt;
  The Domain for the List? [] : example.org&lt;br /&gt;
  The emailaddress of the list owner? [postmaster] : webmaster@example.org&lt;br /&gt;
  For the list texts you can choose between the following languages or&lt;br /&gt;
  give an absolute path to a directory containing the texts.&lt;br /&gt;
  Available languages:&lt;br /&gt;
  cz  da	de  en	es  fr	it  nl	ru&lt;br /&gt;
  The path to texts for the list? [en] : de&lt;br /&gt;
&lt;br /&gt;
Das skript &#039;&#039;mlmmj-make-ml&#039;&#039; legt daraufhin unter &amp;quot;/home/pacs/xyz00/users/list/mlmmj&amp;quot; ein Verzeichnis &amp;quot;discuss&amp;quot; an, das die Datenstruktur zur Verwaltung der Mailingliste enthält.&lt;br /&gt;
&lt;br /&gt;
Weitere Konfigurationen der Liste erfolgen durch das Anlegen von Dateien im&lt;br /&gt;
Verzeichnis &amp;quot;/home/pacs/xyz00/users/list/mlmmj/discuss/control&amp;quot;.&lt;br /&gt;
Die Konfigurationsmöglichkeiten finden Sie auf der [http://mlmmj.org/docs/tunables/ Internetseite von mlmmj].&lt;br /&gt;
&lt;br /&gt;
Damit mlmmj die Verteilung der Post übernimmt, muß ich im Heimat-Verzeichnis des users xyz00-list die Datei &amp;lt;tt&amp;gt;.forward&amp;lt;/tt&amp;gt; mit folgenden Inhalt (INKLUSIVE der Anführungszeichen!) erstellen:&lt;br /&gt;
&lt;br /&gt;
  &amp;quot;|/usr/bin/mlmmj-recieve -L /home/pacs/xyz00/users/list/mlmmj/discuss/&amp;quot;&lt;br /&gt;
&lt;br /&gt;
(Ja, &#039;&#039;receive&#039;&#039; schreibt sich mit &#039;&#039;-ei-&#039;&#039;, aber mlmmj hält einen symbolischen Link bereit für diejenigen, die in englischer Rechtschreibung unsicher sind:)&lt;br /&gt;
&lt;br /&gt;
   xyz00-list@h03:~$ ls -la /usr/bin/mlmmj-rec*&lt;br /&gt;
   -rwxr-xr-x 1 root root 27104 Sep 25  2018 /usr/bin/mlmmj-receive&lt;br /&gt;
   lrwxrwxrwx 1 root root    13 Sep 25  2018 /usr/bin/mlmmj-recieve -&amp;gt; mlmmj-receive&lt;br /&gt;
&lt;br /&gt;
Die &amp;lt;tt&amp;gt;.forward&amp;lt;/tt&amp;gt;-Datei sorgt dafür, dass eingehende E-Mails an das User-Postfach an das Programm &#039;&#039;mlmmj-recieve&#039;&#039; übergeben werden.&lt;br /&gt;
&lt;br /&gt;
Für regelmäßige Aufgaben der Listen-Managers definiere ich die&lt;br /&gt;
crontab wie folgt (immer noch als &#039;&#039;xyz00-list&#039;&#039;):&lt;br /&gt;
&lt;br /&gt;
  xyz00-list@h03:~$ crontab -e&lt;br /&gt;
&lt;br /&gt;
 MAILTO=webmaster@example.org&lt;br /&gt;
 PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/X11R6/bin&lt;br /&gt;
 HOME=/home/pacs/xyz00/users/list&lt;br /&gt;
 SHELL=/bin/bash&lt;br /&gt;
 LANG=en_US.UTF-8&lt;br /&gt;
 # m h  dom mon dow   command&lt;br /&gt;
 28 */4 * * * /usr/bin/mlmmj-maintd -d /home/pacs/xyz00/users/list/mlmmj -F&lt;br /&gt;
&lt;br /&gt;
Zum Schluss rufe ich das Skript mlmmj-sub auf, um die E-Mail-Adressen der gewünschten Abonnenten des Verteilers einzutragen:&lt;br /&gt;
&lt;br /&gt;
 /usr/bin/mlmmj-sub -L /home/pacs/xyz00/users/list/mlmmj/discuss -a klaus.muster@gmx.de -c &lt;br /&gt;
 /usr/bin/mlmmj-sub -L /home/pacs/xyz00/users/list/mlmmj/discuss -a sabine.beispiel@arcor.de -c &lt;br /&gt;
&lt;br /&gt;
Dabei bewirkt &amp;quot;-c&amp;quot;, dass der Abonnent eine Begrüßungs-Nachricht erhält. Alternativ kann man &amp;quot;-C&amp;quot; (großes C) angeben: dann muss der Abonnent das Abo durch Antworten auf die Nachricht bestätigen.&lt;br /&gt;
&lt;br /&gt;
=== weitere Konfiguration  ===&lt;br /&gt;
&lt;br /&gt;
Noch ein paar Dinge, die Sie möglicherweise einstellen wollen:&lt;br /&gt;
&lt;br /&gt;
Ein Prefix in der Betreffzeile setzen, z.B.: &amp;quot;[discuss]&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
 echo &amp;quot;[discuss]&amp;quot; &amp;gt; /home/pacs/xyz00/users/list/mlmmj/discuss/control/prefix&lt;br /&gt;
&lt;br /&gt;
Wenn die Liste nur E-Mails von eingetragenen Abonnenten weiterleiten soll:&lt;br /&gt;
&lt;br /&gt;
 touch /home/pacs/xyz00/users/list/mlmmj/discuss/control/subonlypost&lt;br /&gt;
&lt;br /&gt;
Damit der Listen-Owner weitere Abonnements bestätigen muss:&lt;br /&gt;
&lt;br /&gt;
 touch /home/pacs/xyz00/users/list/mlmmj/discuss/control/submod&lt;br /&gt;
&lt;br /&gt;
Einen &amp;quot;Reply-To:&amp;quot;-Header setzen, damit Antwort-Mails standardmäßig an die Mailing-Liste gehen:&lt;br /&gt;
&lt;br /&gt;
  echo &amp;quot;Reply-To:&amp;quot; &amp;gt; /home/pacs/xyz00/users/list/mlmmj/discuss/control/delheaders&lt;br /&gt;
  echo &amp;quot;Reply-To: discuss@example.org&amp;quot; &amp;gt; /home/pacs/xyz00/users/list/mlmmj/discuss/control/customheaders&lt;br /&gt;
&lt;br /&gt;
Weitere Möglichkeiten finden Sie (wie oben bereits angegeben) &lt;br /&gt;
auf der [http://mlmmj.org/docs/tunables/ Internetseite von mlmmj].&lt;br /&gt;
&lt;br /&gt;
=== Konfiguration im Browser ===&lt;br /&gt;
&lt;br /&gt;
Die Original-Distribution von &#039;&#039;mlmmj&#039;&#039; enthält ein paar einfache PHP- und Perl-Skripte.  Das sind Beispiele für Subscribe-/Unsubscribe-Formulare, ein Admin-Formular zum Eintragen und Löschen von Abonnements und eine Seite mit der gesamten Listen-Konfiguration.&lt;br /&gt;
&lt;br /&gt;
Wer es sich ansehen möchte:&lt;br /&gt;
&lt;br /&gt;
Als Paket-Admin eine Domain aufschalten:&lt;br /&gt;
&lt;br /&gt;
 hsscript -u xyz00 -e &amp;quot;domain.add({set:{name:&#039;lists.example.org&#039;,user:&#039;xyz00-list&#039;}})&amp;quot;&lt;br /&gt;
&lt;br /&gt;
Und weiter als &amp;quot;xyz00-list&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
Download der neuesten Version der Sourcen von mlmmj von http://mlmmj.org/downloads/ und diese in einem temporären Verzeichnis entpacken.&lt;br /&gt;
&lt;br /&gt;
Unter &amp;quot;/mlmmj-$versionsnummer/contrib/web/php-admin/&amp;quot; findet sich die PHP-Admin-Anwendung.&lt;br /&gt;
&lt;br /&gt;
Also den Inhalt diese Verzeichnisses nach &amp;quot;/home/pacs/xyz00/users/list/doms/lists.example.org/&amp;quot; packen,&lt;br /&gt;
* in &amp;quot;/home/pacs/xyz00/users/list/doms/lists.example.org/conf/config.php&amp;quot; die Variable &amp;quot;$topdir&amp;quot; anpassen&lt;br /&gt;
* die Dateien aus &amp;quot;/home/pacs/xyz00/users/list/doms/lists.example.org/htdocs/&amp;quot; nach &amp;quot;/home/pacs/xyz00/users/list/doms/lists.example.org/htdocs-ssl/&amp;quot; verschieben&lt;br /&gt;
* in &amp;quot;/home/pacs/xyz00/users/list/mlmmj&amp;quot; und in &amp;quot;/home/pacs/xyz00/users/list/doms/lists.example.org/htdocs-ssl/&amp;quot; eine &amp;quot;.htaccess&amp;quot; mit folgendem Inhalt ablegen: &lt;br /&gt;
 &lt;br /&gt;
 Require valid-user&lt;br /&gt;
 AuthType Basic&lt;br /&gt;
 AuthName &amp;quot;mlmmj web-interface&amp;quot;&lt;br /&gt;
 AuthUserFile /home/pacs/xyz00/users/list/doms/lists.example.org/etc/htpasswd&lt;br /&gt;
&lt;br /&gt;
Und schließlich die &amp;quot;htpasswd&amp;quot;-Datei anlegen.&lt;br /&gt;
&lt;br /&gt;
 cd /home/pacs/xyz00/users/list/doms/lists.example.org/etc/&lt;br /&gt;
 htpasswd -c htpasswd listadmin&lt;br /&gt;
&lt;br /&gt;
Ein Passwort angeben und auf&lt;br /&gt;
https://lists.example.org schauen.&lt;br /&gt;
&lt;br /&gt;
== Mehrere Mailinglisten betreiben ==&lt;br /&gt;
&lt;br /&gt;
Wenn mehrere Mailinglisten in einem Account und mit einer Admin-Oberfläche betrieben werden soll, empfiehlt sich die Nutzung von Procmail für den Aufruf von &#039;&#039;mlmmj&#039;&#039; für die jeweiligen Liste mit ihrem Daten-Verzeichnis.&lt;br /&gt;
&lt;br /&gt;
Dazu trägt man in der Date &#039;&#039;.forward&#039;&#039; statt des Aufrufs von &#039;&#039;mlmmj-recieve&#039;&#039; einen Aufruf von &#039;&#039;procmail&#039;&#039; ein:&lt;br /&gt;
&lt;br /&gt;
 |/usr/bin/procmail&lt;br /&gt;
&lt;br /&gt;
Die Konfiguration von Procmail kann generisch erfolgen. Dazu legt man eine Datei &#039;&#039;.procmailrc&#039;&#039; mit folgendem Inhalt ins $HOME des Users:&lt;br /&gt;
&lt;br /&gt;
 SHELL=/bin/sh&lt;br /&gt;
 HOMEDIR=/home/pacs/xyz00/users/list&lt;br /&gt;
 MAILDIR=/home/pacs/xyz00/users/list/Maildir&lt;br /&gt;
 PMDIR=/home/pacs/xyz00/users/list&lt;br /&gt;
 VERBOSE=yes&lt;br /&gt;
 LOGFILE=/home/pacs/xyz00/users/list/var/procmail.log&lt;br /&gt;
 DEFAULT&lt;br /&gt;
 &lt;br /&gt;
 :0:&lt;br /&gt;
 * ^X-Original-To: ()\/[^@+]+&lt;br /&gt;
 |/usr/bin/mlmmj-receive -F -L /home/pacs/xyz00/users/list/mlmmj/${MATCH}/&lt;br /&gt;
 &lt;br /&gt;
 :0&lt;br /&gt;
 { EXITCODE 67 }&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Der kryptische reguläre Ausdruck hinter dem Header &#039;&#039;X-Original-To:&#039;&#039; passt auf den Beginn der E-Mail-Adresse bis zum ersten &#039;&#039;@&#039;&#039;- oder &#039;&#039;+&#039;&#039;-Zeichen. In der Variable &#039;&#039;MATCH&#039;&#039; steht also der Name der Mailingliste, d.h. der Name der Verzeichnisses, in dem die Liste verwaltet wird.&lt;br /&gt;
&lt;br /&gt;
Sehr wichtig ist die Zeile &#039;&#039;DEFAULT&#039;&#039; zu Beginn der &#039;&#039;.procmailrc&#039;&#039;. Die Variable &#039;&#039;DEFAULT&#039;&#039; wird von &#039;&#039;procmail&#039;&#039; gesetzt. Wir sorgen mit dieser Zeile dafür, dass sie wieder undefiniert ist. Diese Variable wird intern von &#039;&#039;mlmmj&#039;&#039; benutzt, wenn sie gesetzt ist. Das führt in Kombination mit &#039;&#039;procmail&#039;&#039; zu Fehlfunktionen (vgl. Links).&lt;br /&gt;
&lt;br /&gt;
== Links ==&lt;br /&gt;
&lt;br /&gt;
* http://mlmmj.org/ Projektseite&lt;br /&gt;
* https://codeberg.org/mlmmj mlmmj auf Codeberg&lt;br /&gt;
* https://github.com/tchapi/mlmmj-simple-web-interface ein Admin-Interface in NodeJS&lt;br /&gt;
* https://www.tablix.org/~avian/blog/archives/2010/04/the_faulty_default/ Nutzung von mlmmj in Verbindung mit Procmail&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
[[Kategorie:HSDoku]]&lt;br /&gt;
[[Kategorie:Installationsanleitungen]]&lt;br /&gt;
[[Kategorie:Software]]&lt;br /&gt;
[[Kategorie:Mailinglisten]]&lt;br /&gt;
[[Kategorie:E-Mail]]&lt;/div&gt;</summary>
		<author><name>Apc00-tony</name></author>
	</entry>
	<entry>
		<id>https://wiki.hostsharing.net/index.php?title=Mailman_Installieren&amp;diff=6276</id>
		<title>Mailman Installieren</title>
		<link rel="alternate" type="text/html" href="https://wiki.hostsharing.net/index.php?title=Mailman_Installieren&amp;diff=6276"/>
		<updated>2023-11-10T17:14:53Z</updated>

		<summary type="html">&lt;p&gt;Apc00-tony: /* E-Mail Adressen bei Mailman einrichten */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Vorab: Die Wahl von Mailman 2 ==&lt;br /&gt;
&lt;br /&gt;
Mailman 2 hängt von Python 2.7 ab und wird damit voraussichtlich nur noch eine begrenzte Nutzungsdauer haben. Mailman 3 ist jetzt verfügbar (siehe [[Mailman_3_installieren]]), aber deutlich schwerer und komplexer im Betrieb. Es gibt auch weniger leistungsfähige Software, um E-Mail-Verteiler zu betreiben, wie beispielsweise [[mlmmj]]. Für eine Diskussion der Situation im Oktober 2019, siehe das HS-Support-Archiv ab [https://lists.hostsharing.net/archiv/support/2019-October/067243.html hier.]&lt;br /&gt;
&lt;br /&gt;
== Mailman 2 installieren == &lt;br /&gt;
&lt;br /&gt;
(zuletzt getestet mit mailman-2.1.29; Installation durch Paketuser)&lt;br /&gt;
&lt;br /&gt;
Vielen Dank an alle Benutzer, die Verbesserungen beisteuern!&lt;br /&gt;
&lt;br /&gt;
=== Unter welchem Account installieren? ===&lt;br /&gt;
&lt;br /&gt;
Mailman kann vom Paketadmin (beipsielsweise &amp;quot;xyz00&amp;quot;) oder von einem Paketuser (bspw. &amp;quot;xyz00-listen&amp;quot;) installiert werden. Letzteres ist dringend empfohlen, denn wenn Mailman vom Paketadmin installiert wird, haben ausnahmslos alle Paketuser direkten Zugriff auf die Mailman-Daten, und bei Sicherheitslücken in Mailman wäre eventuell eine Rechte-Eskalierung auf Paketadmin-Ebene potentiell zu befürchten.&lt;br /&gt;
&lt;br /&gt;
Dem Paketuser, unter dem Mailman installiert wird, können mehrere Subdomains aufschaltet werden, und Mailinglisten können auch die Domainnamen verwenden, die anderen Paketusern gehören.&lt;br /&gt;
&lt;br /&gt;
Vorteil der Installation als Paketuser ist, dass nur dieser direkten Zugriff auf die Mailmandaten hat und mailman ohne Paketadminrechte läuft. Während der Emailauslieferung gelten (wie immer bei der Mailweiterleitung durch .forward-Dateien oder durch procmail) die Rechte des Paketusers, dem die Mailman-Installation gehört.&lt;br /&gt;
&lt;br /&gt;
Nachteil der Installation als Paketuser ist lediglich, dass die Paketdomain mit dem SSL Zertifikat von Hostsharing nicht genutzt werden kann.&amp;lt;!-- Aktualisieren? --&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Einen User und eine Domain anlegen ===&lt;br /&gt;
&lt;br /&gt;
Unter admin.hostsharing.net als xyz00 anmelden; den User xyz00-listen erzeugen; die Domain listen.example.com mit &amp;quot;Domain-User&amp;quot; xyz00-listen anlegen. Aus admin.hostsharing.net abmelden.&lt;br /&gt;
&lt;br /&gt;
Mit [[Login_mit_SSH|SSH]] an hostsharing.net als xyz00-listen anmelden. Die Redirect-Zeile aus &amp;lt;tt&amp;gt;&amp;lt;nowiki&amp;gt;~/doms/listen.example.com/htdocs-ssl/.htaccess&amp;lt;/nowiki&amp;gt;&amp;lt;/tt&amp;gt; löschen:&lt;br /&gt;
&lt;br /&gt;
 ~$ echo &amp;quot;&amp;quot; &amp;gt; ~/doms/listen.example.com/htdocs-ssl/.htaccess&lt;br /&gt;
&lt;br /&gt;
Die Default-Subdomains www.* löschen:&lt;br /&gt;
&lt;br /&gt;
   ~$ rm -r doms/listen.example.com/subs/www/&lt;br /&gt;
   ~$ rm -r doms/listen.example.com/subs-ssl/www/&lt;br /&gt;
&lt;br /&gt;
=== Sourcen besorgen und entpacken ===&lt;br /&gt;
&lt;br /&gt;
Unter http://www.gnu.org/software/mailman/ die aktuelle Software besorgen. Dort findet sich ein Link zu den 2er-Versionen von Mailman (http://ftp.gnu.org/gnu/mailman/). Die letzte Version downloaden ...&lt;br /&gt;
&lt;br /&gt;
 ~$ wget http://ftp.gnu.org/gnu/mailman/mailman-2.1.29.tgz&lt;br /&gt;
&lt;br /&gt;
... und entpacken:&lt;br /&gt;
&lt;br /&gt;
 ~$ tar -xzvf mailman-2.1.29.tgz&lt;br /&gt;
&lt;br /&gt;
Ab diesem Augenblick gibt es ein Verzeichnis namens &amp;lt;tt&amp;gt;mailman-2.1.29/&amp;lt;/tt&amp;gt;. Darin liegt die nunmehr entpackte &#039;&#039;Quellcode&#039;&#039; der Mailman-Software. Nach dem Kompilieren (folgt unten) wird die fertig kompilierte, gebrauchsfähige Mailman-Software in dem zusätzlich vorhandenen Verzeichnis &amp;lt;tt&amp;gt;mailman/&amp;lt;/tt&amp;gt; liegen. (Dieses Verzeichnis wird beim Konfigurieren der Source als &amp;quot;prefix&amp;quot; angegeben.)&lt;br /&gt;
&lt;br /&gt;
=== var-Verzeichnis für Log-Dateien anlegen ===&lt;br /&gt;
&lt;br /&gt;
Bei der Installation als Paketuser (xyz00-listen):&lt;br /&gt;
 ~$ cd &amp;amp;&amp;amp; mkdir -p mailman/var&lt;br /&gt;
 ~$ chmod 02775 mailman/var&lt;br /&gt;
&lt;br /&gt;
Bei der Installation als Paketadmin (xyz00):&lt;br /&gt;
 ~$ cd &amp;amp;&amp;amp; mkdir var/mailman&lt;br /&gt;
 ~$ chmod 02775 var/mailman&lt;br /&gt;
&lt;br /&gt;
=== Mailman konfigurieren ===&lt;br /&gt;
&lt;br /&gt;
In das Source-Verzeichnis wechseln:&lt;br /&gt;
&lt;br /&gt;
 ~$ cd mailman-2.1.29&lt;br /&gt;
&lt;br /&gt;
Bei der Installation durch den Paketuser (xyz00-listen):&lt;br /&gt;
      ~/mailman-2.1.29$ ./configure --prefix=/home/pacs/xyz00/users/listen/mailman \&lt;br /&gt;
              --with-username=xyz00-listen \&lt;br /&gt;
              --with-groupname=xyz00 \&lt;br /&gt;
              --with-var-prefix=/home/pacs/xyz00/users/listen/mailman/var \&lt;br /&gt;
              --with-cgi-gid=xyz00 \&lt;br /&gt;
              --with-mail-gid=xyz00&lt;br /&gt;
&lt;br /&gt;
Bei der Installation durch den Paketadmin (xyz00):&lt;br /&gt;
      ~/mailman-2.1.29$ ./configure --prefix=/home/pacs/xyz00/mailman \&lt;br /&gt;
              --with-username=xyz00 \&lt;br /&gt;
              --with-groupname=xyz00 \&lt;br /&gt;
              --with-var-prefix=/home/pacs/xyz00/var/mailman \&lt;br /&gt;
              --with-cgi-gid=xyz00 \&lt;br /&gt;
              --with-mail-gid=nogroup&lt;br /&gt;
&lt;br /&gt;
(Die Rückwärtsschrägstriche &amp;quot;\&amp;quot; am Zeilenende bedeuten, dass der Befehl in der nächsten Zeile weitergeht. Alternativ können alle Argumente in eine Zeile getippt werden.)&lt;br /&gt;
&lt;br /&gt;
=== Mailman kompilieren ===&lt;br /&gt;
&lt;br /&gt;
 ~/mailman-2.1.29$ make&lt;br /&gt;
 ~/mailman-2.1.29$ make install&lt;br /&gt;
&lt;br /&gt;
=== Datenrechte prüfen ===&lt;br /&gt;
&lt;br /&gt;
Sicherheitshalber die Dateirechte durch Mailmans mitgeliefertes Tool prüfen und ggf. korrigieren lassen:&lt;br /&gt;
&lt;br /&gt;
 ~/mailman-2.1.29$ cd ..      &lt;br /&gt;
 ~$ mailman/bin/check_perms -f&lt;br /&gt;
&lt;br /&gt;
== Die neue Mailman-Installation konfigurieren ==&lt;br /&gt;
&lt;br /&gt;
=== Konfigurationsdatei &amp;lt;tt&amp;gt;mm_cfg.py&amp;lt;/tt&amp;gt; editieren ===&lt;br /&gt;
&lt;br /&gt;
 ~$ nano mailman/Mailman/mm_cfg.py&lt;br /&gt;
      &lt;br /&gt;
Eine Beispielkonfiguration für listen.example.com könnte so aussehen:&lt;br /&gt;
&lt;br /&gt;
 [...]&lt;br /&gt;
      ##################################################&lt;br /&gt;
      # Put YOUR site-specific settings below this line.&lt;br /&gt;
      # -*- python -*-&lt;br /&gt;
 &lt;br /&gt;
      DEFAULT_HOST_NAME = &#039;listen.example.com&#039;&lt;br /&gt;
      DEFAULT_EMAIL_HOST = &#039;listen.example.com&#039;&lt;br /&gt;
      DEFAULT_URL_HOST = &#039;listen.example.com&#039;&lt;br /&gt;
      add_virtualhost(DEFAULT_URL_HOST, DEFAULT_EMAIL_HOST)&lt;br /&gt;
      add_virtualhost(zweite.listendomain.com, zweite.listendomain.com)&lt;br /&gt;
 &lt;br /&gt;
      DEFAULT_SERVER_LANGUAGE = &#039;de&#039;&lt;br /&gt;
 &lt;br /&gt;
      DEFAULT_URL_PATTERN = &#039;http://%s/&#039;&lt;br /&gt;
  &lt;br /&gt;
      # Es wird der HS Mailversand für Bulkmail verwendet:&lt;br /&gt;
      SMTPHOST = &#039;localhost&#039;&lt;br /&gt;
      SMTPPORT = 4587 &lt;br /&gt;
      SMTP_AUTH = True&lt;br /&gt;
      SMTP_USER = &#039;xyz00-listen&#039;&lt;br /&gt;
      SMTP_PASSWD = &#039;das-passwort-des-o.-g.-users&#039;&lt;br /&gt;
      SMTP_USE_TLS = True&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
In &amp;lt;tt&amp;gt;~/mailman/Mailman/Defaults.py&amp;lt;/tt&amp;gt; sieht man, was in mm_cfg.py alles angepasst werden kann.&lt;br /&gt;
&lt;br /&gt;
==== Mailman gegen Subscription Spam härten ====&lt;br /&gt;
&lt;br /&gt;
Mailman wird gelegentlich von böswilligen Crackern benutzt, die damit sogenannten Subscription Spam erzeugen. Dabei wird eine Mailadresse von Bots an Mailman zur Eintragung übergeben. Diese Mailadresse wird daraufhin brav von Mailman angeschrieben. Wenn das tausende von Mailmans auf der ganzen Welt zugleich machen, wird die Mailadresse zugespammt. Hier ist die Abhilfe:&lt;br /&gt;
&lt;br /&gt;
Die Idee kommt von https://www.ralfj.de/blog/2018/06/02/mailman-subscription-spam.html&lt;br /&gt;
&lt;br /&gt;
Auf der Kommandozeile ein zufälliges Secret-String erstellen:&lt;br /&gt;
 openssl rand -base64 18&lt;br /&gt;
&lt;br /&gt;
Und dann in die Konfigurationsdatei den erzeugten String einfügen:&lt;br /&gt;
&lt;br /&gt;
 SUBSCRIBE_FORM_SECRET = &#039;&amp;lt;Secret-String&amp;gt;&#039;&lt;br /&gt;
&lt;br /&gt;
=== CGI-Programme in die Domain kopieren ===&lt;br /&gt;
&lt;br /&gt;
Bei der Installation als Paketuser (xyz00-listen):&lt;br /&gt;
&lt;br /&gt;
Die fertig kompilierten CGIs von Mailman müssen in das CGI-Verzeichnis der Domain (oder der Domains), auf der das Webfrontend von Mailman laufen soll, kopiert werden. Symbolische Links sind nicht ausreichend.&lt;br /&gt;
&lt;br /&gt;
 ~$ mkdir ~/doms/listen.example.com/cgi-ssl/mailman&lt;br /&gt;
 ~$ cp mailman/cgi-bin/* doms/listen.example.com/cgi-ssl/mailman/&lt;br /&gt;
&lt;br /&gt;
Zusätzlich muss das sticky-Flag von den kopierten Dateien entfernt werden:&lt;br /&gt;
&lt;br /&gt;
 ~$ chmod g-s ~/doms/listen.example.com/cgi/mailman/*&lt;br /&gt;
&lt;br /&gt;
Bei der Installation als Paketadmin (xyz00): &lt;br /&gt;
&lt;br /&gt;
Die CGI-Programme können im Mailman-Verzeichnis bleiben. Im CGI-Verzeichnis von jeder Domain, auf der das Mailman-Webfrontend laufen soll, werden symbolische Links dazu erstellt: &lt;br /&gt;
&lt;br /&gt;
 ~$ cd doms/listen.example.com/cgi-ssl&lt;br /&gt;
 ~/doms/listen.example.com/cgi-ssl$ ln -s ../../../mailman/cgi-bin mailman&lt;br /&gt;
&lt;br /&gt;
===  Mailman-Icons in die Domains kopieren ===&lt;br /&gt;
&lt;br /&gt;
Die Icons können wahlweise verlinkt oder kopiert werden:&lt;br /&gt;
&lt;br /&gt;
 ~$ cd doms/listen.example.com/htdocs-ssl&lt;br /&gt;
 ~/doms/listen.example.com/htdocs-ssl$ ln -s ../../../mailman/icons&lt;br /&gt;
&lt;br /&gt;
oder&lt;br /&gt;
&lt;br /&gt;
 ~$ cp -R mailman/icons doms/listen.example.com/htdocs-ssl/&lt;br /&gt;
&lt;br /&gt;
=== Die Datei .htaccess bearbeiten ===&lt;br /&gt;
&lt;br /&gt;
Bei einer dedizierten Mailman-Domain sollte man dafür sorgen, dass Mailman nicht nur unter &amp;lt;tt&amp;gt;&amp;lt;nowiki&amp;gt;https://listen.example.com/cgi-bin/mailman&amp;lt;/nowiki&amp;gt;&amp;lt;/tt&amp;gt;, sondern auch unter &amp;lt;tt&amp;gt;&amp;lt;nowiki&amp;gt;https://listen.example.com/&amp;lt;/nowiki&amp;gt;&amp;lt;/tt&amp;gt;  erreichbar ist.&lt;br /&gt;
&lt;br /&gt;
Dazu werden in &amp;lt;tt&amp;gt;&amp;lt;nowiki&amp;gt;~/doms/listen.example.com/htdocs-ssl/.htaccess&amp;lt;/nowiki&amp;gt;&amp;lt;/tt&amp;gt; folgende Rewrite-Anweisungen eintragen.&lt;br /&gt;
&lt;br /&gt;
 RewriteEngine On&lt;br /&gt;
 RewriteCond	%{REQUEST_URI}		!^/icons/&lt;br /&gt;
 RewriteRule	^(.*)$			/cgi-bin/mailman/$1&lt;br /&gt;
 RewriteRule	^/cgi-bin/mailman/$	/cgi-bin/mailman/listinfo&lt;br /&gt;
&lt;br /&gt;
Beachte dabei die zweite Zeile: Anfragen für Icons sollen &#039;&#039;nicht&#039;&#039; umgeschrieben werden.&lt;br /&gt;
&lt;br /&gt;
Wenn Mailman z.B. auf einer als Unterverzeichnis angelegten Subdomain läuft und unter &amp;lt;tt&amp;gt;&amp;lt;nowiki&amp;gt;https://www.example.com/mailman&amp;lt;/nowiki&amp;gt;&amp;lt;/tt&amp;gt; statt &amp;lt;tt&amp;gt;&amp;lt;nowiki&amp;gt;https://www.example.com/cgi-bin/mailman&amp;lt;/nowiki&amp;gt;&amp;lt;/tt&amp;gt; erreichbar sein soll, hilft folgendes in der &amp;lt;tt&amp;gt;&amp;lt;nowiki&amp;gt;~/doms/example.com/subs-ssl/www/.htaccess&amp;lt;/nowiki&amp;gt;&amp;lt;/tt&amp;gt;:&lt;br /&gt;
&lt;br /&gt;
 RewriteEngine On&lt;br /&gt;
 RewriteCond	%{REQUEST_URI}		!^/icons/&lt;br /&gt;
 RewriteRule    ^mailman/(.*)$          /cgi-bin/mailman/$1&lt;br /&gt;
 RewriteRule    ^/cgi-bin/mailman/$	/cgi-bin/mailman/listinfo&lt;br /&gt;
&lt;br /&gt;
(In diesem Fall kann die Zeile &amp;lt;tt&amp;gt;DEFAULT_URL_PATTERN...&amp;lt;/tt&amp;gt; in der &amp;lt;tt&amp;gt;mm_cfg.py&amp;lt;/tt&amp;gt; auskommentiert werden.)&lt;br /&gt;
&lt;br /&gt;
=== Hauptpasswort setzen ===&lt;br /&gt;
&lt;br /&gt;
Das &amp;quot;site password&amp;quot; ist in Mailman eine Art Generalschlüssel: es wird neben dem jeweiligen Admin- oder Moderator-Passwort überall in der Weboberfläche für sämtliche Mailing-Listen akzeptiert. Also vorsichtig wählen! Das &amp;quot;site password&amp;quot; einrichten mit dem Befehl: &lt;br /&gt;
&lt;br /&gt;
 ~$ mailman/bin/mmsitepass&lt;br /&gt;
&lt;br /&gt;
=== Cronjobs einrichten ===&lt;br /&gt;
&lt;br /&gt;
In die [[Cron |Crontab]] werden Befehle eingetragen, um die Mail-Warteschlange abzuarbeiten, Logs zu löschen, usw.:&lt;br /&gt;
&lt;br /&gt;
 # Warteschlange jede Minute bearbeiten:&lt;br /&gt;
 * * * * *	~/mailman/bin/qrunner -o -r All&lt;br /&gt;
 # Verarbeitungslogs in der 47ten Minute jeder Stunde löschen:&lt;br /&gt;
 47 * * * *	rm -f ~/var/mailman/logs/qrunner&lt;br /&gt;
&lt;br /&gt;
Damit übernimmt cron die Funktion des qrunner-Dämons, der normalerweise auf einem Mailman-Server laufen sollte.&lt;br /&gt;
&lt;br /&gt;
Das Logfile wird stündlich gelöscht, da es sonst sehr schnell sehr groß wird. Falls Mailman von einem Paketuser (bspw. &amp;quot;xyz00-listen&amp;quot;) installiert wurde, sollte die letzte Zeile im Beispiel oben so lauten:&lt;br /&gt;
&lt;br /&gt;
 47 * * * * rm -f ~/mailman/var/logs/qrunner&lt;br /&gt;
&lt;br /&gt;
... entsprechend dem beim Konfigurieren angegebenen &amp;lt;tt&amp;gt;var&amp;lt;/tt&amp;gt;-Verzeichnis, siehe oben.&lt;br /&gt;
&lt;br /&gt;
Zudem müssen noch die von Mailman ohnehin vorgesehenen cron-Aufträge aus &amp;lt;tt&amp;gt;~/mailman/cron/crontab.in&amp;lt;/tt&amp;gt; dem crontab des Users angehängt werden:&lt;br /&gt;
&lt;br /&gt;
 crontab -l &amp;gt; mycronjobs.tmp&lt;br /&gt;
 cat ~/mailman/cron/crontab.in &amp;gt;&amp;gt; mycronjobs.tmp&lt;br /&gt;
 crontab mycronjobs.tmp&lt;br /&gt;
&lt;br /&gt;
== Mailinglisten einrichten ==&lt;br /&gt;
&lt;br /&gt;
Jetzt läuft die Software; nun können die eigentlichen Verteiler angelegt werden. Als erster &#039;&#039;&#039;muß&#039;&#039;&#039; ein Hauptverteiler (&amp;quot;site list&amp;quot;) eingerichtet werden. Dieser Verteiler dient u.a. als Absender der Paßwort-Erinnerungen an die Abonnenten aller Mailinglisten. Er hat standardmäßig den Namen &amp;quot;mailman&amp;quot;. Falls ein anderer Name verwendet werden soll, muß dieser mit der Anweisung &lt;br /&gt;
&lt;br /&gt;
 MAILMAN_SITE_LIST = &#039;sitelistname&#039;&lt;br /&gt;
&lt;br /&gt;
in der Konfigurationsdatei &amp;lt;tt&amp;gt;mailman/Mailman/mm_cfg.py&amp;lt;/tt&amp;gt; eingetragen werden.&lt;br /&gt;
&lt;br /&gt;
=== Den Hauptverteiler &amp;quot;mailman&amp;quot; anlegen ===&lt;br /&gt;
&lt;br /&gt;
Die &amp;quot;site list&amp;quot; mit dem Namen &amp;quot;mailman&amp;quot; ist die Mailingliste der lokalen Mailman-Administratoren. Sie wird zur einwandfreien Funktion von Mailman benötigt.&lt;br /&gt;
&lt;br /&gt;
Mit dem Mailman-Befehl newlist den Verteiler anlegen:&lt;br /&gt;
&lt;br /&gt;
 ~$ mailman/bin/newlist mailman&lt;br /&gt;
 Enter the email of the person running the list: admin@xyz00.hostsharing.net&lt;br /&gt;
 Initial mailman password:&lt;br /&gt;
&lt;br /&gt;
(Der Befehl newlist kann – alternativ zur Weboberfläche – später benutzt werden, um gewöhnliche Mailinglisten anzulegen.)&lt;br /&gt;
&lt;br /&gt;
Nur dieses eine Mal für die &amp;quot;site list&amp;quot; müssen wir die Konfigurationsvorgaben laden. (Gewöhnliche Mailinglisten werden später über die Weboberfläche konfiguriert.)&lt;br /&gt;
&lt;br /&gt;
Falls mailman vom Paketuser (bspw. &amp;quot;xyz00-listen&amp;quot;) installiert wurde:&lt;br /&gt;
&lt;br /&gt;
 ~$ mailman/bin/config_list -i ~/mailman/var/data/sitelist.cfg mailman&lt;br /&gt;
&lt;br /&gt;
Falls mailman vom Paketadmin (&amp;quot;xyz00&amp;quot;) installiert wurde:&lt;br /&gt;
&lt;br /&gt;
 ~$ mailman/bin/config_list -i ~/var/mailman/data/sitelist.cfg mailman&lt;br /&gt;
&lt;br /&gt;
Diese Konfigurationsdatei soll &#039;&#039;&#039;nicht&#039;&#039;&#039; auf gewöhnliche Mailinglisten anwendet werden.&lt;br /&gt;
&lt;br /&gt;
=== E-Mail Adressen bei Mailman einrichten ===&lt;br /&gt;
&lt;br /&gt;
Sobald ein neuer Verteiler angelegt worden ist, sendet Mailman eine E-Mail an den dabei eingetragenen Listenadministrator. Diese E-Mail enthält die Anweisung, E-Mail-Aliases für den neuen Verteiler und für die verschiedenen Mailman-Funktionen anzulegen. Bei Hostsharing wird die Zustellung von E-Mails an Mailman anders geregelt: alle E-Mails an Mailman werden an erweiterte &#039;&#039;E-Mail-Adressen&#039;&#039; des Mailman-Users xyz00-listen geschickt. Diese Adressen haben die form &amp;lt;tt&amp;gt;xyz00-listen&#039;&#039;&#039;+&#039;&#039;&#039;&amp;lt;liste&amp;gt;[_funktion]&amp;lt;/tt&amp;gt;. E-Mails an diese Adressen werden dann durch Pipe-Anweisungen in &#039;&#039;.forward-Dateien&#039;&#039; im Home-Verzeichnis des Mailman-Users mit den entsprechenden Argumenten an Mailman übergeben. &lt;br /&gt;
&lt;br /&gt;
Falls Mailman von einem Paketuser (bspw. &amp;quot;xyz00-listen&amp;quot;) installiert wurde, werden  &#039;&#039;E-Mail-Adressen&#039;&#039; durch [https://doc.hostsharing.net/users/administration/hsadmin/index.html hsadmin (bzw. das Befehlszeilentool hsscript)] eingerichtet; die &#039;&#039;.forward-Dateien&#039;&#039; werden durch [[Login_mit_SSH|Shell-Befehle]] angelegt.&lt;br /&gt;
&lt;br /&gt;
Das folgende Beispiel zeigt die Befehle, mit denen in einer interaktiven hsscript-Sitzung die E-Mail-Adressen für die Hauptliste &amp;quot;mailman&amp;quot; eingerichtet werden. (Für spätere Mailinglisten wird in den Argumenten &amp;quot;mailman&amp;quot; durch den Namen der Mailingliste ersetzt.)&lt;br /&gt;
&lt;br /&gt;
   hsscript -u xyz00 -i&lt;br /&gt;
   [hsscript verlangt die Eingabe des Passworts vom Paketadmin xyz00; dann können diese Befehle eingegeben werden:]&lt;br /&gt;
   emailaddress.add ({set:{domain:&#039;listen.example.com&#039;,localpart:&#039;mailman&#039;,target:&#039;xyz00-listen+mailman&#039;}})&lt;br /&gt;
   emailaddress.add ({set:{domain:&#039;listen.example.com&#039;,localpart:&#039;mailman-admin&#039;,target:&#039;xyz00-listen+mailman-admin&#039;}})&lt;br /&gt;
   emailaddress.add ({set:{domain:&#039;listen.example.com&#039;,localpart:&#039;mailman-bounces&#039;,target:&#039;xyz00-listen+mailman-bounces&#039;}})&lt;br /&gt;
   emailaddress.add ({set:{domain:&#039;listen.example.com&#039;,localpart:&#039;mailman-confirm&#039;,target:&#039;xyz00-listen+mailman-confirm&#039;}})&lt;br /&gt;
   emailaddress.add ({set:{domain:&#039;listen.example.com&#039;,localpart:&#039;mailman-join&#039;,target:&#039;xyz00-listen+mailman-join&#039;}})&lt;br /&gt;
   emailaddress.add ({set:{domain:&#039;listen.example.com&#039;,localpart:&#039;mailman-leave&#039;,target:&#039;xyz00-listen+mailman-leave&#039;}})&lt;br /&gt;
   emailaddress.add ({set:{domain:&#039;listen.example.com&#039;,localpart:&#039;mailman-owner&#039;,target:&#039;xyz00-listen+mailman-owner&#039;}})&lt;br /&gt;
   emailaddress.add ({set:{domain:&#039;listen.example.com&#039;,localpart:&#039;mailman-request&#039;,target:&#039;xyz00-listen+mailman-request&#039;}})&lt;br /&gt;
   emailaddress.add ({set:{domain:&#039;listen.example.com&#039;,localpart:&#039;mailman-subscribe&#039;,target:&#039;xyz00-listen+mailman-subscribe&#039;}})&lt;br /&gt;
   emailaddress.add ({set:{domain:&#039;listen.example.com&#039;,localpart:&#039;mailman-unsubscribe&#039;,target:&#039;xyz00-listen+mailman-unsubscribe&#039;}})&lt;br /&gt;
&lt;br /&gt;
Die korrekte Einrichtung der E-Mail-Adressen kann in der Web-Oberfläche von hsadmin kontrolliert werden.&lt;br /&gt;
&lt;br /&gt;
Für jede der soeben eingerichteten Adressen wird nun eine &amp;lt;tt&amp;gt;.forward&amp;lt;/tt&amp;gt;-Datei im Homeverzeichnis des Users xyz00-listen angelegt. Die Dateinamen bestehen aus der Zeichenfolge &amp;lt;tt&amp;gt;.forward+&amp;lt;/tt&amp;gt; gefolgt vom Namen der ausführen soll. Der Inhalt der jeweiligen &amp;lt;tt&amp;gt;.forward&amp;lt;/tt&amp;gt;-Datei legt die Weiterleitung der Mail durch einen Pipe an Mailman fest, mit dem jeweiligen Befehl als Argument:&lt;br /&gt;
&lt;br /&gt;
   &amp;quot;|/home/pacs/xyz00/users/listen/mailman/mail/mailman [Befehl] [Listenname]&amp;quot;&lt;br /&gt;
&lt;br /&gt;
Zum Beispiel wird die &amp;lt;tt&amp;gt;.forward&amp;lt;/tt&amp;gt;-Datei .forward+mailman-subscribe verwendet, wenn eine E-Mail an die Adresse &amp;lt;tt&amp;gt;mailman-subscribe@listen.example.com&amp;lt;/tt&amp;gt; eingeht. Aufgrund der oben eingerichteten E-Mail-Adresse mit dem Ziel &amp;lt;tt&amp;gt;xyz00-listen+mailman-subscribe&amp;lt;/tt&amp;gt; wertet der Mail-Transfer-Agent die &amp;lt;tt&amp;gt;.forward&amp;lt;/tt&amp;gt;-Datei &amp;lt;tt&amp;gt;.forward+mailman-subscribe&amp;lt;/tt&amp;gt; im Home-Verzeichnis des Users xyz00-listen aus, und entsprechend ihrem Inhalt wird die Mail an die Mailman-Software mit den Argumenten &amp;quot;subscribe mailman&amp;quot; übergeben.&lt;br /&gt;
&lt;br /&gt;
Das folgende Beispiel zeigt die Befehle, mit denen an der Befehlszeilenaufforderung der Shell die &amp;lt;tt&amp;gt;.forward&amp;lt;/tt&amp;gt;-Dateien für die Hauptliste &amp;quot;mailman&amp;quot; eingerichtet werden. (Für spätere Mailinglisten wird in den Argumenten und in den Namen der &amp;lt;tt&amp;gt;.forward&amp;lt;/tt&amp;gt;-Dateien &amp;quot;mailman&amp;quot; durch den Namen der Mailingliste ersetzt, jedoch &#039;&#039;&#039;nicht&#039;&#039;&#039; in der Pfadangabe zum Mailman-Programm selbst; diese ändert sich ja nicht.)&lt;br /&gt;
&lt;br /&gt;
 echo &#039;admin@xyz00.hostsharing.net&#039; &amp;gt; .forward # Weiterleitung von cron Fehlern etc an Paketadmin.&lt;br /&gt;
 echo &#039;&amp;quot;|/home/pacs/xyz00/users/listen/mailman/mail/mailman post mailman&amp;quot;&#039; &amp;gt; .forward+mailman&lt;br /&gt;
 echo &#039;&amp;quot;|/home/pacs/xyz00/users/listen/mailman/mail/mailman admin mailman&amp;quot;&#039; &amp;gt; .forward+mailman-admin&lt;br /&gt;
 echo &#039;&amp;quot;|/home/pacs/xyz00/users/listen/mailman/mail/mailman bounces mailman&amp;quot;&#039; &amp;gt; .forward+mailman-bounces&lt;br /&gt;
 echo &#039;&amp;quot;|/home/pacs/xyz00/users/listen/mailman/mail/mailman confirm mailman&amp;quot;&#039; &amp;gt; .forward+mailman-confirm&lt;br /&gt;
 echo &#039;&amp;quot;|/home/pacs/xyz00/users/listen/mailman/mail/mailman join mailman&amp;quot;&#039; &amp;gt; .forward+mailman-join&lt;br /&gt;
 echo &#039;&amp;quot;|/home/pacs/xyz00/users/listen/mailman/mail/mailman leave mailman&amp;quot;&#039; &amp;gt; .forward+mailman-leave&lt;br /&gt;
 echo &#039;&amp;quot;|/home/pacs/xyz00/users/listen/mailman/mail/mailman owner mailman&amp;quot;&#039; &amp;gt; .forward+mailman-owner&lt;br /&gt;
 echo &#039;&amp;quot;|/home/pacs/xyz00/users/listen/mailman/mail/mailman request mailman&amp;quot;&#039; &amp;gt; .forward+mailman-request&lt;br /&gt;
 echo &#039;&amp;quot;|/home/pacs/xyz00/users/listen/mailman/mail/mailman subscribe mailman&amp;quot;&#039; &amp;gt; .forward+mailman-subscribe&lt;br /&gt;
 echo &#039;&amp;quot;|/home/pacs/xyz00/users/listen/mailman/mail/mailman unsubscribe mailman&amp;quot;&#039; &amp;gt; .forward+mailman-unsubscribe&lt;br /&gt;
&lt;br /&gt;
Die vielen Befehle können von dieser Anleitung kopiert und nach Anpassung auf den tatsächlichen Unsernamen in die SSH-Sitzung kopiert werden. Noch leichter ist es, mit einem Editor einen Shell-Skript namens &amp;lt;tt&amp;gt;~/bin/mailmanaddresses&amp;lt;/tt&amp;gt; mit folgendem Inhalt zu erstellen:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#!/bin/bash&lt;br /&gt;
# Add e-mail addresses and dot-forward files for mailman lists.&lt;br /&gt;
#&lt;br /&gt;
&lt;br /&gt;
# All the sanity checks.&lt;br /&gt;
&lt;br /&gt;
if [ &amp;quot;$3&amp;quot; = &amp;quot;&amp;quot; -o &amp;quot;$2&amp;quot; = &amp;quot;&amp;quot; -o &amp;quot;$1&amp;quot; = &amp;quot;&amp;quot; ] ; then&lt;br /&gt;
    echo &amp;quot;Syntax: $0 listname domainname listowner\n&amp;quot; &lt;br /&gt;
    exit&lt;br /&gt;
fi&lt;br /&gt;
&lt;br /&gt;
if [ &amp;quot;$4&amp;quot; != &amp;quot;&amp;quot; ] ; then&lt;br /&gt;
    echo &amp;quot;Syntax: $0 listname domainname listowner\n&amp;quot; &lt;br /&gt;
    exit&lt;br /&gt;
fi&lt;br /&gt;
&lt;br /&gt;
if [ &amp;quot;`pwd`&amp;quot; != &amp;quot;`echo ~`&amp;quot; ] ; then&lt;br /&gt;
    echo &amp;quot;Run this script from your home directory.\n&amp;quot; &lt;br /&gt;
    exit&lt;br /&gt;
fi&lt;br /&gt;
&lt;br /&gt;
if [ ! -d &amp;quot;../${3:6}&amp;quot; ] ; then&lt;br /&gt;
	echo &amp;quot;There&#039;s no user named $3.&amp;quot;&lt;br /&gt;
	exit&lt;br /&gt;
else&lt;br /&gt;
	echo &amp;quot;You may be asked for a password for $3.&amp;quot;&lt;br /&gt;
fi&lt;br /&gt;
&lt;br /&gt;
if [ ! -d &amp;quot;./mailman/Mailman&amp;quot; ] ; then&lt;br /&gt;
	echo &amp;quot;Are you sure you have a Mailman installation?&amp;quot;&lt;br /&gt;
	exit&lt;br /&gt;
fi&lt;br /&gt;
&lt;br /&gt;
# hsscript fails with a &amp;quot;no result&amp;quot; and 255 if $2 (domain name) is not valid.&lt;br /&gt;
# It also fails if a requested address already exists.&lt;br /&gt;
# scriptexpr contains the expanded variables. Avoid spaces, because it&#039;s unquoted in the hsscript call.&lt;br /&gt;
&lt;br /&gt;
# Add the base list address and its forward file:&lt;br /&gt;
scriptexpr=&amp;quot;emailaddress.add({set:{localpart:\&amp;quot;$1\&amp;quot;,target:\&amp;quot;xyz00-lists+$1\&amp;quot;,domain:\&amp;quot;$2\&amp;quot;}})&amp;quot;&lt;br /&gt;
hsscript -r$3 -u$3 -e $scriptexpr&lt;br /&gt;
if [ &amp;quot;$?&amp;quot; != &amp;quot;0&amp;quot; ] ; then echo &amp;quot;hsscript failed to add address with localpart $1&amp;quot; ; exit ; fi&lt;br /&gt;
echo &amp;quot;\&amp;quot;|/home/pacs/xyz00/users/lists/mailman/mail/mailman post $1\&amp;quot;&amp;quot; &amp;gt; .forward+$1&lt;br /&gt;
if [ &amp;quot;$?&amp;quot; != &amp;quot;0&amp;quot; ] ; then echo &amp;quot;failed to create a forward file for posts&amp;quot; ; exit ; fi&lt;br /&gt;
&lt;br /&gt;
# Now do the same for all the suffixes&lt;br /&gt;
for subpart in admin bounces confirm join leave owner request subscribe unsubscribe&lt;br /&gt;
do&lt;br /&gt;
    scriptexpr=&amp;quot;emailaddress.add({set:{localpart:\&amp;quot;$1-${subpart}\&amp;quot;,target:\&amp;quot;xyz00-lists+$1-${subpart}\&amp;quot;,domain:\&amp;quot;$2\&amp;quot;}})&amp;quot;&lt;br /&gt;
    hsscript -r$3 -u$3 -e $scriptexpr&lt;br /&gt;
    if [ &amp;quot;$?&amp;quot; != &amp;quot;0&amp;quot; ] ; then echo &amp;quot;hsscript failed on subpart ${subpart}&amp;quot; ; exit ; fi&lt;br /&gt;
    echo &amp;quot;\&amp;quot;|/home/pacs/xyz00/users/lists/mailman/mail/mailman $subpart $1\&amp;quot;&amp;quot; &amp;gt; .forward+$1-$subpart&lt;br /&gt;
    if [ &amp;quot;$?&amp;quot; != &amp;quot;0&amp;quot; ] ; then echo &amp;quot;failed to create a forward file for ${subpart}&amp;quot; ; exit ; fi&lt;br /&gt;
done&lt;br /&gt;
&lt;br /&gt;
echo &amp;quot;$0 ran to the end and finished with $?&amp;quot;&lt;br /&gt;
exit&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Der Skript muß als ausführbar gekennzeichnet werden:&lt;br /&gt;
&lt;br /&gt;
  ~$ chmod u+x bin/mailmanaddresses&lt;br /&gt;
&lt;br /&gt;
Die Erstellung eines Skripts um die Adressen wieder zu entfernen wird dem Leser überlassen.&lt;br /&gt;
(Der hsscript-Befehl lautet &amp;lt;tt&amp;gt;hsscript -r&amp;lt;listenowner&amp;gt; -u&amp;lt;listenowner&amp;gt; -e &#039;emailaddress.remove({where:{localpart:&amp;quot;&amp;lt;listenname[-suffix]&amp;gt;&amp;quot;,target:&amp;quot;&amp;lt;mailman-owner+listenname-suffix&amp;quot;,domain:&amp;quot;dommainname&amp;quot;}})&#039;&amp;lt;/tt&amp;gt;.)&lt;br /&gt;
&lt;br /&gt;
=== Administration ===&lt;br /&gt;
&lt;br /&gt;
Als erstes sollte man als Administrator der neuen Mailman-Installation die Liste &amp;quot;mailman&amp;quot; selbst abonnieren. Die Liste &amp;quot;mailman&amp;quot; kann aber unter &amp;lt;tt&amp;gt;&amp;lt;nowiki&amp;gt;https://listen.example.com/mailman/admin/mailman&amp;lt;/nowiki&amp;gt;&amp;lt;/tt&amp;gt; verwaltet werden.&lt;br /&gt;
&lt;br /&gt;
Die Hauptseite der Mailman-Web-Verwaltung ist in unserem Beispiel (mit den oben angegebenen Rewrite-Anweisungen in der Datei &amp;lt;tt&amp;gt;.htaccess&amp;lt;/tt&amp;gt;) &amp;lt;tt&amp;gt;&amp;lt;nowiki&amp;gt;https://listen.example.com/mailman/admin/&amp;lt;/nowiki&amp;gt;&amp;lt;/tt&amp;gt;. Diese Seite enthält Links zu den bisher eingerichteten Mailinglisten (außer &amp;quot;mailman&amp;quot;) und einen Link, um neue Mailinglisten anzulegen (&amp;lt;tt&amp;gt;&amp;lt;nowiki&amp;gt;https://listen.example.com/mailman/create&amp;lt;/nowiki&amp;gt;&amp;lt;/tt&amp;gt;). Das Anlegen einer neuen Mailingliste geschieht entweder über diesen Link oder (wie oben) in der Shell mit dem Befehl:&lt;br /&gt;
&lt;br /&gt;
 ~$ mailman/bin/newlist &amp;lt;Listenname&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In beiden Fällen müssen zusätzlich die E-Mail-Adressen und die &amp;lt;tt&amp;gt;.forward&amp;lt;/tt&amp;gt;-Dateien wie bei dem Einrichten der Liste &amp;quot;mailman&amp;quot; nach Verfahren im obigen Abschnitt angelegt werden.&lt;br /&gt;
&lt;br /&gt;
Für die Verwaltung der Mailinglisten im Alltag, d.h. den Umgang mit Bounces, Spam, Abonnenten usw., siehe u.a. die [https://wiki.list.org/ Mailman-Wiki].&lt;br /&gt;
&lt;br /&gt;
== Feintuning == &lt;br /&gt;
&lt;br /&gt;
Wer will, kann auch noch etwas Platz sparen. Die normale Mailmaninstallation schlägt mit über 20 MB zu Buche...&lt;br /&gt;
&lt;br /&gt;
Mit den folgenden Tips kann man das auf ca. 6 MB reduzieren :)&lt;br /&gt;
&lt;br /&gt;
Es kann natürlich sein, dass ich zuviel lösche, aber bei mir funktioniert&#039;s. Wenn ihr also sicher(er) sein wollt, dass euch der Mailman nicht um die Ohren fliegt, macht das nicht!&lt;br /&gt;
&lt;br /&gt;
*  ~/mailman/cgi-bin und ~/mailman/icons können gelöscht werden, falls sie an andere Stelle kopiert worden sind.&lt;br /&gt;
* Die nicht benötigten Sprachen in ~/mailman/messages löschen.&lt;br /&gt;
* Die nicht benötigten Sprachen in ~/mailman/templates löschen (bis auf englisch).&lt;br /&gt;
* ~/mailman/tests kann, soweit ich das sehe, komplett gelöscht werden.&lt;br /&gt;
* Falls man koreanisch und japanisch nicht braucht, kann man folgendes machen:&lt;br /&gt;
* in ~/mailman/bin/paths.py, ~/mailman/cron/paths.py und ~/mailman/scripts/paths.py die Zeilen:&lt;br /&gt;
&lt;br /&gt;
 # In a normal interactive Python environment, the japanese.pth and korean.pth&lt;br /&gt;
 # files would be imported automatically.  But because we inhibit the importing&lt;br /&gt;
 # of the site module, we need to be explicit about importing these codecs.&lt;br /&gt;
 if not jaok:&lt;br /&gt;
     import japanese&lt;br /&gt;
 # As of KoreanCodecs 2.0.5, you had to do the second import to get the Korean&lt;br /&gt;
 # codecs installed, however leave the first import in there in case an upgrade&lt;br /&gt;
 # changes this.&lt;br /&gt;
 if not kook:&lt;br /&gt;
     import korean&lt;br /&gt;
     import korean.aliases&lt;br /&gt;
&lt;br /&gt;
auskommentieren.&lt;br /&gt;
&lt;br /&gt;
Dann kann man ~/mailman/pythonlib/japanese, ~/mailman/pythonlib/korean, ~/mailman/pythonlib/korean.pth sowie ~/mailman/pythonlib/lib löschen.&lt;br /&gt;
   &lt;br /&gt;
Man kann auch noch die Debug-Informationen aus den binaries strippen:&lt;br /&gt;
&lt;br /&gt;
 strip ~/mailman/mail/mailman&lt;br /&gt;
 strip ~/mailman/cgi-bin/*&lt;br /&gt;
&lt;br /&gt;
Falls die CGIs nicht gesymlinkt wurden:&lt;br /&gt;
&lt;br /&gt;
 strip ~/doms/listen.example.com/cgi/mailman/*&lt;br /&gt;
&lt;br /&gt;
== Multidomainfähigkeit ==&lt;br /&gt;
&lt;br /&gt;
Seit Mailman 2.x kann eine Mailman-Installation unter gewissen Einschränkungen für mehrere Domains verwendet werden. Hier soll kurz gezeigt werden, was geht und wie es geht.&lt;br /&gt;
&lt;br /&gt;
=== Anleitung ===&lt;br /&gt;
&lt;br /&gt;
Logischerweise muss das Webfrontend (die CGIs) auf allen Domains installiert werden.&lt;br /&gt;
&lt;br /&gt;
Wenn man nun Mailinglisten mit newlist neu anlegt, muss man den Hostnamen für das Webfontend mit angeben, und zwar so:&lt;br /&gt;
&lt;br /&gt;
 ~$ mailman/bin/newlist listenname@listen.example.com&lt;br /&gt;
&lt;br /&gt;
Es ist ggf. wichtig, dass in der mm_cfg.py eine entsprechende add_virtualhost-Direktive für www.example.com steht, die der Frontend-URL einen Host-Part für die Mailadressen zuordnet. Ist eine solche Direktive nicht vorhanden, so wird listen.example.com sowohl als URL für das Webfrontend wie auch als Hostpart für E-Mailadressen verwendet. (Was für separate aufgeschaltete Domains wie z.B. listen.example.com gerade zutrifft.)&lt;br /&gt;
&lt;br /&gt;
Liegt das Frondend nicht auf der Maildomain ist es wichtig, dass ihr Mailman sagt, für welches die zugehörige Maildomain ist. Dies tut ihr in der Datei ~/mailman/Mailman/mm_cfg.py:&lt;br /&gt;
&lt;br /&gt;
Also z.B.&lt;br /&gt;
 DEFAULT_URL_HOST = &#039;www.example.com&#039;&lt;br /&gt;
 DEFAULT_EMAIL_HOST = &#039;listen.example.com&#039;&lt;br /&gt;
 add_virtualhost(DEFAULT_URL_HOST,DEFAULT_EMAIL_HOST)&lt;br /&gt;
&lt;br /&gt;
und&lt;br /&gt;
 add_virtualhost(&#039;www.zoopnet.de&#039;, &#039;lists.zoopnet.de&#039;)&lt;br /&gt;
&lt;br /&gt;
Das bedeutet, dass Mailman per default davon ausgeht, dass alle Listen für die Domain example.com sind.&lt;br /&gt;
Alle weiteren add_virtualhost-Direktiven ordnen einem Hostnamen für das Webfrontend (z.B. www.zoopnet.de) einen Hostpart für die Adresse der Mailinglisten (z.B. lists.zoopnet.de) zu.&lt;br /&gt;
&lt;br /&gt;
Tip von Raimund Specht: Lässt man den zweiten Parameter weg, also schreibt z.B. add_virtualhost(&#039;www.example.org&#039;), dann benutzt Mailman als Hostpart alles was nach dem ersten Punkt steht, hier also example.org als Maildomain.&lt;br /&gt;
 &lt;br /&gt;
&lt;br /&gt;
Prinzipiell war&#039;s das. Man muss die Listeneinträge natürlich immer in die richtige virtusertable eintragen, und für gleichnamige Mailinglisten auf verschiedenen Domains (mailman@*) verschidene +Ergänzungen bzw. aliase verwenden. :)&lt;br /&gt;
&lt;br /&gt;
=== Probleme ===&lt;br /&gt;
&lt;br /&gt;
Verschiedene Listen mit gleichem Namen (also z.B. liste@example1.com und liste@example2.com) sind mit Mailman 2.1 leider nicht möglich.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Tips und Tricks ==&lt;br /&gt;
&lt;br /&gt;
=== URL Änderungen ===&lt;br /&gt;
Nach URL Änderungen stimmen Links im Web-Interface nicht mehr und Listen werden nicht mehr angezeigt.&lt;br /&gt;
Es sind dann, zusätzlich zur Anpassung der mm_cfg.py, schon bestehende Listen und Archive mit folgendem Befehl zu aktualisieren:&lt;br /&gt;
 ~/mailman/bin/withlist -l -r fix_url &amp;lt;Listen_Name&amp;gt; -v -u &amp;lt;Neue_Url&amp;gt;&lt;br /&gt;
&amp;lt;Listen_Name&amp;gt; steht für die Mailingliste, die bearbeitet werden soll. &amp;lt;Neue_Url&amp;gt; für die neue URL/Webadresse des Webinterfaces.&lt;br /&gt;
&lt;br /&gt;
=== Weitere Cron-Jobs zur Mailinglisten Verwaltung ===&lt;br /&gt;
&lt;br /&gt;
Folgende Cronjobs helfen bei der Verwaltung und sind User freundlich:&lt;br /&gt;
&lt;br /&gt;
&amp;lt; In Arbeit &amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Referenzen ==&lt;br /&gt;
&lt;br /&gt;
Lösung zur installation als Domainadmin (xyz00-listen) statt Paketadmin (xyz00): https://lists.hostsharing.net/archiv/support/2009-June/019414.html&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Ältere Anleitung für Installation als Domain-Admin (xyz00-listen): &amp;lt;http://lists.hostsharing.net/archiv/support/2005-January/012426.html&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;quot;Kleine Tools&amp;quot; auf http://hs.andreasloesch.de/, wobei das &#039;pac-mm-install&#039; wahrscheinlich nicht aktuell (genug) ist&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
[[Kategorie:HSDoku]]&lt;br /&gt;
[[Kategorie:Installationsanleitungen]]&lt;br /&gt;
[[Kategorie:Software]]&lt;br /&gt;
[[Kategorie:Mailinglisten]]&lt;br /&gt;
[[Kategorie:E-Mail]]&lt;br /&gt;
[[Kategorie:Python]]&lt;/div&gt;</summary>
		<author><name>Apc00-tony</name></author>
	</entry>
	<entry>
		<id>https://wiki.hostsharing.net/index.php?title=Mailman_Installieren&amp;diff=6275</id>
		<title>Mailman Installieren</title>
		<link rel="alternate" type="text/html" href="https://wiki.hostsharing.net/index.php?title=Mailman_Installieren&amp;diff=6275"/>
		<updated>2023-11-10T17:04:49Z</updated>

		<summary type="html">&lt;p&gt;Apc00-tony: /* E-Mail Adressen bei Mailman einrichten */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Vorab: Die Wahl von Mailman 2 ==&lt;br /&gt;
&lt;br /&gt;
Mailman 2 hängt von Python 2.7 ab und wird damit voraussichtlich nur noch eine begrenzte Nutzungsdauer haben. Mailman 3 ist jetzt verfügbar (siehe [[Mailman_3_installieren]]), aber deutlich schwerer und komplexer im Betrieb. Es gibt auch weniger leistungsfähige Software, um E-Mail-Verteiler zu betreiben, wie beispielsweise [[mlmmj]]. Für eine Diskussion der Situation im Oktober 2019, siehe das HS-Support-Archiv ab [https://lists.hostsharing.net/archiv/support/2019-October/067243.html hier.]&lt;br /&gt;
&lt;br /&gt;
== Mailman 2 installieren == &lt;br /&gt;
&lt;br /&gt;
(zuletzt getestet mit mailman-2.1.29; Installation durch Paketuser)&lt;br /&gt;
&lt;br /&gt;
Vielen Dank an alle Benutzer, die Verbesserungen beisteuern!&lt;br /&gt;
&lt;br /&gt;
=== Unter welchem Account installieren? ===&lt;br /&gt;
&lt;br /&gt;
Mailman kann vom Paketadmin (beipsielsweise &amp;quot;xyz00&amp;quot;) oder von einem Paketuser (bspw. &amp;quot;xyz00-listen&amp;quot;) installiert werden. Letzteres ist dringend empfohlen, denn wenn Mailman vom Paketadmin installiert wird, haben ausnahmslos alle Paketuser direkten Zugriff auf die Mailman-Daten, und bei Sicherheitslücken in Mailman wäre eventuell eine Rechte-Eskalierung auf Paketadmin-Ebene potentiell zu befürchten.&lt;br /&gt;
&lt;br /&gt;
Dem Paketuser, unter dem Mailman installiert wird, können mehrere Subdomains aufschaltet werden, und Mailinglisten können auch die Domainnamen verwenden, die anderen Paketusern gehören.&lt;br /&gt;
&lt;br /&gt;
Vorteil der Installation als Paketuser ist, dass nur dieser direkten Zugriff auf die Mailmandaten hat und mailman ohne Paketadminrechte läuft. Während der Emailauslieferung gelten (wie immer bei der Mailweiterleitung durch .forward-Dateien oder durch procmail) die Rechte des Paketusers, dem die Mailman-Installation gehört.&lt;br /&gt;
&lt;br /&gt;
Nachteil der Installation als Paketuser ist lediglich, dass die Paketdomain mit dem SSL Zertifikat von Hostsharing nicht genutzt werden kann.&amp;lt;!-- Aktualisieren? --&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Einen User und eine Domain anlegen ===&lt;br /&gt;
&lt;br /&gt;
Unter admin.hostsharing.net als xyz00 anmelden; den User xyz00-listen erzeugen; die Domain listen.example.com mit &amp;quot;Domain-User&amp;quot; xyz00-listen anlegen. Aus admin.hostsharing.net abmelden.&lt;br /&gt;
&lt;br /&gt;
Mit [[Login_mit_SSH|SSH]] an hostsharing.net als xyz00-listen anmelden. Die Redirect-Zeile aus &amp;lt;tt&amp;gt;&amp;lt;nowiki&amp;gt;~/doms/listen.example.com/htdocs-ssl/.htaccess&amp;lt;/nowiki&amp;gt;&amp;lt;/tt&amp;gt; löschen:&lt;br /&gt;
&lt;br /&gt;
 ~$ echo &amp;quot;&amp;quot; &amp;gt; ~/doms/listen.example.com/htdocs-ssl/.htaccess&lt;br /&gt;
&lt;br /&gt;
Die Default-Subdomains www.* löschen:&lt;br /&gt;
&lt;br /&gt;
   ~$ rm -r doms/listen.example.com/subs/www/&lt;br /&gt;
   ~$ rm -r doms/listen.example.com/subs-ssl/www/&lt;br /&gt;
&lt;br /&gt;
=== Sourcen besorgen und entpacken ===&lt;br /&gt;
&lt;br /&gt;
Unter http://www.gnu.org/software/mailman/ die aktuelle Software besorgen. Dort findet sich ein Link zu den 2er-Versionen von Mailman (http://ftp.gnu.org/gnu/mailman/). Die letzte Version downloaden ...&lt;br /&gt;
&lt;br /&gt;
 ~$ wget http://ftp.gnu.org/gnu/mailman/mailman-2.1.29.tgz&lt;br /&gt;
&lt;br /&gt;
... und entpacken:&lt;br /&gt;
&lt;br /&gt;
 ~$ tar -xzvf mailman-2.1.29.tgz&lt;br /&gt;
&lt;br /&gt;
Ab diesem Augenblick gibt es ein Verzeichnis namens &amp;lt;tt&amp;gt;mailman-2.1.29/&amp;lt;/tt&amp;gt;. Darin liegt die nunmehr entpackte &#039;&#039;Quellcode&#039;&#039; der Mailman-Software. Nach dem Kompilieren (folgt unten) wird die fertig kompilierte, gebrauchsfähige Mailman-Software in dem zusätzlich vorhandenen Verzeichnis &amp;lt;tt&amp;gt;mailman/&amp;lt;/tt&amp;gt; liegen. (Dieses Verzeichnis wird beim Konfigurieren der Source als &amp;quot;prefix&amp;quot; angegeben.)&lt;br /&gt;
&lt;br /&gt;
=== var-Verzeichnis für Log-Dateien anlegen ===&lt;br /&gt;
&lt;br /&gt;
Bei der Installation als Paketuser (xyz00-listen):&lt;br /&gt;
 ~$ cd &amp;amp;&amp;amp; mkdir -p mailman/var&lt;br /&gt;
 ~$ chmod 02775 mailman/var&lt;br /&gt;
&lt;br /&gt;
Bei der Installation als Paketadmin (xyz00):&lt;br /&gt;
 ~$ cd &amp;amp;&amp;amp; mkdir var/mailman&lt;br /&gt;
 ~$ chmod 02775 var/mailman&lt;br /&gt;
&lt;br /&gt;
=== Mailman konfigurieren ===&lt;br /&gt;
&lt;br /&gt;
In das Source-Verzeichnis wechseln:&lt;br /&gt;
&lt;br /&gt;
 ~$ cd mailman-2.1.29&lt;br /&gt;
&lt;br /&gt;
Bei der Installation durch den Paketuser (xyz00-listen):&lt;br /&gt;
      ~/mailman-2.1.29$ ./configure --prefix=/home/pacs/xyz00/users/listen/mailman \&lt;br /&gt;
              --with-username=xyz00-listen \&lt;br /&gt;
              --with-groupname=xyz00 \&lt;br /&gt;
              --with-var-prefix=/home/pacs/xyz00/users/listen/mailman/var \&lt;br /&gt;
              --with-cgi-gid=xyz00 \&lt;br /&gt;
              --with-mail-gid=xyz00&lt;br /&gt;
&lt;br /&gt;
Bei der Installation durch den Paketadmin (xyz00):&lt;br /&gt;
      ~/mailman-2.1.29$ ./configure --prefix=/home/pacs/xyz00/mailman \&lt;br /&gt;
              --with-username=xyz00 \&lt;br /&gt;
              --with-groupname=xyz00 \&lt;br /&gt;
              --with-var-prefix=/home/pacs/xyz00/var/mailman \&lt;br /&gt;
              --with-cgi-gid=xyz00 \&lt;br /&gt;
              --with-mail-gid=nogroup&lt;br /&gt;
&lt;br /&gt;
(Die Rückwärtsschrägstriche &amp;quot;\&amp;quot; am Zeilenende bedeuten, dass der Befehl in der nächsten Zeile weitergeht. Alternativ können alle Argumente in eine Zeile getippt werden.)&lt;br /&gt;
&lt;br /&gt;
=== Mailman kompilieren ===&lt;br /&gt;
&lt;br /&gt;
 ~/mailman-2.1.29$ make&lt;br /&gt;
 ~/mailman-2.1.29$ make install&lt;br /&gt;
&lt;br /&gt;
=== Datenrechte prüfen ===&lt;br /&gt;
&lt;br /&gt;
Sicherheitshalber die Dateirechte durch Mailmans mitgeliefertes Tool prüfen und ggf. korrigieren lassen:&lt;br /&gt;
&lt;br /&gt;
 ~/mailman-2.1.29$ cd ..      &lt;br /&gt;
 ~$ mailman/bin/check_perms -f&lt;br /&gt;
&lt;br /&gt;
== Die neue Mailman-Installation konfigurieren ==&lt;br /&gt;
&lt;br /&gt;
=== Konfigurationsdatei &amp;lt;tt&amp;gt;mm_cfg.py&amp;lt;/tt&amp;gt; editieren ===&lt;br /&gt;
&lt;br /&gt;
 ~$ nano mailman/Mailman/mm_cfg.py&lt;br /&gt;
      &lt;br /&gt;
Eine Beispielkonfiguration für listen.example.com könnte so aussehen:&lt;br /&gt;
&lt;br /&gt;
 [...]&lt;br /&gt;
      ##################################################&lt;br /&gt;
      # Put YOUR site-specific settings below this line.&lt;br /&gt;
      # -*- python -*-&lt;br /&gt;
 &lt;br /&gt;
      DEFAULT_HOST_NAME = &#039;listen.example.com&#039;&lt;br /&gt;
      DEFAULT_EMAIL_HOST = &#039;listen.example.com&#039;&lt;br /&gt;
      DEFAULT_URL_HOST = &#039;listen.example.com&#039;&lt;br /&gt;
      add_virtualhost(DEFAULT_URL_HOST, DEFAULT_EMAIL_HOST)&lt;br /&gt;
      add_virtualhost(zweite.listendomain.com, zweite.listendomain.com)&lt;br /&gt;
 &lt;br /&gt;
      DEFAULT_SERVER_LANGUAGE = &#039;de&#039;&lt;br /&gt;
 &lt;br /&gt;
      DEFAULT_URL_PATTERN = &#039;http://%s/&#039;&lt;br /&gt;
  &lt;br /&gt;
      # Es wird der HS Mailversand für Bulkmail verwendet:&lt;br /&gt;
      SMTPHOST = &#039;localhost&#039;&lt;br /&gt;
      SMTPPORT = 4587 &lt;br /&gt;
      SMTP_AUTH = True&lt;br /&gt;
      SMTP_USER = &#039;xyz00-listen&#039;&lt;br /&gt;
      SMTP_PASSWD = &#039;das-passwort-des-o.-g.-users&#039;&lt;br /&gt;
      SMTP_USE_TLS = True&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
In &amp;lt;tt&amp;gt;~/mailman/Mailman/Defaults.py&amp;lt;/tt&amp;gt; sieht man, was in mm_cfg.py alles angepasst werden kann.&lt;br /&gt;
&lt;br /&gt;
==== Mailman gegen Subscription Spam härten ====&lt;br /&gt;
&lt;br /&gt;
Mailman wird gelegentlich von böswilligen Crackern benutzt, die damit sogenannten Subscription Spam erzeugen. Dabei wird eine Mailadresse von Bots an Mailman zur Eintragung übergeben. Diese Mailadresse wird daraufhin brav von Mailman angeschrieben. Wenn das tausende von Mailmans auf der ganzen Welt zugleich machen, wird die Mailadresse zugespammt. Hier ist die Abhilfe:&lt;br /&gt;
&lt;br /&gt;
Die Idee kommt von https://www.ralfj.de/blog/2018/06/02/mailman-subscription-spam.html&lt;br /&gt;
&lt;br /&gt;
Auf der Kommandozeile ein zufälliges Secret-String erstellen:&lt;br /&gt;
 openssl rand -base64 18&lt;br /&gt;
&lt;br /&gt;
Und dann in die Konfigurationsdatei den erzeugten String einfügen:&lt;br /&gt;
&lt;br /&gt;
 SUBSCRIBE_FORM_SECRET = &#039;&amp;lt;Secret-String&amp;gt;&#039;&lt;br /&gt;
&lt;br /&gt;
=== CGI-Programme in die Domain kopieren ===&lt;br /&gt;
&lt;br /&gt;
Bei der Installation als Paketuser (xyz00-listen):&lt;br /&gt;
&lt;br /&gt;
Die fertig kompilierten CGIs von Mailman müssen in das CGI-Verzeichnis der Domain (oder der Domains), auf der das Webfrontend von Mailman laufen soll, kopiert werden. Symbolische Links sind nicht ausreichend.&lt;br /&gt;
&lt;br /&gt;
 ~$ mkdir ~/doms/listen.example.com/cgi-ssl/mailman&lt;br /&gt;
 ~$ cp mailman/cgi-bin/* doms/listen.example.com/cgi-ssl/mailman/&lt;br /&gt;
&lt;br /&gt;
Zusätzlich muss das sticky-Flag von den kopierten Dateien entfernt werden:&lt;br /&gt;
&lt;br /&gt;
 ~$ chmod g-s ~/doms/listen.example.com/cgi/mailman/*&lt;br /&gt;
&lt;br /&gt;
Bei der Installation als Paketadmin (xyz00): &lt;br /&gt;
&lt;br /&gt;
Die CGI-Programme können im Mailman-Verzeichnis bleiben. Im CGI-Verzeichnis von jeder Domain, auf der das Mailman-Webfrontend laufen soll, werden symbolische Links dazu erstellt: &lt;br /&gt;
&lt;br /&gt;
 ~$ cd doms/listen.example.com/cgi-ssl&lt;br /&gt;
 ~/doms/listen.example.com/cgi-ssl$ ln -s ../../../mailman/cgi-bin mailman&lt;br /&gt;
&lt;br /&gt;
===  Mailman-Icons in die Domains kopieren ===&lt;br /&gt;
&lt;br /&gt;
Die Icons können wahlweise verlinkt oder kopiert werden:&lt;br /&gt;
&lt;br /&gt;
 ~$ cd doms/listen.example.com/htdocs-ssl&lt;br /&gt;
 ~/doms/listen.example.com/htdocs-ssl$ ln -s ../../../mailman/icons&lt;br /&gt;
&lt;br /&gt;
oder&lt;br /&gt;
&lt;br /&gt;
 ~$ cp -R mailman/icons doms/listen.example.com/htdocs-ssl/&lt;br /&gt;
&lt;br /&gt;
=== Die Datei .htaccess bearbeiten ===&lt;br /&gt;
&lt;br /&gt;
Bei einer dedizierten Mailman-Domain sollte man dafür sorgen, dass Mailman nicht nur unter &amp;lt;tt&amp;gt;&amp;lt;nowiki&amp;gt;https://listen.example.com/cgi-bin/mailman&amp;lt;/nowiki&amp;gt;&amp;lt;/tt&amp;gt;, sondern auch unter &amp;lt;tt&amp;gt;&amp;lt;nowiki&amp;gt;https://listen.example.com/&amp;lt;/nowiki&amp;gt;&amp;lt;/tt&amp;gt;  erreichbar ist.&lt;br /&gt;
&lt;br /&gt;
Dazu werden in &amp;lt;tt&amp;gt;&amp;lt;nowiki&amp;gt;~/doms/listen.example.com/htdocs-ssl/.htaccess&amp;lt;/nowiki&amp;gt;&amp;lt;/tt&amp;gt; folgende Rewrite-Anweisungen eintragen.&lt;br /&gt;
&lt;br /&gt;
 RewriteEngine On&lt;br /&gt;
 RewriteCond	%{REQUEST_URI}		!^/icons/&lt;br /&gt;
 RewriteRule	^(.*)$			/cgi-bin/mailman/$1&lt;br /&gt;
 RewriteRule	^/cgi-bin/mailman/$	/cgi-bin/mailman/listinfo&lt;br /&gt;
&lt;br /&gt;
Beachte dabei die zweite Zeile: Anfragen für Icons sollen &#039;&#039;nicht&#039;&#039; umgeschrieben werden.&lt;br /&gt;
&lt;br /&gt;
Wenn Mailman z.B. auf einer als Unterverzeichnis angelegten Subdomain läuft und unter &amp;lt;tt&amp;gt;&amp;lt;nowiki&amp;gt;https://www.example.com/mailman&amp;lt;/nowiki&amp;gt;&amp;lt;/tt&amp;gt; statt &amp;lt;tt&amp;gt;&amp;lt;nowiki&amp;gt;https://www.example.com/cgi-bin/mailman&amp;lt;/nowiki&amp;gt;&amp;lt;/tt&amp;gt; erreichbar sein soll, hilft folgendes in der &amp;lt;tt&amp;gt;&amp;lt;nowiki&amp;gt;~/doms/example.com/subs-ssl/www/.htaccess&amp;lt;/nowiki&amp;gt;&amp;lt;/tt&amp;gt;:&lt;br /&gt;
&lt;br /&gt;
 RewriteEngine On&lt;br /&gt;
 RewriteCond	%{REQUEST_URI}		!^/icons/&lt;br /&gt;
 RewriteRule    ^mailman/(.*)$          /cgi-bin/mailman/$1&lt;br /&gt;
 RewriteRule    ^/cgi-bin/mailman/$	/cgi-bin/mailman/listinfo&lt;br /&gt;
&lt;br /&gt;
(In diesem Fall kann die Zeile &amp;lt;tt&amp;gt;DEFAULT_URL_PATTERN...&amp;lt;/tt&amp;gt; in der &amp;lt;tt&amp;gt;mm_cfg.py&amp;lt;/tt&amp;gt; auskommentiert werden.)&lt;br /&gt;
&lt;br /&gt;
=== Hauptpasswort setzen ===&lt;br /&gt;
&lt;br /&gt;
Das &amp;quot;site password&amp;quot; ist in Mailman eine Art Generalschlüssel: es wird neben dem jeweiligen Admin- oder Moderator-Passwort überall in der Weboberfläche für sämtliche Mailing-Listen akzeptiert. Also vorsichtig wählen! Das &amp;quot;site password&amp;quot; einrichten mit dem Befehl: &lt;br /&gt;
&lt;br /&gt;
 ~$ mailman/bin/mmsitepass&lt;br /&gt;
&lt;br /&gt;
=== Cronjobs einrichten ===&lt;br /&gt;
&lt;br /&gt;
In die [[Cron |Crontab]] werden Befehle eingetragen, um die Mail-Warteschlange abzuarbeiten, Logs zu löschen, usw.:&lt;br /&gt;
&lt;br /&gt;
 # Warteschlange jede Minute bearbeiten:&lt;br /&gt;
 * * * * *	~/mailman/bin/qrunner -o -r All&lt;br /&gt;
 # Verarbeitungslogs in der 47ten Minute jeder Stunde löschen:&lt;br /&gt;
 47 * * * *	rm -f ~/var/mailman/logs/qrunner&lt;br /&gt;
&lt;br /&gt;
Damit übernimmt cron die Funktion des qrunner-Dämons, der normalerweise auf einem Mailman-Server laufen sollte.&lt;br /&gt;
&lt;br /&gt;
Das Logfile wird stündlich gelöscht, da es sonst sehr schnell sehr groß wird. Falls Mailman von einem Paketuser (bspw. &amp;quot;xyz00-listen&amp;quot;) installiert wurde, sollte die letzte Zeile im Beispiel oben so lauten:&lt;br /&gt;
&lt;br /&gt;
 47 * * * * rm -f ~/mailman/var/logs/qrunner&lt;br /&gt;
&lt;br /&gt;
... entsprechend dem beim Konfigurieren angegebenen &amp;lt;tt&amp;gt;var&amp;lt;/tt&amp;gt;-Verzeichnis, siehe oben.&lt;br /&gt;
&lt;br /&gt;
Zudem müssen noch die von Mailman ohnehin vorgesehenen cron-Aufträge aus &amp;lt;tt&amp;gt;~/mailman/cron/crontab.in&amp;lt;/tt&amp;gt; dem crontab des Users angehängt werden:&lt;br /&gt;
&lt;br /&gt;
 crontab -l &amp;gt; mycronjobs.tmp&lt;br /&gt;
 cat ~/mailman/cron/crontab.in &amp;gt;&amp;gt; mycronjobs.tmp&lt;br /&gt;
 crontab mycronjobs.tmp&lt;br /&gt;
&lt;br /&gt;
== Mailinglisten einrichten ==&lt;br /&gt;
&lt;br /&gt;
Jetzt läuft die Software; nun können die eigentlichen Verteiler angelegt werden. Als erster &#039;&#039;&#039;muß&#039;&#039;&#039; ein Hauptverteiler (&amp;quot;site list&amp;quot;) eingerichtet werden. Dieser Verteiler dient u.a. als Absender der Paßwort-Erinnerungen an die Abonnenten aller Mailinglisten. Er hat standardmäßig den Namen &amp;quot;mailman&amp;quot;. Falls ein anderer Name verwendet werden soll, muß dieser mit der Anweisung &lt;br /&gt;
&lt;br /&gt;
 MAILMAN_SITE_LIST = &#039;sitelistname&#039;&lt;br /&gt;
&lt;br /&gt;
in der Konfigurationsdatei &amp;lt;tt&amp;gt;mailman/Mailman/mm_cfg.py&amp;lt;/tt&amp;gt; eingetragen werden.&lt;br /&gt;
&lt;br /&gt;
=== Den Hauptverteiler &amp;quot;mailman&amp;quot; anlegen ===&lt;br /&gt;
&lt;br /&gt;
Die &amp;quot;site list&amp;quot; mit dem Namen &amp;quot;mailman&amp;quot; ist die Mailingliste der lokalen Mailman-Administratoren. Sie wird zur einwandfreien Funktion von Mailman benötigt.&lt;br /&gt;
&lt;br /&gt;
Mit dem Mailman-Befehl newlist den Verteiler anlegen:&lt;br /&gt;
&lt;br /&gt;
 ~$ mailman/bin/newlist mailman&lt;br /&gt;
 Enter the email of the person running the list: admin@xyz00.hostsharing.net&lt;br /&gt;
 Initial mailman password:&lt;br /&gt;
&lt;br /&gt;
(Der Befehl newlist kann – alternativ zur Weboberfläche – später benutzt werden, um gewöhnliche Mailinglisten anzulegen.)&lt;br /&gt;
&lt;br /&gt;
Nur dieses eine Mal für die &amp;quot;site list&amp;quot; müssen wir die Konfigurationsvorgaben laden. (Gewöhnliche Mailinglisten werden später über die Weboberfläche konfiguriert.)&lt;br /&gt;
&lt;br /&gt;
Falls mailman vom Paketuser (bspw. &amp;quot;xyz00-listen&amp;quot;) installiert wurde:&lt;br /&gt;
&lt;br /&gt;
 ~$ mailman/bin/config_list -i ~/mailman/var/data/sitelist.cfg mailman&lt;br /&gt;
&lt;br /&gt;
Falls mailman vom Paketadmin (&amp;quot;xyz00&amp;quot;) installiert wurde:&lt;br /&gt;
&lt;br /&gt;
 ~$ mailman/bin/config_list -i ~/var/mailman/data/sitelist.cfg mailman&lt;br /&gt;
&lt;br /&gt;
Diese Konfigurationsdatei soll &#039;&#039;&#039;nicht&#039;&#039;&#039; auf gewöhnliche Mailinglisten anwendet werden.&lt;br /&gt;
&lt;br /&gt;
=== E-Mail Adressen bei Mailman einrichten ===&lt;br /&gt;
&lt;br /&gt;
Sobald ein neuer Verteiler angelegt worden ist, sendet Mailman eine E-Mail an den dabei eingetragenen Listenadministrator. Diese E-Mail enthält die Anweisung, E-Mail-Aliases für den neuen Verteiler und für die verschiedenen Mailman-Funktionen anzulegen. Bei Hostsharing wird die Zustellung von E-Mails an Mailman anders geregelt: alle E-Mails an Mailman werden an erweiterte &#039;&#039;E-Mail-Adressen&#039;&#039; des Mailman-Users xyz00-listen geschickt. Diese Adressen haben die form &amp;lt;tt&amp;gt;xyz00-listen&#039;&#039;&#039;+&#039;&#039;&#039;&amp;lt;liste&amp;gt;[_funktion]&amp;lt;/tt&amp;gt;. E-Mails an diese Adressen werden dann durch Pipe-Anweisungen in &#039;&#039;.forward-Dateien&#039;&#039; im Home-Verzeichnis des Mailman-Users mit den entsprechenden Argumenten an Mailman übergeben. &lt;br /&gt;
&lt;br /&gt;
Falls Mailman von einem Paketuser (bspw. &amp;quot;xyz00-listen&amp;quot;) installiert wurde, werden  &#039;&#039;E-Mail-Adressen&#039;&#039; durch [https://doc.hostsharing.net/users/administration/hsadmin/index.html hsadmin (bzw. das Befehlszeilentool hsscript)] eingerichtet; die &#039;&#039;.forward-Dateien&#039;&#039; werden durch [[Login_mit_SSH|Shell-Befehle]] angelegt.&lt;br /&gt;
&lt;br /&gt;
Das folgende Beispiel zeigt die Befehle, mit denen in einer interaktiven hsscript-Sitzung die E-Mail-Adressen für die Hauptliste &amp;quot;mailman&amp;quot; eingerichtet werden. (Für spätere Mailinglisten wird in den Argumenten &amp;quot;mailman&amp;quot; durch den Namen der Mailingliste ersetzt.)&lt;br /&gt;
&lt;br /&gt;
   hsscript -u xyz00 -i&lt;br /&gt;
   [hsscript verlangt die Eingabe des Passworts vom Paketadmin xyz00; dann können diese Befehle eingegeben werden:]&lt;br /&gt;
   emailaddress.add ({set:{domain:&#039;listen.example.com&#039;,localpart:&#039;mailman&#039;,target:&#039;xyz00-listen+mailman&#039;}})&lt;br /&gt;
   emailaddress.add ({set:{domain:&#039;listen.example.com&#039;,localpart:&#039;mailman-admin&#039;,target:&#039;xyz00-listen+mailman-admin&#039;}})&lt;br /&gt;
   emailaddress.add ({set:{domain:&#039;listen.example.com&#039;,localpart:&#039;mailman-bounces&#039;,target:&#039;xyz00-listen+mailman-bounces&#039;}})&lt;br /&gt;
   emailaddress.add ({set:{domain:&#039;listen.example.com&#039;,localpart:&#039;mailman-confirm&#039;,target:&#039;xyz00-listen+mailman-confirm&#039;}})&lt;br /&gt;
   emailaddress.add ({set:{domain:&#039;listen.example.com&#039;,localpart:&#039;mailman-join&#039;,target:&#039;xyz00-listen+mailman-join&#039;}})&lt;br /&gt;
   emailaddress.add ({set:{domain:&#039;listen.example.com&#039;,localpart:&#039;mailman-leave&#039;,target:&#039;xyz00-listen+mailman-leave&#039;}})&lt;br /&gt;
   emailaddress.add ({set:{domain:&#039;listen.example.com&#039;,localpart:&#039;mailman-owner&#039;,target:&#039;xyz00-listen+mailman-owner&#039;}})&lt;br /&gt;
   emailaddress.add ({set:{domain:&#039;listen.example.com&#039;,localpart:&#039;mailman-request&#039;,target:&#039;xyz00-listen+mailman-request&#039;}})&lt;br /&gt;
   emailaddress.add ({set:{domain:&#039;listen.example.com&#039;,localpart:&#039;mailman-subscribe&#039;,target:&#039;xyz00-listen+mailman-subscribe&#039;}})&lt;br /&gt;
   emailaddress.add ({set:{domain:&#039;listen.example.com&#039;,localpart:&#039;mailman-unsubscribe&#039;,target:&#039;xyz00-listen+mailman-unsubscribe&#039;}})&lt;br /&gt;
&lt;br /&gt;
Die korrekte Einrichtung der E-Mail-Adressen kann in der Web-Oberfläche von hsadmin kontrolliert werden.&lt;br /&gt;
&lt;br /&gt;
Für jede der soeben eingerichteten Adressen wird nun eine &amp;lt;tt&amp;gt;.forward&amp;lt;/tt&amp;gt;-Datei im Homeverzeichnis des Users xyz00-listen angelegt. Die Dateinamen bestehen aus der Zeichenfolge &amp;lt;tt&amp;gt;.forward+&amp;lt;/tt&amp;gt; gefolgt vom Namen der ausführen soll. Der Inhalt der jeweiligen &amp;lt;tt&amp;gt;.forward&amp;lt;/tt&amp;gt;-Datei legt die Weiterleitung der Mail durch einen Pipe an Mailman fest, mit dem jeweiligen Befehl als Argument:&lt;br /&gt;
&lt;br /&gt;
   &amp;quot;|/home/pacs/xyz00/users/listen/mailman/mail/mailman [Befehl] [Listenname]&amp;quot;&lt;br /&gt;
&lt;br /&gt;
Zum Beispiel wird die &amp;lt;tt&amp;gt;.forward&amp;lt;/tt&amp;gt;-Datei .forward+mailman-subscribe verwendet, wenn eine E-Mail an die Adresse &amp;lt;tt&amp;gt;mailman-subscribe@listen.example.com&amp;lt;/tt&amp;gt; eingeht. Aufgrund der oben eingerichteten E-Mail-Adresse mit dem Ziel &amp;lt;tt&amp;gt;xyz00-listen+mailman-subscribe&amp;lt;/tt&amp;gt; wertet der Mail-Transfer-Agent die &amp;lt;tt&amp;gt;.forward&amp;lt;/tt&amp;gt;-Datei &amp;lt;tt&amp;gt;.forward+mailman-subscribe&amp;lt;/tt&amp;gt; im Home-Verzeichnis des Users xyz00-listen aus, und entsprechend ihrem Inhalt wird die Mail an die Mailman-Software mit den Argumenten &amp;quot;subscribe mailman&amp;quot; übergeben.&lt;br /&gt;
&lt;br /&gt;
Das folgende Beispiel zeigt die Befehle, mit denen an der Befehlszeilenaufforderung der Shell die &amp;lt;tt&amp;gt;.forward&amp;lt;/tt&amp;gt;-Dateien für die Hauptliste &amp;quot;mailman&amp;quot; eingerichtet werden. (Für spätere Mailinglisten wird in den Argumenten und in den Namen der &amp;lt;tt&amp;gt;.forward&amp;lt;/tt&amp;gt;-Dateien &amp;quot;mailman&amp;quot; durch den Namen der Mailingliste ersetzt, jedoch &#039;&#039;&#039;nicht&#039;&#039;&#039; in der Pfadangabe zum Mailman-Programm selbst; diese ändert sich ja nicht.)&lt;br /&gt;
&lt;br /&gt;
 echo &#039;admin@xyz00.hostsharing.net&#039; &amp;gt; .forward # Weiterleitung von cron Fehlern etc an Paketadmin.&lt;br /&gt;
 echo &#039;&amp;quot;|/home/pacs/xyz00/users/listen/mailman/mail/mailman post mailman&amp;quot;&#039; &amp;gt; .forward+mailman&lt;br /&gt;
 echo &#039;&amp;quot;|/home/pacs/xyz00/users/listen/mailman/mail/mailman admin mailman&amp;quot;&#039; &amp;gt; .forward+mailman-admin&lt;br /&gt;
 echo &#039;&amp;quot;|/home/pacs/xyz00/users/listen/mailman/mail/mailman bounces mailman&amp;quot;&#039; &amp;gt; .forward+mailman-bounces&lt;br /&gt;
 echo &#039;&amp;quot;|/home/pacs/xyz00/users/listen/mailman/mail/mailman confirm mailman&amp;quot;&#039; &amp;gt; .forward+mailman-confirm&lt;br /&gt;
 echo &#039;&amp;quot;|/home/pacs/xyz00/users/listen/mailman/mail/mailman join mailman&amp;quot;&#039; &amp;gt; .forward+mailman-join&lt;br /&gt;
 echo &#039;&amp;quot;|/home/pacs/xyz00/users/listen/mailman/mail/mailman leave mailman&amp;quot;&#039; &amp;gt; .forward+mailman-leave&lt;br /&gt;
 echo &#039;&amp;quot;|/home/pacs/xyz00/users/listen/mailman/mail/mailman owner mailman&amp;quot;&#039; &amp;gt; .forward+mailman-owner&lt;br /&gt;
 echo &#039;&amp;quot;|/home/pacs/xyz00/users/listen/mailman/mail/mailman request mailman&amp;quot;&#039; &amp;gt; .forward+mailman-request&lt;br /&gt;
 echo &#039;&amp;quot;|/home/pacs/xyz00/users/listen/mailman/mail/mailman subscribe mailman&amp;quot;&#039; &amp;gt; .forward+mailman-subscribe&lt;br /&gt;
 echo &#039;&amp;quot;|/home/pacs/xyz00/users/listen/mailman/mail/mailman unsubscribe mailman&amp;quot;&#039; &amp;gt; .forward+mailman-unsubscribe&lt;br /&gt;
&lt;br /&gt;
Die vielen Befehle können von dieser Anleitung kopiert und nach Anpassung auf den tatsächlichen Unsernamen in die SSH-Sitzung kopiert werden. Noch leichter ist es, mit einem Editor einen Shell-Skript namens &amp;lt;tt&amp;gt;~/bin/mailmanaddresses&amp;lt;/tt&amp;gt; mit folgendem Inhalt zu erstellen:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#!/bin/bash&lt;br /&gt;
# Add e-mail addresses and dot-forward files for mailman lists.&lt;br /&gt;
#&lt;br /&gt;
&lt;br /&gt;
# All the sanity checks.&lt;br /&gt;
&lt;br /&gt;
if [ &amp;quot;$3&amp;quot; = &amp;quot;&amp;quot; -o &amp;quot;$2&amp;quot; = &amp;quot;&amp;quot; -o &amp;quot;$1&amp;quot; = &amp;quot;&amp;quot; ] ; then&lt;br /&gt;
    echo &amp;quot;Syntax: $0 listname domainname listowner\n&amp;quot; &lt;br /&gt;
    exit&lt;br /&gt;
fi&lt;br /&gt;
&lt;br /&gt;
if [ &amp;quot;$4&amp;quot; != &amp;quot;&amp;quot; ] ; then&lt;br /&gt;
    echo &amp;quot;Syntax: $0 listname domainname listowner\n&amp;quot; &lt;br /&gt;
    exit&lt;br /&gt;
fi&lt;br /&gt;
&lt;br /&gt;
if [ &amp;quot;`pwd`&amp;quot; != &amp;quot;`echo ~`&amp;quot; ] ; then&lt;br /&gt;
    echo &amp;quot;Run this script from your home directory.\n&amp;quot; &lt;br /&gt;
    exit&lt;br /&gt;
fi&lt;br /&gt;
&lt;br /&gt;
if [ ! -d &amp;quot;../${3:6}&amp;quot; ] ; then&lt;br /&gt;
	echo &amp;quot;There&#039;s no user named $3.&amp;quot;&lt;br /&gt;
	exit&lt;br /&gt;
else&lt;br /&gt;
	echo &amp;quot;You may be asked for a password for $3.&amp;quot;&lt;br /&gt;
fi&lt;br /&gt;
&lt;br /&gt;
if [ ! -d &amp;quot;./mailman/Mailman&amp;quot; ] ; then&lt;br /&gt;
	echo &amp;quot;Are you sure you have a Mailman installation?&amp;quot;&lt;br /&gt;
	exit&lt;br /&gt;
fi&lt;br /&gt;
&lt;br /&gt;
# hsscript fails with a &amp;quot;no result&amp;quot; and 255 if $2 (domain name) is not valid.&lt;br /&gt;
# It also fails if a requested address already exists.&lt;br /&gt;
# scriptexpr contains the expanded variables. Avoid spaces, because it&#039;s unquoted in the hsscript call.&lt;br /&gt;
&lt;br /&gt;
# Add the base list address and its forward file:&lt;br /&gt;
scriptexpr=&amp;quot;emailaddress.add({set:{localpart:\&amp;quot;$1\&amp;quot;,target:\&amp;quot;xyz00-lists+$1\&amp;quot;,domain:\&amp;quot;$2\&amp;quot;}})&amp;quot;&lt;br /&gt;
hsscript -r$3 -u$3 -e $scriptexpr&lt;br /&gt;
if [ &amp;quot;$?&amp;quot; != &amp;quot;0&amp;quot; ] ; then echo &amp;quot;hsscript failed to add address with localpart $1&amp;quot; ; exit ; fi&lt;br /&gt;
echo &amp;quot;\&amp;quot;|/home/pacs/xyz00/users/lists/mailman/mail/mailman post $1\&amp;quot;&amp;quot; &amp;gt; .forward+$1&lt;br /&gt;
if [ &amp;quot;$?&amp;quot; != &amp;quot;0&amp;quot; ] ; then echo &amp;quot;failed to create a forward file for posts&amp;quot; ; exit ; fi&lt;br /&gt;
&lt;br /&gt;
# Now do the same for all the suffixes&lt;br /&gt;
for subpart in admin bounces confirm join leave owner request subscribe unsubscribe&lt;br /&gt;
do&lt;br /&gt;
    scriptexpr=&amp;quot;emailaddress.add({set:{localpart:\&amp;quot;$1-${subpart}\&amp;quot;,target:\&amp;quot;xyz00-lists+$1-${subpart}\&amp;quot;,domain:\&amp;quot;$2\&amp;quot;}})&amp;quot;&lt;br /&gt;
    hsscript -r$3 -u$3 -e $scriptexpr&lt;br /&gt;
    if [ &amp;quot;$?&amp;quot; != &amp;quot;0&amp;quot; ] ; then echo &amp;quot;hsscript failed on subpart ${subpart}&amp;quot; ; exit ; fi&lt;br /&gt;
    echo &amp;quot;\&amp;quot;|/home/pacs/xyz00/users/lists/mailman/mail/mailman $subpart $1\&amp;quot;&amp;quot; &amp;gt; .forward+$1-$subpart&lt;br /&gt;
    if [ &amp;quot;$?&amp;quot; != &amp;quot;0&amp;quot; ] ; then echo &amp;quot;failed to create a forward file for ${subpart}&amp;quot; ; exit ; fi&lt;br /&gt;
done&lt;br /&gt;
&lt;br /&gt;
echo &amp;quot;$0 ran to the end and finished with $?&amp;quot;&lt;br /&gt;
exit&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Der Skript muß natürlich als ausführbar gekennzeichnet werden:&lt;br /&gt;
&lt;br /&gt;
  ~$ chmod u+x bin/mailmanaddresses&lt;br /&gt;
&lt;br /&gt;
Um .&lt;br /&gt;
&lt;br /&gt;
=== Administration ===&lt;br /&gt;
&lt;br /&gt;
Als erstes sollte man als Administrator der neuen Mailman-Installation die Liste &amp;quot;mailman&amp;quot; selbst abonnieren. Die Liste &amp;quot;mailman&amp;quot; kann aber unter &amp;lt;tt&amp;gt;&amp;lt;nowiki&amp;gt;https://listen.example.com/mailman/admin/mailman&amp;lt;/nowiki&amp;gt;&amp;lt;/tt&amp;gt; verwaltet werden.&lt;br /&gt;
&lt;br /&gt;
Die Hauptseite der Mailman-Web-Verwaltung ist in unserem Beispiel (mit den oben angegebenen Rewrite-Anweisungen in der Datei &amp;lt;tt&amp;gt;.htaccess&amp;lt;/tt&amp;gt;) &amp;lt;tt&amp;gt;&amp;lt;nowiki&amp;gt;https://listen.example.com/mailman/admin/&amp;lt;/nowiki&amp;gt;&amp;lt;/tt&amp;gt;. Diese Seite enthält Links zu den bisher eingerichteten Mailinglisten (außer &amp;quot;mailman&amp;quot;) und einen Link, um neue Mailinglisten anzulegen (&amp;lt;tt&amp;gt;&amp;lt;nowiki&amp;gt;https://listen.example.com/mailman/create&amp;lt;/nowiki&amp;gt;&amp;lt;/tt&amp;gt;). Das Anlegen einer neuen Mailingliste geschieht entweder über diesen Link oder (wie oben) in der Shell mit dem Befehl:&lt;br /&gt;
&lt;br /&gt;
 ~$ mailman/bin/newlist &amp;lt;Listenname&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In beiden Fällen müssen zusätzlich die E-Mail-Adressen und die &amp;lt;tt&amp;gt;.forward&amp;lt;/tt&amp;gt;-Dateien wie bei dem Einrichten der Liste &amp;quot;mailman&amp;quot; nach Verfahren im obigen Abschnitt angelegt werden.&lt;br /&gt;
&lt;br /&gt;
Für die Verwaltung der Mailinglisten im Alltag, d.h. den Umgang mit Bounces, Spam, Abonnenten usw., siehe u.a. die [https://wiki.list.org/ Mailman-Wiki].&lt;br /&gt;
&lt;br /&gt;
== Feintuning == &lt;br /&gt;
&lt;br /&gt;
Wer will, kann auch noch etwas Platz sparen. Die normale Mailmaninstallation schlägt mit über 20 MB zu Buche...&lt;br /&gt;
&lt;br /&gt;
Mit den folgenden Tips kann man das auf ca. 6 MB reduzieren :)&lt;br /&gt;
&lt;br /&gt;
Es kann natürlich sein, dass ich zuviel lösche, aber bei mir funktioniert&#039;s. Wenn ihr also sicher(er) sein wollt, dass euch der Mailman nicht um die Ohren fliegt, macht das nicht!&lt;br /&gt;
&lt;br /&gt;
*  ~/mailman/cgi-bin und ~/mailman/icons können gelöscht werden, falls sie an andere Stelle kopiert worden sind.&lt;br /&gt;
* Die nicht benötigten Sprachen in ~/mailman/messages löschen.&lt;br /&gt;
* Die nicht benötigten Sprachen in ~/mailman/templates löschen (bis auf englisch).&lt;br /&gt;
* ~/mailman/tests kann, soweit ich das sehe, komplett gelöscht werden.&lt;br /&gt;
* Falls man koreanisch und japanisch nicht braucht, kann man folgendes machen:&lt;br /&gt;
* in ~/mailman/bin/paths.py, ~/mailman/cron/paths.py und ~/mailman/scripts/paths.py die Zeilen:&lt;br /&gt;
&lt;br /&gt;
 # In a normal interactive Python environment, the japanese.pth and korean.pth&lt;br /&gt;
 # files would be imported automatically.  But because we inhibit the importing&lt;br /&gt;
 # of the site module, we need to be explicit about importing these codecs.&lt;br /&gt;
 if not jaok:&lt;br /&gt;
     import japanese&lt;br /&gt;
 # As of KoreanCodecs 2.0.5, you had to do the second import to get the Korean&lt;br /&gt;
 # codecs installed, however leave the first import in there in case an upgrade&lt;br /&gt;
 # changes this.&lt;br /&gt;
 if not kook:&lt;br /&gt;
     import korean&lt;br /&gt;
     import korean.aliases&lt;br /&gt;
&lt;br /&gt;
auskommentieren.&lt;br /&gt;
&lt;br /&gt;
Dann kann man ~/mailman/pythonlib/japanese, ~/mailman/pythonlib/korean, ~/mailman/pythonlib/korean.pth sowie ~/mailman/pythonlib/lib löschen.&lt;br /&gt;
   &lt;br /&gt;
Man kann auch noch die Debug-Informationen aus den binaries strippen:&lt;br /&gt;
&lt;br /&gt;
 strip ~/mailman/mail/mailman&lt;br /&gt;
 strip ~/mailman/cgi-bin/*&lt;br /&gt;
&lt;br /&gt;
Falls die CGIs nicht gesymlinkt wurden:&lt;br /&gt;
&lt;br /&gt;
 strip ~/doms/listen.example.com/cgi/mailman/*&lt;br /&gt;
&lt;br /&gt;
== Multidomainfähigkeit ==&lt;br /&gt;
&lt;br /&gt;
Seit Mailman 2.x kann eine Mailman-Installation unter gewissen Einschränkungen für mehrere Domains verwendet werden. Hier soll kurz gezeigt werden, was geht und wie es geht.&lt;br /&gt;
&lt;br /&gt;
=== Anleitung ===&lt;br /&gt;
&lt;br /&gt;
Logischerweise muss das Webfrontend (die CGIs) auf allen Domains installiert werden.&lt;br /&gt;
&lt;br /&gt;
Wenn man nun Mailinglisten mit newlist neu anlegt, muss man den Hostnamen für das Webfontend mit angeben, und zwar so:&lt;br /&gt;
&lt;br /&gt;
 ~$ mailman/bin/newlist listenname@listen.example.com&lt;br /&gt;
&lt;br /&gt;
Es ist ggf. wichtig, dass in der mm_cfg.py eine entsprechende add_virtualhost-Direktive für www.example.com steht, die der Frontend-URL einen Host-Part für die Mailadressen zuordnet. Ist eine solche Direktive nicht vorhanden, so wird listen.example.com sowohl als URL für das Webfrontend wie auch als Hostpart für E-Mailadressen verwendet. (Was für separate aufgeschaltete Domains wie z.B. listen.example.com gerade zutrifft.)&lt;br /&gt;
&lt;br /&gt;
Liegt das Frondend nicht auf der Maildomain ist es wichtig, dass ihr Mailman sagt, für welches die zugehörige Maildomain ist. Dies tut ihr in der Datei ~/mailman/Mailman/mm_cfg.py:&lt;br /&gt;
&lt;br /&gt;
Also z.B.&lt;br /&gt;
 DEFAULT_URL_HOST = &#039;www.example.com&#039;&lt;br /&gt;
 DEFAULT_EMAIL_HOST = &#039;listen.example.com&#039;&lt;br /&gt;
 add_virtualhost(DEFAULT_URL_HOST,DEFAULT_EMAIL_HOST)&lt;br /&gt;
&lt;br /&gt;
und&lt;br /&gt;
 add_virtualhost(&#039;www.zoopnet.de&#039;, &#039;lists.zoopnet.de&#039;)&lt;br /&gt;
&lt;br /&gt;
Das bedeutet, dass Mailman per default davon ausgeht, dass alle Listen für die Domain example.com sind.&lt;br /&gt;
Alle weiteren add_virtualhost-Direktiven ordnen einem Hostnamen für das Webfrontend (z.B. www.zoopnet.de) einen Hostpart für die Adresse der Mailinglisten (z.B. lists.zoopnet.de) zu.&lt;br /&gt;
&lt;br /&gt;
Tip von Raimund Specht: Lässt man den zweiten Parameter weg, also schreibt z.B. add_virtualhost(&#039;www.example.org&#039;), dann benutzt Mailman als Hostpart alles was nach dem ersten Punkt steht, hier also example.org als Maildomain.&lt;br /&gt;
 &lt;br /&gt;
&lt;br /&gt;
Prinzipiell war&#039;s das. Man muss die Listeneinträge natürlich immer in die richtige virtusertable eintragen, und für gleichnamige Mailinglisten auf verschiedenen Domains (mailman@*) verschidene +Ergänzungen bzw. aliase verwenden. :)&lt;br /&gt;
&lt;br /&gt;
=== Probleme ===&lt;br /&gt;
&lt;br /&gt;
Verschiedene Listen mit gleichem Namen (also z.B. liste@example1.com und liste@example2.com) sind mit Mailman 2.1 leider nicht möglich.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Tips und Tricks ==&lt;br /&gt;
&lt;br /&gt;
=== URL Änderungen ===&lt;br /&gt;
Nach URL Änderungen stimmen Links im Web-Interface nicht mehr und Listen werden nicht mehr angezeigt.&lt;br /&gt;
Es sind dann, zusätzlich zur Anpassung der mm_cfg.py, schon bestehende Listen und Archive mit folgendem Befehl zu aktualisieren:&lt;br /&gt;
 ~/mailman/bin/withlist -l -r fix_url &amp;lt;Listen_Name&amp;gt; -v -u &amp;lt;Neue_Url&amp;gt;&lt;br /&gt;
&amp;lt;Listen_Name&amp;gt; steht für die Mailingliste, die bearbeitet werden soll. &amp;lt;Neue_Url&amp;gt; für die neue URL/Webadresse des Webinterfaces.&lt;br /&gt;
&lt;br /&gt;
=== Weitere Cron-Jobs zur Mailinglisten Verwaltung ===&lt;br /&gt;
&lt;br /&gt;
Folgende Cronjobs helfen bei der Verwaltung und sind User freundlich:&lt;br /&gt;
&lt;br /&gt;
&amp;lt; In Arbeit &amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Referenzen ==&lt;br /&gt;
&lt;br /&gt;
Lösung zur installation als Domainadmin (xyz00-listen) statt Paketadmin (xyz00): https://lists.hostsharing.net/archiv/support/2009-June/019414.html&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Ältere Anleitung für Installation als Domain-Admin (xyz00-listen): &amp;lt;http://lists.hostsharing.net/archiv/support/2005-January/012426.html&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;quot;Kleine Tools&amp;quot; auf http://hs.andreasloesch.de/, wobei das &#039;pac-mm-install&#039; wahrscheinlich nicht aktuell (genug) ist&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
[[Kategorie:HSDoku]]&lt;br /&gt;
[[Kategorie:Installationsanleitungen]]&lt;br /&gt;
[[Kategorie:Software]]&lt;br /&gt;
[[Kategorie:Mailinglisten]]&lt;br /&gt;
[[Kategorie:E-Mail]]&lt;br /&gt;
[[Kategorie:Python]]&lt;/div&gt;</summary>
		<author><name>Apc00-tony</name></author>
	</entry>
	<entry>
		<id>https://wiki.hostsharing.net/index.php?title=Mailman_Installieren&amp;diff=6274</id>
		<title>Mailman Installieren</title>
		<link rel="alternate" type="text/html" href="https://wiki.hostsharing.net/index.php?title=Mailman_Installieren&amp;diff=6274"/>
		<updated>2023-11-10T17:03:05Z</updated>

		<summary type="html">&lt;p&gt;Apc00-tony: /* E-Mail Adressen bei Mailman einrichten */ Updated script&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Vorab: Die Wahl von Mailman 2 ==&lt;br /&gt;
&lt;br /&gt;
Mailman 2 hängt von Python 2.7 ab und wird damit voraussichtlich nur noch eine begrenzte Nutzungsdauer haben. Mailman 3 ist jetzt verfügbar (siehe [[Mailman_3_installieren]]), aber deutlich schwerer und komplexer im Betrieb. Es gibt auch weniger leistungsfähige Software, um E-Mail-Verteiler zu betreiben, wie beispielsweise [[mlmmj]]. Für eine Diskussion der Situation im Oktober 2019, siehe das HS-Support-Archiv ab [https://lists.hostsharing.net/archiv/support/2019-October/067243.html hier.]&lt;br /&gt;
&lt;br /&gt;
== Mailman 2 installieren == &lt;br /&gt;
&lt;br /&gt;
(zuletzt getestet mit mailman-2.1.29; Installation durch Paketuser)&lt;br /&gt;
&lt;br /&gt;
Vielen Dank an alle Benutzer, die Verbesserungen beisteuern!&lt;br /&gt;
&lt;br /&gt;
=== Unter welchem Account installieren? ===&lt;br /&gt;
&lt;br /&gt;
Mailman kann vom Paketadmin (beipsielsweise &amp;quot;xyz00&amp;quot;) oder von einem Paketuser (bspw. &amp;quot;xyz00-listen&amp;quot;) installiert werden. Letzteres ist dringend empfohlen, denn wenn Mailman vom Paketadmin installiert wird, haben ausnahmslos alle Paketuser direkten Zugriff auf die Mailman-Daten, und bei Sicherheitslücken in Mailman wäre eventuell eine Rechte-Eskalierung auf Paketadmin-Ebene potentiell zu befürchten.&lt;br /&gt;
&lt;br /&gt;
Dem Paketuser, unter dem Mailman installiert wird, können mehrere Subdomains aufschaltet werden, und Mailinglisten können auch die Domainnamen verwenden, die anderen Paketusern gehören.&lt;br /&gt;
&lt;br /&gt;
Vorteil der Installation als Paketuser ist, dass nur dieser direkten Zugriff auf die Mailmandaten hat und mailman ohne Paketadminrechte läuft. Während der Emailauslieferung gelten (wie immer bei der Mailweiterleitung durch .forward-Dateien oder durch procmail) die Rechte des Paketusers, dem die Mailman-Installation gehört.&lt;br /&gt;
&lt;br /&gt;
Nachteil der Installation als Paketuser ist lediglich, dass die Paketdomain mit dem SSL Zertifikat von Hostsharing nicht genutzt werden kann.&amp;lt;!-- Aktualisieren? --&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Einen User und eine Domain anlegen ===&lt;br /&gt;
&lt;br /&gt;
Unter admin.hostsharing.net als xyz00 anmelden; den User xyz00-listen erzeugen; die Domain listen.example.com mit &amp;quot;Domain-User&amp;quot; xyz00-listen anlegen. Aus admin.hostsharing.net abmelden.&lt;br /&gt;
&lt;br /&gt;
Mit [[Login_mit_SSH|SSH]] an hostsharing.net als xyz00-listen anmelden. Die Redirect-Zeile aus &amp;lt;tt&amp;gt;&amp;lt;nowiki&amp;gt;~/doms/listen.example.com/htdocs-ssl/.htaccess&amp;lt;/nowiki&amp;gt;&amp;lt;/tt&amp;gt; löschen:&lt;br /&gt;
&lt;br /&gt;
 ~$ echo &amp;quot;&amp;quot; &amp;gt; ~/doms/listen.example.com/htdocs-ssl/.htaccess&lt;br /&gt;
&lt;br /&gt;
Die Default-Subdomains www.* löschen:&lt;br /&gt;
&lt;br /&gt;
   ~$ rm -r doms/listen.example.com/subs/www/&lt;br /&gt;
   ~$ rm -r doms/listen.example.com/subs-ssl/www/&lt;br /&gt;
&lt;br /&gt;
=== Sourcen besorgen und entpacken ===&lt;br /&gt;
&lt;br /&gt;
Unter http://www.gnu.org/software/mailman/ die aktuelle Software besorgen. Dort findet sich ein Link zu den 2er-Versionen von Mailman (http://ftp.gnu.org/gnu/mailman/). Die letzte Version downloaden ...&lt;br /&gt;
&lt;br /&gt;
 ~$ wget http://ftp.gnu.org/gnu/mailman/mailman-2.1.29.tgz&lt;br /&gt;
&lt;br /&gt;
... und entpacken:&lt;br /&gt;
&lt;br /&gt;
 ~$ tar -xzvf mailman-2.1.29.tgz&lt;br /&gt;
&lt;br /&gt;
Ab diesem Augenblick gibt es ein Verzeichnis namens &amp;lt;tt&amp;gt;mailman-2.1.29/&amp;lt;/tt&amp;gt;. Darin liegt die nunmehr entpackte &#039;&#039;Quellcode&#039;&#039; der Mailman-Software. Nach dem Kompilieren (folgt unten) wird die fertig kompilierte, gebrauchsfähige Mailman-Software in dem zusätzlich vorhandenen Verzeichnis &amp;lt;tt&amp;gt;mailman/&amp;lt;/tt&amp;gt; liegen. (Dieses Verzeichnis wird beim Konfigurieren der Source als &amp;quot;prefix&amp;quot; angegeben.)&lt;br /&gt;
&lt;br /&gt;
=== var-Verzeichnis für Log-Dateien anlegen ===&lt;br /&gt;
&lt;br /&gt;
Bei der Installation als Paketuser (xyz00-listen):&lt;br /&gt;
 ~$ cd &amp;amp;&amp;amp; mkdir -p mailman/var&lt;br /&gt;
 ~$ chmod 02775 mailman/var&lt;br /&gt;
&lt;br /&gt;
Bei der Installation als Paketadmin (xyz00):&lt;br /&gt;
 ~$ cd &amp;amp;&amp;amp; mkdir var/mailman&lt;br /&gt;
 ~$ chmod 02775 var/mailman&lt;br /&gt;
&lt;br /&gt;
=== Mailman konfigurieren ===&lt;br /&gt;
&lt;br /&gt;
In das Source-Verzeichnis wechseln:&lt;br /&gt;
&lt;br /&gt;
 ~$ cd mailman-2.1.29&lt;br /&gt;
&lt;br /&gt;
Bei der Installation durch den Paketuser (xyz00-listen):&lt;br /&gt;
      ~/mailman-2.1.29$ ./configure --prefix=/home/pacs/xyz00/users/listen/mailman \&lt;br /&gt;
              --with-username=xyz00-listen \&lt;br /&gt;
              --with-groupname=xyz00 \&lt;br /&gt;
              --with-var-prefix=/home/pacs/xyz00/users/listen/mailman/var \&lt;br /&gt;
              --with-cgi-gid=xyz00 \&lt;br /&gt;
              --with-mail-gid=xyz00&lt;br /&gt;
&lt;br /&gt;
Bei der Installation durch den Paketadmin (xyz00):&lt;br /&gt;
      ~/mailman-2.1.29$ ./configure --prefix=/home/pacs/xyz00/mailman \&lt;br /&gt;
              --with-username=xyz00 \&lt;br /&gt;
              --with-groupname=xyz00 \&lt;br /&gt;
              --with-var-prefix=/home/pacs/xyz00/var/mailman \&lt;br /&gt;
              --with-cgi-gid=xyz00 \&lt;br /&gt;
              --with-mail-gid=nogroup&lt;br /&gt;
&lt;br /&gt;
(Die Rückwärtsschrägstriche &amp;quot;\&amp;quot; am Zeilenende bedeuten, dass der Befehl in der nächsten Zeile weitergeht. Alternativ können alle Argumente in eine Zeile getippt werden.)&lt;br /&gt;
&lt;br /&gt;
=== Mailman kompilieren ===&lt;br /&gt;
&lt;br /&gt;
 ~/mailman-2.1.29$ make&lt;br /&gt;
 ~/mailman-2.1.29$ make install&lt;br /&gt;
&lt;br /&gt;
=== Datenrechte prüfen ===&lt;br /&gt;
&lt;br /&gt;
Sicherheitshalber die Dateirechte durch Mailmans mitgeliefertes Tool prüfen und ggf. korrigieren lassen:&lt;br /&gt;
&lt;br /&gt;
 ~/mailman-2.1.29$ cd ..      &lt;br /&gt;
 ~$ mailman/bin/check_perms -f&lt;br /&gt;
&lt;br /&gt;
== Die neue Mailman-Installation konfigurieren ==&lt;br /&gt;
&lt;br /&gt;
=== Konfigurationsdatei &amp;lt;tt&amp;gt;mm_cfg.py&amp;lt;/tt&amp;gt; editieren ===&lt;br /&gt;
&lt;br /&gt;
 ~$ nano mailman/Mailman/mm_cfg.py&lt;br /&gt;
      &lt;br /&gt;
Eine Beispielkonfiguration für listen.example.com könnte so aussehen:&lt;br /&gt;
&lt;br /&gt;
 [...]&lt;br /&gt;
      ##################################################&lt;br /&gt;
      # Put YOUR site-specific settings below this line.&lt;br /&gt;
      # -*- python -*-&lt;br /&gt;
 &lt;br /&gt;
      DEFAULT_HOST_NAME = &#039;listen.example.com&#039;&lt;br /&gt;
      DEFAULT_EMAIL_HOST = &#039;listen.example.com&#039;&lt;br /&gt;
      DEFAULT_URL_HOST = &#039;listen.example.com&#039;&lt;br /&gt;
      add_virtualhost(DEFAULT_URL_HOST, DEFAULT_EMAIL_HOST)&lt;br /&gt;
      add_virtualhost(zweite.listendomain.com, zweite.listendomain.com)&lt;br /&gt;
 &lt;br /&gt;
      DEFAULT_SERVER_LANGUAGE = &#039;de&#039;&lt;br /&gt;
 &lt;br /&gt;
      DEFAULT_URL_PATTERN = &#039;http://%s/&#039;&lt;br /&gt;
  &lt;br /&gt;
      # Es wird der HS Mailversand für Bulkmail verwendet:&lt;br /&gt;
      SMTPHOST = &#039;localhost&#039;&lt;br /&gt;
      SMTPPORT = 4587 &lt;br /&gt;
      SMTP_AUTH = True&lt;br /&gt;
      SMTP_USER = &#039;xyz00-listen&#039;&lt;br /&gt;
      SMTP_PASSWD = &#039;das-passwort-des-o.-g.-users&#039;&lt;br /&gt;
      SMTP_USE_TLS = True&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
In &amp;lt;tt&amp;gt;~/mailman/Mailman/Defaults.py&amp;lt;/tt&amp;gt; sieht man, was in mm_cfg.py alles angepasst werden kann.&lt;br /&gt;
&lt;br /&gt;
==== Mailman gegen Subscription Spam härten ====&lt;br /&gt;
&lt;br /&gt;
Mailman wird gelegentlich von böswilligen Crackern benutzt, die damit sogenannten Subscription Spam erzeugen. Dabei wird eine Mailadresse von Bots an Mailman zur Eintragung übergeben. Diese Mailadresse wird daraufhin brav von Mailman angeschrieben. Wenn das tausende von Mailmans auf der ganzen Welt zugleich machen, wird die Mailadresse zugespammt. Hier ist die Abhilfe:&lt;br /&gt;
&lt;br /&gt;
Die Idee kommt von https://www.ralfj.de/blog/2018/06/02/mailman-subscription-spam.html&lt;br /&gt;
&lt;br /&gt;
Auf der Kommandozeile ein zufälliges Secret-String erstellen:&lt;br /&gt;
 openssl rand -base64 18&lt;br /&gt;
&lt;br /&gt;
Und dann in die Konfigurationsdatei den erzeugten String einfügen:&lt;br /&gt;
&lt;br /&gt;
 SUBSCRIBE_FORM_SECRET = &#039;&amp;lt;Secret-String&amp;gt;&#039;&lt;br /&gt;
&lt;br /&gt;
=== CGI-Programme in die Domain kopieren ===&lt;br /&gt;
&lt;br /&gt;
Bei der Installation als Paketuser (xyz00-listen):&lt;br /&gt;
&lt;br /&gt;
Die fertig kompilierten CGIs von Mailman müssen in das CGI-Verzeichnis der Domain (oder der Domains), auf der das Webfrontend von Mailman laufen soll, kopiert werden. Symbolische Links sind nicht ausreichend.&lt;br /&gt;
&lt;br /&gt;
 ~$ mkdir ~/doms/listen.example.com/cgi-ssl/mailman&lt;br /&gt;
 ~$ cp mailman/cgi-bin/* doms/listen.example.com/cgi-ssl/mailman/&lt;br /&gt;
&lt;br /&gt;
Zusätzlich muss das sticky-Flag von den kopierten Dateien entfernt werden:&lt;br /&gt;
&lt;br /&gt;
 ~$ chmod g-s ~/doms/listen.example.com/cgi/mailman/*&lt;br /&gt;
&lt;br /&gt;
Bei der Installation als Paketadmin (xyz00): &lt;br /&gt;
&lt;br /&gt;
Die CGI-Programme können im Mailman-Verzeichnis bleiben. Im CGI-Verzeichnis von jeder Domain, auf der das Mailman-Webfrontend laufen soll, werden symbolische Links dazu erstellt: &lt;br /&gt;
&lt;br /&gt;
 ~$ cd doms/listen.example.com/cgi-ssl&lt;br /&gt;
 ~/doms/listen.example.com/cgi-ssl$ ln -s ../../../mailman/cgi-bin mailman&lt;br /&gt;
&lt;br /&gt;
===  Mailman-Icons in die Domains kopieren ===&lt;br /&gt;
&lt;br /&gt;
Die Icons können wahlweise verlinkt oder kopiert werden:&lt;br /&gt;
&lt;br /&gt;
 ~$ cd doms/listen.example.com/htdocs-ssl&lt;br /&gt;
 ~/doms/listen.example.com/htdocs-ssl$ ln -s ../../../mailman/icons&lt;br /&gt;
&lt;br /&gt;
oder&lt;br /&gt;
&lt;br /&gt;
 ~$ cp -R mailman/icons doms/listen.example.com/htdocs-ssl/&lt;br /&gt;
&lt;br /&gt;
=== Die Datei .htaccess bearbeiten ===&lt;br /&gt;
&lt;br /&gt;
Bei einer dedizierten Mailman-Domain sollte man dafür sorgen, dass Mailman nicht nur unter &amp;lt;tt&amp;gt;&amp;lt;nowiki&amp;gt;https://listen.example.com/cgi-bin/mailman&amp;lt;/nowiki&amp;gt;&amp;lt;/tt&amp;gt;, sondern auch unter &amp;lt;tt&amp;gt;&amp;lt;nowiki&amp;gt;https://listen.example.com/&amp;lt;/nowiki&amp;gt;&amp;lt;/tt&amp;gt;  erreichbar ist.&lt;br /&gt;
&lt;br /&gt;
Dazu werden in &amp;lt;tt&amp;gt;&amp;lt;nowiki&amp;gt;~/doms/listen.example.com/htdocs-ssl/.htaccess&amp;lt;/nowiki&amp;gt;&amp;lt;/tt&amp;gt; folgende Rewrite-Anweisungen eintragen.&lt;br /&gt;
&lt;br /&gt;
 RewriteEngine On&lt;br /&gt;
 RewriteCond	%{REQUEST_URI}		!^/icons/&lt;br /&gt;
 RewriteRule	^(.*)$			/cgi-bin/mailman/$1&lt;br /&gt;
 RewriteRule	^/cgi-bin/mailman/$	/cgi-bin/mailman/listinfo&lt;br /&gt;
&lt;br /&gt;
Beachte dabei die zweite Zeile: Anfragen für Icons sollen &#039;&#039;nicht&#039;&#039; umgeschrieben werden.&lt;br /&gt;
&lt;br /&gt;
Wenn Mailman z.B. auf einer als Unterverzeichnis angelegten Subdomain läuft und unter &amp;lt;tt&amp;gt;&amp;lt;nowiki&amp;gt;https://www.example.com/mailman&amp;lt;/nowiki&amp;gt;&amp;lt;/tt&amp;gt; statt &amp;lt;tt&amp;gt;&amp;lt;nowiki&amp;gt;https://www.example.com/cgi-bin/mailman&amp;lt;/nowiki&amp;gt;&amp;lt;/tt&amp;gt; erreichbar sein soll, hilft folgendes in der &amp;lt;tt&amp;gt;&amp;lt;nowiki&amp;gt;~/doms/example.com/subs-ssl/www/.htaccess&amp;lt;/nowiki&amp;gt;&amp;lt;/tt&amp;gt;:&lt;br /&gt;
&lt;br /&gt;
 RewriteEngine On&lt;br /&gt;
 RewriteCond	%{REQUEST_URI}		!^/icons/&lt;br /&gt;
 RewriteRule    ^mailman/(.*)$          /cgi-bin/mailman/$1&lt;br /&gt;
 RewriteRule    ^/cgi-bin/mailman/$	/cgi-bin/mailman/listinfo&lt;br /&gt;
&lt;br /&gt;
(In diesem Fall kann die Zeile &amp;lt;tt&amp;gt;DEFAULT_URL_PATTERN...&amp;lt;/tt&amp;gt; in der &amp;lt;tt&amp;gt;mm_cfg.py&amp;lt;/tt&amp;gt; auskommentiert werden.)&lt;br /&gt;
&lt;br /&gt;
=== Hauptpasswort setzen ===&lt;br /&gt;
&lt;br /&gt;
Das &amp;quot;site password&amp;quot; ist in Mailman eine Art Generalschlüssel: es wird neben dem jeweiligen Admin- oder Moderator-Passwort überall in der Weboberfläche für sämtliche Mailing-Listen akzeptiert. Also vorsichtig wählen! Das &amp;quot;site password&amp;quot; einrichten mit dem Befehl: &lt;br /&gt;
&lt;br /&gt;
 ~$ mailman/bin/mmsitepass&lt;br /&gt;
&lt;br /&gt;
=== Cronjobs einrichten ===&lt;br /&gt;
&lt;br /&gt;
In die [[Cron |Crontab]] werden Befehle eingetragen, um die Mail-Warteschlange abzuarbeiten, Logs zu löschen, usw.:&lt;br /&gt;
&lt;br /&gt;
 # Warteschlange jede Minute bearbeiten:&lt;br /&gt;
 * * * * *	~/mailman/bin/qrunner -o -r All&lt;br /&gt;
 # Verarbeitungslogs in der 47ten Minute jeder Stunde löschen:&lt;br /&gt;
 47 * * * *	rm -f ~/var/mailman/logs/qrunner&lt;br /&gt;
&lt;br /&gt;
Damit übernimmt cron die Funktion des qrunner-Dämons, der normalerweise auf einem Mailman-Server laufen sollte.&lt;br /&gt;
&lt;br /&gt;
Das Logfile wird stündlich gelöscht, da es sonst sehr schnell sehr groß wird. Falls Mailman von einem Paketuser (bspw. &amp;quot;xyz00-listen&amp;quot;) installiert wurde, sollte die letzte Zeile im Beispiel oben so lauten:&lt;br /&gt;
&lt;br /&gt;
 47 * * * * rm -f ~/mailman/var/logs/qrunner&lt;br /&gt;
&lt;br /&gt;
... entsprechend dem beim Konfigurieren angegebenen &amp;lt;tt&amp;gt;var&amp;lt;/tt&amp;gt;-Verzeichnis, siehe oben.&lt;br /&gt;
&lt;br /&gt;
Zudem müssen noch die von Mailman ohnehin vorgesehenen cron-Aufträge aus &amp;lt;tt&amp;gt;~/mailman/cron/crontab.in&amp;lt;/tt&amp;gt; dem crontab des Users angehängt werden:&lt;br /&gt;
&lt;br /&gt;
 crontab -l &amp;gt; mycronjobs.tmp&lt;br /&gt;
 cat ~/mailman/cron/crontab.in &amp;gt;&amp;gt; mycronjobs.tmp&lt;br /&gt;
 crontab mycronjobs.tmp&lt;br /&gt;
&lt;br /&gt;
== Mailinglisten einrichten ==&lt;br /&gt;
&lt;br /&gt;
Jetzt läuft die Software; nun können die eigentlichen Verteiler angelegt werden. Als erster &#039;&#039;&#039;muß&#039;&#039;&#039; ein Hauptverteiler (&amp;quot;site list&amp;quot;) eingerichtet werden. Dieser Verteiler dient u.a. als Absender der Paßwort-Erinnerungen an die Abonnenten aller Mailinglisten. Er hat standardmäßig den Namen &amp;quot;mailman&amp;quot;. Falls ein anderer Name verwendet werden soll, muß dieser mit der Anweisung &lt;br /&gt;
&lt;br /&gt;
 MAILMAN_SITE_LIST = &#039;sitelistname&#039;&lt;br /&gt;
&lt;br /&gt;
in der Konfigurationsdatei &amp;lt;tt&amp;gt;mailman/Mailman/mm_cfg.py&amp;lt;/tt&amp;gt; eingetragen werden.&lt;br /&gt;
&lt;br /&gt;
=== Den Hauptverteiler &amp;quot;mailman&amp;quot; anlegen ===&lt;br /&gt;
&lt;br /&gt;
Die &amp;quot;site list&amp;quot; mit dem Namen &amp;quot;mailman&amp;quot; ist die Mailingliste der lokalen Mailman-Administratoren. Sie wird zur einwandfreien Funktion von Mailman benötigt.&lt;br /&gt;
&lt;br /&gt;
Mit dem Mailman-Befehl newlist den Verteiler anlegen:&lt;br /&gt;
&lt;br /&gt;
 ~$ mailman/bin/newlist mailman&lt;br /&gt;
 Enter the email of the person running the list: admin@xyz00.hostsharing.net&lt;br /&gt;
 Initial mailman password:&lt;br /&gt;
&lt;br /&gt;
(Der Befehl newlist kann – alternativ zur Weboberfläche – später benutzt werden, um gewöhnliche Mailinglisten anzulegen.)&lt;br /&gt;
&lt;br /&gt;
Nur dieses eine Mal für die &amp;quot;site list&amp;quot; müssen wir die Konfigurationsvorgaben laden. (Gewöhnliche Mailinglisten werden später über die Weboberfläche konfiguriert.)&lt;br /&gt;
&lt;br /&gt;
Falls mailman vom Paketuser (bspw. &amp;quot;xyz00-listen&amp;quot;) installiert wurde:&lt;br /&gt;
&lt;br /&gt;
 ~$ mailman/bin/config_list -i ~/mailman/var/data/sitelist.cfg mailman&lt;br /&gt;
&lt;br /&gt;
Falls mailman vom Paketadmin (&amp;quot;xyz00&amp;quot;) installiert wurde:&lt;br /&gt;
&lt;br /&gt;
 ~$ mailman/bin/config_list -i ~/var/mailman/data/sitelist.cfg mailman&lt;br /&gt;
&lt;br /&gt;
Diese Konfigurationsdatei soll &#039;&#039;&#039;nicht&#039;&#039;&#039; auf gewöhnliche Mailinglisten anwendet werden.&lt;br /&gt;
&lt;br /&gt;
=== E-Mail Adressen bei Mailman einrichten ===&lt;br /&gt;
&lt;br /&gt;
Sobald ein neuer Verteiler angelegt worden ist, sendet Mailman eine E-Mail an den dabei eingetragenen Listenadministrator. Diese E-Mail enthält die Anweisung, E-Mail-Aliases für den neuen Verteiler und für die verschiedenen Mailman-Funktionen anzulegen. Bei Hostsharing wird die Zustellung von E-Mails an Mailman anders geregelt: alle E-Mails an Mailman werden an erweiterte &#039;&#039;E-Mail-Adressen&#039;&#039; des Mailman-Users xyz00-listen geschickt. Diese Adressen haben die form &amp;lt;tt&amp;gt;xyz00-listen&#039;&#039;&#039;+&#039;&#039;&#039;&amp;lt;liste&amp;gt;[_funktion]&amp;lt;/tt&amp;gt;. E-Mails an diese Adressen werden dann durch Pipe-Anweisungen in &#039;&#039;.forward-Dateien&#039;&#039; im Home-Verzeichnis des Mailman-Users mit den entsprechenden Argumenten an Mailman übergeben. &lt;br /&gt;
&lt;br /&gt;
Falls Mailman von einem Paketuser (bspw. &amp;quot;xyz00-listen&amp;quot;) installiert wurde, werden  &#039;&#039;E-Mail-Adressen&#039;&#039; durch [https://doc.hostsharing.net/users/administration/hsadmin/index.html hsadmin (bzw. das Befehlszeilentool hsscript)] eingerichtet; die &#039;&#039;.forward-Dateien&#039;&#039; werden durch [[Login_mit_SSH|Shell-Befehle]] angelegt.&lt;br /&gt;
&lt;br /&gt;
Das folgende Beispiel zeigt die Befehle, mit denen in einer interaktiven hsscript-Sitzung die E-Mail-Adressen für die Hauptliste &amp;quot;mailman&amp;quot; eingerichtet werden. (Für spätere Mailinglisten wird in den Argumenten &amp;quot;mailman&amp;quot; durch den Namen der Mailingliste ersetzt.)&lt;br /&gt;
&lt;br /&gt;
   hsscript -u xyz00 -i&lt;br /&gt;
   [hsscript verlangt die Eingabe des Passworts vom Paketadmin xyz00; dann können diese Befehle eingegeben werden:]&lt;br /&gt;
   emailaddress.add ({set:{domain:&#039;listen.example.com&#039;,localpart:&#039;mailman&#039;,target:&#039;xyz00-listen+mailman&#039;}})&lt;br /&gt;
   emailaddress.add ({set:{domain:&#039;listen.example.com&#039;,localpart:&#039;mailman-admin&#039;,target:&#039;xyz00-listen+mailman-admin&#039;}})&lt;br /&gt;
   emailaddress.add ({set:{domain:&#039;listen.example.com&#039;,localpart:&#039;mailman-bounces&#039;,target:&#039;xyz00-listen+mailman-bounces&#039;}})&lt;br /&gt;
   emailaddress.add ({set:{domain:&#039;listen.example.com&#039;,localpart:&#039;mailman-confirm&#039;,target:&#039;xyz00-listen+mailman-confirm&#039;}})&lt;br /&gt;
   emailaddress.add ({set:{domain:&#039;listen.example.com&#039;,localpart:&#039;mailman-join&#039;,target:&#039;xyz00-listen+mailman-join&#039;}})&lt;br /&gt;
   emailaddress.add ({set:{domain:&#039;listen.example.com&#039;,localpart:&#039;mailman-leave&#039;,target:&#039;xyz00-listen+mailman-leave&#039;}})&lt;br /&gt;
   emailaddress.add ({set:{domain:&#039;listen.example.com&#039;,localpart:&#039;mailman-owner&#039;,target:&#039;xyz00-listen+mailman-owner&#039;}})&lt;br /&gt;
   emailaddress.add ({set:{domain:&#039;listen.example.com&#039;,localpart:&#039;mailman-request&#039;,target:&#039;xyz00-listen+mailman-request&#039;}})&lt;br /&gt;
   emailaddress.add ({set:{domain:&#039;listen.example.com&#039;,localpart:&#039;mailman-subscribe&#039;,target:&#039;xyz00-listen+mailman-subscribe&#039;}})&lt;br /&gt;
   emailaddress.add ({set:{domain:&#039;listen.example.com&#039;,localpart:&#039;mailman-unsubscribe&#039;,target:&#039;xyz00-listen+mailman-unsubscribe&#039;}})&lt;br /&gt;
&lt;br /&gt;
Die korrekte Einrichtung der E-Mail-Adressen kann in der Web-Oberfläche von hsadmin kontrolliert werden.&lt;br /&gt;
&lt;br /&gt;
Für jede der soeben eingerichteten Adressen wird nun eine &amp;lt;tt&amp;gt;.forward&amp;lt;/tt&amp;gt;-Datei im Homeverzeichnis des Users xyz00-listen angelegt. Die Dateinamen bestehen aus der Zeichenfolge &amp;lt;tt&amp;gt;.forward+&amp;lt;/tt&amp;gt; gefolgt vom Namen der ausführen soll. Der Inhalt der jeweiligen &amp;lt;tt&amp;gt;.forward&amp;lt;/tt&amp;gt;-Datei legt die Weiterleitung der Mail durch einen Pipe an Mailman fest, mit dem jeweiligen Befehl als Argument:&lt;br /&gt;
&lt;br /&gt;
   &amp;quot;|/home/pacs/xyz00/users/listen/mailman/mail/mailman [Befehl] [Listenname]&amp;quot;&lt;br /&gt;
&lt;br /&gt;
Zum Beispiel wird die &amp;lt;tt&amp;gt;.forward&amp;lt;/tt&amp;gt;-Datei .forward+mailman-subscribe verwendet, wenn eine E-Mail an die Adresse &amp;lt;tt&amp;gt;mailman-subscribe@listen.example.com&amp;lt;/tt&amp;gt; eingeht. Aufgrund der oben eingerichteten E-Mail-Adresse mit dem Ziel &amp;lt;tt&amp;gt;xyz00-listen+mailman-subscribe&amp;lt;/tt&amp;gt; wertet der Mail-Transfer-Agent die &amp;lt;tt&amp;gt;.forward&amp;lt;/tt&amp;gt;-Datei &amp;lt;tt&amp;gt;.forward+mailman-subscribe&amp;lt;/tt&amp;gt; im Home-Verzeichnis des Users xyz00-listen aus, und entsprechend ihrem Inhalt wird die Mail an die Mailman-Software mit den Argumenten &amp;quot;subscribe mailman&amp;quot; übergeben.&lt;br /&gt;
&lt;br /&gt;
Das folgende Beispiel zeigt die Befehle, mit denen an der Befehlszeilenaufforderung der Shell die &amp;lt;tt&amp;gt;.forward&amp;lt;/tt&amp;gt;-Dateien für die Hauptliste &amp;quot;mailman&amp;quot; eingerichtet werden. (Für spätere Mailinglisten wird in den Argumenten und in den Namen der &amp;lt;tt&amp;gt;.forward&amp;lt;/tt&amp;gt;-Dateien &amp;quot;mailman&amp;quot; durch den Namen der Mailingliste ersetzt, jedoch &#039;&#039;&#039;nicht&#039;&#039;&#039; in der Pfadangabe zum Mailman-Programm selbst; diese ändert sich ja nicht.)&lt;br /&gt;
&lt;br /&gt;
 echo &#039;admin@xyz00.hostsharing.net&#039; &amp;gt; .forward # Weiterleitung von cron Fehlern etc an Paketadmin.&lt;br /&gt;
 echo &#039;&amp;quot;|/home/pacs/xyz00/users/listen/mailman/mail/mailman post mailman&amp;quot;&#039; &amp;gt; .forward+mailman&lt;br /&gt;
 echo &#039;&amp;quot;|/home/pacs/xyz00/users/listen/mailman/mail/mailman admin mailman&amp;quot;&#039; &amp;gt; .forward+mailman-admin&lt;br /&gt;
 echo &#039;&amp;quot;|/home/pacs/xyz00/users/listen/mailman/mail/mailman bounces mailman&amp;quot;&#039; &amp;gt; .forward+mailman-bounces&lt;br /&gt;
 echo &#039;&amp;quot;|/home/pacs/xyz00/users/listen/mailman/mail/mailman confirm mailman&amp;quot;&#039; &amp;gt; .forward+mailman-confirm&lt;br /&gt;
 echo &#039;&amp;quot;|/home/pacs/xyz00/users/listen/mailman/mail/mailman join mailman&amp;quot;&#039; &amp;gt; .forward+mailman-join&lt;br /&gt;
 echo &#039;&amp;quot;|/home/pacs/xyz00/users/listen/mailman/mail/mailman leave mailman&amp;quot;&#039; &amp;gt; .forward+mailman-leave&lt;br /&gt;
 echo &#039;&amp;quot;|/home/pacs/xyz00/users/listen/mailman/mail/mailman owner mailman&amp;quot;&#039; &amp;gt; .forward+mailman-owner&lt;br /&gt;
 echo &#039;&amp;quot;|/home/pacs/xyz00/users/listen/mailman/mail/mailman request mailman&amp;quot;&#039; &amp;gt; .forward+mailman-request&lt;br /&gt;
 echo &#039;&amp;quot;|/home/pacs/xyz00/users/listen/mailman/mail/mailman subscribe mailman&amp;quot;&#039; &amp;gt; .forward+mailman-subscribe&lt;br /&gt;
 echo &#039;&amp;quot;|/home/pacs/xyz00/users/listen/mailman/mail/mailman unsubscribe mailman&amp;quot;&#039; &amp;gt; .forward+mailman-unsubscribe&lt;br /&gt;
&lt;br /&gt;
Die vielen Befehle können von dieser Anleitung kopiert und nach Anpassung auf den tatsächlichen Unsernamen in die SSH-Sitzung kopiert werden. Noch leichter ist es, mit einem Editor einen Shell-Skript namens &amp;lt;tt&amp;gt;~/bin/mailmanaddresses&amp;lt;/tt&amp;gt; mit folgendem Inhalt zu erstellen:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#!/bin/bash&lt;br /&gt;
# Add e-mail addresses and dot-forward files for mailman lists.&lt;br /&gt;
#&lt;br /&gt;
&lt;br /&gt;
# All the sanity checks.&lt;br /&gt;
&lt;br /&gt;
if [ &amp;quot;$3&amp;quot; = &amp;quot;&amp;quot; -o &amp;quot;$2&amp;quot; = &amp;quot;&amp;quot; -o &amp;quot;$1&amp;quot; = &amp;quot;&amp;quot; ] ; then&lt;br /&gt;
    echo &amp;quot;Syntax: $0 listname domainname listowner\n&amp;quot; &lt;br /&gt;
    exit&lt;br /&gt;
fi&lt;br /&gt;
&lt;br /&gt;
if [ &amp;quot;$4&amp;quot; != &amp;quot;&amp;quot; ] ; then&lt;br /&gt;
    echo &amp;quot;Syntax: $0 listname domainname listowner\n&amp;quot; &lt;br /&gt;
    exit&lt;br /&gt;
fi&lt;br /&gt;
&lt;br /&gt;
if [ &amp;quot;`pwd`&amp;quot; != &amp;quot;`echo ~`&amp;quot; ] ; then&lt;br /&gt;
    echo &amp;quot;Run this script from your home directory.\n&amp;quot; &lt;br /&gt;
    exit&lt;br /&gt;
fi&lt;br /&gt;
&lt;br /&gt;
if [ ! -d &amp;quot;../${3:6}&amp;quot; ] ; then&lt;br /&gt;
	echo &amp;quot;There&#039;s no user named $3.&amp;quot;&lt;br /&gt;
	exit&lt;br /&gt;
else&lt;br /&gt;
	echo &amp;quot;You may be asked for a password for $3.&amp;quot;&lt;br /&gt;
fi&lt;br /&gt;
&lt;br /&gt;
if [ ! -d &amp;quot;./mailman/Mailman&amp;quot; ] ; then&lt;br /&gt;
	echo &amp;quot;Are you sure you have a Mailman installation?&amp;quot;&lt;br /&gt;
	exit&lt;br /&gt;
fi&lt;br /&gt;
&lt;br /&gt;
# hsscript fails with a &amp;quot;no result&amp;quot; and 255 if $2 (domain name) is not valid.&lt;br /&gt;
# It also fails if a requested address already exists.&lt;br /&gt;
# scriptexpr contains the expanded variables. Avoid spaces, because it&#039;s unquoted in the hsscript call.&lt;br /&gt;
&lt;br /&gt;
# Add the base list address and its forward file:&lt;br /&gt;
scriptexpr=&amp;quot;emailaddress.add({set:{localpart:\&amp;quot;$1\&amp;quot;,target:\&amp;quot;apc00-lists+$1\&amp;quot;,domain:\&amp;quot;$2\&amp;quot;}})&amp;quot;&lt;br /&gt;
hsscript -r$3 -u$3 -e $scriptexpr&lt;br /&gt;
if [ &amp;quot;$?&amp;quot; != &amp;quot;0&amp;quot; ] ; then echo &amp;quot;hsscript failed to add address with localpart $1&amp;quot; ; exit ; fi&lt;br /&gt;
echo &amp;quot;\&amp;quot;|/home/pacs/apc00/users/lists/mailman/mail/mailman post $1\&amp;quot;&amp;quot; &amp;gt; .forward+$1&lt;br /&gt;
if [ &amp;quot;$?&amp;quot; != &amp;quot;0&amp;quot; ] ; then echo &amp;quot;failed to create a forward file for posts&amp;quot; ; exit ; fi&lt;br /&gt;
&lt;br /&gt;
# Now do the same for all the suffixes&lt;br /&gt;
for subpart in admin bounces confirm join leave owner request subscribe unsubscribe&lt;br /&gt;
do&lt;br /&gt;
    scriptexpr=&amp;quot;emailaddress.add({set:{localpart:\&amp;quot;$1-${subpart}\&amp;quot;,target:\&amp;quot;apc00-lists+$1-${subpart}\&amp;quot;,domain:\&amp;quot;$2\&amp;quot;}})&amp;quot;&lt;br /&gt;
    hsscript -r$3 -u$3 -e $scriptexpr&lt;br /&gt;
    if [ &amp;quot;$?&amp;quot; != &amp;quot;0&amp;quot; ] ; then echo &amp;quot;hsscript failed on subpart ${subpart}&amp;quot; ; exit ; fi&lt;br /&gt;
    echo &amp;quot;\&amp;quot;|/home/pacs/apc00/users/lists/mailman/mail/mailman $subpart $1\&amp;quot;&amp;quot; &amp;gt; .forward+$1-$subpart&lt;br /&gt;
    if [ &amp;quot;$?&amp;quot; != &amp;quot;0&amp;quot; ] ; then echo &amp;quot;failed to create a forward file for ${subpart}&amp;quot; ; exit ; fi&lt;br /&gt;
done&lt;br /&gt;
&lt;br /&gt;
echo &amp;quot;$0 ran to the end and finished with $?&amp;quot;&lt;br /&gt;
exit&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Der Skript muß natürlich als ausführbar gekennzeichnet werden:&lt;br /&gt;
&lt;br /&gt;
  ~$ chmod u+x bin/mailmanaddresses&lt;br /&gt;
&lt;br /&gt;
Die Erweiterung dieses Skripts um die &amp;lt;tt&amp;gt;hsscript&amp;lt;/tt&amp;gt;-Befehle wird dem geneigten Leser als Aufgabe überlassen.&lt;br /&gt;
&lt;br /&gt;
=== Administration ===&lt;br /&gt;
&lt;br /&gt;
Als erstes sollte man als Administrator der neuen Mailman-Installation die Liste &amp;quot;mailman&amp;quot; selbst abonnieren. Die Liste &amp;quot;mailman&amp;quot; kann aber unter &amp;lt;tt&amp;gt;&amp;lt;nowiki&amp;gt;https://listen.example.com/mailman/admin/mailman&amp;lt;/nowiki&amp;gt;&amp;lt;/tt&amp;gt; verwaltet werden.&lt;br /&gt;
&lt;br /&gt;
Die Hauptseite der Mailman-Web-Verwaltung ist in unserem Beispiel (mit den oben angegebenen Rewrite-Anweisungen in der Datei &amp;lt;tt&amp;gt;.htaccess&amp;lt;/tt&amp;gt;) &amp;lt;tt&amp;gt;&amp;lt;nowiki&amp;gt;https://listen.example.com/mailman/admin/&amp;lt;/nowiki&amp;gt;&amp;lt;/tt&amp;gt;. Diese Seite enthält Links zu den bisher eingerichteten Mailinglisten (außer &amp;quot;mailman&amp;quot;) und einen Link, um neue Mailinglisten anzulegen (&amp;lt;tt&amp;gt;&amp;lt;nowiki&amp;gt;https://listen.example.com/mailman/create&amp;lt;/nowiki&amp;gt;&amp;lt;/tt&amp;gt;). Das Anlegen einer neuen Mailingliste geschieht entweder über diesen Link oder (wie oben) in der Shell mit dem Befehl:&lt;br /&gt;
&lt;br /&gt;
 ~$ mailman/bin/newlist &amp;lt;Listenname&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In beiden Fällen müssen zusätzlich die E-Mail-Adressen und die &amp;lt;tt&amp;gt;.forward&amp;lt;/tt&amp;gt;-Dateien wie bei dem Einrichten der Liste &amp;quot;mailman&amp;quot; nach Verfahren im obigen Abschnitt angelegt werden.&lt;br /&gt;
&lt;br /&gt;
Für die Verwaltung der Mailinglisten im Alltag, d.h. den Umgang mit Bounces, Spam, Abonnenten usw., siehe u.a. die [https://wiki.list.org/ Mailman-Wiki].&lt;br /&gt;
&lt;br /&gt;
== Feintuning == &lt;br /&gt;
&lt;br /&gt;
Wer will, kann auch noch etwas Platz sparen. Die normale Mailmaninstallation schlägt mit über 20 MB zu Buche...&lt;br /&gt;
&lt;br /&gt;
Mit den folgenden Tips kann man das auf ca. 6 MB reduzieren :)&lt;br /&gt;
&lt;br /&gt;
Es kann natürlich sein, dass ich zuviel lösche, aber bei mir funktioniert&#039;s. Wenn ihr also sicher(er) sein wollt, dass euch der Mailman nicht um die Ohren fliegt, macht das nicht!&lt;br /&gt;
&lt;br /&gt;
*  ~/mailman/cgi-bin und ~/mailman/icons können gelöscht werden, falls sie an andere Stelle kopiert worden sind.&lt;br /&gt;
* Die nicht benötigten Sprachen in ~/mailman/messages löschen.&lt;br /&gt;
* Die nicht benötigten Sprachen in ~/mailman/templates löschen (bis auf englisch).&lt;br /&gt;
* ~/mailman/tests kann, soweit ich das sehe, komplett gelöscht werden.&lt;br /&gt;
* Falls man koreanisch und japanisch nicht braucht, kann man folgendes machen:&lt;br /&gt;
* in ~/mailman/bin/paths.py, ~/mailman/cron/paths.py und ~/mailman/scripts/paths.py die Zeilen:&lt;br /&gt;
&lt;br /&gt;
 # In a normal interactive Python environment, the japanese.pth and korean.pth&lt;br /&gt;
 # files would be imported automatically.  But because we inhibit the importing&lt;br /&gt;
 # of the site module, we need to be explicit about importing these codecs.&lt;br /&gt;
 if not jaok:&lt;br /&gt;
     import japanese&lt;br /&gt;
 # As of KoreanCodecs 2.0.5, you had to do the second import to get the Korean&lt;br /&gt;
 # codecs installed, however leave the first import in there in case an upgrade&lt;br /&gt;
 # changes this.&lt;br /&gt;
 if not kook:&lt;br /&gt;
     import korean&lt;br /&gt;
     import korean.aliases&lt;br /&gt;
&lt;br /&gt;
auskommentieren.&lt;br /&gt;
&lt;br /&gt;
Dann kann man ~/mailman/pythonlib/japanese, ~/mailman/pythonlib/korean, ~/mailman/pythonlib/korean.pth sowie ~/mailman/pythonlib/lib löschen.&lt;br /&gt;
   &lt;br /&gt;
Man kann auch noch die Debug-Informationen aus den binaries strippen:&lt;br /&gt;
&lt;br /&gt;
 strip ~/mailman/mail/mailman&lt;br /&gt;
 strip ~/mailman/cgi-bin/*&lt;br /&gt;
&lt;br /&gt;
Falls die CGIs nicht gesymlinkt wurden:&lt;br /&gt;
&lt;br /&gt;
 strip ~/doms/listen.example.com/cgi/mailman/*&lt;br /&gt;
&lt;br /&gt;
== Multidomainfähigkeit ==&lt;br /&gt;
&lt;br /&gt;
Seit Mailman 2.x kann eine Mailman-Installation unter gewissen Einschränkungen für mehrere Domains verwendet werden. Hier soll kurz gezeigt werden, was geht und wie es geht.&lt;br /&gt;
&lt;br /&gt;
=== Anleitung ===&lt;br /&gt;
&lt;br /&gt;
Logischerweise muss das Webfrontend (die CGIs) auf allen Domains installiert werden.&lt;br /&gt;
&lt;br /&gt;
Wenn man nun Mailinglisten mit newlist neu anlegt, muss man den Hostnamen für das Webfontend mit angeben, und zwar so:&lt;br /&gt;
&lt;br /&gt;
 ~$ mailman/bin/newlist listenname@listen.example.com&lt;br /&gt;
&lt;br /&gt;
Es ist ggf. wichtig, dass in der mm_cfg.py eine entsprechende add_virtualhost-Direktive für www.example.com steht, die der Frontend-URL einen Host-Part für die Mailadressen zuordnet. Ist eine solche Direktive nicht vorhanden, so wird listen.example.com sowohl als URL für das Webfrontend wie auch als Hostpart für E-Mailadressen verwendet. (Was für separate aufgeschaltete Domains wie z.B. listen.example.com gerade zutrifft.)&lt;br /&gt;
&lt;br /&gt;
Liegt das Frondend nicht auf der Maildomain ist es wichtig, dass ihr Mailman sagt, für welches die zugehörige Maildomain ist. Dies tut ihr in der Datei ~/mailman/Mailman/mm_cfg.py:&lt;br /&gt;
&lt;br /&gt;
Also z.B.&lt;br /&gt;
 DEFAULT_URL_HOST = &#039;www.example.com&#039;&lt;br /&gt;
 DEFAULT_EMAIL_HOST = &#039;listen.example.com&#039;&lt;br /&gt;
 add_virtualhost(DEFAULT_URL_HOST,DEFAULT_EMAIL_HOST)&lt;br /&gt;
&lt;br /&gt;
und&lt;br /&gt;
 add_virtualhost(&#039;www.zoopnet.de&#039;, &#039;lists.zoopnet.de&#039;)&lt;br /&gt;
&lt;br /&gt;
Das bedeutet, dass Mailman per default davon ausgeht, dass alle Listen für die Domain example.com sind.&lt;br /&gt;
Alle weiteren add_virtualhost-Direktiven ordnen einem Hostnamen für das Webfrontend (z.B. www.zoopnet.de) einen Hostpart für die Adresse der Mailinglisten (z.B. lists.zoopnet.de) zu.&lt;br /&gt;
&lt;br /&gt;
Tip von Raimund Specht: Lässt man den zweiten Parameter weg, also schreibt z.B. add_virtualhost(&#039;www.example.org&#039;), dann benutzt Mailman als Hostpart alles was nach dem ersten Punkt steht, hier also example.org als Maildomain.&lt;br /&gt;
 &lt;br /&gt;
&lt;br /&gt;
Prinzipiell war&#039;s das. Man muss die Listeneinträge natürlich immer in die richtige virtusertable eintragen, und für gleichnamige Mailinglisten auf verschiedenen Domains (mailman@*) verschidene +Ergänzungen bzw. aliase verwenden. :)&lt;br /&gt;
&lt;br /&gt;
=== Probleme ===&lt;br /&gt;
&lt;br /&gt;
Verschiedene Listen mit gleichem Namen (also z.B. liste@example1.com und liste@example2.com) sind mit Mailman 2.1 leider nicht möglich.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Tips und Tricks ==&lt;br /&gt;
&lt;br /&gt;
=== URL Änderungen ===&lt;br /&gt;
Nach URL Änderungen stimmen Links im Web-Interface nicht mehr und Listen werden nicht mehr angezeigt.&lt;br /&gt;
Es sind dann, zusätzlich zur Anpassung der mm_cfg.py, schon bestehende Listen und Archive mit folgendem Befehl zu aktualisieren:&lt;br /&gt;
 ~/mailman/bin/withlist -l -r fix_url &amp;lt;Listen_Name&amp;gt; -v -u &amp;lt;Neue_Url&amp;gt;&lt;br /&gt;
&amp;lt;Listen_Name&amp;gt; steht für die Mailingliste, die bearbeitet werden soll. &amp;lt;Neue_Url&amp;gt; für die neue URL/Webadresse des Webinterfaces.&lt;br /&gt;
&lt;br /&gt;
=== Weitere Cron-Jobs zur Mailinglisten Verwaltung ===&lt;br /&gt;
&lt;br /&gt;
Folgende Cronjobs helfen bei der Verwaltung und sind User freundlich:&lt;br /&gt;
&lt;br /&gt;
&amp;lt; In Arbeit &amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Referenzen ==&lt;br /&gt;
&lt;br /&gt;
Lösung zur installation als Domainadmin (xyz00-listen) statt Paketadmin (xyz00): https://lists.hostsharing.net/archiv/support/2009-June/019414.html&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Ältere Anleitung für Installation als Domain-Admin (xyz00-listen): &amp;lt;http://lists.hostsharing.net/archiv/support/2005-January/012426.html&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;quot;Kleine Tools&amp;quot; auf http://hs.andreasloesch.de/, wobei das &#039;pac-mm-install&#039; wahrscheinlich nicht aktuell (genug) ist&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
[[Kategorie:HSDoku]]&lt;br /&gt;
[[Kategorie:Installationsanleitungen]]&lt;br /&gt;
[[Kategorie:Software]]&lt;br /&gt;
[[Kategorie:Mailinglisten]]&lt;br /&gt;
[[Kategorie:E-Mail]]&lt;br /&gt;
[[Kategorie:Python]]&lt;/div&gt;</summary>
		<author><name>Apc00-tony</name></author>
	</entry>
	<entry>
		<id>https://wiki.hostsharing.net/index.php?title=Benutzer:Apc00-tony/Dynamisches_DNS&amp;diff=6229</id>
		<title>Benutzer:Apc00-tony/Dynamisches DNS</title>
		<link rel="alternate" type="text/html" href="https://wiki.hostsharing.net/index.php?title=Benutzer:Apc00-tony/Dynamisches_DNS&amp;diff=6229"/>
		<updated>2023-09-11T14:36:09Z</updated>

		<summary type="html">&lt;p&gt;Apc00-tony: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Update 2023: Ich habe die Verwaltung über Befehlszeile durch eine PHP-Web-Oberfläche ersetzt; Details irgendwo ... ah, [https://ddns.crawfords.de/verwaltung/ddnsadminhints?name=acanthus_crawford_berlin hier]. Meine Hostsharing-DDNS-Lösung läuft übrigens schon lange einwandfrei; ich benutze sie dazu, ein VPN zwischen meinen Fritz!Box-LANS zu Hause und im Büro zu realisieren sowie um auf ein Backup- und Music-Server (ein Raspberry Pi) zu Hause von unterwegs zuzugreifen.&lt;br /&gt;
&lt;br /&gt;
((Provisorischer Vorspann: Auf Grund einer Mailing-Listen-Diskussion habe ich angefangen, Dynamisches DNS über einen CGI-Skript bei Hostsharing zu realisieren. Meine Lösung habe ich dann vorgestellt; sie wurde für nicht ausreichend selbsterklärend befunden und fand wenig Akzeptanz. Hier also der Versuch, die Sache zu dokumentieren.))&lt;br /&gt;
&lt;br /&gt;
Mit der regelmäßigen Aufnahme von benutzerspezifischen Zonefiles in seiner DNS-Konfiguration bietet  Hostsharing alles, was man braucht, um &amp;amp;bdquo;dynamisches DNS&amp;amp;ldquo; in Eigenregie zu realisieren.&lt;br /&gt;
&lt;br /&gt;
Das heißt, wenn ich mindestens eine Domain bei Hostsharing verwalte, und mindestens eine Einwahlverbindung (oder DSL-Verbindung) ins Internet mit wechselnder IP-Adresse über irgendeinen ISP für meinen Arbeitsplatzrechner zu Hause betreibe, dann kann ich dem Arbeitsplatzrechner über die DNS-Server von Hostsharing einen vollqualifizieren Domainnamen zuweisen, der der jeweiligen IP-Adresse meiner Einwahlleitung zugeordnet ist.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
(ASCII-Art-Diagramm der beschriebenen Konstellation)&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Im Folgenden wird eine real existierende Implementierung von Dynamischem DNS (&amp;amp;bdquo;DDNS&amp;amp;ldquo;) beschrieben. Die verschiedenen Elemente könnten durchaus anders realisiert werden; die beschriebene Implementierung könnte durchaus verbessert werden. Sie dient hier der Illustration.&lt;br /&gt;
&lt;br /&gt;
In der folgenden Beschreibung werden diese Beispielwerte benutzt:&lt;br /&gt;
* Ein Hostsharing-Mitglied hat ein Account als Paket-Admin mit Kennung xyz00.&lt;br /&gt;
* Im Paket xyz00 gibt es einen Domain-Admin namens xyz00-benutzername.&lt;br /&gt;
* Dieser Domain-Admin verwaltet bei Hostsharing die Domains example.com und beispiel.de.&lt;br /&gt;
* Ein Benutzer hat zu Hause (oder im Büro) einen Arbeitsplatzrechner hinter der marktüblichen DSL-Leitung, die von seinem ISP bereitgestellt wird.&lt;br /&gt;
* Dieser Arbeitsplatzrechner (oder der Router, der seine Internetverbindung steuert) bekommt vom ISP immer wechselnde IP-Adressen zugewiesen.&lt;br /&gt;
* Dennoch möchte der Benutzer seinen Arbeitsplatzrechner aus dem Internet unter dem Hostnamen einwahl.example.com ansprechen können.&lt;br /&gt;
&lt;br /&gt;
Dazu kann ein System wie Hostsharing, das authoritative DNS-Informationen für viele Domains bereitstellt, auch veränderliche DNS-Information über dynamisch verbundene Rechner verwalten &amp;amp;ndash; sofern das ressourcenschonend gemacht werden kann ohne andere Funktionen zu stören.&lt;br /&gt;
&lt;br /&gt;
== Aufgaben des Servers ==&lt;br /&gt;
&lt;br /&gt;
Um einem Rechner mit wechselnder IP-Adresse einen DDNS-Eintrag zu bieten, muß der Hostsharing-Server folgendes leisten (in ungefährer Reihenfolge der Ereignisse):&lt;br /&gt;
&lt;br /&gt;
# Eine Anfrage entgegennehmen, beispielsweise über HTTPS, von einem entfernten Rechner, der einen DNS-Eintrag für seine momentane IP-Adresse wünscht. &lt;br /&gt;
# Prüfen, ob die Anfrage einen berechtigten DDNS-Dienst-Usernamen mit zugehörigem Paßwort enthält.&lt;br /&gt;
# Prüfen, ob die Anfrage einen gültigen Domainnamen betrifft, den der Server bieten darf.&lt;br /&gt;
# Prüfen, ob die Domain example.com demselben Benutzer gehört, unter dessen Namen der Dynamisches-DNS-Server läuft.&lt;br /&gt;
# Eine gültige [[Zonefile]] mit &amp;amp;ndash; neben dem bisherigen Inhalt &amp;amp;ndash; einem A-Eintrag für einwahl.example.com in /home/pacs/xyz00/users/benutzername/doms/example.com/pri.example.com schreiben.&lt;br /&gt;
# Dem Client eine Bestätigung oder ggf. eine Fehlermeldung als Antwort senden.&lt;br /&gt;
# In irgendeiner Datenbank den momentan eingestellter Status all seiner DDNS-Einträge speichern.&lt;br /&gt;
# In einer Logdatei protokollieren, daß obiges getan wurde, oder ggf. welche Fehler traten auf.&lt;br /&gt;
&lt;br /&gt;
== Aufgaben des Clients ==&lt;br /&gt;
Bevor ich anfange, meinen Arbeitsplatzrechner so zu konfigurieren, daß er bei welchem Server auch immer einen DDNS-Eintrag anfordert, muß ich mich als verantwortlicher Benutzer dieses Rechners und der dazugehörigen Internetverbindung &amp;amp;ndash; das heißt, als Mensch &amp;amp;ndash; mit dem Betreiber des dynamisches-DNS-Servers vereinbaren, daß ich das darf und welchen Eintrag ich bekommen kann. Im Folgenden wird vorausgesetzt, daß solche Vereinbarungen getroffen und die Parameter geklärt wurden.&lt;br /&gt;
&lt;br /&gt;
Der DDNS-Client muß aus Server-Sicht nur wenig leisten:&lt;br /&gt;
&lt;br /&gt;
# Eine Anfrage senden, beispielsweise über HTTPS, an einen entfernten Rechner, der einen Eintrag ins DNS für die momentane IP-Adresse des Clients vornehmen kann.&amp;lt;br /&amp;gt;Diese Anfrage muß einem festgelegten Format entsprechen und muß gültige Werte für die Authorisation des Clients, den gewünschten Domainnamen, und eventuell andere Parameter enthalten.&lt;br /&gt;
# Eine Antwort des Servers entgegennehmen und als Erfolgs- oder Fehlermeldung auswerten.&lt;br /&gt;
# Von überflüssigen Anfragen absehen: das heißt bei Erfolg, nicht wiederholt den gleichen Eintrag erneut wünschen; bei Fehlern, nicht die gleiche fehlerhafte Anfrage erneut schicken.&lt;br /&gt;
&lt;br /&gt;
== Kommunikation zwischen Client und Server ==&lt;br /&gt;
&lt;br /&gt;
Ein einziges Nachrichtenpaar von Anfrage und Antwort genügt, um einen DDNS-Eintrag einzurichten: Der Client teilt die IP-Adresse und den Domainnamen mit, die in einem DNS-Eintrag verbunden werden sollen; der Server bestätigt den Auftrag.&lt;br /&gt;
&lt;br /&gt;
In der Beispielimplementierung erfolgt die Kommunikation über HTTP, und die Anfrage des Clients könnte so aussehen:&lt;br /&gt;
&lt;br /&gt;
  GET /cgi-bin/ddns?hostname=einwahl.example.com&amp;amp;myip=87.65.43.21 HTTP/1.1&lt;br /&gt;
  Host: ddns.beispiel.de&lt;br /&gt;
  User-Agent: Fritz!Box DDNS/1.0.1&lt;br /&gt;
  Authorization: Basic QWxhZGRpbjpvcGVuIHNlc2FtZQ==&lt;br /&gt;
&lt;br /&gt;
Bei Erhalt dieser Anfrage ruft Apache das CGI-Programm .../doms/ddns.beispiel.de/cgi-ssl/ddns auf. Das Fragezeichen trennt den Programmnamen von einem &amp;quot;Query-String&amp;quot;, in dem zwei Metavariablen definiert und übergeben werden. Die erste Metavariable, hostname, hat den Wert &amp;quot;einwahl.example.com&amp;quot;; die zweite, myip, hat den Wert &amp;quot;87.65.43.21&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
Das Server-Programm, hier &#039;&#039;ddns&#039;&#039;, prüft diese Informationen auf Form und Berechtigung, und schreibt gegebenenfalls einen entsprechenden Eintrag in einer Zonefile. Es schreibt auch verschiedene Informationen in die Standardausgabe. Wenn es die Standardausgabe geschlossen wird &amp;amp;ndash; also spätestens bei Programmende &amp;amp;ndash; schickt Apache diese Informationen als Antwort an den anfragenden Rechner zurück.&lt;br /&gt;
&lt;br /&gt;
Im Falle unserer Beispielimplementierung sieht die Antwort bei Erfolg so aus: &lt;br /&gt;
&lt;br /&gt;
  HTTP/1.1 200 OK&lt;br /&gt;
  Date: Wed, 22 Apr 2020 08:35:15 GMT&lt;br /&gt;
  Server: Apache&lt;br /&gt;
  Content-Length: 17&lt;br /&gt;
  Content-Type: text/plain; charset=ISO-8859-1&lt;br /&gt;
 &lt;br /&gt;
  good 87.65.43.21&lt;br /&gt;
&lt;br /&gt;
=== Das DDNS-Protokoll von DynDNS.org ===&lt;br /&gt;
&lt;br /&gt;
In den 90er Jahren, bevor das Internet so durchgehend vergeschäftlicht wurde, boten einige Organisationen kostenlose DDNS-Dienste an. Ein sehr beliebtes Angebot war das von DynDNS.org. Das DDNS-Protokoll von diesem Dienst wurde sogar in Einwahl-Routern einprogrammiert und der Dienst wurde von ISPs und Router-Herstellern als Leistungsmerkmal beworben.&lt;br /&gt;
&lt;br /&gt;
DynDNS.org gehört inzwischen Oracle und bietet keine kostenlose Dienste mehr. Dennoch wird das DDNS-Protokoll von DynDNS.org in der vorliegenden Beispielimplementierung übernommen in der Hoffnung, daß die Kompatibilität mit einigen gängigen Einwahl-Routern von Vorteil sein kann. Es gibt noch eine kurze Online-Dokumentation der [https://help.dyn.com/remote-access-api/perform-update/ Anfrage] und [https://help.dyn.com/remote-access-api/perform-update/ Antwortnachrichten].&lt;br /&gt;
&lt;br /&gt;
Das gesammte Protokoll sieht einen einzigen Nachrichtenaustausch aus Anfrage und Antwort vor. Die Anfrage kann mehrere Argumente enthalten; die Antwort kann verschiedene Code-Wörtern enthalten. Übrigens können in einer einzigen Anfrage mehrere DNS-Einträge gewünscht werden. In diesem Fall kann die Antwort mehrzeilig ausfallen.&lt;br /&gt;
&lt;br /&gt;
Das Verhalten von Server und Client bei künftigen Kommunikationsvorgängen wird unter Umständen von vorangegangenen Kommunikationsergebnissen beeinflußt: nach wiederholten fehlerhaften oder redundanten Anfragen kann der Server weitere Anfragen des Benutzers verweigern; nach wiederholten Fehlermeldungen sollte ein Client aufhören, immer dieselbe Anfrage zu schicken. Und für den Fall, daß mehrere Clients dynamische DNS-Einträge in derselben Domain example.com bestellen, muß der Server den Stand aller Client-Einträge intern speichern, damit er nicht mit einer neuen Zonefile einen früher erstellten Eintrag löscht. Zu diesen Fragen siehe den Abschnitt &#039;&#039;&#039;[[#Sukzessive_Kommunikationsabläufe]]&#039;&#039;&#039; nach der Beschreibung von Anfragen und Antworten unten.&lt;br /&gt;
&lt;br /&gt;
====Anfrage====&lt;br /&gt;
&lt;br /&gt;
Die Anfrage in Form eines URL übergibt dem DDNS-Programm in einem &#039;Query-String&#039; einige Metavariablen. Das heißt, in einem URL der Form&lt;br /&gt;
&lt;br /&gt;
  &amp;lt;nowiki&amp;gt;https://benutzername:passwort@ddns.beisiel.de/cgi-bin/ddns?hostname=einwahl.example.com&amp;amp;myip=87.65.43.21&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
signalisert das Fragezeichen, daß ein Query-String folgt. In einem solchen Query-String können in der Beispielimplementierung folgende Metavariablen definiert werden:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|- class=&amp;quot;hintergrundfarbe5&amp;quot;&lt;br /&gt;
! Variable !! Beispiel !! Bemerkungen&lt;br /&gt;
|-&lt;br /&gt;
| hostname || &amp;lt;tt&amp;gt;hostname=einwahl.example.com&amp;lt;/tt&amp;gt;&amp;lt;br /&amp;gt;&amp;lt;div style=&amp;quot;font-size:smaller;&amp;quot;&amp;gt;&amp;lt;tt&amp;gt;hostname=eins.example.com,zwei.example.com[,...]&amp;lt;/tt&amp;gt;&amp;lt;/div&amp;gt; ||&lt;br /&gt;
Muß ein vollständig qualifizierter Domain-Name (&amp;quot;FQDN&amp;quot;) sein; &amp;lt;tt&amp;gt;example.com&amp;lt;/tt&amp;gt; muß eine vom Besitzer des DDNS-Programms verwaltete Domain sein. Genaugenommen kann der Wert eine durch Kommata gegliederte Liste mehrerer gültiger Domainnamen sein, falls mehrere Einträge mit derselben IP-Adresse gewünscht werden.&lt;br /&gt;
|-&lt;br /&gt;
| myip || &amp;lt;tt&amp;gt;myip=87.65.43.21&amp;lt;/tt&amp;gt;||&lt;br /&gt;
Kann entfallen; kann vom Server ignoriert werden. Maßgeblich ist dann die IP-Adresse des Absenders, wie sie vom Web-Server mitgeteilt wird.&lt;br /&gt;
|-&lt;br /&gt;
| mx || &amp;lt;tt&amp;gt;mx=87.65.43.21&amp;lt;/tt&amp;gt;&amp;lt;br /&amp;gt;&amp;lt;tt&amp;gt;mx=NOCHG&amp;lt;/tt&amp;gt;&amp;lt;br /&amp;gt; ||&lt;br /&gt;
Neben dem A-Eintrag möchte der Client auch einen MX-Eintrag. Der Wert &amp;lt;tt&amp;gt;NOCHG&amp;lt;/tt&amp;gt; (für &amp;amp;bdquo;no change&amp;amp;ldquo;) bedeutet, der bestehende MX-Eintrag (oder seine Abwesenheit) soll nicht geändert werden. &lt;br /&gt;
|-&lt;br /&gt;
| backmx || &amp;lt;tt&amp;gt;backmx=YES&amp;lt;/tt&amp;gt;&amp;lt;br /&amp;gt;&amp;lt;tt&amp;gt;backmx=NOCHG&amp;lt;/tt&amp;gt;&amp;lt;br /&amp;gt;&amp;lt;tt&amp;gt;backmx=NO&amp;lt;/tt&amp;gt;   ||&lt;br /&gt;
Falls &amp;lt;tt&amp;gt;YES&amp;lt;/tt&amp;gt;, wird ein zweiter MX-Eintrag erzeugt, der &amp;lt;tt&amp;gt;einwahl.example.com&amp;lt;/tt&amp;gt; als Mail-Server für &amp;lt;tt&amp;gt;einwahl.example.com&amp;lt;/tt&amp;gt; nennt. Dieser Eintrag hat eine niedrigere Präferenzzahl (also eine höhere Priorität) als der mit &amp;lt;tt&amp;gt;mx&amp;lt;/tt&amp;gt; angeforderten Eintrag.&lt;br /&gt;
|-&lt;br /&gt;
| wildcard || &amp;lt;tt&amp;gt;wildcard=ON&amp;lt;/tt&amp;gt;&amp;lt;br /&amp;gt;&amp;lt;tt&amp;gt;wildcard=NOCHG&amp;lt;/tt&amp;gt;&amp;lt;br /&amp;gt;&amp;lt;tt&amp;gt;wildcard=OFF&amp;lt;/tt&amp;gt; ||&lt;br /&gt;
Neben dem A-Eintrag für den Domainnamen &amp;lt;tt&amp;gt;einwahl.example.com&amp;lt;/tt&amp;gt; wünscht der Client auch einen Eintrag für beliebige Subdomains, also &amp;lt;tt&amp;gt;*.einwahl.example.com&amp;lt;/tt&amp;gt;, mit der gleichen IP-Adresse.&lt;br /&gt;
|-&lt;br /&gt;
| offline ||&amp;lt;tt&amp;gt;offline=YES&amp;lt;/tt&amp;gt;&amp;lt;br /&amp;gt;&amp;lt;tt&amp;gt;offline=NOCHG&amp;lt;/tt&amp;gt;||&lt;br /&gt;
Falls &amp;lt;tt&amp;gt;YES&amp;lt;/tt&amp;gt;, wird ein DNS-Eintrag für &amp;lt;tt&amp;gt;einwahl.example.com&amp;lt;/tt&amp;gt; aus der Zonefile getilgt. Gegebenenfalls wird der Hostname dann auf Grund eines parallelen Wildcard-Eintrags für &amp;lt;tt&amp;gt;*.example.com&amp;lt;/tt&amp;gt; einer anderen IP-Adresse zugeordnet werden.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;!-- IPv6? --&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Alle Parameter bis auf hostname können entfallen. Bei nichtdokumentierten Argumenten ist das Verhalten undefiniert&amp;amp;trade;.&lt;br /&gt;
&lt;br /&gt;
====Antwort====&lt;br /&gt;
&lt;br /&gt;
Die Antwort auf eine erfolgreiche HTTP-Anfrage besteht im häufigsten Fall aus einigen Header-Zeilen, gefolgt vom Inhalt der gewünschten Text- oder andere Datei. Ein Status-Code in der ersten Header-Zeile gibt an, ob die Anfrage bedient werden kann oder kreist andernfalls den Grund für die Enttäuschung ein.&lt;br /&gt;
&lt;br /&gt;
Die vorliegende Beispielimplementierung von DDNS schickt einen der üblichen HTTP-Status-Codes &amp;quot;200 OK&amp;quot; oder &amp;quot;500 Internal Server Error&amp;quot;, gefolgt von einer kurzen Textnachricht nach dem HTTP-Header. Bei diesem Programm  ist &amp;amp;ndash; laut Gebrauchshinweise von DynDNS.org &amp;amp;ndash; &#039;&#039;nicht&#039;&#039; der Status-Code im Header, sondern der Inhalt der Nachricht  die definierte, maßgebliche Ergebnismeldung des Programms.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|- class=&amp;quot;hintergrundfarbe5&amp;quot;&lt;br /&gt;
! Meldung !! Bedeutung !! Bemerkungen&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;good&amp;amp;nbsp;&amp;amp;lt;IP&amp;amp;nbsp;number&amp;amp;gt;&amp;lt;/tt&amp;gt; ||&lt;br /&gt;
Der gewünschte DNS-Eintrag wurde erfolgreich in einer Zonefile eingetragen. &lt;br /&gt;
|| Es kann natürlich noch einige Minuten dauern, bis die Zonefile vom Hostsharing-Roboter abgelesen wird und der Inhalt in die BIND-Konfiguration übernommen.&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;good&amp;amp;nbsp;0.0.0.0&amp;lt;/tt&amp;gt; ||&lt;br /&gt;
Das Argument &amp;lt;tt&amp;gt;offline=YES&amp;lt;/tt&amp;gt; wurde empfangen und verarbeitet.&lt;br /&gt;
|| Der Domainname hat also keinen dynamischen DNS-Eintrag mehr.&lt;br /&gt;
|-&lt;br /&gt;
&amp;lt;!-- We don&#039;t do this!&lt;br /&gt;
| &amp;lt;tt&amp;gt;good&amp;amp;nbsp;127.0.0.1&amp;lt;/tt&amp;gt; ||&lt;br /&gt;
Die Anfrage entsprach nicht den Erfordernissen des Servers.&lt;br /&gt;
|| Trotz des Worts &amp;lt;tt&amp;gt;good&amp;lt;/tt&amp;gt; war die Anfrage nicht erfolgreich, falls in der Rückmeldung die IP-Adresse mit &amp;lt;tt&amp;gt;127.0.0.1&amp;lt;/tt&amp;gt; angegeben wird. Dieser verwirrende Fehlercode ist aus unerklärlichen Gründen in der Spezifikation von DynDNS.org so definiert.&lt;br /&gt;
|-&lt;br /&gt;
--&amp;gt;&lt;br /&gt;
| &amp;lt;tt&amp;gt;nochg&amp;amp;nbsp;&amp;amp;lt;IP&amp;amp;nbsp;number&amp;amp;gt;&amp;lt;/tt&amp;gt; ||&lt;br /&gt;
Der gewünschte DNS-Eintrag war bereits vorhanden. &lt;br /&gt;
|| Der Server selbst macht keine DNS-Abfrage, um das zu vermitteln: die &amp;amp;bdquo;no change&amp;amp;ldquo;-Antwort besagt nur, daß eine Anfrage für diesen Eintrag bereits mit Erfolg quittiert wurde.&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;notfqdn&amp;lt;/tt&amp;gt; ||&lt;br /&gt;
Fehlschlag: der gewünschte Domainname ist nicht gültig, oder es wurde keiner angegeben.&lt;br /&gt;
|| ...&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;nohost&amp;lt;/tt&amp;gt; ||&lt;br /&gt;
Fehlschlag: der gewünschte Domainname ist gehört nicht zu denen, die für diesen Benutzer des DDNS-Dienstes konfiguriert sind.&lt;br /&gt;
|| Siehe den Abschnitt [[#Administration|Administration]] weiter unten.&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;badauth&amp;lt;/tt&amp;gt; ||&lt;br /&gt;
Fehlschlag: Die Kombination von Benutzernamen und Paßwort entsprach keinem DDNS-Account, oder das Account ist momentan gesperrt.&lt;br /&gt;
|| Ein gesperrtes Account kann nur der Domain-Admin mittels des Administrationswerkzeugs wieder freigeben: siehe den Abschnit [[#Administration|Administration]] weiter unten.&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;abuse&amp;lt;/tt&amp;gt; ||&lt;br /&gt;
Fehlschlag: der gewünschte Domainname ist wegen vorangeganger Fehlschläge oder überflüssiger Aufrufe gesperrt.&lt;br /&gt;
|| Siehe den Abschnitt [[#Sukzessive_Kommunikationsabläufe|Sukzessive Kommunikationsabläufe]] unten.&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;911&amp;lt;/tt&amp;gt; ||&lt;br /&gt;
Fehlschlag: Das Server-Programm hat einen internen Fehler festgestellt.&lt;br /&gt;
|| Das Problem liegt nicht in der Anfrage an sich.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Man kann sich durchaus eine sinnreichere Kommunikation zwischen Client und Server vorstellen, doch das hier beschriebene Protokoll ist eben von DynDNS.org verwendet worden und wird in gängigen Routern implementiert, also wird es in der vorliegenden DDNS-Implementierung nachgebildet.&lt;br /&gt;
&lt;br /&gt;
=== Sukzessive Kommunikationsabläufe ===&lt;br /&gt;
Der Server muß sich zwischen einzelnen Aufrufen einiges merken, um Ressourcen zu schonen und um zu verhindern, daß einmal vergebene DDNS-Einträge von neuen Anfragen, die dieselbe übergeordnete Domain betreffen, durch Überschreiben  verlorengehen.&lt;br /&gt;
&lt;br /&gt;
==== Mißbrauch und Benutzersperrung ====&lt;br /&gt;
Zur Schonung von Ressourcen muß sich die Implementierung weigern, sich mit zuvielen fehlerhaften oder auch nur überflüssigen Anfragen zu beschäftigen. Dazu führt der Server eine Strichliste über solche Anfragen jedes Clients und sperrt nach einer bestimmten Anzahl solcher Anfragen den Benutzernamen oder einzelne Domainnamen gegen die weitere Nutzung des Dienstes.&lt;br /&gt;
&lt;br /&gt;
Mißbrauchspunkte gegen einen einzelnen Domainnamen gibt es für:&lt;br /&gt;
* eine Anfrage, die keinen neuen DNS-Eintrag (und keine Änderung oder Löschung eines Eintrags) erfordert, sondern bestehende Merkmale nur wiederholt&lt;br /&gt;
&lt;br /&gt;
Mißbrauchspunkte gegen einen Benutzernamen gibt es für:&lt;br /&gt;
* die Angabe eines Domainnamens, der in der Dienstkonfiguration dem anfragenden Benutzernamen nicht zugeordnet ist&lt;br /&gt;
* die Angabe eines Domainnamen in einer Domain, die nicht demselben Hostsharing-Domain-Admin gehört, der den DDNS-Dienst anbietet&lt;br /&gt;
* die Angabe eines Domainnamens, der in der Dienstkonfiguration bereits wegen mißbräuchlicher Anfragen gesperrt ist (siehe oben)&lt;br /&gt;
&lt;br /&gt;
Um eine Sperrung aufzuheben, wird in der Regel eine Handlung durch den Administrator erforderlich sein.&lt;br /&gt;
&lt;br /&gt;
==== Mehrere dynamische Subdomains in derselben Domain ====&lt;br /&gt;
Sobald zwei verschiedene DDNS-Einträge in derselben Domain verlangt werden &amp;amp;ndash; beispielsweise home.example.com und office.example.com &amp;amp;ndash; wird es notwendig, bei jeder neuen Zonefile für example.com eventuell frühere Einträge zu konservieren. Der Rechner zu Hause weiß beim Bestellen seines DDNS-Eintrags nichts vom Rechner im Büro und umgekehrt. Der Server muß in irgendeiner Form über bereits vergebene Einträge Buch führen und bei einer neuen Anfrage, die example.com betrifft, alle bereits aktiven DDNS-Einträge für example.com mit in die neue Zonefile aufnehmen &amp;amp;ndash auch wenn sie auf Anfragen verschiedener Benutzer zurückgehen.&lt;br /&gt;
&lt;br /&gt;
==== Datenbank ====&lt;br /&gt;
In der Beispielimplementierung werden diese Informationen in einer SQLite-Datenbank gespeichert.&lt;br /&gt;
&lt;br /&gt;
== Sicherheit ==&lt;br /&gt;
=== Rechte ===&lt;br /&gt;
Die &#039;&#039;&#039;Benutzerrechte&#039;&#039;&#039; werden durch das Hostsharing-System kontrolliert. Sowohl das CGI-Programm als auch das [[#Administration|Administrationswerkzeug]] werden mit den Rechten des Domain-Admins (xyz00-benutzername in unserem Beispiel) ausgeführt, also kann dieses Programm nur die Domains bearbeiten, die von xyz00-benutzername verwaltet werden.&lt;br /&gt;
&lt;br /&gt;
=== Authentifizierung ===&lt;br /&gt;
In der Beispielimplementierung (wie auch seinerzeit bei DynDNS.org) wird das CGI-Programm durch einen .htaccess-Eintrag geschützt, der HTTP-Basic-Authentication vorschreibt. Also wird das Programm eigentlich mit einem URL der form&lt;br /&gt;
&lt;br /&gt;
  &amp;lt;nowiki&amp;gt;https://ddnsaccount:passwort@ddns.example.com/cgi-bin/ddns?hostname=...&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
aufgerufen.&lt;br /&gt;
&lt;br /&gt;
=== Verschlüsselung ===&lt;br /&gt;
Das CGI-Programm sollte nur in example.com/cgi-ssl/ installiert werden, nicht in example.com/cgi/. Damit ist die Kommunikation zwischen Client und Server durch SSL verschlüsselt.&lt;br /&gt;
&lt;br /&gt;
== Administration ==&lt;br /&gt;
&lt;br /&gt;
Der Verwalter des DDNS-Programms trägt berechtigte Benutzer und die ihnen zugeteilten Domainnamen in die Datenbank des Programms ein mit Hilfe eines kleinen Hilfsprogramms. Das ist im vorliegenden Fall ein menügesteuertes Programm für die Befehlszeile, daß die naheliegenden Funktionen anbietet: Account hinzufügen, löschen, sperren, entsperren, Paßwort setzen, ändern; Domainnamen hinzufügen, ändern, entsperren, löschen; Accounts und Domainnamen mit aktuellem Status auflisten. Die Funktionen sind auch über Befehlszeilenargumente verfügbar, also skriptfähig.&lt;br /&gt;
&lt;br /&gt;
Eine Übersicht der Funktionen des Administrationswerkzeugs gibt dieses selbst aus:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
xyz00-benutzername@h02:~$ bin/ddnsadmin -h&lt;br /&gt;
ddnsadmin.pl: Verwaltungswerkzeug für ddns&lt;br /&gt;
&lt;br /&gt;
Verwendung:&lt;br /&gt;
    ddnsadmin -A{[ahlusf]} [&amp;lt;Account&amp;gt;] [-f &amp;lt;DB-Datei&amp;gt;]&lt;br /&gt;
    ddnsadmin -D{[ahlsf]} [&amp;lt;Domain&amp;gt;] -A &amp;lt;Account&amp;gt; [-f &amp;lt;DB-Datei&amp;gt;]&lt;br /&gt;
    ddnsadmin -E &amp;lt;Einstellung&amp;gt; &amp;lt;Wert&amp;gt; [-f &amp;lt;DB-Datei&amp;gt;]&lt;br /&gt;
    ddnsadmin [-f &amp;lt;DB-Datei&amp;gt;] [-n]&lt;br /&gt;
&lt;br /&gt;
Wenn keine Option oder nur -f &amp;lt;DB-Datei&amp;gt; angegeben wird, bietet&lt;br /&gt;
ddnsadmin.pl eine interaktive Menüoberfläche.&lt;br /&gt;
&lt;br /&gt;
Optionen:&lt;br /&gt;
    -f &amp;lt;DB-Datei&amp;gt;                    Angegebene Datenbankdatei verwenden&lt;br /&gt;
    -n                               Neue, leere Datenbank erzeugen&lt;br /&gt;
    -Aa  [&amp;lt;Account&amp;gt;]                 Account(s) auflisten&lt;br /&gt;
    -Ah &amp;lt;Account&amp;gt; &amp;lt;Paßwort&amp;gt;          Account hinzufügen&lt;br /&gt;
    -A{lsf} &amp;lt;Account&amp;gt;                Account löschen, sperren, freigeben&lt;br /&gt;
    -Au &amp;lt;Account&amp;gt; &amp;lt;Name&amp;gt;             Account umbenennen&lt;br /&gt;
    -A  &amp;lt;Account&amp;gt; -Da [&amp;lt;Domain&amp;gt;]     Domain(s) auflisten&lt;br /&gt;
    -A  &amp;lt;Account&amp;gt; -D{hlsf} &amp;lt;Domain&amp;gt;  Domain hinzufügen,&lt;br /&gt;
                                     löschen, sperren, freigeben&lt;br /&gt;
    -E &amp;lt;Einstellung&amp;gt; &amp;lt;Wert&amp;gt;          Einstellung ändern&lt;br /&gt;
    -h                               Diese Übersicht ausgeben&lt;br /&gt;
&lt;br /&gt;
Einstellungen: &lt;br /&gt;
    maxacctabuse    Anzahl der mißbräuchlichen Aufrufe,&lt;br /&gt;
                    bevor ein Account gesperrt wird&lt;br /&gt;
    maxhostabuse    Anzahl der mißbräuchlichen Aufrufe,&lt;br /&gt;
                    bevor ein Domainname gesperrt wird&lt;br /&gt;
    safeinterval    Mindestabstand zwischen redundanten Aufrufen&lt;br /&gt;
                    (in Sekunden)&lt;br /&gt;
    cgihost         Server, der das DDNS-Skript bereithält&lt;br /&gt;
&lt;br /&gt;
xyz00-benutzername@h02:~$ &lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Eine Auflistung des momentanen Inhalts der DDNS-Datenbank durch das Administrationswerkzeug könnte beispielsweise so aussehen:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  xyz00-benutzername@h02:~$ bin/ddnsadmin.pl -Aa&lt;br /&gt;
  1.  papst	Mißbrauch: 0; gesperrt: nein&lt;br /&gt;
  	avignon.example.com&lt;br /&gt;
  		zuletzt aktiv am Sun Apr 26 22:24:49 2020&lt;br /&gt;
  		mit IP-Nr. 87.65.43.21; MX: 0;  Backup-MX: nein;&lt;br /&gt;
  		Subdomains: nein; Mißbrauch: 0;  gesperrt: nein&lt;br /&gt;
  	vatican.beispiel.de&lt;br /&gt;
  		zuletzt aktiv am Sun Apr 26 22:24:49 2020&lt;br /&gt;
  		mit IP-Nr. 87.65.43.21; MX: 0;  Backup-MX: nein;&lt;br /&gt;
  		Subdomains: nein; Mißbrauch: 0;  gesperrt: nein&lt;br /&gt;
  2.  kaiser	Mißbrauch: 4; gesperrt: ja&lt;br /&gt;
  	augsburg.beispiel.de&lt;br /&gt;
  		zuletzt aktiv am Fri Apr 24 16:13:49 2020&lt;br /&gt;
  		mit IP-Nr. 64.82.31.75; MX: 0;  Backup-MX: nein;&lt;br /&gt;
  		Subdomains: nein; Mißbrauch: 0;  gesperrt: ja&lt;br /&gt;
  3.  luther	Mißbrauch: 1; gesperrt: nein&lt;br /&gt;
  	wittenberg.example.com&lt;br /&gt;
  		zuletzt aktiv am Mon Apr 27 10:12:49 2020&lt;br /&gt;
  		mit IP-Nr. 78.56.34.12; MX: 0;  Backup-MX: nein;&lt;br /&gt;
  		Subdomains: nein; Mißbrauch: 1;  gesperrt: nein&lt;br /&gt;
  xyz00-benutzername@h02:~$&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Das DDNS-Account &amp;amp;bdquo;kaiser&amp;amp;ldquo; in dieser Auflistung ist wohl auf Grund fehlerhafter Anfragen automatisch gesperrt worden. Der Inhaber wird sich wohl bald melden, um nach Korrektur seiner Client-Konfiguration die Aufhebung der Sperre zu wünschen.&lt;br /&gt;
&lt;br /&gt;
=== Log ===&lt;br /&gt;
Alle Anfragen werden in einer täglich wechselnden Log-Datei protokolliert, entweder schlicht oder ausführlich, je nachdem, ob eine Variable &amp;lt;tt&amp;gt;verbose&amp;lt;/tt&amp;gt; wahr ist.&lt;br /&gt;
Ein ausführlicher Log-Eintrag sieht so aus:&lt;br /&gt;
&lt;br /&gt;
  Sun Apr 26 20:21:45 2020  ddns aufgerufen von papst&lt;br /&gt;
  			unter 84.185.97.8&lt;br /&gt;
  	URL: &amp;lt;nowiki&amp;gt;https://ddns.example.com/cgi-bin/ddns.cgi?hostname=&lt;br /&gt;
  			avignon.example.com,vatican.beispiel.de&amp;amp;&lt;br /&gt;
  			myip=84.185.97.8&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
  	Verwende IP 84.185.97.8 (= 1421435144)&lt;br /&gt;
  	DB-Version: 1&lt;br /&gt;
  	Skript und DB exklusiv geöffnet&lt;br /&gt;
  	avignon.example.com: IP: 84.185.97.8; MX: 0; Backup-MX: nein;&lt;br /&gt;
  			Wildcard: nein; Mißbrauch: 0; gesperrt: nein &lt;br /&gt;
  	vatican.beispiel.de: IP: 84.185.97.8; MX: 0; Backup-MX: nein;&lt;br /&gt;
  			Wildcard: nein; Mißbrauch: 0; gesperrt: nein &lt;br /&gt;
  	Betroffene Zonen: example.com, beispiel.de&lt;br /&gt;
  	Temporärdatei example.com_hxNa.new geschrieben&lt;br /&gt;
  	Zonendatei /home/pacs/xyz00/users/benutzername/doms/example.com/&lt;br /&gt;
  			etc/pri.example.com eingestellt&lt;br /&gt;
  	Temporärdatei beispiel.de_6HcO.new geschrieben&lt;br /&gt;
  	Zonendatei /home/pacs/xyz00/users/benutzername/doms/beispiel.de/&lt;br /&gt;
  			etc/pri.beispiel.de eingestellt&lt;br /&gt;
  	Abgeschlossen: 	Fertig&lt;br /&gt;
&lt;br /&gt;
Wenn &amp;lt;tt&amp;gt;verbose&amp;lt;/tt&amp;gt; auf falsch gesetzt ist, sind die Log-Einträge einzeilig.&lt;/div&gt;</summary>
		<author><name>Apc00-tony</name></author>
	</entry>
	<entry>
		<id>https://wiki.hostsharing.net/index.php?title=Benutzer:Apc00-tony/Dynamisches_DNS&amp;diff=6228</id>
		<title>Benutzer:Apc00-tony/Dynamisches DNS</title>
		<link rel="alternate" type="text/html" href="https://wiki.hostsharing.net/index.php?title=Benutzer:Apc00-tony/Dynamisches_DNS&amp;diff=6228"/>
		<updated>2023-09-11T14:35:40Z</updated>

		<summary type="html">&lt;p&gt;Apc00-tony: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Update 2023: Ich habe die Verwaltung über Befehlszeile durch eine PHP-Web-Oberfläche ersetzt; Details irgendwo ... ah, [https://ddns.crawfords.de/verwaltung/ddnsadminhints?name=host_domain_tld hier]. Meine Hostsharing-DDNS-Lösung läuft übrigens schon lange einwandfrei; ich benutze sie dazu, ein VPN zwischen meinen Fritz!Box-LANS zu Hause und im Büro zu realisieren sowie um auf ein Backup- und Music-Server (ein Raspberry Pi) zu Hause von unterwegs zuzugreifen.&lt;br /&gt;
&lt;br /&gt;
((Provisorischer Vorspann: Auf Grund einer Mailing-Listen-Diskussion habe ich angefangen, Dynamisches DNS über einen CGI-Skript bei Hostsharing zu realisieren. Meine Lösung habe ich dann vorgestellt; sie wurde für nicht ausreichend selbsterklärend befunden und fand wenig Akzeptanz. Hier also der Versuch, die Sache zu dokumentieren.))&lt;br /&gt;
&lt;br /&gt;
Mit der regelmäßigen Aufnahme von benutzerspezifischen Zonefiles in seiner DNS-Konfiguration bietet  Hostsharing alles, was man braucht, um &amp;amp;bdquo;dynamisches DNS&amp;amp;ldquo; in Eigenregie zu realisieren.&lt;br /&gt;
&lt;br /&gt;
Das heißt, wenn ich mindestens eine Domain bei Hostsharing verwalte, und mindestens eine Einwahlverbindung (oder DSL-Verbindung) ins Internet mit wechselnder IP-Adresse über irgendeinen ISP für meinen Arbeitsplatzrechner zu Hause betreibe, dann kann ich dem Arbeitsplatzrechner über die DNS-Server von Hostsharing einen vollqualifizieren Domainnamen zuweisen, der der jeweiligen IP-Adresse meiner Einwahlleitung zugeordnet ist.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
(ASCII-Art-Diagramm der beschriebenen Konstellation)&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Im Folgenden wird eine real existierende Implementierung von Dynamischem DNS (&amp;amp;bdquo;DDNS&amp;amp;ldquo;) beschrieben. Die verschiedenen Elemente könnten durchaus anders realisiert werden; die beschriebene Implementierung könnte durchaus verbessert werden. Sie dient hier der Illustration.&lt;br /&gt;
&lt;br /&gt;
In der folgenden Beschreibung werden diese Beispielwerte benutzt:&lt;br /&gt;
* Ein Hostsharing-Mitglied hat ein Account als Paket-Admin mit Kennung xyz00.&lt;br /&gt;
* Im Paket xyz00 gibt es einen Domain-Admin namens xyz00-benutzername.&lt;br /&gt;
* Dieser Domain-Admin verwaltet bei Hostsharing die Domains example.com und beispiel.de.&lt;br /&gt;
* Ein Benutzer hat zu Hause (oder im Büro) einen Arbeitsplatzrechner hinter der marktüblichen DSL-Leitung, die von seinem ISP bereitgestellt wird.&lt;br /&gt;
* Dieser Arbeitsplatzrechner (oder der Router, der seine Internetverbindung steuert) bekommt vom ISP immer wechselnde IP-Adressen zugewiesen.&lt;br /&gt;
* Dennoch möchte der Benutzer seinen Arbeitsplatzrechner aus dem Internet unter dem Hostnamen einwahl.example.com ansprechen können.&lt;br /&gt;
&lt;br /&gt;
Dazu kann ein System wie Hostsharing, das authoritative DNS-Informationen für viele Domains bereitstellt, auch veränderliche DNS-Information über dynamisch verbundene Rechner verwalten &amp;amp;ndash; sofern das ressourcenschonend gemacht werden kann ohne andere Funktionen zu stören.&lt;br /&gt;
&lt;br /&gt;
== Aufgaben des Servers ==&lt;br /&gt;
&lt;br /&gt;
Um einem Rechner mit wechselnder IP-Adresse einen DDNS-Eintrag zu bieten, muß der Hostsharing-Server folgendes leisten (in ungefährer Reihenfolge der Ereignisse):&lt;br /&gt;
&lt;br /&gt;
# Eine Anfrage entgegennehmen, beispielsweise über HTTPS, von einem entfernten Rechner, der einen DNS-Eintrag für seine momentane IP-Adresse wünscht. &lt;br /&gt;
# Prüfen, ob die Anfrage einen berechtigten DDNS-Dienst-Usernamen mit zugehörigem Paßwort enthält.&lt;br /&gt;
# Prüfen, ob die Anfrage einen gültigen Domainnamen betrifft, den der Server bieten darf.&lt;br /&gt;
# Prüfen, ob die Domain example.com demselben Benutzer gehört, unter dessen Namen der Dynamisches-DNS-Server läuft.&lt;br /&gt;
# Eine gültige [[Zonefile]] mit &amp;amp;ndash; neben dem bisherigen Inhalt &amp;amp;ndash; einem A-Eintrag für einwahl.example.com in /home/pacs/xyz00/users/benutzername/doms/example.com/pri.example.com schreiben.&lt;br /&gt;
# Dem Client eine Bestätigung oder ggf. eine Fehlermeldung als Antwort senden.&lt;br /&gt;
# In irgendeiner Datenbank den momentan eingestellter Status all seiner DDNS-Einträge speichern.&lt;br /&gt;
# In einer Logdatei protokollieren, daß obiges getan wurde, oder ggf. welche Fehler traten auf.&lt;br /&gt;
&lt;br /&gt;
== Aufgaben des Clients ==&lt;br /&gt;
Bevor ich anfange, meinen Arbeitsplatzrechner so zu konfigurieren, daß er bei welchem Server auch immer einen DDNS-Eintrag anfordert, muß ich mich als verantwortlicher Benutzer dieses Rechners und der dazugehörigen Internetverbindung &amp;amp;ndash; das heißt, als Mensch &amp;amp;ndash; mit dem Betreiber des dynamisches-DNS-Servers vereinbaren, daß ich das darf und welchen Eintrag ich bekommen kann. Im Folgenden wird vorausgesetzt, daß solche Vereinbarungen getroffen und die Parameter geklärt wurden.&lt;br /&gt;
&lt;br /&gt;
Der DDNS-Client muß aus Server-Sicht nur wenig leisten:&lt;br /&gt;
&lt;br /&gt;
# Eine Anfrage senden, beispielsweise über HTTPS, an einen entfernten Rechner, der einen Eintrag ins DNS für die momentane IP-Adresse des Clients vornehmen kann.&amp;lt;br /&amp;gt;Diese Anfrage muß einem festgelegten Format entsprechen und muß gültige Werte für die Authorisation des Clients, den gewünschten Domainnamen, und eventuell andere Parameter enthalten.&lt;br /&gt;
# Eine Antwort des Servers entgegennehmen und als Erfolgs- oder Fehlermeldung auswerten.&lt;br /&gt;
# Von überflüssigen Anfragen absehen: das heißt bei Erfolg, nicht wiederholt den gleichen Eintrag erneut wünschen; bei Fehlern, nicht die gleiche fehlerhafte Anfrage erneut schicken.&lt;br /&gt;
&lt;br /&gt;
== Kommunikation zwischen Client und Server ==&lt;br /&gt;
&lt;br /&gt;
Ein einziges Nachrichtenpaar von Anfrage und Antwort genügt, um einen DDNS-Eintrag einzurichten: Der Client teilt die IP-Adresse und den Domainnamen mit, die in einem DNS-Eintrag verbunden werden sollen; der Server bestätigt den Auftrag.&lt;br /&gt;
&lt;br /&gt;
In der Beispielimplementierung erfolgt die Kommunikation über HTTP, und die Anfrage des Clients könnte so aussehen:&lt;br /&gt;
&lt;br /&gt;
  GET /cgi-bin/ddns?hostname=einwahl.example.com&amp;amp;myip=87.65.43.21 HTTP/1.1&lt;br /&gt;
  Host: ddns.beispiel.de&lt;br /&gt;
  User-Agent: Fritz!Box DDNS/1.0.1&lt;br /&gt;
  Authorization: Basic QWxhZGRpbjpvcGVuIHNlc2FtZQ==&lt;br /&gt;
&lt;br /&gt;
Bei Erhalt dieser Anfrage ruft Apache das CGI-Programm .../doms/ddns.beispiel.de/cgi-ssl/ddns auf. Das Fragezeichen trennt den Programmnamen von einem &amp;quot;Query-String&amp;quot;, in dem zwei Metavariablen definiert und übergeben werden. Die erste Metavariable, hostname, hat den Wert &amp;quot;einwahl.example.com&amp;quot;; die zweite, myip, hat den Wert &amp;quot;87.65.43.21&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
Das Server-Programm, hier &#039;&#039;ddns&#039;&#039;, prüft diese Informationen auf Form und Berechtigung, und schreibt gegebenenfalls einen entsprechenden Eintrag in einer Zonefile. Es schreibt auch verschiedene Informationen in die Standardausgabe. Wenn es die Standardausgabe geschlossen wird &amp;amp;ndash; also spätestens bei Programmende &amp;amp;ndash; schickt Apache diese Informationen als Antwort an den anfragenden Rechner zurück.&lt;br /&gt;
&lt;br /&gt;
Im Falle unserer Beispielimplementierung sieht die Antwort bei Erfolg so aus: &lt;br /&gt;
&lt;br /&gt;
  HTTP/1.1 200 OK&lt;br /&gt;
  Date: Wed, 22 Apr 2020 08:35:15 GMT&lt;br /&gt;
  Server: Apache&lt;br /&gt;
  Content-Length: 17&lt;br /&gt;
  Content-Type: text/plain; charset=ISO-8859-1&lt;br /&gt;
 &lt;br /&gt;
  good 87.65.43.21&lt;br /&gt;
&lt;br /&gt;
=== Das DDNS-Protokoll von DynDNS.org ===&lt;br /&gt;
&lt;br /&gt;
In den 90er Jahren, bevor das Internet so durchgehend vergeschäftlicht wurde, boten einige Organisationen kostenlose DDNS-Dienste an. Ein sehr beliebtes Angebot war das von DynDNS.org. Das DDNS-Protokoll von diesem Dienst wurde sogar in Einwahl-Routern einprogrammiert und der Dienst wurde von ISPs und Router-Herstellern als Leistungsmerkmal beworben.&lt;br /&gt;
&lt;br /&gt;
DynDNS.org gehört inzwischen Oracle und bietet keine kostenlose Dienste mehr. Dennoch wird das DDNS-Protokoll von DynDNS.org in der vorliegenden Beispielimplementierung übernommen in der Hoffnung, daß die Kompatibilität mit einigen gängigen Einwahl-Routern von Vorteil sein kann. Es gibt noch eine kurze Online-Dokumentation der [https://help.dyn.com/remote-access-api/perform-update/ Anfrage] und [https://help.dyn.com/remote-access-api/perform-update/ Antwortnachrichten].&lt;br /&gt;
&lt;br /&gt;
Das gesammte Protokoll sieht einen einzigen Nachrichtenaustausch aus Anfrage und Antwort vor. Die Anfrage kann mehrere Argumente enthalten; die Antwort kann verschiedene Code-Wörtern enthalten. Übrigens können in einer einzigen Anfrage mehrere DNS-Einträge gewünscht werden. In diesem Fall kann die Antwort mehrzeilig ausfallen.&lt;br /&gt;
&lt;br /&gt;
Das Verhalten von Server und Client bei künftigen Kommunikationsvorgängen wird unter Umständen von vorangegangenen Kommunikationsergebnissen beeinflußt: nach wiederholten fehlerhaften oder redundanten Anfragen kann der Server weitere Anfragen des Benutzers verweigern; nach wiederholten Fehlermeldungen sollte ein Client aufhören, immer dieselbe Anfrage zu schicken. Und für den Fall, daß mehrere Clients dynamische DNS-Einträge in derselben Domain example.com bestellen, muß der Server den Stand aller Client-Einträge intern speichern, damit er nicht mit einer neuen Zonefile einen früher erstellten Eintrag löscht. Zu diesen Fragen siehe den Abschnitt &#039;&#039;&#039;[[#Sukzessive_Kommunikationsabläufe]]&#039;&#039;&#039; nach der Beschreibung von Anfragen und Antworten unten.&lt;br /&gt;
&lt;br /&gt;
====Anfrage====&lt;br /&gt;
&lt;br /&gt;
Die Anfrage in Form eines URL übergibt dem DDNS-Programm in einem &#039;Query-String&#039; einige Metavariablen. Das heißt, in einem URL der Form&lt;br /&gt;
&lt;br /&gt;
  &amp;lt;nowiki&amp;gt;https://benutzername:passwort@ddns.beisiel.de/cgi-bin/ddns?hostname=einwahl.example.com&amp;amp;myip=87.65.43.21&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
signalisert das Fragezeichen, daß ein Query-String folgt. In einem solchen Query-String können in der Beispielimplementierung folgende Metavariablen definiert werden:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|- class=&amp;quot;hintergrundfarbe5&amp;quot;&lt;br /&gt;
! Variable !! Beispiel !! Bemerkungen&lt;br /&gt;
|-&lt;br /&gt;
| hostname || &amp;lt;tt&amp;gt;hostname=einwahl.example.com&amp;lt;/tt&amp;gt;&amp;lt;br /&amp;gt;&amp;lt;div style=&amp;quot;font-size:smaller;&amp;quot;&amp;gt;&amp;lt;tt&amp;gt;hostname=eins.example.com,zwei.example.com[,...]&amp;lt;/tt&amp;gt;&amp;lt;/div&amp;gt; ||&lt;br /&gt;
Muß ein vollständig qualifizierter Domain-Name (&amp;quot;FQDN&amp;quot;) sein; &amp;lt;tt&amp;gt;example.com&amp;lt;/tt&amp;gt; muß eine vom Besitzer des DDNS-Programms verwaltete Domain sein. Genaugenommen kann der Wert eine durch Kommata gegliederte Liste mehrerer gültiger Domainnamen sein, falls mehrere Einträge mit derselben IP-Adresse gewünscht werden.&lt;br /&gt;
|-&lt;br /&gt;
| myip || &amp;lt;tt&amp;gt;myip=87.65.43.21&amp;lt;/tt&amp;gt;||&lt;br /&gt;
Kann entfallen; kann vom Server ignoriert werden. Maßgeblich ist dann die IP-Adresse des Absenders, wie sie vom Web-Server mitgeteilt wird.&lt;br /&gt;
|-&lt;br /&gt;
| mx || &amp;lt;tt&amp;gt;mx=87.65.43.21&amp;lt;/tt&amp;gt;&amp;lt;br /&amp;gt;&amp;lt;tt&amp;gt;mx=NOCHG&amp;lt;/tt&amp;gt;&amp;lt;br /&amp;gt; ||&lt;br /&gt;
Neben dem A-Eintrag möchte der Client auch einen MX-Eintrag. Der Wert &amp;lt;tt&amp;gt;NOCHG&amp;lt;/tt&amp;gt; (für &amp;amp;bdquo;no change&amp;amp;ldquo;) bedeutet, der bestehende MX-Eintrag (oder seine Abwesenheit) soll nicht geändert werden. &lt;br /&gt;
|-&lt;br /&gt;
| backmx || &amp;lt;tt&amp;gt;backmx=YES&amp;lt;/tt&amp;gt;&amp;lt;br /&amp;gt;&amp;lt;tt&amp;gt;backmx=NOCHG&amp;lt;/tt&amp;gt;&amp;lt;br /&amp;gt;&amp;lt;tt&amp;gt;backmx=NO&amp;lt;/tt&amp;gt;   ||&lt;br /&gt;
Falls &amp;lt;tt&amp;gt;YES&amp;lt;/tt&amp;gt;, wird ein zweiter MX-Eintrag erzeugt, der &amp;lt;tt&amp;gt;einwahl.example.com&amp;lt;/tt&amp;gt; als Mail-Server für &amp;lt;tt&amp;gt;einwahl.example.com&amp;lt;/tt&amp;gt; nennt. Dieser Eintrag hat eine niedrigere Präferenzzahl (also eine höhere Priorität) als der mit &amp;lt;tt&amp;gt;mx&amp;lt;/tt&amp;gt; angeforderten Eintrag.&lt;br /&gt;
|-&lt;br /&gt;
| wildcard || &amp;lt;tt&amp;gt;wildcard=ON&amp;lt;/tt&amp;gt;&amp;lt;br /&amp;gt;&amp;lt;tt&amp;gt;wildcard=NOCHG&amp;lt;/tt&amp;gt;&amp;lt;br /&amp;gt;&amp;lt;tt&amp;gt;wildcard=OFF&amp;lt;/tt&amp;gt; ||&lt;br /&gt;
Neben dem A-Eintrag für den Domainnamen &amp;lt;tt&amp;gt;einwahl.example.com&amp;lt;/tt&amp;gt; wünscht der Client auch einen Eintrag für beliebige Subdomains, also &amp;lt;tt&amp;gt;*.einwahl.example.com&amp;lt;/tt&amp;gt;, mit der gleichen IP-Adresse.&lt;br /&gt;
|-&lt;br /&gt;
| offline ||&amp;lt;tt&amp;gt;offline=YES&amp;lt;/tt&amp;gt;&amp;lt;br /&amp;gt;&amp;lt;tt&amp;gt;offline=NOCHG&amp;lt;/tt&amp;gt;||&lt;br /&gt;
Falls &amp;lt;tt&amp;gt;YES&amp;lt;/tt&amp;gt;, wird ein DNS-Eintrag für &amp;lt;tt&amp;gt;einwahl.example.com&amp;lt;/tt&amp;gt; aus der Zonefile getilgt. Gegebenenfalls wird der Hostname dann auf Grund eines parallelen Wildcard-Eintrags für &amp;lt;tt&amp;gt;*.example.com&amp;lt;/tt&amp;gt; einer anderen IP-Adresse zugeordnet werden.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;!-- IPv6? --&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Alle Parameter bis auf hostname können entfallen. Bei nichtdokumentierten Argumenten ist das Verhalten undefiniert&amp;amp;trade;.&lt;br /&gt;
&lt;br /&gt;
====Antwort====&lt;br /&gt;
&lt;br /&gt;
Die Antwort auf eine erfolgreiche HTTP-Anfrage besteht im häufigsten Fall aus einigen Header-Zeilen, gefolgt vom Inhalt der gewünschten Text- oder andere Datei. Ein Status-Code in der ersten Header-Zeile gibt an, ob die Anfrage bedient werden kann oder kreist andernfalls den Grund für die Enttäuschung ein.&lt;br /&gt;
&lt;br /&gt;
Die vorliegende Beispielimplementierung von DDNS schickt einen der üblichen HTTP-Status-Codes &amp;quot;200 OK&amp;quot; oder &amp;quot;500 Internal Server Error&amp;quot;, gefolgt von einer kurzen Textnachricht nach dem HTTP-Header. Bei diesem Programm  ist &amp;amp;ndash; laut Gebrauchshinweise von DynDNS.org &amp;amp;ndash; &#039;&#039;nicht&#039;&#039; der Status-Code im Header, sondern der Inhalt der Nachricht  die definierte, maßgebliche Ergebnismeldung des Programms.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|- class=&amp;quot;hintergrundfarbe5&amp;quot;&lt;br /&gt;
! Meldung !! Bedeutung !! Bemerkungen&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;good&amp;amp;nbsp;&amp;amp;lt;IP&amp;amp;nbsp;number&amp;amp;gt;&amp;lt;/tt&amp;gt; ||&lt;br /&gt;
Der gewünschte DNS-Eintrag wurde erfolgreich in einer Zonefile eingetragen. &lt;br /&gt;
|| Es kann natürlich noch einige Minuten dauern, bis die Zonefile vom Hostsharing-Roboter abgelesen wird und der Inhalt in die BIND-Konfiguration übernommen.&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;good&amp;amp;nbsp;0.0.0.0&amp;lt;/tt&amp;gt; ||&lt;br /&gt;
Das Argument &amp;lt;tt&amp;gt;offline=YES&amp;lt;/tt&amp;gt; wurde empfangen und verarbeitet.&lt;br /&gt;
|| Der Domainname hat also keinen dynamischen DNS-Eintrag mehr.&lt;br /&gt;
|-&lt;br /&gt;
&amp;lt;!-- We don&#039;t do this!&lt;br /&gt;
| &amp;lt;tt&amp;gt;good&amp;amp;nbsp;127.0.0.1&amp;lt;/tt&amp;gt; ||&lt;br /&gt;
Die Anfrage entsprach nicht den Erfordernissen des Servers.&lt;br /&gt;
|| Trotz des Worts &amp;lt;tt&amp;gt;good&amp;lt;/tt&amp;gt; war die Anfrage nicht erfolgreich, falls in der Rückmeldung die IP-Adresse mit &amp;lt;tt&amp;gt;127.0.0.1&amp;lt;/tt&amp;gt; angegeben wird. Dieser verwirrende Fehlercode ist aus unerklärlichen Gründen in der Spezifikation von DynDNS.org so definiert.&lt;br /&gt;
|-&lt;br /&gt;
--&amp;gt;&lt;br /&gt;
| &amp;lt;tt&amp;gt;nochg&amp;amp;nbsp;&amp;amp;lt;IP&amp;amp;nbsp;number&amp;amp;gt;&amp;lt;/tt&amp;gt; ||&lt;br /&gt;
Der gewünschte DNS-Eintrag war bereits vorhanden. &lt;br /&gt;
|| Der Server selbst macht keine DNS-Abfrage, um das zu vermitteln: die &amp;amp;bdquo;no change&amp;amp;ldquo;-Antwort besagt nur, daß eine Anfrage für diesen Eintrag bereits mit Erfolg quittiert wurde.&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;notfqdn&amp;lt;/tt&amp;gt; ||&lt;br /&gt;
Fehlschlag: der gewünschte Domainname ist nicht gültig, oder es wurde keiner angegeben.&lt;br /&gt;
|| ...&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;nohost&amp;lt;/tt&amp;gt; ||&lt;br /&gt;
Fehlschlag: der gewünschte Domainname ist gehört nicht zu denen, die für diesen Benutzer des DDNS-Dienstes konfiguriert sind.&lt;br /&gt;
|| Siehe den Abschnitt [[#Administration|Administration]] weiter unten.&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;badauth&amp;lt;/tt&amp;gt; ||&lt;br /&gt;
Fehlschlag: Die Kombination von Benutzernamen und Paßwort entsprach keinem DDNS-Account, oder das Account ist momentan gesperrt.&lt;br /&gt;
|| Ein gesperrtes Account kann nur der Domain-Admin mittels des Administrationswerkzeugs wieder freigeben: siehe den Abschnit [[#Administration|Administration]] weiter unten.&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;abuse&amp;lt;/tt&amp;gt; ||&lt;br /&gt;
Fehlschlag: der gewünschte Domainname ist wegen vorangeganger Fehlschläge oder überflüssiger Aufrufe gesperrt.&lt;br /&gt;
|| Siehe den Abschnitt [[#Sukzessive_Kommunikationsabläufe|Sukzessive Kommunikationsabläufe]] unten.&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;911&amp;lt;/tt&amp;gt; ||&lt;br /&gt;
Fehlschlag: Das Server-Programm hat einen internen Fehler festgestellt.&lt;br /&gt;
|| Das Problem liegt nicht in der Anfrage an sich.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Man kann sich durchaus eine sinnreichere Kommunikation zwischen Client und Server vorstellen, doch das hier beschriebene Protokoll ist eben von DynDNS.org verwendet worden und wird in gängigen Routern implementiert, also wird es in der vorliegenden DDNS-Implementierung nachgebildet.&lt;br /&gt;
&lt;br /&gt;
=== Sukzessive Kommunikationsabläufe ===&lt;br /&gt;
Der Server muß sich zwischen einzelnen Aufrufen einiges merken, um Ressourcen zu schonen und um zu verhindern, daß einmal vergebene DDNS-Einträge von neuen Anfragen, die dieselbe übergeordnete Domain betreffen, durch Überschreiben  verlorengehen.&lt;br /&gt;
&lt;br /&gt;
==== Mißbrauch und Benutzersperrung ====&lt;br /&gt;
Zur Schonung von Ressourcen muß sich die Implementierung weigern, sich mit zuvielen fehlerhaften oder auch nur überflüssigen Anfragen zu beschäftigen. Dazu führt der Server eine Strichliste über solche Anfragen jedes Clients und sperrt nach einer bestimmten Anzahl solcher Anfragen den Benutzernamen oder einzelne Domainnamen gegen die weitere Nutzung des Dienstes.&lt;br /&gt;
&lt;br /&gt;
Mißbrauchspunkte gegen einen einzelnen Domainnamen gibt es für:&lt;br /&gt;
* eine Anfrage, die keinen neuen DNS-Eintrag (und keine Änderung oder Löschung eines Eintrags) erfordert, sondern bestehende Merkmale nur wiederholt&lt;br /&gt;
&lt;br /&gt;
Mißbrauchspunkte gegen einen Benutzernamen gibt es für:&lt;br /&gt;
* die Angabe eines Domainnamens, der in der Dienstkonfiguration dem anfragenden Benutzernamen nicht zugeordnet ist&lt;br /&gt;
* die Angabe eines Domainnamen in einer Domain, die nicht demselben Hostsharing-Domain-Admin gehört, der den DDNS-Dienst anbietet&lt;br /&gt;
* die Angabe eines Domainnamens, der in der Dienstkonfiguration bereits wegen mißbräuchlicher Anfragen gesperrt ist (siehe oben)&lt;br /&gt;
&lt;br /&gt;
Um eine Sperrung aufzuheben, wird in der Regel eine Handlung durch den Administrator erforderlich sein.&lt;br /&gt;
&lt;br /&gt;
==== Mehrere dynamische Subdomains in derselben Domain ====&lt;br /&gt;
Sobald zwei verschiedene DDNS-Einträge in derselben Domain verlangt werden &amp;amp;ndash; beispielsweise home.example.com und office.example.com &amp;amp;ndash; wird es notwendig, bei jeder neuen Zonefile für example.com eventuell frühere Einträge zu konservieren. Der Rechner zu Hause weiß beim Bestellen seines DDNS-Eintrags nichts vom Rechner im Büro und umgekehrt. Der Server muß in irgendeiner Form über bereits vergebene Einträge Buch führen und bei einer neuen Anfrage, die example.com betrifft, alle bereits aktiven DDNS-Einträge für example.com mit in die neue Zonefile aufnehmen &amp;amp;ndash auch wenn sie auf Anfragen verschiedener Benutzer zurückgehen.&lt;br /&gt;
&lt;br /&gt;
==== Datenbank ====&lt;br /&gt;
In der Beispielimplementierung werden diese Informationen in einer SQLite-Datenbank gespeichert.&lt;br /&gt;
&lt;br /&gt;
== Sicherheit ==&lt;br /&gt;
=== Rechte ===&lt;br /&gt;
Die &#039;&#039;&#039;Benutzerrechte&#039;&#039;&#039; werden durch das Hostsharing-System kontrolliert. Sowohl das CGI-Programm als auch das [[#Administration|Administrationswerkzeug]] werden mit den Rechten des Domain-Admins (xyz00-benutzername in unserem Beispiel) ausgeführt, also kann dieses Programm nur die Domains bearbeiten, die von xyz00-benutzername verwaltet werden.&lt;br /&gt;
&lt;br /&gt;
=== Authentifizierung ===&lt;br /&gt;
In der Beispielimplementierung (wie auch seinerzeit bei DynDNS.org) wird das CGI-Programm durch einen .htaccess-Eintrag geschützt, der HTTP-Basic-Authentication vorschreibt. Also wird das Programm eigentlich mit einem URL der form&lt;br /&gt;
&lt;br /&gt;
  &amp;lt;nowiki&amp;gt;https://ddnsaccount:passwort@ddns.example.com/cgi-bin/ddns?hostname=...&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
aufgerufen.&lt;br /&gt;
&lt;br /&gt;
=== Verschlüsselung ===&lt;br /&gt;
Das CGI-Programm sollte nur in example.com/cgi-ssl/ installiert werden, nicht in example.com/cgi/. Damit ist die Kommunikation zwischen Client und Server durch SSL verschlüsselt.&lt;br /&gt;
&lt;br /&gt;
== Administration ==&lt;br /&gt;
&lt;br /&gt;
Der Verwalter des DDNS-Programms trägt berechtigte Benutzer und die ihnen zugeteilten Domainnamen in die Datenbank des Programms ein mit Hilfe eines kleinen Hilfsprogramms. Das ist im vorliegenden Fall ein menügesteuertes Programm für die Befehlszeile, daß die naheliegenden Funktionen anbietet: Account hinzufügen, löschen, sperren, entsperren, Paßwort setzen, ändern; Domainnamen hinzufügen, ändern, entsperren, löschen; Accounts und Domainnamen mit aktuellem Status auflisten. Die Funktionen sind auch über Befehlszeilenargumente verfügbar, also skriptfähig.&lt;br /&gt;
&lt;br /&gt;
Eine Übersicht der Funktionen des Administrationswerkzeugs gibt dieses selbst aus:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
xyz00-benutzername@h02:~$ bin/ddnsadmin -h&lt;br /&gt;
ddnsadmin.pl: Verwaltungswerkzeug für ddns&lt;br /&gt;
&lt;br /&gt;
Verwendung:&lt;br /&gt;
    ddnsadmin -A{[ahlusf]} [&amp;lt;Account&amp;gt;] [-f &amp;lt;DB-Datei&amp;gt;]&lt;br /&gt;
    ddnsadmin -D{[ahlsf]} [&amp;lt;Domain&amp;gt;] -A &amp;lt;Account&amp;gt; [-f &amp;lt;DB-Datei&amp;gt;]&lt;br /&gt;
    ddnsadmin -E &amp;lt;Einstellung&amp;gt; &amp;lt;Wert&amp;gt; [-f &amp;lt;DB-Datei&amp;gt;]&lt;br /&gt;
    ddnsadmin [-f &amp;lt;DB-Datei&amp;gt;] [-n]&lt;br /&gt;
&lt;br /&gt;
Wenn keine Option oder nur -f &amp;lt;DB-Datei&amp;gt; angegeben wird, bietet&lt;br /&gt;
ddnsadmin.pl eine interaktive Menüoberfläche.&lt;br /&gt;
&lt;br /&gt;
Optionen:&lt;br /&gt;
    -f &amp;lt;DB-Datei&amp;gt;                    Angegebene Datenbankdatei verwenden&lt;br /&gt;
    -n                               Neue, leere Datenbank erzeugen&lt;br /&gt;
    -Aa  [&amp;lt;Account&amp;gt;]                 Account(s) auflisten&lt;br /&gt;
    -Ah &amp;lt;Account&amp;gt; &amp;lt;Paßwort&amp;gt;          Account hinzufügen&lt;br /&gt;
    -A{lsf} &amp;lt;Account&amp;gt;                Account löschen, sperren, freigeben&lt;br /&gt;
    -Au &amp;lt;Account&amp;gt; &amp;lt;Name&amp;gt;             Account umbenennen&lt;br /&gt;
    -A  &amp;lt;Account&amp;gt; -Da [&amp;lt;Domain&amp;gt;]     Domain(s) auflisten&lt;br /&gt;
    -A  &amp;lt;Account&amp;gt; -D{hlsf} &amp;lt;Domain&amp;gt;  Domain hinzufügen,&lt;br /&gt;
                                     löschen, sperren, freigeben&lt;br /&gt;
    -E &amp;lt;Einstellung&amp;gt; &amp;lt;Wert&amp;gt;          Einstellung ändern&lt;br /&gt;
    -h                               Diese Übersicht ausgeben&lt;br /&gt;
&lt;br /&gt;
Einstellungen: &lt;br /&gt;
    maxacctabuse    Anzahl der mißbräuchlichen Aufrufe,&lt;br /&gt;
                    bevor ein Account gesperrt wird&lt;br /&gt;
    maxhostabuse    Anzahl der mißbräuchlichen Aufrufe,&lt;br /&gt;
                    bevor ein Domainname gesperrt wird&lt;br /&gt;
    safeinterval    Mindestabstand zwischen redundanten Aufrufen&lt;br /&gt;
                    (in Sekunden)&lt;br /&gt;
    cgihost         Server, der das DDNS-Skript bereithält&lt;br /&gt;
&lt;br /&gt;
xyz00-benutzername@h02:~$ &lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Eine Auflistung des momentanen Inhalts der DDNS-Datenbank durch das Administrationswerkzeug könnte beispielsweise so aussehen:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  xyz00-benutzername@h02:~$ bin/ddnsadmin.pl -Aa&lt;br /&gt;
  1.  papst	Mißbrauch: 0; gesperrt: nein&lt;br /&gt;
  	avignon.example.com&lt;br /&gt;
  		zuletzt aktiv am Sun Apr 26 22:24:49 2020&lt;br /&gt;
  		mit IP-Nr. 87.65.43.21; MX: 0;  Backup-MX: nein;&lt;br /&gt;
  		Subdomains: nein; Mißbrauch: 0;  gesperrt: nein&lt;br /&gt;
  	vatican.beispiel.de&lt;br /&gt;
  		zuletzt aktiv am Sun Apr 26 22:24:49 2020&lt;br /&gt;
  		mit IP-Nr. 87.65.43.21; MX: 0;  Backup-MX: nein;&lt;br /&gt;
  		Subdomains: nein; Mißbrauch: 0;  gesperrt: nein&lt;br /&gt;
  2.  kaiser	Mißbrauch: 4; gesperrt: ja&lt;br /&gt;
  	augsburg.beispiel.de&lt;br /&gt;
  		zuletzt aktiv am Fri Apr 24 16:13:49 2020&lt;br /&gt;
  		mit IP-Nr. 64.82.31.75; MX: 0;  Backup-MX: nein;&lt;br /&gt;
  		Subdomains: nein; Mißbrauch: 0;  gesperrt: ja&lt;br /&gt;
  3.  luther	Mißbrauch: 1; gesperrt: nein&lt;br /&gt;
  	wittenberg.example.com&lt;br /&gt;
  		zuletzt aktiv am Mon Apr 27 10:12:49 2020&lt;br /&gt;
  		mit IP-Nr. 78.56.34.12; MX: 0;  Backup-MX: nein;&lt;br /&gt;
  		Subdomains: nein; Mißbrauch: 1;  gesperrt: nein&lt;br /&gt;
  xyz00-benutzername@h02:~$&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Das DDNS-Account &amp;amp;bdquo;kaiser&amp;amp;ldquo; in dieser Auflistung ist wohl auf Grund fehlerhafter Anfragen automatisch gesperrt worden. Der Inhaber wird sich wohl bald melden, um nach Korrektur seiner Client-Konfiguration die Aufhebung der Sperre zu wünschen.&lt;br /&gt;
&lt;br /&gt;
=== Log ===&lt;br /&gt;
Alle Anfragen werden in einer täglich wechselnden Log-Datei protokolliert, entweder schlicht oder ausführlich, je nachdem, ob eine Variable &amp;lt;tt&amp;gt;verbose&amp;lt;/tt&amp;gt; wahr ist.&lt;br /&gt;
Ein ausführlicher Log-Eintrag sieht so aus:&lt;br /&gt;
&lt;br /&gt;
  Sun Apr 26 20:21:45 2020  ddns aufgerufen von papst&lt;br /&gt;
  			unter 84.185.97.8&lt;br /&gt;
  	URL: &amp;lt;nowiki&amp;gt;https://ddns.example.com/cgi-bin/ddns.cgi?hostname=&lt;br /&gt;
  			avignon.example.com,vatican.beispiel.de&amp;amp;&lt;br /&gt;
  			myip=84.185.97.8&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
  	Verwende IP 84.185.97.8 (= 1421435144)&lt;br /&gt;
  	DB-Version: 1&lt;br /&gt;
  	Skript und DB exklusiv geöffnet&lt;br /&gt;
  	avignon.example.com: IP: 84.185.97.8; MX: 0; Backup-MX: nein;&lt;br /&gt;
  			Wildcard: nein; Mißbrauch: 0; gesperrt: nein &lt;br /&gt;
  	vatican.beispiel.de: IP: 84.185.97.8; MX: 0; Backup-MX: nein;&lt;br /&gt;
  			Wildcard: nein; Mißbrauch: 0; gesperrt: nein &lt;br /&gt;
  	Betroffene Zonen: example.com, beispiel.de&lt;br /&gt;
  	Temporärdatei example.com_hxNa.new geschrieben&lt;br /&gt;
  	Zonendatei /home/pacs/xyz00/users/benutzername/doms/example.com/&lt;br /&gt;
  			etc/pri.example.com eingestellt&lt;br /&gt;
  	Temporärdatei beispiel.de_6HcO.new geschrieben&lt;br /&gt;
  	Zonendatei /home/pacs/xyz00/users/benutzername/doms/beispiel.de/&lt;br /&gt;
  			etc/pri.beispiel.de eingestellt&lt;br /&gt;
  	Abgeschlossen: 	Fertig&lt;br /&gt;
&lt;br /&gt;
Wenn &amp;lt;tt&amp;gt;verbose&amp;lt;/tt&amp;gt; auf falsch gesetzt ist, sind die Log-Einträge einzeilig.&lt;/div&gt;</summary>
		<author><name>Apc00-tony</name></author>
	</entry>
	<entry>
		<id>https://wiki.hostsharing.net/index.php?title=Benutzer:Apc00-tony/Dynamisches_DNS&amp;diff=6227</id>
		<title>Benutzer:Apc00-tony/Dynamisches DNS</title>
		<link rel="alternate" type="text/html" href="https://wiki.hostsharing.net/index.php?title=Benutzer:Apc00-tony/Dynamisches_DNS&amp;diff=6227"/>
		<updated>2023-09-11T14:33:55Z</updated>

		<summary type="html">&lt;p&gt;Apc00-tony: Update 2023&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Update 2023: Ich habe die Verwaltung über Befehlszeile durch eine PHP-Web-Oberfläche ersetzt; Details irgendwo ... ah, [http://hier https://ddns.crawfords.de/verwaltung/ddnsadminhints?name=acanthus_crawford_berlin]. Meine Hostsharing-DDNS-Lösung läuft übrigens schon lange einwandfrei; ich benutze sie dazu, ein VPN zwischen meinen Fritz!Box-LANS zu Hause und im Büro zu realisieren sowie um auf ein Backup- und Music-Server (ein Raspberry Pi) zu Hause von unterwegs zuzugreifen.&lt;br /&gt;
&lt;br /&gt;
((Provisorischer Vorspann: Auf Grund einer Mailing-Listen-Diskussion habe ich angefangen, Dynamisches DNS über einen CGI-Skript bei Hostsharing zu realisieren. Meine Lösung habe ich dann vorgestellt; sie wurde für nicht ausreichend selbsterklärend befunden und fand wenig Akzeptanz. Hier also der Versuch, die Sache zu dokumentieren.))&lt;br /&gt;
&lt;br /&gt;
Mit der regelmäßigen Aufnahme von benutzerspezifischen Zonefiles in seiner DNS-Konfiguration bietet  Hostsharing alles, was man braucht, um &amp;amp;bdquo;dynamisches DNS&amp;amp;ldquo; in Eigenregie zu realisieren.&lt;br /&gt;
&lt;br /&gt;
Das heißt, wenn ich mindestens eine Domain bei Hostsharing verwalte, und mindestens eine Einwahlverbindung (oder DSL-Verbindung) ins Internet mit wechselnder IP-Adresse über irgendeinen ISP für meinen Arbeitsplatzrechner zu Hause betreibe, dann kann ich dem Arbeitsplatzrechner über die DNS-Server von Hostsharing einen vollqualifizieren Domainnamen zuweisen, der der jeweiligen IP-Adresse meiner Einwahlleitung zugeordnet ist.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
(ASCII-Art-Diagramm der beschriebenen Konstellation)&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Im Folgenden wird eine real existierende Implementierung von Dynamischem DNS (&amp;amp;bdquo;DDNS&amp;amp;ldquo;) beschrieben. Die verschiedenen Elemente könnten durchaus anders realisiert werden; die beschriebene Implementierung könnte durchaus verbessert werden. Sie dient hier der Illustration.&lt;br /&gt;
&lt;br /&gt;
In der folgenden Beschreibung werden diese Beispielwerte benutzt:&lt;br /&gt;
* Ein Hostsharing-Mitglied hat ein Account als Paket-Admin mit Kennung xyz00.&lt;br /&gt;
* Im Paket xyz00 gibt es einen Domain-Admin namens xyz00-benutzername.&lt;br /&gt;
* Dieser Domain-Admin verwaltet bei Hostsharing die Domains example.com und beispiel.de.&lt;br /&gt;
* Ein Benutzer hat zu Hause (oder im Büro) einen Arbeitsplatzrechner hinter der marktüblichen DSL-Leitung, die von seinem ISP bereitgestellt wird.&lt;br /&gt;
* Dieser Arbeitsplatzrechner (oder der Router, der seine Internetverbindung steuert) bekommt vom ISP immer wechselnde IP-Adressen zugewiesen.&lt;br /&gt;
* Dennoch möchte der Benutzer seinen Arbeitsplatzrechner aus dem Internet unter dem Hostnamen einwahl.example.com ansprechen können.&lt;br /&gt;
&lt;br /&gt;
Dazu kann ein System wie Hostsharing, das authoritative DNS-Informationen für viele Domains bereitstellt, auch veränderliche DNS-Information über dynamisch verbundene Rechner verwalten &amp;amp;ndash; sofern das ressourcenschonend gemacht werden kann ohne andere Funktionen zu stören.&lt;br /&gt;
&lt;br /&gt;
== Aufgaben des Servers ==&lt;br /&gt;
&lt;br /&gt;
Um einem Rechner mit wechselnder IP-Adresse einen DDNS-Eintrag zu bieten, muß der Hostsharing-Server folgendes leisten (in ungefährer Reihenfolge der Ereignisse):&lt;br /&gt;
&lt;br /&gt;
# Eine Anfrage entgegennehmen, beispielsweise über HTTPS, von einem entfernten Rechner, der einen DNS-Eintrag für seine momentane IP-Adresse wünscht. &lt;br /&gt;
# Prüfen, ob die Anfrage einen berechtigten DDNS-Dienst-Usernamen mit zugehörigem Paßwort enthält.&lt;br /&gt;
# Prüfen, ob die Anfrage einen gültigen Domainnamen betrifft, den der Server bieten darf.&lt;br /&gt;
# Prüfen, ob die Domain example.com demselben Benutzer gehört, unter dessen Namen der Dynamisches-DNS-Server läuft.&lt;br /&gt;
# Eine gültige [[Zonefile]] mit &amp;amp;ndash; neben dem bisherigen Inhalt &amp;amp;ndash; einem A-Eintrag für einwahl.example.com in /home/pacs/xyz00/users/benutzername/doms/example.com/pri.example.com schreiben.&lt;br /&gt;
# Dem Client eine Bestätigung oder ggf. eine Fehlermeldung als Antwort senden.&lt;br /&gt;
# In irgendeiner Datenbank den momentan eingestellter Status all seiner DDNS-Einträge speichern.&lt;br /&gt;
# In einer Logdatei protokollieren, daß obiges getan wurde, oder ggf. welche Fehler traten auf.&lt;br /&gt;
&lt;br /&gt;
== Aufgaben des Clients ==&lt;br /&gt;
Bevor ich anfange, meinen Arbeitsplatzrechner so zu konfigurieren, daß er bei welchem Server auch immer einen DDNS-Eintrag anfordert, muß ich mich als verantwortlicher Benutzer dieses Rechners und der dazugehörigen Internetverbindung &amp;amp;ndash; das heißt, als Mensch &amp;amp;ndash; mit dem Betreiber des dynamisches-DNS-Servers vereinbaren, daß ich das darf und welchen Eintrag ich bekommen kann. Im Folgenden wird vorausgesetzt, daß solche Vereinbarungen getroffen und die Parameter geklärt wurden.&lt;br /&gt;
&lt;br /&gt;
Der DDNS-Client muß aus Server-Sicht nur wenig leisten:&lt;br /&gt;
&lt;br /&gt;
# Eine Anfrage senden, beispielsweise über HTTPS, an einen entfernten Rechner, der einen Eintrag ins DNS für die momentane IP-Adresse des Clients vornehmen kann.&amp;lt;br /&amp;gt;Diese Anfrage muß einem festgelegten Format entsprechen und muß gültige Werte für die Authorisation des Clients, den gewünschten Domainnamen, und eventuell andere Parameter enthalten.&lt;br /&gt;
# Eine Antwort des Servers entgegennehmen und als Erfolgs- oder Fehlermeldung auswerten.&lt;br /&gt;
# Von überflüssigen Anfragen absehen: das heißt bei Erfolg, nicht wiederholt den gleichen Eintrag erneut wünschen; bei Fehlern, nicht die gleiche fehlerhafte Anfrage erneut schicken.&lt;br /&gt;
&lt;br /&gt;
== Kommunikation zwischen Client und Server ==&lt;br /&gt;
&lt;br /&gt;
Ein einziges Nachrichtenpaar von Anfrage und Antwort genügt, um einen DDNS-Eintrag einzurichten: Der Client teilt die IP-Adresse und den Domainnamen mit, die in einem DNS-Eintrag verbunden werden sollen; der Server bestätigt den Auftrag.&lt;br /&gt;
&lt;br /&gt;
In der Beispielimplementierung erfolgt die Kommunikation über HTTP, und die Anfrage des Clients könnte so aussehen:&lt;br /&gt;
&lt;br /&gt;
  GET /cgi-bin/ddns?hostname=einwahl.example.com&amp;amp;myip=87.65.43.21 HTTP/1.1&lt;br /&gt;
  Host: ddns.beispiel.de&lt;br /&gt;
  User-Agent: Fritz!Box DDNS/1.0.1&lt;br /&gt;
  Authorization: Basic QWxhZGRpbjpvcGVuIHNlc2FtZQ==&lt;br /&gt;
&lt;br /&gt;
Bei Erhalt dieser Anfrage ruft Apache das CGI-Programm .../doms/ddns.beispiel.de/cgi-ssl/ddns auf. Das Fragezeichen trennt den Programmnamen von einem &amp;quot;Query-String&amp;quot;, in dem zwei Metavariablen definiert und übergeben werden. Die erste Metavariable, hostname, hat den Wert &amp;quot;einwahl.example.com&amp;quot;; die zweite, myip, hat den Wert &amp;quot;87.65.43.21&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
Das Server-Programm, hier &#039;&#039;ddns&#039;&#039;, prüft diese Informationen auf Form und Berechtigung, und schreibt gegebenenfalls einen entsprechenden Eintrag in einer Zonefile. Es schreibt auch verschiedene Informationen in die Standardausgabe. Wenn es die Standardausgabe geschlossen wird &amp;amp;ndash; also spätestens bei Programmende &amp;amp;ndash; schickt Apache diese Informationen als Antwort an den anfragenden Rechner zurück.&lt;br /&gt;
&lt;br /&gt;
Im Falle unserer Beispielimplementierung sieht die Antwort bei Erfolg so aus: &lt;br /&gt;
&lt;br /&gt;
  HTTP/1.1 200 OK&lt;br /&gt;
  Date: Wed, 22 Apr 2020 08:35:15 GMT&lt;br /&gt;
  Server: Apache&lt;br /&gt;
  Content-Length: 17&lt;br /&gt;
  Content-Type: text/plain; charset=ISO-8859-1&lt;br /&gt;
 &lt;br /&gt;
  good 87.65.43.21&lt;br /&gt;
&lt;br /&gt;
=== Das DDNS-Protokoll von DynDNS.org ===&lt;br /&gt;
&lt;br /&gt;
In den 90er Jahren, bevor das Internet so durchgehend vergeschäftlicht wurde, boten einige Organisationen kostenlose DDNS-Dienste an. Ein sehr beliebtes Angebot war das von DynDNS.org. Das DDNS-Protokoll von diesem Dienst wurde sogar in Einwahl-Routern einprogrammiert und der Dienst wurde von ISPs und Router-Herstellern als Leistungsmerkmal beworben.&lt;br /&gt;
&lt;br /&gt;
DynDNS.org gehört inzwischen Oracle und bietet keine kostenlose Dienste mehr. Dennoch wird das DDNS-Protokoll von DynDNS.org in der vorliegenden Beispielimplementierung übernommen in der Hoffnung, daß die Kompatibilität mit einigen gängigen Einwahl-Routern von Vorteil sein kann. Es gibt noch eine kurze Online-Dokumentation der [https://help.dyn.com/remote-access-api/perform-update/ Anfrage] und [https://help.dyn.com/remote-access-api/perform-update/ Antwortnachrichten].&lt;br /&gt;
&lt;br /&gt;
Das gesammte Protokoll sieht einen einzigen Nachrichtenaustausch aus Anfrage und Antwort vor. Die Anfrage kann mehrere Argumente enthalten; die Antwort kann verschiedene Code-Wörtern enthalten. Übrigens können in einer einzigen Anfrage mehrere DNS-Einträge gewünscht werden. In diesem Fall kann die Antwort mehrzeilig ausfallen.&lt;br /&gt;
&lt;br /&gt;
Das Verhalten von Server und Client bei künftigen Kommunikationsvorgängen wird unter Umständen von vorangegangenen Kommunikationsergebnissen beeinflußt: nach wiederholten fehlerhaften oder redundanten Anfragen kann der Server weitere Anfragen des Benutzers verweigern; nach wiederholten Fehlermeldungen sollte ein Client aufhören, immer dieselbe Anfrage zu schicken. Und für den Fall, daß mehrere Clients dynamische DNS-Einträge in derselben Domain example.com bestellen, muß der Server den Stand aller Client-Einträge intern speichern, damit er nicht mit einer neuen Zonefile einen früher erstellten Eintrag löscht. Zu diesen Fragen siehe den Abschnitt &#039;&#039;&#039;[[#Sukzessive_Kommunikationsabläufe]]&#039;&#039;&#039; nach der Beschreibung von Anfragen und Antworten unten.&lt;br /&gt;
&lt;br /&gt;
====Anfrage====&lt;br /&gt;
&lt;br /&gt;
Die Anfrage in Form eines URL übergibt dem DDNS-Programm in einem &#039;Query-String&#039; einige Metavariablen. Das heißt, in einem URL der Form&lt;br /&gt;
&lt;br /&gt;
  &amp;lt;nowiki&amp;gt;https://benutzername:passwort@ddns.beisiel.de/cgi-bin/ddns?hostname=einwahl.example.com&amp;amp;myip=87.65.43.21&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
signalisert das Fragezeichen, daß ein Query-String folgt. In einem solchen Query-String können in der Beispielimplementierung folgende Metavariablen definiert werden:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|- class=&amp;quot;hintergrundfarbe5&amp;quot;&lt;br /&gt;
! Variable !! Beispiel !! Bemerkungen&lt;br /&gt;
|-&lt;br /&gt;
| hostname || &amp;lt;tt&amp;gt;hostname=einwahl.example.com&amp;lt;/tt&amp;gt;&amp;lt;br /&amp;gt;&amp;lt;div style=&amp;quot;font-size:smaller;&amp;quot;&amp;gt;&amp;lt;tt&amp;gt;hostname=eins.example.com,zwei.example.com[,...]&amp;lt;/tt&amp;gt;&amp;lt;/div&amp;gt; ||&lt;br /&gt;
Muß ein vollständig qualifizierter Domain-Name (&amp;quot;FQDN&amp;quot;) sein; &amp;lt;tt&amp;gt;example.com&amp;lt;/tt&amp;gt; muß eine vom Besitzer des DDNS-Programms verwaltete Domain sein. Genaugenommen kann der Wert eine durch Kommata gegliederte Liste mehrerer gültiger Domainnamen sein, falls mehrere Einträge mit derselben IP-Adresse gewünscht werden.&lt;br /&gt;
|-&lt;br /&gt;
| myip || &amp;lt;tt&amp;gt;myip=87.65.43.21&amp;lt;/tt&amp;gt;||&lt;br /&gt;
Kann entfallen; kann vom Server ignoriert werden. Maßgeblich ist dann die IP-Adresse des Absenders, wie sie vom Web-Server mitgeteilt wird.&lt;br /&gt;
|-&lt;br /&gt;
| mx || &amp;lt;tt&amp;gt;mx=87.65.43.21&amp;lt;/tt&amp;gt;&amp;lt;br /&amp;gt;&amp;lt;tt&amp;gt;mx=NOCHG&amp;lt;/tt&amp;gt;&amp;lt;br /&amp;gt; ||&lt;br /&gt;
Neben dem A-Eintrag möchte der Client auch einen MX-Eintrag. Der Wert &amp;lt;tt&amp;gt;NOCHG&amp;lt;/tt&amp;gt; (für &amp;amp;bdquo;no change&amp;amp;ldquo;) bedeutet, der bestehende MX-Eintrag (oder seine Abwesenheit) soll nicht geändert werden. &lt;br /&gt;
|-&lt;br /&gt;
| backmx || &amp;lt;tt&amp;gt;backmx=YES&amp;lt;/tt&amp;gt;&amp;lt;br /&amp;gt;&amp;lt;tt&amp;gt;backmx=NOCHG&amp;lt;/tt&amp;gt;&amp;lt;br /&amp;gt;&amp;lt;tt&amp;gt;backmx=NO&amp;lt;/tt&amp;gt;   ||&lt;br /&gt;
Falls &amp;lt;tt&amp;gt;YES&amp;lt;/tt&amp;gt;, wird ein zweiter MX-Eintrag erzeugt, der &amp;lt;tt&amp;gt;einwahl.example.com&amp;lt;/tt&amp;gt; als Mail-Server für &amp;lt;tt&amp;gt;einwahl.example.com&amp;lt;/tt&amp;gt; nennt. Dieser Eintrag hat eine niedrigere Präferenzzahl (also eine höhere Priorität) als der mit &amp;lt;tt&amp;gt;mx&amp;lt;/tt&amp;gt; angeforderten Eintrag.&lt;br /&gt;
|-&lt;br /&gt;
| wildcard || &amp;lt;tt&amp;gt;wildcard=ON&amp;lt;/tt&amp;gt;&amp;lt;br /&amp;gt;&amp;lt;tt&amp;gt;wildcard=NOCHG&amp;lt;/tt&amp;gt;&amp;lt;br /&amp;gt;&amp;lt;tt&amp;gt;wildcard=OFF&amp;lt;/tt&amp;gt; ||&lt;br /&gt;
Neben dem A-Eintrag für den Domainnamen &amp;lt;tt&amp;gt;einwahl.example.com&amp;lt;/tt&amp;gt; wünscht der Client auch einen Eintrag für beliebige Subdomains, also &amp;lt;tt&amp;gt;*.einwahl.example.com&amp;lt;/tt&amp;gt;, mit der gleichen IP-Adresse.&lt;br /&gt;
|-&lt;br /&gt;
| offline ||&amp;lt;tt&amp;gt;offline=YES&amp;lt;/tt&amp;gt;&amp;lt;br /&amp;gt;&amp;lt;tt&amp;gt;offline=NOCHG&amp;lt;/tt&amp;gt;||&lt;br /&gt;
Falls &amp;lt;tt&amp;gt;YES&amp;lt;/tt&amp;gt;, wird ein DNS-Eintrag für &amp;lt;tt&amp;gt;einwahl.example.com&amp;lt;/tt&amp;gt; aus der Zonefile getilgt. Gegebenenfalls wird der Hostname dann auf Grund eines parallelen Wildcard-Eintrags für &amp;lt;tt&amp;gt;*.example.com&amp;lt;/tt&amp;gt; einer anderen IP-Adresse zugeordnet werden.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;!-- IPv6? --&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Alle Parameter bis auf hostname können entfallen. Bei nichtdokumentierten Argumenten ist das Verhalten undefiniert&amp;amp;trade;.&lt;br /&gt;
&lt;br /&gt;
====Antwort====&lt;br /&gt;
&lt;br /&gt;
Die Antwort auf eine erfolgreiche HTTP-Anfrage besteht im häufigsten Fall aus einigen Header-Zeilen, gefolgt vom Inhalt der gewünschten Text- oder andere Datei. Ein Status-Code in der ersten Header-Zeile gibt an, ob die Anfrage bedient werden kann oder kreist andernfalls den Grund für die Enttäuschung ein.&lt;br /&gt;
&lt;br /&gt;
Die vorliegende Beispielimplementierung von DDNS schickt einen der üblichen HTTP-Status-Codes &amp;quot;200 OK&amp;quot; oder &amp;quot;500 Internal Server Error&amp;quot;, gefolgt von einer kurzen Textnachricht nach dem HTTP-Header. Bei diesem Programm  ist &amp;amp;ndash; laut Gebrauchshinweise von DynDNS.org &amp;amp;ndash; &#039;&#039;nicht&#039;&#039; der Status-Code im Header, sondern der Inhalt der Nachricht  die definierte, maßgebliche Ergebnismeldung des Programms.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|- class=&amp;quot;hintergrundfarbe5&amp;quot;&lt;br /&gt;
! Meldung !! Bedeutung !! Bemerkungen&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;good&amp;amp;nbsp;&amp;amp;lt;IP&amp;amp;nbsp;number&amp;amp;gt;&amp;lt;/tt&amp;gt; ||&lt;br /&gt;
Der gewünschte DNS-Eintrag wurde erfolgreich in einer Zonefile eingetragen. &lt;br /&gt;
|| Es kann natürlich noch einige Minuten dauern, bis die Zonefile vom Hostsharing-Roboter abgelesen wird und der Inhalt in die BIND-Konfiguration übernommen.&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;good&amp;amp;nbsp;0.0.0.0&amp;lt;/tt&amp;gt; ||&lt;br /&gt;
Das Argument &amp;lt;tt&amp;gt;offline=YES&amp;lt;/tt&amp;gt; wurde empfangen und verarbeitet.&lt;br /&gt;
|| Der Domainname hat also keinen dynamischen DNS-Eintrag mehr.&lt;br /&gt;
|-&lt;br /&gt;
&amp;lt;!-- We don&#039;t do this!&lt;br /&gt;
| &amp;lt;tt&amp;gt;good&amp;amp;nbsp;127.0.0.1&amp;lt;/tt&amp;gt; ||&lt;br /&gt;
Die Anfrage entsprach nicht den Erfordernissen des Servers.&lt;br /&gt;
|| Trotz des Worts &amp;lt;tt&amp;gt;good&amp;lt;/tt&amp;gt; war die Anfrage nicht erfolgreich, falls in der Rückmeldung die IP-Adresse mit &amp;lt;tt&amp;gt;127.0.0.1&amp;lt;/tt&amp;gt; angegeben wird. Dieser verwirrende Fehlercode ist aus unerklärlichen Gründen in der Spezifikation von DynDNS.org so definiert.&lt;br /&gt;
|-&lt;br /&gt;
--&amp;gt;&lt;br /&gt;
| &amp;lt;tt&amp;gt;nochg&amp;amp;nbsp;&amp;amp;lt;IP&amp;amp;nbsp;number&amp;amp;gt;&amp;lt;/tt&amp;gt; ||&lt;br /&gt;
Der gewünschte DNS-Eintrag war bereits vorhanden. &lt;br /&gt;
|| Der Server selbst macht keine DNS-Abfrage, um das zu vermitteln: die &amp;amp;bdquo;no change&amp;amp;ldquo;-Antwort besagt nur, daß eine Anfrage für diesen Eintrag bereits mit Erfolg quittiert wurde.&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;notfqdn&amp;lt;/tt&amp;gt; ||&lt;br /&gt;
Fehlschlag: der gewünschte Domainname ist nicht gültig, oder es wurde keiner angegeben.&lt;br /&gt;
|| ...&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;nohost&amp;lt;/tt&amp;gt; ||&lt;br /&gt;
Fehlschlag: der gewünschte Domainname ist gehört nicht zu denen, die für diesen Benutzer des DDNS-Dienstes konfiguriert sind.&lt;br /&gt;
|| Siehe den Abschnitt [[#Administration|Administration]] weiter unten.&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;badauth&amp;lt;/tt&amp;gt; ||&lt;br /&gt;
Fehlschlag: Die Kombination von Benutzernamen und Paßwort entsprach keinem DDNS-Account, oder das Account ist momentan gesperrt.&lt;br /&gt;
|| Ein gesperrtes Account kann nur der Domain-Admin mittels des Administrationswerkzeugs wieder freigeben: siehe den Abschnit [[#Administration|Administration]] weiter unten.&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;abuse&amp;lt;/tt&amp;gt; ||&lt;br /&gt;
Fehlschlag: der gewünschte Domainname ist wegen vorangeganger Fehlschläge oder überflüssiger Aufrufe gesperrt.&lt;br /&gt;
|| Siehe den Abschnitt [[#Sukzessive_Kommunikationsabläufe|Sukzessive Kommunikationsabläufe]] unten.&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;911&amp;lt;/tt&amp;gt; ||&lt;br /&gt;
Fehlschlag: Das Server-Programm hat einen internen Fehler festgestellt.&lt;br /&gt;
|| Das Problem liegt nicht in der Anfrage an sich.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Man kann sich durchaus eine sinnreichere Kommunikation zwischen Client und Server vorstellen, doch das hier beschriebene Protokoll ist eben von DynDNS.org verwendet worden und wird in gängigen Routern implementiert, also wird es in der vorliegenden DDNS-Implementierung nachgebildet.&lt;br /&gt;
&lt;br /&gt;
=== Sukzessive Kommunikationsabläufe ===&lt;br /&gt;
Der Server muß sich zwischen einzelnen Aufrufen einiges merken, um Ressourcen zu schonen und um zu verhindern, daß einmal vergebene DDNS-Einträge von neuen Anfragen, die dieselbe übergeordnete Domain betreffen, durch Überschreiben  verlorengehen.&lt;br /&gt;
&lt;br /&gt;
==== Mißbrauch und Benutzersperrung ====&lt;br /&gt;
Zur Schonung von Ressourcen muß sich die Implementierung weigern, sich mit zuvielen fehlerhaften oder auch nur überflüssigen Anfragen zu beschäftigen. Dazu führt der Server eine Strichliste über solche Anfragen jedes Clients und sperrt nach einer bestimmten Anzahl solcher Anfragen den Benutzernamen oder einzelne Domainnamen gegen die weitere Nutzung des Dienstes.&lt;br /&gt;
&lt;br /&gt;
Mißbrauchspunkte gegen einen einzelnen Domainnamen gibt es für:&lt;br /&gt;
* eine Anfrage, die keinen neuen DNS-Eintrag (und keine Änderung oder Löschung eines Eintrags) erfordert, sondern bestehende Merkmale nur wiederholt&lt;br /&gt;
&lt;br /&gt;
Mißbrauchspunkte gegen einen Benutzernamen gibt es für:&lt;br /&gt;
* die Angabe eines Domainnamens, der in der Dienstkonfiguration dem anfragenden Benutzernamen nicht zugeordnet ist&lt;br /&gt;
* die Angabe eines Domainnamen in einer Domain, die nicht demselben Hostsharing-Domain-Admin gehört, der den DDNS-Dienst anbietet&lt;br /&gt;
* die Angabe eines Domainnamens, der in der Dienstkonfiguration bereits wegen mißbräuchlicher Anfragen gesperrt ist (siehe oben)&lt;br /&gt;
&lt;br /&gt;
Um eine Sperrung aufzuheben, wird in der Regel eine Handlung durch den Administrator erforderlich sein.&lt;br /&gt;
&lt;br /&gt;
==== Mehrere dynamische Subdomains in derselben Domain ====&lt;br /&gt;
Sobald zwei verschiedene DDNS-Einträge in derselben Domain verlangt werden &amp;amp;ndash; beispielsweise home.example.com und office.example.com &amp;amp;ndash; wird es notwendig, bei jeder neuen Zonefile für example.com eventuell frühere Einträge zu konservieren. Der Rechner zu Hause weiß beim Bestellen seines DDNS-Eintrags nichts vom Rechner im Büro und umgekehrt. Der Server muß in irgendeiner Form über bereits vergebene Einträge Buch führen und bei einer neuen Anfrage, die example.com betrifft, alle bereits aktiven DDNS-Einträge für example.com mit in die neue Zonefile aufnehmen &amp;amp;ndash auch wenn sie auf Anfragen verschiedener Benutzer zurückgehen.&lt;br /&gt;
&lt;br /&gt;
==== Datenbank ====&lt;br /&gt;
In der Beispielimplementierung werden diese Informationen in einer SQLite-Datenbank gespeichert.&lt;br /&gt;
&lt;br /&gt;
== Sicherheit ==&lt;br /&gt;
=== Rechte ===&lt;br /&gt;
Die &#039;&#039;&#039;Benutzerrechte&#039;&#039;&#039; werden durch das Hostsharing-System kontrolliert. Sowohl das CGI-Programm als auch das [[#Administration|Administrationswerkzeug]] werden mit den Rechten des Domain-Admins (xyz00-benutzername in unserem Beispiel) ausgeführt, also kann dieses Programm nur die Domains bearbeiten, die von xyz00-benutzername verwaltet werden.&lt;br /&gt;
&lt;br /&gt;
=== Authentifizierung ===&lt;br /&gt;
In der Beispielimplementierung (wie auch seinerzeit bei DynDNS.org) wird das CGI-Programm durch einen .htaccess-Eintrag geschützt, der HTTP-Basic-Authentication vorschreibt. Also wird das Programm eigentlich mit einem URL der form&lt;br /&gt;
&lt;br /&gt;
  &amp;lt;nowiki&amp;gt;https://ddnsaccount:passwort@ddns.example.com/cgi-bin/ddns?hostname=...&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
aufgerufen.&lt;br /&gt;
&lt;br /&gt;
=== Verschlüsselung ===&lt;br /&gt;
Das CGI-Programm sollte nur in example.com/cgi-ssl/ installiert werden, nicht in example.com/cgi/. Damit ist die Kommunikation zwischen Client und Server durch SSL verschlüsselt.&lt;br /&gt;
&lt;br /&gt;
== Administration ==&lt;br /&gt;
&lt;br /&gt;
Der Verwalter des DDNS-Programms trägt berechtigte Benutzer und die ihnen zugeteilten Domainnamen in die Datenbank des Programms ein mit Hilfe eines kleinen Hilfsprogramms. Das ist im vorliegenden Fall ein menügesteuertes Programm für die Befehlszeile, daß die naheliegenden Funktionen anbietet: Account hinzufügen, löschen, sperren, entsperren, Paßwort setzen, ändern; Domainnamen hinzufügen, ändern, entsperren, löschen; Accounts und Domainnamen mit aktuellem Status auflisten. Die Funktionen sind auch über Befehlszeilenargumente verfügbar, also skriptfähig.&lt;br /&gt;
&lt;br /&gt;
Eine Übersicht der Funktionen des Administrationswerkzeugs gibt dieses selbst aus:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
xyz00-benutzername@h02:~$ bin/ddnsadmin -h&lt;br /&gt;
ddnsadmin.pl: Verwaltungswerkzeug für ddns&lt;br /&gt;
&lt;br /&gt;
Verwendung:&lt;br /&gt;
    ddnsadmin -A{[ahlusf]} [&amp;lt;Account&amp;gt;] [-f &amp;lt;DB-Datei&amp;gt;]&lt;br /&gt;
    ddnsadmin -D{[ahlsf]} [&amp;lt;Domain&amp;gt;] -A &amp;lt;Account&amp;gt; [-f &amp;lt;DB-Datei&amp;gt;]&lt;br /&gt;
    ddnsadmin -E &amp;lt;Einstellung&amp;gt; &amp;lt;Wert&amp;gt; [-f &amp;lt;DB-Datei&amp;gt;]&lt;br /&gt;
    ddnsadmin [-f &amp;lt;DB-Datei&amp;gt;] [-n]&lt;br /&gt;
&lt;br /&gt;
Wenn keine Option oder nur -f &amp;lt;DB-Datei&amp;gt; angegeben wird, bietet&lt;br /&gt;
ddnsadmin.pl eine interaktive Menüoberfläche.&lt;br /&gt;
&lt;br /&gt;
Optionen:&lt;br /&gt;
    -f &amp;lt;DB-Datei&amp;gt;                    Angegebene Datenbankdatei verwenden&lt;br /&gt;
    -n                               Neue, leere Datenbank erzeugen&lt;br /&gt;
    -Aa  [&amp;lt;Account&amp;gt;]                 Account(s) auflisten&lt;br /&gt;
    -Ah &amp;lt;Account&amp;gt; &amp;lt;Paßwort&amp;gt;          Account hinzufügen&lt;br /&gt;
    -A{lsf} &amp;lt;Account&amp;gt;                Account löschen, sperren, freigeben&lt;br /&gt;
    -Au &amp;lt;Account&amp;gt; &amp;lt;Name&amp;gt;             Account umbenennen&lt;br /&gt;
    -A  &amp;lt;Account&amp;gt; -Da [&amp;lt;Domain&amp;gt;]     Domain(s) auflisten&lt;br /&gt;
    -A  &amp;lt;Account&amp;gt; -D{hlsf} &amp;lt;Domain&amp;gt;  Domain hinzufügen,&lt;br /&gt;
                                     löschen, sperren, freigeben&lt;br /&gt;
    -E &amp;lt;Einstellung&amp;gt; &amp;lt;Wert&amp;gt;          Einstellung ändern&lt;br /&gt;
    -h                               Diese Übersicht ausgeben&lt;br /&gt;
&lt;br /&gt;
Einstellungen: &lt;br /&gt;
    maxacctabuse    Anzahl der mißbräuchlichen Aufrufe,&lt;br /&gt;
                    bevor ein Account gesperrt wird&lt;br /&gt;
    maxhostabuse    Anzahl der mißbräuchlichen Aufrufe,&lt;br /&gt;
                    bevor ein Domainname gesperrt wird&lt;br /&gt;
    safeinterval    Mindestabstand zwischen redundanten Aufrufen&lt;br /&gt;
                    (in Sekunden)&lt;br /&gt;
    cgihost         Server, der das DDNS-Skript bereithält&lt;br /&gt;
&lt;br /&gt;
xyz00-benutzername@h02:~$ &lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Eine Auflistung des momentanen Inhalts der DDNS-Datenbank durch das Administrationswerkzeug könnte beispielsweise so aussehen:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  xyz00-benutzername@h02:~$ bin/ddnsadmin.pl -Aa&lt;br /&gt;
  1.  papst	Mißbrauch: 0; gesperrt: nein&lt;br /&gt;
  	avignon.example.com&lt;br /&gt;
  		zuletzt aktiv am Sun Apr 26 22:24:49 2020&lt;br /&gt;
  		mit IP-Nr. 87.65.43.21; MX: 0;  Backup-MX: nein;&lt;br /&gt;
  		Subdomains: nein; Mißbrauch: 0;  gesperrt: nein&lt;br /&gt;
  	vatican.beispiel.de&lt;br /&gt;
  		zuletzt aktiv am Sun Apr 26 22:24:49 2020&lt;br /&gt;
  		mit IP-Nr. 87.65.43.21; MX: 0;  Backup-MX: nein;&lt;br /&gt;
  		Subdomains: nein; Mißbrauch: 0;  gesperrt: nein&lt;br /&gt;
  2.  kaiser	Mißbrauch: 4; gesperrt: ja&lt;br /&gt;
  	augsburg.beispiel.de&lt;br /&gt;
  		zuletzt aktiv am Fri Apr 24 16:13:49 2020&lt;br /&gt;
  		mit IP-Nr. 64.82.31.75; MX: 0;  Backup-MX: nein;&lt;br /&gt;
  		Subdomains: nein; Mißbrauch: 0;  gesperrt: ja&lt;br /&gt;
  3.  luther	Mißbrauch: 1; gesperrt: nein&lt;br /&gt;
  	wittenberg.example.com&lt;br /&gt;
  		zuletzt aktiv am Mon Apr 27 10:12:49 2020&lt;br /&gt;
  		mit IP-Nr. 78.56.34.12; MX: 0;  Backup-MX: nein;&lt;br /&gt;
  		Subdomains: nein; Mißbrauch: 1;  gesperrt: nein&lt;br /&gt;
  xyz00-benutzername@h02:~$&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Das DDNS-Account &amp;amp;bdquo;kaiser&amp;amp;ldquo; in dieser Auflistung ist wohl auf Grund fehlerhafter Anfragen automatisch gesperrt worden. Der Inhaber wird sich wohl bald melden, um nach Korrektur seiner Client-Konfiguration die Aufhebung der Sperre zu wünschen.&lt;br /&gt;
&lt;br /&gt;
=== Log ===&lt;br /&gt;
Alle Anfragen werden in einer täglich wechselnden Log-Datei protokolliert, entweder schlicht oder ausführlich, je nachdem, ob eine Variable &amp;lt;tt&amp;gt;verbose&amp;lt;/tt&amp;gt; wahr ist.&lt;br /&gt;
Ein ausführlicher Log-Eintrag sieht so aus:&lt;br /&gt;
&lt;br /&gt;
  Sun Apr 26 20:21:45 2020  ddns aufgerufen von papst&lt;br /&gt;
  			unter 84.185.97.8&lt;br /&gt;
  	URL: &amp;lt;nowiki&amp;gt;https://ddns.example.com/cgi-bin/ddns.cgi?hostname=&lt;br /&gt;
  			avignon.example.com,vatican.beispiel.de&amp;amp;&lt;br /&gt;
  			myip=84.185.97.8&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
  	Verwende IP 84.185.97.8 (= 1421435144)&lt;br /&gt;
  	DB-Version: 1&lt;br /&gt;
  	Skript und DB exklusiv geöffnet&lt;br /&gt;
  	avignon.example.com: IP: 84.185.97.8; MX: 0; Backup-MX: nein;&lt;br /&gt;
  			Wildcard: nein; Mißbrauch: 0; gesperrt: nein &lt;br /&gt;
  	vatican.beispiel.de: IP: 84.185.97.8; MX: 0; Backup-MX: nein;&lt;br /&gt;
  			Wildcard: nein; Mißbrauch: 0; gesperrt: nein &lt;br /&gt;
  	Betroffene Zonen: example.com, beispiel.de&lt;br /&gt;
  	Temporärdatei example.com_hxNa.new geschrieben&lt;br /&gt;
  	Zonendatei /home/pacs/xyz00/users/benutzername/doms/example.com/&lt;br /&gt;
  			etc/pri.example.com eingestellt&lt;br /&gt;
  	Temporärdatei beispiel.de_6HcO.new geschrieben&lt;br /&gt;
  	Zonendatei /home/pacs/xyz00/users/benutzername/doms/beispiel.de/&lt;br /&gt;
  			etc/pri.beispiel.de eingestellt&lt;br /&gt;
  	Abgeschlossen: 	Fertig&lt;br /&gt;
&lt;br /&gt;
Wenn &amp;lt;tt&amp;gt;verbose&amp;lt;/tt&amp;gt; auf falsch gesetzt ist, sind die Log-Einträge einzeilig.&lt;/div&gt;</summary>
		<author><name>Apc00-tony</name></author>
	</entry>
	<entry>
		<id>https://wiki.hostsharing.net/index.php?title=Benutzer:Apc00-tony/Dynamisches_DNS&amp;diff=6226</id>
		<title>Benutzer:Apc00-tony/Dynamisches DNS</title>
		<link rel="alternate" type="text/html" href="https://wiki.hostsharing.net/index.php?title=Benutzer:Apc00-tony/Dynamisches_DNS&amp;diff=6226"/>
		<updated>2023-09-11T14:26:08Z</updated>

		<summary type="html">&lt;p&gt;Apc00-tony: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Update 2023: Ich habe die Verwaltung über Befehlszeile durch eine PHP-Web-Oberfläche ersetzt; Details irgendwo ...  Meine Hostsharing-DDNS-Lösung läuft übrigens schon lange einwandfrei; ich benutze sie dazu, ein VPN zwischen meinen Fritz!Box-LANS zu Hause und im Büro zu realisieren sowie um auf ein Backup- und Music-Server (ein Raspberry Pi) zu Hause von unterwegs zuzugreifen.&lt;br /&gt;
&lt;br /&gt;
((Provisorischer Vorspann: Auf Grund einer Mailing-Listen-Diskussion habe ich angefangen, Dynamisches DNS über einen CGI-Skript bei Hostsharing zu realisieren. Meine Lösung habe ich dann vorgestellt; sie wurde für nicht ausreichend selbsterklärend befunden und fand wenig Akzeptanz. Hier also der Versuch, die Sache zu dokumentieren.))&lt;br /&gt;
&lt;br /&gt;
Mit der regelmäßigen Aufnahme von benutzerspezifischen Zonefiles in seiner DNS-Konfiguration bietet  Hostsharing alles, was man braucht, um &amp;amp;bdquo;dynamisches DNS&amp;amp;ldquo; in Eigenregie zu realisieren.&lt;br /&gt;
&lt;br /&gt;
Das heißt, wenn ich mindestens eine Domain bei Hostsharing verwalte, und mindestens eine Einwahlverbindung (oder DSL-Verbindung) ins Internet mit wechselnder IP-Adresse über irgendeinen ISP für meinen Arbeitsplatzrechner zu Hause betreibe, dann kann ich dem Arbeitsplatzrechner über die DNS-Server von Hostsharing einen vollqualifizieren Domainnamen zuweisen, der der jeweiligen IP-Adresse meiner Einwahlleitung zugeordnet ist.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
(ASCII-Art-Diagramm der beschriebenen Konstellation)&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Im Folgenden wird eine real existierende Implementierung von Dynamischem DNS (&amp;amp;bdquo;DDNS&amp;amp;ldquo;) beschrieben. Die verschiedenen Elemente könnten durchaus anders realisiert werden; die beschriebene Implementierung könnte durchaus verbessert werden. Sie dient hier der Illustration.&lt;br /&gt;
&lt;br /&gt;
In der folgenden Beschreibung werden diese Beispielwerte benutzt:&lt;br /&gt;
* Ein Hostsharing-Mitglied hat ein Account als Paket-Admin mit Kennung xyz00.&lt;br /&gt;
* Im Paket xyz00 gibt es einen Domain-Admin namens xyz00-benutzername.&lt;br /&gt;
* Dieser Domain-Admin verwaltet bei Hostsharing die Domains example.com und beispiel.de.&lt;br /&gt;
* Ein Benutzer hat zu Hause (oder im Büro) einen Arbeitsplatzrechner hinter der marktüblichen DSL-Leitung, die von seinem ISP bereitgestellt wird.&lt;br /&gt;
* Dieser Arbeitsplatzrechner (oder der Router, der seine Internetverbindung steuert) bekommt vom ISP immer wechselnde IP-Adressen zugewiesen.&lt;br /&gt;
* Dennoch möchte der Benutzer seinen Arbeitsplatzrechner aus dem Internet unter dem Hostnamen einwahl.example.com ansprechen können.&lt;br /&gt;
&lt;br /&gt;
Dazu kann ein System wie Hostsharing, das authoritative DNS-Informationen für viele Domains bereitstellt, auch veränderliche DNS-Information über dynamisch verbundene Rechner verwalten &amp;amp;ndash; sofern das ressourcenschonend gemacht werden kann ohne andere Funktionen zu stören.&lt;br /&gt;
&lt;br /&gt;
== Aufgaben des Servers ==&lt;br /&gt;
&lt;br /&gt;
Um einem Rechner mit wechselnder IP-Adresse einen DDNS-Eintrag zu bieten, muß der Hostsharing-Server folgendes leisten (in ungefährer Reihenfolge der Ereignisse):&lt;br /&gt;
&lt;br /&gt;
# Eine Anfrage entgegennehmen, beispielsweise über HTTPS, von einem entfernten Rechner, der einen DNS-Eintrag für seine momentane IP-Adresse wünscht. &lt;br /&gt;
# Prüfen, ob die Anfrage einen berechtigten DDNS-Dienst-Usernamen mit zugehörigem Paßwort enthält.&lt;br /&gt;
# Prüfen, ob die Anfrage einen gültigen Domainnamen betrifft, den der Server bieten darf.&lt;br /&gt;
# Prüfen, ob die Domain example.com demselben Benutzer gehört, unter dessen Namen der Dynamisches-DNS-Server läuft.&lt;br /&gt;
# Eine gültige [[Zonefile]] mit &amp;amp;ndash; neben dem bisherigen Inhalt &amp;amp;ndash; einem A-Eintrag für einwahl.example.com in /home/pacs/xyz00/users/benutzername/doms/example.com/pri.example.com schreiben.&lt;br /&gt;
# Dem Client eine Bestätigung oder ggf. eine Fehlermeldung als Antwort senden.&lt;br /&gt;
# In irgendeiner Datenbank den momentan eingestellter Status all seiner DDNS-Einträge speichern.&lt;br /&gt;
# In einer Logdatei protokollieren, daß obiges getan wurde, oder ggf. welche Fehler traten auf.&lt;br /&gt;
&lt;br /&gt;
== Aufgaben des Clients ==&lt;br /&gt;
Bevor ich anfange, meinen Arbeitsplatzrechner so zu konfigurieren, daß er bei welchem Server auch immer einen DDNS-Eintrag anfordert, muß ich mich als verantwortlicher Benutzer dieses Rechners und der dazugehörigen Internetverbindung &amp;amp;ndash; das heißt, als Mensch &amp;amp;ndash; mit dem Betreiber des dynamisches-DNS-Servers vereinbaren, daß ich das darf und welchen Eintrag ich bekommen kann. Im Folgenden wird vorausgesetzt, daß solche Vereinbarungen getroffen und die Parameter geklärt wurden.&lt;br /&gt;
&lt;br /&gt;
Der DDNS-Client muß aus Server-Sicht nur wenig leisten:&lt;br /&gt;
&lt;br /&gt;
# Eine Anfrage senden, beispielsweise über HTTPS, an einen entfernten Rechner, der einen Eintrag ins DNS für die momentane IP-Adresse des Clients vornehmen kann.&amp;lt;br /&amp;gt;Diese Anfrage muß einem festgelegten Format entsprechen und muß gültige Werte für die Authorisation des Clients, den gewünschten Domainnamen, und eventuell andere Parameter enthalten.&lt;br /&gt;
# Eine Antwort des Servers entgegennehmen und als Erfolgs- oder Fehlermeldung auswerten.&lt;br /&gt;
# Von überflüssigen Anfragen absehen: das heißt bei Erfolg, nicht wiederholt den gleichen Eintrag erneut wünschen; bei Fehlern, nicht die gleiche fehlerhafte Anfrage erneut schicken.&lt;br /&gt;
&lt;br /&gt;
== Kommunikation zwischen Client und Server ==&lt;br /&gt;
&lt;br /&gt;
Ein einziges Nachrichtenpaar von Anfrage und Antwort genügt, um einen DDNS-Eintrag einzurichten: Der Client teilt die IP-Adresse und den Domainnamen mit, die in einem DNS-Eintrag verbunden werden sollen; der Server bestätigt den Auftrag.&lt;br /&gt;
&lt;br /&gt;
In der Beispielimplementierung erfolgt die Kommunikation über HTTP, und die Anfrage des Clients könnte so aussehen:&lt;br /&gt;
&lt;br /&gt;
  GET /cgi-bin/ddns?hostname=einwahl.example.com&amp;amp;myip=87.65.43.21 HTTP/1.1&lt;br /&gt;
  Host: ddns.beispiel.de&lt;br /&gt;
  User-Agent: Fritz!Box DDNS/1.0.1&lt;br /&gt;
  Authorization: Basic QWxhZGRpbjpvcGVuIHNlc2FtZQ==&lt;br /&gt;
&lt;br /&gt;
Bei Erhalt dieser Anfrage ruft Apache das CGI-Programm .../doms/ddns.beispiel.de/cgi-ssl/ddns auf. Das Fragezeichen trennt den Programmnamen von einem &amp;quot;Query-String&amp;quot;, in dem zwei Metavariablen definiert und übergeben werden. Die erste Metavariable, hostname, hat den Wert &amp;quot;einwahl.example.com&amp;quot;; die zweite, myip, hat den Wert &amp;quot;87.65.43.21&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
Das Server-Programm, hier &#039;&#039;ddns&#039;&#039;, prüft diese Informationen auf Form und Berechtigung, und schreibt gegebenenfalls einen entsprechenden Eintrag in einer Zonefile. Es schreibt auch verschiedene Informationen in die Standardausgabe. Wenn es die Standardausgabe geschlossen wird &amp;amp;ndash; also spätestens bei Programmende &amp;amp;ndash; schickt Apache diese Informationen als Antwort an den anfragenden Rechner zurück.&lt;br /&gt;
&lt;br /&gt;
Im Falle unserer Beispielimplementierung sieht die Antwort bei Erfolg so aus: &lt;br /&gt;
&lt;br /&gt;
  HTTP/1.1 200 OK&lt;br /&gt;
  Date: Wed, 22 Apr 2020 08:35:15 GMT&lt;br /&gt;
  Server: Apache&lt;br /&gt;
  Content-Length: 17&lt;br /&gt;
  Content-Type: text/plain; charset=ISO-8859-1&lt;br /&gt;
 &lt;br /&gt;
  good 87.65.43.21&lt;br /&gt;
&lt;br /&gt;
=== Das DDNS-Protokoll von DynDNS.org ===&lt;br /&gt;
&lt;br /&gt;
In den 90er Jahren, bevor das Internet so durchgehend vergeschäftlicht wurde, boten einige Organisationen kostenlose DDNS-Dienste an. Ein sehr beliebtes Angebot war das von DynDNS.org. Das DDNS-Protokoll von diesem Dienst wurde sogar in Einwahl-Routern einprogrammiert und der Dienst wurde von ISPs und Router-Herstellern als Leistungsmerkmal beworben.&lt;br /&gt;
&lt;br /&gt;
DynDNS.org gehört inzwischen Oracle und bietet keine kostenlose Dienste mehr. Dennoch wird das DDNS-Protokoll von DynDNS.org in der vorliegenden Beispielimplementierung übernommen in der Hoffnung, daß die Kompatibilität mit einigen gängigen Einwahl-Routern von Vorteil sein kann. Es gibt noch eine kurze Online-Dokumentation der [https://help.dyn.com/remote-access-api/perform-update/ Anfrage] und [https://help.dyn.com/remote-access-api/perform-update/ Antwortnachrichten].&lt;br /&gt;
&lt;br /&gt;
Das gesammte Protokoll sieht einen einzigen Nachrichtenaustausch aus Anfrage und Antwort vor. Die Anfrage kann mehrere Argumente enthalten; die Antwort kann verschiedene Code-Wörtern enthalten. Übrigens können in einer einzigen Anfrage mehrere DNS-Einträge gewünscht werden. In diesem Fall kann die Antwort mehrzeilig ausfallen.&lt;br /&gt;
&lt;br /&gt;
Das Verhalten von Server und Client bei künftigen Kommunikationsvorgängen wird unter Umständen von vorangegangenen Kommunikationsergebnissen beeinflußt: nach wiederholten fehlerhaften oder redundanten Anfragen kann der Server weitere Anfragen des Benutzers verweigern; nach wiederholten Fehlermeldungen sollte ein Client aufhören, immer dieselbe Anfrage zu schicken. Und für den Fall, daß mehrere Clients dynamische DNS-Einträge in derselben Domain example.com bestellen, muß der Server den Stand aller Client-Einträge intern speichern, damit er nicht mit einer neuen Zonefile einen früher erstellten Eintrag löscht. Zu diesen Fragen siehe den Abschnitt &#039;&#039;&#039;[[#Sukzessive_Kommunikationsabläufe]]&#039;&#039;&#039; nach der Beschreibung von Anfragen und Antworten unten.&lt;br /&gt;
&lt;br /&gt;
====Anfrage====&lt;br /&gt;
&lt;br /&gt;
Die Anfrage in Form eines URL übergibt dem DDNS-Programm in einem &#039;Query-String&#039; einige Metavariablen. Das heißt, in einem URL der Form&lt;br /&gt;
&lt;br /&gt;
  &amp;lt;nowiki&amp;gt;https://benutzername:passwort@ddns.beisiel.de/cgi-bin/ddns?hostname=einwahl.example.com&amp;amp;myip=87.65.43.21&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
signalisert das Fragezeichen, daß ein Query-String folgt. In einem solchen Query-String können in der Beispielimplementierung folgende Metavariablen definiert werden:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|- class=&amp;quot;hintergrundfarbe5&amp;quot;&lt;br /&gt;
! Variable !! Beispiel !! Bemerkungen&lt;br /&gt;
|-&lt;br /&gt;
| hostname || &amp;lt;tt&amp;gt;hostname=einwahl.example.com&amp;lt;/tt&amp;gt;&amp;lt;br /&amp;gt;&amp;lt;div style=&amp;quot;font-size:smaller;&amp;quot;&amp;gt;&amp;lt;tt&amp;gt;hostname=eins.example.com,zwei.example.com[,...]&amp;lt;/tt&amp;gt;&amp;lt;/div&amp;gt; ||&lt;br /&gt;
Muß ein vollständig qualifizierter Domain-Name (&amp;quot;FQDN&amp;quot;) sein; &amp;lt;tt&amp;gt;example.com&amp;lt;/tt&amp;gt; muß eine vom Besitzer des DDNS-Programms verwaltete Domain sein. Genaugenommen kann der Wert eine durch Kommata gegliederte Liste mehrerer gültiger Domainnamen sein, falls mehrere Einträge mit derselben IP-Adresse gewünscht werden.&lt;br /&gt;
|-&lt;br /&gt;
| myip || &amp;lt;tt&amp;gt;myip=87.65.43.21&amp;lt;/tt&amp;gt;||&lt;br /&gt;
Kann entfallen; kann vom Server ignoriert werden. Maßgeblich ist dann die IP-Adresse des Absenders, wie sie vom Web-Server mitgeteilt wird.&lt;br /&gt;
|-&lt;br /&gt;
| mx || &amp;lt;tt&amp;gt;mx=87.65.43.21&amp;lt;/tt&amp;gt;&amp;lt;br /&amp;gt;&amp;lt;tt&amp;gt;mx=NOCHG&amp;lt;/tt&amp;gt;&amp;lt;br /&amp;gt; ||&lt;br /&gt;
Neben dem A-Eintrag möchte der Client auch einen MX-Eintrag. Der Wert &amp;lt;tt&amp;gt;NOCHG&amp;lt;/tt&amp;gt; (für &amp;amp;bdquo;no change&amp;amp;ldquo;) bedeutet, der bestehende MX-Eintrag (oder seine Abwesenheit) soll nicht geändert werden. &lt;br /&gt;
|-&lt;br /&gt;
| backmx || &amp;lt;tt&amp;gt;backmx=YES&amp;lt;/tt&amp;gt;&amp;lt;br /&amp;gt;&amp;lt;tt&amp;gt;backmx=NOCHG&amp;lt;/tt&amp;gt;&amp;lt;br /&amp;gt;&amp;lt;tt&amp;gt;backmx=NO&amp;lt;/tt&amp;gt;   ||&lt;br /&gt;
Falls &amp;lt;tt&amp;gt;YES&amp;lt;/tt&amp;gt;, wird ein zweiter MX-Eintrag erzeugt, der &amp;lt;tt&amp;gt;einwahl.example.com&amp;lt;/tt&amp;gt; als Mail-Server für &amp;lt;tt&amp;gt;einwahl.example.com&amp;lt;/tt&amp;gt; nennt. Dieser Eintrag hat eine niedrigere Präferenzzahl (also eine höhere Priorität) als der mit &amp;lt;tt&amp;gt;mx&amp;lt;/tt&amp;gt; angeforderten Eintrag.&lt;br /&gt;
|-&lt;br /&gt;
| wildcard || &amp;lt;tt&amp;gt;wildcard=ON&amp;lt;/tt&amp;gt;&amp;lt;br /&amp;gt;&amp;lt;tt&amp;gt;wildcard=NOCHG&amp;lt;/tt&amp;gt;&amp;lt;br /&amp;gt;&amp;lt;tt&amp;gt;wildcard=OFF&amp;lt;/tt&amp;gt; ||&lt;br /&gt;
Neben dem A-Eintrag für den Domainnamen &amp;lt;tt&amp;gt;einwahl.example.com&amp;lt;/tt&amp;gt; wünscht der Client auch einen Eintrag für beliebige Subdomains, also &amp;lt;tt&amp;gt;*.einwahl.example.com&amp;lt;/tt&amp;gt;, mit der gleichen IP-Adresse.&lt;br /&gt;
|-&lt;br /&gt;
| offline ||&amp;lt;tt&amp;gt;offline=YES&amp;lt;/tt&amp;gt;&amp;lt;br /&amp;gt;&amp;lt;tt&amp;gt;offline=NOCHG&amp;lt;/tt&amp;gt;||&lt;br /&gt;
Falls &amp;lt;tt&amp;gt;YES&amp;lt;/tt&amp;gt;, wird ein DNS-Eintrag für &amp;lt;tt&amp;gt;einwahl.example.com&amp;lt;/tt&amp;gt; aus der Zonefile getilgt. Gegebenenfalls wird der Hostname dann auf Grund eines parallelen Wildcard-Eintrags für &amp;lt;tt&amp;gt;*.example.com&amp;lt;/tt&amp;gt; einer anderen IP-Adresse zugeordnet werden.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;!-- IPv6? --&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Alle Parameter bis auf hostname können entfallen. Bei nichtdokumentierten Argumenten ist das Verhalten undefiniert&amp;amp;trade;.&lt;br /&gt;
&lt;br /&gt;
====Antwort====&lt;br /&gt;
&lt;br /&gt;
Die Antwort auf eine erfolgreiche HTTP-Anfrage besteht im häufigsten Fall aus einigen Header-Zeilen, gefolgt vom Inhalt der gewünschten Text- oder andere Datei. Ein Status-Code in der ersten Header-Zeile gibt an, ob die Anfrage bedient werden kann oder kreist andernfalls den Grund für die Enttäuschung ein.&lt;br /&gt;
&lt;br /&gt;
Die vorliegende Beispielimplementierung von DDNS schickt einen der üblichen HTTP-Status-Codes &amp;quot;200 OK&amp;quot; oder &amp;quot;500 Internal Server Error&amp;quot;, gefolgt von einer kurzen Textnachricht nach dem HTTP-Header. Bei diesem Programm  ist &amp;amp;ndash; laut Gebrauchshinweise von DynDNS.org &amp;amp;ndash; &#039;&#039;nicht&#039;&#039; der Status-Code im Header, sondern der Inhalt der Nachricht  die definierte, maßgebliche Ergebnismeldung des Programms.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|- class=&amp;quot;hintergrundfarbe5&amp;quot;&lt;br /&gt;
! Meldung !! Bedeutung !! Bemerkungen&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;good&amp;amp;nbsp;&amp;amp;lt;IP&amp;amp;nbsp;number&amp;amp;gt;&amp;lt;/tt&amp;gt; ||&lt;br /&gt;
Der gewünschte DNS-Eintrag wurde erfolgreich in einer Zonefile eingetragen. &lt;br /&gt;
|| Es kann natürlich noch einige Minuten dauern, bis die Zonefile vom Hostsharing-Roboter abgelesen wird und der Inhalt in die BIND-Konfiguration übernommen.&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;good&amp;amp;nbsp;0.0.0.0&amp;lt;/tt&amp;gt; ||&lt;br /&gt;
Das Argument &amp;lt;tt&amp;gt;offline=YES&amp;lt;/tt&amp;gt; wurde empfangen und verarbeitet.&lt;br /&gt;
|| Der Domainname hat also keinen dynamischen DNS-Eintrag mehr.&lt;br /&gt;
|-&lt;br /&gt;
&amp;lt;!-- We don&#039;t do this!&lt;br /&gt;
| &amp;lt;tt&amp;gt;good&amp;amp;nbsp;127.0.0.1&amp;lt;/tt&amp;gt; ||&lt;br /&gt;
Die Anfrage entsprach nicht den Erfordernissen des Servers.&lt;br /&gt;
|| Trotz des Worts &amp;lt;tt&amp;gt;good&amp;lt;/tt&amp;gt; war die Anfrage nicht erfolgreich, falls in der Rückmeldung die IP-Adresse mit &amp;lt;tt&amp;gt;127.0.0.1&amp;lt;/tt&amp;gt; angegeben wird. Dieser verwirrende Fehlercode ist aus unerklärlichen Gründen in der Spezifikation von DynDNS.org so definiert.&lt;br /&gt;
|-&lt;br /&gt;
--&amp;gt;&lt;br /&gt;
| &amp;lt;tt&amp;gt;nochg&amp;amp;nbsp;&amp;amp;lt;IP&amp;amp;nbsp;number&amp;amp;gt;&amp;lt;/tt&amp;gt; ||&lt;br /&gt;
Der gewünschte DNS-Eintrag war bereits vorhanden. &lt;br /&gt;
|| Der Server selbst macht keine DNS-Abfrage, um das zu vermitteln: die &amp;amp;bdquo;no change&amp;amp;ldquo;-Antwort besagt nur, daß eine Anfrage für diesen Eintrag bereits mit Erfolg quittiert wurde.&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;notfqdn&amp;lt;/tt&amp;gt; ||&lt;br /&gt;
Fehlschlag: der gewünschte Domainname ist nicht gültig, oder es wurde keiner angegeben.&lt;br /&gt;
|| ...&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;nohost&amp;lt;/tt&amp;gt; ||&lt;br /&gt;
Fehlschlag: der gewünschte Domainname ist gehört nicht zu denen, die für diesen Benutzer des DDNS-Dienstes konfiguriert sind.&lt;br /&gt;
|| Siehe den Abschnitt [[#Administration|Administration]] weiter unten.&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;badauth&amp;lt;/tt&amp;gt; ||&lt;br /&gt;
Fehlschlag: Die Kombination von Benutzernamen und Paßwort entsprach keinem DDNS-Account, oder das Account ist momentan gesperrt.&lt;br /&gt;
|| Ein gesperrtes Account kann nur der Domain-Admin mittels des Administrationswerkzeugs wieder freigeben: siehe den Abschnit [[#Administration|Administration]] weiter unten.&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;abuse&amp;lt;/tt&amp;gt; ||&lt;br /&gt;
Fehlschlag: der gewünschte Domainname ist wegen vorangeganger Fehlschläge oder überflüssiger Aufrufe gesperrt.&lt;br /&gt;
|| Siehe den Abschnitt [[#Sukzessive_Kommunikationsabläufe|Sukzessive Kommunikationsabläufe]] unten.&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;911&amp;lt;/tt&amp;gt; ||&lt;br /&gt;
Fehlschlag: Das Server-Programm hat einen internen Fehler festgestellt.&lt;br /&gt;
|| Das Problem liegt nicht in der Anfrage an sich.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Man kann sich durchaus eine sinnreichere Kommunikation zwischen Client und Server vorstellen, doch das hier beschriebene Protokoll ist eben von DynDNS.org verwendet worden und wird in gängigen Routern implementiert, also wird es in der vorliegenden DDNS-Implementierung nachgebildet.&lt;br /&gt;
&lt;br /&gt;
=== Sukzessive Kommunikationsabläufe ===&lt;br /&gt;
Der Server muß sich zwischen einzelnen Aufrufen einiges merken, um Ressourcen zu schonen und um zu verhindern, daß einmal vergebene DDNS-Einträge von neuen Anfragen, die dieselbe übergeordnete Domain betreffen, durch Überschreiben  verlorengehen.&lt;br /&gt;
&lt;br /&gt;
==== Mißbrauch und Benutzersperrung ====&lt;br /&gt;
Zur Schonung von Ressourcen muß sich die Implementierung weigern, sich mit zuvielen fehlerhaften oder auch nur überflüssigen Anfragen zu beschäftigen. Dazu führt der Server eine Strichliste über solche Anfragen jedes Clients und sperrt nach einer bestimmten Anzahl solcher Anfragen den Benutzernamen oder einzelne Domainnamen gegen die weitere Nutzung des Dienstes.&lt;br /&gt;
&lt;br /&gt;
Mißbrauchspunkte gegen einen einzelnen Domainnamen gibt es für:&lt;br /&gt;
* eine Anfrage, die keinen neuen DNS-Eintrag (und keine Änderung oder Löschung eines Eintrags) erfordert, sondern bestehende Merkmale nur wiederholt&lt;br /&gt;
&lt;br /&gt;
Mißbrauchspunkte gegen einen Benutzernamen gibt es für:&lt;br /&gt;
* die Angabe eines Domainnamens, der in der Dienstkonfiguration dem anfragenden Benutzernamen nicht zugeordnet ist&lt;br /&gt;
* die Angabe eines Domainnamen in einer Domain, die nicht demselben Hostsharing-Domain-Admin gehört, der den DDNS-Dienst anbietet&lt;br /&gt;
* die Angabe eines Domainnamens, der in der Dienstkonfiguration bereits wegen mißbräuchlicher Anfragen gesperrt ist (siehe oben)&lt;br /&gt;
&lt;br /&gt;
Um eine Sperrung aufzuheben, wird in der Regel eine Handlung durch den Administrator erforderlich sein.&lt;br /&gt;
&lt;br /&gt;
==== Mehrere dynamische Subdomains in derselben Domain ====&lt;br /&gt;
Sobald zwei verschiedene DDNS-Einträge in derselben Domain verlangt werden &amp;amp;ndash; beispielsweise home.example.com und office.example.com &amp;amp;ndash; wird es notwendig, bei jeder neuen Zonefile für example.com eventuell frühere Einträge zu konservieren. Der Rechner zu Hause weiß beim Bestellen seines DDNS-Eintrags nichts vom Rechner im Büro und umgekehrt. Der Server muß in irgendeiner Form über bereits vergebene Einträge Buch führen und bei einer neuen Anfrage, die example.com betrifft, alle bereits aktiven DDNS-Einträge für example.com mit in die neue Zonefile aufnehmen &amp;amp;ndash auch wenn sie auf Anfragen verschiedener Benutzer zurückgehen.&lt;br /&gt;
&lt;br /&gt;
==== Datenbank ====&lt;br /&gt;
In der Beispielimplementierung werden diese Informationen in einer SQLite-Datenbank gespeichert.&lt;br /&gt;
&lt;br /&gt;
== Sicherheit ==&lt;br /&gt;
=== Rechte ===&lt;br /&gt;
Die &#039;&#039;&#039;Benutzerrechte&#039;&#039;&#039; werden durch das Hostsharing-System kontrolliert. Sowohl das CGI-Programm als auch das [[#Administration|Administrationswerkzeug]] werden mit den Rechten des Domain-Admins (xyz00-benutzername in unserem Beispiel) ausgeführt, also kann dieses Programm nur die Domains bearbeiten, die von xyz00-benutzername verwaltet werden.&lt;br /&gt;
&lt;br /&gt;
=== Authentifizierung ===&lt;br /&gt;
In der Beispielimplementierung (wie auch seinerzeit bei DynDNS.org) wird das CGI-Programm durch einen .htaccess-Eintrag geschützt, der HTTP-Basic-Authentication vorschreibt. Also wird das Programm eigentlich mit einem URL der form&lt;br /&gt;
&lt;br /&gt;
  &amp;lt;nowiki&amp;gt;https://ddnsaccount:passwort@ddns.example.com/cgi-bin/ddns?hostname=...&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
aufgerufen.&lt;br /&gt;
&lt;br /&gt;
=== Verschlüsselung ===&lt;br /&gt;
Das CGI-Programm sollte nur in example.com/cgi-ssl/ installiert werden, nicht in example.com/cgi/. Damit ist die Kommunikation zwischen Client und Server durch SSL verschlüsselt.&lt;br /&gt;
&lt;br /&gt;
== Administration ==&lt;br /&gt;
&lt;br /&gt;
Der Verwalter des DDNS-Programms trägt berechtigte Benutzer und die ihnen zugeteilten Domainnamen in die Datenbank des Programms ein mit Hilfe eines kleinen Hilfsprogramms. Das ist im vorliegenden Fall ein menügesteuertes Programm für die Befehlszeile, daß die naheliegenden Funktionen anbietet: Account hinzufügen, löschen, sperren, entsperren, Paßwort setzen, ändern; Domainnamen hinzufügen, ändern, entsperren, löschen; Accounts und Domainnamen mit aktuellem Status auflisten. Die Funktionen sind auch über Befehlszeilenargumente verfügbar, also skriptfähig.&lt;br /&gt;
&lt;br /&gt;
Eine Übersicht der Funktionen des Administrationswerkzeugs gibt dieses selbst aus:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
xyz00-benutzername@h02:~$ bin/ddnsadmin -h&lt;br /&gt;
ddnsadmin.pl: Verwaltungswerkzeug für ddns&lt;br /&gt;
&lt;br /&gt;
Verwendung:&lt;br /&gt;
    ddnsadmin -A{[ahlusf]} [&amp;lt;Account&amp;gt;] [-f &amp;lt;DB-Datei&amp;gt;]&lt;br /&gt;
    ddnsadmin -D{[ahlsf]} [&amp;lt;Domain&amp;gt;] -A &amp;lt;Account&amp;gt; [-f &amp;lt;DB-Datei&amp;gt;]&lt;br /&gt;
    ddnsadmin -E &amp;lt;Einstellung&amp;gt; &amp;lt;Wert&amp;gt; [-f &amp;lt;DB-Datei&amp;gt;]&lt;br /&gt;
    ddnsadmin [-f &amp;lt;DB-Datei&amp;gt;] [-n]&lt;br /&gt;
&lt;br /&gt;
Wenn keine Option oder nur -f &amp;lt;DB-Datei&amp;gt; angegeben wird, bietet&lt;br /&gt;
ddnsadmin.pl eine interaktive Menüoberfläche.&lt;br /&gt;
&lt;br /&gt;
Optionen:&lt;br /&gt;
    -f &amp;lt;DB-Datei&amp;gt;                    Angegebene Datenbankdatei verwenden&lt;br /&gt;
    -n                               Neue, leere Datenbank erzeugen&lt;br /&gt;
    -Aa  [&amp;lt;Account&amp;gt;]                 Account(s) auflisten&lt;br /&gt;
    -Ah &amp;lt;Account&amp;gt; &amp;lt;Paßwort&amp;gt;          Account hinzufügen&lt;br /&gt;
    -A{lsf} &amp;lt;Account&amp;gt;                Account löschen, sperren, freigeben&lt;br /&gt;
    -Au &amp;lt;Account&amp;gt; &amp;lt;Name&amp;gt;             Account umbenennen&lt;br /&gt;
    -A  &amp;lt;Account&amp;gt; -Da [&amp;lt;Domain&amp;gt;]     Domain(s) auflisten&lt;br /&gt;
    -A  &amp;lt;Account&amp;gt; -D{hlsf} &amp;lt;Domain&amp;gt;  Domain hinzufügen,&lt;br /&gt;
                                     löschen, sperren, freigeben&lt;br /&gt;
    -E &amp;lt;Einstellung&amp;gt; &amp;lt;Wert&amp;gt;          Einstellung ändern&lt;br /&gt;
    -h                               Diese Übersicht ausgeben&lt;br /&gt;
&lt;br /&gt;
Einstellungen: &lt;br /&gt;
    maxacctabuse    Anzahl der mißbräuchlichen Aufrufe,&lt;br /&gt;
                    bevor ein Account gesperrt wird&lt;br /&gt;
    maxhostabuse    Anzahl der mißbräuchlichen Aufrufe,&lt;br /&gt;
                    bevor ein Domainname gesperrt wird&lt;br /&gt;
    safeinterval    Mindestabstand zwischen redundanten Aufrufen&lt;br /&gt;
                    (in Sekunden)&lt;br /&gt;
    cgihost         Server, der das DDNS-Skript bereithält&lt;br /&gt;
&lt;br /&gt;
xyz00-benutzername@h02:~$ &lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Eine Auflistung des momentanen Inhalts der DDNS-Datenbank durch das Administrationswerkzeug könnte beispielsweise so aussehen:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  xyz00-benutzername@h02:~$ bin/ddnsadmin.pl -Aa&lt;br /&gt;
  1.  papst	Mißbrauch: 0; gesperrt: nein&lt;br /&gt;
  	avignon.example.com&lt;br /&gt;
  		zuletzt aktiv am Sun Apr 26 22:24:49 2020&lt;br /&gt;
  		mit IP-Nr. 87.65.43.21; MX: 0;  Backup-MX: nein;&lt;br /&gt;
  		Subdomains: nein; Mißbrauch: 0;  gesperrt: nein&lt;br /&gt;
  	vatican.beispiel.de&lt;br /&gt;
  		zuletzt aktiv am Sun Apr 26 22:24:49 2020&lt;br /&gt;
  		mit IP-Nr. 87.65.43.21; MX: 0;  Backup-MX: nein;&lt;br /&gt;
  		Subdomains: nein; Mißbrauch: 0;  gesperrt: nein&lt;br /&gt;
  2.  kaiser	Mißbrauch: 4; gesperrt: ja&lt;br /&gt;
  	augsburg.beispiel.de&lt;br /&gt;
  		zuletzt aktiv am Fri Apr 24 16:13:49 2020&lt;br /&gt;
  		mit IP-Nr. 64.82.31.75; MX: 0;  Backup-MX: nein;&lt;br /&gt;
  		Subdomains: nein; Mißbrauch: 0;  gesperrt: ja&lt;br /&gt;
  3.  luther	Mißbrauch: 1; gesperrt: nein&lt;br /&gt;
  	wittenberg.example.com&lt;br /&gt;
  		zuletzt aktiv am Mon Apr 27 10:12:49 2020&lt;br /&gt;
  		mit IP-Nr. 78.56.34.12; MX: 0;  Backup-MX: nein;&lt;br /&gt;
  		Subdomains: nein; Mißbrauch: 1;  gesperrt: nein&lt;br /&gt;
  xyz00-benutzername@h02:~$&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Das DDNS-Account &amp;amp;bdquo;kaiser&amp;amp;ldquo; in dieser Auflistung ist wohl auf Grund fehlerhafter Anfragen automatisch gesperrt worden. Der Inhaber wird sich wohl bald melden, um nach Korrektur seiner Client-Konfiguration die Aufhebung der Sperre zu wünschen.&lt;br /&gt;
&lt;br /&gt;
=== Log ===&lt;br /&gt;
Alle Anfragen werden in einer täglich wechselnden Log-Datei protokolliert, entweder schlicht oder ausführlich, je nachdem, ob eine Variable &amp;lt;tt&amp;gt;verbose&amp;lt;/tt&amp;gt; wahr ist.&lt;br /&gt;
Ein ausführlicher Log-Eintrag sieht so aus:&lt;br /&gt;
&lt;br /&gt;
  Sun Apr 26 20:21:45 2020  ddns aufgerufen von papst&lt;br /&gt;
  			unter 84.185.97.8&lt;br /&gt;
  	URL: &amp;lt;nowiki&amp;gt;https://ddns.example.com/cgi-bin/ddns.cgi?hostname=&lt;br /&gt;
  			avignon.example.com,vatican.beispiel.de&amp;amp;&lt;br /&gt;
  			myip=84.185.97.8&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
  	Verwende IP 84.185.97.8 (= 1421435144)&lt;br /&gt;
  	DB-Version: 1&lt;br /&gt;
  	Skript und DB exklusiv geöffnet&lt;br /&gt;
  	avignon.example.com: IP: 84.185.97.8; MX: 0; Backup-MX: nein;&lt;br /&gt;
  			Wildcard: nein; Mißbrauch: 0; gesperrt: nein &lt;br /&gt;
  	vatican.beispiel.de: IP: 84.185.97.8; MX: 0; Backup-MX: nein;&lt;br /&gt;
  			Wildcard: nein; Mißbrauch: 0; gesperrt: nein &lt;br /&gt;
  	Betroffene Zonen: example.com, beispiel.de&lt;br /&gt;
  	Temporärdatei example.com_hxNa.new geschrieben&lt;br /&gt;
  	Zonendatei /home/pacs/xyz00/users/benutzername/doms/example.com/&lt;br /&gt;
  			etc/pri.example.com eingestellt&lt;br /&gt;
  	Temporärdatei beispiel.de_6HcO.new geschrieben&lt;br /&gt;
  	Zonendatei /home/pacs/xyz00/users/benutzername/doms/beispiel.de/&lt;br /&gt;
  			etc/pri.beispiel.de eingestellt&lt;br /&gt;
  	Abgeschlossen: 	Fertig&lt;br /&gt;
&lt;br /&gt;
Wenn &amp;lt;tt&amp;gt;verbose&amp;lt;/tt&amp;gt; auf falsch gesetzt ist, sind die Log-Einträge einzeilig.&lt;/div&gt;</summary>
		<author><name>Apc00-tony</name></author>
	</entry>
	<entry>
		<id>https://wiki.hostsharing.net/index.php?title=Benutzer_Diskussion:Apc00-tony&amp;diff=5362</id>
		<title>Benutzer Diskussion:Apc00-tony</title>
		<link rel="alternate" type="text/html" href="https://wiki.hostsharing.net/index.php?title=Benutzer_Diskussion:Apc00-tony&amp;diff=5362"/>
		<updated>2021-01-12T20:19:14Z</updated>

		<summary type="html">&lt;p&gt;Apc00-tony: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Laß es raus!&lt;br /&gt;
--[[Benutzer:Apc00-tony|Apc00-tony]] 20:45, 8. Sep. 2009 (CEST)&lt;/div&gt;</summary>
		<author><name>Apc00-tony</name></author>
	</entry>
	<entry>
		<id>https://wiki.hostsharing.net/index.php?title=MySQL&amp;diff=5235</id>
		<title>MySQL</title>
		<link rel="alternate" type="text/html" href="https://wiki.hostsharing.net/index.php?title=MySQL&amp;diff=5235"/>
		<updated>2020-06-02T16:14:49Z</updated>

		<summary type="html">&lt;p&gt;Apc00-tony: Tote Links im Vorspann ersetzt&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Textkasten|gruen|Hinweis:|Datenbanken in der HS Kern-Dokumentation:&lt;br /&gt;
https://doc.hostsharing.net/einstieg/datenbank.html&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
== Datenbank anlegen ==&lt;br /&gt;
&lt;br /&gt;
erfolgt mit [https://doc.hostsharing.net/users/administration/hsadmin/index.html hsadmin] siehe [https://doc.hostsharing.net/users/administration/datenbanken/index.html Datenbanken].&lt;br /&gt;
&lt;br /&gt;
Datenbanknamen in MySQL beginnen bei Hostsharing immer mit dem Namen des Pakets, gefolgt von einem Unterstrich; danach folgt der frei wählbare eigentliche Name.&lt;br /&gt;
&lt;br /&gt;
Beispiele gültiger Datenbanken für ein Paket &amp;lt;b&amp;gt;xyz00&amp;lt;/b&amp;gt;:&lt;br /&gt;
* &amp;lt;b&amp;gt;xyz00_otto&amp;lt;/b&amp;gt;&lt;br /&gt;
* &amp;lt;b&amp;gt;xyz00_anna&amp;lt;/b&amp;gt;&lt;br /&gt;
* &amp;lt;b&amp;gt;xyz00_db_fuer_hans&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Administration ==&lt;br /&gt;
&lt;br /&gt;
Die Administration einer Mysql-Datenbank (das Verwalten von Tabellen) erfolgt üblicherweise mit [https://phpmyadmin.hostsharing.net/current/ PhpMyAdmin]&lt;br /&gt;
&lt;br /&gt;
== Der MySQL Command Line Client ==&lt;br /&gt;
&lt;br /&gt;
Mit einem Datenbanknutzer kann auch direkt im [https://dev.mysql.com/doc/refman/5.7/en/mysql.html MySQL Command Line Client] gearbeitet werden, in dem die MySQL-Befehle eingegeben und verarbeitet werden. Der Client wird auf der [[Shell]] mit dem Befehl &amp;lt;b&amp;gt;mysql&amp;lt;/b&amp;gt; aufgerufen. Es ist hier übrigens egal, ob wir als Paketadmin oder als Domainadmin eingeloggt sind, denn MySQL-User und UNIX-Accounts haben keinen Zusammenhang. Wir können mit jedem UNIX-Account, also auch als normaler Domainadmin auf jeden Datenbank-Account zugreifen – auch auf den Paketadmin-Account.&lt;br /&gt;
&lt;br /&gt;
Da wir uns mit Benutzernamen und Passwort anmelden müssen, verwenden wir die Optionen -u (und danach den Benutzernamen) und -p. Das Passwort geben wir nicht in dieser Kommandozeile an, denn sonst ist es für andere User sichtbar. Wenn wir nach -p nichts angeben, werden wir von mysql danach gefragt und geben es dann an.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&amp;lt;nowiki&amp;gt;&lt;br /&gt;
xyz00@hopi$ mysql -u xyz00_otto -p&lt;br /&gt;
Enter password: password&lt;br /&gt;
Welcome to the MySQL monitor. Commands end with ; or \g.&lt;br /&gt;
Your MySQL connection id is 1257230 to server version: 3.23.49-log&lt;br /&gt;
Type &#039;help;&#039; or &#039;\h&#039; for help. Type &#039;\c&#039; to clear the buffer.&lt;br /&gt;
mysql&amp;gt;&lt;br /&gt;
&amp;lt;/nowiki&amp;gt;&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Nun können wir MySQL-Befehle eingeben. Zu beachten ist, dass man nach einem Kommando mit einem ; abschließen muss. Es gibt einige Ausnahmen, wo man das nicht braucht, z.B. beim Befehl QUIT, mit dem man den Client wieder verlässt.&lt;br /&gt;
&lt;br /&gt;
=== Rechte an der Datenbank vergeben ===&lt;br /&gt;
&lt;br /&gt;
Optional kann man weitere Datenbank-User anlegen, denen man nur dedizierte Rechte für die neue Datenbank erteilt. Dafür werden die normalen SQL-Befehle verwendet. Der Datenbankadmin muss sich mit Hilfe des Kommandozeilen-Werkzeugs mysql mit der Datenbank verbinden und dann die Rechte wie gewünscht vergeben:&lt;br /&gt;
&lt;br /&gt;
  xyz00@host:~$ mysql -u xyz00-otto -p&lt;br /&gt;
  Enter password:&lt;br /&gt;
  Welcome to the MySQL ...&lt;br /&gt;
  &lt;br /&gt;
 mysql&amp;gt; GRANT SELECT, INSERT, UPDATE, DELETE, CREATE, DROP, REFERENCES, INDEX, ALTER ON xyz00_beispiel.* TO xyz00_beispiel;&lt;br /&gt;
  Query OK, 0 rows affected (0.01 sec)&lt;br /&gt;
  &lt;br /&gt;
  mysql&amp;gt; exit&lt;br /&gt;
  Bye&lt;br /&gt;
&lt;br /&gt;
Mit dem obigen GRANT-Befehl werden dem Benutzer alle Rechte an der Datenbank gegeben. In der Regel wird dies nicht notwendig sein; es ist sicherer, dem Benutzer nur die tatsächlich benötigten Rechte einzuräumen. Eine Auflistung der verschiedenen Rechte befindet sich in der MySQL-Dokumentation zum GRANT-Befehl.&lt;br /&gt;
&lt;br /&gt;
=== Datenbank testen ===&lt;br /&gt;
&lt;br /&gt;
Jetzt sollte der Benutzer die Datenbank nutzen können:&lt;br /&gt;
&lt;br /&gt;
  xyz00@host:~$ mysql -D xyz00_beispiel -u xyz00_beispiel -p&lt;br /&gt;
  Enter password:&lt;br /&gt;
  Welcome to the MySQL ...&lt;br /&gt;
&lt;br /&gt;
Ausprobieren, kann man dies Beispielsweise durch das Anlegen und Löschen einer Tabelle:&lt;br /&gt;
&lt;br /&gt;
  mysql&amp;gt; create table test(id INT);&lt;br /&gt;
  Query OK, 0 rows affected (0.86 sec)&lt;br /&gt;
  &lt;br /&gt;
  mysql&amp;gt; show tables;&lt;br /&gt;
  +--------------------------+&lt;br /&gt;
  | Tables_in_xyz00_beispiel |&lt;br /&gt;
  +--------------------------+&lt;br /&gt;
  | test                     |&lt;br /&gt;
  +--------------------------+&lt;br /&gt;
  1 row in set&lt;br /&gt;
  &lt;br /&gt;
  mysql&amp;gt; drop table test;&lt;br /&gt;
  Query ok, 0 rows affected (0.00 sec)&lt;br /&gt;
  &lt;br /&gt;
  mysql&amp;gt; exit&lt;br /&gt;
  Bye&lt;br /&gt;
&lt;br /&gt;
Das Anlegen und Löschen einer Tabelle funktioniert dabei natürlich nur, wenn dem Benutzer auch tatsächlich die dafür nötigen Rechte eingeräumt wurden. In der Regel wird ein Benutzerkonto, das für die Verwendung in einer Web-Anwendung eingerichtet wurde, diese Rechte nicht benötigen. Es ist dann sicherer, diese Rechte auch nicht zu vergeben.&lt;br /&gt;
&lt;br /&gt;
=== Rechte vergeben ===&lt;br /&gt;
&lt;br /&gt;
Allen Benutzern, außer dem Datenbank-Administrator, müssen wir noch Rechte geben, sonst können sie gar nichts machen. Das erledigt man mit dem Befehl &amp;lt;b&amp;gt;GRANT&amp;lt;/b&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&amp;lt;nowiki&amp;gt;&lt;br /&gt;
mysql&amp;gt;GRANT SELECT, INSERT, DELETE, UPDATE ON xyz00_meinedatenbank.* TO xyz00_otto;&lt;br /&gt;
&amp;lt;/nowiki&amp;gt;&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Hinter der Datenbank verwenden wir .*, um alle Tabellen der Datenbank zu inkludieren. &lt;br /&gt;
&lt;br /&gt;
Mit &amp;lt;b&amp;gt;GRANT ALL&amp;lt;/b&amp;gt; kann man einem User auch alle Kommandorechte zuweisen.&lt;br /&gt;
&lt;br /&gt;
Alle Aufgaben können wir jetzt in Zukunft vom User &amp;lt;b&amp;gt;xyz00_otto&amp;lt;/b&amp;gt; erledigen lassen.&lt;br /&gt;
&lt;br /&gt;
=== Import eines Mysql-Dump in eine leere Datenbank ===&lt;br /&gt;
&lt;br /&gt;
Wurde eine Mysql Datenbank in eine Datei exportiert (als eine Folge von SQL-Befehle in einer Textdatei, hier mit dem Namen backup_xyz.sql) , kann sie mit folgendem Befehl auf der Shell in die Datenbank xyz00_beispiel des Benutzers xyz00_beispiel importiert werden:&lt;br /&gt;
&lt;br /&gt;
  mysql --user xyz00_beispiel -p xyz00_beispiel &amp;lt; backup_xyz00_beispiel.sql&lt;br /&gt;
&lt;br /&gt;
=== Export einer Mysql Datenbank in eine Textdatei ===&lt;br /&gt;
&lt;br /&gt;
Um eine Datenbank auf der Shell in eine Textdatei zu exportieren, dient dieser Befehl:&lt;br /&gt;
  mysqldump --user xyz00_beispiel -p xyz00_beispiel &amp;gt; backup_xyz00_beispiel.sql&lt;br /&gt;
&lt;br /&gt;
== Verschiedenes ==&lt;br /&gt;
&lt;br /&gt;
* Web-Frontend: [http://www.phpmyadmin.net phpMyAdmin] ist unter https://phpmyadmin.hostsharing.net/current erreichbar.&lt;br /&gt;
* Online-Dokumentation: Die Online-Doku zu MySQL gibt es unter http://dev.mysql.com/doc/. Auf dieser Site gibt es auch mehrere Fassungen der kompletten Doku zum Downloaden.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
[[Kategorie:HSDoku]]&lt;br /&gt;
[[Kategorie:Datenbanken]]&lt;br /&gt;
[[Kategorie:Mysql]]&lt;/div&gt;</summary>
		<author><name>Apc00-tony</name></author>
	</entry>
	<entry>
		<id>https://wiki.hostsharing.net/index.php?title=Mailman_Installieren&amp;diff=5226</id>
		<title>Mailman Installieren</title>
		<link rel="alternate" type="text/html" href="https://wiki.hostsharing.net/index.php?title=Mailman_Installieren&amp;diff=5226"/>
		<updated>2020-05-14T20:37:34Z</updated>

		<summary type="html">&lt;p&gt;Apc00-tony: &amp;lt;tt&amp;gt; und &amp;lt;nowiki&amp;gt;&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Vorab: Die Wahl von Mailman 2 ==&lt;br /&gt;
&lt;br /&gt;
Mailman 2 hängt von Python 2.7 ab und wird damit voraussichtlich nur noch eine begrenzte Nutzungsdauer haben. Mailman 3 ist jetzt verfügbar (siehe [[Mailman_3_installieren]]), aber deutlich schwerer und komplexer im Betrieb. Es gibt auch weniger leistungsfähige Software, um E-Mail-Verteiler zu betreiben, wie beispielsweise [[mlmmj]]. Für eine Diskussion der Situation im Oktober 2019, siehe das HS-Support-Archiv ab [https://lists.hostsharing.net/archiv/support/2019-October/067243.html hier.]&lt;br /&gt;
&lt;br /&gt;
== Mailman 2 installieren == &lt;br /&gt;
&lt;br /&gt;
(zuletzt getestet mit mailman-2.1.29; Installation durch Paketuser)&lt;br /&gt;
&lt;br /&gt;
Vielen Dank an alle Benutzer, die Verbesserungen beisteuern!&lt;br /&gt;
&lt;br /&gt;
=== Unter welchem Account installieren? ===&lt;br /&gt;
&lt;br /&gt;
Mailman kann vom Paketadmin (beipsielsweise &amp;quot;xyz00&amp;quot;) oder von einem Paketuser (bspw. &amp;quot;xyz00-listen&amp;quot;) installiert werden. Letzteres ist dringend empfohlen, denn wenn Mailman vom Paketadmin installiert wird, haben ausnahmslos alle Paketuser direkten Zugriff auf die Mailman-Daten, und bei Sicherheitslücken in Mailman wäre eventuell eine Rechte-Eskalierung auf Paketadmin-Ebene potentiell zu befürchten.&lt;br /&gt;
&lt;br /&gt;
Dem Paketuser, unter dem Mailman installiert wird, können mehrere Subdomains aufschaltet werden, und Mailinglisten können auch die Domainnamen verwenden, die anderen Paketusern gehören.&lt;br /&gt;
&lt;br /&gt;
Vorteil der Installation als Paketuser ist, dass nur dieser direkten Zugriff auf die Mailmandaten hat und mailman ohne Paketadminrechte läuft. Während der Emailauslieferung gelten (wie immer bei der Mailweiterleitung durch .forward-Dateien oder durch procmail) die Rechte des Paketusers, dem die Mailman-Installation gehört.&lt;br /&gt;
&lt;br /&gt;
Nachteil der Installation als Paketuser ist lediglich, dass die Paketdomain mit dem SSL Zertifikat von Hostsharing nicht genutzt werden kann.&amp;lt;!-- Aktualisieren? --&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Einen User und eine Domain anlegen ===&lt;br /&gt;
&lt;br /&gt;
Unter admin.hostsharing.net als xyz00 anmelden; den User xyz00-listen erzeugen; die Domain listen.example.com mit &amp;quot;Domain-User&amp;quot; xyz00-listen anlegen. Aus admin.hostsharing.net abmelden.&lt;br /&gt;
&lt;br /&gt;
Mit [[Login_mit_SSH|SSH]] an hostsharing.net als xyz00-listen anmelden. Die Redirect-Zeile aus &amp;lt;tt&amp;gt;&amp;lt;nowiki&amp;gt;~/doms/listen.example.com/htdocs-ssl/.htaccess&amp;lt;/nowiki&amp;gt;&amp;lt;/tt&amp;gt; löschen:&lt;br /&gt;
&lt;br /&gt;
 ~$ echo &amp;quot;&amp;quot; &amp;gt; ~/doms/listen.example.com/htdocs-ssl/.htaccess&lt;br /&gt;
&lt;br /&gt;
Die Default-Subdomains www.* löschen:&lt;br /&gt;
&lt;br /&gt;
   ~$ rm -r doms/listen.example.com/subs/www/&lt;br /&gt;
   ~$ rm -r doms/listen.example.com/subs-ssl/www/&lt;br /&gt;
&lt;br /&gt;
=== Sourcen besorgen und entpacken ===&lt;br /&gt;
&lt;br /&gt;
Unter http://www.gnu.org/software/mailman/ die aktuelle Software besorgen. Dort findet sich ein Link zu den 2er-Versionen von Mailman (http://ftp.gnu.org/gnu/mailman/). Die letzte Version downloaden ...&lt;br /&gt;
&lt;br /&gt;
 ~$ wget http://ftp.gnu.org/gnu/mailman/mailman-2.1.29.tgz&lt;br /&gt;
&lt;br /&gt;
... und entpacken:&lt;br /&gt;
&lt;br /&gt;
 ~$ tar -xzvf mailman-2.1.29.tgz&lt;br /&gt;
&lt;br /&gt;
Ab diesem Augenblick gibt es ein Verzeichnis namens &amp;lt;tt&amp;gt;mailman-2.1.29/&amp;lt;/tt&amp;gt;. Darin liegt die nunmehr entpackte &#039;&#039;Quellcode&#039;&#039; der Mailman-Software. Nach dem Kompilieren (folgt unten) wird die fertig kompilierte, gebrauchsfähige Mailman-Software in dem zusätzlich vorhandenen Verzeichnis &amp;lt;tt&amp;gt;mailman/&amp;lt;/tt&amp;gt; liegen. (Dieses Verzeichnis wird beim Konfigurieren der Source als &amp;quot;prefix&amp;quot; angegeben.)&lt;br /&gt;
&lt;br /&gt;
=== var-Verzeichnis für Log-Dateien anlegen ===&lt;br /&gt;
&lt;br /&gt;
Bei der Installation als Paketuser (xyz00-listen):&lt;br /&gt;
 ~$ cd &amp;amp;&amp;amp; mkdir -p mailman/var&lt;br /&gt;
 ~$ chmod 02775 mailman/var&lt;br /&gt;
&lt;br /&gt;
Bei der Installation als Paketadmin (xyz00):&lt;br /&gt;
 ~$ cd &amp;amp;&amp;amp; mkdir var/mailman&lt;br /&gt;
 ~$ chmod 02775 var/mailman&lt;br /&gt;
&lt;br /&gt;
=== Mailman konfigurieren ===&lt;br /&gt;
&lt;br /&gt;
In das Source-Verzeichnis wechseln:&lt;br /&gt;
&lt;br /&gt;
 ~$ cd mailman-2.1.29&lt;br /&gt;
&lt;br /&gt;
Bei der Installation durch den Paketuser (xyz00-listen):&lt;br /&gt;
      ~/mailman-2.1.29$ ./configure --prefix=/home/pacs/xyz00/users/listen/mailman \&lt;br /&gt;
              --with-username=xyz00-listen \&lt;br /&gt;
              --with-groupname=xyz00 \&lt;br /&gt;
              --with-var-prefix=/home/pacs/xyz00/users/listen/mailman/var \&lt;br /&gt;
              --with-cgi-gid=xyz00 \&lt;br /&gt;
              --with-mail-gid=xyz00&lt;br /&gt;
&lt;br /&gt;
Bei der Installation durch den Paketadmin (xyz00):&lt;br /&gt;
      ~/mailman-2.1.29$ ./configure --prefix=/home/pacs/xyz00/mailman \&lt;br /&gt;
              --with-username=xyz00 \&lt;br /&gt;
              --with-groupname=xyz00 \&lt;br /&gt;
              --with-var-prefix=/home/pacs/xyz00/var/mailman \&lt;br /&gt;
              --with-cgi-gid=xyz00 \&lt;br /&gt;
              --with-mail-gid=nogroup&lt;br /&gt;
&lt;br /&gt;
(Die Rückwärtsschrägstriche &amp;quot;\&amp;quot; am Zeilenende bedeuten, dass der Befehl in der nächsten Zeile weitergeht. Alternativ können alle Argumente in eine Zeile getippt werden.)&lt;br /&gt;
&lt;br /&gt;
=== Mailman kompilieren ===&lt;br /&gt;
&lt;br /&gt;
 ~/mailman-2.1.29$ make&lt;br /&gt;
 ~/mailman-2.1.29$ make install&lt;br /&gt;
&lt;br /&gt;
=== Datenrechte prüfen ===&lt;br /&gt;
&lt;br /&gt;
Sicherheitshalber die Dateirechte durch Mailmans mitgeliefertes Tool prüfen und ggf. korrigieren lassen:&lt;br /&gt;
&lt;br /&gt;
 ~/mailman-2.1.29$ cd ..      &lt;br /&gt;
 ~$ mailman/bin/check_perms -f&lt;br /&gt;
&lt;br /&gt;
== Die neue Mailman-Installation konfigurieren ==&lt;br /&gt;
&lt;br /&gt;
=== Konfigurationsdatei &amp;lt;tt&amp;gt;mm_cfg.py&amp;lt;/tt&amp;gt; editieren ===&lt;br /&gt;
&lt;br /&gt;
 ~$ nano mailman/Mailman/mm_cfg.py&lt;br /&gt;
      &lt;br /&gt;
Eine Beispielkonfiguration für listen.example.com könnte so aussehen:&lt;br /&gt;
&lt;br /&gt;
 [...]&lt;br /&gt;
      ##################################################&lt;br /&gt;
      # Put YOUR site-specific settings below this line.&lt;br /&gt;
      # -*- python -*-&lt;br /&gt;
 &lt;br /&gt;
      DEFAULT_HOST_NAME = &#039;listen.example.com&#039;&lt;br /&gt;
      DEFAULT_EMAIL_HOST = &#039;listen.example.com&#039;&lt;br /&gt;
      DEFAULT_URL_HOST = &#039;listen.example.com&#039;&lt;br /&gt;
      add_virtualhost(DEFAULT_URL_HOST, DEFAULT_EMAIL_HOST)&lt;br /&gt;
      add_virtualhost(zweite.listendomain.com, zweite.listendomain.com)&lt;br /&gt;
 &lt;br /&gt;
      DEFAULT_SERVER_LANGUAGE = &#039;de&#039;&lt;br /&gt;
 &lt;br /&gt;
      DEFAULT_URL_PATTERN = &#039;http://%s/&#039;&lt;br /&gt;
  &lt;br /&gt;
      # Es wird der HS Mailversand für Bulkmail verwendet:&lt;br /&gt;
      SMTPHOST = &#039;localhost&#039;&lt;br /&gt;
      SMTPPORT = 4587 &lt;br /&gt;
      SMTP_AUTH = True&lt;br /&gt;
      SMTP_USER = &#039;xyz00-listen&#039;&lt;br /&gt;
      SMTP_PASSWD = &#039;das-passwort-des-o.-g.-users&#039;&lt;br /&gt;
      SMTP_USE_TLS = True&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
In &amp;lt;tt&amp;gt;~/mailman/Mailman/Defaults.py&amp;lt;/tt&amp;gt; sieht man, was in mm_cfg.py alles angepasst werden kann.&lt;br /&gt;
&lt;br /&gt;
=== CGI-Programme in die Domain kopieren ===&lt;br /&gt;
&lt;br /&gt;
Bei der Installation als Paketuser (xyz00-listen):&lt;br /&gt;
&lt;br /&gt;
Die fertig kompilierten CGIs von Mailman müssen in das CGI-Verzeichnis der Domain (oder der Domains), auf der das Webfrontend von Mailman laufen soll, kopiert werden. Symbolische Links sind nicht ausreichend.&lt;br /&gt;
&lt;br /&gt;
 ~$ mkdir ~/doms/listen.example.com/cgi-ssl/mailman&lt;br /&gt;
 ~$ cp mailman/cgi-bin/* doms/listen.example.com/cgi-ssl/mailman/&lt;br /&gt;
&lt;br /&gt;
Zusätzlich muss das sticky-Flag von den kopierten Dateien entfernt werden:&lt;br /&gt;
&lt;br /&gt;
 ~$ chmod g-s ~/doms/listen.example.com/cgi/mailman/*&lt;br /&gt;
&lt;br /&gt;
Bei der Installation als Paketadmin (xyz00): &lt;br /&gt;
&lt;br /&gt;
Die CGI-Programme können im Mailman-Verzeichnis bleiben. Im CGI-Verzeichnis von jeder Domain, auf der das Mailman-Webfrontend laufen soll, werden symbolische Links dazu erstellt: &lt;br /&gt;
&lt;br /&gt;
 ~$ cd doms/listen.example.com/cgi-ssl&lt;br /&gt;
 ~/doms/listen.example.com/cgi-ssl$ ln -s ../../../mailman/cgi-bin mailman&lt;br /&gt;
&lt;br /&gt;
===  Mailman-Icons in die Domains kopieren ===&lt;br /&gt;
&lt;br /&gt;
Die Icons können wahlweise verlinkt oder kopiert werden:&lt;br /&gt;
&lt;br /&gt;
 ~$ cd doms/listen.example.com/htdocs-ssl&lt;br /&gt;
 ~/doms/listen.example.com/htdocs-ssl$ ln -s ../../../mailman/icons&lt;br /&gt;
&lt;br /&gt;
oder&lt;br /&gt;
&lt;br /&gt;
 ~$ cp -R mailman/icons doms/listen.example.com/htdocs-ssl/&lt;br /&gt;
&lt;br /&gt;
=== Die Datei .htaccess bearbeiten ===&lt;br /&gt;
&lt;br /&gt;
Bei einer dedizierten Mailman-Domain sollte man dafür sorgen, dass Mailman nicht nur unter &amp;lt;tt&amp;gt;&amp;lt;nowiki&amp;gt;https://listen.example.com/cgi-bin/mailman&amp;lt;/nowiki&amp;gt;&amp;lt;/tt&amp;gt;, sondern auch unter &amp;lt;tt&amp;gt;&amp;lt;nowiki&amp;gt;https://listen.example.com/&amp;lt;/nowiki&amp;gt;&amp;lt;/tt&amp;gt;  erreichbar ist.&lt;br /&gt;
&lt;br /&gt;
Dazu werden in &amp;lt;tt&amp;gt;&amp;lt;nowiki&amp;gt;~/doms/listen.example.com/htdocs-ssl/.htaccess&amp;lt;/nowiki&amp;gt;&amp;lt;/tt&amp;gt; folgende Rewrite-Anweisungen eintragen.&lt;br /&gt;
&lt;br /&gt;
 RewriteEngine On&lt;br /&gt;
 RewriteCond	%{REQUEST_URI}		!^/icons/&lt;br /&gt;
 RewriteRule	^(.*)$			/cgi-bin/mailman/$1&lt;br /&gt;
 RewriteRule	^/cgi-bin/mailman/$	/cgi-bin/mailman/listinfo&lt;br /&gt;
&lt;br /&gt;
Beachte dabei die zweite Zeile: Anfragen für Icons sollen &#039;&#039;nicht&#039;&#039; umgeschrieben werden.&lt;br /&gt;
&lt;br /&gt;
Wenn Mailman z.B. auf einer als Unterverzeichnis angelegten Subdomain läuft und unter &amp;lt;tt&amp;gt;&amp;lt;nowiki&amp;gt;https://www.example.com/mailman&amp;lt;/nowiki&amp;gt;&amp;lt;/tt&amp;gt; statt &amp;lt;tt&amp;gt;&amp;lt;nowiki&amp;gt;https://www.example.com/cgi-bin/mailman&amp;lt;/nowiki&amp;gt;&amp;lt;/tt&amp;gt; erreichbar sein soll, hilft folgendes in der &amp;lt;tt&amp;gt;&amp;lt;nowiki&amp;gt;~/doms/example.com/subs-ssl/www/.htaccess&amp;lt;/nowiki&amp;gt;&amp;lt;/tt&amp;gt;:&lt;br /&gt;
&lt;br /&gt;
 RewriteEngine On&lt;br /&gt;
 RewriteCond	%{REQUEST_URI}		!^/icons/&lt;br /&gt;
 RewriteRule    ^mailman/(.*)$          /cgi-bin/mailman/$1&lt;br /&gt;
 RewriteRule    ^/cgi-bin/mailman/$	/cgi-bin/mailman/listinfo&lt;br /&gt;
&lt;br /&gt;
(In diesem Fall kann die Zeile &amp;lt;tt&amp;gt;DEFAULT_URL_PATTERN...&amp;lt;/tt&amp;gt; in der &amp;lt;tt&amp;gt;mm_cfg.py&amp;lt;/tt&amp;gt; auskommentiert werden.)&lt;br /&gt;
&lt;br /&gt;
=== Hauptpasswort setzen ===&lt;br /&gt;
&lt;br /&gt;
Das &amp;quot;site password&amp;quot; ist in Mailman eine Art Generalschlüssel: es wird neben dem jeweiligen Admin- oder Moderator-Passwort überall in der Weboberfläche für sämtliche Mailing-Listen akzeptiert. Also vorsichtig wählen! Das &amp;quot;site password&amp;quot; einrichten mit dem Befehl: &lt;br /&gt;
&lt;br /&gt;
 ~$ mailman/bin/mmsitepass&lt;br /&gt;
&lt;br /&gt;
=== Cronjobs einrichten ===&lt;br /&gt;
&lt;br /&gt;
In die [[Cron |Crontab]] werden Befehle eingetragen, um die Mail-Warteschlange abzuarbeiten, Logs zu löschen, usw.:&lt;br /&gt;
&lt;br /&gt;
 # Warteschlange jede Minute bearbeiten:&lt;br /&gt;
 * * * * *	~/mailman/bin/qrunner -o -r All&lt;br /&gt;
 # Verarbeitungslogs in der 47ten Minute jeder Stunde löschen:&lt;br /&gt;
 47 * * * *	rm -f ~/var/mailman/logs/qrunner&lt;br /&gt;
&lt;br /&gt;
Damit übernimmt cron die Funktion des qrunner-Dämons, der normalerweise auf einem Mailman-Server laufen sollte.&lt;br /&gt;
&lt;br /&gt;
Das Logfile wird stündlich gelöscht, da es sonst sehr schnell sehr groß wird. Falls Mailman von einem Paketuser (bspw. &amp;quot;xyz00-listen&amp;quot;) installiert wurde, sollte die letzte Zeile im Beispiel oben so lauten:&lt;br /&gt;
&lt;br /&gt;
 47 * * * * rm -f ~/mailman/var/logs/qrunner&lt;br /&gt;
&lt;br /&gt;
... entsprechend dem beim Konfigurieren angegebenen &amp;lt;tt&amp;gt;var&amp;lt;/tt&amp;gt;-Verzeichnis, siehe oben.&lt;br /&gt;
&lt;br /&gt;
Zudem müssen noch die von Mailman ohnehin vorgesehenen cron-Aufträge aus &amp;lt;tt&amp;gt;~/mailman/cron/crontab.in&amp;lt;/tt&amp;gt; dem crontab des Users angehängt werden:&lt;br /&gt;
&lt;br /&gt;
 crontab -l &amp;gt; mycronjobs.tmp&lt;br /&gt;
 cat ~/mailman/cron/crontab.in &amp;gt;&amp;gt; mycronjobs.tmp&lt;br /&gt;
 crontab mycronjobs.tmp&lt;br /&gt;
&lt;br /&gt;
== Mailinglisten einrichten ==&lt;br /&gt;
&lt;br /&gt;
Jetzt läuft die Software; nun können die eigentlichen Verteiler angelegt werden. Als erster &#039;&#039;&#039;muß&#039;&#039;&#039; ein Hauptverteiler (&amp;quot;site list&amp;quot;) eingerichtet werden. Dieser Verteiler dient u.a. als Absender der Paßwort-Erinnerungen an die Abonnenten aller Mailinglisten. Er hat standardmäßig den Namen &amp;quot;mailman&amp;quot;. Falls ein anderer Name verwendet werden soll, muß dieser mit der Anweisung &lt;br /&gt;
&lt;br /&gt;
 MAILMAN_SITE_LIST = &#039;sitelistname&#039;&lt;br /&gt;
&lt;br /&gt;
in der Konfigurationsdatei &amp;lt;tt&amp;gt;mailman/Mailman/mm_cfg.py&amp;lt;/tt&amp;gt; eingetragen werden.&lt;br /&gt;
&lt;br /&gt;
=== Den Hauptverteiler &amp;quot;mailman&amp;quot; anlegen ===&lt;br /&gt;
&lt;br /&gt;
Die &amp;quot;site list&amp;quot; mit dem Namen &amp;quot;mailman&amp;quot; ist die Mailingliste der lokalen Mailman-Administratoren. Sie wird zur einwandfreien Funktion von Mailman benötigt.&lt;br /&gt;
&lt;br /&gt;
Mit dem Mailman-Befehl newlist den Verteiler anlegen:&lt;br /&gt;
&lt;br /&gt;
 ~$ mailman/bin/newlist mailman&lt;br /&gt;
 Enter the email of the person running the list: admin@xyz00.hostsharing.net&lt;br /&gt;
 Initial mailman password:&lt;br /&gt;
&lt;br /&gt;
(Der Befehl newlist kann – alternativ zur Weboberfläche – später benutzt werden, um gewöhnliche Mailinglisten anzulegen.)&lt;br /&gt;
&lt;br /&gt;
Nur dieses eine Mal für die &amp;quot;site list&amp;quot; müssen wir die Konfigurationsvorgaben laden. (Gewöhnliche Mailinglisten werden später über die Weboberfläche konfiguriert.)&lt;br /&gt;
&lt;br /&gt;
Falls mailman vom Paketuser (bspw. &amp;quot;xyz00-listen&amp;quot;) installiert wurde:&lt;br /&gt;
&lt;br /&gt;
 ~$ mailman/bin/config_list -i ~/mailman/var/data/sitelist.cfg mailman&lt;br /&gt;
&lt;br /&gt;
Falls mailman vom Paketadmin (&amp;quot;xyz00&amp;quot;) installiert wurde:&lt;br /&gt;
&lt;br /&gt;
 ~$ mailman/bin/config_list -i ~/var/mailman/data/sitelist.cfg mailman&lt;br /&gt;
&lt;br /&gt;
Diese Konfigurationsdatei soll &#039;&#039;&#039;nicht&#039;&#039;&#039; auf gewöhnliche Mailinglisten anwendet werden.&lt;br /&gt;
&lt;br /&gt;
=== E-Mail Adressen bei Mailman einrichten ===&lt;br /&gt;
&lt;br /&gt;
Sobald ein neuer Verteiler angelegt worden ist, sendet Mailman eine E-Mail an den dabei eingetragenen Listenadministrator. Diese E-Mail enthält die Anweisung, E-Mail-Aliases für den neuen Verteiler und für die verschiedenen Mailman-Funktionen anzulegen. Bei Hostsharing wird die Zustellung von E-Mails an Mailman anders geregelt: alle E-Mails an Mailman werden an erweiterte &#039;&#039;E-Mail-Adressen&#039;&#039; des Mailman-Users xyz00-listen geschickt. Diese Adressen haben die form &amp;lt;tt&amp;gt;xyz00-listen&#039;&#039;&#039;+&#039;&#039;&#039;&amp;lt;liste&amp;gt;[_funktion]&amp;lt;/tt&amp;gt;. E-Mails an diese Adressen werden dann durch Pipe-Anweisungen in &#039;&#039;.forward-Dateien&#039;&#039; im Home-Verzeichnis des Mailman-Users mit den entsprechenden Argumenten an Mailman übergeben. &lt;br /&gt;
&lt;br /&gt;
Falls Mailman von einem Paketuser (bspw. &amp;quot;xyz00-listen&amp;quot;) installiert wurde, werden  &#039;&#039;E-Mail-Adressen&#039;&#039; durch [https://doc.hostsharing.net/users/administration/hsadmin/index.html hsadmin (bzw. das Befehlszeilentool hsscript)] eingerichtet; die &#039;&#039;.forward-Dateien&#039;&#039; werden durch [[Login_mit_SSH|Shell-Befehle]] angelegt.&lt;br /&gt;
&lt;br /&gt;
Das folgende Beispiel zeigt die Befehle, mit denen in einer interaktiven hsscript-Sitzung die E-Mail-Adressen für die Hauptliste &amp;quot;mailman&amp;quot; eingerichtet werden. (Für spätere Mailinglisten wird in den Argumenten &amp;quot;mailman&amp;quot; durch den Namen der Mailingliste ersetzt.)&lt;br /&gt;
&lt;br /&gt;
   hsscript -u xyz00 -i&lt;br /&gt;
   [hsscript verlangt die Eingabe des Passworts vom Paketadmin xyz00; dann können diese Befehle eingegeben werden:]&lt;br /&gt;
   emailaddress.add ({set:{domain:&#039;listen.example.com&#039;,localpart:&#039;mailman&#039;,target:&#039;xyz00-listen+mailman&#039;}})&lt;br /&gt;
   emailaddress.add ({set:{domain:&#039;listen.example.com&#039;,localpart:&#039;mailman-admin&#039;,target:&#039;xyz00-listen+mailman-admin&#039;}})&lt;br /&gt;
   emailaddress.add ({set:{domain:&#039;listen.example.com&#039;,localpart:&#039;mailman-bounces&#039;,target:&#039;xyz00-listen+mailman-bounces&#039;}})&lt;br /&gt;
   emailaddress.add ({set:{domain:&#039;listen.example.com&#039;,localpart:&#039;mailman-confirm&#039;,target:&#039;xyz00-listen+mailman-confirm&#039;}})&lt;br /&gt;
   emailaddress.add ({set:{domain:&#039;listen.example.com&#039;,localpart:&#039;mailman-join&#039;,target:&#039;xyz00-listen+mailman-join&#039;}})&lt;br /&gt;
   emailaddress.add ({set:{domain:&#039;listen.example.com&#039;,localpart:&#039;mailman-leave&#039;,target:&#039;xyz00-listen+mailman-leave&#039;}})&lt;br /&gt;
   emailaddress.add ({set:{domain:&#039;listen.example.com&#039;,localpart:&#039;mailman-owner&#039;,target:&#039;xyz00-listen+mailman-owner&#039;}})&lt;br /&gt;
   emailaddress.add ({set:{domain:&#039;listen.example.com&#039;,localpart:&#039;mailman-request&#039;,target:&#039;xyz00-listen+mailman-request&#039;}})&lt;br /&gt;
   emailaddress.add ({set:{domain:&#039;listen.example.com&#039;,localpart:&#039;mailman-subscribe&#039;,target:&#039;xyz00-listen+mailman-subscribe&#039;}})&lt;br /&gt;
   emailaddress.add ({set:{domain:&#039;listen.example.com&#039;,localpart:&#039;mailman-unsubscribe&#039;,target:&#039;xyz00-listen+mailman-unsubscribe&#039;}})&lt;br /&gt;
&lt;br /&gt;
Die korrekte Einrichtung der E-Mail-Adressen kann in der Web-Oberfläche von hsadmin kontrolliert werden.&lt;br /&gt;
&lt;br /&gt;
Für jede der soeben eingerichteten Adressen wird nun eine &amp;lt;tt&amp;gt;.forward&amp;lt;/tt&amp;gt;-Datei im Homeverzeichnis des Users xyz00-listen angelegt. Die Dateinamen bestehen aus der Zeichenfolge &amp;lt;tt&amp;gt;.forward+&amp;lt;/tt&amp;gt; gefolgt vom Namen der ausführen soll. Der Inhalt der jeweiligen &amp;lt;tt&amp;gt;.forward&amp;lt;/tt&amp;gt;-Datei legt die Weiterleitung der Mail durch einen Pipe an Mailman fest, mit dem jeweiligen Befehl als Argument:&lt;br /&gt;
&lt;br /&gt;
   &amp;quot;|/home/pacs/xyz00/users/listen/mailman/mail/mailman [Befehl] [Listenname]&amp;quot;&lt;br /&gt;
&lt;br /&gt;
Zum Beispiel wird die &amp;lt;tt&amp;gt;.forward&amp;lt;/tt&amp;gt;-Datei .forward+mailman-subscribe verwendet, wenn eine E-Mail an die Adresse &amp;lt;tt&amp;gt;mailman-subscribe@listen.example.com&amp;lt;/tt&amp;gt; eingeht. Aufgrund der oben eingerichteten E-Mail-Adresse mit dem Ziel &amp;lt;tt&amp;gt;xyz00-listen+mailman-subscribe&amp;lt;/tt&amp;gt; wertet der Mail-Transfer-Agent die &amp;lt;tt&amp;gt;.forward&amp;lt;/tt&amp;gt;-Datei &amp;lt;tt&amp;gt;.forward+mailman-subscribe&amp;lt;/tt&amp;gt; im Home-Verzeichnis des Users xyz00-listen aus, und entsprechend ihrem Inhalt wird die Mail an die Mailman-Software mit den Argumenten &amp;quot;subscribe mailman&amp;quot; übergeben.&lt;br /&gt;
&lt;br /&gt;
Das folgende Beispiel zeigt die Befehle, mit denen an der Befehlszeilenaufforderung der Shell die &amp;lt;tt&amp;gt;.forward&amp;lt;/tt&amp;gt;-Dateien für die Hauptliste &amp;quot;mailman&amp;quot; eingerichtet werden. (Für spätere Mailinglisten wird in den Argumenten und in den Namen der &amp;lt;tt&amp;gt;.forward&amp;lt;/tt&amp;gt;-Dateien &amp;quot;mailman&amp;quot; durch den Namen der Mailingliste ersetzt, jedoch &#039;&#039;&#039;nicht&#039;&#039;&#039; in der Pfadangabe zum Mailman-Programm selbst; diese ändert sich ja nicht.)&lt;br /&gt;
&lt;br /&gt;
 echo &#039;admin@xyz00.hostsharing.net&#039; &amp;gt; .forward # Weiterleitung von cron Fehlern etc an Paketadmin.&lt;br /&gt;
 echo &#039;&amp;quot;|/home/pacs/xyz00/users/listen/mailman/mail/mailman post mailman&amp;quot;&#039; &amp;gt; .forward+mailman&lt;br /&gt;
 echo &#039;&amp;quot;|/home/pacs/xyz00/users/listen/mailman/mail/mailman admin mailman&amp;quot;&#039; &amp;gt; .forward+mailman-admin&lt;br /&gt;
 echo &#039;&amp;quot;|/home/pacs/xyz00/users/listen/mailman/mail/mailman bounces mailman&amp;quot;&#039; &amp;gt; .forward+mailman-bounces&lt;br /&gt;
 echo &#039;&amp;quot;|/home/pacs/xyz00/users/listen/mailman/mail/mailman confirm mailman&amp;quot;&#039; &amp;gt; .forward+mailman-confirm&lt;br /&gt;
 echo &#039;&amp;quot;|/home/pacs/xyz00/users/listen/mailman/mail/mailman join mailman&amp;quot;&#039; &amp;gt; .forward+mailman-join&lt;br /&gt;
 echo &#039;&amp;quot;|/home/pacs/xyz00/users/listen/mailman/mail/mailman leave mailman&amp;quot;&#039; &amp;gt; .forward+mailman-leave&lt;br /&gt;
 echo &#039;&amp;quot;|/home/pacs/xyz00/users/listen/mailman/mail/mailman owner mailman&amp;quot;&#039; &amp;gt; .forward+mailman-owner&lt;br /&gt;
 echo &#039;&amp;quot;|/home/pacs/xyz00/users/listen/mailman/mail/mailman request mailman&amp;quot;&#039; &amp;gt; .forward+mailman-request&lt;br /&gt;
 echo &#039;&amp;quot;|/home/pacs/xyz00/users/listen/mailman/mail/mailman subscribe mailman&amp;quot;&#039; &amp;gt; .forward+mailman-subscribe&lt;br /&gt;
 echo &#039;&amp;quot;|/home/pacs/xyz00/users/listen/mailman/mail/mailman unsubscribe mailman&amp;quot;&#039; &amp;gt; .forward+mailman-unsubscribe&lt;br /&gt;
&lt;br /&gt;
Die vielen Befehle können von dieser Anleitung kopiert und nach Anpassung auf den tatsächlichen Unsernamen in die SSH-Sitzung kopiert werden. Noch leichter ist es, mit einem Editor einen Shell-Skript namens &amp;lt;tt&amp;gt;~/bin/addforwards&amp;lt;/tt&amp;gt; mit folgendem Inhalt zu erstellen:&lt;br /&gt;
&lt;br /&gt;
 #!/bin/sh&lt;br /&gt;
 # .forward-Dateien für einen Verteiler unter Mailman einrichten.&lt;br /&gt;
 #&lt;br /&gt;
 if [ &amp;quot;$1&amp;quot; = &amp;quot;&amp;quot; ] ; then&lt;br /&gt;
    echo &amp;quot;Aufruf: $0 Listenname\n&amp;quot; &lt;br /&gt;
    exit&lt;br /&gt;
 fi&lt;br /&gt;
 if [ &amp;quot;$2&amp;quot; != &amp;quot;&amp;quot; ] ; then&lt;br /&gt;
    echo &amp;quot;Aufruf: $0 Listenname\n&amp;quot; &lt;br /&gt;
    exit&lt;br /&gt;
 fi&lt;br /&gt;
 if [ &amp;quot;`pwd`&amp;quot; != &amp;quot;`echo ~`&amp;quot; ] ; then&lt;br /&gt;
    echo &amp;quot;Diesen Befehl vom Home-Verzeichnis aus aufrufen.\n&amp;quot; &lt;br /&gt;
    exit&lt;br /&gt;
 fi&lt;br /&gt;
 echo &amp;quot;\&amp;quot;|/home/pacs/xyz00/users/listen/mailman/mail/mailman post $1\&amp;quot;&amp;quot; &amp;gt; .forward+$1&lt;br /&gt;
 echo &amp;quot;\&amp;quot;|/home/pacs/xyz00/users/listen/mailman/mail/mailman admin $1\&amp;quot;&amp;quot; &amp;gt; .forward+$1-admin&lt;br /&gt;
 echo &amp;quot;\&amp;quot;|/home/pacs/xyz00/users/listen/mailman/mail/mailman bounces $1\&amp;quot;&amp;quot; &amp;gt; .forward+$1-bounces&lt;br /&gt;
 echo &amp;quot;\&amp;quot;|/home/pacs/xyz00/users/listen/mailman/mail/mailman confirm $1\&amp;quot;&amp;quot; &amp;gt; .forward+$1-confirm&lt;br /&gt;
 echo &amp;quot;\&amp;quot;|/home/pacs/xyz00/users/listen/mailman/mail/mailman join $1\&amp;quot;&amp;quot; &amp;gt; .forward+$1-join&lt;br /&gt;
 echo &amp;quot;\&amp;quot;|/home/pacs/xyz00/users/listen/mailman/mail/mailman leave $1\&amp;quot;&amp;quot; &amp;gt; .forward+$1-leave&lt;br /&gt;
 echo &amp;quot;\&amp;quot;|/home/pacs/xyz00/users/listen/mailman/mail/mailman owner $1\&amp;quot;&amp;quot; &amp;gt; .forward+$1-owner&lt;br /&gt;
 echo &amp;quot;\&amp;quot;|/home/pacs/xyz00/users/listen/mailman/mail/mailman request $1\&amp;quot;&amp;quot; &amp;gt; .forward+$1-request&lt;br /&gt;
 echo &amp;quot;\&amp;quot;|/home/pacs/xyz00/users/listen/mailman/mail/mailman subscribe $1\&amp;quot;&amp;quot; &amp;gt; .forward+$1-subscribe&lt;br /&gt;
 echo &amp;quot;\&amp;quot;|/home/pacs/xyz00/users/listen/mailman/mail/mailman unsubscribe $1\&amp;quot;&amp;quot; &amp;gt; .forward+$1-unsubscribe&lt;br /&gt;
 exit&lt;br /&gt;
&lt;br /&gt;
Der Skript muß natürlich als ausführbar gekennzeichnet werden:&lt;br /&gt;
&lt;br /&gt;
  ~$ chmod u+x bin/addforwards&lt;br /&gt;
&lt;br /&gt;
Die Erweiterung dieses Skripts um die &amp;lt;tt&amp;gt;hsscript&amp;lt;/tt&amp;gt;-Befehle wird dem geneigten Leser als Aufgabe überlassen.&lt;br /&gt;
&lt;br /&gt;
=== Administration ===&lt;br /&gt;
&lt;br /&gt;
Als erstes sollte man als Administrator der neuen Mailman-Installation die Liste &amp;quot;mailman&amp;quot; selbst abonnieren. Die Liste &amp;quot;mailman&amp;quot; kann aber unter &amp;lt;tt&amp;gt;&amp;lt;nowiki&amp;gt;https://listen.example.com/mailman/admin/mailman&amp;lt;/nowiki&amp;gt;&amp;lt;/tt&amp;gt; verwaltet werden.&lt;br /&gt;
&lt;br /&gt;
Die Hauptseite der Mailman-Web-Verwaltung ist in unserem Beispiel (mit den oben angegebenen Rewrite-Anweisungen in der Datei &amp;lt;tt&amp;gt;.htaccess&amp;lt;/tt&amp;gt;) &amp;lt;tt&amp;gt;&amp;lt;nowiki&amp;gt;https://listen.example.com/mailman/admin/&amp;lt;/nowiki&amp;gt;&amp;lt;/tt&amp;gt;. Diese Seite enthält Links zu den bisher eingerichteten Mailinglisten (außer &amp;quot;mailman&amp;quot;) und einen Link, um neue Mailinglisten anzulegen (&amp;lt;tt&amp;gt;&amp;lt;nowiki&amp;gt;https://listen.example.com/mailman/create&amp;lt;/nowiki&amp;gt;&amp;lt;/tt&amp;gt;). Das Anlegen einer neuen Mailingliste geschieht entweder über diesen Link oder (wie oben) in der Shell mit dem Befehl:&lt;br /&gt;
&lt;br /&gt;
 ~$ mailman/bin/newlist &amp;lt;Listenname&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In beiden Fällen müssen zusätzlich die E-Mail-Adressen und die &amp;lt;tt&amp;gt;.forward&amp;lt;/tt&amp;gt;-Dateien wie bei dem Einrichten der Liste &amp;quot;mailman&amp;quot; nach Verfahren im obigen Abschnitt angelegt werden.&lt;br /&gt;
&lt;br /&gt;
Für die Verwaltung der Mailinglisten im Alltag, d.h. den Umgang mit Bounces, Spam, Abonnenten usw., siehe u.a. die [https://wiki.list.org/ Mailman-Wiki].&lt;br /&gt;
&lt;br /&gt;
== Feintuning == &lt;br /&gt;
&lt;br /&gt;
Wer will, kann auch noch etwas Platz sparen. Die normale Mailmaninstallation schlägt mit über 20 MB zu Buche...&lt;br /&gt;
&lt;br /&gt;
Mit den folgenden Tips kann man das auf ca. 6 MB reduzieren :)&lt;br /&gt;
&lt;br /&gt;
Es kann natürlich sein, dass ich zuviel lösche, aber bei mir funktioniert&#039;s. Wenn ihr also sicher(er) sein wollt, dass euch der Mailman nicht um die Ohren fliegt, macht das nicht!&lt;br /&gt;
&lt;br /&gt;
*  ~/mailman/cgi-bin und ~/mailman/icons können gelöscht werden, falls sie an andere Stelle kopiert worden sind.&lt;br /&gt;
* Die nicht benötigten Sprachen in ~/mailman/messages löschen.&lt;br /&gt;
* Die nicht benötigten Sprachen in ~/mailman/templates löschen (bis auf englisch).&lt;br /&gt;
* ~/mailman/tests kann, soweit ich das sehe, komplett gelöscht werden.&lt;br /&gt;
* Falls man koreanisch und japanisch nicht braucht, kann man folgendes machen:&lt;br /&gt;
* in ~/mailman/bin/paths.py, ~/mailman/cron/paths.py und ~/mailman/scripts/paths.py die Zeilen:&lt;br /&gt;
&lt;br /&gt;
 # In a normal interactive Python environment, the japanese.pth and korean.pth&lt;br /&gt;
 # files would be imported automatically.  But because we inhibit the importing&lt;br /&gt;
 # of the site module, we need to be explicit about importing these codecs.&lt;br /&gt;
 if not jaok:&lt;br /&gt;
     import japanese&lt;br /&gt;
 # As of KoreanCodecs 2.0.5, you had to do the second import to get the Korean&lt;br /&gt;
 # codecs installed, however leave the first import in there in case an upgrade&lt;br /&gt;
 # changes this.&lt;br /&gt;
 if not kook:&lt;br /&gt;
     import korean&lt;br /&gt;
     import korean.aliases&lt;br /&gt;
&lt;br /&gt;
auskommentieren.&lt;br /&gt;
&lt;br /&gt;
Dann kann man ~/mailman/pythonlib/japanese, ~/mailman/pythonlib/korean, ~/mailman/pythonlib/korean.pth sowie ~/mailman/pythonlib/lib löschen.&lt;br /&gt;
   &lt;br /&gt;
Man kann auch noch die Debug-Informationen aus den binaries strippen:&lt;br /&gt;
&lt;br /&gt;
 strip ~/mailman/mail/mailman&lt;br /&gt;
 strip ~/mailman/cgi-bin/*&lt;br /&gt;
&lt;br /&gt;
Falls die CGIs nicht gesymlinkt wurden:&lt;br /&gt;
&lt;br /&gt;
 strip ~/doms/listen.example.com/cgi/mailman/*&lt;br /&gt;
&lt;br /&gt;
== Multidomainfähigkeit ==&lt;br /&gt;
&lt;br /&gt;
Seit Mailman 2.x kann eine Mailman-Installation unter gewissen Einschränkungen für mehrere Domains verwendet werden. Hier soll kurz gezeigt werden, was geht und wie es geht.&lt;br /&gt;
&lt;br /&gt;
=== Anleitung ===&lt;br /&gt;
&lt;br /&gt;
Logischerweise muss das Webfrontend (die CGIs) auf allen Domains installiert werden.&lt;br /&gt;
&lt;br /&gt;
Wenn man nun Mailinglisten mit newlist neu anlegt, muss man den Hostnamen für das Webfontend mit angeben, und zwar so:&lt;br /&gt;
&lt;br /&gt;
 ~$ mailman/bin/newlist listenname@listen.example.com&lt;br /&gt;
&lt;br /&gt;
Es ist ggf. wichtig, dass in der mm_cfg.py eine entsprechende add_virtualhost-Direktive für www.example.com steht, die der Frontend-URL einen Host-Part für die Mailadressen zuordnet. Ist eine solche Direktive nicht vorhanden, so wird listen.example.com sowohl als URL für das Webfrontend wie auch als Hostpart für E-Mailadressen verwendet. (Was für separate aufgeschaltete Domains wie z.B. listen.example.com gerade zutrifft.)&lt;br /&gt;
&lt;br /&gt;
Liegt das Frondend nicht auf der Maildomain ist es wichtig, dass ihr Mailman sagt, für welches die zugehörige Maildomain ist. Dies tut ihr in der Datei ~/mailman/Mailman/mm_cfg.py:&lt;br /&gt;
&lt;br /&gt;
Also z.B.&lt;br /&gt;
 DEFAULT_URL_HOST = &#039;www.example.com&#039;&lt;br /&gt;
 DEFAULT_EMAIL_HOST = &#039;listen.example.com&#039;&lt;br /&gt;
 add_virtualhost(DEFAULT_URL_HOST,DEFAULT_EMAIL_HOST)&lt;br /&gt;
&lt;br /&gt;
und&lt;br /&gt;
 add_virtualhost(&#039;www.zoopnet.de&#039;, &#039;lists.zoopnet.de&#039;)&lt;br /&gt;
&lt;br /&gt;
Das bedeutet, dass Mailman per default davon ausgeht, dass alle Listen für die Domain example.com sind.&lt;br /&gt;
Alle weiteren add_virtualhost-Direktiven ordnen einem Hostnamen für das Webfrontend (z.B. www.zoopnet.de) einen Hostpart für die Adresse der Mailinglisten (z.B. lists.zoopnet.de) zu.&lt;br /&gt;
&lt;br /&gt;
Tip von Raimund Specht: Lässt man den zweiten Parameter weg, also schreibt z.B. add_virtualhost(&#039;www.example.org&#039;), dann benutzt Mailman als Hostpart alles was nach dem ersten Punkt steht, hier also example.org als Maildomain.&lt;br /&gt;
 &lt;br /&gt;
&lt;br /&gt;
Prinzipiell war&#039;s das. Man muss die Listeneinträge natürlich immer in die richtige virtusertable eintragen, und für gleichnamige Mailinglisten auf verschiedenen Domains (mailman@*) verschidene +Ergänzungen bzw. aliase verwenden. :)&lt;br /&gt;
&lt;br /&gt;
=== Probleme ===&lt;br /&gt;
&lt;br /&gt;
Verschiedene Listen mit gleichem Namen (also z.B. liste@example1.com und liste@example2.com) sind mit Mailman 2.1 leider nicht möglich.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Tips und Tricks ==&lt;br /&gt;
&lt;br /&gt;
=== URL Änderungen ===&lt;br /&gt;
Nach URL Änderungen stimmen Links im Web-Interface nicht mehr und Listen werden nicht mehr angezeigt.&lt;br /&gt;
Es sind dann, zusätzlich zur Anpassung der mm_cfg.py, schon bestehende Listen und Archive mit folgendem Befehl zu aktualisieren:&lt;br /&gt;
 ~/mailman/bin/withlist -l -r fix_url &amp;lt;Listen_Name&amp;gt; -v -u &amp;lt;Neue_Url&amp;gt;&lt;br /&gt;
&amp;lt;Listen_Name&amp;gt; steht für die Mailingliste, die bearbeitet werden soll. &amp;lt;Neue_Url&amp;gt; für die neue URL/Webadresse des Webinterfaces.&lt;br /&gt;
&lt;br /&gt;
=== Weitere Cron-Jobs zur Mailinglisten Verwaltung ===&lt;br /&gt;
&lt;br /&gt;
Folgende Cronjobs helfen bei der Verwaltung und sind User freundlich:&lt;br /&gt;
&lt;br /&gt;
&amp;lt; In Arbeit &amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Referenzen ==&lt;br /&gt;
&lt;br /&gt;
Lösung zur installation als Domainadmin (xyz00-listen) statt Paketadmin (xyz00): https://lists.hostsharing.net/archiv/support/2009-June/019414.html&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Ältere Anleitung für Installation als Domain-Admin (xyz00-listen): &amp;lt;http://lists.hostsharing.net/archiv/support/2005-January/012426.html&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;quot;Kleine Tools&amp;quot; auf http://hs.andreasloesch.de/, wobei das &#039;pac-mm-install&#039; wahrscheinlich nicht aktuell (genug) ist&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
[[Kategorie:HSDoku]]&lt;br /&gt;
[[Kategorie:Installationsanleitungen]]&lt;br /&gt;
[[Kategorie:Software]]&lt;br /&gt;
[[Kategorie:Mailinglisten]]&lt;br /&gt;
[[Kategorie:E-Mail]]&lt;/div&gt;</summary>
		<author><name>Apc00-tony</name></author>
	</entry>
	<entry>
		<id>https://wiki.hostsharing.net/index.php?title=Mailman_Installieren&amp;diff=5225</id>
		<title>Mailman Installieren</title>
		<link rel="alternate" type="text/html" href="https://wiki.hostsharing.net/index.php?title=Mailman_Installieren&amp;diff=5225"/>
		<updated>2020-05-14T16:29:45Z</updated>

		<summary type="html">&lt;p&gt;Apc00-tony: /* E-Mail Adressen bei Mailman einrichten */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Vorab: Die Wahl von Mailman 2 ==&lt;br /&gt;
&lt;br /&gt;
Mailman 2 hängt von Python 2.7 ab und wird damit voraussichtlich nur noch eine begrenzte Nutzungsdauer haben. Mailman 3 ist jetzt verfügbar (siehe [[Mailman_3_installieren]]), aber deutlich schwerer und komplexer im Betrieb. Es gibt auch weniger leistungsfähige Software, um E-Mail-Verteiler zu betreiben, wie beispielsweise [[mlmmj]]. Für eine Diskussion der Situation im Oktober 2019, siehe das HS-Support-Archiv ab [https://lists.hostsharing.net/archiv/support/2019-October/067243.html hier.]&lt;br /&gt;
&lt;br /&gt;
== Mailman 2 installieren == &lt;br /&gt;
&lt;br /&gt;
(zuletzt getestet mit mailman-2.1.29; Installation durch Paketuser)&lt;br /&gt;
&lt;br /&gt;
Vielen Dank an alle Benutzer, die Verbesserungen beisteuern!&lt;br /&gt;
&lt;br /&gt;
=== Unter welchem Account installieren? ===&lt;br /&gt;
&lt;br /&gt;
Mailman kann vom Paketadmin (beipsielsweise &amp;quot;xyz00&amp;quot;) oder von einem Paketuser (bspw. &amp;quot;xyz00-listen&amp;quot;) installiert werden. Letzteres ist dringend empfohlen, denn wenn Mailman vom Paketadmin installiert wird, haben ausnahmslos alle Paketuser direkten Zugriff auf die Mailman-Daten, und bei Sicherheitslücken in Mailman wäre eventuell eine Rechte-Eskalierung auf Paketadmin-Ebene potentiell zu befürchten.&lt;br /&gt;
&lt;br /&gt;
Dem Paketuser, unter dem Mailman installiert wird, können mehrere Subdomains aufschaltet werden, und Mailinglisten können auch die Domainnamen verwenden, die anderen Paketusern gehören.&lt;br /&gt;
&lt;br /&gt;
Vorteil der Installation als Paketuser ist, dass nur dieser direkten Zugriff auf die Mailmandaten hat und mailman ohne Paketadminrechte läuft. Während der Emailauslieferung gelten (wie immer bei der Mailweiterleitung durch .forward-Dateien oder durch procmail) die Rechte des Paketusers, dem die Mailman-Installation gehört.&lt;br /&gt;
&lt;br /&gt;
Nachteil der Installation als Paketuser ist lediglich, dass die Paketdomain mit dem SSL Zertifikat von Hostsharing nicht genutzt werden kann.&amp;lt;!-- Aktualisieren? --&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Einen User und eine Domain anlegen ===&lt;br /&gt;
&lt;br /&gt;
Unter admin.hostsharing.net als xyz00 anmelden; den User xyz00-listen erzeugen; die Domain listen.example.com mit &amp;quot;Domain-User&amp;quot; xyz00-listen anlegen. Aus admin.hostsharing.net abmelden.&lt;br /&gt;
&lt;br /&gt;
Mit [[Login_mit_SSH|SSH]] an hostsharing.net als xyz00-listen anmelden. Die Redirect-Zeile aus ~/doms/listen.example.com/htdocs-ssl/.htaccess löschen:&lt;br /&gt;
&lt;br /&gt;
 ~$ echo &amp;quot;&amp;quot; &amp;gt; ~/doms/listen.example.com/htdocs-ssl/.htaccess&lt;br /&gt;
&lt;br /&gt;
Die Default-Subdomains www.* löschen:&lt;br /&gt;
&lt;br /&gt;
   ~$ rm -r doms/listen.example.com/subs/www/&lt;br /&gt;
   ~$ rm -r doms/listen.example.com/subs-ssl/www/&lt;br /&gt;
&lt;br /&gt;
=== Sourcen besorgen und entpacken ===&lt;br /&gt;
&lt;br /&gt;
Unter http://www.gnu.org/software/mailman/ die aktuelle Software besorgen. Dort findet sich ein Link zu den 2er-Versionen von Mailman (http://ftp.gnu.org/gnu/mailman/). Die letzte Version downloaden ...&lt;br /&gt;
&lt;br /&gt;
 ~$ wget http://ftp.gnu.org/gnu/mailman/mailman-2.1.29.tgz&lt;br /&gt;
&lt;br /&gt;
... und entpacken:&lt;br /&gt;
&lt;br /&gt;
 ~$ tar -xzvf mailman-2.1.29.tgz&lt;br /&gt;
&lt;br /&gt;
Ab diesem Augenblick gibt es ein Verzeichnis namens mailman-2.1.29/. Darin liegt die nunmehr entpackte &#039;&#039;Quellcode&#039;&#039; der Mailman-Software. Nach dem Kompilieren (folgt unten) wird die fertig kompilierte, gebrauchsfähige Mailman-Software in dem zusätzlich vorhandenen Verzeichnis mailman/ liegen. (Dieses Verzeichnis wird beim Konfigurieren der Source als &amp;quot;prefix&amp;quot; angegeben.)&lt;br /&gt;
&lt;br /&gt;
=== var-Verzeichnis für Log-Dateien anlegen ===&lt;br /&gt;
&lt;br /&gt;
Bei der Installation als Paketuser (xyz00-listen):&lt;br /&gt;
 ~$ cd &amp;amp;&amp;amp; mkdir -p mailman/var&lt;br /&gt;
 ~$ chmod 02775 mailman/var&lt;br /&gt;
&lt;br /&gt;
Bei der Installation als Paketadmin (xyz00):&lt;br /&gt;
 ~$ cd &amp;amp;&amp;amp; mkdir var/mailman&lt;br /&gt;
 ~$ chmod 02775 var/mailman&lt;br /&gt;
&lt;br /&gt;
=== Mailman konfigurieren ===&lt;br /&gt;
&lt;br /&gt;
In das Source-Verzeichnis wechseln:&lt;br /&gt;
&lt;br /&gt;
 ~$ cd mailman-2.1.29&lt;br /&gt;
&lt;br /&gt;
Bei der Installation als Paketuser (xyz00-listen):&lt;br /&gt;
      ~/mailman-2.1.29$ ./configure --prefix=/home/pacs/xyz00/users/listen/mailman \&lt;br /&gt;
              --with-username=xyz00-listen \&lt;br /&gt;
              --with-groupname=xyz00 \&lt;br /&gt;
              --with-var-prefix=/home/pacs/xyz00/users/listen/mailman/var \&lt;br /&gt;
              --with-cgi-gid=xyz00 \&lt;br /&gt;
              --with-mail-gid=xyz00&lt;br /&gt;
&lt;br /&gt;
Bei der Installation als Paketadmin (xyz00):&lt;br /&gt;
      ~/mailman-2.1.29$ ./configure --prefix=/home/pacs/xyz00/mailman \&lt;br /&gt;
              --with-username=xyz00 \&lt;br /&gt;
              --with-groupname=xyz00 \&lt;br /&gt;
              --with-var-prefix=/home/pacs/xyz00/var/mailman \&lt;br /&gt;
              --with-cgi-gid=xyz00 \&lt;br /&gt;
              --with-mail-gid=nogroup&lt;br /&gt;
&lt;br /&gt;
(Die Rückwärtsschrägstriche &amp;quot;\&amp;quot; am Zeilenende bedeuten, dass der Befehl in der nächsten Zeile weitergeht. Alternativ können alle Argumente in eine Zeile getippt werden.)&lt;br /&gt;
&lt;br /&gt;
=== Mailman kompilieren ===&lt;br /&gt;
&lt;br /&gt;
 ~/mailman-2.1.29$ make&lt;br /&gt;
 ~/mailman-2.1.29$ make install&lt;br /&gt;
&lt;br /&gt;
=== Datenrechte prüfen ===&lt;br /&gt;
&lt;br /&gt;
Sicherheitshalber die Dateirechte durch Mailmans mitgeliefertes Tool prüfen und ggf. korrigieren lassen:&lt;br /&gt;
&lt;br /&gt;
 ~/mailman-2.1.29$ cd ..      &lt;br /&gt;
 ~$ mailman/bin/check_perms -f&lt;br /&gt;
&lt;br /&gt;
== Die neue Mailman-Installation konfigurieren ==&lt;br /&gt;
&lt;br /&gt;
=== Konfigurationsdatei mm_cfg.py editieren ===&lt;br /&gt;
&lt;br /&gt;
 ~$ nano mailman/Mailman/mm_cfg.py&lt;br /&gt;
      &lt;br /&gt;
Eine Beispielkonfiguration für listen.example.com könnte so aussehen:&lt;br /&gt;
&lt;br /&gt;
 [...]&lt;br /&gt;
      ##################################################&lt;br /&gt;
      # Put YOUR site-specific settings below this line.&lt;br /&gt;
      # -*- python -*-&lt;br /&gt;
 &lt;br /&gt;
      DEFAULT_HOST_NAME = &#039;listen.example.com&#039;&lt;br /&gt;
      DEFAULT_EMAIL_HOST = &#039;listen.example.com&#039;&lt;br /&gt;
      DEFAULT_URL_HOST = &#039;listen.example.com&#039;&lt;br /&gt;
      add_virtualhost(DEFAULT_URL_HOST, DEFAULT_EMAIL_HOST)&lt;br /&gt;
      add_virtualhost(zweite.listendomain.com, zweite.listendomain.com)&lt;br /&gt;
 &lt;br /&gt;
      DEFAULT_SERVER_LANGUAGE = &#039;de&#039;&lt;br /&gt;
 &lt;br /&gt;
      DEFAULT_URL_PATTERN = &#039;http://%s/&#039;&lt;br /&gt;
  &lt;br /&gt;
      # Es wird der HS Mailversand für Bulkmail verwendet:&lt;br /&gt;
      SMTPHOST = &#039;localhost&#039;&lt;br /&gt;
      SMTPPORT = 4587 &lt;br /&gt;
      SMTP_AUTH = True&lt;br /&gt;
      SMTP_USER = &#039;xyz00-listen&#039;&lt;br /&gt;
      SMTP_PASSWD = &#039;das-passwort-des-o.-g.-users&#039;&lt;br /&gt;
      SMTP_USE_TLS = True&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
In ~/mailman/Mailman/Defaults.py sieht man, was in mm_cfg.py alles angepasst werden kann.&lt;br /&gt;
&lt;br /&gt;
=== CGI-Programme in die Domain kopieren ===&lt;br /&gt;
&lt;br /&gt;
Bei der Installation als Paketuser (xyz00-listen):&lt;br /&gt;
&lt;br /&gt;
Die fertig kompilierten CGIs von Mailman müssen in das CGI-Verzeichnis der Domain (oder der Domains), auf der das Webfrontend von Mailman laufen soll, kopiert werden. Symbolische Links sind nicht ausreichend.&lt;br /&gt;
&lt;br /&gt;
 ~$ mkdir ~/doms/listen.example.com/cgi-ssl/mailman&lt;br /&gt;
 ~$ cp mailman/cgi-bin/* doms/listen.example.com/cgi-ssl/mailman/&lt;br /&gt;
&lt;br /&gt;
 Zusätzlich muss das sticky-Flag von den kopierten Dateien entfernt werden:&lt;br /&gt;
&lt;br /&gt;
 ~$ chmod g-s ~/doms/listen.example.com/cgi/mailman/*&lt;br /&gt;
&lt;br /&gt;
Bei der Installation als Paketadmin (xyz00): &lt;br /&gt;
&lt;br /&gt;
Die CGI-Programme können im Mailman-Verzeichnis bleiben. Im CGI-Verzeichnis von jeder Domain, auf der das Mailman-Webfrontend laufen soll, werden symbolische Links dazu erstellt: &lt;br /&gt;
&lt;br /&gt;
 ~$ cd doms/listen.example.com/cgi-ssl&lt;br /&gt;
 ~/doms/listen.example.com/cgi-ssl$ ln -s ../../../mailman/cgi-bin mailman&lt;br /&gt;
&lt;br /&gt;
===  Mailman-Icons in die Domains kopieren ===&lt;br /&gt;
&lt;br /&gt;
Die Icons können wahlweise verlinkt oder kopiert werden:&lt;br /&gt;
&lt;br /&gt;
 ~$ cd doms/listen.example.com/htdocs-ssl&lt;br /&gt;
 ~/doms/listen.example.com/htdocs-ssl$ ln -s ../../../mailman/icons&lt;br /&gt;
&lt;br /&gt;
oder&lt;br /&gt;
&lt;br /&gt;
 ~$ cp -R mailman/icons doms/listen.example.com/htdocs-ssl/&lt;br /&gt;
&lt;br /&gt;
=== Die Datei .htaccess bearbeiten ===&lt;br /&gt;
&lt;br /&gt;
Bei einer dedizierten Mailman-Domain sollte man dafür sorgen, dass Mailman nicht nur unter https://listen.example.com/cgi-bin/mailman, sondern auch unter https://listen.example.com  erreichbar ist.&lt;br /&gt;
&lt;br /&gt;
Dazu werden in ~/doms/listen.example.com/htdocs-ssl/.htaccess folgende Rewrite-Anweisungen eintragen.&lt;br /&gt;
&lt;br /&gt;
 RewriteEngine On&lt;br /&gt;
 RewriteCond	%{REQUEST_URI}		!^/icons/&lt;br /&gt;
 RewriteRule	^(.*)$			/cgi-bin/mailman/$1&lt;br /&gt;
 RewriteRule	^/cgi-bin/mailman/$	/cgi-bin/mailman/listinfo&lt;br /&gt;
&lt;br /&gt;
Beachte dabei die zweite Zeile: Anfragen für Icons sollen &#039;&#039;nicht&#039;&#039; umgeschrieben werden.&lt;br /&gt;
&lt;br /&gt;
Wenn Mailman z.B. auf einer als Unterverzeichnis angelegten Subdomain läuft und unter https://www.example.com/mailman statt https://www.example.com/cgi-bin/mailman erreichbar sein soll, hilft folgendes in der ~/doms/example.com/subs-ssl/www/.htaccess:&lt;br /&gt;
&lt;br /&gt;
 RewriteEngine On&lt;br /&gt;
 RewriteCond	%{REQUEST_URI}		!^/icons/&lt;br /&gt;
 RewriteRule    ^mailman/(.*)$          /cgi-bin/mailman/$1&lt;br /&gt;
 RewriteRule    ^/cgi-bin/mailman/$	/cgi-bin/mailman/listinfo&lt;br /&gt;
&lt;br /&gt;
(In diesem Fall kann die Zeile DEFAULT_URL_PATTERN... in der mm_cfg.py auskommentiert werden.)&lt;br /&gt;
&lt;br /&gt;
=== Hauptpasswort setzen ===&lt;br /&gt;
&lt;br /&gt;
Das &amp;quot;site password&amp;quot; ist in Mailman eine Art Generalschlüssel: es wird neben dem jeweiligen Admin- oder Moderator-Passwort überall in der Weboberfläche für sämtliche Mailing-Listen akzeptiert. Also vorsichtig wählen! Das &amp;quot;site password&amp;quot; einrichten mit dem Befehl: &lt;br /&gt;
&lt;br /&gt;
 ~$ mailman/bin/mmsitepass&lt;br /&gt;
&lt;br /&gt;
=== Cronjobs einrichten ===&lt;br /&gt;
&lt;br /&gt;
In die [[Cron |Crontab]] werden Befehle eingetragen, um die Mail-Warteschlange abzuarbeiten, Logs zu löschen, usw.:&lt;br /&gt;
&lt;br /&gt;
 # Warteschlange jede Minute bearbeiten:&lt;br /&gt;
 * * * * *	~/mailman/bin/qrunner -o -r All&lt;br /&gt;
 # Verarbeitungslogs in der 47ten Minute jeder Stunde löschen:&lt;br /&gt;
 47 * * * *	rm -f ~/var/mailman/logs/qrunner&lt;br /&gt;
&lt;br /&gt;
Damit übernimmt cron die Funktion des qrunner-Dämons, der normalerweise auf einem Mailman-Server laufen sollte.&lt;br /&gt;
&lt;br /&gt;
Das Logfile wird stündlich gelöscht, da es sonst sehr schnell sehr groß wird. Falls Mailman von einem Paketuser (bspw. &amp;quot;xyz00-listen&amp;quot;) installiert wurde, sollte die letzte Zeile im Beispiel oben so lauten:&lt;br /&gt;
&lt;br /&gt;
 47 * * * * rm -f ~/mailman/var/logs/qrunner&lt;br /&gt;
&lt;br /&gt;
... entsprechend dem beim Konfigurieren angegebenen var-Verzeichnis, siehe oben.&lt;br /&gt;
&lt;br /&gt;
Zudem müssen noch die von Mailman ohnehin vorgesehenen cron-Aufträge aus ~/mailman/cron/crontab.in dem crontab des Users angehängt werden:&lt;br /&gt;
&lt;br /&gt;
 crontab -l &amp;gt; mycronjobs.tmp&lt;br /&gt;
 cat ~/mailman/cron/crontab.in &amp;gt;&amp;gt; mycronjobs.tmp&lt;br /&gt;
 crontab mycronjobs.tmp&lt;br /&gt;
&lt;br /&gt;
== Mailinglisten einrichten ==&lt;br /&gt;
&lt;br /&gt;
Jetzt läuft die Software; nun können die eigentlichen Verteiler angelegt werden. Als erster &#039;&#039;&#039;muß&#039;&#039;&#039; ein Hauptverteiler (&amp;quot;site list&amp;quot;) eingerichtet werden. Dieser Verteiler dient u.a. als Absender der Paßwort-Erinnerungen an die Abonnenten aller Mailinglisten. Er hat standardmäßig den Namen &amp;quot;mailman&amp;quot;. Falls ein anderer Name verwendet werden soll, muß dieser mit der Anweisung &lt;br /&gt;
&lt;br /&gt;
 MAILMAN_SITE_LIST = &#039;sitelistname&#039;&lt;br /&gt;
&lt;br /&gt;
in der Konfigurationsdatei mailman/Mailman/mm_cfg.py eingetragen werden.&lt;br /&gt;
&lt;br /&gt;
=== Den Hauptverteiler &amp;quot;mailman&amp;quot; anlegen ===&lt;br /&gt;
&lt;br /&gt;
Die &amp;quot;site list&amp;quot; mit dem Namen &amp;quot;mailman&amp;quot; ist die Mailingliste der lokalen Mailman-Administratoren. Sie wird zur einwandfreien Funktion von Mailman benötigt.&lt;br /&gt;
&lt;br /&gt;
Mit dem Mailman-Befehl newlist den Verteiler anlegen:&lt;br /&gt;
&lt;br /&gt;
 ~$ mailman/bin/newlist mailman&lt;br /&gt;
 Enter the email of the person running the list: admin@xyz00.hostsharing.net&lt;br /&gt;
 Initial mailman password:&lt;br /&gt;
&lt;br /&gt;
(Der Befehl newlist kann – alternativ zur Weboberfläche – später benutzt werden, um gewöhnliche Mailinglisten anzulegen.)&lt;br /&gt;
&lt;br /&gt;
Nur dieses eine Mal für die &amp;quot;site list&amp;quot; müssen wir die Konfigurationsvorgaben laden. (Gewöhnliche Mailinglisten werden später über die Weboberfläche konfiguriert.)&lt;br /&gt;
&lt;br /&gt;
Falls mailman vom Paketuser (bspw. &amp;quot;xyz00-listen&amp;quot;) installiert wurde:&lt;br /&gt;
&lt;br /&gt;
 ~$ mailman/bin/config_list -i ~/mailman/var/data/sitelist.cfg mailman&lt;br /&gt;
&lt;br /&gt;
Falls mailman vom Paketadmin (&amp;quot;xyz00&amp;quot;) installiert wurde:&lt;br /&gt;
&lt;br /&gt;
 ~$ mailman/bin/config_list -i ~/var/mailman/data/sitelist.cfg mailman&lt;br /&gt;
&lt;br /&gt;
Diese Konfigurationsdatei soll &#039;&#039;&#039;nicht&#039;&#039;&#039; auf gewöhnliche Mailinglisten anwendet werden.&lt;br /&gt;
&lt;br /&gt;
=== E-Mail Adressen bei Mailman einrichten ===&lt;br /&gt;
&lt;br /&gt;
Sobald ein neuer Verteiler angelegt worden ist, sendet Mailman eine E-Mail an den dabei eingetragenen Listenadministrator. Diese E-Mail enthält die Anweisung, E-Mail-Aliases für den neuen Verteiler und für die verschiedenen Mailman-Funktionen anzulegen. Bei Hostsharing wird die Zustellung von E-Mails an Mailman anders geregelt: alle E-Mails an Mailman werden an erweiterte &#039;&#039;E-Mail-Adressen&#039;&#039; des Mailman-Users xyz00-listen geschickt. Diese Adressen haben die form xyz00-listen&#039;&#039;&#039;+&#039;&#039;&#039;&amp;lt;liste&amp;gt;[_funktion]. E-Mails an diese Adressen werden dann durch Pipe-Anweisungen in &#039;&#039;.forward-Dateien&#039;&#039; im Home-Verzeichnis des Mailman-Users mit den entsprechenden Argumenten an Mailman übergeben. &lt;br /&gt;
&lt;br /&gt;
Falls Mailman von einem Paketuser (bspw. &amp;quot;xyz00-listen&amp;quot;) installiert wurde, werden  &#039;&#039;E-Mail-Adressen&#039;&#039; durch [https://doc.hostsharing.net/users/administration/hsadmin/index.html hsadmin (bzw. das Befehlszeilentool hsscript)] eingerichtet; die &#039;&#039;.forward-Dateien&#039;&#039; werden durch [[Login_mit_SSH|Shell-Befehle]] angelegt.&lt;br /&gt;
&lt;br /&gt;
Das folgende Beispiel zeigt die Befehle, mit denen in einer interaktiven hsscript-Sitzung die E-Mail-Adressen für die Hauptliste &amp;quot;mailman&amp;quot; eingerichtet werden. (Für spätere Mailinglisten wird in den Argumenten &amp;quot;mailman&amp;quot; durch den Namen der Mailingliste ersetzt.)&lt;br /&gt;
&lt;br /&gt;
   hsscript -u xyz00 -i&lt;br /&gt;
   [hsscript verlangt die Eingabe des Passworts vom Paketadmin xyz00; dann können diese Befehle eingegeben werden:]&lt;br /&gt;
   emailaddress.add ({set:{domain:&#039;listen.example.com&#039;,localpart:&#039;mailman&#039;,target:&#039;xyz00-listen+mailman&#039;}})&lt;br /&gt;
   emailaddress.add ({set:{domain:&#039;listen.example.com&#039;,localpart:&#039;mailman-admin&#039;,target:&#039;xyz00-listen+mailman-admin&#039;}})&lt;br /&gt;
   emailaddress.add ({set:{domain:&#039;listen.example.com&#039;,localpart:&#039;mailman-bounces&#039;,target:&#039;xyz00-listen+mailman-bounces&#039;}})&lt;br /&gt;
   emailaddress.add ({set:{domain:&#039;listen.example.com&#039;,localpart:&#039;mailman-confirm&#039;,target:&#039;xyz00-listen+mailman-confirm&#039;}})&lt;br /&gt;
   emailaddress.add ({set:{domain:&#039;listen.example.com&#039;,localpart:&#039;mailman-join&#039;,target:&#039;xyz00-listen+mailman-join&#039;}})&lt;br /&gt;
   emailaddress.add ({set:{domain:&#039;listen.example.com&#039;,localpart:&#039;mailman-leave&#039;,target:&#039;xyz00-listen+mailman-leave&#039;}})&lt;br /&gt;
   emailaddress.add ({set:{domain:&#039;listen.example.com&#039;,localpart:&#039;mailman-owner&#039;,target:&#039;xyz00-listen+mailman-owner&#039;}})&lt;br /&gt;
   emailaddress.add ({set:{domain:&#039;listen.example.com&#039;,localpart:&#039;mailman-request&#039;,target:&#039;xyz00-listen+mailman-request&#039;}})&lt;br /&gt;
   emailaddress.add ({set:{domain:&#039;listen.example.com&#039;,localpart:&#039;mailman-subscribe&#039;,target:&#039;xyz00-listen+mailman-subscribe&#039;}})&lt;br /&gt;
   emailaddress.add ({set:{domain:&#039;listen.example.com&#039;,localpart:&#039;mailman-unsubscribe&#039;,target:&#039;xyz00-listen+mailman-unsubscribe&#039;}})&lt;br /&gt;
&lt;br /&gt;
Die korrekte Einrichtung der E-Mail-Adressen kann in der Web-Oberfläche von hsadmin kontrolliert werden.&lt;br /&gt;
&lt;br /&gt;
Für jede der soeben eingerichteten Adressen wird nun eine .forward-Datei im Homeverzeichnis des Users xyz00-listen angelegt. Die Dateinamen bestehen aus der Zeichenfolge &amp;quot;.forward+&amp;quot; gefolgt vom Namen der ausführen soll. Der Inhalt der jeweiligen .forward-Datei legt die Weiterleitung der Mail durch einen Pipe an Mailman fest, mit dem jeweiligen Befehl als Argument:&lt;br /&gt;
&lt;br /&gt;
   &amp;quot;|/home/pacs/xyz00/users/listen/mailman/mail/mailman [Befehl] [Listenname]&amp;quot;&lt;br /&gt;
&lt;br /&gt;
Zum Beispiel wird die .forward-Datei .forward+mailman-subscribe verwendet, wenn eine E-Mail an die Adresse mailman-subscribe@listen.example.com eingeht. Aufgrund der oben eingerichteten E-Mail-Adresse mit dem Ziel &amp;quot;xyz00-listen+mailman-subscribe&amp;quot; wertet der Mail-Transfer-Agent die .forward-Datei .forward+mailman-subscribe im Home-Verzeichnis des Users xyz00-listen aus, und entsprechend ihrem Inhalt wird die Mail an die Mailman-Software mit den Argumenten &amp;quot;subscribe mailman&amp;quot; übergeben.&lt;br /&gt;
&lt;br /&gt;
Das folgende Beispiel zeigt die Befehle, mit denen an der Befehlszeilenaufforderung der Shell die .forward-Dateien für die Hauptliste &amp;quot;mailman&amp;quot; eingerichtet werden. (Für spätere Mailinglisten wird in den Argumenten und in den Namen der .forward-Dateien &amp;quot;mailman&amp;quot; durch den Namen der Mailingliste ersetzt, jedoch &#039;&#039;&#039;nicht&#039;&#039;&#039; in der Pfadangabe zum Mailman-Programm selbst; diese ändert sich ja nicht.)&lt;br /&gt;
&lt;br /&gt;
 echo &#039;admin@xyz00.hostsharing.net&#039; &amp;gt; .forward # Weiterleitung von cron Fehlern etc an Paketadmin.&lt;br /&gt;
 echo &#039;&amp;quot;|/home/pacs/xyz00/users/listen/mailman/mail/mailman post mailman&amp;quot;&#039; &amp;gt; .forward+mailman&lt;br /&gt;
 echo &#039;&amp;quot;|/home/pacs/xyz00/users/listen/mailman/mail/mailman admin mailman&amp;quot;&#039; &amp;gt; .forward+mailman-admin&lt;br /&gt;
 echo &#039;&amp;quot;|/home/pacs/xyz00/users/listen/mailman/mail/mailman bounces mailman&amp;quot;&#039; &amp;gt; .forward+mailman-bounces&lt;br /&gt;
 echo &#039;&amp;quot;|/home/pacs/xyz00/users/listen/mailman/mail/mailman confirm mailman&amp;quot;&#039; &amp;gt; .forward+mailman-confirm&lt;br /&gt;
 echo &#039;&amp;quot;|/home/pacs/xyz00/users/listen/mailman/mail/mailman join mailman&amp;quot;&#039; &amp;gt; .forward+mailman-join&lt;br /&gt;
 echo &#039;&amp;quot;|/home/pacs/xyz00/users/listen/mailman/mail/mailman leave mailman&amp;quot;&#039; &amp;gt; .forward+mailman-leave&lt;br /&gt;
 echo &#039;&amp;quot;|/home/pacs/xyz00/users/listen/mailman/mail/mailman owner mailman&amp;quot;&#039; &amp;gt; .forward+mailman-owner&lt;br /&gt;
 echo &#039;&amp;quot;|/home/pacs/xyz00/users/listen/mailman/mail/mailman request mailman&amp;quot;&#039; &amp;gt; .forward+mailman-request&lt;br /&gt;
 echo &#039;&amp;quot;|/home/pacs/xyz00/users/listen/mailman/mail/mailman subscribe mailman&amp;quot;&#039; &amp;gt; .forward+mailman-subscribe&lt;br /&gt;
 echo &#039;&amp;quot;|/home/pacs/xyz00/users/listen/mailman/mail/mailman unsubscribe mailman&amp;quot;&#039; &amp;gt; .forward+mailman-unsubscribe&lt;br /&gt;
&lt;br /&gt;
Die vielen Befehle können von dieser Anleitung kopiert und nach Anpassung auf den tatsächlichen Unsernamen in die SSH-Sitzung kopiert werden. Noch leichter ist es, mit einem Editor einen Shell-Skript namens ~/bin/addforwards mit folgendem Inhalt zu erstellen:&lt;br /&gt;
&lt;br /&gt;
 #!/bin/sh&lt;br /&gt;
 # .forward-Dateien für einen Verteiler unter Mailman einrichten.&lt;br /&gt;
 #&lt;br /&gt;
 if [ &amp;quot;$1&amp;quot; = &amp;quot;&amp;quot; ] ; then&lt;br /&gt;
    echo &amp;quot;Aufruf: $0 Listenname\n&amp;quot; &lt;br /&gt;
    exit&lt;br /&gt;
 fi&lt;br /&gt;
 if [ &amp;quot;$2&amp;quot; != &amp;quot;&amp;quot; ] ; then&lt;br /&gt;
    echo &amp;quot;Aufruf: $0 Listenname\n&amp;quot; &lt;br /&gt;
    exit&lt;br /&gt;
 fi&lt;br /&gt;
 if [ &amp;quot;`pwd`&amp;quot; != &amp;quot;`echo ~`&amp;quot; ] ; then&lt;br /&gt;
    echo &amp;quot;Diesen Befehl vom Home-Verzeichnis aus aufrufen.\n&amp;quot; &lt;br /&gt;
    exit&lt;br /&gt;
 fi&lt;br /&gt;
 echo &amp;quot;\&amp;quot;|/home/pacs/xyz00/users/listen/mailman/mail/mailman post $1\&amp;quot;&amp;quot; &amp;gt; .forward+$1&lt;br /&gt;
 echo &amp;quot;\&amp;quot;|/home/pacs/xyz00/users/listen/mailman/mail/mailman admin $1\&amp;quot;&amp;quot; &amp;gt; .forward+$1-admin&lt;br /&gt;
 echo &amp;quot;\&amp;quot;|/home/pacs/xyz00/users/listen/mailman/mail/mailman bounces $1\&amp;quot;&amp;quot; &amp;gt; .forward+$1-bounces&lt;br /&gt;
 echo &amp;quot;\&amp;quot;|/home/pacs/xyz00/users/listen/mailman/mail/mailman confirm $1\&amp;quot;&amp;quot; &amp;gt; .forward+$1-confirm&lt;br /&gt;
 echo &amp;quot;\&amp;quot;|/home/pacs/xyz00/users/listen/mailman/mail/mailman join $1\&amp;quot;&amp;quot; &amp;gt; .forward+$1-join&lt;br /&gt;
 echo &amp;quot;\&amp;quot;|/home/pacs/xyz00/users/listen/mailman/mail/mailman leave $1\&amp;quot;&amp;quot; &amp;gt; .forward+$1-leave&lt;br /&gt;
 echo &amp;quot;\&amp;quot;|/home/pacs/xyz00/users/listen/mailman/mail/mailman owner $1\&amp;quot;&amp;quot; &amp;gt; .forward+$1-owner&lt;br /&gt;
 echo &amp;quot;\&amp;quot;|/home/pacs/xyz00/users/listen/mailman/mail/mailman request $1\&amp;quot;&amp;quot; &amp;gt; .forward+$1-request&lt;br /&gt;
 echo &amp;quot;\&amp;quot;|/home/pacs/xyz00/users/listen/mailman/mail/mailman subscribe $1\&amp;quot;&amp;quot; &amp;gt; .forward+$1-subscribe&lt;br /&gt;
 echo &amp;quot;\&amp;quot;|/home/pacs/xyz00/users/listen/mailman/mail/mailman unsubscribe $1\&amp;quot;&amp;quot; &amp;gt; .forward+$1-unsubscribe&lt;br /&gt;
 exit&lt;br /&gt;
&lt;br /&gt;
Der Skript muß natürlich als ausführbar gekennzeichnet werden:&lt;br /&gt;
&lt;br /&gt;
  ~$ chmod u+x bin/addforwards&lt;br /&gt;
&lt;br /&gt;
Die Erweiterung dieses Skripts um die hsscript-Befehle wird dem Leser als Aufgabe überlassen.&lt;br /&gt;
&lt;br /&gt;
=== Administration ===&lt;br /&gt;
&lt;br /&gt;
Als erstes sollte man als Administrator der neuen Mailman-Installation die Liste &amp;quot;mailman&amp;quot; selbst abonnieren. Die Liste &amp;quot;mailman&amp;quot; kann aber unter https://listen.example.com/mailman/admin/mailman verwaltet werden.&lt;br /&gt;
&lt;br /&gt;
Die Hauptseite der Mailman-Web-Verwaltung ist in unserem Beispiel (mit den oben angegebenen Rewrite-Anweisungen in der Datei .htaccess) https://listen.example.com/mailman/admin/. Diese Seite enthält Links zu den bisher eingerichteten Mailinglisten (außer &amp;quot;mailman&amp;quot;) und einen Link, um neue Mailinglisten anzulegen (https://listen.example.com/mailman/create). Das Anlegen einer neuen Mailingliste geschieht entweder über diesen Link oder (wie oben) in der Shell mit dem Befehl:&lt;br /&gt;
&lt;br /&gt;
 ~$ mailman/bin/newlist &amp;lt;Listenname&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In beiden Fällen müssen zusätzlich die E-Mail-Adressen und die .forward-Dateien wie bei dem Einrichten der Liste &amp;quot;mailman&amp;quot; nach Verfahren im obigen Abschnitt angelegt werden.&lt;br /&gt;
&lt;br /&gt;
Für die Verwaltung der Mailinglisten im Alltag, d.h. den Umgang mit Bounces, Spam, Abonnenten usw., siehe u.a. die [https://wiki.list.org/ Mailman-Wiki].&lt;br /&gt;
&lt;br /&gt;
== Feintuning == &lt;br /&gt;
&lt;br /&gt;
Wer will, kann auch noch etwas Platz sparen. Die normale Mailmaninstallation schlägt mit über 20 MB zu Buche...&lt;br /&gt;
&lt;br /&gt;
Mit den folgenden Tips kann man das auf ca. 6 MB reduzieren :)&lt;br /&gt;
&lt;br /&gt;
Es kann natürlich sein, dass ich zuviel lösche, aber bei mir funktioniert&#039;s. Wenn ihr also sicher(er) sein wollt, dass euch der Mailman nicht um die Ohren fliegt, macht das nicht!&lt;br /&gt;
&lt;br /&gt;
*  ~/mailman/cgi-bin und ~/mailman/icons können gelöscht werden, falls sie an andere Stelle kopiert worden sind.&lt;br /&gt;
* Die nicht benötigten Sprachen in ~/mailman/messages löschen.&lt;br /&gt;
* Die nicht benötigten Sprachen in ~/mailman/templates löschen (bis auf englisch).&lt;br /&gt;
* ~/mailman/tests kann, soweit ich das sehe, komplett gelöscht werden.&lt;br /&gt;
* Falls man koreanisch und japanisch nicht braucht, kann man folgendes machen:&lt;br /&gt;
* in ~/mailman/bin/paths.py, ~/mailman/cron/paths.py und ~/mailman/scripts/paths.py die Zeilen:&lt;br /&gt;
&lt;br /&gt;
 # In a normal interactive Python environment, the japanese.pth and korean.pth&lt;br /&gt;
 # files would be imported automatically.  But because we inhibit the importing&lt;br /&gt;
 # of the site module, we need to be explicit about importing these codecs.&lt;br /&gt;
 if not jaok:&lt;br /&gt;
     import japanese&lt;br /&gt;
 # As of KoreanCodecs 2.0.5, you had to do the second import to get the Korean&lt;br /&gt;
 # codecs installed, however leave the first import in there in case an upgrade&lt;br /&gt;
 # changes this.&lt;br /&gt;
 if not kook:&lt;br /&gt;
     import korean&lt;br /&gt;
     import korean.aliases&lt;br /&gt;
&lt;br /&gt;
auskommentieren.&lt;br /&gt;
&lt;br /&gt;
Dann kann man ~/mailman/pythonlib/japanese, ~/mailman/pythonlib/korean, ~/mailman/pythonlib/korean.pth sowie ~/mailman/pythonlib/lib löschen.&lt;br /&gt;
   &lt;br /&gt;
Man kann auch noch die Debug-Informationen aus den binaries strippen:&lt;br /&gt;
&lt;br /&gt;
 strip ~/mailman/mail/mailman&lt;br /&gt;
 strip ~/mailman/cgi-bin/*&lt;br /&gt;
&lt;br /&gt;
Falls die CGIs nicht gesymlinkt wurden:&lt;br /&gt;
&lt;br /&gt;
 strip ~/doms/listen.example.com/cgi/mailman/*&lt;br /&gt;
&lt;br /&gt;
== Multidomainfähigkeit ==&lt;br /&gt;
&lt;br /&gt;
Seit Mailman 2.x kann eine Mailman-Installation unter gewissen Einschränkungen für mehrere Domains verwendet werden. Hier soll kurz gezeigt werden, was geht und wie es geht.&lt;br /&gt;
&lt;br /&gt;
=== Anleitung ===&lt;br /&gt;
&lt;br /&gt;
Logischerweise muss das Webfrontend (die CGIs) auf allen Domains installiert werden.&lt;br /&gt;
&lt;br /&gt;
Wenn man nun Mailinglisten mit newlist neu anlegt, muss man den Hostnamen für das Webfontend mit angeben, und zwar so:&lt;br /&gt;
&lt;br /&gt;
 ~$ mailman/bin/newlist listenname@listen.example.com&lt;br /&gt;
&lt;br /&gt;
Es ist ggf. wichtig, dass in der mm_cfg.py eine entsprechende add_virtualhost-Direktive für www.example.com steht, die der Frontend-URL einen Host-Part für die Mailadressen zuordnet. Ist eine solche Direktive nicht vorhanden, so wird listen.example.com sowohl als URL für das Webfrontend wie auch als Hostpart für E-Mailadressen verwendet. (Was für separate aufgeschaltete Domains wie z.B. listen.example.com gerade zutrifft.)&lt;br /&gt;
&lt;br /&gt;
Liegt das Frondend nicht auf der Maildomain ist es wichtig, dass ihr Mailman sagt, für welches die zugehörige Maildomain ist. Dies tut ihr in der Datei ~/mailman/Mailman/mm_cfg.py:&lt;br /&gt;
&lt;br /&gt;
Also z.B.&lt;br /&gt;
 DEFAULT_URL_HOST = &#039;www.example.com&#039;&lt;br /&gt;
 DEFAULT_EMAIL_HOST = &#039;listen.example.com&#039;&lt;br /&gt;
 add_virtualhost(DEFAULT_URL_HOST,DEFAULT_EMAIL_HOST)&lt;br /&gt;
&lt;br /&gt;
und&lt;br /&gt;
 add_virtualhost(&#039;www.zoopnet.de&#039;, &#039;lists.zoopnet.de&#039;)&lt;br /&gt;
&lt;br /&gt;
Das bedeutet, dass Mailman per default davon ausgeht, dass alle Listen für die Domain example.com sind.&lt;br /&gt;
Alle weiteren add_virtualhost-Direktiven ordnen einem Hostnamen für das Webfrontend (z.B. www.zoopnet.de) einen Hostpart für die Adresse der Mailinglisten (z.B. lists.zoopnet.de) zu.&lt;br /&gt;
&lt;br /&gt;
Tip von Raimund Specht: Lässt man den zweiten Parameter weg, also schreibt z.B. add_virtualhost(&#039;www.example.org&#039;), dann benutzt Mailman als Hostpart alles was nach dem ersten Punkt steht, hier also example.org als Maildomain.&lt;br /&gt;
 &lt;br /&gt;
&lt;br /&gt;
Prinzipiell war&#039;s das. Man muss die Listeneinträge natürlich immer in die richtige virtusertable eintragen, und für gleichnamige Mailinglisten auf verschiedenen Domains (mailman@*) verschidene +Ergänzungen bzw. aliase verwenden. :)&lt;br /&gt;
&lt;br /&gt;
=== Probleme ===&lt;br /&gt;
&lt;br /&gt;
Verschiedene Listen mit gleichem Namen (also z.B. liste@example1.com und liste@example2.com) sind mit Mailman 2.1 leider nicht möglich.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Tips und Tricks ==&lt;br /&gt;
&lt;br /&gt;
=== URL Änderungen ===&lt;br /&gt;
Nach URL Änderungen stimmen Links im Web-Interface nicht mehr und Listen werden nicht mehr angezeigt.&lt;br /&gt;
Es sind dann, zusätzlich zur Anpassung der mm_cfg.py, schon bestehende Listen und Archive mit folgendem Befehl zu aktualisieren:&lt;br /&gt;
 ~/mailman/bin/withlist -l -r fix_url &amp;lt;Listen_Name&amp;gt; -v -u &amp;lt;Neue_Url&amp;gt;&lt;br /&gt;
&amp;lt;Listen_Name&amp;gt; steht für die Mailingliste, die bearbeitet werden soll. &amp;lt;Neue_Url&amp;gt; für die neue URL/Webadresse des Webinterfaces.&lt;br /&gt;
&lt;br /&gt;
=== Weitere Cron-Jobs zur Mailinglisten Verwaltung ===&lt;br /&gt;
&lt;br /&gt;
Folgende Cronjobs helfen bei der Verwaltung und sind User freundlich:&lt;br /&gt;
&lt;br /&gt;
&amp;lt; In Arbeit &amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Referenzen ==&lt;br /&gt;
&lt;br /&gt;
Lösung zur installation als Domainadmin (xyz00-listen) statt Paketadmin (xyz00): https://lists.hostsharing.net/archiv/support/2009-June/019414.html&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Ältere Anleitung für Installation als Domain-Admin (xyz00-listen): &amp;lt;http://lists.hostsharing.net/archiv/support/2005-January/012426.html&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;quot;Kleine Tools&amp;quot; auf http://hs.andreasloesch.de/, wobei das &#039;pac-mm-install&#039; wahrscheinlich nicht aktuell (genug) ist&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
[[Kategorie:HSDoku]]&lt;br /&gt;
[[Kategorie:Installationsanleitungen]]&lt;br /&gt;
[[Kategorie:Software]]&lt;br /&gt;
[[Kategorie:Mailinglisten]]&lt;br /&gt;
[[Kategorie:E-Mail]]&lt;/div&gt;</summary>
		<author><name>Apc00-tony</name></author>
	</entry>
	<entry>
		<id>https://wiki.hostsharing.net/index.php?title=Diskussion:Mailman_Installieren&amp;diff=5224</id>
		<title>Diskussion:Mailman Installieren</title>
		<link rel="alternate" type="text/html" href="https://wiki.hostsharing.net/index.php?title=Diskussion:Mailman_Installieren&amp;diff=5224"/>
		<updated>2020-05-14T16:00:11Z</updated>

		<summary type="html">&lt;p&gt;Apc00-tony: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Sehr schön; sauberer gegliedert als die Vorversion. &lt;br /&gt;
&lt;br /&gt;
Ein paar Vorschläge dennoch:&lt;br /&gt;
&lt;br /&gt;
&amp;quot;Mailman kann als Paketadmin oder Paketuser installiert werden.&amp;quot;&lt;br /&gt;
&lt;br /&gt;
* &amp;quot;Paket-Admin&amp;quot;, &amp;quot;Paketadmin&amp;quot;: Ich wäre dafür, wir würden überall im Wiki die Schreibweise &amp;quot;Paket-Admin&amp;quot; verwenden. Einfach als konservativer Umgang mit Wortschöpfungen. Andere Meinungen?&lt;br /&gt;
&lt;br /&gt;
* &amp;quot;Paketuser&amp;quot; ist auf der Seite [[User-Arten]] nicht definiert. Sollte es hier wohl &amp;quot;Domain-Admin&amp;quot; heißen?&lt;br /&gt;
&lt;br /&gt;
* Syntax: Strenggenommen kann Mailman nur als Softwareprogramm installiert werden, nicht als Paket-Admin oder als Domain-Admin. Alternativer Satzbau: &amp;quot;Mailman kann vom Paket-Admin oder von einem Domain-Admin installiert werden.&amp;quot; Oder: &amp;quot;Mailman kann man als Paket-Admin oder als Domain-Admin installieren.&amp;quot;&lt;br /&gt;
&lt;br /&gt;
== Verzeichnisstruktur ==&lt;br /&gt;
&lt;br /&gt;
Als Verzeichnisname fuer die Mailman Installation wird in der Anleitung teilweise &amp;quot;mailman&amp;quot; und teilweise &amp;quot;mailman-2.1.12&amp;quot; verwendet. Ist das beabsichtigt? Bin mir nicht sicher, aber ich vermute, dass es einheitlich &amp;quot;mailman-2.1.12&amp;quot; heissen sollte. Z.B.&lt;br /&gt;
&lt;br /&gt;
      ~$ mkdir -p mailman-2.1.12/var&lt;br /&gt;
      ~$ chmod 02775 mailman-2.1.12/var&lt;br /&gt;
&lt;br /&gt;
statt:&lt;br /&gt;
      ~$ mkdir -p mailman/var&lt;br /&gt;
      ~$ chmod 02775 mailman/var&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
oder:&lt;br /&gt;
&lt;br /&gt;
      ~/mailman-2.1.12$ ./configure --prefix=/home/pacs/XYZ00/mailman-2.1.12 \&lt;br /&gt;
        --with-username=XYZ00 \&lt;br /&gt;
        --with-groupname=XYZ00 \&lt;br /&gt;
        --with-var-prefix=/home/pacs/XYZ00/var/mailman-2.1.12 \&lt;br /&gt;
        --with-cgi-gid=XYZ00 \&lt;br /&gt;
        --with-mail-gid=nogroup&lt;br /&gt;
&lt;br /&gt;
satt:&lt;br /&gt;
&lt;br /&gt;
      ~/mailman-2.1.12$ ./configure --prefix=/home/pacs/XYZ00/mailman \&lt;br /&gt;
        --with-username=XYZ00 \&lt;br /&gt;
        --with-groupname=XYZ00 \&lt;br /&gt;
        --with-var-prefix=/home/pacs/XYZ00/var/mailman \&lt;br /&gt;
        --with-cgi-gid=XYZ00 \&lt;br /&gt;
        --with-mail-gid=nogroup&lt;br /&gt;
&lt;br /&gt;
: Nein, das ist Absicht. Unter &amp;quot;mailman-2.1.12&amp;quot; liegen die entpackten Sourcen, wohingegen nach &amp;quot;mailman&amp;quot; installiert wird. --[[Benutzer:Daz00-daniel|Daz00-daniel]] 13:33, 6. Okt. 2009 (CEST)&lt;br /&gt;
&lt;br /&gt;
== Don&#039;t try this at home! ==&lt;br /&gt;
&lt;br /&gt;
Also bitte nicht mehr Mailman als Paketadmin installieren und nicht mehr mittels Aliases die Mails auf Mailman pipen.&lt;br /&gt;
&lt;br /&gt;
Und nicht mehr die E-Mail-Adressen und Aliases auf diese Art einrichten:&lt;br /&gt;
&lt;br /&gt;
   hsscript -u xyz00 -i&lt;br /&gt;
   emailalias.add ({set:{name:&#039;xyz00-listname_ohne_bindestriche&#039;,target:&#039;&amp;quot;|/home/pacs/xyz00/mailman/mail/mailman post listname-bindestriche-okay&amp;quot;&#039;}})&lt;br /&gt;
   emailalias.add ({set:{name:&#039;xyz00-listname_ohne_bindestriche_admin&#039;,target:&#039;&amp;quot;|/home/pacs/xyz00/mailman/mail/mailman admin listname-bindestriche-okay&amp;quot;&#039;}})&lt;br /&gt;
   emailalias.add ({set:{name:&#039;xyz00-listname_ohne_bindestriche_bounce&#039;,target:&#039;&amp;quot;|/home/pacs/xyz00/mailman/mail/mailman bounce listname-bindestriche-okay&amp;quot;&#039;}})&lt;br /&gt;
   emailalias.add ({set:{name:&#039;xyz00-listname_ohne_bindestriche_confirm&#039;,target:&#039;&amp;quot;|/home/pacs/xyz00/mailman/mail/mailman confirm listname-bindestriche-okay&amp;quot;&#039;}})&lt;br /&gt;
   emailalias.add ({set:{name:&#039;xyz00-listname_ohne_bindestriche_join&#039;,target:&#039;&amp;quot;|/home/pacs/xyz00/mailman/mail/mailman join listname-bindestriche-okay&amp;quot;&#039;}})&lt;br /&gt;
   emailalias.add ({set:{name:&#039;xyz00-listname_ohne_bindestriche_leave&#039;,target:&#039;&amp;quot;|/home/pacs/xyz00/mailman/mail/mailman leave listname-bindestriche-okay&amp;quot;&#039;}})&lt;br /&gt;
   emailalias.add ({set:{name:&#039;xyz00-listname_ohne_bindestriche_owner&#039;,target:&#039;&amp;quot;|/home/pacs/xyz00/mailman/mail/mailman owner listname-bindestriche-okay&amp;quot;&#039;}})&lt;br /&gt;
   emailalias.add ({set:{name:&#039;xyz00-listname_ohne_bindestriche_request&#039;,target:&#039;&amp;quot;|/home/pacs/xyz00/mailman/mail/mailman request listname-bindestriche-okay&amp;quot;&#039;}})&lt;br /&gt;
   emailalias.add ({set:{name:&#039;xyz00-listname_ohne_bindestriche_subscribe&#039;,target:&#039;&amp;quot;|/home/pacs/xyz00/mailman/mail/mailman subscribe listname-bindestriche-okay&amp;quot;&#039;}})&lt;br /&gt;
   emailalias.add ({set:{name:&#039;xyz00-listname_ohne_bindestriche_unsubscribe&#039;,target:&#039;&amp;quot;|/home/pacs/xyz00/mailman/mail/mailman unsubscribe listname-bindestriche-okay&amp;quot;&#039;}})&lt;br /&gt;
   emailaddress.add ({set:{domain:&#039;lists.example.com&#039;,localpart:&#039;listname-bindestriche-okay&#039;,target:&#039;xyz00-listname_ohne_bindestriche&#039;}})&lt;br /&gt;
   emailaddress.add ({set:{domain:&#039;lists.example.com&#039;,localpart:&#039;listname-bindestriche-okay-admin&#039;,target:&#039;xyz00-listname_ohne_bindestriche_admin&#039;}})&lt;br /&gt;
   emailaddress.add ({set:{domain:&#039;lists.example.com&#039;,localpart:&#039;listname-bindestriche-okay-bounces&#039;,target:&#039;xyz00-listname_ohne_bindestriche_bounces&#039;}})&lt;br /&gt;
   emailaddress.add ({set:{domain:&#039;lists.example.com&#039;,localpart:&#039;listname-bindestriche-okay-confirm&#039;,target:&#039;xyz00-listname_ohne_bindestriche_confirm&#039;}})&lt;br /&gt;
   emailaddress.add ({set:{domain:&#039;lists.example.com&#039;,localpart:&#039;listname-bindestriche-okay-join&#039;,target:&#039;xyz00-listname_ohne_bindestriche_join&#039;}})&lt;br /&gt;
   emailaddress.add ({set:{domain:&#039;lists.example.com&#039;,localpart:&#039;listname-bindestriche-okay-leave&#039;,target:&#039;xyz00-listname_ohne_bindestriche_leave&#039;}})&lt;br /&gt;
   emailaddress.add ({set:{domain:&#039;lists.example.com&#039;,localpart:&#039;listname-bindestriche-okay-owner&#039;,target:&#039;xyz00-listname_ohne_bindestriche_owner&#039;}})&lt;br /&gt;
   emailaddress.add ({set:{domain:&#039;lists.example.com&#039;,localpart:&#039;listname-bindestriche-okay-request&#039;,target:&#039;xyz00-listname_ohne_bindestriche_request&#039;}})&lt;br /&gt;
   emailaddress.add ({set:{domain:&#039;lists.example.com&#039;,localpart:&#039;listname-bindestriche-okay-subscribe&#039;,target:&#039;xyz00-listname_ohne_bindestriche_subscribe&#039;}})&lt;br /&gt;
   emailaddress.add ({set:{domain:&#039;lists.example.com&#039;,localpart:&#039;listname-bindestriche-okay-unsubscribe&#039;,target:&#039;xyz00-listname_ohne_bindestriche_unsubscribe&#039;}})&lt;br /&gt;
&lt;br /&gt;
Und dabei nicht die doppelten Anführungszeichen bei dem Alias-Ziel beachten.&lt;br /&gt;
&lt;br /&gt;
Okay? Okay! [[Benutzer:Apc00|Tony Crawford (apc00)]] ([[Benutzer Diskussion:Apc00|Diskussion]]) 15:52, 15. Mär. 2017 (CET)&lt;br /&gt;
&lt;br /&gt;
== XYZ00 in Versalien? ==&lt;br /&gt;
&lt;br /&gt;
Wir schreiben xyz00 im ganzen Wiki klein, nur hier nicht. Das kann doch geändert werden, oder gibt es etwas, das dagegen spricht? --[[Benutzer:Deg00-m.website|ChristofT]] ([[Benutzer Diskussion:Deg00-m.website|Diskussion]]) 12:39, 2. Sep. 2017 (CEST)&lt;br /&gt;
:Ich denke: Es MUSS klein geschrieben werden, sonst kommt noch jemand auf die Idee, Paket-Nutzer oder -Verzeichnisnamen müssten gross geschrieben sein. das wäre ein Missverständnis. --[[Benutzer:Hsh00-peh|Peter]] ([[Benutzer Diskussion:Hsh00-peh|Diskussion]]) 19:38, 2. Sep. 2017 (CEST)&lt;br /&gt;
::Alles klar, habe es ersetzt --[[Benutzer:Deg00-m.website|ChristofT]] ([[Benutzer Diskussion:Deg00-m.website|Diskussion]]) 19:11, 16. Sep. 2017 (CEST)&lt;/div&gt;</summary>
		<author><name>Apc00-tony</name></author>
	</entry>
	<entry>
		<id>https://wiki.hostsharing.net/index.php?title=Benutzer:Apc00-tony/sandbox&amp;diff=5217</id>
		<title>Benutzer:Apc00-tony/sandbox</title>
		<link rel="alternate" type="text/html" href="https://wiki.hostsharing.net/index.php?title=Benutzer:Apc00-tony/sandbox&amp;diff=5217"/>
		<updated>2020-05-05T15:09:22Z</updated>

		<summary type="html">&lt;p&gt;Apc00-tony: Apc00-tony verschob die Seite Benutzer:Apc00-tony/sandbox nach Benutzer:Apc00-tony/Dynamisches DNS: Inhalt relativ ausgereift und ich will den Link einsetzen.&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;#WEITERLEITUNG [[Benutzer:Apc00-tony/Dynamisches DNS]]&lt;/div&gt;</summary>
		<author><name>Apc00-tony</name></author>
	</entry>
	<entry>
		<id>https://wiki.hostsharing.net/index.php?title=Benutzer:Apc00-tony/Dynamisches_DNS&amp;diff=5216</id>
		<title>Benutzer:Apc00-tony/Dynamisches DNS</title>
		<link rel="alternate" type="text/html" href="https://wiki.hostsharing.net/index.php?title=Benutzer:Apc00-tony/Dynamisches_DNS&amp;diff=5216"/>
		<updated>2020-05-05T15:09:21Z</updated>

		<summary type="html">&lt;p&gt;Apc00-tony: Apc00-tony verschob die Seite Benutzer:Apc00-tony/sandbox nach Benutzer:Apc00-tony/Dynamisches DNS: Inhalt relativ ausgereift und ich will den Link einsetzen.&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;((Provisorischer Vorspann: Auf Grund einer Mailing-Listen-Diskussion habe ich angefangen, Dynamisches DNS über einen CGI-Skript bei Hostsharing zu realisieren. Meine Lösung habe ich dann vorgestellt; sie wurde für nicht ausreichend selbsterklärend befunden und fand wenig Akzeptanz. Hier also der Versuch, die Sache zu dokumentieren.))&lt;br /&gt;
&lt;br /&gt;
Mit der regelmäßigen Aufnahme von benutzerspezifischen Zonefiles in seiner DNS-Konfiguration bietet  Hostsharing alles, was man braucht, um &amp;amp;bdquo;dynamisches DNS&amp;amp;ldquo; in Eigenregie zu realisieren.&lt;br /&gt;
&lt;br /&gt;
Das heißt, wenn ich mindestens eine Domain bei Hostsharing verwalte, und mindestens eine Einwahlverbindung (oder DSL-Verbindung) ins Internet mit wechselnder IP-Adresse über irgendeinen ISP für meinen Arbeitsplatzrechner zu Hause betreibe, dann kann ich dem Arbeitsplatzrechner über die DNS-Server von Hostsharing einen vollqualifizieren Domainnamen zuweisen, der der jeweiligen IP-Adresse meiner Einwahlleitung zugeordnet ist.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
(ASCII-Art-Diagramm der beschriebenen Konstellation)&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Im Folgenden wird eine real existierende Implementierung von Dynamischem DNS (&amp;amp;bdquo;DDNS&amp;amp;ldquo;) beschrieben. Die verschiedenen Elemente könnten durchaus anders realisiert werden; die beschriebene Implementierung könnte durchaus verbessert werden. Sie dient hier der Illustration.&lt;br /&gt;
&lt;br /&gt;
In der folgenden Beschreibung werden diese Beispielwerte benutzt:&lt;br /&gt;
* Ein Hostsharing-Mitglied hat ein Account als Paket-Admin mit Kennung xyz00.&lt;br /&gt;
* Im Paket xyz00 gibt es einen Domain-Admin namens xyz00-benutzername.&lt;br /&gt;
* Dieser Domain-Admin verwaltet bei Hostsharing die Domains example.com und beispiel.de.&lt;br /&gt;
* Ein Benutzer hat zu Hause (oder im Büro) einen Arbeitsplatzrechner hinter der marktüblichen DSL-Leitung, die von seinem ISP bereitgestellt wird.&lt;br /&gt;
* Dieser Arbeitsplatzrechner (oder der Router, der seine Internetverbindung steuert) bekommt vom ISP immer wechselnde IP-Adressen zugewiesen.&lt;br /&gt;
* Dennoch möchte der Benutzer seinen Arbeitsplatzrechner aus dem Internet unter dem Hostnamen einwahl.example.com ansprechen können.&lt;br /&gt;
&lt;br /&gt;
Dazu kann ein System wie Hostsharing, das authoritative DNS-Informationen für viele Domains bereitstellt, auch veränderliche DNS-Information über dynamisch verbundene Rechner verwalten &amp;amp;ndash; sofern das ressourcenschonend gemacht werden kann ohne andere Funktionen zu stören.&lt;br /&gt;
&lt;br /&gt;
== Aufgaben des Servers ==&lt;br /&gt;
&lt;br /&gt;
Um einem Rechner mit wechselnder IP-Adresse einen DDNS-Eintrag zu bieten, muß der Hostsharing-Server folgendes leisten (in ungefährer Reihenfolge der Ereignisse):&lt;br /&gt;
&lt;br /&gt;
# Eine Anfrage entgegennehmen, beispielsweise über HTTPS, von einem entfernten Rechner, der einen DNS-Eintrag für seine momentane IP-Adresse wünscht. &lt;br /&gt;
# Prüfen, ob die Anfrage einen berechtigten DDNS-Dienst-Usernamen mit zugehörigem Paßwort enthält.&lt;br /&gt;
# Prüfen, ob die Anfrage einen gültigen Domainnamen betrifft, den der Server bieten darf.&lt;br /&gt;
# Prüfen, ob die Domain example.com demselben Benutzer gehört, unter dessen Namen der Dynamisches-DNS-Server läuft.&lt;br /&gt;
# Eine gültige [[Zonefile]] mit &amp;amp;ndash; neben dem bisherigen Inhalt &amp;amp;ndash; einem A-Eintrag für einwahl.example.com in /home/pacs/xyz00/users/benutzername/doms/example.com/pri.example.com schreiben.&lt;br /&gt;
# Dem Client eine Bestätigung oder ggf. eine Fehlermeldung als Antwort senden.&lt;br /&gt;
# In irgendeiner Datenbank den momentan eingestellter Status all seiner DDNS-Einträge speichern.&lt;br /&gt;
# In einer Logdatei protokollieren, daß obiges getan wurde, oder ggf. welche Fehler traten auf.&lt;br /&gt;
&lt;br /&gt;
== Aufgaben des Clients ==&lt;br /&gt;
Bevor ich anfange, meinen Arbeitsplatzrechner so zu konfigurieren, daß er bei welchem Server auch immer einen DDNS-Eintrag anfordert, muß ich mich als verantwortlicher Benutzer dieses Rechners und der dazugehörigen Internetverbindung &amp;amp;ndash; das heißt, als Mensch &amp;amp;ndash; mit dem Betreiber des dynamisches-DNS-Servers vereinbaren, daß ich das darf und welchen Eintrag ich bekommen kann. Im Folgenden wird vorausgesetzt, daß solche Vereinbarungen getroffen und die Parameter geklärt wurden.&lt;br /&gt;
&lt;br /&gt;
Der DDNS-Client muß aus Server-Sicht nur wenig leisten:&lt;br /&gt;
&lt;br /&gt;
# Eine Anfrage senden, beispielsweise über HTTPS, an einen entfernten Rechner, der einen Eintrag ins DNS für die momentane IP-Adresse des Clients vornehmen kann.&amp;lt;br /&amp;gt;Diese Anfrage muß einem festgelegten Format entsprechen und muß gültige Werte für die Authorisation des Clients, den gewünschten Domainnamen, und eventuell andere Parameter enthalten.&lt;br /&gt;
# Eine Antwort des Servers entgegennehmen und als Erfolgs- oder Fehlermeldung auswerten.&lt;br /&gt;
# Von überflüssigen Anfragen absehen: das heißt bei Erfolg, nicht wiederholt den gleichen Eintrag erneut wünschen; bei Fehlern, nicht die gleiche fehlerhafte Anfrage erneut schicken.&lt;br /&gt;
&lt;br /&gt;
== Kommunikation zwischen Client und Server ==&lt;br /&gt;
&lt;br /&gt;
Ein einziges Nachrichtenpaar von Anfrage und Antwort genügt, um einen DDNS-Eintrag einzurichten: Der Client teilt die IP-Adresse und den Domainnamen mit, die in einem DNS-Eintrag verbunden werden sollen; der Server bestätigt den Auftrag.&lt;br /&gt;
&lt;br /&gt;
In der Beispielimplementierung erfolgt die Kommunikation über HTTP, und die Anfrage des Clients könnte so aussehen:&lt;br /&gt;
&lt;br /&gt;
  GET /cgi-bin/ddns?hostname=einwahl.example.com&amp;amp;myip=87.65.43.21 HTTP/1.1&lt;br /&gt;
  Host: ddns.beispiel.de&lt;br /&gt;
  User-Agent: Fritz!Box DDNS/1.0.1&lt;br /&gt;
  Authorization: Basic QWxhZGRpbjpvcGVuIHNlc2FtZQ==&lt;br /&gt;
&lt;br /&gt;
Bei Erhalt dieser Anfrage ruft Apache das CGI-Programm .../doms/ddns.beispiel.de/cgi-ssl/ddns auf. Das Fragezeichen trennt den Programmnamen von einem &amp;quot;Query-String&amp;quot;, in dem zwei Metavariablen definiert und übergeben werden. Die erste Metavariable, hostname, hat den Wert &amp;quot;einwahl.example.com&amp;quot;; die zweite, myip, hat den Wert &amp;quot;87.65.43.21&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
Das Server-Programm, hier &#039;&#039;ddns&#039;&#039;, prüft diese Informationen auf Form und Berechtigung, und schreibt gegebenenfalls einen entsprechenden Eintrag in einer Zonefile. Es schreibt auch verschiedene Informationen in die Standardausgabe. Wenn es die Standardausgabe geschlossen wird &amp;amp;ndash; also spätestens bei Programmende &amp;amp;ndash; schickt Apache diese Informationen als Antwort an den anfragenden Rechner zurück.&lt;br /&gt;
&lt;br /&gt;
Im Falle unserer Beispielimplementierung sieht die Antwort bei Erfolg so aus: &lt;br /&gt;
&lt;br /&gt;
  HTTP/1.1 200 OK&lt;br /&gt;
  Date: Wed, 22 Apr 2020 08:35:15 GMT&lt;br /&gt;
  Server: Apache&lt;br /&gt;
  Content-Length: 17&lt;br /&gt;
  Content-Type: text/plain; charset=ISO-8859-1&lt;br /&gt;
 &lt;br /&gt;
  good 87.65.43.21&lt;br /&gt;
&lt;br /&gt;
=== Das DDNS-Protokoll von DynDNS.org ===&lt;br /&gt;
&lt;br /&gt;
In den 90er Jahren, bevor das Internet so durchgehend vergeschäftlicht wurde, boten einige Organisationen kostenlose DDNS-Dienste an. Ein sehr beliebtes Angebot war das von DynDNS.org. Das DDNS-Protokoll von diesem Dienst wurde sogar in Einwahl-Routern einprogrammiert und der Dienst wurde von ISPs und Router-Herstellern als Leistungsmerkmal beworben.&lt;br /&gt;
&lt;br /&gt;
DynDNS.org gehört inzwischen Oracle und bietet keine kostenlose Dienste mehr. Dennoch wird das DDNS-Protokoll von DynDNS.org in der vorliegenden Beispielimplementierung übernommen in der Hoffnung, daß die Kompatibilität mit einigen gängigen Einwahl-Routern von Vorteil sein kann. Es gibt noch eine kurze Online-Dokumentation der [https://help.dyn.com/remote-access-api/perform-update/ Anfrage] und [https://help.dyn.com/remote-access-api/perform-update/ Antwortnachrichten].&lt;br /&gt;
&lt;br /&gt;
Das gesammte Protokoll sieht einen einzigen Nachrichtenaustausch aus Anfrage und Antwort vor. Die Anfrage kann mehrere Argumente enthalten; die Antwort kann verschiedene Code-Wörtern enthalten. Übrigens können in einer einzigen Anfrage mehrere DNS-Einträge gewünscht werden. In diesem Fall kann die Antwort mehrzeilig ausfallen.&lt;br /&gt;
&lt;br /&gt;
Das Verhalten von Server und Client bei künftigen Kommunikationsvorgängen wird unter Umständen von vorangegangenen Kommunikationsergebnissen beeinflußt: nach wiederholten fehlerhaften oder redundanten Anfragen kann der Server weitere Anfragen des Benutzers verweigern; nach wiederholten Fehlermeldungen sollte ein Client aufhören, immer dieselbe Anfrage zu schicken. Und für den Fall, daß mehrere Clients dynamische DNS-Einträge in derselben Domain example.com bestellen, muß der Server den Stand aller Client-Einträge intern speichern, damit er nicht mit einer neuen Zonefile einen früher erstellten Eintrag löscht. Zu diesen Fragen siehe den Abschnitt &#039;&#039;&#039;[[#Sukzessive_Kommunikationsabläufe]]&#039;&#039;&#039; nach der Beschreibung von Anfragen und Antworten unten.&lt;br /&gt;
&lt;br /&gt;
====Anfrage====&lt;br /&gt;
&lt;br /&gt;
Die Anfrage in Form eines URL übergibt dem DDNS-Programm in einem &#039;Query-String&#039; einige Metavariablen. Das heißt, in einem URL der Form&lt;br /&gt;
&lt;br /&gt;
  &amp;lt;nowiki&amp;gt;https://benutzername:passwort@ddns.beisiel.de/cgi-bin/ddns?hostname=einwahl.example.com&amp;amp;myip=87.65.43.21&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
signalisert das Fragezeichen, daß ein Query-String folgt. In einem solchen Query-String können in der Beispielimplementierung folgende Metavariablen definiert werden:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|- class=&amp;quot;hintergrundfarbe5&amp;quot;&lt;br /&gt;
! Variable !! Beispiel !! Bemerkungen&lt;br /&gt;
|-&lt;br /&gt;
| hostname || &amp;lt;tt&amp;gt;hostname=einwahl.example.com&amp;lt;/tt&amp;gt;&amp;lt;br /&amp;gt;&amp;lt;div style=&amp;quot;font-size:smaller;&amp;quot;&amp;gt;&amp;lt;tt&amp;gt;hostname=eins.example.com,zwei.example.com[,...]&amp;lt;/tt&amp;gt;&amp;lt;/div&amp;gt; ||&lt;br /&gt;
Muß ein vollständig qualifizierter Domain-Name (&amp;quot;FQDN&amp;quot;) sein; &amp;lt;tt&amp;gt;example.com&amp;lt;/tt&amp;gt; muß eine vom Besitzer des DDNS-Programms verwaltete Domain sein. Genaugenommen kann der Wert eine durch Kommata gegliederte Liste mehrerer gültiger Domainnamen sein, falls mehrere Einträge mit derselben IP-Adresse gewünscht werden.&lt;br /&gt;
|-&lt;br /&gt;
| myip || &amp;lt;tt&amp;gt;myip=87.65.43.21&amp;lt;/tt&amp;gt;||&lt;br /&gt;
Kann entfallen; kann vom Server ignoriert werden. Maßgeblich ist dann die IP-Adresse des Absenders, wie sie vom Web-Server mitgeteilt wird.&lt;br /&gt;
|-&lt;br /&gt;
| mx || &amp;lt;tt&amp;gt;mx=87.65.43.21&amp;lt;/tt&amp;gt;&amp;lt;br /&amp;gt;&amp;lt;tt&amp;gt;mx=NOCHG&amp;lt;/tt&amp;gt;&amp;lt;br /&amp;gt; ||&lt;br /&gt;
Neben dem A-Eintrag möchte der Client auch einen MX-Eintrag. Der Wert &amp;lt;tt&amp;gt;NOCHG&amp;lt;/tt&amp;gt; (für &amp;amp;bdquo;no change&amp;amp;ldquo;) bedeutet, der bestehende MX-Eintrag (oder seine Abwesenheit) soll nicht geändert werden. &lt;br /&gt;
|-&lt;br /&gt;
| backmx || &amp;lt;tt&amp;gt;backmx=YES&amp;lt;/tt&amp;gt;&amp;lt;br /&amp;gt;&amp;lt;tt&amp;gt;backmx=NOCHG&amp;lt;/tt&amp;gt;&amp;lt;br /&amp;gt;&amp;lt;tt&amp;gt;backmx=NO&amp;lt;/tt&amp;gt;   ||&lt;br /&gt;
Falls &amp;lt;tt&amp;gt;YES&amp;lt;/tt&amp;gt;, wird ein zweiter MX-Eintrag erzeugt, der &amp;lt;tt&amp;gt;einwahl.example.com&amp;lt;/tt&amp;gt; als Mail-Server für &amp;lt;tt&amp;gt;einwahl.example.com&amp;lt;/tt&amp;gt; nennt. Dieser Eintrag hat eine niedrigere Präferenzzahl (also eine höhere Priorität) als der mit &amp;lt;tt&amp;gt;mx&amp;lt;/tt&amp;gt; angeforderten Eintrag.&lt;br /&gt;
|-&lt;br /&gt;
| wildcard || &amp;lt;tt&amp;gt;wildcard=ON&amp;lt;/tt&amp;gt;&amp;lt;br /&amp;gt;&amp;lt;tt&amp;gt;wildcard=NOCHG&amp;lt;/tt&amp;gt;&amp;lt;br /&amp;gt;&amp;lt;tt&amp;gt;wildcard=OFF&amp;lt;/tt&amp;gt; ||&lt;br /&gt;
Neben dem A-Eintrag für den Domainnamen &amp;lt;tt&amp;gt;einwahl.example.com&amp;lt;/tt&amp;gt; wünscht der Client auch einen Eintrag für beliebige Subdomains, also &amp;lt;tt&amp;gt;*.einwahl.example.com&amp;lt;/tt&amp;gt;, mit der gleichen IP-Adresse.&lt;br /&gt;
|-&lt;br /&gt;
| offline ||&amp;lt;tt&amp;gt;offline=YES&amp;lt;/tt&amp;gt;&amp;lt;br /&amp;gt;&amp;lt;tt&amp;gt;offline=NOCHG&amp;lt;/tt&amp;gt;||&lt;br /&gt;
Falls &amp;lt;tt&amp;gt;YES&amp;lt;/tt&amp;gt;, wird ein DNS-Eintrag für &amp;lt;tt&amp;gt;einwahl.example.com&amp;lt;/tt&amp;gt; aus der Zonefile getilgt. Gegebenenfalls wird der Hostname dann auf Grund eines parallelen Wildcard-Eintrags für &amp;lt;tt&amp;gt;*.example.com&amp;lt;/tt&amp;gt; einer anderen IP-Adresse zugeordnet werden.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;!-- IPv6? --&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Alle Parameter bis auf hostname können entfallen. Bei nichtdokumentierten Argumenten ist das Verhalten undefiniert&amp;amp;trade;.&lt;br /&gt;
&lt;br /&gt;
====Antwort====&lt;br /&gt;
&lt;br /&gt;
Die Antwort auf eine erfolgreiche HTTP-Anfrage besteht im häufigsten Fall aus einigen Header-Zeilen, gefolgt vom Inhalt der gewünschten Text- oder andere Datei. Ein Status-Code in der ersten Header-Zeile gibt an, ob die Anfrage bedient werden kann oder kreist andernfalls den Grund für die Enttäuschung ein.&lt;br /&gt;
&lt;br /&gt;
Die vorliegende Beispielimplementierung von DDNS schickt einen der üblichen HTTP-Status-Codes &amp;quot;200 OK&amp;quot; oder &amp;quot;500 Internal Server Error&amp;quot;, gefolgt von einer kurzen Textnachricht nach dem HTTP-Header. Bei diesem Programm  ist &amp;amp;ndash; laut Gebrauchshinweise von DynDNS.org &amp;amp;ndash; &#039;&#039;nicht&#039;&#039; der Status-Code im Header, sondern der Inhalt der Nachricht  die definierte, maßgebliche Ergebnismeldung des Programms.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|- class=&amp;quot;hintergrundfarbe5&amp;quot;&lt;br /&gt;
! Meldung !! Bedeutung !! Bemerkungen&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;good&amp;amp;nbsp;&amp;amp;lt;IP&amp;amp;nbsp;number&amp;amp;gt;&amp;lt;/tt&amp;gt; ||&lt;br /&gt;
Der gewünschte DNS-Eintrag wurde erfolgreich in einer Zonefile eingetragen. &lt;br /&gt;
|| Es kann natürlich noch einige Minuten dauern, bis die Zonefile vom Hostsharing-Roboter abgelesen wird und der Inhalt in die BIND-Konfiguration übernommen.&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;good&amp;amp;nbsp;0.0.0.0&amp;lt;/tt&amp;gt; ||&lt;br /&gt;
Das Argument &amp;lt;tt&amp;gt;offline=YES&amp;lt;/tt&amp;gt; wurde empfangen und verarbeitet.&lt;br /&gt;
|| Der Domainname hat also keinen dynamischen DNS-Eintrag mehr.&lt;br /&gt;
|-&lt;br /&gt;
&amp;lt;!-- We don&#039;t do this!&lt;br /&gt;
| &amp;lt;tt&amp;gt;good&amp;amp;nbsp;127.0.0.1&amp;lt;/tt&amp;gt; ||&lt;br /&gt;
Die Anfrage entsprach nicht den Erfordernissen des Servers.&lt;br /&gt;
|| Trotz des Worts &amp;lt;tt&amp;gt;good&amp;lt;/tt&amp;gt; war die Anfrage nicht erfolgreich, falls in der Rückmeldung die IP-Adresse mit &amp;lt;tt&amp;gt;127.0.0.1&amp;lt;/tt&amp;gt; angegeben wird. Dieser verwirrende Fehlercode ist aus unerklärlichen Gründen in der Spezifikation von DynDNS.org so definiert.&lt;br /&gt;
|-&lt;br /&gt;
--&amp;gt;&lt;br /&gt;
| &amp;lt;tt&amp;gt;nochg&amp;amp;nbsp;&amp;amp;lt;IP&amp;amp;nbsp;number&amp;amp;gt;&amp;lt;/tt&amp;gt; ||&lt;br /&gt;
Der gewünschte DNS-Eintrag war bereits vorhanden. &lt;br /&gt;
|| Der Server selbst macht keine DNS-Abfrage, um das zu vermitteln: die &amp;amp;bdquo;no change&amp;amp;ldquo;-Antwort besagt nur, daß eine Anfrage für diesen Eintrag bereits mit Erfolg quittiert wurde.&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;notfqdn&amp;lt;/tt&amp;gt; ||&lt;br /&gt;
Fehlschlag: der gewünschte Domainname ist nicht gültig, oder es wurde keiner angegeben.&lt;br /&gt;
|| ...&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;nohost&amp;lt;/tt&amp;gt; ||&lt;br /&gt;
Fehlschlag: der gewünschte Domainname ist gehört nicht zu denen, die für diesen Benutzer des DDNS-Dienstes konfiguriert sind.&lt;br /&gt;
|| Siehe den Abschnitt [[#Administration|Administration]] weiter unten.&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;badauth&amp;lt;/tt&amp;gt; ||&lt;br /&gt;
Fehlschlag: Die Kombination von Benutzernamen und Paßwort entsprach keinem DDNS-Account, oder das Account ist momentan gesperrt.&lt;br /&gt;
|| Ein gesperrtes Account kann nur der Domain-Admin mittels des Administrationswerkzeugs wieder freigeben: siehe den Abschnit [[#Administration|Administration]] weiter unten.&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;abuse&amp;lt;/tt&amp;gt; ||&lt;br /&gt;
Fehlschlag: der gewünschte Domainname ist wegen vorangeganger Fehlschläge oder überflüssiger Aufrufe gesperrt.&lt;br /&gt;
|| Siehe den Abschnitt [[#Sukzessive_Kommunikationsabläufe|Sukzessive Kommunikationsabläufe]] unten.&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;911&amp;lt;/tt&amp;gt; ||&lt;br /&gt;
Fehlschlag: Das Server-Programm hat einen internen Fehler festgestellt.&lt;br /&gt;
|| Das Problem liegt nicht in der Anfrage an sich.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Man kann sich durchaus eine sinnreichere Kommunikation zwischen Client und Server vorstellen, doch das hier beschriebene Protokoll ist eben von DynDNS.org verwendet worden und wird in gängigen Routern implementiert, also wird es in der vorliegenden DDNS-Implementierung nachgebildet.&lt;br /&gt;
&lt;br /&gt;
=== Sukzessive Kommunikationsabläufe ===&lt;br /&gt;
Der Server muß sich zwischen einzelnen Aufrufen einiges merken, um Ressourcen zu schonen und um zu verhindern, daß einmal vergebene DDNS-Einträge von neuen Anfragen, die dieselbe übergeordnete Domain betreffen, durch Überschreiben  verlorengehen.&lt;br /&gt;
&lt;br /&gt;
==== Mißbrauch und Benutzersperrung ====&lt;br /&gt;
Zur Schonung von Ressourcen muß sich die Implementierung weigern, sich mit zuvielen fehlerhaften oder auch nur überflüssigen Anfragen zu beschäftigen. Dazu führt der Server eine Strichliste über solche Anfragen jedes Clients und sperrt nach einer bestimmten Anzahl solcher Anfragen den Benutzernamen oder einzelne Domainnamen gegen die weitere Nutzung des Dienstes.&lt;br /&gt;
&lt;br /&gt;
Mißbrauchspunkte gegen einen einzelnen Domainnamen gibt es für:&lt;br /&gt;
* eine Anfrage, die keinen neuen DNS-Eintrag (und keine Änderung oder Löschung eines Eintrags) erfordert, sondern bestehende Merkmale nur wiederholt&lt;br /&gt;
&lt;br /&gt;
Mißbrauchspunkte gegen einen Benutzernamen gibt es für:&lt;br /&gt;
* die Angabe eines Domainnamens, der in der Dienstkonfiguration dem anfragenden Benutzernamen nicht zugeordnet ist&lt;br /&gt;
* die Angabe eines Domainnamen in einer Domain, die nicht demselben Hostsharing-Domain-Admin gehört, der den DDNS-Dienst anbietet&lt;br /&gt;
* die Angabe eines Domainnamens, der in der Dienstkonfiguration bereits wegen mißbräuchlicher Anfragen gesperrt ist (siehe oben)&lt;br /&gt;
&lt;br /&gt;
Um eine Sperrung aufzuheben, wird in der Regel eine Handlung durch den Administrator erforderlich sein.&lt;br /&gt;
&lt;br /&gt;
==== Mehrere dynamische Subdomains in derselben Domain ====&lt;br /&gt;
Sobald zwei verschiedene DDNS-Einträge in derselben Domain verlangt werden &amp;amp;ndash; beispielsweise home.example.com und office.example.com &amp;amp;ndash; wird es notwendig, bei jeder neuen Zonefile für example.com eventuell frühere Einträge zu konservieren. Der Rechner zu Hause weiß beim Bestellen seines DDNS-Eintrags nichts vom Rechner im Büro und umgekehrt. Der Server muß in irgendeiner Form über bereits vergebene Einträge Buch führen und bei einer neuen Anfrage, die example.com betrifft, alle bereits aktiven DDNS-Einträge für example.com mit in die neue Zonefile aufnehmen &amp;amp;ndash auch wenn sie auf Anfragen verschiedener Benutzer zurückgehen.&lt;br /&gt;
&lt;br /&gt;
==== Datenbank ====&lt;br /&gt;
In der Beispielimplementierung werden diese Informationen in einer SQLite-Datenbank gespeichert.&lt;br /&gt;
&lt;br /&gt;
== Sicherheit ==&lt;br /&gt;
=== Rechte ===&lt;br /&gt;
Die &#039;&#039;&#039;Benutzerrechte&#039;&#039;&#039; werden durch das Hostsharing-System kontrolliert. Sowohl das CGI-Programm als auch das [[#Administration|Administrationswerkzeug]] werden mit den Rechten des Domain-Admins (xyz00-benutzername in unserem Beispiel) ausgeführt, also kann dieses Programm nur die Domains bearbeiten, die von xyz00-benutzername verwaltet werden.&lt;br /&gt;
&lt;br /&gt;
=== Authentifizierung ===&lt;br /&gt;
In der Beispielimplementierung (wie auch seinerzeit bei DynDNS.org) wird das CGI-Programm durch einen .htaccess-Eintrag geschützt, der HTTP-Basic-Authentication vorschreibt. Also wird das Programm eigentlich mit einem URL der form&lt;br /&gt;
&lt;br /&gt;
  &amp;lt;nowiki&amp;gt;https://ddnsaccount:passwort@ddns.example.com/cgi-bin/ddns?hostname=...&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
aufgerufen.&lt;br /&gt;
&lt;br /&gt;
=== Verschlüsselung ===&lt;br /&gt;
Das CGI-Programm sollte nur in example.com/cgi-ssl/ installiert werden, nicht in example.com/cgi/. Damit ist die Kommunikation zwischen Client und Server durch SSL verschlüsselt.&lt;br /&gt;
&lt;br /&gt;
== Administration ==&lt;br /&gt;
&lt;br /&gt;
Der Verwalter des DDNS-Programms trägt berechtigte Benutzer und die ihnen zugeteilten Domainnamen in die Datenbank des Programms ein mit Hilfe eines kleinen Hilfsprogramms. Das ist im vorliegenden Fall ein menügesteuertes Programm für die Befehlszeile, daß die naheliegenden Funktionen anbietet: Account hinzufügen, löschen, sperren, entsperren, Paßwort setzen, ändern; Domainnamen hinzufügen, ändern, entsperren, löschen; Accounts und Domainnamen mit aktuellem Status auflisten. Die Funktionen sind auch über Befehlszeilenargumente verfügbar, also skriptfähig.&lt;br /&gt;
&lt;br /&gt;
Eine Übersicht der Funktionen des Administrationswerkzeugs gibt dieses selbst aus:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
xyz00-benutzername@h02:~$ bin/ddnsadmin -h&lt;br /&gt;
ddnsadmin.pl: Verwaltungswerkzeug für ddns&lt;br /&gt;
&lt;br /&gt;
Verwendung:&lt;br /&gt;
    ddnsadmin -A{[ahlusf]} [&amp;lt;Account&amp;gt;] [-f &amp;lt;DB-Datei&amp;gt;]&lt;br /&gt;
    ddnsadmin -D{[ahlsf]} [&amp;lt;Domain&amp;gt;] -A &amp;lt;Account&amp;gt; [-f &amp;lt;DB-Datei&amp;gt;]&lt;br /&gt;
    ddnsadmin -E &amp;lt;Einstellung&amp;gt; &amp;lt;Wert&amp;gt; [-f &amp;lt;DB-Datei&amp;gt;]&lt;br /&gt;
    ddnsadmin [-f &amp;lt;DB-Datei&amp;gt;] [-n]&lt;br /&gt;
&lt;br /&gt;
Wenn keine Option oder nur -f &amp;lt;DB-Datei&amp;gt; angegeben wird, bietet&lt;br /&gt;
ddnsadmin.pl eine interaktive Menüoberfläche.&lt;br /&gt;
&lt;br /&gt;
Optionen:&lt;br /&gt;
    -f &amp;lt;DB-Datei&amp;gt;                    Angegebene Datenbankdatei verwenden&lt;br /&gt;
    -n                               Neue, leere Datenbank erzeugen&lt;br /&gt;
    -Aa  [&amp;lt;Account&amp;gt;]                 Account(s) auflisten&lt;br /&gt;
    -Ah &amp;lt;Account&amp;gt; &amp;lt;Paßwort&amp;gt;          Account hinzufügen&lt;br /&gt;
    -A{lsf} &amp;lt;Account&amp;gt;                Account löschen, sperren, freigeben&lt;br /&gt;
    -Au &amp;lt;Account&amp;gt; &amp;lt;Name&amp;gt;             Account umbenennen&lt;br /&gt;
    -A  &amp;lt;Account&amp;gt; -Da [&amp;lt;Domain&amp;gt;]     Domain(s) auflisten&lt;br /&gt;
    -A  &amp;lt;Account&amp;gt; -D{hlsf} &amp;lt;Domain&amp;gt;  Domain hinzufügen,&lt;br /&gt;
                                     löschen, sperren, freigeben&lt;br /&gt;
    -E &amp;lt;Einstellung&amp;gt; &amp;lt;Wert&amp;gt;          Einstellung ändern&lt;br /&gt;
    -h                               Diese Übersicht ausgeben&lt;br /&gt;
&lt;br /&gt;
Einstellungen: &lt;br /&gt;
    maxacctabuse    Anzahl der mißbräuchlichen Aufrufe,&lt;br /&gt;
                    bevor ein Account gesperrt wird&lt;br /&gt;
    maxhostabuse    Anzahl der mißbräuchlichen Aufrufe,&lt;br /&gt;
                    bevor ein Domainname gesperrt wird&lt;br /&gt;
    safeinterval    Mindestabstand zwischen redundanten Aufrufen&lt;br /&gt;
                    (in Sekunden)&lt;br /&gt;
    cgihost         Server, der das DDNS-Skript bereithält&lt;br /&gt;
&lt;br /&gt;
xyz00-benutzername@h02:~$ &lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Eine Auflistung des momentanen Inhalts der DDNS-Datenbank durch das Administrationswerkzeug könnte beispielsweise so aussehen:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  xyz00-benutzername@h02:~$ bin/ddnsadmin.pl -Aa&lt;br /&gt;
  1.  papst	Mißbrauch: 0; gesperrt: nein&lt;br /&gt;
  	avignon.example.com&lt;br /&gt;
  		zuletzt aktiv am Sun Apr 26 22:24:49 2020&lt;br /&gt;
  		mit IP-Nr. 87.65.43.21; MX: 0;  Backup-MX: nein;&lt;br /&gt;
  		Subdomains: nein; Mißbrauch: 0;  gesperrt: nein&lt;br /&gt;
  	vatican.beispiel.de&lt;br /&gt;
  		zuletzt aktiv am Sun Apr 26 22:24:49 2020&lt;br /&gt;
  		mit IP-Nr. 87.65.43.21; MX: 0;  Backup-MX: nein;&lt;br /&gt;
  		Subdomains: nein; Mißbrauch: 0;  gesperrt: nein&lt;br /&gt;
  2.  kaiser	Mißbrauch: 4; gesperrt: ja&lt;br /&gt;
  	augsburg.beispiel.de&lt;br /&gt;
  		zuletzt aktiv am Fri Apr 24 16:13:49 2020&lt;br /&gt;
  		mit IP-Nr. 64.82.31.75; MX: 0;  Backup-MX: nein;&lt;br /&gt;
  		Subdomains: nein; Mißbrauch: 0;  gesperrt: ja&lt;br /&gt;
  3.  luther	Mißbrauch: 1; gesperrt: nein&lt;br /&gt;
  	wittenberg.example.com&lt;br /&gt;
  		zuletzt aktiv am Mon Apr 27 10:12:49 2020&lt;br /&gt;
  		mit IP-Nr. 78.56.34.12; MX: 0;  Backup-MX: nein;&lt;br /&gt;
  		Subdomains: nein; Mißbrauch: 1;  gesperrt: nein&lt;br /&gt;
  xyz00-benutzername@h02:~$&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Das DDNS-Account &amp;amp;bdquo;kaiser&amp;amp;ldquo; in dieser Auflistung ist wohl auf Grund fehlerhafter Anfragen automatisch gesperrt worden. Der Inhaber wird sich wohl bald melden, um nach Korrektur seiner Client-Konfiguration die Aufhebung der Sperre zu wünschen.&lt;br /&gt;
&lt;br /&gt;
=== Log ===&lt;br /&gt;
Alle Anfragen werden in einer täglich wechselnden Log-Datei protokolliert, entweder schlicht oder ausführlich, je nachdem, ob eine Variable &amp;lt;tt&amp;gt;verbose&amp;lt;/tt&amp;gt; wahr ist.&lt;br /&gt;
Ein ausführlicher Log-Eintrag sieht so aus:&lt;br /&gt;
&lt;br /&gt;
  Sun Apr 26 20:21:45 2020  ddns aufgerufen von papst&lt;br /&gt;
  			unter 84.185.97.8&lt;br /&gt;
  	URL: &amp;lt;nowiki&amp;gt;https://ddns.example.com/cgi-bin/ddns.cgi?hostname=&lt;br /&gt;
  			avignon.example.com,vatican.beispiel.de&amp;amp;&lt;br /&gt;
  			myip=84.185.97.8&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
  	Verwende IP 84.185.97.8 (= 1421435144)&lt;br /&gt;
  	DB-Version: 1&lt;br /&gt;
  	Skript und DB exklusiv geöffnet&lt;br /&gt;
  	avignon.example.com: IP: 84.185.97.8; MX: 0; Backup-MX: nein;&lt;br /&gt;
  			Wildcard: nein; Mißbrauch: 0; gesperrt: nein &lt;br /&gt;
  	vatican.beispiel.de: IP: 84.185.97.8; MX: 0; Backup-MX: nein;&lt;br /&gt;
  			Wildcard: nein; Mißbrauch: 0; gesperrt: nein &lt;br /&gt;
  	Betroffene Zonen: example.com, beispiel.de&lt;br /&gt;
  	Temporärdatei example.com_hxNa.new geschrieben&lt;br /&gt;
  	Zonendatei /home/pacs/xyz00/users/benutzername/doms/example.com/&lt;br /&gt;
  			etc/pri.example.com eingestellt&lt;br /&gt;
  	Temporärdatei beispiel.de_6HcO.new geschrieben&lt;br /&gt;
  	Zonendatei /home/pacs/xyz00/users/benutzername/doms/beispiel.de/&lt;br /&gt;
  			etc/pri.beispiel.de eingestellt&lt;br /&gt;
  	Abgeschlossen: 	Fertig&lt;br /&gt;
&lt;br /&gt;
Wenn &amp;lt;tt&amp;gt;verbose&amp;lt;/tt&amp;gt; auf falsch gesetzt ist, sind die Log-Einträge einzeilig.&lt;/div&gt;</summary>
		<author><name>Apc00-tony</name></author>
	</entry>
	<entry>
		<id>https://wiki.hostsharing.net/index.php?title=Benutzer:Apc00-tony/Dynamisches_DNS&amp;diff=5202</id>
		<title>Benutzer:Apc00-tony/Dynamisches DNS</title>
		<link rel="alternate" type="text/html" href="https://wiki.hostsharing.net/index.php?title=Benutzer:Apc00-tony/Dynamisches_DNS&amp;diff=5202"/>
		<updated>2020-04-29T10:03:13Z</updated>

		<summary type="html">&lt;p&gt;Apc00-tony: /* Administration */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;((Provisorischer Vorspann: Auf Grund einer Mailing-Listen-Diskussion habe ich angefangen, Dynamisches DNS über einen CGI-Skript bei Hostsharing zu realisieren. Meine Lösung habe ich dann vorgestellt; sie wurde für nicht ausreichend selbsterklärend befunden und fand wenig Akzeptanz. Hier also der Versuch, die Sache zu dokumentieren.))&lt;br /&gt;
&lt;br /&gt;
Mit der regelmäßigen Aufnahme von benutzerspezifischen Zonefiles in seiner DNS-Konfiguration bietet  Hostsharing alles, was man braucht, um &amp;amp;bdquo;dynamisches DNS&amp;amp;ldquo; in Eigenregie zu realisieren.&lt;br /&gt;
&lt;br /&gt;
Das heißt, wenn ich mindestens eine Domain bei Hostsharing verwalte, und mindestens eine Einwahlverbindung (oder DSL-Verbindung) ins Internet mit wechselnder IP-Adresse über irgendeinen ISP für meinen Arbeitsplatzrechner zu Hause betreibe, dann kann ich dem Arbeitsplatzrechner über die DNS-Server von Hostsharing einen vollqualifizieren Domainnamen zuweisen, der der jeweiligen IP-Adresse meiner Einwahlleitung zugeordnet ist.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
(ASCII-Art-Diagramm der beschriebenen Konstellation)&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Im Folgenden wird eine real existierende Implementierung von Dynamischem DNS (&amp;amp;bdquo;DDNS&amp;amp;ldquo;) beschrieben. Die verschiedenen Elemente könnten durchaus anders realisiert werden; die beschriebene Implementierung könnte durchaus verbessert werden. Sie dient hier der Illustration.&lt;br /&gt;
&lt;br /&gt;
In der folgenden Beschreibung werden diese Beispielwerte benutzt:&lt;br /&gt;
* Ein Hostsharing-Mitglied hat ein Account als Paket-Admin mit Kennung xyz00.&lt;br /&gt;
* Im Paket xyz00 gibt es einen Domain-Admin namens xyz00-benutzername.&lt;br /&gt;
* Dieser Domain-Admin verwaltet bei Hostsharing die Domains example.com und beispiel.de.&lt;br /&gt;
* Ein Benutzer hat zu Hause (oder im Büro) einen Arbeitsplatzrechner hinter der marktüblichen DSL-Leitung, die von seinem ISP bereitgestellt wird.&lt;br /&gt;
* Dieser Arbeitsplatzrechner (oder der Router, der seine Internetverbindung steuert) bekommt vom ISP immer wechselnde IP-Adressen zugewiesen.&lt;br /&gt;
* Dennoch möchte der Benutzer seinen Arbeitsplatzrechner aus dem Internet unter dem Hostnamen einwahl.example.com ansprechen können.&lt;br /&gt;
&lt;br /&gt;
Dazu kann ein System wie Hostsharing, das authoritative DNS-Informationen für viele Domains bereitstellt, auch veränderliche DNS-Information über dynamisch verbundene Rechner verwalten &amp;amp;ndash; sofern das ressourcenschonend gemacht werden kann ohne andere Funktionen zu stören.&lt;br /&gt;
&lt;br /&gt;
== Aufgaben des Servers ==&lt;br /&gt;
&lt;br /&gt;
Um einem Rechner mit wechselnder IP-Adresse einen DDNS-Eintrag zu bieten, muß der Hostsharing-Server folgendes leisten (in ungefährer Reihenfolge der Ereignisse):&lt;br /&gt;
&lt;br /&gt;
# Eine Anfrage entgegennehmen, beispielsweise über HTTPS, von einem entfernten Rechner, der einen DNS-Eintrag für seine momentane IP-Adresse wünscht. &lt;br /&gt;
# Prüfen, ob die Anfrage einen berechtigten DDNS-Dienst-Usernamen mit zugehörigem Paßwort enthält.&lt;br /&gt;
# Prüfen, ob die Anfrage einen gültigen Domainnamen betrifft, den der Server bieten darf.&lt;br /&gt;
# Prüfen, ob die Domain example.com demselben Benutzer gehört, unter dessen Namen der Dynamisches-DNS-Server läuft.&lt;br /&gt;
# Eine gültige [[Zonefile]] mit &amp;amp;ndash; neben dem bisherigen Inhalt &amp;amp;ndash; einem A-Eintrag für einwahl.example.com in /home/pacs/xyz00/users/benutzername/doms/example.com/pri.example.com schreiben.&lt;br /&gt;
# Dem Client eine Bestätigung oder ggf. eine Fehlermeldung als Antwort senden.&lt;br /&gt;
# In irgendeiner Datenbank den momentan eingestellter Status all seiner DDNS-Einträge speichern.&lt;br /&gt;
# In einer Logdatei protokollieren, daß obiges getan wurde, oder ggf. welche Fehler traten auf.&lt;br /&gt;
&lt;br /&gt;
== Aufgaben des Clients ==&lt;br /&gt;
Bevor ich anfange, meinen Arbeitsplatzrechner so zu konfigurieren, daß er bei welchem Server auch immer einen DDNS-Eintrag anfordert, muß ich mich als verantwortlicher Benutzer dieses Rechners und der dazugehörigen Internetverbindung &amp;amp;ndash; das heißt, als Mensch &amp;amp;ndash; mit dem Betreiber des dynamisches-DNS-Servers vereinbaren, daß ich das darf und welchen Eintrag ich bekommen kann. Im Folgenden wird vorausgesetzt, daß solche Vereinbarungen getroffen und die Parameter geklärt wurden.&lt;br /&gt;
&lt;br /&gt;
Der DDNS-Client muß aus Server-Sicht nur wenig leisten:&lt;br /&gt;
&lt;br /&gt;
# Eine Anfrage senden, beispielsweise über HTTPS, an einen entfernten Rechner, der einen Eintrag ins DNS für die momentane IP-Adresse des Clients vornehmen kann.&amp;lt;br /&amp;gt;Diese Anfrage muß einem festgelegten Format entsprechen und muß gültige Werte für die Authorisation des Clients, den gewünschten Domainnamen, und eventuell andere Parameter enthalten.&lt;br /&gt;
# Eine Antwort des Servers entgegennehmen und als Erfolgs- oder Fehlermeldung auswerten.&lt;br /&gt;
# Von überflüssigen Anfragen absehen: das heißt bei Erfolg, nicht wiederholt den gleichen Eintrag erneut wünschen; bei Fehlern, nicht die gleiche fehlerhafte Anfrage erneut schicken.&lt;br /&gt;
&lt;br /&gt;
== Kommunikation zwischen Client und Server ==&lt;br /&gt;
&lt;br /&gt;
Ein einziges Nachrichtenpaar von Anfrage und Antwort genügt, um einen DDNS-Eintrag einzurichten: Der Client teilt die IP-Adresse und den Domainnamen mit, die in einem DNS-Eintrag verbunden werden sollen; der Server bestätigt den Auftrag.&lt;br /&gt;
&lt;br /&gt;
In der Beispielimplementierung erfolgt die Kommunikation über HTTP, und die Anfrage des Clients könnte so aussehen:&lt;br /&gt;
&lt;br /&gt;
  GET /cgi-bin/ddns?hostname=einwahl.example.com&amp;amp;myip=87.65.43.21 HTTP/1.1&lt;br /&gt;
  Host: ddns.beispiel.de&lt;br /&gt;
  User-Agent: Fritz!Box DDNS/1.0.1&lt;br /&gt;
  Authorization: Basic QWxhZGRpbjpvcGVuIHNlc2FtZQ==&lt;br /&gt;
&lt;br /&gt;
Bei Erhalt dieser Anfrage ruft Apache das CGI-Programm .../doms/ddns.beispiel.de/cgi-ssl/ddns auf. Das Fragezeichen trennt den Programmnamen von einem &amp;quot;Query-String&amp;quot;, in dem zwei Metavariablen definiert und übergeben werden. Die erste Metavariable, hostname, hat den Wert &amp;quot;einwahl.example.com&amp;quot;; die zweite, myip, hat den Wert &amp;quot;87.65.43.21&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
Das Server-Programm, hier &#039;&#039;ddns&#039;&#039;, prüft diese Informationen auf Form und Berechtigung, und schreibt gegebenenfalls einen entsprechenden Eintrag in einer Zonefile. Es schreibt auch verschiedene Informationen in die Standardausgabe. Wenn es die Standardausgabe geschlossen wird &amp;amp;ndash; also spätestens bei Programmende &amp;amp;ndash; schickt Apache diese Informationen als Antwort an den anfragenden Rechner zurück.&lt;br /&gt;
&lt;br /&gt;
Im Falle unserer Beispielimplementierung sieht die Antwort bei Erfolg so aus: &lt;br /&gt;
&lt;br /&gt;
  HTTP/1.1 200 OK&lt;br /&gt;
  Date: Wed, 22 Apr 2020 08:35:15 GMT&lt;br /&gt;
  Server: Apache&lt;br /&gt;
  Content-Length: 17&lt;br /&gt;
  Content-Type: text/plain; charset=ISO-8859-1&lt;br /&gt;
 &lt;br /&gt;
  good 87.65.43.21&lt;br /&gt;
&lt;br /&gt;
=== Das DDNS-Protokoll von DynDNS.org ===&lt;br /&gt;
&lt;br /&gt;
In den 90er Jahren, bevor das Internet so durchgehend vergeschäftlicht wurde, boten einige Organisationen kostenlose DDNS-Dienste an. Ein sehr beliebtes Angebot war das von DynDNS.org. Das DDNS-Protokoll von diesem Dienst wurde sogar in Einwahl-Routern einprogrammiert und der Dienst wurde von ISPs und Router-Herstellern als Leistungsmerkmal beworben.&lt;br /&gt;
&lt;br /&gt;
DynDNS.org gehört inzwischen Oracle und bietet keine kostenlose Dienste mehr. Dennoch wird das DDNS-Protokoll von DynDNS.org in der vorliegenden Beispielimplementierung übernommen in der Hoffnung, daß die Kompatibilität mit einigen gängigen Einwahl-Routern von Vorteil sein kann. Es gibt noch eine kurze Online-Dokumentation der [https://help.dyn.com/remote-access-api/perform-update/ Anfrage] und [https://help.dyn.com/remote-access-api/perform-update/ Antwortnachrichten].&lt;br /&gt;
&lt;br /&gt;
Das gesammte Protokoll sieht einen einzigen Nachrichtenaustausch aus Anfrage und Antwort vor. Die Anfrage kann mehrere Argumente enthalten; die Antwort kann verschiedene Code-Wörtern enthalten. Übrigens können in einer einzigen Anfrage mehrere DNS-Einträge gewünscht werden. In diesem Fall kann die Antwort mehrzeilig ausfallen.&lt;br /&gt;
&lt;br /&gt;
Das Verhalten von Server und Client bei künftigen Kommunikationsvorgängen wird unter Umständen von vorangegangenen Kommunikationsergebnissen beeinflußt: nach wiederholten fehlerhaften oder redundanten Anfragen kann der Server weitere Anfragen des Benutzers verweigern; nach wiederholten Fehlermeldungen sollte ein Client aufhören, immer dieselbe Anfrage zu schicken. Und für den Fall, daß mehrere Clients dynamische DNS-Einträge in derselben Domain example.com bestellen, muß der Server den Stand aller Client-Einträge intern speichern, damit er nicht mit einer neuen Zonefile einen früher erstellten Eintrag löscht. Zu diesen Fragen siehe den Abschnitt &#039;&#039;&#039;[[#Sukzessive_Kommunikationsabläufe]]&#039;&#039;&#039; nach der Beschreibung von Anfragen und Antworten unten.&lt;br /&gt;
&lt;br /&gt;
====Anfrage====&lt;br /&gt;
&lt;br /&gt;
Die Anfrage in Form eines URL übergibt dem DDNS-Programm in einem &#039;Query-String&#039; einige Metavariablen. Das heißt, in einem URL der Form&lt;br /&gt;
&lt;br /&gt;
  &amp;lt;nowiki&amp;gt;https://benutzername:passwort@ddns.beisiel.de/cgi-bin/ddns?hostname=einwahl.example.com&amp;amp;myip=87.65.43.21&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
signalisert das Fragezeichen, daß ein Query-String folgt. In einem solchen Query-String können in der Beispielimplementierung folgende Metavariablen definiert werden:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|- class=&amp;quot;hintergrundfarbe5&amp;quot;&lt;br /&gt;
! Variable !! Beispiel !! Bemerkungen&lt;br /&gt;
|-&lt;br /&gt;
| hostname || &amp;lt;tt&amp;gt;hostname=einwahl.example.com&amp;lt;/tt&amp;gt;&amp;lt;br /&amp;gt;&amp;lt;div style=&amp;quot;font-size:smaller;&amp;quot;&amp;gt;&amp;lt;tt&amp;gt;hostname=eins.example.com,zwei.example.com[,...]&amp;lt;/tt&amp;gt;&amp;lt;/div&amp;gt; ||&lt;br /&gt;
Muß ein vollständig qualifizierter Domain-Name (&amp;quot;FQDN&amp;quot;) sein; &amp;lt;tt&amp;gt;example.com&amp;lt;/tt&amp;gt; muß eine vom Besitzer des DDNS-Programms verwaltete Domain sein. Genaugenommen kann der Wert eine durch Kommata gegliederte Liste mehrerer gültiger Domainnamen sein, falls mehrere Einträge mit derselben IP-Adresse gewünscht werden.&lt;br /&gt;
|-&lt;br /&gt;
| myip || &amp;lt;tt&amp;gt;myip=87.65.43.21&amp;lt;/tt&amp;gt;||&lt;br /&gt;
Kann entfallen; kann vom Server ignoriert werden. Maßgeblich ist dann die IP-Adresse des Absenders, wie sie vom Web-Server mitgeteilt wird.&lt;br /&gt;
|-&lt;br /&gt;
| mx || &amp;lt;tt&amp;gt;mx=87.65.43.21&amp;lt;/tt&amp;gt;&amp;lt;br /&amp;gt;&amp;lt;tt&amp;gt;mx=NOCHG&amp;lt;/tt&amp;gt;&amp;lt;br /&amp;gt; ||&lt;br /&gt;
Neben dem A-Eintrag möchte der Client auch einen MX-Eintrag. Der Wert &amp;lt;tt&amp;gt;NOCHG&amp;lt;/tt&amp;gt; (für &amp;amp;bdquo;no change&amp;amp;ldquo;) bedeutet, der bestehende MX-Eintrag (oder seine Abwesenheit) soll nicht geändert werden. &lt;br /&gt;
|-&lt;br /&gt;
| backmx || &amp;lt;tt&amp;gt;backmx=YES&amp;lt;/tt&amp;gt;&amp;lt;br /&amp;gt;&amp;lt;tt&amp;gt;backmx=NOCHG&amp;lt;/tt&amp;gt;&amp;lt;br /&amp;gt;&amp;lt;tt&amp;gt;backmx=NO&amp;lt;/tt&amp;gt;   ||&lt;br /&gt;
Falls &amp;lt;tt&amp;gt;YES&amp;lt;/tt&amp;gt;, wird ein zweiter MX-Eintrag erzeugt, der &amp;lt;tt&amp;gt;einwahl.example.com&amp;lt;/tt&amp;gt; als Mail-Server für &amp;lt;tt&amp;gt;einwahl.example.com&amp;lt;/tt&amp;gt; nennt. Dieser Eintrag hat eine niedrigere Präferenzzahl (also eine höhere Priorität) als der mit &amp;lt;tt&amp;gt;mx&amp;lt;/tt&amp;gt; angeforderten Eintrag.&lt;br /&gt;
|-&lt;br /&gt;
| wildcard || &amp;lt;tt&amp;gt;wildcard=ON&amp;lt;/tt&amp;gt;&amp;lt;br /&amp;gt;&amp;lt;tt&amp;gt;wildcard=NOCHG&amp;lt;/tt&amp;gt;&amp;lt;br /&amp;gt;&amp;lt;tt&amp;gt;wildcard=OFF&amp;lt;/tt&amp;gt; ||&lt;br /&gt;
Neben dem A-Eintrag für den Domainnamen &amp;lt;tt&amp;gt;einwahl.example.com&amp;lt;/tt&amp;gt; wünscht der Client auch einen Eintrag für beliebige Subdomains, also &amp;lt;tt&amp;gt;*.einwahl.example.com&amp;lt;/tt&amp;gt;, mit der gleichen IP-Adresse.&lt;br /&gt;
|-&lt;br /&gt;
| offline ||&amp;lt;tt&amp;gt;offline=YES&amp;lt;/tt&amp;gt;&amp;lt;br /&amp;gt;&amp;lt;tt&amp;gt;offline=NOCHG&amp;lt;/tt&amp;gt;||&lt;br /&gt;
Falls &amp;lt;tt&amp;gt;YES&amp;lt;/tt&amp;gt;, wird ein DNS-Eintrag für &amp;lt;tt&amp;gt;einwahl.example.com&amp;lt;/tt&amp;gt; aus der Zonefile getilgt. Gegebenenfalls wird der Hostname dann auf Grund eines parallelen Wildcard-Eintrags für &amp;lt;tt&amp;gt;*.example.com&amp;lt;/tt&amp;gt; einer anderen IP-Adresse zugeordnet werden.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;!-- IPv6? --&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Alle Parameter bis auf hostname können entfallen. Bei nichtdokumentierten Argumenten ist das Verhalten undefiniert&amp;amp;trade;.&lt;br /&gt;
&lt;br /&gt;
====Antwort====&lt;br /&gt;
&lt;br /&gt;
Die Antwort auf eine erfolgreiche HTTP-Anfrage besteht im häufigsten Fall aus einigen Header-Zeilen, gefolgt vom Inhalt der gewünschten Text- oder andere Datei. Ein Status-Code in der ersten Header-Zeile gibt an, ob die Anfrage bedient werden kann oder kreist andernfalls den Grund für die Enttäuschung ein.&lt;br /&gt;
&lt;br /&gt;
Die vorliegende Beispielimplementierung von DDNS schickt einen der üblichen HTTP-Status-Codes &amp;quot;200 OK&amp;quot; oder &amp;quot;500 Internal Server Error&amp;quot;, gefolgt von einer kurzen Textnachricht nach dem HTTP-Header. Bei diesem Programm  ist &amp;amp;ndash; laut Gebrauchshinweise von DynDNS.org &amp;amp;ndash; &#039;&#039;nicht&#039;&#039; der Status-Code im Header, sondern der Inhalt der Nachricht  die definierte, maßgebliche Ergebnismeldung des Programms.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|- class=&amp;quot;hintergrundfarbe5&amp;quot;&lt;br /&gt;
! Meldung !! Bedeutung !! Bemerkungen&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;good&amp;amp;nbsp;&amp;amp;lt;IP&amp;amp;nbsp;number&amp;amp;gt;&amp;lt;/tt&amp;gt; ||&lt;br /&gt;
Der gewünschte DNS-Eintrag wurde erfolgreich in einer Zonefile eingetragen. &lt;br /&gt;
|| Es kann natürlich noch einige Minuten dauern, bis die Zonefile vom Hostsharing-Roboter abgelesen wird und der Inhalt in die BIND-Konfiguration übernommen.&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;good&amp;amp;nbsp;0.0.0.0&amp;lt;/tt&amp;gt; ||&lt;br /&gt;
Das Argument &amp;lt;tt&amp;gt;offline=YES&amp;lt;/tt&amp;gt; wurde empfangen und verarbeitet.&lt;br /&gt;
|| Der Domainname hat also keinen dynamischen DNS-Eintrag mehr.&lt;br /&gt;
|-&lt;br /&gt;
&amp;lt;!-- We don&#039;t do this!&lt;br /&gt;
| &amp;lt;tt&amp;gt;good&amp;amp;nbsp;127.0.0.1&amp;lt;/tt&amp;gt; ||&lt;br /&gt;
Die Anfrage entsprach nicht den Erfordernissen des Servers.&lt;br /&gt;
|| Trotz des Worts &amp;lt;tt&amp;gt;good&amp;lt;/tt&amp;gt; war die Anfrage nicht erfolgreich, falls in der Rückmeldung die IP-Adresse mit &amp;lt;tt&amp;gt;127.0.0.1&amp;lt;/tt&amp;gt; angegeben wird. Dieser verwirrende Fehlercode ist aus unerklärlichen Gründen in der Spezifikation von DynDNS.org so definiert.&lt;br /&gt;
|-&lt;br /&gt;
--&amp;gt;&lt;br /&gt;
| &amp;lt;tt&amp;gt;nochg&amp;amp;nbsp;&amp;amp;lt;IP&amp;amp;nbsp;number&amp;amp;gt;&amp;lt;/tt&amp;gt; ||&lt;br /&gt;
Der gewünschte DNS-Eintrag war bereits vorhanden. &lt;br /&gt;
|| Der Server selbst macht keine DNS-Abfrage, um das zu vermitteln: die &amp;amp;bdquo;no change&amp;amp;ldquo;-Antwort besagt nur, daß eine Anfrage für diesen Eintrag bereits mit Erfolg quittiert wurde.&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;notfqdn&amp;lt;/tt&amp;gt; ||&lt;br /&gt;
Fehlschlag: der gewünschte Domainname ist nicht gültig, oder es wurde keiner angegeben.&lt;br /&gt;
|| ...&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;nohost&amp;lt;/tt&amp;gt; ||&lt;br /&gt;
Fehlschlag: der gewünschte Domainname ist gehört nicht zu denen, die für diesen Benutzer des DDNS-Dienstes konfiguriert sind.&lt;br /&gt;
|| Siehe den Abschnitt [[#Administration|Administration]] weiter unten.&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;badauth&amp;lt;/tt&amp;gt; ||&lt;br /&gt;
Fehlschlag: Die Kombination von Benutzernamen und Paßwort entsprach keinem DDNS-Account, oder das Account ist momentan gesperrt.&lt;br /&gt;
|| Ein gesperrtes Account kann nur der Domain-Admin mittels des Administrationswerkzeugs wieder freigeben: siehe den Abschnit [[#Administration|Administration]] weiter unten.&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;abuse&amp;lt;/tt&amp;gt; ||&lt;br /&gt;
Fehlschlag: der gewünschte Domainname ist wegen vorangeganger Fehlschläge oder überflüssiger Aufrufe gesperrt.&lt;br /&gt;
|| Siehe den Abschnitt [[#Sukzessive_Kommunikationsabläufe|Sukzessive Kommunikationsabläufe]] unten.&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;911&amp;lt;/tt&amp;gt; ||&lt;br /&gt;
Fehlschlag: Das Server-Programm hat einen internen Fehler festgestellt.&lt;br /&gt;
|| Das Problem liegt nicht in der Anfrage an sich.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Man kann sich durchaus eine sinnreichere Kommunikation zwischen Client und Server vorstellen, doch das hier beschriebene Protokoll ist eben von DynDNS.org verwendet worden und wird in gängigen Routern implementiert, also wird es in der vorliegenden DDNS-Implementierung nachgebildet.&lt;br /&gt;
&lt;br /&gt;
=== Sukzessive Kommunikationsabläufe ===&lt;br /&gt;
Der Server muß sich zwischen einzelnen Aufrufen einiges merken, um Ressourcen zu schonen und um zu verhindern, daß einmal vergebene DDNS-Einträge von neuen Anfragen, die dieselbe übergeordnete Domain betreffen, durch Überschreiben  verlorengehen.&lt;br /&gt;
&lt;br /&gt;
==== Mißbrauch und Benutzersperrung ====&lt;br /&gt;
Zur Schonung von Ressourcen muß sich die Implementierung weigern, sich mit zuvielen fehlerhaften oder auch nur überflüssigen Anfragen zu beschäftigen. Dazu führt der Server eine Strichliste über solche Anfragen jedes Clients und sperrt nach einer bestimmten Anzahl solcher Anfragen den Benutzernamen oder einzelne Domainnamen gegen die weitere Nutzung des Dienstes.&lt;br /&gt;
&lt;br /&gt;
Mißbrauchspunkte gegen einen einzelnen Domainnamen gibt es für:&lt;br /&gt;
* eine Anfrage, die keinen neuen DNS-Eintrag (und keine Änderung oder Löschung eines Eintrags) erfordert, sondern bestehende Merkmale nur wiederholt&lt;br /&gt;
&lt;br /&gt;
Mißbrauchspunkte gegen einen Benutzernamen gibt es für:&lt;br /&gt;
* die Angabe eines Domainnamens, der in der Dienstkonfiguration dem anfragenden Benutzernamen nicht zugeordnet ist&lt;br /&gt;
* die Angabe eines Domainnamen in einer Domain, die nicht demselben Hostsharing-Domain-Admin gehört, der den DDNS-Dienst anbietet&lt;br /&gt;
* die Angabe eines Domainnamens, der in der Dienstkonfiguration bereits wegen mißbräuchlicher Anfragen gesperrt ist (siehe oben)&lt;br /&gt;
&lt;br /&gt;
Um eine Sperrung aufzuheben, wird in der Regel eine Handlung durch den Administrator erforderlich sein.&lt;br /&gt;
&lt;br /&gt;
==== Mehrere dynamische Subdomains in derselben Domain ====&lt;br /&gt;
Sobald zwei verschiedene DDNS-Einträge in derselben Domain verlangt werden &amp;amp;ndash; beispielsweise home.example.com und office.example.com &amp;amp;ndash; wird es notwendig, bei jeder neuen Zonefile für example.com eventuell frühere Einträge zu konservieren. Der Rechner zu Hause weiß beim Bestellen seines DDNS-Eintrags nichts vom Rechner im Büro und umgekehrt. Der Server muß in irgendeiner Form über bereits vergebene Einträge Buch führen und bei einer neuen Anfrage, die example.com betrifft, alle bereits aktiven DDNS-Einträge für example.com mit in die neue Zonefile aufnehmen &amp;amp;ndash auch wenn sie auf Anfragen verschiedener Benutzer zurückgehen.&lt;br /&gt;
&lt;br /&gt;
==== Datenbank ====&lt;br /&gt;
In der Beispielimplementierung werden diese Informationen in einer SQLite-Datenbank gespeichert.&lt;br /&gt;
&lt;br /&gt;
== Sicherheit ==&lt;br /&gt;
=== Rechte ===&lt;br /&gt;
Die &#039;&#039;&#039;Benutzerrechte&#039;&#039;&#039; werden durch das Hostsharing-System kontrolliert. Sowohl das CGI-Programm als auch das [[#Administration|Administrationswerkzeug]] werden mit den Rechten des Domain-Admins (xyz00-benutzername in unserem Beispiel) ausgeführt, also kann dieses Programm nur die Domains bearbeiten, die von xyz00-benutzername verwaltet werden.&lt;br /&gt;
&lt;br /&gt;
=== Authentifizierung ===&lt;br /&gt;
In der Beispielimplementierung (wie auch seinerzeit bei DynDNS.org) wird das CGI-Programm durch einen .htaccess-Eintrag geschützt, der HTTP-Basic-Authentication vorschreibt. Also wird das Programm eigentlich mit einem URL der form&lt;br /&gt;
&lt;br /&gt;
  &amp;lt;nowiki&amp;gt;https://ddnsaccount:passwort@ddns.example.com/cgi-bin/ddns?hostname=...&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
aufgerufen.&lt;br /&gt;
&lt;br /&gt;
=== Verschlüsselung ===&lt;br /&gt;
Das CGI-Programm sollte nur in example.com/cgi-ssl/ installiert werden, nicht in example.com/cgi/. Damit ist die Kommunikation zwischen Client und Server durch SSL verschlüsselt.&lt;br /&gt;
&lt;br /&gt;
== Administration ==&lt;br /&gt;
&lt;br /&gt;
Der Verwalter des DDNS-Programms trägt berechtigte Benutzer und die ihnen zugeteilten Domainnamen in die Datenbank des Programms ein mit Hilfe eines kleinen Hilfsprogramms. Das ist im vorliegenden Fall ein menügesteuertes Programm für die Befehlszeile, daß die naheliegenden Funktionen anbietet: Account hinzufügen, löschen, sperren, entsperren, Paßwort setzen, ändern; Domainnamen hinzufügen, ändern, entsperren, löschen; Accounts und Domainnamen mit aktuellem Status auflisten. Die Funktionen sind auch über Befehlszeilenargumente verfügbar, also skriptfähig.&lt;br /&gt;
&lt;br /&gt;
Eine Übersicht der Funktionen des Administrationswerkzeugs gibt dieses selbst aus:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
xyz00-benutzername@h02:~$ bin/ddnsadmin -h&lt;br /&gt;
ddnsadmin.pl: Verwaltungswerkzeug für ddns&lt;br /&gt;
&lt;br /&gt;
Verwendung:&lt;br /&gt;
    ddnsadmin -A{[ahlusf]} [&amp;lt;Account&amp;gt;] [-f &amp;lt;DB-Datei&amp;gt;]&lt;br /&gt;
    ddnsadmin -D{[ahlsf]} [&amp;lt;Domain&amp;gt;] -A &amp;lt;Account&amp;gt; [-f &amp;lt;DB-Datei&amp;gt;]&lt;br /&gt;
    ddnsadmin -E &amp;lt;Einstellung&amp;gt; &amp;lt;Wert&amp;gt; [-f &amp;lt;DB-Datei&amp;gt;]&lt;br /&gt;
    ddnsadmin [-f &amp;lt;DB-Datei&amp;gt;] [-n]&lt;br /&gt;
&lt;br /&gt;
Wenn keine Option oder nur -f &amp;lt;DB-Datei&amp;gt; angegeben wird, bietet&lt;br /&gt;
ddnsadmin.pl eine interaktive Menüoberfläche.&lt;br /&gt;
&lt;br /&gt;
Optionen:&lt;br /&gt;
    -f &amp;lt;DB-Datei&amp;gt;                    Angegebene Datenbankdatei verwenden&lt;br /&gt;
    -n                               Neue, leere Datenbank erzeugen&lt;br /&gt;
    -Aa  [&amp;lt;Account&amp;gt;]                 Account(s) auflisten&lt;br /&gt;
    -Ah &amp;lt;Account&amp;gt; &amp;lt;Paßwort&amp;gt;          Account hinzufügen&lt;br /&gt;
    -A{lsf} &amp;lt;Account&amp;gt;                Account löschen, sperren, freigeben&lt;br /&gt;
    -Au &amp;lt;Account&amp;gt; &amp;lt;Name&amp;gt;             Account umbenennen&lt;br /&gt;
    -A  &amp;lt;Account&amp;gt; -Da [&amp;lt;Domain&amp;gt;]     Domain(s) auflisten&lt;br /&gt;
    -A  &amp;lt;Account&amp;gt; -D{hlsf} &amp;lt;Domain&amp;gt;  Domain hinzufügen,&lt;br /&gt;
                                     löschen, sperren, freigeben&lt;br /&gt;
    -E &amp;lt;Einstellung&amp;gt; &amp;lt;Wert&amp;gt;          Einstellung ändern&lt;br /&gt;
    -h                               Diese Übersicht ausgeben&lt;br /&gt;
&lt;br /&gt;
Einstellungen: &lt;br /&gt;
    maxacctabuse    Anzahl der mißbräuchlichen Aufrufe,&lt;br /&gt;
                    bevor ein Account gesperrt wird&lt;br /&gt;
    maxhostabuse    Anzahl der mißbräuchlichen Aufrufe,&lt;br /&gt;
                    bevor ein Domainname gesperrt wird&lt;br /&gt;
    safeinterval    Mindestabstand zwischen redundanten Aufrufen&lt;br /&gt;
                    (in Sekunden)&lt;br /&gt;
    cgihost         Server, der das DDNS-Skript bereithält&lt;br /&gt;
&lt;br /&gt;
xyz00-benutzername@h02:~$ &lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Eine Auflistung des momentanen Inhalts der DDNS-Datenbank durch das Administrationswerkzeug könnte beispielsweise so aussehen:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  xyz00-benutzername@h02:~$ bin/ddnsadmin.pl -Aa&lt;br /&gt;
  1.  papst	Mißbrauch: 0; gesperrt: nein&lt;br /&gt;
  	avignon.example.com&lt;br /&gt;
  		zuletzt aktiv am Sun Apr 26 22:24:49 2020&lt;br /&gt;
  		mit IP-Nr. 87.65.43.21; MX: 0;  Backup-MX: nein;&lt;br /&gt;
  		Subdomains: nein; Mißbrauch: 0;  gesperrt: nein&lt;br /&gt;
  	vatican.beispiel.de&lt;br /&gt;
  		zuletzt aktiv am Sun Apr 26 22:24:49 2020&lt;br /&gt;
  		mit IP-Nr. 87.65.43.21; MX: 0;  Backup-MX: nein;&lt;br /&gt;
  		Subdomains: nein; Mißbrauch: 0;  gesperrt: nein&lt;br /&gt;
  2.  kaiser	Mißbrauch: 4; gesperrt: ja&lt;br /&gt;
  	augsburg.beispiel.de&lt;br /&gt;
  		zuletzt aktiv am Fri Apr 24 16:13:49 2020&lt;br /&gt;
  		mit IP-Nr. 64.82.31.75; MX: 0;  Backup-MX: nein;&lt;br /&gt;
  		Subdomains: nein; Mißbrauch: 0;  gesperrt: ja&lt;br /&gt;
  3.  luther	Mißbrauch: 1; gesperrt: nein&lt;br /&gt;
  	wittenberg.example.com&lt;br /&gt;
  		zuletzt aktiv am Mon Apr 27 10:12:49 2020&lt;br /&gt;
  		mit IP-Nr. 78.56.34.12; MX: 0;  Backup-MX: nein;&lt;br /&gt;
  		Subdomains: nein; Mißbrauch: 1;  gesperrt: nein&lt;br /&gt;
  xyz00-benutzername@h02:~$&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Das DDNS-Account &amp;amp;bdquo;kaiser&amp;amp;ldquo; in dieser Auflistung ist wohl auf Grund fehlerhafter Anfragen automatisch gesperrt worden. Der Inhaber wird sich wohl bald melden, um nach Korrektur seiner Client-Konfiguration die Aufhebung der Sperre zu wünschen.&lt;br /&gt;
&lt;br /&gt;
=== Log ===&lt;br /&gt;
Alle Anfragen werden in einer täglich wechselnden Log-Datei protokolliert, entweder schlicht oder ausführlich, je nachdem, ob eine Variable &amp;lt;tt&amp;gt;verbose&amp;lt;/tt&amp;gt; wahr ist.&lt;br /&gt;
Ein ausführlicher Log-Eintrag sieht so aus:&lt;br /&gt;
&lt;br /&gt;
  Sun Apr 26 20:21:45 2020  ddns aufgerufen von papst&lt;br /&gt;
  			unter 84.185.97.8&lt;br /&gt;
  	URL: &amp;lt;nowiki&amp;gt;https://ddns.example.com/cgi-bin/ddns.cgi?hostname=&lt;br /&gt;
  			avignon.example.com,vatican.beispiel.de&amp;amp;&lt;br /&gt;
  			myip=84.185.97.8&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
  	Verwende IP 84.185.97.8 (= 1421435144)&lt;br /&gt;
  	DB-Version: 1&lt;br /&gt;
  	Skript und DB exklusiv geöffnet&lt;br /&gt;
  	avignon.example.com: IP: 84.185.97.8; MX: 0; Backup-MX: nein;&lt;br /&gt;
  			Wildcard: nein; Mißbrauch: 0; gesperrt: nein &lt;br /&gt;
  	vatican.beispiel.de: IP: 84.185.97.8; MX: 0; Backup-MX: nein;&lt;br /&gt;
  			Wildcard: nein; Mißbrauch: 0; gesperrt: nein &lt;br /&gt;
  	Betroffene Zonen: example.com, beispiel.de&lt;br /&gt;
  	Temporärdatei example.com_hxNa.new geschrieben&lt;br /&gt;
  	Zonendatei /home/pacs/xyz00/users/benutzername/doms/example.com/&lt;br /&gt;
  			etc/pri.example.com eingestellt&lt;br /&gt;
  	Temporärdatei beispiel.de_6HcO.new geschrieben&lt;br /&gt;
  	Zonendatei /home/pacs/xyz00/users/benutzername/doms/beispiel.de/&lt;br /&gt;
  			etc/pri.beispiel.de eingestellt&lt;br /&gt;
  	Abgeschlossen: 	Fertig&lt;br /&gt;
&lt;br /&gt;
Wenn &amp;lt;tt&amp;gt;verbose&amp;lt;/tt&amp;gt; auf falsch gesetzt ist, sind die Log-Einträge einzeilig.&lt;/div&gt;</summary>
		<author><name>Apc00-tony</name></author>
	</entry>
	<entry>
		<id>https://wiki.hostsharing.net/index.php?title=Benutzer:Apc00-tony/Dynamisches_DNS&amp;diff=5201</id>
		<title>Benutzer:Apc00-tony/Dynamisches DNS</title>
		<link rel="alternate" type="text/html" href="https://wiki.hostsharing.net/index.php?title=Benutzer:Apc00-tony/Dynamisches_DNS&amp;diff=5201"/>
		<updated>2020-04-29T09:36:50Z</updated>

		<summary type="html">&lt;p&gt;Apc00-tony: /* Mißbrauch und Benutzersperrung */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;((Provisorischer Vorspann: Auf Grund einer Mailing-Listen-Diskussion habe ich angefangen, Dynamisches DNS über einen CGI-Skript bei Hostsharing zu realisieren. Meine Lösung habe ich dann vorgestellt; sie wurde für nicht ausreichend selbsterklärend befunden und fand wenig Akzeptanz. Hier also der Versuch, die Sache zu dokumentieren.))&lt;br /&gt;
&lt;br /&gt;
Mit der regelmäßigen Aufnahme von benutzerspezifischen Zonefiles in seiner DNS-Konfiguration bietet  Hostsharing alles, was man braucht, um &amp;amp;bdquo;dynamisches DNS&amp;amp;ldquo; in Eigenregie zu realisieren.&lt;br /&gt;
&lt;br /&gt;
Das heißt, wenn ich mindestens eine Domain bei Hostsharing verwalte, und mindestens eine Einwahlverbindung (oder DSL-Verbindung) ins Internet mit wechselnder IP-Adresse über irgendeinen ISP für meinen Arbeitsplatzrechner zu Hause betreibe, dann kann ich dem Arbeitsplatzrechner über die DNS-Server von Hostsharing einen vollqualifizieren Domainnamen zuweisen, der der jeweiligen IP-Adresse meiner Einwahlleitung zugeordnet ist.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
(ASCII-Art-Diagramm der beschriebenen Konstellation)&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Im Folgenden wird eine real existierende Implementierung von Dynamischem DNS (&amp;amp;bdquo;DDNS&amp;amp;ldquo;) beschrieben. Die verschiedenen Elemente könnten durchaus anders realisiert werden; die beschriebene Implementierung könnte durchaus verbessert werden. Sie dient hier der Illustration.&lt;br /&gt;
&lt;br /&gt;
In der folgenden Beschreibung werden diese Beispielwerte benutzt:&lt;br /&gt;
* Ein Hostsharing-Mitglied hat ein Account als Paket-Admin mit Kennung xyz00.&lt;br /&gt;
* Im Paket xyz00 gibt es einen Domain-Admin namens xyz00-benutzername.&lt;br /&gt;
* Dieser Domain-Admin verwaltet bei Hostsharing die Domains example.com und beispiel.de.&lt;br /&gt;
* Ein Benutzer hat zu Hause (oder im Büro) einen Arbeitsplatzrechner hinter der marktüblichen DSL-Leitung, die von seinem ISP bereitgestellt wird.&lt;br /&gt;
* Dieser Arbeitsplatzrechner (oder der Router, der seine Internetverbindung steuert) bekommt vom ISP immer wechselnde IP-Adressen zugewiesen.&lt;br /&gt;
* Dennoch möchte der Benutzer seinen Arbeitsplatzrechner aus dem Internet unter dem Hostnamen einwahl.example.com ansprechen können.&lt;br /&gt;
&lt;br /&gt;
Dazu kann ein System wie Hostsharing, das authoritative DNS-Informationen für viele Domains bereitstellt, auch veränderliche DNS-Information über dynamisch verbundene Rechner verwalten &amp;amp;ndash; sofern das ressourcenschonend gemacht werden kann ohne andere Funktionen zu stören.&lt;br /&gt;
&lt;br /&gt;
== Aufgaben des Servers ==&lt;br /&gt;
&lt;br /&gt;
Um einem Rechner mit wechselnder IP-Adresse einen DDNS-Eintrag zu bieten, muß der Hostsharing-Server folgendes leisten (in ungefährer Reihenfolge der Ereignisse):&lt;br /&gt;
&lt;br /&gt;
# Eine Anfrage entgegennehmen, beispielsweise über HTTPS, von einem entfernten Rechner, der einen DNS-Eintrag für seine momentane IP-Adresse wünscht. &lt;br /&gt;
# Prüfen, ob die Anfrage einen berechtigten DDNS-Dienst-Usernamen mit zugehörigem Paßwort enthält.&lt;br /&gt;
# Prüfen, ob die Anfrage einen gültigen Domainnamen betrifft, den der Server bieten darf.&lt;br /&gt;
# Prüfen, ob die Domain example.com demselben Benutzer gehört, unter dessen Namen der Dynamisches-DNS-Server läuft.&lt;br /&gt;
# Eine gültige [[Zonefile]] mit &amp;amp;ndash; neben dem bisherigen Inhalt &amp;amp;ndash; einem A-Eintrag für einwahl.example.com in /home/pacs/xyz00/users/benutzername/doms/example.com/pri.example.com schreiben.&lt;br /&gt;
# Dem Client eine Bestätigung oder ggf. eine Fehlermeldung als Antwort senden.&lt;br /&gt;
# In irgendeiner Datenbank den momentan eingestellter Status all seiner DDNS-Einträge speichern.&lt;br /&gt;
# In einer Logdatei protokollieren, daß obiges getan wurde, oder ggf. welche Fehler traten auf.&lt;br /&gt;
&lt;br /&gt;
== Aufgaben des Clients ==&lt;br /&gt;
Bevor ich anfange, meinen Arbeitsplatzrechner so zu konfigurieren, daß er bei welchem Server auch immer einen DDNS-Eintrag anfordert, muß ich mich als verantwortlicher Benutzer dieses Rechners und der dazugehörigen Internetverbindung &amp;amp;ndash; das heißt, als Mensch &amp;amp;ndash; mit dem Betreiber des dynamisches-DNS-Servers vereinbaren, daß ich das darf und welchen Eintrag ich bekommen kann. Im Folgenden wird vorausgesetzt, daß solche Vereinbarungen getroffen und die Parameter geklärt wurden.&lt;br /&gt;
&lt;br /&gt;
Der DDNS-Client muß aus Server-Sicht nur wenig leisten:&lt;br /&gt;
&lt;br /&gt;
# Eine Anfrage senden, beispielsweise über HTTPS, an einen entfernten Rechner, der einen Eintrag ins DNS für die momentane IP-Adresse des Clients vornehmen kann.&amp;lt;br /&amp;gt;Diese Anfrage muß einem festgelegten Format entsprechen und muß gültige Werte für die Authorisation des Clients, den gewünschten Domainnamen, und eventuell andere Parameter enthalten.&lt;br /&gt;
# Eine Antwort des Servers entgegennehmen und als Erfolgs- oder Fehlermeldung auswerten.&lt;br /&gt;
# Von überflüssigen Anfragen absehen: das heißt bei Erfolg, nicht wiederholt den gleichen Eintrag erneut wünschen; bei Fehlern, nicht die gleiche fehlerhafte Anfrage erneut schicken.&lt;br /&gt;
&lt;br /&gt;
== Kommunikation zwischen Client und Server ==&lt;br /&gt;
&lt;br /&gt;
Ein einziges Nachrichtenpaar von Anfrage und Antwort genügt, um einen DDNS-Eintrag einzurichten: Der Client teilt die IP-Adresse und den Domainnamen mit, die in einem DNS-Eintrag verbunden werden sollen; der Server bestätigt den Auftrag.&lt;br /&gt;
&lt;br /&gt;
In der Beispielimplementierung erfolgt die Kommunikation über HTTP, und die Anfrage des Clients könnte so aussehen:&lt;br /&gt;
&lt;br /&gt;
  GET /cgi-bin/ddns?hostname=einwahl.example.com&amp;amp;myip=87.65.43.21 HTTP/1.1&lt;br /&gt;
  Host: ddns.beispiel.de&lt;br /&gt;
  User-Agent: Fritz!Box DDNS/1.0.1&lt;br /&gt;
  Authorization: Basic QWxhZGRpbjpvcGVuIHNlc2FtZQ==&lt;br /&gt;
&lt;br /&gt;
Bei Erhalt dieser Anfrage ruft Apache das CGI-Programm .../doms/ddns.beispiel.de/cgi-ssl/ddns auf. Das Fragezeichen trennt den Programmnamen von einem &amp;quot;Query-String&amp;quot;, in dem zwei Metavariablen definiert und übergeben werden. Die erste Metavariable, hostname, hat den Wert &amp;quot;einwahl.example.com&amp;quot;; die zweite, myip, hat den Wert &amp;quot;87.65.43.21&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
Das Server-Programm, hier &#039;&#039;ddns&#039;&#039;, prüft diese Informationen auf Form und Berechtigung, und schreibt gegebenenfalls einen entsprechenden Eintrag in einer Zonefile. Es schreibt auch verschiedene Informationen in die Standardausgabe. Wenn es die Standardausgabe geschlossen wird &amp;amp;ndash; also spätestens bei Programmende &amp;amp;ndash; schickt Apache diese Informationen als Antwort an den anfragenden Rechner zurück.&lt;br /&gt;
&lt;br /&gt;
Im Falle unserer Beispielimplementierung sieht die Antwort bei Erfolg so aus: &lt;br /&gt;
&lt;br /&gt;
  HTTP/1.1 200 OK&lt;br /&gt;
  Date: Wed, 22 Apr 2020 08:35:15 GMT&lt;br /&gt;
  Server: Apache&lt;br /&gt;
  Content-Length: 17&lt;br /&gt;
  Content-Type: text/plain; charset=ISO-8859-1&lt;br /&gt;
 &lt;br /&gt;
  good 87.65.43.21&lt;br /&gt;
&lt;br /&gt;
=== Das DDNS-Protokoll von DynDNS.org ===&lt;br /&gt;
&lt;br /&gt;
In den 90er Jahren, bevor das Internet so durchgehend vergeschäftlicht wurde, boten einige Organisationen kostenlose DDNS-Dienste an. Ein sehr beliebtes Angebot war das von DynDNS.org. Das DDNS-Protokoll von diesem Dienst wurde sogar in Einwahl-Routern einprogrammiert und der Dienst wurde von ISPs und Router-Herstellern als Leistungsmerkmal beworben.&lt;br /&gt;
&lt;br /&gt;
DynDNS.org gehört inzwischen Oracle und bietet keine kostenlose Dienste mehr. Dennoch wird das DDNS-Protokoll von DynDNS.org in der vorliegenden Beispielimplementierung übernommen in der Hoffnung, daß die Kompatibilität mit einigen gängigen Einwahl-Routern von Vorteil sein kann. Es gibt noch eine kurze Online-Dokumentation der [https://help.dyn.com/remote-access-api/perform-update/ Anfrage] und [https://help.dyn.com/remote-access-api/perform-update/ Antwortnachrichten].&lt;br /&gt;
&lt;br /&gt;
Das gesammte Protokoll sieht einen einzigen Nachrichtenaustausch aus Anfrage und Antwort vor. Die Anfrage kann mehrere Argumente enthalten; die Antwort kann verschiedene Code-Wörtern enthalten. Übrigens können in einer einzigen Anfrage mehrere DNS-Einträge gewünscht werden. In diesem Fall kann die Antwort mehrzeilig ausfallen.&lt;br /&gt;
&lt;br /&gt;
Das Verhalten von Server und Client bei künftigen Kommunikationsvorgängen wird unter Umständen von vorangegangenen Kommunikationsergebnissen beeinflußt: nach wiederholten fehlerhaften oder redundanten Anfragen kann der Server weitere Anfragen des Benutzers verweigern; nach wiederholten Fehlermeldungen sollte ein Client aufhören, immer dieselbe Anfrage zu schicken. Und für den Fall, daß mehrere Clients dynamische DNS-Einträge in derselben Domain example.com bestellen, muß der Server den Stand aller Client-Einträge intern speichern, damit er nicht mit einer neuen Zonefile einen früher erstellten Eintrag löscht. Zu diesen Fragen siehe den Abschnitt &#039;&#039;&#039;[[#Sukzessive_Kommunikationsabläufe]]&#039;&#039;&#039; nach der Beschreibung von Anfragen und Antworten unten.&lt;br /&gt;
&lt;br /&gt;
====Anfrage====&lt;br /&gt;
&lt;br /&gt;
Die Anfrage in Form eines URL übergibt dem DDNS-Programm in einem &#039;Query-String&#039; einige Metavariablen. Das heißt, in einem URL der Form&lt;br /&gt;
&lt;br /&gt;
  &amp;lt;nowiki&amp;gt;https://benutzername:passwort@ddns.beisiel.de/cgi-bin/ddns?hostname=einwahl.example.com&amp;amp;myip=87.65.43.21&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
signalisert das Fragezeichen, daß ein Query-String folgt. In einem solchen Query-String können in der Beispielimplementierung folgende Metavariablen definiert werden:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|- class=&amp;quot;hintergrundfarbe5&amp;quot;&lt;br /&gt;
! Variable !! Beispiel !! Bemerkungen&lt;br /&gt;
|-&lt;br /&gt;
| hostname || &amp;lt;tt&amp;gt;hostname=einwahl.example.com&amp;lt;/tt&amp;gt;&amp;lt;br /&amp;gt;&amp;lt;div style=&amp;quot;font-size:smaller;&amp;quot;&amp;gt;&amp;lt;tt&amp;gt;hostname=eins.example.com,zwei.example.com[,...]&amp;lt;/tt&amp;gt;&amp;lt;/div&amp;gt; ||&lt;br /&gt;
Muß ein vollständig qualifizierter Domain-Name (&amp;quot;FQDN&amp;quot;) sein; &amp;lt;tt&amp;gt;example.com&amp;lt;/tt&amp;gt; muß eine vom Besitzer des DDNS-Programms verwaltete Domain sein. Genaugenommen kann der Wert eine durch Kommata gegliederte Liste mehrerer gültiger Domainnamen sein, falls mehrere Einträge mit derselben IP-Adresse gewünscht werden.&lt;br /&gt;
|-&lt;br /&gt;
| myip || &amp;lt;tt&amp;gt;myip=87.65.43.21&amp;lt;/tt&amp;gt;||&lt;br /&gt;
Kann entfallen; kann vom Server ignoriert werden. Maßgeblich ist dann die IP-Adresse des Absenders, wie sie vom Web-Server mitgeteilt wird.&lt;br /&gt;
|-&lt;br /&gt;
| mx || &amp;lt;tt&amp;gt;mx=87.65.43.21&amp;lt;/tt&amp;gt;&amp;lt;br /&amp;gt;&amp;lt;tt&amp;gt;mx=NOCHG&amp;lt;/tt&amp;gt;&amp;lt;br /&amp;gt; ||&lt;br /&gt;
Neben dem A-Eintrag möchte der Client auch einen MX-Eintrag. Der Wert &amp;lt;tt&amp;gt;NOCHG&amp;lt;/tt&amp;gt; (für &amp;amp;bdquo;no change&amp;amp;ldquo;) bedeutet, der bestehende MX-Eintrag (oder seine Abwesenheit) soll nicht geändert werden. &lt;br /&gt;
|-&lt;br /&gt;
| backmx || &amp;lt;tt&amp;gt;backmx=YES&amp;lt;/tt&amp;gt;&amp;lt;br /&amp;gt;&amp;lt;tt&amp;gt;backmx=NOCHG&amp;lt;/tt&amp;gt;&amp;lt;br /&amp;gt;&amp;lt;tt&amp;gt;backmx=NO&amp;lt;/tt&amp;gt;   ||&lt;br /&gt;
Falls &amp;lt;tt&amp;gt;YES&amp;lt;/tt&amp;gt;, wird ein zweiter MX-Eintrag erzeugt, der &amp;lt;tt&amp;gt;einwahl.example.com&amp;lt;/tt&amp;gt; als Mail-Server für &amp;lt;tt&amp;gt;einwahl.example.com&amp;lt;/tt&amp;gt; nennt. Dieser Eintrag hat eine niedrigere Präferenzzahl (also eine höhere Priorität) als der mit &amp;lt;tt&amp;gt;mx&amp;lt;/tt&amp;gt; angeforderten Eintrag.&lt;br /&gt;
|-&lt;br /&gt;
| wildcard || &amp;lt;tt&amp;gt;wildcard=ON&amp;lt;/tt&amp;gt;&amp;lt;br /&amp;gt;&amp;lt;tt&amp;gt;wildcard=NOCHG&amp;lt;/tt&amp;gt;&amp;lt;br /&amp;gt;&amp;lt;tt&amp;gt;wildcard=OFF&amp;lt;/tt&amp;gt; ||&lt;br /&gt;
Neben dem A-Eintrag für den Domainnamen &amp;lt;tt&amp;gt;einwahl.example.com&amp;lt;/tt&amp;gt; wünscht der Client auch einen Eintrag für beliebige Subdomains, also &amp;lt;tt&amp;gt;*.einwahl.example.com&amp;lt;/tt&amp;gt;, mit der gleichen IP-Adresse.&lt;br /&gt;
|-&lt;br /&gt;
| offline ||&amp;lt;tt&amp;gt;offline=YES&amp;lt;/tt&amp;gt;&amp;lt;br /&amp;gt;&amp;lt;tt&amp;gt;offline=NOCHG&amp;lt;/tt&amp;gt;||&lt;br /&gt;
Falls &amp;lt;tt&amp;gt;YES&amp;lt;/tt&amp;gt;, wird ein DNS-Eintrag für &amp;lt;tt&amp;gt;einwahl.example.com&amp;lt;/tt&amp;gt; aus der Zonefile getilgt. Gegebenenfalls wird der Hostname dann auf Grund eines parallelen Wildcard-Eintrags für &amp;lt;tt&amp;gt;*.example.com&amp;lt;/tt&amp;gt; einer anderen IP-Adresse zugeordnet werden.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;!-- IPv6? --&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Alle Parameter bis auf hostname können entfallen. Bei nichtdokumentierten Argumenten ist das Verhalten undefiniert&amp;amp;trade;.&lt;br /&gt;
&lt;br /&gt;
====Antwort====&lt;br /&gt;
&lt;br /&gt;
Die Antwort auf eine erfolgreiche HTTP-Anfrage besteht im häufigsten Fall aus einigen Header-Zeilen, gefolgt vom Inhalt der gewünschten Text- oder andere Datei. Ein Status-Code in der ersten Header-Zeile gibt an, ob die Anfrage bedient werden kann oder kreist andernfalls den Grund für die Enttäuschung ein.&lt;br /&gt;
&lt;br /&gt;
Die vorliegende Beispielimplementierung von DDNS schickt einen der üblichen HTTP-Status-Codes &amp;quot;200 OK&amp;quot; oder &amp;quot;500 Internal Server Error&amp;quot;, gefolgt von einer kurzen Textnachricht nach dem HTTP-Header. Bei diesem Programm  ist &amp;amp;ndash; laut Gebrauchshinweise von DynDNS.org &amp;amp;ndash; &#039;&#039;nicht&#039;&#039; der Status-Code im Header, sondern der Inhalt der Nachricht  die definierte, maßgebliche Ergebnismeldung des Programms.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|- class=&amp;quot;hintergrundfarbe5&amp;quot;&lt;br /&gt;
! Meldung !! Bedeutung !! Bemerkungen&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;good&amp;amp;nbsp;&amp;amp;lt;IP&amp;amp;nbsp;number&amp;amp;gt;&amp;lt;/tt&amp;gt; ||&lt;br /&gt;
Der gewünschte DNS-Eintrag wurde erfolgreich in einer Zonefile eingetragen. &lt;br /&gt;
|| Es kann natürlich noch einige Minuten dauern, bis die Zonefile vom Hostsharing-Roboter abgelesen wird und der Inhalt in die BIND-Konfiguration übernommen.&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;good&amp;amp;nbsp;0.0.0.0&amp;lt;/tt&amp;gt; ||&lt;br /&gt;
Das Argument &amp;lt;tt&amp;gt;offline=YES&amp;lt;/tt&amp;gt; wurde empfangen und verarbeitet.&lt;br /&gt;
|| Der Domainname hat also keinen dynamischen DNS-Eintrag mehr.&lt;br /&gt;
|-&lt;br /&gt;
&amp;lt;!-- We don&#039;t do this!&lt;br /&gt;
| &amp;lt;tt&amp;gt;good&amp;amp;nbsp;127.0.0.1&amp;lt;/tt&amp;gt; ||&lt;br /&gt;
Die Anfrage entsprach nicht den Erfordernissen des Servers.&lt;br /&gt;
|| Trotz des Worts &amp;lt;tt&amp;gt;good&amp;lt;/tt&amp;gt; war die Anfrage nicht erfolgreich, falls in der Rückmeldung die IP-Adresse mit &amp;lt;tt&amp;gt;127.0.0.1&amp;lt;/tt&amp;gt; angegeben wird. Dieser verwirrende Fehlercode ist aus unerklärlichen Gründen in der Spezifikation von DynDNS.org so definiert.&lt;br /&gt;
|-&lt;br /&gt;
--&amp;gt;&lt;br /&gt;
| &amp;lt;tt&amp;gt;nochg&amp;amp;nbsp;&amp;amp;lt;IP&amp;amp;nbsp;number&amp;amp;gt;&amp;lt;/tt&amp;gt; ||&lt;br /&gt;
Der gewünschte DNS-Eintrag war bereits vorhanden. &lt;br /&gt;
|| Der Server selbst macht keine DNS-Abfrage, um das zu vermitteln: die &amp;amp;bdquo;no change&amp;amp;ldquo;-Antwort besagt nur, daß eine Anfrage für diesen Eintrag bereits mit Erfolg quittiert wurde.&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;notfqdn&amp;lt;/tt&amp;gt; ||&lt;br /&gt;
Fehlschlag: der gewünschte Domainname ist nicht gültig, oder es wurde keiner angegeben.&lt;br /&gt;
|| ...&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;nohost&amp;lt;/tt&amp;gt; ||&lt;br /&gt;
Fehlschlag: der gewünschte Domainname ist gehört nicht zu denen, die für diesen Benutzer des DDNS-Dienstes konfiguriert sind.&lt;br /&gt;
|| Siehe den Abschnitt [[#Administration|Administration]] weiter unten.&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;badauth&amp;lt;/tt&amp;gt; ||&lt;br /&gt;
Fehlschlag: Die Kombination von Benutzernamen und Paßwort entsprach keinem DDNS-Account, oder das Account ist momentan gesperrt.&lt;br /&gt;
|| Ein gesperrtes Account kann nur der Domain-Admin mittels des Administrationswerkzeugs wieder freigeben: siehe den Abschnit [[#Administration|Administration]] weiter unten.&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;abuse&amp;lt;/tt&amp;gt; ||&lt;br /&gt;
Fehlschlag: der gewünschte Domainname ist wegen vorangeganger Fehlschläge oder überflüssiger Aufrufe gesperrt.&lt;br /&gt;
|| Siehe den Abschnitt [[#Sukzessive_Kommunikationsabläufe|Sukzessive Kommunikationsabläufe]] unten.&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;911&amp;lt;/tt&amp;gt; ||&lt;br /&gt;
Fehlschlag: Das Server-Programm hat einen internen Fehler festgestellt.&lt;br /&gt;
|| Das Problem liegt nicht in der Anfrage an sich.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Man kann sich durchaus eine sinnreichere Kommunikation zwischen Client und Server vorstellen, doch das hier beschriebene Protokoll ist eben von DynDNS.org verwendet worden und wird in gängigen Routern implementiert, also wird es in der vorliegenden DDNS-Implementierung nachgebildet.&lt;br /&gt;
&lt;br /&gt;
=== Sukzessive Kommunikationsabläufe ===&lt;br /&gt;
Der Server muß sich zwischen einzelnen Aufrufen einiges merken, um Ressourcen zu schonen und um zu verhindern, daß einmal vergebene DDNS-Einträge von neuen Anfragen, die dieselbe übergeordnete Domain betreffen, durch Überschreiben  verlorengehen.&lt;br /&gt;
&lt;br /&gt;
==== Mißbrauch und Benutzersperrung ====&lt;br /&gt;
Zur Schonung von Ressourcen muß sich die Implementierung weigern, sich mit zuvielen fehlerhaften oder auch nur überflüssigen Anfragen zu beschäftigen. Dazu führt der Server eine Strichliste über solche Anfragen jedes Clients und sperrt nach einer bestimmten Anzahl solcher Anfragen den Benutzernamen oder einzelne Domainnamen gegen die weitere Nutzung des Dienstes.&lt;br /&gt;
&lt;br /&gt;
Mißbrauchspunkte gegen einen einzelnen Domainnamen gibt es für:&lt;br /&gt;
* eine Anfrage, die keinen neuen DNS-Eintrag (und keine Änderung oder Löschung eines Eintrags) erfordert, sondern bestehende Merkmale nur wiederholt&lt;br /&gt;
&lt;br /&gt;
Mißbrauchspunkte gegen einen Benutzernamen gibt es für:&lt;br /&gt;
* die Angabe eines Domainnamens, der in der Dienstkonfiguration dem anfragenden Benutzernamen nicht zugeordnet ist&lt;br /&gt;
* die Angabe eines Domainnamen in einer Domain, die nicht demselben Hostsharing-Domain-Admin gehört, der den DDNS-Dienst anbietet&lt;br /&gt;
* die Angabe eines Domainnamens, der in der Dienstkonfiguration bereits wegen mißbräuchlicher Anfragen gesperrt ist (siehe oben)&lt;br /&gt;
&lt;br /&gt;
Um eine Sperrung aufzuheben, wird in der Regel eine Handlung durch den Administrator erforderlich sein.&lt;br /&gt;
&lt;br /&gt;
==== Mehrere dynamische Subdomains in derselben Domain ====&lt;br /&gt;
Sobald zwei verschiedene DDNS-Einträge in derselben Domain verlangt werden &amp;amp;ndash; beispielsweise home.example.com und office.example.com &amp;amp;ndash; wird es notwendig, bei jeder neuen Zonefile für example.com eventuell frühere Einträge zu konservieren. Der Rechner zu Hause weiß beim Bestellen seines DDNS-Eintrags nichts vom Rechner im Büro und umgekehrt. Der Server muß in irgendeiner Form über bereits vergebene Einträge Buch führen und bei einer neuen Anfrage, die example.com betrifft, alle bereits aktiven DDNS-Einträge für example.com mit in die neue Zonefile aufnehmen &amp;amp;ndash auch wenn sie auf Anfragen verschiedener Benutzer zurückgehen.&lt;br /&gt;
&lt;br /&gt;
==== Datenbank ====&lt;br /&gt;
In der Beispielimplementierung werden diese Informationen in einer SQLite-Datenbank gespeichert.&lt;br /&gt;
&lt;br /&gt;
== Sicherheit ==&lt;br /&gt;
=== Rechte ===&lt;br /&gt;
Die &#039;&#039;&#039;Benutzerrechte&#039;&#039;&#039; werden durch das Hostsharing-System kontrolliert. Sowohl das CGI-Programm als auch das [[#Administration|Administrationswerkzeug]] werden mit den Rechten des Domain-Admins (xyz00-benutzername in unserem Beispiel) ausgeführt, also kann dieses Programm nur die Domains bearbeiten, die von xyz00-benutzername verwaltet werden.&lt;br /&gt;
&lt;br /&gt;
=== Authentifizierung ===&lt;br /&gt;
In der Beispielimplementierung (wie auch seinerzeit bei DynDNS.org) wird das CGI-Programm durch einen .htaccess-Eintrag geschützt, der HTTP-Basic-Authentication vorschreibt. Also wird das Programm eigentlich mit einem URL der form&lt;br /&gt;
&lt;br /&gt;
  &amp;lt;nowiki&amp;gt;https://ddnsaccount:passwort@ddns.example.com/cgi-bin/ddns?hostname=...&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
aufgerufen.&lt;br /&gt;
&lt;br /&gt;
=== Verschlüsselung ===&lt;br /&gt;
Das CGI-Programm sollte nur in example.com/cgi-ssl/ installiert werden, nicht in example.com/cgi/. Damit ist die Kommunikation zwischen Client und Server durch SSL verschlüsselt.&lt;br /&gt;
&lt;br /&gt;
== Administration ==&lt;br /&gt;
&lt;br /&gt;
Der Verwalter des DDNS-Programms trägt berechtigte Benutzer und die ihnen zugeteilten Domainnamen in die Datenbank des Programms ein mit Hilfe eines kleinen Hilfsprogramms. Das ist im vorliegenden Fall ein menügesteuertes Programm für die Befehlszeile, daß die naheliegenden Funktionen anbietet: Account hinzufügen, löschen, sperren, entsperren, Paßwort setzen, ändern; Domainnamen hinzufügen, ändern, entsperren, löschen; Accounts und Domainnamen mit aktuellem Status auflisten. Die Funktionen sind auch über Befehlszeilenargumente verfügbar, also skriptfähig.&lt;br /&gt;
&lt;br /&gt;
Eine Auflistung des momentanen Inhalts der DDNS-Datenbank durch das Administrationswerkzeug könnte beispielsweise so aussehen:&lt;br /&gt;
&lt;br /&gt;
  xyz00-benutzername@h02:~$ bin/ddnsadmin.pl -Aa&lt;br /&gt;
  1.  papst	Mißbrauch: 0; gesperrt: nein&lt;br /&gt;
  	avignon.example.com&lt;br /&gt;
  		zuletzt aktiv am Sun Apr 26 22:24:49 2020&lt;br /&gt;
  		mit IP-Nr. 87.65.43.21; MX: 0;  Backup-MX: nein;&lt;br /&gt;
  		Subdomains: nein; Mißbrauch: 0;  gesperrt: nein&lt;br /&gt;
  	vatican.beispiel.de&lt;br /&gt;
  		zuletzt aktiv am Sun Apr 26 22:24:49 2020&lt;br /&gt;
  		mit IP-Nr. 87.65.43.21; MX: 0;  Backup-MX: nein;&lt;br /&gt;
  		Subdomains: nein; Mißbrauch: 0;  gesperrt: nein&lt;br /&gt;
  2.  kaiser	Mißbrauch: 4; gesperrt: ja&lt;br /&gt;
  	augsburg.beispiel.de&lt;br /&gt;
  		zuletzt aktiv am Fri Apr 24 16:13:49 2020&lt;br /&gt;
  		mit IP-Nr. 64.82.31.75; MX: 0;  Backup-MX: nein;&lt;br /&gt;
  		Subdomains: nein; Mißbrauch: 0;  gesperrt: ja&lt;br /&gt;
  3.  luther	Mißbrauch: 1; gesperrt: nein&lt;br /&gt;
  	wittenberg.example.com&lt;br /&gt;
  		zuletzt aktiv am Mon Apr 27 10:12:49 2020&lt;br /&gt;
  		mit IP-Nr. 78.56.34.12; MX: 0;  Backup-MX: nein;&lt;br /&gt;
  		Subdomains: nein; Mißbrauch: 1;  gesperrt: nein&lt;br /&gt;
  xyz00-benutzername@h02:~$&lt;br /&gt;
&lt;br /&gt;
Das DDNS-Account &amp;amp;bdquo;kaiser&amp;amp;ldquo; in dieser Auflistung ist wohl auf Grund fehlerhafter Anfragen automatisch gesperrt worden. Der Inhaber wird sich wohl bald melden, um nach Korrektur seiner Client-Konfiguration die Aufhebung der Sperre zu wünschen.&lt;br /&gt;
&lt;br /&gt;
=== Log ===&lt;br /&gt;
Alle Anfragen werden in einer täglich wechselnden Log-Datei protokolliert, entweder schlicht oder ausführlich, je nachdem, ob eine Variable &amp;lt;tt&amp;gt;verbose&amp;lt;/tt&amp;gt; wahr ist.&lt;br /&gt;
Ein ausführlicher Log-Eintrag sieht so aus:&lt;br /&gt;
&lt;br /&gt;
  Sun Apr 26 20:21:45 2020  ddns aufgerufen von papst&lt;br /&gt;
  			unter 84.185.97.8&lt;br /&gt;
  	URL: &amp;lt;nowiki&amp;gt;https://ddns.example.com/cgi-bin/ddns.cgi?hostname=&lt;br /&gt;
  			avignon.example.com,vatican.beispiel.de&amp;amp;&lt;br /&gt;
  			myip=84.185.97.8&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
  	Verwende IP 84.185.97.8 (= 1421435144)&lt;br /&gt;
  	DB-Version: 1&lt;br /&gt;
  	Skript und DB exklusiv geöffnet&lt;br /&gt;
  	avignon.example.com: IP: 84.185.97.8; MX: 0; Backup-MX: nein;&lt;br /&gt;
  			Wildcard: nein; Mißbrauch: 0; gesperrt: nein &lt;br /&gt;
  	vatican.beispiel.de: IP: 84.185.97.8; MX: 0; Backup-MX: nein;&lt;br /&gt;
  			Wildcard: nein; Mißbrauch: 0; gesperrt: nein &lt;br /&gt;
  	Betroffene Zonen: example.com, beispiel.de&lt;br /&gt;
  	Temporärdatei example.com_hxNa.new geschrieben&lt;br /&gt;
  	Zonendatei /home/pacs/xyz00/users/benutzername/doms/example.com/&lt;br /&gt;
  			etc/pri.example.com eingestellt&lt;br /&gt;
  	Temporärdatei beispiel.de_6HcO.new geschrieben&lt;br /&gt;
  	Zonendatei /home/pacs/xyz00/users/benutzername/doms/beispiel.de/&lt;br /&gt;
  			etc/pri.beispiel.de eingestellt&lt;br /&gt;
  	Abgeschlossen: 	Fertig&lt;br /&gt;
&lt;br /&gt;
Wenn &amp;lt;tt&amp;gt;verbose&amp;lt;/tt&amp;gt; auf falsch gesetzt ist, sind die Log-Einträge einzeilig.&lt;/div&gt;</summary>
		<author><name>Apc00-tony</name></author>
	</entry>
	<entry>
		<id>https://wiki.hostsharing.net/index.php?title=Benutzer:Apc00-tony/Dynamisches_DNS&amp;diff=5200</id>
		<title>Benutzer:Apc00-tony/Dynamisches DNS</title>
		<link rel="alternate" type="text/html" href="https://wiki.hostsharing.net/index.php?title=Benutzer:Apc00-tony/Dynamisches_DNS&amp;diff=5200"/>
		<updated>2020-04-29T09:35:24Z</updated>

		<summary type="html">&lt;p&gt;Apc00-tony: /* Antwort */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;((Provisorischer Vorspann: Auf Grund einer Mailing-Listen-Diskussion habe ich angefangen, Dynamisches DNS über einen CGI-Skript bei Hostsharing zu realisieren. Meine Lösung habe ich dann vorgestellt; sie wurde für nicht ausreichend selbsterklärend befunden und fand wenig Akzeptanz. Hier also der Versuch, die Sache zu dokumentieren.))&lt;br /&gt;
&lt;br /&gt;
Mit der regelmäßigen Aufnahme von benutzerspezifischen Zonefiles in seiner DNS-Konfiguration bietet  Hostsharing alles, was man braucht, um &amp;amp;bdquo;dynamisches DNS&amp;amp;ldquo; in Eigenregie zu realisieren.&lt;br /&gt;
&lt;br /&gt;
Das heißt, wenn ich mindestens eine Domain bei Hostsharing verwalte, und mindestens eine Einwahlverbindung (oder DSL-Verbindung) ins Internet mit wechselnder IP-Adresse über irgendeinen ISP für meinen Arbeitsplatzrechner zu Hause betreibe, dann kann ich dem Arbeitsplatzrechner über die DNS-Server von Hostsharing einen vollqualifizieren Domainnamen zuweisen, der der jeweiligen IP-Adresse meiner Einwahlleitung zugeordnet ist.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
(ASCII-Art-Diagramm der beschriebenen Konstellation)&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Im Folgenden wird eine real existierende Implementierung von Dynamischem DNS (&amp;amp;bdquo;DDNS&amp;amp;ldquo;) beschrieben. Die verschiedenen Elemente könnten durchaus anders realisiert werden; die beschriebene Implementierung könnte durchaus verbessert werden. Sie dient hier der Illustration.&lt;br /&gt;
&lt;br /&gt;
In der folgenden Beschreibung werden diese Beispielwerte benutzt:&lt;br /&gt;
* Ein Hostsharing-Mitglied hat ein Account als Paket-Admin mit Kennung xyz00.&lt;br /&gt;
* Im Paket xyz00 gibt es einen Domain-Admin namens xyz00-benutzername.&lt;br /&gt;
* Dieser Domain-Admin verwaltet bei Hostsharing die Domains example.com und beispiel.de.&lt;br /&gt;
* Ein Benutzer hat zu Hause (oder im Büro) einen Arbeitsplatzrechner hinter der marktüblichen DSL-Leitung, die von seinem ISP bereitgestellt wird.&lt;br /&gt;
* Dieser Arbeitsplatzrechner (oder der Router, der seine Internetverbindung steuert) bekommt vom ISP immer wechselnde IP-Adressen zugewiesen.&lt;br /&gt;
* Dennoch möchte der Benutzer seinen Arbeitsplatzrechner aus dem Internet unter dem Hostnamen einwahl.example.com ansprechen können.&lt;br /&gt;
&lt;br /&gt;
Dazu kann ein System wie Hostsharing, das authoritative DNS-Informationen für viele Domains bereitstellt, auch veränderliche DNS-Information über dynamisch verbundene Rechner verwalten &amp;amp;ndash; sofern das ressourcenschonend gemacht werden kann ohne andere Funktionen zu stören.&lt;br /&gt;
&lt;br /&gt;
== Aufgaben des Servers ==&lt;br /&gt;
&lt;br /&gt;
Um einem Rechner mit wechselnder IP-Adresse einen DDNS-Eintrag zu bieten, muß der Hostsharing-Server folgendes leisten (in ungefährer Reihenfolge der Ereignisse):&lt;br /&gt;
&lt;br /&gt;
# Eine Anfrage entgegennehmen, beispielsweise über HTTPS, von einem entfernten Rechner, der einen DNS-Eintrag für seine momentane IP-Adresse wünscht. &lt;br /&gt;
# Prüfen, ob die Anfrage einen berechtigten DDNS-Dienst-Usernamen mit zugehörigem Paßwort enthält.&lt;br /&gt;
# Prüfen, ob die Anfrage einen gültigen Domainnamen betrifft, den der Server bieten darf.&lt;br /&gt;
# Prüfen, ob die Domain example.com demselben Benutzer gehört, unter dessen Namen der Dynamisches-DNS-Server läuft.&lt;br /&gt;
# Eine gültige [[Zonefile]] mit &amp;amp;ndash; neben dem bisherigen Inhalt &amp;amp;ndash; einem A-Eintrag für einwahl.example.com in /home/pacs/xyz00/users/benutzername/doms/example.com/pri.example.com schreiben.&lt;br /&gt;
# Dem Client eine Bestätigung oder ggf. eine Fehlermeldung als Antwort senden.&lt;br /&gt;
# In irgendeiner Datenbank den momentan eingestellter Status all seiner DDNS-Einträge speichern.&lt;br /&gt;
# In einer Logdatei protokollieren, daß obiges getan wurde, oder ggf. welche Fehler traten auf.&lt;br /&gt;
&lt;br /&gt;
== Aufgaben des Clients ==&lt;br /&gt;
Bevor ich anfange, meinen Arbeitsplatzrechner so zu konfigurieren, daß er bei welchem Server auch immer einen DDNS-Eintrag anfordert, muß ich mich als verantwortlicher Benutzer dieses Rechners und der dazugehörigen Internetverbindung &amp;amp;ndash; das heißt, als Mensch &amp;amp;ndash; mit dem Betreiber des dynamisches-DNS-Servers vereinbaren, daß ich das darf und welchen Eintrag ich bekommen kann. Im Folgenden wird vorausgesetzt, daß solche Vereinbarungen getroffen und die Parameter geklärt wurden.&lt;br /&gt;
&lt;br /&gt;
Der DDNS-Client muß aus Server-Sicht nur wenig leisten:&lt;br /&gt;
&lt;br /&gt;
# Eine Anfrage senden, beispielsweise über HTTPS, an einen entfernten Rechner, der einen Eintrag ins DNS für die momentane IP-Adresse des Clients vornehmen kann.&amp;lt;br /&amp;gt;Diese Anfrage muß einem festgelegten Format entsprechen und muß gültige Werte für die Authorisation des Clients, den gewünschten Domainnamen, und eventuell andere Parameter enthalten.&lt;br /&gt;
# Eine Antwort des Servers entgegennehmen und als Erfolgs- oder Fehlermeldung auswerten.&lt;br /&gt;
# Von überflüssigen Anfragen absehen: das heißt bei Erfolg, nicht wiederholt den gleichen Eintrag erneut wünschen; bei Fehlern, nicht die gleiche fehlerhafte Anfrage erneut schicken.&lt;br /&gt;
&lt;br /&gt;
== Kommunikation zwischen Client und Server ==&lt;br /&gt;
&lt;br /&gt;
Ein einziges Nachrichtenpaar von Anfrage und Antwort genügt, um einen DDNS-Eintrag einzurichten: Der Client teilt die IP-Adresse und den Domainnamen mit, die in einem DNS-Eintrag verbunden werden sollen; der Server bestätigt den Auftrag.&lt;br /&gt;
&lt;br /&gt;
In der Beispielimplementierung erfolgt die Kommunikation über HTTP, und die Anfrage des Clients könnte so aussehen:&lt;br /&gt;
&lt;br /&gt;
  GET /cgi-bin/ddns?hostname=einwahl.example.com&amp;amp;myip=87.65.43.21 HTTP/1.1&lt;br /&gt;
  Host: ddns.beispiel.de&lt;br /&gt;
  User-Agent: Fritz!Box DDNS/1.0.1&lt;br /&gt;
  Authorization: Basic QWxhZGRpbjpvcGVuIHNlc2FtZQ==&lt;br /&gt;
&lt;br /&gt;
Bei Erhalt dieser Anfrage ruft Apache das CGI-Programm .../doms/ddns.beispiel.de/cgi-ssl/ddns auf. Das Fragezeichen trennt den Programmnamen von einem &amp;quot;Query-String&amp;quot;, in dem zwei Metavariablen definiert und übergeben werden. Die erste Metavariable, hostname, hat den Wert &amp;quot;einwahl.example.com&amp;quot;; die zweite, myip, hat den Wert &amp;quot;87.65.43.21&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
Das Server-Programm, hier &#039;&#039;ddns&#039;&#039;, prüft diese Informationen auf Form und Berechtigung, und schreibt gegebenenfalls einen entsprechenden Eintrag in einer Zonefile. Es schreibt auch verschiedene Informationen in die Standardausgabe. Wenn es die Standardausgabe geschlossen wird &amp;amp;ndash; also spätestens bei Programmende &amp;amp;ndash; schickt Apache diese Informationen als Antwort an den anfragenden Rechner zurück.&lt;br /&gt;
&lt;br /&gt;
Im Falle unserer Beispielimplementierung sieht die Antwort bei Erfolg so aus: &lt;br /&gt;
&lt;br /&gt;
  HTTP/1.1 200 OK&lt;br /&gt;
  Date: Wed, 22 Apr 2020 08:35:15 GMT&lt;br /&gt;
  Server: Apache&lt;br /&gt;
  Content-Length: 17&lt;br /&gt;
  Content-Type: text/plain; charset=ISO-8859-1&lt;br /&gt;
 &lt;br /&gt;
  good 87.65.43.21&lt;br /&gt;
&lt;br /&gt;
=== Das DDNS-Protokoll von DynDNS.org ===&lt;br /&gt;
&lt;br /&gt;
In den 90er Jahren, bevor das Internet so durchgehend vergeschäftlicht wurde, boten einige Organisationen kostenlose DDNS-Dienste an. Ein sehr beliebtes Angebot war das von DynDNS.org. Das DDNS-Protokoll von diesem Dienst wurde sogar in Einwahl-Routern einprogrammiert und der Dienst wurde von ISPs und Router-Herstellern als Leistungsmerkmal beworben.&lt;br /&gt;
&lt;br /&gt;
DynDNS.org gehört inzwischen Oracle und bietet keine kostenlose Dienste mehr. Dennoch wird das DDNS-Protokoll von DynDNS.org in der vorliegenden Beispielimplementierung übernommen in der Hoffnung, daß die Kompatibilität mit einigen gängigen Einwahl-Routern von Vorteil sein kann. Es gibt noch eine kurze Online-Dokumentation der [https://help.dyn.com/remote-access-api/perform-update/ Anfrage] und [https://help.dyn.com/remote-access-api/perform-update/ Antwortnachrichten].&lt;br /&gt;
&lt;br /&gt;
Das gesammte Protokoll sieht einen einzigen Nachrichtenaustausch aus Anfrage und Antwort vor. Die Anfrage kann mehrere Argumente enthalten; die Antwort kann verschiedene Code-Wörtern enthalten. Übrigens können in einer einzigen Anfrage mehrere DNS-Einträge gewünscht werden. In diesem Fall kann die Antwort mehrzeilig ausfallen.&lt;br /&gt;
&lt;br /&gt;
Das Verhalten von Server und Client bei künftigen Kommunikationsvorgängen wird unter Umständen von vorangegangenen Kommunikationsergebnissen beeinflußt: nach wiederholten fehlerhaften oder redundanten Anfragen kann der Server weitere Anfragen des Benutzers verweigern; nach wiederholten Fehlermeldungen sollte ein Client aufhören, immer dieselbe Anfrage zu schicken. Und für den Fall, daß mehrere Clients dynamische DNS-Einträge in derselben Domain example.com bestellen, muß der Server den Stand aller Client-Einträge intern speichern, damit er nicht mit einer neuen Zonefile einen früher erstellten Eintrag löscht. Zu diesen Fragen siehe den Abschnitt &#039;&#039;&#039;[[#Sukzessive_Kommunikationsabläufe]]&#039;&#039;&#039; nach der Beschreibung von Anfragen und Antworten unten.&lt;br /&gt;
&lt;br /&gt;
====Anfrage====&lt;br /&gt;
&lt;br /&gt;
Die Anfrage in Form eines URL übergibt dem DDNS-Programm in einem &#039;Query-String&#039; einige Metavariablen. Das heißt, in einem URL der Form&lt;br /&gt;
&lt;br /&gt;
  &amp;lt;nowiki&amp;gt;https://benutzername:passwort@ddns.beisiel.de/cgi-bin/ddns?hostname=einwahl.example.com&amp;amp;myip=87.65.43.21&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
signalisert das Fragezeichen, daß ein Query-String folgt. In einem solchen Query-String können in der Beispielimplementierung folgende Metavariablen definiert werden:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|- class=&amp;quot;hintergrundfarbe5&amp;quot;&lt;br /&gt;
! Variable !! Beispiel !! Bemerkungen&lt;br /&gt;
|-&lt;br /&gt;
| hostname || &amp;lt;tt&amp;gt;hostname=einwahl.example.com&amp;lt;/tt&amp;gt;&amp;lt;br /&amp;gt;&amp;lt;div style=&amp;quot;font-size:smaller;&amp;quot;&amp;gt;&amp;lt;tt&amp;gt;hostname=eins.example.com,zwei.example.com[,...]&amp;lt;/tt&amp;gt;&amp;lt;/div&amp;gt; ||&lt;br /&gt;
Muß ein vollständig qualifizierter Domain-Name (&amp;quot;FQDN&amp;quot;) sein; &amp;lt;tt&amp;gt;example.com&amp;lt;/tt&amp;gt; muß eine vom Besitzer des DDNS-Programms verwaltete Domain sein. Genaugenommen kann der Wert eine durch Kommata gegliederte Liste mehrerer gültiger Domainnamen sein, falls mehrere Einträge mit derselben IP-Adresse gewünscht werden.&lt;br /&gt;
|-&lt;br /&gt;
| myip || &amp;lt;tt&amp;gt;myip=87.65.43.21&amp;lt;/tt&amp;gt;||&lt;br /&gt;
Kann entfallen; kann vom Server ignoriert werden. Maßgeblich ist dann die IP-Adresse des Absenders, wie sie vom Web-Server mitgeteilt wird.&lt;br /&gt;
|-&lt;br /&gt;
| mx || &amp;lt;tt&amp;gt;mx=87.65.43.21&amp;lt;/tt&amp;gt;&amp;lt;br /&amp;gt;&amp;lt;tt&amp;gt;mx=NOCHG&amp;lt;/tt&amp;gt;&amp;lt;br /&amp;gt; ||&lt;br /&gt;
Neben dem A-Eintrag möchte der Client auch einen MX-Eintrag. Der Wert &amp;lt;tt&amp;gt;NOCHG&amp;lt;/tt&amp;gt; (für &amp;amp;bdquo;no change&amp;amp;ldquo;) bedeutet, der bestehende MX-Eintrag (oder seine Abwesenheit) soll nicht geändert werden. &lt;br /&gt;
|-&lt;br /&gt;
| backmx || &amp;lt;tt&amp;gt;backmx=YES&amp;lt;/tt&amp;gt;&amp;lt;br /&amp;gt;&amp;lt;tt&amp;gt;backmx=NOCHG&amp;lt;/tt&amp;gt;&amp;lt;br /&amp;gt;&amp;lt;tt&amp;gt;backmx=NO&amp;lt;/tt&amp;gt;   ||&lt;br /&gt;
Falls &amp;lt;tt&amp;gt;YES&amp;lt;/tt&amp;gt;, wird ein zweiter MX-Eintrag erzeugt, der &amp;lt;tt&amp;gt;einwahl.example.com&amp;lt;/tt&amp;gt; als Mail-Server für &amp;lt;tt&amp;gt;einwahl.example.com&amp;lt;/tt&amp;gt; nennt. Dieser Eintrag hat eine niedrigere Präferenzzahl (also eine höhere Priorität) als der mit &amp;lt;tt&amp;gt;mx&amp;lt;/tt&amp;gt; angeforderten Eintrag.&lt;br /&gt;
|-&lt;br /&gt;
| wildcard || &amp;lt;tt&amp;gt;wildcard=ON&amp;lt;/tt&amp;gt;&amp;lt;br /&amp;gt;&amp;lt;tt&amp;gt;wildcard=NOCHG&amp;lt;/tt&amp;gt;&amp;lt;br /&amp;gt;&amp;lt;tt&amp;gt;wildcard=OFF&amp;lt;/tt&amp;gt; ||&lt;br /&gt;
Neben dem A-Eintrag für den Domainnamen &amp;lt;tt&amp;gt;einwahl.example.com&amp;lt;/tt&amp;gt; wünscht der Client auch einen Eintrag für beliebige Subdomains, also &amp;lt;tt&amp;gt;*.einwahl.example.com&amp;lt;/tt&amp;gt;, mit der gleichen IP-Adresse.&lt;br /&gt;
|-&lt;br /&gt;
| offline ||&amp;lt;tt&amp;gt;offline=YES&amp;lt;/tt&amp;gt;&amp;lt;br /&amp;gt;&amp;lt;tt&amp;gt;offline=NOCHG&amp;lt;/tt&amp;gt;||&lt;br /&gt;
Falls &amp;lt;tt&amp;gt;YES&amp;lt;/tt&amp;gt;, wird ein DNS-Eintrag für &amp;lt;tt&amp;gt;einwahl.example.com&amp;lt;/tt&amp;gt; aus der Zonefile getilgt. Gegebenenfalls wird der Hostname dann auf Grund eines parallelen Wildcard-Eintrags für &amp;lt;tt&amp;gt;*.example.com&amp;lt;/tt&amp;gt; einer anderen IP-Adresse zugeordnet werden.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;!-- IPv6? --&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Alle Parameter bis auf hostname können entfallen. Bei nichtdokumentierten Argumenten ist das Verhalten undefiniert&amp;amp;trade;.&lt;br /&gt;
&lt;br /&gt;
====Antwort====&lt;br /&gt;
&lt;br /&gt;
Die Antwort auf eine erfolgreiche HTTP-Anfrage besteht im häufigsten Fall aus einigen Header-Zeilen, gefolgt vom Inhalt der gewünschten Text- oder andere Datei. Ein Status-Code in der ersten Header-Zeile gibt an, ob die Anfrage bedient werden kann oder kreist andernfalls den Grund für die Enttäuschung ein.&lt;br /&gt;
&lt;br /&gt;
Die vorliegende Beispielimplementierung von DDNS schickt einen der üblichen HTTP-Status-Codes &amp;quot;200 OK&amp;quot; oder &amp;quot;500 Internal Server Error&amp;quot;, gefolgt von einer kurzen Textnachricht nach dem HTTP-Header. Bei diesem Programm  ist &amp;amp;ndash; laut Gebrauchshinweise von DynDNS.org &amp;amp;ndash; &#039;&#039;nicht&#039;&#039; der Status-Code im Header, sondern der Inhalt der Nachricht  die definierte, maßgebliche Ergebnismeldung des Programms.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|- class=&amp;quot;hintergrundfarbe5&amp;quot;&lt;br /&gt;
! Meldung !! Bedeutung !! Bemerkungen&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;good&amp;amp;nbsp;&amp;amp;lt;IP&amp;amp;nbsp;number&amp;amp;gt;&amp;lt;/tt&amp;gt; ||&lt;br /&gt;
Der gewünschte DNS-Eintrag wurde erfolgreich in einer Zonefile eingetragen. &lt;br /&gt;
|| Es kann natürlich noch einige Minuten dauern, bis die Zonefile vom Hostsharing-Roboter abgelesen wird und der Inhalt in die BIND-Konfiguration übernommen.&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;good&amp;amp;nbsp;0.0.0.0&amp;lt;/tt&amp;gt; ||&lt;br /&gt;
Das Argument &amp;lt;tt&amp;gt;offline=YES&amp;lt;/tt&amp;gt; wurde empfangen und verarbeitet.&lt;br /&gt;
|| Der Domainname hat also keinen dynamischen DNS-Eintrag mehr.&lt;br /&gt;
|-&lt;br /&gt;
&amp;lt;!-- We don&#039;t do this!&lt;br /&gt;
| &amp;lt;tt&amp;gt;good&amp;amp;nbsp;127.0.0.1&amp;lt;/tt&amp;gt; ||&lt;br /&gt;
Die Anfrage entsprach nicht den Erfordernissen des Servers.&lt;br /&gt;
|| Trotz des Worts &amp;lt;tt&amp;gt;good&amp;lt;/tt&amp;gt; war die Anfrage nicht erfolgreich, falls in der Rückmeldung die IP-Adresse mit &amp;lt;tt&amp;gt;127.0.0.1&amp;lt;/tt&amp;gt; angegeben wird. Dieser verwirrende Fehlercode ist aus unerklärlichen Gründen in der Spezifikation von DynDNS.org so definiert.&lt;br /&gt;
|-&lt;br /&gt;
--&amp;gt;&lt;br /&gt;
| &amp;lt;tt&amp;gt;nochg&amp;amp;nbsp;&amp;amp;lt;IP&amp;amp;nbsp;number&amp;amp;gt;&amp;lt;/tt&amp;gt; ||&lt;br /&gt;
Der gewünschte DNS-Eintrag war bereits vorhanden. &lt;br /&gt;
|| Der Server selbst macht keine DNS-Abfrage, um das zu vermitteln: die &amp;amp;bdquo;no change&amp;amp;ldquo;-Antwort besagt nur, daß eine Anfrage für diesen Eintrag bereits mit Erfolg quittiert wurde.&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;notfqdn&amp;lt;/tt&amp;gt; ||&lt;br /&gt;
Fehlschlag: der gewünschte Domainname ist nicht gültig, oder es wurde keiner angegeben.&lt;br /&gt;
|| ...&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;nohost&amp;lt;/tt&amp;gt; ||&lt;br /&gt;
Fehlschlag: der gewünschte Domainname ist gehört nicht zu denen, die für diesen Benutzer des DDNS-Dienstes konfiguriert sind.&lt;br /&gt;
|| Siehe den Abschnitt [[#Administration|Administration]] weiter unten.&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;badauth&amp;lt;/tt&amp;gt; ||&lt;br /&gt;
Fehlschlag: Die Kombination von Benutzernamen und Paßwort entsprach keinem DDNS-Account, oder das Account ist momentan gesperrt.&lt;br /&gt;
|| Ein gesperrtes Account kann nur der Domain-Admin mittels des Administrationswerkzeugs wieder freigeben: siehe den Abschnit [[#Administration|Administration]] weiter unten.&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;abuse&amp;lt;/tt&amp;gt; ||&lt;br /&gt;
Fehlschlag: der gewünschte Domainname ist wegen vorangeganger Fehlschläge oder überflüssiger Aufrufe gesperrt.&lt;br /&gt;
|| Siehe den Abschnitt [[#Sukzessive_Kommunikationsabläufe|Sukzessive Kommunikationsabläufe]] unten.&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;911&amp;lt;/tt&amp;gt; ||&lt;br /&gt;
Fehlschlag: Das Server-Programm hat einen internen Fehler festgestellt.&lt;br /&gt;
|| Das Problem liegt nicht in der Anfrage an sich.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Man kann sich durchaus eine sinnreichere Kommunikation zwischen Client und Server vorstellen, doch das hier beschriebene Protokoll ist eben von DynDNS.org verwendet worden und wird in gängigen Routern implementiert, also wird es in der vorliegenden DDNS-Implementierung nachgebildet.&lt;br /&gt;
&lt;br /&gt;
=== Sukzessive Kommunikationsabläufe ===&lt;br /&gt;
Der Server muß sich zwischen einzelnen Aufrufen einiges merken, um Ressourcen zu schonen und um zu verhindern, daß einmal vergebene DDNS-Einträge von neuen Anfragen, die dieselbe übergeordnete Domain betreffen, durch Überschreiben  verlorengehen.&lt;br /&gt;
&lt;br /&gt;
==== Mißbrauch und Benutzersperrung ====&lt;br /&gt;
Zur Schonung von Ressourcen muß sich die Implementierung weigern, sich mit zuvielen fehlerhaften oder auch nur überflüssigen Anfragen zu beschäftigen. Dazu führt eine Strichliste über solche Anfragen jedes Clients und sperrt nach einer bestimmten Anzahl solcher Anfragen den Benutzernamen oder einzelne Domainnamen gegen die weitere Nutzung des Dienstes.&lt;br /&gt;
&lt;br /&gt;
Mißbrauchspunkte gegen einen einzelnen Domainnamen gibt es für:&lt;br /&gt;
* eine Anfrage, die keinen neuen DNS-Eintrag (und keine Änderung oder Löschung eines Eintrags) erfordert, sondern bestehende Merkmale nur wiederholt&lt;br /&gt;
&lt;br /&gt;
Mißbrauchspunkte gegen einen Benutzernamen gibt es für:&lt;br /&gt;
* die Angabe eines Domainnamens, der in der Dienstkonfiguration dem anfragenden Benutzernamen nicht zugeordnet ist&lt;br /&gt;
* die Angabe eines Domainnamen in einer Domain, die nicht demselben Hostsharing-Domain-Admin gehört, der den DDNS-Dienst anbietet&lt;br /&gt;
* die Angabe eines Domainnamens, der in der Dienstkonfiguration bereits wegen mißbräuchlicher Anfragen gesperrt ist (siehe oben)&lt;br /&gt;
&lt;br /&gt;
Um eine Sperrung aufzuheben, wird in der Regel eine Handlung durch den Administrator erforderlich sein.&lt;br /&gt;
&lt;br /&gt;
==== Mehrere dynamische Subdomains in derselben Domain ====&lt;br /&gt;
Sobald zwei verschiedene DDNS-Einträge in derselben Domain verlangt werden &amp;amp;ndash; beispielsweise home.example.com und office.example.com &amp;amp;ndash; wird es notwendig, bei jeder neuen Zonefile für example.com eventuell frühere Einträge zu konservieren. Der Rechner zu Hause weiß beim Bestellen seines DDNS-Eintrags nichts vom Rechner im Büro und umgekehrt. Der Server muß in irgendeiner Form über bereits vergebene Einträge Buch führen und bei einer neuen Anfrage, die example.com betrifft, alle bereits aktiven DDNS-Einträge für example.com mit in die neue Zonefile aufnehmen &amp;amp;ndash auch wenn sie auf Anfragen verschiedener Benutzer zurückgehen.&lt;br /&gt;
&lt;br /&gt;
==== Datenbank ====&lt;br /&gt;
In der Beispielimplementierung werden diese Informationen in einer SQLite-Datenbank gespeichert.&lt;br /&gt;
&lt;br /&gt;
== Sicherheit ==&lt;br /&gt;
=== Rechte ===&lt;br /&gt;
Die &#039;&#039;&#039;Benutzerrechte&#039;&#039;&#039; werden durch das Hostsharing-System kontrolliert. Sowohl das CGI-Programm als auch das [[#Administration|Administrationswerkzeug]] werden mit den Rechten des Domain-Admins (xyz00-benutzername in unserem Beispiel) ausgeführt, also kann dieses Programm nur die Domains bearbeiten, die von xyz00-benutzername verwaltet werden.&lt;br /&gt;
&lt;br /&gt;
=== Authentifizierung ===&lt;br /&gt;
In der Beispielimplementierung (wie auch seinerzeit bei DynDNS.org) wird das CGI-Programm durch einen .htaccess-Eintrag geschützt, der HTTP-Basic-Authentication vorschreibt. Also wird das Programm eigentlich mit einem URL der form&lt;br /&gt;
&lt;br /&gt;
  &amp;lt;nowiki&amp;gt;https://ddnsaccount:passwort@ddns.example.com/cgi-bin/ddns?hostname=...&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
aufgerufen.&lt;br /&gt;
&lt;br /&gt;
=== Verschlüsselung ===&lt;br /&gt;
Das CGI-Programm sollte nur in example.com/cgi-ssl/ installiert werden, nicht in example.com/cgi/. Damit ist die Kommunikation zwischen Client und Server durch SSL verschlüsselt.&lt;br /&gt;
&lt;br /&gt;
== Administration ==&lt;br /&gt;
&lt;br /&gt;
Der Verwalter des DDNS-Programms trägt berechtigte Benutzer und die ihnen zugeteilten Domainnamen in die Datenbank des Programms ein mit Hilfe eines kleinen Hilfsprogramms. Das ist im vorliegenden Fall ein menügesteuertes Programm für die Befehlszeile, daß die naheliegenden Funktionen anbietet: Account hinzufügen, löschen, sperren, entsperren, Paßwort setzen, ändern; Domainnamen hinzufügen, ändern, entsperren, löschen; Accounts und Domainnamen mit aktuellem Status auflisten. Die Funktionen sind auch über Befehlszeilenargumente verfügbar, also skriptfähig.&lt;br /&gt;
&lt;br /&gt;
Eine Auflistung des momentanen Inhalts der DDNS-Datenbank durch das Administrationswerkzeug könnte beispielsweise so aussehen:&lt;br /&gt;
&lt;br /&gt;
  xyz00-benutzername@h02:~$ bin/ddnsadmin.pl -Aa&lt;br /&gt;
  1.  papst	Mißbrauch: 0; gesperrt: nein&lt;br /&gt;
  	avignon.example.com&lt;br /&gt;
  		zuletzt aktiv am Sun Apr 26 22:24:49 2020&lt;br /&gt;
  		mit IP-Nr. 87.65.43.21; MX: 0;  Backup-MX: nein;&lt;br /&gt;
  		Subdomains: nein; Mißbrauch: 0;  gesperrt: nein&lt;br /&gt;
  	vatican.beispiel.de&lt;br /&gt;
  		zuletzt aktiv am Sun Apr 26 22:24:49 2020&lt;br /&gt;
  		mit IP-Nr. 87.65.43.21; MX: 0;  Backup-MX: nein;&lt;br /&gt;
  		Subdomains: nein; Mißbrauch: 0;  gesperrt: nein&lt;br /&gt;
  2.  kaiser	Mißbrauch: 4; gesperrt: ja&lt;br /&gt;
  	augsburg.beispiel.de&lt;br /&gt;
  		zuletzt aktiv am Fri Apr 24 16:13:49 2020&lt;br /&gt;
  		mit IP-Nr. 64.82.31.75; MX: 0;  Backup-MX: nein;&lt;br /&gt;
  		Subdomains: nein; Mißbrauch: 0;  gesperrt: ja&lt;br /&gt;
  3.  luther	Mißbrauch: 1; gesperrt: nein&lt;br /&gt;
  	wittenberg.example.com&lt;br /&gt;
  		zuletzt aktiv am Mon Apr 27 10:12:49 2020&lt;br /&gt;
  		mit IP-Nr. 78.56.34.12; MX: 0;  Backup-MX: nein;&lt;br /&gt;
  		Subdomains: nein; Mißbrauch: 1;  gesperrt: nein&lt;br /&gt;
  xyz00-benutzername@h02:~$&lt;br /&gt;
&lt;br /&gt;
Das DDNS-Account &amp;amp;bdquo;kaiser&amp;amp;ldquo; in dieser Auflistung ist wohl auf Grund fehlerhafter Anfragen automatisch gesperrt worden. Der Inhaber wird sich wohl bald melden, um nach Korrektur seiner Client-Konfiguration die Aufhebung der Sperre zu wünschen.&lt;br /&gt;
&lt;br /&gt;
=== Log ===&lt;br /&gt;
Alle Anfragen werden in einer täglich wechselnden Log-Datei protokolliert, entweder schlicht oder ausführlich, je nachdem, ob eine Variable &amp;lt;tt&amp;gt;verbose&amp;lt;/tt&amp;gt; wahr ist.&lt;br /&gt;
Ein ausführlicher Log-Eintrag sieht so aus:&lt;br /&gt;
&lt;br /&gt;
  Sun Apr 26 20:21:45 2020  ddns aufgerufen von papst&lt;br /&gt;
  			unter 84.185.97.8&lt;br /&gt;
  	URL: &amp;lt;nowiki&amp;gt;https://ddns.example.com/cgi-bin/ddns.cgi?hostname=&lt;br /&gt;
  			avignon.example.com,vatican.beispiel.de&amp;amp;&lt;br /&gt;
  			myip=84.185.97.8&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
  	Verwende IP 84.185.97.8 (= 1421435144)&lt;br /&gt;
  	DB-Version: 1&lt;br /&gt;
  	Skript und DB exklusiv geöffnet&lt;br /&gt;
  	avignon.example.com: IP: 84.185.97.8; MX: 0; Backup-MX: nein;&lt;br /&gt;
  			Wildcard: nein; Mißbrauch: 0; gesperrt: nein &lt;br /&gt;
  	vatican.beispiel.de: IP: 84.185.97.8; MX: 0; Backup-MX: nein;&lt;br /&gt;
  			Wildcard: nein; Mißbrauch: 0; gesperrt: nein &lt;br /&gt;
  	Betroffene Zonen: example.com, beispiel.de&lt;br /&gt;
  	Temporärdatei example.com_hxNa.new geschrieben&lt;br /&gt;
  	Zonendatei /home/pacs/xyz00/users/benutzername/doms/example.com/&lt;br /&gt;
  			etc/pri.example.com eingestellt&lt;br /&gt;
  	Temporärdatei beispiel.de_6HcO.new geschrieben&lt;br /&gt;
  	Zonendatei /home/pacs/xyz00/users/benutzername/doms/beispiel.de/&lt;br /&gt;
  			etc/pri.beispiel.de eingestellt&lt;br /&gt;
  	Abgeschlossen: 	Fertig&lt;br /&gt;
&lt;br /&gt;
Wenn &amp;lt;tt&amp;gt;verbose&amp;lt;/tt&amp;gt; auf falsch gesetzt ist, sind die Log-Einträge einzeilig.&lt;/div&gt;</summary>
		<author><name>Apc00-tony</name></author>
	</entry>
	<entry>
		<id>https://wiki.hostsharing.net/index.php?title=Benutzer:Apc00-tony/Dynamisches_DNS&amp;diff=5199</id>
		<title>Benutzer:Apc00-tony/Dynamisches DNS</title>
		<link rel="alternate" type="text/html" href="https://wiki.hostsharing.net/index.php?title=Benutzer:Apc00-tony/Dynamisches_DNS&amp;diff=5199"/>
		<updated>2020-04-29T09:33:23Z</updated>

		<summary type="html">&lt;p&gt;Apc00-tony: /* Antwort */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;((Provisorischer Vorspann: Auf Grund einer Mailing-Listen-Diskussion habe ich angefangen, Dynamisches DNS über einen CGI-Skript bei Hostsharing zu realisieren. Meine Lösung habe ich dann vorgestellt; sie wurde für nicht ausreichend selbsterklärend befunden und fand wenig Akzeptanz. Hier also der Versuch, die Sache zu dokumentieren.))&lt;br /&gt;
&lt;br /&gt;
Mit der regelmäßigen Aufnahme von benutzerspezifischen Zonefiles in seiner DNS-Konfiguration bietet  Hostsharing alles, was man braucht, um &amp;amp;bdquo;dynamisches DNS&amp;amp;ldquo; in Eigenregie zu realisieren.&lt;br /&gt;
&lt;br /&gt;
Das heißt, wenn ich mindestens eine Domain bei Hostsharing verwalte, und mindestens eine Einwahlverbindung (oder DSL-Verbindung) ins Internet mit wechselnder IP-Adresse über irgendeinen ISP für meinen Arbeitsplatzrechner zu Hause betreibe, dann kann ich dem Arbeitsplatzrechner über die DNS-Server von Hostsharing einen vollqualifizieren Domainnamen zuweisen, der der jeweiligen IP-Adresse meiner Einwahlleitung zugeordnet ist.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
(ASCII-Art-Diagramm der beschriebenen Konstellation)&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Im Folgenden wird eine real existierende Implementierung von Dynamischem DNS (&amp;amp;bdquo;DDNS&amp;amp;ldquo;) beschrieben. Die verschiedenen Elemente könnten durchaus anders realisiert werden; die beschriebene Implementierung könnte durchaus verbessert werden. Sie dient hier der Illustration.&lt;br /&gt;
&lt;br /&gt;
In der folgenden Beschreibung werden diese Beispielwerte benutzt:&lt;br /&gt;
* Ein Hostsharing-Mitglied hat ein Account als Paket-Admin mit Kennung xyz00.&lt;br /&gt;
* Im Paket xyz00 gibt es einen Domain-Admin namens xyz00-benutzername.&lt;br /&gt;
* Dieser Domain-Admin verwaltet bei Hostsharing die Domains example.com und beispiel.de.&lt;br /&gt;
* Ein Benutzer hat zu Hause (oder im Büro) einen Arbeitsplatzrechner hinter der marktüblichen DSL-Leitung, die von seinem ISP bereitgestellt wird.&lt;br /&gt;
* Dieser Arbeitsplatzrechner (oder der Router, der seine Internetverbindung steuert) bekommt vom ISP immer wechselnde IP-Adressen zugewiesen.&lt;br /&gt;
* Dennoch möchte der Benutzer seinen Arbeitsplatzrechner aus dem Internet unter dem Hostnamen einwahl.example.com ansprechen können.&lt;br /&gt;
&lt;br /&gt;
Dazu kann ein System wie Hostsharing, das authoritative DNS-Informationen für viele Domains bereitstellt, auch veränderliche DNS-Information über dynamisch verbundene Rechner verwalten &amp;amp;ndash; sofern das ressourcenschonend gemacht werden kann ohne andere Funktionen zu stören.&lt;br /&gt;
&lt;br /&gt;
== Aufgaben des Servers ==&lt;br /&gt;
&lt;br /&gt;
Um einem Rechner mit wechselnder IP-Adresse einen DDNS-Eintrag zu bieten, muß der Hostsharing-Server folgendes leisten (in ungefährer Reihenfolge der Ereignisse):&lt;br /&gt;
&lt;br /&gt;
# Eine Anfrage entgegennehmen, beispielsweise über HTTPS, von einem entfernten Rechner, der einen DNS-Eintrag für seine momentane IP-Adresse wünscht. &lt;br /&gt;
# Prüfen, ob die Anfrage einen berechtigten DDNS-Dienst-Usernamen mit zugehörigem Paßwort enthält.&lt;br /&gt;
# Prüfen, ob die Anfrage einen gültigen Domainnamen betrifft, den der Server bieten darf.&lt;br /&gt;
# Prüfen, ob die Domain example.com demselben Benutzer gehört, unter dessen Namen der Dynamisches-DNS-Server läuft.&lt;br /&gt;
# Eine gültige [[Zonefile]] mit &amp;amp;ndash; neben dem bisherigen Inhalt &amp;amp;ndash; einem A-Eintrag für einwahl.example.com in /home/pacs/xyz00/users/benutzername/doms/example.com/pri.example.com schreiben.&lt;br /&gt;
# Dem Client eine Bestätigung oder ggf. eine Fehlermeldung als Antwort senden.&lt;br /&gt;
# In irgendeiner Datenbank den momentan eingestellter Status all seiner DDNS-Einträge speichern.&lt;br /&gt;
# In einer Logdatei protokollieren, daß obiges getan wurde, oder ggf. welche Fehler traten auf.&lt;br /&gt;
&lt;br /&gt;
== Aufgaben des Clients ==&lt;br /&gt;
Bevor ich anfange, meinen Arbeitsplatzrechner so zu konfigurieren, daß er bei welchem Server auch immer einen DDNS-Eintrag anfordert, muß ich mich als verantwortlicher Benutzer dieses Rechners und der dazugehörigen Internetverbindung &amp;amp;ndash; das heißt, als Mensch &amp;amp;ndash; mit dem Betreiber des dynamisches-DNS-Servers vereinbaren, daß ich das darf und welchen Eintrag ich bekommen kann. Im Folgenden wird vorausgesetzt, daß solche Vereinbarungen getroffen und die Parameter geklärt wurden.&lt;br /&gt;
&lt;br /&gt;
Der DDNS-Client muß aus Server-Sicht nur wenig leisten:&lt;br /&gt;
&lt;br /&gt;
# Eine Anfrage senden, beispielsweise über HTTPS, an einen entfernten Rechner, der einen Eintrag ins DNS für die momentane IP-Adresse des Clients vornehmen kann.&amp;lt;br /&amp;gt;Diese Anfrage muß einem festgelegten Format entsprechen und muß gültige Werte für die Authorisation des Clients, den gewünschten Domainnamen, und eventuell andere Parameter enthalten.&lt;br /&gt;
# Eine Antwort des Servers entgegennehmen und als Erfolgs- oder Fehlermeldung auswerten.&lt;br /&gt;
# Von überflüssigen Anfragen absehen: das heißt bei Erfolg, nicht wiederholt den gleichen Eintrag erneut wünschen; bei Fehlern, nicht die gleiche fehlerhafte Anfrage erneut schicken.&lt;br /&gt;
&lt;br /&gt;
== Kommunikation zwischen Client und Server ==&lt;br /&gt;
&lt;br /&gt;
Ein einziges Nachrichtenpaar von Anfrage und Antwort genügt, um einen DDNS-Eintrag einzurichten: Der Client teilt die IP-Adresse und den Domainnamen mit, die in einem DNS-Eintrag verbunden werden sollen; der Server bestätigt den Auftrag.&lt;br /&gt;
&lt;br /&gt;
In der Beispielimplementierung erfolgt die Kommunikation über HTTP, und die Anfrage des Clients könnte so aussehen:&lt;br /&gt;
&lt;br /&gt;
  GET /cgi-bin/ddns?hostname=einwahl.example.com&amp;amp;myip=87.65.43.21 HTTP/1.1&lt;br /&gt;
  Host: ddns.beispiel.de&lt;br /&gt;
  User-Agent: Fritz!Box DDNS/1.0.1&lt;br /&gt;
  Authorization: Basic QWxhZGRpbjpvcGVuIHNlc2FtZQ==&lt;br /&gt;
&lt;br /&gt;
Bei Erhalt dieser Anfrage ruft Apache das CGI-Programm .../doms/ddns.beispiel.de/cgi-ssl/ddns auf. Das Fragezeichen trennt den Programmnamen von einem &amp;quot;Query-String&amp;quot;, in dem zwei Metavariablen definiert und übergeben werden. Die erste Metavariable, hostname, hat den Wert &amp;quot;einwahl.example.com&amp;quot;; die zweite, myip, hat den Wert &amp;quot;87.65.43.21&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
Das Server-Programm, hier &#039;&#039;ddns&#039;&#039;, prüft diese Informationen auf Form und Berechtigung, und schreibt gegebenenfalls einen entsprechenden Eintrag in einer Zonefile. Es schreibt auch verschiedene Informationen in die Standardausgabe. Wenn es die Standardausgabe geschlossen wird &amp;amp;ndash; also spätestens bei Programmende &amp;amp;ndash; schickt Apache diese Informationen als Antwort an den anfragenden Rechner zurück.&lt;br /&gt;
&lt;br /&gt;
Im Falle unserer Beispielimplementierung sieht die Antwort bei Erfolg so aus: &lt;br /&gt;
&lt;br /&gt;
  HTTP/1.1 200 OK&lt;br /&gt;
  Date: Wed, 22 Apr 2020 08:35:15 GMT&lt;br /&gt;
  Server: Apache&lt;br /&gt;
  Content-Length: 17&lt;br /&gt;
  Content-Type: text/plain; charset=ISO-8859-1&lt;br /&gt;
 &lt;br /&gt;
  good 87.65.43.21&lt;br /&gt;
&lt;br /&gt;
=== Das DDNS-Protokoll von DynDNS.org ===&lt;br /&gt;
&lt;br /&gt;
In den 90er Jahren, bevor das Internet so durchgehend vergeschäftlicht wurde, boten einige Organisationen kostenlose DDNS-Dienste an. Ein sehr beliebtes Angebot war das von DynDNS.org. Das DDNS-Protokoll von diesem Dienst wurde sogar in Einwahl-Routern einprogrammiert und der Dienst wurde von ISPs und Router-Herstellern als Leistungsmerkmal beworben.&lt;br /&gt;
&lt;br /&gt;
DynDNS.org gehört inzwischen Oracle und bietet keine kostenlose Dienste mehr. Dennoch wird das DDNS-Protokoll von DynDNS.org in der vorliegenden Beispielimplementierung übernommen in der Hoffnung, daß die Kompatibilität mit einigen gängigen Einwahl-Routern von Vorteil sein kann. Es gibt noch eine kurze Online-Dokumentation der [https://help.dyn.com/remote-access-api/perform-update/ Anfrage] und [https://help.dyn.com/remote-access-api/perform-update/ Antwortnachrichten].&lt;br /&gt;
&lt;br /&gt;
Das gesammte Protokoll sieht einen einzigen Nachrichtenaustausch aus Anfrage und Antwort vor. Die Anfrage kann mehrere Argumente enthalten; die Antwort kann verschiedene Code-Wörtern enthalten. Übrigens können in einer einzigen Anfrage mehrere DNS-Einträge gewünscht werden. In diesem Fall kann die Antwort mehrzeilig ausfallen.&lt;br /&gt;
&lt;br /&gt;
Das Verhalten von Server und Client bei künftigen Kommunikationsvorgängen wird unter Umständen von vorangegangenen Kommunikationsergebnissen beeinflußt: nach wiederholten fehlerhaften oder redundanten Anfragen kann der Server weitere Anfragen des Benutzers verweigern; nach wiederholten Fehlermeldungen sollte ein Client aufhören, immer dieselbe Anfrage zu schicken. Und für den Fall, daß mehrere Clients dynamische DNS-Einträge in derselben Domain example.com bestellen, muß der Server den Stand aller Client-Einträge intern speichern, damit er nicht mit einer neuen Zonefile einen früher erstellten Eintrag löscht. Zu diesen Fragen siehe den Abschnitt &#039;&#039;&#039;[[#Sukzessive_Kommunikationsabläufe]]&#039;&#039;&#039; nach der Beschreibung von Anfragen und Antworten unten.&lt;br /&gt;
&lt;br /&gt;
====Anfrage====&lt;br /&gt;
&lt;br /&gt;
Die Anfrage in Form eines URL übergibt dem DDNS-Programm in einem &#039;Query-String&#039; einige Metavariablen. Das heißt, in einem URL der Form&lt;br /&gt;
&lt;br /&gt;
  &amp;lt;nowiki&amp;gt;https://benutzername:passwort@ddns.beisiel.de/cgi-bin/ddns?hostname=einwahl.example.com&amp;amp;myip=87.65.43.21&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
signalisert das Fragezeichen, daß ein Query-String folgt. In einem solchen Query-String können in der Beispielimplementierung folgende Metavariablen definiert werden:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|- class=&amp;quot;hintergrundfarbe5&amp;quot;&lt;br /&gt;
! Variable !! Beispiel !! Bemerkungen&lt;br /&gt;
|-&lt;br /&gt;
| hostname || &amp;lt;tt&amp;gt;hostname=einwahl.example.com&amp;lt;/tt&amp;gt;&amp;lt;br /&amp;gt;&amp;lt;div style=&amp;quot;font-size:smaller;&amp;quot;&amp;gt;&amp;lt;tt&amp;gt;hostname=eins.example.com,zwei.example.com[,...]&amp;lt;/tt&amp;gt;&amp;lt;/div&amp;gt; ||&lt;br /&gt;
Muß ein vollständig qualifizierter Domain-Name (&amp;quot;FQDN&amp;quot;) sein; &amp;lt;tt&amp;gt;example.com&amp;lt;/tt&amp;gt; muß eine vom Besitzer des DDNS-Programms verwaltete Domain sein. Genaugenommen kann der Wert eine durch Kommata gegliederte Liste mehrerer gültiger Domainnamen sein, falls mehrere Einträge mit derselben IP-Adresse gewünscht werden.&lt;br /&gt;
|-&lt;br /&gt;
| myip || &amp;lt;tt&amp;gt;myip=87.65.43.21&amp;lt;/tt&amp;gt;||&lt;br /&gt;
Kann entfallen; kann vom Server ignoriert werden. Maßgeblich ist dann die IP-Adresse des Absenders, wie sie vom Web-Server mitgeteilt wird.&lt;br /&gt;
|-&lt;br /&gt;
| mx || &amp;lt;tt&amp;gt;mx=87.65.43.21&amp;lt;/tt&amp;gt;&amp;lt;br /&amp;gt;&amp;lt;tt&amp;gt;mx=NOCHG&amp;lt;/tt&amp;gt;&amp;lt;br /&amp;gt; ||&lt;br /&gt;
Neben dem A-Eintrag möchte der Client auch einen MX-Eintrag. Der Wert &amp;lt;tt&amp;gt;NOCHG&amp;lt;/tt&amp;gt; (für &amp;amp;bdquo;no change&amp;amp;ldquo;) bedeutet, der bestehende MX-Eintrag (oder seine Abwesenheit) soll nicht geändert werden. &lt;br /&gt;
|-&lt;br /&gt;
| backmx || &amp;lt;tt&amp;gt;backmx=YES&amp;lt;/tt&amp;gt;&amp;lt;br /&amp;gt;&amp;lt;tt&amp;gt;backmx=NOCHG&amp;lt;/tt&amp;gt;&amp;lt;br /&amp;gt;&amp;lt;tt&amp;gt;backmx=NO&amp;lt;/tt&amp;gt;   ||&lt;br /&gt;
Falls &amp;lt;tt&amp;gt;YES&amp;lt;/tt&amp;gt;, wird ein zweiter MX-Eintrag erzeugt, der &amp;lt;tt&amp;gt;einwahl.example.com&amp;lt;/tt&amp;gt; als Mail-Server für &amp;lt;tt&amp;gt;einwahl.example.com&amp;lt;/tt&amp;gt; nennt. Dieser Eintrag hat eine niedrigere Präferenzzahl (also eine höhere Priorität) als der mit &amp;lt;tt&amp;gt;mx&amp;lt;/tt&amp;gt; angeforderten Eintrag.&lt;br /&gt;
|-&lt;br /&gt;
| wildcard || &amp;lt;tt&amp;gt;wildcard=ON&amp;lt;/tt&amp;gt;&amp;lt;br /&amp;gt;&amp;lt;tt&amp;gt;wildcard=NOCHG&amp;lt;/tt&amp;gt;&amp;lt;br /&amp;gt;&amp;lt;tt&amp;gt;wildcard=OFF&amp;lt;/tt&amp;gt; ||&lt;br /&gt;
Neben dem A-Eintrag für den Domainnamen &amp;lt;tt&amp;gt;einwahl.example.com&amp;lt;/tt&amp;gt; wünscht der Client auch einen Eintrag für beliebige Subdomains, also &amp;lt;tt&amp;gt;*.einwahl.example.com&amp;lt;/tt&amp;gt;, mit der gleichen IP-Adresse.&lt;br /&gt;
|-&lt;br /&gt;
| offline ||&amp;lt;tt&amp;gt;offline=YES&amp;lt;/tt&amp;gt;&amp;lt;br /&amp;gt;&amp;lt;tt&amp;gt;offline=NOCHG&amp;lt;/tt&amp;gt;||&lt;br /&gt;
Falls &amp;lt;tt&amp;gt;YES&amp;lt;/tt&amp;gt;, wird ein DNS-Eintrag für &amp;lt;tt&amp;gt;einwahl.example.com&amp;lt;/tt&amp;gt; aus der Zonefile getilgt. Gegebenenfalls wird der Hostname dann auf Grund eines parallelen Wildcard-Eintrags für &amp;lt;tt&amp;gt;*.example.com&amp;lt;/tt&amp;gt; einer anderen IP-Adresse zugeordnet werden.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;!-- IPv6? --&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Alle Parameter bis auf hostname können entfallen. Bei nichtdokumentierten Argumenten ist das Verhalten undefiniert&amp;amp;trade;.&lt;br /&gt;
&lt;br /&gt;
====Antwort====&lt;br /&gt;
&lt;br /&gt;
Die Antwort auf eine erfolgreiche HTTP-Anfrage besteht im häufigsten Fall aus einigen Header-Zeilen, gefolgt vom Inhalt der gewünschten Text- oder andere Datei. Ein Status-Code in der ersten Header-Zeile gibt an, ob die Anfrage bedient werden kann oder kreist andernfalls den Grund für die Enttäuschung ein.&lt;br /&gt;
&lt;br /&gt;
Die vorliegende Beispielimplementierung von DDNS schickt einen der üblichen HTTP-Status-Codes &amp;quot;200 OK&amp;quot; oder &amp;quot;500 Internal Server Error&amp;quot;, gefolgt von einer kurzen Textnachricht nach dem HTTP-Header. Bei diesem Programm  ist &amp;amp;ndash; laut Gebrauchshinweise von DynDNS.org &amp;amp;ndash; &#039;&#039;nicht&#039;&#039; der Status-Code im Header, sondern der Inhalt der Nachricht  die definierte, maßgebliche Ergebnismeldung des Programms.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|- class=&amp;quot;hintergrundfarbe5&amp;quot;&lt;br /&gt;
! Meldung !! Bedeutung !! Bemerkungen&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;good&amp;amp;nbsp;&amp;amp;lt;IP&amp;amp;nbsp;number&amp;amp;gt;&amp;lt;/tt&amp;gt; ||&lt;br /&gt;
Der gewünschte DNS-Eintrag wurde erfolgreich in einer Zonefile eingetragen. &lt;br /&gt;
|| Es kann natürlich noch einige Minuten dauern, bis die Zonefile vom Hostsharing-Roboter abgelesen wird und der Inhalt in die BIND-Konfiguration übernommen.&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;good&amp;amp;nbsp;0.0.0.0&amp;lt;/tt&amp;gt; ||&lt;br /&gt;
Das Argument &amp;lt;tt&amp;gt;offline=YES&amp;lt;/tt&amp;gt; wurde empfangen und verarbeitet.&lt;br /&gt;
|| Der Domainname hat also keinen dynamischen DNS-Eintrag mehr.&lt;br /&gt;
|-&lt;br /&gt;
&amp;lt;!-- We don&#039;t do this!&lt;br /&gt;
| &amp;lt;tt&amp;gt;good&amp;amp;nbsp;127.0.0.1&amp;lt;/tt&amp;gt; ||&lt;br /&gt;
Die Anfrage entsprach nicht den Erfordernissen des Servers.&lt;br /&gt;
|| Trotz des Worts &amp;lt;tt&amp;gt;good&amp;lt;/tt&amp;gt; war die Anfrage nicht erfolgreich, falls in der Rückmeldung die IP-Adresse mit &amp;lt;tt&amp;gt;127.0.0.1&amp;lt;/tt&amp;gt; angegeben wird. Dieser verwirrende Fehlercode ist aus unerklärlichen Gründen in der Spezifikation von DynDNS.org so definiert.&lt;br /&gt;
|-&lt;br /&gt;
--&amp;gt;&lt;br /&gt;
| &amp;lt;tt&amp;gt;nochg&amp;amp;nbsp;&amp;amp;lt;IP&amp;amp;nbsp;number&amp;amp;gt;&amp;lt;/tt&amp;gt; ||&lt;br /&gt;
Der gewünschte DNS-Eintrag war bereits vorhanden. &lt;br /&gt;
|| Der Server selbst macht keine DNS-Abfrage, um das zu vermitteln: die &amp;amp;bdquo;no change&amp;amp;ldquo;-Antwort besagt nur, daß eine Anfrage für diesen Eintrag bereits mit Erfolg quittiert wurde.&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;notfqdn&amp;lt;/tt&amp;gt; ||&lt;br /&gt;
Fehlschlag: der gewünschte Domainname ist nicht gültig, oder es wurde keiner angegeben.&lt;br /&gt;
|| ...&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;nohost&amp;lt;/tt&amp;gt; ||&lt;br /&gt;
Fehlschlag: der gewünschte Domainname ist gehört nicht zu denen, die für diesen Benutzer des DDNS-Dienstes konfiguriert sind.&lt;br /&gt;
|| Siehe den Abschnitt [[#Administration|Administration]] weiter unten.&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;badauth&amp;lt;/tt&amp;gt; ||&lt;br /&gt;
Fehlschlag: Die Kombination von Benutzernamen und Paßwort entsprach keinem DDNS-Account, oder das Account ist momentan gesperrt.&lt;br /&gt;
|| Ein gesperrtes Account kann nur der Domain-Admin mittels des Administrationswerkzeugs wieder freigeben: siehe den Abschnit [[#Administration|Administration]] weiter unten.&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;abuse&amp;lt;/tt&amp;gt; ||&lt;br /&gt;
Fehlschlag: der gewünschte Domainname ist wegen vorangeganger Fehlschläge oder überflüssiger Aufrufe gesperrt.&lt;br /&gt;
|| Siehe den Abschnitt [[Sukzessive_Kommunikationsabläufe|Sukzessive Kommunikationsabläufe]] unten.&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;911&amp;lt;/tt&amp;gt; ||&lt;br /&gt;
Fehlschlag: Das Server-Programm hat einen internen Fehler festgestellt.&lt;br /&gt;
|| Das Problem liegt nicht in der Anfrage an sich.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Man kann sich durchaus eine sinnreichere Kommunikation zwischen Client und Server vorstellen, doch das hier beschriebene Protokoll ist eben von DynDNS.org verwendet worden und wird in gängigen Routern implementiert, also wird es in der vorliegenden DDNS-Implementierung nachgebildet.&lt;br /&gt;
&lt;br /&gt;
=== Sukzessive Kommunikationsabläufe ===&lt;br /&gt;
Der Server muß sich zwischen einzelnen Aufrufen einiges merken, um Ressourcen zu schonen und um zu verhindern, daß einmal vergebene DDNS-Einträge von neuen Anfragen, die dieselbe übergeordnete Domain betreffen, durch Überschreiben  verlorengehen.&lt;br /&gt;
&lt;br /&gt;
==== Mißbrauch und Benutzersperrung ====&lt;br /&gt;
Zur Schonung von Ressourcen muß sich die Implementierung weigern, sich mit zuvielen fehlerhaften oder auch nur überflüssigen Anfragen zu beschäftigen. Dazu führt eine Strichliste über solche Anfragen jedes Clients und sperrt nach einer bestimmten Anzahl solcher Anfragen den Benutzernamen oder einzelne Domainnamen gegen die weitere Nutzung des Dienstes.&lt;br /&gt;
&lt;br /&gt;
Mißbrauchspunkte gegen einen einzelnen Domainnamen gibt es für:&lt;br /&gt;
* eine Anfrage, die keinen neuen DNS-Eintrag (und keine Änderung oder Löschung eines Eintrags) erfordert, sondern bestehende Merkmale nur wiederholt&lt;br /&gt;
&lt;br /&gt;
Mißbrauchspunkte gegen einen Benutzernamen gibt es für:&lt;br /&gt;
* die Angabe eines Domainnamens, der in der Dienstkonfiguration dem anfragenden Benutzernamen nicht zugeordnet ist&lt;br /&gt;
* die Angabe eines Domainnamen in einer Domain, die nicht demselben Hostsharing-Domain-Admin gehört, der den DDNS-Dienst anbietet&lt;br /&gt;
* die Angabe eines Domainnamens, der in der Dienstkonfiguration bereits wegen mißbräuchlicher Anfragen gesperrt ist (siehe oben)&lt;br /&gt;
&lt;br /&gt;
Um eine Sperrung aufzuheben, wird in der Regel eine Handlung durch den Administrator erforderlich sein.&lt;br /&gt;
&lt;br /&gt;
==== Mehrere dynamische Subdomains in derselben Domain ====&lt;br /&gt;
Sobald zwei verschiedene DDNS-Einträge in derselben Domain verlangt werden &amp;amp;ndash; beispielsweise home.example.com und office.example.com &amp;amp;ndash; wird es notwendig, bei jeder neuen Zonefile für example.com eventuell frühere Einträge zu konservieren. Der Rechner zu Hause weiß beim Bestellen seines DDNS-Eintrags nichts vom Rechner im Büro und umgekehrt. Der Server muß in irgendeiner Form über bereits vergebene Einträge Buch führen und bei einer neuen Anfrage, die example.com betrifft, alle bereits aktiven DDNS-Einträge für example.com mit in die neue Zonefile aufnehmen &amp;amp;ndash auch wenn sie auf Anfragen verschiedener Benutzer zurückgehen.&lt;br /&gt;
&lt;br /&gt;
==== Datenbank ====&lt;br /&gt;
In der Beispielimplementierung werden diese Informationen in einer SQLite-Datenbank gespeichert.&lt;br /&gt;
&lt;br /&gt;
== Sicherheit ==&lt;br /&gt;
=== Rechte ===&lt;br /&gt;
Die &#039;&#039;&#039;Benutzerrechte&#039;&#039;&#039; werden durch das Hostsharing-System kontrolliert. Sowohl das CGI-Programm als auch das [[#Administration|Administrationswerkzeug]] werden mit den Rechten des Domain-Admins (xyz00-benutzername in unserem Beispiel) ausgeführt, also kann dieses Programm nur die Domains bearbeiten, die von xyz00-benutzername verwaltet werden.&lt;br /&gt;
&lt;br /&gt;
=== Authentifizierung ===&lt;br /&gt;
In der Beispielimplementierung (wie auch seinerzeit bei DynDNS.org) wird das CGI-Programm durch einen .htaccess-Eintrag geschützt, der HTTP-Basic-Authentication vorschreibt. Also wird das Programm eigentlich mit einem URL der form&lt;br /&gt;
&lt;br /&gt;
  &amp;lt;nowiki&amp;gt;https://ddnsaccount:passwort@ddns.example.com/cgi-bin/ddns?hostname=...&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
aufgerufen.&lt;br /&gt;
&lt;br /&gt;
=== Verschlüsselung ===&lt;br /&gt;
Das CGI-Programm sollte nur in example.com/cgi-ssl/ installiert werden, nicht in example.com/cgi/. Damit ist die Kommunikation zwischen Client und Server durch SSL verschlüsselt.&lt;br /&gt;
&lt;br /&gt;
== Administration ==&lt;br /&gt;
&lt;br /&gt;
Der Verwalter des DDNS-Programms trägt berechtigte Benutzer und die ihnen zugeteilten Domainnamen in die Datenbank des Programms ein mit Hilfe eines kleinen Hilfsprogramms. Das ist im vorliegenden Fall ein menügesteuertes Programm für die Befehlszeile, daß die naheliegenden Funktionen anbietet: Account hinzufügen, löschen, sperren, entsperren, Paßwort setzen, ändern; Domainnamen hinzufügen, ändern, entsperren, löschen; Accounts und Domainnamen mit aktuellem Status auflisten. Die Funktionen sind auch über Befehlszeilenargumente verfügbar, also skriptfähig.&lt;br /&gt;
&lt;br /&gt;
Eine Auflistung des momentanen Inhalts der DDNS-Datenbank durch das Administrationswerkzeug könnte beispielsweise so aussehen:&lt;br /&gt;
&lt;br /&gt;
  xyz00-benutzername@h02:~$ bin/ddnsadmin.pl -Aa&lt;br /&gt;
  1.  papst	Mißbrauch: 0; gesperrt: nein&lt;br /&gt;
  	avignon.example.com&lt;br /&gt;
  		zuletzt aktiv am Sun Apr 26 22:24:49 2020&lt;br /&gt;
  		mit IP-Nr. 87.65.43.21; MX: 0;  Backup-MX: nein;&lt;br /&gt;
  		Subdomains: nein; Mißbrauch: 0;  gesperrt: nein&lt;br /&gt;
  	vatican.beispiel.de&lt;br /&gt;
  		zuletzt aktiv am Sun Apr 26 22:24:49 2020&lt;br /&gt;
  		mit IP-Nr. 87.65.43.21; MX: 0;  Backup-MX: nein;&lt;br /&gt;
  		Subdomains: nein; Mißbrauch: 0;  gesperrt: nein&lt;br /&gt;
  2.  kaiser	Mißbrauch: 4; gesperrt: ja&lt;br /&gt;
  	augsburg.beispiel.de&lt;br /&gt;
  		zuletzt aktiv am Fri Apr 24 16:13:49 2020&lt;br /&gt;
  		mit IP-Nr. 64.82.31.75; MX: 0;  Backup-MX: nein;&lt;br /&gt;
  		Subdomains: nein; Mißbrauch: 0;  gesperrt: ja&lt;br /&gt;
  3.  luther	Mißbrauch: 1; gesperrt: nein&lt;br /&gt;
  	wittenberg.example.com&lt;br /&gt;
  		zuletzt aktiv am Mon Apr 27 10:12:49 2020&lt;br /&gt;
  		mit IP-Nr. 78.56.34.12; MX: 0;  Backup-MX: nein;&lt;br /&gt;
  		Subdomains: nein; Mißbrauch: 1;  gesperrt: nein&lt;br /&gt;
  xyz00-benutzername@h02:~$&lt;br /&gt;
&lt;br /&gt;
Das DDNS-Account &amp;amp;bdquo;kaiser&amp;amp;ldquo; in dieser Auflistung ist wohl auf Grund fehlerhafter Anfragen automatisch gesperrt worden. Der Inhaber wird sich wohl bald melden, um nach Korrektur seiner Client-Konfiguration die Aufhebung der Sperre zu wünschen.&lt;br /&gt;
&lt;br /&gt;
=== Log ===&lt;br /&gt;
Alle Anfragen werden in einer täglich wechselnden Log-Datei protokolliert, entweder schlicht oder ausführlich, je nachdem, ob eine Variable &amp;lt;tt&amp;gt;verbose&amp;lt;/tt&amp;gt; wahr ist.&lt;br /&gt;
Ein ausführlicher Log-Eintrag sieht so aus:&lt;br /&gt;
&lt;br /&gt;
  Sun Apr 26 20:21:45 2020  ddns aufgerufen von papst&lt;br /&gt;
  			unter 84.185.97.8&lt;br /&gt;
  	URL: &amp;lt;nowiki&amp;gt;https://ddns.example.com/cgi-bin/ddns.cgi?hostname=&lt;br /&gt;
  			avignon.example.com,vatican.beispiel.de&amp;amp;&lt;br /&gt;
  			myip=84.185.97.8&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
  	Verwende IP 84.185.97.8 (= 1421435144)&lt;br /&gt;
  	DB-Version: 1&lt;br /&gt;
  	Skript und DB exklusiv geöffnet&lt;br /&gt;
  	avignon.example.com: IP: 84.185.97.8; MX: 0; Backup-MX: nein;&lt;br /&gt;
  			Wildcard: nein; Mißbrauch: 0; gesperrt: nein &lt;br /&gt;
  	vatican.beispiel.de: IP: 84.185.97.8; MX: 0; Backup-MX: nein;&lt;br /&gt;
  			Wildcard: nein; Mißbrauch: 0; gesperrt: nein &lt;br /&gt;
  	Betroffene Zonen: example.com, beispiel.de&lt;br /&gt;
  	Temporärdatei example.com_hxNa.new geschrieben&lt;br /&gt;
  	Zonendatei /home/pacs/xyz00/users/benutzername/doms/example.com/&lt;br /&gt;
  			etc/pri.example.com eingestellt&lt;br /&gt;
  	Temporärdatei beispiel.de_6HcO.new geschrieben&lt;br /&gt;
  	Zonendatei /home/pacs/xyz00/users/benutzername/doms/beispiel.de/&lt;br /&gt;
  			etc/pri.beispiel.de eingestellt&lt;br /&gt;
  	Abgeschlossen: 	Fertig&lt;br /&gt;
&lt;br /&gt;
Wenn &amp;lt;tt&amp;gt;verbose&amp;lt;/tt&amp;gt; auf falsch gesetzt ist, sind die Log-Einträge einzeilig.&lt;/div&gt;</summary>
		<author><name>Apc00-tony</name></author>
	</entry>
	<entry>
		<id>https://wiki.hostsharing.net/index.php?title=Benutzer:Apc00-tony/Dynamisches_DNS&amp;diff=5198</id>
		<title>Benutzer:Apc00-tony/Dynamisches DNS</title>
		<link rel="alternate" type="text/html" href="https://wiki.hostsharing.net/index.php?title=Benutzer:Apc00-tony/Dynamisches_DNS&amp;diff=5198"/>
		<updated>2020-04-29T09:31:38Z</updated>

		<summary type="html">&lt;p&gt;Apc00-tony: /* Antwort */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;((Provisorischer Vorspann: Auf Grund einer Mailing-Listen-Diskussion habe ich angefangen, Dynamisches DNS über einen CGI-Skript bei Hostsharing zu realisieren. Meine Lösung habe ich dann vorgestellt; sie wurde für nicht ausreichend selbsterklärend befunden und fand wenig Akzeptanz. Hier also der Versuch, die Sache zu dokumentieren.))&lt;br /&gt;
&lt;br /&gt;
Mit der regelmäßigen Aufnahme von benutzerspezifischen Zonefiles in seiner DNS-Konfiguration bietet  Hostsharing alles, was man braucht, um &amp;amp;bdquo;dynamisches DNS&amp;amp;ldquo; in Eigenregie zu realisieren.&lt;br /&gt;
&lt;br /&gt;
Das heißt, wenn ich mindestens eine Domain bei Hostsharing verwalte, und mindestens eine Einwahlverbindung (oder DSL-Verbindung) ins Internet mit wechselnder IP-Adresse über irgendeinen ISP für meinen Arbeitsplatzrechner zu Hause betreibe, dann kann ich dem Arbeitsplatzrechner über die DNS-Server von Hostsharing einen vollqualifizieren Domainnamen zuweisen, der der jeweiligen IP-Adresse meiner Einwahlleitung zugeordnet ist.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
(ASCII-Art-Diagramm der beschriebenen Konstellation)&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Im Folgenden wird eine real existierende Implementierung von Dynamischem DNS (&amp;amp;bdquo;DDNS&amp;amp;ldquo;) beschrieben. Die verschiedenen Elemente könnten durchaus anders realisiert werden; die beschriebene Implementierung könnte durchaus verbessert werden. Sie dient hier der Illustration.&lt;br /&gt;
&lt;br /&gt;
In der folgenden Beschreibung werden diese Beispielwerte benutzt:&lt;br /&gt;
* Ein Hostsharing-Mitglied hat ein Account als Paket-Admin mit Kennung xyz00.&lt;br /&gt;
* Im Paket xyz00 gibt es einen Domain-Admin namens xyz00-benutzername.&lt;br /&gt;
* Dieser Domain-Admin verwaltet bei Hostsharing die Domains example.com und beispiel.de.&lt;br /&gt;
* Ein Benutzer hat zu Hause (oder im Büro) einen Arbeitsplatzrechner hinter der marktüblichen DSL-Leitung, die von seinem ISP bereitgestellt wird.&lt;br /&gt;
* Dieser Arbeitsplatzrechner (oder der Router, der seine Internetverbindung steuert) bekommt vom ISP immer wechselnde IP-Adressen zugewiesen.&lt;br /&gt;
* Dennoch möchte der Benutzer seinen Arbeitsplatzrechner aus dem Internet unter dem Hostnamen einwahl.example.com ansprechen können.&lt;br /&gt;
&lt;br /&gt;
Dazu kann ein System wie Hostsharing, das authoritative DNS-Informationen für viele Domains bereitstellt, auch veränderliche DNS-Information über dynamisch verbundene Rechner verwalten &amp;amp;ndash; sofern das ressourcenschonend gemacht werden kann ohne andere Funktionen zu stören.&lt;br /&gt;
&lt;br /&gt;
== Aufgaben des Servers ==&lt;br /&gt;
&lt;br /&gt;
Um einem Rechner mit wechselnder IP-Adresse einen DDNS-Eintrag zu bieten, muß der Hostsharing-Server folgendes leisten (in ungefährer Reihenfolge der Ereignisse):&lt;br /&gt;
&lt;br /&gt;
# Eine Anfrage entgegennehmen, beispielsweise über HTTPS, von einem entfernten Rechner, der einen DNS-Eintrag für seine momentane IP-Adresse wünscht. &lt;br /&gt;
# Prüfen, ob die Anfrage einen berechtigten DDNS-Dienst-Usernamen mit zugehörigem Paßwort enthält.&lt;br /&gt;
# Prüfen, ob die Anfrage einen gültigen Domainnamen betrifft, den der Server bieten darf.&lt;br /&gt;
# Prüfen, ob die Domain example.com demselben Benutzer gehört, unter dessen Namen der Dynamisches-DNS-Server läuft.&lt;br /&gt;
# Eine gültige [[Zonefile]] mit &amp;amp;ndash; neben dem bisherigen Inhalt &amp;amp;ndash; einem A-Eintrag für einwahl.example.com in /home/pacs/xyz00/users/benutzername/doms/example.com/pri.example.com schreiben.&lt;br /&gt;
# Dem Client eine Bestätigung oder ggf. eine Fehlermeldung als Antwort senden.&lt;br /&gt;
# In irgendeiner Datenbank den momentan eingestellter Status all seiner DDNS-Einträge speichern.&lt;br /&gt;
# In einer Logdatei protokollieren, daß obiges getan wurde, oder ggf. welche Fehler traten auf.&lt;br /&gt;
&lt;br /&gt;
== Aufgaben des Clients ==&lt;br /&gt;
Bevor ich anfange, meinen Arbeitsplatzrechner so zu konfigurieren, daß er bei welchem Server auch immer einen DDNS-Eintrag anfordert, muß ich mich als verantwortlicher Benutzer dieses Rechners und der dazugehörigen Internetverbindung &amp;amp;ndash; das heißt, als Mensch &amp;amp;ndash; mit dem Betreiber des dynamisches-DNS-Servers vereinbaren, daß ich das darf und welchen Eintrag ich bekommen kann. Im Folgenden wird vorausgesetzt, daß solche Vereinbarungen getroffen und die Parameter geklärt wurden.&lt;br /&gt;
&lt;br /&gt;
Der DDNS-Client muß aus Server-Sicht nur wenig leisten:&lt;br /&gt;
&lt;br /&gt;
# Eine Anfrage senden, beispielsweise über HTTPS, an einen entfernten Rechner, der einen Eintrag ins DNS für die momentane IP-Adresse des Clients vornehmen kann.&amp;lt;br /&amp;gt;Diese Anfrage muß einem festgelegten Format entsprechen und muß gültige Werte für die Authorisation des Clients, den gewünschten Domainnamen, und eventuell andere Parameter enthalten.&lt;br /&gt;
# Eine Antwort des Servers entgegennehmen und als Erfolgs- oder Fehlermeldung auswerten.&lt;br /&gt;
# Von überflüssigen Anfragen absehen: das heißt bei Erfolg, nicht wiederholt den gleichen Eintrag erneut wünschen; bei Fehlern, nicht die gleiche fehlerhafte Anfrage erneut schicken.&lt;br /&gt;
&lt;br /&gt;
== Kommunikation zwischen Client und Server ==&lt;br /&gt;
&lt;br /&gt;
Ein einziges Nachrichtenpaar von Anfrage und Antwort genügt, um einen DDNS-Eintrag einzurichten: Der Client teilt die IP-Adresse und den Domainnamen mit, die in einem DNS-Eintrag verbunden werden sollen; der Server bestätigt den Auftrag.&lt;br /&gt;
&lt;br /&gt;
In der Beispielimplementierung erfolgt die Kommunikation über HTTP, und die Anfrage des Clients könnte so aussehen:&lt;br /&gt;
&lt;br /&gt;
  GET /cgi-bin/ddns?hostname=einwahl.example.com&amp;amp;myip=87.65.43.21 HTTP/1.1&lt;br /&gt;
  Host: ddns.beispiel.de&lt;br /&gt;
  User-Agent: Fritz!Box DDNS/1.0.1&lt;br /&gt;
  Authorization: Basic QWxhZGRpbjpvcGVuIHNlc2FtZQ==&lt;br /&gt;
&lt;br /&gt;
Bei Erhalt dieser Anfrage ruft Apache das CGI-Programm .../doms/ddns.beispiel.de/cgi-ssl/ddns auf. Das Fragezeichen trennt den Programmnamen von einem &amp;quot;Query-String&amp;quot;, in dem zwei Metavariablen definiert und übergeben werden. Die erste Metavariable, hostname, hat den Wert &amp;quot;einwahl.example.com&amp;quot;; die zweite, myip, hat den Wert &amp;quot;87.65.43.21&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
Das Server-Programm, hier &#039;&#039;ddns&#039;&#039;, prüft diese Informationen auf Form und Berechtigung, und schreibt gegebenenfalls einen entsprechenden Eintrag in einer Zonefile. Es schreibt auch verschiedene Informationen in die Standardausgabe. Wenn es die Standardausgabe geschlossen wird &amp;amp;ndash; also spätestens bei Programmende &amp;amp;ndash; schickt Apache diese Informationen als Antwort an den anfragenden Rechner zurück.&lt;br /&gt;
&lt;br /&gt;
Im Falle unserer Beispielimplementierung sieht die Antwort bei Erfolg so aus: &lt;br /&gt;
&lt;br /&gt;
  HTTP/1.1 200 OK&lt;br /&gt;
  Date: Wed, 22 Apr 2020 08:35:15 GMT&lt;br /&gt;
  Server: Apache&lt;br /&gt;
  Content-Length: 17&lt;br /&gt;
  Content-Type: text/plain; charset=ISO-8859-1&lt;br /&gt;
 &lt;br /&gt;
  good 87.65.43.21&lt;br /&gt;
&lt;br /&gt;
=== Das DDNS-Protokoll von DynDNS.org ===&lt;br /&gt;
&lt;br /&gt;
In den 90er Jahren, bevor das Internet so durchgehend vergeschäftlicht wurde, boten einige Organisationen kostenlose DDNS-Dienste an. Ein sehr beliebtes Angebot war das von DynDNS.org. Das DDNS-Protokoll von diesem Dienst wurde sogar in Einwahl-Routern einprogrammiert und der Dienst wurde von ISPs und Router-Herstellern als Leistungsmerkmal beworben.&lt;br /&gt;
&lt;br /&gt;
DynDNS.org gehört inzwischen Oracle und bietet keine kostenlose Dienste mehr. Dennoch wird das DDNS-Protokoll von DynDNS.org in der vorliegenden Beispielimplementierung übernommen in der Hoffnung, daß die Kompatibilität mit einigen gängigen Einwahl-Routern von Vorteil sein kann. Es gibt noch eine kurze Online-Dokumentation der [https://help.dyn.com/remote-access-api/perform-update/ Anfrage] und [https://help.dyn.com/remote-access-api/perform-update/ Antwortnachrichten].&lt;br /&gt;
&lt;br /&gt;
Das gesammte Protokoll sieht einen einzigen Nachrichtenaustausch aus Anfrage und Antwort vor. Die Anfrage kann mehrere Argumente enthalten; die Antwort kann verschiedene Code-Wörtern enthalten. Übrigens können in einer einzigen Anfrage mehrere DNS-Einträge gewünscht werden. In diesem Fall kann die Antwort mehrzeilig ausfallen.&lt;br /&gt;
&lt;br /&gt;
Das Verhalten von Server und Client bei künftigen Kommunikationsvorgängen wird unter Umständen von vorangegangenen Kommunikationsergebnissen beeinflußt: nach wiederholten fehlerhaften oder redundanten Anfragen kann der Server weitere Anfragen des Benutzers verweigern; nach wiederholten Fehlermeldungen sollte ein Client aufhören, immer dieselbe Anfrage zu schicken. Und für den Fall, daß mehrere Clients dynamische DNS-Einträge in derselben Domain example.com bestellen, muß der Server den Stand aller Client-Einträge intern speichern, damit er nicht mit einer neuen Zonefile einen früher erstellten Eintrag löscht. Zu diesen Fragen siehe den Abschnitt &#039;&#039;&#039;[[#Sukzessive_Kommunikationsabläufe]]&#039;&#039;&#039; nach der Beschreibung von Anfragen und Antworten unten.&lt;br /&gt;
&lt;br /&gt;
====Anfrage====&lt;br /&gt;
&lt;br /&gt;
Die Anfrage in Form eines URL übergibt dem DDNS-Programm in einem &#039;Query-String&#039; einige Metavariablen. Das heißt, in einem URL der Form&lt;br /&gt;
&lt;br /&gt;
  &amp;lt;nowiki&amp;gt;https://benutzername:passwort@ddns.beisiel.de/cgi-bin/ddns?hostname=einwahl.example.com&amp;amp;myip=87.65.43.21&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
signalisert das Fragezeichen, daß ein Query-String folgt. In einem solchen Query-String können in der Beispielimplementierung folgende Metavariablen definiert werden:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|- class=&amp;quot;hintergrundfarbe5&amp;quot;&lt;br /&gt;
! Variable !! Beispiel !! Bemerkungen&lt;br /&gt;
|-&lt;br /&gt;
| hostname || &amp;lt;tt&amp;gt;hostname=einwahl.example.com&amp;lt;/tt&amp;gt;&amp;lt;br /&amp;gt;&amp;lt;div style=&amp;quot;font-size:smaller;&amp;quot;&amp;gt;&amp;lt;tt&amp;gt;hostname=eins.example.com,zwei.example.com[,...]&amp;lt;/tt&amp;gt;&amp;lt;/div&amp;gt; ||&lt;br /&gt;
Muß ein vollständig qualifizierter Domain-Name (&amp;quot;FQDN&amp;quot;) sein; &amp;lt;tt&amp;gt;example.com&amp;lt;/tt&amp;gt; muß eine vom Besitzer des DDNS-Programms verwaltete Domain sein. Genaugenommen kann der Wert eine durch Kommata gegliederte Liste mehrerer gültiger Domainnamen sein, falls mehrere Einträge mit derselben IP-Adresse gewünscht werden.&lt;br /&gt;
|-&lt;br /&gt;
| myip || &amp;lt;tt&amp;gt;myip=87.65.43.21&amp;lt;/tt&amp;gt;||&lt;br /&gt;
Kann entfallen; kann vom Server ignoriert werden. Maßgeblich ist dann die IP-Adresse des Absenders, wie sie vom Web-Server mitgeteilt wird.&lt;br /&gt;
|-&lt;br /&gt;
| mx || &amp;lt;tt&amp;gt;mx=87.65.43.21&amp;lt;/tt&amp;gt;&amp;lt;br /&amp;gt;&amp;lt;tt&amp;gt;mx=NOCHG&amp;lt;/tt&amp;gt;&amp;lt;br /&amp;gt; ||&lt;br /&gt;
Neben dem A-Eintrag möchte der Client auch einen MX-Eintrag. Der Wert &amp;lt;tt&amp;gt;NOCHG&amp;lt;/tt&amp;gt; (für &amp;amp;bdquo;no change&amp;amp;ldquo;) bedeutet, der bestehende MX-Eintrag (oder seine Abwesenheit) soll nicht geändert werden. &lt;br /&gt;
|-&lt;br /&gt;
| backmx || &amp;lt;tt&amp;gt;backmx=YES&amp;lt;/tt&amp;gt;&amp;lt;br /&amp;gt;&amp;lt;tt&amp;gt;backmx=NOCHG&amp;lt;/tt&amp;gt;&amp;lt;br /&amp;gt;&amp;lt;tt&amp;gt;backmx=NO&amp;lt;/tt&amp;gt;   ||&lt;br /&gt;
Falls &amp;lt;tt&amp;gt;YES&amp;lt;/tt&amp;gt;, wird ein zweiter MX-Eintrag erzeugt, der &amp;lt;tt&amp;gt;einwahl.example.com&amp;lt;/tt&amp;gt; als Mail-Server für &amp;lt;tt&amp;gt;einwahl.example.com&amp;lt;/tt&amp;gt; nennt. Dieser Eintrag hat eine niedrigere Präferenzzahl (also eine höhere Priorität) als der mit &amp;lt;tt&amp;gt;mx&amp;lt;/tt&amp;gt; angeforderten Eintrag.&lt;br /&gt;
|-&lt;br /&gt;
| wildcard || &amp;lt;tt&amp;gt;wildcard=ON&amp;lt;/tt&amp;gt;&amp;lt;br /&amp;gt;&amp;lt;tt&amp;gt;wildcard=NOCHG&amp;lt;/tt&amp;gt;&amp;lt;br /&amp;gt;&amp;lt;tt&amp;gt;wildcard=OFF&amp;lt;/tt&amp;gt; ||&lt;br /&gt;
Neben dem A-Eintrag für den Domainnamen &amp;lt;tt&amp;gt;einwahl.example.com&amp;lt;/tt&amp;gt; wünscht der Client auch einen Eintrag für beliebige Subdomains, also &amp;lt;tt&amp;gt;*.einwahl.example.com&amp;lt;/tt&amp;gt;, mit der gleichen IP-Adresse.&lt;br /&gt;
|-&lt;br /&gt;
| offline ||&amp;lt;tt&amp;gt;offline=YES&amp;lt;/tt&amp;gt;&amp;lt;br /&amp;gt;&amp;lt;tt&amp;gt;offline=NOCHG&amp;lt;/tt&amp;gt;||&lt;br /&gt;
Falls &amp;lt;tt&amp;gt;YES&amp;lt;/tt&amp;gt;, wird ein DNS-Eintrag für &amp;lt;tt&amp;gt;einwahl.example.com&amp;lt;/tt&amp;gt; aus der Zonefile getilgt. Gegebenenfalls wird der Hostname dann auf Grund eines parallelen Wildcard-Eintrags für &amp;lt;tt&amp;gt;*.example.com&amp;lt;/tt&amp;gt; einer anderen IP-Adresse zugeordnet werden.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;!-- IPv6? --&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Alle Parameter bis auf hostname können entfallen. Bei nichtdokumentierten Argumenten ist das Verhalten undefiniert&amp;amp;trade;.&lt;br /&gt;
&lt;br /&gt;
====Antwort====&lt;br /&gt;
&lt;br /&gt;
Die Antwort auf eine erfolgreiche HTTP-Anfrage besteht im häufigsten Fall aus einigen Header-Zeilen, gefolgt vom Inhalt der gewünschten Text- oder andere Datei. Ein Status-Code in der ersten Header-Zeile gibt an, ob die Anfrage bedient werden kann oder kreist andernfalls den Grund für die Enttäuschung ein.&lt;br /&gt;
&lt;br /&gt;
Die vorliegende Beispielimplementierung von DDNS schickt einen der üblichen HTTP-Status-Codes &amp;quot;200 OK&amp;quot; oder &amp;quot;500 Internal Server Error&amp;quot;, gefolgt von einer kurzen Textnachricht nach dem HTTP-Header. Bei diesem Programm  ist &amp;amp;ndash; laut Gebrauchshinweise von DynDNS.org &amp;amp;ndash; &#039;&#039;nicht&#039;&#039; der Status-Code im Header, sondern der Inhalt der Nachricht  die definierte, maßgebliche Ergebnismeldung des Programms.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|- class=&amp;quot;hintergrundfarbe5&amp;quot;&lt;br /&gt;
! Meldung !! Bedeutung !! Bemerkungen&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;good&amp;amp;nbsp;&amp;amp;lt;IP&amp;amp;nbsp;number&amp;amp;gt;&amp;lt;/tt&amp;gt; ||&lt;br /&gt;
Der gewünschte DNS-Eintrag wurde erfolgreich in einer Zonefile eingetragen. &lt;br /&gt;
|| Es kann natürlich noch einige Minuten dauern, bis die Zonefile vom Hostsharing-Roboter abgelesen wird und der Inhalt in die BIND-Konfiguration übernommen.&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;good&amp;amp;nbsp;0.0.0.0&amp;lt;/tt&amp;gt; ||&lt;br /&gt;
Das Argument &amp;lt;tt&amp;gt;offline=YES&amp;lt;/tt&amp;gt; wurde empfangen und verarbeitet.&lt;br /&gt;
|| Der Domainname hat also keinen dynamischen DNS-Eintrag mehr.&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;good&amp;amp;nbsp;127.0.0.1&amp;lt;/tt&amp;gt; ||&lt;br /&gt;
Die Anfrage entsprach nicht den Erfordernissen des Servers.&lt;br /&gt;
|| Trotz des Worts &amp;lt;tt&amp;gt;good&amp;lt;/tt&amp;gt; war die Anfrage nicht erfolgreich, falls in der Rückmeldung die IP-Adresse mit &amp;lt;tt&amp;gt;127.0.0.1&amp;lt;/tt&amp;gt; angegeben wird. Dieser verwirrende Fehlercode ist aus unerklärlichen Gründen in der Spezifikation von DynDNS.org so definiert.&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;nochg&amp;amp;nbsp;&amp;amp;lt;IP&amp;amp;nbsp;number&amp;amp;gt;&amp;lt;/tt&amp;gt; ||&lt;br /&gt;
Der gewünschte DNS-Eintrag war bereits vorhanden. &lt;br /&gt;
|| Der Server selbst macht keine DNS-Abfrage, um das zu vermitteln: die &amp;amp;bdquo;no change&amp;amp;ldquo;-Antwort besagt nur, daß eine Anfrage für diesen Eintrag bereits mit Erfolg quittiert wurde.&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;notfqdn&amp;lt;/tt&amp;gt; ||&lt;br /&gt;
Fehlschlag: der gewünschte Domainname ist nicht gültig, oder es wurde keiner angegeben.&lt;br /&gt;
|| ...&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;nohost&amp;lt;/tt&amp;gt; ||&lt;br /&gt;
Fehlschlag: der gewünschte Domainname ist gehört nicht zu denen, die für diesen Benutzer des DDNS-Dienstes konfiguriert sind.&lt;br /&gt;
|| Siehe den Abschnitt [[#Administration|Administration]] weiter unten.&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;badauth&amp;lt;/tt&amp;gt; ||&lt;br /&gt;
Fehlschlag: Die Kombination von Benutzernamen und Paßwort entsprach keinem DDNS-Account, oder das Account ist momentan gesperrt.&lt;br /&gt;
|| Ein gesperrtes Account kann nur der Domain-Admin mittels des Administrationswerkzeugs wieder freigeben: siehe den Abschnit [[#Administration|Administration]] weiter unten.&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;abuse&amp;lt;/tt&amp;gt; ||&lt;br /&gt;
Fehlschlag: der gewünschte Domainname ist wegen vorangeganger Fehlschläge oder überflüssiger Aufrufe gesperrt.&lt;br /&gt;
|| Siehe den Abschnitt [[Sukzessive_Kommunikationsabläufe|Sukzessive Kommunikationsabläufe]] unten.&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;911&amp;lt;/tt&amp;gt; ||&lt;br /&gt;
Fehlschlag: Das Server-Programm hat einen internen Fehler festgestellt.&lt;br /&gt;
|| Das Problem liegt nicht in der Anfrage an sich.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Man kann sich durchaus eine sinnreichere Kommunikation zwischen Client und Server vorstellen, doch das hier beschriebene Protokoll ist eben von DynDNS.org verwendet worden und wird in gängigen Routern implementiert, also wird es in der vorliegenden DDNS-Implementierung nachgebildet.&lt;br /&gt;
&lt;br /&gt;
=== Sukzessive Kommunikationsabläufe ===&lt;br /&gt;
Der Server muß sich zwischen einzelnen Aufrufen einiges merken, um Ressourcen zu schonen und um zu verhindern, daß einmal vergebene DDNS-Einträge von neuen Anfragen, die dieselbe übergeordnete Domain betreffen, durch Überschreiben  verlorengehen.&lt;br /&gt;
&lt;br /&gt;
==== Mißbrauch und Benutzersperrung ====&lt;br /&gt;
Zur Schonung von Ressourcen muß sich die Implementierung weigern, sich mit zuvielen fehlerhaften oder auch nur überflüssigen Anfragen zu beschäftigen. Dazu führt eine Strichliste über solche Anfragen jedes Clients und sperrt nach einer bestimmten Anzahl solcher Anfragen den Benutzernamen oder einzelne Domainnamen gegen die weitere Nutzung des Dienstes.&lt;br /&gt;
&lt;br /&gt;
Mißbrauchspunkte gegen einen einzelnen Domainnamen gibt es für:&lt;br /&gt;
* eine Anfrage, die keinen neuen DNS-Eintrag (und keine Änderung oder Löschung eines Eintrags) erfordert, sondern bestehende Merkmale nur wiederholt&lt;br /&gt;
&lt;br /&gt;
Mißbrauchspunkte gegen einen Benutzernamen gibt es für:&lt;br /&gt;
* die Angabe eines Domainnamens, der in der Dienstkonfiguration dem anfragenden Benutzernamen nicht zugeordnet ist&lt;br /&gt;
* die Angabe eines Domainnamen in einer Domain, die nicht demselben Hostsharing-Domain-Admin gehört, der den DDNS-Dienst anbietet&lt;br /&gt;
* die Angabe eines Domainnamens, der in der Dienstkonfiguration bereits wegen mißbräuchlicher Anfragen gesperrt ist (siehe oben)&lt;br /&gt;
&lt;br /&gt;
Um eine Sperrung aufzuheben, wird in der Regel eine Handlung durch den Administrator erforderlich sein.&lt;br /&gt;
&lt;br /&gt;
==== Mehrere dynamische Subdomains in derselben Domain ====&lt;br /&gt;
Sobald zwei verschiedene DDNS-Einträge in derselben Domain verlangt werden &amp;amp;ndash; beispielsweise home.example.com und office.example.com &amp;amp;ndash; wird es notwendig, bei jeder neuen Zonefile für example.com eventuell frühere Einträge zu konservieren. Der Rechner zu Hause weiß beim Bestellen seines DDNS-Eintrags nichts vom Rechner im Büro und umgekehrt. Der Server muß in irgendeiner Form über bereits vergebene Einträge Buch führen und bei einer neuen Anfrage, die example.com betrifft, alle bereits aktiven DDNS-Einträge für example.com mit in die neue Zonefile aufnehmen &amp;amp;ndash auch wenn sie auf Anfragen verschiedener Benutzer zurückgehen.&lt;br /&gt;
&lt;br /&gt;
==== Datenbank ====&lt;br /&gt;
In der Beispielimplementierung werden diese Informationen in einer SQLite-Datenbank gespeichert.&lt;br /&gt;
&lt;br /&gt;
== Sicherheit ==&lt;br /&gt;
=== Rechte ===&lt;br /&gt;
Die &#039;&#039;&#039;Benutzerrechte&#039;&#039;&#039; werden durch das Hostsharing-System kontrolliert. Sowohl das CGI-Programm als auch das [[#Administration|Administrationswerkzeug]] werden mit den Rechten des Domain-Admins (xyz00-benutzername in unserem Beispiel) ausgeführt, also kann dieses Programm nur die Domains bearbeiten, die von xyz00-benutzername verwaltet werden.&lt;br /&gt;
&lt;br /&gt;
=== Authentifizierung ===&lt;br /&gt;
In der Beispielimplementierung (wie auch seinerzeit bei DynDNS.org) wird das CGI-Programm durch einen .htaccess-Eintrag geschützt, der HTTP-Basic-Authentication vorschreibt. Also wird das Programm eigentlich mit einem URL der form&lt;br /&gt;
&lt;br /&gt;
  &amp;lt;nowiki&amp;gt;https://ddnsaccount:passwort@ddns.example.com/cgi-bin/ddns?hostname=...&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
aufgerufen.&lt;br /&gt;
&lt;br /&gt;
=== Verschlüsselung ===&lt;br /&gt;
Das CGI-Programm sollte nur in example.com/cgi-ssl/ installiert werden, nicht in example.com/cgi/. Damit ist die Kommunikation zwischen Client und Server durch SSL verschlüsselt.&lt;br /&gt;
&lt;br /&gt;
== Administration ==&lt;br /&gt;
&lt;br /&gt;
Der Verwalter des DDNS-Programms trägt berechtigte Benutzer und die ihnen zugeteilten Domainnamen in die Datenbank des Programms ein mit Hilfe eines kleinen Hilfsprogramms. Das ist im vorliegenden Fall ein menügesteuertes Programm für die Befehlszeile, daß die naheliegenden Funktionen anbietet: Account hinzufügen, löschen, sperren, entsperren, Paßwort setzen, ändern; Domainnamen hinzufügen, ändern, entsperren, löschen; Accounts und Domainnamen mit aktuellem Status auflisten. Die Funktionen sind auch über Befehlszeilenargumente verfügbar, also skriptfähig.&lt;br /&gt;
&lt;br /&gt;
Eine Auflistung des momentanen Inhalts der DDNS-Datenbank durch das Administrationswerkzeug könnte beispielsweise so aussehen:&lt;br /&gt;
&lt;br /&gt;
  xyz00-benutzername@h02:~$ bin/ddnsadmin.pl -Aa&lt;br /&gt;
  1.  papst	Mißbrauch: 0; gesperrt: nein&lt;br /&gt;
  	avignon.example.com&lt;br /&gt;
  		zuletzt aktiv am Sun Apr 26 22:24:49 2020&lt;br /&gt;
  		mit IP-Nr. 87.65.43.21; MX: 0;  Backup-MX: nein;&lt;br /&gt;
  		Subdomains: nein; Mißbrauch: 0;  gesperrt: nein&lt;br /&gt;
  	vatican.beispiel.de&lt;br /&gt;
  		zuletzt aktiv am Sun Apr 26 22:24:49 2020&lt;br /&gt;
  		mit IP-Nr. 87.65.43.21; MX: 0;  Backup-MX: nein;&lt;br /&gt;
  		Subdomains: nein; Mißbrauch: 0;  gesperrt: nein&lt;br /&gt;
  2.  kaiser	Mißbrauch: 4; gesperrt: ja&lt;br /&gt;
  	augsburg.beispiel.de&lt;br /&gt;
  		zuletzt aktiv am Fri Apr 24 16:13:49 2020&lt;br /&gt;
  		mit IP-Nr. 64.82.31.75; MX: 0;  Backup-MX: nein;&lt;br /&gt;
  		Subdomains: nein; Mißbrauch: 0;  gesperrt: ja&lt;br /&gt;
  3.  luther	Mißbrauch: 1; gesperrt: nein&lt;br /&gt;
  	wittenberg.example.com&lt;br /&gt;
  		zuletzt aktiv am Mon Apr 27 10:12:49 2020&lt;br /&gt;
  		mit IP-Nr. 78.56.34.12; MX: 0;  Backup-MX: nein;&lt;br /&gt;
  		Subdomains: nein; Mißbrauch: 1;  gesperrt: nein&lt;br /&gt;
  xyz00-benutzername@h02:~$&lt;br /&gt;
&lt;br /&gt;
Das DDNS-Account &amp;amp;bdquo;kaiser&amp;amp;ldquo; in dieser Auflistung ist wohl auf Grund fehlerhafter Anfragen automatisch gesperrt worden. Der Inhaber wird sich wohl bald melden, um nach Korrektur seiner Client-Konfiguration die Aufhebung der Sperre zu wünschen.&lt;br /&gt;
&lt;br /&gt;
=== Log ===&lt;br /&gt;
Alle Anfragen werden in einer täglich wechselnden Log-Datei protokolliert, entweder schlicht oder ausführlich, je nachdem, ob eine Variable &amp;lt;tt&amp;gt;verbose&amp;lt;/tt&amp;gt; wahr ist.&lt;br /&gt;
Ein ausführlicher Log-Eintrag sieht so aus:&lt;br /&gt;
&lt;br /&gt;
  Sun Apr 26 20:21:45 2020  ddns aufgerufen von papst&lt;br /&gt;
  			unter 84.185.97.8&lt;br /&gt;
  	URL: &amp;lt;nowiki&amp;gt;https://ddns.example.com/cgi-bin/ddns.cgi?hostname=&lt;br /&gt;
  			avignon.example.com,vatican.beispiel.de&amp;amp;&lt;br /&gt;
  			myip=84.185.97.8&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
  	Verwende IP 84.185.97.8 (= 1421435144)&lt;br /&gt;
  	DB-Version: 1&lt;br /&gt;
  	Skript und DB exklusiv geöffnet&lt;br /&gt;
  	avignon.example.com: IP: 84.185.97.8; MX: 0; Backup-MX: nein;&lt;br /&gt;
  			Wildcard: nein; Mißbrauch: 0; gesperrt: nein &lt;br /&gt;
  	vatican.beispiel.de: IP: 84.185.97.8; MX: 0; Backup-MX: nein;&lt;br /&gt;
  			Wildcard: nein; Mißbrauch: 0; gesperrt: nein &lt;br /&gt;
  	Betroffene Zonen: example.com, beispiel.de&lt;br /&gt;
  	Temporärdatei example.com_hxNa.new geschrieben&lt;br /&gt;
  	Zonendatei /home/pacs/xyz00/users/benutzername/doms/example.com/&lt;br /&gt;
  			etc/pri.example.com eingestellt&lt;br /&gt;
  	Temporärdatei beispiel.de_6HcO.new geschrieben&lt;br /&gt;
  	Zonendatei /home/pacs/xyz00/users/benutzername/doms/beispiel.de/&lt;br /&gt;
  			etc/pri.beispiel.de eingestellt&lt;br /&gt;
  	Abgeschlossen: 	Fertig&lt;br /&gt;
&lt;br /&gt;
Wenn &amp;lt;tt&amp;gt;verbose&amp;lt;/tt&amp;gt; auf falsch gesetzt ist, sind die Log-Einträge einzeilig.&lt;/div&gt;</summary>
		<author><name>Apc00-tony</name></author>
	</entry>
	<entry>
		<id>https://wiki.hostsharing.net/index.php?title=Benutzer:Apc00-tony/Dynamisches_DNS&amp;diff=5197</id>
		<title>Benutzer:Apc00-tony/Dynamisches DNS</title>
		<link rel="alternate" type="text/html" href="https://wiki.hostsharing.net/index.php?title=Benutzer:Apc00-tony/Dynamisches_DNS&amp;diff=5197"/>
		<updated>2020-04-29T09:30:22Z</updated>

		<summary type="html">&lt;p&gt;Apc00-tony: /* Antwort */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;((Provisorischer Vorspann: Auf Grund einer Mailing-Listen-Diskussion habe ich angefangen, Dynamisches DNS über einen CGI-Skript bei Hostsharing zu realisieren. Meine Lösung habe ich dann vorgestellt; sie wurde für nicht ausreichend selbsterklärend befunden und fand wenig Akzeptanz. Hier also der Versuch, die Sache zu dokumentieren.))&lt;br /&gt;
&lt;br /&gt;
Mit der regelmäßigen Aufnahme von benutzerspezifischen Zonefiles in seiner DNS-Konfiguration bietet  Hostsharing alles, was man braucht, um &amp;amp;bdquo;dynamisches DNS&amp;amp;ldquo; in Eigenregie zu realisieren.&lt;br /&gt;
&lt;br /&gt;
Das heißt, wenn ich mindestens eine Domain bei Hostsharing verwalte, und mindestens eine Einwahlverbindung (oder DSL-Verbindung) ins Internet mit wechselnder IP-Adresse über irgendeinen ISP für meinen Arbeitsplatzrechner zu Hause betreibe, dann kann ich dem Arbeitsplatzrechner über die DNS-Server von Hostsharing einen vollqualifizieren Domainnamen zuweisen, der der jeweiligen IP-Adresse meiner Einwahlleitung zugeordnet ist.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
(ASCII-Art-Diagramm der beschriebenen Konstellation)&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Im Folgenden wird eine real existierende Implementierung von Dynamischem DNS (&amp;amp;bdquo;DDNS&amp;amp;ldquo;) beschrieben. Die verschiedenen Elemente könnten durchaus anders realisiert werden; die beschriebene Implementierung könnte durchaus verbessert werden. Sie dient hier der Illustration.&lt;br /&gt;
&lt;br /&gt;
In der folgenden Beschreibung werden diese Beispielwerte benutzt:&lt;br /&gt;
* Ein Hostsharing-Mitglied hat ein Account als Paket-Admin mit Kennung xyz00.&lt;br /&gt;
* Im Paket xyz00 gibt es einen Domain-Admin namens xyz00-benutzername.&lt;br /&gt;
* Dieser Domain-Admin verwaltet bei Hostsharing die Domains example.com und beispiel.de.&lt;br /&gt;
* Ein Benutzer hat zu Hause (oder im Büro) einen Arbeitsplatzrechner hinter der marktüblichen DSL-Leitung, die von seinem ISP bereitgestellt wird.&lt;br /&gt;
* Dieser Arbeitsplatzrechner (oder der Router, der seine Internetverbindung steuert) bekommt vom ISP immer wechselnde IP-Adressen zugewiesen.&lt;br /&gt;
* Dennoch möchte der Benutzer seinen Arbeitsplatzrechner aus dem Internet unter dem Hostnamen einwahl.example.com ansprechen können.&lt;br /&gt;
&lt;br /&gt;
Dazu kann ein System wie Hostsharing, das authoritative DNS-Informationen für viele Domains bereitstellt, auch veränderliche DNS-Information über dynamisch verbundene Rechner verwalten &amp;amp;ndash; sofern das ressourcenschonend gemacht werden kann ohne andere Funktionen zu stören.&lt;br /&gt;
&lt;br /&gt;
== Aufgaben des Servers ==&lt;br /&gt;
&lt;br /&gt;
Um einem Rechner mit wechselnder IP-Adresse einen DDNS-Eintrag zu bieten, muß der Hostsharing-Server folgendes leisten (in ungefährer Reihenfolge der Ereignisse):&lt;br /&gt;
&lt;br /&gt;
# Eine Anfrage entgegennehmen, beispielsweise über HTTPS, von einem entfernten Rechner, der einen DNS-Eintrag für seine momentane IP-Adresse wünscht. &lt;br /&gt;
# Prüfen, ob die Anfrage einen berechtigten DDNS-Dienst-Usernamen mit zugehörigem Paßwort enthält.&lt;br /&gt;
# Prüfen, ob die Anfrage einen gültigen Domainnamen betrifft, den der Server bieten darf.&lt;br /&gt;
# Prüfen, ob die Domain example.com demselben Benutzer gehört, unter dessen Namen der Dynamisches-DNS-Server läuft.&lt;br /&gt;
# Eine gültige [[Zonefile]] mit &amp;amp;ndash; neben dem bisherigen Inhalt &amp;amp;ndash; einem A-Eintrag für einwahl.example.com in /home/pacs/xyz00/users/benutzername/doms/example.com/pri.example.com schreiben.&lt;br /&gt;
# Dem Client eine Bestätigung oder ggf. eine Fehlermeldung als Antwort senden.&lt;br /&gt;
# In irgendeiner Datenbank den momentan eingestellter Status all seiner DDNS-Einträge speichern.&lt;br /&gt;
# In einer Logdatei protokollieren, daß obiges getan wurde, oder ggf. welche Fehler traten auf.&lt;br /&gt;
&lt;br /&gt;
== Aufgaben des Clients ==&lt;br /&gt;
Bevor ich anfange, meinen Arbeitsplatzrechner so zu konfigurieren, daß er bei welchem Server auch immer einen DDNS-Eintrag anfordert, muß ich mich als verantwortlicher Benutzer dieses Rechners und der dazugehörigen Internetverbindung &amp;amp;ndash; das heißt, als Mensch &amp;amp;ndash; mit dem Betreiber des dynamisches-DNS-Servers vereinbaren, daß ich das darf und welchen Eintrag ich bekommen kann. Im Folgenden wird vorausgesetzt, daß solche Vereinbarungen getroffen und die Parameter geklärt wurden.&lt;br /&gt;
&lt;br /&gt;
Der DDNS-Client muß aus Server-Sicht nur wenig leisten:&lt;br /&gt;
&lt;br /&gt;
# Eine Anfrage senden, beispielsweise über HTTPS, an einen entfernten Rechner, der einen Eintrag ins DNS für die momentane IP-Adresse des Clients vornehmen kann.&amp;lt;br /&amp;gt;Diese Anfrage muß einem festgelegten Format entsprechen und muß gültige Werte für die Authorisation des Clients, den gewünschten Domainnamen, und eventuell andere Parameter enthalten.&lt;br /&gt;
# Eine Antwort des Servers entgegennehmen und als Erfolgs- oder Fehlermeldung auswerten.&lt;br /&gt;
# Von überflüssigen Anfragen absehen: das heißt bei Erfolg, nicht wiederholt den gleichen Eintrag erneut wünschen; bei Fehlern, nicht die gleiche fehlerhafte Anfrage erneut schicken.&lt;br /&gt;
&lt;br /&gt;
== Kommunikation zwischen Client und Server ==&lt;br /&gt;
&lt;br /&gt;
Ein einziges Nachrichtenpaar von Anfrage und Antwort genügt, um einen DDNS-Eintrag einzurichten: Der Client teilt die IP-Adresse und den Domainnamen mit, die in einem DNS-Eintrag verbunden werden sollen; der Server bestätigt den Auftrag.&lt;br /&gt;
&lt;br /&gt;
In der Beispielimplementierung erfolgt die Kommunikation über HTTP, und die Anfrage des Clients könnte so aussehen:&lt;br /&gt;
&lt;br /&gt;
  GET /cgi-bin/ddns?hostname=einwahl.example.com&amp;amp;myip=87.65.43.21 HTTP/1.1&lt;br /&gt;
  Host: ddns.beispiel.de&lt;br /&gt;
  User-Agent: Fritz!Box DDNS/1.0.1&lt;br /&gt;
  Authorization: Basic QWxhZGRpbjpvcGVuIHNlc2FtZQ==&lt;br /&gt;
&lt;br /&gt;
Bei Erhalt dieser Anfrage ruft Apache das CGI-Programm .../doms/ddns.beispiel.de/cgi-ssl/ddns auf. Das Fragezeichen trennt den Programmnamen von einem &amp;quot;Query-String&amp;quot;, in dem zwei Metavariablen definiert und übergeben werden. Die erste Metavariable, hostname, hat den Wert &amp;quot;einwahl.example.com&amp;quot;; die zweite, myip, hat den Wert &amp;quot;87.65.43.21&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
Das Server-Programm, hier &#039;&#039;ddns&#039;&#039;, prüft diese Informationen auf Form und Berechtigung, und schreibt gegebenenfalls einen entsprechenden Eintrag in einer Zonefile. Es schreibt auch verschiedene Informationen in die Standardausgabe. Wenn es die Standardausgabe geschlossen wird &amp;amp;ndash; also spätestens bei Programmende &amp;amp;ndash; schickt Apache diese Informationen als Antwort an den anfragenden Rechner zurück.&lt;br /&gt;
&lt;br /&gt;
Im Falle unserer Beispielimplementierung sieht die Antwort bei Erfolg so aus: &lt;br /&gt;
&lt;br /&gt;
  HTTP/1.1 200 OK&lt;br /&gt;
  Date: Wed, 22 Apr 2020 08:35:15 GMT&lt;br /&gt;
  Server: Apache&lt;br /&gt;
  Content-Length: 17&lt;br /&gt;
  Content-Type: text/plain; charset=ISO-8859-1&lt;br /&gt;
 &lt;br /&gt;
  good 87.65.43.21&lt;br /&gt;
&lt;br /&gt;
=== Das DDNS-Protokoll von DynDNS.org ===&lt;br /&gt;
&lt;br /&gt;
In den 90er Jahren, bevor das Internet so durchgehend vergeschäftlicht wurde, boten einige Organisationen kostenlose DDNS-Dienste an. Ein sehr beliebtes Angebot war das von DynDNS.org. Das DDNS-Protokoll von diesem Dienst wurde sogar in Einwahl-Routern einprogrammiert und der Dienst wurde von ISPs und Router-Herstellern als Leistungsmerkmal beworben.&lt;br /&gt;
&lt;br /&gt;
DynDNS.org gehört inzwischen Oracle und bietet keine kostenlose Dienste mehr. Dennoch wird das DDNS-Protokoll von DynDNS.org in der vorliegenden Beispielimplementierung übernommen in der Hoffnung, daß die Kompatibilität mit einigen gängigen Einwahl-Routern von Vorteil sein kann. Es gibt noch eine kurze Online-Dokumentation der [https://help.dyn.com/remote-access-api/perform-update/ Anfrage] und [https://help.dyn.com/remote-access-api/perform-update/ Antwortnachrichten].&lt;br /&gt;
&lt;br /&gt;
Das gesammte Protokoll sieht einen einzigen Nachrichtenaustausch aus Anfrage und Antwort vor. Die Anfrage kann mehrere Argumente enthalten; die Antwort kann verschiedene Code-Wörtern enthalten. Übrigens können in einer einzigen Anfrage mehrere DNS-Einträge gewünscht werden. In diesem Fall kann die Antwort mehrzeilig ausfallen.&lt;br /&gt;
&lt;br /&gt;
Das Verhalten von Server und Client bei künftigen Kommunikationsvorgängen wird unter Umständen von vorangegangenen Kommunikationsergebnissen beeinflußt: nach wiederholten fehlerhaften oder redundanten Anfragen kann der Server weitere Anfragen des Benutzers verweigern; nach wiederholten Fehlermeldungen sollte ein Client aufhören, immer dieselbe Anfrage zu schicken. Und für den Fall, daß mehrere Clients dynamische DNS-Einträge in derselben Domain example.com bestellen, muß der Server den Stand aller Client-Einträge intern speichern, damit er nicht mit einer neuen Zonefile einen früher erstellten Eintrag löscht. Zu diesen Fragen siehe den Abschnitt &#039;&#039;&#039;[[#Sukzessive_Kommunikationsabläufe]]&#039;&#039;&#039; nach der Beschreibung von Anfragen und Antworten unten.&lt;br /&gt;
&lt;br /&gt;
====Anfrage====&lt;br /&gt;
&lt;br /&gt;
Die Anfrage in Form eines URL übergibt dem DDNS-Programm in einem &#039;Query-String&#039; einige Metavariablen. Das heißt, in einem URL der Form&lt;br /&gt;
&lt;br /&gt;
  &amp;lt;nowiki&amp;gt;https://benutzername:passwort@ddns.beisiel.de/cgi-bin/ddns?hostname=einwahl.example.com&amp;amp;myip=87.65.43.21&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
signalisert das Fragezeichen, daß ein Query-String folgt. In einem solchen Query-String können in der Beispielimplementierung folgende Metavariablen definiert werden:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|- class=&amp;quot;hintergrundfarbe5&amp;quot;&lt;br /&gt;
! Variable !! Beispiel !! Bemerkungen&lt;br /&gt;
|-&lt;br /&gt;
| hostname || &amp;lt;tt&amp;gt;hostname=einwahl.example.com&amp;lt;/tt&amp;gt;&amp;lt;br /&amp;gt;&amp;lt;div style=&amp;quot;font-size:smaller;&amp;quot;&amp;gt;&amp;lt;tt&amp;gt;hostname=eins.example.com,zwei.example.com[,...]&amp;lt;/tt&amp;gt;&amp;lt;/div&amp;gt; ||&lt;br /&gt;
Muß ein vollständig qualifizierter Domain-Name (&amp;quot;FQDN&amp;quot;) sein; &amp;lt;tt&amp;gt;example.com&amp;lt;/tt&amp;gt; muß eine vom Besitzer des DDNS-Programms verwaltete Domain sein. Genaugenommen kann der Wert eine durch Kommata gegliederte Liste mehrerer gültiger Domainnamen sein, falls mehrere Einträge mit derselben IP-Adresse gewünscht werden.&lt;br /&gt;
|-&lt;br /&gt;
| myip || &amp;lt;tt&amp;gt;myip=87.65.43.21&amp;lt;/tt&amp;gt;||&lt;br /&gt;
Kann entfallen; kann vom Server ignoriert werden. Maßgeblich ist dann die IP-Adresse des Absenders, wie sie vom Web-Server mitgeteilt wird.&lt;br /&gt;
|-&lt;br /&gt;
| mx || &amp;lt;tt&amp;gt;mx=87.65.43.21&amp;lt;/tt&amp;gt;&amp;lt;br /&amp;gt;&amp;lt;tt&amp;gt;mx=NOCHG&amp;lt;/tt&amp;gt;&amp;lt;br /&amp;gt; ||&lt;br /&gt;
Neben dem A-Eintrag möchte der Client auch einen MX-Eintrag. Der Wert &amp;lt;tt&amp;gt;NOCHG&amp;lt;/tt&amp;gt; (für &amp;amp;bdquo;no change&amp;amp;ldquo;) bedeutet, der bestehende MX-Eintrag (oder seine Abwesenheit) soll nicht geändert werden. &lt;br /&gt;
|-&lt;br /&gt;
| backmx || &amp;lt;tt&amp;gt;backmx=YES&amp;lt;/tt&amp;gt;&amp;lt;br /&amp;gt;&amp;lt;tt&amp;gt;backmx=NOCHG&amp;lt;/tt&amp;gt;&amp;lt;br /&amp;gt;&amp;lt;tt&amp;gt;backmx=NO&amp;lt;/tt&amp;gt;   ||&lt;br /&gt;
Falls &amp;lt;tt&amp;gt;YES&amp;lt;/tt&amp;gt;, wird ein zweiter MX-Eintrag erzeugt, der &amp;lt;tt&amp;gt;einwahl.example.com&amp;lt;/tt&amp;gt; als Mail-Server für &amp;lt;tt&amp;gt;einwahl.example.com&amp;lt;/tt&amp;gt; nennt. Dieser Eintrag hat eine niedrigere Präferenzzahl (also eine höhere Priorität) als der mit &amp;lt;tt&amp;gt;mx&amp;lt;/tt&amp;gt; angeforderten Eintrag.&lt;br /&gt;
|-&lt;br /&gt;
| wildcard || &amp;lt;tt&amp;gt;wildcard=ON&amp;lt;/tt&amp;gt;&amp;lt;br /&amp;gt;&amp;lt;tt&amp;gt;wildcard=NOCHG&amp;lt;/tt&amp;gt;&amp;lt;br /&amp;gt;&amp;lt;tt&amp;gt;wildcard=OFF&amp;lt;/tt&amp;gt; ||&lt;br /&gt;
Neben dem A-Eintrag für den Domainnamen &amp;lt;tt&amp;gt;einwahl.example.com&amp;lt;/tt&amp;gt; wünscht der Client auch einen Eintrag für beliebige Subdomains, also &amp;lt;tt&amp;gt;*.einwahl.example.com&amp;lt;/tt&amp;gt;, mit der gleichen IP-Adresse.&lt;br /&gt;
|-&lt;br /&gt;
| offline ||&amp;lt;tt&amp;gt;offline=YES&amp;lt;/tt&amp;gt;&amp;lt;br /&amp;gt;&amp;lt;tt&amp;gt;offline=NOCHG&amp;lt;/tt&amp;gt;||&lt;br /&gt;
Falls &amp;lt;tt&amp;gt;YES&amp;lt;/tt&amp;gt;, wird ein DNS-Eintrag für &amp;lt;tt&amp;gt;einwahl.example.com&amp;lt;/tt&amp;gt; aus der Zonefile getilgt. Gegebenenfalls wird der Hostname dann auf Grund eines parallelen Wildcard-Eintrags für &amp;lt;tt&amp;gt;*.example.com&amp;lt;/tt&amp;gt; einer anderen IP-Adresse zugeordnet werden.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;!-- IPv6? --&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Alle Parameter bis auf hostname können entfallen. Bei nichtdokumentierten Argumenten ist das Verhalten undefiniert&amp;amp;trade;.&lt;br /&gt;
&lt;br /&gt;
====Antwort====&lt;br /&gt;
&lt;br /&gt;
Die Antwort auf eine erfolgreiche HTTP-Anfrage besteht im häufigsten Fall aus einigen Header-Zeilen, gefolgt vom Inhalt der gewünschten Text- oder andere Datei. Ein Status-Code in der ersten Header-Zeile gibt an, ob die Anfrage bedient werden kann oder kreist andernfalls den Grund für die Enttäuschung ein.&lt;br /&gt;
&lt;br /&gt;
Die vorliegende Beispielimplementierung von DDNS schickt einen der üblichen HTTP-Status-Codes &amp;quot;200 OK&amp;quot; oder &amp;quot;500 Internal Server Error&amp;quot;, gefolgt von einer kurzen Textnachricht nach dem HTTP-Header. Bei diesem Programm  ist &amp;amp;ndash; laut Gebrauchshinweise von DynDNS.org &amp;amp;ndash; &#039;&#039;nicht&#039;&#039; der Status-Code im Header, sondern der Inhalt der Nachricht  die definierte, maßgebliche Ergebnismeldung des Programms.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|- class=&amp;quot;hintergrundfarbe5&amp;quot;&lt;br /&gt;
! Meldung !! Bedeutung !! Bemerkungen&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;good&amp;amp;nbsp;&amp;amp;lt;IP&amp;amp;nbsp;number&amp;amp;gt;&amp;lt;/tt&amp;gt; ||&lt;br /&gt;
Der gewünschte DNS-Eintrag wurde erfolgreich in einer Zonefile eingetragen. &lt;br /&gt;
|| Es kann natürlich noch einige Minuten dauern, bis die Zonefile vom Hostsharing-Roboter abgelesen wird und der Inhalt in die BIND-Konfiguration übernommen.&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;good&amp;amp;nbsp;0.0.0.0&amp;lt;/tt&amp;gt; ||&lt;br /&gt;
Das Argument &amp;lt;tt&amp;gt;offline=YES&amp;lt;/tt&amp;gt; wurde empfangen und verarbeitet.&lt;br /&gt;
|| Der Domainnamen hat also keinen dynamischen DNS-Eintrag mehr.&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;good&amp;amp;nbsp;127.0.0.1&amp;lt;/tt&amp;gt; ||&lt;br /&gt;
Die Anfrage entsprach nicht den Erfordernissen des Servers.&lt;br /&gt;
|| Trotz des Worts &amp;lt;tt&amp;gt;good&amp;lt;/tt&amp;gt; war die Anfrage nicht erfolgreich, falls in der Rückmeldung die IP-Adresse mit &amp;lt;tt&amp;gt;127.0.0.1&amp;lt;/tt&amp;gt; angegeben wird. Dieser verwirrende Fehlercode ist aus unerklärlichen Gründen in der Spezifikation von DynDNS.org so definiert.&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;nochg&amp;amp;nbsp;&amp;amp;lt;IP&amp;amp;nbsp;number&amp;amp;gt;&amp;lt;/tt&amp;gt; ||&lt;br /&gt;
Der gewünschte DNS-Eintrag war bereits vorhanden. &lt;br /&gt;
|| Der Server selbst macht keine DNS-Abfrage, um das zu vermitteln: die &amp;amp;bdquo;no change&amp;amp;ldquo;-Antwort besagt nur, daß eine Anfrage für diesen Eintrag bereits mit Erfolg quittiert wurde.&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;notfqdn&amp;lt;/tt&amp;gt; ||&lt;br /&gt;
Fehlschlag: der gewünschte Domainname ist nicht gültig, oder es wurde keiner angegeben.&lt;br /&gt;
|| ...&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;nohost&amp;lt;/tt&amp;gt; ||&lt;br /&gt;
Fehlschlag: der gewünschte Domainname ist gehört nicht zu denen, die für diesen Benutzer des DDNS-Dienstes konfiguriert sind.&lt;br /&gt;
|| Siehe den Abschnitt [[#Administration|Administration]] weiter unten.&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;badauth&amp;lt;/tt&amp;gt; ||&lt;br /&gt;
Fehlschlag: Die Kombination von Benutzernamen und Paßwort entsprach keinem DDNS-Account, oder das Account ist momentan gesperrt.&lt;br /&gt;
|| Ein gesperrtes Account kann nur der Domain-Admin mittels des Administrationswerkzeugs wieder freigeben: siehe den Abschnit [[#Administration|Administration]] weiter unten.&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;abuse&amp;lt;/tt&amp;gt; ||&lt;br /&gt;
Fehlschlag: der gewünschte Domainname ist wegen vorangeganger Fehlschläge oder überflüssiger Aufrufe gesperrt.&lt;br /&gt;
|| Siehe den Abschnitt [[Sukzessive_Kommunikationsabläufe|Sukzessive Kommunikationsabläufe]] unten.&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;911&amp;lt;/tt&amp;gt; ||&lt;br /&gt;
Fehlschlag: Das Server-Programm hat einen internen Fehler festgestellt.&lt;br /&gt;
|| Das Problem liegt nicht in der Anfrage an sich.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Man kann sich durchaus eine sinnreichere Kommunikation zwischen Client und Server vorstellen, doch das hier beschriebene Protokoll ist eben von DynDNS.org verwendet worden und wird in gängigen Routern implementiert, also wird es in der vorliegenden DDNS-Implementierung nachgebildet.&lt;br /&gt;
&lt;br /&gt;
=== Sukzessive Kommunikationsabläufe ===&lt;br /&gt;
Der Server muß sich zwischen einzelnen Aufrufen einiges merken, um Ressourcen zu schonen und um zu verhindern, daß einmal vergebene DDNS-Einträge von neuen Anfragen, die dieselbe übergeordnete Domain betreffen, durch Überschreiben  verlorengehen.&lt;br /&gt;
&lt;br /&gt;
==== Mißbrauch und Benutzersperrung ====&lt;br /&gt;
Zur Schonung von Ressourcen muß sich die Implementierung weigern, sich mit zuvielen fehlerhaften oder auch nur überflüssigen Anfragen zu beschäftigen. Dazu führt eine Strichliste über solche Anfragen jedes Clients und sperrt nach einer bestimmten Anzahl solcher Anfragen den Benutzernamen oder einzelne Domainnamen gegen die weitere Nutzung des Dienstes.&lt;br /&gt;
&lt;br /&gt;
Mißbrauchspunkte gegen einen einzelnen Domainnamen gibt es für:&lt;br /&gt;
* eine Anfrage, die keinen neuen DNS-Eintrag (und keine Änderung oder Löschung eines Eintrags) erfordert, sondern bestehende Merkmale nur wiederholt&lt;br /&gt;
&lt;br /&gt;
Mißbrauchspunkte gegen einen Benutzernamen gibt es für:&lt;br /&gt;
* die Angabe eines Domainnamens, der in der Dienstkonfiguration dem anfragenden Benutzernamen nicht zugeordnet ist&lt;br /&gt;
* die Angabe eines Domainnamen in einer Domain, die nicht demselben Hostsharing-Domain-Admin gehört, der den DDNS-Dienst anbietet&lt;br /&gt;
* die Angabe eines Domainnamens, der in der Dienstkonfiguration bereits wegen mißbräuchlicher Anfragen gesperrt ist (siehe oben)&lt;br /&gt;
&lt;br /&gt;
Um eine Sperrung aufzuheben, wird in der Regel eine Handlung durch den Administrator erforderlich sein.&lt;br /&gt;
&lt;br /&gt;
==== Mehrere dynamische Subdomains in derselben Domain ====&lt;br /&gt;
Sobald zwei verschiedene DDNS-Einträge in derselben Domain verlangt werden &amp;amp;ndash; beispielsweise home.example.com und office.example.com &amp;amp;ndash; wird es notwendig, bei jeder neuen Zonefile für example.com eventuell frühere Einträge zu konservieren. Der Rechner zu Hause weiß beim Bestellen seines DDNS-Eintrags nichts vom Rechner im Büro und umgekehrt. Der Server muß in irgendeiner Form über bereits vergebene Einträge Buch führen und bei einer neuen Anfrage, die example.com betrifft, alle bereits aktiven DDNS-Einträge für example.com mit in die neue Zonefile aufnehmen &amp;amp;ndash auch wenn sie auf Anfragen verschiedener Benutzer zurückgehen.&lt;br /&gt;
&lt;br /&gt;
==== Datenbank ====&lt;br /&gt;
In der Beispielimplementierung werden diese Informationen in einer SQLite-Datenbank gespeichert.&lt;br /&gt;
&lt;br /&gt;
== Sicherheit ==&lt;br /&gt;
=== Rechte ===&lt;br /&gt;
Die &#039;&#039;&#039;Benutzerrechte&#039;&#039;&#039; werden durch das Hostsharing-System kontrolliert. Sowohl das CGI-Programm als auch das [[#Administration|Administrationswerkzeug]] werden mit den Rechten des Domain-Admins (xyz00-benutzername in unserem Beispiel) ausgeführt, also kann dieses Programm nur die Domains bearbeiten, die von xyz00-benutzername verwaltet werden.&lt;br /&gt;
&lt;br /&gt;
=== Authentifizierung ===&lt;br /&gt;
In der Beispielimplementierung (wie auch seinerzeit bei DynDNS.org) wird das CGI-Programm durch einen .htaccess-Eintrag geschützt, der HTTP-Basic-Authentication vorschreibt. Also wird das Programm eigentlich mit einem URL der form&lt;br /&gt;
&lt;br /&gt;
  &amp;lt;nowiki&amp;gt;https://ddnsaccount:passwort@ddns.example.com/cgi-bin/ddns?hostname=...&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
aufgerufen.&lt;br /&gt;
&lt;br /&gt;
=== Verschlüsselung ===&lt;br /&gt;
Das CGI-Programm sollte nur in example.com/cgi-ssl/ installiert werden, nicht in example.com/cgi/. Damit ist die Kommunikation zwischen Client und Server durch SSL verschlüsselt.&lt;br /&gt;
&lt;br /&gt;
== Administration ==&lt;br /&gt;
&lt;br /&gt;
Der Verwalter des DDNS-Programms trägt berechtigte Benutzer und die ihnen zugeteilten Domainnamen in die Datenbank des Programms ein mit Hilfe eines kleinen Hilfsprogramms. Das ist im vorliegenden Fall ein menügesteuertes Programm für die Befehlszeile, daß die naheliegenden Funktionen anbietet: Account hinzufügen, löschen, sperren, entsperren, Paßwort setzen, ändern; Domainnamen hinzufügen, ändern, entsperren, löschen; Accounts und Domainnamen mit aktuellem Status auflisten. Die Funktionen sind auch über Befehlszeilenargumente verfügbar, also skriptfähig.&lt;br /&gt;
&lt;br /&gt;
Eine Auflistung des momentanen Inhalts der DDNS-Datenbank durch das Administrationswerkzeug könnte beispielsweise so aussehen:&lt;br /&gt;
&lt;br /&gt;
  xyz00-benutzername@h02:~$ bin/ddnsadmin.pl -Aa&lt;br /&gt;
  1.  papst	Mißbrauch: 0; gesperrt: nein&lt;br /&gt;
  	avignon.example.com&lt;br /&gt;
  		zuletzt aktiv am Sun Apr 26 22:24:49 2020&lt;br /&gt;
  		mit IP-Nr. 87.65.43.21; MX: 0;  Backup-MX: nein;&lt;br /&gt;
  		Subdomains: nein; Mißbrauch: 0;  gesperrt: nein&lt;br /&gt;
  	vatican.beispiel.de&lt;br /&gt;
  		zuletzt aktiv am Sun Apr 26 22:24:49 2020&lt;br /&gt;
  		mit IP-Nr. 87.65.43.21; MX: 0;  Backup-MX: nein;&lt;br /&gt;
  		Subdomains: nein; Mißbrauch: 0;  gesperrt: nein&lt;br /&gt;
  2.  kaiser	Mißbrauch: 4; gesperrt: ja&lt;br /&gt;
  	augsburg.beispiel.de&lt;br /&gt;
  		zuletzt aktiv am Fri Apr 24 16:13:49 2020&lt;br /&gt;
  		mit IP-Nr. 64.82.31.75; MX: 0;  Backup-MX: nein;&lt;br /&gt;
  		Subdomains: nein; Mißbrauch: 0;  gesperrt: ja&lt;br /&gt;
  3.  luther	Mißbrauch: 1; gesperrt: nein&lt;br /&gt;
  	wittenberg.example.com&lt;br /&gt;
  		zuletzt aktiv am Mon Apr 27 10:12:49 2020&lt;br /&gt;
  		mit IP-Nr. 78.56.34.12; MX: 0;  Backup-MX: nein;&lt;br /&gt;
  		Subdomains: nein; Mißbrauch: 1;  gesperrt: nein&lt;br /&gt;
  xyz00-benutzername@h02:~$&lt;br /&gt;
&lt;br /&gt;
Das DDNS-Account &amp;amp;bdquo;kaiser&amp;amp;ldquo; in dieser Auflistung ist wohl auf Grund fehlerhafter Anfragen automatisch gesperrt worden. Der Inhaber wird sich wohl bald melden, um nach Korrektur seiner Client-Konfiguration die Aufhebung der Sperre zu wünschen.&lt;br /&gt;
&lt;br /&gt;
=== Log ===&lt;br /&gt;
Alle Anfragen werden in einer täglich wechselnden Log-Datei protokolliert, entweder schlicht oder ausführlich, je nachdem, ob eine Variable &amp;lt;tt&amp;gt;verbose&amp;lt;/tt&amp;gt; wahr ist.&lt;br /&gt;
Ein ausführlicher Log-Eintrag sieht so aus:&lt;br /&gt;
&lt;br /&gt;
  Sun Apr 26 20:21:45 2020  ddns aufgerufen von papst&lt;br /&gt;
  			unter 84.185.97.8&lt;br /&gt;
  	URL: &amp;lt;nowiki&amp;gt;https://ddns.example.com/cgi-bin/ddns.cgi?hostname=&lt;br /&gt;
  			avignon.example.com,vatican.beispiel.de&amp;amp;&lt;br /&gt;
  			myip=84.185.97.8&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
  	Verwende IP 84.185.97.8 (= 1421435144)&lt;br /&gt;
  	DB-Version: 1&lt;br /&gt;
  	Skript und DB exklusiv geöffnet&lt;br /&gt;
  	avignon.example.com: IP: 84.185.97.8; MX: 0; Backup-MX: nein;&lt;br /&gt;
  			Wildcard: nein; Mißbrauch: 0; gesperrt: nein &lt;br /&gt;
  	vatican.beispiel.de: IP: 84.185.97.8; MX: 0; Backup-MX: nein;&lt;br /&gt;
  			Wildcard: nein; Mißbrauch: 0; gesperrt: nein &lt;br /&gt;
  	Betroffene Zonen: example.com, beispiel.de&lt;br /&gt;
  	Temporärdatei example.com_hxNa.new geschrieben&lt;br /&gt;
  	Zonendatei /home/pacs/xyz00/users/benutzername/doms/example.com/&lt;br /&gt;
  			etc/pri.example.com eingestellt&lt;br /&gt;
  	Temporärdatei beispiel.de_6HcO.new geschrieben&lt;br /&gt;
  	Zonendatei /home/pacs/xyz00/users/benutzername/doms/beispiel.de/&lt;br /&gt;
  			etc/pri.beispiel.de eingestellt&lt;br /&gt;
  	Abgeschlossen: 	Fertig&lt;br /&gt;
&lt;br /&gt;
Wenn &amp;lt;tt&amp;gt;verbose&amp;lt;/tt&amp;gt; auf falsch gesetzt ist, sind die Log-Einträge einzeilig.&lt;/div&gt;</summary>
		<author><name>Apc00-tony</name></author>
	</entry>
	<entry>
		<id>https://wiki.hostsharing.net/index.php?title=Benutzer:Apc00-tony/Dynamisches_DNS&amp;diff=5196</id>
		<title>Benutzer:Apc00-tony/Dynamisches DNS</title>
		<link rel="alternate" type="text/html" href="https://wiki.hostsharing.net/index.php?title=Benutzer:Apc00-tony/Dynamisches_DNS&amp;diff=5196"/>
		<updated>2020-04-29T08:25:00Z</updated>

		<summary type="html">&lt;p&gt;Apc00-tony: /* Antwort */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;((Provisorischer Vorspann: Auf Grund einer Mailing-Listen-Diskussion habe ich angefangen, Dynamisches DNS über einen CGI-Skript bei Hostsharing zu realisieren. Meine Lösung habe ich dann vorgestellt; sie wurde für nicht ausreichend selbsterklärend befunden und fand wenig Akzeptanz. Hier also der Versuch, die Sache zu dokumentieren.))&lt;br /&gt;
&lt;br /&gt;
Mit der regelmäßigen Aufnahme von benutzerspezifischen Zonefiles in seiner DNS-Konfiguration bietet  Hostsharing alles, was man braucht, um &amp;amp;bdquo;dynamisches DNS&amp;amp;ldquo; in Eigenregie zu realisieren.&lt;br /&gt;
&lt;br /&gt;
Das heißt, wenn ich mindestens eine Domain bei Hostsharing verwalte, und mindestens eine Einwahlverbindung (oder DSL-Verbindung) ins Internet mit wechselnder IP-Adresse über irgendeinen ISP für meinen Arbeitsplatzrechner zu Hause betreibe, dann kann ich dem Arbeitsplatzrechner über die DNS-Server von Hostsharing einen vollqualifizieren Domainnamen zuweisen, der der jeweiligen IP-Adresse meiner Einwahlleitung zugeordnet ist.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
(ASCII-Art-Diagramm der beschriebenen Konstellation)&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Im Folgenden wird eine real existierende Implementierung von Dynamischem DNS (&amp;amp;bdquo;DDNS&amp;amp;ldquo;) beschrieben. Die verschiedenen Elemente könnten durchaus anders realisiert werden; die beschriebene Implementierung könnte durchaus verbessert werden. Sie dient hier der Illustration.&lt;br /&gt;
&lt;br /&gt;
In der folgenden Beschreibung werden diese Beispielwerte benutzt:&lt;br /&gt;
* Ein Hostsharing-Mitglied hat ein Account als Paket-Admin mit Kennung xyz00.&lt;br /&gt;
* Im Paket xyz00 gibt es einen Domain-Admin namens xyz00-benutzername.&lt;br /&gt;
* Dieser Domain-Admin verwaltet bei Hostsharing die Domains example.com und beispiel.de.&lt;br /&gt;
* Ein Benutzer hat zu Hause (oder im Büro) einen Arbeitsplatzrechner hinter der marktüblichen DSL-Leitung, die von seinem ISP bereitgestellt wird.&lt;br /&gt;
* Dieser Arbeitsplatzrechner (oder der Router, der seine Internetverbindung steuert) bekommt vom ISP immer wechselnde IP-Adressen zugewiesen.&lt;br /&gt;
* Dennoch möchte der Benutzer seinen Arbeitsplatzrechner aus dem Internet unter dem Hostnamen einwahl.example.com ansprechen können.&lt;br /&gt;
&lt;br /&gt;
Dazu kann ein System wie Hostsharing, das authoritative DNS-Informationen für viele Domains bereitstellt, auch veränderliche DNS-Information über dynamisch verbundene Rechner verwalten &amp;amp;ndash; sofern das ressourcenschonend gemacht werden kann ohne andere Funktionen zu stören.&lt;br /&gt;
&lt;br /&gt;
== Aufgaben des Servers ==&lt;br /&gt;
&lt;br /&gt;
Um einem Rechner mit wechselnder IP-Adresse einen DDNS-Eintrag zu bieten, muß der Hostsharing-Server folgendes leisten (in ungefährer Reihenfolge der Ereignisse):&lt;br /&gt;
&lt;br /&gt;
# Eine Anfrage entgegennehmen, beispielsweise über HTTPS, von einem entfernten Rechner, der einen DNS-Eintrag für seine momentane IP-Adresse wünscht. &lt;br /&gt;
# Prüfen, ob die Anfrage einen berechtigten DDNS-Dienst-Usernamen mit zugehörigem Paßwort enthält.&lt;br /&gt;
# Prüfen, ob die Anfrage einen gültigen Domainnamen betrifft, den der Server bieten darf.&lt;br /&gt;
# Prüfen, ob die Domain example.com demselben Benutzer gehört, unter dessen Namen der Dynamisches-DNS-Server läuft.&lt;br /&gt;
# Eine gültige [[Zonefile]] mit &amp;amp;ndash; neben dem bisherigen Inhalt &amp;amp;ndash; einem A-Eintrag für einwahl.example.com in /home/pacs/xyz00/users/benutzername/doms/example.com/pri.example.com schreiben.&lt;br /&gt;
# Dem Client eine Bestätigung oder ggf. eine Fehlermeldung als Antwort senden.&lt;br /&gt;
# In irgendeiner Datenbank den momentan eingestellter Status all seiner DDNS-Einträge speichern.&lt;br /&gt;
# In einer Logdatei protokollieren, daß obiges getan wurde, oder ggf. welche Fehler traten auf.&lt;br /&gt;
&lt;br /&gt;
== Aufgaben des Clients ==&lt;br /&gt;
Bevor ich anfange, meinen Arbeitsplatzrechner so zu konfigurieren, daß er bei welchem Server auch immer einen DDNS-Eintrag anfordert, muß ich mich als verantwortlicher Benutzer dieses Rechners und der dazugehörigen Internetverbindung &amp;amp;ndash; das heißt, als Mensch &amp;amp;ndash; mit dem Betreiber des dynamisches-DNS-Servers vereinbaren, daß ich das darf und welchen Eintrag ich bekommen kann. Im Folgenden wird vorausgesetzt, daß solche Vereinbarungen getroffen und die Parameter geklärt wurden.&lt;br /&gt;
&lt;br /&gt;
Der DDNS-Client muß aus Server-Sicht nur wenig leisten:&lt;br /&gt;
&lt;br /&gt;
# Eine Anfrage senden, beispielsweise über HTTPS, an einen entfernten Rechner, der einen Eintrag ins DNS für die momentane IP-Adresse des Clients vornehmen kann.&amp;lt;br /&amp;gt;Diese Anfrage muß einem festgelegten Format entsprechen und muß gültige Werte für die Authorisation des Clients, den gewünschten Domainnamen, und eventuell andere Parameter enthalten.&lt;br /&gt;
# Eine Antwort des Servers entgegennehmen und als Erfolgs- oder Fehlermeldung auswerten.&lt;br /&gt;
# Von überflüssigen Anfragen absehen: das heißt bei Erfolg, nicht wiederholt den gleichen Eintrag erneut wünschen; bei Fehlern, nicht die gleiche fehlerhafte Anfrage erneut schicken.&lt;br /&gt;
&lt;br /&gt;
== Kommunikation zwischen Client und Server ==&lt;br /&gt;
&lt;br /&gt;
Ein einziges Nachrichtenpaar von Anfrage und Antwort genügt, um einen DDNS-Eintrag einzurichten: Der Client teilt die IP-Adresse und den Domainnamen mit, die in einem DNS-Eintrag verbunden werden sollen; der Server bestätigt den Auftrag.&lt;br /&gt;
&lt;br /&gt;
In der Beispielimplementierung erfolgt die Kommunikation über HTTP, und die Anfrage des Clients könnte so aussehen:&lt;br /&gt;
&lt;br /&gt;
  GET /cgi-bin/ddns?hostname=einwahl.example.com&amp;amp;myip=87.65.43.21 HTTP/1.1&lt;br /&gt;
  Host: ddns.beispiel.de&lt;br /&gt;
  User-Agent: Fritz!Box DDNS/1.0.1&lt;br /&gt;
  Authorization: Basic QWxhZGRpbjpvcGVuIHNlc2FtZQ==&lt;br /&gt;
&lt;br /&gt;
Bei Erhalt dieser Anfrage ruft Apache das CGI-Programm .../doms/ddns.beispiel.de/cgi-ssl/ddns auf. Das Fragezeichen trennt den Programmnamen von einem &amp;quot;Query-String&amp;quot;, in dem zwei Metavariablen definiert und übergeben werden. Die erste Metavariable, hostname, hat den Wert &amp;quot;einwahl.example.com&amp;quot;; die zweite, myip, hat den Wert &amp;quot;87.65.43.21&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
Das Server-Programm, hier &#039;&#039;ddns&#039;&#039;, prüft diese Informationen auf Form und Berechtigung, und schreibt gegebenenfalls einen entsprechenden Eintrag in einer Zonefile. Es schreibt auch verschiedene Informationen in die Standardausgabe. Wenn es die Standardausgabe geschlossen wird &amp;amp;ndash; also spätestens bei Programmende &amp;amp;ndash; schickt Apache diese Informationen als Antwort an den anfragenden Rechner zurück.&lt;br /&gt;
&lt;br /&gt;
Im Falle unserer Beispielimplementierung sieht die Antwort bei Erfolg so aus: &lt;br /&gt;
&lt;br /&gt;
  HTTP/1.1 200 OK&lt;br /&gt;
  Date: Wed, 22 Apr 2020 08:35:15 GMT&lt;br /&gt;
  Server: Apache&lt;br /&gt;
  Content-Length: 17&lt;br /&gt;
  Content-Type: text/plain; charset=ISO-8859-1&lt;br /&gt;
 &lt;br /&gt;
  good 87.65.43.21&lt;br /&gt;
&lt;br /&gt;
=== Das DDNS-Protokoll von DynDNS.org ===&lt;br /&gt;
&lt;br /&gt;
In den 90er Jahren, bevor das Internet so durchgehend vergeschäftlicht wurde, boten einige Organisationen kostenlose DDNS-Dienste an. Ein sehr beliebtes Angebot war das von DynDNS.org. Das DDNS-Protokoll von diesem Dienst wurde sogar in Einwahl-Routern einprogrammiert und der Dienst wurde von ISPs und Router-Herstellern als Leistungsmerkmal beworben.&lt;br /&gt;
&lt;br /&gt;
DynDNS.org gehört inzwischen Oracle und bietet keine kostenlose Dienste mehr. Dennoch wird das DDNS-Protokoll von DynDNS.org in der vorliegenden Beispielimplementierung übernommen in der Hoffnung, daß die Kompatibilität mit einigen gängigen Einwahl-Routern von Vorteil sein kann. Es gibt noch eine kurze Online-Dokumentation der [https://help.dyn.com/remote-access-api/perform-update/ Anfrage] und [https://help.dyn.com/remote-access-api/perform-update/ Antwortnachrichten].&lt;br /&gt;
&lt;br /&gt;
Das gesammte Protokoll sieht einen einzigen Nachrichtenaustausch aus Anfrage und Antwort vor. Die Anfrage kann mehrere Argumente enthalten; die Antwort kann verschiedene Code-Wörtern enthalten. Übrigens können in einer einzigen Anfrage mehrere DNS-Einträge gewünscht werden. In diesem Fall kann die Antwort mehrzeilig ausfallen.&lt;br /&gt;
&lt;br /&gt;
Das Verhalten von Server und Client bei künftigen Kommunikationsvorgängen wird unter Umständen von vorangegangenen Kommunikationsergebnissen beeinflußt: nach wiederholten fehlerhaften oder redundanten Anfragen kann der Server weitere Anfragen des Benutzers verweigern; nach wiederholten Fehlermeldungen sollte ein Client aufhören, immer dieselbe Anfrage zu schicken. Und für den Fall, daß mehrere Clients dynamische DNS-Einträge in derselben Domain example.com bestellen, muß der Server den Stand aller Client-Einträge intern speichern, damit er nicht mit einer neuen Zonefile einen früher erstellten Eintrag löscht. Zu diesen Fragen siehe den Abschnitt &#039;&#039;&#039;[[#Sukzessive_Kommunikationsabläufe]]&#039;&#039;&#039; nach der Beschreibung von Anfragen und Antworten unten.&lt;br /&gt;
&lt;br /&gt;
====Anfrage====&lt;br /&gt;
&lt;br /&gt;
Die Anfrage in Form eines URL übergibt dem DDNS-Programm in einem &#039;Query-String&#039; einige Metavariablen. Das heißt, in einem URL der Form&lt;br /&gt;
&lt;br /&gt;
  &amp;lt;nowiki&amp;gt;https://benutzername:passwort@ddns.beisiel.de/cgi-bin/ddns?hostname=einwahl.example.com&amp;amp;myip=87.65.43.21&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
signalisert das Fragezeichen, daß ein Query-String folgt. In einem solchen Query-String können in der Beispielimplementierung folgende Metavariablen definiert werden:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|- class=&amp;quot;hintergrundfarbe5&amp;quot;&lt;br /&gt;
! Variable !! Beispiel !! Bemerkungen&lt;br /&gt;
|-&lt;br /&gt;
| hostname || &amp;lt;tt&amp;gt;hostname=einwahl.example.com&amp;lt;/tt&amp;gt;&amp;lt;br /&amp;gt;&amp;lt;div style=&amp;quot;font-size:smaller;&amp;quot;&amp;gt;&amp;lt;tt&amp;gt;hostname=eins.example.com,zwei.example.com[,...]&amp;lt;/tt&amp;gt;&amp;lt;/div&amp;gt; ||&lt;br /&gt;
Muß ein vollständig qualifizierter Domain-Name (&amp;quot;FQDN&amp;quot;) sein; &amp;lt;tt&amp;gt;example.com&amp;lt;/tt&amp;gt; muß eine vom Besitzer des DDNS-Programms verwaltete Domain sein. Genaugenommen kann der Wert eine durch Kommata gegliederte Liste mehrerer gültiger Domainnamen sein, falls mehrere Einträge mit derselben IP-Adresse gewünscht werden.&lt;br /&gt;
|-&lt;br /&gt;
| myip || &amp;lt;tt&amp;gt;myip=87.65.43.21&amp;lt;/tt&amp;gt;||&lt;br /&gt;
Kann entfallen; kann vom Server ignoriert werden. Maßgeblich ist dann die IP-Adresse des Absenders, wie sie vom Web-Server mitgeteilt wird.&lt;br /&gt;
|-&lt;br /&gt;
| mx || &amp;lt;tt&amp;gt;mx=87.65.43.21&amp;lt;/tt&amp;gt;&amp;lt;br /&amp;gt;&amp;lt;tt&amp;gt;mx=NOCHG&amp;lt;/tt&amp;gt;&amp;lt;br /&amp;gt; ||&lt;br /&gt;
Neben dem A-Eintrag möchte der Client auch einen MX-Eintrag. Der Wert &amp;lt;tt&amp;gt;NOCHG&amp;lt;/tt&amp;gt; (für &amp;amp;bdquo;no change&amp;amp;ldquo;) bedeutet, der bestehende MX-Eintrag (oder seine Abwesenheit) soll nicht geändert werden. &lt;br /&gt;
|-&lt;br /&gt;
| backmx || &amp;lt;tt&amp;gt;backmx=YES&amp;lt;/tt&amp;gt;&amp;lt;br /&amp;gt;&amp;lt;tt&amp;gt;backmx=NOCHG&amp;lt;/tt&amp;gt;&amp;lt;br /&amp;gt;&amp;lt;tt&amp;gt;backmx=NO&amp;lt;/tt&amp;gt;   ||&lt;br /&gt;
Falls &amp;lt;tt&amp;gt;YES&amp;lt;/tt&amp;gt;, wird ein zweiter MX-Eintrag erzeugt, der &amp;lt;tt&amp;gt;einwahl.example.com&amp;lt;/tt&amp;gt; als Mail-Server für &amp;lt;tt&amp;gt;einwahl.example.com&amp;lt;/tt&amp;gt; nennt. Dieser Eintrag hat eine niedrigere Präferenzzahl (also eine höhere Priorität) als der mit &amp;lt;tt&amp;gt;mx&amp;lt;/tt&amp;gt; angeforderten Eintrag.&lt;br /&gt;
|-&lt;br /&gt;
| wildcard || &amp;lt;tt&amp;gt;wildcard=ON&amp;lt;/tt&amp;gt;&amp;lt;br /&amp;gt;&amp;lt;tt&amp;gt;wildcard=NOCHG&amp;lt;/tt&amp;gt;&amp;lt;br /&amp;gt;&amp;lt;tt&amp;gt;wildcard=OFF&amp;lt;/tt&amp;gt; ||&lt;br /&gt;
Neben dem A-Eintrag für den Domainnamen &amp;lt;tt&amp;gt;einwahl.example.com&amp;lt;/tt&amp;gt; wünscht der Client auch einen Eintrag für beliebige Subdomains, also &amp;lt;tt&amp;gt;*.einwahl.example.com&amp;lt;/tt&amp;gt;, mit der gleichen IP-Adresse.&lt;br /&gt;
|-&lt;br /&gt;
| offline ||&amp;lt;tt&amp;gt;offline=YES&amp;lt;/tt&amp;gt;&amp;lt;br /&amp;gt;&amp;lt;tt&amp;gt;offline=NOCHG&amp;lt;/tt&amp;gt;||&lt;br /&gt;
Falls &amp;lt;tt&amp;gt;YES&amp;lt;/tt&amp;gt;, wird ein DNS-Eintrag für &amp;lt;tt&amp;gt;einwahl.example.com&amp;lt;/tt&amp;gt; aus der Zonefile getilgt. Gegebenenfalls wird der Hostname dann auf Grund eines parallelen Wildcard-Eintrags für &amp;lt;tt&amp;gt;*.example.com&amp;lt;/tt&amp;gt; einer anderen IP-Adresse zugeordnet werden.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;!-- IPv6? --&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Alle Parameter bis auf hostname können entfallen. Bei nichtdokumentierten Argumenten ist das Verhalten undefiniert&amp;amp;trade;.&lt;br /&gt;
&lt;br /&gt;
====Antwort====&lt;br /&gt;
&lt;br /&gt;
Die Antwort auf eine erfolgreiche HTTP-Anfrage besteht im häufigsten Fall aus einigen Header-Zeilen, gefolgt vom Inhalt der gewünschten Text- oder andere Datei. Ein Status-Code in der ersten Header-Zeile gibt an, ob die Anfrage bedient werden kann oder kreist andernfalls den Grund für die Enttäuschung ein.&lt;br /&gt;
&lt;br /&gt;
Die vorliegende Beispielimplementierung von DDNS schickt einen der üblichen HTTP-Status-Codes &amp;quot;200 OK&amp;quot; oder &amp;quot;500 Internal Server Error&amp;quot;, gefolgt von einer kurzen Textnachricht nach dem HTTP-Header. Bei diesem Programm  ist &amp;amp;ndash; laut Gebrauchshinweise von DynDNS.org &amp;amp;ndash; &#039;&#039;nicht&#039;&#039; der Status-Code im Header, sondern der Inhalt der Nachricht  die definierte, maßgebliche Ergebnismeldung des Programms.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|- class=&amp;quot;hintergrundfarbe5&amp;quot;&lt;br /&gt;
! Meldung !! Bedeutung !! Bemerkungen&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;good&amp;amp;nbsp;&amp;amp;lt;IP&amp;amp;nbsp;number&amp;amp;gt;&amp;lt;/tt&amp;gt; ||&lt;br /&gt;
Der gewünschte DNS-Eintrag wurde erfolgreich in einer Zonefile eingetragen. &lt;br /&gt;
|| Es kann natürlich noch einige Minuten dauern, bis die Zonefile vom Hostsharing-Roboter abgelesen wird und der Inhalt in die BIND-Konfiguration übernommen.&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;good&amp;amp;nbsp;0.0.0.0&amp;lt;/tt&amp;gt; ||&lt;br /&gt;
Das Argument &amp;lt;tt&amp;gt;offline=YES&amp;lt;/tt&amp;gt; wurde empfangen und verarbeitet.&lt;br /&gt;
|| Der Domainnamen hat also keinen dynamischen DNS-Eintrag mehr.&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;good&amp;amp;nbsp;127.0.0.1&amp;lt;/tt&amp;gt; ||&lt;br /&gt;
Die Anfrage entsprach nicht den Erfordernissen des Servers.&lt;br /&gt;
|| Trotz des Worts &amp;lt;tt&amp;gt;good&amp;lt;/tt&amp;gt; war die Anfrage nicht erfolgreich, falls in der Rückmeldung die IP-Adresse mit &amp;lt;tt&amp;gt;127.0.0.1&amp;lt;/tt&amp;gt; angegeben wird. Dieser verwirrende Fehlercode ist aus unerklärlichen Gründen in der Spezifikation von DynDNS.org so definiert.&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;nochg&amp;amp;nbsp;&amp;amp;lt;IP&amp;amp;nbsp;number&amp;amp;gt;&amp;lt;/tt&amp;gt; ||&lt;br /&gt;
Der gewünschte DNS-Eintrag war bereits vorhanden. &lt;br /&gt;
|| Der Server selbst macht keine DNS-Abfrage, um das zu vermitteln: die &amp;amp;bdquo;no change&amp;amp;ldquo;-Antwort besagt nur, daß eine Anfrage für diesen Eintrag bereits mit Erfolg quittiert wurde.&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;notfqdn&amp;lt;/tt&amp;gt; ||&lt;br /&gt;
Fehlschlag: der gewünschte Domainname ist nicht gültig, oder es wurde keiner angegeben.&lt;br /&gt;
|| ...&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;nohost&amp;lt;/tt&amp;gt; ||&lt;br /&gt;
Fehlschlag: der gewünschte Domainname ist gehört nicht zu denen, die für diesen Benutzer des DDNS-Dienstes konfiguriert sind.&lt;br /&gt;
|| Siehe den Abschnitt [[#Administration|Administration]] weiter unten.&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;badauth&amp;lt;/tt&amp;gt; ||&lt;br /&gt;
Fehlschlag: Die Kombination von Benutzernamen und Paßwort entsprach keinem DDNS-Account, oder das Account ist momentan gesperrt.&lt;br /&gt;
|| Ein gesperrtes Account kann nur der Domain-Admin mittels des Administrationswerkzeugs wieder freigeben: siehe den Abschnit [[#Administration|Administration]] weiter unten.&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;abuse&amp;lt;/tt&amp;gt; ||&lt;br /&gt;
Fehlschlag: der gewünschte Domainname ist wegen vorangeganger Fehlschläge oder überflüssiger Aufrufe gesperrt.&lt;br /&gt;
|| Siehe den Abschnitt &#039;&#039;&#039;Sukzessive Kommunikationsvorgänge&#039;&#039;&#039; unten.&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;911&amp;lt;/tt&amp;gt; ||&lt;br /&gt;
Fehlschlag: Das Server-Programm hat einen internen Fehler festgestellt.&lt;br /&gt;
|| Das Problem liegt nicht in der Anfrage an sich.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Man kann sich durchaus eine sinnreichere Kommunikation zwischen Client und Server vorstellen, doch das hier beschriebene Protokoll ist eben von DynDNS.org verwendet worden und wird in gängigen Routern implementiert, also wird es in der vorliegenden DDNS-Implementierung nachgebildet.&lt;br /&gt;
&lt;br /&gt;
=== Sukzessive Kommunikationsabläufe ===&lt;br /&gt;
Der Server muß sich zwischen einzelnen Aufrufen einiges merken, um Ressourcen zu schonen und um zu verhindern, daß einmal vergebene DDNS-Einträge von neuen Anfragen, die dieselbe übergeordnete Domain betreffen, durch Überschreiben  verlorengehen.&lt;br /&gt;
&lt;br /&gt;
==== Mißbrauch und Benutzersperrung ====&lt;br /&gt;
Zur Schonung von Ressourcen muß sich die Implementierung weigern, sich mit zuvielen fehlerhaften oder auch nur überflüssigen Anfragen zu beschäftigen. Dazu führt eine Strichliste über solche Anfragen jedes Clients und sperrt nach einer bestimmten Anzahl solcher Anfragen den Benutzernamen oder einzelne Domainnamen gegen die weitere Nutzung des Dienstes.&lt;br /&gt;
&lt;br /&gt;
Mißbrauchspunkte gegen einen einzelnen Domainnamen gibt es für:&lt;br /&gt;
* eine Anfrage, die keinen neuen DNS-Eintrag (und keine Änderung oder Löschung eines Eintrags) erfordert, sondern bestehende Merkmale nur wiederholt&lt;br /&gt;
&lt;br /&gt;
Mißbrauchspunkte gegen einen Benutzernamen gibt es für:&lt;br /&gt;
* die Angabe eines Domainnamens, der in der Dienstkonfiguration dem anfragenden Benutzernamen nicht zugeordnet ist&lt;br /&gt;
* die Angabe eines Domainnamen in einer Domain, die nicht demselben Hostsharing-Domain-Admin gehört, der den DDNS-Dienst anbietet&lt;br /&gt;
* die Angabe eines Domainnamens, der in der Dienstkonfiguration bereits wegen mißbräuchlicher Anfragen gesperrt ist (siehe oben)&lt;br /&gt;
&lt;br /&gt;
Um eine Sperrung aufzuheben, wird in der Regel eine Handlung durch den Administrator erforderlich sein.&lt;br /&gt;
&lt;br /&gt;
==== Mehrere dynamische Subdomains in derselben Domain ====&lt;br /&gt;
Sobald zwei verschiedene DDNS-Einträge in derselben Domain verlangt werden &amp;amp;ndash; beispielsweise home.example.com und office.example.com &amp;amp;ndash; wird es notwendig, bei jeder neuen Zonefile für example.com eventuell frühere Einträge zu konservieren. Der Rechner zu Hause weiß beim Bestellen seines DDNS-Eintrags nichts vom Rechner im Büro und umgekehrt. Der Server muß in irgendeiner Form über bereits vergebene Einträge Buch führen und bei einer neuen Anfrage, die example.com betrifft, alle bereits aktiven DDNS-Einträge für example.com mit in die neue Zonefile aufnehmen &amp;amp;ndash auch wenn sie auf Anfragen verschiedener Benutzer zurückgehen.&lt;br /&gt;
&lt;br /&gt;
==== Datenbank ====&lt;br /&gt;
In der Beispielimplementierung werden diese Informationen in einer SQLite-Datenbank gespeichert.&lt;br /&gt;
&lt;br /&gt;
== Sicherheit ==&lt;br /&gt;
=== Rechte ===&lt;br /&gt;
Die &#039;&#039;&#039;Benutzerrechte&#039;&#039;&#039; werden durch das Hostsharing-System kontrolliert. Sowohl das CGI-Programm als auch das [[#Administration|Administrationswerkzeug]] werden mit den Rechten des Domain-Admins (xyz00-benutzername in unserem Beispiel) ausgeführt, also kann dieses Programm nur die Domains bearbeiten, die von xyz00-benutzername verwaltet werden.&lt;br /&gt;
&lt;br /&gt;
=== Authentifizierung ===&lt;br /&gt;
In der Beispielimplementierung (wie auch seinerzeit bei DynDNS.org) wird das CGI-Programm durch einen .htaccess-Eintrag geschützt, der HTTP-Basic-Authentication vorschreibt. Also wird das Programm eigentlich mit einem URL der form&lt;br /&gt;
&lt;br /&gt;
  &amp;lt;nowiki&amp;gt;https://ddnsaccount:passwort@ddns.example.com/cgi-bin/ddns?hostname=...&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
aufgerufen.&lt;br /&gt;
&lt;br /&gt;
=== Verschlüsselung ===&lt;br /&gt;
Das CGI-Programm sollte nur in example.com/cgi-ssl/ installiert werden, nicht in example.com/cgi/. Damit ist die Kommunikation zwischen Client und Server durch SSL verschlüsselt.&lt;br /&gt;
&lt;br /&gt;
== Administration ==&lt;br /&gt;
&lt;br /&gt;
Der Verwalter des DDNS-Programms trägt berechtigte Benutzer und die ihnen zugeteilten Domainnamen in die Datenbank des Programms ein mit Hilfe eines kleinen Hilfsprogramms. Das ist im vorliegenden Fall ein menügesteuertes Programm für die Befehlszeile, daß die naheliegenden Funktionen anbietet: Account hinzufügen, löschen, sperren, entsperren, Paßwort setzen, ändern; Domainnamen hinzufügen, ändern, entsperren, löschen; Accounts und Domainnamen mit aktuellem Status auflisten. Die Funktionen sind auch über Befehlszeilenargumente verfügbar, also skriptfähig.&lt;br /&gt;
&lt;br /&gt;
Eine Auflistung des momentanen Inhalts der DDNS-Datenbank durch das Administrationswerkzeug könnte beispielsweise so aussehen:&lt;br /&gt;
&lt;br /&gt;
  xyz00-benutzername@h02:~$ bin/ddnsadmin.pl -Aa&lt;br /&gt;
  1.  papst	Mißbrauch: 0; gesperrt: nein&lt;br /&gt;
  	avignon.example.com&lt;br /&gt;
  		zuletzt aktiv am Sun Apr 26 22:24:49 2020&lt;br /&gt;
  		mit IP-Nr. 87.65.43.21; MX: 0;  Backup-MX: nein;&lt;br /&gt;
  		Subdomains: nein; Mißbrauch: 0;  gesperrt: nein&lt;br /&gt;
  	vatican.beispiel.de&lt;br /&gt;
  		zuletzt aktiv am Sun Apr 26 22:24:49 2020&lt;br /&gt;
  		mit IP-Nr. 87.65.43.21; MX: 0;  Backup-MX: nein;&lt;br /&gt;
  		Subdomains: nein; Mißbrauch: 0;  gesperrt: nein&lt;br /&gt;
  2.  kaiser	Mißbrauch: 4; gesperrt: ja&lt;br /&gt;
  	augsburg.beispiel.de&lt;br /&gt;
  		zuletzt aktiv am Fri Apr 24 16:13:49 2020&lt;br /&gt;
  		mit IP-Nr. 64.82.31.75; MX: 0;  Backup-MX: nein;&lt;br /&gt;
  		Subdomains: nein; Mißbrauch: 0;  gesperrt: ja&lt;br /&gt;
  3.  luther	Mißbrauch: 1; gesperrt: nein&lt;br /&gt;
  	wittenberg.example.com&lt;br /&gt;
  		zuletzt aktiv am Mon Apr 27 10:12:49 2020&lt;br /&gt;
  		mit IP-Nr. 78.56.34.12; MX: 0;  Backup-MX: nein;&lt;br /&gt;
  		Subdomains: nein; Mißbrauch: 1;  gesperrt: nein&lt;br /&gt;
  xyz00-benutzername@h02:~$&lt;br /&gt;
&lt;br /&gt;
Das DDNS-Account &amp;amp;bdquo;kaiser&amp;amp;ldquo; in dieser Auflistung ist wohl auf Grund fehlerhafter Anfragen automatisch gesperrt worden. Der Inhaber wird sich wohl bald melden, um nach Korrektur seiner Client-Konfiguration die Aufhebung der Sperre zu wünschen.&lt;br /&gt;
&lt;br /&gt;
=== Log ===&lt;br /&gt;
Alle Anfragen werden in einer täglich wechselnden Log-Datei protokolliert, entweder schlicht oder ausführlich, je nachdem, ob eine Variable &amp;lt;tt&amp;gt;verbose&amp;lt;/tt&amp;gt; wahr ist.&lt;br /&gt;
Ein ausführlicher Log-Eintrag sieht so aus:&lt;br /&gt;
&lt;br /&gt;
  Sun Apr 26 20:21:45 2020  ddns aufgerufen von papst&lt;br /&gt;
  			unter 84.185.97.8&lt;br /&gt;
  	URL: &amp;lt;nowiki&amp;gt;https://ddns.example.com/cgi-bin/ddns.cgi?hostname=&lt;br /&gt;
  			avignon.example.com,vatican.beispiel.de&amp;amp;&lt;br /&gt;
  			myip=84.185.97.8&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
  	Verwende IP 84.185.97.8 (= 1421435144)&lt;br /&gt;
  	DB-Version: 1&lt;br /&gt;
  	Skript und DB exklusiv geöffnet&lt;br /&gt;
  	avignon.example.com: IP: 84.185.97.8; MX: 0; Backup-MX: nein;&lt;br /&gt;
  			Wildcard: nein; Mißbrauch: 0; gesperrt: nein &lt;br /&gt;
  	vatican.beispiel.de: IP: 84.185.97.8; MX: 0; Backup-MX: nein;&lt;br /&gt;
  			Wildcard: nein; Mißbrauch: 0; gesperrt: nein &lt;br /&gt;
  	Betroffene Zonen: example.com, beispiel.de&lt;br /&gt;
  	Temporärdatei example.com_hxNa.new geschrieben&lt;br /&gt;
  	Zonendatei /home/pacs/xyz00/users/benutzername/doms/example.com/&lt;br /&gt;
  			etc/pri.example.com eingestellt&lt;br /&gt;
  	Temporärdatei beispiel.de_6HcO.new geschrieben&lt;br /&gt;
  	Zonendatei /home/pacs/xyz00/users/benutzername/doms/beispiel.de/&lt;br /&gt;
  			etc/pri.beispiel.de eingestellt&lt;br /&gt;
  	Abgeschlossen: 	Fertig&lt;br /&gt;
&lt;br /&gt;
Wenn &amp;lt;tt&amp;gt;verbose&amp;lt;/tt&amp;gt; auf falsch gesetzt ist, sind die Log-Einträge einzeilig.&lt;/div&gt;</summary>
		<author><name>Apc00-tony</name></author>
	</entry>
	<entry>
		<id>https://wiki.hostsharing.net/index.php?title=Benutzer:Apc00-tony/Dynamisches_DNS&amp;diff=5195</id>
		<title>Benutzer:Apc00-tony/Dynamisches DNS</title>
		<link rel="alternate" type="text/html" href="https://wiki.hostsharing.net/index.php?title=Benutzer:Apc00-tony/Dynamisches_DNS&amp;diff=5195"/>
		<updated>2020-04-29T08:19:45Z</updated>

		<summary type="html">&lt;p&gt;Apc00-tony: /* Antwort */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;((Provisorischer Vorspann: Auf Grund einer Mailing-Listen-Diskussion habe ich angefangen, Dynamisches DNS über einen CGI-Skript bei Hostsharing zu realisieren. Meine Lösung habe ich dann vorgestellt; sie wurde für nicht ausreichend selbsterklärend befunden und fand wenig Akzeptanz. Hier also der Versuch, die Sache zu dokumentieren.))&lt;br /&gt;
&lt;br /&gt;
Mit der regelmäßigen Aufnahme von benutzerspezifischen Zonefiles in seiner DNS-Konfiguration bietet  Hostsharing alles, was man braucht, um &amp;amp;bdquo;dynamisches DNS&amp;amp;ldquo; in Eigenregie zu realisieren.&lt;br /&gt;
&lt;br /&gt;
Das heißt, wenn ich mindestens eine Domain bei Hostsharing verwalte, und mindestens eine Einwahlverbindung (oder DSL-Verbindung) ins Internet mit wechselnder IP-Adresse über irgendeinen ISP für meinen Arbeitsplatzrechner zu Hause betreibe, dann kann ich dem Arbeitsplatzrechner über die DNS-Server von Hostsharing einen vollqualifizieren Domainnamen zuweisen, der der jeweiligen IP-Adresse meiner Einwahlleitung zugeordnet ist.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
(ASCII-Art-Diagramm der beschriebenen Konstellation)&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Im Folgenden wird eine real existierende Implementierung von Dynamischem DNS (&amp;amp;bdquo;DDNS&amp;amp;ldquo;) beschrieben. Die verschiedenen Elemente könnten durchaus anders realisiert werden; die beschriebene Implementierung könnte durchaus verbessert werden. Sie dient hier der Illustration.&lt;br /&gt;
&lt;br /&gt;
In der folgenden Beschreibung werden diese Beispielwerte benutzt:&lt;br /&gt;
* Ein Hostsharing-Mitglied hat ein Account als Paket-Admin mit Kennung xyz00.&lt;br /&gt;
* Im Paket xyz00 gibt es einen Domain-Admin namens xyz00-benutzername.&lt;br /&gt;
* Dieser Domain-Admin verwaltet bei Hostsharing die Domains example.com und beispiel.de.&lt;br /&gt;
* Ein Benutzer hat zu Hause (oder im Büro) einen Arbeitsplatzrechner hinter der marktüblichen DSL-Leitung, die von seinem ISP bereitgestellt wird.&lt;br /&gt;
* Dieser Arbeitsplatzrechner (oder der Router, der seine Internetverbindung steuert) bekommt vom ISP immer wechselnde IP-Adressen zugewiesen.&lt;br /&gt;
* Dennoch möchte der Benutzer seinen Arbeitsplatzrechner aus dem Internet unter dem Hostnamen einwahl.example.com ansprechen können.&lt;br /&gt;
&lt;br /&gt;
Dazu kann ein System wie Hostsharing, das authoritative DNS-Informationen für viele Domains bereitstellt, auch veränderliche DNS-Information über dynamisch verbundene Rechner verwalten &amp;amp;ndash; sofern das ressourcenschonend gemacht werden kann ohne andere Funktionen zu stören.&lt;br /&gt;
&lt;br /&gt;
== Aufgaben des Servers ==&lt;br /&gt;
&lt;br /&gt;
Um einem Rechner mit wechselnder IP-Adresse einen DDNS-Eintrag zu bieten, muß der Hostsharing-Server folgendes leisten (in ungefährer Reihenfolge der Ereignisse):&lt;br /&gt;
&lt;br /&gt;
# Eine Anfrage entgegennehmen, beispielsweise über HTTPS, von einem entfernten Rechner, der einen DNS-Eintrag für seine momentane IP-Adresse wünscht. &lt;br /&gt;
# Prüfen, ob die Anfrage einen berechtigten DDNS-Dienst-Usernamen mit zugehörigem Paßwort enthält.&lt;br /&gt;
# Prüfen, ob die Anfrage einen gültigen Domainnamen betrifft, den der Server bieten darf.&lt;br /&gt;
# Prüfen, ob die Domain example.com demselben Benutzer gehört, unter dessen Namen der Dynamisches-DNS-Server läuft.&lt;br /&gt;
# Eine gültige [[Zonefile]] mit &amp;amp;ndash; neben dem bisherigen Inhalt &amp;amp;ndash; einem A-Eintrag für einwahl.example.com in /home/pacs/xyz00/users/benutzername/doms/example.com/pri.example.com schreiben.&lt;br /&gt;
# Dem Client eine Bestätigung oder ggf. eine Fehlermeldung als Antwort senden.&lt;br /&gt;
# In irgendeiner Datenbank den momentan eingestellter Status all seiner DDNS-Einträge speichern.&lt;br /&gt;
# In einer Logdatei protokollieren, daß obiges getan wurde, oder ggf. welche Fehler traten auf.&lt;br /&gt;
&lt;br /&gt;
== Aufgaben des Clients ==&lt;br /&gt;
Bevor ich anfange, meinen Arbeitsplatzrechner so zu konfigurieren, daß er bei welchem Server auch immer einen DDNS-Eintrag anfordert, muß ich mich als verantwortlicher Benutzer dieses Rechners und der dazugehörigen Internetverbindung &amp;amp;ndash; das heißt, als Mensch &amp;amp;ndash; mit dem Betreiber des dynamisches-DNS-Servers vereinbaren, daß ich das darf und welchen Eintrag ich bekommen kann. Im Folgenden wird vorausgesetzt, daß solche Vereinbarungen getroffen und die Parameter geklärt wurden.&lt;br /&gt;
&lt;br /&gt;
Der DDNS-Client muß aus Server-Sicht nur wenig leisten:&lt;br /&gt;
&lt;br /&gt;
# Eine Anfrage senden, beispielsweise über HTTPS, an einen entfernten Rechner, der einen Eintrag ins DNS für die momentane IP-Adresse des Clients vornehmen kann.&amp;lt;br /&amp;gt;Diese Anfrage muß einem festgelegten Format entsprechen und muß gültige Werte für die Authorisation des Clients, den gewünschten Domainnamen, und eventuell andere Parameter enthalten.&lt;br /&gt;
# Eine Antwort des Servers entgegennehmen und als Erfolgs- oder Fehlermeldung auswerten.&lt;br /&gt;
# Von überflüssigen Anfragen absehen: das heißt bei Erfolg, nicht wiederholt den gleichen Eintrag erneut wünschen; bei Fehlern, nicht die gleiche fehlerhafte Anfrage erneut schicken.&lt;br /&gt;
&lt;br /&gt;
== Kommunikation zwischen Client und Server ==&lt;br /&gt;
&lt;br /&gt;
Ein einziges Nachrichtenpaar von Anfrage und Antwort genügt, um einen DDNS-Eintrag einzurichten: Der Client teilt die IP-Adresse und den Domainnamen mit, die in einem DNS-Eintrag verbunden werden sollen; der Server bestätigt den Auftrag.&lt;br /&gt;
&lt;br /&gt;
In der Beispielimplementierung erfolgt die Kommunikation über HTTP, und die Anfrage des Clients könnte so aussehen:&lt;br /&gt;
&lt;br /&gt;
  GET /cgi-bin/ddns?hostname=einwahl.example.com&amp;amp;myip=87.65.43.21 HTTP/1.1&lt;br /&gt;
  Host: ddns.beispiel.de&lt;br /&gt;
  User-Agent: Fritz!Box DDNS/1.0.1&lt;br /&gt;
  Authorization: Basic QWxhZGRpbjpvcGVuIHNlc2FtZQ==&lt;br /&gt;
&lt;br /&gt;
Bei Erhalt dieser Anfrage ruft Apache das CGI-Programm .../doms/ddns.beispiel.de/cgi-ssl/ddns auf. Das Fragezeichen trennt den Programmnamen von einem &amp;quot;Query-String&amp;quot;, in dem zwei Metavariablen definiert und übergeben werden. Die erste Metavariable, hostname, hat den Wert &amp;quot;einwahl.example.com&amp;quot;; die zweite, myip, hat den Wert &amp;quot;87.65.43.21&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
Das Server-Programm, hier &#039;&#039;ddns&#039;&#039;, prüft diese Informationen auf Form und Berechtigung, und schreibt gegebenenfalls einen entsprechenden Eintrag in einer Zonefile. Es schreibt auch verschiedene Informationen in die Standardausgabe. Wenn es die Standardausgabe geschlossen wird &amp;amp;ndash; also spätestens bei Programmende &amp;amp;ndash; schickt Apache diese Informationen als Antwort an den anfragenden Rechner zurück.&lt;br /&gt;
&lt;br /&gt;
Im Falle unserer Beispielimplementierung sieht die Antwort bei Erfolg so aus: &lt;br /&gt;
&lt;br /&gt;
  HTTP/1.1 200 OK&lt;br /&gt;
  Date: Wed, 22 Apr 2020 08:35:15 GMT&lt;br /&gt;
  Server: Apache&lt;br /&gt;
  Content-Length: 17&lt;br /&gt;
  Content-Type: text/plain; charset=ISO-8859-1&lt;br /&gt;
 &lt;br /&gt;
  good 87.65.43.21&lt;br /&gt;
&lt;br /&gt;
=== Das DDNS-Protokoll von DynDNS.org ===&lt;br /&gt;
&lt;br /&gt;
In den 90er Jahren, bevor das Internet so durchgehend vergeschäftlicht wurde, boten einige Organisationen kostenlose DDNS-Dienste an. Ein sehr beliebtes Angebot war das von DynDNS.org. Das DDNS-Protokoll von diesem Dienst wurde sogar in Einwahl-Routern einprogrammiert und der Dienst wurde von ISPs und Router-Herstellern als Leistungsmerkmal beworben.&lt;br /&gt;
&lt;br /&gt;
DynDNS.org gehört inzwischen Oracle und bietet keine kostenlose Dienste mehr. Dennoch wird das DDNS-Protokoll von DynDNS.org in der vorliegenden Beispielimplementierung übernommen in der Hoffnung, daß die Kompatibilität mit einigen gängigen Einwahl-Routern von Vorteil sein kann. Es gibt noch eine kurze Online-Dokumentation der [https://help.dyn.com/remote-access-api/perform-update/ Anfrage] und [https://help.dyn.com/remote-access-api/perform-update/ Antwortnachrichten].&lt;br /&gt;
&lt;br /&gt;
Das gesammte Protokoll sieht einen einzigen Nachrichtenaustausch aus Anfrage und Antwort vor. Die Anfrage kann mehrere Argumente enthalten; die Antwort kann verschiedene Code-Wörtern enthalten. Übrigens können in einer einzigen Anfrage mehrere DNS-Einträge gewünscht werden. In diesem Fall kann die Antwort mehrzeilig ausfallen.&lt;br /&gt;
&lt;br /&gt;
Das Verhalten von Server und Client bei künftigen Kommunikationsvorgängen wird unter Umständen von vorangegangenen Kommunikationsergebnissen beeinflußt: nach wiederholten fehlerhaften oder redundanten Anfragen kann der Server weitere Anfragen des Benutzers verweigern; nach wiederholten Fehlermeldungen sollte ein Client aufhören, immer dieselbe Anfrage zu schicken. Und für den Fall, daß mehrere Clients dynamische DNS-Einträge in derselben Domain example.com bestellen, muß der Server den Stand aller Client-Einträge intern speichern, damit er nicht mit einer neuen Zonefile einen früher erstellten Eintrag löscht. Zu diesen Fragen siehe den Abschnitt &#039;&#039;&#039;[[#Sukzessive_Kommunikationsabläufe]]&#039;&#039;&#039; nach der Beschreibung von Anfragen und Antworten unten.&lt;br /&gt;
&lt;br /&gt;
====Anfrage====&lt;br /&gt;
&lt;br /&gt;
Die Anfrage in Form eines URL übergibt dem DDNS-Programm in einem &#039;Query-String&#039; einige Metavariablen. Das heißt, in einem URL der Form&lt;br /&gt;
&lt;br /&gt;
  &amp;lt;nowiki&amp;gt;https://benutzername:passwort@ddns.beisiel.de/cgi-bin/ddns?hostname=einwahl.example.com&amp;amp;myip=87.65.43.21&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
signalisert das Fragezeichen, daß ein Query-String folgt. In einem solchen Query-String können in der Beispielimplementierung folgende Metavariablen definiert werden:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|- class=&amp;quot;hintergrundfarbe5&amp;quot;&lt;br /&gt;
! Variable !! Beispiel !! Bemerkungen&lt;br /&gt;
|-&lt;br /&gt;
| hostname || &amp;lt;tt&amp;gt;hostname=einwahl.example.com&amp;lt;/tt&amp;gt;&amp;lt;br /&amp;gt;&amp;lt;div style=&amp;quot;font-size:smaller;&amp;quot;&amp;gt;&amp;lt;tt&amp;gt;hostname=eins.example.com,zwei.example.com[,...]&amp;lt;/tt&amp;gt;&amp;lt;/div&amp;gt; ||&lt;br /&gt;
Muß ein vollständig qualifizierter Domain-Name (&amp;quot;FQDN&amp;quot;) sein; &amp;lt;tt&amp;gt;example.com&amp;lt;/tt&amp;gt; muß eine vom Besitzer des DDNS-Programms verwaltete Domain sein. Genaugenommen kann der Wert eine durch Kommata gegliederte Liste mehrerer gültiger Domainnamen sein, falls mehrere Einträge mit derselben IP-Adresse gewünscht werden.&lt;br /&gt;
|-&lt;br /&gt;
| myip || &amp;lt;tt&amp;gt;myip=87.65.43.21&amp;lt;/tt&amp;gt;||&lt;br /&gt;
Kann entfallen; kann vom Server ignoriert werden. Maßgeblich ist dann die IP-Adresse des Absenders, wie sie vom Web-Server mitgeteilt wird.&lt;br /&gt;
|-&lt;br /&gt;
| mx || &amp;lt;tt&amp;gt;mx=87.65.43.21&amp;lt;/tt&amp;gt;&amp;lt;br /&amp;gt;&amp;lt;tt&amp;gt;mx=NOCHG&amp;lt;/tt&amp;gt;&amp;lt;br /&amp;gt; ||&lt;br /&gt;
Neben dem A-Eintrag möchte der Client auch einen MX-Eintrag. Der Wert &amp;lt;tt&amp;gt;NOCHG&amp;lt;/tt&amp;gt; (für &amp;amp;bdquo;no change&amp;amp;ldquo;) bedeutet, der bestehende MX-Eintrag (oder seine Abwesenheit) soll nicht geändert werden. &lt;br /&gt;
|-&lt;br /&gt;
| backmx || &amp;lt;tt&amp;gt;backmx=YES&amp;lt;/tt&amp;gt;&amp;lt;br /&amp;gt;&amp;lt;tt&amp;gt;backmx=NOCHG&amp;lt;/tt&amp;gt;&amp;lt;br /&amp;gt;&amp;lt;tt&amp;gt;backmx=NO&amp;lt;/tt&amp;gt;   ||&lt;br /&gt;
Falls &amp;lt;tt&amp;gt;YES&amp;lt;/tt&amp;gt;, wird ein zweiter MX-Eintrag erzeugt, der &amp;lt;tt&amp;gt;einwahl.example.com&amp;lt;/tt&amp;gt; als Mail-Server für &amp;lt;tt&amp;gt;einwahl.example.com&amp;lt;/tt&amp;gt; nennt. Dieser Eintrag hat eine niedrigere Präferenzzahl (also eine höhere Priorität) als der mit &amp;lt;tt&amp;gt;mx&amp;lt;/tt&amp;gt; angeforderten Eintrag.&lt;br /&gt;
|-&lt;br /&gt;
| wildcard || &amp;lt;tt&amp;gt;wildcard=ON&amp;lt;/tt&amp;gt;&amp;lt;br /&amp;gt;&amp;lt;tt&amp;gt;wildcard=NOCHG&amp;lt;/tt&amp;gt;&amp;lt;br /&amp;gt;&amp;lt;tt&amp;gt;wildcard=OFF&amp;lt;/tt&amp;gt; ||&lt;br /&gt;
Neben dem A-Eintrag für den Domainnamen &amp;lt;tt&amp;gt;einwahl.example.com&amp;lt;/tt&amp;gt; wünscht der Client auch einen Eintrag für beliebige Subdomains, also &amp;lt;tt&amp;gt;*.einwahl.example.com&amp;lt;/tt&amp;gt;, mit der gleichen IP-Adresse.&lt;br /&gt;
|-&lt;br /&gt;
| offline ||&amp;lt;tt&amp;gt;offline=YES&amp;lt;/tt&amp;gt;&amp;lt;br /&amp;gt;&amp;lt;tt&amp;gt;offline=NOCHG&amp;lt;/tt&amp;gt;||&lt;br /&gt;
Falls &amp;lt;tt&amp;gt;YES&amp;lt;/tt&amp;gt;, wird ein DNS-Eintrag für &amp;lt;tt&amp;gt;einwahl.example.com&amp;lt;/tt&amp;gt; aus der Zonefile getilgt. Gegebenenfalls wird der Hostname dann auf Grund eines parallelen Wildcard-Eintrags für &amp;lt;tt&amp;gt;*.example.com&amp;lt;/tt&amp;gt; einer anderen IP-Adresse zugeordnet werden.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;!-- IPv6? --&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Alle Parameter bis auf hostname können entfallen. Bei nichtdokumentierten Argumenten ist das Verhalten undefiniert&amp;amp;trade;.&lt;br /&gt;
&lt;br /&gt;
====Antwort====&lt;br /&gt;
&lt;br /&gt;
Die Antwort auf eine erfolgreiche HTTP-Anfrage besteht im häufigsten Fall aus einigen Header-Zeilen, gefolgt vom Inhalt der gewünschten Text- oder andere Datei. Ein Status-Code in der ersten Header-Zeile gibt an, ob die Anfrage bedient werden kann oder kreist andernfalls den Grund für die Enttäuschung ein.&lt;br /&gt;
&lt;br /&gt;
Die vorliegende Beispielimplementierung von DDNS schickt einen der üblichen HTTP-Status-Codes &amp;quot;200 OK&amp;quot; oder &amp;quot;500 Internal Server Error&amp;quot;, gefolgt von einer kurzen Textnachricht nach dem HTTP-Header. Bei diesem Programm  ist &amp;amp;ndash; laut Gebrauchshinweise von DynDNS.org &amp;amp;ndash; &#039;&#039;nicht&#039;&#039; der Status-Code im Header, sondern der Inhalt der Nachricht  die definierte, maßgebliche Ergebnismeldung des Programms.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|- class=&amp;quot;hintergrundfarbe5&amp;quot;&lt;br /&gt;
! Meldung !! Bedeutung !! Bemerkungen&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;good&amp;amp;nbsp;&amp;amp;lt;IP&amp;amp;nbsp;number&amp;amp;gt;&amp;lt;/tt&amp;gt; ||&lt;br /&gt;
Der gewünschte DNS-Eintrag wurde erfolgreich in einer Zonefile eingetragen. &lt;br /&gt;
|| Es kann natürlich noch einige Minuten dauern, bis die Zonefile vom Hostsharing-Roboter abgelesen wird und der Inhalt in die BIND-Konfiguration übernommen.&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;good&amp;amp;nbsp;0.0.0.0&amp;lt;/tt&amp;gt; ||&lt;br /&gt;
Das Argument &amp;lt;tt&amp;gt;offline=YES&amp;lt;/tt&amp;gt; wurde empfangen und verarbeitet.&lt;br /&gt;
|| Der Domainnamen hat also keinen dynamischen DNS-Eintrag mehr.&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;good&amp;amp;nbsp;127.0.0.1&amp;lt;/tt&amp;gt; ||&lt;br /&gt;
Die Anfrage entsprach nicht den Erfordernissen des Servers.&lt;br /&gt;
|| Trotz des Worts &amp;lt;tt&amp;gt;good&amp;lt;/tt&amp;gt; war die Anfrage nicht erfolgreich, falls in der Rückmeldung die IP-Adresse mit &amp;lt;tt&amp;gt;127.0.0.1&amp;lt;/tt&amp;gt; angegeben wird. Dieser verwirrende Fehlercode ist aus unerklärlichen Gründen in der Spezifikation von DynDNS.org so definiert.&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;nochg&amp;amp;nbsp;&amp;amp;lt;IP&amp;amp;nbsp;number&amp;amp;gt;&amp;lt;/tt&amp;gt; ||&lt;br /&gt;
Der gewünschte DNS-Eintrag war bereits vorhanden. &lt;br /&gt;
|| Der Server selbst macht keine DNS-Abfrage, um das zu vermitteln: die &amp;amp;bdquo;no change&amp;amp;ldquo;-Antwort besagt nur, daß eine Anfrage für diesen Eintrag bereits mit Erfolg quittiert wurde.&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;notfqdn&amp;lt;/tt&amp;gt; ||&lt;br /&gt;
Fehlschlag: der gewünschte Domainname ist nicht gültig, oder es wurde keiner angegeben.&lt;br /&gt;
|| ...&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;nohost&amp;lt;/tt&amp;gt; ||&lt;br /&gt;
Fehlschlag: der gewünschte Domainname ist gehört nicht zu denen, die für diesen Benutzer des DDNS-Dienstes konfiguriert sind.&lt;br /&gt;
|| Siehe den Abschnitt &#039;&#039;&#039;Administration&#039;&#039;&#039; weiter unten.&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;abuse&amp;lt;/tt&amp;gt; ||&lt;br /&gt;
Fehlschlag: der gewünschte Domainname ist wegen vorangeganger Fehlschläge oder überflüssiger Aufrufe gesperrt.&lt;br /&gt;
|| Siehe den Abschnitt &#039;&#039;&#039;Sukzessive Kommunikationsvorgänge&#039;&#039;&#039; unten.&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;911&amp;lt;/tt&amp;gt; ||&lt;br /&gt;
Fehlschlag: Das Server-Programm hat einen internen Fehler festgestellt.&lt;br /&gt;
|| Das Problem liegt nicht in der Anfrage an sich.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Man kann sich durchaus eine sinnreichere Kommunikation zwischen Client und Server vorstellen, doch das hier beschriebene Protokoll ist eben von DynDNS.org verwendet worden und wird in gängigen Routern implementiert, also wird es in der vorliegenden DDNS-Implementierung nachgebildet.&lt;br /&gt;
&lt;br /&gt;
=== Sukzessive Kommunikationsabläufe ===&lt;br /&gt;
Der Server muß sich zwischen einzelnen Aufrufen einiges merken, um Ressourcen zu schonen und um zu verhindern, daß einmal vergebene DDNS-Einträge von neuen Anfragen, die dieselbe übergeordnete Domain betreffen, durch Überschreiben  verlorengehen.&lt;br /&gt;
&lt;br /&gt;
==== Mißbrauch und Benutzersperrung ====&lt;br /&gt;
Zur Schonung von Ressourcen muß sich die Implementierung weigern, sich mit zuvielen fehlerhaften oder auch nur überflüssigen Anfragen zu beschäftigen. Dazu führt eine Strichliste über solche Anfragen jedes Clients und sperrt nach einer bestimmten Anzahl solcher Anfragen den Benutzernamen oder einzelne Domainnamen gegen die weitere Nutzung des Dienstes.&lt;br /&gt;
&lt;br /&gt;
Mißbrauchspunkte gegen einen einzelnen Domainnamen gibt es für:&lt;br /&gt;
* eine Anfrage, die keinen neuen DNS-Eintrag (und keine Änderung oder Löschung eines Eintrags) erfordert, sondern bestehende Merkmale nur wiederholt&lt;br /&gt;
&lt;br /&gt;
Mißbrauchspunkte gegen einen Benutzernamen gibt es für:&lt;br /&gt;
* die Angabe eines Domainnamens, der in der Dienstkonfiguration dem anfragenden Benutzernamen nicht zugeordnet ist&lt;br /&gt;
* die Angabe eines Domainnamen in einer Domain, die nicht demselben Hostsharing-Domain-Admin gehört, der den DDNS-Dienst anbietet&lt;br /&gt;
* die Angabe eines Domainnamens, der in der Dienstkonfiguration bereits wegen mißbräuchlicher Anfragen gesperrt ist (siehe oben)&lt;br /&gt;
&lt;br /&gt;
Um eine Sperrung aufzuheben, wird in der Regel eine Handlung durch den Administrator erforderlich sein.&lt;br /&gt;
&lt;br /&gt;
==== Mehrere dynamische Subdomains in derselben Domain ====&lt;br /&gt;
Sobald zwei verschiedene DDNS-Einträge in derselben Domain verlangt werden &amp;amp;ndash; beispielsweise home.example.com und office.example.com &amp;amp;ndash; wird es notwendig, bei jeder neuen Zonefile für example.com eventuell frühere Einträge zu konservieren. Der Rechner zu Hause weiß beim Bestellen seines DDNS-Eintrags nichts vom Rechner im Büro und umgekehrt. Der Server muß in irgendeiner Form über bereits vergebene Einträge Buch führen und bei einer neuen Anfrage, die example.com betrifft, alle bereits aktiven DDNS-Einträge für example.com mit in die neue Zonefile aufnehmen &amp;amp;ndash auch wenn sie auf Anfragen verschiedener Benutzer zurückgehen.&lt;br /&gt;
&lt;br /&gt;
==== Datenbank ====&lt;br /&gt;
In der Beispielimplementierung werden diese Informationen in einer SQLite-Datenbank gespeichert.&lt;br /&gt;
&lt;br /&gt;
== Sicherheit ==&lt;br /&gt;
=== Rechte ===&lt;br /&gt;
Die &#039;&#039;&#039;Benutzerrechte&#039;&#039;&#039; werden durch das Hostsharing-System kontrolliert. Sowohl das CGI-Programm als auch das [[#Administration|Administrationswerkzeug]] werden mit den Rechten des Domain-Admins (xyz00-benutzername in unserem Beispiel) ausgeführt, also kann dieses Programm nur die Domains bearbeiten, die von xyz00-benutzername verwaltet werden.&lt;br /&gt;
&lt;br /&gt;
=== Authentifizierung ===&lt;br /&gt;
In der Beispielimplementierung (wie auch seinerzeit bei DynDNS.org) wird das CGI-Programm durch einen .htaccess-Eintrag geschützt, der HTTP-Basic-Authentication vorschreibt. Also wird das Programm eigentlich mit einem URL der form&lt;br /&gt;
&lt;br /&gt;
  &amp;lt;nowiki&amp;gt;https://ddnsaccount:passwort@ddns.example.com/cgi-bin/ddns?hostname=...&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
aufgerufen.&lt;br /&gt;
&lt;br /&gt;
=== Verschlüsselung ===&lt;br /&gt;
Das CGI-Programm sollte nur in example.com/cgi-ssl/ installiert werden, nicht in example.com/cgi/. Damit ist die Kommunikation zwischen Client und Server durch SSL verschlüsselt.&lt;br /&gt;
&lt;br /&gt;
== Administration ==&lt;br /&gt;
&lt;br /&gt;
Der Verwalter des DDNS-Programms trägt berechtigte Benutzer und die ihnen zugeteilten Domainnamen in die Datenbank des Programms ein mit Hilfe eines kleinen Hilfsprogramms. Das ist im vorliegenden Fall ein menügesteuertes Programm für die Befehlszeile, daß die naheliegenden Funktionen anbietet: Account hinzufügen, löschen, sperren, entsperren, Paßwort setzen, ändern; Domainnamen hinzufügen, ändern, entsperren, löschen; Accounts und Domainnamen mit aktuellem Status auflisten. Die Funktionen sind auch über Befehlszeilenargumente verfügbar, also skriptfähig.&lt;br /&gt;
&lt;br /&gt;
Eine Auflistung des momentanen Inhalts der DDNS-Datenbank durch das Administrationswerkzeug könnte beispielsweise so aussehen:&lt;br /&gt;
&lt;br /&gt;
  xyz00-benutzername@h02:~$ bin/ddnsadmin.pl -Aa&lt;br /&gt;
  1.  papst	Mißbrauch: 0; gesperrt: nein&lt;br /&gt;
  	avignon.example.com&lt;br /&gt;
  		zuletzt aktiv am Sun Apr 26 22:24:49 2020&lt;br /&gt;
  		mit IP-Nr. 87.65.43.21; MX: 0;  Backup-MX: nein;&lt;br /&gt;
  		Subdomains: nein; Mißbrauch: 0;  gesperrt: nein&lt;br /&gt;
  	vatican.beispiel.de&lt;br /&gt;
  		zuletzt aktiv am Sun Apr 26 22:24:49 2020&lt;br /&gt;
  		mit IP-Nr. 87.65.43.21; MX: 0;  Backup-MX: nein;&lt;br /&gt;
  		Subdomains: nein; Mißbrauch: 0;  gesperrt: nein&lt;br /&gt;
  2.  kaiser	Mißbrauch: 4; gesperrt: ja&lt;br /&gt;
  	augsburg.beispiel.de&lt;br /&gt;
  		zuletzt aktiv am Fri Apr 24 16:13:49 2020&lt;br /&gt;
  		mit IP-Nr. 64.82.31.75; MX: 0;  Backup-MX: nein;&lt;br /&gt;
  		Subdomains: nein; Mißbrauch: 0;  gesperrt: ja&lt;br /&gt;
  3.  luther	Mißbrauch: 1; gesperrt: nein&lt;br /&gt;
  	wittenberg.example.com&lt;br /&gt;
  		zuletzt aktiv am Mon Apr 27 10:12:49 2020&lt;br /&gt;
  		mit IP-Nr. 78.56.34.12; MX: 0;  Backup-MX: nein;&lt;br /&gt;
  		Subdomains: nein; Mißbrauch: 1;  gesperrt: nein&lt;br /&gt;
  xyz00-benutzername@h02:~$&lt;br /&gt;
&lt;br /&gt;
Das DDNS-Account &amp;amp;bdquo;kaiser&amp;amp;ldquo; in dieser Auflistung ist wohl auf Grund fehlerhafter Anfragen automatisch gesperrt worden. Der Inhaber wird sich wohl bald melden, um nach Korrektur seiner Client-Konfiguration die Aufhebung der Sperre zu wünschen.&lt;br /&gt;
&lt;br /&gt;
=== Log ===&lt;br /&gt;
Alle Anfragen werden in einer täglich wechselnden Log-Datei protokolliert, entweder schlicht oder ausführlich, je nachdem, ob eine Variable &amp;lt;tt&amp;gt;verbose&amp;lt;/tt&amp;gt; wahr ist.&lt;br /&gt;
Ein ausführlicher Log-Eintrag sieht so aus:&lt;br /&gt;
&lt;br /&gt;
  Sun Apr 26 20:21:45 2020  ddns aufgerufen von papst&lt;br /&gt;
  			unter 84.185.97.8&lt;br /&gt;
  	URL: &amp;lt;nowiki&amp;gt;https://ddns.example.com/cgi-bin/ddns.cgi?hostname=&lt;br /&gt;
  			avignon.example.com,vatican.beispiel.de&amp;amp;&lt;br /&gt;
  			myip=84.185.97.8&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
  	Verwende IP 84.185.97.8 (= 1421435144)&lt;br /&gt;
  	DB-Version: 1&lt;br /&gt;
  	Skript und DB exklusiv geöffnet&lt;br /&gt;
  	avignon.example.com: IP: 84.185.97.8; MX: 0; Backup-MX: nein;&lt;br /&gt;
  			Wildcard: nein; Mißbrauch: 0; gesperrt: nein &lt;br /&gt;
  	vatican.beispiel.de: IP: 84.185.97.8; MX: 0; Backup-MX: nein;&lt;br /&gt;
  			Wildcard: nein; Mißbrauch: 0; gesperrt: nein &lt;br /&gt;
  	Betroffene Zonen: example.com, beispiel.de&lt;br /&gt;
  	Temporärdatei example.com_hxNa.new geschrieben&lt;br /&gt;
  	Zonendatei /home/pacs/xyz00/users/benutzername/doms/example.com/&lt;br /&gt;
  			etc/pri.example.com eingestellt&lt;br /&gt;
  	Temporärdatei beispiel.de_6HcO.new geschrieben&lt;br /&gt;
  	Zonendatei /home/pacs/xyz00/users/benutzername/doms/beispiel.de/&lt;br /&gt;
  			etc/pri.beispiel.de eingestellt&lt;br /&gt;
  	Abgeschlossen: 	Fertig&lt;br /&gt;
&lt;br /&gt;
Wenn &amp;lt;tt&amp;gt;verbose&amp;lt;/tt&amp;gt; auf falsch gesetzt ist, sind die Log-Einträge einzeilig.&lt;/div&gt;</summary>
		<author><name>Apc00-tony</name></author>
	</entry>
	<entry>
		<id>https://wiki.hostsharing.net/index.php?title=Benutzer:Apc00-tony/Dynamisches_DNS&amp;diff=5194</id>
		<title>Benutzer:Apc00-tony/Dynamisches DNS</title>
		<link rel="alternate" type="text/html" href="https://wiki.hostsharing.net/index.php?title=Benutzer:Apc00-tony/Dynamisches_DNS&amp;diff=5194"/>
		<updated>2020-04-27T09:04:08Z</updated>

		<summary type="html">&lt;p&gt;Apc00-tony: /* Antwort */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;((Provisorischer Vorspann: Auf Grund einer Mailing-Listen-Diskussion habe ich angefangen, Dynamisches DNS über einen CGI-Skript bei Hostsharing zu realisieren. Meine Lösung habe ich dann vorgestellt; sie wurde für nicht ausreichend selbsterklärend befunden und fand wenig Akzeptanz. Hier also der Versuch, die Sache zu dokumentieren.))&lt;br /&gt;
&lt;br /&gt;
Mit der regelmäßigen Aufnahme von benutzerspezifischen Zonefiles in seiner DNS-Konfiguration bietet  Hostsharing alles, was man braucht, um &amp;amp;bdquo;dynamisches DNS&amp;amp;ldquo; in Eigenregie zu realisieren.&lt;br /&gt;
&lt;br /&gt;
Das heißt, wenn ich mindestens eine Domain bei Hostsharing verwalte, und mindestens eine Einwahlverbindung (oder DSL-Verbindung) ins Internet mit wechselnder IP-Adresse über irgendeinen ISP für meinen Arbeitsplatzrechner zu Hause betreibe, dann kann ich dem Arbeitsplatzrechner über die DNS-Server von Hostsharing einen vollqualifizieren Domainnamen zuweisen, der der jeweiligen IP-Adresse meiner Einwahlleitung zugeordnet ist.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
(ASCII-Art-Diagramm der beschriebenen Konstellation)&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Im Folgenden wird eine real existierende Implementierung von Dynamischem DNS (&amp;amp;bdquo;DDNS&amp;amp;ldquo;) beschrieben. Die verschiedenen Elemente könnten durchaus anders realisiert werden; die beschriebene Implementierung könnte durchaus verbessert werden. Sie dient hier der Illustration.&lt;br /&gt;
&lt;br /&gt;
In der folgenden Beschreibung werden diese Beispielwerte benutzt:&lt;br /&gt;
* Ein Hostsharing-Mitglied hat ein Account als Paket-Admin mit Kennung xyz00.&lt;br /&gt;
* Im Paket xyz00 gibt es einen Domain-Admin namens xyz00-benutzername.&lt;br /&gt;
* Dieser Domain-Admin verwaltet bei Hostsharing die Domains example.com und beispiel.de.&lt;br /&gt;
* Ein Benutzer hat zu Hause (oder im Büro) einen Arbeitsplatzrechner hinter der marktüblichen DSL-Leitung, die von seinem ISP bereitgestellt wird.&lt;br /&gt;
* Dieser Arbeitsplatzrechner (oder der Router, der seine Internetverbindung steuert) bekommt vom ISP immer wechselnde IP-Adressen zugewiesen.&lt;br /&gt;
* Dennoch möchte der Benutzer seinen Arbeitsplatzrechner aus dem Internet unter dem Hostnamen einwahl.example.com ansprechen können.&lt;br /&gt;
&lt;br /&gt;
Dazu kann ein System wie Hostsharing, das authoritative DNS-Informationen für viele Domains bereitstellt, auch veränderliche DNS-Information über dynamisch verbundene Rechner verwalten &amp;amp;ndash; sofern das ressourcenschonend gemacht werden kann ohne andere Funktionen zu stören.&lt;br /&gt;
&lt;br /&gt;
== Aufgaben des Servers ==&lt;br /&gt;
&lt;br /&gt;
Um einem Rechner mit wechselnder IP-Adresse einen DDNS-Eintrag zu bieten, muß der Hostsharing-Server folgendes leisten (in ungefährer Reihenfolge der Ereignisse):&lt;br /&gt;
&lt;br /&gt;
# Eine Anfrage entgegennehmen, beispielsweise über HTTPS, von einem entfernten Rechner, der einen DNS-Eintrag für seine momentane IP-Adresse wünscht. &lt;br /&gt;
# Prüfen, ob die Anfrage einen berechtigten DDNS-Dienst-Usernamen mit zugehörigem Paßwort enthält.&lt;br /&gt;
# Prüfen, ob die Anfrage einen gültigen Domainnamen betrifft, den der Server bieten darf.&lt;br /&gt;
# Prüfen, ob die Domain example.com demselben Benutzer gehört, unter dessen Namen der Dynamisches-DNS-Server läuft.&lt;br /&gt;
# Eine gültige [[Zonefile]] mit &amp;amp;ndash; neben dem bisherigen Inhalt &amp;amp;ndash; einem A-Eintrag für einwahl.example.com in /home/pacs/xyz00/users/benutzername/doms/example.com/pri.example.com schreiben.&lt;br /&gt;
# Dem Client eine Bestätigung oder ggf. eine Fehlermeldung als Antwort senden.&lt;br /&gt;
# In irgendeiner Datenbank den momentan eingestellter Status all seiner DDNS-Einträge speichern.&lt;br /&gt;
# In einer Logdatei protokollieren, daß obiges getan wurde, oder ggf. welche Fehler traten auf.&lt;br /&gt;
&lt;br /&gt;
== Aufgaben des Clients ==&lt;br /&gt;
Bevor ich anfange, meinen Arbeitsplatzrechner so zu konfigurieren, daß er bei welchem Server auch immer einen DDNS-Eintrag anfordert, muß ich mich als verantwortlicher Benutzer dieses Rechners und der dazugehörigen Internetverbindung &amp;amp;ndash; das heißt, als Mensch &amp;amp;ndash; mit dem Betreiber des dynamisches-DNS-Servers vereinbaren, daß ich das darf und welchen Eintrag ich bekommen kann. Im Folgenden wird vorausgesetzt, daß solche Vereinbarungen getroffen und die Parameter geklärt wurden.&lt;br /&gt;
&lt;br /&gt;
Der DDNS-Client muß aus Server-Sicht nur wenig leisten:&lt;br /&gt;
&lt;br /&gt;
# Eine Anfrage senden, beispielsweise über HTTPS, an einen entfernten Rechner, der einen Eintrag ins DNS für die momentane IP-Adresse des Clients vornehmen kann.&amp;lt;br /&amp;gt;Diese Anfrage muß einem festgelegten Format entsprechen und muß gültige Werte für die Authorisation des Clients, den gewünschten Domainnamen, und eventuell andere Parameter enthalten.&lt;br /&gt;
# Eine Antwort des Servers entgegennehmen und als Erfolgs- oder Fehlermeldung auswerten.&lt;br /&gt;
# Von überflüssigen Anfragen absehen: das heißt bei Erfolg, nicht wiederholt den gleichen Eintrag erneut wünschen; bei Fehlern, nicht die gleiche fehlerhafte Anfrage erneut schicken.&lt;br /&gt;
&lt;br /&gt;
== Kommunikation zwischen Client und Server ==&lt;br /&gt;
&lt;br /&gt;
Ein einziges Nachrichtenpaar von Anfrage und Antwort genügt, um einen DDNS-Eintrag einzurichten: Der Client teilt die IP-Adresse und den Domainnamen mit, die in einem DNS-Eintrag verbunden werden sollen; der Server bestätigt den Auftrag.&lt;br /&gt;
&lt;br /&gt;
In der Beispielimplementierung erfolgt die Kommunikation über HTTP, und die Anfrage des Clients könnte so aussehen:&lt;br /&gt;
&lt;br /&gt;
  GET /cgi-bin/ddns?hostname=einwahl.example.com&amp;amp;myip=87.65.43.21 HTTP/1.1&lt;br /&gt;
  Host: ddns.beispiel.de&lt;br /&gt;
  User-Agent: Fritz!Box DDNS/1.0.1&lt;br /&gt;
  Authorization: Basic QWxhZGRpbjpvcGVuIHNlc2FtZQ==&lt;br /&gt;
&lt;br /&gt;
Bei Erhalt dieser Anfrage ruft Apache das CGI-Programm .../doms/ddns.beispiel.de/cgi-ssl/ddns auf. Das Fragezeichen trennt den Programmnamen von einem &amp;quot;Query-String&amp;quot;, in dem zwei Metavariablen definiert und übergeben werden. Die erste Metavariable, hostname, hat den Wert &amp;quot;einwahl.example.com&amp;quot;; die zweite, myip, hat den Wert &amp;quot;87.65.43.21&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
Das Server-Programm, hier &#039;&#039;ddns&#039;&#039;, prüft diese Informationen auf Form und Berechtigung, und schreibt gegebenenfalls einen entsprechenden Eintrag in einer Zonefile. Es schreibt auch verschiedene Informationen in die Standardausgabe. Wenn es die Standardausgabe geschlossen wird &amp;amp;ndash; also spätestens bei Programmende &amp;amp;ndash; schickt Apache diese Informationen als Antwort an den anfragenden Rechner zurück.&lt;br /&gt;
&lt;br /&gt;
Im Falle unserer Beispielimplementierung sieht die Antwort bei Erfolg so aus: &lt;br /&gt;
&lt;br /&gt;
  HTTP/1.1 200 OK&lt;br /&gt;
  Date: Wed, 22 Apr 2020 08:35:15 GMT&lt;br /&gt;
  Server: Apache&lt;br /&gt;
  Content-Length: 17&lt;br /&gt;
  Content-Type: text/plain; charset=ISO-8859-1&lt;br /&gt;
 &lt;br /&gt;
  good 87.65.43.21&lt;br /&gt;
&lt;br /&gt;
=== Das DDNS-Protokoll von DynDNS.org ===&lt;br /&gt;
&lt;br /&gt;
In den 90er Jahren, bevor das Internet so durchgehend vergeschäftlicht wurde, boten einige Organisationen kostenlose DDNS-Dienste an. Ein sehr beliebtes Angebot war das von DynDNS.org. Das DDNS-Protokoll von diesem Dienst wurde sogar in Einwahl-Routern einprogrammiert und der Dienst wurde von ISPs und Router-Herstellern als Leistungsmerkmal beworben.&lt;br /&gt;
&lt;br /&gt;
DynDNS.org gehört inzwischen Oracle und bietet keine kostenlose Dienste mehr. Dennoch wird das DDNS-Protokoll von DynDNS.org in der vorliegenden Beispielimplementierung übernommen in der Hoffnung, daß die Kompatibilität mit einigen gängigen Einwahl-Routern von Vorteil sein kann. Es gibt noch eine kurze Online-Dokumentation der [https://help.dyn.com/remote-access-api/perform-update/ Anfrage] und [https://help.dyn.com/remote-access-api/perform-update/ Antwortnachrichten].&lt;br /&gt;
&lt;br /&gt;
Das gesammte Protokoll sieht einen einzigen Nachrichtenaustausch aus Anfrage und Antwort vor. Die Anfrage kann mehrere Argumente enthalten; die Antwort kann verschiedene Code-Wörtern enthalten. Übrigens können in einer einzigen Anfrage mehrere DNS-Einträge gewünscht werden. In diesem Fall kann die Antwort mehrzeilig ausfallen.&lt;br /&gt;
&lt;br /&gt;
Das Verhalten von Server und Client bei künftigen Kommunikationsvorgängen wird unter Umständen von vorangegangenen Kommunikationsergebnissen beeinflußt: nach wiederholten fehlerhaften oder redundanten Anfragen kann der Server weitere Anfragen des Benutzers verweigern; nach wiederholten Fehlermeldungen sollte ein Client aufhören, immer dieselbe Anfrage zu schicken. Und für den Fall, daß mehrere Clients dynamische DNS-Einträge in derselben Domain example.com bestellen, muß der Server den Stand aller Client-Einträge intern speichern, damit er nicht mit einer neuen Zonefile einen früher erstellten Eintrag löscht. Zu diesen Fragen siehe den Abschnitt &#039;&#039;&#039;[[#Sukzessive_Kommunikationsabläufe]]&#039;&#039;&#039; nach der Beschreibung von Anfragen und Antworten unten.&lt;br /&gt;
&lt;br /&gt;
====Anfrage====&lt;br /&gt;
&lt;br /&gt;
Die Anfrage in Form eines URL übergibt dem DDNS-Programm in einem &#039;Query-String&#039; einige Metavariablen. Das heißt, in einem URL der Form&lt;br /&gt;
&lt;br /&gt;
  &amp;lt;nowiki&amp;gt;https://benutzername:passwort@ddns.beisiel.de/cgi-bin/ddns?hostname=einwahl.example.com&amp;amp;myip=87.65.43.21&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
signalisert das Fragezeichen, daß ein Query-String folgt. In einem solchen Query-String können in der Beispielimplementierung folgende Metavariablen definiert werden:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|- class=&amp;quot;hintergrundfarbe5&amp;quot;&lt;br /&gt;
! Variable !! Beispiel !! Bemerkungen&lt;br /&gt;
|-&lt;br /&gt;
| hostname || &amp;lt;tt&amp;gt;hostname=einwahl.example.com&amp;lt;/tt&amp;gt;&amp;lt;br /&amp;gt;&amp;lt;div style=&amp;quot;font-size:smaller;&amp;quot;&amp;gt;&amp;lt;tt&amp;gt;hostname=eins.example.com,zwei.example.com[,...]&amp;lt;/tt&amp;gt;&amp;lt;/div&amp;gt; ||&lt;br /&gt;
Muß ein vollständig qualifizierter Domain-Name (&amp;quot;FQDN&amp;quot;) sein; &amp;lt;tt&amp;gt;example.com&amp;lt;/tt&amp;gt; muß eine vom Besitzer des DDNS-Programms verwaltete Domain sein. Genaugenommen kann der Wert eine durch Kommata gegliederte Liste mehrerer gültiger Domainnamen sein, falls mehrere Einträge mit derselben IP-Adresse gewünscht werden.&lt;br /&gt;
|-&lt;br /&gt;
| myip || &amp;lt;tt&amp;gt;myip=87.65.43.21&amp;lt;/tt&amp;gt;||&lt;br /&gt;
Kann entfallen; kann vom Server ignoriert werden. Maßgeblich ist dann die IP-Adresse des Absenders, wie sie vom Web-Server mitgeteilt wird.&lt;br /&gt;
|-&lt;br /&gt;
| mx || &amp;lt;tt&amp;gt;mx=87.65.43.21&amp;lt;/tt&amp;gt;&amp;lt;br /&amp;gt;&amp;lt;tt&amp;gt;mx=NOCHG&amp;lt;/tt&amp;gt;&amp;lt;br /&amp;gt; ||&lt;br /&gt;
Neben dem A-Eintrag möchte der Client auch einen MX-Eintrag. Der Wert &amp;lt;tt&amp;gt;NOCHG&amp;lt;/tt&amp;gt; (für &amp;amp;bdquo;no change&amp;amp;ldquo;) bedeutet, der bestehende MX-Eintrag (oder seine Abwesenheit) soll nicht geändert werden. &lt;br /&gt;
|-&lt;br /&gt;
| backmx || &amp;lt;tt&amp;gt;backmx=YES&amp;lt;/tt&amp;gt;&amp;lt;br /&amp;gt;&amp;lt;tt&amp;gt;backmx=NOCHG&amp;lt;/tt&amp;gt;&amp;lt;br /&amp;gt;&amp;lt;tt&amp;gt;backmx=NO&amp;lt;/tt&amp;gt;   ||&lt;br /&gt;
Falls &amp;lt;tt&amp;gt;YES&amp;lt;/tt&amp;gt;, wird ein zweiter MX-Eintrag erzeugt, der &amp;lt;tt&amp;gt;einwahl.example.com&amp;lt;/tt&amp;gt; als Mail-Server für &amp;lt;tt&amp;gt;einwahl.example.com&amp;lt;/tt&amp;gt; nennt. Dieser Eintrag hat eine niedrigere Präferenzzahl (also eine höhere Priorität) als der mit &amp;lt;tt&amp;gt;mx&amp;lt;/tt&amp;gt; angeforderten Eintrag.&lt;br /&gt;
|-&lt;br /&gt;
| wildcard || &amp;lt;tt&amp;gt;wildcard=ON&amp;lt;/tt&amp;gt;&amp;lt;br /&amp;gt;&amp;lt;tt&amp;gt;wildcard=NOCHG&amp;lt;/tt&amp;gt;&amp;lt;br /&amp;gt;&amp;lt;tt&amp;gt;wildcard=OFF&amp;lt;/tt&amp;gt; ||&lt;br /&gt;
Neben dem A-Eintrag für den Domainnamen &amp;lt;tt&amp;gt;einwahl.example.com&amp;lt;/tt&amp;gt; wünscht der Client auch einen Eintrag für beliebige Subdomains, also &amp;lt;tt&amp;gt;*.einwahl.example.com&amp;lt;/tt&amp;gt;, mit der gleichen IP-Adresse.&lt;br /&gt;
|-&lt;br /&gt;
| offline ||&amp;lt;tt&amp;gt;offline=YES&amp;lt;/tt&amp;gt;&amp;lt;br /&amp;gt;&amp;lt;tt&amp;gt;offline=NOCHG&amp;lt;/tt&amp;gt;||&lt;br /&gt;
Falls &amp;lt;tt&amp;gt;YES&amp;lt;/tt&amp;gt;, wird ein DNS-Eintrag für &amp;lt;tt&amp;gt;einwahl.example.com&amp;lt;/tt&amp;gt; aus der Zonefile getilgt. Gegebenenfalls wird der Hostname dann auf Grund eines parallelen Wildcard-Eintrags für &amp;lt;tt&amp;gt;*.example.com&amp;lt;/tt&amp;gt; einer anderen IP-Adresse zugeordnet werden.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;!-- IPv6? --&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Alle Parameter bis auf hostname können entfallen. Bei nichtdokumentierten Argumenten ist das Verhalten undefiniert&amp;amp;trade;.&lt;br /&gt;
&lt;br /&gt;
====Antwort====&lt;br /&gt;
&lt;br /&gt;
Die Antwort auf eine erfolgreiche HTTP-Anfrage besteht im häufigsten Fall aus einigen Header-Zeilen, gefolgt vom Inhalt der gewünschten Text- oder andere Datei. Ein Status-Code in der ersten Header-Zeile gibt an, ob die Anfrage bedient werden kann oder kreist andernfalls den Grund für die Enttäuschung ein.&lt;br /&gt;
&lt;br /&gt;
Die vorliegende Beispielimplementierung von DDNS schickt einen der üblichen HTTP-Status-Codes &amp;quot;200 OK&amp;quot; oder &amp;quot;500 Internal Server Error&amp;quot;, gefolgt von einer kurzen Textnachricht nach dem HTTP-Header. Bei diesem Programm  ist &amp;amp;ndash; laut Gebrauchshinweise von DynDNS.org &amp;amp;ndash; &#039;&#039;nicht&#039;&#039; der Status-Code im Header, sondern der Inhalt der Nachricht  die definierte, maßgebliche Ergebnismeldung des Programms.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|- class=&amp;quot;hintergrundfarbe5&amp;quot;&lt;br /&gt;
! Meldung !! Bedeutung !! Bemerkungen&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;good&amp;amp;nbsp;&amp;amp;lt;IP&amp;amp;nbsp;number&amp;amp;gt;&amp;lt;/tt&amp;gt; ||&lt;br /&gt;
Der gewünschte DNS-Eintrag wurde erfolgreich in einer Zonefile eingetragen. &lt;br /&gt;
|| Es kann natürlich noch einige Minuten dauern, bis die Zonefile vom Hostsharing-Roboter abgelesen wird und der Inhalt in die BIND-Konfiguration übernommen.&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;good&amp;amp;nbsp;127.0.0.1&amp;lt;/tt&amp;gt; ||&lt;br /&gt;
Die Anfrage entsprach nicht den Erfordernissen des Servers.&lt;br /&gt;
|| Trotz des Worts &amp;lt;tt&amp;gt;good&amp;lt;/tt&amp;gt; war die Anfrage nicht erfolgreich, falls in der Rückmeldung die IP-Adresse mit &amp;lt;tt&amp;gt;127.0.0.1&amp;lt;/tt&amp;gt; angegeben wird. Dieser verwirrende Fehlercode ist aus unerklärlichen Gründen in der Spezifikation von DynDNS.org so definiert.&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;nochg&amp;amp;nbsp;&amp;amp;lt;IP&amp;amp;nbsp;number&amp;amp;gt;&amp;lt;/tt&amp;gt; ||&lt;br /&gt;
Der gewünschte DNS-Eintrag war bereits vorhanden. &lt;br /&gt;
|| Der Server selbst macht keine DNS-Abfrage, um das zu vermitteln: die &amp;amp;bdquo;no change&amp;amp;ldquo;-Antwort besagt nur, daß eine Anfrage für diesen Eintrag bereits mit Erfolg quittiert wurde.&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;notfqdn&amp;lt;/tt&amp;gt; ||&lt;br /&gt;
Fehlschlag: der gewünschte Domainname ist nicht gültig, oder es wurde keiner angegeben.&lt;br /&gt;
|| ...&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;nohost&amp;lt;/tt&amp;gt; ||&lt;br /&gt;
Fehlschlag: der gewünschte Domainname ist gehört nicht zu denen, die für diesen Benutzer des DDNS-Dienstes konfiguriert sind.&lt;br /&gt;
|| Siehe den Abschnitt &#039;&#039;&#039;Administration&#039;&#039;&#039; weiter unten.&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;abuse&amp;lt;/tt&amp;gt; ||&lt;br /&gt;
Fehlschlag: der gewünschte Domainname ist wegen vorangeganger Fehlschläge oder überflüssiger Aufrufe gesperrt.&lt;br /&gt;
|| Siehe den Abschnitt &#039;&#039;&#039;Sukzessive Kommunikationsvorgänge&#039;&#039;&#039; unten.&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;911&amp;lt;/tt&amp;gt; ||&lt;br /&gt;
Fehlschlag: Das Server-Programm hat einen internen Fehler festgestellt.&lt;br /&gt;
|| Das Problem liegt nicht in der Anfrage an sich.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Man kann sich durchaus eine sinnreichere Kommunikation zwischen Client und Server vorstellen, doch das hier beschriebene Protokoll ist eben von DynDNS.org verwendet worden und wird in gängigen Routern implementiert, also wird es in der vorliegenden DDNS-Implementierung nachgebildet.&lt;br /&gt;
&lt;br /&gt;
=== Sukzessive Kommunikationsabläufe ===&lt;br /&gt;
Der Server muß sich zwischen einzelnen Aufrufen einiges merken, um Ressourcen zu schonen und um zu verhindern, daß einmal vergebene DDNS-Einträge von neuen Anfragen, die dieselbe übergeordnete Domain betreffen, durch Überschreiben  verlorengehen.&lt;br /&gt;
&lt;br /&gt;
==== Mißbrauch und Benutzersperrung ====&lt;br /&gt;
Zur Schonung von Ressourcen muß sich die Implementierung weigern, sich mit zuvielen fehlerhaften oder auch nur überflüssigen Anfragen zu beschäftigen. Dazu führt eine Strichliste über solche Anfragen jedes Clients und sperrt nach einer bestimmten Anzahl solcher Anfragen den Benutzernamen oder einzelne Domainnamen gegen die weitere Nutzung des Dienstes.&lt;br /&gt;
&lt;br /&gt;
Mißbrauchspunkte gegen einen einzelnen Domainnamen gibt es für:&lt;br /&gt;
* eine Anfrage, die keinen neuen DNS-Eintrag (und keine Änderung oder Löschung eines Eintrags) erfordert, sondern bestehende Merkmale nur wiederholt&lt;br /&gt;
&lt;br /&gt;
Mißbrauchspunkte gegen einen Benutzernamen gibt es für:&lt;br /&gt;
* die Angabe eines Domainnamens, der in der Dienstkonfiguration dem anfragenden Benutzernamen nicht zugeordnet ist&lt;br /&gt;
* die Angabe eines Domainnamen in einer Domain, die nicht demselben Hostsharing-Domain-Admin gehört, der den DDNS-Dienst anbietet&lt;br /&gt;
* die Angabe eines Domainnamens, der in der Dienstkonfiguration bereits wegen mißbräuchlicher Anfragen gesperrt ist (siehe oben)&lt;br /&gt;
&lt;br /&gt;
Um eine Sperrung aufzuheben, wird in der Regel eine Handlung durch den Administrator erforderlich sein.&lt;br /&gt;
&lt;br /&gt;
==== Mehrere dynamische Subdomains in derselben Domain ====&lt;br /&gt;
Sobald zwei verschiedene DDNS-Einträge in derselben Domain verlangt werden &amp;amp;ndash; beispielsweise home.example.com und office.example.com &amp;amp;ndash; wird es notwendig, bei jeder neuen Zonefile für example.com eventuell frühere Einträge zu konservieren. Der Rechner zu Hause weiß beim Bestellen seines DDNS-Eintrags nichts vom Rechner im Büro und umgekehrt. Der Server muß in irgendeiner Form über bereits vergebene Einträge Buch führen und bei einer neuen Anfrage, die example.com betrifft, alle bereits aktiven DDNS-Einträge für example.com mit in die neue Zonefile aufnehmen &amp;amp;ndash auch wenn sie auf Anfragen verschiedener Benutzer zurückgehen.&lt;br /&gt;
&lt;br /&gt;
==== Datenbank ====&lt;br /&gt;
In der Beispielimplementierung werden diese Informationen in einer SQLite-Datenbank gespeichert.&lt;br /&gt;
&lt;br /&gt;
== Sicherheit ==&lt;br /&gt;
=== Rechte ===&lt;br /&gt;
Die &#039;&#039;&#039;Benutzerrechte&#039;&#039;&#039; werden durch das Hostsharing-System kontrolliert. Sowohl das CGI-Programm als auch das [[#Administration|Administrationswerkzeug]] werden mit den Rechten des Domain-Admins (xyz00-benutzername in unserem Beispiel) ausgeführt, also kann dieses Programm nur die Domains bearbeiten, die von xyz00-benutzername verwaltet werden.&lt;br /&gt;
&lt;br /&gt;
=== Authentifizierung ===&lt;br /&gt;
In der Beispielimplementierung (wie auch seinerzeit bei DynDNS.org) wird das CGI-Programm durch einen .htaccess-Eintrag geschützt, der HTTP-Basic-Authentication vorschreibt. Also wird das Programm eigentlich mit einem URL der form&lt;br /&gt;
&lt;br /&gt;
  &amp;lt;nowiki&amp;gt;https://ddnsaccount:passwort@ddns.example.com/cgi-bin/ddns?hostname=...&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
aufgerufen.&lt;br /&gt;
&lt;br /&gt;
=== Verschlüsselung ===&lt;br /&gt;
Das CGI-Programm sollte nur in example.com/cgi-ssl/ installiert werden, nicht in example.com/cgi/. Damit ist die Kommunikation zwischen Client und Server durch SSL verschlüsselt.&lt;br /&gt;
&lt;br /&gt;
== Administration ==&lt;br /&gt;
&lt;br /&gt;
Der Verwalter des DDNS-Programms trägt berechtigte Benutzer und die ihnen zugeteilten Domainnamen in die Datenbank des Programms ein mit Hilfe eines kleinen Hilfsprogramms. Das ist im vorliegenden Fall ein menügesteuertes Programm für die Befehlszeile, daß die naheliegenden Funktionen anbietet: Account hinzufügen, löschen, sperren, entsperren, Paßwort setzen, ändern; Domainnamen hinzufügen, ändern, entsperren, löschen; Accounts und Domainnamen mit aktuellem Status auflisten. Die Funktionen sind auch über Befehlszeilenargumente verfügbar, also skriptfähig.&lt;br /&gt;
&lt;br /&gt;
Eine Auflistung des momentanen Inhalts der DDNS-Datenbank durch das Administrationswerkzeug könnte beispielsweise so aussehen:&lt;br /&gt;
&lt;br /&gt;
  xyz00-benutzername@h02:~$ bin/ddnsadmin.pl -Aa&lt;br /&gt;
  1.  papst	Mißbrauch: 0; gesperrt: nein&lt;br /&gt;
  	avignon.example.com&lt;br /&gt;
  		zuletzt aktiv am Sun Apr 26 22:24:49 2020&lt;br /&gt;
  		mit IP-Nr. 87.65.43.21; MX: 0;  Backup-MX: nein;&lt;br /&gt;
  		Subdomains: nein; Mißbrauch: 0;  gesperrt: nein&lt;br /&gt;
  	vatican.beispiel.de&lt;br /&gt;
  		zuletzt aktiv am Sun Apr 26 22:24:49 2020&lt;br /&gt;
  		mit IP-Nr. 87.65.43.21; MX: 0;  Backup-MX: nein;&lt;br /&gt;
  		Subdomains: nein; Mißbrauch: 0;  gesperrt: nein&lt;br /&gt;
  2.  kaiser	Mißbrauch: 4; gesperrt: ja&lt;br /&gt;
  	augsburg.beispiel.de&lt;br /&gt;
  		zuletzt aktiv am Fri Apr 24 16:13:49 2020&lt;br /&gt;
  		mit IP-Nr. 64.82.31.75; MX: 0;  Backup-MX: nein;&lt;br /&gt;
  		Subdomains: nein; Mißbrauch: 0;  gesperrt: ja&lt;br /&gt;
  3.  luther	Mißbrauch: 1; gesperrt: nein&lt;br /&gt;
  	wittenberg.example.com&lt;br /&gt;
  		zuletzt aktiv am Mon Apr 27 10:12:49 2020&lt;br /&gt;
  		mit IP-Nr. 78.56.34.12; MX: 0;  Backup-MX: nein;&lt;br /&gt;
  		Subdomains: nein; Mißbrauch: 1;  gesperrt: nein&lt;br /&gt;
  xyz00-benutzername@h02:~$&lt;br /&gt;
&lt;br /&gt;
Das DDNS-Account &amp;amp;bdquo;kaiser&amp;amp;ldquo; in dieser Auflistung ist wohl auf Grund fehlerhafter Anfragen automatisch gesperrt worden. Der Inhaber wird sich wohl bald melden, um nach Korrektur seiner Client-Konfiguration die Aufhebung der Sperre zu wünschen.&lt;br /&gt;
&lt;br /&gt;
=== Log ===&lt;br /&gt;
Alle Anfragen werden in einer täglich wechselnden Log-Datei protokolliert, entweder schlicht oder ausführlich, je nachdem, ob eine Variable &amp;lt;tt&amp;gt;verbose&amp;lt;/tt&amp;gt; wahr ist.&lt;br /&gt;
Ein ausführlicher Log-Eintrag sieht so aus:&lt;br /&gt;
&lt;br /&gt;
  Sun Apr 26 20:21:45 2020  ddns aufgerufen von papst&lt;br /&gt;
  			unter 84.185.97.8&lt;br /&gt;
  	URL: &amp;lt;nowiki&amp;gt;https://ddns.example.com/cgi-bin/ddns.cgi?hostname=&lt;br /&gt;
  			avignon.example.com,vatican.beispiel.de&amp;amp;&lt;br /&gt;
  			myip=84.185.97.8&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
  	Verwende IP 84.185.97.8 (= 1421435144)&lt;br /&gt;
  	DB-Version: 1&lt;br /&gt;
  	Skript und DB exklusiv geöffnet&lt;br /&gt;
  	avignon.example.com: IP: 84.185.97.8; MX: 0; Backup-MX: nein;&lt;br /&gt;
  			Wildcard: nein; Mißbrauch: 0; gesperrt: nein &lt;br /&gt;
  	vatican.beispiel.de: IP: 84.185.97.8; MX: 0; Backup-MX: nein;&lt;br /&gt;
  			Wildcard: nein; Mißbrauch: 0; gesperrt: nein &lt;br /&gt;
  	Betroffene Zonen: example.com, beispiel.de&lt;br /&gt;
  	Temporärdatei example.com_hxNa.new geschrieben&lt;br /&gt;
  	Zonendatei /home/pacs/xyz00/users/benutzername/doms/example.com/&lt;br /&gt;
  			etc/pri.example.com eingestellt&lt;br /&gt;
  	Temporärdatei beispiel.de_6HcO.new geschrieben&lt;br /&gt;
  	Zonendatei /home/pacs/xyz00/users/benutzername/doms/beispiel.de/&lt;br /&gt;
  			etc/pri.beispiel.de eingestellt&lt;br /&gt;
  	Abgeschlossen: 	Fertig&lt;br /&gt;
&lt;br /&gt;
Wenn &amp;lt;tt&amp;gt;verbose&amp;lt;/tt&amp;gt; auf falsch gesetzt ist, sind die Log-Einträge einzeilig.&lt;/div&gt;</summary>
		<author><name>Apc00-tony</name></author>
	</entry>
	<entry>
		<id>https://wiki.hostsharing.net/index.php?title=Benutzer:Apc00-tony/Dynamisches_DNS&amp;diff=5193</id>
		<title>Benutzer:Apc00-tony/Dynamisches DNS</title>
		<link rel="alternate" type="text/html" href="https://wiki.hostsharing.net/index.php?title=Benutzer:Apc00-tony/Dynamisches_DNS&amp;diff=5193"/>
		<updated>2020-04-27T08:57:44Z</updated>

		<summary type="html">&lt;p&gt;Apc00-tony: /* Administration */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;((Provisorischer Vorspann: Auf Grund einer Mailing-Listen-Diskussion habe ich angefangen, Dynamisches DNS über einen CGI-Skript bei Hostsharing zu realisieren. Meine Lösung habe ich dann vorgestellt; sie wurde für nicht ausreichend selbsterklärend befunden und fand wenig Akzeptanz. Hier also der Versuch, die Sache zu dokumentieren.))&lt;br /&gt;
&lt;br /&gt;
Mit der regelmäßigen Aufnahme von benutzerspezifischen Zonefiles in seiner DNS-Konfiguration bietet  Hostsharing alles, was man braucht, um &amp;amp;bdquo;dynamisches DNS&amp;amp;ldquo; in Eigenregie zu realisieren.&lt;br /&gt;
&lt;br /&gt;
Das heißt, wenn ich mindestens eine Domain bei Hostsharing verwalte, und mindestens eine Einwahlverbindung (oder DSL-Verbindung) ins Internet mit wechselnder IP-Adresse über irgendeinen ISP für meinen Arbeitsplatzrechner zu Hause betreibe, dann kann ich dem Arbeitsplatzrechner über die DNS-Server von Hostsharing einen vollqualifizieren Domainnamen zuweisen, der der jeweiligen IP-Adresse meiner Einwahlleitung zugeordnet ist.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
(ASCII-Art-Diagramm der beschriebenen Konstellation)&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Im Folgenden wird eine real existierende Implementierung von Dynamischem DNS (&amp;amp;bdquo;DDNS&amp;amp;ldquo;) beschrieben. Die verschiedenen Elemente könnten durchaus anders realisiert werden; die beschriebene Implementierung könnte durchaus verbessert werden. Sie dient hier der Illustration.&lt;br /&gt;
&lt;br /&gt;
In der folgenden Beschreibung werden diese Beispielwerte benutzt:&lt;br /&gt;
* Ein Hostsharing-Mitglied hat ein Account als Paket-Admin mit Kennung xyz00.&lt;br /&gt;
* Im Paket xyz00 gibt es einen Domain-Admin namens xyz00-benutzername.&lt;br /&gt;
* Dieser Domain-Admin verwaltet bei Hostsharing die Domains example.com und beispiel.de.&lt;br /&gt;
* Ein Benutzer hat zu Hause (oder im Büro) einen Arbeitsplatzrechner hinter der marktüblichen DSL-Leitung, die von seinem ISP bereitgestellt wird.&lt;br /&gt;
* Dieser Arbeitsplatzrechner (oder der Router, der seine Internetverbindung steuert) bekommt vom ISP immer wechselnde IP-Adressen zugewiesen.&lt;br /&gt;
* Dennoch möchte der Benutzer seinen Arbeitsplatzrechner aus dem Internet unter dem Hostnamen einwahl.example.com ansprechen können.&lt;br /&gt;
&lt;br /&gt;
Dazu kann ein System wie Hostsharing, das authoritative DNS-Informationen für viele Domains bereitstellt, auch veränderliche DNS-Information über dynamisch verbundene Rechner verwalten &amp;amp;ndash; sofern das ressourcenschonend gemacht werden kann ohne andere Funktionen zu stören.&lt;br /&gt;
&lt;br /&gt;
== Aufgaben des Servers ==&lt;br /&gt;
&lt;br /&gt;
Um einem Rechner mit wechselnder IP-Adresse einen DDNS-Eintrag zu bieten, muß der Hostsharing-Server folgendes leisten (in ungefährer Reihenfolge der Ereignisse):&lt;br /&gt;
&lt;br /&gt;
# Eine Anfrage entgegennehmen, beispielsweise über HTTPS, von einem entfernten Rechner, der einen DNS-Eintrag für seine momentane IP-Adresse wünscht. &lt;br /&gt;
# Prüfen, ob die Anfrage einen berechtigten DDNS-Dienst-Usernamen mit zugehörigem Paßwort enthält.&lt;br /&gt;
# Prüfen, ob die Anfrage einen gültigen Domainnamen betrifft, den der Server bieten darf.&lt;br /&gt;
# Prüfen, ob die Domain example.com demselben Benutzer gehört, unter dessen Namen der Dynamisches-DNS-Server läuft.&lt;br /&gt;
# Eine gültige [[Zonefile]] mit &amp;amp;ndash; neben dem bisherigen Inhalt &amp;amp;ndash; einem A-Eintrag für einwahl.example.com in /home/pacs/xyz00/users/benutzername/doms/example.com/pri.example.com schreiben.&lt;br /&gt;
# Dem Client eine Bestätigung oder ggf. eine Fehlermeldung als Antwort senden.&lt;br /&gt;
# In irgendeiner Datenbank den momentan eingestellter Status all seiner DDNS-Einträge speichern.&lt;br /&gt;
# In einer Logdatei protokollieren, daß obiges getan wurde, oder ggf. welche Fehler traten auf.&lt;br /&gt;
&lt;br /&gt;
== Aufgaben des Clients ==&lt;br /&gt;
Bevor ich anfange, meinen Arbeitsplatzrechner so zu konfigurieren, daß er bei welchem Server auch immer einen DDNS-Eintrag anfordert, muß ich mich als verantwortlicher Benutzer dieses Rechners und der dazugehörigen Internetverbindung &amp;amp;ndash; das heißt, als Mensch &amp;amp;ndash; mit dem Betreiber des dynamisches-DNS-Servers vereinbaren, daß ich das darf und welchen Eintrag ich bekommen kann. Im Folgenden wird vorausgesetzt, daß solche Vereinbarungen getroffen und die Parameter geklärt wurden.&lt;br /&gt;
&lt;br /&gt;
Der DDNS-Client muß aus Server-Sicht nur wenig leisten:&lt;br /&gt;
&lt;br /&gt;
# Eine Anfrage senden, beispielsweise über HTTPS, an einen entfernten Rechner, der einen Eintrag ins DNS für die momentane IP-Adresse des Clients vornehmen kann.&amp;lt;br /&amp;gt;Diese Anfrage muß einem festgelegten Format entsprechen und muß gültige Werte für die Authorisation des Clients, den gewünschten Domainnamen, und eventuell andere Parameter enthalten.&lt;br /&gt;
# Eine Antwort des Servers entgegennehmen und als Erfolgs- oder Fehlermeldung auswerten.&lt;br /&gt;
# Von überflüssigen Anfragen absehen: das heißt bei Erfolg, nicht wiederholt den gleichen Eintrag erneut wünschen; bei Fehlern, nicht die gleiche fehlerhafte Anfrage erneut schicken.&lt;br /&gt;
&lt;br /&gt;
== Kommunikation zwischen Client und Server ==&lt;br /&gt;
&lt;br /&gt;
Ein einziges Nachrichtenpaar von Anfrage und Antwort genügt, um einen DDNS-Eintrag einzurichten: Der Client teilt die IP-Adresse und den Domainnamen mit, die in einem DNS-Eintrag verbunden werden sollen; der Server bestätigt den Auftrag.&lt;br /&gt;
&lt;br /&gt;
In der Beispielimplementierung erfolgt die Kommunikation über HTTP, und die Anfrage des Clients könnte so aussehen:&lt;br /&gt;
&lt;br /&gt;
  GET /cgi-bin/ddns?hostname=einwahl.example.com&amp;amp;myip=87.65.43.21 HTTP/1.1&lt;br /&gt;
  Host: ddns.beispiel.de&lt;br /&gt;
  User-Agent: Fritz!Box DDNS/1.0.1&lt;br /&gt;
  Authorization: Basic QWxhZGRpbjpvcGVuIHNlc2FtZQ==&lt;br /&gt;
&lt;br /&gt;
Bei Erhalt dieser Anfrage ruft Apache das CGI-Programm .../doms/ddns.beispiel.de/cgi-ssl/ddns auf. Das Fragezeichen trennt den Programmnamen von einem &amp;quot;Query-String&amp;quot;, in dem zwei Metavariablen definiert und übergeben werden. Die erste Metavariable, hostname, hat den Wert &amp;quot;einwahl.example.com&amp;quot;; die zweite, myip, hat den Wert &amp;quot;87.65.43.21&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
Das Server-Programm, hier &#039;&#039;ddns&#039;&#039;, prüft diese Informationen auf Form und Berechtigung, und schreibt gegebenenfalls einen entsprechenden Eintrag in einer Zonefile. Es schreibt auch verschiedene Informationen in die Standardausgabe. Wenn es die Standardausgabe geschlossen wird &amp;amp;ndash; also spätestens bei Programmende &amp;amp;ndash; schickt Apache diese Informationen als Antwort an den anfragenden Rechner zurück.&lt;br /&gt;
&lt;br /&gt;
Im Falle unserer Beispielimplementierung sieht die Antwort bei Erfolg so aus: &lt;br /&gt;
&lt;br /&gt;
  HTTP/1.1 200 OK&lt;br /&gt;
  Date: Wed, 22 Apr 2020 08:35:15 GMT&lt;br /&gt;
  Server: Apache&lt;br /&gt;
  Content-Length: 17&lt;br /&gt;
  Content-Type: text/plain; charset=ISO-8859-1&lt;br /&gt;
 &lt;br /&gt;
  good 87.65.43.21&lt;br /&gt;
&lt;br /&gt;
=== Das DDNS-Protokoll von DynDNS.org ===&lt;br /&gt;
&lt;br /&gt;
In den 90er Jahren, bevor das Internet so durchgehend vergeschäftlicht wurde, boten einige Organisationen kostenlose DDNS-Dienste an. Ein sehr beliebtes Angebot war das von DynDNS.org. Das DDNS-Protokoll von diesem Dienst wurde sogar in Einwahl-Routern einprogrammiert und der Dienst wurde von ISPs und Router-Herstellern als Leistungsmerkmal beworben.&lt;br /&gt;
&lt;br /&gt;
DynDNS.org gehört inzwischen Oracle und bietet keine kostenlose Dienste mehr. Dennoch wird das DDNS-Protokoll von DynDNS.org in der vorliegenden Beispielimplementierung übernommen in der Hoffnung, daß die Kompatibilität mit einigen gängigen Einwahl-Routern von Vorteil sein kann. Es gibt noch eine kurze Online-Dokumentation der [https://help.dyn.com/remote-access-api/perform-update/ Anfrage] und [https://help.dyn.com/remote-access-api/perform-update/ Antwortnachrichten].&lt;br /&gt;
&lt;br /&gt;
Das gesammte Protokoll sieht einen einzigen Nachrichtenaustausch aus Anfrage und Antwort vor. Die Anfrage kann mehrere Argumente enthalten; die Antwort kann verschiedene Code-Wörtern enthalten. Übrigens können in einer einzigen Anfrage mehrere DNS-Einträge gewünscht werden. In diesem Fall kann die Antwort mehrzeilig ausfallen.&lt;br /&gt;
&lt;br /&gt;
Das Verhalten von Server und Client bei künftigen Kommunikationsvorgängen wird unter Umständen von vorangegangenen Kommunikationsergebnissen beeinflußt: nach wiederholten fehlerhaften oder redundanten Anfragen kann der Server weitere Anfragen des Benutzers verweigern; nach wiederholten Fehlermeldungen sollte ein Client aufhören, immer dieselbe Anfrage zu schicken. Und für den Fall, daß mehrere Clients dynamische DNS-Einträge in derselben Domain example.com bestellen, muß der Server den Stand aller Client-Einträge intern speichern, damit er nicht mit einer neuen Zonefile einen früher erstellten Eintrag löscht. Zu diesen Fragen siehe den Abschnitt &#039;&#039;&#039;[[#Sukzessive_Kommunikationsabläufe]]&#039;&#039;&#039; nach der Beschreibung von Anfragen und Antworten unten.&lt;br /&gt;
&lt;br /&gt;
====Anfrage====&lt;br /&gt;
&lt;br /&gt;
Die Anfrage in Form eines URL übergibt dem DDNS-Programm in einem &#039;Query-String&#039; einige Metavariablen. Das heißt, in einem URL der Form&lt;br /&gt;
&lt;br /&gt;
  &amp;lt;nowiki&amp;gt;https://benutzername:passwort@ddns.beisiel.de/cgi-bin/ddns?hostname=einwahl.example.com&amp;amp;myip=87.65.43.21&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
signalisert das Fragezeichen, daß ein Query-String folgt. In einem solchen Query-String können in der Beispielimplementierung folgende Metavariablen definiert werden:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|- class=&amp;quot;hintergrundfarbe5&amp;quot;&lt;br /&gt;
! Variable !! Beispiel !! Bemerkungen&lt;br /&gt;
|-&lt;br /&gt;
| hostname || &amp;lt;tt&amp;gt;hostname=einwahl.example.com&amp;lt;/tt&amp;gt;&amp;lt;br /&amp;gt;&amp;lt;div style=&amp;quot;font-size:smaller;&amp;quot;&amp;gt;&amp;lt;tt&amp;gt;hostname=eins.example.com,zwei.example.com[,...]&amp;lt;/tt&amp;gt;&amp;lt;/div&amp;gt; ||&lt;br /&gt;
Muß ein vollständig qualifizierter Domain-Name (&amp;quot;FQDN&amp;quot;) sein; &amp;lt;tt&amp;gt;example.com&amp;lt;/tt&amp;gt; muß eine vom Besitzer des DDNS-Programms verwaltete Domain sein. Genaugenommen kann der Wert eine durch Kommata gegliederte Liste mehrerer gültiger Domainnamen sein, falls mehrere Einträge mit derselben IP-Adresse gewünscht werden.&lt;br /&gt;
|-&lt;br /&gt;
| myip || &amp;lt;tt&amp;gt;myip=87.65.43.21&amp;lt;/tt&amp;gt;||&lt;br /&gt;
Kann entfallen; kann vom Server ignoriert werden. Maßgeblich ist dann die IP-Adresse des Absenders, wie sie vom Web-Server mitgeteilt wird.&lt;br /&gt;
|-&lt;br /&gt;
| mx || &amp;lt;tt&amp;gt;mx=87.65.43.21&amp;lt;/tt&amp;gt;&amp;lt;br /&amp;gt;&amp;lt;tt&amp;gt;mx=NOCHG&amp;lt;/tt&amp;gt;&amp;lt;br /&amp;gt; ||&lt;br /&gt;
Neben dem A-Eintrag möchte der Client auch einen MX-Eintrag. Der Wert &amp;lt;tt&amp;gt;NOCHG&amp;lt;/tt&amp;gt; (für &amp;amp;bdquo;no change&amp;amp;ldquo;) bedeutet, der bestehende MX-Eintrag (oder seine Abwesenheit) soll nicht geändert werden. &lt;br /&gt;
|-&lt;br /&gt;
| backmx || &amp;lt;tt&amp;gt;backmx=YES&amp;lt;/tt&amp;gt;&amp;lt;br /&amp;gt;&amp;lt;tt&amp;gt;backmx=NOCHG&amp;lt;/tt&amp;gt;&amp;lt;br /&amp;gt;&amp;lt;tt&amp;gt;backmx=NO&amp;lt;/tt&amp;gt;   ||&lt;br /&gt;
Falls &amp;lt;tt&amp;gt;YES&amp;lt;/tt&amp;gt;, wird ein zweiter MX-Eintrag erzeugt, der &amp;lt;tt&amp;gt;einwahl.example.com&amp;lt;/tt&amp;gt; als Mail-Server für &amp;lt;tt&amp;gt;einwahl.example.com&amp;lt;/tt&amp;gt; nennt. Dieser Eintrag hat eine niedrigere Präferenzzahl (also eine höhere Priorität) als der mit &amp;lt;tt&amp;gt;mx&amp;lt;/tt&amp;gt; angeforderten Eintrag.&lt;br /&gt;
|-&lt;br /&gt;
| wildcard || &amp;lt;tt&amp;gt;wildcard=ON&amp;lt;/tt&amp;gt;&amp;lt;br /&amp;gt;&amp;lt;tt&amp;gt;wildcard=NOCHG&amp;lt;/tt&amp;gt;&amp;lt;br /&amp;gt;&amp;lt;tt&amp;gt;wildcard=OFF&amp;lt;/tt&amp;gt; ||&lt;br /&gt;
Neben dem A-Eintrag für den Domainnamen &amp;lt;tt&amp;gt;einwahl.example.com&amp;lt;/tt&amp;gt; wünscht der Client auch einen Eintrag für beliebige Subdomains, also &amp;lt;tt&amp;gt;*.einwahl.example.com&amp;lt;/tt&amp;gt;, mit der gleichen IP-Adresse.&lt;br /&gt;
|-&lt;br /&gt;
| offline ||&amp;lt;tt&amp;gt;offline=YES&amp;lt;/tt&amp;gt;&amp;lt;br /&amp;gt;&amp;lt;tt&amp;gt;offline=NOCHG&amp;lt;/tt&amp;gt;||&lt;br /&gt;
Falls &amp;lt;tt&amp;gt;YES&amp;lt;/tt&amp;gt;, wird ein DNS-Eintrag für &amp;lt;tt&amp;gt;einwahl.example.com&amp;lt;/tt&amp;gt; aus der Zonefile getilgt. Gegebenenfalls wird der Hostname dann auf Grund eines parallelen Wildcard-Eintrags für &amp;lt;tt&amp;gt;*.example.com&amp;lt;/tt&amp;gt; einer anderen IP-Adresse zugeordnet werden.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;!-- IPv6? --&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Alle Parameter bis auf hostname können entfallen. Bei nichtdokumentierten Argumenten ist das Verhalten undefiniert&amp;amp;trade;.&lt;br /&gt;
&lt;br /&gt;
====Antwort====&lt;br /&gt;
&lt;br /&gt;
Die Antwort auf eine erfolgreiche HTTP-Anfrage besteht im häufigsten Fall aus einigen Header-Zeilen, gefolgt vom Inhalt der gewünschten Text- oder andere Datei. Ein Status-Code in der ersten Header-Zeile gibt an, ob die Anfrage bedient werden kann oder kreist andernfalls den Grund für die Enttäuschung ein.&lt;br /&gt;
&lt;br /&gt;
Die vorliegende Beispielimplementierung von DDNS schickt einen der üblichen HTTP-Status-Codes &amp;quot;200 OK&amp;quot; oder &amp;quot;500 Internal Server Error&amp;quot;, gefolgt von einer kurzen Textnachricht nach dem HTTP-Header. Bei diesem Programm  ist &amp;amp;ndash; laut Gebrauchshinweise von DynDNS.org &amp;amp;ndash; &#039;&#039;nicht&#039;&#039; der Status-Code im Header, sondern der Inhalt der Nachricht  die definierte, maßgebliche Ergebnismeldung des Programms.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|- class=&amp;quot;hintergrundfarbe5&amp;quot;&lt;br /&gt;
! Meldung !! Bedeutung !! Bemerkungen&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;good&amp;amp;nbsp;&amp;amp;lt;IP&amp;amp;nbsp;number&amp;amp;gt;&amp;lt;/tt&amp;gt; ||&lt;br /&gt;
Der gewünschte DNS-Eintrag wurde erfolgreich in einer Zonefile eingetragen. &lt;br /&gt;
|| Es kann natürlich noch einige Minuten dauern, bis die Zonefile vom Hostsharing-Roboter abgelesen wird und der Inhalt in die BIND-Konfiguration übernommen.&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;nochg&amp;amp;nbsp;&amp;amp;lt;IP&amp;amp;nbsp;number&amp;amp;gt;&amp;lt;/tt&amp;gt; ||&lt;br /&gt;
Der gewünschte DNS-Eintrag war bereits vorhanden. &lt;br /&gt;
|| Der Server selbst macht keine DNS-Abfrage, um das zu vermitteln: die &amp;amp;bdquo;no change&amp;amp;ldquo;-Antwort besagt nur, daß eine Anfrage für diesen Eintrag bereits mit Erfolg quittiert wurde.&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;notfqdn&amp;lt;/tt&amp;gt; ||&lt;br /&gt;
Fehlschlag: der gewünschte Domainname ist nicht gültig, oder es wurde keiner angegeben.&lt;br /&gt;
|| ...&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;nohost&amp;lt;/tt&amp;gt; ||&lt;br /&gt;
Fehlschlag: der gewünschte Domainname ist gehört nicht zu denen, die für diesen Benutzer des DDNS-Dienstes konfiguriert sind.&lt;br /&gt;
|| Siehe den Abschnitt &#039;&#039;&#039;Administration&#039;&#039;&#039; weiter unten.&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;abuse&amp;lt;/tt&amp;gt; ||&lt;br /&gt;
Fehlschlag: der gewünschte Domainname ist wegen vorangeganger Fehlschläge oder überflüssiger Aufrufe gesperrt.&lt;br /&gt;
|| Siehe den Abschnitt &#039;&#039;&#039;Sukzessive Kommunikationsvorgänge&#039;&#039;&#039; unten.&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;911&amp;lt;/tt&amp;gt; ||&lt;br /&gt;
Fehlschlag: Das Server-Programm hat einen internen Fehler festgestellt.&lt;br /&gt;
|| Das Problem liegt nicht in der Anfrage an sich.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Man kann sich durchaus eine sinnreichere Kommunikation zwischen Client und Server vorstellen, doch das hier beschriebene Protokoll ist eben von DynDNS.org verwendet worden und wird in gängigen Routern implementiert, also wird es in der vorliegenden DDNS-Implementierung nachgebildet.&lt;br /&gt;
&lt;br /&gt;
=== Sukzessive Kommunikationsabläufe ===&lt;br /&gt;
Der Server muß sich zwischen einzelnen Aufrufen einiges merken, um Ressourcen zu schonen und um zu verhindern, daß einmal vergebene DDNS-Einträge von neuen Anfragen, die dieselbe übergeordnete Domain betreffen, durch Überschreiben  verlorengehen.&lt;br /&gt;
&lt;br /&gt;
==== Mißbrauch und Benutzersperrung ====&lt;br /&gt;
Zur Schonung von Ressourcen muß sich die Implementierung weigern, sich mit zuvielen fehlerhaften oder auch nur überflüssigen Anfragen zu beschäftigen. Dazu führt eine Strichliste über solche Anfragen jedes Clients und sperrt nach einer bestimmten Anzahl solcher Anfragen den Benutzernamen oder einzelne Domainnamen gegen die weitere Nutzung des Dienstes.&lt;br /&gt;
&lt;br /&gt;
Mißbrauchspunkte gegen einen einzelnen Domainnamen gibt es für:&lt;br /&gt;
* eine Anfrage, die keinen neuen DNS-Eintrag (und keine Änderung oder Löschung eines Eintrags) erfordert, sondern bestehende Merkmale nur wiederholt&lt;br /&gt;
&lt;br /&gt;
Mißbrauchspunkte gegen einen Benutzernamen gibt es für:&lt;br /&gt;
* die Angabe eines Domainnamens, der in der Dienstkonfiguration dem anfragenden Benutzernamen nicht zugeordnet ist&lt;br /&gt;
* die Angabe eines Domainnamen in einer Domain, die nicht demselben Hostsharing-Domain-Admin gehört, der den DDNS-Dienst anbietet&lt;br /&gt;
* die Angabe eines Domainnamens, der in der Dienstkonfiguration bereits wegen mißbräuchlicher Anfragen gesperrt ist (siehe oben)&lt;br /&gt;
&lt;br /&gt;
Um eine Sperrung aufzuheben, wird in der Regel eine Handlung durch den Administrator erforderlich sein.&lt;br /&gt;
&lt;br /&gt;
==== Mehrere dynamische Subdomains in derselben Domain ====&lt;br /&gt;
Sobald zwei verschiedene DDNS-Einträge in derselben Domain verlangt werden &amp;amp;ndash; beispielsweise home.example.com und office.example.com &amp;amp;ndash; wird es notwendig, bei jeder neuen Zonefile für example.com eventuell frühere Einträge zu konservieren. Der Rechner zu Hause weiß beim Bestellen seines DDNS-Eintrags nichts vom Rechner im Büro und umgekehrt. Der Server muß in irgendeiner Form über bereits vergebene Einträge Buch führen und bei einer neuen Anfrage, die example.com betrifft, alle bereits aktiven DDNS-Einträge für example.com mit in die neue Zonefile aufnehmen &amp;amp;ndash auch wenn sie auf Anfragen verschiedener Benutzer zurückgehen.&lt;br /&gt;
&lt;br /&gt;
==== Datenbank ====&lt;br /&gt;
In der Beispielimplementierung werden diese Informationen in einer SQLite-Datenbank gespeichert.&lt;br /&gt;
&lt;br /&gt;
== Sicherheit ==&lt;br /&gt;
=== Rechte ===&lt;br /&gt;
Die &#039;&#039;&#039;Benutzerrechte&#039;&#039;&#039; werden durch das Hostsharing-System kontrolliert. Sowohl das CGI-Programm als auch das [[#Administration|Administrationswerkzeug]] werden mit den Rechten des Domain-Admins (xyz00-benutzername in unserem Beispiel) ausgeführt, also kann dieses Programm nur die Domains bearbeiten, die von xyz00-benutzername verwaltet werden.&lt;br /&gt;
&lt;br /&gt;
=== Authentifizierung ===&lt;br /&gt;
In der Beispielimplementierung (wie auch seinerzeit bei DynDNS.org) wird das CGI-Programm durch einen .htaccess-Eintrag geschützt, der HTTP-Basic-Authentication vorschreibt. Also wird das Programm eigentlich mit einem URL der form&lt;br /&gt;
&lt;br /&gt;
  &amp;lt;nowiki&amp;gt;https://ddnsaccount:passwort@ddns.example.com/cgi-bin/ddns?hostname=...&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
aufgerufen.&lt;br /&gt;
&lt;br /&gt;
=== Verschlüsselung ===&lt;br /&gt;
Das CGI-Programm sollte nur in example.com/cgi-ssl/ installiert werden, nicht in example.com/cgi/. Damit ist die Kommunikation zwischen Client und Server durch SSL verschlüsselt.&lt;br /&gt;
&lt;br /&gt;
== Administration ==&lt;br /&gt;
&lt;br /&gt;
Der Verwalter des DDNS-Programms trägt berechtigte Benutzer und die ihnen zugeteilten Domainnamen in die Datenbank des Programms ein mit Hilfe eines kleinen Hilfsprogramms. Das ist im vorliegenden Fall ein menügesteuertes Programm für die Befehlszeile, daß die naheliegenden Funktionen anbietet: Account hinzufügen, löschen, sperren, entsperren, Paßwort setzen, ändern; Domainnamen hinzufügen, ändern, entsperren, löschen; Accounts und Domainnamen mit aktuellem Status auflisten. Die Funktionen sind auch über Befehlszeilenargumente verfügbar, also skriptfähig.&lt;br /&gt;
&lt;br /&gt;
Eine Auflistung des momentanen Inhalts der DDNS-Datenbank durch das Administrationswerkzeug könnte beispielsweise so aussehen:&lt;br /&gt;
&lt;br /&gt;
  xyz00-benutzername@h02:~$ bin/ddnsadmin.pl -Aa&lt;br /&gt;
  1.  papst	Mißbrauch: 0; gesperrt: nein&lt;br /&gt;
  	avignon.example.com&lt;br /&gt;
  		zuletzt aktiv am Sun Apr 26 22:24:49 2020&lt;br /&gt;
  		mit IP-Nr. 87.65.43.21; MX: 0;  Backup-MX: nein;&lt;br /&gt;
  		Subdomains: nein; Mißbrauch: 0;  gesperrt: nein&lt;br /&gt;
  	vatican.beispiel.de&lt;br /&gt;
  		zuletzt aktiv am Sun Apr 26 22:24:49 2020&lt;br /&gt;
  		mit IP-Nr. 87.65.43.21; MX: 0;  Backup-MX: nein;&lt;br /&gt;
  		Subdomains: nein; Mißbrauch: 0;  gesperrt: nein&lt;br /&gt;
  2.  kaiser	Mißbrauch: 4; gesperrt: ja&lt;br /&gt;
  	augsburg.beispiel.de&lt;br /&gt;
  		zuletzt aktiv am Fri Apr 24 16:13:49 2020&lt;br /&gt;
  		mit IP-Nr. 64.82.31.75; MX: 0;  Backup-MX: nein;&lt;br /&gt;
  		Subdomains: nein; Mißbrauch: 0;  gesperrt: ja&lt;br /&gt;
  3.  luther	Mißbrauch: 1; gesperrt: nein&lt;br /&gt;
  	wittenberg.example.com&lt;br /&gt;
  		zuletzt aktiv am Mon Apr 27 10:12:49 2020&lt;br /&gt;
  		mit IP-Nr. 78.56.34.12; MX: 0;  Backup-MX: nein;&lt;br /&gt;
  		Subdomains: nein; Mißbrauch: 1;  gesperrt: nein&lt;br /&gt;
  xyz00-benutzername@h02:~$&lt;br /&gt;
&lt;br /&gt;
Das DDNS-Account &amp;amp;bdquo;kaiser&amp;amp;ldquo; in dieser Auflistung ist wohl auf Grund fehlerhafter Anfragen automatisch gesperrt worden. Der Inhaber wird sich wohl bald melden, um nach Korrektur seiner Client-Konfiguration die Aufhebung der Sperre zu wünschen.&lt;br /&gt;
&lt;br /&gt;
=== Log ===&lt;br /&gt;
Alle Anfragen werden in einer täglich wechselnden Log-Datei protokolliert, entweder schlicht oder ausführlich, je nachdem, ob eine Variable &amp;lt;tt&amp;gt;verbose&amp;lt;/tt&amp;gt; wahr ist.&lt;br /&gt;
Ein ausführlicher Log-Eintrag sieht so aus:&lt;br /&gt;
&lt;br /&gt;
  Sun Apr 26 20:21:45 2020  ddns aufgerufen von papst&lt;br /&gt;
  			unter 84.185.97.8&lt;br /&gt;
  	URL: &amp;lt;nowiki&amp;gt;https://ddns.example.com/cgi-bin/ddns.cgi?hostname=&lt;br /&gt;
  			avignon.example.com,vatican.beispiel.de&amp;amp;&lt;br /&gt;
  			myip=84.185.97.8&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
  	Verwende IP 84.185.97.8 (= 1421435144)&lt;br /&gt;
  	DB-Version: 1&lt;br /&gt;
  	Skript und DB exklusiv geöffnet&lt;br /&gt;
  	avignon.example.com: IP: 84.185.97.8; MX: 0; Backup-MX: nein;&lt;br /&gt;
  			Wildcard: nein; Mißbrauch: 0; gesperrt: nein &lt;br /&gt;
  	vatican.beispiel.de: IP: 84.185.97.8; MX: 0; Backup-MX: nein;&lt;br /&gt;
  			Wildcard: nein; Mißbrauch: 0; gesperrt: nein &lt;br /&gt;
  	Betroffene Zonen: example.com, beispiel.de&lt;br /&gt;
  	Temporärdatei example.com_hxNa.new geschrieben&lt;br /&gt;
  	Zonendatei /home/pacs/xyz00/users/benutzername/doms/example.com/&lt;br /&gt;
  			etc/pri.example.com eingestellt&lt;br /&gt;
  	Temporärdatei beispiel.de_6HcO.new geschrieben&lt;br /&gt;
  	Zonendatei /home/pacs/xyz00/users/benutzername/doms/beispiel.de/&lt;br /&gt;
  			etc/pri.beispiel.de eingestellt&lt;br /&gt;
  	Abgeschlossen: 	Fertig&lt;br /&gt;
&lt;br /&gt;
Wenn &amp;lt;tt&amp;gt;verbose&amp;lt;/tt&amp;gt; auf falsch gesetzt ist, sind die Log-Einträge einzeilig.&lt;/div&gt;</summary>
		<author><name>Apc00-tony</name></author>
	</entry>
	<entry>
		<id>https://wiki.hostsharing.net/index.php?title=Benutzer:Apc00-tony/Dynamisches_DNS&amp;diff=5192</id>
		<title>Benutzer:Apc00-tony/Dynamisches DNS</title>
		<link rel="alternate" type="text/html" href="https://wiki.hostsharing.net/index.php?title=Benutzer:Apc00-tony/Dynamisches_DNS&amp;diff=5192"/>
		<updated>2020-04-27T08:56:15Z</updated>

		<summary type="html">&lt;p&gt;Apc00-tony: /* Administration */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;((Provisorischer Vorspann: Auf Grund einer Mailing-Listen-Diskussion habe ich angefangen, Dynamisches DNS über einen CGI-Skript bei Hostsharing zu realisieren. Meine Lösung habe ich dann vorgestellt; sie wurde für nicht ausreichend selbsterklärend befunden und fand wenig Akzeptanz. Hier also der Versuch, die Sache zu dokumentieren.))&lt;br /&gt;
&lt;br /&gt;
Mit der regelmäßigen Aufnahme von benutzerspezifischen Zonefiles in seiner DNS-Konfiguration bietet  Hostsharing alles, was man braucht, um &amp;amp;bdquo;dynamisches DNS&amp;amp;ldquo; in Eigenregie zu realisieren.&lt;br /&gt;
&lt;br /&gt;
Das heißt, wenn ich mindestens eine Domain bei Hostsharing verwalte, und mindestens eine Einwahlverbindung (oder DSL-Verbindung) ins Internet mit wechselnder IP-Adresse über irgendeinen ISP für meinen Arbeitsplatzrechner zu Hause betreibe, dann kann ich dem Arbeitsplatzrechner über die DNS-Server von Hostsharing einen vollqualifizieren Domainnamen zuweisen, der der jeweiligen IP-Adresse meiner Einwahlleitung zugeordnet ist.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
(ASCII-Art-Diagramm der beschriebenen Konstellation)&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Im Folgenden wird eine real existierende Implementierung von Dynamischem DNS (&amp;amp;bdquo;DDNS&amp;amp;ldquo;) beschrieben. Die verschiedenen Elemente könnten durchaus anders realisiert werden; die beschriebene Implementierung könnte durchaus verbessert werden. Sie dient hier der Illustration.&lt;br /&gt;
&lt;br /&gt;
In der folgenden Beschreibung werden diese Beispielwerte benutzt:&lt;br /&gt;
* Ein Hostsharing-Mitglied hat ein Account als Paket-Admin mit Kennung xyz00.&lt;br /&gt;
* Im Paket xyz00 gibt es einen Domain-Admin namens xyz00-benutzername.&lt;br /&gt;
* Dieser Domain-Admin verwaltet bei Hostsharing die Domains example.com und beispiel.de.&lt;br /&gt;
* Ein Benutzer hat zu Hause (oder im Büro) einen Arbeitsplatzrechner hinter der marktüblichen DSL-Leitung, die von seinem ISP bereitgestellt wird.&lt;br /&gt;
* Dieser Arbeitsplatzrechner (oder der Router, der seine Internetverbindung steuert) bekommt vom ISP immer wechselnde IP-Adressen zugewiesen.&lt;br /&gt;
* Dennoch möchte der Benutzer seinen Arbeitsplatzrechner aus dem Internet unter dem Hostnamen einwahl.example.com ansprechen können.&lt;br /&gt;
&lt;br /&gt;
Dazu kann ein System wie Hostsharing, das authoritative DNS-Informationen für viele Domains bereitstellt, auch veränderliche DNS-Information über dynamisch verbundene Rechner verwalten &amp;amp;ndash; sofern das ressourcenschonend gemacht werden kann ohne andere Funktionen zu stören.&lt;br /&gt;
&lt;br /&gt;
== Aufgaben des Servers ==&lt;br /&gt;
&lt;br /&gt;
Um einem Rechner mit wechselnder IP-Adresse einen DDNS-Eintrag zu bieten, muß der Hostsharing-Server folgendes leisten (in ungefährer Reihenfolge der Ereignisse):&lt;br /&gt;
&lt;br /&gt;
# Eine Anfrage entgegennehmen, beispielsweise über HTTPS, von einem entfernten Rechner, der einen DNS-Eintrag für seine momentane IP-Adresse wünscht. &lt;br /&gt;
# Prüfen, ob die Anfrage einen berechtigten DDNS-Dienst-Usernamen mit zugehörigem Paßwort enthält.&lt;br /&gt;
# Prüfen, ob die Anfrage einen gültigen Domainnamen betrifft, den der Server bieten darf.&lt;br /&gt;
# Prüfen, ob die Domain example.com demselben Benutzer gehört, unter dessen Namen der Dynamisches-DNS-Server läuft.&lt;br /&gt;
# Eine gültige [[Zonefile]] mit &amp;amp;ndash; neben dem bisherigen Inhalt &amp;amp;ndash; einem A-Eintrag für einwahl.example.com in /home/pacs/xyz00/users/benutzername/doms/example.com/pri.example.com schreiben.&lt;br /&gt;
# Dem Client eine Bestätigung oder ggf. eine Fehlermeldung als Antwort senden.&lt;br /&gt;
# In irgendeiner Datenbank den momentan eingestellter Status all seiner DDNS-Einträge speichern.&lt;br /&gt;
# In einer Logdatei protokollieren, daß obiges getan wurde, oder ggf. welche Fehler traten auf.&lt;br /&gt;
&lt;br /&gt;
== Aufgaben des Clients ==&lt;br /&gt;
Bevor ich anfange, meinen Arbeitsplatzrechner so zu konfigurieren, daß er bei welchem Server auch immer einen DDNS-Eintrag anfordert, muß ich mich als verantwortlicher Benutzer dieses Rechners und der dazugehörigen Internetverbindung &amp;amp;ndash; das heißt, als Mensch &amp;amp;ndash; mit dem Betreiber des dynamisches-DNS-Servers vereinbaren, daß ich das darf und welchen Eintrag ich bekommen kann. Im Folgenden wird vorausgesetzt, daß solche Vereinbarungen getroffen und die Parameter geklärt wurden.&lt;br /&gt;
&lt;br /&gt;
Der DDNS-Client muß aus Server-Sicht nur wenig leisten:&lt;br /&gt;
&lt;br /&gt;
# Eine Anfrage senden, beispielsweise über HTTPS, an einen entfernten Rechner, der einen Eintrag ins DNS für die momentane IP-Adresse des Clients vornehmen kann.&amp;lt;br /&amp;gt;Diese Anfrage muß einem festgelegten Format entsprechen und muß gültige Werte für die Authorisation des Clients, den gewünschten Domainnamen, und eventuell andere Parameter enthalten.&lt;br /&gt;
# Eine Antwort des Servers entgegennehmen und als Erfolgs- oder Fehlermeldung auswerten.&lt;br /&gt;
# Von überflüssigen Anfragen absehen: das heißt bei Erfolg, nicht wiederholt den gleichen Eintrag erneut wünschen; bei Fehlern, nicht die gleiche fehlerhafte Anfrage erneut schicken.&lt;br /&gt;
&lt;br /&gt;
== Kommunikation zwischen Client und Server ==&lt;br /&gt;
&lt;br /&gt;
Ein einziges Nachrichtenpaar von Anfrage und Antwort genügt, um einen DDNS-Eintrag einzurichten: Der Client teilt die IP-Adresse und den Domainnamen mit, die in einem DNS-Eintrag verbunden werden sollen; der Server bestätigt den Auftrag.&lt;br /&gt;
&lt;br /&gt;
In der Beispielimplementierung erfolgt die Kommunikation über HTTP, und die Anfrage des Clients könnte so aussehen:&lt;br /&gt;
&lt;br /&gt;
  GET /cgi-bin/ddns?hostname=einwahl.example.com&amp;amp;myip=87.65.43.21 HTTP/1.1&lt;br /&gt;
  Host: ddns.beispiel.de&lt;br /&gt;
  User-Agent: Fritz!Box DDNS/1.0.1&lt;br /&gt;
  Authorization: Basic QWxhZGRpbjpvcGVuIHNlc2FtZQ==&lt;br /&gt;
&lt;br /&gt;
Bei Erhalt dieser Anfrage ruft Apache das CGI-Programm .../doms/ddns.beispiel.de/cgi-ssl/ddns auf. Das Fragezeichen trennt den Programmnamen von einem &amp;quot;Query-String&amp;quot;, in dem zwei Metavariablen definiert und übergeben werden. Die erste Metavariable, hostname, hat den Wert &amp;quot;einwahl.example.com&amp;quot;; die zweite, myip, hat den Wert &amp;quot;87.65.43.21&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
Das Server-Programm, hier &#039;&#039;ddns&#039;&#039;, prüft diese Informationen auf Form und Berechtigung, und schreibt gegebenenfalls einen entsprechenden Eintrag in einer Zonefile. Es schreibt auch verschiedene Informationen in die Standardausgabe. Wenn es die Standardausgabe geschlossen wird &amp;amp;ndash; also spätestens bei Programmende &amp;amp;ndash; schickt Apache diese Informationen als Antwort an den anfragenden Rechner zurück.&lt;br /&gt;
&lt;br /&gt;
Im Falle unserer Beispielimplementierung sieht die Antwort bei Erfolg so aus: &lt;br /&gt;
&lt;br /&gt;
  HTTP/1.1 200 OK&lt;br /&gt;
  Date: Wed, 22 Apr 2020 08:35:15 GMT&lt;br /&gt;
  Server: Apache&lt;br /&gt;
  Content-Length: 17&lt;br /&gt;
  Content-Type: text/plain; charset=ISO-8859-1&lt;br /&gt;
 &lt;br /&gt;
  good 87.65.43.21&lt;br /&gt;
&lt;br /&gt;
=== Das DDNS-Protokoll von DynDNS.org ===&lt;br /&gt;
&lt;br /&gt;
In den 90er Jahren, bevor das Internet so durchgehend vergeschäftlicht wurde, boten einige Organisationen kostenlose DDNS-Dienste an. Ein sehr beliebtes Angebot war das von DynDNS.org. Das DDNS-Protokoll von diesem Dienst wurde sogar in Einwahl-Routern einprogrammiert und der Dienst wurde von ISPs und Router-Herstellern als Leistungsmerkmal beworben.&lt;br /&gt;
&lt;br /&gt;
DynDNS.org gehört inzwischen Oracle und bietet keine kostenlose Dienste mehr. Dennoch wird das DDNS-Protokoll von DynDNS.org in der vorliegenden Beispielimplementierung übernommen in der Hoffnung, daß die Kompatibilität mit einigen gängigen Einwahl-Routern von Vorteil sein kann. Es gibt noch eine kurze Online-Dokumentation der [https://help.dyn.com/remote-access-api/perform-update/ Anfrage] und [https://help.dyn.com/remote-access-api/perform-update/ Antwortnachrichten].&lt;br /&gt;
&lt;br /&gt;
Das gesammte Protokoll sieht einen einzigen Nachrichtenaustausch aus Anfrage und Antwort vor. Die Anfrage kann mehrere Argumente enthalten; die Antwort kann verschiedene Code-Wörtern enthalten. Übrigens können in einer einzigen Anfrage mehrere DNS-Einträge gewünscht werden. In diesem Fall kann die Antwort mehrzeilig ausfallen.&lt;br /&gt;
&lt;br /&gt;
Das Verhalten von Server und Client bei künftigen Kommunikationsvorgängen wird unter Umständen von vorangegangenen Kommunikationsergebnissen beeinflußt: nach wiederholten fehlerhaften oder redundanten Anfragen kann der Server weitere Anfragen des Benutzers verweigern; nach wiederholten Fehlermeldungen sollte ein Client aufhören, immer dieselbe Anfrage zu schicken. Und für den Fall, daß mehrere Clients dynamische DNS-Einträge in derselben Domain example.com bestellen, muß der Server den Stand aller Client-Einträge intern speichern, damit er nicht mit einer neuen Zonefile einen früher erstellten Eintrag löscht. Zu diesen Fragen siehe den Abschnitt &#039;&#039;&#039;[[#Sukzessive_Kommunikationsabläufe]]&#039;&#039;&#039; nach der Beschreibung von Anfragen und Antworten unten.&lt;br /&gt;
&lt;br /&gt;
====Anfrage====&lt;br /&gt;
&lt;br /&gt;
Die Anfrage in Form eines URL übergibt dem DDNS-Programm in einem &#039;Query-String&#039; einige Metavariablen. Das heißt, in einem URL der Form&lt;br /&gt;
&lt;br /&gt;
  &amp;lt;nowiki&amp;gt;https://benutzername:passwort@ddns.beisiel.de/cgi-bin/ddns?hostname=einwahl.example.com&amp;amp;myip=87.65.43.21&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
signalisert das Fragezeichen, daß ein Query-String folgt. In einem solchen Query-String können in der Beispielimplementierung folgende Metavariablen definiert werden:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|- class=&amp;quot;hintergrundfarbe5&amp;quot;&lt;br /&gt;
! Variable !! Beispiel !! Bemerkungen&lt;br /&gt;
|-&lt;br /&gt;
| hostname || &amp;lt;tt&amp;gt;hostname=einwahl.example.com&amp;lt;/tt&amp;gt;&amp;lt;br /&amp;gt;&amp;lt;div style=&amp;quot;font-size:smaller;&amp;quot;&amp;gt;&amp;lt;tt&amp;gt;hostname=eins.example.com,zwei.example.com[,...]&amp;lt;/tt&amp;gt;&amp;lt;/div&amp;gt; ||&lt;br /&gt;
Muß ein vollständig qualifizierter Domain-Name (&amp;quot;FQDN&amp;quot;) sein; &amp;lt;tt&amp;gt;example.com&amp;lt;/tt&amp;gt; muß eine vom Besitzer des DDNS-Programms verwaltete Domain sein. Genaugenommen kann der Wert eine durch Kommata gegliederte Liste mehrerer gültiger Domainnamen sein, falls mehrere Einträge mit derselben IP-Adresse gewünscht werden.&lt;br /&gt;
|-&lt;br /&gt;
| myip || &amp;lt;tt&amp;gt;myip=87.65.43.21&amp;lt;/tt&amp;gt;||&lt;br /&gt;
Kann entfallen; kann vom Server ignoriert werden. Maßgeblich ist dann die IP-Adresse des Absenders, wie sie vom Web-Server mitgeteilt wird.&lt;br /&gt;
|-&lt;br /&gt;
| mx || &amp;lt;tt&amp;gt;mx=87.65.43.21&amp;lt;/tt&amp;gt;&amp;lt;br /&amp;gt;&amp;lt;tt&amp;gt;mx=NOCHG&amp;lt;/tt&amp;gt;&amp;lt;br /&amp;gt; ||&lt;br /&gt;
Neben dem A-Eintrag möchte der Client auch einen MX-Eintrag. Der Wert &amp;lt;tt&amp;gt;NOCHG&amp;lt;/tt&amp;gt; (für &amp;amp;bdquo;no change&amp;amp;ldquo;) bedeutet, der bestehende MX-Eintrag (oder seine Abwesenheit) soll nicht geändert werden. &lt;br /&gt;
|-&lt;br /&gt;
| backmx || &amp;lt;tt&amp;gt;backmx=YES&amp;lt;/tt&amp;gt;&amp;lt;br /&amp;gt;&amp;lt;tt&amp;gt;backmx=NOCHG&amp;lt;/tt&amp;gt;&amp;lt;br /&amp;gt;&amp;lt;tt&amp;gt;backmx=NO&amp;lt;/tt&amp;gt;   ||&lt;br /&gt;
Falls &amp;lt;tt&amp;gt;YES&amp;lt;/tt&amp;gt;, wird ein zweiter MX-Eintrag erzeugt, der &amp;lt;tt&amp;gt;einwahl.example.com&amp;lt;/tt&amp;gt; als Mail-Server für &amp;lt;tt&amp;gt;einwahl.example.com&amp;lt;/tt&amp;gt; nennt. Dieser Eintrag hat eine niedrigere Präferenzzahl (also eine höhere Priorität) als der mit &amp;lt;tt&amp;gt;mx&amp;lt;/tt&amp;gt; angeforderten Eintrag.&lt;br /&gt;
|-&lt;br /&gt;
| wildcard || &amp;lt;tt&amp;gt;wildcard=ON&amp;lt;/tt&amp;gt;&amp;lt;br /&amp;gt;&amp;lt;tt&amp;gt;wildcard=NOCHG&amp;lt;/tt&amp;gt;&amp;lt;br /&amp;gt;&amp;lt;tt&amp;gt;wildcard=OFF&amp;lt;/tt&amp;gt; ||&lt;br /&gt;
Neben dem A-Eintrag für den Domainnamen &amp;lt;tt&amp;gt;einwahl.example.com&amp;lt;/tt&amp;gt; wünscht der Client auch einen Eintrag für beliebige Subdomains, also &amp;lt;tt&amp;gt;*.einwahl.example.com&amp;lt;/tt&amp;gt;, mit der gleichen IP-Adresse.&lt;br /&gt;
|-&lt;br /&gt;
| offline ||&amp;lt;tt&amp;gt;offline=YES&amp;lt;/tt&amp;gt;&amp;lt;br /&amp;gt;&amp;lt;tt&amp;gt;offline=NOCHG&amp;lt;/tt&amp;gt;||&lt;br /&gt;
Falls &amp;lt;tt&amp;gt;YES&amp;lt;/tt&amp;gt;, wird ein DNS-Eintrag für &amp;lt;tt&amp;gt;einwahl.example.com&amp;lt;/tt&amp;gt; aus der Zonefile getilgt. Gegebenenfalls wird der Hostname dann auf Grund eines parallelen Wildcard-Eintrags für &amp;lt;tt&amp;gt;*.example.com&amp;lt;/tt&amp;gt; einer anderen IP-Adresse zugeordnet werden.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;!-- IPv6? --&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Alle Parameter bis auf hostname können entfallen. Bei nichtdokumentierten Argumenten ist das Verhalten undefiniert&amp;amp;trade;.&lt;br /&gt;
&lt;br /&gt;
====Antwort====&lt;br /&gt;
&lt;br /&gt;
Die Antwort auf eine erfolgreiche HTTP-Anfrage besteht im häufigsten Fall aus einigen Header-Zeilen, gefolgt vom Inhalt der gewünschten Text- oder andere Datei. Ein Status-Code in der ersten Header-Zeile gibt an, ob die Anfrage bedient werden kann oder kreist andernfalls den Grund für die Enttäuschung ein.&lt;br /&gt;
&lt;br /&gt;
Die vorliegende Beispielimplementierung von DDNS schickt einen der üblichen HTTP-Status-Codes &amp;quot;200 OK&amp;quot; oder &amp;quot;500 Internal Server Error&amp;quot;, gefolgt von einer kurzen Textnachricht nach dem HTTP-Header. Bei diesem Programm  ist &amp;amp;ndash; laut Gebrauchshinweise von DynDNS.org &amp;amp;ndash; &#039;&#039;nicht&#039;&#039; der Status-Code im Header, sondern der Inhalt der Nachricht  die definierte, maßgebliche Ergebnismeldung des Programms.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|- class=&amp;quot;hintergrundfarbe5&amp;quot;&lt;br /&gt;
! Meldung !! Bedeutung !! Bemerkungen&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;good&amp;amp;nbsp;&amp;amp;lt;IP&amp;amp;nbsp;number&amp;amp;gt;&amp;lt;/tt&amp;gt; ||&lt;br /&gt;
Der gewünschte DNS-Eintrag wurde erfolgreich in einer Zonefile eingetragen. &lt;br /&gt;
|| Es kann natürlich noch einige Minuten dauern, bis die Zonefile vom Hostsharing-Roboter abgelesen wird und der Inhalt in die BIND-Konfiguration übernommen.&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;nochg&amp;amp;nbsp;&amp;amp;lt;IP&amp;amp;nbsp;number&amp;amp;gt;&amp;lt;/tt&amp;gt; ||&lt;br /&gt;
Der gewünschte DNS-Eintrag war bereits vorhanden. &lt;br /&gt;
|| Der Server selbst macht keine DNS-Abfrage, um das zu vermitteln: die &amp;amp;bdquo;no change&amp;amp;ldquo;-Antwort besagt nur, daß eine Anfrage für diesen Eintrag bereits mit Erfolg quittiert wurde.&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;notfqdn&amp;lt;/tt&amp;gt; ||&lt;br /&gt;
Fehlschlag: der gewünschte Domainname ist nicht gültig, oder es wurde keiner angegeben.&lt;br /&gt;
|| ...&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;nohost&amp;lt;/tt&amp;gt; ||&lt;br /&gt;
Fehlschlag: der gewünschte Domainname ist gehört nicht zu denen, die für diesen Benutzer des DDNS-Dienstes konfiguriert sind.&lt;br /&gt;
|| Siehe den Abschnitt &#039;&#039;&#039;Administration&#039;&#039;&#039; weiter unten.&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;abuse&amp;lt;/tt&amp;gt; ||&lt;br /&gt;
Fehlschlag: der gewünschte Domainname ist wegen vorangeganger Fehlschläge oder überflüssiger Aufrufe gesperrt.&lt;br /&gt;
|| Siehe den Abschnitt &#039;&#039;&#039;Sukzessive Kommunikationsvorgänge&#039;&#039;&#039; unten.&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;911&amp;lt;/tt&amp;gt; ||&lt;br /&gt;
Fehlschlag: Das Server-Programm hat einen internen Fehler festgestellt.&lt;br /&gt;
|| Das Problem liegt nicht in der Anfrage an sich.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Man kann sich durchaus eine sinnreichere Kommunikation zwischen Client und Server vorstellen, doch das hier beschriebene Protokoll ist eben von DynDNS.org verwendet worden und wird in gängigen Routern implementiert, also wird es in der vorliegenden DDNS-Implementierung nachgebildet.&lt;br /&gt;
&lt;br /&gt;
=== Sukzessive Kommunikationsabläufe ===&lt;br /&gt;
Der Server muß sich zwischen einzelnen Aufrufen einiges merken, um Ressourcen zu schonen und um zu verhindern, daß einmal vergebene DDNS-Einträge von neuen Anfragen, die dieselbe übergeordnete Domain betreffen, durch Überschreiben  verlorengehen.&lt;br /&gt;
&lt;br /&gt;
==== Mißbrauch und Benutzersperrung ====&lt;br /&gt;
Zur Schonung von Ressourcen muß sich die Implementierung weigern, sich mit zuvielen fehlerhaften oder auch nur überflüssigen Anfragen zu beschäftigen. Dazu führt eine Strichliste über solche Anfragen jedes Clients und sperrt nach einer bestimmten Anzahl solcher Anfragen den Benutzernamen oder einzelne Domainnamen gegen die weitere Nutzung des Dienstes.&lt;br /&gt;
&lt;br /&gt;
Mißbrauchspunkte gegen einen einzelnen Domainnamen gibt es für:&lt;br /&gt;
* eine Anfrage, die keinen neuen DNS-Eintrag (und keine Änderung oder Löschung eines Eintrags) erfordert, sondern bestehende Merkmale nur wiederholt&lt;br /&gt;
&lt;br /&gt;
Mißbrauchspunkte gegen einen Benutzernamen gibt es für:&lt;br /&gt;
* die Angabe eines Domainnamens, der in der Dienstkonfiguration dem anfragenden Benutzernamen nicht zugeordnet ist&lt;br /&gt;
* die Angabe eines Domainnamen in einer Domain, die nicht demselben Hostsharing-Domain-Admin gehört, der den DDNS-Dienst anbietet&lt;br /&gt;
* die Angabe eines Domainnamens, der in der Dienstkonfiguration bereits wegen mißbräuchlicher Anfragen gesperrt ist (siehe oben)&lt;br /&gt;
&lt;br /&gt;
Um eine Sperrung aufzuheben, wird in der Regel eine Handlung durch den Administrator erforderlich sein.&lt;br /&gt;
&lt;br /&gt;
==== Mehrere dynamische Subdomains in derselben Domain ====&lt;br /&gt;
Sobald zwei verschiedene DDNS-Einträge in derselben Domain verlangt werden &amp;amp;ndash; beispielsweise home.example.com und office.example.com &amp;amp;ndash; wird es notwendig, bei jeder neuen Zonefile für example.com eventuell frühere Einträge zu konservieren. Der Rechner zu Hause weiß beim Bestellen seines DDNS-Eintrags nichts vom Rechner im Büro und umgekehrt. Der Server muß in irgendeiner Form über bereits vergebene Einträge Buch führen und bei einer neuen Anfrage, die example.com betrifft, alle bereits aktiven DDNS-Einträge für example.com mit in die neue Zonefile aufnehmen &amp;amp;ndash auch wenn sie auf Anfragen verschiedener Benutzer zurückgehen.&lt;br /&gt;
&lt;br /&gt;
==== Datenbank ====&lt;br /&gt;
In der Beispielimplementierung werden diese Informationen in einer SQLite-Datenbank gespeichert.&lt;br /&gt;
&lt;br /&gt;
== Sicherheit ==&lt;br /&gt;
=== Rechte ===&lt;br /&gt;
Die &#039;&#039;&#039;Benutzerrechte&#039;&#039;&#039; werden durch das Hostsharing-System kontrolliert. Sowohl das CGI-Programm als auch das [[#Administration|Administrationswerkzeug]] werden mit den Rechten des Domain-Admins (xyz00-benutzername in unserem Beispiel) ausgeführt, also kann dieses Programm nur die Domains bearbeiten, die von xyz00-benutzername verwaltet werden.&lt;br /&gt;
&lt;br /&gt;
=== Authentifizierung ===&lt;br /&gt;
In der Beispielimplementierung (wie auch seinerzeit bei DynDNS.org) wird das CGI-Programm durch einen .htaccess-Eintrag geschützt, der HTTP-Basic-Authentication vorschreibt. Also wird das Programm eigentlich mit einem URL der form&lt;br /&gt;
&lt;br /&gt;
  &amp;lt;nowiki&amp;gt;https://ddnsaccount:passwort@ddns.example.com/cgi-bin/ddns?hostname=...&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
aufgerufen.&lt;br /&gt;
&lt;br /&gt;
=== Verschlüsselung ===&lt;br /&gt;
Das CGI-Programm sollte nur in example.com/cgi-ssl/ installiert werden, nicht in example.com/cgi/. Damit ist die Kommunikation zwischen Client und Server durch SSL verschlüsselt.&lt;br /&gt;
&lt;br /&gt;
== Administration ==&lt;br /&gt;
&lt;br /&gt;
Der Verwalter des DDNS-Programms trägt berechtigte Benutzer und die ihnen zugeteilten Domainnamen in die Datenbank des Programms ein mit Hilfe eines kleinen Hilfsprogramms. Das ist im vorliegenden Fall ein menügesteuertes Programm für die Befehlszeile, daß die naheliegenden Funktionen anbietet: Account hinzufügen, löschen, sperren, entsperren, Paßwort setzen, ändern; Domainnamen hinzufügen, ändern, entsperren, löschen; Accounts und Domainnamen mit aktuellem Status auflisten. Die Funktionen sind auch über Befehlszeilenargumente verfügbar, also skriptfähig.&lt;br /&gt;
&lt;br /&gt;
Eine Auflistung des momentanen Inhalts der DDNS-Datenbank durch das Administrationswerkzeug könnte beispielsweise so aussehen:&lt;br /&gt;
&lt;br /&gt;
  xyz00-benutzername@h02:~$ bin/ddnsadmin.pl -Aa&lt;br /&gt;
  1.  papst	Mißbrauch: 0; gesperrt: nein&lt;br /&gt;
  	avignon.example.com&lt;br /&gt;
  		zuletzt aktiv am Sun Apr 26 22:24:49 2020&lt;br /&gt;
  		mit IP-Nr. 87.65.43.21; MX: 0;  Backup-MX: nein;&lt;br /&gt;
  		Subdomains: nein; Mißbrauch: 0;  gesperrt: nein&lt;br /&gt;
  	vatican.beispiel.de&lt;br /&gt;
  		zuletzt aktiv am Sun Apr 26 22:24:49 2020&lt;br /&gt;
  		mit IP-Nr. 87.65.43.21; MX: 0;  Backup-MX: nein;&lt;br /&gt;
  		Subdomains: nein; Mißbrauch: 0;  gesperrt: nein&lt;br /&gt;
  2.  kaiser	Mißbrauch: 4; gesperrt: ja&lt;br /&gt;
  	augsburg.beispiel.de&lt;br /&gt;
  		zuletzt aktiv am Sun Apr 27 10:13:49 2020&lt;br /&gt;
  		mit IP-Nr. 64.82.31.75; MX: 0;  Backup-MX: nein;&lt;br /&gt;
  		Subdomains: nein; Mißbrauch: 0;  gesperrt: ja&lt;br /&gt;
  3.  luther	Mißbrauch: 1; gesperrt: nein&lt;br /&gt;
  	wittenberg.example.com&lt;br /&gt;
  		zuletzt aktiv am Sun Apr 26 18:12:49 2020&lt;br /&gt;
  		mit IP-Nr. 78.56.34.12; MX: 0;  Backup-MX: nein;&lt;br /&gt;
  		Subdomains: nein; Mißbrauch: 1;  gesperrt: nein&lt;br /&gt;
  xyz00-benutzername@h02:~$&lt;br /&gt;
&lt;br /&gt;
Das DDNS-Account &amp;amp;bdquo;kaiser&amp;amp;ldquo; in dieser Auflistung ist wohl auf Grund fehlerhafter Anfragen automatisch gesperrt worden. Der Inhaber wird sich wohl bald melden, um nach Korrektur seiner Client-Konfiguration die Aufhebung der Sperre zu wünschen.&lt;br /&gt;
&lt;br /&gt;
=== Log ===&lt;br /&gt;
Alle Anfragen werden in einer täglich wechselnden Log-Datei protokolliert, entweder schlicht oder ausführlich, je nachdem, ob eine Variable &amp;lt;tt&amp;gt;verbose&amp;lt;/tt&amp;gt; wahr ist.&lt;br /&gt;
Ein ausführlicher Log-Eintrag sieht so aus:&lt;br /&gt;
&lt;br /&gt;
  Sun Apr 26 20:21:45 2020  ddns aufgerufen von papst&lt;br /&gt;
  			unter 84.185.97.8&lt;br /&gt;
  	URL: &amp;lt;nowiki&amp;gt;https://ddns.example.com/cgi-bin/ddns.cgi?hostname=&lt;br /&gt;
  			avignon.example.com,vatican.beispiel.de&amp;amp;&lt;br /&gt;
  			myip=84.185.97.8&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
  	Verwende IP 84.185.97.8 (= 1421435144)&lt;br /&gt;
  	DB-Version: 1&lt;br /&gt;
  	Skript und DB exklusiv geöffnet&lt;br /&gt;
  	avignon.example.com: IP: 84.185.97.8; MX: 0; Backup-MX: nein;&lt;br /&gt;
  			Wildcard: nein; Mißbrauch: 0; gesperrt: nein &lt;br /&gt;
  	vatican.beispiel.de: IP: 84.185.97.8; MX: 0; Backup-MX: nein;&lt;br /&gt;
  			Wildcard: nein; Mißbrauch: 0; gesperrt: nein &lt;br /&gt;
  	Betroffene Zonen: example.com, beispiel.de&lt;br /&gt;
  	Temporärdatei example.com_hxNa.new geschrieben&lt;br /&gt;
  	Zonendatei /home/pacs/xyz00/users/benutzername/doms/example.com/&lt;br /&gt;
  			etc/pri.example.com eingestellt&lt;br /&gt;
  	Temporärdatei beispiel.de_6HcO.new geschrieben&lt;br /&gt;
  	Zonendatei /home/pacs/xyz00/users/benutzername/doms/beispiel.de/&lt;br /&gt;
  			etc/pri.beispiel.de eingestellt&lt;br /&gt;
  	Abgeschlossen: 	Fertig&lt;br /&gt;
&lt;br /&gt;
Wenn &amp;lt;tt&amp;gt;verbose&amp;lt;/tt&amp;gt; auf falsch gesetzt ist, sind die Log-Einträge einzeilig.&lt;/div&gt;</summary>
		<author><name>Apc00-tony</name></author>
	</entry>
	<entry>
		<id>https://wiki.hostsharing.net/index.php?title=Benutzer:Apc00-tony/Dynamisches_DNS&amp;diff=5191</id>
		<title>Benutzer:Apc00-tony/Dynamisches DNS</title>
		<link rel="alternate" type="text/html" href="https://wiki.hostsharing.net/index.php?title=Benutzer:Apc00-tony/Dynamisches_DNS&amp;diff=5191"/>
		<updated>2020-04-27T08:25:33Z</updated>

		<summary type="html">&lt;p&gt;Apc00-tony: /* Authentifizierung */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;((Provisorischer Vorspann: Auf Grund einer Mailing-Listen-Diskussion habe ich angefangen, Dynamisches DNS über einen CGI-Skript bei Hostsharing zu realisieren. Meine Lösung habe ich dann vorgestellt; sie wurde für nicht ausreichend selbsterklärend befunden und fand wenig Akzeptanz. Hier also der Versuch, die Sache zu dokumentieren.))&lt;br /&gt;
&lt;br /&gt;
Mit der regelmäßigen Aufnahme von benutzerspezifischen Zonefiles in seiner DNS-Konfiguration bietet  Hostsharing alles, was man braucht, um &amp;amp;bdquo;dynamisches DNS&amp;amp;ldquo; in Eigenregie zu realisieren.&lt;br /&gt;
&lt;br /&gt;
Das heißt, wenn ich mindestens eine Domain bei Hostsharing verwalte, und mindestens eine Einwahlverbindung (oder DSL-Verbindung) ins Internet mit wechselnder IP-Adresse über irgendeinen ISP für meinen Arbeitsplatzrechner zu Hause betreibe, dann kann ich dem Arbeitsplatzrechner über die DNS-Server von Hostsharing einen vollqualifizieren Domainnamen zuweisen, der der jeweiligen IP-Adresse meiner Einwahlleitung zugeordnet ist.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
(ASCII-Art-Diagramm der beschriebenen Konstellation)&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Im Folgenden wird eine real existierende Implementierung von Dynamischem DNS (&amp;amp;bdquo;DDNS&amp;amp;ldquo;) beschrieben. Die verschiedenen Elemente könnten durchaus anders realisiert werden; die beschriebene Implementierung könnte durchaus verbessert werden. Sie dient hier der Illustration.&lt;br /&gt;
&lt;br /&gt;
In der folgenden Beschreibung werden diese Beispielwerte benutzt:&lt;br /&gt;
* Ein Hostsharing-Mitglied hat ein Account als Paket-Admin mit Kennung xyz00.&lt;br /&gt;
* Im Paket xyz00 gibt es einen Domain-Admin namens xyz00-benutzername.&lt;br /&gt;
* Dieser Domain-Admin verwaltet bei Hostsharing die Domains example.com und beispiel.de.&lt;br /&gt;
* Ein Benutzer hat zu Hause (oder im Büro) einen Arbeitsplatzrechner hinter der marktüblichen DSL-Leitung, die von seinem ISP bereitgestellt wird.&lt;br /&gt;
* Dieser Arbeitsplatzrechner (oder der Router, der seine Internetverbindung steuert) bekommt vom ISP immer wechselnde IP-Adressen zugewiesen.&lt;br /&gt;
* Dennoch möchte der Benutzer seinen Arbeitsplatzrechner aus dem Internet unter dem Hostnamen einwahl.example.com ansprechen können.&lt;br /&gt;
&lt;br /&gt;
Dazu kann ein System wie Hostsharing, das authoritative DNS-Informationen für viele Domains bereitstellt, auch veränderliche DNS-Information über dynamisch verbundene Rechner verwalten &amp;amp;ndash; sofern das ressourcenschonend gemacht werden kann ohne andere Funktionen zu stören.&lt;br /&gt;
&lt;br /&gt;
== Aufgaben des Servers ==&lt;br /&gt;
&lt;br /&gt;
Um einem Rechner mit wechselnder IP-Adresse einen DDNS-Eintrag zu bieten, muß der Hostsharing-Server folgendes leisten (in ungefährer Reihenfolge der Ereignisse):&lt;br /&gt;
&lt;br /&gt;
# Eine Anfrage entgegennehmen, beispielsweise über HTTPS, von einem entfernten Rechner, der einen DNS-Eintrag für seine momentane IP-Adresse wünscht. &lt;br /&gt;
# Prüfen, ob die Anfrage einen berechtigten DDNS-Dienst-Usernamen mit zugehörigem Paßwort enthält.&lt;br /&gt;
# Prüfen, ob die Anfrage einen gültigen Domainnamen betrifft, den der Server bieten darf.&lt;br /&gt;
# Prüfen, ob die Domain example.com demselben Benutzer gehört, unter dessen Namen der Dynamisches-DNS-Server läuft.&lt;br /&gt;
# Eine gültige [[Zonefile]] mit &amp;amp;ndash; neben dem bisherigen Inhalt &amp;amp;ndash; einem A-Eintrag für einwahl.example.com in /home/pacs/xyz00/users/benutzername/doms/example.com/pri.example.com schreiben.&lt;br /&gt;
# Dem Client eine Bestätigung oder ggf. eine Fehlermeldung als Antwort senden.&lt;br /&gt;
# In irgendeiner Datenbank den momentan eingestellter Status all seiner DDNS-Einträge speichern.&lt;br /&gt;
# In einer Logdatei protokollieren, daß obiges getan wurde, oder ggf. welche Fehler traten auf.&lt;br /&gt;
&lt;br /&gt;
== Aufgaben des Clients ==&lt;br /&gt;
Bevor ich anfange, meinen Arbeitsplatzrechner so zu konfigurieren, daß er bei welchem Server auch immer einen DDNS-Eintrag anfordert, muß ich mich als verantwortlicher Benutzer dieses Rechners und der dazugehörigen Internetverbindung &amp;amp;ndash; das heißt, als Mensch &amp;amp;ndash; mit dem Betreiber des dynamisches-DNS-Servers vereinbaren, daß ich das darf und welchen Eintrag ich bekommen kann. Im Folgenden wird vorausgesetzt, daß solche Vereinbarungen getroffen und die Parameter geklärt wurden.&lt;br /&gt;
&lt;br /&gt;
Der DDNS-Client muß aus Server-Sicht nur wenig leisten:&lt;br /&gt;
&lt;br /&gt;
# Eine Anfrage senden, beispielsweise über HTTPS, an einen entfernten Rechner, der einen Eintrag ins DNS für die momentane IP-Adresse des Clients vornehmen kann.&amp;lt;br /&amp;gt;Diese Anfrage muß einem festgelegten Format entsprechen und muß gültige Werte für die Authorisation des Clients, den gewünschten Domainnamen, und eventuell andere Parameter enthalten.&lt;br /&gt;
# Eine Antwort des Servers entgegennehmen und als Erfolgs- oder Fehlermeldung auswerten.&lt;br /&gt;
# Von überflüssigen Anfragen absehen: das heißt bei Erfolg, nicht wiederholt den gleichen Eintrag erneut wünschen; bei Fehlern, nicht die gleiche fehlerhafte Anfrage erneut schicken.&lt;br /&gt;
&lt;br /&gt;
== Kommunikation zwischen Client und Server ==&lt;br /&gt;
&lt;br /&gt;
Ein einziges Nachrichtenpaar von Anfrage und Antwort genügt, um einen DDNS-Eintrag einzurichten: Der Client teilt die IP-Adresse und den Domainnamen mit, die in einem DNS-Eintrag verbunden werden sollen; der Server bestätigt den Auftrag.&lt;br /&gt;
&lt;br /&gt;
In der Beispielimplementierung erfolgt die Kommunikation über HTTP, und die Anfrage des Clients könnte so aussehen:&lt;br /&gt;
&lt;br /&gt;
  GET /cgi-bin/ddns?hostname=einwahl.example.com&amp;amp;myip=87.65.43.21 HTTP/1.1&lt;br /&gt;
  Host: ddns.beispiel.de&lt;br /&gt;
  User-Agent: Fritz!Box DDNS/1.0.1&lt;br /&gt;
  Authorization: Basic QWxhZGRpbjpvcGVuIHNlc2FtZQ==&lt;br /&gt;
&lt;br /&gt;
Bei Erhalt dieser Anfrage ruft Apache das CGI-Programm .../doms/ddns.beispiel.de/cgi-ssl/ddns auf. Das Fragezeichen trennt den Programmnamen von einem &amp;quot;Query-String&amp;quot;, in dem zwei Metavariablen definiert und übergeben werden. Die erste Metavariable, hostname, hat den Wert &amp;quot;einwahl.example.com&amp;quot;; die zweite, myip, hat den Wert &amp;quot;87.65.43.21&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
Das Server-Programm, hier &#039;&#039;ddns&#039;&#039;, prüft diese Informationen auf Form und Berechtigung, und schreibt gegebenenfalls einen entsprechenden Eintrag in einer Zonefile. Es schreibt auch verschiedene Informationen in die Standardausgabe. Wenn es die Standardausgabe geschlossen wird &amp;amp;ndash; also spätestens bei Programmende &amp;amp;ndash; schickt Apache diese Informationen als Antwort an den anfragenden Rechner zurück.&lt;br /&gt;
&lt;br /&gt;
Im Falle unserer Beispielimplementierung sieht die Antwort bei Erfolg so aus: &lt;br /&gt;
&lt;br /&gt;
  HTTP/1.1 200 OK&lt;br /&gt;
  Date: Wed, 22 Apr 2020 08:35:15 GMT&lt;br /&gt;
  Server: Apache&lt;br /&gt;
  Content-Length: 17&lt;br /&gt;
  Content-Type: text/plain; charset=ISO-8859-1&lt;br /&gt;
 &lt;br /&gt;
  good 87.65.43.21&lt;br /&gt;
&lt;br /&gt;
=== Das DDNS-Protokoll von DynDNS.org ===&lt;br /&gt;
&lt;br /&gt;
In den 90er Jahren, bevor das Internet so durchgehend vergeschäftlicht wurde, boten einige Organisationen kostenlose DDNS-Dienste an. Ein sehr beliebtes Angebot war das von DynDNS.org. Das DDNS-Protokoll von diesem Dienst wurde sogar in Einwahl-Routern einprogrammiert und der Dienst wurde von ISPs und Router-Herstellern als Leistungsmerkmal beworben.&lt;br /&gt;
&lt;br /&gt;
DynDNS.org gehört inzwischen Oracle und bietet keine kostenlose Dienste mehr. Dennoch wird das DDNS-Protokoll von DynDNS.org in der vorliegenden Beispielimplementierung übernommen in der Hoffnung, daß die Kompatibilität mit einigen gängigen Einwahl-Routern von Vorteil sein kann. Es gibt noch eine kurze Online-Dokumentation der [https://help.dyn.com/remote-access-api/perform-update/ Anfrage] und [https://help.dyn.com/remote-access-api/perform-update/ Antwortnachrichten].&lt;br /&gt;
&lt;br /&gt;
Das gesammte Protokoll sieht einen einzigen Nachrichtenaustausch aus Anfrage und Antwort vor. Die Anfrage kann mehrere Argumente enthalten; die Antwort kann verschiedene Code-Wörtern enthalten. Übrigens können in einer einzigen Anfrage mehrere DNS-Einträge gewünscht werden. In diesem Fall kann die Antwort mehrzeilig ausfallen.&lt;br /&gt;
&lt;br /&gt;
Das Verhalten von Server und Client bei künftigen Kommunikationsvorgängen wird unter Umständen von vorangegangenen Kommunikationsergebnissen beeinflußt: nach wiederholten fehlerhaften oder redundanten Anfragen kann der Server weitere Anfragen des Benutzers verweigern; nach wiederholten Fehlermeldungen sollte ein Client aufhören, immer dieselbe Anfrage zu schicken. Und für den Fall, daß mehrere Clients dynamische DNS-Einträge in derselben Domain example.com bestellen, muß der Server den Stand aller Client-Einträge intern speichern, damit er nicht mit einer neuen Zonefile einen früher erstellten Eintrag löscht. Zu diesen Fragen siehe den Abschnitt &#039;&#039;&#039;[[#Sukzessive_Kommunikationsabläufe]]&#039;&#039;&#039; nach der Beschreibung von Anfragen und Antworten unten.&lt;br /&gt;
&lt;br /&gt;
====Anfrage====&lt;br /&gt;
&lt;br /&gt;
Die Anfrage in Form eines URL übergibt dem DDNS-Programm in einem &#039;Query-String&#039; einige Metavariablen. Das heißt, in einem URL der Form&lt;br /&gt;
&lt;br /&gt;
  &amp;lt;nowiki&amp;gt;https://benutzername:passwort@ddns.beisiel.de/cgi-bin/ddns?hostname=einwahl.example.com&amp;amp;myip=87.65.43.21&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
signalisert das Fragezeichen, daß ein Query-String folgt. In einem solchen Query-String können in der Beispielimplementierung folgende Metavariablen definiert werden:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|- class=&amp;quot;hintergrundfarbe5&amp;quot;&lt;br /&gt;
! Variable !! Beispiel !! Bemerkungen&lt;br /&gt;
|-&lt;br /&gt;
| hostname || &amp;lt;tt&amp;gt;hostname=einwahl.example.com&amp;lt;/tt&amp;gt;&amp;lt;br /&amp;gt;&amp;lt;div style=&amp;quot;font-size:smaller;&amp;quot;&amp;gt;&amp;lt;tt&amp;gt;hostname=eins.example.com,zwei.example.com[,...]&amp;lt;/tt&amp;gt;&amp;lt;/div&amp;gt; ||&lt;br /&gt;
Muß ein vollständig qualifizierter Domain-Name (&amp;quot;FQDN&amp;quot;) sein; &amp;lt;tt&amp;gt;example.com&amp;lt;/tt&amp;gt; muß eine vom Besitzer des DDNS-Programms verwaltete Domain sein. Genaugenommen kann der Wert eine durch Kommata gegliederte Liste mehrerer gültiger Domainnamen sein, falls mehrere Einträge mit derselben IP-Adresse gewünscht werden.&lt;br /&gt;
|-&lt;br /&gt;
| myip || &amp;lt;tt&amp;gt;myip=87.65.43.21&amp;lt;/tt&amp;gt;||&lt;br /&gt;
Kann entfallen; kann vom Server ignoriert werden. Maßgeblich ist dann die IP-Adresse des Absenders, wie sie vom Web-Server mitgeteilt wird.&lt;br /&gt;
|-&lt;br /&gt;
| mx || &amp;lt;tt&amp;gt;mx=87.65.43.21&amp;lt;/tt&amp;gt;&amp;lt;br /&amp;gt;&amp;lt;tt&amp;gt;mx=NOCHG&amp;lt;/tt&amp;gt;&amp;lt;br /&amp;gt; ||&lt;br /&gt;
Neben dem A-Eintrag möchte der Client auch einen MX-Eintrag. Der Wert &amp;lt;tt&amp;gt;NOCHG&amp;lt;/tt&amp;gt; (für &amp;amp;bdquo;no change&amp;amp;ldquo;) bedeutet, der bestehende MX-Eintrag (oder seine Abwesenheit) soll nicht geändert werden. &lt;br /&gt;
|-&lt;br /&gt;
| backmx || &amp;lt;tt&amp;gt;backmx=YES&amp;lt;/tt&amp;gt;&amp;lt;br /&amp;gt;&amp;lt;tt&amp;gt;backmx=NOCHG&amp;lt;/tt&amp;gt;&amp;lt;br /&amp;gt;&amp;lt;tt&amp;gt;backmx=NO&amp;lt;/tt&amp;gt;   ||&lt;br /&gt;
Falls &amp;lt;tt&amp;gt;YES&amp;lt;/tt&amp;gt;, wird ein zweiter MX-Eintrag erzeugt, der &amp;lt;tt&amp;gt;einwahl.example.com&amp;lt;/tt&amp;gt; als Mail-Server für &amp;lt;tt&amp;gt;einwahl.example.com&amp;lt;/tt&amp;gt; nennt. Dieser Eintrag hat eine niedrigere Präferenzzahl (also eine höhere Priorität) als der mit &amp;lt;tt&amp;gt;mx&amp;lt;/tt&amp;gt; angeforderten Eintrag.&lt;br /&gt;
|-&lt;br /&gt;
| wildcard || &amp;lt;tt&amp;gt;wildcard=ON&amp;lt;/tt&amp;gt;&amp;lt;br /&amp;gt;&amp;lt;tt&amp;gt;wildcard=NOCHG&amp;lt;/tt&amp;gt;&amp;lt;br /&amp;gt;&amp;lt;tt&amp;gt;wildcard=OFF&amp;lt;/tt&amp;gt; ||&lt;br /&gt;
Neben dem A-Eintrag für den Domainnamen &amp;lt;tt&amp;gt;einwahl.example.com&amp;lt;/tt&amp;gt; wünscht der Client auch einen Eintrag für beliebige Subdomains, also &amp;lt;tt&amp;gt;*.einwahl.example.com&amp;lt;/tt&amp;gt;, mit der gleichen IP-Adresse.&lt;br /&gt;
|-&lt;br /&gt;
| offline ||&amp;lt;tt&amp;gt;offline=YES&amp;lt;/tt&amp;gt;&amp;lt;br /&amp;gt;&amp;lt;tt&amp;gt;offline=NOCHG&amp;lt;/tt&amp;gt;||&lt;br /&gt;
Falls &amp;lt;tt&amp;gt;YES&amp;lt;/tt&amp;gt;, wird ein DNS-Eintrag für &amp;lt;tt&amp;gt;einwahl.example.com&amp;lt;/tt&amp;gt; aus der Zonefile getilgt. Gegebenenfalls wird der Hostname dann auf Grund eines parallelen Wildcard-Eintrags für &amp;lt;tt&amp;gt;*.example.com&amp;lt;/tt&amp;gt; einer anderen IP-Adresse zugeordnet werden.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;!-- IPv6? --&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Alle Parameter bis auf hostname können entfallen. Bei nichtdokumentierten Argumenten ist das Verhalten undefiniert&amp;amp;trade;.&lt;br /&gt;
&lt;br /&gt;
====Antwort====&lt;br /&gt;
&lt;br /&gt;
Die Antwort auf eine erfolgreiche HTTP-Anfrage besteht im häufigsten Fall aus einigen Header-Zeilen, gefolgt vom Inhalt der gewünschten Text- oder andere Datei. Ein Status-Code in der ersten Header-Zeile gibt an, ob die Anfrage bedient werden kann oder kreist andernfalls den Grund für die Enttäuschung ein.&lt;br /&gt;
&lt;br /&gt;
Die vorliegende Beispielimplementierung von DDNS schickt einen der üblichen HTTP-Status-Codes &amp;quot;200 OK&amp;quot; oder &amp;quot;500 Internal Server Error&amp;quot;, gefolgt von einer kurzen Textnachricht nach dem HTTP-Header. Bei diesem Programm  ist &amp;amp;ndash; laut Gebrauchshinweise von DynDNS.org &amp;amp;ndash; &#039;&#039;nicht&#039;&#039; der Status-Code im Header, sondern der Inhalt der Nachricht  die definierte, maßgebliche Ergebnismeldung des Programms.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|- class=&amp;quot;hintergrundfarbe5&amp;quot;&lt;br /&gt;
! Meldung !! Bedeutung !! Bemerkungen&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;good&amp;amp;nbsp;&amp;amp;lt;IP&amp;amp;nbsp;number&amp;amp;gt;&amp;lt;/tt&amp;gt; ||&lt;br /&gt;
Der gewünschte DNS-Eintrag wurde erfolgreich in einer Zonefile eingetragen. &lt;br /&gt;
|| Es kann natürlich noch einige Minuten dauern, bis die Zonefile vom Hostsharing-Roboter abgelesen wird und der Inhalt in die BIND-Konfiguration übernommen.&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;nochg&amp;amp;nbsp;&amp;amp;lt;IP&amp;amp;nbsp;number&amp;amp;gt;&amp;lt;/tt&amp;gt; ||&lt;br /&gt;
Der gewünschte DNS-Eintrag war bereits vorhanden. &lt;br /&gt;
|| Der Server selbst macht keine DNS-Abfrage, um das zu vermitteln: die &amp;amp;bdquo;no change&amp;amp;ldquo;-Antwort besagt nur, daß eine Anfrage für diesen Eintrag bereits mit Erfolg quittiert wurde.&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;notfqdn&amp;lt;/tt&amp;gt; ||&lt;br /&gt;
Fehlschlag: der gewünschte Domainname ist nicht gültig, oder es wurde keiner angegeben.&lt;br /&gt;
|| ...&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;nohost&amp;lt;/tt&amp;gt; ||&lt;br /&gt;
Fehlschlag: der gewünschte Domainname ist gehört nicht zu denen, die für diesen Benutzer des DDNS-Dienstes konfiguriert sind.&lt;br /&gt;
|| Siehe den Abschnitt &#039;&#039;&#039;Administration&#039;&#039;&#039; weiter unten.&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;abuse&amp;lt;/tt&amp;gt; ||&lt;br /&gt;
Fehlschlag: der gewünschte Domainname ist wegen vorangeganger Fehlschläge oder überflüssiger Aufrufe gesperrt.&lt;br /&gt;
|| Siehe den Abschnitt &#039;&#039;&#039;Sukzessive Kommunikationsvorgänge&#039;&#039;&#039; unten.&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;911&amp;lt;/tt&amp;gt; ||&lt;br /&gt;
Fehlschlag: Das Server-Programm hat einen internen Fehler festgestellt.&lt;br /&gt;
|| Das Problem liegt nicht in der Anfrage an sich.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Man kann sich durchaus eine sinnreichere Kommunikation zwischen Client und Server vorstellen, doch das hier beschriebene Protokoll ist eben von DynDNS.org verwendet worden und wird in gängigen Routern implementiert, also wird es in der vorliegenden DDNS-Implementierung nachgebildet.&lt;br /&gt;
&lt;br /&gt;
=== Sukzessive Kommunikationsabläufe ===&lt;br /&gt;
Der Server muß sich zwischen einzelnen Aufrufen einiges merken, um Ressourcen zu schonen und um zu verhindern, daß einmal vergebene DDNS-Einträge von neuen Anfragen, die dieselbe übergeordnete Domain betreffen, durch Überschreiben  verlorengehen.&lt;br /&gt;
&lt;br /&gt;
==== Mißbrauch und Benutzersperrung ====&lt;br /&gt;
Zur Schonung von Ressourcen muß sich die Implementierung weigern, sich mit zuvielen fehlerhaften oder auch nur überflüssigen Anfragen zu beschäftigen. Dazu führt eine Strichliste über solche Anfragen jedes Clients und sperrt nach einer bestimmten Anzahl solcher Anfragen den Benutzernamen oder einzelne Domainnamen gegen die weitere Nutzung des Dienstes.&lt;br /&gt;
&lt;br /&gt;
Mißbrauchspunkte gegen einen einzelnen Domainnamen gibt es für:&lt;br /&gt;
* eine Anfrage, die keinen neuen DNS-Eintrag (und keine Änderung oder Löschung eines Eintrags) erfordert, sondern bestehende Merkmale nur wiederholt&lt;br /&gt;
&lt;br /&gt;
Mißbrauchspunkte gegen einen Benutzernamen gibt es für:&lt;br /&gt;
* die Angabe eines Domainnamens, der in der Dienstkonfiguration dem anfragenden Benutzernamen nicht zugeordnet ist&lt;br /&gt;
* die Angabe eines Domainnamen in einer Domain, die nicht demselben Hostsharing-Domain-Admin gehört, der den DDNS-Dienst anbietet&lt;br /&gt;
* die Angabe eines Domainnamens, der in der Dienstkonfiguration bereits wegen mißbräuchlicher Anfragen gesperrt ist (siehe oben)&lt;br /&gt;
&lt;br /&gt;
Um eine Sperrung aufzuheben, wird in der Regel eine Handlung durch den Administrator erforderlich sein.&lt;br /&gt;
&lt;br /&gt;
==== Mehrere dynamische Subdomains in derselben Domain ====&lt;br /&gt;
Sobald zwei verschiedene DDNS-Einträge in derselben Domain verlangt werden &amp;amp;ndash; beispielsweise home.example.com und office.example.com &amp;amp;ndash; wird es notwendig, bei jeder neuen Zonefile für example.com eventuell frühere Einträge zu konservieren. Der Rechner zu Hause weiß beim Bestellen seines DDNS-Eintrags nichts vom Rechner im Büro und umgekehrt. Der Server muß in irgendeiner Form über bereits vergebene Einträge Buch führen und bei einer neuen Anfrage, die example.com betrifft, alle bereits aktiven DDNS-Einträge für example.com mit in die neue Zonefile aufnehmen &amp;amp;ndash auch wenn sie auf Anfragen verschiedener Benutzer zurückgehen.&lt;br /&gt;
&lt;br /&gt;
==== Datenbank ====&lt;br /&gt;
In der Beispielimplementierung werden diese Informationen in einer SQLite-Datenbank gespeichert.&lt;br /&gt;
&lt;br /&gt;
== Sicherheit ==&lt;br /&gt;
=== Rechte ===&lt;br /&gt;
Die &#039;&#039;&#039;Benutzerrechte&#039;&#039;&#039; werden durch das Hostsharing-System kontrolliert. Sowohl das CGI-Programm als auch das [[#Administration|Administrationswerkzeug]] werden mit den Rechten des Domain-Admins (xyz00-benutzername in unserem Beispiel) ausgeführt, also kann dieses Programm nur die Domains bearbeiten, die von xyz00-benutzername verwaltet werden.&lt;br /&gt;
&lt;br /&gt;
=== Authentifizierung ===&lt;br /&gt;
In der Beispielimplementierung (wie auch seinerzeit bei DynDNS.org) wird das CGI-Programm durch einen .htaccess-Eintrag geschützt, der HTTP-Basic-Authentication vorschreibt. Also wird das Programm eigentlich mit einem URL der form&lt;br /&gt;
&lt;br /&gt;
  &amp;lt;nowiki&amp;gt;https://ddnsaccount:passwort@ddns.example.com/cgi-bin/ddns?hostname=...&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
aufgerufen.&lt;br /&gt;
&lt;br /&gt;
=== Verschlüsselung ===&lt;br /&gt;
Das CGI-Programm sollte nur in example.com/cgi-ssl/ installiert werden, nicht in example.com/cgi/. Damit ist die Kommunikation zwischen Client und Server durch SSL verschlüsselt.&lt;br /&gt;
&lt;br /&gt;
== Administration ==&lt;br /&gt;
&lt;br /&gt;
Der Verwalter des DDNS-Programms trägt berechtigte Benutzer und die ihnen zugeteilten Domainnamen in die Datenbank des Programms ein mit Hilfe eines kleinen Hilfsprogramms. Das ist im vorliegenden Fall ein menügesteuertes Programm für die Befehlszeile, daß die naheliegenden Funktionen anbietet: Account hinzufügen, löschen, sperren, entsperren, Paßwort setzen, ändern; Domainnamen hinzufügen, ändern, entsperren, löschen; Accounts und Domainnamen mit aktuellem Status auflisten. Die Funktionen sind auch über Befehlszeilenargumente verfügbar, also skriptfähig.&lt;br /&gt;
&lt;br /&gt;
=== Log ===&lt;br /&gt;
Alle Anfragen werden in einer täglich wechselnden Log-Datei protokolliert, entweder schlicht oder ausführlich, je nachdem, ob eine Variable &amp;lt;tt&amp;gt;verbose&amp;lt;/tt&amp;gt; wahr ist.&lt;br /&gt;
Ein ausführlicher Log-Eintrag sieht so aus:&lt;br /&gt;
&lt;br /&gt;
  Sun Apr 26 20:21:45 2020  ddns aufgerufen von papst&lt;br /&gt;
  			unter 84.185.97.8&lt;br /&gt;
  	URL: &amp;lt;nowiki&amp;gt;https://ddns.example.com/cgi-bin/ddns.cgi?hostname=&lt;br /&gt;
  			avignon.example.com,vatican.beispiel.de&amp;amp;&lt;br /&gt;
  			myip=84.185.97.8&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
  	Verwende IP 84.185.97.8 (= 1421435144)&lt;br /&gt;
  	DB-Version: 1&lt;br /&gt;
  	Skript und DB exklusiv geöffnet&lt;br /&gt;
  	avignon.example.com: IP 84.185.97.8; MX 0; Backup-MX 0;&lt;br /&gt;
  			Wildcard 0; Mißbrauch 0; gesperrt 0 &lt;br /&gt;
  	vatican.beispiel.de: IP 84.185.97.8; MX 0; Backup-MX 0;&lt;br /&gt;
  			Wildcard 0; Mißbrauch 0; gesperrt 0 &lt;br /&gt;
  	Betroffene Zonen: example.com, beispiel.de&lt;br /&gt;
  	Temporärdatei example.com_hxNa.new geschrieben&lt;br /&gt;
  	Zonendatei /home/pacs/xyz00/users/benutzername/doms/example.com/&lt;br /&gt;
  			etc/pri.example.com eingestellt&lt;br /&gt;
  	Temporärdatei beispiel.de_6HcO.new geschrieben&lt;br /&gt;
  	Zonendatei /home/pacs/xyz00/users/benutzername/doms/beispiel.de/&lt;br /&gt;
  			etc/pri.beispiel.de eingestellt&lt;br /&gt;
  	Abgeschlossen: 	Fertig&lt;br /&gt;
&lt;br /&gt;
ölkölkj&lt;/div&gt;</summary>
		<author><name>Apc00-tony</name></author>
	</entry>
</feed>