Apache: Unterschied zwischen den Versionen

aus www.kruedewagen.de, Homepage von Ralf und Judith Krüdewagen (Kruedewagen)
Zur Navigation springen Zur Suche springen
 
(37 dazwischenliegende Versionen desselben Benutzers werden nicht angezeigt)
Zeile 144: Zeile 144:
   RewriteRule ^(.*) https://%{SERVER_NAME}%{REQUEST_URI} [L,R]
   RewriteRule ^(.*) https://%{SERVER_NAME}%{REQUEST_URI} [L,R]
</Directory>
</Directory>
</source>
Wenn man Zugriffe von '''Localhost''' (Port 80) '''nicht nach HTTPS umleiten will''' (z.B. bei Problemen mit MediaWiki Job Queue):
<source lang="apache">
<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>
</source>
=== Zugriff auf IP auf FQDN umleiten  ===
Eingabe im Browser: http://1.2.3.4 , Ziel der Umleitung: https://www.example.com.
<source lang="apache">
<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>
</source>
</source>


Zeile 159: Zeile 192:
   RewriteLogLevel 2
   RewriteLogLevel 2
</source>
</source>
=== Aussperren ===
*Zugriff für User Agent (z.B. Bot bzw. Suchmaschine) verhindern
<syntaxhighlight lang="apache">
RewriteEngine On
RewriteCond %{HTTP_USER_AGENT} (bot1|bot2) [NC]
RewiteRule ^ - [L,R=403]
</syntaxhighlight>
*IP Adressen aussperren: wie oben aber mittels RewriteCond auf IP setzen
<syntaxhighlight lang="apache">
RewriteCond  %{REMOTE_ADDR} 1.2.3.4
</syntaxhighlight>


== Authentifizierung ==
== Authentifizierung ==
Zeile 245: Zeile 290:
</Directory>
</Directory>
</syntaxhighlight>
</syntaxhighlight>
Authentifizierung auf bestimmte Bereiche (Webseiten) beschränken mit [http://httpd.apache.org/docs/current/mod/core.html#filesmatch FilesMatch]-Direktive, z.B. bei [[Wordpress]] auf die Login- und Konfigurationsseite:
<syntaxhighlight lang="apache">
<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>
</syntaxhighlight>
== TLS ==
===SSL/TLS Zertifikate allgemein===
*siehe [[c't]] 4/2005, S. 205, u.a. [[WebDAV]]
*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 ===
*http://en.wikipedia.org/wiki/SubjectAltName
*http://apetec.com/support/GenerateSAN-CSR.htm
Die "alternativen Namen" müssen im CSR stehen! Dazu muss eine Konfiguration erstellt werden, z.B.
<pre>
[ 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
</pre>
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 ===
*[https://mozilla.github.io/server-side-tls/ssl-config-generator/ Mozilla SSL Configuration Generator]
=== Zertifikate-Chain ===
Ab Apache 2.4.8 kann bzw. sollte die komplette Zertifikate-Chain (inkl. Server-Zertifikat, Intermediates, Root CA) in ''SSLCertificateFile'' angegeben werden.
*http://serverfault.com/questions/588986/sslcertificatechainfile-deprecation-warning-on-apache-2-4-8
*http://stackoverflow.com/questions/31370454/sslcertificatechainfile-is-obsolete


== Performance Tuning ==
== Performance Tuning ==
Siehe http://httpd.apache.org/docs/2.2/misc/perf-tuning.html.
Siehe
*http://httpd.apache.org/docs/2.2/misc/perf-tuning.html
*http://httpd.apache.org/docs/2.4/misc/perf-tuning.html
*http://www.thomas-krenn.com/de/wiki/Apache_Performance_Tuning


=== Server-Einstellungen ===
Möglichst gute Settings:
Möglichst gute Settings:
<source lang="apache">
<source lang="apache">
Zeile 281: Zeile 422:


Hinweis: "ExtendedStatus On" sollte nut temporär gesetzt sein.
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:
[[/deflate_expires.conf|/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://betterexplained.com/articles/how-to-optimize-your-site-with-gzip-compression/
*http://gtmetrix.com/enable-gzip-compression.html
*http://stackoverflow.com/questions/12367858/how-can-i-get-apache-gzip-compression-to-work
*http://tecadmin.net/how-to-enable-gzip-compression-on-apache/
*http://www.linux-faqs.info/apache/optimize-website-speed-with-mod-expire-and-mod-deflate
== HTTP/2 ==
In Apache HTTP/2 zusammen mit PHP-FPM, TLS 1.3 einrichten siehe [[/Apache+HTTP2+PHP-FPM+TLS1.3|Apache + HTTP2 + PHP-FPM + TLS 1.3]].
HTTP/2 Testseiten:
*https://http2.golang.org/
*https://tools.keycdn.com/http2-test


== Spezialitäten ==
== Spezialitäten ==
Zeile 298: Zeile 464:
== Siehe auch ==
== Siehe auch ==
*[[PHP]]
*[[PHP]]
*[[Postfix]]


[[Kategorie:Webserver]]
[[Kategorie:Webserver]]

Aktuelle Version vom 11. November 2020, 16:58 Uhr

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