NGINX 前端 HTTPS 服务器拒绝对本地后端 http express 服务器的请求

NGINX 前端 HTTPS 服务器拒绝对本地后端 http express 服务器的请求

我有一个应用程序分为两个服务器:一个是在端口 8080 上运行的 React 应用程序,另一个是在 3001 上运行的 Express 服务器。运行此应用程序的机器还必须运行其他一些应用程序,因此我使用 Nginx 设置了一个 https 反向代理:

** 我为了测试而禁用了一些代理选项,但如果需要启用它们,请告诉我。

server {
server_name example.com ;
location / {
 proxy_pass http://example.com:8080;
#  proxy_set_header Host $host;
#  proxy_set_header X-SSL-CERT $ssl_client_escaped_cert;
#  proxy_set_header X-Real-IP $remote_addr;
#  proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
#  proxy_set_header X-Forwarded-Proto https;
}
listen 443 ssl; # managed by Certbot
   ssl_certificate /etc/letsencrypt/live/example.com/fullchain.pem; # managed by Certbot
   ssl_certificate_key /etc/letsencrypt/live/example.com/privkey.pem; # managed by Certbot
   include /etc/letsencrypt/options-ssl-nginx.conf; # managed by Certbot
   ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem; # managed by Certbot
}

这按预期工作;我可以访问该网站并且它是安全的,但是对我的后端服务器(在 http://localhost:3001 上运行)发出的请求被阻止,因为它试图加载混合活动内容。因此,我调整了客户端以向 https://localhost:3001 发出请求,然后为 Express 服务器生成了一个自签名证书并将其设置为使用 https,这就是我遇到障碍的地方。由于此证书是自签名的,因此除非有人明确这样做,否则不会信任它,这对用户来说是不合理的。从搜索来看,似乎您不能将 certbot 用于 localhost(可以理解),所以我不太确定接下来该怎么做。我对该proxy_pass字段的假设是后端的请求来自 http,但从浏览器中的错误消息来看,情况似乎并非如此。在同一台机器上运行的两台服务器真的需要使用 https 进行通信吗?

这个问题:使用 NGINX 将 HTTPS 请求代理到 HTTP 后端 几乎与我尝试执行的操作相符,只是我仅使用 Nginx 为客户端提供服务;对后端的请求通过 Apollo 客户端/服务器的组合来处理,因此 Nginx 不知道这些请求。我是否遗漏了什么,或者还有其他配置选项可以尝试?

答案1

因此,在考虑了 Tero Kilkanen 的答案后,我设法解决了我的问题。 Express 允许您在 app.listen(PORT, HOST) 中设置主机名,因此我将 HOST 设置为 example.com。我的后端使用 graphql,所以现在我的后端 url 是:example.com:3001/graphql。之前,我的客户端与后端的连接定义为localhost:3001/graphql,因此我将其修改为连接到example.com/graphql,然后在我的 Nginx 配置中,为 exmaple.com 的服务器创建了一个新位置:

 location /graphql {
  proxy_pass http://130.245.12.107:3001/graphql;                                                                       $  proxy_set_header X-SSL-CERT $ssl_client_escaped_cert;
  proxy_set_header X-Real-IP $remote_addr;
  proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
  proxy_set_header X-Forwarded-Proto https;
 }

现在我对后端的请求有 https。

答案2

对于遇到此问题的其他任何人,您可能已经疯了。您不想将请求发送到托管服务器端口上的 nginx,您希望它们转到端口 80(用于 http)或 443(用于 https)。因此,如果您的服务器是 localhost:3001,则在您的 nginx 配置中,但 postman 或前端 API 环境变量应分别使用 80/443(而不是 3001),然后 nginx 将处理其余部分。我希望这可以省去一些麻烦。

如果您收到 SSL 错误或仅在 :3001 处获得 http 形式的服务器响应并且无法使 https 正常工作,则您可能遇到了此问题。

答案3

虽然 OP 随后的回答解释了他是如何解决问题的,但是源生成的内容可能仍然包含对 http(而不是 https)的引用,尽管可以说,如果响应带有来自源的方案而不是请求的值,那么它也可能包含源的主机名/端口。

另一方面,并​​非所有后端系统都会遵守 X-forwarded-proto 标头。

更为强大的方法是使用证书(有效或自签名或过期或...)并proxy_ssl_verify off在 nginx 上设置。

相关内容