防止 Nginx 更改主机

Prevent Nginx from changing host

我正在构建一个正在本地主机上运行的应用程序。我在 https://localhost/ 上安装了整个 docker 化的应用程序和 运行。 HTTP 请求正在重定向到 HTTPS

我在 docker-compose.yml 中的 nginx 配置正在按应有的方式处理所有请求。

我希望我的应用程序可以从任何地方访问,因此我尝试使用 Ngrok 将请求路由到我的本地主机。实际上,我有一个正在开发的移动应用程序,因此需要一个用于 api 的本地服务器。

现在,当我在浏览器中输入 ngrok 的 url 如 abc123.ngrok.io 时,nginx 将其转换为 https://localhost/。这适用于我的主机系统的浏览器,因为我的网络应用程序只能在那里工作,但是当我在我的移动模拟器中打开它时。没用。

我是nginx的新手。欢迎任何建议。 这是我的 nginx 配置。

nginx.conf

upstream web {
    ip_hash;
    server web:443;
}

# Redirect all HTTP requests to HTTPS
server {
    listen 80;
    server_name localhost;
    return 301 https://$server_name$request_uri;
}

# for https requests
server {

    # Pass request to the web container
    location / {
        proxy_pass https://web/;
    }

    location /static/ {
        root /var/www/mysite/;
    }
    
    listen 443 ssl;
    server_name localhost;

    # SSL properties
    # (http://nginx.org/en/docs/http/configuring_https_servers.html)    
    ssl_certificate /etc/nginx/conf.d/certs/localhost.crt;
    ssl_certificate_key /etc/nginx/conf.d/certs/localhost.key;
    root /usr/share/nginx/html;    
    add_header Strict-Transport-Security "max-age=31536000" always;
}

这个配置是我从教程中得到的。

首先,您设置从每个 HTTP 请求到 HTTPS 的重定向:

# Redirect all HTTP requests to HTTPS
server {
    listen 80;
    server_name localhost;
    return 301 https://$server_name$request_uri;
}

您在此处使用 $server_name 变量,因此对您应用的每个 /some/path?request_string HTTP 请求都将重定向到 https://localhost/some/path?request_string。至少将 return 指令更改为

return 301 https://$host$request_uri;

检查 this 问题以获取有关 $host$server_name 变量之间差异的信息。

如果这些是您的 nginx 配置中唯一的服务器块,您可以完全安全地删除 server_name localhost; 指令,这些块仍然是 80 和 443 TCP 端口上所有传入请求的默认块。

第二个,如果您正在为 localhost 使用 self-signed 证书,请准备好浏览器抱怨不匹配的证书(为 localhost 颁发,出现在 abc123.ngrok.io) .如果它没有破坏您的移动应用程序,那没问题,但如果是,您可以在启动 ngrok 连接后从 Lets Encrypt 免费获取 abc123.ngrok.io 域的证书,请查看 this 页面用于可用的 ACME 客户端和选项。或者,如果您的调试过程没有严格要求,您可以完全禁用 HTTPS,只需使用这个 server 块:

server {
    listen 80;

    # Pass request to the web container
    location / {
        proxy_pass https://web/;
    }

    location /static/ {
        root /var/www/mysite/;
    }
}

当然这不应该用于生产,仅用于调试。

最后一个。我看不出在 docker 本身内部的 nginx 和 web 容器之间加密流量有任何意义,特别是如果您已经使用 nginx 设置了 HTTP-to-HTTPS 重定向。它在安全方面没有给你任何好处,只是一些额外的开销。在端口 80 上使用纯 HTTP 协议在 nginx 和 web 容器之间进行通信:

upstream web {
    ip_hash;
    server web:80;
}

server {
    ...
    location / {
        proxy_pass http://web;
    }
}