{"id":6680,"date":"2020-07-18T09:43:00","date_gmt":"2020-07-18T07:43:00","guid":{"rendered":"https:\/\/u-labs.de\/portal\/?p=6680"},"modified":"2020-07-18T09:42:51","modified_gmt":"2020-07-18T07:42:51","slug":"urls-und-andere-zeichenketten-in-http-anfragen-mit-mod_substitute-ersetzen-apache2","status":"publish","type":"post","link":"https:\/\/u-labs.de\/portal\/urls-und-andere-zeichenketten-in-http-anfragen-mit-mod_substitute-ersetzen-apache2\/","title":{"rendered":"Urls und andere Zeichenketten in HTTP-Anfragen mit mod_substitute ersetzen (Apache2)"},"content":{"rendered":"<p>Das Apache-Modul <strong>mod_substitute <\/strong>erlaubt die Ersetzung von Zeichenketten in HTT-Anfragen. Und zwar nicht nur im Header, sondern auch dem Body. Dank regul\u00e4rer Ausdr\u00fccke ist es sehr m\u00e4chtig. <\/p>\n<h2 class=\"wp-block-heading\">Warum Zeichenketten im HTTP-Body ersetzen?<\/h2>\n<p>Im besten Falle ben\u00f6tigt man dieses Modul nicht, weil die Webanwendung selbst einwandfrei funktioniert. Oder man diese wie gew\u00fcnscht anpassen kann. Allerdings gibt es im Alltag verschiedene Konstellationen, in denen das nicht ohne weiteres m\u00f6glich ist. <\/p>\n<p>Beispiele:<\/p>\n<ul class=\"wp-block-list\">\n<li>URLs\/Weiterleitungen sind nicht korrekt. Dies kann\/darf in der Anwendung nicht behoben werden<\/li>\n<li>Eine Applikation soll \u00fcber mehrere URLs erreichbar sein, unterst\u00fctzt dies aber nicht offiziell<\/li>\n<li>Propriet\u00e4re Software, deren Quellcode nicht vorliegt, soll in kleinerem Ma\u00dfe angepasst oder erweitert werden<\/li>\n<\/ul>\n<p>Solche Ersetzungsl\u00f6sungen sollten nicht pauschal angewendet werden! Im Regelfall ist es in verschiedenster Hinsicht besser, diese wenn m\u00f6glich direkt im Backend durchzuf\u00fchren. Bei quelloffener Software z.B. kann die Software wie gew\u00fcnscht angepasst werden. Nur wenn es keine bessere Alternative gibt, sollte man diesen Weg gehen.<\/p>\n<h2 class=\"wp-block-heading\">Was ist zu beachten?<\/h2>\n<p><strong>Gzip <\/strong>ist in Kombination mit <strong>mod_substitute <\/strong>problematisch: Die Inhalte werden in diesem Falle nicht dekompromiert, um diese zu Ersetzen und anschlie\u00dfend wieder zu kompromieren. Dies w\u00e4re performancetechnisch auch nicht unbedingt zu empfehlen. Grunds\u00e4tzlich muss man mit <strong>mod_substitute <\/strong>jedoch nicht per se vollst\u00e4ndig auf die Gzip-Kompression verzichten. <\/p>\n<h3 class=\"wp-block-heading\">Apache nutzt Gzip f\u00fcr eigene Inhalte<\/h3>\n<p>Soll der Apache-Webserver lokal ausgelieferte Inhalte kompromieren, ist schlicht die Reihenfolge entscheidend: mod_substitute muss <strong>vor<\/strong> der Deflate-Kompression stattfinden. Dann wird erst Ersetzt und anschlie\u00dfend Komprimiert. In umgekehrter Reihenfolge findet <strong>keine Ersetzung<\/strong> statt! Mit der korrekten Reihenfolge kann Gzip also <strong>vollst\u00e4ndig genutzt werden<\/strong>.<\/p>\n<h3 class=\"wp-block-heading\">Proxy-Server hinter Apache nutzt Gzip<\/h3>\n<p>Fungiert Apache mit mod_proxy als Reverse-Proxy f\u00fcr einen anderen Webserver, d\u00fcrfen die zu ersetzenden Mime-Typen <strong>keine Gzip-Kompression<\/strong> aufweisen. Ansonsten wird auch hier nichts Ersetzt. Je nachdem um welches Backend es sich handelt, kann man ggf. nur bestimmte Typen komprimieren lassen.<\/p>\n<p><strong>Beispiel Bitbucket:<\/strong><\/p>\n<p>Hier war gew\u00fcnscht, den Bitbucket-Server sowohl intern als auch extern erreichbar zu machen. Allerdings mit verschiedenen Adressen. In der Konfigurationsdatei <strong>${BB_DATA}\/shared\/bitbucket.properties<\/strong> lassen sich die Mime-Types festlegen, f\u00fcr die eine Kompression angewendet werden soll. M\u00f6chten wir Ersetzungen nur in HTML-Seiten durchf\u00fchren, entfernen wir einfach <strong>text\/html<\/strong> aus dieser Liste:<\/p>\n<pre class=\"wp-block-prismatic-blocks\"><code class=\"\" data-line=\"\">server.compression.mime-types=text\/css,text\/javascript,text\/json,text\/plain,text\/xml,text\/x-javascript<\/code><\/pre>\n<p>Alternativ kann die Kompression mit folgendem Schalter auch vollst\u00e4ndig abgeschaltet werden:<\/p>\n<pre class=\"wp-block-prismatic-blocks\"><code class=\"\" data-line=\"\">server.compression.enabled=false<\/code><\/pre>\n<h3 class=\"wp-block-heading\">Alternativ: Gzip f\u00fcr das Backend via Apache deaktivieren<\/h3>\n<p>Falls es keine M\u00f6glichkeit gibt die Komprimierung im Backend zu deaktivieren, gibt es einen Trick: Der Browser sendet die von ihm unterst\u00fctzten Verfahren im <strong>Accept-Encoding<\/strong> Header an den Server. Der Hintergrund ist, dass es verschiedene Kompressionsverfahren (z.B. Gzip oder Brotli) gibt. Nicht alle Clients unterst\u00fctzen s\u00e4mtliche Verfahren. Teilt der Client dem Server \u00fcber diesen Header nicht mit, dass er beispielsweise Gzip unterst\u00fctzt, findet keine Kompression statt.<\/p>\n<p>Dies k\u00f6nnen wir uns zunutze machen, um das Backend zu zwingen, uns die Daten im Klartext auszuliefern:<\/p>\n<pre class=\"wp-block-prismatic-blocks\"><code class=\"language-apache\" data-line=\"\">RequestHeader unset Accept-Encoding<\/code><\/pre>\n<p>Je nach Applikation kann dies auch nur f\u00fcr bestimmte Lokationen gesetzt werden.<\/p>\n<h2 class=\"wp-block-heading\">Ersetzungen von Zeichenketten mit mod_substitute<\/h2>\n<p>Voraussetzung ist zun\u00e4chst, dass <strong>mod_substitute<\/strong> und <strong>mod_filter<\/strong> geladen sind. Das Filter-Modul wird ben\u00f6tigt, um die Ersetzungen auf bestimmte Mime-Types beschr\u00e4nken zu k\u00f6nnen. Vor allem wenn nur einzelne Typen (z.B. HTML) betroffen sind, kommt dies der Performance zugute: Der Apache-Webserver muss die Regex-Ersetzungen dann nicht f\u00fcr jede Anfrage durchf\u00fchren.<\/p>\n<pre class=\"wp-block-prismatic-blocks\"><code class=\"language-apache\" data-line=\"\">LoadModule filter_module \/usr\/lib64\/apache2-prefork\/mod_filter.so\nLoadModule substitute_module \/usr\/lib64\/apache2-prefork\/mod_substitute.so<\/code><\/pre>\n<p>Je nach Distribution und Installationsart finden sich die Module in einem anderen Verzeichnis. Falls man dies nicht kennt, einfach nach <strong>LoadModule<\/strong> in der <strong>httpd.conf<\/strong> suchen. M\u00f6glicherweise sind die obigen Zeilen dort auch bereits vorhanden und m\u00fcssen nur auskommentiert werden.<\/p>\n<p>Sind beide Module geladen, kann man mit der <strong>Substitute<\/strong> Direktive \u00fcberall Ersetzungen durchf\u00fchren.<\/p>\n<pre class=\"wp-block-prismatic-blocks\"><code class=\"language-apache\" data-line=\"\">AddOutputFilterByType SUBSTITUTE text\/html\nSubstitute &quot;s|server1|server2|i&quot;<\/code><\/pre>\n<p><strong>AddOutputFilterByType <\/strong>aktiviert Ersetzungen f\u00fcr die angegebenen Mime-Typen. In diesem Falle wird nur ersetzt, wenn dieser <strong>text\/html <\/strong>lautet. Es k\u00f6nnen auch mehrere mit Leerzeichen getrennt angegeben werden.<\/p>\n<p><strong>Substitute <\/strong>erwartet ein Pattern mit optionalen Flags, wie man es von Unix\/Linux-Tools wie grep oder sed bereits kennt. Obiges Beispiel ersetzt alle Vorkommen von <strong>server1 <\/strong>mit <strong>server2 <\/strong>und ignoriert dabei die Gro\u00df\/Kleinschreibung. <strong>Server1<\/strong> wird dadurch eben so ersetzt wie <strong>SeRvEr1<\/strong>. Der Grunds\u00e4tzliche Aufbau des Patterns ist<\/p>\n<pre class=\"wp-block-prismatic-blocks\"><code class=\"language-apache\" data-line=\"\">&quot;s|SUCHBEGRIFF|ERSETZUNG|FLAGS&quot;<\/code><\/pre>\n<p>Die Pipe | ist in diesem Falle der Delimiter. Er trennt diese drei Segmente voneinander und ist frei w\u00e4hlbar. Oft wird in der Linux-Welt ein Schr\u00e4gstrich genutzt. Da URLs oft selbst einen enthalten, empfehle ich hier ein anderes Trennzeichen zu nutzen. Neben der Pipe eignet sich auch die Raute. <\/p>\n<p>Die wichtigsten Flags:<\/p>\n<ul class=\"wp-block-list\">\n<li>i (Ignose cases): Ignoriert die Gro\u00df\/Kleinschreibung<\/li>\n<li>n (No Regexp): Ersetzt nur String-Zeichenketten. Fehlt dieses Flag, wird der Suchbegriff als regul\u00e4rer Ausdruck betrachtet. Somit w\u00e4re z.B. das Pattern example.(de|com) g\u00fcltig, um sowohl example.de als auch .com zu ersetzen<\/li>\n<\/ul>\n<p>Mehrere Flags lassen sich ohne Trennzeichen kombinieren, beispielsweise <strong>in<\/strong> um Strings unabh\u00e4ngig von ihrer Schreibweise zu ersetzen.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Das Apache-Modul mod_substitute erlaubt die Ersetzung von Zeichenketten in HTT-Anfragen. Und zwar nicht nur im Header, sondern auch dem Body. Dank regul\u00e4rer Ausdr\u00fccke ist es sehr m\u00e4chtig. Warum Zeichenketten im HTTP-Body ersetzen? Im besten Falle ben\u00f6tigt man dieses Modul nicht, weil die Webanwendung selbst einwandfrei funktioniert. Oder man diese wie gew\u00fcnscht anpassen kann. Allerdings gibt &#8230;<\/p>\n","protected":false},"author":5,"featured_media":6878,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[391,78],"tags":[799,819],"class_list":["post-6680","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-linux-server","category-software","tag-apache2","tag-apache2-modul"],"_links":{"self":[{"href":"https:\/\/u-labs.de\/portal\/wp-json\/wp\/v2\/posts\/6680","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/u-labs.de\/portal\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/u-labs.de\/portal\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/u-labs.de\/portal\/wp-json\/wp\/v2\/users\/5"}],"replies":[{"embeddable":true,"href":"https:\/\/u-labs.de\/portal\/wp-json\/wp\/v2\/comments?post=6680"}],"version-history":[{"count":5,"href":"https:\/\/u-labs.de\/portal\/wp-json\/wp\/v2\/posts\/6680\/revisions"}],"predecessor-version":[{"id":6685,"href":"https:\/\/u-labs.de\/portal\/wp-json\/wp\/v2\/posts\/6680\/revisions\/6685"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/u-labs.de\/portal\/wp-json\/wp\/v2\/media\/6878"}],"wp:attachment":[{"href":"https:\/\/u-labs.de\/portal\/wp-json\/wp\/v2\/media?parent=6680"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/u-labs.de\/portal\/wp-json\/wp\/v2\/categories?post=6680"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/u-labs.de\/portal\/wp-json\/wp\/v2\/tags?post=6680"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}