Google Cloud Function 403 用于内部经过身份验证的请求

Google Cloud Function 403 for internal authenticated requests

我正在从我的 GCP 项目中调用云函数。

当功能配置为仅允许内部流量时,我收到 403(权限被拒绝),请参阅 https://cloud.google.com/functions/docs/networking/network-settings#ingress_settings

移除入口控制时没有问题,函数以状态 200 响应。 该函数 不允许 允许未经身份验证的访问,已配置 IAM 策略

效仿 https://cloud.google.com/functions/docs/securing/authenticating#function-to-function 中的示例:

# main.py
import requests

# TODO<developer>: set these values
# REGION = None
# PROJECT_ID = None

RECEIVING_FUNCTION = 'hello-get'

# Constants for setting up metadata server request
# See https://cloud.google.com/compute/docs/instances/verifying-instance-identity#request_signature
function_url = f'https://{REGION}-{PROJECT_ID}.cloudfunctions.net/{RECEIVING_FUNCTION}'

metadata_server_url = \
    'http://metadata/computeMetadata/v1/instance/service-accounts/default/identity?audience='
token_full_url = metadata_server_url + function_url
token_headers = {'Metadata-Flavor': 'Google'}


def hello_trigger(request):
    token_response = requests.get(token_full_url, headers=token_headers)
    jwt = token_response.text

    function_headers = {'Authorization': f'bearer {jwt}'}
    function_response = requests.get(function_url, headers=function_headers)

    function_response.raise_for_status()

    return function_response.text


def hello_get(req):
    return 'Hello there...'

使用所需的入口设置部署函数和触发函数:

gcloud functions deploy hello-get --trigger-http --entry-point hello_get --runtime python37 --ingress-settings internal-only
gcloud functions deploy hello-trigger --trigger-http --entry-point hello_trigger --runtime python37 --ingress-settings all --allow-unauthenticated

呼叫 hello-trigger returns 403.

更改 hello-get 的入口解决了问题:

gcloud functions deploy hello-get --trigger-http --entry-point hello_get --runtime python37 --ingress-settings all

正在拨打 hello-trigger returns 200.

用于 Cloud Functions 的服务帐户被赋予了此设置的 Functions Invoker 角色。

当您将入口流量设置为 internal-only 时,仅接受来自您的 VPC 或来自 VPC SC(服务控制)的流量。

在这里,在你的触发函数中,你不是来自你的 vpc,而是来自另一个(一个无服务器 VPC,由 Google 管理,部署云函数的地方)。因此,入口设置不受尊重,您会收到 403。

因此,为此您有 2 个解决方案:

  1. 仅使用 IAM 服务来过滤谁可以调用您的函数,并让“public”您的函数具有 ingress=all。 (约翰在他的第二条评论中提出的解决方案)。安全级别已经很高了。

但是,有时出于监管原因(或老式安全团队设计)网络控制是首选。

  1. 如果你想通过你的VPC,你需要

像这样,您的触发器函数的所有传出流量都将通过无服务器 VPC 连接器,因此,流量在尝试到达您的“ingress-internal”云函数之前先在您的 VPC 中路由。它将被接受。


如果您的函数使用 ingress=all 设置,任何人都可以通过互联网访问它。

但是,如果你不让功能 public 可以访问,我的意思是,授权给未经身份验证的用户,只有有效的请求(经​​过身份验证和授权角色 cloudfunctions.invoker) 将由您的 Cloud Functions

处理

事实上,任何 Google 服务名称 GFE: Google Front End 都有一个公共层。该层负责许多事情(在 HTTPS 中公开您的服务、管理您的证书、丢弃 DDoS 攻击 OSI 第 4 层,...),其中验证检查 header 和针对 IAM 服务的授权检查。

因此,如果在第 4 层发生 DDoS 攻击,GFE 默认会过滤这些攻击。在第 7 层攻击的情况下,只允许授权请求(有效),您只需为此付费。 GFE 执行的过滤器是免费的。