Apache

aus www.kruedewagen.de, Homepage von Ralf und Judith Krüdewagen (Kruedewagen)
Zur Navigation springen Zur Suche springen
Die druckbare Version wird nicht mehr unterstützt und kann Darstellungsfehler aufweisen. Bitte aktualisiere deine Browser-Lesezeichen und verwende stattdessen die Standard-Druckfunktion des Browsers.

Virtual Hosts mit SSL

Echte IP-based Virtual Hosts

Die beliebten named-based Virtual Hosts lassen sich eigentlich mit SSL nicht verwenden (Begründung siehe hier). Man muss also pro Virtual Host eine separate IP-Adresse verwenden, z.B. durch Zuweisung einer Alias-IP-Adresse und (bei NAT) Umleitung eines zusätzlichen Ports vom Router.

Die Konfig sieht dann so aus:

<IfDefine SSL>
<IfDefine !NOSSL>

<Directory "/srv/www/vhosts/server1">
        Options None
        AllowOverride AuthConfig
        Order allow,deny
        Allow from all
</Directory>

<Directory "/srv/www/vhosts/server2">
        Options None
        AllowOverride AuthConfig
        Order allow,deny
        Allow from all
</Directory>

<VirtualHost 1.1.1.1:443>
...
DocumentRoot "/srv/www/vhosts/server1"
...
SSLCertificateFile /etc/apache2/ssl.crt/server1.crt
SSLCertificateKeyFile /etc/apache2/ssl.key/server1.key
...
</VirtualHost>

<VirtualHost 1.1.1.2:443>
...
DocumentRoot "/srv/www/vhosts/server2"
...
SSLCertificateFile /etc/apache2/ssl.crt/server2.crt
SSLCertificateKeyFile /etc/apache2/ssl.key/server2.key
...
</VirtualHost>

</IfDefine>
</IfDefine>

Vorteil: Man kann jedem Virtual Host eigene Keys und SSL-Zertifikate zuordnen.

Named-based Virtual Hosts

Es ist jedoch mit named-based Virtual Hosts zumindest möglich, Server mit verschiedenen DocumentRoot Verzeichnissen aufzusetzen . Allerdings wird dabei immer nur das SSL-Zertifikat des ersten Hosts verwendet, da der Host-Header erst nach dem SSL-Handshake ausgewertet wird (so dass es am Client ggf. eine Fehlermeldung gibt).

Die Konfig sieht dann so aus:

NameVirtualHost *:443
<IfDefine SSL>
<IfDefine !NOSSL>

<Directory "/srv/www/vhosts/server1">
        Options None
        AllowOverride AuthConfig
        Order allow,deny
        Allow from all
</Directory>

<Directory "/srv/www/vhosts/server2">
        Options None
        AllowOverride AuthConfig
        Order allow,deny
        Allow from all
</Directory>

<VirtualHost *:443>
...
DocumentRoot "/srv/www/vhosts/server1"
...
SSLCertificateFile /etc/apache2/ssl.crt/server1.crt
SSLCertificateKeyFile /etc/apache2/ssl.key/server1.key
...
</VirtualHost>

<VirtualHost *:443>
...
DocumentRoot "/srv/www/vhosts/server2"
...
SSLCertificateFile /etc/apache2/ssl.crt/server1.crt
SSLCertificateKeyFile /etc/apache2/ssl.key/server1.key
...
</VirtualHost>

</IfDefine>
</IfDefine>

SSL-Proxy

Das Problem mit mehreren IP-Adressen kann man umgehen, wenn man das Modul mod_rewrite einsetzt, um einen "SSL-Proxy" zu bauen. Siehe z.B. http://www.serversupportforum.de/forum/faqs-anleitungen/2558-howto-ssl-proxy.html.

Nachteil: Unschöne URLs.

mod_rewrite

siehe

Alle Zugriffe von Port 80 auf Port 443 (SSL) umleiten

RewriteEngine on
RewriteCond %{SERVER_PORT} =80
RewriteRule ^(.*) https://%{SERVER_NAME}%{REQUEST_URI}

bzw.

RewriteEngine on
RewriteCond %{SERVER_PORT} !^430$
RewriteRule ^(.*) https://%{SERVER_NAME}%{REQUEST_URI} [L,R]

oder

<VirtualHost *:80>
       ServerAlias *
       RewriteEngine On
       RewriteRule ^(.*)$ https://%{HTTP_HOST}$1 [redirect=301]
</VirtualHost>

Diese Konfig funktioniert auch im <Directory>-Kontext, um z.B. nur eine bestimmte URL umzuleiten. Die folgende Konfig leitet nur http://www.kruedewagen.de/path auf https://www.kruedewagen.de/path um (und alle Unterverzeichnisse):

Alias /path /usr/share/path
<Directory /usr/share/path/>
  Options FollowSymLinks
  RewriteEngine On
  RewriteCond %{SERVER_PORT} !^443$
  RewriteRule ^(.*) https://%{SERVER_NAME}%{REQUEST_URI} [L,R]
</Directory>

Wenn man Zugriffe von Localhost (Port 80) nicht nach HTTPS umleiten will (z.B. bei Problemen mit MediaWiki Job Queue):

<VirtualHost *:80>
       RewriteEngine On
       RewriteCond %{REMOTE_HOST} !127.0.0.1$
       RewriteCond %{REMOTE_HOST} !::1$
       RewriteCond %{REMOTE_HOST} !192.168.1.9$
       RewriteCond %{REMOTE_HOST} !2a2a:2b2b2:2c2c2::1$
       RewriteCond %{SERVER_PORT} !^443$
       RewriteRule ^(.*) https://%{SERVER_NAME}%{REQUEST_URI} [L,R]
</VirtualHost>

Zugriff auf IP auf FQDN umleiten

Eingabe im Browser: http://1.2.3.4 , Ziel der Umleitung: https://www.example.com.

<VirtualHost 1.2.3.4:80>
        ServerName www-ip.example.com
        RewriteEngine On
        # Redirect access by IP address

        #RewriteCond %{SERVER_NAME} 1.2.3.4
        #RewriteRule ^(.*) https://www.example.com/$1 [L,R]

        # nur direkter Aufruf, nicht alle URLs
        #RewriteCond %{HTTP_HOST} !^www.example.com$
        #RewriteRule /.* https://www.example.com/ [R]

        RewriteCond %{HTTP_HOST} !^www.example.com$
        RewriteRule /.* https://www.example.com/$1 [R]
</VirtualHost>

Ein / am Ende der URL einfügen

RewriteEngine on
RewriteRule ^/url$ http://www.mydomain.de/url/ [R]

Logging

Um rewrite Logging einzuschalten (für gesamten Server oder auf Virtual Host Ebene):

  RewriteEngine on
  RewriteLog "/var/log/apache2/rewrite.log"
  RewriteLogLevel 2

Aussperren

  • Zugriff für User Agent (z.B. Bot bzw. Suchmaschine) verhindern
RewriteEngine On
RewriteCond %{HTTP_USER_AGENT} (bot1|bot2) [NC]
RewiteRule ^ - [L,R=403]
  • IP Adressen aussperren: wie oben aber mittels RewriteCond auf IP setzen
RewriteCond  %{REMOTE_ADDR} 1.2.3.4

Authentifizierung

Apache 2.2

Wenn man eine Basic-Authentifizierung für ein Verzeichnis eingerichtet hat, gilt das normalerweise auch für alle Unterverzeichnisse. Man kann jedoch die Abfrage von Username/Passwort für Unterverzeichnisse ausschließen mittels:

Allow from all
Satisfy Any

siehe:

Mit der folgenden Konfiguration wird Authentifizierung nur für bestimmte IP-Ranges ausgeschaltet:

<Directory /path/>
  AllowOverride None
  Order allow,deny
  Allow from 127
  Allow from 192.168.0.0/16
  Allow from 10.1.0.0/16
  AuthType Basic
  AuthName "Login"
  AuthUserFile /path/to/htpasswd
  Require user user1
  Satisfy Any
</Directory>

Apache 2.4

Die Require-Direktiven werden nun im Modul mod_authz_core behandelt.

Änderung gegenüber Apache 2.2: Statt

Order allow,deny
Allow from all

verwendet man

Require all granted

Hinwiese:

  • "Require all denied" ist i.d.R. als Default gesetzt, so dass "Require all granted" in jeder Directory-Direktive gesetzt werden muss, wenn ein Zugriff allgemein erlaubt sein soll.
  • Eine Mischung der neuen Require-Direktiven mit "Allow/Deny from" sollte unbedingt vermieden werden.

Beispiele

Login nur mit Basic Auth:

<Directory "/srv/www/vhosts/myhost">
        Options FollowSymLinks
        AllowOverride None

        Require all denied

        AuthType Basic
        AuthName "MyHost Login"
        AuthUserFile /srv/www/passwdfile

        <RequireAny>
                Require user myuser
        </RequireAny>
</Directory>

Erlaube Zugriff über IP-Ranges oder - falls man von anderer IP kommt - alternativ per Basic Auth:

<Directory "/srv/www/vhosts/myhost">
        Options FollowSymLinks
        AllowOverride None

        Require all denied

        AuthType Basic
        AuthName "MyHost Login"
        AuthUserFile /srv/www/passwdfile

        <RequireAny>
                Require ip 192.168
                Require ip ::1
                Require user myuser
        </RequireAny>
</Directory>

Authentifizierung auf bestimmte Bereiche (Webseiten) beschränken mit FilesMatch-Direktive, z.B. bei Wordpress auf die Login- und Konfigurationsseite:

<Directory "/srv/www/vhosts/myhost">
        Options FollowSymLinks
        AllowOverride None

        <FilesMatch "(wp-config.php|wp-login.php">
          Require all denied
          AuthType Basic
          AuthName "MyHost Login"
          AuthUserFile /srv/www/passwdfile

          <RequireAny>
                Require ip 192.168
                Require ip ::1
                Require user myuser
          </RequireAny>
        </FilesMatch>
</Directory>

TLS

SSL/TLS Zertifikate allgemein

  • erstellt private Key mit Passphrase
openssl genrsa -des3 -out server.key 2048
  • erstellt private Key ohne Passphrase
openssl genrsa -out server.key 2048
  • erstellt Zertifikatssignierungsanfrage (CSR)
openssl req -sha256 -new -key server.key -out server.csr
  • Zertifikatssignierungsanfrage (CSR) anzeigen
openssl req -in server.csr -noout -text
  • erstellt selbstsigniertes Zertifikat
openssl x509 -req -days 365 -in server.csr -signkey server.key -out server.crt
  • Zertifikat anzeigen
openssl x509 -in server.crt -noout -text

Zertifikate für mehrere Namen

Die "alternativen Namen" müssen im CSR stehen! Dazu muss eine Konfiguration erstellt werden, z.B.

[ req_distinguished_name ]
countryName = DE
stateOrProvinceName = NRW
localityName = Mettmann
O = Example GmbH
organizationalUnitName  = IT 
commonName = www.example.com
emailAddress = user@example.com

[ v3_req ]
basicConstraints        = CA:FALSE
subjectAltName = @alt_names

[alt_names]
DNS.1 = www.example.com
DNS.2 = example.com

Dann CSR erstellen:

openssl req -sha256 -new -key server.key -out server.csr -config openssl.cnf

SSL/TLS Zertifikate unter openSUSE

Keys und CSR können mit folgendem Script aus dem Paket apache2-utils erzeugt werden:

/usr/bin/gensslcert

Vorgehen:

  • Änderungen in /usr/bin/gensslcert vornehmen
    • Schlüssellänge auf 4096 setzen
    • Ggf. Email-Adresse aus dem CSR entfernen (je nach CA)
    • "-sha256" als Option bei der Erzeugung des CSR hinzufügen
  • Schlüssel und CSR erzeugen, z.B. für CAcert:
gensslcert -c DE -s NRW -l Mettmann -o "privat" -u "privat" -e "webmaster@kruedewagen.de" -n kruedewagen.de
oder für StartSSL ("www" im CN-Feld):
gensslcert -c DE -s NRW -l Mettmann -o "privat" -u "privat" -e "webmaster@kruedewagen.de" -n www.kruedewagen.de
ACHTUNG: Dieses Kommando überschreibt die server.* Dateien in /etc/apache2/ssl.*.

Server Name Indication (SNI)

Mehrere SSL-Server unter einer IP-Adresse.

Generatoren und Konfiguration erstellen

Zertifikate-Chain

Ab Apache 2.4.8 kann bzw. sollte die komplette Zertifikate-Chain (inkl. Server-Zertifikat, Intermediates, Root CA) in SSLCertificateFile angegeben werden.

Performance Tuning

Siehe

Server-Einstellungen

Möglichst gute Settings:

StartServers         5
MinSpareServers      5
MaxSpareServers     10
ServerLimit       255
MaxClients         255
MaxRequestsPerChild  50000

KeepAlive On
MaxKeepAliveRequests 500
KeepAliveTimeout 15

Server Status

<IfModule mod_status.c>
    <Location /server-status>
        SetHandler server-status
        Order deny,allow
        Deny from all
        Allow from localhost 127.0.0.1
    </Location>
</IfModule>
ExtendedStatus On

Hinweis: "ExtendedStatus On" sollte nut temporär gesetzt sein.

Komprimierung und Cache Expiration

Die Module mod_deflate und mod_expires sollten geladen sein, unter Apache 2.4 auch das filter Modul. Zur richtigen Einrichtung der Komprimierung und der Ablauf-Zeiten, sollte folgende Konfig erstellt werden:

/etc/httpd/conf.d/deflate_expires.conf

Resultat:

  • Der Server sollte in der Antwort zurücksenden:
Content-Encoding	gzip
  • Der Content ist mit den eingestellten Expiry Zeiten versehen, so dass das Caching auf der Client-Seite verbessert wird.

Weblinks:

HTTP/2

In Apache HTTP/2 zusammen mit PHP-FPM, TLS 1.3 einrichten siehe Apache + HTTP2 + PHP-FPM + TLS 1.3.

HTTP/2 Testseiten:

Spezialitäten

Samba Share

Folgende Konfiguration ist nötig, falls Dateien von einem Samba-Share über Apache zugänglich gemacht werden sollen, ansonsten werden z.B. größere Dateien nicht vollständig transferiert (nur ca. 60 kByte):

<directory /path_to_dir>
  EnableMMAP off
  EnableSendfile off
</directory>

/path_to_dir ist das Verzeichnis, welches dann u.U. per symlink auf das Samba Share verweist.

Dokumentation

Siehe auch