Apache/HTTP/Konfiguration/Abschnitte
Konfigurationsabschnitte
Direktiven in den Konfigurationsdateien können für den gesamten Server gelten oder auf bestimmte Verzeichnisse, Dateien, Hosts oder URLs beschränkt sein
- Konfigurationsabschnittscontainer oder .htaccess-Dateien werden verwendet, um den Geltungsbereich von Konfigurationsdirektiven zu ändern
Container für Konfigurationsabschnitte
Verwandte Module | Verwandte Anweisungen |
---|---|
- Es gibt zwei grundlegende Containertypen
- Die meisten Container werden für jede Anfrage ausgewertet
- Die eingeschlossenen Anweisungen werden nur auf Anfragen angewendet, die den Containern entsprechen
- Die <IfDefine>-, <IfModule>- und <IfVersion>-Container werden dagegen nur beim Starten und Neustarten des Servers ausgewertet
- Wenn ihre Bedingungen beim Start erfüllt sind, gelten die eingeschlossenen Anweisungen für alle Anfragen
- Wenn die Bedingungen nicht erfüllt sind, werden die eingeschlossenen Anweisungen ignoriert
Die <IfDefine>-Direktive umschließt Direktiven, die nur angewendet werden, wenn ein entsprechender Parameter in der httpd-Befehlszeile definiert ist
- Bei der folgenden Konfiguration werden beispielsweise alle Anfragen nur dann an eine andere Website umgeleitet, wenn der Server mit httpd -DClosedForNow gestartet wird:
<IfDefine ClosedForNow>
Redirect "/" "http://otherserver.example.com/"
</IfDefine>
Die <IfModule>-Direktive ist sehr ähnlich, außer dass sie Direktiven enthält, die nur angewendet werden, wenn ein bestimmtes Modul im Server verfügbar ist
- Das Modul muss entweder statisch im Server kompiliert sein oder es muss dynamisch kompiliert sein und seine LoadModule-Zeile muss sich weiter vorne in der Konfigurationsdatei befinden
- Diese Direktive sollte nur verwendet werden, wenn Ihre Konfigurationsdatei unabhängig davon funktionieren muss, ob bestimmte Module installiert sind oder nicht
- Sie sollte nicht verwendet werden, um Anweisungen einzuschließen, die immer funktionieren sollen, da sie nützliche Fehlermeldungen über fehlende Module unterdrücken kann
Im folgenden Beispiel wird die MimeMagicFile-Anweisung nur angewendet, wenn mod_mime_magic verfügbar ist
<IfModule mod_mime_magic.c>
MimeMagicFile "conf/magic"
</IfModule>
Die <IfVersion>-Direktive ist <IfDefine> und <IfModule> sehr ähnlich, außer dass sie Direktiven enthält, die nur angewendet werden, wenn eine bestimmte Version des Servers ausgeführt wird
- Dieses Modul ist für die Verwendung in Testsuiten und großen Netzwerken konzipiert, die mit verschiedenen httpd-Versionen und unterschiedlichen Konfigurationen umgehen müssen
<IfVersion >= 2.4>
# dies geschieht nur in Versionen größer oder
# gleich 2.4.0.
</IfVersion>
<IfDefine>, <IfModule> und <IfVersion> können negative Bedingungen anwenden, indem sie ihrem Test ein "!" voranstellen
- Diese Abschnitte können auch verschachtelt werden, um komplexere Einschränkungen zu erreichen
Dateisystem, Webspace und boolesche Ausdrücke
Die am häufigsten verwendeten Konfigurationsabschnittscontainer sind diejenigen, die die Konfiguration bestimmter Stellen im Dateisystem oder Webspace ändern
- Zunächst ist es wichtig, den Unterschied zwischen den beiden zu verstehen
- Das Dateisystem ist die Ansicht Ihrer Festplatten, wie sie von Ihrem Betriebssystem gesehen wird
- Bei einer Standardinstallation befindet sich Apache httpd beispielsweise unter /usr/local/apache2 im Unix-Dateisystem oder "c:/Program Files/Apache Group/Apache2" im Windows-Dateisystem. (Beachten Sie, dass in Apache httpd-Konfigurationsdateien immer Schrägstriche als Pfadtrenner verwendet werden sollten, auch unter Windows.) Im Gegensatz dazu ist der Webspace die Ansicht Ihrer Website, wie sie vom Webserver bereitgestellt und vom Client gesehen wird
- Der Pfad /dir/ im Webspace entspricht also dem Pfad /usr/local/apache2/htdocs/dir/ im Dateisystem einer standardmäßigen Apache-httpd-Installation unter Unix
- Der Webspace muss nicht direkt dem Dateisystem zugeordnet sein, da Webseiten dynamisch aus Datenbanken oder anderen Speicherorten generiert werden können
Dateisystem-Container
Die <Directory>- und <Files>-Direktiven sowie ihre Gegenstücke "regex" wenden Direktiven auf Teile des Dateisystems an
- Direktiven, die in einem <Directory>-Abschnitt eingeschlossen sind, gelten für das benannte Dateisystemverzeichnis und alle Unterverzeichnisse dieses Verzeichnisses (sowie für die Dateien in diesen Verzeichnissen)
- Der gleiche Effekt kann mit .htaccess-Dateien erzielt werden
- In der folgenden Konfiguration werden beispielsweise Verzeichnisindizes für das Verzeichnis /var/web/dir1 und alle Unterverzeichnisse aktiviert
<Directory "/var/web/dir1">
Options +Indexes
</Directory>
In einem <Files>-Abschnitt enthaltene Anweisungen gelten für jede Datei mit dem angegebenen Namen, unabhängig davon, in welchem Verzeichnis sie sich befindet
- So verweigern etwa die folgenden Konfigurationsanweisungen, wenn sie im Hauptabschnitt der Konfigurationsdatei platziert werden, den Zugriff auf jede Datei mit dem Namen private.html, unabhängig davon, wo sie sich befindet
<Files "private.html">
Require all denied
</Files>
Um Dateien zu adressieren, die sich in einem bestimmten Teil des Dateisystems befinden, können die Abschnitte <Files> und <Directory> kombiniert werden
- Beispielsweise wird mit der folgenden Konfiguration der Zugriff auf /var/web/dir1/private.html, /var/web/dir1/subdir2/private.html, /var/web/dir1/subdir3/private.htmlund alle anderen Instanzen von private.html, die sich im Verzeichnis /var/web/dir1/ befinden,
<Directory "/var/web/dir1">
<Files "private.html">
Require all denied
</Files>
</Directory>
Webspace-Container
Die <Location>-Anweisung und ihr Gegenstück, der Reguläre Ausdruck, ändern dagegen die Konfiguration für Inhalte im Webspace
- Die folgende Konfiguration verhindert beispielsweise den Zugriff auf alle URL-Pfade, die mit /private beginnen
- Dies gilt insbesondere für Anfragen für
- http://yoursite.example.com/private
- http://yoursite.example.com/private123
- http://yoursite.example.com/private/dir/file.html
sowie für alle anderen Anfragen, die mit der Zeichenfolge /private beginnen
<LocationMatch "^/private">
Require all denied
</LocationMatch>
Die <Location>-Anweisung muss nichts mit dem Dateisystem zu tun haben
- Das folgende Beispiel zeigt beispielsweise, wie eine bestimmte URL einem internen Apache HTTP Server-Handler zugeordnet wird, der von mod_status bereitgestellt wird
- Im Dateisystem muss keine Datei namens server-status vorhanden sein
<Location "/server-status">
SetHandler server-status
</Location>
Überlappender Webspace
Um zwei sich überlappende URLs zu haben, muss man die Reihenfolge berücksichtigen, in der bestimmte Abschnitte oder Anweisungen ausgewertet werden
<Location "/foo">
</Location>
<Location "/foo/bar">
</Location>
<Alias>es werden umgekehrt zugeordnet
Alias "/foo/bar" "/srv/www/uncommon/bar"
Alias "/foo" "/srv/www/common/foo"
Das Gleiche gilt für die ProxyPass-Anweisungen
ProxyPass "/special-area" "http://special.example.com" smax=5 max=10
ProxyPass "/" "balancer://mycluster/" stickysession=JSESSIONID|jsessionid nofailover=On
Platzhalter und reguläre Ausdrücke
Die Anweisungen <Directory>, <Files> und <Location> können jeweils Shell-artige Platzhalterzeichen wie in fnmatch aus der C-Standardbibliothek verwenden
- Das Zeichen "*" entspricht einer beliebigen Zeichenfolge, "?" entspricht einem beliebigen einzelnen Zeichen und "[seq]" entspricht einem beliebigen Zeichen in seq
- Das Zeichen "/" wird von keinem Platzhalter erkannt; es muss explizit angegeben werden
Wenn noch flexiblere Übereinstimmungen erforderlich sind, verfügt jeder Container über ein Gegenstück zu regulären Ausdrücken (regex) <DirectoryMatch>, <FilesMatch> und <LocationMatch>, die die Verwendung von perl-kompatiblen regulären Ausdrücken bei der Auswahl der Übereinstimmungen ermöglichen
- Im Abschnitt "Konfigurationszusammenführung" erfahren Sie jedoch, wie sich die Verwendung von Regex-Abschnitten auf die Anwendung von Direktiven auswirkt
Ein Nicht-Regex-Platzhalterabschnitt, der die Konfiguration aller Benutzerverzeichnisse ändert, könnte wie folgt aussehen:
<Directory "/home/*/public_html">
Options Indexes
</Directory>
Mit Regex-Abschnitten können wir den Zugriff auf viele Arten von Bilddateien gleichzeitig verweigern:
<FilesMatch "\.(?i:gif|jpe?g|png)$">
Require all denied
</FilesMatch>
Reguläre Ausdrücke, die benannte Gruppen und Rückverweise enthalten, werden der Umgebung mit dem entsprechenden Namen in Großbuchstaben hinzugefügt
- Dadurch können Elemente von Dateinamenpfaden und URLs in Ausdrücken und Modulen wie mod_rewrite referenziert werden
<DirectoryMatch "^/var/www/combined/(?<SITENAME>[^/]+)">
Require ldap-group "cn=%{env:MATCH_SITENAME},ou=combined,o=Example"
</DirectoryMatch>
Boolesche Ausdrücke
Die <If>-Direktive ändert die Konfiguration in Abhängigkeit von einer Bedingung, die durch einen booleschen Ausdruck ausgedrückt werden kann
- Die folgende Konfiguration verweigert beispielsweise den Zugriff, wenn der HTTP-Referer-Header nicht mit
http://www.example.com/ beginnt
<If "!(%{HTTP_REFERER} -strmatch 'http://www.example.com/*')">
Require all denied
</If>
Was ist zu verwenden?
Die Entscheidung zwischen Dateisystem-Containern und Webspace-Containern ist eigentlich ganz einfach
- Wenn Sie Direktiven auf Objekte anwenden, die sich im Dateisystem befinden, verwenden Sie immer <Directory> oder <Files>
- Wenn Sie Direktiven auf Objekte anwenden, die sich nicht im Dateisystem befinden (z.B. eine aus einer Datenbank generierte Webseite), verwenden Sie <Location>
Es ist wichtig, niemals <Location> zu verwenden, wenn Sie versuchen, den Zugriff auf Objekte im Dateisystem einzuschränken
- Dies liegt daran, dass viele verschiedene Webspace-Speicherorte (URLs) demselben Dateisystem-Speicherort zugeordnet werden können, wodurch Ihre Einschränkungen umgangen werden können
- Betrachten Sie folgende Konfiguration
<Location "/dir/">
Require all denied
</Location>
Dies funktioniert einwandfrei, wenn die Anfrage für http://yoursite.example.com/dir/ erfolgt
- Was aber, wenn Sie sich auf einem Dateisystem befinden, bei dem die Groß-/Kleinschreibung keine Rolle spielt? Dann könnte Ihre Einschränkung leicht umgangen werden, indem http://yoursite.example.com/DIR/ angefordert wird
- Die <Directory>-Anweisung gilt dagegen für alle Inhalte, die von diesem Speicherort bereitgestellt werden, unabhängig davon, wie sie aufgerufen werden. (Eine Ausnahme bilden Dateisystemverknüpfungen
- Das gleiche Verzeichnis kann mithilfe symbolischer Links in mehr als einem Teil des Dateisystems platziert werden
- Die <Directory>-Anweisung folgt dem symbolischen Link, ohne den Pfadnamen zurückzusetzen
- Aus Sicherheitsgründen sollten symbolische Links daher mit der entsprechenden Options-Anweisung deaktiviert werden
Wenn Sie vielleicht denken, dass dies alles nicht auf Sie zutrifft, weil Sie ein Dateisystem verwenden, bei dem zwischen Groß- und Kleinschreibung unterschieden wird, denken Sie daran, dass es viele andere Möglichkeiten gibt, mehrere Webspace-Speicherorte demselben Dateisystem-Speicherort zuzuordnen
- Daher sollten Sie immer die Dateisystem-Container verwenden, wenn Sie können
- Es gibt jedoch eine Ausnahme von dieser Regel
- Das Einfügen von Konfigurationseinschränkungen in einen <Location "/"> Abschnitt ist vollkommen sicher, da dieser Abschnitt für alle Anfragen gilt, unabhängig von der spezifischen URL
Verschachtelung von Abschnitten
Einige Abschnittstypen können in andere Abschnittstypen verschachtelt werden
- Einerseits können <Files> in <Directory> verwendet werden
- Andererseits kann <If> in <Directory>, <Location> und <Files> Abschnitten verwendet werden (jedoch nicht in einem anderen <If>)
- Die Regex-Gegenstücke der genannten Abschnitte verhalten sich identisch
Verschachtelte Abschnitte werden nach nicht verschachtelten Abschnitten desselben Typs zusammengeführt
Virtuelle Hosts
Der <VirtualHost>-Container enthält Anweisungen, die für bestimmte Hosts gelten
- Dies ist nützlich, wenn mehrere Hosts von derselben Maschine aus mit jeweils unterschiedlicher Konfiguration bedient werden
- Weitere Informationen finden Sie in der Virtual Host Documentation
Proxy
Die <Proxy>- und <ProxyMatch>-Container wenden eingeschlossene Konfigurationsanweisungen nur auf Sites an, auf die über den mod_proxy-Proxyserver zugegriffen wird und die mit der angegebenen URL übereinstimmen
- Die folgende Konfiguration erlaubt beispielsweise nur einer Teilmenge von Clients den Zugriff auf die www.example.com Website über den Proxyserver:
<Proxy "http://www.example.com/*">
Require host yournetwork.example.com
</Proxy>
Welche Anweisungen sind zulässig?
Um herauszufinden, welche Anweisungen in welchen Konfigurationsabschnitten zulässig sind, überprüfen Sie den Kontext der Anweisung
- Alles, was in <Directory>-Abschnitten zulässig ist, ist auch syntaktisch in <DirectoryMatch>-, <Files>-, <FilesMatch>-, <Location>-, <LocationMatch>-, <Proxy>- und <ProxyMatch>-Abschnitten zulässig
Es gibt jedoch einige Ausnahmen
- Die AllowOverride-Anweisung funktioniert nur in <Directory>-Abschnitten
- Die Optionen "FollowSymLinks" und "SymLinksIfOwnerMatch" funktionieren nur in <Directory>-Abschnitten oder .htaccess-Dateien
- Die Option "" kann nicht in <Files>- und <FilesMatch>-Abschnitten verwendet werden
Wie die Abschnitte zusammengeführt werden
Die Konfigurationsabschnitte werden in einer ganz bestimmten Reihenfolge angewendet
- Da dies wichtige Auswirkungen darauf haben kann, wie Konfigurationsanweisungen interpretiert werden, ist es wichtig zu verstehen, wie dies funktioniert
- Reihenfolge der Zusammenführung
- <Directory> (außer reguläre Ausdrücke) und .htaccess werden gleichzeitig ausgeführt (wobei .htaccess, falls zulässig, <Directory> überschreibt)
- <DirectoryMatch> (und <Directory "~">)
- <Files> und <FilesMatch> werden gleichzeitig ausgeführt
- <Location> und <LocationMatch> werden gleichzeitig ausgeführt
- <If> Abschnitte, auch wenn sie in einem der vorhergehenden Kontexte eingeschlossen sind
- Wichtige Anmerkungen
- Abgesehen von <Directory> werden die Abschnitte innerhalb jeder Gruppe in der Reihenfolge verarbeitet, in der sie in den Konfigurationsdateien erscheinen
- Beispielsweise entspricht eine Anfrage für /foo/bar <Location "/foo/bar"> und <Location "/foo"> (in diesem Fall Gruppe 4): Beide Abschnitte werden ausgewertet, jedoch in der Reihenfolge, in der sie in den Konfigurationsdateien erscheinen
- <Directory> (Gruppe 1 oben) wird in der Reihenfolge vom kürzesten zum längsten Verzeichnisbestandteil verarbeitet
- Beispielsweise wird <Directory "/var/web/dir"> vor <Directory "/var/web/dir/subdir">verarbeitet
- Wenn mehrere <Directory>-Abschnitte auf dasselbe Verzeichnis zutreffen, werden sie in der Reihenfolge der Konfigurationsdatei verarbeitet
- Konfigurationen, die über die Include-Direktive eingebunden werden, werden so behandelt, als befänden sie sich innerhalb der einbindenden Datei an der Stelle der Include-Direktive
- Abschnitte innerhalb von <VirtualHost>-Abschnitten werden nach den entsprechenden Abschnitten außerhalb der Virtual-Host-Definition angewendet
- Dadurch können virtuelle Hosts die Hauptserverkonfiguration überschreiben
- Wenn die Anfrage von mod_proxy bedient wird, nimmt der <Proxy>-Container in der Verarbeitungsreihenfolge den Platz des <Directory>-Containers ein
- Beim Mischen verwandter Konfigurationsanweisungen innerhalb und außerhalb von <If> ist aufgrund der Auswirkungen auf die Zusammenführungsreihenfolge Vorsicht geboten
- Die explizite Verwendung von <Else> kann helfen
- Wenn <If> in .htaccess verwendet wird, werden die eingeschlossenen Anweisungen in einem übergeordneten Verzeichnis nach den nicht eingeschlossenen Anweisungen in einem Unterverzeichnis zusammengeführt
Technischer Hinweis
Es gibt tatsächlich eine <Location>/<LocationMatch> Sequenz, die direkt vor der Namensübersetzungsphase ausgeführt wird (in der Aliases und DocumentRoots verwendet werden, um URLs Dateinamen zuzuordnen)
- Die Ergebnisse dieser Sequenz werden nach Abschluss der Übersetzung vollständig verworfen
Beziehung zwischen Modulen und Konfigurationsabschnitten
Eine Frage, die sich oft stellt, nachdem man gelesen hat, wie Konfigurationsabschnitte zusammengeführt werden, bezieht sich darauf, wie und wann Anweisungen bestimmter Module wie mod_rewrite verarbeitet werden
- Die Antwort ist nicht trivial und erfordert ein wenig Hintergrundwissen
- Jedes httpd-Modul verwaltet seine eigene Konfiguration, und jede seiner Anweisungen in httpd.conf gibt einen Teil der Konfiguration in einem bestimmten Kontext an
- httpd führt beim Lesen keinen Befehl aus
Zur Laufzeit durchläuft der Kern von httpd die definierten Konfigurationsabschnitte in der oben beschriebenen Reihenfolge, um festzustellen, welche für die aktuelle Anfrage gelten
- Wenn der erste Abschnitt übereinstimmt, wird er als aktuelle Konfiguration für diese Anfrage betrachtet
- Wenn ein nachfolgender Abschnitt ebenfalls übereinstimmt, erhält jedes Modul mit einer Anweisung in einem der Abschnitte die Möglichkeit, seine Konfiguration zwischen den beiden Abschnitten zusammenzuführen
- Das Ergebnis ist eine dritte Konfiguration, und der Prozess wird fortgesetzt, bis alle Konfigurationsabschnitte ausgewertet wurden
Nach dem oben genannten Schritt beginnt die "eigentliche" Verarbeitung der HTTP-Anfrage: Jedes Modul hat die Möglichkeit, ausgeführt zu werden und beliebige Aufgaben auszuführen
- Sie können ihre eigene endgültige zusammengeführte Konfiguration aus dem Kern des httpd abrufen, um zu bestimmen, wie sie sich verhalten sollen
Ein Beispiel kann helfen, den gesamten Prozess zu veranschaulichen
- Die folgende Konfiguration verwendet die Header-Direktive von mod_headers, um einen bestimmten HTTP-Header festzulegen
- Welchen Wert setzt httpd im CustomHeaderName-Header für eine Anfrage an /example/index.html ?
<Directory "/">
Header set CustomHeaderName one
<FilesMatch ".*">
Header set CustomHeaderName three
</FilesMatch>
</Directory>
<Directory "/example">
Header set CustomHeaderName two
</Directory>
- Directory "/" entspricht und eine Erstkonfiguration zum Festlegen des CustomHeaderName Headers mit dem Wert eins erstellt wird
- Directory "/example" entspricht und da mod_headers in seinem Code angibt, dass es im Falle einer Zusammenführung überschrieben werden soll, wird eine neue Konfiguration erstellt, um den CustomHeaderName Header mit dem Wert zweifestzulegen
- FilesMatch ".*" entspricht und eine weitere Zusammenführungsmöglichkeit entsteht, wodurch der CustomHeaderName Header mit dem Wert dreifestgelegt wird
- Schließlich wird während der nächsten Schritte der Verarbeitung der HTTP-Anforderung mod_headers aufgerufen und erhält die Konfiguration, um den CustomHeaderName-Header mit dem Wert drei zu setzen. mod_headers verwendet diese Konfiguration normalerweise, um seine Aufgabe zu erfüllen, nämlich den foo-Header zu setzen
- Dies bedeutet nicht, dass ein Modul keine komplexere Aktion ausführen kann, wie z. B. das Verwerfen von Anweisungen, weil sie nicht benötigt werden oder veraltet sind usw
Dies gilt auch für .htaccess, da sie in der Zusammenführungsreihenfolge dieselbe Priorität wie Directory haben
- Es ist wichtig zu verstehen, dass Konfigurationsabschnitte wie Directory und FilesMatch nicht mit modulspezifischen Anweisungen wie Header oder RewriteRule vergleichbar sind, da sie auf unterschiedlichen Ebenen arbeiten
Einige nützliche Beispiele
Nachfolgend finden Sie ein fiktives Beispiel, das die Reihenfolge der Zusammenführung veranschaulichen soll
- Angenommen, sie alle gelten für die Anfrage, dann werden die Direktiven in diesem Beispiel in der Reihenfolge A > B > C > D > E angewendet
<Location "/">
E
</Location>
<Files "f.html">
D
</Files>
<VirtualHost *>
<Directory "/a/b">
B
</Directory>
</VirtualHost>
<DirectoryMatch "^.*b$">
C
</DirectoryMatch>
<Directory "/a/b">
A
</Directory>
- Beispiel
Unabhängig von Zugriffsbeschränkungen in <Directory>-Abschnitten wird der <Location>-Abschnitt zuletzt ausgewertet und ermöglicht uneingeschränkten Zugriff auf den Server
- Mit anderen Worten: Die Reihenfolge der Zusammenführung ist wichtig, seien Sie also vorsichtig!
<Location "/">
Require all granted
</Location>
# Whoops! Dieser <Directory>-Abschnitt hat keine Wirkung
<Directory "/">
<RequireAll>
Require all granted
Require not host badguy.example.com
</RequireAll>
</Directory>