NEWS:




Info-Blog

Ein Leben für das World Wide Web
Archiv

Sinopia Docker Image

Ich habe gerade auf Docker-Hub ein Image für den NPM Caching Proxy Sinopia veröffentlicht. Das Tool ist dazu gedacht, dass man Builds, bei denen viele NPM-Pakete benötigt werden, etwas beschleunigen kann, indem man multiple Downloads dieser Pakete vermeidet.

Um das Image zu nutzen, zieht man es sich zuerst auf seinen Rechner:

docker pull bitmuncher/sinopia

Im nächsten Schritt startet man es natürlich. Hierbei wird der Port 4873, der von Sinopia als HTTP-Port verwendet wird, an das Host-System freigegeben.

docker run --name sinopia -d -p 4873:4873 bitmuncher/sinopia

Um den Proxy mit NPM zu nutzen, muss man seine Registry entsprechend umstellen:

npm set registry http://localhost:4873

Abschliessend muss man noch einen Nutzer auf dem Proxy anlegen:

npm adduser --registry http://localhost:4873

Eigene NPM-Pakete kann man mittels 'npm publish' auf dem Proxy ablegen, so dass auch diese von ihm ausgeliefert werden.

Will man wissen, welche Pakete sich im Cache befinden, reicht ein Blick in den Storage-Bereich des Proxies.

docker exec sinopia ls /home/sinopia/storage

Das Image basiert auf meinem Debian-Basis-Image, das ich mittels debootstrap erstellt habe.

Kommentare (0) - Kommentar schreiben

Software-Optimierung bei Webapplikationen

Immer wieder hatte ich in der Vergangenheit mit Unternehmen zu tun, die für vergleichsweise kleine Webapplikationen recht große Server-Netzwerke betrieben. Bei genauerem Hinsehen stellt man in solchen Unternehmen schnell fest, dass die Ursache für diese überbordende Netzwerk-Größe zumeist fehlerhafte oder fehlende Software-Optimierung war. Ich möchte an dieser Stelle auf die 2 häufigsten Probleme bei der Software-Optimierung eingehen.

Die Zeit-Komplexität

Wenn eine Software im Laufe der Zeit immer langsamer wird, ist dies ein Anzeichen dafür, dass hier etwas mit der Zeit-Komplexität nicht stimmt. Das bedeutet, dass sie immer mehr Anweisungen ausführen muss, weil die Datenbasis wächst, mit der sie arbeitet.

Schauen wir uns dazu ein einfaches Beispiel an. Gegeben sei folgende Tabelle in einer Datenbank...

+---------+-----------+
| data    | directive |
+---------+-----------+
| foobar1 | header    |
+---------+-----------+
| foobar2 | header1   |
+---------+-----------+
| foobar3 | header2   |
+---------+-----------+
| foobar4 | header3   |
+---------+-----------+
| foobar5 | header4   |
+---------+-----------+

... sowie folgende SQL-Anweisung:

UPDATE data SET data='foobar' WHERE directive='header'

Wie hier zu sehen ist, wird eine Update-Anweisung auf genau einen Datensatz ausgeführt. Wir haben also eine Zeitkomplexität von 1. Egal welche Daten für $newdata eingesetzt werden, die Anweisung manipuliert immer genau einen Datensatz, wird also genau ein Mal ausgeführt.

Etwas anders sieht es aus, wenn wir die Anweisung geringfügig ändern:

UPDATE data SET data='foobar' WHERE directive='header%'

Den Unterschied macht hier lediglich ein einzelnes Zeichen aus. Dennoch steigt damit die Zeitkomplexität und zwar in dem Maß, in dem Datensätze hinzukommen, die in der Spalte 'directive' Daten ablegen, die mit dem String 'header' beginnen. Bleiben wir also bei unserer Beispiel-Tabelle, werden 5 Datensätze geändert anstatt einem. Fügen wir einen weiteren Datensatz hinzu mit directive='header5', werden 6 Datensätze geändert. Die Zeitkomplexität steigt also linear an.

Problematisch werden solche Situationen immer dann, wenn Manipulationen von Daten auftreten, die ständigem Wachstum unterliegen. Mit jedem Datensatz der hinzukommt, muss eine weitere Anweisung ausgeführt werden, selbst wenn im Code nur eine einzelne Anweisung steht. Es ist daher wichtig im Auge zu behalten auf wie viele Datensätze eine Anweisung im Code angewendet wird.

Doch nicht nur bei Datenbank-Abfragen spielt das eine Rolle, sondern auch bei Programm-Code. Dort stellen vor allem Schleifen ein Risiko für eine wachsende Zeit-Komplexität dar. Nehmen wir uns auch dazu 2 Beispiele:

for($i=0; i<=10; i++) {
	print $foobar[$i];
}

Hier wird die Schleife immer genau 10 Mal durchlaufen. Die Zeit-Komplexität dieses Codes steigt also nicht, unabhängig davon wie viele Elemente im Array $foobar vorhanden sind. Lassen wir den Code jedoch komplett über ein Array iterieren, steigt seine Ausführungszeit mit jedem Element, das zum Array hinzu kommt.

for($i=0; $i<=count($foobar); $i++) {
	print $foobar[$i];
}

Hat unser Array $foobar 10 Elemente, wird es (so wie der erste Code) genau 10 Mal ausgeführt. Doch mit jedem Element, das wir dem Array hinzufügen, wird eine weitere print()-Anweisung ausgelöst. Mit steigender Anzahl an Array-Elementen steigt somit auch die Ausführungszeit des Codes.

Die Speicherplatz-Komplexität

Der letzte Code offenbart ein weiteres Problem. Bei ihm steigt nämlich auch die Speicherplatz-Komplexität mit jedem Element, das dem Array hinzugefügt wird. Das bedeutet, dass der Speicherverbrauch der Anwendung wächst, wenn neue Elemente zum Array hinzu kommen. Das wäre theoretisch im Falle des erstes Codes auch der Fall, allerdings machen dort mehr als 11 Elemente im Array eh keinen Sinn, weil mehr nicht verarbeitet würde. Daher kann man dort davon ausgehen, dass der Entwickler auch nicht mehr als diese Anzahl an Elementen in's Array packt. Ein solcher Speicherplatz-Zuwachs ist im Falle eines solchen Arrays natürlich recht offensichtlich. Doch gibt es auch Fälle, wo das weniger offensichtlich ist.

Ein typisches Beispiel aus dem Bereich der Webapplikationen

Ein Beispiel, wo das weniger offensichtlich ist, sind Sessions in einem Webserver. Legt eine Webapplikation für jeden User, der die Webapplikation nutzt, eine Session an, steigt der Speicherverbrauch des Webservers mit jedem User. Nun legen die meisten Webserver ihre Sessions auf der Festplatte ab und greifen nur darauf zu, wenn die entsprechenden Daten angefragt werden. Festplattenplatz ist hingegen heutzutage kaum noch ein Engpass bei Webservern und stellt somit kein Problem dar. Problematisch wird das aber, wenn man die Sessions für einen schnelleren Zugriff im RAM hält oder in einem Memcaching-System ablegt. Dann wird die steigende Speicherplatz-Komplexität schnell zu einem Problem.

Werden Session-Daten vom Webserver hingegen auf einer Festplatte abgelegt, steigt wiederum die Zeit-Komplexität, denn mit den Session-Zugriffen steigen die Festplattenzugriffe. Der Plattendurchsatz wird dann schnell zum Bottleneck. In solchen Situationen entscheiden sich Manager dann gern für die vermeintlich einfache Lösung die Sessions in den RAM zu verlegen, weil sie dort schneller abgerufen werden können. Das führt dann aber dazu, dass der RAM der Webserver bald nicht mehr ausreicht und das Auslagern von Speicherseiten in Swap-Spaces zum Problem wird. Die vermeintliche Problemlösung produziert also nur ein weiteres Problem. Die tatsächliche Lösung liegt darin die Daten dem Client/Webbrowser zu übergeben, zum Beispiel in Form eines Cookies. Diese Cookie-Daten kann sich eine Webapplikation einfach abrufen, wenn sie diese braucht. Die Server-Ressourcen werden dadurch geschont. Mit entsprechender Komprimierung des Cookies werden nicht einmal die Netzwerk-Ressourcen über Gebühr belastet.

Zusammenfassung

Abschliessend kann man daher nur feststellen, dass die Optimierung von Code eine sinnvolle Sache ist. Spätestens in der Qualitätssicherung sollte bereits von Anfang an geprüft werden, ob eine Zunahme an Funktionsaufrufen durch wachsende Datensätze auftreten kann und ob der Speicherverbrauch wächst, wenn neue Daten hinzukommen. Wird Code gefunden, bei dem das auftreten kann, sollte er zur Überarbeitung an den Entwickler zurückgegeben werden. Es macht wenig Sinn abzuwarten bis Probleme auftreten und sie erst dann anzugehen. Die Suche nach Bottlenecks ist erfahrungsgemäss wesentlich aufwendiger als eine Optimierung von Anfang an. Ausserdem spart eine gute Optimierung auch jede Menge Serverkosten. Ich habe bereits Webapplikationen erlebt, die mehr als 1 Million Anfragen am Tag locker auf einem einzelnen Webserver schluckten. Ich kenne aber auch Webapplikationen die nicht in der Lage waren mehr als 3 Anfragen pro Sekunde auf einem Webserver abzuarbeiten. Der Unterschied lag dort lediglich in der Optimierung der Webapplikation.

Kommentare (0) - Kommentar schreiben

Webapplikationen und Caching

Will man für eine Webplattform maximale Redundanz erreichen und möglichst geringe Serverkosten haben, ist Caching das A und O. Damit das Caching korrekt funktioniert, gilt es einiges zu beachten.

Session-Daten

Einer der häufigsten Fehler, dem ich im Bereich der Webapplikationen immer wieder finde, ist die Nutzung der Session-Daten. Gemeint sind damit die Sessions, die direkt vom Webserver kommen bzw. in diesem implementiert sind. In PHP nutzt man sie z.B. mit der globalen Variable $_SESSION. Andere Programmiersprachen stellen ähnliche Möglichkeiten zur Verfügung.

Session-Daten haben den Nachteil, dass sie bei fast allen Caching-Servern dafür sorgen, dass die mit solchen Daten verbundenen Inhalte nicht im Cache landen. Lässt man mit Session-Daten verbundene Inhalte dennoch im Cache ablegen, bekommt man einen Cache, in dem jeder User seine eigenen Seiten im Cache hat, was diesen natürlich enorm schnell füllt. Gerade auf hoch frequentierten Plattformen führt dies schnell dazu, dass der Arbeitsspeicher der Caching-Server voll wird. Es ist daher nicht ratsam für jeden Request an eine Webapplikation gleich eine Session zu öffnen. Sessions sollten erst verwendet werden, wenn ein User mit einer Plattform direkt interagiert (sich einloggt o.ä.), nicht schon dann, wenn er nur liest.

Cookies

Ähnliche Auswirkungen wie Sessions haben Cookies. Auch hier sorgen viele Webcaches dafür, dass Daten, die mit Cookies verbunden sind, nicht im Cache landen. Nun sind aber Cookies für Webapplikationen zumeist essentiell, allein schon für Tracking und ähnliche Mechanismen. Doch schon aus Sicherheitsgründen sollten Cookies prinzipiell SSL-verschlüsselt übertragen werden. Um dennoch ein Caching zu ermöglichen, sollten SSL-verschlüsselte Inhalte immer von einer anderen Domain bzw. Subdomain (Third Level Domain) kommen als die restlichen Inhalte. Kommen z.B. die hauptsächlichen Inhalte von www.domain.tld, sollten verschlüsselte Inhalte von secure.domain.tld kommen. Auf diese Weise können die Inhalte, die über www.domain.tld kommen, weiterhin in einen Cache gezogen werden.

SSL / HTTPS

SSL-Verschlüsselung ist gut dazu geeignet Caching zu verhindern. Nun leben wir allerdings in einer Welt, in der Monopolisten wie Google die Vorgaben machen. Und so müssen unsinnigerweise auch Inhalte verschlüsselt werden, wenn diese gar keine sicherheitsrelevanten Informationen übertragen. Sonst leidet nämlich das Google-Ranking. Doch auch dafür gibt es einen Workaround. Man leitet einfach alle Anfragen von Google-Bots auf die verschlüsselten Inhalte um, liefert dem User aber den Content weiterhin unverschlüsselt aus. Lediglich sicherheitsrelevante Bereiche einer Seite (Login, Übertragung von Session-Daten und Cookies etc.) verschlüsselt man mittels SSL. So ist die Suchmaschine zufrieden und man hält sich ein paar mehr Optionen für's Caching frei.

Die Alternative dazu besteht darin die SSL-Terminierung auf dem Caching-System oder dem vorgeschalteten Loadbalancer durchzuführen. Das ist aber eine wesentlich kostenintensivere Lösung, da entweder entsprechend ausgestattete Loadbalancer oder mit besserer Hardware versehene Caching-Server notwendig sind. Vor allem für Startups, deren Erfolg noch ungewiss ist, lohnt es sich erfahrungsgemäß eher, etwas mehr Zeit in die Planung der Webapp zu investieren und diese so aufzubauen, dass sie auch mit unterschiedlichen Caching-Layern umgehen kann. Wer aber die Möglichkeit hat, sollte die SSL-Terminierung erst am Ende der Request-Kette durchführen.

Memcaching

Unabhängig vom Webcache ist auch die Nutzung von Memcaching anzuraten. Memcache-Server geben die Möglichkeit einzelne Elemente einer Website im RAM anzulegen, wo sie enorm schnell abrufbar sind. Dadurch können Webserver und Datenbanken massiv entlastet werden. Mit dem richtigen Memcaching-Konzept können selbst mehrere tausend User gleichzeitig bedient werden, ohne dass auf den Webservern eine spürbare Last entsteht, da diese nur Daten aus dem Memcache holen und direkt ausliefern ohne großartige Berechnungen durchführen zu müssen.

Datenbank-Cache

Die meisten Datenbank-Systeme unterstützen verschiedene Formen von Caches. Ich will an dieser Stelle aber nicht auf die internen Caches von Datenbank-Systemen eingehen sondern auf die Möglichkeit Caches vor die Datenbank zu schalten. So ist es z.B. möglich mittels MySQL-Proxy gleichzeitig einen Memcache zu befüllen. Der MySQL-Proxy-Server kann dann die Daten aus dem Cache holen anstatt sie von der Datenbank abzufragen, wodurch die Datenbank-Server massiv entlastet werden. Somit können die Datenbank-Server mit entsprechend kleinerer Hardware auskommen. Ausserdem bietet Memcache einen schnelleren Datenzugriff, so dass DB-Anfragen dadurch auch noch schneller bearbeitet werden können. Dies kommt logischerweise der Performance der Webapplikation zugute.

Caching-Server zur Redundanz

Vor allem Seiten, die viele Inhalte mit wenig Benutzer-Interaktion ausliefern, können ihren Caching-Layer auch zur Verbesserung der Redundanz ihrer Webapplikation nutzen. Ein klassisches Beispiel dafür sind Nachrichtenseiten, Blogs oder auch einfache Websites von Unternehmen. Werden Inhalte grossteils über den Caching-Layer ausgeliefert, können die Webserver dahinter problemlos für eine Weile vom Netz getrennt werden (z.B. für Wartungsarbeiten), ohne dass die Auslieferung dadurch negativ beeinflusst wird. Lediglich die Benutzer-Interaktion wird eingeschränkt. Echte Downtimes, in denen die gesamte Plattform nicht erreichbar ist, werden verhindert.

Caching-Server zur Performance-Steigerung

Da die meisten Caching-Systeme ihre Daten im Arbeitsspeicher halten, können sie enorm zur Steigerung der Performance beitragen. Es ist ja kein Geheimnis, dass Daten aus einem Arbeitsspeicher schneller ausgelesen werden können als von der Festplatte. Hinzu kommt, dass Caching-Server die Daten auch noch so strukturieren, dass sie möglichst schnell durchsuchbar sind. Hierfür werden z.B. Checksummen von Objekten, Assoziationen mit URLs usw. vorgenommen. Ein zeitaufwendiges Zusammensammeln der Daten (z.B. aus verschiedenen Tabellen) entfällt damit. Die Webapplikation oder der anfragende Client/Browser kann direkt mit den Daten beliefert werden. Selbst die Verarbeitung von Skript-Code kann auf ein Minimum beschränkt werden, so lange sich die Inhalte mehr oder weniger statisch darstellen.

Aus technischer Sicht muss aber zwingend darauf geachtet werden, dass Caching-Server niemals mit Auslagerungsspeicher (Swap) ausgestattet werden dürfen. Sonst läuft man Gefahr, dass bei einem vollen Arbeitsspeicher der Auslagerungsspeicher verwendet wird. Und der wiederum ist wesentlich langsamer als jedes andere System. Auslagerungsspeicher sind für Caching-Systeme ein No-Go.

Was gilt es zu beachten?

Plant man eine Webapplikation, sollte man die Verhaltensweisen von Caching-Layern in die Planung einbeziehen. Der einmalige Entwicklungsaufwand mag dadurch zwar etwas steigen, die dabei entstehenden Kosten spart man aber schnell wieder ein, weil man weniger Hardware für das Hosting benötigt. Das gilt ganz besonders für Webapplikationen, die in erster Linie Inhalte ausliefern und wo Nutzer-Interaktionen wie Kommentare an externe Dienste ausgelagert werden. Aber auch für Webapplikationen, auf denen nicht jeder Nutzer auch gleich Interaktionen ausführt (z.B. Shop-Systeme, Blogs, Nachrichtenportale etc.) kann ein gutes Caching viel ausmachen.

Bei der Planung sollte man immer darauf achten, Session-Daten wo immer möglich zu vermeiden. Erst wenn ein Benutzer sich einloggt, d.h. mit der Plattform in Interaktion tritt, sollten Session-Daten genutzt werden. Meine Erfahrung zeigt, dass dies oft nur einen Bruchteil der auf einer Plattform stattfindenden Requests betrifft. Gleiches gilt für Cookies.

Benutzt man keine externen Tracking-Dienste, sollte man Cookies, die man für's Tracking verwendet, durch eine extra Applikation ausliefern lassen. So behält man sich die Möglichkeit den eigentlichen Content optimal zu cachen. Das Tracking hat in der eigentlichen Webapplikation nichts zu suchen. Es sollte immer eine eigene Webapp bilden.

Auch statische Inhalte wie Bilder, Javascript-Dateien oder Videos sollten im Optimalfall über eigene Subdomains (static.domain.tld o.ä.) ausgeliefert werden. Dies gibt einem vorgeschalteten Caching-Layer die Möglichkeit alle statischen Inhalte zu cachen. Da solche statischen Elemente möglicherweise auch auf vielen Seiten verwendet werden (beispielsweise die Bilder von Templates), kann der Cache-Inhalt dadurch recht klein gehalten werden. Schliesslich müssen diese Elemente dann nur ein Mal im Cache landen und können von dort für alle Requests verwendet werden.

Da die Verwendung von HTTPS heutzutage kaum vermieden werden kann und aus Sicherheitsgründen auch nicht vermieden werden sollte, empfiehlt es sich die SSL-Terminierung erst am Ende der Server-Kette stattfinden zu lassen. Das heisst, dass die SSL-Terminierung erst auf dem Loadbalancer stattfinden sollte. Der Loadbalancer sollte immer mit den Caching-Systemen verbunden sein, nicht mit den Webservern. Ist dies nicht möglich, sollte man zu den oben genannten Workarounds greifen.

Ein weiterer wichtiger Punkt ist die Strukturierung einer Webapplikation. Glücklicherweise (aus Sicht der Systemadministratoren und Entwickler) setzen sich sogenannte Microservices mehr und mehr durch. Wird eine Webapplikation in solche Microservices aufgeteilt, ergeben sich neben mehr Flexibilität bei der Entwicklung auch neue Möglichkeiten für's Caching. Das geschieht schlicht und einfach dadurch, dass jeder Microservice mit einem eigenen Caching-Layer versehen werden kann. Jeder Microservice kann dabei selbst bestimmen, wann sein Cache resettet wird, wodurch das langwierige "Vorheizen" riesiger Caches unnötig wird. Ausserdem kann das Caching dann individuell an die vom Service ausgelieferten Daten angepasst werden.

Wie bereits erwähnt haben Auslagerungsspeicher auf Caching-Systemen nichts zu suchen. Sie bremsen das System nur unnötig aus und widersprechen allen Bedingungen, die man für ein gutes Caching benötigt.

Und zu guter Letzt ist es auch empfehlenswert für Spider/Bots von Suchmaschinen eigene Systeme bereitzustellen. Zum einen werden durch die zum Teil recht vielen Anfragen solcher Bots die Server, mit denen die echten Nutzer interagieren, nicht unnötig ausgebremst. Zum anderen bietet diese Aufteilung die Möglichkeit den Suchmaschinen eine weitaus kleinere Webapplikation anzubieten, die tatsächlich nur die zu indizierenden Inhalte enthält, nicht aber die Elemente, die zur Benutzer-Interaktion notwendig sind. Das minimiert einerseits die Möglichkeiten zum sogenannten Google-Hacking, zum anderen aber auch die Rechenlast, die durch Bot-Anfragen entsteht.

Fazit

Wie wir sehen können, kann Caching einen wesentlichen Beitrag dazu leisten Server zu entlasten und Redundanz herzustellen. Gerade wenn man Continious Delivery einsetzt, können Caching-Layer auch verwendet werden um Ausfälle/Aussetzer, die durch den Restart von Diensten entstehen können, zu kompensieren, denn der Cache kann einfach nach dem Deployment resettet werden. Weiterhin kann die Performance einer Webapplikation enorm gesteigert werden, wenn das Caching ordentlich konzeptioniert und implementiert wurde.

Kommentare (0) - Kommentar schreiben

Server-Sicherheit - so geht's

Beschränken sich Ihre Systemadministratoren beim Schutz Ihrer Server auch nur auf System-Updates, Firewall und Benutzerverwaltung? Meiner Erfahrung nach ist dies in den meisten Unternehmen der Fall, die im WWW tätig sind. Dort, wo Serversicherheit „gross geschrieben“ wird, ist zumeist noch eine WAF (Web Application Firewall) vorgeschaltet oder in die Webserver integriert. Meine Erfahrung ist allerdings auch, dass dies nicht reicht. In diesem Artikel werde ich Sicherheitsmechanismen betrachten, wie sie angesichts heutiger Angriffsszenarien im WWW notwendig sind.

System-Updates

Natürlich sind System-Updates der kritischste Punkt, wenn es um die Sicherheit der Server geht. Schliesslich werden darüber die Sicherheitslücken gestopft, die bereits bekannt geworden sind. Somit sind sie essentiell für die Sicherheit von Servern. Doch ist es ein Irrglauben, dass ein Server sicher ist, wenn er sich auf einem aktuellen Update-Stand befindet. Ich war selbst jahrelang in der Hacker-Szene aktiv und habe noch immer Einblick in einige Bereiche, die im IT-Volksmund als „Underground“ bezeichnet werden. Wer sich mal in privaten Newsgroups umschaut oder privat betriebene Bulletin-Boards mitlesen kann, der wird schnell feststellen, dass keineswegs alle bekannten Sicherheitslücken auch sofort an die Öffentlichkeit gelangen. Gerade sogenannte Blackhat-Hacker behalten ihre Exploits gern für sich und verteilen sie nur an Leute weiter, die mit ihnen bekannt (z.B. in der gleichen Crew aktiv) sind. Und so manches Exploit wird auch teuer verkauft. Damit ist klar, dass es mit System-Updates nicht getan ist. Selbst Zero-Day-Exploits können bereits ausgenutzt werden, bevor der Distributor passende Updates bereitstellt.

Firewalls

Bei Firewalls kann man grundlegend 2 Arten unterscheiden: Paketfilter und Application Firewalls. Letztere sind auf Servern kaum im Einsatz und werden daher auch häufig als Desktop-Firewalls bezeichnet. Aktuell gibt es (glücklicherweise) einen Trend Firewalls mit Angriffserkennungssystemen zu koppeln. Vor allem im Appliance-Bereich entwickelt sich dies derzeit zum Standard. Nun leisten sich meiner Erfahrung nach nur wenige Unternehmen solche vergleichsweise teuren Appliances und gerade für kleine Unternehmen wie Startups stellen sie einen enormen Kostenfaktor dar, da sie zumeist auch noch mit Lizenzgebühren gekoppelt sind. Aufgrund dessen nutzen die meisten Unternehmen als Firewall lediglich Paketfilter wie pfSense oder IPtables.
 
Prinzipiell ist das nicht verkehrt, stellen solche Paketfilter doch sicher, dass nur jene Server-Ports nach außen erreichbar sind, auf die Clients direkt zugreifen müssen. Gute Systemadministratoren können sogar grundlegende Content-Filter mit Paketfiltern umsetzen. Diese stoßen aber spätestens dann an ihre Grenzen, wenn bei einem Angriff Paketfragmentierung eingesetzt wird, denn Paketfilter sind selten in der Lage die Pakete zu defragmentieren und erst dann auszuwerten. Paketfilter können daher nur als Schutz vor unberechtigten Zugriffen auf Server-Ports angesehen werden.

Zugriffskontrolle

Es versteht sich von selbst, dass die Zugriffskontrolle ein wichtiger Teil bei der Absicherung von Servern ist. Meiner Erfahrung nach wird aber auch in diesem Bereich sehr nachlässig agiert. Üblicherweise besteht die Zugriffskontrolle aus der Benutzerverwaltung. Linux, als eines der am weitesten verbreiteten Server-Systeme, verwendet dazu Benutzer und Gruppen. Jede Datei im System hat dabei Zugriffsrechte für den Besitzer (ein einzelner Benutzer), eine Gruppe (mehrere Benutzer, die gemeinsam in einer Gruppe sind) und Andere (Benutzer, die weder Eigentümer noch in der festgelegten Gruppe sind).
 
Diese recht enge Begrenzung führt häufig dazu, dass vielen Mitarbeitern mehr Rechte im System eingeräumt werden, als sie eigentlich benötigen. Weitere systembedingte Beschränkungen sorgen sogar oft dafür, dass Mitarbeitern das Ausführen von Befehlen mit Root-Rechten erlaubt wird, weil sie z.B. einen Dienst restarten müssen, der einen Port mit einer Nummer kleiner als 1024 verwendet. Ein klassisches Beispiel dafür sind Webserver mit den Ports 80 und 443, die gern auch mal von Entwicklern nach einem Rollout neugestartet werden.
 
Die Lösung für dieses Problem stellt RBAC (Role Based Access Control) dar. Allerdings steigt der Verwaltungsaufwand ziemlich an, wenn man RBAC einsetzt. Obwohl einige Linux-Distributionen wie CentOS mittlerweile RBAC in Form von SELinux als Default anbieten, findet man nicht selten Server, bei denen dieses Feature deaktiviert wurde. RBAC erweitert die klassische Rechte-Verwaltung von Linux-Systemen um Benutzer-Rollen. Auf diese Weise kann man einem Benutzer ohne Root-Rechte den Zugriff auf Ressourcen erlauben, für die er eigentlich Root-Rechte benötigen würde. Das Einräumen von Root-Rechten zum Ausführen bestimmter Befehle (z.B. über sudo) kann damit entfallen.
 
Doch die Zugriffskontrolle endet nicht mit der Definition von Zugriffsrechten. Ich habe in meiner beruflichen Laufbahn bisher noch kein Unternehmen erlebt, wo nicht auf mindestens einem Rechner eines IT-Mitarbeiters SSH-Schlüssel ungeschützt abgelegt wurden. Für einen Angreifer bedeutet dies, dass er sich nur Zugriff auf den Rechner des Mitarbeiters verschaffen muss um an den Key für den Zugriff auf einen oder mehrere Server zu kommen. Und erfahrungsgemäß sind Desktop-Systeme immer weitaus weniger gut geschützt als die Server.
 
Selbst wenn ein Angreifer keinen Zugriff auf ein Desktop-System mit entsprechenden Zugangsdaten erlangt, sind seine Möglichkeiten damit noch lange nicht ausgeschöpft. Wann haben Sie denn zum Beispiel das letzte Mal den Update-Stand Ihrer Telefonanlage überprüft? Oder nutzen Sie kein Internet, das über Ihre Telefonleitung läuft? In dem Fall sind Sie zumindest halbwegs sicher vor MITM (Man In The Middle) auf ihrer Telefonanlage. Doch das ist nicht zwingend eine Barriere für einen Angreifer. Denn ziemlich sicher haben Sie dennoch Telefonnummern beim Support Ihres Hosters hinterlegt, über die bestimmte Administratoren dort Aufträge erteilen dürfen. Ein Angreifer könnte also einfach die Telefonanlage nutzen um darüber den Hoster zu kontaktieren und sich als Mitarbeiter des Unternehmens auszugeben. Und schon ist die ganze Zugriffskontrolle hinfällig. Zugriffskontrolle darf sich daher nicht nur auf Desktop- und Server-Rechner beschränken sondern muss sämtliche Technik des Unternehmens beinhalten.
 
Eine große Rolle spielen die Zugriffsrechte auch für den Schutz von Dateien mit sicherheitskritischen Inhalten. Ein klassisches Beispiel dafür sind SSL-Zertifikate mit ihren zugehörigen Schlüssel-Dateien. Es ist logisch, dass keine Person auf diese Daten zugreifen sollte, wenn das Zertifikat nicht gerade ausgetauscht werden muss. Und wie ich hoffentlich darlegen konnte, sollten auch die Accounts der Systemadministratoren nicht ständig Zugriff darauf haben. Auch hier kann RBAC die Lösung des Problems sein, indem man eine Rolle definiert, der der ausschliessliche schreibende Zugriff auf diese Dateien vorbehalten ist. Der lesende Zugriff sollte nur durch die Nutzer von Applikationen möglich sein, die diese Daten nutzen müssen.

Web Application Firewall (WAF)

Man kann sagen, dass glücklicherweise immer mehr Unternehmen, die Webserver betreiben, auch eine WAF einsetzen. Zumeist werden diese von externen Anbietern genutzt, so dass ungültige Requests gar nicht erst bei den eigenen Webservern ankommen. Dennoch ist es leider häufig der Fall, dass Unternehmen, die Webapplikationen entwickeln, gar nicht sagen können welche Requests valide sind und welche nicht. Aus diesem Grund werden dann auch nur Standard-Filter gegen XSS, SQL-Injections und ähnliches angewendet.
 
Für einen Angreifer stellt es aber üblicherweise kein Problem dar sich den gleichen Service auch zu mieten und sich die dort verfügbaren Standard-Filter anzuschauen. Es ist dann ein Leichtes, die Requests für einen Angriff entsprechend anzupassen, so dass sie die Filter dennoch passieren. Aus diesem Grund ist es ratsam auf den Webservern selbst auch noch eigene Filter zu betreiben. Die meisten Webserver bieten entsprechende Erweiterungen. Als Beispiele seien hier mod_security für Apache und NAXSI für NGINX genannt. Alternativ sollte man sich für einen WAF-Anbieter entscheiden, der es erlaubt eigene Filter zu definieren und diese so zu pflegen, dass sie möglichst restriktiv sind. Dafür ist es allerdings notwendig sich genau darüber im Klaren zu sein, welche Requests für die eigene Webapplikation valide sind. Nur diese sollten dann auch durchgelassen werden.

Sicherheit der Applikation und des Systems

Leider hilft die beste WAF nichts, wenn die Entwickler Unsinn machen. Meine Erfahrung zeigt, dass sich viele Entwickler diverser Angriffsszenarien gar nicht bewusst sind. Es gibt heutzutage kaum noch eine Webapplikation, in der die Benutzer nicht irgendwo Daten eingeben können. Seien es Bilder, die hochgeladen werden, oder Profilinformationen, die ausgefüllt werden können. Logischerweise kann man nicht bei jeder Eingabe erst mal einen Wörterbuch-Abgleich machen um herauszubekommen, ob es alles natürliche Wörter sind, die in der Eingabe vorkommen. Und bei hochgeladenen Dateien geht die Sicherung auch nur selten über die Überprüfung des Dateityps hinaus. Benutzereingaben sind daher der klassische Angriffsvektor.
 
In vielen Unternehmen ist es gängige Praxis, dass Entwickler sich im Fehlerfall von der Webapplikation eine sogenannte Debug-Email zusenden lassen. In diese werden alle Daten, die zum Request gehören eingefügt um diesen auf einem Test-System nachzuspielen. Es ist allerdings kaum jemandem bewusst, dass durch diese Vorgehensweise neue Angriffsvektoren geschaffen werden. Ein Angreifer kann seinen Request zum Beispiel so aufbauen, dass er Schutzfunktionen wie Antivirus-Scans im Mailserver umgeht oder dort ein Exploit auslöst. Auf diese Weise werden plötzlich die Mailserver zum Angriffsziel. Und von dort ist oft der Weg zum restlichen Server-Netzwerk nicht weit. Oft läuft sogar der Mailserver auf dem gleichen System wie der Webserver, weil ja der Versand über localhost so schön einfach ist. Schliesslich kann man dort ja auf Authentifizierung verzichten, da der Mailserver nach außen ja nicht erreichbar ist. Leider ist dies ein Irrglaube.
 
Weiterhin spielt auch die Konfiguration des Systems und der eingesetzten Software eine wichtige Rolle beim Schutz von Server-Systemen. Wer in den letzten Jahren die Security-News verfolgt hat, der wird ab und an auf den Tipp gestoßen sein, bestimmte Konfigurationsanpassungen vorzunehmen, bis ein Update für eine bekanntgewordene Lücke bereitsteht. Die Schlussfolgerung, die man daraus treffen sollte, ist, dass man Konfigurationen möglichst restriktiv machen sollte. Features, die bei einer Software nicht benötigt werden, sollte man deaktivieren. Komponenten, die man nicht braucht, sollte man deinstallieren.
 
Die Absicherung einer Webapplikation endet also nicht beim Webserver. Man sollte sich diesbezüglich durchaus mal von einem Hacker beraten lassen um auch mal Einblick in komplexere Angriffsszenarien zu bekommen, wie sie zum Beispiel in der Wirtschaftsspionage eingesetzt werden. Es ist mir aus Platzgründen nicht möglich hier auf alle einzugehen, denn allein schon für die theoretische Betrachtung müsste ich ein ganzes Buch füllen. Die Angriffsmöglichkeiten sind vielfältig und hängen immer individuell von der jeweils eingesetzten Software, der verwendeten Programmiersprache und weiteren Faktoren ab.

Angriffserkennungssysteme

Nun komme ich zu einem Punkt, der noch in viel zu wenigen Unternehmen ausreichend Beachtung findet: der Einsatz von Angriffserkennungssystemen. Hierbei unterscheidet man zwei Formen solcher Systeme, die Host-basierte und die Netzwerk-basierte Angriffserkennung (HIDS - Host Intrusion Detection System - und NIDS - Network Intrusion Detection System).
 
Auch wenn viele HIDS mittlerweile grundlegende Scans von Netzwerk-Daten mitbringen, liegt ihr Fokus vor allem darauf unberechtigte Änderungen und Vorkommnisse im Server-System zu erkennen. HIDS sind in der Lage Änderungen am Dateisystem zu erkennen, Log-Daten auszuwerten und ungewöhnliche Fehler im System an die zuständigen Administratoren zu melden.
 
Dem gegenüber stehen NIDS, die darauf spezialisiert sind den Traffic eines Servers auszuwerten. Sie können z.B. erkennen wenn TCP-Flags falsch gesetzt sind oder wenn auf einem Port Traffic ankommt, der nicht den Vorgaben des erwarteten Protokolls entspricht. Ausserdem erkennen sie Portscans und ähnliche Maßnahmen, die häufig Angriffen vorausgehen. Auch verfügen sie über Filter, die bekannte Exploits und Angriffsszenarien erkennen und entsprechend blockieren.
 
Schon anhand dieser Funktionen kann man erkennen, dass sie einen erheblichen Beitrag für die Server-Sicherheit leisten können. HIDS sollten dabei auf allen Servern zum Einsatz kommen. NIDS sollte man im Optimalfall vor das Server-Netzwerk setzen, so dass unerwünschter Traffic gar nicht erst bei den Servern ankommt.
 
Man sollte sich aber nicht damit zufriedengeben solche Systeme einmalig aufzusetzen. Sie machen nur dann Sinn, wenn sie regelmäßig überprüft und an aktuelle Angriffsszenarien angepasst werden. Auch sollte man nicht dem Irrglauben unterliegen, dass IDS die Server aktiv schützen. Es gibt durchaus auch aktive Systeme, sogenannte IPS (Intrusion Prevention System). IDS sind aber in erster Linie dazu da, die Administratoren zu warnen, wenn ungewöhnliche Vorgänge im Netzwerk stattfinden. Die Abwehr des Angriffs liegt dann immer noch in deren Verantwortung.
 
IPS können in einigen wenigen Fällen auch Sinn machen. Allerdings sind meine persönlichen Erfahrungen zumindest im Webumfeld damit eher negativ. Die Ursache dafür liegt darin, dass Angreifer häufig Proxy-Server verwenden, die auch von normalen Usern verwendet werden. Die meisten IPS blockieren bei einem erkannten Angriff die Source-IP des Angreifers und sperren dann auch jene User aus, die den gleichen Proxy verwenden. Auf diese Weise können Angreifer dafür sorgen, dass valide User gar nicht mehr über Proxies auf eine Plattform zugreifen können, was in den meisten Fällen nicht erwünscht ist.

Infrastruktur-Komponenten

Da die meisten Unternehmen ihre Server in einem Rechenzentrum hosten, wird die Infrastruktur des Netzwerks häufig nur unzureichend betrachtet, wenn es um die Absicherung der Server geht. Man sollte sich hierbei allerdings keineswegs ausschliesslich auf den RZ-Betreiber verlassen. Und man sollte nicht vergessen, dass man ggf. auch Infrastruktur nutzt, die gar nicht vom RZ-Betreiber gehostet wird. Hat man zum Beispiel keine eigenen DNS-Server im Einsatz, nutzt man vermutlich DNS-Server, die von anderen öffentlichen Anbietern betrieben werden. Doch was ist, wenn diese DNS-Server kompromittiert werden? Oder wenn die Server auf einen gänzlich anderen DNS umgeleitet werden, indem man ihre Einstellungen manipuliert? Das kann zwar durch Angriffserkennungssysteme großteils ausgeschlossen werden, aber nicht gänzlich. Daher sollte man auch Infrastruktur-Komponenten entsprechend überwachen. Bei einem DNS bedeutet dies, dass man die Route zum DNS überwacht und prüft, ob er für bestimmte Domains die erwartete IP zurückgibt. Bei einem Mailserver könnte man z.B. die SMTP-Begrüßung überwachen und regelmäßig eine bestimmte Email abholen, deren Inhalt man validiert. Mit solchen Maßnahmen kann man sicherstellen, dass man tatsächlich die Infrastruktur nutzt, die man erwartet und nicht einfach auf MITM-Proxies umgeleitet wird. Im Optimalfall sollte jede Verbindung mittels Zertifikaten validiert werden. Natürlich müssen dann auch die Zertifikate gut geschützt werden.

Weitere Maßnahmen

Damit sind wir fast am Ende angelangt. Es soll aber nicht unerwähnt bleiben, dass es weitere Technologien gibt, deren Einsatz gegebenenfalls ratsam ist. Regelmäßige Sicherheitsprüfungen sind auf jeden Fall anzuraten. Bei diesen sollte man die Server auf ungewollt laufende Prozesse prüfen, Rootkit-Scanner durchlaufen lassen, nachschauen ob Kernel-Module geladen sind, die nicht benötigt werden, und prüfen, ob Ports verwendet werden, die man keinem Prozess zuordnen kann.
Auch der Einsatz von Virtualisierungstechnologien kann einen Beitrag zur Sicherheit leisten. Anstatt immer nur Updates einzuspielen kann man damit immer gleich das komplette System austauschen, indem man einfach eine neue virtuelle Maschine mit dem aktuellen Update-Stand startet. Etwaige eingeschleuste Schadsoftware wird damit automatisch entfernt. Man sollte bei dieser Vorgehensweise allerdings die entfernten VMs nochmals in einer Sandbox-Umgebung überprüfen. Sollte sich eine eingeschleuste Schadsoftware finden, ist logischerweise die Suche nach der Sicherheitslücke notwendig.

Abschliessende Worte

Dieser Artikel soll nicht darüber hinwegtäuschen, dass Sicherheit ein Prozess ist und immer von den Gegebenheiten des Server-Netzwerks abhängt. Es ist nicht möglich eine allgemein gültige Lösung für alle Server-Netzwerke zu definieren. Die hier aufgeführten Technologien und Vorsichtsmaßnahmen sollten aber ein Mindestmaß an Sicherheit für Web-Netzwerke gewährleisten, sofern diese richtig eingesetzt und gut gewartet werden. Sicherheit ist in jedem Fall ein Prozess, der in die Unternehmenskultur eingepflegt werden muss. Dabei sollte nicht vergessen werden, dass auch der Mensch eine mögliche Sicherheitslücke darstellt. Hier sei das Stichwort „Social Engineering“ genannt. Diese Sicherheitslücke kann man nur durch Schulungen und Verhaltensvorgaben schliessen, die strikt eingehalten werden müssen. Es darf auch nicht unerwähnt bleiben, dass viele Angriffe von innen kommen. So besteht immer die Möglichkeit, dass ein entlassener Mitarbeiter Daten mitnimmt, die nicht in die Öffentlichkeit gehören und/oder für Angriffe genutzt werden können. Ein Unternehmen sollte daher seine Daten immer möglichst restriktiv an die Mitarbeiter weitergeben. Es gibt Bereiche, in denen sich das nicht vermeiden lässt. Genannt sei hier als Beispiel die Systemadministration. Sysadmins brauchen üblicherweise Zugriff auf alle Systeme um ihren Job zu machen. Umso wichtiger ist es, dass diese ihre Daten entsprechend absichern und dass ihre Accounts, wenn sie das Unternehmen verlassen, möglichst schnell entfernt werden. Eine rechtliche Handhabe in Form von Geheimhaltungsverträgen sollte ein Unternehmen mit allen Mitarbeitern solcher sicherheitskritischen Bereiche sicherstellen.
Kommentare (0) - Kommentar schreiben

Apache mit PHP aus dem Source installieren

Will man eine optimale Performance aus seiner Server-Software holen, lässt es sich manchmal nicht vermeiden bestimmte Software direkt über die Quelltexte zu installieren. Dabei sollte man allerdings immer genau abwägen, ob die vom Distributor mitgelieferten Pakete für die eigenen Zwecke ausreichend sind oder ob man bestimmte Features hinzufügen oder entfernen muss um den eigenen Anforderungen gerecht zu werden. Es gibt auch Linux-Distributionen, bei denen Updates immer eine Weile auf sich warten lassen, wodurch es aus Sicherheitsgründen ratsam ist zu einer Installation aus dem Source zu greifen.

Wichtig ist in jedem Fall, dass man immer die aktuellste Version der Software installiert. Daher wird im folgenden Artikel nicht mit einer bestimmten Version gearbeitet sondern die Versionsnummer immer durch $VERSION ersetzt. Dies ermöglicht es, die Befehle in Skripte einzufügen, wo die Umgebungsvariable VERSION einfach via export-Befehl oder direkt im Skript definiert werden kann.

Weiterhin wird im Folgenden die Umgebungsvariable $INSTALL_TARGET genutzt, die den Ordner angibt, in dem die Software installiert werden soll. Üblicherweise ist das /usr/local. Will man die Software recht einfach auf andere Server verteilen, kann sich aber auch ein separater Ordner wie /operation anbieten.

Apache

Die aktuelle Version von Apache kann man immer unter http://www.apache.org/dist/httpd/ herunterladen.

cd /usr/src
wget http://www.apache.org/dist/httpd/httpd-$VERSION.tar.gz

Es bietet sich an diese URL mittels eines Monitorings zu auf neue Versionen zu überwachen. Bitte achten Sie darauf, dass das Monitoring den Inhalt der Seite nicht gerade minütlich prüft. Man sollte die Infrastruktur von Apache.org nicht unnötig belasten. Eine stündliche oder auch nur tägliche Prüfung ist angemessen.

Mit hilfe der ASC-Datei, die unter der gleichen URL verfügbar ist, lässt sich die Quelltext-Datei validieren.

wget http://www.apache.org/dist/httpd/httpd-$VERSION.tar.gz.asc
gpg --verify httpd-$VERSION.tar.gz.asc httpd-$VERSION.tar.gz

War die Validierung erfolgreich, können die Quelltexte ausgepackt werden.

tar -xzf httpd-$VERSION.tar.gz

Als nächstes müssen die Quelltexte konfiguriert werden, wodurch dann auch das zugehörige Makefile generiert wird. Hierbei sollte man sich nicht auf den üblichen Dreisatz verlassen, sondern mittels einiger Parameter für das configure-Skript sicherstellen, dass die gewünschten Features aktiviert sind.

cd httpd-$VERSION
./configure --prefix=$INSTALL_TARGET 
--enable-so 
--with-ssl 
--enable-cgi 
--enable-modules=all 
--enable-mods-shared=all 
--enable-ssl 
--enable-cache 
--enable-mem-cache

In diesem Beispiel werden alle von Apache angeboteten Funktionalitäten als "shared modules" kompiliert. Ausserdem wird sichergestellt, dass die Nutzung von SSL möglich ist, dass CGI verwendet werden kann und dass bei Bedarf ein Memcache-Server zum Einsatz kommen kann. Letzteres hat aber nichts damit zu tun ob die Webapp einen Memcache nutzen kann. Hierbei geht es ausschliesslich darum, dass die Webserver-Software selbst Daten im Memcache ablegen kann, z.B. für den Session-Cache. Dies kann den Zugriff auf Sessions erheblich beschleunigen. Nutzt man diese Möglichkeit nicht, kann man den Memcache-Parameter natürlich weglassen.

Wurde das configure-Skript erfolgreich ausgeführt - ggf. müssen noch entsprechende dev/devel-Pakete für die Abhängigkeiten nachinstalliert werden - kann das Kompilieren und Installieren erfolgen.

make
make install

PHP

In ähnlicher Weise geht man nun mit PHP vor. Hier sollte man aber darauf achten, dass nur jene Funktionalitäten kompiliert werden, die für die gehostete Webapp notwendig sind. So hält man seine PHP-Installation möglichst schlank. 

Zuerst benötigt man natürlich die Quelltexte von PHP. Im Folgenden wird noch auf das Kompilieren von PHP 5 eingegangen, da dies noch am häufigsten im Einsatz ist. Die Parameter für configure von PHP 7 unterscheiden sich in einigen Punkten.

cd /usr/src
wget http://de1.php.net/distributions/php-$VERSION.tar.gz

Auch hier sollte man die Quelltexte wieder validieren.

wget http://de1.php.net/distributions/php-$VERSION.tar.gz.asc
gpg --verify php-$VERSION.tar.gz.asc php-$VERSION.tar.gz

Ist die Verifizierung erfolgreich, werden die Quelltexte ausgepackt.

tar -xzf php-$VERSION.tar.gz

Im nächsten Schritt werden die Quelltexte dann konfiguriert. Hier im Beispiel verwende ich alle configure-Parameter, wie sie für Webapps wie Wordpress notwendig sind. Ich möchte aber noch einmal betonen, dass man nur jene Parameter nutzen sollte, die für die eigene Webapp benötigt werden.

./configure --enable-zip 
--enable-wddx 
--enable-sysvshm 
--enable-sysvsem 
--enable-sysvmsg 
--enable-soap 
--enable-shmop 
--with-recode 
--with-readline 
--with-mysql=/usr 
--enable-mbstring 
--with-gettext 
--with-png-dir 
--with-jpeg-dir 
--with-gd 
--with-pcre-dir 
--with-gmp 
--with-mhash 
--with-freetype-dir 
--with-xpm-dir 
--with-pcre-dir 
--enable-exif 
--enable-dba=shared 
--with-bz2 
--enable-bcmath 
--enable-sigchild 
--with-apxs2=$INSTALL_TARGET/bin/apxs 
--prefix=$INSTALL_TARGET 
--with-pear=$INSTALL_TARGET/bin 
--with-config-file-path=$INSTALL_TARGET/conf/ 
--with-libdir=lib64 
--with-openssl 
--with-xsl=/usr 
--with-libxml-dir=/usr 
--with-pdo-mysql=/usr 
--with-curl=/usr

Auch hierbei wird es ziemlich sicher einige Abhängigkeiten geben, die aufgelöst werden müssen. Das heisst, dass dafür die entsprechenden dev/devel-Pakete installiert werden müssen. Für ein Debian-System sind zum Beispiel folgende Pakete für die Abhängigkeiten notwendig:

  • gnupg
  • build-essential
  • libapr1-dev
  • libaprutil1-dev
  • wget
  • libxml2-dev
  • openssl
  • libssl-dev
  • libsslcommon2-dev
  • libcurl4-openssl-dev
  • libbz2-dev
  • libjpeg62-dev
  • libpng12-dev
  • libxpm-dev
  • libfreetype6-dev
  • libgmp-dev
  • libreadline6-dev
  • librecode-dev
  • libxslt1-dev
 

Nun kann PHP kompiliert und installiert werden.

make
make install

Abschliessend müssen nur noch die Konfigurationen angepasst werden. Das Binary $INSTALL_TARGET/bin/apachectl kann als Init-Skript verwendet werden, da es die Parameter start, stop und restart problemlos versteht. Will man allerdings einen Watchdog verwenden, sollte man ein entsprechendes Init-Skript dafür erstellen.

Abschliessende Worte

Zum Schluss sei nochmals angemerkt, dass es sich bei den hier verwendeten configure-Parametern nur um ein Beispiel handelt. Dieser Artikel soll lediglich aufzeigen welche Schritte notwendig sind, wenn man einen Apache-Webserver mit PHP aus dem Source installieren will. Je nach Webapp unterscheiden sich die verwendeten Parameter für die configure-Skripte der Quelltexte. Man sollte immer darauf achten möglichst wenig einzubauen. 

Weiterhin ist es ratsam entsprechende Rollout-Mechanismen/Skripte aufzubauen, wenn man Software aus den Sources installiert. Schliesslich ist es mit einer einmaligen Installation nicht getan und man wird kaum Lust haben, bei jedem Update die ganzen Befehle wieder und wieder einzutippen. Wie solche Rollout-Skripte mit Perl und dem Framework Rex aussehen können, kann man sich in meinen Git-Repository anschauen. Dort werden die gewünschten Versionen und sonstige Werte im Rexfile definiert. Ausserdem wird auch gleich die Konfiguration damit verwaltet und ausgerollt. Eine Einführung in Rex findet man in meinem TechBlog.

Kommentare (0) - Kommentar schreiben

MacPorts aktualisieren

Wer MacPorts nutzt, kennt das Problem, dass nach einem System-Update von OSX die Installation neuer Ports nicht mehr funktioniert. Um dieses Problem zu beheben, müssen die bereits installierten Pakete aktualisiert werden.

Was sind MacPorts?

Bei MacPorts handelt es sich um eine Sammlung von OpenSource-Tools für MacOSX, die mittels eines Paketmanagers installiert werden können. Die Funktionsweise ist vergleichbar mit den Ports von FreeBSD.

Wie aktualisiert man MacPorts richtig?

Aktualisiert man sein OSX, ist auch ein Update der MacPorts fällig. Dazu muss man zuerst das MacPorts-System passend zur OSX-Version installieren. Entsprechende Installationspakete findet man unter https://www.macports.org/install.php.

Im nächsten Schritt muss die Liste der installierten Ports gesichert werden. Dies geschieht mit Hilfe des Befehls 'port'.

mkdir ~/macports_tmp && cd ~/macports_tmp
port -qv installed > myports.txt

Um eine saubere Basis für die Reinstallation zu haben, sollten die bereits installierten Ports entfernt werden.

sudo port -f uninstall installed

Auch das Build-Verzeichnis sollte bereinigt werden.

sudo rm -rf /opt/local/var/macports/build/*

Für eine einfache Reinstallation stellt das MacPorts-Projekt ein Skript zu Verfügung, das man sich aus dem Subversion-Repository herunterladen kann. Da es per Default nicht mit einem Executable-Flag versehen ist, muss dieses nach dem Download gesetzt werden.

cd ~/macports_tmp && curl -O https://svn.macports.org/repository/macports/contrib/restore_ports/restore_ports.tcl
chmod +x restore_ports.tcl

Als Parameter übergibt man dem Skript die Datei, in der man die Liste der installierten Ports gespeichert hat

cd ~/macports_tmp && sudo ./restore_ports.tcl myports.txt

Damit ist die Aktualisierung der Ports dann zumeist auch schon abgeschlossen.

Probleme

Manchmal kommt es vor, dass einzelne Ports entfernt wurden oder in Konflikt mit neuen Ports stehen, die als Abhängigkeit installiert werden. In einem solchen Fall wirft MacPorts eine entsprechende Meldung über den Konflikt aus. Die einfachste Lösung besteht darin, die beanstandete Software aus der myports.txt zu entfernen.

Kommentare (0) - Kommentar schreiben

noexec-tmp-Verzeichnis auf Rootservern

Mittlerweile hat es sich in der Welt des Webs bereits rumgesprochen, dass eine der wichtigsten Schutzvorkehrungen gegen das Einschleusen von Bots ein Temp-Verzeichnis ist, das mit dem noexec-Flag eingehängt wird. Gerade bei Rootservern, die mit einem vorinstallierten System daher kommen, ist das zumeist nicht der Fall und eine Änderung der Partitionierung nur bedingt möglich.

Warum noexec?

Der typische Weg von Bots auf einen Webserver führt über eine File-Injection-Lücke der Webapp. Dabei wird ausgenutzt, dass eine Webapp Dateien in das Temp-Verzeichnis des Servers laden kann. Kommt nun noch hinzu, dass man die so hochgeladene Datei aufrufen kann, wird so die Möglichkeit geschaffen Bots anzusprechen. Eine andere Möglichkeit ist, dass eine Webapp die Ausführung von Systembefehlen ermöglicht. Hierbei wird dann zumeist ein Befehl ausgeführt, mit dem eine Datei auf den Server geladen wird, beispielsweise mittels wget, curl oder ähnlicher Befehle, die fast jedes Linux- oder Unix-System dabei hat. Auch dabei wird als Speicherort für die geladene Datei zumeist eines der bekannten Temp-Verzeichnisse verwendet, wie die Auswertung meiner Angriffserkennungssysteme und Honeypots in den letzten Jahren zeigte.

Ist nun allerdings dieses Temp-Verzeichnis mit dem noexec-Flag im System eingehängt, ist zwar der Download erfolgreich, aber die Ausführung des heruntergeladenen Skripts oder Programms schlägt fehl, so dass kein weiterer Schaden mehr angerichtet wird. Daher ist es sinnvoll zumindest die Temp-Verzeichnisse eines Systems mit dem noexec-Flag zu mounten. Im Optimalfall sind alle Verzeichnisse mit diesem Flag eingehängt, die keine ausführbaren Dateien beinhalten sollen oder dürfen. 

Wie bekommt man ein noexec-Temp-Verzeichnis auf vorinstallierte Systeme?

Der einfachste Weg, der ohne grosses Umpartitionieren von Festplatten funktioniert, führt bei Rootservern oder sonstigen Servern mit vorinstallierten Betriebssystemen über eine Image-Datei, die über das Loop-Device im System eingehängt wird. Dazu muss natürlich zuerst ein solches Image erstellt werden, wobei uns das Tool 'dd' hilft:

dd if=/dev/zero of=/tmp.img bs=1 count=0 seek=1G

In diesem Beispiel wird die Image-Datei /tmp.img mit einer Größe von 1 GB erstellt. Das ist eine Größe, die üblicherweise für Temp-Verzeichnisse ausreicht.

Im nächsten Schritt muss nun ein Dateisystem auf dem Image angelegt werden:

echo "y" | mkfs.ext4 /tmp.img

Hier im Beispiel wird das ext4-Dateisystem verwendet. 

Nun muss man noch sicherstellen, dass das aktuelle tmp-Verzeichnis leer ist, damit keine Daten verloren gehen. Hierfür verschiebt man die bereits im Verzeichnis befindlichen Dateien in einen anderen Ordner (z.B. /tmp.old). Erst wenn der Mountpoint, der als Ziel vorgesehen ist, leer ist, kann das Image dort eingehängt werden:

mount -o defaults,nosuid,noexec,nodev,loop -t ext4 /tmp.img /tmp

Zu guter Letzt verschiebt man die zuvor gesicherten Dateien wieder in den ursprünglichen Ordner (/tmp ist hier nur ein Beispiel) und hat damit ein Temp-Verzeichnis, in dem die Ausführung von Skripten immer fehlschlägt. 

Natürlich sollte man diese Prozedur für alle Temp-Verzeichnisse im System wiederholen. Dabei ist zu beachten, dass z.B. bei PHP-Applikationen in der PHP-Konfiguration ein extra Temp-Verzeichnis definiert werden kann. Vor allem diese Verzeichnisse sollten natürlich das noexec-Flag bekommen.

Was gibt es sonst noch zu beachten?

Leider neigen manche Betreuer von Software-Paketen dazu ihre Postinstall- und Preinstall-Skripte auch im Temp-Verzeichnis abzulegen und dort auszuführen. In der Folge schlägt die Installation mancher Pakete fehl, wenn man noexec-Flags verwendet. Um dieses Problem zu umgehen, sollte man vor der Installation oder dem Update von Paketen die Umgebungsvariablen für Temp-Verzeichnisse zeitweise entsprechend umdefinieren, so dass der Paketmanager nicht in die noexec-Verzeichnisse geht. 

Damit man nicht nach jedem Reboot den Mount-Vorgang manuell durchführen muss, sollte man natürlich auch einen entsprechenden Eintrag in der /etc/fstab anlegen.

/tmp.img /tmp ext4 defaults,nosuid,noexec,nodev,loop 0 0
Kommentare (0) - Kommentar schreiben

Netzwerk-Design für Web-Startups

Berlin ist die Hauptstadt der Startups... so sagt man zumindest. Die meisten dieser Startups sind meiner Erfahrung nach im Web tätig. Und wenn man das WWW zum Tummelplatz seines Produkts erwählt hat, benötigt man eine Plattform, auf der das Produkt gehostet wird. Ich bin aus Berlin und habe bereits in einigen Startups aus dem Web-Bereich gearbeitet und vom initialen Netzwerk-Design bis zu Aufräumarbeiten in gewachsenen Strukturen einiges erlebt. Gewachsene Strukturen in einem Startup? Ja, das gibt's. Bereits nach 3-5 Jahren treten die ersten Skalierungsprobleme auf, wenn man nicht von Anfang an ein ordentliches Netzwerk- und Applikationsdesign anwendet.
 
Das grösste Problem, das Startups haben, ist, dass sie zumeist von Menschen geleitet werden, die man nicht unbedingt als technik-affin bezeichnen würde. Das ist auch gar nicht notwendig, denn schliesslich müssen sie Management-Aufgaben übernehmen und nicht programmieren oder Server administrieren. Sie kennen sich zwar mit der Nutzung von Anwendungen nicht aber mit dem Design oder gar der Programmierung selbiger aus. Die meisten Startups werden von Leuten mit BWL-Hintergrund oder ähnlichen "Manager-Kenntnissen" hochgezogen. Um ihre Idee umzusetzen benötigen sie somit die Expertise von Technikern. Und da kann man leider schnell in's Fettnäpfchen treten. Daher ist es notwendig, dass auch Manager von Startups ein grundlegendes Verständnis für ihre Webapp und ihr Netzwerk aufbauen. Nur so können sie selbst feststellen, ob ihnen ein Berater eventuell gerade Unsinn erzählt.

Die NWO der Web-Netzwerke

Drei Komponenten spielen bei der IT von Startups im Web (im Folgenden kurz als Startups bezeichnet) die Hauptrolle: Network, Webapp, Office - kurz NWO. Das ist die Welt-Ordnung um die sich die Technik des Startups, von den finanziellen Aspekten und dem Marketing abgesehen, drehen muss. Wobei natürlich auch bei diesen drei Komponenten die finanziellen Aspekte eine Rolle spielen, doch dazu später mehr.
 
Will man diese Komponenten priorisieren, dann würde man vermutlich die Server mit der Webapp auf Platz 1 setzen und das Office-Netzwerk auf Platz 2.

Das Office

Auf das Office-Netzwerk will ich nicht zu weitschweifend eingehen. Die Erfahrung zeigt, dass selbst bei einem abgebrannten Büro die Mitarbeiter zur Not auch von zu Hause arbeiten können. Es ist daher für Startups noch nicht zwingend notwendig, dass sie im Office auf Dinge wie Redundanz der Internet-Anbindung u.ä. achten. Dennoch gibt es ein paar Dinge, die beachtet werden müssen.
 
Eines der wichtigen Gebote in einem Office-Netzwerk ist der Datenschutz. Dazu gehört neben dem Schutz der Daten auch ihre Verfügbarkeit und ihre Redundanz. Mit anderen Worten: Daten, die im Büro verfügbar sein müssen, müssen jederzeit abrufbar sein und es muss sichergestellt werden, dass nur autorisierte Personen Zugriff haben. Außerdem müssen einige Daten auch für Mitarbeiter im Außendienst zur Verfügung stehen.
 
Es gibt daher im Office-Netzwerk drei grundlegende Dinge beim Netzwerk-Design zu beachten. Von allen Daten müssen regelmäßig Backups erstellt werden, die außerhalb des Büros aufbewahrt werden. Weiterhin müssen Technologien für den Datenzugriff eingesetzt werden, die eine ausreichend feine Granulierung der Zugriffsrechte ermöglichen. Und es muss ein sicherer Remote-Zugang zur Verfügung stehen, über den Mitarbeiter, die nicht im Büro arbeiten, auf die Daten zugreifen können.
 
Technisch gesehen benötigt man also eine Router mit VPN-Funktionen sowie einen Fileserver und einen externen Backup-Space zum sichern der Daten des Fileservers.

Remote-Zugang via VPN

Es gibt kaum ein Startup, wo es nicht notwendig ist, dass Daten wie Präsentationen und ggf. auch Geschäftsdaten für Partner remote verfügbar sind. Um dies zu bewerkstelligen verwendet man heutzutage einen sogenannten VPN-Zugang (Virtual Private Network). Damit ist es möglich ausserhalb des Büros zu arbeiten als wäre man vor Ort.
 
VPN bietet dabei einige Vorteile. Der grösste Vorteil liegt in der Verschlüsselung der Verbindung. Das erschwert Industrie-Spionage erheblich und sollte daher für Startups mit neuen Ideen für sämtliche Datenübertragungen ein wichtiges Kriterium sein. Spätestens seit dem NSA-Skandal wissen wir, dass unsere Geheimdienste fleissig an Industriespionage beteiligt sind. Ausserdem wird VPN mittlerweile von den meisten Betriebssystemen, inklusive mobiler Betriebssysteme, out-of-the-box unterstützt. Der Sicherheit zuliebe sollte man also auf von aussen zugängliche FTP-Server oder ähnliche Mittel verzichten und zur sicheren Alterntive VPN greifen.
 
Auch die Verwaltung von VPN-Servern ist heutzutage nicht mehr besonders aufwendig. Jeder halbwegs brauchbare Router hat heutzutage einen VPN-Server integriert, bei dem man die Verwaltung bequem via Webinterface machen kann. Solche Router gibt es bereits ab 50 Euro, sind also als Kostenfaktor fast schon zu vernachlässigen. Meine besten Erfahrungen habe ich in diesem Bereich mit Geräten von Mikrotik gemacht. Sie stellen eine besonders kostengünstige Möglichkeit dar und bieten dabei dennoch eine Flexibilität, wie man sie sonst nur von wesentlich teureren Geräten von Cisco kennt.

Fileserver

Eine der wichtigsten Datenquellen in einem Büro ist zumeist der Fileserver. Da findet man von fertigen NAS-Lösungen bis zu Servern mit FTP, Samba & Co so ziemlich alles in Startups. Natürlich haben NAS-Lösungen den Vorteil, dass sie ohne viel Aufwand in Betrieb genommen werden können. Aber sie haben auch den Nachteil der Unflexibilität. Wenn das Startup wächst, steht daher zumeist ziemlich bald ein Umzug auf ein anderes System an. Dadurch entsteht zusätzlicher Aufwand für den Systemadministrator, der den Umzug der Daten durchführen muss (zumeist ausserhalb der üblichen Office-Zeiten also in der Nacht oder am Wochenende, damit der Betriebsablauf nicht gestört wird). Es muss neue Hardware angeschafft werden und das (zumeist nicht gerade billige) NAS ist nur noch Elektro-Schrott, der kaum weiter verwendet werden kann.
 
Daher sollte man sich schon beim Beginn eines Startups fragen, ob man nicht besser ein paar Euro mehr in die Hand nimmt um einen echten Fileserver zu besorgen und mit einem Cluster-Dateisystem auszustatten. So kann der Speicherplatz jederzeit flexibel nach oben skalieren, wenn Bedarf besteht.
 
Ist allerdings klar, dass die Menge der im Büro anfallenden Daten in einem überschaubaren Rahmen bleibt (z.B. weil die Webapplikation die meisten Daten für Rechungswesen hält oder weil die Zielgruppe nicht sehr groß ist), kann ein NAS durchaus eine preiswerte Lösung sein. Es ist also notwendig sich über den zu erwartenden Datenzuwachs Gedanken zu machen

Backups

Gerade Startups sparen gern bei den Backups. So werden zwar zumeist Backups von Daten im Büro erstellt, aber leider auch eben dort aufbewahrt. Im Fall eines Brandes oder einer ähnlichen Katastrophe im Büro bedeutet dies, dass auch die Backups verloren sind. Auch eine feuerfeste Tür vor dem Serverraum kann im Fall eines Hausbrandes die Hitzeentwicklung nicht lange genug abhalten um ein Unversehrtheit der Backup-Datenträger oder gar der Server zu gewährleisten. Feuerfeste Türen sind daher nur dazu geeignet das Büro im Fall eines Brandes im Serverraum zu schützen und nicht umgekehrt.
 
Aus diesem Grund sollten regelmässig Backups ausserhalb des Büros gelagert werden. Dabei ist es keineswegs notwendig jeden Tag Backups in eine Bank zu tragen und dort in einem Schliessfach abzulegen. Aber wöchentliche Backups an einem sicheren Ort abzulegen, ist durchaus notwendig um im schlimmsten Fall nicht zuviel der geleisteten Arbeit zu verlieren. Steht kein Schliessfach oder Safe für Backup-Datenträger zur Verfügung, sind die Backups zwingend zu verschlüsseln.
 
Allerdings müssen es keineswegs immer Datenträger sein, die man irgendwo an einem anderen Ort ablegt. Heutzutage gibt es auch Rechenzentren, bei denen man recht sicher seine Daten unterbringen kann, wo sie dann automatisch auf mehrere Standort gespiegelt und bei Bedarf auch verschlüsselt werden. Dabei sollte natürlich darauf geachtet werden, dass die Daten über eine verschlüsselte Verbindung in das Rechenzentrum übertragen werden, dort verschlüsselt gespeichert sind und dass der Datenschutz eingehalten wird. Clouds sind definitiv keine brauchbaren Backup-Speicher, auch wenn sie noch so preiswert sind.

Die Server

Die Server stellen, zusammen mit der Webapp, in einem Startup das Herz des Unternehmens dar. Dabei werden leider häufig ein paar grundlegende Fehler bei der Einrichtung, dem Standort und auch der Verwaltung gemacht, die man vermeiden kann, wenn man sie kennt. Die Ursache dieser Probleme liegt zumeist darin, dass weder Management noch die eingesetzten Sysadmins jemals in grossen Netzwerken gearbeitet haben. Nun sind aber Startups zumeist bestrebt zu wachsen und diesem Anspruch muss auch das Server-Netzwerk gerecht werden. Man sollte daher bereits bei der initialen Planung im Hinterkopf haben, dass das Netzwerk gegebenenfalls schnell nach oben skalieren muss um bei einem starken Benutzerandrang nicht in die Knie zu gehen. Auch ein sehr kleines Netzwerk sollte darauf vorbereitet sein irgendwann ein sehr grosses zu werden. Das erspart in späteren Jahren teure und aufwendige Server-Umzüge.

Der Standort

Einer der grössten Fehler, dem ich in Startups immer wieder begegne, ist die Wahl des Server-Standorts. Dabei geht es weniger um den Ort sondern um die Wahl des Rechenzentrums. Wobei auch manchmal der Ort eine Rolle spielt, denn es gibt so manches Startup, das seine ersten Server im Büro stehen hat, wo weder Brand- noch Datenschutz oder -verfügbarkeit gewährleistet sind. Das Büro ist der denkbar schlechteste Standort für die Server sofern kein entsprechend ausgestatteter Raum mit redundanter Internet-Anbindung, Brandschutz-Anlagen, Klimatisierung und Zugangsschutz zur Verfügung steht.
 
Doch selbst wenn man seine Server in ein Rechenzentrum stellt, kann man dabei einiges falsch machen. Ein paar Punkte sind auch hier zu beachten:
- Redundanz
- Datenschutz
- Support
- Kapazitäten
 
Der wichtigste Punkt bei der Auswahl eines RZ ist die Redundanz. Was bringen die besten Server und die beste Webapp, wenn ein Stromausfall oder der Ausfall eines Peering-Anbieters dazu führt, dass diese nicht mehr erreichbar sind? Daher sollte schon bei der Wahl des Rechenzentrums darauf geachtet werden, dass einige Kriterien für die Redundanz gewährleistet sind. Denn nichts ist für ein Geschäft im WWW schädlicher als eine Nicht-Verfügbarkeit der Plattform.
 
Zuerst sollte natürlich eine redundante Anbindung an das Internet vorhanden sein, die über verschiedene Peers läuft und nicht nur auf einen Peering-Anbieter angewiesen ist. Ob dies gegeben ist, erfährt man auf Nachfrage bei jedem anständigen RZ-Anbieter.
 
Weiterhin ist darauf zu achten, dass auch die Stromversorgung sowie die Klimatisierung redundant ausgelegt sind. Das heisst also, dass min. 2 verschiedene Stromkreise vorhanden sein müssen, die unabhängig voneinander funktionieren. Einer der Stromkreise sollte im Optimalfall durch eine Notstromversorgung (z.b. über Diesel-Aggregate) abgesichert sein. Ich habe in den letzten Jahren auch vermehrt erlebt, dass Wartungsarbeiten an der Stromversorgung zu Ausfällen oder ungeplanten Reboots der Server führten. Aus diesem Grund halte ich es für notwendig, dass man sich bereits im Voraus informiert, wann solche Wartungsarbeiten geplant sind, wie diese durchgeführt werden und wie häufig sie in den letzten Jahren notwendig waren. Im Optimalfall werden solche Wartungsarbeiten immer nur an einem Stromkreis vorgenommen, so dass es für die Server keine Ausfälle gibt.
 
Auch die Klimatisierung ist bei Rechenzentren häufig ein wunder Punkt. Da kann es dann schonmal vorkommen, dass im Sommer die Klimaanlage versagt und die Server wegen Überhitzung abschalten. Es ist daher für ein modernes Rechenzentrum absolut unerlässlich eine redundante Klima-Anlage zu verwenden. Fällt eine aus, übernimmt die andere.
 
Der häufigste Punkt, der gerade bei Startups gern vernachlässigt wird, ist der Support des Hosters. Egal ob man seine eigenen Server in einer Colocation abstellt oder Server anmietet, der Support ist eine Schlüsselstelle für die Verfügbarkeit der Systeme. Es sollte daher bei jedem Hosting ein SLA abgeschlossen werden, der eine möglichst geringe Reaktionszeit des Supports sicherstellt. Mehr als eine Stunde Reaktionszeit auf schriftliche Anfragen ist als kritisch anzusehen. Und auch beim Telefon-Support muss sicher sein, dass ein Auftrag entsprechend schnell an die Techniker weitergereicht wird.
 
Bleiben nur noch die Kapazitäten. Aber wieso sind die wichtig? Ganz einfach... Wenn das Produkt eines Startups tatsächlich einschlägt, muss ggf. das Netzwerk schnell vergrössert werden. Muss man erst mit seinen Servern in ein anderes Rechenzentrum umziehen oder gar mehrere Standorte miteinander vernetzen, weil das derzeit genutzte Rechenzentrum keine ausreichenden Kapazitäten mehr hat, kostet dies Zeit und Geld. Daher sollte sichergestellt werden, dass in verschiedenen Brandschutzzonen noch genug Raum ist um bei Bedarf weitere Server unterzubringen. Natürlich hängt es auch ein wenig vom Skalierungskonzept ab, ob dieser Punkt wichtig ist, doch dazu später mehr.

Die Hardware

Logischerweise bringt es auch wenig, wenn das Rechenzentrum zwar redundante Netzwerk- und Stromanbindung bereitstellt, die Server das aber nicht unterstützen. Nun ist allerdings das Problem, dass mehrere Netzteile und Netzwerkkarten zusätzliche Kosten verursachen und Startups möchten sich dieses Geld verständlicherweise gern sparen. Schließlich weiß man nicht, ob sich die Kosten jemals wieder einspielen, weswegen man die Kosten für die Server anfangs möglichst gering halten sollte. Kosten zu sparen ist daher absolut richtig, so lange man darauf achtet, dass die eingesetzte Hardware bei Bedarf später nachgerüstet werden kann.
 
Dennoch gibt es einige Komponenten eines Server-Netzwerks, die zwingend redundant sein müssen. Das sind vor allem Firewall und Loadbalancing. Alles andere kann man bei Bedarf auch softwareseitig redundant machen, indem man z.B. mehrere Systeme eines Typs bereitstellt. Doch auch dazu später mehr.
 
Im Gegensatz zu dieser Sparsamkeit steht der Drang vieler Startups bekannte Marken-Hardware zu nutzen, die zumeist wesentlich teurer ist als ihre unbekannteren Gegenstücke. Dabei ist auch bei den unbekannteren Server-Herstellern zumeist die gleiche Hardware verbaut wie bei IBM, HP und ähnlich bekannten Marken. Daher sollte man besser auf das Innenleben der Server achten anstatt auf das Label, das die Front ziert. Da Startups zumeist eh gern bei den Support-Kosten für Hardware sparen, und meiner Meinung nach ganz zu Recht, spricht kaum etwas für die Verwendung von Marken-Servern. Meine persönliche Erfahrung als Systemadministrator zeigte mir in der Vergangenheit sogar, dass kleinere Hersteller oft einen wesentlich besseren Support bieten, wenn es z.B. darum geht Betriebssysteme einzusetzen, die eigentlich nicht vom Hersteller unterstützt werden. Oft bekommt man sogar direkten Kontakt zu den Technikern, die die Server entwickeln. Das kann in manchen Situationen ein grosser Vorteil sein.

Skalierbarkeit

Sofern nicht bereits von Anfang an klar ist, dass der Markt für ein Produkt relativ klein und begrenzt ist, muss ein Startup immer damit rechnen, dass es in relativ kurzer Zeit sein Server-Netzwerk schnell nach oben skalieren können muss. Skalierbarkeit und vor allem die Fähigkeit schnell nach oben skalieren zu können ist somit essentiell. Hier ist ein fähiger System Engineer gefragt, der dies von Anfang an mit einplant. Da ein weniger technisch versiertes Management dies aber meiner Erfahrung nach schlecht einschätzen kann, möchte ich auf ein paar Techniken eingehen, die man nutzen kann um eine Skalierbarkeit zu gewährleisten und was es dabei zu beachten gilt.

Der Core

Jedes Netzwerk sollte einen festen Kern haben, der die durchschnittlich benötigte Leistung bereit stellt. Steigt die durchschnittlich benötigte Leistung, sollte auch diese Kern wachsen. Ich kann nur absolut davon abraten sich bei der Kern-Leistung eines Netzwerks auf Cloud-Plattformen zu verlassen, sofern das Netzwerk nicht komplett in einer Cloud läuft. Und wie der Name schon sagt, sollte dieser Kern auch die Kern-Komponenten des Netzwerks umfassen:
- Loadbalancing
- Security-Layer
- Caching-Layer
- Webserver
- Datenbank-Master
- Satellitensysteme (bei Bedarf)
Alle anderen Komponenten wie Storage sind, je nach Schutzanforderung, durchaus in einer Cloud gar nicht so falsch untergebracht. Auch muss der Kern des Netzwerks keineswegs immer auf den eigenen Servern laufen. Gerade beim Security-Layer und beim Loadbalancing ist es gar nicht so verkehrt externe Dienste mit einzubeziehen.
 
Natürlich müssen die eigenen Server durch eine Firewall und möglichst auch durch ein Angriffserkennungssystem gesichert sein. Aber Dinge wie DDoS-Schutz und Web Application Firewall sind oftmals bei entsprechend spezialisierten Anbietern wie Akamai oder Myra recht gut untergebracht. Diese haben wesentlich bessere Möglichkeiten und wesentlich mehr Ressourcen um bei Bedarf auch nach oben skalieren zu können. Auch das Loadbalancing muss nicht zwingend über eigene Loadbalancer laufen sondern kann z.B. mittels DNS-basiertem Loadbalancing erfolgen und somit dem DNS-Anbieter überlassen werden. Das ist vor allem dann von Vorteil, wenn man ein globales Loadbalancing benötigt, weil das Produkt, d.h. die Webapp, auf der ganzen Welt oder zumindest verteilt auf mehr als einem Kontinent genutzt wird. Auch Caching-Anbieter wie Akamai bieten zumeist Loadbalancing-Lösungen an.

Standby-Ressourcen

Ich halte das Prinzip der Standby-Server, die genutzt werden um Lastspitzen abzufangen, zumindest im Web-Bereich heutzutage für überholt. Sofern man den Datenschutz sicherstellt, kann man mittlerweile problemlos auf Cloud-Ressourcen zurückgreifen. So ist es zum Beispiel durchaus ratsam seinen Storage von Anfang an so zu planen, dass er Cloud-Ressourcen nutzt, wenn zu erwarten ist, dass die gespeicherten Daten permanent wachsen werden. Dadurch muss man keine Festplatten oder gar ganze Storage-Systeme bereit halten, die enorme Kosten verursachen solange sie nicht genutzt werden, denn Storage-Systeme gehören noch immer zu den teuersten Komponenten im Web-Bereich. Bei Cloud-Anbietern bezahlt man hingegen nur die tatsächlich genutzte Speichermenge. Bleibt das Wachstum aus, halten sich somit auch die Kosten in Grenzen.
 
Insgesamt haben sich durch Cloud-Computing für Anbieter von Webapplikationen heutzutage völlig neue Möglichkeiten für die Skalierung ergeben, von denen man vor einigen Jahren nur träumen konnte.

Die Cloud und ihre Nutzung

Wie bereits erwähnt haben die Möglichkeiten von Cloud-Computing auch im Web-Bereich viele Skalierungsprobleme gelöst. So muss ein Startup mittlerweile keine teuren Server mehr bereit stehen haben nur um Last-Spitzen bei Promo-Aktionen oder ähnlichem abzufangen. Wenn man einige Dinge beachtet, kann man solche Lastspitzen problemlos via Cloud-Instanzen abfangen. Doch muss auch dabei bereits bei der initialen Planung des Server-Netzwerk einiges beachtet werden.
 
Zuerst muss das Netzwerk natürlich die Möglichkeit bieten Cloud-Instanzen und/oder Cloud-Storage sinnvoll einzubinden. Da bei Webapplikationen die häufigsten Bottlenecks bei den Webservern und bei den Datenbanken liegen, wenn es zu einer Lastspitze kommt, müssen diese Komponenten von Anfang an entsprechend eingerichtet sein. Will man das Webserver-Netzwerk mittels Cloud-Instanzen erweitern können, muss dies vom Loadbalancer unterstützt werden. Dies ist nur dann gegeben, wenn das Loadbalancing es ermöglicht beliebige IPs als Webserver einzubinden. Die meisten Appliance-Lösungen unterstützen diese Möglichkeit nicht. Bei ihnen können nur Webserver in's Loadbalancing eingebunden werden, die direkt mit der Appliance verbunden sind. Daher sollte man besser einen "normalen" Server mit einem Software-Loadbalancer wie Varnish, HAProxy oder mod _ proxy _ balancer einsetzen, wenn man den Einsatz von Cloud-Instanzen als Webserver plant. Auch eine DNS-basierte Loadbalancing-Lösung macht wenig Sinn, wenn man auf die Cloud bei Lastspitzen setzen will. DNS-basierte Lösungen haben nämlich den Nachteil, dass sie eine Time-To-Life haben. Es braucht also eine gewisse Zeit, bis Änderungen am DNS überall verfügbar sind. In dieser Zeit kann so manche Lastspitze bereits längst vorbei sein.
 
Kurz gesagt: Die Schlüsselstelle für den Einsatz von Cloud-Instanzen als Webserver ist das Loadbalancing. Man sollte sich daher als Management nicht einfach für eine Lösung entscheiden, weil sie gerade als besonders preiswert erscheint oder von einem "Berater" hoch gelobt wird. Auch ist es zumeist wenig sinnvoll sich an anderen Unternehmen zu orientieren und sich für eine Lösung zu entscheiden nur weil diese so etwas einsetzen. Jedes Server-Netzwerk hat seine Eigenheiten und diese müssen beachtet werden. Gäbe es eine Standard-Lösung, bräuchte man keine System Engineers mehr und könnte nach einem standardisierten Verfahren Appliances dafür aufbauen, die jedes Unternehmen dann einsetzen könnte. Dass es solche "Web-Appliances" nicht gibt, zeigt deutlich genug, dass es auch keine Standards gibt, die für jede Webapplikation passend sind. Am besten ist man beraten, wenn man sich mit seinem System Engineer oder Sysadmin zusammensetzt und von Anfang an ein sinnvolles Skalierungskonzept ausarbeitet.
 
Ein gern vergessenener Punkt beim Einsatz von Cloud-Computing ist der Datenschutz. Überhaupt wird in vielen Startups dem Datenschutz zu wenig Bedeutung beigemessen, was letztendlich irgendwann zu Problemen führt. Gerade wenn man seine Webserver oder gar seine Datenbanken in eine Cloud auslagert oder diese mit Cloud-Instanzen erweitert, sollte man sich immer bewusst sein, dass dort personenbezogene und/oder personenbeziehbare Daten verarbeitet werden. So liegen zum Beispiel die Benutzerdaten wie Email-Adressen etc. in den Datenbanken und will man einen halbwegs vernünftigen Security-Layer aufbauen ist es notwendig, dass die Webserver auch die IP-Adressen für die Anfragen in Log-Dateien vermerken. Sobald personenbeziehbare oder gar personenbezogene Daten in der Cloud landen, ist ein sogenannten Auftragsdatenverarbeitungsvertrag mit dem Anbieter zwingend notwendig. Gleiches gilt übrigens auch bei der Zusammenarbeit mit Tracking-Anbietern und Anbietern von Werbung.
 
Nutzt man die Cloud ausschliesslich für seine Webserver, reicht es auch nicht, wenn man das Logging remote im eigenen Netzwerk machen lässt. Zum einen kann dies die Cloud-Instanzen enorm ausbremsen, zum anderen sieht der Cloud-Anbieter in seinem Routing trotzdem von welchen IPs Anfragen an die Instanzen weitergeleitet werden. Man ist daher nur dann auf der rechtlich sicheren Seite, wenn man immer einen Auftragsdatenverarbeitungsvertrag abschliesst, sobald man den Einsatz einer Cloud zum Abfangen von Lastspitzen plant.

Die Software

Neben der Inhouse entwickelten Webapplikation setzt jedes Unternehmen eine Reihe von Software ein, auf die sie nur begrenzt Einfluss hat. Gerade Startups neigen gern dazu hierbei immer zum neuesten Trend zu greifen. Das ist nicht immer verkehrt, sorgt es doch dafür, dass vor allem im Bereich der OpenSource-Software so manches Projekt ein paar starke Partner bekommt, doch ist auch eine gewisse Vorsicht geboten. Nicht jede Technologie, die gerade Trend ist, setzt sich dauerhaft auf dem Markt durch. Im schlimmsten Fall hat man irgendwann eine Software im Einsatz, die nicht mehr weiterentwickelt und somit auch nicht mehr mit Sicherheitsupdates versorgt wird. Wenn man sich einem Trend als Startup anschliesst, sollte man immer genau schauen welche anderen Unternehmen die gewünschte Software noch einsetzen, welche Partner das entsprechende Projekt hat und wie die finanzielle Ausstattung des Projekts aussieht. Denn auch im OpenSource-Bereich setzen sich Projekte auf dem Markt dauerhaft nur dann durch, wenn sie von grösseren Unternehmen eingesetzt werden und zuverlässige Finanzierungskonzepte haben. Ein Spenden-Button auf der Homepage reicht dabei jedenfalls nicht aus, wie man erst kürzlich am Beispiel von GPG sehen konnte. Obwohl diese Software von vielen Unternehmen zur Email- Verschlüsselung eingesetzt wird, stand es dennoch kurz vor dem Aus, denn es wird nur von einem einzelnen Entwickler weiter entwickelt und erst ein Hilfeschrei in den sozialen Netzwerken brachte genug Geld in die Kasse um die Weiterentwicklung zu gewährleisten. Wäre diese Hilfeschrei nicht erfolgt, würden viele Unternehmen jetzt eine Email-Verschlüsselung einsetzen, für die es keine Sicherheitsupdates mehr geben würde, was gerade in diesem Bereich ein enormes Problem wäre.
 
Doch auch bei der Inhouse entwickelten Software, also bei der eigenen Webapplikation sollte man ein paar Dinge beachten um nicht irgendwann in Probleme zu rennen. Auch hier sind die sensibelsten Punkte die Skalierbarkeit und der Datenschutz. Dass man Passwörter und Zahlungsdaten verschlüsseln sollte, haben glücklicherweise die meisten Unternehmen bereits begriffen. Doch wie sieht es zum Beispiel mit der Verteilung der Sessions auf mehrere Server aus oder überhaupt mit der Verfügbarkeit bestimmter Daten über Server- oder gar Standort-Grenzen hinweg. Leider machen sich darüber zu wenige Startups am Anfang Gedanken, was sie später zu aufwendigen Rewrites einzelner Komponenten zwingt, wodurch Kosten verursacht werden, die man sich hätte sparen können, wenn man von Anfang an an solche Probleme gedacht hätte. Leider suchen sich Unternehmen immer nur "lösungsorientiert arbeitende" Mitarbeiter. Dabei ist es durchaus wichtig Mitarbeiter zu haben, die ein problemorientiertes Denken haben, um frühzeitig auf kommende Probleme aufmerksam zu machen. Ich habe bereits zu oft Unternehmen erlebt, die immer jedes Problem, das von Mitarbeitern angesprochen wurde, kleingeredet haben, um im Endeffekt irgendwann genau in diese Probleme zu rennen, wodurch enorme Mehrkosten zur Behebung selbiger verursacht wurden. Es ist nunmal preiswerter sich schon am Anfang über ein sinnvolles Software-Design ein paar Tage Gedanken zu machen als später wochenlange Rewrites von Komponenten finanzieren zu müssen.

Typische Bottlenecks von Webapplikationen

Der RAM-Verbrauch

Bei der heutigen Rechenleistung von Servern stellt die CPU-Power kaum noch ein Problem dar. Brauchbare Server-Software ist in der Lage ihre Rechenleistung auf mehrere CPUs/Cores zu verteilen. Doch vor allem der Verbrauch des Arbeitsspeichers wird gerade bei Startups, die schnell mit einem Produkt an den Markt gehen wollen, schnell zu einem Problem. Unerfahrene Entwickler neigen dazu möglichst viele der Daten im RAM abzulegen, weil sie dort am schnellsten wieder verfügbar sind. Da kann es dann durchaus passieren, dass komplette Userdaten-Bestände dann mal kurzerhand in den RAM geladen werden. Logischerweise stellt das kein Problem dar, wenn man nur ein paar Hundert User hat. Aber wie sieht es aus, wenn die User-Anzahl in die Millionen geht? Dann wird diese Vorgehensweise schnell zum Problem und ein nicht unerheblicher Teil der Software muss umgeschrieben werden. Lädt man Daten, die einem stetigen Wachstum unterliegen, in den RAM, sollten dafür entsprechende Caching-Layer genutzt werden.
 
Für diese Zwecke gibt es Software wie Memcached, die darauf spezialisiert ist auch grosse Datenmengen mit einer halbwegs sauberen Struktur im Arbeitsspeicher zu verwalten. Kaum eine Webapplikation kommt daher heutzutage ohne Memcache-Server aus. Dabei sollte aber beachtet werden, dass ein Crash oder auch ein Abschalten des Servers zum Verlust dieser Daten führt. Memcache-Server sind also nicht dazu geeignet Daten zu halten, die für die Verfügbarkeit der Webapp essentiell sind. Leider ist es noch immer üblich Session-Daten in Memcache-Servern abzulegen. Muss dann der Memcache-Server neu gestartet werden, gehen diese Daten verloren. Für den User heisst dies, dass er ohne Vorwarnung ausgeloggt wird. In den meisten Unternehmen wird das dadurch gehandhabt, dass ein Sysadmin ankündigen muss, wenn er den Memcache neu starten muss. Sogenannte "geplante Downtimes" entstehen... unnötigerweise.
 
Man schränkt die Systemadministration dadurch ein. Dies kann aber nicht der richtige Weg sein, wenn man eine agile und hochverfügbare Plattform betreiben will. Die Systemadministration muss für eine immer aktuelle Plattform sorgen können um schnell auf Sicherheitsrisiken und ähnliches reagieren zu können. Sorgt das Design der eigenen Webapplikation dafür, dass Restarts von Komponenten nur nach vorheriger Ankündigung erfolgen können, ist dies im Prinzip nicht mehr möglich und es liegt ein sichtbarer Design-Fehler vor. Es schränkt die Agilität der Produkt-Entwicklung ein, was durchaus auch in den Bereich der Bottlenecks fällt. Agile Software-Entwicklung betrifft nunmal nicht nur die Programmierung sondern auch den Betrieb, was leider in vielen Unternehmen noch immer nicht angekommen ist.
 
Die Lösung für dieses Problem besteht hauptsächlich aus 4 Teilen
1. kleine Software-Komponenten
2. keine Fixierung von Datenzugriffen auf IP-Adressen
3. Message-Bus-Systeme
4. Software-Optimierungen
 
In der heutigen Welt des WWW besteht eine Webapplikation aus vielen kleinen Subsystemen. In der Praxis sieht das so aus, dass der User auf ein Kernsystem zugreift, welches sich die zur Beantwortung der Anfrage benötigten Daten bei spezialisierten Satellitensystemen abholt. Das bedeutet nicht, dass das Kern-System sich seine Daten aus verschiedenen Datenbanken einsammelt, sondern dass es die Daten bereits fertig aufbereitet über wohl definierte Schnittstellen (API) von anderen Applikationen bekommt. Schliesslich lassen sich mit entsprechenden Frameworks Daten, die bereits als XML oder ähnliches aufbereitet sind, weitaus schneller verarbeiten als die Rohdaten aus einer Datenbanken. Ausserdem können die Satellitensysteme eigene Caching-Layer, die für ihre Art der zu verarbeitenden Daten spezialisiert sind, implementieren, wodurch Datenbanken entlastet werden. Ein weiterer Vorteil dieser Satellitensysteme ist, dass sie in einer für ihre Aufgabe bestens geeigneten Programmiersprache umgesetzt werden können. Auch können solche Satellitensysteme später bei Bedarf problemlos an externe Dienstleister zur Weiterentwicklung übergeben werden, wodurch man sich besser auf das eigene Kerngeschäft konzentrieren kann. Und Kosten kann man häufig auch noch einsparen, denn so manches Satelliten-System ist bei einem Freelancer weitaus besser aufgehoben als bei fest angestellten Entwicklern. Gerade bei solchen kleinen "Datenzulieferern" kommt irgendwann der Punkt, wo der Entwickler nichts oder nicht mehr viel zu tun hat. Und dann hat man einen Entwickler mit festem Vertrag, der eigentlich nur noch Däumchen dreht oder anderweitig eingesetzt, d.h. in andere Komponenten eingearbeitet, werden muss. 
 
Warum aber sollte man sich nicht auf IP-Adressen fixieren? Nun... jede Applikation, die auf verteilten Systemen mit einer anderen Applikation kommuniziert, tut dies üblicherweise über das Netzwerk. Aber nicht jede Netzwerk-Komponente ist in der Lage sich die IP von einem anderen System zu nehmen, wenn dieses mal ausfällt. Betreibt man aber für sein Server- Netzwerk einen eigenen DNS-Server (natürlich auch redundant ausgelegt), hat man ein System, das jederzeit für eine Adresse eine neue IP zuordnen kann. Ein Systemadministrator, der ein System aus irgendwelchen Gründen kurz vom Netz nehmen muss, ist mit einem solchen DNS-Server in der Lage jederzeit die Anfragen der Server auf eine andere IP umzuleiten, wenn alle Komponenten nur über Namen, die durch das DNS aufgelöst werden, miteinander kommunizieren. Das Netzwerk wird dadurch insgesamt wesentlich flexibler und Downtimes werden vermieden.
 
Unsere dritte Komponente, die für die Skalierung unserer Software eine Rolle spielt, ist das Message-Bus-System. Dabei handelt es sich um eine Software, die auf jedem Server läuft und über die verschiedene Komponenten miteinander kommunizieren können. Jedes halbwegs vernünftige Cluster-System nutzt heutzutage solche Message-Bus-Systeme um Daten zwischen den Knoten des Clusters auszutauschen oder Aufgaben auf mehrere Systeme zu verteilen. Der Vorteil davon liegt klar auf der Hand. Eine Komponente sendet eine Nachricht an ein solches System und eine andere Komponente, die sich für die Aufgabe als zuständig betrachtet, nimmt sich dieser an, wenn es ausreichend Ressourcen zur Abarbeitung zur Verfügung hat. Die Verteilung von Aufgaben kann dadurch maximal dynamisiert werden und man muss sich nicht mehr darum kümmern welche Systeme verfügbar sind und unter welcher Adresse man diese erreichen kann. Die Applikation kommuniziert dann primär mit ihrem lokalen Message-Bus. Das ist nicht in allen Fällen möglich, weswegen wir das DNS für jene Fälle verwenden, in denen es nicht möglich ist. Aber gerade die Kommunikation zwischen den Satelliten-Systemen kann dadurch drastisch vereinfacht werden.
 
Zu guter Letzt bleiben noch die Optimierungen. Leider ist das ein Thema, das in vielen Unternehmen noch zu sehr auf die leichte Schulter genommen wird. Man versucht alles durch Rechenleistung zu erschlagen, wenn es irgendwo zu Engpässen kommt. Im Endeffekt sorgt diese Strategie aber nur für dauerhaft höhere Kosten. Investiert man hingegen einmalig etwas Zeit in notwendige Optimierungen, verursacht dies auch nur einmalige Mehrkosten. Zweifellos gibt es Bereiche, in denen Optimierungen manchmal mehr kosten als der Jahre lange Betrieb von zusätzlichen Servern, aber meiner Erfahrung nach ist dies nur in sehr wenigen Fällen gegeben. Ein paar Optimierungen bei den Datenbank-Abfragen haben schon so manchem Unternehmen monatliche Mehrkosten von mehreren Hundert Euro gespart, die sonst für den Betrieb zusätzlicher Datenbank-Server angefallen wären. Optimierungen können so zu einer umfangreichen Senkung der Hosting-Kosten führen. Und schneller als man denkt hat man so das Gehalt für einen Mitarbeiter beim Hosting gespart.
 
Natürlich sind auch dies keine Standard-Lösungen. Wie immer gilt auch bei solchen Maßnahmen, dass man die Relationen betrachten muss. Nicht immer macht das Auslagern einer Aufgabe in ein eigenes Satelliten-System Sinn, nicht immer ist ein Message-Bus die beste Lösung und auch Optimierungen können manchmal teurer werden als der Betrieb eines zusätzlichen Servers. Daher ist es wichtig, dass man sich schon bei der Konzeptionierung einer Webapp darüber Gedanken macht welche Aufgaben wie hohe Kosten verursachen, und wo bestimmte Technologien eingesetzt werden müssen um spätere Probleme zu vermeiden. Hierbei sind erfahrene Software-Designer und erfahrener System Engineers gefragt, die entsprechende Kosten-Nutzen-Rechnungen aufstellen können.

Die Datenbanken

Ein weiteres häufiges Problem stellen die Datenbanken für eine Webapp dar, vor allem dann, wenn man eine stetig wachsende Datenmenge hat. Gerade relationale Datenbanken stossen bei bestimmten Datenmengen irgendwann an ihre Grenzen. Und dabei sind keineswegs die Datenbanken selbst das Problem sondern zumeist das Software-Design und die Art und Weise wie man die Daten zwischen den Datenbank-Servern verteilt.
 
Vor allem beim Software-Design legen nur wenige Webentwickler Wert auf die Performance der Datenbank-Anfragen. Die Ursache dafür ist, dass üblicherweise Datenbank-Administratoren (DBA) für solche Dinge zuständig sind. Nun kann sich aber kaum ein Startup einen extra DBA leisten, weswegen es dort dazu führt, dass selbst relativ kleine Datenmengen irgendwann die DB-Server in Bedrängnis bringen. In einem Startup muss der CTO daher darauf achten, dass die Performance der DB-Abfragen stimmt. Sonst werden ziemlich bald unnötig viele DB-Server benötigt, die trotzdem auf Dauer nicht mit der Last klar kommen. Bewährt hat es sich, dass einem Entwickler oder der Systemadministrator die Aufgabe übertragen wird sämtliche in der Webapp verwendete DB-Anfragen zu dokumentieren und ihre Performance zu überprüfen. Die meisten DB-Systeme stellen entsprechende Funktionen oder Tools zur Verfügung um die Effizienz der Anfragen zu prüfen.
 
Doch auch bei der Verteilung der Datenbanken auf mehrere Server gibt es einige Dinge, die beachtet werden müssen. Üblicherweise nutzt man im Bereich der relationalen Datenbanken eine sogenannte Replikation um die Daten auf mehrere Server zu verteilen. Dabei werden dann die Master-Server genutzt um Schreibzugriffe auf diesen zu machen und die Slave-Server verarbeiten die lesenden Anfragen. Natürlich muss dies bereits beim Design der Webapp beachtet werden, denn sie muss die Anfragen entsprechend verteilen. Doch wird dabei gern vergessen, dass sämtliche Daten auch auf den Slave-Servern geschrieben werden müssen. Schliesslich müssen die Daten ja irgendwie auf diese kommen. Die Slave-Server sind daher einer zusätzlichen Belastung ausgesetzt. Auch wenn die Schreibzugriffe nicht 1 zu 1 auf diese übertragen werden, sorgt die Übertragung der Daten doch immer dafür dass ca. 20-30% der Auslastung durch Schreibzugriffe verursacht wird, wenn sich die Daten häufig ändern. Dieses Konzept macht daher nur dann Sinn, wenn man beim Design der Webapp darauf achtet, dass Datenänderungen nicht allzu häufig stattfinden. Daten, die sich sehr häufig ändern, sollten, soweit dies möglich ist, nicht in relationalen Datenbanksystemen abgelegt werden. Solche Daten sind in sogenannten NoSQL-Datenbanken besser aufgehoben oder sollten nur in regelmässigen Intervallen aus einem Memcache-Server in die DB synchronisiert werden. Entscheidet man sich für letzteres müssen natürlich die weiter oben beschriebenen Eigenheiten von Memcache-Servern beachtet werden, weswegen man zumeist mit NoSQL-Datenbanken besser beraten ist.
 
Die Alternative dazu stellen echte DB-Cluster dar. In diesen werden die Daten zwar auch repliziert, aber nur dann, wenn ein Knoten des Clusters ausreichend Ressourcen dafür zur Verfügung hat. Ein Management-Knoten leitet die Anfragen dann nur auf jene Server weiter, die die angefragten Daten auch zur Verfügung haben. Der Nachteil solcher DB-Cluster ist allerdings, dass der administrative Aufwand für sie wesentlich höher ist als für eine einfache Datenbank-Replikation. Cluster machen daher üblicherweise nur dann Sinn, wenn ein DBA für die Verwaltung zur Verfügung steht.

Warnungen des Codes

Auch Warnungen, die der Code in den Servern auflöst werden immer wieder gern vernachlässigt. So seltsam dies auch klingen mag, aber diese Warnungen werden irgendwann zu einem ernsthaften Problem und Bottleneck. "Das sind doch nur Warnungen" ist daher eine Aussage, die man als CTO eines Startups niemals akzeptieren sollte. Häufen sich solche Warnungen später, sind die Server immer mehr mit dem Logging beschäftigt, was wertvolle Ressourcen kostet und unnötig hohe Input/Output-Last verursacht. Geschwindigkeitseinbußen von 20% und mehr sind durchaus möglich, wenn man solche Warnungen nicht rechtzeitig beseitigt. Das Monitoring sollte sicherstellen, dass Warnungen, die in den Servern verursacht werden, prinzipiell an die Entwickler gemeldet werden. Und diese müssen verpflichtet sein, solche Warnungen innerhalb einer annehmbaren Zeit zu beheben.

Zusammenfassung

Abschliessend kann man also feststellen, dass es durchaus Sinn macht, sich bereits vor den ersten Zeilen Code, die geschrieben werden, genaue Gedanken um das Software- und Netzwerk-Design zu machen. Beides ist untrennbar miteinander verbunden. Das beste Marketing bringt nichts, wenn die Software nicht in der Lage ist, die dadurch aufkommende Last auf den Servern später auch zu handhaben. Und viele Kosten lassen sich sparen, wenn man von Anfang an ein paar grundlegende Dinge beachtet. Es muss an dieser Stelle aber auch ganz klar gesagt werden, dass es keine Standard-Lösungen gibt, die für jedes Netzwerk anwendbar sind. Die hier genannten Eckpunkte sind daher nur als Orientierung zu betrachten und sollen die Aufmerksamkeit auf ein paar Faktoren lenken, die häufig in Startups vernachlässigt werden. Meine Erfahrung ist, dass zumeist unnötig hohe Kosten verursacht werden, wenn man diese Eckpunkte nicht beachtet. 
Kommentare (0) - Kommentar schreiben

Server-Monitoring - aber richtig

Vor allem junge Kollegen fragen mich immer wieder, wie man das Monitoring für ein Server-Netzwerk richtig aufbaut und welche Parameter überwacht werden sollten. Ein Patentrezept kann ich da natürlich auch nie geben, da dies auch immer zu gewissen Teilen vom Netzwerk abhängt, aber es gibt ein paar Richtlinien, die man einhalten sollte. Auf diese will ich im folgenden etwas eingehen.

Verfügbarkeit von Diensten

Einer der wichtigsten Punkte ist immer die Verfügbarkeit der Dienste, die das Netzwerk anbietet. Hierbei sollte der Fokus auf jenen Diensten liegen, die für das angebotene Produkt essentiell sind. Bei einer Webapplikation wären das zum Beispiel die Webserver, die Caching-Server, die Servlet-Container (sofern im Einsatz), das CDN, die Datenbanken und zumeist auch die Mailserver, über die die Webapplikation Emails versendet. 

Dabei reicht es aber nicht aus nur sicherzustellen, dass die Dienste laufen. Wichtig ist, dass sie die gewünschten Daten auch wirklich ausliefern. Allzu häufig beschränkt sich das Verfügbarkeitsmonitoring in Firmen auf die Erreichbarkeit von Diensten. Ein Webserver zum Beispiel kann jedoch durchaus eine Seite ausliefern, ohne dass diese einen Inhalt hat. Als Resultat bekommt der User dann nur eine weisse Seite zu sehen. Das gilt es natürlich zu vermeiden.

Aus diesem Grund nutze ich für das Verfügbarkeitsmonitoring eingebaute "Pings" um die Richtigkeit des Inhalts sicherzustellen. Das bedeutet, dass die Entwickler in die Seiten, die ein Webserver ausliefert, immer einen HTML-Kommentar mit dem Inhalt "PING" einbauen. Da es sich um einen Kommentar handelt, bekommt ein User diesen nur zu Gesicht, wenn er sich den Quelltext der Seite anschaut. Er bleibt also weitestgehend unsichtbar für normale Nutzer. Mein Monitoring hat dadurch die Möglichkeit zu prüfen, ob im Inhalt dieser Kommentar auch vorhanden ist. Ist dies nicht der Fall, stimmt etwas mit dem Inhalt nicht, und ein entsprechender Alarm wird ausgelöst.

Ähnliche Vorgehensweisen nutze ich auch bei Applicationservern und dem CDN. Bei letzterem ruft mein Monitoring immer einen bestimmten Inhalt ab und prüft, ob die MD5-Checksumme identisch mit dem erwarteten Ergebnis ist. Auch hierbei wird ein Alarm ausgelöst, wenn die Checksummen-Überprüfung fehlschlägt. Denn das deutet darauf hin, dass die vom CDN ausgelieferten Inhalte fehlerhaft sind.

Etwas komplizierter wird es, wenn Dienste keine abfragbaren Inhalte haben. Mailserver sind dafür ein gutes Beispiel. Bei solchen Diensten kann man die korrekte Funktionalität nur prüfen, indem man sie auf dem üblichen Weg nutzt. Im Fall eines Mailservers bedeutet dies, dass man eine Email über den Mailserver versendet und prüft, ob sie korrekt bei der Empfängeradresse zugestellt wurde. Mit einem guten Monitoring ist so etwas problemlos umsetzbar, auch wenn man dafür zumeist seine eigenen Plugins schreiben muss. Dennoch ist es ratsam sich diese Arbeit zu machen. Man will schliesslich nicht, dass erst die User den Support darauf aufmerksam machen müssen, wenn mit der eigenen Plattform etwas nicht stimmt. 

Allzu gern werden Systemdienste beim Monitoring vergessen, was in der Folge immer wieder zu Problemen führt. Solche Dienste sind zum Beispiel der Cron-Daemon, der Logging-Daemon des Systemkernels, der SSH-Service und ähnliches. Da solche Dienste oftmals keine Daten nach außen reichen, sollte zumindest auf den Servern geprüft werden, ob diese laufen und ob sie eventuell Fehler in den Logs verursachen (siehe dazu auch den Abschnitt "Log-Monitoring").

Nicht zuletzt sollte auch überwacht werden, ob die Infrastruktur des Rechenzentrums korrekt funktioniert. Nicht selten kommt es vor, dass Dienste zwar innerhalb des Rechenzentrums erreichbar sind und korrekt funktionieren, ein Zugriff von außen aber nicht möglich ist. Daher sollte ein gutes Monitoring-System immer auch über eine Instanz verfügen, die in einem anderen Rechenzentrum angesiedelt ist. Mit dieser kann man dann prüfen ob die gewünschten Dienste auch "von außen" erreichbar sind und eine annehmbare Antwortzeit haben.

Performance-Monitoring

Ein weiterer wichtiger Faktor beim Monitoring ist die Performance der Server. Nicht selten kommt es vor, dass Dienste nicht mehr erreichbar sind, weil die Server schlicht überlastet sind oder weil der Speicher ausgeht. Daher ist es notwendig bestimmte Parameter im Blick zu behalten. Diese sind vor allem:

- verbrauchte CPU-Leistung
- RAM-Verbrauch
- Festplattennutzung
- Netzwerk-Durchsatz
- Antwortzeit der Dienste

Bei diesen 4 Punkten sollte ein Alarm an den zuständigen Systemadministrator gehen, wenn sie zu 80% belegt sind oder, im Falle der Antwortzeiten von Diensten, die Zeiten zu hoch werden. So hat man noch etwas "Puffer" um entsprechende Gegenmaßnahmen zu ergreifen. 

Es kann aber auch noch einige andere Faktoren geben, die von den jeweilig eingesetzten Server-Applikationen abhängig sind. So macht es z.B. bei PHP-Applikationen durchaus Sinn zu prüfen, wie viel RAM ein einzelner Request aktuell verbraucht, damit man nicht die Memory-Limits, die von der PHP-Konfiguration festgelegt sind, überschreitet. Bei Java-basierten Anwendungen sollte man auch die Speicherwerte der Applikationen überwachen um die durch die Java-VM vorgegebenen Werte nicht zu überschreiten. Und bei Caching-Servern ist es logischerweise notwendig die Belegung des Cache im Blick zu behalten. Bei Mailservern wiederum sollte man die Anzahl der verschickten Emails überwachen um mitzubekommen, wenn diese ungewöhnlich hoch werden.

Security-Monitoring

Ein häufig vernachlässigter Punkt bei der Überwachung von Server-Netzwerken ist die Sicherheit der Server. In vielen Unternehmen geht dies über einen täglichen Rootkit-Check selten hinaus. Allerdings ist es bereits zu spät, wenn ein Rootkit auf einem Server entdeckt wird. Will man den wieder weg bekommen, muss man den entsprechenden Server komplett neu einrichten, denn es ist in den meisten Fällen nicht nachvollziehbar, was sonst noch in's System eingeschleust wurde.

Daher sollte ein Host Intrusion Detection System (kurz: HIDS) eingesetzt werden, um Veränderungen am System sofort zu bemerken. Solche Systeme überwachen dauerhaft das Dateisystem auf ungewollte Änderung und geben einen Alarm aus, wenn eine solche Änderung erkannt wird. Ausserdem überwachen gute HIDS auch die Logdateien auf ungewöhnliche Meldungen und informieren den zuständigen Administrator, wenn sie entsprechende Anomalien erkennen. 

Log-Monitoring

Allerdings reicht ein HIDS als Log-Monitoring nicht aus. Um ein echtes Log-Monitoring zu erhalten sollte man sämtliche Fehler, auch jene, die nicht sicherheitsrelevant sind, im Blick behalten. Ich habe in meiner Berufslaufbahn bereits einige Webapplikationen erlebt, die scheinbar von heute auf morgen regelmässig die Webserver zum Absturz brachten. Ursache dafür war in vielen Fällen ein Aufeinandertreffen verschiedener Fehler, die man nie im Blick behalten bzw. ignoriert hatte. 

Daher empfehle ich ein explizites Log-Monitoring über Applikationen wie Logstash oder ähnliche. Diese sollten Alarm-Meldungen auslösen, wenn die Fehler mit dem Level "Warning" in den Logs pro definierter Zeiteinheit ein bestimmtes Maß überschreiten. Bei kritischen Fehlern (Critical) sollte sofort ein Alarm ausgelöst werden. 

Vor allem über Fehler vom Level "Warning" gehen Techniker gern hinweg. "Das sind doch nur Warnungen. Die kann man ignorieren." heisst es dann häufig. Meine Erfahrung ist, dass man diese nur bis zu einem bestimmten Maß ignorieren kann. Besser ist es aber immer, wenn man die Ursache dieser Warnungen erforscht und sie schnellstmöglich behebt. Denn allzu oft sind sie Hinweise darauf, dass im System etwas nicht stimmt, was in naher Zukunft kritisch werden kann.

Nachwort

Das sind also die wichtisten Faktoren, die man beim Monitoring von Server-Netzwerken beachten sollte. Logischerweise kann es weitere Faktoren geben, die vom jeweiligen Netzwerk abhängig sind. Für einen Systemadministrator ist es wichtig sich über sämtliche Faktoren Gedanken zu machen. Dabei sollten auch das Office-Netzwerk und Test-Umgebungen nicht unbeachtet bleiben. Sysadmins neigen dazu diese immer etwas stiefmütterlich zu behandeln. Allerdings kann ein gutes Monitoring bei Test-Netzwerken bereits Schwierigkeiten im späteren Live-Betrieb vermeiden. Und die Kollegen sind auch wesentlich glücklicher, wenn sie die Sysadmins nicht erst darauf aufmerksam machen müssen, wenn der Drucker mal wieder spinnt oder leer ist. Wie bereits gesagt kann ich kein Patent-Rezept für's Monitoring liefern. Doch ich hoffe, dass Berufseinsteiger oder auch die verantwortlichen Manager durch diesen Artikel ein Bild davon bekommen worauf sie beim Monitoring ihre Aufmerksamkeit lenken müssen.

Sollten Sie ein individuelles Monitoring für Ihre Server benötigen, können Sie sich gern an mich wenden. Ich betreibe eine eigene Infrastruktur für verschiedene Monitoring-Lösungen und kann diese je nach Bedarf um individuelle Checks für Ihre Server erweitern. 

Kommentare (0) - Kommentar schreiben

Redundanz für Web-Plattformen

Verfügbarkeit ist heutzutage das A und O für jede Plattform im World Wide Web. Anwender kennen im Prinzip kaum noch den Zustand, dass eine Plattform nicht verfügbar ist. Und wenn es dann doch mal einen Ausfall gibt, verbreitet sich das binnen Sekunden über soziale Medien wie Twitter selbst bei den Usern, die gerade nicht auf der Seite unterwegs sind. Umso wichtiger ist es, dass man Redundanz bei seiner Webapp sicherstellt.

Nun ist "Redundanz sicherstellen" leicht gesagt. Leider denken viele, dass es damit getan ist, wenn alle Systeme mehrfach vorhanden sind. Dass es damit nicht getan ist, wird oft erst dann bemerkt, wenn es zu einem Ausfall kommt.

Die Anbindung

Der Einstiegspunkt bei jedem Netzwerk, das an das Internet angebunden ist, ist die Anbindung des Rechenzentrums, in dem die Server stehen. Um Kosten zu senken, wird gerade bei dieser Anbindung gern gespart. Ein typischer Fehler ist, dass nur ein Peering-Provider genutzt wird. Das bedeutet, dass die Verteilung des Traffics im Internet nur durch einen Anbieter durchgeführt wird. Doch auch Peering-Provider sind vor Ausfällen nicht geschützt.

Daher ist es wichtig, dass das verwendete Rechenzentrum nicht nur mit einem Peering-Anbieter kooperiert sondern mindestens 3 Peers zur Verfügung hat. Gleichermaßen wichtig ist es, dass nicht nur das Rechenzentrum entsprechend angebunden ist, sondern auch den Servern diese Lösung zur Verfügung gestellt wird. Meiner Erfahrung nach hat man bei vielen Colocation-Angeboten die Möglichkeit die Anzahl der verfügbaren Peers mitzubestimmen. Damit sind entsprechende Kosten verbunden. Gern wird nun an dieser Stelle gespart und man nutzt lieber nur einen Peer anstatt mehrere. Fällt dieser Peer mal aus, bedeutet dies, dass die gesamte Plattform nicht mehr erreichbar ist. Der Worst Case ist also vorprogrammiert.

Daher darf die Anbindung niemals als Einsparpotential genutzt werden. Da gibt es besser Möglichkeiten, auf die ich später noch eingehen werde.

Das Loadbalancing

Dass Loadbalancer verwendet werden, ist heutzutage bei den meisten Webplattformen Standard. Doch auch hier wird gern bei der Anbindung dieser Systeme gespart. So habe ich bereits häufiger erlebt, dass für 2 Loadbalancer, die theoretisch eine volle Redundanz ermöglicht hätten, nur eine Leitung zum Backbone zur Verfügung stand. Das führt natürlich dazu, dass beim Ausfall eines Loadbalancers erst das entsprechende Kabel in den anderen gesteckt werden musst. Und schon war die Redundanz wieder dahin.

Auch sollten Loadbalancer immer so aufgebaut sein, dass sie ihre aktuellen Cluster-Konfigurationen untereinander synchronisieren. Nur so kann eine lückenlose Umschaltung auf ein Hot-Standby-System erfolgen.

Das Caching

Viel zu wenig Zeit investieren Firmen in anständige Konzepte zum Caching ihrer Daten. Dabei sind gute Caching-Layer ein enormer Faktor, wenn es um die Entlastung der Systeme und auch die Verfügbarkeit geht. Bei News-Portalen und ähnlichen Seiten, wo eine Benutzer-Interaktion nur begrenzt stattfindet, können im Prinzip sämtliche Inhalte selbst dann noch vom Caching-Layer ausgeliefert werden, wenn alle Webserver, die diesen Layer füttern, nicht mehr verfügbar sind. Ich hatte das Glück bereits in Unternehmen zu arbeiten, in denen das vorbildlich umgesetzt ist. Dort konnten wir für Systemupdates, die ein Reboot aller Systeme notwendig machten, ganze Netzwerk-Segmente für Stunden trennen ohne dass die Auslieferung der Inhalte zum Anwender dadurch negativ beeinflusst wurde. Mit anderen Worten: Der Anwender hat von unserer Downtime gar nichts bemerkt, weil der Caching-Layer weiterhin die Inhalte auslieferte.

Allzu häufig findet man aber Netzwerke, in denen nur statische Inhalte im Caching landen. Doch was nutzt es, wenn die Bilder zwar noch ausgeliefert werden, die zugehörigen Texte und HTML-Inhalte aber nicht mehr? Daher ist es notwendig sich bei einer Web-Plattform genaue Gedanken zum Caching zu machen. Inhalte, die keine Benutzer-Interaktion benötigen sollten ohne Session-Bindung ausgeliefert werden. Denn alles, was an Sessions gebunden ist, kann nur begrenzt im Cache landen. Will man auch Session-gebundene Daten cachen, muss entsprechend mehr Caching-Speicher eingeplant werden. Allerdings wird eine Redundanz durch Caches damit quasi verhindert, da jede Session eigene Daten benötigt.

Datenbanken

Doch nicht nur die ausgelieferten Daten sollten im Caching-Konzept beachtet werden. Ein nicht zu unterschätzender Punkt sind auch die Daten, die von den Datenbanken an die Webserver gereicht werden. Um eine optimale Performance aus Datenbanken zu holen sind Faktoren wie der Query-Cache nicht zu unterschätzen. Da dies aber für die Redundanz nur bedingt relevant ist, will ich an dieser Stelle darauf nicht weiter eingehen. Wichtiger ist ein zwischen Datenbanken und abfragenden Servern eingesetzter Caching-Layer, den man leider noch relativ selten in Unternehmen findet. Es gibt Projekte wie mysql-cache, die es ermöglichen die Ergebnisse von SELECT-Abfragen im RAM des Webservers zu halten. Damit können Inhalte selbst dann noch von der Webapplikation abgefragt werden, wenn die Datenbank-Server nicht mehr zur Verfügung stehen.

Bei Datenbanken gibt es aber auch noch andere Faktoren für die Redundanz. Einer der wichtigsten ist wohl die Replikation der Daten zwischen mehreren Datenbank-Servern. Nur so ist es möglich, dass mehrere Datenbank-Server gleichzeitig von einer Webapplikation genutzt werden können. Dabei muss beachtet werden, dass auch Fehler gegebenenfalls repliziert werden. Leider wird das in den meisten Unternehmen nicht beachtet. Meine Empfehlung ist, dass immer ein Datenbank-Server mitläuft, bei dem die Replikation verzögert um ca. 30 Minuten erfolgt. So muss man bei der Restaurierung der Daten nach einem Fehler nicht auf ein vermutlich mehrere Stunden altes Backup zurückgreifen und hat ein Backup, das maximal 30 Minuten alt ist. Meiner Erfahrung nach werden replizierte Fehler (nicht zu verwechseln mit Replikationsfehlern), also Fehler bei denen falsche Daten über alle Cluster-Knoten hinweg verteilt wurden, üblicherweise binnen 30 Minuten erkannt, weil die Webapplikation nicht mehr so funktioniert wie erwartet. Hier ist natürlich auch ein gutes Monitoring gefragt.

Doch auch das Zusammenspiel zwischen Webservern und Datenbanken spielt für die Redundanz eine wichtige Rolle. Leider findet man häufig ein Setup, wo es einen oder zwei Master-Server gibt und jeder Webserver hat einen Slave-Server zugeordnet. Ich persönlich halte ein solches Setup nur bedingt für brauchbar. Grund dafür ist, dass beim Ausfall eines Slave-Servers auch der zugehörige Webserver im Prinzip ausfällt. Solche Abhängigkeiten zwischen 2 Layers sind unnötig. Ursächlich dafür ist meiner Erfahrung nach, dass die Webapplikationen in vielen Unternehmen so programmiert werden, dass sie nur zwischen einem Master- und einem Slave-Server unterscheiden können. Auf diese Weise werden Schreibzugriffe auf den Master-Server gelenkt, die lesenden Zugriffe erfolgen dann logischerweise auf dem Slave.

Zuerst einmal möchte ich sagen, dass ich es bevorzuge, wenn 2 Master-Server zur Verfügung stehen, die untereinander mittels einer Master-Master-Replikation verbunden sind. Steht nur ein Master zur Verfügung und fällt dieser aus, ist der administrative Aufwand relativ hoch um einen Slave zum Master zu machen. Die Folge ist eine Downtime von mehreren Minuten, in der auf allen Webservern der Master-Server gewechselt werden muss.

Die feste Zuordnung zwischen Webservern und Slave-Servern halte ich für unnötig. Zum einen muss dann auch für jeden Webserver ein eigener Caching-Layer gepflegt werden, sofern man einen solchen verwenden möchte. Zum anderen besteht das bereits angesprochene Problem, dass mit dem Ausfall des Slave-Servers auch der zugehörige Webserver ausfällt. Sinnvoller ist, wenn alle Webserver auf einen zentralen MySQL-Gateway zugreifen, der die Anfragen auf die Slaves entsprechend verteilt. Dadurch ist es auch möglich die Zugriffe auf die Slave-Server zu gewichten, so dass kleinere Maschinen mit weniger Anfragen belastet werden als grössere. Vor allem wenn ein Unternehmen wächst, will man nicht immer alle DB-Server austauschen, wenn diese mal vergrössert werden müssen. Man möchte üblicherweise auch die bereits vorhandenen Server weiter nutzen. Da diese aber zumeist etwas kleiner sind als die neuen Rechner, ist eine Gewichtung der Anfragen, d.h. die Menge der Anfragen, die ein Server verarbeiten muss, notwendig.

Weiterhin ermöglicht ein MySQL-Gateway auch das Caching von lesenden Zugriffen. So ist es möglich einen Caching-Layer aufzubauen, der selbst dann noch die Daten ausliefert, wenn an den Datenbank-Servern Wartungsarbeiten notwendig sind.

Doch natürlich muss auch ein solcher Gateway redundant sein. Schliesslich würden sonst gar keine DB-Zugriffe mehr möglich sein, sobald der Gateway ausfällt. Hierfür gibt es 2 verschiedene Lösungsansätze.

Beim ersten Lösungsansatz werden einfach mehrere Gateway zur Verfügung gestellt und die Webapplikation rotiert selbstständig durch eine Liste der verfügbaren Gateways. Dabei prüft sie natürlich, ob der aktuell verwendete Gateway auch erreichbar ist. Ähnliches kann man natürlich auch machen um durch eine Liste der Slave-Server zu rotieren, wenn man auf Gateways, und damit auf ein Caching, verzichten will. Nachteil ist allerdings, dass durch die Prüfung der Erreichbarkeit die Auslieferung der Daten um einige Millisekunden verzögert wird, was sich im Endeffekt auf die Performance bei der Auslieferung auswirkt.

Beim zweiten Lösungsansatz wird ein Heartbeat-System verwendet. Das bedeutet, dass ein zweiter Gateway immer als Hot-Standby zur Verfügung steht. Fällt der aktive Gateway aus, übernimmt der zweite Gateway selbstständig die IP des ausgefallenen Servers und damit auch seine Aufgaben.

Beide Lösungsansätze haben ihre Vor- und Nachteile. Wichtig ist, dass die zuständigen Systemadministratoren immer darauf achten, dass solche Maschinen untereinander abgeglichen werden, so dass sie immer auf dem gleichen Software-Stand sind. Wird ein Caching-Layer verwendet, muss das Vorheizen der Caches immer auf beiden Gateways erfolgen.

Der Storage

Es gibt kaum noch eine Web-Plattform, die nicht ein dediziertes Storage-System verwendet. Leider verlassen sich viele Unternehmen dabei auf die Spiegelung der Daten mittels eines RAID-Verbundes. Das schützt logischerweise nicht davor, dass mal ein kompletter Storage-Server ausfällt. Besser ist es daher sogenannte Cluster-Dateisysteme zu verwenden, bei denen die Daten zwischen mehreren Maschinen gespiegelt oder verteilt werden. Werden die Daten über mehrere Server verteilt, muss darauf geachtet werden, dass alle Daten mindestens zwei Mal vorhanden sind. Sonst fehlen beim Ausfall eines Storage-Servers ein paar Dateien, die ggf. für die Webapplikation notwendig sind.

Webserver und Webapplikationen

Natürlich gibt es auch bei den Webservern selbst einige Dinge, die man beachten muss, um eine möglichst hohe Redundanz zu erreichen. Neben dem heutzutage bereits überall üblichen Loadbalancing kann hierbei auch die Webapplikation einiges beitragen. Ein ganz wichtiges Stichwort ist hier Memcaching. Dieses beschleunigt nicht nur die Zugriffe auf Inhalte sondern kann auch genutzt werden um Inhalte selbst dann noch auszuliefern, wenn ein im Hintergrund werkelnder Application-Server oder die Datenbanken nicht mehr erreichbar sind. Wie Memcaching im Detail effizient eingesetzt werden kann, hängt aber zu sehr von der Webapplikation ab, die verwendet wird.

Kosten senken

Nun klingt das alles nach sehr vielen multiplen Systemen, die entsprechend höhere Kosten verursachen. Allerdings gibt es auch ein paar Bereiche, in denen man massiv Kosten einsparen kann ohne an Redundanz zu verlieren.

Einer dieser Bereiche sind die Storage-Systeme. Hierfür stehen heutzutage Cloud-Lösungen zur Verfügung, bei denen man nur die Speichermenge und die Zugriffe bezahlt, die tatsächlich genutzt werden. Im Vergleich zu eigenen Storage-Servern ist dies erfahrungsgemäss massiv preiswerter als der Unterhalt eigener Storage-Lösungen. Allein die Stromkosten, die gute Storage-Server verursachen, sind zumeist schon so hoch wie eine entsprechende Cloud-Lösung, da Storage-Server enorme Stromfresser sind.

Auch müssen für Caching-Layer nicht immer gleich dedizierte Server zur Verfügung gestellt werden. Mittels Virtualisierung lassen sich solche Layer problemlos auch auf Maschinen unterbringen, die nicht ausgelastet sind und wo vor allem der RAM nicht vollständig genutzt wird.

Überhaupt ist Virtualisierung ein Faktor, mit dem sich die verfügbare Leistung von Servern effizienter ausnutzen lässt. Ein Datenbank-Slave kann z.B. auch problemlos auf einem Webserver mitlaufen. Auch für's Memcaching muss nicht immer gleich ein Server mit Unmengen RAM zur Verfügung gestellt werden. Doch sollte man, wenn man Virtualisierung einsetzt um die Last besser zu verteilen, genauestens wissen, welcher Layer wie viele Ressourcen verbraucht. Neben einem Redundanz-Konzept sollte es dann auch ein Virtualisierungskonzept geben, wobei beide natürlich nicht getrennt voneinander betrachtet werden können. Beide Konzepte müssen ineinander übergreifen.

Zusammenfassung

Man sieht also, dass Redundanz von Web-Plattformen ein recht komplexes Thema ist. Die hier angesprochenen Punkte sollten auch nur als Eckpunkte verstanden werden. Es gibt noch viele weitere Details, die es zu beachten gilt. Meine Erfahrung ist, dass Caching-Layer in allen möglichen Ebenen eine Menge zur Redundanz beitragen können, sofern sie richtig gepflegt und genutzt werden. Caches sollten dabei immer vorgeheizt werden, d.h. sie sollten dazu gezwungen werden alle Daten, die für die Auslieferung der Webapplikation wichtig sind, zu laden. Dies kann man zum Beispiel tun, indem man die Zugriffe der letzten 24 Stunden auf die Plattform mittels der Access-Logs nachspielt. Dennoch gibt es kein allgemeingültiges Redundanz-Konzept, das man auf alle Plattformen anwenden kann. Will man eine möglichst hohe Redundanz erhalten, muss man auf die Eigenheiten der Webapplikation, die vorhandene Hardware und mögliche Cloud-Lösungen individuell eingehen. Sollten Sie Unterstützung beim Aufbau und der Umsetzung eines sinnvollen Redundanz-Konzepts benötigen, stehe ich Ihnen gern zur Verfügung.

Kommentare (0) - Kommentar schreiben