Suche im Katalog
Linux Netzwerker-Handbuch

Linux Netzwerker-Handbuch


Tony Bautts, Terry Dawson & Gregor N. Purdy
3. Auflage Juli 2005
ISBN 3-89721-414-8
382 Seiten
Weitere Informationen zur gedruckten Version des Buches finden Sie unter:
www.oreilly.de/catalog/linag3ger/

Zur Übersicht aller OpenBooks


TOC PREV NEXT INDEX

Kapitel 10

Wichtige Netzwerkfunktionen

Nachdem Sie IP und den Resolver (DNS) erfolgreich eingerichtet haben, müssen Sie sich den Diensten zuwenden, die Sie in Ihrem Netzwerk anbieten wollen. Dieses Kapitel behandelt die Konfiguration einiger einfacher Netzwerkanwendungen, einschließlich der inetd- und xinetd-Server und der Programme aus der rlogin-Familie. Wir behandeln außerdem kurz die RPC-Schnittstelle (Remote Procedure Call), auf der Dienste wie das Network File System (NFS) basieren. Die Konfiguration von NFS dagegen ist komplizierter und wird in diesem Buch nicht beschrieben.

Natürlich können wir nicht alle Netzwerkanwendungen in diesem Buch beschreiben. Falls Sie einen Dienst installieren wollen, auf den wir hier nicht eingehen, schauen Sie in die entsprechenden Manpages.

Der Super-Server inetd

Programme, die Anwendungsdienste über das Netzwerk bereitstellen, werden als Netzwerk-Dämonen bezeichnet. Ein Dämon ist ein Programm, das einen bestimmten Port öffnet und auf eingehende Verbindungen wartet. Wird eine solche Verbindung aufgebaut, erzeugt der Dämon einen Kind-Prozess, der die Verbindung übernimmt, während er selbst weiter nach eingehenden Anforderungen Ausschau hält. Dieses an sich gute Konzept hat den Nachteil, dass für jeden angebotenen Dienst ein entsprechender Dämon im Hauptspeicher laufen muss. Außerdem müssen in jedem einzelnen Netzwerk-Dämon, der für die Verbindungsüberwachung und die Verwaltung der Ports zuständig ist, immer wieder dieselben Softwareroutinen eingebunden werden.

Um diesen Mangel an Effizienz zu überwinden, verwenden nahezu alle Unix-Installationen einen speziellen Netzwerk-Dämon, den man als »Super-Server« auffassen kann und der Sockets für eine Reihe von Diensten erzeugt und simultan abhört. Fordert ein entfernter Host einen Dienst über einen dieser Sockets an, wird das vom Super-Server registriert, und er startet den für diesen Port zuständigen Server. Der Socket wird dann an den Kind-Prozess übergeben, und der Super-Server fährt daraufhin mit dem Abhören der Sockets fort.

Der am häufigsten verwendete Super-Server ist inetd, der »Internet-Dämon«. Er wird während der Boot-Phase des Systems gestartet und liest eine Liste der Dienste, die er verwalten soll, aus der Datei /etc/inetd.conf. Außer diesen Servern gibt es eine Reihe trivialer Dienste, so genannte interne Dienste, die inetd selbstständig ausführt. Dazu gehören beispielsweise chargen, das einfach eine Zeichenkette erzeugt, und daytime, das die nach Meinung des Systems aktuelle Tageszeit zurückliefert.

Ein Eintrag in dieser Datei besteht aus einer einzelnen Zeile, die sich aus den folgenden Feldern zusammensetzt:

service type protocol wait user server cmdline

Die Bedeutung der Felder wird nachfolgend erklärt:

service
Enthält den Namen des Dienstes. Dieser Name muss in eine Portnummer übersetzt werden, was durch Nachschlagen in der Datei /etc/services geschieht. Diese Datei wird im Abschnitt 1
type
Bestimmt den Socket-Typ entweder als stream (für verbindungsorientierte Protokolle) oder als dgram (für paketorientierte Protokolle). TCP-basierte Dienste müssen daher immer stream verwenden, während UDP-basierte Dienste immer dgram benutzen müssen.
protocol
Benennt das vom Dienst verwendete Transportprotokoll. Hier muss ein gültiger, in der Datei protocols enthaltener Protokollname stehen.
wait
Diese Option gilt nur für dgram-Sockets. Sie kann entweder wait oder nowait lauten. Wird wait angegeben, führt inetd immer nur einen Server für den angegebenen Port aus. Anderenfalls beginnt inetd unverzüglich wieder damit, an diesem Port zu lauschen, sobald der Server gestartet wurde.
Das ist bei so genannten »Single-Threaded-Servern« sinnvoll, die alle eingehenden Datagramme lesen, bis keine weiteren mehr ankommen, und sich dann beenden. Die meisten RPC-Server sind von dieser Art und sollten daher immer wait verwenden. Der entgegengesetzte Typ, der »Multithreaded-Server«, erlaubt eine unbeschränkte Anzahl von gleichzeitig laufenden Instanzen. Dieser Servertyp sollte nowait angeben.
stream-Sockets sollten immer nowait verwenden.
user
Hier steht die Login-ID des Benutzers, unter dem der Prozess ausgeführt wird. Das wird häufig root sein, einige Dienste verwenden aber auch andere Benutzerzugänge. Sie sollten übrigens immer das Prinzip der geringsten Rechte anwenden, d.h., ein Befehl sollte nur mit den Privilegien ausgestattet sein, die er zur fehlerfreien Ausführung unbedingt benötigt. Zum Beispiel läuft der NNTP-Newsserver als news, während Dienste, die ein Sicherheitsrisiko darstellen könnten (wie etwa tftp oder finger), oft als nobody ausgeführt werden.
server
Enthält den vollständigen Pfadnamen des auszuführenden Serverprogramms. Interne Dienste werden mit dem Schlüsselwort internal gekennzeichnet.
cmdline
Das ist die an den Server zu übergebende Kommandozeile. Sie beginnt mit dem Namen des auszuführenden Servers und kann alle dafür notwendigen Argumente enthalten. Falls Sie den TCP-Wrapper benutzen, geben Sie hier den vollständigen Pfadnamen zum Server an. Falls nicht, geben Sie den Servernamen so an, wie er in der Prozessliste erscheinen soll. Über TCP-Wrapper reden wir in Kürze.
Dieses Feld ist für interne Dienste leer.

Ein Beispiel für inetd.conf finden Sie in Beispiel 10-1. Der finger-Dienst ist auskommentiert und steht daher nicht zur Verfügung. Das geschieht häufig aus Sicherheitsgründen, weil er von Angreifern dazu verwendet werden kann, um Namen und andere Details der Benutzer Ihres Systems zu ermitteln.

Beispiel 10-1
/etc/inetd.conf-Beispieldatei 
#
# inetd-Dienste
ftp stream tcp nowait root /usr/sbin/ftpd in.ftpd -l
telnet stream tcp nowait root /usr/sbin/telnetd in.telnetd -b/etc/issue
#finger stream tcp nowait bin /usr/sbin/fingerd in.fingerd
#tftp dgram udp wait nobody /usr/sbin/tftpd in.tftpd
#tftp dgram udp wait nobody /usr/sbin/tftpd in.tftpd /boot/diskless
#login stream tcp nowait root /usr/sbin/rlogind in.rlogind
#shell stream tcp nowait root /usr/sbin/rshd in.rshd
#exec stream tcp nowait root /usr/sbin/rexecd in.rexecd
#
# inetd-interne Dienste
#
daytime stream tcp nowait root internal
daytime dgram udp nowait root internal
time stream tcp nowait root internal
time dgram udp nowait root internal
echo stream tcp nowait root internal
echo dgram udp nowait root internal
discard stream tcp nowait root internal
discard dgram udp nowait root internal
chargen stream tcp nowait root internal
chargen dgram udp nowait root internal

Der tftp-Dämon ist ebenfalls auskommentiert. tftp implementiert das Trivial File Transfer Protocol (TFTP), das es einem erlaubt, allgemein lesbare Dateien ohne Kennwortprüfung von Ihrem System zu übertragen. Das ist vor allem bei der Datei /etc/passwd gefährlich, umso mehr, wenn Sie keine Shadow-Passwörter benutzen.

tftp wird üblicherweise von plattenlosen Clients und X-Terminals benutzt, um deren Code von einem Boot-Server herunterzuladen. Falls Sie den tftpd-Dämon aus diesem Grund ausführen müssen, stellen Sie sicher, dass Sie den Zugriff auf diejenigen Verzeichnisse beschränken, aus denen die Clients die Dateien beziehen. Diese Verzeichnisse können Sie auf der tftpd-Kommandozeile angeben. Wie das geht, ist auf der zweiten tftp-Zeile im Beispiel zu sehen.

Zugriffskontrolle mit tcpd

Da die Erweiterung eines Computers um Netzwerkfähigkeiten viele Sicherheitsrisiken in sich birgt, sind die Anwendungen so entwickelt worden, dass sie sich vor verschiedenen Arten von Angriffen schützen können. Allerdings sind einige Sicherheitsmerkmale fehlerhaft (was der RTM-Internet-Wurm auf besonders drastische Weise in einer Reihe von Programmen demonstrierte, zu denen auch alte Versionen des sendmail-Dämons gehörten) oder es wird nicht unterschieden zwischen sicheren Hosts, von denen Anforderungen nach einem bestimmten Dienst akzeptiert werden können, und unsicheren Hosts, deren Anforderungen abgelehnt werden müssen. Die Dienste finger und tftp hatten wir ja bereits angesprochen. Netzwerkadministratoren würden den Zugriff auf diese Dienste gerne auf »vertrauenswürdige Hosts« beschränken, was aber mit dem normalen Setup, bei dem inetd den Dienst entweder allen Clients anbietet oder überhaupt keinem, nicht möglich ist.

Ein für die Verwaltung hostspezifischer Zugriffe nützliches Werkzeug ist tcpd, das oft auch als Dämon-»Wrapper« bezeichnet wird. Es wird für TCP-Dienste, die Sie überwachen oder schützen wollen, anstelle des normalen Serverprogramms gestartet. tcpd prüft, ob der entfernte Host einen solchen Dienst überhaupt benutzen darf, und führt nur dann das eigentliche Serverprogramm aus. tcpd schickt auch eine Meldung über die Anforderungen an den syslog-Dämon. Beachten Sie, dass dies bei UDP-basierten Diensten nicht funktioniert.

Um beispielsweise den finger-Dämon mit einem Wrapper zu schützen, müssen Sie die entsprechende Zeile in inetd.conf

# finger-Dämon (ohne Wrapper)
finger stream tcp nowait bin /usr/sbin/fingerd in.fingerd

folgendermaßen ändern:

# finger-Dämon (mit Wrapper)
finger stream tcp nowait root /usr/sbin/tcpd in.fingerd

Ohne eine zusätzliche Zugriffskontrolle erscheint dies für den Client wie ein ganz gewöhnliches finger-Setup, mit der Ausnahme, dass alle Anforderungen im auth-Kanal von syslog aufgezeichnet werden.

Die Zugriffskontrolle wird mit Hilfe der beiden Dateien /etc/hosts.allow und /etc/hosts.deny implementiert. Sie enthalten Einträge, die den Zugriff auf bestimmte Dienste und Hosts erlauben oder verweigern. Wenn tcpd eine Anforderung für einen Dienst wie finger von einem Client-Host namens biff.foobar.com behandelt, durchsucht es hosts.allow und hosts.deny (in dieser Reihenfolge) nach einem Eintrag, bei dem sowohl der Dienst als auch der Client übereinstimmen. Wird ein passender Eintrag in hosts.allow gefunden, wird der Zugriff freigegeben, unabhängig davon, ob es noch einen Eintrag in hosts.deny gibt. Wird keine Übereinstimmung in hosts.allow, aber eine in hosts.deny gefunden, wird die Anforderung abgewiesen, indem die Verbindung unterbrochen wird. Die Anforderung wird akzeptiert, wenn überhaupt kein passender Eintrag gefunden wird.

Die Einträge in den Zugriffsdateien sehen folgendermaßen aus:

dienstliste: hostliste [:shellbefehl]

dienstliste ist eine Liste mit Dienstbezeichnungen aus /etc/services oder das Schlüsselwort ALL. Damit der Eintrag alle Dienste bis auf finger und tftp betrifft, geben Sie ALL EXCEPT finger, tftp an.

hostliste ist eine Liste mit Hostnamen, IP-Adressen oder den Schlüsselwörtern ALL, LOCAL, UNKNOWN oder PARANOID. ALL steht für alle Hosts, während LOCAL nur Hostnamen erfasst, die keinen Punkt enthalten.1 UNKNOWN gilt für jeden Host, dessen Name oder Adresse nicht durch Nachschlagen ermittelt werden konnte. PARANOID gilt für jeden Host, dessen Name sich nicht zu seiner IP-Adresse auflösen lässt.2 Ein Name, der mit einem Punkt beginnt, gilt für alle Hosts, deren Domain mit diesem Namen übereinstimmt. Zum Beispiel passt .foobar.com zu biff.foobar.com, nicht aber zu nurks.fredsville.com. Ein Muster, das mit einem Punkt endet, gilt für jeden Host, dessen IP-Adresse mit dem angegebenen Muster beginnt. So passt 172.16. zu 172.16.32.0, nicht aber zu 172.15.9.1. Ein Muster der Form n.n.n.n/m.m.m.m wird als IP-Adresse und Netzmaske betrachtet. Wir könnten daher unser Beispiel von eben auch als 172.16.0.0/255.255.0.0 angeben. Schließlich können Sie mit einem Muster, das mit einem »/«-Zeichen beginnt, eine Datei festlegen, von der angenommen wird, dass sie eine Liste mit Hostnamen- oder IP-Adressmustern enthält, von denen jedes zutreffen darf. So würde die Angabe /var/access/trustedhosts den tcpd-Dämon veranlassen, diese Datei zu lesen und zu prüfen, ob irgendeine der darin enthaltenen Zeilen zum verbindenden Host passt.

Um nur den lokalen Hosts den Zugriff auf finger und tftp zu gestatten, lassen Sie die Datei /etc/hosts.allow leer und tragen in /etc/hosts.deny Folgendes ein:

in.tftpd, in.fingerd: ALL EXCEPT LOCAL, .ihre.domain

Das optionale Feld shellbefehl kann einen Shell-Befehl enthalten, der ausgeführt wird, wenn der Eintrag passt. Das ist sinnvoll, wenn Sie Fallen einrichten wollen, die potenzielle Angreifer enttarnen. Das folgende Beispiel erzeugt eine Protokolldatei, die den verbindenden Benutzer und den Host anzeigt. Wenn dieser Host nicht vlager.vbrew.com ist, werden die Ausgaben einer finger-Anwendung auf diesen Host dort eingetragen:

in.ftpd: ALL EXCEPT LOCAL, .vbrew.com : \
echo "request from %d@%h: >> /var/log/finger.log; \
if [ %h != "vlager.vbrew.com:" ]; then \
finger -l @%h >> /var/log/finger.log \
fi

Die Argumente %h und %d werden von tcpd zum Client-Hostnamen bzw. zum Dienstnamen erweitert. Details entnehmen Sie bitte der Manpage hosts_access(5).

Die xinetd-Alternative

Mit xinetd ist eine Alternative zum normalen inetd aufgetaucht, die inzwischen weithin akzeptiert wird. Sie wird als sicherer und robuster eingestuft und bietet Schutz vor einigen DoS-Angriffen, die gegen inetd ausgeführt wurden. Die zahlreichen Funktionen und Eigenschaften, die von xinetd angeboten werden, lassen es außerdem als eine sehr verlockende Alternative erscheinen. Hier ist eine kurze Liste seiner Funktionen:

Es bietet vollwertige Zugriffskontrolle und Protokollierung.
Es beschränkt die Anzahl der Server, die gleichzeitig ausgeführt werden.
Es bietet eine genaue Bindung der Dienste mittels -services; die Dienste können an bestimmte IP-Adressen gebunden werden.

xinetd ist mittlerweile standardmäßig Bestandteil der meisten Linux-Distributionen. Falls Sie den neuesten Quellcode oder aktuelle Informationen darüber suchen, schauen Sie auf die Website http://www.xinetd.org. Wenn Sie das Programm kompilieren und IPv6 benutzen, dürfen Sie nicht vergessen, die Option --with-inet6 einzustellen.

Die Konfiguration von xinetd ist etwas anders, aber dennoch nicht komplizierter als die von inetd. Anstatt eine Master-Konfigurationsdatei für alle Dienste zu erzwingen, kann xinetd so konfiguriert werden, dass es eine Master-Konfigurationsdatei namens /etc/xinetd.conf und separate Konfigurationsdateien für jeden zusätzlichen konfigurierten Dienst verwendet. Neben einer vereinfachten Konfiguration gestattet dies eine feinere Einstellung jedes Dienstes und führt zu einer größeren Flexibilität von xinetd.

Die erste Datei, die Sie konfigurieren müssen, ist /etc/xinetd.conf. Eine Beispieldatei sieht so aus:

# Beispielkonfigurationsdatei für xinetd

defaults
{
only_from = localhost
instances = 60
log_type = SYSLOG authpriv info
log_on_success = HOST PID
log_on_failure = HOST
cps = 25 30
}

includedir /etc/xinetd.d

Es gibt eine Reihe von Optionen, die konfiguriert werden können. Die oben verwendeten Optionen sind:

only_from
Legt die IP-Adressen oder Hostnamen fest, von denen Sie Verbindungen erlauben. In diesem Beispiel haben wir die Verbindungen auf die Loopback-Schnittstelle beschränkt.
instances
Legt die Anzahl der Server fest, die xinetd ausführen wird. Wenn Sie diese Option auf einen vernünftigen Wert setzen, können Sie verhindern, dass böswillige Benutzer einen DoS-Angriff gegen Ihre Maschine vornehmen.
log_type SYSLOG|FILE
Diese Option erlaubt es Ihnen, die Art der Protokollierung festzulegen, die Sie verwenden wollen. Es gibt zwei Möglichkeiten, syslog oder file. Mit der ersten, syslog, werden alle Protokollierungsinformationen an das Systemprotokoll geschickt. Die Anweisung file schickt Protokollnachrichten an eine von Ihnen vorgegebene Datei. Eine Liste weiterer Optionen aus diesem Bereich finden Sie in der xinetd.conf-Man-page.
log_on_success
Mit dieser Option können Sie die Art der Informationen bestimmen, die aufgezeichnet werden, wenn eine Benutzerverbindung erfolgreich zustande gekommen ist. Hier ist eine Liste der verfügbaren Unteroptionen:
HOST
Zeichnet die IP-Adresse des entfernten Hosts auf.
PID
Zeichnet die Prozess-ID des neuen Servers auf.
DURATION
Aktivieren Sie dies, um die Gesamtzeit der Sitzung aufzuzeichnen.
TRAFFIC
Diese Option kann für Administratoren nützlich sein, die sich um die Netzwerkauslastung sorgen. Wenn Sie diese Option aktivieren, wird die Gesamtzahl der ein-/ausgehenden Bytes aufgezeichnet.
log_on_failure
HOST
Zeichnet die IP-Adresse des entfernten Hosts auf.
ATTEMPT
Vermerkt alle fehlgeschlagenen Versuche, auf Dienste zuzugreifen.
cps
Diese Option, eine weitere Sicherheitsfunktion, beschränkt die Rate der für einen Dienst eingehenden Verbindungen. Sie verlangt zwei Optionen: erstens die Anzahl der Verbindungen, die pro Sekunde erlaubt sind, und zweitens die Zeitdauer in Sekunden, für die der Dienst deaktiviert wird.

All diese Optionen können in den Konfigurationsdateien der einzelnen Dienste überschrieben werden, die wir im Verzeichnis /etc/xinetd.d ablegen. Diese Optionen in der Master-Konfigurationsdatei dienen als Vorgabewerte. Die Konfiguration einzelner Dienste ist eben-so einfach. Hier ist ein Beispiel des FTP-Dienstes, der für xinetd konfiguriert wurde:

service ftp
{
socket_type = stream
wait = no
user = root
server = /usr/sbin/vsftpd
server_args = /etc/vsftpd/vsftpd.conf
log_on_success += DURATION USERID
log_on_failure += USERID
nice = 10
disable = no
}

Als Erstes werden Sie feststellen, dass die einzelnen Dienste im Verzeichnis xinetd.d dankenswerterweise sinnvoll benannt sind, was es einfacher macht, die entsprechenden Konfigurationsdateien zu identifizieren und zu verwalten. In diesem Fall heißt die Datei einfach vsftp, was sich auf den Namen des von uns verwendeten FTP-Servers bezieht.

Schauen Sie sich das Beispiel an. Die erste aktive Konfigurationszeile definiert den Namen des Dienstes, der konfiguriert wird. Was für eine Überraschung, der Diensttyp wird durch die Anweisung service definiert! Der Rest der Konfiguration ist in geschweiften Klammern enthalten, fast wie C-Funktionen. Einige der Optionen, die in den Dienstkonfigurationen zu finden sind, überschneiden sich mit denjenigen aus dem defaults-Abschnitt. Wenn ein Element in den defaults definiert ist und dann noch einmal in der Konfiguration eines Dienstes definiert wird, hat dieser letzte Wert Vorrang. Es stehen viele Konfigurationsoptionen zur Verfügung, die auch ausführlich in der xinetd.conf-Manpage diskutiert werden. Um einen Dienst jedoch grundsätzlich zum Laufen zu bringen, brauchen wir nur ein paar Optionen:

socket_type
Definiert die Art des Socket, der von dem Dienst benutzt wird. Administratoren, die mit inetd vertraut sind, werden die folgenden verfügbaren Optionen erkennen, etwa stream, dgram, raw und seqpacket.
wait
Diese Option legt fest, ob der Dienst »single-threaded« oder »dual-threaded« ist. yes bedeutet, dass der Dienst »single-threaded« ist; xinetd startet also den Dienst und verarbeitet Anfragen nach neuen Verbindungen erst dann wieder, wenn die aktuelle Sitzung beendet wird. no bedeutet, dass neue Sitzungsanforderungen verarbeitet werden können.
user
Hier stellen Sie den Namen des Benutzers ein, der den Dienst ausführen wird.
server
Diese Option wird verwendet, um anzugeben, wo sich der Dienst befindet, der ausgeführt werden soll.
server_args
Sie können diese Option einsetzen, um zusätzliche Optionen festzulegen, die an den Server übergeben werden müssen.
nice
Diese Option legt die Priorität des Servers fest. Auch mit dieser Option können Sie die von den Servern verwendeten Ressourcen einschränken.
disable
Diese sehr direkte Option legt fest, ob der Dienst aktiviert wird oder nicht.

Die Dateien services und protocols

Die Portnummern, über die bestimmte »Standard«-Dienste angeboten werden, sind im Assigned Numbers-RFC definiert. Um Server- und Client-Programme dazu zu bringen, Dienstnamen in diese Nummern umzuwandeln, ist zumindest ein Teil dieser Liste auf jedem Host vorhanden, und zwar in einer Datei namens /etc/services. Ein Eintrag setzt sich aus folgenden Bestandteilen zusammen:

dienst port/protokoll [aliase]

Hier gibt dienst den Namen des Dienstes an, port definiert, auf welchem Port dieser Dienst angeboten wird, und protokoll definiert das zu verwendende Transportprotokoll. Im Allgemeinen ist dies entweder udp oder tcp. Ein Dienst kann für mehr als ein Protokoll angeboten werden. Genauso können verschiedene Dienste am gleichen Port angeboten werden, solange die Protokolle verschieden sind. Im Feld aliase können Sie alternative Namen für denselben Dienst angeben.

Normalerweise müssen Sie die services-Datei, die der Netzwerksoftware auf Ihrem Linux-System beiliegt, nicht ändern. Dennoch wollen wir Ihnen in Beispiel 10-2 einen kleinen Ausschnitt aus dieser Datei zeigen.

Beispiel 10-2
Ausschnitt aus /etc/services (Beispiel) 
# /etc/services
tcpmux 1/tcp # TCP Port Services Multiplexer
echo 7/tcp
echo 7/udp
discard 9/tcp sink null
discard 9/udp sink null
systat 11/tcp users
daytime 13/tcp
daytime 13/udp
netstat 15/tcp
qotd 17/tcp quote
msp 18/tcp # Message Send Protocol
msp 18/udp # Message Send Protocol
chargen 19/tcp ttytst source
chargen 19/udp ttytst source
ftp-data 20/tcp
ftp 21/tcp
fsp 21/udp fspd
ssh 22/tcp # SSH Remote Login Protocol
ssh 22/udp # SSH Remote Login Protocol
telnet 23/tcp
# 24 - private
smtp 25/tcp mail
# 26 - unassigned

Wie die services-Datei benötigt die Netzwerkbibliothek eine Möglichkeit, um Protokollnamen - beispielsweise die in der services-Datei verwendeten - in Protokollnummern zu übersetzen, die von der IP-Schicht auf anderen Hosts verstanden werden. Dazu wird der Name in der Datei /etc/protocols nachgeschlagen. Diese Datei enthält einen Eintrag pro Zeile, in dem jeweils ein Protokollname und die ihm zugewiesene Nummer steht. Dass Sie sich mit dieser Datei auseinander setzen müssen, ist allerdings noch unwahrscheinlicher als bei /etc/services. Wie die Datei aufgebaut ist, sehen Sie in Beispiel 10-3.

Beispiel 10-3
Ausschnitt aus /etc/protocols (Beispiel) 
#
# Internet (IP) protocols
#
ip 0 IP # Internet-Protokoll, Pseudo-Protokollnummer
icmp 1 ICMP # Internet Control Message Protocol
igmp 2 IGMP # Internet Group Multicast Protocol
tcp 6 TCP # Transmission Control Protocol
udp 17 UDP # User Datagram Protocol
raw 255 RAW # RAW-IP-Schnittstelle
esp 50 ESP # Encap Security Payload für IPv6
ah 51 AH # Authentication Header für IPv6
skip 57 SKIP # SKIP
ipv6-icmp 58 IPv6-ICMP # ICMP für IPv6
ipv6-nonxt 59 IPv6-NoNxt # No Next Header für IPv6
ipv6-opts 60 IPv6-Opts # Zieloptionen für IPv6
rspf 73 RSPF # Radio Shortest Path First.

Aufruf entfernter Prozeduren (Remote Procedure Call)

Der grundlegende Mechanismus für Client-Server-Anwendungen wird vom RPC-Paket (Remote Procedure Call) bereitgestellt. RPC wurde von Sun Microsystems entwickelt und ist eine Sammlung von Werkzeugen und Bibliotheksfunktionen. Eine wichtige Anwendung, die auf RPC aufsetzt, ist NFS.

Ein RPC-Server besteht aus einer Reihe von Prozeduren, die ein Client aufrufen kann, indem er eine RPC-Anforderung zusammen mit den Prozedurparametern an den Server schickt. Der Server führt die gewählte Prozedur im Namen des Clients aus und liefert das Ergebnis zurück, falls es eines gibt. Um maschinenunabhängig zu sein, werden alle zwischen dem Client und dem Server ausgetauschten Daten vom Sender in das so genannte XDR-Format (External Data Representation) umgewandelt und vom Empfänger wieder in die lokale Repräsentation der Maschine zurückübersetzt. RPC benutzt Standard-UDP- und -TCP-Sockets, um die XDR-formatierten Daten zum entfernten Host zu übertragen. Sun hat RPC großzügigerweise als Public Domain freigegeben. Es wird in einer Reihe von RFCs beschrieben.

Manchmal führen Verbesserungen an einer RPC-Anwendung zu inkompatiblen Veränderungen in der Schnittstelle der Prozeduraufrufe. Natürlich würde ein einfacher Austausch des Servers alle Anwendungen zum Absturz bringen, die noch das ursprüngliche Verhalten erwarten. Deshalb werden RPC-Programmen Versionsnummern zugewiesen, die normalerweise bei 1 beginnen und mit jeder neuen RPC-Version erhöht werden. Häufig kann ein Server mehrere Versionen gleichzeitig anbieten. Die Clients geben dann in ihren Anforderungen durch die Versionsnummer an, welche Implementierung des Dienstes sie benutzen wollen.

Die Kommunikation zwischen RPC-Servern und -Clients ist etwas eigenartig. Ein RPC-Server bietet eine oder mehrere Sammlungen von Prozeduren an; jede Sammlung wird als Programm bezeichnet und durch eine Programmnummer eindeutig identifiziert. Eine Liste, die Dienstnamen auf Programmnummern abbildet, wird für gewöhnlich in der Datei /etc/rpc gespeichert. Ein Ausschnitt davon ist in Beispiel 10-4 zu sehen.

Beispiel 10-4
Ausschnitt aus /etc/rpc (Beispiel) 
#
# /etc/rpc - verschiedene RPC-basierte Dienste
#
portmapper 100000 portmap sunrpc
rstatd 100001 rstat rstat_svc rup perfmeter
rusersd 100002 rusers
nfs 100003 nfsprog
ypserv 100004 ypprog
mountd 100005 mount showmount
ypbind 100007
walld 100008 rwall shutdown
yppasswdd 100009 yppasswd
bootparam 100026
ypupdated 100028 ypupdate

In TCP/IP-Netzwerken wurden die Autoren von RPC mit dem Problem konfrontiert, Programmnummern auf allgemeine Netzwerkdienste abzubilden. Sie gestalteten jeden Server so, dass er für jedes Programm und jede Version sowohl einen TCP- als auch einen UDP-Port bereitstellt. Im Allgemeinen verwenden RPC-Anwendungen UDP, um Daten zu übertragen, und greifen nur dann auf TCP zurück, wenn die zu übertragenden Daten nicht in ein einzelnes UDP-Datagramm passen.

Natürlich müssen Client-Programme eine Möglichkeit haben, um herauszufinden, auf welchen Port eine Programmnummer abgebildet wird. Die Verwendung einer Konfigurationsdatei wäre für diesen Zweck zu unflexibel. Da RPC-Anwendungen keine reservierten Ports verwenden, gibt es keine Garantie, dass ein ursprünglich von unserer Datenbankanwendung zu benutzender Port nicht von einem anderen Prozess besetzt wurde. Darum nimmt eine RPC-Anwendung irgendeinen Port, den sie kriegen kann, und registriert ihn mit einem speziellen Programm, dem so genannten Portmapper-Dämon. Der Portmapper fungiert als Dienstvermittler für alle RPC-Server, die auf dieser Maschine laufen. Ein Client, der einen Dienst mit einer gegebenen Programmnummer kontaktieren möchte, fragt zuerst den Portmapper auf dem Host des Servers ab, der dann die TCP- und UDP-Portnummern zurückliefert, über die der Dienst erreicht werden kann.

Diese Methode hat den Nachteil, dass sie - genau wie inetd für die normalen Berkeley-Dienste - einen »single point of failure« darstellt. Nur ist dieser Fall sogar noch schlimmer, weil alle RPC-Port-Informationen verloren gehen, wenn der Portmapper seinen Geist aufgibt. Das bedeutet normalerweise, dass Sie alle RPC-Server manuell neu starten oder sogar die gesamte Maschine neu hochfahren müssen.

Unter Linux wird der Portmapper /sbin/portmap oder manchmal auch /usr/sbin/rpc.portmap genannt. Sie müssen lediglich sicherstellen, dass er von einem Ihrer Netzwerk-Boot-Skripten aus gestartet wird; ansonsten erfordert der Portmapper keine Konfiguration.

Konfiguration von Remote-Logins und Ausführen von Befehlen

Häufig ist es sehr nützlich, einen Befehl direkt auf einem entfernten Host ausführen zu können und diesem Befehl sogar noch Ein- und Ausgaben über das Netzwerk zu ermöglichen.

Die traditionellen Befehle zum Ausführen von Befehlen auf entfernten Hosts sind rlogin, rsh und rcp. Über die damit einhergehenden Sicherheitsfragen haben wir in Kapitel 1 bereits kurz gesprochen und dabei ssh als Ersatz vorgeschlagen. Das ssh-Paket bietet die Ersatzbefehle ssh und scp.

Jeder dieser Befehle führt eine Shell auf dem entfernten Host aus und erlaubt dem Benutzer die Ausführung von Befehlen. Natürlich benötigt der Client einen Benutzerzugang auf dem Host, auf dem der Befehl ausgeführt werden soll. Folglich führen all diese Befehle einen Authentifizierungsvorgang durch. Die r-Befehle tauschen dazu zwischen den Hosts einfach die Benutzernamen und Kennwörter aus. Das geschieht ohne Verschlüsselung, so dass jeder leicht die Kennwörter abhören kann. Die ssh-Befehle dagegen bieten mehr Sicherheit. Sie benutzen dafür eine Technik, die als Public Key Cryptography (Verschlüsselung mit öffentlichem Schlüssel) bezeichnet wird. Sie bietet Authentifizierung und Verschlüsselung zwischen Hosts und stellt sicher, dass weder Kennwörter noch andere Daten von anderen Hosts leicht abgehört werden können.

Es ist möglich, die Authentifizierungsprüfungen für bestimmte Benutzer noch weiter zu lockern. Wenn Sie sich beispielsweise sehr häufig auf einer anderen Maschine in Ihrem LAN einloggen müssen, wollen Sie vielleicht auch direkten Zugriff erhalten, ohne jedes Mal Ihr Kennwort eingeben zu müssen. Mit den r-Befehlen war das schon immer möglich, aber die ssh-Suite macht Ihnen das noch etwas leichter. Das ist zwar immer noch keine gute Idee, denn wenn erst einmal ein Benutzerkonto geknackt wurde, kann man Zugriff auf alle anderen Benutzerkonten erlangen, die dieser Anwender für ein kennwortfreies Login konfiguriert hat. Trotz allem ist es eine bequeme Methode, und die Leute benutzen sie auch.

Lassen Sie uns nun darüber reden, wie Sie die r-Befehle über Bord werfen und stattdessen die ssh-Befehle nutzen.

Die r-Befehle deaktivieren

Als Erstes entfernen wir alle r-Befehle, falls sie installiert sind. Der einfachste Weg, die alten r-Befehle zu deaktivieren, besteht darin, ihre Einträge in der Datei /etc/inetd.conf auszukommentieren (oder zu löschen). Die wichtigen Einträge dort sehen in etwa so aus:

# Shell, login, exec und talk sind BSD-Protokolle.
shell stream tcp nowait root /usr/sbin/tcpd /usr/sbin/in.rshd
login stream tcp nowait root /usr/sbin/tcpd /usr/sbin/in.rlogind
exec stream tcp nowait root /usr/sbin/tcpd /usr/sbin/in.rexecd

Sie können diese Zeilen auskommentieren, indem Sie ein #-Zeichen an den Zeilenanfang schreiben, oder die Zeilen komplett löschen. Denken Sie daran, dass Sie den inetd-Dämon neu starten müssen, um diese Änderungen wirksam werden zu lassen. Am besten entfernen Sie auch die Dämonprogramme selbst aus Ihrem System.

ssh installieren und konfigurieren

OpenSSH ist eine freie Version der ssh-Software. Die Linux-Portierung ist über ftp://ftp.openbsd.org/unix/OpenBSD/OpenSSH/portable/ und die meisten modernen Linux-Distributionen erhältlich.3 Die Kompilierung werden wir hier nicht beschreiben; im Quellcode finden Sie entsprechende Anweisungen. Falls Ihnen das Programm in Form eines vorkompilierten Pakets zur Verfügung steht, sollten Sie es auch daraus installieren.

Eine ssh-Sitzung besteht aus zwei Komponenten. Zum einen gibt es einen ssh-Client, den Sie konfigurieren müssen und auf dem lokalen Host ausführen, zum anderen einen ssh-Dämon, der auf dem entfernten Host laufen muss.

Der ssh-Dämon

Der sshd-Dämon ist ein Programm, das auf Netzwerkverbindungen von ssh-Clients achtet, die Authentifizierung erledigt und den gewünschten Befehl ausführt. Es benutzt eine Haupt-Konfigurationsdatei namens /etc/ssh/sshd_config sowie eine spezielle Datei, die einen Schlüssel enthält, der von den Authentifizierungs- und Verschlüsselungsprozessen benutzt wird, um den Rechner selbst zu repräsentieren. Jeder Server und jeder Client hat seinen eigenen Schlüssel.

Den Distributionen liegt ein Dienstprogramm namens ssh-keygen bei, mit dem sich zufällige Schlüssel erzeugen lassen. Das wird normalerweise nur einmal während der Installation gemacht, um den Hostschlüssel zu bilden, den der Systemadministrator für gewöhnlich in der Datei /etc/ssh/ssh_host_key ablegt. Die Schlüssel können beliebig lang sein, ab 512 Bits und mehr. Standardmäßig erzeugt ssh-keygen Schlüssel mit einer Länge von 1024 Bits, was auch von den meisten Anwendern übernommen wird. Wenn Sie OpenSSH mit SSH Version 2 benutzen, müssen Sie RSA- und DSA-Schlüssel erzeugen. Um die Schlüssel zu erzeugen, rufen Sie ssh-keygen folgendermaßen auf:

# ssh-keygen -t rsa1 -f /etc/openssh/ssh_host_key -N ""
# ssh-keygen -t dsa -f /etc/openssh/ssh_host_dsa_key -N ""
# ssh-keygen -t rsa -f /etc/openssh/ssh_host_rsa_key -N ""

Sie werden aufgefordert, eine Passphrase einzugeben, falls Sie die Option -N weggelassen haben. Hostschlüssel benötigen jedoch keine Passphrase, so dass Sie hier einfach die Return-Taste drücken können. Die Programmausgabe sieht dann etwa so aus:

Generating public/private dsa key pair.
Your identification has been saved in sshkey.
Your public key has been saved in sshkey.pub.
The key fingerprint is:
fb:bf:d1:53:08:7a:29:6f:fb:45:96:63:7a:6e:04:22 tb@eskimo 1024

Wahrscheinlich haben Sie bemerkt, dass drei unterschiedliche Schlüssel angelegt wurden. Der erste, Typ rsa1, wird für das SSH-Protokoll Version 1 verwendet, die beiden nächsten Typen, rsa und dsa, werden für das SSH-Protokoll Version 2 benutzt. Es wird empfohlen, wegen der Gefahr von Man-in-the-Middle- und anderen Angriffen SSH-Protokoll Version 2 anstelle von SSH-Protokoll Version 1 einzusetzen.

Am Ende haben Sie zwei erzeugte Dateien vor sich. Der erste Schlüssel wird als privater Schlüssel bezeichnet, der geheim gehalten werden muss und in /etc/openssh/ssh_host_key aufbewahrt wird. Der zweite wird als öffentlicher Schlüssel bezeichnet und ist derjenige, den Sie mit anderen gemeinsam benutzen können; er wird in /etc/openssh/ssh_host_key.pub abgelegt.

Nachdem Sie mit den Schlüsseln für die ssh-Kommunikation ausgestattet sind, müssen Sie noch eine Konfigurationsdatei erzeugen. Die ssh-Software ist sehr leistungsfähig, und die Konfigurationsdatei kann daher viele Optionen enthalten. Zur Einführung präsentieren wir Ihnen ein kleines Beispiel. Um die anderen Funktionen zu aktivieren, sollten Sie in der ssh-Dokumentation nachlesen. Der folgende Code zeigt eine sichere und minimale sshd-Konfigurationsdatei. Die weiteren Konfigurationsoptionen werden ausführlich in der Manpage sshd(8) beschrieben:

# $OpenBSD: sshd_config,v 1.59 2002/09/25 11:17:16 markus Exp $

#Port 22
Protocol 2
#ListenAddress 0.0.0.0
#ListenAddress ::

# HostKeys für Protokoll Version 2
HostKey /etc/openssh/ssh_host_rsa_key
HostKey /etc/openssh/ssh_host_dsa_key

# Lebensdauer und Größe des Version-1-Server-Schlüssels
#KeyRegenerationInterval 3600
#ServerKeyBits 768

# Authentifizierung:

#LoginGraceTime 120
#PermitRootLogin yes
#StrictModes yes

#RSAAuthentication yes
#PubkeyAuthentication yes
# Auf yes ändern, falls Sie ~/.ssh/known_hosts nicht für
# RhostsRSAAuthentication und HostbasedAuthentication vertrauen
#IgnoreUserKnownHosts no

# Um getunnelte Klartextkennwörter zu deaktivieren, hier auf no ändern!
#PasswordAuthentication yes
#PermitEmptyPasswords no

# Auf no ändern, um s/key-Kennwörter zu deaktivieren
#ChallengeResponseAuthentication yes

#X11Forwarding no
#X11DisplayOffset 10
#X11UseLocalhost yes
#PrintMotd yes
#PrintLastLog yes
#KeepAlive yes
#UseLogin no
#UsePrivilegeSeparation yes
#PermitUserEnvironment no
MaxStartups 10
# kein Standard-Banner-Pfad
#Banner /irgendein/pfad
#VerifyReverseMapping no
# Standardwerte überschreiben, falls keine Subsysteme vorhanden
Subsystem sftp /usr/lib/misc/sftp-server

Sie sollten auf jeden Fall überprüfen, ob die Zugriffsrechte der Konfigurationsdateien korrekt eingestellt sind, um sicherzustellen, dass die Systemsicherheit gewährleistet ist. Führen Sie dazu folgende Anweisungen aus:

# chown -R root:root /etc/ssh
# chmod 755 /etc/ssh
# chmod 600 /etc/ssh/ssh_host_rsa_key
# chmod 600 /etc/ssh/ssh_host_dsa_key
# chmod 644 /etc/ssh/sshd_config

Der letzte Schritt in der Administration des sshd-Dämons besteht nur noch darin, ihn zum Laufen zu bringen. Normalerweise würden Sie dazu eine rc-Datei erzeugen oder ihn in eine existierende Datei eintragen, so dass er beim Systemstart automatisch ausgeführt wird. Der Dämon läuft eigenständig und braucht keinen Eintrag in der Datei /etc/inetd.conf. Der Dämon muss als root laufen. Die Syntax ist sehr einfach:

/usr/sbin/sshd

Der sshd-Dämon versetzt sich beim Start automatisch in den Hintergrund. Nun sind Sie in der Lage, ssh-Verbindungen zu akzeptieren.

Der ssh-Client

Es gibt eine Reihe von ssh-Client-Programmen: slogin, scp und ssh. Sie alle lesen dieselbe Konfigurationsdatei ein, für gewöhnlich /etc/openssh/ssh_config. Außerdem lesen sie Konfigurationsdateien aus dem Verzeichnis .ssh im Home-Verzeichnis des Benutzers, der sie ausführt. Die wichtigsten dieser Dateien sind .ssh/config, die Optionen enthalten kann, die die in der Datei /etc/openssh/ssh_config enthaltenen Optionen überschreiben, außerdem .ssh/identity, die den benutzereigenen privaten Schlüssel enthält, und die entsprechende Datei .ssh/identity.pub mit dem öffentlichen Schlüssel des Benutzers. Weitere wichtige Dateien sind .ssh/known_hosts und .ssh/authorized_keys. Über sie sprechen wir im nächsten Abschnitt »ssh anwenden«. Zunächst erzeugen wir die globale Konfigurationsdatei und die Schlüsseldatei des Benutzers.

Die Datei /etc/ssh/ssh_config ist der Server-Konfigurationsdatei sehr ähnlich. Auch hier gibt es viele Funktionen, die Sie konfigurieren können. Eine minimale Konfigurationsdatei hat die in Beispiel 10-5 gezeigte Form. Die restlichen Konfigurationsoptionen werden detailliert in der Manpage sshd(8) beschrieben. Sie können Abschnitte hinzufügen, die zu bestimmten Hosts oder Gruppen von Hosts passen. Der Parameter für die Host-Anweisung kann entweder der vollständige Name eines Hosts oder ein Wildcard-Ausdruck sein, wie wir es in unserem Beispiel gemacht haben, um alle Hosts auszuwählen. Wir könnten zum Beispiel einen Eintrag wie Host *.vbrew.com erzeugen, der zu jedem Host in der Domain vbrew.com passt.

Beispiel 10-5
Beispielkonfigurationsdatei für ssh-Client 
# $OpenBSD: ssh_config,v 1.19 2003/08/13 08:46:31 markus Exp $
# Site-weite Vorgabewerte für verschiedene Optionen
# Host *
# ForwardAgent no
# ForwardX11 no
# RhostsRSAAuthentication no
# RSAAuthentication yes
# PasswordAuthentication yes
# HostbasedAuthentication no
# BatchMode no
# CheckHostIP yes
# AddressFamily any
# ConnectTimeout 0
# StrictHostKeyChecking ask
# IdentityFile ~/.ssh/identity
# IdentityFile ~/.ssh/id_rsa
# IdentityFile ~/.ssh/id_dsa
# Port 22
# Protocol 2,1
# Cipher 3des
# Ciphers aes128-cbc,3des-cbc,blowfish-cbc,cast128-cbc,arcfour,
# aes192-cbc,aes256-cbc
# EscapeChar ~

Im Abschnitt über die Serverkonfiguration erwähnten wir, dass jeder Host und jeder Benutzer einen Schlüssel hat. Der Benutzerschlüssel wird in dessen ~/.ssh/identity-Datei gespeichert. Zur Erzeugung des Schlüssels benutzen Sie denselben ssh-keygen-Befehl, den wir auch zur Erzeugung des Hostschlüssels verwendet haben; nur müssen Sie diesmal nicht den Namen der Datei angeben, in der Sie den Schlüssel aufbewahren wollen. ssh-keygen gibt dafür die richtige Voreinstellung an, fragt aber trotzdem nach, ob Sie einen anderen Dateinamen wünschen. Manchmal ist es sinnvoll, mehrere identity-Dateien zu haben, weshalb ssh dies auch gestattet. Wie vorher fordert ssh-keygen Sie auf, eine Passphrase einzugeben. Passphrasen tragen zur Erhöhung der Sicherheit bei und sind somit eine gute Sache. Ihre Passphrase wird bei der Eingabe nicht auf dem Bildschirm angezeigt.


Es gibt keine Möglichkeit, eine Passphrase wiederherzustellen, wenn Sie sie vergessen haben. Wählen Sie also eine, die Sie sich gut merken können; aber wie bei allen Kennwörtern sollten Sie auch hier nichts wählen, was zu offensichtlich ist, zum Beispiel ein gängiges Substantiv oder Ihren Namen. Damit eine Passphrase wirklich ihren Zweck erfüllt, sollte sie zwischen 10 und 30 Zeichen lang sein und keine einfache Prosa enthalten. Versuchen Sie, einige Sonderzeichen einzustreuen. Wenn Sie Ihre Passphrase vergessen, kommen Sie nicht umhin, einen neuen Schlüssel zu erzeugen.

Sie sollten jeden Ihrer Benutzer auffordern, den Befehl ssh-keygen nur einmal auszuführen, um sicherzustellen, dass seine Schlüsseldatei korrekt angelegt wird. Der Befehl erzeugt für sie ein ~/.ssh/-Verzeichnis mit den entsprechenden Zugriffsrechten und ihre privaten bzw. öffentlichen Schlüssel in .ssh/identity bzw. .ssh/identity.pub. Eine Beispielsitzung sieht etwa so aus:

$ ssh-keygen
Key generation complete.
Enter file in which to save the key (/home/maggie/.ssh/identity):
Enter passphrase (empty for no passphrase):
Enter same passphrase again:
Your identification has been saved in /home/maggie/.ssh/identity.
Your public key has been saved in /home/maggie/.ssh/identity.pub.
The key fingerprint is:
1024 85:49:53:f4:8a:d6:d9:05:d0:1f:23:c4:d7:2a:11:67 maggie@moria
$

Nun kann man mit ssh loslegen.

ssh anwenden

Inzwischen sollten wir ssh und seine zugehörigen Programme installiert und betriebsbereit haben. Lassen Sie uns einen kurzen Blick darauf werfen, wie man sie anwendet.

Als Erstes versuchen wir, uns an einem entfernten Host anzumelden. Beim ersten Versuch, eine Verbindung mit einem Host herzustellen, empfängt der ssh-Client den öffentlichen Schlüssel vom Host und fordert Sie auf, seine Identität zu bestätigen, indem er Ihnen eine Kurzform dieses Schlüssels ausgibt, die als »Fingerabdruck« bzw. Fingerprint bezeichnet wird.

Der Administrator des entfernten Hosts sollte Ihnen bereits vorsorglich den Fingerprint des öffentlichen Schlüssels mitgeteilt haben. Diesen sollten Sie Ihrer Datei .ssh/known_hosts hinzufügen. Haben Sie dagegen noch keinen Fingerprint bekommen, können Sie sich trotzdem mit dem entfernten Host verbinden, jedoch warnt ssh Sie mit dem Hinweis, dass dieser Host einen Schlüssel hat, und fragt Sie, ob Sie den Schlüssel vom entfernten Host akzeptieren wollen. Wenn Sie sicher sind, dass niemand gerade ein DNS-Spoofing bei Ihnen durchführt und Sie tatsächlich mit dem richtigen Host kommunizieren, beantworten Sie die Frage mit »yes«. Der relevante Schlüssel wird dann automatisch in Ihrer .ssh/known_hosts-Datei vermerkt, und Sie werden in Zukunft nicht mehr danach gefragt. Wenn Sie irgendwann wieder eine Verbindung aufbauen und der vom Host empfangene öffentliche Schlüssel nicht mit dem gespeicherten übereinstimmt, werden Sie gewarnt, da hier eine potenzielle Sicherheitsverletzung vorliegt.

Das erstmalige Login an einem entfernten Host geht etwa so vor sich:

$ ssh vlager.vbrew.com
The authenticity of host `vlager.vbrew.com' can't be established.
Key fingerprint is 1024 7b:d4:a8:28:c5:19:52:53:3a:fe:8d:95:dd:14:93:f5.
Are you sure you want to continue connecting (yes/no)? yes
Warning: Permanently added 'vchianti.vbrew.com,172.16.2.3' to the list of/
known hosts.
maggie@vlager.vbrew.com's password:
Last login: Tue Feb 1 23:28:58 2004 from vstout.vbrew.com
$

Sie werden nach einem Kennwort gefragt. Hier sollten Sie das Kennwort für den entfernten Benutzerzugang eingeben, nicht das für den lokalen Zugang. Das Kennwort wird bei der Eingabe nicht angezeigt.

Sind keine besonderen Argumente angegeben, versucht ssh einen Login mit derselben Benutzer-ID wie auf der lokalen Maschine. Mit der Option -l können Sie das überschreiben und einen alternativen Login-Namen für den entfernten Host angeben. Genau das haben wir in einem früheren Beispiel in diesem Buch getan. Alternativ können Sie mit dem Format benutzerid@hostname.ext einen anderen Benutzernamen festlegen.

Dateien zum bzw. vom entfernten Host können wir mit dem Programm scp kopieren. Die Syntax gleicht der des konventionellen cp-Befehls mit der Ausnahme, dass Sie vor einem Dateinamen auch einen Hostnamen angeben können, was bedeutet, dass sich die Datei auf dem genannten Host befindet. (Es ist auch möglich, das bereits erwähnte benutzerid@ hostname-Format zu benutzen.) Das folgende Beispiel illustriert die scp-Syntax, indem eine lokale Datei namens /tmp/fred nach /home/maggie/ auf dem entfernten Host vlager.vbrew.com kopiert wird:

$ scp /tmp/fred vlager.vbrew.com:/home/maggie/
maggie@vlager.vbrew.com's password:
fred 100% |*****************************| 50165 00:01 ETA

Auch hier werden Sie nach einem Kennwort gefragt. Der Befehl scp zeigt standardmäßig nützliche Informationen über den Stand des Dateitransfers an. Genauso einfach kopieren Sie eine Datei von einem entfernten Host. Dazu geben Sie einfach nur einen Hostnamen und ein Verzeichnis als Quelle sowie den lokalen Pfad als Ziel an. Es ist sogar möglich, eine Datei von einem entfernten Host auf einen anderen entfernten Host zu kopieren. Allerdings würde man so etwas normalerweise nicht machen, da die gesamten Daten den Umweg über Ihren Host nehmen müssen.

Mit ssh können Sie Befehle auf entfernten Hosts ausführen. Auch hier ist die Syntax sehr einfach. Nehmen wir an, die Benutzerin maggie will sich das Wurzelverzeichnis auf dem entfernten Host vchianti.vbrew.com ansehen. Das kann sie folgendermaßen tun:

$ ssh vchianti.vbrew.com ls -CF /
maggie@vchianti.vbrew.com's password:
bin/ ftp/ mnt/ sbin/ tmp/
boot/ home/ opt/ service/ usr/
dev/ lib/ proc/ stage3-pentium3-1.4-20030726.tar.bz2 var/
etc/ lost+found/ root/

Sie können ssh auch in eine Befehls-Pipeline setzen und damit Ein-/Ausgabeumleitungen durchführen wie mit allen anderen Befehlen auch, mit der Ausnahme, dass die Ein- bzw. Ausgabe vom bzw. zum entfernten Host über die ssh-Verbindung erfolgt. Das folgende Beispiel zeigt, wie Sie diese Möglichkeit mit dem Befehl tar kombinieren können, um ein komplettes Verzeichnis inklusive aller Unterverzeichnisse und Dateien von einem entfernten auf den lokalen Host zu kopieren:

$ ssh vchianti.vbrew.com "tar cf - /etc/" | tar xvf -
maggie@vchianti.vbrew.com's password:
etc/GNUstep
etc/Muttrc
etc/Net
etc/X11
etc/adduser.conf
..
..

In diesem Beispiel haben wir die auszuführende Anweisung in Anführungszeichen gesetzt, um festzulegen, was als Argument an ssh übergeben wird und was von der lokalen Shell verarbeitet werden soll. Diese Anweisung startet das Programm tar auf dem entfernten Host, archiviert das Verzeichnis /etc/ und gibt das Archiv auf der Standardausgabe aus. Diese Ausgabe leiten wir auf die Standardeingabe eines lokalen tar-Befehls um, der das Archiv auf der lokalen Maschine wieder entpackt.

Wiederum werden wir nach dem Kennwort gefragt. Wir wollen unseren lokalen ssh-Client jetzt so konfigurieren, dass er nicht nach einem Kennwort fragt, wenn wir eine Verbindung zu vchianti.vbrew.com herstellen. Wir erwähnten bereits die Datei .ssh/authorized_keys, sie kommt hier ins Spiel. Die Datei .ssh/authorized_keys enthält die öffentlichen Schlüssel für alle entfernten Benutzerkonten, an denen wir uns automatisch anmelden wollen. Sie können die automatischen Logins aktivieren, indem Sie den Inhalt der Datei .ssh/identity.pub vom entfernten Zugang in Ihre lokale .ssh/authorized_keys-Datei kopieren. Achten Sie unbedingt darauf, dass die Zugriffsrechte von .ssh/authorized_keys so gesetzt sind, dass nur Sie darin lesen und schreiben können, damit nicht andere die Schlüssel stehlen und sich damit auf dem entfernten Host anmelden können. Um sicherzugehen, dass die Zugriffsrechte korrekt eingestellt sind, setzen Sie sie für .ssh/authorized_keys folgendermaßen:

$ chmod 600 ~/.ssh/authorized_keys

Die öffentlichen Schlüssel bestehen aus einer einzelnen langen Klartextzeile. Wenn Sie einen solchen Schlüssel mittels Copy-and-Paste in Ihre lokale Datei übertragen, stellen Sie sicher, dass Sie nicht versehentlich irgendwelche anderen Zeichen (z.B. Zeilenwechsel) mit übernehmen. Die Datei .ssh/authorized_keys kann viele Schlüssel enthalten, jeden davon in einer eigenen Zeile.

Die ssh-Software ist sehr leistungsfähig und bietet noch viele andere nützliche Funktionen und Optionen, die Sie vielleicht kennen lernen wollen. Mehr Informationen finden Sie in den Manpages und in anderen Dokumentationen, die mit der Software geliefert werden.

1Normalerweise enthalten nur lokale Hostnamen, die durch Nachschlagen in /etc/hosts ermittelt wurden, keinen Punkt.
2Obwohl sein Name einen extremen Eindruck vermittelt, ein extremes Maß zu sein, ist das Schlüsselwort PARANOID doch eine gute Vorgabe, da es Sie vor böswilligen Hosts schützt, die sich als jemand anderes ausgeben. Nicht jedes tcpd wird standardmäßig mit einkompiliertem PARANOID geliefert. Falls das auch bei Ihnen so ist, müssen Sie Ihr tcpd dafür neu kompilieren.
3OpenSSH wurde vom OpenBSD-Projekt entwickelt und ist ein besonders gelungenes Beispiel dafür, was freie Software zustande bringen kann.

TOC PREV NEXT INDEX


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

© 2005, O'Reilly Verlag GmbH & Co. KG