Einführung in cfengine
Automatische Systemkonfiguration
René Pfeiffer
pfeiffer ät luchs døt at
Was ist Systemadministration?
- Wikipedia:
Sysadmins are usually charged with installing, supporting, and maintaining servers or other computer systems, and planning for and responding to service outages and other problems.
- Systemadministration handelt also von Netzwerken und Rechnern.
- Systemadministration ist in Wirklichkeit viel komplizierter! ☺
Wer seinem oder seinen Systemadministratoren eine Freude machen möchte, der/die/das sei auf
den
letzten Freitag im Juli
verwiesen. An diesem Tag kann man diesen gequälten Menschen eine große Freude machen oder
einfach nur nett zu ihnen sein.
Systemadministration à la 911
Es muß nicht immer
UserFriendly sein, auch
xkcd kann die harsche Realität oft sehr gut einfangen.
Nach einigen Berufsjahren kann man dann später auf das alt.bewährte
Usenet und
einschlägige Therapien zurückgreifen.
Systemadministration à la Zen
Das ist eine auf den ersten Blick langweilige Art der Systemadministration, mathematisch
notiert. Wenn man sich das Bild genauer anschaut, dann trifft es aber die oft gehegte
Wunschvorstellung. Ein Eingriff in ein System soll es nur auf den „rechten Weg” zurückführen.
Ein bereits im gewünschten Zustand befindliches soll auch in diesem Zustand bleiben.
Das sind wesentliche Anforderungen an Systemadministration, die man leider nicht mit allen
Werkzeugen erfüllen kann.
Zum Thema: Warum cfengine?
- Zentrale Konfiguration (wenn gewünscht)
- Klassenbasierte Systemkonfiguration
- Verschlüsselter & authentisierter Datentransfer zwischen Systemen
- Entdecken von Anomalien
- Delegieren von Automatismen an Automaten
Diese Liste gibt einen kurzen Überblick über die behandelten Themenbereiche in diesem
Vortrag. cfengines Projektwebseite findet man unter www.cfengine.org.
cfengine hat ein eigenes Wiki mit vielen weiterführenden
Informationen zum Umgang mit dem Werkzeug.
Zum Thema Verschlüsselung und Authentifizierung: cfengine generiert bei der
ersten Installation automatisch ein Public/Private Schlüsselpaar für asymmetrische
Verschlüsselung. Systeme, die sich beim ersten Mal an einem cfengine melden,
werden dann identifiziert (sie müssen beim „Erstkontakt” als vertrauenswürdig eingestuft
sein). Ihre Identität wird in jedem folgenden Kontakt mit der bei Erstkontakt verglichen.
Gibt es eine Abweichung, so bricht die Verbindung ab.
Passende Probleme zur Lösung
- Automatisches Anpassen einer Installation
- Systeme konvergieren in gewünschten Zustand
- Verwalten von Berechtigungen, Dateien, symbolischen Links
- Kontrolliertes Ausführen von Skripten & Befehlen
- Korrigieren von unauthorisierten Änderungen
- Vergleichen von Dateien mittels Checksummen
cfengine kann sehr viel mehr als in den Beispielen angeführt ist. Beim Erlernen
der Konfiguration und beim Begreifen der Möglichkeiten kommt man leider um Ausprobieren
nicht herum, ganz wie beim Programmieren. Am besten fängt man mit einer überschaubaren
Beispielkonfiguration an, die aus zwei Maschinen besteht, und arbeitet sich schrittweise
vor.
Komponenten
- cfagent - ein autonomer Konfigurationsagent
- cfservd - ein Dateiserver und Aktivierungsdienst
- cfexecd - Dämon für Abläufe und Berichte
- cfenvd - Dämon zur Anomalieerkennung
- cfrun - Werkzeug, um cfagent aus der Ferne aufzurufen
- cfshow - Werkzeug zum Anzeigen lokaler Speicher
- cfkey - Werkzeug zum Erzeugen von Schlüsseln
Eine cfengine Installation muß nicht notwendigerweise alle hier aufgeführten
Komponenten benutzen. Ein cfagent und ein cfservd können auch vollkommen
ausreichen.
Policies, Aktionen & Klassen
- cfengine benutzt Policies
- Beschreibung des erwünschten Zustandes
- Dokumentation wie ein Zustand erreicht wird
- Policy ist Liste von Versprechungen
- Aktionen beschreiben Kommandos
- Klassen beschreiben Eigenschaften
- Host ist ein GNU/Linux® System
- Host hat Datei namens /etc/motd
- Host ist ein SMTP-Server
- Host gehört zur Domain example.net
- …
Die Interpretation von Policy als Versprechung ist näher an der Realität als man
vermuten mag. Leider wird oft eine Policy in Stein gemeißelt und als Gesetz verstanden.
Das funktioniert in der Praxis nicht. Wenn es Raum für Abweichungen gibt, dann wird
es auch Abweichungen geben. Das ist normal. Dies wird erst zum Problem, wenn sich
niemand, sprich kein Mensch und kein Automat, dieser Abweichung annimmt und sie korrigiert.
Eine Policy kann also niemals ein Gesetz sein.
Beispiel für Policy
control:
tmpdirs = ( tmp:scratch:store )
actionsequence = ( files copy tidy )
files:
/usr/local/bin owner=root group=bin mode=755
action=fixall recurse=1
copy:
solaris::
/config/pam/solaris server=pammaster
dest=/etc/pam.d recurse=1
linux::
/config/pam/common-auth server=pammaster
dest=/etc/pam.d/common-auth
tidy:
/$(tmpdirs) include=* age=7 recurse=inf
Die control Sektion definiert Konstanten und legt die Abfolge der Aktionen fest.
In dieser Sektion lassen sich generelle Einstellungen vornehmen, die dann in Folge gelten.
actionsequence legt fest in welcher Reihenfolge die Aktionen ausgeführt werden.
Vordefinierte Aktionen
alerts | copy |
disks | disable |
editfiles | files |
links | netconfig |
resolve | packages |
processes | shellcommands |
tidy | |
- alerts
- Aktion zum Anzeigen von Nachrichten; diese Meldungen können auch als E-Mail verschickt werden.
- copy
- Aktion, die Dateien kopiert.
- disks
- Aktion, die die Existenz einer Datei oder eines Dateisystems prüft.
- disable
- Diese Aktion macht Dateien durch Umbenennen „unschädlich”.
- editfiles
- Mit dieser Aktion kann man Dateien editieren.
- files
- Diese Aktion erlaubt alle Tests und Modifikationen, die auf Dateien angewendet werden können.
- links
- Diese Aktion erlaubt alle Tests und Modifikationen, die auf symbolische Links angewendet werden können.
- netconfig
- Überprüft oder verändert Netzwerkparameter.
- resolve
- Erlaubt das Verwalten der Datei /etc/resolv.conf.
- packages
- Diese Aktion erlaubt Zugriff auf das Paketverwaltungssystem der Maschine. cfengine versteht
RPM am besten, kann aber auch beliebige andere Paketverwaltungssysteme integrieren.
- processes
- Diese Aktion erlaubt alle Tests und Modifikationen, die auf Prozesse angewendet werden können.
- shellcommands
- Erlaubt das Ausführen von Shell Kommandos innerhalb gesetzter Parameter wie beispielsweise
maximale Zeit für Ausführung oder umask.
Konvergente Versprechen
- cfengine unterstützt konvergente Regeln
- cfengine(inkorrekt) ⇒ korrekt
- cfengine(korrekt) ⇒ korrekt
- cfengine markiert Veränderungen
- Hosts bleiben autonom
- Hosts wählen Quelle für Policies selbst
- Freiwillige Teilnahme an Konfiguration
Klassen
- „Harte” Klassen gruppieren Hosts mit Eigenschaften
- linux, ultrix, openbsd, …
- nephtys_luchs_at, luchs_at, …
- 32-bit, i686, x86_64, …
- cfengine_2, …
- Berechnete („weiche”) Klassen
- Hr12_Q3, Min35, April, Friday, Day14, …
- ipv4_62_116_64_107, net_iface_eth0, …
- entropy_tcpack_out_low, entropy_udp_out_low, …
- cfagent -p -v | grep -i classes
Selbstdefinierte Klassen
- has_xinetd = ( FileExists("/usr/sbin/xinetd.conf") )
- ip_ok = ( IPRange(192.168.89.100-150) )
- need_restart = ( IsNewerThan(/old/file,/new/file) )
- do_import = ( IsDir("/tmp/import") )
- my_subnet = ( IPRange(192.168.89.200/26) )
Den Art und Weisen wie man Klassen selbst definieren kann, sind keine Grenzen
gesetzt. cfengine unterstützt eine Vielzahl von Funktionen.
cfengine Infrastruktur
- cfservd erlaubt Zugriff von anderen cfagents
- Pull Methode für Verteilung von Daten
- cfengine kommuniziert verschlüsselt
- = Protokoll mit RSA und Blowfish
- ≠ TLS/SSL (a.k.a. „X.509 Zeug”)
- ≠ SSH
- cfkey erzeugt Schlüssel pro Hosts lokal
- cfengine authentisiert Client mit Server und umgekehrt
cfengine „Hierarchie”
Die Hierarchien, die man mittels cfengine aufbauen kann, müssen nicht vollständig
zentral oder vollständig dezentral sein. Es ist auch möglich auf Bedarf lokale Master,
Konfigurationsspeicher oder sonstige spezielle Hosts zu definieren.
Im Bild ist zu beachten, daß die Pfeile zwar zum Client zeigen, aber der Transport
nach einer Pull Methode abläuft. Der Client kontaktiert den Server, nicht umgekehrt,
so wie es sein sollte.
cfengine Bootstrap
- cfengine Bootstrap Master erstellen
- Vertrauensverhältnis Master/Client sicherstellen
- Bootstrap Konfigurationsdatei kopieren (lassen)
- cfengine auf Client starten
- Warten. ☺
Bootstrap Master cfagent.conf
control:
domain = ( example.net )
actionsequence = ( directories copy )
policyhost = ( master.example.net )
cfdir = ( /var/lib/cfengine2 )
master_cfinput = ( /etc/cfengine/policies )
directories:
/etc/cfengine/policies m=0775 o=root g=root
copy:
${master_cfinput} server=${policyhost}
dest=${cfdir}/inputs
recurse=inf mode=700
type=binary trustkey=true
Die dargestellte Konfiguration ist ein Fragment. Man kann das Generieren
der
Trust Keys am Client und das Neustarten der relevanten
cfengine
Prozesse auch in die Bootstrap Konfiguration einbauen.
Wichtig:
Die vorgestellte Konfiguration basiert auf Debian Paketen. Dort ist
/var/lib/cfengine2/inputs/
ein symbolischer Link auf das Verzeichnis
/etc/cfengine/.
# Control section
control:
domain = ( example.net )
actionsequence = ( shellcommands directories copy processes )
policyhost = ( master.example.net )
cfdir = ( /var/lib/cfengine2 )
master_cfinput = ( /etc/cfengine/policies )
directories:
/etc/cfengine/policies m=0775 o=root g=root
copy:
${master_cfinput} server=${policyhost}
dest=${cfdir}/inputs
recurse=inf
mode=700
type=binary
trustkey=true
shellcommands:
# Only needed if we don't have a key yet
# /usr/sbin/cfkey
processes:
"cfservd" restart "/usr/sbin/cfservd"
"cfexecd" restart "/usr/sbin/cfexecd"
"cfenvd" restart "/usr/sbin/cfenvd"
Master cfservd.conf
control:
domain = ( example.net )
DynamicAddresses = ( 172.16.23.42 )
AllowMultipleConnectionsFrom = ( 172.16.23.42 )
TrustKeysFrom = ( 192.168.0.72 )
classes:
ourhosts = ( "23.23.23.84,172.16.23.42,…" )
policyhost = ( master.example.net )
admit:
ourhosts::
/usr/sbin/cfagent ourhosts
policyhost::
/etc/cfengine/policies
*.example.net
23.23.23.84
Der Prozeß cfservd erlaubt anderen cfagent Prozessen den Zugriff
auf Resourcen. In unserem Fall möchten wir anderen cfagents erlauben
auf den Pfad /etc/cfengine/policies/ am Master zuzugreifen.
Aktualisierungen durch update.conf
control:
domain = ( example.net )
actionsequence = ( copy processes )
policyhost = ( master.example.net )
cfdir = ( /var/lib/cfengine2 )
master_cfinput = ( /etc/cfengine/policies )
master_modules = ( /var/lib/cfengine2/modules )
SplayTime = ( 2 )
schedule = ( Min00_05 Min45_50 )
timezone = ( CET )
copy:
${master_cfinput} server=${policyhost}
dest=${cfdir}/inputs
recurse=inf mode=700
type=binary trustkey=true
${master_modules} server=${policyhost}
dest=${cfdir}/modules
recurse=1 mode=700 type=binary
processes:
newservd::
"bin/cfservd$" signal=term restart "/usr/sbin/cfexecd"
Die Datei update.conf regelt die Aktualisierung von Konfigurationen. Diese
Datei wird immer vor der cfagent.conf ausgeführt. Man kann auf diese Weise
automatisch neuere Versionen von Konfigurationen an alle „interessierten” Hosts
verteilen.
Mögliche Fallstricke
- Zeitverzögerungen zwischen Aktionen
- cfengine verwendet Verzögerungen (splay time)
- Deaktivieren für Tests
- Vertrauensverhältnisse
- Schlüssel müssen passen
- IP Adresse/DNS muß passen
- IPv4/IPv6 muß passen
- Keine Benachrichtigungen
- cfengine ist ein „hands off” System
- Nutzen von Logs und alerts Aktion
Anomalie voraus!
Der Graph zeigt die E/A-Statistiken der Blockgeräte eines Servers. Die rote und die
blaue Kurve zeigen deutliche Aktivitäten, die auf das Synchronisieren zweier RAID1
Verbunde mit dem Linux® Software-RAID-Treiber zurückzuführen sind. Es ist eine Anomalie,
aber es kann durchaus normal sein, wenn der RAID1 Verbund gerade zusammengebaut wird.
Anomalie voraus?
Der Graph zeigt die Auslastung der CPU eines Servers. Sie stammt vom selben Server, der
die E/A-Statistiken produziert hat.
Eisberg voraus!
Der Graph zeigt die Speicherauslastung unseres Asterisk™ Servers im Büro. Die Maschine
erfuhr zu Testzwecken einen Scan mit der SIP Suite der
PROTOS Tools.
Die Auswirkungen machten sich erst Wochen später bemerkbar. Im Idealfall bemerken
Überwachungswerkzeuge diese Entwicklung vorher und melden sich bei einer Schwelle.
Erkennen von Anomalien
- cfenvd hat zwei Rollen
- Generieren von Entropie für Zufallsgenerator
- Überwachen von Systemstatistiken
- Prozeß meldet nach Lernperiode Abweichungen
- Abweichungen signalisiert durch Klassen
- nfsd_in_high_dev2
- smtp_out_high_anomaly
- entropy_tcpsyn_out_low
- entropy_tcpfin_out_low
Reagieren auf Anomalien
- Anomalienklassen erlauben Aktionen
- Automatische Gegenmaßnahmen
- nur wenn man seine Infrastruktur versteht!
- nur mit konservativen Aktionen!
- Behandlung von Anomalien erfordert
- gründliche Beobachtung
- viel Erfahrung
- sehr gute Kenntnis der Infrastruktur
Über dieses Dokument
Copyright © 2008 by René Pfeiffer
<lynx ät luchs døt at>. This material
may be distributed only subject to the terms and conditions set
forth in the Open Publication License, v1.0 or later (the latest
version is presently available at
http://www.opencontent.org/openpub/).