我有一个正在运行的 Node 应用程序,该应用程序在 http 和 https 上正常运行。
我设置了 Nginx,它也运行良好,用 sshtunnel 测试,并且它从静态文件(例如 MyPath/index.html)获得了正确的响应。
但是,我尝试让 Nginx 充当 Node 的反向代理。因为我想在我的机器上创建另一个应用程序,并且 Nginx 应该对每个应用程序的传入请求进行排序。
但是 Nginx 似乎有一个我无法弄清楚的问题。我怀疑这是一个配置问题。当我尝试通过 localhost 上的 SSH 隧道访问我的 Node 应用程序时,我总是从浏览器获取一个错误页面,而不是获取网页,内容如下:
此站点无法提供安全连接localhost 发送了无效响应。ERR_SSL_PROTOCOL_ERROR。
当我尝试从 WAN 访问它时,它就超时了。
Nginx 配置
server {
listen [::]:4444 default_server;
server_name localhost mysite.com www.mysite.com;
access_log /home/mysite/access-log;
location / {
proxy_pass http://127.0.0.1:5555;
}
}
我尝试改变http://127.0.0.1:5555到https://127.0.0.1:6666但这并没有改变什么。
节点应用程序
const port = 5555;
const secureport = 6666;
...
const privateKey = fs.readFileSync('PATHTOCERT');
const certificate = fs.readFileSync('PATHTOKEY');
const credentials = {key: privateKey, cert: certificate};
... 我在这里使用了一个 express 应用实例,还配置了头盔的 CSP。但我不认为这是问题所在,因为我禁用了头盔,但这并没有解决任何问题。...
const httpServer = http.createServer(app);
const httpsServer = https.createServer(credentials, app);
httpServer.listen(port);
httpsServer.listen(secureport);
答案1
我找到了问题所在。问题在于 SSL 证书始终无效,因为域名“localhost”或 IP 地址 (MyIP) 显然与证书记录不匹配。我不得不将其放在我的“实时服务器”上以检查它是否有效(有点信心十足)。:-)
我现在已使用 Nginx 中的以下配置来工作。
/etc/nginx/nginx.conf
#user www-data;
user $nginxuser $nginxusergroup;
worker_processes auto;
#pid run/nginx.pid
include /etc/nginx/modules-enabled/*.conf;
为了提高安全性,我更改了 Nginx 工作进程的用户。我本来想用没有 root 权限的用户完全运行 Nginx,但这样会引发几个错误。我稍后会研究这个问题。更改用户后,我还必须注释掉 pid 指令,因为它会带来问题。主配置文件的其余部分未受影响,除了日志位置。
对于 HTTPS:
/etc/nginx/sites-available/mysite-ssl
(使用从 sites-enabled 到该文件的符号链接)
server {
# Ports
listen 4444 ssl http2 default_server;
listen [::]:4444 ssl http2 default_server;
# Server name
server_name localhost example.com www.example.com;
# SSL
ssl_certificate /mypath/fullchain.pem;
ssl_certificate_key /mypath/privkey.pem;
# Logs
access_log /mypath/access.log;
error_log /mypath/ssl-error.log;
location / {
proxy_pass https://127.0.0.1:6666;
proxy_redirect https://127.0.0.1:6666 https://www.example.com;
proxy_set_header Host $host;
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 true;
}
}
对于 HTTP:
/etc/nginx/sites-available/mysite
(使用从 sites-enabled 到该文件的符号链接)
server {
# Ports
listen 3333 default_server;
listen [::]:3333 default_server;
# Server name
server_name localhost example.com www.example.com;
# Logs
access_log /mypath/access.log;
error_log /mypath/error.log;
location / {
proxy_pass http://127.0.0.1:5555;
proxy_redirect http://127.0.0.1:5555 http://www.example.com;
proxy_set_header Host $host;
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 true;
}
}
我的节点应用程序具有以下(未改变的)配置:
const port = 5555;
const secureport = 6666;
...
const privateKey = fs.readFileSync('PATHTOCERT');
const certificate = fs.readFileSync('PATHTOKEY');
const credentials = {key: privateKey, cert: certificate};
...
这部分将 Node 内部的 http 重定向到 https:
app.use(function (req, res, next) {
if(!req.secure) {
return res.redirect(301, ['https://', req.get('Host'), req.url].join(''));
}
next();
});
... 一款由 Express 驱动的应用程序 ...
const httpServer = http.createServer(app);
const httpsServer = https.createServer(credentials, app);
httpServer.listen(port);
httpsServer.listen(secureport);
重新启动节点和 nginx 服务后,此设置在 https 和 http 上对我有效。