Apache2 - Erläuterung

Aus xinux.net
Zur Navigation springen Zur Suche springen

Einführung

Im Jahre 1991 gab es das Internet schon fast 20 Jahre, aber es war nicht so einfach möglich, Informationen von anderen Rechnern abzurufen. Die Möglichkeiten, eine wissenschaftliche Arbeit zu publizieren, beschränkte sich darauf, eine entsprechende Text- oder PostScript-Datei auf einen FTP-Server zu stellen. Dem Physiker Tim Berners-Lee, der damals am europäischen Kernforschungszentrum CERN in Genf arbeitete, war dies nicht genug. Er erfand das Hypertext Transfer Protocol (HTTP) sowie die HyperText Markup Language (HTML), um den Austausch von Informationen auf einfache Art und Weise zwischen unterschiedlichen Rechner-Architekturen zu ermöglichen. Berners-Lee programmierte auf einem Rechner mit dem Nextstep-Betriebssystem den ersten Webserver und den ersten Web-Browser, den er WorldWideWeb nannte: das WWW war geboren. Damit war es zum ersten Mal möglich, wissenschaftliche Arbeiten in Text und Bild ins Internet zu stellen und diese dann plattformunabhängig auf jedem Rechner im Internet zu betrachten. Das Nextstep-Betriebssystem war jedoch nicht sehr weit verbreitet, und seinen Siegeszug konnte das WWW erst antreten, als Webserver und Web-Browser auch für Unix- und später dann auch für Windows-Systeme entwickelt wurden. Am NCSA (National Center for Supercomputer Applications) entstand der erste HTTP-Server NCSA httpd, sowie mit NCSA Mosaic der erste Web-Browser, zuerst für das UNIX X-Window-System, später auch für Microsoft Windows. Ab diesem Zeitpunkt war es zum ersten Mal möglich, dass Benutzer ohne große Computerkenntnisse Information im Internet abrufen konnten, was zum explosionshaften Erfolg des WWW in den 90er Jahren führte. Mitte 1994 verließ der Chefprogrammierer des NCSA httpd das NCSA, und die weitere Entwick­lung ruhte. Da der Quellcode verfügbar war, entwickelten einige Programmierer eigene Erweiter­ungen zu NCSA httpd und nannten den Server nun scherzhaft einen geflickten Server – a patchy server. 1995 schlossen sich einige dieser Programmierer zu einer Gruppe zusammen, um ihre Energien zu bündeln – in Anlehnung an "a patchy server" nannten sie sich die Apache-Group. Im April 1995 wurde die erste Version des Apache HTTP-Servers freigegeben. Apache wurde ein voller Erfolg. Seitdem ist der Marktanteil des Apache-Servers ständig gestiegen und hat heutzutage mit über 50 Prozent mehr als alle anderen HTTP-Server zusammen. Apache ist ein komplett im Quellcode verfügbarer HTTP-Server, der kostenlos, auch für kom­merzielle Zwecke, eingesetzt werden darf. Seine Schnelligkeit, Flexibilität und nicht zuletzt Sta­bilität trugen maßgeblich zu seinem Erfolg bei.

Aufbau des HTTP-Protokolls

Ein HTTP-Server wartet standardmässig auf Port 80 (TCP) auf eingehende Verbindungen. Auf diesem empfängt er HTTP-Anfragen und beantwortet sie entsprechend. Er liefert über diese TCP-Verbindung die gewünschte Ressource und beendet die Verbindung normalerweise anschließend.

Beispiel für eine Anfrage über HTTP

Um einen HTTP-Server zu testen, baut man mittels Telnet eine Verbindung zu diesem auf und schickt eine einfache HTTP-Anfrage. Wir sehen im folgenden Beispiel ein solche Verbindung:

pate:~/ telnet www.xinux.de 80
Trying 85.10.194.199...
Connected to neelix.talaxia.de.
Escape character is '^]'.
GET /
Die Anfrage GET / fragt die Ressource / mit der ersten Version 0.9 des HTTP-Protokolls ab. Sie ist die einfachste, aber auch die unflexibelste. Der 
Server antwortet mit der angefragten Ressource, bzw. einer Fehlermeldung, wenn die Ressource nicht existiert.
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<title>Xinux Networks - Ihr kompetenter Partner in Sachen Netzwerksicherheit</title>

Als Antwort erhalten wir eine Seite im HTML-Format. Mit dieser Seite können wir in unserer Anwendung telnet nicht viel anfangen. Ein ”richtiger” Web-Browser stellt die Seite dann entsprechend dar. Für unseren Test reicht uns eigentlich, dass der Browser eine HTML-Seite übermittelt, um die Funktionsweise des Servers zu überprüfen. Es ist kaum möglich, mit der Anwendung telnet zu ”surfen”. Wir werden im Laufe des Kurses allerdings sehen, dass zur Fehlersuche und -Behebung der Einsatz von telnet durchaus sinnvoll ist. Ein weiterer Vorteil ist, dass telnet auf fast jedem Betriebssystem, das TCP/IP-Unterstützung hat, verfügbar ist.

Versionen des HTTP-Protokolls

Wenn wir mit telnet verschiedene Webserver testen und uns die Ausgabe einmal genau anschauen, fällt auf, dass nicht immer die erwartete Seite erscheint. Dies kann daran liegen, dass der Server mehrere virtuelle Webserver verwaltet, auf die man mit HTTP/0.9 allerdings nicht zugreifen kann. Hierfür und um mehr über den HTTP-Server zu erfahren, muss man eine HTTP/1.0 Anfrage stellen. Dieses Protokoll definiert neben der Anfrage der Ressource noch zusätzliche Felder, mit denen die Art der Anfrage verändert werden kann, eben z.B. den Namen des Webservers, von dem man die Ressource benötigt:

pate:/etc/apache2# telnet www.xinux.de 80
Trying 85.10.194.199...
Connected to neelix.talaxia.de.
Escape character is '^]'.
GET / HTTP/1.0
Neuere Versionen der Web-Browser senden grundsätzlich noch den sog. Host Header zum Webserver, den Fully Qualified Domain Name, der in der Adresszeile
des Browsers eingetragen wurde. Der Webserver kann diese Information auswerten und die Browser-Anfrage zu dem entsprechenden virtuellen Servers
weiterleiten. 
Außerdem liefert der Webserver nun weitere Angaben über die Art des gelieferten Dokumentes, während bei HTTP/0.9 die Antwort des Servers nur die “reine”
HTML-Seite beinhaltet. 
HTTP/1.1  200 OK
Date: Tue, 25 Oct 2005 09:32:32 GMT
Server: Apache/2.0.54 (Debian GNU/Linux) PHP/4.3.10-15 mod_ssl/2.0.54 OpenSSL/0.9.7e
Last-Modified: Wed, 26 May 2004 22:00:00 GMT
ETag: "f10056-2924-fee39800"
Accept-Ranges: bytes
Content-Length: 10532
Connection: close
Content-Type: text/html
<html>
<head>
<title> ... 

Wir erfahren u.a. den MIME-Type (vereinfacht: Typ des Dokumentes), Angaben über den Server oder die letzte Änderung des Dokumentes. Die aktuelle Version des HTTP-Protokolls ist HTTP/1.1. Wir sehen am obigen Beispiel, dass der Server mit HTTP/1.1 anwortet, obwohl wir mit HTTP/1.0 angefragt haben. HTTP/1.1 unterscheidet sich von HTTP/1.0 nur geringfügig, so wurde es u.a. um die Möglichkeit der beständigen Verbindungen erweitert, die es erlauben, mehrere Anfragen über eine Verbindung abzusetzen. Hierbei wird die Verbindung nicht nach einer Übertragung beendet, sondern steht für weitere Anfragen zu Verfügung. Dieses Verfahren nennt man Keep-Alive. HTML-Seiten enthalten oftmals viele einzelne Elemente, wie z.B Grafiken, die gesondert geladen werden müssen. Da der TCP/IP-Verbindungsaufbau oftmals länger dauert als die Übertragung an sich, beschleunigen beständige Verbindungen das Übertragen der Webseiten deutlich, und der Webserver wird weniger belastet, da weniger Verbindungen aufgebaut werden.

Installation und zugehörige Dateien

root@game:~# apt-get install apache2

Apache-MPM prefork: Dieses Multi-Processing-Modul (MPM) implementiert einen im Voraus forkenden Webserver ohne Thread-Unterstützung, der Anfragen auf ähnliche Weise behandelt wie der Apache 1.3. Es ist für Angebote geeignet, die aus Kompatibilitätsgründen mit nicht-Thread-sicheren Bibliotheken Threading vermeiden müssen. Es ist außerdem das geeignetste MPM, um jede Anfrage isoliert zu bearbeiten, so dass Probleme mit einem einzelnen Prozess keinen anderen beeinflussen. Das MPM ist stark selbstregulierend, so dass es selten notwendig ist, seine Konfigurationseinstellungen zu justieren. Das Wichtigste ist, dass MaxClients groß genug ist, so viele gleichzeitige Anfragen zu bedienen, wie Sie erwarten, aber klein genug, um sicherzustellen, dass genug physischer Arbeitsspeicher für alle Prozesse vorhanden ist.

Apache-MPM-worker: Dieses Multi-Processing-Modul (MPM) implementiert einen Hybrid-Server mit Multi-Thread und Multi-Prozess-Unterstützung. Durch die Verwendung von Threads für die Bedienung von Anfragen ist er in der Lage, eine große Anzahl von Anfragen mit weniger Systemressourcen als ein Prozess-basierter Server zu bedienen. Er behält jedoch viel von der Stabilität eines Prozess-basierten Servers bei, indem er mehrere Prozesse verfügbar hält, jeden mit etlichen Threads.

Die wichtigsten Direktiven zur Steuerung des MPMs sind ThreadsPerChild, welche die Anzahl der Threads beeinflusst, die von jedem Kindprozess verwendet werden, und MaxClients, welche die maximale Gesamtzahl an Threads regelt, die gestartet werden können.

Standardmäßig wird bei der Installation unter Debian das Apache MPM-worker Module installiert. Sollte man späterhin wechseln wollen, so kann man dies durch die Installation des MPM-prefork Moduls erreichen (das MPM-worker Modul wird dann automatisch deinstalliert):

apt-get install apache2-mpm-prefork

Die Namen der beiden MPM-Pakete lauten:

- apache2-mpm-prefork
- apache2-mpm-worker

Prüfen, ob der Dienst läuft

root@game:~# netstat -lntp
Aktive Internetverbindungen (Nur Server)
Proto Recv-Q Send-Q Local Address           Foreign Address         State       PID/Program name
tcp        0      0 0.0.0.0:80              0.0.0.0:*               LISTEN      2601/apache2 
...

Alternativ Eingabe von http://localhost im Browser.

Starten und Beenden des HTTP-Servers

Bei der Installation werden automatisch start/stop-Skripte unter /etc/init.d angelegt, so dass man apache2 mit

  • systemctl restart apache2
  • systemctl stop apache2
  • systemctl status apache2
  • systemctl start apache2


/etc/init.d/apache2 start 	starten
/etc/init.d/apache2  stop	stoppen
/etc/init.d/apache2  restart	neu starten

kann.

Ausserdem werden Links in den entsprechenden Runleveln angelegt, so dass apache beim nächsten Neustart des Rechners automatisch mitgestartet wird.

Für Testzwecke bietet es sich an den Server (Binarie) direkt zustarten zumal man hier auch weitere Möglichkeiten hat Fehler in der Konfgurationsdatei zu erkennen.

Das Absetzen des Befehls apache2 -h bewirkt die Ausgabe einer kurzen Zusammenfassung der vorhandenen Kommandozeilenoptionen:

pate:~# apache2 -h
Usage: apache2 [-D name] [-d directory] [-f file]
               [-C "directive"] [-c "directive"]
               [-k start|restart|graceful|stop]
               [-v] [-V] [-h] [-l] [-L] [-t] [-S]
Options:
  -D name           		: define a name for use in <IfDefine name> directives
  -d directory      		: specify an alternate initial ServerRoot
  -f file          			: specify an alternate ServerConfigFile
  -C "directive"    		: process directive before reading config files
  -c "directive"    		: process directive after reading config files
  -e level         	 	: show startup errors of level (see LogLevel)
  -E file           		: log startup errors to file
  -v               			: show version number
  -V                			: show compile settings
  -h                			: list available command line options (this page)
  -l                			: list compiled in modules
  -L                			: list available configuration directives
  -t -D DUMP_VHOSTS 	: show parsed settings (currently only vhost settings)
  -S                			: a synonym for -t -D DUMP_VHOSTS
  -t                			: run syntax check for config files

Konfiguration des Servers

Nach der Installation aus Paketen liegen die Konfigurationsdateien bei Debian unter /etc/apache2. Die Konfigurationsdateien werden hier gesplittet, was den Vorteil von übersichtlichen kleinen Dateien gegenüber einer großen unübersichtlichen Datei bringt.

Es liegt danach unter /etc/apache2 folgende Verzeichnisstruktur vor.

pate:~# tree  -d  /etc/apache2
/etc/apache2
|-- conf.d		=>	Verzeichnis für freiwählbare Konfgurationsdateien  
|-- mods-available	=>	Verfügbare Module  
|-- mods-enabled	=>	Aktivierte Module
|-- sites-available	=>	Verfügbare Webseiten 
|-- sites-enabled	=>	Aktivierte Webseiten
|-- ssl			=>	Secure Socket Layer Konfgurationsdateien
6 directories

Die Hauptkonfigurationsdatei ist die apache2.conf. Darin werden über Include-Anweisungen weitere Dateien unterhalb von /etc/apache2 eingebunden. Die Hauptkonfigurationsdatei /etc/apache2/apache2.conf sieht gekürzt folgendermassen aus.

pate:/etc/apache2# cat /etc/apache2/apache2.conf
ServerRoot "/etc/apache2"
LockFile /var/lock/apache2/accept.lock
PidFile /var/run/apache2.pid
Timeout 300
KeepAlive On
MaxKeepAliveRequests 100
KeepAliveTimeout 15
StartServers         5
MaxClients          25
MaxClients          150
MinSpareThreads      25
MaxSpareThreads      75
ThreadsPerChild      25
MaxRequestsPerChild  0
User www-data
Group www-data
LogFormat "%h %l %u %t \"%r\" %>s %b \"%{Referer}i\" \"%{User-Agent}i\"" combined
LogFormat "%h %l %u %t \"%r\" %>s %b" common
LogFormat "%{Referer}i -> %U" referer
LogFormat "%{User-agent}i" agent
ErrorLog /var/log/apache2/error.log
Include /etc/apache2/mods-enabled/*.load
Include /etc/apache2/mods-enabled/*.conf
Include /etc/apache2/httpd.conf
Include /etc/apache2/ports.conf
Include /etc/apache2/conf.d/[^.#]*
Include /etc/apache2/sites-enabled/[^.#]*
UseCanonicalName Off
TypesConfig /etc/mime.types
DefaultType text/plain
HostnameLookups Off
DirectoryIndex index.html index.cgi index.pl index.php index.xhtml
pate:/etc/apache2# cat ports.conf
Listen 80
pate:/etc/apache2# cat sites-available/default 
<VirtualHost *:80>
       ServerAdmin webmaster@localhost
       DocumentRoot /var/www
       <Directory />
               Options FollowSymLinks
               AllowOverride None
       </Directory>
       <Directory /var/www/>
               Options Indexes FollowSymLinks MultiViews
               AllowOverride None
               Order allow,deny
               allow from all
       </Directory>
       ScriptAlias /cgi-bin/ /usr/lib/cgi-bin/
       <Directory "/usr/lib/cgi-bin">
               AllowOverride None
               Options +ExecCGI -MultiViews +SymLinksIfOwnerMatch
               Order allow,deny
               Allow from all
       </Directory>
       ErrorLog /var/log/apache2/error.log
       LogLevel warn
       CustomLog /var/log/apache2/access.log combined
   Alias /doc/ "/usr/share/doc/"
   <Directory "/usr/share/doc/">
       Options Indexes MultiViews FollowSymLinks
       AllowOverride None
       Order deny,allow
       Deny from all
       Allow from 127.0.0.0/255.0.0.0 ::1/128
   </Directory>
</VirtualHost>

Globale Einstellungen

Die folgenden Einstellungen finden sich bei Source-Installation in der httpd.conf, bei Debian Paketinstallation in der apache2.conf oder der in der Klammer genannten Dateien.

ServerRoot

ServerRoot gibt das Wurzelverzeichnis an, unter dem sich die Konfigurations-, Fehler- und Log­dateien befinden. Diese Angabe darf nicht mit einem ‘/’ enden. Man kann dieses Verzeichnis auch als “Arbeitsverzeichnis” des Apache bezeichnen

LockFile

Pfad zur Lockdatei von Apache. Die Anweisung sollte normalerweise bei der Voreinstellung belassen werden. Der Hauptgrund, sie zu ändern, ist, wenn das logs-Verzeichnis auf einem per NFS-eingebundenen Laufwerk liegt, da die Lock-Datei auf einer lokalen Platte abgelegt sein muss.

PidFile Angabe der Datei, in welcher der Server die Prozess-ID des Daemons ablegt. Wird der Dateiname nicht absolut angegeben, wird er als relativ zum ServerRoot interpretiert.

Timeout

Mit dieser Direktive wird eine Zeitspanne definiert, die der Server auf verschieden Dinge wartet, bevor er eine Anfrage abbricht. Derzeit werden über den hier angegebenen Wert Timeouts für 3 Ereignisse definiert:

  1. Die gesamte Zeispanne, die benötigt wird, um eine GET-Anfrage zu empfangen.
  2. Die Zeitspanne zwischen dem Empfang von TCP-Paketen einer POST- oder PUT-Anfrage.
  3. Die Zeitspanne zwischen ACKs bei der Übermittlung der TCP-Pakete der Antwort.

KeepAlive

Diese Direktive dient dem An- bzw. Abschalten von persisteten HTTP-Verbindungen. Bei persistenten Verbindungen werden mehrere Anfragen über die gleiche TCP-Verbindung gesendet.

MaxKeepAliveRequests

Maximale Anzahl der Anfragen, die bei einer perstistenten Verbindung zulässig sind.

KeepAliveTimeout

Definition einer Zeitspanne, die der Server während persistenter Verbindungen auf nachfolgende Anfragen wartet

StartServers

Analog zu Min/MaxSpareServers gibt diese Direktive an, wie viele Server beim Programmstart gestartet werden sollen.

Min/MaxSpareServers

Apache läuft standardmäßig multithreaded, d.h. statt einem Server warten mehrere Instanzen des gleichen Servers auf Anfragen. Jede eingehende Anfrage wird jeweils an einen der Server weitergeleitet. Dies vereinfacht die Programmierung von Apache, da nur jeweils eine einzige Anfrage beachtet werden muss. Apache passt die Anzahl der Server dynamisch an die aktuelle Last an, damit immer ausreichend viele zur Verfügung stehen. In regelmäßigen Abständen vergleicht Apache die Anzahl der laufenden Server mit den Angaben bei MinSpareServers und MaxSpareServers. Laufen weniger als MinSpareServers Server, so werden weitere gestartet; laufen mehr MinSpareServers als MaxSpareServers, werden einige beendet.

MaxClients

Um zu verhindern, dass ein böswilliger Angreifer den Server durch Überlastung außer Gefecht setzt, begrenzt diese Angabe die maximale Anzahl der gleichzeitig zugreifenden Clients. Jeder weitere Client erhält eine Fehlermeldung. Wählen Sie deshalb einen entsprechend großen Wert. Hierbei handelt es sich um die Anzahl tatsächlich gleichzeitig offener Verbindungen, wobei der voreingestellte Wert von 150 schon sehr hoch gewählt ist.

MaxRequestsPerChild

Obergrenze für die Anzahl von Anfragen, die ein einzelner Kindprozess während seines Lebens bearbeitet

Listen

(in ports.conf bei Paketinstallation) Standardmäßig läuft Apache auf dem HTTP-Port (80). Mit dieser Direktive können Sie Apache auf einem anderen Port, bzw. auf einer bestimmten IP-Adresse laufen lassen.

Listen 80
Listen 12.34.56.78:80

Hauptserver-Konfiguration

In diesem Abschnitt werden Einstellungen gemacht, die den Hauptserver betreffen. Werden vir­tuelle Server verwendet, so beantwortet der Hauptserver alle Anfragen, die nicht von einem virtu­ellen Server beantwortet werden.

User

Der Benutzer, unter dessen UID der Server laufen soll. Hierfür muss der Server von root gestartet werden. Alle Zugriffe auf die HTML-Dateien und Skripte werden im Namen dieses Benutzers ausgeführt. Dies bedeutet eine stark erhöhte Sicherheit, da Programmierfehler in den Seiten oder Skripten nicht bewirken können, dass ein Angreifer Programme als root ausführen kann. Er hat lediglich die gleichen Rechte wie der Besitzer der Seiten/Programme, darf also nicht mehr als z.B. der Benutzer wwwrun. Auf der anderen Seite müssen wir aber auch darauf achten, dass der Benutzer wwwrun auf die entsprechenden Dateien (Skripte, Seiten, ...) zumindest lesend zugreifen kann.

Group

Die Gruppe, unter deren GID der Server laufen soll. Hierfür muss der Server von root gestartet werden.

LogFormat

Definition eines benannten Formates für Logdateien. Über den Namen kann auf ein definiertes Format zugegriffen werden.

ErrorLog

Analog zu den Webzugriffen lassen sich auch die Zugriffsfehler protokollieren. Hierbei stehen allerdings keine unterschiedlichen Formate zur Verfügung.

ErrorLog /var/log/apache2/error.log

Include

Mit der Include-Direktive können weitere Konfigurationsdateien innerhalb der Serverkonfigurationsdatei eingefügt werden.

Alias

Mit dieser Option kann die normale Verzeichnisstruktur des Servers durchbrochen werden. Man gibt hier jeweils den Zielnamen gefolgt von dem Originalnamen an. Jeder Zugriff auf den Zielnamen wird auf den Originalnamen umgeleitet. Will man als Zielnamen ein Verzeichnis haben, so ist dieser mit einem abschließenden / zu versehen.

Alias /icons/ "/usr/local/apache2/icons/"

UseCanonicalName

Durch diese Direktive wird bestimmt, wie der Server seinen eigenen Namen und Port ermittelt.

  • UseCanonicalName On Verwendung von Namen und Port, die mit ServerName angegeben wurden.
  • UseCanonicalName Off Verwendung des vom Client übermittelten Namens und Ports.
  • UseCanonicalName DNS Verwendung des Nameservers.

TypesConfig

Pfad zur Konfigurationsdatei für die MIME Typen.

DefaultType

MIME-Content-Type, der gesendet wird, wenn der Server den Typ nicht auf andere Weise ermitteln kann

HostNameLookups

Jeder Zugriff auf den Webserver wird protokolliert, wobei standardmäßig der zugreifende Client nur mit seiner IP-Adresse aufgeführt wird. Will man diese Statistiken auswerten, so will man meist auch den Namen der Internetdomain wissen, in der sich der Client befindet, um z.B. das Herkunftsland zu erfahren. Hierzu muss der DNS-Server mit einem reverse lookup befragt werden, der eine IP-Adresse in den entsprechenden Hostnamen umwandelt Dieser Zugriff benötigt Zeit und Ressourcen, so dass man ihn normalerweise nicht aktivieren sollte. Gute Loganalyse-Programme können die reverse lookups auch während der Analyse der Logdatei durchführen.

Eine gute und kostenlose Software für die Logfile-Analyse ist unter www.mrunix.net/webalizer/ zu finden.

HostNameLookups Off

DirectoryIndex

Wird bei einer Anfrage als Ressource der Name eines Verzeichnisses angegeben, so wird stan­dardmäßig dessen Inhalt ausgegeben. Dies will man normalerweise nicht und erzeugt deshalb eine Datei, die statt dessen ausgegeben werden soll. Mit dieser Direktive gibt man den Namen dieser Datei an. Standardmäßig sollte man hier index.html angeben, sowie index.htm, wenn DOS-Programme zur Erzeugung von HTML-Seiten verwendet werden.

DirectoryIndex index.html index.htm

CustomLog

(in sites-available/default bei Paketinstallation)
Mit dieser Direktive bestimmt man den Namen der Datei, in der die Webzugriffe protokolliert wer­den. Das Format der Logeinträge kann selbst definiert werden. Es stehen mehrere Formate zur Auswahl

  • common Standardformat
  • refer Angabe der verweisenden Webseite
  • agent Angabe des benutzten Webbrowsers
  • combined Kombination aus common, refer und agent

Welches Format für eine Site am besten geeignet ist, muss man selbst entscheiden, aber das combined-Format ist in der Regel keine schlechte Wahl.

ScriptAlias (in sites-available/default bei Paketinstallation)
Diese Direktive gibt an, in welchem Verzeichnis sich CGI-Skripte befinden und verwendet die gleiche Syntax wie Alias, d.h. es sind die gleichen Regeln für Verzeichnisse zu beachten. Jede Datei, die sich in dem angegebenen Verzeichnis befindet, wird nicht an den Client übermittelt, sondern ausgeführt und seine Ausgabe an den Client geschickt.

ScriptAlias /cgi-bin/ "/usr/local/apache2/cgi-bin/"

ServerAdmin

(in sites-available/default bei Paketinstallation)
Alle Fehlermeldungen erhalten eine E-Mail-Adresse, an die man sich bei Problemen wenden kann. Diese Adresse wird mit dieser Direktive definiert. Hier sollte die E-Mail-Adresse der Person angegeben werden, die für die Behebung von Fehlern auf der Website (z.B. Fehler 404 Datei nicht gefunden) verantwortlich ist.

DocumentRoot

(in sites-available/default bei Paketinstallation)
Das Wurzelverzeichnis, in dem sich die Dokumente befinden, die der Server ausliefern soll. Hier könnte dann eine HTML-Datei index.html liegen, die angezeigt wird, wenn ein Client auf die Res­source / (z.B.: http://www.webmasters-europe.de/) unseres Webservers zugreift.

DocumentRoot "/usr/local/apache2/htdocs"

UserDir

Apache erlaubt es, dass jeder Benutzer des Servers eigene Dateien auf den Webserver stellen kann. Hierzu kopiert der User einfach alle entsprechenden Dateien in ein bestimmtes Unterverzeichnis seines Heimatverzeichnisses. Der Name dieses Unterverzeichnisses wird mit dieser Direktive eingestellt. Eine Angabe von public_html bedeutet, dass sich die HTML-Dateien des Benutzers thomas im Verzeichnis ~thomas/public_html befinden und über http://servername/~thomas/ ansprechbar sind.

AccessFileName

Jedes Verzeichnis lässt sich mit einem Passwort vor Zugriffen schützen, indem man in dem je-weiligen Verzeichnis eine bestimmte Datei erzeugt. Der Name der Datei lässt sich mit dieser Direktive einstellen; normalerweise verwendet man .htaccess. AccessFileName .htaccess

Bereiche

Durch Bereiche lassen sich bestimmte Einstellungen auf bestimmte Teile, z.B. spezielle Verzeichnisse, einschränken. Apache kennt mehrere Bereiche, von denen die wichtigsten hier erläutert werden.

Die Definition von Bereichen entspricht hierbei der SGML-Syntax, d.h. sie werden durch den Bereichsnamen in spitzen Klammern eingeleitet, z.B. <Directory> und mit dem Namen in spitzen Klammern mit einem / davor, z.B. </Directory>, beendet. Alle dazwischen angegebenen Direktiven beziehen sich nur auf diesen Bereich und nicht auf die anderen Bereiche oder den Webserver selbst.

<Directory>

Mit diesem Bereich kann man Direktiven auf einzelne Verzeichnisse beschränken, d.h. sie gelten nur dort und in allen Unterverzeichnissen des angegebenen Verzeichnisses. Angaben in Unter­verzeichnissen können Angaben in höherliegenden Verzeichnissen allerdings überschreiben:

<Directory /home/dosuser>
    DirectoryIndex index.htm
</Directory>
<Directory /home/dosuser/poweruser>
    DirectoryIndex index.html
</Directory>

Bei diesem Beispiel ist die Standard-Datei index.htm für das Verzeichnis /home/dosuser und alle Unterverzeichnisse außer für das Unterverzeichnis “poweruser”.

<Location>

Der Bereich <Location> ist dem Bereich <Directory> sehr ähnlich. Er bezieht sich auch auf ein Verzeichnis und dessen Unterverzeichnisse. Er unterscheidet sich von <Directory> lediglich durch die Sichtweise auf das Verzeichnis: Durch <Location> wird das Verzeichnis angegeben, wie es der Benutzer am Browser angibt. Ein Beispiel veranschaulicht den Unterschied zwischen den beiden Bereichen:

<Directory /var/www/dosdir>
     DirectoryIndex index.htm
</Directory>
<Location /dosdir>
     DirectoryIndex index.htm
</Location>

Diese zwei Beispiele haben im Großen und Ganzen die gleiche Wirkung: Im Unterverzeichnis dosdir unseres Servers heisst die Index-Datei index.htm. Der Unterschied ist die Betrachtungsweise: Bei <Directory> betrachtet man das Verzeichnis auf dem Server, das der Benutzer (Browser) nicht erfahren kann. Beim Beispiel für <Location> gibt man das Verzeichnis an, wie es im Browser angegeben ist.

<Files>

Mit diesem Bereich kann man Direktiven auf einzelne Dateie beschränken.

Wird in der Files Klammer ein absoluter Dateiname angegeben, so gelten die Anweisungen in der Klammer nur für diese Datei. Wird jedoch ein einfacher Dateiname angegeben, so gelten die Angaben für alle Dateien dieses Namens. Die Filesklammer darf auch in der Directory Klammer enthalten sein.

<Directory /usr/local/apache2/htdocs/Info> 
 <Files ".htaccess"> 
     Order deny,allow
     deny All 
 </Files> 
</Directory> 

Dieses Beispiel verbietet z.B. den Zugriff auf alle Dateien des Namens geheim.html aus dem angegebenen Verzeichnis oder einem Unterverzeichnis davon.

Bei den Verzeichnis, Datei und URL-Angaben dürfen auch Dateimusterzeichen (*,?, ) oder reguläre Ausdrücke verwendet werden. Bei Verwendung von regulären Ausdrücken müssen diese in " " eingeschlossen sein und vor dem regulären Ausdruck muß eine Tilde ~ stehen. <Directory ~ "/web/.*docs/.*"> .... </Directory>

Zugriffsbeschränkungen

Oft ist es wichtig, bestimmte Bereiche oder gar den ganzen Server durch Zugriffsbeschränkungen zu schützen. Dies kann sinnvoll sein, um z.B. Zugriffe auf den Webserver des Intranet grundsätzlich nur von Rechnern aus dem Intranet zuzulassen. Oder Sie wollen auf Ihrem Webserver Preislisten veröffentlichen, die nur von einem bestimmten Kundenkreis lesbar sein dürfen. Apache bietet hier eine sehr umfangreiche Zugriffskontrolle auf seine Ressourcen an. Prinzipiell sollen hier zwei Möglichkeiten besprochen werden, Zugriffe einzuschränken:

  • IP (Rechner)-basierende Zugriffsbeschränkung
  • Zugriffsbeschränkung mit Benutzerauthentifikation

Auch bei der Vergabe der Rechte gibt es mehrere Möglichkeiten, wer die Rechte vergibt. Man kann hier folgende Unterscheidungen machen:

  • Rechtevergabe durch den Administrator des Webservers (im Allgemeinen root)
  • Rechtevergabe durch den Administrator der Webseiten

Wir betrachten zunächst die Möglichkeiten, die der Administrator des Servers hat, Zugriffsbes­chränkungen anzuwenden.

Hostbasierende Zugriffsbeschränkungen

Zunächst sollten wir uns überlegen, was wir vor Zugriffen schützen wollen: Unseren ganzen Server, bestimmte Dateien, einzelne Verzeichnisse oder ganze Verzeichnisbäume. Entsprechend unserer Entscheidung wählen wir zunächst den passenden Bereich, den wir schützen wollen.

Szenario

Der Webserver hat folgende Daten:

  • IP-Nummern: 192.168.0.1 und 192.168.1.1
  • Netzwerke des Intranet: 192.168.0.0 und 192.168.1.0, Netzmaske: 255.255.255.0
  • Verzeichnis der html-Dokumente: /var/www

Optionen:

Name Wert Default Kontext Bemerkung
allow from IP-Nr|Domainname|all <Directory>, <Files>, <Location>,<Limit>,.htaccess Erlaubt den Zugriff explizit für einen Rechner oder ein Sub-Netz.
deny from IP-Nr|Domainname|all <Directory>, <Files>, <Location>,<Limit>,.htaccess Verbietet den Zugriff explizit für einen Rechner oder ein Sub-Netz.
Order deny,allow allow,deny deny,allow <Directory>, <Files>, <Location>,<Limit>,.htaccess deny,allow verbietet zuerst und läßt anschließend Ausnahmen zu. allow,deny erlaubt zuerst und schränkt anschließend die Erlaubnis ein.
Require User-ID / Group-ID / valid-user <Directory>, <Files>, <Location>,<Limit>,.htaccess Erlaubt dem angegebenen Nutzer bzw. Gruppenmitglied den Zugriff.valid-user erlaubt jedem Nutzer aus der Passworddatei den Zugriff.
Satisfy All oder Any All <Directory>, <Files>, <Location>,<Limit>,.htaccess Kombiniert die Kriterien bzgl. des Rechners und des Nutzers.All: beide Kriterien müssen erfüllt sein. Any: mindestens eins der beiden Kriterien muß erfüllt sein.


Wir wollen erreichen, dass nur Rechner aus dem Intranet auf die html-Dokumente zugreifen dürfen.

<Directory /var/www>
    AllowOverride None
    Order Deny,Allow
    Deny from all
    Allow from 192.168.0.0/255.255.255.0
    Allow from 192.168.1.0/255.255.255.0
</Directory>

Zunächst wird über Order die Reihenfolge festgelegt, in der Apache die einzelnen Direktiven abarbeitet: Zuerst werden die Direktiven für Deny abgearbeitet. Apache merkt sich hierbei für einen zugreifenden Rechner den Zustand, ob dieser zugreifen darf oder nicht. In diesem Beispiel ergibt sich für alle Rechner zunächst der Zustand Deny (auch für die Rechner des lokalen Netzes, da diese auch unter all fallen). Danach werden die Regeln für Allow abgearbeitet, der Zustand für den zugreifenden Rechner wird eventuell auf Allow umgestellt. In unserem Beispiel ist es so, dass Rechner aus dem Intranet (192.168.1.0/24 und 192.168.0.0/24) von einer der Allow-Direktiven beschrieben werden und damit der Zustand auf Allow umgestellt wird. Nachdem alle Regeln abgearbeitet sind, ist der letzte Zustand für einen Rechner aus dem Intranet Allow. Damit dürfen Rechner aus dem lokalen Netz auf diesen Bereich zugreifen, alle anderen Rechner nicht.

Rechnernamen
Es ist auch möglich, Zugriffsbeschränkungen auf Rechner- und Netznamen anzuwenden, nicht nur auf IP-Nummern. Hierzu ist es allerdings nötig, dass Apache die Möglichkeit hat, über reverse lookup die IP-Nummer des zugreifenden Rechners in dessen Namen aufzulösen. Diese Direktive ist unabhängig von der Direktive “HostNameLookups“!

Betrachten wird das gleiche Beispiel, wenn wir davon ausgehen, dass alle Rechner unseres lokalen Netzes über reverse lookup auf einen Namen innerhalb der Domain kurs.trainingscenter.de aufgelöst werden:

<Directory /var/www>
     AllowOverride None
     Order Deny,Allow
     Deny from all
     Allow from rechner1.int
</Directory>

Beispiel 1: Die Dateien des WWW-Verzeichnises /Info dürfen nur von den Rechnern 123.45.66.77 und 123.45.66.78 gelesen werden.

<Location /Info > 
   Order deny,allow
   deny  from all
   allow from 123.45.66.77
   allow from 123.45.66.78
</Location > 

Beispiel 2: Jeder darf die Dateien des WWW-Verzeichnises /Info lesen, nur nicht Rechner der Domain .xinux.de.

<Location /Info >
   Order allow,deny
   allow from all
   deny from .xinux.de
</Location >

Beispiel 3: Die Dateien des WWW-Verzeichnises /Info dürfen nur von dem Nutzer meyer und den Mitgliedern der Gruppe service gelesen werden.

<Location /Info >
   require user  meyer
   require group service
</Location > 

Beispiel 4: Die Dateien des WWW-Verzeichnises /Info dürfen nur von Nutzern gelesen werden, die sich authentifiziert haben und an einem Rechner der in der Domane .xinux.de sitzen.

<Location /Info >
   Order   deny,allow
   deny    from all
   allow   from .xinux.de
   require valid-user
   satisfy All
</Location >

Beispiel 5: Das WWW-Dokument /Info/geheim.html darf nur von den Rechnern 123.45.66.77 und 123.45.66.78 gelesen werden.

<Location /Info/geheim >
   Order deny,allow
   deny  from all
   allow from 123.45.66.77
   allow from 123.45.66.78
</Location >

Alternativ kann auch konfiguriert werden:

<Directory /usr/local/apache2/htdocs/Info >
  <Files geheim.html >
   Order deny,allow
   deny  from all
   allow from 123.45.66.77
   allow from 123.45.66.78
  </Files >
</Directory >

Standard-Authentifizierung

Es ist auch möglich, Verzeichnisse so zu schützen, dass ein Benutzer sich zunächst mit Benutzernamen und Passwort am HTTP-Server anmelden muss, bevor er auf bestimmte Ressourcen zugreifen kann. Diese Standard-Benutzerauthentifikation ist mit jedem modernen Browser möglich. Beim Zugriff auf eine Seite im geschützten Bereich des Servers fordert der Browser den Benutzer zur Eingabe des Benutzernamens und eines Passwortes auf. Diese überträgt der Browser dann bei weiteren Zugriffen an den HTTP-Server. Auf Client-Seite ist also nichts einzurichten. Die Möglichkeit, Zugriffsrechte für einzelne Benutzer festzulegen, läuft prinzipiell ähnlich ab wie bei den IP-basierenden Zugriffsrechten: Wir legen zunächst den Bereich fest, für den die Direktiven gelten sollen, dann aktivieren wir für diesen Bereich Zugriffsbeschränkungen auf Benutzerebene:

<Directory /var/www>
    AllowOverride AuthConfig
</Directory>

AuthConfig aktiviert für diesen Bereich die Möglichkeit, Benutzerauthentifikation zur Zugriff­skontrolle zu nutzen. Zur Benutzerauthentifikation ist es natürlich unumgänglich, dass man dem HTTP-Server eine Datenbank mit Benutzernamen und Passwörtern zur Verfügung stellt. Die kann im einfachsten Fall (auch hier in unserem Beispiel) eine Datei mit der Benutzer- und Passwortliste sein. Außer der Angabe dieser Datei muss man noch Angaben zur Art der Benutzerauthentifikation machen und festlegen, welche Benutzer der Passwort-Datei dann auch tatsächlich auf den geschützten Bereich zugreifen dürfen. Für eine einfache Konfiguration setzen wir folgende Direktiven:

<Directory /var/www>
    AllowOverride AuthConfig
    AuthType Basic
    AuthName "geheim"
    AuthUserFile /etc/httpd/httppasswd
    Require valid-user
</Directory>

AuthType

Mit AuthType legt man fest, welches Protokoll zur Authentifizierung benutzt werden soll. Die meisten Browser beherrschen nur ein einfaches Standardprotokoll ohne Verschlüsselung. Daher sollten wir hier als Typ Basic angeben.

AuthName

Hier kann man einen Text angeben, der vom Browser im Fenster zur Eingabe des Benutzernamens und Passwortes erscheint. Er dient dem Benutzer als Information für den Bereich, an dem er sich anmeldet Wenn der Text Sonderzeichen enthält (auch Leerzeichen) müssen Sie ihn in Anführungszeichen setzen, wie im obigen Beispiel gezeigt.

AuthUserFile

Mit der Direktive AuthUserFile geben Sie die Datei an, in der die Liste der Benutzernamen und Passwörter liegt. Hier können Sie eine beliebige Datei wählen, sollten aber zum einen darauf achten, dass der Benutzer wwwrun lesend darauf zugreifen kann, da sonst Apache die Datei nicht lesen kann. Auf der anderen Seite sollten Sie aber vermeiden, dass ein Benutzer über den Webserver “von außen” auf diese Datei zugreifen kann, da er sonst Informationen über andere Benutzer erhalten könnte. In unserem Beispiel ist es nicht möglich, über HTTP auf diese Datei zuzugreifen, da sie ausserhalb des Bereiches für unsere Webseiten liegt.

Require

Die Direktive Require legt fest, welche Benutzer, die in der Passwort-Datei stehen, auch tatsächlich Zugriff auf den Bereich haben. So wäre es denkbar, dass man eine einzige Passwortdatei für verschiedene Bereiche hat und im jeweiligen Bereich nur die Benutzer angibt, die auch auf diesen Bereich Zugriff haben sollen. Wenn der Benutzer nicht in dieser Zugriffsliste steht, gewährt ihm auch die Kenntnis des richtigen Passwortes keinen Zugang. Wir haben hier zwei Möglichkeiten:

  • valid-user: Hiermit wird jedem Benutzer, der einen Benutzernamen und das passende Passwort kennt, der Zugriff erlaubt.
  • user user1, user2, ...: Nur bestimmten authentifizierten Benutzern (user1, user2, ...) wird der Zugriff gewährt. Die Benutzer sind hier in einer Liste, durch Komma und Leer-zeichen getrennt, anzugeben, also user1 usw. sind hier durch die entsprechenden Benutzer, wie sie in der Passwort-Datei vorkommen, zu ersetzen.
<Directory /var/www>
     AllowOverride AuthConfig
     AuthType Basic
     AuthName "geheim"
     AuthUserFile /etc/apache2/httppasswd
     Require user thomas, martin
</Directory>

Erzeugen der Passwort-Datei

Was uns jetzt noch fehlt, ist die Passwort-Datei selbst. Der Aufbau dieser Datei ist relativ einfach: In jeder Zeile steht ein Benutzername gefolgt von einem Doppelpunkt und dem gehashten Pass­wort:

thomas:hjjK4gj9lNPPe
martin:ks8DFja.njKsM

Das gehashte Passwort erhält man z.B. aus /etc/shadow, oder man erzeugt die Einträge wie in folgendem Beispiel:

htpasswd -c /etc/apache2/httppasswd thomas

Mit diesem Befehl kann man interaktiv einen Benutzer anlegen, wenn die Passwortdatei noch nicht existiert. Zum Anlegen weiterer Benutzer lässt man die Option -c weg:

Zugriffsbeschränkungen über .htaccess

Die Möglichkeit der Zugriffsbeschränkungen, die wir oben gesehen haben, hat zwei entscheidende Nachteile: Zum einen kann nur root die Zugriffsbeschränkungen ändern. Zum anderen muss der Webserver nach jeder Änderung neu initialisiert oder neu gestartet werden, was auch nicht unbedingt komfortabel ist.

Apache gibt auch dem Administrator der Webseiten eine einfache Möglichkeit, selbst die oben gezeigten Zugriffsbeschränkungen einzurichten. Voraussetzung

Zur Aktivierung der Zugriffsbeschränkungen muss root, wie im obigen Beispiel schon gezeigt, die Benutzung grundsätzlich aktivieren. Im hier gezeigten Beispiel wird gleichzeitig Host- und Benutzerauthentifikation benutzt:

<Directory /var/www>
     AllowOverride AuthConfig Limit
</Directory>

Weitere Einstellungen braucht der Administrator des Servers dann nicht mehr vorzunehmen.

Berechtigungen in einem Verzeichnis: .htaccess

Um einzelne Verzeichnisse auf dem Webserver vor unberechtigten Zugriffen zu schützen, legt man in dem zu schützenden Verzeichnis eine Datei an, die die Einstellungen für die Zugriffs­berechtigung enthält. Diese Datei heißt normalerweise .htaccess und kann viele Direktiven enthalten, die normalerweise in der globalen Konfigurationsdatei httpd.conf enthalten sind. Auch hier gelten Zugriffsbeschränkungen für das Verzeichnis selbst und alle Unterverzeichnisse, wenn die Direktiven in einem Unterverzeichnis nicht durch andere überschrieben werden. Der Inhalt der Datei .htaccess sieht wie folgt aus:

AuthType Basic
AuthName "Kundenbereich"
AuthUserFile /etc/apache2/httppasswd
Require valid-user

Nach Neustart des apache erfolgt die Anzeige der Seite erst nach erfolgreichem login.

Virtuelle Hosts

Die ersten Webserver verstanden nur Zugriffe auf den Host selbst. Damit war es schwierig, auf einem Rechner mehrere Webserver für verschiedene Domains zu verwalten. Schon früh wurde dieser Mangel erkannt und die HTTP-Spezifikation soweit erweitert, dass der gewünschte Zielhost mit übermittelt wurde. Der Webserver kann daran erkennen, wem der eigentliche Zugriff gilt und das ohne eine eigene IP-Adresse für jede Domain zu haben. Diese Erweiterung wird von allen gängigen Web-Browsern unterstützt.

Mit Apache kann man auf einem Rechner beliebig viele sog. virtuelle Webserver anlegen und damit beliebig viele Domains verwalten.

IP-basierende virtuelle Hosts

Für jeden virtuellen Webserver ist eine eigene IP-Adresse notwendig. Das kann entweder dadurch geschehen, dass auf eine Netzwerkkarte mehrere IP-Nummern gebunden werden, oder dass der Server über mehrere Netzwerkkarten und damit IP-Nummern verfügt. IP-basierende virtuelle Hosts sind für den Client transparent, da jeder virtuelle Server über eine eigene IP-Nummer verfügt. Es ist auch nicht nötig, für Anfragen das Protokoll HTTP/1.0 oder höher zu verwenden.

Namensbasierende virtuelle Hosts

Es ist nicht nötig, für jeden virtuellen Webserver eine eigene IP-Nummer auf dem Server vorzu­halten. Mehrere Namen für virtuelle Webserver können auf einer einzigen IP-Nummer ansprechbar sein. Voraussetzung für die Nutzung von virtuellen Webservern ist das Übertragungsprotokoll HTTP ab Version 1.0.

Voraussetzungen

  • Nameservereintrag

Die Konfiguration virtueller Webserver ist relativ einfach. Als Grundvoraussetzung muss der Nameservereintrag für den Webserver auf mindestens eine IP-Nummer des Webservers zeigen. Wir können das mit den Befehlen host bzw. ping prüfen. Wenn diese Voraussetzung nicht erfüllt ist, kann ein Client (Browser) unseren virtuellen Webserver nicht ansprechen, da ihm die IP-Nummer des Servers nicht bekannt ist.

Verzeichnisse für virtuelle Server

Für jeden zu verwaltenden Webserver empfiehlt es sich, ein eigenes Verzeichnis zu erstellen und evtl. einen Benutzer anzulegen, dem alle diese Dateien gehören und mit dem sich der virtuelle Server verwalten lässt. Hier können dann für den Verwalter des Servers Unterverzeichnisse für log-Dateien, html-Dokumente und sonstige Dateien liegen, die für den Betrieb des virtuellen Webservers gebraucht werden.

  • Globale Konfiguration

Um namensbasierende virtuelle Server von IP-basierenden zu unterscheiden, benötigt man die Direktive NameVirtualHost, mit der man die IP-Adresse der virtuellen Server angibt. Hat man mehrere IP-Adressen, so sind diese in separaten Zeilen anzugeben.

NameVirtualHost 12.34.56.78

Wenn alle Netzwerkkarten des Webservers für virtuelle Hosts benutzt werden sollen, kann man einfach einen Stern (*) statt der IP-Nummer angeben:

  • NameVirtualHost

Die Direktive NameVirtualHost ist zwingend für den Betrieb von name-based virtuellen Webservern nötig! Konfiguration für einen virtuellen Webserver Jeder virtuelle Server hat seinen eigenen Bereich in der Apache-Konfigurationsdatei, der mit VirtualHost markiert ist. Innerhalb dieses Bereichs kann (fast) jede Direktive stehen, die auch in der allgemeinen Serverkonfiguration erlaubt ist.

NameVirtualHost 192.168.254.30:80
<VirtualHost 192.168.254.30:80>
       ServerName game
       DocumentRoot /var/www/game
       <Directory /var/www/game>
               Options Indexes FollowSymLinks MultiViews
               AllowOverride AuthConfig Limit
               Order allow,deny
               allow from all
       </Directory>
       ErrorLog /var/log/apache2/game_error.log
       LogLevel warn
       CustomLog /var/log/apache2/game.log combined
</VirtualHost>

<VirtualHost 192.168.254.30:80>
       ServerName game1
       DocumentRoot /var/www/game1
       CustomLog /var/log/apache2/game1.log combined
       ErrorLog /var/log/apache2/game1_error.log
       <Directory /var/www/game1>
               Options Indexes FollowSymLinks MultiViews
               AllowOverride None
               Order allow,deny
               allow from all
       </Directory>
</VirtualHost>

Im obigen Beispiel sind die wichtigsten Direktiven angegeben, die nötig sind, um einen virtuellen Host zu betreiben: Der Name des virtuellen Hosts (ServerName) und eigene Log-Dateien für diesen Server.

Beispiel: Virtuelle Hosts

Nachdem wir nun die wichtigsten Punkte der Grundkonfiguration kennengelernt haben, betrachten wir ein Beispiel für die Anwendung virtueller Hosts. Wir setzen einen HTTP-Server für folgende Konfiguration auf: Wir sind angehender Internetprovider und sollen für zwei Kunden den Webserver für deren Domain hosten. Die Host-Namen der Webserver unserer Kunden sind:

www.apfel.int
www.birne.int

Die DNS-Einträge für diese Host-Namen werden in die IP-Adresse unseres Webservers aufgelöst, d.h. wir brauchen uns um die Namensauflösung hier keine Gedanken zu machen. Die einzelnen Kunden sollen

  • selbst ihre Seiten verwalten können
  • die Logdateien ihres Webservers einsehen können
  • Zugriffsbeschränkungen für Benutzer und Hosts einrichten können

Benutzerverwaltung für den Webserver

Damit die Kunden selbst ihre Seiten verwalten können, muss unser Webserver die einzelnen Kunden als Benutzer kennen. Zum Verwalten der Seiten ist eine Authentifikation nötig, um unberechtigte Zugriffe zu verbieten. Unter Linux bietet es sich an, für jeden Kunden einen Benutzer anzulegen. Dadurch können wir einfach einrichten, dass Kunden Dateien in ihren Bereich kopieren, beispielsweise über ftp oder scp (secure copy). Hier ist es auch sinnvoll, nicht nur die Benutzer anzulegen, sondern auch eine neue (Benutzer-)Gruppe, deren Mitglieder die Benutzer dann werden. Wir wählen als Benutzernamen aussagekräftige Namen, in diesem Fall z.B.:

  • Benutzername des Kunden 1: apfel Gruppe: wwwusers
  • Benutzername des Kunden 2: birne Gruppe: wwwusers

Musterverzeichnis anlegen

pate:/etc/apache2# mkdir /etc/webskel
pate:/etc/apache2# mkdir /etc/webskel/log

Wir legen jetzt Beispiel index.html Dateien an.

pate:/var/www/apfel# cat index.html
<HTML>
<HEAD>
<TITLE>
Webpräsenz bei Provider
</TITLE>
</HEAD>
<BODY>
Hier entsteht eine Webpräsenz gehostet von Provider
</BODY>
</HTML>

Anlegen der gruppe wwwusers

pate:/var/www# groupadd wwwusers

Anlegen der User und zuordnen zu der Gruppe

pate:/var/www# useradd -m -k /etc/webskel -g wwwusers -s /bin/false -d /var/www/apfel apfel
pate:/var/www# useradd -m -k /etc/webskel -g wwwusers -s /bin/false -d /var/www/birne birne

Danach gehören alle Dateien in den Verzeichnissen dem jeweiligen Benutzer und der Gruppe wwwusers. Wir müssen allerdings hier darauf achten, dass die Benutzer nicht auf die Verzeichnisse der anderen Benutzer, die in der gleichen Gruppe sind, zugreifen können. Ausserdem muss der Benutzer wwwrun auf alle Dateien lesend zugreifen dürfen, da Apache die Seiten sonst nicht lesen kann. Diese zwei Bedingungen kann man erfüllen, indem man die Rechte an den Dateien geschickt setzt:

pate:/var/www# chmod -R 705 apfel/
pate:/var/www# chmod -R 705 birne/

Damit ist folgendes erreicht:

Der Besitzer selbst darf auf jeden Fall lesen und schreiben. Andere Mitglieder der Gruppe (andere Kunden) dürfen überhaupt nicht auf die Dateien zugreifen Alle anderen (dazu gehört auch wwwrun) dürfen lesend auf die Dateien zugreifen. Somit haben wir das Einrichten der Benutzer und ihrer Verzeichnisse abgeschlossen.

Wenden wir uns nun der Konfiguration des Webservers zu. Zunächst müssen wir namensbasierende virtuelle Hosts erlauben, da wir in unserem Beispiel nur eine IP-Nummer für den Server haben. Sehen wir uns eine Minimalkonfiguration für einen Eintrag in der Datei /etc/httpd/httpd.conf (bei Paketinstallation unter /etc/apache2/sites-enabled, die über eine Include-Anweisung in der /etc/apache2/apache2.conf eingebunden ist), die unsere Aufgabe löst:

pate:/etc/apache2/sites-available# cat  apfel
<VirtualHost *>
        ServerAdmin webmaster@apfel.int
        DocumentRoot /var/www/apfel
        Servername www.apfel.int
        ErrorLog /var/www/apfel/log/error.log
        CustomLog /var/www/apfel/access.log combined
        <Directory /var/www/apfel>
             Options +Indexes
             AllowOverride None
             Order allow,deny
             Allow from all
       </Directory>
</VirtualHost>
pate:/etc/apache2/sites-available# cat birne
<VirtualHost *>
       ServerAdmin webmaster@birne.int
       DocumentRoot /var/www/birne
       Servername www.birne.int
       ErrorLog /var/www/birne/log/error.log
       LogLevel warn
       CustomLog /var/www/birne/access.log combined
       <Directory /var/www/birne>
            Options +Indexes
            AllowOverride None
            Order allow,deny
            Allow from all
       </Directory>
</VirtualHost>

Aktivieren der Virtuellen Seiten

pate:/etc/apache2/sites-enabled# ln -s ../sites-available/apfel apfel
pate:/etc/apache2/sites-enabled# ln -s ../sites-available/birne birne

Jetzt müssen wir nur noch mit killall -1 apache2 bzw. /etc/init.d/apache2 restart unseren HTTP-Server neu initialisieren, und der Webserver hostet die Webseiten der zwei Kunden.

Wir haben an dieser Stelle nicht besprochen, wie die Kunden ihre Webseiten pflegen. Da für die Kunden Benutzer angelegt wurden, gibt es viele Möglichkeiten, wie die Kunden ihre Dateien auf den Server kopieren können, z.B. ftp oder scp. Wie diese Dienste eingerichtet werden, wird an anderer Stelle besprochen.

Zugriffsbeschränkungen erlauben

Da alle Verzeichnisse, in denen die Seiten der Kunden liegen, unterhalb des Verzeichnisses /var/www liegen, bietet es sich an, die entsprechenden Direktiven in einen Bereich zu schreiben, der sich auf dieses Verzeichnis auf dem Server bezieht. Der passende Bereich wäre hier:

<Directory /var/www>
     AllowOverride AuthConfig Limit
</Directory>

Damit ist aus Sicht des Server-Administrators schon alles getan. Nach Reinitialisierung des Apache steht den Kunden die Möglichkeit zur Verfügung, Zugriffsrechte über .htaccess-Dateien zu vergeben.

CGI-Skripte

CGI-Skripte sind Programme, die auf dem Webserver installiert werden und bei bestimmten Clientanfragen ausgeführt werden. Die Programme erhalten Informationen über die Art der Clientanfrage, sowie evtl. in Formulare eingegebene Daten. Alles was sie ausgeben, wird an den Client weitergegeben. Es gibt keine Einschränkung, in welcher Programmiersprache diese Programme geschrieben sind; sie können z.B. in C, C++, Java, Pascal, Python, Perl usw. geschrieben sein. Ebenso gibt es keine Kontrolle darüber, was diese Programme machen.

Normalerweise verwendet man die Direktiven User und Group um einzustellen, unter welcher Benutzer- und Gruppen-ID die CGI-Skripte ausgeführt werden sollen. Man gibt hierbei den jew­eiligen Benutzer und die Gruppe an, der auch für die Administration der Webseiten zuständig ist, also in der Regel den Zugang des entsprechenden Kunden.

Damit ist sichergestellt, dass die CGI-Programme eines Kunden nur auf die eigenen Daten zugreifen und z.B. nicht die Seiten der anderen Kunden verändern können.

<VirtualHost www.provider.int:80>
    User thomas
    Group wwwusers
    [...]
</VirtualHost>


Für CGI-Skripte sind 3 Konfigurationsvarianten üblich:

  • Alle CGI-Skripte befinden sich in einem Verzeichnis z.B. /usr/local/etc/httpd/cgi-bin. Alle Dateien in diesem Verzeichnis oder den Unterverzeichnissen werden als CGI-Skripte behandelt. Schreibrechte in diesem Verzeichnis hat nur der WWWadmin.
<Location /cgi-bin >
  Options     ExecCGI
  SetHandler  cgi-script
</Location >
  • CGI-Skripte dürfen in allen Verzeichnissen enthalten sein, und sind durch die Dateiendung .cgi erkennbar.
<Directory /home >
   Options     +ExecCGI
   AddHandler  cgi-script cgi
</Directory >
  • Einzelne Dateien sind als CGI-Skript zugelassen.
<Location /~meier/ >
  <Files Auskunft.cgi_script >
    SetHandler   cgi-script
  </Files >
</Location >