PHP CLI und FPM-Service: /tmp besser meiden
Ich habe da eine PHP-Applikation, die ein Webinterface besitzt als auch per CLI einige Dinge - z.B. als Cronjob - aufruft.
Beide Arten von Skripten - bei Http Aufruf oder aber CLI - durchliefen dasselbe Init-Prozedere und referenzierten ein und dasselbe File.
$this->sTouchfile = sys_get_temp_dir() . '/some_file.tmp';
Oder besser: ich hatte es zumindest gemeint. sys_get_temp_dir() wurde auf dem Linux-System als “/tmp” aufgelöst. Also optisch war es dieselbe Datei: /tmp/some_file.tmp - aber Das Webinterface erkannte eine Aktion auf CLI Seite nicht … und umgekehrt das CLI nicht eine Schreibaktion aus dem Webinterface.
Bis ich dann mal auf die Idee kam und mir mit einem per Http aufgerufenem Skript eine spezifische Datei in /tmp/ anlegte und diese mal im Filesystem suchte. Unter dem PHP-FPM Service war als /tmp/ jenes “tmp” Verzeichnis verwendet worden:
/tmp/systemd-private-d1b7cf65cce54d4ca9f98c49cca1887f-httpd.service-NoEzTN/tmp/
Das hat mir das ungewöhnliche Verhalten auch sofort erklärt.
Man merke: /tmp sollte man meiden, wenn man gemeinsame Daten per http als auch CLI Daten teilt. Ich habe in meiner Applikation von sys_get_temp_dir() auf ein “tmp” unterhalb [Approot] umgestellt…
weiterführende Links:
IML Appmonitor ist nun PHP 8.1 kompatibel
Der Appmonitor ist eine PHP-Applikation mit geringstmöglichen Anforderungen. Mit dieser lassen sich andere (Web-)Applikationen in einem Webfrontend überwachen und bei Statuswechsel Notifikationen per E-Mail und Slack an die am Projekt beteiligten Personen auslösen.
Das Applikationsmonitoring ergänzt unser System-Monitoring, weil es die applikationsseitigen Checks aus Sicht der Applikation und mit den Rechten der Applikation ausführt.
Der Appmonitor ist Freie Software, Opensource und untersteht der GNU GPL 3.0.
Nach gefühlt 2 Jahren habe ich am IML Appmonitor weitergecodet. Es sollte PHP 8 kompatibel werden. Und weil soeben PHP 8.1 erschienen ist, wurde es nun auch für ebenjene Version 8.1 fit gemacht:
Tadaaa: der Appmonitor ist die erste PHP 8.1 kompatible Opensource Applikation unseres Instituts :-)
Zudem wird die Plugin-Unterstützung vorangetrieben, es kam eine grafische Darstellung der Checks in einem ersten Wurf hinzu und die Möglichkeit, die Checks nach vorgegebenen Gruppen zu clustern. Die Notifikation eines Fehlers erfolgt nicht beim ersten Auftreten, sondern wird erst bei der 3. Wiederholung ausgelöst.
Ich bin gerade motiviert, weitere Updates einzubringen und nachzuliefern. Es gibt beispielsweise vorgefertigte Checks für einige PHP-Applikationen, wie Wordpress, Ilias LMS, Concrete5 und Matomo. Diese befinden sich in einem separaten Repository und werden in Kürze in das Repo integriert.
weiterführende Links:
AhCrawler läuft mit PHP8
Der AhCrawler ist ein PHP Open Source Projekt, das für den Einbau einer Suche auf der eigenen Webseite enststand. Im Backend kann man den Suchindex wie auch die von Besuchern eingegebenen Suchbegriffe analysieren. Hinzu kommen Werkzeuge, wie Linkchecker, Http-Header-Analyse, SSL-Check und Annehmlichkeiten, wie der integrierte webbasierte Updater oder die Verwaltungsmöglichkeit mehrerer Webseiten.
Nachdem PHP in Version 8 erschien, kam Anfang Dezember 2020 eine Version heraus, die offensichtliche Fehler in der WebGUI unter PHP8 bereinigte. Der Crawler zeigte hingegen bei Http Head Requests mit Curl “irgendwann” ein komisches Verhalten und brach mit einem “Segmentation Fault” ab.
Mit dem heutigen Release des AhCrawler ist aber auch das Geschichte. Ich bezeichne die Software nunmehr als PHP8 kompatibel! Tusch :-)
weiterführende Links:
- AhCrawler (de)
- DOCs: AhCrawler (en)
Flatpress - sichere Passwortfunktion statt MD5 Hash
Ich hatte es es ja genauso in mein meinen Webtools mit Login gern gemacht: neben dem Admin User wurde das Passwort als MD5 Hash in einer Config-Datei hinterlegt.
Die Hashfunktion MD5 ist nach IT Masstäben nicht mehr wirklich sicher - heisst: man kann mit einem zeitlich vertretbaren Aufwand aus dem Hash das (oder ein) Passwort ermitteln, dass auf den Hash matcht. Verzichtet man gar auf Salts, ist der Angreifer mit Rainbow Tables gar in Sekundenbruchteilen am Ziel. Das ist gar nicht gut. Auf MD5 sollte man heutzutage beim Hashing von Passwörtern - egal ob in einer Konfigurationsdatei oder Datenbank-Feld - komplett verzichten.
Ich will es keineswegs verdammen: als reine Hash Funktion zum Bilden von Prüfsummen von nicht-sensiblen Daten, wie Prüfsummen von Download-Dateien, ist es bedenkenlos einsetzbar.
Aber zurück zum Speichern von Passwörtern. PHP bietet seit einiger Zeit von Haus sichere Funktionen an, sichere Passwort-Hashes zu generieren [2] wie auch eine Check-Funktion [3]. Auf dieses Paar habe ich meine Tools umgestellt und kannte das Prozedere der Umstellung bereits.
Da ich hier als “mein” Blogtool Flatpress seit gefühlten Äonen selbst verwende, hab ich mich gern auch an jenem Tool drangesetzt, und dessen md5 Passwort-Hash durch eine sicherere Variante ersetzt - und eine Lösung für den Issue #59 [4] als Pull Request eingereicht.
Das gilt nicht nur für die neu angelegten Passwörter - auch die Migration ist berücksichtigt: bestehende mit md5 Hash gespeicherte Passwörter werden on the fly beim nächsten Login umgeschrieben.
Arvid, danke und merci für den Merge und Erwähnung auf Twitter [1] für die kommende Version 1.2!
I love OpenSource :-)
weiterführende Links:
Xampp: Port 3306 belegt - durch Firefox
Schon komisch: ein Programm krallt sich einen Port. Ich dachte, das wäre die Domäne von Skype.
Abhilfe:
- Firefox beenden
- Mysql im Xampp starten
- Firefox starten
preDispatcher - speed up my slow Concrete5 website
Meine Concrete5 Webseite wurde langsamer und langsamer. Sie wird auf einem Shared Hosting betrieben (was ohnehin nicht die schnellste Option sein kann) - hier kann ich zudem keinen Varnish oder auch nur irgendeinen anderen Caching Dienst installieren und davorschalten, sondern muss mich mit .htaccess und Standard-PHP-Mitteln behelfen können.
Das Initialisieren eines Requests in Concrete5 (Bootstrapping) braucht scheinbar sehr lange. Selbst statische Inhalts-Seiten, die ein aktives Fullpage Cache haben, benötigen für die Verarbeitung am Server mehr als 200 ms. Hinzu kommen für einen kompletten Request dann noch Netzwerkzeiten für Namensauflösung (DNS), Anfrage zum Server senden … und das Ergebnis zum Browser zurücksenden, was der Browser dann rendert. Meine schnellsten Seiten aus dem CMS waren bei 300 ms. Andere brauchten 3 Sekunden und mehr. Concrete5 ist einfach langsam.
Ich habe einen Cache geschrieben, der Concrete5 vorgeschaltet ist und im Filesystem seine Caching-Daten ablegt. Kurz er hat minimalste Anforderungen und arbeitet mit einem Shared Hoster. Dieses “Vorschalten” umgeht die lange Initialisierungszeit von Concrete5 - dies macht die Seite schnell.
Vor einigen Tagen habe ich eine erste Version meines preDispatchers eingespielt. Erwartungsgemäss muss man ein paar Kinderkrankheiten ausmerzen. Aber erste Ergebnisse in der Webseiten-Statistik (Matomo) zeigen, dass es eine gute Entscheidung war: die mittleren Seiten-Generierungs-Zeiten sanken von über 2s auf unter 0.4s
Der PreDispatcher besitzt eine Debugging-Ausgabe, die die Arbeitsweise veranschaulicht und den Unterschied deutlich macht. Das ist ein ungecachter Aufruf einer Seite mit Fullpage Cache in C5 - also inkl. Bootstrapping + Auslieferung einer in C5 gecachten Seite:
Der PreDispatcher speichert den Request, der nicht im Cache ist (oder dessen Caching Zeit abgelaufen ist). Der nächste Request auf dieselbe Seite wird dann schnell. Richtig schnell:
Wie lange eine Seite aus einem Cache kommt? Man definiert einen Default für alle Seiten. Mit einer Liste von Regex für aufzurufende URLS kann man die Standard-Vorgabe übersteuern und einen neuen Wert zuweisen.
Zudem gibt es eine Erkennung, was nicht gecacht werden darf - oder wo ein Cache verworfen werden muss. Ich kann mich im C5 Backend einloggen - und der Cache jeder mit Login aufgerufenen Seite wird verworfen.
Ich bin wohl auf dem richtigen Weg. Aber ein wenig Feintuning braucht es noch. Bei Interesse, schaut auf Github … oder fragt mich an :-)
Der PreDispatcher ist Freie Software - unter GNU GPL 3!
weiterführende Links:
- Github: pre-dispatcher for more speed
- Concrete5 webseite
PHP-Snippet - URL Parameter escapen
Dieser Blogeintrag ist eine Snippet-Ablage.
Die PHP-Funktion mysql_real_escape() maskierte Sonderzeichen in Werten, bevor man sie für Datenbankabfragen verwenden sollte. Die Funktion arbeitet nur dann, wenn Mysql vorab initialisiert wurde.
/** * mysql_real_escape for an array of options * @param array $aParams * @return array */ function escapeAllParams($aParams) { foreach (array_keys($aParams) as $sKey) { $aParams[$sKey] = escapeParam($aParams[$sKey]); } return $aParams; } /** * replacement for mysql_real_escape. * @param string $s * @return string */ function escapeParam($s) { $s = str_replace(array('\\', "\0", "\n", "\r", "'", '"', "\x1a"), array('\\\\', '\\0', '\\n', '\\r', "\\'", '\\"', '\\Z'), $s); return $s; }
Pimped Apache Status: über 500 Downloads im März
Ich bin leider erst soeben darüber gestolpert: diesen März gab es auf Sourceforge einen absoluten Peak von 565 Downloads im Monat.
Warum habe ich das nicht gesehen?
In die tageweise Statistik reingezoomt … davon waren 500 an einem Tag (19.3.) - ich glaube, da hat sich wer einen Scherz erlaubt und wget bemüht - oder gar öfter F5 im Browser gedrückt.
So schnell kann eine kleine Euphorieblase wieder platzen.
weiterführende Links:
- Axels Webseite - Docs Pimped Apache Status Get started - hier ist das Youtube Video
- Github: Pimped Apache Status
- Sourceforge: Pimped Apache Status
PHP: komisch grosse Zeiten in Curl
Ich hatte wirklich seltsame Antwortzeiten mit der Curl-Bibliothek in PHP in meiner eigenen Monitoring-Anwendung.
Bei Verwendung von curl_getinfo($curl) ist der Wert von “total_time” ein Wert in Sekunden. Eigentlich. Bei einer Reaktionszeit von 16ms sollte es 0,016 sein, ich erhielt aber 16000.
Das Problem ist, dass sich die Werte der Curl-Funktion bei Verwendung von PHP mit mod_php korrekt verhalten - nur im FCGI Modus gibt es Zahlenwerte, die Faktor 1 Mio. zu gross sind.
Bei einer Antwort-Zeit von 16 ms sollte der Wert im Feld total_time 0.016 sein - unter FCGI kommt aber 16000 zurück.
Nach einer kurzen Suche, fand ich einen bestehenden Bugreport, wo ich meine Daten ergänzte. Mal schauen, ob da wohl was geht …
weiterführende Links:
Appmonitor Server Webgui auf AdminLTE portiert
Ich weiss ja auch nicht, was mich vor ein paar Jahre geritten hat, Oberfläche und CSS von Hand und selbst erstellen zu wollen. Weil es schlank ist. Aber eben nicht produktiv.
Nun habe ich die GUI auf AdminLTE portiert - und mir für die benötigten Elemente in AdminLTE die notwendigen Abstraktionen geschrieben. Nun ist es deutlich aufgeräumter!
GUI-Kram kann schon ziemlich lästig sein. Ich bin froh, bin ich damit durch. Nun kann ich mich wieder auf das Implementieren echter Features konzentrieren.
weiterführende Links: