使用WordPress、Varish和SSL终结符分离HTTP和HTTPS内容?

时间:2014-10-05 作者:heypete

Background: 我与一家托管公司托管了一个WordPress网站,该公司在我的web服务器的上游放置了一个组合Varnish服务器+SSL终端系统。WordPress站点运行在Apache上,可以通过Varnish+SSL终止符通过HTTP和HTTPS访问。

设置如下所示:Imgur

图像信用:DigitalOcean (仅供参考,DigitalOcean不是我的主机,但其图像精确描述了我的主机上的设置。)

我没有Varnish+SSL系统的管理权限。

SSL终止符、Varnish和我的web服务器之间的所有本地通信都是未加密的。

Objective: 我希望WordPress管理界面只能通过安全(HTTPS)连接访问。用户应该可以选择通过HTTP或HTTPS访问WordPress站点,默认为HTTP。

Relevant Configuration: 由于web服务器本身不知道初始连接是否安全,如果我使用以下命令强制管理界面只能通过HTTPS访问,WordPress就会进入重定向循环define(\'FORCE_SSL_ADMIN\', true); 在我的wp-config.php 文件

然而,Varnish+SSL terminator系统确实包含指示所使用协议的标头,因此我使用以下工作配置:

define(\'FORCE_SSL_ADMIN\', true);
if ($_SERVER[\'HTTP_X_FORWARDED_PROTO\'] == \'https\')
       $_SERVER[\'HTTPS\']=\'on\';
因此,WordPress将自动识别访问者是否通过HTTP或HTTPS访问网站,并适当修改指向CSS/JavaScript文件的链接,以避免出现“不安全内容”警告。

Problem: 虽然WordPress会根据协议修改链接,以防止出现“不安全内容”警告,但Varnish并不关心协议,它会缓存内容(无论协议如何),直到过期。

例如,如果Varnish以空缓存开始,并且第一个访问者使用HTTPS,WordPress会修改所有链接以引用HTTPS并返回请求的内容。Varnish使用HTTPS链接缓存此内容。如果第二个访问者使用HTTP进行连接,Varnish将返回带有HTTPS链接的缓存内容,访问者将通过HTTPS加载CSS/JavaScript。如果用户单击指向站点上其他内容的任何链接,他们将通过HTTPS访问该内容。

然而,如果我们改变这种情况(即第一个访问者使用HTTP,第二个访问者使用HTTPS),第二个访问者就会出现问题:缓存的内容指示访问者通过HTTP加载CSS/JavaScript。浏览器出于安全原因拒绝这样做,浏览器显示“不安全内容”警告,并且所有格式/脚本均不起作用。

Attempted Solutions:

<完全禁用SSL,包括管理接口。这是最不受欢迎的选择,但至少它保持了工作的一致性(尽管不安全)

RewriteCond %{HTTP:X-Forwarded-Proto} =https
RewriteRule !^wp-(admin|login|register)(.*) - [C]
RewriteRule ^(.*)$ http://%{SERVER_NAME}/$1 [L]
如果没有Varnish,这将起作用:如果访问者通过HTTPS访问站点上的非管理员/登录/注册URL,Apache会进行重写,将访问者指向内容的HTTP版本。Varnish缓存重定向,而不关心使用哪种协议,因此访问者和所有后续访问者都会陷入重写循环。即使有效,这种方法也不太理想,因为它强制所有非管理员用户只能通过HTTP访问该网站——我希望允许用户可以选择使用HTTP或HTTPS访问内容。

Question: 如果没有对Varnish+SSL系统的管理员访问权限,是否有办法解决此问题,以便通过HTTP和HTTPS访问站点的用户不会踩到彼此的缓存?

2 个回复
SO网友:Cha0s

我知道这是一个很老的问题,但我会留下我的发现,以防其他人需要这样做。

您的方法帮助我实现了类似的设置。

为了让Varnish为同一页的http和https版本保留单独的缓存,只需在vcl\\U哈希中的hash\\u data()函数中添加X-Forwarded-Proto头。

像这样:

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);
}
这样用户访问http://www.example.net 将在用户访问时获取http版本的缓存https://www.example.net 将获取https版本的缓存。

您可能希望使其更加具体,以便它只保留html内容的双缓存,而不保留图像、css、js等,无论使用何种协议,它们通常都是相同的。

SO网友:Mark Kaplun

除非您有一些配置错误或行为不端的主题或插件,否则应该不会有问题。Wordpress core发送一个http标头,指示缓存服务器在登录用户访问页面时不要缓存发送的内容。

作为参考,标题设置为wp_get_nocache_headers 并发送自send_headers, 从现在2分钟的代码回顾来看,代码对我来说非常可靠。

结束

相关推荐

多站点数据库升级SSL错误

我已将我的多站点设置WordPress升级到3.6.1。在那之后,当我Network Upgrade > Database Upgrade 它显示:警告更新时出现问题http://www.example.com/site1. 您的服务器可能无法连接到其上运行的站点。错误消息:无法使用已知CA证书对对等证书进行身份验证请问发生了什么事我当前正在受信任的通配符SSL下运行该站点(not self-signed), 但仅安装在负载平衡器上。(显然,Apache服务器不需要安装证书。)<这是根本原因吗