使用 VPC 防火墙规则

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

准备工作

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

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

创建 VPC 防火墙规则

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

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

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

如果您想要为目标或来源服务账号字段指定多个服务账号,请使用 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 地址与网络标记或服务账号所标识实例的并集。也就是说,如果来源 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 地址不在来源范围内也是如此。
  • 对于出站流量规则,如需进一步优化来源,请使用 --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:您可以在创建或更新规则时,为规则启用防火墙规则日志记录。通过防火墙规则日志记录,您可以审核、验证和分析防火墙规则所带来的影响。如需了解详情,请参阅防火墙规则日志记录

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

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\Enums\Firewall\Direction;

/**
 * To correctly handle string enums in Cloud Compute library
 * use constants defined in the Enums subfolder.
 */
use Google\Cloud\Compute\V1\Firewall;
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::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.

    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 patch_firewall_priority(
    project_id: str, firewall_rule_name: str, priority: int
) -> None:
    """
    Modifies the priority of a given firewall rule.

    Args:
        project_id: project ID or project number of the Cloud project you want to use.
        firewall_rule_name: name of the rule you want to modify.
        priority: the new priority to be set for the rule.
    """
    firewall_rule = compute_v1.Firewall()
    firewall_rule.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.
    firewall_client = compute_v1.FirewallsClient()
    operation = firewall_client.patch(
        project=project_id, firewall=firewall_rule_name, firewall_resource=firewall_rule
    )

    wait_for_extended_operation(operation, "firewall rule patching")

Ruby


require "google/cloud/compute/v1"

# Modifies the priority of a given firewall rule.
#
# @param [String] project project ID or project number of the Cloud project you want to use.
# @param [String] name name of the rule you want to modify.
# @param [Google::Protobuf::RepeatedField] allowed the repeated instances of the Allowed field in the rule.
#         Compute errors out if allowed is empty.
# @param [Integer] priority the new priority to be set for the rule.
def patch_firewall_priority project:, name:, allowed:, priority:
  allowed_arr = allowed.map do |instance|
    {
      I_p_protocol: instance.I_p_protocol,
      ports: instance.ports.to_a
    }
  end.to_a

  rule = {
    priority: priority,
    allowed: allowed_arr
  }

  request = {
    project: project,
    firewall: name,
    firewall_resource: rule
  }

  # 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.
  client = ::Google::Cloud::Compute::V1::Firewalls::Rest::Client.new
  operation = client.patch request

  wait_until_done operation: operation
end

列出 VPC 网络的 VPC 防火墙规则

您可以列出您的项目或某个特定 VPC 网络的所有 VPC 防火墙规则。对于每条防火墙规则,Google Cloud 都会显示规则详情,例如规则的类型、目标和过滤条件。

如果您启用了防火墙规则日志记录,则防火墙数据分析可以提供有关您的防火墙规则的数据分析,以帮助您更好地了解并安全地优化防火墙配置。例如,您可以查看最近六周未使用哪些 allow 规则。如需了解详情,请参阅防火墙数据分析文档中的使用防火墙规则详情屏幕

控制台

如需显示项目中所有网络的所有 VPC 防火墙规则,请执行以下操作:

如需显示特定网络中的 VPC 防火墙规则,请执行以下操作:

  1. 在 Google Cloud 控制台中,转到 VPC 网络页面。

    进入 VPC 网络页面

  2. 点击某个 VPC 网络的名称以转到其详情页面。

  3. 在该网络的详情页面上,点击防火墙标签页。

  4. 展开 vpc-firewall-rules

gcloud

如需为给定网络生成经过排序的 VPC 防火墙规则列表,请使用 gcloud compute firewall-rules list 命令:

gcloud compute firewall-rules list --filter network=NETWORK \
    --sort-by priority \
    --format="table(
        name,
        network,
        direction,
        priority,
        sourceRanges.list():label=SRC_RANGES,
        destinationRanges.list():label=DEST_RANGES,
        allowed[].map().firewall_rule().list():label=ALLOW,
        denied[].map().firewall_rule().list():label=DENY,
        sourceTags.list():label=SRC_TAGS,
        targetTags.list():label=TARGET_TAGS
        )"

NETWORK 替换为要列出其防火墙规则的网络的名称。

API

列出给定网络的所有 VPC 防火墙规则。

GET https://compute.googleapis.com/compute/v1/projects/PROJECT_ID/global/firewalls/?filter=network="NETWORK

请替换以下内容:

  • PROJECT_ID:VPC 网络所在项目的 ID。
  • NETWORK:包含要列出的防火墙规则的 VPC 网络的名称。

如需了解详情,请参阅 firewalls.list 方法。

C#


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

public class ListFirewallRulesAsyncSample
{
    public async Task ListFirewallRulesAsync(
        // TODO(developer): Set your own default values for these parameters or pass different values when calling this method.
        string projectId = "your-project-id")
    {
        // 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();

        // Make the request to list all firewall rules.
        await foreach (var firewallRule in client.ListAsync(projectId))
        {
            // The result is a Firewall sequence that you can iterate over.
            Console.WriteLine($"Firewal Rule: {firewallRule.Name}");
        }
    }
}

Go

import (
	"context"
	"fmt"
	"io"

	compute "cloud.google.com/go/compute/apiv1"
	computepb "cloud.google.com/go/compute/apiv1/computepb"
	"google.golang.org/api/iterator"
)

// listFirewallRules prints the list of firewall names and their descriptions in specified project
func listFirewallRules(w io.Writer, projectID string) error {
	// projectID := "your_project_id"

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

	req := &computepb.ListFirewallsRequest{
		Project: projectID,
	}

	it := firewallsClient.List(ctx, req)
	for {
		firewallRule, err := it.Next()
		if err == iterator.Done {
			break
		}
		if err != nil {
			return err
		}
		fmt.Fprintf(w, "- %s: %s\n", firewallRule.GetName(), firewallRule.GetDescription())
	}

	return nil
}

Java


import com.google.cloud.compute.v1.Firewall;
import com.google.cloud.compute.v1.FirewallsClient;
import com.google.cloud.compute.v1.FirewallsClient.ListPagedResponse;
import java.io.IOException;

public class ListFirewallRules {

  public static void main(String[] args) throws IOException {
    // TODO(developer): Replace these variables before running the sample
    // project: project ID or project number of the Cloud project you want to use.
    String project = "your-project-id";
    listFirewallRules(project);
  }

  // Return a list of all the firewall rules in specified project.
  // Also prints the list of firewall names and their descriptions.
  public static ListPagedResponse listFirewallRules(String project)
      throws IOException {
    /* 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()) {
      ListPagedResponse firewallResponse = firewallsClient.list(project);
      for (Firewall firewall : firewallResponse.iterateAll()) {
        System.out.println(firewall.getName());
      }
      return firewallResponse;
    }
  }
}

Node.js

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

const compute = require('@google-cloud/compute');

async function listFirewallRules() {
  const firewallsClient = new compute.FirewallsClient();

  const [firewallRules] = await firewallsClient.list({
    project: projectId,
  });

  for (const rule of firewallRules) {
    console.log(` - ${rule.name}: ${rule.description}`);
  }
}

listFirewallRules();

PHP

use Google\Cloud\Compute\V1\Client\FirewallsClient;
use Google\Cloud\Compute\V1\ListFirewallsRequest;

/**
 * Return a list of all the firewall rules in specified project. Also prints the
 * list of firewall names and their descriptions.
 *
 * @param string $projectId Project ID or project number of the Cloud project you want to list rules from.
 *
 * @throws \Google\ApiCore\ApiException if the remote call fails.
 */
function list_firewall_rules(string $projectId)
{
    // List all firewall rules defined for the project using Firewalls Client.
    $firewallClient = new FirewallsClient();
    $request = (new ListFirewallsRequest())
        ->setProject($projectId);
    $firewallList = $firewallClient->list($request);

    print('--- Firewall Rules ---' . PHP_EOL);
    foreach ($firewallList->iterateAllElements() as $firewall) {
        printf(' -  %s : %s : %s' . PHP_EOL, $firewall->getName(), $firewall->getDescription(), $firewall->getNetwork());
    }
}

Python

from __future__ import annotations

from collections.abc import Iterable

from google.cloud import compute_v1

def list_firewall_rules(project_id: str) -> Iterable[compute_v1.Firewall]:
    """
    Return a list of all the firewall rules in specified project. Also prints the
    list of firewall names and their descriptions.

    Args:
        project_id: project ID or project number of the Cloud project you want to use.

    Returns:
        A flat list of all firewall rules defined for given project.
    """
    firewall_client = compute_v1.FirewallsClient()
    firewalls_list = firewall_client.list(project=project_id)

    for firewall in firewalls_list:
        print(f" - {firewall.name}: {firewall.description}")

    return firewalls_list

Ruby


require "google/cloud/compute/v1"

# Return a list of all the firewall rules in specified project. Also prints the
# list of firewall names and their descriptions.
#
# @param [String] project project ID or project number of the project you want to use.
# @return [Array<::Google::Cloud::Compute::V1::Firewall>]
#     A list of all firewall rules defined for the given project.
def list_firewall_rules project:
  client = ::Google::Cloud::Compute::V1::Firewalls::Rest::Client.new
  firewalls = client.list project: project

  firewall_list = []
  firewalls.each do |firewall|
    puts " - #{firewall.name}: #{firewall.description}"
    firewall_list << firewall
  end

  firewall_list
end

列出虚拟机实例网络接口的 VPC 防火墙规则

对于每个网络接口,Google Cloud 控制台都会列出适用于该接口的所有 VPC 防火墙规则以及该接口实际使用的规则。防火墙规则可以屏蔽其他规则,因此并非所有适用于接口的规则都会被该接口实际使用。

防火墙规则通过规则的目标参数与虚拟机实例相关联并应用于虚拟机实例。通过查看所有适用的规则,您可以检查特定规则是否适用于接口。

如果您启用了防火墙规则日志记录,则防火墙数据分析可以提供有关您的防火墙规则的数据分析,以帮助您更好地了解并安全地优化防火墙配置。例如,您可以查看最近六周内界面上有哪些规则命中。如需了解详情,请参阅防火墙数据分析文档中的使用虚拟机网络接口详情屏幕

控制台

如需查看适用于某个虚拟机实例的特定网络接口的 VPC 规则,请执行以下操作:

  1. 在 Google Cloud 控制台中,前往虚拟机实例页面。

    打开“虚拟机实例”

  2. 找到要查看的实例。

  3. 在该实例的更多操作菜单 () 中,选择查看网络详情

  4. 如果某个实例具有多个网络接口,请在选定的网络接口字段中选择要查看的网络接口。

  5. 防火墙和路由详细信息部分中,选择防火墙标签页。

  6. 展开 vpc-firewall-rules

  7. 查看表,以确定是否允许流量进出特定 IP 地址。

查看 VPC 防火墙规则详细信息

您可以检查 VPC 防火墙规则,以查看其名称、适用网络和组件(包括规则是否处于启用状态)。

控制台

  1. 列出您的防火墙规则。您可以查看规则的完整列表,也可以仅查看特定网络中的规则。
  2. 点击要查看的规则。

gcloud

以下命令可列出某个 VPC 防火墙规则的详细信息。防火墙规则名称在项目中是唯一的,因此您在描述现有防火墙规则时无需指定网络。

gcloud compute firewall-rules describe RULE_NAME

RULE_NAME 替换为防火墙规则的名称。

API

描述给定 VPC 防火墙规则。

GET https://compute.googleapis.com/compute/v1/projects/PROJECT_ID/global/firewalls/RULE_NAME

请将占位符替换为有效值:

  • PROJECT_ID:防火墙规则所在项目的 ID。
  • RULE_NAME:要描述的防火墙规则的名称。

如需了解详情,请参阅 firewalls.get 方法。

删除 VPC 防火墙规则

控制台

  1. 列出您的 VPC 防火墙规则。您可以查看规则的完整列表,也可以仅查看特定网络中的规则。
  2. 点击要删除的规则。
  3. 点击删除
  4. 再次点击删除进行确认。

gcloud

如需删除 VPC 防火墙规则,请使用 gcloud compute firewall-rules delete 命令:

gcloud compute firewall-rules delete RULE_NAME

RULE_NAME 替换为要删除的规则的名称。

API

删除 VPC 防火墙规则。

DELETE https://compute.googleapis.com/compute/v1/projects/PROJECT_ID/global/firewalls/RULE_NAME

请替换以下内容:

  • PROJECT_ID:防火墙规则所在项目的 ID。
  • RULE_NAME:要删除的防火墙规则的名称。

如需了解详情,请参阅 firewalls.delete 方法。

C#


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

public class DeleteFirewallRuleAsyncSample
{
    public async Task DeleteFirewallRuleAsync(
        // 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")
    {

        // 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();

        // Make the request to delete the firewall rule.
        var firewallRuleDeletion = await client.DeleteAsync(projectId, firewallRuleName);

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

Go

import (
	"context"
	"fmt"
	"io"

	compute "cloud.google.com/go/compute/apiv1"
	computepb "cloud.google.com/go/compute/apiv1/computepb"
)

// deleteFirewallRule deletes a firewall rule from the project.
func deleteFirewallRule(w io.Writer, projectID, firewallRuleName string) error {
	// projectID := "your_project_id"
	// firewallRuleName := "europe-central2-b"

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

	req := &computepb.DeleteFirewallRequest{
		Project:  projectID,
		Firewall: firewallRuleName,
	}

	op, err := firewallsClient.Delete(ctx, req)
	if err != nil {
		return fmt.Errorf("unable to delete 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 deleted\n")

	return nil
}

Java


import com.google.api.gax.longrunning.OperationFuture;
import com.google.cloud.compute.v1.FirewallsClient;
import com.google.cloud.compute.v1.Operation;
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 DeleteFirewallRule {

  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 firewall rule you want to delete.
    String project = "your-project-id";
    String firewallRuleName = "firewall-rule-name-" + UUID.randomUUID();
    deleteFirewallRule(project, firewallRuleName);
  }

  // Deletes a firewall rule from the project.
  public static void deleteFirewallRule(String project, String firewallRuleName)
      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()) {

      OperationFuture<Operation, Operation> operation = firewallsClient.deleteAsync(project,
          firewallRuleName);
      operation.get(3, TimeUnit.MINUTES);

      System.out.println("Deleted firewall rule -> " + firewallRuleName);
    }
  }
}

Node.js

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

const compute = require('@google-cloud/compute');

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

  const [response] = await firewallsClient.delete({
    project: projectId,
    firewall: firewallRuleName,
  });
  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 deleted');
}

deleteFirewallRule();

PHP

use Google\Cloud\Compute\V1\Client\FirewallsClient;
use Google\Cloud\Compute\V1\DeleteFirewallRequest;

/**
 * Delete a firewall rule from the specified project.
 *
 * @param string $projectId Project ID or project number of the Cloud project you want to delete a rule for.
 * @param string $firewallRuleName Name of the rule that is deleted.
 *
 * @throws \Google\ApiCore\ApiException if the remote call fails.
 * @throws \Google\ApiCore\ValidationException if local error occurs before remote call.
 */
function delete_firewall_rule(string $projectId, string $firewallRuleName)
{
    $firewallsClient = new FirewallsClient();

    // Delete the firewall rule using Firewalls Client.
    $request = (new DeleteFirewallRequest())
        ->setFirewall($firewallRuleName)
        ->setProject($projectId);
    $operation = $firewallsClient->delete($request);

    // Wait for the operation to complete.
    $operation->pollUntilComplete();
    if ($operation->operationSucceeded()) {
        printf('Rule %s deleted successfully!' . PHP_EOL, $firewallRuleName);
    } else {
        $error = $operation->getError();
        printf('Failed to delete firewall rule: %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 delete_firewall_rule(project_id: str, firewall_rule_name: str) -> None:
    """
    Deletes a firewall rule from the project.

    Args:
        project_id: project ID or project number of the Cloud project you want to use.
        firewall_rule_name: name of the firewall rule you want to delete.
    """
    firewall_client = compute_v1.FirewallsClient()
    operation = firewall_client.delete(project=project_id, firewall=firewall_rule_name)

    wait_for_extended_operation(operation, "firewall rule deletion")

Ruby


require "google/cloud/compute/v1"

# Deletes a firewall rule from the project.
#
# @param [String] project project ID or project number of the Cloud project you want to use.
# @param [String] name name of the firewall rule you want to delete.
def delete_firewall_rule project:, name:
  client = ::Google::Cloud::Compute::V1::Firewalls::Rest::Client.new
  operation = client.delete project: project, firewall: name

  wait_until_done operation: operation
end

监控 VPC 防火墙规则

您可以为 VPC 防火墙规则启用日志记录,以便了解哪条规则允许或阻止了哪些流量。如需了解相关说明,请参阅使用防火墙规则日志记录

为常见使用场景配置 VPC 防火墙规则

以下部分提供了一些示例,演示如何使用 gcloud CLI 和 API 重新创建为默认网络创建的预定义 VPC 防火墙规则。您可以使用这些示例为自定义和自动模式网络创建类似的规则。每条防火墙规则都可以包含 IPv4 或 IPv6 地址范围,但不能同时包含两者。

允许虚拟机之间的内部入站连接

以下示例创建一条防火墙规则,以允许通过内部 TCP、UDP 和 ICMP 连接到虚拟机实例,类似于默认网络的 allow-internal 规则。

gcloud

使用 gcloud compute firewall-rules create 命令:

gcloud compute firewall-rules create RULE_NAME \
    --action=ALLOW \
    --direction=INGRESS \
    --network=NETWORK \
    --priority=1000 \
    --rules=tcp:0-65535,udp:0-65535,ICMP_PROTOCOL \
    --source-ranges=SUBNET_RANGES

请替换以下内容:

  • RULE_NAME:此防火墙规则的名称。
  • NETWORK:应用此防火墙规则的网络的名称。默认值为 default
  • ICMP_PROTOCOL:ICMP 协议类型。使用协议名称 icmp 或协议编号 1 指定 ICMPv4。使用协议编号 58 指定 ICMPv6。
  • SUBNET_RANGES:一个或多个 IP 地址范围。添加 IP 地址范围后,来自该范围的流量便可以到达 VPC 网络中的任何虚拟机目的地。您可以在给定的防火墙规则中指定 IPv4 或 IPv6 范围。

    IPv4 子网范围:

    • 自动模式 VPC 网络使用 10.128.0.0/9 内的 IP 地址范围。
    • 自定义模式网络可以使用任何有效的 IPv4 地址范围。如果您未使用 VPC 网络中子网的连续范围,则可能需要指定多个范围。
    • 您可以使用 10.0.0.0/8,172.16.0.0/12,192.168.0.0/16 允许来自所有专用 IPv4 地址范围(RFC 1918 范围)的流量。

    IPv6 子网范围:

    • 如果您为 VPC 网络分配了内部 IPv6 地址范围,则可以将该范围用作来源范围。如果对 VPC 网络使用内部 IPv6 范围,防火墙规则将包含所有当前和未来的内部 IPv6 子网范围。您可以使用以下命令找到 VPC 网络的内部 IPv6 范围:

      gcloud compute networks describe NETWORK \
        --format="flattened(internalIpv6Range)"
      

      您还可以指定特定的内部 IPv6 子网范围。

    • 如需允许来自双栈子网的外部 IPv6 子网范围的流量,您必须指定要包含的每个子网的 IPv6 地址范围。

API

POST https://www.googleapis.com/compute/v1/projects/PROJECT_ID/global/firewalls
{
  "kind": "compute#firewall",
  "name": "RULE_NAME",
  "network": "projects/PROJECT_ID/global/networks/NETWORK",
  "direction": "INGRESS",
  "priority": 1000,
  "targetTags": [],
  "allowed": [
    {
      "IPProtocol": "tcp",
      "ports": [
        "0-65535"
      ]
    },
    {
      "IPProtocol": "udp",
      "ports": [
        "0-65535"
      ]
    },
    {
      "IPProtocol": "ICMP_PROTOCOL"
    }
  ],
  "sourceRanges": [
    "SUBNET_RANGES"
  ]
}

替换以下内容:

  • PROJECT_ID:VPC 网络所在项目的 ID。
  • RULE_NAME:防火墙规则的名称。
  • NETWORK:在其中创建防火墙规则的 VPC 网络的名称。默认值为 default
  • ICMP_PROTOCOL:ICMP 协议类型。使用协议名称 icmp 或协议编号 1 指定 ICMPv4。使用协议编号 58 指定 ICMPv6。
  • INTERNAL_SOURCE_RANGES:一个或多个 IP 地址范围。要允许 VPC 网络中所有子网内的内部流量,请指定您的 VPC 网络中使用的 IP 地址范围。 您可以在给定的防火墙规则中指定 IPv4 或 IPv6 范围。

    IPv4 子网范围:

    • 自动模式 VPC 网络使用 10.128.0.0/9 内的 IP 地址范围。
    • 自定义模式网络可以使用任何有效的 IPv4 地址范围。如果您未使用 VPC 网络中子网的连续范围,则可能需要指定多个范围。
    • 您可以使用 10.0.0.0/8,172.16.0.0/12,192.168.0.0/16 允许来自所有专用 IPv4 地址范围(RFC 1918 范围)的流量。

    IPv6 子网范围:

    • 如果您为 VPC 网络分配了内部 IPv6 地址范围,则可以将该范围用作来源范围。如果对 VPC 网络使用内部 IPv6 范围,防火墙规则将包含所有当前和未来的内部 IPv6 子网范围。您可以使用以下命令找到 VPC 网络的内部 IPv6 范围:

      gcloud compute networks describe NETWORK \
        --format="flattened(internalIpv6Range)"
      

      您还可以指定特定的内部 IPv6 子网范围。

    • 如需允许来自双栈子网的外部 IPv6 子网范围的流量,您必须指定要包含的每个子网的 IPv6 地址范围。

允许到虚拟机的入站 SSH 连接

以下示例创建一条防火墙规则,以允许通过 SSH 连接到虚拟机实例,类似于默认网络的 allow-ssh 规则。

gcloud

使用 gcloud compute firewall-rules create 命令:

gcloud compute firewall-rules create RULE_NAME \
    --action=ALLOW \
    --direction=INGRESS \
    --network=NETWORK \
    --priority=1000 \
    --rules=tcp:22 \
    --source-ranges=RANGES_OUTSIDE_VPC_NETWORK

请替换以下内容:

  • RULE_NAME:此防火墙规则的名称。
  • NETWORK:应用此防火墙规则的网络的名称。默认值为 default
  • RANGES_OUTSIDE_VPC_NETWORK:一个或多个 IP 地址范围。您可以在给定的防火墙规则中指定 IPv4 或 IPv6 范围。最佳实践是指定您需要允许访问的特定来源 IP 地址范围,而不是所有 IPv4 或 IPv6 来源。

    • 如果满足所有其他前提条件,则在来源范围中包含 35.235.240.0/20 允许使用 Identity-Aware Proxy (IAP) TCP 转发的 SSH 连接。如需了解详情,请参阅使用 IAP 进行 TCP 转发
    • 如果使用 0.0.0.0/0 作为来源范围,系统会允许来自所有 IPv4 来源(包括 Google Cloud 外部的来源)的流量。
    • 如果使用 ::/0 作为来源范围,系统会允许来自所有 IPv6 来源(包括 Google Cloud 外部的来源)的流量。

API

POST https://www.googleapis.com/compute/v1/projects/PROJECT_ID/global/firewalls
{
  "kind": "compute#firewall",
  "name": "RULE_NAME",
  "network": "projects/PROJECT_ID/global/networks/NETWORK",
  "direction": "INGRESS",
  "priority": 1000,
  "targetTags": [],
  "allowed": [
    {
      "IPProtocol": "tcp",
      "ports": [
        "22"
      ]
    }
  ],
  "sourceRanges": [
    "RANGES_OUTSIDE_VPC_NETWORK"
  ]
}

替换以下内容:

  • PROJECT_ID:VPC 网络所在项目的 ID。
  • RULE_NAME:防火墙规则的名称。
  • NETWORK:在其中创建防火墙规则的 VPC 网络的名称。
  • RANGES_OUTSIDE_VPC_NETWORK:一个或多个 IP 地址范围。您可以在给定的防火墙规则中指定 IPv4 或 IPv6 范围。最佳实践是指定您需要允许访问的特定来源 IP 地址范围,而不是所有 IPv4 或 IPv6 来源。

    • 如果满足所有其他前提条件,则在来源范围中包含 35.235.240.0/20 允许使用 Identity-Aware Proxy (IAP) TCP 转发的 SSH 连接。如需了解详情,请参阅使用 IAP 进行 TCP 转发
    • 如果使用 0.0.0.0/0 作为来源范围,系统会允许来自所有 IPv4 来源(包括 Google Cloud 外部的来源)的流量。
    • 如果使用 ::/0 作为来源范围,系统会允许来自所有 IPv6 来源(包括 Google Cloud 外部的来源)的流量。

允许到虚拟机的入站 RDP 连接

以下示例会创建一条防火墙规则,以允许通过 Microsoft 远程桌面协议 (RDP) 连接到虚拟机实例,类似于默认网络的 allow-rdp 规则。

gcloud

使用 gcloud compute firewall-rules create 命令:

gcloud compute firewall-rules create RULE_NAME \
    --action=ALLOW \
    --direction=INGRESS \
    --network=NETWORK \
    --priority=1000 \
    --rules=tcp:3389 \
    --source-ranges=RANGES_OUTSIDE_VPC_NETWORK

请替换以下内容:

  • RULE_NAME:此防火墙规则的名称。
  • NETWORK:应用此防火墙规则的网络的名称。默认值为 default
  • RANGES_OUTSIDE_VPC_NETWORK:一个或多个 IP 地址范围。您可以在给定的防火墙规则中指定 IPv4 或 IPv6 范围。最佳实践是指定您需要允许访问的特定来源 IP 地址范围,而不是所有 IPv4 或 IPv6 来源。

    • 如果满足所有其他前提条件,则在来源范围中包含 35.235.240.0/20 允许使用 Identity-Aware Proxy (IAP) TCP 转发的 RDP 连接。如需了解详情,请参阅使用 IAP 进行 TCP 转发
    • 如果使用 0.0.0.0/0 作为来源范围,系统会允许来自所有 IPv4 来源(包括 Google Cloud 外部的来源)的流量。
    • 如果使用 ::/0 作为来源范围,系统会允许来自所有 IPv6 来源(包括 Google Cloud 外部的来源)的流量。

API

POST https://www.googleapis.com/compute/v1/projects/PROJECT_ID/global/firewalls
{
  "kind": "compute#firewall",
  "name": "RULE_NAME",
  "network": "projects/PROJECT_ID/global/networks/NETWORK",
  "direction": "INGRESS",
  "priority": 1000,
  "allowed": [
    {
      "IPProtocol": "tcp",
      "ports": [
        "3389"
      ]
    }
  ],
  "sourceRanges": [
    "EXTERNAL_SOURCE_RANGES"
  ]
}

替换以下内容:

  • PROJECT_ID:VPC 网络所在项目的 ID。
  • RULE_NAME:防火墙规则的名称。
  • NETWORK:在其中创建防火墙规则的 VPC 网络的名称。
  • RANGES_OUTSIDE_VPC_NETWORK:一个或多个 IP 地址范围。您可以在给定的防火墙规则中指定 IPv4 或 IPv6 范围。最佳实践是指定您需要允许访问的特定来源 IP 地址范围,而不是所有 IPv4 或 IPv6 来源。

    • 如果满足所有其他前提条件,则在来源范围中包含 35.235.240.0/20 允许使用 Identity-Aware Proxy (IAP) TCP 转发的 RDP 连接。如需了解详情,请参阅使用 IAP 进行 TCP 转发
    • 如果使用 0.0.0.0/0 作为来源范围,系统会允许来自所有 IPv4 来源(包括 Google Cloud 外部的来源)的流量。
    • 如果使用 ::/0 作为来源范围,系统会允许来自所有 IPv6 来源(包括 Google Cloud 外部的来源)的流量。

允许到虚拟机的入站 ICMP 连接

以下示例创建一条防火墙规则,以允许通过 ICMP 连接到虚拟机实例,类似于默认网络的 allow-icmp 规则。

gcloud

使用 gcloud compute firewall-rules create 命令:

gcloud compute firewall-rules create RULE_NAME \
    --action=ALLOW \
    --direction=INGRESS \
    --network=NETWORK \
    --priority=1000 \
    --rules=ICMP_PROTOCOL \
    --source-ranges=RANGES_OUTSIDE_VPC_NETWORK

请替换以下内容:

  • RULE_NAME:防火墙规则的名称。
  • NETWORK:应用此防火墙规则的网络的名称。默认值为 default
  • ICMP_PROTOCOL:ICMP 协议类型。使用协议名称 icmp 或协议编号 1 指定 ICMPv4。使用协议编号 58 指定 ICMPv6。
  • RANGES_OUTSIDE_VPC_NETWORK:一个或多个 IP 地址范围。您可以在给定的防火墙规则中指定 IPv4 或 IPv6 范围。最佳实践是指定您需要允许访问的特定来源 IP 地址范围,而不是所有 IPv4 或 IPv6 来源。

    • 如果使用 0.0.0.0/0 作为来源范围,系统会允许来自所有 IPv4 来源(包括 Google Cloud 外部的来源)的流量。
    • 如果使用 ::/0 作为来源范围,系统会允许来自所有 IPv6 来源(包括 Google Cloud 外部的来源)的流量。

API

POST https://www.googleapis.com/compute/v1/projects/PROJECT_ID/global/firewalls
{
  "kind": "compute#firewall",
  "name": "RULE_NAME",
  "network": "projects/PROJECT_ID/global/networks/NETWORK",
  "direction": "INGRESS",
  "priority": 1000,
  "targetTags": [],
  "allowed": [
    {
      "IPProtocol": "ICMP_PROTOCOL"
    }
  ],
  "sourceRanges": [
    "RANGES_OUTSIDE_VPC_NETWORK"
  ]
}

替换以下内容:

  • PROJECT_ID:VPC 网络所在项目的 ID。
  • RULE_NAME:防火墙规则的名称。
  • NETWORK:在其中创建防火墙规则的 VPC 网络的名称。
  • ICMP_PROTOCOL:要使用的 ICMP 协议的类型。使用协议名称 icmp 或协议编号 1 指定 ICMPv4。使用协议编号 58 指定 ICMPv6。
  • RANGES_OUTSIDE_VPC_NETWORK:一个或多个 IP 地址范围。您可以在给定的防火墙规则中指定 IPv4 或 IPv6 范围。最佳实践是指定您需要允许访问的特定来源 IP 地址范围,而不是所有 IPv4 或 IPv6 来源。

    • 如果使用 0.0.0.0/0 作为来源范围,系统会允许来自所有 IPv4 来源(包括 Google Cloud 外部的来源)的流量。
    • 如果使用 ::/0 作为来源范围,系统会允许来自所有 IPv6 来源(包括 Google Cloud 外部的来源)的流量。

其他配置示例

图 1 展示了名为 my-network 的 VPC 网络的示例配置。该网络包含以下内容:

  • 名为 subnet1 的子网,IP 范围为 10.240.10.0/24,具有单个实例
  • 名为 subnet2 的子网,IP 范围为 192.168.1.0/24
  • 名为 subnet2 且具有 webserver 标记和内部 IP 地址 192.168.1.2vm1 实例
  • 名为 subnet2 且具有 database 标记和内部 IP 地址 192.168.1.3vm2 实例
此 VPC 网络包含两个子网,每个子网都包含虚拟机;subnet2 包含分配了网络标记的虚拟机。
图 1. 此 VPC 网络包含两个子网,每个子网都包含虚拟机;subnet2 包含已分配了网络标记的虚拟机(点击可放大)。

示例 1:拒绝所有入站 TCP 连接(从 subnet1 到端口 80 的连接除外)

在本例中,我们将创建一组防火墙规则,以拒绝所有入站 TCP 连接(从 subnet1 到端口 80 的连接除外)。

gcloud

  1. 创建一条防火墙规则,以拒绝流向带有 webserver 标记的实例的所有入站 TCP 流量。

    gcloud compute firewall-rules create deny-subnet1-webserver-access \
        --network NETWORK_NAME \
        --action deny \
        --direction ingress \
        --rules tcp \
        --source-ranges 0.0.0.0/0 \
        --priority 1000 \
        --target-tags webserver
    

    NETWORK_NAME 替换为网络的名称。

  2. 创建一条防火墙规则,以允许 subnet1 (10.240.10.0/24) 中的所有 IP 地址访问带有 webserver 标记的实例上的 TCP 端口 80

    gcloud compute firewall-rules create vm1-allow-ingress-tcp-port80-from-subnet1 \
        --network NETWORK_NAME \
        --action allow \
        --direction ingress \
        --rules tcp:80 \
        --source-ranges 10.240.10.0/24 \
        --priority 50 \
        --target-tags webserver
    

    NETWORK_NAME 替换为网络的名称。

示例 2:拒绝所有出站 TCP 连接(与 vm1 的端口 80 的连接除外)

gcloud

  1. 创建一条防火墙规则,拒绝所有出站 TCP 流量。

    gcloud compute firewall-rules create deny-all-access \
        --network NETWORK_NAME \
        --action deny \
        --direction egress \
        --rules tcp \
        --destination-ranges 0.0.0.0/0 \
        --priority 1000
    

    NETWORK_NAME 替换为网络的名称。

  2. 创建一条防火墙规则,以允许定向到 vm1 的端口 80 的 TCP 流量。

    gcloud compute firewall-rules create vm1-allow-egress-tcp-port80-to-vm1 \
        --network NETWORK_NAME \
        --action allow \
        --direction egress \
        --rules tcp:80 \
        --destination-ranges 192.168.1.2/32 \
        --priority 60
    

    NETWORK_NAME 替换为网络的名称。

示例 3:允许与外部主机的端口 443 的出站 TCP 连接

创建一条防火墙规则,以允许带有 webserver 标记的实例将出站 TCP 流量发送到示例外部 IP 地址 192.0.2.5 的端口 443

gcloud

gcloud compute firewall-rules create vm1-allow-egress-tcp-port443-to-192-0-2-5 \
    --network NETWORK_NAME \
    --action allow \
    --direction egress \
    --rules tcp:443 \
    --destination-ranges 192.0.2.5/32 \
    --priority 70 \
    --target-tags webserver

NETWORK_NAME 替换为网络的名称。

示例 4:允许从 vm2 到 vm1 的 SSH 连接

创建一条防火墙规则,以允许 SSH 流量从带有 database 标记的实例 (vm2) 到达带有 webserver 标记的实例 (vm1)。

gcloud

gcloud compute firewall-rules create vm1-allow-ingress-tcp-ssh-from-vm2 \
    --network NETWORK_NAME \
    --action allow \
    --direction ingress \
    --rules tcp:22 \
    --source-tags database \
    --priority 80 \
    --target-tags webserver

NETWORK_NAME 替换为网络的名称。

示例 5:允许 1443 端口的 TCP 流量从网络服务器流向数据库(使用服务账号)

如需详细了解服务账号和角色,请参阅向服务账号授予角色

请考虑图 2 中的情景,其中有两个通过模板自动扩缩的应用:与 my-sa-webserver 服务账号关联的 Web 服务器应用和与 my-sa-database 服务账号关联的数据库应用。安全管理员希望允许 TCP 流量从具有 my-sa-webserver 服务账号的虚拟机流向具有 my-sa-database 服务账号的虚拟机的目标端口 1443

防火墙规则允许来自使用服务账号 my-sa-webserver 的虚拟机的流量到达使用服务账号 my-sa-database 的虚拟机的端口 1443。
图 2. 防火墙规则允许来自使用服务账号 my-sa-webserver 的虚拟机的流量到达使用服务账号 my-sa-database 的虚拟机的端口 1443(点击可放大)。

配置步骤(包括创建服务账号)如下所示:

gcloud

  1. 项目 EDITOR 或项目 OWNER 创建服务账号 my-sa-webservermy-sa-database

    gcloud iam service-accounts create my-sa-webserver \
        --display-name "webserver service account"
    
    gcloud iam service-accounts create my-sa-database \
        --display-name "database service account"
    
  2. 项目 OWNER 通过设置 Identity and Access Management (IAM) 政策,针对服务账号 my-sa-webserver 为 Web 服务器开发者 web-dev@example.com 分配 serviceAccountUser 角色。

    gcloud iam service-accounts add-iam-policy-binding \
    my-sa-webserver@my-project.iam.gserviceaccount.com \
        --member='user:web-dev@example.com' \
        --role='roles/iam.serviceAccountUser'
    
  3. 项目 OWNER 通过设置 IAM 政策针对服务账号 my-sa-database 为数据库开发者 db-dev@example.com 分配 serviceAccountUser 角色。

    gcloud iam service-accounts add-iam-policy-binding \
    my-sa-database@my-project.iam.gserviceaccount.com \
        --member='user:db-dev@example.com' \
        --role='roles/iam.serviceAccountUser'
    
  4. 具有 Instance Admin 角色的开发者 web-dev@example.com 创建 Web 服务器实例模板,并授权实例以服务账号 my-sa-webserver 的身份运行。

    gcloud compute instance-templates create INSTANCE_TEMPLATE_NAME \
        --service-account my-sa-webserver@my-project-123.iam.gserviceaccount.com
    
  5. 具有 Instance Admin 角色的开发者 db-dev@example.com 创建数据库实例模板,并授权实例以服务账号 my-sa-database 的身份运行。

    gcloud compute instance-templates create INSTANCE_TEMPLATE_NAME \
        --service-account my-sa-database@my-project-123.iam.gserviceaccount.com
    
  6. Security Admin 会创建一条防火墙规则,该规则允许来自具有服务账号 my-sa-webserver 的虚拟机的 TCP 流量到达具有服务账号 my-sa-database 的虚拟机的端口 1443。

    gcloud compute firewall-rules create RULE_NAME \
        --network network_a \
        --allow TCP:1443 \
        --source-service-accounts my-sa-webserver@my-project.iam.gserviceaccount.com \
        --target-service-accounts my-sa-database@my-project.iam.gserviceaccount.com
    

问题排查

创建或更新 VPC 防火墙规则时出现错误消息

您可能会看到以下某条错误消息:

  • Should not specify destination range for ingress direction.

    目标地址范围不是入站防火墙规则的有效参数。 除非明确指定方向为 egress,否则防火墙规则假定为入站规则。如果您创建的规则未指定方向,则该规则为入站规则,此类规则不允许使用目标范围。此外,对出站规则来说,来源范围也是无效参数。

  • Firewall direction cannot be changed once created.

    现有防火墙规则的方向无法更改。您必须使用正确的参数创建新规则,然后删除旧规则。

  • Firewall traffic control action cannot be changed once created.

    现有防火墙规则的操作无法更改。您必须使用正确的参数创建新规则,然后删除旧规则。

  • Service accounts must be valid RFC 822 email addresses. 防火墙规则中指定的服务账号必须采用符合 RFC 822 规范的电子邮件地址格式。

    gcloud compute firewall-rules create bad --allow tcp --source-service-accounts invalid-email
    
    Creating firewall...failed.
    ERROR: (gcloud.compute.firewall-rules.create) Could not fetch resource:
    – Invalid value for field 'resource.sourceServiceAccounts[0]': 'invalid-email'. Service accounts must be valid RFC 822 email addresses.
    
  • ServiceAccounts and Tags are mutually exclusive and can't be combined in the same firewall rule. 您不能在同一条规则中同时指定服务账号和标记。

    gcloud compute firewall-rules create bad --allow tcp --source-service-accounts test@google.com --target-tags target
    
    Creating firewall...failed.
     ERROR: (gcloud.compute.firewall-rules.create) Could not fetch resource:
    – ServiceAccounts and Tags are mutually exclusive and can't be combined in the same firewall rule.
    

“找不到资源”错误

删除 VPC 网络或防火墙规则时,您可能会看到类似于以下内容的消息:The resource "aet-uscentral1-subnet--1-egrfw" was not found.

此错误可能会阻止您删除隐式防火墙规则或查看其详细信息。处于此状态的防火墙规则也可能会阻止您删除 VPC 网络。

如需删除以这种方式阻止的防火墙规则或网络,请先删除关联的无服务器 VPC 访问通道连接器,然后重试。如需详细了解如何删除无服务器 VPC 访问通道连接器,请参阅删除连接器

“大型防火墙过多”错误

您可能会看到以下错误消息: Google Compute Engine: The network contains too many large firewalls.

为了保证安全性和性能,在 VPC 网络中可以实施的防火墙规则的复杂性和数量存在限制。如果您看到此错误,请联系客户管理团队以简化或整合防火墙规则。

无法连接到虚拟机实例

如果无法连接到虚拟机实例,请检查您的防火墙规则。

gcloud

  1. 如果您是从其他虚拟机实例发起连接,请列出该实例的出站防火墙规则。

    gcloud compute firewall-rules list --filter network=NETWORK_NAME \
      --filter EGRESS \
      --sort-by priority \
      --format="table(
          name,
          network,
          direction,
          priority,
          sourceRanges.list():label=SRC_RANGES,
          destinationRanges.list():label=DEST_RANGES,
          allowed[].map().firewall_rule().list():label=ALLOW,
          denied[].map().firewall_rule().list():label=DENY,
          sourceTags.list():label=SRC_TAGS,
          sourceServiceAccounts.list():label=SRC_SVC_ACCT,
          targetTags.list():label=TARGET_TAGS,
          targetServiceAccounts.list():label=TARGET_SVC_ACCT
          )"
    

    NETWORK_NAME 替换为网络的名称。

  2. 检查目标 IP 是否被任何出站规则拒绝。优先级最高的规则(优先级数值最小)将替换优先级较低的规则。如果两个规则的优先级相同,则拒绝规则优先。

  3. 检查目标虚拟机实例所在网络的入站防火墙规则。

    gcloud compute firewall-rules list --filter network=NETWORK_NAME \
      --filter INGRESS \
      --sort-by priority \
      --format="table(
          name,
          network,
          direction,
          priority,
          sourceRanges.list():label=SRC_RANGES,
          destinationRanges.list():label=DEST_RANGES,
          allowed[].map().firewall_rule().list():label=ALLOW,
          denied[].map().firewall_rule().list():label=DENY,
          sourceTags.list():label=SRC_TAGS,
          sourceServiceAccounts.list():label=SRC_SVC_ACCT,
          targetTags.list():label=TARGET_TAGS,
          targetServiceAccounts.list():label=TARGET_SVC_ACCT
          )"
    

    NETWORK_NAME 替换为网络的名称。

    示例输出。实际输出取决于您的防火墙规则列表。

    NAME                    NETWORK  DIRECTION  PRIORITY  SRC_RANGES    DEST_RANGES  ALLOW                         DENY  SRC_TAGS  SRC_SVC_ACCT      TARGET_TAGS  TARGET_SVC_ACCT
    default-allow-icmp      default  INGRESS    65534     0.0.0.0/0                  icmp
    default-allow-internal  default  INGRESS    65534     10.128.0.0/9               tcp:0-65535,udp:0-65535,icmp
    default-allow-rdp       default  INGRESS    65534     0.0.0.0/0                  tcp:3389
    default-allow-ssh       default  INGRESS    65534     0.0.0.0/0                  tcp:22
    firewall-with-sa        default  INGRESS    1000                                 tcp:10000                                     test1@google.com               target@google.com
    
  4. 此外,如果流量被任何入站流量或出站流量防火墙规则丢弃,您还可以在某个 VPC 网络中的虚拟机实例与其他 VPC 网络或非 Google Cloud 网络之间运行连接测试,以便排查问题。如需详细了解如何运行连接测试以排查各种场景问题,请参阅运行连接测试

我的 VPC 防火墙规则处于启用状态还是停用状态?

要了解某条防火墙规则是否处于启用状态,请查看防火墙规则详情

Google Cloud 控制台强制执行部分,查找已启用已停用

在 gcloud CLI 输出中,查找 disabled 字段。如果该字段显示 disabled:false,则表明规则已启用且正在实施。如果该字段显示 disabled: true,则表明规则已停用。

虚拟机实例上正在应用什么规则?

创建规则后,您可以检查它是否在特定实例上得到正确应用。如需了解详情,请参阅列出虚拟机实例网络接口的防火墙规则

使用来源标记的 VPC 防火墙规则不会立即生效

使用来源标记的入站防火墙规则可能需要一段时间才能生效。如需了解详情,请参阅与入站防火墙规则的来源标记相关的注意事项

后续步骤