# Apache

# Zugriff auf .git und .svn Unterverzeichnisse verbieten

Mit folgendem Snippet läßt sich der Zugriff auf .git und .svn Verzeichnisse verhindern. Das funktioniert entweder per Vhost oder auch global, z.B. als Datei in /etc/apache2/conf.d/.

```code
# Apache 2.4
<DirectoryMatch ".*/\.(git|svn)/.*">
    Require all denied
</DirectoryMatch>

# Apache 2.2
<DirectoryMatch ".*/\.(git|svn)/.*">
    Order deny,allow
    Deny from all
</Directorymatch>
```

Alternativen per Einzeiler (braucht mod\_alias):

```code
AliasMatch \.(svn|git) /404-error.html
# oder:
RedirectMatch 404 /\.(git|svn)
```

# Apache Grundinstallation und Absicherung mit SSL und mod_php

<p class="callout info">Diese Anleitung wurde für Debian Jessie geschrieben.</p>

In diesem Artikel geht es darum Apache mit PHP (mod\_php) zu installieren und grundlegend sicher zu konfigurieren.

Folgendes soll erreicht werden (Stand 11.12.2015):

- Keine Ausgabe von Versionsinformationen bei Apache und PHP
- Verwendung sicherer Ciphers und Hashingalgorithmen bei SSL
- Versteckte Dateien sollen nicht abrufbar sein (z.B. .git- oder .svn-Verzeichnisse)
- DocumentRoots sicher machen

Nach Änderungen an den Konfigurationsdateien die Apache-Syntax testen und neu laden:

```code
# apache2ctl configtest
Syntax OK
# systemctl restart apache2.service
```

Installation von apache2.4 mit PHP und SSL

```code
aptitude install apache2 libapache2-mod-php5 php5
```

#### Apache 2.4 absichern

Ausgabe von Versionsinformationen bei Apache deaktivieren

/etc/apache2/conf-available/security.conf

```code
ServerTokens Prod
ServerSignature Off
```

ggf. zusätzliche Header mitsenden (mod\_headers aktivieren: „a2enmod headers“)

/etc/apache2/conf-available/security.conf

```code
# prevent MSIE from interpreting files as something else than declared by HTTP headers
Header set X-Content-Type-Options: "nosniff"
# disable loading pages from this site as frames
Header set X-Frame-Options: "sameorigin"
```

Zugriff auf Verzeichnisse von Versionskontrollsystemen wie Git und SVN unterbinden. Aktivieren mit „a2enconf cvs-deny“

/etc/apache2/conf-available/cvs-deny.conf

```code
RedirectMatch 403 (?i)\.git
RedirectMatch 403 (?i)\.svn
```

ggf. Zugriff auf alle versteckten Verzeichnisse unterbinden (kann auch Probleme machen). Aktivieren mit „a2enconf hidden-deny“

/etc/apache2/conf-available/hidden-deny.conf

```code
RedirectMatch 404 (?i)/\..+
```

SSL soll möglichst sicher konfiguriert (soweit die alten SSL-Libs bei Debian es erlauben) werden. Wie man SSL mit modernen Ciphers sicher konfiguriert steht in [diesem Artikel](https://wiki.magenbrot.net/linux/webserver/apache/sichere_ssl_konfiguration "linux:webserver:apache:sichere_ssl_konfiguration").

Ggf. mod\_security installieren, ein Filter und IDS gegen verschiedene Angriffe auf den Webserver (XSS, SQL injection):

```code
# aptitude install libapache2-mod-security2
# cp /etc/modsecurity/modsecurity.conf-recommended /etc/modsecurity/modsecurity.conf
```

ein sicherer Apache default-Vhost (auch als Vorlage für weitere Vhosts verwendbar)

/etc/apache2/sites-available/000-default.conf

```code
<VirtualHost *:80>
    ServerName www.FQDN
    ServerAlias FQDN
    ServerAdmin webmaster@FQDN
    DocumentRoot /var/www/FQDN
    
    LogLevel info
    ErrorLog ${APACHE_LOG_DIR}/FQDN-error.log
    CustomLog ${APACHE_LOG_DIR}/FQDN-access.log combined
</VirtualHost>

<VirtualHost _default_:443>
    ServerName www.FQDN
    ServerAlias FQDN
    ServerAdmin webmaster@FQDN
    DocumentRoot /var/www/FQDN
    
    LogLevel info ssl:warn
    ErrorLog ${APACHE_LOG_DIR}/FQDN-error.log
    CustomLog ${APACHE_LOG_DIR}/FQDN-access.log combined
    
    SSLEngine on
    SSLCertificateFile	/etc/apache2/ssl/FQDN.pem    # contains the domain certificate and intermediate certificates
    SSLCertificateKeyFile /etc/apache2/ssl/FQDN.key
</VirtualHost>

# vim: syntax=apache ts=4 sw=4 sts=4 sr noet
```

#### PHP absichern

Ausgabe von Versionsinformationen bei PHP deaktivieren

/etc/php5/apache2/php.ini

```code
expose_php=Off
```

bei Bedarf können weitere Sicherungsmaßnahmen getroffen werden

/etc/php5/apache2/php.ini

```code
# ggf. Dateiuploads deaktivieren
file_uploads=Off

# Ausführung von entferntem Code unterbinden
allow_url_fopen=Off
allow_url_include=Off

# Zugriff auf das Dateisystem einschränken
open_basedir="/var/www/html/"
```

# schlechte Perfomance

folgender Eintrag im error\_log

```code
child pid 18609 exit signal File size limit exceeded (25)
```

deutet darauf hin, dass der Apache nicht in seine Logfiles schreiben darf, da die max. Größe überschritten wurde. Tritt eigentlich nur bei älteren Systemen auf, die eine Begrenzung auf 2GB haben. Diese Files einfach rotieren/löschen und ein SIGHUP auf den Apache durchführen.

# Apache mit PHP-FPM

<p class="callout info">Diese Anleitung wurde für Debian Stretch geschrieben</p>

Die Installation von Apache und PHP mit PHP-FPM gestaltet sich inzwischen recht einfach. Zuerst werden alle nötigen Pakete installiert (der performante event-Worker von Apache kommt automatisch mit):

```code
aptitude update
aptitude install apache2 php7.0 php7.0-cgi php7.0-cli php7.0-fpm php7.0-mbstring php7.0-mcrypt php7.0-opcache php7.0-intl php7.0-gd php-apcu php-apcu-bc ssl-cert
```

proxy\_fcgi und die PHP-FPM Konfiguration aktivieren:

```code
a2enmod proxy_fcgi
a2enconf php7.0-fpm
systemctl restart apache2.service
```

PHP Installation testen:

```code
echo "<?php phpinfo();" > /var/www/html/index.php
```

Unter http:*&lt;servername&gt;/index.php sollte nun die PHP Infoseite zu sehen sein.*

# Apache mit php5-fpm installieren

<p class="callout info">Diese Anleitung wurde für Debian Wheezy geschrieben.</p>

Voraussetzung: Frisch installierter Debian-Standardserver.

```code
apt-get update
apt-get -y install apache2 apache2-mpm-worker apache2-utils php5 php5-fpm php5-common php5-gd php5-mysql php5-imap php5-cli libapache2-mod-fastcgi php-pear php-auth php5-mcrypt mcrypt php5-curl php5-intl php5-ming php5-ps php5-pspell php5-recode php5-snmp php5-sqlite php5-xmlrpc php5-xsl
```

Jetzt wird Apache noch mit php5-fpm verheiratet. Dazu das folgende File nach /etc/apache2/conf.d/ legen:

/etc/apache2/conf.d/php5-fpm

```code
<FilesMatch ".+\.ph(p[345]?|t|tml)$">
    SetHandler application/x-httpd-php
</FilesMatch>
<FilesMatch ".+\.phps$">
    SetHandler application/x-httpd-php-source
    Order Deny,Allow
    Deny from all
</FilesMatch>
<FilesMatch "^\.ph(p[345]?|t|tml|ps)$">
    Order Deny,Allow
    Deny from all
</FilesMatch>
Action application/x-httpd-php /fcgi-bin/php5-fpm virtual
Alias /fcgi-bin/php5-fpm /fcgi-bin-php5-fpm
<Location /fcgi-bin/php5-fpm>
  Order Deny,Allow
  Deny from All
  Allow from env=REDIRECT_STATUS
</Location>
FastCgiExternalServer /fcgi-bin-php5-fpm -socket /var/run/php5-fpm.sock -pass-header Authorization -idle-timeout 3600 -flush
```

Benötigte Apache-Module aktivieren und neu starten:

```code
a2enmod actions fastcgi
service apache2 restart
```

Ein Testfile für PHP anlegen:

/var/www/test.php

```code
<?php phpinfo(); ?>
```

Abschließend noch den Apache neu starten (service apache2 restart) und das Testfile im Browser aufrufen (http://dein-server.de/test.php). Die PHP-Infoseite sollte nun angezeigt werden.

Die php.ini liegt bei dieser Konfiguration in /etc/php5/fpm/php.ini. Verwendete Module dort im conf.d-Unterverzeichnis. PHP-FPM selbst wird dort in php-fpm.conf konfiguriert. Standardmäßig gibts nur einen Pool, der mit dem User www-data läuft. Dieser Pool wird in /etc/php5/fpm/pool.d/www.conf konfiguriert. In dieser Datei kann auch das Performance-Tuning von FPM erfolgen.

# Authentifizierung via LDAP

Getestet unter CentOS-5 32bit mit Apache 2.2.3

- Installation der nötigen Module:

```code
yum -y install mod_authz_ldap
```

- Die Änderung kann in jeder Vhost-, Directory-, Location-Direktive oder z.B. gleich in der Datei /etc/httpd/conf.d/authz\_ldap.conf vorgenommen werden. Der folgende Eintrag schützt z.B. den ganzen Auftritt:

```code
<Location />
        AuthType Basic
        AuthName "LDAP-Authentifizierung"
        AuthBasicProvider ldap
        AuthzLDAPAuthoritative off
        AuthLDAPURL "ldap://mein.ldapserver.de/ou=People,dc=ldapserver,dc=de?uid?sub?(objectClass=*)"
        require valid-user
</Location>
```

#### SSL-verschlüsselte Kommunikation zum Webserver aktivieren

um den LDAP-Server verschlüsselt anzusprechen (wenn sich z.B. Web- und LDAP-Server in verschiedenen Hosting-Locations befinden, würde keiner machen, aber nur mal als Beispiel) sind 2 kleine Änderungen notwendig.

- Check des Serverzertifikates deaktivieren (oder das CA-Cert auf jedem Webserver einbinden). Dazu folgende Zeile am besten in die Datei /etc/httpd/conf.d/authz\_ldap.conf eintragen:

```code
LDAPVerifyServerCert off
```

- die AuthLDAPURL auf „ldaps:*…“ abändern*

# MultiViews

oder „Warum liefert Apache etwas aus, dass es gar nicht gibt?“

MultiViews gehören zu mod\_negotiation und ermöglichen dem Apache Dateinamen zu „erraten“.

Bekommt der Apache bei aktivierten MultiViews einen Request auf eine Datei, die es gar nicht gibt, z.B. /var/www/bla, aber es gibt eine Datei namens /var/www/bla.png, dann wird diese .png Datei ausgeliefert (die URL ändert sich trotzdem nicht). Apache sucht nach bla.\* und liefert den besten Treffer (mit allen dazugehörigen Media-Typen, content encodings und Headern) aus.

Leider hat das auch negative Folgen. Wenn es z.B. einen Rewrite auf /bla gibt, funktioniert dieser nicht! Also lieber alles sauber verlinken oder programmieren und auf MultiViews verzichten, als sich hinterher über dieses Verhalten zu ärgern.

MultiViews sind standardmäßig aktiviert (/etc/apache2/sites-enabled/default), zum Deaktivieren einfach den Eintrag entfernen oder explizit ein - vorne ran setzen:

```code
...
<Directory /var/www>
Options Indexes FollowSymLinks -MultiViews
...
```

# HSTS-Header (HTTP Strict Transport Security) konfigurieren

HTTP Strict Transport Security (abgekürzt HSTS, definiert in [RFC6797](https://tools.ietf.org/html/rfc6797 "https://tools.ietf.org/html/rfc6797")) ist ein Sicherheitsfeature einer Webseite, das dem Besucher, bzw. dessen Browser sagt, dass sie nur noch per HTTPS verschlüsselt mit ihm kommunizieren will. Dazu wird ein zusätzlicher HTTP-Header gesetzt, der Angaben zum Zeitraum, Umgang mit Subdomains und der Verwendung der [HSTS Preloadliste](https://hstspreload.appspot.com/ "https://hstspreload.appspot.com/") enthält.

Das Feature funktioniert folgendermaßen: Ein Besucher tippt z.B. www.seite-x.de in seinen Browser ein. Der Webserver leitet ihn auf HTTPS um. In der HTTPS-Verbindung wird ein zusätzlicher HTTP-Header gesendet, der bestimmte Informationen für den Browser enthält. Der Browser merkt sich das für den angegebenen Zeitraum. Bei zukünftigen Besuchen greift der Browser dann sofort auf die HTTPS Seite zu.

Es gibt folgende Keywörter:

- `max-age=63072000;` ⇐ innerhalb dieses Zeitraums wird direkt HTTPS angesteuert (Angabe in Sekunden).
- `includeSubDomains;` ⇐ der Eintrag gilt auch für sämtliche anderen Subdomains (vorsichtig damit, wenn andere Subdomains z.B. nicht per HTTPS funktionieren).
- `preload;` ⇐ Google [pflegt eine Liste](https://hstspreload.appspot.com/ "https://hstspreload.appspot.com/") mit Webseiten, die HSTS aktiviert haben. Diese Liste ist in aktuellen Versionen von Chrome, Firefox, Safari, IE11 und Edge enthalten. Diese Webseiten werden sofort per HTTPS angesurft. In die Liste kann man seine eigenen Webseiten jederzeit selbst eintragen, sofern die Voraussetzungen erfüllt werden.

Beim Apache-Webserver muss dazu folgender Eintrag in dem entsprechenden HTTPS-Vhost hinterlegt werden (vorher „`a2enmod headers`“ ausführen):

```code
Header always set Strict-Transport-Security "max-age=63072000; includeSubDomains; preload"
```

Die HTTP-Version der Webseite muss nun permanent auf HTTPS umgeleitet werden. Wie das für Apache einzurichten ist, habe ich [hier](https://wiki.magenbrot.net/linux/webserver/apache/permanente_umleitung_auf_https "linux:webserver:apache:permanente_umleitung_auf_https") beschrieben.

Danach muss Apache neu geladen/neu gestartet werden!

Wie man SSL mit modernen Ciphers und sicher konfiguriert steht in [diesem Artikel](https://wiki.magenbrot.net/books/webserver/page/sichere-ssl-konfiguration-Fpk "Sichere SSL Konfiguration").

# Sichere SSL Konfiguration

Mit dem „[Mozilla SSL Configuration Generator](https://ssl-config.mozilla.org/ "https://ssl-config.mozilla.org/")“ läßt sich aktuell wohl am einfachsten und schnellsten eine sichere Konfiguration für den nginx-Webserver erstellen.

Einfach Webserver, Version von Webserver und OpenSSL setzen und zwischen verschiedenen Cipherprofilen wählen, fertig ist eine Beispielkonfiguration.

Der Eintrag zu [TLS im Mozilla Wiki](https://wiki.mozilla.org/Security/Server_Side_TLS "https://wiki.mozilla.org/Security/Server_Side_TLS") ist auch sehr lesenswert.

<div id="bkmrk-"><div>---

</div></div>Alternativ habe ich hier noch meine (**veraltete**) Anleitung:

Die Empfehlungen richten sich nach den Vorgaben von [BetterCrypto.org](https://bettercrypto.org/ "https://bettercrypto.org/") und ihrem [Applied Crypto Hardening PDF](https://bettercrypto.org/static/applied-crypto-hardening.pdf "https://bettercrypto.org/static/applied-crypto-hardening.pdf") mit dem Stand vom 21.04.2016.

Folgendes kann man machen, um die Standard-SSL Konfiguration von Apache 2.4 sicherer zu gestalten:

<div id="bkmrk-schwache-cipher-und-"><div>- <div>Schwache Cipher und Protokolle abschalten</div>
- <div>Webserver soll die Reihenfolge der Ciphers vorgeben</div>
- <div>SSL-Komprimierung ausschalten</div>
- <div>[HSTS aktivieren](https://wiki.magenbrot.net/linux/webserver/apache/hsts-header_http_strict_transport_security_konfigurieren "linux:webserver:apache:hsts-header_http_strict_transport_security_konfigurieren")</div>
- <div>[Permanente Umleitung von HTTP nach HTTPS aktivieren](https://wiki.magenbrot.net/linux/webserver/apache/permanente_umleitung_auf_https "linux:webserver:apache:permanente_umleitung_auf_https")</div>

</div></div>Das folgende gilt für Apache 2.4 unter Debian. Ich trage dabei nur die beiden Direktiven für SSL-Zertifikatsbundle (SSLCertificateFile) und SSL-Keyfile (SSLCertificateKeyFile) direkt in den jeweiligen Vhost ein. Die restliche SSL-Konfiguration setze ich global (nach „`a2enmod ssl`“) in /etc/apache2/mods-enabled/ssl.conf. Vorher die bereits konfigurierten Settings auskommentieren (es sollen keine Direktiven doppelt eingetragen sein) und diesen Teil am Ende der Datei einfügen:

<div id="bkmrk-sslprotocol-all--ssl"><div>```
SSLProtocol All -SSLv2 -SSLv3
SSLHonorCipherOrder On
SSLCompression off
SSLCipherSuite 'EDH+CAMELLIA:EDH+aRSA:EECDH+aRSA+AESGCM:EECDH+aRSA+SHA256:EECDH:+CAMELLIA128:+AES128:+SSLv3:!aNULL:!eNULL:!LOW:!3DES:!MD5:!EXP:!PSK:!DSS:!RC4:!SEED:!IDEA:!ECDSA:kEDH:CAMELLIA128-SHA:AES128-SHA'
```

</div></div>Danach muss Apache neu geladen/neu gestartet werden!

# htaccess Verzeichnis schützen

Einfachstes Beispiel - ein Verzeichnis mit Username/Passwort-Abfrage schützen:

folgendes im zu schützenden Verzeichnis in der Datei .htaccess einfügen:

```code
AuthType Basic
AuthName "Interner Bereich"
AuthUserFile /var/www/html/.htpasswd
Require valid-user
```

damit dürfen sich alle in der .htpasswd existierenden Benutzer anmelden.

neue .htpasswd im aktuellen Verzeichnis erzeugen:

```code
htpasswd -c .htpasswd <username>
```

einen neuen Benutzer zu vorhandener .htpasswd hinzufügen (mit diesem Befehl lassen sich auch Kennwörter ändern):

```code
htpasswd .htpasswd <username>
```

[weiterführende Infos](http://de.selfhtml.org/servercgi/server/htaccess.htm "http://de.selfhtml.org/servercgi/server/htaccess.htm")

# Performancetuning

Folgende Fehlermeldung taucht im Log auf:

```code
[Fri Jul 13 10:48:59 2007] [error] server reached MaxClients setting, consider raising the MaxClients setting
```

Folgende Parameter beeinflussen die Server-Performance enorm. Grundsätzlich kann man mit folgenden Parametern mit dem Performance-Tuning beginnen:

```code
Timeout 15

KeepAlive On
MaxKeepAliveRequests 1000
KeepAliveTimeout 2

<IfModule prefork.c>
StartServers      10
MinSpareServers   10
MaxSpareServers   20
ServerLimit      250
MaxClients       250
MaxRequestsPerChild 8000
</IfModule>
```

# Permanente Umleitung auf HTTPS

Um Besucher permanent auf HTTPS umzuleiten kann dieser einfache Codeteil im HTTP-Vhost (Port 80) eingetragen werden:

```code
<VirtualHost *:80>
  ServerName seite-x.de
  Redirect permanent / https://seite-x.de/
  [...]
</VirtualHost>
```

Alternativ geht das auch mit mod\_rewrite (vorher „`a2enmod rewrite`“ ausführen):

```code
<VirtualHost *:80>
  ServerName seite-x.de
  RewriteEngine On
  RewriteCond %{HTTPS} off
  RewriteRule (.*) https://%{HTTP_HOST}%{REQUEST_URI}
  [...]
</VirtualHost>
```

Umleitung auf https nur für bestimmte Domains:

```code
# seite-z.de soll NICHT umgeleitet werden
<VirtualHost *:80>
  ServerName seite-x.de www.seite-x.de
  ServerAlias seite-y.de www.seite-y.de
  ServerAlias seite-z.de www.seite-z.de

  RewriteEngine On
  RewriteCond %{HTTPS} off
  RewriteCond %{HTTP_HOST} ^(www\.)seite-x.de$ [OR]
  RewriteCond %{HTTP_HOST} ^(www\.)seite-y.de$
  RewriteRule (.*) https://%{HTTP_HOST}%{REQUEST_URI} [R=301,L]
  
  # alternativ gleiche Regel mit seite-z.de negiert in der RewriteCond
```

Danach muss einmal der Apache neu gestartet werden. Wie man SSL mit modernen Ciphers und sicher konfiguriert steht in [diesem Artikel](https://wiki.magenbrot.net/books/webserver/page/sichere-ssl-konfiguration-Fpk "Sichere SSL Konfiguration").

# Reverse Proxy

Reverse Proxies werden (neben der Möglichkeit eine SSL-Version einer Webseite einfach einzubinden) auch benutzt, um z.B. eine Applikation, die auf einem anderen Port läuft, über Port 80 verfügbar zu machen. Typisches Beispiel wäre eine Java-App, die auf Port 8080 läuft.

- benötigte Module in der Apache-Config aktivieren, unter Debian geht das einfach mit „a2enmod proxy proxy\_http“ oder in anderen Distris diese beiden Zeilen in der httpd.conf einkommentieren:

```code
LoadModule  proxy_module         modules/mod_proxy.so
LoadModule  proxy_http_module    modules/mod_proxy_http.so
```

- jetzt folgendes in der VHost-Konfiguration eintragen (ACHTUNG: in diesem Beispiel wird der externe Inhalt direkt unter / eingebunden):

```code
ProxyRequests off
ProxyPreserveHost on
ProxyPass / http://localhost:8080/
ProxyPassReverse / http://localhost:8080/
```

- soll es über ein Unterverzeichnis erreichbar sein, wird der Code etwa so angepasst:

```code
ProxyRequests off
ProxyPreserveHost on
ProxyPass /applikation http://localhost:8080/
ProxyPassReverse /applikation http://localhost:8080/
```

- jetzt noch „service apache2 reload“, danach kann die Applikation z.B. als http://meinserver.de/applikation1 aufgerufen werden.

# SSL Reverse Proxy

Ein SSL Reverse Proxy ermöglicht es eine bestimmte Webseite über ein bereits vorhandenes Zertifikat über SSL abrufbar zu machen. Beispiel: Ihr habt eine Domain www.kundenshops.de gekauft und für diese ein SSL-Zertifikat gekauft. Jetzt haben Eure Kunden eigene Webshops aufgemacht und fragen Euch, wie sie diese günstig absichern können, damit z.B. Kundendaten verschlüsselt übertragen werden.

Statt jetzt jedem Kunden ein teures SSL-Zertifikat und eine eigene IP-Adresse zu verkaufen, könnt ihr seinen Shop auch per SSL Reverse Proxy absichern. Das bedeutet, dass der Shop des Kunden unter Eurem Zertifikat aufrufbar sein wird, eine URL würde dann z.B. so aussehen: https://www.kundenshops.de/www.mein-autoshop.de oder https://www.kundenshops.de/www.nasenfloetenshop.de.

Wie konfiguriere ich nun meinen Apache, damit das so funktioniert?

- benötigte Module in der Apache-Config aktivieren, unter Debian geht das einfach mit „a2enmod proxy proxy\_http“ oder in anderen Distris diese beiden Zeilen in der httpd.conf einkommentieren:

```code
LoadModule  proxy_module         modules/mod_proxy.so
LoadModule  proxy_http_module    modules/mod_proxy_http.so
```

- nun muss in der Konfiguration des SSL-Vhosts www.kundenshops.de folgendes eingetragen werden:

```code
RewriteRule ^/www.nasenfloetenshop.de$ /www.nasenfloetenshop.de/ [R,L]
ProxyPass /www.nasenfloetenshop.de/ http://www.nasenfloetenshop.de/
<Location /www.nasenfloetenshop.de/>
  ProxyPassReverse /
</Location>
```

- nach einem „service httpd reload“ steht nun der Inhalt von www.nasenfloetenshop.de SSL gesichert unter der URL https://www.kundenshops.de/www.nasenfloetenshop.de zur Verfügung.

<p class="callout info">Bei manchen CMS, wie z.B. Wordpress, sind noch Anpassungen in der Konfiguration nötig, da etwa die SITE\_URL fest hinterlegt ist und dynamisiert werden muss. Weitere Infos dazu finden sich zuhauf im Netz.</p>

Wie man SSL mit modernen Ciphers und sicher konfiguriert steht in [diesem Artikel](https://wiki.magenbrot.net/books/webserver/page/sichere-ssl-konfiguration-Fpk "Sichere SSL Konfiguration").

# TRACK und TRACE ausschalten

*von [Heise-Security](http://www.heise.de/security/news/meldung/43354 "http://www.heise.de/security/news/meldung/43354")*

**HTTP-Methoden ermöglichen unerlaubtes Ausspähen von Cookies**

Ist in einem Cookie die Option httpOnly definiert, darf nur der entsprechende Server darauf zugreifen. Versucht ein Skript den Inhalt des Cookies über die Methode document.cookie abzufragen, wird der Inhalt nicht zurückgeliefert. Damit lassen sich so genannte Cross-Site-Scripting-Attacken (XSS) abwehren. Das CERT/CC weist nun aber in einer Vulnerability Note darauf hin, dass Microsofts Internet Information Server (IIS) eine HTTP-Methode unterstützt, mit der sich solche Cookies trotzdem heimlich ausspähen lassen. Dieses Problem lässt sich allerdings auch analog auf andere Server wie den Apache übertragen.

Zur Fehlersuche ist im HTTP-Protokoll die TRACE-Methode definiert, die als Antwort die ursprüngliche Anfrage eines Web-Clients zurücksendet. Erfordert der Webserver eine Authentifizierung per Cookie, sendet der Client diese mit. In der HTTP-Antwort ist dementsprechend auch das Cookie enthalten. Mit einem Skript kann man nun das Cookie auslesen und anzeigen.

Um nicht das Sicherheitszonen-Modell zu verletzen, darf ein Skript nur mit der Domäne kommunizieren, aus der es stammt. Diverse Fehler in Web-Browsern ermöglichen es aber, Scripting-Code auch in anderen Domänen auszuführen. Damit kann ein Angreifer über eine manipulierte Webseite Code auf einem Client ausführen und über die TRACE-Methode andere Server ansprechen und Cookies auslesen. Diese Art von Angriff bezeichnet man als Cross-Site-Tracing-Angriffe (XST).

Die TRACE-Methode sollte aus Sicherheitsgründen auf Servern im Internet deaktiviert sein, die Anfrage eines Clients bleibt dann ohne Antwort. Ist sie doch aktiviert, schreibt der Server solche Anfragen immerhin in seine Log-Files. Microsoft hat im IIS eine eigene TRACE-Methode implementiert: TRACK. Diese Methode ist zwar nicht vollständig dokumentiert, erfüllt aber weitestgehend den gleichen Zweck wie TRACE. Allerdings loggt der IIS derlei Anfragen nicht mit. Damit kann man einen Angriff nicht mehr nachvollziehen.

Um beim Apache-Webserver die TRACE-Methode zu deaktivieren ist folgende Rewrite-Rule erforderlich:

```code
# TRACK und TRACE deaktivieren - http://www.heise.de/security/news/meldung/43354
RewriteCond %{REQUEST_METHOD} ^(TRACE|TRACK)
RewriteRule .* - [F,L]
```

Beim IIS lassen sich TRACE- und TRACK-Anfragen mit dem Tool URLScan ausfiltern. Als Methoden sollten nur noch GET, HEAD und POST erlaubt sein.

# virtuellen Host konfigurieren

Beispiel fuer einen NamedVirtualHost (HTTP + HTTPS):

```code
NameVirtualHost *:80
NameVirtualHost *:443

<VirtualHost _default_:80>
   ServerAdmin     webmaster@example.com
   ServerName      www.example.com
   ServerAlias     example.com
   DocumentRoot    /var/www/html/example.com
   ScriptAlias     /cgi-bin/ /var/www/html/example.com/cgi-bin/

   ErrorLog        logs/example.com-error_log
   CustomLog       logs/example.com-access_log combined

   RewriteEngine On

   # Umleitung auf komplette URL www.example.com
   RewriteCond %{HTTP_HOST}   !^www\.example\.com [NC]
   RewriteCond %{HTTP_HOST}   !^$
   RewriteRule ^/(.*)         http://www.example.com/$1 [L,R]

   # TRACK und TRACE deaktivieren - http://www.heise.de/security/news/meldung/43354
   RewriteCond %{REQUEST_METHOD} ^(TRACE|TRACK)
   RewriteRule .* - [F,L]
</VirtualHost>

<VirtualHost _default_:443>
   ServerAdmin     webmaster@example.com
   ServerName      www.example.com
   ServerAlias     example.com
   DocumentRoot    /var/www/html/example.com
   ScriptAlias     /cgi-bin/ /var/www/html/example.com/cgi-bin/

   ErrorLog logs/example.com-error_log
   TransferLog logs/example.com-access_log
   CustomLog logs/example.com-ssl_request_log "%t %h %{SSL_PROTOCOL}x %{SSL_CIPHER}x \"%r\" %b"
   LogLevel warn

   SSLEngine on
   #SSLCipherSuite ALL:!ADH:!EXPORT56:RC4+RSA:+HIGH:+MEDIUM:+LOW:+SSLv2:+EXP
   SSLCipherSuite SSLv3
   SSLCertificateFile /etc/pki/tls/certs/www.example.com.crt
   SSLCertificateKeyFile /etc/pki/tls/private/www.example.com.key
   SSLCACertificateFile /etc/pki/tls/certs/cacert.pem

   <Files ~ "\.(cgi|shtml|phtml|php3?)$">
     SSLOptions +StdEnvVars
   </Files>

   <Directory "/var/www/html/example.com/cgi-bin">
     SSLOptions +StdEnvVars
   </Directory>

   SetEnvIf User-Agent ".*MSIE.*" nokeepalive ssl-unclean-shutdown downgrade-1.0 force-response-1.0

   RewriteEngine On

   RewriteCond %{HTTP_HOST}   !^www\.example\.com [NC]
   RewriteCond %{HTTP_HOST}   !^$
   RewriteRule ^/(.*)         https://www.example.com/$1 [L,R]

   RewriteCond %{REQUEST_METHOD} ^(TRACE|TRACK)
   RewriteRule .* - [F,L]
</VirtualHost>
```

# X-Frame-Options setzen

Über den X-Frame-Options Header ([RFC 7034](https://tools.ietf.org/html/rfc7034 "https://tools.ietf.org/html/rfc7034")) kann eine Webseite den Browser anweisen, dass sie nicht (ggf. entfernt) über &lt;frame&gt; oder &lt;iframe&gt; geladen werden darf. Das soll sog. [Clickjacking](https://de.wikipedia.org/wiki/Clickjacking "https://de.wikipedia.org/wiki/Clickjacking") verhindern.

Im Apache läßt sich das so setzen (vorher „`a2enmod headers`“):

```code
Header always set X-Frame-Options DENY
```

Danach den Apache reloaden/neu starten.

Folgende Optionen sind möglich:

- DENY ⇐ Es ist keinerlei Einbettung per Frame erlaubt, egal welche Seite es versucht.
- SAMEORIGIN ⇐ Es ist nur die Einbettung in Seiten vom gleichen Ursprung erlaubt.
- ALLOW-FROM ⇐ Es ist nur die Einbettung in Seiten vom angebenen Ursprung erlaubt.

<p class="callout info">aktuell wird ALLOW-FROM nur von Firefox und Internet Explorer / Edge unterstützt.</p>

# Eigene Startseite für einen VHost mit vielen Aliasen

Problem: Wir haben einen VHost mit vielen Aliasen und jeder konfigurierte Alias soll eine eigene Startseite bekommen. ServerName ist z.B. domain.de, die Aliase tolledomain.de und ganzanderedomain.de sind im gleichen VHost konfiguriert, haben also auch das gleiche DocumentRoot. Ruft man jetzt die URLs auf, würde man auf der index.html landen. Um jetzt jedem VHost eine eigene Startseite zu geben, legt man im DocumentRoot eine .htaccess-Datei mit folgendem Inhalt an:

```code
RewriteEngine On
RewriteCond     %{HTTP_HOST}    ^(www\.)?tolledomain.de$
RewriteCond     %{REQUEST_URI}  ^/$
RewriteRule     ^(.*)$          /index_tolledomain.html

RewriteCond     %{HTTP_HOST}    ^(www\.)?ganzanderedomain.de$
RewriteCond     %{REQUEST_URI}  ^/$
RewriteRule     ^(.*)$          /index_ganzanderedomain.html
```

Die erste Zeile aktiviert die RewriteEngine. Die nächste Zeile bestimmt die Bedingung für welche URLs die Regel gilt. Durch das „(www\\.)?“ gilt diese Bedingung sowohl für tolledomain.de als auch für [www.tolledomain.de](http://www.tolledomain.de "http://www.tolledomain.de"). Die letzte Zeile lenkt schließlich alle Zugriffe auf /, d.h. alle Zugriffe, die nicht direkt auf eine Datei gehen auf die spezielle index-Seite für diese Domain um.

# weitere Möglichkeiten der Weiterleitung (ohne mod_rewrite)

#### Serverseitige Weiterleitung

- mit PHP:

```code
<?php
header("Status: 301 Moved Permanently");
header("Location:http://www.bla.de");
exit;
?>
```

- .htaccess-Weiterleitung, im DocumentRoot oder im gewünschten Unterordner des Auftritts eine Datei .htaccess mit folgendem Inhalt anlegen:

```code
Redirect permanent / http://www.bla.de
oder
Redirect permanent /dir/bla.html http://www.bla.de/bla/bla.html
```

#### clientseitige Weiterleitung

- durch ein Frameset (fremde Seite in eigener HTML-Seite laden, ist unschön und ist nicht gern gesehen):

```code
<html>
<head>
<title>sieht eh keiner</title>
</head>
<frameset rows="*">
<frame src="http://www.bla.de" name="Content">
</frameset>
</html>
```

- Metatag im Header einer Datei:

```code
<meta http-equiv="refresh" content="0; url=http://www.bla.de">
```

- JavaScript:

```code
<script language ="JavaScript">
<!--
window.location.replace('http://www.neueadresse.de');
// -->
</script>
```

oder

```code
<script LANGUAGE="JavaScript">
<!--
top.location.href='http://www.bla.de/'
// -->
</script>
```

</body></html>

# Weiterleitung ohne URL-Änderung (mit mod_rewrite)

Einfach den folgenden Code in der httpd.conf oder im entsprechenden vhost eintragen:

```code
RewriteEngine On
RewriteRule ^/(.*)$ https://www.zielserver.de/$1 [R,NC,P]
```

# mod_rewrite - /index.php/ aus URL entfernen

für lesbare und SEO-freundliche URLs kann man die index.php aus der URL entfernen. Das kann z.B. so aussehen:

```
RewriteCond %{THE_REQUEST} /index\.php/(.+)\sHTTP [NC]
RewriteRule ^ /%1 [NE,L,R]
```

außerdem müssen dann Zugriffe auf nicht-existente Dateien auf die index.php umgeleitet werden. Die Clients bekommen davon nichts mit:

```
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)$ /index.php/$1 [L]
```

Damit das funktioniert muss natürlich das rewrite-Modul aktiviert sein (`a2enmod rewrite`).