Kategorien
Technisches

WordPress mit Object Cache (memcached/Redis) für Entwickler

Zielgruppe

Entwickler von WordPress Themes und/oder Plugins, die $wpdb benutzen und sich jetzt wundern, warum die Website spinnt.

Intro – Caching

Caching beschleunigt Webapplikationen – so auch WordPress. Es gibt einen Schwung Caches, welche alle ihre Eigenarten haben. Für den Entwickler eines WordPress Plugins oder eines WordPress Themes ist dabei besonders der Object Cache (memcached oder Redis) zu beachten.

  • Viele andere Caches funktionieren im Hintergrund, ohne dass der Programmierer sich Gedanken um die Invalidierung machen muss
  • Komplette Seiten-Caches müssen wohlüberdacht sein und liegen eher im Verantwortungsbereich des Seitenbetreibers

Hier soll es also um die Object Caches (z.B. memcached) gehen und was man bei der Programmierung von Applikationen unter WordPress dafür beachten muss.

Funktionsweise von Object Caches

Object Caches sind einfache Key/Value-Speicher. Wenn man zum Beispiel mit einer aufwändigen Berechnung und vielen Datenbankabfragen ein Ergebnis bekommen hat, dann kann man dieses zwischenspeichern, um es bei späteren Aufrufen der Seite wider verwenden zu können, ohne die Berechnung und die Datenbankabfragen noch einmal machen zu müssen.

Der errechnete Wert (z.B. „42“) wird dann unter einem Key (z.B. „Antwort“) im Cache gespeichert. Bei der Speicherung wird neben dem Key und dem Wert auch noch eine Lebenszeit angegeben, nachdem der Wert automatisch invalidiert wird. Gibt man keine Lebenszeit an, dann muss man sich darum kümmern, dass der Wert bei einer Änderung der zugrundeliegenden Daten automatisch invalidiert wird.

Object Caches in WordPress

Unter WordPress kann man die Funktionen benutzen:

Wichtig ist aber zu wissen, dass WordPress diese Funktionen auch selbst benutzt. Wenn kein Plugin installiert ist, welches einen Object-Cache bereitstellt, dann cacht WordPress die Werte nur für die Dauer des Aufrufs. Wird allerdings ein Caching-Plugin installiert, dann werden die Werte auch über Aufrufe hinweg gespeichert – und das kann dann bei unachtsamer Programmierung zu Problemen führen.

Wann Invalidieren von Daten notwendig ist

WordPress bietet verschiedene Abstraktionsebenen.

  • Auf der obersten Ebene haben wir ein paar Funktionen wie the_title() und so, mit denen wir einfach in Templates auf Daten zugreifen können. Diese Funktionen nutzen den Cache ohne unser zutun.
  • Eine Ebene darunter befinden sich die Funktionen, mit denen man auf die Daten zugreifen kann, die WordPress in der Datenbank gespeichert hat. Hier kann man auch Daten ändern. wp_update_user(), get_post_meta() und so. Auch diese Funktionen nutzen den Cache, und wenn man mit ihnen (mit den Update-Funktionen) Daten ändert, dann invalidieren sie auch automatisch den Cache.
  • Als unterste Ebene stellt WordPress aber die $wpdb-Klasse zur Verfügung, mit denen man mehr oder weniger direkt mit der Datenbank interagieren kann. Hier umgeht man den Cache. Für Daten, die man so aus der Datenbank holt wird nicht zuerst der Cache befragt, sondern direkt die Datenbank. Gleiches gilt auch für Updates: Der Cache wir nicht invalidiert.

Das bedeutet, dass man bei der Nutzung der wpdb-Klasse vorsichtig sein muss. Ein Beispiel verdeutlicht das:

Beispiel

Zuerst schauen wir uns an, wie das funktioniert, wenn man die Funktionen eines höhren Abstraktionslevels benutzt:

  • Ein Benutzer schaut sich einen Post an. Dieser wird durch get_post() o.ä. aus der Datenbank geholt. Da das potentiell aufwändig ist wird das Ergebnis der Datenbankabfrage im Cache abgelegt.
  • Ein weiterer Benutzer schaut sich den gleichen Post an. WordPress holt die Daten nicht mehr aus der Datenbank, sondern aus dem Cache.
  • Mittels wp_update_post() wird der Post geändert. WordPress kümmert sich automatisch darum, dass der Cache invalidiert wird.
  • Ein dritter Benutzer schaut sich den Post an. Er wird wieder aus der Datenbank geholt, denn es gibt ja keinen gültigen Cache-Eintrag mehr für diesen Post. Das Ergebnis wird wieder im Cache abgelegt für den vierten Benutzer

Jetzt das Gleiche, nur dass wir zum Update des Posts nicht wp_update_post() benutzen, sondern direkt mit $wpdb arbeiten:

  • (identisch) Ein Benutzer schaut sich einen Post an. Dieser wird durch get_post() o.ä. aus der Datenbank geholt. Da das potentiell aufwändig ist wird das Ergebnis der Datenbankabfrage im Cache abgelegt.
  • (identisch) Ein weiterer Benutzer schaut sich den gleichen Post an. WordPress holt die Daten nicht mehr aus der Datenbank, sondern aus dem Cache.
  • Mittels wpdb wird der Post geändert. Da wir die Caching-Schicht umgehen bekommt der Cache nichts von der Änderung mit und der Cache wird nicht invalidiert.
  • Ein dritter Benutzer schaut sich den Post an. Da es noch einen gültigen Cache-Eintrag gibt bekommt der Benutzer die alte Version des Posts zu sehen. Das ist falsch uns sollte vermieden werden.

Man hat als Programmierer jetzt also drei Möglichkeiten:

  • Entweder benutzt man nur die Funktionen des höheren Abstraktionslevels (wp_update_post() o.ä.)
  • Oder man speichert seine Daten in eigenen Tabellen, so dass man sicher sein kann, dass WordPress nicht „von Haus aus“ darauf zugreift.
  • Oder man invalidiert den Cache nach Updates manuell

So invalidiert man Daten

Das kann man sich im Quelltext von WordPress schön anschauen, wie das die WordPress-eigenen Funktionen machen. In der Funktionsreferenz kann man nach „clean cache“ suchen, da findet sich sicherlich was passendes:

https://developer.wordpress.org/?s=clean+cache

Disclaimer

Dieser Text ist nur schnell für den Eigengebrauch runtergeschrieben und wurde nicht noch mal „Kontroll-gelesen“. Falls das jemand vor mir schafft werden Verbesserungen und Korrekturen gerne per Mail entgegen genommen.

Kategorien
Technisches

WordPress Media Upload broken

An Update to WordPress core broke media upload on all my sites. The update was on 2019-10-14, but problems arised now, when november begun.

Setup

We use a special directory structure which is like this:

  • wp/
  • uploads/
  • wp-content/
  • index.html
  • wp-config.php

With this layout it’s possible for us to have the different parts in different places: wp is a clean, unmodified WordPress checkout, uploads contains all the media files and wp-content contains the code for the website.

With setting constants WP_SITEURL, WP_CONTENT_DIR, WP_CONTENT_URL, WP_PLUGIN_DIR and WP_PLUGIN_URL along with UPLOADs this worked fine. However:

define(‚UPLOADS‘,‘../uploads‘);

was needed, because _wp_upload_dir() calculates the uploads-directory by appending UPLOADS to ABSURL – and ABSURL is in my wp-folder.

Problem

Recent Changes in WordPress Core forbid creating directories with „../“ in their path. Uploading files works, but creation of the „2019/11/“-folder fails.

https://core.trac.wordpress.org/ticket/48316

https://foliovision.com/2019/11/wordpress-unable-to-create-directory

https://wordpress.stackexchange.com/questions/352042/install-wordpress-with-custom-directory-layout-without-breakting-media-upload

Kategorien
Technisches

Uncaught ImagickException: not authorized @ error/constitute.c/ReadImage/412

Bei Imagick gab es eine Sicherheitslücke, welche durch eine Änderung der Standardkonfiguration gefixt wurde. Die Konfigurationsdatei ist (bei mir, Ubuntu 16.04 LTS) /etc/ImageMagick-6/policy.xml. Hier wurde dem ImageMagick verboten PDF-Dateien (und mehr) zu lesen. Wenn man (wie ich) aber PDF-Dateien zu JPEGs umwandeln will, dann führt das zu o.g. Fehler.

Die Relevante Zeile in der Datei war:

<!-- disable ghostscript format types -->
<policy domain="coder" rights="none" pattern="PS" />
<policy domain="coder" rights="none" pattern="EPS" />
<policy domain="coder" rights="read|write" pattern="PDF" />
<policy domain="coder" rights="none" pattern="XPS" />

Wie man sieht habe ich einfach auf PDF die Rechte „read|write“ statt „none“ gegeben.

Zusammenspiel mit PHP

In meinem konkreten Fall äußerte sich der Bugfix (Funktionalität ging kaputt) erst viel später, als das PHP (als FPM) neu gestartet wurde. Ebenso wirkte sich meine Konfigurationsänderung erst aus als ich das PHP neu gestartet hatte.

Kategorien
Technisches

Firefox HTTP/2 & IPv6: Webserver Subdomain Configuration Pitfall

Conditions

  • two (or more) subdomains (same domain)
  • …share a common wildcard ssl certificate
  • on the same host (same IPv4-address)
  • but with different IPv6-addresses
  • client: Firefox (only Firefox has this behavior)
  • use HTTP/2
  • use IPv6

Expected behavior:

  • foo.example.com in location bar shows foo.example.com
  • bar.example.com in location bar shows bar.example.com

Seen behavior

Requests for the second host (bar) go to the first host (foo).

Explanation

With HTTP/2 Firefox shares connections to webservers („pooling“) to speed up page loading by omitting handshake and tcp slow start. Firefox determines which connections can be pooled together not by looking at the hostname, but by looking at the IPv4-address and the certificate. If the IPv4 address of the second host (bar) matches the IPv4-address of the first host (foo) AND the certificate used for foo also matches bar then the connection to foo is reused for bar.

Problem

The webserver may not be configured to show the contents of bar when someone connects to the IPv6-Adress of foo. Webserver administrators who were happy about the fact that with IPv6 there’s no need for SNI and name based virtual hosting anymore (like me) may have configured their webservers in the false assumption that if an IPv6 address is published for hostname foo incoming connections to that host will go to that IP address.

The behavior of Firefox is highly unexpected – or simply wrong.

Workaround

There are many obvious workarounds, but all of them have disadvantages.

  1. use different certificates (cheap nowadays) or
  2. use the same IPv6 address (use name based virtual hosting and SNI even when using IPv6) or
  3. use http status code 421 to answer „misguided“ requests

Links

Bugzilla: Firefox should decide whether reuse connection separately for IPv4 and IPv6

Daniel Steinberg: HTTP/2 connection coalescing

RFC 7540 Hypertext Transfer Protocol Version 2 (HTTP/2): 9.1.1. Connection Reuse

Kategorien
Technisches

Charset, Encoding & Collation (MySQL „utf8mb4“)

Charset

Das Charset (der Zeichensatz) ist EIGENTLICH eine definierte Menge an Buchstaben. Da nutzen wir „Unicode“ – das ist das, was man heutzutage so hat. Wenn man aber „Charset“ oder „Zeichensatz“ sagt, dann meint man i.d.R. das Encoding.

Encoding

Das Encoding ist die Kodierung von Zeichen in Bytes. Fast alle üblichen Kodierungen sind Supersets von US-ASCII, gleichen sich also in den wichtigesten, üblichen Zeichen.

UTF-16 ist da eine Ausnahme, weil das für JEDEN Buchstaben zwei Bytes benutzt, deshalb mit NIX kompatibel ist außer mit sich selbst und das deshalb auch NIEMAND benutzt (Außer Microsoft natürlich – und Java, weil wenn’s eine bekloppte Idee gibt, dann macht Java da natürlich mit).

Das wichtigste Encoding (mit dem bei uns alles gemacht sein sollte) ist UTF-8. Ich kann das nicht so gut erklären wie Computerphile:

Youtube: Computerphile on UTF-8 (Must-see, 10 min.)

Als UTF-8 in das MySQL eingebaut wurde haben sie aber nur ein Subset genommen, und zwar gibt es die Beschränkung, dass es nur maximal 2 Bytes haben kann. Das kann zu Problemen bei irgendwelchen asiatischen und klingonischen Sprachen führen. Deshalb gibt es jetzt utf8mb4, welches maximal 4 Bytes hat.

Collation

Man hat jetzt zwar die Möglichkeit die Zeichen alle zu Codieren, jedoch hat man dadurch noch keine Interpretation der Zeichen als Teil des Alphabets. Für deutsche ist ein „ß“ so etwas wie „ss“ und ein „ö“ so ähnlich wie „oe“, ein „ë“ aber nicht wie ein „ee“.

Deshalb brauchen wir die Collation: Im türkischen sind i und I zwei unterschiedliche Buchstaben, im schwedischen kommt ä hinter z, im Lateinischen sind „U“ und „V“ äquivalent und so weiter. Damit das richtig sortiert wird gibt es die Kollationen.

Eine Kollation ist demzufolge die Konkretisierung eines Encodings bezüglich der Sortierung. Deshalb beginnt der Name der Collation auch immer mit der Name des Encodings.

„utf8mb4“ hat als Default-Collation z.B. „utf8mb4_general_ci“ – das könnte man auf „utf8mb4_german1_ci“ umstellen (für Duden-Reihenfolge) oder auf „utf8mb4_german2_ci“ für Telefonbuch-Reihenfolge. Die Unterschiede sind aber weniger wichtig. Relevant ist vor allen Dingen die Unterscheidung zwischen utf8 und utf8mb4 als Chars^W Colla^W Encoding.

Kategorien
Allgemein Technisches

Papiermenschens Cyber

Wenn mir ein Papiermensch…

Ein Papiermensch ist ein Mensch, der Dinge, die am Bildschirm zu lesen sind, nicht so wichtig findet wie die Dinge, die auf Papier ausgedruckt sind. Menschen, die Informationen ausdrucken um sie zu lesen. Menschen, die einer 2048-RSA-Schüssel (von einer CA signiert) als unsicher erachten, aber ein bisschen Gekritzel mit Kuli auf einem Papier sicher finden.

Wenn mir also ein Papiermensch sagt, ich solle etwas über „Cyber“ schreiben, was schreib ich dann? Papiermenschen finden den Duden gut. Im Duden steht, dass die Vorsilbe „Cyber“ Dinge kennzeichnet, die eine von Computern generierte Scheinwelt betreffen. Das hört sich nach „VR“ an, aber es soll eigentlich über Mailserver und Netzwerksicherheit gehen. Wie unterscheidet sich die Sicherheit eines Computernetzwerkes von der Cybersicherheit eines Computernetzwerkes?

Wisst ihr, was ich glaube? Ich glaube „die Sicherheit von Computern“ ist für diese Menschen zum Beispiel, dass einem kein Computer auf den Fuß fällt, denn da könnte sich jemand verletzen. Auch darf ein Computergehäuse keine scharfen Kanten haben. Das ist „die Sicherheit von Computern“.

Die „Cybersicherheit“ hingegen ist dann das, was ich unter Sicherheit verstehe.

Sicherheit von Computernetzwerken

Niemand stolpert über Netzwerkkabel und die Computer sind so im Regal festgeschraubt, dass sie nicht rausfallen können.

Cybersicherheit von Computernetzwerken

Die Computer tun das was sie sollen statt irgendwelche Angriffe auf Infrastruktur zu fahren.

Cyber

Cyber: Das Wort haben in den 90ern die Menschen benutzt, die noch kein Internet hatten, wenn sie den Menschen, die schon Internet hatten, das Internet erklärt haben. Das war damals schon lächerlich.

Kategorien
Technisches

Du willst keinen FTP-Zugang zu Deiner Website

FTP ist ein schlechtes und unsicheres Prototoll aus vor-WWW-Zeiten. Wer es verwendet oder anbietet legt damit Zeugnis ab über seine Inkompetenz und Ignoranz.

FTP ist unsicher

FTP unterstützt keine Verschlüsselung. Die Daten werden unverschlüsselt über das Internet übertragen. Jeder kann sie mitlesen. Aber nicht nur die übertragenen Nutzdaten, sondern auch der Benutzername und das Kennwort werden unverschlüsselt übertragen.

Wenn man einen FTP-Zugang verwendet, dann kann man die Zugangsdaten genausogut veröffentlichen. Alles was man mit FTP macht können andere dann auch.

Trotzdem meinen manche (selbst Profis) es sei eine gute Idee zur Verwaltung eines Online-Shops FTP zu benutzen. Das ist lustig und gleichzeitig traurig, denn die Verbindung vom Server zu den Benutzern ist ja ordentlich verschlüsselt und die Kunden verlassen sich darauf.

FTP ist alt

Nur weil etwas alt ist bedeutet das nicht, dass es deshalb schlecht sein muss. Viele alte Autos sind z.B. toll; oder alte Gemälde. FTP ist aber nicht alt. Es ist saualt. Als FTP im Oktober 1985 spezifiziert wurde gab es noch gar kein World Wide Web. Und das ist auch nur die Basis der aktuellen Version. Eigentlich ist das Protokoll von 1972, als es noch gar kein Internet gab.

FTP wurde für das Arpanet, den Vorläufer des Internet, entwickelt. In der Google Bildersuche kann man sehen wie Computer 1972 aussahen. Für diese Computer, und Leute, die an Schwarz-Weiß-Terminals sitzen und über ein längst vergessenes Netzwerkprotokoll Daten übertragen wollen – dafür wurde FTP entwickelt.

FTP ist ungeeignet

Wenn vor so langer Zeit ein Protokoll entwickelt wurde, dann ist es natürlich für heutige Einsatzzwecke so gut geeignet wie eine Sänfte für den Einsatz auf einer bundesdeutschen Autobahn. Insbesondere zum Verwalten von Website ist es total ungeeigent, weil es den Status auf dem Server nicht verfolgt:

Wenn man nicht einfach immer alle Dateien übertragen will, dann muss man jede Datei vergleichen. Außerdem kann es passieren, dass man Änderungen überschreibt, die jemand anderes auf dem Server vorgenommen hat. Man muss also immer die komplette Website vom Server auf den Client kopieren bevor man Änderungen vornimmt.

Hat man Änderungen auf dem Server vorgenommen, dann kann man diese nicht mehr einfach rückgängig machen. Um das tun zu können muss man jedesmal vorher manuell ein Backup erstellt haben.

Und nein: Ich bin nicht der Einzige, der das meint

Wer FTP nutzt, der tut das weil er es nicht besser weiß. Jeder, der sich Gedanken macht wird FTP nicht nutzen. Dementsprechend gubt es keine Argumentation für FTP, nur dagegen: Schon 2011 war klar, dass man FTP nicht mehr nutzen will und es gibt schöne Listen mit Argumenten.

Fazit: Do not use

Es gibt nur noch ganz wenige Einsatzzwecke für die FTP ein geeignetes Protokoll ist: nur dann wenn es sich quasi um öffentliche Daten handelt. Für das Verwalten von Websites ist es definitiv das falsche Protokoll.

Kategorien
Technisches

SSL vs. TLS vs. STARTTLS

Insbesondere beim Bearbeiten der Verbindungseinstellungen von E-Mail-Programmen kommt immer wieder die Frage auf ob denn SSL oder TLS besser wäre; deshalb hier ein GANZ kurzer Überblick:

tl;dr

I.d.R. ist die Auswahl „SSL“ besser.

Die Verschlüsselung

TLS ist die neue Version von SSL, der Nachfolger von SSL. Deshalb ist TLS sicherer, SSL sollte man nicht mehr verwenden. Welche Version benutzt wird, machen die Programme aber unter sich aus. Das ist für den Benutzer nicht einzustellen. Kein normaler Benutzer sollte mit dieser Entscheidung in Kontakt kommen.

Wenn gefragt wird „willst Du SSL oder TLS“, dann ist nur die Frage falsch formuliert. Korrekt müsste die Frage lauten: „Willst Du einen Verbindungsaufbau nach Art von SSL oder STARTTLS?“

Der Verbindungsaufbau

Früher (zu Zeiten von (dem alten) SSL) brauchte man für verschlüsselte Übertragung und für unverschlüsselte Übertragung zwei verschiedene Ports. Wenn man also heute „SSL“ auswählt, dann verbindet sich das Mailprogramm auf einen Port, der nur für verschlüsselte Verbindungen da ist.

Heute (zu Zeiten von TLS) gibt es eine weitere Möglichkeit: STARTTLS. Damit verbindet sich das Mailprogramm auf den unverschlüsselten Port und schaltet dann auf Verschlüsselung um. Über dieses Umschalten müssen sich Client und Server einig werden und wenn man nicht genau aufpasst (und das Mailprogramm so konfiguriert, dass es die Verschlüsselung zwingend voraussetzt), dann kann es passieren, dass dann ohne Verschlüsselung übertragen wird.

(START)TLS ist also eher als eine Krücke zu sehen, die benutzt wird, wenn kein eigener Port für die verschlüsselten Verbindungen zur Verfügung steht.

Fazit

Zwar ist TLS „besser“ als SSL, aber wenn Du (als normaler Anwender) gefragt wirst: nimm SSL statt (START)TLS. Wenn Du die Auswahl hast. I.d.R. hast Du die Auswahl bei POP und IMAP, bei SMTP ist ein eigener Port eher unüblich, da muss man i.d.R. (START)TLS nehmen.

Weiterlesen

Auf englisch hier:

…oder bei der Wikipedia:

Rant

Es ist eigentlich gar nicht so schwer – wenn nur die Software-Herstellen mal dazu übergehen würden, die Dinge richtig zu bezeichnen. Regelfall ist aber, dass nicht die fachlich korrekten Bezeichnungen verwendet werden, sondern jedes Programm an die Optionen irgendwas hinschreibt, so dass man selbst als sehr erfahrener Anwender raten muss. Wenn es also nicht wie erwartet geht: das liegt nicht an euch, sondern an der Ahnungslosigkeit und Ignoranz der Softwarehersteller und insbesondere der Software-Oberflächen-Übersetzer. Vielleicht hilft es schon, das Programm auf englisch zu installieren.

Kategorien
Technisches

E-Mail Autoconfig & AutoDiscover

Wenn man E-Mail-Dienste bereitstellt, dann sollte man es den Nutzern einfach machen die E-Mail-Programme korrekt zu konfigurieren.

Kategorien
Technisches

502 Bad Gateway erklärt/Bedeutung

„502 Bad Gateway“ ist ein http-Fehler. „502“ ist die Fehlernummer und „Bad Gateway“ die Erklärung.

Bedeutung

Der Browser (Firefox, Chrome, IE, Safari o.ä) hat bei einem Webserver (www.example.com o.ä.) nach einer Website gefragt. Der Webserver kann die Anfrage aber nicht alleine beantworten. Er muss dazu eine weitere Software befragen (z.B. Online-Shop, Forum, anderer Webserver, etc.)

Bei dieser Anfrage kam es zu einem Fehler, welche die Schnittstelle („Gateway“) zu dieser Software dem Webserver zurückgemeldet hat. Der Webserver kann die Anfrage von Deinem Browser also nicht beantworten und versucht sich mit der bösen Schnittstelle rauszureden.

Wie kann ich das beheben/umgehen?

Beheben kann das nur der Webmaster der Website. Umgehen kann man das höchstens mittels eines Caches wie Googles Cache, Wayback-Machine o.ä.