【问题标题】:Nginx has conflict with an application running on 443Nginx 与在 443 上运行的应用程序发生冲突
【发布时间】:2021-12-16 08:27:35
【问题描述】:

在 MacOS 中,我通常通过 sudo PORT=443 HTTPS=true ./node_modules/.bin/react-scripts start 在 localhost 中运行我的项目。因此,https://localhost/#/start 在浏览器中工作。

现在,要在 localhost 中运行第三方身份验证,我需要运行 nginx。这是我的/usr/local/etc/nginx/nginx.conf

worker_processes  1;

events {
    worker_connections  1024;
}

http {
    include       mime.types;
    default_type  application/octet-stream;

    sendfile        on;

    keepalive_timeout  65;

    upstream funfun {
        server 178.62.87.72:443;
    }

    server {
        listen              443 ssl;
        server_name localhost;
        ssl_certificate /etc/ssl/localhost/localhost.crt;
        ssl_certificate_key /etc/ssl/localhost/localhost.key;
        ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
        ssl_prefer_server_ciphers on;
        ssl_session_timeout 1d;
        ssl_stapling off;
        ssl_stapling_verify off;
        add_header Strict-Transport-Security max-age=15768000;
        add_header X-Frame-Options "";
        proxy_ssl_name "www.funfun.io";
        proxy_ssl_server_name on;

        location ~ /socialLoginSuccess {
            rewrite ^ '/#/socialLoginSuccess' redirect;
        }

        location ~ /auth/(.*) {
            proxy_pass  https://funfun/10studio/auth/$1?$query_string;
            proxy_set_header Host localhost;
        }

        location / {
            proxy_set_header    Host                $host;
            proxy_set_header    X-Forwarded-For     $proxy_add_x_forwarded_for;
            proxy_set_header    X-Forwarded-Proto   $scheme;
            proxy_set_header    Accept-Encoding     "";
            proxy_set_header    Proxy               "";
            proxy_pass          https://localhost/;
            # These three lines added as per https://github.com/socketio/socket.io/issues/1942 to remove socketio error
            proxy_http_version 1.1;
            proxy_set_header   Upgrade $http_upgrade;
            proxy_set_header   Connection "upgrade";
        }
    }
    include servers/*;
}

但是,启动 nginx 会返回以下错误:

$ sudo nginx
nginx: [emerg] bind() to 0.0.0.0:443 failed (48: Address already in use)
nginx: [emerg] bind() to 0.0.0.0:443 failed (48: Address already in use)
nginx: [emerg] bind() to 0.0.0.0:443 failed (48: Address already in use)
nginx: [emerg] bind() to 0.0.0.0:443 failed (48: Address already in use)
nginx: [emerg] bind() to 0.0.0.0:443 failed (48: Address already in use)
nginx: [emerg] still could not bind()

看来,nginx 已经和 443 上运行的应用发生冲突了。有谁知道为什么?

另外,谁能告诉我 nginx 配置文件中 location / { ... } 块的用途是什么?

【问题讨论】:

    标签: nginx port


    【解决方案1】:

    一次只有一个应用程序可以绑定/侦听给定端口。

    您的 应用 在端口 443 上运行: sudo PORT=443 HTTPS=true ./node_modules/.bin/react-scripts start

    然后,当您尝试在端口 443 上启动 nginx 时,它会失败,因为您的应用程序已经在使用 443。

    解决这个问题:

    • 停止 nginx
    • 停止您的应用程序并重新启动它在不同的端口上运行(例如3000):
      • sudo PORT=3000 HTTPS=true ./node_modules/.bin/react-scripts start
    • 编辑您的 nginx 配置,告诉 nginx 您的应用程序(“上游”)现在正在端口 3000 上运行。
      • proxy_pass https://localhost:3000;
    • 启动 nginx

    另外,我建议您在 nginx 上执行 SSL (https) 终止,并让 nginx 不安全地连接到本地主机上的应用程序,以减少其他问题。目前,您似乎正在 nginx 上进行 ssl 终止,然后对您的应用程序/上游进行另一个 ssl 连接/终止。在 localhost 或通过安全/私有网络(例如在 AWS VPC 中)进行连接时,这确实没有必要。

    • 停止 nginx
    • 停止您的应用程序并重新启动它在不同的端口上运行(例如3000):
      • sudo PORT=3000 HTTPS=true ./node_modules/.bin/react-scripts start 中删除HTTPS=true
      • ...以及您的 React 应用中禁用 ssl/https 所需的任何其他更改。
    • 编辑您的 nginx 配置以告诉 nginx 您的应用程序(“上游”)现在在端口 3000 上运行并且不安全(将 https 更改为 http)。
      • proxy_pass http://localhost:3000;
    • 启动 nginx

    对于生产来说,你真的应该总是在你的应用程序前面运行 nginx。这使您可以轻松地进行 ssl 终止、负载平衡(多个应用程序/上游)以及提供静态文件(jpg、css 等),而无需通过 nodejs 或其他应用程序服务器运行。它将更好地扩展。适合工作的正确工具。

    出于本地开发目的,您可以针对本地不安全的 http://localhost:3000 工作。如果您出于某种原因真的讨厌使用端口 3000,那么您当然可以将 NODE_ENV 与 dotenv 或类似方法结合使用来更改应用程序在开发模式和生产模式下使用的端口。在开发期间确实没有任何理由需要在 localhost 上使用 https/443。您将无法为 localhost 获得受信任的 SSL 证书,因此真的没有任何意义……它只会让您的生活更加困难。

    例如,我使用 google 针对 http://localhost:3000 测试 oauth 登录流程没有问题。

    【讨论】:

    • 谁能告诉我我的 nginx 配置文件中 location / { ... } 块的用途是什么?删除它似乎对我的测试没有影响。
    • 位置块告诉 nginx 你想如何处理不同的请求。例如将请求发送到 /auth 到一个地方,然后发送到 /foobar 到其他地方或使用不同的缓存规则。最具体(正则表达式或最长)匹配的位置块“获胜”,但请参阅precedence。在您的情况下,您有两个正则表达式块... /auth 转到 funfun (不是域...在您的主机文件中还是?)和 /success 正在重定向。所有其他请求将由代理到您的应用的 / 位置处理。
    • "编辑您的 nginx 配置以告诉 nginx 您的应用程序(“上游”)现在在端口 3000 上运行并且不安全(将 https 更改为 http)。 => 我的文件中有几个proxy_pass,您建议将哪个替换为proxy_pass http://localhost:3000;
    • 我说的是proxy_passlocalhost,你只有一个我能看到的。另一个proxy_pass 是https://funfun/10studio/auth/...,我不确定应该做什么,因为它不是本地主机,也不是真正的域。您是否在主机文件中添加了某些内容或将 funfun 映射到真实计算机?
    • https://funfun/10studio/auth/...upstream funfun { server 178.62.87.72:443; } 相关。
    【解决方案2】:

    任何端口都可以绑定到给定接口一次。现在,如果您运行您的反应应用程序服务器并且它已经在接口0.0.0.0 上绑定了端口443,在这种情况下用作通配符,这意味着“在我的计算机上的所有接口上侦听端口443” 那么任何其他应用程序都不能使用这个端口,因为它已经被占用了。在您的 nginx 配置中,您可以看到表示它也想使用端口 443 的行:

    server {
        listen              443 ssl;  #<--- this is port config
        server_name localhost;
    

    您有(至少)2 个选项来修复该错误:

    • 在您的本地应用程序中更改 PORT=443
    • 将 nginx 配置中的端口号更改为任何其他未占用的行

    Next - location / { ... } 表示从 / 开始的所有请求(实际上是除了在前两个 location 块中捕获的请求之外的所有请求)将被转发到位于 https://localhost/ 的另一个 Web 服务器,并带有一些额外的标头.这称为反向代理

    【讨论】:

    • 我不想在我的应用程序中更改PORT=443,因为我想始终在https://localhost/... 下运行应用程序(包括重定向)。我尝试将listen 444 ssl; 放入 nginx 配置文件中。 Nginx 可以启动,https://localhost/#/start 工作。但是,https://localhost/auth/... 无法像以前那样重定向;我不得不使用https://localhost:444/auth/... 来让反向代理工作。
    • 那么是的,那行不通。尽管如此,回答你的问题为什么它不起作用仍然成立。只有我能建议的是将您的应用程序的端口更改为其他端口,例如 4433 并将 nginx 中反向代理的配置更改为 proxy_pass https://localhost:4433/;
    猜你喜欢
    • 1970-01-01
    • 2013-09-15
    • 1970-01-01
    • 1970-01-01
    • 2017-03-23
    • 1970-01-01
    • 1970-01-01
    • 2020-01-26
    • 1970-01-01
    相关资源
    最近更新 更多