【问题标题】:nginx + docker: http to https redirectionnginx + docker:http 到 https 重定向
【发布时间】:2019-08-16 15:25:45
【问题描述】:

我在 docker 容器中有一个 nginx,我想对所有请求强制使用 SSL。因为我需要在容器外部的不同端口中公开网络服务器端口,所以在访问服务器时我没有使用标准端口。

我将容器内的 SSL 端口 443 映射到外部的 8888,所以当我编写 URL https://myserver:8888 时,HTTPS 工作正常。

当我不使用 https 前缀时会发生什么?端口 443 仍在侦听,但由于我没有使用 https 架构,我收到以下错误:

400 Bad Request
The plain HTTP request was sent to HTTPS port

如果我将请求重定向到端口 80 到 443 是不够的,因为我通过端口 8888 访问所有请求都是通过端口 443 传入的,但我不能保证使用的架构是 HTTP。

我的意思是,下面的块没有效果,因为我没有将端口 80 暴露在外面,只有 8888 直接映射到 443

server {
        server_name myserver;
        listen 80;
        return 301 https://$host:$server_port$request_uri;
}

即使用户将 http 放在 URL 上,我如何才能强制它工作?

谢谢

【问题讨论】:

    标签: docker nginx https


    【解决方案1】:

    您必须使用两个不同的端口:例如 8888 和 8889。

    将第一个端口绑定到容器的 80,第二个绑定到 443。

    如果客户想通过 http 联系您的容器,则必须使用 8888 (-> 80)。如果 vhost 配置良好,nginx 将向 https 端口 (8889 -> 443) 提供 301 或 302 HTTP 返回码(重定向)。

    所以你的回报可能看起来像

      return 301 https://$host:8889$request_uri;
    

    客户端将在正确的端口上启动 TLS 连接。


    由于技术限制,很难同时使用同一个端口来进行透明流量和 TLS 加密的流量,因此大多数网络服务器将侦听两个不同的端口:80 用于纯文本,443 用于 TLS。

    【讨论】:

    • 谢谢,我虽然关于这个方法,但我放弃了它,因为我不希望内部容器配置依赖于外部暴露端口(将来可以更改)。事实上,对我来说,在不同的端口上导出 http 以最终重定向到 https 端口是没有意义的,我只希望一切正常,而不需要在 URL 中写“https”。无论如何谢谢:)
    • 在这种情况下,您可以在 CDN 级别启用重定向(例如 Cloudlfare)。如果您在 Kubernetes 上,您可以使用 ingresses 进行 TLS 终止,如果您在单个服务器上,您可能需要使用 traefik.io
    猜你喜欢
    • 1970-01-01
    • 2020-09-11
    • 2020-03-21
    • 2016-03-10
    • 2015-08-16
    • 2015-02-14
    • 2019-06-04
    • 2015-05-09
    • 2011-03-29
    相关资源
    最近更新 更多