8    Webserver

In diesem Kapitel erlernen Sie die Konfiguration der Webserver »Apache« und »nginx«. Die Schwerpunkte dieses Kapitels liegen auf der Einrichtung virtueller Hosts mit und ohne SSL und auf der Logfile-Auswertung.

Obwohl es beileibe nicht an Herausforderern mangelt, wird ein Großteil aller Webangebote von einem Apache-Webserver ausgeliefert. Der Grund dafür dürfte Apaches enorme Flexibilität sein. Es gibt kaum ein Problem beim Ausliefern statischer und dynamischer Webseiten, das Apache nicht mit Bordmitteln oder einem Plugin lösen könnte.

In den letzten Jahren hat Apache einen ernst zu nehmenden Konkurenten bekommen: nginx. Was die beiden unterscheidet und wie Sie mit ihnen erfolgreich und sicher Webseiten betreiben können, zeigen wir Ihnen in diesem Kapitel.

Dabei bilden virtuelle Hosts und HTTPS den Kern dieses Kapitels, ergänzt um Apache-Spezifika wie das Sicherheits-Plug-in ModSecurity und Erläuterungen zum Tuning. Ebenso ausführlich gehen wir auf die heutzutage essenzielle SSL/TLS-Konfiguration ein. Den Schluss des Kapitels bildet das für jeden Webserver-Admin wichtige Thema Logfile-Auswertung.

8.1    Apache

Selbst wenn Sie nur ein einziges Webangebot auf Ihrem Server betreiben möchten, lohnt es sich, das Angebot als virtuellen Host zu konfigurieren. Auf diese Art ist die Konfiguration übersichtlicher, und Sie können schneller reagieren, wenn eines Tages doch einmal ein zweites Webangebot (oder gar mehr) auf dem Server einziehen soll. Daher ist diese Betriebsart auch zum Standard geworden.

8.1.1    Installation

Selbstverständlich gehört der Apache zum Standard und ist in den Paketquellen vorhanden. Die Installation erfolgt daher wie gewohnt:

Nach dem Installationsvorgang finden Sie die zentralen Konfigurationsdateien unter /etc/apache2/, außer bei CentOS, dort lautet nicht nur der Pfad /etc/httpd, sondern auch der Daemon und somit auch die Start-Skripte heißen so.

Die Hauptkonfigurationsdatei heißt httpd.conf. Jede Distribution verfolgt einen anderen Ansatz, wie die Konfigurationen verteilt und eingebunden werden. Debian und Ubuntu arbeiten nach dem gleichen Standard, CentOS verfolgt eine ganz eigene (eher an die Ursprünge erinnernde) Philosophie, und openSUSE Leap steht irgendwo dazwischen. Im weiteren Verlauf dieses Abschnitts arbeiten wir mit einem Ubuntu-System. Daher werden wir Ihnen an der einen oder anderen Stelle die Abweichungen, zum Beispiel bei den Pfaden oder den zu verwendenden Konfigurationsdateien, entsprechend ausweisen.

8.1.2    Virtuelle Hosts einrichten

Um mehrere Webangebote auf einem Server zu betreiben, bieten sich namensbasierte virtuelle Hosts an. Der Webserver »lauscht« dabei nur auf einer einzigen IP-Adresse und entscheidet anhand der HTTP-Header in der Anfrage des Clients, welcher virtuelle Host die Anfrage beantworten soll.

[+]  Veraltet: »NameVirtualHost«

In älteren Versionen des Apache musste für den Betrieb mit virtuellen Hosts zunächst die Zeile NameVirtualHost *:80 eingebunden werden. Dies ist nun nicht mehr notwendig, da virtuelle Hosts inzwischen den Standard darstellen.

Standardmäßig sind bei Debian, Ubuntu und openSUSE Leap bereits zwei virtuelle Hosts eingerichtet – einer für HTTP (000default.conf bzw. vhost.template) und einer für HTTPS (defaultssl.conf bzw. vhost-ssl.template). Im Folgenden richten wir nun einen eigenen virtuellen Host für die Webseite example.com ein:

<VirtualHost *:80>
ServerName example.com
ServerAlias sub.example.com www.example.com

ServerAdmin webmaster@example.com
DocumentRoot /var/www/example.com/

ErrorLog /var/log/apache2/error.log # CentOS: /var/log/httpd
CustomLog /var/log/apache2/example.com.log combined # CentOS: /var/log/httpd
<Directory /var/www/example.com/>
Options Indexes FollowSymLinks
### openSUSE Leap:
# <IfModule !mod_access_compat.c>
# Require all granted
# </IfModule>
# <IfModule mod_access_compat.c>
# Order allow,deny
# Allow from all
# </IfModule>
###
</Directory>
</VirtualHost>

Listing 8.1    Konfigurationsdatei für einen virtuellen Host

Beachten Sie bitte, dass Sie die Konfiguration aus Listing 8.1 an Ihre Distribution anpassen müssen.

Debian/Ubuntu

Bei Debian- und Ubuntu-Systemen legen Sie im Verzeichnis /etc/apache2/sites-available/ für jeden virtuellen Host eine Konfigurationsdatei an. Für unser Beispiel sollten Sie daher die Datei /etc/apache2/sites-available/example.com.conf mit dem Inhalt aus Listing 8.1 anlegen. Achten Sie darauf, dass Ihre Konfigurationsdatei mit der Endung .conf versehen ist, da Apache nur Dateien mit dieser Endung verarbeitet.

openSUSE Leap

Auf openSUSE-Leap-Systemen müssen Sie ebenfalls eine Konfigurationsdatei für die virtuellen Hosts erstellen – dort aber im Verzeichnis /etc/apache2/vhost.d. Für unser Beispiel müssen Sie also die Datei /etc/apache2/vhost.d/example.com.conf mit dem Inhalt aus Listing 8.1 anlegen. Auch hier ist die Endung .conf Pflicht. Passen Sie dort die Pfade in den Direktiven DocumentRoot und Directory auf /srv/www/ an, und entfernen Sie die Kommentarzeichen für die zusätzliche Modulabfrage, da standardmäßig keine Zugriffe erlaubt sind. Ohne die Abfrage erhalten Sie beim Aufruf die Fehlermeldung 403 – Zugriff verweigert.

CentOS

Bei CentOS sind keine Verzeichnisse für das Beherbergen von virtuellen Hosts explizit vorgesehen. Daher können Sie die Konfigurationsdatei entweder an dem zentralen Konfigurationsort unter /etc/httpd/conf.d ablegen oder einen eigenen Ordner anlegen (zum Beispiel wie bei openSUSE Leap vhost.d) und diesen mit der Direktive IncludeOptional vhost.d/*.conf in httpd.conf einbinden.

Legen Sie nun eine Konfigurationsdatei mit dem Inhalt aus Listing 8.1 unter dem Verzeichnis Ihrer Wahl unter dem Namen example.com.conf ab. Bei CentOS müssen Sie die Pfade zu den Log-Dateien entweder absolut (/var/log/httpd/<LOG>.log) oder relativ (logs/<LOG>.log) anpassen.

Allgemein

Die Direktiven der virtuellen Hostkonfiguration aus Listing 8.1 haben nachstehende Bedeutung:

8.1.3    Debian/Ubuntu: Virtuelle Hosts aktivieren

Wie Sie am Verzeichnisnamen vermutlich schon festgestellt haben, ist der virtuelle Host auf Debian und Ubuntu jetzt konfiguriert, aber noch nicht aktiv. Um ihn zu aktivieren, setzen Sie im Verzeichnis sites-enabled einen Symlink auf Ihre Konfigurationsdatei, die ja unter sites-available liegt, und lassen die Serverkonfiguration mit root-Rechten neu einlesen:

$ ln -s /etc/apache2/sites-available/example.com.conf \
/etc/apache2/sites-enabled/example.com.conf
$ systemctl reload apache2

Listing 8.2    Virtuellen Host aktivieren

Das Gleiche geht auch kürzer mit dem a2ensite-Kommando:

$ a2ensite /etc/apache2/sites-available/example.com.conf
Enabling site example.com.
To activate the new configuration, you need to run:
service apache2 reload

Listing 8.3    Virtuellen Host mit »a2ensite« aktivieren

Lassen Sie sich von der Ausgabe nicht verwirren: Sie müssen natürlich zum Aktivieren der Konfiguration nicht service verwenden. An dieser Stelle wurde die Ausgabe lediglich noch nicht an systemd angepasst.

Wollen Sie Ihren virtuellen Host wieder deaktivieren, benutzen Sie das Kommando a2dissite, oder löschen Sie den Symlink, gefolgt von einem Server-Reload.

Unter CentOS oder openSUSE Leap ist dieser Schritt nicht notwendig, da die Konfiguration des virtuellen Hosts direkt eingebunden wird.

Default

[+]  Die Verarbeitung der virtuellen Hosts geschieht alphabetisch. Daher lautet der Name der Konfigurationsdatei auf Debian- und Ubuntu-Systemen auch 000-default.conf. Somit wird sichergestellt, dass diese Datei stets zuerst geladen wird. Falls der Apache bei einer Anfrage keine passende Konfiguration findet, wird der Default verwendet. Dies ist entweder die zuerst gefundene Konfiguration oder die, die keine ServerName- oder ServerAlias-Direktive enthält, wodurch sie universal wird.

8.1.4    HTTPS konfigurieren

Um Webseiten verschlüsselt auszuliefern, benötigt Ihr Webserver zunächst ein Serverzertifikat. Zu Testzwecken oder für den Eigenbedarf können Sie sich ein solches Zertifikat schnell und einfach selbst erstellen. Sie müssen lediglich damit leben, dass Ihr Browser beim Ansurfen der HTTPS-geschützten Webseite eine Warnung ausgibt, weil das selbst erstellte Zertifikat nicht von einer vertrauenswürdigen Instanz signiert wurde. Da unbedarfte Nutzer von dieser Warnung leicht abgeschreckt werden, sollten Sie für Ihre Produktivsysteme auf signierte Zertifikate kommerzieller Anbieter zurückgreifen. Für die Beispiele in diesem Kapitel genügt natürlich ein selbst erstelltes Zertifikat.

[+]  Mehr zu Zertifikaten

Alle Details zu Zertifikaten haben wir für Sie in Kapitel 30, »Verschlüsselung und Zertifikate«, zusammengetragen. Schauen Sie sich dort insbesondere Abschnitt 30.4, »Einmal mit allem und kostenlos bitte: ›Let's Encrypt‹«, an. Dort zeigen wir Ihnen, wie Sie kostenlose SSL-Zertifikate erstellen können, die von allen Browsern akzeptiert werden.

Erstellen Sie als root unterhalb dieses Pfades ein neues Verzeichnis mit dem Namen ssl, und wechseln Sie hinein. Dieses Verzeichnis soll unser Serverzertifikat beheimaten:

$ mkdir /etc/apache2/ssl     ### CentOS: /etc/httpd/
$ cd /etc/apache2/ssl

Listing 8.4    Verzeichnis für das SSL-Zertifikat anlegen

Mit dem folgenden Kommando erstellen Sie das Serverzertifikat:

$ openssl req -new -x509 -keyout myserver.pem -out myserver.pem -days 365 -nodes

Listing 8.5    Ein selbst signiertes Zertifikat erstellen

OpenSSL stellt Ihnen eine Reihe von Fragen zu Ihrer Location und Kontaktadresse, die Sie nach Belieben beantworten können oder auch nicht – bei einem selbst signierten Testzertifikat sind diese Informationen nicht wesentlich.

[+]  Passen Sie aber auf, wenn die Frage nach dem Common Name erscheint! Hier müssen Sie unbedingt den exakten Namen eingeben, unter dem Ihr HTTPS-Webangebot später erreichbar sein soll. Wollen Sie Ihre Webseite also unter https://www.example.com aufrufen können, so müssen Sie auf die Frage nach dem Common Name mit www.example.com antworten.

Debian/Ubuntu

Zur Aktivierung von SSL müssen die Statements aus Listing 8.6 in der Datei ports.conf vorhanden sein:

<IfModule ssl_module>
Listen 443
</IfModule>

<IfModule mod_gnutls.c>
Listen 443
</IfModule>

Listing 8.6    Das »Listen 443«-Statement in »ports.conf«

Falls die Zeilen mit Kommentarzeichen (#) beginnen, entfernen Sie diese und verlassen die ports.conf. Führen Sie nun die beiden folgenden Kommandos aus, um das SSL-Modul zu aktivieren und Apache neu zu starten:

$ a2enmod ssl
$ systemctl restart apache2

Listing 8.7    Debian/Ubuntu: SSL-Modul aktivieren

openSUSE Leap

Ähnlich wie unter Debian und Ubuntu muss auch unter openSUSE Leap die Listen-Direktive gesetzt werden. Hier verbirgt sie sich aber in der Datei /etc/apache2/listen.conf, wie Listing 8.8 zeigt:

<IfDefine SSL>
<IfDefine !NOSSL>
<IfModule mod_ssl.c>

Listen 443

</IfModule>
</IfDefine>
</IfDefine>

Listing 8.8    Das »Listen 443«-Statement in »listen.conf«

Auch hier müssen Sie sicherstellen, dass die Zeilen nicht auskommentiert sind. Ebenso müssen Sie, wie es in Listing 8.9 dargestellt ist, mit den folgenden Kommandos das SSL-Modul aktivieren und den Apache neu starten:

$ a2enmod ssl
$ systemctl restart apache2

Listing 8.9    openSUSE: SSL-Modul aktivieren

CentOS

Per Default verfügt der Apache unter CentOS nicht über SSL-Unterstützung. Um diese zu erhalten, müssen Sie das Paket mod_ssl installieren:

[root@centos ~]# yum install mod_ssl

Listing 8.10    Installation des SSL-Moduls auf CentOS

Bei der Installation wird die notwendige Konfiguration direkt mitgeliefert. Sie finden diese in der Datei /etc/httpd/conf.d/ssl.conf. Dort ist direkt auch ein virtueller Host eingerichtet, der als Default-Webseite dient.

HTTPS-Konfiguration eines virtuellen Hosts

Apache ist jetzt grundsätzlich in der Lage, HTTPS-Anfragen zu bedienen. Sie benötigen also nur noch einen virtuellen Host, der sie auch beantwortet. Legen Sie im entsprechenden Verzeichnis für die Konfigurationsdateien die Datei ssl_example.com.conf mit dem Inhalt aus Listing 8.11 an:

<VirtualHost *:443>
ServerName www.example.com
ServerAdmin webmaster@example.com
DocumentRoot /var/www/example.com/

ErrorLog /var/log/apache2/error.log
CustomLog /var/log/apache2/example.com.log combined

SSLEngine On
SSLCertificateFile /etc/apache2/ssl/myserver.pem

<Directory /var/www/example.com/>
Options Indexes FollowSymLinks
### openSUSE Leap:
# <IfModule !mod_access_compat.c>
# Require all granted
# </IfModule>
# <IfModule mod_access_compat.c>
# Order allow,deny
# Allow from all
# </IfModule>
###
</Directory>
</VirtualHost>

Listing 8.11    Konfigurationsdatei für einen virtuellen SSL-Host

Beachten Sie dabei, dass auch bei dieser Konfiguration die Pfade an Ihre Distribution angepasst werden müssen. Auf openSUSE-Leap-Systemen müssen Sie zusätzlich in der Datei /etc/sysconfig/apache2 die nachstehende Direktive um den Wert SSL erweitern:

APACHE_SERVER_FLAGS="SSL"

Listing 8.12    openSUSE Leap: Anpassung für SSL in »/etc/sysconfig/apache2«

Nach dem obligatorischen systemctl restart apache2 (bzw. httpd) können Sie Ihre HTTPS-Seite jetzt im Browser aufrufen. Da Ihr Server dem Browser ein selbst signiertes Zertifikat präsentiert, werden Sie zunächst mit einer Warnmeldung wie in Abbildung 8.1 konfrontiert.

Der Browser erhält ein selbst signiertes Zertifikat.

Abbildung 8.1    Der Browser erhält ein selbst signiertes Zertifikat.

Der Browser verlangt nun (einmalig) von Ihnen, dass Sie das Zertifikat vom Server laden, anschauen und dann ausdrücklich akzeptieren (siehe Abbildung 8.2).

Das selbst signierte Zertifikat

Abbildung 8.2    Das selbst signierte Zertifikat

Ihr Browser merkt sich, dass Sie dem Zertifikat vertrauen, und wird Sie bei einem erneuten Besuch der Webseite nicht mehr fragen. Damit haben Sie die Konfiguration Ihres virtuellen SSL-Hosts abgeschlossen.

[ ! ]  Mehrere virtuelle SSL-Hosts mit einer IP-Adresse

Im Gegensatz zu »normalen« virtuellen Hosts – also solchen ohne SSL – können Sie nicht beliebig viele virtuelle SSL-Hosts auf einer IP-Adresse konfigurieren. Sie benötigen für jeden SSL-Host eine eigene IP-Adresse. Um dieser Verschwendung von IP-Adressen entgegenzutreten, wurde eine Erweiterung geschaffen: Server Name Indication.

8.1.5    Benutzer-Authentifizierung mit Kerberos

Wenn Sie den Zugriff auf bestimmte virtuelle Hosts, Verzeichnisse oder den gesamten Inhalt des Webservers nur für bestimmte Benutzer freigeben möchten, muss Ihr Server diese berechtigten Benutzer identifizieren können.

Dafür gibt es mehrere Möglichkeiten, aber wenn Sie bereits einen Kerberos-gesicherten Verzeichnisdienst betreiben, ist es sinnvoll, ihn auch in diesem Fall zu benutzen.

[»]  Im folgenden Beispiel wird davon ausgegangen, dass im Netz ein Kerberos-Server vorhanden und für Anfragen des Webservers vorbereitet ist (Account, Keytab ...). Sollten Sie diese Schritte noch vor sich haben, finden Sie Hilfe in Kapitel 14, »Kerberos«.

Für den ApacheWebserver stellt Ihre Distribution ein Paket namens libapache2-mod-auth-kerb (oder so ähnlich) bereit, das Sie installieren müssen. Starten Sie den Webserver nach der Installation neu, damit die Funktionalität zur Verfügung steht.

Ein Verzeichnis für angemeldete Benutzer freigeben

Erstellen Sie in dem Verzeichnis, dessen Inhalt Sie nur angemeldeten Benutzern zugänglich machen möchten, eine .htaccess-Datei mit dem Inhalt aus Listing 8.13:

AuthName "Kerberos-Anmeldung"
AuthType Kerberos
Krb5Keytab /etc/apache2/wwwserver.keytab
KrbAuthRealms EXAMPLE.COM
KrbServiceName HTTP
KrbMethodNegotiate on
KrbVerifyKDC on
require valid-user

Listing 8.13    Angemeldeten Benutzern den Zugriff erlauben

Den Pfad und Namen der Keytab-Datei müssen Sie dabei wahrscheinlich noch anpassen. Nach einem Reload der Apache-Konfiguration erhalten alle diejenigen Benutzer Zugriff auf das Verzeichnis, die Mitglied des Realms »example.com« sind.

Ein Verzeichnis für eine bestimmte Benutzergruppe freigeben

Wenn Sie die »Zutrittsberechtigung« zu Ihrem Verzeichnis noch feiner regeln möchten, indem Sie etwa nur Mitgliedern einer bestimmten Benutzergruppe den Zugriff erlauben, so aktivieren Sie zunächst das Apache-Modul authnz_ldap:

$ a2enmod authnz_ldap

Listing 8.14    Das Apache-Modul »authnz_ldap« aktivieren

Starten Sie danach den Apache-Server einmal neu. Nun ändern Sie die .htaccess-Datei wie folgt ab:

AuthName "Kerberos-Anmeldung"
AuthType Kerberos

Krb5Keytab /etc/apache2/wwwserver.keytab
KrbAuthRealms EXAMPLE.COM
KrbServiceName HTTP
KrbMethodNegotiate on
KrbVerifyKDC on

#require valid-user

AuthLDAPURL "ldap://kerberos.example.com/dc=example,dc=com?sAMAccountName"
AuthLDAPBindDN wwwserver@example.com
AuthLDAPBindPassword wwwserverpasswort
Require ldap-group CN=wwwusers,OU=groups,DC=example,DC=com

Listing 8.15    Mitgliedern einer bestimmten Gruppe den Zugriff erlauben

Hier werden Sie die Werte für den Kerberos-Server, den Benutzernamen und das Passwort des Apache-Servers sowie den Namen der Benutzergruppe anpassen müssen. Im Beispiel ist der Zugriff für alle Benutzer freigegeben, die der Gruppe wwwusers angehören.

8.1.6    Apache-Server mit ModSecurity schützen

ModSecurity nennt sich selbst »Web Application Firewall (WAF)«. Es ist ein Apache-Modul, das den HTTP-Datenverkehr mithilfe eines Regelwerks auf Angriffsmuster prüft. Der Unterschied zu klassischen Firewalls besteht in der OSI-Schicht, auf der der Filter arbeitet. Ein Paketfilter arbeitet auf der Transportebene, also der OSI-Schicht 3 oder 4. Er muss seine Entscheidungen anhand von Quelle, Ziel und Status des Pakets treffen. Die Web Application Firewall werkelt dagegen auf der gleichen Ebene wie der Webserver selbst (auf der Applikationsebene 7) und kann so den Inhalt der Pakete analysieren.

Die Motivation hinter dieser Vorgehensweise ist eine Verschiebung der Angriffsvektoren. Früher zielten Angreifer darauf ab, Sicherheitslücken in der Serversoftware auszunutzen. Durch den jahrelangen Reifeprozess sind klaffende Sicherheitslücken jedoch selten geworden, und auftretende Sicherheitsprobleme werden schnell durch Updates behoben. Anders sieht es bei den Webangeboten selbst aus. Viele werden nicht mit einem Fokus auf der Sicherheit entwickelt und enthalten Schnittstellen zu anderen Diensten wie SQL-Servern oder Verzeichnisdiensten. Angreifer versuchen heute nicht mehr, den Server selbst anzugreifen, sondern wollen über geschickt formulierte HTTP-Anfragen Daten stehlen oder eigenen Code ausführen lassen.

Genau diese HTTP-Anfragen versucht ModSecurity mithilfe seines Regelwerks zu erkennen und herauszufiltern. ModSecurity wird derzeit von der Firma Trustwave SpiderLabs weiterentwickelt, die neben der Open-Source-Version auch einen kommerziellen Zweig anbietet. Die Software kann direkt auf dem Server eingebunden werden oder als Proxy mehreren Servern vorgeschaltet werden.

Installation

Die meisten Distributionen stellen ModSecurity als Paket zur Verfügung. Debian war lange Zeit eine Ausnahme, aber das hat sich inzwischen geändert. Debian 6.0 »Squeeze« war die erste stabile Debian-Version, in der ModSecurity enthalten ist.

Die Installation erfolgt über die Paketquellen:

Bevor Sie ModSecurity einsetzten können, müssen Sie noch etwas Vorarbeit leisten.

Debian/Ubuntu

Neben dem eigentlichen Modul lebt ModSecurity vom Regelwerk. Dieses laden wir zunächst in der aktuellen Version vom GitHub-Repository des Herstellers herunter:

$ rm -rf /usr/share/modsecurity-crs
$ git clone https://github.com/SpiderLabs/owasp-modsecurity-crs.git \
/usr/share/modsecurity-crs

Listing 8.16    Aktuelles Regelwerk herunterladen mit »git«

Anschließend müssen die Regeln noch aktiviert werden. Dafür müssen die Konfigurationsdateien an ihren Bestimmungsort gebracht und symbolische Links der aktiven Regeln erzeugt werden.

In Listing 8.17 sehen Sie die notwendigen Kommandos:

$ cd /usr/share/modsecurity-crs
$ cp modsecurity_crs_10_setup.conf.example modsecurity_crs_10_setup.conf
$ ln -s ../modsecurity_crs_10_setup.conf \
activated_rules/modsecurity_crs_10_setup.conf
$ for f in $(ls base_rules); do ln -s ../base_rules/$f \
activated_rules/$f; done

Listing 8.17    Konfiguration und Regeln aktivieren

Im Paket ist bereits eine umfangreiche Beispielkonfiguration vorhanden. Damit diese auch verwendet wird, muss sie nun einen neuen Namen erhalten:

$ cd /etc/modsecurity
$ cp modsecurity.conf-recommended modsecurity.conf

Listing 8.18    Kopieren der Beispielkonfiguration »modsecurity.conf«

Per Default werden Regelverstöße lediglich dokumentiert. Damit ModSecurity auch wirklich arbeitet, muss nun die Direktive SecRuleEngine auf On gesetzt werden:

# SecRuleEngine DetectionOnly
SecRuleEngine On

Listing 8.19    Anpassung in »/etc/modsecurity/modsecurity.conf«

Zu guter Letzt müssen Sie noch in der Modulkonfiguration die neu heruntergeladenen Regeln hinzufügen. Öffnen Sie dafür die Datei /etc/apache2/mods-available/security2.conf, und fügen Sie die in Fettschrift dargestellte Zeile aus Listing 8.20 hinzu:

<IfModule security2_module>
# Default Debian dir for modsecurity's persistent data
SecDataDir /var/cache/modsecurity

# Include all the *.conf files in /etc/modsecurity.
# Keeping your local configuration in that directory
# will allow for an easy upgrade of THIS file and
# make your life easier
IncludeOptional /etc/modsecurity/*.conf
IncludeOptional /usr/share/modsecurity-crs/activated_rules/*.conf
</IfModule>

Listing 8.20    Anpassung in »/etc/apache2/mods-available/security2.conf«

Mit den in Listing 8.21 gezeigten Kommandos aktivieren Sie das Modul und starten den Webserver neu, damit die WAF ihren Dienst auch antreten kann:

$ a2enmod security2
$ systemctl restart apache2

Listing 8.21    Aktivieren des Moduls und Neustart des Apache

Anschließend werden alle Anfragen durch ModSecurity geschützt.

CentOS

Auch auf CentOS-Systemen sollte zunächst das aktuelle Regelwerk geladen werden. Führen Sie dafür die Befehle aus Listing 8.22 aus:

$ cd /etc/httpd/modsecurity.d/
$ rm -rf activated_rules
$ git clone https://github.com/SpiderLabs/owasp-modsecurity-crs.git .

Listing 8.22    Aktuelles Regelwerk herunterladen mit »git« für CentOS

Anschließend müssen sowohl die Konfiguration als auch die Regeln aktiviert werden (siehe Listing 8.23).

$ cd /etc/httpd/modsecurity.d/
$ cp modsecurity_crs_10_setup.conf.example modsecurity_crs_10_setup.conf
$ ln -s ../modsecurity_crs_10_setup.conf \
activated_rules/modsecurity_crs_10_setup.conf
$ for f in $(ls base_rules); do ln -s ../base_rules/$f \
./activated_rules/$f; done

Listing 8.23    Konfiguration und Regeln aktivieren unter CentOS

Die übrige Konfiguration ist bereits Bestandteil des Pakets, sodass keine weiteren Arbeiten notwendig sind. Nach dem obligatorischen Neustart des Webservers ist die WAF aktiv.

openSUSE Leap

Nach der Installation müssen die Module so aktiviert werden, wie es Listing 8.24 zeigt:

$ a2enmod security2
$ a2enmod unique_id

Listing 8.24    Aktivieren der Module für »ModSecurity«

Bei openSUSE Leap wird direkt ein Regelwerk mit installiert. Dieses müssen wir nur noch aktivieren:

$ cd /etc/apache2/mod_security2.d
$ for f in /usr/share/apache2-mod_security2/rules/base_rules/mod*; do \
ln -s $f . ; done

Listing 8.25    Aktivieren des Regelwerks auf openSUSE Leap

Die übrige Konfiguration ist bereits bei der Paketinstallation vorgenommen worden, sodass keine weiteren Arbeiten notwendig sind. Nach dem obligatorischen Neustart des Apache mit systemctl restart apache2 ist die WAF aktiv.

Konfiguration

Das Standardregelwerk, das ModSecurity mitbringt, ist schon recht restriktiv und blockiert oft mehr, als erwünscht ist. Das kann dazu führen, dass plötzlich Teile Ihrer Webanwendung nicht mehr aufrufbar sind, weil ModSecurity die entsprechenden Anfragen für gefährlich hält.

Um die Wirksamkeit der Regeln ohne Gefahr für Ihren Blutdruck auszuprobieren, können Sie ModSecurity in einen »Detection«-Modus schalten. Dabei durchlaufen alle Anfragen das Regelwerk, eventuelle Treffer werden aber lediglich ins Logfile geschrieben.

Diesen Modus aktivieren Sie, indem Sie in der Datei modsecurity_crs_10_config.conf die Zeile SecRuleEngine On auskommentieren und wie im folgenden Beispiel ersetzen:

#SecRuleEngine On
SecRuleEngine DetectionOnly

Listing 8.26    »ModSecurity« in den »DetectionOnly«-Modus schalten

Wenn ModSecurity einen Zugriff ablehnt, finden Sie im Audit-Logfile Zeilen wie diese:

Message: Access denied with code 403 (phase 2).
Pattern match "(?:(?<!\\w)(?:\\.(?:ht(?:access|passwd|group)|\
www_?acl)|global\\.asa|httpd\\.conf|boot\\.ini)\\b|\
\\/etc\\/)" at ARGS:secret_file.
[file "/etc/httpd/modsecurity.d/activated_rules/modsecurity_crs_40_generic_\
attacks.conf"]
[line "218"]
[id "950005"]
[rev "3"]
[msg "Remote File Access Attempt"]
[data "Matched Data: /etc/ found within ARGS:secret_file: /etc/passwd"]
[severity "CRITICAL"]
[ver "OWASP_CRS/2.2.9"]
[maturity "9"]
[accuracy "9"]
[tag "OWASP_CRS/WEB_ATTACK/FILE_INJECTION"]
[tag "WASCTC/WASC-33"]
[tag "OWASP_TOP_10/A4"]

Listing 8.27    »ModSecurity« lehnt einen Zugriff ab.

Hier bekommen Sie genaue Informationen darüber, welche Regel wirksam wurde, in welcher Konfigurationsdatei und sogar in welcher Zeile. Jede Regel hat eine eindeutige Kennnummer, im Beispiel aus Listing 8.27 ist es [id "950005"].

Wenn Sie der Meinung sind, dass ModSecurity übereifrig war und den Zugriff zu Unrecht unterbunden hat, können Sie die Regel deaktivieren.

[ ! ]  Erstellen Sie eigene Konfigurationsdateien!

Es ist nicht sinnvoll, die Regeln des Kernregelwerks direkt zu editieren. Das funktioniert zwar zunächst, rächt sich aber beim nächsten Update des Regelwerks. Benutzen Sie eine oder mehrere eigene Konfigurationsdateien, um Regeln hinzuzufügen oder zu deaktivieren.

Wechseln Sie in das Verzeichnis, in dem Ihr ModSecurity-Regelwerk residiert, und legen Sie dort eine neue Konfigurationsdatei an. Geben Sie ihr dann beispielsweise den Namen modsecurity_crs_99_meineregeln.conf, und füllen Sie sie mit dem folgenden Inhalt:

<LocationMatch /mysite/modsectest.php>
SecRuleRemoveById 950005
</LocationMatch>

Listing 8.28    Eine Regel deaktivieren

Für den Webpfad, den Sie in der LocationMatch-Zeile angegeben haben, bleibt die Regel mit der ID 950005 inaktiv.

8.1.7    Tuning und Monitoring

Leistungsoptimierung fängt bei der Hardware an. Dabei ist die reine Rechenleistung des Servers eher selten ein limitierender Faktor, wenn Sie nicht gerade hochkomplexe dynamische Webangebote betreiben. Viel eher kommt es auf den Speicher an.

Kaum eine Tuning-Maßnahme ist so wirksam wie das Aufstocken des verfügbaren RAMs. Die Leistung jedes Webservers bricht schlagartig und dramatisch ein, wenn das System in den Swap-Betrieb schlittert.

Aber auch dann, wenn Sie Ihrem Server ausreichend Speicher spendiert haben, können Sie durch einige einfache Handgriffe noch etwas mehr Leistung herauskitzeln. Außerdem bringt Apache bereits ein Bordmittel mit, das Ihnen einen Blick unter die Motorhaube erlaubt.

Multi-Processing-Module

Zur Verarbeitung der eingehenden HTTP-Anfragen greift Apache auf eines von mehreren, teils plattformabhängigen Multi-Processing-Modulen (MPMs) zurück. Drei davon sind unter Linux besonders relevant:

Die »MaxRequestWorkers«-Direktive

In den Konfigurationsdateien finden Sie unter anderem die MaxRequestWorkers-Direktive. Sie gibt an, wie viele Clientverbindungen maximal bedient werden können (beim Prefork-MPM) oder wie viele Threads für Clientverbindungen zur Verfügung stehen (beim Worker- und Event-MPM). Per Default sind dies 256, manche Distributionen arbeiten aber mit anderen Voreinstellungen. Unter Debian ist der MaxRequestWorkers-Wert auf 150 eingestellt.

Sollte der voreingestellte Wert zu niedrig sein, können nicht alle Clients bedient werden. Sie erkennen das Problem an Meldungen im Error-Log, die etwa so aussehen wie in Listing 8.29:

[Fri Jun 05 13:15:24.760818 2016] [mpm_prefork:error] [pid 1648] AH00161: server \
reached MaxRequestWorkers setting, consider raising the MaxRequestWorkers setting

Listing 8.29    Fehlermeldung wegen zu niedriger »MaxRequestWorkers«-Einstellung

Erhöhen Sie in diesem Fall den Wert, aber behalten Sie, etwa mit top, Ihren RAM-Verbrauch im Auge. Ein höherer MaxRequestWorkers-Wert geht unweigerlich mit erhöhten Speicheranforderungen einher.

DNS-Anfragen

Apache protokolliert alle Zugriffe in einem Logfile. Damit Sie leicht erkennen können, welche Clients auf Ihren Webserver zugegriffen haben, versucht Apache immer, durch DNS-Anfragen den Namen des Clients zu ermitteln.

Diese Anfragen bestehen in der Regel zwar nur aus recht kleinen UDP-Paketen, aber wenn Sie einen stark frequentierten Webserver betreiben, können die Reverse Lookups trotzdem bremsend wirken. Fügen Sie der Konfigurationsdatei Ihrer (virtuellen) Hosts die in Listing 8.30 gezeigte Direktive hinzu:

[…]
HostnameLookups Off
[…]

Listing 8.30    DNS-Anfragen deaktivieren

Auf die Information, welche Clients Ihre Webseite besucht haben, müssen Sie dennoch nicht verzichten. Log-Auswerter wie Webalizer (siehe Abschnitt 8.3, »Logfiles auswerten«) können die Lookups zu einer günstigeren Zeit, etwa nachts, automatisch nachholen.

Der »htaccess«-Mechanismus

Der htaccess-Mechanismus erlaubt es Ihnen, bestimmte Konfigurationsoptionen pro Verzeichnis ein- oder auszuschalten, und trägt damit wesentlich zur Flexibilität Ihres Servers bei. Falls Sie diese Flexibilität nicht benötigen, sollten Sie den Mechanismus unbedingt abschalten. Sie ersparen Ihrem Apache damit unzählige unnötige Lesevorgänge und Fallentscheidungen. Fügen Sie die Zeilen aus Listing 8.31 der Konfigurationsdatei Ihres (virtuellen) Hosts hinzu, um den htaccess-Mechanismus zu deaktivieren:

[…]
<Directory />
AllowOverride none
</Directory>
[…]

Listing 8.31    »htaccess« deaktivieren

Anzeigen des Serverstatus

Apaches Statusmodul mod_status erlaubt es Ihnen, den Apache-Prozessen zu jedem Zeitpunkt auf die Finger zu schauen. Sie aktivieren das Modul auf Debian-, Ubuntu- und openSUSE-Systemen mit dem bereits bekannten Programm a2enmod. Wie gewohnt wird dem Programm nur das entsprechende Modul als Parameter übergeben: a2enmod status.

Nach einem Neustart des Apache können Sie die Statuswebseite unter der Adresse www.example.com/server-status betrachten – theoretisch. In der Praxis darf per Default nur localhost auf die Statusseite zugreifen. Andere Rechner müssen Sie explizit freigeben. Das können Sie in der Konfigurationsdatei /etc/apache2/mods_available/status.conf (Debian/Ubuntu) oder /etc/apache2/mod_status.conf (openSUSE Leap) tun. Die Datei enthält den Konfigurationsblock aus Listing 8.32:

[…]
# Allow server status reports generated by mod_status,
# with the URL of http://servername/server-status
# Uncomment and change the "192.0.2.0/24" to allow access from other hosts.
<Location /server-status>
SetHandler server-status
Require local
#Require ip 192.0.2.0/24
</Location>
[…]

Listing 8.32    Konfigurationsdatei des Statusmoduls

Entfernen Sie das Kommentarzeichen vor der in Fettschrift dargestellten Zeile, und passen Sie das Netzwerk an Ihre Umgebung an, oder tragen Sie nur die IP-Adresse Ihres Clients ein. Neben IP-Adressen sind auch Hostnamen und die Angabe von Subnetzen erlaubt. Alternativ können Sie auch eine oder mehrere zusätzliche Require-Zeilen einfügen:

Require ip 10.20.30.40
Require host client01.lan.example.com
Require ip 172.31.0.0/16

Listing 8.33    »Require«-Statements im Statusmodul

Bei CentOS müssen Sie die Konfigurationsdatei zunächst selbst anlegen. Speichern Sie den Inhalt aus Listing 8.34 in die Datei /etc/httpd/conf.d/status.conf:

<IfModule mod_status.c>
<Location /server-status>
SetHandler server-status
Require local
Require ip 192.168.1.0/24 ### <-- Anpassung an Ihr Netzwerk!
</Location>

ExtendedStatus On
<IfModule mod_proxy.c>
# Show Proxy LoadBalancer status in mod_status
ProxyStatus On
</IfModule>
</IfModule>

Listing 8.34    Konfiguration des Statusmoduls für CentOS

Nach einem Apache-Reload können Sie die Statusseite aufrufen. Sie sieht etwa so aus, wie Listing 8.35 zeigt:

Server Version: Apache/2.4.18 (Ubuntu) OpenSSL/1.0.2g-fips
Server MPM: prefork
Server Built: 2016-07-14T12:32:26

Current Time: Thursday, 08-Sep-2016 10:27:07 CEST
Restart Time: Thursday, 08-Sep-2016 09:24:03 CEST
Parent Server Config. Generation: 2
Parent Server MPM Generation: 1
Server uptime: 11 hours 31 minutes 38 seconds
Total accesses: 2835168 - Total Traffic: 414.3 GB
CPU Usage: u187.68 s76.8281 cu0 cs0 - .637% CPU load
68.3 requests/sec - 10.2 MB/second - 153.2 kB/request
305 requests currently being processed, 143 idle workers

[…]
W_WKWWWWW_WW_WCWKWWWCWWKKW_WWWWWWW_WW_WWWWK_WWWKW_WWK_WWWKW_WWKW
______________KC_____KWK_W_W__W__KKKKK_KCK___WW_CKWWC_KK_KWC____
KKW_WKW_W_CK_K__C__WC______W_W_K_____KW___W__K__KKWW___C_WK_____
WK_WKWC_KKKKWWW__W__W_W_KK_KW_WWWC__KW_W__WK_WWWWKWW__KWW___WWW_
WWWK__WKCWWKWKKWWWCWWKWK__W__CKWWCW__KW_W_K__WKWWWKKC_W_KWWKWWWK
................................................................
[…]

Listing 8.35    Apache-Serverstatus (Auszug)

Der zunächst etwas unsortiert anmutende Zeichenblock zeigt an, womit jeder Apache-Prozess im Moment beschäftigt ist. Tabelle 8.1 listet die Bedeutung der Zeichen auf.

Zeichen Bedeutung
_ wartet auf Verbindung
S Prozess startet
R Anfrage des Clients wird empfangen.
W Antwort wird gesendet.
K Keep-Alive – die Verbindungen bleiben für weitere Anfragen offen.
D Nameserver-Lookup
C Verbindung wird geschlossen.
L Eintrag wird ins Logfile geschrieben.
G Ein Prozess wird kontrolliert beendet.
I Idle Cleanup – ein Prozess erhielt keine Verbindungen und wird aufgeräumt.
. Verbindungs-Slot ohne laufenden Prozess

Tabelle 8.1    Statuskürzel in der Serverstatusanzeige