【问题标题】:Hosting multiple node.js sites with SSL使用 SSL 托管多个 node.js 站点
【发布时间】:2015-11-11 02:04:22
【问题描述】:

我们正在研究使用 node.js 在我们的网络服务器上托管多个网站。目前,我们在 IIS 中托管所有内容,使用域名来区分网站,并使用 URL 重写从 HTTP 到 HTTPS。

根据我的阅读,nginx 似乎是在同一台服务器上托管多个节点应用程序的方式:本质上 nginx 是所有客户端连接到的外观,然后它将请求发送到各个节点进程,具体取决于在主机名上。

但我无法理解的是 SSL 部分。 Node.js 提供 SSL 功能,但 nginx 也提供。如果 nginx 托管 SSL 证书,并监听 443,并将请求转发到各种 node.js 应用程序,那么 node.js 应用程序是否也必须运行 SSL 证书?这样做有什么安全损失吗?还是使用 https 运行每个 node js 应用程序,然后在 node.js 应用程序内部执行 http 到 https 并一直传递到 nginx 并返回更好?

【问题讨论】:

    标签: node.js ssl nginx https


    【解决方案1】:

    您只需要在 NGINX 中使用 SSL 证书。此外,NGINX 可用作 Node.js 服务器的负载均衡器,而且非常易于配置。

    将所有 http 流量重定向到 https 也非常简单。

    从我的服务器检查以下配置文件。我加了cmets,希望通俗易懂:

    http {
    
        # ......    
        # add proxy, gzip and other http settings here //
        # ......    
    
        # running node.js servers for nginx proxy - servers are choosen randomly and can be used as load balancers
        # You can add as many servers as you want or just use one, but all servers must be running same script
        # if you want to add servers with different script, just add new upstream and link it to other location in server settings
        upstream example_com {
          server 127.0.0.1:3000;
          server 127.0.0.1:3001;
          keepalive 64;
        }
    
        # listen http on port 80 and redirect all requested urls to https server
        server {
               listen 80;
               server_name example.com www.example.com;
               return 301 https://$server_name$request_uri;
        }
    
        # listen https on port 443 and proxy Node.js servers
        server {
            listen 443 ssl;
    
            # SSL Certificate settings
            ssl_certificate /ssl_cert/location/example.com.bundle.crt;
            ssl_certificate_key /ssl_cert/location/example.com.key;
            ssl_protocols SSLv3 TLSv1;
            ssl_ciphers HIGH:!aNULL:!MD5;
    
            server_name example.com www.example.com;
    
            # ......
            # add location, rewrite, error handling, public folders for static files served from directly NGINX and other settings here
            # ......
    
            # redirect traffic to Node.js servers.
            location / {
              proxy_redirect off;
              # Proxy original headers to Node.js
              # for example if you want to get client IP address from Node.js, there is no way without redirecting headers from NGINX
              proxy_set_header X-Real-IP $remote_addr;
              proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
              proxy_set_header X-Forwarded-Proto $scheme;
              proxy_set_header Host $http_host;
              proxy_set_header X-NginX-Proxy true;
              proxy_set_header Connection "";
              proxy_http_version 1.1;
              # Add comment (#) to "proxy_cache one;" and "proxy_cache_key sfs$request_uri$scheme;" if you want to serve files more than 2MB from Node.js
              proxy_cache one;
              proxy_cache_key sfs$request_uri$scheme;
              # upstream name with Node.js servers in it
              # no need to install SSL for Node.js, you can use http:// between NGINX and Node.js, all traffic to client will be encrypted by NGINX anyway
              proxy_pass http://example_com;
            }
        }
    }
    

    要在同一域下使用多个应用,请使用上面的配置文件,只需为其他应用添加 upstreamlocation

    http {
    
        # ..........
    
        upstream example_com {
          server 127.0.0.1:3000;
          server 127.0.0.1:3001;
          keepalive 64;
        }
    
        upstream example_com_second_app {
          server 127.0.0.1:3002;
          server 127.0.0.1:3003;
          keepalive 64;
        }
    
    
        # ..........
    
        server {
    
            # ..........
    
            location / {
    
              # ..........
    
              proxy_pass http://example_com;
            }
    
            location /second_app/ {
    
              # ..........
    
              proxy_pass http://example_com_second_app;
            }
        }
    }
    

    要在同一台服务器上使用不同的域和 SSL 证书,您可以使用相同的配置并添加具有不同 server_name

    的另一台服务器
    http {
    
        # ..........
    
        # Configure server for example.com
        server {
               listen 80;
               server_name example.com www.example.com;
               return 301 https://$server_name$request_uri;
        }
    
        server {
            listen 443 ssl;
    
            # SSL Certificate settings
            ssl_certificate /ssl_cert/location/example.com.bundle.crt;
            ssl_certificate_key /ssl_cert/location/example.com.key;
            ssl_protocols SSLv3 TLSv1;
            ssl_ciphers HIGH:!aNULL:!MD5;
    
            server_name example.com www.example.com;
    
            # ..........     
        }
    
        # Configure server for my_example.com
        server {
               listen 80;
               server_name my_example.com www.my_example.com;
               return 301 https://$server_name$request_uri;
        }
    
        server {
            listen 443 ssl;
    
            # SSL Certificate settings
            ssl_certificate /ssl_cert/location/my_example.com.bundle.crt;
            ssl_certificate_key /ssl_cert/location/my_example.com.key;
            ssl_protocols SSLv3 TLSv1;
            ssl_ciphers HIGH:!aNULL:!MD5;
    
            server_name my_example.com www.my_example.com;
    
            # ..........     
        }
    }
    

    您甚至可以为不同的域使用相同的上游

    NGINX 真的很酷、免费、最快且易于配置:)

    【讨论】:

      【解决方案2】:

      node.js 应用程序是否也必须运行 SSL 证书?

      不,node.js 应用程序可以提供明文 HTTP。

      通常它是从浏览器/客户端到 nginx 的 HTTPS,然后是从 nginx 到 node.js 应用程序服务器的 HTTP。因此,nginx 在架构术语中既是反向代理,又是“TLS 终结者”。

      出于维护开销和性能原因,大多数部署不会从 nginx 运行 HTTPS 到同一数据中心/VPC 中的节点应用服务器,但如果您担心该跃点的额外安全性并且您可以处理,您当然可以这样做证书管理等。但根据我所见,这样的设置非常罕见。

      【讨论】:

        【解决方案3】:

        您最好的选择是让 Nginx 进行 SSL 终止。这意味着传入的请求首先在端口 443 上到达 Nginx 实例,然后 Nginx 将它们转发到端口 80 上的上游 Node.JS 服务器,或者可能是您的应用程序使用的其他一些非特权端口。

        一般来说,Node.JS 不擅长处理 CPU 密集型任务。不幸的是,几乎任何形式的加密都将受 CPU 限制,这意味着当您将 SSL 处理从 Node 转移到 Nginx 时,您可能会看到更好的基准。但是,如果您担心有人监视您在 Nginx 和 Node 之间的流量,您可能仍希望在 Node 接口上使用 SSL。

        这是一个用于监听 HTTP 和 HTTPS 请求的 Nginx 配置,它充当 Node 进程的反向代理,同时还支持 websocket。它侦听端口 80 和 443,对 HTTPS 请求执行 SSL 终止,并将所有流量转发到同一主机上的端口 8000。

        上游示例 { # 你的 Node 应用程序的主机和端口属于这里 服务器 127.0.0.1:8000; } 服务器 { 听 80; # 所有主机名都应该在这里定义 server_name example.com www.example.com # 你可能需要创建 /var/log/nginx access_log /var/log/nginx/example.access.log; 错误日志/var/log/nginx/example.error.log; # 防止 502 bad gateway 错误 large_client_header_buffers 8 32k; 地点 / { proxy_next_upstream 错误超时 invalid_header http_500 http_502 http_503 http_504; proxy_set_header Accept-Encoding ""; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header X-NginX-Proxy 真; proxy_http_version 1.1; proxy_set_header 升级 $http_upgrade; proxy_set_header 连接“升级”; proxy_set_header 主机 $host; proxy_buffers 8 32k; proxy_buffer_size 64k; proxy_set_header X-Forwarded-Proto $scheme; proxy_pass http://example; 代理重定向关闭; } } 服务器 { 听 443 ssl; # 所有主机名都应该在这里定义 server_name example.com www.example.com # 你可能需要创建 /var/log/nginx access_log /var/log/nginx/example.access.log; 错误日志/var/log/nginx/example.error.log; ssl_certificate /path/to/example.com.crt; ssl_certificate_key /path/to/example.com.key; ssl_protocols TLSv1 TLSv1.1 TLSv1.2; ssl_ciphers RC4:HIGH:!aNULL:!MD5; ssl_prefer_server_ciphers 开启; keepalive_timeout 60; ssl_session_cache 共享:SSL:10m; ssl_session_timeout 10m; # 防止 502 bad gateway 错误 large_client_header_buffers 8 32k; 地点 / { proxy_next_upstream 错误超时 invalid_header http_500 http_502 http_503 http_504; proxy_set_header Accept-Encoding ""; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header X-NginX-Proxy 真; proxy_http_version 1.1; proxy_set_header 升级 $http_upgrade; proxy_set_header 连接“升级”; proxy_set_header 主机 $host; proxy_buffers 8 32k; proxy_buffer_size 64k; proxy_set_header X-Forwarded-Proto $scheme; proxy_pass http://example; 代理重定向关闭; } }

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2014-08-13
          • 2015-10-11
          • 1970-01-01
          • 2012-05-10
          • 2011-05-02
          • 2011-04-09
          • 1970-01-01
          • 2012-02-11
          相关资源
          最近更新 更多