Wozu Internet Protocol?
An ein globales Netz werden verschiedene, einander widersprechende,
Anforderungen gestellt: schnell, grosse Distanz, kostengünstig und
Rückwärtskompatibilität. Das kann, insbesonders im Anblick des
technischen Fortschritts, nur mit einem Gemisch an vielen verschiedenen
Technologien erreicht werden.
Benützer wollen aber nicht, sich mit mehreren verschiedenen Systemen
herumschlagen, geschweige denn wissen müssen, welche Leitung von wo nach
wo in welcher Technologie implementiert ist.
Als einzige gangbare Lösung müssen alle Leitungen als ein einzelnes
virtuelles Netz (mit variabler Leistung in den Teilsegmenten) behandelt
werden, als ein internet (mit kleinem i). Vermittlerrechner (früher
Gateways genannt, heute üblicherweise Router) zwischen den Leitungen
reichen die Daten weiter, bis sie beim Empfänger ankommen.
Das grösste bisher konstruierte internet ist das Internet (grosses I),
ausgehend vom ARPA (Advanced Research Projects Agency) und später dem
NSF (National Science Foundation) der USA, basierend auf dem Internet
Protocol (IP) Verfahren.
Wie funktioniert das IP Verfahren?
Genauso wie beliebige Ein-/Ausgabe Gerate unter Unix als Characterströme
(z.B. tty0, ttyS0) representiert werden und die Details im jeweiligen
Treiber versteckt werden, werden beliebige Leitungen als
Datenpaketübertrager (z.B. lo0, eth0, slip0) representiert und die Details
in die jeweiligen Treiber versteckt.
Wie kommen die IP Pakete ans Ziel?
Jeder Anschluss an jede Leitung bekommt eine einmalige Nummer (ihre IP
Adresse) zugewiesen (z.B. 10.0.3.2 für meine Ethernet Karte). Diese
Nummern sind 32 Bit lang, der Bereich geht also von 0.0.0.0 bis
255.255.255.255, da die Nummern stets als 4 mal 8 Bit geschrieben
werden. Wenn eine Maschine mehrere Anschluesse an verschiedene Leitungen
hat hat jeder dieser Anschlüsse eine eigene IP Adresse (z.B 193.72.192.35
mein SLIP Anschluss). Ausserdem hat jede Maschine fürs Ausliefern von
Datenpaketen an die wartenden Programme noch den lokalen Anschluss lo0,
der stets mit der Nummer 127.0.0.1 versehen wird. Wichtig: die Nummern
gehören den Anschlüssen, nicht den Maschinen.
Die Datenpakete werden vom Absender mit der Empfängeradresse (die IP
Adresse eines beliebigen Anschlusses der Empfängermaschine) versehen und
dann über einen der Anschlüsse der Sendermaschine hinausgeschickt. Damit
die Adressen (und noch etwas mehr Verwaltungskram) in das Datenpaket hinein
können, ohne die Daten zu zerstören, wird vor den Daten ein
Verwaltungsblock angefügt, der IP Header, formatiert nach den Regeln des
Internet Protocols (IP).
Damit ein Rechner weiss an welche Leitung (welchen eigenen Anschluss) und
auf dieser Leitung and welchen Anschluss (anderer Rechner) er ein
Datenpaket weitergeben soll, muss er die Empfängeradresse analysieren.
Um Arbeit zu sparen wurde festgelegt, dass alle Anschlüsse an einer
Leitung in den ersten N Bits der Adresse identisch sein müssen. Der Test
auf direkte Erreichbarkeit ist daher einfach: Für alle eigenen Anschlüsse:
Wie stell ich das bei meinem Rechner ein?
Damit ein Rechner diese Tests durchführen kann muss er für jeden Anschluss
einige Parameter kennen, dafür setzt man in /etc/rc.d/rc.inet1
für jede Leitung folgende Variablen:
- die eigene Anschlussnummer an diese Leitung, die IPAddr
(z.B. meine Ethernet Karte am LUGS Ethernet ist 10.0.3.2)
- wieviele N Bits gemeinsam sind für alle Anschlüsse dieser Leitung,
die Netmask (z.B fürs LUGS Ethernet die ersten 8, das ergibt
255.0.0.0)
- welche Bitkombination in diesen N für alle Anschlüsse dieser Leitung
gelten, die Network ist heute stets Anschlussnummer mit allen
Bits nach der Position N auf 0 gesetzt (z.B. LUGS 10.0.0.0)
- die Pseudo-Anschlussnummer um "alle" Anschlüsse anzusprechen, die
Broadcast, die ist heute stets die höchstmögliche Nummer
in einem Netzwerk (z.B. LUGS 10.255.255.255)
Ausserdem brauchts noch einen Rechner, der nicht direkt verschickbare
Pakete annimmt, die Gateway (z.B. LUGS 10.0.0.1, der Phonic).
Schliesslich brauchts Einträge um die Adresse 127.0.0.1 und alle
eigenen Anschluss-Adressen an den lo0 Treiber weiterzugeben (sonst
schickt man seine eigenen Daten an die entsprechende Leitung, anstelle
davon sie zu bekommen).
Was ist wenn meine IP Pakete zu gross sind?
Bisher haben wir stillschweigend angenommen, dass IP Pakete immer in ein
Leitungspaket passen. Dafür hat der Leitungstreiber zu sorgen. Bloss:
Ethernet erträgt maximal 1500 Bytes pro Paket, X.25 erträgt sogar nur ganze
128 Bytes. Diese maximale Grösse eines Leitungspaketes ist als die Maximal
Transfer Unit (MTU) der Leitung bekannt.
IP Pakete kaönnen aber bis zu 64kByte (inclusive Header) gross sein (z.B.
sendet NFS Pakete von 8kByte). Daher müssen IP Pakete in mehrere
Leitungspakete zerlegt werden, das nennt man Fragmentierung. Dazu
hat der IP Header mehrere Felder zum Ausfüllen:
- IP Paket Identifikationsnummer (jeder gesendete Paket hat eine
eigene Nummer, alle Fragmente sind identisch)
- Fragment Offset gibt an, wieviele Bytes in vorhergehenden Fragmenten
angekommen sein sollten. Zusamman mit der Fragmantlänge und der
Gesamtpaketlänge ist so das Paket wieder zusammensetzbar
- Fragment Flags geben an, ob fragmantiert geworden ist und
Fragmentierverbot (für primitive Betriebssysteme wie Boot ROMs
wichtig)
Kann ein Paket nicht richtig Zusammengesetzt werden (z.B. ein Fragment
fehlt) wird das ganze Paket fortgeworfen.
In der letzen Zeit war von einem Security Bug im ping die Rede.
Dieser hatte aber gar nichts mit dem Ping Befehl zu tun! Der Fehler lag
vielmehr beim Defragmenter! Dieser hatte die fatale Eigenschaft IP Pakete
mit vielen Fragmenten die zusammen grösser als 64k sind zu akzeptieren,
diese wurden beim zusammensetztn zu gross und überschrieben dabei einen
Teil des Kernals, Folge: Absturz. Zu dem Namen ping Bug kam das ganze weil
der ping in Windows95 dazu gebraucht werden kann solche ungültigen Pakete
zu generieren (genauer 64k ohne Header). Aber richtig sollte man Security
Bugs nach dem defekten Program benennen, nicht dem Angriffswerkzeug.
Was geschieht mit meinen Daten beim Empfänger?
Datenpakete von einem Rechner zum anderen zu bringen ist erst der Anfang
einer erfolgreichen Kommunikation, dort müssen sie auch an das richtige
Programm ausgeliefert werden und es sollte (mehrere mögliche absendende
Programme vorausgesetzt) zwischen diesen unterscheiden können.
Dazu wird an beiden Enden der Verbindung eine Portnummer vergeben. Das
sind 16 bit Nummern, also im Bereich 0..65535. Damit diese Nummern
übertragen werden können wird vor dem eigentlichen Datenpaket (aber
nach dem IP Header) ein zusätzlicher Header eingeführt, dieser wird
formatiert nach den Regeln des User Datagram Protocol (UDP).
Will ein Client-Program eine Verbindung zu einem Server-Program haben
bezieht es vom Kernal einen zufälligen UDP Port im Bereich 1024..65535.
Will ein Server-Program sich anbieten bezieht es beim Kernal den für
seinen spezifischen Servertyp festgelegten Port im Bereich 0..1023.
Die Liste der festgelegten Ports ist in /etc/services einsehbar.
Unix Kernal erlauben übrigens nur den Bezug eines Portes unter 1024
wenn das Program, das den Port bestellt, mit root-Privilegien läuft, daher
sind Server SUID Programme oder müssen von root gestartet werden, das gibt
dann die berühmten Security Problems, die regelmässig auftauchen (z.B. der
LPD/lpr Bug letztehin in der Mailing Liste).
Aber kommen meine Daten überhaupt an?
IP, bzw manche Leitungstechnologien darunter (z.B. Ethernet), garantieren
nicht, dass ein Datenpaket überhaupt ankommt! Geschweige denn die
Reihenforge der Pakete (Ueberholung!), selbst Duplikate sind möglich. Es
wird nur ein "möglichst guter Versuch" unternommen, ein Paket ans Ziel zu
bringen. Damit Zuverlässigkeit in die Kommunikation kommt müssen daher
alle Pakete überwacht (bestätigt), geordnet und Duplikate ausgeschieden
werden. Dazu werden weitere Verwaltungsdaten mitgegeben, in einem Header,
formatiert gemäss dem Transmission Control Protocol (TCP).
Der TCP Header wird wie der UDP Header zwischen Daten und IP Header
eingefügt. TCP wird anstelle von UDP eingesetzt, daher muss es auch noch
Portnummern transportieren. TCP hat ebenfalls daher eine eigene
Portnummernvergabe im Kernal und eine eigene Liste von festgelegten Ports
unter 1024. Die sind aber meistens parallel zu UDP. Diese Doppelspurigkeit
ist historisch bedingt, UDP ist eine neuere Erfindung für weniger Overhead
(z.B. NFS benutzt UDP für höhere Geschwindigkeit).
Jedes Paket trägt im TCP Header unter anderem folgende Angaben: N Bytes ab
M-te Position in der Verbindung von Host:Port zu Host:Port und bestätige
bisherigen Empfang bis L-ter Position in Gegenrichtung. Normalfall ist,
das auf jedes Paket ein Bestätigungspaket in die andere Richtung geht,
falls gerade auch Daten gehen müssen werden sie zusammen geschickt.
Bekommt der Sender nicht innerhalb einer Timeout-Zeit keine Bestätigung
wird eine erneute Sendung aller Daten der Verbindung ab letzter bestätigter
Position geschickt. Der Empfänger bestätigt immer den letzten
zusammenhängenden Stand der Verbindung (auch nach Duplikat Empfang).
Mögliche Unfälle und ihre Korrektur:
- Datenpaket verloren: Sender wiederholt, Empfänger bestätigt ohne
je etwas gemerkt zu haben
- Bestätigung verloren: Sender wiederholt (weiss ja nicht vom Empfang),
Empfänger bekommt duplikat, wirft es fort, schickt 2. Bestätigung
- Datenpaket unterwegs dupliziert: Empfänger wirft Duplikat fort
- Bestätigung dupliziert: Sender weiss schon bestätigt, fortwerfen
- Datenpaket verzögert: keine Bestätigung, Sender schickt es erneut,
der Empfänger bekommt ein Duplikat, fortwerfen wie oben
- Bestätigung verzögert: wie bei Datenpaket verzögert
- Datenpaket überholt: Empfänger merkt "Loch" aus letztem angekommenen
Position, Anzahl und neue bis-Position. Fortwerfen oder auf Seite
- Bestätigung überholt: Sender merkt Loch, wie oben
Bei guter Leitung (wenige Korrekturen nötig) wird aus Geschwindigkeits
Gründen "auf Vorrat gesendet", da sonst die Zeit für jedes hin-her
den Datendurchsatz erheblich reduzieren würde. Dafür wird ein "maximaler
Ueberbezug" für jede Verbindung auf dem Laufenden gehalten, bei jedem
Unfall wird es verkleinert, bei jeden problemlosen Paket erhöht. Das
Verhalten ist an dem TxD und RxD LEDs eines Modems schön zu sehen.
Kann ich mein Ziel via IP erreichen?
Wer soeben in seinem Rechner IP konfiguriert hat will es testen. Dazu
gibt es handliche Werkzeuge:
- Neben UDP und TCP Daten zwischen Programmen auszutauschen wollen
oft die Kernals mit einander Kommunizieren, dazu gibt es das Internet
Control Message Protocol (ICMP). Damit wird z.B. vor absichtlich
fortgeworfenen Paketen gewarnt (aber ohne Garantie, dass die Warnung
ankommt!).
Häufigster Gebrauch von ICMP ist der Test für die Erreichbarkeit
einer Maschine, dazu verschickt der Packet INternet Groper
(PING) ein ICMP Paket mit "echo request" als Inhalt, der Kernal
(nicht ein Program wie inetd!) antwortet mit "echo reply".
- Manchmal reicht "Empfänger (nicht) vorhanden" nicht aus, z.B. wenn
man wissen will, wo die Pakete verloren gehen. Dafür gibt es
traceroute. Dieses nutzt ein Feature von IP aus: jedes Paket hat
im IP Header ein Feld names Time To Live (TTL), dessen Inhalt wird bei
jedem Routerdurchgang um 1 reduziert, wird es 0 wird das Paket
fortgeworfen und eine ICMP Warnung geschickt, damit werden endlos
zirkulierende Pakete gekillt.
traceroute schickt nun das erste Paket mit TTL=1 (im ersten Router
killen), dann 2, dann 3, usw. Indem es die Absenderadressen der ICMP
Warnungen anschaut erhält es die Route. Da für gescheiterte ICMP
Pakete keine ICMP Fehlermeldungen gemacht werden (Gefahr endloser
Fehler) muss traceroute UDP Pakete (mit Port=33434) machen. Das er den
Empfänger erreicht hat erkennt er daran, dass anstelle von "time
exceeded" nun "port unreachable" kommt.
Uebrigens: ein fest im Kernal einkompliliertes TTL von 30 wurde
Windows NT 3.5 zum Verhängnis: Internet Verbindungen mit mehr als 30
Routern sind nicht möglich, Linux hat übrigens 255.
Aber kann ichs nicht mit Namen haben?
Jeden Anschluss eines Rechners mit einer Nummer zu versehen mag zwar
effizient für das Routing sein, aber zum merken durch die Benutzer
sind die blöden Nummern alles andere als komfortabel.
Damit die Benutzer mit einfach zu merkenden Namen hantieren können muss
eine Namen zu Nummern Umwandlung stattfinden. Dazu gibt es 2 Methoden:
- Die Datei /etc/hosts:
Da wird für jede Adresse ein Datensatz angelegt von der Form:
Nummer Voller-Name Kurz-Name-1 Kurz-Name-2 ...
- Die Datenbank
Domain Name System (DNS): Da wird mit über vielen Maschinen
weltweit verstreut ein riesiges Gegenstück zu /etc/hosts geführt.
Jeder Rechner hat seinen "ersten Ansprechpartner", dieser ist in der
Datei /etc/resolv.conf in der Zeile mit nameserver
eingetragen (z.B bei mir 146.228.10.15). Diese bekommt man vom seinem
Internet Provider angegeben.
Kann ich Internet über RS-232 benutzen?
IP kann über jede Leitungsart, für die ein Treiber existiert, geschickt
werden. Also auch über die an jedem PC vorhandene serielle Schnittstelle
und einem eventuell daran hängendem Moden. Dazu müssen die IP Pakete
"verpackt" werden, dazu wird seit langem das einfache Serial Line IP (SLIP)
und seit neuerem das flexiblere Point to Point Protocol (PPP) benutzt.
PPP verursacht einen höheren Overhead, ist aber selbstkonfigurierend und
bei ISDN verkürzt es den wieder-Login nachdem man die Leitung unterbrochen
hat.
Da eine RS-232 Leitung von IP aus betrachtet eine Leitung wie jede andere
ist brauchen die beiden Anschlüsse je eine IP Adresse. Das ist aber lästig
zum vergeben, geschweige denn zum konfigurieren. Ein Ausweg aus diesen
Dilemma bietet ein als Proxy-ARP bekanntes Verfahren:
- Da alle Daten auf einer RS-232 Leitung stets von einem Ende zum
anderen müssen (wozu sie denn sonst auf die Leitung setzen) bekommen
beide Enden die selbige IP Adresse. Diese ist auch gleich Network
Adresse der RS-232 Leitung
- Broadcast gibt es nicht auf RS-232, die Netmask ist immer
255.255.255.255
- Damit der Rechner zwischen dem RS-232 und dem Ethernet nicht
bei allen Rechnern als Gateway eingetragen werden muss wird er so
(miss-)konfiguriert, dass er die Adresse seines RS-232 Kollegen als
eine zweite eigene ausgibt
- Daten für den am RS-232 hängenden Rechner werden dann einfach
an sein RS-232 Anschluss weitergeroutet, darauf bekommt es automatisch
der richtige Empfänger
Dies alles einzustellen wird automatisch vom dip Programm nach dem
Einloggen in den RS-232 Server erledigt.
Dieses Verfahren funktioniert natürlich nur, wenn am RS-232 nur ein Rechner
ist. Sitzt hinter dem RS-232 ein zweites Ethernet mit mehreren Maschinen
muss eine richtige IP Konfiguration gemacht werden.
Aber kann ich nicht verhindern, erreicht zu werden?
Eigentlich dienen Netzwerke dazu, Daten ans Ziel zu bringen. Aber manchmal
will man, dass nur erwünschte Daten ankommen und andere aussen vor bleiben.
Dazu kann man das Internet absichtlich "kaputtmachen". Dazu wird eine
Leitung absichtlich unterbrochen und in das Loch eine Maschine eingesetzt,
die selektiv Daten weiterleitet, eine Firewall.
Dazu gibt es 4 grundsätzliche Verfahren:
- Paketfilter: Pakete mit "innen"-Ports >= 1024 gelten als eigene User,
diese werden durchgelassen. Pakete mit "innen"-Ports < 1023 gelten als
Verbindungsaufbau eines Externen an eigene Maschinen, diese werden
fortgeworfen.
Diese Firewalls sind sehr unsicher: ein absichtlich auf einen Port
>= 1024 aufgesetzter Server ist ungeschützt. Die Firewall bei Norberts
altem Arbeitgeber war von dieser Sorte.
- Connectionfilter: Die Firewall analysiert die IP Adressen und die
UDP/TCP Ports. Für jede von "innen" kommende Verbindung werden von
"aussen" kommende Pakete durchgelassen. Alles andere von aussen (z.B
das erste Paket eines Verbindungsversuches) wird fortgeworfen.
Solche Firewalls sind sicher gegen "inoffizielle" Server. So eine
Firewall ist im Linux Kernal ab 1.2.13 eingebaut. Sie wird mit dem
ipfwconfig Befehl konfiguriert
- Masquerading: Wie ein Connectionfilter, aber alle nach aussen
gehenden Verbindungen bekommen die Senderadresse der Firewall (und
eine neue Portnummer). Verbindungen von aussen, die keine gültige
Umwandlung haben, werden fortgeworfen. Masquerading versteckt die
internen Netznummern, und ist daher sicherer gegen Netzanalyse.
So eine Firewall kann auch benutzt werden um ein ganzes Ethernet (z.B.
LUGS) an einen 10baseT Anschluss mit nur einer IP Adresse anzuhängen.
Auch ein Netzwerk mit privaten Adressen (z.B. die 10er Adressen des
LUGS) kann auf diese Weise Internet-fähig gemacht werden. Der Linux
Kernal Firewall kann dies auch>/li>
- Proxy: Keine IP Pakete werden direkt durchgelassen! Statt dessen
müssen alle Programme die "durch" wollen dies via ein Proxy-Program
auf der Firewall machen. Diese 2-Schritt-Verbindungen müssen entweder
vom Benutzer gemacht werden (mühsam) oder von modifizierten Programmen,
sogenannt "Socksified", was zu jeweils 2 Programmversionen führt
(ebenfalls mühsam).
Für diese Mühe bekommt man die sicherste Firewall, allerdings wird
gestritten, wie gross der Fortschritt gegenäber dem Masquerading
wirklich ist, und ob die Mühe gerechtfertigt ist.
Wo find ich mehr zum Thema IP?
Douglas E Comer, Internetworking with TCP/IP
Prentice-Hall, 1991, ISBN 0-13-474321-0
Der standard Universitätstext über TCP/IP. Trotzdem gut zum lesen!
Douglas E Comer/David L Stevens, Internetworking with TCP/IP II
Prentice-Hall, 1991, ISBN 0-13-465378-5
Ein Beispielimplementation von TCP/IP (im Xinu Betriebssystem) wird
detailiert besprochen.
Douglas E Comer/David L Stevens, Internetworking with TCP/IP III
Prentice-Hall, 1993, ISBN 0-13-020272-X
Wie man Programme schreibt, die TCP/IP via dem Berkley Sockets interface
benutzen.
Diese Page ist von Neil Franklin,
letzte Modifikation 96.12.04
|