<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>lemmingzshadow.net &#187; Performance - lemmingzshadow.net - a webdevel&#039;s weblog</title>
	<atom:link href="http://lemmingzshadow.net/tag/performance/feed/" rel="self" type="application/rss+xml" />
	<link>http://lemmingzshadow.net</link>
	<description>a webdevel&#039;s weblog</description>
	<lastBuildDate>Fri, 27 Apr 2012 20:35:38 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.3.2</generator>
		<item>
		<title>Performante PHP Projekte &#8211; Teil 1</title>
		<link>http://lemmingzshadow.net/449/performante-php-projekte-teil-1/</link>
		<comments>http://lemmingzshadow.net/449/performante-php-projekte-teil-1/#comments</comments>
		<pubDate>Fri, 27 Apr 2012 20:35:31 +0000</pubDate>
		<dc:creator>Lemmingz Shadow</dc:creator>
				<category><![CDATA[Uncategorized]]></category>
		<category><![CDATA[Lighttpd]]></category>
		<category><![CDATA[Performance]]></category>
		<category><![CDATA[PHP]]></category>
		<category><![CDATA[XCache]]></category>

		<guid isPermaLink="false">http://lemmingzshadow.net/?p=449</guid>
		<description><![CDATA[Immer mal wieder höre oder lese ich, dass man mit PHP keine performaten Webprojekte umsetzen könne. Satt aber nun einen weiteren PHP vs. Sprache-X Artikel zu verfassen habe ich mir überlegt stattdessen ein paar Tipps zu geben wie man meiner Meinung nach die Performance von PHP-Projekten optimieren kann. Da dies ein sehr umfangreiches Thema ist [...]]]></description>
			<content:encoded><![CDATA[<p>Immer mal wieder höre oder lese ich, dass man mit PHP keine performaten Webprojekte umsetzen könne. Satt aber nun einen weiteren PHP vs. Sprache-X Artikel zu verfassen habe ich mir überlegt stattdessen ein paar Tipps zu geben wie man meiner Meinung nach die Performance von PHP-Projekten optimieren kann. Da dies ein sehr umfangreiches Thema ist werde ich das Ganze in mehrere Artikel aufteilen. Anfangen werde ich in diesem ersten Beitrag mit ein paar Tipps zum Webserver.</p>
<p><strong>Lighttpd mit PHP-FPM</strong></p>
<p>Die meisten Root- oder V-Server werden in der Standard-Konfiguration ganz ohne Webserver oder mit Apache2 ausgeliefert. Mein Tipp hier: Alternativen testen! <a href="http://www.lighttpd.net/">Lighttpd </a>oder <a href="http://nginx.org/">Nginx</a> sind in vielen Fällen schneller und benötigen weniger Ressourcen. Jeder Webserver hat seine Vor- und Nachteile, es kann also nicht schaden die Alternativen einmal zu testen. Ich persönlich verwende schon seit längerem Lighttpd und bin sehr zufrieden damit. Die Konfiguration der verschieden Webserver sollte Dank zahlreicher Tutorials die im Netz verfügbar sind kein Problem darstellen.<br />
Desweiteren empfehle ich dringen statt des &#8220;üblichen&#8221; PHP-Moduls (mod_php) <a href="http://php-fpm.org/">PHP-FPM</a> zu verwenden.<span id="more-449"></span> Zusammen mit Lighttpd oder Nginx schafft ein Server so nicht selten wesentlich mehr Requests/Sec abzuarbeiten. Darüber hinaus bietet PHP-FPM einige sehr nützliche Features wie z.b. das Anlegen verschiedener Pools. Damit ist es möglich verschiedenen PHP-Prozesse mit verschiedenen Benutzern zu starten. Das bringt Sicherheits-Vorteile mit sich und lässt Schreibrechte-Probleme der Vergangenheit angehören. Zum Thema Lighttpd und PHP-FPM habe ich hier auch schon andere Beiträge <a href="http://lemmingzshadow.net/tag/lighttpd/">verfasst</a>.</p>
<p><strong>Opcode Caching mit XCache</strong></p>
<p><a href="http://lemmingzshadow.net/files/2012/04/xcache_admin.jpg" rel="facebox" rel="attachment wp-att-456"><img src="http://lemmingzshadow.net/files/2012/04/xcache_admin-150x150.jpg" alt="" title="xcache_admin" width="150" height="150" class="alignleft size-thumbnail wp-image-456" /></a>Da PHP keinen eigenen Opcode-Cache mit sich bringt fehlt dieser häufig auf Webserver. Ein Opcode oder <a href="http://de.wikipedia.org/wiki/PHP#Bytecode-Caching">Bytecode-Cache</a> sorgt dafür, dass PHP-Scripte nicht bei jedem Aufruf neu in Bytecode übersetzt werden müssen. Besonders bei vielen gleichzeitigen Anfragen an den Webserver kann ein solcher Cache die CPU-Last erheblich verringern. Neben dem Zend-Optimizer, eAccelerator und APC gibt es hier noch meinen persönlichen Favoriten <a href="http://xcache.lighttpd.net/">XCache</a>. Installation und Konfiguration sollten keine Probleme bereiten, da es für quasi jede Linux-Distribution bereits fertige Pakete gibt.<br />
Hinweisen möchte ich jedoch noch auf das <a href="http://xcache.lighttpd.net/wiki/InstallAdministration">XCache-Admin Feature</a> denn hier kann man gut sehen ob und wie gut der Opcode-Cache tatsächlich arbeitet. Die obere &#8220;Total&#8221; Zeile zeigt an wie viele der Requests aus dem Cache (hits) ausgeliefert werden konnten und wie viele nicht (misses). Ausserdem kann man sehen wie viel der zur Verfügung stehen Speichers aktuell benutzt wird. Sollte der Wert der Misses im Verhältnis zu den Hits sehr hoch sein, ist es ggf. sinnvoll XCache etwas mehr Speicher zu Verfügung zu stellen.</p>
<p><strong>Requests begrenzen &#8211; mod_evasive und mod_status</strong></p>
<p><a href="http://lemmingzshadow.net/files/2012/04/mod_status.jpg" rel="facebox" rel="attachment wp-att-450"><img src="http://lemmingzshadow.net/files/2012/04/mod_status-150x150.jpg" alt="" title="mod_status" width="150" height="150" class="alignleft size-thumbnail wp-image-450" /></a>Über Sinn oder Unsinn von Modulen wie <a href="http://redmine.lighttpd.net/projects/lighttpd/wiki/Docs:ModEvasive">mod_evasive</a> kann man sich selbstverständlich streiten und mir ist klar, dass keines dieser Module einem richtigen DDoS Angriff entgegenwirken kann, das liegt in der Natur der Sachen. Dennoch halte ich den Einsatz für sinnvoll, denn vielen &#8220;Script-Kiddy&#8221;-, Spam-, Brutforce- und sonstigen Attacken kann man damit einen Riegel vorschieben. Mod_evasive mach im Prinzip nichts weiter als die Requets pro IP auf den Webserver zu limitieren. Eine gute Übersicht über die Requests die Lighttp aktuell verabeitet liefert das Modul <a href="http://redmine.lighttpd.net/projects/lighttpd/wiki/Docs:ModStatus">mod_status</a>.</p>
<p><strong>Lasttest</strong><br />
Nachdem man nun alle (oder einen Teil) dieser Optimierungen vorgenommen hat. Sollte man seinen Webserver mit einem simplen Lasttest durchführen um zu sehen ob der Webserver wirklich durchhält wenn er ein paar parallele Requests abzuarbeiten hat. Tools für diese Aufgabe sind zum Beispiel <a href="http://httpd.apache.org/docs/2.0/programs/ab.html">Apache Benchmark</a> oder <a href="http://www.loadui.org/">LoadUI</a>. Am besten startet man mit einigen wenigen Anfragen pro Sekunde und schaut auf der Konsole des Server wie sich da auf die Last auswirkt. Da man bei solchen Lasttests in der Regel nur von einer IP aus testet kann man hier auch direkt prüfen ob mod_evasive korrekt funktioniert. Ist das der Falls sollte man die Anfragen pro Sekunde im Lasttest-Tools quasi beliebig nach oben schrauben können ohne das die Serverlast merklich steigt. Wie viele Requests/Sec ein Server verträgt hängt natürlich start von der Hardware und dem aufgerufenen Script ab.<br />
Neben den Requests pro Sekunde sollte man auch noch darauf achten ob alle Anfragen nach einer bestimmten Zeit wieder geschlossen werden. Hierzu kann an einen Blick auf die mod_status Weboberfläche werden. Normalerweise sollten allen Verbindungen nach einer kurzen Zeit wieder geschlossen werden. Wenn Verbindungen für eine sehr lange Zeit offen bleiben oder gar nicht geschlossen werden, sollten die entsprechenden Parameter in der Konfiguration noch einmal überprüft werden.</p>
<p>Ich hoffe ich konnte in diesem kurzen Anriss zum Thema Webserver-Konfiguration auf die häufigsten Performance-Bremsen eingehen und ein paar nützliche Tipps geben. Anregungen natürlich wie immer hin den Kommentaren.</p>
<p>Im zweiten Teil der &#8220;Performance-Reihe&#8221; wird es dann um Datenbank-Abfragen gehen, bzw. darum wie man hier optimieren kann.</p>
]]></content:encoded>
			<wfw:commentRss>http://lemmingzshadow.net/449/performante-php-projekte-teil-1/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>mcrypt_create_iv teilweise sehr langsam</title>
		<link>http://lemmingzshadow.net/366/mcrypt_create_iv-teilweise-sehr-langsam/</link>
		<comments>http://lemmingzshadow.net/366/mcrypt_create_iv-teilweise-sehr-langsam/#comments</comments>
		<pubDate>Mon, 09 May 2011 11:19:54 +0000</pubDate>
		<dc:creator>Lemmingz Shadow</dc:creator>
				<category><![CDATA[Uncategorized]]></category>
		<category><![CDATA[Performance]]></category>
		<category><![CDATA[PHP]]></category>

		<guid isPermaLink="false">http://lemmingzshadow.net/?p=366</guid>
		<description><![CDATA[Für ein privates Projekt bastle ich seit einiger Zeit an einem IRC-Bot wobei folgendes Problem auftrat: Sobald Nachrichten in einem IRC-Channel gelesen oder geschrieben wurden hing das Script für einige Sekunden als würde irgendwo ein sleep ausgeführt. Dies war allerdings nicht immer der Fall und trat zudem nicht auf einem Windows System auf. (Weshalb mein [...]]]></description>
			<content:encoded><![CDATA[<p>Für ein privates Projekt bastle ich seit einiger Zeit an einem IRC-Bot wobei folgendes Problem auftrat:<br />
Sobald Nachrichten in einem IRC-Channel gelesen oder geschrieben wurden hing das Script für einige Sekunden als würde irgendwo ein sleep ausgeführt. Dies war allerdings nicht immer der Fall und trat zudem nicht auf einem Windows System auf. (Weshalb mein Xdebug-Profiling erfolglos war). Es blieb mir also nichts anderes übrig als solange Komponenten des Bots zu deaktivieren bis das Problem nicht mehr auftrat. So stelle ich fest dass, das Problem irgendwo in der Klasse für die FiSH-Verschlüsselung lag.<span id="more-366"></span><br />
Bei genauerer Analyse stelle sich heraus dass die Funktion mcrypt_create_iv aus der Mcrypt-Extension Ursache des Problems war. Diese Funktion generiert eine Initialisierungsvektor für die Ver-/Entschlüsselung und braucht dafür teilweise extrem lange. In meinem Fall 5-6 Sekunden. Eine Lösung für das Problem fand ich auf php.net: Statt MCRYPT_DEV_RANDOM kann man MCRYPT_DEV_URANDOM  als Quelle für die benötigen Zufallswerte benutzen und das Problem ist behoben. Ein simple Änderung mit großer Wirkung.</p>
<p>Vorher:</p>

<div class="wp_syntax"><div class="code"><pre class="php" style="font-family:monospace;"><span style="color: #000088;">$iv</span> <span style="color: #339933;">=</span> <span style="color: #990000;">mcrypt_create_iv</span><span style="color: #009900;">&#40;</span><span style="color: #990000;">mcrypt_enc_get_iv_size</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$td</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">,</span> MCRYPT_DEV_RANDOM<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></pre></div></div>

<p>Nacher:</p>

<div class="wp_syntax"><div class="code"><pre class="php" style="font-family:monospace;"><span style="color: #000088;">$iv</span> <span style="color: #339933;">=</span> <span style="color: #990000;">mcrypt_create_iv</span><span style="color: #009900;">&#40;</span><span style="color: #990000;">mcrypt_enc_get_iv_size</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$td</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">,</span> MCRYPT_DEV_URANDOM<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></pre></div></div>

]]></content:encoded>
			<wfw:commentRss>http://lemmingzshadow.net/366/mcrypt_create_iv-teilweise-sehr-langsam/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>PHP: isset vs. array_key_exists</title>
		<link>http://lemmingzshadow.net/232/php-isset-vs-array_key_exists/</link>
		<comments>http://lemmingzshadow.net/232/php-isset-vs-array_key_exists/#comments</comments>
		<pubDate>Wed, 07 Oct 2009 16:32:29 +0000</pubDate>
		<dc:creator>Lemmingz Shadow</dc:creator>
				<category><![CDATA[Uncategorized]]></category>
		<category><![CDATA[Performance]]></category>
		<category><![CDATA[PHP]]></category>
		<category><![CDATA[Webtechnik]]></category>

		<guid isPermaLink="false">http://lemmingzshadow.net/?p=232</guid>
		<description><![CDATA[Heute möchte ich mal ein paar Worte zu den Funktionen isset und array_key_exists loswerden. Genauer angeschaut habe ich mir das Verhalten der beiden Funktionen beim Prüfen ob ein Feld in einem Array existiert. Bevor ich zur Performance komme möchte ich jedoch noch auf ein paar Besonderheiten der Funktionen eingehen: Um zu prüfen ob ein Feld [...]]]></description>
			<content:encoded><![CDATA[<p>Heute möchte ich mal ein paar Worte zu den Funktionen <em>isset</em> und <em>array_key_exists</em> loswerden. Genauer angeschaut habe ich mir das Verhalten der beiden Funktionen beim Prüfen ob ein Feld in einem Array existiert. Bevor ich zur Performance komme möchte ich jedoch noch auf ein paar Besonderheiten der Funktionen eingehen:</p>
<p>Um zu prüfen ob ein Feld in einem Array existiert ohne dabei Fehlermeldungen zu erzeugen muss vor beiden Funktionen <em>isset</em> und <em>is_array</em> aufgerufen werden.</p>
<p><strong>Beispiel:</strong></p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
4
</pre></td><td class="code"><pre class="php" style="font-family:monospace;"><span style="color: #b1b100;">if</span><span style="color: #009900;">&#40;</span><span style="color: #990000;">isset</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$foo</span><span style="color: #009900;">&#41;</span> <span style="color: #339933;">&amp;&amp;</span> <span style="color: #990000;">is_array</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$foo</span><span style="color: #009900;">&#41;</span> <span style="color: #339933;">&amp;&amp;</span> <span style="color: #990000;">isset</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$foo</span><span style="color: #009900;">&#91;</span><span style="color: #0000ff;">'bar'</span><span style="color: #009900;">&#93;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span>
<span style="color: #009900;">&#123;</span>
	<span style="color: #000088;">$check</span> <span style="color: #339933;">=</span> <span style="color: #009900; font-weight: bold;">true</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span></pre></td></tr></table></div>


<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
4
</pre></td><td class="code"><pre class="php" style="font-family:monospace;"><span style="color: #b1b100;">if</span><span style="color: #009900;">&#40;</span><span style="color: #990000;">isset</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$foo</span><span style="color: #009900;">&#41;</span> <span style="color: #339933;">&amp;&amp;</span> <span style="color: #990000;">is_array</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$foo</span><span style="color: #009900;">&#41;</span> <span style="color: #339933;">&amp;&amp;</span> <span style="color: #990000;">array_key_exists</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'bar'</span><span style="color: #339933;">,</span> <span style="color: #000088;">$foo</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span>
<span style="color: #009900;">&#123;</span>
	<span style="color: #000088;">$check</span> <span style="color: #339933;">=</span> <span style="color: #009900; font-weight: bold;">true</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span></pre></td></tr></table></div>

<p><span id="more-232"></span><br />
Der Grund hierfür ist nicht immer direkt ersichtlich, deswegen hier die Erklärung:<br />
<em>isset</em> erzeugt zwar keine Notices oder Warnings falls die Variable $foo nicht gesetzt ist, aber es gibt ein anderes Problem. Wenn die Variable $foo vom Typ String ist würde die Prüfung auf ein Array-Feld mit isset true liefern.</p>
<p><strong>Beispiel:</strong></p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
</pre></td><td class="code"><pre class="php" style="font-family:monospace;"><span style="color: #000088;">$foo</span> <span style="color: #339933;">=</span> <span style="color: #0000ff;">'bar'</span><span style="color: #339933;">;</span>
<span style="color: #990000;">var_dump</span><span style="color: #009900;">&#40;</span><span style="color: #990000;">isset</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$foo</span><span style="color: #009900;">&#91;</span><span style="color: #0000ff;">'bar'</span><span style="color: #009900;">&#93;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span> <span style="color: #666666; font-style: italic;">// true</span></pre></td></tr></table></div>

<p>Dieses Verhalten erklärt die Notwendigkeit von <em>is_array</em> vor dem Prüfen mit isset. Das <em>isset</em> vor dem <em>is_array</em> ist schließlich notwendig weil <em>is_array</em> eine Notice erzeugt wenn die zu prüfende Variable nicht gesetzt ist.</p>
<p>Die Funktion<em> array_key_exists</em> erzeugt ein Warning falls das zu prüfende Array nicht existiert oder die übergebene Variable nicht vom Typ Array ist. Somit ist hier ebenfalls die Nutzung von <em>is_array</em> in Kombination mit <em>isset</em> zu empfehlen.</p>
<p>Mit obiger Syntax lässt sich nun eigentlich in beide Fällen prüfen ob ein Feld im einem Array existiert. Dabei ist jedoch eine Ausnahme zu beachten, und zwar der Wert null in einem Array.</p>
<p><strong>Beispiel:</strong></p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
</pre></td><td class="code"><pre class="php" style="font-family:monospace;"><span style="color: #000088;">$foo</span><span style="color: #009900;">&#91;</span><span style="color: #0000ff;">'bar'</span><span style="color: #009900;">&#93;</span> <span style="color: #339933;">=</span> <span style="color: #009900; font-weight: bold;">null</span><span style="color: #339933;">;</span>
<span style="color: #990000;">var_dump</span><span style="color: #009900;">&#40;</span><span style="color: #990000;">isset</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$foo</span><span style="color: #009900;">&#91;</span><span style="color: #0000ff;">'bar'</span><span style="color: #009900;">&#93;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span> <span style="color: #666666; font-style: italic;">// false</span>
<span style="color: #990000;">var_dump</span><span style="color: #009900;">&#40;</span><span style="color: #990000;">array_key_exists</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'bar'</span><span style="color: #339933;">,</span> <span style="color: #000088;">$foo</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span> <span style="color: #666666; font-style: italic;">// true</span></pre></td></tr></table></div>

<p>Damit sollte die Verwendung der beiden Funktionen geklärt sein (falls nicht bitte ich um einen kurzen Kommentar), aber es bleibt die Frage: Welche der beiden Varianten ist schneller, <em>isset</em> oder <em>array_key_exists</em>?<br />
Hier das Ergebnis:<br />
<a href="http://lemmingzshadow.net/files/2009/10/performance_array_key_exists.jpg" rel="facebox"><img src="http://lemmingzshadow.net/files/2009/10/performance_array_key_exists-150x150.jpg" alt="performance_array_key_exists" title="performance_array_key_exists" width="150" height="150" class="alignnone size-thumbnail wp-image-240" style="float: left; margin: 5px;" /></a> <a href="http://lemmingzshadow.net/files/2009/10/performance_isset.jpg" rel="facebox"><img src="http://lemmingzshadow.net/files/2009/10/performance_isset-150x150.jpg" alt="performance_isset" title="performance_isset" width="150" height="150" class="alignnone size-thumbnail wp-image-241" style="float: left; margin: 5px;" /></a></p>
<div style="clear: both;"></div>
<p>Klare Sache: <em>isset</em> ist wesentlich schneller als <em>array_key_exists</em>, 10000 Prüfungen dauert nur etwa halb so lange.<br />
Zudem fallen zwei weitere Dinge auf: <em>isset</em> taucht nicht in den Xdebug Ergebnissen auf. Die Begründung ist relativ simpel. Da <em>isset</em> keine Funktion ist sondern lediglich ein Sprachkonstrukt, taucht dieses nicht in den Xdebug-Listings auf. Weiterhin fällt auf, dass is_array fast genauso viel Zeit in Anspruch nimmt wie <em>array_key_exists</em>. Hierfür habe ich leider keine Erklärung, denn ich hätte erwarten dass <em>array_key_exists</em> im Gegensatz zu <em>is_array</em> eine Array-Funktion und damit wesentlich langsamer ist. Falls jemand eine Erklärung hat: Immer her damit!</p>
]]></content:encoded>
			<wfw:commentRss>http://lemmingzshadow.net/232/php-isset-vs-array_key_exists/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>PHP-Performance: preg_match vs. strpos</title>
		<link>http://lemmingzshadow.net/214/php-performance-preg_match-vs-strpos/</link>
		<comments>http://lemmingzshadow.net/214/php-performance-preg_match-vs-strpos/#comments</comments>
		<pubDate>Thu, 01 Oct 2009 17:40:42 +0000</pubDate>
		<dc:creator>Lemmingz Shadow</dc:creator>
				<category><![CDATA[Uncategorized]]></category>
		<category><![CDATA[Performance]]></category>
		<category><![CDATA[PHP]]></category>
		<category><![CDATA[Webtechnik]]></category>

		<guid isPermaLink="false">http://lemmingzshadow.net/?p=214</guid>
		<description><![CDATA[Folgendes Problem hat man als Coder sicherlich öfters zu lösen: Man möchte wissen ob String A, String B oder String C (u.s.w) in einem Text vorkommen. Beispielsweise holt man eine Liste mit Keywords aus einer Datenbank und möchte wissen ob eins dieser Keywords in einem Text vorkommt. Um das Problem zu lösen gibt es sicherlich [...]]]></description>
			<content:encoded><![CDATA[<p>Folgendes Problem hat man als Coder sicherlich öfters zu lösen: Man möchte wissen ob String A,  String B oder String C (u.s.w) in einem Text vorkommen. Beispielsweise holt man eine Liste mit Keywords aus einer Datenbank und möchte wissen ob eins dieser Keywords in einem Text vorkommt.<br />
Um das Problem zu lösen gibt es sicherlich zig verschiedene Möglichkeiten. Die gängigsten sehen wahrscheinlich in etwas so aus:</p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
4
</pre></td><td class="code"><pre class="php" style="font-family:monospace;"><span style="color: #b1b100;">if</span><span style="color: #009900;">&#40;</span><span style="color: #990000;">stripos</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$haystack</span><span style="color: #339933;">,</span> <span style="color: #000088;">$needle</span><span style="color: #009900;">&#41;</span> <span style="color: #339933;">!==</span> <span style="color: #009900; font-weight: bold;">false</span><span style="color: #009900;">&#41;</span>
<span style="color: #009900;">&#123;</span>
	<span style="color: #000088;">$found</span> <span style="color: #339933;">=</span> <span style="color: #009900; font-weight: bold;">true</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span></pre></td></tr></table></div>


<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
4
</pre></td><td class="code"><pre class="php" style="font-family:monospace;"><span style="color: #b1b100;">if</span><span style="color: #009900;">&#40;</span><span style="color: #990000;">preg_match</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'/'</span><span style="color: #339933;">.</span><span style="color: #000088;">$needle</span><span style="color: #339933;">.</span><span style="color: #0000ff;">'/is'</span><span style="color: #339933;">,</span> <span style="color: #000088;">$haystack</span><span style="color: #009900;">&#41;</span> <span style="color: #339933;">==</span> <span style="color: #cc66cc;">1</span><span style="color: #009900;">&#41;</span>
<span style="color: #009900;">&#123;</span>
	<span style="color: #000088;">$found</span> <span style="color: #339933;">=</span> <span style="color: #009900; font-weight: bold;">true</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span></pre></td></tr></table></div>

<p><span id="more-214"></span><br />
Hierbei wird eine Sache schnell klar: Bei mehr als einem Suchsting wird das ganze etwas komplizierter. Man muss die strpos Variante für jeden Suchstring einmal laufen lassen, bzw. in der zweiten Variante die Suchstrings mit einem oder verknüpfen.<br />
Die Frage ist nun: Welche der beiden Varianten ist schneller?</p>
<p>Ich habe ein kurzes Testscript gebastelt, und hier ist das Ergebnis:<br />
<a href="http://lemmingzshadow.net/files/2009/10/performance_preg_match.jpg" rel="facebox"><img src="http://lemmingzshadow.net/files/2009/10/performance_preg_match-150x150.jpg" alt="performance_preg_match" title="performance_preg_match" width="150" height="150" class="alignnone size-thumbnail wp-image-217" style="margin: 5px; float: left;" /></a> <a href="http://lemmingzshadow.net/files/2009/10/performance_strpos.jpg" rel="facebox"><img src="http://lemmingzshadow.net/files/2009/10/performance_strpos-150x150.jpg" alt="performance_strpos" title="performance_strpos" width="150" height="150" class="alignnone size-thumbnail wp-image-228" style="margin: 5px; float: left;" /></a>
<div style="clear: both;"></div>
<p>Die preg_match Varinate ist um einiges schneller. Ausserdem fällt auf das bei 10000 Durchläufen des Testscript die Funktion stripos öfter als 10000 mal ausgeführt wird. Die liegt daran, dass die Funktion so oft aufgerufen werden muss, bis der erste Suchstring gefunden wurde (oder eben keiner der gesuchten Strings im Text vorkommt). Durch die oder-Verknüpfung der einzelnen Strings muss preg_match bei jedem Durchlauf nur einmal ausgeführt werden.<br />
Klar wird also: Je mehr Suchstrings in einem Text gesucht werden sollen, desto langsamer wird die strpos Variante im Vergleich zu preg_match, obwohl natürlich auch der reguläre Ausdruck bei einem längeren Suchstring etwas langsamer wird.</p>
<p>Zum Schluss noch das Script mit dem ich dieses Verhalten getestet habe:<br />
<a href='http://lemmingzshadow.net/files/2009/10/performance_preg_vs_strpos_php.txt'>performance_preg_vs_strpos.php</a></p>
]]></content:encoded>
			<wfw:commentRss>http://lemmingzshadow.net/214/php-performance-preg_match-vs-strpos/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>PHPIDS im Praxistest</title>
		<link>http://lemmingzshadow.net/10/phpids-im-praxistest/</link>
		<comments>http://lemmingzshadow.net/10/phpids-im-praxistest/#comments</comments>
		<pubDate>Mon, 02 Jun 2008 21:33:56 +0000</pubDate>
		<dc:creator>Lemmingz Shadow</dc:creator>
				<category><![CDATA[Uncategorized]]></category>
		<category><![CDATA[Performance]]></category>
		<category><![CDATA[PHP]]></category>
		<category><![CDATA[PHPIDS]]></category>
		<category><![CDATA[Security]]></category>
		<category><![CDATA[Test]]></category>

		<guid isPermaLink="false">http://lemmingzshadow.net/?p=10</guid>
		<description><![CDATA[Nachdem ich in letzter Zeit einiges über das Intrusion-Detection-System PHPIDS gelesen habe, habe ich es nun selbst einmal getestet. Hier meine bisherigen Erfahrungen: Testumgebung Für den Test habe ich Projekt genutzt welches sich derzeit noch in der Entwicklung befindet. Das Projekt liegt lokal auf einem Thinkpad T42 (1,7Ghz und 2GB Ram) in einer XAMPP-Umgebung mit [...]]]></description>
			<content:encoded><![CDATA[<p>Nachdem ich in letzter Zeit einiges über das Intrusion-Detection-System <a href="http://php-ids.org/">PHPIDS</a> gelesen habe, habe ich es nun selbst einmal getestet. Hier meine bisherigen Erfahrungen:</p>
<p><strong>Testumgebung</strong><br />
Für den Test habe ich Projekt genutzt welches sich derzeit noch in der Entwicklung befindet.<br />
Das Projekt liegt lokal auf einem Thinkpad T42 (1,7Ghz und 2GB Ram) in einer XAMPP-Umgebung mit XDEBUG.<br />
<span id="more-10"></span><br />
<strong>Installation / Integration</strong><br />
Zunächst müssen die PHPIDS-Dateien (es reicht das Verzeichnis &#8220;lib/IDS&#8221;) auf den Server geladen werden. Das Verzeichnis &#8220;IDS/tmp&#8221; benötigt Schreibrechte falls man dort Log- oder Cache-Files ablegen möchte. Anschließend  müssen in der Datei Config.ini (IDS/Config) ein paar Einstellungen angepasst werden. Die Datei ist selbsterklärend, ich habe jedoch nur die Pfade angepasst da ich für meinen Test auf Logging oder Caching in einer Datenbank verzichtet habe.</p>
<p>Die Integration von PHPIDS in ein bestehendes Projekt hängt natürlich sehr stark vom Projekt selbst ab. In meinem Testfall werden sämtliche Anfragen per mod_rewrite auf die Datei index.php umgeleitet. Dort wird unter anderem eine Klasse <em>security</em> instanziert welche verschiedene Methoden zur Input-Validierung enthält. Eine dieser Methoden (<em>validate_request</em>) wird bei jedem Aufruf des Projektes ausgeführt und ist somit der ideale Ansatzpunkt für PHPIDS.<br />
Das ist der hier relevante Teil der<em> security</em>-Klasse:</p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
</pre></td><td class="code"><pre class="php" style="font-family:monospace;"><span style="color: #666666; font-style: italic;">// include-path auf den Ordner mit IDS setzen:</span>
<span style="color: #990000;">ini_set</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'include_path'</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">'/path/to/libs'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #666666; font-style: italic;">// IDS einbinden:</span>
<span style="color: #b1b100;">require_once</span> <span style="color: #0000ff;">'IDS/Init.php'</span><span style="color: #339933;">;</span>
<span style="color: #666666; font-style: italic;">// Array mit möglichen User-Inputs bilden:</span>
<span style="color: #000088;">$request</span> <span style="color: #339933;">=</span> <span style="color: #990000;">array</span><span style="color: #009900;">&#40;</span>
	<span style="color: #0000ff;">'REQUEST'</span> <span style="color: #339933;">=&gt;</span> <span style="color: #000088;">$GLOBALS</span><span style="color: #009900;">&#91;</span><span style="color: #0000ff;">'_REQUEST'</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">,</span>
	<span style="color: #0000ff;">'GET'</span> <span style="color: #339933;">=&gt;</span> <span style="color: #000088;">$GLOBALS</span><span style="color: #009900;">&#91;</span><span style="color: #0000ff;">'_GET'</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">,</span>
	<span style="color: #0000ff;">'POST'</span> <span style="color: #339933;">=&gt;</span> <span style="color: #000088;">$GLOBALS</span><span style="color: #009900;">&#91;</span><span style="color: #0000ff;">'_POST'</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">,</span>
	<span style="color: #0000ff;">'COOKIE'</span> <span style="color: #339933;">=&gt;</span> <span style="color: #000088;">$GLOBALS</span><span style="color: #009900;">&#91;</span><span style="color: #0000ff;">'_COOKIE'</span><span style="color: #009900;">&#93;</span>
<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #666666; font-style: italic;">// IDS initialisieren:</span>
<span style="color: #000088;">$init</span> <span style="color: #339933;">=</span> IDS_Init<span style="color: #339933;">::</span><span style="color: #004000;">init</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'/path/to/libs/IDS/Config/Config.ini'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #666666; font-style: italic;">// Caching ausschalten:</span>
<span style="color: #000088;">$init</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">config</span><span style="color: #009900;">&#91;</span><span style="color: #0000ff;">'Caching'</span><span style="color: #009900;">&#93;</span><span style="color: #009900;">&#91;</span><span style="color: #0000ff;">'caching'</span><span style="color: #009900;">&#93;</span> <span style="color: #339933;">=</span> <span style="color: #0000ff;">'none'</span><span style="color: #339933;">;</span>
<span style="color: #666666; font-style: italic;">// Request-Array analysieren:</span>
<span style="color: #000088;">$ids</span> <span style="color: #339933;">=</span> <span style="color: #000000; font-weight: bold;">new</span> IDS_Monitor<span style="color: #009900;">&#40;</span><span style="color: #000088;">$request</span><span style="color: #339933;">,</span> <span style="color: #000088;">$init</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #000088;">$result</span> <span style="color: #339933;">=</span> <span style="color: #000088;">$ids</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">run</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #666666; font-style: italic;">// Impact abfragen und ggf. reagieren:</span>
<span style="color: #b1b100;">if</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$result</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">getImpact</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #339933;">&gt;</span> <span style="color: #cc66cc;">1</span><span style="color: #009900;">&#41;</span>
<span style="color: #009900;">&#123;</span>
	<span style="color: #990000;">die</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'Hacking attempt detected. IP logged.'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span>
<span style="color: #666666; font-style: italic;">// include-path auf seinen ursprünglichen Wert zurücksetzten:</span>
<span style="color: #990000;">ini_restore</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'include_path'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></pre></td></tr></table></div>

<p>Was hier passiert ist schnell erklärt:<br />
Es wird ein Array gebildet welches alle Variablen enthält die vom Benutzer beeinflusst werden können, etwa durch Formulareingaben oder Ähnliches. Der Inhalt dieses Arrays wird nun von PHPIDS auf mögliche Angriffsversuche untersucht. Mögliche Angriffe wären z.B. XSS oder SQL-Injection Attacken. Erkannte Angriffe werden von PHPIDS bewertet. Je &#8220;gefährlicher&#8221; oder &#8220;bedrohlicher&#8221; ein Angriff ist, desto höher ist der Impact-Wert. Im obigen Beispiel wird das Script sofort beendet sobald der Wert größer als 1 ist.</p>
<p><strong>Performance</strong><br />
Aufgrund vieler regulärer Ausdrücke u.Ä. ist PHPIDS sicherlich nicht extrem Performant, aber es ist auch nicht extrem langsam. In meinen Test gab es nur einen Angriff der PHPIDS quasi in die Knie gezwungen hat. (Genaueres weiter unten) Ob man dieses Tool nun auf einer High-Performance Webseite einsetzen kann ist schwer zu sagen. Hier kommt es sicherlich auf die Server, das Caching und viele andere Dinge an.<br />
Hier jedoch ein kurzer Vergleich der Methode validate_request mit und ohne PHPIDS (eingebunden wie oben beschrieben). Es handelt sich um einen einfachen Aufruf der Seite ohne dass irgendwelche Angriffe versucht werden.<br />
<a href='http://lemmingzshadow.net/files/2008/06/phpids_performance1.jpg' rel="facebox"><img src="http://lemmingzshadow.net/files/2008/06/phpids_performance1-150x150.jpg" alt="" title="phpids_performance1" width="150" height="150" class="alignnone size-thumbnail wp-image-11" style="float: left; margin: 5px;" /></a> <a href='http://lemmingzshadow.net/files/2008/06/phpids_performance2.jpg' rel="facebox"><img src="http://lemmingzshadow.net/files/2008/06/phpids_performance2-150x150.jpg" alt="" title="phpids_performance2" width="150" height="150" class="alignnone size-thumbnail wp-image-12" style="margin: 5px;" /></a></p>
<p>Bei Standard-XSS-Angriffsversuchen wie man sie z.B. <a href="http://ha.ckers.org/xss.html">hier</a> findet gehen die Zeiten leicht nach oben, bleiben aber immer im Rahmen. Hier das Ergebnis bei einem GET-Parameter mit folgendem Imhalt:</p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
</pre></td><td class="code"><pre class="html" style="font-family:monospace;">&lt;img SRC=&quot;javascript:alert('XSS');&quot;&gt;</pre></td></tr></table></div>

<p><a href='http://lemmingzshadow.net/files/2008/06/phpids_performance3.jpg' rel="facebox"><img src="http://lemmingzshadow.net/files/2008/06/phpids_performance3-150x150.jpg" alt="" title="phpids_performance3" width="150" height="150" class="alignnone size-thumbnail wp-image-13" style="margin: 5px;" /></a></p>
<p>Einen Fall konnte ich jedoch finden, bei dem PHPIDS stark einbricht. Es handelt sich um einen SQL-Injection Angriff der kürzlich verwendet wurde um Javascript auf vielen Webseiten einzuschleusen. <a href="http://www.heise.de/security/Hunderttausende-Webseiten-mit-schaedlichem-JavaScript-infiziert--/news/meldung/106959">(Artikel bei heise.de</a>)<br />
Wird der String aus diesem Angriff per GET-Parameter übergeben steigt die Prozessorlast extrem an und das Script braucht lange für die Ausführung. Verantwortlich dafür sind 164 Aufrufe der Funktion preg_match die extrem lange brauchen. In meinem Test waren es über 4000ms.<br />
<a href='http://lemmingzshadow.net/files/2008/06/phpids_performance4.jpg' rel="facebox"><img src="http://lemmingzshadow.net/files/2008/06/phpids_performance4-150x150.jpg" alt="" title="phpids_performance4" width="150" height="150" class="alignnone size-thumbnail wp-image-14" style="float: left; margin: 5px;" /></a> <a href='http://lemmingzshadow.net/files/2008/06/phpids_performance5.jpg' rel="facebox"><img src="http://lemmingzshadow.net/files/2008/06/phpids_performance5-150x150.jpg" alt="" title="phpids_performance5" width="150" height="150" class="alignnone size-thumbnail wp-image-15" style="margin: 5px;" /></a></p>
<p><strong>Fazit</strong><br />
PHPIDS ist ein sehr nützliches Hilfsmittel um viele Angriffe auf Webprojekte zu erkennen. Die Installation ist kinderleicht und auch bei der Integration in ein bestehendes Projekt sollte es keine größeren Probleme geben.<br />
Auf zwei Dinge möchte ich jedoch Hinweisen:<br />
1. PHPIDS ist ein System zur <strong>Erkennung</strong> von Angriffen, es ist nicht dazu da sie zu verhindern oder zu blockieren. Diese Aufgabe muss ein Entwickler selbst übernehmen.<br />
2. PHPIDS verwendet teilweise viele reguläre Ausdrücke welche resourcenhungrig sind. Bei High-Traffic Projekten sollte man deshalb ein Auge auf die Serverlast haben und sich das PHPIDS-Caching genauer anschauen.</p>
]]></content:encoded>
			<wfw:commentRss>http://lemmingzshadow.net/10/phpids-im-praxistest/feed/</wfw:commentRss>
		<slash:comments>9</slash:comments>
		</item>
	</channel>
</rss>

