Verwandeln einer Apache-http-Site in eine sichere https-Site über einen Nginx-Reverse-Proxy
Ich muss eine alte WordPress-Site unterstützen, die auf einem Apache-Webserver ausgeführt wird. Um die Sicherheit zu erhöhen, befindet sich dieser Apache-Server in einem Docker-Container und ist über die Nginx-Reverse-Proxy-Konfiguration für die Welt zugänglich. Diese Site wird derzeit über http bereitgestellt und ich möchte sie auf https verschieben.
Ich glaube, ich habe zwei Möglichkeiten:
Das SSL-Zertifikat wird für die Nginx-Site installiert und
proxy_passfür die einfache http-Site im Apache-Container:server { listen 443 ssl; server_name www.example.com; ssl_certificate /etc/nginx/ssl/letsencrypt/live/www.example.com/fullchain.pem; ssl_certificate_key /etc/nginx/ssl/letsencrypt/live/www.example.com/privkey.pem; access_log /var/log/nginx/example.com.access.log; location / { proxy_pass http://Apache2-PHP5.6:80; proxy_set_header Host $host; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; } }In diesem Szenario wird die Site aus Sicht des Apache-Servers weiterhin über http bereitgestellt
Dies ist aufwändiger: Das SSL-Zertifikat wird sowohl auf dem Gateway-Nginx-Server als auch auf der Proxy-Site mit Proxy installiert. Dann wäre es erforderlich sein , zu ändern ,
httpumhttpsin demproxy_passWert Config.
Ich wünschte, mit dem ersten Szenario wäre alles in Ordnung. Die Tatsache, dass Apache das Gefühl hat, Inhalte über http bereitzustellen, führt jedoch zu einigen Problemen: Es gibt einige versteckte URL-Weiterleitungen, die ich wirklich nicht neu konfigurieren / debuggen möchte. Und diese URL-Weiterleitungen machen ungefähr so: Wenn die angeforderte URL lautet http://www.example.com, wird sie als (http-Status 301) umgeschrieben http://www.example.com/main. Diese Weiterleitung wird vom Browser empfangen. Obwohl die erste Anforderung über https erfolgte, lautet die umgeleitete URL jetzt http one. Außerdem enthält die HTML-Site mehrere Vollpfad-Hrefs zu ihren eigenen Ressourcen (JavaScript- und CSS-Dateien), die auch die Protokollreferenz enthalten. Zu diesem Zeitpunkt ist nicht klar, ob diese hrefs das Protokoll übernehmen, aus dem die Anforderung stammt, oder ob es fest codiert ist. Wie auch immer, leider funktioniert dies nicht ohne ernsthaftes Eingraben.
Ich habe also noch die Option 2. Ich habe versucht, es funktioniert, ich kann das gleiche SSL-Zertifikat sowohl für Nginx als auch für den containerisierten Apache einrichten. Aber ich würde gerne wissen, ob es wirklich so ist, wie es laufen sollte. Denn obwohl der Apache-Server jetzt weiß, dass der Inhalt über https bereitgestellt wird, findet jetzt für jede Anforderung ein doppeltes SSL-Verfahren statt. Es fühlt sich nicht richtig an.
Antworten
Sie sollten Apache mitteilen können, dass die eingehende Anforderung von einer HTTPS-Anforderung mit der proxy_set_header X-Forwarded-Proto "https";Deklaration im ersten Setup weitergeleitet wird
Sie können das Problem in Ihrer Option 1 lösen (was, wie Sie sagten, ein viel besserer Ansatz ist), indem Sie HTTP_X_FORWARDED_PROTO in Ihrer Nginx-Konfiguration mit festlegen
proxy_set_header X-Forwarded-Proto $scheme;
und Konfigurieren von WordPress, um es zu erkennen, indem diese Zeile an wp-config.php angehängt wird
if (isset($_SERVER['HTTP_X_FORWARDED_PROTO']) && $_SERVER['HTTP_X_FORWARDED_PROTO'] === 'https') { $_SERVER['HTTPS'] = 'on';
}
Eine Variation dieser Lösung finden Sie auch im Wordpress-Support-Artikel .
Normalerweise würde ich es vorziehen, das ganze schwere Heben auf dem Reverse-Proxy durchzuführen und die Backend-Site, die freigelegt wird, so original wie möglich zu halten.
Ihr Problem scheint im Wesentlichen darin zu liegen, dass das (WordPress-) Backend (absolute) URIs generiert und verwendet, die sich von den von Besuchern gewünschten unterscheiden.
Sie können Abhilfe schaffen, indem Sie den (HTML-) Inhalt , den WordPress in nginx generiert, mit dem ngx_http_sub_module neu schreiben . Auf diese Weise können Sie auch absolute URLs mit ähnlichen Eigenschaften umschreiben:
location / {
sub_filter 'http://example.com/' 'https://www.example.com/' ;
sub_filter 'http://www.example.com/' 'https://www.example.com/' ;
sub_filter_once off;
proxy_pass http://Apache2-PHP5.6:80;
proxy_set_header Host $host; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}