首页 > 解决方案 > 如何让 SSL 与非 ssl 协议数据配合得很好

问题描述

简短的背景:如果我们回到 2006 年左右:我们(即:我的公司)使用嵌入在浏览器中的 java 客户端应用程序,该应用程序通过端口 443 连接到在内部端口 8068 上运行的 C 程序后端服务器。在第一次开发 java 应用程序时,端口 443 是我们知道不会被使用该软件的客户阻止的唯一端口(易于安装并且可能客户内部人员没有电源或控制其内部防火墙的知识)。

快进到 2016 年,我受雇帮助开发该 Java 应用程序的 NodeJS/Javascript 版本。Java 应用程序在其替代产品的开发过程中继续使用,但是糟糕——我们了解到浏览器将在不久的将来放弃对嵌入式 Java 的支持。所以我们切换到Java Web Start,这样客户可以继续下载应用程序,它仍然通过端口443->8068路由连接到内部服务器。

2017 年即将到来,你不知道吗,我们不能同时使用即将推出的带有 HTTPS/SSL 的 JS 网络应用程序和 Java 应用程序,因为它们使用相同的端口。“好吧,让我们用 NGINX 来解决这个问题。” 但是由于内部政治、客户需求和网络开发人员的更替,我们从来没有抽出时间真正做到这一点。

所以我们到了 2020 年,准备部署新的 Web 版本的客户端软件,而整个 443 的烂摊子又重新抬头了。

本质上,我希望允许(暂时)Java 应用程序继续使用 443,但现在需要让 Web 应用程序也使用 HTTPS。早在 2017/2018 年,我们在 Google 上搜索了通过 NGINX 让它们同居的方法,但我们从未真正让它们正常工作,或者示例和教程不完整或令人困惑。似乎我们需要按照https://www.nginx.com/blog/running-non-ssl-protocols-over-ssl-port-nginx-1-15-2/的方式使用流式传输,或者查看在传入的 HTTPS 标头处,并if (https) { route to nodeJS server } else { assume it must be the java app and route to port 8068 }在 NGINX 配置文件中进行 ' ' 排序。

过去的 Google 链接似乎不再存在,所以如果有人知道 NGINX 配置允许 HTTPS 网站移交给仍需要使用 443 的非 SSL 应用程序,我将不胜感激。任何为我们指明正确方向的文档和/或教程也会有所帮助。提前致谢!

标签: node.jssslnginxhttpsjava-web-start

解决方案


您可以使用ssl_preread选项执行此操作。基本上,此选项将允许访问变量$ssl_preread_protocol,其中包含在 SSL 端口协商的协议。如果未检测到有效协议,则该变量将为空。

使用此参数,您可以对您的环境使用以下配置:

stream {
    upstream java {
        server __your_java_server_ip__:8068;
    }

    upstream nodejs {
        server __your_node_js_server_ip__:443;
    }

    map $ssl_preread_protocol $upstream {
        default java;
        "TLSv1.2" nodejs;
    }

    server {
        listen 443;

        proxy_pass $upstream;
        ssl_preread on;
    }
}

在您的情况下,此配置会将连接直接传递到您的 nodejs 和 java 后端服务器,因此 nodejs 将需要协商 SSL。您可以使用另一个服务器上下文将这项工作传递给 NGiNX,例如:

stream {
    upstream java {
        server __your_java_server_ip__:8068;
    }

    upstream nodejs {
        server 127.0.0.1:444;
    }

    map $ssl_preread_protocol $upstream {
        default java;
        "TLSv1.2" nodejs;
    }

    server {
        listen 443;

        proxy_pass $upstream;
        ssl_preread on;
    }
}

http {
    server {
        listen 444 ssl;
        __your_ssl_cert_configurations_here__

        location / {
            proxy_pass http://__your_nodejs_server_ip__:80;
        }
    }
}

您需要 NGiNX 至少 1.15.2 版才能使用此配置,并使用ngx_stream_ssl_preread_module模块编译(需要使用--with-stream_ssl_preread_module配置参数编译,因为默认情况下不构建此模块)。

来源:https ://www.nginx.com/blog/running-non-ssl-protocols-over-ssl-port-nginx-1-15-2/


推荐阅读