【问题标题】:Traefik (Docker) Not Setting X-Forwarded-* Headers?Traefik(Docker)未设置 X-Forwarded-* 标头?
【发布时间】:2019-04-14 20:13:35
【问题描述】:

我正在尝试在 Docker 中运行 Apache,在 https 的 Traefik 反向代理之后。一切正常,除了当我访问没有尾部斜杠的文件夹 URL 时,Apache 将我重定向到非 https(即https://www.example.com/folder -> http://www.example.com/folder/)。这是由 Apache mod_dir DirectorySlash 引起的,如 herehere 所述。解决方案是使用重写规则,该规则在 DirectorySlash 之前启动,如下所示:

# Redirect to HTTPS before Apache mod_dir DirectorySlash redirect to HTTP
RewriteCond %{HTTP:X-Forwarded-Proto} =https
RewriteCond %{LA-U:REQUEST_FILENAME} -d
RewriteRule ^/(.*[^/])$ https://%{HTTP_HOST}/$1/ [R=301,L,QSA]

但是,问题是 Traefik 似乎没有设置 X-Forwarded-* 标头。这是我得到的标题的屏幕截图:

这是我在 Apache docker-compose 文件中使用的标签:

  labels:
    - traefik.enable=true
    - traefik.port=80
    - traefik.frontend.rule=PathPrefix:/web  #Apache is accessible under https://example.com/web/

我尝试了各种标签组合,但无论我做什么,x-forwarded-* 标头似乎总是丢失。例如(refref):

- "traefik.frontend.headers.SSLProxyHeaders=X-Forwarded-Proto:https"
- "traefik.frontend.headers.SSLRedirect=true"

我什至尝试让 Traefik 添加我自己的自定义标头,但无法显示它们 (ref):

- "traefik.https.middlewares.testHeader.Headers.CustomRequestHeaders.X-Script-Name=test"

...但是,只是为了说服自己我没有发疯,而这个实际上在 Traefik 后面运行,并且 Traefik 可以添加我可以看到的标题,这确实有效并导致 X-Frame-Options 标头出现在 Firefox 中:

- traefik.frontend.headers.frameDeny=true

总而言之,问题是:为什么 Traefik 不设置 x-forwarded-* 标头(然后我可以在我的 Apache RewriteRules 中使用它) - 我怎样才能让它这样做?

【问题讨论】:

    标签: docker docker-compose http-headers reverse-proxy traefik


    【解决方案1】:

    对于任何发现此问题并想知道的人,我的问题是双重的:

    1) X-Forwarded-* 标头在浏览器中不可见。您可以使用 phpinfo() 或转储 $_SERVER 变量在服务器上查看它们:

    2) 重定向不起作用(修复 DirectorySlash 问题)的原因是除了上面列出的 RewriteRules 之外,您的 htaccess 还必须包含 RewriteOptions AllowNoSlash。来自Apache documentation

    默认情况下,mod_rewrite 将忽略映射到磁盘目录但缺少尾部斜杠的 URL,期望 mod_dir 模块向客户端发出重定向到带有尾部斜杠的规范 URL。 [...] 可以启用 AllowNoSlash 选项以确保不再忽略重写规则。如果需要,此选项可以在与目录匹配的 .htaccess 文件中应用重写规则,而无需尾部斜杠。

    【讨论】:

    • 您是如何解决斜线问题的?我相信我遇到了同样的问题,但我没有在 htaccess 中重写任何内容或在 apache 中重定向。所以我不知道如何解决这个问题。
    • 根据我的回答 - 使用 RewriteRule 和 AllowNoSlash 解决。
    【解决方案2】:

    你试过了吗

    traefik.frontend.passHostHeader: true
    

    如果可能的话,我建议让 http 到 https 的重定向按 traefik 排序:

    [entryPoints]
        [entryPoints.http]
        address = ":80"
          [entryPoints.http.redirect]
          entryPoint = "https"
    
        [entryPoints.https]
        address = ":443"
          [entryPoints.https.tls]
    

    【讨论】:

    • passhostheader:是的,我试过了。重定向:我什至没有向 Traefik(或通过我的路由器)公开一个 http 入口点——只是一个 https、入口点/端口。
    • 嗯,但是如果您的问题是 apache 对 http 的重写 - 为什么不在 traefik 入口点再次重写呢?
    • 因为那时我必须通过我的路由器不必要地打开另一个端口。问题的症结在于“为什么 Traefik 不设置预期的标头”——好像是这样,无需额外的前端配置或额外的端口就可以解决所有问题。
    • 将 http 流量重定向到 https 不再以这种方式完成(适用于 Traefik 1.7 及之前的版本)。使用 Traefik 2.0 及更高版本,它现在在路由器上配置,请参阅:docs.traefik.io/migration/v1-to-v2/…
    • 做这个 http 到 https 重定向已经解决了我的类似问题!
    猜你喜欢
    • 2021-12-06
    • 1970-01-01
    • 2018-03-19
    • 1970-01-01
    • 1970-01-01
    • 2013-12-05
    • 2018-06-15
    • 2020-07-20
    • 2020-01-25
    相关资源
    最近更新 更多