使用 VPC 防火墙规则

本页面介绍了用于处理虚拟私有云 (VPC) 防火墙规则的命令,还提供了一些命令用法示例。通过 VPC 防火墙规则,您可以根据端口号、标记或协议来允许或拒绝进出 VPC 网络中的虚拟机 (VM) 实例的流量。

准备工作

如需详细了解 VPC 防火墙规则(例如默认网络的隐式规则和系统生成的规则),请参阅 VPC 防火墙规则

在配置防火墙规则前,请先查看防火墙规则组件,以熟悉 Google Cloud中使用的防火墙组件。

创建 VPC 防火墙规则

VPC 防火墙规则是在网络级别定义的,仅会应用于在其中创建它们的网络;但是,您为每条规则选择的名称在项目中必须是唯一的。

防火墙规则可以包含 IPv4 或 IPv6 地址范围,但不能同时包含两者。

创建防火墙规则时,可选择启用防火墙规则日志记录。如果启用日志记录,则可以省略元数据字段以节省存储费用。如需了解详情,请参阅使用 VPC 防火墙规则日志记录

如果您想要为目标或来源服务账号字段指定多个服务账号,请使用 Google Cloud CLI、API 或客户端库。

默认网络在创建时提供自动防火墙规则。如果您使用 Google Cloud 控制台,则可以利用自定义和自动模式网络在创建网络时轻松创建类似的防火墙。如果您使用 gcloud CLI 或 API,并且想要创建与默认网络提供的防火墙规则类似的防火墙规则,请参阅为常见使用场景配置防火墙规则

控制台

  1. 在 Google Cloud 控制台中,前往防火墙政策页面。

    转到“防火墙政策”

  2. 点击创建防火墙规则

  3. 输入防火墙规则的名称

    该名称在项目中必须是唯一的。

  4. (可选)您可以启用防火墙规则日志记录

    • 点击日志 > 开启
    • 如需省略元数据,请点击显示日志详细信息,然后清除包括元数据复选框。
  5. 为防火墙规则指定网络

  6. 指定规则的优先级

    数字越小,优先级越高。

  7. 选择“入站”或“出站”作为流量方向

  8. 对于对匹配项执行的操作,选择“允许”或“拒绝”。

  9. 指定规则的目标

    • 如果您希望将规则应用于网络中的所有实例,请选择 All instances in the network
    • 如果您希望按网络(目标)标记将规则应用于部分实例,请选择指定的目标标记,然后在目标标记字段中输入要应用该规则的标记。
    • 如果您希望按关联的服务账号将规则应用于部分实例,请选择指定的服务账号,在服务账号范围中指明该服务账号属于当前项目还是其他项目,然后在目标服务账号字段中选择或输入服务账号名称。
  10. 对于入站流量规则,请指定来源过滤条件

    • 如需按来源 IPv4 范围过滤传入的流量,请选择 IPv4 范围,然后在来源 IPv4 范围字段中输入 CIDR 地址块。如需选择所有 IPv4 来源,请使用 0.0.0.0/0
    • 如需按来源 IPv6 范围过滤传入的流量,请选择 IPv6 范围,然后在来源 IPv6 范围字段中输入 CIDR 地址块。如需选择所有 IPv6 来源,请使用 ::/0
    • 如需按网络标记过滤传入的流量,请选择来源标记,然后在来源标记字段中输入网络标记。如需了解针对来源标记数量的限制,请参阅每个网络的限制。只有在未按服务账号指定目标时,才能按来源标记过滤。
    • 如需按服务账号过滤传入的流量,请选择服务账号,在服务账号范围中指明该服务账号属于当前项目还是其他项目,然后在来源服务账号字段中选择或输入服务账号名称。只有在未通过网络标记指定目标时,才能按来源服务账号过滤。
    • 如果需要,请指定次要来源过滤条件。次要来源过滤条件不能与主要过滤条件相同。 来源 IP 地址范围可以与来源标记来源服务账号搭配使用。有效来源集是来源范围内的 IP 地址与网络标记或服务账号所标识实例的并集union。也就是说,如果来源 IP 地址范围或来源标记(或来源服务账号)与过滤条件匹配,则来源会包含在有效来源集中。
    • 来源标记来源服务账号不能同时使用。

    如需详细了解如何使用服务账号和网络标记,请参阅按服务账号过滤与按网络标记过滤

  11. 对于入站流量规则,请指定目标过滤条件

    • 如需按目标 IPv4 范围过滤传入的流量,请选择 IPv4 范围,然后在目标 IPv4 范围字段中输入 CIDR 地址块。对于任何 IPv4 目标,请使用 0.0.0.0/0
    • 如需按目标 IPv6 范围过滤传入的流量,请选择 IPv6 范围,然后在目标 IPv6 范围字段中输入 CIDR 地址块。对于任何 IPv6 目标,请使用 ::/0

    如需了解详情,请参阅入站流量规则的目的地

  12. 对于出站流量规则,请指定目标过滤条件

    • 如需按目标 IPv4 范围过滤传出的流量,请选择 IPv4 范围,然后在目标 IPv4 范围字段中输入 CIDR 地址块。对于任何 IPv4 目标,请使用 0.0.0.0/0
    • 如需按目标 IPv6 范围过滤传出的流量,请选择 IPv6 范围,然后在目标 IPv6 范围字段中输入 CIDR 地址块。对于任何 IPv6 目标,请使用 ::/0

    如需了解详情,请参阅出站流量规则的目的地

  13. 对于出站流量规则,请指定来源过滤条件

    • 如需按来源 IPv4 范围过滤传出的流量,请选择 IPv4 范围,然后在来源 IPv4 范围字段中输入 CIDR 地址块。如需选择所有 IPv4 来源,请使用 0.0.0.0/0
    • 如需按来源 IPv6 范围过滤传出的流量,请选择 IPv6 范围,然后在来源 IPv6 范围字段中输入 CIDR 地址块。对于任何 IPv6 目标,请使用 ::/0

    如需了解详情,请参阅出站流量规则的来源

  14. 定义规则适用的协议和端口

    • 要将规则应用于所有协议和目标端口,请选择全部允许全部拒绝,具体取决于操作。
    • 如需定义特定协议和目标端口,请选择指定的协议和端口
      • 选择 TCP 以包括 TCP 协议和目标端口。输入 all 或英文逗号分隔的目的地端口列表,例如 20-22, 80, 8080
      • 选择 UDP 以包括 UDP 协议和目标端口。输入 all 或英文逗号分隔的目的地端口列表,例如 67-69, 123
      • 选择其他以包括 icmpsctp 或某个协议编号等协议。例如,对于 IPv4 ICMP,请使用 icmp 或协议编号 1。对于 IPv6 ICMP,请使用协议编号 58

    如需了解详情,请参阅协议和目标端口

  15. (可选)您可以创建防火墙规则但不实施,只需将其实施状态设置为已停用即可。具体方法为:点击停用规则,然后选择已停用

  16. 点击创建

gcloud

如需创建 VPC 防火墙规则,请使用 gcloud compute firewall-rules create 命令:

gcloud compute firewall-rules create RULE_NAME \
    [--network NETWORK; default="default"] \
    [--priority PRIORITY;default=1000] \
    [--direction (ingress|egress|in|out); default="ingress"] \
    [--action (deny | allow )] \
    [--target-tags TAG[,TAG,...]] \
    [--target-service-accounts=IAM_SERVICE_ACCOUNT[,IAM_SERVICE_ACCOUNT,...]] \
    [--source-ranges CIDR_RANGE[,CIDR_RANGE,...]] \
    [--source-tags TAG[,TAG, ...]] \
    [--source-service-accounts=IAM_SERVICE_ACCOUNT[,IAM_SERVICE_ACCOUNT,...]] \
    [--destination-ranges CIDR_RANGE[,CIDR_RANGE,...]] \
    [--rules (PROTOCOL[:PORT[-PORT]],[PROTOCOL[:PORT[-PORT]],...]] | all ) \
    [--disabled | --no-disabled] \
    [--enable-logging | --no-enable-logging] \
    [--logging-metadata LOGGING_METADATA]

请使用如下参数。如需详细了解各个参数,请参阅 SDK 参考文档

  • --network 规则的网络。如果省略此参数,则会在 default 网络中创建规则。如果您没有默认网络或者想要在特定网络中创建规则,则必须使用该字段。
  • --priority:表示规则优先级的数值。数字越小,优先级越高。
  • --direction流量方向INGRESSEGRESS)。
  • --action对匹配项执行的操作allowdeny)。必须与 --rules 标志结合使用。
  • 通过以下任一方式指定目标
    • 如果应将规则应用于网络中的所有目标,则省略 --target-tags--target-service-accounts
    • 使用 --target-tags 标记可按网络标记定义目标
    • 使用 --target-service-accounts 标记可按关联的服务账号定义目标
  • 对于入站流量规则,如需进一步优化目的地,请使用 --destination-ranges 以 CIDR 格式指定 IPv4 或 IPv6 地址范围。如果省略 --destination-ranges,则入站流量目的地是任何 IPv4 地址 0.0.0.0/0。如需了解详情,请参阅入站流量规则的目的地以及入站流量规则的目标和 IP 地址

  • 对于入站流量规则,请指定来源

    • --source-ranges:使用此标志可以以 CIDR 格式指定来源 IPv4 或 IPv6 地址的范围。
    • 如果省略 --source-rangessource-tags--source-service-accounts,则入站流量来源是任何 IPv4 地址 0.0.0.0/0
    • --source-tags:使用此标志可以按网络标记指定来源实例。只有在未按服务账号指定目标时,才能按来源标记过滤。如需了解详情,请参阅按服务账号过滤与按网络标记过滤
    • --source-ranges--source-tags 可同时使用。如果同时指定了两者,则有效来源集就是来源范围内的 IP 地址与网络标记所标识实例的并集,即使所标记实例的 IP 不在来源范围内也是如此。
    • --source-service-accounts:使用此标志可以按实例使用的服务账号指定实例。只有在未按网络标记指定目标时,才能按来源服务账号过滤。如需了解详情,请参阅按服务账号过滤与按网络标记过滤--source-ranges--source-service-accounts 可同时使用。如果同时指定了两者,则有效来源集就是来源范围内的 IP 地址与来源服务账号所标识实例的并集,即使来源服务账号所标识的实例的 IP 地址不在来源范围内也是如此。union
  • 对于出站流量规则,如需进一步优化来源,请使用 --source-ranges 指定 CIDR 格式的 IPv4 或 IPv6 地址范围。如果省略 --source-ranges,则出站流量来源是任何 IPv4 地址 0.0.0.0/0。如需了解详情,请参阅出站流量规则的来源以及出站流量规则的目标和 IP 地址

  • 对于出站流量规则,请指定目的地

    • --destination-ranges:使用此标志可以以 CIDR 格式指定目标 IPv4 或 IPv6 地址的范围。
    • 如果省略 --destination-ranges,则出站流量目的地是任何 IPv4 地址 0.0.0.0/0
  • --rules:规则适用的协议和目标端口列表。使用 all 可使规则适用于所有协议和所有目的地端口。需要用到 --action 标志。

  • 默认情况下,防火墙规则会在创建后自动执行,不过,您可以改变这种做法。

    • 如果同时省略 --disabled--no-disabled,则系统会创建并实施防火墙规则。
    • --disabled:添加此标志可以创建防火墙规则,但不会实施。防火墙规则会保持停用状态,直到您更新防火墙规则以将其启用。
    • --no-disabled:添加此标志可确保实施防火墙规则。
  • --enable-logging | --no-enable-logging:您可以在创建或更新规则时,为规则启用防火墙规则日志记录。通过 VPC 防火墙规则日志记录,您可以审核、验证和分析防火墙规则所带来的影响。 如需了解详情,请参阅 VPC 防火墙规则日志记录

    • --logging-metadata:如果启用日志记录,则默认情况下防火墙规则日志记录包含基本字段和元数据字段。您可以省略元数据字段以节省存储费用。如需了解详情,请参阅使用 VPC 防火墙规则日志记录

Terraform

如需创建防火墙规则,您可以使用 google_compute_firewall 资源

resource "google_compute_firewall" "rules" {
  name        = "my-firewall-rule"
  network     = "default"
  description = "Creates firewall rule targeting tagged instances"

  allow {
    protocol = "tcp"
    ports    = ["80", "443"]
  }

  source_ranges = ["0.0.0.0/0"]
  target_tags   = ["web"]
}

如需了解如何应用或移除 Terraform 配置,请参阅基本 Terraform 命令

API

创建 VPC 防火墙规则。

POST https://compute.googleapis.com/compute/v1/projects/PROJECT_ID/global/firewalls
{
  "name": "RULE_NAME",
  "network": "projects/PROJECT-ID/global/networks/NETWORK",
  ... other fields
}

请替换以下内容:

  • PROJECT_ID:VPC 网络所在项目的 ID。
  • NETWORK:在其中创建防火墙规则的 VPC 网络的名称。
  • RULE_NAME:防火墙规则的名称。

  • 对于入站流量防火墙规则,请指定入站流量来源和目的地:

    • 使用 sourceRangessourceTagssourceServiceAccounts 字段指定入站流量来源。

    • sourceRanges 可以是 IPv4 或 IPv6 范围,但不能是这两者的组合。如需使用范围 0.0.0.0/0,请勿指定任何字段。

    • 您不能同时使用 sourceTagssourceServiceAccounts 字段。不过,您可以将 sourceRangessourceTagssourceServiceAccounts 结合使用。如果这样,连接只需要匹配其中一个字段,即可应用防火墙规则。

    • 对于目标字段,如果您使用 sourceTags 字段,则不能使用 targetServiceAccounts 字段。您必须使用 targetTags 字段或不使用目标字段。同样,如果您使用 sourceServiceAccounts 字段,则不能使用 targetTags 字段。如果您不指定目标字段,则规则将应用于网络中的所有目标。

    • 使用 destinationRanges 字段指定入站流量目的地。destinationRanges 可以是 IPv4 范围或 IPv6 范围,但不能是这两者的组合。
      如果您不指定目的地,则 Google Cloud 将使用 0.0.0.0/0。如需了解详情,请参阅入站流量规则的目的地以及入站流量规则的目标和 IP 地址

  • 对于出站流量防火墙规则,请指定出站流量来源和目的地:

    • 使用 sourceRanges 字段指定出站来源。sourceRange 可以是 IPv4 或 IPv6 范围,但不能是这两者的组合。
      如果您不指定来源, Google Cloud 将使用 0.0.0.0/0。如需了解详情,请参阅出站流量规则的来源以及出站流量规则的目标和 IP 地址

    • 使用 destinationRanges 字段指定目的地。destinationRanges 可以是 IPv4 或 IPv6 范围,但不能是这两者的组合。
      如果您不指定目的地, Google Cloud将使用 0.0.0.0/0。使用 targetTagstargetServiceAccounts 字段可指定规则应用于的目标。如果您不指定目标字段,则规则将应用于网络中的所有目标。

如需详细了解各字段,请参阅 firewalls.insert 方法。

C#


using Google.Cloud.Compute.V1;
using System.Threading.Tasks;

public class CreateFirewallRuleAsyncSample
{
    public async Task CreateFirewallRuleAsync(
        // TODO(developer): Set your own default values for these parameters or pass different values when calling this method.
        string projectId = "your-project-id",
        string firewallRuleName = "my-test-firewall-rule",
        // Name of the network the rule will be applied to. Some available name formats:
        // projects/{project_id}/global/networks/{network}
        // global/networks/{network}
        string networkName = "global/networks/default")
    {
        Firewall firewallRule = new Firewall
        {
            Name = firewallRuleName,
            Network = networkName,
            Direction = ComputeEnumConstants.Firewall.Direction.Ingress,
            Allowed =
            {
                new Allowed
                {
                    Ports = { "80", "443" },
                    IPProtocol = "tcp"
                }
            },
            TargetTags = { "web" },
            Description = "Allows TCP traffic on port 80 and 443 from anywhere."
        };

        // Note that the default value of priority for the firewall API is 1000.
        // If you check the value of firewallRule.Priority at this point it
        // will be equal to 0, however it is not treated as "set" by the library, and thus
        // the default will be applied to the new rule. If you want to create a rule that
        // has priority == 0, you'll need to explicitly set it: firewallRule.Priority = 0.
        // You can use the firewallRule.HasPriority property to check if the priority has been set.
        // You can use the firewallRule.ClearPriority() method to unset the priority.

        // Initialize client that will be used to send requests. This client only needs to be created
        // once, and can be reused for multiple requests.
        FirewallsClient client = await FirewallsClient.CreateAsync();

        // Create the firewall rule in the specified project.
        var firewallRuleCreation = await client.InsertAsync(projectId, firewallRule);

        // Wait for the operation to complete using client-side polling.
        await firewallRuleCreation.PollUntilCompletedAsync();
    }
}

Go

import (
	"context"
	"fmt"
	"io"

	compute "cloud.google.com/go/compute/apiv1"
	computepb "cloud.google.com/go/compute/apiv1/computepb"
	"google.golang.org/protobuf/proto"
)

// createFirewallRule creates a firewall rule allowing for incoming HTTP and HTTPS access from the entire Internet.
func createFirewallRule(w io.Writer, projectID, firewallRuleName, networkName string) error {
	// projectID := "your_project_id"
	// firewallRuleName := "europe-central2-b"
	// networkName := "global/networks/default"

	ctx := context.Background()
	firewallsClient, err := compute.NewFirewallsRESTClient(ctx)
	if err != nil {
		return fmt.Errorf("NewInstancesRESTClient: %w", err)
	}
	defer firewallsClient.Close()

	firewallRule := &computepb.Firewall{
		Allowed: []*computepb.Allowed{
			{
				IPProtocol: proto.String("tcp"),
				Ports:      []string{"80", "443"},
			},
		},
		Direction: proto.String(computepb.Firewall_INGRESS.String()),
		Name:      &firewallRuleName,
		TargetTags: []string{
			"web",
		},
		Network:     &networkName,
		Description: proto.String("Allowing TCP traffic on port 80 and 443 from Internet."),
	}

	// Note that the default value of priority for the firewall API is 1000.
	// If you check the value of `firewallRule.GetPriority()` at this point it
	// will be equal to 0, however it is not treated as "set" by the library and thus
	// the default will be applied to the new rule. If you want to create a rule that
	// has priority == 0, you need to explicitly set it so:

	// firewallRule.Priority = proto.Int32(0)

	req := &computepb.InsertFirewallRequest{
		Project:          projectID,
		FirewallResource: firewallRule,
	}

	op, err := firewallsClient.Insert(ctx, req)
	if err != nil {
		return fmt.Errorf("unable to create firewall rule: %w", err)
	}

	if err = op.Wait(ctx); err != nil {
		return fmt.Errorf("unable to wait for the operation: %w", err)
	}

	fmt.Fprintf(w, "Firewall rule created\n")

	return nil
}

Java


import com.google.cloud.compute.v1.Allowed;
import com.google.cloud.compute.v1.Firewall;
import com.google.cloud.compute.v1.Firewall.Direction;
import com.google.cloud.compute.v1.FirewallsClient;
import com.google.cloud.compute.v1.InsertFirewallRequest;
import java.io.IOException;
import java.util.UUID;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;

public class CreateFirewallRule {

  public static void main(String[] args)
      throws IOException, ExecutionException, InterruptedException, TimeoutException {
    // TODO(developer): Replace these variables before running the sample
    /* project: project ID or project number of the Cloud project you want to use.
       firewallRuleName: name of the rule that is created.
       network: name of the network the rule will be applied to. Available name formats:
        * https://www.googleapis.com/compute/v1/projects/{project_id}/global/networks/{network}
        * projects/{project_id}/global/networks/{network}
        * global/networks/{network} */
    String project = "your-project-id";
    String firewallRuleName = "firewall-rule-name-" + UUID.randomUUID();
    String network = "global/networks/default";

    // The rule will be created with default priority of 1000.
    createFirewall(project, firewallRuleName, network);
  }

  // Creates a simple firewall rule allowing for incoming HTTP and 
  // HTTPS access from the entire Internet.
  public static void createFirewall(String project, String firewallRuleName, String network)
      throws IOException, ExecutionException, InterruptedException, TimeoutException {
    /* Initialize client that will be used to send requests. This client only needs to be created
       once, and can be reused for multiple requests. After completing all of your requests, call
       the `firewallsClient.close()` method on the client to safely
       clean up any remaining background resources. */
    try (FirewallsClient firewallsClient = FirewallsClient.create()) {

      // The below firewall rule is created in the default network.
      Firewall firewallRule = Firewall.newBuilder()
          .setName(firewallRuleName)
          .setDirection(Direction.INGRESS.toString())
          .addAllowed(
              Allowed.newBuilder().addPorts("80").addPorts("443").setIPProtocol("tcp").build())
          .addSourceRanges("0.0.0.0/0")
          .setNetwork(network)
          .addTargetTags("web")
          .setDescription("Allowing TCP traffic on port 80 and 443 from Internet.")
          .build();

      /* Note that the default value of priority for the firewall API is 1000.
         If you check the value of `firewallRule.getPriority()` at this point it
         will be equal to 0, however it is not treated as "set" by the library and thus
         the default will be applied to the new rule. If you want to create a rule that
         has priority == 0, you'll need to explicitly set it so: setPriority(0) */

      InsertFirewallRequest insertFirewallRequest = InsertFirewallRequest.newBuilder()
          .setFirewallResource(firewallRule)
          .setProject(project).build();

      firewallsClient.insertAsync(insertFirewallRequest).get(3, TimeUnit.MINUTES);

      System.out.println("Firewall rule created successfully -> " + firewallRuleName);
    }
  }
}

Node.js

/**
 * TODO(developer): Uncomment and replace these variables before running the sample.
 */
// const projectId = 'YOUR_PROJECT_ID';
// const firewallRuleName = 'YOUR_FIREWALL_RULE_NAME'
// const networkName = 'global/networks/default'

const compute = require('@google-cloud/compute');
const computeProtos = compute.protos.google.cloud.compute.v1;

async function createFirewallRule() {
  const firewallsClient = new compute.FirewallsClient();
  const operationsClient = new compute.GlobalOperationsClient();

  const firewallRule = new computeProtos.Firewall();
  firewallRule.name = firewallRuleName;
  firewallRule.direction = 'INGRESS';
  firewallRule.allowed = [
    {
      IPProtocol: 'tcp',
      ports: ['80', '443'],
    },
  ];
  firewallRule.targetTags = ['web'];
  firewallRule.network = networkName;
  firewallRule.description =
    'Allowing TCP traffic on port 80 and 443 from Internet.';

  // Note that the default value of priority for the firewall API is 1000.
  // If you check the value of `firewallRule.priority` at this point it
  // will be equal to null, however it is not treated as "set" by the library and thus
  // the default will be applied to the new rule. If you want to create a rule that
  // has priority == 0, you need to explicitly set it so:

  // firewallRule.priority = 0

  const [response] = await firewallsClient.insert({
    project: projectId,
    firewallResource: firewallRule,
  });
  let operation = response.latestResponse;

  // Wait for the create operation to complete.
  while (operation.status !== 'DONE') {
    [operation] = await operationsClient.wait({
      operation: operation.name,
      project: projectId,
    });
  }

  console.log('Firewall rule created');
}

createFirewallRule();

PHP

use Google\Cloud\Compute\V1\Allowed;
use Google\Cloud\Compute\V1\Client\FirewallsClient;
use Google\Cloud\Compute\V1\Firewall;
use Google\Cloud\Compute\V1\Firewall\Direction;
use Google\Cloud\Compute\V1\InsertFirewallRequest;

/**
 * Creates a simple firewall rule allowing incoming HTTP and HTTPS access from the entire internet.
 *
 * @param string $projectId Project ID or project number of the Cloud project you want to create a rule for.
 * @param string $firewallRuleName Name of the rule that is created.
 * @param string $network Name of the network the rule will be applied to. Available name formats:
 *                        https://www.googleapis.com/compute/v1/projects/{project_id}/global/networks/{network}
 *                        projects/{project_id}/global/networks/{network}
 *                        global/networks/{network}
 *
 * @throws \Google\ApiCore\ApiException if the remote call fails.
 * @throws \Google\ApiCore\ValidationException if local error occurs before remote call.
 */

function create_firewall_rule(string $projectId, string $firewallRuleName, string $network = 'global/networks/default')
{
    $firewallsClient = new FirewallsClient();
    $allowedPorts = (new Allowed())
      ->setIPProtocol('tcp')
      ->setPorts(['80', '443']);
    $firewallResource = (new Firewall())
      ->setName($firewallRuleName)
      ->setDirection(Direction::name(Direction::INGRESS))
      ->setAllowed([$allowedPorts])
      ->setSourceRanges(['0.0.0.0/0'])
      ->setTargetTags(['web'])
      ->setNetwork($network)
      ->setDescription('Allowing TCP traffic on ports 80 and 443 from Internet.');

    /**
    * Note that the default value of priority for the firewall API is 1000.
    * If you check the value of its priority at this point it will be
    * equal to 0, however it is not treated as "set" by the library and thus
    * the default will be applied to the new rule. If you want to create a rule
    * that has priority == 0, you need to explicitly set it so:
    *
    *   $firewallResource->setPriority(0);
    */

    //Create the firewall rule using Firewalls Client.
    $request = (new InsertFirewallRequest())
        ->setFirewallResource($firewallResource)
        ->setProject($projectId);
    $operation = $firewallsClient->insert($request);

    // Wait for the operation to complete.
    $operation->pollUntilComplete();
    if ($operation->operationSucceeded()) {
        printf('Created rule %s.' . PHP_EOL, $firewallRuleName);
    } else {
        $error = $operation->getError();
        printf('Firewall rule creation failed: %s' . PHP_EOL, $error?->getMessage());
    }
}

Python

from __future__ import annotations

import sys
from typing import Any

from google.api_core.extended_operation import ExtendedOperation
from google.cloud import compute_v1


def wait_for_extended_operation(
    operation: ExtendedOperation, verbose_name: str = "operation", timeout: int = 300
) -> Any:
    """
    Waits for the extended (long-running) operation to complete.

    If the operation is successful, it will return its result.
    If the operation ends with an error, an exception will be raised.
    If there were any warnings during the execution of the operation
    they will be printed to sys.stderr.

    Args:
        operation: a long-running operation you want to wait on.
        verbose_name: (optional) a more verbose name of the operation,
            used only during error and warning reporting.
        timeout: how long (in seconds) to wait for operation to finish.
            If None, wait indefinitely.

    Returns:
        Whatever the operation.result() returns.

    Raises:
        This method will raise the exception received from `operation.exception()`
        or RuntimeError if there is no exception set, but there is an `error_code`
        set for the `operation`.

        In case of an operation taking longer than `timeout` seconds to complete,
        a `concurrent.futures.TimeoutError` will be raised.
    """
    result = operation.result(timeout=timeout)

    if operation.error_code:
        print(
            f"Error during {verbose_name}: [Code: {operation.error_code}]: {operation.error_message}",
            file=sys.stderr,
            flush=True,
        )
        print(f"Operation ID: {operation.name}", file=sys.stderr, flush=True)
        raise operation.exception() or RuntimeError(operation.error_message)

    if operation.warnings:
        print(f"Warnings during {verbose_name}:\n", file=sys.stderr, flush=True)
        for warning in operation.warnings:
            print(f" - {warning.code}: {warning.message}", file=sys.stderr, flush=True)

    return result


def create_firewall_rule(
    project_id: str, firewall_rule_name: str, network: str = "global/networks/default"
) -> compute_v1.Firewall:
    """
    Creates a simple firewall rule allowing for incoming HTTP and HTTPS access from the entire Internet.

    Args:
        project_id: project ID or project number of the Cloud project you want to use.
        firewall_rule_name: name of the rule that is created.
        network: name of the network the rule will be applied to. Available name formats:
            * https://www.googleapis.com/compute/v1/projects/{project_id}/global/networks/{network}
            * projects/{project_id}/global/networks/{network}
            * global/networks/{network}

    Returns:
        A Firewall object.
    """
    firewall_rule = compute_v1.Firewall()
    firewall_rule.name = firewall_rule_name
    firewall_rule.direction = "INGRESS"

    allowed_ports = compute_v1.Allowed()
    allowed_ports.I_p_protocol = "tcp"
    allowed_ports.ports = ["80", "443"]

    firewall_rule.allowed = [allowed_ports]
    firewall_rule.source_ranges = ["0.0.0.0/0"]
    firewall_rule.network = network
    firewall_rule.description = "Allowing TCP traffic on port 80 and 443 from Internet."

    firewall_rule.target_tags = ["web"]

    # Note that the default value of priority for the firewall API is 1000.
    # If you check the value of `firewall_rule.priority` at this point it
    # will be equal to 0, however it is not treated as "set" by the library and thus
    # the default will be applied to the new rule. If you want to create a rule that
    # has priority == 0, you need to explicitly set it so:
    # TODO: Uncomment to set the priority to 0
    # firewall_rule.priority = 0

    firewall_client = compute_v1.FirewallsClient()
    operation = firewall_client.insert(
        project=project_id, firewall_resource=firewall_rule
    )

    wait_for_extended_operation(operation, "firewall rule creation")

    return firewall_client.get(project=project_id, firewall=firewall_rule_name)

Ruby


require "google/cloud/compute/v1"

# Creates a simple firewall rule allowing for incoming HTTP and HTTPS access from the entire Internet.
#
# @param [String] project project ID or project number of the Cloud project you want to use.
# @param [String] name: name of the rule that is created.
# @param network: name of the network the rule will be applied to. Available name formats:
#         * https://www.googleapis.com/compute/v1/projects/{project_id}/global/networks/{network}
#         * projects/{project_id}/global/networks/{network}
#         * global/networks/{network}
def create_firewall_rule project:, name:, network: "global/networks/default"
  rule = {
    name: name,
    direction: "INGRESS",
    allowed: [{
      I_p_protocol: "tcp",
      ports: ["80", "443"]
    }],
    source_ranges: ["0.0.0.0/0"],
    network: network,
    description: "Allowing TCP traffic on port 80 and 443 from Internet.",
    target_tags: ["web"]
  }

  # Note that the default value of priority for the firewall API is 1000.
  # If you want to create a rule that has priority == 0, you need to explicitly set it:
  #   rule[:priority] = 0
  # Use `rule.has_key? :priority` to check if the priority has been set.
  # Use `rule.delete :priority` method to unset the priority.

  request = {
    firewall_resource: rule,
    project: project
  }

  client = ::Google::Cloud::Compute::V1::Firewalls::Rest::Client.new
  operation = client.insert request

  wait_until_done operation: operation
end

更新 VPC 防火墙规则

您可以修改 VPC 防火墙规则的某些组成部分,例如匹配条件的指定协议和目的地端口。您不能修改防火墙规则的名称、网络、对匹配项执行的操作流量方向

如果您需要更改名称、网络、操作或方向组件,则必须删除现有规则,然后改为创建新规则

如果要添加或移除多个服务账号,请使用 gcloud CLI、API 或客户端库。您无法使用 Google Cloud 控制台来指定多个目标服务账号或来源服务账号。

控制台

  1. 在 Google Cloud 控制台中,前往防火墙政策页面。

    转到“防火墙政策”

  2. 点击要修改的防火墙规则。

  3. 点击修改

  4. 根据您的需求修改任何可修改的组件

  5. 点击保存

gcloud

如需更新 VPC 防火墙规则,请使用 gcloud compute firewall-rules update 命令:

gcloud compute firewall-rules update RULE_NAME \
    [--priority=PRIORITY] \
    [--description=DESCRIPTION] \
    [--target-tags=TAG,...] \
    [--target-service-accounts=IAM_SERVICE_ACCOUNT,_] \
    [--source-ranges=CIDR_RANGE,...] \
    [--source-tags=TAG,...] \
    [--source-service-accounts=IAM_SERVICE_ACCOUNT,_] \
    [--destination-ranges=CIDR_RANGE,...] \
    [--rules=[PROTOCOL[:PORT[-PORT]],…]] \
    [--disabled | --no-disabled] \
    [--enable-logging | --no-enable-logging]

每个标志的说明均与创建防火墙规则部分相同。如需详细了解各个标志,请参阅 SDK 参考文档

API

使用 PATCH 可更新以下字段:alloweddescriptionsourceRangessourceTagstargetTags。对所有其他字段使用 PUT 或 POST。

(PATCH|(POST|PUT)) https://www.googleapis.com/compute/v1/projects/PROJECT_ID/global/firewalls/RULE_NAME
{
  "name": "RULE_NAME",
  "network": "projects/PROJECT-ID/global/networks/NETWORK",
  ... other fields
}

请替换以下内容:

  • PROJECT_ID:VPC 网络所在项目的 ID。
  • NETWORK:防火墙规则所在的 VPC 网络的名称。
  • RULE_NAME:要更新的防火墙规则的名称。

如需详细了解各字段,请参阅 firewalls.patchfirewalls.update 方法。

C#


using Google.Cloud.Compute.V1;
using System.Threading.Tasks;

public class PatchFirewallRuleAsyncSample
{
    public async Task PatchFirewallRuleAsync(
        // TODO(developer): Set your own default values for these parameters or pass different values when calling this method.
        string projectId = "your-project-id",
        string firewallRuleName = "my-test-firewall-rule",
        int newPriority = 10)
    {
        // The patch operation doesn't require the full definition of a Firewall object.
        // It will only update the values that were set in it,
        // in this case it will only change the priority.
        Firewall firewallRule = new Firewall
        {
            Priority = newPriority
        };

        // Initialize client that will be used to send requests. This client only needs to be created
        // once, and can be reused for multiple requests.
        FirewallsClient client = await FirewallsClient.CreateAsync();

        // Patch the firewall rule in the specified project.
        var firewallRulePatching = await client.PatchAsync(projectId, firewallRuleName, firewallRule);

        // Wait for the operation to complete using client-side polling.
        await firewallRulePatching.PollUntilCompletedAsync();
    }
}

Go

import (
	"context"
	"fmt"
	"io"

	compute "cloud.google.com/go/compute/apiv1"
	computepb "cloud.google.com/go/compute/apiv1/computepb"
	"google.golang.org/protobuf/proto"
)

// patchFirewallPriority modifies the priority of a given firewall rule.
func patchFirewallPriority(w io.Writer, projectID, firewallRuleName string, priority int32) error {
	// projectID := "your_project_id"
	// firewallRuleName := "europe-central2-b"
	// priority := 10

	ctx := context.Background()
	firewallsClient, err := compute.NewFirewallsRESTClient(ctx)
	if err != nil {
		return fmt.Errorf("NewInstancesRESTClient: %w", err)
	}
	defer firewallsClient.Close()

	firewallRule := &computepb.Firewall{
		Priority: proto.Int32(priority),
	}

	req := &computepb.PatchFirewallRequest{
		Project:          projectID,
		Firewall:         firewallRuleName,
		FirewallResource: firewallRule,
	}

	// The patch operation doesn't require the full definition of a Firewall interface. It will only update
	// the values that were set in it, in this case it will only change the priority.
	op, err := firewallsClient.Patch(ctx, req)
	if err != nil {
		return fmt.Errorf("unable to patch firewall rule: %w", err)
	}

	if err = op.Wait(ctx); err != nil {
		return fmt.Errorf("unable to wait for the operation: %w", err)
	}

	fmt.Fprintf(w, "Firewall rule updated\n")

	return nil
}

Java


import com.google.api.gax.longrunning.OperationFuture;
import com.google.cloud.compute.v1.Firewall;
import com.google.cloud.compute.v1.FirewallsClient;
import com.google.cloud.compute.v1.Operation;
import com.google.cloud.compute.v1.PatchFirewallRequest;
import java.io.IOException;
import java.util.UUID;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;

public class PatchFirewallRule {

  public static void main(String[] args)
      throws IOException, ExecutionException, InterruptedException, TimeoutException {
    // TODO(developer): Replace these variables before running the sample
    // project: project ID or project number of the Cloud project you want to use.
    // firewallRuleName: name of the rule you want to modify.
    // priority: the new priority to be set for the rule.
    String project = "your-project-id";
    String firewallRuleName = "firewall-rule-name-" + UUID.randomUUID();
    int priority = 10;

    patchFirewallPriority(project, firewallRuleName, priority);
  }

  // Modifies the priority of a given firewall rule.
  public static void patchFirewallPriority(String project, String firewallRuleName, int priority)
      throws IOException, ExecutionException, InterruptedException, TimeoutException {
    /* Initialize client that will be used to send requests. This client only needs to be created
       once, and can be reused for multiple requests. After completing all of your requests, call
       the `firewallsClient.close()` method on the client to safely
       clean up any remaining background resources. */
    try (FirewallsClient firewallsClient = FirewallsClient.create()) {

      /* The patch operation doesn't require the full definition of a Firewall object. It will only 
         update the values that were set in it, in this case it will only change the priority. */
      Firewall firewall = Firewall.newBuilder()
          .setPriority(priority).build();

      PatchFirewallRequest patchFirewallRequest = PatchFirewallRequest.newBuilder()
          .setProject(project)
          .setFirewall(firewallRuleName)
          .setFirewallResource(firewall).build();

      OperationFuture<Operation, Operation> operation = firewallsClient.patchAsync(
          patchFirewallRequest);
      operation.get(3, TimeUnit.MINUTES);
      System.out.println("Firewall Patch applied successfully ! ");
    }
  }
}

Node.js

/**
 * TODO(developer): Uncomment and replace these variables before running the sample.
 */
// const projectId = 'YOUR_PROJECT_ID';
// const firewallRuleName = 'FIREWALL_RULE_NAME';
// const priority = 10;

const compute = require('@google-cloud/compute');
const computeProtos = compute.protos.google.cloud.compute.v1;

async function patchFirewallPriority() {
  const firewallsClient = new compute.FirewallsClient();
  const operationsClient = new compute.GlobalOperationsClient();

  const firewallRule = new computeProtos.Firewall();
  firewallRule.priority = priority;

  // The patch operation doesn't require the full definition of a Firewall object. It will only update
  // the values that were set in it, in this case it will only change the priority.
  const [response] = await firewallsClient.patch({
    project: projectId,
    firewall: firewallRuleName,
    firewallResource: firewallRule,
  });
  let operation = response.latestResponse;

  // Wait for the create operation to complete.
  while (operation.status !== 'DONE') {
    [operation] = await operationsClient.wait({
      operation: operation.name,
      project: projectId,
    });
  }

  console.log('Firewall rule updated');
}

patchFirewallPriority();

PHP

use Google\Cloud\Compute\V1\Client\FirewallsClient;
use Google\Cloud\Compute\V1\Firewall;
use Google\Cloud\Compute\V1\PatchFirewallRequest;

/**
 * Modifies the priority of a given firewall rule.
 *
 * @param string $projectId Project ID or project number of the Cloud project you want to patch a rule from.
 * @param string $firewallRuleName Name of the rule that you want to modify.
 * @param int $priority The new priority to be set for the rule.
 *
 * @throws \Google\ApiCore\ApiException if the remote call fails.
 * @throws \Google\ApiCore\ValidationException if local error occurs before remote call.
 */
function patch_firewall_priority(string $projectId, string $firewallRuleName, int $priority)
{
    $firewallsClient = new FirewallsClient();
    $firewallResource = (new Firewall())->setPriority($priority);

    // The patch operation doesn't require the full definition of a Firewall object. It will only update
    // the values that were set in it, in this case it will only change the priority.
    $request = (new PatchFirewallRequest())
        ->setFirewall($firewallRuleName)
        ->setFirewallResource($firewallResource)
        ->setProject($projectId);
    $operation = $firewallsClient->patch($request);

    // Wait for the operation to complete.
    $operation->pollUntilComplete();
    if ($operation->operationSucceeded()) {
        printf('Patched %s priority to %d.' . PHP_EOL, $firewallRuleName, $priority);
    } else {
        $error = $operation->getError();
        printf('Patching failed: %s' . PHP_EOL, $error?->getMessage());
    }
}

Python

from __future__ import annotations

import sys
from typing import Any

from google.api_core.extended_operation import ExtendedOperation
from google.cloud import compute_v1


def wait_for_extended_operation(
    operation: ExtendedOperation, verbose_name: str = "operation", timeout: int = 300
) -> Any:
    """
    Waits for the extended (long-running) operation to complete.

    If the operation is successful, it will return its result.
    If the operation ends with an error, an exception will be raised.
    If there were any warnings during the execution of the operation
    they will be printed to sys.stderr.

    Args:
        operation: a long-running operation you want to wait on.
        verbose_name: (optional) a more verbose name of the operation,
            used only during error and warning reporting.
        timeout: how long (in seconds) to wait for operation to finish.
            If None, wait indefinitely.