HAProxy+Keepalived+Varnish+Apache架构下WordPress静态资源HTTP加载异常问题求助
大家好,我目前在搭建一套HAProxy+Keepalived+Varnish+Apache的Web架构,现在遇到了一个头疼的问题,想请教下有没有朋友碰到过或者解决过类似的情况。
先跟大家说下我的架构演进过程:
最开始我用Virtualmin管理单台Apache服务器,通过家里的路由器NAT转发80和443端口,网站的HTTPS和HTTP都正常运行。后来我做了架构优化,先加了HAProxy做SSL终止,架构变成:
Client 443/HTTPS -> 路由器NAT -> HAProxy 443/HTTPS(SSL终止) -> Apache 82/HTTP或442/HTTPS(192.168.0.40)
这一步没问题,网站依然能正常通过HTTPS访问,只是Apache的端口改成了82和442。
之后我又加上了Keepalived做高可用,架构变成:
Client 443/HTTPS -> 路由器NAT -> Keepalived虚拟IP -> HAProxy 443/HTTPS(SSL终止) -> Apache 82/HTTP或442/HTTPS
这一步也正常工作。
现在我想加入Varnish做Web缓存,因为免费版Varnish不支持HTTPS,刚好我有HAProxy做SSL终止,所以打算把Varnish放在HAProxy和Apache之间,最终架构是:
Client 443/HTTPS -> 路由器NAT -> Keepalived虚拟IP -> HAProxy 443/HTTPS(SSL终止) -> Varnish 81/HTTP -> Apache 82/HTTP或442/HTTPS
但问题来了:访问网站(比如https://myexemple.com)时,首页能正常加载,但所有静态资源(CSS、JS、图片等)都加载失败。打开浏览器F12的网络面板一看,发现这些静态资源都是用HTTP协议请求的,而不是HTTPS(附截图)。
[静态资源HTTP请求截图](enter image description here)
这个网站是刚安装的WordPress,没做任何额外配置。
想请教大家几个问题:
- 有没有人成功搭建过我这种架构?有没有什么我漏掉的配置细节?
- 一般使用Varnish时,该怎么处理HTTPS相关的问题?
- 特别是针对WordPress,我后台已经把网站URL设置成
https://kmx.ovh了,为什么还会出现静态资源走HTTP的情况?
下面是我的相关配置,供大家参考:
HAProxy配置
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配置(/etc/varnish/default.vcl)
# # 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服务配置(systemd单元文件)
[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
备注:内容来源于stack exchange,提问作者kiminox

