PHP 7.2 - Mcrypt durch OpenSSL ersetzen

Thema: Replace mcrypt_encrypt mit openssl_encrypt in PHP

Hallo liebe Leser,
die Zeit schreitet voran und mittlerweile gibt es seit Ende 2018 auch PHP 7.3. Was viele Leute aber bis heute nicht getan haben ist die Migration Ihres alten Verschlüsselungscodes basierend auf der mcrypt Library zu etwas modernerem wie OpenSSL, welches seit PHP 7.2 als Standard implementiert wurde und mcrypt abgelöst hat. In PHP7.2 wurde außerdem die Krypto-Library LibSodium integriert welche moderne und starke Verschlüsselungsmethoden zur Verfügung stellt.

Mcrypt Beispiel ersetzen mit OpenSSL

Vor uns liegt nun ein typisches MCrypt Beispiel Konstrukt welches wir zu OpenSSL Abwärtskompatibel portieren möchten.

Mcrypt Code:


Der equivalente OpenSSL PHP Code dazu würde wie folgt aussehen:

OpenSSL Code:


Wie Ihr sehen könnt, hat sich bei OpenSSL die Methode geändert, in diesem Fall entspricht 'aes-128-cbc' der Mcrypt Methode 'cbc'. Wenn diese Option 'OPENSSL_RAW_DATA' gesetzt ist gibt openssl_encrypt lediglich die Rohdaten zurück. Denn standardmäßig macht openssl_encrypt schon ein base64_encode auf das Ergebnis, wird die Option gesetzt geschieht dies nicht automatisch.

Das Beispiel ist relativ einfach gehalten um die grundlegende Mechanik und den Unterschied deutlich sichtbar zu machen. Außerdem wird empfohlen einen zufälligen IV zu generieren und einen Schlüssel mit entsprechender länge.

Für tiefgründigeres Wissen über OpenSSL in PHP empfehle ich die Dokumentation auf PHP.net, dort erfahrt Ihr ausführlich erklärt alle Einzelheiten über die verfügbaren OpenSSL Funktionen in PHP.

Falls Ihr gute oder schlechte Erfahrungen mit OpenSSL oder Mcrypt in PHP gemacht habt dann hinterlasst doch ein Kommentar. Ansonsten hoffe ich das euch dieser Artikel ein Schritt in die richtige Richtung weisen konnte.

PHP-FPM Einstellungen optimieren

Heute geht es darum den unter PHP Nutzern bekannten FastCGI Process Manager (FPM) richtig zu konfigurieren und zu optimieren. (https://php-fpm.org/)

Die meisten PHP Anwendungen verwenden Heutzutage den PHP-FPM um Ihre PHP Anwendungen auszuliefern. In Kombination mit NGINX als Webserver ist dies mit einer der effektivsten Methoden eine Webanwendung mit PHP im Produktiveinsatz laufen zu lassen.

Der Teufel steckt im Detail

Bei FPM reichen schon ein paar falsch gesetzte Werte und schon startet der FPM Prozess nicht mehr oder der Speicher des Servers läuft voll oder oder oder ... die Liste ist lang ;)

Häufige Fehler die auftreten können:
  • FPM Master Prozess startet nicht mehr
  • RAM des Servers läuft voll
  • "server reached max_children"

Prüfen ob PHP-FPM Prozess läuft

Das Beispiel zeigt die PHP-FPM Prozesse und für welche pool Konfiguration / User diese ist, in dem Falle zu sehen "web1" da unter ISPConfig der erste angelegt Host "web1" ist.
ps aux | grep fpm

PHP-FPM Konfiguration anpassen

In diesem Beispiel hier zeige ich euch wie Ihr die Konfiguration anpasst anhand einer ISPConfig Standard Installation mit einer angelegten Webseite. Dazu bearbeiten wir die Datei:

nano /etc/php/7.0/fpm/pool.d/web1.conf

Der Inhalt der Datei sieht dann so aus (kann je nach Installation abweichen):

[web1]

listen = /var/lib/php7.0-fpm/web1.sock
listen.owner = web1
listen.group = www-data
listen.mode = 0660

user = web1
group = www-data

pm = dynamic
pm.max_children = 50
pm.start_servers = 12
pm.min_spare_servers = 8
pm.max_spare_servers = 24
pm.max_requests = 1000

....
....

Ich werde jetzt die wichtigsten Einstellung im Detail erklären und euch gegebenenfalls Hinweise dazu geben. Aber fangen wir direkt an mit der wohl wichtigsten Einstellung "pm.max_children".

Wichtigste PHP-FPM Einstellungen einfach erklärt

  • pm (string)
    • es gibt 3 mögliche Einstellungen, dynamic ist meistens die beste Wahl
      • static - Anzahl der Kindprozesse ist fest (pm.max_children)
      • ondemand - Kindprozess wird erst erstellt wenn er benötigt wird (pm.start_servers)
      • dynamic - dynamische Einstellung der Kindprozesse (benötigt folgenden Einstellungen: pm.max_children, pm.start_servers, pm.min_spare_servers, pm.max_spare_servers)
  • pm.max_children (int)
    • Anzahl der Kindprozesse die erstellt werden wenn pm = static oder die maximale Anzahl der Kindprozesse wenn pm = dynamic. Einstellung ist notwendig!
  • pm.start_servers (int)
    • Anzahl an Kindprozessen, die beim Start erstellt werden. Wird nur verwendet, wenn pm auf dynamic gesetzt ist. Standardwert: min_spare_servers + (max_spare_servers - min_spare_servers) / 2.
  • pm.min_spare_servers (int)
    • gewünschte Mindestanzahl an Prozessen. Wird nur genutzt, wenn pm auf dynamic gesetzt ist. Zwingend notwendig!
  • pm.max_spare_servers (int)
    • gewünschte Maximalanzahl an Prozessen. Wird nur genutzt, wenn pm auf dynamic gesetzt ist. Zwingend notwendig!
  • pm.max_requests (int)
    • Anzahl der Requests bis der FPM Prozess neustartet, hilft Memory Leaks in einigen PHP Libs zu fixen
Noch viele weitere und detailliertere Beschreibungen könnt Ihr in der Dokumentation von PHP finden.

Optimalen Wert für "pm.max_children" bestimmen

Um den perfekten Wert für pm.max_children zu finden muss man zuerst herausfinden wieviel Speicher ein FPM Prozess mit der aktuellen Anwendung verbraucht. Dazu können wir auf 2 verschiedenen Befehle zurück greifen.

ps -ylC php-fpm7.0 --sort:rss

Das sollte dann in etwa so bei euch aussehen:
Für uns von Bedeutung ist die Spalte "RSS" diese gibt den Speicherverbrauch des Prozesses in Kilobyte an. Also wären 43868 rund ~ 43MB für diesen Prozess. Um das ganze etwas zu vereinfachen können wir aber einfach den Befehl ausführen und erhalten den Durchschnitt.

ps --no-headers -o "rss,cmd" -C php-fpm7.0 | awk '{ sum+=$1 } END { printf ("%d%s\n", sum/NR/1024,"Mb") }'

// Output
34Mb

Mit diesem Verbrauchswert können wir nun den passenden Wert für pm.max_children berechnen. Dazu nehme ich einfach mal ein Beispiel (einen VPS der 2GB RAM hat).
  • VPS mit 2 GB RAM
    • wir ziehen 256 MB ab da noch andere Dienste auf dem VPS laufen
    • uns bleiben 1792 MB Ram
      • Formel: max_children = Free RAM VPS / RAM pro Prozess
      • max_children = 1792 / 34
      • = 52,7 = ~ 52
Der Ideale Wert für diesen VPS wäre also pm.max_children = 52. Natürlich sollte man diesen Wert nicht einfach Blind übernehmen! Ändert eure Einstellungen und dann testet wie sich euer Server verhält. Wenn Ihr eure Konfiguration angepasst habt, startet Ihr am besten euer FPM neu. Dies könnt Ihr mit folgendem Befehl machen:

sudo /etc/init.d/php7.0-fpm restart

Resümee

Ein optimal Konfigurierter PHP-FPM Service erspart euch auf eurem Produktivsystem eine Menge ärger. Denn niemand möchte einen überlaufenden Speicher oder eine langsame PHP Anwendung nur weil der FPM Dienst falsch konfiguriert ist. Nehmt euch die Zeit ermittelt die optimalen Werte und setzt diese dann um. Oft hilft es auch die Logs regelmäßig zu checken um sehen ob alles ohne Probleme funktioniert und ob nicht doch der Server bald an seine Grenzen kommt. 

Ich hoffe ich konnte dem ein oder anderem das Mysterium PHP-FPM näher bringen und wünsche euch viel Erfolg beim optimieren eurer Einstellungen.

PHP "< ?=" vs "< ?php echo"

Einleitung

Hi,
heute geht es kurz um das PHP Tag "<?=". Vielleicht kennen es die meisten schon oder benutzen es sogar in Ihrem Code. Das Konstrukt ist schon etwas älter aber ich wollte trotzdem kurz darauf eingehen.

Beispiel: (zwischen < und ? ist ein extra Leerzeichen das da nicht hin soll!)

Lange Schreibweise:
< ?php echo $value; ?>

Kurze Schreibweise:
< ?= $value ?>
Beide Varianten funktionieren und resultieren in der selben Ausgabe.

Wann sollte ich "<?=" nehmen?
  • > PHP 5.4 Standardmäßig aktiv
  • spart Zeichen und Zeit
  • wenn short_open_tag in der php.ini aktiv ist
Wann sollte ich "<?php echo" nehmen?
  • < PHP 5.4
  • wenn man Angst hat das der Syntax irgendwann nicht mehr unterstützt wird
Ab PHP 5.4 ist das Kürzel Standardmäßig aktiv auch wenn die Option "short_open_tag" deaktiviert ist in der php.ini Datei. Man sollte also die Verwendung nicht scheuen ;)

Hier noch mal eine interessante Grafik dazu:

Wer noch mehr Informationen zu dem Thema möchte sollte sich ein mal die Diskussion dazu hier anschauen: Link

Das war es auch schon. Fragen und Anregungen gern in die Kommentare. 

Debug SplObjectStorage, ArrayObject und update Xdebug

Unser Thema: SplObjectStorage, ArrayObject debuggen

Hallo,
heute dreht sich alles um die Frage:
"Wie kann man PHP Klassen die von SplObjectStorage oder ArrayObject erben debuggen und dessen Inhalt sehen?"

Mein Problem

In meinem PHP Projekt benutze ich viele Collection Klassen die von ArrayObject erben. (Erklärung: ArrayObject ist eine PHP interne Klasse die es erlaubt Objekte so wie Arrays arbeiten zu lassen. PHP.net).

Dabei ist mir aufgefallen das ich den Inhalt von solchen Collections nicht in PHPStorm debuggen kann. Ich erhielt nur Meldungen wie "can not get property".

Nach kurzer Recherche im Internet fand ich ich dann auch die Ursache des Problems.





Die Ursache

Die Ursache des Problems war eine veraltet Xdebug Version. In meinem Fall war es die Version 2.2.3 welche die Darstellung von solchen Objekten nicht unterstützte.

Die Lösung

Das Problem war also gefunden nun musste es nur noch gelöst werden. Der Fehler in Xdebug wurde in der Version 2.3.3 behoben. Also musste ich nur eine Version installieren die >2.3.3 ist. (Xdebug Bug Ticket)

Xdebug updaten >2.3.3

Um Xdebug zu aktualisieren müssen wir eigentlich nur eine aktuelle Version herunterladen diese kompilieren und aktivieren. Wie das geht erkläre ich euch jetzt.

Xdebug Wizard hilft euch

Um einfach die für euch empfohlene Xdebug Version herauszufinden könnt Ihr den von der Xdebug Homepage bereitgestellten Wizard benutzen. Xdebug Wizard

Dem Wizard müsst Ihr nur den Inhalt eurer PHPInfo übergeben. Dazu einfach eine Datei anlegen (z.B. info.php) mit dem Inhalt:
<?php echo phpinfo(); 
Den Inhalt der Seite kopiert Ihr mit Strg + A (alles Markieren) und Strg + C (kopieren) in das Feld auf der Wizard Seite.

Der Wizard erzeugt euch dann eine Ausgabe mit einer passenden Installationsanleitung für euer System.

Xdebug herunterladen und kompilieren

  • In /tmp Verzeichnis wechseln
    • Befehl: cd /tmp
  • Xdebug herunterladen
    • Befehl: wget http://xdebug.org/files/xdebug-2.4.1.tgz
  • Archiv entpacken
    • Befehl: tar -xvzf xdebug-2.4.1.tgz
  • In entpackte Verzeichnis wechseln
    • Befehl: cd xdebug-2.4.1
  • Build initialisieren
    • Befehl: phpize
  • Konfigurieren
    • Befehl: ./configure
  • Builden
    • Befehl: make
  • Kompiliertes Modul in PHP Ordner kopieren
    • Befehl: cp modules/xdebug.so /usr/lib/php5/20121212
  • Falls nötig Extension Pfad anpassen in der php.ini
    • nano /etc/php5/apache2/php.ini
    • Einfügen: zend_extension = /usr/lib/php5/20121212/xdebug.so
Bei mir war der letzte Schritt nicht nötig da in meiner php.ini nur die Extension per Name "xdebug.so" geladen wird.

Wichtig! Nach den Änderungen PHP/Apache neustarten, damit die Änderungen wirksam werden.

Ergebnis

Eure phpinfo Datei sollte nun die aktuell installierte Version von Xdebug anzeigen. In etwa so:
Nachdem alles geklappt hat könnt Ihr nun ohne Probleme solche ArrayObject Klassen debuggen :)

Falls Ihr Probleme oder Anregungen habt schreibt diese bitte in die Kommentare.

Viel Spass und bis bald.

PHPStorm Portable machen

PHPStorm Portable machen (in separaten Ordner installieren)

Hier erkläre ich euch wie Ihr die beliebte PHP IDE - PHPStorm portabel machen könnt. Das bedeutet das Programm wird komplett in einem separaten Ordner installiert und auch von dort gestartet. Wo der Ordner liegt (z.B. auf einem USB Stick, Festplatte) ist völlig egal.

Schritt 1: PHPStorm herunterladen

Am besten ladet Ihr PHPStorm von der offiziellen Herstellerseite herunter.
Link: https://www.jetbrains.com/phpstorm/download/

Linux: Archiv in euren wunsch Ordner extrahieren
Windos: PHPStorm Installation in euren Wunschordner vornehmen

Schritt 2: idea.properties im Ordner /bin anpassen

Jetzt müssen wir eine wichtige Anpassung in der idea.properties Datei vornehmen. Diese findet Ihr in dem Ordner /bin eurer PHPStorm installation.

In der Datei tauschen wir die Variablen:
  ${user.home} gegen ${idea.home}

Wichtig!: Die Zeilen müssen einkommentiert werden.

idea.config.path=${idea.home}/.WebIde/config
idea.system.path=${idea.home}/.WebIde/system
idea.plugins.path=${idea.home}/plugins
idea.log.path=${idea.home}/log

Mehr Infos zur Datei idea.proteries: Klick hier

Schritt 3: PHPStorm starten

Im Ordner /bin könnt Ihr nun die phpstorm.sh ausführen und PHPStorm starten.

Fertig. Eure Installation ist nun portable.

PHP Mcrypt Erweiterung installieren (Linux und Windows)


PHP Mcrypt Erweiterung installieren (Linux und Windows)

Heute hatte ich das Problem das die Mcrypt Erweiterung in PHP nicht in meiner VM aktiviert war. Obwohl ich die Erweiterung installiert hatte weigerte sich PHP diese zu benutzen. Dies resultierte in folgenden Fehlermeldungen:
Call to undefined function mcrypt_module_open()
Fatal error: Call to undefined function mcrypt_encrypt()
Durch ein wenig probieren war die Lösung doch einfacher als gedacht. Die Erweiterung wurde einfach nicht vom Apache2 geladen. Durch das Aktivieren und Neustarten des Webservers konnte das Problem gelöst werden und PHP konnte die mcrypt Funktionen ausführen. (PHP 5.5)

Deshalb habe ich hier noch einmal eine kurze Zusammenfassung der Installation und Aktivierung der Mcrypt Erweiterung.  

Anleitung Ubuntu:
  • sudo apt-get install php5-mcrypt
  • sudo service apache2 restart
 // nur benötigt wenn Modul nicht automatisch aktiviert wurde
  • sudo php5enmod mcrypt
  • sudo service apache2 restart  

Anleitung Windows:
  • ;extension=php_mcrypt.dll einkommentieren zu extension=php_mcrypt.dll 
  • Apache Webserver neustarten  

Anleitung Redhat
  • sudo yum install php55-mcrypt //wenn php5.5
  • sudo yum install php-mcrypt //wenn < 5.4 sudo
  • service httpd restart //wenn Apache 2.4
  • sudo /etc/init.d/httpd restart //wenn Apache 2.2 oder niedriger

Um zu überprüfen ob Mcrypt installiert und aktiviert ist kann man einfach eine PHP Datei mit folgendem Inhalt auf seinen Webserver legen. Diese dann aufrufen und die Erweiterung in der Liste suchen.
 <?php phpinfo(); ?>
Wer noch mehr zum Thema Mcrypt wissen will kann gerne noch mal bei PHP.net vorbeischauen.
Link: Mcrypt PHP.net

Uploaded.to API PHP Fix für PHP 5.5

Hi,
ich habe die Uploaded.to API Klasse geschrieben von Julius Fischer dem Betreiber von http://www.it-gecko.de/ an PHP 5.5 angepasst. Dabei habe ich nur eine kleine Änderung am upload Vorgang gemacht und die CURLFile Klasse implementiert.

Orginal API: http://www.it-gecko.de/uploaded-to-api-script.html
API für PHP 5.5: http://www47.zippyshare.com/v/94843895/file.html

Information zur Verwendung:
1. Dateinamen ändern
2. Namespace der Datei anpassen

PBKDF2 Hash Funktion mit PHP


Für den ein oder anderen bestimmt zu gebrauchen ;)

Was ist PBKDF2?
http://de.wikipedia.org/wiki/PBKDF2

Quelle:
https://github.com/defuse/password-hashing/blob/master/PasswordHash.php

Die Funktion in PHP:

Beispiel Nutzung:

echo Hallo Welt


Hallo liebe Leser,
das hier ist mein erster Blog Post und dieser dient eigentlich nur Testzwecken.
Gruß