|
Der Internet-SuperserverRein theoretisch müßte jeder Daemon bei Systemstart hochgefahren werden, für die eine Anforderung eines entfernten Rechner (Host) auftreten könnte. Dies würde aber die Zahl der laufenden Prozesse unnötig in die Höhe treiben und Systemresourcen verbrauchen. Deshalb wurde der Daemon inetd, der Internet-Superserver, entwickelt. Er "lauscht" auf alle Diensteanforderungen, die an dem von ihm überwachten Ports eingehen. Tritt eine solche Anforderung auf, prüft der Daemon die Zugriffsberechtigung (exakt: Die Kontrolle wird an den TCP-Warapper tcpd übergeben und dieser macht weiter) und startet im positivem Fall den entsprechenden Daemon, der dann die Anforderungen des Clients bearbeitet. Die Konfigurationsdatei ist /etc/inetd.conf. In ihr sind alle Dienste und die entsprechenden Dämonen mit Parametern verzeichnet. Der inetd vereinfacht zudem das Schreiben von Server-Daemonen, da etlicheStart-Details bereits durch den inetd selbst abgehandelt werden. DerNachteil besteht darin, daß der inetd für jede Anfragesowohl ein fork als auch ein exec ausführen muß,um den aktuellen Serverprozeß zu starten. Der Ablauf entspricht in etwafolgendem Schema: - Beim Starten liest der Daemon die Datei /etc/inetd.conf und generiert für jeden der angegebenen Server einen Socket.
- Danach wird für jeden Socket ein bind() ausgeführt.
- Für jeden Stream-Socket wird nun ein listen() ausgeführt.
- Nun wird auf einen Verbindungswunsch von außen gewartet (perselect()-Aufruf).
- Kommt ein Verbindungswunsch, wird er mit accept() angenommen.
- Nun erzeugt der inetd einen Kondprozeß zum Bearbeiten der
Anforderung. Das Kind schließt alle Dateideskriptoren (außer dem
Socket). Mittels dup2() wird der Socket dupliziert und Deskriptoren
für stdin, stdout und stderr angelegt.
Anschließend wechselt der Prozeß die Benutzeridentität und
startet schließlich mittels exec() den Prozeß für
den gewünschten Dienst.
- Bei eine Stream-Socket wird der angeschlossene Socket geschlossen.
Der inetd und die von ihm gestarteten Server stüten sich auf
folgenden Dateien.
- Die Datei /etc/inetd.conf hat folgende Zeilenstruktur:
Programmname Sockettyp Protokoll Flags User Programmpfad Programmargumente
- Der Programmname ist frei wählbar, aber es ist darauf zu achten, dass
der gleiche Name auch in der Datei /etc/services benutzt wird.
- Als Sockettyp kommen stream, dgram, raw,
rdm und seqpacket in Frage.
- Das Protokoll gibt eines der in der Datei /etc/protocols aufgelisteten
Protokolle an.
- Mögliche Flags sind wait, nowait, udp und tcp.
- Danach folgt der User, unter dessen Rechten das Programm ausgeführt wird.
- Der Programmpfad gibt an, wo das Programm zu finden ist.
- Schließlich folgen eventuelle Parameter für das Programm.
Beispiel:
...
ftp stream tcp nowait root /usr/sbin/in.ftpd in.ftpd
telnet stream tcp nowait root /usr/sbin/in.telnetd in.telnetd
...
shell stream tcp nowait root /usr/sbin/in.rshd in.rshd
login stream tcp nowait root /usr/sbin/in.rlogind in.rlogind
exec stream tcp nowait root /usr/sbin/in.rexecd in.rexecd
...
#tftp dgram udp wait root /usr/sbin/in.tftpd in.tftpd -s /tftpboot
...
Nach Änderungen der Konfiguration (z.B. Ein- und Ausschalten des
TFTP-Dienstes durch Entfernen bzw. Hinzufügen des Kommentarzeichens)
muß der inetd nicht neu gestartet werden, sondern kann durch das
Versenden des Signal SIGHUP angewiesen werden, sich neu zu konfigurieren.
Das Hauptproblem beim Einsatz des inetd ist die Reaktionszeit auf
Dienstanforderungen. Das ist bei Diensten wie Telnet oder FTP unproblematisch,
kann aber z.B. bei HTTP-Servern sehr kritisch werden, da ja HTTP für jede
einzelne Datein eines Webdokuments eine Verbindung aufbaut, demnach für jede
einzelne Datei der httpd vom inetd neu gestartet werden
muß. Daher werden zeitkritischen Dienste und Server als Standalone-Server
betrieben.
- Die Datei /etc/services hat folgende Zeilenstruktur:
Programmname Port/Protokoll
Programm muß der gleiche Name sein wie er in /etc/inetd.conf
an erster Position angegeben wurde. Port/Protokoll bezeichnet den Port, auf
dem gelauscht werden soll, und das dazugehörigen Protokoll, z. B.:
37 telnet/tcp
- Der TCP-Wrapper und die Dateien /etc/hosts.allow und /etc/hosts.deny:
Im inetd selbst sind keinerlei Sicherheitsmechanismen implementiert.
Deswegen wurde ein Filter geschaffen, der vom inetd anstelle des für
den Port zuständigen Dienstes gestartet wird, der sogenannte TCP-Wrapper
tcpd. Er erhält den Programmnamen des Dienstes als Argument.
Der tcpd arbeitet für Server und Client transparent, er wird durch den
zu startenden Dienst ersetzt. Zuvor protokolliert und überprüft er die
Zulässigkeit des Zugriffs.
Falls also in inetd.conf an der vorletzten Position zusätzlich noch der
tcp-Wrapper (tcpd) aufgerufen wird (also beispielsweise statt
/etc/ftpd nun /etc/tcpd /etc/ftpd), wird vom tcpd
vor dem Programmaufruf geprüft, ob der entsprechende Host überhaupt das
Recht besitzt, Serverdienste in Anspruch zu nehmen. Dazu werden die Dateien
/etc/hosts.allow und /etc/hosts.deny herangezogen.
- In keiner der beiden Dateien verzeichnete Hosts, Domains oder Dienste
werden immer zugelassen.
- /etc/hosts.deny
Hier verzeichnete Hosts, Domains oder Dienste werden nicht zugelassen.
Will man nur einige Bösewichte aussperren, wird man diese in dieser Datei
eintragen uns alles andere zulassen, z.B.:
# Host sperren
192.168.0.2: ALL
# Domain sperren
.boese.org: ALL
Sicherer ist es jedoch, in dieser Datei alles zu sperren, was nicht ausdrücklich
erlaubt ist:
ALL: ALL
- /etc/hosts.allow
Hier verzeichnete Hosts, Domains oder Dienste werden zugelassen. Man kann wahlweise
Dienste sperren oder Hosts und Domains nach IP-Nummer oder Namen. Als Beispiel
eine aktuelle Datei:
# See tcpd(8) and hosts_access(5) for a description.
sshd: ALL : ALLOW
proftpd: ALL : ALLOW
sendmail: ALL : ALLOW
popper: ALL : ALLOW
in.telnetd: localhost : ALLOW
bcpd: e-technik.fh-muenchen.de, ariacenter.rz.fh-muenchen.de : ALLOW
Die Daemons für SSH, FTP, SMTP und POP sind für alle offen, Telnet
ist nur am lokalen Rechner erlaubt (Das ":ALLOW" kann man auch weglassen) und der
Backup-CLient (bcpd) darf nur innerhalb des Fachbereichs und vom
Backupserver des Rechenzentrums angesprochen werden.
Eine Zeile in den beiden Dateien hat folgenden Aufbau:
Dienst : Rechner : [Kommando]
An Stelle von Dienst kann entweder ein Programmname stehen oder das
Schlüsselwort ALL, falls die Zeile alle Dienste betreffen soll. Einem
ALL kann ein EXCEPT Dienstname folgen, dann sind alle Dienste mit
Ausnahme der benannten gemeint. Per Komma getrennt, lassen sich mehrere Dienste angeben.
Die möglichen Einträge sind Rechnernamen, IP-Adressen oder die folgenden
Schlüsselworte:
- ALL: Alle Rechner
- KNOWN: Rechner, deren Namen der tcpd ermitteln kann (DNS und reverse DNS)
- LOCAL: Alle Rechner, deren Namen keinen Punkt enthalten (Rechner, die in /etc/hosts
unter einem Kurznamen aufgeführt sind)
- UNKOWN: Rechner, deren Namen der tcpd nicht ermitteln kann.
- PARANOID: Alle Rechner, deren Namens- und Adressauflösung über DNS
widersprüchliche Angaben ergibt.
Schließlich kann ein optionales Kommando angegeben werden, das immer dann
ausgeführt wird, wenn diese Zeile für eine Anforderung zutrifft. Falls auf
diese Möglichkeit zurückgegriffen wird, dann meist für ein detailliertes
Protokoll. Im Argument des Kommandos können einige Sonderzeichen verwendet werden:
%a liefert die IP des rufenden Rechners
%c gibt den Namen des Nutzers und Rechners zurück (sofern ermittelbar)
%d Name des gewünschten Dienstes
%h Name des zugreifenden Rechners oder dessen IP
%n Name des zugreifenden Rechners (oder unknown oder paranoia)
%p Prozessnummer des Dienstes
%s Name des Serves in Verbindung mit dem Rechnernamen
%u Name des Nutzers auf Clientseite, sofern er ermittelt werden kann
Die Konfiguration kann mit dem Kommando tcpdchk überprüft werden
(Unstimmigkeiten in inetd.conf, Syntaxfehler in hosts.deny / hosts.allow,
unbekannte Rechnernamen).
|
|
|