Title: Dynamisch konfiguriertes virtuelles Massen-Hosting
Dieses Dokument beschreibt, wie eine beliebige Anzahl virtueller Hosts mit dem Apache effizient bedient werden kann.
Die hier beschriebenen Techniken sind interessant, wenn Ihre
httpd.conf-Datei viele
<VirtualHost>-Abschnitte enthält, die sich im
Wesentlichen gleichen. Zum Beispiel:
<VirtualHost 111.22.33.44>
DocumentRoot /www/hosts/www.customer-1.com/docs
ScriptAlias /cgi-bin/ /www/hosts/www.customer-1.com/cgi-bin
<VirtualHost 111.22.33.44>
DocumentRoot /www/hosts/www.customer-2.com/docs
ScriptAlias /cgi-bin/ /www/hosts/www.customer-2.com/cgi-bin
# blah blah blah
<VirtualHost 111.22.33.44>
DocumentRoot /www/hosts/www.customer-N.com/docs
ScriptAlias /cgi-bin/ /www/hosts/www.customer-N.com/cgi-bin
Der Grundgedanke ist es, die gesamte statische
<VirtualHost>-Konfiguration durch einen Mechanismus zu
ersetzen, der sie dynamisch erzeugen kann. Das hat eine Reihe von Vorteilen:
- Die Konfigurationsdatei ist kleiner, daher startet der Apache schneller und er benötigt weniger Speicher.
- Zum Hinzufügen neuer virtueller Hosts müssen nur die entsprechenden Verzeichnisse im Dateisystem eingerichtet und die DNS-Einträge vorgenommen werden. Der Apache muss nicht neu konfiguriert oder gestartet werden.
Der größte Nachteil ist, dass keine getrennten Protokolldateien für die einzelnen virtuellen Hosts angelegt werden können. Werden aber sehr viele virtuelle Hosts eingerichtet, dann ist das sowieso bedenklich, denn dafür werden sehr viele Dateideskriptoren benötigt. Es ist sinnvoller das Protokoll in eine Pipe oder einen FIFO-Stapel zu schreiben und mit einem Prozess am anderen Ende die Protokolldaten zu zerlegen und zu verteilen (sie können auch Statistiken zusammenstellen usw.).
Ein virtueller Host wird mit zwei Informationen definiert, nämlich mit der
IP-Adresse und den Inhalten des Host:-Headers der
HTTP-Anfrage. Die Technik des dynamischen virtuellen Massen-Hosting
basiert auf dem automatischen Einfügen dieser Informationen in den Pfadnamen
der Datei, mit der die Anfrage beantwortet wird. Dies geschieht am einfachsten
mit dem Modul
Einige Dinge müssen "getürkt" werden, damit der dynamische virtuelle Host
wie ein normaler Host aussieht. Am wichtigsten ist der Servername, mit dem der
Apache selbstreferenzierende URLs usw. erzeugt. Er wird mit der
ServerName-Direktive festgelegt und steht für CGI als
Umgebungsvariable SERVER_NAME zur Verfügung. Der zur
Ausführungszeit benutzte Wert wird mit den Einstellungen der Direktive
UseCanonicalName Off kommt der Servername
aus dem Inhalt des Host:-Headers der Anfrage. Bei der
Anweisung UseCanonicalName DNS ist er das Ergebnis einer
reversiven DNS-Suche in den IP-Adressen des virtuellen Hosts. Die erste
Variante wird für namensbasiertes dynamisches virtuelles Hosting und die zweite
für IP-basiertes Hosting benutzt. Kann der Apache den Servernamen nicht
ermitteln, weil es keinen Host:-Header gibt oder die DNS-Suche
kein Ergebnis liefert, wird der Wert mit ServerName gebildet.
Auch die DocumentRoot muss vorgetäuscht werden. Sie
steht über die Umgebungsvariable DOCUMENT_ROOT
zur Verfügung. In einer normalen Konfiguration wird ihr Wert vom Kernmodul
bei der Zuweisung von URIs zu Dateinamen benutzt, wird der Server aber für
dynamisches virtuelles Hosting konfiguriert, übernimmt ein anderes Modul
diese Aufgabe (entweder mod_vhost_alias oder
mod_rewrite), das die Zuordnung auf eine andere Weise
durchführt. Keines dieser Module übernimmt das Setzen der Variablen
DOCUMENT_ROOT, so dass sie bei der Verwendung durch
CGI-Skripte oder SSI-Dokumente einen irreführenden Wert enthält.
Der folgende Auszug aus der Datei httpd.conf implementiert
das oben beschriebene virtuelle Host-Arrangement
mit mod_vhost_alias auf eine generische Art.
UseCanonicalName Off
# Dieses Protokollformat kann pro virtuellem Host anhand des ersten Feldes # aufgeteilt werden
LogFormat "%V %h %l %u %t \"%r\" %s %b" vcommon
CustomLog logs/access_log vcommon
# Den Servernamen in die Dateinamen einbinden
VirtualDocumentRoot /www/hosts/%0/docs
VirtualScriptAlias /www/hosts/%0/cgi-bin
Diese Konfiguration kann durch Veränderung von
UseCanonicalName Off in UseCanonicalName DNS
für IP-basiertes virtuelles Hosting umgewandelt werde. Der in den Dateinamen
eingefügte Servername wird von der IP-Adresse des virtuellen Host abgeleitet.
Dieses Beispiel ist eine Anpassung des letzten Beispiels für Homepage-Server
eines Providers. Mit einer etwas komplizierteren Konfiguration können Teile
des Servernamens als Zeichenfolge für die Verwendung im Dateinamen benutzt
werden, z.B. befinden sich die Dokumente für www.user.isp.com
im Verzeichnis /home/user/. Es wird ein einziges
cgi-bin-Verzeichnis und nicht pro virtuellem Host ein
Verzeichnis benutzt.
# Einen Teil des Servernamens in Dateinamen verwenden
VirtualDocumentRoot /www/hosts/%2/docs
# Ein einziges cgi-bin-Verzeichnis
ScriptAlias /cgi-bin/ /www/std-cgi/
In der Beschreibung des Moduls VirtualDocumentRoot-Anweisungen.
Mit etwas komplizierteren Konfigurationen können Sie mit den normalen
<VirtualHost>-Direktiven den Bereich der verschiedenen
virtuellen Hosting-Konfigurationen kontrollieren. Beispielsweise kann wie folgt eine
IP-Adresse für Homepage-Kunden und eine andere für kommerzielle Kunden
eingerichtet werden. Das lässt sich selbstverständlich mit konventionellen
<VirtualHost>-Konfigurationsabschnitten kombinieren.
LogFormat "%V %h %l %u %t \"%r\" %s %b" vcommon
<Directory /www/commercial>
AllowOverride All
<Directory /www/homepages>
AllowOverride None
<VirtualHost 111.22.33.44>
CustomLog logs/access_log.commercial vcommon
VirtualDocumentRoot /www/commercial/%0/docs
VirtualScriptAlias /www/commercial/%0/cgi-bin
<VirtualHost 111.22.33.45>
CustomLog logs/access_log.homepages vcommon
VirtualDocumentRoot /www/homepages/%0/docs
ScriptAlias /cgi-bin/ /www/std-cgi/
Nach dem ersten Beispiel wurde angemerkt, dass es einfach für IP-basiertes virtuelles Hosting umgewandelt werden kann. Leider ist diese Konfiguration nicht sehr effizient, weil eine DNS-Suche pro Anfrage erforderlich ist. Wird das Dateisystem entsprechend der IP-Adressen aufgebaut und sich nicht an den Namen orientiert und die Protokollierung in ähnlicher Weise geändert wird, lässt sich das vermeiden. Der Apache muss dann den Dateinamen in der Regel nicht ermitteln und daher unterbleibt die DNS-Suche.
UseCanonicalName DNS
# Die IP-Adresse in die Protokolle übernehmen, damit sie zerlegt werden können
LogFormat "%A %h %l %u %t \"%r\" %s %b" vcommon
CustomLog logs/access_log vcommon
# Die IP-Adresse in den Dateinamen einschließen
VirtualDocumentRootIP /www/hosts/%0/docs
VirtualScriptAliasIP /www/hosts/%0/cgi-bin
Die oben aufgeführten Beispiele basieren auf mod_vhost_alias,
ein Modul, das es seit der Version 1.3.6 gibt. Haben Sie eine Version ohne
mod_vhost_alias, dann können Sie diese Technik wie unten gezeigt mit
mod_rewrite implementieren, allerdings nur für
auf Host:-Header basierende virtuelle Hosts.
Außerdem müssen noch einige Dinge für die Protokollierung beachtet
werden. Die Version 1.3.6 war die erste Version mit der Protokollformat-Direktive
%V. In den Versionen 1.3.0 - 1.3.3 hat die Option
%v das Gleiche wie %V geleistet. In
Version 1.3.4 gibt es keine Entsprechung. In allen diesen Versionen des Apache
kann die UseCanonicalName-Direktive in .htaccess
stehen, was bedeutet, das Anwender eine falsche Protokollierung verursachen können.
Deshalb sollte die %{Host}i-Direktive benutzt werden, mit der der
Host:-Header direkt protokolliert wird. Hierbei kann
:port am Ende stehen, was bei %V nicht der
Fall ist.
mod_rewriteDer folgende Auszug aus der Datei httpd.conf bewirkt das
Gleiche wie das erste Beispiel. Die erste Hälfte ist
vergleichbar mit dem entsprechenden Teil oben, für die Abwärtskompatibilität
und für die korrekte Funktion von mod_rewrite
wurden aber einige Änderungen vorgenommen. In der zweiten Hälfte wird
mod_rewrite für die eigentliche Arbeit konfiguriert.
Es gibt einige besonders schwierige Kleinigkeiten: Standardmäßig
wird mod_rewrite vor den übrigen URI-Umwandlungsmodulen
ausgeführt (mod_alias usw.). Werden sie benutzt, muss
mod_rewrite entsprechend konfiguriert werden.
Außerdem muss etwas getan werden, um ein Äquivalent für
ScriptAlias zu schaffen.
UseCanonicalName Off
# Zerlegbare Protokolle
LogFormat "%{Host}i %h %l %u %t \"%r\" %s %b" vcommon
CustomLog logs/access_log vcommon
<Directory /www/hosts>
# nicht wie ScriptAlias veranlasst werden kann.
Options FollowSymLinks ExecCGI
# Jetzt zum schwierigeren Teil:
RewriteEngine On
# Ein vom Host-Header abgeleiteter ServerName kann jede Form haben
RewriteMap lowercase int:tolower
## Zuerst das normale Dokument:
# Alias /icons/ zulassen - für andere Aliase wiederholen
RewriteCond %{REQUEST_URI} !^/icons/
# CGIs zulassen
RewriteCond %{REQUEST_URI} !^/cgi-bin/
# Der Kunstgriff
RewriteRule ^/(.*)$ /www/hosts/${lowercase:%{SERVER_NAME}}/docs/$1
## und jetzt zu CGIs - ein MIME-Typ muss festgelegt werden
RewriteCond %{REQUEST_URI} ^/cgi-bin/
RewriteRule ^/(.*)$ /www/hosts/${lowercase:%{SERVER_NAME}}/cgi-bin/$1 [T=application/x-httpd-cgi]
# Das war's!
mod_rewriteLeistet das Gleiche wie das zweite Beispiel.
RewriteMap lowercase int:tolower
# CGIs zulassen
RewriteCond %{REQUEST_URI} !^/cgi-bin/
# Den Hostnamen überprüfen, damit RewriteRule funktioniert
RewriteCond ${lowercase:%{SERVER_NAME}} ^www\.[a-z-]+\.isp\.com$
# Den virtuellen Hostnamen bis zum Beginn des URI verknüpfen
# Das [C] bewirkt, dass die nächste Manipulation für das Ergebnis # dieser Manipulation durchgeführt wird.
RewriteRule ^(.+) ${lowercase:%{SERVER_NAME}}$1 [C]
# Den richtigen Namen erzeugen
RewriteRule ^www\.([a-z-]+)\.isp\.com/(.*) /home/$1/$2
# Das globale CGI-Verzeichnis definieren
ScriptAlias /cgi-bin/ /www/std-cgi/
Bei diesem Arrangement werden erweiterte
mod_rewrite-Eigenschaften für die Umwandlung vom
virtuellen Host zur DocumentRoot mit einer separaten
Konfigurationsdatei benötigt. Das bietet mehr Flexibilität,
verlangt aber eine kompliziertere Konfiguration.
Die Vhost.map-Datei sieht folgendermaßen aus:
www.customer-2.com /www/customers/2
# ...
www.customer-N.com /www/customers/N
In der httpd.conf-Datei steht:
RewriteMap lowercase int:tolower
# Die Map-Datei definieren
RewriteMap vhost txt:/www/conf/vhost.map
# Behandlung der Aliase wie oben
RewriteCond %{REQUEST_URI} !^/icons/
RewriteCond %{REQUEST_URI} !^/cgi-bin/
RewriteCond ${lowercase:%{SERVER_NAME}} ^(.+)$
# Neuzuordnung auf Dateibasis
RewriteCond ${vhost:%1} ^(/.*)$
RewriteRule ^/(.*)$ %1/docs/$1
RewriteCond %{REQUEST_URI} ^/cgi-bin/
RewriteCond ${lowercase:%{SERVER_NAME}} ^(.+)$
RewriteCond ${vhost:%1} ^(/.*)$
RewriteRule ^/(.*)$ %1/cgi-bin/$1
Bei einer großen Anzahl virtueller Hosts können dem Apache die Dateideskriptoren (oder Datei-Handler) ausgehen, wenn jeder virtuelle Host andere Protokolldateien benutzt. Insgesamt benutzt der Apache für jedes einzelne Fehlerprotokoll einen Dateideskriptor, einen weiteren für jede weitere Protokolldatei-Direktive sowie 10 - 20 Dateideskriptoren für die interne Verwendung. Unix-Betriebssysteme limitieren die Anzahl der Dateideskriptoren, die von einem Prozess benutzt werden dürfen. Normalerweise liegt die Grenze bei 64 und kann gewöhnlich auf eine Obergrenze gesetzt werden.
Der Apache versucht zwar das Limit bei Bedarf hochzusetzen, das funktioniert aber nicht, wenn:
- das System den Systemaufruf
setrlimit()nicht kennt. - der
setrlimit(RLIMIT_NOFILE)-Call bei einem System nicht funktioniert (siehe Solaris 2.3). - die Anzahl der erforderlichen Dateideskriptoren die Obergrenze überschreitet.
- das System andere Obergrenzen für die Anzahl der Dateideskriptoren setzt,
wie zum Beispiel eine Obergrenze für
stdio-Streams mit 256 Dateideskriptoren (Solaris 2).
Wenn es zu Problemen kommt, können Sie:
- die Anzahl der Protokolldateien reduzieren. Geben Sie in
VirtualHost -Abschnitten keine Protokolldateien an, sondern schreiben Sie nur in die Hauptprotokolldateien. (Wie Sie dies tun, lesen Sie im Abschnitt Protokolldateien zerlegen.) -
die Obergrenze für die Dateideskriptoren vorm Apache-Start mit einem Skript
hochsetzen:
#!/bin/sh
ulimit -S -n 100
exec httpd
Im Abschnitt Deskriptoren und der Apache finden Sie weitere Informationen zu Problemen mit Dateideskriptoren und wie sie zu lösen sind.
Wenn Sie mehrere virtuelle Hosts in einer Datei protokollieren möchten, dann ist es sinnvoll, diese Datei anschließend zu zerlegen, damit eine statistische Analyse der einzelnen virtuellen Hosts möglich ist. Wie das geschieht, wird im folgenden beschrieben.
Als erstes muss den Protokolleinträgen ein Hinweis auf den virtuellen Host
hinzugefügt werden. Das kann mit der Direktive
%v-Variablen geschehen:
CustomLog logs/multiple_vhost_log vhost
Jetzt wird eine Protokolldatei im allgemeinen Protokollformat aber mit Angabe
des tatsächlichen virtuellen Host (unabhängig davon, was in der
Soll die Protokolldatei in einzelne Bestandteile zerlegt werden (eine Datei für
jeden virtuellen Host), dann benutzen Sie dafür das Programm
split-logfile.
Sie finden es im Apache-Verzeichnis support.
Führen Sie das Programm wie folgt aus:
Das Programm erzeugt für jeden virtuellen Host, der in der Protokolldatei
auftaucht, eine Datei, wenn der Name der Vhost-Protokolldatei übergeben
wird. Die Dateien erhalten die Bezeichnung Hostname.log.
--------------------------------------------------------------------- To unsubscribe, e-mail: [EMAIL PROTECTED] For additional commands, e-mail: [EMAIL PROTECTED]
