如何在docker traefik中使用SSL端接清漆



我使用的是docker traefik,在清漆后面缓存,我的网站在清漆后面。这是docker为我的网站和清漆服务撰写:

version: "3.7"

services:
dev-ui-service:
image: mywebsite.ui:latest
networks:
- localnetwork
varnish:
image: myvarnish:latest
deploy:
labels:
- "traefik.enable=true"
- "traefik.http.routers.ui.rule=Host(`mydomain.com`)"
- "traefik.http.routers.ui.entrypoints=web"
- "traefik.http.services.ui.loadbalancer.server.port=80"
- "traefik.http.routers.ui-secured.rule=Host(`mydomain.com`)"
- "traefik.http.routers.ui-secured.entrypoints=web-secured"
- "traefik.http.routers.ui-secured.tls.certresolver=mytlschallenge"
- "traefik.docker.network=traefik-proxy"
mode: replicated
replicas: 1
resources:
limits:
cpus: '0.5'
memory: 200M
reservations:
cpus: '0.2'
memory: 20M
networks:
- localnetwork
- traefik-proxy
depends_on:
- dev-ui-service
networks:
localnetwork:
traefik-proxy:
external: true

这是我默认的.vcl文件:

vcl 4.0;
backend default {
.host = "dev-ui-service";
.port = "4200";
}
# If you don't include below, header Age in response to client always be 0
sub vcl_deliver {
# Display hit/miss info
if (obj.hits > 0) {
set resp.http.V-Cache = "HIT";
}
else {
set resp.http.V-Cache = "MISS";
}
set resp.http.Access-Control-Allow-Origin = "*";
set resp.http.Access-Control-Allow-Headers = "Accept,Authorization,Cache-Control,Content-Type,DNT,If-Modified-Since,Keep-Alive,Origin,User-Agent,X-Mx-ReqToken,X-Requested-With";
set resp.http.Allow = "GET, POST";
set resp.http.Access-Control-Allow-Credentials = "true";
set resp.http.Access-Control-Allow-Methods = "GET, POST, PUT, DELETE, OPTIONS, PATCH";
set resp.http.Access-Control-Expose-Headers = "X-Pagination-Total, X-Pagination-Page, X-Pagination-Limit";
}
sub vcl_backend_response {
if (beresp.status == 200) {
unset beresp.http.Cache-Control;
set beresp.http.Cache-Control = "public; max-age=200";
set beresp.ttl = 200s;
}
set beresp.http.Served-By = beresp.backend.name;
set beresp.http.V-Cache-TTL = beresp.ttl;
set beresp.http.V-Cache-Grace = beresp.grace;
}

一切都可以,但清漆不支持https,所以所有请求都来自https MISS。当请求从traefik发送到清漆时,我如何终止SSL?

内置VCL行为

VCL扩展了vcl_delivervcl_backend_response子例程的标准行为。因为您没有为vcl_recv提供任何逻辑,所以将使用Varnish内置的VCL行为。

事实上,Varnish总是使用内置的VCL,除非有问题的子例程被重写。

请参阅https://github.com/varnishcache/varnish-cache/blob/6.0/bin/varnishd/builtin.vcl

为什么会错过

If we look at the built-in VCL for `vcl_recv`, you'll see that there are some caching rules in place:
sub vcl_recv {
if (req.method == "PRI") {
/* This will never happen in properly formed traffic (see: RFC7540) */
return (synth(405));
}
if (!req.http.host &&
req.esi_level == 0 &&
req.proto ~ "^(?i)HTTP/1.1") {
/* In HTTP/1.1, Host is required. */
return (synth(400));
}
if (req.method != "GET" &&
req.method != "HEAD" &&
req.method != "PUT" &&
req.method != "POST" &&
req.method != "TRACE" &&
req.method != "OPTIONS" &&
req.method != "DELETE" &&
req.method != "PATCH") {
/* Non-RFC2616 or CONNECT which is weird. */
return (pipe);
}
if (req.method != "GET" && req.method != "HEAD") {
/* We only deal with GET and HEAD by default */
return (pass);
}
if (req.http.Authorization || req.http.Cookie) {
/* Not cacheable by default */
return (pass);
}
return (hash);
}

当以下条件成立时,会发生缓存未命中:

  • GETHEAD之外的请求方法
  • 请求包含Authorization标头
  • 请求包含Cookie标头

最有可能的情况是导致MISS的请求包含cookie。

如何将未命中转化为命中

假设cookie是问题所在,您应该在vcl_recv中编写一些VCL逻辑,并确定保留哪些cookie和删除哪些cookie。

大多数跟踪cookie对服务器端没有影响,可以删除。

其他cookie由应用程序使用,无法删除。

如果特定的URL资源需要cookie值,可以使用return(pass)来确保Varnish不会缓存它。

其他不需要cookie值的页面可以剥离这些cookie,以确保缓存命中。

对于需要cookie但cookie值变化较小且可控的页面,可以使用缓存变化并将cookie值缓存在vcl_hash中。

再次,我假设cookie是发生缓存未命中的原因。

如何优化TLS终止

Varnish的开源版本不支持本机TLS,因此需要终止。

Varnish通过支持PROXY协议方便TLS终止。显然Traefik也支持它。

通过打开一个额外的监听端口,您可以在Varnish级别启用PROXY协议

而简化的仅限HTTP的varnishd命令可以如下所示:

varnishd -a :80 -f /etc/varnish/default.vcl

PROXY供电的varnishd命令可能如下所示:

varnishd -a :80 -a :8443,PROXY -f /etc/varnish/default.vcl

正如您所看到的,我在端口8443上添加了一个额外的侦听接口,它只支持PROXY流量。端口80对于常规HTTP流量仍然处于活动状态。

然后,您可以将Traefik配置为终止TLS并将流量路由到Varnish。如果您在Traefik上启用PROXY协议,Varnish将能够利用该协议。

在VCL中,您可以使用以下VCL片段检测HTTP/HTTPS请求:

vcl 4.1;
import proxy;
sub vcl_recv {
if (proxy.is_ssl()) {
set req.http.X-Forwarded-Proto = "https";
} else {
set req.http.X-Forwarded-Proto = "http";
}
}

然后,您可以在应用程序中返回Vary: X-Forwarded-Proto响应标头,以基于协议创建缓存变体。

PROXY协议的另一个优点是X-Forwarded-For报头总是包含原始客户端的客户端IP地址,而与跳数无关。

相关内容

  • 没有找到相关文章

最新更新