Im Katalog suchen

Linux - Wegweiser für Netzwerker

Online-Version

Copyright © 2001 by O'Reilly Verlag GmbH & Co.KG

Bitte denken Sie daran: Sie dürfen zwar die Online-Version ausdrucken, aber diesen Druck nicht fotokopieren oder verkaufen. Das Werk einschließlich aller seiner Teile ist urheberrechtlich geschützt. Alle Rechte vorbehalten einschließlich der Vervielfältigung, Übersetzung, Mikroverfilmung sowie Einspeicherung und Verarbeitung in elektronischen Systemen.

Wünschen Sie mehr Informationen zu der gedruckten Version des Buches Linux - Wegweiser für Netzwerker oder wollen Sie es bestellen, dann klicken Sie bitte hier.


vorheriges Kapitel Inhaltsverzeichnis Stichwortverzeichnis nächstes Kapitel



Netfilter und IP tables (2.4-Kernel)

Während der Entwicklung der IP Firewall Chains entschied sich Paul Russell dafür, das IP-Firewalling weiter zu vereinfachen. Er machte es sich ziemlich bald zur Aufgabe, verschiedene Aspekte der Datagramm-Verarbeitung im Kernel-Firewall-Code einfacher zu gestalten. Das Ergebnis war ein Gebilde, das sowohl erheblich einfacher gestaltet als auch wesentlich flexibler war. Paul gab seiner neuen Konstruktion die Bezeichnung ­netfilter.

Hinweis

Während dieses Buch geschrieben wurde, war das endgültige Design von netfilter noch nicht festgelegt. Für mögliche Unzulänglichkeiten in der Beschreibung von netfilter und seiner zugehörigen Konfigurations-Tools, deren Ursache in Änderungen begründet sind, die nach Drucklegung dieses Buches zustande kamen, bitten wir vorab um Ihr Verständnis. Wir halten die Arbeit an netfilter für so wichtig, daß wir uns trotz des laufenden Entwicklungsstandes dafür entschieden haben, dieses Thema aufzunehmen. Im Zweifelsfall verweisen wir auf die zuständigen HOWTO-Dokumente, die stets die akkuratesten und aktuellsten Informationen über netfilter enthalten.

Was war denn an den IP-Chains so verkehrt? Hatten sie nicht die Effizienz und die Verwaltung von Firewall-Regeln deutlich verbessert? Nun ja, die Art und Weise, wie sie die Datagramme verarbeiten, war immer noch ziemlich komplex, besonders in Verbindung mit Firewall-bezogenen Features wie IP-Masquerading (beschrieben in Kapitel 11 IP-Masquerade und die Umsetzung von Netzwerkadressen) und anderen Formen der Adressenumsetzung. Diese Komplexität liegt zum Teil darin begründet, daß IP-Masquerading und Netzwerkadressenumsetzung nicht von Anfang an Bestandteil des Firewall-Codes waren, sondern zunächst unabhängig davon entwickelt und erst später darin integriert wurden. Wollte ein Entwickler neue Features für die Datagramm-Verarbeitung einführen, hätte er Probleme bekommen festzustellen, an welcher Stelle er den neuen Code einfügen sollte. Unter Umständen wäre er sogar gezwungen gewesen, dafür Teile des Kernel-Codes zu modifizieren.

Es traten aber auch noch ganz andere Probleme auf. So beschreibt zum Beispiel die “Input”-Kette die Eingabe in die IP-Netzwerkebene als Ganzes. Die Eingabe-Kette betraf sowohl Datagramme, die für diesen Host bestimmt waren, als auch Datagramme, die von diesem Host geroutet wurden. Das führte zur Verwirrung, da es die eigentliche Funktion der Eingabe-Kette mit der Funktion der Weitergabe-Kette durcheinanderbrachte, die nur auf weiterzuleitende Datagramme angewendet wurde, aber immer der Eingabe-Kette folgte. Wollten Sie nun Datagramme für diesen Host anders behandeln als die nur weiterzuleitenden Datagramme, mußten Sie dafür komplexe Regeln bilden, die die einen oder anderen Datagramme wechselseitig ausschlossen. Das gleiche Problem ergab sich auch für die Ausgabe-Kette.

Ein Teil dieser Komplexität wurde unvermeidlich auf die Schultern des Netzwerkadministrators abgewälzt, da sie gerade im Design der Regelsätze deutlich in Erscheinung trat. Erschwerend kam hinzu, daß neue Filtererweiterungen direkte Änderungen im Kernel-Code notwendig machten, da alle Filteraktionen dort implementiert waren und es keine transparente Schnittstelle dafür gab. netfilter nimmt sich der Komplexität und Unflexibilität der älteren Lösungen an, indem es ein allgemeines Rahmengebilde im Kernel implementiert, das die Datagrammverarbeitung rationeller gestaltet und zudem die Möglichkeit bietet, die Filtermethoden zu erweitern, ohne daß dafür Änderungen im Kernel-Code notwendig wären.

Werfen wir mal einen Blick auf zwei wesentliche Unterschiede. Abbildung 9.8 zeigt, wie Datagramme in der IP-Chains-Implementierung verarbeitet werden, während Abbildung 9.9 veranschaulicht, wie die Verarbeitung in der netfilter-Implementierung vor sich geht. Die entscheidenden Unterschiede liegen zum einen in der Herauslösung der Masquerade-Funktion aus dem Kern-Code und zum anderen in der Änderung der Positionen der Eingabe- und Ausgabe-Ketten. Im Zuge dieser Änderungen wurde ein neues, erweiterbares Konfigurations-Tool namens iptables entwickelt.

In IP-Chains war die Eingabe-Kette für alle vom Host empfangenen Datagramme zuständig, egal ob sie für den Host bestimmt waren oder nur von ihm an andere Hosts weitergeleitet wurden. In netfilter dagegen ist die Eingangskette nur für solche Datagramme zuständig, die direkt für diesen Host bestimmt sind. Entsprechend ist die Weitergabe-Kette hier nur für die an andere Hosts zu routenden Datagramme zuständig. Auf ähnliche Weise ist in IP-Chains die Ausgabe-Kette für alle Datagramme zuständig, die den lokalen Host verlassen, egal ob sie nun auf dem lokalen Host erzeugt oder von einem anderen Host stammen und hier nur weitergeleitet wurden. In netfilter ist die Ausgabe-Kette dagegen nur für die auf diesem Host erzeugten Datagramme zuständig und wird nicht auf Datagramme angewendet, die von anderen Hosts empfangen wurden und zur Weiterleitung bestimmt sind. Diese Änderung bedeutet eine ganz erhebliche Vereinfachung vieler Firewall-Konfigurationen.

Abbildung 9.8: Datagrammverarbeitende Kette in IP-Chains

In Abbildung 9.8 sind die mit “demasq” bzw. “masq” bezeichneten separaten Kernel-Komponenten verantwortlich für die eingehende bzw. ausgehende Verarbeitung von Masquerade-Datagrammen. Sie wurden in Form von netfilter-Modulen reimplementiert.

Wir betrachten nun eine Konfiguration, bei der die Standardaktion für die Eingabe-, Ausgabe- und Weitergabe-Kette auf deny eingestellt ist. Um nun alle Verbindungen durch unsere Firewall zuzulassen, benötigen wir in IP-Chains sechs Regeln, jeweils zwei für die eben genannten Ketten, von denen eine die Vorwärtsrichtung und die zweite die umgekehrte Richtung abdeckt. Sie können sich vorstellen, daß dieses Vorgehen schnell sehr kompliziert und schwer zu handhaben wird, wenn Sie Verbindungen, die geroutet werden sollen, mit denen vermischen, die an den lokalen Host gerichtet sind und nicht geroutet werden müssen. Sie könnten mit IP-Chains zwar Ketten erzeugen, was diese Aufgabe ein wenig vereinfacht, jedoch ist die dafür notwendige Vorgehensweise nicht offensichtlich und erfordert zudem einiges an Sachverstand oder Geschicklichkeit.

In der netfilter-Implementierung mit iptables verschwindet diese Komplexität völlig. Zum Beispiel werden für einen Dienst, der durch den Firewall-Host geroutet, aber nicht am lokalen Host enden soll, nur zwei Regeln benötigt: jeweils eine für die Vorwärtsrichtung und eine für die Rückwärtsrichtung in der Weitergabe-Kette. Das ist der intuitive Weg, Firewall-Regeln zu gestalten, und trägt dazu bei, das Design von Firewall-Konfigurationen drastisch zu vereinfachen.

Abbildung 9.9: Kette für die Datagramm-Verarbeitung in netfilter

Das PACKET-FILTERING-HOWTO enthält eine detaillierte Liste der durchgeführten Änderungen. Hier beschränken wir uns auf die eher praxisorientierten Aspekte.

Abwärtskompatibilität zu ipfwadm und ipchains

Die netfilter-Implementierung in Linux ist derart flexibel, daß sie sogar imstande ist, die ältere Firewall-Software ipfwadm und ipchains zu emulieren. Das erleichtert etwas den Umstieg auf diese neue Generation von Firewall-Software.

Die beiden netfilter-Kernel-Module ipfwadm.o und ipchains.o stellen die Abwärtskompatibilität zu ipfwadm und ipchains zur Verfügung. Sie dürfen immer nur eines der ­beiden Module zur Zeit laden, und Sie können sie nur benutzen, wenn das Modul ­ip_tables.o nicht gleichzeitig geladen ist. Sobald eines der entsprechenden Module aktiv ist, verhält sich netfilter exakt wie die frühere Firewall-Implementierung.

netfilter bildet das ipchains-Interface mit folgenden Befehlen nach:

rmmod ip_tables modprobe ipchains ipchains ...

Anwendung von iptables

Das Utility iptables wird benutzt, um netfilter-Filterregeln zu konfigurieren. Seine Syntax lehnt sich eng an die von ipchains an, unterscheidet sich aber davon in einem wesentlichen Punkt: Sie ist erweiterbar. Das heißt, die Funktionalität kann erweitert werden, ohne daß dafür eine Neukompilierung erforderlich wäre. Dieser Trick wurde mittels Shared Libraries möglich. Es gibt bereits einige Standarderweiterungen, auf die wir teilweise noch näher eingehen werden.

Bevor Sie den Befehl iptables benutzen können, müssen Sie erst das netfilter-Kernel-Modul laden, das die notwendige Unterstützung dafür bietet. Der einfachste Weg hierfür ist die Anwendung des Befehls modprobe wie folgt:

modprobe ip_tables

Der Befehl iptables wird sowohl für die Konfiguration der IP-Filterung als auch der Netzwerk-Adressenumsetzung benutzt. Um diese Eigenschaft nutzen zu können, gibt es zwei Regeltabellen namens filter und nat. Wenn Sie keine -t-Option angeben, wird automatisch die filter-Tabelle genommen. Des weiteren stehen fünf fest installierte Ketten zur Verfügung. Die Ketten INPUT und FORWARD sind für die filter-Tabelle bestimmt, während die PREROUTING- und POSTROUTING-Ketten für die nat-Tabelle zur Verfügung stehen. Die OUTPUT-Kette steht beiden Tabellen zur Verfügung. In diesem Kapitel beschäftigen wir uns nur mit der filter-Tabelle. Die nat-Tabelle behandeln wir in Kapitel 11 IP-Masquerade und die Umsetzung von Netzwerkadressen.

Die allgemeine Syntax der meisten iptables-Befehle ist:

iptables Befehl Regelspezifikation Erweiterungen
Nun nehmen wir einige der Optionen genauer unter die Lupe. Danach betrachten wir einige Anwendungsbeispiele.

Befehle

Es gibt verschiedene Wege, Regeln und Regelsätze mit dem iptables-Befehl zu bearbeiten. Die für IP-Firewalling relevanten Befehle sind:

-A Chain

Erweitert das Ende der bezeichneten Kette um eine oder mehrere Regeln. Falls ein Hostname als Quelle oder Ziel angegeben ist, der sich zu mehr als einer IP-Adresse auflöst, wird für jede dieser Adressen eine Regel hinzugefügt.

-I Chain Regel-Nummer

Fügt eine oder mehrere Regeln am Anfang der bezeichneten Kette ein. Auch hier wird für jede IP-Adresse, zu der ein angegebener Hostname resolviert, eine Regel hinzugefügt.

-D Chain

Entfernt eine oder mehrere Regeln aus der angegebenen Kette, die die Regelspezifikation erfüllt.

-D Chain Regel-Nummer

Entfernt die Regel an Position Regel-Nummer aus der angegebenen Kette. Die erste Regel der Kette hat die Regel-Nummer 1.

-R Chain Regel-Nummer

Ersetzt die Regel an Position Regel-Nummer in der angegebenen Kette durch die übergebene Regelspezifikation.

-C Chain

Testet ein durch die Regelspezifikation beschriebenes Datagramm gegen die angegebene Kette. Diese Anweisung liefert eine Meldung zurück, wie das Datagramm von der Kette verarbeitet wurde. Sie ist sehr nützlich zum Testen von Firewall-Konfigurationen. Darauf gehen wir später im Detail ein.

-L [Chain]

Listet die Regeln der angegebenen Kette auf (oder die Regeln aller Ketten, falls keine Kette angegeben ist).

-F [Chain]

Aktualisiert die Regeln der angegebenen Kette (oder für alle Ketten, falls keine bestimmte angegeben ist).

-Z [Chain]

Setzt die Datagramm- und Bytezähler aller Regeln der angegebenen Kette auf null (oder für alle Ketten, falls keine bestimmte angegeben ist).

-N Chain

Erzeugt eine neue Kette mit der angegebenen Bezeichnung (es darf allerdings keine Kette mit gleichem Namen existieren). Hiermit werden benutzerdefinierte Ketten erzeugt.

-X [Chain]

Entfernt die angegebene benutzerdefinierte Kette (oder alle benutzerdefinierten Ketten, falls keine bestimmte angegeben ist). Damit diese Anweisung tatsächlich ausgeführt wird, darf es keine Referenzen von irgendeiner anderen Regel-Kette auf diese Kette geben.

-P Chain Standardaktion

Setzt die Standardaktion der angegebenen Kette auf die angegebene Aktion. Zulässige Firewalling-Aktionen sind ACCEPT, DROP, QUEUE und RETURN. ACCEPT gewährt dem Datagramm Durchlaß. DROP verwirft das Datagramm. QUEUE reicht das Datagramm zur Weiterverarbeitung in den Benutzerbereich weiter. RETURN bewirkt, daß die Ausführung des Firewall-Codes direkt im Anschluß an die aufrufende Regel fortgesetzt wird, in der ersten ihr unmittelbar nachfolgenden Regel der Kette, die die Ausgangsregel aufrief.

Parameter zur Regelspezifikation

Zur Bildung einer Regelspezifikation gibt es eine Reihe von iptables-Parametern. Wo immer eine Regelspezifikation benötigt wird, muß jeder dieser Parameter angegeben werden, oder es wird sein jeweiliger Vorgabewert eingesetzt.

-p [!]Protokoll

Spezifiziert das Protokoll des Datagramms, das zu dieser Regel paßt. Zulässige Protokollnamen sind tcp, udp und icmp. Sie können hier auch eine IP-Protokollnummer angeben.1 Beispielsweise könnten Sie 4 angeben, um die jeweilige Regel auf Datagramme dieses IP-über-IP-Protokolls (ipip-Encapsulation-Protokolls) anzuwenden. Wenn Sie das Zeichen ! mit angeben, wird die Regel negiert, und es wird nur gegen Datagramme anderer Protokolle getestet. Ist dieser Parameter überhaupt nicht angegeben, sind alle Protokolle zugelassen.

-s [!]Adresse[/Netzmaske]

Spezifiziert die Quelladresse des Datagramms, das zu dieser Regel paßt. Die Adresse kann als Hostname, Netzwerkname oder IP-Adresse angegeben werden. Die optionale Netzmaske kann entweder in traditioneller Form (z.B. /255.255.255.0) oder in moderner Form (z.B. /24) angegeben werden.

-d [!]Adresse[/Netzmaske]

Spezifiziert die Zieladresse des Datagramms, das zu dieser Regel paßt. Beide Größen werden wie beim Parameter -s angegeben.

-j Ziel

Spezifiziert die durchzuführende Aktion, wenn diese Regel paßt. Die Regel können Sie gewissermaßen als “GOTO”-Anweisung auffassen, deren Zielanweisung eine der folgenden ist: ACCEPT, DROP, QUEUE und RETURN.Die Bedeutung dieser Ziele haben wir bereits im Abschnitt “Befehle” beschrieben. Sie können hier auch den Namen einer benutzerdefinierten Kette angeben, in der die Abarbeitung fortgesetzt werden soll. Außerdem können Sie ein Ziel angeben, das von einer Erweiterung stammt. Über Erweiterungen sprechen wir noch in Kürze. Fehlt der Parameter, findet für die Datagramme überhaupt keine Aktion statt. Es werden lediglich der Datagramm- und der Bytezähler aktualisiert.

-i [!]Schnittstelle

Spezifiziert die Schnittstelle, von der ein Datagramm empfangen wird. Auch hier dient ! zur Negierung des Vergleichstests. Endet der Schnittstellen-Bezeichner mit +, gilt die Regel für alle Schnittstellen, deren Name mit der angegebenen Zeichenfolge beginnt. Beispielsweise bezeichnet der Ausdruck -i ppp+ alle PPP-Netzwerkgeräte. Der Ausdruck -i ! eth+ bezeichnet dagegen alle Schnittstellen mit Ausnahme der Ethernet-Geräte.

-o [!]Schnittstelle

Spezifiziert die Schnittstelle, an die ein Datagramm gesendet werden soll. Die Notation ist dieselbe wie bei der Option -i.

[!] -f

Gibt an, daß die Regel auf alle Fragmente eines fragmentierten Datagramms — mit Ausnahme des ersten Fragments — angewendet werden soll.

Optionen

Die folgenden iptables-Optionen sind allgemeiner Natur. Einige von ihnen steuern ziemlich ausgefallene Features der netfilter-Software:

-v

Veranlaßt iptables zur Ausgabe detaillierter Informationen.

-n

Bewirkt, daß iptables IP-Adressen und Ports nur als Nummern ausgibt, ohne sie in ihre entsprechenden Hostnamen aufzulösen.

-x

Bewirkt, daß jeder Zahlenwert in der iptables-Ausgabe exakt, also ohne Auf- oder Abrunden, angezeigt wird.

- -line-numbers

Bewirkt die Ausgabe von Zeilennummern beim Auflisten von Regelsätzen. Die Zeilennummern geben immer die Regelpositionen innerhalb der Kette an.

Erweiterungen

Wir hatten bereits erwähnt, daß das Utility iptables mittels optionaler Shared-Library-Module erweiterbar ist. Es gibt einige Standarderweiterungen, die einige der Features von ipchains zur Verfügung stellen. Um eine solche Erweiterung anwenden zu können, müssen Sie ihren Namen im Argument -m name an iptables übergeben. Die folgende Liste zeigt Ihnen die Verwendung der Optionen -m und -p, die den Kontext der jeweiligen Erweiterung angeben, sowie die Optionen, die diese Erweiterung zur Verfügung stellt:

TCP-Erweiterungen mit -m tcp -p tcp
- -sport [!] [Port[:Port]]

Gibt den Quell-Port, den das Datagramm für diese Regel haben muß, an. Es können auch Bereiche für Ports angegeben werden, indem die Unter- und die Obergrenze durch einen Doppelpunkt getrennt aufgeführt werden. So beschreibt zum Beispiel der Ausdruck 20:25 alle Ports zwischen 20 und 25 (inklusive). Auch hier kann das Zeichen ! zur Negierung eingesetzt werden.

- -dport [!] [Port[:Port]]

Gibt den Ziel-Port, den das Datagramm für diese Regel haben muß, an. Die Notation ist dieselbe wie bei der Option - -sport.

- -tcp-Flags [!] Maske Liste

Gibt an, daß die Regel das Datagramm verarbeiten soll, wenn dessen TCP-Flags mit denen in Maske und Liste übereinstimmen. Maske ist eine Liste von Flags (die durch Kommata getrennt sind), die im Testfall geprüft werden sollen. Liste ist eine Liste von Flags (ebenfalls durch Kommata getrennt), die im Datagramm auf jeden Fall gesetzt sein müssen, damit es von der Regel verarbeitet wird. Zulässige Flags sind: SYN, ACK, FIN, RST, URG, PSH, ALL und NONE. Hierbei handelt es sich um eine erweiterte Option. Für eine Beschreibung der Bedeutung und der Auswirkungen dieser Flags sollten Sie eine gute Beschreibung des TCP-Protokolls heranziehen, zum Beispiel RFC-793. Das Zeichen ! negiert die Regel.

[!] - -syn

Bewirkt, daß die Regel nur solche Datagramme behandelt, deren SYN-Bit gesetzt und deren ACK- und FIN-Bit nicht gesetzt ist. Hierbei handelt es sich um Datagramme, die TCP-Verbindungen aufzubauen versuchen. Daher kann diese Option zur Steuerung von Verbindungsanforderungen benutzt werden. Diese Option ist eine Abkürzung für:

- -tcp-flags SYN,RST,ACK SYN
Wenn Sie den Negierungsoperator benutzen, verarbeitet die Regel nur Datagramme, bei denen nicht beide SYN- und ACK-Bits gesetzt sind.

UDP-Erweiterungen mit -m udp -p udp
- -sport [!] [Port[:Port]]

Spezifiziert den Quell-Port, den das Datagramm für diese Regel haben muß. Ports können hier auch bereichsweise angegeben werden, und zwar in Form einer Untergrenze, gefolgt von einem Doppelpunkt, gefolgt von einer Obergrenze. So beschreibt zum Beispiel der Ausdruck 20:25 alle Ports zwischen 20 und 25 (inklusive). Auch hier kann das Zeichen ! zur Negierung eingesetzt werden.

- -dport [!] [Port[:Port]]

Spezifiziert den Ziel-Port, den das Datagramm für diese Regel haben muß. Die Notation ist dieselbe wie bei der Option - -sport.

ICMP-Erweiterungen mit -m icmp -p icmp
- -icmp-type [!] Typname

Spezifiziert die Art der ICMP-Nachricht, die diese Regel verarbeitet. Sie kann in Form einer Nummer oder als Name angegeben werden. Einige zulässige Namen sind: echo-request, echo-reply, source-quench, time-exceeded, destination-unreachable, network-unreachable, host-unreachable, protocol-unreachable sowie port-unreachable.

MAC-Erweiterungen mit -m mac
- -mac-source [!] Adresse

Legt die Ethernet-Adresse des Hosts fest, die das von dieser Regel zu verarbeitende Datagramm überträgt. Diese Option macht nur Sinn in einer Regel der Eingabe- oder Weitergabe-Kette, da wir grundsätzlich jedes Datagramm übertragen, das die Ausgabe-Kette passiert.

Erneuter Rückblick auf unser einfaches Beispiel

Zur Implementierung unseres “naiven” Beispiels, diesmal mit netfilter, könnten Sie einfach das Kernel-Modul ipchains.o laden und so tun, als ob es eine echte ipchains-Version wäre. Aber wir gehen hier einen anderen Weg und implementieren das Beispiel direkt mit iptables, um zu zeigen, wie ähnlich es ist.

Wir nehmen wieder an, daß wir ein Netzwerk in unserer Firma haben und einen Linux-basierten Firewall-Rechner benutzen, um unseren Anwendern Zugriffe auf WWW-Server im Internet zu ermöglichen, dabei aber jeglichen anderen Datenverkehr zu unterbinden.

Wenn unser Netzwerk eine 24-Bit-Netzmaske (Class C) und die IP-Adresse 172.16.1.0 hat, würden wir folgende iptables-Regeln benutzen:

 # modprobe ip_tables # iptables -F FORWARD # iptables -P FORWARD DROP # iptables -A FORWARD -m tcp -p tcp -s 0/0 --sport 80 -d 172.16.1.0/24 \     --syn -j DROP # iptables -A FORWARD -m tcp -p tcp -s 172.16.1.0/24 --sport \     80 -d 0/0 -j ACCEPT # iptables -A FORWARD -m tcp -p tcp -d 172.16.1.0/24 --dport 80 -s 0/0 -j \     ACCEPT

In diesem Beispiel werden die iptables-Befehle exakt wie beim äquivalenten ipchains-Kommando interpretiert. Der wesentliche Unterschied besteht aber darin, daß vorher erst das Kernel-Modul ip_tables.o korrekt geladen werden muß. Beachten Sie, daß iptables die Option -b nicht unterstützt, weswegen wir für jede Richtung eine Regel angeben müssen.




1.

Werfen Sie einen Blick in die Datei /etc/protocols. Dort finden Sie einige Protokollnamen und -nummern.


vorheriges Kapitel Inhaltsverzeichnis Stichwortverzeichnis nächstes Kapitel


Weitere Informationen zum Linux - Wegweiser für Netzwerker

Weitere Online-Bücher & Probekapitel finden Sie in unserem Online Book Center


O'Reilly Home|O'Reilly-Partnerbuchhandlungen|Bestellinformationen
Kontakt|Über O'Reilly|Datenschutz

© 2001, O'Reilly Verlag