> Projekte > root Server
Inhalt
Übersicht
Ziel dieses ausserordentlich umfangreichen Projektes war einen root Server zu konfigurieren, um als Non-Profit ISP für Familie und Freunde zu arbeiten. Die angebotenen Dienste sollten unter anderem einen IMAP, SMTP, DNS und Web Server umfassen.
Zu lösende Herausforderungen waren unter anderem ein hohes Mass an Sicherheit zu erreichen (sowohl gegen Angriffe von aussen als auch gegen interne Fehler), eine einfache Backupmöglichkeit zu finden die möglichst in Echtzeit wichtige veränderliche Daten wie eMails sichert und eine einfache Verwaltungsoberfläche für die Benutzer zu entwickeln (Mailboxen, Weiterleitungen, Subdomains anlegen etc).
Da es sich um kein kommerzielles Projekt sondern um ein reines Lern-Projekt ohne Zeitdruck gehandelt hat, konnte in mehreren Iterationen die best mögliche Lösung gesucht und realisiert werden. Hierfür wurde ein lokales Testsystem installiert, das im Laufe von etwa 8 Monaten langsam zum fertigen Server gewachsen ist. Zu grossen Verzögerungen hat unter anderem geführt, dass unerwartet grosse Mengen Software selbst entwickelt werden mussten, oder zumindest vorhandene Software modifiziert werden musste.
Da relativ viel Software nur verwendet wird "da diese jeder nutzt" und nicht da sie die Beste ist, stand von Anfang an nur fest dass Linux als Betriebssystem eingesetzt wird. Bei der Anwendungssoftware habe ich mir meist verschiedene Lösungen angeschaut und mich dann für die für meinen Fall beste entschieden. Einen Überblick über eingesetzt Software gibt es hier.
Heraus kam ein Server der um eine Datenbank herum aufgebaut ist und für jede Funktionsklasse chroots verwendet.
Rückblickend nach einem Jahr läßt sich sagen daß sich der Spruch bewahrheitet hat: man versteht ein zu lösendes Problem erst nachdem man es einmal gelöst (implementiert) hat. Es wurden einige Details der ursprünglichen Implementierung und des Datenbank Designs verändert, das grundsätzliche Konzept hat sich aber absolut bewährt.
Herzstück Datenbank
Eine Datenbank zur Datenhaltung bieten gegenüber klassischen Dateisystemen eine grosse Anzahl Vorteile:
- definierter Zugriff (über SQL)
- Datenzugriff: "Was will ich" und nicht "Wie finde ich es"; kein fehleranfälliges parsen unterschiedlicher Formate notwendig
- einfacher Zugriff aus verschiedenen Programmiersprachen, Scriptsprachen bis zur Shell möglich
- fein abgestufte Rechteverwaltung
- Speicherstrukturen können ohne Applikationswissen angepasst oder verschoben werden
- Zukunftssicher: ein Transfer in Speicherstrukturen der Zukunft wird immer mit relativ wenig Aufwand möglich sein; Applikationen nutzen oft eigene (binär) Formate für effizienten Zugriff, was eventuell zu einem enormen Aufwand führen kann um die Daten zu extrahieren
- zentralisierte Kontrolle über alle Daten
- verhindert redundante Speicherung, spart Speicherplatz, verhindert vergessene Updates
- ohne können fehlerhafte, widersprüchliche, unvollständige Aktualisierungen nicht oder nur sehr schwer bemerkt werden
- Constraints können an zentraler Stelle verwaltet werden und verhindern unsinnige Daten; beim auslesen der Daten müssen keine aufwendigen Überprüfungen erfolgen, da die Korrektheit schon beim schreiben sichergestellt wurde
- Transaktionen erlauben ein vollständiges zurücksetzen einer Operation auch wenn ein Fehler erst am Ende auftritt; Operationen laufen immer nach dem alles oder nichts Prinzip ab
- effiziente Datenhaltung und Zugriff auch bei sehr grossen Datenmengen möglich
- effizienter paralleler Zugriff möglich, der jedoch isoliert wird und einen logischen Einbenutzerbetrieb ermöglicht
- Trigger und Stored Procedures erlauben es Intelligenz in die Datenbank zu verlagern, die damit nicht in jeder Applikation erneut realisiert werden muss
- Fremdschlüssel Beziehungen und kaskadierende Löschoperationen erlauben einfaches löschen großer Bäume
- Backups können konsistent und ohne Unterbrechung durchgeführt werden (Snapshot)
- Datenbankspiegel enthalten nur vollständig durchgeführte Transaktionen, keine aufgetretenen Fehler
- höhere Sicherheit bei IO: Schreib-/Lesevorgänge werden besser abgesichert als bei normalen Dateisystemen (mehrfach zur Kontrolle, Redundanz etc)
- Datenbank Puffer besitzen erheblich mehr Intelligenz als Caches des Betriebssystem (durch den Datenbank Optimizer/Query Planer)
Konkret bedeutet dies beispielsweise:
- Datenbankspiegel: im Gegensatz zu einem spiegel Verfahren das nur auf Dateisystem Ebene arbeitet und daher auch versehentliche Änderungen (Bitkipper, ...) spiegelt, werden von einer Datenbank nur bewusst durchgeführte Transaktionen gespiegelt
- Transaktionen: wird beispielsweise eine neue Domain angelegt muss dies an vielen unterschiedlichen Stellen erfolgen: im DNS Server, SMTP Server, IMAP Server, Web Server, FTP Server ... die alle eigene Config Dateien mitbringen; tritt beim letzten Config File ein Fehler auf, müssten alle vorher durchgeführten Änderungen an den anderen Dateien wieder rückgängig gemacht werden, was einen enormen Aufwand darstellt und extrem fehleranfällig ist; tritt ein Systemabsturz während der Verarbeitung auf muss geprüft werden wie weit der Vorgang war; bei Datenbank Transaktionen ist garantiert dass der komplette Vorgang entweder vollständig oder gar nicht durchgeführt wird
- Fremdschlüssel Beziehungen: beim löschen eines Benutzers werden automatisch alle Mailboxen, Mails, Domains, ... des Benutzers mit gelöscht
- Rechteverwaltung: für Logging reicht ein INSERT, UPDATE und DELETE sind dagegen nicht notwendig
Unix bietet nur 'w' auf eine Datei, was schreiben aber auch ändern und löschen erlaubt - zentrale effiziente Datenhaltung ermöglicht das speichern einer Mail nur 1x wenn Benutzer A eine Mail an Benutzer B schickt (Sent-Mailbox Nutzer A, Inbox Nutzer B - Header werden getrennt vom Body gespeichert)
- effiziente Datenhaltung: Zugriffszeiten bei klassischen Speicherstrukturen steigen i.d.R. linear mit dem Datenvolumen, bei Datenbanken maximal logarithmisch
- Anpassung Speicherstrukturen: Postgres Komprimierung langer Textfelder - De-/Kompressionsaufwand wird durch IO Reduktion ausgeglichen (bei eMails sehr wirkungsvoll)
Einen Nachteil hat das ganze aber: die Datenbank ist ein Single Point of Failure - fällt sie aus geht praktisch nichts mehr.
Chroots
Ein chroot verändert das Root Verzeichnis eines Prozesses:
chroot /var/local/webserver/ /usr/sbin/webserver
Greift der Webserver jetzt auf die Datei /etc/datei zu, ist dies in Wirklichkeit die Datei /var/local/webserver/etc/datei.
Bei dem Server habe ich als chroot hierbei immer eine komplette Distribution installiert, was einige Vorteile mit sich bringt:
- Sicherheitsgewinn, Software wird voneinander abgeschottet: der Webserver kann nicht auf die Dateien des Mailservers zugreifen da jeder in einem eigenen chroot läuft
- einfache Wartung
- dadurch dass eine vollständige Distribution verwendet wird können mit den normalen Distributionsmitteln Änderungen durchgeführt werden
- vor Änderungen kann ein chroot vollständig kopiert werden - bei Problemen kann es dann einfach zurück kopiert werden: ohne chroot muss neu installierte Software deinstalliert und die alte erneut installiert werden
- Updates können in kleinen Schritten durchgeführt werden: bei einem Distributions-Update wird nur wenig Software aktualisiert wenn jede Software Kategorie ihr eigenes chroot nutzt (Web-, Mail-, Datenbank Server, ...)
- in verschiedenen chroots können unterschiedliche Distributionen genutzt werden
- alte und neue Software kann parallel genutzt werden um diese einfach ausgiebig zu testen: ein vorhandenes chroot kopieren, Software aktualisieren und die neue Software auf einem anderen Port laufen lassen als die alte
- muß aus Lastgründen ein weiterer Server eingesetzt werden, kann ein chroot einfach auf eine andere Maschine kopiert werden
- wenn die versprochene Virtualisierung auf Hardware Ebene kommt (zum Beispiel Intels Vanderpool Technologie) kann ein chroot einfach als eigener Server genutzt werden - oder heute schon zum Beispiel mit Xen
Das ganze hat aber leider auch Nachteile:
- mehr Plattenbedarf da die Distributionen mehrfach installiert werden - im Fall von Debian sind das aber nur etwa 150-200 MB pro chroot
- mehr Hauptspeicherbedarf da Libraries mehrfach geladen werden
- für die Kommunikation können keine UNIX Sockets mehr verwendet werden (z.B. Datenbank, MTA -> Mail Storage, ...)
Verwendete Software
Muss noch geschrieben werden ...
