我正在尝试在 VPS (Debian 12) 上建立一个带有联系表的网站。 Nnginx 在domain.com 上提供静态文件,并将联系表单POST 到form.domain.com,这由使用nodemailer 的节点/express 服务器处理。
我在 http 中完成了所有工作,Nginx 在端口 80 上侦听,并在端口 3000 上对 form.domain.com 的节点执行 proxy_pass。但后来我尝试使用 certbot 安装 ssl,它破坏了形式。
我修复了 http/https 和 Nginx 传递给 Node 的 proxy_pass 问题,但该解决方案意味着 Node 必须使用 SSL 证书,这就是我遇到 Node 无法读取证书文件的问题的地方,即显然是一个已知问题。
基本上,我的问题是:正确的方法是什么?
---到目前为止我尝试过的---
在通过 Certbot 安装 SSL 之前,在努力让子域 proxy_pass 正常工作时,我对 Nginx .conf 文件进行了一些修改。最初,我尝试了 nginx.conf 中一个服务器块的变体,大致如下:
server {
listen 80 default_server;
server_name domain.com;
location / {
root /data/www;
index index.html;
}
location /form/ {
proxy_pass http://012.345.678.99:3000;
}
结果:没有代理通行证... 最后,我放弃了domain.com/form,改用form.domain.com,注释掉所有服务器块,删除/etc/nginx/*-enabled/中的所有链接,并在/etc中添加2个新文件/nginx/conf.d/ -- 域.conf:
server {
listen 80;
server_name domain.com;
location / {
root /data/www;
index index.html;
}
}
-- 和 form.conf:
server {
listen 80;
server_name form.domain.com;
location / {
proxy_pass http://012.345.678.99:3000;
}
}
结果:代理通行证有效,端口 3000 上的节点服务器获取表单数据,电子邮件有效,一切正常,耶!只是没有 ssl。
然后我安装了 snap,安装了 Certbot,做了
sudo certbot --nginx
并选择仅针对 domain.com 安装。结果:https 在domain.com 上有效,静态站点仍然有效,但现在提交联系表单会导致 Nginx 错误(我忘记最初是 404 还是 502)。
好吧,长话短说(呃):我为 form.domain.com 安装了 SSL,将所有 http 链接更改为 https,并以某种方式让 Nginx proxy_pass 工作,以便表单提交数据到达 Node,但是 Node /Express 代码必须更新才能使用 SSL 证书。看起来我正在跌跌撞撞地寻找解决方案,其变化如下:
const privateKey = fs.readFileSync('/etc/letsencrypt/live/form.domain.com/privkey.pem', 'utf8');
const certificate = fs.readFileSync('/etc/letsencrypt/live/form.domain.com/cert.pem', 'utf8');
const ca = fs.readFileSync('/etc/letsencrypt/live/form.domain.com/chain.pem', 'utf8');
const credentials = {
key: privateKey,
cert: certificate,
ca: ca
};
const httpServer = http.createServer(app);
const httpsServer = https.createServer(credentials, app);
结果:节点:权限被拒绝。
显然这是 Linux 上 Node ssl 的一个已知问题。我尝试按照该线程中不情愿的建议更改权限,但没有喜悦。
那么如何解决节点权限问题呢?或者,由于我想做的只是在 VPS 上设置一个带有联系表单的静态网站,我应该如何修改我的方法?
我找到了答案。 (神奇的线条最终是
proxy_ssl_trusted_certificate /etc/letsencrypt/live/domain.com/fullchain.pem
—— 即在 proxy_pass 旁边的子域 nginx 服务器块的位置部分中对主域证书的引用。)
如果它对任何人有帮助:
在向 NodeJS 应用程序发送 Nginx 代理请求并尝试让整个过程通过 https 而不是 http 工作的情况下,您根本不需要弄乱任何 NodeJS 代码。与 ssl 证书有关的所有事情都可以由 Nginx 处理。
起始假设:
我做了什么:
已安装certbot
编辑了 /etc/nginx/sites-available/form.domain.com.conf 位置块以包含以下内容:
proxy_pass https://123.456.789.01:3000;
、proxy_ssl_trusted_certificate /path/to/main/domain's/certificate
、proxy_set_header Host $host;
、proxy_set_header X-Forwarded-Proto $scheme;
、proxy_set_header X-Real-IP $remote_addr;
和proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
》
使用
sudo certbot certonly --nginx
为两个域安装了新的ssl证书(我先安装了主域的证书,然后进行了测试,然后安装了子域的证书。我想你可以同时执行这些操作,但无法确认。)