[HOWTO] - Apache & MySQL unter Windows absichern.

Tarnatos

Lt. Commander
Registriert
Nov. 2005
Beiträge
1.308
Hallo Leute,

ich möchte diesen Thread nach und nach zu einen Howto ausbauen und brauche dafür eure Mithilfe.

Ziel soll es sein, die Windows Server Apache und MySQL sicher, d.h. internettauglich zu installieren. Als Basis verwende ich hier XAMPP, welches ja von Hause aus NICHT für den Produktivbetrieb geeignet ist. Dies möchte ich mit den Guide in Zukunft ändern.

Folgende Versionen kommen zum Einsatz:
  • XAMPP 1.8.0
  • Apache 2.4.2
  • MySQL 5.5.25a
  • PHP 5.4.4
  • phpMyAdmin 3.5.2

1. Grundlegendes
1.1 Windows Benutzer anlagen


Damit XAMPP und später auch die Server nicht direkt als Administrator ausgeführt werden, muss ein neuer Benutzer auf dem System angelegt werden. Dieser sollte maximal der Benutzergruppe "Benutzer" angehören und mit einem Passwort versehen sein. Hier sollte natürlich darauf geachtet werden, dass sowohl Benutzername als auch das Passwort nicht leicht erraten werden können.

2. XAMPP Installation

Nun kann XAMPP installiert werden. Nach Möglichkeit sollte dies nicht auf dem Systemlaufwerk geschehen. Ich schlage hier vor, mit 3 Partitionen zu arbeiten. Die erste für Windows, die zweite für Programme, die dritte für die Daten, u.a. das htdocs Verzeichnis. Wer nicht extra seine Festplatte umpartitionieren möchte kann z.B. mit TrueCrypt ein neues verschlüsseltes Laufwerk für den htdocs Ordner erstellen oder arbeitet ab Windows 7 mit virtuellen Festplatten. Was ihr macht ist euch überlassen. Ich beschreibe in dieses Guide eine Möglichkeit mit 3 Partitionen.

Achte hier darauf dass du als Dateisystem NTFS einsetzt um mit Dateirechten Arbeiten zu können!

  • C:\ für Windows
  • D:\ für Programme
  • E:\ für Dateien

Installiert nun also XAMPP auf D:\ und startet es nicht.

2.1 Rechtekonfiguration

Eine sinnvolle Rechtekonfiguration ist unerlässlich.

Folgende Verzeichnisse benötigen Leserechte:
  • XAMPP Hauptverzeichnis
  • htdocs
Folgende Verzeichnisse benötigen Schreibrechte:
htdocs
  • \xampp\apache\logs
  • \xampp\mysql\backup
  • \xampp\mysql\data
  • \xampp\tmp
  • \xampp\php\logs
  • \xampp\php\www

Alle selbst erstellten Ordner im PHP Verzeichnis:

Gemäß diesem Guide also (s.u.):
  • \xampp\php\work
  • \xampp\php\input

Die Benutzergruppe "Benutzer" sollte, abgesehen von ihrem "Benutzerordner" weder Lese noch Schreibrechte auf Laufwerk C besitzen. Da diese Benutzergruppe sich nicht am System anmelden wird sondern gem. diesem Guide nur für Anwendungen genutzt wird sollte es daher keine Probleme geben.

Zum "Benutzerordner" Ordner sollten jedoch Leserechte und Schreibrechte eingeräumt werden.

2.1.1 Firewallkonfiguration

Hier kommt es nun drauf an, was du möchtest. Oft reicht es aus, wenn nur der Apache Web Server aus dem Internet erreichbar ist.

2.2 MySQL

Der MySQL Server (mysqld.exe) muss nicht zwingend von außen erreichbar sein. Möchtet ihr die Datenbanken nur für Webanwendungen nutzen die auf dem gleichen Computer laufen reicht es, wenn du den Zugriff in der Firewall für den MySQL Server auf localhost (127.0.0.1) beschränkst.

Zusätzlich muss noch die "my.ini" („XAMPP-Verzeichnis/mysql/bin/my.ini“) angepasst werden.

Suche und ersetze durch:
#bind-address="127.0.0.1"

Durch:

bind-address="127.0.0.1"

Unnötige Benutzer löschen:
Offnet PHPMyAdmin und lösche folgende Benutzer inkl. der zugehörigen Datenbanken:

  • Jeder
  • root (Host Linux)
Öffnet in der Datenbank "mysql" die Tabelle "user". Stellt sicher, dass dort bei jedem Benutzer als "Host" "localhost" eingetragen ist. Hier darf auf keinen Fall ein % auftauchen, dies würde den Zugriff auf den MySQL Server von überall aus erlauben.

Schließt nun PHPMyAdmin und geht auf die Seite: https://localhost/security/xamppsecurity.php. Dort vergebt für ihr ein möglichst komplexes Passwort für den "root" Benutzer und ein weiteres für das XAMPP Verzeichnis.

Abfragenanzahl begrenzen:
Um bei fehlerhaften Abfragen den Server nicht totlaufen zu lassen, kann die Dauer der Abfrage begrenzt werden. Dies verhindert eine konstante Auslastung des MySQL Servers bei fehlerhaften oder gewollt falschen Abfragen.

Suche und füge danach ein:
max_allowed_packet = 1M

Füge danach ein:

max_join_size=20000000

2.2.1 PHPMyAdmin absichern

Öffnet nun wieder PHPMyAdmin (als "root" anmelden) und vergebt ein Passwort für den Benutzer "pma". Schießt den PHPMyAdmin und öffnet die Datei "XAMPP Verzeichnis\phpMyAdmin\config.inc.php".

PMA Passwort eintragen:
Sucht nach:
"$cfg['Servers'][$i]['controlpass'] = "
und tragt zwischen den '' das eben erstellt Passwort ein.

PhpMyAdmin Authentifikation auf "http"ändern:

Sucht nach und ersetze es durch:
/* Authentication type and info */
$cfg['Servers'][$i]['auth_type'] = 'cookie'; // Authentication method (config, http or cookie based)
$cfg['Servers'][$i]['user'] = 'root';
$cfg['Servers'][$i]['password'] = '';


Ersetzen durch:

/* Authentication type and info */
$cfg['Servers'][$i]['auth_type'] = 'http'; // Authentication method (config, http or cookie based)
$cfg['Servers'][$i]['user'] = '';
$cfg['Servers'][$i]['password'] = '';

PHPMyAdmin nur lokal erreichbar machen:
Öffne die Datei "httpd-xampp.conf".

Suche und ersetze durch:
"Alias /phpmyadmin "D:/xampp/phpMyAdmin/"

Allow from all


Ersetze durch:

Allow from 127.0.0.1
Deny from all

2.3 Apache

Der Apache Web Server muss in jeden Fall von außen erreichbar sein, damit andere via Internet auf ihn zugreifen können.

Öffne die Datei "httpd.conf".

Listen Ports ändern:
ACHTUNG! Nicht jede Webanwendung muss zwingend auch den Port 80 nutzen. In meinem Fall möchte ich ausschließlich SSL verschlüsselte (https) Verbindungen nutzen. Daher benötige ich nur den Port 443. Bedenkt bitte, dass der PHPMyAdmin und die XAMPP Willkommens Seite dann nicht mehr ohne weiteres aus dem XAMPP Control Center aufrufbar sind. Eurer Browser wird dann einen 404 Fehler ausgeben. Setzt daher statt des http ein https vor die URL und speichert euch die beiden Seiten als Favorit ab.

Suche und füge davor ein:

Trace abschalten um XST Angriffe zu verhindern:

Gehe an das Ende der Datei und füge ein:

Directory Listing abschalten:

Suche und ersetze durch:
Options Indexes

Ersetze durch:

Options

CGI und SSI Erweiterungen abschlaten

Suche und lösche:

Unnötige Statusanzeigen unterbinden:

Gehe an das Ende der Datei und füge ein:
ServerSignature Off
ServerTokens Prod

Nicht jeder muss wissen, welche Apache Version ihr einsetzt. Um das zu verhindern, gibt es diverse Möglichkeiten. Es reicht, wenn der Apache als Antwort sendet, dass er ein Apache Server ist.

DS Store Files verbieten:

Wer WEBDAV nutzt und nicht möchte, dass .DS Store Files von Mac Rechnern auf im WEBDAV Laufwerk erstellt werden können, muss dies vermerken.

Gehe ans Ende der Datei und füge ein:
<FilesMatch '^\.[Dd][Ss]_[Ss]'>
Order allow,deny
Deny from all
</FilesMatch>

thumbs.db Files verbieten:

Gehe ans Ende der Datei und füge ein:
<FilesMatch '\.[Dd][Bb]'>
Order allow,deny
Deny from all
</FilesMatch>

SVN Dateien verbieten:

Suche und füge darunter ein:
# CGI directory exists, if you have that configured.
#

<DirectoryMatch "/\.svn/">
Order allow,Deny
Deny from all
</DirectoryMatch>

Unnötige Module abschalten:

Suche und füge davor ein:
LoadModule cgi_module modules/mod_cgi.so
#
Dies schaltet die CGI Erweiterung ab, die nur noch in sehr seltenen Fällen benötigt wird.

Suche und füge davor ein:
LoadModule proxy_module modules/mod_proxy.so
LoadModule proxy_ajp_module modules/mod_proxy_ajp.s

#
Dies verhindert, dass der Apache als Proxy eingesetzt werden kann.

Suche und füge davor ein:
LoadModule status_module modules/mod_status.so
LoadModule info_module modules/mod_info.so

#
Nun gibt der Apache keine unnötigen Statusinformationen mehr aus.

2.3.1 Scheunentor xampp\apache\conf\extra

Alle Einstellungen die wir bis jetzt vorgenommen haben sind völlig wirkungslos, wenn man nicht den o.g. Ordner aufräumt.

Wer die hier beschriebene Konfiguration vornimmt kann folgende Dateien löschen oder besser archivieren:

  • httpd-ajp.conf
  • httpd-proxy.conf
  • proxy-html.conf

Einige Dateien müssen hier jedoch noch angepasst werden, um Hintertürchen zu schließen.

2.3.1.1 httpd-default.conf

Um im Fall der Fälle auch eine sichere Grundkonfiguration zu haben müssen alle Einträge die in der httpd.conf gemacht wurden auch in der httpd-default.conf eingetragen sein. Hier das Ganze nochmal im Schnelldurchgang:

ServerTokens Prod
ServerSignature Off
TraceEnable Off

2.3.1.2 httpd-xampp.conf

Hier muss etwas mehr Hand angelegt werden, da die Datei bewußt einige Türchen offen läßt.

CGI abschalten:

Suche und ersetze durch:
<Directory "D:/xampp/cgi-bin">
<FilesMatch "\.php$">
SetHandler cgi-script
</FilesMatch>
<FilesMatch "\.phps$">
SetHandler None
</FilesMatch>
</Directory>


Ersetze durch:

#<Directory "D:/saveHOUSE/xampp/cgi-bin">
# <FilesMatch "\.php$">
# SetHandler cgi-script
# </FilesMatch>
# <FilesMatch "\.phps$">
# SetHandler None
# </FilesMatch>
#</Directory>


XAMP Security, Lizenzen, PHPMyAdmin und Webanalizer nur local verfügbar machen:

Suche und ersetze durch:
<Files "xamppsecurity.php">
php_admin_flag safe_mode off
</Files>
</IfModule>
AllowOverride AuthConfig
Order allow,deny
Allow from all


Ersetze durch:

<Files "xamppsecurity.php">
php_admin_flag safe_mode off
</Files>
</IfModule>
AllowOverride AuthConfig
Order allow,deny
Allow from 127.0.0.1
Deny from all

Suche und ersetze durch:
DirectoryIndexALinkColor "#bb3902"
</IfModule>
Order allow,deny
Allow from all


Ersetze durch:

DirectoryIndexALinkColor "#bb3902"
</IfModule>
Order allow,deny
Allow from 127.0.0.1
Deny from all


Suche und ersetze durch:
<Directory "D:/xampp/phpMyAdmin">
AllowOverride AuthConfig
Order allow,deny
Allow from all

Ersetze durch:

<Directory "D:/xampp/phpMyAdmin">
AllowOverride AuthConfig
Order allow,deny
Allow from 127.0.0.1
Deny from all

Suche und ersetze durch:
<Files "webalizer.php">
php_admin_flag safe_mode off
</Files>
</IfModule>
AllowOverride AuthConfig
Order allow,deny
Allow from all


Ersetze durch:

<Files "webalizer.php">
php_admin_flag safe_mode off
</Files>
</IfModule>
AllowOverride AuthConfig
Order allow,deny
Allow from 127.0.0.1
Deny from all

Suche und lösche:
fc00::/7 10.0.0.0/8 172.16.0.0/12 192.168.0.0/16 \
fe80::/10 169.254.0.0/16

Suche und ersetze durch:
Allow from ::1 127.0.0.0/8 \
Deny from all


Ersetze durch:

Allow from ::1 127.0.0.1
#Deny from all

2.3.1.3 httpd-autoindex.conf

Suche und ersetze durch:
Order allow,deny
Allow from all


Ersetze durch:

Order allow,deny
Allow from 127.0.0.1
Deny from all

2.4 PHP absichern

Auch das PHP Modul sollte nachkonfiguriert werden.

Header verkürzen:
Öffnet die Datei "php.ini"

Suche und ersetze durch:
expose_php = On

Ersetzte durch:

expose_php = Off

PHP Fehlermeldungen sollten nicht ausgegeben werden, sondern in eine Datei gespeichert werden. Dies muss jedoch eingestellt werden.

Suche und ersetze
display_errors = On

Ersetze durch:

display_errors = Off

Mitlerweile ist es voreingestellt, dass Fehler nun unter "XAMP Verzeichnis\php\logs\php_error_log" gespeichert werden.

Automatisches Nachladen von PHP Scripten verhindern:

Suche und ersetze:
enable_dl = On

Ersetze durch:

enable_dl = Off

URL include / require abschalten:

Suche und ersetze
allow_url_include = On

Ersetze durch:

allow_url_include = Off

Einzelne PHP Funktionen deaktivieren:

Suche und ersetze
disable_functions =

Ersetze durch:

disable_functions = system, shell_exec, popen, pclose, proc_open, proc_close, proc_get_status, proc_nice, proc_terminate, exec, passthru, show_source, readfile, escapeshellcmd, escapeshellarg

Hierbei muss man genau wissen (oder probieren) welche PHP Funktionen für seine Webanwendung(en) benötigt werden. Ggf. müßen einzelne Funktionen nach und nach wieder aktiviert werden.

Memory Limit setzen:

Suche und ersetze durch:
memory_limit = 128M

Ersetze durch:

memory_limit = 64M

Maximale Ausführdauer eines Scripts begrenzen:

Suche und ersetze durch:
max_execution_time = 30

Ersetze durch:

max_execution_time = 60

Nachladen von beliebigen HTTP Daten verhindern:

Suche und ersetze durch:
allow_url_fopen = On

Ersetze durch:

allow_url_fopen = Off

Standardverzeichnisse ersetzen:

Erstelle ein neues temporäres Verzeichnis unter "XAMPP Verzeichnis\php". Der Verzeichnisname sollte nicht auf dessen Funktion (Temp) hindeuten.

Ich wähle hier: "work".

Suche und ersetze durch:
; session.save_path = "N;/path"

Ersetze durch:

session.save_path = "D:\xampp\php\work"

Upload Ordner ändern:
Erstelle ein neues Upload Verzeichnis unter "XAMPP Verzeichnis\php". Der Verzeichnisname sollte nicht auf dessen Funktion hindeuten.

Ich wähle hier: "input"

Suche und ersetze durch:
upload_tmp_dir = "

Ersetze durch:

upload_tmp_dir = "D:\xampp\input"

Dateigröße der Hochgeladenen Dateien begrenzen:
Hier kommt es jetzt wieder auf die Webanwendung an. Standardmäßig sind 2MegaBytes voreingestellt, wem das nicht reicht kann dies wie folgt ändern:

Suche und ersetze durch:
upload_max_filesize = 2M

Ersetze durch:

upload_max_filesize = 1024M

3. HTDOCS Ordner verschieben

Zum leichteren sichern und auch um evtl. Exploits vorzubeugen, sollte der htdocs Ordner nicht im XAMPP Hauptverzeichnis liegen. Daher verschiebe ich ihn mit dem Explorer auf Laufwerk E:\.

Stelle sicher, das nach dem Verschieben die Gruppe "Benutzer" Vollzugriff auf diesen Ordner erhält.

Damit der Apache nun auch den neuen Speicherort erfährt, müßen folgende Daten angepasst werden:

  • httpd.conf
  • httpd-ssl.conf
  • httpd-xampp.conf
Klicke dazu in dem XAMPP Control Panel in der Spalte für Apache auf "Konfig" und Editiert die o.g. Dateien.

3.1 httpd.conf und httpd-ssl.conf

Sucht nach "DocumentRoot" und ändert den Pfad.
Sucht nach "<Directory "D:/xampp/htdocs/">" und ändert den Pfad.

3.2 httpd-xampp.conf

Sucht nach "<Directory "D:/xampp/htdocs/xampp">" und ändert den Pfad.

3.3 HTDOCS Ordner aufräumen:

Folgende Dateien und Verzeichnisse werden nun nicht mehr benötigt und können entweder gelöscht, oder besser in ein Archiv gepackt und archiviert werden:

  • forbidden
  • restricted
  • xampp
  • apache_pb.gif
  • apache_pb.png
  • apache_pb2.gif
  • apache_pb2.png
  • apache_pb2_ani.gif
  • favicon.ico
  • index.php
  • index.html

4. Dienstekonfiguration

Öffne das XAMPP Control Panel und installiere den Apache und den MySQL Server als Dienst. Öffne dann die Dienstverwaltung und ändere die Dienste so ab, dass der zuvor erstellte Windows-Benutzeraccount zum Anmelden verwendet wird.

5. Kleinigkeiten

Webserver verschleiern:

Nicht jeder muss sofort wissen, das du einen Webserver betreibst. Wenn du z.B. nur mit Webanwendungen arbeitest, die in einem Unterverzeichnis ausgeführt werden, empfiehlt es sich im "root" Verzeichnis eine kleine index.html zu erstellen, welche z.B. direkt auf Google weiterleitet.

Hier der Quelltext:
<html>
<head>
<meta http-equiv="refresh" content="0; URL=http://www.google.de/">
</head>
</html>

Dies ist zwar nicht wirklich ein Schutz, da der Server ja noch auf Anfragen via Port 443 antwortet, aber so wird man schon so einige los, die die Server Adresse in die Finger bekommen haben und nun schauen wollen was sich dahinter verbirgt.

Durchsuchen des Servers von Suchmaschinen verhindern:

Wer wie ich nicht möchte, dass sein Server von Google und Co. durchsucht wird, muss dies mit der Datei "robots.txt" welche im "root" Verzeichnis des Webservers (htdocs) liegen muss anzeigen.

Diese Datei muss folgendes enthalten:

User-agent: *
Disallow: /

ACHTUNG! Achtet darauf, dass der Dateiname klein geschrieben ist.

---

Nun brauch ich eure Hilfe. Fehlt noch etwas? Habe ich irgendwo groben Unfug geschrieben? Gebt mir Input um das Guide nach und nach zu verbessern. Ich werde das Guide mit der Zeit noch etwas detaillierter ausformulieren und ggf. mit Bildern ergänzen.
 
Zuletzt bearbeitet:
Ist es nicht so, dass bei den Regeln am Ende immer die erste passende angewendet wird? Demzufolge würdest du so alles sperren und die "Deny from all" Regel muss ganz am Ende stehen.
 
Freezedevil schrieb:
Ist es nicht so, dass bei den Regeln am Ende immer die erste passende angewendet wird? Demzufolge würdest du so alles sperren und die "Deny from all" Regel muss ganz am Ende stehen.

Ok, geändert.
 
Freezedevil schrieb:
Ist es nicht so, dass bei den Regeln am Ende immer die erste passende angewendet wird? Demzufolge würdest du so alles sperren und die "Deny from all" Regel muss ganz am Ende stehen.

ich dachte das ist abhängig davon wie man es konfiguriert...also entweder "Order Deny, Allow" oder "Order Allow, Deny"
ich muss aber zugeben, dass mich das schon immer etwas verwirrt hat und fände es toll, wenn es jemanden gibt, der mich da mal aufklären kann

was man noch machen könnte, nachdem du ja eh schon einmal verschiedene verzeichnisse für programme und daten nutzt und dazu verschiedene konten, könnte man den zugriff der einzelnen nutzerkonten für laufwerke und ordner auf denen sie keinen zugriff brauchen, sperren

also zB das C:\ Laufwerk, beim apache-nutzer den ordner mit der datenbank, beim DB-User den apache-ordner, usw. und auch nur bei den verzeichnissen schreibrechte gewähren, die sie auch brauchen (also bei apache zB das Web-DAV verzeichniss)
 
d4nY schrieb:
was man noch machen könnte, nachdem du ja eh schon einmal verschiedene verzeichnisse für programme und daten nutzt und dazu verschiedene konten, könnte man den zugriff der einzelnen nutzerkonten für laufwerke und ordner auf denen sie keinen zugriff brauchen, sperren(...)

Das klingt gut. Ich formuliere mal was und baue es ein.
Ergänzung ()

So, ich habe das Guide nocheinmal Gründlich überarbeitet und alles was ich zum Thema PHP,MySQL und Apache Absicherung gefunden habe in den Thread eingefügt.

Auch die Ausführungen zum Thema Rechtevergabe ich ergänzt.

Bald werde ich mit noch mit den Apache Erweiterungen Suhosin und mod_security befassen.
Ergänzung ()

d4nY schrieb:
ich dachte das ist abhängig davon wie man es konfiguriert...also entweder "Order Deny, Allow" oder "Order Allow, Deny"
ich muss aber zugeben, dass mich das schon immer etwas verwirrt hat und fände es toll, wenn es jemanden gibt, der mich da mal aufklären kann

Apache ist es eigentlich egal, in welcher Reihenfolge man es angibt. Es verarbeitet beide Regeln egal ob via Order erst Allow und dann Deny vorgegeben wurde oder anders herum.

Um seinen Quellcode jedoch aufgeräumt zu halten empfehle ich mit "Allow, Deny" zu arbeiten und dann auch erst die Allow Regel und dann die Deny Regel einzufügen.

Beispiel:

Code:
Order Allow, Deny
Allow from 127.0.0.1
Deny from all
 
Zuletzt bearbeitet:
Hallo,

sind damit nun wirklich alle Lücken geschlossen und ich kann das System auch produktiv einsetzen?

CYA_D0c
 
Moin Moin,

das kann ich dir nicht mit Sicherheit sagen. Grundsätzlich würde ich mal nein sagen, denn eine Software hat immer Lücken die erst im laufe der Zeit erkannt werden.

Das Guide oben beschreibt etliche Dinge die man Absichern kann. Ich habe dafür so manche Seiten im Netz gelesen und das wichtige daraus hier zusammen gefasst. Ich bin jedoch kein PHP Programmierer oder Server Admin, daher kenne ich auch nicht alle Schalter und Funktionen aus dem FF. Aber da sich hier noch niemand mit dem Aufschrei "Grober Unfug" gemeldet hat kann es nicht so falsch sein, was ich da zusammengetragen habe.
 
Zurück
Oben