node.js - 使用 SSL 托管多个 node.js 站点

标签 node.js ssl nginx https

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

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

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

最佳答案

您只需要在 NGINX 中使用 SSL 证书。此外,NGINX 还可以用作 Node.js 服务器的负载均衡器,而且配置极其简单。

将所有 http 流量重定向到 https 也非常容易。

从我的服务器检查以下配置文件。我添加评论并希望它易于理解:

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 真的很酷、免费、最快且易于配置:)

关于node.js - 使用 SSL 托管多个 node.js 站点,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33635018/

相关文章:

macos - 服务 'nginx'无法构建:…只读文件系统

ssl - 绑定(bind)站点 ssl 后出现 ERR_CONNECTION_REFUSED,为什么?

ssl - 如何使用 Lets Encrypt 为子域添加证书

nginx 和星号 server_name?

node.js - 具有匹配模式的 ioredis key

java - 使用现有的中间 CA key 和证书与 keytool 生成客户端证书

php - 无法使用带 SSL 的 php CURL 获取图像

node.js - 在 Mono 存储库中 Docker 化多个微服务

mysql - 环回应用程序错误 ERR_ABORTED 404(未找到)

javascript - 如何将lite-server用于nodejs应用程序?