Sicherheit von Webservern - Einführung anhand praktischer Beispiele

Sicherheit von Webservern

Einführung anhand praktischer Beispiele

von Sean Rütschi
Lesezeit: 17 Minuten

Das World Wide Web ist bereits seit mehreren Jahrzehnten ein integraler Teil des Alltags von vielen Menschen. Dabei spielen Websites eine grosse Rolle, mit dem Aufschwung des Social Media umso mehr. Facebook, Twitter, Xing, Linkedin und alle anderen haben eines gemeinsam: Sie alle pflegen eine Website, über die sich täglich tausende von Menschen anmelden und ihren Beschäftigungen nachgehen.

Es ist daher kein Wunder, dass bei einem solchen Bekanntheitsgrad Sicherheitsmassnahmen, welche die User vor bösartigen Absichten schützen sollen, getroffen werden müssen. Doch nicht nur für solche grossen Seiten müssen Sicherheitsvorkehrungen getroffen werden, denn auch bereits schon kleine Websites können beispielsweise für die Verbreiter von Malware ein gefundenes Fressen sein, wenn diese nicht korrekt abgesichert sind.

Dabei fallen die häufigsten Sicherheitslücken auf Programmierfehler in den einzelnen Webapplikationen zurück. Eine übersichtliche Liste bietet die OWASP Top Ten Liste. Doch selbst bei einer hypothetisch angenommen fehlerlosen Webapplikation ist es möglich, dass eine Website für bösartige Absichten missbraucht werden kann, wenn der darunterliegende Webserver nicht korrekt konfiguriert wurde.

Ich werde in diesem Beispiel von einem Webserver ausgehen, auf dem Debian Linux in der Version Squeeze (6.0) installiert ist. Aus den Standardrepositories wird der Apache Webserver in der Version Apache/2.2.16 installiert, namentlich apache2. Dieses Paket stellt alle weiteren, für einen funktionierenden Webserver benötigte Pakete zur Verfügung. Ein weiteres, möglicherweise benötigtes Paket ist libapache-mod-security, welches ModSecurity, einer Web Application Firewall, in der Version 2.5.12 bereitstellt. Wichtig zu wissen ist jeweils, dass die Versionsnummer auf Debian Linux nicht angehoben wird, Sicherheitspatches aber jeweils rückwirkend eingespielt werden. Auf anderen Linuxdistributionen sind diese Pakete möglicherweise anders benannt und in anderen Versionen vorhanden.

Auf weitere Installationen wie PHP oder ähnliche Skriptsprachen werde ich hier nicht eingehen, da diese für eine grundlegende Webserverkonfiguration nur eine bedingte und sehr individuelle Rolle spielen.

Best Practices

Als Erstes möchte ich über einige Grundlagen eines guten Serverbetriebs gehen. Dazu gehört an erster Stelle ein vernünftiges Upgradekonzept. Upgrades sollten so schnell wie möglich eingespielt werden, nachdem sie, sofern nötig, vorher getestet wurden. Dabei ist es auch nötig, dass die Testumgebung eine exakte Kopie der Liveumgebung ist, um Fehler aufgrund unterschiedlicher Konfigurationen zu vermeiden.

Schon unzählige Angriffe wären erfolglos gewesen, wäre der darunterliegende Webserver auf dem neusten Stand gewesen!

Als Zweites gehört für mich die Verschlüsselung erwähnt. Wer eine Verschlüsselung anbietet, sollte entsprechend sicherstellen, dass ein gültiges SSL-Zertifikat verwendet wird, welches von allen gängigen Browsern als legitim anerkannt wird.

Besonders bei Webshops und anderen Websites, die Bezahlung über die Website annehmen, ist eine seriöse Verschlüsselung ein Muss.

Als Drittes möchte ich anmerken, dass versteckte Subversion- und Gitverzeichnisse in einem Rootverzeichnis eines Webservers nichts verloren haben. Ich habe bei einer routinemässigen Untersuchung eines Kundenservers einmal einen .svn-Ordner entdeckt, in dem ich gültige Benutzer und Passwörter für SSH- und Datenbankverbindungen vorfand. Solche Fehler können fatale Auswirkungen haben und sollten daher bei einem Deployment oder ähnlichem zwingend bedacht werden.

An sich müssten die oben erwähnte Dinge selbstverständlich sein. Doch manchmal denkt man in der alltäglichen Hektik nicht an alles und es unterlaufen einem Fehler. Aus diesem Grunde empfiehlt es sich, Checklisten anzulegen, die stets angepasst und erneuert werden, damit solche Fehler unterbunden werden können.

Eine Internetsuche fördert Unmengen solcher Best Practice Listen hervor. Wer noch keine solche einsetzt, sollte ernsthaft über deren Einsatz nachdenken.

Konfiguration

Kommen wir nun zur eigentliche Konfiguration des Webservers. In der Standardinstallation wird Apache in einer nicht konsistent sicheren Konfiguration ausgeliefert. Viele der Module, die in /etc/apache2/mods-enabled/ bereitgestellt werden, sind für Basisinstallationen gar nicht nötig. Ich empfehle, die hier geladenen Module genau unter die Lupe zu nehmen und dann jeweils individuell zu beurteilen, ob diese für die zu betreibende Websites benötigt werden. Jedes unnötige Modul sollte deaktiviert werden.

Debian Linux betreibt den Server automatisch als den eingeschränkten User www-data. Dies ist besonders wichtig, da bei einem geglückten Angriff der User root in den meisten Fällen nicht automatisch kompromittiert wird. Um sicherzugehen, dass auch bei einer solchen Kompromittierung die Website an sich so lange als möglich unangetastet bleibt, sollten die Dateien der Website einem weiteren User, also weder root noch www-data, gehören. Beachtet werden muss dabei, dass lediglich globale Leseberechtigungen benötigt werden, damit www-data die Dateien dann zur Verfügung stellen kann.

Nun zur eigentlichen Apachekonfiguration: Debian Linux beachtet für individuelle Konfigurationen den Ordner /etc/apache2/conf.d/. Ich empfehle, die Standardkonfiguration weitgehend unangetastet zu lassen und Änderungen hier einzutragen. Da Apache die Dateien nach alphabetischer Reihenfolge einliest, füge ich vor den Dateinamen jeweils ein zzz_ an, damit diese Dateien als letzte geladen werden und vorherige Konfigurationsparameter überschreiben.

Eine mögliche solche Datei könnte beispielsweise zzz_apache2.conf benannt werden und folgenden Inhalt aufweisen:

MaxClients 500
Timeout 30
TraceEnable Off
ServerSignature Off
ServerTokens Prod

Mit MaxClients werden die Anzahl gleichzeitig zugreifender Clients auf maximal 500 reduziert, alle darauf folgenden Zugriffe werden erst bei Zugriffsende eines vorherigen Clients nachträglich abgearbeitet. Diese Option sollte gemäss der gängigen Besucheranzahl gesetzt werden, um mögliche DoS-Angriffe abzuwehren. Ein zu gering gesetztes MaxClients vereinfacht DoS-Angriffe entsprechend, ein zu hoch gesetztes MaxClients kann den Server bei rechenintensiven Websites überladen.

Der Parameter Timeout definiert die maximal erlaubte Zeit

und sollte auf einen individuell ermittelten Wert gesetzt werden. Die von Apache standardmässig vorgegebene Zeit liegt bei 300 Sekunden. In den meisten Fällen kann diese problemlos gesenkt werden.

TraceEnable Off verbietet TRACE Requests. Diese sind für einen sicheren Betrieb eines Webserver unnötig und sollten deaktiviert werden.

ServerSignature Off und ServerTokens Prod stellen sicher, dass in den HTTP-Headern jeweils nur Apache ohne jeglichen Zusatz von Versionsnummer oder ähnlichen verschickt wird. Sollte sogar dies unerwünscht sein, lässt sich mithilfe von ModSecurity der Header verfälschen. Hierfür muss allerdings folgender Eintrag gemacht werden:

ServerTokens Full
SecServerSignature "Apache/2.2.0 (Fedora)"

Apache/2.2.0 (Fedora) ist der von ModSecurity standardmässig gesetzte Wert, der problemlos auf jeden beliebigen Wert geändert werden kann. Weitere mögliche Anpassungen können in den ModSecurity Core Rules gefunden werden.

Webserver Mitschnitt ohne Anpassungen

Auf dem vorangehenden Bild wird ersichtlich, dass die ServerSignature bereits auf Off und die ServerTokens auf Prod gesetzt wurden. Dies erschwert es Angreifern grundsätzlich, die genaue Versionsnummer des Webservers zu eruieren.

Allerdings gibt es einige weiteren HTTP-Header, die eingesetzt werden können und von denen viele Webserveradministratoren keine Kenntniss haben. Dies rührt daher, dass sie meistens explizit in Hardening-Guides erwähnt werden und nicht in Standardinstallationen und -Guides enthalten sind.

Diese Header können wie folgt in einer Konfigurationsdatei eingefügt werden:

Header set X-Content-Type-Options nosniff
Header set X-Frame-Options deny
Header set X-XSS-Protection "1; mode=block"

Nach der Konfigurationsanpassung sehen die mitgelieferten Header bereits etwas anders aus:

Webserver Mitschnitt mit angepasstem Header

Wie dem vorangehenden Bild zu erkennen ist, werden die neu hinzugefügten Header aufgeführt. Ausserdem wurde der Serverheader auf Microsoft-IIS/5.0 gesetzt. Die Header X-Content-Type-Options, X-Frame-Options und X-XSS-Protection werden ausgeliefert.

Wer eine komplette Auflistung aller möglichen HTTP Header möchte, kann diese auf Wikipedia genauer betrachten.

Zu guter Letzt möchte ich ein Thema ansprechen, welches viele Webserveradministratoren, aber auch viele Webentwickler ignorieren, vergessen und nicht genügend kennen. Die Rede ist von Cookies sowie deren Konfiguration auf einem Webserver.

Cookies werden hauptsächlich dafür eingesetzt, Sessionvariablen zu verwalten, wenn sich Benutzer auf einer Website einloggen. Das Problem ist, dass Cookies auf den PCs der Benutzer und nicht auf den Servern abgelegt werden. Dies ist aus Performancegründen sinnvoll, da der Server dann weniger belastet wird, hat aber aus Sicht der Sicherheit einen gravierenden Nachteil: Der Webserveradministrator kann schliesslich nur in den wenigsten Fällen die Schutzmassnahmen auf einem Benutzer-PC definieren. Wenn dieser das Ausführen von Scripts erlaubt, kann auf die Cookies zugegriffen werden.

Ein durch Cross Site Scripting gestohlenes Cookie kann aber möglicherweise vom Webserveradministrator verhindert werden. Dies bedingt lediglich das Setzen eines einzelnen Parameters:

Header edit Set-Cookie ^(.*)$ $1;HttpOnly

Damit wird, sofern es der eingesetzte Browser unterstützt, das Cookie mit HttpOnly generiert, wodurch es nicht von Scripts gelesen werden kann.

Es gibt eine weitere Option, die sicherstellt, dass der Inhalt von Cookies nur über eine verschlüsselte Verbindung ausgelesen werden kann. Dieser Parameter kann folgendermassen gesetzt werden:

Header edit Set-Cookie ^(.*)$ $1;Secure;HttpOnly

Damit kann der Inhalt eines Cookies nicht mehr über eine gewöhnliche HTTP-Verbindung ausgelesen werden und forciert somit den Einsatz von SSL beziehungsweise TLS.

Natürlich sind diese Optionen nach wie vor von der Sicherheitseinstellung der jeweiligen Benutzer abhängig. Denn wenn die Benutzer durch fahrlässiges Verhalten ihre Benutzerkonten zur Verfügung stellen, kann auch der beste Webserveradministrator nicht weiterhelfen.

Denn damit haben wir den grössten Teil der Grundkonfiguration des Webservers erledigt. Was nun folgt, sind weitere Elemente, die beachtet werden sollten. Dazu gehören die Themen Logs und Backups.

Logs

Logs spielen eine zentrale Rolle bei der Mitigierung von Angriffen, denn ohne sie wüssten wir oft nicht, dass Angriffe respektive deren Versuche überhaupt stattgefunden haben. Aus diesem Grund sollte ein Webserver seine Logs stets auch an einen zusätzlichen Logserver senden, damit diese im Falle eines gelungenen Angriffs zur Rekonstruierung des Vorgehens der Angreifer beitragen können. Die Logs einer Standardinstallation liegen unter Debian Linux im Verzeichnis /var/log/apache2/.

Ausserdem sollte automatisiert nach unerwünschten Zugriffen gescannt werden, um Möchtegernangreifer bereits aussperren zu können, bevor sie nennenswerten Schaden anzurichten in der Lage sind.

Auszüge eines Angriff mittels Brute-Force könnten beispielsweise so aussehen:

[Tue Apr 17 16:56:47 2012] [error] [client X.X.X.X] client denied by server configuration: /var/www/admin/ 
[Tue Apr 17 16:56:47 2012] [error] [client X.X.X.X] client denied by server configuration: /var/www/admin/ 
[Tue Apr 17 16:56:47 2012] [error] [client X.X.X.X] client denied by server configuration: /var/www/admin/ 
[Tue Apr 17 16:56:47 2012] [error] [client X.X.X.X] client denied by server configuration: /var/www/admin/ 
[Tue Apr 17 16:56:47 2012] [error] [client X.X.X.X] client denied by server configuration: /var/www/admin/ 
[Tue Apr 17 16:56:48 2012] [error] [client X.X.X.X] client denied by server configuration: /var/www/admin/ 
[Tue Apr 17 16:56:48 2012] [error] [client X.X.X.X] client denied by server configuration: /var/www/admin/ 
[Tue Apr 17 16:56:48 2012] [error] [client X.X.X.X] client denied by server configuration: /var/www/admin/ 
[Tue Apr 17 16:56:48 2012] [error] [client X.X.X.X] client denied by server configuration: /var/www/admin/ 
[Tue Apr 17 16:56:48 2012] [error] [client X.X.X.X] client denied by server configuration: /var/www/admin/

Mehrere Zugriffe pro Sekunde deuten auf einen automatischen Zugriff mittels eines Bots hin. Natürlich könnten diese Logeinträge auch von einem legitimen Fehlverhalten eines Benutzers stammen, doch ich gehe in solchen Fällen lieber auf Nummer sicher.

Die Aufgabe des automatisierten Aussperrens lässt sich mit Cronjobs jeweils leicht lösen. Hilfreich ist es dabei jeweils, wie bereits bei den Systemupgrades eine E-Mail verschicken zu lassen, wenn beispielsweise eine IP geblockt wurde. In diesem Beispiel könnte ein entsprechendes Skript in etwa so aussehen:

#!/bin/bash 
#alle ips, die einen 403 er generieren, blockieren

HOSTDENY=$(grep ‘client denied by server configuration:’ /var/log/apache2/error.log /var/log/apache2/error.log.1 | awk ‘{print $8}’ | uniq | sed ‘s/\]//’

for host in $HOSTDENY; do ATTACKS=$(grep $host /var/log/apache2/error.log | wc -l) if [ $ATTACKS -gt 10 ]; then HOSTEXISTS=$(grep $host /etc/hosts.deny) if [ -z “$HOSTEXISTS” ]; then echo “Blocked IP $host” | mailx -s “ipblocker for $(hostname)” noreply@email.ch echo “ALL: $host” >> /etc/hosts.deny fi fi done

exit 0

Alle Szenarien abzudecken ist sicherlich nicht einfach, doch mit entsprechender Erfahrung kann für jede Umgebung ein entsprechender Logsucher geschrieben werden, der automatisch nach Diskrepanzen in den Logs sucht und die Übeltäter aussperrt. Wird die Mühe auf sich genommen, diese Überprüfungen zu automatisieren, wird man mit schnelleren Reaktionszeiten im Ernstfall sowie eine vereinfachte Statistikerstellung belohnt.

Backups

Ein weiteres Thema sind Backups und deren korrekte Durchführung respektive Aufbewahrung. Dass dies noch nicht überall wie wünschenswert durchgeführt wird, zeigte sich erst kürzlich beim Hack der Firma RedSky, als diese ihre gesamte Website inklusive aller Backups verlor.

Grundsätzlich haben Backups von Websites auf dem Server, auf dem sie betrieben werden, nichts verloren. Ausser einigen wenigen Snapshots, die man für rasche Wiederherstellungen verwenden kann, sollte stets eine dedizierte Backupmaschine bereitstehen, die solche Aufgaben übernimmt.

Auch Backups können, wie bereits die Logauswertung, automatisiert vorgenommen werden. Unter eine reinen Linuxumgebung werden Backups häufig mit rsync realisiert. Dazu benötigt der Webserver lediglich einen laufenden SSH-Dienst, doch auch dieser muss entsprechend konfiguriert werden. Um ein gesamtes System zu backupen, muss der Prozess mit dem User root gestartet werden.

Dies muss natürlich entsprechend abgesichert werden, da ein für root automatisiert geöffnetes Tor eine Möglichkeit zum Missbrauch bietet. Aus diesem Grund muss in /etc/ssh/sshd_config der PermitRootLogin-Parameter folgendermassen gesetzt werden:

PermitRootLogin forced-commands-only

Damit kann der User root über SSH nur noch vordefinierte Befehle ausführen. In der Datei /root/.ssh/authorized_keys wird nun folgendes eingetragen:

from="10.0.1.2",command="rsync --server --sender -vlHogDtpre.iLsf --numeric-ids . /",no-pty,no-agent-forwarding,no-port-forwarding,no-user-rc,no-X11-forwarding ssh-rsa AAAA... root@backupserver

Dies erlaubt dem User root, nunmehr nur noch einen bestimmten rsync auszuführen. Dieser kann in einem Skript, beispielsweise unter /usr/local/sbin/ abgelegt, wie folgt festgelegt werden:

#!/bin/bash 

SERVERS=“10.0.0.1 10.0.0.2”

for i in $SERVERS; do status=“1” until [ “$status” == “0” ]; do rsync -avH —numeric-ids —exclude=/dev/* —exclude=/proc/* —exclude=/sys/* —exclude=/tmp/* $i:/ /backups/$i/$(date ‘+%Y-%m-%d_-_%H-%M-%S’) status=$? done done

exit 0

Somit können alle in der Variable SERVERS eingetragenen Server in den Backupprozess eingetragen werden. Das Skript selber muss lediglich als Cronjob hinterlegt werden, um regelmässige Backups anzulegen.

Schlusswort

Einen Apache Webserver abzusichern benötigt einige Schritte, die für viele auf den ersten Blick nicht offensichtlich erscheinen. Dies liegt häufig auch daran, dass häufig Kenntnisse benötigt werden, die erst nach längerem Suchen gefunden werden können. Ich hoffe, dass ich auf einige allgemein gültige Punkte hinweisen konnte, die übersehen oder missachtet wurden, und aufzeigen, weshalb diese Punkte beachtet werden sollten.

Über den Autor

Sean Rütschi interessiert sich seit 2008 für den Bereich der Informationssicherheit. Seine Schwerpunkte liegen bei OS-Hardening, wobei er sich auf Linux spezialisiert hat.

Links

Werden auch Ihre Daten im Darknet gehandelt?

Wir führen gerne für Sie ein Monitoring des Digitalen Untergrunds durch!

×
Dynamische Analyse von Android Apps

Dynamische Analyse von Android Apps

Ralph Meier

Security Testing

Security Testing

Tomaso Vasella

Active Directory-Zertifikatsdienste

Active Directory-Zertifikatsdienste

Eric Maurer

Fremde Workloadidentitäten

Fremde Workloadidentitäten

Marius Elmiger

Sie wollen mehr?

Weitere Artikel im Archiv

Sie brauchen Unterstützung bei einem solchen Projekt?

Unsere Spezialisten kontaktieren Sie gern!

Sie wollen mehr?

Weitere Artikel im Archiv