1.112.1 – Grundlagen von TCP/IP

zurück zu Linux Zertifizierungen LPIC
Prüfungskandidaten sollten ein richtiges Verständnis der Netzwerk-Grundlagen demonstrieren können. Dieses Lernziel beinhaltet das Verständnis von IP-Adressen, Netzwerkmasken und ihrer Bedeutung (d.h. Bestimmung einer Netzwerk- und Broadcast-Adresse für einen Host auf Grundlage seiner Subnetzmaske in “dotted quad” oder abgekürzter Notation oder die Bestimmung der Netzwerk-Adresse, Broadcast-Adresse und Netzwerkmaske bei gegebener IP-Adresse und Anzahl von Bits). Dies deckt auch das Verstehen der Netzwerkklassen und klassenloser Subnetze (CIDR) und der für private Netzwerke reservierten Adressen ab. Ebenfalls enthalten ist das Verständnis der Funktion und Anwendung der Default Route. Weiters enthalten ist das Verstehen der grundlegenden Internet-Protokolle (IP, ICMP, TCP, UDP) und der gebräuchlicheren TCP- und UDP-Ports (20, 21, 23, 25, 53, 80, 110, 119, 139, 143, 161).

Die wichtigsten Dateien, Bezeichnungen und Anwendungen:

* /etc/services
* ftp
* telnet
* host
* ping
* dig
* traceroute
* whois

Dieses Kapitel ist wenig Linux-spezifisch, sondern bezieht sich auf das Verständnis von TCP/IP im Allgemeinen. Natürlich werden die jeweiligen Linux-Techniken auch mit erwähnt, wo sie anfallen, wichtig ist jedoch das fundierte Verständnis der Technik von IP-Netzwerken, von Netzadressen usw. Ich beginne hier also mit ein paar ausführlichen Abschnitten über diese Themen. Abschließend werden noch die hier aufgeführten Programme besprochen.

Die TCP/IP Protokollfamilie
TCP/IP hält sich nicht an das OSI-Schichtenmodell, es hat ein eigenes Modell, das sich nicht eins zu eins übertragen lässt.

pic

Jede der vier Schichten des TCP/IP Schichtenmodells verfügt über ein bzw. mehrere Protokolle, die den Umgang mit den jeweiligen Daten regeln. Unter Protokollen werden hier Regelsammlungen bezeichnet, die in sogenannten RFCs (Request for comment) veröffentlicht werden.

Das Entscheidende an der Konstruktion von TCP/IP sind die beiden mittleren Schichten, die Transport- und die Vermittlungsschicht. Hier arbeiten immer die gleichen Protokolle. In der Transportschicht stehen zwei zur Verfügung, eins für verbindungsorientierten Datenverkehr (TCP) und eins für verbindungslosen Datentransfer (UDP). In der Vermittlungsschicht arbeitet nur ein Protokoll in der Datenübertragung (IP), so steht also eine einheitliche und verbindliche Übertragungsform zur Verfügung.

In der obersten und untersten Schicht können so die verschiedensten Protokolle arbeiten, von denen die beiden mittleren Schichten nichts wissen müssen. In der Anwendungsschicht können so Standardprotokolle wie etwa FTP (Dateiübertragung), TELNET (Terminal EmuLation über NET), HTTP (WWW-Seiten), SMTP (E-Mail) oder NNTP (News) arbeiten, aber auch eigens entwickelte Protokolle etwa für ein Schachspiel übers Netz. Jedes dieser Anwendungsprotokolle hat eine Identitätsnummer zugewiesen bekommen, die sogenannte Portnummer. Mit Hilfe dieser Portnummer kann das Transportprotokoll wissen, an welche Anwendung in der Anwendungsschicht es Daten weitergeben soll. Unter Linux ist die Liste aller bekannten Portnummern in der Datei /etc/services zu finden.

Die unterste Schicht übernimmt die Steuerung der Netzhardware, also die der Netzwerkkarten o.ä. Diese Schicht kann mit beinahe jedem beliebigen Protokoll arbeiten, wie etwa die IEEE 802.3 802.4 802.5 oder FDDI, ATP aber auch mit PPP oder SLIP auf seriellen oder mit PLIP auf paralelle Schnittstellen.

pic

Um die Funktion des Netzsystems genau zu verstehen ist ein Wissen über die einzelnen Schichten und Protokolle unabdingbar. Anhand einiger Beispiele sollen hier die einzelnen Aufgaben der Schichten erklärt werden.

Die Netzzugriffsschicht mit ihren Protokollen
In dieser Schicht arbeiten, wie oben schon erwähnt, beinahe alle Protokolle von Netzhardware, von einfachen seriellen Verbindungen bis zu Hochleistungssysteme mit Glasfaserkabeln. Ein typisches Beispiel soll hier näher betrachtet werden, das Protokoll IEEE-802.3, das Protokoll des Ethernet. Das hier dargestellte Protokoll ist das der 10Mbit Version von Ethernet, die moderneren Versionen unterscheiden sich in Kleinigkeiten, die aber nicht technisch relevant sind.

Die Aufgabe des IEEE-802.3 Protokolls ist es, Daten, die von der Vermittlungsschicht kommen, in Pakete zu packen, und diese Pakete dann über die Netzhardware zu verschicken. Umgekehrt nehmen sie Pakete vom Netz entgegen und geben sie gegebenenfalls an die Vermittlungsschicht weiter. Der Inhalt der Daten spielt dabei keinerlei Rolle.

Physikalisch gesehen, ist ein Ethernet eine parallele elektrische Verbindung aller Rechner, die an einem Netzsegment hängen. Das heißt, wenn ein Rechner einem anderen Rechner ein Paket schickt, so bekommen alle angeschlossenen Rechner dieses Paket. Anhand einer (weltweit eindeutigen) Adresse, die jede Netzwerkkarte besitzt, kann dann aber entschieden werden, ob das Paket tatsächlich für diesen Rechner bestimmt ist. Jedes Paket, das über ein IEEE-802.3 Protokoll verschickt wird enthält sowohl diese Adresse des Absenders, als auch die des Empfängers. Alle angeschlossenen Rechner im Netz (genauer gesagt, alle angeschlossenen Netzwerkkarten im Netz) empfangen das gesendete Paket, aber nur die Netzwerkkarte, die tatsächlich die Adresse aufweist, die im Paket als Empfängeradresse angegeben ist, gibt das Paket entpackt an die Vermittlungsschicht weiter. Diese Adressen sind die sogenannten MAC-Adressen.

Die detaillierte Darstellung des IEEE 802.3 Frameformat ist hier einsehbar:

Die interne Struktur des IEEE 802.3 Frames

Der IEEE802.3 Standard (Ethernet) bedient sich auch der Aufteilung des zu transportierenden Datenstromes in Pakete. Diese Pakete werden auch Rahmen (Frames) genannt, weil sie vor und nach den eigentlichen Daten noch Steuerinformationen ablegen. Die folgende Abbildung zeigt das verwendete Rahmenformat:

pic

Jeder Rahmen beginnt mit einer Präambel von 7 Bytes, die jeweils die Bitfolge 10101010 enthalten. Durch die Kodierung dieser Bitfolge (Manchester) entsteht eine 10 MHz Schwingung, die 5,6 µs dauert. Dadurch kann sich der Taktgeber des Senders mit dem des Empfängers synchronisieren.

Als nächstes folgt ein Rahmenstartbyte (Rahmenbegrenzer) also die Markierung, daß hier der Frame beginnt. Dieses Byte enthält immer die Bitfolge 10101011

Die beiden folgenden Blöcke, Zieladresse und Quelladresse enthalten die physikalischen Netzwerkadressen (Ethernetadressen, MAC-Adressen) des Empfängers und Senders. In etwa also das, was ein Briefumschlag enthält, Absender und Empfängerangaben…

Dabei wird intern bei der Zieladresse noch zwischen Einzeladressen, Gruppenadressen und Broadcastadressen unterschieden, also Pakete, die entweder an einen bestimten Rechner gehen, oder an eine bestimmte Gruppe von Rechnern oder an alle Rechner im Netz.

Im nächsten Feld (Länge) steht die Angabe, wie lang das folgende Datenpaket ist, gültige Werte sind hier 0 bis 1500. Theoretisch sind also Datenpakete mit der Länge 0 möglich, aus physikalischen Gründen ist aber eine minimale Länge von 46 Bytes erforderlich. Dafür sorgt dann das Pad Feld, das Datenfelder mit einer Länge unter 46 Bytes bis auf desen Minimalwert auffüllt.

Im Datenfeld zwischen Länge und Pad stehen die eigentlich zu übertragenen Daten. Durch die Angabe der tatsächlichen Länge dieses Feldes im Feld Länge kann der Empfänger des Paketes mit unterschiedlich großen Datenfeldern immer richtig umgehen.

Das letzte Feld des Rahmens ist die Prüfsumme, die vom Sender errechnet wurde und sich natürlich auf das Datenfeld bezieht. Der Empfänger kann nun das Datenfeld ebenso überprüfen und, falls er zu einem anderen Ergebnis kommt, eine erneute Zusendung des Pakets beantragen. Dieses Verfahren wird übrigens in der IEEE Norm 802.2 beschrieben, die für alle drei folgenden Normen (802.3, 802.4, 802.5) angewendet wird.

Natürlich gibt es noch viele weitere Protokolle auf der Netztzugriffsschicht, etwa ppp und slip für die serielle Anbindung an ein IP-Netz, oder andere Hardware-Netzfamilien wie Token Ring. Diese Darstellung ist also nur ein Beispiel von vielen.

Die Vermittlungsschicht und das InternetProtokoll (IP)
Die Vermittlungs- oder auch Internetschicht hat ein allumfassendes Protokoll, das zum Transport der Daten zuständig ist, das Internet Protokoll (IP). Daneben arbeitet noch ein weiteres wichtiges Protokoll auf dieser Schicht, das für technische Informationen statt für Daten zuständig ist, das Internet Control Message Protokoll (ICMP).

Das Internet Protokoll (IP)
Das Internet-Protokoll ist für die Vermittlung zwischen zwei Rechnern zuständig. Hier wird mit den IP-Adressen gearbeitet, statt mit den physikalischen Adressen im Netzwerk. Die zentrale Aufgabe des IP ist das Versenden und Empfangen von Daten, die für diesen Zweck wieder mal in Pakete aufgeteilt werden müssen. Die Pakete des IP werden Datagramme genannt und beinhalten neben den eigentlichen Daten wieder verschiedenste Steuerinformationen.

Der Aufbau von IP-Datagrammen:

Das Internet Protokoll (IP) packt den Datenstrom, den es aus der Transportschicht bekommt wiederum in Pakete, die aber diesmal mit den logischen IP-Adressen versehen sind statt mit den physikalischen Netzadressen. Die interne Struktur eines solchen Datagramms (Paketes) ist in der folgenden Graphik dargestellt.

pic

Der Aufbau eines IP-Datagramms entspricht also nicht dem Frame System, sondern stellt nur einen Header (Kopfteil) zur Verfügung. Nach dem Header folgen nur noch Daten, keine Frame-Ende-Zeichen o.ä.

Die einzelnen Felder sollen kurz noch dargestellt werden:

Version – 4 Bit
Dieses Feld enthält die Versionsnummer des IP. Aktuelle Version ist 4, bald kommt 6…
Internet Header Length (IHL) – 4 Bit
Gibt die Länge des Headers in 32 Bit Worten an. Damit kann ermittelt werden, ob Optionen gesetzt sind. Normalerweise (ohne Optionen) hat dieses Feld den Wert 5.
TOS (Type of Service – Diensttyp) – 8 Bit
Enthält Flags, die zur Steuerung der Zuverlässigkeit des Netzes dienen. Sie werden automatisch erstellt.
Gesamtlänge – 16 Bit
Enthält die Gesamtlänge des Datagramms (incl. Kopf) in Byte. Aus der Breite dieses Feldes (16 Bit) ergibt sich so eine maximale Größe von Datagrammen von 65535 Byte. Dieser Wert liegt weit über dem maximalen Wert der einzelnen Netzsysteme, daher reichen 16 Bit aus.
Kennung – 16 Bit
Jedes IP-Datagramm muß eine eigene Kennung haben, um beim Wiederzusammenbau richtig eingeordnet zu werden.
Flags – 3 Bit
Flags zur Steuerung der Fragmentierung.
Fragment-Offset – 13 Bit
Unter Fragmentierung von Datagrammen ist zu verstehen, daß einzelne Datagramme, die durch Gateways in unterschiedliche Netze geroutet werden, dort oft unterschiedlichen Größenbestimmungen unterliegen. IP fragmentiert solche Datagramme und baut sie wieder zusammen. Dieses Feld enthält die Information, an welcher Stelle das Fragment ursprünglich war.
Lebensdauer – 8 Bit
In Netzen wie dem Internet, in denen viele Datagramme auf unterschiedlchsten Wegen versuchen zum Ziel zu kommen, muß eine maximale Lebensdauer haben, sonst werden sie unendlich oft geroutet. Dieses Feld enthält eine Zahl, die vom Sender eingetragen wurde. Jeder Gateway muß diese Zahl um eins herunterzählen, wenn er ein Datagramm routet. Ist der Wert Null, so darf kein Router das Datagramm mehr weiterleiten. Übliche Startwerte sind 32 oder 4 (nur lokale Netze setzen so niedrige Lebensdauer an)
Protokoll – 8 Bit
Dieses Feld gibt an, von welchem Protokoll der Transportschicht dieses Datagramm kommt. Das ist wichtig für den Empfänger, weil ja mehrere Netzanwendungen gleichzeitig laufen können. Nur durch diese Information kann das Empfänger IP das Datagramm an das richtige Transportschichtprotokoll weiterleiten. Übliche Werte sind:

* 17 – UDP
* 6 – TCP
* 1 – ICMP

Kopf-Prüfsumme – 16 Bit
Prüfsumme über den Inhalt des Headers, nicht der Daten. Sicherung der Daten wird von der Transportschicht überprüft.
Sender IP-Adresse – 32 Bit
32 Bit IP-Adresse des Senders
Empfänger IP-Adresse – 32 Bit
32 Bit IP-Adresse des Empfängers
Optionen – 10010101.01001100.00000000.00000000
Netmask 11111111.11111111.00000000.00000000
–> 255.255.0.0

Wollen wir jetzt dieses Netz in mehrere Unternetze aufteilen, so können wir z.B. das dritte Byte als Unternetzadresse und das letzte Byte als Hostadresse werten. Für die Netmask käme folgendes Bild heraus:

Netzadresse Hostadresse
149.76.0.0 –> 10010101.01001100.00000000.00000000
Netmask 11111111.11111111.11111111.00000000
–> 255.255.255.0

Die Netzmaske kann entweder in dieser Form angegeben werden (dotted quad) oder als verinfachte Angabe, indem einer IP-Adresse einfach die Anzahl der Bits angegeben wird, die Netzadressenbits sind. Die folgenden Adressenangaben sind also äquivalent:

Dotted Quad Vereinfacht
192.168.100.1 Netmask 255.255.255.0 192.168.100.1/24
175.12.34.56 Netmask 255.255.0.0 175.12.34.56/16

Schwieriger wird es, wenn wir etwa ein C-Klasse Netz in weitere Unternetze aufteilen wollen. Hier muß dann jede Adresse errechnet werden, je nach der Aufteilung. Die Netmask wäre dann entsprechend auch nicht mehr nur 255 sondern würde sich aus anderen Zahlen zusammensetzen. Nochmal ein Beispiel:

Das C-Klasse Netzwerk 192.168.200.0 soll in vier Unternetze aufgeteilt werden. Um vier Netze anzusprechen benötigen wir zwei Bits der Hostadresse für die Subnetzangabe:

Subnetzbits
||
Netzadresse VV
192.168.200.0 –> 11000000.10101000.11001000.00000000
Netmask 11111111.11111111.11111111.11000000
–> 255.255.255.192

Statt der üblichen 255.255.255.0 haben wir jetzt also 255.255.255.192 als Netzmaskierung (oder – vereinfacht /26 weil die ersten 26 Bits der Adresse jetzt die Netzadresse sind). Damit weiß IP, daß diese Adresse kein normales C-Klasse Netz ist. Allerdings müssen wir jetzt auch bei der Vergabe der einzelnen Rechneradressen aufpassen, daß die verwendeten Zahlen im jeweiligen Netz liegen:

Subnetz 0
Netzadresse 0 -> 00000000
Hostadressen 1 -> 00000001
2 -> 00000010
3 -> 00000011

Broadcast 63 -> 00111111

Subnetz 1
Netzadresse 64 -> 01000000
Hostadressen 65 -> 01000001
66 -> 01000010
67 -> 01000011

Broadcast 127 -> 01111111

Subnetz 2
Netzadresse 128 -> 10000000
Hostadresse 129 -> 10000001
130 -> 10000010
131 -> 10000011

Broadcast 191 -> 10111111

Subnetz 3
Netzadresse 192 -> 11000000
Hostadresse 193 -> 11000001
194 -> 11000010
195 -> 11000011

Broadcast 255 -> 11111111

Netzadressen und Broadcast errechnen sich nach der Regel

* Alle Bits der Hostadresse auf 0 ist die Netzadresse.
* Alle Bits der Hostadresse auf 1 ist die Broadcastadresse.

Nur daß eben die Hostadresse jetzt nur noch aus den letzten 6 Bits besteht.

Die Transportschicht (TCP und UDP)
In der Transportschicht arbeiten zwei unterschiedliche Protokolle, TCP und UDP. Der wesentliche Unterschied zwischen beiden Protokollen ist, daß TCP verbindungsorientiert arbeitet und UDP verbindungslos.

Beiden Protokollen gemeinsam ist die Verwendung sogenannter Portnummern. Dieses System beruht auf der Tatsache, daß es mehrere Verbindungen über ein Transportprotokoll gleichzeitig geben kann. So kann ein Rechner beispielsweise gleichzeitig über FTP Daten von einem anderen Rechner kopieren und via TELNET auf dem gleichen Rechner eingeloggt sein. Das erfordert es, daß das Transportprotokoll in der Lage ist, zu unterscheiden, welche Pakete an FTP und welche an TELNET adressiert sind. Diese Adressierung übernehmen die Portnummern. Die Standard-Internet-Protokolle haben festgelegte Portnummern (definiert in /etc/services).

User Datagram Protocol (UDP)

UDP ist ein sehr einfaches Protokoll, das Anwendungen die Möglichkeit bietet, direkten Zugriff auf die Datagramm-Services von IP zu nutzen. Das ermöglicht die Übermittlung von Daten mit einem Minimum an Protokollinformationen.

Das UDP-Message Format:

UDP als datagramorientiertes Protokoll benötigt keinerlei Informationen über Sequenznummern oder ähnliches, eine sehr einfache Headerstruktur genügt hier:

pic

Quellportnummer
bezeichnet die Portnummer (/etc/services) des Anwenderschichtprotokolls, von dem die UDP-Message abgeschickt wurde.
Zielportnummer
bezeichnet die Portnummer des Empfängerprotokolls auf der Anwendungsschicht.
Länge
Hier steht die Länge der gesamten UDP-Message
Prüfsumme
Eine Prüfsumme über das Datenfeld

UDP wird überall dort verwendet, wo entweder die Datenmenge so klein ist, daß es sich nicht lohnen würde, einen großen Header zu benutzen, weil der größer als die eigentlichen Daten wäre oder wo die Anwendungen selbst noch Überprüfungen des Paketinhaltes vornehmen.

Lohnenswert ist der Einsatz auch dort, wo reine Frage-Antwort Mechanismen auftreten. Dort ist kein verbindungsorientiertes Protokoll nötig, weil ja nach dem Senden einer Frage klar ist, wenn nach einer bestimmten Zeit keine Antwort eingeht, so wird das Paket verlorengegangen sein und die Frage muß nochmal gestellt werden.

Wichtig ist die Feststellung, daß das UDP-Protokoll keinen Datenstrom verarbeitet, sondern Datagramme direkt. Es stellt also keinerlei Mechanismen zur Verfügung um einen Datenstrom in Pakete aufzuteilen und wieder zusammenzubauen.

Transmission Control Protocol (TCP)
TCP ist im Gegensatz zu UDP ein verbindungsorientiertes Protokoll, das Datenströme verarbeitet, die von der Anwendungsschicht kommen. TCP garantiert die Versendung von Daten durch eingebaute Handshake-Mechanismen.

TCP bietet einen verlässlichen Datentransfer durch die Verwendung eines Mechanismus, der Datenpakete (sogenannte Segmente) solange an einen Empfänger schickt, bis der eine Bestätigung des Empfangs rückmeldet. Dabei überprüft der Empfänger auch wieder eine Prüfsumme, erst wenn die richtig ist, schickt er das Signal des Empfangs.

Das TCP-Segment Format

Im Gegensatz zu UDP braucht TCP als streamorientiertes Protokoll immer Informationen, an welcher Stelle des Datenstroms das Segment eingefügt werden soll. Außerdem ist Information über die Größe des Empfängerbuffers nötig, um zu verhindern, daß es zu Überläufen kommt. Es ist also ein entsprechend komplexer Header nötig:

pic

Absender Portnummer
bezeichnet die Portnummer (/etc/services) des Anwenderschichtprotokolls, von dem der Datenstrom abgeschickt wurde.
Empfänger Portnummer
bezeichnet die Portnummer des Empfängerprotokolls auf der Anwendungsschicht.
Sequenznummer
Gibt die Position im Datenstrom an, an der dieses Segment eingefügt werden soll.
Bestätigungsnummer
Dient zur Bestätigung des Empfangs eines Segments. Dieses Feld enthält immer die Nummer, die im nächsten Segment als Sequenznummer stehen soll.
Daten-Offset
Gibt die Größe des Headers in 32 Bit Worten an. Ohne Optionen sind es 5. Damit kann genau bestimmt weden, wo der Datenbereich des Segments beginnt.
Flags
Verschiedene Flags zur Kommunikationssteuerung
Fenster
Mit diesem Wert wird die Größe des Buffers angezeigt, der von einem Endknoten für diese Verbindung reserviert wurde. Der sendende Knoten darf keinesfalls mehr Daten als die angegebene Puffergröße senden, ohne auf den Eingang einer Bestätigung zu warten.
Prüfsumme
Eine Prüfsumme über das gesamte Segment (Daten und Header)
Dringlichkeitszeiger
Wird bei besonders dringend zu verarbeitenden Paketen gesetzt. Wenn gesetzt enthält dieses Feld als Wert die Endadresse des Datenfeldes, das als dringlich gilt.
Optionen
Verschiedene Optionen zur Kommunikation wie etwa die maximale Segmentgröße
Füllzeichen
Zum Auffüllen der Optionszeile auf 32 Bit

TCP ist verbindungsorientiert, d.h., daß dieses Protokoll nicht einfach Daten losschickt wie UDP sondern zuerst einen Handshake durchführt, um sich mit dem Empfänger über dessen Bereitschaft zu synchronisieren. Das Prinzip ist einfach, eine TCP Übertragung beginnt immer erst mit der Nachfrage ob der Empfänger bereit ist (SYN). Der Empfänger sendet ein entsprechendes Signal (SYN.ACK) und erst nachdem dieses Signal erhalten wurde startet TCP die Übertragung der Segmente.

TCP ist streamorientiert, d.h., daß es seine Daten als kontinuierlichen Datenstrom ansieht. Durch die Verwendung von Sequenznummern kann das empfangende TCP die Segmente wieder in richtiger Reihenfolge zusammenbauen und sie wieder zu einem Datenstrom formieren.

Die Anwendungsschicht
Auf dieser Schicht laufen die Anwendungen, die übers Netz miteinander kommunizieren. In der Regel handelt es sich hier um Client/Server Paare, also um zwei verschiedene Programme, eins, das einen Dienst anbietet (server), ein anderes, das diesen Dienst in Anspruch nimmt (client).

Damit diese Anwendungen sich nicht gegenseitig stören, hat jede Anwendung eine eigene Portnummer. Sie dient als Adresse, an die die Transportschicht einen Datenstrom oder eine UDP-Meldung weiterleitet.

Die wichtigsten Portnummern sollte man parat haben, um die LPI102-Prüfung abzulegen. Es sind

Port Protokoll Transportprotokoll Beschreibung
20 FTP-Data TCP Datenkanal einer FTP-Verbindung.
21 FTP TCP Kontrollkanal einer FTP-Verbindung.
22 SSH TCP oder UDP SecureShell (Verschlüsselter Login)
23 TELNET TCP Terminal Emulation over Network
25 SMTP TCP Simple Mail Transfer Protocol
53 DNS TCP oder meist UDP Nameserver
80 WWW/HTTP meist TCP oder UDP Hypertext Transfer Protokoll
110 POP3 TCP oder UDP Post Office Protocol zum Holen von Mails
119 NNTP TCP Net News Transfer Protocol
139 NetBIOS-SSN TCP oder meist UDP Windows Netzwerk Sitzungsdienste
143 IMAP2 TCP oder UDP Interim Mail Access Protocol (verschlüsselt)
161 SNMP UDP Simple Network Management Protocol

Programme in diesem Zusammenhang
Die geforderten Kenntnisse der ganz oben genannten Programme dient zunächst nur dafür, zu wissen, wozu welches Programm benutzt werden kann. Hier jeweils eine kurze Beschreibung über die Programme und ihre Anwendung:

ping
Das Programm ping benutzt das ICMP-Protokoll um herauszufinden, ob ein Rechner im Netz verfügbar ist. Dazu sendet es eine ICMP-Meldung (Typ 8) an den Zielrechner. Der Zielrechner gibt dann eine Kopie des Paketes mit dem Typ 0 (pong) zurück. Das wieder ankommende Paket wird auf die Standard-Ausgabe geschrieben. ping sendet ohne Unterlass weiter, bis es mit Strg-C abgebrochen wird.

Um ping von vorneherein auf eine bestimmte Anzahl von Paketen zu beschränken, gibt es den Parameter -c, mit dem die Anzahl der zu sendenden Pakete angegeben werden kann:

ping -c4 foo.bar.com

sendet 4 Pakete an den Rechner foo.bar.com. Wenn ping mindestens eine Antwort erhält, so gibt es in diesem Fall eine 0 zurück, ansonsten einen Wert ungleich 0. Somit kann ping auch in Scripts benutzt werden, um festzustellen, ob ein bestimmter Rechner verfügbar ist.

traceroute
Das Programm traceroute ermöglicht es, genau zu bestimmen, über welche Gateways ein Paket zu einem Zielrechner geroutet wird. Es schickt ein Paket an den nächsten Gateway (unsere default route), das das Lebensdauerfeld auf 0 gesetzt hat. Der Gateway schickt daraufhin eine ICMP-Fehlermeldung Typ 11 (time-exceeded) an uns zurück. Anschließend wird das selbe Paket mit einer Lebensdauer von 1 geschickt. Jetzt bleibt es beim nächsten Gateway hängen, auch der schickt eine ICMP-Typ 11 Fehlermeldung zurück. So wird die Lebensdauer jedesmal um eins erhöht und das Paket kommt so immer einen Gateway weiter. Aus den Fehlermeldungen der Gateways werden ihre IP-Adressen extrahiert und auf die Standard-Ausgabe geschrieben. Das Ganze wird solange wiederholt, bis der Zielrechner erreicht ist.

Der einzig nötige Parameter für traceroute ist der Name oder die IP-Adresse des Zielrechners.

host
Das Programm host wird benutzt, um Nameserverabfragen direkt von der Kommandozeile aus vorzunehmen. Es kann über sehr viele Kommandozeilenparameter genau eingestellt werden, wie und was gesucht werden soll. Der einzig notwendige Parameter ist der gesuchte Domainnamen. Die Antwort besteht in diesem Fall aus seiner IP-Adresse.

Wird statt einem Domainnamen eine IP-Adresse eingegeben, so wird umgekehrt der passende Domainnamen ausgegeben, sofern er existiert und ermittelbar ist.

Wenn nicht nur die Information über die IP-Adresse eines Domainnamens gesucht wird, kann der Parameter -a angegeben werden, der alle verfügbaren Informationen über einen Rechner anfordert und darstellt.

dig, nslookup, nsquery
Auch diese Programme machen Nameserverabfragen. Sie unterscheiden sich in ihren Fähigkeiten und ihrer Anwendung. So bietet beispielsweise nslookup eine interaktive Abfrageshell. dig ist in der Lage auch komplexe Probleme zu lösen, so kann zum Beispiel die aktuelle Liste aller Root-Nameserver mit dem Befehl

dig . ns

erfragt werden oder dig kann eine Liste aller Nameserver für eine bestimmte Zone erfragen. An sich werden alle vier Programme (host, dig, nslookup und nsquery) im Alltag dazu benutzt, explizit einen Nameserver abzufragen.

whois
whois sendet eine Nachfrage an eine RFC-812 Datenbank. In einer solchen Datenbank werden die Daten von Domaininhabern abgelegt. So kann mit whois herausgefunden werden, wer eine bestimmte Domain registriert hat, wer der Administrator davon ist usw. Die Menge der Ausgaben wird entweder durch die entsprechende Datenbank vorgegeben oder es wird über Kommandozeilenparameter genau angegeben, welche Information gesucht wird.

Im einfachsten Fall wird whois nur mit dem Parameter der Domain aufgerufen, über die Informationen erfragt werden sollen:

whois lpi.org

gibt als Ausgabe

Registrant:
Linux Professional Institute Inc.
78 Leander St.
Brampton, ON L6S 3M7
CA

Domain Name: LPI.ORG

Administrative Contact:
Silberman, Wilma nic@lpi.org
78 Leander St.
Brampton, ON L6S 3M7
CA
(905) 874-4822

Technical Contact:
starnix, DNS dns@starnix.com
175 Commerce Valley Dr. W.
Thornhill, ON L3T 7P6
CA
(416) 410-9342

ftp
Das File Transfer Protokoll dient zur Übertragung von Dateien über das Netzwerk. Es nutzt die TCP-Ports 21 (Kommandokanal) und 20 (Datenkanal) um über TCP/IP Dateien von einem Rechner zum anderen zu kopieren. Auch hier gibt es unter Unix Befehle (rcp), die besser auf das System abgestimmt sind, aber auch hier gilt, in heterogenen Netzen hat FTP den Vorteil.

Wie bei Telnet, so gibt es auch hier einen Server (ftpd) und einen Client (ftp, xftp, Netscape), die miteinander kommunizieren. Früher war es üblich, mit der FTP-eigenen Kommandosprache zu arbeiten, heute gibt es graphische Frontends, die FTP wesentlich konfortabler machen.

FTP besitzt zwei Übertragungsmodi, Text und Binärformat. Heute ist es üblich, alle Übertragungen im Binärformat vorzunehmen, es entstehen so weniger Probleme beim Umgang mit Textdateien, die 8 Bit Zeichensätze verwenden (Umlaute…).

Die klassische Art, FTP zu nutzen war interaktiv, mit der FTP-eigenen Kommandosprache. Dabei war fast der Eindruck einer kleinen Terminalsitzung zu erahnen, um sich im Dateibaum zu bewegen und dort Dateien zu kopieren. Die wichtigsten Befehle von FTP sind:

open Hostname
Stellt eine Verbindung zum gewünschten Host her. Dabei wird ein Passwort abgefragt.
close
Schließt eine bestehende Verbindung.
dir
Zeigt das aktuelle Inhaltsverzeichnis.
cd Verzeichnis
Wechselt in das angegebene Verzeichnis.
lcd Verzeichnis
Wechselt das Verzeichnis auf der Client Seite (local change dir).
pwd
Print Working Dir – gibt das aktuelle Verzeichnis an.
get Datei
Kopiert eine Datei vom Server zum Client.
put Datei
Kopiert eine Datei vom Client zum Server.
del Datei
Löscht eine Datei auf dem Server.
binary
Wechselt in den Binärmodus.
ascii
Wechselt in den Textmodus.
quit
Beendet FTP.

Moderne FTP-Clients wie Netscape oder xftp steuern diesen Vorgang über eine graphische Benutzeroberfläche, die den Umgang mit ftp stark vereinfacht.

Eine große Bedeutung im Internet hat anonymes FTP (ohne Username und Passwort), das als Möglichkeit verwendet wird, um Public-Domain-Software downzuloaden.

telnet
Telnet (Terminal EmuLation over NETwork) dient dazu, Zugriff auf einen, am Netz angeschlossenen Rechner in Form einer Terminalsitzung zu liefern. Auf Unix-Systemen läuft auf der Clientseite das Programm telnet, auf der Serverseite ein Daemon namens telnetd. Der Telnet-Service liegt auf dem TCP-Port 23.

Auf Unix-Systemen wird heute das Kommando rlogin verwendet, das in etwa die gleiche Funktionalität besitzt, wie Telnet, dabei aber die Unix Eigenheiten besser unterstützt. In heterogenen Umgebungen, die nicht nur aus Unix-Systemen bestehen ist Telnet aber flexibler. Sicherer ist allerdings die Anwendung von ssh statt Telnet, da es die gesamte Kommunikation (inklusive der Login-Prozedur und Passwortübergabe) verschlüsselt abwickelt. Telnet überträgt alles, auch das Passwort unverschlüsselt.

Eine Telnetsitzung wird gewöhnlich durch den Client mit dem Befehl

telnet Hostname

gestartet. Das Programm stellt dann eine TCP-Verbindung mit dem gewünschten Host her und kommuniziert dort mit dem Telnet-Daemon telnetd. Dieser Daemon stellt jetzt ein sogenanntes Pseudo-Terminal (oder auch Network Virtual Terminal – NVT) zur Verfügung. Dieses Terminal lässt sich genauso steuern, wie eine Unix-Konsole, so daß auch bildschirmorientierte Programme via Telnet benutzt werden können (z.B. vi, mc, …)

1.111.6 – Verwalten der Systemzeit

zurück zu Linux Zertifizierungen LPIC
Prüfungskandidaten sollten in der Lage sein, die Systemzeit richtig zu verwalten und die Uhr über NTP zu synchronisieren. Dieses Lernziel beinhaltet das Setzen von Systemdatum und -zeit, das Setzen der BIOS-Uhr auf die korrekte Zeit in UTC, die Konfiguration der korrekten Zeitzone des Systems und die Konfiguration der automatischen Korrektur der Zeit auf die NTP-Uhr.

Die wichtigsten Dateien, Bezeichnungen und Anwendungen:

* date
* hwclock
* ntpd
* ntpdate
* /usr/share/zoneinfo
* /etc/timezone
* /etc/localtime
* /etc/ntp.conf
* /etc/ntp.drift

Linux arbeitet mit zwei verschiedenen Uhren, die beide eine große Rolle spielen, die Hardware-Uhr (oder auch RTC, RealTimeClock, CMOS-Uhr, BIOS Uhr) und die Systemzeit. Um mit Linux und der Uhrzeit korrekt umzugehen müssen diese beiden Systeme genau unterschieden werden.

Die Hardware-Uhr ist ein Uhrenbaustein, der völlig unabhängig vom verwendeten Betriebssystem arbeitet. Es handelt sich um eine batteriegepufferte Uhr, die also selbst dann arbeitet, wenn der Computer ausgeschaltet (und von der Stromversorgung getrennt) ist.

Die Systemuhr von Linux ist eine Software-Uhr, die ein Teil des Linux-Kernel ist und durch einen regelmäßigen Timer-Interrupt gesteuert wird. Diese Software-Uhr zählt die Sekunden, die seit dem 1. Januar 1970 um 0:00 Uhr vergangen sind.

Unter Linux zählt nur die Systemzeit, also die kernelgesteuerte Software-Uhr. Der einzige Punkt, wo die Hardware-Uhr ins Spiel kommt ist der Moment des Systemstarts, wo die Systemzeit gestellt werden muß. Hier wird die Hardware-Uhr gelesen und die Systemzeit entsprechend eingestellt. Danach wird die Hardware-Uhr nicht weiter benutzt bis zum nächsten Systemstart.

Es gibt im Wesentlichen zwei Programme, die benutzt werden um auf die beiden Uhren zuzugreifen:

* date
Anzeigen und Stellen der Systemzeit
* hwclock
Anzeigen und Stellen der Hardware-Uhr

Bei Unix/Linux-Systemen bestehen jetzt zwei grundsätzliche Möglichkeiten, wie die Uhr gestellt werden sollte. Zum einen können wir die Uhr einfach nach der lokalen Zeit stellen, zum anderen haben wir die Möglichkeit, die Hardware-Uhr (und damit auch die Systemzeit) nach der UTC (Greenwich Mean Time) zu stellen und uns anhand einer entsprechenden Zeitzoneninformation die lokale Zeit daraus ausrechnen zu lassen. Diese zweite Möglichkeit ist heute die, der im Allgemeinen der Vorzug gegeben wird. Auch die Lernziele der LPI102 Prüfung zielen auf diese zweite Möglichkeit ab, also werden wir uns entsprechend daran halten.

Der Vorgang ist eigentlich ganz einfach. Wir stellen die Hardware-Uhr manuell (über das BIOS-Setup) auf Greenwich-Zeit und weisen der Umgebungsvariable TZ (TimeZone) den Wert zu, der unsere lokalen Zeitzone entspricht. Das verbreitete Shellscript tzselect bietet eine Auswahlmöglichkeit für die zur Verfügung stehenden Zeitzonen. In einigermaßen modernen Linuxen besteht zudem die Möglichkeit, in der Datei /etc/timezone die aktuelle Zeitzone einzutragen.

Die moderne Standard-Library von Linux kennt noch eine genauere Methode. Im Verzeichnis /usr/share/zoneinfo befinden sich binäre Informationsdateien für jede Zeitzone der Welt (inkl. Antarktis). Im Verzeichnis /etc kann jetzt ein symbolischer Link mit Namen localtime angelegt werden, der auf die entsprechende Zonendatei zeigt, also z.B. für Deutschland

ln -s /usr/share/zoneinfo/Europe/Berlin /etc/localtime

Um das zu vereinfachen existiert auf vielen Linuxen ein Script mit Namen tzconfig, das genau die Zeitzone abfrägt und anschließend den Link erstellt.

Ist die Zeitzone richtig eingestellt, so verhalten sich alle Linux-Programme, die mit Uhrzeiten arbeiten, automatisch korrekt. Jetzt können wir z.B. auch unsere Hardware-Uhr oder die Systemzeit stellen und die Programme hwclock und date rechnen aus der angegebenen Lokalzeit und der Information der Zeitzone die Greenwich-Zeit aus und stellen die Uhren entsprechend.

Damit Linux jetzt weiß, daß unsere Hardware-Uhr (und die Systemuhr) auf UTC (Greenwich) eingestellt ist, benutzen wir wieder das Programm hwclock. In einem Init-Script sollte die Anweisung

hwclock –utc –hctosys

stehen. (Falls die Uhr aber auf lokaler Zeit steht sollte statt –utc eben –localtime eingetragen sein)
date
Der Befehl date ist der normale Weg, wie auf die Systemzeit von Unix zugegriffen werden kann. Er bezieht sich aber immer auf die Systemzeit und nicht auf die CMos-Uhr (RTC Real-Time-Clock).

Als einfachste Form der Anwendung kann date einfach ohne Parameter aufgerufen werden. Dann gibt er die Systemzeit in einem String der Form

Sat Aug 21 14:17:40 MEST 1999

auf die Standard-Ausgabe aus. Das ist aber, gerade für Nicht-Amerikaner, nicht immer die gewünschte Form. Aus diesem Grund bietet date auch die Möglichkeit, eine beliebige Ausgabeform für ein Datum zu erstellen.

Wenn date einen Parameter erhält, der mit einem Pluszeichen (+) beginnt, so interpretiert es die folgende Zeichenkette und ersetzt bestimmte Elemente darin mit den entsprechenden Werten der Systemzeit.

Diese interpretierten Elemente beginnen immer mit einem Prozentzeichen (%) dem ein Buchstabe folgt. So bedeutet etwa das %H die Stunden im 24 Stunden-Modus, %M die Minuten. Wenn wir also nur wissen wollen, wie spät es gerade ist, könnten wir schreiben:

date “+Es ist jetzt %H Uhr und %M Minuten”

Die Anführungszeichen sind nötig, weil in unserer Zeichenkette Leerzeichen enthalten sind. Die Ausgabe des Befehls wäre jetzt etwas in der Art:

Es ist jetzt 14 Uhr und 25 Minuten

Eine genaue Darstellung aller unterstützter Parameter ist in der Handbuchseite aufgeführt.

Der Systemverwalter kann mit dem Befehl date auch die Systemuhr stellen, allerdings wird nur die Systemzeit, nicht die CMos-Zeit verändert. Dazu gibt es zwei Möglichkeiten:

1. Dem Kommando date folgt ein Parameter in der Form MMDDhhmm, also eine Zeichenkette, deren erste zwei Zeichen die Monatszahl (01-12) enthält, die nächsten zwei den Tag des Monats (01-31), die nächsten die Stunden (00-23) und die letzten die Minuten (00-59). Optional kann die Zeichenkette auch noch eine zwei oder vierstellige Jahreszahl und danach, durch einen Punkt getrennt die Angabe der Sekunden (zweistellig) enthalten. (MMDDhhmmYYYY.ss)
2. Das Kommando date wird mit dem Schalter -s und einem darauffolgendem Datum der Art “Sat Aug 21 14:17:40 MEST 1999” aufgerufen. Das macht in der Regel nur dann einen Sinn, wenn vorher das date-Programm benutzt wurde um diese Zeit abzuspeichern, oder wenn ein date eines Rechners benutzt wird, die Uhren anderer Rechner zu stellen.

Verlässlichere Uhren
Sowohl die Hardware-Uhr, als auch die kernelbasierte Systemuhr sind nicht besonders verlässlich. Zwar bietet die Systemuhr die Möglichkeit über ausgeklügelte Mechanismen wie die Datei /etc/adjtime die Genauigkeit der Zeit zu erhöhen, aber eine wirklich hundertprozentige Zeit ist das auch nicht. Gerade aber bei Servern, die monatelang laufen, summiert sich auch eine kleine Ungenauigkeit auf eine störende Größenordnung. Aus diesem Grund gibt es ein spezielles Protokoll, das eine Synchronisation der Zeit über das Netz ermöglicht: das Network Time Protocol (NTP).

Damit NTP aber vernünftig arbeiten kann, benötigt es eine verläßliche Quelle für die Uhrzeit. Ein NTP-Server wird in der Regel eine Funkuhr besitzen, die eine absolut genaue Uhrzeit für den Rechner zur Verfügung stellt. Diese genaue Zeit kann er jetzt an NTP-Clients weitergeben.

Der Haken an dieser Sache ist, daß Pakete, die über das Netz transportiert werden, auch eine bestimmte Zeit benötigen, von einem Rechner zum anderen zu kommen. In einem lokalen Netz ist dieser Wert vernachlässigbar, im Internet können schon einige Sekunden zusammenkommen, je nach aktueller Verbindungsqualität und der Anzahl der Router, die zwischen den beiden Kommunikationspartnern liegen.

NTP hat auch für diese Frage eine Lösung parat. In der Regel werden nicht nur ein, sondern mehrere Server im Internet als Zeitquelle benutzt. Zu jedem Server wird eine Verbindung aufgebaut, und der Client errechnet sich aktuell, wieviel Zeit eine solche Verbindung dauert. Dazu sendet er eine Anfrage und wartet auf die Antwort. Er misst die entsprechend vergangene Zeit und errechnet sich so ein Mittel der Dauer, die ein Paket vom NTP-Server zu ihm benötigt. So kann er – mit mehreren Servern – auf eine Genauigkeit im Millisekundenbereich kommen, was völlig ausreicht, da unsere Uhr als kleinste Einheit sowieso mit Sekunden arbeitet.

Grundsätzlich geht es in diesem Zusammenhang nicht um den Aufbau eines NTP-Servers, der mit einer Funkuhr ausgestattet ist, sondern um die Anbindung eines Clients an einen existierenden Server. Diese Aufgabe ist sehr einfach zu realisieren, es gibt aber zwei verschiedene Möglichkeiten, einer solchen Anbindung:

* Anbindung über einen ständig laufenden Daemon-Prozess mit ntpd
* Anbindung über einen cron-gesteuerten Aufruf von ntpdate

Beide Möglichkeiten arbeiten mit dem NTP-Protokoll, aber im ersten Fall arbeitet unser Rechner auch als Server, während er im zweiten Fall nur Client ist.
Zeitsynchronisation mit ntpdate
Wenn es nur gewünscht ist, eine regelmäßige Anpassung der Uhrzeit über einen bestehenden Zeitserver vorzunehmen, so genügt es, mit dem Programm ntpdate die Uhrzeit eines öffentlichen Zeitservers einzuholen. In diesem Fall kann unsere Systemzeit vollkommen verstellt sein, die Uhrzeit (und das Datum) werden einfach vom genannten Server übernommen. Der Aufruf lautet:

ntpdate Zeitserver

wobei der Zeitserver entweder über seinen Namen oder seine IP-Adresse angegeben werden kann. Eine Liste öffentlicher Zeitserver im Internet ist unter https://www.eecis.udel.edu/~mills/ntp/clock1.htm erhältlich.

Natürlich bietet es sich an, diesen Aufruf regelmäßig über cron vorzunehmen. Ein entsprechender Eintrag in /etc/crontab könnte also lauten:

12 * * * * root /usr/sbin/ntpdate ntp3.fau.de

Damit würde einmal stündlich (jeweils um 12 Minuten nach der vollen Stunde) die aktuelle Uhrzeit vom Server ntp3.fau.de (einem öffentlichen Zeitserver der Universität Erlangen) geholt und die Systemzeit danach gestellt.
Zeitsynchronisation mit ntpd
Komplexer ist die Aufgabe, die Zeit über einen Daemon zu stellen. Der ntpd oder auch xntpd ermöglicht diese Form der Synchronisation. Der Daemon synchronisiert sich alle 5 Minuten mit einem oder mehreren Zeitservern oder einer lokalen Funkuhr. Seine Konfiguration erhält er über die Datei /etc/ntp.conf. In dieser Datei stehen im einfachsten Fall nur zwei Einträge:

server ntp3.fau.de
driftfile /etc/ntp.drift

Die erste Zeile bestimmt den verwendeten Zeitserver, von dem regelmäßig (alle 5 Minuten) die Zeit geholt werden soll. Die zweite Zeile bestimmt eine Datei, die ntpd selbst anlegt und in der die Abweichung der Systemzeit zur realen Zeit gespeichert wird. ntpd ermittelt über Stunden hinweg die Ungenauigkeit der lokalen Zeit und ermittelt einen Wert der Ungenauigkeit in PPM (Parts per Million), der als einfache Fließkommazahl in der Datei /etc/ntp.drift abgelegt wird. Bei jedem Neustart von ntpd kann dann mit diesem Wert gerechnet werden.

Bei der Verwendung von ntpd als Daemon haben wir jetzt neben einer genauen Uhrzeit die Möglichkeit, selbst als Zeitserver für lokale Clients aufzutreten.

Im Gegensatz zur Verwendung von ntpdate darf die Systemzeit unseres Rechners aber nie wirklich größere Abweichungen enthalten. Sobald unsere lokale Zeit mehr als 1000 Sekunden Verschiebung zur Zeit des Servers enthält, weigert sich ntpd die Zeit tatsächlich zu stellen, sondern fordert (in einer Syslog-Meldung) dazu auf, die Zeit manuell zu stellen.

Es ist nicht möglich, beide Techniken auf einmal zu betreiben. Ein Versuch, ntpdate aufzurufen, obwohl ein lokaler ntpd-Prozess läuft, endet mit der Fehlermeldung:

13 Aug 14:37:05 ntpdate[3209]: the NTP socket is in use, exiting

Beide Programme benutzen den selben Socket, können also nicht nebeneinander existieren. Es ist aber sehr wohl möglich, im entsprechenden init-Script, das ntpd starten soll, einen Aufruf von ntpdate vor dem Aufruf des Daemons zu veranlassen, um sicherzustellen, daß die Systemzeit keine zu große Abweichung aufweist.

1.111.5 – Datensicherungsstrategie

zurück zu Linux Zertifizierungen LPIC
1.111.5 – Aufrechterhaltung einer effektiven Datensicherungsstrategie
Prüfungskandidaten sollten in der Lage sein, eine Sicherungsstrategie zu planen und Dateisysteme automatisch auf verschiedene Medien zu sichern. Die Tätigkeiten beinhalten das Sichern einer rohen Partition in eine Datei oder umgekehrt, das Durchführen teilweiser und manueller Backups, das Überprüfuen der Integrität von Backupdateien und teilweises oder vollständiges Wiederherstellen von Backups.

Die wichtigsten Dateien, Bezeichnungen und Anwendungen:

* cpio
* dd
* dump
* restore
* tar

Dieser Abschnitt der LPI102 Prüfung erfordert nicht nur das Wissen um die konkrete Syntax einzelner Befehle, sondern auch die grundsätzliche Architektur von Backup-Strategien. Backups werden heute mit den unterschiedlichsten Programmen erstellt und auf unterschiedlichsten Medien abgelegt. Die genaue Syntax aller hier denkbarer Programme ist sicherlich etwas, was den Rahmen sowohl der LPI-Prüfung, als auch dieser Darstellung sprengen würde. Die wichtigsten Bordmittel werden aber hier genau besprochen.

Vorüberlegungen
Grunsätzlich ist zu sagen, daß ein Backup auf jedem Rechner notwendig ist, dessen Dateien nicht rein statisch sind. Ein Rechner, der etwa nur als Router ins Internet Dienst tut, muß sicherlich kein regelmäßiges Backup ausführen, hier würde die einmalige Sicherung nach der abschließenden Konfiguration ausreichen. Jeder Rechner, auf dem gearbeitet wird, dessen Dateien also nicht statisch sind, muß aber regelmäßige Backups erledigen, um die getane Arbeit zu sichern. Wie im einzelnen die Backups aussehen, was gesichert wird, das muß gründlich geplant werden.

Ein wesentliches Kriterium für ein Backup ist die Frage, auf welches Medium die gesicherten Daten gespeichert werden sollen. Es bietet sich grundsätzlich an, Wechselmedien zu benutzen, die an einem anderen Ort gelagert werden können. Wird ein Backup nur auf eine zweite Platte im Rechner gemacht, so haben wir vielleicht eine Absicherung gegen eine physikalische Zerstörung der Platte (Headcrash), Feuerschäden, Wasserschäden oder Diebstahl des Rechners würde diese Form des Backups nicht abdecken, die Daten wären verloren.

Wechselmedien stehen in verschiedenen Formen zur Verfügung. Neben Wechselplatten, die auf der Festplattentechnik beruhen, sind es meist Bandlaufwerke, die für Backups verwendet werden. Hier spielen drei wesentliche Familien eine Rolle, Viertelzoll-Cartridges (QIC), DAT-Cassetten und Videobänder.

Die Speicherkapazität eines Backup-Mediums ist von großer Bedeutung. Muß das Medium während des Backups gewechselt werden, weil es nicht genügend Speicherplatz aufweist, so kann ein Backup nicht vollständig automatisiert werden. Der Aufwand (und damit auch die Hemmschwelle) ist wesentlich größer, als bei einem Medium, das das ganze Backup in einem Rutsch aufnehmen kann.

Die Frage, was überhaupt gesichert werden muß, ist die nächste Überlegung. Wir unterscheiden zwischen verschiedenen Backup-Strategien. Insbesondere zwei Begriffe werden hier immer wieder fallen: volles Backup und inkrementelles Backup.

Ein Vollbackup ist ein Backup, das alle Daten, die gesichert werden müssen, in einem Arbeitsgang auf ein Medium speichert. Ein inkrementelles Backup speichert im Gegensatz dazu nur die Daten, die sich seit dem letzten Backup verändert haben. Ein inkrementelles Backup ist nur in Zussammenarbeit mit einem Vollbackup möglich!. Abhängig von der Sicherheitsanforderung kann z.B. überlegt werden, jeden Tag der Woche ein inkrementelles Backup vorzunehmen, und Freitags ein Vollbackup. Das bedingt aber, daß alle Medien, die diese Backups aufgenommen haben, zu einer Wiederherstellung (restore) der Daten benötigt werden.

Nehmen wir ein Beispiel: Wir haben folgenden Backup-Plan:

* Montag – inkrementelles Backup – Band 1
* Dienstag – inkrementelles Backup – Band 2
* Mittwoch – inkrementelles Backup – Band 3
* Donnerstag – inkrementelles Backup – Band 4
* Freitag – volles Backup – Band 5

Es ist jetzt Mittwoch, wir haben einen Headcrash, der uns zwingt, alle Daten auf eine neue Platte aufzuspielen. Wie müssen wir vorgehen?

Die Reihenfolge des Wiederaufspielens ist hier wichtig. Wir brauchen:

* Das Band mit dem letzten Vollbackup (Band 5)
* Die Bänder der letzten inkrementellen Backups vom letzten Vollbackup bis zum Eintreten der Katastrophe. Also in unserem Beispiel die Bänder von Montag und Dienstag (Band 1 und 2)

Das Wiederaufspielen muß jetzt in genau der Reihenfolge passieren, wie das Backup selbst. Zunächst spielen wir die Daten des Vollbackups wieder auf die Platte, dann die des Montag-Bandes und erst dann die des Dienstag-Bandes. Nur so stellen wir sicher, daß wir nicht alte Versionen von Dateien aufspielen, die die neueren wieder überschreiben…

Das ist ein aufwendiges Verfahren, das in der Praxis selten vorkommt. Um variabel mit Kombinationen von vollen und inkrementellen Backups arbeiten zu können, werden sogenannte Backup-Level definiert. Dabei wird ein Vollbackup immer Level 0 genannt, ein inkrementelles Backup hat dann Levelnummern größer als 0. Jedes inkrementelle Backup, egal welche Levelnummer es trägt, sichert immer alle Daten, die sich seit dem letzten Backup mit einer Nummer niedriger verändert haben. Ein Beispiel:

* Erster Montag des Monats
Level 0 (Vollbackup)
* Jeder andere Montag
Level 1 (wöchentliches inkrementelles Backup relativ zu Level 0)
* Dienstag
Level 2 (tägliches inkrementelles Backup relativ zu Level 1)
* Mittwoch
Level 2 (tägliches inkrementelles Backup relativ zu Level 1)
* Donnerstag
Level 2 (tägliches inkrementelles Backup relativ zu Level 1)
* Freitag
Level 2 (tägliches inkrementelles Backup relativ zu Level 1)

In diesem Fall brauchen wir für ein Wiederherstellen (restore) der Daten immer nur das aktuellste Band von jedem Level. Da jeder Level über 0 immer alle Daten sichert, die seit dem letzten Backup des vorgehenden Levels verändert wurden hat z.B. das Donnerstagsband immer auch die Daten gespeichert, die am Mittwoch verändert wurden. Es speichert ja alle Daten, seit dem letzten Backup mit niedrigerer Nummer, also seit Montag.

Zum Wiederherstellen der Daten nach einer Katastrophe am Freitag brauchen wir also

* Das letzte Vollbackup (Level 0)
* Das letzte inkrementelle Wochenbackup (Level 1)
* Das letzte inkrementelle Tagesbackup vom Donnerstag (Level 2)

Das Wiederaufspielen der Daten erfolgt jetzt in genau dieser Reihenfolge; zuerst das Vollbackup, dann Level 1 und erst dann Level 2. Jetzt ist garantiert, daß immer die aktuellsten Versionen der Dateien wiederaufgespielt sind.
Planung von Backups
Bei der Planung einer Backup-Strategie müssen ein paar Fragen durchüberlegt werden, deren Beantwortung das Backup leichter planbar machen. Wenn wir schon bei der Planung der Architektur des ganzen Systems auf solche Kriterien achten, können wir uns das Leben wesentlich erleichtern.

Die wichtigste aller Fragen ist die, welche Dateien überhaupt gesichert werden müssen. Bei einer vernünftigen Planung eines Systems können einige Teilbereiche des Systems völlig statisch angelegt werden. Das kann seinen Ausdruck dann darin finden, daß ganze Partitionen Read-Only gemountet werden, so daß selbst versehentliche Änderungen nicht möglich sind. Ein Beispiel hierfür ist die Tatsache, daß das /usr-Verzeichnis geradezu dafür gemacht ist, nur lesend eingehängt zu werden. Solche Bereiche können wir einmal – direkt nach der Installation – sichern und müssen sie dann nie wieder in unsere Backup-Überlegungen aufnehmen…

Eine weitere Überlegung beim Aufbau des Systems ist die, wo die User eines Systems Daten ablegen dürfen und wo nicht. Gibt es hier strenge Richtlinien, die etwa festlegen, daß User ihre Daten grundsätzlich nur in ihren Home-Verzeichnissen ablegen dürfen und diese Homeverzeichnisse auf einer separaten Partition liegen, dann ist durch das Backup dieser einen Partition schon der wesentliche Datenbesatz gesichert. Die Daten der User sind auf alle Fälle nicht verloren.

Ein weiterer wichtiger Bereich, der immer Teil des Backups sein sollte, ist der Bereich der Systemkonfigurationsdateien in /etc. Diese Konfiguration ist vielleicht nicht so hochdynamisch wie der Userdatenbereich, aber er enthält doch auch einige Daten, die sich oft verändern können. Neue oder veränderte Passwörter, die gesammte Arbeit der Systemkonfiguration usw. Um zu vermeiden, daß ein zu großer Datenbestand gesichert werden muß, ist es auch möglich, ein Verzeichnis auf einem Dateisystem anzulegen, das regelmäßig im Backup aufgenommen wird (z.B. /home). Dann wird ein Shellscript erstellt, das alle wichtigen Systemkonfigurationen aus /etc dorthin kopiert. Etwas wie

#!/bin/bash

cp /etc/passwd /home/backup
cp /etc/shadow /home/backup
cp /etc/group /home/backup
cp /etc/gpasswd /home/backup
cp /etc/fstab /home/backup

Dieses Script sollte jetzt täglich von cron aufgerufen werden. Damit ist sichergestellt, daß die wichtigsten Konfigurationsdateien ins Backup aufgenommen sind.

Backup mit dump
Das Programm dump bietet alle Funktionalität, um entweder ganze Dateisysteme (Partitionen) oder einzelne Verzeichnisse in ein Backup aufzunehmen. Die ursprüngliche Version von dump kommt aus der BSD Unix Welt, das Linux-Dump Programm ist aber eine eigene Version, die speziell für das EXT2 Dateisystem geschrieben wurde. Es gibt heute aber auch schon Versionen für weitere Dateisystemtypen, insbesondere für das ReiserFS.

Dump untersucht Dateien eines Dateisystems und entscheidet, welche Dateien in ein Backup aufgenommen werden müssen. Diese Dateien werden dann auf das angegebene Backup-Medium geschrieben, das entweder eine Platte, ein Band oder eine Datei sein kann. (Einstellbar mit der -f Option)

Passt das Backup nicht auf das angegebene Medium, so fordert dump zu einem Medienwechsel auf, und verteilt das Backup auf mehrere solcher Medien.

Dump unterstützt 10 Backup-Level (0-9), wobei wie oben beschrieben das Level 0 ein Vollbackup meint und jedes weitere Level ein inkrementelles Backup relativ zum letzten Backup des nächst-niedrigeren Levels bedeutet. Die grundsätzliche Aufrufform von dump ist

dump [-Level] [-u] [-f Backupdatei] Dateisystem

oder

dump [-Level] [-u] [-f Backupdatei] Verzeichnis

Wobei meist also zuerst das Backup-Level angegeben wird (0-9), gefolgt von einem u (update /etc/dumpdates). Mit der Anweisung -f Backupdatei wird das Medium gewählt. Hier steht also entweder eine Gerätedatei des verwendeten Bandlaufwerks oder ein Dateiname, der Datei, die das Backup aufnehmen soll. Die abschließende Angabe des Dateisystems oder Verzeichnisses gibt an, was gesichert werden soll.

Passt das Backup nicht auf das angegebene Medium, so fordert dump zu einem Medienwechsel auf, und verteilt das Backup auf mehrere solcher Medien.

Dump unterstützt 10 Backup-Level (0-9), wobei wie oben beschrieben das Level 0 ein Vollbackup meint und jedes weitere Level ein inkrementelles Backup relativ zum letzten Backup des nächst-niedrigeren Levels bedeutet. Die grundsätzliche Aufrufform von dump ist

dump [-Level] [-ua] [-f Backupdatei] Dateisystem

oder

dump [-Level] [-ua] [-f Backupdatei] Verzeichnis

Wobei meist also zuerst das Backup-Level angegeben wird (0-9), gefolgt von einem u (update /etc/dumpdates) und einem a, das die automatische Bandendeerkennung aktiviert. Dieses -a Argument ist bei modernen Bandlaufwerken besser als die Kalkulation, wieviel Daten auf das Band passen und wann es gewechselt werden muß. Bei der Verwendung von Dateien als Medium ist es unabdingbar diese Option zu setzen! Mit der Anweisung -f Backupdatei wird das Medium gewählt. Hier steht also entweder eine Gerätedatei des verwendeten Bandlaufwerks oder ein Dateiname, der Datei, die das Backup aufnehmen soll. Die abschließende Angabe des Dateisystems oder Verzeichnisses gibt an, was gesichert werden soll.

Die Datei /etc/dumpdates speichert die Daten alle bisherigen Backups in der Form:

/dev/hda8 0 Sat May 5 21:56:49 2001
/dev/hda8 1 Mon May 7 21:55:58 2001

Hier zeigt sich also, daß die Partition /dev/hda8 am Samstag, den 5. Mai 2001 um 21:48 Uhr ein Vollbackup (Level 0) erhalten hat, während am darauffolgenden Montag ein inkrementelles Backup (Level 1) ausgeführt wurde.

Der Aufruf

dump -0ua -f /dev/tape /dev/hda8

hatte das erste dieser beiden genannten Backups erstellt, das zweite wurde mit

dump -1ua -f /dev/tape /dev/hda8

erstellt.

Es sei hier an dieser Stelle noch einmal ausdrücklich an die Datei /etc/fstab erinnert, deren fünftes Feld die Frage klärt, ob die jeweilige Partition von dump bearbeitet werden soll, oder nicht.
Daten wiederherstellen mit restore
Das Gegenstück zum Programm dump ist restore, mit dem sich Daten von einem Backup-Medium wiederherstellen lassen. Dieses Programm hat sehr viele verschiedene Anwendungen, die alle mit Kommandozeilenparametern einstellbar sind. Die wichtigsten Aktionen für die wir dieses Programm brauchen sind nicht nur das Wiederherstellen von Daten, sondern auch der Vergleich eines Backups mit dem Orginaldatenbestand. Damit können wir bei wichtigen Backups die Konsistenz des Backups überprüfen.

Wichtige Aufrufformen von restore sind:

restore -C -f Datei

Das Backup, das sich in der Datei (Gerätedatei eines Tapes oder Datei) befindet wird mit dem Orginaldatenbestand verglichen. Eventuell auftretende Unstimmigkeiten werden angezeigt.

restore -i -f Datei

Das Backup, das sich in der Datei (Gerätedatei eines Tapes oder Datei) befindet wird mit einem interaktiven – shellähnlichen – Mechanismus durchwandert. Einzelne Dateien und Verzeichnisse können markiert werden und dann können alle markierten Dateien wiederhergestellt werden. Die wichtigsten Befehle dieser shellähnlichen Oberfläche sind:

cd Verzeichnis
Wechselt in das angegebene Verzeichnis.
ls [Verzeichnis|Datei]
Zeigt den Inhalt eines Verzeichnisses oder den Namen einer Datei. Ist eine Datei zur Wiederherstellung markiert, wird das durch ein * angezeigt.
add Verzeichnis|Datei
Das angegebene Verzeichnis oder die angegebene Datei wird zur Wiederherstellung markiert. Ist es ein Verzeichnis so werden alle darin enthaltenen Dateien auch in die Liste der zu wiederherstellenden Dateien aufgenommen (wenn nicht die -h Option auf der Kommandozeile gesetzt war).
delete Verzeichnis|Datei
Das angegebene Verzeichnis oder die angegebene Datei werden von der Liste der wiederherzustellenden Dateien gestrichen.
extract
Die Dateien und Verzeichnisse, die in der Liste der wiederherzustellenden Dateien aufgelistet sind werden wiederhergestellt.
quit
Das Programm wird beendet.

Zu beachten ist, daß restore beim Widerherstellen die Dateien im aktuellen Verzeichnis auspackt. Sollen also Dateien eines Dateisystems /dev/XXX wiederhergestellt werden, so bietet es sich an, auf die Wurzel dieser Partition zu wechseln.

restore -r -f Datei

Ein komplettes Dateisystem wird wiederhergestellt. Idealerweise ist das Ziel eine leere, frische Partition, in die dann gewechselt wird um den restore-Befehl auszuführen. Also z.B.:

mke2fs /dev/sda1
mount /dev/sda1 /mnt
cd /mnt

restore -r -f /dev/tape

Das ist die beste Lösung nach einem Plattencrash, wenn die orginale Platte zerstört ist und eine neue Platte komplett restauriert werden muß.

restore -x -f BackupDatei Datei1 Datei2 …

Die angegebenen Dateien (Datei1 Datei2 …) werden von dem Backup der Backupdatei (Gerätedatei oder Datei) gelesen und extrahiert. Auch hier wird wieder ins aktuelle Verzeichnis extrahiert. Sind einzelne der angegebenen zu extrahierenden Dateien Verzeichnisse, dann werden diese Verzeichnisse samt aller Dateien darin wiederhergestellt.

Restore ist also das Programm, mit dem alle Bearbeitung der bereits gemachten Backups vorgenommen werden, insbesondere die Wiederherstellung der gesicherten Dateien.

Ist ein Backup auf mehrere Medien verteilt, so fordert restore zum gegebenen Zeitpunkt zum Medienwechsel auf..

Partielle und manuelle Backups mit tar
Um schnell ein Verzeichnis oder ein paar Dateien zu sichern ist die Anwendung von dump und restore sicherlich übertrieben. Hier findet das Programm tar seine Anwendung. tar steht für Tape Archiver, ist also grundsätzlich auch gedacht gewesen, Backups auf Bandlaufwerke zu schreiben. Heute wird tar aber sehr häufig eingesetzt, um Verzeichnisse oder Dateien in eine Archivdatei zu packen, die dann auf anderen Medien abgespeichert werden kann oder auch an andere User weitergegeben werden kann. Vor der Einführung der modernen Paket-Manager (RPM, DPKG) war das tar-Format das bestimmende Format für Linux-Distributionen.

Tar wird sowohl zum Erstellen, als auch zum Entpacken von Archiven benutzt. Es ist also kein zusätzlicher Entpacker wie etwa restore nötig.

Wie schon dump und restore kennt auch tar die Option -f Dateiname mit der angegeben wird, welche Datei als Medium zum Speichern (oder entpacken) des Archivs verwendet werden soll. Auch hier kann entweder eine Gerätedatei eines Bandlaufwerks, eine reguläre Datei oder ein Bindestrich (für StdIn bzw StdOut) angegeben werden.

Tar selbst nimmt keinerlei Komprimierung vor, arbeitet jedoch gerne mit dem gzip-Programm zusammen. Musste man früher die Archivdatei noch manuell komprimieren, so kennt tar heute die Optionen -z (komprimieren oder dekomprimieren mit gzip) und -Z (komprimieren oder dekomprimieren mit compress – veraltet) um selbstständig gleich gepackte Archive zu erstellen oder zu entpacken. Die jeweiligen Programme gzip und compress müssen dazu aber vorhanden sein, tar ruft sie nur auf, es kann selbst keine Kompression vornehmen.

Die normale Endung einer Archivdatei, die mit tar hergestellt wurde heisst in der Regel .tar – wurde das Archiv mit gzip komprimiert trägt es standardmäßig die Endung .tar.gz oder (um auch DOS-konform zu sein) .tgz. Wurde die Archivdatei mit compress komprimiert, so endet ihr Name meist auf .tar.Z

Die drei wichtigsten Funktionen von tar sind

* Erstellen (create) von Archiven (-c)
* Inhaltsverzeichnis (table of content) von Archiven anzeigen (-t)
* Archive entpacken (extract) (-x)

Um ein Archiv mit dem Namen Test.tgz anzulegen, das mit gzip komprimiert ist und alle Dateien des Verzeichnisses Testdir enthält, rufen wir tar folgendermaßen auf:

tar -czf Test.tgz Testdir

Um den Inhalt dieses frisch geschaffenen Archivs anzusehen schreiben wir:

tar -tzf Test.tgz

Und um das Archiv im aktuellen Verzeichnis wieder zu entpacken ist der Befehl

tar -xzf Test.tgz

nötig. Wird zusätzlich noch die Option -v angegeben, so arbeitet tar “geschwätzig” (verbose), gibt uns also mehr Informationen mit. Insbesondere beim Ansehen des Inhaltsverzeichnis ist das eine gute Idee. Aber vorsicht: Der erste Parameter von tar legt die Aktion fest (c oder t oder x), die Parameter v und z folgen beliebig. Der f-Parameter kommt am Schluß, denn ihm folgt der Dateiname.
Archive mit cpio bearbeiten
Anstelle von tar kann auch das Programm cpio verwendet werden, um Archive zu erstellen oder zu bearbeiten. cpio kann dabei verschiedene Formate – unter anderem auch das tar-Format – bearbeiten. Ein großer Vorteil von cpio ist der, daß die Liste der zu archivierenden Dateien nicht auf der Kommandozeile (wie bei tar) erwartet wird, sondern auf der Standard-Eingabe. Dadurch ist es möglich, die Ergebnisse etwa des find-Befehls direkt an cpio weiterzupipen und so ein Archiv mit den Suchergebnissen aufzubauen.

cpio arbeitet in drei verschiedenen Modi:

* copy-out
Dateien werden in ein Archiv geschrieben (out meint die Ausgabe in ein Archiv)
* copy-in
Dateien werden aus einem Archiv extrahiert (in meint die Eingabe ins Dateisystem)
* copy-pass
Dateien werden von einem Ort zu einem anderen kopiert, quasi eine Kombination aus copy-out und copy-in, ohne jedoch tatsächlich ein Archiv zu erstellen.

Durch die Verwendung unterschiedlicher Formate und die Fähigkeit die zu archivierenden Dateien sowohl aus einer Dateiliste, als auch von der Standard-Eingabe zu lesen, ist cpio wesentlich flexibler als tar. Allerdings ist es auch um einiges komplizierter anzuwenden.
Ein- und Ausgabe mit dd
Um Dateien beliebiger Art (in unserem Fall speziell Archivdateien) von und auf Gerätedateien zu kopieren, existiert das sehr nützliche (und sehr häufig verwendete) Programm dd. dd steht für DiskDump und ermöglicht es, Daten von Gerätedateien zu regulären Dateien zu kopieren oder umgekehrt. Es ist natürlich auch möglich, von Gerätedatei zu Gerätedatei zu kopieren. Die grundsätzliche Form ist dabei

dd if=Eingabedatei of=Ausgabedatei bs=Blockgröße count=Anzahl

Dieser Befehl kopiert Anzahl Blöcke der Größe Blockgröße aus der Eingabedatei in die Ausgabedatei. Dabei können sowoh Ein-, als auch Ausgabedatei entweder Gerätedateien oder reguläre Dateien sein. Wird die Angabe der Blockgröße weggelassen, so werden die “natürlichen” Blockgrößen der jeweiligen Geräte verwendet. Wird die Anzahl der zu lesenden Blöcke weggelassen, so werden alle Blöcke der Datei (oder des Gerätes) gelesen. So kann z.B ein komplettes Image einer Festplatte oder Partition (oder Diskette oder CDROM) in eine Datei durch den Befehl

dd if=Gerätedatei_des_Laufwerks of=Imagedateiname

erstellt werden. Mit dem umgekehrten Befehl

dd of=Gerätedatei_des_Laufwerks if=Imagedateiname

wird das entsprechende Image wieder auf das Gerät geschrieben.

Durch die Angabe von ibs= (Input-Blocksize) und obs= (Output-Blocksize) kann sogar noch zwischen verschiedenen Blockgrößen bei Ein- und Ausgabe unterschieden werden.

Zusätzlich kann dd auch noch Konvertierungen der zu kopierenden Blöcke vornehmen, wie etwa die Reihenfolge der Bytes in einem Datenwort oder Klein-Großschreibung.

Für die Backup-Technik ist dd besonders interessant, weil damit Archivdateien direkt auf Band geschrieben werden können oder von Bändern gelesen werden können.

1.111.4 – Systemadministrationsaufgaben

zurück zu Linux Zertifizierungen LPIC
1.111.4 – Automatisieren von Systemadministrationsaufgaben durch Planen von zukünftig laufenden Jobs
Prüfungskandidaten sollten in der Lage sein, cron oder anacron zu verwenden, um Prozesse in regelmäßigen Intervallen ausführen zu lassen, und at zu benutzen, um Jobs zu einer bestimmten Zeit auszuführen. Dies beinhaltet das Verwalten von cron und at Jobs und die Konfiguration von Benutzerzugang zu cron und at Diensten.

Die wichtigsten Dateien, Bezeichnungen und Anwendungen:

* at
* atq
* atrm
* crontab
* /etc/anacrontab
* /etc/at.deny
* /etc/at.allow
* /etc/crontab
* /etc/cron.allow
* /etc/cron.deny
* /var/spool/cron/*

Systemverwaltungsaufgaben bestehen zu einem großen Teil aus immer wiederkehrenden Routinejobs. Diese Routine kann durch Kommandos vereinfacht werden, die automatisch immer wieder in bestimmten Intervallen oder zu bestimmten Zeiten ausgeführt werden. Für diese Aufgabe existiert ein eigener Daemon, der cron-Daemon. Er kann auf verschiedene Weisen konfiguriert werden, die hier genauer beschrieben werden sollen.

Manche Aufgaben sind aber nicht regelmäßig auszuführen, sondern nur genau einmal, aber zu einem ganz bestimmten Zeitpunkt. Diese Aufgabe wird vom at-Daemon gelöst, der genau dazu gemacht ist.

Der cron-Daemon und seine Konfiguration
Der Cron-Daemon überwacht verschiedene Dateien und Verzeichnisse, in denen Anweisungen liegen, die in regelmäßigen Abständen ausgeführt werden sollen. Diese Anweisungen werden Cron-Tabellen oder eben crontabs genannt.

Cron läd beim Start all die Dateien und Verzeichnisse, die er überwacht in den Arbeitsspeicher und überprüft jede Minute einmal, ob darin Jobs enthalten sind, die in der aktuellen Minute ausgeführt werden sollen. Wenn ja, so führt er sie aus. Außerdem überprüft cron jede Minute, ob sich an den Dateien oder Verzeichnissen etwas geändert hat und – falls ja – übernimmt er diese Änderungen im Speicher.

Es gibt also mehrere Möglichkeiten, dem Cron-Daemon einen Job zur Ausführung zu übergeben. Die einzelnen Möglichkeiten sind:

User-Crontabs
Jeder User des Systems kann eine eigene Crontab (also eine Datei mit Anweisungen für Cron) erstellen und bearbeiten. Die Jobs, die darin aufgeführt sind werden von Cron unter der Userkennung des Users ausgeführt, um dessen Crontab-Datei es sich handelt. Die User-Crontabs werden nicht direkt mit einem Editor verändert, sondern mit dem Befehl crontab(1).

Systemweite Crontab-Datei
Im Verzeichnis /etc existiert eine Datei crontab, die ebenfalls Cronjobs definiert. Das Format dieser Datei unterscheidet sich etwas von dem der Usercrontabs – siehe weiter unten…

cron.d Verzeichnis
Im Verzeichnis /etc kann ein Verzeichnis cron.d existieren, das Dateien im selben Format wie /etc/crontab enthalten darf. Auch diese Dateien werden von cron überwacht und darin enthaltene Befehle werden ausgeführt.

cron.{hourly,daily,weekly,monthly} Verzeichnisse
Ebenfalls im /etc/verzeichnis können Verzeichnisse der Namen cron.hourly, cron.daily, cron.weekly und cron.monthly existieren. Diese Verzeichnisse enthalten nicht crontabs, sondern Shellscripts, die entsprechend stündlich, täglich, wöchentlich oder monatlich ausgeführt werden.

Das Format der User-Crontabs
Das Format der Crontabs der User ist etwas speziell, hier das Grundprinzip: Crontab-Einträge sind entweder Definitionen von Shellvariablen oder zeitgesteuerte Cron-Befehle. Leere Zeilen oder Zeilen, die mit einem # beginnen werden ignoriert. Das Kommentarzeichen (#) darf aber nur am Anfang der Zeile stehen mitten in einer Zeile wird es als Teil des Kommandos interpretiert. Die Definition einer Shellvariable hat immer die Form:

Name=Wert

Einige Variablen werden von Cron selbst gesetzt. SHELL wird auf /bin/sh gesetzt, HOME und LOGNAME werden den Informationen über den User aus der /etc/passwd entnommen. Die Variablen SHELL und HOME dürfen verändert werden, LOGNAME nicht.

Normalerweise schickt cron alle Ausgaben von ausgeführten Kommandos per Mail an den User, der das Cron-Kommando ausführen liess. Die Variable MAILTO kann diese Eigenschaft verändern. Wenn sie den Namen eines Users enthält, so werden ihm und nicht dem ursprünglichen Cron-User die Mail geschickt. Ist die Variable MAILTO definiert, aber leer, so wird gar keine Mail verschickt.

Alle anderen Zeilen der Crontabs, die also nicht Variablen definieren, beschreibt Kommandos, die zu bestimmten Zeiten ausgeführt werden sollen. Das grundlegende Format dieser Zeilen ist:

Minute Stunde Tag Monat Wochentag Kommando

Die einzelnen Felder definieren also die Zeit, zu der das angegebene Kommando ausgeführt werden soll. Jedes der fünf Zeitfelder darf statt einem Wert auch ein Sternchen (*) enthalten, das als Jokerzeichen gilt und für jeden beliebigen Wert steht.

Die jeweiligen Zeitfelder dürfen folgende Werte aufnehmen:

Minute 0-59
Stunde 0-23
Tag 1-31
Monat 1-12
Wochentag 0-7 (0 und 7 bedeutet Sonntag)

Auch Bereichsangabe sind erlaubt. Bereiche werden mit Bindestrich definiert. So würde die Angabe 8-11 im Stundenfeld die Stunden 8, 9, 10 und 11 meinen.

Auch Listen sind erlaubt. Listen werden durch Kommata aufgebaut. So würde die Angabe 1,2,5 im Wochentagfeld die Tage Montag, Dienstag und Freitag meinen.

Auch Kombinationen von Listen und Bereichen sind möglich. Die Angabe 1,3,15-19,30 spricht also die Zahlen 1, 3, 15, 16, 17, 18, 19 und 30 an.

Im Zusammenhang mit Bereichen können sogar Schrittweiten angegeben werden. Die Angabe 0-23/2 im Stundenfeld meint also die Stunden 0-23 aber in der Schrittweite 2 Stunden. Also 0, 2, 4, 6, 8, 10, …. Um diesen Schritt zu vervollständigen kann z.B. die Angabe alle zwei Stunden” einfach mit */2 ausgedrückt werden. Gleiches gilt für alle anderen Zeitfelder.

Das Wochentagfeld und das Tag-Feld sind – wenn beide angegeben sind – aditiv gemeint. Die Angabe

* * 13 * 5 …

meint also nicht alle Freitag der 13., sondern alle Freitage und alle 13. des Monats.

Die letzte Angabe in einer Crontab-Zeile ist der Befehl, der zur gegebenen Zeit ausgeführt werden soll. Er wird von /bin/sh oder der in der Variable SHELL angegebenen Shell ausgeführt.

Eine Beispiel-Crontab könnte also folgendermaßen aussehen – mit Kommentaren zum besseren Verständnis:

# Variablendefinition
SHELL=/bin/bash
PATH=/usr/bin:/bin

# Cronbefehle
# Das Programm foo wird täglich um 23 Uhr 56 ausgeführt
56 23 * * * foo

# Das Programm backup wird jeden Freitag um 17 Uhr 30 ausgeführt
30 17 * * 5 backup

# Alle 2 Stunden zwischen 6 und 23 Uhr wird das Programm fetchmail
# ausgeführt
0 6-23/2 * * * fetchmail

# Am ersten jedes Monats wird um 8 Uhr morgens das Programm bar ausgeführt
0 8 1 * * bar

Wenn der User, dem der crontab gehört die UserID 0 hat, also der Systemverwalter ist, dann kann eine Crontab-Zeile mit einem Bindestrich beginnen. In diesem Fall wird cron die ausgeführte Aktion nicht an den Syslog-Daemon weiterleiten. In jedem anderen Fall wird jede Cron-Aktion ins Logbuch übernommen und kann dort im Nachhinein überprüft werden.

User Crontabs verwalten mit crontab(1)
Die Crontabs der User sind zwar im Dateisystem als einzelne Dateien vorhanden (/var/spool/cron/tabs/Username), können aber dort nicht direkt editiert werden, weil sie nicht dem User gehören. Damit ein User trotzdem eigene Jobs definieren kann, steht ihm das Programm crontab zur Verfügung.

Dieses Programm erlaubt einem User, die folgenden Aktionen:

Anlegen einer neuen Crontab-Datei
Wenn ein User mit seinem Lieblings-Editor eine Datei erstellt hat, die seine Crontab-Befehle im oben beschriebenen Format enthält, und der User bisher keine Crontab besaß oder die bisherige Crontab durch diese neue Datei ersetzen will, dann kann er diese Datei mit dem Befehl

crontab Dateiname

zu seinem Crontab machen.

Ansehen der aktuellen Crontab
Mit dem Befehl

crontab -l

kann sich ein User seine Crontab am Bildschirm anzeigen lassen.

Löschen der Crontab-Datei
Wenn ein User seine Crontab-Datei löschen will, kann er dazu den Befehl

crontab -r

benutzen. Die ganze Crontab-Datei des Users wird dadurch gelöscht – alle bisherigen Jobs sind damit automatisch auch gelöscht. Die Veränderung wird sofort aktiv.

Einträge in der Crontab editieren
Mit dem Befehl

crontab -e

kann ein User seine Crontab-Datei editieren. Dazu wird der Editor aufgerufen, der in der Umgebungsvariable VISUAL bzw. EDITOR definiert ist – meist also der vi. Alle Veränderungen, die vom User dort vorgenommen werden, werden sofort nach dem Sichern und Verlassen des Editors aktiv.

Der Systemverwalter kann dem Programm crontab mit der Option -u username auch noch den User mitgeben, dessen Eintrag bearbeitet werden soll. Er kann also die Einträge jedes Users erstellen, löschen, ansehen und editieren. Ein Normaluser darf selbstverständlich nur seine eigene Datei bearbeiten.

Das Format der Crontabs in /etc
Die Datei /etc/crontab und alle Dateien (beliebigen Namens) im Verzeichnis /etc/cron.d werden auch als Crontabs gewertet und vom Cron-Daemon überwacht und ausgeführt. Im Wesentlichen entspricht das Format genau dem der User-Crontabs, mit einer Ausnahme. Zwischen dem fünften Zeitfeld (Wochentag) und dem Befehl wird hier noch ein Username angegeben, unter dessen ID der Befehl ausgeführt werden soll. Das Format ist also:

Minute Stunde Tag Monat Wochentag Username Kommando

Alle anderen oben genannten Eigenschaften bleiben unverändert, also auch die Bereichs- und Listenangabe der Zeitfelder.

Diese Dateien dürfen nur vom Systemverwalter angelegt und editiert werden, er kann aber durch das zusätzliche Userfeld bestimmen, unter wessen UserID der Befehl ausgeführt werden soll.

Die Verzeichnisse in /etc
Neben der Datei /etc/crontab und dem Verzeichnis /etc/cron.d existieren in vielen Linux-Distributionen (RedHat, Debian, SuSE,…) auch noch die Verzeichnisse

/etc/cron.hourly
/etc/cron.daily
/etc/cron.weekly
/etc/cron.monthly

Diese Verzeichnisse enthalten keine Crontabs, sondern Programme, die entsprechend stündlich, täglich, wöchentlich oder monatlich einmal ausgeführt werden sollen. In der Regel handelt es sich bei diesen Programmen um Shellscripts, die dann wiederum bestimmte Programme aufrufen. Standardeinstellungen, wann diese Programme ausgeführt werden sind:

* cron.hourly – Stündlich jeweils um *:30 Uhr
* cron.daily – Täglich jeweils um 0:00 Uhr
* cron.weekly – Wöchentlich jeweils Samstags um 0:00 Uhr
* cron.monthly – Monatlich jeweils am ersten eines Monats um 0:00 Uhr

In der Regel sind diese Verzeichnisse für regelmäßige Kommandos gemacht, die schon beim Installieren bestimmter Pakete festgelegt sind. Zumeist tragen die Scripts innerhalb dieser Verzeichnisse die Namen der Pakete, die sie installiert haben.

Cron-Dienste für User erlauben oder verbieten
Normalerweise kann jeder User eines Linux-Systems seine eigene Crontab besitzen und beliebige Aufgaben zu beliebigen Zeiten damit erledigen lassen. Das kann er aber nur – wie oben gesehen – durch die Verwendung des Programms crontab. Dieses Programm bietet aber auch eine Art Zugriffsschutz, mit dem der Systemverwalter einzelnen Usern die Verwendung dieses Programms erlauben oder verbieten kann.

Wie so oft, gibt es hier zwei verschiedene Lösungsansätze. Entweder dürfen nur die User Crontab benutzen, die die ausdrückliche Erlaubnis besitzen, oder alle User dürfen crontab benutzen, denen es nicht explizit verboten wurde.

Dazu kann der Systemverwalter im Verzeichnis /etc mit zwei Dateien arbeiten, die er dort anlegen muß. Die folgenden Möglichkeiten existieren:

Existiert die Datei /etc/cron.allow, dann dürfen nur die User mit crontab arbeiten, die in dieser Datei aufgelistet sind.

Wenn die Datei /etc/cron.allow nicht existiert, stattdessen aber die Datei /etc/cron.deny, dann dürfen alle User mit crontab arbeiten, außer denen, die in der Datei cron.deny aufgelistet sind.

Beide Dateien sind reine Textdateien, die pro Zeile einen Usernamen enthalten dürfen.

In älteren Versionen von Cron lagen diese beiden Dateien nicht in /etc sondern hießen /var/spool/cron/allow und /var/spool/cron/deny. Die Funktionsweise war aber die selbe. Auf manchen älteren Linux-Versionen finden sich noch diese älteren Einstellungen. Nach der Revision hat LPI aber auf die neuen Dateien umgestellt.
anacron
Anacron ist wie cron ein periodischer Kommandoscheduler. Er führt bestimmte Befehle in Intervallen aus, die aber – im Gegensatzt zu cron – nur in Tagen angegeben werden. Der wesentliche Unterschied ist aber der, daß anacron nicht annimmt, daß der Rechner Tag und Nacht läuft.

Wenn cron einen bestimmten Job zu einer Zeit ausführen soll, zu der der Rechner nicht angeschalten ist, dann verfällt dieser Job. Oft ist es zum Beispiel so, daß die täglichen cron-Jobs um 0:00 Uhr ausgeführt werden sollen oder die wöchentlichen am Sonntag (Tag 0). Wenn ein Rechner aber weder Sonntags, noch Nachts läuft, werden diese Jobs niemals ausgeführt. Meist handelt es sich bei diesen Jobs um Verwaltungsaufgaben, wie der Auffrischung bestimmter Systemdatenbanken (locate und man) oder der Rotation der Logdateien.

Anacron kann dieses Problem lösen. Man kann einfach diese Jobs in Intervallen von einem, sieben oder 30 Tagen starten um tägliche, wöchentliche oder monatliche Ausführung zu erzwingen. Anacron führt seine Jobs aus, wenn der letzte Ablauf eines Jobs länger als die genannte Intervallzeit in Tagen her ist. Somit wird ein Job auch dann ausgeführt, wenn der Rechner das nächste Mal angeschalten wird und nicht – wie bei cron – wenn das nächste Wochen- oder Monatsende erreicht ist.

Jedesmal, wenn anacron aufgerufen wird, ließt es seine Konfigurationsdatei (/etc/anacrontab) in der seine Jobs mit den Perioden eingestellt werden. Wenn ein Job die letzten n Tage nicht ausgeführt wurde, wobei n die angegebene Periode dieses Jobs ist, führt anacron ihn aus. Anacron erzeugt dann einen Eintrag in einer speziellen Zeitmarkendatei, die es für jeden Job erstellt, so daß es weiß, wann der Job zuletzt ausgeführt wurde. Wurden alle Kommandos ausgeführt, wird anacron beendet.

Anacron ist also kein Daemon, der die ganze Zeit läuft, sondern muß entweder über init-Scripts oder cron regelmäßig gestartet werden.

Die Konfigurationsdatei von anacron ist sehr einfach aufgebaut. Sie enthält entweder Variablenzuweisungen, die der Umgebung zugewiesen werden, in der der entsprechende Befehl ausgeführt werden soll, oder Befehlszeilen der Form

Periode Verzögerung Job-Identifikation Kommando

Die Periode ist eine Zahl, die die Anzahl von Tagen angibt, die zwischen der letzten Ausführung des Jobs und der nächsten Ausführung mindestens vergangen sein müssen. Die Verzögerung ist ein Wert in Minuten, der angegeben wird, damit nicht alle anacron-Jobs gleichzeitig gestartet werden und so den Rechner unnötig strapazieren. Somit können die verschiedenen Jobs leicht zeitversetzt gestartet werden. Die Job-Identifikation ist ein beliebiges Wort, daß alle Zeichen außer Leerzeichen und Slashs enthalten darf. Mit Hilfe dieses Wortes wird der Dateiname der Zeitmarkendatei erstellt (das ist der Grund für die verbotenen Slashs). Am Ende der Zeile steht dann der auszuführende Befehl. Eine simple /etc/anacrontab Datei könnte also folgendermaßen aussehen:

SHELL=/bin/sh
PATH=/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin

1 1 updatedb updatedb
7 10 logrotate logrotate /etc/logrotate.conf
31 15 tmpclean rm /tmp/*

Jeden Tag, eine Minute nachdem anacron gestartet wurde, wird der Befehl updatedb ausgeführt. Die Zeitmarke wird in eine Datei heißt ebenfalls updatedb.

Alle 7 Tage jeweils 10 Minuten nach dem Start von anacron wird der Befehl logrotate /etc/logrotate.conf ausgeführt. Die Zeitmarkendatei heißt nur logrotate.

Alle 31 Tage werden alle Dateien im /tmp Verzeichnis gelöscht, die Zeitmarkendatei heißt tmpclean. Der Befehl wird 15 Minuten nach Aufruf von anacron gestartet.

Hat anacron all diese drei Befehle abgearbeitet, dann beendet sich das Programm wieder.
Das at-Spoolsystem
Wenn ein Kommando nicht regelmäßig ausgeführt werden soll, sondern nur zu einem ganz bestimmten Zeitpunkt, dann können wir das mit dem at-Kommando erledigen. At ist ein typisches Unix-Spoolsystem, das Aufträge entgegennimmt, in eine Warteschlange stellt und zur gegebenen Zeit dann ausführt. Die Architektur ist wie bei allen anderen Unix-Spoolsystemen ausgeführt:

* Der Befehl at gibt Aufträge in die Warteschlange
* Der Befehl atq zeigt alle Aufträge, die in der Warteschlange stehen.
* Der Befehl atrm löscht einzelne Aufträge aus der Warteschlange.
* Der Daemon atd arbeitet die Warteschlange ab. In älteren Versionen von Linux findet sich kein eigener Daemon, in diesem Fall wurde von cron jede Minute einmal das Programm atrun aufgerufen, das die Warteschlange nach Aufträgen durchsuchte, die im Augenblick ausgeführt werden sollten und – sofern gefunden – diese Jobs ausführte.

Um mit at einen Job in Auftrag zu geben, muß einfach nur der Befehl

at Zeit

aufgerufen werden. Danach kann über die Standard-Eingabe die gewümschte Befehlszeile eingegeben werden, die zu der Angegebenen Zeit ausgeführt werden soll. Um die Eingabe abzuschließen, wird in einer eigenen Zeile das Dateiendezeichen Strg-D eingegeben. Alternativ kann eine Datei angelegt werden, die die Befehle enthält, die zu der bestimmten Zeit ausgeführt werden sollen. Dann kann at entweder mit

at Zeit < Datei

oder mit

at -f Datei Zeit

aufgerufen werden.

Die verschiedenen Formen der Zeitangaben enthehmen Sie bitte der Handbuchseite.

Die Ausgaben der Kommandos, die von at zu bestimmten Zeiten ausgeführt wurden, werden dem User als Mail zugeschickt, der den Auftrag losgeschickt hatte.

Wie schon bei cron, so können wir auch bei at festlegen, wer mit diesem Programm arbeiten darf bzw. wer nicht. Dazu dienen die Dateien /etc/at.allow und /etc/at.deny. Existiert die Datei /etc/at.allow, so dürfen nur die User mit at arbeiten, die dort aufgeführt sind (ein User pro Zeile). Existiert diese Datei nicht, aber die Datei /etc/at.deny, so dürfen alle User at benutzen, außer den Usern, die in at.deny aufgelistet sind. Existieren beide Dateien nicht, so darf nur der Systemverwalter mit at arbeiten.