为 Express 和 Nginx 配置 HTTPS

问题描述 投票:0回答:3

我正在尝试配置我的 ExpressJS 应用程序以进行 https 连接。 Express 服务器运行在 localhost:8080,安全服务器运行在 localhost:8443。

这里是与https相关的server.js代码:

var app = express();

var https = require('https');

const options = {
    cert: fs.readFileSync('/etc/letsencrypt/live/fire.mydomain.me/fullchain.pem'),
    key: fs.readFileSync('/etc/letsencrypt/live/fire.mydomain.me/privkey.pem')
};

app.listen(8080, console.log("Server running"));
https.createServer(options, app).listen(8443, console.log("Secure server running on port 8443"));

这是我的 Nginx 配置:

server {
    listen 80;
    listen [::]:80;
    server_name fire.mydomain.me;

    location / {
        proxy_pass http://localhost:8080;
        proxy_http_version 1.1;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection 'upgrade';
        proxy_set_header Host $host;
        proxy_cache_bypass $http_upgrade;
    }
}

server {
    listen 443;
    listen [::]:443;
    server_name fire.mydomain.me;
    location / {
        proxy_pass https://localhost:8443;
        proxy_http_version 1.1;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection 'upgrade';
        proxy_set_header Host $host;
        proxy_cache_bypass $http_upgrade;
    }
}

我做了什么:

  • 使用 Letsencrypt certonly 工具为域 fire.mydomain.me 生成 SSL 证书。
  • 配置 nginx。
  • 配置 server.js 节点应用程序。
  • 在 Ufw 中添加 443 端口的 TCP 规则。

我试过了

  • 注释 server.js 中的 not-ssl 服务器行以强制连接通过 ssl 配置:当我尝试访问 fire.mydomain.me:443 但不访问“https:// fire.mydomain.me:443”时,这将提供页面服务。 mydomain.me”。在这两种情况下,都没有 SSL。尝试访问 https://fire.mydomain.me 会在 Google Chrome 中生成此消息“此网站不提供安全连接”。

  • 我首先按照本教程设置我的 ssl 节点配置: https://medium.com/@yash.kulshrestha/using-lets-encrypt-with-express-e069c7abe625#.93jgjlgsc

javascript node.js ssl nginx https
3个回答
57
投票

您不需要在同一主机上运行的 nginx 反向代理和 Node 应用程序之间使用 HTTPS。您可以将对端口 80 的 HTTP 请求和对端口 443 的 HTTPS 请求代理到 Node 应用程序中的同一端口(本例中为 8080),并且在这种情况下您不需要配置 TLS 证书。

您可以将 server.js 文件更改为:

var app = express();

app.listen(8080, console.log("Server running"));

并使用具有

proxy_pass http://localhost:8080;
的 nginx 配置,用于端口 80 上的 HTTP 和端口 443 上的 HTTPS。

这就是通常的做法。加密环回接口上的流量不会增加任何安全性,因为要嗅探流量,您需要对盒子进行根访问,并且当您拥有它时,您就可以读取证书并解密流量。考虑到 https://nodejs.org/en/blog/vulnerability/ 上的大多数帖子都与 OpenSSL 相关,有人可能会说,在 Node 中使用 SSL 在加密环回的特定情况下会降低其安全性接口流量。有关更多信息,请参阅 GitHub 上 Node 项目的此讨论


22
投票

感谢@rsp解决方案,这里是工作的Nginx配置:

server {
listen 80;
listen 443 ssl;

server_name fire.mydomain.me;

ssl_certificate     /etc/letsencrypt/live/fire.mydomain.me/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/fire.mydomain.me/privkey.pem;

location / {
    proxy_pass http://localhost:8080;
    proxy_http_version 1.1;
    proxy_set_header Upgrade $http_upgrade;
    proxy_set_header Connection 'upgrade';
    proxy_set_header Host $host;
    proxy_cache_bypass $http_upgrade;
   }
}

0
投票

为 HTTPS(端口 443)设置 Nginx 反向代理而苦苦挣扎

你好,社区!

我已经为这个问题苦苦挣扎了近两周,需要一些帮助。我在我的服务器上托管一个简单的应用程序来在线测试它。为了正确设置它,我决定使用 Nginx 作为我的 Node.js 应用程序的反向代理


目标

我希望能够使用 HTTPS(端口 443) 连接到我的应用程序,而无需在 URL 中指定任何端口。目前,我可以通过不同端口(例如 8080 或 443)连接到服务器,但我始终需要显式包含端口号。我想让这一切变得无缝并按 HTTPS 的预期工作。


我尝试过的事情

  1. 网络配置:

    • 我已经在路由器上打开了必要的端口:
      Public 80 -> Private 80
      Public 443 -> Private 443
      Public 8080 -> Private 8080
      
      端口转发配置示例:
      Public   Private   Protocol
      80-80    80-80     TCP
      443-443  443-443   TCP
      8080-8080 8080-8080 TCP
      
  2. Node.js Express 服务器:

    • 我的 Express 应用程序设置为侦听 端口 8080
    • 这是我的
      server/index.js
      文件:
      const express = require('express');
      const routes = require('./routes');
      const path = require('path');
      const app = express();
      
      const httpPort = 8080; // Port to listen for HTTP
      
      // Middleware for processing JSON data
      app.use(express.json());
      
      // API routes
      app.use('/api', routes);
      
      // Static files served by Vue.js
      app.use(express.static(path.join(__dirname, "../client", "dist")));
      
      // Error handling for static files
      app.use((err, req, res, next) => {
          res.status(500).send('Something went wrong!');
      });
      
      // Vue.js default route
      app.get('*', (req, res) => {
          res.sendFile(path.join(__dirname, "../client", "dist", "index.html"));
      });
      
      // Start the HTTP server
      app.listen(httpPort, () => {
          console.log(`Server running on http://localhost:${httpPort}`);
      });
      
  3. Nginx 配置:

    • 我的 Nginx 配置为:
      • 监听 HTTP 的 端口 80 并将其重定向到 HTTPS 的端口 443
      • 使用 端口 443 进行 SSL,并在 端口 8080 上反向代理到我的 Node.js 应用程序。
    • 这是我的 Nginx 配置:
      server {
          listen 80;
          server_name MY_SERVER_NAME;
      
          # Redirect HTTP to HTTPS
          return 301 https://$host$request_uri;
      }
      
      server {
          listen 443 ssl;
          server_name MY_SERVER_NAME;
      
          # SSL certificates (Let's Encrypt or your own certs)
          ssl_certificate /home/<user>/certificates/fullchain.pem;
          ssl_certificate_key /home/<user>/certificates/privkey.pem;
      
          # Configure the proxy to pass traffic to Node.js (HTTP)
          location / {
              proxy_pass http://localhost:8080;
              proxy_http_version 1.1;
              proxy_set_header Upgrade $http_upgrade;
              proxy_set_header Connection 'upgrade';
              proxy_set_header Host $host;
              proxy_cache_bypass $http_upgrade;
          }
      }
      
  4. 防火墙规则(UFW):

    • 我已确保允许所有相关端口:
      To      Action    From
      443/tcp ALLOW     Anywhere
      80/tcp  ALLOW     Anywhere
      8080/tcp ALLOW    Anywhere
      
  5. 检查插座:

    • 当我启动 Node.js 服务器并使用
      ss -tuln
      检查活动套接字时,我可以看到:
      tcp   LISTEN   0   511    0.0.0.0:443    0.0.0.0:*
      tcp   LISTEN   0   511       *:8080       *:*
      

问题

尽管如此,我仍无法通过 HTTPS(端口 443) 无缝连接到我的应用程序。我仍然需要在 URL 中手动指定端口才能使连接正常工作。


我错过了什么?

  1. 我的 Nginx 配置或 Node.js 设置有问题吗?
  2. 这可能是我处理 SSL 或反向代理的方式有问题吗?
  3. 我是否忽略了网络或防火墙设置中的某些内容?

预先感谢您的帮助!任何见解将不胜感激。


© www.soinside.com 2019 - 2024. All rights reserved.