【问题标题】:How to configure nginx reverse proxy in Google Cloud Run to point to a different Google Cloud Run app如何在 Google Cloud Run 中配置 nginx 反向代理以指向不同的 Google Cloud Run 应用
【发布时间】:2022-06-16 15:25:31
【问题描述】:

我在 GCP Cloud Run 中设置了一个由 nginx 前端的 Web 应用程序,效果很好。我正在尝试使用 nginx 将请求代理到 另一个 GCP Cloud Run 服务的某个路由。例如——我希望https://my-cloud-run-frontend.app.run 的请求解析为https://my-cloud-run-frontend.run.app,但是我希望https://my-cloud-run-frontend.run.run/api/* 的请求被代理为https://my-cloud-run-backend.run.app

两种云运行服务都使用 IAM Auth。

当我在本地 docker 容器中运行我的服务时,代理效果很好。同样,如果我在 Cloud Run 设置中从 frontend 应用程序中删除 IAM 身份验证,一切似乎都正常。

但是,启用 IAM 身份验证后,对 https://my-cloud-run-frontend.run.app 的请求会成功,但对 https://my-cloud-run-frontend.run.app/api/ 的请求会因未经授权而失败(具体来说,错误是从 frontend 云运行应用程序抛出的)。

我已确认身份验证通过使用相同的身份验证令牌并直接向https://my-cloud-run-backend.run.apphttps://my-cloud-run-frontend.run.app 发出请求来工作,并且工作正常。

做一些研究,我发现我可能需要设置一个Host 标头,所以我尝试将标头Host 设置为我的目的地(https://my-cloud-run-backend.run.app url)。这会导致调用 https://my-cloud-run-frontend.run.app/api 返回 400 错误。

我的nginx.conf.template 文件:

server {

  access_log /dev/stdout;
  listen 8080;

  location / {

    root   /usr/share/nginx/html;
    index  index.html index.htm;
    try_files $uri $uri/ /index.html;
    proxy_set_header Authorization $http_authorization;
    proxy_pass_header Authorization;
    proxy_pass_request_headers on;

  }

  location /api/ {
    proxy_pass https://my-cloud-run-backend.run.app/;
    proxy_set_header Authorization $http_authorization;
    proxy_pass_header Authorization;
    proxy_set_header Host https://my-cloud-run-backend.run.app;
    proxy_pass_request_headers on;
    rewrite ^/api(.*)$ $1 break;
  }

  error_page   500 502 503 504  /50x.html;

  location = /50x.html {
    root   /usr/share/nginx/html;
  }

}

【问题讨论】:

  • 它不起作用,因为授权标头也被谷歌前端更改(删除身份令牌签名以防止任何可重用性)。为什么不使用负载均衡器?
  • 我不太确定我是否理解——什么时候会发生这种情况?我认为按照我设置 nginx 的方式,应该重新添加该标头,不是吗?负载均衡器不在我批准的技术列表中,并且为此目的感觉有点笨拙/昂贵(将前端代理到后端并转发身份验证)。
  • 出于安全原因,授权标头中提供的身份令牌被截断:签名部分已被删除。您可以使用该令牌来了解请求者的身份,但您不能在后续查询中重复使用该令牌。
  • 明白,谢谢。我认为是这样,它不会被记录/保存/被盗,对吗?我想我可以传入一个令牌作为参数(比如myservice.run.app?upstream-token=ey.....),但我认为它的安全含义不太理想?

标签: nginx google-cloud-platform nginx-reverse-proxy google-cloud-run


【解决方案1】:

您无需在后端进行身份验证即可实现您的用例。实际上,您可以在未经身份验证的情况下部署 API Cloud Run,但使用 ingress set to internal only

然后,在您的反向代理 Cloud Run 上,您必须添加一个 Serverless VPC connector and set the egress to all

该设计仅接受反向代理上经过身份验证和授权的请求,并使 API 后端只能由反向代理(或 VPC 中的其他内部资源)访问。


这种设计可行,但有几个权衡:

  • 您无法定义谁有权访问您的 API 后端。它是“内部的”:项目中的任何内部资源都可以访问它。此外,如果您可以访问反向代理,您也可以访问后端,这里可能没有不同级别的授权(至少使用 Google Cloud 服务。您可以在代码中添加自制授权检查)
  • Serverless VPC 连接器成本高于负载均衡器
  • 设计复杂,仅用于重定向

【讨论】:

    猜你喜欢
    • 2020-10-04
    • 2021-10-06
    • 2019-10-27
    • 2022-01-09
    • 2019-09-28
    • 2020-05-28
    • 2020-07-22
    • 2020-05-31
    • 1970-01-01
    相关资源
    最近更新 更多