Montag, 20. Dezember 2010Apaches HTTPd RFC-unkonform machenEigentlich bin ich ja ein Fan von RFCs, denn Sie beschreiben irgendeine Technik für jedermann mehr oder minder verständlich und meistens recht eindeutig, sodass schlussendlich auch jeder seine eigene Software darauf aufbauen kann und die Interoparabilität gesichert ist. Da ist es eigentlich ein Krampf, wenn irgendwelche Unternehmen oder Entwickler hingehen und irgendetwas abweichend von einem RFC tun. Heute möchte ich mich in die Reihe der RFC-abweichler einreihen - aber nur optional und aufgrund eines expliziten Kundenwunsches. Der Ausgangspunkt war eine Joomla-Installation eines Kunden, die stets URLs wie www.domain-des-kunden.de//images/unterverzeichnis/bild.jpg generierte. Auf den ersten Blick ist hier vielleicht nichts falsch, höchstens das "//" wirkt optisch unschön. Doch falsch gedacht! Ein "//" am Anfang eines Pfades auf einer Domain ist in RFC 2396 Abschnitt 3.2 als "Authority Component" definiert, dementsprechend schneidet ein Webserver (der RFC-konform arbeitet) "//images" von der Adresse ab und wertet es als Authentifizierungs-Informationen aus. Wäre mir das nicht schon mal in Verbindung mit Subversion passiert, würde ich das vermutlich gar nicht wissen und ich kenne auch niemanden, der diese Regel spontan parat hätte. Somit ist das Ergebnis dieser URL stets nicht das jenige, welches man erwarten würde. Da der Kunde auch recht wenig Interesse hatte in Joomla den Fehler zu suchen und dort wegzupatchen, habe ich - eigentlich mehr aus Spaß - ein Modul für den Apache HTTPd geschrieben das die arme wehrlose Webserver-Software RFC-unkonform macht. Genau genommen macht das mod_ignore_authcomponent auf Wunsch zuvor geleistete Arbeit wieder rückgängig und stripped dabei einfach eines der Slashes am Anfang der Domain weg. Überraschenderweise hat das Modul auch gleich seit letzter Woche den Weg durch unser Build-System genommen und es heute Abend in unsere offiziellen Paket-Quellen geschafft. Bei Bedarf werden wir es wohl in den kommenden Nächten auf unsere Webserver ausrollen und einen entsprechenden Button bei uns im Kundeninterface einpflegen. Dienstag, 14. Dezember 2010Speicherkarte kaputt, Dateien gerettetWenn man den Blog hier streng auf Hosting-Themen beschränken würde, wäre dieses Thema wohl Off-Topic. Ich beschränke aber nicht derartig und werde nun voller Freude berichten. Ein Kunde feierte am Freitag Abend seine Weihnachtsfeier, zu der ich auch gelanden war und mit großer Freude teilnahm. Der Höhepunkt war in diesem Jahr ein Menü aus 9 Gängen, dass - mit Verlaub - hervorragend war. Der Koch samt Cheffin wurde dazu extra aus Spanien eingeflogen und beide hatten offensichtlich auch jede Menge Spaß am Abend und dokumentierten fast fleißiger als jeder Gast dort das Geschehen und natürlich das Menü. Nach der Feier wurde die Speicherkarte von einem der Geschäftsführer (sprich: Hätte es eine entsprechend Betriebsvereinbarung zur Nutzung der Computer gegeben, wäre die auch sinnlos gewesen) an einen Computer des Unternehmens angeschlossen - nur um eine Kopie der Bilder zu bekommen. Doch der Virenscanner schlug sofort an und löschte gerade zu Bedingungslos die ersten 2 KB Dateisystems auf der Speicherkarte, eine Wiederherstellung sollte nicht mehr möglich sein. "Hah! Wieder eine gelegenheit zu puzzlen!" war wohl mein erster Gedanke und er sollte nicht mein letzter in dieser Sache sein. Das Problem: In den ersten 512 Byte des Dateisystems stehen eigentlich alle Rahmendaten die zur Nutzung der restlichen Daten notwendig sind, nun standen dort nur noch Nullen. Erschwerend kam hinzu, dass ich eigentlich gar kein Wissen über das FAT-Dateisystem vorzuweisen hatte. Auf meiner Zugfahrt von der Feier nach Hause habe ich mich also erst einmal an ein intaktes FAT-Dateisystem heran getastet. Erst Dateisystem-Informationen ausgelesen, Verzeichnis-Informationen ausgewertet, Cluster lokalisiert und schlussendlich selbige verkettet und daraus ganze Dateien gemacht. Ich würde ja die einzelnen Zwischenschritte zeigen, allerdings sind die mittlerweile in einer Art Bibliothek aufgegangen und vereinfacht worden. Der Schritt zu der kaputten Speicherkarte (die ich als Image mitgenommen hatte) war dann eigentlich nur noch Parameter raten und die Verzeichnisse finden, wo alle Bilder liegen. Und siehe da: Ich habe alle Bilder aus dem Image retten können, fehlerfrei. B-) Damit meine Code-Schnipsel, die mir hierzu verholfen haben, nicht verloren gehen, habe ich sie gleich mal online gestellt. Im Zweifel helfen sie vielleicht auch einem anderen Bastler. Die Fotos werde ich gleich manuell hochladen und so an ihre Urheber zurückgeben. Mittwoch, 8. Dezember 2010Mehr PHP-PatchesIch habe ja gestern schon von ein paar Patches für PHP 5.1.6 berichtet. Die Version ist zwar mittlerweile stein alt und niemand wird sie noch verwenden (außer wir, wenn der Kunde es so will ), aber der Vollständigkeit halber noch zwei Backports / Patches, die ich gestern unterschlagen habe:
Dienstag, 7. Dezember 2010Was machst Du gerade?Es ist irgendwie immer ein Drathseilakt, wenn man Limits auf dem Webserver festlegt - wie lange darf ein Skript laufen, bevor der Webserver ihn automatisch beendet? Wählt man das Limit zu kurz, schreien etliche Kunden, wählt man es zu lange, schreien sie vermutlich wieder wenn man ein Skript amok läuft. Ich finde die Aussage "Da läuft halt gerade ein Skript von Dir nicht rund und belegt alle Ressourcen" wenig befriedigend - auch oder gerade dann wenn ich der jenige bin, der sie gibt, und nicht der jenige, der sie bekommt. Aber in dem Moment ist alles andere unwirtschaftlich, wir können nicht die Zeit aufbringen herauszufinden, welcher Skript da gerade läuft und wo genau es hakt. Wenngleich wir natürlich auch hier unser Bestes zu geben versuchen. Um ein wenig mehr Licht in die Angelegenheit zu bringen, haben wir uns nun aufgemacht und einen kleinen Patch in der FastCGI-SAPI von PHP eingebaut: Die laufenden FastCGI-Server ändern nun ihren Prozess-Title und geben somit Preis was sie gerade tun, z.B. ob sie gerade eine Anfrage bearbeiten oder auf die nächste warten. Super! Nun muss es sich nur noch im Produktiv-Betrieb bewähren. Bei der Gelegenheit haben wir noch ein paar Änderungen in den PHP 5.1er-Baum zurückgeführt, um PHP 5.1.6 mit OpenSSL 1.0 und neueren CURL-Versionen zu bauen. Samstag, 27. November 2010Beta-Tester gesuchtWir suchen gegenwärtig nach interessierten Kunden, die mal den Gegenwärtigen Zustand unserer Multi-User-Chat-Komponente samt Anbindung ans Kundeninterface testen möchten. Super wäre natürlich eine bereits vorhandene Jabber/XMPP-Domain bei uns im Hause, sofern mindestens eine "normale" Domain vorhanden ist, kann man den aber natürlich noch ergänzen. Tiefgreifendere Kenntnisse oder Erfahrungen mit mit dem Multi-User-Chat (XEP-0045) sind wünschenswert. Bei Interesse einfach per E-Mail melden. Montag, 25. Oktober 2010Speicherhunger von Wordpress zähmenJeder, der sich schon mal mit mir über das Thema Weblogs unterhalten hat, kennt meinen Erzfeind: Wordpress. Ich kann diese Software nicht ausstehen, denn der absolut größte Teil der Probleme im Support dreht sich um diese Software. In letzter Zeit wesentlich mehr als früher. Da ich mich Kunden gegenüber aber mindestens neutral verhalten muss und ein "Läuft bei uns halt nicht" für mich selten in die Tüte kommt, so muss ich diesen ganzen Frust in mich rein fressen. Mir musste auffallen, dass sich Speicherprobleme bei Wordpress sehr oft im Package "pomo" ereignen. Der Name hat mich gleich an das GNU gettext-Projekt erinnert, da dort mit .po-Dateien in .mo-Dateien kompiliert werden um Anwendungen quasi eine Datenbank zur Lokalisierung (bzw. Übersetzung) von Texten bereit zu stellen. Bei Wordpress verhält es sich genau so: "pomo" ist dazu da um Wordpress vom Englischen her in andere Sprachen zu übersetzen. Auf wordpress.org kann man ebenfalls nachlesen, dass man sich für die Lokalisierung mittels gettext entschieden hat. Sehr schön bis hier hin! Auch wir setzen in unseren Projekten auf diese quasi als Standard etablierte Technik ein - auch wenn ich zugegebener Maßen selbst oft das Rad neu erfinden will. Nur eifert Wordpress mir in dieser Sache etwas hinterher: "pomo" ist eine komplett eigenständige Implementierung, die .mo-Dateien auf dem Server parsed und entsprechend übersetzt - in PHP geschrieben. Ich habe es nun nicht geprüft, aber ich wette nahezu, dass der Code etwas ineffizient ist (warum? Mehr dazu später) Heute morgen hatte ich irgendwie die Faxen dicke. Es kann doch nicht sein, dass so schöne Grundlagen geschaffen werden aber zum Schluss hin dann nur halbherzig umgesetzt werden. Also habe ich mir ein deutsches Wordpress heruntergeladen und auf einem normalen 64-Bit-System mit PHP (5.3.3) über FastCGI und mit einem Speicherlimit von 28 MB installiert - ein ganz normaler Kundenaccount der Größe "Starter" also - und ich hatte von vorne herein Probleme. Als "jemand vom Fach" für mich eigentlich nur kaum nachvollziehbar und als ich den "pomo"-Teil von Wordpress deaktiviert habe auch sofort weg. Nun ist das Abschalten sämtlicher Übersetzungsfunktionen keine Lösung. Deswegen habe ich einen kleinen Patch für die Datei wp-include/l10n.php geschrieben und die .mo-Dateien von Wordpress in einer mit gettext kompatiblen Verzeichnis-Struktur abgelegt (Siehe Skript). Mit dem Patch nutzt Wordpress nun (sofern Verfügbar) die native gettext-Erweiterung von PHP. Und siehe da: Mein Test-Blog ist in deutscher Sprache verfügbar und ich konnte das Speicher-Limit von PHP sogar testweise auf 6 MB herabsetzen (mehr habe ich mich nicht getraut). Das muss man sich mal vorstellen: Mit einer kleinen Änderung von ca. 30 Minuten habe ich den Speicherbedarf von Wordpress um weit mehr als 75% gesenkt. Wobei man hier zugegeben muss: Ich habe nur auf einem Test-Blog gearbeitet. Folglich funktioniert der Patch nachweislich für eine Standard-Installation - mit einem anderen Theme oder einer Reihe von Plugins habe ich es nicht getestet. Wenn diese aber den etablierten gettext-Richtlinien folgen, sollte das eigentlich kein Problem sein. Alle Dateien meiner kleinen Wordpress-Exkursion gibt es hier: http://oss.tiggerswelt.net/wordpress/ Nachtrag (17:57): Donnerstag, 21. Oktober 2010PHP mag nicht mit zwei oder mehr Optimizern gebaut werdenEs hätte so schön sein können: APC und XCache lassen sich problemlos statisch in PHP einkompilieren. Einzeln. eAccelerator mochte das auf Anhieb nicht so gerne, hätte sich aber bestimmt noch dazu überreden lassen. So weit kamen wir jedoch gar nicht, denn zunächst wagten wir ein Build von PHP mit den beiden zuerst genannten Cachern/Optimizern. PHP baute sich auch wunderschön zusammen, verweigerte danach jedoch komplett den Start, da APC und XCache sich wohl duellierten. Der Plan war eigentlich eine monolithische Version von PHP zu haben und den bevorzugten Optimizer per php.ini zu aktivieren. Nach dem Motto "Ganz oder gar nicht" haben wir das bisher statisch einkompilierte APC komplett rausgenommen und in den Modul-Build-Prozess neben eAccelerator und XCache integriert. Die News, die sich hier heimlich eingeschlichen hat, ist eher dass wir nun auch XCache im Angebot haben und dementsprechend auf Kundenwunsch dort hin umschalten können. Voreiliges MonitoringUnser Monitoring kann manchmal echt ätzend sein... Da will man mal ganz normal nachts den Webserver (bzw. httpd) neu starten. Und es schlägt fehl. Aber warum? Ganz einfach: Nachdem der Webserver heruntergefahren war, hat das Monitoring den Webserver umgehend neu gestartet und war dabei schneller als der eigentliche Skript der die beiden Aufgaben des stoppens und starten ausgeführt hat. Nun gut, nicht ganz ein Fehlschlag, dennoch gibt es mir zu denken, warum das Monitoring hier schneller war. Dienstag, 12. Oktober 2010IPv6 auf dem VPN GatewayAm Wochenende habe ich mich eher in meiner Freizeit hingesetzt und kleinere Änderungen an unserem VPN Gateway vorgenommen. "Er" weiß nun, dass es sowas wie IPv6 gibt. Das will heißen, dass ich ein /64er-Netz (das rein für Test-Zwecke und nicht für den produktiven Betrieb geeignet ist) bereitgestellt habe, dass der VPN Gateway bedient. "Er" weiß nun, wie es bei einem Neustart einzurichten ist und wie Routing-Regeln zu setzen sind, ein wenig mit der Firewall spielen kann er auch - zumindest soviel um eine generelle IPv6-Nutzung noch zu verbieten und die "Herkunft" eines IPv6-Paketes zu verifizieren (also ein Schutz vor Spoofing). In meiner ersten Version unterteilt der VPN Gateway das /64er-Netz in 65536 /80er-Segmente, wovon er das erste für sich selbst beansprucht und den Rest theoretisch an Kunden weiterleitet. Nach einem manuellen Setup auf Client-Seite, hatte ich in windeseile (binnen 3 Befehlen) eine IPv6-Anbindung über den VPN-Gateway und hätte auch noch knapp 281.474.976.710.656 Geräte hinter meinem Laptop nativ adressieren können. Wobei im "manuellen Setup" auch der aktuell technologische Knackpunkt liegt: Das von uns eingesetzte OpenVPN hat wenn man es genau nimmt keine Unterstützung für IPv6 an Bord. Es gibt ein paar Anstrengungen in diese Richtung, z.B. Patches in der Community, aber nichts was produktiv in der offiziellen Distribution verfügbar wäre und helfen würde. Mittlerweile geht der Trend etwas stärker in Richtung IPv6, sodass ich doch sehr hoffe, dass OpenVPN hier bald nachzieht. Kunden-spezifisches Black- und WhitelistingWie letzte Woche bereits angekündigt und in den Kommentaren erraten, haben wir ein wenig mehr Funktionalität in unser Backend bzw. auch ins Kundeninterface eingebaut. Auf speziellen Wunsch, aus gegebenem Anlass und aufgrund meines unendlich großen Spieltriebes, können unsere Kunden nun auf unserem Mailserver eine eigene Blacklist verwalten. "Eigene" heißt in diesem Sinne natürlich, dass die Regeln nur für E-Mail-Adressen des Kunden selbst und nicht für die von anderen Kunden gelten, so kann es sein, dass eine E-Mail für Kunde A angenommen wird, wohingegen eine andere vom selben Server für Kunde B abgelehnt wird. Der Regelsatz lässt momentan eine Identifizierung des Servers anhand seiner IP-Adresse, seiner HELO-Kennung und seinem RDNS-Namen zu. Die Regeln sind ähnlich einfach gehalten: Sofort Blacklisten, Nachrichten ab einer bestimmten Größe Blacklisten oder E-Mails einfach durchreichen, bzw. Whitelisten. Über das Wochenende hat schon eine Hand voll Kunden das Feature eingeweiht und auch das Feedback, das ich primär aus dem professionellen Bereich erhalten habe, war durchweg positiv. Viel mehr erwarte ich schon gar nicht mehr - das ist jetzt keine bahnbrechende Neuerung, aber sicherlich eine, die recht gut in unseren Anspruch passt Montag, 27. September 2010Jabber/XMPP auf Standard- und HTTP-Ports verfügbarSeit heute betreiben wir (wie schon einmal angedroht) auf unserem Jabber/XMPP-Server eine c2s-Komponente, die alle bei uns gehosteten Domains bedient und auf den wohlbekannten Standard-Ports 5222 und 5223 (klassisches SSL) horcht. Für ganz restriktive Umgebungen haben wir noch die Ports 80 (HTTP) und 443 (HTTPS) hinzugefügt. Damit sollte der Dienst wohl für alle Nutzer von überall erreichbar sein. Auf den von vorne herein verschlüsselten Ports liefern wir unser SSL-Zertifikat für ssl.tiggerswelt.net aus - das ist nicht direkt schön, aber offiziell signiert. Für die modernere StartTLS-Variante funktionieren die jeweiligen Kunden-/Domain-spezifischen SSL-Zertifikate bzw. wieder unser SSL-Zertifikat als Fall-Back. Einziger Nachteil bei dieser Variante: Änderungen auf Kundendomains spielen wir maximal alle 2 Stunden ein. Das bedeutet zum einen, dass Änderungen an der XMPP-Konfiguration wie z.B. verwendetes Zertifikat, Passwort-Änderungen oder Benutzer-Registrierung werden nur stark verzögert übernommen. Zudem kann es dann entsprechend im "worst case" zu einem Disconnect aller Nutzer auf dieser Komponente kommen. Ich bin mal gespannt, wie viele die neue Variante nutzen werden und wie oft da tatsächlich neu gestartet wird. SMTP-Server in 350 Zeilen und 9000 ZeichenIch musste mal wieder das Rad neu erfinden... Für interne Zwecke wollte ich einen Content-Filter installieren, der bestimmte E-Mails, die bei unserem Postfix ankommen, verarbeitet. Ich wette es gibt mindestens eine Hand voll Lösungen da draußen, die genau das tun was ich brauche - aber ich habe sie wie üblich nicht einmal gesucht, sondern sofort eine eigene Implementierung zusammen geschrieben. In knapp 40 Minuten habe ich in 350 Zeilen Quellcode insgesamt 9095 Zeichen zusammengetippt, wobei knapp 2/3 davon Kommentare und Dokumentation sind. Wenn man mal bei Seite lässt, dass ein paar Validierungen fehlen ist das Ding sogar komplett Konform zu RFC 5321. Wenn man bedenkt, dass sich selbst produzierter Code meistens besser in unsere Umgebung integriert als jeder andere Fremdkörper, bin ich mal gespannt oder würde gerne wissen, was in Sachen Maintinance mehr Arbeit bereitet. Da das Ding aber wesentlich mehr Dokumentation im Quelltext besitzt als die meisten OpenSource-Applikationen die mir bekannt sind, sich ohnehin nach unseren internen Programmier-Richtlinien richtet und bei uns wohlbekannte Schnittstellen verwendet bin ich aber recht zuversichtlich, dass die Rechnung zu meinen Gunsten aufgeht Montag, 20. September 2010INBOX-Verschlüsselung für den Produktiv-Betrieb freigegebenNachdem wir im Test-Betrieb nun ein paar tausend E-Mails mit S/MIME und GnuPG testweise verschlüsselt haben, habe ich heute die entsprechende Komponente heute für den Produktiv-Betrieb freigegeben. Das heißt aber erst einmal rein gar nichts bzw. bieten wir das Feature noch nicht von der Stange ab an, sondern schlagen jetzt erst diesen Weg ein und automatisieren den Vorgang. Pünktlich zu Weihnachten darf dann aber bestimmt jeder Kunde seine E-Mails in einem kryptographischen Geschenkpapier einpacken - wenn er denn will. Analog dazu arbeiten wir auch schon an einer weiteren Komponente, die das selbe auf der Postausgangsseite realisiert. Entweder automatisch verschlüsseln oder - wenn der Kunde unbedingt will und soviel Vertrauen aufbringt - signieren. Die Postausgangsseite wird wohl auch noch mit anderen Features, die speziell auf Geschäftskunden abziehlt, etwas mächtiger werden. Dazu bewahre ich aber erst einmal stillschweigen, zumal hier auch noch nichts in trockenen Tüchern ist. Mittwoch, 15. September 2010Multi-User-ChatIch habe gestern nun endlich aktiv damit begonnen, unseren Jabber/XMPP-Server um eine MUC-Komponente zu erweitern. Ein wenig überrascht war ich schon, denn bevor ich zur eigentlichen Arbeit gekommen bin, hagelte es erst einmal ein paar Patches für meine Event-Bibliothek, meine XMPP-Komponente und natürlich auch die recht generische MUC-Implementation von mir. Am Ende des Tages war ich dann aber doch recht zufrieden und fast schon wieder im Arbeitsrausch. Die Sache mit dem Klappe halten hat bei einem kurzen Test auf unserem Produktiv-Server recht gut funktioniert, wenngleich mich die 700 KB an Traffic überrascht haben, die bei einem einfach Start der Komponente mit Authentifizierung und dem Bekanntmachen mit anderen Komponenten auf dem Server (presence und Service-Discovery) verbraten wurden. Was jetzt noch fehlt ist das dynamische Hinzufügen und Entfernen von MUC-Domains und alles, was so zu einem Chat-Raum dazu gehört - wobei beides wohl weniger ist, als es klingt - und natürlich jede Menge Ideen, die das Ding einzigartig machen Wer schon eine Jabber/XMPP-Instanz bei uns hat und an einer Public-Beta interessiert ist, darf mich gerne mal anschreiben. Montag, 13. September 2010Einfach mal die Klappe halten...Wir betreiben ja bekanntlich einen Jabber/XMPP-Server mit einigen Domains unserer Kunden. Vergangene Woche kam hierzu die Frage auf, ob es eigentlich möglich ist, hier eine Komponente anzuschließen, die nicht bei jeder Domain (in der Service-Discovery) als verfügbarer Dienst angezeigt wird. Gerade wenn es darum geht personalisierte Dienste auf den Domains der Kunden oder speziell gebuchte Dienste für einen speziellen Kunden anzubieten. Die Antwort hierauf ist recht einfach: Ja, es geht! Ganz egal, ob die Komponenten mittels XEP-0114 oder mit dem nativen Component-Protocol des Jabberd2 (bzw. hier sobald eine Domain gebunden wird) an den Server "angeschlossen" werden, der Router sendet immer einen <presence>-Tag an alle anderen Komponenten, darunter auch die Session-Manager für die Kundendomains. Diese veranlassen daraufhin eine Service-Discovery, deren Ergebnis sie zwischenspeichern und bei eingehenden Anfragen einfach weiterreichen. Wenn wir also nicht wollen, dass ein Dienst unterhalb einer bestimmten Kundendomain angezeigt wird, unterlassen wir einfach Service-Discovery-Antworten an diese Domain. Schade nur, dass ich selbst auf die Idee kommen musste und mir eigentlich keine Komponente auf dem freien Markt bekannt ist, die so eine Funktionalität von Haus aus anbieten würde. Egal, ich muss das Rad ja sowieso immer neu erfinden
« vorherige Seite
(Seite 5 von 30, insgesamt 443 Einträge)
» nächste Seite
|
SucheRead this blog!KategorienBlog abonnierenNotice this! |
Kommentare