且构网

分享程序员开发的那些事...
且构网 - 分享程序员编程开发的那些事

为 Express 和 Nginx 配置 HTTPS

更新时间:2022-12-06 12:42:33

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

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

var app = express();app.listen(8080, console.log("服务器运行"));

并使用具有 proxy_pass http://localhost:8080; 的 nginx 配置,用于端口 80 上的 HTTP 和端口 443 上的 HTTPS.

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

I am trying to configure my ExpressJS app for https connection. The Express server runs at localhost:8080 and the secure one localhost:8443.

Here is the server.js code related to https:

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"));

And here is my Nginx configuration:

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;
    }
}

What I did :

  • Generating SSL certificate with Letsencrypt certonly tool for the domain fire.mydomain.me.
  • Configuring nginx.
  • Configuring the server.js node app.
  • Adding TCP rules for the 443 port in Ufw.

I tried

  • Commenting the not-ssl server line in server.js to force the connections to go through ssl configuration: this serve the page when I try to go to fire.mydomain.me:443 but not to "https:// fire.mydomain.me". In both cases, no SSL. Trying to go to https:// fire.mydomain.me generate this message "This website doensn't provide a secure connection" in Google Chrome.

  • I followed this tutorial in the first place to set my ssl node config : https://medium.com/@yash.kulshrestha/using-lets-encrypt-with-express-e069c7abe625#.93jgjlgsc

You don't need to use HTTPS between your nginx reverse proxy and Node app running on the same host. You can proxy both HTTP requests to port 80 and HTTPS requests to port 443 to the same port in your Node app - 8080 in this case - and you don't need to configure TLS certificates in that case.

You can change your server.js file to:

var app = express();

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

and use an nginx config that has proxy_pass http://localhost:8080; for both HTTP on port 80 and HTTPS on port 443.

This is how it is usually done. Encrypting traffic on the loopback interface doesn't add any security because to sniff the traffic you need root access to the box and when you have it then you can read the certs and decrypt the traffic anyway. Considering the fact that most of the posts on https://nodejs.org/en/blog/vulnerability/ are related to OpenSSL, one could argue that using SSL in Node can make it less secure in that particular case of encrypting loopback interface traffic. See this discussion on the Node project on GitHub for more info.