Immer dann, wenn dritte Dienste ins Spiel kommen, also nicht der Besucher mit der Webseite kommuniziert, sondern das WordPress mit einem anderen Server, ist es etwas schwieriger die Kommunikation zu debuggen. Und mit der (zum Glück) immer weiter steigenden Verbreitung von SSL sind diese Verbindungen auch noch verschlüsselt. Egal ob WordPress mit dem Servern von wordpress.org redet um nach Updates zu fragen oder Veranstaltungsdaten von einem Anbieter geladen werden. Immer dann wenn die Funktionsaufrufe einen Fehler zurück liefern, stellt sich die Frage „was genau wurde denn Übertragen“, zumal die Fehlermeldung oftmals nicht sonderlich aussagekräftig sind.
Ich verwende dazu das Programm Charles, eine „Web Debugging Proxy Application“ für Windows, Mac und Linux.
Neben vielen anderen Features ist die für diesen Anwendungsfall wichtigste, die Möglichkeit das Charles sich als Man-in-the-Middle in die SSL Verbindung reinhängen kann. Da dies aber auch ein Angriffsszenario ist, muss das (hoffentlich) erst erlaubt werden im Verbindungsaufbau der Komponente (im Normalfall ein WordPress Plugin) die wir untersuchen wollen. Voraussetzung ist, das WordPress den Rechner auf dem Charles läuft erreichen kann. Der Normalfall bei mir ist, das die zu untersuchende WordPress-Instanz lokal auf meinem Rechner läuft.
Nach dem Start von Charles zeichnet er Verbindungen auf. Der SSL Support muss erst nach aktiviert werden. Darauf wird hingewiesen.
und daher ist der Inhalt der Anfrage nicht lesbar.
Um den SSL Support zu aktivieren ruft man im Menü Proxy / Proxy SSL Settings auf und trägt Host und Port ein. Freie Felder werden als Wildcard gewertet. Ein Klick einfach auf OK trägt die Regel */* ein und aktiviert damit den SSL Support für alle Verbindungen. Das kann dann dazu führen das andere Programme wie Mail, Kalender, Chattools usw ihren Dienst einstellen weil die erkennen das sich das Zertifikat geändert hat und es als Man-in-the-Middle Angriff werten.
Charles generiert ein eigenes SSL Zertifikat für die Verbindung zum Client ( mein lokales WordPress).
Ein Hinweis kann dann so aussehen (Hier Beispielhaft von Fantastical)
Verbindungen von WordPress (HTTP-API)
Die von WordPress selbst bzz allgemein die über die WordPress HTTP-API iniziierten Verbindungen fragen einige Konstanten aus der wp-config.php ab.
define('WP_PROXY_HOST', 'localhost'); define('WP_PROXY_PORT', '8888');
Damit kann WordPress gesagt werden das alle Verbindungen über den Proxy gehen. Allerdings gibt es keine Konstante zum abschalten der Zertifikatsprüfung.
Der Versuch in der WordPress Instanz zu prüfen ob es Aktualisierungen gibt, endet in einer Fehlermeldung
und in Charles sehen wir den genauen Grund, das Zertifikat stimmt nicht.
Um das s.g. sslverify zu deaktivieren nutzen wir den Filter http_request_args und schalten mit folgenden Zeilen (z.b. in der functions.php des Themes) die Überprüfung des Zertifikates ab.
add_filter( 'http_request_args', function( $arg ) { $arg[ 'sslverify'] = false; return $arg; });
und nun können wir den Inhalt der Antwort von api.wordpress.org in Charles lesen.
PHP cURL Verbindungen
Auch wenn in einem Plugin nach Möglichkeit die HTTP-API verwendet werden sollte, es mag Fälle geben wo man direkt mit den cURL Funktionen arbeitet.
Dazu sucht man die Stelle, an der mittels curl_setopt die Optionen der Verbindung gesetzt werden und ergänzt die Proxyadresse, Port und deaktiviert das prüfen des Zertifikates.
curl_setopt( $ch, CURLOPT_PROXY, "127.0.0.1"); curl_setopt( $ch, CURLOPT_PROXYPORT, 8888); curl_setopt( $ch, CURLOPT_SSL_VERIFYPEER, 0);
PHP SOAP Verbindungen
Bei den SOAP Funktionen ist es wieder ein wenig anders. Da habe ich keine Möglichkeit gesehen die Zertifikatsprüfung abzuschalten. Darum wird in Charles unter dem Menüpunkt Help / SSL Proxying / Save Charles Root Certificate das Zertifikat heruntergeladen und gespeichert. Beispielsweise in der Datei “/Users/frank/charles-ssl-proxying-certificate.crt”
Nun kann bei den Soap-Options der Proxy und das Zertifikat übergeben werden.
$soap_options = array( 'cache_wsdl' => WSDL_CACHE_NONE, 'soap_version' => SOAP_1_1, 'trace' => 1, 'proxy_host' => 'localhost', 'proxy_port' => 8888, 'stream_context' => stream_context_create([ 'ssl' => [ 'cafile' => '/Users/frank/charles-ssl-proxying-certificate.crt' ] ]), );
Beispielhaft ein Screenshot bei einen SOAP Abruf aus WordPress heraus gegen einen echten Dienstanbieter (Daten soweit unkenntlich gemacht)