HTTP- und HTTPS-Inhalte mit WordPress, Varnish und einem SSL-Terminator trennen?

Hintergrund: Ich hoste eine WordPress-Site mit einem Hosting-Unternehmen, das ein kombiniertes Varnish-Server + SSL-Terminator-System vor meinem Webserver installiert. Die WordPress-Site läuft auf Apache und ist sowohl über HTTP als auch über HTTPS über den Varnish + SSL-Terminator erreichbar.

Das Setup sieht so aus: Imgur

Bildnachweis: DigitalOcean (Als Referenz ist DigitalOcean nicht mein Host, aber das Bild beschreibt genau das Setup auf meinem Host.)

Ich habe keinen administrativen Zugriff auf das Varnish + SSL-System.

Der gesamte lokale Verkehr zwischen dem SSL-Terminator, Varnish und meinem Webserver ist unverschlüsselt.

Ziel: Ich möchte die WordPress Admin-Schnittstelle nur über eine sichere (HTTPS) Verbindung zugänglich machen. Benutzer sollten in der Lage sein, auf die WordPress-Site über HTTP oder HTTPS nach ihrer Wahl zuzugreifen, wobei der Standard HTTP ist.

Relevante Konfiguration: Da der Webserver selbst nicht weiß, ob die ursprüngliche Verbindung sicher war, geht WordPress in eine Redirect-Schleife, wenn ich erzwinge, dass die Admin-Schnittstelle nur über HTTPS erreichbar ist mit define('FORCE_SSL_ADMIN', true); in meiner wp-config.php Datei.

Das Varnish + SSL-Terminatorsystem enthält jedoch Header, die angeben, welches Protokoll verwendet wurde. Daher verwende ich die folgende funktionierende Konfiguration:

 define('FORCE_SSL_ADMIN', true); if ($_SERVER['HTTP_X_FORWARDED_PROTO'] == 'https') $_SERVER['HTTPS']='on'; 

Auf diese Weise erkennt WordPress automatisch, ob ein Besucher über HTTP oder HTTPS auf die Site zugreift, und ändert Links zu CSS / JavaScript-Dateien entsprechend, um Warnungen über “unsicheren Inhalt” zu vermeiden.

Problem: Obwohl WordPress Links basierend auf dem Protokoll modifiziert, um “unsichere Inhalte” Warnungen zu vermeiden, kümmert sich Varnish nicht um Protokolle und speichert Inhalte (unabhängig vom Protokoll) bis zum Ablauf.

Wenn Varnish beispielsweise mit einem leeren Cache beginnt und der erste Besucher HTTPS verwendet, ändert WordPress alle Links, die auf HTTPS verweisen, und gibt den angeforderten Inhalt zurück. Varnish speichert diesen Inhalt mit den HTTPS-Links. Wenn der zweite Besucher eine Verbindung über HTTP herstellt, gibt Varnish den zwischengespeicherten Inhalt mit HTTPS-Links zurück, und der Besucher lädt CSS / JavaScript über HTTPS. Wenn der Benutzer auf Links zu anderen Inhalten auf der Website klickt, greifen sie über HTTPS auf diesen Inhalt zu.

Wenn wir jedoch die Situation umkehren (dh der erste Besucher verwendet HTTP und der zweite Besucher HTTPS), tritt ein Problem für den zweiten Besucher auf: Der zwischengespeicherte Inhalt weist den Besucher an, das CSS / JavaScript über HTTP zu laden. Browser verweigern dies aus Sicherheitsgründen, der Browser zeigt eine Warnung “unsicherer Inhalt” an und keine der Formatierungen / Skripts funktioniert.

Versuchte Lösungen:

  1. Deaktivieren Sie SSL vollständig, auch für die Admin-Oberfläche. Dies ist die am wenigsten bevorzugte Option, aber zumindest hält es die Dinge konsequent (wenn auch unsicher).
  2. Leiten Sie den gesamten Nicht-Administrator-Datenverkehr mit der folgenden .htaccess-Regel an HTTP um:

     RewriteCond %{HTTP:X-Forwarded-Proto} =https RewriteRule !^wp-(admin|login|register)(.*) - [C] RewriteRule ^(.*)$ http://%{SERVER_NAME}/$1 [L] 

    Dies würde funktionieren, wenn nicht für Varnish: Wenn der Besucher über HTTPS auf eine Nicht-Admin / Login / Register-URL auf der Site zugreift, schreibt Apache den Besucher auf die HTTP-Version des Inhalts um. Varnish speichert die Weiterleitung zwischen, ohne sich darum zu kümmern, welches Protokoll verwendet wird, so dass Besucher und alle nachfolgenden Besucher in einer Neuschreibungsschleife stecken bleiben. Selbst wenn es funktionierte, ist diese Methode nicht ideal, da alle Nicht-Admin-Benutzer gezwungen sind, nur über HTTP auf die Site zuzugreifen. Ich möchte Benutzern erlauben, auf den Inhalt mit HTTP oder HTTPS nach ihrer Wahl zuzugreifen.

Frage: Gibt es eine Möglichkeit, dieses Problem zu lösen, ohne dass Benutzer Zugriff auf das Varnish + SSL-System haben, sodass Benutzer, die über HTTP und HTTPS auf die Website zugreifen, nicht gegenseitig auf die Caches zugreifen?

Solutions Collecting From Web of "HTTP- und HTTPS-Inhalte mit WordPress, Varnish und einem SSL-Terminator trennen?"

Ich weiß, dass dies eine ziemlich alte Frage ist, aber ich werde meine Ergebnisse für den Fall hinterlassen, dass jemand anderes diese Arbeit machen muss.

Ihr Ansatz hat mir geholfen, ein ähnliches Setup zu implementieren.

Damit Varnisse einen separaten Cache für HTTP- und HTTPS-Versionen derselben Seite behält, müssen Sie lediglich den X-Forwarded-Proto-Header in der function hash_data () in vcl_hash hinzufügen.

So was:

 sub vcl_hash { if (req.http.host) { hash_data(req.http.host); } else { hash_data(server.ip); } # Keep separate caches if https is used hash_data(req.http.X-Forwarded-Proto); } 

Auf diese Weise erhält ein Benutzer, der http://www.example.net besucht , den Cache für die http-Version, während ein Benutzer, der https://www.example.net besucht , den Cache für die https-Version erhält.

Vielleicht möchten Sie es genauer machen, so dass es nur Doppel-Caches für den HTML-Inhalt und nicht Bilder, CSS, JS usw., die normalerweise unabhängig vom verwendeten Protokoll sind, beibehalten.

Es sollte kein Problem geben, es sei denn, Sie haben eine Fehlkonfiguration oder ein schlecht funktionierendes Thema oder Plugin. WordPress Core sendet einen http-Header, der Caching-Server anweist, den gesendeten Inhalt nicht zwischenzuspeichern, wenn ein eingeloggter Benutzer auf die Seite zugreift.

Als Referenz werden die Header auf wp_get_nocache_headers und von send_headers gesendet, und von einem 2- send_headers Code-Review scheint mir der Code jetzt sehr solide zu sein.