Aus Linux-Magazin 10/2008

Konfigurationsverwaltung mit Cfengine2

Konfigurationsmanagement fängt bei jedem einzelnen Client an. Dort sind lokale Eigenheiten zu beachten, Bedingungen zu formulieren und dynamisch anzupassen. Der Altmeister der Zunft bringt eine Sprache mit, die intuitiv ist – das Linux-Magazin untersucht, ob sie heutigen Ansprüchen genügt.

Als Write-only-Software gelten Admin-Skripte, die Perl oder »sed« ausführen. Zu dieser Erkenntnis kam bereits 1993 die Universität Oslo [1] und entwickelte daraufhin Cfengine, den Ahnvater aller freien Konfigurationswerkzeuge [2]. Noch heute arbeitet eine aktive Entwicklergemeinde daran, das Tool weiterzuentwickeln. Cfengine setzt Richtlinien automatisch um, die sich auf Funktionsgruppen, zum Beispiel Mail- oder Webserver, Hardware oder auf das Betriebssystem beziehen. Neben den gängigen Linux- und Unix-Varianten unterstützt Cfengine nämlich auch Windows.

Das Tool unterscheidet sich von anderen Lösungen für das Konfigurationsmanagement durch seinen pragmatischen Ansatz. Die Syntax der Konfigurationssprache gilt als gut lesbar (andere Tools benutzen XML), die Konzepte als verständlich. Das Werkzeug richtet Systeme nicht nur initial ein, sondern kümmert sich bei Abweichungen auch darum, den Status quo wieder herzustellen. Wartungsarbeiten startet es über einen Scheduler, der Cron ähnelt, aber Rücksicht auf den aktuellen Zustand des Systems nimmt, beispielsweise hohe Last oder niedriges Mailaufkommen.

Installation und Setup

Aktuell ist die Version 2.2.7, in vielen Paket-Repositories der Distributionen findet sich noch die Release 2.2.3, mit der sich ebenfalls arbeiten lässt. Unter Debian und Derivaten erledigt das übliche

aptitude install cfengine2 cfengine2-doc

die Installation samt ausführlicher Dokumentation und einigen Konfigurationsbeispielen, die sich als Grundlage für eigene Anpassungen eignen. Cfengine operiert nach dem Client-Server-Prinzip, wobei ein Admin den Client auch autark betreiben kann. Bei größeren Installationen bietet es sich zwangsläufig an, die Master-Konfiguration auf einem Server vorzuhalten und dann auf die verwalteten Clients zu verteilen. Dazu erzeugt die Installtionsroutine ein RSA-Schlüsselpaar, das die Kommunikation absichert. Hat eine verwundbare Version von OpenSSL die Schlüssel erzeugt [3], sorgt

rm /var/lib/cfengine2/ppkeys/localhost*
/usr/sbin/cfkey

wieder für Sicherheit. Cfengine setzt sich aus den vier Programmen »cfagent«, »cfexecd«, »cfservd« und »cfenvd« sowie einigen Hilfswerkzeugen zusammen, die gemeinsam die Infrastruktur der Gruppenrichtlinien bilden (siehe Tabelle 1). Die eigentliche Arbeit übernimmt der »cfagent«, der die stets lokal vorgehaltene Policy interpretiert, überprüft und gegebenenfalls nötige Änderungen vornimmt. Wer nicht gleich die vollständige Infrastruktur aufsetzen möchte, kann auch einzelne Cfengine-Skripte schreiben und mit »cfagent« lokal ausführen.

Die Master-Konfiguration »/etc/cfengine/cfagent.conf« ist in Blöcke unterteilt, die jeweils eine Aufgabe – Action im Sprachgebrauch von Cfengine – übernimmt. Jede Aufgabe enthält Bedingungen, die das Werkzeug zu erfüllen versucht. Sind einige von ihnen nicht erfüllt, entwickelt es Aktivitäten, um den Zustand herbeizuführen. So passt es etwa eine Datei mit falschen Leserechten an.

Jedes Cfengine-Skript enthält einen »control«-Block, der in die modular aufgeteilten Blöcke verzweigt und damit die Ausführung steuert (siehe Listing 1). Zeile 1 leitet den »control«-Block ein, der allgemeine Konfigurationseinstellungen, etwa den DNS-Namen der Domain festlegt, aber auch eigene Variablen zu definieren erlaubt. Das Schlüsselwort »actionsequence« in Zeile 5 legt fest, welche Aufgaben der Agent in welcher Reihenfolge bearbeitet. Der durch die Anweisung konfigurierte Block »files« beginnt ab Zeile 7. Er überprüft, ob die angegebenen Dateien mit den angegeben Rechten auf dem System vorliegen, und korrigiert diese bei Abweichungen durch die Zuweisung »action=fixall«. Die Action »shellcommands« in Zeile 11 führt dort verzeichnete Shellbefehle bei jedem Durchlauf aus.

Listing 1: Schlichte
»cfagent.conf«

01 control:
02   domain      = ( linux-magazin.com )
03   access      = ( root )
04   tier        = ( Fisch )
05   actionsequence = ( files shellcommands )
06 
07 files:
08   /etc/passwd mode=644 owner=root group=root action=fixall
09   /etc/shadow mode=600 owner=root group=root action=fixall
10 
11 shellcommands:
12   suse|64_bit::
13     echo "Mach's gut und danke für den $(tier)"
14   Friday.Day13::
15     echo "Vorsicht! Heute ist Freitag, der 13."

Einfach Klasse

Sollen durch »shellcommands« definierte Befehle von Bedingungen abhängen, etwa dem Betriebssystem, der Plattform oder schlicht dem Wochentag, verwendet der Admin so genannte Klassen. Sie lassen sich an der Doppelpunkt-Notation erkennen. Eine Klassendefinition ist innerhalb eines Abschnitts so lange gültig, bis eine weitere Definition erfolgt. Fehlt die Angabe einer Klasse, tritt automatisch die für alle Systeme gültige Klasse »any::« in Kraft.

Führt Cfengine das Skript unter Suse oder einem 64-Bit-System aus (Zeile 12), gibt es sich literarisch. An einem Freitag dem 13. gibt das Tool die nötige Warnung aus (Zeilen 14 und 15). Einige Klassen bringt Cfengine bereits mit und nennt sie Hardcoded Classes. Der Admin kann Klassen auch zur Laufzeit definieren oder zuvor anhand bestimmter Voraussetzungen, etwa dem Verwendungszweck des Servers, festlegen. Welche Bedingungen greifen und welche Kommandos ausgeführt würden, verrät der Aufruf von:

cfagent --verbose --dry-run

Diese Trockenübung verändert nichts am System. Entspricht das der Erwartung, erfolgt durch Streichen des letzten Parameters der Sprung ins angewärmte Wasser.

Tabelle 1:
Komponenten von Cfengine

 

Dienst

Aufgabe

cfagent

Interpretiert die Policy und nimmt nötige Änderungen
am Client vor

cfexecd

Als Daemon oder über Cron aufgerufener Scheduler und
Wrapper um »cfagent«

cfservd

Server-Daemon, der Dateien im Netz bereitstellt und entfernt
ausführt

cfenvd

Sammelt statistische Daten über das System und erkennt
Anomalien

cfrun

Hilfswerkzeug, das die Ausführung von
»cfagent« auf entfernten Systemen im Push-Verfahren
anstößt

cfkey

Generiert den privaten und öffentlichen RSA-Schlüssel
für einen Server

Einfach viele

Seine wahre Stärke entfaltet Cfengine, wenn es als Policy-Host, also als Server, im Netzwerk zum Einsatz kommt, die Master-Konfiguration verteilt und Sorge trägt, dass die Clients sie auch umsetzen. Der Admin richtet dafür den »cfservd« ein und konfiguriert dazu »/etc/cfengine/cfservd.conf« (siehe Listing 2). Ist der Dienst eingerichtet und neu gestartet, dürfen sich die Clients die Master-Policy, aber auch zusätzliche Dateien, etwa Antiviren-Patterns oder Regeln für den Spamfilter, dort abholen.

Der obligatorische »control«-Block erlaubt den Zugriff aus dem Netzsegment 192.168.1.0/24 heraus (Zeile 3). Das fehlende Oktett im Listing ist kein Schreibfehler, sondern eine erlaubte Notation von Cfengine, die so das 24-Bit-Subnetz anzeigt. Zusätzlich zur IP-Adresse müssen sich Clients mit ihrem RSA-Schlüssel authentifizieren. Zeile 4 hebelt diese Vorsichtsmaßnahme aus. Sie sollte nur so lange aktiviert bleiben, bis alle Clients den öffentlichen Schlüssel des Servers gesammelt haben.

Die Anweisungen in den Zeilen 7 bis 10 zügeln allzu eifrige Clients, indem sie die maximale Anzahl gleichzeitiger Verbindungen beschränken. Die Option »SplayTime« verhindert, dass alle Clients wiederkehrend zur selben Zeit ihre Anfrage stellen. Dazu lässt sie jeden einzelnen Client eine bis zu einer Minute andauernde Pause einlegen, bevor sie erneut den Zugriff auf die im »grant«-Block (Zeile 12) freigegeben Ressourcen gewährt. Das ist im Beispiel-Listing die Master-Konfiguration.

Listing 2:
»cfservd.conf«

01 control:
02   domain                = ( linux-magazin.com )
03   AllowConnectionsFrom  = ( 192.168.1 )
04   TrustKeysFrom         = ( 192.168.1 )
05   AllowUsers            = ( root )
06   LogAllConnections     = ( true )
07   MaxConnections        = ( 50 )
08   MultipleConnections   = ( true )
09   SplayTime             = ( 1 )
10   IfElapsed             = ( 15 )
11 
12 grant: /var/lib/cfengine2/masterfiles/inputs
13           *.linux-magazin.com

Config, du sollst wandern

Um stets mit der aktuellen Konfiguration zu arbeiten, führt der Cfengine-Client vor allen anderen Aktionen zunächst die Anweisungen aus der Datei »/etc/cfengine/update.conf« aus (siehe Listing 3). Üblicherweise richtet der Admin hier die Übertragung vom Policy-Server (Zeile 3) ein. Das hat den Vorteil, dass jeder Client mit einer lokalen Kopie arbeitet, also auch seine Arbeit verrichtet, wenn der Master einmal ausfällt. Hat sich in die Konfiguration ein Syntaxfehler eingeschlichen, bleiben die Clients trotzdem handlungsfähig, da der Admin seinen Fehler nur in der Masterkonfiguration korrigieren und erneut verteilen muss.

Cfengine bewahrt sicherheitshalber Logfiles sowie Kopien geänderter Dateien im Repository-Verzeichnis (Zeile 5) auf. Der Block »tidy« (Zeile 12) erledigt die Aufräumarbeiten und löscht dort alle Dateien, die älter als eine Woche sind.

Listing 3:
»update.conf«

01 control:
02   domain     = ( linux-magazin.com)
03   policyhost = ( 192.168.1.1 )
04   workdir    = ( /etc/cfengine )
05   repository = ( /var/cfengine2/outputs )
06   masterfiles = ( /var/cfengine2/masterfiles/inputs )
07   actionsequence = ( copy tidy )
08 
09 copy:
10   $(masterfiles) dest=$(workdir) server=$(policyhost) 
11                  mode=0600 r=inf
12 tidy:
13   $(repository)  pattern=* age=7

Keine einfache Aufgabe

Um komplexe Aufgaben zu erledigen, stehen diverse Aktionen und Direktiven zur Verfügung, die Cfengine mitliefert [4]. Die Auswahl lässt sich zwar in puncto Vielfältigkeit und Abstraktion nicht mit den Möglichkeiten anderer Konfigurationstools wie Bcfg2 oder Puppet vergleichen, viele Hürden der täglichen Sysadmin-Arbeit sind damit aber gut und schnell zu meistern: Die Konfiguration eines Mailservers etwa erfordert es, mehrere Komponenten am System an dessen Erfordernisse anzupassen. Zusätzlich wollen der Spam- und Virenschutz auf dem neuesten Stand gehalten, regelmäßig Statistiken über die Nutzlast erstellt und sich anbahnende Mailprobleme frühzeitig erkannt sein.

Traditionell behilft sich der Admin nach der manuellen Grundkonfiguration mit Skripten, die er mit Cron ausführt. Anfallende Änderungen der Konfiguration sind jedoch mühsam, da der Systemverwalter so jeden einzelnen der betreuten Mailserver gleichermaßen anpasst.

Einfacher ist es, einmalig eine Policy für alle Mailserver zu konfigurieren und Cfengine die Arbeit erledigen zu lassen (siehe Listing 4). Soll ein zusätzlicher Mailserver zum Einsatz kommen, trägt ihn der Admin in die Gruppe »MailServers« ein (Zeile 9). Nach dem ersten Aufruf von »cfagent«, den »cfexecd« periodisch ungefähr alle 15 Minuten aufruft (Zeile 2), sind alle notwendigen Änderungen erfolgt: Der neue Mailserver nimmt die Arbeit auf. Übersicht bewahrt, wer die Konfigurationsdateien aufteilt und über die »import«-Anweisung einbindet.

Listing 4: Ausführliche
»cfagent.conf«

01 control:
02   Schedule           = ( Min00_05 Min15_20 Min30_35 Min45_50 )
03   AddInstallable     = ( RELOAD_SPAMASSASSIN RELOAD_POSTFIX )
04   DefaultPkgMgr      = ( dpkg )
05   DPKGInstallCommand = ( "/usr/bin/apt-get install -q -y %s" )
06   actionsequence     = ( packages copy directories editfiles shellcommands )
07 
08 groups:
09   MailServers = ( mail01 mail02 )
10 
11 packages:
12   postfix          action=install
13   ...
14 
15 directories:
16   !debian.MailServers::
17   /var/spool/postfix/var/run/saslauthd m=710 o=root g=sasl
18 
19 copy:
20   MailServers::
21   (masterfiles)/spamassassin/ dest=/etc/spamassassin/ mode=644
22                               server=$(policyhost) recurse=inf
23 editfiles:
24   MailServers::
25   { /etc/postfix/main.cf
26   AppendIfNoSuchLine "smtpd_sasl_auth_enable = yes"
27   BeginGroupIfNoLineContaining "smtpd_recipient_restrictions"
28       Append "smtpd_recipient_restrictions = permit_sasl_authenticated, reject"
29   EndGroup
30   DefineClasses "RELOAD_POSTFIX"
31   }
32 
33   { /etc/passwd
34     AppendIfNoSuchLine "spamd:x:108:65534::/home/spamd:/bin/false"
35   }
36 
37 alerts:
38   MailServers.smtp_in_high_anomaly::
39     "High SMTP incoming rate at $(host) value: $(value_smtp_in) average: $(average_smtp_in)"
40     ShowState(incoming.smtp) ifelapsed=60
41 
42 shellcommands:
43   MailServers.Hr03_Q1::
44     "/usr/bin/sa-update && /etc/init.d/spamassassin reload"
45   MailServers.RELOAD_SPAMASSASSIN::
46     "/etc/init.d/spamassassin restart" ifelapsed=10
47   MailServers.RELOAD_POSTFIX::
48     "/etc/init.d/postfix reload"

Pakete installieren

Das durch »DPKGInstallCommand« festgelege Kommando installiert die für einen Mailserver benötigen Pakete im Block »packages« (Zeile 11). Ähnliche Direktiven gibt es außerdem für Distributionen, die auf RPM basieren, Gentoos Portage Tree sowie für Open Solaris und FreeBSD. Über die Parameter »version« und »cmp« nimmt der Admin Einfluss auf die gewünschten Version der Pakete.

Sind alle Pakete installiert, kümmert sich der Block »editfiles« in Zeile 23 um die nötigen Änderungen an den Konfigurationsdateien. Die Befehle tragen in der Regel sprechende Namen und sind daher auch nach längerer Zeit noch leicht verständlich. So hängt »AppendIfNoSuchLine« sein Argument an eine Konfigurationsdatei an, wenn es noch nicht eingetragen ist. Zeile 34 legt damit einen Benutzer für den Antispam-Daemon an.

Handarbeit notwendig

Die Möglichkeiten, die »editfiles« bietet, machen zwar manches Skript überflüssig, lassen aber den Komfort einiger anderer Konfigurationsmanager missen. So muss der Anwender von Cfengine auf diesen Mechanismus zurückgreifen, um beispielsweise User und Gruppen den Dateien »/etc/passwd« und »/etc/groups« hinzuzufügen, da Cfengine solche Aufgaben nicht explizit unterstützt.

Führt Cfengine wegen nötiger Änderungen die »editfiles«-Aktion ab Zeile 23 durch und trifft die Bedingung der Klasse »Mailservers::« zu, definiert das Keyword »DefineClasses« in Zeile 30 zur Laufzeit eine dynamische eigene Klasse. Daher startet der »cfagent« später in Zeile 48 den Postfix-Server nur dann neu, wenn das Konfigurationstool tatsächlich Änderungen vorgenommen hat.

Abbildung 1: Der Policy-Host stellt die Richtlinien für die Clients im Netz bereit, die diese lokal interpretieren. Optional können die Clients selbst Freigaben erteilen.

Abbildung 1: Der Policy-Host stellt die Richtlinien für die Clients im Netz bereit, die diese lokal interpretieren. Optional können die Clients selbst Freigaben erteilen.

Dynamische Bedingungen

Die Klassen, die »DefineClasses« zur Laufzeit ergänzt, führt der Admin vorher zusätzlich im »control«-Block mit der Direktive »AddInstallable« auf (Zeile 3). Andernfalls erkennt Cfengine die neue Klasse nicht an. Der »directories«-Block (Zeile 15) verschiebt das Verzeichnis für den Socket von »saslauthd« in das Postfix-Jail. Debian-Aficionados erledigen diesen Schritt zwar durch »dpkg-divert«; auf anderen Systemen ist dieser Weg aber durchaus denkbar. Die Klassendefinition »!debian::« beschränkt die Ausführung auf diese Gruppe der Distributionen.

Alarm

Den Block »alerts« (Zeile 37) muss Cfengine nicht extra über die »actionsequence« aufrufen. Es verarbeitet die vom »cfenvd« gesammelten Laufzeitinformationen über das System. Bei ungewohnt hohem Aufkommen eingehender Mails alarmiert das Tool den Admin wie in Zeile 40 konfiguriert. Die Ausgabe von »ShowState()« liefert im Detail, was der Mailserver gerade zu tun hat, und gibt dem Systemverwalter einen Hinweis darauf, was seinen Server umtreibt.

Eigene Checks sind möglich, die etwa Alarm schlagen, wenn eine bestimmte Klasse definiert ist oder sonst eine Situation eintritt, die den Admin interessiert. Läuft ein Zertifikat aus oder liegen neue Sicherheitsupdates vor, informiert Cfengine darüber. Sind hingegen keine Änderungen notwendig, arbeitet Cfengine still vor sich hin. Sollen sich alle Clients stündlich zur Stelle melden, weil der Admin sich regelmäßig vergewissern will, ob der Agent noch seine Arbeit verrichtet, hilft:

"$(host) meldet sich zum Dienst!" ifElapsed=60

Das vollständige Cfengine-Skript steht auf dem FTP-Server des Linux-Magazins zum Download bereit [5].

Mächtig gewachsen

Mit Cfengine bekommt der Admin ein mächtiges Werkzeug an die Hand, das nicht nur flexibel und automatisiert auf notwendige Konfigurationsänderungen reagiert, sondern auch die Entwicklung kleinerer Skripte ersetzt. So verhindert es deren schnell auftretenden Wildwuchs. Cfengine trägt mit seinen Monitoring-Fähigkeiten zum stabilen Serverbetrieb bei. Das Werkzeug lässt sich nicht ganz so bequem erweitern wie manch anderes Tool zum Konfiguarationsmanagement, sodass in der Praxis vieles auf halbmanuelles Umschreiben von Konfigurationsdateien mittels »editfiles« hinausläuft.

Dafür hat sich Cfengine in vielen Jahren praktischen Einsatzes bewährt und hält nach Angaben der Entwickler trotz einiger Fallstricke bis zu 20000 Computer unter Kontrolle. Für Ende 2008 kündigen sie Version 3 an, die sich sogar an ITIL orientiert [6]. Die Sprachkonstrukte sollen bis dahin vollständig überarbeitet sein und damit uniformer als bislang. Der Urahn bleibt am Ball. (mg)

Infos

[1] University College Oslo: [http://www.hio.no]

[2] Cfengine:[http://www.cfengine.org/about.php]

[3] Sicherheitsmeldung des Debian-Projekts: [http://www.debian.org/security/2008/dsa-1571]

[4] Cfagent-Referenz: [http://www.cfengine.org/docs/cfengine-Reference.html#Cfagent-reference]

[5] Listings zu diesem Artikel: [ftp://www.linux-magazin.de/pub/listings/magazin/2008/10/Cfengine]

[6] Cfengine 3:[http://www.cfengine.org/cfengine3.php]

Der Autor

Andreas Putzo ist bei NMMN (New Media Markets & Networks) als Systemadministrator tätig. In seiner Freizeit engagiert er sich im Debian-Projekt.

LINUX-MAGAZIN KAUFEN
EINZELNE AUSGABE Print-Ausgaben Digitale Ausgaben
ABONNEMENTS Print-Abos Digitales Abo
TABLET & SMARTPHONE APPS Readly Logo
E-Mail Benachrichtigung
Benachrichtige mich zu:
0 Kommentare
Älteste
Neuste Beste Bewertung
Inline Feedbacks
Alle Kommentare anzeigen
Nach oben