可以组合多个Header中间件吗?

时间:2019-09-29 21:24:47

标签: http-headers traefik

我有一些服务需要不同的 Content-Security-Policy 标头。我最初的尝试是创建一个默认的中间件来处理所有通用标头,然后我可以为每个路由器创建具有唯一contentSecurityPolicy设置的新中间件。

当您发现如果您有多个带有标头的中间件时,我感到很惊讶,最后应用的一个会覆盖前一个。这意味着我必须为每个服务在中间件中重新创建所有标头。而且,如果我将来进行更改,则必须确保在所有这些更改中都得到体现。

作为一种解决方法,我尝试添加带有 Content-Security-Policy 标头的customResponseHeaders,但这并没有覆盖默认标头,即使它显示在仪表板上。

我的设置摘录:

...
[http.routers.service]
  rule = "Host(`example.com`)"
  entrypoints = ["https"]
  middlewares = ["default", "service"]
  service = "service"
...
[http.middlewares.default.headers]
  accessControlAllowOrigin = "origin-list-or-null"
  stsSeconds = 315360000
  stsIncludeSubdomains = true
  stsPreload = true
  customFrameOptionsValue = "SAMEORIGIN"
  contentTypeNosniff = true
  browserXssFilter = true
  referrerPolicy = "strict-origin"
  contentSecurityPolicy = "default-src 'none';form-action 'none';frame-ancestors 'none';base-uri 'none'"
  featurePolicy = "notifications 'none'; camera 'none'"
[http.middlewares.service.headers]
  contentSecurityPolicy = "default-src 'none';script-src 'self' 'unsafe-inline';style-src 'self';img-src 'self'"

1 个答案:

答案 0 :(得分:0)

Traefik forums的讨论中,我指出了这样一个事实,即the used library的这种行为似乎是预期的。经过一些试验,我想出了以下解决方案:

跳过默认的安全标头,仅使用customResponseHeaders选项。它们似乎是与提到的库分开处理的,可以合并,因此您必须首先从最特定的库开始,然后添加常规库,例如:middlewares = ["service", "default"]

这是问题中的重构标头:

[http.middlewares.default.headers.customResponseHeaders]
  Access-Control-Allow-Origin = "null"
  Content-Security-Policy = "default-src 'none';form-action 'none';frame-ancestors 'none';base-uri 'none'"
  Feature-Policy = "notifications 'none'; camera 'none'"
  Referrer-Policy = "strict-origin"
  Server = "home.stoinov.com"
  Strict-Transport-Security = "max-age=315360000; includeSubDomains; preload"
  X-Content-Type-Options = "nosniff"
  X-Frame-Options = "SAMEORIGIN"
  X-Xss-Protection = "1; mode=block"
[http.middlewares.service.headers.customResponseHeaders]
  Content-Security-Policy = "default-src 'none';script-src 'self' 'unsafe-inline';style-src 'self';img-src 'self'"

对于相同的结果,默认设置实际上比使用预定义的标题短了一行。

一个缺点是,在仪表板上,您会看到标题堆积在中间件卡的顶部,但是实际的安全标题将保留其默认值。如果我们有标头名称和值,说实话,这可能是一个加号。