详细说明 Node.js 不同版本的 SSL 配置方法,包括原生 HTTPS 和 Express.js 框架的配置
| Node.js 版本 | 状态 | TLS 1.2 | TLS 1.3 | OpenSSL 版本 | 推荐使用 |
|---|---|---|---|---|---|
| Node.js 12.x | 已弃用 | ✅ | ⚠️ 需配置 | 1.1.1 | ❌ |
| Node.js 14.x | 稳定 | ✅ | ✅ | 1.1.1 | ✅ |
| Node.js 16.x | 稳定 | ✅ | ✅ | 1.1.1 | ✅ |
| Node.js 18.x | LTS | ✅ | ✅ | 3.0.x | ✅ 推荐 |
| Node.js 20.x | LTS | ✅ | ✅ | 3.0.x | ✅ |
Node.js 可以直接使用 .crt 和 .key 文件,也可以使用合并后的证书链文件。
# # 合并主证书和中间证书cat your_domain.crt intermediate_ca.crt > fullchain.crt
# # 确保私钥文件存在# your_domain.key
# # 设置私钥文件权限(仅所有者可读)chmod 600 your_domain.key
# # 设置证书文件权限chmod 644 fullchain.crt
const https = require('https');
const fs = require('fs');
const options = {
key: fs.readFileSync('/path/to/your_domain.key'),
cert: fs.readFileSync('/path/to/fullchain.crt')
};
const server = https.createServer(options, (req, res) => {
res.writeHead(200);
res.end('Hello HTTPS!');
});
server.listen(443, () => {
console.log('HTTPS server running on port 443');
});
const https = require('https');
const fs = require('fs');
const options = {
key: fs.readFileSync('/path/to/your_domain.key'),
cert: fs.readFileSync('/path/to/your_domain.crt'),
ca: [
fs.readFileSync('/path/to/intermediate_ca.crt'),
fs.readFileSync('/path/to/root_ca.crt')
]
};
const server = https.createServer(options, (req, res) => {
res.writeHead(200);
res.end('Hello HTTPS!');
});
server.listen(443);
key:key:私钥文件路径cert:cert:证书文件路径(可以是合并后的 fullchain.crt)ca:ca:中间证书数组(可选,如果 cert 已包含完整链则不需要)const express = require('express');
const https = require('https');
const fs = require('fs');
const app = express();
app.get('/', (req, res) => {
res.send('Hello HTTPS!');
});
const options = {
key: fs.readFileSync('/path/to/your_domain.key'),
cert: fs.readFileSync('/path/to/fullchain.crt')
};
https.createServer(options, app).listen(443, () => {
console.log('Express HTTPS server running on port 443');
});
const express = require('express');
const http = require('http');
const https = require('https');
const fs = require('fs');
const app = express();
app.get('/', (req, res) => {
res.send('Hello!');
});
// HTTP 服务器(重定向到 HTTPS)
http.createServer((req, res) => {
res.writeHead(301, { "Location": "https://" + req.headers['host'] + req.url });
res.end();
}).listen(80);
// HTTPS 服务器
const options = {
key: fs.readFileSync('/path/to/your_domain.key'),
cert: fs.readFileSync('/path/to/fullchain.crt')
};
https.createServer(options, app).listen(443, () => {
console.log('HTTPS server running on port 443');
});
const https = require('https');
const fs = require('fs');
const options = {
key: fs.readFileSync('/path/to/your_domain.key'),
cert: fs.readFileSync('/path/to/fullchain.crt'),
secureProtocol: 'TLSv1_2_method', // 或 TLSv1_3_method
ciphers: 'ECDHE-RSA-AES128-GCM-SHA256:ECDHE-RSA-AES256-GCM-SHA384'
};
const server = https.createServer(options, (req, res) => {
res.writeHead(200);
res.end('Hello HTTPS!');
});
server.listen(443);
const https = require('https');
const fs = require('fs');
const options = {
key: fs.readFileSync('/path/to/your_domain.key'),
cert: fs.readFileSync('/path/to/fullchain.crt'),
minVersion: 'TLSv1.2',
maxVersion: 'TLSv1.3',
ciphers: 'TLS_AES_256_GCM_SHA384:TLS_AES_128_GCM_SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-RSA-AES256-GCM-SHA384'
};
const server = https.createServer(options, (req, res) => {
res.writeHead(200);
res.end('Hello HTTPS!');
});
server.listen(443);
const https = require('https');
const fs = require('fs');
const options = {
key: fs.readFileSync('/path/to/your_domain.key'),
cert: fs.readFileSync('/path/to/fullchain.crt'),
minVersion: 'TLSv1.2',
maxVersion: 'TLSv1.3',
ciphers: [
'TLS_AES_256_GCM_SHA384',
'TLS_AES_128_GCM_SHA256',
'ECDHE-RSA-AES128-GCM-SHA256',
'ECDHE-RSA-AES256-GCM-SHA384',
'ECDHE-RSA-CHACHA20-POLY1305'
].join(':'),
honorCipherOrder: true
};
const server = https.createServer(options, (req, res) => {
res.writeHead(200);
res.end('Hello HTTPS!');
});
server.listen(443);
const options = {
key: fs.readFileSync('/path/to/your_domain.key'),
cert: fs.readFileSync('/path/to/fullchain.crt'),
minVersion: 'TLSv1.2',
maxVersion: 'TLSv1.3'
};
const options = {
key: fs.readFileSync('/path/to/your_domain.key'),
cert: fs.readFileSync('/path/to/fullchain.crt'),
minVersion: 'TLSv1.2', // // 禁用 TLS 1.0 和 1.1 rejectUnauthorized: true // // 拒绝无效证书};
const options = {
key: fs.readFileSync('/path/to/your_domain.key'),
cert: fs.readFileSync('/path/to/fullchain.crt'),
minVersion: 'TLSv1.2',
maxVersion: 'TLSv1.3',
ciphers: [
'TLS_AES_256_GCM_SHA384', // // TLS 1.3 'TLS_AES_128_GCM_SHA256', // // TLS 1.3 'ECDHE-RSA-AES128-GCM-SHA256', // // TLS 1.2 'ECDHE-RSA-AES256-GCM-SHA384', // // TLS 1.2 'ECDHE-RSA-CHACHA20-POLY1305' // // TLS 1.2 ].join(':'),
honorCipherOrder: true
};
const express = require('express');
const app = express();
// // 强制 HTTPS 中间件app.use((req, res, next) => {
if (req.header('x-forwarded-proto') !== 'https') {
res.redirect(`https://${req.header('host')}${req.url}`);
} else {
next();
}
});
app.get('/', (req, res) => {
res.send('Hello HTTPS!');
});
// // 检查协议(适用于反向代理)app.listen(3000);
const express = require('express');
const enforce = require('express-enforces-ssl');
const app = express();
// 强制 HTTPS
app.use(enforce());
app.get('/', (req, res) => {
res.send('Hello HTTPS!');
});
app.listen(3000);
const http = require('http');
const https = require('https');
const fs = require('fs');
// HTTP 服务器(重定向)
http.createServer((req, res) => {
res.writeHead(301, {
'Location': 'https://' + req.headers['host'] + req.url
});
res.end();
}).listen(80);
// HTTPS 服务器
const options = {
key: fs.readFileSync('/path/to/your_domain.key'),
cert: fs.readFileSync('/path/to/fullchain.crt')
};
https.createServer(options, (req, res) => {
res.writeHead(200);
res.end('Hello HTTPS!');
}).listen(443);
const https = require('https');
const fs = require('fs');
const express = require('express');
const app = express();
// // 安全头设置app.use((req, res, next) => {
res.setHeader('Strict-Transport-Security', 'max-age=31536000; includeSubDomains');
res.setHeader('X-Content-Type-Options', 'nosniff');
res.setHeader('X-Frame-Options', 'DENY');
res.setHeader('X-XSS-Protection', '1; mode=block');
next();
});
app.get('/', (req, res) => {
res.send('Hello HTTPS!');
});
const options = {
key: fs.readFileSync(process.env.SSL_KEY_PATH || '/etc/ssl/private/your_domain.key'),
cert: fs.readFileSync(process.env.SSL_CERT_PATH || '/etc/ssl/certs/fullchain.crt'),
minVersion: 'TLSv1.2',
maxVersion: 'TLSv1.3',
ciphers: [
'TLS_AES_256_GCM_SHA384',
'TLS_AES_128_GCM_SHA256',
'ECDHE-RSA-AES128-GCM-SHA256',
'ECDHE-RSA-AES256-GCM-SHA384',
'ECDHE-RSA-CHACHA20-POLY1305'
].join(':'),
honorCipherOrder: true
};
https.createServer(options, app).listen(443, () => {
console.log('HTTPS server running on port 443');
});
错误: 错误信息:Error: ENOENT: no such file or directory
解决:
错误: 错误信息:Error: listen EADDRINUSE: address already in use :::443
解决:
错误: 错误信息:Error: SSL routines:ssl3_read_bytes:sslv3 alert handshake failure
解决:
错误: 错误信息:Error: listen EACCES: permission denied
解决:
解决: 问题:浏览器显示证书警告,提示证书链不完整
解决: