有没有办法为我的谷歌云功能HTTP端点创建防火墙规则?

Laz*_*har 2 google-cloud-platform google-cloud-functions google-cloud-networking

只是想检查,如果这是在已有的路线图和我刚才错过了这些。在为重要项目构建功能时,由于多种原因(安全性,如果垃圾邮件导致突然收费,请避免高昂的价格),我想应用一些防火墙规则来限制某些Google Cloud Functions(HTTP端点触发器)的网络访问要求等)

这是可用的还是正在准备中?如果没有,您将如何限制对特定功能的访问,以仅允许几个Google Compute Engine,其他GCF和其他Google Cloud Services(Firestore,Storage,PubSub)。

Jor*_*les 5

More than firewall rules what you should be looking at is to authenticate your requests to your Cloud Functions with Access Tokens.

Here there is a good example on how to do this.

Basically you will be creating an HTTP triggered Cloud Function.

First create a bucket, mine is called auth-123 .Then drop to a Cloud shell and define the project name and the bucket as environment variables:

jordim@yrmv-191108:~$ export BUCKET=auth-123
jordim@yrmv-191108:~$ export PROJECT=yrmv-191108
Run Code Online (Sandbox Code Playgroud)

Create a couple of service accounts

jordim@yrmv-191108:~$ gcloud iam service-accounts create alpha-account --
display-name "Account 1"
jordim@yrmv-191108:~$ gcloud iam service-accounts create beta-account --display-name "Account 2"
Created service account [beta-account].
Run Code Online (Sandbox Code Playgroud)

Now to create the function! On a folder on your cloud shell create first a package.json with the dependencies:

jordim@yrmv-191108:~/cloudfunction$ cat > package.json
{
  "dependencies": {
    "googleapis": "21.2"
  }
}
Run Code Online (Sandbox Code Playgroud)

And now the function itself:

const Google = require('googleapis');
const BUCKET = 'auth-123'; // Replace with name of your bucket

/**
 * Cloud Function.
 *
 * @param {Object} req Cloud Function request context.
 * @param {Object} res Cloud Function response context.
 */
exports.secureFunction = function secureFunction(req, res) {
    var accessToken = getAccessToken(req.get('Authorization'));
    var oauth = new Google.auth.OAuth2();
    oauth.setCredentials({access_token: accessToken});

    var permission = 'storage.buckets.get';
    var gcs = Google.storage('v1');
    gcs.buckets.testIamPermissions(
        {bucket: BUCKET, permissions: [permission], auth: oauth}, {},
        function (err, response) {
            if (response && response['permissions'] && response['permissions'].includes(permission)) {
                authorized(res);
            } else {
                res.status(403).send("The request is forbidden.");
            }
        });



function authorized(res) {
            res.send("The request was successfully authorized.");
            // The code to execute goes here! :)
}
}


function getAccessToken(header) {
    if (header) {
        var match = header.match(/^Bearer\s+([^\s]+)$/); //We are looking for an HTTP request with the content Bearer: + a token
        if (match) {
            return match[1];
        }
    }

    return null;
}
Run Code Online (Sandbox Code Playgroud)

In this case we are checking that the account launching the request has the permission storage.buckets.get, but it can be changed to any other just by changing the the variable permission.

Then you deploy the function:

jordim@yrmv-191108:~/cloudfunction$ gcloud beta  functions deploy secureFunction --stage-bucket $BUCKET --trigger-http
Run Code Online (Sandbox Code Playgroud)

Now you have a cloud function that only triggers its content if it receives a request from an authorized account. Let's make tokens for the accounts we created before:

   jordim@yrmv-191108:~/cloudfunction$ gcloud iam service-accounts keys create --iam-account alpha-account@$PROJECT.iam.gserviceaccount.com ./alpha-account.json
    jordim@yrmv-191108:~/cloudfunction$ export ALPHA_ACCOUNT_TOKEN=$(GOOGLE_APPLICATION_CREDENTIALS=./alpha-account.json gcloud auth application-default print-access-token)


jordim@yrmv-191108:~/cloudfunction$ gcloud iam service-accounts keys create --iam-account beta-account@$PROJECT.iam.gserviceaccount.com ./beta-account.json
created key [4a9251d7611e74da8b4565657b52b7c940606630] of type [json] as [./beta-account.json] for [beta-account@yrmv-191108.iam.gserviceaccount.com]
jordim@yrmv-191108:~/cloudfunction$ export BETA_ACCOUNT_TOKEN=$(GOOGLE_APPLICATION_CREDENTIALS=./beta-account.json gcloud auth application-default print-access-token)
Run Code Online (Sandbox Code Playgroud)

We have the auth tokens on a json now and also exported them as an env var for easy testing. Let's give permission to ALPHA user and not give it to BETA user:

jordim@yrmv-191108:~/cloudfunction$ gsutil acl ch -u alpha-account@$PROJECT.iam.gserviceaccount.com:R gs://auth-123
Run Code Online (Sandbox Code Playgroud)

And now to test:

jordim@yrmv-191108:~/cloudfunction$ curl https://us-central1-yrmv-191108.cloudfunctions.net/secureFunction -H "Authorization: Bearer $ALPHA_ACCOUNT_TOKEN"
The request was successfully authorized.

jordim@yrmv-191108:~/cloudfunction$ curl https://us-central1-yrmv-191108.cloudfunctions.net/secureFunction -H "Authorization: Bearer $BETA_ACCOUNT_TOKEN"
The request is forbidden
Run Code Online (Sandbox Code Playgroud)

You can apply this logic to any of your cloud functions, and unless the request comes with a valid token on its header the amount of resources used for rejecting it is minimal.

  • 我希望有一天他们能够为Cloud Endpoints添加Cloud Function支持。这将有助于两件事。第一,我们将能够从云功能内部删除身份验证检查,这只会使它们成为业务逻辑。第二,该函数不会被调用,因为Cloud Endpoint服务将不允许访问该特定函数端点。 (2认同)