Der INN im Überblick: Konzepte, Funktionsweise, Konfigurationsdateien und Logfiles

Es gibt zum INN inzwischen ein gutes Howto zur Einrichtung und Erstkonfiguration, darüber hinaus Dokumentation zu den einzelnen Programmen, Scripts und Konfigurationsdateien sowie FAQs zu wesentlichen Abläufen. Was meines Erachtens noch fehlt, ist ein Überblick zum hinter dem INN stehenden Konzept und den Abläufen, also dem Zusammengreifen der einzelnen teile. Einen solchen möchte ich hier - aus meiner immer noch einigermaßen laienhaften Sicht - zu geben versuchen. Für Korrekturen und Ergänzungen habe ich daher ein offenes Ohr.

Ich gehe bei meinen Ausführungen von einem INN neueren Datums (2.3.x oder neuer) aus, der in /usr/local/news installiert wurde; bei einer Installation als Paket, bspw. aus der Debian-Distribution, liegen verschiedene Dateien ggf. woanders, worauf dann jeweils hingewiesen wird. Im Zweifelsfall ist der Abschnitt Paths aus der inn.conf der richtige Ort, um festzustellen, wo in der eigenen Installation welche Dateien zu vermuten sind. Ich erlaube mir im übrigen, bei wiederholten Erwähnungen bestimmter Dateien und Kommandos ggf. den Pfad wegzulassen.

In diesem Test soll es im übrigen keine konkreten Konfigurationsvorschläge geben; auch erläutere ich das Format der Konfigurationsdateien oder die Funktionsweise und Parameter der einzelnen Programme nicht in Einzelheiten. Die entsprechenden Informationen lassen sich der vorhandenen, durchaus brauchbaren Dokumentation, namentlich den man-pages, entnehmen. Die Schwierigkeit liegt am Anfang vielmehr darin, das richtige Programm bzw. die richtige Konfigurationsdatei (und damit auch die zugehörige man-page) erst einmal zu finden. Dabei soll dieser Überblick helfen.

Verschiedene Links zu Tutorials, Dokumentation und Software finden Sie auf meiner INN-Seite.

Konzepte

Zunächst möchte ich einige grundlegende Konzepte des INN vorstellen.

Daemons, Programme, Scripts

Der INN besteht aus zwei Kernprozessen: einmal dem innd, der für eingehende Feeder-Verbindungen, also einliefernde Server, zuständig ist; zum anderen den nnrpd, der für die Behandlung von Reader-Prozessen, also Newsreadern / Clients, zuständig ist. Auf Port 119 lauscht der innd; wenn sich ein Newsreader verbindet, d.h. entweder eine Verbindung von einer IP kommt, die nicht als Feeder - in der incoming.conf - bekannt ist oder wenn in einer solchen Verbindung das Kommando MODE READER erfolgt, wird für jede dieser Newsreader-Verbindungen ein neuer nnrpd-Prozess gestartet.

Daneben laufen noch andere, sekundäre Prozesse wie innwatch zur Überwachung der Funktion oder innfeed zum Feeden von Postings an andere Server; außerdem gibt es eine Vielzahl von Programmen und Scripts, die bei Bedarf gestartet werden.

History und artcutoff

INN muss sicherstellen können, dass er keine Postings entgegennimmt, die er schon hat, denn anderenfalls würde er sie doppelt speichern und ggf. auch erneut an seine Peeringpartner weitergeben. Dazu prüft er ggf. zunächst, ob sein eigener Servername schon im Path:-Header steht; im Wesentlichen macht er das aber an der Message-ID fest, die für jedes Posting einmalig sein muss.

Jedes ihm angebotene Posting notiert INN in der History (~/db/history bzw. /var/lib/news/history): er hält dort jeweils pro Posting in einer Zeile den Hashwert der Message-ID (früher einmal tatsächlich die Message-ID), das Datum des Postings als Unix-Timestamp (Sekunden seit dem 01.01.1970 - durch eine Tilde getrennt das tatsächliche Eintreffen, ggf. den Inhalt des Expires:-Headers und den Inhalt des Date:-Headers) und - falls das Posting noch vorhanden ist - das

Storage-Token fest, mit dem der Storage-Manager sm es aus dem Artikelspeicher (Spool) abrufen kann. Postings, deren Message-ID schon in der History vorhanden sind, nimmt der INN nicht mehr entgegen, weder von anderen Servern noch von Newsreadern. Der entsprechende Eintrag verbleibt in der History so lange, wie auch das entsprechende Posting noch verfügbar ist; über die History lassen sich also Postings anhand ihrer Message-ID finden, sie stellt (neben ihrer Funktion zur Verhinderung von Duplikaten) eine Verknüpfung zwischen Message-ID und Storage-Token her.

Wie lange Einträge in der History noch erhalten bleiben, nachdem das entsprechende Posting nicht mehr verfügbar ist, regelt der Eintrag für remember in ~/etc/expire.ctl bzw. /etc/news/expire.ctl. Ältere Postings dürfen keinesfalls entgegengenommen werden, weil sonst die Gefahr besteht, dass ihre Message-ID aus der History schon herausgefallen ist, obwohl das Posting bereits einmal dem Server angeboten wurde. Daher kennt INN den Parameter artcutoff in der ~/etc/inn.conf bzw. /etc/news/inn.conf, der angibt, wie alt Postings höchstens sein dürfen. Dieser Wert darf nicht höher sein als der Eintrag für remember in der expire.ctl; er kann auch via ~/bin/ctlinnd mode bzw. /usr/lib/news/bin/ctlinnd mode abgefragt werden (Parameter c) und entsprechend über ctlinnd param c XX temporär geändert werden, wenn bspw. ältere Postings bewusst eingespeist werden sollen.

Storage-Methoden

Ein Newsserver muss Postings nicht nur annehmen, weitergeben und auf Anfrage wieder herausrücken, er muss sie vor allem auch speichern, und zwar auf eine solche Weise, dass er sie einerseits schnell speichern und andererseits effizient wiederfinden und herausgeben kann.

Bei älteren INN-Versionen hat man dazu einfach die vorhandene Gliederungsstruktur der Newsgroup-Namen im Dateisystem nachgebildet: in dem entsprechenden Verzeichnis, dem Newsspool, wurde für jede Top-Level-Hierarchie (TLH) ein Unterverzeichnis angelegt, unterhalb dieses Verzeichnisses für jede Second-Level-Hierarchie wieder eines, usw., bis man schließlich zu einem Verzeichnis kam, das einer Newsgroup entspricht. In diesem waren dann die einzelnen Postings gespeichert, wobei der Dateiname zugleich die interne Nummer des Postings in der jeweiligen Gruppe darstellte. Das Posting mit der laufenden Nummer 3745 in de.admin.news.groups wäre also - ausgehend vom Newsspool-Verzeichnis, bspw. /var/spool/news - in einer Datei mit dem Namen .../de/admin/news/groups/3745 gespeichert worden. Crossposts wurden durch symbolische Links auf Dateiebene wiedergegeben; im active (~/db/active bzw. /var/lib/news/active) fand man dann die niedrigste und höchste vorhandene laufende Nummer der jeweiligen Gruppe angegeben, und über die History wurde der Zusammenhang zwischen der Message-ID und dem Speicherort hergestellt. Beim Expire - oder auch bei einem Cancel - wurden schließlich einfach die entsprechenden Dateien gelöscht und (ggf. erst später, je nach Wert für remember in der expire.ctl) die Einträge aus der History entfernt. Ein Lesezugriff anhand der laufenden Nummer konnte schnell durch die Umsetzung in einen Dateinamen geschehen, bei einem Zugriff über die Message-ID bedurfte es einer Umsetzung anhand der History. Gleichermaßen einfach war es, Postings weiterzubearbeiten; notfalls konnte man einfach die Datei im Spool modifizieren. Newsreader, die auf derselben Maschine wie der Server betrieben wurden, konnten direkt lesend auf den Spool zugreifen, ohne dass sie NNRP beherrschen mussten.

Diese einfache Art der Speicherung, der sog. traditional spool, hatte aber auch ihre Nachteile; namentlich konnte es zu einer Überfüllung der Platte kommen, wenn mehr Postings eingingen als erwartet oder zu wenig Postings expired wurden, wenn also der Traffic überraschend anstieg. Außerdem ist das Verfahren zwar einfach im Zugriff, aber alles andere als schnell beim Schreiben und führt folglich bei dem heutigen Postingaufkommen gerade in Binärgruppen leicht zu einer Überlastung des Systems durch die notwendigen Schreibzugriffe auf die Platte. Daher bieten neuere INN-Versionen (2.3.x und neuer) weitere Speichermethoden an und regeln den Zugriff auf den Spool einheitlich durch eine sog. Storage-API, deren storage manager sm als Eingabe ein sog. "Token" erwartet und als Ausgabe dann das dazugehörige Posting liefert, egal wo und auf welche Weise dieses Posting gespeichert wurde.

Der traditional spool lebt in der Storage-Methode tradspool weiter; diese unterscheidet sich nur insofern vom traditional spool, als der Zugriff auch hier über den storage manager erfolgt. Ansonsten weist sie die Vor- und Nachteile des traditional spool auf, also namentlich Einfachheit (leichteres "Reinschauen", einfaches Backup, …) und Kompatibilität zu älterer Software, die mit sm nicht umgehen kann, aber schlechtere Performance und die Notwendigkeit eines angepassten Expires.

Neu ist das Cyclic News File System (CNFS). Bei dieser Storage-Methode werden sog. Buffer angelegt, in die die Postings der Eingangsreihenfolge nach hineingeschrieben werden. Ist das Ende des Buffers erreicht, wird an den Anfang zurückgesprungen; die ältesten Postings werden durch die neueintreffenden überschrieben. Das geht sehr fix und führt zu einem automatischen, aber zeitlich nicht genau festgelegten Expire - ein Posting ist genau dann expired, wenn eben der Buffer voll ist und es überschrieben wird. Andererseits ist ein direkter Lesezugriff auf einen Buffer nicht sinnvoll möglich, der Zugriff über den storage manager also zwingend.

Daneben gibt es noch die seltener benutzten Methoden timehash und timecaf, bei denen Postings wiederum in der Art des traditional spool als einzelne Dateien geschrieben werden, aber nicht nach Newsgroups, sondern nach Eingansgzeit geordnet (timehash), bzw. nach Eingangszeit geordnet in Sammeldateien geschrieben werden (timecaf).

Es ist möglich, verschiedene Storage-Methoden nebeneinander zu verwenden, bspw. große und unvorhersehbar wachsende Hierarchien und Binaries in - verschieden großen - CNFS-Buffern abzulegen, kleine und lokale Hierarchien aber als tradspool. Die Entscheidung, wo ein Posting gespeichert werden soll, kann anhand der Newsgroups, in die es gepostet wurde, der Größe oder auch des Expire-Zeitraumes erfolgen.

Overview-Arten

Es genügt nicht, auf Postings unter Angabe ihrer Message-ID oder innerhalb einer Newsgroup nach ihrer laufenden Nummer zugreifen zu können. Vielmehr bedarf es einer Möglichkeit, sich einen Überblick über den Inhalt einer Newsgroup zu verschaffen, ohne dazu jedes einzelne Posting (oder auch nur dessen komplette Header) herunterzuladen und auszuwerten. Alles andere würde zum einen eine unnötige Belastung des Servers bedeuten, der jedes einzelne Posting hervorkramen müsste, als auch unnötig Daten übertragen, die zunächst gar nicht benötigt werden.

Daher hält der INN spezielle Überblicksdaten vor, die dementsprechend als Overview bezeichnet werden. Für jedes Posting werden die Inhalte der Header "Subject", "From", "Date", "Message-ID" und "References" vorgehalten, zudem die Größe des Artikels in Byte und in Zeilen, und in der Regel auch die laufende Nummer innerhalb der Gruppe(n), in denen der Artikel vorgehalten wird (als XRef-Header). Der genaue Inhalt des Overviews ergibt sich aus der Konfigurationsdatei ~/etc/overview.fmt bzw. /etc/news/overview.fmt. Newsreader können die Overview-Daten mithilfe des XOVER-Kommandos abrufen. Dies ermöglicht ihnen die Anwendung üblicher Filter nach Betreff, Autor, Alter und Größe des Postings, den Aufbau eines Threads anhand der References, und nachfolgend den Abruf des kompletten Postings entweder mittels Message-ID oder direkt mit der Laufnummer innerhalb einer Newsgroup.

INN bietet drei verschiedene Overview-Methoden an. tradindexed, die Speicherung in Textdateien, ist die älteste, am besten getestete und zuverlässigste Methode, die auch am einfachsten eine Wiederherstellung der Daten ermöglicht; sie ist aber auch am langsamsten. buffindexed benutzt zur Speicherung vorher erstellte Buffer wie bei CNFS, was schnelleres Schreiben ermöglicht, aber ggf. Schwierigkeiten bei einer Wiederherstellung bietet; die dritte Methode nennt sich ovdb und hält die Overview-Daten in einer BerkeleyDB-Datenbank.

Laufweg eines Postings

Wenn der INN ein neu eingehendes Posting erhält, durchläuft es zuvor erstmal einige Checks. So wird bei der Einlieferung durch einen anderen Server per NNTP (genauer: bei der Annahme von Postings direkt durch den innd) regelmäßig zunächst nur die Message-ID angeboten, damit geprüft werden kann, ob das Posting nicht schon in der History vorhanden ist und die Übertragung des kompletten Postings daher unterlassen werden kann. Danach wird in jedem Fall überprüft, ob das Posting nicht zu alt - älter als artcutoff - ist, und ob die Newsgroups, in die es gehört, überhaupt geführt werden und ob der Einlieferer in diese Gruppen schreiben darf. Im Falle der Einlieferung durch einen Newsreader (bei der Annahme durch den nnrpd) finden noch weitere formale Überprüfungen statt, die ggf. dazu führen, dass das Posting mit einem Fehlercode zurückgewiesen wird. Sollte es von einem Reader in eine moderierte Gruppe eingeliefert worden sein und nicht über den notwendigen Approved:-Header verfügen, so wird es zwar angenommen, aber direkt vom nnrpd-Prozess per E-Mail an den zuständigen Moderator der Newsgroup weitergeleitet, der anhand der ~/etc/moderators-Datei (bzw. /etc/news/moderators) bestimmt wird.

Überdies durchlaufen alle Postings noch den Filter ~/etc/filter/filter_innd.pl (bzw. /etc/news/filter/filter_innd.pl), Postings durch einen Newsreader (also via nnrpd) zusätzlich noch den Filter ~/etc/filter/filter_nnrpd.pl bzw. /etc/news/filter/filter_nnrpd.pl (und/oder deren jeweilige Äquivalente in der Programmiersprache Python), soweit INN mit Unterstützung für Perl und/oder Python installiert wurde. Diese Filter können Postings sowohl ablehnen als auch verändern.

Nach erfolgreichem Verlauf der Überprüfungen wird das (ggf. durch einen Filter modifizierte) Postings einerseits auf dem Newsserver gespeichert, wo und wie auch immer - das ist eine Frage der Datenhaltung. Zum anderen wird es sofort im selben Moment weiterverarbeitet, d.h. an andere Newsserver oder Auswertungsprogramme weitergereicht - eine Frage der konfigurierten Feeds. An welche Feeds das Posting weitergeleitet wurde ergibt sich dabei aus der Logdatei ~/log/news bzw. /var/log/news/news; dort entspricht jede Zeile einem eingehenden Posting, wobei am Anfang der Zeile vor dem einliefernden Host und der jeweiligen Message-ID ein Symbol angibt, ob das Posting angenommen wurde ("+"), abgelehnt wurde ("-") oder gecancelt wurde ("c") und am Ende der Zeile nach der Größenangabe alle Feeds aufgeführt werden, an die das Posting weitergereicht wurde.

Funktionsweise

Im folgenden gehe ich auf die Funktionsweise bei einzelnen Vorgängen, bspw. dem Annehmen oder Aussenden von Postings, ein.

Eingehende Postings

Postings können auf unterschiedlichen Wegen und auf unterschiedliche Weisen eingehen. Beispielsweise können sie über das Netz von anderen Servern per NNTP (an den innd) oder von Newsreadern (Clients) per NNRP (an einen durch den innd gestarteten nnrpd-Prozess) eingeliefert liefern, oder lokal durch den Aufruf entsprechener Programme eingespeist werden (bspw. durch rnews bei einer Einlieferung via UUCP).

NNTP

Anhand der Einträge in der ~/etc/incoming.conf bzw. /etc/news/incoming.confentscheidet der INN, welche Systeme als Peer, also als anderer Server, bei ihm einliefern dürfen. Von dort aus wird der komplette NNTP-Befehlssatz akzeptiert; auf diese Weise eingelieferte Postings werden in der Regel nicht weiter geprüft und nicht mehr um weitere Headerzeilen zur Rückverfolgung ergänzt; nur in den Path:-Header trägt sich der Server mit seinen in der ~/etc/inn.conf bzw. /etc/news/inn.conf konfigurierten Namen ein.

NNRP

Wenn eine Verbindung auf Port 119 - oder dem Port, an dem INN horcht - nicht von einem Peer, d.h. einem in der incoming.conf genannten System, stammt, oder dort das Kommando MODE READER abgesetzt wird, wird eine nnrpd-Instanz gestartet. Auf welche Newsgroups sie diesem Client dann lesenden oder schreibenden Zugriff gestattet, ist abhängig von den Einstellungen in der ~/etc/readers.conf bzw. /etc/news/readers.conf und damit eine Frage der Zugangskontrolle.

UUCP

Über UUCP eingehenden Postings werden in der Regel als komprimierter Batch angeliefert, ausgepackt und dann mittels rnews an den INN verfüttert. Eine weitere Kontrolle, in welche Newsgroups geschrieben werden kann, ist nicht möglich.

Ausgehende Postings (Feeds)

Die Steuerung der ausgehenden Feeds, also die Entscheidung darüber, welche eingehenden Postings wohin weitergegeben oder auch weiterbearbeitet werden sollen, findet in ~/etc/newsfeeds bzw. /etc/news/newsfeedsstatt. Wenn der INN ein neues Posting erhält, sei es von einem anderen Server via NNTP oder UUCP, sei es von einem Newsreader via NNRP, dann entscheidet er anhand der Einträge in newsfeeds zu diesem Zeitpunkt, wo es - neben der lokalen Speicherung, also der Ablage im Storage - noch hingeschickt werden soll. Weitergegeben werden regelmäßig also keine alten, bereits vorhandenen, sondern nur neu eingehende Postings.

Die Weitergabe ist dabei ein zweiteiliger Vorgang. In newsfeeds ist nur definiert, dass der INN für jedes eingehende Postings, das bestimmte Kriterien erfüllt, bestimmte Daten an ein anderes Programm weitergeben oder in eine Datei schreiben soll. Die eigentliche Weitergabe oder Bearbeitung erfolgt dann entweder durch das aufgerufene Programm (in Echtzeit) oder durch eine Auswertung der geschriebenen Datei (regelmäßig, bspw. durch crontab-Einträge gesteuert). Als Kriterien kommen dabei in Betracht die Newsgroups:- oder Distribution:-Header, als Daten die Message-ID oder andere Header, das Storage-Token, die Größe usw. Außerdem können noch weitere Vorgaben gemacht werden, bspw. die, das Steuernachrichten von der Weitergabe ausgeschlossen werden können. Welche Daten geschrieben werden sollen, hängt davon ab, welches Eingabeformat das weiterverarbeitende Programm erwartet.

Will man beispielsweise Steuernachrichten bearbeiten, so schickt man für jede Steuernachricht Token, sendenden Peer und die Message-ID an ~/bin/controlchan bzw. /usr/lib/news/bin/controlchan, von dem dauernd eine Instanz läuft und diese Daten verarbeitet:

# Send non-cancel control messages through controlchan.
controlchan!\
        :!*,control,control.*,!control.cancel\
        :Tc,Wnsm:/usr/lib/news/bin/controlchan

Tc sorgt dabei dafür, dass nur eine Instanz von controlchan gestartet wird, immer weiterläuft und der Reihe nach die Daten erhält; Tp würde für jede Steuernachricht jedesmal eine neue Instanz von controlchan starten.

Möchte man Postings in Echtzeit per innfeed an einen anderen Server weiterreichen, dann wirft man einem dafür eingerichteten funnel-Feed an ~/bin/innfeed bzw. /usr/lib/news/bin/innfeed (quasi ein Sammeleintrag) die Message-ID ein:

# peer.example
# News Master <newsmaster@peer.example>
peer.example/news.peer.example\
        :de.*,!de.alt.dateien.*\
        :Tm:innfeed!

Mit diesem Eintrag wird (nur) festgelegt, Postings aus welchen Newsgroups an den anderen Server weitergereicht werden sollen; dabei ist "peer.example" ein symbolischer Name, der diesen Feed kennzeichnen soll. Die übrigen Einstellungen - namentlich: welcher Server ist gemeint, wie viele Verbindungen sollen gleichzeitig geöffnet werden usw. - werden in ~/etc/innfeed.conf bzw. /etc/news/innfeed.conf getroffen, wobei der dortige Eintrag denselben symbolischen Namen ("peer.example") verwendet. Soweit für die Verbindung zu dem externen Server ausnahmsweise ein Passwort benötigt wird, findet sich der entsprechende Eintrag in der ~/etc/passwd.nntp bzw. /etc/news/passwd.nntp

Möchte man nicht in Echtzeit arbeiten, sondern erstmal die Liste der zu verarbeitenden Postings in eine Datei schreiben, die dann - beispielsweise - durch ~/bin/nntpsend (/usr/lib/news/bin/nntpsend) bzw. ~/bin/innxmit (/usr/lib/news/bin/innxmit) für NNTP oder ~/bin/sendbatch (/usr/lib/news/bin/sendbatch) für UUCP oder rpost für NNRP weiterverarbeitet werden sollen, kann man - abhängig von den Parametern, die diese Programme erwarten - einen solchen Eintrag verwenden:

## uucp.gnuu.de (sendbatch)
uucp.gnuu.de\
           :de.*\
           :Tf,Wnb,B4096/1024:

# otherpeer.example (nntpsend)
news.otherpeer.example\
           :de.*,\
           :Tf,Wnm,B4096/1024:

Auch hier wird nur eine Liste von Postings in eine Datei geschrieben. Die weiterverarbeitende Software setzt in der Regel zunächst ein ctlinnd flush $feedname ab und sorgt so dafür, dass die Daten auch in die Datei auf die Platte geschrieben werden, benennt danach die Datei um und arbeitet mit der umbenannten Datei weiter. Zu welchem Server sie wie Verbindung aufnimmt, wird im Falle von UUCP in den dortigen Konfigurationsdateien und im Falle von nntpsend in ~/etc/nntpsend.ctl (/etc/news/nntpsend.ctl) definiert. Auch hier findet sich ein eventuell benötigtes Passwort in der passwd.nntp.

Genauso wie in den vorstehenden Beispielen kann man für andere oder eigene Programme entsprechende Einträge vornehmen; entscheidend ist, dass die Daten, die der INN aufgrund des newsfeeds-Eintrages an ein anderes Programm sendet oder auf die Platte schreibt, auch die Daten sind, die das weiterverarbeitende Programm erwartet.

Natürlich lassen sich die vorhandenen Programme auch aus anderen Quellen als newsfeeds speisen. So kann man beispielsweise aus der History die Daten aller vorhandenen Postings auslesen und in eine Datei schreiben, mit der man dann innxmit füttert, um den Inhalt eines ganzen Servers an einen anderen Server zu übertragen, wie in der INN 2.x-FAQ dargestellt.

Speichern und Vorhalten der Postings (Storage)

Welche der verschiedenen Methoden, Postings auf der Platte zu speichern, für ein bestimmtes eingehendes Posting zur Anwendung kommt, d.h. wo es wie gespeichert wird, entscheidet sich in der ~/etc/storage.conf (/etc/news/storage.conf) anhand verschiedener Kategorien, bspw. Newsgroups:-Header oder Größe.

Soweit zur Speicherung CNFS-Buffer verwendet werden, werden diese in der ~/etc/cycbuff.conf (/etc/news/cycbuff.conf) definiert und zu Metabuffern zusammengefasst; diese Metabuffer werden dann wiederum in der storage.conf als Speicherort genannt. Bevor ein CNFS-Buffer verwendet werden kann, muss er erst einmal angelegt werden!

Eingehende Postings für lokal nicht geführte Gruppen werden in der Pseudogruppe junk abgelegt; gleichermaßen werden Steuernachrichten in den Pseudogruppen control.* abgelegt. "Pseudogruppen" deshalb, weil diese Postings dort unabhängig von den Angaben in ihrem Newsgroups:-Header gespeichert werden, obwohl der Newsgroups:-Header bei der Weitergabe beachtet wird.

Begrenzung der Haltezeit (Expire)

Ein Newsserver hält Postings nicht dauerhaft, sondern nur für eine bestimmte, einstellbare Haltezeit vor; danach "laufen sie ab" ("expirern") und werden aus dem Spool gelöscht; zugleich werden Verweise auf diese Postings aus der History und dem Overview entfernt. Gesteuert werden diese Vorgänge über die Angaben in der expire.ctl, ausgeführt werden sie durch die Scripts expire und expireover, die regelmäßig, in der Regel täglich durch einen Cronjob (news.daily) ausgeführt werden. Grundsätzlich ist dabei expire für das Entfernen der Postings selbst und der History-Einträge zuständig, expireover für das Entfernen der Beiträge aus dem Overview; inzwischen teilen sich die Scripts diese Funktionalität aber, wobei die genaue Aufgabenverteilung teilweise konfigurationsabhängig ist.

Entscheidend für das Verhalten von expire/expireover und für das korrekte Format von expire.ctl ist zunächst, ob der Parameter groupbaseexpiry in der inn.conf "true" oder "false" ist. In zweiter Linie spielt es eine Rolle, ob die verwendete(n) Storage- Methode(n) self-expiring sind, also alte Postings schon technisch bedingt automatisch entfernt werden (bspw. bei CNFS-Buffern, die sich immer wieder selbst überschreiben), oder nicht. Ist groupbaseexpiry gesetzt ("true"), wird die Haltezeit für einzelne Newsgroups - gruppenspezifisch - vorgegeben, ist es nicht gesetzt ("false"), wird die Haltezeit nach den in der storage.conf definierten Storage Classes bestimmt.

In jedem Fall beginnt die expire.ctl aber mit einer Zeile der Art /remember/:<days>. Dieser Parameter gibt vor, wie lange ein Posting auf jeden Fall, unabhängig von der sonstigen Konfiguration, in der History gehalten wird. Dieser Wert sollte mindestens so groß sein wie der in der inn.conf definierte artcutoff, um Duplikate zu vermeiden.

Bei "groupbaseexpiry: true" haben die folgenden Einträge dann das Format <pattern>:<flag>:<min>:<default>:<max>. pattern steht dabei für ein INN-übliches Newsgroup-Pattern (de.alt.*), flag für eine Eingrenzung der betroffenen Newsgroup nach Status (moderiert, unmoderiert, alle), die übrigen drei Werte geben die kürzeste, die übliche und die längste Haltezeit an. Ein Posting wird dabei normalerweise nach default Tagen entfernt; hat es einen "Expires:"-Header, wird es entsprechend der Datumsangabe dort entfernt, frühestens aber nach min Tagen und spätestens nach max Tagen. In der History verbleibt es überdies immer mindestens remember Tage.

Bei groupbaseexpiry: false haben die Einträge in der expire.ctl das Format <classnum>:<min>:<default>:<max>. classnum steht dabei für die in der storage.conf vergebene laufende Nummer der Storage Class (bspw. einer bestimmten Gruppe von CNFS-Buffern oder bestimmter Gruppen im tradspool). Die folgenden Angaben gelten dann wie zuvor beschrieben für diese bestimmte Storage Class.

Zu beachten ist weiterhin, dass bei groupbaseexpiry: true normalerweise bei self-expiring Storage-Methoden wie CNFS sämtliche Angaben außer remember in der expire.ctl nicht beachtet werden. expire bzw. expireover prüfen in diesem Fall nur, ob ein Posting tatsächlich noch im CNFS-Buffer vorhanden ist und entfernen die Einträge aus History und Overbiew nur, wenn das Posting nicht mehr zugreifbar ist. Die Postings selbst werden nie vor dem Ablauf ihrer "natürlichen Lebenszeit" im Buffer - der sich ja, sobald sein Ende erreicht ist, von vorne wieder überschreibt - entfernt. Anders dann, wenn groupbaseexpiry: false gesetzt ist. Dann werden, je nach Vorgaben in storage.conf und expire.ctl, auch in CNFS-Buffern Postings vorzeitig entfernt.

Auswertung und Ausführung von Steuernachrichten

Das Usenet kennt neben "normalen" Postings, die für menschliche Leser bestimmt sind, auch noch sog. Steuernachrichten (control messages), die zur automatischen Auswertung durch Newsserversoftware vorgesehen sind und daher dem menschlichen Leser üblicherweise - durch Einsortierung in die Pseudogruppen control.* - vorenthalten werden. Eine Steuernachricht zeichnet sich durch die zusätzliche Headerzeile "Control:" aus, in der dann die Art der Steuernachricht und die notwendigen Parameter enthalten sind. Gebräuchliche Steuernachrichten sind solche zum Löschen von Beiträgen (cancel) sowie zur Änderung des Newsgroups-Bestands (newgroup zur Neuanlage einer Newsgroup, rmgroup zu deren Entfernung und checkgroups zur Überprüfung des Newsgroups- Bestands); alle anderen Arten von Steuernachrichten sind nicht mehr praxisrelevant. Cancel- Steuernachrichten werden aufgrund ihrer Häufigkeit von INN direkt intern ausgewertet; die übrigen müssen an controlchan gefeedet und dort verarbeitet werden. Controlchan greift zur tatsächlichen Ausführung der Steuernachrichten dann auf die in ~/bin/control/ (/usr/lib/news/bin/control/) gespeicherten Scripts zurück; für jede Steuernachricht, die ausgeführt werden soll, ist dort ein entsprechend benanntes Script vorhanden. So wird zur Abarbeitung einer newgroup-Steuernachricht das Script ~/bin/control/newgroup.pl (/usr/lib/news/bin/control/newgroup.pl) ausgeführt.

In der Konfigurationsdatei control.ctl ist festgelegt, welche Steuernachrichten von welchem Absender unter welchen Umständen wie ausgeführt werden sollen. Für jede einzelne Newsgroups-Hierarchie oder - Teilhierarchie (im Extremfall für jede einzelne Newsgroup) kann für jede Art von Steuernachricht und für jeden (angeblichen) Absender einer solchen definiert werden, ob die entsprechende Steuernachricht verworfen, in das Error-Logfile (~/log/errlog bzw. /var/log/news/errlog)geschrieben, an den Administrator des Newsservers gemailt und (generell oder nur nach positiver Überprüfung einer digitalen Sigantur) ausgeführt werden soll. Dabei können alle Aktionen außer "verwerfen" und "mailen" noch zusätzlich in ein Logfile geschrieben werden. Treffen mehrere Einträge auf eine bestimmte Steuernachricht zu, so wird der letzte Eintrag berücksichtigt, der auf sie passt; auf diese Weise lassen sich Standardwerte vorgeben und dann immer weiter verfeinern.

Jede Zeile dort hat folgenden Aufbau:

##  Format:
##     <message>:<from>:<newsgroups>:<action>

Dabei steht message für die Art der Steuernachricht (newgroup, rmgroup, checkgroups usw.) oder all für alle Arten von Steuernachrichten, from steht für den (angeblichen) Absender der Steuernachricht, newsgroups für die Newsgroup, die mit der Steuernachricht angelegt oder gelöscht werden soll (soweit zutreffend) und action für die Aktion, die ausgeführt werden soll. from und newsgroups können in Form eines INN-üblichen Patterns (bspw. de.alt.* oder *@news.example.org) angegeben werden, für action sind die Werte doit ("ausführen"), drop ("verwerfen"), log ("Eintrag im Error-Log schreiben"), mail ("E-Mail an Administrator") oder

verify-USERID" ("nur bei erfolgreicher Prüfung der digitalen Signatur ausführen") zulässig, wobei im letzten Fall für USERID die User-ID des PGP- oder GPG- Schlüssels, mit dem die Signatur geprüft werden soll, einzusetzen ist. Selbstverständlich muss dieser Schlüssel sich im passenden Keyring befinden. Die Werte log, doit und verify-USERID können zudem noch um die Angabe eines Logfiles oder das Schlüsselwort mail ergänzt werden (=mail oder =LOGFILENAME).

Ein beispielhafter Eintrag könnte dann so aussehen:

## DE (German language)
# Contact: moderator@dana.de
# URL: http://www.dana.de/mod/
# Admin group: de.admin.news.announce
# Key URL: http://www.dana.de/mod/pgp/dana.asc
# Key fingerprint = 5B B0 52 88 BF 55 19 4F  66 7D C2 AE 16 26 28 25
# *PGP*   See comment at top of file.
newgroup:*:de.*:drop
rmgroup:*:de.*:drop
checkgroups:moderator@dana.de:de.*:verify-de.admin.news.announce
newgroup:moderator@dana.de:de.*:verify-de.admin.news.announce
rmgroup:moderator@dana.de:de.*:verify-de.admin.news.announce

## DE.ALT (German language alternative hierarchy)
# *PGP*   See comment at top of file.
newgroup:*:de.alt.*:mail
rmgroup:*:de.alt.*:mail
rmgroup:moderator@dana.de:de.alt.*:verify-de.admin.news.announce

Hier werden zunächst grundsätzlich alle newgroup- und rmgroup-Nachrichten für die Hierarchie "de.*" verworfen, gleichviel, von welchem Absender sie stammen. Sie werden aber - ebenso wie checkgroups- Nachrichten (für die am Anfang des control.ctl als Standard "E-Mail an den Administrator" festgelegt ist, so dass hier keine besondere Regelung getroffen werden muss) - stattdessen (nur dann) ausgeführt, wenn sie als Absender "moderator@dana.de" angeben und mit dem Schlüssel mit der User-ID "de.admin.news.announce" (der sich im entsprechenden Keyring, standardmäßig in ~/etc/pgp/ respektive /etc/news/pgp/ abgelegt, befinden muss) digital signiert sind. Für "de.alt.*" gilt wiederum eine Sonderregel: hier werden alle newgroup-und rmgroup-Nachrichten an den Administrator gemailt; nur rmgroup-Nachrichten werden stattdessen ausgeführt, wenn sie (angeblich) von "moderator@dana.de" stammen und mit dem vorgenannten Schlüssel digital signiert sind.

Ein aktuelles control.ctl wird mit INN ausgeliefert und kann jederzeit auch vom FTP-Server des ISC heruntergeladen werden.

Zugangskontrolle für Newsreader

Über die readers.conf kann der Zugriff von Newsreadern auf den INN - genauer: einen nnrpd-Prozess - geregelt werden; der Zugriff von Peers, gleichberechtigten Newsservern (der immer nur schreibend sein kann), wird hingegen über die incoming.conf geregelt.

Die Überprüfung der Zugriffsberechtigung innerhalb der readers.conf erfolgt zweistufig: zunächst wird der Nutzer anhand nahezu beliebiger Kriterien (Hostname oder IP-Adresse oder Ergebnisse externer Programme, die bspw. Benutzerkennung und Passwort (auf beliebige Weise) überprüfen) in eine Nutzergruppe (auth group)eingeordnet, und danach werden dieser Nutzergruppe bestimmte Rechte - namentlich Lesen von und Schreiben in bestimmte Newsgroups - zugewiesen (access group). Dabei kann ein nnrpd-Prozess auch als virtual host auftreten und sich in Message-ID:, Path: etc. mit einem anderen Hostnamen verewigen.

In Verbindung mit eingebundenen Perl- oder Python-Programmen lassen sich nahezu beliebig flexibel Nutzergruppen mit beliebigen Rechten oder beliebige Server-Identitäten erzeugen.

Filtern eingehender Postings

INN bietet die Möglichkeit zur Definition umfangreicher Filter, getrennt für lokal (via nnrpd) eingespeiste Artikel und solche, die mit anderen Newsservern ausgetauscht werden. Diese Filter sind als Scripts in den Sprachen Perl oder Python - früher auch noch TCL - implementiert und ermöglichen den Zugriff auf eine Vielzahl von Informationen über das jeweilige Posting, das sie durchläuft, wie bspw. alle Header und auch den Body. Außerdem stehen alle Möglichkeiten der betreffenden Scriptsprache zur Verfügung, so dass der Phantasie des jeweiligen Newsserverbetreibers grundsätzlich keine Grenzen gesetzt sind. Jeder Filter gibt am Ende an INN zurück, ob das Posting angenommen oder abgelehnt werden soll, wobei im letzten Fall auch die Fehlermeldung für den Newsreader und das Logfile definiert werden kann. Überdies kann der Filter ein angenommenes Posting verändern, bspw. Headerzeilen löschen, hinzufügen oder durch andere Inhalte ersetzen.

Die Filter befinden sich üblicherweise im Verzeichnis ~/etc/filter/ (bzw. /etc/news/filter/) und heißen filter_innd.pl (Perl) bzw. filter_innd.py (Python) für den globalen Filter und filter_nnrpd.pl (Perl) bzw. filter_nnrpd.py (Python) für den auf lokal via nnrpd eingespeiste Postings beschränkten Filter. Nach Veränderungen werden die neuen Filter im Falle von filter_nnrpd.* automatisch beim nächsten Eingang eines Postings via nnrpd und im Falle von filter_innd.* nach einem expliziten Reload vermittels ctlinnd reload filter.perl TEXT (bzw. ctlinnd reload filter.python TEXT für den Python-Filter) berücksichtigt. Vorher sollte unbedingt die Fehlerfreiheit der entsprechenden Scripts überprüft werden, bspw., indem man sie zumindest einmal von der Shell aus ausführt!

Gebräuchlich ist bspw. die Einbindung von cleanfeed, einem Filter gegen Spam und anderen Netzmissbrauch, als filter_innd.pl.

Konfigurationsdateien

Die Konfigurationsdateien finden sich in ~/etc (bzw. /etc/news/).

inn.conf
Zentrale Serverkonfiguration.

Eingehende Feeds, Readerzugriff

incoming.conf
Konfiguration der eingehenden NNTP-Feeds.
readers.conf
Konfiguration der NNRP-Client-Rechte.
radius.conf
Konfiguration des RADIUS-Servers, falls ein solcher in der readers.conf verwendet wird.
sasl.conf
SSL/TLS-Konfiguration für den Readerzugriff.

Ausgehende Feeds, moderierte Gruppen, Steuernachrichten

newsfeeds
Konfiguration, welche Newsgroups an welche ausgehenden Feeds (und weitere Programme, einschließlich der internen Verarbeitung von Steuernachrichten u.ä.) zu liefern sind. Hier wird festgelegt, was mit Postings noch - außer der lokalen Speicherung - geschehen soll.
innfeed.conf
Konfiguration der via innfeed ausgehenden NNTP-Feeds.
nntpsend.ctl
Konfiguration der via nntpsend ausgehenden Feeds.
passwd.nntp
Konfiguration der Passworte für Zugriff externe Server.
moderators
Konfiguration der Moderator-Adressen, an die nicht-approvete Postings in moderierten Gruppen gemailt werden sollen.
control.ctl
Verarbeitung eingehender Steuernachrichten (mit Ausnahme von Canceln), insbesondere Ausführung von newgroups, rmgroups, checkgroups und Kontrolle derer digitaler Signaturen.

Storage und Expire

storage.conf
Konfiguration der Storage-Methoden: welche Postings werden wo auf welche Weise lokal gespeichert?
cycbuff.conf
Definition der CNFS-Buffer und -Metabuffer.
expire.ctl
Festlegung der Haltezeit für Postings.

Overview

overview.fmt
Format der gespeicherten Overview-Daten. Sollte regelmäßig nicht verändert werden!
buffindexed.conf
Konfiguration für die buffindexed-Overview-Methoe.
ovdb.conf
Konfiguration für die ovdb-Overview-Datenbank.

Optionale Programme

innwatch.ctl
Konfiguration von innwatch: Welche Reaktionen sollen bei welchen Feststellungen erfolgen?
innreport.conf
innreport kann Statistiken und graphische Auswertungen über den Betrieb des Newsservers erzeugen, die auch als Webseiten bereitgestellt werden können.
actsync.conf, actsync.ign
actsync kann die eigene active-Datei mit der eines anderen Servers (Referenzservers) vergleichen und das eigene active an den Referenzserver angleichen.
news2mail.cf
News2Mail-Gateway mit news2mail: Zieladressen für die Mailinglisten.

Sonstiges

subscriptions
Liste der Newsgroups, die einem Newsreader auf das Kommando LIST SUBSCRIPTIONS geliefert werden sollen. Der Newsreader kann diese Gruppen dann ggf. initial automatisch abonnieren.
motd.news
Informationen, die einem Newsreader auf das Kommando LIST MOTD geliefert werden sollen. Die Datei darf fehlen.
distrib.pats
Zuordnung eines Distribution:-Headers anhand des Newsgroups:- Headers. Wird regelmäßig nicht benötigt.
nnrpd.track
Festlegung, von welchem Hosts bei aktiviertem readertrack in der inn.conf Trackingdaten gesammelt werden sollen.

Log-Dateien

Die Logdateien finden sich in ~/log (oder in /var/log/news, je nach Konfiguration).

news
In diesem Log wird jedes vom Server erhaltene - nicht direkt als Duplikat oder anderweitig zurückgewiesene - Posting aufgeführt, mit einer Kennung, ob es angenommen oder abgelehnt (oder gecancelt) wurde (+ / - / c), dem einliefernden Feed, der Message-ID, der Größe und allen ausgehenden Feeds, an die es weitergereicht wurde.
news.notice, news.err, news.crit
In diesen Logdateien werden alle übrigen Logeinträge seitens des INN-Paketes gespeichert, die via syslog mit dem entsprechenden Loglevel eingehen. news.err enthält dabei Fehlermeldungen, news.crit kritische Fehler.
errlog
Hier landen alle Fehlermeldungen, die der innd- Prozess direkt generiert und auf STDERR ausgibt.
unwanted.log
Hier werden die lokal nicht vorhandenen Newsgroups genannt, für die dennoch Postings eingehen, die dann in junk gespeichert werden, zusammen mit der Anzahl der jeweils eingegangenen Postings.
expire.log
Das Ergebnis des Expire-Laufs.
expire.list, expire.lastlowmark
Hilfsdateien für Expire.

Es können sich Logfiles weiterer Programme aus dem INN-Paket in diesem Verzeichnis befinden, wie zum Beispiel:

innfeed.log
Ausgaben von innfeed.
innfeed.status
Aktueller Status von innfeed.
nntpsend.log
Ausgaben von nntpsend / innxmit.

Alte Logfiles werden in der Regel durch news.daily komprimiert und ins Verzeichnis ~/log/OLD/ (bzw. /var/log/news/OLD/) verschoben.

Ergänzende Links habe ich zentral auf meiner INN-Seite gesammelt.

Lizenz

Creative Commons-Lizenzvertrag Dieser Inhalt ist unter der Creative Commons-Lizenz BY-NC-SA 3.0 DE lizenziert; er darf unter Namensnennung des Autors nicht-kommerziell weitergegeben und auch bearbeitet werden, soweit das neue Werk gleichfalls wieder dieser Creative-Commons-Lizenz unterliegt. Die Einzelheiten ergeben sich aus dem Lizenzvertrag.