在家里,我有 1 台托管服务器,上面有一些网站,使用 Virtualmin(很棒的工具!),一切都运行良好,HTTPS、HTTP……甚至在我的互联网路由器后面,使用 NAT 通过将端口 80 和 443 转发到我的网络服务器。
客户端 443/HTTPS -> 我的互联网路由器 NAT -> 80/HTTP 或 443/HTTPS Apache
我通过在 Apache 前面添加负载平衡器 HA 代理来进行一些改进:运行良好。
客户端 443/HTTPS -> 我的互联网路由器 NAT ->HA 代理 443/HTTPS SSL 终止-> 82/HTTP 或 442/HTTPS Apache (192.168.0.40)
这意味着我的网站仍然可以通过 HTTPS 协议访问,但端口为 442
我甚至添加了 keepalived 并且它运行良好:
客户端 443/HTTPS -> 我的互联网路由器 NAT ->保留 IP 地址-> HA 代理 443/HTTPS SSL 终止 -> 82/HTTP 或 442/HTTPS Apache
现在,我想添加 Web 缓存 Varnish。您可能知道,Varnish 的免费版本不支持 HTTPS。这对我来说不是问题,因为我有处理 SSL 终止的 HA Proxy。我想要做的是将 Varnish 设置在 HA Proxy 后面和 Apache 前面。
客户端 443/HTTPS -> 我的互联网路由器 NAT -> KEEPALIVED IP 地址 -> HA 代理 443/HTTPS SSL 终止 ->清漆 81/HTTP-> 82/HTTP 或 442/HTTPS Apache
但它不起作用...例如,当我尝试使用 HTTPS 访问我的网站时https://myexemple.com,主页已加载,但所有其他静态文件均未加载...查看页面网络检查器(在浏览器中按 F12),我可以看到这些静态文件是使用 HTTP 提供的(参见附加的屏幕截图)。
仅为本网站安装了 wordpress,没有其他任何内容。
是否有人遇到过类似的问题,或者可能成功实现了像我这样的架构模式:
客户端 443/HTTPS -> KEEPALIVED IP 地址 -> HA 代理 443/HTTPS SSL 终止 ->清漆 81/HTTP-> 82/HTTP 或 442/HTTPS Apache
一般来说,使用 Varnish 时如何处理 HTTPS?特别是使用 Wordpress 时:在后端,我们必须指定网站的 URL(即https://kmx.ovh就我而言)?谢谢
好吧,我尝试在 HA Proxy 后面和 Apache 网站前面设置 Varnish,请参阅以下配置:
这是我的 HA Proxy 的配置(非常简单):
global
log /dev/log local0
log /dev/log local1 notice
chroot /var/lib/haproxy
stats socket /run/haproxy/admin.sock mode 660 level admin expose-fd listeners
stats timeout 30s
user haproxy
group haproxy
daemon
ca-base /etc/ssl/certs
crt-base /etc/ssl/private
ssl-default-bind-ciphers ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384
ssl-default-bind-ciphersuites TLS_AES_128_GCM_SHA256:TLS_AES_256_GCM_SHA384:TLS_CHACHA20_POLY1305_SHA256
ssl-default-bind-options ssl-min-ver TLSv1.2 no-tls-tickets
tune.ssl.default-dh-param 4096
defaults
log global
mode http
option httplog
option dontlognull
retries 3
option redispatch
maxconn 2000
timeout connect 5000
timeout client 50000
timeout server 50000
errorfile 400 /etc/haproxy/errors/400.http
errorfile 403 /etc/haproxy/errors/403.http
errorfile 408 /etc/haproxy/errors/408.http
errorfile 500 /etc/haproxy/errors/500.http
errorfile 502 /etc/haproxy/errors/502.http
errorfile 503 /etc/haproxy/errors/503.http
errorfile 504 /etc/haproxy/errors/504.http
frontend http
description "HTTP handler"
bind *:80
mode http
option httplog
option http-keep-alive
maxconn 500
acl ACL_is_acme_challenge path_beg /.well-known/acme-challenge/
acl ACL_allowed_ip src 192.168.0.0/24
http-request allow if ACL_is_acme_challenge
http-request allow if ACL_allowed_ip
use_backend be_default
frontend https
description "SSL Endpoint!"
bind *:443 ssl crt /etc/haproxy/cert/
mode http
option httplog
acl tls req.ssl_hello_type 1
option http-server-close
http-request capture req.hdr(X-Forwarded-Proto) len 10
http-request add-header X-Forwarded-Proto %[capture.req.hdr(0)]
http-request add-header X-Forwarded-Proto https if { ssl_fc }
option forwardfor except 127.0.0.1
use_backend bes_default
backend be_default
description 'Forward to Apache HTTP backend'
mode http
option forwardfor
balance roundrobin
server 37-81 192.168.0.37:81 maxconn 250 check
backend bes_default
description 'Forward to Apache HTTPS backend'
mode http
option forwardfor
balance roundrobin
server 37-81 192.168.0.37:81 maxconn 250 check
下面是我的 Varnish 配置文件(非常简单……):
#
# This is an example VCL file for Varnish.
#
# It does not do anything by default, delegating control to the
# builtin VCL. The builtin VCL is called when there is no explicit
# return statement.
#
# See the VCL chapters in the Users Guide for a comprehensive documentation
# at https://www.varnish-cache.org/docs/.
# Marker to tell the VCL compiler that this VCL has been written with the
# 4.0 or 4.1 syntax.
vcl 4.1;
# Default backend definition. Set this to point to your content server.
backend default {
.host = "192.168.0.37";
.port = "82";
}
backend tmp-kiminox-net {
.host = "tmp.kiminox.net";
.port = "82";
}
backend kmx-ovh {
.host = "kmx.ovh";
.port = "82";
}
sub vcl_recv {
# Happens before we check if we have this in cache already.
#
# Typically you clean up the request here, removing cookies you don't need,
# rewriting the request, etc.
if (req.http.host == "tmp.kiminox.net") {
#You will need the following line only if your backend has multiple virtual host names
set req.http.host = "tmp.kiminox.net";
set req.backend_hint = tmp-kiminox-net;
return (pipe);
}
if (req.http.host ~ "kmx.ovh") {
set req.http.Host = req.http.host;
set req.backend_hint = kmx-ovh;
return (pipe);
}
}
sub vcl_backend_response {
# Happens after we have read the response headers from the backend.
#
# Here you clean the response headers, removing silly Set-Cookie headers
# and other mistakes your backend does.
set beresp.http.X-Cache2 = "via Varnish cache 37";
}
sub vcl_deliver {
# Happens when we have all the pieces we need, and are about to send the
# response to the client.
#
# You can do accounting or modifying the final object here.
if (obj.hits > 0) {
set resp.http.X-Cache = "HIT";
} else {
set resp.http.X-Cache = "MISS";
}
}
sub vcl_hash {
if(req.http.X-Forwarded-Proto) {
hash_data(req.http.X-Forwarded-Proto);
}
}
Varnish 服务:
[Unit]
Description=Varnish Cache, a high-performance HTTP accelerator
Documentation=https://www.varnish-cache.org/docs/ man:varnishd
[Service]
Type=simple
# Maximum number of open files (for ulimit -n)
LimitNOFILE=131072
# Locked shared memory - should suffice to lock the shared memory log
# (varnishd -l argument)
# Default log size is 80MB vsl + 1M vsm + header -> 82MB
# unit is bytes
LimitMEMLOCK=85983232
ExecStart=/usr/sbin/varnishd \
-j unix,user=vcache \
-F \
-a :81 \
-T localhost:6082 \
-f /etc/varnish/default.vcl \
-S /etc/varnish/secret \
-s malloc,256m
ExecReload=/usr/share/varnish/varnishreload
ProtectSystem=full
ProtectHome=true
PrivateTmp=true
PrivateDevices=true
[Install]
WantedBy=multi-user.target
答案1
步骤 1:确保 HAProxy 发送 X-Forwarded-Proto 标头
正如所提到的https://stackoverflow.com/questions/77885246/client-443-https-virtual-ip-ha-proxy-80-http-and-443-https-ssl-terminaison/77885399?noredirect=1#comment137311196_77885399您也问了这个问题,我建议您首先在 HAProxy 后端配置中添加以下标头:
http-request add-header X-Forwarded-Proto https if { ssl_fc }
第 2 步:让 WordPress 理解 X-Forwarded-Proto
现在我知道您正在使用 WordPress,您必须告知 WordPress 有关X-Forwarded-Proto
标题的信息,因为它不支持开箱即用的功能。
正如所提到的https://www.varnish-software.com/developers/tutorials/mixed-content-err-too-many-redirects-wordpress-varnish/#checking-the-x-forwarded-proto-header-in-wordpress,将以下代码添加到您的wp-config.php
:
if (isset($_SERVER['HTTP_X_FORWARDED_PROTO']) &&
strpos($_SERVER['HTTP_X_FORWARDED_PROTO'], 'https') !== false) {
$_SERVER['HTTPS'] = 'on';
}
步骤 3:根据 X-Forwarded-Proto 标头创建缓存变体
为了确保 Varnish 在不同的缓存对象中缓存 HTTPS 和 HTTP 响应,您必须更改vcl_hash
子例程并添加X-Forwarded-Proto
变体。
以下是实现该功能的代码:
sub vcl_hash {
if(req.http.X-Forwarded-Proto) {
hash_data(req.http.X-Forwarded-Proto);
}
}
但是,为了确保 Varnish 中的缓存正确,你应该使用专门的 VCL 文件。我建议你阅读https://www.varnishsoftware.com/developers/tutorials/configuring-varnish-wordpress/并使用该 VCL 代码以及清除插件。