在 https 上下文中为所有服务器块强制使用 https

Force https for all server blocks in https context

我是第一次尝试 nginx,我是用 docker 来做的。 基本上我想实现以下架构

我在启动时生成带有一些环境变量的 /etc/nginx/conf.d/default.conf 文件。然后该文件包含在 default.conf 文件的 http 上下文中,从而对我可以配置的内容带来一些限制。 (related issue)

你可以看到我当前的 nginx.conf file here(文件很大,无法嵌入此处)。

并且您可以看到 docker-compose.yml file here

问题:

400 Bad Request 纯 HTTP 请求发送到 HTTPS 端口

我实际上无法将对 http://(app/api).example.com 的任何调用重定向到它的 https 版本,我已经尝试过但没有成功:(参见上面的链接文件)

server {
    listen 80 ssl;
    listen 443 ssl;
    listen [::]:80 ssl;
    listen [::]:443 ssl;
    server_name  api.dev.local;

    if ($http_x_forwarded_proto = "http") {
      return 301 https://$server_name$request_uri;
    }

    # more code...
}

任何关于我的实际配置的建议都非常欢迎在评论部分!我刚刚开始使用 nginx,因此阅读了 tons of artciles,其中提供了代码片段,在阅读了它们的用途后,我只需复制并粘贴这些代码片段。

https 协议是 http 的扩展,因此它们在某种程度上是 不同的 协议。目前,您的服务器不期望 :80 上出现 http,而是由于设置 listen 80 ssl 而期望 https。这会导致错误。

您需要分开处理 :80 上的 http 请求,应该重定向到 :443 上的 https 和处理 :443 上的 https 请求,后者应该被处理通常。

这可以通过在 :80:

上为 http 拆分出另一个 server 配置块来完成
server {
    listen 80 default_server;
    listen [::]:80 default_server;
    server_name _;
    return 301 https://$host$request_uri;
}

...并从当前块中删除对 :80 的监听:

server {
    listen 443 ssl;
    listen [::]:443 ssl;

    # more code...
}

如果需要,以下博客文章提供了更多详细信息https://bjornjohansen.no/redirect-to-https-with-nginx